{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/players/index.cjs","../../src/players/index.ts","../../src/utils.ts","../../src/patterns.ts","../../src/players/HlsPlayer.tsx","../../src/sdk/hlsAdPlayer.ts","../../src/sdk/pal.ts","../../src/utils/mqttConfig.ts","../../src/utils/mqttClient.ts","../../src/utils/vastEnvironmentSignals.ts","../../src/utils/tracking.ts","../../src/utils/polyfills.ts","../../src/utils/vastMacros.ts","../../src/utils/browserCompat.ts","../../src/player/Scte35Parser.ts","../../src/player/Scte35CueManager.ts","../../src/player/AdConfigManager.ts","../../src/player/AdTimingService.ts","../../src/player/AdPreloadPool.ts","../../src/player/PlaceholderLayer.ts","../../src/player/HlsEngine.ts","../../src/player/PlayerControls.ts","../../src/player/AdBreakOrchestrator.ts"],"names":["__create","Object","create","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","__getProtoOf","getOwnPropertyNames","getPrototypeOf","__export","target","all","name","__defProp","get","enumerable","from","key","__hasOwnProp","call","to","except","desc","mod","__toESM","isNodeMode","__copyProps","__esModule","value","__toCommonJS","players_exports","default","players_default","exports","import_react","require","lazy","reactLazy","IS_BROWSER","window","document","IS_GLOBAL","globalThis","IS_IOS","test","navigator","userAgent","IS_SAFARI","HLS_EXTENSIONS","HLS_PATHS","DASH_EXTENSIONS","AUDIO_EXTENSIONS","canPlay","hls","url","dash","video","VIDEO_EXTENSIONS","audio","file","import_hls","MAX_VAST_WRAPPER_DEPTH","createHlsAdPlayer","contentVideo","options","adPlaying","originalMutedState","originalVolume","Math","max","min","volume","listeners","Map","licenseKey","mainHlsInstance","adVideoElement","adHls","preloadedAds","adContainerEl","currentAd","podAds","podIndex","preloadingAds","destroyed","pendingTimeouts","trackingFired","impression","start","firstQuartile","thirdQuartile","complete","emit","event","payload","set","Array","fn","error","fireTrackingPixels","urls","trackingUrl","console","warn","generateSessionId","Date","now","random","toString","substr","length","forEach","sessionId","includes","img","Image","src","log","currentLevel","levels","autoLevel","loadLevel","level","width","height","bitrate","selectBestMediaFile","mediaFiles","Error","firstFile","mainQuality","getMainStreamQuality","scoredFiles","map","widthDiff","abs","heightDiff","resolutionDiff","fileBitrate","bitrateDiff","score","sort","a","b","bestMatch","resolution","isHlsMediaFile","mediaFile","type","toLowerCase","isProgressiveMediaFile","startsWith","endsWith","createEmptyTrackingUrls","midpoint","mute","unmute","pause","resume","fullscreen","exitFullscreen","skip","extractTrackingUrls","scope","trackingUrls","querySelectorAll","el","textContent","trim","push","getAttribute","eventKey","mergeTrackingUrls","source","keys","concat","parseVastXml","xmlString","xmlDoc","parser","DOMParser","parseFromString","parserError","querySelector","adElement","adId","title","clickThrough","wrapperUri","vastAdTagUri","isNoAdAvailable","durationText","durationParts","split","duration","parseInt","mediaFileElements","mf","index","bitrateAttr","bitrateValue","ad","id","parseAdElement","fetchVastXml","vastTagUrl","response","fetch","mode","credentials","headers","referrerPolicy","ok","statusText","text","fetchAndParseVastAd","depth","accumulatedTracking","vastXml","parsed","substring","fetchAndParsePod","adElements","ads","resolved","aSeq","bSeq","aVal","Number","isFinite","MAX_SAFE_INTEGER","bVal","createAdVideoElement","createElement","style","position","top","backgroundColor","playsInline","muted","setupAdEventListeners","addEventListener","progress","currentTime","advanceToNextPodAd","handleAdComplete","e","handleAdError","ended","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","resetQuartileTracking","preserveImpression","loadCurrentAdMedia","isHlsAd","Hls","isSupported","destroy","enableWorker","lowLatencyMode","loadSource","attachMedia","on","Events","MANIFEST_PARSED","play","catch","ERROR","_event","data","fatal","canPlayType","load","total","display","pointerEvents","continueLiveStreamDuringAds","paused","initialize","container","left","right","bottom","alignItems","justifyContent","zIndex","parentElement","appendChild","requestAds","preloaded","Promise","reject","has","delete","resolve","contentVolume","stop","previousMutedState","visibility","opacity","timeoutId","clearTimeout","remove","removeChild","clear","isAdPlaying","resize","listener","Set","add","off","updateOriginalMutedState","nextVolume","isNaN","getOriginalMutedState","getOriginalVolume","setAdVolume","clamped","getAdVolume","showPlaceholder","hidePlaceholder","getLoadedAdDuration","getLoadedAdId","getPodAdCount","getPodTotalDurationMs","reduce","PAL_SDK_URL","_nonceLoader","_palLoadPromise","loadPalSdk","goog","pal","existing","timeout","setTimeout","script","async","onload","onerror","head","getOrCreateNonceLoader","currentNonceManager","generateNonce","sendAdTouch","mqttConfig","enabled","consentSettings","ConsentSettings","allowStorage","NonceLoader","createPalNonceManager","currentNonce","loader","request","manager","NonceRequest","adWillAutoPlay","adWillPlayMuted","playerVolume","continuousPlayback","descriptionUrl","location","href","iconsSupported","playerType","playerVersion","supportedApiFrameworks","videoWidth","videoHeight","ppid","loadNonceManager","getNonce","getCurrentNonce","injectNonce","URL","searchParams","base","replace","sep","encodeURIComponent","sendPlaybackStart","sendPlaybackEnd","sendAdClick","reset","DEFAULT_MQTT_CONFIG","brokerAddress","brokerPort","wsPort","username","password","topicPrefix","qos","isMQTTEnabled","buildMQTTBrokerUrl","brokerUrl","buildPlayerTopic","channel","client","status","info","import_mqtt","initMQTTClient","clientId","slice","mqtt","connect","clean","reconnectPeriod","err","LOG","message","ensureMQTTClient","publishMQTT","topic","publish","JSON","stringify","AIRY_WEBOS_APP_ID","AIRY_TIZEN_APP_ID","AIRY_ROKU_APP_ID","AIRY_APP_NAME","AIRY_DEFAULT_CONTENT_URL","CTV_SESSION_STORAGE_KEY","LG_TEST_APP_NAME","isLgWebOS","PLAYER_ID_STORAGE_KEY","LG_TEST_CONTENT_URL","_lgTestDeviceId","getLgTestDeviceId","createUuid","ua","AIRY_ANDROID_APP_ID","DEVICE_ID_STORAGE_KEYS","ANDROID_ID_TYPES","resolveVastEnvironmentSignals","isCtv","platformLat","lg","deviceId","bridgeSignals","readStoredDeviceId","platformDevice","limitAdTracking","deviceIdType","readStoredString","inferDeviceIdType","readStoredLimitAdTracking","contentUrl","appId","LG_TEST_APP_ID","getDefaultAppId","appName","getOrCreateCtvSessionId","deviceTypeHint","isEquivalentDeviceIdType","tagType","runtimeType","tag","runtime","resolveNativeDeviceId","readNativeBridgeSignals","readPlatformNativeDeviceId","isMacroPlaceholder","isZeroedAdId","getOrCreateStoredUuid","storageKey","readPersistentId","writePersistentId","readCookie","localStorage","setItem","writeCookie","PERSISTENT_ID_COOKIE_MAX_AGE","prefix","parts","cookie","part","entry","decodeURIComponent","bytes","crypto","randomUUID","Uint8Array","getRandomValues","seed","floor","performanceNow","i","hex","performance","adinfo","webapis","tifa","getTIFA","lat","isLATEnabled","webOSDev","lgudid","LGUDID","roku","Roku","rida","getPublisherUniqueId","ZEROED_AD_ID_PATTERNS","t","candidates","__STORMCLOUD_CTV_AD_INFO__","__STORMCLOUD_CTV__","stormcloudCtv","Android","webOS","tizen","amazon","filter","Boolean","readBridgeValue","readBridgeBoolean","result","normalized","normalizeBoolean","getItem","cachedBrowserId","buildAnalyticsContext","config","context","debugAdTiming","isLiveStream","inputStreamType","getClientInfo","screen","platform","vendor","maxTouchPoints","memory","deviceMemory","hardwareConcurrency","screenInfo","availWidth","availHeight","orientation","pixelDepth","deviceType","brand","os","model","isSmartTV","isAndroid","isWebView","isWebApp","webosMatch","match","tizenMatch","tvMatch","androidModelMatch","outerHeight","outerWidth","matchMedia","matches","standalone","angle","domain","hostname","origin","path","pathname","language","languages","join","cookieEnabled","doNotTrack","referrer","visibilityState","sha256Hex","input","encodedData","utf8","buffer","hashBuffer","hash","char","fallbackHash","timestamp","subtle","digest","TextEncoder","encode","unescape","charCodeAt","padStart","padEnd","resolvePlayerIdentitySeed","clientInfo","nativeDeviceId","persistedId","getBrowserID","canPublish","buildPlayerMetricEvent","flags","playerId","captureAt","toISOString","player_id","device_type","ad_loaded","adLoaded","ad_detect","adDetect","capture_at","input_stream_type","publishTracking","body","sendInitialTracking","metricEvent","events","sendAdDetectTracking","adDetectInfo","sendHeartbeat","sendAdLoadedTracking","adLoadedInfo","sendAdImpressionTracking","adImpressionInfo","ad_played_count","ad_url","adUrl","heartbeatData","polyfillURLSearchParams","URLSearchParams","URLSearchParamsPolyfill","init","params","parseQueryString","append","query","cleanQuery","param","decodedKey","safeDecodeURIComponent","decodedValue","str","values","String","getAll","callback","polyfillTextEncoder","TextEncoderPolyfill","encoding","charcode","polyfillPromiseFinally","prototype","finally","then","constructor","reason","polyfillObjectAssign","assign","sources","TypeError","nextSource","nextKey","hasOwnProperty","arrayLike","mapFn","thisArg","items","len","polyfillStringStartsWith","search","pos","polyfillStringEndsWith","polyfillStringIncludes","indexOf","initializePolyfills","polyfillArrayFrom","UNEXPANDED_MACRO_PATTERN","INVALID_VAST_PARAM_KEY","EXAMPLE_COM_URL","CTV_UNSUPPORTED_PARAMS","INLINE_DEVICE_MACRO_REPLACEMENTS","pattern","getValue","ctx","correlator","trimmed","generateCorrelator","buf","Uint32Array","expandInlineMacroPlaceholders","baseUrl","applyDeviceIdentityParams","runtimeId","tagRdid","tagLat","latValue","tagRdidValid","tagTypeValid","removeBrokenAppNameOrphans","toDelete","_value","suffix","trimStart","normalizeVastTagUrl","raw","anValue","orphanFragments","reconstructed","trimEnd","_match","val","applyVastMacros","expandedUrl","replaceCorrelatorFallback","streamCorrelator","pod","optimizedPodMode","podMaxAds","podMinDurationMs","podMaxDurationMs","round","adPosition","requestUrl","pageUrl","existingUrl","consent","staleKeys","correlatorRegex","tasks","gdpr","gdprConsent","usPrivacy","adTest","fetchConsentSignals","timeoutMs","signals","tcfApi","__tcfapi","settled","tcData","success","eventStatus","gdprApplies","tcString","listenerId","uspApi","__uspapi","uspString","getChromeVersion","getWebKitVersion","getPlatform","userAgentData","detectBrowser","version","majorVersion","isLegacyTV","supportsModernJS","webOSVersion","tizenVersion","chromeVersionNum","chromeVersion","webkitVersion","getBrowserConfigOverrides","browser","overrides","allowNativeHls","logBrowserInfo","debug","parseCueOutDuration","num","parseFloat","dStr","d","parseCueOutCont","res","elapsedMatch","durationMatch","elapsed","slashMatch","parseAttributeList","attrs","regex","exec","rawVal","toNumber","n","isManifestBasedMarker","marker","id3","splice_command_type","decodeId3ValueToText","decoder","TextDecoder","decode","out","fromCharCode","getFragmentStartSeconds","frag","startPTS","candidate","parseScte35FromId3","cueOutMatch","arg","dur","ptsSeconds","durationSeconds","cueOutContMatch","cont","cueInMatch","daterangeMatch","hasScteOut","hasScteIn","klass","bin","parseScte35Binary","normalizeFragmentPayload","ArrayBuffer","isView","view","byteOffset","byteLength","detectTsPacketFormat","packetSizes","packetSize","tsPayloadOffset","offset","matchedPackets","packetStart","getPsiSectionStart","payloadUnitStart","pointerField","sectionStart","getPsiSectionLength","parsePatSection","pmtPids","sectionLength","sectionEnd","programNumber","pid","descriptorsIdentifyScte35","end","descriptorStart","descriptorEnd","registration","parsePmtSection","tsScte35Pids","programInfoLength","streamType","elementaryPid","esInfoLength","hasProcessedTsScte35Section","checksum","section","processedSections","size","firstKey","next","addScte35SectionMarker","markers","appendScte35Bytes","assemblers","assembler","expectedLength","collectScte35SectionsFromPayload","previousAssembler","subarray","tableId","totalLength","parseScte35FromTsPackets","packetInfo","sectionAssemblers","tsStart","secondByte","thirdByte","fourthByte","adaptationFieldControl","hasPayload","payloadStart","adaptationLength","payloadEnd","BitReader","bytePos","bitPos","readBits","numBits","remainingInByte","toRead","currentByte","shift","mask","bits","skipBits","bytePosition","readSpliceTime","r","ptsAdjustmentTicks","timeSpecifiedFlag","high","low","ptsTicks","markerTypeFromSegmentationTypeId","segmentationTypeId","segmentationUpidLength","parseScte35SegmentationDescriptor","descriptor","identifier","segmentationEventId","cancelIndicator","programSegmentationFlag","segmentationDurationFlag","componentCount","durationTicks","markerType","parseScte35SegmentationDescriptors","descriptorLoopLength","descriptorOffset","descriptorTag","descriptorLength","descriptorDataStart","descriptorDataEnd","descriptorMarker","spliceImmediateFlag","ptsAdjHigh","ptsAdjLow","spliceCommandLength","spliceCommandType","spliceEventId","cancel","outOfNetwork","programSpliceFlag","durationFlag","componentPtsSeconds","expectedDescriptorOffset","commandBodyStart","splice_event_id","Scte35CueManager","callbacks","pendingScte35Cues","recentScte35CueKeys","recentScte35CueLimit","processedTsScte35Sections","pendingScte35CueKey","pendingScte35CueKeyValue","activeScte35BreakKey","activeScte35BreakKeyValue","scheduledScte35BreakKey","scheduledScte35BreakKeyValue","createScte35CueContext","readiness","sn","fragmentSn","fragmentStartSec","fragmentStartSeconds","onScte35Cue","cue","createScte35Cue","pendingKey","getPendingScte35CueKey","trimRecentScte35CueMaps","onEarlyStartCue","shouldAcceptScte35EndCue","inAdBreak","isInAdBreak","hasRecentlyHandledScte35Cue","markScte35CueHandled","onPlaybackCue","activatePendingScte35CuesForFragment","matchingCues","entries","getScte35CueKey","getScte35MarkerRaw","toIdentityString","daterangeId","ID","scteValue","isStrongScte35CueKey","recentKey","AdConfigManager","vmapBreaks","consumedVmapBreakIds","viewCorrelator","consentSignals","podCounter","podAssignedByPrefetch","adRequestPositionInBreak","lastHeartbeatTime","defaultPodMaxAds","isVmapEnabled","isVmap","vmapUrl","fetchAdConfiguration","vastMode","vastEndpoint","apiUrl","imaPayload","decodedPayload","numberAds","fetchAndParseVmap","apiVastTagUrl","json","ima","vast","cue_tones","number_ads","apiNumberAds","vmapXml","parseVmapToBreaks","doc","VMAP_NS","adBreakNodes","getElementsByTagNameNS","getElementsByTagName","localName","node","timeOffsetRaw","startTimeMs","parseVmapTimeOffsetToMs","adTagNode","adTagUrl","breakId","aStart","bStart","timeOffset","hms","hh","mm","ss","ms","hours","minutes","seconds","millis","percent","ratio","durationSec","getAdBreakKey","adBreak","resolveBreakStartMs","findCurrentOrNextBreak","nowMs","schedule","tol","driftToleranceMs","breakStartMs","findBreakForTime","durationMs","selectVastTagsForBreak","s","beginNewAdPod","generateVastUrlsWithCorrelators","count","adPlayer","palNonce","envSignals","ctvAdRequest","urlWithMacros","autoplay","finalUrl","resolvePodParams","breakDurationMs","maxDurationMs","maxAds","minDurationMs","podExactDuration","generatePodVastUrl","podParams","destroyTracking","AdTimingService","adRequestWatchdogToken","adFailsafeToken","globalLastGamRequestTime","adStopTimerId","scheduleAdStartIn","ptsDriftEmaMs","nowWallClockMs","scheduleAdStopAtBreakBoundary","initializeTracking","heartbeatInterval","setInterval","sendHeartbeatIfNeeded","clearInterval","adBreakPlayedDurationMs","adBreakEpoch","adRequestTokenCounter","activeAdRequestToken","currentAdIndex","totalAdsInBreak","totalAdRequestsInBreak","maxTotalAdRequestsPerBreak","lastAdRequestTime","consecutiveFailures","maxConsecutiveFailures","minAdRequestIntervalMs","backoffBaseMs","maxBackoffMs","defaultMinRemainingMsToStartAd","failedVastUrls","temporaryFailureUrls","temporaryFailureCooldownMs","globalConsecutiveNoFills","globalNoFillThreshold","globalNoFillCooldownUntil","globalNoFillBackoffBaseMs","globalNoFillBackoffMaxMs","globalMinGamIntervalMs","scheduleAdStopCountdown","remainingMs","clearAdStopTimer","ensureAdStoppedByTimer","onAdStopTimerFired","delayMs","cueKey","clearAdStartTimer","onAdStartTimerFired","adStartTimerId","updatePtsDrift","ptsSecondsSample","sampleMs","alpha","resolveScteBreakStartWallClockMs","estimatedCurrentPtsMs","deltaMs","setAdBreakDurationBoundary","expectedAdBreakDurationMs","currentAdBreakStartWallClockMs","scteAdBreakEndWallClockMs","getWallClockRemainingAdMs","endWallClockMs","getAdBreakEndWallClockMs","adController","getDurationBudgetRemainingMs","getLoadedAdDurationMs","adFitsRemainingBudget","logAdDurationDecision","remainingBudget","accepted","recordPlayedAdDuration","ensureLoadedAdFitsBudget","fits","rejectLoadedAdForDuration","markAdStarted","notePodAdStarted","getRemainingAdMs","wallClockRemaining","budgetRemaining","getMinRemainingMsToStartAd","configured","minRemainingMsToStartAd","hasTimeToStartAnotherAd","minRemaining","isTemporaryAdError","isUrlInCooldown","failureTime","cleanupTemporaryFailures","recordGamNoFill","isGamInCooldown","exponent","backoff","pow","clearAdRequestWatchdog","resetGamNoFillCounter","enforceGlobalRateLimit","waitMs","startAdRequestWatchdog","token","adFailsafeTimeoutMs","adRequestWatchdogId","logAdState","onWatchdogTimeout","startAdFailsafeTimer","failsafeMs","adFailsafeTimerId","active","startPreloadPool","videoPaused","onFailsafeTimeout","clearAdFailsafeTimer","extra","showAds","resetForBreakEnd","AdPreloadPool","deps","pool","maxPoolSize","poolActive","loopRunning","isLoopRunning","baseVastUrl","initialUrls","startLoopImmediately","preloadAdIntoPool","epoch","timing","loadPromise","preloadPoolLoop","vastUrl","some","hasAdError","adErrorPayload","errorListenerCleanup","preloadAd","errorListener","isNoFill","poolEntry","loadedDuration","lateErrorListener","shouldContinueLiveStreamDuringAds","createAdPlayer","code","vastErrorCode","findIndex","splice","getPendingAdBreak","newUrls","newUrl","getPreloadedAd","isReady","PlaceholderLayer","ensureContainer","transition","show","wasHidden","offsetHeight","requestAnimationFrame","hide","HlsEngine","cueManager","nativeHlsMode","videoSrcProtection","bufferedSegmentsCount","shouldAutoplayAfterBuffering","hasInitialBufferCompleted","shouldUseNativeHls","getStreamType","canNative","setupNativeHls","adBehavior","isLive","setupHls","import_hls2","backBufferLength","liveDurationInfinity","maxLiveSyncPlaybackRate","liveSyncDuration","maxBufferLength","maxMaxBufferLength","maxBufferSize","maxBufferHole","highBufferWatchdogPeriod","nudgeOffset","nudgeMaxRetry","startPosition","MEDIA_ATTACHED","_","_data","minSegments","details","live","onManifestParsed","minSegmentsBeforePlay","LEVEL_LOADED","_evt","hasPendingAdBreak","fragmentsToScan","fragments","tagList","isArray","idx","earlyDetection","FRAG_BUFFERED","FRAG_PARSING_METADATA","id3Tags","samples","pts","onId3Tag","FRAG_LOADED","processFragmentScte35Payload","FRAG_DECRYPTED","FRAG_CHANGED","activatePendingCuesForFragment","prog","ErrorTypes","NETWORK_ERROR","startLoad","MEDIA_ERROR","recoverMediaError","onFatalDestroy","payloadData","getLiveSyncPosition","liveSyncPosition","getAdAudioVolume","toggleMute","newMutedState","restoreVolume","toggleFullscreen","fullscreenElement","requestFullscreen","isMuted","setMuted","clampedVolume","getVolume","isFullscreen","resizePlayer","clientHeight","AdBreakOrchestrator","host","preloadPool","adConfig","placeholder","isShowingPlaceholder","adDetectSentForCurrentBreak","continuousFetchingActive","continuousFetchLoopRunning","adRequestQueue","adPodQueue"],"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/players/index.ts\nvar players_exports = {};\n__export(players_exports, {\n  default: () => players_default\n});\nmodule.exports = __toCommonJS(players_exports);\n\n// src/utils.ts\nvar import_react = require(\"react\");\nvar lazy = import_react.lazy;\nvar IS_BROWSER = typeof window !== \"undefined\" && window.document;\nvar IS_GLOBAL = typeof globalThis !== \"undefined\" && globalThis.window && globalThis.window.document;\nvar IS_IOS = IS_BROWSER && /iPad|iPhone|iPod/.test(navigator.userAgent);\nvar IS_SAFARI = IS_BROWSER && /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n\n// src/patterns.ts\nvar HLS_EXTENSIONS = /\\.(m3u8)($|\\?)/i;\nvar HLS_PATHS = /\\/hls\\//i;\nvar DASH_EXTENSIONS = /\\.(mpd)($|\\?)/i;\nvar VIDEO_EXTENSIONS = /\\.(mp4|webm|ogg|avi|mov|wmv|flv|mkv)($|\\?)/i;\nvar AUDIO_EXTENSIONS = /\\.(mp3|wav|ogg|aac|wma|flac|m4a)($|\\?)/i;\nvar canPlay = {\n  hls: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return HLS_EXTENSIONS.test(url) || HLS_PATHS.test(url);\n  },\n  dash: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return DASH_EXTENSIONS.test(url);\n  },\n  video: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return VIDEO_EXTENSIONS.test(url);\n  },\n  audio: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return AUDIO_EXTENSIONS.test(url);\n  },\n  file: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return VIDEO_EXTENSIONS.test(url) || AUDIO_EXTENSIONS.test(url);\n  }\n};\n\n// src/players/HlsPlayer.tsx\nvar import_react2 = require(\"react\");\n\n// src/sdk/hlsAdPlayer.ts\nvar import_hls = __toESM(require(\"hls.js\"), 1);\nvar MAX_VAST_WRAPPER_DEPTH = 5;\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 podAds = [];\n  let podIndex = 0;\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 isHlsMediaFile(mediaFile) {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return type === \"application/x-mpegurl\" || type === \"application/vnd.apple.mpegurl\" || type.includes(\"mpegurl\") || url.includes(\".m3u8\");\n  }\n  function isProgressiveMediaFile(mediaFile) {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return type.startsWith(\"video/\") || url.endsWith(\".mp4\") || url.includes(\".mp4?\");\n  }\n  function createEmptyTrackingUrls() {\n    return {\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  function extractTrackingUrls(scope) {\n    const trackingUrls = createEmptyTrackingUrls();\n    scope.querySelectorAll(\"Impression\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.impression.push(url);\n    });\n    scope.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    scope.querySelectorAll(\"Error\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.error.push(url);\n    });\n    return trackingUrls;\n  }\n  function mergeTrackingUrls(target, source) {\n    Object.keys(target).forEach((key) => {\n      if (source[key] && source[key].length > 0) {\n        target[key] = target[key].concat(source[key]);\n      }\n    });\n    return target;\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 { type: \"empty\" };\n      }\n      const adElement = xmlDoc.querySelector(\"Ad\");\n      if (!adElement) {\n        console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n        return { type: \"empty\" };\n      }\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n      const clickThrough = xmlDoc.querySelector(\"ClickThrough\")?.textContent?.trim();\n      const wrapperUri = xmlDoc.querySelector(\"VASTAdTagURI\")?.textContent?.trim();\n      if (wrapperUri) {\n        console.log(\n          `[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ${wrapperUri}`\n        );\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough\n        };\n      }\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        const mediaFile = {\n          url,\n          type,\n          width: parseInt(width || \"1920\", 10),\n          height: parseInt(height || \"1080\", 10),\n          bitrate: void 0\n        };\n        if (!url) {\n          console.warn(`[HlsAdPlayer] MediaFile ${index} has empty URL`);\n          return;\n        }\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n        mediaFile.bitrate = bitrateValue && bitrateValue > 0 ? bitrateValue : void 0;\n        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n          console.log(\n            `[HlsAdPlayer] Added ${isHlsMediaFile(mediaFile) ? \"HLS\" : \"progressive\"} MediaFile: ${url}`\n          );\n        } else {\n          console.log(\n            `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not supported)`\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 supported media files found in VAST XML\");\n        }\n        return { type: \"empty\" };\n      }\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough\n        }\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n      return { type: \"empty\" };\n    }\n  }\n  function parseAdElement(adElement) {\n    try {\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n      const clickThrough = adElement.querySelector(\"ClickThrough\")?.textContent?.trim();\n      const wrapperUri = adElement.querySelector(\"VASTAdTagURI\")?.textContent?.trim();\n      if (wrapperUri) {\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough\n        };\n      }\n      const isNoAdAvailable = adId === \"empty\" || title.toLowerCase().includes(\"no ad available\") || title.toLowerCase() === \"no ad available\";\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 + parseInt(durationParts[2] || \"0\", 10);\n      const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n      const mediaFiles = [];\n      mediaFileElements.forEach((mf) => {\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        if (!url) return;\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n        const mediaFile = {\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        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n        }\n      });\n      if (mediaFiles.length === 0) {\n        if (isNoAdAvailable) {\n          console.warn(\n            \"[HlsAdPlayer] Pod <Ad> indicates no ad available\"\n          );\n        } else {\n          console.warn(\"[HlsAdPlayer] No supported media files in pod <Ad>\");\n        }\n        return { type: \"empty\" };\n      }\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough\n        }\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing pod <Ad> element:\", error);\n      return { type: \"empty\" };\n    }\n  }\n  async function fetchVastXml(vastTagUrl) {\n    const response = await fetch(vastTagUrl, {\n      mode: \"cors\",\n      credentials: \"include\",\n      headers: {\n        \"Accept\": \"application/xml, text/xml, */*\"\n      },\n      referrerPolicy: \"no-referrer-when-downgrade\"\n    });\n    if (!response.ok) {\n      throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n    }\n    return response.text();\n  }\n  async function fetchAndParseVastAd(vastTagUrl, depth = 0, accumulatedTracking = createEmptyTrackingUrls()) {\n    const vastXml = await fetchVastXml(vastTagUrl);\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    const parsed = parseVastXml(vastXml);\n    if (parsed.type === \"empty\") {\n      return null;\n    }\n    if (parsed.type === \"wrapper\") {\n      if (depth >= MAX_VAST_WRAPPER_DEPTH) {\n        console.warn(\n          `[HlsAdPlayer] VAST wrapper depth limit (${MAX_VAST_WRAPPER_DEPTH}) reached, aborting redirect chain`\n        );\n        return null;\n      }\n      mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);\n      return fetchAndParseVastAd(\n        parsed.vastAdTagUri,\n        depth + 1,\n        accumulatedTracking\n      );\n    }\n    mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);\n    return parsed.ad;\n  }\n  async function fetchAndParsePod(vastTagUrl) {\n    const vastXml = await fetchVastXml(vastTagUrl);\n    console.log(\"[HlsAdPlayer] Pod VAST XML received\");\n    const parser = new DOMParser();\n    const xmlDoc = parser.parseFromString(vastXml, \"text/xml\");\n    if (xmlDoc.querySelector(\"parsererror\")) {\n      console.error(\"[HlsAdPlayer] Pod VAST XML parsing error (malformed)\");\n      return [];\n    }\n    const adElements = Array.from(xmlDoc.querySelectorAll(\"Ad\"));\n    if (adElements.length === 0) {\n      console.warn(\"[HlsAdPlayer] No <Ad> elements found in pod VAST response\");\n      return [];\n    }\n    adElements.sort((a, b) => {\n      const aSeq = parseInt(a.getAttribute(\"sequence\") || \"\", 10);\n      const bSeq = parseInt(b.getAttribute(\"sequence\") || \"\", 10);\n      const aVal = Number.isFinite(aSeq) ? aSeq : Number.MAX_SAFE_INTEGER;\n      const bVal = Number.isFinite(bSeq) ? bSeq : Number.MAX_SAFE_INTEGER;\n      return aVal - bVal;\n    });\n    const ads = [];\n    for (const adElement of adElements) {\n      const parsed = parseAdElement(adElement);\n      if (parsed.type === \"inline\") {\n        ads.push(parsed.ad);\n      } else if (parsed.type === \"wrapper\") {\n        try {\n          const resolved = await fetchAndParseVastAd(\n            parsed.vastAdTagUri,\n            1,\n            parsed.trackingUrls\n          );\n          if (resolved) {\n            ads.push(resolved);\n          }\n        } catch (error) {\n          console.warn(\n            \"[HlsAdPlayer] Failed to resolve wrapper <Ad> in pod:\",\n            error\n          );\n        }\n      }\n    }\n    console.log(`[HlsAdPlayer] Parsed ${ads.length} ad(s) from pod VAST response`);\n    return ads;\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      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\n      }\n      handleAdComplete();\n    });\n    adVideoElement.addEventListener(\"error\", (e) => {\n      if (!adPlaying) return;\n      console.error(\"[HlsAdPlayer] Ad video error:\", e);\n      if (currentAd) {\n        fireTrackingPixels(currentAd.trackingUrls.error);\n      }\n      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\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 resetQuartileTracking(preserveImpression) {\n    trackingFired = {\n      impression: preserveImpression ? trackingFired.impression : false,\n      start: false,\n      firstQuartile: false,\n      midpoint: false,\n      thirdQuartile: false,\n      complete: false\n    };\n  }\n  function loadCurrentAdMedia() {\n    if (!adVideoElement || !currentAd) {\n      throw new Error(\"No ad video element or ad to load\");\n    }\n    const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n    if (!mediaFile) {\n      throw new Error(\"No media file available for ad\");\n    }\n    const isHlsAd = isHlsMediaFile(mediaFile);\n    console.log(\n      `[HlsAdPlayer] Loading ${isHlsAd ? \"HLS\" : \"progressive\"} ad (pod ${podIndex + 1}/${podAds.length || 1}) from: ${mediaFile.url}`\n    );\n    if (isHlsAd && 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 (isHlsAd && 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 if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {\n      if (adHls) {\n        adHls.destroy();\n        adHls = void 0;\n      }\n      adVideoElement.src = mediaFile.url;\n      adVideoElement.load();\n      adVideoElement.play().catch((error) => {\n        console.error(\"[HlsAdPlayer] Error starting progressive ad playback:\", error);\n        handleAdError();\n      });\n    } else {\n      throw new Error(`Unsupported ad media file type: ${mediaFile.type}`);\n    }\n  }\n  function advanceToNextPodAd() {\n    if (podIndex >= podAds.length - 1) {\n      return false;\n    }\n    podIndex++;\n    currentAd = podAds[podIndex];\n    resetQuartileTracking(false);\n    if (currentAd) {\n      fireTrackingPixels(currentAd.trackingUrls.impression);\n      trackingFired.impression = true;\n      console.log(\n        `[HlsAdPlayer] Advancing to next pod ad (${podIndex + 1}/${podAds.length}): ${currentAd.title}, duration: ${currentAd.duration}s`\n      );\n    }\n    try {\n      loadCurrentAdMedia();\n      emit(\"pod_ad_started\", { index: podIndex, total: podAds.length });\n      return true;\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Failed to load next pod ad:\", error);\n      return false;\n    }\n  }\n  function handleAdComplete() {\n    console.log(\"[HlsAdPlayer] Handling ad completion\");\n    adPlaying = false;\n    setAdPlayingFlag(false);\n    contentVideo.muted = true;\n    if (adContainerEl) {\n      adContainerEl.style.display = \"none\";\n      adContainerEl.style.pointerEvents = \"none\";\n    }\n    if (options?.continueLiveStreamDuringAds) {\n      if (contentVideo.paused) {\n        console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback\");\n        contentVideo.play().catch(() => {\n        });\n      } else {\n        console.log(\"[HlsAdPlayer] Content video already playing in live mode\");\n      }\n    }\n    emit(\"content_resume\");\n  }\n  function handleAdError() {\n    console.log(\"[HlsAdPlayer] Handling ad error\");\n    adPlaying = false;\n    setAdPlayingFlag(false);\n    contentVideo.muted = true;\n    if (adContainerEl) {\n      adContainerEl.style.display = \"none\";\n      adContainerEl.style.pointerEvents = \"none\";\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 = \"30\";\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 ads = [];\n        if (preloadedAds.has(vastTagUrl)) {\n          const preloaded = preloadedAds.get(vastTagUrl);\n          preloadedAds.delete(vastTagUrl);\n          if (preloaded) {\n            ads = [preloaded];\n          }\n          console.log(\n            \"[HlsAdPlayer] Using preloaded VAST response:\",\n            vastTagUrl\n          );\n        } else {\n          ads = await fetchAndParsePod(vastTagUrl);\n        }\n        if (!ads.length) {\n          console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n          emit(\"ad_error\");\n          return Promise.reject(new Error(\"No ads available from VAST response\"));\n        }\n        podAds = ads;\n        podIndex = 0;\n        currentAd = ads[0];\n        console.log(\n          `[HlsAdPlayer] Pod parsed: ${ads.length} ad(s), first=\"${currentAd?.title}\", duration=${currentAd?.duration}s`\n        );\n        if (currentAd) {\n          fireTrackingPixels(currentAd.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 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        resetQuartileTracking(true);\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        adPlaying = true;\n        setAdPlayingFlag(true);\n        if (adVideoElement) {\n          adVideoElement.volume = Math.max(0, Math.min(1, originalVolume));\n          adVideoElement.muted = originalMutedState;\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        loadCurrentAdMedia();\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    pause() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n      try {\n        if (adVideoElement && !adVideoElement.paused) {\n          adVideoElement.pause();\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error pausing ad:\", error);\n      }\n    },\n    resume() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n      try {\n        if (adVideoElement && adVideoElement.paused) {\n          adVideoElement.play().catch(() => {\n          });\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error resuming ad:\", error);\n      }\n    },\n    async stop() {\n      console.log(\"[HlsAdPlayer] Stopping ad\");\n      adPlaying = false;\n      setAdPlayingFlag(false);\n      const previousMutedState = contentVideo.muted;\n      contentVideo.muted = originalMutedState;\n      contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n      console.log(\n        `[HlsAdPlayer] Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}, volume: ${contentVideo.volume}`\n      );\n      if (adContainerEl) {\n        adContainerEl.style.display = \"none\";\n        adContainerEl.style.pointerEvents = \"none\";\n      }\n      contentVideo.style.visibility = \"visible\";\n      contentVideo.style.opacity = \"1\";\n      if (options?.continueLiveStreamDuringAds) {\n        if (contentVideo.paused) {\n          console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback on stop\");\n          contentVideo.play().catch(() => {\n          });\n        }\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      podAds = [];\n      podIndex = 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 = Math.max(0, Math.min(1, 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      podAds = [];\n      podIndex = 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        const clamped = Math.max(0, Math.min(1, volume));\n        adVideoElement.volume = clamped;\n        adVideoElement.muted = clamped === 0;\n      }\n    },\n    getAdVolume() {\n      if (adVideoElement && adPlaying) {\n        return adVideoElement.volume;\n      }\n      return 1;\n    },\n    showPlaceholder() {\n      contentVideo.style.opacity = \"0\";\n      contentVideo.style.visibility = \"hidden\";\n      if (!adContainerEl) {\n        const container = document.createElement(\"div\");\n        container.style.position = \"absolute\";\n        container.style.left = \"0\";\n        container.style.top = \"0\";\n        container.style.right = \"0\";\n        container.style.bottom = \"0\";\n        container.style.display = \"none\";\n        container.style.alignItems = \"center\";\n        container.style.justifyContent = \"center\";\n        container.style.pointerEvents = \"none\";\n        container.style.zIndex = \"10\";\n        container.style.backgroundColor = \"#000\";\n        contentVideo.parentElement?.appendChild(container);\n        adContainerEl = container;\n      }\n      if (adContainerEl) {\n        adContainerEl.style.display = \"flex\";\n        adContainerEl.style.pointerEvents = \"auto\";\n      }\n    },\n    hidePlaceholder() {\n      if (adContainerEl) {\n        adContainerEl.style.display = \"none\";\n        adContainerEl.style.pointerEvents = \"none\";\n      }\n      if (!adPlaying) {\n        contentVideo.style.visibility = \"visible\";\n        contentVideo.style.opacity = \"1\";\n      }\n    },\n    getLoadedAdDuration() {\n      return currentAd?.duration;\n    },\n    getLoadedAdId() {\n      return currentAd?.id;\n    },\n    getPodAdCount() {\n      return podAds.length;\n    },\n    getPodTotalDurationMs() {\n      return podAds.reduce(\n        (total, ad) => total + (ad.duration > 0 ? ad.duration * 1e3 : 0),\n        0\n      );\n    }\n  };\n}\n\n// src/sdk/pal.ts\nvar PAL_SDK_URL = \"https://imasdk.googleapis.com/pal/sdkloader/pal.js\";\nvar _nonceLoader;\nvar _palLoadPromise;\nfunction loadPalSdk() {\n  if (typeof window !== \"undefined\" && window.goog?.pal) {\n    return Promise.resolve();\n  }\n  if (_palLoadPromise) return _palLoadPromise;\n  _palLoadPromise = new Promise((resolve, reject) => {\n    const existing = document.querySelector(\n      'script[data-pal=\"true\"]'\n    );\n    if (existing) {\n      if (window.goog?.pal) {\n        resolve();\n        return;\n      }\n      const timeout = setTimeout(\n        () => reject(new Error(\"PAL SDK load timeout\")),\n        1e4\n      );\n      existing.addEventListener(\"load\", () => {\n        clearTimeout(timeout);\n        resolve();\n      });\n      existing.addEventListener(\"error\", () => {\n        clearTimeout(timeout);\n        reject(new Error(\"PAL SDK load failed\"));\n      });\n      return;\n    }\n    const script = document.createElement(\"script\");\n    script.src = PAL_SDK_URL;\n    script.async = true;\n    script.setAttribute(\"data-pal\", \"true\");\n    script.onload = () => resolve();\n    script.onerror = () => reject(new Error(\"PAL SDK load failed\"));\n    document.head.appendChild(script);\n  });\n  return _palLoadPromise;\n}\nfunction getOrCreateNonceLoader() {\n  if (_nonceLoader) return _nonceLoader;\n  const goog = window.goog;\n  const consentSettings = new goog.pal.ConsentSettings();\n  consentSettings.allowStorage = true;\n  _nonceLoader = new goog.pal.NonceLoader(consentSettings);\n  return _nonceLoader;\n}\nfunction createPalNonceManager() {\n  let currentNonce = \"\";\n  let currentNonceManager;\n  return {\n    async generateNonce(options = {}) {\n      try {\n        await loadPalSdk();\n        const loader = getOrCreateNonceLoader();\n        const goog = window.goog;\n        const request = new goog.pal.NonceRequest();\n        request.adWillAutoPlay = options.adWillAutoPlay ?? true;\n        request.adWillPlayMuted = options.adWillPlayMuted ?? false;\n        request.playerVolume = options.playerVolume ?? (request.adWillPlayMuted ? 0 : 1);\n        request.continuousPlayback = options.continuousPlayback ?? true;\n        request.descriptionUrl = options.descriptionUrl || (typeof window !== \"undefined\" ? window.location.href : \"\");\n        request.iconsSupported = true;\n        request.playerType = \"StormcloudVideoPlayer\";\n        request.playerVersion = \"1.0\";\n        request.supportedApiFrameworks = \"2,7,9\";\n        request.url = options.descriptionUrl || (typeof window !== \"undefined\" ? window.location.href : \"\");\n        request.videoWidth = options.videoWidth || 640;\n        request.videoHeight = options.videoHeight || 480;\n        if (options.ppid) request.ppid = options.ppid;\n        if (options.sessionId) request.sessionId = options.sessionId;\n        const manager = await loader.loadNonceManager(request);\n        currentNonceManager = manager;\n        currentNonce = manager.getNonce();\n        console.log(\"[PAL] Nonce generated successfully\");\n        return currentNonce;\n      } catch (error) {\n        console.warn(\"[PAL] Failed to generate nonce:\", error);\n        currentNonce = \"\";\n        currentNonceManager = void 0;\n        return \"\";\n      }\n    },\n    getCurrentNonce() {\n      return currentNonce;\n    },\n    injectNonce(vastTagUrl) {\n      if (!currentNonce || !vastTagUrl) return vastTagUrl;\n      try {\n        const url = new URL(vastTagUrl);\n        url.searchParams.delete(\"paln\");\n        url.searchParams.set(\"givn\", currentNonce);\n        return url.toString();\n      } catch {\n        let base = vastTagUrl.replace(/([?&])paln=[^&]*/g, \"\").replace(/[?&]$/, \"\");\n        const sep = base.includes(\"?\") ? \"&\" : \"?\";\n        return `${base}${sep}givn=${encodeURIComponent(currentNonce)}`;\n      }\n    },\n    sendPlaybackStart() {\n      try {\n        currentNonceManager?.sendPlaybackStart();\n      } catch {\n      }\n    },\n    sendPlaybackEnd() {\n      try {\n        currentNonceManager?.sendPlaybackEnd();\n      } catch {\n      }\n    },\n    sendAdClick() {\n      try {\n        currentNonceManager?.sendAdClick();\n      } catch {\n      }\n    },\n    sendAdTouch(event) {\n      try {\n        currentNonceManager?.sendAdTouch(event);\n      } catch {\n      }\n    },\n    reset() {\n      currentNonce = \"\";\n      currentNonceManager = void 0;\n    }\n  };\n}\n\n// src/utils/mqttConfig.ts\nvar DEFAULT_MQTT_CONFIG = {\n  enabled: true,\n  brokerAddress: \"vecbae77.ala.us-east-1.emqxsl.com\",\n  brokerPort: 8883,\n  wsPort: 8084,\n  username: \"for-sonifi\",\n  password: \"sonifi-mqtt\",\n  topicPrefix: \"adstorm/players\",\n  qos: 1\n};\nvar mqttConfig = { ...DEFAULT_MQTT_CONFIG };\nfunction isMQTTEnabled() {\n  return mqttConfig.enabled;\n}\nfunction buildMQTTBrokerUrl() {\n  if (mqttConfig.brokerUrl) return mqttConfig.brokerUrl;\n  return `wss://${mqttConfig.brokerAddress}:${mqttConfig.wsPort}/mqtt`;\n}\nfunction buildPlayerTopic(licenseKey, channel) {\n  return `${mqttConfig.topicPrefix}/${licenseKey}/${channel}`;\n}\n\n// src/utils/mqttClient.ts\nvar import_mqtt = __toESM(require(\"mqtt\"), 1);\nvar LOG = \"[StormcloudVideoPlayer][MQTT]\";\nvar client = null;\nvar status = \"disconnected\";\nfunction initMQTTClient() {\n  if (client || !isMQTTEnabled()) return;\n  const url = buildMQTTBrokerUrl();\n  status = \"connecting\";\n  const clientId = `stormcloud-vp-${Math.random().toString(36).slice(2, 9)}`;\n  try {\n    client = import_mqtt.default.connect(url, {\n      clientId,\n      username: mqttConfig.username,\n      password: mqttConfig.password,\n      keepalive: 60,\n      clean: true,\n      reconnectPeriod: 5e3,\n      connectTimeout: 1e4,\n      queueQoSZero: false\n    });\n  } catch (err) {\n    status = \"error\";\n    console.warn(`${LOG} connect() threw:`, err);\n    return;\n  }\n  client.on(\"connect\", () => {\n    status = \"connected\";\n    console.info(`${LOG} connected to ${url}`);\n  });\n  client.on(\"reconnect\", () => {\n    status = \"connecting\";\n    console.info(`${LOG} reconnecting\\u2026`);\n  });\n  client.on(\"offline\", () => {\n    status = \"disconnected\";\n    console.warn(`${LOG} offline`);\n  });\n  client.on(\"error\", (err) => {\n    status = \"error\";\n    console.warn(`${LOG} error:`, err.message);\n  });\n  client.on(\"close\", () => {\n    if (status === \"connected\") {\n      status = \"disconnected\";\n    }\n  });\n}\nfunction ensureMQTTClient() {\n  if (isMQTTEnabled() && !client) {\n    initMQTTClient();\n  }\n}\nfunction publishMQTT(topic, payload) {\n  if (!isMQTTEnabled()) {\n    return false;\n  }\n  ensureMQTTClient();\n  if (!client) {\n    return false;\n  }\n  try {\n    client.publish(topic, JSON.stringify(payload), { qos: mqttConfig.qos });\n    return true;\n  } catch (err) {\n    console.warn(`${LOG} publish failed on ${topic}:`, err);\n    return false;\n  }\n}\n\n// src/utils/vastEnvironmentSignals.ts\nvar AIRY_ANDROID_APP_ID = \"com.freeairytv.android\";\nvar AIRY_WEBOS_APP_ID = \"com.freeairytv.webos\";\nvar AIRY_TIZEN_APP_ID = \"com.freeairytv.samsung\";\nvar AIRY_ROKU_APP_ID = \"com.freeairytv.roku\";\nvar AIRY_APP_NAME = \"AiryTV Movies & TV\";\nvar AIRY_DEFAULT_CONTENT_URL = \"https://live.airy.tv\";\nvar CTV_SESSION_STORAGE_KEY = \"stormcloud.ctv.sid\";\nvar PLAYER_ID_STORAGE_KEY = \"stormcloud.player.id\";\nvar LG_TEST_APP_ID = \"com.hulu.plus\";\nvar LG_TEST_APP_NAME = \"Hulu\";\nvar LG_TEST_CONTENT_URL = \"https://www.hulu.com/live-tv\";\nvar _lgTestDeviceId;\nfunction getLgTestDeviceId() {\n  if (!_lgTestDeviceId) _lgTestDeviceId = createUuid();\n  return _lgTestDeviceId;\n}\nfunction isLgWebOS() {\n  if (typeof navigator === \"undefined\") return false;\n  return /Web0S|webOS|LG Browser|LGSTB|LGE/i.test(navigator.userAgent);\n}\nfunction getDefaultAppId() {\n  if (typeof navigator === \"undefined\") return AIRY_ANDROID_APP_ID;\n  const ua = navigator.userAgent;\n  if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;\n  if (/Tizen|Samsung/i.test(ua)) return AIRY_TIZEN_APP_ID;\n  if (/Roku/i.test(ua)) return AIRY_ROKU_APP_ID;\n  return AIRY_ANDROID_APP_ID;\n}\nvar DEVICE_ID_STORAGE_KEYS = [\n  \"rdid\",\n  \"ifa\",\n  \"advertisingId\",\n  \"advertising_id\",\n  \"deviceAdvertisingId\",\n  \"aaid\",\n  \"adid\",\n  \"rida\",\n  \"tifa\",\n  \"lgudid\"\n];\nvar ANDROID_ID_TYPES = /* @__PURE__ */ new Set([\"aaid\", \"adid\"]);\nfunction resolveVastEnvironmentSignals(isCtv) {\n  const bridgeSignals = readNativeBridgeSignals();\n  const platformDevice = readPlatformNativeDeviceId();\n  const lg = isCtv && isLgWebOS();\n  const deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId || (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : void 0);\n  const deviceIdType = bridgeSignals.deviceIdType || readStoredString(\"deviceIdType\") || readStoredString(\"idtype\") || platformDevice.deviceIdType || inferDeviceIdType() || (lg ? \"lgudid\" : void 0);\n  const platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;\n  const limitAdTracking = deviceId != null ? platformLat ?? readStoredLimitAdTracking() ?? false : void 0;\n  if (isCtv) {\n    return {\n      isCtv: true,\n      contentUrl: bridgeSignals.contentUrl || readStoredString(\"contentUrl\") || (lg ? LG_TEST_CONTENT_URL : AIRY_DEFAULT_CONTENT_URL),\n      appId: bridgeSignals.appId || readStoredString(\"appId\") || readStoredString(\"msid\") || (lg ? LG_TEST_APP_ID : getDefaultAppId()),\n      appName: bridgeSignals.appName || readStoredString(\"appName\") || readStoredString(\"an\") || (lg ? LG_TEST_APP_NAME : AIRY_APP_NAME),\n      sessionId: getOrCreateCtvSessionId(),\n      ...deviceId ? { deviceId } : {},\n      ...deviceIdType ? { deviceIdType } : {},\n      ...limitAdTracking != null ? { limitAdTracking } : {},\n      deviceTypeHint: 5\n    };\n  }\n  return {\n    isCtv: false,\n    ...deviceId ? { deviceId } : {},\n    ...deviceIdType ? { deviceIdType } : {},\n    ...limitAdTracking != null ? { limitAdTracking } : {}\n  };\n}\nfunction inferDeviceIdType() {\n  if (typeof navigator === \"undefined\") {\n    return void 0;\n  }\n  const ua = navigator.userAgent;\n  if (/Roku/i.test(ua)) return \"rida\";\n  if (/Tizen|Samsung/i.test(ua)) return \"tifa\";\n  if (/AppleTV|Apple TV/i.test(ua)) return \"tvOS\";\n  if (/AFT|Fire TV|Amazon/i.test(ua)) return \"afai\";\n  if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return \"lgudid\";\n  if (/Android|Google TV/i.test(ua)) return \"aaid\";\n  if (/iPhone|iPad|iPod/i.test(ua)) return \"idfa\";\n  return void 0;\n}\nfunction isEquivalentDeviceIdType(tagType, runtimeType) {\n  if (!tagType || !runtimeType) return false;\n  const tag = tagType.toLowerCase();\n  const runtime = runtimeType.toLowerCase();\n  if (tag === runtime) return true;\n  return ANDROID_ID_TYPES.has(tag) && ANDROID_ID_TYPES.has(runtime);\n}\nfunction resolveNativeDeviceId() {\n  const bridgeSignals = readNativeBridgeSignals();\n  const platformDevice = readPlatformNativeDeviceId();\n  const deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId;\n  if (!deviceId || isMacroPlaceholder(deviceId) || isZeroedAdId(deviceId)) {\n    return void 0;\n  }\n  return deviceId;\n}\nfunction getOrCreateStoredUuid(storageKey) {\n  if (typeof window === \"undefined\") {\n    return void 0;\n  }\n  const existing = readPersistentId(storageKey);\n  if (existing) {\n    writePersistentId(storageKey, existing);\n    return existing;\n  }\n  const id = createUuid();\n  writePersistentId(storageKey, id);\n  return id;\n}\nfunction getOrCreateCtvSessionId() {\n  const existing = readPersistentId(CTV_SESSION_STORAGE_KEY);\n  if (existing) {\n    writePersistentId(CTV_SESSION_STORAGE_KEY, existing);\n    return existing;\n  }\n  const sessionId = createUuid();\n  writePersistentId(CTV_SESSION_STORAGE_KEY, sessionId);\n  return sessionId;\n}\nfunction readPersistentId(storageKey) {\n  return readStoredString(storageKey) || readCookie(storageKey);\n}\nfunction writePersistentId(storageKey, value) {\n  try {\n    window.localStorage?.setItem(storageKey, value);\n  } catch {\n  }\n  writeCookie(storageKey, value);\n}\nvar PERSISTENT_ID_COOKIE_MAX_AGE = 60 * 60 * 24 * 365 * 5;\nfunction readCookie(name) {\n  if (typeof document === \"undefined\") {\n    return void 0;\n  }\n  try {\n    const prefix = encodeURIComponent(name) + \"=\";\n    const parts = document.cookie ? document.cookie.split(\";\") : [];\n    for (const part of parts) {\n      const entry = part.trim();\n      if (entry.startsWith(prefix)) {\n        return decodeURIComponent(entry.slice(prefix.length)) || void 0;\n      }\n    }\n  } catch {\n  }\n  return void 0;\n}\nfunction writeCookie(name, value) {\n  if (typeof document === \"undefined\") {\n    return;\n  }\n  try {\n    document.cookie = encodeURIComponent(name) + \"=\" + encodeURIComponent(value) + \";path=/;max-age=\" + PERSISTENT_ID_COOKIE_MAX_AGE + \";SameSite=Lax\";\n  } catch {\n  }\n}\nfunction createUuid() {\n  if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n    return crypto.randomUUID();\n  }\n  const bytes = new Uint8Array(16);\n  if (typeof crypto !== \"undefined\" && typeof crypto.getRandomValues === \"function\") {\n    crypto.getRandomValues(bytes);\n  } else {\n    let seed = Date.now() ^ Math.floor(performanceNow() * 1e3);\n    for (let i = 0; i < 16; i++) {\n      seed = seed * 1103515245 + 12345 & 2147483647;\n      bytes[i] = (seed ^ Math.floor(Math.random() * 256)) & 255;\n    }\n  }\n  bytes[6] = (bytes[6] ?? 0) & 15 | 64;\n  bytes[8] = (bytes[8] ?? 0) & 63 | 128;\n  let hex = \"\";\n  for (let i = 0; i < 16; i++) {\n    hex += (bytes[i] ?? 0).toString(16).padStart(2, \"0\");\n  }\n  return hex.slice(0, 8) + \"-\" + hex.slice(8, 12) + \"-\" + hex.slice(12, 16) + \"-\" + hex.slice(16, 20) + \"-\" + hex.slice(20, 32);\n}\nfunction performanceNow() {\n  try {\n    if (typeof performance !== \"undefined\" && typeof performance.now === \"function\") {\n      return performance.now();\n    }\n  } catch {\n  }\n  return 0;\n}\nfunction readPlatformNativeDeviceId() {\n  if (typeof window === \"undefined\") return {};\n  try {\n    const adinfo = window.webapis?.adinfo;\n    if (adinfo) {\n      const tifa = typeof adinfo.getTIFA === \"function\" ? adinfo.getTIFA() : adinfo.tifa;\n      if (typeof tifa === \"string\" && tifa && !isMacroPlaceholder(tifa)) {\n        const lat = typeof adinfo.isLATEnabled === \"function\" ? adinfo.isLATEnabled() : void 0;\n        return {\n          deviceId: tifa,\n          deviceIdType: \"tifa\",\n          ...typeof lat === \"boolean\" ? { limitAdTracking: lat } : {}\n        };\n      }\n    }\n  } catch {\n  }\n  try {\n    const webOSDev = window.webOSDev;\n    if (webOSDev) {\n      const lgudid = typeof webOSDev.LGUDID === \"function\" ? webOSDev.LGUDID() : webOSDev.lgudid ?? webOSDev.LGUDID;\n      if (typeof lgudid === \"string\" && lgudid) {\n        if (isZeroedAdId(lgudid)) {\n          return { deviceIdType: \"lgudid\", limitAdTracking: true };\n        }\n        if (!isMacroPlaceholder(lgudid)) {\n          return { deviceId: lgudid, deviceIdType: \"lgudid\", limitAdTracking: false };\n        }\n      }\n    }\n  } catch {\n  }\n  try {\n    const roku = window.Roku;\n    if (roku) {\n      const rida = typeof roku.getPublisherUniqueId === \"function\" ? roku.getPublisherUniqueId() : roku.rida;\n      if (typeof rida === \"string\" && rida && !isMacroPlaceholder(rida)) {\n        return { deviceId: rida, deviceIdType: \"rida\", limitAdTracking: false };\n      }\n    }\n  } catch {\n  }\n  return {};\n}\nvar ZEROED_AD_ID_PATTERNS = /* @__PURE__ */ new Set([\n  \"38400000-8cf0-11bd-b23e-10b96e40000d\",\n  \"00000000-0000-0000-0000-000000000000\"\n]);\nfunction isMacroPlaceholder(value) {\n  const t = value.trim();\n  return !t || /^(\\[[^\\]]*\\]|\\{[^}]*\\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\\/a|\\$\\{[^}]+\\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());\n}\nfunction isZeroedAdId(value) {\n  return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());\n}\nfunction readNativeBridgeSignals() {\n  if (typeof window === \"undefined\") {\n    return {};\n  }\n  const candidates = [\n    window.__STORMCLOUD_CTV_AD_INFO__,\n    window.__STORMCLOUD_CTV__,\n    window.stormcloudCtv,\n    window.AiryTV,\n    window.Android,\n    window.webOS,\n    window.tizen,\n    window.amazon\n  ].filter(Boolean);\n  for (const source of candidates) {\n    const contentUrl = readBridgeValue(source, [\"contentUrl\", \"url\", \"videoUrl\", \"canonicalUrl\"]) || void 0;\n    const appId = readBridgeValue(source, [\"appId\", \"msid\", \"applicationId\", \"packageName\"]) || void 0;\n    const appName = readBridgeValue(source, [\"appName\", \"an\", \"applicationName\"]) || void 0;\n    const deviceId = readBridgeValue(source, [\n      \"rdid\",\n      \"ifa\",\n      \"advertisingId\",\n      \"adId\",\n      \"deviceId\",\n      \"lgudid\",\n      \"LGUDID\",\n      \"tifa\",\n      \"rida\",\n      \"afai\",\n      \"aaid\"\n    ]) || void 0;\n    if (!contentUrl && !deviceId && !appId && !appName) continue;\n    const deviceIdType = readBridgeValue(source, [\n      \"idtype\",\n      \"deviceIdType\",\n      \"advertisingIdType\",\n      \"idType\"\n    ]) || inferDeviceIdType();\n    const limitAdTracking = readBridgeBoolean(source, [\n      \"is_lat\",\n      \"limitAdTracking\",\n      \"limitedAdTracking\",\n      \"lat\"\n    ]);\n    return {\n      ...contentUrl ? { contentUrl } : {},\n      ...appId ? { appId } : {},\n      ...appName ? { appName } : {},\n      ...deviceId ? { deviceId } : {},\n      ...deviceId && deviceIdType ? { deviceIdType } : {},\n      ...deviceId && limitAdTracking != null ? { limitAdTracking } : {}\n    };\n  }\n  return {};\n}\nfunction readBridgeValue(source, keys) {\n  for (const key of keys) {\n    const value = source?.[key];\n    if (typeof value === \"string\" && value) {\n      return value;\n    }\n    if (typeof value === \"function\") {\n      try {\n        const result = value.call(source);\n        if (typeof result === \"string\" && result) {\n          return result;\n        }\n      } catch {\n      }\n    }\n  }\n  return void 0;\n}\nfunction readBridgeBoolean(source, keys) {\n  for (const key of keys) {\n    const value = source?.[key];\n    const normalized = normalizeBoolean(value);\n    if (normalized != null) {\n      return normalized;\n    }\n    if (typeof value === \"function\") {\n      try {\n        const result = normalizeBoolean(value.call(source));\n        if (result != null) {\n          return result;\n        }\n      } catch {\n      }\n    }\n  }\n  return void 0;\n}\nfunction readStoredDeviceId() {\n  for (const key of DEVICE_ID_STORAGE_KEYS) {\n    const value = readStoredString(key);\n    if (value) {\n      return value;\n    }\n  }\n  return void 0;\n}\nfunction readStoredString(key) {\n  if (typeof window === \"undefined\") {\n    return void 0;\n  }\n  try {\n    const value = window.localStorage?.getItem(key);\n    return value || void 0;\n  } catch {\n    return void 0;\n  }\n}\nfunction readStoredLimitAdTracking() {\n  return normalizeBoolean(\n    readStoredString(\"limitAdTracking\") || readStoredString(\"limitedAdTracking\") || readStoredString(\"is_lat\")\n  );\n}\nfunction normalizeBoolean(value) {\n  if (typeof value === \"boolean\") {\n    return value;\n  }\n  if (typeof value === \"number\") {\n    return value === 1;\n  }\n  if (typeof value === \"string\") {\n    const normalized = value.toLowerCase();\n    if (normalized === \"1\" || normalized === \"true\" || normalized === \"yes\") {\n      return true;\n    }\n    if (normalized === \"0\" || normalized === \"false\" || normalized === \"no\") {\n      return false;\n    }\n  }\n  return void 0;\n}\n\n// src/utils/tracking.ts\nvar cachedBrowserId = null;\nfunction buildAnalyticsContext(config) {\n  const context = {};\n  if (config.debugAdTiming) {\n    context.debugAdTiming = true;\n  }\n  if (config.isLiveStream !== void 0) {\n    context.inputStreamType = config.isLiveStream ? \"live\" : \"vod\";\n  }\n  return context;\n}\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 sha256Hex(input) {\n  if (typeof crypto !== \"undefined\" && 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(input);\n      } else {\n        const utf8 = unescape(encodeURIComponent(input));\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      return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n    } catch {\n      console.warn(\n        \"[StormcloudVideoPlayer] crypto.subtle not supported, using fallback hash\"\n      );\n    }\n  }\n  let hash = 0;\n  for (let i = 0; i < input.length; i++) {\n    const char = input.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  return (fallbackHash + timestamp + random).padEnd(64, \"0\");\n}\nfunction resolvePlayerIdentitySeed(clientInfo) {\n  const nativeDeviceId = resolveNativeDeviceId();\n  if (nativeDeviceId) {\n    return `device:${nativeDeviceId}`;\n  }\n  const persistedId = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);\n  if (persistedId) {\n    return `persisted:${persistedId}`;\n  }\n  return `fingerprint:${JSON.stringify(clientInfo)}`;\n}\nasync function getBrowserID(clientInfo) {\n  if (cachedBrowserId) {\n    return cachedBrowserId;\n  }\n  cachedBrowserId = await sha256Hex(resolvePlayerIdentitySeed(clientInfo));\n  return cachedBrowserId;\n}\nfunction canPublish(licenseKey) {\n  return Boolean(isMQTTEnabled() && licenseKey);\n}\nasync function buildPlayerMetricEvent(context = {}, flags = {}) {\n  const clientInfo = getClientInfo();\n  const debugAdTiming = !!context.debugAdTiming;\n  if (debugAdTiming) {\n    console.log(\"[StormcloudVideoPlayer] clientInfo: \", JSON.stringify(clientInfo, null, 2));\n  }\n  const playerId = await getBrowserID(clientInfo);\n  if (debugAdTiming) {\n    console.log(\"[StormcloudVideoPlayer] playerId: \", playerId);\n  }\n  const captureAt = flags.captureAt ?? (/* @__PURE__ */ new Date()).toISOString();\n  return {\n    player_id: playerId,\n    device_type: clientInfo.deviceType,\n    os: clientInfo.os.toLowerCase(),\n    ad_loaded: flags.adLoaded ?? false,\n    ad_detect: flags.adDetect ?? false,\n    capture_at: captureAt,\n    ...context.inputStreamType ? { input_stream_type: context.inputStreamType } : {}\n  };\n}\nfunction publishTracking(licenseKey, channel, body) {\n  ensureMQTTClient();\n  publishMQTT(buildPlayerTopic(licenseKey, channel), body);\n}\nasync function sendInitialTracking(licenseKey, context = {}) {\n  if (!canPublish(licenseKey)) return;\n  try {\n    const metricEvent = await buildPlayerMetricEvent(context, {\n      adLoaded: false,\n      adDetect: false\n    });\n    publishTracking(licenseKey, \"metrics\", {\n      events: [metricEvent]\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n      error\n    );\n  }\n}\nasync function sendAdDetectTracking(licenseKey, adDetectInfo, context = {}) {\n  try {\n    await sendHeartbeat(licenseKey, context, {\n      adDetect: true,\n      captureAt: adDetectInfo.timestamp\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n      error\n    );\n  }\n}\nasync function sendAdLoadedTracking(licenseKey, adLoadedInfo, context = {}) {\n  try {\n    await sendHeartbeat(licenseKey, context, {\n      adLoaded: true,\n      captureAt: adLoadedInfo.timestamp\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n      error\n    );\n  }\n}\nasync function sendAdImpressionTracking(licenseKey, adImpressionInfo, context = {}) {\n  if (!canPublish(licenseKey)) return;\n  try {\n    const metricEvent = await buildPlayerMetricEvent(context, {\n      captureAt: adImpressionInfo.timestamp\n    });\n    publishTracking(licenseKey, \"heartbeat\", metricEvent);\n    publishTracking(licenseKey, \"impressions\", {\n      events: [\n        {\n          player_id: metricEvent.player_id,\n          ad_played_count: 1,\n          ad_url: adImpressionInfo.adUrl,\n          capture_at: adImpressionInfo.timestamp\n        }\n      ]\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n      error\n    );\n  }\n}\nasync function sendHeartbeat(licenseKey, context = {}, flags = {}) {\n  if (!canPublish(licenseKey)) return;\n  try {\n    const heartbeatData = await buildPlayerMetricEvent(context, flags);\n    publishTracking(licenseKey, \"heartbeat\", heartbeatData);\n  } catch (error) {\n    console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n  }\n}\n\n// src/utils/polyfills.ts\nfunction polyfillURLSearchParams() {\n  if (typeof URLSearchParams !== \"undefined\") {\n    return;\n  }\n  class URLSearchParamsPolyfill {\n    constructor(init) {\n      this.params = /* @__PURE__ */ new Map();\n      if (typeof init === \"string\") {\n        this.parseQueryString(init);\n      } else if (init instanceof URLSearchParamsPolyfill) {\n        init.forEach((value, key) => {\n          this.append(key, value);\n        });\n      }\n    }\n    parseQueryString(query) {\n      const cleanQuery = query.startsWith(\"?\") ? query.slice(1) : query;\n      if (!cleanQuery) return;\n      cleanQuery.split(\"&\").forEach((param) => {\n        const [key, value] = param.split(\"=\");\n        if (key) {\n          const decodedKey = this.safeDecodeURIComponent(key);\n          const decodedValue = value ? this.safeDecodeURIComponent(value) : \"\";\n          this.append(decodedKey, decodedValue);\n        }\n      });\n    }\n    safeDecodeURIComponent(str) {\n      try {\n        return decodeURIComponent(str.replace(/\\+/g, \" \"));\n      } catch (e) {\n        return str;\n      }\n    }\n    append(name, value) {\n      const values = this.params.get(name) || [];\n      values.push(String(value));\n      this.params.set(name, values);\n    }\n    delete(name) {\n      this.params.delete(name);\n    }\n    get(name) {\n      const values = this.params.get(name);\n      return values && values.length > 0 && values[0] !== void 0 ? values[0] : null;\n    }\n    getAll(name) {\n      return this.params.get(name) || [];\n    }\n    has(name) {\n      return this.params.has(name);\n    }\n    set(name, value) {\n      this.params.set(name, [String(value)]);\n    }\n    forEach(callback) {\n      this.params.forEach((values, key) => {\n        values.forEach((value) => {\n          callback(value, key, this);\n        });\n      });\n    }\n    toString() {\n      const parts = [];\n      this.params.forEach((values, key) => {\n        values.forEach((value) => {\n          parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\n        });\n      });\n      return parts.join(\"&\");\n    }\n  }\n  window.URLSearchParams = URLSearchParamsPolyfill;\n}\nfunction polyfillTextEncoder() {\n  if (typeof TextEncoder !== \"undefined\") {\n    return;\n  }\n  class TextEncoderPolyfill {\n    constructor() {\n      this.encoding = \"utf-8\";\n    }\n    encode(str) {\n      const utf8 = [];\n      for (let i = 0; i < str.length; i++) {\n        let charcode = str.charCodeAt(i);\n        if (charcode < 128) {\n          utf8.push(charcode);\n        } else if (charcode < 2048) {\n          utf8.push(192 | charcode >> 6, 128 | charcode & 63);\n        } else if (charcode < 55296 || charcode >= 57344) {\n          utf8.push(\n            224 | charcode >> 12,\n            128 | charcode >> 6 & 63,\n            128 | charcode & 63\n          );\n        } else {\n          i++;\n          charcode = 65536 + ((charcode & 1023) << 10 | str.charCodeAt(i) & 1023);\n          utf8.push(\n            240 | charcode >> 18,\n            128 | charcode >> 12 & 63,\n            128 | charcode >> 6 & 63,\n            128 | charcode & 63\n          );\n        }\n      }\n      return new Uint8Array(utf8);\n    }\n  }\n  window.TextEncoder = TextEncoderPolyfill;\n}\nfunction polyfillPromiseFinally() {\n  if (typeof Promise !== \"undefined\" && !Promise.prototype.finally) {\n    Promise.prototype.finally = function(callback) {\n      const constructor = this.constructor;\n      return this.then(\n        (value) => constructor.resolve(callback()).then(() => value),\n        (reason) => constructor.resolve(callback()).then(() => {\n          throw reason;\n        })\n      );\n    };\n  }\n}\nfunction polyfillObjectAssign() {\n  if (typeof Object.assign !== \"function\") {\n    Object.assign = function(target, ...sources) {\n      if (target == null) {\n        throw new TypeError(\"Cannot convert undefined or null to object\");\n      }\n      const to = Object(target);\n      for (let i = 0; i < sources.length; i++) {\n        const nextSource = sources[i];\n        if (nextSource != null) {\n          for (const nextKey in nextSource) {\n            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n              to[nextKey] = nextSource[nextKey];\n            }\n          }\n        }\n      }\n      return to;\n    };\n  }\n}\nfunction polyfillArrayFrom() {\n  if (!Array.from) {\n    Array.from = function(arrayLike, mapFn, thisArg) {\n      const items = Object(arrayLike);\n      if (arrayLike == null) {\n        throw new TypeError(\"Array.from requires an array-like object\");\n      }\n      const len = items.length >>> 0;\n      const result = new Array(len);\n      for (let i = 0; i < len; i++) {\n        if (mapFn) {\n          result[i] = mapFn.call(thisArg, items[i], i);\n        } else {\n          result[i] = items[i];\n        }\n      }\n      return result;\n    };\n  }\n}\nfunction polyfillStringStartsWith() {\n  if (!String.prototype.startsWith) {\n    String.prototype.startsWith = function(search, pos) {\n      pos = !pos || pos < 0 ? 0 : +pos;\n      return this.substring(pos, pos + search.length) === search;\n    };\n  }\n}\nfunction polyfillStringEndsWith() {\n  if (!String.prototype.endsWith) {\n    String.prototype.endsWith = function(search, length) {\n      if (length === void 0 || length > this.length) {\n        length = this.length;\n      }\n      return this.substring(length - search.length, length) === search;\n    };\n  }\n}\nfunction polyfillStringIncludes() {\n  if (!String.prototype.includes) {\n    String.prototype.includes = function(search, start) {\n      if (typeof start !== \"number\") {\n        start = 0;\n      }\n      if (start + search.length > this.length) {\n        return false;\n      }\n      return this.indexOf(search, start) !== -1;\n    };\n  }\n}\nfunction initializePolyfills() {\n  polyfillObjectAssign();\n  polyfillArrayFrom();\n  polyfillStringStartsWith();\n  polyfillStringEndsWith();\n  polyfillStringIncludes();\n  polyfillURLSearchParams();\n  polyfillTextEncoder();\n  polyfillPromiseFinally();\n}\n\n// src/utils/vastMacros.ts\nvar UNEXPANDED_MACRO_PATTERN = /^(\\[[^\\]]*\\]|\\{[^}]*\\}|%%[^%]*%%)$/;\nvar INVALID_VAST_PARAM_KEY = /^\\s|\\s$/;\nvar EXAMPLE_COM_URL = /example\\.com/i;\nvar CTV_UNSUPPORTED_PARAMS = [\n  \"description_url\",\n  \"tfcd\",\n  \"npa\",\n  \"min_ad_duration\",\n  \"max_ad_duration\",\n  \"unviewed_position_start\",\n  \"impl\",\n  \"vad_type\",\n  \"gdpr\",\n  \"gdpr_consent\",\n  \"us_privacy\"\n];\nvar INLINE_DEVICE_MACRO_REPLACEMENTS = [\n  { pattern: /\\[RDID\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[IFA\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[ADVERTISING[_-]?ID(?:ENTIFIER)?\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[DEVICE[_-]?ID\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[IDTYPE\\]/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /\\{rdid\\}/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\{device[_-]?id\\}/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\{idtype\\}/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /%%ADVERTISING_IDENTIFIER_PLAIN%%/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /%%ADVERTISING_ID_OPT_OUT%%/gi, getValue: (ctx) => ctx.limitAdTracking != null ? ctx.limitAdTracking ? \"1\" : \"0\" : void 0 },\n  { pattern: /%%ADVERTISING_ID_TYPE%%/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /%%ADVERTISING_ID%%/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /%%LIMIT_AD_TRACKING%%/gi, getValue: (ctx) => ctx.limitAdTracking != null ? ctx.limitAdTracking ? \"1\" : \"0\" : void 0 },\n  { pattern: /%%MSID%%/gi, getValue: (ctx) => ctx.appId },\n  { pattern: /%%APP_NAME%%/gi, getValue: (ctx) => ctx.appName },\n  { pattern: /%%SESSION_ID%%/gi, getValue: (ctx) => ctx.sessionId },\n  { pattern: /%%CORRELATOR%%/gi, getValue: (ctx) => ctx.correlator }\n];\nfunction isMacroPlaceholder2(value) {\n  if (value == null) return true;\n  const trimmed = value.trim();\n  if (!trimmed) return true;\n  if (UNEXPANDED_MACRO_PATTERN.test(trimmed)) return true;\n  return /^(unknown|null|undefined|none|n\\/a|\\$\\{[^}]+\\})$/i.test(trimmed);\n}\nfunction generateCorrelator() {\n  if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n    try {\n      const buf = new Uint32Array(2);\n      crypto.getRandomValues(buf);\n      const value = (buf[0] ?? 0) * 2097152 + ((buf[1] ?? 0) & 2097151);\n      if (value > 0) {\n        return String(value);\n      }\n    } catch {\n    }\n  }\n  return String(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER) + 1);\n}\nfunction expandInlineMacroPlaceholders(baseUrl, ctx) {\n  let url = baseUrl;\n  for (const { pattern, getValue } of INLINE_DEVICE_MACRO_REPLACEMENTS) {\n    const value = getValue(ctx);\n    if (value != null && value !== \"\") {\n      url = url.replace(pattern, encodeURIComponent(value));\n    }\n  }\n  return url;\n}\nfunction applyDeviceIdentityParams(params, ctx) {\n  const runtimeId = ctx.deviceId?.trim();\n  const runtimeType = ctx.deviceIdType?.trim() || inferDeviceIdType();\n  const tagRdid = params.get(\"rdid\");\n  const tagType = params.get(\"idtype\");\n  const tagLat = params.get(\"is_lat\");\n  const latValue = ctx.limitAdTracking != null ? ctx.limitAdTracking ? \"1\" : \"0\" : void 0;\n  if (runtimeId) {\n    params.set(\"rdid\", runtimeId);\n    params.set(\"idtype\", runtimeType || tagType || \"aaid\");\n    params.set(\"is_lat\", latValue ?? (isMacroPlaceholder2(tagLat) ? \"0\" : tagLat));\n    return;\n  }\n  const tagRdidValid = Boolean(tagRdid && !isMacroPlaceholder2(tagRdid));\n  const tagTypeValid = Boolean(tagType && !isMacroPlaceholder2(tagType));\n  if (tagRdidValid && tagTypeValid && runtimeType && !isEquivalentDeviceIdType(tagType, runtimeType)) {\n    params.delete(\"rdid\");\n    params.delete(\"idtype\");\n    params.delete(\"is_lat\");\n    return;\n  }\n  if (tagRdidValid) {\n    if (isMacroPlaceholder2(tagType) && runtimeType) {\n      params.set(\"idtype\", runtimeType);\n    }\n    if (isMacroPlaceholder2(tagLat)) {\n      params.set(\"is_lat\", latValue ?? \"0\");\n    }\n    return;\n  }\n  params.delete(\"rdid\");\n  params.delete(\"idtype\");\n  params.delete(\"is_lat\");\n}\nfunction removeBrokenAppNameOrphans(params, appName) {\n  const toDelete = [];\n  params.forEach((_value, key) => {\n    if (!key || INVALID_VAST_PARAM_KEY.test(key)) {\n      toDelete.push(key);\n    }\n  });\n  if (appName && appName.includes(\"&\")) {\n    for (const suffix of appName.split(\"&\").slice(1)) {\n      const trimmed = suffix.trimStart();\n      if (!trimmed) continue;\n      toDelete.push(suffix, ` ${trimmed}`, trimmed);\n    }\n  }\n  for (const key of new Set(toDelete)) {\n    if (key) params.delete(key);\n  }\n}\nfunction normalizeVastTagUrl(raw) {\n  if (!raw) return raw;\n  try {\n    const url = new URL(raw);\n    const anValue = url.searchParams.get(\"an\");\n    if (anValue !== null) {\n      const orphanFragments = [];\n      url.searchParams.forEach((_value, key) => {\n        if (key && INVALID_VAST_PARAM_KEY.test(key)) {\n          orphanFragments.push(key.trim());\n        }\n      });\n      if (orphanFragments.length > 0) {\n        const reconstructed = [anValue.trimEnd(), ...orphanFragments].filter(Boolean).join(\" & \");\n        url.searchParams.forEach((_value, key) => {\n          if (key && INVALID_VAST_PARAM_KEY.test(key)) {\n            url.searchParams.delete(key);\n          }\n        });\n        url.searchParams.set(\"an\", reconstructed);\n        return url.toString().replace(\n          /([?&]an=)([^&]*)/,\n          (_match, prefix, val) => prefix + val.replace(/\\+/g, \"%20\")\n        );\n      }\n    }\n    removeBrokenAppNameOrphans(url.searchParams);\n    return url.toString();\n  } catch {\n    return raw;\n  }\n}\nfunction applyVastMacros(baseUrl, ctx) {\n  const expandedUrl = expandInlineMacroPlaceholders(baseUrl, ctx);\n  let url;\n  try {\n    url = new URL(normalizeVastTagUrl(expandedUrl));\n  } catch {\n    return replaceCorrelatorFallback(expandedUrl, ctx.correlator);\n  }\n  const params = url.searchParams;\n  removeBrokenAppNameOrphans(params, ctx.appName);\n  params.set(\"correlator\", ctx.correlator);\n  params.set(\"scor\", ctx.streamCorrelator);\n  if (ctx.isCtv) {\n    for (const key of CTV_UNSUPPORTED_PARAMS) {\n      params.delete(key);\n    }\n  }\n  if (ctx.pod != null) {\n    params.set(\"pod\", String(ctx.pod));\n  }\n  const optimizedPodMode = ctx.podMaxAds != null || ctx.podMinDurationMs != null || ctx.podMaxDurationMs != null;\n  if (optimizedPodMode) {\n    params.delete(\"ppos\");\n    params.delete(\"lip\");\n    if (ctx.podMinDurationMs != null) {\n      params.set(\"pmnd\", String(Math.max(0, Math.round(ctx.podMinDurationMs))));\n    }\n    if (ctx.podMaxDurationMs != null) {\n      params.set(\"pmxd\", String(Math.max(0, Math.round(ctx.podMaxDurationMs))));\n    }\n    if (ctx.podMaxAds != null) {\n      params.set(\"pmad\", String(Math.max(1, Math.round(ctx.podMaxAds))));\n    }\n  } else if (ctx.adPosition != null) {\n    params.set(\"ppos\", String(ctx.adPosition));\n  }\n  const requestUrl = ctx.contentUrl || ctx.pageUrl;\n  if (requestUrl) {\n    params.set(\"url\", requestUrl);\n    if (!ctx.isCtv) {\n      params.set(\"description_url\", requestUrl);\n    }\n  } else {\n    const existingUrl = params.get(\"url\") || \"\";\n    if (EXAMPLE_COM_URL.test(existingUrl)) {\n      params.delete(\"url\");\n      params.delete(\"description_url\");\n    }\n  }\n  if (ctx.adWillPlayMuted != null) {\n    params.set(\"vpmute\", ctx.adWillPlayMuted ? \"1\" : \"0\");\n  }\n  if (ctx.adWillAutoPlay != null) {\n    params.set(\"vpa\", ctx.adWillAutoPlay ? \"auto\" : \"click\");\n  }\n  if (ctx.appId) {\n    params.set(\"msid\", ctx.appId);\n  }\n  if (ctx.appName) {\n    removeBrokenAppNameOrphans(params, ctx.appName);\n    params.set(\"an\", ctx.appName);\n  }\n  if (ctx.sessionId) {\n    params.set(\"sid\", ctx.sessionId);\n  }\n  if (ctx.deviceTypeHint != null) {\n    params.set(\"dth\", String(ctx.deviceTypeHint));\n  } else if (ctx.isCtv) {\n    params.set(\"dth\", \"5\");\n  }\n  applyDeviceIdentityParams(params, ctx);\n  if (!ctx.isCtv) {\n    const consent = ctx.consent;\n    if (consent?.gdpr != null) {\n      params.set(\"gdpr\", consent.gdpr);\n    }\n    if (consent?.gdprConsent != null) {\n      params.set(\"gdpr_consent\", consent.gdprConsent);\n    }\n    if (consent?.usPrivacy != null) {\n      params.set(\"us_privacy\", consent.usPrivacy);\n    }\n  }\n  if (ctx.adTest) {\n    params.set(\"adtest\", \"on\");\n  }\n  const staleKeys = [];\n  params.forEach((value, key) => {\n    if (isMacroPlaceholder2(value)) {\n      staleKeys.push(key);\n    }\n  });\n  for (const key of staleKeys) {\n    params.delete(key);\n  }\n  removeBrokenAppNameOrphans(params, ctx.appName);\n  return url.toString();\n}\nfunction replaceCorrelatorFallback(baseUrl, correlator) {\n  const correlatorRegex = /([?&])correlator=([^&]*)/;\n  if (correlatorRegex.test(baseUrl)) {\n    return baseUrl.replace(correlatorRegex, `$1correlator=${correlator}`);\n  }\n  const sep = baseUrl.includes(\"?\") ? \"&\" : \"?\";\n  return `${baseUrl}${sep}correlator=${correlator}`;\n}\nfunction fetchConsentSignals(timeoutMs = 1500) {\n  const signals = {};\n  if (typeof window === \"undefined\") {\n    return Promise.resolve(signals);\n  }\n  const tasks = [];\n  const tcfApi = window.__tcfapi;\n  if (typeof tcfApi === \"function\") {\n    tasks.push(\n      new Promise((resolve) => {\n        let settled = false;\n        try {\n          tcfApi(\"addEventListener\", 2, (tcData, success) => {\n            if (settled) return;\n            if (success && tcData && (tcData.eventStatus === \"tcloaded\" || tcData.eventStatus === \"useractioncomplete\")) {\n              settled = true;\n              signals.gdpr = tcData.gdprApplies ? \"1\" : \"0\";\n              if (typeof tcData.tcString === \"string\" && tcData.tcString) {\n                signals.gdprConsent = tcData.tcString;\n              }\n              try {\n                tcfApi(\"removeEventListener\", 2, () => {\n                }, tcData.listenerId);\n              } catch {\n              }\n              resolve();\n            }\n          });\n        } catch {\n          resolve();\n        }\n        setTimeout(() => {\n          if (!settled) {\n            settled = true;\n            resolve();\n          }\n        }, timeoutMs);\n      })\n    );\n  }\n  const uspApi = window.__uspapi;\n  if (typeof uspApi === \"function\") {\n    tasks.push(\n      new Promise((resolve) => {\n        try {\n          uspApi(\"getUSPData\", 1, (data, success) => {\n            if (success && typeof data?.uspString === \"string\" && data.uspString) {\n              signals.usPrivacy = data.uspString;\n            }\n            resolve();\n          });\n        } catch {\n          resolve();\n        }\n        setTimeout(resolve, timeoutMs);\n      })\n    );\n  }\n  if (tasks.length === 0) {\n    return Promise.resolve(signals);\n  }\n  return Promise.all(tasks).then(() => signals);\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  let webOSVersion;\n  let tizenVersion;\n  let chromeVersionNum;\n  const chromeVersion = getChromeVersion(ua);\n  const webkitVersion = getWebKitVersion(ua);\n  chromeVersionNum = chromeVersion > 0 ? chromeVersion : void 0;\n  if (/Web0S|webOS|LG Browser|LGSTB/i.test(ua)) {\n    name = \"LG WebOS\";\n    isSmartTV = true;\n    let match = ua.match(/Web0S[/\\s]*([\\d.]+)/i) || ua.match(/webOS[/\\s]*([\\d.]+)/i);\n    if (!match || !match[1]) {\n      match = ua.match(/webOSTV[/\\s-]*([\\d.]+)/i) || ua.match(/webOS\\.TV[/\\s-]*([\\d.]+)/i);\n    }\n    if (match && match[1]) {\n      version = match[1];\n      const parts = version.split(\".\");\n      majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n      webOSVersion = majorVersion;\n    } else if (chromeVersion > 0) {\n      if (chromeVersion >= 79) {\n        webOSVersion = 6;\n        version = \"6.0\";\n        majorVersion = 6;\n      } else if (chromeVersion >= 68) {\n        webOSVersion = 5;\n        version = \"5.0\";\n        majorVersion = 5;\n      } else if (chromeVersion >= 53) {\n        webOSVersion = 4;\n        version = \"4.0\";\n        majorVersion = 4;\n      } else if (chromeVersion >= 38) {\n        webOSVersion = 3;\n        version = \"3.0\";\n        majorVersion = 3;\n      } else {\n        webOSVersion = 2;\n        version = \"2.0\";\n        majorVersion = 2;\n      }\n    } else {\n      version = \"Unknown\";\n      webOSVersion = void 0;\n    }\n    isLegacyTV = webOSVersion !== void 0 && webOSVersion < 3;\n  } else if (/Tizen/i.test(ua)) {\n    name = \"Samsung Tizen\";\n    isSmartTV = true;\n    const match = ua.match(/Tizen[/\\s]*([\\d.]+)/i);\n    version = match && match[1] ? match[1] : \"Unknown\";\n    if (version !== \"Unknown\") {\n      const parts = version.split(\".\");\n      majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n      tizenVersion = majorVersion;\n    }\n    isLegacyTV = tizenVersion !== void 0 && tizenVersion < 3;\n  } else if (/SMART-TV|SmartTV/i.test(ua)) {\n    name = \"Smart TV\";\n    isSmartTV = true;\n    isLegacyTV = chromeVersion > 0 && chromeVersion < 53;\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    isLegacyTV = chromeVersion > 0 && chromeVersion < 53;\n  } else {\n    if (chromeVersion > 0) {\n      name = \"Chrome\";\n      version = chromeVersion.toString();\n      majorVersion = chromeVersion;\n      if (chromeVersion < 50) {\n        supportsModernJS = false;\n      }\n    }\n    if (webkitVersion > 0 && webkitVersion < 600) {\n      supportsModernJS = false;\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    webOSVersion,\n    tizenVersion,\n    chromeVersion: chromeVersionNum\n  };\n}\nfunction getBrowserConfigOverrides() {\n  const browser = detectBrowser();\n  const overrides = {};\n  if (browser.isSmartTV) {\n    overrides.allowNativeHls = true;\n  }\n  return overrides;\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    ...browser.webOSVersion !== void 0 ? { webOSVersion: browser.webOSVersion } : {},\n    ...browser.tizenVersion !== void 0 ? { tizenVersion: browser.tizenVersion } : {},\n    ...browser.chromeVersion !== void 0 ? { chromeVersion: browser.chromeVersion } : {},\n    userAgent: navigator.userAgent\n  });\n}\n\n// src/player/Scte35Parser.ts\nfunction 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}\nfunction parseCueOutCont(value) {\n  const res = {};\n  const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n  const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n  if (elapsedMatch && elapsedMatch[1] != null) {\n    const e = parseFloat(elapsedMatch[1]);\n    if (!Number.isNaN(e)) res.elapsed = e;\n  }\n  if (durationMatch && durationMatch[1] != null) {\n    const d = parseFloat(durationMatch[1]);\n    if (!Number.isNaN(d)) res.duration = d;\n  }\n  if (!(\"elapsed\" in res) || !(\"duration\" in res)) {\n    const slashMatch = value.match(/([0-9.]+)\\s*\\/\\s*([0-9.]+)/);\n    if (slashMatch && slashMatch[1] && slashMatch[2]) {\n      const elapsed = parseFloat(slashMatch[1]);\n      const duration = parseFloat(slashMatch[2]);\n      if (!Number.isNaN(elapsed) && !(\"elapsed\" in res)) res.elapsed = elapsed;\n      if (!Number.isNaN(duration) && !(\"duration\" in res)) res.duration = duration;\n    }\n  }\n  if (\"elapsed\" in res || \"duration\" in res) return res;\n  return void 0;\n}\nfunction 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}\nfunction 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}\nfunction 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}\nfunction 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}\nfunction getFragmentStartSeconds(frag) {\n  const candidates = [frag?.start, frag?.startPTS];\n  for (const candidate of candidates) {\n    if (typeof candidate === \"number\" && Number.isFinite(candidate)) {\n      return candidate;\n    }\n  }\n  return void 0;\n}\nfunction parseScte35FromId3(tag) {\n  const text = 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 = 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 = 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 = 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 = 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 = parseScte35Binary(tag.value);\n    if (bin) return bin;\n  }\n  return void 0;\n}\nfunction normalizeFragmentPayload(payload) {\n  if (payload instanceof Uint8Array) {\n    return payload;\n  }\n  if (payload instanceof ArrayBuffer) {\n    return new Uint8Array(payload);\n  }\n  if (ArrayBuffer.isView(payload)) {\n    const view = payload;\n    return new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n  }\n  return void 0;\n}\nfunction detectTsPacketFormat(data) {\n  const packetSizes = [188, 192, 204];\n  for (const packetSize of packetSizes) {\n    const tsPayloadOffset = packetSize === 192 ? 4 : 0;\n    for (let offset = 0; offset < packetSize; offset++) {\n      let matchedPackets = 0;\n      for (let packetStart = offset; packetStart + tsPayloadOffset < data.length && matchedPackets < 5; packetStart += packetSize) {\n        if (data[packetStart + tsPayloadOffset] !== 71) {\n          break;\n        }\n        matchedPackets++;\n      }\n      if (matchedPackets >= 2) {\n        return { offset, packetSize, tsPayloadOffset };\n      }\n    }\n  }\n  return void 0;\n}\nfunction getPsiSectionStart(payload, payloadUnitStart) {\n  if (!payloadUnitStart) {\n    return void 0;\n  }\n  const pointerField = payload[0];\n  if (pointerField == null) {\n    return void 0;\n  }\n  const sectionStart = 1 + pointerField;\n  return sectionStart < payload.length ? sectionStart : void 0;\n}\nfunction getPsiSectionLength(data, offset) {\n  return ((data[offset + 1] ?? 0) & 15) << 8 | (data[offset + 2] ?? 0);\n}\nfunction parsePatSection(payload, payloadUnitStart, pmtPids) {\n  const sectionStart = getPsiSectionStart(payload, payloadUnitStart);\n  if (sectionStart == null || sectionStart + 8 >= payload.length) {\n    return;\n  }\n  if (payload[sectionStart] !== 0) {\n    return;\n  }\n  const sectionLength = getPsiSectionLength(payload, sectionStart);\n  const sectionEnd = Math.min(\n    payload.length,\n    sectionStart + 3 + sectionLength\n  );\n  for (let offset = sectionStart + 8; offset + 4 <= sectionEnd - 4; offset += 4) {\n    const programNumber = (payload[offset] ?? 0) << 8 | (payload[offset + 1] ?? 0);\n    const pid = ((payload[offset + 2] ?? 0) & 31) << 8 | (payload[offset + 3] ?? 0);\n    if (programNumber !== 0) {\n      pmtPids.add(pid);\n    }\n  }\n}\nfunction descriptorsIdentifyScte35(data, start, end) {\n  let offset = start;\n  while (offset + 2 <= end) {\n    const tag = data[offset] ?? 0;\n    const length = data[offset + 1] ?? 0;\n    const descriptorStart = offset + 2;\n    const descriptorEnd = descriptorStart + length;\n    if (descriptorEnd > end) {\n      return false;\n    }\n    const registration = length >= 4 ? String.fromCharCode(\n      data[descriptorStart] ?? 0,\n      data[descriptorStart + 1] ?? 0,\n      data[descriptorStart + 2] ?? 0,\n      data[descriptorStart + 3] ?? 0\n    ) : \"\";\n    if (tag === 138 || registration === \"CUEI\" || registration === \"SCTE\") {\n      return true;\n    }\n    offset = descriptorEnd;\n  }\n  return false;\n}\nfunction parsePmtSection(payload, payloadUnitStart, tsScte35Pids) {\n  const sectionStart = getPsiSectionStart(payload, payloadUnitStart);\n  if (sectionStart == null || sectionStart + 12 >= payload.length) {\n    return;\n  }\n  if (payload[sectionStart] !== 2) {\n    return;\n  }\n  const sectionLength = getPsiSectionLength(payload, sectionStart);\n  const sectionEnd = Math.min(\n    payload.length,\n    sectionStart + 3 + sectionLength\n  );\n  const programInfoLength = ((payload[sectionStart + 10] ?? 0) & 15) << 8 | (payload[sectionStart + 11] ?? 0);\n  let offset = sectionStart + 12 + programInfoLength;\n  while (offset + 5 <= sectionEnd - 4) {\n    const streamType = payload[offset] ?? 0;\n    const elementaryPid = ((payload[offset + 1] ?? 0) & 31) << 8 | (payload[offset + 2] ?? 0);\n    const esInfoLength = ((payload[offset + 3] ?? 0) & 15) << 8 | (payload[offset + 4] ?? 0);\n    const descriptorStart = offset + 5;\n    const descriptorEnd = Math.min(descriptorStart + esInfoLength, sectionEnd - 4);\n    if (streamType === 134 || streamType === 6 && descriptorsIdentifyScte35(payload, descriptorStart, descriptorEnd)) {\n      tsScte35Pids.add(elementaryPid);\n    }\n    offset = descriptorStart + esInfoLength;\n  }\n}\nfunction hasProcessedTsScte35Section(section, processedSections) {\n  let checksum = 0;\n  for (let i = 0; i < section.length; i++) {\n    checksum = checksum * 31 + (section[i] ?? 0) >>> 0;\n  }\n  const key = `${section.length}:${checksum}`;\n  if (processedSections.has(key)) {\n    return true;\n  }\n  processedSections.add(key);\n  if (processedSections.size > 200) {\n    const firstKey = processedSections.values().next().value;\n    if (firstKey) {\n      processedSections.delete(firstKey);\n    }\n  }\n  return false;\n}\nfunction addScte35SectionMarker(section, markers, processedSections) {\n  if (section[0] !== 252 || hasProcessedTsScte35Section(section, processedSections)) {\n    return;\n  }\n  const marker = parseScte35Binary(section);\n  if (!marker) {\n    return;\n  }\n  marker.raw = {\n    ...typeof marker.raw === \"object\" && marker.raw ? marker.raw : {},\n    source: \"ts-packet\"\n  };\n  markers.push(marker);\n}\nfunction appendScte35Bytes(pid, bytes, assemblers, markers, processedSections) {\n  const assembler = assemblers.get(pid);\n  if (!assembler) {\n    return;\n  }\n  for (let i = 0; i < bytes.length && assembler.bytes.length < assembler.expectedLength; i++) {\n    assembler.bytes.push(bytes[i] ?? 0);\n  }\n  if (assembler.bytes.length >= assembler.expectedLength) {\n    assemblers.delete(pid);\n    addScte35SectionMarker(new Uint8Array(assembler.bytes), markers, processedSections);\n  }\n}\nfunction collectScte35SectionsFromPayload(pid, payload, payloadUnitStart, assemblers, markers, processedSections) {\n  if (payload.length === 0) {\n    return;\n  }\n  let offset = 0;\n  if (payloadUnitStart) {\n    const pointerField = payload[0] ?? 0;\n    const previousAssembler = assemblers.get(pid);\n    if (previousAssembler && pointerField > 0) {\n      appendScte35Bytes(\n        pid,\n        payload.subarray(1, Math.min(1 + pointerField, payload.length)),\n        assemblers,\n        markers,\n        processedSections\n      );\n    }\n    assemblers.delete(pid);\n    offset = 1 + pointerField;\n  } else {\n    appendScte35Bytes(pid, payload, assemblers, markers, processedSections);\n    return;\n  }\n  while (offset + 3 <= payload.length) {\n    const tableId = payload[offset];\n    if (tableId == null || tableId === 255) {\n      return;\n    }\n    const sectionLength = getPsiSectionLength(payload, offset);\n    const totalLength = 3 + sectionLength;\n    if (sectionLength <= 0 || totalLength <= 3) {\n      return;\n    }\n    if (offset + totalLength <= payload.length) {\n      addScte35SectionMarker(\n        payload.subarray(offset, offset + totalLength),\n        markers,\n        processedSections\n      );\n      offset += totalLength;\n    } else {\n      assemblers.set(pid, {\n        bytes: Array.from(payload.subarray(offset)),\n        expectedLength: totalLength\n      });\n      return;\n    }\n  }\n}\nfunction parseScte35FromTsPackets(data, tsScte35Pids, pmtPids, processedSections) {\n  const packetInfo = detectTsPacketFormat(data);\n  if (!packetInfo) {\n    return [];\n  }\n  const markers = [];\n  const sectionAssemblers = /* @__PURE__ */ new Map();\n  for (let packetStart = packetInfo.offset; packetStart + packetInfo.packetSize <= data.length; packetStart += packetInfo.packetSize) {\n    const tsStart = packetStart + packetInfo.tsPayloadOffset;\n    if (data[tsStart] !== 71) {\n      continue;\n    }\n    const secondByte = data[tsStart + 1];\n    const thirdByte = data[tsStart + 2];\n    const fourthByte = data[tsStart + 3];\n    if (secondByte == null || thirdByte == null || fourthByte == null || (secondByte & 128) !== 0) {\n      continue;\n    }\n    const payloadUnitStart = (secondByte & 64) !== 0;\n    const pid = (secondByte & 31) << 8 | thirdByte;\n    const adaptationFieldControl = fourthByte >> 4 & 3;\n    const hasPayload = adaptationFieldControl === 1 || adaptationFieldControl === 3;\n    if (!hasPayload) {\n      continue;\n    }\n    let payloadStart = tsStart + 4;\n    if (adaptationFieldControl === 3) {\n      const adaptationLength = data[payloadStart];\n      if (adaptationLength == null) {\n        continue;\n      }\n      payloadStart += 1 + adaptationLength;\n    }\n    const payloadEnd = Math.min(tsStart + 188, data.length);\n    if (payloadStart >= payloadEnd || payloadStart >= data.length) {\n      continue;\n    }\n    const payload = data.subarray(payloadStart, payloadEnd);\n    if (pid === 0) {\n      parsePatSection(payload, payloadUnitStart, pmtPids);\n    } else if (pmtPids.has(pid)) {\n      parsePmtSection(payload, payloadUnitStart, tsScte35Pids);\n    } else if (tsScte35Pids.has(pid)) {\n      collectScte35SectionsFromPayload(\n        pid,\n        payload,\n        payloadUnitStart,\n        sectionAssemblers,\n        markers,\n        processedSections\n      );\n    }\n  }\n  return markers;\n}\nvar BitReader = class {\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  get bytePosition() {\n    return this.bitPos === 0 ? this.bytePos : this.bytePos + 1;\n  }\n};\nfunction readSpliceTime(r, ptsAdjustmentTicks) {\n  const timeSpecifiedFlag = r.readBits(1) === 1;\n  if (!timeSpecifiedFlag) {\n    r.readBits(7);\n    return void 0;\n  }\n  r.readBits(6);\n  const high = r.readBits(1);\n  const low = r.readBits(32);\n  const ptsTicks = (high * 4294967296 + low + ptsAdjustmentTicks) % 8589934592;\n  return ptsTicks / 9e4;\n}\nfunction markerTypeFromSegmentationTypeId(segmentationTypeId) {\n  switch (segmentationTypeId) {\n    case 16:\n    case 34:\n    case 48:\n    case 50:\n    case 52:\n    case 54:\n      return \"start\";\n    case 17:\n    case 35:\n    case 49:\n    case 51:\n    case 53:\n    case 55:\n      return \"end\";\n    default:\n      return void 0;\n  }\n}\nfunction parseScte35SegmentationDescriptor(descriptor) {\n  if (descriptor.length < 11) {\n    return void 0;\n  }\n  const identifier = String.fromCharCode(\n    descriptor[0] ?? 0,\n    descriptor[1] ?? 0,\n    descriptor[2] ?? 0,\n    descriptor[3] ?? 0\n  );\n  if (identifier !== \"CUEI\") {\n    return void 0;\n  }\n  const segmentationEventId = (descriptor[4] ?? 0) * 16777216 + ((descriptor[5] ?? 0) << 16) + ((descriptor[6] ?? 0) << 8) + (descriptor[7] ?? 0);\n  const cancelIndicator = ((descriptor[8] ?? 0) & 128) !== 0;\n  if (cancelIndicator) {\n    return void 0;\n  }\n  const flags = descriptor[9] ?? 0;\n  const programSegmentationFlag = (flags & 128) !== 0;\n  const segmentationDurationFlag = (flags & 64) !== 0;\n  let offset = 10;\n  if (!programSegmentationFlag) {\n    const componentCount = descriptor[offset] ?? 0;\n    offset += 1 + componentCount * 6;\n    if (offset > descriptor.length) {\n      return void 0;\n    }\n  }\n  let durationSeconds = void 0;\n  if (segmentationDurationFlag) {\n    if (offset + 5 > descriptor.length) {\n      return void 0;\n    }\n    const durationTicks = (descriptor[offset] ?? 0) * 4294967296 + (descriptor[offset + 1] ?? 0) * 16777216 + ((descriptor[offset + 2] ?? 0) << 16) + ((descriptor[offset + 3] ?? 0) << 8) + (descriptor[offset + 4] ?? 0);\n    durationSeconds = durationTicks / 9e4;\n    offset += 5;\n  }\n  if (offset + 2 > descriptor.length) {\n    return void 0;\n  }\n  offset += 1;\n  const segmentationUpidLength = descriptor[offset] ?? 0;\n  offset += 1 + segmentationUpidLength;\n  if (offset >= descriptor.length) {\n    return void 0;\n  }\n  const segmentationTypeId = descriptor[offset] ?? 0;\n  const markerType = markerTypeFromSegmentationTypeId(segmentationTypeId);\n  if (!markerType) {\n    return void 0;\n  }\n  return {\n    type: markerType,\n    ...durationSeconds !== void 0 ? { durationSeconds } : {},\n    segmentationEventId\n  };\n}\nfunction parseScte35SegmentationDescriptors(data, offset) {\n  if (offset + 2 > data.length) {\n    return void 0;\n  }\n  const descriptorLoopLength = (data[offset] ?? 0) << 8 | (data[offset + 1] ?? 0);\n  let descriptorOffset = offset + 2;\n  const descriptorEnd = Math.min(\n    data.length,\n    descriptorOffset + descriptorLoopLength\n  );\n  while (descriptorOffset + 2 <= descriptorEnd) {\n    const descriptorTag = data[descriptorOffset] ?? 0;\n    const descriptorLength = data[descriptorOffset + 1] ?? 0;\n    const descriptorDataStart = descriptorOffset + 2;\n    const descriptorDataEnd = descriptorDataStart + descriptorLength;\n    if (descriptorDataEnd > descriptorEnd) {\n      return void 0;\n    }\n    if (descriptorTag === 2) {\n      const descriptorMarker = parseScte35SegmentationDescriptor(\n        data.subarray(descriptorDataStart, descriptorDataEnd)\n      );\n      if (descriptorMarker) {\n        return descriptorMarker;\n      }\n    }\n    descriptorOffset = descriptorDataEnd;\n  }\n  return void 0;\n}\nfunction parseScte35Binary(data) {\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  if (sectionLength <= 0 || data.length < 3 + sectionLength) {\n    return void 0;\n  }\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  const ptsAdjustmentTicks = ptsAdjHigh * 4294967296 + ptsAdjLow;\n  r.readBits(8);\n  r.readBits(12);\n  const spliceCommandLength = r.readBits(12);\n  const spliceCommandType = r.readBits(8);\n  let markerType;\n  let durationSeconds = void 0;\n  let ptsSeconds = void 0;\n  let spliceEventId = void 0;\n  const commandBodyStart = r.bytePosition;\n  if (spliceCommandType === 5) {\n    spliceEventId = 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    markerType = outOfNetwork ? \"start\" : \"end\";\n    if (programSpliceFlag && !spliceImmediateFlag) {\n      ptsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\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 componentPtsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n          if (ptsSeconds === void 0) {\n            ptsSeconds = componentPtsSeconds;\n          }\n        }\n      }\n    }\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  } else if (spliceCommandType === 6) {\n    ptsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n  } else {\n    return void 0;\n  }\n  const expectedDescriptorOffset = spliceCommandLength === 4095 ? r.bytePosition : commandBodyStart + spliceCommandLength;\n  const descriptorMarker = parseScte35SegmentationDescriptors(\n    data,\n    expectedDescriptorOffset\n  );\n  if (descriptorMarker) {\n    markerType = descriptorMarker.type;\n    if (durationSeconds === void 0) {\n      durationSeconds = descriptorMarker.durationSeconds;\n    }\n  }\n  if (!markerType) {\n    return void 0;\n  }\n  const marker = {\n    type: markerType,\n    ...ptsSeconds !== void 0 ? { ptsSeconds } : {},\n    ...durationSeconds !== void 0 ? { durationSeconds } : {},\n    raw: {\n      splice_command_type: spliceCommandType,\n      ...spliceEventId !== void 0 ? { splice_event_id: spliceEventId } : {},\n      ...descriptorMarker?.segmentationEventId !== void 0 ? { segmentation_event_id: descriptorMarker.segmentationEventId } : {}\n    }\n  };\n  return marker;\n}\n\n// src/player/Scte35CueManager.ts\nvar Scte35CueManager = class {\n  constructor(debug, callbacks) {\n    this.pendingScte35Cues = /* @__PURE__ */ new Map();\n    this.recentScte35CueKeys = /* @__PURE__ */ new Map();\n    this.recentScte35CueLimit = 200;\n    this.tsScte35Pids = /* @__PURE__ */ new Set();\n    this.pmtPids = /* @__PURE__ */ new Set();\n    this.processedTsScte35Sections = /* @__PURE__ */ new Set();\n    this.debug = debug;\n    this.callbacks = callbacks;\n  }\n  get pendingScte35CueKey() {\n    return this.pendingScte35CueKeyValue;\n  }\n  set pendingScte35CueKey(value) {\n    this.pendingScte35CueKeyValue = value;\n  }\n  get activeScte35BreakKey() {\n    return this.activeScte35BreakKeyValue;\n  }\n  set activeScte35BreakKey(value) {\n    this.activeScte35BreakKeyValue = value;\n  }\n  get scheduledScte35BreakKey() {\n    return this.scheduledScte35BreakKeyValue;\n  }\n  set scheduledScte35BreakKey(value) {\n    this.scheduledScte35BreakKeyValue = value;\n  }\n  createScte35CueContext(source, readiness, frag) {\n    const context = { source, readiness };\n    if (typeof frag?.sn === \"number\") {\n      context.fragmentSn = frag.sn;\n    }\n    const fragmentStartSec = getFragmentStartSeconds(frag);\n    if (fragmentStartSec !== void 0) {\n      context.fragmentStartSeconds = fragmentStartSec;\n    }\n    return context;\n  }\n  onScte35Cue(marker, context) {\n    const cue = this.createScte35Cue(marker, context);\n    const pendingKey = this.getPendingScte35CueKey(cue);\n    if (context.readiness === \"early\") {\n      this.pendingScte35Cues.set(pendingKey, cue);\n      this.trimRecentScte35CueMaps();\n      if (marker.type === \"start\") {\n        this.callbacks.onEarlyStartCue(marker, context.fragmentSn, cue.key);\n      }\n      return;\n    }\n    if (marker.type === \"end\" && !this.shouldAcceptScte35EndCue(cue)) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ignoring SCTE-35 end cue\", {\n          key: cue.key,\n          activeScte35BreakKey: this.activeScte35BreakKeyValue,\n          inAdBreak: this.callbacks.isInAdBreak(),\n          source: cue.source\n        });\n      }\n      return;\n    }\n    if (marker.type === \"start\" && this.hasRecentlyHandledScte35Cue(cue)) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ignoring duplicate SCTE-35 start cue\", {\n          key: cue.key,\n          source: cue.source\n        });\n      }\n      return;\n    }\n    this.pendingScte35Cues.delete(pendingKey);\n    this.markScte35CueHandled(cue);\n    this.callbacks.onPlaybackCue(marker, cue.key);\n  }\n  activatePendingScte35CuesForFragment(frag) {\n    const fragmentSn = typeof frag?.sn === \"number\" ? frag.sn : void 0;\n    if (fragmentSn === void 0) {\n      return;\n    }\n    const matchingCues = Array.from(this.pendingScte35Cues.entries()).filter(\n      ([, cue]) => cue.fragmentSn === fragmentSn\n    );\n    matchingCues.forEach(([pendingKey, cue]) => {\n      this.pendingScte35Cues.delete(pendingKey);\n      const context = {\n        source: cue.source,\n        readiness: \"playback\"\n      };\n      context.fragmentSn = fragmentSn;\n      const fragmentStartSec = cue.fragmentStartSeconds ?? getFragmentStartSeconds(frag);\n      if (fragmentStartSec !== void 0) {\n        context.fragmentStartSeconds = fragmentStartSec;\n      }\n      this.onScte35Cue(cue.marker, context);\n    });\n  }\n  createScte35Cue(marker, context) {\n    const cue = {\n      marker,\n      source: context.source,\n      readiness: context.readiness,\n      key: this.getScte35CueKey(marker, context)\n    };\n    if (context.fragmentSn !== void 0) {\n      cue.fragmentSn = context.fragmentSn;\n    }\n    if (context.fragmentStartSeconds !== void 0) {\n      cue.fragmentStartSeconds = context.fragmentStartSeconds;\n    }\n    return cue;\n  }\n  getScte35CueKey(marker, context) {\n    const raw = this.getScte35MarkerRaw(marker);\n    const spliceEventId = this.toIdentityString(raw?.splice_event_id);\n    if (spliceEventId) {\n      return `splice:${spliceEventId}`;\n    }\n    const segmentationEventId = this.toIdentityString(raw?.segmentation_event_id);\n    if (segmentationEventId) {\n      return `segmentation:${segmentationEventId}`;\n    }\n    const daterangeId = this.toIdentityString(raw?.attrs?.ID);\n    if (daterangeId) {\n      return `daterange:${daterangeId}`;\n    }\n    const scteValue = this.toIdentityString(raw?.attrs?.[\"SCTE35-OUT\"]) || this.toIdentityString(raw?.attrs?.[\"SCTE35-IN\"]);\n    if (scteValue) {\n      return `daterange-scte:${scteValue}`;\n    }\n    if (typeof marker.ptsSeconds === \"number\" && Number.isFinite(marker.ptsSeconds)) {\n      return `pts:${Math.round(marker.ptsSeconds * 2) / 2}`;\n    }\n    if (context.fragmentSn !== void 0) {\n      return `fragment:${context.fragmentSn}`;\n    }\n    return `${context.source}:wallclock:${Math.floor(Date.now() / 1e3)}`;\n  }\n  getPendingScte35CueKey(cue) {\n    return `${cue.marker.type}:${cue.key}:${cue.fragmentSn !== void 0 ? cue.fragmentSn : \"unknown\"}`;\n  }\n  getScte35MarkerRaw(marker) {\n    return typeof marker.raw === \"object\" && marker.raw !== null ? marker.raw : {};\n  }\n  toIdentityString(value) {\n    if (typeof value === \"number\" && Number.isFinite(value)) {\n      return String(value);\n    }\n    if (typeof value === \"string\" && value.trim().length > 0) {\n      return value.trim();\n    }\n    return void 0;\n  }\n  isStrongScte35CueKey(key) {\n    return !!(key && (key.startsWith(\"splice:\") || key.startsWith(\"segmentation:\") || key.startsWith(\"daterange:\") || key.startsWith(\"daterange-scte:\")));\n  }\n  hasRecentlyHandledScte35Cue(cue) {\n    if (this.activeScte35BreakKeyValue === cue.key || this.scheduledScte35BreakKeyValue === cue.key) {\n      return true;\n    }\n    const recentKey = `${cue.marker.type}:${cue.key}`;\n    return this.recentScte35CueKeys.has(recentKey);\n  }\n  markScte35CueHandled(cue) {\n    this.recentScte35CueKeys.set(`${cue.marker.type}:${cue.key}`, Date.now());\n    this.trimRecentScte35CueMaps();\n  }\n  trimRecentScte35CueMaps() {\n    while (this.recentScte35CueKeys.size > this.recentScte35CueLimit) {\n      const firstKey = this.recentScte35CueKeys.keys().next().value;\n      if (!firstKey) {\n        break;\n      }\n      this.recentScte35CueKeys.delete(firstKey);\n    }\n    while (this.pendingScte35Cues.size > this.recentScte35CueLimit) {\n      const firstKey = this.pendingScte35Cues.keys().next().value;\n      if (!firstKey) {\n        break;\n      }\n      this.pendingScte35Cues.delete(firstKey);\n    }\n  }\n  shouldAcceptScte35EndCue(cue) {\n    if (!this.callbacks.isInAdBreak()) {\n      return false;\n    }\n    if (this.isStrongScte35CueKey(this.activeScte35BreakKeyValue) && this.isStrongScte35CueKey(cue.key) && this.activeScte35BreakKeyValue !== cue.key) {\n      return false;\n    }\n    return true;\n  }\n};\n\n// src/player/AdConfigManager.ts\nvar AdConfigManager = class {\n  constructor(config, video) {\n    this.vmapBreaks = [];\n    this.consumedVmapBreakIds = /* @__PURE__ */ new Set();\n    this.streamCorrelator = generateCorrelator();\n    this.viewCorrelator = generateCorrelator();\n    this.consentSignals = {};\n    this.podCounter = 0;\n    this.podAssignedByPrefetch = false;\n    this.adRequestPositionInBreak = 0;\n    this.lastHeartbeatTime = 0;\n    this.defaultPodMaxAds = 6;\n    this.config = config;\n    this.video = video;\n  }\n  get debug() {\n    return !!this.config.debugAdTiming;\n  }\n  isVmapEnabled() {\n    return !!(this.config.isVmap && this.config.vmapUrl?.trim());\n  }\n  async fetchAdConfiguration() {\n    if (this.isVmapEnabled()) {\n      await this.fetchAndParseVmap(this.config.vmapUrl);\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] VMAP mode enabled\");\n      }\n      return;\n    }\n    const vastMode = this.config.vastMode || \"default\";\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] VAST mode:\", vastMode);\n    }\n    if (vastMode === \"adstorm\") {\n      if (!this.config.licenseKey) {\n        if (this.debug) {\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.debug) {\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 = normalizeVastTagUrl(this.config.vastTagUrl);\n      if (this.debug) {\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.debug) {\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.debug) {\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      let decodedPayload = imaPayload;\n      try {\n        decodedPayload = decodeURIComponent(imaPayload);\n      } catch {\n        console.warn(\"[StormcloudVideoPlayer] imaPayload was not URI-encoded; using as-is:\", imaPayload);\n      }\n      console.log(\"[StormcloudVideoPlayer] Raw VAST tag URL (from API):\", decodedPayload);\n      this.apiVastTagUrl = normalizeVastTagUrl(decodedPayload);\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Normalized VAST tag URL:\",\n          this.apiVastTagUrl\n        );\n      }\n    } else {\n      if (this.debug) {\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.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Number of ads per break from API:\",\n          this.apiNumberAds\n        );\n      }\n    }\n  }\n  async fetchAndParseVmap(vmapUrl) {\n    if (!vmapUrl.trim()) {\n      return;\n    }\n    try {\n      const response = await fetch(vmapUrl);\n      if (!response.ok) {\n        throw new Error(`Failed to fetch VMAP (${response.status})`);\n      }\n      const vmapXml = await response.text();\n      this.vmapBreaks = this.parseVmapToBreaks(vmapXml);\n      this.consumedVmapBreakIds.clear();\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] Loaded ${this.vmapBreaks.length} VMAP ad break(s) from:`,\n          vmapUrl\n        );\n      }\n    } catch (error) {\n      this.vmapBreaks = [];\n      this.consumedVmapBreakIds.clear();\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Failed to load VMAP:\", error);\n      }\n    }\n  }\n  parseVmapToBreaks(vmapXml) {\n    if (typeof DOMParser === \"undefined\") {\n      return [];\n    }\n    const doc = new DOMParser().parseFromString(vmapXml, \"application/xml\");\n    if (doc.querySelector(\"parsererror\")) {\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Invalid VMAP XML received\");\n      }\n      return [];\n    }\n    const VMAP_NS = \"http://www.iab.net/videosuite/vmap\";\n    let adBreakNodes = Array.from(doc.getElementsByTagNameNS(VMAP_NS, \"AdBreak\"));\n    if (adBreakNodes.length === 0) {\n      adBreakNodes = Array.from(\n        doc.querySelectorAll(\"AdBreak, vmap\\\\:AdBreak\")\n      );\n    }\n    if (adBreakNodes.length === 0) {\n      adBreakNodes = Array.from(doc.getElementsByTagName(\"*\")).filter(\n        (el) => el.localName === \"AdBreak\"\n      );\n    }\n    const parsed = [];\n    adBreakNodes.forEach((node, index) => {\n      const timeOffsetRaw = (node.getAttribute(\"timeOffset\") || \"\").trim();\n      const startTimeMs = this.parseVmapTimeOffsetToMs(timeOffsetRaw);\n      if (startTimeMs == null) {\n        return;\n      }\n      let adTagNode = node.getElementsByTagNameNS(VMAP_NS, \"AdTagURI\")[0];\n      if (!adTagNode) {\n        adTagNode = node.querySelector(\"AdTagURI, vmap\\\\:AdTagURI\") ?? void 0;\n      }\n      const adTagUrl = (adTagNode?.textContent || \"\").trim();\n      if (!adTagUrl) {\n        return;\n      }\n      const breakId = node.getAttribute(\"breakId\") || `vmap-break-${index}-${timeOffsetRaw || \"unknown\"}`;\n      parsed.push({\n        id: breakId,\n        startTimeMs,\n        vastTagUrl: adTagUrl\n      });\n    });\n    parsed.sort((a, b) => {\n      const aStart = a.startTimeMs < 0 ? Number.MAX_SAFE_INTEGER : a.startTimeMs;\n      const bStart = b.startTimeMs < 0 ? Number.MAX_SAFE_INTEGER : b.startTimeMs;\n      return aStart - bStart;\n    });\n    return parsed;\n  }\n  parseVmapTimeOffsetToMs(timeOffset) {\n    if (!timeOffset) {\n      return void 0;\n    }\n    const normalized = timeOffset.trim().toLowerCase();\n    if (normalized === \"start\") {\n      return 0;\n    }\n    if (normalized === \"end\") {\n      return -1;\n    }\n    const hms = timeOffset.match(\n      /^(\\d{1,2}):(\\d{2}):(\\d{2})(?:\\.(\\d{1,3}))?$/\n    );\n    if (hms) {\n      const [, hh, mm, ss, ms = \"0\"] = hms;\n      const hours = Number(hh);\n      const minutes = Number(mm);\n      const seconds = Number(ss);\n      const millis = Number(ms.padEnd(3, \"0\").slice(0, 3));\n      return (hours * 3600 + minutes * 60 + seconds) * 1e3 + millis;\n    }\n    const percent = timeOffset.match(/^(\\d+(?:\\.\\d+)?)%$/);\n    if (percent) {\n      const ratio = Number(percent[1]) / 100;\n      const durationSec = this.video.duration;\n      if (Number.isFinite(durationSec) && durationSec > 0) {\n        return Math.floor(durationSec * 1e3 * ratio);\n      }\n      return void 0;\n    }\n    return void 0;\n  }\n  getAdBreakKey(adBreak) {\n    if (adBreak.id) {\n      return adBreak.id;\n    }\n    return `${adBreak.startTimeMs}-${adBreak.vastTagUrl || \"\"}`;\n  }\n  resolveBreakStartMs(adBreak) {\n    if (adBreak.startTimeMs >= 0) {\n      return adBreak.startTimeMs;\n    }\n    if (adBreak.startTimeMs === -1) {\n      const durationSec = this.video.duration;\n      if (Number.isFinite(durationSec) && durationSec > 0) {\n        return Math.floor(durationSec * 1e3);\n      }\n    }\n    return void 0;\n  }\n  findCurrentOrNextBreak(nowMs) {\n    const schedule = this.vmapBreaks;\n    let candidate;\n    const tol = this.config.driftToleranceMs ?? 1e3;\n    for (const b of schedule) {\n      if (this.consumedVmapBreakIds.has(this.getAdBreakKey(b))) {\n        continue;\n      }\n      const breakStartMs = this.resolveBreakStartMs(b);\n      if (breakStartMs == null) {\n        continue;\n      }\n      if (breakStartMs <= nowMs + tol && (candidate == null || breakStartMs > (this.resolveBreakStartMs(candidate) ?? 0))) {\n        candidate = b;\n      }\n    }\n    return candidate;\n  }\n  findBreakForTime(nowMs) {\n    const schedule = this.vmapBreaks;\n    for (const b of schedule) {\n      if (this.consumedVmapBreakIds.has(this.getAdBreakKey(b))) {\n        continue;\n      }\n      const breakStartMs = this.resolveBreakStartMs(b);\n      if (breakStartMs == null) {\n        continue;\n      }\n      if (b.durationMs) {\n        const end = breakStartMs + b.durationMs;\n        if (nowMs >= breakStartMs && nowMs < end) {\n          return b;\n        }\n        continue;\n      }\n      if (nowMs >= breakStartMs) {\n        return b;\n      }\n    }\n    return void 0;\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  beginNewAdPod() {\n    this.podCounter++;\n    this.adRequestPositionInBreak = 0;\n  }\n  generateVastUrlsWithCorrelators(baseUrl, count, adPlayer, palNonce, inAdBreak) {\n    const urls = [];\n    for (let i = 0; i < count; i++) {\n      this.adRequestPositionInBreak++;\n      const adWillPlayMuted = inAdBreak ? adPlayer.getOriginalMutedState() : this.video.muted;\n      const envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);\n      const urlWithMacros = applyVastMacros(baseUrl, {\n        correlator: this.viewCorrelator,\n        streamCorrelator: this.streamCorrelator,\n        pod: this.podCounter > 0 ? this.podCounter : void 0,\n        adPosition: this.adRequestPositionInBreak,\n        isCtv: envSignals.isCtv,\n        contentUrl: envSignals.contentUrl,\n        pageUrl: !envSignals.isCtv && typeof window !== \"undefined\" ? window.location.href : void 0,\n        adWillPlayMuted,\n        adWillAutoPlay: !!this.config.autoplay,\n        appId: envSignals.appId,\n        appName: envSignals.appName,\n        sessionId: envSignals.sessionId,\n        deviceId: envSignals.deviceId,\n        deviceIdType: envSignals.deviceIdType,\n        limitAdTracking: envSignals.limitAdTracking,\n        deviceTypeHint: envSignals.deviceTypeHint,\n        adTest: this.config.adTest,\n        consent: this.consentSignals\n      });\n      const finalUrl = palNonce.injectNonce(urlWithMacros);\n      console.log(\n        `[StormcloudVideoPlayer] Resolved ad request URL (pod=${this.podCounter}, pos=${this.adRequestPositionInBreak}):`,\n        finalUrl\n      );\n      urls.push(finalUrl);\n    }\n    return urls;\n  }\n  resolvePodParams(breakDurationMs) {\n    const maxDurationMs = breakDurationMs != null && breakDurationMs > 0 ? breakDurationMs : this.config.podMaxDurationMs;\n    const maxAds = this.config.podMaxAds && this.config.podMaxAds > 0 ? this.config.podMaxAds : this.apiNumberAds && this.apiNumberAds > 0 ? this.apiNumberAds : this.defaultPodMaxAds;\n    const minDurationMs = this.config.podExactDuration && maxDurationMs != null ? maxDurationMs : 0;\n    return { maxAds, minDurationMs, maxDurationMs };\n  }\n  generatePodVastUrl(baseUrl, podParams, adPlayer, palNonce, inAdBreak) {\n    const adWillPlayMuted = inAdBreak ? adPlayer.getOriginalMutedState() : this.video.muted;\n    const envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);\n    const urlWithMacros = applyVastMacros(baseUrl, {\n      correlator: this.viewCorrelator,\n      streamCorrelator: this.streamCorrelator,\n      pod: this.podCounter > 0 ? this.podCounter : void 0,\n      podMaxAds: podParams.maxAds,\n      podMinDurationMs: podParams.minDurationMs,\n      podMaxDurationMs: podParams.maxDurationMs,\n      isCtv: envSignals.isCtv,\n      contentUrl: envSignals.contentUrl,\n      pageUrl: !envSignals.isCtv && typeof window !== \"undefined\" ? window.location.href : void 0,\n      adWillPlayMuted,\n      adWillAutoPlay: !!this.config.autoplay,\n      appId: envSignals.appId,\n      appName: envSignals.appName,\n      sessionId: envSignals.sessionId,\n      deviceId: envSignals.deviceId,\n      deviceIdType: envSignals.deviceIdType,\n      limitAdTracking: envSignals.limitAdTracking,\n      deviceTypeHint: envSignals.deviceTypeHint,\n      adTest: this.config.adTest,\n      consent: this.consentSignals\n    });\n    const finalUrl = palNonce.injectNonce(urlWithMacros);\n    console.log(\n      `[StormcloudVideoPlayer] Resolved optimized-pod request URL (pod=${this.podCounter}, pmad=${podParams.maxAds}, pmnd=${podParams.minDurationMs}, pmxd=${podParams.maxDurationMs ?? \"?\"}):`,\n      finalUrl\n    );\n    return finalUrl;\n  }\n  // --- Tracking ---\n  initializeTracking() {\n    sendInitialTracking(this.config.licenseKey, buildAnalyticsContext(this.config)).then(() => {\n      this.heartbeatInterval = window.setInterval(() => {\n        this.sendHeartbeatIfNeeded();\n      }, 5e3);\n    }).catch((error) => {\n      if (this.debug) {\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, buildAnalyticsContext(this.config)).catch((error) => {\n        if (this.debug) {\n          console.warn(\n            \"[StormcloudVideoPlayer] Failed to send heartbeat:\",\n            error\n          );\n        }\n      });\n    }\n  }\n  destroyTracking() {\n    if (this.heartbeatInterval) {\n      clearInterval(this.heartbeatInterval);\n      this.heartbeatInterval = void 0;\n    }\n  }\n};\n\n// src/player/AdTimingService.ts\nvar AdTimingService = class {\n  constructor(config, video, callbacks) {\n    this.adRequestWatchdogToken = null;\n    this.adFailsafeToken = null;\n    this.ptsDriftEmaMs = 0;\n    this.adBreakPlayedDurationMs = 0;\n    this.adBreakEpoch = 0;\n    this.adRequestTokenCounter = 0;\n    this.activeAdRequestToken = null;\n    this.currentAdIndex = 0;\n    this.totalAdsInBreak = 0;\n    this.totalAdRequestsInBreak = 0;\n    this.maxTotalAdRequestsPerBreak = 10;\n    this.lastAdRequestTime = 0;\n    this.consecutiveFailures = 0;\n    this.maxConsecutiveFailures = 5;\n    this.minAdRequestIntervalMs = 3e3;\n    this.backoffBaseMs = 1e3;\n    this.maxBackoffMs = 15e3;\n    this.defaultMinRemainingMsToStartAd = 4e3;\n    this.failedVastUrls = /* @__PURE__ */ new Set();\n    this.temporaryFailureUrls = /* @__PURE__ */ new Map();\n    this.temporaryFailureCooldownMs = 3e4;\n    this.globalConsecutiveNoFills = 0;\n    this.globalNoFillThreshold = 3;\n    this.globalNoFillCooldownUntil = 0;\n    this.globalNoFillBackoffBaseMs = 5e3;\n    this.globalNoFillBackoffMaxMs = 6e4;\n    this.globalLastGamRequestTime = 0;\n    this.globalMinGamIntervalMs = 3e3;\n    this.config = config;\n    this.video = video;\n    this.callbacks = callbacks;\n  }\n  get debug() {\n    return !!this.config.debugAdTiming;\n  }\n  // --- Ad stop timer ---\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    this.adStopTimerId = void 0;\n    this.callbacks.onAdStopTimerFired();\n  }\n  // --- Ad start timer ---\n  scheduleAdStartIn(delayMs, marker = { type: \"start\" }, cueKey) {\n    this.clearAdStartTimer();\n    const ms = Math.max(0, Math.floor(delayMs));\n    if (ms === 0) {\n      this.callbacks.onAdStartTimerFired(marker, cueKey);\n      return;\n    }\n    this.adStartTimerId = window.setTimeout(() => {\n      this.callbacks.onAdStartTimerFired(marker, cueKey);\n    }, ms);\n  }\n  clearAdStartTimer() {\n    if (this.adStartTimerId != null) {\n      clearTimeout(this.adStartTimerId);\n      this.adStartTimerId = void 0;\n    }\n  }\n  // --- PTS drift ---\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  resolveScteBreakStartWallClockMs(marker) {\n    const nowWallClockMs = Date.now();\n    if (typeof marker.ptsSeconds !== \"number\") {\n      return nowWallClockMs;\n    }\n    const nowMs = this.video.currentTime * 1e3;\n    const estimatedCurrentPtsMs = nowMs - this.ptsDriftEmaMs;\n    const deltaMs = marker.ptsSeconds * 1e3 - estimatedCurrentPtsMs;\n    if (!Number.isFinite(deltaMs)) {\n      return nowWallClockMs;\n    }\n    return nowWallClockMs + Math.floor(deltaMs);\n  }\n  // --- Duration boundary ---\n  setAdBreakDurationBoundary(durationMs) {\n    this.expectedAdBreakDurationMs = durationMs;\n    if (durationMs != null && this.currentAdBreakStartWallClockMs != null) {\n      this.scteAdBreakEndWallClockMs = this.currentAdBreakStartWallClockMs + durationMs;\n    } else {\n      this.scteAdBreakEndWallClockMs = void 0;\n    }\n  }\n  scheduleAdStopAtBreakBoundary() {\n    if (this.expectedAdBreakDurationMs == null) {\n      return;\n    }\n    this.scheduleAdStopCountdown(this.getWallClockRemainingAdMs());\n  }\n  // --- Duration budget ---\n  getWallClockRemainingAdMs() {\n    const endWallClockMs = this.getAdBreakEndWallClockMs();\n    if (endWallClockMs != null) {\n      return Math.max(0, endWallClockMs - Date.now());\n    }\n    return 0;\n  }\n  getAdBreakEndWallClockMs() {\n    if (this.scteAdBreakEndWallClockMs != null) {\n      return this.scteAdBreakEndWallClockMs;\n    }\n    if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null) {\n      return void 0;\n    }\n    return this.currentAdBreakStartWallClockMs + this.expectedAdBreakDurationMs;\n  }\n  getDurationBudgetRemainingMs() {\n    if (this.expectedAdBreakDurationMs == null) {\n      return 0;\n    }\n    return Math.max(0, this.expectedAdBreakDurationMs - this.adBreakPlayedDurationMs);\n  }\n  getLoadedAdDurationMs(adController) {\n    const durationSec = adController.getLoadedAdDuration?.();\n    if (durationSec == null || durationSec <= 0) {\n      return 0;\n    }\n    return Math.round(durationSec * 1e3);\n  }\n  adFitsRemainingBudget(durationMs) {\n    if (durationMs <= 0) {\n      return true;\n    }\n    return durationMs <= this.getDurationBudgetRemainingMs();\n  }\n  logAdDurationDecision(accepted, durationMs, adController) {\n    if (!this.debug) {\n      return;\n    }\n    const remainingBudget = this.getDurationBudgetRemainingMs();\n    const adId = adController.getLoadedAdId?.() ?? \"unknown\";\n    if (accepted) {\n      console.log(\n        `[AD-DURATION] Accepted ad id=${adId}, duration=${durationMs}ms, budget remaining after play=${Math.max(0, remainingBudget - durationMs)}ms`\n      );\n    } else {\n      console.log(\n        `[AD-DURATION] Rejected ad id=${adId}, duration=${durationMs}ms exceeds remaining budget=${remainingBudget}ms \\u2014 requesting another ad`\n      );\n    }\n  }\n  recordPlayedAdDuration(adController) {\n    const durationMs = this.getLoadedAdDurationMs(adController);\n    if (durationMs <= 0) {\n      return;\n    }\n    this.adBreakPlayedDurationMs += durationMs;\n    if (this.debug) {\n      console.log(\n        `[AD-DURATION] Played ${durationMs}ms \\u2014 total played=${this.adBreakPlayedDurationMs}ms / ${this.expectedAdBreakDurationMs ?? \"?\"}ms`\n      );\n    }\n  }\n  ensureLoadedAdFitsBudget(adController) {\n    const durationMs = this.getLoadedAdDurationMs(adController);\n    const fits = this.adFitsRemainingBudget(durationMs);\n    this.logAdDurationDecision(fits, durationMs, adController);\n    return fits;\n  }\n  rejectLoadedAdForDuration(adController) {\n    try {\n      adController.destroy();\n    } catch {\n    }\n  }\n  markAdStarted() {\n    this.currentAdIndex++;\n    this.totalAdsInBreak = this.currentAdIndex;\n    this.totalAdRequestsInBreak++;\n    this.lastAdRequestTime = Date.now();\n  }\n  notePodAdStarted() {\n    this.currentAdIndex++;\n    this.totalAdsInBreak = this.currentAdIndex;\n  }\n  getRemainingAdMs() {\n    const wallClockRemaining = this.getWallClockRemainingAdMs();\n    const budgetRemaining = this.getDurationBudgetRemainingMs();\n    if (this.expectedAdBreakDurationMs == null) {\n      return wallClockRemaining;\n    }\n    return Math.min(wallClockRemaining, budgetRemaining);\n  }\n  getMinRemainingMsToStartAd() {\n    const configured = this.config.minRemainingMsToStartAd;\n    if (typeof configured === \"number\" && configured >= 0) {\n      return configured;\n    }\n    return this.defaultMinRemainingMsToStartAd;\n  }\n  hasTimeToStartAnotherAd() {\n    const minRemaining = this.getMinRemainingMsToStartAd();\n    return this.getWallClockRemainingAdMs() > minRemaining && this.getDurationBudgetRemainingMs() > minRemaining;\n  }\n  // --- Circuit breaker ---\n  isTemporaryAdError(error) {\n    const message = error?.message?.toLowerCase() || \"\";\n    if (message.includes(\"no ads available\") || message.includes(\"no fill\") || message.includes(\"nofill\")) {\n      return true;\n    }\n    if (message.includes(\"timeout\")) {\n      return true;\n    }\n    if (message.includes(\"rate limit\") || message.includes(\"too many requests\")) {\n      return true;\n    }\n    if (message.includes(\"ad playback error\")) {\n      return true;\n    }\n    return false;\n  }\n  isUrlInCooldown(vastTagUrl) {\n    const failureTime = this.temporaryFailureUrls.get(vastTagUrl);\n    if (failureTime == null) {\n      return false;\n    }\n    const elapsed = Date.now() - failureTime;\n    if (elapsed >= this.temporaryFailureCooldownMs) {\n      this.temporaryFailureUrls.delete(vastTagUrl);\n      return false;\n    }\n    return true;\n  }\n  cleanupTemporaryFailures() {\n    const now = Date.now();\n    for (const [url, timestamp] of this.temporaryFailureUrls) {\n      if (now - timestamp >= this.temporaryFailureCooldownMs) {\n        this.temporaryFailureUrls.delete(url);\n      }\n    }\n  }\n  isGamInCooldown() {\n    return Date.now() < this.globalNoFillCooldownUntil;\n  }\n  recordGamNoFill() {\n    this.globalConsecutiveNoFills++;\n    if (this.globalConsecutiveNoFills >= this.globalNoFillThreshold) {\n      const exponent = this.globalConsecutiveNoFills - this.globalNoFillThreshold;\n      const backoff = Math.min(\n        this.globalNoFillBackoffBaseMs * Math.pow(2, exponent),\n        this.globalNoFillBackoffMaxMs\n      );\n      this.globalNoFillCooldownUntil = Date.now() + backoff;\n      if (this.debug) {\n        console.log(\n          `[CIRCUIT-BREAKER] GAM cooldown activated: ${backoff}ms (${this.globalConsecutiveNoFills} consecutive no-fills)`\n        );\n      }\n    }\n  }\n  resetGamNoFillCounter() {\n    if (this.globalConsecutiveNoFills > 0 && this.debug) {\n      console.log(\n        `[CIRCUIT-BREAKER] Resetting no-fill counter (was ${this.globalConsecutiveNoFills})`\n      );\n    }\n    this.globalConsecutiveNoFills = 0;\n    this.globalNoFillCooldownUntil = 0;\n  }\n  async enforceGlobalRateLimit() {\n    const now = Date.now();\n    const elapsed = now - this.globalLastGamRequestTime;\n    if (elapsed < this.globalMinGamIntervalMs) {\n      const waitMs = this.globalMinGamIntervalMs - elapsed;\n      if (this.debug) {\n        console.log(`[RATE-LIMIT] Waiting ${waitMs}ms before next GAM request`);\n      }\n      await new Promise((resolve) => setTimeout(resolve, waitMs));\n    }\n    this.globalLastGamRequestTime = Date.now();\n  }\n  // --- Watchdog ---\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.callbacks.onWatchdogTimeout();\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  // --- Failsafe ---\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      });\n      this.callbacks.onFailsafeTimeout();\n    }, failsafeMs);\n    this.logAdState(\"ad_failsafe_started\", { token, failsafeMs });\n  }\n  clearAdFailsafeTimer() {\n    if (this.adFailsafeTimerId != null) {\n      clearTimeout(this.adFailsafeTimerId);\n      this.logAdState(\"ad_failsafe_cleared\", { token: this.adFailsafeToken });\n      this.adFailsafeTimerId = void 0;\n    }\n    this.adFailsafeToken = null;\n  }\n  logAdState(event, extra = {}, adPlayer, inAdBreak, showAds) {\n    if (!this.debug) {\n      return;\n    }\n    console.log(\"[StormcloudVideoPlayer][AdState]\", {\n      event,\n      timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n      showAds: showAds ?? false,\n      adPlaying: adPlayer?.isAdPlaying() ?? false,\n      inAdBreak: inAdBreak ?? false,\n      activeAdRequestToken: this.activeAdRequestToken,\n      ...extra\n    });\n  }\n  // --- Reset for ad break end ---\n  resetForBreakEnd() {\n    this.clearAdStopTimer();\n    this.clearAdStartTimer();\n    this.clearAdRequestWatchdog();\n    this.clearAdFailsafeTimer();\n    this.activeAdRequestToken = null;\n    this.expectedAdBreakDurationMs = void 0;\n    this.currentAdBreakStartWallClockMs = void 0;\n    this.scteAdBreakEndWallClockMs = void 0;\n    this.adBreakPlayedDurationMs = 0;\n    this.currentAdIndex = 0;\n    this.totalAdsInBreak = 0;\n    this.consecutiveFailures = 0;\n    this.globalConsecutiveNoFills = 0;\n    this.adBreakEpoch++;\n  }\n  destroy() {\n    this.clearAdStopTimer();\n    this.clearAdStartTimer();\n    this.clearAdFailsafeTimer();\n    this.clearAdRequestWatchdog();\n  }\n};\n\n// src/player/AdPreloadPool.ts\nvar AdPreloadPool = class {\n  constructor(deps) {\n    this.pool = [];\n    this.maxPoolSize = 2;\n    this.poolActive = false;\n    this.loopRunning = false;\n    this.deps = deps;\n  }\n  get active() {\n    return this.poolActive;\n  }\n  set active(value) {\n    this.poolActive = value;\n  }\n  get isLoopRunning() {\n    return this.loopRunning;\n  }\n  startPreloadPool(baseVastUrl, initialUrls, startLoopImmediately = true) {\n    if (this.poolActive) {\n      if (this.deps.debug) {\n        console.log(\"[PRELOAD-POOL] Already active, skipping duplicate start\");\n      }\n      return;\n    }\n    this.poolActive = true;\n    if (this.deps.debug) {\n      console.log(`[PRELOAD-POOL] Starting preload pool EARLY (target size: ${this.maxPoolSize})`);\n      console.log(`[PRELOAD-POOL] Ad break hasn't started yet, but preloading ads in advance`);\n    }\n    for (const url of initialUrls) {\n      if (this.pool.length < this.maxPoolSize) {\n        this.preloadAdIntoPool(url);\n      }\n    }\n    if (startLoopImmediately) {\n      this.preloadPoolLoop(baseVastUrl);\n    } else if (this.deps.debug) {\n      console.log(\n        \"[PRELOAD-POOL] Pre-break mode: preloaded once, waiting for SCTE start to continue fetching\"\n      );\n    }\n  }\n  async preloadAdIntoPool(vastUrl) {\n    const timing = this.deps.timing;\n    if (timing.isGamInCooldown()) {\n      if (this.deps.debug) {\n        console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping preload\");\n      }\n      return;\n    }\n    if (this.pool.some((entry) => entry.vastUrl === vastUrl) || timing.failedVastUrls.has(vastUrl) || timing.isUrlInCooldown(vastUrl)) {\n      return;\n    }\n    if (this.pool.length >= this.maxPoolSize) {\n      return;\n    }\n    if (this.deps.debug) {\n      console.log(`[PRELOAD-POOL] Preloading ad into pool: ${vastUrl}`);\n    }\n    const epoch = timing.adBreakEpoch;\n    const loadPromise = (async () => {\n      let hasAdError = false;\n      let adErrorPayload = null;\n      let errorListenerCleanup = null;\n      try {\n        const continueLiveStreamDuringAds = this.deps.shouldContinueLiveStreamDuringAds();\n        const preloadAd = this.deps.createAdPlayer(continueLiveStreamDuringAds);\n        preloadAd.initialize();\n        const errorListener = (payload) => {\n          hasAdError = true;\n          adErrorPayload = payload;\n        };\n        preloadAd.on(\"ad_error\", errorListener);\n        errorListenerCleanup = () => preloadAd.off(\"ad_error\", errorListener);\n        await timing.enforceGlobalRateLimit();\n        await preloadAd.requestAds(vastUrl);\n        preloadAd.pause();\n        await new Promise((resolve) => setTimeout(resolve, 1500));\n        preloadAd.pause();\n        if (hasAdError) {\n          const isNoFill = adErrorPayload?.isNoFill || adErrorPayload?.code === 303 || adErrorPayload?.vastErrorCode === 303;\n          if (errorListenerCleanup) {\n            errorListenerCleanup();\n          }\n          preloadAd.destroy();\n          timing.recordGamNoFill();\n          if (isNoFill) {\n            if (this.deps.debug) {\n              console.log(`[PRELOAD-POOL] Ad preload returned no-fill: ${vastUrl}`);\n            }\n            timing.temporaryFailureUrls.set(vastUrl, Date.now());\n          } else {\n            if (this.deps.debug) {\n              console.log(`[PRELOAD-POOL] Ad preload failed with error: ${vastUrl}`, adErrorPayload);\n            }\n            if (adErrorPayload && !timing.isTemporaryAdError(adErrorPayload)) {\n              timing.failedVastUrls.add(vastUrl);\n            } else {\n              timing.temporaryFailureUrls.set(vastUrl, Date.now());\n            }\n          }\n          return;\n        }\n        if (!this.poolActive || epoch !== timing.adBreakEpoch) {\n          if (this.deps.debug) {\n            console.log(\n              \"[PRELOAD-POOL] Discarding preloaded ad - break ended during fetch\"\n            );\n          }\n          if (errorListenerCleanup) {\n            errorListenerCleanup();\n          }\n          try {\n            preloadAd.destroy();\n          } catch {\n          }\n          return;\n        }\n        const poolEntry = {\n          vastUrl,\n          adController: preloadAd,\n          loadedAt: Date.now(),\n          isReady: true,\n          loadPromise: Promise.resolve()\n        };\n        const loadedDuration = preloadAd.getLoadedAdDuration?.();\n        if (loadedDuration != null && loadedDuration > 0) {\n          poolEntry.durationSeconds = loadedDuration;\n        }\n        const lateErrorListener = (payload) => {\n          const index = this.pool.findIndex((entry) => entry.vastUrl === vastUrl);\n          if (index >= 0) {\n            this.pool.splice(index, 1);\n            if (this.deps.debug) {\n              console.log(`[PRELOAD-POOL] Late error detected, removed from pool: ${vastUrl}`, payload);\n            }\n            try {\n              preloadAd.destroy();\n            } catch {\n            }\n          }\n        };\n        preloadAd.on(\"ad_error\", lateErrorListener);\n        this.pool.push(poolEntry);\n        if (this.deps.debug) {\n          console.log(`[PRELOAD-POOL] Ad preloaded (no errors detected within timeout) (pool size: ${this.pool.length}/${this.maxPoolSize}, duration=${poolEntry.durationSeconds ?? \"?\"}s)`);\n        }\n        if (errorListenerCleanup) {\n          errorListenerCleanup();\n        }\n      } catch (error) {\n        if (errorListenerCleanup) {\n          errorListenerCleanup();\n        }\n        timing.recordGamNoFill();\n        if (this.deps.debug) {\n          console.warn(`[PRELOAD-POOL] Failed to preload ad: ${vastUrl}`, error);\n        }\n        if (error instanceof Error && !timing.isTemporaryAdError(error)) {\n          timing.failedVastUrls.add(vastUrl);\n        } else if (error instanceof Error && timing.isTemporaryAdError(error)) {\n          timing.temporaryFailureUrls.set(vastUrl, Date.now());\n        }\n      }\n    })();\n    loadPromise.catch(() => {\n    });\n  }\n  async preloadPoolLoop(baseVastUrl) {\n    if (this.loopRunning) {\n      return;\n    }\n    this.loopRunning = true;\n    const epoch = this.deps.timing.adBreakEpoch;\n    if (this.deps.debug) {\n      console.log(\"[PRELOAD-POOL] Starting continuous preload loop\");\n    }\n    while (this.poolActive && epoch === this.deps.timing.adBreakEpoch) {\n      if (this.deps.timing.isGamInCooldown()) {\n        if (this.deps.debug) {\n          console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, stopping preload pool loop\");\n        }\n        break;\n      }\n      if (!this.deps.isInAdBreak() && this.pool.length >= this.maxPoolSize) {\n        await new Promise((resolve) => setTimeout(resolve, 2e3));\n        continue;\n      }\n      if (!this.deps.isInAdBreak() && this.deps.getPendingAdBreak() === null) {\n        if (this.deps.debug) {\n          console.log(\"[PRELOAD-POOL] Ad break cancelled, stopping preload pool\");\n        }\n        break;\n      }\n      while (this.pool.length < this.maxPoolSize) {\n        if (!this.poolActive || epoch !== this.deps.timing.adBreakEpoch || this.deps.timing.isGamInCooldown()) {\n          break;\n        }\n        if (this.deps.isInAdBreak() && !this.deps.timing.hasTimeToStartAnotherAd()) {\n          if (this.deps.debug) {\n            console.log(\"[PRELOAD-POOL] Not enough ad break time left, stopping preload\");\n          }\n          break;\n        }\n        const newUrls = this.deps.generateVastUrlsWithCorrelators(baseVastUrl, 1);\n        const newUrl = newUrls[0];\n        if (newUrl && !this.deps.timing.failedVastUrls.has(newUrl) && !this.deps.timing.isUrlInCooldown(newUrl)) {\n          await this.preloadAdIntoPool(newUrl);\n        }\n        await new Promise((resolve) => setTimeout(resolve, 1e3));\n      }\n      await new Promise((resolve) => setTimeout(resolve, 2e3));\n    }\n    this.loopRunning = false;\n    if (this.deps.debug) {\n      console.log(\"[PRELOAD-POOL] Preload loop ended\");\n    }\n  }\n  getPreloadedAd() {\n    if (this.pool.length === 0) {\n      return null;\n    }\n    const entry = this.pool.shift();\n    if (!entry || !entry.isReady) {\n      return null;\n    }\n    if (this.deps.debug) {\n      console.log(`[PRELOAD-POOL] Using preloaded ad from pool (${this.pool.length} remaining)`);\n    }\n    return {\n      vastUrl: entry.vastUrl,\n      adController: entry.adController\n    };\n  }\n  stop() {\n    this.poolActive = false;\n    this.loopRunning = false;\n    for (const entry of this.pool) {\n      try {\n        entry.adController.destroy();\n      } catch (error) {\n        if (this.deps.debug) {\n          console.warn(\"[PRELOAD-POOL] Error destroying preloaded controller:\", error);\n        }\n      }\n    }\n    this.pool = [];\n    if (this.deps.debug) {\n      console.log(\"[PRELOAD-POOL] Preload pool stopped and cleaned up\");\n    }\n  }\n};\n\n// src/player/PlaceholderLayer.ts\nvar PlaceholderLayer = class {\n  constructor(video, debug) {\n    this.video = video;\n    this.debug = debug;\n  }\n  ensureContainer() {\n    if (this.container) {\n      return;\n    }\n    const el = document.createElement(\"div\");\n    el.style.position = \"absolute\";\n    el.style.left = \"0\";\n    el.style.top = \"0\";\n    el.style.right = \"0\";\n    el.style.bottom = \"0\";\n    el.style.display = \"none\";\n    el.style.alignItems = \"center\";\n    el.style.justifyContent = \"center\";\n    el.style.pointerEvents = \"none\";\n    el.style.zIndex = \"5\";\n    el.style.backgroundColor = \"#000\";\n    el.style.transition = \"opacity 0.3s ease-in-out\";\n    el.style.opacity = \"0\";\n    if (!this.video.parentElement) {\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Video element has no parent for placeholder container\");\n      }\n      return;\n    }\n    this.video.parentElement.appendChild(el);\n    this.container = el;\n  }\n  show() {\n    this.ensureContainer();\n    if (!this.container) {\n      return;\n    }\n    if (!this.video.muted) {\n      this.video.muted = true;\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Muted video when showing placeholder\");\n      }\n    }\n    const wasHidden = this.container.style.display === \"none\" || this.container.style.opacity === \"0\";\n    if (wasHidden) {\n      this.container.style.transition = \"none\";\n    } else {\n      this.container.style.transition = \"opacity 0.3s ease-in-out\";\n    }\n    this.container.style.backgroundColor = \"#000\";\n    this.container.style.display = \"flex\";\n    this.container.offsetHeight;\n    this.container.style.opacity = \"1\";\n    this.container.style.pointerEvents = \"auto\";\n    if (wasHidden) {\n      requestAnimationFrame(() => {\n        if (this.container) {\n          this.container.style.transition = \"opacity 0.3s ease-in-out\";\n        }\n      });\n    }\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Showing placeholder layer (between content and ad layer)\");\n    }\n  }\n  hide() {\n    if (!this.container) {\n      return;\n    }\n    this.container.style.opacity = \"0\";\n    setTimeout(() => {\n      if (this.container) {\n        this.container.style.display = \"none\";\n        this.container.style.pointerEvents = \"none\";\n        this.container.style.backgroundColor = \"#000\";\n      }\n    }, 300);\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Hiding placeholder layer\");\n    }\n  }\n  destroy() {\n    if (this.container) {\n      if (this.container.parentElement) {\n        this.container.parentElement.removeChild(this.container);\n      }\n      this.container = void 0;\n    }\n  }\n};\n\n// src/player/HlsEngine.ts\nvar import_hls2 = __toESM(require(\"hls.js\"), 1);\nvar HlsEngine = class {\n  constructor(config, video, cueManager, timing, callbacks) {\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.config = config;\n    this.video = video;\n    this.cueManager = cueManager;\n    this.timing = timing;\n    this.callbacks = callbacks;\n  }\n  get debug() {\n    return !!this.config.debugAdTiming;\n  }\n  shouldUseNativeHls(getStreamType) {\n    const streamType = 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  async setupNativeHls() {\n    this.nativeHlsMode = true;\n    this.videoSrcProtection = this.config.src;\n    this.video.src = this.config.src;\n    this.isLiveStream = this.config.isLiveStream ?? (this.config.lowLatencyMode ?? false);\n    if (this.debug) {\n      const adBehavior = this.isLiveStream ? \"live (main video continues muted during ads)\" : \"vod (main video pauses during ads)\";\n      console.log(\n        \"[StormcloudVideoPlayer] Using native HLS playback:\",\n        {\n          isLive: this.isLiveStream,\n          allowNativeHls: this.config.allowNativeHls,\n          adBehavior\n        }\n      );\n    }\n    if (this.config.autoplay) {\n      await this.video.play()?.catch(() => {\n      });\n    }\n  }\n  setupHls() {\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.config.isLiveStream ?? (this.hls?.levels?.some(\n        (level) => level?.details?.live === true || level?.details?.type === \"LIVE\"\n      ) ?? false);\n      await this.callbacks.onManifestParsed(this.isLiveStream);\n      this.bufferedSegmentsCount = 0;\n      this.hasInitialBufferCompleted = false;\n      this.shouldAutoplayAfterBuffering = !!this.config.autoplay;\n      const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Waiting for\",\n          minSegments,\n          \"segments to buffer before playback\"\n        );\n      }\n      if (minSegments === 0 || !this.config.autoplay) {\n        this.hasInitialBufferCompleted = true;\n        if (this.config.autoplay) {\n          await this.video.play()?.catch(() => {\n          });\n        }\n      }\n    });\n    this.hls.on(import_hls2.default.Events.LEVEL_LOADED, (_evt, data) => {\n      if (this.callbacks.isInAdBreak() || this.callbacks.hasPendingAdBreak()) {\n        return;\n      }\n      const details = data?.details;\n      if (!details || !details.fragments || details.fragments.length === 0) {\n        return;\n      }\n      const fragmentsToScan = Math.min(5, details.fragments.length);\n      for (let i = 0; i < fragmentsToScan; i++) {\n        const frag = details.fragments[i];\n        const tagList = frag?.tagList;\n        if (!Array.isArray(tagList)) continue;\n        for (const entry of tagList) {\n          let tag = \"\";\n          let value = \"\";\n          if (Array.isArray(entry)) {\n            tag = String(entry[0] ?? \"\");\n            value = String(entry[1] ?? \"\");\n          } else if (typeof entry === \"string\") {\n            const idx = entry.indexOf(\":\");\n            if (idx >= 0) {\n              tag = entry.substring(0, idx);\n              value = entry.substring(idx + 1);\n            } else {\n              tag = entry;\n            }\n          }\n          if (!tag) continue;\n          if (tag.includes(\"EXT-X-CUE-OUT\") || tag.includes(\"EXT-X-DATERANGE\")) {\n            const attrs = tag.includes(\"EXT-X-DATERANGE\") ? parseAttributeList(value) : {};\n            const hasScteOut = tag.includes(\"EXT-X-CUE-OUT\") || \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== void 0;\n            if (hasScteOut) {\n              const durationSeconds = parseCueOutDuration(value);\n              const marker = {\n                type: \"start\",\n                ...durationSeconds !== void 0 ? { durationSeconds } : {},\n                raw: { tag, value, earlyDetection: true }\n              };\n              if (this.debug) {\n                console.log(\"[StormcloudVideoPlayer] EARLY SCTE-35 DETECTION: Ad break marker found in fragment\", i, \"- starting pre-fetch (NOT playing yet)\");\n              }\n              this.callbacks.onScte35Cue(marker, {\n                ...this.cueManager.createScte35CueContext(\"manifest\", \"early\", frag)\n              });\n              return;\n            }\n          }\n        }\n      }\n    });\n    this.hls.on(import_hls2.default.Events.FRAG_BUFFERED, async (_evt, _data) => {\n      if (this.hasInitialBufferCompleted) {\n        return;\n      }\n      this.bufferedSegmentsCount++;\n      const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n      if (this.debug) {\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.debug) {\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.debug) {\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_LOADED, (_evt, data) => {\n      this.processFragmentScte35Payload(\n        data?.payload,\n        typeof data?.frag?.sn === \"number\" ? data.frag.sn : void 0,\n        getFragmentStartSeconds(data?.frag)\n      );\n    });\n    this.hls.on(import_hls2.default.Events.FRAG_DECRYPTED, (_evt, data) => {\n      this.processFragmentScte35Payload(\n        data?.payload,\n        typeof data?.frag?.sn === \"number\" ? data.frag.sn : void 0,\n        getFragmentStartSeconds(data?.frag)\n      );\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)) {\n        this.callbacks.activatePendingCuesForFragment(frag);\n        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        if (!tag) continue;\n        if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n          const prog = 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.callbacks.onScte35Cue(marker, {\n            ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag)\n          });\n        } else if (tag.includes(\"EXT-X-CUE-OUT\")) {\n          const durationSeconds = parseCueOutDuration(value);\n          const marker = {\n            type: \"start\",\n            ...durationSeconds !== void 0 ? { durationSeconds } : {},\n            raw: { tag, value }\n          };\n          this.callbacks.onScte35Cue(marker, {\n            ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag)\n          });\n        } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n          this.callbacks.onScte35Cue(\n            { type: \"end\", raw: { tag, value } },\n            {\n              ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag)\n            }\n          );\n        } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n          const attrs = 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 = 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.callbacks.onScte35Cue(marker, {\n              ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag)\n            });\n          }\n          if (hasScteIn) {\n            this.callbacks.onScte35Cue(\n              { type: \"end\", raw: { tag, value, attrs } },\n              {\n                ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag)\n              }\n            );\n          }\n        }\n      }\n      this.callbacks.activatePendingCuesForFragment(frag);\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.callbacks.onFatalDestroy();\n            break;\n        }\n      }\n    });\n    this.hls.attachMedia(this.video);\n  }\n  onId3Tag(tag) {\n    if (typeof tag.ptsSeconds === \"number\") {\n      this.timing.updatePtsDrift(tag.ptsSeconds);\n    }\n    const marker = parseScte35FromId3(tag);\n    if (marker) {\n      this.callbacks.onScte35Cue(marker, {\n        source: \"id3\",\n        readiness: \"playback\"\n      });\n    }\n  }\n  processFragmentScte35Payload(payloadData, fragmentSn, fragmentStartSeconds) {\n    const payload = normalizeFragmentPayload(payloadData);\n    if (!payload) {\n      return;\n    }\n    const markers = parseScte35FromTsPackets(\n      payload,\n      this.cueManager.tsScte35Pids,\n      this.cueManager.pmtPids,\n      this.cueManager.processedTsScte35Sections\n    );\n    markers.forEach((marker) => {\n      const context = {\n        source: \"ts\",\n        readiness: \"early\"\n      };\n      if (fragmentSn !== void 0) {\n        context.fragmentSn = fragmentSn;\n      }\n      if (fragmentStartSeconds !== void 0) {\n        context.fragmentStartSeconds = fragmentStartSeconds;\n      }\n      this.callbacks.onScte35Cue(marker, context);\n    });\n  }\n  getLiveSyncPosition() {\n    const pos = this.hls?.liveSyncPosition;\n    return typeof pos === \"number\" && Number.isFinite(pos) ? pos : void 0;\n  }\n  destroy() {\n    this.hls?.destroy();\n    this.hls = void 0;\n  }\n};\n\n// src/player/PlayerControls.ts\nfunction getAdAudioVolume(adPlayer) {\n  return adPlayer.getOriginalMutedState() ? 0 : adPlayer.getOriginalVolume();\n}\nfunction toggleMute(video, adPlayer, debug) {\n  if (adPlayer.isAdPlaying()) {\n    const newMutedState = !adPlayer.getOriginalMutedState();\n    const restoreVolume = adPlayer.getOriginalVolume() || 1;\n    adPlayer.updateOriginalMutedState(newMutedState, video.volume);\n    adPlayer.setAdVolume(newMutedState ? 0 : restoreVolume);\n    if (debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] Mute toggle during ad - immediately applied:\",\n        newMutedState\n      );\n    }\n  } else {\n    video.muted = !video.muted;\n    adPlayer.updateOriginalMutedState(video.muted, video.volume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] Muted:\", video.muted);\n    }\n  }\n}\nfunction toggleFullscreen(video, debug) {\n  return new Promise((resolve, reject) => {\n    if (!document.fullscreenElement) {\n      const container = video.parentElement;\n      if (!container) {\n        reject(new Error(\"No parent container found for fullscreen\"));\n        return;\n      }\n      container.requestFullscreen().then(() => {\n        if (debug) {\n          console.log(\"[StormcloudVideoPlayer] Entered fullscreen\");\n        }\n        resolve();\n      }).catch((err) => {\n        if (debug) {\n          console.error(\"[StormcloudVideoPlayer] Fullscreen error:\", err);\n        }\n        reject(err);\n      });\n    } else {\n      document.exitFullscreen().then(() => {\n        if (debug) {\n          console.log(\"[StormcloudVideoPlayer] Exited fullscreen\");\n        }\n        resolve();\n      }).catch((err) => {\n        if (debug) {\n          console.error(\n            \"[StormcloudVideoPlayer] Exit fullscreen error:\",\n            err\n          );\n        }\n        reject(err);\n      });\n    }\n  });\n}\nfunction isMuted(video, adPlayer) {\n  if (adPlayer.isAdPlaying()) {\n    return adPlayer.getOriginalMutedState();\n  }\n  return video.muted;\n}\nfunction setMuted(video, adPlayer, muted, debug) {\n  const adPlaying = adPlayer.isAdPlaying();\n  if (adPlaying && muted === video.muted) {\n    if (debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] setMuted reflective update during ad ignored\",\n        { muted }\n      );\n    }\n    return;\n  }\n  video.muted = muted;\n  if (adPlaying) {\n    adPlayer.updateOriginalMutedState(muted, video.volume);\n    adPlayer.setAdVolume(muted ? 0 : 1);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setMuted applied during ad\", {\n        muted\n      });\n    }\n    return;\n  }\n  adPlayer.updateOriginalMutedState(muted, video.volume);\n  if (debug) {\n    console.log(\"[StormcloudVideoPlayer] setMuted called:\", muted);\n  }\n}\nfunction setVolume(video, adPlayer, volume, debug) {\n  const clampedVolume = Math.max(0, Math.min(1, volume));\n  const adPlaying = adPlayer.isAdPlaying();\n  if (adPlaying) {\n    adPlayer.setAdVolume(clampedVolume);\n    adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setVolume applied during ad\", {\n        volume: clampedVolume\n      });\n    }\n  } else {\n    video.volume = clampedVolume;\n    video.muted = clampedVolume === 0;\n    adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setVolume called:\", clampedVolume);\n    }\n  }\n}\nfunction getVolume(video, adPlayer) {\n  const adPlaying = adPlayer.isAdPlaying();\n  if (adPlaying) {\n    return adPlayer.getAdVolume();\n  }\n  return video.volume;\n}\nfunction isFullscreen() {\n  return !!document.fullscreenElement;\n}\nfunction resizePlayer(video, adPlayer, debug) {\n  if (debug) {\n    console.log(\"[StormcloudVideoPlayer] Resizing player\");\n  }\n  if (adPlayer && adPlayer.isAdPlaying()) {\n    const width = video.clientWidth || 640;\n    const height = video.clientHeight || 480;\n    if (debug) {\n      console.log(\n        `[StormcloudVideoPlayer] Resizing ads manager to ${width}x${height}`\n      );\n    }\n    adPlayer.resize(width, height);\n  }\n}\n\n// src/player/AdBreakOrchestrator.ts\nvar AdBreakOrchestrator = class {\n  constructor(host, timing, preloadPool, adConfig, cueManager, placeholder) {\n    this.inAdBreak = false;\n    this.showAds = false;\n    this.isShowingPlaceholder = false;\n    this.adDetectSentForCurrentBreak = false;\n    this.continuousFetchingActive = false;\n    this.continuousFetchLoopRunning = false;\n    this.adRequestQueue = [];\n    this.adPodQueue = [];\n    this.maxPlaceholderDurationMs = 5e3;\n    this.pendingAdBreak = null;\n    this.host = host;\n    this.timing = timing;\n    this.preloadPool = preloadPool;\n    this.adConfig = adConfig;\n    this.cueManager = cueManager;\n    this.placeholder = placeholder;\n  }\n  get debug() {\n    return !!this.host.config.debugAdTiming;\n  }\n  get analyticsContext() {\n    return buildAnalyticsContext(this.host.config);\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  IMA event listeners\n  // ───────────────────────────────────────────────────────────────\n  get optimizedPodsEnabled() {\n    return this.host.config.optimizedPods !== false;\n  }\n  attachImaEventListeners() {\n    const adPlayer = this.host.getAdPlayer();\n    adPlayer.on(\"pod_ad_started\", (payload) => {\n      this.timing.notePodAdStarted();\n      if (this.debug) {\n        console.log(\n          `[POD] Playing pod ad ${payload?.index != null ? payload.index + 1 : \"?\"}/${payload?.total ?? \"?\"}`\n        );\n      }\n    });\n    adPlayer.on(\"all_ads_completed\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n      this.timing.consecutiveFailures = 0;\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] all_ads_completed event received - remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n      if (this.inAdBreak) {\n        if (this.timing.hasTimeToStartAnotherAd()) {\n          this.tryNextAvailableAdWithRateLimit();\n        } else {\n          this.handleAdPodComplete();\n        }\n      }\n    });\n    adPlayer.on(\"ad_error\", (errorPayload) => {\n      let errorMessage = \"Ad playback failed\";\n      if (errorPayload) {\n        const errorCode = errorPayload.code || errorPayload.errorCode || \"unknown\";\n        const vastErrorCode = errorPayload.vastErrorCode;\n        const message = errorPayload.message || errorPayload.errorMessage || \"Unknown error\";\n        const cause = errorPayload.cause || errorPayload.innerError || errorPayload.error;\n        errorMessage = `Ad error: AdError ${errorCode}: ${message}`;\n        if (vastErrorCode && vastErrorCode !== \"N/A\" && vastErrorCode !== errorCode) {\n          errorMessage += ` (VAST Error Code: ${vastErrorCode})`;\n        }\n        if (cause) {\n          const causeMessage = typeof cause === \"string\" ? cause : cause.message || String(cause);\n          errorMessage += `. Caused by: ${causeMessage}`;\n        }\n      }\n      console.error(\"[AD-ERROR]\", errorMessage, errorPayload || \"\");\n      this.handleAdFailure();\n    });\n    adPlayer.on(\"content_pause\", () => {\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = true;\n      this.timing.resetGamNoFillCounter();\n      if (this.inAdBreak && this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)\");\n        }\n      }\n      this.host.getAdPlayer().setAdVolume(getAdAudioVolume(this.host.getAdPlayer()));\n      if (this.isShowingPlaceholder) {\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Hiding placeholder - new ads starting\");\n        }\n        this.host.getAdPlayer().hidePlaceholder();\n        this.isShowingPlaceholder = false;\n      }\n    });\n    adPlayer.on(\"content_resume\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      if (!this.host.video.muted) {\n        this.host.video.muted = true;\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Muted video on content_resume (ad ended, gap between ads)\");\n        }\n      }\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = false;\n      if (!this.inAdBreak) {\n        return;\n      }\n      this.timing.consecutiveFailures = 0;\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n      if (this.debug) {\n        console.log(\n          `[CONTINUOUS-FETCH] content_resume event: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n      if (this.timing.hasTimeToStartAnotherAd()) {\n        this.tryNextAvailableAdWithRateLimit();\n      } else {\n        this.handleAdPodComplete();\n      }\n    });\n  }\n  recreateAdController() {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Recreating AdController for new ad\");\n    }\n    const shouldShowPlaceholder = this.inAdBreak && this.showAds;\n    const adPlayer = this.host.getAdPlayer();\n    if (shouldShowPlaceholder && adPlayer) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Showing placeholder before destroying old AdController\");\n      }\n      this.placeholder.show();\n      adPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n    const preservedMutedState = adPlayer.getOriginalMutedState();\n    const preservedVolumeState = adPlayer.getOriginalVolume();\n    if (adPlayer) {\n      try {\n        adPlayer.destroy();\n        this.host.video.muted = true;\n      } catch (error) {\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] Error destroying old AdController:\", error);\n        }\n      }\n    }\n    const continueLiveStreamDuringAds = this.host.shouldContinueLiveStreamDuringAds();\n    const newAdPlayer = this.host.createAdPlayer(continueLiveStreamDuringAds);\n    this.host.setAdPlayer(newAdPlayer);\n    newAdPlayer.initialize();\n    newAdPlayer.updateOriginalMutedState(preservedMutedState, preservedVolumeState);\n    this.attachImaEventListeners();\n    if (shouldShowPlaceholder) {\n      this.placeholder.show();\n      newAdPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n  }\n  clearPendingAdBreak() {\n    if (this.prefetchTimerId != null) {\n      clearTimeout(this.prefetchTimerId);\n      this.prefetchTimerId = void 0;\n    }\n    this.pendingAdBreak = null;\n    this.cueManager.pendingScte35CueKey = void 0;\n    this.adConfig.podAssignedByPrefetch = false;\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Ad break start\n  // ───────────────────────────────────────────────────────────────\n  async handleAdStart(_marker) {\n    const scheduled = this.adConfig.findCurrentOrNextBreak(\n      this.host.video.currentTime * 1e3\n    );\n    if (scheduled) {\n      this.adConfig.consumedVmapBreakIds.add(this.adConfig.getAdBreakKey(scheduled));\n    }\n    const tags = this.adConfig.selectVastTagsForBreak(scheduled);\n    let baseVastUrl;\n    if (tags && tags.length > 0 && tags[0]) {\n      baseVastUrl = tags[0];\n    } else if (this.adConfig.apiVastTagUrl) {\n      baseVastUrl = this.adConfig.apiVastTagUrl;\n    } else {\n      this.clearPendingAdBreak();\n      return;\n    }\n    const adBreakDurationMs = _marker.durationSeconds != null ? _marker.durationSeconds * 1e3 : scheduled?.durationMs;\n    if (this.debug) {\n      const mode = this.host.config.isLiveStream ? \"LIVE\" : \"VOD\";\n      console.log(\n        `[CONTINUOUS-FETCH] ${mode} MODE: Target duration=${adBreakDurationMs}ms`\n      );\n    }\n    this.timing.failedVastUrls.clear();\n    this.timing.temporaryFailureUrls.clear();\n    this.timing.consecutiveFailures = 0;\n    this.continuousFetchingActive = true;\n    this.isShowingPlaceholder = false;\n    this.timing.totalAdRequestsInBreak = 0;\n    if (this.adConfig.podAssignedByPrefetch) {\n      this.adConfig.podAssignedByPrefetch = false;\n    } else {\n      this.adConfig.beginNewAdPod();\n    }\n    const currentMuted = this.host.video.muted;\n    const currentVolume = this.host.video.volume;\n    this.host.getAdPlayer().updateOriginalMutedState(currentMuted, currentVolume);\n    this.inAdBreak = true;\n    this.timing.adBreakPlayedDurationMs = 0;\n    this.timing.currentAdIndex = 0;\n    this.timing.totalAdsInBreak = 0;\n    this.adPodQueue = [];\n    this.showAds = false;\n    if (this.timing.expectedAdBreakDurationMs == null && adBreakDurationMs != null) {\n      this.timing.expectedAdBreakDurationMs = adBreakDurationMs;\n    }\n    if (this.optimizedPodsEnabled) {\n      const podPlayed = await this.startOptimizedPod(\n        baseVastUrl,\n        adBreakDurationMs,\n        currentMuted,\n        currentVolume\n      );\n      if (podPlayed) {\n        return;\n      }\n      if (this.debug) {\n        console.log(\"[POD] Optimized pod unavailable, falling back to sequential single-ad path\");\n      }\n    }\n    let firstAdUrl;\n    let usePreloadedAd = false;\n    let preloadedController;\n    const preloaded = this.preloadPool.getPreloadedAd();\n    if (preloaded) {\n      firstAdUrl = preloaded.vastUrl;\n      preloadedController = preloaded.adController;\n      usePreloadedAd = true;\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: firstAdUrl, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Using preloaded ad from pool (preloaded in advance, ready immediately!)\");\n      }\n    } else if (this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0) {\n      this.adRequestQueue = [...this.pendingAdBreak.vastUrls];\n      firstAdUrl = this.adRequestQueue.shift();\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Pool empty, using prefetched URLs (${this.adRequestQueue.length + 1} available)`);\n      }\n      this.clearPendingAdBreak();\n    } else {\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Generating new ad URLs...\");\n      }\n      const firstAdUrlArray = this.host.generateVastUrls(baseVastUrl, 1);\n      firstAdUrl = firstAdUrlArray[0];\n      this.adRequestQueue = [];\n    }\n    if (!firstAdUrl) {\n      if (this.debug) {\n        console.warn(\"[CONTINUOUS-FETCH] Failed to get first ad URL\");\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] First VAST URL:\", firstAdUrl);\n    }\n    try {\n      if (usePreloadedAd && preloadedController) {\n        if (!this.timing.ensureLoadedAdFitsBudget(preloadedController)) {\n          this.timing.rejectLoadedAdForDuration(preloadedController);\n          this.startContinuousFetching(baseVastUrl);\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n        const adPlayer = this.host.getAdPlayer();\n        const preservedMuted = adPlayer.getOriginalMutedState();\n        const preservedVolume = adPlayer.getOriginalVolume();\n        adPlayer.destroy();\n        this.host.video.muted = true;\n        this.host.setAdPlayer(preloadedController);\n        preloadedController.updateOriginalMutedState(preservedMuted, preservedVolume);\n        this.attachImaEventListeners();\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] Using preloaded ad, resuming and starting playback immediately (no request delay!)\");\n        }\n        preloadedController.resume();\n        this.timing.consecutiveFailures = 0;\n        this.startContinuousFetching(baseVastUrl);\n        if (!this.preloadPool.active) {\n          this.preloadPool.active = true;\n        }\n        if (!this.preloadPool.isLoopRunning) {\n          this.preloadPool.preloadPoolLoop(baseVastUrl);\n        }\n        await preloadedController.play();\n        this.timing.markAdStarted();\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n        const adVolume = currentMuted ? 0 : currentVolume;\n        preloadedController.setAdVolume(adVolume);\n      } else {\n        const adPlayer = this.host.getAdPlayer();\n        await this.timing.enforceGlobalRateLimit();\n        this.timing.lastAdRequestTime = Date.now();\n        await adPlayer.requestAds(firstAdUrl);\n        sendAdLoadedTracking(\n          this.host.config.licenseKey,\n          { source: \"hls\", vastUrl: firstAdUrl, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n          this.analyticsContext\n        ).catch(() => {\n        });\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] First ad request successful, starting playback\");\n        }\n        if (!this.timing.ensureLoadedAdFitsBudget(adPlayer)) {\n          this.timing.rejectLoadedAdForDuration(adPlayer);\n          this.recreateAdController();\n          this.startContinuousFetching(baseVastUrl);\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n        this.timing.consecutiveFailures = 0;\n        this.startContinuousFetching(baseVastUrl);\n        if (!this.preloadPool.active) {\n          this.preloadPool.startPreloadPool(baseVastUrl, []);\n        }\n        await adPlayer.play();\n        this.timing.markAdStarted();\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n        const adVolume = currentMuted ? 0 : currentVolume;\n        adPlayer.setAdVolume(adVolume);\n      }\n    } catch (error) {\n      if (this.debug) {\n        console.warn(\"[CONTINUOUS-FETCH] First ad request failed:\", error);\n      }\n      if (!usePreloadedAd) {\n        const fallbackPreloaded = this.preloadPool.getPreloadedAd();\n        if (fallbackPreloaded) {\n          if (this.debug) {\n            console.log(\"[CONTINUOUS-FETCH] First ad failed, using preloaded fallback\");\n          }\n          try {\n            if (!this.timing.ensureLoadedAdFitsBudget(fallbackPreloaded.adController)) {\n              this.timing.rejectLoadedAdForDuration(fallbackPreloaded.adController);\n              this.startContinuousFetching(baseVastUrl);\n              await this.tryNextAvailableAdWithRateLimit();\n              return;\n            }\n            this.swapToPreloadedAdPlayer(fallbackPreloaded.adController);\n            this.timing.consecutiveFailures = 0;\n            this.startContinuousFetching(baseVastUrl);\n            if (!this.preloadPool.active) {\n              this.preloadPool.active = true;\n              this.preloadPool.preloadPoolLoop(baseVastUrl);\n            }\n            const ap = this.host.getAdPlayer();\n            await ap.play();\n            this.timing.markAdStarted();\n            if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n              this.timing.scheduleAdStopAtBreakBoundary();\n            }\n            const adVolume = currentMuted ? 0 : currentVolume;\n            ap.setAdVolume(adVolume);\n            return;\n          } catch (fallbackError) {\n            if (this.debug) {\n              console.warn(\"[CONTINUOUS-FETCH] Preloaded fallback also failed:\", fallbackError);\n            }\n          }\n        }\n      }\n      if (this.timing.isTemporaryAdError(error)) {\n        this.timing.temporaryFailureUrls.set(firstAdUrl, Date.now());\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] First ad had temporary error (no-fill) - will try alternatives\");\n        }\n      } else {\n        this.timing.failedVastUrls.add(firstAdUrl);\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] First ad had permanent error - URL blacklisted\");\n        }\n      }\n      this.timing.consecutiveFailures++;\n      this.startContinuousFetching(baseVastUrl);\n      await this.tryNextAvailableAdWithRateLimit();\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Optimized pod (single multi-ad request)\n  // ───────────────────────────────────────────────────────────────\n  async startOptimizedPod(baseVastUrl, breakDurationMs, currentMuted, currentVolume) {\n    let podUrl;\n    if (this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0) {\n      podUrl = this.pendingAdBreak.vastUrls[0];\n      this.clearPendingAdBreak();\n    } else {\n      podUrl = this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);\n    }\n    if (!podUrl) {\n      return false;\n    }\n    this.continuousFetchingActive = false;\n    this.recreateAdController();\n    const adPlayer = this.host.getAdPlayer();\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      await adPlayer.requestAds(podUrl);\n      this.timing.clearAdRequestWatchdog();\n      if (this.timing.activeAdRequestToken !== requestToken) {\n        return true;\n      }\n      const podCount = adPlayer.getPodAdCount?.() ?? 1;\n      if (podCount < 1) {\n        return false;\n      }\n      if (this.debug) {\n        console.log(\n          podCount === 1 ? \"[POD] Response contained a single ad; playing it and enabling sequential top-up\" : `[POD] Optimized pod returned ${podCount} ads; playing pod in one controller`\n        );\n      }\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: podUrl, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      this.timing.startAdFailsafeTimer(requestToken);\n      await adPlayer.play();\n      this.timing.markAdStarted();\n      if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n      }\n      adPlayer.setAdVolume(currentMuted ? 0 : currentVolume);\n      this.timing.consecutiveFailures = 0;\n      if (podCount === 1) {\n        this.continuousFetchingActive = true;\n        this.startContinuousFetching(baseVastUrl);\n        if (!this.preloadPool.active) {\n          this.preloadPool.startPreloadPool(baseVastUrl, []);\n        }\n      }\n      return true;\n    } catch (error) {\n      this.timing.clearAdRequestWatchdog();\n      this.timing.clearAdFailsafeTimer();\n      if (this.timing.activeAdRequestToken === requestToken) {\n        this.timing.activeAdRequestToken = null;\n      }\n      if (this.debug) {\n        console.warn(\"[POD] Optimized pod request/play failed:\", error);\n      }\n      if (this.timing.isTemporaryAdError(error)) {\n        this.timing.temporaryFailureUrls.set(podUrl, Date.now());\n      }\n      this.continuousFetchingActive = true;\n      this.recreateAdController();\n      return false;\n    }\n  }\n  swapToPreloadedAdPlayer(preloadedController) {\n    const adPlayer = this.host.getAdPlayer();\n    const preservedMuted = adPlayer.getOriginalMutedState();\n    const preservedVolume = adPlayer.getOriginalVolume();\n    adPlayer.destroy();\n    this.host.video.muted = true;\n    this.host.setAdPlayer(preloadedController);\n    this.attachImaEventListeners();\n    preloadedController.updateOriginalMutedState(preservedMuted, preservedVolume);\n    preloadedController.resume();\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Continuous fetching\n  // ───────────────────────────────────────────────────────────────\n  startContinuousFetching(baseVastUrl) {\n    if (!this.continuousFetchingActive) {\n      return;\n    }\n    if (this.continuousFetchLoopRunning) {\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Fetch loop already running, skipping duplicate start\");\n      }\n      return;\n    }\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] Starting continuous ad fetching loop\");\n    }\n    this.continuousFetchLoopRunning = true;\n    this.continuousFetchLoop(baseVastUrl);\n  }\n  async continuousFetchLoop(baseVastUrl) {\n    const epoch = this.timing.adBreakEpoch;\n    while (this.continuousFetchingActive && this.inAdBreak && epoch === this.timing.adBreakEpoch) {\n      const remaining = Math.min(\n        this.timing.getWallClockRemainingAdMs(),\n        this.timing.getDurationBudgetRemainingMs()\n      );\n      if (remaining <= this.timing.getMinRemainingMsToStartAd()) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Not enough ad break time left (wall=${this.timing.getWallClockRemainingAdMs()}ms, budget=${this.timing.getDurationBudgetRemainingMs()}ms), stopping URL generation`);\n        }\n        break;\n      }\n      if (this.timing.isGamInCooldown()) {\n        if (this.debug) {\n          console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, stopping URL generation\");\n        }\n        break;\n      }\n      if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), stopping URL generation`);\n        }\n        break;\n      }\n      if (this.timing.totalAdRequestsInBreak >= this.timing.maxTotalAdRequestsPerBreak) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Maximum ad requests reached (${this.timing.maxTotalAdRequestsPerBreak}), stopping`);\n        }\n        break;\n      }\n      const maxQueueSize = 5;\n      if (this.adRequestQueue.length >= maxQueueSize) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] URL queue full (${this.adRequestQueue.length}), waiting...`);\n        }\n        await new Promise((resolve) => setTimeout(resolve, 1e3));\n        continue;\n      }\n      const newAdUrl = this.host.generateVastUrls(baseVastUrl, 1)[0];\n      if (!newAdUrl || this.timing.failedVastUrls.has(newAdUrl) || this.timing.isUrlInCooldown(newAdUrl)) {\n        await new Promise((resolve) => setTimeout(resolve, 500));\n        continue;\n      }\n      if (this.debug) {\n        const queuedUrlsPreview = [...this.adRequestQueue, newAdUrl];\n        console.log(\n          `[CONTINUOUS-FETCH] Queued VAST URL (queue size: ${queuedUrlsPreview.length})`,\n          { queuedUrls: queuedUrlsPreview }\n        );\n      }\n      this.adRequestQueue.push(newAdUrl);\n      const generationDelay = this.timing.consecutiveFailures > 0 ? Math.min(1e3 * Math.pow(2, this.timing.consecutiveFailures), 5e3) : 500;\n      await new Promise((resolve) => setTimeout(resolve, generationDelay));\n    }\n    this.continuousFetchLoopRunning = false;\n    if (this.debug) {\n      console.log(\n        `[CONTINUOUS-FETCH] URL generation loop ended (queued: ${this.adRequestQueue.length})`,\n        this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n      );\n    }\n  }\n  stopContinuousFetching() {\n    this.continuousFetchingActive = false;\n    this.continuousFetchLoopRunning = false;\n    this.placeholder.hide();\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] Stopping continuous ad fetching\");\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Ad iteration\n  // ───────────────────────────────────────────────────────────────\n  async tryNextAvailableAdWithRateLimit() {\n    if (!this.inAdBreak) {\n      return;\n    }\n    const epoch = this.timing.adBreakEpoch;\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), ending ad break gracefully`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n    const backoffMultiplier = Math.pow(2, this.timing.consecutiveFailures);\n    const backoffDelay = Math.min(this.timing.backoffBaseMs * backoffMultiplier, this.timing.maxBackoffMs);\n    const effectiveMinInterval = this.timing.minAdRequestIntervalMs + (this.timing.consecutiveFailures > 0 ? backoffDelay : 0);\n    const timeSinceLastRequest = Date.now() - this.timing.lastAdRequestTime;\n    if (timeSinceLastRequest < effectiveMinInterval) {\n      const waitTime = effectiveMinInterval - timeSinceLastRequest;\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Rate limiting: waiting ${waitTime}ms before next request (backoff: ${this.timing.consecutiveFailures} failures)`);\n      }\n      await new Promise((resolve) => setTimeout(resolve, waitTime));\n    }\n    if (!this.inAdBreak || epoch !== this.timing.adBreakEpoch) {\n      return;\n    }\n    return this.tryNextAvailableAd(0);\n  }\n  async tryNextAvailableAd(retryCount = 0) {\n    if (!this.inAdBreak) {\n      return;\n    }\n    const remaining = this.timing.getRemainingAdMs();\n    if (!this.timing.hasTimeToStartAnotherAd()) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Not enough time remaining (${remaining}ms) to start another ad, ending ad break`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) {\n        console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, ending ad break gracefully\");\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), ending ad break`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n    this.timing.cleanupTemporaryFailures();\n    const preloaded = this.preloadPool.getPreloadedAd();\n    if (preloaded) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Using preloaded ad from pool`);\n      }\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: preloaded.vastUrl, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      try {\n        if (!this.timing.ensureLoadedAdFitsBudget(preloaded.adController)) {\n          this.timing.rejectLoadedAdForDuration(preloaded.adController);\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n        this.swapToPreloadedAdPlayer(preloaded.adController);\n        const ap = this.host.getAdPlayer();\n        await ap.play();\n        this.timing.markAdStarted();\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n        ap.setAdVolume(getAdAudioVolume(ap));\n        this.timing.consecutiveFailures = 0;\n        return;\n      } catch (error) {\n        if (this.debug) {\n          console.warn(\"[CONTINUOUS-FETCH] Preloaded ad failed to play:\", error);\n        }\n      }\n    }\n    while (this.adRequestQueue.length > 0) {\n      const nextAdUrl = this.adRequestQueue.shift();\n      if (!nextAdUrl) continue;\n      if (this.timing.failedVastUrls.has(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping permanently-failed URL, trying next...\");\n        continue;\n      }\n      if (this.timing.isUrlInCooldown(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping URL in cooldown (recent no-fill), trying next...\");\n        continue;\n      }\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Requesting next ad via HLS ad player (${this.timing.currentAdIndex + 1}, ${this.adRequestQueue.length} remaining in queue)`);\n      }\n      try {\n        await this.playSingleAd(nextAdUrl);\n        this.timing.consecutiveFailures = 0;\n      } catch (error) {\n        const errorMessage = error.message;\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Ad request failed:\", errorMessage);\n        if (errorMessage.includes(\"ad_duration_exceeds_budget\")) {\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n        if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n          this.timing.consecutiveFailures++;\n        }\n        await this.tryNextAvailableAdWithRateLimit();\n      }\n      return;\n    }\n    const maxRetries = 3;\n    if (this.continuousFetchingActive && retryCount < maxRetries && remaining > 2e3) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Queue empty, waiting for URLs... (${retryCount + 1}/${maxRetries})`);\n      }\n      await new Promise((resolve) => setTimeout(resolve, 500));\n      await this.tryNextAvailableAd(retryCount + 1);\n      return;\n    }\n    if (!this.isShowingPlaceholder && remaining > 1e3) {\n      this.showPlaceholderAndWaitForAds();\n    } else {\n      if (this.debug) console.log(\"[CONTINUOUS-FETCH] No more ads available, ending ad break\");\n      this.handleAdPodComplete();\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Single ad playback\n  // ───────────────────────────────────────────────────────────────\n  async playSingleAd(vastTagUrl) {\n    const adPlayer = this.host.getAdPlayer();\n    if (adPlayer.isAdPlaying()) return;\n    if (this.timing.failedVastUrls.has(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping permanently-failed VAST URL:\", vastTagUrl);\n      throw new Error(\"VAST URL permanently failed\");\n    }\n    if (this.timing.isUrlInCooldown(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping URL in cooldown (recent no-fill):\", vastTagUrl);\n      throw new Error(\"VAST URL in cooldown after no-fill\");\n    }\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.warn(\"[AD-ERROR] Too many consecutive failures, not requesting more ads\");\n      throw new Error(\"Too many consecutive failures\");\n    }\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) console.warn(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping ad request\");\n      throw new Error(\"GAM in cooldown\");\n    }\n    this.recreateAdController();\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      const ap = this.host.getAdPlayer();\n      await ap.requestAds(vastTagUrl);\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: vastTagUrl, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      this.timing.clearAdRequestWatchdog();\n      if (this.timing.activeAdRequestToken !== requestToken) return;\n      if (!this.timing.ensureLoadedAdFitsBudget(ap)) {\n        this.timing.rejectLoadedAdForDuration(ap);\n        this.recreateAdController();\n        throw new Error(\"ad_duration_exceeds_budget\");\n      }\n      try {\n        this.timing.startAdFailsafeTimer(requestToken);\n        await ap.play();\n        this.timing.markAdStarted();\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n        ap.setAdVolume(getAdAudioVolume(ap));\n        this.timing.consecutiveFailures = 0;\n        this.timing.temporaryFailureUrls.delete(vastTagUrl);\n      } catch (playError) {\n        if (this.debug) console.error(\"[AD-ERROR] Failed to play ad:\", playError);\n        const preloadedFallback = this.preloadPool.getPreloadedAd();\n        if (preloadedFallback) {\n          if (this.debug) console.log(\"[AD-ERROR] Play failed, trying preloaded fallback ad\");\n          try {\n            if (!this.timing.ensureLoadedAdFitsBudget(preloadedFallback.adController)) {\n              this.timing.rejectLoadedAdForDuration(preloadedFallback.adController);\n              throw playError;\n            }\n            this.timing.clearAdFailsafeTimer();\n            this.swapToPreloadedAdPlayer(preloadedFallback.adController);\n            this.timing.consecutiveFailures = 0;\n            const fbAp = this.host.getAdPlayer();\n            await fbAp.play();\n            this.timing.markAdStarted();\n            if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n              this.timing.scheduleAdStopAtBreakBoundary();\n            }\n            fbAp.setAdVolume(getAdAudioVolume(fbAp));\n            return;\n          } catch (fallbackError) {\n            if (this.debug) console.warn(\"[AD-ERROR] Preloaded fallback also failed:\", fallbackError);\n          }\n        }\n        if (this.timing.isTemporaryAdError(playError)) {\n          this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());\n          if (this.debug) console.log(\"[AD-ERROR] Temporary play error - URL can be retried after cooldown\");\n        } else {\n          this.timing.failedVastUrls.add(vastTagUrl);\n          if (this.debug) console.log(\"[AD-ERROR] Permanent play error - URL blacklisted\");\n        }\n        this.timing.clearAdFailsafeTimer();\n        if (this.timing.activeAdRequestToken === requestToken) {\n          this.timing.activeAdRequestToken = null;\n        }\n        throw playError;\n      }\n    } catch (error) {\n      const errorMessage = error?.message || \"\";\n      if (this.debug) console.error(\"[AD-ERROR] Ad request failed:\", errorMessage);\n      const preloadedFallback = this.preloadPool.getPreloadedAd();\n      if (preloadedFallback) {\n        if (this.debug) console.log(\"[AD-ERROR] Request failed, trying preloaded fallback ad\");\n        try {\n          if (!this.timing.ensureLoadedAdFitsBudget(preloadedFallback.adController)) {\n            this.timing.rejectLoadedAdForDuration(preloadedFallback.adController);\n            throw error;\n          }\n          this.timing.clearAdRequestWatchdog();\n          this.timing.clearAdFailsafeTimer();\n          this.swapToPreloadedAdPlayer(preloadedFallback.adController);\n          this.timing.consecutiveFailures = 0;\n          const fbAp = this.host.getAdPlayer();\n          await fbAp.play();\n          this.timing.markAdStarted();\n          fbAp.setAdVolume(getAdAudioVolume(fbAp));\n          return;\n        } catch (fallbackError) {\n          if (this.debug) console.warn(\"[AD-ERROR] Preloaded fallback also failed:\", fallbackError);\n        }\n      }\n      if (this.timing.isTemporaryAdError(error)) {\n        this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());\n        if (this.debug) console.log(\"[AD-ERROR] Temporary error (no-fill/timeout) - URL can be retried after cooldown\");\n      } else {\n        this.timing.failedVastUrls.add(vastTagUrl);\n        if (this.debug) console.log(\"[AD-ERROR] Permanent error - URL blacklisted:\", errorMessage);\n      }\n      this.timing.clearAdRequestWatchdog();\n      this.timing.clearAdFailsafeTimer();\n      if (this.timing.activeAdRequestToken === requestToken) {\n        this.timing.activeAdRequestToken = null;\n      }\n      throw error;\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Placeholder wait\n  // ───────────────────────────────────────────────────────────────\n  async showPlaceholderAndWaitForAds() {\n    const remaining = this.timing.getRemainingAdMs();\n    const waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping placeholder wait\");\n      this.handleAdPodComplete();\n      return;\n    }\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping placeholder - too many consecutive failures\");\n      this.handleAdPodComplete();\n      return;\n    }\n    if (waitTime < 1e3) {\n      this.handleAdPodComplete();\n      return;\n    }\n    if (this.debug) {\n      console.log(`[CONTINUOUS-FETCH] Showing placeholder for ${waitTime}ms while waiting for ad URLs`);\n    }\n    this.isShowingPlaceholder = true;\n    this.host.getAdPlayer().showPlaceholder();\n    const checkInterval = 300;\n    const maxChecks = Math.floor(waitTime / checkInterval);\n    for (let i = 0; i < maxChecks; i++) {\n      await new Promise((resolve) => setTimeout(resolve, checkInterval));\n      if (!this.inAdBreak) return;\n      if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Too many failures during placeholder wait\");\n        break;\n      }\n      if (!this.timing.hasTimeToStartAnotherAd()) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Not enough time remaining during placeholder wait, ending ad break\");\n        break;\n      }\n      while (this.adRequestQueue.length > 0) {\n        if (!this.timing.hasTimeToStartAnotherAd()) break;\n        const nextAdUrl = this.adRequestQueue.shift();\n        if (!nextAdUrl) continue;\n        if (this.timing.failedVastUrls.has(nextAdUrl)) continue;\n        if (this.timing.isUrlInCooldown(nextAdUrl)) continue;\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Ad URL available, requesting via HLS ad player\");\n        this.isShowingPlaceholder = false;\n        this.host.getAdPlayer().hidePlaceholder();\n        try {\n          await this.playSingleAd(nextAdUrl);\n          this.timing.consecutiveFailures = 0;\n        } catch (error) {\n          const errorMessage = error.message;\n          if (errorMessage.includes(\"ad_duration_exceeds_budget\")) {\n            await this.tryNextAvailableAdWithRateLimit();\n            return;\n          }\n          if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n            this.timing.consecutiveFailures++;\n          }\n          await this.tryNextAvailableAdWithRateLimit();\n        }\n        return;\n      }\n    }\n    if (this.debug) console.log(\"[CONTINUOUS-FETCH] Placeholder timeout, ending ad break\");\n    this.isShowingPlaceholder = false;\n    this.host.getAdPlayer().hidePlaceholder();\n    this.handleAdPodComplete();\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Ad break completion\n  // ───────────────────────────────────────────────────────────────\n  handleAdPodComplete() {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Ad pod complete - cleaning up\");\n    }\n    this.timing.resetForBreakEnd();\n    this.stopContinuousFetching();\n    this.preloadPool.stop();\n    this.clearPendingAdBreak();\n    if (this.isShowingPlaceholder) {\n      this.host.getAdPlayer().hidePlaceholder();\n      this.isShowingPlaceholder = false;\n    }\n    this.adRequestQueue = [];\n    this.inAdBreak = false;\n    this.adDetectSentForCurrentBreak = false;\n    this.cueManager.activeScte35BreakKey = void 0;\n    this.cueManager.scheduledScte35BreakKey = void 0;\n    this.adPodQueue = [];\n    this.showAds = false;\n    this.host.getAdPlayer().stop().catch(() => {\n    });\n    const restoredMuted = this.host.getAdPlayer().getOriginalMutedState();\n    const restoredVolume = this.host.getAdPlayer().getOriginalVolume();\n    if (this.host.video.muted !== restoredMuted) {\n      this.host.video.muted = restoredMuted;\n    }\n    if (Math.abs(this.host.video.volume - restoredVolume) > 0.01) {\n      this.host.video.volume = restoredVolume;\n    }\n    if (this.host.shouldContinueLiveStreamDuringAds()) {\n      const liveSyncPos = this.host.getLiveSyncPosition();\n      if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {\n        if (this.debug) {\n          console.log(\n            `[StormcloudVideoPlayer] Live break end \\u2014 snapping to live edge: ${this.host.video.currentTime.toFixed(2)}s \\u2192 ${liveSyncPos.toFixed(2)}s`\n          );\n        }\n        this.host.video.currentTime = liveSyncPos;\n      }\n      if (this.host.video.paused) {\n        if (this.debug) console.log(\"[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback\");\n        this.host.video.play()?.catch(() => {\n        });\n      } else {\n        if (this.debug) console.log(\"[StormcloudVideoPlayer] Content video already playing in live mode after ads\");\n      }\n    } else if (this.host.video.paused) {\n      this.host.video.play()?.catch(() => {\n      });\n    }\n  }\n  handleAdFailure() {\n    this.timing.consecutiveFailures++;\n    this.timing.recordGamNoFill();\n    const remaining = this.timing.getRemainingAdMs();\n    if (this.debug) {\n      console.log(\n        `[CONTINUOUS-FETCH] Ad failure: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}, consecutiveFailures=${this.timing.consecutiveFailures}`,\n        this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n      );\n    }\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.log(`[CONTINUOUS-FETCH] Max consecutive failures reached (${this.timing.consecutiveFailures}), ending ad break gracefully`);\n      this.handleAdPodComplete();\n      return;\n    }\n    if (this.timing.hasTimeToStartAnotherAd()) {\n      this.tryNextAvailableAdWithRateLimit();\n    } else {\n      if (this.debug) console.log(\"[AD-ERROR] Ad failed and not enough time remaining for another ad. Failed URLs:\", this.timing.failedVastUrls.size);\n      this.handleAdPodComplete();\n    }\n  }\n};\n\n// src/player/StormcloudVideoPlayer.ts\nvar StormcloudVideoPlayer = class {\n  constructor(config) {\n    this.attached = false;\n    this.palPlaybackStarted = false;\n    initializePolyfills();\n    const browserOverrides = getBrowserConfigOverrides();\n    this.config = { ...browserOverrides, ...config };\n    this.video = config.videoElement;\n    logBrowserInfo(config.debugAdTiming);\n    this.adPlayer = this.createAdPlayer(false);\n    this.palNonce = createPalNonceManager();\n    this.cueManager = new Scte35CueManager(!!this.config.debugAdTiming, {\n      onEarlyStartCue: (marker, fragmentSn, cueKey) => {\n        this.startAdPrefetch(marker, fragmentSn, cueKey);\n      },\n      onPlaybackCue: (marker, cueKey) => {\n        this.onScte35Marker(marker, cueKey);\n      },\n      isInAdBreak: () => this.adBreak.inAdBreak\n    });\n    this.adConfig = new AdConfigManager(this.config, this.video);\n    this.timing = new AdTimingService(this.config, this.video, {\n      onAdStopTimerFired: () => this.onAdStopTimerFired(),\n      onAdStartTimerFired: (marker, cueKey) => {\n        this.startScte35AdBreak(\n          marker,\n          cueKey,\n          marker.durationSeconds != null ? marker.durationSeconds * 1e3 : this.timing.expectedAdBreakDurationMs\n        );\n      },\n      onWatchdogTimeout: () => this.adBreak.handleAdFailure(),\n      onFailsafeTimeout: () => this.adBreak.handleAdFailure()\n    });\n    this.preloadPool = new AdPreloadPool({\n      debug: !!this.config.debugAdTiming,\n      createAdPlayer: (c) => this.createAdPlayer(c),\n      shouldContinueLiveStreamDuringAds: () => this.shouldContinueLiveStreamDuringAds(),\n      timing: this.timing,\n      generateVastUrlsWithCorrelators: (base, count) => this.generateVastUrls(base, count),\n      isInAdBreak: () => this.adBreak.inAdBreak,\n      getPendingAdBreak: () => this.adBreak.pendingAdBreak\n    });\n    this.placeholder = new PlaceholderLayer(this.video, !!this.config.debugAdTiming);\n    this.hlsEngine = new HlsEngine(this.config, this.video, this.cueManager, this.timing, {\n      onManifestParsed: async (isLive) => this.onManifestParsed(isLive),\n      onScte35Cue: (marker, context) => this.cueManager.onScte35Cue(marker, context),\n      activatePendingCuesForFragment: (frag) => this.cueManager.activatePendingScte35CuesForFragment(frag),\n      onFatalDestroy: () => this.destroy(),\n      isInAdBreak: () => this.adBreak.inAdBreak,\n      hasPendingAdBreak: () => this.adBreak.pendingAdBreak !== null\n    });\n    this.adBreak = new AdBreakOrchestrator(\n      {\n        config: this.config,\n        video: this.video,\n        getAdPlayer: () => this.adPlayer,\n        setAdPlayer: (p) => {\n          this.adPlayer = p;\n        },\n        createAdPlayer: (c) => this.createAdPlayer(c),\n        shouldContinueLiveStreamDuringAds: () => this.shouldContinueLiveStreamDuringAds(),\n        getLiveSyncPosition: () => this.hlsEngine.getLiveSyncPosition(),\n        generateVastUrls: (base, count) => this.generateVastUrls(base, count),\n        generatePodVastUrl: (base, breakDurationMs) => this.generatePodVastUrl(base, breakDurationMs)\n      },\n      this.timing,\n      this.preloadPool,\n      this.adConfig,\n      this.cueManager,\n      this.placeholder\n    );\n  }\n  get debug() {\n    return !!this.config.debugAdTiming;\n  }\n  createAdPlayer(continueLiveStreamDuringAds) {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Creating HLS ad player\");\n    }\n    return createHlsAdPlayer(this.video, {\n      continueLiveStreamDuringAds,\n      ...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {},\n      ...this.hlsEngine?.hls ? { mainHlsInstance: this.hlsEngine.hls } : {}\n    });\n  }\n  generateVastUrls(baseUrl, count) {\n    return this.adConfig.generateVastUrlsWithCorrelators(\n      baseUrl,\n      count,\n      this.adPlayer,\n      this.palNonce,\n      this.adBreak.inAdBreak\n    );\n  }\n  generatePodVastUrl(baseUrl, breakDurationMs) {\n    const podParams = this.adConfig.resolvePodParams(breakDurationMs);\n    return this.adConfig.generatePodVastUrl(\n      baseUrl,\n      podParams,\n      this.adPlayer,\n      this.palNonce,\n      this.adBreak.inAdBreak\n    );\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Lifecycle\n  // ───────────────────────────────────────────────────────────────\n  async load() {\n    if (!this.attached) {\n      this.attach();\n    }\n    try {\n      await this.adConfig.fetchAdConfiguration();\n    } catch (error) {\n      if (this.debug) {\n        console.warn(\n          \"[StormcloudVideoPlayer] Failed to fetch ad configuration:\",\n          error\n        );\n      }\n    }\n    this.palNonce.generateNonce({\n      videoWidth: this.video.offsetWidth || this.video.clientWidth || 640,\n      videoHeight: this.video.offsetHeight || this.video.clientHeight || 480,\n      adWillAutoPlay: !!this.config.autoplay,\n      adWillPlayMuted: true,\n      playerVolume: 0,\n      continuousPlayback: this.config.lowLatencyMode ?? false\n    }).catch(() => {\n    });\n    fetchConsentSignals().then((signals) => {\n      this.adConfig.consentSignals = signals;\n    }).catch(() => {\n    });\n    this.adConfig.initializeTracking();\n    if (this.hlsEngine.shouldUseNativeHls(() => this.getStreamType())) {\n      await this.hlsEngine.setupNativeHls();\n      const continueLiveStreamDuringAds = this.shouldContinueLiveStreamDuringAds();\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Native HLS ad behavior:\", {\n          isLive: this.hlsEngine.isLiveStream,\n          continueLiveStreamDuringAds\n        });\n      }\n      this.adPlayer.destroy();\n      this.adPlayer = this.createAdPlayer(continueLiveStreamDuringAds);\n      this.adPlayer.initialize();\n      return;\n    }\n    this.hlsEngine.setupHls();\n  }\n  async onManifestParsed(isLive) {\n    if (!this.adConfig.isVmapEnabled() && !isLive && this.adConfig.vmapBreaks.length === 0 && this.adConfig.apiVastTagUrl) {\n      const prerollKey = \"synthetic-vod-preroll\";\n      if (!this.adConfig.consumedVmapBreakIds.has(prerollKey)) {\n        this.adConfig.vmapBreaks = [\n          { id: prerollKey, startTimeMs: 0, vastTagUrl: this.adConfig.apiVastTagUrl }\n        ];\n        if (this.debug) {\n          console.log(\n            \"[StormcloudVideoPlayer] Injected synthetic VOD preroll from apiVastTagUrl\"\n          );\n        }\n      }\n    }\n    if (this.debug) {\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,\n        allowNativeHls: this.config.allowNativeHls,\n        adBehavior\n      });\n    }\n    this.adPlayer.destroy();\n    this.adPlayer = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());\n    this.adPlayer.initialize();\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.adBreak.attachImaEventListeners();\n    this.video.addEventListener(\"play\", () => {\n      if (!this.palPlaybackStarted && !this.adPlayer.isAdPlaying()) {\n        this.palPlaybackStarted = true;\n        this.palNonce.sendPlaybackStart();\n      }\n    });\n    this.endedHandler = () => {\n      if (this.palPlaybackStarted) {\n        this.palPlaybackStarted = false;\n        this.palNonce.sendPlaybackEnd();\n      }\n      this.onVideoEnded();\n    };\n    this.video.addEventListener(\"ended\", this.endedHandler);\n    this.video.addEventListener(\"mousedown\", (e) => {\n      this.palNonce.sendAdTouch(e);\n    });\n    this.video.addEventListener(\"touchstart\", (e) => {\n      this.palNonce.sendAdTouch(e);\n    });\n    this.timeUpdateHandler = () => {\n      this.onTimeUpdate(this.video.currentTime);\n    };\n    this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n    this.emptiedHandler = () => {\n      if (this.hlsEngine.nativeHlsMode && this.hlsEngine.videoSrcProtection && !this.adPlayer.isAdPlaying()) {\n        if (this.debug) {\n          console.log(\n            \"[StormcloudVideoPlayer] Video src was cleared, restoring:\",\n            this.hlsEngine.videoSrcProtection\n          );\n        }\n        const currentTime = this.video.currentTime;\n        const wasPaused = this.video.paused;\n        this.video.src = this.hlsEngine.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  shouldContinueLiveStreamDuringAds() {\n    if (this.hlsEngine.isLiveStream) {\n      return true;\n    }\n    const duration = this.video.duration;\n    if (!Number.isFinite(duration) || duration === Infinity) {\n      return true;\n    }\n    return false;\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  SCTE-35 marker orchestration\n  // ───────────────────────────────────────────────────────────────\n  onScte35Marker(marker, cueKey) {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] SCTE-35 marker detected:\", {\n        type: marker.type,\n        ptsSeconds: marker.ptsSeconds,\n        durationSeconds: marker.durationSeconds,\n        currentTime: this.video.currentTime,\n        raw: marker.raw,\n        hasPendingAdBreak: !!this.adBreak.pendingAdBreak\n      });\n    }\n    if (marker.type === \"start\") {\n      if (this.adBreak.inAdBreak) {\n        if (marker.durationSeconds != null) {\n          const newDurationMs = marker.durationSeconds * 1e3;\n          if (this.timing.expectedAdBreakDurationMs == null || newDurationMs > this.timing.expectedAdBreakDurationMs) {\n            this.timing.setAdBreakDurationBoundary(newDurationMs);\n            this.timing.scheduleAdStopAtBreakBoundary();\n            if (this.debug) {\n              console.log(\n                `[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ${newDurationMs}ms, remaining: ${this.timing.getWallClockRemainingAdMs()}ms`\n              );\n            }\n          }\n        }\n        return;\n      }\n      if (!this.adBreak.adDetectSentForCurrentBreak) {\n        this.adBreak.adDetectSentForCurrentBreak = true;\n        const detectPayload = {};\n        if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;\n        if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;\n        sendAdDetectTracking(this.config.licenseKey, { source: \"scte35\", timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...detectPayload }, buildAnalyticsContext(this.config)).catch(() => {\n        });\n      }\n      const hasPrefetchedAds = this.adBreak.pendingAdBreak && this.adBreak.pendingAdBreak.vastUrls.length > 0;\n      const durationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : this.adBreak.pendingAdBreak?.marker.durationSeconds != null ? this.adBreak.pendingAdBreak.marker.durationSeconds * 1e3 : void 0;\n      const isManifest = isManifestBasedMarker(marker);\n      const forceImmediate = this.config.immediateManifestAds ?? true;\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ad start decision:\", {\n          isManifestMarker: isManifest,\n          forceImmediate,\n          hasPts: typeof marker.ptsSeconds === \"number\",\n          hasPrefetchedAds\n        });\n      }\n      if (isManifest && forceImmediate) {\n        if (this.debug) {\n          console.log(\n            `[StormcloudVideoPlayer] Starting ad immediately (manifest-based)${hasPrefetchedAds ? \" with prefetched ads\" : \"\"}`\n          );\n        }\n        this.timing.clearAdStartTimer();\n        this.startScte35AdBreak(marker, cueKey, durationMs);\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.timing.ptsDriftEmaMs;\n        const deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);\n        if (this.debug) {\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.debug) {\n            console.log(`[StormcloudVideoPlayer] Scheduling ad start in ${deltaMs}ms`);\n          }\n          this.timing.expectedAdBreakDurationMs = durationMs;\n          this.cueManager.scheduledScte35BreakKey = cueKey;\n          this.timing.scheduleAdStartIn(deltaMs, marker, cueKey);\n        } else {\n          if (this.debug) {\n            console.log(\"[StormcloudVideoPlayer] Starting ad immediately (within tolerance)\");\n          }\n          this.timing.clearAdStartTimer();\n          this.startScte35AdBreak(marker, cueKey, durationMs);\n        }\n      } else {\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Starting ad immediately (fallback)\");\n        }\n        this.timing.clearAdStartTimer();\n        this.startScte35AdBreak(marker, cueKey, durationMs);\n      }\n      return;\n    }\n    if (marker.type === \"progress\" && this.adBreak.inAdBreak) {\n      if (marker.durationSeconds != null) {\n        this.timing.setAdBreakDurationBoundary(marker.durationSeconds * 1e3);\n      }\n      this.timing.scheduleAdStopAtBreakBoundary();\n      if (!this.adPlayer.isAdPlaying() && this.timing.activeAdRequestToken === null && this.adBreak.adRequestQueue.length > 0 && this.timing.hasTimeToStartAnotherAd()) {\n        this.adBreak.tryNextAvailableAdWithRateLimit();\n      }\n      return;\n    }\n    if (marker.type === \"end\") {\n      if (!this.video.muted) {\n        this.video.muted = true;\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Muted video on SCTE end marker\");\n        }\n      }\n      const remaining = this.timing.getRemainingAdMs();\n      const adPlaying = this.adPlayer.isAdPlaying();\n      const hasQueuedAds = this.adBreak.adRequestQueue.length > 0;\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] SCTE-35 end marker received:\", {\n          remaining,\n          adPlaying,\n          hasQueuedAds,\n          activeAdRequest: this.timing.activeAdRequestToken !== null\n        });\n      }\n      this.timing.scteAdBreakEndWallClockMs = Date.now();\n      this.timing.clearAdStartTimer();\n      this.timing.clearAdStopTimer();\n      if (adPlaying) {\n        this.adPlayer.stop().catch(() => {\n        });\n      }\n      this.adBreak.handleAdPodComplete();\n      return;\n    }\n  }\n  startScte35AdBreak(marker, cueKey, durationMs) {\n    this.adBreak.inAdBreak = true;\n    this.cueManager.activeScte35BreakKey = cueKey ?? this.cueManager.pendingScte35CueKey;\n    this.cueManager.scheduledScte35BreakKey = void 0;\n    this.timing.currentAdBreakStartWallClockMs = this.timing.resolveScteBreakStartWallClockMs(marker);\n    this.timing.setAdBreakDurationBoundary(durationMs);\n    this.adBreak.handleAdStart(marker);\n    this.timing.scheduleAdStopAtBreakBoundary();\n  }\n  onAdStopTimerFired() {\n    if (!this.adBreak.inAdBreak) return;\n    const adPlaying = this.adPlayer.isAdPlaying();\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 : 0;\n    const endWallClockMs = this.timing.getAdBreakEndWallClockMs() ?? Date.now();\n    const overrunMs = Math.max(0, Date.now() - endWallClockMs);\n    const shouldExtendAdBreak = adPlaying && overrunMs < maxExtensionMs;\n    if (shouldExtendAdBreak) {\n      this.timing.scheduleAdStopCountdown(checkIntervalMs);\n      return;\n    }\n    if (this.debug) {\n      console.log(\n        `[StormcloudVideoPlayer] Ad break boundary reached (overrun=${overrunMs}ms) - hard-stopping ads and resuming stream`\n      );\n    }\n    if (adPlaying) {\n      this.adPlayer.stop().catch(() => {\n      });\n    }\n    this.adBreak.handleAdPodComplete();\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Ad prefetch\n  // ───────────────────────────────────────────────────────────────\n  startAdPrefetch(marker, fragmentSn, cueKey) {\n    if (this.adBreak.pendingAdBreak || this.adBreak.inAdBreak) return;\n    const scheduled = this.adConfig.findCurrentOrNextBreak(this.video.currentTime * 1e3);\n    const tags = this.adConfig.selectVastTagsForBreak(scheduled);\n    let baseVastUrl;\n    if (tags && tags.length > 0 && tags[0]) {\n      baseVastUrl = tags[0];\n    } else if (this.adConfig.apiVastTagUrl) {\n      baseVastUrl = this.adConfig.apiVastTagUrl;\n    } else {\n      if (this.debug) console.warn(\"[StormcloudVideoPlayer] No VAST URL available for prefetch\");\n      return;\n    }\n    this.adConfig.beginNewAdPod();\n    this.adConfig.podAssignedByPrefetch = true;\n    const optimizedPods = this.config.optimizedPods !== false;\n    const breakDurationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : void 0;\n    const generatedUrls = optimizedPods ? [this.generatePodVastUrl(baseVastUrl, breakDurationMs)] : this.generateVastUrls(baseVastUrl, 1);\n    this.adBreak.pendingAdBreak = {\n      marker,\n      ...fragmentSn !== void 0 ? { detectedAtFragmentSn: fragmentSn } : {},\n      vastUrls: generatedUrls,\n      isFetching: false,\n      fetchStartTime: Date.now()\n    };\n    this.cueManager.pendingScte35CueKey = cueKey;\n    this.adBreak.adDetectSentForCurrentBreak = true;\n    const detectPayload = {};\n    if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;\n    if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;\n    if (fragmentSn !== void 0) detectPayload.detectedAtFragmentSn = fragmentSn;\n    sendAdDetectTracking(this.config.licenseKey, { source: \"scte35\", timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...detectPayload }, buildAnalyticsContext(this.config)).catch(() => {\n    });\n    if (this.debug) {\n      console.log(\"[PREFETCH] Starting ad prefetch for upcoming ad break\");\n      console.log(\n        `[PREFETCH] Pre-generated ${generatedUrls.length} ${optimizedPods ? \"pod\" : \"VAST\"} URL(s)`\n      );\n    }\n    if (optimizedPods) {\n      if (this.debug) {\n        console.log(\"[PREFETCH] Optimized pods enabled - skipping single-ad preload pool\");\n      }\n      return;\n    }\n    this.preloadPool.startPreloadPool(baseVastUrl, generatedUrls.slice(0, 1), false);\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  VMAP time-based ad breaks\n  // ───────────────────────────────────────────────────────────────\n  onTimeUpdate(currentTimeSec) {\n    if (!this.adConfig.isVmapEnabled() || this.adConfig.vmapBreaks.length === 0) return;\n    if (this.adPlayer.isAdPlaying() || this.adBreak.inAdBreak) return;\n    const nowMs = currentTimeSec * 1e3;\n    const breakToPlay = this.adConfig.findBreakForTime(nowMs);\n    if (breakToPlay) {\n      void this.handleVmapAdBreak(breakToPlay, nowMs).catch((error) => {\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] VMAP ad break failed gracefully:\", error);\n        }\n      });\n    }\n  }\n  onVideoEnded() {\n    if (!this.adConfig.isVmapEnabled() || this.adConfig.vmapBreaks.length === 0) return;\n    if (this.adPlayer.isAdPlaying() || this.adBreak.inAdBreak) return;\n    const durationMs = Number.isFinite(this.video.duration) ? Math.floor(this.video.duration * 1e3) : 0;\n    const postroll = this.adConfig.vmapBreaks.find(\n      (b) => b.startTimeMs === -1 && !this.adConfig.consumedVmapBreakIds.has(this.adConfig.getAdBreakKey(b))\n    );\n    if (postroll) {\n      void this.handleVmapAdBreak(postroll, durationMs).catch((error) => {\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] VMAP post-roll failed gracefully:\", error);\n        }\n      });\n    }\n  }\n  async handleVmapAdBreak(adBreak, nowMs) {\n    const key = this.adConfig.getAdBreakKey(adBreak);\n    if (this.adConfig.consumedVmapBreakIds.has(key)) return;\n    const breakStartMs = this.adConfig.resolveBreakStartMs(adBreak);\n    if (breakStartMs == null) return;\n    const durationMs = adBreak.durationMs ?? 0;\n    const endMs = breakStartMs + durationMs;\n    const inWindow = durationMs > 0 ? nowMs >= breakStartMs && nowMs < endMs : nowMs >= breakStartMs;\n    if (inWindow) {\n      this.adConfig.consumedVmapBreakIds.add(key);\n      const tags = this.adConfig.selectVastTagsForBreak(adBreak);\n      if (!tags || tags.length === 0) return;\n      const first = tags[0];\n      const rest = tags.slice(1);\n      this.adBreak.adPodQueue = rest;\n      this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n      this.adBreak.showAds = true;\n      this.adBreak.inAdBreak = true;\n      this.timing.currentAdBreakStartWallClockMs = Date.now();\n      try {\n        await this.adBreak.playSingleAd(first);\n      } catch (error) {\n        this.adBreak.adPodQueue = [];\n        this.adBreak.inAdBreak = false;\n        this.adBreak.showAds = false;\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] VMAP ad request failed:\", error);\n        }\n      }\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Public API\n  // ───────────────────────────────────────────────────────────────\n  getCurrentAdIndex() {\n    return this.timing.currentAdIndex;\n  }\n  getTotalAdsInBreak() {\n    return this.timing.totalAdsInBreak;\n  }\n  getAdRemainingMs() {\n    return this.timing.getRemainingAdMs();\n  }\n  isAdPlaying() {\n    return this.adBreak.inAdBreak && this.adPlayer.isAdPlaying();\n  }\n  isShowingAds() {\n    return this.adBreak.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  isLive() {\n    return this.hlsEngine.isLiveStream;\n  }\n  get videoElement() {\n    return this.video;\n  }\n  toggleMute() {\n    toggleMute(this.video, this.adPlayer, this.debug);\n  }\n  toggleFullscreen() {\n    return toggleFullscreen(this.video, this.debug);\n  }\n  isMuted() {\n    return isMuted(this.video, this.adPlayer);\n  }\n  setMuted(muted) {\n    setMuted(this.video, this.adPlayer, muted, this.debug);\n  }\n  setVolume(volume) {\n    setVolume(this.video, this.adPlayer, volume, this.debug);\n  }\n  getVolume() {\n    return getVolume(this.video, this.adPlayer);\n  }\n  isFullscreen() {\n    return isFullscreen();\n  }\n  resize() {\n    resizePlayer(this.video, this.adPlayer, this.debug);\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Destroy\n  // ───────────────────────────────────────────────────────────────\n  destroy() {\n    this.adBreak.stopContinuousFetching();\n    this.preloadPool.stop();\n    this.timing.destroy();\n    this.adBreak.clearPendingAdBreak();\n    this.placeholder.destroy();\n    if (this.timeUpdateHandler) {\n      this.video.removeEventListener(\"timeupdate\", this.timeUpdateHandler);\n      delete this.timeUpdateHandler;\n    }\n    if (this.endedHandler) {\n      this.video.removeEventListener(\"ended\", this.endedHandler);\n      delete this.endedHandler;\n    }\n    if (this.emptiedHandler) {\n      this.video.removeEventListener(\"emptied\", this.emptiedHandler);\n      delete this.emptiedHandler;\n    }\n    this.adConfig.destroyTracking();\n    this.hlsEngine.destroy();\n    this.adPlayer?.destroy();\n    if (this.palPlaybackStarted) {\n      this.palPlaybackStarted = false;\n      this.palNonce.sendPlaybackEnd();\n    }\n    this.palNonce.reset();\n    this.adBreak.adRequestQueue = [];\n    this.timing.consecutiveFailures = 0;\n  }\n};\n\n// src/players/HlsPlayer.tsx\nvar HlsPlayer = class extends import_react2.Component {\n  constructor() {\n    super(...arguments);\n    this.player = null;\n    this.mounted = false;\n    this.load = async () => {\n      if (!this.props.videoElement || !this.props.src) return;\n      try {\n        if (this.player) {\n          this.player.destroy();\n          this.player = null;\n        }\n        const config = {\n          src: this.props.src,\n          videoElement: this.props.videoElement\n        };\n        if (this.props.autoplay !== void 0)\n          config.autoplay = this.props.autoplay;\n        if (this.props.muted !== void 0) config.muted = this.props.muted;\n        if (this.props.lowLatencyMode !== void 0)\n          config.lowLatencyMode = this.props.lowLatencyMode;\n        if (this.props.allowNativeHls !== void 0)\n          config.allowNativeHls = this.props.allowNativeHls;\n        if (this.props.isLiveStream !== void 0)\n          config.isLiveStream = this.props.isLiveStream;\n        if (this.props.driftToleranceMs !== void 0)\n          config.driftToleranceMs = this.props.driftToleranceMs;\n        if (this.props.immediateManifestAds !== void 0)\n          config.immediateManifestAds = this.props.immediateManifestAds;\n        if (this.props.debugAdTiming !== void 0)\n          config.debugAdTiming = this.props.debugAdTiming;\n        if (this.props.showCustomControls !== void 0)\n          config.showCustomControls = this.props.showCustomControls;\n        if (this.props.onVolumeToggle !== void 0)\n          config.onVolumeToggle = this.props.onVolumeToggle;\n        if (this.props.onFullscreenToggle !== void 0)\n          config.onFullscreenToggle = this.props.onFullscreenToggle;\n        if (this.props.onControlClick !== void 0)\n          config.onControlClick = this.props.onControlClick;\n        if (this.props.licenseKey !== void 0)\n          config.licenseKey = this.props.licenseKey;\n        if (this.props.adFailsafeTimeoutMs !== void 0)\n          config.adFailsafeTimeoutMs = this.props.adFailsafeTimeoutMs;\n        if (this.props.minSegmentsBeforePlay !== void 0)\n          config.minSegmentsBeforePlay = this.props.minSegmentsBeforePlay;\n        if (this.props.ctvAdRequest !== void 0)\n          config.ctvAdRequest = this.props.ctvAdRequest;\n        this.player = new StormcloudVideoPlayer(config);\n        this.props.onMount?.(this);\n        await this.player.load();\n        if (this.mounted) {\n          this.props.onReady?.();\n        }\n      } catch (error) {\n        if (this.mounted) {\n          this.props.onError?.(error);\n        }\n      }\n    };\n    this.play = () => {\n      if (this.props.videoElement) {\n        const video = this.props.videoElement;\n        const hasValidSource = video.src || video.currentSrc && video.currentSrc !== \"\" || video.readyState >= 1;\n        if (hasValidSource) {\n          video.play()?.catch((error) => {\n            console.error(\"[HlsPlayer] Failed to play:\", error);\n            this.props.onError?.(error);\n          });\n          this.props.onPlay?.();\n        } else {\n          console.warn(\"[HlsPlayer] Cannot play: video has no valid source\");\n        }\n      }\n    };\n    this.pause = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.pause();\n        this.props.onPause?.();\n      }\n    };\n    this.stop = () => {\n      this.pause();\n      if (this.props.videoElement) {\n        this.props.videoElement.currentTime = 0;\n      }\n    };\n    this.seekTo = (seconds, keepPlaying) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.currentTime = seconds;\n        if (!keepPlaying) {\n          this.pause();\n        }\n      }\n    };\n    this.setVolume = (volume) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.volume = Math.max(0, Math.min(1, volume));\n      }\n    };\n    this.mute = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.muted = true;\n      }\n    };\n    this.unmute = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.muted = false;\n      }\n    };\n    this.setPlaybackRate = (rate) => {\n      if (this.props.videoElement && rate > 0) {\n        this.props.videoElement.playbackRate = rate;\n      }\n    };\n    this.getDuration = () => {\n      if (this.props.videoElement && isFinite(this.props.videoElement.duration)) {\n        return this.props.videoElement.duration;\n      }\n      return null;\n    };\n    this.getCurrentTime = () => {\n      if (this.props.videoElement && isFinite(this.props.videoElement.currentTime)) {\n        return this.props.videoElement.currentTime;\n      }\n      return null;\n    };\n    this.getSecondsLoaded = () => {\n      if (this.props.videoElement && this.props.videoElement.buffered.length > 0) {\n        return this.props.videoElement.buffered.end(\n          this.props.videoElement.buffered.length - 1\n        );\n      }\n      return null;\n    };\n    this.getInternalPlayer = (key = \"player\") => {\n      if (key === \"player\") return this.player;\n      if (key === \"video\") return this.props.videoElement;\n      if (key === \"hls\" && this.player) return this.player.hls;\n      return null;\n    };\n  }\n  componentDidMount() {\n    this.mounted = true;\n    this.load();\n  }\n  componentWillUnmount() {\n    this.mounted = false;\n    if (this.player) {\n      this.player.destroy();\n      this.player = null;\n    }\n  }\n  componentDidUpdate(prevProps) {\n    if (prevProps.src !== this.props.src) {\n      this.load();\n    }\n  }\n  render() {\n    return null;\n  }\n};\nHlsPlayer.displayName = \"HlsPlayer\";\nHlsPlayer.canPlay = canPlay.hls;\n\n// src/players/FilePlayer.tsx\nvar import_react3 = require(\"react\");\nvar FilePlayer = class extends import_react3.Component {\n  constructor() {\n    super(...arguments);\n    this.mounted = false;\n    this.ready = false;\n    this.load = () => {\n      if (!this.props.videoElement || !this.props.src) return;\n      const video = this.props.videoElement;\n      const handleLoadedMetadata = () => {\n        if (this.mounted && !this.ready) {\n          this.ready = true;\n          this.props.onReady?.();\n        }\n      };\n      const handlePlay = () => {\n        if (this.mounted) {\n          this.props.onPlay?.();\n        }\n      };\n      const handlePause = () => {\n        if (this.mounted) {\n          this.props.onPause?.();\n        }\n      };\n      const handleEnded = () => {\n        if (this.mounted) {\n          this.props.onEnded?.();\n        }\n      };\n      const handleError = (error) => {\n        if (this.mounted) {\n          this.props.onError?.(error);\n        }\n      };\n      const handleLoadedData = () => {\n        if (this.mounted) {\n          this.props.onLoaded?.();\n        }\n      };\n      video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n      video.addEventListener(\"play\", handlePlay);\n      video.addEventListener(\"pause\", handlePause);\n      video.addEventListener(\"ended\", handleEnded);\n      video.addEventListener(\"error\", handleError);\n      video.addEventListener(\"loadeddata\", handleLoadedData);\n      video.src = this.props.src;\n      if (this.props.autoplay !== void 0) video.autoplay = this.props.autoplay;\n      if (this.props.muted !== void 0) video.muted = this.props.muted;\n      if (this.props.loop !== void 0) video.loop = this.props.loop;\n      if (this.props.controls !== void 0) video.controls = this.props.controls;\n      if (this.props.playsInline !== void 0)\n        video.playsInline = this.props.playsInline;\n      if (this.props.preload !== void 0)\n        video.preload = this.props.preload;\n      if (this.props.poster !== void 0) video.poster = this.props.poster;\n      this.props.onMount?.(this);\n      return () => {\n        video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n        video.removeEventListener(\"play\", handlePlay);\n        video.removeEventListener(\"pause\", handlePause);\n        video.removeEventListener(\"ended\", handleEnded);\n        video.removeEventListener(\"error\", handleError);\n        video.removeEventListener(\"loadeddata\", handleLoadedData);\n      };\n    };\n    this.play = () => {\n      if (this.props.videoElement) {\n        const video = this.props.videoElement;\n        const hasValidSource = video.src || video.currentSrc && video.currentSrc !== \"\" || video.readyState >= 1;\n        if (hasValidSource) {\n          video.play()?.catch((error) => {\n            console.error(\"[FilePlayer] Failed to play:\", error);\n            this.props.onError?.(error);\n          });\n        } else {\n          console.warn(\"[FilePlayer] Cannot play: video has no valid source\");\n        }\n      }\n    };\n    this.pause = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.pause();\n      }\n    };\n    this.stop = () => {\n      this.pause();\n      if (this.props.videoElement) {\n        this.props.videoElement.currentTime = 0;\n      }\n    };\n    this.seekTo = (seconds, keepPlaying) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.currentTime = seconds;\n        if (!keepPlaying) {\n          this.pause();\n        }\n      }\n    };\n    this.setVolume = (volume) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.volume = Math.max(0, Math.min(1, volume));\n      }\n    };\n    this.mute = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.muted = true;\n      }\n    };\n    this.unmute = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.muted = false;\n      }\n    };\n    this.setPlaybackRate = (rate) => {\n      if (this.props.videoElement && rate > 0) {\n        this.props.videoElement.playbackRate = rate;\n      }\n    };\n    this.setLoop = (loop) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.loop = loop;\n      }\n    };\n    this.getDuration = () => {\n      if (this.props.videoElement && isFinite(this.props.videoElement.duration)) {\n        return this.props.videoElement.duration;\n      }\n      return null;\n    };\n    this.getCurrentTime = () => {\n      if (this.props.videoElement && isFinite(this.props.videoElement.currentTime)) {\n        return this.props.videoElement.currentTime;\n      }\n      return null;\n    };\n    this.getSecondsLoaded = () => {\n      if (this.props.videoElement && this.props.videoElement.buffered.length > 0) {\n        return this.props.videoElement.buffered.end(\n          this.props.videoElement.buffered.length - 1\n        );\n      }\n      return null;\n    };\n    this.getInternalPlayer = (key = \"player\") => {\n      if (key === \"video\") return this.props.videoElement;\n      return null;\n    };\n    this.enablePIP = async () => {\n      if (this.props.videoElement && \"requestPictureInPicture\" in this.props.videoElement) {\n        try {\n          await this.props.videoElement.requestPictureInPicture();\n        } catch (error) {\n          console.warn(\"Picture-in-Picture failed:\", error);\n        }\n      }\n    };\n    this.disablePIP = async () => {\n      if (document.pictureInPictureElement) {\n        try {\n          await document.exitPictureInPicture();\n        } catch (error) {\n          console.warn(\"Exit Picture-in-Picture failed:\", error);\n        }\n      }\n    };\n  }\n  componentDidMount() {\n    this.mounted = true;\n    this.load();\n  }\n  componentWillUnmount() {\n    this.mounted = false;\n  }\n  componentDidUpdate(prevProps) {\n    if (prevProps.src !== this.props.src) {\n      this.load();\n    }\n  }\n  render() {\n    return null;\n  }\n};\nFilePlayer.displayName = \"FilePlayer\";\nFilePlayer.canPlay = canPlay.file;\n\n// src/players/index.ts\nvar players = [\n  {\n    key: \"hls\",\n    name: \"HLS Player\",\n    canPlay: canPlay.hls,\n    lazyPlayer: lazy(() => Promise.resolve({ default: HlsPlayer }))\n  },\n  {\n    key: \"file\",\n    name: \"File Player\",\n    canPlay: canPlay.file,\n    canEnablePIP: (url) => {\n      return canPlay.file(url) && (document.pictureInPictureEnabled || typeof document.webkitSupportsPresentationMode === \"function\");\n    },\n    lazyPlayer: lazy(() => Promise.resolve({ default: FilePlayer }))\n  }\n];\nvar players_default = players;\n","import { lazy } from \"../utils\";\nimport { canPlay } from \"../patterns\";\nimport HlsPlayer from \"./HlsPlayer\";\nimport FilePlayer from \"./FilePlayer\";\n\nexport interface PlayerConfig {\n  key: string;\n  name: string;\n  canPlay: (url: string) => boolean;\n  canEnablePIP?: (url: string) => boolean;\n  lazyPlayer?: any;\n}\n\nconst players: PlayerConfig[] = [\n  {\n    key: \"hls\",\n    name: \"HLS Player\",\n    canPlay: canPlay.hls,\n    lazyPlayer: lazy(() => Promise.resolve({ default: HlsPlayer })),\n  },\n  {\n    key: \"file\",\n    name: \"File Player\",\n    canPlay: canPlay.file,\n    canEnablePIP: (url: string) => {\n      return (\n        canPlay.file(url) &&\n        (document.pictureInPictureEnabled ||\n          typeof (document as any).webkitSupportsPresentationMode ===\n            \"function\")\n      );\n    },\n    lazyPlayer: lazy(() => Promise.resolve({ default: FilePlayer })),\n  },\n];\n\nexport default players;\n","import { lazy as reactLazy } from \"react\";\n\nexport const lazy = reactLazy;\n\nexport const omit = <T extends Record<string, any>, K extends keyof T>(\n  object: T,\n  keys: K[]\n): Omit<T, K> => {\n  const result = { ...object };\n  keys.forEach((key) => {\n    delete result[key];\n  });\n  return result;\n};\n\nexport const isMediaStream = (url: any): url is MediaStream => {\n  return (\n    typeof window !== \"undefined\" &&\n    window.MediaStream &&\n    url instanceof window.MediaStream\n  );\n};\n\nexport const supportsWebKitPresentationMode = (): boolean => {\n  if (typeof window === \"undefined\") return false;\n  const video = document.createElement(\"video\");\n  return \"webkitSupportsPresentationMode\" in video;\n};\n\nexport const randomString = (): string => {\n  return Math.random().toString(36).substr(2, 9);\n};\n\nexport const parseQuery = (url: string): Record<string, string> => {\n  const query: Record<string, string> = {};\n  const queryString = url.split(\"?\")[1] || \"\";\n\n  if (!queryString) return query;\n\n  const manualParse = (qs: string) => {\n    qs.split(\"&\").forEach((param) => {\n      const [key, value] = param.split(\"=\");\n      if (key) {\n        try {\n          query[decodeURIComponent(key)] = value\n            ? decodeURIComponent(value.replace(/\\+/g, \" \"))\n            : \"\";\n        } catch (e) {\n          query[key] = value || \"\";\n        }\n      }\n    });\n  };\n\n  if (typeof URLSearchParams !== \"undefined\") {\n    try {\n      const params = new URLSearchParams(queryString);\n      params.forEach((value, key) => {\n        query[key] = value;\n      });\n      return query;\n    } catch (e) {\n      manualParse(queryString);\n    }\n  } else {\n    manualParse(queryString);\n  }\n\n  return query;\n};\n\nexport const merge = <T extends Record<string, any>>(\n  target: T,\n  ...sources: Partial<T>[]\n): T => {\n  if (!sources.length) return target;\n  const source = sources.shift();\n\n  if (isObject(target) && isObject(source)) {\n    for (const key in source) {\n      if (isObject(source[key])) {\n        if (!target[key]) Object.assign(target, { [key]: {} });\n        merge(target[key] as any, source[key] as any);\n      } else {\n        Object.assign(target, { [key]: source[key] });\n      }\n    }\n  }\n\n  return merge(target, ...sources);\n};\n\nconst isObject = (item: any): item is Record<string, any> => {\n  return item && typeof item === \"object\" && !Array.isArray(item);\n};\n\nexport const IS_BROWSER = typeof window !== \"undefined\" && window.document;\nexport const IS_GLOBAL =\n  typeof globalThis !== \"undefined\" &&\n  globalThis.window &&\n  globalThis.window.document;\nexport const IS_IOS =\n  IS_BROWSER && /iPad|iPhone|iPod/.test(navigator.userAgent);\nexport const IS_SAFARI =\n  IS_BROWSER && /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n\nexport const SUPPORTS_HLS = (): boolean => {\n  if (!IS_BROWSER) return false;\n  const video = document.createElement(\"video\");\n  return Boolean(video.canPlayType(\"application/vnd.apple.mpegurl\"));\n};\n\nexport const SUPPORTS_DASH = (): boolean => {\n  if (!IS_BROWSER) return false;\n  const video = document.createElement(\"video\");\n  return Boolean(video.canPlayType(\"application/dash+xml\"));\n};\n","export const HLS_EXTENSIONS = /\\.(m3u8)($|\\?)/i;\nexport const HLS_PATHS = /\\/hls\\//i;\nexport const DASH_EXTENSIONS = /\\.(mpd)($|\\?)/i;\nexport const VIDEO_EXTENSIONS = /\\.(mp4|webm|ogg|avi|mov|wmv|flv|mkv)($|\\?)/i;\nexport const AUDIO_EXTENSIONS = /\\.(mp3|wav|ogg|aac|wma|flac|m4a)($|\\?)/i;\n\nexport const canPlay = {\n  hls: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return HLS_EXTENSIONS.test(url) || HLS_PATHS.test(url);\n  },\n\n  dash: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return DASH_EXTENSIONS.test(url);\n  },\n\n  video: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return VIDEO_EXTENSIONS.test(url);\n  },\n\n  audio: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return AUDIO_EXTENSIONS.test(url);\n  },\n\n  file: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return VIDEO_EXTENSIONS.test(url) || AUDIO_EXTENSIONS.test(url);\n  },\n};\n","import { Component } from \"react\";\nimport { StormcloudVideoPlayer } from \"../player/StormcloudVideoPlayer\";\nimport type { StormcloudVideoPlayerConfig } from \"../types\";\nimport { canPlay } from \"../patterns\";\n\nexport interface HlsPlayerProps extends StormcloudVideoPlayerConfig {\n  onMount?: (player: any) => void;\n  onReady?: () => void;\n  onPlay?: () => void;\n  onPause?: () => void;\n  onEnded?: () => void;\n  onLoaded?: () => void;\n  onError?: (error: any) => void;\n}\n\nexport default class HlsPlayer extends Component<HlsPlayerProps> {\n  static displayName = \"HlsPlayer\";\n\n  static canPlay = canPlay.hls;\n\n  private player: StormcloudVideoPlayer | null = null;\n  private mounted = false;\n\n  componentDidMount() {\n    this.mounted = true;\n    this.load();\n  }\n\n  componentWillUnmount() {\n    this.mounted = false;\n    if (this.player) {\n      this.player.destroy();\n      this.player = null;\n    }\n  }\n\n  componentDidUpdate(prevProps: HlsPlayerProps) {\n    if (prevProps.src !== this.props.src) {\n      this.load();\n    }\n  }\n\n  load = async () => {\n    if (!this.props.videoElement || !this.props.src) return;\n\n    try {\n      if (this.player) {\n        this.player.destroy();\n        this.player = null;\n      }\n\n      const config: StormcloudVideoPlayerConfig = {\n        src: this.props.src,\n        videoElement: this.props.videoElement,\n      };\n\n      if (this.props.autoplay !== undefined)\n        config.autoplay = this.props.autoplay;\n      if (this.props.muted !== undefined) config.muted = this.props.muted;\n      if (this.props.lowLatencyMode !== undefined)\n        config.lowLatencyMode = this.props.lowLatencyMode;\n      if (this.props.allowNativeHls !== undefined)\n        config.allowNativeHls = this.props.allowNativeHls;\n      if (this.props.isLiveStream !== undefined)\n        config.isLiveStream = this.props.isLiveStream;\n      if (this.props.driftToleranceMs !== undefined)\n        config.driftToleranceMs = this.props.driftToleranceMs;\n      if (this.props.immediateManifestAds !== undefined)\n        config.immediateManifestAds = this.props.immediateManifestAds;\n      if (this.props.debugAdTiming !== undefined)\n        config.debugAdTiming = this.props.debugAdTiming;\n      if (this.props.showCustomControls !== undefined)\n        config.showCustomControls = this.props.showCustomControls;\n      if (this.props.onVolumeToggle !== undefined)\n        config.onVolumeToggle = this.props.onVolumeToggle;\n      if (this.props.onFullscreenToggle !== undefined)\n        config.onFullscreenToggle = this.props.onFullscreenToggle;\n      if (this.props.onControlClick !== undefined)\n        config.onControlClick = this.props.onControlClick;\n      if (this.props.licenseKey !== undefined)\n        config.licenseKey = this.props.licenseKey;\n      if (this.props.adFailsafeTimeoutMs !== undefined)\n        config.adFailsafeTimeoutMs = this.props.adFailsafeTimeoutMs;\n      if (this.props.minSegmentsBeforePlay !== undefined)\n        config.minSegmentsBeforePlay = this.props.minSegmentsBeforePlay;\n      if (this.props.ctvAdRequest !== undefined)\n        config.ctvAdRequest = this.props.ctvAdRequest;\n\n      this.player = new StormcloudVideoPlayer(config);\n\n      this.props.onMount?.(this);\n\n      await this.player.load();\n\n      if (this.mounted) {\n        this.props.onReady?.();\n      }\n    } catch (error) {\n      if (this.mounted) {\n        this.props.onError?.(error);\n      }\n    }\n  };\n\n  play = () => {\n    if (this.props.videoElement) {\n      const video = this.props.videoElement;\n      const hasValidSource =\n        video.src ||\n        (video.currentSrc && video.currentSrc !== \"\") ||\n        video.readyState >= 1;\n\n      if (hasValidSource) {\n        video.play()?.catch((error) => {\n          console.error(\"[HlsPlayer] Failed to play:\", error);\n          this.props.onError?.(error);\n        });\n        this.props.onPlay?.();\n      } else {\n        console.warn(\"[HlsPlayer] Cannot play: video has no valid source\");\n      }\n    }\n  };\n\n  pause = () => {\n    if (this.props.videoElement) {\n      this.props.videoElement.pause();\n      this.props.onPause?.();\n    }\n  };\n\n  stop = () => {\n    this.pause();\n    if (this.props.videoElement) {\n      this.props.videoElement.currentTime = 0;\n    }\n  };\n\n  seekTo = (seconds: number, keepPlaying?: boolean) => {\n    if (this.props.videoElement) {\n      this.props.videoElement.currentTime = seconds;\n      if (!keepPlaying) {\n        this.pause();\n      }\n    }\n  };\n\n  setVolume = (volume: number) => {\n    if (this.props.videoElement) {\n      this.props.videoElement.volume = Math.max(0, Math.min(1, volume));\n    }\n  };\n\n  mute = () => {\n    if (this.props.videoElement) {\n      this.props.videoElement.muted = true;\n    }\n  };\n\n  unmute = () => {\n    if (this.props.videoElement) {\n      this.props.videoElement.muted = false;\n    }\n  };\n\n  setPlaybackRate = (rate: number) => {\n    if (this.props.videoElement && rate > 0) {\n      this.props.videoElement.playbackRate = rate;\n    }\n  };\n\n  getDuration = (): number | null => {\n    if (this.props.videoElement && isFinite(this.props.videoElement.duration)) {\n      return this.props.videoElement.duration;\n    }\n    return null;\n  };\n\n  getCurrentTime = (): number | null => {\n    if (\n      this.props.videoElement &&\n      isFinite(this.props.videoElement.currentTime)\n    ) {\n      return this.props.videoElement.currentTime;\n    }\n    return null;\n  };\n\n  getSecondsLoaded = (): number | null => {\n    if (\n      this.props.videoElement &&\n      this.props.videoElement.buffered.length > 0\n    ) {\n      return this.props.videoElement.buffered.end(\n        this.props.videoElement.buffered.length - 1\n      );\n    }\n    return null;\n  };\n\n  getInternalPlayer = (key = \"player\") => {\n    if (key === \"player\") return this.player;\n    if (key === \"video\") return this.props.videoElement;\n    if (key === \"hls\" && this.player) return (this.player as any).hls;\n    return null;\n  };\n\n  render() {\n    return null;\n  }\n}\n","import type { AdController } 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\ntype VastParseResult =\n  | { type: \"inline\"; ad: VastAd }\n  | {\n      type: \"wrapper\";\n      vastAdTagUri: string;\n      trackingUrls: VastTrackingUrls;\n      clickThrough?: string | undefined;\n    }\n  | { type: \"empty\" };\n\nconst MAX_VAST_WRAPPER_DEPTH = 5;\n\nexport function createHlsAdPlayer(\n  contentVideo: HTMLVideoElement,\n  options?: {\n    continueLiveStreamDuringAds?: boolean;\n    licenseKey?: string;\n    mainHlsInstance?: Hls;\n  }\n): AdController {\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 podAds: VastAd[] = [];\n  let podIndex = 0;\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 isHlsMediaFile(mediaFile: VastMediaFile): boolean {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return (\n      type === \"application/x-mpegurl\" ||\n      type === \"application/vnd.apple.mpegurl\" ||\n      type.includes(\"mpegurl\") ||\n      url.includes(\".m3u8\")\n    );\n  }\n\n  function isProgressiveMediaFile(mediaFile: VastMediaFile): boolean {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return (\n      type.startsWith(\"video/\") ||\n      url.endsWith(\".mp4\") ||\n      url.includes(\".mp4?\")\n    );\n  }\n\n  function createEmptyTrackingUrls(): VastTrackingUrls {\n    return {\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\n  function extractTrackingUrls(scope: Document | Element): VastTrackingUrls {\n    const trackingUrls = createEmptyTrackingUrls();\n\n    scope.querySelectorAll(\"Impression\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.impression.push(url);\n    });\n\n    scope.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    scope.querySelectorAll(\"Error\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.error.push(url);\n    });\n\n    return trackingUrls;\n  }\n\n  function mergeTrackingUrls(\n    target: VastTrackingUrls,\n    source: VastTrackingUrls\n  ): VastTrackingUrls {\n    (Object.keys(target) as Array<keyof VastTrackingUrls>).forEach((key) => {\n      if (source[key] && source[key].length > 0) {\n        target[key] = target[key].concat(source[key]);\n      }\n    });\n    return target;\n  }\n\n  function parseVastXml(xmlString: string): VastParseResult {\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 { type: \"empty\" };\n      }\n\n      const adElement = xmlDoc.querySelector(\"Ad\");\n      if (!adElement) {\n        console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n        return { type: \"empty\" };\n      }\n\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n      const clickThrough = xmlDoc\n        .querySelector(\"ClickThrough\")\n        ?.textContent?.trim();\n\n      const wrapperUri = xmlDoc\n        .querySelector(\"VASTAdTagURI\")\n        ?.textContent?.trim();\n      if (wrapperUri) {\n        console.log(\n          `[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ${wrapperUri}`\n        );\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough,\n        };\n      }\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        const mediaFile: VastMediaFile = {\n          url,\n          type,\n          width: parseInt(width || \"1920\", 10),\n          height: parseInt(height || \"1080\", 10),\n          bitrate: undefined,\n        };\n\n        if (!url) {\n          console.warn(`[HlsAdPlayer] MediaFile ${index} has empty URL`);\n          return;\n        }\n\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr\n          ? parseInt(bitrateAttr, 10)\n          : undefined;\n        mediaFile.bitrate =\n          bitrateValue && bitrateValue > 0 ? bitrateValue : undefined;\n\n        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n          console.log(\n            `[HlsAdPlayer] Added ${isHlsMediaFile(mediaFile) ? \"HLS\" : \"progressive\"} MediaFile: ${url}`\n          );\n        } else {\n          console.log(\n            `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not supported)`\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 supported media files found in VAST XML\");\n        }\n        return { type: \"empty\" };\n      }\n\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough,\n        },\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n      return { type: \"empty\" };\n    }\n  }\n\n  function parseAdElement(adElement: Element): VastParseResult {\n    try {\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n      const clickThrough = adElement\n        .querySelector(\"ClickThrough\")\n        ?.textContent?.trim();\n\n      const wrapperUri = adElement\n        .querySelector(\"VASTAdTagURI\")\n        ?.textContent?.trim();\n      if (wrapperUri) {\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough,\n        };\n      }\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        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        parseInt(durationParts[2] || \"0\", 10);\n\n      const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n      const mediaFiles: VastMediaFile[] = [];\n\n      mediaFileElements.forEach((mf) => {\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        if (!url) return;\n\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : undefined;\n\n        const mediaFile: VastMediaFile = {\n          url,\n          type,\n          width: parseInt(width || \"1920\", 10),\n          height: parseInt(height || \"1080\", 10),\n          bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : undefined,\n        };\n\n        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n        }\n      });\n\n      if (mediaFiles.length === 0) {\n        if (isNoAdAvailable) {\n          console.warn(\n            \"[HlsAdPlayer] Pod <Ad> indicates no ad available\"\n          );\n        } else {\n          console.warn(\"[HlsAdPlayer] No supported media files in pod <Ad>\");\n        }\n        return { type: \"empty\" };\n      }\n\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough,\n        },\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing pod <Ad> element:\", error);\n      return { type: \"empty\" };\n    }\n  }\n\n  async function fetchVastXml(vastTagUrl: string): Promise<string> {\n    const response = await fetch(vastTagUrl, {\n      mode: \"cors\",\n      credentials: \"include\",\n      headers: {\n        \"Accept\": \"application/xml, text/xml, */*\",\n      },\n      referrerPolicy: \"no-referrer-when-downgrade\",\n    });\n    if (!response.ok) {\n      throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n    }\n    return response.text();\n  }\n\n  async function fetchAndParseVastAd(\n    vastTagUrl: string,\n    depth = 0,\n    accumulatedTracking: VastTrackingUrls = createEmptyTrackingUrls()\n  ): Promise<VastAd | null> {\n    const vastXml = await fetchVastXml(vastTagUrl);\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    const parsed = parseVastXml(vastXml);\n\n    if (parsed.type === \"empty\") {\n      return null;\n    }\n\n    if (parsed.type === \"wrapper\") {\n      if (depth >= MAX_VAST_WRAPPER_DEPTH) {\n        console.warn(\n          `[HlsAdPlayer] VAST wrapper depth limit (${MAX_VAST_WRAPPER_DEPTH}) reached, aborting redirect chain`\n        );\n        return null;\n      }\n\n      mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);\n      return fetchAndParseVastAd(\n        parsed.vastAdTagUri,\n        depth + 1,\n        accumulatedTracking\n      );\n    }\n\n    mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);\n    return parsed.ad;\n  }\n\n  async function fetchAndParsePod(vastTagUrl: string): Promise<VastAd[]> {\n    const vastXml = await fetchVastXml(vastTagUrl);\n    console.log(\"[HlsAdPlayer] Pod VAST XML received\");\n\n    const parser = new DOMParser();\n    const xmlDoc = parser.parseFromString(vastXml, \"text/xml\");\n\n    if (xmlDoc.querySelector(\"parsererror\")) {\n      console.error(\"[HlsAdPlayer] Pod VAST XML parsing error (malformed)\");\n      return [];\n    }\n\n    const adElements = Array.from(xmlDoc.querySelectorAll(\"Ad\"));\n    if (adElements.length === 0) {\n      console.warn(\"[HlsAdPlayer] No <Ad> elements found in pod VAST response\");\n      return [];\n    }\n\n    adElements.sort((a, b) => {\n      const aSeq = parseInt(a.getAttribute(\"sequence\") || \"\", 10);\n      const bSeq = parseInt(b.getAttribute(\"sequence\") || \"\", 10);\n      const aVal = Number.isFinite(aSeq) ? aSeq : Number.MAX_SAFE_INTEGER;\n      const bVal = Number.isFinite(bSeq) ? bSeq : Number.MAX_SAFE_INTEGER;\n      return aVal - bVal;\n    });\n\n    const ads: VastAd[] = [];\n    for (const adElement of adElements) {\n      const parsed = parseAdElement(adElement);\n\n      if (parsed.type === \"inline\") {\n        ads.push(parsed.ad);\n      } else if (parsed.type === \"wrapper\") {\n        try {\n          const resolved = await fetchAndParseVastAd(\n            parsed.vastAdTagUri,\n            1,\n            parsed.trackingUrls\n          );\n          if (resolved) {\n            ads.push(resolved);\n          }\n        } catch (error) {\n          console.warn(\n            \"[HlsAdPlayer] Failed to resolve wrapper <Ad> in pod:\",\n            error\n          );\n        }\n      }\n    }\n\n    console.log(`[HlsAdPlayer] Parsed ${ads.length} ad(s) from pod VAST response`);\n    return ads;\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      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\n      }\n\n      handleAdComplete();\n    });\n\n    adVideoElement.addEventListener(\"error\", (e) => {\n      if (!adPlaying) return;\n      console.error(\"[HlsAdPlayer] Ad video error:\", e);\n      if (currentAd) {\n        fireTrackingPixels(currentAd.trackingUrls.error);\n      }\n\n      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\n      }\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 resetQuartileTracking(preserveImpression: boolean): void {\n    trackingFired = {\n      impression: preserveImpression ? trackingFired.impression : false,\n      start: false,\n      firstQuartile: false,\n      midpoint: false,\n      thirdQuartile: false,\n      complete: false,\n    };\n  }\n\n  function loadCurrentAdMedia(): void {\n    if (!adVideoElement || !currentAd) {\n      throw new Error(\"No ad video element or ad to load\");\n    }\n\n    const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n    if (!mediaFile) {\n      throw new Error(\"No media file available for ad\");\n    }\n\n    const isHlsAd = isHlsMediaFile(mediaFile);\n    console.log(\n      `[HlsAdPlayer] Loading ${isHlsAd ? \"HLS\" : \"progressive\"} ad (pod ${podIndex + 1}/${podAds.length || 1}) from: ${mediaFile.url}`\n    );\n\n    if (isHlsAd && 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      isHlsAd &&\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 if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {\n      if (adHls) {\n        adHls.destroy();\n        adHls = undefined;\n      }\n\n      adVideoElement.src = mediaFile.url;\n      adVideoElement.load();\n      adVideoElement.play().catch((error) => {\n        console.error(\"[HlsAdPlayer] Error starting progressive ad playback:\", error);\n        handleAdError();\n      });\n    } else {\n      throw new Error(`Unsupported ad media file type: ${mediaFile.type}`);\n    }\n  }\n\n  function advanceToNextPodAd(): boolean {\n    if (podIndex >= podAds.length - 1) {\n      return false;\n    }\n\n    podIndex++;\n    currentAd = podAds[podIndex];\n    resetQuartileTracking(false);\n\n    if (currentAd) {\n      fireTrackingPixels(currentAd.trackingUrls.impression);\n      trackingFired.impression = true;\n      console.log(\n        `[HlsAdPlayer] Advancing to next pod ad (${podIndex + 1}/${podAds.length}): ${currentAd.title}, duration: ${currentAd.duration}s`\n      );\n    }\n\n    try {\n      loadCurrentAdMedia();\n      emit(\"pod_ad_started\", { index: podIndex, total: podAds.length });\n      return true;\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Failed to load next pod ad:\", error);\n      return false;\n    }\n  }\n\n  function handleAdComplete(): void {\n    console.log(\"[HlsAdPlayer] Handling ad completion\");\n    adPlaying = false;\n    setAdPlayingFlag(false);\n\n    contentVideo.muted = true;\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        console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback\");\n        contentVideo.play().catch(() => {});\n      } else {\n        console.log(\"[HlsAdPlayer] Content video already playing in live mode\");\n      }\n    }\n\n    emit(\"content_resume\");\n  }\n\n  function handleAdError(): void {\n    console.log(\"[HlsAdPlayer] Handling ad error\");\n    adPlaying = false;\n    setAdPlayingFlag(false);\n\n    contentVideo.muted = true;\n\n    if (adContainerEl) {\n      adContainerEl.style.display = \"none\";\n      adContainerEl.style.pointerEvents = \"none\";\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 = \"30\";\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 ads: VastAd[] = [];\n\n        if (preloadedAds.has(vastTagUrl)) {\n          const preloaded = preloadedAds.get(vastTagUrl);\n          preloadedAds.delete(vastTagUrl);\n          if (preloaded) {\n            ads = [preloaded];\n          }\n          console.log(\n            \"[HlsAdPlayer] Using preloaded VAST response:\",\n            vastTagUrl\n          );\n        } else {\n          ads = await fetchAndParsePod(vastTagUrl);\n        }\n\n        if (!ads.length) {\n          console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n          emit(\"ad_error\");\n          return Promise.reject(new Error(\"No ads available from VAST response\"));\n        }\n\n        podAds = ads;\n        podIndex = 0;\n        currentAd = ads[0];\n        console.log(\n          `[HlsAdPlayer] Pod parsed: ${ads.length} ad(s), first=\"${currentAd?.title}\", duration=${currentAd?.duration}s`\n        );\n\n        if (currentAd) {\n          fireTrackingPixels(currentAd.trackingUrls.impression);\n          trackingFired.impression = true;\n        }\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 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        resetQuartileTracking(true);\n\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        adPlaying = true;\n        setAdPlayingFlag(true);\n\n        if (adVideoElement) {\n          adVideoElement.volume = Math.max(0, Math.min(1, originalVolume));\n          adVideoElement.muted = originalMutedState;\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        loadCurrentAdMedia();\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    pause() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n\n      try {\n        if (adVideoElement && !adVideoElement.paused) {\n          adVideoElement.pause();\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error pausing ad:\", error);\n      }\n    },\n    resume() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n\n      try {\n        if (adVideoElement && adVideoElement.paused) {\n          adVideoElement.play().catch(() => {});\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error resuming ad:\", error);\n      }\n    },\n    async stop() {\n      console.log(\"[HlsAdPlayer] Stopping ad\");\n      adPlaying = false;\n      setAdPlayingFlag(false);\n\n      const previousMutedState = contentVideo.muted;\n      contentVideo.muted = originalMutedState;\n      contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n      console.log(\n        `[HlsAdPlayer] Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}, volume: ${contentVideo.volume}`\n      );\n\n      if (adContainerEl) {\n        adContainerEl.style.display = \"none\";\n        adContainerEl.style.pointerEvents = \"none\";\n      }\n\n      contentVideo.style.visibility = \"visible\";\n      contentVideo.style.opacity = \"1\";\n\n      if (options?.continueLiveStreamDuringAds) {\n        if (contentVideo.paused) {\n          console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback on stop\");\n          contentVideo.play().catch(() => {});\n        }\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      podAds = [];\n      podIndex = 0;\n    },\n\n    destroy() {\n      console.log(\"[HlsAdPlayer] Destroying\");\n      destroyed = true;\n      \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 = Math.max(0, Math.min(1, 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      podAds = [];\n      podIndex = 0;\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        const clamped = Math.max(0, Math.min(1, volume));\n        adVideoElement.volume = clamped;\n        adVideoElement.muted = clamped === 0;\n      }\n    },\n\n    getAdVolume(): number {\n      if (adVideoElement && adPlaying) {\n        return adVideoElement.volume;\n      }\n      return 1;\n    },\n    showPlaceholder() {\n      contentVideo.style.opacity = \"0\";\n      contentVideo.style.visibility = \"hidden\";\n      \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      if (!adPlaying) {\n        contentVideo.style.visibility = \"visible\";\n        contentVideo.style.opacity = \"1\";\n      }\n    },\n    getLoadedAdDuration() {\n      return currentAd?.duration;\n    },\n    getLoadedAdId() {\n      return currentAd?.id;\n    },\n    getPodAdCount() {\n      return podAds.length;\n    },\n    getPodTotalDurationMs() {\n      return podAds.reduce(\n        (total, ad) => total + (ad.duration > 0 ? ad.duration * 1000 : 0),\n        0\n      );\n    },\n  };\n}\n","declare global {\n  interface Window {\n    goog?: any;\n  }\n}\n\nconst PAL_SDK_URL =\n  \"https://imasdk.googleapis.com/pal/sdkloader/pal.js\";\n\nlet _nonceLoader: any | undefined;\nlet _palLoadPromise: Promise<void> | undefined;\n\nfunction loadPalSdk(): Promise<void> {\n  if (typeof window !== \"undefined\" && window.goog?.pal) {\n    return Promise.resolve();\n  }\n\n  if (_palLoadPromise) return _palLoadPromise;\n\n  _palLoadPromise = new Promise<void>((resolve, reject) => {\n    const existing = document.querySelector(\n      'script[data-pal=\"true\"]'\n    ) as HTMLScriptElement | null;\n\n    if (existing) {\n      if (window.goog?.pal) {\n        resolve();\n        return;\n      }\n      const timeout = setTimeout(\n        () => reject(new Error(\"PAL SDK load timeout\")),\n        10000\n      );\n      existing.addEventListener(\"load\", () => {\n        clearTimeout(timeout);\n        resolve();\n      });\n      existing.addEventListener(\"error\", () => {\n        clearTimeout(timeout);\n        reject(new Error(\"PAL SDK load failed\"));\n      });\n      return;\n    }\n\n    const script = document.createElement(\"script\");\n    script.src = PAL_SDK_URL;\n    script.async = true;\n    script.setAttribute(\"data-pal\", \"true\");\n    script.onload = () => resolve();\n    script.onerror = () => reject(new Error(\"PAL SDK load failed\"));\n    document.head.appendChild(script);\n  });\n\n  return _palLoadPromise;\n}\n\nfunction getOrCreateNonceLoader(): any {\n  if (_nonceLoader) return _nonceLoader;\n  const goog = window.goog;\n  const consentSettings = new goog.pal.ConsentSettings();\n  consentSettings.allowStorage = true;\n  _nonceLoader = new goog.pal.NonceLoader(consentSettings);\n  return _nonceLoader;\n}\n\nexport interface PalNonceOptions {\n  videoWidth?: number;\n  videoHeight?: number;\n  descriptionUrl?: string;\n  ppid?: string;\n  sessionId?: string;\n  adWillAutoPlay?: boolean;\n  adWillPlayMuted?: boolean;\n  playerVolume?: number;\n  continuousPlayback?: boolean;\n}\n\nexport interface PalNonceManager {\n  generateNonce(options?: PalNonceOptions): Promise<string>;\n\n  getCurrentNonce(): string;\n\n  injectNonce(vastTagUrl: string): string;\n\n  sendPlaybackStart(): void;\n\n  sendPlaybackEnd(): void;\n\n  sendAdClick(): void;\n\n  sendAdTouch(event: MouseEvent | TouchEvent): void;\n\n  reset(): void;\n}\n\nexport function createPalNonceManager(): PalNonceManager {\n  let currentNonce = \"\";\n  let currentNonceManager: any | undefined;\n\n  return {\n    async generateNonce(options: PalNonceOptions = {}): Promise<string> {\n      try {\n        await loadPalSdk();\n\n        const loader = getOrCreateNonceLoader();\n        const goog = window.goog;\n\n        const request = new goog.pal.NonceRequest();\n        request.adWillAutoPlay = options.adWillAutoPlay ?? true;\n        request.adWillPlayMuted = options.adWillPlayMuted ?? false;\n        request.playerVolume =\n          options.playerVolume ?? (request.adWillPlayMuted ? 0 : 1);\n        request.continuousPlayback = options.continuousPlayback ?? true;\n        request.descriptionUrl =\n          options.descriptionUrl ||\n          (typeof window !== \"undefined\" ? window.location.href : \"\");\n        request.iconsSupported = true;\n        request.playerType = \"StormcloudVideoPlayer\";\n        request.playerVersion = \"1.0\";\n        request.supportedApiFrameworks = \"2,7,9\";\n        request.url =\n          options.descriptionUrl ||\n          (typeof window !== \"undefined\" ? window.location.href : \"\");\n        request.videoWidth = options.videoWidth || 640;\n        request.videoHeight = options.videoHeight || 480;\n\n        if (options.ppid) request.ppid = options.ppid;\n        if (options.sessionId) request.sessionId = options.sessionId;\n\n        const manager = await loader.loadNonceManager(request);\n        currentNonceManager = manager;\n        currentNonce = manager.getNonce() as string;\n\n        console.log(\"[PAL] Nonce generated successfully\");\n        return currentNonce;\n      } catch (error) {\n        console.warn(\"[PAL] Failed to generate nonce:\", error);\n        currentNonce = \"\";\n        currentNonceManager = undefined;\n        return \"\";\n      }\n    },\n\n    getCurrentNonce(): string {\n      return currentNonce;\n    },\n\n    injectNonce(vastTagUrl: string): string {\n      if (!currentNonce || !vastTagUrl) return vastTagUrl;\n\n      try {\n        const url = new URL(vastTagUrl);\n        url.searchParams.delete(\"paln\");\n        url.searchParams.set(\"givn\", currentNonce);\n        return url.toString();\n      } catch {\n        let base = vastTagUrl\n          .replace(/([?&])paln=[^&]*/g, \"\")\n          .replace(/[?&]$/, \"\");\n        const sep = base.includes(\"?\") ? \"&\" : \"?\";\n        return `${base}${sep}givn=${encodeURIComponent(currentNonce)}`;\n      }\n    },\n\n    sendPlaybackStart(): void {\n      try {\n        currentNonceManager?.sendPlaybackStart();\n      } catch {}\n    },\n\n    sendPlaybackEnd(): void {\n      try {\n        currentNonceManager?.sendPlaybackEnd();\n      } catch {}\n    },\n\n    sendAdClick(): void {\n      try {\n        currentNonceManager?.sendAdClick();\n      } catch {}\n    },\n\n    sendAdTouch(event: MouseEvent | TouchEvent): void {\n      try {\n        currentNonceManager?.sendAdTouch(event);\n      } catch {}\n    },\n\n    reset(): void {\n      currentNonce = \"\";\n      currentNonceManager = undefined;\n    },\n  };\n}\n","export const MQTT_CA_CERT_FILE = \"src/certs/emqxsl-ca.crt\";\n\nexport type MQTTConfig = {\n  enabled: boolean;\n  brokerAddress: string;\n  brokerPort: number;\n  wsPort: number;\n  username: string;\n  password: string;\n  topicPrefix: string;\n  qos: 0 | 1 | 2;\n  brokerUrl?: string;\n};\n\nexport const DEFAULT_MQTT_CONFIG: MQTTConfig = {\n  enabled: true,\n  brokerAddress: \"vecbae77.ala.us-east-1.emqxsl.com\",\n  brokerPort: 8883,\n  wsPort: 8084,\n  username: \"for-sonifi\",\n  password: \"sonifi-mqtt\",\n  topicPrefix: \"adstorm/players\",\n  qos: 1,\n};\n\nexport const mqttConfig: MQTTConfig = { ...DEFAULT_MQTT_CONFIG };\n\nexport function applyMQTTConfig(overrides: Partial<MQTTConfig>): void {\n  Object.assign(mqttConfig, overrides);\n}\n\nexport function isMQTTEnabled(): boolean {\n  return mqttConfig.enabled;\n}\n\nexport function buildMQTTBrokerUrl(): string {\n  if (mqttConfig.brokerUrl) return mqttConfig.brokerUrl;\n  return `wss://${mqttConfig.brokerAddress}:${mqttConfig.wsPort}/mqtt`;\n}\n\nexport function buildPlayerTopic(\n  licenseKey: string,\n  channel: \"metrics\" | \"impressions\" | \"heartbeat\"\n): string {\n  return `${mqttConfig.topicPrefix}/${licenseKey}/${channel}`;\n}\n","import mqtt from \"mqtt\";\nimport type { MqttClient } from \"mqtt\";\nimport {\n  applyMQTTConfig,\n  buildMQTTBrokerUrl,\n  isMQTTEnabled,\n  mqttConfig,\n} from \"./mqttConfig\";\nimport type { MQTTConfig } from \"./mqttConfig\";\n\nconst LOG = \"[StormcloudVideoPlayer][MQTT]\";\n\nexport type MQTTStatus = \"disconnected\" | \"connecting\" | \"connected\" | \"error\";\n\nlet client: MqttClient | null = null;\nlet status: MQTTStatus = \"disconnected\";\n\nexport function getMQTTStatus(): MQTTStatus {\n  return status;\n}\n\nexport function isMQTTConnected(): boolean {\n  return status === \"connected\" && client !== null && client.connected;\n}\n\nexport function isMQTTConfigured(): boolean {\n  return isMQTTEnabled();\n}\n\nexport function configureMQTT(overrides: Partial<MQTTConfig>): void {\n  applyMQTTConfig(overrides);\n  disconnectMQTT();\n}\n\nexport function initMQTTClient(): void {\n  if (client || !isMQTTEnabled()) return;\n\n  const url = buildMQTTBrokerUrl();\n  status = \"connecting\";\n\n  const clientId = `stormcloud-vp-${Math.random().toString(36).slice(2, 9)}`;\n\n  try {\n    client = mqtt.connect(url, {\n      clientId,\n      username: mqttConfig.username,\n      password: mqttConfig.password,\n      keepalive: 60,\n      clean: true,\n      reconnectPeriod: 5000,\n      connectTimeout: 10_000,\n      queueQoSZero: false,\n    });\n  } catch (err) {\n    status = \"error\";\n    console.warn(`${LOG} connect() threw:`, err);\n    return;\n  }\n\n  client.on(\"connect\", () => {\n    status = \"connected\";\n    console.info(`${LOG} connected to ${url}`);\n  });\n\n  client.on(\"reconnect\", () => {\n    status = \"connecting\";\n    console.info(`${LOG} reconnecting…`);\n  });\n\n  client.on(\"offline\", () => {\n    status = \"disconnected\";\n    console.warn(`${LOG} offline`);\n  });\n\n  client.on(\"error\", (err) => {\n    status = \"error\";\n    console.warn(`${LOG} error:`, err.message);\n  });\n\n  client.on(\"close\", () => {\n    if (status === \"connected\") {\n      status = \"disconnected\";\n    }\n  });\n}\n\nexport function ensureMQTTClient(): void {\n  if (isMQTTEnabled() && !client) {\n    initMQTTClient();\n  }\n}\n\nexport function publishMQTT(\n  topic: string,\n  payload: Record<string, unknown>\n): boolean {\n  if (!isMQTTEnabled()) {\n    return false;\n  }\n\n  ensureMQTTClient();\n\n  if (!client) {\n    return false;\n  }\n\n  try {\n    client.publish(topic, JSON.stringify(payload), { qos: mqttConfig.qos });\n    return true;\n  } catch (err) {\n    console.warn(`${LOG} publish failed on ${topic}:`, err);\n    return false;\n  }\n}\n\nexport function disconnectMQTT(): void {\n  if (client) {\n    client.end(true);\n    client = null;\n    status = \"disconnected\";\n  }\n}\n","export interface VastEnvironmentSignals {\n  isCtv: boolean;\n  contentUrl?: string;\n  appId?: string;\n  appName?: string;\n  sessionId?: string;\n  deviceId?: string;\n  deviceIdType?: string;\n  limitAdTracking?: boolean;\n  deviceTypeHint?: number;\n}\n\nconst AIRY_ANDROID_APP_ID = \"com.freeairytv.android\";\nconst AIRY_WEBOS_APP_ID    = \"com.freeairytv.webos\";\nconst AIRY_TIZEN_APP_ID    = \"com.freeairytv.samsung\";\nconst AIRY_ROKU_APP_ID     = \"com.freeairytv.roku\";\nconst AIRY_APP_NAME = \"AiryTV Movies & TV\";\nconst AIRY_DEFAULT_CONTENT_URL = \"https://live.airy.tv\";\nconst CTV_SESSION_STORAGE_KEY = \"stormcloud.ctv.sid\";\nexport const PLAYER_ID_STORAGE_KEY = \"stormcloud.player.id\";\n\nconst LG_TEST_APP_ID      = \"com.hulu.plus\";\nconst LG_TEST_APP_NAME    = \"Hulu\";\nconst LG_TEST_CONTENT_URL = \"https://www.hulu.com/live-tv\";\n\nlet _lgTestDeviceId: string | undefined;\nfunction getLgTestDeviceId(): string {\n  if (!_lgTestDeviceId) _lgTestDeviceId = createUuid();\n  return _lgTestDeviceId;\n}\n\nfunction isLgWebOS(): boolean {\n  if (typeof navigator === \"undefined\") return false;\n  return /Web0S|webOS|LG Browser|LGSTB|LGE/i.test(navigator.userAgent);\n}\n\nfunction getDefaultAppId(): string {\n  if (typeof navigator === \"undefined\") return AIRY_ANDROID_APP_ID;\n  const ua = navigator.userAgent;\n  if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;\n  if (/Tizen|Samsung/i.test(ua))                       return AIRY_TIZEN_APP_ID;\n  if (/Roku/i.test(ua))                                return AIRY_ROKU_APP_ID;\n  return AIRY_ANDROID_APP_ID;\n}\n\nconst DEVICE_ID_STORAGE_KEYS = [\n  \"rdid\",\n  \"ifa\",\n  \"advertisingId\",\n  \"advertising_id\",\n  \"deviceAdvertisingId\",\n  \"aaid\",\n  \"adid\",\n  \"rida\",\n  \"tifa\",\n  \"lgudid\",\n];\n\nconst ANDROID_ID_TYPES = new Set([\"aaid\", \"adid\"]);\n\nexport function resolveVastEnvironmentSignals(isCtv: boolean): VastEnvironmentSignals {\n  const bridgeSignals  = readNativeBridgeSignals();\n  const platformDevice = readPlatformNativeDeviceId();\n  const lg = isCtv && isLgWebOS();\n\n  const deviceId =\n    bridgeSignals.deviceId  ||\n    readStoredDeviceId()    ||\n    platformDevice.deviceId ||\n    (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : undefined);\n  const deviceIdType =\n    bridgeSignals.deviceIdType  ||\n    readStoredString(\"deviceIdType\") ||\n    readStoredString(\"idtype\") ||\n    platformDevice.deviceIdType ||\n    inferDeviceIdType() ||\n    (lg ? \"lgudid\" : undefined);\n  const platformLat = bridgeSignals.deviceId\n    ? bridgeSignals.limitAdTracking\n    : platformDevice.limitAdTracking;\n  const limitAdTracking =\n    deviceId != null\n      ? platformLat ?? readStoredLimitAdTracking() ?? false\n      : undefined;\n\n  if (isCtv) {\n    return {\n      isCtv: true,\n      contentUrl:\n        bridgeSignals.contentUrl ||\n        readStoredString(\"contentUrl\") ||\n        (lg ? LG_TEST_CONTENT_URL : AIRY_DEFAULT_CONTENT_URL),\n      appId:\n        bridgeSignals.appId ||\n        readStoredString(\"appId\") ||\n        readStoredString(\"msid\") ||\n        (lg ? LG_TEST_APP_ID : getDefaultAppId()),\n      appName:\n        bridgeSignals.appName ||\n        readStoredString(\"appName\") ||\n        readStoredString(\"an\") ||\n        (lg ? LG_TEST_APP_NAME : AIRY_APP_NAME),\n      sessionId: getOrCreateCtvSessionId(),\n      ...(deviceId ? { deviceId } : {}),\n      ...(deviceIdType ? { deviceIdType } : {}),\n      ...(limitAdTracking != null ? { limitAdTracking } : {}),\n      deviceTypeHint: 5,\n    };\n  }\n\n  return {\n    isCtv: false,\n    ...(deviceId ? { deviceId } : {}),\n    ...(deviceIdType ? { deviceIdType } : {}),\n    ...(limitAdTracking != null ? { limitAdTracking } : {}),\n  };\n}\n\nexport function inferDeviceIdType(): string | undefined {\n  if (typeof navigator === \"undefined\") {\n    return undefined;\n  }\n\n  const ua = navigator.userAgent;\n  if (/Roku/i.test(ua)) return \"rida\";\n  if (/Tizen|Samsung/i.test(ua)) return \"tifa\";\n  if (/AppleTV|Apple TV/i.test(ua)) return \"tvOS\";\n  if (/AFT|Fire TV|Amazon/i.test(ua)) return \"afai\";\n  if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return \"lgudid\";\n  if (/Android|Google TV/i.test(ua)) return \"aaid\";\n  if (/iPhone|iPad|iPod/i.test(ua)) return \"idfa\";\n  return undefined;\n}\n\nexport function isEquivalentDeviceIdType(\n  tagType: string | undefined,\n  runtimeType: string | undefined\n): boolean {\n  if (!tagType || !runtimeType) return false;\n  const tag = tagType.toLowerCase();\n  const runtime = runtimeType.toLowerCase();\n  if (tag === runtime) return true;\n  return ANDROID_ID_TYPES.has(tag) && ANDROID_ID_TYPES.has(runtime);\n}\n\nexport function resolveNativeDeviceId(): string | undefined {\n  const bridgeSignals = readNativeBridgeSignals();\n  const platformDevice = readPlatformNativeDeviceId();\n  const deviceId =\n    bridgeSignals.deviceId ||\n    readStoredDeviceId() ||\n    platformDevice.deviceId;\n\n  if (!deviceId || isMacroPlaceholder(deviceId) || isZeroedAdId(deviceId)) {\n    return undefined;\n  }\n\n  return deviceId;\n}\n\nexport function getOrCreateStoredUuid(storageKey: string): string | undefined {\n  if (typeof window === \"undefined\") {\n    return undefined;\n  }\n\n  const existing = readPersistentId(storageKey);\n  if (existing) {\n    writePersistentId(storageKey, existing);\n    return existing;\n  }\n\n  const id = createUuid();\n  writePersistentId(storageKey, id);\n  return id;\n}\n\nfunction getOrCreateCtvSessionId(): string {\n  const existing = readPersistentId(CTV_SESSION_STORAGE_KEY);\n  if (existing) {\n    writePersistentId(CTV_SESSION_STORAGE_KEY, existing);\n    return existing;\n  }\n\n  const sessionId = createUuid();\n  writePersistentId(CTV_SESSION_STORAGE_KEY, sessionId);\n  return sessionId;\n}\n\nfunction readPersistentId(storageKey: string): string | undefined {\n  return readStoredString(storageKey) || readCookie(storageKey);\n}\n\nfunction writePersistentId(storageKey: string, value: string): void {\n  try {\n    window.localStorage?.setItem(storageKey, value);\n  } catch {}\n  writeCookie(storageKey, value);\n}\n\nconst PERSISTENT_ID_COOKIE_MAX_AGE = 60 * 60 * 24 * 365 * 5; // ~5 years\n\nfunction readCookie(name: string): string | undefined {\n  if (typeof document === \"undefined\") {\n    return undefined;\n  }\n\n  try {\n    const prefix = encodeURIComponent(name) + \"=\";\n    const parts = document.cookie ? document.cookie.split(\";\") : [];\n    for (const part of parts) {\n      const entry = part.trim();\n      if (entry.startsWith(prefix)) {\n        return decodeURIComponent(entry.slice(prefix.length)) || undefined;\n      }\n    }\n  } catch {}\n\n  return undefined;\n}\n\nfunction writeCookie(name: string, value: string): void {\n  if (typeof document === \"undefined\") {\n    return;\n  }\n\n  try {\n    document.cookie =\n      encodeURIComponent(name) +\n      \"=\" +\n      encodeURIComponent(value) +\n      \";path=/;max-age=\" +\n      PERSISTENT_ID_COOKIE_MAX_AGE +\n      \";SameSite=Lax\";\n  } catch {}\n}\n\nfunction createUuid(): string {\n  if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n    return crypto.randomUUID();\n  }\n\n  const bytes = new Uint8Array(16);\n  if (typeof crypto !== \"undefined\" && typeof crypto.getRandomValues === \"function\") {\n    crypto.getRandomValues(bytes);\n  } else {\n    let seed = Date.now() ^ Math.floor(performanceNow() * 1e3);\n    for (let i = 0; i < 16; i++) {\n      seed = (seed * 1103515245 + 12345) & 0x7fffffff;\n      bytes[i] = (seed ^ Math.floor(Math.random() * 256)) & 0xff;\n    }\n  }\n\n  bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;\n  bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;\n\n  let hex = \"\";\n  for (let i = 0; i < 16; i++) {\n    hex += (bytes[i] ?? 0).toString(16).padStart(2, \"0\");\n  }\n\n  return (\n    hex.slice(0, 8) +\n    \"-\" +\n    hex.slice(8, 12) +\n    \"-\" +\n    hex.slice(12, 16) +\n    \"-\" +\n    hex.slice(16, 20) +\n    \"-\" +\n    hex.slice(20, 32)\n  );\n}\n\nfunction performanceNow(): number {\n  try {\n    if (typeof performance !== \"undefined\" && typeof performance.now === \"function\") {\n      return performance.now();\n    }\n  } catch {}\n  return 0;\n}\n\nfunction readPlatformNativeDeviceId(): {\n  deviceId?: string;\n  deviceIdType?: string;\n  limitAdTracking?: boolean;\n} {\n  if (typeof window === \"undefined\") return {};\n\n  try {\n    const adinfo = (window as any).webapis?.adinfo;\n    if (adinfo) {\n      const tifa: unknown =\n        typeof adinfo.getTIFA === \"function\" ? adinfo.getTIFA() : adinfo.tifa;\n      if (typeof tifa === \"string\" && tifa && !isMacroPlaceholder(tifa)) {\n        const lat: unknown =\n          typeof adinfo.isLATEnabled === \"function\"\n            ? adinfo.isLATEnabled()\n            : undefined;\n        return {\n          deviceId: tifa,\n          deviceIdType: \"tifa\",\n          ...(typeof lat === \"boolean\" ? { limitAdTracking: lat } : {}),\n        };\n      }\n    }\n  } catch {}\n\n  try {\n    const webOSDev = (window as any).webOSDev;\n    if (webOSDev) {\n      const lgudid: unknown =\n        typeof webOSDev.LGUDID === \"function\"\n          ? webOSDev.LGUDID()\n          : webOSDev.lgudid ?? webOSDev.LGUDID;\n      if (typeof lgudid === \"string\" && lgudid) {\n        if (isZeroedAdId(lgudid)) {\n          return { deviceIdType: \"lgudid\", limitAdTracking: true };\n        }\n        if (!isMacroPlaceholder(lgudid)) {\n          return { deviceId: lgudid, deviceIdType: \"lgudid\", limitAdTracking: false };\n        }\n      }\n    }\n  } catch {}\n\n  try {\n    const roku = (window as any).Roku;\n    if (roku) {\n      const rida: unknown =\n        typeof roku.getPublisherUniqueId === \"function\"\n          ? roku.getPublisherUniqueId()\n          : roku.rida;\n      if (typeof rida === \"string\" && rida && !isMacroPlaceholder(rida)) {\n        return { deviceId: rida, deviceIdType: \"rida\", limitAdTracking: false };\n      }\n    }\n  } catch {}\n\n  return {};\n}\n\nconst ZEROED_AD_ID_PATTERNS: ReadonlySet<string> = new Set([\n  \"38400000-8cf0-11bd-b23e-10b96e40000d\",\n  \"00000000-0000-0000-0000-000000000000\",\n]);\n\nfunction isMacroPlaceholder(value: string): boolean {\n  const t = value.trim();\n  return !t ||\n    /^(\\[[^\\]]*\\]|\\{[^}]*\\}|%%[^%]*%%)$/.test(t) ||\n    /^(unknown|null|undefined|none|n\\/a|\\$\\{[^}]+\\})$/i.test(t) ||\n    ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());\n}\n\nfunction isZeroedAdId(value: string): boolean {\n  return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());\n}\n\nfunction readNativeBridgeSignals(): {\n  contentUrl?: string;\n  appId?: string;\n  appName?: string;\n  deviceId?: string;\n  deviceIdType?: string;\n  limitAdTracking?: boolean;\n} {\n  if (typeof window === \"undefined\") {\n    return {};\n  }\n\n  const candidates = [\n    (window as any).__STORMCLOUD_CTV_AD_INFO__,\n    (window as any).__STORMCLOUD_CTV__,\n    (window as any).stormcloudCtv,\n    (window as any).AiryTV,\n    (window as any).Android,\n    (window as any).webOS,\n    (window as any).tizen,\n    (window as any).amazon,\n  ].filter(Boolean);\n\n  for (const source of candidates) {\n    const contentUrl =\n      readBridgeValue(source, [\"contentUrl\", \"url\", \"videoUrl\", \"canonicalUrl\"]) ||\n      undefined;\n    const appId =\n      readBridgeValue(source, [\"appId\", \"msid\", \"applicationId\", \"packageName\"]) ||\n      undefined;\n    const appName =\n      readBridgeValue(source, [\"appName\", \"an\", \"applicationName\"]) || undefined;\n    const deviceId =\n      readBridgeValue(source, [\n        \"rdid\",\n        \"ifa\",\n        \"advertisingId\",\n        \"adId\",\n        \"deviceId\",\n        \"lgudid\",\n        \"LGUDID\",\n        \"tifa\",\n        \"rida\",\n        \"afai\",\n        \"aaid\",\n      ]) || undefined;\n\n    if (!contentUrl && !deviceId && !appId && !appName) continue;\n\n    const deviceIdType =\n      readBridgeValue(source, [\n        \"idtype\",\n        \"deviceIdType\",\n        \"advertisingIdType\",\n        \"idType\",\n      ]) || inferDeviceIdType();\n    const limitAdTracking = readBridgeBoolean(source, [\n      \"is_lat\",\n      \"limitAdTracking\",\n      \"limitedAdTracking\",\n      \"lat\",\n    ]);\n\n    return {\n      ...(contentUrl ? { contentUrl } : {}),\n      ...(appId ? { appId } : {}),\n      ...(appName ? { appName } : {}),\n      ...(deviceId ? { deviceId } : {}),\n      ...(deviceId && deviceIdType ? { deviceIdType } : {}),\n      ...(deviceId && limitAdTracking != null ? { limitAdTracking } : {}),\n    };\n  }\n\n  return {};\n}\n\nfunction readBridgeValue(source: any, keys: string[]): string | undefined {\n  for (const key of keys) {\n    const value = source?.[key];\n    if (typeof value === \"string\" && value) {\n      return value;\n    }\n    if (typeof value === \"function\") {\n      try {\n        const result = value.call(source);\n        if (typeof result === \"string\" && result) {\n          return result;\n        }\n      } catch {}\n    }\n  }\n  return undefined;\n}\n\nfunction readBridgeBoolean(source: any, keys: string[]): boolean | undefined {\n  for (const key of keys) {\n    const value = source?.[key];\n    const normalized = normalizeBoolean(value);\n    if (normalized != null) {\n      return normalized;\n    }\n    if (typeof value === \"function\") {\n      try {\n        const result = normalizeBoolean(value.call(source));\n        if (result != null) {\n          return result;\n        }\n      } catch {}\n    }\n  }\n  return undefined;\n}\n\nfunction readStoredDeviceId(): string | undefined {\n  for (const key of DEVICE_ID_STORAGE_KEYS) {\n    const value = readStoredString(key);\n    if (value) {\n      return value;\n    }\n  }\n  return undefined;\n}\n\nfunction readStoredString(key: string): string | undefined {\n  if (typeof window === \"undefined\") {\n    return undefined;\n  }\n\n  try {\n    const value = window.localStorage?.getItem(key);\n    return value || undefined;\n  } catch {\n    return undefined;\n  }\n}\n\nfunction readStoredLimitAdTracking(): boolean | undefined {\n  return normalizeBoolean(\n    readStoredString(\"limitAdTracking\") ||\n      readStoredString(\"limitedAdTracking\") ||\n      readStoredString(\"is_lat\")\n  );\n}\n\nfunction normalizeBoolean(value: unknown): boolean | undefined {\n  if (typeof value === \"boolean\") {\n    return value;\n  }\n  if (typeof value === \"number\") {\n    return value === 1;\n  }\n  if (typeof value === \"string\") {\n    const normalized = value.toLowerCase();\n    if (normalized === \"1\" || normalized === \"true\" || normalized === \"yes\") {\n      return true;\n    }\n    if (normalized === \"0\" || normalized === \"false\" || normalized === \"no\") {\n      return false;\n    }\n  }\n  return undefined;\n}\n","import type {\n  ClientInfo,\n  AdDetectInfo,\n  AdLoadedInfo,\n  AdImpressionInfo,\n  PlayerAnalyticsContext,\n  StormcloudVideoPlayerConfig,\n} from \"../types\";\n\nimport { buildPlayerTopic, isMQTTEnabled } from \"./mqttConfig\";\nimport { ensureMQTTClient, publishMQTT } from \"./mqttClient\";\nimport {\n  getOrCreateStoredUuid,\n  PLAYER_ID_STORAGE_KEY,\n  resolveNativeDeviceId,\n} from \"./vastEnvironmentSignals\";\n\nlet cachedBrowserId: string | null = null;\n\nexport function buildAnalyticsContext(\n  config: Pick<StormcloudVideoPlayerConfig, \"debugAdTiming\" | \"isLiveStream\">\n): PlayerAnalyticsContext {\n  const context: PlayerAnalyticsContext = {};\n  if (config.debugAdTiming) {\n    context.debugAdTiming = true;\n  }\n  if (config.isLiveStream !== undefined) {\n    context.inputStreamType = config.isLiveStream ? \"live\" : \"vod\";\n  }\n  return context;\n}\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\nasync function sha256Hex(input: string): Promise<string> {\n  if (typeof crypto !== \"undefined\" && 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(input);\n      } else {\n        const utf8 = unescape(encodeURIComponent(input));\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      return Array.from(new Uint8Array(hashBuffer))\n        .map((b) => b.toString(16).padStart(2, \"0\"))\n        .join(\"\");\n    } catch {\n      console.warn(\n        \"[StormcloudVideoPlayer] crypto.subtle not supported, using fallback hash\"\n      );\n    }\n  }\n\n  let hash = 0;\n  for (let i = 0; i < input.length; i++) {\n    const char = input.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  return (fallbackHash + timestamp + random).padEnd(64, \"0\");\n}\n\nfunction resolvePlayerIdentitySeed(clientInfo: ClientInfo): string {\n  const nativeDeviceId = resolveNativeDeviceId();\n  if (nativeDeviceId) {\n    return `device:${nativeDeviceId}`;\n  }\n\n  const persistedId = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);\n  if (persistedId) {\n    return `persisted:${persistedId}`;\n  }\n\n  return `fingerprint:${JSON.stringify(clientInfo)}`;\n}\n\nexport async function getBrowserID(clientInfo: ClientInfo): Promise<string> {\n  if (cachedBrowserId) {\n    return cachedBrowserId;\n  }\n\n  cachedBrowserId = await sha256Hex(resolvePlayerIdentitySeed(clientInfo));\n  return cachedBrowserId;\n}\n\ntype PlayerMetricFlags = {\n  adLoaded?: boolean;\n  adDetect?: boolean;\n  captureAt?: string;\n};\n\nfunction canPublish(licenseKey: string | undefined): licenseKey is string {\n  return Boolean(isMQTTEnabled() && licenseKey);\n}\n\nasync function buildPlayerMetricEvent(\n  context: PlayerAnalyticsContext = {},\n  flags: PlayerMetricFlags = {}\n): Promise<Record<string, unknown>> {\n  const clientInfo = getClientInfo();\n\n  const debugAdTiming = !!context.debugAdTiming;\n  if (debugAdTiming) {\n    console.log(\"[StormcloudVideoPlayer] clientInfo: \", JSON.stringify(clientInfo, null, 2));\n  }\n\n  const playerId = await getBrowserID(clientInfo);\n\n  if (debugAdTiming) {\n    console.log(\"[StormcloudVideoPlayer] playerId: \", playerId);\n  }\n\n  const captureAt = flags.captureAt ?? new Date().toISOString();\n\n  return {\n    player_id: playerId,\n    device_type: clientInfo.deviceType,\n    os: clientInfo.os.toLowerCase(),\n    ad_loaded: flags.adLoaded ?? false,\n    ad_detect: flags.adDetect ?? false,\n    capture_at: captureAt,\n    ...(context.inputStreamType\n      ? { input_stream_type: context.inputStreamType }\n      : {}),\n  };\n}\n\nfunction publishTracking(\n  licenseKey: string,\n  channel: \"metrics\" | \"impressions\" | \"heartbeat\",\n  body: Record<string, unknown>\n): void {\n  ensureMQTTClient();\n  publishMQTT(buildPlayerTopic(licenseKey, channel), body);\n}\n\nexport async function sendInitialTracking(\n  licenseKey?: string,\n  context: PlayerAnalyticsContext = {}\n): Promise<void> {\n  if (!canPublish(licenseKey)) return;\n\n  try {\n    const metricEvent = await buildPlayerMetricEvent(context, {\n      adLoaded: false,\n      adDetect: false,\n    });\n\n    publishTracking(licenseKey, \"metrics\", {\n      events: [metricEvent],\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n      error\n    );\n  }\n}\n\nexport async function sendAdDetectTracking(\n  licenseKey: string | undefined,\n  adDetectInfo: AdDetectInfo,\n  context: PlayerAnalyticsContext = {}\n): Promise<void> {\n  try {\n    await sendHeartbeat(licenseKey, context, {\n      adDetect: true,\n      captureAt: adDetectInfo.timestamp,\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n      error\n    );\n  }\n}\n\nexport async function sendAdLoadedTracking(\n  licenseKey: string | undefined,\n  adLoadedInfo: AdLoadedInfo,\n  context: PlayerAnalyticsContext = {}\n): Promise<void> {\n  try {\n    await sendHeartbeat(licenseKey, context, {\n      adLoaded: true,\n      captureAt: adLoadedInfo.timestamp,\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n      error\n    );\n  }\n}\n\nexport async function sendAdImpressionTracking(\n  licenseKey: string | undefined,\n  adImpressionInfo: AdImpressionInfo,\n  context: PlayerAnalyticsContext = {}\n): Promise<void> {\n  if (!canPublish(licenseKey)) return;\n\n  try {\n    const metricEvent = await buildPlayerMetricEvent(context, {\n      captureAt: adImpressionInfo.timestamp,\n    });\n\n    publishTracking(licenseKey, \"heartbeat\", metricEvent);\n    publishTracking(licenseKey, \"impressions\", {\n      events: [\n        {\n          player_id: metricEvent.player_id,\n          ad_played_count: 1,\n          ad_url: adImpressionInfo.adUrl,\n          capture_at: adImpressionInfo.timestamp,\n        },\n      ],\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n      error\n    );\n  }\n}\n\nexport async function sendHeartbeat(\n  licenseKey?: string,\n  context: PlayerAnalyticsContext = {},\n  flags: PlayerMetricFlags = {}\n): Promise<void> {\n  if (!canPublish(licenseKey)) return;\n\n  try {\n    const heartbeatData = await buildPlayerMetricEvent(context, flags);\n    publishTracking(licenseKey, \"heartbeat\", heartbeatData);\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","import {\n  inferDeviceIdType,\n  isEquivalentDeviceIdType,\n} from \"./vastEnvironmentSignals\";\n\nexport interface VastConsentSignals {\n  gdpr?: string | undefined;\n  gdprConsent?: string | undefined;\n  usPrivacy?: string | undefined;\n}\n\nexport interface VastMacroContext {\n  correlator: string;\n  streamCorrelator: string;\n  pod?: number | undefined;\n  adPosition?: number | undefined;\n  podMaxAds?: number | undefined;\n  podMinDurationMs?: number | undefined;\n  podMaxDurationMs?: number | undefined;\n  isCtv?: boolean | undefined;\n  contentUrl?: string | undefined;\n  pageUrl?: string | undefined;\n  adWillPlayMuted?: boolean | undefined;\n  adWillAutoPlay?: boolean | undefined;\n  appId?: string | undefined;\n  appName?: string | undefined;\n  sessionId?: string | undefined;\n  deviceId?: string | undefined;\n  deviceIdType?: string | undefined;\n  limitAdTracking?: boolean | undefined;\n  deviceTypeHint?: number | undefined;\n  adTest?: boolean | undefined;\n  consent?: VastConsentSignals | undefined;\n}\n\nconst UNEXPANDED_MACRO_PATTERN = /^(\\[[^\\]]*\\]|\\{[^}]*\\}|%%[^%]*%%)$/;\nconst INVALID_VAST_PARAM_KEY = /^\\s|\\s$/;\nconst EXAMPLE_COM_URL = /example\\.com/i;\nconst CTV_UNSUPPORTED_PARAMS = [\n  \"description_url\",\n  \"tfcd\",\n  \"npa\",\n  \"min_ad_duration\",\n  \"max_ad_duration\",\n  \"unviewed_position_start\",\n  \"impl\",\n  \"vad_type\",\n  \"gdpr\",\n  \"gdpr_consent\",\n  \"us_privacy\",\n];\n\nconst INLINE_DEVICE_MACRO_REPLACEMENTS: Array<{\n  pattern: RegExp;\n  getValue: (ctx: VastMacroContext) => string | undefined;\n}> = [\n  { pattern: /\\[RDID\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[IFA\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[ADVERTISING[_-]?ID(?:ENTIFIER)?\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[DEVICE[_-]?ID\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[IDTYPE\\]/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /\\{rdid\\}/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\{device[_-]?id\\}/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\{idtype\\}/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /%%ADVERTISING_IDENTIFIER_PLAIN%%/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /%%ADVERTISING_ID_OPT_OUT%%/gi, getValue: (ctx) =>\n      ctx.limitAdTracking != null ? (ctx.limitAdTracking ? \"1\" : \"0\") : undefined },\n  { pattern: /%%ADVERTISING_ID_TYPE%%/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /%%ADVERTISING_ID%%/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /%%LIMIT_AD_TRACKING%%/gi, getValue: (ctx) =>\n      ctx.limitAdTracking != null ? (ctx.limitAdTracking ? \"1\" : \"0\") : undefined },\n  { pattern: /%%MSID%%/gi, getValue: (ctx) => ctx.appId },\n  { pattern: /%%APP_NAME%%/gi, getValue: (ctx) => ctx.appName },\n  { pattern: /%%SESSION_ID%%/gi, getValue: (ctx) => ctx.sessionId },\n  { pattern: /%%CORRELATOR%%/gi, getValue: (ctx) => ctx.correlator },\n];\n\nexport function isMacroPlaceholder(value: string | null | undefined): boolean {\n  if (value == null) return true;\n  const trimmed = value.trim();\n  if (!trimmed) return true;\n  if (UNEXPANDED_MACRO_PATTERN.test(trimmed)) return true;\n  return /^(unknown|null|undefined|none|n\\/a|\\$\\{[^}]+\\})$/i.test(trimmed);\n}\n\nexport function generateCorrelator(): string {\n  if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n    try {\n      const buf = new Uint32Array(2);\n      crypto.getRandomValues(buf);\n      const value = (buf[0] ?? 0) * 0x200000 + ((buf[1] ?? 0) & 0x1fffff);\n      if (value > 0) {\n        return String(value);\n      }\n    } catch {\n    }\n  }\n  return String(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER) + 1);\n}\n\nfunction expandInlineMacroPlaceholders(baseUrl: string, ctx: VastMacroContext): string {\n  let url = baseUrl;\n  for (const { pattern, getValue } of INLINE_DEVICE_MACRO_REPLACEMENTS) {\n    const value = getValue(ctx);\n    if (value != null && value !== \"\") {\n      url = url.replace(pattern, encodeURIComponent(value));\n    }\n  }\n  return url;\n}\n\nfunction applyDeviceIdentityParams(\n  params: URLSearchParams,\n  ctx: VastMacroContext\n): void {\n  const runtimeId = ctx.deviceId?.trim();\n  const runtimeType = ctx.deviceIdType?.trim() || inferDeviceIdType();\n  const tagRdid = params.get(\"rdid\");\n  const tagType = params.get(\"idtype\");\n  const tagLat = params.get(\"is_lat\");\n  const latValue =\n    ctx.limitAdTracking != null ? (ctx.limitAdTracking ? \"1\" : \"0\") : undefined;\n\n  if (runtimeId) {\n    params.set(\"rdid\", runtimeId);\n    params.set(\"idtype\", runtimeType || tagType || \"aaid\");\n    params.set(\"is_lat\", latValue ?? (isMacroPlaceholder(tagLat) ? \"0\" : tagLat!));\n    return;\n  }\n\n  const tagRdidValid = Boolean(tagRdid && !isMacroPlaceholder(tagRdid));\n  const tagTypeValid = Boolean(tagType && !isMacroPlaceholder(tagType));\n\n  if (\n    tagRdidValid &&\n    tagTypeValid &&\n    runtimeType &&\n    !isEquivalentDeviceIdType(tagType!, runtimeType)\n  ) {\n    params.delete(\"rdid\");\n    params.delete(\"idtype\");\n    params.delete(\"is_lat\");\n    return;\n  }\n\n  if (tagRdidValid) {\n    if (isMacroPlaceholder(tagType) && runtimeType) {\n      params.set(\"idtype\", runtimeType);\n    }\n    if (isMacroPlaceholder(tagLat)) {\n      params.set(\"is_lat\", latValue ?? \"0\");\n    }\n    return;\n  }\n\n  params.delete(\"rdid\");\n  params.delete(\"idtype\");\n  params.delete(\"is_lat\");\n}\n\nfunction removeBrokenAppNameOrphans(\n  params: URLSearchParams,\n  appName?: string\n): void {\n  const toDelete: string[] = [];\n\n  params.forEach((_value, key) => {\n    if (!key || INVALID_VAST_PARAM_KEY.test(key)) {\n      toDelete.push(key);\n    }\n  });\n\n  if (appName && appName.includes(\"&\")) {\n    for (const suffix of appName.split(\"&\").slice(1)) {\n      const trimmed = suffix.trimStart();\n      if (!trimmed) continue;\n      toDelete.push(suffix, ` ${trimmed}`, trimmed);\n    }\n  }\n\n  for (const key of new Set(toDelete)) {\n    if (key) params.delete(key);\n  }\n}\n\nexport function normalizeVastTagUrl(raw: string): string {\n  if (!raw) return raw;\n\n  try {\n    const url = new URL(raw);\n\n    const anValue = url.searchParams.get(\"an\");\n    if (anValue !== null) {\n      const orphanFragments: string[] = [];\n      url.searchParams.forEach((_value, key) => {\n        if (key && INVALID_VAST_PARAM_KEY.test(key)) {\n          orphanFragments.push(key.trim());\n        }\n      });\n      if (orphanFragments.length > 0) {\n        const reconstructed = [anValue.trimEnd(), ...orphanFragments]\n          .filter(Boolean)\n          .join(\" & \");\n\n        url.searchParams.forEach((_value, key) => {\n          if (key && INVALID_VAST_PARAM_KEY.test(key)) {\n            url.searchParams.delete(key);\n          }\n        });\n        url.searchParams.set(\"an\", reconstructed);\n\n        return url.toString().replace(\n          /([?&]an=)([^&]*)/,\n          (_match, prefix, val) => prefix + val.replace(/\\+/g, \"%20\")\n        );\n      }\n    }\n\n    removeBrokenAppNameOrphans(url.searchParams);\n    return url.toString();\n  } catch {\n    return raw;\n  }\n}\n\nexport function applyVastMacros(\n  baseUrl: string,\n  ctx: VastMacroContext\n): string {\n  const expandedUrl = expandInlineMacroPlaceholders(baseUrl, ctx);\n  let url: URL;\n  try {\n    url = new URL(normalizeVastTagUrl(expandedUrl));\n  } catch {\n    return replaceCorrelatorFallback(expandedUrl, ctx.correlator);\n  }\n\n  const params = url.searchParams;\n\n  removeBrokenAppNameOrphans(params, ctx.appName);\n\n  params.set(\"correlator\", ctx.correlator);\n  params.set(\"scor\", ctx.streamCorrelator);\n  if (ctx.isCtv) {\n    for (const key of CTV_UNSUPPORTED_PARAMS) {\n      params.delete(key);\n    }\n  }\n\n  if (ctx.pod != null) {\n    params.set(\"pod\", String(ctx.pod));\n  }\n\n  const optimizedPodMode =\n    ctx.podMaxAds != null ||\n    ctx.podMinDurationMs != null ||\n    ctx.podMaxDurationMs != null;\n\n  if (optimizedPodMode) {\n    params.delete(\"ppos\");\n    params.delete(\"lip\");\n    if (ctx.podMinDurationMs != null) {\n      params.set(\"pmnd\", String(Math.max(0, Math.round(ctx.podMinDurationMs))));\n    }\n    if (ctx.podMaxDurationMs != null) {\n      params.set(\"pmxd\", String(Math.max(0, Math.round(ctx.podMaxDurationMs))));\n    }\n    if (ctx.podMaxAds != null) {\n      params.set(\"pmad\", String(Math.max(1, Math.round(ctx.podMaxAds))));\n    }\n  } else if (ctx.adPosition != null) {\n    params.set(\"ppos\", String(ctx.adPosition));\n  }\n\n  const requestUrl = ctx.contentUrl || ctx.pageUrl;\n  if (requestUrl) {\n    params.set(\"url\", requestUrl);\n    if (!ctx.isCtv) {\n      params.set(\"description_url\", requestUrl);\n    }\n  } else {\n    const existingUrl = params.get(\"url\") || \"\";\n    if (EXAMPLE_COM_URL.test(existingUrl)) {\n      params.delete(\"url\");\n      params.delete(\"description_url\");\n    }\n  }\n\n  if (ctx.adWillPlayMuted != null) {\n    params.set(\"vpmute\", ctx.adWillPlayMuted ? \"1\" : \"0\");\n  }\n  if (ctx.adWillAutoPlay != null) {\n    params.set(\"vpa\", ctx.adWillAutoPlay ? \"auto\" : \"click\");\n  }\n\n  if (ctx.appId) {\n    params.set(\"msid\", ctx.appId);\n  }\n  if (ctx.appName) {\n    removeBrokenAppNameOrphans(params, ctx.appName);\n    params.set(\"an\", ctx.appName);\n  }\n  if (ctx.sessionId) {\n    params.set(\"sid\", ctx.sessionId);\n  }\n  if (ctx.deviceTypeHint != null) {\n    params.set(\"dth\", String(ctx.deviceTypeHint));\n  } else if (ctx.isCtv) {\n    params.set(\"dth\", \"5\");\n  }\n\n  applyDeviceIdentityParams(params, ctx);\n\n  if (!ctx.isCtv) {\n    const consent = ctx.consent;\n    if (consent?.gdpr != null) {\n      params.set(\"gdpr\", consent.gdpr);\n    }\n    if (consent?.gdprConsent != null) {\n      params.set(\"gdpr_consent\", consent.gdprConsent);\n    }\n    if (consent?.usPrivacy != null) {\n      params.set(\"us_privacy\", consent.usPrivacy);\n    }\n  }\n\n  if (ctx.adTest) {\n    params.set(\"adtest\", \"on\");\n  }\n\n  const staleKeys: string[] = [];\n  params.forEach((value, key) => {\n    if (isMacroPlaceholder(value)) {\n      staleKeys.push(key);\n    }\n  });\n  for (const key of staleKeys) {\n    params.delete(key);\n  }\n\n  removeBrokenAppNameOrphans(params, ctx.appName);\n\n  return url.toString();\n}\n\nfunction replaceCorrelatorFallback(baseUrl: string, correlator: string): string {\n  const correlatorRegex = /([?&])correlator=([^&]*)/;\n  if (correlatorRegex.test(baseUrl)) {\n    return baseUrl.replace(correlatorRegex, `$1correlator=${correlator}`);\n  }\n  const sep = baseUrl.includes(\"?\") ? \"&\" : \"?\";\n  return `${baseUrl}${sep}correlator=${correlator}`;\n}\n\nexport function fetchConsentSignals(\n  timeoutMs: number = 1500\n): Promise<VastConsentSignals> {\n  const signals: VastConsentSignals = {};\n  if (typeof window === \"undefined\") {\n    return Promise.resolve(signals);\n  }\n\n  const tasks: Promise<void>[] = [];\n\n  const tcfApi = (window as any).__tcfapi;\n  if (typeof tcfApi === \"function\") {\n    tasks.push(\n      new Promise<void>((resolve) => {\n        let settled = false;\n        try {\n          tcfApi(\"addEventListener\", 2, (tcData: any, success: boolean) => {\n            if (settled) return;\n            if (\n              success &&\n              tcData &&\n              (tcData.eventStatus === \"tcloaded\" ||\n                tcData.eventStatus === \"useractioncomplete\")\n            ) {\n              settled = true;\n              signals.gdpr = tcData.gdprApplies ? \"1\" : \"0\";\n              if (typeof tcData.tcString === \"string\" && tcData.tcString) {\n                signals.gdprConsent = tcData.tcString;\n              }\n              try {\n                tcfApi(\"removeEventListener\", 2, () => {}, tcData.listenerId);\n              } catch {}\n              resolve();\n            }\n          });\n        } catch {\n          resolve();\n        }\n        setTimeout(() => {\n          if (!settled) {\n            settled = true;\n            resolve();\n          }\n        }, timeoutMs);\n      })\n    );\n  }\n\n  const uspApi = (window as any).__uspapi;\n  if (typeof uspApi === \"function\") {\n    tasks.push(\n      new Promise<void>((resolve) => {\n        try {\n          uspApi(\"getUSPData\", 1, (data: any, success: boolean) => {\n            if (success && typeof data?.uspString === \"string\" && data.uspString) {\n              signals.usPrivacy = data.uspString;\n            }\n            resolve();\n          });\n        } catch {\n          resolve();\n        }\n        setTimeout(resolve, timeoutMs);\n      })\n    );\n  }\n\n  if (tasks.length === 0) {\n    return Promise.resolve(signals);\n  }\n\n  return Promise.all(tasks).then(() => signals);\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  webOSVersion?: number | undefined;\n  tizenVersion?: number | undefined;\n  chromeVersion?: number | undefined;\n}\n\nfunction getChromeVersion(ua: string): number {\n  const match = ua.match(/Chrome\\/(\\d+)/);\n  return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getWebKitVersion(ua: string): number {\n  const match = ua.match(/AppleWebKit\\/(\\d+)/);\n  return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getPlatform(): string {\n  if ('userAgentData' in navigator && navigator.userAgentData?.platform) {\n    return navigator.userAgentData.platform;\n  }\n\n  const ua = navigator.userAgent;\n  if (/Mac|iPhone|iPad|iPod/i.test(ua)) {\n    return /iPhone|iPad|iPod/i.test(ua) ? 'iPhone' : 'MacIntel';\n  }\n  if (/Win/i.test(ua)) {\n    return 'Win32';\n  }\n  if (/Linux/i.test(ua)) {\n    return /Android/i.test(ua) ? 'Linux armv8l' : 'Linux x86_64';\n  }\n  if (/CrOS/i.test(ua)) {\n    return 'CrOS';\n  }\n\n  // eslint-disable-next-line deprecation/deprecation\n  return (navigator as any).platform || 'Unknown';\n}\n\nexport function detectBrowser(): BrowserInfo {\n  const ua = navigator.userAgent;\n  const platform = getPlatform();\n\n  let name = 'Unknown';\n  let version = '0';\n  let majorVersion = 0;\n  let isSmartTV = false;\n  let isLegacyTV = false;\n  let supportsModernJS = true;\n  let webOSVersion: number | undefined;\n  let tizenVersion: number | undefined;\n  let chromeVersionNum: number | undefined;\n\n  const chromeVersion = getChromeVersion(ua);\n  const webkitVersion = getWebKitVersion(ua);\n  chromeVersionNum = chromeVersion > 0 ? chromeVersion : undefined;\n\n  if (/Web0S|webOS|LG Browser|LGSTB/i.test(ua)) {\n    name = 'LG WebOS';\n    isSmartTV = true;\n\n    let match = ua.match(/Web0S[/\\s]*([\\d.]+)/i) || ua.match(/webOS[/\\s]*([\\d.]+)/i);\n\n    if (!match || !match[1]) {\n      match = ua.match(/webOSTV[/\\s-]*([\\d.]+)/i) || ua.match(/webOS\\.TV[/\\s-]*([\\d.]+)/i);\n    }\n\n    if (match && match[1]) {\n      version = match[1];\n      const parts = version.split('.');\n      majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n      webOSVersion = majorVersion;\n    } else if (chromeVersion > 0) {\n      if (chromeVersion >= 79) {\n        webOSVersion = 6;\n        version = '6.0';\n        majorVersion = 6;\n      } else if (chromeVersion >= 68) {\n        webOSVersion = 5;\n        version = '5.0';\n        majorVersion = 5;\n      } else if (chromeVersion >= 53) {\n        webOSVersion = 4;\n        version = '4.0';\n        majorVersion = 4;\n      } else if (chromeVersion >= 38) {\n        webOSVersion = 3;\n        version = '3.0';\n        majorVersion = 3;\n      } else {\n        webOSVersion = 2;\n        version = '2.0';\n        majorVersion = 2;\n      }\n    } else {\n      version = 'Unknown';\n      webOSVersion = undefined;\n    }\n\n    isLegacyTV = webOSVersion !== undefined && webOSVersion < 3;\n  } else if (/Tizen/i.test(ua)) {\n    name = 'Samsung Tizen';\n    isSmartTV = true;\n    const match = ua.match(/Tizen[/\\s]*([\\d.]+)/i);\n    version = match && match[1] ? match[1] : 'Unknown';\n    if (version !== 'Unknown') {\n      const parts = version.split('.');\n      majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n      tizenVersion = majorVersion;\n    }\n\n    isLegacyTV = tizenVersion !== undefined && tizenVersion < 3;\n  } else if (/SMART-TV|SmartTV/i.test(ua)) {\n    name = 'Smart TV';\n    isSmartTV = true;\n    isLegacyTV = chromeVersion > 0 && chromeVersion < 53;\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    isLegacyTV = chromeVersion > 0 && chromeVersion < 53;\n  } else {\n    if (chromeVersion > 0) {\n      name = 'Chrome';\n      version = chromeVersion.toString();\n      majorVersion = chromeVersion;\n\n      if (chromeVersion < 50) {\n        supportsModernJS = false;\n      }\n    }\n\n    if (webkitVersion > 0 && webkitVersion < 600) {\n      supportsModernJS = false;\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    webOSVersion,\n    tizenVersion,\n    chromeVersion: chromeVersionNum,\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 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    ...(browser.webOSVersion !== undefined ? { webOSVersion: browser.webOSVersion } : {}),\n    ...(browser.tizenVersion !== undefined ? { tizenVersion: browser.tizenVersion } : {}),\n    ...(browser.chromeVersion !== undefined ? { chromeVersion: browser.chromeVersion } : {}),\n    userAgent: navigator.userAgent,\n  });\n}\n\nexport function 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","import type { Scte35Marker, Id3TagInfo } from \"../types\";\n\nexport function 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\nexport function parseCueOutCont(\n  value: string\n): { elapsed?: number; duration?: number } | undefined {\n  const res: { elapsed?: number; duration?: number } = {};\n\n  const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n  const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n  if (elapsedMatch && elapsedMatch[1] != null) {\n    const e = parseFloat(elapsedMatch[1]);\n    if (!Number.isNaN(e)) res.elapsed = e;\n  }\n  if (durationMatch && durationMatch[1] != null) {\n    const d = parseFloat(durationMatch[1]);\n    if (!Number.isNaN(d)) res.duration = d;\n  }\n\n  if (!(\"elapsed\" in res) || !(\"duration\" in res)) {\n    const slashMatch = value.match(/([0-9.]+)\\s*\\/\\s*([0-9.]+)/);\n    if (slashMatch && slashMatch[1] && slashMatch[2]) {\n      const elapsed = parseFloat(slashMatch[1]);\n      const duration = parseFloat(slashMatch[2]);\n      if (!Number.isNaN(elapsed) && !(\"elapsed\" in res)) res.elapsed = elapsed;\n      if (!Number.isNaN(duration) && !(\"duration\" in res)) res.duration = duration;\n    }\n  }\n\n  if (\"elapsed\" in res || \"duration\" in res) return res;\n  return undefined;\n}\n\nexport function 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\nexport function 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\nexport function 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\nexport function 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\nexport function getFragmentStartSeconds(frag: any): number | undefined {\n  const candidates = [frag?.start, frag?.startPTS];\n  for (const candidate of candidates) {\n    if (typeof candidate === \"number\" && Number.isFinite(candidate)) {\n      return candidate;\n    }\n  }\n  return undefined;\n}\n\nexport function parseScte35FromId3(tag: Id3TagInfo): Scte35Marker | undefined {\n  const text = 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 = 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 = 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 = 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 = 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 = parseScte35Binary(tag.value);\n    if (bin) return bin;\n  }\n\n  return undefined;\n}\n\nexport function normalizeFragmentPayload(payload: unknown): Uint8Array | undefined {\n  if (payload instanceof Uint8Array) {\n    return payload;\n  }\n  if (payload instanceof ArrayBuffer) {\n    return new Uint8Array(payload);\n  }\n  if (ArrayBuffer.isView(payload)) {\n    const view = payload as ArrayBufferView;\n    return new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n  }\n  return undefined;\n}\n\n// --- Transport Stream SCTE-35 parsing ---\n\nexport function detectTsPacketFormat(\n  data: Uint8Array\n): { offset: number; packetSize: number; tsPayloadOffset: number } | undefined {\n  const packetSizes = [188, 192, 204];\n  for (const packetSize of packetSizes) {\n    const tsPayloadOffset = packetSize === 192 ? 4 : 0;\n    for (let offset = 0; offset < packetSize; offset++) {\n      let matchedPackets = 0;\n      for (\n        let packetStart = offset;\n        packetStart + tsPayloadOffset < data.length &&\n        matchedPackets < 5;\n        packetStart += packetSize\n      ) {\n        if (data[packetStart + tsPayloadOffset] !== 0x47) {\n          break;\n        }\n        matchedPackets++;\n      }\n      if (matchedPackets >= 2) {\n        return { offset, packetSize, tsPayloadOffset };\n      }\n    }\n  }\n  return undefined;\n}\n\nfunction getPsiSectionStart(\n  payload: Uint8Array,\n  payloadUnitStart: boolean\n): number | undefined {\n  if (!payloadUnitStart) {\n    return undefined;\n  }\n  const pointerField = payload[0];\n  if (pointerField == null) {\n    return undefined;\n  }\n  const sectionStart = 1 + pointerField;\n  return sectionStart < payload.length ? sectionStart : undefined;\n}\n\nfunction getPsiSectionLength(data: Uint8Array, offset: number): number {\n  return (((data[offset + 1] ?? 0) & 0x0f) << 8) | (data[offset + 2] ?? 0);\n}\n\nfunction parsePatSection(\n  payload: Uint8Array,\n  payloadUnitStart: boolean,\n  pmtPids: Set<number>\n): void {\n  const sectionStart = getPsiSectionStart(payload, payloadUnitStart);\n  if (sectionStart == null || sectionStart + 8 >= payload.length) {\n    return;\n  }\n  if (payload[sectionStart] !== 0x00) {\n    return;\n  }\n\n  const sectionLength = getPsiSectionLength(payload, sectionStart);\n  const sectionEnd = Math.min(\n    payload.length,\n    sectionStart + 3 + sectionLength\n  );\n\n  for (let offset = sectionStart + 8; offset + 4 <= sectionEnd - 4; offset += 4) {\n    const programNumber =\n      ((payload[offset] ?? 0) << 8) | (payload[offset + 1] ?? 0);\n    const pid =\n      (((payload[offset + 2] ?? 0) & 0x1f) << 8) |\n      (payload[offset + 3] ?? 0);\n    if (programNumber !== 0) {\n      pmtPids.add(pid);\n    }\n  }\n}\n\nfunction descriptorsIdentifyScte35(\n  data: Uint8Array,\n  start: number,\n  end: number\n): boolean {\n  let offset = start;\n  while (offset + 2 <= end) {\n    const tag = data[offset] ?? 0;\n    const length = data[offset + 1] ?? 0;\n    const descriptorStart = offset + 2;\n    const descriptorEnd = descriptorStart + length;\n    if (descriptorEnd > end) {\n      return false;\n    }\n\n    const registration =\n      length >= 4\n        ? String.fromCharCode(\n            data[descriptorStart] ?? 0,\n            data[descriptorStart + 1] ?? 0,\n            data[descriptorStart + 2] ?? 0,\n            data[descriptorStart + 3] ?? 0\n          )\n        : \"\";\n    if (tag === 0x8a || registration === \"CUEI\" || registration === \"SCTE\") {\n      return true;\n    }\n\n    offset = descriptorEnd;\n  }\n  return false;\n}\n\nfunction parsePmtSection(\n  payload: Uint8Array,\n  payloadUnitStart: boolean,\n  tsScte35Pids: Set<number>\n): void {\n  const sectionStart = getPsiSectionStart(payload, payloadUnitStart);\n  if (sectionStart == null || sectionStart + 12 >= payload.length) {\n    return;\n  }\n  if (payload[sectionStart] !== 0x02) {\n    return;\n  }\n\n  const sectionLength = getPsiSectionLength(payload, sectionStart);\n  const sectionEnd = Math.min(\n    payload.length,\n    sectionStart + 3 + sectionLength\n  );\n  const programInfoLength =\n    (((payload[sectionStart + 10] ?? 0) & 0x0f) << 8) |\n    (payload[sectionStart + 11] ?? 0);\n\n  let offset = sectionStart + 12 + programInfoLength;\n  while (offset + 5 <= sectionEnd - 4) {\n    const streamType = payload[offset] ?? 0;\n    const elementaryPid =\n      (((payload[offset + 1] ?? 0) & 0x1f) << 8) |\n      (payload[offset + 2] ?? 0);\n    const esInfoLength =\n      (((payload[offset + 3] ?? 0) & 0x0f) << 8) |\n      (payload[offset + 4] ?? 0);\n    const descriptorStart = offset + 5;\n    const descriptorEnd = Math.min(descriptorStart + esInfoLength, sectionEnd - 4);\n\n    if (\n      streamType === 0x86 ||\n      (streamType === 0x06 &&\n        descriptorsIdentifyScte35(payload, descriptorStart, descriptorEnd))\n    ) {\n      tsScte35Pids.add(elementaryPid);\n    }\n\n    offset = descriptorStart + esInfoLength;\n  }\n}\n\nfunction hasProcessedTsScte35Section(\n  section: Uint8Array,\n  processedSections: Set<string>\n): boolean {\n  let checksum = 0;\n  for (let i = 0; i < section.length; i++) {\n    checksum = (checksum * 31 + (section[i] ?? 0)) >>> 0;\n  }\n\n  const key = `${section.length}:${checksum}`;\n  if (processedSections.has(key)) {\n    return true;\n  }\n\n  processedSections.add(key);\n  if (processedSections.size > 200) {\n    const firstKey = processedSections.values().next().value;\n    if (firstKey) {\n      processedSections.delete(firstKey);\n    }\n  }\n  return false;\n}\n\nfunction addScte35SectionMarker(\n  section: Uint8Array,\n  markers: Scte35Marker[],\n  processedSections: Set<string>\n): void {\n  if (section[0] !== 0xfc || hasProcessedTsScte35Section(section, processedSections)) {\n    return;\n  }\n\n  const marker = parseScte35Binary(section);\n  if (!marker) {\n    return;\n  }\n\n  marker.raw = {\n    ...(typeof marker.raw === \"object\" && marker.raw ? marker.raw : {}),\n    source: \"ts-packet\",\n  };\n  markers.push(marker);\n}\n\nfunction appendScte35Bytes(\n  pid: number,\n  bytes: Uint8Array,\n  assemblers: Map<number, { bytes: number[]; expectedLength: number }>,\n  markers: Scte35Marker[],\n  processedSections: Set<string>\n): void {\n  const assembler = assemblers.get(pid);\n  if (!assembler) {\n    return;\n  }\n\n  for (let i = 0; i < bytes.length && assembler.bytes.length < assembler.expectedLength; i++) {\n    assembler.bytes.push(bytes[i] ?? 0);\n  }\n\n  if (assembler.bytes.length >= assembler.expectedLength) {\n    assemblers.delete(pid);\n    addScte35SectionMarker(new Uint8Array(assembler.bytes), markers, processedSections);\n  }\n}\n\nfunction collectScte35SectionsFromPayload(\n  pid: number,\n  payload: Uint8Array,\n  payloadUnitStart: boolean,\n  assemblers: Map<number, { bytes: number[]; expectedLength: number }>,\n  markers: Scte35Marker[],\n  processedSections: Set<string>\n): void {\n  if (payload.length === 0) {\n    return;\n  }\n\n  let offset = 0;\n  if (payloadUnitStart) {\n    const pointerField = payload[0] ?? 0;\n    const previousAssembler = assemblers.get(pid);\n    if (previousAssembler && pointerField > 0) {\n      appendScte35Bytes(\n        pid,\n        payload.subarray(1, Math.min(1 + pointerField, payload.length)),\n        assemblers,\n        markers,\n        processedSections\n      );\n    }\n    assemblers.delete(pid);\n    offset = 1 + pointerField;\n  } else {\n    appendScte35Bytes(pid, payload, assemblers, markers, processedSections);\n    return;\n  }\n\n  while (offset + 3 <= payload.length) {\n    const tableId = payload[offset];\n    if (tableId == null || tableId === 0xff) {\n      return;\n    }\n\n    const sectionLength = getPsiSectionLength(payload, offset);\n    const totalLength = 3 + sectionLength;\n    if (sectionLength <= 0 || totalLength <= 3) {\n      return;\n    }\n\n    if (offset + totalLength <= payload.length) {\n      addScte35SectionMarker(\n        payload.subarray(offset, offset + totalLength),\n        markers,\n        processedSections\n      );\n      offset += totalLength;\n    } else {\n      assemblers.set(pid, {\n        bytes: Array.from(payload.subarray(offset)),\n        expectedLength: totalLength,\n      });\n      return;\n    }\n  }\n}\n\nexport function parseScte35FromTsPackets(\n  data: Uint8Array,\n  tsScte35Pids: Set<number>,\n  pmtPids: Set<number>,\n  processedSections: Set<string>\n): Scte35Marker[] {\n  const packetInfo = detectTsPacketFormat(data);\n  if (!packetInfo) {\n    return [];\n  }\n\n  const markers: Scte35Marker[] = [];\n  const sectionAssemblers = new Map<\n    number,\n    { bytes: number[]; expectedLength: number }\n  >();\n\n  for (\n    let packetStart = packetInfo.offset;\n    packetStart + packetInfo.packetSize <= data.length;\n    packetStart += packetInfo.packetSize\n  ) {\n    const tsStart = packetStart + packetInfo.tsPayloadOffset;\n    if (data[tsStart] !== 0x47) {\n      continue;\n    }\n\n    const secondByte = data[tsStart + 1];\n    const thirdByte = data[tsStart + 2];\n    const fourthByte = data[tsStart + 3];\n    if (\n      secondByte == null ||\n      thirdByte == null ||\n      fourthByte == null ||\n      (secondByte & 0x80) !== 0\n    ) {\n      continue;\n    }\n\n    const payloadUnitStart = (secondByte & 0x40) !== 0;\n    const pid = ((secondByte & 0x1f) << 8) | thirdByte;\n    const adaptationFieldControl = (fourthByte >> 4) & 0x03;\n    const hasPayload =\n      adaptationFieldControl === 1 || adaptationFieldControl === 3;\n    if (!hasPayload) {\n      continue;\n    }\n\n    let payloadStart = tsStart + 4;\n    if (adaptationFieldControl === 3) {\n      const adaptationLength = data[payloadStart];\n      if (adaptationLength == null) {\n        continue;\n      }\n      payloadStart += 1 + adaptationLength;\n    }\n\n    const payloadEnd = Math.min(tsStart + 188, data.length);\n    if (payloadStart >= payloadEnd || payloadStart >= data.length) {\n      continue;\n    }\n\n    const payload = data.subarray(payloadStart, payloadEnd);\n    if (pid === 0) {\n      parsePatSection(payload, payloadUnitStart, pmtPids);\n    } else if (pmtPids.has(pid)) {\n      parsePmtSection(payload, payloadUnitStart, tsScte35Pids);\n    } else if (tsScte35Pids.has(pid)) {\n      collectScte35SectionsFromPayload(\n        pid,\n        payload,\n        payloadUnitStart,\n        sectionAssemblers,\n        markers,\n        processedSections\n      );\n    }\n  }\n\n  return markers;\n}\n\n// --- Binary SCTE-35 parsing ---\n\nclass 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  get bytePosition(): number {\n    return this.bitPos === 0 ? this.bytePos : this.bytePos + 1;\n  }\n}\n\nfunction readSpliceTime(\n  r: BitReader,\n  ptsAdjustmentTicks: number\n): number | undefined {\n  const timeSpecifiedFlag = r.readBits(1) === 1;\n  if (!timeSpecifiedFlag) {\n    r.readBits(7);\n    return undefined;\n  }\n  r.readBits(6);\n  const high = r.readBits(1);\n  const low = r.readBits(32);\n  const ptsTicks =\n    (high * 0x100000000 + low + ptsAdjustmentTicks) % 0x200000000;\n  return ptsTicks / 90000;\n}\n\nfunction markerTypeFromSegmentationTypeId(\n  segmentationTypeId: number\n): Scte35Marker[\"type\"] | undefined {\n  switch (segmentationTypeId) {\n    case 0x10:\n    case 0x22:\n    case 0x30:\n    case 0x32:\n    case 0x34:\n    case 0x36:\n      return \"start\";\n    case 0x11:\n    case 0x23:\n    case 0x31:\n    case 0x33:\n    case 0x35:\n    case 0x37:\n      return \"end\";\n    default:\n      return undefined;\n  }\n}\n\nfunction parseScte35SegmentationDescriptor(\n  descriptor: Uint8Array\n):\n  | {\n      type: Scte35Marker[\"type\"];\n      durationSeconds?: number;\n      segmentationEventId?: number;\n    }\n  | undefined {\n  if (descriptor.length < 11) {\n    return undefined;\n  }\n\n  const identifier = String.fromCharCode(\n    descriptor[0] ?? 0,\n    descriptor[1] ?? 0,\n    descriptor[2] ?? 0,\n    descriptor[3] ?? 0\n  );\n  if (identifier !== \"CUEI\") {\n    return undefined;\n  }\n\n  const segmentationEventId =\n    ((descriptor[4] ?? 0) * 0x1000000) +\n    ((descriptor[5] ?? 0) << 16) +\n    ((descriptor[6] ?? 0) << 8) +\n    (descriptor[7] ?? 0);\n  const cancelIndicator = ((descriptor[8] ?? 0) & 0x80) !== 0;\n  if (cancelIndicator) {\n    return undefined;\n  }\n\n  const flags = descriptor[9] ?? 0;\n  const programSegmentationFlag = (flags & 0x80) !== 0;\n  const segmentationDurationFlag = (flags & 0x40) !== 0;\n  let offset = 10;\n\n  if (!programSegmentationFlag) {\n    const componentCount = descriptor[offset] ?? 0;\n    offset += 1 + componentCount * 6;\n    if (offset > descriptor.length) {\n      return undefined;\n    }\n  }\n\n  let durationSeconds: number | undefined = undefined;\n  if (segmentationDurationFlag) {\n    if (offset + 5 > descriptor.length) {\n      return undefined;\n    }\n    const durationTicks =\n      ((descriptor[offset] ?? 0) * 0x100000000) +\n      ((descriptor[offset + 1] ?? 0) * 0x1000000) +\n      ((descriptor[offset + 2] ?? 0) << 16) +\n      ((descriptor[offset + 3] ?? 0) << 8) +\n      (descriptor[offset + 4] ?? 0);\n    durationSeconds = durationTicks / 90000;\n    offset += 5;\n  }\n\n  if (offset + 2 > descriptor.length) {\n    return undefined;\n  }\n  offset += 1;\n  const segmentationUpidLength = descriptor[offset] ?? 0;\n  offset += 1 + segmentationUpidLength;\n  if (offset >= descriptor.length) {\n    return undefined;\n  }\n\n  const segmentationTypeId = descriptor[offset] ?? 0;\n  const markerType = markerTypeFromSegmentationTypeId(segmentationTypeId);\n  if (!markerType) {\n    return undefined;\n  }\n\n  return {\n    type: markerType,\n    ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n    segmentationEventId,\n  };\n}\n\nfunction parseScte35SegmentationDescriptors(\n  data: Uint8Array,\n  offset: number\n):\n  | {\n      type: Scte35Marker[\"type\"];\n      durationSeconds?: number;\n      segmentationEventId?: number;\n    }\n  | undefined {\n  if (offset + 2 > data.length) {\n    return undefined;\n  }\n\n  const descriptorLoopLength =\n    ((data[offset] ?? 0) << 8) | (data[offset + 1] ?? 0);\n  let descriptorOffset = offset + 2;\n  const descriptorEnd = Math.min(\n    data.length,\n    descriptorOffset + descriptorLoopLength\n  );\n\n  while (descriptorOffset + 2 <= descriptorEnd) {\n    const descriptorTag = data[descriptorOffset] ?? 0;\n    const descriptorLength = data[descriptorOffset + 1] ?? 0;\n    const descriptorDataStart = descriptorOffset + 2;\n    const descriptorDataEnd = descriptorDataStart + descriptorLength;\n    if (descriptorDataEnd > descriptorEnd) {\n      return undefined;\n    }\n\n    if (descriptorTag === 0x02) {\n      const descriptorMarker = parseScte35SegmentationDescriptor(\n        data.subarray(descriptorDataStart, descriptorDataEnd)\n      );\n      if (descriptorMarker) {\n        return descriptorMarker;\n      }\n    }\n\n    descriptorOffset = descriptorDataEnd;\n  }\n\n  return undefined;\n}\n\nexport function parseScte35Binary(data: Uint8Array): Scte35Marker | undefined {\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  if (sectionLength <= 0 || data.length < 3 + sectionLength) {\n    return undefined;\n  }\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  const ptsAdjustmentTicks = ptsAdjHigh * 0x100000000 + ptsAdjLow;\n  r.readBits(8);\n  r.readBits(12);\n  const spliceCommandLength = r.readBits(12);\n  const spliceCommandType = r.readBits(8);\n\n  let markerType: Scte35Marker[\"type\"] | undefined;\n  let durationSeconds: number | undefined = undefined;\n  let ptsSeconds: number | undefined = undefined;\n  let spliceEventId: number | undefined = undefined;\n  const commandBodyStart = r.bytePosition;\n\n  if (spliceCommandType === 5) {\n    spliceEventId = 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    markerType = outOfNetwork ? \"start\" : \"end\";\n\n    if (programSpliceFlag && !spliceImmediateFlag) {\n      ptsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\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 componentPtsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n          if (ptsSeconds === undefined) {\n            ptsSeconds = componentPtsSeconds;\n          }\n        }\n      }\n    }\n\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  } else if (spliceCommandType === 6) {\n    ptsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n  } else {\n    return undefined;\n  }\n\n  const expectedDescriptorOffset =\n    spliceCommandLength === 0x0fff\n      ? r.bytePosition\n      : commandBodyStart + spliceCommandLength;\n  const descriptorMarker = parseScte35SegmentationDescriptors(\n    data,\n    expectedDescriptorOffset\n  );\n\n  if (descriptorMarker) {\n    markerType = descriptorMarker.type;\n    if (durationSeconds === undefined) {\n      durationSeconds = descriptorMarker.durationSeconds;\n    }\n  }\n\n  if (!markerType) {\n    return undefined;\n  }\n\n  const marker: Scte35Marker = {\n    type: markerType,\n    ...(ptsSeconds !== undefined ? { ptsSeconds } : {}),\n    ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n    raw: {\n      splice_command_type: spliceCommandType,\n      ...(spliceEventId !== undefined ? { splice_event_id: spliceEventId } : {}),\n      ...(descriptorMarker?.segmentationEventId !== undefined\n        ? { segmentation_event_id: descriptorMarker.segmentationEventId }\n        : {}),\n    },\n  } as Scte35Marker;\n  return marker;\n}\n","import type { Scte35Marker } from \"../types\";\nimport type {\n  NormalizedScte35Cue,\n  Scte35CueContext,\n  Scte35CueSource,\n  Scte35CueReadiness,\n} from \"./playerTypes\";\nimport { getFragmentStartSeconds } from \"./Scte35Parser\";\n\nexport interface Scte35CueManagerCallbacks {\n  onEarlyStartCue(marker: Scte35Marker, fragmentSn: number | undefined, cueKey: string): void;\n  onPlaybackCue(marker: Scte35Marker, cueKey?: string): void;\n  isInAdBreak(): boolean;\n}\n\nexport class Scte35CueManager {\n  private readonly pendingScte35Cues: Map<string, NormalizedScte35Cue> = new Map();\n  private readonly recentScte35CueKeys: Map<string, number> = new Map();\n  private readonly recentScte35CueLimit: number = 200;\n  private pendingScte35CueKeyValue: string | undefined;\n  private activeScte35BreakKeyValue: string | undefined;\n  private scheduledScte35BreakKeyValue: string | undefined;\n\n  readonly tsScte35Pids: Set<number> = new Set();\n  readonly pmtPids: Set<number> = new Set();\n  readonly processedTsScte35Sections: Set<string> = new Set();\n\n  private debug: boolean;\n  private callbacks: Scte35CueManagerCallbacks;\n\n  constructor(debug: boolean, callbacks: Scte35CueManagerCallbacks) {\n    this.debug = debug;\n    this.callbacks = callbacks;\n  }\n\n  get pendingScte35CueKey(): string | undefined {\n    return this.pendingScte35CueKeyValue;\n  }\n  set pendingScte35CueKey(value: string | undefined) {\n    this.pendingScte35CueKeyValue = value;\n  }\n\n  get activeScte35BreakKey(): string | undefined {\n    return this.activeScte35BreakKeyValue;\n  }\n  set activeScte35BreakKey(value: string | undefined) {\n    this.activeScte35BreakKeyValue = value;\n  }\n\n  get scheduledScte35BreakKey(): string | undefined {\n    return this.scheduledScte35BreakKeyValue;\n  }\n  set scheduledScte35BreakKey(value: string | undefined) {\n    this.scheduledScte35BreakKeyValue = value;\n  }\n\n  createScte35CueContext(\n    source: Scte35CueSource,\n    readiness: Scte35CueReadiness,\n    frag?: any\n  ): Scte35CueContext {\n    const context: Scte35CueContext = { source, readiness };\n    if (typeof frag?.sn === \"number\") {\n      context.fragmentSn = frag.sn;\n    }\n    const fragmentStartSec = getFragmentStartSeconds(frag);\n    if (fragmentStartSec !== undefined) {\n      context.fragmentStartSeconds = fragmentStartSec;\n    }\n    return context;\n  }\n\n  onScte35Cue(marker: Scte35Marker, context: Scte35CueContext): void {\n    const cue = this.createScte35Cue(marker, context);\n    const pendingKey = this.getPendingScte35CueKey(cue);\n\n    if (context.readiness === \"early\") {\n      this.pendingScte35Cues.set(pendingKey, cue);\n      this.trimRecentScte35CueMaps();\n\n      if (marker.type === \"start\") {\n        this.callbacks.onEarlyStartCue(marker, context.fragmentSn, cue.key);\n      }\n      return;\n    }\n\n    if (marker.type === \"end\" && !this.shouldAcceptScte35EndCue(cue)) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ignoring SCTE-35 end cue\", {\n          key: cue.key,\n          activeScte35BreakKey: this.activeScte35BreakKeyValue,\n          inAdBreak: this.callbacks.isInAdBreak(),\n          source: cue.source,\n        });\n      }\n      return;\n    }\n\n    if (marker.type === \"start\" && this.hasRecentlyHandledScte35Cue(cue)) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ignoring duplicate SCTE-35 start cue\", {\n          key: cue.key,\n          source: cue.source,\n        });\n      }\n      return;\n    }\n\n    this.pendingScte35Cues.delete(pendingKey);\n    this.markScte35CueHandled(cue);\n    this.callbacks.onPlaybackCue(marker, cue.key);\n  }\n\n  activatePendingScte35CuesForFragment(frag: any): void {\n    const fragmentSn = typeof frag?.sn === \"number\" ? frag.sn : undefined;\n    if (fragmentSn === undefined) {\n      return;\n    }\n\n    const matchingCues = Array.from(this.pendingScte35Cues.entries()).filter(\n      ([, cue]) => cue.fragmentSn === fragmentSn\n    );\n\n    matchingCues.forEach(([pendingKey, cue]) => {\n      this.pendingScte35Cues.delete(pendingKey);\n      const context: Scte35CueContext = {\n        source: cue.source,\n        readiness: \"playback\",\n      };\n      context.fragmentSn = fragmentSn;\n      const fragmentStartSec =\n        cue.fragmentStartSeconds ?? getFragmentStartSeconds(frag);\n      if (fragmentStartSec !== undefined) {\n        context.fragmentStartSeconds = fragmentStartSec;\n      }\n      this.onScte35Cue(cue.marker, context);\n    });\n  }\n\n  private createScte35Cue(\n    marker: Scte35Marker,\n    context: Scte35CueContext\n  ): NormalizedScte35Cue {\n    const cue: NormalizedScte35Cue = {\n      marker,\n      source: context.source,\n      readiness: context.readiness,\n      key: this.getScte35CueKey(marker, context),\n    };\n    if (context.fragmentSn !== undefined) {\n      cue.fragmentSn = context.fragmentSn;\n    }\n    if (context.fragmentStartSeconds !== undefined) {\n      cue.fragmentStartSeconds = context.fragmentStartSeconds;\n    }\n    return cue;\n  }\n\n  private getScte35CueKey(\n    marker: Scte35Marker,\n    context: Scte35CueContext\n  ): string {\n    const raw = this.getScte35MarkerRaw(marker);\n    const spliceEventId = this.toIdentityString(raw?.splice_event_id);\n    if (spliceEventId) {\n      return `splice:${spliceEventId}`;\n    }\n\n    const segmentationEventId = this.toIdentityString(raw?.segmentation_event_id);\n    if (segmentationEventId) {\n      return `segmentation:${segmentationEventId}`;\n    }\n\n    const daterangeId = this.toIdentityString(raw?.attrs?.ID);\n    if (daterangeId) {\n      return `daterange:${daterangeId}`;\n    }\n\n    const scteValue =\n      this.toIdentityString(raw?.attrs?.[\"SCTE35-OUT\"]) ||\n      this.toIdentityString(raw?.attrs?.[\"SCTE35-IN\"]);\n    if (scteValue) {\n      return `daterange-scte:${scteValue}`;\n    }\n\n    if (typeof marker.ptsSeconds === \"number\" && Number.isFinite(marker.ptsSeconds)) {\n      return `pts:${Math.round(marker.ptsSeconds * 2) / 2}`;\n    }\n\n    if (context.fragmentSn !== undefined) {\n      return `fragment:${context.fragmentSn}`;\n    }\n\n    return `${context.source}:wallclock:${Math.floor(Date.now() / 1000)}`;\n  }\n\n  private getPendingScte35CueKey(cue: NormalizedScte35Cue): string {\n    return `${cue.marker.type}:${cue.key}:${\n      cue.fragmentSn !== undefined ? cue.fragmentSn : \"unknown\"\n    }`;\n  }\n\n  private getScte35MarkerRaw(marker: Scte35Marker): any {\n    return typeof marker.raw === \"object\" && marker.raw !== null\n      ? (marker.raw as any)\n      : {};\n  }\n\n  private toIdentityString(value: unknown): string | undefined {\n    if (typeof value === \"number\" && Number.isFinite(value)) {\n      return String(value);\n    }\n    if (typeof value === \"string\" && value.trim().length > 0) {\n      return value.trim();\n    }\n    return undefined;\n  }\n\n  isStrongScte35CueKey(key: string | undefined): boolean {\n    return !!(\n      key &&\n      (key.startsWith(\"splice:\") ||\n        key.startsWith(\"segmentation:\") ||\n        key.startsWith(\"daterange:\") ||\n        key.startsWith(\"daterange-scte:\"))\n    );\n  }\n\n  private hasRecentlyHandledScte35Cue(cue: NormalizedScte35Cue): boolean {\n    if (\n      this.activeScte35BreakKeyValue === cue.key ||\n      this.scheduledScte35BreakKeyValue === cue.key\n    ) {\n      return true;\n    }\n\n    const recentKey = `${cue.marker.type}:${cue.key}`;\n    return this.recentScte35CueKeys.has(recentKey);\n  }\n\n  private markScte35CueHandled(cue: NormalizedScte35Cue): void {\n    this.recentScte35CueKeys.set(`${cue.marker.type}:${cue.key}`, Date.now());\n    this.trimRecentScte35CueMaps();\n  }\n\n  private trimRecentScte35CueMaps(): void {\n    while (this.recentScte35CueKeys.size > this.recentScte35CueLimit) {\n      const firstKey = this.recentScte35CueKeys.keys().next().value;\n      if (!firstKey) {\n        break;\n      }\n      this.recentScte35CueKeys.delete(firstKey);\n    }\n\n    while (this.pendingScte35Cues.size > this.recentScte35CueLimit) {\n      const firstKey = this.pendingScte35Cues.keys().next().value;\n      if (!firstKey) {\n        break;\n      }\n      this.pendingScte35Cues.delete(firstKey);\n    }\n  }\n\n  private shouldAcceptScte35EndCue(cue: NormalizedScte35Cue): boolean {\n    if (!this.callbacks.isInAdBreak()) {\n      return false;\n    }\n\n    if (\n      this.isStrongScte35CueKey(this.activeScte35BreakKeyValue) &&\n      this.isStrongScte35CueKey(cue.key) &&\n      this.activeScte35BreakKeyValue !== cue.key\n    ) {\n      return false;\n    }\n\n    return true;\n  }\n}\n","import type {\n  StormcloudVideoPlayerConfig,\n  AdBreak,\n  StormcloudApiResponse,\n  AdController,\n} from \"../types\";\nimport type { PalNonceManager } from \"../sdk/pal\";\nimport { applyVastMacros, generateCorrelator, normalizeVastTagUrl } from \"../utils/vastMacros\";\nimport type { VastConsentSignals } from \"../utils/vastMacros\";\nimport { resolveVastEnvironmentSignals } from \"../utils/vastEnvironmentSignals\";\nimport {\n  buildAnalyticsContext,\n  sendHeartbeat,\n  sendInitialTracking,\n} from \"../utils/tracking\";\n\nexport class AdConfigManager {\n  vmapBreaks: AdBreak[] = [];\n  consumedVmapBreakIds: Set<string> = new Set();\n  apiVastTagUrl: string | undefined;\n  apiNumberAds: number | undefined;\n  readonly streamCorrelator: string = generateCorrelator();\n  readonly viewCorrelator: string = generateCorrelator();\n  consentSignals: VastConsentSignals = {};\n  podCounter: number = 0;\n  podAssignedByPrefetch: boolean = false;\n  adRequestPositionInBreak: number = 0;\n\n  private lastHeartbeatTime: number = 0;\n  private heartbeatInterval: number | undefined;\n\n  private config: StormcloudVideoPlayerConfig;\n  private video: HTMLVideoElement;\n\n  constructor(config: StormcloudVideoPlayerConfig, video: HTMLVideoElement) {\n    this.config = config;\n    this.video = video;\n  }\n\n  get debug(): boolean {\n    return !!this.config.debugAdTiming;\n  }\n\n  isVmapEnabled(): boolean {\n    return !!(this.config.isVmap && this.config.vmapUrl?.trim());\n  }\n\n  async fetchAdConfiguration(): Promise<void> {\n    if (this.isVmapEnabled()) {\n      await this.fetchAndParseVmap(this.config.vmapUrl!);\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] VMAP mode enabled\");\n      }\n      return;\n    }\n\n    const vastMode = this.config.vastMode || \"default\";\n\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] VAST mode:\", vastMode);\n    }\n\n    if (vastMode === \"adstorm\") {\n      if (!this.config.licenseKey) {\n        if (this.debug) {\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.debug) {\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 = normalizeVastTagUrl(this.config.vastTagUrl);\n      if (this.debug) {\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.debug) {\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.debug) {\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      let decodedPayload = imaPayload;\n      try {\n        decodedPayload = decodeURIComponent(imaPayload);\n      } catch {\n        console.warn(\"[StormcloudVideoPlayer] imaPayload was not URI-encoded; using as-is:\", imaPayload);\n      }\n      console.log(\"[StormcloudVideoPlayer] Raw VAST tag URL (from API):\", decodedPayload);\n      this.apiVastTagUrl = normalizeVastTagUrl(decodedPayload);\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Normalized VAST tag URL:\",\n          this.apiVastTagUrl\n        );\n      }\n    } else {\n      if (this.debug) {\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.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Number of ads per break from API:\",\n          this.apiNumberAds\n        );\n      }\n    }\n  }\n\n  private async fetchAndParseVmap(vmapUrl: string): Promise<void> {\n    if (!vmapUrl.trim()) {\n      return;\n    }\n\n    try {\n      const response = await fetch(vmapUrl);\n      if (!response.ok) {\n        throw new Error(`Failed to fetch VMAP (${response.status})`);\n      }\n\n      const vmapXml = await response.text();\n      this.vmapBreaks = this.parseVmapToBreaks(vmapXml);\n      this.consumedVmapBreakIds.clear();\n\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] Loaded ${this.vmapBreaks.length} VMAP ad break(s) from:`,\n          vmapUrl\n        );\n      }\n    } catch (error) {\n      this.vmapBreaks = [];\n      this.consumedVmapBreakIds.clear();\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Failed to load VMAP:\", error);\n      }\n    }\n  }\n\n  private parseVmapToBreaks(vmapXml: string): AdBreak[] {\n    if (typeof DOMParser === \"undefined\") {\n      return [];\n    }\n\n    const doc = new DOMParser().parseFromString(vmapXml, \"application/xml\");\n    if (doc.querySelector(\"parsererror\")) {\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Invalid VMAP XML received\");\n      }\n      return [];\n    }\n\n    const VMAP_NS = \"http://www.iab.net/videosuite/vmap\";\n    let adBreakNodes = Array.from(doc.getElementsByTagNameNS(VMAP_NS, \"AdBreak\"));\n    if (adBreakNodes.length === 0) {\n      adBreakNodes = Array.from(\n        doc.querySelectorAll(\"AdBreak, vmap\\\\:AdBreak\")\n      );\n    }\n    if (adBreakNodes.length === 0) {\n      adBreakNodes = Array.from(doc.getElementsByTagName(\"*\")).filter(\n        (el) => el.localName === \"AdBreak\"\n      );\n    }\n    const parsed: AdBreak[] = [];\n\n    adBreakNodes.forEach((node, index) => {\n      const timeOffsetRaw = (node.getAttribute(\"timeOffset\") || \"\").trim();\n      const startTimeMs = this.parseVmapTimeOffsetToMs(timeOffsetRaw);\n      if (startTimeMs == null) {\n        return;\n      }\n\n      let adTagNode = node.getElementsByTagNameNS(VMAP_NS, \"AdTagURI\")[0];\n      if (!adTagNode) {\n        adTagNode =\n          (node.querySelector(\"AdTagURI, vmap\\\\:AdTagURI\") as Element | null) ??\n          undefined;\n      }\n      const adTagUrl = (adTagNode?.textContent || \"\").trim();\n      if (!adTagUrl) {\n        return;\n      }\n\n      const breakId =\n        node.getAttribute(\"breakId\") ||\n        `vmap-break-${index}-${timeOffsetRaw || \"unknown\"}`;\n      parsed.push({\n        id: breakId,\n        startTimeMs,\n        vastTagUrl: adTagUrl,\n      });\n    });\n\n    parsed.sort((a, b) => {\n      const aStart = a.startTimeMs < 0 ? Number.MAX_SAFE_INTEGER : a.startTimeMs;\n      const bStart = b.startTimeMs < 0 ? Number.MAX_SAFE_INTEGER : b.startTimeMs;\n      return aStart - bStart;\n    });\n\n    return parsed;\n  }\n\n  private parseVmapTimeOffsetToMs(timeOffset: string): number | undefined {\n    if (!timeOffset) {\n      return undefined;\n    }\n\n    const normalized = timeOffset.trim().toLowerCase();\n    if (normalized === \"start\") {\n      return 0;\n    }\n\n    if (normalized === \"end\") {\n      return -1;\n    }\n\n    const hms = timeOffset.match(\n      /^(\\d{1,2}):(\\d{2}):(\\d{2})(?:\\.(\\d{1,3}))?$/\n    );\n    if (hms) {\n      const [, hh, mm, ss, ms = \"0\"] = hms;\n      const hours = Number(hh);\n      const minutes = Number(mm);\n      const seconds = Number(ss);\n      const millis = Number(ms.padEnd(3, \"0\").slice(0, 3));\n      return ((hours * 3600 + minutes * 60 + seconds) * 1000) + millis;\n    }\n\n    const percent = timeOffset.match(/^(\\d+(?:\\.\\d+)?)%$/);\n    if (percent) {\n      const ratio = Number(percent[1]) / 100;\n      const durationSec = this.video.duration;\n      if (Number.isFinite(durationSec) && durationSec > 0) {\n        return Math.floor(durationSec * 1000 * ratio);\n      }\n      return undefined;\n    }\n\n    return undefined;\n  }\n\n  getAdBreakKey(adBreak: AdBreak): string {\n    if (adBreak.id) {\n      return adBreak.id;\n    }\n    return `${adBreak.startTimeMs}-${adBreak.vastTagUrl || \"\"}`;\n  }\n\n  resolveBreakStartMs(adBreak: AdBreak): number | undefined {\n    if (adBreak.startTimeMs >= 0) {\n      return adBreak.startTimeMs;\n    }\n\n    if (adBreak.startTimeMs === -1) {\n      const durationSec = this.video.duration;\n      if (Number.isFinite(durationSec) && durationSec > 0) {\n        return Math.floor(durationSec * 1000);\n      }\n    }\n\n    return undefined;\n  }\n\n  findCurrentOrNextBreak(nowMs: number): AdBreak | undefined {\n    const schedule: AdBreak[] = this.vmapBreaks;\n    let candidate: AdBreak | undefined;\n    const tol = this.config.driftToleranceMs ?? 1000;\n    for (const b of schedule) {\n      if (this.consumedVmapBreakIds.has(this.getAdBreakKey(b))) {\n        continue;\n      }\n      const breakStartMs = this.resolveBreakStartMs(b);\n      if (breakStartMs == null) {\n        continue;\n      }\n      if (\n        breakStartMs <= nowMs + tol &&\n        (candidate == null ||\n          breakStartMs > (this.resolveBreakStartMs(candidate) ?? 0))\n      ) {\n        candidate = b;\n      }\n    }\n    return candidate;\n  }\n\n  findBreakForTime(nowMs: number): AdBreak | undefined {\n    const schedule: AdBreak[] = this.vmapBreaks;\n    for (const b of schedule) {\n      if (this.consumedVmapBreakIds.has(this.getAdBreakKey(b))) {\n        continue;\n      }\n      const breakStartMs = this.resolveBreakStartMs(b);\n      if (breakStartMs == null) {\n        continue;\n      }\n\n      if (b.durationMs) {\n        const end = breakStartMs + b.durationMs;\n        if (nowMs >= breakStartMs && nowMs < end) {\n          return b;\n        }\n        continue;\n      }\n\n      if (nowMs >= breakStartMs) {\n        return b;\n      }\n    }\n    return undefined;\n  }\n\n  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  beginNewAdPod(): void {\n    this.podCounter++;\n    this.adRequestPositionInBreak = 0;\n  }\n\n  generateVastUrlsWithCorrelators(\n    baseUrl: string,\n    count: number,\n    adPlayer: AdController,\n    palNonce: PalNonceManager,\n    inAdBreak: boolean\n  ): string[] {\n    const urls: string[] = [];\n\n    for (let i = 0; i < count; i++) {\n      this.adRequestPositionInBreak++;\n\n      const adWillPlayMuted = inAdBreak\n        ? adPlayer.getOriginalMutedState()\n        : this.video.muted;\n      const envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);\n\n      const urlWithMacros = applyVastMacros(baseUrl, {\n        correlator: this.viewCorrelator,\n        streamCorrelator: this.streamCorrelator,\n        pod: this.podCounter > 0 ? this.podCounter : undefined,\n        adPosition: this.adRequestPositionInBreak,\n        isCtv: envSignals.isCtv,\n        contentUrl: envSignals.contentUrl,\n        pageUrl:\n          !envSignals.isCtv && typeof window !== \"undefined\"\n            ? window.location.href\n            : undefined,\n        adWillPlayMuted,\n        adWillAutoPlay: !!this.config.autoplay,\n        appId: envSignals.appId,\n        appName: envSignals.appName,\n        sessionId: envSignals.sessionId,\n        deviceId: envSignals.deviceId,\n        deviceIdType: envSignals.deviceIdType,\n        limitAdTracking: envSignals.limitAdTracking,\n        deviceTypeHint: envSignals.deviceTypeHint,\n        adTest: this.config.adTest,\n        consent: this.consentSignals,\n      });\n\n      const finalUrl = palNonce.injectNonce(urlWithMacros);\n      console.log(\n        `[StormcloudVideoPlayer] Resolved ad request URL (pod=${this.podCounter}, pos=${this.adRequestPositionInBreak}):`,\n        finalUrl\n      );\n      urls.push(finalUrl);\n    }\n\n    return urls;\n  }\n\n  private readonly defaultPodMaxAds: number = 6;\n\n  resolvePodParams(breakDurationMs?: number): {\n    maxAds: number;\n    minDurationMs: number;\n    maxDurationMs: number | undefined;\n  } {\n    const maxDurationMs =\n      breakDurationMs != null && breakDurationMs > 0\n        ? breakDurationMs\n        : this.config.podMaxDurationMs;\n\n    const maxAds =\n      this.config.podMaxAds && this.config.podMaxAds > 0\n        ? this.config.podMaxAds\n        : this.apiNumberAds && this.apiNumberAds > 0\n          ? this.apiNumberAds\n          : this.defaultPodMaxAds;\n\n    const minDurationMs =\n      this.config.podExactDuration && maxDurationMs != null ? maxDurationMs : 0;\n\n    return { maxAds, minDurationMs, maxDurationMs };\n  }\n\n  generatePodVastUrl(\n    baseUrl: string,\n    podParams: { maxAds: number; minDurationMs: number; maxDurationMs: number | undefined },\n    adPlayer: AdController,\n    palNonce: PalNonceManager,\n    inAdBreak: boolean\n  ): string {\n    const adWillPlayMuted = inAdBreak\n      ? adPlayer.getOriginalMutedState()\n      : this.video.muted;\n    const envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);\n\n    const urlWithMacros = applyVastMacros(baseUrl, {\n      correlator: this.viewCorrelator,\n      streamCorrelator: this.streamCorrelator,\n      pod: this.podCounter > 0 ? this.podCounter : undefined,\n      podMaxAds: podParams.maxAds,\n      podMinDurationMs: podParams.minDurationMs,\n      podMaxDurationMs: podParams.maxDurationMs,\n      isCtv: envSignals.isCtv,\n      contentUrl: envSignals.contentUrl,\n      pageUrl:\n        !envSignals.isCtv && typeof window !== \"undefined\"\n          ? window.location.href\n          : undefined,\n      adWillPlayMuted,\n      adWillAutoPlay: !!this.config.autoplay,\n      appId: envSignals.appId,\n      appName: envSignals.appName,\n      sessionId: envSignals.sessionId,\n      deviceId: envSignals.deviceId,\n      deviceIdType: envSignals.deviceIdType,\n      limitAdTracking: envSignals.limitAdTracking,\n      deviceTypeHint: envSignals.deviceTypeHint,\n      adTest: this.config.adTest,\n      consent: this.consentSignals,\n    });\n\n    const finalUrl = palNonce.injectNonce(urlWithMacros);\n    console.log(\n      `[StormcloudVideoPlayer] Resolved optimized-pod request URL (pod=${this.podCounter}, pmad=${podParams.maxAds}, pmnd=${podParams.minDurationMs}, pmxd=${podParams.maxDurationMs ?? \"?\"}):`,\n      finalUrl\n    );\n    return finalUrl;\n  }\n\n  // --- Tracking ---\n\n  initializeTracking(): void {\n    sendInitialTracking(this.config.licenseKey, buildAnalyticsContext(this.config))\n      .then(() => {\n        this.heartbeatInterval = window.setInterval(() => {\n          this.sendHeartbeatIfNeeded();\n        }, 5000);\n      })\n      .catch((error) => {\n        if (this.debug) {\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, buildAnalyticsContext(this.config)).catch((error) => {\n        if (this.debug) {\n          console.warn(\n            \"[StormcloudVideoPlayer] Failed to send heartbeat:\",\n            error\n          );\n        }\n      });\n    }\n  }\n\n  destroyTracking(): void {\n    if (this.heartbeatInterval) {\n      clearInterval(this.heartbeatInterval);\n      this.heartbeatInterval = undefined;\n    }\n  }\n}\n","import type { AdController, StormcloudVideoPlayerConfig, Scte35Marker } from \"../types\";\n\nexport interface AdTimingCallbacks {\n  onAdStopTimerFired(): void;\n  onAdStartTimerFired(marker: Scte35Marker, cueKey: string | undefined): void;\n  onWatchdogTimeout(): void;\n  onFailsafeTimeout(): void;\n}\n\nexport class AdTimingService {\n  private adStopTimerId: number | undefined;\n  private adStartTimerId: number | undefined;\n  private adFailsafeTimerId: number | undefined;\n  private adRequestWatchdogId: number | undefined;\n  private adRequestWatchdogToken: number | null = null;\n  private adFailsafeToken: number | null = null;\n\n  ptsDriftEmaMs = 0;\n  expectedAdBreakDurationMs: number | undefined;\n  currentAdBreakStartWallClockMs: number | undefined;\n  scteAdBreakEndWallClockMs: number | undefined;\n  adBreakPlayedDurationMs: number = 0;\n  adBreakEpoch: number = 0;\n\n  adRequestTokenCounter = 0;\n  activeAdRequestToken: number | null = null;\n  currentAdIndex: number = 0;\n  totalAdsInBreak: number = 0;\n  totalAdRequestsInBreak: number = 0;\n  readonly maxTotalAdRequestsPerBreak: number = 10;\n  lastAdRequestTime: number = 0;\n  consecutiveFailures: number = 0;\n  readonly maxConsecutiveFailures: number = 5;\n  readonly minAdRequestIntervalMs: number = 3000;\n  readonly backoffBaseMs: number = 1000;\n  readonly maxBackoffMs: number = 15000;\n  private readonly defaultMinRemainingMsToStartAd: number = 4000;\n\n  failedVastUrls: Set<string> = new Set();\n  temporaryFailureUrls: Map<string, number> = new Map();\n  private readonly temporaryFailureCooldownMs: number = 30000;\n\n  private globalConsecutiveNoFills: number = 0;\n  private readonly globalNoFillThreshold: number = 3;\n  private globalNoFillCooldownUntil: number = 0;\n  private readonly globalNoFillBackoffBaseMs: number = 5000;\n  private readonly globalNoFillBackoffMaxMs: number = 60000;\n  private globalLastGamRequestTime: number = 0;\n  private readonly globalMinGamIntervalMs: number = 3000;\n\n  private config: StormcloudVideoPlayerConfig;\n  private video: HTMLVideoElement;\n  private callbacks: AdTimingCallbacks;\n\n  constructor(\n    config: StormcloudVideoPlayerConfig,\n    video: HTMLVideoElement,\n    callbacks: AdTimingCallbacks\n  ) {\n    this.config = config;\n    this.video = video;\n    this.callbacks = callbacks;\n  }\n\n  get debug(): boolean {\n    return !!this.config.debugAdTiming;\n  }\n\n  // --- Ad stop timer ---\n\n  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  clearAdStopTimer(): void {\n    if (this.adStopTimerId != null) {\n      clearTimeout(this.adStopTimerId);\n      this.adStopTimerId = undefined;\n    }\n  }\n\n  private ensureAdStoppedByTimer(): void {\n    this.adStopTimerId = undefined;\n    this.callbacks.onAdStopTimerFired();\n  }\n\n  // --- Ad start timer ---\n\n  scheduleAdStartIn(\n    delayMs: number,\n    marker: Scte35Marker = { type: \"start\" } as Scte35Marker,\n    cueKey?: string\n  ): void {\n    this.clearAdStartTimer();\n    const ms = Math.max(0, Math.floor(delayMs));\n    if (ms === 0) {\n      this.callbacks.onAdStartTimerFired(marker, cueKey);\n      return;\n    }\n    this.adStartTimerId = window.setTimeout(() => {\n      this.callbacks.onAdStartTimerFired(marker, cueKey);\n    }, ms) as unknown as number;\n  }\n\n  clearAdStartTimer(): void {\n    if (this.adStartTimerId != null) {\n      clearTimeout(this.adStartTimerId);\n      this.adStartTimerId = undefined;\n    }\n  }\n\n  // --- PTS drift ---\n\n  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  resolveScteBreakStartWallClockMs(marker: Scte35Marker): number {\n    const nowWallClockMs = Date.now();\n    if (typeof marker.ptsSeconds !== \"number\") {\n      return nowWallClockMs;\n    }\n\n    const nowMs = this.video.currentTime * 1000;\n    const estimatedCurrentPtsMs = nowMs - this.ptsDriftEmaMs;\n    const deltaMs = marker.ptsSeconds * 1000 - estimatedCurrentPtsMs;\n    if (!Number.isFinite(deltaMs)) {\n      return nowWallClockMs;\n    }\n\n    return nowWallClockMs + Math.floor(deltaMs);\n  }\n\n  // --- Duration boundary ---\n\n  setAdBreakDurationBoundary(durationMs: number | undefined): void {\n    this.expectedAdBreakDurationMs = durationMs;\n    if (\n      durationMs != null &&\n      this.currentAdBreakStartWallClockMs != null\n    ) {\n      this.scteAdBreakEndWallClockMs =\n        this.currentAdBreakStartWallClockMs + durationMs;\n    } else {\n      this.scteAdBreakEndWallClockMs = undefined;\n    }\n  }\n\n  scheduleAdStopAtBreakBoundary(): void {\n    if (this.expectedAdBreakDurationMs == null) {\n      return;\n    }\n    this.scheduleAdStopCountdown(this.getWallClockRemainingAdMs());\n  }\n\n  // --- Duration budget ---\n\n  getWallClockRemainingAdMs(): number {\n    const endWallClockMs = this.getAdBreakEndWallClockMs();\n    if (endWallClockMs != null) {\n      return Math.max(0, endWallClockMs - Date.now());\n    }\n    return 0;\n  }\n\n  getAdBreakEndWallClockMs(): number | undefined {\n    if (this.scteAdBreakEndWallClockMs != null) {\n      return this.scteAdBreakEndWallClockMs;\n    }\n    if (\n      this.expectedAdBreakDurationMs == null ||\n      this.currentAdBreakStartWallClockMs == null\n    ) {\n      return undefined;\n    }\n    return this.currentAdBreakStartWallClockMs + this.expectedAdBreakDurationMs;\n  }\n\n  getDurationBudgetRemainingMs(): number {\n    if (this.expectedAdBreakDurationMs == null) {\n      return 0;\n    }\n    return Math.max(0, this.expectedAdBreakDurationMs - this.adBreakPlayedDurationMs);\n  }\n\n  getLoadedAdDurationMs(adController: AdController): number {\n    const durationSec = adController.getLoadedAdDuration?.();\n    if (durationSec == null || durationSec <= 0) {\n      return 0;\n    }\n    return Math.round(durationSec * 1000);\n  }\n\n  adFitsRemainingBudget(durationMs: number): boolean {\n    if (durationMs <= 0) {\n      return true;\n    }\n    return durationMs <= this.getDurationBudgetRemainingMs();\n  }\n\n  logAdDurationDecision(\n    accepted: boolean,\n    durationMs: number,\n    adController: AdController\n  ): void {\n    if (!this.debug) {\n      return;\n    }\n    const remainingBudget = this.getDurationBudgetRemainingMs();\n    const adId = adController.getLoadedAdId?.() ?? \"unknown\";\n    if (accepted) {\n      console.log(\n        `[AD-DURATION] Accepted ad id=${adId}, duration=${durationMs}ms, budget remaining after play=${Math.max(0, remainingBudget - durationMs)}ms`\n      );\n    } else {\n      console.log(\n        `[AD-DURATION] Rejected ad id=${adId}, duration=${durationMs}ms exceeds remaining budget=${remainingBudget}ms — requesting another ad`\n      );\n    }\n  }\n\n  recordPlayedAdDuration(adController: AdController): void {\n    const durationMs = this.getLoadedAdDurationMs(adController);\n    if (durationMs <= 0) {\n      return;\n    }\n    this.adBreakPlayedDurationMs += durationMs;\n    if (this.debug) {\n      console.log(\n        `[AD-DURATION] Played ${durationMs}ms — total played=${this.adBreakPlayedDurationMs}ms / ${this.expectedAdBreakDurationMs ?? \"?\"}ms`\n      );\n    }\n  }\n\n  ensureLoadedAdFitsBudget(adController: AdController): boolean {\n    const durationMs = this.getLoadedAdDurationMs(adController);\n    const fits = this.adFitsRemainingBudget(durationMs);\n    this.logAdDurationDecision(fits, durationMs, adController);\n    return fits;\n  }\n\n  rejectLoadedAdForDuration(adController: AdController): void {\n    try {\n      adController.destroy();\n    } catch {}\n  }\n\n  markAdStarted(): void {\n    this.currentAdIndex++;\n    this.totalAdsInBreak = this.currentAdIndex;\n    this.totalAdRequestsInBreak++;\n    this.lastAdRequestTime = Date.now();\n  }\n\n  notePodAdStarted(): void {\n    this.currentAdIndex++;\n    this.totalAdsInBreak = this.currentAdIndex;\n  }\n\n  getRemainingAdMs(): number {\n    const wallClockRemaining = this.getWallClockRemainingAdMs();\n    const budgetRemaining = this.getDurationBudgetRemainingMs();\n    if (this.expectedAdBreakDurationMs == null) {\n      return wallClockRemaining;\n    }\n    return Math.min(wallClockRemaining, budgetRemaining);\n  }\n\n  getMinRemainingMsToStartAd(): number {\n    const configured = this.config.minRemainingMsToStartAd;\n    if (typeof configured === \"number\" && configured >= 0) {\n      return configured;\n    }\n    return this.defaultMinRemainingMsToStartAd;\n  }\n\n  hasTimeToStartAnotherAd(): boolean {\n    const minRemaining = this.getMinRemainingMsToStartAd();\n    return (\n      this.getWallClockRemainingAdMs() > minRemaining &&\n      this.getDurationBudgetRemainingMs() > minRemaining\n    );\n  }\n\n  // --- Circuit breaker ---\n\n  isTemporaryAdError(error: Error): boolean {\n    const message = error?.message?.toLowerCase() || \"\";\n\n    if (message.includes(\"no ads available\") || message.includes(\"no fill\") || message.includes(\"nofill\")) {\n      return true;\n    }\n    if (message.includes(\"timeout\")) {\n      return true;\n    }\n    if (message.includes(\"rate limit\") || message.includes(\"too many requests\")) {\n      return true;\n    }\n    if (message.includes(\"ad playback error\")) {\n      return true;\n    }\n    return false;\n  }\n\n  isUrlInCooldown(vastTagUrl: string): boolean {\n    const failureTime = this.temporaryFailureUrls.get(vastTagUrl);\n    if (failureTime == null) {\n      return false;\n    }\n\n    const elapsed = Date.now() - failureTime;\n    if (elapsed >= this.temporaryFailureCooldownMs) {\n      this.temporaryFailureUrls.delete(vastTagUrl);\n      return false;\n    }\n\n    return true;\n  }\n\n  cleanupTemporaryFailures(): void {\n    const now = Date.now();\n    for (const [url, timestamp] of this.temporaryFailureUrls) {\n      if (now - timestamp >= this.temporaryFailureCooldownMs) {\n        this.temporaryFailureUrls.delete(url);\n      }\n    }\n  }\n\n  isGamInCooldown(): boolean {\n    return Date.now() < this.globalNoFillCooldownUntil;\n  }\n\n  recordGamNoFill(): void {\n    this.globalConsecutiveNoFills++;\n\n    if (this.globalConsecutiveNoFills >= this.globalNoFillThreshold) {\n      const exponent = this.globalConsecutiveNoFills - this.globalNoFillThreshold;\n      const backoff = Math.min(\n        this.globalNoFillBackoffBaseMs * Math.pow(2, exponent),\n        this.globalNoFillBackoffMaxMs\n      );\n      this.globalNoFillCooldownUntil = Date.now() + backoff;\n\n      if (this.debug) {\n        console.log(\n          `[CIRCUIT-BREAKER] GAM cooldown activated: ${backoff}ms (${this.globalConsecutiveNoFills} consecutive no-fills)`\n        );\n      }\n    }\n  }\n\n  resetGamNoFillCounter(): void {\n    if (this.globalConsecutiveNoFills > 0 && this.debug) {\n      console.log(\n        `[CIRCUIT-BREAKER] Resetting no-fill counter (was ${this.globalConsecutiveNoFills})`\n      );\n    }\n    this.globalConsecutiveNoFills = 0;\n    this.globalNoFillCooldownUntil = 0;\n  }\n\n  async enforceGlobalRateLimit(): Promise<void> {\n    const now = Date.now();\n    const elapsed = now - this.globalLastGamRequestTime;\n    if (elapsed < this.globalMinGamIntervalMs) {\n      const waitMs = this.globalMinGamIntervalMs - elapsed;\n      if (this.debug) {\n        console.log(`[RATE-LIMIT] Waiting ${waitMs}ms before next GAM request`);\n      }\n      await new Promise(resolve => setTimeout(resolve, waitMs));\n    }\n    this.globalLastGamRequestTime = Date.now();\n  }\n\n  // --- Watchdog ---\n\n  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.callbacks.onWatchdogTimeout();\n    }, timeoutMs) as unknown as number;\n\n    this.logAdState(\"ad_request_watchdog_started\", { token, timeoutMs });\n  }\n\n  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  // --- Failsafe ---\n\n  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      });\n\n      this.callbacks.onFailsafeTimeout();\n    }, failsafeMs) as unknown as number;\n\n    this.logAdState(\"ad_failsafe_started\", { token, failsafeMs });\n  }\n\n  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  logAdState(event: string, extra: Record<string, unknown> = {}, adPlayer?: AdController, inAdBreak?: boolean, showAds?: boolean): void {\n    if (!this.debug) {\n      return;\n    }\n\n    console.log(\"[StormcloudVideoPlayer][AdState]\", {\n      event,\n      timestamp: new Date().toISOString(),\n      showAds: showAds ?? false,\n      adPlaying: adPlayer?.isAdPlaying() ?? false,\n      inAdBreak: inAdBreak ?? false,\n      activeAdRequestToken: this.activeAdRequestToken,\n      ...extra,\n    });\n  }\n\n  // --- Reset for ad break end ---\n\n  resetForBreakEnd(): void {\n    this.clearAdStopTimer();\n    this.clearAdStartTimer();\n    this.clearAdRequestWatchdog();\n    this.clearAdFailsafeTimer();\n    this.activeAdRequestToken = null;\n    this.expectedAdBreakDurationMs = undefined;\n    this.currentAdBreakStartWallClockMs = undefined;\n    this.scteAdBreakEndWallClockMs = undefined;\n    this.adBreakPlayedDurationMs = 0;\n    this.currentAdIndex = 0;\n    this.totalAdsInBreak = 0;\n    this.consecutiveFailures = 0;\n    this.globalConsecutiveNoFills = 0;\n    this.adBreakEpoch++;\n  }\n\n  destroy(): void {\n    this.clearAdStopTimer();\n    this.clearAdStartTimer();\n    this.clearAdFailsafeTimer();\n    this.clearAdRequestWatchdog();\n  }\n}\n","import type { AdController, Scte35Marker } from \"../types\";\nimport type { AdTimingService } from \"./AdTimingService\";\n\nexport interface AdPreloadPoolDeps {\n  debug: boolean;\n  createAdPlayer(continueLiveStreamDuringAds: boolean): AdController;\n  shouldContinueLiveStreamDuringAds(): boolean;\n  timing: AdTimingService;\n  generateVastUrlsWithCorrelators(baseUrl: string, count: number): string[];\n  isInAdBreak(): boolean;\n  getPendingAdBreak(): { marker: Scte35Marker; vastUrls: string[]; isFetching: boolean } | null;\n}\n\nexport class AdPreloadPool {\n  private pool: Array<{\n    vastUrl: string;\n    adController: AdController;\n    loadedAt: number;\n    isReady: boolean;\n    loadPromise: Promise<void>;\n    durationSeconds?: number;\n  }> = [];\n  private readonly maxPoolSize: number = 2;\n  private poolActive: boolean = false;\n  private loopRunning: boolean = false;\n\n  private deps: AdPreloadPoolDeps;\n\n  constructor(deps: AdPreloadPoolDeps) {\n    this.deps = deps;\n  }\n\n  get active(): boolean {\n    return this.poolActive;\n  }\n\n  set active(value: boolean) {\n    this.poolActive = value;\n  }\n\n  get isLoopRunning(): boolean {\n    return this.loopRunning;\n  }\n\n  startPreloadPool(\n    baseVastUrl: string,\n    initialUrls: string[],\n    startLoopImmediately: boolean = true\n  ): void {\n    if (this.poolActive) {\n      if (this.deps.debug) {\n        console.log(\"[PRELOAD-POOL] Already active, skipping duplicate start\");\n      }\n      return;\n    }\n\n    this.poolActive = true;\n\n    if (this.deps.debug) {\n      console.log(`[PRELOAD-POOL] Starting preload pool EARLY (target size: ${this.maxPoolSize})`);\n      console.log(`[PRELOAD-POOL] Ad break hasn't started yet, but preloading ads in advance`);\n    }\n\n    for (const url of initialUrls) {\n      if (this.pool.length < this.maxPoolSize) {\n        this.preloadAdIntoPool(url);\n      }\n    }\n\n    if (startLoopImmediately) {\n      this.preloadPoolLoop(baseVastUrl);\n    } else if (this.deps.debug) {\n      console.log(\n        \"[PRELOAD-POOL] Pre-break mode: preloaded once, waiting for SCTE start to continue fetching\"\n      );\n    }\n  }\n\n  private async preloadAdIntoPool(vastUrl: string): Promise<void> {\n    const timing = this.deps.timing;\n\n    if (timing.isGamInCooldown()) {\n      if (this.deps.debug) {\n        console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping preload\");\n      }\n      return;\n    }\n\n    if (\n      this.pool.some(entry => entry.vastUrl === vastUrl) ||\n      timing.failedVastUrls.has(vastUrl) ||\n      timing.isUrlInCooldown(vastUrl)\n    ) {\n      return;\n    }\n\n    if (this.pool.length >= this.maxPoolSize) {\n      return;\n    }\n\n    if (this.deps.debug) {\n      console.log(`[PRELOAD-POOL] Preloading ad into pool: ${vastUrl}`);\n    }\n\n    const epoch = timing.adBreakEpoch;\n    const loadPromise = (async () => {\n      let hasAdError = false;\n      let adErrorPayload: any = null;\n      let errorListenerCleanup: (() => void) | null = null;\n\n      try {\n        const continueLiveStreamDuringAds = this.deps.shouldContinueLiveStreamDuringAds();\n        const preloadAd = this.deps.createAdPlayer(continueLiveStreamDuringAds);\n        preloadAd.initialize();\n\n        const errorListener = (payload?: any) => {\n          hasAdError = true;\n          adErrorPayload = payload;\n        };\n        preloadAd.on(\"ad_error\", errorListener);\n        errorListenerCleanup = () => preloadAd.off(\"ad_error\", errorListener);\n\n        await timing.enforceGlobalRateLimit();\n        await preloadAd.requestAds(vastUrl);\n\n        preloadAd.pause();\n\n        await new Promise(resolve => setTimeout(resolve, 1500));\n\n        preloadAd.pause();\n\n        if (hasAdError) {\n          const isNoFill = adErrorPayload?.isNoFill ||\n                          adErrorPayload?.code === 303 ||\n                          adErrorPayload?.vastErrorCode === 303;\n\n          if (errorListenerCleanup) {\n            errorListenerCleanup();\n          }\n          preloadAd.destroy();\n\n          timing.recordGamNoFill();\n\n          if (isNoFill) {\n            if (this.deps.debug) {\n              console.log(`[PRELOAD-POOL] Ad preload returned no-fill: ${vastUrl}`);\n            }\n            timing.temporaryFailureUrls.set(vastUrl, Date.now());\n          } else {\n            if (this.deps.debug) {\n              console.log(`[PRELOAD-POOL] Ad preload failed with error: ${vastUrl}`, adErrorPayload);\n            }\n            if (adErrorPayload && !timing.isTemporaryAdError(adErrorPayload as Error)) {\n              timing.failedVastUrls.add(vastUrl);\n            } else {\n              timing.temporaryFailureUrls.set(vastUrl, Date.now());\n            }\n          }\n          return;\n        }\n\n        if (!this.poolActive || epoch !== timing.adBreakEpoch) {\n          if (this.deps.debug) {\n            console.log(\n              \"[PRELOAD-POOL] Discarding preloaded ad - break ended during fetch\"\n            );\n          }\n          if (errorListenerCleanup) {\n            errorListenerCleanup();\n          }\n          try {\n            preloadAd.destroy();\n          } catch {}\n          return;\n        }\n\n        const poolEntry: {\n          vastUrl: string;\n          adController: AdController;\n          loadedAt: number;\n          isReady: boolean;\n          loadPromise: Promise<void>;\n          durationSeconds?: number;\n        } = {\n          vastUrl,\n          adController: preloadAd,\n          loadedAt: Date.now(),\n          isReady: true,\n          loadPromise: Promise.resolve(),\n        };\n        const loadedDuration = preloadAd.getLoadedAdDuration?.();\n        if (loadedDuration != null && loadedDuration > 0) {\n          poolEntry.durationSeconds = loadedDuration;\n        }\n\n        const lateErrorListener = (payload?: any) => {\n          const index = this.pool.findIndex(entry => entry.vastUrl === vastUrl);\n          if (index >= 0) {\n            this.pool.splice(index, 1);\n            if (this.deps.debug) {\n              console.log(`[PRELOAD-POOL] Late error detected, removed from pool: ${vastUrl}`, payload);\n            }\n            try {\n              preloadAd.destroy();\n            } catch {}\n          }\n        };\n        preloadAd.on(\"ad_error\", lateErrorListener);\n\n        this.pool.push(poolEntry);\n\n        if (this.deps.debug) {\n          console.log(`[PRELOAD-POOL] Ad preloaded (no errors detected within timeout) (pool size: ${this.pool.length}/${this.maxPoolSize}, duration=${poolEntry.durationSeconds ?? \"?\"}s)`);\n        }\n\n        if (errorListenerCleanup) {\n          errorListenerCleanup();\n        }\n      } catch (error) {\n        if (errorListenerCleanup) {\n          errorListenerCleanup();\n        }\n\n        timing.recordGamNoFill();\n\n        if (this.deps.debug) {\n          console.warn(`[PRELOAD-POOL] Failed to preload ad: ${vastUrl}`, error);\n        }\n\n        if (error instanceof Error && !timing.isTemporaryAdError(error)) {\n          timing.failedVastUrls.add(vastUrl);\n        } else if (error instanceof Error && timing.isTemporaryAdError(error)) {\n          timing.temporaryFailureUrls.set(vastUrl, Date.now());\n        }\n      }\n    })();\n\n    loadPromise.catch(() => {});\n  }\n\n  async preloadPoolLoop(baseVastUrl: string): Promise<void> {\n    if (this.loopRunning) {\n      return;\n    }\n\n    this.loopRunning = true;\n    const epoch = this.deps.timing.adBreakEpoch;\n\n    if (this.deps.debug) {\n      console.log(\"[PRELOAD-POOL] Starting continuous preload loop\");\n    }\n\n    while (this.poolActive && epoch === this.deps.timing.adBreakEpoch) {\n      if (this.deps.timing.isGamInCooldown()) {\n        if (this.deps.debug) {\n          console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, stopping preload pool loop\");\n        }\n        break;\n      }\n\n      if (!this.deps.isInAdBreak() && this.pool.length >= this.maxPoolSize) {\n        await new Promise(resolve => setTimeout(resolve, 2000));\n        continue;\n      }\n\n      if (!this.deps.isInAdBreak() && this.deps.getPendingAdBreak() === null) {\n        if (this.deps.debug) {\n          console.log(\"[PRELOAD-POOL] Ad break cancelled, stopping preload pool\");\n        }\n        break;\n      }\n\n      while (this.pool.length < this.maxPoolSize) {\n        if (\n          !this.poolActive ||\n          epoch !== this.deps.timing.adBreakEpoch ||\n          this.deps.timing.isGamInCooldown()\n        ) {\n          break;\n        }\n\n        if (this.deps.isInAdBreak() && !this.deps.timing.hasTimeToStartAnotherAd()) {\n          if (this.deps.debug) {\n            console.log(\"[PRELOAD-POOL] Not enough ad break time left, stopping preload\");\n          }\n          break;\n        }\n\n        const newUrls = this.deps.generateVastUrlsWithCorrelators(baseVastUrl, 1);\n        const newUrl = newUrls[0];\n\n        if (newUrl && !this.deps.timing.failedVastUrls.has(newUrl) && !this.deps.timing.isUrlInCooldown(newUrl)) {\n          await this.preloadAdIntoPool(newUrl);\n        }\n\n        await new Promise(resolve => setTimeout(resolve, 1000));\n      }\n\n      await new Promise(resolve => setTimeout(resolve, 2000));\n    }\n\n    this.loopRunning = false;\n\n    if (this.deps.debug) {\n      console.log(\"[PRELOAD-POOL] Preload loop ended\");\n    }\n  }\n\n  getPreloadedAd(): { vastUrl: string; adController: AdController } | null {\n    if (this.pool.length === 0) {\n      return null;\n    }\n\n    const entry = this.pool.shift();\n    if (!entry || !entry.isReady) {\n      return null;\n    }\n\n    if (this.deps.debug) {\n      console.log(`[PRELOAD-POOL] Using preloaded ad from pool (${this.pool.length} remaining)`);\n    }\n\n    return {\n      vastUrl: entry.vastUrl,\n      adController: entry.adController,\n    };\n  }\n\n  stop(): void {\n    this.poolActive = false;\n    this.loopRunning = false;\n\n    for (const entry of this.pool) {\n      try {\n        entry.adController.destroy();\n      } catch (error) {\n        if (this.deps.debug) {\n          console.warn(\"[PRELOAD-POOL] Error destroying preloaded controller:\", error);\n        }\n      }\n    }\n\n    this.pool = [];\n\n    if (this.deps.debug) {\n      console.log(\"[PRELOAD-POOL] Preload pool stopped and cleaned up\");\n    }\n  }\n}\n","export class PlaceholderLayer {\n  private container: HTMLDivElement | undefined;\n  private debug: boolean;\n  private video: HTMLVideoElement;\n\n  constructor(video: HTMLVideoElement, debug: boolean) {\n    this.video = video;\n    this.debug = debug;\n  }\n\n  private ensureContainer(): void {\n    if (this.container) {\n      return;\n    }\n\n    const el = document.createElement(\"div\");\n    el.style.position = \"absolute\";\n    el.style.left = \"0\";\n    el.style.top = \"0\";\n    el.style.right = \"0\";\n    el.style.bottom = \"0\";\n    el.style.display = \"none\";\n    el.style.alignItems = \"center\";\n    el.style.justifyContent = \"center\";\n    el.style.pointerEvents = \"none\";\n    el.style.zIndex = \"5\";\n    el.style.backgroundColor = \"#000\";\n    el.style.transition = \"opacity 0.3s ease-in-out\";\n    el.style.opacity = \"0\";\n\n    if (!this.video.parentElement) {\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Video element has no parent for placeholder container\");\n      }\n      return;\n    }\n\n    this.video.parentElement.appendChild(el);\n    this.container = el;\n  }\n\n  show(): void {\n    this.ensureContainer();\n\n    if (!this.container) {\n      return;\n    }\n\n    if (!this.video.muted) {\n      this.video.muted = true;\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Muted video when showing placeholder\");\n      }\n    }\n\n    const wasHidden = this.container.style.display === \"none\" || this.container.style.opacity === \"0\";\n    if (wasHidden) {\n      this.container.style.transition = \"none\";\n    } else {\n      this.container.style.transition = \"opacity 0.3s ease-in-out\";\n    }\n\n    this.container.style.backgroundColor = \"#000\";\n    this.container.style.display = \"flex\";\n    this.container.offsetHeight;\n    this.container.style.opacity = \"1\";\n    this.container.style.pointerEvents = \"auto\";\n\n    if (wasHidden) {\n      requestAnimationFrame(() => {\n        if (this.container) {\n          this.container.style.transition = \"opacity 0.3s ease-in-out\";\n        }\n      });\n    }\n\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Showing placeholder layer (between content and ad layer)\");\n    }\n  }\n\n  hide(): void {\n    if (!this.container) {\n      return;\n    }\n\n    this.container.style.opacity = \"0\";\n    setTimeout(() => {\n      if (this.container) {\n        this.container.style.display = \"none\";\n        this.container.style.pointerEvents = \"none\";\n        this.container.style.backgroundColor = \"#000\";\n      }\n    }, 300);\n\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Hiding placeholder layer\");\n    }\n  }\n\n  destroy(): void {\n    if (this.container) {\n      if (this.container.parentElement) {\n        this.container.parentElement.removeChild(this.container);\n      }\n      this.container = undefined;\n    }\n  }\n}\n","import Hls from \"hls.js\";\nimport type {\n  StormcloudVideoPlayerConfig,\n  Scte35Marker,\n  Id3TagInfo,\n} from \"../types\";\nimport type { Scte35CueContext } from \"./playerTypes\";\nimport {\n  parseScte35FromId3,\n  parseScte35FromTsPackets,\n  normalizeFragmentPayload,\n  getFragmentStartSeconds,\n  parseCueOutDuration,\n  parseCueOutCont,\n  parseAttributeList,\n  toNumber,\n} from \"./Scte35Parser\";\nimport type { Scte35CueManager } from \"./Scte35CueManager\";\nimport type { AdTimingService } from \"./AdTimingService\";\n\nexport interface HlsEngineCallbacks {\n  onManifestParsed(isLive: boolean): Promise<void>;\n  onScte35Cue(marker: Scte35Marker, context: Scte35CueContext): void;\n  activatePendingCuesForFragment(frag: any): void;\n  onFatalDestroy(): void;\n  isInAdBreak(): boolean;\n  hasPendingAdBreak(): boolean;\n}\n\nexport class HlsEngine {\n  hls: Hls | undefined;\n  isLiveStream: boolean = false;\n  nativeHlsMode: boolean = false;\n  videoSrcProtection: string | null = null;\n\n  private bufferedSegmentsCount: number = 0;\n  private shouldAutoplayAfterBuffering: boolean = false;\n  private hasInitialBufferCompleted: boolean = false;\n\n  private readonly config: StormcloudVideoPlayerConfig;\n  private readonly video: HTMLVideoElement;\n  private readonly cueManager: Scte35CueManager;\n  private readonly timing: AdTimingService;\n  private readonly callbacks: HlsEngineCallbacks;\n\n  constructor(\n    config: StormcloudVideoPlayerConfig,\n    video: HTMLVideoElement,\n    cueManager: Scte35CueManager,\n    timing: AdTimingService,\n    callbacks: HlsEngineCallbacks\n  ) {\n    this.config = config;\n    this.video = video;\n    this.cueManager = cueManager;\n    this.timing = timing;\n    this.callbacks = callbacks;\n  }\n\n  private get debug(): boolean {\n    return !!this.config.debugAdTiming;\n  }\n\n  shouldUseNativeHls(getStreamType: () => \"hls\" | \"other\"): boolean {\n    const streamType = 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  async setupNativeHls(): Promise<void> {\n    this.nativeHlsMode = true;\n    this.videoSrcProtection = this.config.src;\n    this.video.src = this.config.src;\n\n    this.isLiveStream = this.config.isLiveStream ?? (this.config.lowLatencyMode ?? false);\n\n    if (this.debug) {\n      const adBehavior = this.isLiveStream\n        ? \"live (main video continues muted during ads)\"\n        : \"vod (main video pauses during ads)\";\n      console.log(\n        \"[StormcloudVideoPlayer] Using native HLS playback:\",\n        {\n          isLive: this.isLiveStream,\n          allowNativeHls: this.config.allowNativeHls,\n          adBehavior,\n        }\n      );\n    }\n\n    if (this.config.autoplay) {\n      await this.video.play()?.catch(() => {});\n    }\n  }\n\n  setupHls(): void {\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.config.isLiveStream ??\n        (this.hls?.levels?.some(\n          (level) =>\n            level?.details?.live === true || level?.details?.type === \"LIVE\"\n        ) ?? false);\n\n      await this.callbacks.onManifestParsed(this.isLiveStream);\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.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Waiting for\",\n          minSegments,\n          \"segments to buffer before playback\"\n        );\n      }\n\n      if (minSegments === 0 || !this.config.autoplay) {\n        this.hasInitialBufferCompleted = true;\n        if (this.config.autoplay) {\n          await this.video.play()?.catch(() => {});\n        }\n      }\n    });\n\n    this.hls.on(Hls.Events.LEVEL_LOADED, (_evt, data: any) => {\n      if (this.callbacks.isInAdBreak() || this.callbacks.hasPendingAdBreak()) {\n        return;\n      }\n\n      const details = data?.details;\n      if (!details || !details.fragments || details.fragments.length === 0) {\n        return;\n      }\n\n      const fragmentsToScan = Math.min(5, details.fragments.length);\n\n      for (let i = 0; i < fragmentsToScan; i++) {\n        const frag = details.fragments[i];\n        const tagList: any[] | undefined = frag?.tagList;\n\n        if (!Array.isArray(tagList)) continue;\n\n        for (const entry of tagList) {\n          let tag = \"\";\n          let value = \"\";\n\n          if (Array.isArray(entry)) {\n            tag = String(entry[0] ?? \"\");\n            value = String(entry[1] ?? \"\");\n          } else if (typeof entry === \"string\") {\n            const idx = entry.indexOf(\":\");\n            if (idx >= 0) {\n              tag = entry.substring(0, idx);\n              value = entry.substring(idx + 1);\n            } else {\n              tag = entry;\n            }\n          }\n\n          if (!tag) continue;\n\n          if (tag.includes(\"EXT-X-CUE-OUT\") || tag.includes(\"EXT-X-DATERANGE\")) {\n            const attrs = tag.includes(\"EXT-X-DATERANGE\")\n              ? parseAttributeList(value)\n              : {};\n            const hasScteOut = tag.includes(\"EXT-X-CUE-OUT\") ||\n              \"SCTE35-OUT\" in attrs ||\n              attrs[\"SCTE35-OUT\"] !== undefined;\n\n            if (hasScteOut) {\n              const durationSeconds = parseCueOutDuration(value);\n              const marker: Scte35Marker = {\n                type: \"start\",\n                ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n                raw: { tag, value, earlyDetection: true },\n              } as Scte35Marker;\n\n              if (this.debug) {\n                console.log(\"[StormcloudVideoPlayer] EARLY SCTE-35 DETECTION: Ad break marker found in fragment\", i, \"- starting pre-fetch (NOT playing yet)\");\n              }\n\n              this.callbacks.onScte35Cue(marker, {\n                ...this.cueManager.createScte35CueContext(\"manifest\", \"early\", frag),\n              });\n              return;\n            }\n          }\n        }\n      }\n    });\n\n    this.hls.on(Hls.Events.FRAG_BUFFERED, async (_evt, _data: any) => {\n      if (this.hasInitialBufferCompleted) {\n        return;\n      }\n\n      this.bufferedSegmentsCount++;\n      const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n\n      if (this.debug) {\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.debug) {\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.debug) {\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_LOADED, (_evt, data: any) => {\n      this.processFragmentScte35Payload(\n        data?.payload,\n        typeof data?.frag?.sn === \"number\" ? data.frag.sn : undefined,\n        getFragmentStartSeconds(data?.frag)\n      );\n    });\n\n    this.hls.on(Hls.Events.FRAG_DECRYPTED, (_evt, data: any) => {\n      this.processFragmentScte35Payload(\n        data?.payload,\n        typeof data?.frag?.sn === \"number\" ? data.frag.sn : undefined,\n        getFragmentStartSeconds(data?.frag)\n      );\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)) {\n        this.callbacks.activatePendingCuesForFragment(frag);\n        return;\n      }\n\n      for (const entry of tagList) {\n        let tag = \"\";\n        let value = \"\";\n        if (Array.isArray(entry)) {\n          tag = String(entry[0] ?? \"\");\n          value = String(entry[1] ?? \"\");\n        } else if (typeof entry === \"string\") {\n          const idx = entry.indexOf(\":\");\n          if (idx >= 0) {\n            tag = entry.substring(0, idx);\n            value = entry.substring(idx + 1);\n          } else {\n            tag = entry;\n            value = \"\";\n          }\n        }\n\n        if (!tag) continue;\n        if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n          const prog = 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.callbacks.onScte35Cue(marker, {\n            ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag),\n          });\n        } else if (tag.includes(\"EXT-X-CUE-OUT\")) {\n          const durationSeconds = parseCueOutDuration(value);\n          const marker: Scte35Marker = {\n            type: \"start\",\n            ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n            raw: { tag, value },\n          } as Scte35Marker;\n          this.callbacks.onScte35Cue(marker, {\n            ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag),\n          });\n        } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n          this.callbacks.onScte35Cue(\n            { type: \"end\", raw: { tag, value } },\n            {\n              ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag),\n            }\n          );\n        } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n          const attrs = 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 = 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.callbacks.onScte35Cue(marker, {\n              ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag),\n            });\n          }\n          if (hasScteIn) {\n            this.callbacks.onScte35Cue(\n              { type: \"end\", raw: { tag, value, attrs } },\n              {\n                ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag),\n              }\n            );\n          }\n        }\n      }\n      this.callbacks.activatePendingCuesForFragment(frag);\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.callbacks.onFatalDestroy();\n            break;\n        }\n      }\n    });\n\n    this.hls.attachMedia(this.video);\n  }\n\n  private onId3Tag(tag: Id3TagInfo): void {\n    if (typeof tag.ptsSeconds === \"number\") {\n      this.timing.updatePtsDrift(tag.ptsSeconds);\n    }\n    const marker = parseScte35FromId3(tag);\n    if (marker) {\n      this.callbacks.onScte35Cue(marker, {\n        source: \"id3\",\n        readiness: \"playback\",\n      });\n    }\n  }\n\n  private processFragmentScte35Payload(\n    payloadData: unknown,\n    fragmentSn?: number,\n    fragmentStartSeconds?: number\n  ): void {\n    const payload = normalizeFragmentPayload(payloadData);\n    if (!payload) {\n      return;\n    }\n\n    const markers = parseScte35FromTsPackets(\n      payload,\n      this.cueManager.tsScte35Pids,\n      this.cueManager.pmtPids,\n      this.cueManager.processedTsScte35Sections\n    );\n    markers.forEach((marker) => {\n      const context: Scte35CueContext = {\n        source: \"ts\",\n        readiness: \"early\",\n      };\n      if (fragmentSn !== undefined) {\n        context.fragmentSn = fragmentSn;\n      }\n      if (fragmentStartSeconds !== undefined) {\n        context.fragmentStartSeconds = fragmentStartSeconds;\n      }\n      this.callbacks.onScte35Cue(marker, context);\n    });\n  }\n\n  getLiveSyncPosition(): number | undefined {\n    const pos = this.hls?.liveSyncPosition;\n    return typeof pos === \"number\" && Number.isFinite(pos) ? pos : undefined;\n  }\n\n  destroy(): void {\n    this.hls?.destroy();\n    this.hls = undefined;\n  }\n}\n","import type { AdController } from \"../types\";\n\nexport function getAdAudioVolume(adPlayer: AdController): number {\n  return adPlayer.getOriginalMutedState() ? 0 : adPlayer.getOriginalVolume();\n}\n\nexport function toggleMute(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  debug: boolean\n): void {\n  if (adPlayer.isAdPlaying()) {\n    const newMutedState = !adPlayer.getOriginalMutedState();\n    const restoreVolume = adPlayer.getOriginalVolume() || 1;\n\n    adPlayer.updateOriginalMutedState(newMutedState, video.volume);\n    adPlayer.setAdVolume(newMutedState ? 0 : restoreVolume);\n\n    if (debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] Mute toggle during ad - immediately applied:\",\n        newMutedState\n      );\n    }\n  } else {\n    video.muted = !video.muted;\n    adPlayer.updateOriginalMutedState(video.muted, video.volume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] Muted:\", video.muted);\n    }\n  }\n}\n\nexport function toggleFullscreen(\n  video: HTMLVideoElement,\n  debug: boolean\n): Promise<void> {\n  return new Promise((resolve, reject) => {\n    if (!document.fullscreenElement) {\n      const container = 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 (debug) {\n            console.log(\"[StormcloudVideoPlayer] Entered fullscreen\");\n          }\n          resolve();\n        })\n        .catch((err) => {\n          if (debug) {\n            console.error(\"[StormcloudVideoPlayer] Fullscreen error:\", err);\n          }\n          reject(err);\n        });\n    } else {\n      document\n        .exitFullscreen()\n        .then(() => {\n          if (debug) {\n            console.log(\"[StormcloudVideoPlayer] Exited fullscreen\");\n          }\n          resolve();\n        })\n        .catch((err) => {\n          if (debug) {\n            console.error(\n              \"[StormcloudVideoPlayer] Exit fullscreen error:\",\n              err\n            );\n          }\n          reject(err);\n        });\n    }\n  });\n}\n\nexport function isMuted(\n  video: HTMLVideoElement,\n  adPlayer: AdController\n): boolean {\n  if (adPlayer.isAdPlaying()) {\n    return adPlayer.getOriginalMutedState();\n  }\n  return video.muted;\n}\n\nexport function setMuted(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  muted: boolean,\n  debug: boolean\n): void {\n  const adPlaying = adPlayer.isAdPlaying();\n\n  if (adPlaying && muted === video.muted) {\n    if (debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] setMuted reflective update during ad ignored\",\n        { muted }\n      );\n    }\n    return;\n  }\n\n  video.muted = muted;\n\n  if (adPlaying) {\n    adPlayer.updateOriginalMutedState(muted, video.volume);\n    adPlayer.setAdVolume(muted ? 0 : 1);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setMuted applied during ad\", {\n        muted,\n      });\n    }\n    return;\n  }\n\n  adPlayer.updateOriginalMutedState(muted, video.volume);\n  if (debug) {\n    console.log(\"[StormcloudVideoPlayer] setMuted called:\", muted);\n  }\n}\n\nexport function setVolume(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  volume: number,\n  debug: boolean\n): void {\n  const clampedVolume = Math.max(0, Math.min(1, volume));\n  const adPlaying = adPlayer.isAdPlaying();\n\n  if (adPlaying) {\n    adPlayer.setAdVolume(clampedVolume);\n    adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setVolume applied during ad\", {\n        volume: clampedVolume,\n      });\n    }\n  } else {\n    video.volume = clampedVolume;\n    video.muted = clampedVolume === 0;\n    adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setVolume called:\", clampedVolume);\n    }\n  }\n}\n\nexport function getVolume(\n  video: HTMLVideoElement,\n  adPlayer: AdController\n): number {\n  const adPlaying = adPlayer.isAdPlaying();\n  if (adPlaying) {\n    return adPlayer.getAdVolume();\n  }\n  return video.volume;\n}\n\nexport function isFullscreen(): boolean {\n  return !!document.fullscreenElement;\n}\n\nexport function resizePlayer(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  debug: boolean\n): void {\n  if (debug) {\n    console.log(\"[StormcloudVideoPlayer] Resizing player\");\n  }\n\n  if (adPlayer && adPlayer.isAdPlaying()) {\n    const width = video.clientWidth || 640;\n    const height = video.clientHeight || 480;\n\n    if (debug) {\n      console.log(\n        `[StormcloudVideoPlayer] Resizing ads manager to ${width}x${height}`\n      );\n    }\n\n    adPlayer.resize(width, height);\n  }\n}\n","import type {\n  StormcloudVideoPlayerConfig,\n  Scte35Marker,\n  AdController,\n} from \"../types\";\nimport {\n  buildAnalyticsContext,\n  sendAdLoadedTracking,\n  sendAdImpressionTracking,\n} from \"../utils/tracking\";\nimport type { AdTimingService } from \"./AdTimingService\";\nimport type { AdPreloadPool } from \"./AdPreloadPool\";\nimport type { AdConfigManager } from \"./AdConfigManager\";\nimport type { Scte35CueManager } from \"./Scte35CueManager\";\nimport type { PlaceholderLayer } from \"./PlaceholderLayer\";\nimport { getAdAudioVolume } from \"./PlayerControls\";\n\nexport interface AdBreakOrchestratorHost {\n  readonly config: StormcloudVideoPlayerConfig;\n  readonly video: HTMLVideoElement;\n  getAdPlayer(): AdController;\n  setAdPlayer(player: AdController): void;\n  createAdPlayer(continueLiveStreamDuringAds: boolean): AdController;\n  shouldContinueLiveStreamDuringAds(): boolean;\n  getLiveSyncPosition(): number | undefined;\n  generateVastUrls(baseUrl: string, count: number): string[];\n  generatePodVastUrl(baseUrl: string, breakDurationMs?: number): string;\n}\n\nexport class AdBreakOrchestrator {\n  inAdBreak = false;\n  showAds: boolean = false;\n  isShowingPlaceholder: boolean = false;\n  adDetectSentForCurrentBreak: boolean = false;\n\n  private continuousFetchingActive: boolean = false;\n  private continuousFetchLoopRunning = false;\n  adRequestQueue: string[] = [];\n  adPodQueue: string[] = [];\n  private readonly maxPlaceholderDurationMs: number = 5000;\n\n  pendingAdBreak: {\n    marker: Scte35Marker;\n    detectedAtFragmentSn?: number;\n    vastUrls: string[];\n    isFetching: boolean;\n    fetchStartTime?: number;\n  } | null = null;\n  prefetchTimerId: number | undefined;\n\n  private readonly host: AdBreakOrchestratorHost;\n  private readonly timing: AdTimingService;\n  private readonly preloadPool: AdPreloadPool;\n  private readonly adConfig: AdConfigManager;\n  private readonly cueManager: Scte35CueManager;\n  private readonly placeholder: PlaceholderLayer;\n\n  constructor(\n    host: AdBreakOrchestratorHost,\n    timing: AdTimingService,\n    preloadPool: AdPreloadPool,\n    adConfig: AdConfigManager,\n    cueManager: Scte35CueManager,\n    placeholder: PlaceholderLayer\n  ) {\n    this.host = host;\n    this.timing = timing;\n    this.preloadPool = preloadPool;\n    this.adConfig = adConfig;\n    this.cueManager = cueManager;\n    this.placeholder = placeholder;\n  }\n\n  private get debug(): boolean {\n    return !!this.host.config.debugAdTiming;\n  }\n\n  private get analyticsContext() {\n    return buildAnalyticsContext(this.host.config);\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  IMA event listeners\n  // ───────────────────────────────────────────────────────────────\n\n  private get optimizedPodsEnabled(): boolean {\n    return this.host.config.optimizedPods !== false;\n  }\n\n  attachImaEventListeners(): void {\n    const adPlayer = this.host.getAdPlayer();\n    adPlayer.on(\"pod_ad_started\", (payload?: any) => {\n      this.timing.notePodAdStarted();\n      if (this.debug) {\n        console.log(\n          `[POD] Playing pod ad ${payload?.index != null ? payload.index + 1 : \"?\"}/${payload?.total ?? \"?\"}`\n        );\n      }\n    });\n    adPlayer.on(\"all_ads_completed\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n\n      this.timing.consecutiveFailures = 0;\n\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] all_ads_completed event received - remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n\n      if (this.inAdBreak) {\n        if (this.timing.hasTimeToStartAnotherAd()) {\n          this.tryNextAvailableAdWithRateLimit();\n        } else {\n          this.handleAdPodComplete();\n        }\n      }\n    });\n    adPlayer.on(\"ad_error\", (errorPayload?: any) => {\n      let errorMessage = \"Ad playback failed\";\n\n      if (errorPayload) {\n        const errorCode = errorPayload.code || errorPayload.errorCode || \"unknown\";\n        const vastErrorCode = errorPayload.vastErrorCode;\n        const message = errorPayload.message || errorPayload.errorMessage || \"Unknown error\";\n        const cause = errorPayload.cause || errorPayload.innerError || errorPayload.error;\n\n        errorMessage = `Ad error: AdError ${errorCode}: ${message}`;\n\n        if (vastErrorCode && vastErrorCode !== \"N/A\" && vastErrorCode !== errorCode) {\n          errorMessage += ` (VAST Error Code: ${vastErrorCode})`;\n        }\n\n        if (cause) {\n          const causeMessage = typeof cause === \"string\" ? cause : (cause.message || String(cause));\n          errorMessage += `. Caused by: ${causeMessage}`;\n        }\n      }\n\n      console.error(\"[AD-ERROR]\", errorMessage, errorPayload || \"\");\n      this.handleAdFailure();\n    });\n    adPlayer.on(\"content_pause\", () => {\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = true;\n      this.timing.resetGamNoFillCounter();\n\n      if (this.inAdBreak && this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)\");\n        }\n      }\n\n      this.host.getAdPlayer().setAdVolume(getAdAudioVolume(this.host.getAdPlayer()));\n\n      if (this.isShowingPlaceholder) {\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Hiding placeholder - new ads starting\");\n        }\n        this.host.getAdPlayer().hidePlaceholder();\n        this.isShowingPlaceholder = false;\n      }\n    });\n    adPlayer.on(\"content_resume\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      if (!this.host.video.muted) {\n        this.host.video.muted = true;\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Muted video on content_resume (ad ended, gap between ads)\");\n        }\n      }\n\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = false;\n\n      if (!this.inAdBreak) {\n        return;\n      }\n\n      this.timing.consecutiveFailures = 0;\n\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n\n      if (this.debug) {\n        console.log(\n          `[CONTINUOUS-FETCH] content_resume event: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n\n      if (this.timing.hasTimeToStartAnotherAd()) {\n        this.tryNextAvailableAdWithRateLimit();\n      } else {\n        this.handleAdPodComplete();\n      }\n    });\n  }\n\n  recreateAdController(): void {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Recreating AdController for new ad\");\n    }\n\n    const shouldShowPlaceholder = this.inAdBreak && this.showAds;\n    const adPlayer = this.host.getAdPlayer();\n    if (shouldShowPlaceholder && adPlayer) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Showing placeholder before destroying old AdController\");\n      }\n      this.placeholder.show();\n      adPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n\n    const preservedMutedState = adPlayer.getOriginalMutedState();\n    const preservedVolumeState = adPlayer.getOriginalVolume();\n\n    if (adPlayer) {\n      try {\n        adPlayer.destroy();\n        this.host.video.muted = true;\n      } catch (error) {\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] Error destroying old AdController:\", error);\n        }\n      }\n    }\n\n    const continueLiveStreamDuringAds = this.host.shouldContinueLiveStreamDuringAds();\n    const newAdPlayer = this.host.createAdPlayer(continueLiveStreamDuringAds);\n    this.host.setAdPlayer(newAdPlayer);\n\n    newAdPlayer.initialize();\n    newAdPlayer.updateOriginalMutedState(preservedMutedState, preservedVolumeState);\n    this.attachImaEventListeners();\n\n    if (shouldShowPlaceholder) {\n      this.placeholder.show();\n      newAdPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n  }\n\n  clearPendingAdBreak(): void {\n    if (this.prefetchTimerId != null) {\n      clearTimeout(this.prefetchTimerId);\n      this.prefetchTimerId = undefined;\n    }\n    this.pendingAdBreak = null;\n    this.cueManager.pendingScte35CueKey = undefined;\n    this.adConfig.podAssignedByPrefetch = false;\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Ad break start\n  // ───────────────────────────────────────────────────────────────\n\n  async handleAdStart(_marker: Scte35Marker): Promise<void> {\n    const scheduled = this.adConfig.findCurrentOrNextBreak(\n      this.host.video.currentTime * 1000\n    );\n    if (scheduled) {\n      this.adConfig.consumedVmapBreakIds.add(this.adConfig.getAdBreakKey(scheduled));\n    }\n    const tags = this.adConfig.selectVastTagsForBreak(scheduled);\n\n    let baseVastUrl: string;\n\n    if (tags && tags.length > 0 && tags[0]) {\n      baseVastUrl = tags[0];\n    } else if (this.adConfig.apiVastTagUrl) {\n      baseVastUrl = this.adConfig.apiVastTagUrl;\n    } else {\n      this.clearPendingAdBreak();\n      return;\n    }\n\n    const adBreakDurationMs =\n      _marker.durationSeconds != null\n        ? _marker.durationSeconds * 1000\n        : scheduled?.durationMs;\n\n    if (this.debug) {\n      const mode = this.host.config.isLiveStream ? \"LIVE\" : \"VOD\";\n      console.log(\n        `[CONTINUOUS-FETCH] ${mode} MODE: Target duration=${adBreakDurationMs}ms`\n      );\n    }\n\n    this.timing.failedVastUrls.clear();\n    this.timing.temporaryFailureUrls.clear();\n    this.timing.consecutiveFailures = 0;\n    this.continuousFetchingActive = true;\n    this.isShowingPlaceholder = false;\n    this.timing.totalAdRequestsInBreak = 0;\n\n    if (this.adConfig.podAssignedByPrefetch) {\n      this.adConfig.podAssignedByPrefetch = false;\n    } else {\n      this.adConfig.beginNewAdPod();\n    }\n\n    const currentMuted = this.host.video.muted;\n    const currentVolume = this.host.video.volume;\n    this.host.getAdPlayer().updateOriginalMutedState(currentMuted, currentVolume);\n\n    this.inAdBreak = true;\n    this.timing.adBreakPlayedDurationMs = 0;\n    this.timing.currentAdIndex = 0;\n    this.timing.totalAdsInBreak = 0;\n    this.adPodQueue = [];\n    this.showAds = false;\n\n    if (\n      this.timing.expectedAdBreakDurationMs == null &&\n      adBreakDurationMs != null\n    ) {\n      this.timing.expectedAdBreakDurationMs = adBreakDurationMs;\n    }\n\n    if (this.optimizedPodsEnabled) {\n      const podPlayed = await this.startOptimizedPod(\n        baseVastUrl,\n        adBreakDurationMs,\n        currentMuted,\n        currentVolume\n      );\n      if (podPlayed) {\n        return;\n      }\n      if (this.debug) {\n        console.log(\"[POD] Optimized pod unavailable, falling back to sequential single-ad path\");\n      }\n    }\n\n    let firstAdUrl: string | undefined;\n    let usePreloadedAd = false;\n    let preloadedController: AdController | undefined;\n\n    const preloaded = this.preloadPool.getPreloadedAd();\n    if (preloaded) {\n      firstAdUrl = preloaded.vastUrl;\n      preloadedController = preloaded.adController;\n      usePreloadedAd = true;\n\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: firstAdUrl, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Using preloaded ad from pool (preloaded in advance, ready immediately!)\");\n      }\n    } else if (this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0) {\n      this.adRequestQueue = [...this.pendingAdBreak.vastUrls];\n      firstAdUrl = this.adRequestQueue.shift();\n\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Pool empty, using prefetched URLs (${this.adRequestQueue.length + 1} available)`);\n      }\n\n      this.clearPendingAdBreak();\n    } else {\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Generating new ad URLs...\");\n      }\n\n      const firstAdUrlArray = this.host.generateVastUrls(baseVastUrl, 1);\n      firstAdUrl = firstAdUrlArray[0];\n      this.adRequestQueue = [];\n    }\n\n    if (!firstAdUrl) {\n      if (this.debug) {\n        console.warn(\"[CONTINUOUS-FETCH] Failed to get first ad URL\");\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] First VAST URL:\", firstAdUrl);\n    }\n\n    try {\n      if (usePreloadedAd && preloadedController) {\n        if (!this.timing.ensureLoadedAdFitsBudget(preloadedController)) {\n          this.timing.rejectLoadedAdForDuration(preloadedController);\n          this.startContinuousFetching(baseVastUrl);\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n\n        const adPlayer = this.host.getAdPlayer();\n        const preservedMuted = adPlayer.getOriginalMutedState();\n        const preservedVolume = adPlayer.getOriginalVolume();\n        adPlayer.destroy();\n        this.host.video.muted = true;\n        this.host.setAdPlayer(preloadedController);\n        preloadedController.updateOriginalMutedState(preservedMuted, preservedVolume);\n\n        this.attachImaEventListeners();\n\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] Using preloaded ad, resuming and starting playback immediately (no request delay!)\");\n        }\n\n        preloadedController.resume();\n\n        this.timing.consecutiveFailures = 0;\n        this.startContinuousFetching(baseVastUrl);\n\n        if (!this.preloadPool.active) {\n          this.preloadPool.active = true;\n        }\n        if (!this.preloadPool.isLoopRunning) {\n          this.preloadPool.preloadPoolLoop(baseVastUrl);\n        }\n\n        await preloadedController.play();\n        this.timing.markAdStarted();\n\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n\n        const adVolume = currentMuted ? 0 : currentVolume;\n        preloadedController.setAdVolume(adVolume);\n      } else {\n        const adPlayer = this.host.getAdPlayer();\n        await this.timing.enforceGlobalRateLimit();\n        this.timing.lastAdRequestTime = Date.now();\n        await adPlayer.requestAds(firstAdUrl);\n        sendAdLoadedTracking(\n          this.host.config.licenseKey,\n          { source: \"hls\", vastUrl: firstAdUrl, timestamp: new Date().toISOString() },\n          this.analyticsContext\n        ).catch(() => {});\n\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] First ad request successful, starting playback\");\n        }\n\n        if (!this.timing.ensureLoadedAdFitsBudget(adPlayer)) {\n          this.timing.rejectLoadedAdForDuration(adPlayer);\n          this.recreateAdController();\n          this.startContinuousFetching(baseVastUrl);\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n\n        this.timing.consecutiveFailures = 0;\n        this.startContinuousFetching(baseVastUrl);\n\n        if (!this.preloadPool.active) {\n          this.preloadPool.startPreloadPool(baseVastUrl, []);\n        }\n\n        await adPlayer.play();\n        this.timing.markAdStarted();\n\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n\n        const adVolume = currentMuted ? 0 : currentVolume;\n        adPlayer.setAdVolume(adVolume);\n      }\n    } catch (error) {\n      if (this.debug) {\n        console.warn(\"[CONTINUOUS-FETCH] First ad request failed:\", error);\n      }\n\n      if (!usePreloadedAd) {\n        const fallbackPreloaded = this.preloadPool.getPreloadedAd();\n        if (fallbackPreloaded) {\n          if (this.debug) {\n            console.log(\"[CONTINUOUS-FETCH] First ad failed, using preloaded fallback\");\n          }\n\n          try {\n            if (!this.timing.ensureLoadedAdFitsBudget(fallbackPreloaded.adController)) {\n              this.timing.rejectLoadedAdForDuration(fallbackPreloaded.adController);\n              this.startContinuousFetching(baseVastUrl);\n              await this.tryNextAvailableAdWithRateLimit();\n              return;\n            }\n\n            this.swapToPreloadedAdPlayer(fallbackPreloaded.adController);\n\n            this.timing.consecutiveFailures = 0;\n            this.startContinuousFetching(baseVastUrl);\n\n            if (!this.preloadPool.active) {\n              this.preloadPool.active = true;\n              this.preloadPool.preloadPoolLoop(baseVastUrl);\n            }\n\n            const ap = this.host.getAdPlayer();\n            await ap.play();\n            this.timing.markAdStarted();\n\n            if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n              this.timing.scheduleAdStopAtBreakBoundary();\n            }\n\n            const adVolume = currentMuted ? 0 : currentVolume;\n            ap.setAdVolume(adVolume);\n\n            return;\n          } catch (fallbackError) {\n            if (this.debug) {\n              console.warn(\"[CONTINUOUS-FETCH] Preloaded fallback also failed:\", fallbackError);\n            }\n          }\n        }\n      }\n\n      if (this.timing.isTemporaryAdError(error as Error)) {\n        this.timing.temporaryFailureUrls.set(firstAdUrl, Date.now());\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] First ad had temporary error (no-fill) - will try alternatives\");\n        }\n      } else {\n        this.timing.failedVastUrls.add(firstAdUrl);\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] First ad had permanent error - URL blacklisted\");\n        }\n      }\n      this.timing.consecutiveFailures++;\n\n      this.startContinuousFetching(baseVastUrl);\n      await this.tryNextAvailableAdWithRateLimit();\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Optimized pod (single multi-ad request)\n  // ───────────────────────────────────────────────────────────────\n\n  private async startOptimizedPod(\n    baseVastUrl: string,\n    breakDurationMs: number | undefined,\n    currentMuted: boolean,\n    currentVolume: number\n  ): Promise<boolean> {\n    let podUrl: string | undefined;\n    if (this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0) {\n      podUrl = this.pendingAdBreak.vastUrls[0];\n      this.clearPendingAdBreak();\n    } else {\n      podUrl = this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);\n    }\n\n    if (!podUrl) {\n      return false;\n    }\n\n    this.continuousFetchingActive = false;\n\n    this.recreateAdController();\n\n    const adPlayer = this.host.getAdPlayer();\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      await adPlayer.requestAds(podUrl);\n      this.timing.clearAdRequestWatchdog();\n\n      if (this.timing.activeAdRequestToken !== requestToken) {\n        return true;\n      }\n\n      const podCount = adPlayer.getPodAdCount?.() ?? 1;\n      if (podCount < 1) {\n        return false;\n      }\n\n      if (this.debug) {\n        console.log(\n          podCount === 1\n            ? \"[POD] Response contained a single ad; playing it and enabling sequential top-up\"\n            : `[POD] Optimized pod returned ${podCount} ads; playing pod in one controller`\n        );\n      }\n\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: podUrl, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      this.timing.startAdFailsafeTimer(requestToken);\n      await adPlayer.play();\n      this.timing.markAdStarted();\n\n      if (\n        this.timing.expectedAdBreakDurationMs != null &&\n        this.timing.getAdBreakEndWallClockMs() == null\n      ) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n      }\n\n      adPlayer.setAdVolume(currentMuted ? 0 : currentVolume);\n      this.timing.consecutiveFailures = 0;\n\n      if (podCount === 1) {\n        this.continuousFetchingActive = true;\n        this.startContinuousFetching(baseVastUrl);\n        if (!this.preloadPool.active) {\n          this.preloadPool.startPreloadPool(baseVastUrl, []);\n        }\n      }\n\n      return true;\n    } catch (error) {\n      this.timing.clearAdRequestWatchdog();\n      this.timing.clearAdFailsafeTimer();\n      if (this.timing.activeAdRequestToken === requestToken) {\n        this.timing.activeAdRequestToken = null;\n      }\n      if (this.debug) {\n        console.warn(\"[POD] Optimized pod request/play failed:\", error);\n      }\n\n      if (this.timing.isTemporaryAdError(error as Error)) {\n        this.timing.temporaryFailureUrls.set(podUrl, Date.now());\n      }\n\n      this.continuousFetchingActive = true;\n      this.recreateAdController();\n      return false;\n    }\n  }\n\n  private swapToPreloadedAdPlayer(preloadedController: AdController): void {\n    const adPlayer = this.host.getAdPlayer();\n    const preservedMuted = adPlayer.getOriginalMutedState();\n    const preservedVolume = adPlayer.getOriginalVolume();\n    adPlayer.destroy();\n    this.host.video.muted = true;\n    this.host.setAdPlayer(preloadedController);\n    this.attachImaEventListeners();\n    preloadedController.updateOriginalMutedState(preservedMuted, preservedVolume);\n    preloadedController.resume();\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Continuous fetching\n  // ───────────────────────────────────────────────────────────────\n\n  private startContinuousFetching(baseVastUrl: string): void {\n    if (!this.continuousFetchingActive) {\n      return;\n    }\n\n    if (this.continuousFetchLoopRunning) {\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Fetch loop already running, skipping duplicate start\");\n      }\n      return;\n    }\n\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] Starting continuous ad fetching loop\");\n    }\n\n    this.continuousFetchLoopRunning = true;\n    this.continuousFetchLoop(baseVastUrl);\n  }\n\n  private async continuousFetchLoop(baseVastUrl: string): Promise<void> {\n    const epoch = this.timing.adBreakEpoch;\n    while (\n      this.continuousFetchingActive &&\n      this.inAdBreak &&\n      epoch === this.timing.adBreakEpoch\n    ) {\n      const remaining = Math.min(\n        this.timing.getWallClockRemainingAdMs(),\n        this.timing.getDurationBudgetRemainingMs()\n      );\n\n      if (remaining <= this.timing.getMinRemainingMsToStartAd()) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Not enough ad break time left (wall=${this.timing.getWallClockRemainingAdMs()}ms, budget=${this.timing.getDurationBudgetRemainingMs()}ms), stopping URL generation`);\n        }\n        break;\n      }\n\n      if (this.timing.isGamInCooldown()) {\n        if (this.debug) {\n          console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, stopping URL generation\");\n        }\n        break;\n      }\n\n      if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), stopping URL generation`);\n        }\n        break;\n      }\n\n      if (this.timing.totalAdRequestsInBreak >= this.timing.maxTotalAdRequestsPerBreak) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Maximum ad requests reached (${this.timing.maxTotalAdRequestsPerBreak}), stopping`);\n        }\n        break;\n      }\n\n      const maxQueueSize = 5;\n      if (this.adRequestQueue.length >= maxQueueSize) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] URL queue full (${this.adRequestQueue.length}), waiting...`);\n        }\n        await new Promise(resolve => setTimeout(resolve, 1000));\n        continue;\n      }\n\n      const newAdUrl = this.host.generateVastUrls(baseVastUrl, 1)[0];\n\n      if (!newAdUrl || this.timing.failedVastUrls.has(newAdUrl) || this.timing.isUrlInCooldown(newAdUrl)) {\n        await new Promise(resolve => setTimeout(resolve, 500));\n        continue;\n      }\n\n      if (this.debug) {\n        const queuedUrlsPreview = [...this.adRequestQueue, newAdUrl];\n        console.log(\n          `[CONTINUOUS-FETCH] Queued VAST URL (queue size: ${queuedUrlsPreview.length})`,\n          { queuedUrls: queuedUrlsPreview }\n        );\n      }\n\n      this.adRequestQueue.push(newAdUrl);\n\n      const generationDelay = this.timing.consecutiveFailures > 0\n        ? Math.min(1000 * Math.pow(2, this.timing.consecutiveFailures), 5000)\n        : 500;\n      await new Promise(resolve => setTimeout(resolve, generationDelay));\n    }\n\n    this.continuousFetchLoopRunning = false;\n\n    if (this.debug) {\n      console.log(\n        `[CONTINUOUS-FETCH] URL generation loop ended (queued: ${this.adRequestQueue.length})`,\n        this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n      );\n    }\n  }\n\n  stopContinuousFetching(): void {\n    this.continuousFetchingActive = false;\n    this.continuousFetchLoopRunning = false;\n\n    this.placeholder.hide();\n\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] Stopping continuous ad fetching\");\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Ad iteration\n  // ───────────────────────────────────────────────────────────────\n\n  async tryNextAvailableAdWithRateLimit(): Promise<void> {\n    if (!this.inAdBreak) {\n      return;\n    }\n\n    const epoch = this.timing.adBreakEpoch;\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), ending ad break gracefully`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    const backoffMultiplier = Math.pow(2, this.timing.consecutiveFailures);\n    const backoffDelay = Math.min(this.timing.backoffBaseMs * backoffMultiplier, this.timing.maxBackoffMs);\n    const effectiveMinInterval = this.timing.minAdRequestIntervalMs + (this.timing.consecutiveFailures > 0 ? backoffDelay : 0);\n\n    const timeSinceLastRequest = Date.now() - this.timing.lastAdRequestTime;\n    if (timeSinceLastRequest < effectiveMinInterval) {\n      const waitTime = effectiveMinInterval - timeSinceLastRequest;\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Rate limiting: waiting ${waitTime}ms before next request (backoff: ${this.timing.consecutiveFailures} failures)`);\n      }\n      await new Promise(resolve => setTimeout(resolve, waitTime));\n    }\n\n    if (!this.inAdBreak || epoch !== this.timing.adBreakEpoch) {\n      return;\n    }\n\n    return this.tryNextAvailableAd(0);\n  }\n\n  private async tryNextAvailableAd(retryCount: number = 0): Promise<void> {\n    if (!this.inAdBreak) {\n      return;\n    }\n\n    const remaining = this.timing.getRemainingAdMs();\n\n    if (!this.timing.hasTimeToStartAnotherAd()) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Not enough time remaining (${remaining}ms) to start another ad, ending ad break`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) {\n        console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, ending ad break gracefully\");\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), ending ad break`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    this.timing.cleanupTemporaryFailures();\n\n    const preloaded = this.preloadPool.getPreloadedAd();\n    if (preloaded) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Using preloaded ad from pool`);\n      }\n\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: preloaded.vastUrl, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      try {\n        if (!this.timing.ensureLoadedAdFitsBudget(preloaded.adController)) {\n          this.timing.rejectLoadedAdForDuration(preloaded.adController);\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n\n        this.swapToPreloadedAdPlayer(preloaded.adController);\n\n        const ap = this.host.getAdPlayer();\n        await ap.play();\n        this.timing.markAdStarted();\n\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n\n        ap.setAdVolume(getAdAudioVolume(ap));\n\n        this.timing.consecutiveFailures = 0;\n        return;\n      } catch (error) {\n        if (this.debug) {\n          console.warn(\"[CONTINUOUS-FETCH] Preloaded ad failed to play:\", error);\n        }\n      }\n    }\n\n    while (this.adRequestQueue.length > 0) {\n      const nextAdUrl = this.adRequestQueue.shift();\n\n      if (!nextAdUrl) continue;\n\n      if (this.timing.failedVastUrls.has(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping permanently-failed URL, trying next...\");\n        continue;\n      }\n\n      if (this.timing.isUrlInCooldown(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping URL in cooldown (recent no-fill), trying next...\");\n        continue;\n      }\n\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Requesting next ad via HLS ad player (${this.timing.currentAdIndex + 1}, ${this.adRequestQueue.length} remaining in queue)`);\n      }\n\n      try {\n        await this.playSingleAd(nextAdUrl);\n        this.timing.consecutiveFailures = 0;\n      } catch (error) {\n        const errorMessage = (error as Error).message;\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Ad request failed:\", errorMessage);\n\n        if (errorMessage.includes(\"ad_duration_exceeds_budget\")) {\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n\n        if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n          this.timing.consecutiveFailures++;\n        }\n\n        await this.tryNextAvailableAdWithRateLimit();\n      }\n      return;\n    }\n\n    const maxRetries = 3;\n    if (this.continuousFetchingActive && retryCount < maxRetries && remaining > 2000) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Queue empty, waiting for URLs... (${retryCount + 1}/${maxRetries})`);\n      }\n      await new Promise(resolve => setTimeout(resolve, 500));\n      await this.tryNextAvailableAd(retryCount + 1);\n      return;\n    }\n\n    if (!this.isShowingPlaceholder && remaining > 1000) {\n      this.showPlaceholderAndWaitForAds();\n    } else {\n      if (this.debug) console.log(\"[CONTINUOUS-FETCH] No more ads available, ending ad break\");\n      this.handleAdPodComplete();\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Single ad playback\n  // ───────────────────────────────────────────────────────────────\n\n  async playSingleAd(vastTagUrl: string): Promise<void> {\n    const adPlayer = this.host.getAdPlayer();\n    if (adPlayer.isAdPlaying()) return;\n\n    if (this.timing.failedVastUrls.has(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping permanently-failed VAST URL:\", vastTagUrl);\n      throw new Error(\"VAST URL permanently failed\");\n    }\n\n    if (this.timing.isUrlInCooldown(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping URL in cooldown (recent no-fill):\", vastTagUrl);\n      throw new Error(\"VAST URL in cooldown after no-fill\");\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.warn(\"[AD-ERROR] Too many consecutive failures, not requesting more ads\");\n      throw new Error(\"Too many consecutive failures\");\n    }\n\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) console.warn(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping ad request\");\n      throw new Error(\"GAM in cooldown\");\n    }\n\n    this.recreateAdController();\n\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      const ap = this.host.getAdPlayer();\n      await ap.requestAds(vastTagUrl);\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: vastTagUrl, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      this.timing.clearAdRequestWatchdog();\n\n      if (this.timing.activeAdRequestToken !== requestToken) return;\n\n      if (!this.timing.ensureLoadedAdFitsBudget(ap)) {\n        this.timing.rejectLoadedAdForDuration(ap);\n        this.recreateAdController();\n        throw new Error(\"ad_duration_exceeds_budget\");\n      }\n\n      try {\n        this.timing.startAdFailsafeTimer(requestToken);\n        await ap.play();\n        this.timing.markAdStarted();\n\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n\n        ap.setAdVolume(getAdAudioVolume(ap));\n        this.timing.consecutiveFailures = 0;\n        this.timing.temporaryFailureUrls.delete(vastTagUrl);\n      } catch (playError) {\n        if (this.debug) console.error(\"[AD-ERROR] Failed to play ad:\", playError);\n\n        const preloadedFallback = this.preloadPool.getPreloadedAd();\n        if (preloadedFallback) {\n          if (this.debug) console.log(\"[AD-ERROR] Play failed, trying preloaded fallback ad\");\n          try {\n            if (!this.timing.ensureLoadedAdFitsBudget(preloadedFallback.adController)) {\n              this.timing.rejectLoadedAdForDuration(preloadedFallback.adController);\n              throw playError;\n            }\n            this.timing.clearAdFailsafeTimer();\n            this.swapToPreloadedAdPlayer(preloadedFallback.adController);\n            this.timing.consecutiveFailures = 0;\n            const fbAp = this.host.getAdPlayer();\n            await fbAp.play();\n            this.timing.markAdStarted();\n            if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n              this.timing.scheduleAdStopAtBreakBoundary();\n            }\n            fbAp.setAdVolume(getAdAudioVolume(fbAp));\n            return;\n          } catch (fallbackError) {\n            if (this.debug) console.warn(\"[AD-ERROR] Preloaded fallback also failed:\", fallbackError);\n          }\n        }\n\n        if (this.timing.isTemporaryAdError(playError as Error)) {\n          this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());\n          if (this.debug) console.log(\"[AD-ERROR] Temporary play error - URL can be retried after cooldown\");\n        } else {\n          this.timing.failedVastUrls.add(vastTagUrl);\n          if (this.debug) console.log(\"[AD-ERROR] Permanent play error - URL blacklisted\");\n        }\n\n        this.timing.clearAdFailsafeTimer();\n        if (this.timing.activeAdRequestToken === requestToken) {\n          this.timing.activeAdRequestToken = null;\n        }\n        throw playError;\n      }\n    } catch (error) {\n      const errorMessage = (error as Error)?.message || \"\";\n      if (this.debug) console.error(\"[AD-ERROR] Ad request failed:\", errorMessage);\n\n      const preloadedFallback = this.preloadPool.getPreloadedAd();\n      if (preloadedFallback) {\n        if (this.debug) console.log(\"[AD-ERROR] Request failed, trying preloaded fallback ad\");\n        try {\n          if (!this.timing.ensureLoadedAdFitsBudget(preloadedFallback.adController)) {\n            this.timing.rejectLoadedAdForDuration(preloadedFallback.adController);\n            throw error;\n          }\n          this.timing.clearAdRequestWatchdog();\n          this.timing.clearAdFailsafeTimer();\n          this.swapToPreloadedAdPlayer(preloadedFallback.adController);\n          this.timing.consecutiveFailures = 0;\n          const fbAp = this.host.getAdPlayer();\n          await fbAp.play();\n          this.timing.markAdStarted();\n          fbAp.setAdVolume(getAdAudioVolume(fbAp));\n          return;\n        } catch (fallbackError) {\n          if (this.debug) console.warn(\"[AD-ERROR] Preloaded fallback also failed:\", fallbackError);\n        }\n      }\n\n      if (this.timing.isTemporaryAdError(error as Error)) {\n        this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());\n        if (this.debug) console.log(\"[AD-ERROR] Temporary error (no-fill/timeout) - URL can be retried after cooldown\");\n      } else {\n        this.timing.failedVastUrls.add(vastTagUrl);\n        if (this.debug) console.log(\"[AD-ERROR] Permanent error - URL blacklisted:\", errorMessage);\n      }\n\n      this.timing.clearAdRequestWatchdog();\n      this.timing.clearAdFailsafeTimer();\n      if (this.timing.activeAdRequestToken === requestToken) {\n        this.timing.activeAdRequestToken = null;\n      }\n      throw error;\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Placeholder wait\n  // ───────────────────────────────────────────────────────────────\n\n  private async showPlaceholderAndWaitForAds(): Promise<void> {\n    const remaining = this.timing.getRemainingAdMs();\n    const waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);\n\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping placeholder wait\");\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping placeholder - too many consecutive failures\");\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (waitTime < 1000) {\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.debug) {\n      console.log(`[CONTINUOUS-FETCH] Showing placeholder for ${waitTime}ms while waiting for ad URLs`);\n    }\n\n    this.isShowingPlaceholder = true;\n    this.host.getAdPlayer().showPlaceholder();\n\n    const checkInterval = 300;\n    const maxChecks = Math.floor(waitTime / checkInterval);\n\n    for (let i = 0; i < maxChecks; i++) {\n      await new Promise(resolve => setTimeout(resolve, checkInterval));\n\n      if (!this.inAdBreak) return;\n\n      if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Too many failures during placeholder wait\");\n        break;\n      }\n\n      if (!this.timing.hasTimeToStartAnotherAd()) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Not enough time remaining during placeholder wait, ending ad break\");\n        break;\n      }\n\n      while (this.adRequestQueue.length > 0) {\n        if (!this.timing.hasTimeToStartAnotherAd()) break;\n\n        const nextAdUrl = this.adRequestQueue.shift();\n        if (!nextAdUrl) continue;\n        if (this.timing.failedVastUrls.has(nextAdUrl)) continue;\n        if (this.timing.isUrlInCooldown(nextAdUrl)) continue;\n\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Ad URL available, requesting via HLS ad player\");\n\n        this.isShowingPlaceholder = false;\n        this.host.getAdPlayer().hidePlaceholder();\n\n        try {\n          await this.playSingleAd(nextAdUrl);\n          this.timing.consecutiveFailures = 0;\n        } catch (error) {\n          const errorMessage = (error as Error).message;\n          if (errorMessage.includes(\"ad_duration_exceeds_budget\")) {\n            await this.tryNextAvailableAdWithRateLimit();\n            return;\n          }\n          if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n            this.timing.consecutiveFailures++;\n          }\n          await this.tryNextAvailableAdWithRateLimit();\n        }\n        return;\n      }\n    }\n\n    if (this.debug) console.log(\"[CONTINUOUS-FETCH] Placeholder timeout, ending ad break\");\n\n    this.isShowingPlaceholder = false;\n    this.host.getAdPlayer().hidePlaceholder();\n    this.handleAdPodComplete();\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Ad break completion\n  // ───────────────────────────────────────────────────────────────\n\n  handleAdPodComplete(): void {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Ad pod complete - cleaning up\");\n    }\n\n    this.timing.resetForBreakEnd();\n\n    this.stopContinuousFetching();\n    this.preloadPool.stop();\n    this.clearPendingAdBreak();\n\n    if (this.isShowingPlaceholder) {\n      this.host.getAdPlayer().hidePlaceholder();\n      this.isShowingPlaceholder = false;\n    }\n\n    this.adRequestQueue = [];\n\n    this.inAdBreak = false;\n    this.adDetectSentForCurrentBreak = false;\n    this.cueManager.activeScte35BreakKey = undefined;\n    this.cueManager.scheduledScte35BreakKey = undefined;\n    this.adPodQueue = [];\n    this.showAds = false;\n\n    this.host.getAdPlayer().stop().catch(() => {});\n\n    const restoredMuted = this.host.getAdPlayer().getOriginalMutedState();\n    const restoredVolume = this.host.getAdPlayer().getOriginalVolume();\n\n    if (this.host.video.muted !== restoredMuted) {\n      this.host.video.muted = restoredMuted;\n    }\n    if (Math.abs(this.host.video.volume - restoredVolume) > 0.01) {\n      this.host.video.volume = restoredVolume;\n    }\n\n    if (this.host.shouldContinueLiveStreamDuringAds()) {\n      const liveSyncPos = this.host.getLiveSyncPosition();\n      if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {\n        if (this.debug) {\n          console.log(\n            `[StormcloudVideoPlayer] Live break end — snapping to live edge: ${this.host.video.currentTime.toFixed(2)}s → ${liveSyncPos.toFixed(2)}s`\n          );\n        }\n        this.host.video.currentTime = liveSyncPos;\n      }\n\n      if (this.host.video.paused) {\n        if (this.debug) console.log(\"[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback\");\n        this.host.video.play()?.catch(() => {});\n      } else {\n        if (this.debug) console.log(\"[StormcloudVideoPlayer] Content video already playing in live mode after ads\");\n      }\n    } else if (this.host.video.paused) {\n      this.host.video.play()?.catch(() => {});\n    }\n  }\n\n  handleAdFailure(): void {\n    this.timing.consecutiveFailures++;\n    this.timing.recordGamNoFill();\n    const remaining = this.timing.getRemainingAdMs();\n\n    if (this.debug) {\n      console.log(\n        `[CONTINUOUS-FETCH] Ad failure: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}, consecutiveFailures=${this.timing.consecutiveFailures}`,\n        this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n      );\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.log(`[CONTINUOUS-FETCH] Max consecutive failures reached (${this.timing.consecutiveFailures}), ending ad break gracefully`);\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.hasTimeToStartAnotherAd()) {\n      this.tryNextAvailableAdWithRateLimit();\n    } else {\n      if (this.debug) console.log(\"[AD-ERROR] Ad failed and not enough time remaining for another ad. Failed URLs:\", this.timing.failedVastUrls.size);\n      this.handleAdPodComplete();\n    }\n  }\n}\n"]}