{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/player/StormcloudVideoPlayer.cjs","../../src/player/StormcloudVideoPlayer.ts","../../src/sdk/hlsAdPlayer.ts","../../src/sdk/pal.ts","../../src/utils/mqttClient.ts","../../src/utils/mqttConfig.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"],"names":["__create","Object","create","__defProp","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__toESM","mod","isNodeMode","__esModule","StormcloudVideoPlayer_exports","value","__toCommonJS","StormcloudVideoPlayer","exports","import_hls","require","MAX_VAST_WRAPPER_DEPTH","createHlsAdPlayer","contentVideo","options","adPlaying","originalMutedState","originalVolume","Math","max","min","volume","listeners","Map","licenseKey","mainHlsInstance","adVideoElement","adHls","adContainerEl","currentAd","podAds","podIndex","sessionId","preloadedAds","preloadingAds","destroyed","pendingTimeouts","impression","start","firstQuartile","midpoint","thirdQuartile","complete","emit","event","payload","set","Array","fn","error","console","warn","generateSessionId","Date","now","random","toString","substr","fireTrackingPixels","urls","length","forEach","url","trackingUrl","includes","img","Image","log","getMainStreamQuality","currentLevel","levels","autoLevel","loadLevel","firstFile","mediaFiles","widthDiff","level","width","height","bitrate","selectBestMediaFile","Error","mainQuality","scoredFiles","map","file","abs","heightDiff","resolutionDiff","fileBitrate","score","bitrateDiff","sort","a","b","bestMatch","resolution","isHlsMediaFile","mediaFile","type","toLowerCase","isProgressiveMediaFile","startsWith","endsWith","createEmptyTrackingUrls","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","bSeq","aSeq","aVal","Number","isFinite","MAX_SAFE_INTEGER","bVal","createAdVideoElement","video","document","createElement","style","position","left","top","objectFit","backgroundColor","playsInline","muted","setupAdEventListeners","addEventListener","progress","currentTime","trackingFired","advanceToNextPodAd","handleAdComplete","e","handleAdError","ended","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","resetQuartileTracking","preserveImpression","loadCurrentAdMedia","isHlsAd","Hls","isSupported","destroy","catch","lowLatencyMode","loadSource","enableWorker","attachMedia","on","Events","MANIFEST_PARSED","play","ERROR","_event","data","fatal","canPlayType","src","load","total","display","pointerEvents","continueLiveStreamDuringAds","paused","initialize","container","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","window","goog","pal","existing","timeout","setTimeout","script","async","setAttribute","onload","onerror","head","getOrCreateNonceLoader","consentSettings","ConsentSettings","allowStorage","NonceLoader","createPalNonceManager","currentNonce","currentNonceManager","generateNonce","loader","request","manager","adWillAutoPlay","adWillPlayMuted","playerVolume","continuousPlayback","descriptionUrl","location","href","iconsSupported","playerType","playerVersion","supportedApiFrameworks","videoWidth","videoHeight","ppid","password","loadNonceManager","getNonce","getCurrentNonce","injectNonce","URL","searchParams","base","replace","sep","encodeURIComponent","sendPlaybackStart","sendPlaybackEnd","sendAdClick","sendAdTouch","reset","DEFAULT_MQTT_CONFIG","enabled","brokerAddress","brokerPort","wsPort","username","topicPrefix","qos","mqttConfig","isMQTTEnabled","buildMQTTBrokerUrl","brokerUrl","buildPlayerTopic","channel","import_mqtt","LOG","client","status","initMQTTClient","clientId","slice","mqtt","connect","keepalive","clean","reconnectPeriod","connectTimeout","queueQoSZero","err","info","message","publishMQTT","AIRY_TIZEN_APP_ID","AIRY_ROKU_APP_ID","AIRY_APP_NAME","ensureMQTTClient","topic","AIRY_ANDROID_APP_ID","AIRY_WEBOS_APP_ID","AIRY_DEFAULT_CONTENT_URL","CTV_SESSION_STORAGE_KEY","PLAYER_ID_STORAGE_KEY","LG_TEST_APP_ID","LG_TEST_APP_NAME","LG_TEST_CONTENT_URL","_lgTestDeviceId","getLgTestDeviceId","createUuid","isLgWebOS","navigator","test","userAgent","getDefaultAppId","ua","DEVICE_ID_STORAGE_KEYS","resolveVastEnvironmentSignals","ANDROID_ID_TYPES","isCtv","platformLat","bridgeSignals","readNativeBridgeSignals","lg","deviceId","readStoredDeviceId","platformDevice","limitAdTracking","deviceIdType","readStoredString","inferDeviceIdType","readStoredLimitAdTracking","contentUrl","appId","appName","getOrCreateCtvSessionId","tagType","runtimeType","tag","runtime","resolveNativeDeviceId","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","padStart","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","AiryTV","Android","webOS","tizen","amazon","filter","Boolean","readBridgeValue","result","readBridgeBoolean","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","origin","hostname","path","pathname","language","languages","join","cookieEnabled","doNotTrack","visibilityState","sha256Hex","input","encodedData","utf8","buffer","hashBuffer","hash","char","fallbackHash","timestamp","subtle","digest","TextEncoder","encode","unescape","charCodeAt","padEnd","resolvePlayerIdentitySeed","clientInfo","nativeDeviceId","persistedId","JSON","stringify","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_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","finally","constructor","then","reason","polyfillObjectAssign","assign","sources","TypeError","nextSource","nextKey","polyfillArrayFrom","arrayLike","mapFn","thisArg","items","len","search","pos","polyfillStringEndsWith","polyfillStringIncludes","initializePolyfills","polyfillStringStartsWith","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","isEquivalentDeviceIdType","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","deviceTypeHint","consent","gdpr","gdprConsent","usPrivacy","adTest","staleKeys","tasks","correlatorRegex","fetchConsentSignals","timeoutMs","signals","tcfApi","__tcfapi","settled","tcData","success","eventStatus","gdprApplies","tcString","listenerId","uspApi","__uspapi","uspString","getChromeVersion","getWebKitVersion","getPlatform","userAgentData","detectBrowser","version","webkitVersion","majorVersion","isLegacyTV","supportsModernJS","webOSVersion","tizenVersion","chromeVersion","chromeVersionNum","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","decoder","TextDecoder","decode","out","fromCharCode","getFragmentStartSeconds","frag","startPTS","candidate","parseScte35FromId3","decodeId3ValueToText","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","section","processedSections","checksum","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","ptsTicks","low","markerTypeFromSegmentationTypeId","segmentationTypeId","parseScte35SegmentationDescriptor","descriptor","identifier","segmentationEventId","cancelIndicator","programSegmentationFlag","segmentationDurationFlag","componentCount","spliceImmediateFlag","durationTicks","segmentationUpidLength","markerType","parseScte35SegmentationDescriptors","descriptorLoopLength","descriptorOffset","descriptorTag","descriptorLength","descriptorDataStart","descriptorDataEnd","descriptorMarker","ptsAdjHigh","ptsAdjLow","spliceCommandLength","spliceCommandType","spliceEventId","commandBodyStart","cancel","outOfNetwork","programSpliceFlag","durationFlag","componentPtsSeconds","splice_event_id","expectedDescriptorOffset","segmentation_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","consentSignals","podCounter","podAssignedByPrefetch","lastHeartbeatTime","defaultPodMaxAds","isVmapEnabled","isVmap","vmapUrl","fetchAdConfiguration","vastMode","vastEndpoint","apiUrl","imaPayload","decodedPayload","numberAds","fetchAndParseVmap","apiVastTagUrl","json","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","adRequestPositionInBreak","generateVastUrlsWithCorrelators","count","adPlayer","palNonce","envSignals","ctvAdRequest","urlWithMacros","autoplay","finalUrl","resolvePodParams","breakDurationMs","maxDurationMs","maxAds","minDurationMs","podExactDuration","generatePodVastUrl","podParams","initializeTracking","heartbeatInterval","setInterval","sendHeartbeatIfNeeded","adFailsafeToken","adBreakPlayedDurationMs","remainingMs","ensureAdStoppedByTimer","scheduleAdStartIn","scteAdBreakEndWallClockMs","getLoadedAdDurationMs","destroyTracking","clearInterval","AdTimingService","adRequestWatchdogToken","ptsDriftEmaMs","adBreakEpoch","adRequestTokenCounter","currentAdIndex","totalAdsInBreak","totalAdRequestsInBreak","maxTotalAdRequestsPerBreak","lastAdRequestTime","consecutiveFailures","maxConsecutiveFailures","minAdRequestIntervalMs","backoffBaseMs","maxBackoffMs","defaultMinRemainingMsToStartAd","failedVastUrls","temporaryFailureUrls","temporaryFailureCooldownMs","globalConsecutiveNoFills","globalNoFillThreshold","globalNoFillCooldownUntil","globalNoFillBackoffBaseMs","globalNoFillBackoffMaxMs","globalLastGamRequestTime","globalMinGamIntervalMs","scheduleAdStopCountdown","adStopTimerId","clearAdStopTimer","onAdStopTimerFired","delayMs","cueKey","clearAdStartTimer","onAdStartTimerFired","adStartTimerId","updatePtsDrift","ptsSecondsSample","sampleMs","alpha","resolveScteBreakStartWallClockMs","nowWallClockMs","estimatedCurrentPtsMs","deltaMs","setAdBreakDurationBoundary","expectedAdBreakDurationMs","currentAdBreakStartWallClockMs","scheduleAdStopAtBreakBoundary","getWallClockRemainingAdMs","endWallClockMs","getAdBreakEndWallClockMs","getDurationBudgetRemainingMs","adController","adFitsRemainingBudget","logAdDurationDecision","accepted","remainingBudget","recordPlayedAdDuration","rejectLoadedAdForDuration","ensureLoadedAdFitsBudget","fits","markAdStarted","notePodAdStarted","getRemainingAdMs","wallClockRemaining","budgetRemaining","getMinRemainingMsToStartAd","configured","minRemainingMsToStartAd","hasTimeToStartAnotherAd","minRemaining","isTemporaryAdError","isUrlInCooldown","failureTime","cleanupTemporaryFailures","isGamInCooldown","recordGamNoFill","exponent","backoff","pow","resetGamNoFillCounter","enforceGlobalRateLimit","waitMs","startAdRequestWatchdog","token","clearAdFailsafeTimer","logAdState","clearAdRequestWatchdog","adFailsafeTimeoutMs","adRequestWatchdogId","activeAdRequestToken","onWatchdogTimeout","startAdFailsafeTimer","failsafeMs","adFailsafeTimerId","videoPaused","onFailsafeTimeout","extra","showAds","resetForBreakEnd","isLoopRunning","loopRunning","deps","AdPreloadPool","pool","maxPoolSize","poolActive","active","startPreloadPool","baseVastUrl","initialUrls","startLoopImmediately","preloadAdIntoPool","preloadPoolLoop","vastUrl","timing","epoch","loadPromise","some","hasAdError","adErrorPayload","errorListenerCleanup","preloadAd","errorListener","isNoFill","poolEntry","loadedDuration","lateErrorListener","shouldContinueLiveStreamDuringAds","createAdPlayer","code","vastErrorCode","loadedAt","isReady","splice","newUrls","newUrl","getPendingAdBreak","getPreloadedAd","PlaceholderLayer","ensureContainer","transition","show","wasHidden","offsetHeight","requestAnimationFrame","hide","HlsEngine","cueManager","nativeHlsMode","videoSrcProtection","bufferedSegmentsCount","shouldAutoplayAfterBuffering","hasInitialBufferCompleted","shouldUseNativeHls","getStreamType","canNative","setupNativeHls","adBehavior","isLive","setupHls","hls","import_hls2","backBufferLength","maxLiveSyncPlaybackRate","liveSyncDuration","maxBufferLength","maxMaxBufferLength","maxBufferSize","maxBufferHole","highBufferWatchdogPeriod","nudgeOffset","nudgeMaxRetry","startPosition","MEDIA_ATTACHED","_","_data","minSegments","details","live","onManifestParsed","minSegmentsBeforePlay","LEVEL_LOADED","_evt","hasPendingAdBreak","fragments","fragmentsToScan","tagList","isArray","idx","indexOf","earlyDetection","FRAG_BUFFERED","FRAG_PARSING_METADATA","id3Tags","samples","pts","onId3Tag","FRAG_LOADED","processFragmentScte35Payload","FRAG_DECRYPTED","FRAG_CHANGED","activatePendingCuesForFragment"],"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/player/StormcloudVideoPlayer.ts\nvar StormcloudVideoPlayer_exports = {};\n__export(StormcloudVideoPlayer_exports, {\n  StormcloudVideoPlayer: () => StormcloudVideoPlayer\n});\nmodule.exports = __toCommonJS(StormcloudVideoPlayer_exports);\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.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: generateCorrelator(),\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: generateCorrelator(),\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;\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;\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// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n  StormcloudVideoPlayer\n});\n","import type {\n  StormcloudVideoPlayerConfig,\n  Scte35Marker,\n  AdController,\n  AdBreak,\n} from \"../types\";\nimport { createHlsAdPlayer } from \"../sdk/hlsAdPlayer\";\nimport { createPalNonceManager } from \"../sdk/pal\";\nimport type { PalNonceManager } from \"../sdk/pal\";\nimport {\n  buildAnalyticsContext,\n  sendAdDetectTracking,\n} from \"../utils/tracking\";\nimport { initializePolyfills } from \"../utils/polyfills\";\nimport { fetchConsentSignals } from \"../utils/vastMacros\";\nimport {\n  logBrowserInfo,\n  getBrowserConfigOverrides,\n} from \"../utils/browserCompat\";\n\nimport { isManifestBasedMarker } from \"./Scte35Parser\";\nimport { Scte35CueManager } from \"./Scte35CueManager\";\nimport { AdConfigManager } from \"./AdConfigManager\";\nimport { AdTimingService } from \"./AdTimingService\";\nimport { AdPreloadPool } from \"./AdPreloadPool\";\nimport { PlaceholderLayer } from \"./PlaceholderLayer\";\nimport { HlsEngine } from \"./HlsEngine\";\nimport { AdBreakOrchestrator } from \"./AdBreakOrchestrator\";\nimport {\n  toggleMute as ctrlToggleMute,\n  toggleFullscreen as ctrlToggleFullscreen,\n  isMuted as ctrlIsMuted,\n  setMuted as ctrlSetMuted,\n  setVolume as ctrlSetVolume,\n  getVolume as ctrlGetVolume,\n  isFullscreen as ctrlIsFullscreen,\n  resizePlayer as ctrlResizePlayer,\n} from \"./PlayerControls\";\n\nexport class StormcloudVideoPlayer {\n  private readonly video: HTMLVideoElement;\n  private readonly config: StormcloudVideoPlayerConfig;\n  private adPlayer: AdController;\n  private attached = false;\n\n  private timeUpdateHandler?: (event: Event) => void;\n  private endedHandler?: (event: Event) => void;\n  private emptiedHandler?: (event: Event) => void;\n\n  private palNonce: PalNonceManager;\n  private palPlaybackStarted: boolean = false;\n\n  private readonly cueManager: Scte35CueManager;\n  private readonly adConfig: AdConfigManager;\n  private readonly timing: AdTimingService;\n  private readonly preloadPool: AdPreloadPool;\n  private readonly placeholder: PlaceholderLayer;\n  private readonly hlsEngine: HlsEngine;\n  private readonly adBreak: AdBreakOrchestrator;\n\n  constructor(config: StormcloudVideoPlayerConfig) {\n    initializePolyfills();\n\n    const browserOverrides = getBrowserConfigOverrides();\n\n    this.config = { ...browserOverrides, ...config };\n    this.video = config.videoElement;\n\n    logBrowserInfo(config.debugAdTiming);\n\n    this.adPlayer = this.createAdPlayer(false);\n    this.palNonce = createPalNonceManager();\n\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\n    this.adConfig = new AdConfigManager(this.config, this.video);\n\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 * 1000 : this.timing.expectedAdBreakDurationMs\n        );\n      },\n      onWatchdogTimeout: () => this.adBreak.handleAdFailure(),\n      onFailsafeTimeout: () => this.adBreak.handleAdFailure(),\n    });\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\n    this.placeholder = new PlaceholderLayer(this.video, !!this.config.debugAdTiming);\n\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\n    this.adBreak = new AdBreakOrchestrator(\n      {\n        config: this.config,\n        video: this.video,\n        getAdPlayer: () => this.adPlayer,\n        setAdPlayer: (p) => { this.adPlayer = p; },\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\n  private get debug(): boolean {\n    return !!this.config.debugAdTiming;\n  }\n\n  private createAdPlayer(continueLiveStreamDuringAds: boolean): AdController {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Creating HLS ad player\");\n    }\n    return createHlsAdPlayer(this.video, {\n      continueLiveStreamDuringAds,\n      ...(this.config.licenseKey\n        ? { licenseKey: this.config.licenseKey }\n        : {}),\n      ...(this.hlsEngine?.hls ? { mainHlsInstance: this.hlsEngine.hls } : {}),\n    });\n  }\n\n  private generateVastUrls(baseUrl: string, count: number): string[] {\n    return this.adConfig.generateVastUrlsWithCorrelators(\n      baseUrl, count, this.adPlayer, this.palNonce, this.adBreak.inAdBreak\n    );\n  }\n\n  private generatePodVastUrl(baseUrl: string, breakDurationMs?: number): string {\n    const podParams = this.adConfig.resolvePodParams(breakDurationMs);\n    return this.adConfig.generatePodVastUrl(\n      baseUrl, podParams, this.adPlayer, this.palNonce, this.adBreak.inAdBreak\n    );\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Lifecycle\n  // ───────────────────────────────────────────────────────────────\n\n  async load(): Promise<void> {\n    if (!this.attached) {\n      this.attach();\n    }\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\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()\n      .then((signals) => {\n        this.adConfig.consentSignals = signals;\n      })\n      .catch(() => {});\n\n    this.adConfig.initializeTracking();\n\n    if (this.hlsEngine.shouldUseNativeHls(() => this.getStreamType())) {\n      await this.hlsEngine.setupNativeHls();\n\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\n      this.adPlayer.destroy();\n      this.adPlayer = this.createAdPlayer(continueLiveStreamDuringAds);\n      this.adPlayer.initialize();\n      return;\n    }\n\n    this.hlsEngine.setupHls();\n  }\n\n  private async onManifestParsed(isLive: boolean): Promise<void> {\n    if (\n      !this.adConfig.isVmapEnabled() &&\n      !isLive &&\n      this.adConfig.vmapBreaks.length === 0 &&\n      this.adConfig.apiVastTagUrl\n    ) {\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\n    if (this.debug) {\n      const adBehavior = this.shouldContinueLiveStreamDuringAds()\n        ? \"live (main video continues muted during ads)\"\n        : \"vod (main video pauses during ads)\";\n      console.log(\"[StormcloudVideoPlayer] Stream type detected:\", {\n        isLive,\n        allowNativeHls: this.config.allowNativeHls,\n        adBehavior,\n      });\n    }\n\n    this.adPlayer.destroy();\n    this.adPlayer = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());\n    this.adPlayer.initialize();\n  }\n\n  private attach(): void {\n    if (this.attached) return;\n    this.attached = true;\n    this.video.autoplay = !!this.config.autoplay;\n    this.video.muted = !!this.config.muted;\n\n    this.adPlayer.initialize();\n    this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n    this.adBreak.attachImaEventListeners();\n\n    this.video.addEventListener(\"play\", () => {\n      if (!this.palPlaybackStarted && !this.adPlayer.isAdPlaying()) {\n        this.palPlaybackStarted = true;\n        this.palNonce.sendPlaybackStart();\n      }\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\n    this.video.addEventListener(\"mousedown\", (e) => {\n      this.palNonce.sendAdTouch(e as MouseEvent);\n    });\n\n    this.video.addEventListener(\"touchstart\", (e) => {\n      this.palNonce.sendAdTouch(e as TouchEvent);\n    });\n\n    this.timeUpdateHandler = () => {\n      this.onTimeUpdate(this.video.currentTime);\n    };\n    this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n\n    this.emptiedHandler = () => {\n      if (\n        this.hlsEngine.nativeHlsMode &&\n        this.hlsEngine.videoSrcProtection &&\n        !this.adPlayer.isAdPlaying()\n      ) {\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    this.video.addEventListener(\"emptied\", this.emptiedHandler);\n  }\n\n  private shouldContinueLiveStreamDuringAds(): boolean {\n    // Continue content under ads for live streams regardless of native/hls.js\n    // playback mode. Pausing live content during ads causes replayed break\n    // filler after ads complete on CTV devices.\n    if (this.hlsEngine.isLiveStream) {\n      return true;\n    }\n\n    // Native HLS can still represent live as Infinity duration even when\n    // explicit isLiveStream is not provided.\n    const duration = this.video.duration;\n    if (!Number.isFinite(duration) || duration === Infinity) {\n      return true;\n    }\n\n    return false;\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  SCTE-35 marker orchestration\n  // ───────────────────────────────────────────────────────────────\n\n  private onScte35Marker(marker: Scte35Marker, cueKey?: string): void {\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\n    if (marker.type === \"start\") {\n      if (this.adBreak.inAdBreak) {\n        if (marker.durationSeconds != null) {\n          const newDurationMs = marker.durationSeconds * 1000;\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\n      if (!this.adBreak.adDetectSentForCurrentBreak) {\n        this.adBreak.adDetectSentForCurrentBreak = true;\n        const detectPayload: {\n          durationSeconds?: number;\n          ptsSeconds?: number;\n          detectedAtFragmentSn?: number;\n        } = {};\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: new Date().toISOString(), ...detectPayload }, buildAnalyticsContext(this.config)).catch(() => {});\n      }\n\n      const hasPrefetchedAds = this.adBreak.pendingAdBreak && this.adBreak.pendingAdBreak.vastUrls.length > 0;\n\n      const durationMs =\n        marker.durationSeconds != null\n          ? marker.durationSeconds * 1000\n          : (this.adBreak.pendingAdBreak?.marker.durationSeconds != null\n              ? this.adBreak.pendingAdBreak.marker.durationSeconds * 1000\n              : undefined);\n\n      const isManifest = isManifestBasedMarker(marker);\n      const forceImmediate = this.config.immediateManifestAds ?? true;\n\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\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 ?? 1000;\n        const nowMs = this.video.currentTime * 1000;\n        const estCurrentPtsMs = nowMs - this.timing.ptsDriftEmaMs;\n        const deltaMs = Math.floor(marker.ptsSeconds * 1000 - estCurrentPtsMs);\n\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] PTS-based timing calculation:\", {\n            nowMs,\n            estCurrentPtsMs,\n            markerPtsMs: marker.ptsSeconds * 1000,\n            deltaMs,\n            tolerance: tol,\n          });\n        }\n\n        if (deltaMs > tol) {\n          if (this.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 * 1000);\n      }\n      this.timing.scheduleAdStopAtBreakBoundary();\n\n      if (\n        !this.adPlayer.isAdPlaying() &&\n        this.timing.activeAdRequestToken === null &&\n        this.adBreak.adRequestQueue.length > 0 &&\n        this.timing.hasTimeToStartAnotherAd()\n      ) {\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\n      const remaining = this.timing.getRemainingAdMs();\n      const adPlaying = this.adPlayer.isAdPlaying();\n      const hasQueuedAds = this.adBreak.adRequestQueue.length > 0;\n\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\n      this.timing.scteAdBreakEndWallClockMs = Date.now();\n      this.timing.clearAdStartTimer();\n      this.timing.clearAdStopTimer();\n\n      if (adPlaying) {\n        this.adPlayer.stop().catch(() => {});\n      }\n\n      this.adBreak.handleAdPodComplete();\n      return;\n    }\n  }\n\n  private startScte35AdBreak(\n    marker: Scte35Marker,\n    cueKey: string | undefined,\n    durationMs: number | undefined\n  ): void {\n    this.adBreak.inAdBreak = true;\n    this.cueManager.activeScte35BreakKey = cueKey ?? this.cueManager.pendingScte35CueKey;\n    this.cueManager.scheduledScte35BreakKey = undefined;\n    this.timing.currentAdBreakStartWallClockMs =\n      this.timing.resolveScteBreakStartWallClockMs(marker);\n    this.timing.setAdBreakDurationBoundary(durationMs);\n\n    this.adBreak.handleAdStart(marker);\n\n    this.timing.scheduleAdStopAtBreakBoundary();\n  }\n\n  private onAdStopTimerFired(): void {\n    if (!this.adBreak.inAdBreak) return;\n\n    const adPlaying = this.adPlayer.isAdPlaying();\n    const checkIntervalMs = Math.max(\n      250,\n      Math.floor(this.config.adBreakCheckIntervalMs ?? 1000)\n    );\n    const maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;\n    const maxExtensionMs =\n      typeof maxExtensionMsConfig === \"number\" && maxExtensionMsConfig > 0\n        ? maxExtensionMsConfig\n        : 0;\n\n    const endWallClockMs = this.timing.getAdBreakEndWallClockMs() ?? Date.now();\n    const overrunMs = Math.max(0, Date.now() - endWallClockMs);\n\n    const shouldExtendAdBreak = adPlaying && overrunMs < maxExtensionMs;\n\n    if (shouldExtendAdBreak) {\n      this.timing.scheduleAdStopCountdown(checkIntervalMs);\n      return;\n    }\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\n    if (adPlaying) {\n      this.adPlayer.stop().catch(() => {});\n    }\n\n    this.adBreak.handleAdPodComplete();\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Ad prefetch\n  // ───────────────────────────────────────────────────────────────\n\n  private startAdPrefetch(\n    marker: Scte35Marker,\n    fragmentSn?: number,\n    cueKey?: string\n  ): void {\n    if (this.adBreak.pendingAdBreak || this.adBreak.inAdBreak) return;\n\n    const scheduled = this.adConfig.findCurrentOrNextBreak(this.video.currentTime * 1000);\n    const tags = this.adConfig.selectVastTagsForBreak(scheduled);\n\n    let baseVastUrl: string;\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\n    this.adConfig.beginNewAdPod();\n    this.adConfig.podAssignedByPrefetch = true;\n\n    const optimizedPods = !!this.config.optimizedPods;\n    const breakDurationMs =\n      marker.durationSeconds != null ? marker.durationSeconds * 1000 : undefined;\n\n    const generatedUrls = optimizedPods\n      ? [this.generatePodVastUrl(baseVastUrl, breakDurationMs)]\n      : this.generateVastUrls(baseVastUrl, 1);\n\n    this.adBreak.pendingAdBreak = {\n      marker,\n      ...(fragmentSn !== undefined ? { detectedAtFragmentSn: fragmentSn } : {}),\n      vastUrls: generatedUrls,\n      isFetching: false,\n      fetchStartTime: Date.now(),\n    };\n    this.cueManager.pendingScte35CueKey = cueKey;\n\n    this.adBreak.adDetectSentForCurrentBreak = true;\n    const detectPayload: {\n      durationSeconds?: number;\n      ptsSeconds?: number;\n      detectedAtFragmentSn?: number;\n    } = {};\n    if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;\n    if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;\n    if (fragmentSn !== undefined) detectPayload.detectedAtFragmentSn = fragmentSn;\n    \n    sendAdDetectTracking(this.config.licenseKey, { source: \"scte35\", timestamp: 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\n    if (optimizedPods) {\n      if (this.debug) {\n        console.log(\"[PREFETCH] Optimized pods enabled - skipping single-ad preload pool\");\n      }\n      return;\n    }\n\n    this.preloadPool.startPreloadPool(baseVastUrl, generatedUrls.slice(0, 1), false);\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  VMAP time-based ad breaks\n  // ───────────────────────────────────────────────────────────────\n\n  private onTimeUpdate(currentTimeSec: number): void {\n    if (!this.adConfig.isVmapEnabled() || this.adConfig.vmapBreaks.length === 0) return;\n    if (this.adPlayer.isAdPlaying() || this.adBreak.inAdBreak) return;\n    const nowMs = currentTimeSec * 1000;\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\n  private onVideoEnded(): void {\n    if (!this.adConfig.isVmapEnabled() || this.adConfig.vmapBreaks.length === 0) return;\n    if (this.adPlayer.isAdPlaying() || this.adBreak.inAdBreak) return;\n\n    const durationMs = Number.isFinite(this.video.duration)\n      ? Math.floor(this.video.duration * 1000)\n      : 0;\n    const postroll = this.adConfig.vmapBreaks.find(\n      (b) =>\n        b.startTimeMs === -1 &&\n        !this.adConfig.consumedVmapBreakIds.has(this.adConfig.getAdBreakKey(b))\n    );\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\n  private async handleVmapAdBreak(\n    adBreak: AdBreak,\n    nowMs: number\n  ): Promise<void> {\n    const key = this.adConfig.getAdBreakKey(adBreak);\n    if (this.adConfig.consumedVmapBreakIds.has(key)) return;\n\n    const breakStartMs = this.adConfig.resolveBreakStartMs(adBreak);\n    if (breakStartMs == null) return;\n\n    const durationMs = adBreak.durationMs ?? 0;\n    const endMs = breakStartMs + durationMs;\n    const inWindow =\n      durationMs > 0\n        ? nowMs >= breakStartMs && nowMs < endMs\n        : nowMs >= breakStartMs;\n\n    if (inWindow) {\n      this.adConfig.consumedVmapBreakIds.add(key);\n      const tags = this.adConfig.selectVastTagsForBreak(adBreak);\n      if (!tags || tags.length === 0) return;\n\n      const first = tags[0] as string;\n      const rest = tags.slice(1);\n      this.adBreak.adPodQueue = rest;\n\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\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  // ───────────────────────────────────────────────────────────────\n  //  Public API\n  // ───────────────────────────────────────────────────────────────\n\n  getCurrentAdIndex(): number {\n    return this.timing.currentAdIndex;\n  }\n\n  getTotalAdsInBreak(): number {\n    return this.timing.totalAdsInBreak;\n  }\n\n  getAdRemainingMs(): number {\n    return this.timing.getRemainingAdMs();\n  }\n\n  isAdPlaying(): boolean {\n    return this.adBreak.inAdBreak && this.adPlayer.isAdPlaying();\n  }\n\n  isShowingAds(): boolean {\n    return this.adBreak.showAds;\n  }\n\n  getStreamType(): \"hls\" | \"other\" {\n    const url = this.config.src.toLowerCase();\n    if (\n      url.includes(\".m3u8\") ||\n      url.includes(\"/hls/\") ||\n      url.includes(\"application/vnd.apple.mpegurl\")\n    ) {\n      return \"hls\";\n    }\n    return \"other\";\n  }\n\n  shouldShowNativeControls(): boolean {\n    const streamType = this.getStreamType();\n    if (streamType === \"other\") {\n      return !(this.config.showCustomControls ?? false);\n    }\n    return !!(\n      this.config.allowNativeHls && !(this.config.showCustomControls ?? false)\n    );\n  }\n\n  isLive(): boolean {\n    return this.hlsEngine.isLiveStream;\n  }\n\n  get videoElement(): HTMLVideoElement {\n    return this.video;\n  }\n\n  toggleMute(): void {\n    ctrlToggleMute(this.video, this.adPlayer, this.debug);\n  }\n\n  toggleFullscreen(): Promise<void> {\n    return ctrlToggleFullscreen(this.video, this.debug);\n  }\n\n  isMuted(): boolean {\n    return ctrlIsMuted(this.video, this.adPlayer);\n  }\n\n  setMuted(muted: boolean): void {\n    ctrlSetMuted(this.video, this.adPlayer, muted, this.debug);\n  }\n\n  setVolume(volume: number): void {\n    ctrlSetVolume(this.video, this.adPlayer, volume, this.debug);\n  }\n\n  getVolume(): number {\n    return ctrlGetVolume(this.video, this.adPlayer);\n  }\n\n  isFullscreen(): boolean {\n    return ctrlIsFullscreen();\n  }\n\n  resize(): void {\n    ctrlResizePlayer(this.video, this.adPlayer, this.debug);\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Destroy\n  // ───────────────────────────────────────────────────────────────\n\n  destroy(): void {\n    this.adBreak.stopContinuousFetching();\n    this.preloadPool.stop();\n    this.timing.destroy();\n    this.adBreak.clearPendingAdBreak();\n    this.placeholder.destroy();\n\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\n    this.adConfig.destroyTracking();\n    this.hlsEngine.destroy();\n    this.adPlayer?.destroy();\n\n    if (this.palPlaybackStarted) {\n      this.palPlaybackStarted = false;\n      this.palNonce.sendPlaybackEnd();\n    }\n    this.palNonce.reset();\n\n    this.adBreak.adRequestQueue = [];\n    this.timing.consecutiveFailures = 0;\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","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 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","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  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: generateCorrelator(),\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: generateCorrelator(),\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"]}