{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/index.cjs","../src/index.ts","../src/ui/StormcloudVideoPlayer.tsx","../src/sdk/hlsAdPlayer.ts","../src/sdk/pal.ts","../src/utils/mqttConfig.ts","../src/utils/mqttClient.ts","../src/utils/vastEnvironmentSignals.ts","../src/utils/tracking.ts","../src/utils/polyfills.ts","../src/utils/vastMacros.ts","../src/utils/browserCompat.ts","../src/player/Scte35Parser.ts","../src/player/Scte35CueManager.ts","../src/player/AdConfigManager.ts","../src/player/AdTimingService.ts","../src/player/AdPreloadPool.ts","../src/player/PlaceholderLayer.ts","../src/player/HlsEngine.ts","../src/player/PlayerControls.ts","../src/player/AdBreakOrchestrator.ts","../src/player/StormcloudVideoPlayer.ts","../src/StormcloudPlayer.tsx","../src/props.ts","../src/utils.ts","../src/patterns.ts","../src/players/HlsPlayer.tsx","../src/players/FilePlayer.tsx","../src/players/index.ts","../src/Player.tsx"],"names":["__create","Object","create","__defProp","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","index_exports","DEFAULT_MQTT_CONFIG","IS_BROWSER","IS_GLOBAL","IS_IOS","IS_SAFARI","MQTT_CA_CERT_FILE","SUPPORTS_DASH","SUPPORTS_HLS","StormcloudPlayer","StormcloudPlayer_default","StormcloudVideoPlayer","StormcloudVideoPlayerComponent","applyMQTTConfig","buildAnalyticsContext","buildMQTTBrokerUrl","buildPlayerTopic","canPlay","configureMQTT","createHlsAdPlayer","createPalNonceManager","createStormcloudPlayer","default","detectBrowser","disconnectMQTT","ensureMQTTClient","getBrowserConfigOverrides","getBrowserID","getClientInfo","getMQTTStatus","initMQTTClient","initializePolyfills","isMQTTConfigured","isMQTTConnected","isMQTTEnabled","isMediaStream","lazy","logBrowserInfo","merge","mqttConfig","omit","parseQuery","players","players_default","publishMQTT","randomString","sendAdDetectTracking","sendAdImpressionTracking","sendAdLoadedTracking","sendHeartbeat","sendInitialTracking","supportsFeature","supportsModernJS","supportsWebKitPresentationMode","module","exports","import_react","require","import_hls","MAX_VAST_WRAPPER_DEPTH","contentVideo","options","adPlaying","originalMutedState","originalVolume","Math","max","min","volume","listeners","Map","licenseKey","mainHlsInstance","adVideoElement","adHls","adContainerEl","currentAd","podAds","podIndex","sessionId","preloadedAds","preloadingAds","destroyed","pendingTimeouts","trackingFired","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","src","log","getMainStreamQuality","levels","currentLevel","autoLevel","loadLevel","level","width","height","bitrate","selectBestMediaFile","mediaFiles","Error","firstFile","mainQuality","scoredFiles","map","file","widthDiff","abs","heightDiff","resolutionDiff","fileBitrate","bitrateDiff","score","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","aSeq","bSeq","aVal","Number","isFinite","MAX_SAFE_INTEGER","bVal","createAdVideoElement","video","document","createElement","style","position","left","top","objectFit","backgroundColor","playsInline","muted","setupAdEventListeners","addEventListener","progress","currentTime","advanceToNextPodAd","handleAdComplete","e","handleAdError","ended","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","resetQuartileTracking","preserveImpression","loadCurrentAdMedia","isHlsAd","Hls","isSupported","destroy","enableWorker","lowLatencyMode","loadSource","attachMedia","on","Events","MANIFEST_PARSED","play","catch","ERROR","_event","data","fatal","canPlayType","load","total","display","pointerEvents","continueLiveStreamDuringAds","paused","initialize","container","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","currentNonce","currentNonceManager","generateNonce","loader","request","manager","NonceRequest","adWillAutoPlay","adWillPlayMuted","playerVolume","continuousPlayback","descriptionUrl","location","href","iconsSupported","playerType","playerVersion","supportedApiFrameworks","videoWidth","videoHeight","ppid","loadNonceManager","getNonce","getCurrentNonce","injectNonce","URL","searchParams","base","replace","sep","encodeURIComponent","sendPlaybackStart","sendPlaybackEnd","sendAdClick","sendAdTouch","reset","enabled","brokerAddress","brokerPort","wsPort","username","password","topicPrefix","qos","overrides","assign","brokerUrl","channel","import_mqtt","LOG","client","status","connected","clientId","slice","mqtt","connect","keepalive","clean","reconnectPeriod","connectTimeout","queueQoSZero","err","info","message","topic","publish","JSON","stringify","end","AIRY_ANDROID_APP_ID","AIRY_WEBOS_APP_ID","AIRY_TIZEN_APP_ID","AIRY_ROKU_APP_ID","AIRY_APP_NAME","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","ANDROID_ID_TYPES","resolveVastEnvironmentSignals","isCtv","platformLat","bridgeSignals","readNativeBridgeSignals","platformDevice","readPlatformNativeDeviceId","lg","deviceId","readStoredDeviceId","limitAdTracking","deviceIdType","readStoredString","inferDeviceIdType","readStoredLimitAdTracking","contentUrl","appId","appName","getOrCreateCtvSessionId","deviceTypeHint","isEquivalentDeviceIdType","tagType","runtimeType","tag","runtime","resolveNativeDeviceId","isMacroPlaceholder","isZeroedAdId","getOrCreateStoredUuid","storageKey","localStorage","setItem","crypto","randomUUID","char","floor","nibble","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","readBridgeBoolean","result","normalized","normalizeBoolean","getItem","cachedBrowserId","config","context","debugAdTiming","isLiveStream","inputStreamType","screen","platform","vendor","maxTouchPoints","memory","deviceMemory","hardwareConcurrency","screenInfo","availWidth","availHeight","orientation","pixelDepth","deviceType","brand","os","model","isSmartTV","isAndroid","isWebView","isWebApp","webosMatch","match","tizenMatch","tvMatch","androidModelMatch","outerHeight","outerWidth","matchMedia","matches","standalone","angle","domain","hostname","origin","path","pathname","language","languages","join","cookieEnabled","doNotTrack","referrer","visibilityState","sha256Hex","input","encodedData","utf8","buffer","i","hashBuffer","hash","fallbackHash","timestamp","subtle","digest","Uint8Array","TextEncoder","encode","unescape","charCodeAt","padStart","padEnd","resolvePlayerIdentitySeed","clientInfo","nativeDeviceId","persistedId","canPublish","buildPlayerMetricEvent","flags","playerId","captureAt","toISOString","player_id","device_type","ad_loaded","adLoaded","ad_detect","adDetect","capture_at","input_stream_type","publishTracking","body","metricEvent","events","adDetectInfo","adLoadedInfo","adImpressionInfo","ad_played_count","ad_url","adUrl","heartbeatData","polyfillURLSearchParams","URLSearchParams","URLSearchParamsPolyfill","init","params","parseQueryString","append","query","cleanQuery","param","decodedKey","safeDecodeURIComponent","decodedValue","str","decodeURIComponent","values","String","getAll","callback","parts","polyfillTextEncoder","TextEncoderPolyfill","encoding","charcode","polyfillPromiseFinally","finally","constructor","then","reason","polyfillObjectAssign","sources","TypeError","nextSource","nextKey","polyfillArrayFrom","arrayLike","mapFn","thisArg","items","len","polyfillStringStartsWith","search","pos","polyfillStringEndsWith","polyfillStringIncludes","indexOf","UNEXPANDED_MACRO_PATTERN","INVALID_VAST_PARAM_KEY","EXAMPLE_COM_URL","CTV_UNSUPPORTED_PARAMS","INLINE_DEVICE_MACRO_REPLACEMENTS","pattern","getValue","ctx","correlator","trimmed","generateCorrelator","getRandomValues","buf","Uint32Array","expandInlineMacroPlaceholders","baseUrl","applyDeviceIdentityParams","runtimeId","tagRdid","tagLat","latValue","tagRdidValid","tagTypeValid","removeBrokenAppNameOrphans","toDelete","_value","suffix","trimStart","normalizeVastTagUrl","raw","anValue","orphanFragments","reconstructed","trimEnd","_match","prefix","val","applyVastMacros","expandedUrl","replaceCorrelatorFallback","streamCorrelator","pod","optimizedPodMode","podMaxAds","podMinDurationMs","podMaxDurationMs","round","adPosition","requestUrl","pageUrl","existingUrl","consent","gdpr","gdprConsent","usPrivacy","adTest","staleKeys","correlatorRegex","fetchConsentSignals","timeoutMs","signals","tasks","tcfApi","__tcfapi","settled","tcData","success","eventStatus","gdprApplies","tcString","listenerId","uspApi","__uspapi","uspString","getChromeVersion","getWebKitVersion","getPlatform","userAgentData","version","majorVersion","isLegacyTV","webOSVersion","tizenVersion","chromeVersionNum","chromeVersion","webkitVersion","browser","allowNativeHls","debug","feature","parseCueOutDuration","num","parseFloat","dStr","d","parseCueOutCont","res","elapsedMatch","durationMatch","elapsed","slashMatch","parseAttributeList","attrs","regex","exec","rawVal","toNumber","n","isManifestBasedMarker","marker","id3","splice_command_type","decodeId3ValueToText","decoder","TextDecoder","decode","out","fromCharCode","getFragmentStartSeconds","frag","startPTS","candidate","parseScte35FromId3","cueOutMatch","arg","dur","ptsSeconds","durationSeconds","cueOutContMatch","cont","cueInMatch","daterangeMatch","hasScteOut","hasScteIn","klass","bin","parseScte35Binary","normalizeFragmentPayload","ArrayBuffer","isView","view","byteOffset","byteLength","detectTsPacketFormat","packetSizes","packetSize","tsPayloadOffset","offset","matchedPackets","packetStart","getPsiSectionStart","payloadUnitStart","pointerField","sectionStart","getPsiSectionLength","parsePatSection","pmtPids","sectionLength","sectionEnd","programNumber","pid","descriptorsIdentifyScte35","descriptorStart","descriptorEnd","registration","parsePmtSection","tsScte35Pids","programInfoLength","streamType","elementaryPid","esInfoLength","hasProcessedTsScte35Section","section","processedSections","checksum","size","firstKey","next","addScte35SectionMarker","markers","appendScte35Bytes","bytes","assemblers","assembler","expectedLength","collectScte35SectionsFromPayload","previousAssembler","subarray","tableId","totalLength","parseScte35FromTsPackets","packetInfo","sectionAssemblers","tsStart","secondByte","thirdByte","fourthByte","adaptationFieldControl","hasPayload","payloadStart","adaptationLength","payloadEnd","BitReader","bytePos","bitPos","readBits","numBits","remainingInByte","toRead","currentByte","shift","mask","bits","skipBits","bytePosition","readSpliceTime","r","ptsAdjustmentTicks","timeSpecifiedFlag","high","low","ptsTicks","markerTypeFromSegmentationTypeId","segmentationTypeId","parseScte35SegmentationDescriptor","descriptor","identifier","segmentationEventId","cancelIndicator","programSegmentationFlag","segmentationDurationFlag","componentCount","durationTicks","segmentationUpidLength","markerType","parseScte35SegmentationDescriptors","descriptorLoopLength","descriptorOffset","descriptorTag","descriptorLength","descriptorDataStart","descriptorDataEnd","descriptorMarker","ptsAdjHigh","ptsAdjLow","spliceCommandLength","spliceCommandType","spliceEventId","commandBodyStart","cancel","outOfNetwork","programSpliceFlag","durationFlag","spliceImmediateFlag","componentPtsSeconds","expectedDescriptorOffset","splice_event_id","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","adRequestPositionInBreak","lastHeartbeatTime","defaultPodMaxAds","isVmapEnabled","isVmap","vmapUrl","fetchAdConfiguration","vastMode","vastEndpoint","apiUrl","imaPayload","decodedPayload","numberAds","fetchAndParseVmap","apiVastTagUrl","json","ima","vast","cue_tones","number_ads","apiNumberAds","vmapXml","parseVmapToBreaks","doc","VMAP_NS","adBreakNodes","getElementsByTagNameNS","getElementsByTagName","localName","node","timeOffsetRaw","startTimeMs","parseVmapTimeOffsetToMs","adTagNode","adTagUrl","breakId","aStart","bStart","timeOffset","hms","hh","mm","ss","ms","hours","minutes","seconds","millis","percent","ratio","durationSec","getAdBreakKey","adBreak","resolveBreakStartMs","findCurrentOrNextBreak","nowMs","schedule","tol","driftToleranceMs","breakStartMs","findBreakForTime","durationMs","selectVastTagsForBreak","s","beginNewAdPod","generateVastUrlsWithCorrelators","count","adPlayer","palNonce","envSignals","ctvAdRequest","urlWithMacros","autoplay","finalUrl","resolvePodParams","breakDurationMs","maxDurationMs","maxAds","minDurationMs","podExactDuration","generatePodVastUrl","podParams","initializeTracking","heartbeatInterval","setInterval","sendHeartbeatIfNeeded","destroyTracking","clearInterval","AdTimingService","adRequestWatchdogToken","adFailsafeToken","ptsDriftEmaMs","adBreakPlayedDurationMs","adBreakEpoch","adRequestTokenCounter","activeAdRequestToken","currentAdIndex","totalAdsInBreak","totalAdRequestsInBreak","maxTotalAdRequestsPerBreak","lastAdRequestTime","consecutiveFailures","maxConsecutiveFailures","minAdRequestIntervalMs","backoffBaseMs","maxBackoffMs","defaultMinRemainingMsToStartAd","failedVastUrls","temporaryFailureUrls","temporaryFailureCooldownMs","globalConsecutiveNoFills","globalNoFillThreshold","globalNoFillCooldownUntil","globalNoFillBackoffBaseMs","globalNoFillBackoffMaxMs","globalLastGamRequestTime","globalMinGamIntervalMs","scheduleAdStopCountdown","remainingMs","clearAdStopTimer","ensureAdStoppedByTimer","adStopTimerId","onAdStopTimerFired","scheduleAdStartIn","delayMs","cueKey","clearAdStartTimer","onAdStartTimerFired","adStartTimerId","updatePtsDrift","ptsSecondsSample","sampleMs","alpha","resolveScteBreakStartWallClockMs","nowWallClockMs","estimatedCurrentPtsMs","deltaMs","setAdBreakDurationBoundary","expectedAdBreakDurationMs","currentAdBreakStartWallClockMs","scteAdBreakEndWallClockMs","scheduleAdStopAtBreakBoundary","getWallClockRemainingAdMs","endWallClockMs","getAdBreakEndWallClockMs","getDurationBudgetRemainingMs","getLoadedAdDurationMs","adController","adFitsRemainingBudget","logAdDurationDecision","accepted","remainingBudget","recordPlayedAdDuration","ensureLoadedAdFitsBudget","fits","rejectLoadedAdForDuration","markAdStarted","notePodAdStarted","getRemainingAdMs","wallClockRemaining","budgetRemaining","getMinRemainingMsToStartAd","configured","minRemainingMsToStartAd","hasTimeToStartAnotherAd","minRemaining","isTemporaryAdError","isUrlInCooldown","failureTime","cleanupTemporaryFailures","isGamInCooldown","recordGamNoFill","exponent","backoff","pow","resetGamNoFillCounter","enforceGlobalRateLimit","waitMs","startAdRequestWatchdog","token","clearAdRequestWatchdog","adFailsafeTimeoutMs","adRequestWatchdogId","logAdState","onWatchdogTimeout","startAdFailsafeTimer","clearAdFailsafeTimer","failsafeMs","adFailsafeTimerId","videoPaused","onFailsafeTimeout","extra","showAds","resetForBreakEnd","AdPreloadPool","deps","pool","maxPoolSize","poolActive","loopRunning","active","isLoopRunning","startPreloadPool","baseVastUrl","initialUrls","startLoopImmediately","preloadAdIntoPool","preloadPoolLoop","vastUrl","timing","epoch","loadPromise","some","entry","hasAdError","adErrorPayload","errorListenerCleanup","preloadAd","errorListener","isNoFill","poolEntry","loadedDuration","lateErrorListener","shouldContinueLiveStreamDuringAds","createAdPlayer","code","vastErrorCode","loadedAt","isReady","findIndex","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","liveDurationInfinity","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","earlyDetection","FRAG_BUFFERED","FRAG_PARSING_METADATA","id3Tags","samples","pts","onId3Tag","FRAG_LOADED","processFragmentScte35Payload","FRAG_DECRYPTED","FRAG_CHANGED","activatePendingCuesForFragment","prog","ErrorTypes","NETWORK_ERROR","startLoad","MEDIA_ERROR","recoverMediaError","onFatalDestroy","payloadData","getLiveSyncPosition","liveSyncPosition","getAdAudioVolume","toggleMute","newMutedState","restoreVolume","toggleFullscreen","fullscreenElement","requestFullscreen","isMuted","setMuted","setVolume","clampedVolume","getVolume","isFullscreen","resizePlayer","clientWidth","clientHeight","AdBreakOrchestrator","host","preloadPool","adConfig","placeholder","isShowingPlaceholder","adDetectSentForCurrentBreak","continuousFetchingActive","continuousFetchLoopRunning","adRequestQueue","adPodQueue","maxPlaceholderDurationMs","pendingAdBreak","analyticsContext","optimizedPodsEnabled","optimizedPods","attachImaEventListeners","getAdPlayer","adIndex","remaining","queuedUrls","tryNextAvailableAdWithRateLimit","handleAdPodComplete","errorPayload","errorMessage","errorCode","cause","innerError","causeMessage","handleAdFailure","recreateAdController","shouldShowPlaceholder","preservedMutedState","preservedVolumeState","newAdPlayer","setAdPlayer","clearPendingAdBreak","prefetchTimerId","handleAdStart","_marker","scheduled","tags","adBreakDurationMs","currentMuted","currentVolume","podPlayed","firstAdUrl","usePreloadedAd","preloadedController","firstAdUrlArray","preservedMuted","preservedVolume","adVolume","fallbackPreloaded","ap","fallbackError","startOptimizedPod","vastUrls","generateVastUrls","startContinuousFetching","swapToPreloadedAdPlayer","podUrl","requestToken","podCount","continuousFetchLoop","maxQueueSize","newAdUrl","queuedUrlsPreview","generationDelay","stopContinuousFetching","backoffMultiplier","backoffDelay","effectiveMinInterval","timeSinceLastRequest","waitTime","tryNextAvailableAd","retryCount","nextAdUrl","maxRetries","playSingleAd","showPlaceholderAndWaitForAds","playError","preloadedFallback","fbAp","checkInterval","maxChecks","restoredMuted","restoredVolume","liveSyncPos","toFixed","attached","palPlaybackStarted","browserOverrides","videoElement","startAdPrefetch","onScte35Marker","startScte35AdBreak","c","hlsEngine","p","attach","offsetWidth","prerollKey","endedHandler","onVideoEnded","timeUpdateHandler","onTimeUpdate","emptiedHandler","wasPaused","Infinity","newDurationMs","detectPayload","hasPrefetchedAds","isManifest","forceImmediate","immediateManifestAds","isManifestMarker","hasPts","estCurrentPtsMs","markerPtsMs","tolerance","hasQueuedAds","activeAdRequest","checkIntervalMs","adBreakCheckIntervalMs","maxExtensionMsConfig","maxAdBreakExtensionMs","maxExtensionMs","overrunMs","shouldExtendAdBreak","generatedUrls","detectedAtFragmentSn","isFetching","fetchStartTime","currentTimeSec","breakToPlay","handleVmapAdBreak","postroll","find","endMs","inWindow","first","rest","getCurrentAdIndex","getTotalAdsInBreak","getAdRemainingMs","isShowingAds","shouldShowNativeControls","showCustomControls","removeEventListener","import_fa","import_jsx_runtime","CRITICAL_PROPS","CONTROLS_HIDE_DELAY","DEFAULT_PLAYER_ASPECT_RATIO","React","memo","props","hideLoadingIndicator","onVolumeToggle","onFullscreenToggle","onControlClick","onReady","wrapperClassName","wrapperStyle","className","controls","preload","poster","children","restVideoAttrs","videoRef","useRef","playerRef","bufferingTimeoutRef","controlsTimerRef","wrapperRef","useState","currentIndex","totalAds","remainingSeconds","adStatus","setAdStatus","setShouldShowNativeControls","setIsMuted","setIsFullscreen","setIsPlaying","setCurrentTime","setDuration","playbackRate","setPlaybackRate","showVolumeSlider","setShowVolumeSlider","showSpeedMenu","setShowSpeedMenu","isLoading","setIsLoading","isBuffering","setIsBuffering","showCenterPlay","setShowCenterPlay","showLicenseWarning","setShowLicenseWarning","controlsVisible","setControlsVisible","innerWidth","viewportWidth","setViewportWidth","innerHeight","isPortrait","setIsPortrait","playerAspectRatio","setPlayerAspectRatio","getResponsiveScale","responsiveScale","resetControlsTimer","useCallback","current","handleWrapperMouseMove","handleWrapperMouseLeave","formatTime","handlePlayPause","hasValidSource","currentSrc","readyState","handleCenterPlayClick","handleTimelineSeek","rect","currentTarget","getBoundingClientRect","clickX","clientX","newTime","handleVolumeChange","newVolume","handlePlaybackRateChange","rate","isHlsStream","isLiveUiMode","shouldShowEnhancedControls","criticalPropsKey","useMemo","prop","useEffect","cfg","player","showNative","checkAdStatus","showAdsFromMethod","showAdsFromAttribute","ceil","prev","interval","handleResize","updateStates","currentTimeValue","durationValue","volumeValue","rateValue","handleFullscreenChange","handleLoadedMetadata","handleLoadedData","handleLoadStart","handleCanPlay","handleCanPlayThrough","handleWaiting","handlePlaying","handlePause","isAdActive","handleEnded","progressPercent","VolumeIcon","FaVolumeMute","FaVolumeDown","FaVolumeUp","jsxs","Fragment","jsx","ref","onMouseMove","onMouseLeave","overflow","minHeight","aspectRatio","maxWidth","maxHeight","borderRadius","boxShadow","transform","animation","inset","border","borderTopColor","borderRightColor","background","backdropFilter","color","padding","textAlign","margin","fontSize","fontWeight","marginBottom","letterSpacing","lineHeight","gap","textTransform","onClick","cursor","onMouseEnter","FaPlay","marginLeft","minWidth","FaPause","paddingRight","paddingLeft","onMouseDown","preventDefault","move","ev","up","stopPropagation","fontFamily","fontVariantNumeric","userSelect","WebkitBackdropFilter","speed","FaCompress","FaExpand","flexShrink","textShadow","flexDirection","prevProps","nextProps","uiProps","callbackProps","noop","defaultProps","playing","loop","progressInterval","onStart","onPlay","onPause","onBuffer","onBufferEnd","onEnded","onError","onDuration","onSeek","onProgress","import_react2","reactLazy","object","MediaStream","queryString","manualParse","qs","isObject","item","globalThis","HLS_EXTENSIONS","HLS_PATHS","DASH_EXTENSIONS","VIDEO_EXTENSIONS","AUDIO_EXTENSIONS","dash","audio","HlsPlayer","arguments","mounted","onMount","seekTo","keepPlaying","getDuration","getCurrentTime","getSecondsLoaded","buffered","getInternalPlayer","componentDidMount","componentWillUnmount","componentDidUpdate","render","import_react3","Component","displayName","FilePlayer","ready","handlePlay","handleError","onLoaded","setLoop","enablePIP","requestPictureInPicture","disablePIP","pictureInPictureElement","exitPictureInPicture","import_react4","lazyPlayer","canEnablePIP","pictureInPictureEnabled","webkitSupportsPresentationMode","SEEK_ON_PLAY_EXPIRY","Player","loadOnReady","startOnPlay","seekOnPlay","onDurationCalled","handlePlayerMount","playedSeconds","loadedSeconds","played","loaded","prevPlayed","prevLoaded","progressTimeout","handleReady","handleDurationCheck","activePlayer","loopOnEnded","args","durationCheckTimeout","handleLoaded","forceLoad","amount","isFraction","import_react5","UniversalSuspense","import_react6","Suspense","SUPPORTED_PROPS","customPlayers","playerList","fallback","_a","state","showPreview","references","wrapper","getActivePlayer","getAttributes","fraction","renderActivePlayer","fallbackElement","Wrapper","attributes","addCustomPlayer","removeCustomPlayers"],"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/index.ts\nvar index_exports = {};\n__export(index_exports, {\n  DEFAULT_MQTT_CONFIG: () => DEFAULT_MQTT_CONFIG,\n  IS_BROWSER: () => IS_BROWSER,\n  IS_GLOBAL: () => IS_GLOBAL,\n  IS_IOS: () => IS_IOS,\n  IS_SAFARI: () => IS_SAFARI,\n  MQTT_CA_CERT_FILE: () => MQTT_CA_CERT_FILE,\n  SUPPORTS_DASH: () => SUPPORTS_DASH,\n  SUPPORTS_HLS: () => SUPPORTS_HLS,\n  StormcloudPlayer: () => StormcloudPlayer_default,\n  StormcloudVideoPlayer: () => StormcloudVideoPlayer,\n  StormcloudVideoPlayerComponent: () => StormcloudVideoPlayerComponent,\n  applyMQTTConfig: () => applyMQTTConfig,\n  buildAnalyticsContext: () => buildAnalyticsContext,\n  buildMQTTBrokerUrl: () => buildMQTTBrokerUrl,\n  buildPlayerTopic: () => buildPlayerTopic,\n  canPlay: () => canPlay,\n  configureMQTT: () => configureMQTT,\n  createHlsAdPlayer: () => createHlsAdPlayer,\n  createPalNonceManager: () => createPalNonceManager,\n  createStormcloudPlayer: () => createStormcloudPlayer,\n  default: () => StormcloudVideoPlayerComponent,\n  detectBrowser: () => detectBrowser,\n  disconnectMQTT: () => disconnectMQTT,\n  ensureMQTTClient: () => ensureMQTTClient,\n  getBrowserConfigOverrides: () => getBrowserConfigOverrides,\n  getBrowserID: () => getBrowserID,\n  getClientInfo: () => getClientInfo,\n  getMQTTStatus: () => getMQTTStatus,\n  initMQTTClient: () => initMQTTClient,\n  initializePolyfills: () => initializePolyfills,\n  isMQTTConfigured: () => isMQTTConfigured,\n  isMQTTConnected: () => isMQTTConnected,\n  isMQTTEnabled: () => isMQTTEnabled,\n  isMediaStream: () => isMediaStream,\n  lazy: () => lazy,\n  logBrowserInfo: () => logBrowserInfo,\n  merge: () => merge,\n  mqttConfig: () => mqttConfig,\n  omit: () => omit,\n  parseQuery: () => parseQuery,\n  players: () => players_default,\n  publishMQTT: () => publishMQTT,\n  randomString: () => randomString,\n  sendAdDetectTracking: () => sendAdDetectTracking,\n  sendAdImpressionTracking: () => sendAdImpressionTracking,\n  sendAdLoadedTracking: () => sendAdLoadedTracking,\n  sendHeartbeat: () => sendHeartbeat,\n  sendInitialTracking: () => sendInitialTracking,\n  supportsFeature: () => supportsFeature,\n  supportsModernJS: () => supportsModernJS,\n  supportsWebKitPresentationMode: () => supportsWebKitPresentationMode\n});\nmodule.exports = __toCommonJS(index_exports);\n\n// src/ui/StormcloudVideoPlayer.tsx\nvar import_react = __toESM(require(\"react\"), 1);\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 MQTT_CA_CERT_FILE = \"src/certs/emqxsl-ca.crt\";\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 applyMQTTConfig(overrides) {\n  Object.assign(mqttConfig, overrides);\n}\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 getMQTTStatus() {\n  return status;\n}\nfunction isMQTTConnected() {\n  return status === \"connected\" && client !== null && client.connected;\n}\nfunction isMQTTConfigured() {\n  return isMQTTEnabled();\n}\nfunction configureMQTT(overrides) {\n  applyMQTTConfig(overrides);\n  disconnectMQTT();\n}\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}\nfunction disconnectMQTT() {\n  if (client) {\n    client.end(true);\n    client = null;\n    status = \"disconnected\";\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 = readStoredString(storageKey);\n  if (existing) {\n    return existing;\n  }\n  const id = createUuid();\n  try {\n    window.localStorage?.setItem(storageKey, id);\n  } catch {\n  }\n  return id;\n}\nfunction getOrCreateCtvSessionId() {\n  const existing = readStoredString(CTV_SESSION_STORAGE_KEY);\n  if (existing) {\n    return existing;\n  }\n  const sessionId = createUuid();\n  try {\n    window.localStorage?.setItem(CTV_SESSION_STORAGE_KEY, sessionId);\n  } catch {\n  }\n  return sessionId;\n}\nfunction createUuid() {\n  if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n    return crypto.randomUUID();\n  }\n  return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (char) => {\n    const value = Math.floor(Math.random() * 16);\n    const nibble = char === \"x\" ? value : value & 3 | 8;\n    return nibble.toString(16);\n  });\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 supportsModernJS2 = 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        supportsModernJS2 = false;\n      }\n    }\n    if (webkitVersion > 0 && webkitVersion < 600) {\n      supportsModernJS2 = false;\n    }\n  }\n  if (typeof Promise === \"undefined\" || typeof Map === \"undefined\" || typeof Set === \"undefined\") {\n    supportsModernJS2 = false;\n  }\n  if (typeof URLSearchParams === \"undefined\") {\n    supportsModernJS2 = false;\n  }\n  return {\n    name,\n    version,\n    majorVersion,\n    isSmartTV,\n    isLegacyTV,\n    platform,\n    supportsModernJS: supportsModernJS2,\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 supportsModernJS() {\n  try {\n    return typeof Promise !== \"undefined\" && typeof Map !== \"undefined\" && typeof Set !== \"undefined\" && typeof Array.from !== \"undefined\" && typeof Object.assign !== \"undefined\" && typeof Array.prototype.forEach !== \"undefined\" && typeof String.prototype.includes !== \"undefined\";\n  } catch (e) {\n    return false;\n  }\n}\nfunction logBrowserInfo(debug = false) {\n  if (!debug) return;\n  const browser = detectBrowser();\n  console.log(\"[StormcloudVideoPlayer] Browser Compatibility Info:\", {\n    browser: `${browser.name} ${browser.version}`,\n    platform: browser.platform,\n    isSmartTV: browser.isSmartTV,\n    isLegacyTV: browser.isLegacyTV,\n    supportsModernJS: browser.supportsModernJS,\n    ...browser.webOSVersion !== void 0 ? { webOSVersion: browser.webOSVersion } : {},\n    ...browser.tizenVersion !== void 0 ? { tizenVersion: browser.tizenVersion } : {},\n    ...browser.chromeVersion !== void 0 ? { chromeVersion: browser.chromeVersion } : {},\n    userAgent: navigator.userAgent\n  });\n}\nfunction supportsFeature(feature) {\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\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\n// src/ui/StormcloudVideoPlayer.tsx\nvar import_fa = require(\"react-icons/fa\");\nvar import_jsx_runtime = require(\"react/jsx-runtime\");\nvar CRITICAL_PROPS = [\n  \"src\",\n  \"allowNativeHls\",\n  \"isLiveStream\",\n  \"licenseKey\",\n  \"isVmap\",\n  \"vmapUrl\",\n  \"lowLatencyMode\",\n  \"driftToleranceMs\",\n  \"vastMode\",\n  \"ctvAdRequest\"\n];\nvar CONTROLS_HIDE_DELAY = 3e3;\nvar DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;\nvar StormcloudVideoPlayerComponent = import_react.default.memo(\n  (props) => {\n    const {\n      src,\n      autoplay,\n      muted,\n      lowLatencyMode,\n      allowNativeHls,\n      isLiveStream,\n      driftToleranceMs,\n      immediateManifestAds,\n      debugAdTiming,\n      showCustomControls,\n      hideLoadingIndicator,\n      onVolumeToggle,\n      onFullscreenToggle,\n      onControlClick,\n      onReady,\n      wrapperClassName,\n      wrapperStyle,\n      className,\n      style,\n      controls,\n      playsInline,\n      preload,\n      poster,\n      children,\n      licenseKey,\n      vastMode,\n      vastTagUrl,\n      isVmap,\n      vmapUrl,\n      minSegmentsBeforePlay,\n      ctvAdRequest,\n      ...restVideoAttrs\n    } = props;\n    const videoRef = (0, import_react.useRef)(null);\n    const playerRef = (0, import_react.useRef)(null);\n    const bufferingTimeoutRef = (0, import_react.useRef)(null);\n    const controlsTimerRef = (0, import_react.useRef)(null);\n    const wrapperRef = (0, import_react.useRef)(null);\n    const [adStatus, setAdStatus] = import_react.default.useState({ showAds: false, currentIndex: 0, totalAds: 0, remainingSeconds: 0 });\n    const [shouldShowNativeControls, setShouldShowNativeControls] = import_react.default.useState(true);\n    const [isMuted2, setIsMuted] = import_react.default.useState(false);\n    const [isFullscreen2, setIsFullscreen] = import_react.default.useState(false);\n    const [isPlaying, setIsPlaying] = import_react.default.useState(false);\n    const [currentTime, setCurrentTime] = import_react.default.useState(0);\n    const [duration, setDuration] = import_react.default.useState(0);\n    const [volume, setVolume2] = import_react.default.useState(1);\n    const [playbackRate, setPlaybackRate] = import_react.default.useState(1);\n    const [showVolumeSlider, setShowVolumeSlider] = import_react.default.useState(false);\n    const [showSpeedMenu, setShowSpeedMenu] = import_react.default.useState(false);\n    const [isLoading, setIsLoading] = import_react.default.useState(true);\n    const [isBuffering, setIsBuffering] = import_react.default.useState(false);\n    const [showCenterPlay, setShowCenterPlay] = import_react.default.useState(false);\n    const [showLicenseWarning, setShowLicenseWarning] = import_react.default.useState(false);\n    const [controlsVisible, setControlsVisible] = import_react.default.useState(true);\n    const [viewportWidth, setViewportWidth] = import_react.default.useState(\n      typeof window !== \"undefined\" ? window.innerWidth : 1920\n    );\n    const [isPortrait, setIsPortrait] = import_react.default.useState(\n      typeof window !== \"undefined\" ? window.innerHeight > window.innerWidth : false\n    );\n    const [playerAspectRatio, setPlayerAspectRatio] = import_react.default.useState(\n      DEFAULT_PLAYER_ASPECT_RATIO\n    );\n    const getResponsiveScale = () => {\n      if (viewportWidth < 480) return 0.7;\n      if (viewportWidth < 768) return 0.8;\n      if (viewportWidth < 1024) return 0.9;\n      return 1;\n    };\n    const responsiveScale = getResponsiveScale();\n    const resetControlsTimer = (0, import_react.useCallback)(() => {\n      if (controlsTimerRef.current) {\n        clearTimeout(controlsTimerRef.current);\n      }\n      setControlsVisible(true);\n      controlsTimerRef.current = window.setTimeout(() => {\n        if (!showVolumeSlider && !showSpeedMenu) {\n          setControlsVisible(false);\n        }\n      }, CONTROLS_HIDE_DELAY);\n    }, [showVolumeSlider, showSpeedMenu]);\n    const handleWrapperMouseMove = (0, import_react.useCallback)(() => {\n      resetControlsTimer();\n    }, [resetControlsTimer]);\n    const handleWrapperMouseLeave = (0, import_react.useCallback)(() => {\n      if (!showVolumeSlider && !showSpeedMenu) {\n        setControlsVisible(false);\n      }\n    }, [showVolumeSlider, showSpeedMenu]);\n    const formatTime = (seconds) => {\n      if (!isFinite(seconds)) return \"0:00:00\";\n      const hours = Math.floor(seconds / 3600);\n      const minutes = Math.floor(seconds % 3600 / 60);\n      const remainingSeconds = Math.floor(seconds % 60);\n      return `${hours}:${minutes.toString().padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n    };\n    const handlePlayPause = () => {\n      if (videoRef.current) {\n        if (videoRef.current.paused) {\n          const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n          if (hasValidSource) {\n            videoRef.current.play()?.catch((error) => {\n              console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n            });\n            setShowCenterPlay(false);\n          } else {\n            console.warn(\n              \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n            );\n          }\n        } else {\n          videoRef.current.pause();\n          setShowCenterPlay(true);\n        }\n      }\n      resetControlsTimer();\n    };\n    const handleCenterPlayClick = () => {\n      if (videoRef.current && videoRef.current.paused) {\n        const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n        if (hasValidSource) {\n          videoRef.current.play()?.catch((error) => {\n            console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n          });\n          setShowCenterPlay(false);\n        } else {\n          console.warn(\n            \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n          );\n        }\n      }\n    };\n    const handleTimelineSeek = (e) => {\n      if (videoRef.current && duration > 0 && isFinite(duration)) {\n        const rect = e.currentTarget.getBoundingClientRect();\n        const clickX = e.clientX - rect.left;\n        const progress = Math.max(0, Math.min(1, clickX / rect.width));\n        const newTime = progress * duration;\n        if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n          videoRef.current.currentTime = newTime;\n        }\n      }\n      resetControlsTimer();\n    };\n    const handleVolumeChange = (newVolume) => {\n      if (playerRef.current && isFinite(newVolume)) {\n        const clampedVolume = Math.max(0, Math.min(1, newVolume));\n        playerRef.current.setVolume(clampedVolume);\n      }\n    };\n    const handlePlaybackRateChange = (rate) => {\n      if (videoRef.current && isFinite(rate) && rate > 0) {\n        videoRef.current.playbackRate = rate;\n      }\n      setShowSpeedMenu(false);\n    };\n    const isHlsStream = src?.toLowerCase().includes(\".m3u8\") || src?.toLowerCase().includes(\"/hls/\");\n    const isLiveUiMode = isLiveStream === true;\n    const shouldShowEnhancedControls = showCustomControls && (isHlsStream ? !isLiveUiMode : true);\n    const criticalPropsKey = (0, import_react.useMemo)(() => {\n      return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n    }, [\n      src,\n      allowNativeHls,\n      isLiveStream,\n      licenseKey,\n      isVmap,\n      vmapUrl,\n      lowLatencyMode,\n      driftToleranceMs,\n      vastMode\n    ]);\n    (0, import_react.useEffect)(() => {\n      if (typeof window === \"undefined\") return;\n      const el = videoRef.current;\n      if (!el || !src) return;\n      if (!licenseKey) {\n        setShowLicenseWarning(true);\n        setIsLoading(false);\n        console.warn(\n          \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n        );\n        return;\n      }\n      setShowLicenseWarning(false);\n      if (debugAdTiming) {\n        console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n      }\n      if (playerRef.current) {\n        try {\n          playerRef.current.destroy();\n        } catch {\n        }\n        playerRef.current = null;\n      }\n      const cfg = {\n        src,\n        videoElement: el\n      };\n      if (autoplay !== void 0) cfg.autoplay = autoplay;\n      if (muted !== void 0) cfg.muted = muted;\n      if (lowLatencyMode !== void 0) cfg.lowLatencyMode = lowLatencyMode;\n      if (allowNativeHls !== void 0) cfg.allowNativeHls = allowNativeHls;\n      if (isLiveStream !== void 0) cfg.isLiveStream = isLiveStream;\n      if (driftToleranceMs !== void 0)\n        cfg.driftToleranceMs = driftToleranceMs;\n      if (immediateManifestAds !== void 0)\n        cfg.immediateManifestAds = immediateManifestAds;\n      if (debugAdTiming !== void 0) cfg.debugAdTiming = debugAdTiming;\n      if (showCustomControls !== void 0)\n        cfg.showCustomControls = showCustomControls;\n      if (onVolumeToggle !== void 0) cfg.onVolumeToggle = onVolumeToggle;\n      if (onFullscreenToggle !== void 0)\n        cfg.onFullscreenToggle = onFullscreenToggle;\n      if (onControlClick !== void 0) cfg.onControlClick = onControlClick;\n      if (licenseKey !== void 0) cfg.licenseKey = licenseKey;\n      if (vastMode !== void 0) cfg.vastMode = vastMode;\n      if (vastTagUrl !== void 0) cfg.vastTagUrl = vastTagUrl;\n      if (isVmap !== void 0) cfg.isVmap = isVmap;\n      if (vmapUrl !== void 0) cfg.vmapUrl = vmapUrl;\n      if (minSegmentsBeforePlay !== void 0)\n        cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n      if (ctvAdRequest !== void 0) cfg.ctvAdRequest = ctvAdRequest;\n      const player = new StormcloudVideoPlayer(cfg);\n      playerRef.current = player;\n      player.load().then(() => {\n        const showNative = player.shouldShowNativeControls();\n        setShouldShowNativeControls(showNative);\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n          );\n        }\n        onReady?.(player);\n      }).catch((error) => {\n        console.error(\n          \"StormcloudVideoPlayer: Failed to load player:\",\n          error\n        );\n        setIsLoading(false);\n        onReady?.(player);\n      });\n      return () => {\n        try {\n          player.destroy();\n        } catch {\n        }\n        playerRef.current = null;\n      };\n    }, [criticalPropsKey]);\n    (0, import_react.useEffect)(() => {\n      if (!playerRef.current) return;\n      try {\n        if (autoplay !== void 0 && playerRef.current.videoElement) {\n          playerRef.current.videoElement.autoplay = autoplay;\n        }\n        if (muted !== void 0 && !playerRef.current.isShowingAds()) {\n          playerRef.current.setMuted(muted);\n        }\n      } catch (error) {\n        console.warn(\"Failed to update player properties:\", error);\n      }\n    }, [autoplay, muted]);\n    (0, import_react.useEffect)(() => {\n      if (!playerRef.current) return;\n      const checkAdStatus = () => {\n        if (playerRef.current) {\n          const showAdsFromMethod = playerRef.current.isShowingAds();\n          const showAdsFromAttribute = videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n          const showAds = showAdsFromMethod || showAdsFromAttribute;\n          const currentIndex = playerRef.current.getCurrentAdIndex();\n          const totalAds = playerRef.current.getTotalAdsInBreak();\n          const remainingMs = playerRef.current.getAdRemainingMs();\n          const remainingSeconds = showAds ? Math.max(0, Math.ceil(remainingMs / 1e3)) : 0;\n          setAdStatus((prev) => {\n            if (prev.showAds !== showAds || prev.currentIndex !== currentIndex || prev.totalAds !== totalAds || prev.remainingSeconds !== remainingSeconds) {\n              if (showAds && !prev.showAds) {\n                setShowCenterPlay(false);\n              }\n              return { showAds, currentIndex, totalAds, remainingSeconds };\n            }\n            return prev;\n          });\n        }\n      };\n      const interval = setInterval(checkAdStatus, 50);\n      return () => clearInterval(interval);\n    }, []);\n    (0, import_react.useEffect)(() => {\n      if (typeof window === \"undefined\" || !playerRef.current) return;\n      const handleResize = () => {\n        if (playerRef.current && videoRef.current) {\n          if (typeof playerRef.current.resize === \"function\") {\n            playerRef.current.resize();\n          }\n        }\n        setViewportWidth(window.innerWidth);\n        setIsPortrait(window.innerHeight > window.innerWidth);\n      };\n      window.addEventListener(\"resize\", handleResize);\n      return () => window.removeEventListener(\"resize\", handleResize);\n    }, []);\n    (0, import_react.useEffect)(() => {\n      if (!playerRef.current || !videoRef.current) return;\n      const updateStates = () => {\n        if (playerRef.current && videoRef.current) {\n          setIsMuted(playerRef.current.isMuted());\n          setIsPlaying(!videoRef.current.paused);\n          const currentTimeValue = videoRef.current.currentTime;\n          setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n          const durationValue = videoRef.current.duration;\n          setDuration(isFinite(durationValue) ? durationValue : 0);\n          const volumeValue = playerRef.current.getVolume();\n          setVolume2(\n            isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n          );\n          const rateValue = videoRef.current.playbackRate;\n          setPlaybackRate(\n            isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n          );\n        }\n        setIsFullscreen(\n          document.fullscreenElement === wrapperRef.current\n        );\n      };\n      const interval = setInterval(updateStates, 200);\n      const handleFullscreenChange = () => {\n        setIsFullscreen(\n          document.fullscreenElement === wrapperRef.current\n        );\n      };\n      document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n      return () => {\n        clearInterval(interval);\n        document.removeEventListener(\n          \"fullscreenchange\",\n          handleFullscreenChange\n        );\n      };\n    }, []);\n    (0, import_react.useEffect)(() => {\n      if (!videoRef.current) return;\n      const handleLoadedMetadata = () => {\n        const video2 = videoRef.current;\n        if (video2) {\n          if (video2.videoWidth > 0 && video2.videoHeight > 0) {\n            setPlayerAspectRatio(video2.videoWidth / video2.videoHeight);\n          }\n          void video2.offsetHeight;\n        }\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n            videoRef.current?.readyState\n          );\n        }\n      };\n      const handleLoadedData = () => {\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: loadeddata, readyState:\",\n            videoRef.current?.readyState\n          );\n        }\n      };\n      const handleLoadStart = () => {\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: loadstart, readyState:\",\n            videoRef.current?.readyState\n          );\n        }\n      };\n      const handleCanPlay = () => {\n        setIsLoading(false);\n        if (bufferingTimeoutRef.current) {\n          clearTimeout(bufferingTimeoutRef.current);\n          bufferingTimeoutRef.current = null;\n        }\n        setIsBuffering(false);\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: canplay, readyState:\",\n            videoRef.current?.readyState,\n            \"- clearing loading state, isLoading=false\"\n          );\n        }\n      };\n      const handleCanPlayThrough = () => {\n        setIsLoading(false);\n        if (bufferingTimeoutRef.current) {\n          clearTimeout(bufferingTimeoutRef.current);\n          bufferingTimeoutRef.current = null;\n        }\n        setIsBuffering(false);\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n            videoRef.current?.readyState,\n            \"- clearing loading state, isLoading=false\"\n          );\n        }\n      };\n      const handleWaiting = () => {\n        if (bufferingTimeoutRef.current) {\n          clearTimeout(bufferingTimeoutRef.current);\n        }\n        bufferingTimeoutRef.current = window.setTimeout(() => {\n          setIsBuffering(true);\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n              videoRef.current?.readyState,\n              \"- showing spinner, isBuffering=true\"\n            );\n          }\n        }, 300);\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: waiting, readyState:\",\n            videoRef.current?.readyState,\n            \"- buffering delay started (300ms)\"\n          );\n        }\n      };\n      const handlePlaying = () => {\n        setIsLoading(false);\n        if (bufferingTimeoutRef.current) {\n          clearTimeout(bufferingTimeoutRef.current);\n          bufferingTimeoutRef.current = null;\n        }\n        setIsBuffering(false);\n        setShowCenterPlay(false);\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: playing, readyState:\",\n            videoRef.current?.readyState,\n            \"- playback started, isLoading=false, isBuffering=false\"\n          );\n        }\n      };\n      const handlePause = () => {\n        const isAdActive = playerRef.current?.isShowingAds() || videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n        if (playerRef.current && !isAdActive) {\n          setShowCenterPlay(true);\n        } else {\n          setShowCenterPlay(false);\n        }\n      };\n      const handleEnded = () => {\n        setShowCenterPlay(true);\n      };\n      const video = videoRef.current;\n      video.addEventListener(\"loadstart\", handleLoadStart);\n      video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n      video.addEventListener(\"loadeddata\", handleLoadedData);\n      video.addEventListener(\"canplay\", handleCanPlay);\n      video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n      video.addEventListener(\"waiting\", handleWaiting);\n      video.addEventListener(\"playing\", handlePlaying);\n      video.addEventListener(\"pause\", handlePause);\n      video.addEventListener(\"ended\", handleEnded);\n      if (video.paused) {\n        setShowCenterPlay(true);\n      }\n      return () => {\n        if (bufferingTimeoutRef.current) {\n          clearTimeout(bufferingTimeoutRef.current);\n          bufferingTimeoutRef.current = null;\n        }\n        video.removeEventListener(\"loadstart\", handleLoadStart);\n        video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n        video.removeEventListener(\"loadeddata\", handleLoadedData);\n        video.removeEventListener(\"canplay\", handleCanPlay);\n        video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n        video.removeEventListener(\"waiting\", handleWaiting);\n        video.removeEventListener(\"playing\", handlePlaying);\n        video.removeEventListener(\"pause\", handlePause);\n        video.removeEventListener(\"ended\", handleEnded);\n      };\n    }, [debugAdTiming]);\n    (0, import_react.useEffect)(() => {\n      setPlayerAspectRatio(DEFAULT_PLAYER_ASPECT_RATIO);\n    }, [src]);\n    (0, import_react.useEffect)(() => {\n      return () => {\n        if (controlsTimerRef.current) {\n          clearTimeout(controlsTimerRef.current);\n        }\n      };\n    }, []);\n    const progressPercent = duration > 0 ? currentTime / duration * 100 : 0;\n    const VolumeIcon = isMuted2 || volume === 0 ? import_fa.FaVolumeMute : volume < 0.5 ? import_fa.FaVolumeDown : import_fa.FaVolumeUp;\n    return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n      /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"style\", { children: `\n              @keyframes sc-spin {\n                from { transform: rotate(0deg); }\n                to { transform: rotate(360deg); }\n              }\n              @keyframes sc-loading-glow {\n                0%, 100% { opacity: 0.85; transform: scale(1); }\n                50% { opacity: 1; transform: scale(1.05); }\n              }\n              @keyframes sc-pulse {\n                0%, 100% { opacity: 1; }\n                50% { opacity: 0.6; }\n              }\n              @keyframes sc-fade-in {\n                from { opacity: 0; transform: translateY(8px); }\n                to { opacity: 1; transform: translateY(0); }\n              }\n              .sc-wrapper:fullscreen,\n              .sc-wrapper:has(*:fullscreen) {\n                border-radius: 0 !important;\n                box-shadow: none !important;\n                width: 100vw !important;\n                height: 100vh !important;\n                max-width: 100vw !important;\n                max-height: 100vh !important;\n                position: fixed !important;\n                top: 0 !important;\n                left: 0 !important;\n                z-index: 999999 !important;\n                background: #000 !important;\n                display: flex !important;\n                align-items: center !important;\n                justify-content: center !important;\n              }\n              .sc-ctrl-btn {\n                background: none;\n                border: none;\n                color: #fff;\n                cursor: pointer;\n                display: flex;\n                align-items: center;\n                justify-content: center;\n                border-radius: 50%;\n                padding: 8px;\n                transition: background 0.15s ease, opacity 0.15s ease;\n                opacity: 0.9;\n              }\n              .sc-ctrl-btn:hover {\n                opacity: 1;\n                background: rgba(255, 255, 255, 0.1);\n              }\n              .sc-ctrl-btn:active {\n                opacity: 0.7;\n              }\n              .sc-controls-bar {\n                transition: opacity 0.35s ease, transform 0.35s ease;\n              }\n              .sc-progress-track:hover .sc-progress-thumb {\n                transform: translate(-50%, -50%) scale(1) !important;\n              }\n              .sc-loading-hidden .sc-loading-indicator {\n                display: none !important;\n              }\n            ` }),\n      /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n        \"div\",\n        {\n          ref: wrapperRef,\n          className: `sc-wrapper ${wrapperClassName || \"\"}`,\n          onMouseMove: handleWrapperMouseMove,\n          onMouseLeave: handleWrapperMouseLeave,\n          style: {\n            display: \"flex\",\n            alignItems: \"center\",\n            justifyContent: \"center\",\n            position: isFullscreen2 ? \"fixed\" : \"relative\",\n            top: isFullscreen2 ? 0 : void 0,\n            left: isFullscreen2 ? 0 : void 0,\n            overflow: \"hidden\",\n            width: isFullscreen2 ? \"100vw\" : \"100%\",\n            height: isFullscreen2 ? \"100vh\" : \"auto\",\n            minHeight: isFullscreen2 ? \"100vh\" : \"auto\",\n            aspectRatio: isFullscreen2 ? void 0 : playerAspectRatio,\n            maxWidth: isFullscreen2 ? \"100vw\" : \"100%\",\n            maxHeight: isFullscreen2 ? \"100vh\" : \"none\",\n            zIndex: isFullscreen2 ? 999999 : void 0,\n            backgroundColor: \"#000\",\n            borderRadius: isFullscreen2 ? 0 : void 0,\n            boxShadow: isFullscreen2 ? \"none\" : void 0,\n            ...wrapperStyle\n          },\n          children: [\n            /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n              \"video\",\n              {\n                ref: videoRef,\n                className,\n                style: {\n                  display: \"block\",\n                  width: \"100%\",\n                  height: \"100%\",\n                  maxWidth: \"100%\",\n                  maxHeight: isFullscreen2 ? \"100%\" : \"none\",\n                  objectFit: isFullscreen2 ? \"cover\" : \"contain\",\n                  backgroundColor: \"#000\",\n                  aspectRatio: isFullscreen2 ? \"unset\" : void 0,\n                  ...style\n                },\n                controls: shouldShowNativeControls && controls && !showCustomControls,\n                playsInline,\n                preload,\n                poster,\n                ...restVideoAttrs,\n                children\n              }\n            ),\n            (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n              \"div\",\n              {\n                className: \"sc-loading-indicator\",\n                style: {\n                  position: \"absolute\",\n                  top: \"50%\",\n                  left: \"50%\",\n                  transform: \"translate(-50%, -50%)\",\n                  zIndex: 20,\n                  width: `${Math.max(34, 38 * responsiveScale)}px`,\n                  height: `${Math.max(34, 38 * responsiveScale)}px`,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  justifyContent: \"center\",\n                  animation: \"sc-loading-glow 1.4s ease-in-out infinite\",\n                  filter: \"drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55))\"\n                },\n                children: [\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                    \"div\",\n                    {\n                      style: {\n                        position: \"absolute\",\n                        inset: 0,\n                        borderRadius: \"50%\",\n                        border: \"3px solid rgba(255, 255, 255, 0.25)\",\n                        borderTopColor: \"#ff0000\",\n                        borderRightColor: \"rgba(255, 255, 255, 0.85)\",\n                        animation: \"sc-spin 0.8s linear infinite\"\n                      }\n                    }\n                  ),\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                    \"div\",\n                    {\n                      style: {\n                        width: \"7px\",\n                        height: \"7px\",\n                        borderRadius: \"50%\",\n                        background: \"#ff0000\",\n                        boxShadow: \"0 0 10px rgba(255, 0, 0, 0.65)\"\n                      }\n                    }\n                  )\n                ]\n              }\n            ),\n            showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n              \"div\",\n              {\n                style: {\n                  position: \"absolute\",\n                  top: \"50%\",\n                  left: \"50%\",\n                  transform: \"translate(-50%, -50%)\",\n                  zIndex: 25,\n                  background: \"rgba(220, 38, 38, 0.92)\",\n                  backdropFilter: \"blur(24px)\",\n                  color: \"white\",\n                  padding: \"28px 36px\",\n                  borderRadius: \"14px\",\n                  border: \"1px solid rgba(255, 255, 255, 0.15)\",\n                  boxShadow: \"0 24px 64px rgba(0, 0, 0, 0.5)\",\n                  textAlign: \"center\",\n                  maxWidth: \"400px\",\n                  margin: \"0 16px\"\n                },\n                children: [\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"18px\", fontWeight: \"700\", marginBottom: \"10px\", letterSpacing: \"-0.02em\" }, children: \"License Key Required\" }),\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { fontSize: \"13px\", lineHeight: \"1.6\", color: \"rgba(255, 255, 255, 0.85)\" }, children: [\n                    \"Please provide a valid license key to use the Stormcloud Video Player.\",\n                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"br\", {}),\n                    \"Contact your administrator for licensing information.\"\n                  ] })\n                ]\n              }\n            ),\n            adStatus.showAds && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n              \"div\",\n              {\n                style: {\n                  position: \"absolute\",\n                  top: `${12 * responsiveScale}px`,\n                  left: `${12 * responsiveScale}px`,\n                  zIndex: 50,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  gap: \"8px\",\n                  pointerEvents: \"none\",\n                  animation: \"sc-fade-in 0.3s ease\"\n                },\n                children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                  \"div\",\n                  {\n                    style: {\n                      background: \"rgba(234, 179, 8, 0.95)\",\n                      color: \"#111\",\n                      padding: `${4 * responsiveScale}px ${12 * responsiveScale}px`,\n                      borderRadius: \"6px\",\n                      fontSize: `${11 * responsiveScale}px`,\n                      fontWeight: 700,\n                      letterSpacing: \"0.08em\",\n                      textTransform: \"uppercase\",\n                      boxShadow: \"0 2px 12px rgba(234, 179, 8, 0.35)\"\n                    },\n                    children: `Ad ${Math.max(1, adStatus.currentIndex)}`\n                  }\n                )\n              }\n            ),\n            showCenterPlay && !isLoading && !isBuffering && !showLicenseWarning && !adStatus.showAds && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n              \"div\",\n              {\n                onClick: handleCenterPlayClick,\n                style: {\n                  position: \"absolute\",\n                  top: \"50%\",\n                  left: \"50%\",\n                  transform: \"translate(-50%, -50%)\",\n                  zIndex: 15,\n                  cursor: \"pointer\",\n                  background: \"rgba(0, 0, 0, 0.55)\",\n                  backdropFilter: \"blur(8px)\",\n                  borderRadius: \"50%\",\n                  width: `${92 * responsiveScale}px`,\n                  height: `${92 * responsiveScale}px`,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  justifyContent: \"center\",\n                  transition: \"background 0.2s ease, transform 0.2s ease\",\n                  animation: \"sc-fade-in 0.2s ease\"\n                },\n                onMouseEnter: (e) => {\n                  e.currentTarget.style.background = \"rgba(0, 0, 0, 0.72)\";\n                  e.currentTarget.style.transform = \"translate(-50%, -50%) scale(1.06)\";\n                },\n                onMouseLeave: (e) => {\n                  e.currentTarget.style.background = \"rgba(0, 0, 0, 0.55)\";\n                  e.currentTarget.style.transform = \"translate(-50%, -50%) scale(1)\";\n                },\n                title: \"Play\",\n                children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                  import_fa.FaPlay,\n                  {\n                    size: Math.max(24, 32 * responsiveScale),\n                    color: \"white\",\n                    style: { marginLeft: \"4px\" }\n                  }\n                )\n              }\n            ),\n            shouldShowEnhancedControls && !showLicenseWarning ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n              \"div\",\n              {\n                className: \"sc-controls-bar\",\n                style: {\n                  position: \"absolute\",\n                  bottom: 0,\n                  left: 0,\n                  right: 0,\n                  background: \"linear-gradient(0deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.35) 60%, transparent 100%)\",\n                  padding: `${20 * responsiveScale}px ${12 * responsiveScale}px ${8 * responsiveScale}px`,\n                  zIndex: 10,\n                  opacity: controlsVisible || adStatus.showAds ? 1 : 0,\n                  transform: controlsVisible || adStatus.showAds ? \"translateY(0)\" : \"translateY(6px)\",\n                  pointerEvents: controlsVisible || adStatus.showAds ? \"auto\" : \"none\"\n                },\n                children: [\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                    \"div\",\n                    {\n                      className: \"sc-progress-track\",\n                      style: {\n                        width: \"100%\",\n                        height: \"3px\",\n                        background: \"rgba(255, 255, 255, 0.2)\",\n                        borderRadius: \"1.5px\",\n                        marginBottom: `${8 * responsiveScale}px`,\n                        cursor: \"pointer\",\n                        position: \"relative\",\n                        transition: \"height 0.1s ease\"\n                      },\n                      onClick: handleTimelineSeek,\n                      onMouseEnter: (e) => {\n                        e.currentTarget.style.height = \"5px\";\n                      },\n                      onMouseLeave: (e) => {\n                        e.currentTarget.style.height = \"3px\";\n                      },\n                      children: [\n                        /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                          \"div\",\n                          {\n                            style: {\n                              position: \"absolute\",\n                              top: 0,\n                              left: 0,\n                              bottom: 0,\n                              background: adStatus.showAds ? \"#f5c518\" : \"#ff0000\",\n                              borderRadius: \"1.5px\",\n                              width: `${progressPercent}%`,\n                              transition: \"width 0.15s linear\"\n                            }\n                          }\n                        ),\n                        /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                          \"div\",\n                          {\n                            className: \"sc-progress-thumb\",\n                            style: {\n                              position: \"absolute\",\n                              top: \"50%\",\n                              left: `${progressPercent}%`,\n                              transform: \"translate(-50%, -50%) scale(0)\",\n                              width: \"13px\",\n                              height: \"13px\",\n                              background: adStatus.showAds ? \"#f5c518\" : \"#ff0000\",\n                              borderRadius: \"50%\",\n                              boxShadow: \"0 0 4px rgba(0, 0, 0, 0.3)\",\n                              transition: \"transform 0.1s ease, left 0.15s linear\"\n                            }\n                          }\n                        )\n                      ]\n                    }\n                  ),\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                    \"div\",\n                    {\n                      style: {\n                        display: \"flex\",\n                        alignItems: \"center\",\n                        justifyContent: \"space-between\",\n                        color: \"white\",\n                        gap: `${8 * responsiveScale}px`\n                      },\n                      children: [\n                        /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                          \"div\",\n                          {\n                            style: {\n                              display: \"flex\",\n                              alignItems: \"center\",\n                              gap: `${8 * responsiveScale}px`\n                            },\n                            children: [\n                              /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                \"button\",\n                                {\n                                  className: \"sc-ctrl-btn\",\n                                  onClick: handlePlayPause,\n                                  style: {\n                                    padding: `${8 * responsiveScale}px`,\n                                    borderRadius: \"50%\",\n                                    minWidth: `${36 * responsiveScale}px`,\n                                    minHeight: `${36 * responsiveScale}px`\n                                  },\n                                  title: isPlaying ? \"Pause\" : \"Play\",\n                                  children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaPause, { size: Math.max(14, 18 * responsiveScale) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaPlay, { size: Math.max(14, 18 * responsiveScale), style: { marginLeft: \"2px\" } })\n                                }\n                              ),\n                              /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                \"div\",\n                                {\n                                  style: {\n                                    display: \"flex\",\n                                    alignItems: \"center\",\n                                    paddingRight: `${6 * responsiveScale}px`\n                                  },\n                                  onMouseEnter: () => setShowVolumeSlider(true),\n                                  onMouseLeave: () => setShowVolumeSlider(false),\n                                  children: [\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                      \"button\",\n                                      {\n                                        className: \"sc-ctrl-btn\",\n                                        onClick: () => {\n                                          if (playerRef.current) playerRef.current.toggleMute();\n                                          onVolumeToggle?.();\n                                          resetControlsTimer();\n                                        },\n                                        style: {\n                                          padding: `${8 * responsiveScale}px`,\n                                          borderRadius: \"50%\",\n                                          minWidth: `${36 * responsiveScale}px`,\n                                          minHeight: `${36 * responsiveScale}px`\n                                        },\n                                        title: isMuted2 ? \"Unmute\" : \"Mute\",\n                                        children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VolumeIcon, { size: Math.max(14, 18 * responsiveScale) })\n                                      }\n                                    ),\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                      \"div\",\n                                      {\n                                        style: {\n                                          width: showVolumeSlider ? `${68 * responsiveScale}px` : \"0px\",\n                                          overflow: \"hidden\",\n                                          transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n                                          display: \"flex\",\n                                          alignItems: \"center\",\n                                          paddingLeft: showVolumeSlider ? `${3 * responsiveScale}px` : \"0\",\n                                          paddingRight: showVolumeSlider ? `${8 * responsiveScale}px` : \"0\"\n                                        },\n                                        children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                          \"div\",\n                                          {\n                                            style: {\n                                              position: \"relative\",\n                                              width: `${56 * responsiveScale}px`,\n                                              height: \"3px\",\n                                              cursor: \"pointer\",\n                                              borderRadius: \"1.5px\"\n                                            },\n                                            onMouseDown: (e) => {\n                                              e.preventDefault();\n                                              const el = e.currentTarget;\n                                              const move = (ev) => {\n                                                const r2 = el.getBoundingClientRect();\n                                                handleVolumeChange(Math.max(0, Math.min(1, (ev.clientX - r2.left) / r2.width)));\n                                              };\n                                              const up = () => {\n                                                document.removeEventListener(\"mousemove\", move);\n                                                document.removeEventListener(\"mouseup\", up);\n                                              };\n                                              document.addEventListener(\"mousemove\", move);\n                                              document.addEventListener(\"mouseup\", up);\n                                              const r = el.getBoundingClientRect();\n                                              handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                                            },\n                                            onClick: (e) => {\n                                              e.stopPropagation();\n                                              const r = e.currentTarget.getBoundingClientRect();\n                                              handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                                            },\n                                            children: [\n                                              /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { position: \"absolute\", inset: 0, background: \"rgba(255, 255, 255, 0.2)\", borderRadius: \"1.5px\" } }),\n                                              /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                                \"div\",\n                                                {\n                                                  style: {\n                                                    position: \"absolute\",\n                                                    top: 0,\n                                                    left: 0,\n                                                    bottom: 0,\n                                                    width: `${(isMuted2 ? 0 : volume) * 100}%`,\n                                                    background: \"#fff\",\n                                                    borderRadius: \"1.5px\",\n                                                    transition: \"width 0.1s ease-out\"\n                                                  }\n                                                }\n                                              ),\n                                              /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                                \"div\",\n                                                {\n                                                  style: {\n                                                    position: \"absolute\",\n                                                    top: \"50%\",\n                                                    left: `${(isMuted2 ? 0 : volume) * 100}%`,\n                                                    transform: \"translate(-50%, -50%)\",\n                                                    width: \"12px\",\n                                                    height: \"12px\",\n                                                    background: \"#fff\",\n                                                    borderRadius: \"50%\",\n                                                    boxShadow: \"0 0 3px rgba(0, 0, 0, 0.3)\",\n                                                    transition: \"left 0.1s ease-out\"\n                                                  }\n                                                }\n                                              )\n                                            ]\n                                          }\n                                        )\n                                      }\n                                    )\n                                  ]\n                                }\n                              ),\n                              /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                \"div\",\n                                {\n                                  style: {\n                                    fontSize: `${13 * responsiveScale}px`,\n                                    fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\",\n                                    color: \"rgba(255, 255, 255, 0.9)\",\n                                    display: viewportWidth < 480 ? \"none\" : \"block\",\n                                    fontVariantNumeric: \"tabular-nums\",\n                                    userSelect: \"none\",\n                                    marginLeft: `${4 * responsiveScale}px`\n                                  },\n                                  children: [\n                                    formatTime(currentTime),\n                                    \" \",\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { color: \"rgba(255,255,255,0.5)\" }, children: \"/\" }),\n                                    \" \",\n                                    formatTime(duration)\n                                  ]\n                                }\n                              )\n                            ]\n                          }\n                        ),\n                        /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                          \"div\",\n                          {\n                            style: {\n                              display: \"flex\",\n                              alignItems: \"center\",\n                              gap: `${8 * responsiveScale}px`\n                            },\n                            children: [\n                              /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { position: \"relative\", display: viewportWidth < 600 ? \"none\" : \"block\" }, children: [\n                                /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                  \"button\",\n                                  {\n                                    className: \"sc-ctrl-btn\",\n                                    onClick: () => {\n                                      setShowSpeedMenu(!showSpeedMenu);\n                                      resetControlsTimer();\n                                    },\n                                    style: {\n                                      padding: `${6 * responsiveScale}px ${10 * responsiveScale}px`,\n                                      borderRadius: `${6 * responsiveScale}px`,\n                                      fontSize: `${13 * responsiveScale}px`,\n                                      fontFamily: \"'SF Mono', 'Cascadia Code', monospace\",\n                                      fontWeight: \"600\",\n                                      minHeight: `${32 * responsiveScale}px`\n                                    },\n                                    title: \"Playback Speed\",\n                                    children: [\n                                      playbackRate,\n                                      \"x\"\n                                    ]\n                                  }\n                                ),\n                                showSpeedMenu && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                  \"div\",\n                                  {\n                                    style: {\n                                      position: \"absolute\",\n                                      bottom: \"100%\",\n                                      right: 0,\n                                      marginBottom: \"8px\",\n                                      background: \"rgba(0, 0, 0, 0.8)\",\n                                      backdropFilter: \"blur(24px)\",\n                                      WebkitBackdropFilter: \"blur(24px)\",\n                                      borderRadius: \"10px\",\n                                      border: \"1px solid rgba(255, 255, 255, 0.1)\",\n                                      overflow: \"hidden\",\n                                      minWidth: \"80px\",\n                                      boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.5)\",\n                                      animation: \"sc-fade-in 0.15s ease\"\n                                    },\n                                    children: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map((speed) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                      \"button\",\n                                      {\n                                        onClick: () => handlePlaybackRateChange(speed),\n                                        style: {\n                                          display: \"block\",\n                                          width: \"100%\",\n                                          padding: `${8 * responsiveScale}px ${14 * responsiveScale}px`,\n                                          background: playbackRate === speed ? \"rgba(255, 255, 255, 0.12)\" : \"transparent\",\n                                          border: \"none\",\n                                          color: playbackRate === speed ? \"#fff\" : \"rgba(255, 255, 255, 0.7)\",\n                                          cursor: \"pointer\",\n                                          fontSize: `${12 * responsiveScale}px`,\n                                          fontFamily: \"'SF Mono', monospace\",\n                                          fontWeight: playbackRate === speed ? \"700\" : \"500\",\n                                          textAlign: \"center\",\n                                          transition: \"background 0.15s ease, color 0.15s ease\"\n                                        },\n                                        onMouseEnter: (e) => {\n                                          if (playbackRate !== speed) {\n                                            e.target.style.background = \"rgba(255, 255, 255, 0.08)\";\n                                            e.target.style.color = \"#fff\";\n                                          }\n                                        },\n                                        onMouseLeave: (e) => {\n                                          if (playbackRate !== speed) {\n                                            e.target.style.background = \"transparent\";\n                                            e.target.style.color = \"rgba(255, 255, 255, 0.7)\";\n                                          }\n                                        },\n                                        children: [\n                                          speed,\n                                          \"x\"\n                                        ]\n                                      },\n                                      speed\n                                    ))\n                                  }\n                                )\n                              ] }),\n                              /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                \"button\",\n                                {\n                                  className: \"sc-ctrl-btn\",\n                                  onClick: () => {\n                                    if (onFullscreenToggle) {\n                                      onFullscreenToggle();\n                                    } else if (wrapperRef.current) {\n                                      if (!document.fullscreenElement) {\n                                        wrapperRef.current.requestFullscreen().catch(() => {\n                                        });\n                                      } else {\n                                        document.exitFullscreen().catch(() => {\n                                        });\n                                      }\n                                    }\n                                    resetControlsTimer();\n                                  },\n                                  style: {\n                                    padding: `${8 * responsiveScale}px`,\n                                    borderRadius: \"50%\",\n                                    minWidth: `${36 * responsiveScale}px`,\n                                    minHeight: `${36 * responsiveScale}px`\n                                  },\n                                  title: isFullscreen2 ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n                                  children: isFullscreen2 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaCompress, { size: Math.max(14, 18 * responsiveScale) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaExpand, { size: Math.max(14, 18 * responsiveScale) })\n                                }\n                              )\n                            ]\n                          }\n                        )\n                      ]\n                    }\n                  )\n                ]\n              }\n            ) : showCustomControls && !showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n              /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                \"div\",\n                {\n                  style: {\n                    position: \"absolute\",\n                    top: `${10 * responsiveScale}px`,\n                    left: `${10 * responsiveScale}px`,\n                    display: \"flex\",\n                    alignItems: \"center\",\n                    gap: \"6px\",\n                    zIndex: 10,\n                    opacity: controlsVisible ? 1 : 0,\n                    transition: \"opacity 0.35s ease\"\n                  },\n                  children: [\n                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                      \"div\",\n                      {\n                        style: {\n                          width: \"8px\",\n                          height: \"8px\",\n                          borderRadius: \"50%\",\n                          background: \"#ff3b30\",\n                          animation: \"sc-pulse 1.5s ease-in-out infinite\",\n                          flexShrink: 0\n                        }\n                      }\n                    ),\n                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                      \"span\",\n                      {\n                        style: {\n                          fontSize: `${12 * responsiveScale}px`,\n                          fontFamily: \"'SF Pro Display', 'Segoe UI', Arial, sans-serif\",\n                          fontWeight: 700,\n                          letterSpacing: \"0.08em\",\n                          color: \"#fff\",\n                          textShadow: \"0 1px 3px rgba(0,0,0,0.6)\",\n                          userSelect: \"none\"\n                        },\n                        children: \"LIVE\"\n                      }\n                    )\n                  ]\n                }\n              ),\n              /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                \"div\",\n                {\n                  className: \"sc-controls-bar\",\n                  style: {\n                    position: \"absolute\",\n                    bottom: `${10 * responsiveScale}px`,\n                    right: `${10 * responsiveScale}px`,\n                    display: \"flex\",\n                    flexDirection: isPortrait ? \"column\" : \"row\",\n                    alignItems: isPortrait ? \"flex-end\" : \"center\",\n                    gap: `${8 * responsiveScale}px`,\n                    zIndex: 10,\n                    opacity: controlsVisible ? 1 : 0,\n                    transform: controlsVisible ? \"translateY(0)\" : \"translateY(4px)\",\n                    pointerEvents: controlsVisible ? \"auto\" : \"none\"\n                  },\n                  children: [\n                    /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                      \"div\",\n                      {\n                        style: {\n                          display: \"flex\",\n                          alignItems: \"center\",\n                          background: \"rgba(0, 0, 0, 0.6)\",\n                          borderRadius: `${18 * responsiveScale}px`,\n                          padding: \"2px\",\n                          paddingRight: `${8 * responsiveScale}px`\n                        },\n                        onMouseEnter: () => setShowVolumeSlider(true),\n                        onMouseLeave: () => setShowVolumeSlider(false),\n                        children: [\n                          /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                            \"button\",\n                            {\n                              className: \"sc-ctrl-btn\",\n                              onClick: () => {\n                                if (playerRef.current) playerRef.current.toggleMute();\n                                onVolumeToggle?.();\n                                resetControlsTimer();\n                              },\n                              style: {\n                                padding: `${8 * responsiveScale}px`,\n                                borderRadius: \"50%\",\n                                minWidth: `${36 * responsiveScale}px`,\n                                minHeight: `${36 * responsiveScale}px`\n                              },\n                              title: isMuted2 ? \"Unmute\" : \"Mute\",\n                              children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VolumeIcon, { size: Math.max(14, 18 * responsiveScale) })\n                            }\n                          ),\n                          /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                            \"div\",\n                            {\n                              style: {\n                                width: showVolumeSlider ? `${68 * responsiveScale}px` : \"0px\",\n                                overflow: \"hidden\",\n                                transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n                                display: \"flex\",\n                                alignItems: \"center\",\n                                paddingLeft: showVolumeSlider ? `${3 * responsiveScale}px` : \"0\",\n                                paddingRight: showVolumeSlider ? `${10 * responsiveScale}px` : \"0\"\n                              },\n                              children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                \"div\",\n                                {\n                                  style: {\n                                    position: \"relative\",\n                                    width: `${56 * responsiveScale}px`,\n                                    height: \"3px\",\n                                    cursor: \"pointer\",\n                                    borderRadius: \"1.5px\"\n                                  },\n                                  onMouseDown: (e) => {\n                                    e.preventDefault();\n                                    const el = e.currentTarget;\n                                    const move = (ev) => {\n                                      const r2 = el.getBoundingClientRect();\n                                      handleVolumeChange(Math.max(0, Math.min(1, (ev.clientX - r2.left) / r2.width)));\n                                    };\n                                    const up = () => {\n                                      document.removeEventListener(\"mousemove\", move);\n                                      document.removeEventListener(\"mouseup\", up);\n                                    };\n                                    document.addEventListener(\"mousemove\", move);\n                                    document.addEventListener(\"mouseup\", up);\n                                    const r = el.getBoundingClientRect();\n                                    handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                                  },\n                                  onClick: (e) => {\n                                    e.stopPropagation();\n                                    const r = e.currentTarget.getBoundingClientRect();\n                                    handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                                  },\n                                  children: [\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { position: \"absolute\", inset: 0, background: \"rgba(255, 255, 255, 0.2)\", borderRadius: \"1.5px\" } }),\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                      \"div\",\n                                      {\n                                        style: {\n                                          position: \"absolute\",\n                                          top: 0,\n                                          left: 0,\n                                          bottom: 0,\n                                          width: `${(isMuted2 ? 0 : volume) * 100}%`,\n                                          background: \"#fff\",\n                                          borderRadius: \"1.5px\",\n                                          transition: \"width 0.1s ease-out\"\n                                        }\n                                      }\n                                    ),\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                      \"div\",\n                                      {\n                                        style: {\n                                          position: \"absolute\",\n                                          top: \"50%\",\n                                          left: `${(isMuted2 ? 0 : volume) * 100}%`,\n                                          transform: \"translate(-50%, -50%)\",\n                                          width: \"12px\",\n                                          height: \"12px\",\n                                          background: \"#fff\",\n                                          borderRadius: \"50%\",\n                                          boxShadow: \"0 0 3px rgba(0, 0, 0, 0.3)\",\n                                          transition: \"left 0.1s ease-out\"\n                                        }\n                                      }\n                                    )\n                                  ]\n                                }\n                              )\n                            }\n                          )\n                        ]\n                      }\n                    ),\n                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                      \"button\",\n                      {\n                        className: \"sc-ctrl-btn\",\n                        onClick: () => {\n                          if (onFullscreenToggle) {\n                            onFullscreenToggle();\n                          } else if (wrapperRef.current) {\n                            if (!document.fullscreenElement) {\n                              wrapperRef.current.requestFullscreen().catch(() => {\n                              });\n                            } else {\n                              document.exitFullscreen().catch(() => {\n                              });\n                            }\n                          }\n                          resetControlsTimer();\n                        },\n                        style: {\n                          padding: `${8 * responsiveScale}px`,\n                          borderRadius: \"50%\",\n                          minWidth: `${36 * responsiveScale}px`,\n                          minHeight: `${36 * responsiveScale}px`,\n                          background: \"rgba(0, 0, 0, 0.6)\"\n                        },\n                        title: isFullscreen2 ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n                        children: isFullscreen2 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaCompress, { size: Math.max(14, 18 * responsiveScale) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaExpand, { size: Math.max(14, 18 * responsiveScale) })\n                      }\n                    )\n                  ]\n                }\n              )\n            ] }),\n            onControlClick && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n              \"div\",\n              {\n                onClick: onControlClick,\n                style: {\n                  position: \"absolute\",\n                  top: 0,\n                  left: 0,\n                  right: 0,\n                  bottom: 0,\n                  zIndex: 1,\n                  cursor: \"pointer\"\n                }\n              }\n            )\n          ]\n        }\n      )\n    ] });\n  },\n  (prevProps, nextProps) => {\n    for (const prop of CRITICAL_PROPS) {\n      if (prevProps[prop] !== nextProps[prop]) {\n        return false;\n      }\n    }\n    const uiProps = [\n      \"autoplay\",\n      \"muted\",\n      \"controls\",\n      \"showCustomControls\",\n      \"className\",\n      \"style\",\n      \"wrapperClassName\",\n      \"wrapperStyle\",\n      \"playsInline\",\n      \"preload\",\n      \"poster\",\n      \"children\"\n    ];\n    for (const prop of uiProps) {\n      if (prevProps[prop] !== nextProps[prop]) {\n        return false;\n      }\n    }\n    const callbackProps = [\n      \"onReady\",\n      \"onVolumeToggle\",\n      \"onFullscreenToggle\",\n      \"onControlClick\"\n    ];\n    for (const prop of callbackProps) {\n      if (prevProps[prop] !== nextProps[prop]) {\n        return false;\n      }\n    }\n    return true;\n  }\n);\n\n// src/StormcloudPlayer.tsx\nvar import_react6 = __toESM(require(\"react\"), 1);\n\n// src/props.ts\nvar noop = () => {\n};\nvar defaultProps = {\n  playing: false,\n  loop: false,\n  controls: true,\n  volume: 1,\n  muted: false,\n  playbackRate: 1,\n  width: \"100%\",\n  height: \"auto\",\n  style: {},\n  progressInterval: 1e3,\n  playsInline: false,\n  autoplay: false,\n  preload: \"metadata\",\n  poster: \"\",\n  className: \"\",\n  wrapperClassName: \"\",\n  wrapperStyle: {},\n  allowNativeHls: false,\n  lowLatencyMode: false,\n  driftToleranceMs: 1e3,\n  immediateManifestAds: true,\n  debugAdTiming: false,\n  showCustomControls: false,\n  hideLoadingIndicator: false,\n  licenseKey: \"\",\n  isVmap: false,\n  vmapUrl: \"\",\n  adFailsafeTimeoutMs: 1e4,\n  minSegmentsBeforePlay: 2,\n  onStart: noop,\n  onPlay: noop,\n  onPause: noop,\n  onBuffer: noop,\n  onBufferEnd: noop,\n  onEnded: noop,\n  onError: noop,\n  onDuration: noop,\n  onSeek: noop,\n  onProgress: noop,\n  onVolumeToggle: noop,\n  onFullscreenToggle: noop,\n  onControlClick: noop\n};\n\n// src/utils.ts\nvar import_react2 = require(\"react\");\nvar lazy = import_react2.lazy;\nvar omit = (object, keys) => {\n  const result = { ...object };\n  keys.forEach((key) => {\n    delete result[key];\n  });\n  return result;\n};\nvar isMediaStream = (url) => {\n  return typeof window !== \"undefined\" && window.MediaStream && url instanceof window.MediaStream;\n};\nvar supportsWebKitPresentationMode = () => {\n  if (typeof window === \"undefined\") return false;\n  const video = document.createElement(\"video\");\n  return \"webkitSupportsPresentationMode\" in video;\n};\nvar randomString = () => {\n  return Math.random().toString(36).substr(2, 9);\n};\nvar parseQuery = (url) => {\n  const query = {};\n  const queryString = url.split(\"?\")[1] || \"\";\n  if (!queryString) return query;\n  const manualParse = (qs) => {\n    qs.split(\"&\").forEach((param) => {\n      const [key, value] = param.split(\"=\");\n      if (key) {\n        try {\n          query[decodeURIComponent(key)] = value ? decodeURIComponent(value.replace(/\\+/g, \" \")) : \"\";\n        } catch (e) {\n          query[key] = value || \"\";\n        }\n      }\n    });\n  };\n  if (typeof URLSearchParams !== \"undefined\") {\n    try {\n      const params = new URLSearchParams(queryString);\n      params.forEach((value, key) => {\n        query[key] = value;\n      });\n      return query;\n    } catch (e) {\n      manualParse(queryString);\n    }\n  } else {\n    manualParse(queryString);\n  }\n  return query;\n};\nvar merge = (target, ...sources) => {\n  if (!sources.length) return target;\n  const source = sources.shift();\n  if (isObject(target) && isObject(source)) {\n    for (const key in source) {\n      if (isObject(source[key])) {\n        if (!target[key]) Object.assign(target, { [key]: {} });\n        merge(target[key], source[key]);\n      } else {\n        Object.assign(target, { [key]: source[key] });\n      }\n    }\n  }\n  return merge(target, ...sources);\n};\nvar isObject = (item) => {\n  return item && typeof item === \"object\" && !Array.isArray(item);\n};\nvar IS_BROWSER = typeof window !== \"undefined\" && window.document;\nvar IS_GLOBAL = typeof globalThis !== \"undefined\" && globalThis.window && globalThis.window.document;\nvar IS_IOS = IS_BROWSER && /iPad|iPhone|iPod/.test(navigator.userAgent);\nvar IS_SAFARI = IS_BROWSER && /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\nvar SUPPORTS_HLS = () => {\n  if (!IS_BROWSER) return false;\n  const video = document.createElement(\"video\");\n  return Boolean(video.canPlayType(\"application/vnd.apple.mpegurl\"));\n};\nvar SUPPORTS_DASH = () => {\n  if (!IS_BROWSER) return false;\n  const video = document.createElement(\"video\");\n  return Boolean(video.canPlayType(\"application/dash+xml\"));\n};\n\n// src/patterns.ts\nvar HLS_EXTENSIONS = /\\.(m3u8)($|\\?)/i;\nvar HLS_PATHS = /\\/hls\\//i;\nvar DASH_EXTENSIONS = /\\.(mpd)($|\\?)/i;\nvar VIDEO_EXTENSIONS = /\\.(mp4|webm|ogg|avi|mov|wmv|flv|mkv)($|\\?)/i;\nvar AUDIO_EXTENSIONS = /\\.(mp3|wav|ogg|aac|wma|flac|m4a)($|\\?)/i;\nvar canPlay = {\n  hls: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return HLS_EXTENSIONS.test(url) || HLS_PATHS.test(url);\n  },\n  dash: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return DASH_EXTENSIONS.test(url);\n  },\n  video: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return VIDEO_EXTENSIONS.test(url);\n  },\n  audio: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return AUDIO_EXTENSIONS.test(url);\n  },\n  file: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return VIDEO_EXTENSIONS.test(url) || AUDIO_EXTENSIONS.test(url);\n  }\n};\n\n// src/players/HlsPlayer.tsx\nvar import_react3 = require(\"react\");\nvar HlsPlayer = class extends import_react3.Component {\n  constructor() {\n    super(...arguments);\n    this.player = null;\n    this.mounted = false;\n    this.load = async () => {\n      if (!this.props.videoElement || !this.props.src) return;\n      try {\n        if (this.player) {\n          this.player.destroy();\n          this.player = null;\n        }\n        const config = {\n          src: this.props.src,\n          videoElement: this.props.videoElement\n        };\n        if (this.props.autoplay !== void 0)\n          config.autoplay = this.props.autoplay;\n        if (this.props.muted !== void 0) config.muted = this.props.muted;\n        if (this.props.lowLatencyMode !== void 0)\n          config.lowLatencyMode = this.props.lowLatencyMode;\n        if (this.props.allowNativeHls !== void 0)\n          config.allowNativeHls = this.props.allowNativeHls;\n        if (this.props.isLiveStream !== void 0)\n          config.isLiveStream = this.props.isLiveStream;\n        if (this.props.driftToleranceMs !== void 0)\n          config.driftToleranceMs = this.props.driftToleranceMs;\n        if (this.props.immediateManifestAds !== void 0)\n          config.immediateManifestAds = this.props.immediateManifestAds;\n        if (this.props.debugAdTiming !== void 0)\n          config.debugAdTiming = this.props.debugAdTiming;\n        if (this.props.showCustomControls !== void 0)\n          config.showCustomControls = this.props.showCustomControls;\n        if (this.props.onVolumeToggle !== void 0)\n          config.onVolumeToggle = this.props.onVolumeToggle;\n        if (this.props.onFullscreenToggle !== void 0)\n          config.onFullscreenToggle = this.props.onFullscreenToggle;\n        if (this.props.onControlClick !== void 0)\n          config.onControlClick = this.props.onControlClick;\n        if (this.props.licenseKey !== void 0)\n          config.licenseKey = this.props.licenseKey;\n        if (this.props.adFailsafeTimeoutMs !== void 0)\n          config.adFailsafeTimeoutMs = this.props.adFailsafeTimeoutMs;\n        if (this.props.minSegmentsBeforePlay !== void 0)\n          config.minSegmentsBeforePlay = this.props.minSegmentsBeforePlay;\n        if (this.props.ctvAdRequest !== void 0)\n          config.ctvAdRequest = this.props.ctvAdRequest;\n        this.player = new StormcloudVideoPlayer(config);\n        this.props.onMount?.(this);\n        await this.player.load();\n        if (this.mounted) {\n          this.props.onReady?.();\n        }\n      } catch (error) {\n        if (this.mounted) {\n          this.props.onError?.(error);\n        }\n      }\n    };\n    this.play = () => {\n      if (this.props.videoElement) {\n        const video = this.props.videoElement;\n        const hasValidSource = video.src || video.currentSrc && video.currentSrc !== \"\" || video.readyState >= 1;\n        if (hasValidSource) {\n          video.play()?.catch((error) => {\n            console.error(\"[HlsPlayer] Failed to play:\", error);\n            this.props.onError?.(error);\n          });\n          this.props.onPlay?.();\n        } else {\n          console.warn(\"[HlsPlayer] Cannot play: video has no valid source\");\n        }\n      }\n    };\n    this.pause = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.pause();\n        this.props.onPause?.();\n      }\n    };\n    this.stop = () => {\n      this.pause();\n      if (this.props.videoElement) {\n        this.props.videoElement.currentTime = 0;\n      }\n    };\n    this.seekTo = (seconds, keepPlaying) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.currentTime = seconds;\n        if (!keepPlaying) {\n          this.pause();\n        }\n      }\n    };\n    this.setVolume = (volume) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.volume = Math.max(0, Math.min(1, volume));\n      }\n    };\n    this.mute = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.muted = true;\n      }\n    };\n    this.unmute = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.muted = false;\n      }\n    };\n    this.setPlaybackRate = (rate) => {\n      if (this.props.videoElement && rate > 0) {\n        this.props.videoElement.playbackRate = rate;\n      }\n    };\n    this.getDuration = () => {\n      if (this.props.videoElement && isFinite(this.props.videoElement.duration)) {\n        return this.props.videoElement.duration;\n      }\n      return null;\n    };\n    this.getCurrentTime = () => {\n      if (this.props.videoElement && isFinite(this.props.videoElement.currentTime)) {\n        return this.props.videoElement.currentTime;\n      }\n      return null;\n    };\n    this.getSecondsLoaded = () => {\n      if (this.props.videoElement && this.props.videoElement.buffered.length > 0) {\n        return this.props.videoElement.buffered.end(\n          this.props.videoElement.buffered.length - 1\n        );\n      }\n      return null;\n    };\n    this.getInternalPlayer = (key = \"player\") => {\n      if (key === \"player\") return this.player;\n      if (key === \"video\") return this.props.videoElement;\n      if (key === \"hls\" && this.player) return this.player.hls;\n      return null;\n    };\n  }\n  componentDidMount() {\n    this.mounted = true;\n    this.load();\n  }\n  componentWillUnmount() {\n    this.mounted = false;\n    if (this.player) {\n      this.player.destroy();\n      this.player = null;\n    }\n  }\n  componentDidUpdate(prevProps) {\n    if (prevProps.src !== this.props.src) {\n      this.load();\n    }\n  }\n  render() {\n    return null;\n  }\n};\nHlsPlayer.displayName = \"HlsPlayer\";\nHlsPlayer.canPlay = canPlay.hls;\n\n// src/players/FilePlayer.tsx\nvar import_react4 = require(\"react\");\nvar FilePlayer = class extends import_react4.Component {\n  constructor() {\n    super(...arguments);\n    this.mounted = false;\n    this.ready = false;\n    this.load = () => {\n      if (!this.props.videoElement || !this.props.src) return;\n      const video = this.props.videoElement;\n      const handleLoadedMetadata = () => {\n        if (this.mounted && !this.ready) {\n          this.ready = true;\n          this.props.onReady?.();\n        }\n      };\n      const handlePlay = () => {\n        if (this.mounted) {\n          this.props.onPlay?.();\n        }\n      };\n      const handlePause = () => {\n        if (this.mounted) {\n          this.props.onPause?.();\n        }\n      };\n      const handleEnded = () => {\n        if (this.mounted) {\n          this.props.onEnded?.();\n        }\n      };\n      const handleError = (error) => {\n        if (this.mounted) {\n          this.props.onError?.(error);\n        }\n      };\n      const handleLoadedData = () => {\n        if (this.mounted) {\n          this.props.onLoaded?.();\n        }\n      };\n      video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n      video.addEventListener(\"play\", handlePlay);\n      video.addEventListener(\"pause\", handlePause);\n      video.addEventListener(\"ended\", handleEnded);\n      video.addEventListener(\"error\", handleError);\n      video.addEventListener(\"loadeddata\", handleLoadedData);\n      video.src = this.props.src;\n      if (this.props.autoplay !== void 0) video.autoplay = this.props.autoplay;\n      if (this.props.muted !== void 0) video.muted = this.props.muted;\n      if (this.props.loop !== void 0) video.loop = this.props.loop;\n      if (this.props.controls !== void 0) video.controls = this.props.controls;\n      if (this.props.playsInline !== void 0)\n        video.playsInline = this.props.playsInline;\n      if (this.props.preload !== void 0)\n        video.preload = this.props.preload;\n      if (this.props.poster !== void 0) video.poster = this.props.poster;\n      this.props.onMount?.(this);\n      return () => {\n        video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n        video.removeEventListener(\"play\", handlePlay);\n        video.removeEventListener(\"pause\", handlePause);\n        video.removeEventListener(\"ended\", handleEnded);\n        video.removeEventListener(\"error\", handleError);\n        video.removeEventListener(\"loadeddata\", handleLoadedData);\n      };\n    };\n    this.play = () => {\n      if (this.props.videoElement) {\n        const video = this.props.videoElement;\n        const hasValidSource = video.src || video.currentSrc && video.currentSrc !== \"\" || video.readyState >= 1;\n        if (hasValidSource) {\n          video.play()?.catch((error) => {\n            console.error(\"[FilePlayer] Failed to play:\", error);\n            this.props.onError?.(error);\n          });\n        } else {\n          console.warn(\"[FilePlayer] Cannot play: video has no valid source\");\n        }\n      }\n    };\n    this.pause = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.pause();\n      }\n    };\n    this.stop = () => {\n      this.pause();\n      if (this.props.videoElement) {\n        this.props.videoElement.currentTime = 0;\n      }\n    };\n    this.seekTo = (seconds, keepPlaying) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.currentTime = seconds;\n        if (!keepPlaying) {\n          this.pause();\n        }\n      }\n    };\n    this.setVolume = (volume) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.volume = Math.max(0, Math.min(1, volume));\n      }\n    };\n    this.mute = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.muted = true;\n      }\n    };\n    this.unmute = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.muted = false;\n      }\n    };\n    this.setPlaybackRate = (rate) => {\n      if (this.props.videoElement && rate > 0) {\n        this.props.videoElement.playbackRate = rate;\n      }\n    };\n    this.setLoop = (loop) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.loop = loop;\n      }\n    };\n    this.getDuration = () => {\n      if (this.props.videoElement && isFinite(this.props.videoElement.duration)) {\n        return this.props.videoElement.duration;\n      }\n      return null;\n    };\n    this.getCurrentTime = () => {\n      if (this.props.videoElement && isFinite(this.props.videoElement.currentTime)) {\n        return this.props.videoElement.currentTime;\n      }\n      return null;\n    };\n    this.getSecondsLoaded = () => {\n      if (this.props.videoElement && this.props.videoElement.buffered.length > 0) {\n        return this.props.videoElement.buffered.end(\n          this.props.videoElement.buffered.length - 1\n        );\n      }\n      return null;\n    };\n    this.getInternalPlayer = (key = \"player\") => {\n      if (key === \"video\") return this.props.videoElement;\n      return null;\n    };\n    this.enablePIP = async () => {\n      if (this.props.videoElement && \"requestPictureInPicture\" in this.props.videoElement) {\n        try {\n          await this.props.videoElement.requestPictureInPicture();\n        } catch (error) {\n          console.warn(\"Picture-in-Picture failed:\", error);\n        }\n      }\n    };\n    this.disablePIP = async () => {\n      if (document.pictureInPictureElement) {\n        try {\n          await document.exitPictureInPicture();\n        } catch (error) {\n          console.warn(\"Exit Picture-in-Picture failed:\", error);\n        }\n      }\n    };\n  }\n  componentDidMount() {\n    this.mounted = true;\n    this.load();\n  }\n  componentWillUnmount() {\n    this.mounted = false;\n  }\n  componentDidUpdate(prevProps) {\n    if (prevProps.src !== this.props.src) {\n      this.load();\n    }\n  }\n  render() {\n    return null;\n  }\n};\nFilePlayer.displayName = \"FilePlayer\";\nFilePlayer.canPlay = canPlay.file;\n\n// src/players/index.ts\nvar players = [\n  {\n    key: \"hls\",\n    name: \"HLS Player\",\n    canPlay: canPlay.hls,\n    lazyPlayer: lazy(() => Promise.resolve({ default: HlsPlayer }))\n  },\n  {\n    key: \"file\",\n    name: \"File Player\",\n    canPlay: canPlay.file,\n    canEnablePIP: (url) => {\n      return canPlay.file(url) && (document.pictureInPictureEnabled || typeof document.webkitSupportsPresentationMode === \"function\");\n    },\n    lazyPlayer: lazy(() => Promise.resolve({ default: FilePlayer }))\n  }\n];\nvar players_default = players;\n\n// src/Player.tsx\nvar import_react5 = __toESM(require(\"react\"), 1);\nvar SEEK_ON_PLAY_EXPIRY = 5e3;\nvar Player = class extends import_react5.Component {\n  constructor() {\n    super(...arguments);\n    this.mounted = false;\n    this.isReady = false;\n    this.isPlaying = false;\n    this.isLoading = true;\n    this.loadOnReady = null;\n    this.startOnPlay = true;\n    this.seekOnPlay = null;\n    this.onDurationCalled = false;\n    this.handlePlayerMount = (player) => {\n      if (this.player) {\n        this.progress();\n        return;\n      }\n      this.player = player;\n      this.player.load(this.props.src);\n      this.progress();\n    };\n    this.getInternalPlayer = (key) => {\n      if (!this.player) return null;\n      return this.player.getInternalPlayer(key);\n    };\n    this.progress = () => {\n      if (this.props.src && this.player && this.isReady) {\n        const playedSeconds = this.getCurrentTime() || 0;\n        const loadedSeconds = this.getSecondsLoaded();\n        const duration = this.getDuration();\n        if (duration) {\n          const progress = {\n            playedSeconds,\n            played: playedSeconds / duration,\n            loaded: 0,\n            loadedSeconds: 0\n          };\n          if (loadedSeconds !== null) {\n            progress.loadedSeconds = loadedSeconds;\n            progress.loaded = loadedSeconds / duration;\n          }\n          if (progress.playedSeconds !== this.prevPlayed || progress.loadedSeconds !== this.prevLoaded) {\n            this.props.onProgress?.(progress);\n          }\n          this.prevPlayed = progress.playedSeconds;\n          this.prevLoaded = progress.loadedSeconds;\n        }\n      }\n      this.progressTimeout = window.setTimeout(\n        this.progress,\n        this.props.progressInterval || 1e3\n      );\n    };\n    this.handleReady = () => {\n      if (!this.mounted) return;\n      this.isReady = true;\n      this.isLoading = false;\n      const { onReady, playing, volume, muted } = this.props;\n      onReady();\n      if (!muted && volume !== null) {\n        this.player.setVolume(volume);\n      }\n      if (this.loadOnReady) {\n        this.player.load(this.loadOnReady, true);\n        this.loadOnReady = null;\n      } else if (playing) {\n        this.player.play();\n      }\n      this.handleDurationCheck();\n    };\n    this.handlePlay = () => {\n      this.isPlaying = true;\n      this.isLoading = false;\n      const { onStart, onPlay, playbackRate } = this.props;\n      if (this.startOnPlay) {\n        if (this.player.setPlaybackRate && playbackRate !== 1) {\n          this.player.setPlaybackRate(playbackRate);\n        }\n        onStart?.();\n        this.startOnPlay = false;\n      }\n      onPlay?.();\n      if (this.seekOnPlay) {\n        this.seekTo(this.seekOnPlay);\n        this.seekOnPlay = null;\n      }\n      this.handleDurationCheck();\n    };\n    this.handlePause = (e) => {\n      this.isPlaying = false;\n      if (!this.isLoading) {\n        this.props.onPause?.(e);\n      }\n    };\n    this.handleEnded = () => {\n      const { activePlayer, loop, onEnded } = this.props;\n      if (activePlayer.loopOnEnded && loop) {\n        this.seekTo(0);\n      }\n      if (!loop) {\n        this.isPlaying = false;\n        onEnded?.();\n      }\n    };\n    this.handleError = (...args) => {\n      this.isLoading = false;\n      this.props.onError?.(args[0], args[1], args[2], args[3]);\n    };\n    this.handleDurationCheck = () => {\n      clearTimeout(this.durationCheckTimeout);\n      const duration = this.getDuration();\n      if (duration) {\n        if (!this.onDurationCalled) {\n          this.props.onDuration?.(duration);\n          this.onDurationCalled = true;\n        }\n      } else {\n        this.durationCheckTimeout = window.setTimeout(\n          this.handleDurationCheck,\n          100\n        );\n      }\n    };\n    this.handleLoaded = () => {\n      this.isLoading = false;\n    };\n  }\n  componentDidMount() {\n    this.mounted = true;\n  }\n  componentWillUnmount() {\n    clearTimeout(this.progressTimeout);\n    clearTimeout(this.durationCheckTimeout);\n    this.mounted = false;\n  }\n  componentDidUpdate(prevProps) {\n    if (!this.player) return;\n    const { src, playing, volume, muted, playbackRate, loop, activePlayer } = this.props;\n    if (prevProps.src !== src) {\n      if (this.isLoading && !activePlayer.forceLoad && !isMediaStream(src)) {\n        console.warn(\n          `StormcloudPlayer: the attempt to load ${src} is being deferred until the player has loaded`\n        );\n        this.loadOnReady = src || null;\n        return;\n      }\n      this.isLoading = true;\n      this.startOnPlay = true;\n      this.onDurationCalled = false;\n      this.player.load(src, this.isReady);\n    }\n    if (!prevProps.playing && playing && !this.isPlaying) {\n      this.player.play();\n    }\n    if (prevProps.playing && !playing && this.isPlaying) {\n      this.player.pause();\n    }\n    if (prevProps.volume !== volume && volume !== null) {\n      this.player.setVolume(volume);\n    }\n    if (prevProps.muted !== muted) {\n      if (muted) {\n        this.player.mute();\n      } else {\n        this.player.unmute();\n        if (volume !== null) {\n          setTimeout(() => this.player.setVolume(volume));\n        }\n      }\n    }\n    if (prevProps.playbackRate !== playbackRate && this.player.setPlaybackRate) {\n      this.player.setPlaybackRate(playbackRate);\n    }\n    if (prevProps.loop !== loop && this.player.setLoop) {\n      this.player.setLoop(loop);\n    }\n  }\n  getDuration() {\n    if (!this.isReady) return null;\n    return this.player.getDuration();\n  }\n  getCurrentTime() {\n    if (!this.isReady) return null;\n    return this.player.getCurrentTime();\n  }\n  getSecondsLoaded() {\n    if (!this.isReady) return null;\n    return this.player.getSecondsLoaded();\n  }\n  seekTo(amount, type, keepPlaying) {\n    if (!this.isReady) {\n      if (amount !== 0) {\n        this.seekOnPlay = amount;\n        setTimeout(() => {\n          this.seekOnPlay = null;\n        }, SEEK_ON_PLAY_EXPIRY);\n      }\n      return;\n    }\n    const isFraction = !type ? amount > 0 && amount < 1 : type === \"fraction\";\n    if (isFraction) {\n      const duration = this.player.getDuration();\n      if (!duration) {\n        console.warn(\n          \"StormcloudPlayer: could not seek using fraction \\u2013 duration not yet available\"\n        );\n        return;\n      }\n      this.player.seekTo(duration * amount, keepPlaying);\n      return;\n    }\n    this.player.seekTo(amount, keepPlaying);\n  }\n  render() {\n    const Player2 = this.props.activePlayer;\n    if (!Player2) {\n      return null;\n    }\n    return import_react5.default.createElement(Player2, {\n      ...this.props,\n      onMount: this.handlePlayerMount,\n      onReady: this.handleReady,\n      onPlay: this.handlePlay,\n      onPause: this.handlePause,\n      onEnded: this.handleEnded,\n      onLoaded: this.handleLoaded,\n      onError: this.handleError\n    });\n  }\n};\nPlayer.displayName = \"Player\";\nPlayer.defaultProps = defaultProps;\n\n// src/StormcloudPlayer.tsx\nvar IS_BROWSER2 = typeof window !== \"undefined\" && window.document;\nvar IS_GLOBAL2 = typeof globalThis !== \"undefined\" && globalThis.window && globalThis.window.document;\nvar UniversalSuspense = IS_BROWSER2 || IS_GLOBAL2 ? import_react6.Suspense : () => null;\nvar SUPPORTED_PROPS = [\n  \"src\",\n  \"playing\",\n  \"loop\",\n  \"controls\",\n  \"volume\",\n  \"muted\",\n  \"playbackRate\",\n  \"width\",\n  \"height\",\n  \"style\",\n  \"progressInterval\",\n  \"playsInline\",\n  \"autoplay\",\n  \"preload\",\n  \"poster\",\n  \"className\",\n  \"wrapperClassName\",\n  \"wrapperStyle\",\n  \"allowNativeHls\",\n  \"lowLatencyMode\",\n  \"isLiveStream\",\n  \"driftToleranceMs\",\n  \"immediateManifestAds\",\n  \"debugAdTiming\",\n  \"showCustomControls\",\n  \"licenseKey\",\n  \"isVmap\",\n  \"vmapUrl\",\n  \"adFailsafeTimeoutMs\",\n  \"minSegmentsBeforePlay\",\n  \"ctvAdRequest\",\n  \"onReady\",\n  \"onStart\",\n  \"onPlay\",\n  \"onPause\",\n  \"onBuffer\",\n  \"onBufferEnd\",\n  \"onEnded\",\n  \"onError\",\n  \"onDuration\",\n  \"onSeek\",\n  \"onProgress\",\n  \"onVolumeToggle\",\n  \"onFullscreenToggle\",\n  \"onControlClick\"\n];\nvar customPlayers = [];\nvar createStormcloudPlayer = (playerList, fallback) => {\n  var _a;\n  return _a = class extends import_react6.Component {\n    constructor() {\n      super(...arguments);\n      this.state = {\n        showPreview: false\n      };\n      this.references = {\n        wrapper: (wrapper) => {\n          this.wrapper = wrapper;\n        },\n        player: (player) => {\n          this.player = player;\n        }\n      };\n      this.getActivePlayer = (src) => {\n        if (!src) return null;\n        for (const player of [...customPlayers, ...playerList]) {\n          if (player.canPlay(src)) {\n            return player;\n          }\n        }\n        if (fallback) {\n          return fallback;\n        }\n        return null;\n      };\n      this.getAttributes = (src) => {\n        return omit(this.props, SUPPORTED_PROPS);\n      };\n      this.handleReady = () => {\n        this.props.onReady?.(this);\n      };\n      this.seekTo = (fraction, type, keepPlaying) => {\n        if (!this.player) return null;\n        this.player.seekTo(fraction, type, keepPlaying);\n      };\n      this.getCurrentTime = () => {\n        if (!this.player) return null;\n        return this.player.getCurrentTime();\n      };\n      this.getSecondsLoaded = () => {\n        if (!this.player) return null;\n        return this.player.getSecondsLoaded();\n      };\n      this.getDuration = () => {\n        if (!this.player) return null;\n        return this.player.getDuration();\n      };\n      this.getInternalPlayer = (key = \"player\") => {\n        if (!this.player) return null;\n        return this.player.getInternalPlayer(key);\n      };\n      this.renderActivePlayer = (src) => {\n        if (!src) return null;\n        const activePlayer = this.getActivePlayer(src);\n        if (!activePlayer) return null;\n        return import_react6.default.createElement(Player, {\n          ...this.props,\n          key: activePlayer.key,\n          ref: this.references.player,\n          activePlayer: activePlayer.lazyPlayer || activePlayer,\n          onReady: this.handleReady\n        });\n      };\n    }\n    render() {\n      const {\n        src,\n        style,\n        width,\n        height,\n        fallback: fallbackElement,\n        wrapper: Wrapper\n      } = this.props;\n      const attributes = this.getAttributes(src);\n      const wrapperRef = typeof Wrapper === \"string\" ? this.references.wrapper : void 0;\n      return import_react6.default.createElement(\n        Wrapper,\n        {\n          ref: wrapperRef,\n          style: { ...style, width, height },\n          ...attributes\n        },\n        import_react6.default.createElement(\n          UniversalSuspense,\n          { fallback: fallbackElement },\n          this.renderActivePlayer(src)\n        )\n      );\n    }\n  }, _a.displayName = \"StormcloudPlayer\", _a.defaultProps = {\n    ...defaultProps,\n    fallback: null,\n    wrapper: \"div\"\n  }, _a.addCustomPlayer = (player) => {\n    customPlayers.push(player);\n  }, _a.removeCustomPlayers = () => {\n    customPlayers.length = 0;\n  }, _a.canPlay = (src) => {\n    for (const Player2 of [...customPlayers, ...playerList]) {\n      if (Player2.canPlay(src)) {\n        return true;\n      }\n    }\n    return false;\n  }, _a.canEnablePIP = (src) => {\n    for (const Player2 of [...customPlayers, ...playerList]) {\n      if (Player2.canEnablePIP && Player2.canEnablePIP(src)) {\n        return true;\n      }\n    }\n    return false;\n  }, _a;\n};\nvar StormcloudPlayer = createStormcloudPlayer(\n  players_default,\n  players_default[players_default.length - 1]\n);\nvar StormcloudPlayer_default = StormcloudPlayer;\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n  DEFAULT_MQTT_CONFIG,\n  IS_BROWSER,\n  IS_GLOBAL,\n  IS_IOS,\n  IS_SAFARI,\n  MQTT_CA_CERT_FILE,\n  SUPPORTS_DASH,\n  SUPPORTS_HLS,\n  StormcloudPlayer,\n  StormcloudVideoPlayer,\n  StormcloudVideoPlayerComponent,\n  applyMQTTConfig,\n  buildAnalyticsContext,\n  buildMQTTBrokerUrl,\n  buildPlayerTopic,\n  canPlay,\n  configureMQTT,\n  createHlsAdPlayer,\n  createPalNonceManager,\n  createStormcloudPlayer,\n  detectBrowser,\n  disconnectMQTT,\n  ensureMQTTClient,\n  getBrowserConfigOverrides,\n  getBrowserID,\n  getClientInfo,\n  getMQTTStatus,\n  initMQTTClient,\n  initializePolyfills,\n  isMQTTConfigured,\n  isMQTTConnected,\n  isMQTTEnabled,\n  isMediaStream,\n  lazy,\n  logBrowserInfo,\n  merge,\n  mqttConfig,\n  omit,\n  parseQuery,\n  players,\n  publishMQTT,\n  randomString,\n  sendAdDetectTracking,\n  sendAdImpressionTracking,\n  sendAdLoadedTracking,\n  sendHeartbeat,\n  sendInitialTracking,\n  supportsFeature,\n  supportsModernJS,\n  supportsWebKitPresentationMode\n});\n","export { StormcloudVideoPlayerComponent as default } from \"./ui/StormcloudVideoPlayer\";\nexport { default as StormcloudPlayer } from \"./StormcloudPlayer\";\nexport { createStormcloudPlayer } from \"./StormcloudPlayer\";\n\nexport { StormcloudVideoPlayer } from \"./player/StormcloudVideoPlayer\";\nexport { StormcloudVideoPlayerComponent } from \"./ui/StormcloudVideoPlayer\";\n\nexport type {\n  StormcloudVideoPlayerConfig,\n  AdBreak,\n  AdSchedule,\n  LateJoinPolicy,\n  ClientInfo,\n  TrackingData,\n  HeartbeatData,\n  AdDetectInfo,\n  AdLoadedInfo,\n  AdImpressionInfo,\n  PlayerAnalyticsContext,\n} from \"./types\";\nexport type { StormcloudVideoPlayerProps } from \"./ui/StormcloudVideoPlayer\";\nexport type { BaseStormcloudPlayerProps, OnProgressProps } from \"./props\";\n\nexport { canPlay } from \"./patterns\";\nexport * from \"./utils\";\nexport {\n  getClientInfo,\n  getBrowserID,\n  buildAnalyticsContext,\n  sendInitialTracking,\n  sendHeartbeat,\n  sendAdDetectTracking,\n  sendAdLoadedTracking,\n  sendAdImpressionTracking,\n} from \"./utils/tracking\";\n\nexport {\n  initMQTTClient,\n  disconnectMQTT,\n  publishMQTT,\n  getMQTTStatus,\n  isMQTTConnected,\n  isMQTTConfigured,\n  ensureMQTTClient,\n  configureMQTT,\n} from \"./utils/mqttClient\";\nexport type { MQTTStatus } from \"./utils/mqttClient\";\nexport {\n  mqttConfig,\n  DEFAULT_MQTT_CONFIG,\n  MQTT_CA_CERT_FILE,\n  applyMQTTConfig,\n  isMQTTEnabled,\n  buildMQTTBrokerUrl,\n  buildPlayerTopic,\n} from \"./utils/mqttConfig\";\nexport type { MQTTConfig } from \"./utils/mqttConfig\";\n\nexport { initializePolyfills } from \"./utils/polyfills\";\nexport {\n  detectBrowser,\n  supportsModernJS,\n  logBrowserInfo,\n  getBrowserConfigOverrides,\n  supportsFeature,\n} from \"./utils/browserCompat\";\nexport type { BrowserInfo } from \"./utils/browserCompat\";\n\nexport { default as players } from \"./players\";\n\nexport { createHlsAdPlayer } from \"./sdk/hlsAdPlayer\";\nexport { createPalNonceManager } from \"./sdk/pal\";\nexport type { PalNonceManager, PalNonceOptions } from \"./sdk/pal\";\nexport type { AdController, AdControllerOptions, ImaController, ImaControllerOptions } from \"./types\";\n","import React, { useEffect, useRef, useMemo, useCallback } from \"react\";\nimport { StormcloudVideoPlayer } from \"../player/StormcloudVideoPlayer\";\nimport type { StormcloudVideoPlayerConfig } from \"../types\";\nimport {\n  FaPlay,\n  FaPause,\n  FaVolumeUp,\n  FaVolumeMute,\n  FaVolumeDown,\n  FaExpand,\n  FaCompress,\n} from \"react-icons/fa\";\n\nexport type StormcloudVideoPlayerProps = Omit<\n  StormcloudVideoPlayerConfig,\n  \"videoElement\"\n> &\n  React.VideoHTMLAttributes<HTMLVideoElement> & {\n    onReady?: (player: StormcloudVideoPlayer) => void;\n    wrapperClassName?: string;\n    wrapperStyle?: React.CSSProperties;\n    licenseKey?: string;\n  };\n\nconst CRITICAL_PROPS = [\n  \"src\",\n  \"allowNativeHls\",\n  \"isLiveStream\",\n  \"licenseKey\",\n  \"isVmap\",\n  \"vmapUrl\",\n  \"lowLatencyMode\",\n  \"driftToleranceMs\",\n  \"vastMode\",\n  \"ctvAdRequest\",\n] as const;\n\nconst CONTROLS_HIDE_DELAY = 3000;\nconst DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;\n\nexport const StormcloudVideoPlayerComponent: React.FC<StormcloudVideoPlayerProps> =\n  React.memo(\n    (props) => {\n      const {\n        src,\n        autoplay,\n        muted,\n        lowLatencyMode,\n        allowNativeHls,\n        isLiveStream,\n        driftToleranceMs,\n        immediateManifestAds,\n        debugAdTiming,\n        showCustomControls,\n        hideLoadingIndicator,\n        onVolumeToggle,\n        onFullscreenToggle,\n        onControlClick,\n        onReady,\n        wrapperClassName,\n        wrapperStyle,\n        className,\n        style,\n        controls,\n        playsInline,\n        preload,\n        poster,\n        children,\n        licenseKey,\n        vastMode,\n        vastTagUrl,\n        isVmap,\n        vmapUrl,\n        minSegmentsBeforePlay,\n        ctvAdRequest,\n        ...restVideoAttrs\n      } = props;\n\n      const videoRef = useRef<HTMLVideoElement | null>(null);\n      const playerRef = useRef<StormcloudVideoPlayer | null>(null);\n      const bufferingTimeoutRef = useRef<number | null>(null);\n      const controlsTimerRef = useRef<number | null>(null);\n      const wrapperRef = useRef<HTMLDivElement | null>(null);\n      const [adStatus, setAdStatus] = React.useState<{\n        showAds: boolean;\n        currentIndex: number;\n        totalAds: number;\n        remainingSeconds: number;\n      }>({ showAds: false, currentIndex: 0, totalAds: 0, remainingSeconds: 0 });\n\n      const [shouldShowNativeControls, setShouldShowNativeControls] =\n        React.useState(true);\n\n      const [isMuted, setIsMuted] = React.useState(false);\n      const [isFullscreen, setIsFullscreen] = React.useState(false);\n      const [isPlaying, setIsPlaying] = React.useState(false);\n      const [currentTime, setCurrentTime] = React.useState(0);\n      const [duration, setDuration] = React.useState(0);\n      const [volume, setVolume] = React.useState(1);\n      const [playbackRate, setPlaybackRate] = React.useState(1);\n      const [showVolumeSlider, setShowVolumeSlider] = React.useState(false);\n      const [showSpeedMenu, setShowSpeedMenu] = React.useState(false);\n      const [isLoading, setIsLoading] = React.useState(true);\n      const [isBuffering, setIsBuffering] = React.useState(false);\n      const [showCenterPlay, setShowCenterPlay] = React.useState(false);\n      const [showLicenseWarning, setShowLicenseWarning] = React.useState(false);\n      const [controlsVisible, setControlsVisible] = React.useState(true);\n      const [viewportWidth, setViewportWidth] = React.useState(\n        typeof window !== \"undefined\" ? window.innerWidth : 1920\n      );\n      const [isPortrait, setIsPortrait] = React.useState(\n        typeof window !== \"undefined\"\n          ? window.innerHeight > window.innerWidth\n          : false\n      );\n      const [playerAspectRatio, setPlayerAspectRatio] = React.useState(\n        DEFAULT_PLAYER_ASPECT_RATIO\n      );\n\n      const getResponsiveScale = () => {\n        if (viewportWidth < 480) return 0.7;\n        if (viewportWidth < 768) return 0.8;\n        if (viewportWidth < 1024) return 0.9;\n        return 1;\n      };\n\n      const responsiveScale = getResponsiveScale();\n\n      const resetControlsTimer = useCallback(() => {\n        if (controlsTimerRef.current) {\n          clearTimeout(controlsTimerRef.current);\n        }\n        setControlsVisible(true);\n        controlsTimerRef.current = window.setTimeout(() => {\n          if (!showVolumeSlider && !showSpeedMenu) {\n            setControlsVisible(false);\n          }\n        }, CONTROLS_HIDE_DELAY);\n      }, [showVolumeSlider, showSpeedMenu]);\n\n      const handleWrapperMouseMove = useCallback(() => {\n        resetControlsTimer();\n      }, [resetControlsTimer]);\n\n      const handleWrapperMouseLeave = useCallback(() => {\n        if (!showVolumeSlider && !showSpeedMenu) {\n          setControlsVisible(false);\n        }\n      }, [showVolumeSlider, showSpeedMenu]);\n\n      const formatTime = (seconds: number): string => {\n        if (!isFinite(seconds)) return \"0:00:00\";\n        const hours = Math.floor(seconds / 3600);\n        const minutes = Math.floor((seconds % 3600) / 60);\n        const remainingSeconds = Math.floor(seconds % 60);\n        return `${hours}:${minutes\n          .toString()\n          .padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n      };\n\n      const handlePlayPause = () => {\n        if (videoRef.current) {\n          if (videoRef.current.paused) {\n            const hasValidSource =\n              videoRef.current.src ||\n              (videoRef.current.currentSrc &&\n                videoRef.current.currentSrc !== \"\") ||\n              videoRef.current.readyState >= 1;\n\n            if (hasValidSource) {\n              videoRef.current.play()?.catch((error) => {\n                console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n              });\n              setShowCenterPlay(false);\n            } else {\n              console.warn(\n                \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n              );\n            }\n          } else {\n            videoRef.current.pause();\n            setShowCenterPlay(true);\n          }\n        }\n        resetControlsTimer();\n      };\n\n      const handleCenterPlayClick = () => {\n        if (videoRef.current && videoRef.current.paused) {\n          const hasValidSource =\n            videoRef.current.src ||\n            (videoRef.current.currentSrc &&\n              videoRef.current.currentSrc !== \"\") ||\n            videoRef.current.readyState >= 1;\n\n          if (hasValidSource) {\n            videoRef.current.play()?.catch((error) => {\n              console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n            });\n            setShowCenterPlay(false);\n          } else {\n            console.warn(\n              \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n            );\n          }\n        }\n      };\n\n      const handleTimelineSeek = (e: React.MouseEvent<HTMLDivElement>) => {\n        if (videoRef.current && duration > 0 && isFinite(duration)) {\n          const rect = e.currentTarget.getBoundingClientRect();\n          const clickX = e.clientX - rect.left;\n          const progress = Math.max(0, Math.min(1, clickX / rect.width));\n          const newTime = progress * duration;\n\n          if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n            videoRef.current.currentTime = newTime;\n          }\n        }\n        resetControlsTimer();\n      };\n\n      const handleVolumeChange = (newVolume: number) => {\n        if (playerRef.current && isFinite(newVolume)) {\n          const clampedVolume = Math.max(0, Math.min(1, newVolume));\n          playerRef.current.setVolume(clampedVolume);\n        }\n      };\n\n      const handlePlaybackRateChange = (rate: number) => {\n        if (videoRef.current && isFinite(rate) && rate > 0) {\n          videoRef.current.playbackRate = rate;\n        }\n        setShowSpeedMenu(false);\n      };\n\n      const isHlsStream =\n        src?.toLowerCase().includes(\".m3u8\") ||\n        src?.toLowerCase().includes(\"/hls/\");\n      const isLiveUiMode = isLiveStream === true;\n      const shouldShowEnhancedControls =\n        showCustomControls &&\n        (isHlsStream ? !isLiveUiMode : true);\n\n      const criticalPropsKey = useMemo(() => {\n        return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n      }, [\n        src,\n        allowNativeHls,\n        isLiveStream,\n        licenseKey,\n        isVmap,\n        vmapUrl,\n        lowLatencyMode,\n        driftToleranceMs,\n        vastMode,\n      ]);\n\n      useEffect(() => {\n        if (typeof window === \"undefined\") return;\n        const el = videoRef.current;\n        if (!el || !src) return;\n\n        if (!licenseKey) {\n          setShowLicenseWarning(true);\n          setIsLoading(false);\n          console.warn(\n            \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n          );\n          return;\n        }\n\n        setShowLicenseWarning(false);\n\n        if (debugAdTiming) {\n          console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n        }\n\n        if (playerRef.current) {\n          try {\n            playerRef.current.destroy();\n          } catch {}\n          playerRef.current = null;\n        }\n\n        const cfg: StormcloudVideoPlayerConfig = {\n          src,\n          videoElement: el,\n        } as StormcloudVideoPlayerConfig;\n        if (autoplay !== undefined) cfg.autoplay = autoplay;\n        if (muted !== undefined) cfg.muted = muted;\n        if (lowLatencyMode !== undefined) cfg.lowLatencyMode = lowLatencyMode;\n        if (allowNativeHls !== undefined) cfg.allowNativeHls = allowNativeHls;\n        if (isLiveStream !== undefined) cfg.isLiveStream = isLiveStream;\n        if (driftToleranceMs !== undefined)\n          cfg.driftToleranceMs = driftToleranceMs;\n        if (immediateManifestAds !== undefined)\n          cfg.immediateManifestAds = immediateManifestAds;\n        if (debugAdTiming !== undefined) cfg.debugAdTiming = debugAdTiming;\n        if (showCustomControls !== undefined)\n          cfg.showCustomControls = showCustomControls;\n        if (onVolumeToggle !== undefined) cfg.onVolumeToggle = onVolumeToggle;\n        if (onFullscreenToggle !== undefined)\n          cfg.onFullscreenToggle = onFullscreenToggle;\n        if (onControlClick !== undefined) cfg.onControlClick = onControlClick;\n        if (licenseKey !== undefined) cfg.licenseKey = licenseKey;\n        if (vastMode !== undefined) cfg.vastMode = vastMode;\n        if (vastTagUrl !== undefined) cfg.vastTagUrl = vastTagUrl;\n        if (isVmap !== undefined) cfg.isVmap = isVmap;\n        if (vmapUrl !== undefined) cfg.vmapUrl = vmapUrl;\n        if (minSegmentsBeforePlay !== undefined)\n          cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n        if (ctvAdRequest !== undefined) cfg.ctvAdRequest = ctvAdRequest;\n\n        const player = new StormcloudVideoPlayer(cfg);\n        playerRef.current = player;\n        player\n          .load()\n          .then(() => {\n            const showNative = player.shouldShowNativeControls();\n            setShouldShowNativeControls(showNative);\n            if (debugAdTiming) {\n              console.log(\n                \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n              );\n            }\n            onReady?.(player);\n          })\n          .catch((error) => {\n            console.error(\n              \"StormcloudVideoPlayer: Failed to load player:\",\n              error\n            );\n            setIsLoading(false);\n            onReady?.(player);\n          });\n\n        return () => {\n          try {\n            player.destroy();\n          } catch {}\n          playerRef.current = null;\n        };\n      }, [criticalPropsKey]);\n\n      useEffect(() => {\n        if (!playerRef.current) return;\n\n        try {\n          if (autoplay !== undefined && playerRef.current.videoElement) {\n            playerRef.current.videoElement.autoplay = autoplay;\n          }\n          if (muted !== undefined && !playerRef.current.isShowingAds()) {\n            playerRef.current.setMuted(muted);\n          }\n        } catch (error) {\n          console.warn(\"Failed to update player properties:\", error);\n        }\n      }, [autoplay, muted]);\n\n      useEffect(() => {\n        if (!playerRef.current) return;\n\n        const checkAdStatus = () => {\n          if (playerRef.current) {\n            const showAdsFromMethod = playerRef.current.isShowingAds();\n            const showAdsFromAttribute = videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n            const showAds = showAdsFromMethod || showAdsFromAttribute;\n            const currentIndex = playerRef.current.getCurrentAdIndex();\n            const totalAds = playerRef.current.getTotalAdsInBreak();\n            const remainingMs = playerRef.current.getAdRemainingMs();\n            const remainingSeconds = showAds\n              ? Math.max(0, Math.ceil(remainingMs / 1000))\n              : 0;\n\n            setAdStatus((prev) => {\n              if (\n                prev.showAds !== showAds ||\n                prev.currentIndex !== currentIndex ||\n                prev.totalAds !== totalAds ||\n                prev.remainingSeconds !== remainingSeconds\n              ) {\n                if (showAds && !prev.showAds) {\n                  setShowCenterPlay(false);\n                }\n                return { showAds, currentIndex, totalAds, remainingSeconds };\n              }\n              return prev;\n            });\n          }\n        };\n\n        const interval = setInterval(checkAdStatus, 50);\n        return () => clearInterval(interval);\n      }, []);\n\n      useEffect(() => {\n        if (typeof window === \"undefined\" || !playerRef.current) return;\n\n        const handleResize = () => {\n          if (playerRef.current && videoRef.current) {\n            if (typeof playerRef.current.resize === \"function\") {\n              playerRef.current.resize();\n            }\n          }\n          setViewportWidth(window.innerWidth);\n          setIsPortrait(window.innerHeight > window.innerWidth);\n        };\n\n        window.addEventListener(\"resize\", handleResize);\n        return () => window.removeEventListener(\"resize\", handleResize);\n      }, []);\n\n      useEffect(() => {\n        if (!playerRef.current || !videoRef.current) return;\n\n        const updateStates = () => {\n          if (playerRef.current && videoRef.current) {\n            setIsMuted(playerRef.current.isMuted());\n            setIsPlaying(!videoRef.current.paused);\n\n            const currentTimeValue = videoRef.current.currentTime;\n            setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n\n            const durationValue = videoRef.current.duration;\n            setDuration(isFinite(durationValue) ? durationValue : 0);\n\n            const volumeValue = playerRef.current.getVolume();\n            setVolume(\n              isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n            );\n\n            const rateValue = videoRef.current.playbackRate;\n            setPlaybackRate(\n              isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n            );\n          }\n          setIsFullscreen(\n            document.fullscreenElement === wrapperRef.current\n          );\n        };\n\n        const interval = setInterval(updateStates, 200);\n\n        const handleFullscreenChange = () => {\n          setIsFullscreen(\n            document.fullscreenElement === wrapperRef.current\n          );\n        };\n\n        document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n\n        return () => {\n          clearInterval(interval);\n          document.removeEventListener(\n            \"fullscreenchange\",\n            handleFullscreenChange\n          );\n        };\n      }, []);\n\n      useEffect(() => {\n        if (!videoRef.current) return;\n\n        const handleLoadedMetadata = () => {\n          const video = videoRef.current;\n          if (video) {\n            if (video.videoWidth > 0 && video.videoHeight > 0) {\n              setPlayerAspectRatio(video.videoWidth / video.videoHeight);\n            }\n            void video.offsetHeight;\n          }\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n              videoRef.current?.readyState\n            );\n          }\n        };\n\n        const handleLoadedData = () => {\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: loadeddata, readyState:\",\n              videoRef.current?.readyState\n            );\n          }\n        };\n\n        const handleLoadStart = () => {\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: loadstart, readyState:\",\n              videoRef.current?.readyState\n            );\n          }\n        };\n\n        const handleCanPlay = () => {\n          setIsLoading(false);\n          if (bufferingTimeoutRef.current) {\n            clearTimeout(bufferingTimeoutRef.current);\n            bufferingTimeoutRef.current = null;\n          }\n          setIsBuffering(false);\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: canplay, readyState:\",\n              videoRef.current?.readyState,\n              \"- clearing loading state, isLoading=false\"\n            );\n          }\n        };\n\n        const handleCanPlayThrough = () => {\n          setIsLoading(false);\n          if (bufferingTimeoutRef.current) {\n            clearTimeout(bufferingTimeoutRef.current);\n            bufferingTimeoutRef.current = null;\n          }\n          setIsBuffering(false);\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n              videoRef.current?.readyState,\n              \"- clearing loading state, isLoading=false\"\n            );\n          }\n        };\n\n        const handleWaiting = () => {\n          if (bufferingTimeoutRef.current) {\n            clearTimeout(bufferingTimeoutRef.current);\n          }\n\n          bufferingTimeoutRef.current = window.setTimeout(() => {\n            setIsBuffering(true);\n            if (debugAdTiming) {\n              console.log(\n                \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n                videoRef.current?.readyState,\n                \"- showing spinner, isBuffering=true\"\n              );\n            }\n          }, 300);\n\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: waiting, readyState:\",\n              videoRef.current?.readyState,\n              \"- buffering delay started (300ms)\"\n            );\n          }\n        };\n\n        const handlePlaying = () => {\n          setIsLoading(false);\n          if (bufferingTimeoutRef.current) {\n            clearTimeout(bufferingTimeoutRef.current);\n            bufferingTimeoutRef.current = null;\n          }\n          setIsBuffering(false);\n          setShowCenterPlay(false);\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: playing, readyState:\",\n              videoRef.current?.readyState,\n              \"- playback started, isLoading=false, isBuffering=false\"\n            );\n          }\n        };\n\n      const handlePause = () => {\n        const isAdActive = playerRef.current?.isShowingAds() || \n          videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n        \n        if (playerRef.current && !isAdActive) {\n          setShowCenterPlay(true);\n        } else {\n          setShowCenterPlay(false);\n        }\n      };\n\n        const handleEnded = () => {\n          setShowCenterPlay(true);\n        };\n\n        const video = videoRef.current;\n        video.addEventListener(\"loadstart\", handleLoadStart);\n        video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n        video.addEventListener(\"loadeddata\", handleLoadedData);\n        video.addEventListener(\"canplay\", handleCanPlay);\n        video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n        video.addEventListener(\"waiting\", handleWaiting);\n        video.addEventListener(\"playing\", handlePlaying);\n        video.addEventListener(\"pause\", handlePause);\n        video.addEventListener(\"ended\", handleEnded);\n\n        if (video.paused) {\n          setShowCenterPlay(true);\n        }\n\n        return () => {\n          if (bufferingTimeoutRef.current) {\n            clearTimeout(bufferingTimeoutRef.current);\n            bufferingTimeoutRef.current = null;\n          }\n\n          video.removeEventListener(\"loadstart\", handleLoadStart);\n          video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n          video.removeEventListener(\"loadeddata\", handleLoadedData);\n          video.removeEventListener(\"canplay\", handleCanPlay);\n          video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n          video.removeEventListener(\"waiting\", handleWaiting);\n          video.removeEventListener(\"playing\", handlePlaying);\n          video.removeEventListener(\"pause\", handlePause);\n          video.removeEventListener(\"ended\", handleEnded);\n        };\n      }, [debugAdTiming]);\n\n      useEffect(() => {\n        setPlayerAspectRatio(DEFAULT_PLAYER_ASPECT_RATIO);\n      }, [src]);\n\n      useEffect(() => {\n        return () => {\n          if (controlsTimerRef.current) {\n            clearTimeout(controlsTimerRef.current);\n          }\n        };\n      }, []);\n\n      const progressPercent = duration > 0 ? (currentTime / duration) * 100 : 0;\n\n      const VolumeIcon = isMuted || volume === 0\n        ? FaVolumeMute\n        : volume < 0.5\n          ? FaVolumeDown\n          : FaVolumeUp;\n\n      return (\n        <>\n          <style>\n            {`\n              @keyframes sc-spin {\n                from { transform: rotate(0deg); }\n                to { transform: rotate(360deg); }\n              }\n              @keyframes sc-loading-glow {\n                0%, 100% { opacity: 0.85; transform: scale(1); }\n                50% { opacity: 1; transform: scale(1.05); }\n              }\n              @keyframes sc-pulse {\n                0%, 100% { opacity: 1; }\n                50% { opacity: 0.6; }\n              }\n              @keyframes sc-fade-in {\n                from { opacity: 0; transform: translateY(8px); }\n                to { opacity: 1; transform: translateY(0); }\n              }\n              .sc-wrapper:fullscreen,\n              .sc-wrapper:has(*:fullscreen) {\n                border-radius: 0 !important;\n                box-shadow: none !important;\n                width: 100vw !important;\n                height: 100vh !important;\n                max-width: 100vw !important;\n                max-height: 100vh !important;\n                position: fixed !important;\n                top: 0 !important;\n                left: 0 !important;\n                z-index: 999999 !important;\n                background: #000 !important;\n                display: flex !important;\n                align-items: center !important;\n                justify-content: center !important;\n              }\n              .sc-ctrl-btn {\n                background: none;\n                border: none;\n                color: #fff;\n                cursor: pointer;\n                display: flex;\n                align-items: center;\n                justify-content: center;\n                border-radius: 50%;\n                padding: 8px;\n                transition: background 0.15s ease, opacity 0.15s ease;\n                opacity: 0.9;\n              }\n              .sc-ctrl-btn:hover {\n                opacity: 1;\n                background: rgba(255, 255, 255, 0.1);\n              }\n              .sc-ctrl-btn:active {\n                opacity: 0.7;\n              }\n              .sc-controls-bar {\n                transition: opacity 0.35s ease, transform 0.35s ease;\n              }\n              .sc-progress-track:hover .sc-progress-thumb {\n                transform: translate(-50%, -50%) scale(1) !important;\n              }\n              .sc-loading-hidden .sc-loading-indicator {\n                display: none !important;\n              }\n            `}\n          </style>\n          <div\n            ref={wrapperRef}\n            className={`sc-wrapper ${wrapperClassName || \"\"}`}\n            onMouseMove={handleWrapperMouseMove}\n            onMouseLeave={handleWrapperMouseLeave}\n            style={{\n              display: \"flex\",\n              alignItems: \"center\",\n              justifyContent: \"center\",\n              position: isFullscreen ? \"fixed\" : \"relative\",\n              top: isFullscreen ? 0 : undefined,\n              left: isFullscreen ? 0 : undefined,\n              overflow: \"hidden\",\n              width: isFullscreen ? \"100vw\" : \"100%\",\n              height: isFullscreen ? \"100vh\" : \"auto\",\n              minHeight: isFullscreen ? \"100vh\" : \"auto\",\n              aspectRatio: isFullscreen ? undefined : playerAspectRatio,\n              maxWidth: isFullscreen ? \"100vw\" : \"100%\",\n              maxHeight: isFullscreen ? \"100vh\" : \"none\",\n              zIndex: isFullscreen ? 999999 : undefined,\n              backgroundColor: \"#000\",\n              borderRadius: isFullscreen ? 0 : undefined,\n              boxShadow: isFullscreen ? \"none\" : undefined,\n              ...wrapperStyle,\n            }}\n          >\n            <video\n              ref={videoRef}\n              className={className}\n              style={{\n                display: \"block\",\n                width: \"100%\",\n                height: \"100%\",\n                maxWidth: \"100%\",\n                maxHeight: isFullscreen ? \"100%\" : \"none\",\n                objectFit: isFullscreen ? \"cover\" : \"contain\",\n                backgroundColor: \"#000\",\n                aspectRatio: isFullscreen ? \"unset\" : undefined,\n                ...style,\n              }}\n              controls={\n                shouldShowNativeControls && controls && !showCustomControls\n              }\n              playsInline={playsInline}\n              preload={preload}\n              poster={poster}\n              {...restVideoAttrs}\n            >\n              {children}\n            </video>\n\n            {(isLoading || isBuffering) && !hideLoadingIndicator && (\n              <div\n                className=\"sc-loading-indicator\"\n                style={{\n                  position: \"absolute\",\n                  top: \"50%\",\n                  left: \"50%\",\n                  transform: \"translate(-50%, -50%)\",\n                  zIndex: 20,\n                  width: `${Math.max(34, 38 * responsiveScale)}px`,\n                  height: `${Math.max(34, 38 * responsiveScale)}px`,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  justifyContent: \"center\",\n                  animation: \"sc-loading-glow 1.4s ease-in-out infinite\",\n                  filter: \"drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55))\",\n                }}\n              >\n                <div\n                  style={{\n                    position: \"absolute\",\n                    inset: 0,\n                    borderRadius: \"50%\",\n                    border: \"3px solid rgba(255, 255, 255, 0.25)\",\n                    borderTopColor: \"#ff0000\",\n                    borderRightColor: \"rgba(255, 255, 255, 0.85)\",\n                    animation: \"sc-spin 0.8s linear infinite\",\n                  }}\n                />\n                <div\n                  style={{\n                    width: \"7px\",\n                    height: \"7px\",\n                    borderRadius: \"50%\",\n                    background: \"#ff0000\",\n                    boxShadow: \"0 0 10px rgba(255, 0, 0, 0.65)\",\n                  }}\n                />\n              </div>\n            )}\n\n            {showLicenseWarning && (\n              <div\n                style={{\n                  position: \"absolute\",\n                  top: \"50%\",\n                  left: \"50%\",\n                  transform: \"translate(-50%, -50%)\",\n                  zIndex: 25,\n                  background: \"rgba(220, 38, 38, 0.92)\",\n                  backdropFilter: \"blur(24px)\",\n                  color: \"white\",\n                  padding: \"28px 36px\",\n                  borderRadius: \"14px\",\n                  border: \"1px solid rgba(255, 255, 255, 0.15)\",\n                  boxShadow: \"0 24px 64px rgba(0, 0, 0, 0.5)\",\n                  textAlign: \"center\",\n                  maxWidth: \"400px\",\n                  margin: \"0 16px\",\n                }}\n              >\n                <div style={{ fontSize: \"18px\", fontWeight: \"700\", marginBottom: \"10px\", letterSpacing: \"-0.02em\" }}>\n                  License Key Required\n                </div>\n                <div style={{ fontSize: \"13px\", lineHeight: \"1.6\", color: \"rgba(255, 255, 255, 0.85)\" }}>\n                  Please provide a valid license key to use the Stormcloud Video\n                  Player.\n                  <br />\n                  Contact your administrator for licensing information.\n                </div>\n              </div>\n            )}\n\n            {adStatus.showAds && (\n              <div\n                style={{\n                  position: \"absolute\",\n                  top: `${12 * responsiveScale}px`,\n                  left: `${12 * responsiveScale}px`,\n                  zIndex: 50,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  gap: \"8px\",\n                  pointerEvents: \"none\",\n                  animation: \"sc-fade-in 0.3s ease\",\n                }}\n              >\n                <div\n                  style={{\n                    background: \"rgba(234, 179, 8, 0.95)\",\n                    color: \"#111\",\n                    padding: `${4 * responsiveScale}px ${12 * responsiveScale}px`,\n                    borderRadius: \"6px\",\n                    fontSize: `${11 * responsiveScale}px`,\n                    fontWeight: 700,\n                    letterSpacing: \"0.08em\",\n                    textTransform: \"uppercase\" as const,\n                    boxShadow: \"0 2px 12px rgba(234, 179, 8, 0.35)\",\n                  }}\n                >\n                  {`Ad ${Math.max(1, adStatus.currentIndex)}`}\n                </div>\n              </div>\n            )}\n\n            {showCenterPlay &&\n              !isLoading &&\n              !isBuffering &&\n              !showLicenseWarning &&\n              !adStatus.showAds && (\n                <div\n                  onClick={handleCenterPlayClick}\n                  style={{\n                    position: \"absolute\",\n                    top: \"50%\",\n                    left: \"50%\",\n                    transform: \"translate(-50%, -50%)\",\n                    zIndex: 15,\n                    cursor: \"pointer\",\n                    background: \"rgba(0, 0, 0, 0.55)\",\n                    backdropFilter: \"blur(8px)\",\n                    borderRadius: \"50%\",\n                    width: `${92 * responsiveScale}px`,\n                    height: `${92 * responsiveScale}px`,\n                    display: \"flex\",\n                    alignItems: \"center\",\n                    justifyContent: \"center\",\n                    transition: \"background 0.2s ease, transform 0.2s ease\",\n                    animation: \"sc-fade-in 0.2s ease\",\n                  }}\n                  onMouseEnter={(e) => {\n                    (e.currentTarget as HTMLElement).style.background = \"rgba(0, 0, 0, 0.72)\";\n                    (e.currentTarget as HTMLElement).style.transform = \"translate(-50%, -50%) scale(1.06)\";\n                  }}\n                  onMouseLeave={(e) => {\n                    (e.currentTarget as HTMLElement).style.background = \"rgba(0, 0, 0, 0.55)\";\n                    (e.currentTarget as HTMLElement).style.transform = \"translate(-50%, -50%) scale(1)\";\n                  }}\n                  title=\"Play\"\n                >\n                  <FaPlay\n                    size={Math.max(24, 32 * responsiveScale)}\n                    color=\"white\"\n                    style={{ marginLeft: \"4px\" }}\n                  />\n                </div>\n              )}\n\n            {shouldShowEnhancedControls && !showLicenseWarning ? (\n              <div\n                className=\"sc-controls-bar\"\n                style={{\n                  position: \"absolute\",\n                  bottom: 0,\n                  left: 0,\n                  right: 0,\n                  background: \"linear-gradient(0deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.35) 60%, transparent 100%)\",\n                  padding: `${20 * responsiveScale}px ${12 * responsiveScale}px ${8 * responsiveScale}px`,\n                  zIndex: 10,\n                  opacity: controlsVisible || adStatus.showAds ? 1 : 0,\n                  transform: controlsVisible || adStatus.showAds ? \"translateY(0)\" : \"translateY(6px)\",\n                  pointerEvents: controlsVisible || adStatus.showAds ? \"auto\" : \"none\",\n                }}\n              >\n                {/* Progress Bar */}\n                <div\n                  className=\"sc-progress-track\"\n                  style={{\n                    width: \"100%\",\n                    height: \"3px\",\n                    background: \"rgba(255, 255, 255, 0.2)\",\n                    borderRadius: \"1.5px\",\n                    marginBottom: `${8 * responsiveScale}px`,\n                    cursor: \"pointer\",\n                    position: \"relative\",\n                    transition: \"height 0.1s ease\",\n                  }}\n                  onClick={handleTimelineSeek}\n                  onMouseEnter={(e) => { e.currentTarget.style.height = \"5px\"; }}\n                  onMouseLeave={(e) => { e.currentTarget.style.height = \"3px\"; }}\n                >\n                  <div\n                    style={{\n                      position: \"absolute\",\n                      top: 0, left: 0, bottom: 0,\n                      background: adStatus.showAds ? \"#f5c518\" : \"#ff0000\",\n                      borderRadius: \"1.5px\",\n                      width: `${progressPercent}%`,\n                      transition: \"width 0.15s linear\",\n                    }}\n                  />\n                  <div\n                    className=\"sc-progress-thumb\"\n                    style={{\n                      position: \"absolute\",\n                      top: \"50%\",\n                      left: `${progressPercent}%`,\n                      transform: \"translate(-50%, -50%) scale(0)\",\n                      width: \"13px\",\n                      height: \"13px\",\n                      background: adStatus.showAds ? \"#f5c518\" : \"#ff0000\",\n                      borderRadius: \"50%\",\n                      boxShadow: \"0 0 4px rgba(0, 0, 0, 0.3)\",\n                      transition: \"transform 0.1s ease, left 0.15s linear\",\n                    }}\n                  />\n                </div>\n\n                {/* Controls Row */}\n                <div\n                  style={{\n                    display: \"flex\",\n                    alignItems: \"center\",\n                    justifyContent: \"space-between\",\n                    color: \"white\",\n                    gap: `${8 * responsiveScale}px`,\n                  }}\n                >\n                  {/* Left Group */}\n                  <div\n                    style={{\n                      display: \"flex\",\n                      alignItems: \"center\",\n                      gap: `${8 * responsiveScale}px`,\n                    }}\n                  >\n                    {/* Play/Pause */}\n                    <button\n                      className=\"sc-ctrl-btn\"\n                      onClick={handlePlayPause}\n                      style={{\n                        padding: `${8 * responsiveScale}px`,\n                        borderRadius: \"50%\",\n                        minWidth: `${36 * responsiveScale}px`,\n                        minHeight: `${36 * responsiveScale}px`,\n                      }}\n                      title={isPlaying ? \"Pause\" : \"Play\"}\n                    >\n                      {isPlaying ? (\n                        <FaPause size={Math.max(14, 18 * responsiveScale)} />\n                      ) : (\n                        <FaPlay size={Math.max(14, 18 * responsiveScale)} style={{ marginLeft: \"2px\" }} />\n                      )}\n                    </button>\n\n                    {/* Volume Group - YouTube Style */}\n                    <div\n                      style={{\n                        display: \"flex\",\n                        alignItems: \"center\",\n                        paddingRight: `${6 * responsiveScale}px`,\n                      }}\n                      onMouseEnter={() => setShowVolumeSlider(true)}\n                      onMouseLeave={() => setShowVolumeSlider(false)}\n                    >\n                      <button\n                        className=\"sc-ctrl-btn\"\n                        onClick={() => {\n                          if (playerRef.current) playerRef.current.toggleMute();\n                          onVolumeToggle?.();\n                          resetControlsTimer();\n                        }}\n                        style={{\n                          padding: `${8 * responsiveScale}px`,\n                          borderRadius: \"50%\",\n                          minWidth: `${36 * responsiveScale}px`,\n                          minHeight: `${36 * responsiveScale}px`,\n                        }}\n                        title={isMuted ? \"Unmute\" : \"Mute\"}\n                      >\n                        <VolumeIcon size={Math.max(14, 18 * responsiveScale)} />\n                      </button>\n                      <div\n                        style={{\n                          width: showVolumeSlider ? `${68 * responsiveScale}px` : \"0px\",\n                          overflow: \"hidden\",\n                          transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n                          display: \"flex\",\n                          alignItems: \"center\",\n                          paddingLeft: showVolumeSlider ? `${3 * responsiveScale}px` : \"0\",\n                          paddingRight: showVolumeSlider ? `${8 * responsiveScale}px` : \"0\",\n                        }}\n                      >\n                        <div\n                          style={{\n                            position: \"relative\",\n                            width: `${56 * responsiveScale}px`,\n                            height: \"3px\",\n                            cursor: \"pointer\",\n                            borderRadius: \"1.5px\",\n                          }}\n                          onMouseDown={(e) => {\n                            e.preventDefault();\n                            const el = e.currentTarget;\n                            const move = (ev: MouseEvent) => {\n                              const r = el.getBoundingClientRect();\n                              handleVolumeChange(Math.max(0, Math.min(1, (ev.clientX - r.left) / r.width)));\n                            };\n                            const up = () => { document.removeEventListener(\"mousemove\", move); document.removeEventListener(\"mouseup\", up); };\n                            document.addEventListener(\"mousemove\", move);\n                            document.addEventListener(\"mouseup\", up);\n                            const r = el.getBoundingClientRect();\n                            handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                          }}\n                          onClick={(e) => {\n                            e.stopPropagation();\n                            const r = e.currentTarget.getBoundingClientRect();\n                            handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                          }}\n                        >\n                          <div style={{ position: \"absolute\", inset: 0, background: \"rgba(255, 255, 255, 0.2)\", borderRadius: \"1.5px\" }} />\n                          <div\n                            style={{\n                              position: \"absolute\",\n                              top: 0, left: 0, bottom: 0,\n                              width: `${(isMuted ? 0 : volume) * 100}%`,\n                              background: \"#fff\",\n                              borderRadius: \"1.5px\",\n                              transition: \"width 0.1s ease-out\",\n                            }}\n                          />\n                          <div\n                            style={{\n                              position: \"absolute\",\n                              top: \"50%\",\n                              left: `${(isMuted ? 0 : volume) * 100}%`,\n                              transform: \"translate(-50%, -50%)\",\n                              width: \"12px\",\n                              height: \"12px\",\n                              background: \"#fff\",\n                              borderRadius: \"50%\",\n                              boxShadow: \"0 0 3px rgba(0, 0, 0, 0.3)\",\n                              transition: \"left 0.1s ease-out\",\n                            }}\n                          />\n                        </div>\n                      </div>\n                    </div>\n\n                    {/* Time Display */}\n                    <div\n                      style={{\n                        fontSize: `${13 * responsiveScale}px`,\n                        fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\",\n                        color: \"rgba(255, 255, 255, 0.9)\",\n                        display: viewportWidth < 480 ? \"none\" : \"block\",\n                        fontVariantNumeric: \"tabular-nums\",\n                        userSelect: \"none\",\n                        marginLeft: `${4 * responsiveScale}px`,\n                      }}\n                    >\n                      {formatTime(currentTime)}{\" \"}\n                      <span style={{ color: \"rgba(255,255,255,0.5)\" }}>/</span>{\" \"}\n                      {formatTime(duration)}\n                    </div>\n                  </div>\n\n                  {/* Right Group */}\n                  <div\n                    style={{\n                      display: \"flex\",\n                      alignItems: \"center\",\n                      gap: `${8 * responsiveScale}px`,\n                    }}\n                  >\n                    {/* Speed Selector */}\n                    <div style={{ position: \"relative\", display: viewportWidth < 600 ? \"none\" : \"block\" }}>\n                      <button\n                        className=\"sc-ctrl-btn\"\n                        onClick={() => { setShowSpeedMenu(!showSpeedMenu); resetControlsTimer(); }}\n                        style={{\n                          padding: `${6 * responsiveScale}px ${10 * responsiveScale}px`,\n                          borderRadius: `${6 * responsiveScale}px`,\n                          fontSize: `${13 * responsiveScale}px`,\n                          fontFamily: \"'SF Mono', 'Cascadia Code', monospace\",\n                          fontWeight: \"600\",\n                          minHeight: `${32 * responsiveScale}px`,\n                        }}\n                        title=\"Playback Speed\"\n                      >\n                        {playbackRate}x\n                      </button>\n\n                      {showSpeedMenu && (\n                        <div\n                          style={{\n                            position: \"absolute\",\n                            bottom: \"100%\",\n                            right: 0,\n                            marginBottom: \"8px\",\n                            background: \"rgba(0, 0, 0, 0.8)\",\n                            backdropFilter: \"blur(24px)\",\n                            WebkitBackdropFilter: \"blur(24px)\",\n                            borderRadius: \"10px\",\n                            border: \"1px solid rgba(255, 255, 255, 0.1)\",\n                            overflow: \"hidden\",\n                            minWidth: \"80px\",\n                            boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.5)\",\n                            animation: \"sc-fade-in 0.15s ease\",\n                          }}\n                        >\n                          {[0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map((speed) => (\n                            <button\n                              key={speed}\n                              onClick={() => handlePlaybackRateChange(speed)}\n                              style={{\n                                display: \"block\",\n                                width: \"100%\",\n                                padding: `${8 * responsiveScale}px ${14 * responsiveScale}px`,\n                                background: playbackRate === speed\n                                  ? \"rgba(255, 255, 255, 0.12)\"\n                                  : \"transparent\",\n                                border: \"none\",\n                                color: playbackRate === speed ? \"#fff\" : \"rgba(255, 255, 255, 0.7)\",\n                                cursor: \"pointer\",\n                                fontSize: `${12 * responsiveScale}px`,\n                                fontFamily: \"'SF Mono', monospace\",\n                                fontWeight: playbackRate === speed ? \"700\" : \"500\",\n                                textAlign: \"center\",\n                                transition: \"background 0.15s ease, color 0.15s ease\",\n                              }}\n                              onMouseEnter={(e) => {\n                                if (playbackRate !== speed) {\n                                  (e.target as HTMLElement).style.background = \"rgba(255, 255, 255, 0.08)\";\n                                  (e.target as HTMLElement).style.color = \"#fff\";\n                                }\n                              }}\n                              onMouseLeave={(e) => {\n                                if (playbackRate !== speed) {\n                                  (e.target as HTMLElement).style.background = \"transparent\";\n                                  (e.target as HTMLElement).style.color = \"rgba(255, 255, 255, 0.7)\";\n                                }\n                              }}\n                            >\n                              {speed}x\n                            </button>\n                          ))}\n                        </div>\n                      )}\n                    </div>\n\n                    {/* Fullscreen */}\n                    <button\n                      className=\"sc-ctrl-btn\"\n                      onClick={() => {\n                        if (onFullscreenToggle) {\n                          onFullscreenToggle();\n                        } else if (wrapperRef.current) {\n                          if (!document.fullscreenElement) {\n                            wrapperRef.current.requestFullscreen().catch(() => {});\n                          } else {\n                            document.exitFullscreen().catch(() => {});\n                          }\n                        }\n                        resetControlsTimer();\n                      }}\n                      style={{\n                        padding: `${8 * responsiveScale}px`,\n                        borderRadius: \"50%\",\n                        minWidth: `${36 * responsiveScale}px`,\n                        minHeight: `${36 * responsiveScale}px`,\n                      }}\n                      title={isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"}\n                    >\n                      {isFullscreen ? (\n                        <FaCompress size={Math.max(14, 18 * responsiveScale)} />\n                      ) : (\n                        <FaExpand size={Math.max(14, 18 * responsiveScale)} />\n                      )}\n                    </button>\n                  </div>\n                </div>\n              </div>\n            ) : (\n              showCustomControls && !showLicenseWarning && (\n                <>\n                  <div\n                    style={{\n                      position: \"absolute\",\n                      top: `${10 * responsiveScale}px`,\n                      left: `${10 * responsiveScale}px`,\n                      display: \"flex\",\n                      alignItems: \"center\",\n                      gap: \"6px\",\n                      zIndex: 10,\n                      opacity: controlsVisible ? 1 : 0,\n                      transition: \"opacity 0.35s ease\",\n                    }}\n                  >\n                    <div\n                      style={{\n                        width: \"8px\",\n                        height: \"8px\",\n                        borderRadius: \"50%\",\n                        background: \"#ff3b30\",\n                        animation: \"sc-pulse 1.5s ease-in-out infinite\",\n                        flexShrink: 0,\n                      }}\n                    />\n                    <span\n                      style={{\n                        fontSize: `${12 * responsiveScale}px`,\n                        fontFamily: \"'SF Pro Display', 'Segoe UI', Arial, sans-serif\",\n                        fontWeight: 700,\n                        letterSpacing: \"0.08em\",\n                        color: \"#fff\",\n                        textShadow: \"0 1px 3px rgba(0,0,0,0.6)\",\n                        userSelect: \"none\",\n                      }}\n                    >\n                      LIVE\n                    </span>\n                  </div>\n\n                  <div\n                  className=\"sc-controls-bar\"\n                  style={{\n                    position: \"absolute\",\n                    bottom: `${10 * responsiveScale}px`,\n                    right: `${10 * responsiveScale}px`,\n                    display: \"flex\",\n                    flexDirection: isPortrait ? \"column\" : \"row\",\n                    alignItems: isPortrait ? \"flex-end\" : \"center\",\n                    gap: `${8 * responsiveScale}px`,\n                    zIndex: 10,\n                    opacity: controlsVisible ? 1 : 0,\n                    transform: controlsVisible ? \"translateY(0)\" : \"translateY(4px)\",\n                    pointerEvents: controlsVisible ? \"auto\" : \"none\",\n                  }}\n                >\n                  <div\n                    style={{\n                      display: \"flex\",\n                      alignItems: \"center\",\n                      background: \"rgba(0, 0, 0, 0.6)\",\n                      borderRadius: `${18 * responsiveScale}px`,\n                      padding: \"2px\",\n                      paddingRight: `${8 * responsiveScale}px`,\n                    }}\n                    onMouseEnter={() => setShowVolumeSlider(true)}\n                    onMouseLeave={() => setShowVolumeSlider(false)}\n                  >\n                    <button\n                      className=\"sc-ctrl-btn\"\n                      onClick={() => {\n                        if (playerRef.current) playerRef.current.toggleMute();\n                        onVolumeToggle?.();\n                        resetControlsTimer();\n                      }}\n                      style={{\n                        padding: `${8 * responsiveScale}px`,\n                        borderRadius: \"50%\",\n                        minWidth: `${36 * responsiveScale}px`,\n                        minHeight: `${36 * responsiveScale}px`,\n                      }}\n                      title={isMuted ? \"Unmute\" : \"Mute\"}\n                    >\n                      <VolumeIcon size={Math.max(14, 18 * responsiveScale)} />\n                    </button>\n                    <div\n                      style={{\n                        width: showVolumeSlider ? `${68 * responsiveScale}px` : \"0px\",\n                        overflow: \"hidden\",\n                        transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n                        display: \"flex\",\n                        alignItems: \"center\",\n                        paddingLeft: showVolumeSlider ? `${3 * responsiveScale}px` : \"0\",\n                        paddingRight: showVolumeSlider ? `${10 * responsiveScale}px` : \"0\",\n                      }}\n                    >\n                      <div\n                        style={{\n                          position: \"relative\",\n                          width: `${56 * responsiveScale}px`,\n                          height: \"3px\",\n                          cursor: \"pointer\",\n                          borderRadius: \"1.5px\",\n                        }}\n                        onMouseDown={(e) => {\n                          e.preventDefault();\n                          const el = e.currentTarget;\n                          const move = (ev: MouseEvent) => {\n                            const r = el.getBoundingClientRect();\n                            handleVolumeChange(Math.max(0, Math.min(1, (ev.clientX - r.left) / r.width)));\n                          };\n                          const up = () => { document.removeEventListener(\"mousemove\", move); document.removeEventListener(\"mouseup\", up); };\n                          document.addEventListener(\"mousemove\", move);\n                          document.addEventListener(\"mouseup\", up);\n                          const r = el.getBoundingClientRect();\n                          handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                        }}\n                        onClick={(e) => {\n                          e.stopPropagation();\n                          const r = e.currentTarget.getBoundingClientRect();\n                          handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                        }}\n                      >\n                        <div style={{ position: \"absolute\", inset: 0, background: \"rgba(255, 255, 255, 0.2)\", borderRadius: \"1.5px\" }} />\n                        <div\n                          style={{\n                            position: \"absolute\",\n                            top: 0, left: 0, bottom: 0,\n                            width: `${(isMuted ? 0 : volume) * 100}%`,\n                            background: \"#fff\",\n                            borderRadius: \"1.5px\",\n                            transition: \"width 0.1s ease-out\",\n                          }}\n                        />\n                        <div\n                          style={{\n                            position: \"absolute\",\n                            top: \"50%\",\n                            left: `${(isMuted ? 0 : volume) * 100}%`,\n                            transform: \"translate(-50%, -50%)\",\n                            width: \"12px\",\n                            height: \"12px\",\n                            background: \"#fff\",\n                            borderRadius: \"50%\",\n                            boxShadow: \"0 0 3px rgba(0, 0, 0, 0.3)\",\n                            transition: \"left 0.1s ease-out\",\n                          }}\n                        />\n                      </div>\n                    </div>\n                  </div>\n\n                  <button\n                    className=\"sc-ctrl-btn\"\n                    onClick={() => {\n                      if (onFullscreenToggle) {\n                        onFullscreenToggle();\n                      } else if (wrapperRef.current) {\n                        if (!document.fullscreenElement) {\n                          wrapperRef.current.requestFullscreen().catch(() => {});\n                        } else {\n                          document.exitFullscreen().catch(() => {});\n                        }\n                      }\n                      resetControlsTimer();\n                    }}\n                    style={{\n                      padding: `${8 * responsiveScale}px`,\n                      borderRadius: \"50%\",\n                      minWidth: `${36 * responsiveScale}px`,\n                      minHeight: `${36 * responsiveScale}px`,\n                      background: \"rgba(0, 0, 0, 0.6)\",\n                    }}\n                    title={isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"}\n                  >\n                    {isFullscreen ? (\n                      <FaCompress size={Math.max(14, 18 * responsiveScale)} />\n                    ) : (\n                      <FaExpand size={Math.max(14, 18 * responsiveScale)} />\n                    )}\n                  </button>\n                  </div>\n                </>\n              )\n            )}\n\n            {onControlClick && (\n              <div\n                onClick={onControlClick}\n                style={{\n                  position: \"absolute\",\n                  top: 0,\n                  left: 0,\n                  right: 0,\n                  bottom: 0,\n                  zIndex: 1,\n                  cursor: \"pointer\",\n                }}\n              />\n            )}\n          </div>\n        </>\n      );\n    },\n    (prevProps, nextProps) => {\n      for (const prop of CRITICAL_PROPS) {\n        if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n          return false;\n        }\n      }\n\n      const uiProps = [\n        \"autoplay\",\n        \"muted\",\n        \"controls\",\n        \"showCustomControls\",\n        \"className\",\n        \"style\",\n        \"wrapperClassName\",\n        \"wrapperStyle\",\n        \"playsInline\",\n        \"preload\",\n        \"poster\",\n        \"children\",\n      ] as const;\n\n      for (const prop of uiProps) {\n        if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n          return false;\n        }\n      }\n\n      const callbackProps = [\n        \"onReady\",\n        \"onVolumeToggle\",\n        \"onFullscreenToggle\",\n        \"onControlClick\",\n      ] as const;\n      for (const prop of callbackProps) {\n        if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n          return false;\n        }\n      }\n\n      return true;\n    }\n  );\n","import type { AdController } from \"../types\";\nimport Hls from \"hls.js\";\n\ninterface VastMediaFile {\n  url: string;\n  type: string;\n  width: number;\n  height: number;\n  bitrate?: number | undefined;\n}\n\ninterface VastTrackingUrls {\n  impression: string[];\n  start: string[];\n  firstQuartile: string[];\n  midpoint: string[];\n  thirdQuartile: string[];\n  complete: string[];\n  mute: string[];\n  unmute: string[];\n  pause: string[];\n  resume: string[];\n  fullscreen: string[];\n  exitFullscreen: string[];\n  skip: string[];\n  error: string[];\n}\n\ninterface VastAd {\n  id: string;\n  title: string;\n  duration: number;\n  mediaFiles: VastMediaFile[];\n  trackingUrls: VastTrackingUrls;\n  clickThrough?: string | undefined;\n}\n\ntype VastParseResult =\n  | { type: \"inline\"; ad: VastAd }\n  | {\n      type: \"wrapper\";\n      vastAdTagUri: string;\n      trackingUrls: VastTrackingUrls;\n      clickThrough?: string | undefined;\n    }\n  | { type: \"empty\" };\n\nconst MAX_VAST_WRAPPER_DEPTH = 5;\n\nexport function createHlsAdPlayer(\n  contentVideo: HTMLVideoElement,\n  options?: {\n    continueLiveStreamDuringAds?: boolean;\n    licenseKey?: string;\n    mainHlsInstance?: Hls;\n  }\n): AdController {\n  let adPlaying = false;\n  let originalMutedState = false;\n  let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n  const listeners = new Map<string, Set<(payload?: any) => void>>();\n  const licenseKey = options?.licenseKey;\n  const mainHlsInstance = options?.mainHlsInstance;\n\n  let adVideoElement: HTMLVideoElement | undefined;\n  let adHls: Hls | undefined;\n  let adContainerEl: HTMLDivElement | undefined;\n  let currentAd: VastAd | undefined;\n  let podAds: VastAd[] = [];\n  let podIndex = 0;\n  let sessionId: string | undefined;\n  const preloadedAds = new Map<string, VastAd>();\n  const preloadingAds = new Map<string, Promise<void>>();\n  let destroyed = false;\n  let pendingTimeouts: number[] = [];\n\n  let trackingFired = {\n    impression: false,\n    start: false,\n    firstQuartile: false,\n    midpoint: false,\n    thirdQuartile: false,\n    complete: false,\n  };\n\n  function emit(event: string, payload?: any): void {\n    const set = listeners.get(event);\n    if (!set) return;\n    for (const fn of Array.from(set)) {\n      try {\n        fn(payload);\n      } catch (error) {\n        console.warn(\n          `[HlsAdPlayer] Error in event listener for ${event}:`,\n          error\n        );\n      }\n    }\n  }\n\n  function generateSessionId(): string {\n    return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n  }\n\n  function fireTrackingPixels(urls: string[]): void {\n    if (!urls || urls.length === 0) return;\n\n    urls.forEach((url) => {\n      try {\n        let trackingUrl = url;\n\n        if (sessionId) {\n          trackingUrl = `${trackingUrl}${\n            trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n          }session_id=${sessionId}`;\n        }\n\n        if (licenseKey) {\n          trackingUrl = `${trackingUrl}${\n            trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n          }license_key=${licenseKey}`;\n        }\n\n        const img = new Image(1, 1);\n        img.src = trackingUrl;\n        console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n      } catch (error) {\n        console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n      }\n    });\n  }\n\n  function getMainStreamQuality(): {\n    width: number;\n    height: number;\n    bitrate: number;\n  } | null {\n    if (!mainHlsInstance || !mainHlsInstance.levels) {\n      return null;\n    }\n\n    const currentLevel = mainHlsInstance.currentLevel;\n    if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n      const autoLevel = mainHlsInstance.loadLevel;\n      if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n        const level = mainHlsInstance.levels[autoLevel];\n        return {\n          width: level.width || 1920,\n          height: level.height || 1080,\n          bitrate: level.bitrate || 5000000,\n        };\n      }\n      return null;\n    }\n\n    const level = mainHlsInstance.levels[currentLevel];\n    return {\n      width: level.width || 1920,\n      height: level.height || 1080,\n      bitrate: level.bitrate || 5000000,\n    };\n  }\n\n  function selectBestMediaFile(mediaFiles: VastMediaFile[]): VastMediaFile {\n    if (mediaFiles.length === 0) {\n      throw new Error(\"No media files available\");\n    }\n\n    const firstFile = mediaFiles[0];\n    if (!firstFile) {\n      throw new Error(\"No media files available\");\n    }\n\n    if (mediaFiles.length === 1) {\n      return firstFile;\n    }\n\n    const mainQuality = getMainStreamQuality();\n    if (!mainQuality) {\n      console.log(\n        \"[HlsAdPlayer] No main stream quality info, using first media file\"\n      );\n      return firstFile;\n    }\n\n    console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\n\n    const scoredFiles = mediaFiles.map((file) => {\n      const widthDiff = Math.abs(file.width - mainQuality.width);\n      const heightDiff = Math.abs(file.height - mainQuality.height);\n      const resolutionDiff = widthDiff + heightDiff;\n\n      const fileBitrate = (file.bitrate || 5000) * 1000;\n      const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n\n      const score = resolutionDiff * 2 + bitrateDiff / 1000;\n\n      return { file, score, resolutionDiff, bitrateDiff };\n    });\n\n    scoredFiles.sort((a, b) => a.score - b.score);\n\n    const bestMatch = scoredFiles[0];\n    if (!bestMatch) {\n      console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n      return firstFile;\n    }\n\n    console.log(\"[HlsAdPlayer] Selected media file:\", {\n      url: bestMatch.file.url,\n      resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n      bitrate: bestMatch.file.bitrate,\n      score: bestMatch.score,\n      resolutionDiff: bestMatch.resolutionDiff,\n      bitrateDiff: bestMatch.bitrateDiff,\n    });\n\n    return bestMatch.file;\n  }\n\n  function isHlsMediaFile(mediaFile: VastMediaFile): boolean {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return (\n      type === \"application/x-mpegurl\" ||\n      type === \"application/vnd.apple.mpegurl\" ||\n      type.includes(\"mpegurl\") ||\n      url.includes(\".m3u8\")\n    );\n  }\n\n  function isProgressiveMediaFile(mediaFile: VastMediaFile): boolean {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return (\n      type.startsWith(\"video/\") ||\n      url.endsWith(\".mp4\") ||\n      url.includes(\".mp4?\")\n    );\n  }\n\n  function createEmptyTrackingUrls(): VastTrackingUrls {\n    return {\n      impression: [],\n      start: [],\n      firstQuartile: [],\n      midpoint: [],\n      thirdQuartile: [],\n      complete: [],\n      mute: [],\n      unmute: [],\n      pause: [],\n      resume: [],\n      fullscreen: [],\n      exitFullscreen: [],\n      skip: [],\n      error: [],\n    };\n  }\n\n  function extractTrackingUrls(scope: Document | Element): VastTrackingUrls {\n    const trackingUrls = createEmptyTrackingUrls();\n\n    scope.querySelectorAll(\"Impression\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.impression.push(url);\n    });\n\n    scope.querySelectorAll(\"Tracking\").forEach((el) => {\n      const event = el.getAttribute(\"event\");\n      const url = el.textContent?.trim();\n      if (event && url) {\n        const eventKey = event as keyof VastTrackingUrls;\n        if (trackingUrls[eventKey]) {\n          trackingUrls[eventKey].push(url);\n        }\n      }\n    });\n\n    scope.querySelectorAll(\"Error\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.error.push(url);\n    });\n\n    return trackingUrls;\n  }\n\n  function mergeTrackingUrls(\n    target: VastTrackingUrls,\n    source: VastTrackingUrls\n  ): VastTrackingUrls {\n    (Object.keys(target) as Array<keyof VastTrackingUrls>).forEach((key) => {\n      if (source[key] && source[key].length > 0) {\n        target[key] = target[key].concat(source[key]);\n      }\n    });\n    return target;\n  }\n\n  function parseVastXml(xmlString: string): VastParseResult {\n    try {\n      const parser = new DOMParser();\n      const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n\n      const parserError = xmlDoc.querySelector(\"parsererror\");\n      if (parserError) {\n        console.error(\n          \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n          parserError.textContent\n        );\n        return { type: \"empty\" };\n      }\n\n      const adElement = xmlDoc.querySelector(\"Ad\");\n      if (!adElement) {\n        console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n        return { type: \"empty\" };\n      }\n\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n      const clickThrough = xmlDoc\n        .querySelector(\"ClickThrough\")\n        ?.textContent?.trim();\n\n      const wrapperUri = xmlDoc\n        .querySelector(\"VASTAdTagURI\")\n        ?.textContent?.trim();\n      if (wrapperUri) {\n        console.log(\n          `[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ${wrapperUri}`\n        );\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough,\n        };\n      }\n\n      const isNoAdAvailable =\n        adId === \"empty\" ||\n        title.toLowerCase().includes(\"no ad available\") ||\n        title.toLowerCase() === \"no ad available\";\n\n      const durationText =\n        xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n      const durationParts = durationText.split(\":\");\n      const duration =\n        parseInt(durationParts[0] || \"0\", 10) * 3600 +\n        parseInt(durationParts[1] || \"0\", 10) * 60 +\n        parseInt(durationParts[2] || \"0\", 10);\n\n      const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n      const mediaFiles: VastMediaFile[] = [];\n\n      console.log(\n        `[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n      );\n\n      mediaFileElements.forEach((mf, index) => {\n        const type = mf.getAttribute(\"type\") || \"\";\n        const url = mf.textContent?.trim() || \"\";\n        const width = mf.getAttribute(\"width\") || \"\";\n        const height = mf.getAttribute(\"height\") || \"\";\n\n        console.log(\n          `[HlsAdPlayer] MediaFile ${index}: type=\"${type}\", url=\"${url}\", width=\"${width}\", height=\"${height}\"`\n        );\n\n        const mediaFile: VastMediaFile = {\n          url,\n          type,\n          width: parseInt(width || \"1920\", 10),\n          height: parseInt(height || \"1080\", 10),\n          bitrate: undefined,\n        };\n\n        if (!url) {\n          console.warn(`[HlsAdPlayer] MediaFile ${index} has empty URL`);\n          return;\n        }\n\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr\n          ? parseInt(bitrateAttr, 10)\n          : undefined;\n        mediaFile.bitrate =\n          bitrateValue && bitrateValue > 0 ? bitrateValue : undefined;\n\n        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n          console.log(\n            `[HlsAdPlayer] Added ${isHlsMediaFile(mediaFile) ? \"HLS\" : \"progressive\"} MediaFile: ${url}`\n          );\n        } else {\n          console.log(\n            `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not supported)`\n          );\n        }\n      });\n\n      if (mediaFiles.length === 0) {\n        if (isNoAdAvailable) {\n          console.warn(\n            \"[HlsAdPlayer] No ads available (VAST response indicates no ads)\"\n          );\n        } else {\n          console.warn(\"[HlsAdPlayer] No supported media files found in VAST XML\");\n        }\n        return { type: \"empty\" };\n      }\n\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough,\n        },\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n      return { type: \"empty\" };\n    }\n  }\n\n  function parseAdElement(adElement: Element): VastParseResult {\n    try {\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n      const clickThrough = adElement\n        .querySelector(\"ClickThrough\")\n        ?.textContent?.trim();\n\n      const wrapperUri = adElement\n        .querySelector(\"VASTAdTagURI\")\n        ?.textContent?.trim();\n      if (wrapperUri) {\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough,\n        };\n      }\n\n      const isNoAdAvailable =\n        adId === \"empty\" ||\n        title.toLowerCase().includes(\"no ad available\") ||\n        title.toLowerCase() === \"no ad available\";\n\n      const durationText =\n        adElement.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n      const durationParts = durationText.split(\":\");\n      const duration =\n        parseInt(durationParts[0] || \"0\", 10) * 3600 +\n        parseInt(durationParts[1] || \"0\", 10) * 60 +\n        parseInt(durationParts[2] || \"0\", 10);\n\n      const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n      const mediaFiles: VastMediaFile[] = [];\n\n      mediaFileElements.forEach((mf) => {\n        const type = mf.getAttribute(\"type\") || \"\";\n        const url = mf.textContent?.trim() || \"\";\n        const width = mf.getAttribute(\"width\") || \"\";\n        const height = mf.getAttribute(\"height\") || \"\";\n\n        if (!url) return;\n\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : undefined;\n\n        const mediaFile: VastMediaFile = {\n          url,\n          type,\n          width: parseInt(width || \"1920\", 10),\n          height: parseInt(height || \"1080\", 10),\n          bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : undefined,\n        };\n\n        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n        }\n      });\n\n      if (mediaFiles.length === 0) {\n        if (isNoAdAvailable) {\n          console.warn(\n            \"[HlsAdPlayer] Pod <Ad> indicates no ad available\"\n          );\n        } else {\n          console.warn(\"[HlsAdPlayer] No supported media files in pod <Ad>\");\n        }\n        return { type: \"empty\" };\n      }\n\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough,\n        },\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing pod <Ad> element:\", error);\n      return { type: \"empty\" };\n    }\n  }\n\n  async function fetchVastXml(vastTagUrl: string): Promise<string> {\n    const response = await fetch(vastTagUrl, {\n      mode: \"cors\",\n      credentials: \"include\",\n      headers: {\n        \"Accept\": \"application/xml, text/xml, */*\",\n      },\n      referrerPolicy: \"no-referrer-when-downgrade\",\n    });\n    if (!response.ok) {\n      throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n    }\n    return response.text();\n  }\n\n  async function fetchAndParseVastAd(\n    vastTagUrl: string,\n    depth = 0,\n    accumulatedTracking: VastTrackingUrls = createEmptyTrackingUrls()\n  ): Promise<VastAd | null> {\n    const vastXml = await fetchVastXml(vastTagUrl);\n    console.log(\"[HlsAdPlayer] VAST XML received\");\n    console.log(\n      \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n      vastXml.substring(0, 2000)\n    );\n\n    const parsed = parseVastXml(vastXml);\n\n    if (parsed.type === \"empty\") {\n      return null;\n    }\n\n    if (parsed.type === \"wrapper\") {\n      if (depth >= MAX_VAST_WRAPPER_DEPTH) {\n        console.warn(\n          `[HlsAdPlayer] VAST wrapper depth limit (${MAX_VAST_WRAPPER_DEPTH}) reached, aborting redirect chain`\n        );\n        return null;\n      }\n\n      mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);\n      return fetchAndParseVastAd(\n        parsed.vastAdTagUri,\n        depth + 1,\n        accumulatedTracking\n      );\n    }\n\n    mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);\n    return parsed.ad;\n  }\n\n  async function fetchAndParsePod(vastTagUrl: string): Promise<VastAd[]> {\n    const vastXml = await fetchVastXml(vastTagUrl);\n    console.log(\"[HlsAdPlayer] Pod VAST XML received\");\n\n    const parser = new DOMParser();\n    const xmlDoc = parser.parseFromString(vastXml, \"text/xml\");\n\n    if (xmlDoc.querySelector(\"parsererror\")) {\n      console.error(\"[HlsAdPlayer] Pod VAST XML parsing error (malformed)\");\n      return [];\n    }\n\n    const adElements = Array.from(xmlDoc.querySelectorAll(\"Ad\"));\n    if (adElements.length === 0) {\n      console.warn(\"[HlsAdPlayer] No <Ad> elements found in pod VAST response\");\n      return [];\n    }\n\n    adElements.sort((a, b) => {\n      const aSeq = parseInt(a.getAttribute(\"sequence\") || \"\", 10);\n      const bSeq = parseInt(b.getAttribute(\"sequence\") || \"\", 10);\n      const aVal = Number.isFinite(aSeq) ? aSeq : Number.MAX_SAFE_INTEGER;\n      const bVal = Number.isFinite(bSeq) ? bSeq : Number.MAX_SAFE_INTEGER;\n      return aVal - bVal;\n    });\n\n    const ads: VastAd[] = [];\n    for (const adElement of adElements) {\n      const parsed = parseAdElement(adElement);\n\n      if (parsed.type === \"inline\") {\n        ads.push(parsed.ad);\n      } else if (parsed.type === \"wrapper\") {\n        try {\n          const resolved = await fetchAndParseVastAd(\n            parsed.vastAdTagUri,\n            1,\n            parsed.trackingUrls\n          );\n          if (resolved) {\n            ads.push(resolved);\n          }\n        } catch (error) {\n          console.warn(\n            \"[HlsAdPlayer] Failed to resolve wrapper <Ad> in pod:\",\n            error\n          );\n        }\n      }\n    }\n\n    console.log(`[HlsAdPlayer] Parsed ${ads.length} ad(s) from pod VAST response`);\n    return ads;\n  }\n\n  function createAdVideoElement(): HTMLVideoElement {\n    const video = document.createElement(\"video\");\n    video.style.position = \"absolute\";\n    video.style.left = \"0\";\n    video.style.top = \"0\";\n    video.style.width = \"100%\";\n    video.style.height = \"100%\";\n    video.style.objectFit = \"contain\";\n    video.style.backgroundColor = \"#000\";\n    video.playsInline = true;\n    video.muted = false;\n\n    video.volume = 1.0;\n    console.log(\n      `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n    );\n\n    return video;\n  }\n\n  function setupAdEventListeners(): void {\n    if (!adVideoElement || !currentAd) return;\n\n    adVideoElement.addEventListener(\"timeupdate\", () => {\n      if (!currentAd || !adVideoElement) return;\n\n      const progress = adVideoElement.currentTime / currentAd.duration;\n\n      if (progress >= 0.25 && !trackingFired.firstQuartile) {\n        trackingFired.firstQuartile = true;\n        fireTrackingPixels(currentAd.trackingUrls.firstQuartile);\n      }\n\n      if (progress >= 0.5 && !trackingFired.midpoint) {\n        trackingFired.midpoint = true;\n        fireTrackingPixels(currentAd.trackingUrls.midpoint);\n      }\n\n      if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n        trackingFired.thirdQuartile = true;\n        fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);\n      }\n    });\n\n    adVideoElement.addEventListener(\"playing\", () => {\n      if (!currentAd || trackingFired.start) return;\n      trackingFired.start = true;\n      fireTrackingPixels(currentAd.trackingUrls.start);\n      console.log(\"[HlsAdPlayer] Ad started playing\");\n    });\n\n    adVideoElement.addEventListener(\"ended\", () => {\n      if (!currentAd || trackingFired.complete) return;\n      trackingFired.complete = true;\n      fireTrackingPixels(currentAd.trackingUrls.complete);\n      console.log(\"[HlsAdPlayer] Ad completed\");\n\n      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\n      }\n\n      handleAdComplete();\n    });\n\n    adVideoElement.addEventListener(\"error\", (e) => {\n      if (!adPlaying) return;\n      console.error(\"[HlsAdPlayer] Ad video error:\", e);\n      if (currentAd) {\n        fireTrackingPixels(currentAd.trackingUrls.error);\n      }\n\n      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\n      }\n\n      handleAdError();\n    });\n\n    adVideoElement.addEventListener(\"volumechange\", () => {\n      if (!currentAd) return;\n      if (adVideoElement!.muted) {\n        fireTrackingPixels(currentAd.trackingUrls.mute);\n      } else {\n        fireTrackingPixels(currentAd.trackingUrls.unmute);\n      }\n    });\n\n    adVideoElement.addEventListener(\"pause\", () => {\n      if (currentAd && !adVideoElement!.ended) {\n        fireTrackingPixels(currentAd.trackingUrls.pause);\n      }\n    });\n\n    adVideoElement.addEventListener(\"play\", () => {\n      if (currentAd && adVideoElement!.currentTime > 0) {\n        fireTrackingPixels(currentAd.trackingUrls.resume);\n      }\n    });\n  }\n\n  function setAdPlayingFlag(isPlaying: boolean): void {\n    if (isPlaying) {\n      contentVideo.dataset.stormcloudAdPlaying = \"true\";\n    } else {\n      delete contentVideo.dataset.stormcloudAdPlaying;\n    }\n  }\n\n  function resetQuartileTracking(preserveImpression: boolean): void {\n    trackingFired = {\n      impression: preserveImpression ? trackingFired.impression : false,\n      start: false,\n      firstQuartile: false,\n      midpoint: false,\n      thirdQuartile: false,\n      complete: false,\n    };\n  }\n\n  function loadCurrentAdMedia(): void {\n    if (!adVideoElement || !currentAd) {\n      throw new Error(\"No ad video element or ad to load\");\n    }\n\n    const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n    if (!mediaFile) {\n      throw new Error(\"No media file available for ad\");\n    }\n\n    const isHlsAd = isHlsMediaFile(mediaFile);\n    console.log(\n      `[HlsAdPlayer] Loading ${isHlsAd ? \"HLS\" : \"progressive\"} ad (pod ${podIndex + 1}/${podAds.length || 1}) from: ${mediaFile.url}`\n    );\n\n    if (isHlsAd && Hls.isSupported()) {\n      if (adHls) {\n        adHls.destroy();\n      }\n\n      adHls = new Hls({\n        enableWorker: true,\n        lowLatencyMode: false,\n      });\n\n      adHls.loadSource(mediaFile.url);\n      adHls.attachMedia(adVideoElement);\n\n      adHls.on(Hls.Events.MANIFEST_PARSED, () => {\n        console.log(\"[HlsAdPlayer] HLS manifest parsed, starting playback\");\n        adVideoElement!.play().catch((error) => {\n          console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n          handleAdError();\n        });\n      });\n\n      adHls.on(Hls.Events.ERROR, (_event, data) => {\n        console.error(\"[HlsAdPlayer] HLS error:\", data);\n        if (data.fatal) {\n          handleAdError();\n        }\n      });\n    } else if (\n      isHlsAd &&\n      adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")\n    ) {\n      adVideoElement.src = mediaFile.url;\n      adVideoElement.play().catch((error) => {\n        console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n        handleAdError();\n      });\n    } else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {\n      if (adHls) {\n        adHls.destroy();\n        adHls = undefined;\n      }\n\n      adVideoElement.src = mediaFile.url;\n      adVideoElement.load();\n      adVideoElement.play().catch((error) => {\n        console.error(\"[HlsAdPlayer] Error starting progressive ad playback:\", error);\n        handleAdError();\n      });\n    } else {\n      throw new Error(`Unsupported ad media file type: ${mediaFile.type}`);\n    }\n  }\n\n  function advanceToNextPodAd(): boolean {\n    if (podIndex >= podAds.length - 1) {\n      return false;\n    }\n\n    podIndex++;\n    currentAd = podAds[podIndex];\n    resetQuartileTracking(false);\n\n    if (currentAd) {\n      fireTrackingPixels(currentAd.trackingUrls.impression);\n      trackingFired.impression = true;\n      console.log(\n        `[HlsAdPlayer] Advancing to next pod ad (${podIndex + 1}/${podAds.length}): ${currentAd.title}, duration: ${currentAd.duration}s`\n      );\n    }\n\n    try {\n      loadCurrentAdMedia();\n      emit(\"pod_ad_started\", { index: podIndex, total: podAds.length });\n      return true;\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Failed to load next pod ad:\", error);\n      return false;\n    }\n  }\n\n  function handleAdComplete(): void {\n    console.log(\"[HlsAdPlayer] Handling ad completion\");\n    adPlaying = false;\n    setAdPlayingFlag(false);\n\n    contentVideo.muted = true;\n\n    if (adContainerEl) {\n      adContainerEl.style.display = \"none\";\n      adContainerEl.style.pointerEvents = \"none\";\n    }\n    \n    if (options?.continueLiveStreamDuringAds) {\n      if (contentVideo.paused) {\n        console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback\");\n        contentVideo.play().catch(() => {});\n      } else {\n        console.log(\"[HlsAdPlayer] Content video already playing in live mode\");\n      }\n    }\n\n    emit(\"content_resume\");\n  }\n\n  function handleAdError(): void {\n    console.log(\"[HlsAdPlayer] Handling ad error\");\n    adPlaying = false;\n    setAdPlayingFlag(false);\n\n    contentVideo.muted = true;\n\n    if (adContainerEl) {\n      adContainerEl.style.display = \"none\";\n      adContainerEl.style.pointerEvents = \"none\";\n    }\n\n    emit(\"ad_error\");\n  }\n\n  return {\n    initialize() {\n      console.log(\"[HlsAdPlayer] Initializing\");\n\n      if (!adContainerEl) {\n        const container = document.createElement(\"div\");\n        container.style.position = \"absolute\";\n        container.style.left = \"0\";\n        container.style.top = \"0\";\n        container.style.right = \"0\";\n        container.style.bottom = \"0\";\n        container.style.display = \"none\";\n        container.style.alignItems = \"center\";\n        container.style.justifyContent = \"center\";\n        container.style.pointerEvents = \"none\";\n        container.style.zIndex = \"30\";\n        container.style.backgroundColor = \"#000\";\n\n        contentVideo.parentElement?.appendChild(container);\n        adContainerEl = container;\n      }\n    },\n\n    async requestAds(vastTagUrl: string) {\n      console.log(\"[HlsAdPlayer] Requesting ads:\", vastTagUrl);\n\n      if (adPlaying) {\n        console.warn(\n          \"[HlsAdPlayer] Cannot request new ads while an ad is playing\"\n        );\n        return Promise.reject(new Error(\"Ad already playing\"));\n      }\n\n      try {\n        sessionId = generateSessionId();\n        let ads: VastAd[] = [];\n\n        if (preloadedAds.has(vastTagUrl)) {\n          const preloaded = preloadedAds.get(vastTagUrl);\n          preloadedAds.delete(vastTagUrl);\n          if (preloaded) {\n            ads = [preloaded];\n          }\n          console.log(\n            \"[HlsAdPlayer] Using preloaded VAST response:\",\n            vastTagUrl\n          );\n        } else {\n          ads = await fetchAndParsePod(vastTagUrl);\n        }\n\n        if (!ads.length) {\n          console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n          emit(\"ad_error\");\n          return Promise.reject(new Error(\"No ads available from VAST response\"));\n        }\n\n        podAds = ads;\n        podIndex = 0;\n        currentAd = ads[0];\n        console.log(\n          `[HlsAdPlayer] Pod parsed: ${ads.length} ad(s), first=\"${currentAd?.title}\", duration=${currentAd?.duration}s`\n        );\n\n        if (currentAd) {\n          fireTrackingPixels(currentAd.trackingUrls.impression);\n          trackingFired.impression = true;\n        }\n\n        return Promise.resolve();\n      } catch (error) {\n        console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n        emit(\"ad_error\");\n        return Promise.reject(error);\n      }\n    },\n    async play() {\n      if (!currentAd) {\n        console.warn(\n          \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n        );\n        return Promise.reject(new Error(\"No ad loaded\"));\n      }\n\n      console.log(\"[HlsAdPlayer] Starting ad playback\");\n\n      try {\n        if (!adVideoElement) {\n          adVideoElement = createAdVideoElement();\n          adContainerEl?.appendChild(adVideoElement);\n          setupAdEventListeners();\n        }\n\n        resetQuartileTracking(true);\n\n        const contentVolume = contentVideo.volume;\n        originalVolume = Math.max(\n          0,\n          Math.min(1, contentVolume || originalVolume)\n        );\n\n        if (!options?.continueLiveStreamDuringAds) {\n          contentVideo.pause();\n          console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n        } else {\n          console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n        }\n\n        console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n        contentVideo.muted = true;\n        adPlaying = true;\n        setAdPlayingFlag(true);\n\n        if (adVideoElement) {\n          adVideoElement.volume = Math.max(0, Math.min(1, originalVolume));\n          adVideoElement.muted = originalMutedState;\n          console.log(\n            `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`\n          );\n        }\n\n        if (adContainerEl) {\n          adContainerEl.style.display = \"flex\";\n          adContainerEl.style.pointerEvents = \"auto\";\n        }\n\n        emit(\"content_pause\");\n\n        loadCurrentAdMedia();\n\n        return Promise.resolve();\n      } catch (error) {\n        console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n        handleAdError();\n        return Promise.reject(error);\n      }\n    },\n    pause() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n\n      try {\n        if (adVideoElement && !adVideoElement.paused) {\n          adVideoElement.pause();\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error pausing ad:\", error);\n      }\n    },\n    resume() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n\n      try {\n        if (adVideoElement && adVideoElement.paused) {\n          adVideoElement.play().catch(() => {});\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error resuming ad:\", error);\n      }\n    },\n    async stop() {\n      console.log(\"[HlsAdPlayer] Stopping ad\");\n      adPlaying = false;\n      setAdPlayingFlag(false);\n\n      const previousMutedState = contentVideo.muted;\n      contentVideo.muted = originalMutedState;\n      contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n      console.log(\n        `[HlsAdPlayer] Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}, volume: ${contentVideo.volume}`\n      );\n\n      if (adContainerEl) {\n        adContainerEl.style.display = \"none\";\n        adContainerEl.style.pointerEvents = \"none\";\n      }\n\n      contentVideo.style.visibility = \"visible\";\n      contentVideo.style.opacity = \"1\";\n\n      if (options?.continueLiveStreamDuringAds) {\n        if (contentVideo.paused) {\n          console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback on stop\");\n          contentVideo.play().catch(() => {});\n        }\n      }\n\n      if (adHls) {\n        adHls.destroy();\n        adHls = undefined;\n      }\n\n      if (adVideoElement) {\n        adVideoElement.pause();\n        adVideoElement.src = \"\";\n      }\n\n      currentAd = undefined;\n      podAds = [];\n      podIndex = 0;\n    },\n\n    destroy() {\n      console.log(\"[HlsAdPlayer] Destroying\");\n      destroyed = true;\n      \n      for (const timeoutId of pendingTimeouts) {\n        clearTimeout(timeoutId);\n      }\n      pendingTimeouts = [];\n      \n      adPlaying = false;\n      setAdPlayingFlag(false);\n      contentVideo.muted = originalMutedState;\n      contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n\n      if (adHls) {\n        adHls.destroy();\n        adHls = undefined;\n      }\n\n      if (adVideoElement) {\n        adVideoElement.pause();\n        adVideoElement.src = \"\";\n        adVideoElement.remove();\n        adVideoElement = undefined;\n      }\n\n      if (adContainerEl?.parentElement) {\n        adContainerEl.parentElement.removeChild(adContainerEl);\n      }\n\n      adContainerEl = undefined;\n      currentAd = undefined;\n      podAds = [];\n      podIndex = 0;\n      listeners.clear();\n      preloadedAds.clear();\n      preloadingAds.clear();\n    },\n\n    isAdPlaying() {\n      return adPlaying;\n    },\n\n    resize(width: number, height: number) {\n      console.log(`[HlsAdPlayer] Resizing to ${width}x${height}`);\n\n      if (adContainerEl) {\n        adContainerEl.style.width = `${width}px`;\n        adContainerEl.style.height = `${height}px`;\n      }\n\n      if (adVideoElement) {\n        adVideoElement.style.width = `${width}px`;\n        adVideoElement.style.height = `${height}px`;\n      }\n    },\n\n    on(event: string, listener: (payload?: any) => void) {\n      if (!listeners.has(event)) listeners.set(event, new Set());\n      listeners.get(event)!.add(listener);\n    },\n\n    off(event: string, listener: (payload?: any) => void) {\n      listeners.get(event)?.delete(listener);\n    },\n\n    updateOriginalMutedState(muted: boolean, volume?: number) {\n      const nextVolume =\n        typeof volume === \"number\" && !Number.isNaN(volume)\n          ? Math.max(0, Math.min(1, volume))\n          : originalVolume;\n      console.log(\n        `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n      );\n      originalMutedState = muted;\n      originalVolume = nextVolume;\n    },\n\n    getOriginalMutedState() {\n      return originalMutedState;\n    },\n    getOriginalVolume() {\n      return originalVolume;\n    },\n\n    setAdVolume(volume: number) {\n      if (adVideoElement && adPlaying) {\n        const clamped = Math.max(0, Math.min(1, volume));\n        adVideoElement.volume = clamped;\n        adVideoElement.muted = clamped === 0;\n      }\n    },\n\n    getAdVolume(): number {\n      if (adVideoElement && adPlaying) {\n        return adVideoElement.volume;\n      }\n      return 1;\n    },\n    showPlaceholder() {\n      contentVideo.style.opacity = \"0\";\n      contentVideo.style.visibility = \"hidden\";\n      \n      if (!adContainerEl) {\n        const container = document.createElement(\"div\");\n        container.style.position = \"absolute\";\n        container.style.left = \"0\";\n        container.style.top = \"0\";\n        container.style.right = \"0\";\n        container.style.bottom = \"0\";\n        container.style.display = \"none\";\n        container.style.alignItems = \"center\";\n        container.style.justifyContent = \"center\";\n        container.style.pointerEvents = \"none\";\n        container.style.zIndex = \"10\";\n        container.style.backgroundColor = \"#000\";\n\n        contentVideo.parentElement?.appendChild(container);\n        adContainerEl = container;\n      }\n\n      if (adContainerEl) {\n        adContainerEl.style.display = \"flex\";\n        adContainerEl.style.pointerEvents = \"auto\";\n      }\n    },\n    hidePlaceholder() {\n      if (adContainerEl) {\n        adContainerEl.style.display = \"none\";\n        adContainerEl.style.pointerEvents = \"none\";\n      }\n      \n      if (!adPlaying) {\n        contentVideo.style.visibility = \"visible\";\n        contentVideo.style.opacity = \"1\";\n      }\n    },\n    getLoadedAdDuration() {\n      return currentAd?.duration;\n    },\n    getLoadedAdId() {\n      return currentAd?.id;\n    },\n    getPodAdCount() {\n      return podAds.length;\n    },\n    getPodTotalDurationMs() {\n      return podAds.reduce(\n        (total, ad) => total + (ad.duration > 0 ? ad.duration * 1000 : 0),\n        0\n      );\n    },\n  };\n}\n","declare global {\n  interface Window {\n    goog?: any;\n  }\n}\n\nconst PAL_SDK_URL =\n  \"https://imasdk.googleapis.com/pal/sdkloader/pal.js\";\n\nlet _nonceLoader: any | undefined;\nlet _palLoadPromise: Promise<void> | undefined;\n\nfunction loadPalSdk(): Promise<void> {\n  if (typeof window !== \"undefined\" && window.goog?.pal) {\n    return Promise.resolve();\n  }\n\n  if (_palLoadPromise) return _palLoadPromise;\n\n  _palLoadPromise = new Promise<void>((resolve, reject) => {\n    const existing = document.querySelector(\n      'script[data-pal=\"true\"]'\n    ) as HTMLScriptElement | null;\n\n    if (existing) {\n      if (window.goog?.pal) {\n        resolve();\n        return;\n      }\n      const timeout = setTimeout(\n        () => reject(new Error(\"PAL SDK load timeout\")),\n        10000\n      );\n      existing.addEventListener(\"load\", () => {\n        clearTimeout(timeout);\n        resolve();\n      });\n      existing.addEventListener(\"error\", () => {\n        clearTimeout(timeout);\n        reject(new Error(\"PAL SDK load failed\"));\n      });\n      return;\n    }\n\n    const script = document.createElement(\"script\");\n    script.src = PAL_SDK_URL;\n    script.async = true;\n    script.setAttribute(\"data-pal\", \"true\");\n    script.onload = () => resolve();\n    script.onerror = () => reject(new Error(\"PAL SDK load failed\"));\n    document.head.appendChild(script);\n  });\n\n  return _palLoadPromise;\n}\n\nfunction getOrCreateNonceLoader(): any {\n  if (_nonceLoader) return _nonceLoader;\n  const goog = window.goog;\n  const consentSettings = new goog.pal.ConsentSettings();\n  consentSettings.allowStorage = true;\n  _nonceLoader = new goog.pal.NonceLoader(consentSettings);\n  return _nonceLoader;\n}\n\nexport interface PalNonceOptions {\n  videoWidth?: number;\n  videoHeight?: number;\n  descriptionUrl?: string;\n  ppid?: string;\n  sessionId?: string;\n  adWillAutoPlay?: boolean;\n  adWillPlayMuted?: boolean;\n  playerVolume?: number;\n  continuousPlayback?: boolean;\n}\n\nexport interface PalNonceManager {\n  generateNonce(options?: PalNonceOptions): Promise<string>;\n\n  getCurrentNonce(): string;\n\n  injectNonce(vastTagUrl: string): string;\n\n  sendPlaybackStart(): void;\n\n  sendPlaybackEnd(): void;\n\n  sendAdClick(): void;\n\n  sendAdTouch(event: MouseEvent | TouchEvent): void;\n\n  reset(): void;\n}\n\nexport function createPalNonceManager(): PalNonceManager {\n  let currentNonce = \"\";\n  let currentNonceManager: any | undefined;\n\n  return {\n    async generateNonce(options: PalNonceOptions = {}): Promise<string> {\n      try {\n        await loadPalSdk();\n\n        const loader = getOrCreateNonceLoader();\n        const goog = window.goog;\n\n        const request = new goog.pal.NonceRequest();\n        request.adWillAutoPlay = options.adWillAutoPlay ?? true;\n        request.adWillPlayMuted = options.adWillPlayMuted ?? false;\n        request.playerVolume =\n          options.playerVolume ?? (request.adWillPlayMuted ? 0 : 1);\n        request.continuousPlayback = options.continuousPlayback ?? true;\n        request.descriptionUrl =\n          options.descriptionUrl ||\n          (typeof window !== \"undefined\" ? window.location.href : \"\");\n        request.iconsSupported = true;\n        request.playerType = \"StormcloudVideoPlayer\";\n        request.playerVersion = \"1.0\";\n        request.supportedApiFrameworks = \"2,7,9\";\n        request.url =\n          options.descriptionUrl ||\n          (typeof window !== \"undefined\" ? window.location.href : \"\");\n        request.videoWidth = options.videoWidth || 640;\n        request.videoHeight = options.videoHeight || 480;\n\n        if (options.ppid) request.ppid = options.ppid;\n        if (options.sessionId) request.sessionId = options.sessionId;\n\n        const manager = await loader.loadNonceManager(request);\n        currentNonceManager = manager;\n        currentNonce = manager.getNonce() as string;\n\n        console.log(\"[PAL] Nonce generated successfully\");\n        return currentNonce;\n      } catch (error) {\n        console.warn(\"[PAL] Failed to generate nonce:\", error);\n        currentNonce = \"\";\n        currentNonceManager = undefined;\n        return \"\";\n      }\n    },\n\n    getCurrentNonce(): string {\n      return currentNonce;\n    },\n\n    injectNonce(vastTagUrl: string): string {\n      if (!currentNonce || !vastTagUrl) return vastTagUrl;\n\n      try {\n        const url = new URL(vastTagUrl);\n        url.searchParams.delete(\"paln\");\n        url.searchParams.set(\"givn\", currentNonce);\n        return url.toString();\n      } catch {\n        let base = vastTagUrl\n          .replace(/([?&])paln=[^&]*/g, \"\")\n          .replace(/[?&]$/, \"\");\n        const sep = base.includes(\"?\") ? \"&\" : \"?\";\n        return `${base}${sep}givn=${encodeURIComponent(currentNonce)}`;\n      }\n    },\n\n    sendPlaybackStart(): void {\n      try {\n        currentNonceManager?.sendPlaybackStart();\n      } catch {}\n    },\n\n    sendPlaybackEnd(): void {\n      try {\n        currentNonceManager?.sendPlaybackEnd();\n      } catch {}\n    },\n\n    sendAdClick(): void {\n      try {\n        currentNonceManager?.sendAdClick();\n      } catch {}\n    },\n\n    sendAdTouch(event: MouseEvent | TouchEvent): void {\n      try {\n        currentNonceManager?.sendAdTouch(event);\n      } catch {}\n    },\n\n    reset(): void {\n      currentNonce = \"\";\n      currentNonceManager = undefined;\n    },\n  };\n}\n","export const MQTT_CA_CERT_FILE = \"src/certs/emqxsl-ca.crt\";\n\nexport type MQTTConfig = {\n  enabled: boolean;\n  brokerAddress: string;\n  brokerPort: number;\n  wsPort: number;\n  username: string;\n  password: string;\n  topicPrefix: string;\n  qos: 0 | 1 | 2;\n  brokerUrl?: string;\n};\n\nexport const DEFAULT_MQTT_CONFIG: MQTTConfig = {\n  enabled: true,\n  brokerAddress: \"vecbae77.ala.us-east-1.emqxsl.com\",\n  brokerPort: 8883,\n  wsPort: 8084,\n  username: \"for-sonifi\",\n  password: \"sonifi-mqtt\",\n  topicPrefix: \"adstorm/players\",\n  qos: 1,\n};\n\nexport const mqttConfig: MQTTConfig = { ...DEFAULT_MQTT_CONFIG };\n\nexport function applyMQTTConfig(overrides: Partial<MQTTConfig>): void {\n  Object.assign(mqttConfig, overrides);\n}\n\nexport function isMQTTEnabled(): boolean {\n  return mqttConfig.enabled;\n}\n\nexport function buildMQTTBrokerUrl(): string {\n  if (mqttConfig.brokerUrl) return mqttConfig.brokerUrl;\n  return `wss://${mqttConfig.brokerAddress}:${mqttConfig.wsPort}/mqtt`;\n}\n\nexport function buildPlayerTopic(\n  licenseKey: string,\n  channel: \"metrics\" | \"impressions\" | \"heartbeat\"\n): string {\n  return `${mqttConfig.topicPrefix}/${licenseKey}/${channel}`;\n}\n","import mqtt from \"mqtt\";\nimport type { MqttClient } from \"mqtt\";\nimport {\n  applyMQTTConfig,\n  buildMQTTBrokerUrl,\n  isMQTTEnabled,\n  mqttConfig,\n} from \"./mqttConfig\";\nimport type { MQTTConfig } from \"./mqttConfig\";\n\nconst LOG = \"[StormcloudVideoPlayer][MQTT]\";\n\nexport type MQTTStatus = \"disconnected\" | \"connecting\" | \"connected\" | \"error\";\n\nlet client: MqttClient | null = null;\nlet status: MQTTStatus = \"disconnected\";\n\nexport function getMQTTStatus(): MQTTStatus {\n  return status;\n}\n\nexport function isMQTTConnected(): boolean {\n  return status === \"connected\" && client !== null && client.connected;\n}\n\nexport function isMQTTConfigured(): boolean {\n  return isMQTTEnabled();\n}\n\nexport function configureMQTT(overrides: Partial<MQTTConfig>): void {\n  applyMQTTConfig(overrides);\n  disconnectMQTT();\n}\n\nexport function initMQTTClient(): void {\n  if (client || !isMQTTEnabled()) return;\n\n  const url = buildMQTTBrokerUrl();\n  status = \"connecting\";\n\n  const clientId = `stormcloud-vp-${Math.random().toString(36).slice(2, 9)}`;\n\n  try {\n    client = mqtt.connect(url, {\n      clientId,\n      username: mqttConfig.username,\n      password: mqttConfig.password,\n      keepalive: 60,\n      clean: true,\n      reconnectPeriod: 5000,\n      connectTimeout: 10_000,\n      queueQoSZero: false,\n    });\n  } catch (err) {\n    status = \"error\";\n    console.warn(`${LOG} connect() threw:`, err);\n    return;\n  }\n\n  client.on(\"connect\", () => {\n    status = \"connected\";\n    console.info(`${LOG} connected to ${url}`);\n  });\n\n  client.on(\"reconnect\", () => {\n    status = \"connecting\";\n    console.info(`${LOG} reconnecting…`);\n  });\n\n  client.on(\"offline\", () => {\n    status = \"disconnected\";\n    console.warn(`${LOG} offline`);\n  });\n\n  client.on(\"error\", (err) => {\n    status = \"error\";\n    console.warn(`${LOG} error:`, err.message);\n  });\n\n  client.on(\"close\", () => {\n    if (status === \"connected\") {\n      status = \"disconnected\";\n    }\n  });\n}\n\nexport function ensureMQTTClient(): void {\n  if (isMQTTEnabled() && !client) {\n    initMQTTClient();\n  }\n}\n\nexport function publishMQTT(\n  topic: string,\n  payload: Record<string, unknown>\n): boolean {\n  if (!isMQTTEnabled()) {\n    return false;\n  }\n\n  ensureMQTTClient();\n\n  if (!client) {\n    return false;\n  }\n\n  try {\n    client.publish(topic, JSON.stringify(payload), { qos: mqttConfig.qos });\n    return true;\n  } catch (err) {\n    console.warn(`${LOG} publish failed on ${topic}:`, err);\n    return false;\n  }\n}\n\nexport function disconnectMQTT(): void {\n  if (client) {\n    client.end(true);\n    client = null;\n    status = \"disconnected\";\n  }\n}\n","export interface VastEnvironmentSignals {\n  isCtv: boolean;\n  contentUrl?: string;\n  appId?: string;\n  appName?: string;\n  sessionId?: string;\n  deviceId?: string;\n  deviceIdType?: string;\n  limitAdTracking?: boolean;\n  deviceTypeHint?: number;\n}\n\nconst AIRY_ANDROID_APP_ID = \"com.freeairytv.android\";\nconst AIRY_WEBOS_APP_ID    = \"com.freeairytv.webos\";\nconst AIRY_TIZEN_APP_ID    = \"com.freeairytv.samsung\";\nconst AIRY_ROKU_APP_ID     = \"com.freeairytv.roku\";\nconst AIRY_APP_NAME = \"AiryTV Movies & TV\";\nconst AIRY_DEFAULT_CONTENT_URL = \"https://live.airy.tv\";\nconst CTV_SESSION_STORAGE_KEY = \"stormcloud.ctv.sid\";\nexport const PLAYER_ID_STORAGE_KEY = \"stormcloud.player.id\";\n\nconst LG_TEST_APP_ID      = \"com.hulu.plus\";\nconst LG_TEST_APP_NAME    = \"Hulu\";\nconst LG_TEST_CONTENT_URL = \"https://www.hulu.com/live-tv\";\n\nlet _lgTestDeviceId: string | undefined;\nfunction getLgTestDeviceId(): string {\n  if (!_lgTestDeviceId) _lgTestDeviceId = createUuid();\n  return _lgTestDeviceId;\n}\n\nfunction isLgWebOS(): boolean {\n  if (typeof navigator === \"undefined\") return false;\n  return /Web0S|webOS|LG Browser|LGSTB|LGE/i.test(navigator.userAgent);\n}\n\nfunction getDefaultAppId(): string {\n  if (typeof navigator === \"undefined\") return AIRY_ANDROID_APP_ID;\n  const ua = navigator.userAgent;\n  if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;\n  if (/Tizen|Samsung/i.test(ua))                       return AIRY_TIZEN_APP_ID;\n  if (/Roku/i.test(ua))                                return AIRY_ROKU_APP_ID;\n  return AIRY_ANDROID_APP_ID;\n}\n\nconst DEVICE_ID_STORAGE_KEYS = [\n  \"rdid\",\n  \"ifa\",\n  \"advertisingId\",\n  \"advertising_id\",\n  \"deviceAdvertisingId\",\n  \"aaid\",\n  \"adid\",\n  \"rida\",\n  \"tifa\",\n  \"lgudid\",\n];\n\nconst ANDROID_ID_TYPES = new Set([\"aaid\", \"adid\"]);\n\nexport function resolveVastEnvironmentSignals(isCtv: boolean): VastEnvironmentSignals {\n  const bridgeSignals  = readNativeBridgeSignals();\n  const platformDevice = readPlatformNativeDeviceId();\n  const lg = isCtv && isLgWebOS();\n\n  const deviceId =\n    bridgeSignals.deviceId  ||\n    readStoredDeviceId()    ||\n    platformDevice.deviceId ||\n    (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : undefined);\n  const deviceIdType =\n    bridgeSignals.deviceIdType  ||\n    readStoredString(\"deviceIdType\") ||\n    readStoredString(\"idtype\") ||\n    platformDevice.deviceIdType ||\n    inferDeviceIdType() ||\n    (lg ? \"lgudid\" : undefined);\n  const platformLat = bridgeSignals.deviceId\n    ? bridgeSignals.limitAdTracking\n    : platformDevice.limitAdTracking;\n  const limitAdTracking =\n    deviceId != null\n      ? platformLat ?? readStoredLimitAdTracking() ?? false\n      : undefined;\n\n  if (isCtv) {\n    return {\n      isCtv: true,\n      contentUrl:\n        bridgeSignals.contentUrl ||\n        readStoredString(\"contentUrl\") ||\n        (lg ? LG_TEST_CONTENT_URL : AIRY_DEFAULT_CONTENT_URL),\n      appId:\n        bridgeSignals.appId ||\n        readStoredString(\"appId\") ||\n        readStoredString(\"msid\") ||\n        (lg ? LG_TEST_APP_ID : getDefaultAppId()),\n      appName:\n        bridgeSignals.appName ||\n        readStoredString(\"appName\") ||\n        readStoredString(\"an\") ||\n        (lg ? LG_TEST_APP_NAME : AIRY_APP_NAME),\n      sessionId: getOrCreateCtvSessionId(),\n      ...(deviceId ? { deviceId } : {}),\n      ...(deviceIdType ? { deviceIdType } : {}),\n      ...(limitAdTracking != null ? { limitAdTracking } : {}),\n      deviceTypeHint: 5,\n    };\n  }\n\n  return {\n    isCtv: false,\n    ...(deviceId ? { deviceId } : {}),\n    ...(deviceIdType ? { deviceIdType } : {}),\n    ...(limitAdTracking != null ? { limitAdTracking } : {}),\n  };\n}\n\nexport function inferDeviceIdType(): string | undefined {\n  if (typeof navigator === \"undefined\") {\n    return undefined;\n  }\n\n  const ua = navigator.userAgent;\n  if (/Roku/i.test(ua)) return \"rida\";\n  if (/Tizen|Samsung/i.test(ua)) return \"tifa\";\n  if (/AppleTV|Apple TV/i.test(ua)) return \"tvOS\";\n  if (/AFT|Fire TV|Amazon/i.test(ua)) return \"afai\";\n  if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return \"lgudid\";\n  if (/Android|Google TV/i.test(ua)) return \"aaid\";\n  if (/iPhone|iPad|iPod/i.test(ua)) return \"idfa\";\n  return undefined;\n}\n\nexport function isEquivalentDeviceIdType(\n  tagType: string | undefined,\n  runtimeType: string | undefined\n): boolean {\n  if (!tagType || !runtimeType) return false;\n  const tag = tagType.toLowerCase();\n  const runtime = runtimeType.toLowerCase();\n  if (tag === runtime) return true;\n  return ANDROID_ID_TYPES.has(tag) && ANDROID_ID_TYPES.has(runtime);\n}\n\nexport function resolveNativeDeviceId(): string | undefined {\n  const bridgeSignals = readNativeBridgeSignals();\n  const platformDevice = readPlatformNativeDeviceId();\n  const deviceId =\n    bridgeSignals.deviceId ||\n    readStoredDeviceId() ||\n    platformDevice.deviceId;\n\n  if (!deviceId || isMacroPlaceholder(deviceId) || isZeroedAdId(deviceId)) {\n    return undefined;\n  }\n\n  return deviceId;\n}\n\nexport function getOrCreateStoredUuid(storageKey: string): string | undefined {\n  if (typeof window === \"undefined\") {\n    return undefined;\n  }\n\n  const existing = readStoredString(storageKey);\n  if (existing) {\n    return existing;\n  }\n\n  const id = createUuid();\n  try {\n    window.localStorage?.setItem(storageKey, id);\n  } catch {}\n  return id;\n}\n\nfunction getOrCreateCtvSessionId(): string {\n  const existing = readStoredString(CTV_SESSION_STORAGE_KEY);\n  if (existing) {\n    return existing;\n  }\n\n  const sessionId = createUuid();\n  try {\n    window.localStorage?.setItem(CTV_SESSION_STORAGE_KEY, sessionId);\n  } catch {}\n  return sessionId;\n}\n\nfunction createUuid(): string {\n  if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n    return crypto.randomUUID();\n  }\n\n  return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (char) => {\n    const value = Math.floor(Math.random() * 16);\n    const nibble = char === \"x\" ? value : (value & 0x3) | 0x8;\n    return nibble.toString(16);\n  });\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","import type { AdController } from \"../types\";\n\nexport function getAdAudioVolume(adPlayer: AdController): number {\n  return adPlayer.getOriginalMutedState() ? 0 : adPlayer.getOriginalVolume();\n}\n\nexport function toggleMute(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  debug: boolean\n): void {\n  if (adPlayer.isAdPlaying()) {\n    const newMutedState = !adPlayer.getOriginalMutedState();\n    const restoreVolume = adPlayer.getOriginalVolume() || 1;\n\n    adPlayer.updateOriginalMutedState(newMutedState, video.volume);\n    adPlayer.setAdVolume(newMutedState ? 0 : restoreVolume);\n\n    if (debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] Mute toggle during ad - immediately applied:\",\n        newMutedState\n      );\n    }\n  } else {\n    video.muted = !video.muted;\n    adPlayer.updateOriginalMutedState(video.muted, video.volume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] Muted:\", video.muted);\n    }\n  }\n}\n\nexport function toggleFullscreen(\n  video: HTMLVideoElement,\n  debug: boolean\n): Promise<void> {\n  return new Promise((resolve, reject) => {\n    if (!document.fullscreenElement) {\n      const container = video.parentElement;\n      if (!container) {\n        reject(new Error(\"No parent container found for fullscreen\"));\n        return;\n      }\n      container\n        .requestFullscreen()\n        .then(() => {\n          if (debug) {\n            console.log(\"[StormcloudVideoPlayer] Entered fullscreen\");\n          }\n          resolve();\n        })\n        .catch((err) => {\n          if (debug) {\n            console.error(\"[StormcloudVideoPlayer] Fullscreen error:\", err);\n          }\n          reject(err);\n        });\n    } else {\n      document\n        .exitFullscreen()\n        .then(() => {\n          if (debug) {\n            console.log(\"[StormcloudVideoPlayer] Exited fullscreen\");\n          }\n          resolve();\n        })\n        .catch((err) => {\n          if (debug) {\n            console.error(\n              \"[StormcloudVideoPlayer] Exit fullscreen error:\",\n              err\n            );\n          }\n          reject(err);\n        });\n    }\n  });\n}\n\nexport function isMuted(\n  video: HTMLVideoElement,\n  adPlayer: AdController\n): boolean {\n  if (adPlayer.isAdPlaying()) {\n    return adPlayer.getOriginalMutedState();\n  }\n  return video.muted;\n}\n\nexport function setMuted(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  muted: boolean,\n  debug: boolean\n): void {\n  const adPlaying = adPlayer.isAdPlaying();\n\n  if (adPlaying && muted === video.muted) {\n    if (debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] setMuted reflective update during ad ignored\",\n        { muted }\n      );\n    }\n    return;\n  }\n\n  video.muted = muted;\n\n  if (adPlaying) {\n    adPlayer.updateOriginalMutedState(muted, video.volume);\n    adPlayer.setAdVolume(muted ? 0 : 1);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setMuted applied during ad\", {\n        muted,\n      });\n    }\n    return;\n  }\n\n  adPlayer.updateOriginalMutedState(muted, video.volume);\n  if (debug) {\n    console.log(\"[StormcloudVideoPlayer] setMuted called:\", muted);\n  }\n}\n\nexport function setVolume(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  volume: number,\n  debug: boolean\n): void {\n  const clampedVolume = Math.max(0, Math.min(1, volume));\n  const adPlaying = adPlayer.isAdPlaying();\n\n  if (adPlaying) {\n    adPlayer.setAdVolume(clampedVolume);\n    adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setVolume applied during ad\", {\n        volume: clampedVolume,\n      });\n    }\n  } else {\n    video.volume = clampedVolume;\n    video.muted = clampedVolume === 0;\n    adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setVolume called:\", clampedVolume);\n    }\n  }\n}\n\nexport function getVolume(\n  video: HTMLVideoElement,\n  adPlayer: AdController\n): number {\n  const adPlaying = adPlayer.isAdPlaying();\n  if (adPlaying) {\n    return adPlayer.getAdVolume();\n  }\n  return video.volume;\n}\n\nexport function isFullscreen(): boolean {\n  return !!document.fullscreenElement;\n}\n\nexport function resizePlayer(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  debug: boolean\n): void {\n  if (debug) {\n    console.log(\"[StormcloudVideoPlayer] Resizing player\");\n  }\n\n  if (adPlayer && adPlayer.isAdPlaying()) {\n    const width = video.clientWidth || 640;\n    const height = video.clientHeight || 480;\n\n    if (debug) {\n      console.log(\n        `[StormcloudVideoPlayer] Resizing ads manager to ${width}x${height}`\n      );\n    }\n\n    adPlayer.resize(width, height);\n  }\n}\n","import type {\n  StormcloudVideoPlayerConfig,\n  Scte35Marker,\n  AdController,\n} from \"../types\";\nimport {\n  buildAnalyticsContext,\n  sendAdLoadedTracking,\n  sendAdImpressionTracking,\n} from \"../utils/tracking\";\nimport type { AdTimingService } from \"./AdTimingService\";\nimport type { AdPreloadPool } from \"./AdPreloadPool\";\nimport type { AdConfigManager } from \"./AdConfigManager\";\nimport type { Scte35CueManager } from \"./Scte35CueManager\";\nimport type { PlaceholderLayer } from \"./PlaceholderLayer\";\nimport { getAdAudioVolume } from \"./PlayerControls\";\n\nexport interface AdBreakOrchestratorHost {\n  readonly config: StormcloudVideoPlayerConfig;\n  readonly video: HTMLVideoElement;\n  getAdPlayer(): AdController;\n  setAdPlayer(player: AdController): void;\n  createAdPlayer(continueLiveStreamDuringAds: boolean): AdController;\n  shouldContinueLiveStreamDuringAds(): boolean;\n  getLiveSyncPosition(): number | undefined;\n  generateVastUrls(baseUrl: string, count: number): string[];\n  generatePodVastUrl(baseUrl: string, breakDurationMs?: number): string;\n}\n\nexport class AdBreakOrchestrator {\n  inAdBreak = false;\n  showAds: boolean = false;\n  isShowingPlaceholder: boolean = false;\n  adDetectSentForCurrentBreak: boolean = false;\n\n  private continuousFetchingActive: boolean = false;\n  private continuousFetchLoopRunning = false;\n  adRequestQueue: string[] = [];\n  adPodQueue: string[] = [];\n  private readonly maxPlaceholderDurationMs: number = 5000;\n\n  pendingAdBreak: {\n    marker: Scte35Marker;\n    detectedAtFragmentSn?: number;\n    vastUrls: string[];\n    isFetching: boolean;\n    fetchStartTime?: number;\n  } | null = null;\n  prefetchTimerId: number | undefined;\n\n  private readonly host: AdBreakOrchestratorHost;\n  private readonly timing: AdTimingService;\n  private readonly preloadPool: AdPreloadPool;\n  private readonly adConfig: AdConfigManager;\n  private readonly cueManager: Scte35CueManager;\n  private readonly placeholder: PlaceholderLayer;\n\n  constructor(\n    host: AdBreakOrchestratorHost,\n    timing: AdTimingService,\n    preloadPool: AdPreloadPool,\n    adConfig: AdConfigManager,\n    cueManager: Scte35CueManager,\n    placeholder: PlaceholderLayer\n  ) {\n    this.host = host;\n    this.timing = timing;\n    this.preloadPool = preloadPool;\n    this.adConfig = adConfig;\n    this.cueManager = cueManager;\n    this.placeholder = placeholder;\n  }\n\n  private get debug(): boolean {\n    return !!this.host.config.debugAdTiming;\n  }\n\n  private get analyticsContext() {\n    return buildAnalyticsContext(this.host.config);\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  IMA event listeners\n  // ───────────────────────────────────────────────────────────────\n\n  private get optimizedPodsEnabled(): boolean {\n    return !!this.host.config.optimizedPods;\n  }\n\n  attachImaEventListeners(): void {\n    const adPlayer = this.host.getAdPlayer();\n    adPlayer.on(\"pod_ad_started\", (payload?: any) => {\n      this.timing.notePodAdStarted();\n      if (this.debug) {\n        console.log(\n          `[POD] Playing pod ad ${payload?.index != null ? payload.index + 1 : \"?\"}/${payload?.total ?? \"?\"}`\n        );\n      }\n    });\n    adPlayer.on(\"all_ads_completed\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n\n      this.timing.consecutiveFailures = 0;\n\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] all_ads_completed event received - remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n\n      if (this.inAdBreak) {\n        if (this.timing.hasTimeToStartAnotherAd()) {\n          this.tryNextAvailableAdWithRateLimit();\n        } else {\n          this.handleAdPodComplete();\n        }\n      }\n    });\n    adPlayer.on(\"ad_error\", (errorPayload?: any) => {\n      let errorMessage = \"Ad playback failed\";\n\n      if (errorPayload) {\n        const errorCode = errorPayload.code || errorPayload.errorCode || \"unknown\";\n        const vastErrorCode = errorPayload.vastErrorCode;\n        const message = errorPayload.message || errorPayload.errorMessage || \"Unknown error\";\n        const cause = errorPayload.cause || errorPayload.innerError || errorPayload.error;\n\n        errorMessage = `Ad error: AdError ${errorCode}: ${message}`;\n\n        if (vastErrorCode && vastErrorCode !== \"N/A\" && vastErrorCode !== errorCode) {\n          errorMessage += ` (VAST Error Code: ${vastErrorCode})`;\n        }\n\n        if (cause) {\n          const causeMessage = typeof cause === \"string\" ? cause : (cause.message || String(cause));\n          errorMessage += `. Caused by: ${causeMessage}`;\n        }\n      }\n\n      console.error(\"[AD-ERROR]\", errorMessage, errorPayload || \"\");\n      this.handleAdFailure();\n    });\n    adPlayer.on(\"content_pause\", () => {\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = true;\n      this.timing.resetGamNoFillCounter();\n\n      if (this.inAdBreak && this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)\");\n        }\n      }\n\n      this.host.getAdPlayer().setAdVolume(getAdAudioVolume(this.host.getAdPlayer()));\n\n      if (this.isShowingPlaceholder) {\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Hiding placeholder - new ads starting\");\n        }\n        this.host.getAdPlayer().hidePlaceholder();\n        this.isShowingPlaceholder = false;\n      }\n    });\n    adPlayer.on(\"content_resume\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      if (!this.host.video.muted) {\n        this.host.video.muted = true;\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Muted video on content_resume (ad ended, gap between ads)\");\n        }\n      }\n\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = false;\n\n      if (!this.inAdBreak) {\n        return;\n      }\n\n      this.timing.consecutiveFailures = 0;\n\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n\n      if (this.debug) {\n        console.log(\n          `[CONTINUOUS-FETCH] content_resume event: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n\n      if (this.timing.hasTimeToStartAnotherAd()) {\n        this.tryNextAvailableAdWithRateLimit();\n      } else {\n        this.handleAdPodComplete();\n      }\n    });\n  }\n\n  recreateAdController(): void {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Recreating AdController for new ad\");\n    }\n\n    const shouldShowPlaceholder = this.inAdBreak && this.showAds;\n    const adPlayer = this.host.getAdPlayer();\n    if (shouldShowPlaceholder && adPlayer) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Showing placeholder before destroying old AdController\");\n      }\n      this.placeholder.show();\n      adPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n\n    const preservedMutedState = adPlayer.getOriginalMutedState();\n    const preservedVolumeState = adPlayer.getOriginalVolume();\n\n    if (adPlayer) {\n      try {\n        adPlayer.destroy();\n        this.host.video.muted = true;\n      } catch (error) {\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] Error destroying old AdController:\", error);\n        }\n      }\n    }\n\n    const continueLiveStreamDuringAds = this.host.shouldContinueLiveStreamDuringAds();\n    const newAdPlayer = this.host.createAdPlayer(continueLiveStreamDuringAds);\n    this.host.setAdPlayer(newAdPlayer);\n\n    newAdPlayer.initialize();\n    newAdPlayer.updateOriginalMutedState(preservedMutedState, preservedVolumeState);\n    this.attachImaEventListeners();\n\n    if (shouldShowPlaceholder) {\n      this.placeholder.show();\n      newAdPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n  }\n\n  clearPendingAdBreak(): void {\n    if (this.prefetchTimerId != null) {\n      clearTimeout(this.prefetchTimerId);\n      this.prefetchTimerId = undefined;\n    }\n    this.pendingAdBreak = null;\n    this.cueManager.pendingScte35CueKey = undefined;\n    this.adConfig.podAssignedByPrefetch = false;\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Ad break start\n  // ───────────────────────────────────────────────────────────────\n\n  async handleAdStart(_marker: Scte35Marker): Promise<void> {\n    const scheduled = this.adConfig.findCurrentOrNextBreak(\n      this.host.video.currentTime * 1000\n    );\n    if (scheduled) {\n      this.adConfig.consumedVmapBreakIds.add(this.adConfig.getAdBreakKey(scheduled));\n    }\n    const tags = this.adConfig.selectVastTagsForBreak(scheduled);\n\n    let baseVastUrl: string;\n\n    if (tags && tags.length > 0 && tags[0]) {\n      baseVastUrl = tags[0];\n    } else if (this.adConfig.apiVastTagUrl) {\n      baseVastUrl = this.adConfig.apiVastTagUrl;\n    } else {\n      this.clearPendingAdBreak();\n      return;\n    }\n\n    const adBreakDurationMs =\n      _marker.durationSeconds != null\n        ? _marker.durationSeconds * 1000\n        : scheduled?.durationMs;\n\n    if (this.debug) {\n      const mode = this.host.config.isLiveStream ? \"LIVE\" : \"VOD\";\n      console.log(\n        `[CONTINUOUS-FETCH] ${mode} MODE: Target duration=${adBreakDurationMs}ms`\n      );\n    }\n\n    this.timing.failedVastUrls.clear();\n    this.timing.temporaryFailureUrls.clear();\n    this.timing.consecutiveFailures = 0;\n    this.continuousFetchingActive = true;\n    this.isShowingPlaceholder = false;\n    this.timing.totalAdRequestsInBreak = 0;\n\n    if (this.adConfig.podAssignedByPrefetch) {\n      this.adConfig.podAssignedByPrefetch = false;\n    } else {\n      this.adConfig.beginNewAdPod();\n    }\n\n    const currentMuted = this.host.video.muted;\n    const currentVolume = this.host.video.volume;\n    this.host.getAdPlayer().updateOriginalMutedState(currentMuted, currentVolume);\n\n    this.inAdBreak = true;\n    this.timing.adBreakPlayedDurationMs = 0;\n    this.timing.currentAdIndex = 0;\n    this.timing.totalAdsInBreak = 0;\n    this.adPodQueue = [];\n    this.showAds = false;\n\n    if (\n      this.timing.expectedAdBreakDurationMs == null &&\n      adBreakDurationMs != null\n    ) {\n      this.timing.expectedAdBreakDurationMs = adBreakDurationMs;\n    }\n\n    if (this.optimizedPodsEnabled) {\n      const podPlayed = await this.startOptimizedPod(\n        baseVastUrl,\n        adBreakDurationMs,\n        currentMuted,\n        currentVolume\n      );\n      if (podPlayed) {\n        return;\n      }\n      if (this.debug) {\n        console.log(\"[POD] Optimized pod unavailable, falling back to sequential single-ad path\");\n      }\n    }\n\n    let firstAdUrl: string | undefined;\n    let usePreloadedAd = false;\n    let preloadedController: AdController | undefined;\n\n    const preloaded = this.preloadPool.getPreloadedAd();\n    if (preloaded) {\n      firstAdUrl = preloaded.vastUrl;\n      preloadedController = preloaded.adController;\n      usePreloadedAd = true;\n\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: firstAdUrl, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Using preloaded ad from pool (preloaded in advance, ready immediately!)\");\n      }\n    } else if (this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0) {\n      this.adRequestQueue = [...this.pendingAdBreak.vastUrls];\n      firstAdUrl = this.adRequestQueue.shift();\n\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Pool empty, using prefetched URLs (${this.adRequestQueue.length + 1} available)`);\n      }\n\n      this.clearPendingAdBreak();\n    } else {\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Generating new ad URLs...\");\n      }\n\n      const firstAdUrlArray = this.host.generateVastUrls(baseVastUrl, 1);\n      firstAdUrl = firstAdUrlArray[0];\n      this.adRequestQueue = [];\n    }\n\n    if (!firstAdUrl) {\n      if (this.debug) {\n        console.warn(\"[CONTINUOUS-FETCH] Failed to get first ad URL\");\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] First VAST URL:\", firstAdUrl);\n    }\n\n    try {\n      if (usePreloadedAd && preloadedController) {\n        if (!this.timing.ensureLoadedAdFitsBudget(preloadedController)) {\n          this.timing.rejectLoadedAdForDuration(preloadedController);\n          this.startContinuousFetching(baseVastUrl);\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n\n        const adPlayer = this.host.getAdPlayer();\n        const preservedMuted = adPlayer.getOriginalMutedState();\n        const preservedVolume = adPlayer.getOriginalVolume();\n        adPlayer.destroy();\n        this.host.video.muted = true;\n        this.host.setAdPlayer(preloadedController);\n        preloadedController.updateOriginalMutedState(preservedMuted, preservedVolume);\n\n        this.attachImaEventListeners();\n\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] Using preloaded ad, resuming and starting playback immediately (no request delay!)\");\n        }\n\n        preloadedController.resume();\n\n        this.timing.consecutiveFailures = 0;\n        this.startContinuousFetching(baseVastUrl);\n\n        if (!this.preloadPool.active) {\n          this.preloadPool.active = true;\n        }\n        if (!this.preloadPool.isLoopRunning) {\n          this.preloadPool.preloadPoolLoop(baseVastUrl);\n        }\n\n        await preloadedController.play();\n        this.timing.markAdStarted();\n\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n\n        const adVolume = currentMuted ? 0 : currentVolume;\n        preloadedController.setAdVolume(adVolume);\n      } else {\n        const adPlayer = this.host.getAdPlayer();\n        await this.timing.enforceGlobalRateLimit();\n        this.timing.lastAdRequestTime = Date.now();\n        await adPlayer.requestAds(firstAdUrl);\n        sendAdLoadedTracking(\n          this.host.config.licenseKey,\n          { source: \"hls\", vastUrl: firstAdUrl, timestamp: new Date().toISOString() },\n          this.analyticsContext\n        ).catch(() => {});\n\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] First ad request successful, starting playback\");\n        }\n\n        if (!this.timing.ensureLoadedAdFitsBudget(adPlayer)) {\n          this.timing.rejectLoadedAdForDuration(adPlayer);\n          this.recreateAdController();\n          this.startContinuousFetching(baseVastUrl);\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n\n        this.timing.consecutiveFailures = 0;\n        this.startContinuousFetching(baseVastUrl);\n\n        if (!this.preloadPool.active) {\n          this.preloadPool.startPreloadPool(baseVastUrl, []);\n        }\n\n        await adPlayer.play();\n        this.timing.markAdStarted();\n\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n\n        const adVolume = currentMuted ? 0 : currentVolume;\n        adPlayer.setAdVolume(adVolume);\n      }\n    } catch (error) {\n      if (this.debug) {\n        console.warn(\"[CONTINUOUS-FETCH] First ad request failed:\", error);\n      }\n\n      if (!usePreloadedAd) {\n        const fallbackPreloaded = this.preloadPool.getPreloadedAd();\n        if (fallbackPreloaded) {\n          if (this.debug) {\n            console.log(\"[CONTINUOUS-FETCH] First ad failed, using preloaded fallback\");\n          }\n\n          try {\n            if (!this.timing.ensureLoadedAdFitsBudget(fallbackPreloaded.adController)) {\n              this.timing.rejectLoadedAdForDuration(fallbackPreloaded.adController);\n              this.startContinuousFetching(baseVastUrl);\n              await this.tryNextAvailableAdWithRateLimit();\n              return;\n            }\n\n            this.swapToPreloadedAdPlayer(fallbackPreloaded.adController);\n\n            this.timing.consecutiveFailures = 0;\n            this.startContinuousFetching(baseVastUrl);\n\n            if (!this.preloadPool.active) {\n              this.preloadPool.active = true;\n              this.preloadPool.preloadPoolLoop(baseVastUrl);\n            }\n\n            const ap = this.host.getAdPlayer();\n            await ap.play();\n            this.timing.markAdStarted();\n\n            if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n              this.timing.scheduleAdStopAtBreakBoundary();\n            }\n\n            const adVolume = currentMuted ? 0 : currentVolume;\n            ap.setAdVolume(adVolume);\n\n            return;\n          } catch (fallbackError) {\n            if (this.debug) {\n              console.warn(\"[CONTINUOUS-FETCH] Preloaded fallback also failed:\", fallbackError);\n            }\n          }\n        }\n      }\n\n      if (this.timing.isTemporaryAdError(error as Error)) {\n        this.timing.temporaryFailureUrls.set(firstAdUrl, Date.now());\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] First ad had temporary error (no-fill) - will try alternatives\");\n        }\n      } else {\n        this.timing.failedVastUrls.add(firstAdUrl);\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] First ad had permanent error - URL blacklisted\");\n        }\n      }\n      this.timing.consecutiveFailures++;\n\n      this.startContinuousFetching(baseVastUrl);\n      await this.tryNextAvailableAdWithRateLimit();\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Optimized pod (single multi-ad request)\n  // ───────────────────────────────────────────────────────────────\n\n  private async startOptimizedPod(\n    baseVastUrl: string,\n    breakDurationMs: number | undefined,\n    currentMuted: boolean,\n    currentVolume: number\n  ): Promise<boolean> {\n    let podUrl: string | undefined;\n    if (this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0) {\n      podUrl = this.pendingAdBreak.vastUrls[0];\n      this.clearPendingAdBreak();\n    } else {\n      podUrl = this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);\n    }\n\n    if (!podUrl) {\n      return false;\n    }\n\n    this.continuousFetchingActive = false;\n\n    this.recreateAdController();\n\n    const adPlayer = this.host.getAdPlayer();\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      await adPlayer.requestAds(podUrl);\n      this.timing.clearAdRequestWatchdog();\n\n      if (this.timing.activeAdRequestToken !== requestToken) {\n        return true;\n      }\n\n      const podCount = adPlayer.getPodAdCount?.() ?? 1;\n      if (podCount < 1) {\n        return false;\n      }\n\n      if (this.debug) {\n        console.log(\n          podCount === 1\n            ? \"[POD] Response contained a single ad; playing it and enabling sequential top-up\"\n            : `[POD] Optimized pod returned ${podCount} ads; playing pod in one controller`\n        );\n      }\n\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: podUrl, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      this.timing.startAdFailsafeTimer(requestToken);\n      await adPlayer.play();\n      this.timing.markAdStarted();\n\n      if (\n        this.timing.expectedAdBreakDurationMs != null &&\n        this.timing.getAdBreakEndWallClockMs() == null\n      ) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n      }\n\n      adPlayer.setAdVolume(currentMuted ? 0 : currentVolume);\n      this.timing.consecutiveFailures = 0;\n\n      if (podCount === 1) {\n        this.continuousFetchingActive = true;\n        this.startContinuousFetching(baseVastUrl);\n        if (!this.preloadPool.active) {\n          this.preloadPool.startPreloadPool(baseVastUrl, []);\n        }\n      }\n\n      return true;\n    } catch (error) {\n      this.timing.clearAdRequestWatchdog();\n      this.timing.clearAdFailsafeTimer();\n      if (this.timing.activeAdRequestToken === requestToken) {\n        this.timing.activeAdRequestToken = null;\n      }\n      if (this.debug) {\n        console.warn(\"[POD] Optimized pod request/play failed:\", error);\n      }\n\n      if (this.timing.isTemporaryAdError(error as Error)) {\n        this.timing.temporaryFailureUrls.set(podUrl, Date.now());\n      }\n\n      this.continuousFetchingActive = true;\n      this.recreateAdController();\n      return false;\n    }\n  }\n\n  private swapToPreloadedAdPlayer(preloadedController: AdController): void {\n    const adPlayer = this.host.getAdPlayer();\n    const preservedMuted = adPlayer.getOriginalMutedState();\n    const preservedVolume = adPlayer.getOriginalVolume();\n    adPlayer.destroy();\n    this.host.video.muted = true;\n    this.host.setAdPlayer(preloadedController);\n    this.attachImaEventListeners();\n    preloadedController.updateOriginalMutedState(preservedMuted, preservedVolume);\n    preloadedController.resume();\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Continuous fetching\n  // ───────────────────────────────────────────────────────────────\n\n  private startContinuousFetching(baseVastUrl: string): void {\n    if (!this.continuousFetchingActive) {\n      return;\n    }\n\n    if (this.continuousFetchLoopRunning) {\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Fetch loop already running, skipping duplicate start\");\n      }\n      return;\n    }\n\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] Starting continuous ad fetching loop\");\n    }\n\n    this.continuousFetchLoopRunning = true;\n    this.continuousFetchLoop(baseVastUrl);\n  }\n\n  private async continuousFetchLoop(baseVastUrl: string): Promise<void> {\n    const epoch = this.timing.adBreakEpoch;\n    while (\n      this.continuousFetchingActive &&\n      this.inAdBreak &&\n      epoch === this.timing.adBreakEpoch\n    ) {\n      const remaining = Math.min(\n        this.timing.getWallClockRemainingAdMs(),\n        this.timing.getDurationBudgetRemainingMs()\n      );\n\n      if (remaining <= this.timing.getMinRemainingMsToStartAd()) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Not enough ad break time left (wall=${this.timing.getWallClockRemainingAdMs()}ms, budget=${this.timing.getDurationBudgetRemainingMs()}ms), stopping URL generation`);\n        }\n        break;\n      }\n\n      if (this.timing.isGamInCooldown()) {\n        if (this.debug) {\n          console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, stopping URL generation\");\n        }\n        break;\n      }\n\n      if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), stopping URL generation`);\n        }\n        break;\n      }\n\n      if (this.timing.totalAdRequestsInBreak >= this.timing.maxTotalAdRequestsPerBreak) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Maximum ad requests reached (${this.timing.maxTotalAdRequestsPerBreak}), stopping`);\n        }\n        break;\n      }\n\n      const maxQueueSize = 5;\n      if (this.adRequestQueue.length >= maxQueueSize) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] URL queue full (${this.adRequestQueue.length}), waiting...`);\n        }\n        await new Promise(resolve => setTimeout(resolve, 1000));\n        continue;\n      }\n\n      const newAdUrl = this.host.generateVastUrls(baseVastUrl, 1)[0];\n\n      if (!newAdUrl || this.timing.failedVastUrls.has(newAdUrl) || this.timing.isUrlInCooldown(newAdUrl)) {\n        await new Promise(resolve => setTimeout(resolve, 500));\n        continue;\n      }\n\n      if (this.debug) {\n        const queuedUrlsPreview = [...this.adRequestQueue, newAdUrl];\n        console.log(\n          `[CONTINUOUS-FETCH] Queued VAST URL (queue size: ${queuedUrlsPreview.length})`,\n          { queuedUrls: queuedUrlsPreview }\n        );\n      }\n\n      this.adRequestQueue.push(newAdUrl);\n\n      const generationDelay = this.timing.consecutiveFailures > 0\n        ? Math.min(1000 * Math.pow(2, this.timing.consecutiveFailures), 5000)\n        : 500;\n      await new Promise(resolve => setTimeout(resolve, generationDelay));\n    }\n\n    this.continuousFetchLoopRunning = false;\n\n    if (this.debug) {\n      console.log(\n        `[CONTINUOUS-FETCH] URL generation loop ended (queued: ${this.adRequestQueue.length})`,\n        this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n      );\n    }\n  }\n\n  stopContinuousFetching(): void {\n    this.continuousFetchingActive = false;\n    this.continuousFetchLoopRunning = false;\n\n    this.placeholder.hide();\n\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] Stopping continuous ad fetching\");\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Ad iteration\n  // ───────────────────────────────────────────────────────────────\n\n  async tryNextAvailableAdWithRateLimit(): Promise<void> {\n    if (!this.inAdBreak) {\n      return;\n    }\n\n    const epoch = this.timing.adBreakEpoch;\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), ending ad break gracefully`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    const backoffMultiplier = Math.pow(2, this.timing.consecutiveFailures);\n    const backoffDelay = Math.min(this.timing.backoffBaseMs * backoffMultiplier, this.timing.maxBackoffMs);\n    const effectiveMinInterval = this.timing.minAdRequestIntervalMs + (this.timing.consecutiveFailures > 0 ? backoffDelay : 0);\n\n    const timeSinceLastRequest = Date.now() - this.timing.lastAdRequestTime;\n    if (timeSinceLastRequest < effectiveMinInterval) {\n      const waitTime = effectiveMinInterval - timeSinceLastRequest;\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Rate limiting: waiting ${waitTime}ms before next request (backoff: ${this.timing.consecutiveFailures} failures)`);\n      }\n      await new Promise(resolve => setTimeout(resolve, waitTime));\n    }\n\n    if (!this.inAdBreak || epoch !== this.timing.adBreakEpoch) {\n      return;\n    }\n\n    return this.tryNextAvailableAd(0);\n  }\n\n  private async tryNextAvailableAd(retryCount: number = 0): Promise<void> {\n    if (!this.inAdBreak) {\n      return;\n    }\n\n    const remaining = this.timing.getRemainingAdMs();\n\n    if (!this.timing.hasTimeToStartAnotherAd()) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Not enough time remaining (${remaining}ms) to start another ad, ending ad break`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) {\n        console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, ending ad break gracefully\");\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), ending ad break`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    this.timing.cleanupTemporaryFailures();\n\n    const preloaded = this.preloadPool.getPreloadedAd();\n    if (preloaded) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Using preloaded ad from pool`);\n      }\n\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: preloaded.vastUrl, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      try {\n        if (!this.timing.ensureLoadedAdFitsBudget(preloaded.adController)) {\n          this.timing.rejectLoadedAdForDuration(preloaded.adController);\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n\n        this.swapToPreloadedAdPlayer(preloaded.adController);\n\n        const ap = this.host.getAdPlayer();\n        await ap.play();\n        this.timing.markAdStarted();\n\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n\n        ap.setAdVolume(getAdAudioVolume(ap));\n\n        this.timing.consecutiveFailures = 0;\n        return;\n      } catch (error) {\n        if (this.debug) {\n          console.warn(\"[CONTINUOUS-FETCH] Preloaded ad failed to play:\", error);\n        }\n      }\n    }\n\n    while (this.adRequestQueue.length > 0) {\n      const nextAdUrl = this.adRequestQueue.shift();\n\n      if (!nextAdUrl) continue;\n\n      if (this.timing.failedVastUrls.has(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping permanently-failed URL, trying next...\");\n        continue;\n      }\n\n      if (this.timing.isUrlInCooldown(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping URL in cooldown (recent no-fill), trying next...\");\n        continue;\n      }\n\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Requesting next ad via HLS ad player (${this.timing.currentAdIndex + 1}, ${this.adRequestQueue.length} remaining in queue)`);\n      }\n\n      try {\n        await this.playSingleAd(nextAdUrl);\n        this.timing.consecutiveFailures = 0;\n      } catch (error) {\n        const errorMessage = (error as Error).message;\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Ad request failed:\", errorMessage);\n\n        if (errorMessage.includes(\"ad_duration_exceeds_budget\")) {\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n\n        if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n          this.timing.consecutiveFailures++;\n        }\n\n        await this.tryNextAvailableAdWithRateLimit();\n      }\n      return;\n    }\n\n    const maxRetries = 3;\n    if (this.continuousFetchingActive && retryCount < maxRetries && remaining > 2000) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Queue empty, waiting for URLs... (${retryCount + 1}/${maxRetries})`);\n      }\n      await new Promise(resolve => setTimeout(resolve, 500));\n      await this.tryNextAvailableAd(retryCount + 1);\n      return;\n    }\n\n    if (!this.isShowingPlaceholder && remaining > 1000) {\n      this.showPlaceholderAndWaitForAds();\n    } else {\n      if (this.debug) console.log(\"[CONTINUOUS-FETCH] No more ads available, ending ad break\");\n      this.handleAdPodComplete();\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Single ad playback\n  // ───────────────────────────────────────────────────────────────\n\n  async playSingleAd(vastTagUrl: string): Promise<void> {\n    const adPlayer = this.host.getAdPlayer();\n    if (adPlayer.isAdPlaying()) return;\n\n    if (this.timing.failedVastUrls.has(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping permanently-failed VAST URL:\", vastTagUrl);\n      throw new Error(\"VAST URL permanently failed\");\n    }\n\n    if (this.timing.isUrlInCooldown(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping URL in cooldown (recent no-fill):\", vastTagUrl);\n      throw new Error(\"VAST URL in cooldown after no-fill\");\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.warn(\"[AD-ERROR] Too many consecutive failures, not requesting more ads\");\n      throw new Error(\"Too many consecutive failures\");\n    }\n\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) console.warn(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping ad request\");\n      throw new Error(\"GAM in cooldown\");\n    }\n\n    this.recreateAdController();\n\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      const ap = this.host.getAdPlayer();\n      await ap.requestAds(vastTagUrl);\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: vastTagUrl, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      this.timing.clearAdRequestWatchdog();\n\n      if (this.timing.activeAdRequestToken !== requestToken) return;\n\n      if (!this.timing.ensureLoadedAdFitsBudget(ap)) {\n        this.timing.rejectLoadedAdForDuration(ap);\n        this.recreateAdController();\n        throw new Error(\"ad_duration_exceeds_budget\");\n      }\n\n      try {\n        this.timing.startAdFailsafeTimer(requestToken);\n        await ap.play();\n        this.timing.markAdStarted();\n\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n\n        ap.setAdVolume(getAdAudioVolume(ap));\n        this.timing.consecutiveFailures = 0;\n        this.timing.temporaryFailureUrls.delete(vastTagUrl);\n      } catch (playError) {\n        if (this.debug) console.error(\"[AD-ERROR] Failed to play ad:\", playError);\n\n        const preloadedFallback = this.preloadPool.getPreloadedAd();\n        if (preloadedFallback) {\n          if (this.debug) console.log(\"[AD-ERROR] Play failed, trying preloaded fallback ad\");\n          try {\n            if (!this.timing.ensureLoadedAdFitsBudget(preloadedFallback.adController)) {\n              this.timing.rejectLoadedAdForDuration(preloadedFallback.adController);\n              throw playError;\n            }\n            this.timing.clearAdFailsafeTimer();\n            this.swapToPreloadedAdPlayer(preloadedFallback.adController);\n            this.timing.consecutiveFailures = 0;\n            const fbAp = this.host.getAdPlayer();\n            await fbAp.play();\n            this.timing.markAdStarted();\n            if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n              this.timing.scheduleAdStopAtBreakBoundary();\n            }\n            fbAp.setAdVolume(getAdAudioVolume(fbAp));\n            return;\n          } catch (fallbackError) {\n            if (this.debug) console.warn(\"[AD-ERROR] Preloaded fallback also failed:\", fallbackError);\n          }\n        }\n\n        if (this.timing.isTemporaryAdError(playError as Error)) {\n          this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());\n          if (this.debug) console.log(\"[AD-ERROR] Temporary play error - URL can be retried after cooldown\");\n        } else {\n          this.timing.failedVastUrls.add(vastTagUrl);\n          if (this.debug) console.log(\"[AD-ERROR] Permanent play error - URL blacklisted\");\n        }\n\n        this.timing.clearAdFailsafeTimer();\n        if (this.timing.activeAdRequestToken === requestToken) {\n          this.timing.activeAdRequestToken = null;\n        }\n        throw playError;\n      }\n    } catch (error) {\n      const errorMessage = (error as Error)?.message || \"\";\n      if (this.debug) console.error(\"[AD-ERROR] Ad request failed:\", errorMessage);\n\n      const preloadedFallback = this.preloadPool.getPreloadedAd();\n      if (preloadedFallback) {\n        if (this.debug) console.log(\"[AD-ERROR] Request failed, trying preloaded fallback ad\");\n        try {\n          if (!this.timing.ensureLoadedAdFitsBudget(preloadedFallback.adController)) {\n            this.timing.rejectLoadedAdForDuration(preloadedFallback.adController);\n            throw error;\n          }\n          this.timing.clearAdRequestWatchdog();\n          this.timing.clearAdFailsafeTimer();\n          this.swapToPreloadedAdPlayer(preloadedFallback.adController);\n          this.timing.consecutiveFailures = 0;\n          const fbAp = this.host.getAdPlayer();\n          await fbAp.play();\n          this.timing.markAdStarted();\n          fbAp.setAdVolume(getAdAudioVolume(fbAp));\n          return;\n        } catch (fallbackError) {\n          if (this.debug) console.warn(\"[AD-ERROR] Preloaded fallback also failed:\", fallbackError);\n        }\n      }\n\n      if (this.timing.isTemporaryAdError(error as Error)) {\n        this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());\n        if (this.debug) console.log(\"[AD-ERROR] Temporary error (no-fill/timeout) - URL can be retried after cooldown\");\n      } else {\n        this.timing.failedVastUrls.add(vastTagUrl);\n        if (this.debug) console.log(\"[AD-ERROR] Permanent error - URL blacklisted:\", errorMessage);\n      }\n\n      this.timing.clearAdRequestWatchdog();\n      this.timing.clearAdFailsafeTimer();\n      if (this.timing.activeAdRequestToken === requestToken) {\n        this.timing.activeAdRequestToken = null;\n      }\n      throw error;\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Placeholder wait\n  // ───────────────────────────────────────────────────────────────\n\n  private async showPlaceholderAndWaitForAds(): Promise<void> {\n    const remaining = this.timing.getRemainingAdMs();\n    const waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);\n\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping placeholder wait\");\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping placeholder - too many consecutive failures\");\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (waitTime < 1000) {\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.debug) {\n      console.log(`[CONTINUOUS-FETCH] Showing placeholder for ${waitTime}ms while waiting for ad URLs`);\n    }\n\n    this.isShowingPlaceholder = true;\n    this.host.getAdPlayer().showPlaceholder();\n\n    const checkInterval = 300;\n    const maxChecks = Math.floor(waitTime / checkInterval);\n\n    for (let i = 0; i < maxChecks; i++) {\n      await new Promise(resolve => setTimeout(resolve, checkInterval));\n\n      if (!this.inAdBreak) return;\n\n      if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Too many failures during placeholder wait\");\n        break;\n      }\n\n      if (!this.timing.hasTimeToStartAnotherAd()) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Not enough time remaining during placeholder wait, ending ad break\");\n        break;\n      }\n\n      while (this.adRequestQueue.length > 0) {\n        if (!this.timing.hasTimeToStartAnotherAd()) break;\n\n        const nextAdUrl = this.adRequestQueue.shift();\n        if (!nextAdUrl) continue;\n        if (this.timing.failedVastUrls.has(nextAdUrl)) continue;\n        if (this.timing.isUrlInCooldown(nextAdUrl)) continue;\n\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Ad URL available, requesting via HLS ad player\");\n\n        this.isShowingPlaceholder = false;\n        this.host.getAdPlayer().hidePlaceholder();\n\n        try {\n          await this.playSingleAd(nextAdUrl);\n          this.timing.consecutiveFailures = 0;\n        } catch (error) {\n          const errorMessage = (error as Error).message;\n          if (errorMessage.includes(\"ad_duration_exceeds_budget\")) {\n            await this.tryNextAvailableAdWithRateLimit();\n            return;\n          }\n          if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n            this.timing.consecutiveFailures++;\n          }\n          await this.tryNextAvailableAdWithRateLimit();\n        }\n        return;\n      }\n    }\n\n    if (this.debug) console.log(\"[CONTINUOUS-FETCH] Placeholder timeout, ending ad break\");\n\n    this.isShowingPlaceholder = false;\n    this.host.getAdPlayer().hidePlaceholder();\n    this.handleAdPodComplete();\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Ad break completion\n  // ───────────────────────────────────────────────────────────────\n\n  handleAdPodComplete(): void {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Ad pod complete - cleaning up\");\n    }\n\n    this.timing.resetForBreakEnd();\n\n    this.stopContinuousFetching();\n    this.preloadPool.stop();\n    this.clearPendingAdBreak();\n\n    if (this.isShowingPlaceholder) {\n      this.host.getAdPlayer().hidePlaceholder();\n      this.isShowingPlaceholder = false;\n    }\n\n    this.adRequestQueue = [];\n\n    this.inAdBreak = false;\n    this.adDetectSentForCurrentBreak = false;\n    this.cueManager.activeScte35BreakKey = undefined;\n    this.cueManager.scheduledScte35BreakKey = undefined;\n    this.adPodQueue = [];\n    this.showAds = false;\n\n    this.host.getAdPlayer().stop().catch(() => {});\n\n    const restoredMuted = this.host.getAdPlayer().getOriginalMutedState();\n    const restoredVolume = this.host.getAdPlayer().getOriginalVolume();\n\n    if (this.host.video.muted !== restoredMuted) {\n      this.host.video.muted = restoredMuted;\n    }\n    if (Math.abs(this.host.video.volume - restoredVolume) > 0.01) {\n      this.host.video.volume = restoredVolume;\n    }\n\n    if (this.host.shouldContinueLiveStreamDuringAds()) {\n      const liveSyncPos = this.host.getLiveSyncPosition();\n      if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {\n        if (this.debug) {\n          console.log(\n            `[StormcloudVideoPlayer] Live break end — snapping to live edge: ${this.host.video.currentTime.toFixed(2)}s → ${liveSyncPos.toFixed(2)}s`\n          );\n        }\n        this.host.video.currentTime = liveSyncPos;\n      }\n\n      if (this.host.video.paused) {\n        if (this.debug) console.log(\"[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback\");\n        this.host.video.play()?.catch(() => {});\n      } else {\n        if (this.debug) console.log(\"[StormcloudVideoPlayer] Content video already playing in live mode after ads\");\n      }\n    } else if (this.host.video.paused) {\n      this.host.video.play()?.catch(() => {});\n    }\n  }\n\n  handleAdFailure(): void {\n    this.timing.consecutiveFailures++;\n    this.timing.recordGamNoFill();\n    const remaining = this.timing.getRemainingAdMs();\n\n    if (this.debug) {\n      console.log(\n        `[CONTINUOUS-FETCH] Ad failure: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}, consecutiveFailures=${this.timing.consecutiveFailures}`,\n        this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n      );\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.log(`[CONTINUOUS-FETCH] Max consecutive failures reached (${this.timing.consecutiveFailures}), ending ad break gracefully`);\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.hasTimeToStartAnotherAd()) {\n      this.tryNextAvailableAdWithRateLimit();\n    } else {\n      if (this.debug) console.log(\"[AD-ERROR] Ad failed and not enough time remaining for another ad. Failed URLs:\", this.timing.failedVastUrls.size);\n      this.handleAdPodComplete();\n    }\n  }\n}\n","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 React, { Component, Suspense } from \"react\";\nimport type { BaseStormcloudPlayerProps } from \"./props\";\nimport { defaultProps } from \"./props\";\nimport { omit } from \"./utils\";\nimport players from \"./players\";\nimport type { PlayerConfig } from \"./players\";\nimport Player from \"./Player.js\";\n\nconst IS_BROWSER = typeof window !== \"undefined\" && window.document;\nconst IS_GLOBAL =\n  typeof globalThis !== \"undefined\" &&\n  globalThis.window &&\n  globalThis.window.document;\nconst UniversalSuspense = IS_BROWSER || IS_GLOBAL ? Suspense : () => null;\n\nconst SUPPORTED_PROPS = [\n  \"src\",\n  \"playing\",\n  \"loop\",\n  \"controls\",\n  \"volume\",\n  \"muted\",\n  \"playbackRate\",\n  \"width\",\n  \"height\",\n  \"style\",\n  \"progressInterval\",\n  \"playsInline\",\n  \"autoplay\",\n  \"preload\",\n  \"poster\",\n  \"className\",\n  \"wrapperClassName\",\n  \"wrapperStyle\",\n  \"allowNativeHls\",\n  \"lowLatencyMode\",\n  \"isLiveStream\",\n  \"driftToleranceMs\",\n  \"immediateManifestAds\",\n  \"debugAdTiming\",\n  \"showCustomControls\",\n  \"licenseKey\",\n  \"isVmap\",\n  \"vmapUrl\",\n  \"adFailsafeTimeoutMs\",\n  \"minSegmentsBeforePlay\",\n  \"ctvAdRequest\",\n  \"onReady\",\n  \"onStart\",\n  \"onPlay\",\n  \"onPause\",\n  \"onBuffer\",\n  \"onBufferEnd\",\n  \"onEnded\",\n  \"onError\",\n  \"onDuration\",\n  \"onSeek\",\n  \"onProgress\",\n  \"onVolumeToggle\",\n  \"onFullscreenToggle\",\n  \"onControlClick\",\n];\n\nexport interface StormcloudPlayerProps extends BaseStormcloudPlayerProps {\n  fallback?: React.ReactElement;\n  wrapper?: React.ComponentType<{ children: React.ReactNode }> | string;\n}\n\ninterface StormcloudPlayerState {\n  showPreview: boolean;\n}\n\nconst customPlayers: PlayerConfig[] = [];\n\nexport const createStormcloudPlayer = (\n  playerList: PlayerConfig[],\n  fallback?: PlayerConfig\n) => {\n  return class StormcloudPlayerClass extends Component<\n    StormcloudPlayerProps,\n    StormcloudPlayerState\n  > {\n    static displayName = \"StormcloudPlayer\";\n\n    static defaultProps = {\n      ...defaultProps,\n      fallback: null,\n      wrapper: \"div\",\n    };\n\n    static addCustomPlayer = (player: PlayerConfig) => {\n      customPlayers.push(player);\n    };\n\n    static removeCustomPlayers = () => {\n      customPlayers.length = 0;\n    };\n\n    static canPlay = (src: string): boolean => {\n      for (const Player of [...customPlayers, ...playerList]) {\n        if (Player.canPlay(src)) {\n          return true;\n        }\n      }\n      return false;\n    };\n\n    static canEnablePIP = (src: string): boolean => {\n      for (const Player of [...customPlayers, ...playerList]) {\n        if (Player.canEnablePIP && Player.canEnablePIP(src)) {\n          return true;\n        }\n      }\n      return false;\n    };\n\n    state: StormcloudPlayerState = {\n      showPreview: false,\n    };\n\n    public wrapper?: HTMLElement;\n    public player?: any;\n\n    references = {\n      wrapper: (wrapper: HTMLElement) => {\n        this.wrapper = wrapper;\n      },\n      player: (player: any) => {\n        this.player = player;\n      },\n    };\n\n    getActivePlayer = (src?: string): PlayerConfig | null => {\n      if (!src) return null;\n\n      for (const player of [...customPlayers, ...playerList]) {\n        if (player.canPlay(src)) {\n          return player;\n        }\n      }\n\n      if (fallback) {\n        return fallback;\n      }\n\n      return null;\n    };\n\n    getAttributes = (src?: string) => {\n      return omit(this.props, SUPPORTED_PROPS as any);\n    };\n\n    handleReady = () => {\n      this.props.onReady?.(this as any);\n    };\n\n    seekTo = (\n      fraction: number,\n      type?: \"seconds\" | \"fraction\",\n      keepPlaying?: boolean\n    ) => {\n      if (!this.player) return null;\n      this.player.seekTo(fraction, type, keepPlaying);\n    };\n\n    getCurrentTime = (): number | null => {\n      if (!this.player) return null;\n      return this.player.getCurrentTime();\n    };\n\n    getSecondsLoaded = (): number | null => {\n      if (!this.player) return null;\n      return this.player.getSecondsLoaded();\n    };\n\n    getDuration = (): number | null => {\n      if (!this.player) return null;\n      return this.player.getDuration();\n    };\n\n    getInternalPlayer = (key = \"player\") => {\n      if (!this.player) return null;\n      return this.player.getInternalPlayer(key);\n    };\n\n    renderActivePlayer = (src?: string) => {\n      if (!src) return null;\n\n      const activePlayer = this.getActivePlayer(src);\n      if (!activePlayer) return null;\n\n      return React.createElement(Player, {\n        ...this.props,\n        key: activePlayer.key,\n        ref: this.references.player,\n        activePlayer: activePlayer.lazyPlayer || activePlayer,\n        onReady: this.handleReady,\n      });\n    };\n\n    render() {\n      const {\n        src,\n        style,\n        width,\n        height,\n        fallback: fallbackElement,\n        wrapper: Wrapper,\n      } = this.props;\n      const attributes = this.getAttributes(src);\n      const wrapperRef =\n        typeof Wrapper === \"string\" ? this.references.wrapper : undefined;\n\n      return React.createElement(\n        Wrapper as any,\n        {\n          ref: wrapperRef,\n          style: { ...style, width, height },\n          ...attributes,\n        },\n        React.createElement(\n          UniversalSuspense,\n          { fallback: fallbackElement },\n          this.renderActivePlayer(src)\n        )\n      );\n    }\n  };\n};\n\nconst StormcloudPlayer = createStormcloudPlayer(\n  players,\n  players[players.length - 1]\n);\n\nexport default StormcloudPlayer;\n","import type { CSSProperties } from \"react\";\nimport { StormcloudVideoPlayer } from \"./player/StormcloudVideoPlayer\";\n\nexport interface OnProgressProps {\n  played: number;\n  playedSeconds: number;\n  loaded: number;\n  loadedSeconds: number;\n}\n\nexport interface BaseStormcloudPlayerProps {\n  src?: string;\n  playing?: boolean;\n  loop?: boolean;\n  controls?: boolean;\n  volume?: number;\n  muted?: boolean;\n  playbackRate?: number;\n  width?: string | number;\n  height?: string | number;\n  style?: CSSProperties;\n  progressInterval?: number;\n  playsInline?: boolean;\n  autoplay?: boolean;\n  preload?: string;\n  poster?: string;\n  className?: string;\n  wrapperClassName?: string;\n  wrapperStyle?: CSSProperties;\n\n  allowNativeHls?: boolean;\n  lowLatencyMode?: boolean;\n  isLiveStream?: boolean;\n  driftToleranceMs?: number;\n  immediateManifestAds?: boolean;\n  debugAdTiming?: boolean;\n  showCustomControls?: boolean;\n  hideLoadingIndicator?: boolean;\n  licenseKey?: string;\n  isVmap?: boolean;\n  vmapUrl?: string;\n  adFailsafeTimeoutMs?: number;\n  minSegmentsBeforePlay?: number;\n  ctvAdRequest?: boolean;\n\n  onReady?: (player: StormcloudVideoPlayer) => void;\n  onStart?: () => void;\n  onPlay?: () => void;\n  onPause?: (e?: any) => void;\n  onBuffer?: () => void;\n  onBufferEnd?: () => void;\n  onEnded?: () => void;\n  onError?: (\n    error: any,\n    data?: any,\n    hlsInstance?: any,\n    hlsGlobal?: any\n  ) => void;\n  onDuration?: (duration: number) => void;\n  onSeek?: (seconds: number) => void;\n  onProgress?: (state: OnProgressProps) => void;\n  onVolumeToggle?: () => void;\n  onFullscreenToggle?: () => void;\n  onControlClick?: () => void;\n\n  [otherProps: string]: any;\n}\n\nconst noop = () => {};\n\nexport const defaultProps: Required<\n  Omit<\n    BaseStormcloudPlayerProps,\n    | \"src\"\n    | \"onReady\"\n    | \"children\"\n    | \"ctvAdRequest\"\n    | keyof React.VideoHTMLAttributes<HTMLVideoElement>\n  >\n> = {\n  playing: false,\n  loop: false,\n  controls: true,\n  volume: 1,\n  muted: false,\n  playbackRate: 1,\n  width: \"100%\",\n  height: \"auto\",\n  style: {},\n  progressInterval: 1000,\n  playsInline: false,\n  autoplay: false,\n  preload: \"metadata\",\n  poster: \"\",\n  className: \"\",\n  wrapperClassName: \"\",\n  wrapperStyle: {},\n\n  allowNativeHls: false,\n  lowLatencyMode: false,\n  driftToleranceMs: 1000,\n  immediateManifestAds: true,\n  debugAdTiming: false,\n  showCustomControls: false,\n  hideLoadingIndicator: false,\n  licenseKey: \"\",\n  isVmap: false,\n  vmapUrl: \"\",\n  adFailsafeTimeoutMs: 10000,\n  minSegmentsBeforePlay: 2,\n\n  onStart: noop,\n  onPlay: noop,\n  onPause: noop,\n  onBuffer: noop,\n  onBufferEnd: noop,\n  onEnded: noop,\n  onError: noop,\n  onDuration: noop,\n  onSeek: noop,\n  onProgress: noop,\n  onVolumeToggle: noop,\n  onFullscreenToggle: noop,\n  onControlClick: noop,\n};\n","import { lazy as reactLazy } from \"react\";\n\nexport const lazy = reactLazy;\n\nexport const omit = <T extends Record<string, any>, K extends keyof T>(\n  object: T,\n  keys: K[]\n): Omit<T, K> => {\n  const result = { ...object };\n  keys.forEach((key) => {\n    delete result[key];\n  });\n  return result;\n};\n\nexport const isMediaStream = (url: any): url is MediaStream => {\n  return (\n    typeof window !== \"undefined\" &&\n    window.MediaStream &&\n    url instanceof window.MediaStream\n  );\n};\n\nexport const supportsWebKitPresentationMode = (): boolean => {\n  if (typeof window === \"undefined\") return false;\n  const video = document.createElement(\"video\");\n  return \"webkitSupportsPresentationMode\" in video;\n};\n\nexport const randomString = (): string => {\n  return Math.random().toString(36).substr(2, 9);\n};\n\nexport const parseQuery = (url: string): Record<string, string> => {\n  const query: Record<string, string> = {};\n  const queryString = url.split(\"?\")[1] || \"\";\n\n  if (!queryString) return query;\n\n  const manualParse = (qs: string) => {\n    qs.split(\"&\").forEach((param) => {\n      const [key, value] = param.split(\"=\");\n      if (key) {\n        try {\n          query[decodeURIComponent(key)] = value\n            ? decodeURIComponent(value.replace(/\\+/g, \" \"))\n            : \"\";\n        } catch (e) {\n          query[key] = value || \"\";\n        }\n      }\n    });\n  };\n\n  if (typeof URLSearchParams !== \"undefined\") {\n    try {\n      const params = new URLSearchParams(queryString);\n      params.forEach((value, key) => {\n        query[key] = value;\n      });\n      return query;\n    } catch (e) {\n      manualParse(queryString);\n    }\n  } else {\n    manualParse(queryString);\n  }\n\n  return query;\n};\n\nexport const merge = <T extends Record<string, any>>(\n  target: T,\n  ...sources: Partial<T>[]\n): T => {\n  if (!sources.length) return target;\n  const source = sources.shift();\n\n  if (isObject(target) && isObject(source)) {\n    for (const key in source) {\n      if (isObject(source[key])) {\n        if (!target[key]) Object.assign(target, { [key]: {} });\n        merge(target[key] as any, source[key] as any);\n      } else {\n        Object.assign(target, { [key]: source[key] });\n      }\n    }\n  }\n\n  return merge(target, ...sources);\n};\n\nconst isObject = (item: any): item is Record<string, any> => {\n  return item && typeof item === \"object\" && !Array.isArray(item);\n};\n\nexport const IS_BROWSER = typeof window !== \"undefined\" && window.document;\nexport const IS_GLOBAL =\n  typeof globalThis !== \"undefined\" &&\n  globalThis.window &&\n  globalThis.window.document;\nexport const IS_IOS =\n  IS_BROWSER && /iPad|iPhone|iPod/.test(navigator.userAgent);\nexport const IS_SAFARI =\n  IS_BROWSER && /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n\nexport const SUPPORTS_HLS = (): boolean => {\n  if (!IS_BROWSER) return false;\n  const video = document.createElement(\"video\");\n  return Boolean(video.canPlayType(\"application/vnd.apple.mpegurl\"));\n};\n\nexport const SUPPORTS_DASH = (): boolean => {\n  if (!IS_BROWSER) return false;\n  const video = document.createElement(\"video\");\n  return Boolean(video.canPlayType(\"application/dash+xml\"));\n};\n","export const HLS_EXTENSIONS = /\\.(m3u8)($|\\?)/i;\nexport const HLS_PATHS = /\\/hls\\//i;\nexport const DASH_EXTENSIONS = /\\.(mpd)($|\\?)/i;\nexport const VIDEO_EXTENSIONS = /\\.(mp4|webm|ogg|avi|mov|wmv|flv|mkv)($|\\?)/i;\nexport const AUDIO_EXTENSIONS = /\\.(mp3|wav|ogg|aac|wma|flac|m4a)($|\\?)/i;\n\nexport const canPlay = {\n  hls: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return HLS_EXTENSIONS.test(url) || HLS_PATHS.test(url);\n  },\n\n  dash: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return DASH_EXTENSIONS.test(url);\n  },\n\n  video: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return VIDEO_EXTENSIONS.test(url);\n  },\n\n  audio: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return AUDIO_EXTENSIONS.test(url);\n  },\n\n  file: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return VIDEO_EXTENSIONS.test(url) || AUDIO_EXTENSIONS.test(url);\n  },\n};\n","import { Component } from \"react\";\nimport { StormcloudVideoPlayer } from \"../player/StormcloudVideoPlayer\";\nimport type { StormcloudVideoPlayerConfig } from \"../types\";\nimport { canPlay } from \"../patterns\";\n\nexport interface HlsPlayerProps extends StormcloudVideoPlayerConfig {\n  onMount?: (player: any) => void;\n  onReady?: () => void;\n  onPlay?: () => void;\n  onPause?: () => void;\n  onEnded?: () => void;\n  onLoaded?: () => void;\n  onError?: (error: any) => void;\n}\n\nexport default class HlsPlayer extends Component<HlsPlayerProps> {\n  static displayName = \"HlsPlayer\";\n\n  static canPlay = canPlay.hls;\n\n  private player: StormcloudVideoPlayer | null = null;\n  private mounted = false;\n\n  componentDidMount() {\n    this.mounted = true;\n    this.load();\n  }\n\n  componentWillUnmount() {\n    this.mounted = false;\n    if (this.player) {\n      this.player.destroy();\n      this.player = null;\n    }\n  }\n\n  componentDidUpdate(prevProps: HlsPlayerProps) {\n    if (prevProps.src !== this.props.src) {\n      this.load();\n    }\n  }\n\n  load = async () => {\n    if (!this.props.videoElement || !this.props.src) return;\n\n    try {\n      if (this.player) {\n        this.player.destroy();\n        this.player = null;\n      }\n\n      const config: StormcloudVideoPlayerConfig = {\n        src: this.props.src,\n        videoElement: this.props.videoElement,\n      };\n\n      if (this.props.autoplay !== undefined)\n        config.autoplay = this.props.autoplay;\n      if (this.props.muted !== undefined) config.muted = this.props.muted;\n      if (this.props.lowLatencyMode !== undefined)\n        config.lowLatencyMode = this.props.lowLatencyMode;\n      if (this.props.allowNativeHls !== undefined)\n        config.allowNativeHls = this.props.allowNativeHls;\n      if (this.props.isLiveStream !== undefined)\n        config.isLiveStream = this.props.isLiveStream;\n      if (this.props.driftToleranceMs !== undefined)\n        config.driftToleranceMs = this.props.driftToleranceMs;\n      if (this.props.immediateManifestAds !== undefined)\n        config.immediateManifestAds = this.props.immediateManifestAds;\n      if (this.props.debugAdTiming !== undefined)\n        config.debugAdTiming = this.props.debugAdTiming;\n      if (this.props.showCustomControls !== undefined)\n        config.showCustomControls = this.props.showCustomControls;\n      if (this.props.onVolumeToggle !== undefined)\n        config.onVolumeToggle = this.props.onVolumeToggle;\n      if (this.props.onFullscreenToggle !== undefined)\n        config.onFullscreenToggle = this.props.onFullscreenToggle;\n      if (this.props.onControlClick !== undefined)\n        config.onControlClick = this.props.onControlClick;\n      if (this.props.licenseKey !== undefined)\n        config.licenseKey = this.props.licenseKey;\n      if (this.props.adFailsafeTimeoutMs !== undefined)\n        config.adFailsafeTimeoutMs = this.props.adFailsafeTimeoutMs;\n      if (this.props.minSegmentsBeforePlay !== undefined)\n        config.minSegmentsBeforePlay = this.props.minSegmentsBeforePlay;\n      if (this.props.ctvAdRequest !== undefined)\n        config.ctvAdRequest = this.props.ctvAdRequest;\n\n      this.player = new StormcloudVideoPlayer(config);\n\n      this.props.onMount?.(this);\n\n      await this.player.load();\n\n      if (this.mounted) {\n        this.props.onReady?.();\n      }\n    } catch (error) {\n      if (this.mounted) {\n        this.props.onError?.(error);\n      }\n    }\n  };\n\n  play = () => {\n    if (this.props.videoElement) {\n      const video = this.props.videoElement;\n      const hasValidSource =\n        video.src ||\n        (video.currentSrc && video.currentSrc !== \"\") ||\n        video.readyState >= 1;\n\n      if (hasValidSource) {\n        video.play()?.catch((error) => {\n          console.error(\"[HlsPlayer] Failed to play:\", error);\n          this.props.onError?.(error);\n        });\n        this.props.onPlay?.();\n      } else {\n        console.warn(\"[HlsPlayer] Cannot play: video has no valid source\");\n      }\n    }\n  };\n\n  pause = () => {\n    if (this.props.videoElement) {\n      this.props.videoElement.pause();\n      this.props.onPause?.();\n    }\n  };\n\n  stop = () => {\n    this.pause();\n    if (this.props.videoElement) {\n      this.props.videoElement.currentTime = 0;\n    }\n  };\n\n  seekTo = (seconds: number, keepPlaying?: boolean) => {\n    if (this.props.videoElement) {\n      this.props.videoElement.currentTime = seconds;\n      if (!keepPlaying) {\n        this.pause();\n      }\n    }\n  };\n\n  setVolume = (volume: number) => {\n    if (this.props.videoElement) {\n      this.props.videoElement.volume = Math.max(0, Math.min(1, volume));\n    }\n  };\n\n  mute = () => {\n    if (this.props.videoElement) {\n      this.props.videoElement.muted = true;\n    }\n  };\n\n  unmute = () => {\n    if (this.props.videoElement) {\n      this.props.videoElement.muted = false;\n    }\n  };\n\n  setPlaybackRate = (rate: number) => {\n    if (this.props.videoElement && rate > 0) {\n      this.props.videoElement.playbackRate = rate;\n    }\n  };\n\n  getDuration = (): number | null => {\n    if (this.props.videoElement && isFinite(this.props.videoElement.duration)) {\n      return this.props.videoElement.duration;\n    }\n    return null;\n  };\n\n  getCurrentTime = (): number | null => {\n    if (\n      this.props.videoElement &&\n      isFinite(this.props.videoElement.currentTime)\n    ) {\n      return this.props.videoElement.currentTime;\n    }\n    return null;\n  };\n\n  getSecondsLoaded = (): number | null => {\n    if (\n      this.props.videoElement &&\n      this.props.videoElement.buffered.length > 0\n    ) {\n      return this.props.videoElement.buffered.end(\n        this.props.videoElement.buffered.length - 1\n      );\n    }\n    return null;\n  };\n\n  getInternalPlayer = (key = \"player\") => {\n    if (key === \"player\") return this.player;\n    if (key === \"video\") return this.props.videoElement;\n    if (key === \"hls\" && this.player) return (this.player as any).hls;\n    return null;\n  };\n\n  render() {\n    return null;\n  }\n}\n","import { Component } from \"react\";\nimport { canPlay } from \"../patterns\";\n\nexport interface FilePlayerProps {\n  src: string;\n  videoElement?: HTMLVideoElement;\n  onMount?: (player: any) => void;\n  onReady?: () => void;\n  onPlay?: () => void;\n  onPause?: () => void;\n  onEnded?: () => void;\n  onLoaded?: () => void;\n  onError?: (error: any) => void;\n  autoplay?: boolean;\n  muted?: boolean;\n  loop?: boolean;\n  controls?: boolean;\n  playsInline?: boolean;\n  preload?: string;\n  poster?: string;\n}\n\nexport default class FilePlayer extends Component<FilePlayerProps> {\n  static displayName = \"FilePlayer\";\n\n  static canPlay = canPlay.file;\n\n  private mounted = false;\n  private ready = false;\n\n  componentDidMount() {\n    this.mounted = true;\n    this.load();\n  }\n\n  componentWillUnmount() {\n    this.mounted = false;\n  }\n\n  componentDidUpdate(prevProps: FilePlayerProps) {\n    if (prevProps.src !== this.props.src) {\n      this.load();\n    }\n  }\n\n  load = () => {\n    if (!this.props.videoElement || !this.props.src) return;\n\n    const video = this.props.videoElement;\n\n    const handleLoadedMetadata = () => {\n      if (this.mounted && !this.ready) {\n        this.ready = true;\n        this.props.onReady?.();\n      }\n    };\n\n    const handlePlay = () => {\n      if (this.mounted) {\n        this.props.onPlay?.();\n      }\n    };\n\n    const handlePause = () => {\n      if (this.mounted) {\n        this.props.onPause?.();\n      }\n    };\n\n    const handleEnded = () => {\n      if (this.mounted) {\n        this.props.onEnded?.();\n      }\n    };\n\n    const handleError = (error: any) => {\n      if (this.mounted) {\n        this.props.onError?.(error);\n      }\n    };\n\n    const handleLoadedData = () => {\n      if (this.mounted) {\n        this.props.onLoaded?.();\n      }\n    };\n\n    video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n    video.addEventListener(\"play\", handlePlay);\n    video.addEventListener(\"pause\", handlePause);\n    video.addEventListener(\"ended\", handleEnded);\n    video.addEventListener(\"error\", handleError);\n    video.addEventListener(\"loadeddata\", handleLoadedData);\n\n    video.src = this.props.src;\n    if (this.props.autoplay !== undefined) video.autoplay = this.props.autoplay;\n    if (this.props.muted !== undefined) video.muted = this.props.muted;\n    if (this.props.loop !== undefined) video.loop = this.props.loop;\n    if (this.props.controls !== undefined) video.controls = this.props.controls;\n    if (this.props.playsInline !== undefined)\n      video.playsInline = this.props.playsInline;\n    if (this.props.preload !== undefined)\n      video.preload = this.props.preload as \"\" | \"metadata\" | \"none\" | \"auto\";\n    if (this.props.poster !== undefined) video.poster = this.props.poster;\n\n    this.props.onMount?.(this);\n\n    return () => {\n      video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n      video.removeEventListener(\"play\", handlePlay);\n      video.removeEventListener(\"pause\", handlePause);\n      video.removeEventListener(\"ended\", handleEnded);\n      video.removeEventListener(\"error\", handleError);\n      video.removeEventListener(\"loadeddata\", handleLoadedData);\n    };\n  };\n\n  play = () => {\n    if (this.props.videoElement) {\n      const video = this.props.videoElement;\n      const hasValidSource =\n        video.src ||\n        (video.currentSrc && video.currentSrc !== \"\") ||\n        video.readyState >= 1;\n\n      if (hasValidSource) {\n        video.play()?.catch((error) => {\n          console.error(\"[FilePlayer] Failed to play:\", error);\n          this.props.onError?.(error);\n        });\n      } else {\n        console.warn(\"[FilePlayer] Cannot play: video has no valid source\");\n      }\n    }\n  };\n\n  pause = () => {\n    if (this.props.videoElement) {\n      this.props.videoElement.pause();\n    }\n  };\n\n  stop = () => {\n    this.pause();\n    if (this.props.videoElement) {\n      this.props.videoElement.currentTime = 0;\n    }\n  };\n\n  seekTo = (seconds: number, keepPlaying?: boolean) => {\n    if (this.props.videoElement) {\n      this.props.videoElement.currentTime = seconds;\n      if (!keepPlaying) {\n        this.pause();\n      }\n    }\n  };\n\n  setVolume = (volume: number) => {\n    if (this.props.videoElement) {\n      this.props.videoElement.volume = Math.max(0, Math.min(1, volume));\n    }\n  };\n\n  mute = () => {\n    if (this.props.videoElement) {\n      this.props.videoElement.muted = true;\n    }\n  };\n\n  unmute = () => {\n    if (this.props.videoElement) {\n      this.props.videoElement.muted = false;\n    }\n  };\n\n  setPlaybackRate = (rate: number) => {\n    if (this.props.videoElement && rate > 0) {\n      this.props.videoElement.playbackRate = rate;\n    }\n  };\n\n  setLoop = (loop: boolean) => {\n    if (this.props.videoElement) {\n      this.props.videoElement.loop = loop;\n    }\n  };\n\n  getDuration = (): number | null => {\n    if (this.props.videoElement && isFinite(this.props.videoElement.duration)) {\n      return this.props.videoElement.duration;\n    }\n    return null;\n  };\n\n  getCurrentTime = (): number | null => {\n    if (\n      this.props.videoElement &&\n      isFinite(this.props.videoElement.currentTime)\n    ) {\n      return this.props.videoElement.currentTime;\n    }\n    return null;\n  };\n\n  getSecondsLoaded = (): number | null => {\n    if (\n      this.props.videoElement &&\n      this.props.videoElement.buffered.length > 0\n    ) {\n      return this.props.videoElement.buffered.end(\n        this.props.videoElement.buffered.length - 1\n      );\n    }\n    return null;\n  };\n\n  getInternalPlayer = (key = \"player\") => {\n    if (key === \"video\") return this.props.videoElement;\n    return null;\n  };\n\n  enablePIP = async () => {\n    if (\n      this.props.videoElement &&\n      \"requestPictureInPicture\" in this.props.videoElement\n    ) {\n      try {\n        await (this.props.videoElement as any).requestPictureInPicture();\n      } catch (error) {\n        console.warn(\"Picture-in-Picture failed:\", error);\n      }\n    }\n  };\n\n  disablePIP = async () => {\n    if (document.pictureInPictureElement) {\n      try {\n        await document.exitPictureInPicture();\n      } catch (error) {\n        console.warn(\"Exit Picture-in-Picture failed:\", error);\n      }\n    }\n  };\n\n  render() {\n    return null;\n  }\n}\n","import { lazy } from \"../utils\";\nimport { canPlay } from \"../patterns\";\nimport HlsPlayer from \"./HlsPlayer\";\nimport FilePlayer from \"./FilePlayer\";\n\nexport interface PlayerConfig {\n  key: string;\n  name: string;\n  canPlay: (url: string) => boolean;\n  canEnablePIP?: (url: string) => boolean;\n  lazyPlayer?: any;\n}\n\nconst players: PlayerConfig[] = [\n  {\n    key: \"hls\",\n    name: \"HLS Player\",\n    canPlay: canPlay.hls,\n    lazyPlayer: lazy(() => Promise.resolve({ default: HlsPlayer })),\n  },\n  {\n    key: \"file\",\n    name: \"File Player\",\n    canPlay: canPlay.file,\n    canEnablePIP: (url: string) => {\n      return (\n        canPlay.file(url) &&\n        (document.pictureInPictureEnabled ||\n          typeof (document as any).webkitSupportsPresentationMode ===\n            \"function\")\n      );\n    },\n    lazyPlayer: lazy(() => Promise.resolve({ default: FilePlayer })),\n  },\n];\n\nexport default players;\n","import React, { Component } from \"react\";\nimport type { BaseStormcloudPlayerProps, OnProgressProps } from \"./props\";\nimport { defaultProps } from \"./props\";\nimport { isMediaStream } from \"./utils\";\n\nconst SEEK_ON_PLAY_EXPIRY = 5000;\n\nexport interface PlayerProps extends BaseStormcloudPlayerProps {\n  activePlayer: any;\n  onReady: () => void;\n}\n\nexport default class Player extends Component<PlayerProps> {\n  static displayName = \"Player\";\n  static defaultProps = defaultProps;\n\n  private mounted = false;\n  private isReady = false;\n  private isPlaying = false;\n  private isLoading = true;\n  private loadOnReady: string | null = null;\n  private startOnPlay = true;\n  private seekOnPlay: number | null = null;\n  private onDurationCalled = false;\n  private progressTimeout?: number;\n  private durationCheckTimeout?: number;\n  private prevPlayed?: number;\n  private prevLoaded?: number;\n  private player?: any;\n\n  componentDidMount() {\n    this.mounted = true;\n  }\n\n  componentWillUnmount() {\n    clearTimeout(this.progressTimeout);\n    clearTimeout(this.durationCheckTimeout);\n    this.mounted = false;\n  }\n\n  componentDidUpdate(prevProps: PlayerProps) {\n    if (!this.player) return;\n\n    const { src, playing, volume, muted, playbackRate, loop, activePlayer } =\n      this.props;\n\n    if (prevProps.src !== src) {\n      if (this.isLoading && !activePlayer.forceLoad && !isMediaStream(src)) {\n        console.warn(\n          `StormcloudPlayer: the attempt to load ${src} is being deferred until the player has loaded`\n        );\n        this.loadOnReady = src || null;\n        return;\n      }\n      this.isLoading = true;\n      this.startOnPlay = true;\n      this.onDurationCalled = false;\n      this.player.load(src, this.isReady);\n    }\n\n    if (!prevProps.playing && playing && !this.isPlaying) {\n      this.player.play();\n    }\n\n    if (prevProps.playing && !playing && this.isPlaying) {\n      this.player.pause();\n    }\n\n    if (prevProps.volume !== volume && volume !== null) {\n      this.player.setVolume(volume);\n    }\n\n    if (prevProps.muted !== muted) {\n      if (muted) {\n        this.player.mute();\n      } else {\n        this.player.unmute();\n        if (volume !== null) {\n          setTimeout(() => this.player.setVolume(volume));\n        }\n      }\n    }\n\n    if (\n      prevProps.playbackRate !== playbackRate &&\n      this.player.setPlaybackRate\n    ) {\n      this.player.setPlaybackRate(playbackRate);\n    }\n\n    if (prevProps.loop !== loop && this.player.setLoop) {\n      this.player.setLoop(loop);\n    }\n  }\n\n  handlePlayerMount = (player: any) => {\n    if (this.player) {\n      this.progress();\n      return;\n    }\n\n    this.player = player;\n    this.player.load(this.props.src);\n    this.progress();\n  };\n\n  getInternalPlayer = (key?: string) => {\n    if (!this.player) return null;\n    return this.player.getInternalPlayer(key);\n  };\n\n  progress = () => {\n    if (this.props.src && this.player && this.isReady) {\n      const playedSeconds = this.getCurrentTime() || 0;\n      const loadedSeconds = this.getSecondsLoaded();\n      const duration = this.getDuration();\n\n      if (duration) {\n        const progress: OnProgressProps = {\n          playedSeconds,\n          played: playedSeconds / duration,\n          loaded: 0,\n          loadedSeconds: 0,\n        };\n\n        if (loadedSeconds !== null) {\n          progress.loadedSeconds = loadedSeconds;\n          progress.loaded = loadedSeconds / duration;\n        }\n\n        if (\n          progress.playedSeconds !== this.prevPlayed ||\n          progress.loadedSeconds !== this.prevLoaded\n        ) {\n          this.props.onProgress?.(progress);\n        }\n\n        this.prevPlayed = progress.playedSeconds;\n        this.prevLoaded = progress.loadedSeconds;\n      }\n    }\n\n    this.progressTimeout = window.setTimeout(\n      this.progress,\n      this.props.progressInterval || 1000\n    );\n  };\n\n  handleReady = () => {\n    if (!this.mounted) return;\n\n    this.isReady = true;\n    this.isLoading = false;\n\n    const { onReady, playing, volume, muted } = this.props;\n    onReady();\n\n    if (!muted && volume !== null) {\n      this.player.setVolume(volume);\n    }\n\n    if (this.loadOnReady) {\n      this.player.load(this.loadOnReady, true);\n      this.loadOnReady = null;\n    } else if (playing) {\n      this.player.play();\n    }\n\n    this.handleDurationCheck();\n  };\n\n  handlePlay = () => {\n    this.isPlaying = true;\n    this.isLoading = false;\n\n    const { onStart, onPlay, playbackRate } = this.props;\n\n    if (this.startOnPlay) {\n      if (this.player.setPlaybackRate && playbackRate !== 1) {\n        this.player.setPlaybackRate(playbackRate);\n      }\n      onStart?.();\n      this.startOnPlay = false;\n    }\n\n    onPlay?.();\n\n    if (this.seekOnPlay) {\n      this.seekTo(this.seekOnPlay);\n      this.seekOnPlay = null;\n    }\n\n    this.handleDurationCheck();\n  };\n\n  handlePause = (e?: any) => {\n    this.isPlaying = false;\n    if (!this.isLoading) {\n      this.props.onPause?.(e);\n    }\n  };\n\n  handleEnded = () => {\n    const { activePlayer, loop, onEnded } = this.props;\n    if (activePlayer.loopOnEnded && loop) {\n      this.seekTo(0);\n    }\n    if (!loop) {\n      this.isPlaying = false;\n      onEnded?.();\n    }\n  };\n\n  handleError = (...args: any[]) => {\n    this.isLoading = false;\n    this.props.onError?.(args[0], args[1], args[2], args[3]);\n  };\n\n  handleDurationCheck = () => {\n    clearTimeout(this.durationCheckTimeout);\n    const duration = this.getDuration();\n    if (duration) {\n      if (!this.onDurationCalled) {\n        this.props.onDuration?.(duration);\n        this.onDurationCalled = true;\n      }\n    } else {\n      this.durationCheckTimeout = window.setTimeout(\n        this.handleDurationCheck,\n        100\n      );\n    }\n  };\n\n  handleLoaded = () => {\n    this.isLoading = false;\n  };\n\n  getDuration(): number | null {\n    if (!this.isReady) return null;\n    return this.player.getDuration();\n  }\n\n  getCurrentTime(): number | null {\n    if (!this.isReady) return null;\n    return this.player.getCurrentTime();\n  }\n\n  getSecondsLoaded(): number | null {\n    if (!this.isReady) return null;\n    return this.player.getSecondsLoaded();\n  }\n\n  seekTo(amount: number, type?: \"seconds\" | \"fraction\", keepPlaying?: boolean) {\n    if (!this.isReady) {\n      if (amount !== 0) {\n        this.seekOnPlay = amount;\n        setTimeout(() => {\n          this.seekOnPlay = null;\n        }, SEEK_ON_PLAY_EXPIRY);\n      }\n      return;\n    }\n\n    const isFraction = !type ? amount > 0 && amount < 1 : type === \"fraction\";\n    if (isFraction) {\n      const duration = this.player.getDuration();\n      if (!duration) {\n        console.warn(\n          \"StormcloudPlayer: could not seek using fraction – duration not yet available\"\n        );\n        return;\n      }\n      this.player.seekTo(duration * amount, keepPlaying);\n      return;\n    }\n    this.player.seekTo(amount, keepPlaying);\n  }\n\n  render() {\n    const Player = this.props.activePlayer;\n    if (!Player) {\n      return null;\n    }\n\n    return React.createElement(Player, {\n      ...this.props,\n      onMount: this.handlePlayerMount,\n      onReady: this.handleReady,\n      onPlay: this.handlePlay,\n      onPause: this.handlePause,\n      onEnded: this.handleEnded,\n      onLoaded: this.handleLoaded,\n      onError: this.handleError,\n    });\n  }\n}\n"]}