stormcloud-video-player 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/stormcloud-vp.min.js +1 -1
- package/lib/index.cjs +14 -1
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +14 -1
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +10 -1
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +1 -1
- package/lib/players/HlsPlayer.cjs +10 -1
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.d.cts +1 -1
- package/lib/players/index.cjs +10 -1
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/adstormPlayer.cjs +8 -1
- package/lib/sdk/adstormPlayer.cjs.map +1 -1
- package/lib/sdk/adstormPlayer.d.cts +1 -1
- package/lib/sdk/hlsAdPlayer.cjs +4 -0
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.d.cts +1 -1
- package/lib/{types-Ca4ZDaWw.d.cts → types-2vzNGNdf.d.cts} +1 -0
- package/lib/ui/StormcloudVideoPlayer.cjs +10 -1
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.d.cts +1 -1
- package/lib/utils/tracking.d.cts +1 -1
- package/package.json +1 -1
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/ubuntu24/Dev/stormcloud-vp/lib/index.js","../src/ui/StormcloudVideoPlayer.tsx","../src/player/StormcloudVideoPlayer.ts","../src/sdk/adstormPlayer.ts","../src/utils/polyfills.ts","../src/utils/browserCompat.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","../src/utils/tracking.ts","../src/sdk/hlsAdPlayer.ts"],"names":["React","useEffect","useRef","useMemo","Hls","SUPPORTED_VIDEO_EXTENSIONS","UNSUPPORTED_VIDEO_EXTENSIONS","getFileExtension","url","pathname","URL","lastDot","lastIndexOf","slice","toLowerCase","ext","split","isUnsupportedFormat","indexOf","replaceFlvExtension","replace","isSupportedFormat","mimeType","includes","createAdStormPlayer","contentVideo","options","licenseKey","debug","adPlaying","originalMutedState","originalVolume","Math","max","min","volume","listeners","Map","adVideoElement","adContainerEl","currentAd","destroyed","trackingFired","impression","start","firstQuartile","midpoint","thirdQuartile","complete","log","args","console","emit","event","payload","set","get","Array","from","fn","error","warn","fireTrackingPixels","urls","length","forEach","img","Image","src","buildVastUrl","durationSeconds","metadata","baseUrl","defaultMetadata","video","codec","width","videoWidth","height","videoHeight","fps","bitrate","profile","pix_fmt","has_b_frames","audio","sample_rate","finalMetadata","metadataStr","encodeURIComponent","JSON","stringify","ceil","parseVastXml","xmlString","ads","parser","DOMParser","xmlDoc","parseFromString","parserError","querySelector","textContent","adElements","querySelectorAll","adElement","adId","getAttribute","title","durationText","durationParts","duration","parseInt","parseFloat","mediaFileElements","mediaFiles","mf","type","trim","originalUrl","push","trackingUrls","el","eventKey","clickThrough","id","selectBestMediaFile","mp4Files","filter","candidates","targetWidth","targetHeight","sort","a","b","diffA","abs","diffB","createAdVideoElement","document","createElement","style","position","left","top","objectFit","backgroundColor","zIndex","playsInline","muted","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","setupAdEventListeners","ad","addEventListener","progress","currentTime","handleAdComplete","e","handleAdError","opacity","setTimeout","display","pointerEvents","visibility","fetchVast","vastUrl","response","xmlText","fetch","headers","ok","Error","status","statusText","text","initialize","container","right","bottom","alignItems","justifyContent","transition","parentElement","appendChild","requestAds","parsed","Promise","reject","isNaN","resolve","play","mediaFile","pause","offsetHeight","stop","destroy","remove","removeChild","clear","isAdPlaying","resize","on","listener","has","Set","add","off","delete","updateOriginalMutedState","nextVolume","Number","getOriginalMutedState","getOriginalVolume","setAdVolume","getAdVolume","showPlaceholder","hidePlaceholder","polyfillURLSearchParams","URLSearchParams","URLSearchParamsPolyfill","init","params","parseQueryString","value","key","append","query","cleanQuery","startsWith","param","decodedKey","safeDecodeURIComponent","decodedValue","str","decodeURIComponent","name","values","String","getAll","callback","toString","parts","join","window","polyfillTextEncoder","TextEncoder","TextEncoderPolyfill","encoding","encode","utf8","i","charcode","charCodeAt","Uint8Array","polyfillPromiseFinally","prototype","finally","constructor","then","reason","polyfillObjectAssign","Object","assign","target","sources","TypeError","to","nextSource","nextKey","hasOwnProperty","call","polyfillArrayFrom","arrayLike","mapFn","thisArg","items","len","result","polyfillStringStartsWith","search","pos","substring","polyfillStringEndsWith","endsWith","polyfillStringIncludes","initializePolyfills","getChromeVersion","ua","match","getWebKitVersion","getPlatform","navigator","userAgentData","platform","userAgent","test","detectBrowser","version","majorVersion","isSmartTV","isLegacyTV","supportsModernJS","chromeVersion","webkitVersion","logBrowserInfo","browser","getBrowserConfigOverrides","overrides","allowNativeHls","supportsFeature","feature","crypto","subtle","StormcloudVideoPlayer","config","attached","inAdBreak","ptsDriftEmaMs","isLiveStream","nativeHlsMode","videoSrcProtection","bufferedSegmentsCount","shouldAutoplayAfterBuffering","hasInitialBufferCompleted","browserOverrides","videoElement","debugAdTiming","adPlayer","load","attach","shouldUseNativeHls","lowLatencyMode","isLive","autoplay","catch","hls","enableWorker","backBufferLength","liveDurationInfinity","maxLiveSyncPlaybackRate","liveSyncDuration","maxBufferLength","maxMaxBufferLength","maxBufferSize","maxBufferHole","highBufferWatchdogPeriod","nudgeOffset","nudgeMaxRetry","startPosition","Events","MEDIA_ATTACHED","loadSource","MANIFEST_PARSED","minSegments","levels","some","level","details","live","minSegmentsBeforePlay","FRAG_BUFFERED","err","FRAG_PARSING_METADATA","_evt","data","id3Tags","samples","map","s","ptsSeconds","pts","tag","onId3Tag","FRAG_CHANGED","frag","tagList","isArray","entry","idx","parseCueOutDuration","onScte35Marker","raw","prog","parseCueOutCont","elapsed","attrs","parseAttributeList","hasScteOut","hasScteIn","klass","toNumber","ERROR","fatal","ErrorTypes","NETWORK_ERROR","startLoad","MEDIA_ERROR","recoverMediaError","attachMedia","handleAdPodComplete","timeUpdateHandler","emptiedHandler","wasPaused","paused","streamType","getStreamType","canNative","canPlayType","updatePtsDrift","marker","parseScte35FromId3","decodeId3ValueToText","cueOutMatch","arg","dur","id3","cueOutContMatch","cont","cueInMatch","decoder","TextDecoder","decode","out","fromCharCode","durationMs","expectedAdBreakDurationMs","handleAdStart","scheduleAdStopCountdown","clearAdStopTimer","num","d","elapsedMatch","durationMatch","res","regex","exec","rawVal","val","n","remainingMs","ms","floor","adStopTimerId","clearTimeout","ptsSecondsSample","sampleMs","isFinite","alpha","restoredMuted","restoredVolume","isShowingAds","shouldShowNativeControls","showCustomControls","toggleMute","currentMuted","newMutedState","toggleFullscreen","fullscreenElement","requestFullscreen","exitFullscreen","isMuted","setMuted","setVolume","clampedVolume","isFullscreen","clientWidth","clientHeight","removeEventListener","getCurrentAdIndex","getTotalAdsInBreak","FaPlay","FaPause","FaVolumeUp","FaVolumeMute","FaVolumeDown","FaExpand","FaCompress","FaSpinner","Fragment","jsx","jsxs","CRITICAL_PROPS","StormcloudVideoPlayerComponent","memo","props","driftToleranceMs","immediateManifestAds","hideLoadingIndicator","onVolumeToggle","onFullscreenToggle","onControlClick","onReady","wrapperClassName","wrapperStyle","className","controls","preload","poster","children","restVideoAttrs","videoRef","playerRef","bufferingTimeoutRef","useState","showAds","currentIndex","totalAds","adStatus","setAdStatus","setShouldShowNativeControls","setIsMuted","setIsFullscreen","setIsPlaying","setCurrentTime","setDuration","playbackRate","setPlaybackRate","showVolumeSlider","setShowVolumeSlider","showSpeedMenu","setShowSpeedMenu","isLoading","setIsLoading","isBuffering","setIsBuffering","showCenterPlay","setShowCenterPlay","showLicenseWarning","setShowLicenseWarning","innerWidth","viewportWidth","setViewportWidth","innerHeight","isPortrait","setIsPortrait","getResponsiveScale","responsiveScale","formatTime","seconds","hours","minutes","remainingSeconds","padStart","handlePlayPause","current","hasValidSource","currentSrc","readyState","handleCenterPlayClick","handleTimelineSeek","rect","currentTarget","getBoundingClientRect","clickX","clientX","newTime","handleVolumeChange","newVolume","handlePlaybackRateChange","rate","isHlsStream","shouldShowEnhancedControls","criticalPropsKey","prop","cfg","player","showNative","checkAdStatus","prev","interval","setInterval","clearInterval","handleResize","updateStates","currentTimeValue","durationValue","volumeValue","rateValue","handleFullscreenChange","handleLoadedMetadata","handleLoadedData","handleLoadStart","handleCanPlay","handleCanPlayThrough","handleWaiting","handlePlaying","handlePause","handleEnded","overflow","minHeight","maxWidth","maxHeight","borderRadius","boxShadow","ref","aspectRatio","size","color","animation","transform","background","padding","backdropFilter","border","textAlign","margin","fontSize","fontWeight","marginBottom","textShadow","lineHeight","onClick","cursor","onMouseEnter","borderColor","onMouseLeave","marginLeft","flexWrap","gap","minWidth","flexDirection","onMouseDown","preventDefault","sliderElement","handleMouseMove","moveEvent","y","clientY","percentage","handleMouseUp","stopPropagation","onMouseUp","fontFamily","speed","borderBottom","prevProps","nextProps","uiProps","callbackProps","Component","Suspense","noop","defaultProps","playing","loop","progressInterval","adFailsafeTimeoutMs","onStart","onPlay","onPause","onBuffer","onBufferEnd","onEnded","onError","onDuration","onSeek","onProgress","lazy","reactLazy","omit","object","keys","isMediaStream","MediaStream","supportsWebKitPresentationMode","randomString","random","substr","parseQuery","queryString","manualParse","qs","merge","source","shift","isObject","item","IS_BROWSER","IS_GLOBAL","globalThis","IS_IOS","IS_SAFARI","SUPPORTS_HLS","Boolean","SUPPORTS_DASH","HLS_EXTENSIONS","HLS_PATHS","DASH_EXTENSIONS","VIDEO_EXTENSIONS","AUDIO_EXTENSIONS","canPlay","dash","file","HlsPlayer","mounted","onMount","seekTo","keepPlaying","mute","unmute","getDuration","getCurrentTime","getSecondsLoaded","buffered","end","getInternalPlayer","componentDidMount","componentWillUnmount","componentDidUpdate","render","displayName","FilePlayer","ready","handlePlay","handleError","onLoaded","setLoop","enablePIP","requestPictureInPicture","disablePIP","pictureInPictureElement","exitPictureInPicture","players","lazyPlayer","default","canEnablePIP","pictureInPictureEnabled","webkitSupportsPresentationMode","players_default","SEEK_ON_PLAY_EXPIRY","Player","arguments","isReady","loadOnReady","startOnPlay","seekOnPlay","onDurationCalled","handlePlayerMount","playedSeconds","loadedSeconds","played","loaded","prevPlayed","prevLoaded","progressTimeout","handleReady","handleDurationCheck","activePlayer","loopOnEnded","durationCheckTimeout","handleLoaded","forceLoad","amount","isFraction","UniversalSuspense","SUPPORTED_PROPS","customPlayers","createStormcloudPlayer","playerList","fallback","_a","state","showPreview","references","wrapper","getActivePlayer","getAttributes","fraction","renderActivePlayer","fallbackElement","Wrapper","attributes","wrapperRef","addCustomPlayer","removeCustomPlayers","StormcloudPlayer","StormcloudPlayer_default","cachedBrowserId","getClientInfo","screen","vendor","maxTouchPoints","memory","deviceMemory","hardwareConcurrency","screenInfo","availWidth","availHeight","orientation","pixelDepth","deviceType","brand","os","model","isAndroid","isWebView","isWebApp","webosMatch","tizenMatch","tvMatch","androidModelMatch","outerHeight","outerWidth","matchMedia","matches","standalone","angle","domain","location","hostname","origin","path","language","languages","cookieEnabled","doNotTrack","referrer","visibilityState","getBrowserID","clientInfo","fingerprintString","encodedData","buffer","hashBuffer","hashArray","hashHex","hash","char","fallbackHash","timestamp","digest","unescape","Date","now","padEnd","sendInitialTracking","browserId","trackingData","method","body","json","sendHeartbeat","heartbeatData","toISOString","isUnsupportedForHls","createHlsAdPlayer","mainHlsInstance","adHls","sessionId","pendingTimeouts","generateSessionId","trackingUrl","getMainStreamQuality","currentLevel","autoLevel","loadLevel","firstFile","mainQuality","scoredFiles","widthDiff","heightDiff","resolutionDiff","fileBitrate","bitrateDiff","score","bestMatch","resolution","isNoAdAvailable","index","bitrateAttr","bitrateValue","resume","fullscreen","skip","fetchAndParseVastAd","vastXml","ended","timeoutId","stillInPod","splice","previousMutedState","continueLiveStreamDuringAds","contentVolume","adVolume","isSupported"],"mappings":"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","sourcesContent":["// src/ui/StormcloudVideoPlayer.tsx\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\n// src/player/StormcloudVideoPlayer.ts\nimport Hls from \"hls.js\";\n\n// src/sdk/adstormPlayer.ts\nvar SUPPORTED_VIDEO_EXTENSIONS = [\".mp4\", \".webm\", \".ogg\", \".m3u8\", \".ts\"];\nvar UNSUPPORTED_VIDEO_EXTENSIONS = [\".flv\", \".f4v\", \".swf\", \".wmv\", \".avi\", \".mov\", \".mkv\"];\nfunction getFileExtension(url) {\n try {\n const pathname = new URL(url, \"http://dummy\").pathname;\n const lastDot = pathname.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || \"\").toLowerCase();\n }\n}\nfunction isUnsupportedFormat(url) {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\nfunction replaceFlvExtension(url) {\n const ext = getFileExtension(url);\n if (ext === \".flv\") {\n return url.replace(/\\.flv(\\?|$)/i, \".mp4$1\");\n }\n return url;\n}\nfunction isSupportedFormat(url, mimeType) {\n if (isUnsupportedFormat(url)) {\n return false;\n }\n const ext = getFileExtension(url);\n if (SUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1) {\n return true;\n }\n if (ext === \"\" || ext === \".\") {\n return mimeType.includes(\"video/mp4\") || mimeType.includes(\"video/webm\") || mimeType.includes(\"m3u8\") || mimeType.includes(\"application/x-mpegurl\");\n }\n return false;\n}\nfunction createAdStormPlayer(contentVideo, options) {\n const { licenseKey, debug = false } = options;\n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = /* @__PURE__ */ new Map();\n let adVideoElement;\n let adContainerEl;\n let currentAd;\n let destroyed = false;\n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n function log(...args) {\n if (debug) {\n console.log(\"[AdStormPlayer]\", ...args);\n }\n }\n function emit(event, payload) {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch (error) {\n console.warn(`[AdStormPlayer] Error in event listener for ${event}:`, error);\n }\n }\n }\n function fireTrackingPixels(urls) {\n if (!urls || urls.length === 0) return;\n urls.forEach((url) => {\n try {\n const img = new Image(1, 1);\n img.src = url;\n log(\"Fired tracking pixel:\", url);\n } catch (error) {\n console.warn(\"[AdStormPlayer] Error firing tracking pixel:\", error);\n }\n });\n }\n function buildVastUrl(durationSeconds, metadata) {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n const defaultMetadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5e3,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48e3,\n bitrate: 128\n }\n };\n const finalMetadata = metadata || defaultMetadata;\n const metadataStr = encodeURIComponent(JSON.stringify(finalMetadata));\n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\n }\n function parseVastXml(xmlString) {\n const ads = [];\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\"[AdStormPlayer] XML parsing error:\", parserError.textContent);\n return [];\n }\n const adElements = xmlDoc.querySelectorAll(\"Ad\");\n adElements.forEach((adElement) => {\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n const durationText = adElement.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + parseFloat(durationParts[2] || \"0\");\n const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n const mediaFiles = [];\n mediaFileElements.forEach((mf) => {\n const type = mf.getAttribute(\"type\") || \"\";\n let url = mf.textContent?.trim() || \"\";\n const width = parseInt(mf.getAttribute(\"width\") || \"1920\", 10);\n const height = parseInt(mf.getAttribute(\"height\") || \"1080\", 10);\n const bitrate = mf.getAttribute(\"bitrate\") ? parseInt(mf.getAttribute(\"bitrate\"), 10) : void 0;\n if (!url) {\n log(`Skipping empty MediaFile URL`);\n return;\n }\n const originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n log(`Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n if (isUnsupportedFormat(url)) {\n const ext = getFileExtension(url);\n log(`Skipping unsupported format: ${url} (extension: ${ext}, declared type: ${type})`);\n return;\n }\n if (isSupportedFormat(url, type)) {\n mediaFiles.push({ url, type, width, height, bitrate });\n log(`Found media file: ${url} (${type}, ${width}x${height})`);\n } else {\n log(`Skipping incompatible media file: ${url} (type: ${type})`);\n }\n });\n if (mediaFiles.length === 0) {\n log(\"No valid media files found in ad:\", adId);\n return;\n }\n const trackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n error: []\n };\n adElement.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n adElement.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n const clickThrough = adElement.querySelector(\"ClickThrough\")?.textContent?.trim();\n ads.push({\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough\n });\n log(`Parsed ad: ${title}, duration: ${duration}s, media files: ${mediaFiles.length}`);\n });\n } catch (error) {\n console.error(\"[AdStormPlayer] Error parsing VAST XML:\", error);\n }\n return ads;\n }\n function selectBestMediaFile(mediaFiles) {\n if (mediaFiles.length === 0) return null;\n if (mediaFiles.length === 1) return mediaFiles[0];\n const mp4Files = mediaFiles.filter((mf) => mf.type.includes(\"video/mp4\"));\n const candidates = mp4Files.length > 0 ? mp4Files : mediaFiles;\n const targetWidth = contentVideo.videoWidth || 1280;\n const targetHeight = contentVideo.videoHeight || 720;\n candidates.sort((a, b) => {\n const diffA = Math.abs(a.width - targetWidth) + Math.abs(a.height - targetHeight);\n const diffB = Math.abs(b.width - targetWidth) + Math.abs(b.height - targetHeight);\n return diffA - diffB;\n });\n return candidates[0] || null;\n }\n function createAdVideoElement() {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.style.zIndex = \"15\";\n video.playsInline = true;\n video.muted = false;\n video.volume = originalMutedState ? 0 : originalVolume;\n return video;\n }\n function setAdPlayingFlag(isPlaying) {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n function setupAdEventListeners() {\n if (!adVideoElement || !currentAd) return;\n const ad = currentAd;\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!ad || !adVideoElement) return;\n const progress = adVideoElement.currentTime / ad.duration;\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(ad.trackingUrls.firstQuartile);\n }\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(ad.trackingUrls.midpoint);\n }\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(ad.trackingUrls.thirdQuartile);\n }\n });\n adVideoElement.addEventListener(\"playing\", () => {\n if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(ad.trackingUrls.start);\n log(\"Ad started playing\");\n });\n adVideoElement.addEventListener(\"ended\", () => {\n if (!ad || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(ad.trackingUrls.complete);\n log(\"Ad completed\");\n handleAdComplete();\n });\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[AdStormPlayer] Ad video error:\", e);\n if (ad) {\n fireTrackingPixels(ad.trackingUrls.error);\n }\n handleAdError();\n });\n }\n function handleAdComplete() {\n log(\"Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n emit(\"content_resume\");\n emit(\"all_ads_completed\");\n }\n function handleAdError() {\n log(\"Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n emit(\"ad_error\");\n }\n async function fetchVast(durationSeconds) {\n const vastUrl = buildVastUrl(durationSeconds);\n log(\"Fetching VAST from:\", vastUrl);\n const response = await fetch(vastUrl, {\n headers: {\n \"Accept\": \"application/xml\"\n }\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.status} ${response.statusText}`);\n }\n const xmlText = await response.text();\n log(\"VAST response received, length:\", xmlText.length);\n return parseVastXml(xmlText);\n }\n return {\n initialize() {\n log(\"Initializing\");\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n async requestAds(duration) {\n log(\"Requesting ads for duration:\", duration);\n if (adPlaying) {\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n try {\n let durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n const ads = await fetchVast(durationSeconds);\n if (ads.length === 0) {\n log(\"No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n currentAd = ads[0];\n log(`Ad loaded: ${currentAd.title}, duration: ${currentAd.duration}s`);\n fireTrackingPixels(currentAd.trackingUrls.impression);\n trackingFired.impression = true;\n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n async play() {\n if (!currentAd) {\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n log(\"Starting ad playback\");\n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n contentVideo.style.transition = \"opacity 0.3s ease-in-out\";\n contentVideo.style.opacity = \"0\";\n setTimeout(() => {\n contentVideo.style.visibility = \"hidden\";\n }, 300);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n contentVideo.pause();\n adPlaying = true;\n setAdPlayingFlag(true);\n if (adVideoElement) {\n adVideoElement.volume = originalMutedState ? 0 : originalVolume;\n adVideoElement.muted = originalMutedState;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n }\n emit(\"content_pause\");\n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available\");\n }\n log(\"Playing media file:\", mediaFile.url);\n adVideoElement.src = mediaFile.url;\n await adVideoElement.play();\n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n async stop() {\n log(\"Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n currentAd = void 0;\n },\n destroy() {\n log(\"Destroying\");\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = void 0;\n }\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n adContainerEl = void 0;\n currentAd = void 0;\n listeners.clear();\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width, height) {\n log(`Resizing to ${width}x${height}`);\n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n on(event, listener) {\n if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());\n listeners.get(event).add(listener);\n },\n off(event, listener) {\n listeners.get(event)?.delete(listener);\n },\n updateOriginalMutedState(muted, volume) {\n const nextVolume = typeof volume === \"number\" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;\n log(`updateOriginalMutedState: muted=${muted}, volume=${nextVolume}`);\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n getOriginalMutedState() {\n return originalMutedState;\n },\n getOriginalVolume() {\n return originalVolume;\n },\n setAdVolume(volume) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n adVideoElement.muted = volume === 0;\n }\n },\n getAdVolume() {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n }\n };\n}\n\n// src/utils/polyfills.ts\nfunction polyfillURLSearchParams() {\n if (typeof URLSearchParams !== \"undefined\") {\n return;\n }\n class URLSearchParamsPolyfill {\n constructor(init) {\n this.params = /* @__PURE__ */ new Map();\n if (typeof init === \"string\") {\n this.parseQueryString(init);\n } else if (init instanceof URLSearchParamsPolyfill) {\n init.forEach((value, key) => {\n this.append(key, value);\n });\n }\n }\n parseQueryString(query) {\n const cleanQuery = query.startsWith(\"?\") ? query.slice(1) : query;\n if (!cleanQuery) return;\n cleanQuery.split(\"&\").forEach((param) => {\n const [key, value] = param.split(\"=\");\n if (key) {\n const decodedKey = this.safeDecodeURIComponent(key);\n const decodedValue = value ? this.safeDecodeURIComponent(value) : \"\";\n this.append(decodedKey, decodedValue);\n }\n });\n }\n safeDecodeURIComponent(str) {\n try {\n return decodeURIComponent(str.replace(/\\+/g, \" \"));\n } catch (e) {\n return str;\n }\n }\n append(name, value) {\n const values = this.params.get(name) || [];\n values.push(String(value));\n this.params.set(name, values);\n }\n delete(name) {\n this.params.delete(name);\n }\n get(name) {\n const values = this.params.get(name);\n return values && values.length > 0 && values[0] !== void 0 ? values[0] : null;\n }\n getAll(name) {\n return this.params.get(name) || [];\n }\n has(name) {\n return this.params.has(name);\n }\n set(name, value) {\n this.params.set(name, [String(value)]);\n }\n forEach(callback) {\n this.params.forEach((values, key) => {\n values.forEach((value) => {\n callback(value, key, this);\n });\n });\n }\n toString() {\n const parts = [];\n this.params.forEach((values, key) => {\n values.forEach((value) => {\n parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\n });\n });\n return parts.join(\"&\");\n }\n }\n window.URLSearchParams = URLSearchParamsPolyfill;\n}\nfunction polyfillTextEncoder() {\n if (typeof TextEncoder !== \"undefined\") {\n return;\n }\n class TextEncoderPolyfill {\n constructor() {\n this.encoding = \"utf-8\";\n }\n encode(str) {\n const utf8 = [];\n for (let i = 0; i < str.length; i++) {\n let charcode = str.charCodeAt(i);\n if (charcode < 128) {\n utf8.push(charcode);\n } else if (charcode < 2048) {\n utf8.push(192 | charcode >> 6, 128 | charcode & 63);\n } else if (charcode < 55296 || charcode >= 57344) {\n utf8.push(\n 224 | charcode >> 12,\n 128 | charcode >> 6 & 63,\n 128 | charcode & 63\n );\n } else {\n i++;\n charcode = 65536 + ((charcode & 1023) << 10 | str.charCodeAt(i) & 1023);\n utf8.push(\n 240 | charcode >> 18,\n 128 | charcode >> 12 & 63,\n 128 | charcode >> 6 & 63,\n 128 | charcode & 63\n );\n }\n }\n return new Uint8Array(utf8);\n }\n }\n window.TextEncoder = TextEncoderPolyfill;\n}\nfunction polyfillPromiseFinally() {\n if (typeof Promise !== \"undefined\" && !Promise.prototype.finally) {\n Promise.prototype.finally = function(callback) {\n const constructor = this.constructor;\n return this.then(\n (value) => constructor.resolve(callback()).then(() => value),\n (reason) => constructor.resolve(callback()).then(() => {\n throw reason;\n })\n );\n };\n }\n}\nfunction polyfillObjectAssign() {\n if (typeof Object.assign !== \"function\") {\n Object.assign = function(target, ...sources) {\n if (target == null) {\n throw new TypeError(\"Cannot convert undefined or null to object\");\n }\n const to = Object(target);\n for (let i = 0; i < sources.length; i++) {\n const nextSource = sources[i];\n if (nextSource != null) {\n for (const nextKey in nextSource) {\n if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n }\n}\nfunction polyfillArrayFrom() {\n if (!Array.from) {\n Array.from = function(arrayLike, mapFn, thisArg) {\n const items = Object(arrayLike);\n if (arrayLike == null) {\n throw new TypeError(\"Array.from requires an array-like object\");\n }\n const len = items.length >>> 0;\n const result = new Array(len);\n for (let i = 0; i < len; i++) {\n if (mapFn) {\n result[i] = mapFn.call(thisArg, items[i], i);\n } else {\n result[i] = items[i];\n }\n }\n return result;\n };\n }\n}\nfunction polyfillStringStartsWith() {\n if (!String.prototype.startsWith) {\n String.prototype.startsWith = function(search, pos) {\n pos = !pos || pos < 0 ? 0 : +pos;\n return this.substring(pos, pos + search.length) === search;\n };\n }\n}\nfunction polyfillStringEndsWith() {\n if (!String.prototype.endsWith) {\n String.prototype.endsWith = function(search, length) {\n if (length === void 0 || length > this.length) {\n length = this.length;\n }\n return this.substring(length - search.length, length) === search;\n };\n }\n}\nfunction polyfillStringIncludes() {\n if (!String.prototype.includes) {\n String.prototype.includes = function(search, start) {\n if (typeof start !== \"number\") {\n start = 0;\n }\n if (start + search.length > this.length) {\n return false;\n }\n return this.indexOf(search, start) !== -1;\n };\n }\n}\nfunction initializePolyfills() {\n polyfillObjectAssign();\n polyfillArrayFrom();\n polyfillStringStartsWith();\n polyfillStringEndsWith();\n polyfillStringIncludes();\n polyfillURLSearchParams();\n polyfillTextEncoder();\n polyfillPromiseFinally();\n}\n\n// src/utils/browserCompat.ts\nfunction getChromeVersion(ua) {\n const match = ua.match(/Chrome\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\nfunction getWebKitVersion(ua) {\n const match = ua.match(/AppleWebKit\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\nfunction getPlatform() {\n if (\"userAgentData\" in navigator && navigator.userAgentData?.platform) {\n return navigator.userAgentData.platform;\n }\n const ua = navigator.userAgent;\n if (/Mac|iPhone|iPad|iPod/i.test(ua)) {\n return /iPhone|iPad|iPod/i.test(ua) ? \"iPhone\" : \"MacIntel\";\n }\n if (/Win/i.test(ua)) {\n return \"Win32\";\n }\n if (/Linux/i.test(ua)) {\n return /Android/i.test(ua) ? \"Linux armv8l\" : \"Linux x86_64\";\n }\n if (/CrOS/i.test(ua)) {\n return \"CrOS\";\n }\n return navigator.platform || \"Unknown\";\n}\nfunction detectBrowser() {\n const ua = navigator.userAgent;\n const platform = getPlatform();\n let name = \"Unknown\";\n let version = \"0\";\n let majorVersion = 0;\n let isSmartTV = false;\n let isLegacyTV = false;\n let supportsModernJS2 = true;\n if (/Web0S|webOS/i.test(ua)) {\n name = \"LG WebOS\";\n isSmartTV = true;\n const match = ua.match(/Web0S[/\\s]*([\\d.]+)/i);\n version = match && match[1] ? match[1] : \"Unknown\";\n if (version !== \"Unknown\") {\n const parts = version.split(\".\");\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n }\n } else if (/Tizen/i.test(ua)) {\n name = \"Samsung Tizen\";\n isSmartTV = true;\n const match = ua.match(/Tizen[/\\s]*([\\d.]+)/i);\n version = match && match[1] ? match[1] : \"Unknown\";\n if (version !== \"Unknown\") {\n const parts = version.split(\".\");\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = \"Smart TV\";\n isSmartTV = true;\n } else if (/NetCast/i.test(ua)) {\n name = \"LG NetCast\";\n isSmartTV = true;\n isLegacyTV = true;\n } else if (/BRAVIA/i.test(ua)) {\n name = \"Sony BRAVIA\";\n isSmartTV = true;\n }\n const chromeVersion = getChromeVersion(ua);\n const webkitVersion = getWebKitVersion(ua);\n if (chromeVersion > 0) {\n if (!isSmartTV) {\n name = \"Chrome\";\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n }\n if (chromeVersion < 50) {\n supportsModernJS2 = false;\n isLegacyTV = true;\n }\n }\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS2 = false;\n if (isSmartTV) {\n isLegacyTV = true;\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 };\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 userAgent: navigator.userAgent\n });\n}\nfunction getBrowserConfigOverrides() {\n const browser = detectBrowser();\n const overrides = {};\n if (browser.isSmartTV) {\n overrides.allowNativeHls = true;\n }\n return overrides;\n}\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/StormcloudVideoPlayer.ts\nvar StormcloudVideoPlayer = class {\n constructor(config) {\n this.attached = false;\n this.inAdBreak = false;\n this.ptsDriftEmaMs = 0;\n this.isLiveStream = false;\n this.nativeHlsMode = false;\n this.videoSrcProtection = null;\n this.bufferedSegmentsCount = 0;\n this.shouldAutoplayAfterBuffering = false;\n this.hasInitialBufferCompleted = false;\n initializePolyfills();\n const browserOverrides = getBrowserConfigOverrides();\n this.config = { ...config, ...browserOverrides };\n this.video = config.videoElement;\n logBrowserInfo(config.debugAdTiming);\n if (!this.config.licenseKey) {\n console.warn(\"[StormcloudVideoPlayer] No license key provided - ads will not work\");\n }\n this.adPlayer = createAdStormPlayer(this.video, {\n licenseKey: this.config.licenseKey || \"\",\n debug: this.config.debugAdTiming ?? false\n });\n }\n async load() {\n if (!this.attached) {\n this.attach();\n }\n if (this.shouldUseNativeHls()) {\n this.nativeHlsMode = true;\n this.videoSrcProtection = this.config.src;\n this.video.src = this.config.src;\n this.isLiveStream = this.config.lowLatencyMode ?? false;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Using native HLS playback:\", {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls\n });\n }\n this.adPlayer.initialize();\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {\n });\n }\n return;\n }\n this.hls = new Hls({\n enableWorker: true,\n backBufferLength: 30,\n liveDurationInfinity: true,\n lowLatencyMode: !!this.config.lowLatencyMode,\n maxLiveSyncPlaybackRate: this.config.lowLatencyMode ? 1.5 : 1,\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(Hls.Events.MEDIA_ATTACHED, () => {\n this.hls?.loadSource(this.config.src);\n });\n this.hls.on(Hls.Events.MANIFEST_PARSED, async () => {\n this.isLiveStream = this.hls?.levels?.some(\n (level) => level?.details?.live === true || level?.details?.type === \"LIVE\"\n ) ?? false;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Stream type detected:\", {\n isLive: this.isLiveStream\n });\n }\n this.adPlayer.initialize();\n this.bufferedSegmentsCount = 0;\n this.hasInitialBufferCompleted = false;\n this.shouldAutoplayAfterBuffering = !!this.config.autoplay;\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Waiting for\",\n minSegments,\n \"segments to buffer before playback\"\n );\n }\n if (minSegments === 0 || !this.config.autoplay) {\n this.hasInitialBufferCompleted = true;\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {\n });\n }\n }\n });\n this.hls.on(Hls.Events.FRAG_BUFFERED, async () => {\n if (this.hasInitialBufferCompleted) {\n return;\n }\n this.bufferedSegmentsCount++;\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Buffered segment ${this.bufferedSegmentsCount}/${minSegments}`\n );\n }\n if (this.bufferedSegmentsCount >= minSegments) {\n this.hasInitialBufferCompleted = true;\n if (this.shouldAutoplayAfterBuffering) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Initial buffer complete. Starting playback.`\n );\n }\n await this.video.play()?.catch((err) => {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Autoplay failed:\", err);\n }\n });\n }\n }\n });\n this.hls.on(Hls.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(Hls.Events.FRAG_CHANGED, (_evt, data) => {\n const frag = data?.frag;\n const tagList = frag?.tagList;\n if (!Array.isArray(tagList)) return;\n for (const entry of tagList) {\n let tag = \"\";\n let value = \"\";\n if (Array.isArray(entry)) {\n tag = String(entry[0] ?? \"\");\n value = String(entry[1] ?? \"\");\n } else if (typeof entry === \"string\") {\n const idx = entry.indexOf(\":\");\n if (idx >= 0) {\n tag = entry.substring(0, idx);\n value = entry.substring(idx + 1);\n } else {\n tag = entry;\n value = \"\";\n }\n }\n if (!tag) continue;\n if (tag.includes(\"EXT-X-CUE-OUT\")) {\n const durationSeconds = this.parseCueOutDuration(value);\n this.onScte35Marker({\n type: \"start\",\n ...durationSeconds !== void 0 ? { durationSeconds } : {},\n raw: { tag, value }\n });\n } else if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n const prog = this.parseCueOutCont(value);\n this.onScte35Marker({\n type: \"progress\",\n ...prog?.duration !== void 0 ? { durationSeconds: prog.duration } : {},\n ...prog?.elapsed !== void 0 ? { ptsSeconds: prog.elapsed } : {},\n raw: { tag, value }\n });\n } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value } });\n } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n const attrs = this.parseAttributeList(value);\n const hasScteOut = \"SCTE35-OUT\" in attrs;\n const hasScteIn = \"SCTE35-IN\" in attrs;\n const klass = String(attrs[\"CLASS\"] ?? \"\");\n const duration = this.toNumber(attrs[\"DURATION\"]) ?? this.toNumber(attrs[\"PLANNED-DURATION\"]);\n if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n this.onScte35Marker({\n type: \"start\",\n ...duration !== void 0 ? { durationSeconds: duration } : {},\n raw: { tag, value, attrs }\n });\n }\n if (hasScteIn) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value, attrs } });\n }\n }\n }\n });\n this.hls.on(Hls.Events.ERROR, (_evt, data) => {\n if (data?.fatal) {\n switch (data.type) {\n case Hls.ErrorTypes.NETWORK_ERROR:\n this.hls?.startLoad();\n break;\n case Hls.ErrorTypes.MEDIA_ERROR:\n this.hls?.recoverMediaError();\n break;\n default:\n this.destroy();\n break;\n }\n }\n });\n this.hls.attachMedia(this.video);\n }\n attach() {\n if (this.attached) return;\n this.attached = true;\n this.video.autoplay = !!this.config.autoplay;\n this.video.muted = !!this.config.muted;\n this.adPlayer.initialize();\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n this.adPlayer.on(\"all_ads_completed\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad completed - ending ad break\");\n }\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n this.adPlayer.on(\"ad_error\", () => {\n console.error(\"[StormcloudVideoPlayer] Ad error occurred\");\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n this.adPlayer.on(\"content_pause\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content paused for ad\");\n }\n });\n this.adPlayer.on(\"content_resume\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content resuming after ad\");\n }\n });\n this.timeUpdateHandler = () => {\n };\n this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n this.emptiedHandler = () => {\n if (this.nativeHlsMode && this.videoSrcProtection && !this.adPlayer.isAdPlaying()) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Video src was cleared, restoring\");\n }\n const currentTime = this.video.currentTime;\n const wasPaused = this.video.paused;\n this.video.src = this.videoSrcProtection;\n this.video.currentTime = currentTime;\n if (!wasPaused) {\n this.video.play().catch(() => {\n });\n }\n }\n };\n this.video.addEventListener(\"emptied\", this.emptiedHandler);\n }\n shouldUseNativeHls() {\n const streamType = this.getStreamType();\n if (streamType === \"other\") {\n return true;\n }\n const canNative = this.video.canPlayType(\"application/vnd.apple.mpegurl\");\n return !!(this.config.allowNativeHls && canNative);\n }\n onId3Tag(tag) {\n if (typeof tag.ptsSeconds === \"number\") {\n this.updatePtsDrift(tag.ptsSeconds);\n }\n const marker = this.parseScte35FromId3(tag);\n if (marker) {\n this.onScte35Marker(marker);\n }\n }\n parseScte35FromId3(tag) {\n const text = this.decodeId3ValueToText(tag.value);\n if (!text) return void 0;\n const cueOutMatch = text.match(/EXT-X-CUE-OUT(?::([^\\r\\n]*))?/i) || text.match(/CUE-OUT(?::([^\\r\\n]*))?/i);\n if (cueOutMatch) {\n const arg = (cueOutMatch[1] ?? \"\").trim();\n const dur = this.parseCueOutDuration(arg);\n return {\n type: \"start\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n ...dur !== void 0 ? { durationSeconds: dur } : {},\n raw: { id3: text }\n };\n }\n const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\\r\\n]*)/i);\n if (cueOutContMatch) {\n const arg = (cueOutContMatch[1] ?? \"\").trim();\n const cont = this.parseCueOutCont(arg);\n return {\n type: \"progress\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n ...cont?.duration !== void 0 ? { durationSeconds: cont.duration } : {},\n raw: { id3: text }\n };\n }\n const cueInMatch = text.match(/EXT-X-CUE-IN\\b/i) || text.match(/CUE-IN\\b/i);\n if (cueInMatch) {\n return {\n type: \"end\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n raw: { id3: text }\n };\n }\n return void 0;\n }\n decodeId3ValueToText(value) {\n try {\n if (typeof value === \"string\") return value;\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n const text = decoder.decode(value);\n if (text && /[\\x20-\\x7E]/.test(text)) return text;\n let out = \"\";\n for (let i = 0; i < value.length; i++) {\n out += String.fromCharCode(value[i]);\n }\n return out;\n } catch {\n return void 0;\n }\n }\n async onScte35Marker(marker) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] SCTE-35 marker detected:\", {\n type: marker.type,\n ptsSeconds: marker.ptsSeconds,\n durationSeconds: marker.durationSeconds,\n currentTime: this.video.currentTime\n });\n }\n if (marker.type === \"start\") {\n if (this.inAdBreak) {\n return;\n }\n this.inAdBreak = true;\n const durationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : 3e4;\n this.expectedAdBreakDurationMs = durationMs;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Starting ad break:\", {\n durationMs,\n durationSeconds: marker.durationSeconds\n });\n }\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n await this.handleAdStart(marker);\n if (this.expectedAdBreakDurationMs != null) {\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n if (marker.type === \"progress\" && this.inAdBreak) {\n if (marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;\n }\n return;\n }\n if (marker.type === \"end\") {\n if (!this.inAdBreak) return;\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = void 0;\n this.clearAdStopTimer();\n if (this.adPlayer.isAdPlaying()) {\n await this.adPlayer.stop();\n }\n this.handleAdPodComplete();\n return;\n }\n }\n async handleAdStart(marker) {\n const durationSeconds = marker.durationSeconds ?? 30;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Requesting ads for duration:\", durationSeconds);\n }\n try {\n await this.adPlayer.requestAds(String(durationSeconds));\n await this.adPlayer.play();\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Ad request/play failed:\", error);\n }\n this.handleAdPodComplete();\n }\n }\n parseCueOutDuration(value) {\n const num = parseFloat(value.trim());\n if (!Number.isNaN(num)) return num;\n const match = value.match(/(?:^|[,\\s])DURATION\\s*=\\s*([0-9.]+)/i) || value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n if (match && match[1] != null) {\n const d = parseFloat(match[1]);\n return Number.isNaN(d) ? void 0 : d;\n }\n return void 0;\n }\n parseCueOutCont(value) {\n const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n const res = {};\n if (elapsedMatch && elapsedMatch[1] != null) {\n const e = parseFloat(elapsedMatch[1]);\n if (!Number.isNaN(e)) res.elapsed = e;\n }\n if (durationMatch && durationMatch[1] != null) {\n const d = parseFloat(durationMatch[1]);\n if (!Number.isNaN(d)) res.duration = d;\n }\n if (\"elapsed\" in res || \"duration\" in res) return res;\n return void 0;\n }\n parseAttributeList(value) {\n const attrs = {};\n const regex = /([A-Z0-9-]+)=((\"[^\"]*\")|([^\",]*))(?:,|$)/gi;\n let match;\n while ((match = regex.exec(value)) !== null) {\n const key = match[1] ?? \"\";\n let rawVal = match[3] ?? match[4] ?? \"\";\n if (rawVal.startsWith('\"') && rawVal.endsWith('\"')) {\n rawVal = rawVal.slice(1, -1);\n }\n if (key) {\n attrs[key] = rawVal;\n }\n }\n return attrs;\n }\n toNumber(val) {\n if (val == null) return void 0;\n const n = typeof val === \"string\" ? parseFloat(val) : Number(val);\n return Number.isNaN(n) ? void 0 : n;\n }\n scheduleAdStopCountdown(remainingMs) {\n this.clearAdStopTimer();\n const ms = Math.max(0, Math.floor(remainingMs));\n if (ms === 0) {\n this.handleAdPodComplete();\n return;\n }\n this.adStopTimerId = window.setTimeout(() => {\n this.handleAdPodComplete();\n }, ms);\n }\n clearAdStopTimer() {\n if (this.adStopTimerId != null) {\n clearTimeout(this.adStopTimerId);\n this.adStopTimerId = void 0;\n }\n }\n updatePtsDrift(ptsSecondsSample) {\n const sampleMs = (this.video.currentTime - ptsSecondsSample) * 1e3;\n if (!Number.isFinite(sampleMs) || Math.abs(sampleMs) > 6e4) return;\n const alpha = 0.1;\n this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;\n }\n handleAdPodComplete() {\n this.clearAdStopTimer();\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = void 0;\n this.adPlayer.stop().catch(() => {\n });\n const restoredMuted = this.adPlayer.getOriginalMutedState();\n const restoredVolume = this.adPlayer.getOriginalVolume();\n if (this.video.muted !== restoredMuted) {\n this.video.muted = restoredMuted;\n }\n if (Math.abs(this.video.volume - restoredVolume) > 0.01) {\n this.video.volume = restoredVolume;\n }\n if (this.video.paused) {\n this.video.play()?.catch(() => {\n });\n }\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad break complete\");\n }\n }\n isAdPlaying() {\n return this.inAdBreak && this.adPlayer.isAdPlaying();\n }\n isShowingAds() {\n return this.adPlayer.isAdPlaying();\n }\n getStreamType() {\n const url = this.config.src.toLowerCase();\n if (url.includes(\".m3u8\") || url.includes(\"/hls/\") || url.includes(\"application/vnd.apple.mpegurl\")) {\n return \"hls\";\n }\n return \"other\";\n }\n shouldShowNativeControls() {\n const streamType = this.getStreamType();\n if (streamType === \"other\") {\n return !(this.config.showCustomControls ?? false);\n }\n return !!(this.config.allowNativeHls && !(this.config.showCustomControls ?? false));\n }\n toggleMute() {\n if (this.adPlayer.isAdPlaying()) {\n const currentMuted = this.video.muted;\n const newMutedState = !currentMuted;\n this.adPlayer.updateOriginalMutedState(newMutedState, this.video.volume);\n this.adPlayer.setAdVolume(newMutedState ? 0 : 1);\n } else {\n this.video.muted = !this.video.muted;\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n }\n }\n toggleFullscreen() {\n return new Promise((resolve, reject) => {\n if (!document.fullscreenElement) {\n const container = this.video.parentElement;\n if (!container) {\n reject(new Error(\"No parent container found for fullscreen\"));\n return;\n }\n container.requestFullscreen().then(() => resolve()).catch(reject);\n } else {\n document.exitFullscreen().then(() => resolve()).catch(reject);\n }\n });\n }\n isMuted() {\n return this.video.muted;\n }\n setMuted(muted) {\n this.video.muted = muted;\n this.adPlayer.updateOriginalMutedState(muted, this.video.volume);\n if (this.adPlayer.isAdPlaying()) {\n this.adPlayer.setAdVolume(muted ? 0 : 1);\n }\n }\n setVolume(volume) {\n const clampedVolume = Math.max(0, Math.min(1, volume));\n if (this.adPlayer.isAdPlaying()) {\n this.adPlayer.setAdVolume(clampedVolume);\n this.adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n } else {\n this.video.volume = clampedVolume;\n this.video.muted = clampedVolume === 0;\n this.adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n }\n }\n isFullscreen() {\n return !!document.fullscreenElement;\n }\n isLive() {\n return this.isLiveStream;\n }\n get videoElement() {\n return this.video;\n }\n resize() {\n if (this.adPlayer && this.adPlayer.isAdPlaying()) {\n const width = this.video.clientWidth || 640;\n const height = this.video.clientHeight || 360;\n this.adPlayer.resize(width, height);\n }\n }\n destroy() {\n this.clearAdStopTimer();\n if (this.timeUpdateHandler) {\n this.video.removeEventListener(\"timeupdate\", this.timeUpdateHandler);\n delete this.timeUpdateHandler;\n }\n if (this.emptiedHandler) {\n this.video.removeEventListener(\"emptied\", this.emptiedHandler);\n delete this.emptiedHandler;\n }\n this.hls?.destroy();\n this.adPlayer?.destroy();\n }\n getCurrentAdIndex() {\n return 0;\n }\n getTotalAdsInBreak() {\n return 1;\n }\n};\n\n// src/ui/StormcloudVideoPlayer.tsx\nimport {\n FaPlay,\n FaPause,\n FaVolumeUp,\n FaVolumeMute,\n FaVolumeDown,\n FaExpand,\n FaCompress,\n FaSpinner\n} from \"react-icons/fa\";\nimport { Fragment, jsx, jsxs } from \"react/jsx-runtime\";\nvar CRITICAL_PROPS = [\n \"src\",\n \"allowNativeHls\",\n \"licenseKey\",\n \"lowLatencyMode\",\n \"driftToleranceMs\"\n];\nvar StormcloudVideoPlayerComponent = React.memo(\n (props) => {\n const {\n src,\n autoplay,\n muted,\n lowLatencyMode,\n allowNativeHls,\n driftToleranceMs,\n immediateManifestAds,\n debugAdTiming,\n showCustomControls,\n hideLoadingIndicator,\n onVolumeToggle,\n onFullscreenToggle,\n onControlClick,\n onReady,\n wrapperClassName,\n wrapperStyle,\n className,\n style,\n controls,\n playsInline,\n preload,\n poster,\n children,\n licenseKey,\n minSegmentsBeforePlay,\n ...restVideoAttrs\n } = props;\n const videoRef = useRef(null);\n const playerRef = useRef(null);\n const bufferingTimeoutRef = useRef(null);\n const [adStatus, setAdStatus] = React.useState({ showAds: false, currentIndex: 0, totalAds: 0 });\n const [shouldShowNativeControls, setShouldShowNativeControls] = React.useState(true);\n const [isMuted, setIsMuted] = React.useState(false);\n const [isFullscreen, setIsFullscreen] = React.useState(false);\n const [isPlaying, setIsPlaying] = React.useState(false);\n const [currentTime, setCurrentTime] = React.useState(0);\n const [duration, setDuration] = React.useState(0);\n const [volume, setVolume] = React.useState(1);\n const [playbackRate, setPlaybackRate] = React.useState(1);\n const [showVolumeSlider, setShowVolumeSlider] = React.useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = React.useState(false);\n const [isLoading, setIsLoading] = React.useState(true);\n const [isBuffering, setIsBuffering] = React.useState(false);\n const [showCenterPlay, setShowCenterPlay] = React.useState(false);\n const [showLicenseWarning, setShowLicenseWarning] = React.useState(false);\n const [viewportWidth, setViewportWidth] = React.useState(\n typeof window !== \"undefined\" ? window.innerWidth : 1920\n );\n const [isPortrait, setIsPortrait] = React.useState(\n typeof window !== \"undefined\" ? window.innerHeight > window.innerWidth : false\n );\n const getResponsiveScale = () => {\n if (viewportWidth < 480) return 0.7;\n if (viewportWidth < 768) return 0.8;\n if (viewportWidth < 1024) return 0.9;\n return 1;\n };\n const responsiveScale = getResponsiveScale();\n const formatTime = (seconds) => {\n if (!isFinite(seconds)) return \"0:00:00\";\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor(seconds % 3600 / 60);\n const remainingSeconds = Math.floor(seconds % 60);\n return `${hours}:${minutes.toString().padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n };\n const handlePlayPause = () => {\n if (videoRef.current) {\n if (videoRef.current.paused) {\n const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n } else {\n videoRef.current.pause();\n setShowCenterPlay(true);\n }\n }\n };\n const handleCenterPlayClick = () => {\n if (videoRef.current && videoRef.current.paused) {\n const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n }\n };\n const handleTimelineSeek = (e) => {\n if (videoRef.current && duration > 0 && isFinite(duration)) {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const progress = Math.max(0, Math.min(1, clickX / rect.width));\n const newTime = progress * duration;\n if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n videoRef.current.currentTime = newTime;\n }\n }\n };\n const handleVolumeChange = (newVolume) => {\n if (playerRef.current && isFinite(newVolume)) {\n const clampedVolume = Math.max(0, Math.min(1, newVolume));\n playerRef.current.setVolume(clampedVolume);\n }\n };\n const handlePlaybackRateChange = (rate) => {\n if (videoRef.current && isFinite(rate) && rate > 0) {\n videoRef.current.playbackRate = rate;\n }\n setShowSpeedMenu(false);\n };\n const isHlsStream = src?.toLowerCase().includes(\".m3u8\") || src?.toLowerCase().includes(\"/hls/\");\n const shouldShowEnhancedControls = showCustomControls && (isHlsStream ? allowNativeHls : true);\n const criticalPropsKey = useMemo(() => {\n return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n }, [\n src,\n allowNativeHls,\n licenseKey,\n lowLatencyMode,\n driftToleranceMs\n ]);\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const el = videoRef.current;\n if (!el || !src) return;\n if (!licenseKey) {\n setShowLicenseWarning(true);\n setIsLoading(false);\n console.warn(\n \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n );\n return;\n }\n setShowLicenseWarning(false);\n if (debugAdTiming) {\n console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n }\n if (playerRef.current) {\n try {\n playerRef.current.destroy();\n } catch {\n }\n playerRef.current = null;\n }\n const cfg = {\n src,\n videoElement: el\n };\n if (autoplay !== void 0) cfg.autoplay = autoplay;\n if (muted !== void 0) cfg.muted = muted;\n if (lowLatencyMode !== void 0) cfg.lowLatencyMode = lowLatencyMode;\n if (allowNativeHls !== void 0) cfg.allowNativeHls = allowNativeHls;\n if (driftToleranceMs !== void 0)\n cfg.driftToleranceMs = driftToleranceMs;\n if (immediateManifestAds !== void 0)\n cfg.immediateManifestAds = immediateManifestAds;\n if (debugAdTiming !== void 0) cfg.debugAdTiming = debugAdTiming;\n if (showCustomControls !== void 0)\n cfg.showCustomControls = showCustomControls;\n if (onVolumeToggle !== void 0) cfg.onVolumeToggle = onVolumeToggle;\n if (onFullscreenToggle !== void 0)\n cfg.onFullscreenToggle = onFullscreenToggle;\n if (onControlClick !== void 0) cfg.onControlClick = onControlClick;\n if (licenseKey !== void 0) cfg.licenseKey = licenseKey;\n if (minSegmentsBeforePlay !== void 0)\n cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n const player = new StormcloudVideoPlayer(cfg);\n playerRef.current = player;\n player.load().then(() => {\n const showNative = player.shouldShowNativeControls();\n setShouldShowNativeControls(showNative);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n );\n }\n onReady?.(player);\n }).catch((error) => {\n console.error(\n \"StormcloudVideoPlayer: Failed to load player:\",\n error\n );\n setIsLoading(false);\n onReady?.(player);\n });\n return () => {\n try {\n player.destroy();\n } catch {\n }\n playerRef.current = null;\n };\n }, [criticalPropsKey]);\n 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 useEffect(() => {\n if (!playerRef.current) return;\n const checkAdStatus = () => {\n if (playerRef.current) {\n const showAds = playerRef.current.isShowingAds();\n const currentIndex = playerRef.current.getCurrentAdIndex();\n const totalAds = playerRef.current.getTotalAdsInBreak();\n setAdStatus((prev) => {\n if (prev.showAds !== showAds || prev.currentIndex !== currentIndex || prev.totalAds !== totalAds) {\n return { showAds, currentIndex, totalAds };\n }\n return prev;\n });\n }\n };\n const interval = setInterval(checkAdStatus, 100);\n return () => clearInterval(interval);\n }, []);\n 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 useEffect(() => {\n if (!playerRef.current || !videoRef.current) return;\n const updateStates = () => {\n if (playerRef.current && videoRef.current) {\n setIsMuted(playerRef.current.isMuted());\n setIsPlaying(!videoRef.current.paused);\n const currentTimeValue = videoRef.current.currentTime;\n setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n const durationValue = videoRef.current.duration;\n setDuration(isFinite(durationValue) ? durationValue : 0);\n const volumeValue = videoRef.current.volume;\n setVolume(\n isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n );\n const rateValue = videoRef.current.playbackRate;\n setPlaybackRate(\n isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n );\n }\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n const interval = setInterval(updateStates, 200);\n const handleFullscreenChange = () => {\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () => {\n clearInterval(interval);\n document.removeEventListener(\n \"fullscreenchange\",\n handleFullscreenChange\n );\n };\n }, []);\n useEffect(() => {\n if (!videoRef.current) return;\n const handleLoadedMetadata = () => {\n if (videoRef.current) {\n const video2 = videoRef.current;\n void video2.offsetHeight;\n }\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleLoadedData = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadeddata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleLoadStart = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadstart, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleCanPlay = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplay, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n const handleCanPlayThrough = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n const handleWaiting = () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n }\n bufferingTimeoutRef.current = window.setTimeout(() => {\n setIsBuffering(true);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n videoRef.current?.readyState,\n \"- showing spinner, isBuffering=true\"\n );\n }\n }, 300);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: waiting, readyState:\",\n videoRef.current?.readyState,\n \"- buffering delay started (300ms)\"\n );\n }\n };\n const handlePlaying = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n setShowCenterPlay(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: playing, readyState:\",\n videoRef.current?.readyState,\n \"- playback started, isLoading=false, isBuffering=false\"\n );\n }\n };\n const handlePause = () => {\n if (playerRef.current && !playerRef.current.isShowingAds()) {\n setShowCenterPlay(true);\n } else {\n setShowCenterPlay(false);\n }\n };\n const handleEnded = () => {\n setShowCenterPlay(true);\n };\n const video = videoRef.current;\n video.addEventListener(\"loadstart\", handleLoadStart);\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"playing\", handlePlaying);\n video.addEventListener(\"pause\", handlePause);\n video.addEventListener(\"ended\", handleEnded);\n if (video.paused) {\n setShowCenterPlay(true);\n }\n return () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n video.removeEventListener(\"loadstart\", handleLoadStart);\n video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"playing\", handlePlaying);\n video.removeEventListener(\"pause\", handlePause);\n video.removeEventListener(\"ended\", handleEnded);\n };\n }, [debugAdTiming]);\n return /* @__PURE__ */ jsxs(Fragment, { children: [\n /* @__PURE__ */ jsx(\"style\", { children: `\n @keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n \n .stormcloud-loading-hidden .stormcloud-loading-indicator {\n display: none !important;\n }\n \n .stormcloud-video-wrapper:fullscreen {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n .stormcloud-video-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n *:fullscreen {\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n }\n ` }),\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n className: `stormcloud-video-wrapper ${wrapperClassName || \"\"}`,\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n position: isFullscreen ? \"fixed\" : \"relative\",\n top: isFullscreen ? 0 : void 0,\n left: isFullscreen ? 0 : void 0,\n overflow: \"hidden\",\n width: isFullscreen ? \"100vw\" : \"100%\",\n height: isFullscreen ? \"100vh\" : \"auto\",\n minHeight: isFullscreen ? \"100vh\" : \"auto\",\n maxWidth: isFullscreen ? \"100vw\" : \"100%\",\n maxHeight: isFullscreen ? \"100vh\" : \"none\",\n zIndex: isFullscreen ? 999999 : void 0,\n backgroundColor: isFullscreen ? \"#000\" : void 0,\n borderRadius: isFullscreen ? 0 : void 0,\n boxShadow: isFullscreen ? \"none\" : void 0,\n ...wrapperStyle\n },\n children: [\n /* @__PURE__ */ jsx(\n \"video\",\n {\n ref: videoRef,\n className,\n style: {\n display: \"block\",\n width: \"100%\",\n height: isFullscreen ? \"100%\" : \"auto\",\n maxWidth: \"100%\",\n maxHeight: isFullscreen ? \"100%\" : \"none\",\n objectFit: isFullscreen ? \"cover\" : \"contain\",\n backgroundColor: \"#000\",\n aspectRatio: isFullscreen ? \"unset\" : void 0,\n ...style\n },\n controls: shouldShowNativeControls && controls && !showCustomControls,\n playsInline,\n preload,\n poster,\n ...restVideoAttrs,\n children\n }\n ),\n (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ jsx(\n FaSpinner,\n {\n className: \"stormcloud-loading-indicator\",\n size: 42,\n color: \"white\",\n style: {\n position: \"absolute\",\n top: \"calc(50% - 21px)\",\n left: \"calc(50% - 21px)\",\n zIndex: 20,\n animation: \"spin 1s linear infinite\",\n filter: \"drop-shadow(0 3px 6px rgba(0, 0, 0, 0.8))\"\n }\n }\n ),\n showLicenseWarning && /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 25,\n background: \"linear-gradient(135deg, rgba(220, 38, 38, 0.95) 0%, rgba(185, 28, 28, 0.9) 100%)\",\n color: \"white\",\n padding: \"24px 32px\",\n borderRadius: \"16px\",\n backdropFilter: \"blur(20px)\",\n border: \"2px solid rgba(255, 255, 255, 0.2)\",\n boxShadow: \"0 20px 60px rgba(0, 0, 0, 0.6), inset 0 2px 0 rgba(255, 255, 255, 0.2)\",\n textAlign: \"center\",\n maxWidth: \"400px\",\n margin: \"0 16px\"\n },\n children: [\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n fontSize: \"20px\",\n fontWeight: \"bold\",\n marginBottom: \"12px\",\n color: \"#ffffff\",\n textShadow: \"0 2px 4px rgba(0, 0, 0, 0.5)\"\n },\n children: \"License Key Required\"\n }\n ),\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n fontSize: \"14px\",\n lineHeight: \"1.5\",\n color: \"rgba(255, 255, 255, 0.9)\",\n textShadow: \"0 1px 2px rgba(0, 0, 0, 0.3)\"\n },\n children: [\n \"Please provide a valid license key to use the Stormcloud Video Player.\",\n /* @__PURE__ */ jsx(\"br\", {}),\n \"Contact your administrator for licensing information.\"\n ]\n }\n )\n ]\n }\n ),\n showCenterPlay && !isLoading && !isBuffering && !showLicenseWarning && !adStatus.showAds && /* @__PURE__ */ jsx(\n \"div\",\n {\n onClick: handleCenterPlayClick,\n style: {\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 15,\n cursor: \"pointer\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\",\n borderRadius: \"50%\",\n width: \"100px\",\n height: \"100px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n border: \"3px solid rgba(255, 255, 255, 0.8)\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\"\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.95) 0%, rgba(40, 40, 40, 0.9) 100%)\";\n target.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.9), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.9)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\";\n target.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.8)\";\n },\n title: \"Play\",\n children: /* @__PURE__ */ jsx(\n FaPlay,\n {\n size: 36,\n color: \"white\",\n style: {\n marginLeft: \"6px\",\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\"\n }\n }\n )\n }\n ),\n shouldShowEnhancedControls && !showLicenseWarning ? /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: 0,\n left: 0,\n right: 0,\n background: \"linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.8) 100%)\",\n padding: \"20px 16px 16px\",\n zIndex: 10\n },\n children: [\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"8px\",\n background: \"linear-gradient(90deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%)\",\n borderRadius: \"8px\",\n marginBottom: \"16px\",\n cursor: \"pointer\",\n position: \"relative\",\n backdropFilter: \"blur(5px)\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n boxShadow: \"inset 0 2px 4px rgba(0, 0, 0, 0.2)\"\n },\n onClick: handleTimelineSeek,\n children: [\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n height: \"100%\",\n background: \"linear-gradient(90deg, rgba(139, 92, 246, 0.9) 0%, rgba(59, 130, 246, 0.8) 50%, rgba(34, 197, 94, 0.9) 100%)\",\n borderRadius: \"8px\",\n width: `${duration > 0 ? currentTime / duration * 100 : 0}%`,\n transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 2px 8px rgba(139, 92, 246, 0.4)\"\n }\n }\n ),\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n top: \"-6px\",\n right: `${duration > 0 ? 100 - currentTime / duration * 100 : 100}%`,\n width: \"20px\",\n height: \"20px\",\n background: \"linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(240, 240, 240, 0.9) 100%)\",\n borderRadius: \"50%\",\n border: \"3px solid rgba(139, 92, 246, 0.8)\",\n boxShadow: \"0 4px 16px rgba(139, 92, 246, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.8)\",\n transform: \"translateX(50%)\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\"\n }\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n color: \"white\",\n flexWrap: viewportWidth < 768 ? \"wrap\" : \"nowrap\",\n gap: `${8 * responsiveScale}px`\n },\n children: [\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n flexWrap: viewportWidth < 480 ? \"wrap\" : \"nowrap\"\n },\n children: [\n /* @__PURE__ */ jsx(\n \"button\",\n {\n onClick: handlePlayPause,\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n backdropFilter: \"blur(12px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${10 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n minWidth: `${48 * responsiveScale}px`,\n minHeight: `${48 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n target.style.boxShadow = \"0 12px 48px rgba(0, 0, 0, 0.6), 0 6px 24px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n target.style.boxShadow = \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n },\n title: isPlaying ? \"Pause\" : \"Play\",\n children: isPlaying ? /* @__PURE__ */ jsx(\n FaPause,\n {\n size: Math.max(16, 20 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n ) : /* @__PURE__ */ jsx(\n FaPlay,\n {\n size: Math.max(16, 20 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n )\n }\n ),\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\"\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false),\n children: [\n /* @__PURE__ */ jsx(\n \"button\",\n {\n onClick: () => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: isMuted ? \"Unmute\" : \"Mute\",\n children: isMuted || volume === 0 ? /* @__PURE__ */ jsx(\n FaVolumeMute,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n ) : volume < 0.5 ? /* @__PURE__ */ jsx(\n FaVolumeDown,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n ) : /* @__PURE__ */ jsx(\n FaVolumeUp,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n )\n }\n ),\n showVolumeSlider && /* @__PURE__ */ jsxs(Fragment, { children: [\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false)\n }\n ),\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.88) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(15px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"1px solid rgba(255, 255, 255, 0.15)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\",\n zIndex: 10,\n transition: \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.6), 0 6px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 0 24px rgba(59, 130, 246, 0.3)\";\n e.currentTarget.style.borderColor = \"rgba(59, 130, 246, 0.4)\";\n },\n onMouseLeave: (e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\";\n e.currentTarget.style.borderColor = \"rgba(255, 255, 255, 0.15)\";\n },\n children: /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n },\n onMouseLeave: (e) => {\n },\n onMouseDown: (e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n const handleMouseMove = (moveEvent) => {\n if (!sliderElement) return;\n const rect2 = sliderElement.getBoundingClientRect();\n const y2 = moveEvent.clientY - rect2.top;\n const percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));\n handleVolumeChange(percentage2);\n };\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n const rect = sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n onClick: (e) => {\n e.stopPropagation();\n const rect = e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n children: [\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background: \"linear-gradient(180deg, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0.15) 100%)\",\n borderRadius: \"4px\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.2)\"\n }\n }\n ),\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background: \"linear-gradient(180deg, rgba(96, 165, 250, 1) 0%, rgba(59, 130, 246, 0.95) 50%, rgba(37, 99, 235, 0.9) 100%)\",\n borderRadius: \"4px\",\n transition: \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow: \"0 0 8px rgba(59, 130, 246, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3)\"\n }\n }\n ),\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `calc(${(isMuted ? 0 : volume) * 100}% - 7px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"14px\",\n height: \"14px\",\n background: \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n boxShadow: \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\",\n transition: \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\"\n },\n onMouseEnter: (e) => {\n e.currentTarget.style.boxShadow = \"0 3px 10px rgba(0, 0, 0, 0.4), 0 0 0 3px rgba(59, 130, 246, 0.5), 0 0 20px rgba(59, 130, 246, 0.6)\";\n e.currentTarget.style.cursor = \"grab\";\n },\n onMouseLeave: (e) => {\n e.currentTarget.style.boxShadow = \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\";\n },\n onMouseDown: (e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n },\n onMouseUp: (e) => {\n e.currentTarget.style.cursor = \"grab\";\n }\n }\n )\n ]\n }\n )\n }\n )\n ] })\n ]\n }\n ),\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n color: \"rgba(255, 255, 255, 0.9)\",\n display: viewportWidth < 480 ? \"none\" : \"block\"\n },\n children: [\n formatTime(currentTime),\n \" / \",\n formatTime(duration)\n ]\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`\n },\n children: [\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: viewportWidth < 600 ? \"none\" : \"block\"\n },\n children: [\n /* @__PURE__ */ jsxs(\n \"button\",\n {\n onClick: () => setShowSpeedMenu(!showSpeedMenu),\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px ${14 * responsiveScale}px`,\n borderRadius: `${14 * responsiveScale}px`,\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n fontWeight: \"700\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${56 * responsiveScale}px`,\n minHeight: `${40 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 32px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: \"Playback Speed\",\n children: [\n playbackRate,\n \"x\"\n ]\n }\n ),\n showSpeedMenu && /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n right: 0,\n marginBottom: \"12px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.95) 100%)\",\n backdropFilter: \"blur(20px)\",\n borderRadius: \"12px\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n overflow: \"hidden\",\n minWidth: \"90px\",\n boxShadow: \"0 16px 48px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.1)\"\n },\n children: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map(\n (speed) => /* @__PURE__ */ jsxs(\n \"button\",\n {\n onClick: () => handlePlaybackRateChange(speed),\n style: {\n display: \"block\",\n width: \"100%\",\n padding: \"10px 16px\",\n background: playbackRate === speed ? \"linear-gradient(135deg, rgba(99, 102, 241, 0.8) 0%, rgba(139, 92, 246, 0.6) 100%)\" : \"transparent\",\n border: \"none\",\n color: \"white\",\n cursor: \"pointer\",\n fontSize: \"13px\",\n fontFamily: \"monospace\",\n fontWeight: \"600\",\n textAlign: \"center\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n borderBottom: speed !== 2 ? \"1px solid rgba(255, 255, 255, 0.05)\" : \"none\"\n },\n onMouseEnter: (e) => {\n if (playbackRate !== speed) {\n e.target.style.background = \"linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.05) 100%)\";\n }\n },\n onMouseLeave: (e) => {\n if (playbackRate !== speed) {\n e.target.style.background = \"transparent\";\n }\n },\n children: [\n speed,\n \"x\"\n ]\n },\n speed\n )\n )\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ jsx(\n \"button\",\n {\n onClick: () => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n children: isFullscreen ? /* @__PURE__ */ jsx(\n FaCompress,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n ) : /* @__PURE__ */ jsx(\n FaExpand,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n )\n }\n )\n ]\n }\n )\n ]\n }\n )\n ]\n }\n ) }) : showCustomControls && !showLicenseWarning && /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `${10 * responsiveScale}px`,\n right: `${10 * responsiveScale}px`,\n transform: \"none\",\n display: \"flex\",\n flexDirection: isPortrait ? \"column\" : \"row\",\n gap: `${10 * responsiveScale}px`,\n zIndex: 10\n },\n children: [\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\"\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false),\n children: [\n /* @__PURE__ */ jsx(\n \"button\",\n {\n onClick: () => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow: \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`\n },\n title: isMuted ? \"Unmute\" : \"Mute\",\n children: isMuted || volume === 0 ? /* @__PURE__ */ jsx(\n FaVolumeMute,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : volume < 0.5 ? /* @__PURE__ */ jsx(\n FaVolumeDown,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : /* @__PURE__ */ jsx(\n FaVolumeUp,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n )\n }\n ),\n showVolumeSlider && /* @__PURE__ */ jsxs(Fragment, { children: [\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false)\n }\n ),\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.96) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(20px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"2px solid rgba(255, 255, 255, 0.7)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\",\n zIndex: 10,\n transition: \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.9), 0 6px 16px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 24px rgba(96, 165, 250, 0.4)\";\n e.currentTarget.style.borderColor = \"rgba(96, 165, 250, 0.8)\";\n },\n onMouseLeave: (e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\";\n e.currentTarget.style.borderColor = \"rgba(255, 255, 255, 0.7)\";\n },\n children: /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\"\n },\n onMouseDown: (e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n const handleMouseMove = (moveEvent) => {\n if (!sliderElement) return;\n const rect2 = sliderElement.getBoundingClientRect();\n const y2 = moveEvent.clientY - rect2.top;\n const percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));\n handleVolumeChange(percentage2);\n };\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n const rect = sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n onClick: (e) => {\n e.stopPropagation();\n const rect = e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n children: [\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background: \"linear-gradient(180deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.5) 100%)\",\n borderRadius: \"4px\",\n border: \"1px solid rgba(255, 255, 255, 0.4)\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.3)\"\n }\n }\n ),\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background: \"linear-gradient(180deg, rgba(125, 211, 252, 1) 0%, rgba(96, 165, 250, 0.98) 50%, rgba(59, 130, 246, 0.95) 100%)\",\n borderRadius: \"4px\",\n transition: \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow: \"0 0 12px rgba(96, 165, 250, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.4)\"\n }\n }\n ),\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `calc(${(isMuted ? 0 : volume) * 100}% - 8px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"16px\",\n height: \"16px\",\n background: \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n border: \"2px solid rgba(96, 165, 250, 0.9)\",\n boxShadow: \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\",\n transition: \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\"\n },\n onMouseEnter: (e) => {\n e.currentTarget.style.boxShadow = \"0 4px 12px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(96, 165, 250, 0.6), 0 0 24px rgba(96, 165, 250, 0.7)\";\n e.currentTarget.style.cursor = \"grab\";\n },\n onMouseLeave: (e) => {\n e.currentTarget.style.boxShadow = \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\";\n },\n onMouseDown: (e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n },\n onMouseUp: (e) => {\n e.currentTarget.style.cursor = \"grab\";\n }\n }\n )\n ]\n }\n )\n }\n )\n ] })\n ]\n }\n ),\n /* @__PURE__ */ jsx(\n \"button\",\n {\n onClick: () => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow: \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`\n },\n title: isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n children: isFullscreen ? /* @__PURE__ */ jsx(\n FaCompress,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : /* @__PURE__ */ jsx(\n FaExpand,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n )\n }\n )\n ]\n }\n ),\n onControlClick && /* @__PURE__ */ 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\nimport React3, { Component as Component4, Suspense } from \"react\";\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 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\nimport { lazy as reactLazy } from \"react\";\nvar lazy = reactLazy;\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\nimport { Component } from \"react\";\nvar HlsPlayer = class extends 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.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 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\nimport { Component as Component2 } from \"react\";\nvar FilePlayer = class extends Component2 {\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\nimport React2, { Component as Component3 } from \"react\";\nvar SEEK_ON_PLAY_EXPIRY = 5e3;\nvar Player = class extends Component3 {\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 React2.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 ? 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 \"driftToleranceMs\",\n \"immediateManifestAds\",\n \"debugAdTiming\",\n \"showCustomControls\",\n \"licenseKey\",\n \"adFailsafeTimeoutMs\",\n \"minSegmentsBeforePlay\",\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 Component4 {\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 React3.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 React3.createElement(\n Wrapper,\n {\n ref: wrapperRef,\n style: { ...style, width, height },\n ...attributes\n },\n React3.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\n// src/utils/tracking.ts\nvar cachedBrowserId = null;\nfunction getClientInfo() {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = navigator.deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: screen?.orientation?.type || \"\",\n pixelDepth: screen?.pixelDepth\n };\n let deviceType = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim() : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"NetCast\") || ua.includes(\"LG\"))) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n if (ua.includes(\"Android\") && (maxTouchPoints === 0 || ua.includes(\"Google TV\") || ua.includes(\"XiaoMi\"))) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n isWebApp = window.matchMedia(\"(display-mode: standalone)\").matches || window.navigator.standalone === true || window.screen?.orientation?.angle !== void 0;\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState\n };\n}\nasync function getBrowserID(clientInfo) {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n const fingerprintString = JSON.stringify(clientInfo);\n if (typeof crypto !== \"undefined\" && crypto.subtle && crypto.subtle.digest) {\n try {\n await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n let encodedData;\n if (typeof TextEncoder !== \"undefined\") {\n encodedData = new TextEncoder().encode(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\n const buffer = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i++) {\n buffer[i] = utf8.charCodeAt(i);\n }\n encodedData = buffer;\n }\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n const timestamp = Date.now().toString(16).padStart(12, \"0\");\n const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\nasync function sendInitialTracking(licenseKey) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = {\n browserId,\n ...clientInfo\n };\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(trackingData)\n }\n );\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\nasync function sendHeartbeat(licenseKey) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const heartbeatData = {\n browserId,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n };\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(heartbeatData)\n }\n );\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n } catch (error) {\n console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n }\n}\n\n// src/sdk/hlsAdPlayer.ts\nimport Hls2 from \"hls.js\";\nvar UNSUPPORTED_VIDEO_EXTENSIONS2 = [\".flv\", \".f4v\", \".swf\", \".wmv\", \".avi\", \".mov\", \".mkv\", \".mp4\", \".webm\"];\nfunction getFileExtension2(url) {\n try {\n const pathname = new URL(url, \"http://dummy\").pathname;\n const lastDot = pathname.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || \"\").toLowerCase();\n }\n}\nfunction isUnsupportedForHls(url) {\n const ext = getFileExtension2(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS2.indexOf(ext) !== -1;\n}\nfunction replaceFlvExtension2(url) {\n const ext = getFileExtension2(url);\n if (ext === \".flv\") {\n return url.replace(/\\.flv(\\?|$)/i, \".mp4$1\");\n }\n return url;\n}\nfunction createHlsAdPlayer(contentVideo, options) {\n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = /* @__PURE__ */ new Map();\n const licenseKey = options?.licenseKey;\n const mainHlsInstance = options?.mainHlsInstance;\n let adVideoElement;\n let adHls;\n let adContainerEl;\n let currentAd;\n let sessionId;\n 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 buildVastUrl(durationSeconds) {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n const metadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5e3,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48e3,\n bitrate: 128\n }\n };\n const metadataStr = encodeURIComponent(JSON.stringify(metadata));\n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\n }\n function fireTrackingPixels(urls) {\n if (!urls || urls.length === 0) return;\n urls.forEach((url) => {\n try {\n let trackingUrl = url;\n if (sessionId) {\n trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}session_id=${sessionId}`;\n }\n if (licenseKey) {\n trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}license_key=${licenseKey}`;\n }\n const img = new Image(1, 1);\n img.src = trackingUrl;\n console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n }\n });\n }\n function getMainStreamQuality() {\n if (!mainHlsInstance || !mainHlsInstance.levels) {\n return null;\n }\n const currentLevel = mainHlsInstance.currentLevel;\n if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n const autoLevel = mainHlsInstance.loadLevel;\n if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n const level2 = mainHlsInstance.levels[autoLevel];\n return {\n width: level2.width || 1920,\n height: level2.height || 1080,\n bitrate: level2.bitrate || 5e6\n };\n }\n return null;\n }\n const level = mainHlsInstance.levels[currentLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5e6\n };\n }\n function selectBestMediaFile(mediaFiles) {\n if (mediaFiles.length === 0) {\n throw new Error(\"No media files available\");\n }\n const firstFile = mediaFiles[0];\n if (!firstFile) {\n throw new Error(\"No media files available\");\n }\n if (mediaFiles.length === 1) {\n return firstFile;\n }\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n console.log(\n \"[HlsAdPlayer] No main stream quality info, using first media file\"\n );\n return firstFile;\n }\n console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\n const scoredFiles = mediaFiles.map((file) => {\n const widthDiff = Math.abs(file.width - mainQuality.width);\n const heightDiff = Math.abs(file.height - mainQuality.height);\n const resolutionDiff = widthDiff + heightDiff;\n const fileBitrate = (file.bitrate || 5e3) * 1e3;\n const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n const score = resolutionDiff * 2 + bitrateDiff / 1e3;\n return { file, score, resolutionDiff, bitrateDiff };\n });\n scoredFiles.sort((a, b) => a.score - b.score);\n const bestMatch = scoredFiles[0];\n if (!bestMatch) {\n console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n return firstFile;\n }\n console.log(\"[HlsAdPlayer] Selected media file:\", {\n url: bestMatch.file.url,\n resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n bitrate: bestMatch.file.bitrate,\n score: bestMatch.score,\n resolutionDiff: bestMatch.resolutionDiff,\n bitrateDiff: bestMatch.bitrateDiff\n });\n return bestMatch.file;\n }\n function parseVastXml(xmlString) {\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\n \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n parserError.textContent\n );\n return null;\n }\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n return null;\n }\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n const isNoAdAvailable = adId === \"empty\" || title.toLowerCase().includes(\"no ad available\") || title.toLowerCase() === \"no ad available\";\n const durationText = xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + parseInt(durationParts[2] || \"0\", 10);\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles = [];\n console.log(\n `[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n );\n mediaFileElements.forEach((mf, index) => {\n const type = mf.getAttribute(\"type\") || \"\";\n let 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 originalUrl = url;\n url = replaceFlvExtension2(url);\n if (url !== originalUrl) {\n console.log(`[HlsAdPlayer] Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n if (isUnsupportedForHls(url)) {\n const ext = getFileExtension2(url);\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored: unsupported format (extension: ${ext}, declared type: ${type})`\n );\n return;\n }\n if (type === \"application/x-mpegURL\" || type.includes(\"m3u8\")) {\n if (!url) {\n console.warn(\n `[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`\n );\n return;\n }\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0\n });\n console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);\n } else {\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not HLS)`\n );\n }\n });\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n \"[HlsAdPlayer] No ads available (VAST response indicates no ads)\"\n );\n } else {\n console.warn(\"[HlsAdPlayer] No HLS media files found in VAST XML\");\n }\n return null;\n }\n const trackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: []\n };\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n const clickThrough = xmlDoc.querySelector(\"ClickThrough\")?.textContent?.trim();\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough\n };\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n return null;\n }\n }\n async function fetchAndParseVastAd(url) {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n const vastXml = await response.text();\n console.log(\"[HlsAdPlayer] VAST XML received\");\n console.log(\n \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n vastXml.substring(0, 2e3)\n );\n return parseVastXml(vastXml);\n }\n function createAdVideoElement() {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.playsInline = true;\n video.muted = false;\n video.volume = 1;\n console.log(\n `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n );\n return video;\n }\n function setupAdEventListeners() {\n if (!adVideoElement || !currentAd) return;\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!currentAd || !adVideoElement) return;\n const progress = adVideoElement.currentTime / currentAd.duration;\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.firstQuartile);\n }\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(currentAd.trackingUrls.midpoint);\n }\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);\n }\n });\n adVideoElement.addEventListener(\"playing\", () => {\n if (!currentAd || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(currentAd.trackingUrls.start);\n console.log(\"[HlsAdPlayer] Ad started playing\");\n });\n adVideoElement.addEventListener(\"ended\", () => {\n if (!currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(currentAd.trackingUrls.complete);\n console.log(\"[HlsAdPlayer] Ad completed\");\n handleAdComplete();\n });\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[HlsAdPlayer] Ad video error:\", e);\n if (currentAd) {\n fireTrackingPixels(currentAd.trackingUrls.error);\n }\n handleAdError();\n });\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd) return;\n if (adVideoElement.muted) {\n fireTrackingPixels(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels(currentAd.trackingUrls.unmute);\n }\n });\n adVideoElement.addEventListener(\"pause\", () => {\n if (currentAd && !adVideoElement.ended) {\n fireTrackingPixels(currentAd.trackingUrls.pause);\n }\n });\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && adVideoElement.currentTime > 0) {\n fireTrackingPixels(currentAd.trackingUrls.resume);\n }\n });\n }\n function setAdPlayingFlag(isPlaying) {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n function handleAdComplete() {\n console.log(\"[HlsAdPlayer] Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n emit(\"content_resume\");\n const timeoutId = window.setTimeout(() => {\n if (destroyed) {\n console.log(\"[HlsAdPlayer] Player destroyed, skipping post-completion check\");\n return;\n }\n const stillInPod = contentVideo.dataset.stormcloudAdPlaying === \"true\";\n if (stillInPod) {\n console.log(\n \"[HlsAdPlayer] Still in ad pod - keeping ad container visible (black screen)\"\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n }\n const idx = pendingTimeouts.indexOf(timeoutId);\n if (idx !== -1) {\n pendingTimeouts.splice(idx, 1);\n }\n }, 50);\n pendingTimeouts.push(timeoutId);\n }\n function handleAdError() {\n console.log(\"[HlsAdPlayer] Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n const previousMutedState = contentVideo.muted;\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n console.log(\n `[HlsAdPlayer] Restored mute state: ${previousMutedState} -> ${originalMutedState}`\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (!options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n contentVideo.play().catch(() => {\n });\n }\n }\n emit(\"ad_error\");\n }\n return {\n initialize() {\n console.log(\"[HlsAdPlayer] Initializing\");\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n async requestAds(duration) {\n console.log(\"[HlsAdPlayer] Requesting ads for duration:\", duration);\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 durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n const vastUrl = buildVastUrl(durationSeconds);\n const ad = await fetchAndParseVastAd(vastUrl);\n if (!ad) {\n console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n currentAd = ad;\n console.log(\n `[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`\n );\n fireTrackingPixels(ad.trackingUrls.impression);\n trackingFired.impression = true;\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n async play() {\n if (!currentAd) {\n console.warn(\n \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n );\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n console.log(\"[HlsAdPlayer] Starting ad playback\");\n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(\n 0,\n Math.min(1, contentVolume || originalVolume)\n );\n if (!options?.continueLiveStreamDuringAds) {\n contentVideo.pause();\n console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n } else {\n console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n }\n console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n if (adVideoElement) {\n const adVolume = originalMutedState ? 0 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\n console.log(\n `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`\n );\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n emit(\"content_pause\");\n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available for ad\");\n }\n console.log(`[HlsAdPlayer] Loading ad from: ${mediaFile.url}`);\n if (Hls2.isSupported()) {\n if (adHls) {\n adHls.destroy();\n }\n adHls = new Hls2({\n enableWorker: true,\n lowLatencyMode: false\n });\n adHls.loadSource(mediaFile.url);\n adHls.attachMedia(adVideoElement);\n adHls.on(Hls2.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(Hls2.Events.ERROR, (event, data) => {\n console.error(\"[HlsAdPlayer] HLS error:\", data);\n if (data.fatal) {\n handleAdError();\n }\n });\n } else if (adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n } else {\n throw new Error(\"HLS not supported\");\n }\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n async stop() {\n console.log(\"[HlsAdPlayer] Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n currentAd = void 0;\n },\n destroy() {\n console.log(\"[HlsAdPlayer] Destroying\");\n destroyed = true;\n for (const timeoutId of pendingTimeouts) {\n clearTimeout(timeoutId);\n }\n pendingTimeouts = [];\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = void 0;\n }\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n adContainerEl = void 0;\n currentAd = void 0;\n listeners.clear();\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width, height) {\n console.log(`[HlsAdPlayer] Resizing to ${width}x${height}`);\n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n on(event, listener) {\n if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());\n listeners.get(event).add(listener);\n },\n off(event, listener) {\n listeners.get(event)?.delete(listener);\n },\n updateOriginalMutedState(muted, volume) {\n const nextVolume = typeof volume === \"number\" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;\n console.log(\n `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n );\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n getOriginalMutedState() {\n return originalMutedState;\n },\n getOriginalVolume() {\n return originalVolume;\n },\n setAdVolume(volume) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n }\n },\n getAdVolume() {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }\n };\n}\nexport {\n IS_BROWSER,\n IS_GLOBAL,\n IS_IOS,\n IS_SAFARI,\n SUPPORTS_DASH,\n SUPPORTS_HLS,\n StormcloudPlayer_default as StormcloudPlayer,\n StormcloudVideoPlayer,\n StormcloudVideoPlayerComponent,\n canPlay,\n createAdStormPlayer,\n createHlsAdPlayer,\n createStormcloudPlayer,\n StormcloudVideoPlayerComponent as default,\n detectBrowser,\n getBrowserConfigOverrides,\n getBrowserID,\n getClientInfo,\n initializePolyfills,\n isMediaStream,\n lazy,\n logBrowserInfo,\n merge,\n omit,\n parseQuery,\n players_default as players,\n randomString,\n sendHeartbeat,\n sendInitialTracking,\n supportsFeature,\n supportsModernJS,\n supportsWebKitPresentationMode\n};\n","import React, { useEffect, useRef, useMemo } from \"react\";\nimport { StormcloudVideoPlayer } from \"../player/StormcloudVideoPlayer\";\nimport type { StormcloudVideoPlayerConfig } from \"../types\";\nimport {\n FaPlay,\n FaPause,\n FaVolumeUp,\n FaVolumeMute,\n FaVolumeDown,\n FaExpand,\n FaCompress,\n FaSpinner,\n} from \"react-icons/fa\";\n\nexport type StormcloudVideoPlayerProps = Omit<\n StormcloudVideoPlayerConfig,\n \"videoElement\"\n> &\n React.VideoHTMLAttributes<HTMLVideoElement> & {\n onReady?: (player: StormcloudVideoPlayer) => void;\n wrapperClassName?: string;\n wrapperStyle?: React.CSSProperties;\n licenseKey?: string;\n };\n\nconst CRITICAL_PROPS = [\n \"src\",\n \"allowNativeHls\",\n \"licenseKey\",\n \"lowLatencyMode\",\n \"driftToleranceMs\",\n] as const;\n\nexport const StormcloudVideoPlayerComponent: React.FC<StormcloudVideoPlayerProps> =\n React.memo(\n (props) => {\n const {\n src,\n autoplay,\n muted,\n lowLatencyMode,\n allowNativeHls,\n driftToleranceMs,\n immediateManifestAds,\n debugAdTiming,\n showCustomControls,\n hideLoadingIndicator,\n onVolumeToggle,\n onFullscreenToggle,\n onControlClick,\n onReady,\n wrapperClassName,\n wrapperStyle,\n className,\n style,\n controls,\n playsInline,\n preload,\n poster,\n children,\n licenseKey,\n minSegmentsBeforePlay,\n ...restVideoAttrs\n } = props;\n\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const playerRef = useRef<StormcloudVideoPlayer | null>(null);\n const bufferingTimeoutRef = useRef<number | null>(null);\n const [adStatus, setAdStatus] = React.useState<{\n showAds: boolean;\n currentIndex: number;\n totalAds: number;\n }>({ showAds: false, currentIndex: 0, totalAds: 0 });\n\n const [shouldShowNativeControls, setShouldShowNativeControls] =\n React.useState(true);\n\n const [isMuted, setIsMuted] = React.useState(false);\n const [isFullscreen, setIsFullscreen] = React.useState(false);\n const [isPlaying, setIsPlaying] = React.useState(false);\n const [currentTime, setCurrentTime] = React.useState(0);\n const [duration, setDuration] = React.useState(0);\n const [volume, setVolume] = React.useState(1);\n const [playbackRate, setPlaybackRate] = React.useState(1);\n const [showVolumeSlider, setShowVolumeSlider] = React.useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = React.useState(false);\n const [isLoading, setIsLoading] = React.useState(true);\n const [isBuffering, setIsBuffering] = React.useState(false);\n const [showCenterPlay, setShowCenterPlay] = React.useState(false);\n const [showLicenseWarning, setShowLicenseWarning] = React.useState(false);\n const [viewportWidth, setViewportWidth] = React.useState(\n typeof window !== \"undefined\" ? window.innerWidth : 1920\n );\n const [isPortrait, setIsPortrait] = React.useState(\n typeof window !== \"undefined\"\n ? window.innerHeight > window.innerWidth\n : false\n );\n\n const getResponsiveScale = () => {\n if (viewportWidth < 480) return 0.7;\n if (viewportWidth < 768) return 0.8;\n if (viewportWidth < 1024) return 0.9;\n return 1;\n };\n\n const responsiveScale = getResponsiveScale();\n\n const formatTime = (seconds: number): string => {\n if (!isFinite(seconds)) return \"0:00:00\";\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const remainingSeconds = Math.floor(seconds % 60);\n return `${hours}:${minutes\n .toString()\n .padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n };\n\n const handlePlayPause = () => {\n if (videoRef.current) {\n if (videoRef.current.paused) {\n const hasValidSource =\n videoRef.current.src ||\n (videoRef.current.currentSrc &&\n videoRef.current.currentSrc !== \"\") ||\n videoRef.current.readyState >= 1;\n\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n } else {\n videoRef.current.pause();\n setShowCenterPlay(true);\n }\n }\n };\n\n const handleCenterPlayClick = () => {\n if (videoRef.current && videoRef.current.paused) {\n const hasValidSource =\n videoRef.current.src ||\n (videoRef.current.currentSrc &&\n videoRef.current.currentSrc !== \"\") ||\n videoRef.current.readyState >= 1;\n\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n }\n };\n\n const handleTimelineSeek = (e: React.MouseEvent<HTMLDivElement>) => {\n if (videoRef.current && duration > 0 && isFinite(duration)) {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const progress = Math.max(0, Math.min(1, clickX / rect.width));\n const newTime = progress * duration;\n\n if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n videoRef.current.currentTime = newTime;\n }\n }\n };\n\n const handleVolumeChange = (newVolume: number) => {\n if (playerRef.current && isFinite(newVolume)) {\n const clampedVolume = Math.max(0, Math.min(1, newVolume));\n playerRef.current.setVolume(clampedVolume);\n }\n };\n\n const handlePlaybackRateChange = (rate: number) => {\n if (videoRef.current && isFinite(rate) && rate > 0) {\n videoRef.current.playbackRate = rate;\n }\n setShowSpeedMenu(false);\n };\n\n const isHlsStream =\n src?.toLowerCase().includes(\".m3u8\") ||\n src?.toLowerCase().includes(\"/hls/\");\n const shouldShowEnhancedControls =\n showCustomControls && (isHlsStream ? allowNativeHls : true);\n\n const criticalPropsKey = useMemo(() => {\n return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n }, [\n src,\n allowNativeHls,\n licenseKey,\n lowLatencyMode,\n driftToleranceMs,\n ]);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const el = videoRef.current;\n if (!el || !src) return;\n\n if (!licenseKey) {\n setShowLicenseWarning(true);\n setIsLoading(false);\n console.warn(\n \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n );\n return;\n }\n\n setShowLicenseWarning(false);\n\n if (debugAdTiming) {\n console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n }\n\n if (playerRef.current) {\n try {\n playerRef.current.destroy();\n } catch {}\n playerRef.current = null;\n }\n\n const cfg: StormcloudVideoPlayerConfig = {\n src,\n videoElement: el,\n } as StormcloudVideoPlayerConfig;\n if (autoplay !== undefined) cfg.autoplay = autoplay;\n if (muted !== undefined) cfg.muted = muted;\n if (lowLatencyMode !== undefined) cfg.lowLatencyMode = lowLatencyMode;\n if (allowNativeHls !== undefined) cfg.allowNativeHls = allowNativeHls;\n if (driftToleranceMs !== undefined)\n cfg.driftToleranceMs = driftToleranceMs;\n if (immediateManifestAds !== undefined)\n cfg.immediateManifestAds = immediateManifestAds;\n if (debugAdTiming !== undefined) cfg.debugAdTiming = debugAdTiming;\n if (showCustomControls !== undefined)\n cfg.showCustomControls = showCustomControls;\n if (onVolumeToggle !== undefined) cfg.onVolumeToggle = onVolumeToggle;\n if (onFullscreenToggle !== undefined)\n cfg.onFullscreenToggle = onFullscreenToggle;\n if (onControlClick !== undefined) cfg.onControlClick = onControlClick;\n if (licenseKey !== undefined) cfg.licenseKey = licenseKey;\n if (minSegmentsBeforePlay !== undefined)\n cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n\n const player = new StormcloudVideoPlayer(cfg);\n playerRef.current = player;\n player\n .load()\n .then(() => {\n const showNative = player.shouldShowNativeControls();\n setShouldShowNativeControls(showNative);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n );\n }\n onReady?.(player);\n })\n .catch((error) => {\n console.error(\n \"StormcloudVideoPlayer: Failed to load player:\",\n error\n );\n setIsLoading(false);\n onReady?.(player);\n });\n\n return () => {\n try {\n player.destroy();\n } catch {}\n playerRef.current = null;\n };\n }, [criticalPropsKey]);\n\n useEffect(() => {\n if (!playerRef.current) return;\n\n try {\n if (autoplay !== undefined && playerRef.current.videoElement) {\n playerRef.current.videoElement.autoplay = autoplay;\n }\n if (muted !== undefined && !playerRef.current.isShowingAds()) {\n playerRef.current.setMuted(muted);\n }\n } catch (error) {\n console.warn(\"Failed to update player properties:\", error);\n }\n }, [autoplay, muted]);\n\n useEffect(() => {\n if (!playerRef.current) return;\n\n const checkAdStatus = () => {\n if (playerRef.current) {\n const showAds = playerRef.current.isShowingAds();\n const currentIndex = playerRef.current.getCurrentAdIndex();\n const totalAds = playerRef.current.getTotalAdsInBreak();\n\n setAdStatus((prev) => {\n if (\n prev.showAds !== showAds ||\n prev.currentIndex !== currentIndex ||\n prev.totalAds !== totalAds\n ) {\n return { showAds, currentIndex, totalAds };\n }\n return prev;\n });\n }\n };\n\n const interval = setInterval(checkAdStatus, 100);\n return () => clearInterval(interval);\n }, []);\n\n useEffect(() => {\n if (typeof window === \"undefined\" || !playerRef.current) return;\n\n const handleResize = () => {\n if (playerRef.current && videoRef.current) {\n if (typeof playerRef.current.resize === \"function\") {\n playerRef.current.resize();\n }\n }\n setViewportWidth(window.innerWidth);\n setIsPortrait(window.innerHeight > window.innerWidth);\n };\n\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n\n useEffect(() => {\n if (!playerRef.current || !videoRef.current) return;\n\n const updateStates = () => {\n if (playerRef.current && videoRef.current) {\n setIsMuted(playerRef.current.isMuted());\n setIsPlaying(!videoRef.current.paused);\n\n const currentTimeValue = videoRef.current.currentTime;\n setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n\n const durationValue = videoRef.current.duration;\n setDuration(isFinite(durationValue) ? durationValue : 0);\n\n const volumeValue = videoRef.current.volume;\n setVolume(\n isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n );\n\n const rateValue = videoRef.current.playbackRate;\n setPlaybackRate(\n isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n );\n }\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n\n const interval = setInterval(updateStates, 200);\n\n const handleFullscreenChange = () => {\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n\n return () => {\n clearInterval(interval);\n document.removeEventListener(\n \"fullscreenchange\",\n handleFullscreenChange\n );\n };\n }, []);\n\n useEffect(() => {\n if (!videoRef.current) return;\n\n const handleLoadedMetadata = () => {\n if (videoRef.current) {\n const video = videoRef.current;\n void video.offsetHeight;\n }\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleLoadedData = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadeddata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleLoadStart = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadstart, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleCanPlay = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplay, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n\n const handleCanPlayThrough = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n\n const handleWaiting = () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n }\n\n bufferingTimeoutRef.current = window.setTimeout(() => {\n setIsBuffering(true);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n videoRef.current?.readyState,\n \"- showing spinner, isBuffering=true\"\n );\n }\n }, 300);\n\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: waiting, readyState:\",\n videoRef.current?.readyState,\n \"- buffering delay started (300ms)\"\n );\n }\n };\n\n const handlePlaying = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n setShowCenterPlay(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: playing, readyState:\",\n videoRef.current?.readyState,\n \"- playback started, isLoading=false, isBuffering=false\"\n );\n }\n };\n\n const handlePause = () => {\n if (playerRef.current && !playerRef.current.isShowingAds()) {\n setShowCenterPlay(true);\n } else {\n setShowCenterPlay(false);\n }\n };\n\n const handleEnded = () => {\n setShowCenterPlay(true);\n };\n\n const video = videoRef.current;\n video.addEventListener(\"loadstart\", handleLoadStart);\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"playing\", handlePlaying);\n video.addEventListener(\"pause\", handlePause);\n video.addEventListener(\"ended\", handleEnded);\n\n if (video.paused) {\n setShowCenterPlay(true);\n }\n\n return () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n\n video.removeEventListener(\"loadstart\", handleLoadStart);\n video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"playing\", handlePlaying);\n video.removeEventListener(\"pause\", handlePause);\n video.removeEventListener(\"ended\", handleEnded);\n };\n }, [debugAdTiming]);\n\n return (\n <>\n <style>\n {`\n @keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n \n .stormcloud-loading-hidden .stormcloud-loading-indicator {\n display: none !important;\n }\n \n .stormcloud-video-wrapper:fullscreen {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n .stormcloud-video-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n *:fullscreen {\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n }\n `}\n </style>\n <div\n className={`stormcloud-video-wrapper ${wrapperClassName || \"\"}`}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n position: isFullscreen ? \"fixed\" : \"relative\",\n top: isFullscreen ? 0 : undefined,\n left: isFullscreen ? 0 : undefined,\n overflow: \"hidden\",\n width: isFullscreen ? \"100vw\" : \"100%\",\n height: isFullscreen ? \"100vh\" : \"auto\",\n minHeight: isFullscreen ? \"100vh\" : \"auto\",\n maxWidth: isFullscreen ? \"100vw\" : \"100%\",\n maxHeight: isFullscreen ? \"100vh\" : \"none\",\n zIndex: isFullscreen ? 999999 : undefined,\n backgroundColor: isFullscreen ? \"#000\" : undefined,\n borderRadius: isFullscreen ? 0 : undefined,\n boxShadow: isFullscreen ? \"none\" : undefined,\n ...wrapperStyle,\n }}\n >\n <video\n ref={videoRef}\n className={className}\n style={{\n display: \"block\",\n width: \"100%\",\n height: isFullscreen ? \"100%\" : \"auto\",\n maxWidth: \"100%\",\n maxHeight: isFullscreen ? \"100%\" : \"none\",\n objectFit: isFullscreen ? \"cover\" : \"contain\",\n backgroundColor: \"#000\",\n aspectRatio: isFullscreen ? \"unset\" : undefined,\n ...style,\n }}\n controls={\n shouldShowNativeControls && controls && !showCustomControls\n }\n playsInline={playsInline}\n preload={preload}\n poster={poster}\n {...restVideoAttrs}\n >\n {children}\n </video>\n\n {(isLoading || isBuffering) && !hideLoadingIndicator && (\n <FaSpinner\n className=\"stormcloud-loading-indicator\"\n size={42}\n color=\"white\"\n style={{\n position: \"absolute\",\n top: \"calc(50% - 21px)\",\n left: \"calc(50% - 21px)\",\n zIndex: 20,\n animation: \"spin 1s linear infinite\",\n filter: \"drop-shadow(0 3px 6px rgba(0, 0, 0, 0.8))\",\n }}\n />\n )}\n\n {showLicenseWarning && (\n <div\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 25,\n background:\n \"linear-gradient(135deg, rgba(220, 38, 38, 0.95) 0%, rgba(185, 28, 28, 0.9) 100%)\",\n color: \"white\",\n padding: \"24px 32px\",\n borderRadius: \"16px\",\n backdropFilter: \"blur(20px)\",\n border: \"2px solid rgba(255, 255, 255, 0.2)\",\n boxShadow:\n \"0 20px 60px rgba(0, 0, 0, 0.6), inset 0 2px 0 rgba(255, 255, 255, 0.2)\",\n textAlign: \"center\",\n maxWidth: \"400px\",\n margin: \"0 16px\",\n }}\n >\n <div\n style={{\n fontSize: \"20px\",\n fontWeight: \"bold\",\n marginBottom: \"12px\",\n color: \"#ffffff\",\n textShadow: \"0 2px 4px rgba(0, 0, 0, 0.5)\",\n }}\n >\n License Key Required\n </div>\n <div\n style={{\n fontSize: \"14px\",\n lineHeight: \"1.5\",\n color: \"rgba(255, 255, 255, 0.9)\",\n textShadow: \"0 1px 2px rgba(0, 0, 0, 0.3)\",\n }}\n >\n Please provide a valid license key to use the Stormcloud Video\n Player.\n <br />\n Contact your administrator for licensing information.\n </div>\n </div>\n )}\n\n {showCenterPlay &&\n !isLoading &&\n !isBuffering &&\n !showLicenseWarning &&\n !adStatus.showAds && (\n <div\n onClick={handleCenterPlayClick}\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 15,\n cursor: \"pointer\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\",\n borderRadius: \"50%\",\n width: \"100px\",\n height: \"100px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n border: \"3px solid rgba(255, 255, 255, 0.8)\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLElement;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.95) 0%, rgba(40, 40, 40, 0.9) 100%)\";\n target.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.9), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.9)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLElement;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\";\n target.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.8)\";\n }}\n title=\"Play\"\n >\n <FaPlay\n size={36}\n color=\"white\"\n style={{\n marginLeft: \"6px\",\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n }}\n />\n </div>\n )}\n\n {shouldShowEnhancedControls && !showLicenseWarning ? (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: 0,\n left: 0,\n right: 0,\n background:\n \"linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.8) 100%)\",\n padding: \"20px 16px 16px\",\n zIndex: 10,\n }}\n >\n <div\n style={{\n width: \"100%\",\n height: \"8px\",\n background:\n \"linear-gradient(90deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%)\",\n borderRadius: \"8px\",\n marginBottom: \"16px\",\n cursor: \"pointer\",\n position: \"relative\",\n backdropFilter: \"blur(5px)\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n boxShadow: \"inset 0 2px 4px rgba(0, 0, 0, 0.2)\",\n }}\n onClick={handleTimelineSeek}\n >\n <div\n style={{\n height: \"100%\",\n background:\n \"linear-gradient(90deg, rgba(139, 92, 246, 0.9) 0%, rgba(59, 130, 246, 0.8) 50%, rgba(34, 197, 94, 0.9) 100%)\",\n borderRadius: \"8px\",\n width: `${\n duration > 0 ? (currentTime / duration) * 100 : 0\n }%`,\n transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 2px 8px rgba(139, 92, 246, 0.4)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n top: \"-6px\",\n right: `${\n duration > 0\n ? 100 - (currentTime / duration) * 100\n : 100\n }%`,\n width: \"20px\",\n height: \"20px\",\n background:\n \"linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(240, 240, 240, 0.9) 100%)\",\n borderRadius: \"50%\",\n border: \"3px solid rgba(139, 92, 246, 0.8)\",\n boxShadow:\n \"0 4px 16px rgba(139, 92, 246, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.8)\",\n transform: \"translateX(50%)\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n />\n </div>\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n color: \"white\",\n flexWrap: viewportWidth < 768 ? \"wrap\" : \"nowrap\",\n gap: `${8 * responsiveScale}px`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n flexWrap: viewportWidth < 480 ? \"wrap\" : \"nowrap\",\n }}\n >\n <button\n onClick={handlePlayPause}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n backdropFilter: \"blur(12px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${10 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n minWidth: `${48 * responsiveScale}px`,\n minHeight: `${48 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n target.style.boxShadow =\n \"0 12px 48px rgba(0, 0, 0, 0.6), 0 6px 24px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n target.style.boxShadow =\n \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n }}\n title={isPlaying ? \"Pause\" : \"Play\"}\n >\n {isPlaying ? (\n <FaPause\n size={Math.max(16, 20 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n ) : (\n <FaPlay\n size={Math.max(16, 20 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n )}\n </button>\n\n <div\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\",\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n >\n <button\n onClick={() => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted || volume === 0 ? (\n <FaVolumeMute\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n ) : volume < 0.5 ? (\n <FaVolumeDown\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n ) : (\n <FaVolumeUp\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n )}\n </button>\n\n {showVolumeSlider && (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9,\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.88) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(15px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"1px solid rgba(255, 255, 255, 0.15)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\",\n zIndex: 10,\n transition:\n \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.6), 0 6px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 0 24px rgba(59, 130, 246, 0.3)\";\n e.currentTarget.style.borderColor =\n \"rgba(59, 130, 246, 0.4)\";\n }}\n onMouseLeave={(e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\";\n e.currentTarget.style.borderColor =\n \"rgba(255, 255, 255, 0.15)\";\n }}\n >\n <div\n style={{\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n // Hover effect removed\n }}\n onMouseLeave={(e) => {\n // Hover effect removed\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n\n const handleMouseMove = (\n moveEvent: MouseEvent\n ) => {\n if (!sliderElement) return;\n const rect =\n sliderElement.getBoundingClientRect();\n const y = moveEvent.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n };\n\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n\n const rect =\n sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n onClick={(e) => {\n e.stopPropagation();\n const rect =\n e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n >\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background:\n \"linear-gradient(180deg, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0.15) 100%)\",\n borderRadius: \"4px\",\n boxShadow:\n \"inset 0 1px 3px rgba(0, 0, 0, 0.2)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background:\n \"linear-gradient(180deg, rgba(96, 165, 250, 1) 0%, rgba(59, 130, 246, 0.95) 50%, rgba(37, 99, 235, 0.9) 100%)\",\n borderRadius: \"4px\",\n transition:\n \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow:\n \"0 0 8px rgba(59, 130, 246, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: `calc(${\n (isMuted ? 0 : volume) * 100\n }% - 7px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"14px\",\n height: \"14px\",\n background:\n \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n boxShadow:\n \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\",\n transition:\n \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 3px 10px rgba(0, 0, 0, 0.4), 0 0 0 3px rgba(59, 130, 246, 0.5), 0 0 20px rgba(59, 130, 246, 0.6)\";\n e.currentTarget.style.cursor = \"grab\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\";\n }}\n onMouseDown={(e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n }}\n onMouseUp={(e) => {\n e.currentTarget.style.cursor = \"grab\";\n }}\n />\n </div>\n </div>\n </>\n )}\n </div>\n\n <div\n style={{\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n color: \"rgba(255, 255, 255, 0.9)\",\n display: viewportWidth < 480 ? \"none\" : \"block\",\n }}\n >\n {formatTime(currentTime)} / {formatTime(duration)}\n </div>\n </div>\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n }}\n >\n <div\n style={{\n position: \"relative\",\n display: viewportWidth < 600 ? \"none\" : \"block\",\n }}\n >\n <button\n onClick={() => setShowSpeedMenu(!showSpeedMenu)}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px ${\n 14 * responsiveScale\n }px`,\n borderRadius: `${14 * responsiveScale}px`,\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n fontWeight: \"700\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${56 * responsiveScale}px`,\n minHeight: `${40 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 32px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title=\"Playback Speed\"\n >\n {playbackRate}x\n </button>\n\n {showSpeedMenu && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n right: 0,\n marginBottom: \"12px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.95) 100%)\",\n backdropFilter: \"blur(20px)\",\n borderRadius: \"12px\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n overflow: \"hidden\",\n minWidth: \"90px\",\n boxShadow:\n \"0 16px 48px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.1)\",\n }}\n >\n {[0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map(\n (speed) => (\n <button\n key={speed}\n onClick={() =>\n handlePlaybackRateChange(speed)\n }\n style={{\n display: \"block\",\n width: \"100%\",\n padding: \"10px 16px\",\n background:\n playbackRate === speed\n ? \"linear-gradient(135deg, rgba(99, 102, 241, 0.8) 0%, rgba(139, 92, 246, 0.6) 100%)\"\n : \"transparent\",\n border: \"none\",\n color: \"white\",\n cursor: \"pointer\",\n fontSize: \"13px\",\n fontFamily: \"monospace\",\n fontWeight: \"600\",\n textAlign: \"center\",\n transition:\n \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n borderBottom:\n speed !== 2\n ? \"1px solid rgba(255, 255, 255, 0.05)\"\n : \"none\",\n }}\n onMouseEnter={(e) => {\n if (playbackRate !== speed) {\n (\n e.target as HTMLElement\n ).style.background =\n \"linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.05) 100%)\";\n }\n }}\n onMouseLeave={(e) => {\n if (playbackRate !== speed) {\n (\n e.target as HTMLElement\n ).style.background = \"transparent\";\n }\n }}\n >\n {speed}x\n </button>\n )\n )}\n </div>\n )}\n </div>\n\n <button\n onClick={() => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current\n .toggleFullscreen()\n .catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title={\n isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"\n }\n >\n {isFullscreen ? (\n <FaCompress\n size={Math.max(14, 16 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n ) : (\n <FaExpand\n size={Math.max(14, 16 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n )}\n </button>\n </div>\n </div>\n </div>\n </>\n ) : (\n showCustomControls &&\n !showLicenseWarning && (\n <div\n style={{\n position: \"absolute\",\n bottom: `${10 * responsiveScale}px`,\n right: `${10 * responsiveScale}px`,\n transform: \"none\",\n display: \"flex\",\n flexDirection: isPortrait ? \"column\" : \"row\",\n gap: `${10 * responsiveScale}px`,\n zIndex: 10,\n }}\n >\n <div\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\",\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n >\n <button\n onClick={() => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow:\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`,\n }}\n title={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted || volume === 0 ? (\n <FaVolumeMute\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : volume < 0.5 ? (\n <FaVolumeDown\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : (\n <FaVolumeUp\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n )}\n </button>\n\n {showVolumeSlider && (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9,\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.96) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(20px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"2px solid rgba(255, 255, 255, 0.7)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\",\n zIndex: 10,\n transition:\n \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.9), 0 6px 16px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 24px rgba(96, 165, 250, 0.4)\";\n e.currentTarget.style.borderColor =\n \"rgba(96, 165, 250, 0.8)\";\n }}\n onMouseLeave={(e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\";\n e.currentTarget.style.borderColor =\n \"rgba(255, 255, 255, 0.7)\";\n }}\n >\n <div\n style={{\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\",\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n\n const handleMouseMove = (\n moveEvent: MouseEvent\n ) => {\n if (!sliderElement) return;\n const rect =\n sliderElement.getBoundingClientRect();\n const y = moveEvent.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n };\n\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n\n const rect =\n sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n onClick={(e) => {\n e.stopPropagation();\n const rect =\n e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n >\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background:\n \"linear-gradient(180deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.5) 100%)\",\n borderRadius: \"4px\",\n border: \"1px solid rgba(255, 255, 255, 0.4)\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.3)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background:\n \"linear-gradient(180deg, rgba(125, 211, 252, 1) 0%, rgba(96, 165, 250, 0.98) 50%, rgba(59, 130, 246, 0.95) 100%)\",\n borderRadius: \"4px\",\n transition:\n \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow:\n \"0 0 12px rgba(96, 165, 250, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.4)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: `calc(${\n (isMuted ? 0 : volume) * 100\n }% - 8px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"16px\",\n height: \"16px\",\n background:\n \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n border: \"2px solid rgba(96, 165, 250, 0.9)\",\n boxShadow:\n \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\",\n transition:\n \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 4px 12px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(96, 165, 250, 0.6), 0 0 24px rgba(96, 165, 250, 0.7)\";\n e.currentTarget.style.cursor = \"grab\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\";\n }}\n onMouseDown={(e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n }}\n onMouseUp={(e) => {\n e.currentTarget.style.cursor = \"grab\";\n }}\n />\n </div>\n </div>\n </>\n )}\n </div>\n\n <button\n onClick={() => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow:\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`,\n }}\n title={\n isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"\n }\n >\n {isFullscreen ? (\n <FaCompress\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : (\n <FaExpand\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n )}\n </button>\n </div>\n )\n )}\n\n {onControlClick && (\n <div\n onClick={onControlClick}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 1,\n cursor: \"pointer\",\n }}\n />\n )}\n </div>\n </>\n );\n },\n (prevProps, nextProps) => {\n for (const prop of CRITICAL_PROPS) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n const uiProps = [\n \"autoplay\",\n \"muted\",\n \"controls\",\n \"showCustomControls\",\n \"className\",\n \"style\",\n \"wrapperClassName\",\n \"wrapperStyle\",\n \"playsInline\",\n \"preload\",\n \"poster\",\n \"children\",\n ] as const;\n\n for (const prop of uiProps) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n const callbackProps = [\n \"onReady\",\n \"onVolumeToggle\",\n \"onFullscreenToggle\",\n \"onControlClick\",\n ] as const;\n for (const prop of callbackProps) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n return true;\n }\n );\n","import Hls from \"hls.js\";\nimport type {\n StormcloudVideoPlayerConfig,\n Scte35Marker,\n Id3TagInfo,\n AdController,\n} from \"../types\";\nimport { createAdStormPlayer } from \"../sdk/adstormPlayer\";\nimport { initializePolyfills } from \"../utils/polyfills\";\nimport { getBrowserConfigOverrides, logBrowserInfo } from \"../utils/browserCompat\";\n\nexport class StormcloudVideoPlayer {\n private readonly video: HTMLVideoElement;\n private readonly config: StormcloudVideoPlayerConfig;\n private hls?: Hls;\n private adPlayer: AdController;\n private attached = false;\n private inAdBreak = false;\n private expectedAdBreakDurationMs: number | undefined;\n private adStopTimerId: number | undefined;\n private ptsDriftEmaMs = 0;\n private isLiveStream: boolean = false;\n private nativeHlsMode: boolean = false;\n private videoSrcProtection: string | null = null;\n private bufferedSegmentsCount: number = 0;\n private shouldAutoplayAfterBuffering: boolean = false;\n private hasInitialBufferCompleted: boolean = false;\n private timeUpdateHandler?: (event: Event) => void;\n private emptiedHandler?: (event: Event) => void;\n\n constructor(config: StormcloudVideoPlayerConfig) {\n initializePolyfills();\n\n const browserOverrides = getBrowserConfigOverrides();\n this.config = { ...config, ...browserOverrides };\n this.video = config.videoElement;\n\n logBrowserInfo(config.debugAdTiming);\n\n if (!this.config.licenseKey) {\n console.warn(\"[StormcloudVideoPlayer] No license key provided - ads will not work\");\n }\n\n this.adPlayer = createAdStormPlayer(this.video, {\n licenseKey: this.config.licenseKey || \"\",\n debug: this.config.debugAdTiming ?? false,\n });\n }\n\n async load(): Promise<void> {\n if (!this.attached) {\n this.attach();\n }\n\n if (this.shouldUseNativeHls()) {\n this.nativeHlsMode = true;\n this.videoSrcProtection = this.config.src;\n this.video.src = this.config.src;\n\n this.isLiveStream = this.config.lowLatencyMode ?? false;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Using native HLS playback:\", {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls,\n });\n }\n\n this.adPlayer.initialize();\n\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {});\n }\n return;\n }\n\n this.hls = new Hls({\n enableWorker: true,\n backBufferLength: 30,\n liveDurationInfinity: true,\n lowLatencyMode: !!this.config.lowLatencyMode,\n maxLiveSyncPlaybackRate: this.config.lowLatencyMode ? 1.5 : 1.0,\n ...(this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {}),\n maxBufferLength: 30,\n maxMaxBufferLength: 600,\n maxBufferSize: 60 * 1000 * 1000,\n maxBufferHole: 0.5,\n highBufferWatchdogPeriod: 2,\n nudgeOffset: 0.1,\n nudgeMaxRetry: 3,\n startPosition: -1,\n });\n\n this.hls.on(Hls.Events.MEDIA_ATTACHED, () => {\n this.hls?.loadSource(this.config.src);\n });\n\n this.hls.on(Hls.Events.MANIFEST_PARSED, async () => {\n this.isLiveStream =\n this.hls?.levels?.some(\n (level) =>\n level?.details?.live === true || level?.details?.type === \"LIVE\"\n ) ?? false;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Stream type detected:\", {\n isLive: this.isLiveStream,\n });\n }\n\n this.adPlayer.initialize();\n\n this.bufferedSegmentsCount = 0;\n this.hasInitialBufferCompleted = false;\n this.shouldAutoplayAfterBuffering = !!this.config.autoplay;\n\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Waiting for\",\n minSegments,\n \"segments to buffer before playback\"\n );\n }\n\n if (minSegments === 0 || !this.config.autoplay) {\n this.hasInitialBufferCompleted = true;\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {});\n }\n }\n });\n\n this.hls.on(Hls.Events.FRAG_BUFFERED, async () => {\n if (this.hasInitialBufferCompleted) {\n return;\n }\n\n this.bufferedSegmentsCount++;\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Buffered segment ${this.bufferedSegmentsCount}/${minSegments}`\n );\n }\n\n if (this.bufferedSegmentsCount >= minSegments) {\n this.hasInitialBufferCompleted = true;\n\n if (this.shouldAutoplayAfterBuffering) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Initial buffer complete. Starting playback.`\n );\n }\n await this.video.play()?.catch((err) => {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Autoplay failed:\", err);\n }\n });\n }\n }\n });\n\n this.hls.on(Hls.Events.FRAG_PARSING_METADATA, (_evt, data: any) => {\n const id3Tags: Id3TagInfo[] = (data?.samples || []).map((s: any) => ({\n key: \"ID3\",\n value: s?.data,\n ptsSeconds: s?.pts,\n }));\n id3Tags.forEach((tag) => this.onId3Tag(tag));\n });\n\n this.hls.on(Hls.Events.FRAG_CHANGED, (_evt, data: any) => {\n const frag = data?.frag;\n const tagList: any[] | undefined = frag?.tagList;\n if (!Array.isArray(tagList)) return;\n\n for (const entry of tagList) {\n let tag = \"\";\n let value = \"\";\n if (Array.isArray(entry)) {\n tag = String(entry[0] ?? \"\");\n value = String(entry[1] ?? \"\");\n } else if (typeof entry === \"string\") {\n const idx = entry.indexOf(\":\");\n if (idx >= 0) {\n tag = entry.substring(0, idx);\n value = entry.substring(idx + 1);\n } else {\n tag = entry;\n value = \"\";\n }\n }\n\n if (!tag) continue;\n \n if (tag.includes(\"EXT-X-CUE-OUT\")) {\n const durationSeconds = this.parseCueOutDuration(value);\n this.onScte35Marker({\n type: \"start\",\n ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n raw: { tag, value },\n });\n } else if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n const prog = this.parseCueOutCont(value);\n this.onScte35Marker({\n type: \"progress\",\n ...(prog?.duration !== undefined ? { durationSeconds: prog.duration } : {}),\n ...(prog?.elapsed !== undefined ? { ptsSeconds: prog.elapsed } : {}),\n raw: { tag, value },\n });\n } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value } });\n } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n const attrs = this.parseAttributeList(value);\n const hasScteOut = \"SCTE35-OUT\" in attrs;\n const hasScteIn = \"SCTE35-IN\" in attrs;\n const klass = String(attrs[\"CLASS\"] ?? \"\");\n const duration = this.toNumber(attrs[\"DURATION\"]) ?? this.toNumber(attrs[\"PLANNED-DURATION\"]);\n\n if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n this.onScte35Marker({\n type: \"start\",\n ...(duration !== undefined ? { durationSeconds: duration } : {}),\n raw: { tag, value, attrs },\n });\n }\n if (hasScteIn) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value, attrs } });\n }\n }\n }\n });\n\n this.hls.on(Hls.Events.ERROR, (_evt, data) => {\n if (data?.fatal) {\n switch (data.type) {\n case Hls.ErrorTypes.NETWORK_ERROR:\n this.hls?.startLoad();\n break;\n case Hls.ErrorTypes.MEDIA_ERROR:\n this.hls?.recoverMediaError();\n break;\n default:\n this.destroy();\n break;\n }\n }\n });\n\n this.hls.attachMedia(this.video);\n }\n\n private attach(): void {\n if (this.attached) return;\n this.attached = true;\n this.video.autoplay = !!this.config.autoplay;\n this.video.muted = !!this.config.muted;\n\n this.adPlayer.initialize();\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n \n this.adPlayer.on(\"all_ads_completed\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad completed - ending ad break\");\n }\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n \n this.adPlayer.on(\"ad_error\", () => {\n console.error(\"[StormcloudVideoPlayer] Ad error occurred\");\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n \n this.adPlayer.on(\"content_pause\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content paused for ad\");\n }\n });\n \n this.adPlayer.on(\"content_resume\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content resuming after ad\");\n }\n });\n\n this.timeUpdateHandler = () => {\n };\n this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n\n this.emptiedHandler = () => {\n if (this.nativeHlsMode && this.videoSrcProtection && !this.adPlayer.isAdPlaying()) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Video src was cleared, restoring\");\n }\n const currentTime = this.video.currentTime;\n const wasPaused = this.video.paused;\n this.video.src = this.videoSrcProtection;\n this.video.currentTime = currentTime;\n if (!wasPaused) {\n this.video.play().catch(() => {});\n }\n }\n };\n this.video.addEventListener(\"emptied\", this.emptiedHandler);\n }\n\n private shouldUseNativeHls(): boolean {\n const streamType = this.getStreamType();\n if (streamType === \"other\") {\n return true;\n }\n const canNative = this.video.canPlayType(\"application/vnd.apple.mpegurl\");\n return !!(this.config.allowNativeHls && canNative);\n }\n\n private onId3Tag(tag: Id3TagInfo): void {\n if (typeof tag.ptsSeconds === \"number\") {\n this.updatePtsDrift(tag.ptsSeconds);\n }\n const marker = this.parseScte35FromId3(tag);\n if (marker) {\n this.onScte35Marker(marker);\n }\n }\n\n private parseScte35FromId3(tag: Id3TagInfo): Scte35Marker | undefined {\n const text = this.decodeId3ValueToText(tag.value);\n if (!text) return undefined;\n\n const cueOutMatch =\n text.match(/EXT-X-CUE-OUT(?::([^\\r\\n]*))?/i) ||\n text.match(/CUE-OUT(?::([^\\r\\n]*))?/i);\n if (cueOutMatch) {\n const arg = (cueOutMatch[1] ?? \"\").trim();\n const dur = this.parseCueOutDuration(arg);\n return {\n type: \"start\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n ...(dur !== undefined ? { durationSeconds: dur } : {}),\n raw: { id3: text },\n };\n }\n\n const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\\r\\n]*)/i);\n if (cueOutContMatch) {\n const arg = (cueOutContMatch[1] ?? \"\").trim();\n const cont = this.parseCueOutCont(arg);\n return {\n type: \"progress\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n ...(cont?.duration !== undefined ? { durationSeconds: cont.duration } : {}),\n raw: { id3: text },\n };\n }\n\n const cueInMatch = text.match(/EXT-X-CUE-IN\\b/i) || text.match(/CUE-IN\\b/i);\n if (cueInMatch) {\n return {\n type: \"end\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n raw: { id3: text },\n };\n }\n\n return undefined;\n }\n\n private decodeId3ValueToText(value: string | Uint8Array): string | undefined {\n try {\n if (typeof value === \"string\") return value;\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n const text = decoder.decode(value);\n if (text && /[\\x20-\\x7E]/.test(text)) return text;\n let out = \"\";\n for (let i = 0; i < value.length; i++) {\n out += String.fromCharCode(value[i]!);\n }\n return out;\n } catch {\n return undefined;\n }\n }\n\n private async onScte35Marker(marker: Scte35Marker): Promise<void> {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] SCTE-35 marker detected:\", {\n type: marker.type,\n ptsSeconds: marker.ptsSeconds,\n durationSeconds: marker.durationSeconds,\n currentTime: this.video.currentTime,\n });\n }\n\n if (marker.type === \"start\") {\n if (this.inAdBreak) {\n return;\n }\n\n this.inAdBreak = true;\n const durationMs = marker.durationSeconds != null\n ? marker.durationSeconds * 1000\n : 30000;\n \n this.expectedAdBreakDurationMs = durationMs;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Starting ad break:\", {\n durationMs,\n durationSeconds: marker.durationSeconds,\n });\n }\n\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n\n await this.handleAdStart(marker);\n\n if (this.expectedAdBreakDurationMs != null) {\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n\n if (marker.type === \"progress\" && this.inAdBreak) {\n if (marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1000;\n }\n return;\n }\n\n if (marker.type === \"end\") {\n if (!this.inAdBreak) return;\n \n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = undefined;\n this.clearAdStopTimer();\n\n if (this.adPlayer.isAdPlaying()) {\n await this.adPlayer.stop();\n }\n\n this.handleAdPodComplete();\n return;\n }\n }\n\n private async handleAdStart(marker: Scte35Marker): Promise<void> {\n const durationSeconds = marker.durationSeconds ?? 30;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Requesting ads for duration:\", durationSeconds);\n }\n\n try {\n await this.adPlayer.requestAds(String(durationSeconds));\n \n await this.adPlayer.play();\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Ad request/play failed:\", error);\n }\n this.handleAdPodComplete();\n }\n }\n\n private parseCueOutDuration(value: string): number | undefined {\n const num = parseFloat(value.trim());\n if (!Number.isNaN(num)) return num;\n const match =\n value.match(/(?:^|[,\\s])DURATION\\s*=\\s*([0-9.]+)/i) ||\n value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n if (match && match[1] != null) {\n const d = parseFloat(match[1]);\n return Number.isNaN(d) ? undefined : d;\n }\n return undefined;\n }\n\n private parseCueOutCont(value: string): { elapsed?: number; duration?: number } | undefined {\n const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n const res: { elapsed?: number; duration?: number } = {};\n if (elapsedMatch && elapsedMatch[1] != null) {\n const e = parseFloat(elapsedMatch[1]);\n if (!Number.isNaN(e)) res.elapsed = e;\n }\n if (durationMatch && durationMatch[1] != null) {\n const d = parseFloat(durationMatch[1]);\n if (!Number.isNaN(d)) res.duration = d;\n }\n if (\"elapsed\" in res || \"duration\" in res) return res;\n return undefined;\n }\n\n private parseAttributeList(value: string): Record<string, string> {\n const attrs: Record<string, string> = {};\n const regex = /([A-Z0-9-]+)=((\"[^\"]*\")|([^\",]*))(?:,|$)/gi;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(value)) !== null) {\n const key: string = (match[1] ?? \"\") as string;\n let rawVal: string = (match[3] ?? match[4] ?? \"\") as string;\n if (rawVal.startsWith('\"') && rawVal.endsWith('\"')) {\n rawVal = rawVal.slice(1, -1);\n }\n if (key) {\n attrs[key] = rawVal;\n }\n }\n return attrs;\n }\n\n private toNumber(val: unknown): number | undefined {\n if (val == null) return undefined;\n const n = typeof val === \"string\" ? parseFloat(val) : Number(val);\n return Number.isNaN(n) ? undefined : n;\n }\n\n private scheduleAdStopCountdown(remainingMs: number): void {\n this.clearAdStopTimer();\n const ms = Math.max(0, Math.floor(remainingMs));\n if (ms === 0) {\n this.handleAdPodComplete();\n return;\n }\n this.adStopTimerId = window.setTimeout(() => {\n this.handleAdPodComplete();\n }, ms) as unknown as number;\n }\n\n private clearAdStopTimer(): void {\n if (this.adStopTimerId != null) {\n clearTimeout(this.adStopTimerId);\n this.adStopTimerId = undefined;\n }\n }\n\n private updatePtsDrift(ptsSecondsSample: number): void {\n const sampleMs = (this.video.currentTime - ptsSecondsSample) * 1000;\n if (!Number.isFinite(sampleMs) || Math.abs(sampleMs) > 60000) return;\n const alpha = 0.1;\n this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;\n }\n\n private handleAdPodComplete(): void {\n this.clearAdStopTimer();\n \n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = undefined;\n\n this.adPlayer.stop().catch(() => {});\n\n const restoredMuted = this.adPlayer.getOriginalMutedState();\n const restoredVolume = this.adPlayer.getOriginalVolume();\n\n if (this.video.muted !== restoredMuted) {\n this.video.muted = restoredMuted;\n }\n if (Math.abs(this.video.volume - restoredVolume) > 0.01) {\n this.video.volume = restoredVolume;\n }\n\n if (this.video.paused) {\n this.video.play()?.catch(() => {});\n }\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad break complete\");\n }\n }\n\n isAdPlaying(): boolean {\n return this.inAdBreak && this.adPlayer.isAdPlaying();\n }\n\n isShowingAds(): boolean {\n return this.adPlayer.isAdPlaying();\n }\n\n getStreamType(): \"hls\" | \"other\" {\n const url = this.config.src.toLowerCase();\n if (\n url.includes(\".m3u8\") ||\n url.includes(\"/hls/\") ||\n url.includes(\"application/vnd.apple.mpegurl\")\n ) {\n return \"hls\";\n }\n return \"other\";\n }\n\n shouldShowNativeControls(): boolean {\n const streamType = this.getStreamType();\n if (streamType === \"other\") {\n return !(this.config.showCustomControls ?? false);\n }\n return !!(\n this.config.allowNativeHls && !(this.config.showCustomControls ?? false)\n );\n }\n\n toggleMute(): void {\n if (this.adPlayer.isAdPlaying()) {\n const currentMuted = this.video.muted;\n const newMutedState = !currentMuted;\n\n this.adPlayer.updateOriginalMutedState(newMutedState, this.video.volume);\n this.adPlayer.setAdVolume(newMutedState ? 0 : 1);\n } else {\n this.video.muted = !this.video.muted;\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n }\n }\n\n toggleFullscreen(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!document.fullscreenElement) {\n const container = this.video.parentElement;\n if (!container) {\n reject(new Error(\"No parent container found for fullscreen\"));\n return;\n }\n container\n .requestFullscreen()\n .then(() => resolve())\n .catch(reject);\n } else {\n document.exitFullscreen().then(() => resolve()).catch(reject);\n }\n });\n }\n\n isMuted(): boolean {\n return this.video.muted;\n }\n\n setMuted(muted: boolean): void {\n this.video.muted = muted;\n this.adPlayer.updateOriginalMutedState(muted, this.video.volume);\n\n if (this.adPlayer.isAdPlaying()) {\n this.adPlayer.setAdVolume(muted ? 0 : 1);\n }\n }\n\n setVolume(volume: number): void {\n const clampedVolume = Math.max(0, Math.min(1, volume));\n\n if (this.adPlayer.isAdPlaying()) {\n this.adPlayer.setAdVolume(clampedVolume);\n this.adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n } else {\n this.video.volume = clampedVolume;\n this.video.muted = clampedVolume === 0;\n this.adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n }\n }\n\n isFullscreen(): boolean {\n return !!document.fullscreenElement;\n }\n\n isLive(): boolean {\n return this.isLiveStream;\n }\n\n get videoElement(): HTMLVideoElement {\n return this.video;\n }\n\n resize(): void {\n if (this.adPlayer && this.adPlayer.isAdPlaying()) {\n const width = this.video.clientWidth || 640;\n const height = this.video.clientHeight || 360;\n this.adPlayer.resize(width, height);\n }\n }\n\n destroy(): void {\n this.clearAdStopTimer();\n\n if (this.timeUpdateHandler) {\n this.video.removeEventListener(\"timeupdate\", this.timeUpdateHandler);\n delete this.timeUpdateHandler;\n }\n if (this.emptiedHandler) {\n this.video.removeEventListener(\"emptied\", this.emptiedHandler);\n delete this.emptiedHandler;\n }\n\n this.hls?.destroy();\n this.adPlayer?.destroy();\n }\n\n getCurrentAdIndex(): number {\n return 0;\n }\n\n getTotalAdsInBreak(): number {\n return 1;\n }\n}\n","import type { AdController } from \"../types\";\n\ninterface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\nconst SUPPORTED_VIDEO_EXTENSIONS = ['.mp4', '.webm', '.ogg', '.m3u8', '.ts'];\nconst UNSUPPORTED_VIDEO_EXTENSIONS = ['.flv', '.f4v', '.swf', '.wmv', '.avi', '.mov', '.mkv'];\n\nfunction getFileExtension(url: string): string {\n try {\n const pathname = new URL(url, 'http://dummy').pathname;\n const lastDot = pathname.lastIndexOf('.');\n if (lastDot === -1) return '';\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf('.');\n if (lastDot === -1) return '';\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || '').toLowerCase();\n }\n}\n\nfunction isUnsupportedFormat(url: string): boolean {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\n\nfunction replaceFlvExtension(url: string): string {\n const ext = getFileExtension(url);\n if (ext === '.flv') {\n return url.replace(/\\.flv(\\?|$)/i, '.mp4$1');\n }\n return url;\n}\n\nfunction isSupportedFormat(url: string, mimeType: string): boolean {\n if (isUnsupportedFormat(url)) {\n return false;\n }\n \n const ext = getFileExtension(url);\n \n if (SUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1) {\n return true;\n }\n \n if (ext === '' || ext === '.') {\n return mimeType.includes('video/mp4') || \n mimeType.includes('video/webm') || \n mimeType.includes('m3u8') ||\n mimeType.includes('application/x-mpegurl');\n }\n \n return false;\n}\n\ninterface VastTrackingUrls {\n impression: string[];\n start: string[];\n firstQuartile: string[];\n midpoint: string[];\n thirdQuartile: string[];\n complete: string[];\n error: string[];\n}\n\ninterface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\ninterface AdStormMetadata {\n video?: {\n codec?: string;\n width?: number;\n height?: number;\n fps?: number;\n bitrate?: number;\n profile?: string;\n pix_fmt?: string;\n has_b_frames?: number;\n };\n audio?: {\n codec?: string;\n sample_rate?: number;\n bitrate?: number;\n };\n}\n\nexport interface AdStormPlayerOptions {\n licenseKey: string;\n debug?: boolean;\n}\n\nexport function createAdStormPlayer(\n contentVideo: HTMLVideoElement,\n options: AdStormPlayerOptions\n): AdController {\n const { licenseKey, debug = false } = options;\n \n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = new Map<string, Set<(payload?: any) => void>>();\n \n let adVideoElement: HTMLVideoElement | undefined;\n let adContainerEl: HTMLDivElement | undefined;\n let currentAd: VastAd | undefined;\n let destroyed = false;\n \n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n\n function log(...args: any[]): void {\n if (debug) {\n console.log(\"[AdStormPlayer]\", ...args);\n }\n }\n\n function emit(event: string, payload?: any): void {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch (error) {\n console.warn(`[AdStormPlayer] Error in event listener for ${event}:`, error);\n }\n }\n }\n\n function fireTrackingPixels(urls: string[]): void {\n if (!urls || urls.length === 0) return;\n \n urls.forEach((url) => {\n try {\n const img = new Image(1, 1);\n img.src = url;\n log(\"Fired tracking pixel:\", url);\n } catch (error) {\n console.warn(\"[AdStormPlayer] Error firing tracking pixel:\", error);\n }\n });\n }\n\n function buildVastUrl(durationSeconds: number, metadata?: AdStormMetadata): string {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n \n const defaultMetadata: AdStormMetadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5000,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0,\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48000,\n bitrate: 128,\n },\n };\n \n const finalMetadata = metadata || defaultMetadata;\n const metadataStr = encodeURIComponent(JSON.stringify(finalMetadata));\n \n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\n }\n\n function parseVastXml(xmlString: string): VastAd[] {\n const ads: VastAd[] = [];\n \n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n \n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\"[AdStormPlayer] XML parsing error:\", parserError.textContent);\n return [];\n }\n \n const adElements = xmlDoc.querySelectorAll(\"Ad\");\n \n adElements.forEach((adElement) => {\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n \n const durationText = adElement.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration =\n parseInt(durationParts[0] || \"0\", 10) * 3600 +\n parseInt(durationParts[1] || \"0\", 10) * 60 +\n parseFloat(durationParts[2] || \"0\");\n \n const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n \n mediaFileElements.forEach((mf) => {\n const type = mf.getAttribute(\"type\") || \"\";\n let url = mf.textContent?.trim() || \"\";\n const width = parseInt(mf.getAttribute(\"width\") || \"1920\", 10);\n const height = parseInt(mf.getAttribute(\"height\") || \"1080\", 10);\n const bitrate = mf.getAttribute(\"bitrate\") \n ? parseInt(mf.getAttribute(\"bitrate\")!, 10) \n : undefined;\n \n if (!url) {\n log(`Skipping empty MediaFile URL`);\n return;\n }\n \n const originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n log(`Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n \n if (isUnsupportedFormat(url)) {\n const ext = getFileExtension(url);\n log(`Skipping unsupported format: ${url} (extension: ${ext}, declared type: ${type})`);\n return;\n }\n \n if (isSupportedFormat(url, type)) {\n mediaFiles.push({ url, type, width, height, bitrate });\n log(`Found media file: ${url} (${type}, ${width}x${height})`);\n } else {\n log(`Skipping incompatible media file: ${url} (type: ${type})`);\n }\n });\n \n if (mediaFiles.length === 0) {\n log(\"No valid media files found in ad:\", adId);\n return;\n }\n \n const trackingUrls: VastTrackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n error: [],\n };\n \n adElement.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n \n adElement.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event as keyof VastTrackingUrls;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n \n const clickThrough = adElement.querySelector(\"ClickThrough\")?.textContent?.trim();\n \n ads.push({\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough,\n });\n \n log(`Parsed ad: ${title}, duration: ${duration}s, media files: ${mediaFiles.length}`);\n });\n \n } catch (error) {\n console.error(\"[AdStormPlayer] Error parsing VAST XML:\", error);\n }\n \n return ads;\n }\n\n function selectBestMediaFile(mediaFiles: VastMediaFile[]): VastMediaFile | null {\n if (mediaFiles.length === 0) return null;\n if (mediaFiles.length === 1) return mediaFiles[0]!;\n \n const mp4Files = mediaFiles.filter(mf => mf.type.includes(\"video/mp4\"));\n const candidates = mp4Files.length > 0 ? mp4Files : mediaFiles;\n \n const targetWidth = contentVideo.videoWidth || 1280;\n const targetHeight = contentVideo.videoHeight || 720;\n \n candidates.sort((a, b) => {\n const diffA = Math.abs(a.width - targetWidth) + Math.abs(a.height - targetHeight);\n const diffB = Math.abs(b.width - targetWidth) + Math.abs(b.height - targetHeight);\n return diffA - diffB;\n });\n \n return candidates[0] || null;\n }\n\n function createAdVideoElement(): HTMLVideoElement {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.style.zIndex = \"15\";\n video.playsInline = true;\n video.muted = false;\n video.volume = originalMutedState ? 0 : originalVolume;\n \n return video;\n }\n\n function setAdPlayingFlag(isPlaying: boolean): void {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n\n function setupAdEventListeners(): void {\n if (!adVideoElement || !currentAd) return;\n \n const ad = currentAd;\n \n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!ad || !adVideoElement) return;\n \n const progress = adVideoElement.currentTime / ad.duration;\n \n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(ad.trackingUrls.firstQuartile);\n }\n \n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(ad.trackingUrls.midpoint);\n }\n \n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(ad.trackingUrls.thirdQuartile);\n }\n });\n \n adVideoElement.addEventListener(\"playing\", () => {\n if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(ad.trackingUrls.start);\n log(\"Ad started playing\");\n });\n \n adVideoElement.addEventListener(\"ended\", () => {\n if (!ad || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(ad.trackingUrls.complete);\n log(\"Ad completed\");\n handleAdComplete();\n });\n \n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[AdStormPlayer] Ad video error:\", e);\n if (ad) {\n fireTrackingPixels(ad.trackingUrls.error);\n }\n handleAdError();\n });\n }\n\n function handleAdComplete(): void {\n log(\"Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n \n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n \n emit(\"content_resume\");\n emit(\"all_ads_completed\");\n }\n\n function handleAdError(): void {\n log(\"Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n \n emit(\"ad_error\");\n }\n\n async function fetchVast(durationSeconds: number): Promise<VastAd[]> {\n const vastUrl = buildVastUrl(durationSeconds);\n log(\"Fetching VAST from:\", vastUrl);\n \n const response = await fetch(vastUrl, {\n headers: {\n \"Accept\": \"application/xml\",\n },\n });\n \n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.status} ${response.statusText}`);\n }\n \n const xmlText = await response.text();\n log(\"VAST response received, length:\", xmlText.length);\n \n return parseVastXml(xmlText);\n }\n\n return {\n initialize() {\n log(\"Initializing\");\n \n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n \n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n\n async requestAds(duration: string) {\n log(\"Requesting ads for duration:\", duration);\n \n if (adPlaying) {\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n \n try {\n let durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n \n const ads = await fetchVast(durationSeconds);\n \n if (ads.length === 0) {\n log(\"No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n \n currentAd = ads[0];\n log(`Ad loaded: ${currentAd!.title}, duration: ${currentAd!.duration}s`);\n \n fireTrackingPixels(currentAd!.trackingUrls.impression);\n trackingFired.impression = true;\n \n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n\n async play() {\n if (!currentAd) {\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n \n log(\"Starting ad playback\");\n \n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n \n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n \n contentVideo.style.transition = \"opacity 0.3s ease-in-out\";\n contentVideo.style.opacity = \"0\";\n setTimeout(() => {\n contentVideo.style.visibility = \"hidden\";\n }, 300);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n contentVideo.pause();\n \n adPlaying = true;\n setAdPlayingFlag(true);\n \n if (adVideoElement) {\n adVideoElement.volume = originalMutedState ? 0 : originalVolume;\n adVideoElement.muted = originalMutedState;\n }\n \n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n }\n \n emit(\"content_pause\");\n \n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available\");\n }\n \n log(\"Playing media file:\", mediaFile.url);\n adVideoElement!.src = mediaFile.url;\n \n await adVideoElement!.play();\n \n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n\n async stop() {\n log(\"Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n \n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n \n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n currentAd = undefined;\n },\n\n destroy() {\n log(\"Destroying\");\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n \n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = undefined;\n }\n \n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n \n adContainerEl = undefined;\n currentAd = undefined;\n listeners.clear();\n },\n\n isAdPlaying() {\n return adPlaying;\n },\n\n resize(width: number, height: number) {\n log(`Resizing to ${width}x${height}`);\n \n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n \n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n\n on(event: string, listener: (payload?: any) => void) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(listener);\n },\n\n off(event: string, listener: (payload?: any) => void) {\n listeners.get(event)?.delete(listener);\n },\n\n updateOriginalMutedState(muted: boolean, volume?: number) {\n const nextVolume =\n typeof volume === \"number\" && !Number.isNaN(volume)\n ? Math.max(0, Math.min(1, volume))\n : originalVolume;\n log(`updateOriginalMutedState: muted=${muted}, volume=${nextVolume}`);\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n\n getOriginalMutedState() {\n return originalMutedState;\n },\n\n getOriginalVolume() {\n return originalVolume;\n },\n\n setAdVolume(volume: number) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n adVideoElement.muted = volume === 0;\n }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n\n showPlaceholder() {\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n \n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n \n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n },\n };\n}\n\n","export function polyfillURLSearchParams(): void {\n if (typeof URLSearchParams !== 'undefined') {\n return;\n }\n\n class URLSearchParamsPolyfill {\n private params: Map<string, string[]>;\n\n constructor(init?: string | URLSearchParamsPolyfill) {\n this.params = new Map();\n\n if (typeof init === 'string') {\n this.parseQueryString(init);\n } else if (init instanceof URLSearchParamsPolyfill) {\n init.forEach((value, key) => {\n this.append(key, value);\n });\n }\n }\n\n private parseQueryString(query: string): void {\n const cleanQuery = query.startsWith('?') ? query.slice(1) : query;\n if (!cleanQuery) return;\n\n cleanQuery.split('&').forEach((param) => {\n const [key, value] = param.split('=');\n if (key) {\n const decodedKey = this.safeDecodeURIComponent(key);\n const decodedValue = value ? this.safeDecodeURIComponent(value) : '';\n this.append(decodedKey, decodedValue);\n }\n });\n }\n\n private safeDecodeURIComponent(str: string): string {\n try {\n return decodeURIComponent(str.replace(/\\+/g, ' '));\n } catch (e) {\n return str;\n }\n }\n\n append(name: string, value: string): void {\n const values = this.params.get(name) || [];\n values.push(String(value));\n this.params.set(name, values);\n }\n\n delete(name: string): void {\n this.params.delete(name);\n }\n\n get(name: string): string | null {\n const values = this.params.get(name);\n return values && values.length > 0 && values[0] !== undefined ? values[0] : null;\n }\n\n getAll(name: string): string[] {\n return this.params.get(name) || [];\n }\n\n has(name: string): boolean {\n return this.params.has(name);\n }\n\n set(name: string, value: string): void {\n this.params.set(name, [String(value)]);\n }\n\n forEach(callback: (value: string, key: string, parent: URLSearchParamsPolyfill) => void): void {\n this.params.forEach((values, key) => {\n values.forEach((value) => {\n callback(value, key, this);\n });\n });\n }\n\n toString(): string {\n const parts: string[] = [];\n this.params.forEach((values, key) => {\n values.forEach((value) => {\n parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\n });\n });\n return parts.join('&');\n }\n }\n\n // @ts-ignore\n window.URLSearchParams = URLSearchParamsPolyfill;\n}\n\nexport function polyfillTextEncoder(): void {\n if (typeof TextEncoder !== 'undefined') {\n return;\n }\n\n class TextEncoderPolyfill {\n encoding = 'utf-8';\n\n encode(str: string): Uint8Array {\n const utf8: number[] = [];\n for (let i = 0; i < str.length; i++) {\n let charcode = str.charCodeAt(i);\n if (charcode < 0x80) {\n utf8.push(charcode);\n } else if (charcode < 0x800) {\n utf8.push(0xc0 | (charcode >> 6), 0x80 | (charcode & 0x3f));\n } else if (charcode < 0xd800 || charcode >= 0xe000) {\n utf8.push(\n 0xe0 | (charcode >> 12),\n 0x80 | ((charcode >> 6) & 0x3f),\n 0x80 | (charcode & 0x3f)\n );\n } else {\n i++;\n charcode = 0x10000 + (((charcode & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff));\n utf8.push(\n 0xf0 | (charcode >> 18),\n 0x80 | ((charcode >> 12) & 0x3f),\n 0x80 | ((charcode >> 6) & 0x3f),\n 0x80 | (charcode & 0x3f)\n );\n }\n }\n return new Uint8Array(utf8);\n }\n }\n\n // @ts-ignore\n window.TextEncoder = TextEncoderPolyfill;\n}\n\nexport function polyfillPromiseFinally(): void {\n if (typeof Promise !== 'undefined' && !Promise.prototype.finally) {\n Promise.prototype.finally = function (callback: () => void) {\n const constructor = this.constructor as PromiseConstructor;\n return this.then(\n (value) => constructor.resolve(callback()).then(() => value),\n (reason) =>\n constructor.resolve(callback()).then(() => {\n throw reason;\n })\n );\n };\n }\n}\n\nexport function polyfillObjectAssign(): void {\n if (typeof Object.assign !== 'function') {\n Object.assign = function (target: any, ...sources: any[]) {\n if (target == null) {\n throw new TypeError('Cannot convert undefined or null to object');\n }\n\n const to = Object(target);\n\n for (let i = 0; i < sources.length; i++) {\n const nextSource = sources[i];\n\n if (nextSource != null) {\n for (const nextKey in nextSource) {\n if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n\n return to;\n };\n }\n}\n\nexport function polyfillArrayFrom(): void {\n if (!Array.from) {\n Array.from = function (arrayLike: any, mapFn?: any, thisArg?: any) {\n const items = Object(arrayLike);\n if (arrayLike == null) {\n throw new TypeError('Array.from requires an array-like object');\n }\n\n const len = items.length >>> 0;\n const result = new Array(len);\n\n for (let i = 0; i < len; i++) {\n if (mapFn) {\n result[i] = mapFn.call(thisArg, items[i], i);\n } else {\n result[i] = items[i];\n }\n }\n\n return result;\n };\n }\n}\n\nexport function polyfillStringStartsWith(): void {\n if (!String.prototype.startsWith) {\n String.prototype.startsWith = function (search: string, pos?: number) {\n pos = !pos || pos < 0 ? 0 : +pos;\n return this.substring(pos, pos + search.length) === search;\n };\n }\n}\n\nexport function polyfillStringEndsWith(): void {\n if (!String.prototype.endsWith) {\n String.prototype.endsWith = function (search: string, length?: number) {\n if (length === undefined || length > this.length) {\n length = this.length;\n }\n return this.substring(length - search.length, length) === search;\n };\n }\n}\n\nexport function polyfillStringIncludes(): void {\n if (!String.prototype.includes) {\n String.prototype.includes = function (search: string, start?: number) {\n if (typeof start !== 'number') {\n start = 0;\n }\n if (start + search.length > this.length) {\n return false;\n }\n return this.indexOf(search, start) !== -1;\n };\n }\n}\n\nexport function initializePolyfills(): void {\n polyfillObjectAssign();\n polyfillArrayFrom();\n polyfillStringStartsWith();\n polyfillStringEndsWith();\n polyfillStringIncludes();\n polyfillURLSearchParams();\n polyfillTextEncoder();\n polyfillPromiseFinally();\n}\n\n","interface NavigatorUAData {\n platform?: string;\n brands?: Array<{ brand: string; version: string }>;\n mobile?: boolean;\n}\n\ndeclare global {\n interface Navigator {\n userAgentData?: NavigatorUAData;\n }\n}\n\nexport interface BrowserInfo {\n name: string;\n version: string;\n majorVersion: number;\n isSmartTV: boolean;\n isLegacyTV: boolean;\n platform: string;\n supportsModernJS: boolean;\n}\n\nfunction getChromeVersion(ua: string): number {\n const match = ua.match(/Chrome\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getWebKitVersion(ua: string): number {\n const match = ua.match(/AppleWebKit\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getPlatform(): string {\n if ('userAgentData' in navigator && navigator.userAgentData?.platform) {\n return navigator.userAgentData.platform;\n }\n\n const ua = navigator.userAgent;\n if (/Mac|iPhone|iPad|iPod/i.test(ua)) {\n return /iPhone|iPad|iPod/i.test(ua) ? 'iPhone' : 'MacIntel';\n }\n if (/Win/i.test(ua)) {\n return 'Win32';\n }\n if (/Linux/i.test(ua)) {\n return /Android/i.test(ua) ? 'Linux armv8l' : 'Linux x86_64';\n }\n if (/CrOS/i.test(ua)) {\n return 'CrOS';\n }\n\n // eslint-disable-next-line deprecation/deprecation\n return (navigator as any).platform || 'Unknown';\n}\n\nexport function detectBrowser(): BrowserInfo {\n const ua = navigator.userAgent;\n const platform = getPlatform();\n\n let name = 'Unknown';\n let version = '0';\n let majorVersion = 0;\n let isSmartTV = false;\n let isLegacyTV = false;\n let supportsModernJS = true;\n\n if (/Web0S|webOS/i.test(ua)) {\n name = 'LG WebOS';\n isSmartTV = true;\n const match = ua.match(/Web0S[/\\s]*([\\d.]+)/i);\n version = match && match[1] ? match[1] : 'Unknown';\n if (version !== 'Unknown') {\n const parts = version.split('.');\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n }\n } else if (/Tizen/i.test(ua)) {\n name = 'Samsung Tizen';\n isSmartTV = true;\n const match = ua.match(/Tizen[/\\s]*([\\d.]+)/i);\n version = match && match[1] ? match[1] : 'Unknown';\n if (version !== 'Unknown') {\n const parts = version.split('.');\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = 'Smart TV';\n isSmartTV = true;\n } else if (/NetCast/i.test(ua)) {\n name = 'LG NetCast';\n isSmartTV = true;\n isLegacyTV = true;\n } else if (/BRAVIA/i.test(ua)) {\n name = 'Sony BRAVIA';\n isSmartTV = true;\n }\n\n const chromeVersion = getChromeVersion(ua);\n const webkitVersion = getWebKitVersion(ua);\n\n if (chromeVersion > 0) {\n if (!isSmartTV) {\n name = 'Chrome';\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n }\n\n if (chromeVersion < 50) {\n supportsModernJS = false;\n isLegacyTV = true;\n }\n }\n\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS = false;\n if (isSmartTV) {\n isLegacyTV = true;\n }\n }\n\n if (typeof Promise === 'undefined' ||\n typeof Map === 'undefined' ||\n typeof Set === 'undefined') {\n supportsModernJS = false;\n }\n\n if (typeof URLSearchParams === 'undefined') {\n supportsModernJS = false;\n }\n\n return {\n name,\n version,\n majorVersion,\n isSmartTV,\n isLegacyTV,\n platform,\n supportsModernJS,\n };\n}\n\nexport function supportsModernJS(): boolean {\n try {\n return (\n typeof Promise !== 'undefined' &&\n typeof Map !== 'undefined' &&\n typeof Set !== 'undefined' &&\n typeof Array.from !== 'undefined' &&\n typeof Object.assign !== 'undefined' &&\n typeof Array.prototype.forEach !== 'undefined' &&\n typeof String.prototype.includes !== 'undefined'\n );\n } catch (e) {\n return false;\n }\n}\n\nexport function logBrowserInfo(debug: boolean = false): void {\n if (!debug) return;\n\n const browser = detectBrowser();\n\n console.log('[StormcloudVideoPlayer] Browser Compatibility Info:', {\n browser: `${browser.name} ${browser.version}`,\n platform: browser.platform,\n isSmartTV: browser.isSmartTV,\n isLegacyTV: browser.isLegacyTV,\n supportsModernJS: browser.supportsModernJS,\n userAgent: navigator.userAgent,\n });\n}\n\nexport function getBrowserConfigOverrides(): {\n allowNativeHls?: boolean;\n} {\n const browser = detectBrowser();\n const overrides: { allowNativeHls?: boolean } = {};\n\n if (browser.isSmartTV) {\n overrides.allowNativeHls = true;\n }\n\n return overrides;\n}\n\nexport function supportsFeature(feature: string): boolean {\n switch (feature) {\n case 'urlsearchparams':\n return typeof URLSearchParams !== 'undefined';\n case 'textencoder':\n return typeof TextEncoder !== 'undefined';\n case 'promises':\n return typeof Promise !== 'undefined';\n case 'fetch':\n return typeof fetch !== 'undefined';\n case 'crypto':\n return typeof crypto !== 'undefined' && typeof crypto.subtle !== 'undefined';\n default:\n return false;\n }\n}\n","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 \"driftToleranceMs\",\n \"immediateManifestAds\",\n \"debugAdTiming\",\n \"showCustomControls\",\n \"licenseKey\",\n \"adFailsafeTimeoutMs\",\n \"minSegmentsBeforePlay\",\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 driftToleranceMs?: number;\n immediateManifestAds?: boolean;\n debugAdTiming?: boolean;\n showCustomControls?: boolean;\n hideLoadingIndicator?: boolean;\n licenseKey?: string;\n adFailsafeTimeoutMs?: number;\n minSegmentsBeforePlay?: number;\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 | 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 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.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\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","import type { ClientInfo, TrackingData, HeartbeatData } from \"../types\";\n\nlet cachedBrowserId: string | null = null;\n\nexport function getClientInfo(): ClientInfo {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = (navigator as any).deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: (screen?.orientation as any)?.type || \"\",\n pixelDepth: screen?.pixelDepth,\n };\n\n let deviceType: \"tv\" | \"mobile\" | \"tablet\" | \"desktop\" = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch\n ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim()\n : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))\n ) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"NetCast\") || ua.includes(\"LG\"))\n ) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n\n if (\n ua.includes(\"Android\") &&\n (maxTouchPoints === 0 ||\n ua.includes(\"Google TV\") ||\n ua.includes(\"XiaoMi\"))\n ) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n\n isWebApp =\n window.matchMedia(\"(display-mode: standalone)\").matches ||\n (window.navigator as any).standalone === true ||\n window.screen?.orientation?.angle !== undefined;\n\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState,\n };\n}\n\nexport async function getBrowserID(clientInfo: ClientInfo): Promise<string> {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n\n const fingerprintString = JSON.stringify(clientInfo);\n\n if (typeof crypto !== \"undefined\" && crypto.subtle && crypto.subtle.digest) {\n try {\n await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n\n let encodedData: BufferSource;\n if (typeof TextEncoder !== \"undefined\") {\n encodedData = new TextEncoder().encode(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\n const buffer = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i++) {\n buffer[i] = utf8.charCodeAt(i);\n }\n encodedData = buffer;\n }\n\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n\n const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n const timestamp = Date.now().toString(16).padStart(12, \"0\");\n const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n\n cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\n\nexport async function sendInitialTracking(licenseKey?: string): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n\n const trackingData: TrackingData = {\n browserId,\n ...clientInfo,\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(trackingData),\n }\n );\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n await response.json();\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\n\nexport async function sendHeartbeat(licenseKey?: string): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n\n const heartbeatData: HeartbeatData = {\n browserId,\n timestamp: new Date().toISOString(),\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(heartbeatData),\n }\n );\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n await response.json();\n } catch (error) {\n console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n }\n}\n","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\nconst UNSUPPORTED_VIDEO_EXTENSIONS = ['.flv', '.f4v', '.swf', '.wmv', '.avi', '.mov', '.mkv', '.mp4', '.webm'];\n\nfunction getFileExtension(url: string): string {\n try {\n const pathname = new URL(url, 'http://dummy').pathname;\n const lastDot = pathname.lastIndexOf('.');\n if (lastDot === -1) return '';\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf('.');\n if (lastDot === -1) return '';\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || '').toLowerCase();\n }\n}\n\nfunction isUnsupportedForHls(url: string): boolean {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\n\nfunction replaceFlvExtension(url: string): string {\n const ext = getFileExtension(url);\n if (ext === '.flv') {\n return url.replace(/\\.flv(\\?|$)/i, '.mp4$1');\n }\n return url;\n}\n\ninterface VastTrackingUrls {\n impression: string[];\n start: string[];\n firstQuartile: string[];\n midpoint: string[];\n thirdQuartile: string[];\n complete: string[];\n mute: string[];\n unmute: string[];\n pause: string[];\n resume: string[];\n fullscreen: string[];\n exitFullscreen: string[];\n skip: string[];\n error: string[];\n}\n\ninterface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\nexport function createHlsAdPlayer(\n contentVideo: HTMLVideoElement,\n options?: {\n continueLiveStreamDuringAds?: boolean;\n licenseKey?: string;\n mainHlsInstance?: Hls;\n }\n): 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 sessionId: string | undefined;\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 buildVastUrl(durationSeconds: number): string {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n \n const metadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5000,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0,\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48000,\n bitrate: 128,\n },\n };\n \n const metadataStr = encodeURIComponent(JSON.stringify(metadata));\n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\n }\n\n function fireTrackingPixels(urls: string[]): void {\n if (!urls || urls.length === 0) return;\n\n urls.forEach((url) => {\n try {\n let trackingUrl = url;\n\n if (sessionId) {\n trackingUrl = `${trackingUrl}${\n trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n }session_id=${sessionId}`;\n }\n\n if (licenseKey) {\n trackingUrl = `${trackingUrl}${\n trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n }license_key=${licenseKey}`;\n }\n\n const img = new Image(1, 1);\n img.src = trackingUrl;\n console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n }\n });\n }\n\n function getMainStreamQuality(): {\n width: number;\n height: number;\n bitrate: number;\n } | null {\n if (!mainHlsInstance || !mainHlsInstance.levels) {\n return null;\n }\n\n const currentLevel = mainHlsInstance.currentLevel;\n if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n const autoLevel = mainHlsInstance.loadLevel;\n if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n const level = mainHlsInstance.levels[autoLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5000000,\n };\n }\n return null;\n }\n\n const level = mainHlsInstance.levels[currentLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5000000,\n };\n }\n\n function selectBestMediaFile(mediaFiles: VastMediaFile[]): VastMediaFile {\n if (mediaFiles.length === 0) {\n throw new Error(\"No media files available\");\n }\n\n const firstFile = mediaFiles[0];\n if (!firstFile) {\n throw new Error(\"No media files available\");\n }\n\n if (mediaFiles.length === 1) {\n return firstFile;\n }\n\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n console.log(\n \"[HlsAdPlayer] No main stream quality info, using first media file\"\n );\n return firstFile;\n }\n\n console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\n\n const scoredFiles = mediaFiles.map((file) => {\n const widthDiff = Math.abs(file.width - mainQuality.width);\n const heightDiff = Math.abs(file.height - mainQuality.height);\n const resolutionDiff = widthDiff + heightDiff;\n\n const fileBitrate = (file.bitrate || 5000) * 1000;\n const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n\n const score = resolutionDiff * 2 + bitrateDiff / 1000;\n\n return { file, score, resolutionDiff, bitrateDiff };\n });\n\n scoredFiles.sort((a, b) => a.score - b.score);\n\n const bestMatch = scoredFiles[0];\n if (!bestMatch) {\n console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n return firstFile;\n }\n\n console.log(\"[HlsAdPlayer] Selected media file:\", {\n url: bestMatch.file.url,\n resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n bitrate: bestMatch.file.bitrate,\n score: bestMatch.score,\n resolutionDiff: bestMatch.resolutionDiff,\n bitrateDiff: bestMatch.bitrateDiff,\n });\n\n return bestMatch.file;\n }\n\n function parseVastXml(xmlString: string): VastAd | null {\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\n \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n parserError.textContent\n );\n return null;\n }\n\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n return null;\n }\n\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n const isNoAdAvailable =\n adId === \"empty\" ||\n title.toLowerCase().includes(\"no ad available\") ||\n title.toLowerCase() === \"no ad available\";\n\n const durationText =\n xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration =\n parseInt(durationParts[0] || \"0\", 10) * 3600 +\n parseInt(durationParts[1] || \"0\", 10) * 60 +\n parseInt(durationParts[2] || \"0\", 10);\n\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n\n console.log(\n `[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n );\n\n mediaFileElements.forEach((mf, index) => {\n const type = mf.getAttribute(\"type\") || \"\";\n let 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 originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n console.log(`[HlsAdPlayer] Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n\n if (isUnsupportedForHls(url)) {\n const ext = getFileExtension(url);\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored: unsupported format (extension: ${ext}, declared type: ${type})`\n );\n return;\n }\n\n if (type === \"application/x-mpegURL\" || type.includes(\"m3u8\")) {\n if (!url) {\n console.warn(\n `[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`\n );\n return;\n }\n\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr\n ? parseInt(bitrateAttr, 10)\n : undefined;\n\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate:\n bitrateValue && bitrateValue > 0 ? bitrateValue : undefined,\n });\n\n console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);\n } else {\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not HLS)`\n );\n }\n });\n\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n \"[HlsAdPlayer] No ads available (VAST response indicates no ads)\"\n );\n } else {\n console.warn(\"[HlsAdPlayer] No HLS media files found in VAST XML\");\n }\n return null;\n }\n\n const trackingUrls: VastTrackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: [],\n };\n\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event as keyof VastTrackingUrls;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n\n const clickThrough = xmlDoc\n .querySelector(\"ClickThrough\")\n ?.textContent?.trim();\n\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough,\n };\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n return null;\n }\n }\n\n async function fetchAndParseVastAd(\n url: string\n ): Promise<VastAd | null> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n\n const vastXml = await response.text();\n console.log(\"[HlsAdPlayer] VAST XML received\");\n console.log(\n \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n vastXml.substring(0, 2000)\n );\n\n return parseVastXml(vastXml);\n }\n\n function createAdVideoElement(): HTMLVideoElement {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.playsInline = true;\n video.muted = false;\n\n video.volume = 1.0;\n console.log(\n `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n );\n\n return video;\n }\n\n function setupAdEventListeners(): void {\n if (!adVideoElement || !currentAd) return;\n\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!currentAd || !adVideoElement) return;\n\n const progress = adVideoElement.currentTime / currentAd.duration;\n\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.firstQuartile);\n }\n\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(currentAd.trackingUrls.midpoint);\n }\n\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);\n }\n });\n\n adVideoElement.addEventListener(\"playing\", () => {\n if (!currentAd || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(currentAd.trackingUrls.start);\n console.log(\"[HlsAdPlayer] Ad started playing\");\n });\n\n adVideoElement.addEventListener(\"ended\", () => {\n if (!currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(currentAd.trackingUrls.complete);\n console.log(\"[HlsAdPlayer] Ad completed\");\n\n handleAdComplete();\n });\n\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[HlsAdPlayer] Ad video error:\", e);\n if (currentAd) {\n fireTrackingPixels(currentAd.trackingUrls.error);\n }\n handleAdError();\n });\n\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd) return;\n if (adVideoElement!.muted) {\n fireTrackingPixels(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels(currentAd.trackingUrls.unmute);\n }\n });\n\n adVideoElement.addEventListener(\"pause\", () => {\n if (currentAd && !adVideoElement!.ended) {\n fireTrackingPixels(currentAd.trackingUrls.pause);\n }\n });\n\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && adVideoElement!.currentTime > 0) {\n fireTrackingPixels(currentAd.trackingUrls.resume);\n }\n });\n }\n\n function setAdPlayingFlag(isPlaying: boolean): void {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n\n function handleAdComplete(): void {\n console.log(\"[HlsAdPlayer] Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n emit(\"content_resume\");\n\n const timeoutId = window.setTimeout(() => {\n if (destroyed) {\n console.log(\"[HlsAdPlayer] Player destroyed, skipping post-completion check\");\n return;\n }\n \n const stillInPod = contentVideo.dataset.stormcloudAdPlaying === \"true\";\n if (stillInPod) {\n console.log(\n \"[HlsAdPlayer] Still in ad pod - keeping ad container visible (black screen)\"\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n }\n \n const idx = pendingTimeouts.indexOf(timeoutId);\n if (idx !== -1) {\n pendingTimeouts.splice(idx, 1);\n }\n }, 50);\n \n pendingTimeouts.push(timeoutId);\n }\n\n function handleAdError(): void {\n console.log(\"[HlsAdPlayer] Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n const previousMutedState = contentVideo.muted;\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n console.log(\n `[HlsAdPlayer] Restored mute state: ${previousMutedState} -> ${originalMutedState}`\n );\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n if (!options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n contentVideo.play().catch(() => {});\n }\n }\n\n emit(\"ad_error\");\n }\n\n return {\n initialize() {\n console.log(\"[HlsAdPlayer] Initializing\");\n\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n\n async requestAds(duration: string) {\n console.log(\"[HlsAdPlayer] Requesting ads for duration:\", duration);\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 \n let durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n \n const vastUrl = buildVastUrl(durationSeconds);\n const ad = await fetchAndParseVastAd(vastUrl);\n\n if (!ad) {\n console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n\n currentAd = ad;\n console.log(\n `[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`\n );\n\n fireTrackingPixels(ad.trackingUrls.impression);\n trackingFired.impression = true;\n\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n\n async play() {\n if (!currentAd) {\n console.warn(\n \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n );\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n\n console.log(\"[HlsAdPlayer] Starting ad playback\");\n\n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n\n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(\n 0,\n Math.min(1, contentVolume || originalVolume)\n );\n\n if (!options?.continueLiveStreamDuringAds) {\n contentVideo.pause();\n console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n } else {\n console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n }\n\n console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n\n if (adVideoElement) {\n const adVolume = originalMutedState ? 0 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\n console.log(\n `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`\n );\n }\n\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n\n emit(\"content_pause\");\n\n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available for ad\");\n }\n\n console.log(`[HlsAdPlayer] Loading ad from: ${mediaFile.url}`);\n\n if (Hls.isSupported()) {\n if (adHls) {\n adHls.destroy();\n }\n\n adHls = new Hls({\n enableWorker: true,\n lowLatencyMode: false,\n });\n\n adHls.loadSource(mediaFile.url);\n adHls.attachMedia(adVideoElement);\n\n adHls.on(Hls.Events.MANIFEST_PARSED, () => {\n console.log(\"[HlsAdPlayer] HLS manifest parsed, starting playback\");\n adVideoElement!.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n });\n\n adHls.on(Hls.Events.ERROR, (event, data) => {\n console.error(\"[HlsAdPlayer] HLS error:\", data);\n if (data.fatal) {\n handleAdError();\n }\n });\n } else if (\n adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")\n ) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n } else {\n throw new Error(\"HLS not supported\");\n }\n\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n\n async stop() {\n console.log(\"[HlsAdPlayer] Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n\n currentAd = undefined;\n },\n\n destroy() {\n console.log(\"[HlsAdPlayer] Destroying\");\n destroyed = true;\n for (const timeoutId of pendingTimeouts) {\n clearTimeout(timeoutId);\n }\n pendingTimeouts = [];\n \n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = undefined;\n }\n\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n\n adContainerEl = undefined;\n currentAd = undefined;\n listeners.clear();\n },\n\n isAdPlaying() {\n return adPlaying;\n },\n\n resize(width: number, height: number) {\n console.log(`[HlsAdPlayer] Resizing to ${width}x${height}`);\n\n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n\n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n\n on(event: string, listener: (payload?: any) => void) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(listener);\n },\n\n off(event: string, listener: (payload?: any) => void) {\n listeners.get(event)?.delete(listener);\n },\n\n updateOriginalMutedState(muted: boolean, volume?: number) {\n const nextVolume =\n typeof volume === \"number\" && !Number.isNaN(volume)\n ? Math.max(0, Math.min(1, volume))\n : originalVolume;\n console.log(\n `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n );\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n\n getOriginalMutedState() {\n return originalMutedState;\n },\n getOriginalVolume() {\n return originalVolume;\n },\n\n setAdVolume(volume: number) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/ubuntu24/Dev/stormcloud-vp/lib/index.js","../src/ui/StormcloudVideoPlayer.tsx","../src/player/StormcloudVideoPlayer.ts","../src/sdk/adstormPlayer.ts","../src/utils/polyfills.ts","../src/utils/browserCompat.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","../src/utils/tracking.ts","../src/sdk/hlsAdPlayer.ts"],"names":["React","useEffect","useRef","useMemo","Hls","SUPPORTED_VIDEO_EXTENSIONS","UNSUPPORTED_VIDEO_EXTENSIONS","getFileExtension","url","pathname","URL","lastDot","lastIndexOf","slice","toLowerCase","ext","split","isUnsupportedFormat","indexOf","replaceFlvExtension","replace","isSupportedFormat","mimeType","includes","createAdStormPlayer","contentVideo","options","licenseKey","debug","adPlaying","originalMutedState","originalVolume","Math","max","min","volume","listeners","Map","adVideoElement","adContainerEl","currentAd","destroyed","allowNativeHls","trackingFired","impression","start","firstQuartile","midpoint","thirdQuartile","complete","log","args","console","emit","event","payload","set","get","Array","from","fn","error","warn","fireTrackingPixels","urls","length","forEach","img","Image","src","buildVastUrl","durationSeconds","metadata","baseUrl","defaultMetadata","video","codec","width","videoWidth","height","videoHeight","fps","bitrate","profile","pix_fmt","has_b_frames","audio","sample_rate","finalMetadata","metadataStr","encodeURIComponent","JSON","stringify","ceil","parseVastXml","xmlString","ads","parser","DOMParser","xmlDoc","parseFromString","parserError","querySelector","textContent","adElements","querySelectorAll","adElement","adId","getAttribute","title","durationText","durationParts","duration","parseInt","parseFloat","mediaFileElements","mediaFiles","mf","type","trim","originalUrl","push","trackingUrls","el","eventKey","clickThrough","id","selectBestMediaFile","mp4Files","filter","candidates","targetWidth","targetHeight","sort","a","b","diffA","abs","diffB","createAdVideoElement","document","createElement","style","position","left","top","objectFit","backgroundColor","zIndex","playsInline","muted","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","setupAdEventListeners","ad","addEventListener","progress","currentTime","handleAdComplete","e","handleAdError","opacity","setTimeout","display","pointerEvents","visibility","fetchVast","vastUrl","response","xmlText","fetch","headers","ok","Error","status","statusText","text","initialize","container","right","bottom","alignItems","justifyContent","transition","parentElement","appendChild","requestAds","parsed","Promise","reject","isNaN","resolve","play","mediaFile","pause","offsetHeight","stop","destroy","remove","removeChild","clear","isAdPlaying","resize","on","listener","has","Set","add","off","delete","updateOriginalMutedState","nextVolume","Number","getOriginalMutedState","getOriginalVolume","setAdVolume","getAdVolume","showPlaceholder","hidePlaceholder","setAllowNativeHls","value","polyfillURLSearchParams","URLSearchParams","URLSearchParamsPolyfill","init","params","parseQueryString","key","append","query","cleanQuery","startsWith","param","decodedKey","safeDecodeURIComponent","decodedValue","str","decodeURIComponent","name","values","String","getAll","callback","toString","parts","join","window","polyfillTextEncoder","TextEncoder","TextEncoderPolyfill","encoding","encode","utf8","i","charcode","charCodeAt","Uint8Array","polyfillPromiseFinally","prototype","finally","constructor","then","reason","polyfillObjectAssign","Object","assign","target","sources","TypeError","to","nextSource","nextKey","hasOwnProperty","call","polyfillArrayFrom","arrayLike","mapFn","thisArg","items","len","result","polyfillStringStartsWith","search","pos","substring","polyfillStringEndsWith","endsWith","polyfillStringIncludes","initializePolyfills","getChromeVersion","ua","match","getWebKitVersion","getPlatform","navigator","userAgentData","platform","userAgent","test","detectBrowser","version","majorVersion","isSmartTV","isLegacyTV","supportsModernJS","chromeVersion","webkitVersion","logBrowserInfo","browser","getBrowserConfigOverrides","overrides","supportsFeature","feature","crypto","subtle","StormcloudVideoPlayer","config","attached","inAdBreak","ptsDriftEmaMs","isLiveStream","nativeHlsMode","videoSrcProtection","bufferedSegmentsCount","shouldAutoplayAfterBuffering","hasInitialBufferCompleted","browserOverrides","videoElement","debugAdTiming","adPlayer","load","attach","shouldUseNativeHls","lowLatencyMode","isLive","autoplay","catch","hls","enableWorker","backBufferLength","liveDurationInfinity","maxLiveSyncPlaybackRate","liveSyncDuration","maxBufferLength","maxMaxBufferLength","maxBufferSize","maxBufferHole","highBufferWatchdogPeriod","nudgeOffset","nudgeMaxRetry","startPosition","Events","MEDIA_ATTACHED","loadSource","MANIFEST_PARSED","minSegments","levels","some","level","details","live","minSegmentsBeforePlay","FRAG_BUFFERED","err","FRAG_PARSING_METADATA","_evt","data","id3Tags","samples","map","s","ptsSeconds","pts","tag","onId3Tag","FRAG_CHANGED","frag","tagList","isArray","entry","idx","parseCueOutDuration","onScte35Marker","raw","prog","parseCueOutCont","elapsed","attrs","parseAttributeList","hasScteOut","hasScteIn","klass","toNumber","ERROR","fatal","ErrorTypes","NETWORK_ERROR","startLoad","MEDIA_ERROR","recoverMediaError","attachMedia","handleAdPodComplete","timeUpdateHandler","emptiedHandler","wasPaused","paused","streamType","getStreamType","canNative","canPlayType","updatePtsDrift","marker","parseScte35FromId3","decodeId3ValueToText","cueOutMatch","arg","dur","id3","cueOutContMatch","cont","cueInMatch","decoder","TextDecoder","decode","out","fromCharCode","durationMs","expectedAdBreakDurationMs","handleAdStart","scheduleAdStopCountdown","clearAdStopTimer","num","d","elapsedMatch","durationMatch","res","regex","exec","rawVal","val","n","remainingMs","ms","floor","adStopTimerId","clearTimeout","ptsSecondsSample","sampleMs","isFinite","alpha","restoredMuted","restoredVolume","isShowingAds","shouldShowNativeControls","showCustomControls","toggleMute","currentMuted","newMutedState","toggleFullscreen","fullscreenElement","requestFullscreen","exitFullscreen","isMuted","setMuted","setVolume","clampedVolume","isFullscreen","clientWidth","clientHeight","removeEventListener","getCurrentAdIndex","getTotalAdsInBreak","FaPlay","FaPause","FaVolumeUp","FaVolumeMute","FaVolumeDown","FaExpand","FaCompress","FaSpinner","Fragment","jsx","jsxs","CRITICAL_PROPS","StormcloudVideoPlayerComponent","memo","props","driftToleranceMs","immediateManifestAds","hideLoadingIndicator","onVolumeToggle","onFullscreenToggle","onControlClick","onReady","wrapperClassName","wrapperStyle","className","controls","preload","poster","children","restVideoAttrs","videoRef","playerRef","bufferingTimeoutRef","useState","showAds","currentIndex","totalAds","adStatus","setAdStatus","setShouldShowNativeControls","setIsMuted","setIsFullscreen","setIsPlaying","setCurrentTime","setDuration","playbackRate","setPlaybackRate","showVolumeSlider","setShowVolumeSlider","showSpeedMenu","setShowSpeedMenu","isLoading","setIsLoading","isBuffering","setIsBuffering","showCenterPlay","setShowCenterPlay","showLicenseWarning","setShowLicenseWarning","innerWidth","viewportWidth","setViewportWidth","innerHeight","isPortrait","setIsPortrait","getResponsiveScale","responsiveScale","formatTime","seconds","hours","minutes","remainingSeconds","padStart","handlePlayPause","current","hasValidSource","currentSrc","readyState","handleCenterPlayClick","handleTimelineSeek","rect","currentTarget","getBoundingClientRect","clickX","clientX","newTime","handleVolumeChange","newVolume","handlePlaybackRateChange","rate","isHlsStream","shouldShowEnhancedControls","criticalPropsKey","prop","cfg","player","showNative","checkAdStatus","prev","interval","setInterval","clearInterval","handleResize","updateStates","currentTimeValue","durationValue","volumeValue","rateValue","handleFullscreenChange","handleLoadedMetadata","handleLoadedData","handleLoadStart","handleCanPlay","handleCanPlayThrough","handleWaiting","handlePlaying","handlePause","handleEnded","overflow","minHeight","maxWidth","maxHeight","borderRadius","boxShadow","ref","aspectRatio","size","color","animation","transform","background","padding","backdropFilter","border","textAlign","margin","fontSize","fontWeight","marginBottom","textShadow","lineHeight","onClick","cursor","onMouseEnter","borderColor","onMouseLeave","marginLeft","flexWrap","gap","minWidth","flexDirection","onMouseDown","preventDefault","sliderElement","handleMouseMove","moveEvent","y","clientY","percentage","handleMouseUp","stopPropagation","onMouseUp","fontFamily","speed","borderBottom","prevProps","nextProps","uiProps","callbackProps","Component","Suspense","noop","defaultProps","playing","loop","progressInterval","adFailsafeTimeoutMs","onStart","onPlay","onPause","onBuffer","onBufferEnd","onEnded","onError","onDuration","onSeek","onProgress","lazy","reactLazy","omit","object","keys","isMediaStream","MediaStream","supportsWebKitPresentationMode","randomString","random","substr","parseQuery","queryString","manualParse","qs","merge","source","shift","isObject","item","IS_BROWSER","IS_GLOBAL","globalThis","IS_IOS","IS_SAFARI","SUPPORTS_HLS","Boolean","SUPPORTS_DASH","HLS_EXTENSIONS","HLS_PATHS","DASH_EXTENSIONS","VIDEO_EXTENSIONS","AUDIO_EXTENSIONS","canPlay","dash","file","HlsPlayer","mounted","onMount","seekTo","keepPlaying","mute","unmute","getDuration","getCurrentTime","getSecondsLoaded","buffered","end","getInternalPlayer","componentDidMount","componentWillUnmount","componentDidUpdate","render","displayName","FilePlayer","ready","handlePlay","handleError","onLoaded","setLoop","enablePIP","requestPictureInPicture","disablePIP","pictureInPictureElement","exitPictureInPicture","players","lazyPlayer","default","canEnablePIP","pictureInPictureEnabled","webkitSupportsPresentationMode","players_default","SEEK_ON_PLAY_EXPIRY","Player","arguments","isReady","loadOnReady","startOnPlay","seekOnPlay","onDurationCalled","handlePlayerMount","playedSeconds","loadedSeconds","played","loaded","prevPlayed","prevLoaded","progressTimeout","handleReady","handleDurationCheck","activePlayer","loopOnEnded","durationCheckTimeout","handleLoaded","forceLoad","amount","isFraction","UniversalSuspense","SUPPORTED_PROPS","customPlayers","createStormcloudPlayer","playerList","fallback","_a","state","showPreview","references","wrapper","getActivePlayer","getAttributes","fraction","renderActivePlayer","fallbackElement","Wrapper","attributes","wrapperRef","addCustomPlayer","removeCustomPlayers","StormcloudPlayer","StormcloudPlayer_default","cachedBrowserId","getClientInfo","screen","vendor","maxTouchPoints","memory","deviceMemory","hardwareConcurrency","screenInfo","availWidth","availHeight","orientation","pixelDepth","deviceType","brand","os","model","isAndroid","isWebView","isWebApp","webosMatch","tizenMatch","tvMatch","androidModelMatch","outerHeight","outerWidth","matchMedia","matches","standalone","angle","domain","location","hostname","origin","path","language","languages","cookieEnabled","doNotTrack","referrer","visibilityState","getBrowserID","clientInfo","fingerprintString","encodedData","buffer","hashBuffer","hashArray","hashHex","hash","char","fallbackHash","timestamp","digest","unescape","Date","now","padEnd","sendInitialTracking","browserId","trackingData","method","body","json","sendHeartbeat","heartbeatData","toISOString","isUnsupportedForHls","createHlsAdPlayer","mainHlsInstance","adHls","sessionId","pendingTimeouts","generateSessionId","trackingUrl","getMainStreamQuality","currentLevel","autoLevel","loadLevel","firstFile","mainQuality","scoredFiles","widthDiff","heightDiff","resolutionDiff","fileBitrate","bitrateDiff","score","bestMatch","resolution","isNoAdAvailable","index","bitrateAttr","bitrateValue","resume","fullscreen","skip","fetchAndParseVastAd","vastXml","ended","timeoutId","stillInPod","splice","previousMutedState","continueLiveStreamDuringAds","contentVolume","adVolume","isSupported"],"mappings":"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","sourcesContent":["// src/ui/StormcloudVideoPlayer.tsx\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\n// src/player/StormcloudVideoPlayer.ts\nimport Hls from \"hls.js\";\n\n// src/sdk/adstormPlayer.ts\nvar SUPPORTED_VIDEO_EXTENSIONS = [\".mp4\", \".webm\", \".ogg\", \".m3u8\", \".ts\"];\nvar UNSUPPORTED_VIDEO_EXTENSIONS = [\".flv\", \".f4v\", \".swf\", \".wmv\", \".avi\", \".mov\", \".mkv\"];\nfunction getFileExtension(url) {\n try {\n const pathname = new URL(url, \"http://dummy\").pathname;\n const lastDot = pathname.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || \"\").toLowerCase();\n }\n}\nfunction isUnsupportedFormat(url) {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\nfunction replaceFlvExtension(url) {\n const ext = getFileExtension(url);\n if (ext === \".flv\") {\n return url.replace(/\\.flv(\\?|$)/i, \".mp4$1\");\n }\n return url;\n}\nfunction isSupportedFormat(url, mimeType) {\n if (isUnsupportedFormat(url)) {\n return false;\n }\n const ext = getFileExtension(url);\n if (SUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1) {\n return true;\n }\n if (ext === \"\" || ext === \".\") {\n return mimeType.includes(\"video/mp4\") || mimeType.includes(\"video/webm\") || mimeType.includes(\"m3u8\") || mimeType.includes(\"application/x-mpegurl\");\n }\n return false;\n}\nfunction createAdStormPlayer(contentVideo, options) {\n const { licenseKey, debug = false } = options;\n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = /* @__PURE__ */ new Map();\n let adVideoElement;\n let adContainerEl;\n let currentAd;\n let destroyed = false;\n let allowNativeHls = false;\n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n function log(...args) {\n if (debug) {\n console.log(\"[AdStormPlayer]\", ...args);\n }\n }\n function emit(event, payload) {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch (error) {\n console.warn(`[AdStormPlayer] Error in event listener for ${event}:`, error);\n }\n }\n }\n function fireTrackingPixels(urls) {\n if (!urls || urls.length === 0) return;\n urls.forEach((url) => {\n try {\n const img = new Image(1, 1);\n img.src = url;\n log(\"Fired tracking pixel:\", url);\n } catch (error) {\n console.warn(\"[AdStormPlayer] Error firing tracking pixel:\", error);\n }\n });\n }\n function buildVastUrl(durationSeconds, metadata) {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n const defaultMetadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5e3,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48e3,\n bitrate: 128\n }\n };\n const finalMetadata = metadata || defaultMetadata;\n const metadataStr = encodeURIComponent(JSON.stringify(finalMetadata));\n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\n }\n function parseVastXml(xmlString) {\n const ads = [];\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\"[AdStormPlayer] XML parsing error:\", parserError.textContent);\n return [];\n }\n const adElements = xmlDoc.querySelectorAll(\"Ad\");\n adElements.forEach((adElement) => {\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n const durationText = adElement.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + parseFloat(durationParts[2] || \"0\");\n const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n const mediaFiles = [];\n mediaFileElements.forEach((mf) => {\n const type = mf.getAttribute(\"type\") || \"\";\n let url = mf.textContent?.trim() || \"\";\n const width = parseInt(mf.getAttribute(\"width\") || \"1920\", 10);\n const height = parseInt(mf.getAttribute(\"height\") || \"1080\", 10);\n const bitrate = mf.getAttribute(\"bitrate\") ? parseInt(mf.getAttribute(\"bitrate\"), 10) : void 0;\n if (!url) {\n log(`Skipping empty MediaFile URL`);\n return;\n }\n const originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n log(`Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n if (isUnsupportedFormat(url)) {\n const ext = getFileExtension(url);\n log(`Skipping unsupported format: ${url} (extension: ${ext}, declared type: ${type})`);\n return;\n }\n if (isSupportedFormat(url, type)) {\n mediaFiles.push({ url, type, width, height, bitrate });\n log(`Found media file: ${url} (${type}, ${width}x${height})`);\n } else {\n log(`Skipping incompatible media file: ${url} (type: ${type})`);\n }\n });\n if (mediaFiles.length === 0) {\n log(\"No valid media files found in ad:\", adId);\n return;\n }\n const trackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n error: []\n };\n adElement.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n adElement.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n const clickThrough = adElement.querySelector(\"ClickThrough\")?.textContent?.trim();\n ads.push({\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough\n });\n log(`Parsed ad: ${title}, duration: ${duration}s, media files: ${mediaFiles.length}`);\n });\n } catch (error) {\n console.error(\"[AdStormPlayer] Error parsing VAST XML:\", error);\n }\n return ads;\n }\n function selectBestMediaFile(mediaFiles) {\n if (mediaFiles.length === 0) return null;\n if (mediaFiles.length === 1) return mediaFiles[0];\n const mp4Files = mediaFiles.filter((mf) => mf.type.includes(\"video/mp4\"));\n const candidates = mp4Files.length > 0 ? mp4Files : mediaFiles;\n const targetWidth = contentVideo.videoWidth || 1280;\n const targetHeight = contentVideo.videoHeight || 720;\n candidates.sort((a, b) => {\n const diffA = Math.abs(a.width - targetWidth) + Math.abs(a.height - targetHeight);\n const diffB = Math.abs(b.width - targetWidth) + Math.abs(b.height - targetHeight);\n return diffA - diffB;\n });\n return candidates[0] || null;\n }\n function createAdVideoElement() {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.style.zIndex = \"15\";\n video.playsInline = true;\n video.muted = false;\n video.volume = originalMutedState ? 0 : originalVolume;\n return video;\n }\n function setAdPlayingFlag(isPlaying) {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n function setupAdEventListeners() {\n if (!adVideoElement || !currentAd) return;\n const ad = currentAd;\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!ad || !adVideoElement) return;\n const progress = adVideoElement.currentTime / ad.duration;\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(ad.trackingUrls.firstQuartile);\n }\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(ad.trackingUrls.midpoint);\n }\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(ad.trackingUrls.thirdQuartile);\n }\n });\n adVideoElement.addEventListener(\"playing\", () => {\n if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(ad.trackingUrls.start);\n log(\"Ad started playing\");\n });\n adVideoElement.addEventListener(\"ended\", () => {\n if (!ad || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(ad.trackingUrls.complete);\n log(\"Ad completed\");\n handleAdComplete();\n });\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[AdStormPlayer] Ad video error:\", e);\n if (ad) {\n fireTrackingPixels(ad.trackingUrls.error);\n }\n handleAdError();\n });\n }\n function handleAdComplete() {\n log(\"Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n emit(\"content_resume\");\n emit(\"all_ads_completed\");\n }\n function handleAdError() {\n log(\"Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n emit(\"ad_error\");\n }\n async function fetchVast(durationSeconds) {\n const vastUrl = buildVastUrl(durationSeconds);\n log(\"Fetching VAST from:\", vastUrl);\n const response = await fetch(vastUrl, {\n headers: {\n \"Accept\": \"application/xml\"\n }\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.status} ${response.statusText}`);\n }\n const xmlText = await response.text();\n log(\"VAST response received, length:\", xmlText.length);\n return parseVastXml(xmlText);\n }\n return {\n initialize() {\n log(\"Initializing\");\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n async requestAds(duration) {\n log(\"Requesting ads for duration:\", duration);\n if (adPlaying) {\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n try {\n let durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n const ads = await fetchVast(durationSeconds);\n if (ads.length === 0) {\n log(\"No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n currentAd = ads[0];\n log(`Ad loaded: ${currentAd.title}, duration: ${currentAd.duration}s`);\n fireTrackingPixels(currentAd.trackingUrls.impression);\n trackingFired.impression = true;\n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n async play() {\n if (!currentAd) {\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n log(\"Starting ad playback\");\n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n contentVideo.style.transition = \"opacity 0.3s ease-in-out\";\n contentVideo.style.opacity = \"0\";\n setTimeout(() => {\n contentVideo.style.visibility = \"hidden\";\n }, 300);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n if (allowNativeHls) {\n contentVideo.pause();\n }\n adPlaying = true;\n setAdPlayingFlag(true);\n if (adVideoElement) {\n adVideoElement.volume = originalMutedState ? 0 : originalVolume;\n adVideoElement.muted = originalMutedState;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n }\n emit(\"content_pause\");\n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available\");\n }\n log(\"Playing media file:\", mediaFile.url);\n adVideoElement.src = mediaFile.url;\n await adVideoElement.play();\n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n async stop() {\n log(\"Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n currentAd = void 0;\n },\n destroy() {\n log(\"Destroying\");\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = void 0;\n }\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n adContainerEl = void 0;\n currentAd = void 0;\n listeners.clear();\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width, height) {\n log(`Resizing to ${width}x${height}`);\n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n on(event, listener) {\n if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());\n listeners.get(event).add(listener);\n },\n off(event, listener) {\n listeners.get(event)?.delete(listener);\n },\n updateOriginalMutedState(muted, volume) {\n const nextVolume = typeof volume === \"number\" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;\n log(`updateOriginalMutedState: muted=${muted}, volume=${nextVolume}`);\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n getOriginalMutedState() {\n return originalMutedState;\n },\n getOriginalVolume() {\n return originalVolume;\n },\n setAdVolume(volume) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n adVideoElement.muted = volume === 0;\n }\n },\n getAdVolume() {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n },\n setAllowNativeHls(value) {\n allowNativeHls = value;\n log(`allowNativeHls set to: ${value}`);\n }\n };\n}\n\n// src/utils/polyfills.ts\nfunction polyfillURLSearchParams() {\n if (typeof URLSearchParams !== \"undefined\") {\n return;\n }\n class URLSearchParamsPolyfill {\n constructor(init) {\n this.params = /* @__PURE__ */ new Map();\n if (typeof init === \"string\") {\n this.parseQueryString(init);\n } else if (init instanceof URLSearchParamsPolyfill) {\n init.forEach((value, key) => {\n this.append(key, value);\n });\n }\n }\n parseQueryString(query) {\n const cleanQuery = query.startsWith(\"?\") ? query.slice(1) : query;\n if (!cleanQuery) return;\n cleanQuery.split(\"&\").forEach((param) => {\n const [key, value] = param.split(\"=\");\n if (key) {\n const decodedKey = this.safeDecodeURIComponent(key);\n const decodedValue = value ? this.safeDecodeURIComponent(value) : \"\";\n this.append(decodedKey, decodedValue);\n }\n });\n }\n safeDecodeURIComponent(str) {\n try {\n return decodeURIComponent(str.replace(/\\+/g, \" \"));\n } catch (e) {\n return str;\n }\n }\n append(name, value) {\n const values = this.params.get(name) || [];\n values.push(String(value));\n this.params.set(name, values);\n }\n delete(name) {\n this.params.delete(name);\n }\n get(name) {\n const values = this.params.get(name);\n return values && values.length > 0 && values[0] !== void 0 ? values[0] : null;\n }\n getAll(name) {\n return this.params.get(name) || [];\n }\n has(name) {\n return this.params.has(name);\n }\n set(name, value) {\n this.params.set(name, [String(value)]);\n }\n forEach(callback) {\n this.params.forEach((values, key) => {\n values.forEach((value) => {\n callback(value, key, this);\n });\n });\n }\n toString() {\n const parts = [];\n this.params.forEach((values, key) => {\n values.forEach((value) => {\n parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\n });\n });\n return parts.join(\"&\");\n }\n }\n window.URLSearchParams = URLSearchParamsPolyfill;\n}\nfunction polyfillTextEncoder() {\n if (typeof TextEncoder !== \"undefined\") {\n return;\n }\n class TextEncoderPolyfill {\n constructor() {\n this.encoding = \"utf-8\";\n }\n encode(str) {\n const utf8 = [];\n for (let i = 0; i < str.length; i++) {\n let charcode = str.charCodeAt(i);\n if (charcode < 128) {\n utf8.push(charcode);\n } else if (charcode < 2048) {\n utf8.push(192 | charcode >> 6, 128 | charcode & 63);\n } else if (charcode < 55296 || charcode >= 57344) {\n utf8.push(\n 224 | charcode >> 12,\n 128 | charcode >> 6 & 63,\n 128 | charcode & 63\n );\n } else {\n i++;\n charcode = 65536 + ((charcode & 1023) << 10 | str.charCodeAt(i) & 1023);\n utf8.push(\n 240 | charcode >> 18,\n 128 | charcode >> 12 & 63,\n 128 | charcode >> 6 & 63,\n 128 | charcode & 63\n );\n }\n }\n return new Uint8Array(utf8);\n }\n }\n window.TextEncoder = TextEncoderPolyfill;\n}\nfunction polyfillPromiseFinally() {\n if (typeof Promise !== \"undefined\" && !Promise.prototype.finally) {\n Promise.prototype.finally = function(callback) {\n const constructor = this.constructor;\n return this.then(\n (value) => constructor.resolve(callback()).then(() => value),\n (reason) => constructor.resolve(callback()).then(() => {\n throw reason;\n })\n );\n };\n }\n}\nfunction polyfillObjectAssign() {\n if (typeof Object.assign !== \"function\") {\n Object.assign = function(target, ...sources) {\n if (target == null) {\n throw new TypeError(\"Cannot convert undefined or null to object\");\n }\n const to = Object(target);\n for (let i = 0; i < sources.length; i++) {\n const nextSource = sources[i];\n if (nextSource != null) {\n for (const nextKey in nextSource) {\n if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n }\n}\nfunction polyfillArrayFrom() {\n if (!Array.from) {\n Array.from = function(arrayLike, mapFn, thisArg) {\n const items = Object(arrayLike);\n if (arrayLike == null) {\n throw new TypeError(\"Array.from requires an array-like object\");\n }\n const len = items.length >>> 0;\n const result = new Array(len);\n for (let i = 0; i < len; i++) {\n if (mapFn) {\n result[i] = mapFn.call(thisArg, items[i], i);\n } else {\n result[i] = items[i];\n }\n }\n return result;\n };\n }\n}\nfunction polyfillStringStartsWith() {\n if (!String.prototype.startsWith) {\n String.prototype.startsWith = function(search, pos) {\n pos = !pos || pos < 0 ? 0 : +pos;\n return this.substring(pos, pos + search.length) === search;\n };\n }\n}\nfunction polyfillStringEndsWith() {\n if (!String.prototype.endsWith) {\n String.prototype.endsWith = function(search, length) {\n if (length === void 0 || length > this.length) {\n length = this.length;\n }\n return this.substring(length - search.length, length) === search;\n };\n }\n}\nfunction polyfillStringIncludes() {\n if (!String.prototype.includes) {\n String.prototype.includes = function(search, start) {\n if (typeof start !== \"number\") {\n start = 0;\n }\n if (start + search.length > this.length) {\n return false;\n }\n return this.indexOf(search, start) !== -1;\n };\n }\n}\nfunction initializePolyfills() {\n polyfillObjectAssign();\n polyfillArrayFrom();\n polyfillStringStartsWith();\n polyfillStringEndsWith();\n polyfillStringIncludes();\n polyfillURLSearchParams();\n polyfillTextEncoder();\n polyfillPromiseFinally();\n}\n\n// src/utils/browserCompat.ts\nfunction getChromeVersion(ua) {\n const match = ua.match(/Chrome\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\nfunction getWebKitVersion(ua) {\n const match = ua.match(/AppleWebKit\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\nfunction getPlatform() {\n if (\"userAgentData\" in navigator && navigator.userAgentData?.platform) {\n return navigator.userAgentData.platform;\n }\n const ua = navigator.userAgent;\n if (/Mac|iPhone|iPad|iPod/i.test(ua)) {\n return /iPhone|iPad|iPod/i.test(ua) ? \"iPhone\" : \"MacIntel\";\n }\n if (/Win/i.test(ua)) {\n return \"Win32\";\n }\n if (/Linux/i.test(ua)) {\n return /Android/i.test(ua) ? \"Linux armv8l\" : \"Linux x86_64\";\n }\n if (/CrOS/i.test(ua)) {\n return \"CrOS\";\n }\n return navigator.platform || \"Unknown\";\n}\nfunction detectBrowser() {\n const ua = navigator.userAgent;\n const platform = getPlatform();\n let name = \"Unknown\";\n let version = \"0\";\n let majorVersion = 0;\n let isSmartTV = false;\n let isLegacyTV = false;\n let supportsModernJS2 = true;\n if (/Web0S|webOS/i.test(ua)) {\n name = \"LG WebOS\";\n isSmartTV = true;\n const match = ua.match(/Web0S[/\\s]*([\\d.]+)/i);\n version = match && match[1] ? match[1] : \"Unknown\";\n if (version !== \"Unknown\") {\n const parts = version.split(\".\");\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n }\n } else if (/Tizen/i.test(ua)) {\n name = \"Samsung Tizen\";\n isSmartTV = true;\n const match = ua.match(/Tizen[/\\s]*([\\d.]+)/i);\n version = match && match[1] ? match[1] : \"Unknown\";\n if (version !== \"Unknown\") {\n const parts = version.split(\".\");\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = \"Smart TV\";\n isSmartTV = true;\n } else if (/NetCast/i.test(ua)) {\n name = \"LG NetCast\";\n isSmartTV = true;\n isLegacyTV = true;\n } else if (/BRAVIA/i.test(ua)) {\n name = \"Sony BRAVIA\";\n isSmartTV = true;\n }\n const chromeVersion = getChromeVersion(ua);\n const webkitVersion = getWebKitVersion(ua);\n if (chromeVersion > 0) {\n if (!isSmartTV) {\n name = \"Chrome\";\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n }\n if (chromeVersion < 50) {\n supportsModernJS2 = false;\n isLegacyTV = true;\n }\n }\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS2 = false;\n if (isSmartTV) {\n isLegacyTV = true;\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 };\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 userAgent: navigator.userAgent\n });\n}\nfunction getBrowserConfigOverrides() {\n const browser = detectBrowser();\n const overrides = {};\n if (browser.isSmartTV) {\n overrides.allowNativeHls = true;\n }\n return overrides;\n}\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/StormcloudVideoPlayer.ts\nvar StormcloudVideoPlayer = class {\n constructor(config) {\n this.attached = false;\n this.inAdBreak = false;\n this.ptsDriftEmaMs = 0;\n this.isLiveStream = false;\n this.nativeHlsMode = false;\n this.videoSrcProtection = null;\n this.bufferedSegmentsCount = 0;\n this.shouldAutoplayAfterBuffering = false;\n this.hasInitialBufferCompleted = false;\n initializePolyfills();\n const browserOverrides = getBrowserConfigOverrides();\n this.config = { ...config, ...browserOverrides };\n this.video = config.videoElement;\n logBrowserInfo(config.debugAdTiming);\n if (!this.config.licenseKey) {\n console.warn(\"[StormcloudVideoPlayer] No license key provided - ads will not work\");\n }\n this.adPlayer = createAdStormPlayer(this.video, {\n licenseKey: this.config.licenseKey || \"\",\n debug: this.config.debugAdTiming ?? false\n });\n }\n async load() {\n if (!this.attached) {\n this.attach();\n }\n if (this.shouldUseNativeHls()) {\n this.nativeHlsMode = true;\n this.videoSrcProtection = this.config.src;\n this.video.src = this.config.src;\n this.isLiveStream = this.config.lowLatencyMode ?? false;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Using native HLS playback:\", {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls\n });\n }\n this.adPlayer.initialize();\n this.adPlayer.setAllowNativeHls(!!this.config.allowNativeHls);\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {\n });\n }\n return;\n }\n this.hls = new Hls({\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(Hls.Events.MEDIA_ATTACHED, () => {\n this.hls?.loadSource(this.config.src);\n });\n this.hls.on(Hls.Events.MANIFEST_PARSED, async () => {\n this.isLiveStream = this.hls?.levels?.some(\n (level) => level?.details?.live === true || level?.details?.type === \"LIVE\"\n ) ?? false;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Stream type detected:\", {\n isLive: this.isLiveStream\n });\n }\n this.adPlayer.initialize();\n this.adPlayer.setAllowNativeHls(!!this.config.allowNativeHls);\n this.bufferedSegmentsCount = 0;\n this.hasInitialBufferCompleted = false;\n this.shouldAutoplayAfterBuffering = !!this.config.autoplay;\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Waiting for\",\n minSegments,\n \"segments to buffer before playback\"\n );\n }\n if (minSegments === 0 || !this.config.autoplay) {\n this.hasInitialBufferCompleted = true;\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {\n });\n }\n }\n });\n this.hls.on(Hls.Events.FRAG_BUFFERED, async () => {\n if (this.hasInitialBufferCompleted) {\n return;\n }\n this.bufferedSegmentsCount++;\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Buffered segment ${this.bufferedSegmentsCount}/${minSegments}`\n );\n }\n if (this.bufferedSegmentsCount >= minSegments) {\n this.hasInitialBufferCompleted = true;\n if (this.shouldAutoplayAfterBuffering) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Initial buffer complete. Starting playback.`\n );\n }\n await this.video.play()?.catch((err) => {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Autoplay failed:\", err);\n }\n });\n }\n }\n });\n this.hls.on(Hls.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(Hls.Events.FRAG_CHANGED, (_evt, data) => {\n const frag = data?.frag;\n const tagList = frag?.tagList;\n if (!Array.isArray(tagList)) return;\n for (const entry of tagList) {\n let tag = \"\";\n let value = \"\";\n if (Array.isArray(entry)) {\n tag = String(entry[0] ?? \"\");\n value = String(entry[1] ?? \"\");\n } else if (typeof entry === \"string\") {\n const idx = entry.indexOf(\":\");\n if (idx >= 0) {\n tag = entry.substring(0, idx);\n value = entry.substring(idx + 1);\n } else {\n tag = entry;\n value = \"\";\n }\n }\n if (!tag) continue;\n if (tag.includes(\"EXT-X-CUE-OUT\")) {\n const durationSeconds = this.parseCueOutDuration(value);\n this.onScte35Marker({\n type: \"start\",\n ...durationSeconds !== void 0 ? { durationSeconds } : {},\n raw: { tag, value }\n });\n } else if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n const prog = this.parseCueOutCont(value);\n this.onScte35Marker({\n type: \"progress\",\n ...prog?.duration !== void 0 ? { durationSeconds: prog.duration } : {},\n ...prog?.elapsed !== void 0 ? { ptsSeconds: prog.elapsed } : {},\n raw: { tag, value }\n });\n } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value } });\n } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n const attrs = this.parseAttributeList(value);\n const hasScteOut = \"SCTE35-OUT\" in attrs;\n const hasScteIn = \"SCTE35-IN\" in attrs;\n const klass = String(attrs[\"CLASS\"] ?? \"\");\n const duration = this.toNumber(attrs[\"DURATION\"]) ?? this.toNumber(attrs[\"PLANNED-DURATION\"]);\n if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n this.onScte35Marker({\n type: \"start\",\n ...duration !== void 0 ? { durationSeconds: duration } : {},\n raw: { tag, value, attrs }\n });\n }\n if (hasScteIn) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value, attrs } });\n }\n }\n }\n });\n this.hls.on(Hls.Events.ERROR, (_evt, data) => {\n if (data?.fatal) {\n switch (data.type) {\n case Hls.ErrorTypes.NETWORK_ERROR:\n this.hls?.startLoad();\n break;\n case Hls.ErrorTypes.MEDIA_ERROR:\n this.hls?.recoverMediaError();\n break;\n default:\n this.destroy();\n break;\n }\n }\n });\n this.hls.attachMedia(this.video);\n }\n attach() {\n if (this.attached) return;\n this.attached = true;\n this.video.autoplay = !!this.config.autoplay;\n this.video.muted = !!this.config.muted;\n this.adPlayer.initialize();\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n this.adPlayer.on(\"all_ads_completed\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad completed - ending ad break\");\n }\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n this.adPlayer.on(\"ad_error\", () => {\n console.error(\"[StormcloudVideoPlayer] Ad error occurred\");\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n this.adPlayer.on(\"content_pause\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content paused for ad\");\n }\n });\n this.adPlayer.on(\"content_resume\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content resuming after ad\");\n }\n });\n this.timeUpdateHandler = () => {\n };\n this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n this.emptiedHandler = () => {\n if (this.nativeHlsMode && this.videoSrcProtection && !this.adPlayer.isAdPlaying()) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Video src was cleared, restoring\");\n }\n const currentTime = this.video.currentTime;\n const wasPaused = this.video.paused;\n this.video.src = this.videoSrcProtection;\n this.video.currentTime = currentTime;\n if (!wasPaused) {\n this.video.play().catch(() => {\n });\n }\n }\n };\n this.video.addEventListener(\"emptied\", this.emptiedHandler);\n }\n shouldUseNativeHls() {\n const streamType = this.getStreamType();\n if (streamType === \"other\") {\n return true;\n }\n const canNative = this.video.canPlayType(\"application/vnd.apple.mpegurl\");\n return !!(this.config.allowNativeHls && canNative);\n }\n onId3Tag(tag) {\n if (typeof tag.ptsSeconds === \"number\") {\n this.updatePtsDrift(tag.ptsSeconds);\n }\n const marker = this.parseScte35FromId3(tag);\n if (marker) {\n this.onScte35Marker(marker);\n }\n }\n parseScte35FromId3(tag) {\n const text = this.decodeId3ValueToText(tag.value);\n if (!text) return void 0;\n const cueOutMatch = text.match(/EXT-X-CUE-OUT(?::([^\\r\\n]*))?/i) || text.match(/CUE-OUT(?::([^\\r\\n]*))?/i);\n if (cueOutMatch) {\n const arg = (cueOutMatch[1] ?? \"\").trim();\n const dur = this.parseCueOutDuration(arg);\n return {\n type: \"start\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n ...dur !== void 0 ? { durationSeconds: dur } : {},\n raw: { id3: text }\n };\n }\n const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\\r\\n]*)/i);\n if (cueOutContMatch) {\n const arg = (cueOutContMatch[1] ?? \"\").trim();\n const cont = this.parseCueOutCont(arg);\n return {\n type: \"progress\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n ...cont?.duration !== void 0 ? { durationSeconds: cont.duration } : {},\n raw: { id3: text }\n };\n }\n const cueInMatch = text.match(/EXT-X-CUE-IN\\b/i) || text.match(/CUE-IN\\b/i);\n if (cueInMatch) {\n return {\n type: \"end\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n raw: { id3: text }\n };\n }\n return void 0;\n }\n decodeId3ValueToText(value) {\n try {\n if (typeof value === \"string\") return value;\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n const text = decoder.decode(value);\n if (text && /[\\x20-\\x7E]/.test(text)) return text;\n let out = \"\";\n for (let i = 0; i < value.length; i++) {\n out += String.fromCharCode(value[i]);\n }\n return out;\n } catch {\n return void 0;\n }\n }\n async onScte35Marker(marker) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] SCTE-35 marker detected:\", {\n type: marker.type,\n ptsSeconds: marker.ptsSeconds,\n durationSeconds: marker.durationSeconds,\n currentTime: this.video.currentTime\n });\n }\n if (marker.type === \"start\") {\n if (this.inAdBreak) {\n return;\n }\n this.inAdBreak = true;\n const durationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : 3e4;\n this.expectedAdBreakDurationMs = durationMs;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Starting ad break:\", {\n durationMs,\n durationSeconds: marker.durationSeconds\n });\n }\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n await this.handleAdStart(marker);\n if (this.expectedAdBreakDurationMs != null) {\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n if (marker.type === \"progress\" && this.inAdBreak) {\n if (marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;\n }\n return;\n }\n if (marker.type === \"end\") {\n if (!this.inAdBreak) return;\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = void 0;\n this.clearAdStopTimer();\n if (this.adPlayer.isAdPlaying()) {\n await this.adPlayer.stop();\n }\n this.handleAdPodComplete();\n return;\n }\n }\n async handleAdStart(marker) {\n const durationSeconds = marker.durationSeconds ?? 30;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Requesting ads for duration:\", durationSeconds);\n }\n try {\n await this.adPlayer.requestAds(String(durationSeconds));\n await this.adPlayer.play();\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Ad request/play failed:\", error);\n }\n this.handleAdPodComplete();\n }\n }\n parseCueOutDuration(value) {\n const num = parseFloat(value.trim());\n if (!Number.isNaN(num)) return num;\n const match = value.match(/(?:^|[,\\s])DURATION\\s*=\\s*([0-9.]+)/i) || value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n if (match && match[1] != null) {\n const d = parseFloat(match[1]);\n return Number.isNaN(d) ? void 0 : d;\n }\n return void 0;\n }\n parseCueOutCont(value) {\n const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n const res = {};\n if (elapsedMatch && elapsedMatch[1] != null) {\n const e = parseFloat(elapsedMatch[1]);\n if (!Number.isNaN(e)) res.elapsed = e;\n }\n if (durationMatch && durationMatch[1] != null) {\n const d = parseFloat(durationMatch[1]);\n if (!Number.isNaN(d)) res.duration = d;\n }\n if (\"elapsed\" in res || \"duration\" in res) return res;\n return void 0;\n }\n parseAttributeList(value) {\n const attrs = {};\n const regex = /([A-Z0-9-]+)=((\"[^\"]*\")|([^\",]*))(?:,|$)/gi;\n let match;\n while ((match = regex.exec(value)) !== null) {\n const key = match[1] ?? \"\";\n let rawVal = match[3] ?? match[4] ?? \"\";\n if (rawVal.startsWith('\"') && rawVal.endsWith('\"')) {\n rawVal = rawVal.slice(1, -1);\n }\n if (key) {\n attrs[key] = rawVal;\n }\n }\n return attrs;\n }\n toNumber(val) {\n if (val == null) return void 0;\n const n = typeof val === \"string\" ? parseFloat(val) : Number(val);\n return Number.isNaN(n) ? void 0 : n;\n }\n scheduleAdStopCountdown(remainingMs) {\n this.clearAdStopTimer();\n const ms = Math.max(0, Math.floor(remainingMs));\n if (ms === 0) {\n this.handleAdPodComplete();\n return;\n }\n this.adStopTimerId = window.setTimeout(() => {\n this.handleAdPodComplete();\n }, ms);\n }\n clearAdStopTimer() {\n if (this.adStopTimerId != null) {\n clearTimeout(this.adStopTimerId);\n this.adStopTimerId = void 0;\n }\n }\n updatePtsDrift(ptsSecondsSample) {\n const sampleMs = (this.video.currentTime - ptsSecondsSample) * 1e3;\n if (!Number.isFinite(sampleMs) || Math.abs(sampleMs) > 6e4) return;\n const alpha = 0.1;\n this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;\n }\n handleAdPodComplete() {\n this.clearAdStopTimer();\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = void 0;\n this.adPlayer.stop().catch(() => {\n });\n const restoredMuted = this.adPlayer.getOriginalMutedState();\n const restoredVolume = this.adPlayer.getOriginalVolume();\n if (this.video.muted !== restoredMuted) {\n this.video.muted = restoredMuted;\n }\n if (Math.abs(this.video.volume - restoredVolume) > 0.01) {\n this.video.volume = restoredVolume;\n }\n if (this.video.paused) {\n this.video.play()?.catch(() => {\n });\n }\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad break complete\");\n }\n }\n isAdPlaying() {\n return this.inAdBreak && this.adPlayer.isAdPlaying();\n }\n isShowingAds() {\n return this.adPlayer.isAdPlaying();\n }\n getStreamType() {\n const url = this.config.src.toLowerCase();\n if (url.includes(\".m3u8\") || url.includes(\"/hls/\") || url.includes(\"application/vnd.apple.mpegurl\")) {\n return \"hls\";\n }\n return \"other\";\n }\n shouldShowNativeControls() {\n const streamType = this.getStreamType();\n if (streamType === \"other\") {\n return !(this.config.showCustomControls ?? false);\n }\n return !!(this.config.allowNativeHls && !(this.config.showCustomControls ?? false));\n }\n toggleMute() {\n if (this.adPlayer.isAdPlaying()) {\n const currentMuted = this.video.muted;\n const newMutedState = !currentMuted;\n this.adPlayer.updateOriginalMutedState(newMutedState, this.video.volume);\n this.adPlayer.setAdVolume(newMutedState ? 0 : 1);\n } else {\n this.video.muted = !this.video.muted;\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n }\n }\n toggleFullscreen() {\n return new Promise((resolve, reject) => {\n if (!document.fullscreenElement) {\n const container = this.video.parentElement;\n if (!container) {\n reject(new Error(\"No parent container found for fullscreen\"));\n return;\n }\n container.requestFullscreen().then(() => resolve()).catch(reject);\n } else {\n document.exitFullscreen().then(() => resolve()).catch(reject);\n }\n });\n }\n isMuted() {\n return this.video.muted;\n }\n setMuted(muted) {\n this.video.muted = muted;\n this.adPlayer.updateOriginalMutedState(muted, this.video.volume);\n if (this.adPlayer.isAdPlaying()) {\n this.adPlayer.setAdVolume(muted ? 0 : 1);\n }\n }\n setVolume(volume) {\n const clampedVolume = Math.max(0, Math.min(1, volume));\n if (this.adPlayer.isAdPlaying()) {\n this.adPlayer.setAdVolume(clampedVolume);\n this.adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n } else {\n this.video.volume = clampedVolume;\n this.video.muted = clampedVolume === 0;\n this.adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n }\n }\n isFullscreen() {\n return !!document.fullscreenElement;\n }\n isLive() {\n return this.isLiveStream;\n }\n get videoElement() {\n return this.video;\n }\n resize() {\n if (this.adPlayer && this.adPlayer.isAdPlaying()) {\n const width = this.video.clientWidth || 640;\n const height = this.video.clientHeight || 360;\n this.adPlayer.resize(width, height);\n }\n }\n destroy() {\n this.clearAdStopTimer();\n if (this.timeUpdateHandler) {\n this.video.removeEventListener(\"timeupdate\", this.timeUpdateHandler);\n delete this.timeUpdateHandler;\n }\n if (this.emptiedHandler) {\n this.video.removeEventListener(\"emptied\", this.emptiedHandler);\n delete this.emptiedHandler;\n }\n this.hls?.destroy();\n this.adPlayer?.destroy();\n }\n getCurrentAdIndex() {\n return 0;\n }\n getTotalAdsInBreak() {\n return 1;\n }\n};\n\n// src/ui/StormcloudVideoPlayer.tsx\nimport {\n FaPlay,\n FaPause,\n FaVolumeUp,\n FaVolumeMute,\n FaVolumeDown,\n FaExpand,\n FaCompress,\n FaSpinner\n} from \"react-icons/fa\";\nimport { Fragment, jsx, jsxs } from \"react/jsx-runtime\";\nvar CRITICAL_PROPS = [\n \"src\",\n \"allowNativeHls\",\n \"licenseKey\",\n \"lowLatencyMode\",\n \"driftToleranceMs\"\n];\nvar StormcloudVideoPlayerComponent = React.memo(\n (props) => {\n const {\n src,\n autoplay,\n muted,\n lowLatencyMode,\n allowNativeHls,\n driftToleranceMs,\n immediateManifestAds,\n debugAdTiming,\n showCustomControls,\n hideLoadingIndicator,\n onVolumeToggle,\n onFullscreenToggle,\n onControlClick,\n onReady,\n wrapperClassName,\n wrapperStyle,\n className,\n style,\n controls,\n playsInline,\n preload,\n poster,\n children,\n licenseKey,\n minSegmentsBeforePlay,\n ...restVideoAttrs\n } = props;\n const videoRef = useRef(null);\n const playerRef = useRef(null);\n const bufferingTimeoutRef = useRef(null);\n const [adStatus, setAdStatus] = React.useState({ showAds: false, currentIndex: 0, totalAds: 0 });\n const [shouldShowNativeControls, setShouldShowNativeControls] = React.useState(true);\n const [isMuted, setIsMuted] = React.useState(false);\n const [isFullscreen, setIsFullscreen] = React.useState(false);\n const [isPlaying, setIsPlaying] = React.useState(false);\n const [currentTime, setCurrentTime] = React.useState(0);\n const [duration, setDuration] = React.useState(0);\n const [volume, setVolume] = React.useState(1);\n const [playbackRate, setPlaybackRate] = React.useState(1);\n const [showVolumeSlider, setShowVolumeSlider] = React.useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = React.useState(false);\n const [isLoading, setIsLoading] = React.useState(true);\n const [isBuffering, setIsBuffering] = React.useState(false);\n const [showCenterPlay, setShowCenterPlay] = React.useState(false);\n const [showLicenseWarning, setShowLicenseWarning] = React.useState(false);\n const [viewportWidth, setViewportWidth] = React.useState(\n typeof window !== \"undefined\" ? window.innerWidth : 1920\n );\n const [isPortrait, setIsPortrait] = React.useState(\n typeof window !== \"undefined\" ? window.innerHeight > window.innerWidth : false\n );\n const getResponsiveScale = () => {\n if (viewportWidth < 480) return 0.7;\n if (viewportWidth < 768) return 0.8;\n if (viewportWidth < 1024) return 0.9;\n return 1;\n };\n const responsiveScale = getResponsiveScale();\n const formatTime = (seconds) => {\n if (!isFinite(seconds)) return \"0:00:00\";\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor(seconds % 3600 / 60);\n const remainingSeconds = Math.floor(seconds % 60);\n return `${hours}:${minutes.toString().padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n };\n const handlePlayPause = () => {\n if (videoRef.current) {\n if (videoRef.current.paused) {\n const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n } else {\n videoRef.current.pause();\n setShowCenterPlay(true);\n }\n }\n };\n const handleCenterPlayClick = () => {\n if (videoRef.current && videoRef.current.paused) {\n const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n }\n };\n const handleTimelineSeek = (e) => {\n if (videoRef.current && duration > 0 && isFinite(duration)) {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const progress = Math.max(0, Math.min(1, clickX / rect.width));\n const newTime = progress * duration;\n if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n videoRef.current.currentTime = newTime;\n }\n }\n };\n const handleVolumeChange = (newVolume) => {\n if (playerRef.current && isFinite(newVolume)) {\n const clampedVolume = Math.max(0, Math.min(1, newVolume));\n playerRef.current.setVolume(clampedVolume);\n }\n };\n const handlePlaybackRateChange = (rate) => {\n if (videoRef.current && isFinite(rate) && rate > 0) {\n videoRef.current.playbackRate = rate;\n }\n setShowSpeedMenu(false);\n };\n const isHlsStream = src?.toLowerCase().includes(\".m3u8\") || src?.toLowerCase().includes(\"/hls/\");\n const shouldShowEnhancedControls = showCustomControls && (isHlsStream ? allowNativeHls : true);\n const criticalPropsKey = useMemo(() => {\n return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n }, [\n src,\n allowNativeHls,\n licenseKey,\n lowLatencyMode,\n driftToleranceMs\n ]);\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const el = videoRef.current;\n if (!el || !src) return;\n if (!licenseKey) {\n setShowLicenseWarning(true);\n setIsLoading(false);\n console.warn(\n \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n );\n return;\n }\n setShowLicenseWarning(false);\n if (debugAdTiming) {\n console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n }\n if (playerRef.current) {\n try {\n playerRef.current.destroy();\n } catch {\n }\n playerRef.current = null;\n }\n const cfg = {\n src,\n videoElement: el\n };\n if (autoplay !== void 0) cfg.autoplay = autoplay;\n if (muted !== void 0) cfg.muted = muted;\n if (lowLatencyMode !== void 0) cfg.lowLatencyMode = lowLatencyMode;\n if (allowNativeHls !== void 0) cfg.allowNativeHls = allowNativeHls;\n if (driftToleranceMs !== void 0)\n cfg.driftToleranceMs = driftToleranceMs;\n if (immediateManifestAds !== void 0)\n cfg.immediateManifestAds = immediateManifestAds;\n if (debugAdTiming !== void 0) cfg.debugAdTiming = debugAdTiming;\n if (showCustomControls !== void 0)\n cfg.showCustomControls = showCustomControls;\n if (onVolumeToggle !== void 0) cfg.onVolumeToggle = onVolumeToggle;\n if (onFullscreenToggle !== void 0)\n cfg.onFullscreenToggle = onFullscreenToggle;\n if (onControlClick !== void 0) cfg.onControlClick = onControlClick;\n if (licenseKey !== void 0) cfg.licenseKey = licenseKey;\n if (minSegmentsBeforePlay !== void 0)\n cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n const player = new StormcloudVideoPlayer(cfg);\n playerRef.current = player;\n player.load().then(() => {\n const showNative = player.shouldShowNativeControls();\n setShouldShowNativeControls(showNative);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n );\n }\n onReady?.(player);\n }).catch((error) => {\n console.error(\n \"StormcloudVideoPlayer: Failed to load player:\",\n error\n );\n setIsLoading(false);\n onReady?.(player);\n });\n return () => {\n try {\n player.destroy();\n } catch {\n }\n playerRef.current = null;\n };\n }, [criticalPropsKey]);\n 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 useEffect(() => {\n if (!playerRef.current) return;\n const checkAdStatus = () => {\n if (playerRef.current) {\n const showAds = playerRef.current.isShowingAds();\n const currentIndex = playerRef.current.getCurrentAdIndex();\n const totalAds = playerRef.current.getTotalAdsInBreak();\n setAdStatus((prev) => {\n if (prev.showAds !== showAds || prev.currentIndex !== currentIndex || prev.totalAds !== totalAds) {\n return { showAds, currentIndex, totalAds };\n }\n return prev;\n });\n }\n };\n const interval = setInterval(checkAdStatus, 100);\n return () => clearInterval(interval);\n }, []);\n 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 useEffect(() => {\n if (!playerRef.current || !videoRef.current) return;\n const updateStates = () => {\n if (playerRef.current && videoRef.current) {\n setIsMuted(playerRef.current.isMuted());\n setIsPlaying(!videoRef.current.paused);\n const currentTimeValue = videoRef.current.currentTime;\n setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n const durationValue = videoRef.current.duration;\n setDuration(isFinite(durationValue) ? durationValue : 0);\n const volumeValue = videoRef.current.volume;\n setVolume(\n isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n );\n const rateValue = videoRef.current.playbackRate;\n setPlaybackRate(\n isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n );\n }\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n const interval = setInterval(updateStates, 200);\n const handleFullscreenChange = () => {\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () => {\n clearInterval(interval);\n document.removeEventListener(\n \"fullscreenchange\",\n handleFullscreenChange\n );\n };\n }, []);\n useEffect(() => {\n if (!videoRef.current) return;\n const handleLoadedMetadata = () => {\n if (videoRef.current) {\n const video2 = videoRef.current;\n void video2.offsetHeight;\n }\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleLoadedData = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadeddata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleLoadStart = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadstart, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleCanPlay = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplay, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n const handleCanPlayThrough = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n const handleWaiting = () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n }\n bufferingTimeoutRef.current = window.setTimeout(() => {\n setIsBuffering(true);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n videoRef.current?.readyState,\n \"- showing spinner, isBuffering=true\"\n );\n }\n }, 300);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: waiting, readyState:\",\n videoRef.current?.readyState,\n \"- buffering delay started (300ms)\"\n );\n }\n };\n const handlePlaying = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n setShowCenterPlay(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: playing, readyState:\",\n videoRef.current?.readyState,\n \"- playback started, isLoading=false, isBuffering=false\"\n );\n }\n };\n const handlePause = () => {\n if (playerRef.current && !playerRef.current.isShowingAds()) {\n setShowCenterPlay(true);\n } else {\n setShowCenterPlay(false);\n }\n };\n const handleEnded = () => {\n setShowCenterPlay(true);\n };\n const video = videoRef.current;\n video.addEventListener(\"loadstart\", handleLoadStart);\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"playing\", handlePlaying);\n video.addEventListener(\"pause\", handlePause);\n video.addEventListener(\"ended\", handleEnded);\n if (video.paused) {\n setShowCenterPlay(true);\n }\n return () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n video.removeEventListener(\"loadstart\", handleLoadStart);\n video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"playing\", handlePlaying);\n video.removeEventListener(\"pause\", handlePause);\n video.removeEventListener(\"ended\", handleEnded);\n };\n }, [debugAdTiming]);\n return /* @__PURE__ */ jsxs(Fragment, { children: [\n /* @__PURE__ */ jsx(\"style\", { children: `\n @keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n \n .stormcloud-loading-hidden .stormcloud-loading-indicator {\n display: none !important;\n }\n \n .stormcloud-video-wrapper:fullscreen {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n .stormcloud-video-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n *:fullscreen {\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n }\n ` }),\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n className: `stormcloud-video-wrapper ${wrapperClassName || \"\"}`,\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n position: isFullscreen ? \"fixed\" : \"relative\",\n top: isFullscreen ? 0 : void 0,\n left: isFullscreen ? 0 : void 0,\n overflow: \"hidden\",\n width: isFullscreen ? \"100vw\" : \"100%\",\n height: isFullscreen ? \"100vh\" : \"auto\",\n minHeight: isFullscreen ? \"100vh\" : \"auto\",\n maxWidth: isFullscreen ? \"100vw\" : \"100%\",\n maxHeight: isFullscreen ? \"100vh\" : \"none\",\n zIndex: isFullscreen ? 999999 : void 0,\n backgroundColor: isFullscreen ? \"#000\" : void 0,\n borderRadius: isFullscreen ? 0 : void 0,\n boxShadow: isFullscreen ? \"none\" : void 0,\n ...wrapperStyle\n },\n children: [\n /* @__PURE__ */ jsx(\n \"video\",\n {\n ref: videoRef,\n className,\n style: {\n display: \"block\",\n width: \"100%\",\n height: isFullscreen ? \"100%\" : \"auto\",\n maxWidth: \"100%\",\n maxHeight: isFullscreen ? \"100%\" : \"none\",\n objectFit: isFullscreen ? \"cover\" : \"contain\",\n backgroundColor: \"#000\",\n aspectRatio: isFullscreen ? \"unset\" : void 0,\n ...style\n },\n controls: shouldShowNativeControls && controls && !showCustomControls,\n playsInline,\n preload,\n poster,\n ...restVideoAttrs,\n children\n }\n ),\n (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ jsx(\n FaSpinner,\n {\n className: \"stormcloud-loading-indicator\",\n size: 42,\n color: \"white\",\n style: {\n position: \"absolute\",\n top: \"calc(50% - 21px)\",\n left: \"calc(50% - 21px)\",\n zIndex: 20,\n animation: \"spin 1s linear infinite\",\n filter: \"drop-shadow(0 3px 6px rgba(0, 0, 0, 0.8))\"\n }\n }\n ),\n showLicenseWarning && /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 25,\n background: \"linear-gradient(135deg, rgba(220, 38, 38, 0.95) 0%, rgba(185, 28, 28, 0.9) 100%)\",\n color: \"white\",\n padding: \"24px 32px\",\n borderRadius: \"16px\",\n backdropFilter: \"blur(20px)\",\n border: \"2px solid rgba(255, 255, 255, 0.2)\",\n boxShadow: \"0 20px 60px rgba(0, 0, 0, 0.6), inset 0 2px 0 rgba(255, 255, 255, 0.2)\",\n textAlign: \"center\",\n maxWidth: \"400px\",\n margin: \"0 16px\"\n },\n children: [\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n fontSize: \"20px\",\n fontWeight: \"bold\",\n marginBottom: \"12px\",\n color: \"#ffffff\",\n textShadow: \"0 2px 4px rgba(0, 0, 0, 0.5)\"\n },\n children: \"License Key Required\"\n }\n ),\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n fontSize: \"14px\",\n lineHeight: \"1.5\",\n color: \"rgba(255, 255, 255, 0.9)\",\n textShadow: \"0 1px 2px rgba(0, 0, 0, 0.3)\"\n },\n children: [\n \"Please provide a valid license key to use the Stormcloud Video Player.\",\n /* @__PURE__ */ jsx(\"br\", {}),\n \"Contact your administrator for licensing information.\"\n ]\n }\n )\n ]\n }\n ),\n showCenterPlay && !isLoading && !isBuffering && !showLicenseWarning && !adStatus.showAds && /* @__PURE__ */ jsx(\n \"div\",\n {\n onClick: handleCenterPlayClick,\n style: {\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 15,\n cursor: \"pointer\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\",\n borderRadius: \"50%\",\n width: \"100px\",\n height: \"100px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n border: \"3px solid rgba(255, 255, 255, 0.8)\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\"\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.95) 0%, rgba(40, 40, 40, 0.9) 100%)\";\n target.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.9), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.9)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\";\n target.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.8)\";\n },\n title: \"Play\",\n children: /* @__PURE__ */ jsx(\n FaPlay,\n {\n size: 36,\n color: \"white\",\n style: {\n marginLeft: \"6px\",\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\"\n }\n }\n )\n }\n ),\n shouldShowEnhancedControls && !showLicenseWarning ? /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: 0,\n left: 0,\n right: 0,\n background: \"linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.8) 100%)\",\n padding: \"20px 16px 16px\",\n zIndex: 10\n },\n children: [\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"8px\",\n background: \"linear-gradient(90deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%)\",\n borderRadius: \"8px\",\n marginBottom: \"16px\",\n cursor: \"pointer\",\n position: \"relative\",\n backdropFilter: \"blur(5px)\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n boxShadow: \"inset 0 2px 4px rgba(0, 0, 0, 0.2)\"\n },\n onClick: handleTimelineSeek,\n children: [\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n height: \"100%\",\n background: \"linear-gradient(90deg, rgba(139, 92, 246, 0.9) 0%, rgba(59, 130, 246, 0.8) 50%, rgba(34, 197, 94, 0.9) 100%)\",\n borderRadius: \"8px\",\n width: `${duration > 0 ? currentTime / duration * 100 : 0}%`,\n transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 2px 8px rgba(139, 92, 246, 0.4)\"\n }\n }\n ),\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n top: \"-6px\",\n right: `${duration > 0 ? 100 - currentTime / duration * 100 : 100}%`,\n width: \"20px\",\n height: \"20px\",\n background: \"linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(240, 240, 240, 0.9) 100%)\",\n borderRadius: \"50%\",\n border: \"3px solid rgba(139, 92, 246, 0.8)\",\n boxShadow: \"0 4px 16px rgba(139, 92, 246, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.8)\",\n transform: \"translateX(50%)\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\"\n }\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n color: \"white\",\n flexWrap: viewportWidth < 768 ? \"wrap\" : \"nowrap\",\n gap: `${8 * responsiveScale}px`\n },\n children: [\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n flexWrap: viewportWidth < 480 ? \"wrap\" : \"nowrap\"\n },\n children: [\n /* @__PURE__ */ jsx(\n \"button\",\n {\n onClick: handlePlayPause,\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n backdropFilter: \"blur(12px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${10 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n minWidth: `${48 * responsiveScale}px`,\n minHeight: `${48 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n target.style.boxShadow = \"0 12px 48px rgba(0, 0, 0, 0.6), 0 6px 24px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n target.style.boxShadow = \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n },\n title: isPlaying ? \"Pause\" : \"Play\",\n children: isPlaying ? /* @__PURE__ */ jsx(\n FaPause,\n {\n size: Math.max(16, 20 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n ) : /* @__PURE__ */ jsx(\n FaPlay,\n {\n size: Math.max(16, 20 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n )\n }\n ),\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\"\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false),\n children: [\n /* @__PURE__ */ jsx(\n \"button\",\n {\n onClick: () => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: isMuted ? \"Unmute\" : \"Mute\",\n children: isMuted || volume === 0 ? /* @__PURE__ */ jsx(\n FaVolumeMute,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n ) : volume < 0.5 ? /* @__PURE__ */ jsx(\n FaVolumeDown,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n ) : /* @__PURE__ */ jsx(\n FaVolumeUp,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n )\n }\n ),\n showVolumeSlider && /* @__PURE__ */ jsxs(Fragment, { children: [\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false)\n }\n ),\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.88) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(15px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"1px solid rgba(255, 255, 255, 0.15)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\",\n zIndex: 10,\n transition: \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.6), 0 6px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 0 24px rgba(59, 130, 246, 0.3)\";\n e.currentTarget.style.borderColor = \"rgba(59, 130, 246, 0.4)\";\n },\n onMouseLeave: (e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\";\n e.currentTarget.style.borderColor = \"rgba(255, 255, 255, 0.15)\";\n },\n children: /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n },\n onMouseLeave: (e) => {\n },\n onMouseDown: (e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n const handleMouseMove = (moveEvent) => {\n if (!sliderElement) return;\n const rect2 = sliderElement.getBoundingClientRect();\n const y2 = moveEvent.clientY - rect2.top;\n const percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));\n handleVolumeChange(percentage2);\n };\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n const rect = sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n onClick: (e) => {\n e.stopPropagation();\n const rect = e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n children: [\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background: \"linear-gradient(180deg, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0.15) 100%)\",\n borderRadius: \"4px\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.2)\"\n }\n }\n ),\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background: \"linear-gradient(180deg, rgba(96, 165, 250, 1) 0%, rgba(59, 130, 246, 0.95) 50%, rgba(37, 99, 235, 0.9) 100%)\",\n borderRadius: \"4px\",\n transition: \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow: \"0 0 8px rgba(59, 130, 246, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3)\"\n }\n }\n ),\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `calc(${(isMuted ? 0 : volume) * 100}% - 7px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"14px\",\n height: \"14px\",\n background: \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n boxShadow: \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\",\n transition: \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\"\n },\n onMouseEnter: (e) => {\n e.currentTarget.style.boxShadow = \"0 3px 10px rgba(0, 0, 0, 0.4), 0 0 0 3px rgba(59, 130, 246, 0.5), 0 0 20px rgba(59, 130, 246, 0.6)\";\n e.currentTarget.style.cursor = \"grab\";\n },\n onMouseLeave: (e) => {\n e.currentTarget.style.boxShadow = \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\";\n },\n onMouseDown: (e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n },\n onMouseUp: (e) => {\n e.currentTarget.style.cursor = \"grab\";\n }\n }\n )\n ]\n }\n )\n }\n )\n ] })\n ]\n }\n ),\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n color: \"rgba(255, 255, 255, 0.9)\",\n display: viewportWidth < 480 ? \"none\" : \"block\"\n },\n children: [\n formatTime(currentTime),\n \" / \",\n formatTime(duration)\n ]\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`\n },\n children: [\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: viewportWidth < 600 ? \"none\" : \"block\"\n },\n children: [\n /* @__PURE__ */ jsxs(\n \"button\",\n {\n onClick: () => setShowSpeedMenu(!showSpeedMenu),\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px ${14 * responsiveScale}px`,\n borderRadius: `${14 * responsiveScale}px`,\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n fontWeight: \"700\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${56 * responsiveScale}px`,\n minHeight: `${40 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 32px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: \"Playback Speed\",\n children: [\n playbackRate,\n \"x\"\n ]\n }\n ),\n showSpeedMenu && /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n right: 0,\n marginBottom: \"12px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.95) 100%)\",\n backdropFilter: \"blur(20px)\",\n borderRadius: \"12px\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n overflow: \"hidden\",\n minWidth: \"90px\",\n boxShadow: \"0 16px 48px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.1)\"\n },\n children: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map(\n (speed) => /* @__PURE__ */ jsxs(\n \"button\",\n {\n onClick: () => handlePlaybackRateChange(speed),\n style: {\n display: \"block\",\n width: \"100%\",\n padding: \"10px 16px\",\n background: playbackRate === speed ? \"linear-gradient(135deg, rgba(99, 102, 241, 0.8) 0%, rgba(139, 92, 246, 0.6) 100%)\" : \"transparent\",\n border: \"none\",\n color: \"white\",\n cursor: \"pointer\",\n fontSize: \"13px\",\n fontFamily: \"monospace\",\n fontWeight: \"600\",\n textAlign: \"center\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n borderBottom: speed !== 2 ? \"1px solid rgba(255, 255, 255, 0.05)\" : \"none\"\n },\n onMouseEnter: (e) => {\n if (playbackRate !== speed) {\n e.target.style.background = \"linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.05) 100%)\";\n }\n },\n onMouseLeave: (e) => {\n if (playbackRate !== speed) {\n e.target.style.background = \"transparent\";\n }\n },\n children: [\n speed,\n \"x\"\n ]\n },\n speed\n )\n )\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ jsx(\n \"button\",\n {\n onClick: () => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n children: isFullscreen ? /* @__PURE__ */ jsx(\n FaCompress,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n ) : /* @__PURE__ */ jsx(\n FaExpand,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n )\n }\n )\n ]\n }\n )\n ]\n }\n )\n ]\n }\n ) }) : showCustomControls && !showLicenseWarning && /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `${10 * responsiveScale}px`,\n right: `${10 * responsiveScale}px`,\n transform: \"none\",\n display: \"flex\",\n flexDirection: isPortrait ? \"column\" : \"row\",\n gap: `${10 * responsiveScale}px`,\n zIndex: 10\n },\n children: [\n /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\"\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false),\n children: [\n /* @__PURE__ */ jsx(\n \"button\",\n {\n onClick: () => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow: \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`\n },\n title: isMuted ? \"Unmute\" : \"Mute\",\n children: isMuted || volume === 0 ? /* @__PURE__ */ jsx(\n FaVolumeMute,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : volume < 0.5 ? /* @__PURE__ */ jsx(\n FaVolumeDown,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : /* @__PURE__ */ jsx(\n FaVolumeUp,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n )\n }\n ),\n showVolumeSlider && /* @__PURE__ */ jsxs(Fragment, { children: [\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false)\n }\n ),\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.96) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(20px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"2px solid rgba(255, 255, 255, 0.7)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\",\n zIndex: 10,\n transition: \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.9), 0 6px 16px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 24px rgba(96, 165, 250, 0.4)\";\n e.currentTarget.style.borderColor = \"rgba(96, 165, 250, 0.8)\";\n },\n onMouseLeave: (e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\";\n e.currentTarget.style.borderColor = \"rgba(255, 255, 255, 0.7)\";\n },\n children: /* @__PURE__ */ jsxs(\n \"div\",\n {\n style: {\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\"\n },\n onMouseDown: (e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n const handleMouseMove = (moveEvent) => {\n if (!sliderElement) return;\n const rect2 = sliderElement.getBoundingClientRect();\n const y2 = moveEvent.clientY - rect2.top;\n const percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));\n handleVolumeChange(percentage2);\n };\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n const rect = sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n onClick: (e) => {\n e.stopPropagation();\n const rect = e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n children: [\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background: \"linear-gradient(180deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.5) 100%)\",\n borderRadius: \"4px\",\n border: \"1px solid rgba(255, 255, 255, 0.4)\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.3)\"\n }\n }\n ),\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background: \"linear-gradient(180deg, rgba(125, 211, 252, 1) 0%, rgba(96, 165, 250, 0.98) 50%, rgba(59, 130, 246, 0.95) 100%)\",\n borderRadius: \"4px\",\n transition: \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow: \"0 0 12px rgba(96, 165, 250, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.4)\"\n }\n }\n ),\n /* @__PURE__ */ jsx(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `calc(${(isMuted ? 0 : volume) * 100}% - 8px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"16px\",\n height: \"16px\",\n background: \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n border: \"2px solid rgba(96, 165, 250, 0.9)\",\n boxShadow: \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\",\n transition: \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\"\n },\n onMouseEnter: (e) => {\n e.currentTarget.style.boxShadow = \"0 4px 12px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(96, 165, 250, 0.6), 0 0 24px rgba(96, 165, 250, 0.7)\";\n e.currentTarget.style.cursor = \"grab\";\n },\n onMouseLeave: (e) => {\n e.currentTarget.style.boxShadow = \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\";\n },\n onMouseDown: (e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n },\n onMouseUp: (e) => {\n e.currentTarget.style.cursor = \"grab\";\n }\n }\n )\n ]\n }\n )\n }\n )\n ] })\n ]\n }\n ),\n /* @__PURE__ */ jsx(\n \"button\",\n {\n onClick: () => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow: \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`\n },\n title: isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n children: isFullscreen ? /* @__PURE__ */ jsx(\n FaCompress,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : /* @__PURE__ */ jsx(\n FaExpand,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n )\n }\n )\n ]\n }\n ),\n onControlClick && /* @__PURE__ */ 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\nimport React3, { Component as Component4, Suspense } from \"react\";\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 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\nimport { lazy as reactLazy } from \"react\";\nvar lazy = reactLazy;\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\nimport { Component } from \"react\";\nvar HlsPlayer = class extends 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.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 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\nimport { Component as Component2 } from \"react\";\nvar FilePlayer = class extends Component2 {\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\nimport React2, { Component as Component3 } from \"react\";\nvar SEEK_ON_PLAY_EXPIRY = 5e3;\nvar Player = class extends Component3 {\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 React2.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 ? 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 \"driftToleranceMs\",\n \"immediateManifestAds\",\n \"debugAdTiming\",\n \"showCustomControls\",\n \"licenseKey\",\n \"adFailsafeTimeoutMs\",\n \"minSegmentsBeforePlay\",\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 Component4 {\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 React3.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 React3.createElement(\n Wrapper,\n {\n ref: wrapperRef,\n style: { ...style, width, height },\n ...attributes\n },\n React3.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\n// src/utils/tracking.ts\nvar cachedBrowserId = null;\nfunction getClientInfo() {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = navigator.deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: screen?.orientation?.type || \"\",\n pixelDepth: screen?.pixelDepth\n };\n let deviceType = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim() : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"NetCast\") || ua.includes(\"LG\"))) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n if (ua.includes(\"Android\") && (maxTouchPoints === 0 || ua.includes(\"Google TV\") || ua.includes(\"XiaoMi\"))) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n isWebApp = window.matchMedia(\"(display-mode: standalone)\").matches || window.navigator.standalone === true || window.screen?.orientation?.angle !== void 0;\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState\n };\n}\nasync function getBrowserID(clientInfo) {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n const fingerprintString = JSON.stringify(clientInfo);\n if (typeof crypto !== \"undefined\" && crypto.subtle && crypto.subtle.digest) {\n try {\n await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n let encodedData;\n if (typeof TextEncoder !== \"undefined\") {\n encodedData = new TextEncoder().encode(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\n const buffer = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i++) {\n buffer[i] = utf8.charCodeAt(i);\n }\n encodedData = buffer;\n }\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n const timestamp = Date.now().toString(16).padStart(12, \"0\");\n const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\nasync function sendInitialTracking(licenseKey) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = {\n browserId,\n ...clientInfo\n };\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(trackingData)\n }\n );\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\nasync function sendHeartbeat(licenseKey) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const heartbeatData = {\n browserId,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n };\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(heartbeatData)\n }\n );\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n } catch (error) {\n console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n }\n}\n\n// src/sdk/hlsAdPlayer.ts\nimport Hls2 from \"hls.js\";\nvar UNSUPPORTED_VIDEO_EXTENSIONS2 = [\".flv\", \".f4v\", \".swf\", \".wmv\", \".avi\", \".mov\", \".mkv\", \".mp4\", \".webm\"];\nfunction getFileExtension2(url) {\n try {\n const pathname = new URL(url, \"http://dummy\").pathname;\n const lastDot = pathname.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || \"\").toLowerCase();\n }\n}\nfunction isUnsupportedForHls(url) {\n const ext = getFileExtension2(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS2.indexOf(ext) !== -1;\n}\nfunction replaceFlvExtension2(url) {\n const ext = getFileExtension2(url);\n if (ext === \".flv\") {\n return url.replace(/\\.flv(\\?|$)/i, \".mp4$1\");\n }\n return url;\n}\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 let allowNativeHls = false;\n const listeners = /* @__PURE__ */ new Map();\n const licenseKey = options?.licenseKey;\n const mainHlsInstance = options?.mainHlsInstance;\n let adVideoElement;\n let adHls;\n let adContainerEl;\n let currentAd;\n let sessionId;\n 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 buildVastUrl(durationSeconds) {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n const metadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5e3,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48e3,\n bitrate: 128\n }\n };\n const metadataStr = encodeURIComponent(JSON.stringify(metadata));\n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\n }\n function fireTrackingPixels(urls) {\n if (!urls || urls.length === 0) return;\n urls.forEach((url) => {\n try {\n let trackingUrl = url;\n if (sessionId) {\n trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}session_id=${sessionId}`;\n }\n if (licenseKey) {\n trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}license_key=${licenseKey}`;\n }\n const img = new Image(1, 1);\n img.src = trackingUrl;\n console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n }\n });\n }\n function getMainStreamQuality() {\n if (!mainHlsInstance || !mainHlsInstance.levels) {\n return null;\n }\n const currentLevel = mainHlsInstance.currentLevel;\n if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n const autoLevel = mainHlsInstance.loadLevel;\n if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n const level2 = mainHlsInstance.levels[autoLevel];\n return {\n width: level2.width || 1920,\n height: level2.height || 1080,\n bitrate: level2.bitrate || 5e6\n };\n }\n return null;\n }\n const level = mainHlsInstance.levels[currentLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5e6\n };\n }\n function selectBestMediaFile(mediaFiles) {\n if (mediaFiles.length === 0) {\n throw new Error(\"No media files available\");\n }\n const firstFile = mediaFiles[0];\n if (!firstFile) {\n throw new Error(\"No media files available\");\n }\n if (mediaFiles.length === 1) {\n return firstFile;\n }\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n console.log(\n \"[HlsAdPlayer] No main stream quality info, using first media file\"\n );\n return firstFile;\n }\n console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\n const scoredFiles = mediaFiles.map((file) => {\n const widthDiff = Math.abs(file.width - mainQuality.width);\n const heightDiff = Math.abs(file.height - mainQuality.height);\n const resolutionDiff = widthDiff + heightDiff;\n const fileBitrate = (file.bitrate || 5e3) * 1e3;\n const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n const score = resolutionDiff * 2 + bitrateDiff / 1e3;\n return { file, score, resolutionDiff, bitrateDiff };\n });\n scoredFiles.sort((a, b) => a.score - b.score);\n const bestMatch = scoredFiles[0];\n if (!bestMatch) {\n console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n return firstFile;\n }\n console.log(\"[HlsAdPlayer] Selected media file:\", {\n url: bestMatch.file.url,\n resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n bitrate: bestMatch.file.bitrate,\n score: bestMatch.score,\n resolutionDiff: bestMatch.resolutionDiff,\n bitrateDiff: bestMatch.bitrateDiff\n });\n return bestMatch.file;\n }\n function parseVastXml(xmlString) {\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\n \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n parserError.textContent\n );\n return null;\n }\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n return null;\n }\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n const isNoAdAvailable = adId === \"empty\" || title.toLowerCase().includes(\"no ad available\") || title.toLowerCase() === \"no ad available\";\n const durationText = xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + parseInt(durationParts[2] || \"0\", 10);\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles = [];\n console.log(\n `[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n );\n mediaFileElements.forEach((mf, index) => {\n const type = mf.getAttribute(\"type\") || \"\";\n let 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 originalUrl = url;\n url = replaceFlvExtension2(url);\n if (url !== originalUrl) {\n console.log(`[HlsAdPlayer] Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n if (isUnsupportedForHls(url)) {\n const ext = getFileExtension2(url);\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored: unsupported format (extension: ${ext}, declared type: ${type})`\n );\n return;\n }\n if (type === \"application/x-mpegURL\" || type.includes(\"m3u8\")) {\n if (!url) {\n console.warn(\n `[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`\n );\n return;\n }\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0\n });\n console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);\n } else {\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not HLS)`\n );\n }\n });\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n \"[HlsAdPlayer] No ads available (VAST response indicates no ads)\"\n );\n } else {\n console.warn(\"[HlsAdPlayer] No HLS media files found in VAST XML\");\n }\n return null;\n }\n const trackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: []\n };\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n const clickThrough = xmlDoc.querySelector(\"ClickThrough\")?.textContent?.trim();\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough\n };\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n return null;\n }\n }\n async function fetchAndParseVastAd(url) {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n const vastXml = await response.text();\n console.log(\"[HlsAdPlayer] VAST XML received\");\n console.log(\n \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n vastXml.substring(0, 2e3)\n );\n return parseVastXml(vastXml);\n }\n function createAdVideoElement() {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.playsInline = true;\n video.muted = false;\n video.volume = 1;\n console.log(\n `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n );\n return video;\n }\n function setupAdEventListeners() {\n if (!adVideoElement || !currentAd) return;\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!currentAd || !adVideoElement) return;\n const progress = adVideoElement.currentTime / currentAd.duration;\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.firstQuartile);\n }\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(currentAd.trackingUrls.midpoint);\n }\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);\n }\n });\n adVideoElement.addEventListener(\"playing\", () => {\n if (!currentAd || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(currentAd.trackingUrls.start);\n console.log(\"[HlsAdPlayer] Ad started playing\");\n });\n adVideoElement.addEventListener(\"ended\", () => {\n if (!currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(currentAd.trackingUrls.complete);\n console.log(\"[HlsAdPlayer] Ad completed\");\n handleAdComplete();\n });\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[HlsAdPlayer] Ad video error:\", e);\n if (currentAd) {\n fireTrackingPixels(currentAd.trackingUrls.error);\n }\n handleAdError();\n });\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd) return;\n if (adVideoElement.muted) {\n fireTrackingPixels(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels(currentAd.trackingUrls.unmute);\n }\n });\n adVideoElement.addEventListener(\"pause\", () => {\n if (currentAd && !adVideoElement.ended) {\n fireTrackingPixels(currentAd.trackingUrls.pause);\n }\n });\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && adVideoElement.currentTime > 0) {\n fireTrackingPixels(currentAd.trackingUrls.resume);\n }\n });\n }\n function setAdPlayingFlag(isPlaying) {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n function handleAdComplete() {\n console.log(\"[HlsAdPlayer] Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n emit(\"content_resume\");\n const timeoutId = window.setTimeout(() => {\n if (destroyed) {\n console.log(\"[HlsAdPlayer] Player destroyed, skipping post-completion check\");\n return;\n }\n const stillInPod = contentVideo.dataset.stormcloudAdPlaying === \"true\";\n if (stillInPod) {\n console.log(\n \"[HlsAdPlayer] Still in ad pod - keeping ad container visible (black screen)\"\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n }\n const idx = pendingTimeouts.indexOf(timeoutId);\n if (idx !== -1) {\n pendingTimeouts.splice(idx, 1);\n }\n }, 50);\n pendingTimeouts.push(timeoutId);\n }\n function handleAdError() {\n console.log(\"[HlsAdPlayer] Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n const previousMutedState = contentVideo.muted;\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n console.log(\n `[HlsAdPlayer] Restored mute state: ${previousMutedState} -> ${originalMutedState}`\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (!options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n contentVideo.play().catch(() => {\n });\n }\n }\n emit(\"ad_error\");\n }\n return {\n initialize() {\n console.log(\"[HlsAdPlayer] Initializing\");\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n async requestAds(duration) {\n console.log(\"[HlsAdPlayer] Requesting ads for duration:\", duration);\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 durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n const vastUrl = buildVastUrl(durationSeconds);\n const ad = await fetchAndParseVastAd(vastUrl);\n if (!ad) {\n console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n currentAd = ad;\n console.log(\n `[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`\n );\n fireTrackingPixels(ad.trackingUrls.impression);\n trackingFired.impression = true;\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n async play() {\n if (!currentAd) {\n console.warn(\n \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n );\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n console.log(\"[HlsAdPlayer] Starting ad playback\");\n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(\n 0,\n Math.min(1, contentVolume || originalVolume)\n );\n if (!options?.continueLiveStreamDuringAds) {\n contentVideo.pause();\n console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n } else {\n console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n }\n console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n if (adVideoElement) {\n const adVolume = originalMutedState ? 0 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\n console.log(\n `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`\n );\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n emit(\"content_pause\");\n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available for ad\");\n }\n console.log(`[HlsAdPlayer] Loading ad from: ${mediaFile.url}`);\n if (Hls2.isSupported()) {\n if (adHls) {\n adHls.destroy();\n }\n adHls = new Hls2({\n enableWorker: true,\n lowLatencyMode: false\n });\n adHls.loadSource(mediaFile.url);\n adHls.attachMedia(adVideoElement);\n adHls.on(Hls2.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(Hls2.Events.ERROR, (event, data) => {\n console.error(\"[HlsAdPlayer] HLS error:\", data);\n if (data.fatal) {\n handleAdError();\n }\n });\n } else if (adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n } else {\n throw new Error(\"HLS not supported\");\n }\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n async stop() {\n console.log(\"[HlsAdPlayer] Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n currentAd = void 0;\n },\n destroy() {\n console.log(\"[HlsAdPlayer] Destroying\");\n destroyed = true;\n for (const timeoutId of pendingTimeouts) {\n clearTimeout(timeoutId);\n }\n pendingTimeouts = [];\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = void 0;\n }\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n adContainerEl = void 0;\n currentAd = void 0;\n listeners.clear();\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width, height) {\n console.log(`[HlsAdPlayer] Resizing to ${width}x${height}`);\n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n on(event, listener) {\n if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());\n listeners.get(event).add(listener);\n },\n off(event, listener) {\n listeners.get(event)?.delete(listener);\n },\n updateOriginalMutedState(muted, volume) {\n const nextVolume = typeof volume === \"number\" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;\n console.log(\n `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n );\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n getOriginalMutedState() {\n return originalMutedState;\n },\n getOriginalVolume() {\n return originalVolume;\n },\n setAdVolume(volume) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n }\n },\n getAdVolume() {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n },\n setAllowNativeHls(value) {\n allowNativeHls = value;\n }\n };\n}\nexport {\n IS_BROWSER,\n IS_GLOBAL,\n IS_IOS,\n IS_SAFARI,\n SUPPORTS_DASH,\n SUPPORTS_HLS,\n StormcloudPlayer_default as StormcloudPlayer,\n StormcloudVideoPlayer,\n StormcloudVideoPlayerComponent,\n canPlay,\n createAdStormPlayer,\n createHlsAdPlayer,\n createStormcloudPlayer,\n StormcloudVideoPlayerComponent as default,\n detectBrowser,\n getBrowserConfigOverrides,\n getBrowserID,\n getClientInfo,\n initializePolyfills,\n isMediaStream,\n lazy,\n logBrowserInfo,\n merge,\n omit,\n parseQuery,\n players_default as players,\n randomString,\n sendHeartbeat,\n sendInitialTracking,\n supportsFeature,\n supportsModernJS,\n supportsWebKitPresentationMode\n};\n","import React, { useEffect, useRef, useMemo } from \"react\";\nimport { StormcloudVideoPlayer } from \"../player/StormcloudVideoPlayer\";\nimport type { StormcloudVideoPlayerConfig } from \"../types\";\nimport {\n FaPlay,\n FaPause,\n FaVolumeUp,\n FaVolumeMute,\n FaVolumeDown,\n FaExpand,\n FaCompress,\n FaSpinner,\n} from \"react-icons/fa\";\n\nexport type StormcloudVideoPlayerProps = Omit<\n StormcloudVideoPlayerConfig,\n \"videoElement\"\n> &\n React.VideoHTMLAttributes<HTMLVideoElement> & {\n onReady?: (player: StormcloudVideoPlayer) => void;\n wrapperClassName?: string;\n wrapperStyle?: React.CSSProperties;\n licenseKey?: string;\n };\n\nconst CRITICAL_PROPS = [\n \"src\",\n \"allowNativeHls\",\n \"licenseKey\",\n \"lowLatencyMode\",\n \"driftToleranceMs\",\n] as const;\n\nexport const StormcloudVideoPlayerComponent: React.FC<StormcloudVideoPlayerProps> =\n React.memo(\n (props) => {\n const {\n src,\n autoplay,\n muted,\n lowLatencyMode,\n allowNativeHls,\n driftToleranceMs,\n immediateManifestAds,\n debugAdTiming,\n showCustomControls,\n hideLoadingIndicator,\n onVolumeToggle,\n onFullscreenToggle,\n onControlClick,\n onReady,\n wrapperClassName,\n wrapperStyle,\n className,\n style,\n controls,\n playsInline,\n preload,\n poster,\n children,\n licenseKey,\n minSegmentsBeforePlay,\n ...restVideoAttrs\n } = props;\n\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const playerRef = useRef<StormcloudVideoPlayer | null>(null);\n const bufferingTimeoutRef = useRef<number | null>(null);\n const [adStatus, setAdStatus] = React.useState<{\n showAds: boolean;\n currentIndex: number;\n totalAds: number;\n }>({ showAds: false, currentIndex: 0, totalAds: 0 });\n\n const [shouldShowNativeControls, setShouldShowNativeControls] =\n React.useState(true);\n\n const [isMuted, setIsMuted] = React.useState(false);\n const [isFullscreen, setIsFullscreen] = React.useState(false);\n const [isPlaying, setIsPlaying] = React.useState(false);\n const [currentTime, setCurrentTime] = React.useState(0);\n const [duration, setDuration] = React.useState(0);\n const [volume, setVolume] = React.useState(1);\n const [playbackRate, setPlaybackRate] = React.useState(1);\n const [showVolumeSlider, setShowVolumeSlider] = React.useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = React.useState(false);\n const [isLoading, setIsLoading] = React.useState(true);\n const [isBuffering, setIsBuffering] = React.useState(false);\n const [showCenterPlay, setShowCenterPlay] = React.useState(false);\n const [showLicenseWarning, setShowLicenseWarning] = React.useState(false);\n const [viewportWidth, setViewportWidth] = React.useState(\n typeof window !== \"undefined\" ? window.innerWidth : 1920\n );\n const [isPortrait, setIsPortrait] = React.useState(\n typeof window !== \"undefined\"\n ? window.innerHeight > window.innerWidth\n : false\n );\n\n const getResponsiveScale = () => {\n if (viewportWidth < 480) return 0.7;\n if (viewportWidth < 768) return 0.8;\n if (viewportWidth < 1024) return 0.9;\n return 1;\n };\n\n const responsiveScale = getResponsiveScale();\n\n const formatTime = (seconds: number): string => {\n if (!isFinite(seconds)) return \"0:00:00\";\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const remainingSeconds = Math.floor(seconds % 60);\n return `${hours}:${minutes\n .toString()\n .padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n };\n\n const handlePlayPause = () => {\n if (videoRef.current) {\n if (videoRef.current.paused) {\n const hasValidSource =\n videoRef.current.src ||\n (videoRef.current.currentSrc &&\n videoRef.current.currentSrc !== \"\") ||\n videoRef.current.readyState >= 1;\n\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n } else {\n videoRef.current.pause();\n setShowCenterPlay(true);\n }\n }\n };\n\n const handleCenterPlayClick = () => {\n if (videoRef.current && videoRef.current.paused) {\n const hasValidSource =\n videoRef.current.src ||\n (videoRef.current.currentSrc &&\n videoRef.current.currentSrc !== \"\") ||\n videoRef.current.readyState >= 1;\n\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n }\n };\n\n const handleTimelineSeek = (e: React.MouseEvent<HTMLDivElement>) => {\n if (videoRef.current && duration > 0 && isFinite(duration)) {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const progress = Math.max(0, Math.min(1, clickX / rect.width));\n const newTime = progress * duration;\n\n if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n videoRef.current.currentTime = newTime;\n }\n }\n };\n\n const handleVolumeChange = (newVolume: number) => {\n if (playerRef.current && isFinite(newVolume)) {\n const clampedVolume = Math.max(0, Math.min(1, newVolume));\n playerRef.current.setVolume(clampedVolume);\n }\n };\n\n const handlePlaybackRateChange = (rate: number) => {\n if (videoRef.current && isFinite(rate) && rate > 0) {\n videoRef.current.playbackRate = rate;\n }\n setShowSpeedMenu(false);\n };\n\n const isHlsStream =\n src?.toLowerCase().includes(\".m3u8\") ||\n src?.toLowerCase().includes(\"/hls/\");\n const shouldShowEnhancedControls =\n showCustomControls && (isHlsStream ? allowNativeHls : true);\n\n const criticalPropsKey = useMemo(() => {\n return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n }, [\n src,\n allowNativeHls,\n licenseKey,\n lowLatencyMode,\n driftToleranceMs,\n ]);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const el = videoRef.current;\n if (!el || !src) return;\n\n if (!licenseKey) {\n setShowLicenseWarning(true);\n setIsLoading(false);\n console.warn(\n \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n );\n return;\n }\n\n setShowLicenseWarning(false);\n\n if (debugAdTiming) {\n console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n }\n\n if (playerRef.current) {\n try {\n playerRef.current.destroy();\n } catch {}\n playerRef.current = null;\n }\n\n const cfg: StormcloudVideoPlayerConfig = {\n src,\n videoElement: el,\n } as StormcloudVideoPlayerConfig;\n if (autoplay !== undefined) cfg.autoplay = autoplay;\n if (muted !== undefined) cfg.muted = muted;\n if (lowLatencyMode !== undefined) cfg.lowLatencyMode = lowLatencyMode;\n if (allowNativeHls !== undefined) cfg.allowNativeHls = allowNativeHls;\n if (driftToleranceMs !== undefined)\n cfg.driftToleranceMs = driftToleranceMs;\n if (immediateManifestAds !== undefined)\n cfg.immediateManifestAds = immediateManifestAds;\n if (debugAdTiming !== undefined) cfg.debugAdTiming = debugAdTiming;\n if (showCustomControls !== undefined)\n cfg.showCustomControls = showCustomControls;\n if (onVolumeToggle !== undefined) cfg.onVolumeToggle = onVolumeToggle;\n if (onFullscreenToggle !== undefined)\n cfg.onFullscreenToggle = onFullscreenToggle;\n if (onControlClick !== undefined) cfg.onControlClick = onControlClick;\n if (licenseKey !== undefined) cfg.licenseKey = licenseKey;\n if (minSegmentsBeforePlay !== undefined)\n cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n\n const player = new StormcloudVideoPlayer(cfg);\n playerRef.current = player;\n player\n .load()\n .then(() => {\n const showNative = player.shouldShowNativeControls();\n setShouldShowNativeControls(showNative);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n );\n }\n onReady?.(player);\n })\n .catch((error) => {\n console.error(\n \"StormcloudVideoPlayer: Failed to load player:\",\n error\n );\n setIsLoading(false);\n onReady?.(player);\n });\n\n return () => {\n try {\n player.destroy();\n } catch {}\n playerRef.current = null;\n };\n }, [criticalPropsKey]);\n\n useEffect(() => {\n if (!playerRef.current) return;\n\n try {\n if (autoplay !== undefined && playerRef.current.videoElement) {\n playerRef.current.videoElement.autoplay = autoplay;\n }\n if (muted !== undefined && !playerRef.current.isShowingAds()) {\n playerRef.current.setMuted(muted);\n }\n } catch (error) {\n console.warn(\"Failed to update player properties:\", error);\n }\n }, [autoplay, muted]);\n\n useEffect(() => {\n if (!playerRef.current) return;\n\n const checkAdStatus = () => {\n if (playerRef.current) {\n const showAds = playerRef.current.isShowingAds();\n const currentIndex = playerRef.current.getCurrentAdIndex();\n const totalAds = playerRef.current.getTotalAdsInBreak();\n\n setAdStatus((prev) => {\n if (\n prev.showAds !== showAds ||\n prev.currentIndex !== currentIndex ||\n prev.totalAds !== totalAds\n ) {\n return { showAds, currentIndex, totalAds };\n }\n return prev;\n });\n }\n };\n\n const interval = setInterval(checkAdStatus, 100);\n return () => clearInterval(interval);\n }, []);\n\n useEffect(() => {\n if (typeof window === \"undefined\" || !playerRef.current) return;\n\n const handleResize = () => {\n if (playerRef.current && videoRef.current) {\n if (typeof playerRef.current.resize === \"function\") {\n playerRef.current.resize();\n }\n }\n setViewportWidth(window.innerWidth);\n setIsPortrait(window.innerHeight > window.innerWidth);\n };\n\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n\n useEffect(() => {\n if (!playerRef.current || !videoRef.current) return;\n\n const updateStates = () => {\n if (playerRef.current && videoRef.current) {\n setIsMuted(playerRef.current.isMuted());\n setIsPlaying(!videoRef.current.paused);\n\n const currentTimeValue = videoRef.current.currentTime;\n setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n\n const durationValue = videoRef.current.duration;\n setDuration(isFinite(durationValue) ? durationValue : 0);\n\n const volumeValue = videoRef.current.volume;\n setVolume(\n isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n );\n\n const rateValue = videoRef.current.playbackRate;\n setPlaybackRate(\n isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n );\n }\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n\n const interval = setInterval(updateStates, 200);\n\n const handleFullscreenChange = () => {\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n\n return () => {\n clearInterval(interval);\n document.removeEventListener(\n \"fullscreenchange\",\n handleFullscreenChange\n );\n };\n }, []);\n\n useEffect(() => {\n if (!videoRef.current) return;\n\n const handleLoadedMetadata = () => {\n if (videoRef.current) {\n const video = videoRef.current;\n void video.offsetHeight;\n }\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleLoadedData = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadeddata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleLoadStart = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadstart, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleCanPlay = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplay, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n\n const handleCanPlayThrough = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n\n const handleWaiting = () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n }\n\n bufferingTimeoutRef.current = window.setTimeout(() => {\n setIsBuffering(true);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n videoRef.current?.readyState,\n \"- showing spinner, isBuffering=true\"\n );\n }\n }, 300);\n\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: waiting, readyState:\",\n videoRef.current?.readyState,\n \"- buffering delay started (300ms)\"\n );\n }\n };\n\n const handlePlaying = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n setShowCenterPlay(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: playing, readyState:\",\n videoRef.current?.readyState,\n \"- playback started, isLoading=false, isBuffering=false\"\n );\n }\n };\n\n const handlePause = () => {\n if (playerRef.current && !playerRef.current.isShowingAds()) {\n setShowCenterPlay(true);\n } else {\n setShowCenterPlay(false);\n }\n };\n\n const handleEnded = () => {\n setShowCenterPlay(true);\n };\n\n const video = videoRef.current;\n video.addEventListener(\"loadstart\", handleLoadStart);\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"playing\", handlePlaying);\n video.addEventListener(\"pause\", handlePause);\n video.addEventListener(\"ended\", handleEnded);\n\n if (video.paused) {\n setShowCenterPlay(true);\n }\n\n return () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n\n video.removeEventListener(\"loadstart\", handleLoadStart);\n video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"playing\", handlePlaying);\n video.removeEventListener(\"pause\", handlePause);\n video.removeEventListener(\"ended\", handleEnded);\n };\n }, [debugAdTiming]);\n\n return (\n <>\n <style>\n {`\n @keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n \n .stormcloud-loading-hidden .stormcloud-loading-indicator {\n display: none !important;\n }\n \n .stormcloud-video-wrapper:fullscreen {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n .stormcloud-video-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n *:fullscreen {\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n }\n `}\n </style>\n <div\n className={`stormcloud-video-wrapper ${wrapperClassName || \"\"}`}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n position: isFullscreen ? \"fixed\" : \"relative\",\n top: isFullscreen ? 0 : undefined,\n left: isFullscreen ? 0 : undefined,\n overflow: \"hidden\",\n width: isFullscreen ? \"100vw\" : \"100%\",\n height: isFullscreen ? \"100vh\" : \"auto\",\n minHeight: isFullscreen ? \"100vh\" : \"auto\",\n maxWidth: isFullscreen ? \"100vw\" : \"100%\",\n maxHeight: isFullscreen ? \"100vh\" : \"none\",\n zIndex: isFullscreen ? 999999 : undefined,\n backgroundColor: isFullscreen ? \"#000\" : undefined,\n borderRadius: isFullscreen ? 0 : undefined,\n boxShadow: isFullscreen ? \"none\" : undefined,\n ...wrapperStyle,\n }}\n >\n <video\n ref={videoRef}\n className={className}\n style={{\n display: \"block\",\n width: \"100%\",\n height: isFullscreen ? \"100%\" : \"auto\",\n maxWidth: \"100%\",\n maxHeight: isFullscreen ? \"100%\" : \"none\",\n objectFit: isFullscreen ? \"cover\" : \"contain\",\n backgroundColor: \"#000\",\n aspectRatio: isFullscreen ? \"unset\" : undefined,\n ...style,\n }}\n controls={\n shouldShowNativeControls && controls && !showCustomControls\n }\n playsInline={playsInline}\n preload={preload}\n poster={poster}\n {...restVideoAttrs}\n >\n {children}\n </video>\n\n {(isLoading || isBuffering) && !hideLoadingIndicator && (\n <FaSpinner\n className=\"stormcloud-loading-indicator\"\n size={42}\n color=\"white\"\n style={{\n position: \"absolute\",\n top: \"calc(50% - 21px)\",\n left: \"calc(50% - 21px)\",\n zIndex: 20,\n animation: \"spin 1s linear infinite\",\n filter: \"drop-shadow(0 3px 6px rgba(0, 0, 0, 0.8))\",\n }}\n />\n )}\n\n {showLicenseWarning && (\n <div\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 25,\n background:\n \"linear-gradient(135deg, rgba(220, 38, 38, 0.95) 0%, rgba(185, 28, 28, 0.9) 100%)\",\n color: \"white\",\n padding: \"24px 32px\",\n borderRadius: \"16px\",\n backdropFilter: \"blur(20px)\",\n border: \"2px solid rgba(255, 255, 255, 0.2)\",\n boxShadow:\n \"0 20px 60px rgba(0, 0, 0, 0.6), inset 0 2px 0 rgba(255, 255, 255, 0.2)\",\n textAlign: \"center\",\n maxWidth: \"400px\",\n margin: \"0 16px\",\n }}\n >\n <div\n style={{\n fontSize: \"20px\",\n fontWeight: \"bold\",\n marginBottom: \"12px\",\n color: \"#ffffff\",\n textShadow: \"0 2px 4px rgba(0, 0, 0, 0.5)\",\n }}\n >\n License Key Required\n </div>\n <div\n style={{\n fontSize: \"14px\",\n lineHeight: \"1.5\",\n color: \"rgba(255, 255, 255, 0.9)\",\n textShadow: \"0 1px 2px rgba(0, 0, 0, 0.3)\",\n }}\n >\n Please provide a valid license key to use the Stormcloud Video\n Player.\n <br />\n Contact your administrator for licensing information.\n </div>\n </div>\n )}\n\n {showCenterPlay &&\n !isLoading &&\n !isBuffering &&\n !showLicenseWarning &&\n !adStatus.showAds && (\n <div\n onClick={handleCenterPlayClick}\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 15,\n cursor: \"pointer\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\",\n borderRadius: \"50%\",\n width: \"100px\",\n height: \"100px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n border: \"3px solid rgba(255, 255, 255, 0.8)\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLElement;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.95) 0%, rgba(40, 40, 40, 0.9) 100%)\";\n target.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.9), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.9)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLElement;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\";\n target.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.8)\";\n }}\n title=\"Play\"\n >\n <FaPlay\n size={36}\n color=\"white\"\n style={{\n marginLeft: \"6px\",\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n }}\n />\n </div>\n )}\n\n {shouldShowEnhancedControls && !showLicenseWarning ? (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: 0,\n left: 0,\n right: 0,\n background:\n \"linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.8) 100%)\",\n padding: \"20px 16px 16px\",\n zIndex: 10,\n }}\n >\n <div\n style={{\n width: \"100%\",\n height: \"8px\",\n background:\n \"linear-gradient(90deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%)\",\n borderRadius: \"8px\",\n marginBottom: \"16px\",\n cursor: \"pointer\",\n position: \"relative\",\n backdropFilter: \"blur(5px)\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n boxShadow: \"inset 0 2px 4px rgba(0, 0, 0, 0.2)\",\n }}\n onClick={handleTimelineSeek}\n >\n <div\n style={{\n height: \"100%\",\n background:\n \"linear-gradient(90deg, rgba(139, 92, 246, 0.9) 0%, rgba(59, 130, 246, 0.8) 50%, rgba(34, 197, 94, 0.9) 100%)\",\n borderRadius: \"8px\",\n width: `${\n duration > 0 ? (currentTime / duration) * 100 : 0\n }%`,\n transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 2px 8px rgba(139, 92, 246, 0.4)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n top: \"-6px\",\n right: `${\n duration > 0\n ? 100 - (currentTime / duration) * 100\n : 100\n }%`,\n width: \"20px\",\n height: \"20px\",\n background:\n \"linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(240, 240, 240, 0.9) 100%)\",\n borderRadius: \"50%\",\n border: \"3px solid rgba(139, 92, 246, 0.8)\",\n boxShadow:\n \"0 4px 16px rgba(139, 92, 246, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.8)\",\n transform: \"translateX(50%)\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n />\n </div>\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n color: \"white\",\n flexWrap: viewportWidth < 768 ? \"wrap\" : \"nowrap\",\n gap: `${8 * responsiveScale}px`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n flexWrap: viewportWidth < 480 ? \"wrap\" : \"nowrap\",\n }}\n >\n <button\n onClick={handlePlayPause}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n backdropFilter: \"blur(12px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${10 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n minWidth: `${48 * responsiveScale}px`,\n minHeight: `${48 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n target.style.boxShadow =\n \"0 12px 48px rgba(0, 0, 0, 0.6), 0 6px 24px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n target.style.boxShadow =\n \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n }}\n title={isPlaying ? \"Pause\" : \"Play\"}\n >\n {isPlaying ? (\n <FaPause\n size={Math.max(16, 20 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n ) : (\n <FaPlay\n size={Math.max(16, 20 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n )}\n </button>\n\n <div\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\",\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n >\n <button\n onClick={() => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted || volume === 0 ? (\n <FaVolumeMute\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n ) : volume < 0.5 ? (\n <FaVolumeDown\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n ) : (\n <FaVolumeUp\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n )}\n </button>\n\n {showVolumeSlider && (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9,\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.88) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(15px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"1px solid rgba(255, 255, 255, 0.15)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\",\n zIndex: 10,\n transition:\n \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.6), 0 6px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 0 24px rgba(59, 130, 246, 0.3)\";\n e.currentTarget.style.borderColor =\n \"rgba(59, 130, 246, 0.4)\";\n }}\n onMouseLeave={(e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\";\n e.currentTarget.style.borderColor =\n \"rgba(255, 255, 255, 0.15)\";\n }}\n >\n <div\n style={{\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n // Hover effect removed\n }}\n onMouseLeave={(e) => {\n // Hover effect removed\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n\n const handleMouseMove = (\n moveEvent: MouseEvent\n ) => {\n if (!sliderElement) return;\n const rect =\n sliderElement.getBoundingClientRect();\n const y = moveEvent.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n };\n\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n\n const rect =\n sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n onClick={(e) => {\n e.stopPropagation();\n const rect =\n e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n >\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background:\n \"linear-gradient(180deg, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0.15) 100%)\",\n borderRadius: \"4px\",\n boxShadow:\n \"inset 0 1px 3px rgba(0, 0, 0, 0.2)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background:\n \"linear-gradient(180deg, rgba(96, 165, 250, 1) 0%, rgba(59, 130, 246, 0.95) 50%, rgba(37, 99, 235, 0.9) 100%)\",\n borderRadius: \"4px\",\n transition:\n \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow:\n \"0 0 8px rgba(59, 130, 246, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: `calc(${\n (isMuted ? 0 : volume) * 100\n }% - 7px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"14px\",\n height: \"14px\",\n background:\n \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n boxShadow:\n \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\",\n transition:\n \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 3px 10px rgba(0, 0, 0, 0.4), 0 0 0 3px rgba(59, 130, 246, 0.5), 0 0 20px rgba(59, 130, 246, 0.6)\";\n e.currentTarget.style.cursor = \"grab\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\";\n }}\n onMouseDown={(e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n }}\n onMouseUp={(e) => {\n e.currentTarget.style.cursor = \"grab\";\n }}\n />\n </div>\n </div>\n </>\n )}\n </div>\n\n <div\n style={{\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n color: \"rgba(255, 255, 255, 0.9)\",\n display: viewportWidth < 480 ? \"none\" : \"block\",\n }}\n >\n {formatTime(currentTime)} / {formatTime(duration)}\n </div>\n </div>\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n }}\n >\n <div\n style={{\n position: \"relative\",\n display: viewportWidth < 600 ? \"none\" : \"block\",\n }}\n >\n <button\n onClick={() => setShowSpeedMenu(!showSpeedMenu)}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px ${\n 14 * responsiveScale\n }px`,\n borderRadius: `${14 * responsiveScale}px`,\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n fontWeight: \"700\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${56 * responsiveScale}px`,\n minHeight: `${40 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 32px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title=\"Playback Speed\"\n >\n {playbackRate}x\n </button>\n\n {showSpeedMenu && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n right: 0,\n marginBottom: \"12px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.95) 100%)\",\n backdropFilter: \"blur(20px)\",\n borderRadius: \"12px\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n overflow: \"hidden\",\n minWidth: \"90px\",\n boxShadow:\n \"0 16px 48px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.1)\",\n }}\n >\n {[0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map(\n (speed) => (\n <button\n key={speed}\n onClick={() =>\n handlePlaybackRateChange(speed)\n }\n style={{\n display: \"block\",\n width: \"100%\",\n padding: \"10px 16px\",\n background:\n playbackRate === speed\n ? \"linear-gradient(135deg, rgba(99, 102, 241, 0.8) 0%, rgba(139, 92, 246, 0.6) 100%)\"\n : \"transparent\",\n border: \"none\",\n color: \"white\",\n cursor: \"pointer\",\n fontSize: \"13px\",\n fontFamily: \"monospace\",\n fontWeight: \"600\",\n textAlign: \"center\",\n transition:\n \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n borderBottom:\n speed !== 2\n ? \"1px solid rgba(255, 255, 255, 0.05)\"\n : \"none\",\n }}\n onMouseEnter={(e) => {\n if (playbackRate !== speed) {\n (\n e.target as HTMLElement\n ).style.background =\n \"linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.05) 100%)\";\n }\n }}\n onMouseLeave={(e) => {\n if (playbackRate !== speed) {\n (\n e.target as HTMLElement\n ).style.background = \"transparent\";\n }\n }}\n >\n {speed}x\n </button>\n )\n )}\n </div>\n )}\n </div>\n\n <button\n onClick={() => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current\n .toggleFullscreen()\n .catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title={\n isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"\n }\n >\n {isFullscreen ? (\n <FaCompress\n size={Math.max(14, 16 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n ) : (\n <FaExpand\n size={Math.max(14, 16 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n )}\n </button>\n </div>\n </div>\n </div>\n </>\n ) : (\n showCustomControls &&\n !showLicenseWarning && (\n <div\n style={{\n position: \"absolute\",\n bottom: `${10 * responsiveScale}px`,\n right: `${10 * responsiveScale}px`,\n transform: \"none\",\n display: \"flex\",\n flexDirection: isPortrait ? \"column\" : \"row\",\n gap: `${10 * responsiveScale}px`,\n zIndex: 10,\n }}\n >\n <div\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\",\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n >\n <button\n onClick={() => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow:\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`,\n }}\n title={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted || volume === 0 ? (\n <FaVolumeMute\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : volume < 0.5 ? (\n <FaVolumeDown\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : (\n <FaVolumeUp\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n )}\n </button>\n\n {showVolumeSlider && (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9,\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.96) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(20px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"2px solid rgba(255, 255, 255, 0.7)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\",\n zIndex: 10,\n transition:\n \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.9), 0 6px 16px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 24px rgba(96, 165, 250, 0.4)\";\n e.currentTarget.style.borderColor =\n \"rgba(96, 165, 250, 0.8)\";\n }}\n onMouseLeave={(e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\";\n e.currentTarget.style.borderColor =\n \"rgba(255, 255, 255, 0.7)\";\n }}\n >\n <div\n style={{\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\",\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n\n const handleMouseMove = (\n moveEvent: MouseEvent\n ) => {\n if (!sliderElement) return;\n const rect =\n sliderElement.getBoundingClientRect();\n const y = moveEvent.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n };\n\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n\n const rect =\n sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n onClick={(e) => {\n e.stopPropagation();\n const rect =\n e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n >\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background:\n \"linear-gradient(180deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.5) 100%)\",\n borderRadius: \"4px\",\n border: \"1px solid rgba(255, 255, 255, 0.4)\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.3)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background:\n \"linear-gradient(180deg, rgba(125, 211, 252, 1) 0%, rgba(96, 165, 250, 0.98) 50%, rgba(59, 130, 246, 0.95) 100%)\",\n borderRadius: \"4px\",\n transition:\n \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow:\n \"0 0 12px rgba(96, 165, 250, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.4)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: `calc(${\n (isMuted ? 0 : volume) * 100\n }% - 8px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"16px\",\n height: \"16px\",\n background:\n \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n border: \"2px solid rgba(96, 165, 250, 0.9)\",\n boxShadow:\n \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\",\n transition:\n \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 4px 12px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(96, 165, 250, 0.6), 0 0 24px rgba(96, 165, 250, 0.7)\";\n e.currentTarget.style.cursor = \"grab\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\";\n }}\n onMouseDown={(e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n }}\n onMouseUp={(e) => {\n e.currentTarget.style.cursor = \"grab\";\n }}\n />\n </div>\n </div>\n </>\n )}\n </div>\n\n <button\n onClick={() => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow:\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`,\n }}\n title={\n isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"\n }\n >\n {isFullscreen ? (\n <FaCompress\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : (\n <FaExpand\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n )}\n </button>\n </div>\n )\n )}\n\n {onControlClick && (\n <div\n onClick={onControlClick}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 1,\n cursor: \"pointer\",\n }}\n />\n )}\n </div>\n </>\n );\n },\n (prevProps, nextProps) => {\n for (const prop of CRITICAL_PROPS) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n const uiProps = [\n \"autoplay\",\n \"muted\",\n \"controls\",\n \"showCustomControls\",\n \"className\",\n \"style\",\n \"wrapperClassName\",\n \"wrapperStyle\",\n \"playsInline\",\n \"preload\",\n \"poster\",\n \"children\",\n ] as const;\n\n for (const prop of uiProps) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n const callbackProps = [\n \"onReady\",\n \"onVolumeToggle\",\n \"onFullscreenToggle\",\n \"onControlClick\",\n ] as const;\n for (const prop of callbackProps) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n return true;\n }\n );\n","import Hls from \"hls.js\";\nimport type {\n StormcloudVideoPlayerConfig,\n Scte35Marker,\n Id3TagInfo,\n AdController,\n} from \"../types\";\nimport { createAdStormPlayer } from \"../sdk/adstormPlayer\";\nimport { initializePolyfills } from \"../utils/polyfills\";\nimport { getBrowserConfigOverrides, logBrowserInfo } from \"../utils/browserCompat\";\n\nexport class StormcloudVideoPlayer {\n private readonly video: HTMLVideoElement;\n private readonly config: StormcloudVideoPlayerConfig;\n private hls?: Hls;\n private adPlayer: AdController;\n private attached = false;\n private inAdBreak = false;\n private expectedAdBreakDurationMs: number | undefined;\n private adStopTimerId: number | undefined;\n private ptsDriftEmaMs = 0;\n private isLiveStream: boolean = false;\n private nativeHlsMode: boolean = false;\n private videoSrcProtection: string | null = null;\n private bufferedSegmentsCount: number = 0;\n private shouldAutoplayAfterBuffering: boolean = false;\n private hasInitialBufferCompleted: boolean = false;\n private timeUpdateHandler?: (event: Event) => void;\n private emptiedHandler?: (event: Event) => void;\n\n constructor(config: StormcloudVideoPlayerConfig) {\n initializePolyfills();\n\n const browserOverrides = getBrowserConfigOverrides();\n this.config = { ...config, ...browserOverrides };\n this.video = config.videoElement;\n\n logBrowserInfo(config.debugAdTiming);\n\n if (!this.config.licenseKey) {\n console.warn(\"[StormcloudVideoPlayer] No license key provided - ads will not work\");\n }\n\n this.adPlayer = createAdStormPlayer(this.video, {\n licenseKey: this.config.licenseKey || \"\",\n debug: this.config.debugAdTiming ?? false,\n });\n }\n\n async load(): Promise<void> {\n if (!this.attached) {\n this.attach();\n }\n\n if (this.shouldUseNativeHls()) {\n this.nativeHlsMode = true;\n this.videoSrcProtection = this.config.src;\n this.video.src = this.config.src;\n\n this.isLiveStream = this.config.lowLatencyMode ?? false;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Using native HLS playback:\", {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls,\n });\n }\n\n this.adPlayer.initialize();\n this.adPlayer.setAllowNativeHls(!!this.config.allowNativeHls);\n\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {});\n }\n return;\n }\n\n this.hls = new Hls({\n enableWorker: true,\n backBufferLength: 30,\n liveDurationInfinity: true,\n lowLatencyMode: !!this.config.lowLatencyMode,\n maxLiveSyncPlaybackRate: this.config.lowLatencyMode ? 1.5 : 1.0,\n ...(this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {}),\n maxBufferLength: 30,\n maxMaxBufferLength: 600,\n maxBufferSize: 60 * 1000 * 1000,\n maxBufferHole: 0.5,\n highBufferWatchdogPeriod: 2,\n nudgeOffset: 0.1,\n nudgeMaxRetry: 3,\n startPosition: -1,\n });\n\n this.hls.on(Hls.Events.MEDIA_ATTACHED, () => {\n this.hls?.loadSource(this.config.src);\n });\n\n this.hls.on(Hls.Events.MANIFEST_PARSED, async () => {\n this.isLiveStream =\n this.hls?.levels?.some(\n (level) =>\n level?.details?.live === true || level?.details?.type === \"LIVE\"\n ) ?? false;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Stream type detected:\", {\n isLive: this.isLiveStream,\n });\n }\n\n this.adPlayer.initialize();\n this.adPlayer.setAllowNativeHls(!!this.config.allowNativeHls);\n\n this.bufferedSegmentsCount = 0;\n this.hasInitialBufferCompleted = false;\n this.shouldAutoplayAfterBuffering = !!this.config.autoplay;\n\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Waiting for\",\n minSegments,\n \"segments to buffer before playback\"\n );\n }\n\n if (minSegments === 0 || !this.config.autoplay) {\n this.hasInitialBufferCompleted = true;\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {});\n }\n }\n });\n\n this.hls.on(Hls.Events.FRAG_BUFFERED, async () => {\n if (this.hasInitialBufferCompleted) {\n return;\n }\n\n this.bufferedSegmentsCount++;\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Buffered segment ${this.bufferedSegmentsCount}/${minSegments}`\n );\n }\n\n if (this.bufferedSegmentsCount >= minSegments) {\n this.hasInitialBufferCompleted = true;\n\n if (this.shouldAutoplayAfterBuffering) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Initial buffer complete. Starting playback.`\n );\n }\n await this.video.play()?.catch((err) => {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Autoplay failed:\", err);\n }\n });\n }\n }\n });\n\n this.hls.on(Hls.Events.FRAG_PARSING_METADATA, (_evt, data: any) => {\n const id3Tags: Id3TagInfo[] = (data?.samples || []).map((s: any) => ({\n key: \"ID3\",\n value: s?.data,\n ptsSeconds: s?.pts,\n }));\n id3Tags.forEach((tag) => this.onId3Tag(tag));\n });\n\n this.hls.on(Hls.Events.FRAG_CHANGED, (_evt, data: any) => {\n const frag = data?.frag;\n const tagList: any[] | undefined = frag?.tagList;\n if (!Array.isArray(tagList)) return;\n\n for (const entry of tagList) {\n let tag = \"\";\n let value = \"\";\n if (Array.isArray(entry)) {\n tag = String(entry[0] ?? \"\");\n value = String(entry[1] ?? \"\");\n } else if (typeof entry === \"string\") {\n const idx = entry.indexOf(\":\");\n if (idx >= 0) {\n tag = entry.substring(0, idx);\n value = entry.substring(idx + 1);\n } else {\n tag = entry;\n value = \"\";\n }\n }\n\n if (!tag) continue;\n \n if (tag.includes(\"EXT-X-CUE-OUT\")) {\n const durationSeconds = this.parseCueOutDuration(value);\n this.onScte35Marker({\n type: \"start\",\n ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n raw: { tag, value },\n });\n } else if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n const prog = this.parseCueOutCont(value);\n this.onScte35Marker({\n type: \"progress\",\n ...(prog?.duration !== undefined ? { durationSeconds: prog.duration } : {}),\n ...(prog?.elapsed !== undefined ? { ptsSeconds: prog.elapsed } : {}),\n raw: { tag, value },\n });\n } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value } });\n } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n const attrs = this.parseAttributeList(value);\n const hasScteOut = \"SCTE35-OUT\" in attrs;\n const hasScteIn = \"SCTE35-IN\" in attrs;\n const klass = String(attrs[\"CLASS\"] ?? \"\");\n const duration = this.toNumber(attrs[\"DURATION\"]) ?? this.toNumber(attrs[\"PLANNED-DURATION\"]);\n\n if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n this.onScte35Marker({\n type: \"start\",\n ...(duration !== undefined ? { durationSeconds: duration } : {}),\n raw: { tag, value, attrs },\n });\n }\n if (hasScteIn) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value, attrs } });\n }\n }\n }\n });\n\n this.hls.on(Hls.Events.ERROR, (_evt, data) => {\n if (data?.fatal) {\n switch (data.type) {\n case Hls.ErrorTypes.NETWORK_ERROR:\n this.hls?.startLoad();\n break;\n case Hls.ErrorTypes.MEDIA_ERROR:\n this.hls?.recoverMediaError();\n break;\n default:\n this.destroy();\n break;\n }\n }\n });\n\n this.hls.attachMedia(this.video);\n }\n\n private attach(): void {\n if (this.attached) return;\n this.attached = true;\n this.video.autoplay = !!this.config.autoplay;\n this.video.muted = !!this.config.muted;\n\n this.adPlayer.initialize();\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n \n this.adPlayer.on(\"all_ads_completed\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad completed - ending ad break\");\n }\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n \n this.adPlayer.on(\"ad_error\", () => {\n console.error(\"[StormcloudVideoPlayer] Ad error occurred\");\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n \n this.adPlayer.on(\"content_pause\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content paused for ad\");\n }\n });\n \n this.adPlayer.on(\"content_resume\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content resuming after ad\");\n }\n });\n\n this.timeUpdateHandler = () => {\n };\n this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n\n this.emptiedHandler = () => {\n if (this.nativeHlsMode && this.videoSrcProtection && !this.adPlayer.isAdPlaying()) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Video src was cleared, restoring\");\n }\n const currentTime = this.video.currentTime;\n const wasPaused = this.video.paused;\n this.video.src = this.videoSrcProtection;\n this.video.currentTime = currentTime;\n if (!wasPaused) {\n this.video.play().catch(() => {});\n }\n }\n };\n this.video.addEventListener(\"emptied\", this.emptiedHandler);\n }\n\n private shouldUseNativeHls(): boolean {\n const streamType = this.getStreamType();\n if (streamType === \"other\") {\n return true;\n }\n const canNative = this.video.canPlayType(\"application/vnd.apple.mpegurl\");\n return !!(this.config.allowNativeHls && canNative);\n }\n\n private onId3Tag(tag: Id3TagInfo): void {\n if (typeof tag.ptsSeconds === \"number\") {\n this.updatePtsDrift(tag.ptsSeconds);\n }\n const marker = this.parseScte35FromId3(tag);\n if (marker) {\n this.onScte35Marker(marker);\n }\n }\n\n private parseScte35FromId3(tag: Id3TagInfo): Scte35Marker | undefined {\n const text = this.decodeId3ValueToText(tag.value);\n if (!text) return undefined;\n\n const cueOutMatch =\n text.match(/EXT-X-CUE-OUT(?::([^\\r\\n]*))?/i) ||\n text.match(/CUE-OUT(?::([^\\r\\n]*))?/i);\n if (cueOutMatch) {\n const arg = (cueOutMatch[1] ?? \"\").trim();\n const dur = this.parseCueOutDuration(arg);\n return {\n type: \"start\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n ...(dur !== undefined ? { durationSeconds: dur } : {}),\n raw: { id3: text },\n };\n }\n\n const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\\r\\n]*)/i);\n if (cueOutContMatch) {\n const arg = (cueOutContMatch[1] ?? \"\").trim();\n const cont = this.parseCueOutCont(arg);\n return {\n type: \"progress\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n ...(cont?.duration !== undefined ? { durationSeconds: cont.duration } : {}),\n raw: { id3: text },\n };\n }\n\n const cueInMatch = text.match(/EXT-X-CUE-IN\\b/i) || text.match(/CUE-IN\\b/i);\n if (cueInMatch) {\n return {\n type: \"end\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n raw: { id3: text },\n };\n }\n\n return undefined;\n }\n\n private decodeId3ValueToText(value: string | Uint8Array): string | undefined {\n try {\n if (typeof value === \"string\") return value;\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n const text = decoder.decode(value);\n if (text && /[\\x20-\\x7E]/.test(text)) return text;\n let out = \"\";\n for (let i = 0; i < value.length; i++) {\n out += String.fromCharCode(value[i]!);\n }\n return out;\n } catch {\n return undefined;\n }\n }\n\n private async onScte35Marker(marker: Scte35Marker): Promise<void> {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] SCTE-35 marker detected:\", {\n type: marker.type,\n ptsSeconds: marker.ptsSeconds,\n durationSeconds: marker.durationSeconds,\n currentTime: this.video.currentTime,\n });\n }\n\n if (marker.type === \"start\") {\n if (this.inAdBreak) {\n return;\n }\n\n this.inAdBreak = true;\n const durationMs = marker.durationSeconds != null\n ? marker.durationSeconds * 1000\n : 30000;\n \n this.expectedAdBreakDurationMs = durationMs;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Starting ad break:\", {\n durationMs,\n durationSeconds: marker.durationSeconds,\n });\n }\n\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n\n await this.handleAdStart(marker);\n\n if (this.expectedAdBreakDurationMs != null) {\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n\n if (marker.type === \"progress\" && this.inAdBreak) {\n if (marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1000;\n }\n return;\n }\n\n if (marker.type === \"end\") {\n if (!this.inAdBreak) return;\n \n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = undefined;\n this.clearAdStopTimer();\n\n if (this.adPlayer.isAdPlaying()) {\n await this.adPlayer.stop();\n }\n\n this.handleAdPodComplete();\n return;\n }\n }\n\n private async handleAdStart(marker: Scte35Marker): Promise<void> {\n const durationSeconds = marker.durationSeconds ?? 30;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Requesting ads for duration:\", durationSeconds);\n }\n\n try {\n await this.adPlayer.requestAds(String(durationSeconds));\n \n await this.adPlayer.play();\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Ad request/play failed:\", error);\n }\n this.handleAdPodComplete();\n }\n }\n\n private parseCueOutDuration(value: string): number | undefined {\n const num = parseFloat(value.trim());\n if (!Number.isNaN(num)) return num;\n const match =\n value.match(/(?:^|[,\\s])DURATION\\s*=\\s*([0-9.]+)/i) ||\n value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n if (match && match[1] != null) {\n const d = parseFloat(match[1]);\n return Number.isNaN(d) ? undefined : d;\n }\n return undefined;\n }\n\n private parseCueOutCont(value: string): { elapsed?: number; duration?: number } | undefined {\n const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n const res: { elapsed?: number; duration?: number } = {};\n if (elapsedMatch && elapsedMatch[1] != null) {\n const e = parseFloat(elapsedMatch[1]);\n if (!Number.isNaN(e)) res.elapsed = e;\n }\n if (durationMatch && durationMatch[1] != null) {\n const d = parseFloat(durationMatch[1]);\n if (!Number.isNaN(d)) res.duration = d;\n }\n if (\"elapsed\" in res || \"duration\" in res) return res;\n return undefined;\n }\n\n private parseAttributeList(value: string): Record<string, string> {\n const attrs: Record<string, string> = {};\n const regex = /([A-Z0-9-]+)=((\"[^\"]*\")|([^\",]*))(?:,|$)/gi;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(value)) !== null) {\n const key: string = (match[1] ?? \"\") as string;\n let rawVal: string = (match[3] ?? match[4] ?? \"\") as string;\n if (rawVal.startsWith('\"') && rawVal.endsWith('\"')) {\n rawVal = rawVal.slice(1, -1);\n }\n if (key) {\n attrs[key] = rawVal;\n }\n }\n return attrs;\n }\n\n private toNumber(val: unknown): number | undefined {\n if (val == null) return undefined;\n const n = typeof val === \"string\" ? parseFloat(val) : Number(val);\n return Number.isNaN(n) ? undefined : n;\n }\n\n private scheduleAdStopCountdown(remainingMs: number): void {\n this.clearAdStopTimer();\n const ms = Math.max(0, Math.floor(remainingMs));\n if (ms === 0) {\n this.handleAdPodComplete();\n return;\n }\n this.adStopTimerId = window.setTimeout(() => {\n this.handleAdPodComplete();\n }, ms) as unknown as number;\n }\n\n private clearAdStopTimer(): void {\n if (this.adStopTimerId != null) {\n clearTimeout(this.adStopTimerId);\n this.adStopTimerId = undefined;\n }\n }\n\n private updatePtsDrift(ptsSecondsSample: number): void {\n const sampleMs = (this.video.currentTime - ptsSecondsSample) * 1000;\n if (!Number.isFinite(sampleMs) || Math.abs(sampleMs) > 60000) return;\n const alpha = 0.1;\n this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;\n }\n\n private handleAdPodComplete(): void {\n this.clearAdStopTimer();\n \n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = undefined;\n\n this.adPlayer.stop().catch(() => {});\n\n const restoredMuted = this.adPlayer.getOriginalMutedState();\n const restoredVolume = this.adPlayer.getOriginalVolume();\n\n if (this.video.muted !== restoredMuted) {\n this.video.muted = restoredMuted;\n }\n if (Math.abs(this.video.volume - restoredVolume) > 0.01) {\n this.video.volume = restoredVolume;\n }\n\n if (this.video.paused) {\n this.video.play()?.catch(() => {});\n }\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad break complete\");\n }\n }\n\n isAdPlaying(): boolean {\n return this.inAdBreak && this.adPlayer.isAdPlaying();\n }\n\n isShowingAds(): boolean {\n return this.adPlayer.isAdPlaying();\n }\n\n getStreamType(): \"hls\" | \"other\" {\n const url = this.config.src.toLowerCase();\n if (\n url.includes(\".m3u8\") ||\n url.includes(\"/hls/\") ||\n url.includes(\"application/vnd.apple.mpegurl\")\n ) {\n return \"hls\";\n }\n return \"other\";\n }\n\n shouldShowNativeControls(): boolean {\n const streamType = this.getStreamType();\n if (streamType === \"other\") {\n return !(this.config.showCustomControls ?? false);\n }\n return !!(\n this.config.allowNativeHls && !(this.config.showCustomControls ?? false)\n );\n }\n\n toggleMute(): void {\n if (this.adPlayer.isAdPlaying()) {\n const currentMuted = this.video.muted;\n const newMutedState = !currentMuted;\n\n this.adPlayer.updateOriginalMutedState(newMutedState, this.video.volume);\n this.adPlayer.setAdVolume(newMutedState ? 0 : 1);\n } else {\n this.video.muted = !this.video.muted;\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n }\n }\n\n toggleFullscreen(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!document.fullscreenElement) {\n const container = this.video.parentElement;\n if (!container) {\n reject(new Error(\"No parent container found for fullscreen\"));\n return;\n }\n container\n .requestFullscreen()\n .then(() => resolve())\n .catch(reject);\n } else {\n document.exitFullscreen().then(() => resolve()).catch(reject);\n }\n });\n }\n\n isMuted(): boolean {\n return this.video.muted;\n }\n\n setMuted(muted: boolean): void {\n this.video.muted = muted;\n this.adPlayer.updateOriginalMutedState(muted, this.video.volume);\n\n if (this.adPlayer.isAdPlaying()) {\n this.adPlayer.setAdVolume(muted ? 0 : 1);\n }\n }\n\n setVolume(volume: number): void {\n const clampedVolume = Math.max(0, Math.min(1, volume));\n\n if (this.adPlayer.isAdPlaying()) {\n this.adPlayer.setAdVolume(clampedVolume);\n this.adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n } else {\n this.video.volume = clampedVolume;\n this.video.muted = clampedVolume === 0;\n this.adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n }\n }\n\n isFullscreen(): boolean {\n return !!document.fullscreenElement;\n }\n\n isLive(): boolean {\n return this.isLiveStream;\n }\n\n get videoElement(): HTMLVideoElement {\n return this.video;\n }\n\n resize(): void {\n if (this.adPlayer && this.adPlayer.isAdPlaying()) {\n const width = this.video.clientWidth || 640;\n const height = this.video.clientHeight || 360;\n this.adPlayer.resize(width, height);\n }\n }\n\n destroy(): void {\n this.clearAdStopTimer();\n\n if (this.timeUpdateHandler) {\n this.video.removeEventListener(\"timeupdate\", this.timeUpdateHandler);\n delete this.timeUpdateHandler;\n }\n if (this.emptiedHandler) {\n this.video.removeEventListener(\"emptied\", this.emptiedHandler);\n delete this.emptiedHandler;\n }\n\n this.hls?.destroy();\n this.adPlayer?.destroy();\n }\n\n getCurrentAdIndex(): number {\n return 0;\n }\n\n getTotalAdsInBreak(): number {\n return 1;\n }\n}\n","import type { AdController } from \"../types\";\n\ninterface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\nconst SUPPORTED_VIDEO_EXTENSIONS = ['.mp4', '.webm', '.ogg', '.m3u8', '.ts'];\nconst UNSUPPORTED_VIDEO_EXTENSIONS = ['.flv', '.f4v', '.swf', '.wmv', '.avi', '.mov', '.mkv'];\n\nfunction getFileExtension(url: string): string {\n try {\n const pathname = new URL(url, 'http://dummy').pathname;\n const lastDot = pathname.lastIndexOf('.');\n if (lastDot === -1) return '';\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf('.');\n if (lastDot === -1) return '';\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || '').toLowerCase();\n }\n}\n\nfunction isUnsupportedFormat(url: string): boolean {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\n\nfunction replaceFlvExtension(url: string): string {\n const ext = getFileExtension(url);\n if (ext === '.flv') {\n return url.replace(/\\.flv(\\?|$)/i, '.mp4$1');\n }\n return url;\n}\n\nfunction isSupportedFormat(url: string, mimeType: string): boolean {\n if (isUnsupportedFormat(url)) {\n return false;\n }\n \n const ext = getFileExtension(url);\n \n if (SUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1) {\n return true;\n }\n \n if (ext === '' || ext === '.') {\n return mimeType.includes('video/mp4') || \n mimeType.includes('video/webm') || \n mimeType.includes('m3u8') ||\n mimeType.includes('application/x-mpegurl');\n }\n \n return false;\n}\n\ninterface VastTrackingUrls {\n impression: string[];\n start: string[];\n firstQuartile: string[];\n midpoint: string[];\n thirdQuartile: string[];\n complete: string[];\n error: string[];\n}\n\ninterface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\ninterface AdStormMetadata {\n video?: {\n codec?: string;\n width?: number;\n height?: number;\n fps?: number;\n bitrate?: number;\n profile?: string;\n pix_fmt?: string;\n has_b_frames?: number;\n };\n audio?: {\n codec?: string;\n sample_rate?: number;\n bitrate?: number;\n };\n}\n\nexport interface AdStormPlayerOptions {\n licenseKey: string;\n debug?: boolean;\n}\n\nexport function createAdStormPlayer(\n contentVideo: HTMLVideoElement,\n options: AdStormPlayerOptions\n): AdController {\n const { licenseKey, debug = false } = options;\n \n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = new Map<string, Set<(payload?: any) => void>>();\n \n let adVideoElement: HTMLVideoElement | undefined;\n let adContainerEl: HTMLDivElement | undefined;\n let currentAd: VastAd | undefined;\n let destroyed = false;\n let allowNativeHls = false;\n \n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n\n function log(...args: any[]): void {\n if (debug) {\n console.log(\"[AdStormPlayer]\", ...args);\n }\n }\n\n function emit(event: string, payload?: any): void {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch (error) {\n console.warn(`[AdStormPlayer] Error in event listener for ${event}:`, error);\n }\n }\n }\n\n function fireTrackingPixels(urls: string[]): void {\n if (!urls || urls.length === 0) return;\n \n urls.forEach((url) => {\n try {\n const img = new Image(1, 1);\n img.src = url;\n log(\"Fired tracking pixel:\", url);\n } catch (error) {\n console.warn(\"[AdStormPlayer] Error firing tracking pixel:\", error);\n }\n });\n }\n\n function buildVastUrl(durationSeconds: number, metadata?: AdStormMetadata): string {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n \n const defaultMetadata: AdStormMetadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5000,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0,\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48000,\n bitrate: 128,\n },\n };\n \n const finalMetadata = metadata || defaultMetadata;\n const metadataStr = encodeURIComponent(JSON.stringify(finalMetadata));\n \n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\n }\n\n function parseVastXml(xmlString: string): VastAd[] {\n const ads: VastAd[] = [];\n \n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n \n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\"[AdStormPlayer] XML parsing error:\", parserError.textContent);\n return [];\n }\n \n const adElements = xmlDoc.querySelectorAll(\"Ad\");\n \n adElements.forEach((adElement) => {\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n \n const durationText = adElement.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration =\n parseInt(durationParts[0] || \"0\", 10) * 3600 +\n parseInt(durationParts[1] || \"0\", 10) * 60 +\n parseFloat(durationParts[2] || \"0\");\n \n const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n \n mediaFileElements.forEach((mf) => {\n const type = mf.getAttribute(\"type\") || \"\";\n let url = mf.textContent?.trim() || \"\";\n const width = parseInt(mf.getAttribute(\"width\") || \"1920\", 10);\n const height = parseInt(mf.getAttribute(\"height\") || \"1080\", 10);\n const bitrate = mf.getAttribute(\"bitrate\") \n ? parseInt(mf.getAttribute(\"bitrate\")!, 10) \n : undefined;\n \n if (!url) {\n log(`Skipping empty MediaFile URL`);\n return;\n }\n \n const originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n log(`Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n \n if (isUnsupportedFormat(url)) {\n const ext = getFileExtension(url);\n log(`Skipping unsupported format: ${url} (extension: ${ext}, declared type: ${type})`);\n return;\n }\n \n if (isSupportedFormat(url, type)) {\n mediaFiles.push({ url, type, width, height, bitrate });\n log(`Found media file: ${url} (${type}, ${width}x${height})`);\n } else {\n log(`Skipping incompatible media file: ${url} (type: ${type})`);\n }\n });\n \n if (mediaFiles.length === 0) {\n log(\"No valid media files found in ad:\", adId);\n return;\n }\n \n const trackingUrls: VastTrackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n error: [],\n };\n \n adElement.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n \n adElement.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event as keyof VastTrackingUrls;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n \n const clickThrough = adElement.querySelector(\"ClickThrough\")?.textContent?.trim();\n \n ads.push({\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough,\n });\n \n log(`Parsed ad: ${title}, duration: ${duration}s, media files: ${mediaFiles.length}`);\n });\n \n } catch (error) {\n console.error(\"[AdStormPlayer] Error parsing VAST XML:\", error);\n }\n \n return ads;\n }\n\n function selectBestMediaFile(mediaFiles: VastMediaFile[]): VastMediaFile | null {\n if (mediaFiles.length === 0) return null;\n if (mediaFiles.length === 1) return mediaFiles[0]!;\n \n const mp4Files = mediaFiles.filter(mf => mf.type.includes(\"video/mp4\"));\n const candidates = mp4Files.length > 0 ? mp4Files : mediaFiles;\n \n const targetWidth = contentVideo.videoWidth || 1280;\n const targetHeight = contentVideo.videoHeight || 720;\n \n candidates.sort((a, b) => {\n const diffA = Math.abs(a.width - targetWidth) + Math.abs(a.height - targetHeight);\n const diffB = Math.abs(b.width - targetWidth) + Math.abs(b.height - targetHeight);\n return diffA - diffB;\n });\n \n return candidates[0] || null;\n }\n\n function createAdVideoElement(): HTMLVideoElement {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.style.zIndex = \"15\";\n video.playsInline = true;\n video.muted = false;\n video.volume = originalMutedState ? 0 : originalVolume;\n \n return video;\n }\n\n function setAdPlayingFlag(isPlaying: boolean): void {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n\n function setupAdEventListeners(): void {\n if (!adVideoElement || !currentAd) return;\n \n const ad = currentAd;\n \n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!ad || !adVideoElement) return;\n \n const progress = adVideoElement.currentTime / ad.duration;\n \n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(ad.trackingUrls.firstQuartile);\n }\n \n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(ad.trackingUrls.midpoint);\n }\n \n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(ad.trackingUrls.thirdQuartile);\n }\n });\n \n adVideoElement.addEventListener(\"playing\", () => {\n if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(ad.trackingUrls.start);\n log(\"Ad started playing\");\n });\n \n adVideoElement.addEventListener(\"ended\", () => {\n if (!ad || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(ad.trackingUrls.complete);\n log(\"Ad completed\");\n handleAdComplete();\n });\n \n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[AdStormPlayer] Ad video error:\", e);\n if (ad) {\n fireTrackingPixels(ad.trackingUrls.error);\n }\n handleAdError();\n });\n }\n\n function handleAdComplete(): void {\n log(\"Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n \n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n \n emit(\"content_resume\");\n emit(\"all_ads_completed\");\n }\n\n function handleAdError(): void {\n log(\"Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n \n emit(\"ad_error\");\n }\n\n async function fetchVast(durationSeconds: number): Promise<VastAd[]> {\n const vastUrl = buildVastUrl(durationSeconds);\n log(\"Fetching VAST from:\", vastUrl);\n \n const response = await fetch(vastUrl, {\n headers: {\n \"Accept\": \"application/xml\",\n },\n });\n \n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.status} ${response.statusText}`);\n }\n \n const xmlText = await response.text();\n log(\"VAST response received, length:\", xmlText.length);\n \n return parseVastXml(xmlText);\n }\n\n return {\n initialize() {\n log(\"Initializing\");\n \n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n \n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n\n async requestAds(duration: string) {\n log(\"Requesting ads for duration:\", duration);\n \n if (adPlaying) {\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n \n try {\n let durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n \n const ads = await fetchVast(durationSeconds);\n \n if (ads.length === 0) {\n log(\"No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n \n currentAd = ads[0];\n log(`Ad loaded: ${currentAd!.title}, duration: ${currentAd!.duration}s`);\n \n fireTrackingPixels(currentAd!.trackingUrls.impression);\n trackingFired.impression = true;\n \n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n\n async play() {\n if (!currentAd) {\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n \n log(\"Starting ad playback\");\n \n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n \n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n \n contentVideo.style.transition = \"opacity 0.3s ease-in-out\";\n contentVideo.style.opacity = \"0\";\n setTimeout(() => {\n contentVideo.style.visibility = \"hidden\";\n }, 300);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n \n if (allowNativeHls) {\n contentVideo.pause();\n }\n \n adPlaying = true;\n setAdPlayingFlag(true);\n \n if (adVideoElement) {\n adVideoElement.volume = originalMutedState ? 0 : originalVolume;\n adVideoElement.muted = originalMutedState;\n }\n \n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n }\n \n emit(\"content_pause\");\n \n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available\");\n }\n \n log(\"Playing media file:\", mediaFile.url);\n adVideoElement!.src = mediaFile.url;\n \n await adVideoElement!.play();\n \n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n\n async stop() {\n log(\"Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n \n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n \n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n currentAd = undefined;\n },\n\n destroy() {\n log(\"Destroying\");\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n \n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = undefined;\n }\n \n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n \n adContainerEl = undefined;\n currentAd = undefined;\n listeners.clear();\n },\n\n isAdPlaying() {\n return adPlaying;\n },\n\n resize(width: number, height: number) {\n log(`Resizing to ${width}x${height}`);\n \n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n \n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n\n on(event: string, listener: (payload?: any) => void) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(listener);\n },\n\n off(event: string, listener: (payload?: any) => void) {\n listeners.get(event)?.delete(listener);\n },\n\n updateOriginalMutedState(muted: boolean, volume?: number) {\n const nextVolume =\n typeof volume === \"number\" && !Number.isNaN(volume)\n ? Math.max(0, Math.min(1, volume))\n : originalVolume;\n log(`updateOriginalMutedState: muted=${muted}, volume=${nextVolume}`);\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n\n getOriginalMutedState() {\n return originalMutedState;\n },\n\n getOriginalVolume() {\n return originalVolume;\n },\n\n setAdVolume(volume: number) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n adVideoElement.muted = volume === 0;\n }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n\n showPlaceholder() {\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n \n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n \n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n },\n\n setAllowNativeHls(value: boolean) {\n allowNativeHls = value;\n log(`allowNativeHls set to: ${value}`);\n },\n };\n}\n\n","export function polyfillURLSearchParams(): void {\n if (typeof URLSearchParams !== 'undefined') {\n return;\n }\n\n class URLSearchParamsPolyfill {\n private params: Map<string, string[]>;\n\n constructor(init?: string | URLSearchParamsPolyfill) {\n this.params = new Map();\n\n if (typeof init === 'string') {\n this.parseQueryString(init);\n } else if (init instanceof URLSearchParamsPolyfill) {\n init.forEach((value, key) => {\n this.append(key, value);\n });\n }\n }\n\n private parseQueryString(query: string): void {\n const cleanQuery = query.startsWith('?') ? query.slice(1) : query;\n if (!cleanQuery) return;\n\n cleanQuery.split('&').forEach((param) => {\n const [key, value] = param.split('=');\n if (key) {\n const decodedKey = this.safeDecodeURIComponent(key);\n const decodedValue = value ? this.safeDecodeURIComponent(value) : '';\n this.append(decodedKey, decodedValue);\n }\n });\n }\n\n private safeDecodeURIComponent(str: string): string {\n try {\n return decodeURIComponent(str.replace(/\\+/g, ' '));\n } catch (e) {\n return str;\n }\n }\n\n append(name: string, value: string): void {\n const values = this.params.get(name) || [];\n values.push(String(value));\n this.params.set(name, values);\n }\n\n delete(name: string): void {\n this.params.delete(name);\n }\n\n get(name: string): string | null {\n const values = this.params.get(name);\n return values && values.length > 0 && values[0] !== undefined ? values[0] : null;\n }\n\n getAll(name: string): string[] {\n return this.params.get(name) || [];\n }\n\n has(name: string): boolean {\n return this.params.has(name);\n }\n\n set(name: string, value: string): void {\n this.params.set(name, [String(value)]);\n }\n\n forEach(callback: (value: string, key: string, parent: URLSearchParamsPolyfill) => void): void {\n this.params.forEach((values, key) => {\n values.forEach((value) => {\n callback(value, key, this);\n });\n });\n }\n\n toString(): string {\n const parts: string[] = [];\n this.params.forEach((values, key) => {\n values.forEach((value) => {\n parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\n });\n });\n return parts.join('&');\n }\n }\n\n // @ts-ignore\n window.URLSearchParams = URLSearchParamsPolyfill;\n}\n\nexport function polyfillTextEncoder(): void {\n if (typeof TextEncoder !== 'undefined') {\n return;\n }\n\n class TextEncoderPolyfill {\n encoding = 'utf-8';\n\n encode(str: string): Uint8Array {\n const utf8: number[] = [];\n for (let i = 0; i < str.length; i++) {\n let charcode = str.charCodeAt(i);\n if (charcode < 0x80) {\n utf8.push(charcode);\n } else if (charcode < 0x800) {\n utf8.push(0xc0 | (charcode >> 6), 0x80 | (charcode & 0x3f));\n } else if (charcode < 0xd800 || charcode >= 0xe000) {\n utf8.push(\n 0xe0 | (charcode >> 12),\n 0x80 | ((charcode >> 6) & 0x3f),\n 0x80 | (charcode & 0x3f)\n );\n } else {\n i++;\n charcode = 0x10000 + (((charcode & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff));\n utf8.push(\n 0xf0 | (charcode >> 18),\n 0x80 | ((charcode >> 12) & 0x3f),\n 0x80 | ((charcode >> 6) & 0x3f),\n 0x80 | (charcode & 0x3f)\n );\n }\n }\n return new Uint8Array(utf8);\n }\n }\n\n // @ts-ignore\n window.TextEncoder = TextEncoderPolyfill;\n}\n\nexport function polyfillPromiseFinally(): void {\n if (typeof Promise !== 'undefined' && !Promise.prototype.finally) {\n Promise.prototype.finally = function (callback: () => void) {\n const constructor = this.constructor as PromiseConstructor;\n return this.then(\n (value) => constructor.resolve(callback()).then(() => value),\n (reason) =>\n constructor.resolve(callback()).then(() => {\n throw reason;\n })\n );\n };\n }\n}\n\nexport function polyfillObjectAssign(): void {\n if (typeof Object.assign !== 'function') {\n Object.assign = function (target: any, ...sources: any[]) {\n if (target == null) {\n throw new TypeError('Cannot convert undefined or null to object');\n }\n\n const to = Object(target);\n\n for (let i = 0; i < sources.length; i++) {\n const nextSource = sources[i];\n\n if (nextSource != null) {\n for (const nextKey in nextSource) {\n if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n\n return to;\n };\n }\n}\n\nexport function polyfillArrayFrom(): void {\n if (!Array.from) {\n Array.from = function (arrayLike: any, mapFn?: any, thisArg?: any) {\n const items = Object(arrayLike);\n if (arrayLike == null) {\n throw new TypeError('Array.from requires an array-like object');\n }\n\n const len = items.length >>> 0;\n const result = new Array(len);\n\n for (let i = 0; i < len; i++) {\n if (mapFn) {\n result[i] = mapFn.call(thisArg, items[i], i);\n } else {\n result[i] = items[i];\n }\n }\n\n return result;\n };\n }\n}\n\nexport function polyfillStringStartsWith(): void {\n if (!String.prototype.startsWith) {\n String.prototype.startsWith = function (search: string, pos?: number) {\n pos = !pos || pos < 0 ? 0 : +pos;\n return this.substring(pos, pos + search.length) === search;\n };\n }\n}\n\nexport function polyfillStringEndsWith(): void {\n if (!String.prototype.endsWith) {\n String.prototype.endsWith = function (search: string, length?: number) {\n if (length === undefined || length > this.length) {\n length = this.length;\n }\n return this.substring(length - search.length, length) === search;\n };\n }\n}\n\nexport function polyfillStringIncludes(): void {\n if (!String.prototype.includes) {\n String.prototype.includes = function (search: string, start?: number) {\n if (typeof start !== 'number') {\n start = 0;\n }\n if (start + search.length > this.length) {\n return false;\n }\n return this.indexOf(search, start) !== -1;\n };\n }\n}\n\nexport function initializePolyfills(): void {\n polyfillObjectAssign();\n polyfillArrayFrom();\n polyfillStringStartsWith();\n polyfillStringEndsWith();\n polyfillStringIncludes();\n polyfillURLSearchParams();\n polyfillTextEncoder();\n polyfillPromiseFinally();\n}\n\n","interface NavigatorUAData {\n platform?: string;\n brands?: Array<{ brand: string; version: string }>;\n mobile?: boolean;\n}\n\ndeclare global {\n interface Navigator {\n userAgentData?: NavigatorUAData;\n }\n}\n\nexport interface BrowserInfo {\n name: string;\n version: string;\n majorVersion: number;\n isSmartTV: boolean;\n isLegacyTV: boolean;\n platform: string;\n supportsModernJS: boolean;\n}\n\nfunction getChromeVersion(ua: string): number {\n const match = ua.match(/Chrome\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getWebKitVersion(ua: string): number {\n const match = ua.match(/AppleWebKit\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getPlatform(): string {\n if ('userAgentData' in navigator && navigator.userAgentData?.platform) {\n return navigator.userAgentData.platform;\n }\n\n const ua = navigator.userAgent;\n if (/Mac|iPhone|iPad|iPod/i.test(ua)) {\n return /iPhone|iPad|iPod/i.test(ua) ? 'iPhone' : 'MacIntel';\n }\n if (/Win/i.test(ua)) {\n return 'Win32';\n }\n if (/Linux/i.test(ua)) {\n return /Android/i.test(ua) ? 'Linux armv8l' : 'Linux x86_64';\n }\n if (/CrOS/i.test(ua)) {\n return 'CrOS';\n }\n\n // eslint-disable-next-line deprecation/deprecation\n return (navigator as any).platform || 'Unknown';\n}\n\nexport function detectBrowser(): BrowserInfo {\n const ua = navigator.userAgent;\n const platform = getPlatform();\n\n let name = 'Unknown';\n let version = '0';\n let majorVersion = 0;\n let isSmartTV = false;\n let isLegacyTV = false;\n let supportsModernJS = true;\n\n if (/Web0S|webOS/i.test(ua)) {\n name = 'LG WebOS';\n isSmartTV = true;\n const match = ua.match(/Web0S[/\\s]*([\\d.]+)/i);\n version = match && match[1] ? match[1] : 'Unknown';\n if (version !== 'Unknown') {\n const parts = version.split('.');\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n }\n } else if (/Tizen/i.test(ua)) {\n name = 'Samsung Tizen';\n isSmartTV = true;\n const match = ua.match(/Tizen[/\\s]*([\\d.]+)/i);\n version = match && match[1] ? match[1] : 'Unknown';\n if (version !== 'Unknown') {\n const parts = version.split('.');\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = 'Smart TV';\n isSmartTV = true;\n } else if (/NetCast/i.test(ua)) {\n name = 'LG NetCast';\n isSmartTV = true;\n isLegacyTV = true;\n } else if (/BRAVIA/i.test(ua)) {\n name = 'Sony BRAVIA';\n isSmartTV = true;\n }\n\n const chromeVersion = getChromeVersion(ua);\n const webkitVersion = getWebKitVersion(ua);\n\n if (chromeVersion > 0) {\n if (!isSmartTV) {\n name = 'Chrome';\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n }\n\n if (chromeVersion < 50) {\n supportsModernJS = false;\n isLegacyTV = true;\n }\n }\n\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS = false;\n if (isSmartTV) {\n isLegacyTV = true;\n }\n }\n\n if (typeof Promise === 'undefined' ||\n typeof Map === 'undefined' ||\n typeof Set === 'undefined') {\n supportsModernJS = false;\n }\n\n if (typeof URLSearchParams === 'undefined') {\n supportsModernJS = false;\n }\n\n return {\n name,\n version,\n majorVersion,\n isSmartTV,\n isLegacyTV,\n platform,\n supportsModernJS,\n };\n}\n\nexport function supportsModernJS(): boolean {\n try {\n return (\n typeof Promise !== 'undefined' &&\n typeof Map !== 'undefined' &&\n typeof Set !== 'undefined' &&\n typeof Array.from !== 'undefined' &&\n typeof Object.assign !== 'undefined' &&\n typeof Array.prototype.forEach !== 'undefined' &&\n typeof String.prototype.includes !== 'undefined'\n );\n } catch (e) {\n return false;\n }\n}\n\nexport function logBrowserInfo(debug: boolean = false): void {\n if (!debug) return;\n\n const browser = detectBrowser();\n\n console.log('[StormcloudVideoPlayer] Browser Compatibility Info:', {\n browser: `${browser.name} ${browser.version}`,\n platform: browser.platform,\n isSmartTV: browser.isSmartTV,\n isLegacyTV: browser.isLegacyTV,\n supportsModernJS: browser.supportsModernJS,\n userAgent: navigator.userAgent,\n });\n}\n\nexport function getBrowserConfigOverrides(): {\n allowNativeHls?: boolean;\n} {\n const browser = detectBrowser();\n const overrides: { allowNativeHls?: boolean } = {};\n\n if (browser.isSmartTV) {\n overrides.allowNativeHls = true;\n }\n\n return overrides;\n}\n\nexport function supportsFeature(feature: string): boolean {\n switch (feature) {\n case 'urlsearchparams':\n return typeof URLSearchParams !== 'undefined';\n case 'textencoder':\n return typeof TextEncoder !== 'undefined';\n case 'promises':\n return typeof Promise !== 'undefined';\n case 'fetch':\n return typeof fetch !== 'undefined';\n case 'crypto':\n return typeof crypto !== 'undefined' && typeof crypto.subtle !== 'undefined';\n default:\n return false;\n }\n}\n","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 \"driftToleranceMs\",\n \"immediateManifestAds\",\n \"debugAdTiming\",\n \"showCustomControls\",\n \"licenseKey\",\n \"adFailsafeTimeoutMs\",\n \"minSegmentsBeforePlay\",\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 driftToleranceMs?: number;\n immediateManifestAds?: boolean;\n debugAdTiming?: boolean;\n showCustomControls?: boolean;\n hideLoadingIndicator?: boolean;\n licenseKey?: string;\n adFailsafeTimeoutMs?: number;\n minSegmentsBeforePlay?: number;\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 | 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 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.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\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","import type { ClientInfo, TrackingData, HeartbeatData } from \"../types\";\n\nlet cachedBrowserId: string | null = null;\n\nexport function getClientInfo(): ClientInfo {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = (navigator as any).deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: (screen?.orientation as any)?.type || \"\",\n pixelDepth: screen?.pixelDepth,\n };\n\n let deviceType: \"tv\" | \"mobile\" | \"tablet\" | \"desktop\" = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch\n ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim()\n : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))\n ) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"NetCast\") || ua.includes(\"LG\"))\n ) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n\n if (\n ua.includes(\"Android\") &&\n (maxTouchPoints === 0 ||\n ua.includes(\"Google TV\") ||\n ua.includes(\"XiaoMi\"))\n ) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n\n isWebApp =\n window.matchMedia(\"(display-mode: standalone)\").matches ||\n (window.navigator as any).standalone === true ||\n window.screen?.orientation?.angle !== undefined;\n\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState,\n };\n}\n\nexport async function getBrowserID(clientInfo: ClientInfo): Promise<string> {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n\n const fingerprintString = JSON.stringify(clientInfo);\n\n if (typeof crypto !== \"undefined\" && crypto.subtle && crypto.subtle.digest) {\n try {\n await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n\n let encodedData: BufferSource;\n if (typeof TextEncoder !== \"undefined\") {\n encodedData = new TextEncoder().encode(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\n const buffer = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i++) {\n buffer[i] = utf8.charCodeAt(i);\n }\n encodedData = buffer;\n }\n\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n\n const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n const timestamp = Date.now().toString(16).padStart(12, \"0\");\n const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n\n cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\n\nexport async function sendInitialTracking(licenseKey?: string): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n\n const trackingData: TrackingData = {\n browserId,\n ...clientInfo,\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(trackingData),\n }\n );\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n await response.json();\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\n\nexport async function sendHeartbeat(licenseKey?: string): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n\n const heartbeatData: HeartbeatData = {\n browserId,\n timestamp: new Date().toISOString(),\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(heartbeatData),\n }\n );\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n await response.json();\n } catch (error) {\n console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n }\n}\n","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\nconst UNSUPPORTED_VIDEO_EXTENSIONS = ['.flv', '.f4v', '.swf', '.wmv', '.avi', '.mov', '.mkv', '.mp4', '.webm'];\n\nfunction getFileExtension(url: string): string {\n try {\n const pathname = new URL(url, 'http://dummy').pathname;\n const lastDot = pathname.lastIndexOf('.');\n if (lastDot === -1) return '';\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf('.');\n if (lastDot === -1) return '';\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || '').toLowerCase();\n }\n}\n\nfunction isUnsupportedForHls(url: string): boolean {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\n\nfunction replaceFlvExtension(url: string): string {\n const ext = getFileExtension(url);\n if (ext === '.flv') {\n return url.replace(/\\.flv(\\?|$)/i, '.mp4$1');\n }\n return url;\n}\n\ninterface VastTrackingUrls {\n impression: string[];\n start: string[];\n firstQuartile: string[];\n midpoint: string[];\n thirdQuartile: string[];\n complete: string[];\n mute: string[];\n unmute: string[];\n pause: string[];\n resume: string[];\n fullscreen: string[];\n exitFullscreen: string[];\n skip: string[];\n error: string[];\n}\n\ninterface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\nexport function createHlsAdPlayer(\n contentVideo: HTMLVideoElement,\n options?: {\n continueLiveStreamDuringAds?: boolean;\n licenseKey?: string;\n mainHlsInstance?: Hls;\n }\n): AdController {\n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n let allowNativeHls = false;\n const listeners = new Map<string, Set<(payload?: any) => void>>();\n const licenseKey = options?.licenseKey;\n const mainHlsInstance = options?.mainHlsInstance;\n\n let adVideoElement: HTMLVideoElement | undefined;\n let adHls: Hls | undefined;\n let adContainerEl: HTMLDivElement | undefined;\n let currentAd: VastAd | undefined;\n let sessionId: string | undefined;\n 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 buildVastUrl(durationSeconds: number): string {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n \n const metadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5000,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0,\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48000,\n bitrate: 128,\n },\n };\n \n const metadataStr = encodeURIComponent(JSON.stringify(metadata));\n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\n }\n\n function fireTrackingPixels(urls: string[]): void {\n if (!urls || urls.length === 0) return;\n\n urls.forEach((url) => {\n try {\n let trackingUrl = url;\n\n if (sessionId) {\n trackingUrl = `${trackingUrl}${\n trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n }session_id=${sessionId}`;\n }\n\n if (licenseKey) {\n trackingUrl = `${trackingUrl}${\n trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n }license_key=${licenseKey}`;\n }\n\n const img = new Image(1, 1);\n img.src = trackingUrl;\n console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n }\n });\n }\n\n function getMainStreamQuality(): {\n width: number;\n height: number;\n bitrate: number;\n } | null {\n if (!mainHlsInstance || !mainHlsInstance.levels) {\n return null;\n }\n\n const currentLevel = mainHlsInstance.currentLevel;\n if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n const autoLevel = mainHlsInstance.loadLevel;\n if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n const level = mainHlsInstance.levels[autoLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5000000,\n };\n }\n return null;\n }\n\n const level = mainHlsInstance.levels[currentLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5000000,\n };\n }\n\n function selectBestMediaFile(mediaFiles: VastMediaFile[]): VastMediaFile {\n if (mediaFiles.length === 0) {\n throw new Error(\"No media files available\");\n }\n\n const firstFile = mediaFiles[0];\n if (!firstFile) {\n throw new Error(\"No media files available\");\n }\n\n if (mediaFiles.length === 1) {\n return firstFile;\n }\n\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n console.log(\n \"[HlsAdPlayer] No main stream quality info, using first media file\"\n );\n return firstFile;\n }\n\n console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\n\n const scoredFiles = mediaFiles.map((file) => {\n const widthDiff = Math.abs(file.width - mainQuality.width);\n const heightDiff = Math.abs(file.height - mainQuality.height);\n const resolutionDiff = widthDiff + heightDiff;\n\n const fileBitrate = (file.bitrate || 5000) * 1000;\n const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n\n const score = resolutionDiff * 2 + bitrateDiff / 1000;\n\n return { file, score, resolutionDiff, bitrateDiff };\n });\n\n scoredFiles.sort((a, b) => a.score - b.score);\n\n const bestMatch = scoredFiles[0];\n if (!bestMatch) {\n console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n return firstFile;\n }\n\n console.log(\"[HlsAdPlayer] Selected media file:\", {\n url: bestMatch.file.url,\n resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n bitrate: bestMatch.file.bitrate,\n score: bestMatch.score,\n resolutionDiff: bestMatch.resolutionDiff,\n bitrateDiff: bestMatch.bitrateDiff,\n });\n\n return bestMatch.file;\n }\n\n function parseVastXml(xmlString: string): VastAd | null {\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\n \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n parserError.textContent\n );\n return null;\n }\n\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n return null;\n }\n\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n const isNoAdAvailable =\n adId === \"empty\" ||\n title.toLowerCase().includes(\"no ad available\") ||\n title.toLowerCase() === \"no ad available\";\n\n const durationText =\n xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration =\n parseInt(durationParts[0] || \"0\", 10) * 3600 +\n parseInt(durationParts[1] || \"0\", 10) * 60 +\n parseInt(durationParts[2] || \"0\", 10);\n\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n\n console.log(\n `[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n );\n\n mediaFileElements.forEach((mf, index) => {\n const type = mf.getAttribute(\"type\") || \"\";\n let 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 originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n console.log(`[HlsAdPlayer] Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n\n if (isUnsupportedForHls(url)) {\n const ext = getFileExtension(url);\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored: unsupported format (extension: ${ext}, declared type: ${type})`\n );\n return;\n }\n\n if (type === \"application/x-mpegURL\" || type.includes(\"m3u8\")) {\n if (!url) {\n console.warn(\n `[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`\n );\n return;\n }\n\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr\n ? parseInt(bitrateAttr, 10)\n : undefined;\n\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate:\n bitrateValue && bitrateValue > 0 ? bitrateValue : undefined,\n });\n\n console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);\n } else {\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not HLS)`\n );\n }\n });\n\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n \"[HlsAdPlayer] No ads available (VAST response indicates no ads)\"\n );\n } else {\n console.warn(\"[HlsAdPlayer] No HLS media files found in VAST XML\");\n }\n return null;\n }\n\n const trackingUrls: VastTrackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: [],\n };\n\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event as keyof VastTrackingUrls;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n\n const clickThrough = xmlDoc\n .querySelector(\"ClickThrough\")\n ?.textContent?.trim();\n\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough,\n };\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n return null;\n }\n }\n\n async function fetchAndParseVastAd(\n url: string\n ): Promise<VastAd | null> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n\n const vastXml = await response.text();\n console.log(\"[HlsAdPlayer] VAST XML received\");\n console.log(\n \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n vastXml.substring(0, 2000)\n );\n\n return parseVastXml(vastXml);\n }\n\n function createAdVideoElement(): HTMLVideoElement {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.playsInline = true;\n video.muted = false;\n\n video.volume = 1.0;\n console.log(\n `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n );\n\n return video;\n }\n\n function setupAdEventListeners(): void {\n if (!adVideoElement || !currentAd) return;\n\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!currentAd || !adVideoElement) return;\n\n const progress = adVideoElement.currentTime / currentAd.duration;\n\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.firstQuartile);\n }\n\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(currentAd.trackingUrls.midpoint);\n }\n\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);\n }\n });\n\n adVideoElement.addEventListener(\"playing\", () => {\n if (!currentAd || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(currentAd.trackingUrls.start);\n console.log(\"[HlsAdPlayer] Ad started playing\");\n });\n\n adVideoElement.addEventListener(\"ended\", () => {\n if (!currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(currentAd.trackingUrls.complete);\n console.log(\"[HlsAdPlayer] Ad completed\");\n\n handleAdComplete();\n });\n\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[HlsAdPlayer] Ad video error:\", e);\n if (currentAd) {\n fireTrackingPixels(currentAd.trackingUrls.error);\n }\n handleAdError();\n });\n\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd) return;\n if (adVideoElement!.muted) {\n fireTrackingPixels(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels(currentAd.trackingUrls.unmute);\n }\n });\n\n adVideoElement.addEventListener(\"pause\", () => {\n if (currentAd && !adVideoElement!.ended) {\n fireTrackingPixels(currentAd.trackingUrls.pause);\n }\n });\n\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && adVideoElement!.currentTime > 0) {\n fireTrackingPixels(currentAd.trackingUrls.resume);\n }\n });\n }\n\n function setAdPlayingFlag(isPlaying: boolean): void {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n\n function handleAdComplete(): void {\n console.log(\"[HlsAdPlayer] Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n emit(\"content_resume\");\n\n const timeoutId = window.setTimeout(() => {\n if (destroyed) {\n console.log(\"[HlsAdPlayer] Player destroyed, skipping post-completion check\");\n return;\n }\n \n const stillInPod = contentVideo.dataset.stormcloudAdPlaying === \"true\";\n if (stillInPod) {\n console.log(\n \"[HlsAdPlayer] Still in ad pod - keeping ad container visible (black screen)\"\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n }\n \n const idx = pendingTimeouts.indexOf(timeoutId);\n if (idx !== -1) {\n pendingTimeouts.splice(idx, 1);\n }\n }, 50);\n \n pendingTimeouts.push(timeoutId);\n }\n\n function handleAdError(): void {\n console.log(\"[HlsAdPlayer] Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n const previousMutedState = contentVideo.muted;\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n console.log(\n `[HlsAdPlayer] Restored mute state: ${previousMutedState} -> ${originalMutedState}`\n );\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n if (!options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n contentVideo.play().catch(() => {});\n }\n }\n\n emit(\"ad_error\");\n }\n\n return {\n initialize() {\n console.log(\"[HlsAdPlayer] Initializing\");\n\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n\n async requestAds(duration: string) {\n console.log(\"[HlsAdPlayer] Requesting ads for duration:\", duration);\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 \n let durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n \n const vastUrl = buildVastUrl(durationSeconds);\n const ad = await fetchAndParseVastAd(vastUrl);\n\n if (!ad) {\n console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n\n currentAd = ad;\n console.log(\n `[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`\n );\n\n fireTrackingPixels(ad.trackingUrls.impression);\n trackingFired.impression = true;\n\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n\n async play() {\n if (!currentAd) {\n console.warn(\n \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n );\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n\n console.log(\"[HlsAdPlayer] Starting ad playback\");\n\n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n\n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(\n 0,\n Math.min(1, contentVolume || originalVolume)\n );\n\n if (!options?.continueLiveStreamDuringAds) {\n contentVideo.pause();\n console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n } else {\n console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n }\n\n console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n\n if (adVideoElement) {\n const adVolume = originalMutedState ? 0 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\n console.log(\n `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`\n );\n }\n\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n\n emit(\"content_pause\");\n\n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available for ad\");\n }\n\n console.log(`[HlsAdPlayer] Loading ad from: ${mediaFile.url}`);\n\n if (Hls.isSupported()) {\n if (adHls) {\n adHls.destroy();\n }\n\n adHls = new Hls({\n enableWorker: true,\n lowLatencyMode: false,\n });\n\n adHls.loadSource(mediaFile.url);\n adHls.attachMedia(adVideoElement);\n\n adHls.on(Hls.Events.MANIFEST_PARSED, () => {\n console.log(\"[HlsAdPlayer] HLS manifest parsed, starting playback\");\n adVideoElement!.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n });\n\n adHls.on(Hls.Events.ERROR, (event, data) => {\n console.error(\"[HlsAdPlayer] HLS error:\", data);\n if (data.fatal) {\n handleAdError();\n }\n });\n } else if (\n adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")\n ) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n } else {\n throw new Error(\"HLS not supported\");\n }\n\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n\n async stop() {\n console.log(\"[HlsAdPlayer] Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n\n currentAd = undefined;\n },\n\n destroy() {\n console.log(\"[HlsAdPlayer] Destroying\");\n destroyed = true;\n for (const timeoutId of pendingTimeouts) {\n clearTimeout(timeoutId);\n }\n pendingTimeouts = [];\n \n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = undefined;\n }\n\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n\n adContainerEl = undefined;\n currentAd = undefined;\n listeners.clear();\n },\n\n isAdPlaying() {\n return adPlaying;\n },\n\n resize(width: number, height: number) {\n console.log(`[HlsAdPlayer] Resizing to ${width}x${height}`);\n\n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n\n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n\n on(event: string, listener: (payload?: any) => void) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(listener);\n },\n\n off(event: string, listener: (payload?: any) => void) {\n listeners.get(event)?.delete(listener);\n },\n\n updateOriginalMutedState(muted: boolean, volume?: number) {\n const nextVolume =\n typeof volume === \"number\" && !Number.isNaN(volume)\n ? Math.max(0, Math.min(1, volume))\n : originalVolume;\n console.log(\n `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n );\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n\n getOriginalMutedState() {\n return originalMutedState;\n },\n getOriginalVolume() {\n return originalVolume;\n },\n\n setAdVolume(volume: number) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n },\n setAllowNativeHls(value: boolean) {\n allowNativeHls = value;\n },\n };\n}\n"]}
|