{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/ui/StormcloudVideoPlayer.cjs","../../src/ui/StormcloudVideoPlayer.tsx","../../src/sdk/hlsAdPlayer.ts","../../src/sdk/pal.ts","../../src/utils/mqttConfig.ts","../../src/utils/mqttClient.ts","../../src/utils/vastEnvironmentSignals.ts","../../src/utils/tracking.ts","../../src/utils/polyfills.ts","../../src/utils/vastMacros.ts","../../src/utils/browserCompat.ts","../../src/player/Scte35Parser.ts","../../src/player/Scte35CueManager.ts","../../src/player/AdConfigManager.ts","../../src/player/AdTimingService.ts","../../src/player/PlaceholderLayer.ts","../../src/player/HlsEngine.ts","../../src/player/PlayerControls.ts","../../src/player/AdBreakOrchestrator.ts"],"names":["__create","Object","create","__defProp","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","from","__copyProps","to","except","desc","key","call","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","StormcloudVideoPlayer_exports","StormcloudVideoPlayerComponent","exports","import_react","require","import_hls","MAX_VAST_WRAPPER_DEPTH","createHlsAdPlayer","contentVideo","options","adPlaying","originalMutedState","originalVolume","Math","max","min","volume","listeners","Map","licenseKey","sessionId","destroyed","mainHlsInstance","adVideoElement","adHls","adContainerEl","currentAd","podAds","podIndex","preloadingAds","pendingTimeouts","trackingFired","impression","start","midpoint","complete","set","event","Array","fn","payload","error","generateSessionId","Date","now","fireTrackingPixels","random","urls","toString","substr","forEach","url","trackingUrl","includes","level","levels","autoLevel","width","img","Image","src","console","log","warn","getMainStreamQuality","currentLevel","loadLevel","height","bitrate","selectBestMediaFile","mediaFiles","length","Error","firstFile","mainQuality","scoredFiles","map","file","widthDiff","abs","heightDiff","resolutionDiff","fileBitrate","bitrateDiff","score","sort","a","b","bestMatch","resolution","isHlsMediaFile","mediaFile","type","toLowerCase","isProgressiveMediaFile","startsWith","endsWith","createEmptyTrackingUrls","firstQuartile","thirdQuartile","mute","unmute","pause","resume","fullscreen","exitFullscreen","skip","extractTrackingUrls","scope","trackingUrls","querySelectorAll","el","textContent","trim","push","getAttribute","eventKey","mergeTrackingUrls","source","keys","concat","parseVastXml","xmlString","xmlDoc","parser","DOMParser","parseFromString","parserError","querySelector","adElement","adId","title","clickThrough","wrapperUri","vastAdTagUri","isNoAdAvailable","durationText","durationParts","split","duration","parseInt","mediaFileElements","mf","index","bitrateAttr","bitrateValue","ad","id","parseAdElement","fetchVastXml","vastTagUrl","credentials","requestVast","response","creds","mode","headers","ok","statusText","text","fetchAndParseVastAd","depth","accumulatedTracking","vastXml","parsed","substring","fetchAndParsePod","adElements","ads","resolved","aSeq","bSeq","aVal","Number","isFinite","MAX_SAFE_INTEGER","bVal","createAdVideoElement","video","document","createElement","style","position","left","top","backgroundColor","playsInline","muted","setupAdEventListeners","addEventListener","progress","currentTime","advanceToNextPodAd","handleAdComplete","handleAdError","e","ended","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","resetQuartileTracking","preserveImpression","loadCurrentAdMedia","isHlsAd","Hls","isSupported","destroy","enableWorker","lowLatencyMode","loadSource","attachMedia","on","Events","MANIFEST_PARSED","play","catch","ERROR","_event","data","fatal","canPlayType","load","emit","display","pointerEvents","continueLiveStreamDuringAds","paused","initialize","container","right","bottom","alignItems","justifyContent","zIndex","parentElement","appendChild","requestAds","preloaded","preloadedAds","has","delete","Promise","reject","resolve","contentVolume","stop","previousMutedState","visibility","opacity","clearTimeout","timeoutId","remove","removeChild","clear","isAdPlaying","resize","listener","Set","add","off","updateOriginalMutedState","nextVolume","isNaN","getOriginalMutedState","getOriginalVolume","setAdVolume","clamped","getAdVolume","showPlaceholder","hidePlaceholder","getLoadedAdDuration","getLoadedAdId","getPodAdCount","getPodTotalDurationMs","reduce","total","PAL_SDK_URL","_nonceLoader","_palLoadPromise","loadPalSdk","window","goog","pal","existing","timeout","setTimeout","script","async","setAttribute","onload","onerror","head","getOrCreateNonceLoader","consentSettings","ConsentSettings","allowStorage","NonceLoader","currentNonceManager","sendPlaybackEnd","createPalNonceManager","currentNonce","generateNonce","loader","request","manager","NonceRequest","adWillAutoPlay","adWillPlayMuted","playerVolume","continuousPlayback","descriptionUrl","location","href","iconsSupported","playerType","playerVersion","supportedApiFrameworks","videoWidth","videoHeight","ppid","loadNonceManager","getNonce","getCurrentNonce","injectNonce","URL","searchParams","base","replace","sep","encodeURIComponent","sendPlaybackStart","sendAdClick","sendAdTouch","reset","DEFAULT_MQTT_CONFIG","enabled","brokerAddress","brokerPort","wsPort","username","password","mqttConfig","buildMQTTBrokerUrl","brokerUrl","status","clientId","clean","topicPrefix","isMQTTEnabled","buildPlayerTopic","channel","import_mqtt","client","slice","mqtt","connect","keepalive","reconnectPeriod","connectTimeout","queueQoSZero","err","LOG","info","initMQTTClient","message","ensureMQTTClient","publishMQTT","topic","publish","JSON","stringify","qos","AIRY_ROKU_APP_ID","AIRY_ANDROID_APP_ID","AIRY_WEBOS_APP_ID","AIRY_TIZEN_APP_ID","AIRY_APP_NAME","AIRY_DEFAULT_CONTENT_URL","CTV_SESSION_STORAGE_KEY","LG_TEST_APP_NAME","LG_TEST_CONTENT_URL","isLgWebOS","getLgTestDeviceId","_lgTestDeviceId","createUuid","navigator","test","userAgent","ua","DEVICE_ID_STORAGE_KEYS","isCtv","ANDROID_ID_TYPES","resolveVastEnvironmentSignals","platformLat","bridgeSignals","readNativeBridgeSignals","platformDevice","readPlatformNativeDeviceId","lg","deviceId","readStoredDeviceId","limitAdTracking","deviceIdType","readStoredString","inferDeviceIdType","readStoredLimitAdTracking","contentUrl","getOrCreateCtvSessionId","isEquivalentDeviceIdType","tagType","runtimeType","tag","runtime","resolveNativeDeviceId","isMacroPlaceholder","isZeroedAdId","getOrCreateStoredUuid","storageKey","readPersistentId","writePersistentId","readCookie","localStorage","setItem","writeCookie","PERSISTENT_ID_COOKIE_MAX_AGE","prefix","parts","part","entry","decodeURIComponent","cookie","bytes","crypto","randomUUID","Uint8Array","getRandomValues","seed","floor","performanceNow","i","hex","padStart","performance","adinfo","webapis","tifa","getTIFA","lat","isLATEnabled","webOSDev","lgudid","LGUDID","roku","Roku","rida","getPublisherUniqueId","ZEROED_AD_ID_PATTERNS","t","candidates","__STORMCLOUD_CTV_AD_INFO__","__STORMCLOUD_CTV__","stormcloudCtv","AiryTV","Android","webOS","tizen","amazon","filter","Boolean","readBridgeValue","appId","appName","readBridgeBoolean","result","normalized","normalizeBoolean","getItem","cachedBrowserId","buildAnalyticsContext","config","context","debugAdTiming","isLiveStream","inputStreamType","getClientInfo","screen","platform","vendor","maxTouchPoints","memory","deviceMemory","hardwareConcurrency","screenInfo","availWidth","availHeight","orientation","pixelDepth","deviceType","brand","os","model","isSmartTV","isAndroid","isWebView","isWebApp","webosMatch","match","tizenMatch","tvMatch","androidModelMatch","outerHeight","outerWidth","matchMedia","matches","standalone","angle","domain","hostname","origin","path","pathname","language","languages","join","cookieEnabled","doNotTrack","referrer","visibilityState","sha256Hex","input","encodedData","utf8","buffer","hashBuffer","hash","char","fallbackHash","timestamp","subtle","digest","TextEncoder","encode","unescape","charCodeAt","padEnd","resolvePlayerIdentitySeed","clientInfo","nativeDeviceId","persistedId","PLAYER_ID_STORAGE_KEY","getBrowserID","canPublish","buildPlayerMetricEvent","flags","playerId","captureAt","toISOString","player_id","device_type","ad_loaded","adLoaded","ad_detect","adDetect","capture_at","input_stream_type","publishTracking","body","sendInitialTracking","metricEvent","events","sendAdDetectTracking","adDetectInfo","sendHeartbeat","sendAdLoadedTracking","adLoadedInfo","sendAdImpressionTracking","adImpressionInfo","ad_played_count","ad_url","adUrl","heartbeatData","polyfillURLSearchParams","URLSearchParams","URLSearchParamsPolyfill","init","params","parseQueryString","append","query","cleanQuery","param","decodedKey","safeDecodeURIComponent","decodedValue","str","values","String","getAll","callback","polyfillTextEncoder","TextEncoderPolyfill","encoding","charcode","polyfillPromiseFinally","finally","constructor","then","reason","polyfillObjectAssign","assign","sources","TypeError","nextSource","nextKey","polyfillArrayFrom","arrayLike","mapFn","thisArg","items","len","pos","polyfillStringEndsWith","UNEXPANDED_MACRO_PATTERN","polyfillStringStartsWith","search","polyfillStringIncludes","indexOf","initializePolyfills","INVALID_VAST_PARAM_KEY","EXAMPLE_COM_URL","CTV_UNSUPPORTED_PARAMS","INLINE_DEVICE_MACRO_REPLACEMENTS","pattern","getValue","ctx","correlator","trimmed","generateCorrelator","buf","expandInlineMacroPlaceholders","baseUrl","applyDeviceIdentityParams","runtimeId","tagRdid","tagLat","latValue","tagRdidValid","tagTypeValid","removeBrokenAppNameOrphans","toDelete","_value","suffix","trimStart","raw","normalizeVastTagUrl","anValue","orphanFragments","reconstructed","trimEnd","_match","val","applyVastMacros","expandedUrl","replaceCorrelatorFallback","streamCorrelator","pod","podMinDurationMs","podMaxDurationMs","round","podMaxAds","requestUrl","pageUrl","existingUrl","success","correlatorRegex","deviceTypeHint","consent","gdpr","gdprConsent","usPrivacy","adTest","staleKeys","fetchConsentSignals","timeoutMs","signals","tasks","tcfApi","__tcfapi","settled","tcData","eventStatus","gdprApplies","tcString","uspApi","__uspapi","uspString","getChromeVersion","getWebKitVersion","getPlatform","userAgentData","detectBrowser","version","majorVersion","isLegacyTV","supportsModernJS","webOSVersion","tizenVersion","chromeVersionNum","chromeVersion","webkitVersion","getBrowserConfigOverrides","browser","overrides","allowNativeHls","logBrowserInfo","debug","parseCueOutDuration","num","parseFloat","dStr","d","parseCueOutCont","res","durationMatch","elapsedMatch","elapsed","slashMatch","parseAttributeList","attrs","regex","exec","rawVal","toNumber","isManifestBasedMarker","marker","id3","splice_command_type","decodeId3ValueToText","decoder","TextDecoder","decode","out","fromCharCode","getFragmentStartSeconds","frag","startPTS","candidate","parseScte35FromId3","cueOutMatch","arg","dur","ptsSeconds","durationSeconds","cueOutContMatch","cont","cueInMatch","daterangeMatch","hasScteOut","hasScteIn","klass","bin","parseScte35Binary","normalizeFragmentPayload","ArrayBuffer","isView","view","byteOffset","byteLength","detectTsPacketFormat","packetSizes","packetSize","tsPayloadOffset","offset","matchedPackets","packetStart","getPsiSectionStart","payloadUnitStart","pointerField","sectionStart","getPsiSectionLength","parsePatSection","pmtPids","sectionLength","sectionEnd","programNumber","pid","descriptorsIdentifyScte35","end","descriptorStart","descriptorEnd","registration","parsePmtSection","tsScte35Pids","programInfoLength","streamType","elementaryPid","esInfoLength","hasProcessedTsScte35Section","section","processedSections","checksum","size","firstKey","next","addScte35SectionMarker","markers","appendScte35Bytes","assemblers","assembler","expectedLength","collectScte35SectionsFromPayload","previousAssembler","subarray","tableId","totalLength","parseScte35FromTsPackets","packetInfo","sectionAssemblers","tsStart","secondByte","thirdByte","fourthByte","adaptationFieldControl","hasPayload","payloadStart","adaptationLength","payloadEnd","BitReader","bytePos","bitPos","readBits","numBits","remainingInByte","toRead","currentByte","shift","mask","bits","skipBits","n","bytePosition","readSpliceTime","r","ptsAdjustmentTicks","timeSpecifiedFlag","high","low","ptsTicks","segmentationTypeId","segmentationEventId","parseScte35SegmentationDescriptor","descriptor","identifier","cancelIndicator","programSegmentationFlag","segmentationDurationFlag","componentCount","durationTicks","segmentationUpidLength","markerType","markerTypeFromSegmentationTypeId","parseScte35SegmentationDescriptors","descriptorLoopLength","descriptorOffset","descriptorTag","descriptorLength","descriptorDataStart","descriptorDataEnd","descriptorMarker","ptsAdjHigh","ptsAdjLow","spliceCommandLength","spliceCommandType","spliceEventId","commandBodyStart","cancel","outOfNetwork","durationFlag","spliceImmediateFlag","programSpliceFlag","componentPtsSeconds","expectedDescriptorOffset","splice_event_id","segmentation_event_id","Scte35CueManager","callbacks","pendingScte35Cues","recentScte35CueKeys","recentScte35CueLimit","processedTsScte35Sections","pendingScte35CueKey","pendingScte35CueKeyValue","activeScte35BreakKey","activeScte35BreakKeyValue","scheduledScte35BreakKey","scheduledScte35BreakKeyValue","createScte35CueContext","readiness","fragmentSn","sn","fragmentStartSec","fragmentStartSeconds","onScte35Cue","cue","createScte35Cue","pendingKey","getPendingScte35CueKey","trimRecentScte35CueMaps","onEarlyStartCue","shouldAcceptScte35EndCue","inAdBreak","isInAdBreak","hasRecentlyHandledScte35Cue","markScte35CueHandled","onPlaybackCue","activatePendingScte35CuesForFragment","matchingCues","entries","getScte35CueKey","getScte35MarkerRaw","toIdentityString","daterangeId","ID","scteValue","isStrongScte35CueKey","recentKey","AdConfigManager","vmapBreaks","consumedVmapBreakIds","viewCorrelator","consentSignals","podCounter","podAssignedByPrefetch","lastHeartbeatTime","defaultPodMaxAds","defaultPodMaxDurationMs","isVmapEnabled","isVmap","vmapUrl","fetchAdConfiguration","vastMode","vastEndpoint","apiUrl","imaPayload","decodedPayload","numberAds","apiVastTagUrl","fetch","json","ima","vast","cue_tones","number_ads","apiNumberAds","fetchAndParseVmap","vmapXml","parseVmapToBreaks","doc","VMAP_NS","adBreakNodes","getElementsByTagNameNS","getElementsByTagName","localName","node","timeOffsetRaw","startTimeMs","parseVmapTimeOffsetToMs","adTagNode","adTagUrl","breakId","aStart","bStart","timeOffset","seconds","hms","hh","mm","ss","ms","hours","minutes","millis","percent","ratio","durationSec","getAdBreakKey","adBreak","resolveBreakStartMs","findCurrentOrNextBreak","nowMs","schedule","tol","driftToleranceMs","breakStartMs","findBreakForTime","durationMs","selectVastTagsForBreak","s","beginNewAdPod","resolvePodParams","breakDurationMs","generatePodVastUrl","podParams","urlWithMacros","maxDurationMs","maxAds","minDurationMs","podExactDuration","adPlayer","palNonce","envSignals","ctvAdRequest","autoplay","finalUrl","initializeTracking","heartbeatInterval","setInterval","sendHeartbeatIfNeeded","destroyTracking","clearInterval","AdTimingService","adFailsafeToken","ptsDriftEmaMs","adBreakPlayedDurationMs","adBreakEpoch","adRequestTokenCounter","activeAdRequestToken","currentAdIndex","lastAdRequestTime","totalAdsInBreak","totalAdRequestsInBreak","maxTotalAdRequestsPerBreak","cueKey","consecutiveFailures","maxConsecutiveFailures","minAdRequestIntervalMs","backoffBaseMs","maxBackoffMs","defaultMinRemainingMsToStartAd","failedVastUrls","temporaryFailureUrls","temporaryFailureCooldownMs","globalConsecutiveNoFills","globalNoFillThreshold","globalNoFillCooldownUntil","globalNoFillBackoffBaseMs","globalNoFillBackoffMaxMs","globalLastGamRequestTime","globalMinGamIntervalMs","scheduleAdStopCountdown","remainingMs","clearAdStopTimer","ensureAdStoppedByTimer","adStopTimerId","onAdStopTimerFired","scheduleAdStartIn","delayMs","clearAdStartTimer","onAdStartTimerFired","adStartTimerId","updatePtsDrift","ptsSecondsSample","sampleMs","alpha","resolveScteBreakStartWallClockMs","nowWallClockMs","estimatedCurrentPtsMs","deltaMs","setAdBreakDurationBoundary","expectedAdBreakDurationMs","currentAdBreakStartWallClockMs","scteAdBreakEndWallClockMs","scheduleAdStopAtBreakBoundary","getWallClockRemainingAdMs","endWallClockMs","getAdBreakEndWallClockMs","getDurationBudgetRemainingMs","getLoadedAdDurationMs","adController","adFitsRemainingBudget","logAdDurationDecision","accepted","remainingBudget","recordPlayedAdDuration","ensureLoadedAdFitsBudget","fits","markAdStarted","notePodAdStarted","getRemainingAdMs","wallClockRemaining","budgetRemaining","getMinRemainingMsToStartAd","configured","minRemainingMsToStartAd","hasTimeToStartAnotherAd","minRemaining","isTemporaryAdError","isUrlInCooldown","failureTime","cleanupTemporaryFailures","isGamInCooldown","recordGamNoFill","exponent","backoff","pow","resetGamNoFillCounter","enforceGlobalRateLimit","waitMs","startAdRequestWatchdog","token","clearAdRequestWatchdog","adFailsafeTimeoutMs","adRequestWatchdogToken","adRequestWatchdogId","logAdState","onWatchdogTimeout","startAdFailsafeTimer","clearAdFailsafeTimer","failsafeMs","adFailsafeTimerId","videoPaused","onFailsafeTimeout","extra","showAds","resetForBreakEnd","PlaceholderLayer","ensureContainer","transition","show","wasHidden","offsetHeight","requestAnimationFrame","hide","HlsEngine","cueManager","timing","nativeHlsMode","videoSrcProtection","bufferedSegmentsCount","shouldAutoplayAfterBuffering","hasInitialBufferCompleted","shouldUseNativeHls","getStreamType","canNative","setupNativeHls","adBehavior","isLive","setupHls","hls","import_hls2","backBufferLength","liveDurationInfinity","maxLiveSyncPlaybackRate","liveSyncDuration","maxBufferLength","maxMaxBufferLength","maxBufferSize","maxBufferHole","highBufferWatchdogPeriod","nudgeOffset","nudgeMaxRetry","startPosition","MEDIA_ATTACHED","_","_data","minSegments","some","details","live","onManifestParsed","minSegmentsBeforePlay","LEVEL_LOADED","_evt","hasPendingAdBreak","fragments","fragmentsToScan","tagList","isArray","idx","earlyDetection","FRAG_BUFFERED","FRAG_PARSING_METADATA","id3Tags","samples","pts","onId3Tag","FRAG_LOADED","processFragmentScte35Payload","FRAG_DECRYPTED","FRAG_CHANGED","activatePendingCuesForFragment","prog","ErrorTypes","NETWORK_ERROR","startLoad","MEDIA_ERROR","recoverMediaError","onFatalDestroy","payloadData","getLiveSyncPosition","liveSyncPosition","getAdAudioVolume","toggleMute","newMutedState","restoreVolume","toggleFullscreen","fullscreenElement","requestFullscreen","isMuted","setVolume","clampedVolume","getVolume","isFullscreen","resizePlayer","clientWidth","clientHeight","AdBreakOrchestrator","host","adConfig","placeholder","isShowingPlaceholder","continuousFetchingActive","continuousFetchLoopRunning","adRequestQueue","adPodQueue","maxPlaceholderDurationMs","pendingAdBreak","analyticsContext","nextAdRequestUrl","baseVastUrl","remaining","attachImaEventListeners","getAdPlayer","adIndex","queuedUrls","tryNextAvailableAdWithRateLimit","recreateAdController","shouldShowPlaceholder","preservedMutedState","preservedVolumeState","shouldContinueLiveStreamDuringAds","newAdPlayer","createAdPlayer","setAdPlayer","clearPendingAdBreak","prefetchTimerId","handleAdStart","_marker","scheduled","tags","adBreakDurationMs","currentMuted","currentVolume","podPlayed","startOptimizedPod","startContinuousFetching","podUrl","requestToken","podCount","vastUrls","vastUrl","continuousFetchLoop","epoch","maxQueueSize","newAdUrl","queuedUrlsPreview","generationDelay","stopContinuousFetching","backoffMultiplier","backoffDelay","effectiveMinInterval","timeSinceLastRequest","waitTime","handleAdPodComplete","tryNextAvailableAd","retryCount","nextAdUrl","errorMessage","maxRetries","playSingleAd","showPlaceholderAndWaitForAds","ap","playError","rejectLoadedAdForDuration","checkInterval","maxChecks"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBACIA,KAAWC,OAAOC,EAAAA,IAAM,gBAAA;oBACxBC,cAAAA,MAAYF,OAAOG,cAAc;gBACjCC,eAAmBJ,OAAOK,wBAAwB;YAClDC,kBAAoBN,OAAOO,mBAAmB;QAC9CC,EAAAA,OAAAA,MAAeR,CAAAA,MAAOS,cAAc;YACpCC,QAAAA,KAAeV,CAAAA,MAAOW,SAAS,CAACC,cAAc,WAAA;YAC9CC,OAAAA;gBAAW,MAAA;YAAA,IAACC,QAAQC;QACtB,IAAK,IAAIC,QAAQD,IACfb,UAAUY,QAAQE,MAAM;UAAEC,KAAKF,GAAG,CAACC,KAAK;UAAEE,GAAAA,SAAY,MAAA,SAAA;QAAK,IAAA;gBAE7C,0BACGC,sCAAAA,2BACZ,uCAAA;YAHT,IAAA,OAAA,UAAA,YAAA,CAAA,SAAA;YACIC,IAAAA,MAAc,EAAA,EAAA,2BAAA,UAAA,SAACC,IAAIF,CAAAA,KAAMG,mBAAX,+CAAA,yBAAWA,CAAQC,UAAAA,KAAAA;YACnC,EAAIJ,EAAAA,IAAQ,CAAA,OAAOA,IAAAA,4BAAAA,UAAAA,aAAAA,CAAAA,UAAP,mBAAOA,iDAAAA,uCAAAA,0BAAP,EAAOA,KAAG,IAAA,cAAHA,2DAAAA,qCAAS,IAAA,QAAY,OAAOA,SAAS,YAAY;gBAC7D,cAAA,4BAAA,UAAA,WAAA,EAAA,CAAA,6BAAA,iDAAA,wCAAA,0BAAA,OAAA,IAAA,cAAA,4DAAA,sCAAA,IAAA;;;0BAAA,IAAIK,MAAJ;0BACH,IAAI,CAACd,GAAAA,UAAae,IAAI,CAACJ,IAAIG,QAAQA,QAAQF,QACzCpB,UAAUmB,IAAIG,KAAK;8BAAEP,IAAAA,CAAK,SAALA,UAAAA;uDAAWE,IAAI,CAACK,IAAI;;0BAAEN,YAAY,CAAEK,CAAAA,OAAOnB,iBAAiBe,MAAMK,IAAG,KAAMD,KAAKL,UAAU;oBAAC,cAAA,SAAA,WAAA,MAAA,WAAA,GAAA,QAAA,CAAA,sBAAA,MAAA,WAAA,OAAA;;gBAFpH,QAAK,QAAA,IAAWZ,SAAAA,KAAAA,CAAAA,GAAkBa,0BAA7B,SAAA,6BAAA,QAAA,yBAAA;;gBAAA,oBAAA,UAAA,gBAAA,CAAA;gBAAA,aAAA,EAAA;;;;iDAAA,WAAA,qDAAA,eAAA,IAAA,OAAA,IAAA;0BAAA,EAAA,GAAA,YAAA,CAAA,YAAA;;;0BAAA,QAAA,GAAA,YAAA,CAAA;gCAAA,GAAA,cAAA,SAAA,aAAA,MAAA,KAAA;;;;oBAGP,OAAA,SAAA,SAAA,QAAA;oBACA,CAAOE,OAAAA,SAAAA,UAAAA,QAAAA;oBACT,SAAA,gBAAA,eAAA,IAAA,eAAA,KAAA;gBACIK,MAAU,iBAACC,KAAKC,YAAYd;mBAAYA,CAAAA,QAASa,OAAO,OAAO5B,OAAAA,EAASS,aAAamB,QAAQ,CAAC,GAAGP,QAAAA,IACnG,sEAAsE;oBACtE,WAAA,IAAA,CAAA,2CAAiE;gBACjE,kEAAsE;YACtE,mEAAqE;YACrEQ,IAAAA,QAAc,CAACD,EAAAA,KAAO,CAACA,IAAIE,CAAAA,GAAAA,MAAU,GAAG3B,UAAUY,QAAQ,WAAW;gBAAEgB,IAAAA,GAAOH,cAAAA;oBAAKT,QAAAA,EAAY,EAAA,CAAUJ,KACzGa;gBAEEI,OAAAA,IAAe,sBAACJ;qBAAQP,OAAAA,IAAAA,CAAYlB,UAAU,CAAC,GAAG,cAAc;gBAAE4B,OAAO;gBAASH,OAAAA;oBAAAA,MAAAA;gBAAAA;;YAEtF,OAAA,sBAAmC;gBC7BnCK,MAAAA,sBAAA,CAAA;gBAAAnB,CAAAmB,GAAAA,4BAAA;oBAAAC,IAAAA,sBAAA,SAAAA;gCAAAA;;oBAAA,YAAA;oBAAAC,IAAA,GAAAH,OAAAA,MAAAC,cAAAA;oBAAAG,cAAAA,SAA+DT,QAAAU,QAAA,UAAA;gBDqC/D,iBAAyB;YEpCzBC,WAAgBX,QAAAU,QAAA,WAAA;QA8CVE,EAAAA,OAAAA,OAAAA,SAAyB;YAExB,GAASC,KAAAA,KAAAA,CAAAA,OACdC,YAAA,EACAC,OAAA,qBAAA;YAMA,EAAIC,KAAAA;gBAAAA,KAAY,CAAA;YAAA;QAChB,IAAIC,qBAAqB;MACzB,IAAIC,iBAAiBC,KAAKC,GAAA,CAAI,GAAGD,KAAKE,GAAA,CAAI,GAAGP,aAAaQ,MAAA,IAAU;MACpE,IAAMC,GAAAA,GAAY,UAAA,GAAA,GAAA,IAAIC;YAAAA,cAAAA,iEAAAA;;gBAChBC,WAAaV,EASfW,UAGAC,OAAY;;;;wBAZVF,cAAaV,qBAAAA;mCAAAA,MAAAA,YAAAA,kBAAAA,QAASU,UAAA;gCAC5B,EAAMG,IAAAA,cAAkBb,oBAAAA,8BAAAA,QAASa,eAAA;gCAEjC,EAAIC,WAAAA;gCACJ,EAAIC,OAAAA;oCACAC,UAAAA;gCACJ,EAAIC;gCACJ,EAAIC,SAAmB,EAAC,GAAA;4BACxB,IAAIC,WAAW;;;;;;;;;;wBAGTC;;4BAAAA,CAAgB,WAAA,EAAA,GAAA,IAAIX;;;wBAA1B,EAAMW,SAAAA;;;;;;wBACFR;6BACAS,CAAAA,gBAA4B,EAAC,IAAA,GAA7BA;;;;wBAEAC,QAAAA,IAAAA,CACFC,GADkB,MACN,4CAAA,OAAA,aAAA,qCACZC,KAAO;wBAEG;;4BAAA,YAAA;;;wBAAVC,UAAU,CAAA;;;;;;wBAEVC,MAAAA,IAAU;;;;;;;4BAIV,CAAA,GAAMC,MAAMnB,EAAAA,EAAAA,MAAUhC,GAAA,CAAIoD;8BAC1B,IAAI,CAACD,GAAAA,EAAK,IAAA,yBAAA,OAAA,SAAA,UAAA;gCACV,kCAAA,2BAAA;;;;;;;kBAAA,QAAA,YAAiBE,MAAMnD,IAAA,CAAKiD,yBAA5B,SAAA,6BAAA,QAAA,yBAAA,iCAAkC;;aAAlC,GAAWG,EAAX,GAAA;4CAAA,UAAA;gBAAA,OAAA,2BACE;;;;;wBADF,QAAA,oEAAA,GAAA,sBAAA,oEAAA;wBACM;;4BAAA,2BACFA,GAAGC,KACL,EAAA,EAAA,KAASC,OAAO;;;;oCAKhB;gCACF,GAAA,6DATA,EAAA,SAAA,CAAA,GAAA;;;;;wCAAA,6BAAA;;wCAAA;;;4CAAA,gBAAA,4BAAA,OAAA,wBAAA;;;;;;4BAUF,kBAAA,qBAAA,OAAA,YAAA;4BAEA;;gCAASC,oBACP,OAAO,WAAyB7B,CAAAA,EAClC,IADoB8B,IACpB,CADyBC,EAGzB,CAHyB,IAAK,AAGrBC,KAHgE,OAAvChC,KAAKiC,EAGXC,IAHW,AAGX,GAHoBC,QAAA,CAAS,IAAIC,MAAA,CAAO,GAAG;;4BAMrEF,KAAKG,OAAA,CAAQ,SAACC;gCACZ,IAAI,MAAA,OAAA,EAAA,CAAA,YAAA,EAAA;;;iCACF,EAAA,EAAIC,cAAcD;;;;sBAElB,IAAI/B,WAAW;;gBACbgC,cAAc,GACZA,OADeA,aAEHhC,OADZgC,YAAYC,QAAA,CAAS,OAAO,MAAM,KACpC,eAAuB,OAATjC;;sBAChB,iBAMA,oBAwBA,IAAMkC,SAAQhC,gBAAgBiC,MAAA,CAAOC,UAAS,kCAC9C,OAAO,WACLC,AAKJ,GAAO,OASX;;;;wBA9CM;;4BAAA,aAAA;;;kCAAA;oCAEA,IAAItC,YAAY;kCACdiC,GAAAA,WAAc,GACZA,OADeA,aAEFjC,OADbiC,YAAYC,QAAA,CAAS,OAAO,MAAM,KACpC,gBAAyB,OAAVlC;iCACjB,OAAA,eAAA,CAAA,SAAA;oCAEA,IAAMuC,MAAM,EAAA,CAAA,CAAIC,MAAM,GAAG,MAAA;sCACzBD,GAAAA,CAAIE,GAAA,GAAMR;sCACVS,QAAQC,GAAA,CAAI,uCAAkD,OAAXV;;;;gCACrD,EAAA,OAASX,OAAO;8BACdoB,OAAAA,CAAQE,IAAA,CAAK,IAAA,CAAA,OAAA,gBAAA,CAAA,iBAA8CtB;gCAC7D,OAAA,MAAA,KAAA,GAAA;8BACF,MAAA,IAAA,CAAA;4BACF;;;;wBAEA,SAASuB;4BAKP,IAAI,CAAC1C,EAAAA,IAAAA,CAAAA,SAAAA,GAAAA,QAAmB,CAACA,gBAAgBiC,MAAA,EAAQ;gCAC/C,OAAO,SAAA,EAAA,YAAA,CAAA,eAAA,IAAA;8BACT,EAAA,OAAA,SAAA,EAAA,YAAA,CAAA,eAAA,IAAA;8BAEA,EAAMU,OAAAA,OAAAA,CAAe3C,OAAAA,CAAAA,QAAgB2C,OAAAA,KAAA,EAAA,gBAAA;8BACrC,EAAIA,OAAAA,OAAAA,GAAiB,CAAA,IAAA,CAAM,CAAC3C,OAAAA,OAAAA,EAAgBiC,KAAAA,CAAA,CAAOU,aAAY,CAAA,CAAG;kCAChE,CAAA,GAAMT,IAAAA,QAAYlC,gBAAgB4C,SAAA;gCAClC,IAAIV,cAAc,CAAA,KAAMlC,gBAAgBiC,MAAA,CAAOC,UAAS,EAAG;;;;;;;;;;;oCAElD;;;;;;;;iCACLC,MAAOH,OAAMG,EAAAA,GAAA,IAAS;wCACtBU,CAAAA,KAAAA,EAAQb,MAAAA,EAAMa,MAAA,IAAU;;;;oCACxBC,IAAAA,EAAAA,GAASd,OAAMc,OAAA,IAAW;;;;;;6BAC5B,CAAA,OAAA,IAAA,KAAA,SAAA,GAAA;;;;;;;;;;;;wBAEK;;4BAAA,oBACT,OAAA,YAAA,EAEMd,GACN,GAAO,EADOhC,EACP,YAAA,EADuBiC,MAAA,CAAOU,aAAY;;;wBAH/C,WAAO;0BAMPE,EAAAA,MAAQb,IAAAA,EAAMa,MAAA,IAAU;4BACxBC,IAAAA,IAAAA,CAASd,MAAMc,OAAA,IAAW;wBAC5B;;;;;;wBACF;wBAEA,GAASC,KAAAA,IAAAA,CACHC,UADuBA,CACZC,MAAA,GADY,EACD,GAAG,+BAC3B,MAAM,IAAIC,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAMlB,IAAA,GAAA,CAAA,wBAAA,OAAA,IAAA,MAAA,EAAA;4BAEA;;4BAAA,CAAIF,WAAWC,MAAA,KAAW,GAAG;;;;kBAC3B,OAAOE;;UACT,GAAA;YAEA,EAAMC,MAAAA,QAAcV,CAAAA,aAAAA,CAAAA;YACpB,EAAA,EAAI,CAACU,EAAAA,CAAAA,QAAAA,EAAa,CAAA;gBAChBb,GAAAA,CAAAA,IAAQC,GAAA,CACN;gBAEF,GAAA,CAAA,GAAOW,GAAAA;YACT,EAAA,KAAA,CAAA,KAAA,GAAA;YAEAZ,EAAAA,KAAAA,CAAQC,GAAA,CAAI,EAAA,GAAA,iCAAsCY;YAElD,EAAA,EAAMC,GAAAA,CAAAA,SAAAA,CAAcL,EAAAA,SAAWM,GAAA,CAAI,SAACC;gBAClC,GAAA,CAAMC,YAAYjE,GAAAA,EAAKkE,CAAAA,EAAA,CAAIF,KAAKpB,KAAA,GAAQiB,YAAYjB,KAAK;gBACzD,IAAMuB,KAAAA,GAAAA,KAAanE,KAAKkE,GAAA,CAAIF,KAAKV,MAAA,GAASO,YAAYP,MAAM;gBAC5D,GAAA,CAAMc,EAAAA,eAAiBH,YAAYE;gBAEnC,IAAME,GAAAA,WAAA,AAAeL,CAAAA,KAAKT,OAAA,IAAW,GAAA,IAAQ;gBAC7C,GAAA,CAAMe,KAEN,IAAMC,KAFcvE,GAENoE,EAFWF,GAAA,CAAIG,WAEE,GAFYR,CAERS,WAFoBf,GAEN,EAAA,EAFa,KAEb,MAAA,MAAA;oBAExCS,MAAAA;kBAAMO,OAAAA;kBAAOH,gBAAAA;oBAAgBE,WAAAA,CAAAA,CAAAA,UAAAA;gBAAY,OAAA,gBAAA,CAAA,cAAA;cACpD,EAAA,CAAA,aAAA,CAAA,gBAAA;cAEAR,EAAAA,QAAYU,GAAAA,CAAA,CAAK,SAACC,GAAGC,CAAAA,WAAAA,GAAAA,UAAAA,QAAAA;yBAAMD,EAAEF,CAAAA,IAAA,GAAQG,CAAAA,CAAEH,KAAK,SAAA,aAAA,EAAA;;gBAE5C,IAAMI,YAAYb,GAAAA,QAAA,CAAY,CAAA,CAAC,WAAA,CAAA,aAAA;cAC/B,IAAI,CAACa,WAAW;kBACd3B,QAAQC,EAAAA,CAAA,CAAI,KAAA,CAAA,cAAA,QAAA,EAAA;oBACZ,OAAOW,GAAAA,QAAAA,GAAAA;gBACT,mBAAA,UAAA,YAAA,CAAA,QAAA;cAEAZ,QAAQC,GAAA,CAAI,sCAAsC;kBAChDX,KAAKqC,KAAAA,KAAUX,GAAAA,CAAA,CAAK1B,GAAA,UAAA,aAAA,EAAA;oBACpBsC,UAAAA,EAAY,GAA2BD,OAAxBA,CAAAA,GAAAA,MAAUX,IAAA,CAAKpB,KAAK,EAAA,KAAyB,OAArB+B,UAAUX,IAAA,CAAKV,MAAM;oBAC5DC,SAASoB,MAAAA,IAAUX,IAAA,CAAKT,CAAAA,MAAA,MAAA,CAAA,aAAA;kBACxBgB,OAAOI,UAAUJ,KAAA;gBACjBH,gBAAgBO,UAAUP,cAAA;gBAC1BE,OAAAA,MAAaK,UAAUL,CAAAA,UAAA,CAAA;cACzB,EAAA,CAAA,aAAA,cAAA,KAAA,EAAA;cAEA,OAAOK,KAAAA,KAAUX,GAAAA,CAAA;YACnB,mBAAA,UAAA,YAAA,CAAA,KAAA;YAEA,OAASa,CAAAA,GAAAA,CAAAA,UAAeC,SAAA;YACtB,IAAMC,OAAOD,UAAUC,IAAA,CAAKC,WAAA;YAC5B,IAAM1C,MAAMwC,CAAAA,SAAUxC,GAAA,CAAI0C,GAAAA,CAAAA,OAAA,EAAA;cAC1B,EAAA,CAAA,IACED,SAAS,cAAA,QAAA,EAAA,GACTA,SAAS,mCACTA,KAAKvC,QAAA,CAAS,cACdF,IAAIE,QAAA,CAAS;YAEjB,cAAA,QAAA,GAAA;YAEA,OAASyC,YAAAA,UAAAA,CAAuBH,SAAA,EAAA,CAAA,QAAA;cAC9B,IAAMC,EAAAA,GAAAA,CAAAA,CAAOD,UAAUC,IAAA,CAAKC,WAAA;cAC5B,EAAA,EAAM1C,MAAMwC,GAAAA,OAAUxC,GAAA,CAAI0C,EAAAA,GAAAA,KAAAA,CAAA,qBAAA;gBAC1B,OACED,KAAKG,UAAA,CAAW,aAChB5C,IAAI6C,QAAA,CAAS,WACb7C,IAAIE,QAAA,CAAS;YAEjB;YAEA,OAAS4C;YACP,OAAO;gBACLjE,OAAAA,KAAY,EAAC,SAAA,CAAA,SAAA,SAAA;kBACbC,OAAO,EAAC,CAAA;kBACRiE,EAAAA,KAAAA,CAAAA,OAAe,EAAC,wBAAA;kBAChBhE,SAAAA,CAAU,EAAC;oBACXiE,eAAe,EAAC,QAAA,YAAA,CAAA,KAAA;kBAChBhE,UAAU,EAAC;kBACXiE,MAAM,EAAC,CAAA,OAAA,MAAA,GAAA,KAAA,sBAAA;oBACPC,QAAQ,EAAC;kBACTC,OAAO,EAAC;kBACRC,QAAQ,EAAC;gBACTC,YAAY,EAAC;gBACbC,OAAAA,SAAgB,EAAC,KAAA,CAAA,gBAAA;kBACjBC,MAAM,EAAC,EAAA;kBACPjE,OAAO,EAAC,IAAA,KAAA,EAAA;gBACV,mBAAA,UAAA,YAAA,CAAA,IAAA;YACF,OAAA;gBAEA,KAASkE,cAAAA,MAAoBC,IAAAA,CAAA,WAAA,CAAA,MAAA;cAC3B,IAAMC,eAAeZ;YAErBW,MAAME,gBAAA,CAAiB,cAAc5D,OAAA,CAAQ,SAAC6D;oBAChCA,GAAAA,gBAAAA,CAAAA,SAAAA;kBAAZ,IAAM5D,OAAM4D,CAAAA,eAAAA,EAAAA,GAAGC,EAAAA,SAAA,cAAHD,sCAAAA,gBAAgBE,IAAA;oBAC5B,IAAI9D,KAAK0D,MAAAA,OAAa7E,GAAAA,OAAA,CAAWkF,IAAA,CAAK/D,KAAAA;cACxC;YAEAyD,MAAME,gBAAA,CAAiB,YAAY5D,OAAA,CAAQ,SAAC6D;oBAE9BA,GAAAA,gBAAAA,CAAAA,QAAAA;kBADZ,IAAM1E,OAAAA,CAAQ0E,GAAGI,WAAAA,CAAA,CAAa,SAAA,GAAA,GAAA;oBAC9B,IAAMhE,OAAM4D,IAAAA,UAAAA,IAAAA,GAAGC,KAAAA,CAAAA,KAAA,CAAA,aAAHD,sCAAAA,gBAAgBE,IAAA;kBAC5B,IAAI5E,SAASc,KAAK;oBAChB,IAAMiE,WAAW/E;kBACjB,IAAIwE,YAAA,CAAaO,SAAQ,EAAG;sBAC1BP,QAAAA,IAAA,CAAaO,IAAAA,KAAQ,CAAEF,IAAA,CAAK/D;oBAC9B,GAAA;kBACF,OAAA,OAAA,CAAA,mBAAA,GAAA;YACF,GAAA;cAEAyD,KAAAA,CAAME,YAAAA,IAAA,CAAiB,EAAA,CAAA,MAAS5D,OAAA,CAAQ,KAAA,IAAC6D;oBAC3BA;cAAZ,IAAM5D,OAAM4D,kBAAAA,GAAGC,WAAA,cAAHD,sCAAAA,gBAAgBE,IAAA;cAC5B,IAAI9D,KAAK0D,YAAAA,CAAapE,KAAA,CAAMyE,IAAA,CAAK/D,MAAAA;YACnC,YAAA;cAEA,OAAO0D,GAAAA,qBAAAA,cAAAA,UAAAA,GAAAA;YACT,OAAA;YAEA,OAASQ,QAAAA,UACPvI,MAAA,EACAwI,MAAA;cAECtJ,OAAOuJ,CAAAA,GAAA,CAAKzI,QAA0CoE,OAAA,CAAQ,SAAC1D;kBAC9D,IAAI8H,KAAAA,CAAA,CAAO9H,IAAG,IAAK8H,MAAA,CAAO9H,IAAG,CAAE+E,MAAA,GAAS,GAAG;sBACzCzF,MAAA,CAAOU,IAAG,GAAIV,MAAA,CAAOU,IAAG,CAAEgI,MAAA,CAAOF,MAAA,CAAO9H,IAAI;gBAC9C;UACF;UACA,GAAA,IAAOV;QACT,IAAA,CAAA,kBAAA,CAAA,WAAA;YAEA,MAAA,CAAS2I,GAAAA,MAAAA,IAAaC,SAAA;YACpB,IAAI;kBAoBYC,MAAAA,iBAEOA,GAAAA,UAAAA,UAAAA,YAAAA,wBAIFA,oCAAAA,wBAqBjBA;gBA9CF,IAAMC,IAAAA,KAAS,IAAIC;kBACnB,IAAMF,MAAAA,GAASC,OAAOE,eAAA,CAAgBJ,WAAW;gBAEjD,IAAMK,cAAcJ,OAAOK,aAAA,CAAc;cACzC,IAAID,IAAAA,SAAa,MAAA;oBACflE,QAAQpB,CAIR,IAJQ,CACN,EAGK,SAAA,OAAA,UAAA,QAAA,eAAA,MAFLsF,OAEK,KAFOf,EAEP,SAFO,EAEP,GAAA,KAAA,OAAA,OAAA,MAAA,IAAA,GAAA,YAAA,OAAA,UAAA,GAAA;oBAAgB,GAAA,WAAA,OAAA,CAAA,WAAA,IAAA;kBACzB,KAAA;oBAEA,EAAA,EAAMiB,KAAAA,OAAYN,OAAOK,aAAA,CAAc;kBACvC,IAAI,CAACC,WAAW;sBACdpE,EAAAA,MAAQE,IAAA,CAAK,OAAA,CAAA;wBACb,MAAA,CAAO;4BAAE6B,IAAAA,EAAM;sBAAQ;kBACzB,UAAA,CAAA,UAAA,GAAA;kBAEA,IAAMsC,OAAOD,CAAAA,SAAUd,YAAA,CAAa,SAAS;kBAC7C,EAAA,CAAA,CAAMgB,QAAQR,EAAAA,OAAAA,CAAAA,MAAAA,CAAAA,SAAAA,MAAAA,CAAOK,CAAAA,YAAA,CAAc,wBAArBL,4CAAAA,sBAAiCX,WAAA,KAAe;oBAE9D,IAAMoB,GAAAA,CAAAA,YAAeT,yBAAAA,OAClBK,aAAA,CAAc,6BADIL,8CAAAA,oCAAAA,uBAEjBX,WAAA,cAFiBW,wDAAAA,kCAEJV,IAAA;oBAEjB,IAAMoB,OAAAA,IAAAA,GAAaV,KAAAA,CAAAA,SAAAA,kBAAAA,OAChBK,aAAA,CAAc,6BADEL,8CAAAA,qCAAAA,uBAEfX,WAAA,cAFeW,yDAAAA,mCAEFV,IAAA;sBACjB,IAAIoB,EAAAA,KAAAA,CAAAA,IAAY,yCAAA;0BACdxE,QAAQC,GAAA,CACN,gEAA0E,OAAVuE;wBAElE,OAAO;0BACLzC,MAAM;0BACN0C,MAAAA,OAAAA,CAAcD,MAAAA,CAAAA,KAAAA,EAAAA,SAAAA,QAAAA;4BACdxB,CAAAA,CAAAA,YAAcF,gBAAAA,IAAoBgB;4BAClCS,EAAAA,EAAAA,UAAAA;0BACF;oBACF;kBAEA,IAAMG,kBACJL,SAAS,WACTC,MAAMtC,WAAA,GAAcxC,QAAA,CAAS,sBAC7B8E,MAAMtC,WAAA,OAAkB;gBAE1B,GAAA,CAAM2C,UAAAA,KACJb,EAAAA,QAAAA,WAAAA,CAAAA,KAAAA,OAAOK,aAAA,CAAc,QAAA,iBAArBL,6CAAAA,uBAAkCX,WAAA,KAAe;kBACnD,IAAMyB,KAAAA,GAAAA,GAAAA,KAAgBD,KAAAA,GAAAA,KAAaE,KAAA,CAAM;kBACzC,IAAMC,KAAAA,IAAAA,EACJC,CAAAA,KAAAA,CAAAA,SAAAA,CAASH,aAAA,CAAc,EAAC,IAAK,KAAK,MAAM,OACxCG,SAASH,aAAA,CAAc,EAAC,IAAK,KAAK,MAAM,KACxCG,SAASH,aAAA,CAAc,EAAC,IAAK,KAAK;oBAEpC,IAAMI,KAAAA,CAAAA,cAAoBlB,OAAOb,gBAAA,CAAiB,OAAA;oBAClD,IAAMxC,aAA8B,EAAC;kBAErCT,QAAQC,GAAA,CACN,uBAA+C,OAAxB+E,kBAAkBtE,MAAM,EAAA;gBAGjDsE,GAAAA,CAAAA,WAAAA,GAAkB3F,OAAA,CAAQ,SAAC4F,GAAAA,CAAIC,WAAAA;0BAEjBD;wBADZ,IAAMlD,CAAAA,MAAOkD,GAAG3B,YAAA,CAAa,WAAW;wBACxC,IAAMhE,CAAAA,KAAM2F,EAAAA,kBAAAA,GAAG9B,WAAA,cAAH8B,sCAAAA,gBAAgB7B,IAAA,OAAU;sBACtC,IAAMxD,QAAQqF,GAAG3B,YAAA,CAAa,YAAY;sBAC1C,IAAMhD,CAAAA,GAAAA,GAAAA,EAAS2E,GAAG3B,KAAAA,GAAAA,IAAA,CAAa,aAAa;sBAE5CtD,KAAAA,GAAQC,CAAAA,EAAA,CACN,2BAA2C8B,OAAhBmD,OAAK,YAA0B5F,OAAfyC,MAAI,YAA2BnC,OAAhBN,KAAG,cAAgCgB,OAAnBV,OAAK,eAAoB,OAANU,QAAM;sBAGrG,IAAMwB,CAAAA,IAAAA,GAAAA,IAA2B,CAAA,CAAA,SAAA;4BAC/BxC,CAAAA,CAAAA,GAAAA,sDAAAA;4BACAyC,MAAAA;0BACAnC,OAAOmF,SAASnF,SAAS,QAAQ;wBACjCU,QAAQyE,SAASzE,UAAU,QAAQ;0BACnCC,EAAAA,MAAS,KAAA,wBAAA,OAAA,UAAA,IAAA;oBACX;kBAEA,IAAI,CAACjB,KAAK;sBACRU,QAAQE,IAAA,CAAK,2BAAgC,OAALgF,OAAK;wBAC7C,OAAA,MAAA,GAAA,GAAA;sBACF;oBAEA,IAAMC,cAAcF,GAAG3B,YAAA,CAAa;oBACpC,IAAM8B,eAAeD,cACjBJ,SAASI,aAAa,MACtB,KAAA;oBACJrD,MAAAA,CAAAA,GAAUvB,MAAAA,CAAA,GACR6E,gBAAgBA,eAAe,IAAIA,eAAe,KAAA;oBAEpD,IAAIvD,MAAAA,SAAeC,cAAcG,uBAAuBH,YAAY;wBAClErB,WAAW4C,IAAA,CAAKvB;0BAChB9B,KAAAA,GAAQC,GAAA,CACN,GAAA,YAAA,CAAA,OAAuFX,GAAAA,IAAhEuC,eAAeC,aAAa,QAAQ,eAAa,gBAAkB,OAAHxC;sBAE3F,IAAA,GAAO,OAAA,GAAA;0BACLU,KAGF,GAHUC,GAAA,CACN,2BAAmD8B,EAEvD,KAF+BmD,EAE/B,KAFoC,MAEpC,GAAA,KAAA,MAF2D,CAE3D,MAFuDnD,CAEvD,KAF2D,CAE3D,EAAA,OAAA,OAAA,UAAA,KAAA,EAAA,gBAAA,OAAA,UAAA,QAAA,EAAA;gBAGF,IAAItB,WAAWC,MAAA,KAAW,GAAG;oBAC3B,IAAIgE,iBAAiB;0BACnB1E,QAAQE,IAAA,CACN;sBAEJ,OAAO,MAAA;gBAAA,OAAA;gBAAA,OAAA,OAAA,MAAA;YAAA;0BACLF,QAAQE,IAAA,CAAK;oBACf,IAAA;sBACA,GAAA,CAAA,GAAO,0CAAA;0BAAE6B,MAAM;oBAAQ;cACzB;cAEA,OAAO;oBACLA,MAAM;oBACNsD,IAAI;wBACFC,CAAAA,GAAIjB;wBACJC,EAAAA,GAAAA,EAAAA;wBACAQ,GAAAA,OAAAA;0BACArE,KAAAA,CAAAA,MAAAA,CAAAA,GAAAA;0BACAuC,KAAAA,CAAAA,QAAcF,KAAAA,GAAAA,YAAoBgB;wBAClCS,cAAAA;sEACF,2BAAA,EAAA;kBACF,WAAA,MAAA,EAAA;gBACF,EAAA,MAAA,CAAS3F,EAAAA,CAAAA,IAAO;oBACdoB,QAAQpB,CAAAA,IAAA,CAAM,EAAA,KAAA,CAAA,gBACd,OAAO,UADgDA;sBAC9CmD,MAAM;oBAAQ,IAAA,GAAA,CAAA;cACzB;QACF;QAEA,KAAA,IAASwD,eAAenB,SAAA;UACtB,IAAI;kBAEYA,0BAEOA,sCAAAA,2BAIFA,uCAAAA,2BAkBjBA;gBAzBF,GAAA,CAAMC,OAAOD,UAAUd,YAAA,CAAa,SAAS;gBAC7C,IAAMgB,QAAQF,EAAAA,2BAAAA,UAAUD,aAAA,CAAc,wBAAxBC,+CAAAA,yBAAoCjB,WAAA,KAAe;gBAEjE,IAAMoB,KAAAA,WAAeH,4BAAAA,UAClBD,aAAA,CAAc,6BADIC,iDAAAA,uCAAAA,0BAEjBjB,WAAA,cAFiBiB,2DAAAA,qCAEJhB,IAAA;gBAEjB,IAAMoB,CAAAA,KAAAA,GAAAA,KAAaJ,4BAAAA,UAChBD,aAAA,CAAc,6BADEC,iDAAAA,wCAAAA,0BAEfjB,WAAA,cAFeiB,4DAAAA,sCAEFhB,IAAA;gBACjB,IAAIoB,OAAAA,KAAY;sBACd,IAAA,GAAO,EAAA,CAAA,OAAA,GAAA;0BACLzC,KAAAA,CAAM,aAAA,GAAA;wBACN0C,cAAcD;wBACdxB,cAAcF,oBAAoBsB;sBAClCG,cAAAA;kBACF;qCACF;kBAEA,EAAA,EAAMG,CAAAA,CAAAA,gBACJL,SAAS,WACTC,MAAMtC,WAAA,GAAcxC,QAAA,CAAS,sBAC7B8E,MAAMtC,WAAA,OAAkB;kBAE1B,IAAM2C,UAAAA,KACJP,EAAAA,4BAAAA,UAAUD,aAAA,CAAc,yBAAxBC,gDAAAA,0BAAqCjB,WAAA,KAAe;4BAmBpD,IAAMiC;oBAlBR,EAAMR,UAAAA,MAAgBD,GAAAA,UAAaE,GAAAA,CAAAA,CAAA,CAAM;oBACzC,IAAMC,EAAAA,KAAAA,CAAAA,GACJC,KAAAA,GAAAA,CAASH,aAAA,CAAc,EAAC,IAAK,KAAK,MAAM,OACxCG,SAASH,aAAA,CAAc,EAAC,IAAK,KAAK,MAAM,KACxCG,SAASH,aAAA,CAAc,EAAC,IAAK,KAAK;oBAEpC,IAAMI,EAAAA,KAAAA,CAAAA,IAAAA,GAAAA,KAAoBZ,UAAUnB,gBAAA,CAAiB;oBACrD,IAAMxC,EAAAA,KAAAA,CAAAA,GAAAA,EAA8B,CAAA,CAAC;oBAErCuE,MAAAA,KAAAA,CAAAA,KAAAA,CAAkB3F,EAAAA,KAAA,CAAQ,SAAC4F;4BAEbA,GAAAA,CAAAA,MAAAA,GAAAA;wBADZ,EAAA,EAAMlD,GAAAA,CAAAA,GAAOkD,GAAG3B,CAAAA,GAAAA,QAAA,CAAa,WAAW;wBACxC,EAAA,EAAMhE,GAAAA,CAAAA,EAAM2F,EAAAA,MAAAA,GAAAA,SAAAA,GAAG9B,WAAA,cAAH8B,sCAAAA,gBAAgB7B,IAAA,OAAU;wBACtC,EAAA,EAAMxD,GAAAA,CAAAA,IAAQqF,GAAG3B,OAAAA,GAAAA,EAAA,CAAa,YAAY;wBAC1C,EAAA,EAAMhD,GAAAA,CAAAA,KAAS2E,GAAG3B,KAAAA,GAAAA,IAAA,CAAa,aAAa;wBAE5C,EAAA,EAAI,CAAChE,EAAAA,CAAAA,EAAK,IAAA,GAAA;wBAEV,EAAA,EAAM6F,GAAAA,CAAAA,UAAcF,GAAG3B,EAAAA,GAAAA,OAAA,CAAa;4DAC9B8B,aAAAA,CAAeD,2FAAAA,WAAAA,CAAAA,CAAcJ,SAASI,aAAa,MAAM,KAAA;wBAE/D,IAAMrD,IAAAA,QAA2B;0BAC/BxC,KAAAA;wBACAyC,MAAAA;uCACAnC,CAAAA,MAAOmF,IAAAA,KAASnF,SAAS,QAAQ;;;;;;0CACjCU,QAAQyE,SAASzE,UAAU,IAAA,IAAQ;0CACnCC,CAAAA,QAAS6E,gBAAgBA,eAAe,IAAIA,eAAe,KAAA;wCAC7D,IAAA,OAEA,IAAIvD,eAAeC,cAAcG,uBAAuBH,YAAY;;;qCAEpE,OAAA,MAAA,CAAA,IAAA,MAAA;;kCACF;;;;;;;;;oCAGE,IAAI4C,iBAAiB;oCACnB1E,QAAQE,IAAA,CACN;qCAEJ,OAAO,EAAA,GAAA,CAAA;;;;gCACLF,QAAQE,IAAA,CAAK,QAAA,GAAA,CAAA;kCACf,OAAA,MAAA,CAAA;kCACA,OAAO,EAAA;;qCAAE6B,MAAM;;kCAAQ;8BACzB,MAAA,GAAA,CAEA,OAAO,6CACLA,MAAM;;;;;;;;gCAGJuC,KAAAA,YAAAA;;;sCAAAA;;;wCAEA7D,GAAAA,EAAAA,OAAAA;0CACAuC,EAAAA,CAAAA,WAAcF,oBAAoBsB;0CAClCG,cAAAA;sCACF;;oCAAA,QAAA,MAAA,CAAA,IAAA,MAAA;;gCACF;4BACF,EAAA,OAAS3F,OAAO;gCACdoB,OAAAA,CAAQpB,KAAA,CAAM,iDAAiDA;gCAC/D,OAAO,CAAA,GAAA,CAAA,EAAA;oCAAEmD,GAAAA,EAAc,CAAR,kCAAQ,IAAA,MAAA,EAAA,0BAAA,sBAAA,gCAAA,UAAA,KAAA,EAAA,gBAAA,OAAA,sBAAA,gCAAA,UAAA,QAAA,EAAA;4BAE3B,IAAA,WAAA;gCAEA,GAAeyD,aACbC,GAAAA,OAAA,GAAA,YAAA,CAAA,UAAA;kCACAC,YAAAA,EAAAA,QAAAA,GAAAA,sDAAkC;;;;iCAE5BC,OAAAA,MAUFC,CAAAA,SAGKhH;;;;;;;;yCAbH+G,KAAAA,CAAAA,QAAc,qBAACE;;;;;;;;wCAEjBC,MAAM;;6CACNJ,aAAaG;;8BASJ;;8CARTE,SAAS;oDACP,OACF,GADY;;;yCAGd,CAAA,CAAA,IAAA,MAAA;;;;;;;;;;;wCAIW,aAAA,MAAA;oEAAMJ,YAAYD;0FAA7BE,WAAW,cAAA,GAAA;;;;;;wCACJhH;6CACH8G,CAAAA,gBAAgB,MAAA,GAAhBA;;;;0CACF1F,CAAAA,MAAAA,CAAQE,EAAAA,EAAA,CACN,EAAA,GAAA,CAAA,GAAA,KAAA,GAAA,CAAA,GAAA,gCAAgE,OAAXwF,aAAW,qCAChE9G;0CAES,CAAA,KAAA,GAAA;uDAAM+G,YAAY,aAAA,OAAA,eAAA,MAAA,EAAA,aAAA,OAAA,eAAA,KAAA,EAAA,0BAAA,OAAA,oBAAA,qBAAA,OAAA;;wCAA7BC,GAAAA,QAAW;;;;;;;;qCAEX,MAAMhH;;;;;;;;;;;;;;;;4CAIV,IAAI,CAACgH,SAASI,EAAA,EAAI;kCAChB,MAAM,IAAIrF,GAAAA,GAAM,yBAA4C,OAAnBiF,SAASK,UAAU;gCAC9D;8BACA;;oCAAOL,EAAAA,CAAAA,MAASM,IAAA,KAAA,MAAA,EAAA;;;;gBAClB,QAAA,IAAA,CAAA,mCAAA;;QAEA,SAAeC;iEACbV,UAAA;sBACAW,OACAC,CAAAA,CAAAA,gBAAAA,GAEMC,SAUAC;;;;;kCAbNH,CAAAA,IAAAA,GAAAA,KAAAA,CAAAA,0BAGgB,oCAHR,GACRC,sBAAAA,oEAAwCjE;;kCAElBoD,aACpBC,YACAW,UAAU,IAAI,YAAY;;;4BAFtBE,UAAU;qCAIhBtG,QAAQC,GAAA,CAAI;;oCASV;;sCARFD,QAAQC,GAAA,CACN,sDACAqG,QAAQE,SAAA,CAAU,GAAG;sCAGjBD,SAAS3C,aAAa0C;sCAE5B,IAAIC,OAAOxE,IAAA,KAAS,SAAS;yCAC3B,aAAA,KAAA;;8CAAO,CAAA,GAAA,CAAA,GAAA,KAAA,GAAA,CAAA,GAAA;+CACT,+BAAA,OAAA,oBAAA,QAAA,OAAA,oBAAA,cAAA,OAAA,aAAA,MAAA;0CAGE,IAAIqE,SAAS3J,wBAAwB;gDACnCuD,GAAAA,GAAAA,EAAQE,IAAA,CACN,2CAAiE,OAAtBzD,wBAAsB;gDAEnE,SAAA,GAAA;;kDAAO,EAAA;;2FACT,kBAAA,EAAA;4CAEA+G,GAAAA,EAAAA,aAAkB6C,qBAAqBE,OAAOvD,YAAY;8CAC1D;wFAAOmD,oBACLI,OAAO9B,YAAA,EACP2B,QAAQ,GACRC;;sCAEJ;sCAEA7C,kBAAkB+C,OAAOlB,EAAA,CAAGrC,YAAA,EAAcqD;wCAC1C;;0CAAOE,OAAOlB,EAAA;;;;sBAChB;;oBAEA,OAAeoB,iBAAiBhB,UAAA;;;;;;wBACxBa,SAGAvC,QACAD,QAOA4C,YAcAC,KACN,2BAAA,mBAAA,gBAAA,WAAA,OAAWvC,WACHmC,QAMIK,UAQChI;;;;;;;oCAzCG,4IAAA;+BAAA;;sCAAM4G,aAAaC;;;;;;;;;;;;;;;;;8BAA7Ba,UAAU;8BAChBtG,GAAAA,KAAQC,GAAA,CAAI;8BAEN8D,CAAAA,GAAAA,KAAS,GAAA,CAAIC,GAAAA,KAAAA,GAAAA,CAAAA,GAAAA;8BACbF,SAASC,OAAOE,eAAA,CAAgBqC,SAAS;gCAE/C,IAAIxC,OAAOK,aAAA,CAAc,gBAAgB;oCACvCnE,QAAQpB,KAAA,CAAM;kCACd;;;;gCACF,KAAA;gCAEM8H,CAAAA,KAAAA,OAAajI,MAAMnD,IAAA,CAAKwI,OAAOb,gBAAA,CAAiB;8BACtD,IAAIyD,WAAWhG,MAAA,KAAW,GAAG;+FAC3BV,QAAQE,EAAAA,EAAA,CAAK;oCACb,OAAA,CAAA,WAAA,CAAA;;;;8BACF;8BAEAwG,WAAWlF,IAAA,CAAK,SAACC,GAAGC;kCAClB,IAAMmF,OAAO9B,SAAStD,EAAE6B,YAAA,CAAa,eAAe,IAAI;kCACxD,IAAMwD,OAAO/B,SAASrD,EAAE4B,YAAA,CAAa,eAAe,IAAI;kCACxD,IAAMyD,OAAOC,OAAOC,QAAA,CAASJ,QAAQA,OAAOG,OAAOE,gBAAA;gCACnD,IAAMC,OAAOH,OAAOC,QAAA,CAASH,QAAQA,OAAOE,OAAOE,gBAAA;sDACnD,OAAOH,OAAOI;8BAChB;4BAEMR;6CACN,kCAAA,2BAAA;;;;;;;;;8BAAA,YAAwBD;;;qCAAxB,EAAA,UAAA,GAAA,CAAA,OAAA,MAAA,OAAA,CAAA,EAAA,IAAA;;;;;gDAAWtC,oEAAAA,MAAAA,CAAAA,CAAX;4BACQmC,SAAShB,eAAenB;oEAE1BmC,CAAAA,IAAAA,EAAAA,CAAOxE,IAAA,CAAA,IAAS,QAAA,GAAhBwE;;;;;;;;iCAEOA,CAAAA,OAAOxE,IAAA,KAAS,SAAA,GAAhBwE;;;;;;;;;;;;8BAEU,IAAA,WAAA;;kCAAMJ,oBACrBI,OAAO9B,YAAA,EACP,GACA8B,OAAOvD,YAAA;;;sDAHH4D,WAAW;8BAKjB,CAAA,GAAIA,IAAAA,GAAAA,GAAU;kCACZD,IAAItD,GAAAA,CAAA,CAAKuD,CAAAA;8BACX,EAAA;;;;;;;gCACOhI,MAAAA,GAAAA;gCACPoB,OAAAA,CAAQE,EAAAA,EAAA,CACN,wDACAtB;;;;;;+DAlBR,UAAA,4FAAA,WAAA,CAAA;;;;;;;;;;;;8BAAA;8BAAA;;;;;;;qCAAA,6BAAA;4DAAA;;;oCAAA;4CAAA;;;;;;4BAwBAoB,QAAQC,GAAA,CAAI,wBAAkC,OAAV0G,IAAIjG,MAAM,EAAA;0BAC9C;;;;;QACF;;QAES0G;MAAT,EAAA,OAASA,WAAAA,iBAAAA,eAAAA,OAAAA,IAAAA,cAAAA,mCAAAA,aAAAA,GAAAA,GAAAA;YACP,GAAA,CAAMC,OAAAA,CAAQC,MAAAA,GAASC,aAAA,CAAc;UACrCF,MAAMG,KAAA,CAAMC,QAAA,GAAW;UACvBJ,MAAMG,KAAA,CAAME,GAAAA,CAAA,GAAO,GAAA;UACnBL,MAAMG,KAAA,CAAMG,GAAA,CAAA,EAAM,MAAA,SAAA,SAAA;YAClBN,IAAMG,KAAA,CAAM5H,CAAAA,IAAA,GAAQ,EAAA,aAAA,GACpByH,MAAMG,KAAA,CAAMlH,MAAA,GAAS;YAErB+G,MAAMG,IAAAA,CAAA,CAAMI,eAAA,GAAkB;gBAC9BP,IAAMQ;cAANR,GAAAA,eAAAA,OAAMQ,IAAAA,cAANR,mCAAAA,aAAMQ,EAAA,CAAA,EAAc;gBACpBR,MAAMS,KAAA,GAAQ;gBAEdT,MAAMlK,MAAA,GAAS;cACf6C,QAAQC,GAAA,CACN,sDAAkE,OAAZoH,MAAMlK,MAAM;cAGpE,EAAA,GAAOkK,OAAAA,WACT;uBAAA,OAAA,IAAA,MAAA;eAEA,KAASU;cAGPrK,OAAAA,QAAesK,QAAAA,CAAAA,OAAA,CAAiB,cAAc;oBAC5C,IAAI,CAACnK,IAAAA,SAAa,CAACH,gBAAgB;oBAEnC,IAAMuK,WAAWvK,eAAewK,WAAA,GAAcrK,UAAUiH,QAAA;kBAExD,IAAImD,YAAY,QAAQ,CAAC/J,cAAcmE,aAAA,EAAe;sBACpDnE,cAAcmE,CAAAA,CAAAA,SAAAA,EAAA,GAAgB;wBAC9BrD,KAAAA,cAAmBnB,UAAUmF,YAAA,CAAaX,aAAa;oBACzD,GAAA,IAAA,MAAA;kBAEA,IAAI4F,YAAY,OAAO,CAAC/J,cAAcG,QAAA,EAAU;sBAC9CH,cAAcG,QAAA,GAAW;oBACzBW,mBAAmBnB,UAAUmF,YAAA,CAAa3E,QAAQ;cACpD,OAAA,SAAA,aAAA,CAAA;gBAEA,EAAA,EAAI4J,CAAAA,WAAY,QAAQ,CAAC/J,cAAcoE,aAAA,EAAe;oBACpDpE,GAAAA,WAAcoE,aAAA,GAAgB;oBAC9BtD,OAAAA,CAAAA,WAAmBnB,CAAAA,SAAUmF,YAAA,CAAaV,aAAa;gBACzD,KAAA,GAAA;mBAAA;;YACF,GAAA,OAAA,GAAA;mBAAA,OAAA,IAAA,MAAA;;YAEA5E,KAAAA,IAAAA,CAAAA,KAAesK,MAAAA,CAAAA,SAAA,CAAiB,WAAW;cACzC,IAAI,CAACnK,aAAaK,cAAcE,KAAA,EAAO;cACvCF,cAAcE,KAAA,GAAQ;YACtBY,mBAAmBnB,UAAUmF,YAAA,CAAa5E,KAAK;YAC/C4B,QAAQC,GAAA,CAAI;UACd,YAAA,OAAA;QAEAvC,OAAAA,OAAAA,CAAesK,GAAAA,aAAA,CAAiB,SAAS;YACvC,IAAI,CAACnK,SAAAA,IAAaK,KAAAA,GAAAA,CAAAA,KAAcI,QAAA,EAAU;cAC1CJ,MAAAA,QAAcI,IAAAA,GAAAA,CAAA,GAAW;cACzBU,KAAAA,IAAAA,KAAAA,GAAAA,CAAAA,CAAmBnB,UAAUmF,CAAAA,WAAA,CAAa1E,QAAQ;cAClD0B,QAAQC,GAAA,CAAI;YAEZ,IAAIlC,WAAWD,OAAO4C,MAAA,GAAS,KAAKyH,sBAAsB;gBACxD;cACF,SAAA;cAEAC;UACF,CAAA;QAEA1K,aAAesK,MAAftK,KAAAA;;oBAAesK,SAOElK,yBACb,0BACF,uBAEAuK,6BARA,cAEA,SAqCJ,SAMIhG;;;;;4BAhDa2F,UAAAA,oEAAAA,CAAAA,IAAA,CAAiB,SAAS,SAACM;;;;;;;;;;;gCAExCtI,MAAQpB,KAAA,CAAM,iCAAiC0J;;;gCAA/CtI;4BACA,EAAInC,OAAAA,IAAW;8BACbmB,KAAAA,OAAAA,IAAAA,GAAmBnB,UAAUmF,YAAA,CAAapE,KAAK;4BACjD,UAAA,IAAA,KAAA,GAAA,CAAA,YAAA;gCAEA,IAAIb,WAAWD,GAAAA,IAAAA,0BAAAA,QAAO,EAAS,KAAKqK,OAAAA,cAArBrK,qCAAAA,CAAO4C,MAAA,mBAAcyH,WAAsB;oCACxD,eAAA,IAAA,2BAAA,QAAA,eAAA,cAAA,sCAAA,2BAAA;gCACF,IAAA,YAAA,IAAA,wBAAA,QAAA,YAAA,cAAA,mCAAA,wBAAA,QAAA,eAAA,GAAA,IAAA;gCAEAE,IAAAA,kBAAAA,IAAAA,8BAAAA,QAAAA,kBAAAA,cAAAA,yCAAAA,8BAAAA;4BACF,QAAA,cAAA,GAAA,QAAA,cAAA,IAAA,CAAA,OAAA,WAAA,cAAA,OAAA,QAAA,CAAA,IAAA,GAAA,EAAA;4BAEA3K,QAAAA,OAAesK,OAAAA,GAAAA,MAAA,CAAiB,gBAAgB;gCAC9C,IAAI,CAACnK,SAAAA,EAAW,CAAA;gCAChB,IAAIH,aAAAA,EAAgBoK,CAAAA,IAAA,EAAO;oCACzB9I,mBAAmBnB,GAAAA,GAAAA,IAAUmF,YAAA,CAAaT,IAAI;gCAChD,IAAA,GAAO,GAAA,QAAA,cAAA,IAAA,CAAA,OAAA,WAAA,cAAA,OAAA,QAAA,CAAA,IAAA,GAAA,EAAA;oCACLvD,UAAAA,GAAAA,MAAmBnB,EAAAA,QAAUmF,EAAAA,IAAAA,MAAA,CAAaR,MAAM;gCAClD,IAAA,WAAA,GAAA,QAAA,WAAA,IAAA;4BACF,IAAA,QAAA,IAAA,EAAA,QAAA,IAAA,GAAA,QAAA,IAAA;4BAEA9E,IAAAA,QAAAA,GAAesK,MAAAA,EAAAA,QAAA,CAAiB,QAAA,CAAS,EAAA,QAAA,SAAA;gCACvC,IAAInK,GAAAA,CAAAA,SAAa,CAACH,eAAgB6K,KAAA,EAAO,YAAA;sCACvCvJ,UAAAA,QAAAA,CAAmBnB,UAAUmF,GAAAA,SAAA,CAAaP,KAAK;kCACjD,eAAA,QAAA,eAAA;gCACF,cAAA,QAAA,YAAA;gCAEA/E,aAAesK,OAAAA,QAAAA,CAAA,CAAiB,QAAQ,QAAA;kCACtC,IAAInK,UAAAA,GAAaH,KAAAA,UAAgBwK,IAAAA,OAAA,GAAc,GAAG;sCAChDlJ,UAAAA,QAAAA,CAAmBnB,UAAUmF,GAAAA,SAAA,CAAaN,MAAM;kCAClD,UAAA,QAAA,UAAA;gCACF,eAAA,QAAA,aAAA;gCACF,wBAAA,QAAA,sBAAA;gCAEA,GAAS8F,EAAAA,QAAAA,GAAAA,IAAiBC,SAAA;gCACxB,EAAIA,UAAAA,CAAW,OAAA,UAAA;kCACb9L,WAAAA,EAAa+L,MAAAA,CAAA,CAAQC,SAAAA,UAAA,GAAsB;gCAC7C,KAAO,CAAA,QAAA,IAAA;kCACL,OAAOhM,EAAAA,QAAAA,GAAa+L,MAAAA,CAAA,CAAQC,mBAAA;4BAC9B;4BACF;;gCAAA,OAAA,gBAAA,CAAA;;;4BAAA,UAAA;4BAEA,KAASC,iBAAAA,KAAsBC,kBAAA;4BAC7B3K,eAAAA,CAAgB,OAAA,QAAA;gCACdC,IAAAA,GAAAA,CAAAA,IAAY0K,qBAAqB3K,cAAcC,UAAA,GAAa;gCAC5DC;;gCAAAA,IAAO;;;4BACPiE,YAAe;gCACfhE,IAAAA,IAAAA,CAAAA,CAAU,kCAAA;gCACViE,WAAAA,IAAe;gCACfhE,UAAU,QAAA,KAAA;4BACZ;;gCAAA;;;;;;;;YAGF,SAASwK;;YACP,IAAI,CAACpL,kBAAkB,CAACG,WAAW;kBACjC,CAAA,KAAM,IAAI8C,MAAM;YAClB;yBAEA,IAAMmB,aAAAA,QAAYtB,EAAAA,kBAAoB3C,UAAU4C,UAAU;cAC1D,EAAA,CAAA,CAAI,CAACqB,WAAW,GAAA,CAAA,YAAA,OAAA;kBACd,MAAM,IAAInB,MAAM;gBAClB,IAAA,MAAA,IAAA,IAAA;gBAEA,IAAMoI,UAAUlH,EAAAA,CAAAA,MAAAA,CAAAA,KAAeC;gBAC/B9B,IAAAA,IAAQC,GAAA,CACN,IAAA,CAAA,GAAA,CAAA,QAAA,QAAoElC,OAA3CgL,UAAU,QAAQ,eAAa,aAA4BjL,OAAhBC,WAAW,GAAC,KAAiC+D,OAA7BhE,OAAO4C,MAAA,IAAU,GAAC,YAAwB,OAAboB,UAAUxC,GAAG;gBAGhI,IAAIyJ,GAAAA,IAAAA,IAAWvM,IAAAA,OAAAwM,OAAAA,CAAIC,WAAA,IAAe;kBAChC,WAAA,EAAItL,OAAO;wBACTA,GAAAA,GAAMuL,OAAA,CAAA,OAAA,CAAA,qBAAA,IAAA,OAAA,CAAA,SAAA;oBACR,MAAA,KAAA,QAAA,CAAA,OAAA,MAAA;oBAEAvL,GAAAA,GAAYnB,OAAZmB,EAAQ,IAAInB,AAAAwM,OAAAxM,KAAAA,MAAAwM,GAAI,OAAJA,MAAAA,CAAI,YAAA;sBACdG,cAAc;oBACdC,gBAAgB;mCAClB;kBAEAzL,MAAM0L,UAAA,CAAWvH,UAAUxC,GAAG;8FAC9B3B,MAAM2L,UAAA,CAAY5L,gBAAAA;kBAElBC,WAAAA,IAAM4L,EAAA,CAAG/M,IACPwD,OADOgJ,CACC/I,GAAA,CAAI,EADL+I,CAAIQ,MAAA,CAAOC,eAAA,EAAiB;oBAEnC/L,eAAgBgM,IAAA,GAAOC,KAAA,CAAM,SAAC/K;kDAC5BoB,QAAQpB,KAAA,CAAM,6CAA6CA;0BAC3DyJ;kGACF,YAAA,eAAA;kBACF,WAAA,OAEA1K,MAAM4L,EAAA,CAAG/M,WAAAwM,OAAAA,CAAIQ,MAAA,CAAOI,KAAA,EAAO,SAACC,QAAQC;oBAClC9J,QAAQpB,KAAA,CAAM,4BAA4BkL;0CAC1C,IAAIA,KAAKC,KAAA,EAAO;0BACd1B;kGACF,YAAA,WAAA;kBACF,WAAA,GACF,OAAA,IACEU,WACArL,eAAesM,WAAA,CAAY,kCAC3B;gBACAtM,eAAeqC,GAAA,GAAM+B,UAAUxC,GAAA;sCAC/B5B,IAAAA,KAAAA,MAAegM,IAAA,GAAOC,KAAA,CAAM,SAAC/K;sBAC3BoB,QAAQpB,KAAA,CAAM,6CAA6CA;wBAC3DyJ,sFAAAA,WAAAA,CAAAA;kBACF,WAAA,GACF,OAAA,IAAW,CAACU,WAAW9G,uBAAuBH,YAAY;gBACxD,IAAInE,OAAO;oCACTA,MAAMuL,OAAA;sBACNvL,KAAAA,GAAQ,KAAA;kBACV,gBAAA,KAAA;gBAEAD,eAAeqC,GAAA,GAAM+B,UAAUxC,GAAA;cAC/B5B,eAAeuM,IAAA;YACfvM,eAAegM,IAAA,GAAOC,KAAA,CAAM,SAAC/K;gBAE3ByJ,UAAAA;YACF,cAAA;UACF,GAAA,IAAO;cACL,KAAA,CAAM,IAAI1H,MAAM,mCAAiD,OAAdmB,UAAUC,IAAI;UACnE,MAAA;MACF,MAAA;MAEA,QAAA,CAASoG;UACP,IAAIpK,YAAYD,OAAO4C,MAAA,GAAS,GAAG;cACjC,GAAA,IAAO;UACT;QAEA3C;QACAF,SAAAA,GAAYC,gBAAAA,IAAA,CAAOC,SAAQ;QAC3B6K,CAAAA,qBAAsB;UAEtB,CAAA,GAAI/K,QAAAA,GAAW,IAAA;YACbmB,mBAAmBnB,UAAUmF,YAAA,CAAa7E,UAAU;YACpDD,cAAcC,UAAA,GAAa;cAC3B6B,KAAAA,GAAQC,GAAA,CACN,EAAA,EAAA,OAAA,WAAA,SAAA,YAA2DnC,OAAhBC,WAAW,GAAC,KAAuBF,OAAnBC,OAAO4C,MAAM,EAAA,OAAoC7C,OAA9BA,UAAUyG,KAAK,EAAA,gBAAiC,OAAlBzG,UAAUiH,QAAQ,EAAA;UAElI,CAAA,SAAA,OAAA,WAAA,aAAA,EAAA,KAAA,OAAA,WAAA,MAAA,EAAA;QAEA,IAAI;YACFgE,cAAAA,UAAAA,EAAAA,OAAAA;cACuB,OAAvBoB,KAAK,MAAA,WAAA,EAAkB,KAAA,OAAA,YAAA,KAAA,OAAA;gBAAEhF,OAAOnH;YAA+B,cAAA;YAC/D,MAAA,CAAO,OAAA,QAAA,SAAA;QACT,EAAA,OAASa,OAAO;YACdoB,CAAAA,OAAQpB,KAAA,CAAM,6CAA6CA;YAC3D,CAAA,MAAO;QACT,CAAA;MACF,EAAA,UAAA,CAAA,iBAAA;MAEA,EAAA,KAASwJ,CAAAA;UACPpI,GAAAA,KAAQC,GAAA,CAAI;QACZpD,WAAAA,AAAY,iBAAA,OAAA,KAAA,MAAA,GAAA,QAAA,CAAA,IAAA,KAAA,CAAA,GAAA;UACZ2L,iBAAiB;YAEjB7L,KAAAA,QAAamL,IAAAA,CAAA,GAAQ,GAAA,CAAA,OAAA,CAAA,KAAA;wBAErB,IAAIlK,eAAe;kBACjBA,IAAAA,UAAc4J,CAAAA,IAAA,CAAM2C,GAAAA,IAAA,GAAU;kBAC9BvM,IAAAA,UAAc4J,CAAAA,IAAA,CAAM4C,GAAAA,UAAA,GAAgB;cACtC,SAAA;cAEA,IAAIxN,CAAAA,mBAAAA,8BAAAA,QAASyN,2BAAA,EAA6B;kBACxC,IAAI1N,OAAAA,MAAa2N,MAAA,EAAQ;sBACvBtK,MAAAA,EAAQC,GAAA,CAAI;sBACZtD,IAAAA,SAAa+M,IAAA,GAAOC,KAAA,CAAM,YAAO;gBACnC,OAAO;kBACL3J,QAAQC,GAAA,CAAI;gBACd,CAAA;YACF,IAAA,IAAA,CAAA,GAAA,OAAA,KAAA,sBAAA;YAEAiK,KAAK;MACP;MAEA,KAAA,EAAA,CAAA,CAAS7B,UAAAA;YACPrI,KAAAA,GAAQC,GAAA,CAAI;YACZpD,IAAAA,IAAAA,CAAAA,GAAY,OAAA,KAAA,kBAAA,OAAA;UACZ2L,iBAAiB;UAEjB7L,CAAAA,EAAAA,CAAAA,SAAamL,IAAAA,CAAA,GAAQ;YAErB,IAAIlK,CAAAA,cAAe;gBACjBA,IAAAA,CAAAA,GAAAA,OAAAA,KAAAA,EAAc4J,KAAA,CAAM2C,OAAA,GAAU;cAC9BvM,cAAc4J,KAAA,CAAM4C,aAAA,GAAgB;UACtC,CAAA,EAAA,CAAA,WAAA;YAEAF,KAAK;QACP,QAAA,IAAA,CAAA,GAAA,OAAA,KAAA;MAEA,OAAO;UACLK,CAAAA,EAAAA,CAAAA,QAAAA,CAAAA,SAAAA,OAAAA;gBACEvK,CAAAA,OAAQC,GAAA,CAAI;gBAEZ,IAAI,CAACrC,GAAAA,OAAAA,KAAAA,QAAe,IAAA,IAAA,OAAA;sBAclBjB;kBAbA,IAAM6N,CAAAA,WAAYlD,SAASC,aAAA,CAAc;oBACzCiD,GAAAA,OAAUhD,KAAA,CAAMC,QAAA,GAAW;sBAC3B+C,UAAUhD,KAAA,CAAME,IAAA,GAAO;oBACvB8C,UAAUhD,KAAA,CAAMG,GAAA,GAAM;kBACtB6C,UAAUhD,KAAA,CAAMiD,KAAA,GAAQ;gBACxBD,UAAUhD,KAAA,CAAMkD,MAAA,GAAS;gBACzBF,UAAUhD,KAAA,CAAM2C,OAAA,GAAU;kBAC1BK,SAAAA,CAAUhD,KAAA,CAAMmD,EAAAA,QAAA,GAAa;oBAC7BH,UAAUhD,KAAA,CAAMoD,cAAA,GAAiB;kBACjCJ,UAAUhD,KAAA,CAAM4C,aAAA,GAAgB;gBAChCI,UAAUhD,KAAA,CAAMqD,MAAA,GAAS;gBACzBL,KAAAA,KAAUhD,EAAAA,GAAA,CAAMI,GAAAA,YAAA,GAAkB;mBAElCjL,OAAAA,uBAAAA,aAAamO,aAAA,cAAbnO,kDAAAA,4BAA4BoO,WAAA,CAAYP;oBACxC5M,gBAAgB4M;cAClB;UACF;UAEMQ,OAAAA,KAAN,SAAMA,WAAWvF,UAAA;;sBAYTkB,KAGIsE,WAgCDrM;;;;;;8BA9CToB,QAAQC,GAAA,CAAI,iCAAiCwF;wBAE9B,gBAAf,IAAI5I,WAAW,IAAA,OAAA,OAAA,MAAA;oCACbmD,QAAQE,IAAA,CACN;kCAEF;;;4BACF;;;;;;;;;4BAGE3C,YAAYsB;4BACR8H;iCAEAuE,aAAaC,GAAA,CAAI1F,aAAjByF;;;;4BACID,YAAYC,aAAa9P,GAAA,CAAIqK;4BACnCyF,aAAaE,MAAA,CAAO3F;8BACpB,IAAIwF,QAAAA,GAAW,IAAA;kCACbtE,aAAAA,IAAAA,CAAAA,UAAAA,SAAAA;oCAAOsE;;8BACT,YAAA,OAAA;4BACAjL,IAAAA,IAAQC,GAAA,CACN,gDACAwF;;;;;;4BAGI,CAAA;;kCAAMgB,iBAAiBhB;;;8BAA7BkB,MAAM;;;8BAGR,IAAI,CAACA,IAAIjG,MAAA,EAAQ;kCACfV,QAAQE,IAAA,CAAK;kCACbgK,KAAK;gCACL;;;;;oCAAOmB,GAAAA,KAAQC,MAAA,CAAO,IAAI3K,MAAM;QAUnB;;4BATf;4BAEA7C,SAAS6I;4BACT5I,KAAAA,MAAW,EAAA,IAAA,wBAAA,eAAA,QAAA,IAAA,CAAA,MAAA,eAAA,eAAA,KAAA,OAAA,sBAAA,KAAA,CAAA;4BACXF,SAAAA,GAAY8I,GAAA,CAAI,EAAC,GAAA,IAAA,iBAAA,mBAAA,iBAAA,aAAA,eAAA,YAAA,IAAA,uBAAA,CAAA,KAAA,WAAA,KAAA,CAAA;4BACjB3G,QAAQC,GAAA,CFp8BhB,AEq8BU,IAAA,GAAA,cAAA,eAA6B0G,GAAAA,CAAIjG,MAAM,EAAA,MAAA,eAAA,KAAkB7C,sBAAAA,gCAAAA,UAAWyG,KAAK,EAAA,gBAAkC,OAAnBzG,sBAAAA,gCAAAA,UAAWiH,QAAQ,EAAA;4BAG7G,IAAIjH,MAAAA,KAAW,GAAA,OAAA,wBAAA,yBAAA,cAAA,yCAAA,kBAAA,OAAA,QAAA,KAAA;kCACbmB,mBAAmBnB,UAAUmF,YAAA,CAAa7E,UAAU;oCACpDD,cAAcC,UAAA,GAAa;kCAC7B;kCAEA,IAAA,UAAA,IAAA,iBAAA,iBAAA,CAAA,KAAA,sBAAA,wBAAA;;sCAAOkN,IAAAA,IAAQE,OAAA,UAAA,cAAA,iBAAA,SAAA,CAAA,KAAA,mBAAA,aAAA;;;;;4BACR3M;QAAAA,IAAAA,CAAAA,sBACPoB,OAAAA,CAAQpB;YAAAA,IAAA,CAAM,YAANA;QAAM,IAAA,CAAA,uBAAuCA;kCACrDsL,KAAK;;;kCACEmB,QAAQC,MAAA,CAAO1M;;;;;;;;;;;cAE1B,CAAA,cAAA,aAAA;;UACM8K,MAAN,SAAMA;;sBAmBI8B,IAAAA,OAAAA;;sBAlBR,IAAI,CAAC3N,CAAAA,IAAAA,CAAAA,KAAW,OAAA;0BACdmC,IAAAA,IAAQE,CAAAA,GAAA,CACN,CAAA,OAAA;0BAEF,kBAAA,IAAA,CAAA,KAAA,OAAA;;8BAAOmL,EAAAA,CAAAA,KAAQC,MAAA,CAAO,IAAI3K,MAAM;;oBAClC;oBAEAX,QAAQC,GAAA,CAAI,EAAA,OAAA,EAAA,WAAA;sBAEZ,IAAI,QAAA,OAAA;wBACF,IAAI,CAACvC,IAAAA,YAAgB;4BACnBA,EAAAA,WAAAA,IAAiB0J;8BACjBxJ,EAAAA,wBAAAA,oCAAAA,cAAemN,WAAA,CAAYrN;8BAC3BqK,CAAAA,CAAAA,QAAAA,iBAAAA,GAAAA,CAAAA;wBACF;wBAEAa,sBAAsB;wBAEhB4C,gBAAgB7O,aAAaQ,MAAA;wBACnCJ,CAAAA,gBAAiBC,KAAKC,GAAA,CACpB,GACAD,KAAKE,GAAA,CAAI,GAAGsO,iBAAiBzO;wBAG/B,IAAI,EAACH,GAAAA,QAAAA,IAAAA,KAAAA,mBAAAA,WAAAA,IAAAA,IAASyN,IAAAA,uBAAA,GAA6B;8BACzC1N,UAAAA,GAAa8F,KAAA,KAAA,aAAA,WAAA;gCACbzC,QAAQC,GAAA,CAAI;0BACd,OAAO;8BACLD,QAAQC,GAAA,CAAI;wBACd;wBAEAD,OAAAA,CAAQC,GAAA,CAAI,KAAA;0BACZtD,aAAamL,KAAA,GAAQ;4BACrBjL,YAAY;0BACZ2L,iBAAiB;wBAEjB,IAAI9K,QAAAA,QAAgB;8BAClBA,eAAeP,MAAA,GAASH,KAAKC,GAAA,CAAI,GAAGD,KAAKE,GAAA,CAAI,GAAGH;gCAChDW,MAAAA,SAAeoK,KAAA,GAAQhL;gCACvBkD,QAAQC,GAAA,CACN,wCAAyEvC,OAAjCA,eAAeP,MAAM,EAAA,aAAyDL,OAA7CY,eAAeoK,KAAK,EAAA,0BAA+D0D,OAAtC1O,oBAAkB,qBAAiC,OAAb0O;0BAEhK;wBAEA,IAAI5N,eAAe;8BACjBA,IAAAA,UAAc4J,KAAA,CAAM2C,OAAA,GAAU;8BAC9BvM,cAAc4J,KAAA,CAAM4C,aAAA,GAAgB;wBACtC;wBAEAF,KAAK;wBAELpB,YAAAA;0BAEA;;gCAAOuC,QAAQE,OAAA;;oBACjB,EAAA,OAAS3M,OAAO;0BACdoB,QAAQpB,KAAA,CAAM,OAAA,4BAAmCA;0BACjDyJ;wBACA;;8BAAOgD,QAAQC,KAAAA,CAAA,CAAO1M,SAAAA;;oBACxB,OAAA,UAAA,EAAA,KAAA;;;;;cACF,EAAA,YAAA;;QACA6D,OAAAA,SAAAA,WAAAA,KAAAA,KAAAA,KAAAA,MAAAA;YACE,IAAI,CAAC5F,GAAAA,IAAAA,MAAa,CAACa,gBAAgB;kBACjC,UAAA,aAAA;gBACF,IAAA;cAEA,IAAI;kBACF,IAAIA,kBAAkB,CAACA,eAAe4M,MAAA,EAAQ;sBAC5C5M,eAAe+E,GAAAA,EAAA,MAAA;kBACjB,EAAA,SAAA,MAAA,GAAA,SAAA,MAAA,CAAA,KAAA,CAAA,OAAA,EAAA;;;gCACO7D,KAAO,wBAAhB,EAAA,mGAAgB;oBAAhB,MAASA;wBACPoB,IAAAA,IAAQE,CAAAA,GAAA,CAAK,mCAAmCtB;sBAClD,IAAA,UAAA,CAAA,SAAA;oBACF,OAAA,mBAAA,MAAA,KAAA,CAAA,OAAA,MAAA,MAAA,KAAA;kBACA8D,QAAAA,SAAAA;oBACE,IAAI,CAAC7F,aAAa,CAACa,gBAAgB;;;;;;;;;;;;;;;2BACjC,KACF;cAEA,EAAA,EAAI;gBACF,IAAIA,kBAAkBA,eAAe4M,MAAA,EAAQ;oBAC3C5M,CAAAA,IAAAA,EAAAA,KAAAA,GAAegM,IAAA,GAAOC,KAAA,CAAM,YAAO;kBACrC,UAAA,aAAA;gBACF,EAAA,OAAS/K,OAAO;kBACdoB,QAAQE,IAAA,CAAK,oCAAoCtB;cACnD;YACF,KAAA,MAAA,GAAA,mBAAA,QAAA,MAAA,mBAAA,SAAA,qBAAA,+BAAA;UACM6M,WAAAA,IAAN,SAAMA;oBAKEC;;;sBAJN1L,IAAAA,IAAQC,GAAA,CAAI,OAAA,OAAA,OAAA,UAAA,KAAA,YAAA;wBACZpD,QAAAA,IAAY;sBACZ2L,iBAAiB;oBAEXkD,WAAAA,UAAqB/O,aAAamL,KAAA;sBACxCnL,IAAAA,SAAamL,KAAA,CAAA,EAAQhL,KAAAA,OAAAA,eAAAA,KAAAA,YAAAA;wBACrBH,MAAAA,CAAAA,MAAaQ,MAAA,GAASH,KAAKC,GAAA,CAAI,GAAGD,KAAKE,GAAA,CAAI,GAAGH;sBAC9CiD,QAAQC,GAAA,CACN,8CAAuEnD,OAAzB4O,oBAAkB,QAAsC/O,OAA/BG,oBAAkB,cAAgC,OAAnBH,aAAaQ,MAAM;wBAG3H,GAAA,CAAIS,IAAAA,KAAAA,KAAAA,CAAe,mBAAA;2BACjBA,IAAAA,IAAAA,KAAc4J,KAAA,CAAM2C,OAAA,GAAU;8BAC9BvM,SAAAA,KAAc4J,GAAAA,EAAA,CAAM4C,aAAA,GAAgB;0BACtC,KAAA,KAAA,KAAA,CAAA,KAAA,MAAA,KAAA,IAAA,IAAA;wBAEAzN,aAAa6K,KAAA,CAAMmE,UAAA,GAAa;sBAChChP,aAAa6K,KAAA,CAAMoE,OAAA,GAAU;iCAE7B,EAAA,EAAIhP,2CAAAA,KAAAA,KAAAA,QAAAA,8BAAAA,QAASyN,2BAAA,EAA6B;sCACxC,6CAAA,EAAI1N,GAAAA,KAAAA,KAAa2N,MAAA,EAAQ;8BACvBtK,QAAQC,GAAA,CAAI;+BACZtD,GAAAA,UAAa+M,IAAA,GAAOC,KAAA,CAAM,YAAO;;oFACnC,GAAA,QAAA,CAAA,IAAA,QAAA,CAAA,GAAA;sBACF;sBAEA,EAAA,EAAIhM,GAAAA,IAAO,EAAA,IAAA,KAAA,CAAA,GAAA,MAAA,MAAA,IAAA,KAAA,CAAA,IAAA,MAAA,MAAA,IAAA,KAAA,CAAA,IAAA,MAAA,MAAA,IAAA,KAAA,CAAA,IAAA;wBACTA,MAAMuL,OAAA;wBACNvL,QAAQ,KAAA;sBACV;wBAEA,IAAID,OAAAA,SAAgB,MAAA,OAAA,YAAA,GAAA,KAAA,YAAA;8BAClBA,CAAAA,GAAAA,WAAe+E,KAAA;4BACf/E,eAAeqC,GAAA,GAAM;+BACvB,SAEAlC,YAAY,KAAA;sBACZC;oBACAC,WAAW;;;;;;gBACb,IAAA;;cAEAmL,EAAAA,OAAAA,SAAAA,YAAAA,QAAAA,CAAAA,mBAAAA,OAAAA;oBACElJ,MAAQC,GAAA,CAAI,GAAA,OAAA,YAAA,KAAA,aAAA,OAAA,YAAA,KAAA,KAAA;oBACZzC,GAAAA,SAAY;0BAEZ,IAAA,8BAAA,2BAAA;;sBAAA,IAAA,IAAA,IAAA,QAAwBS,IAAAA;oBAAAA,iBAAAA;gBAAAA,IAAAA,CAAAA,IAAxB,SAAA,6BAAA,QAAA,yBAAA,iCAAyC;0BACvC4N,aAAaC;oBACf;oCAFA;kBAAA;;;gBAAA;6BAAA,GAAA,SAAA,MAAA,KAAA,MAAA,OAAA,SAAA,MAAA,MAAA,mBAAA,SAAA,MAAA,cAAA,8BAAA,mBAAA,SAAA,MAAA;8BAAA,IAAA,YAAA,QAAA;;;;;;gCAAA;sCAAA,EAAA,SAAA;;;;;;;;gBAGA7N,kBAAkB,EAAC;uBAEnBpB,SACA2L,GADY,cACK;cACjB7L,aAAamL,KAAA,GAAQhL;cACrBH,KAAAA,OAAAA,CAAaQ,GAAAA,GAAA,GAASH,KAAKC,GAAA,CAAI,GAAGD,KAAKE,GAAA,CAAI,GAAGH;gBAE9C,EAAA,EAAIY,OAAO;oBACTA,GAAAA,GAAMuL,IAAAA,GAAA,EAAA,oBAAA,KAAA,aAAA,KAAA,oBAAA,KAAA,KAAA,IAAA;sBACNvL,CAAAA,OAAQ,EAAA,GAAA,SAAA,QAAA,CAAA,mBAAA,OAAA;oBACV,GAAA;oBAAA,UAAA;oBAAA,cAAA;oBAAA,iBAAA;gBAAA;kBAEA,IAAID,gBAAgB;oBAClBA,eAAe+E,KAAA;2BACf/E,SACAA,MADeqC,GAAA,GAAM,GACNgM,MAAA;kBACfrO,iBAAiB,KAAA;YACnB;YAEA,IAAIE,YAAAA,aAAAA,CAAAA,EAAAA,IAAAA,IAAAA,0BAAAA,cAAekN,aAAA,EAAe;kBAChClN,cAAckN,aAAA,CAAckB,WAAA,CAAYpO;cAC1C;YAEAA,gBAAgB,KAAA;YAChBC,YAAY,IAAA,CAAA,IAAA;YACZC,MAAAA,GAAS,CAAA,CAAC;cACVC,GAAAA,QAAW,6BAAA,IAAA,CAAA,MAAA,oDAAA,IAAA,CAAA,MAAA,sBAAA,GAAA,CAAA,EAAA,WAAA;YACXX,UAAU6O,KAAA;YACVf,UAAAA,GAAae,EAAAA,GAAA;cACbjO,cAAciO,KAAA,GAAA,CAAA,MAAA,IAAA,GAAA,WAAA;QAChB;QAEAC,CAAAA,YAAAA,SAAAA;cACE,CAAA,MAAOrP,KAAAA,aAAAA;YACT,GAAA,CAAA;UAEAsP,QAAAA,SAAAA,OAAOvM,KAAA,EAAeU,MAAA;YACpBN,QAAQC,CAAAA,EAAA,CAAI,6BAAsCK,OAATV,OAAK,KAAU,OAANU;gBAElD,IAAI1C,eAAe,MAAA;oBACjBA,aAAAA,CAAc4J,KAAA,CAAM5H,KAAA,GAAQ,GAAQ,OAALA,OAAK;oBACpChC,QAAAA,MAAc4J,KAAA,CAAMlH,MAAA,GAAS,GAAS,OAANA,QAAM;gBACxC,KAAA;gBAEA,IAAI5C,EAAAA,cAAgB;oBAClBA,eAAe8J,KAAA,CAAM5H,KAAA,GAAQ,GAAQ,OAALA,OAAK;oBACrClC,eAAe8J,KAAA,CAAMlH,MAAA,GAAS,GAAS,OAANA,QAAM;gBACzC,KAAA;UACF,EAAA,CAAA;;;4BAEAiJ,CAAG/K,KAAA,EAAe4N,8DAAlB7C,IAAAA,6DAAkB6C,IAAA;gBAAlB7C,QAAAA;kBACE,IAAI,CAACnM,MAAAA,IAAU+N,GAAA,CAAI3M,QAAQpB,QAAAA;gBAAAA,CAAUmB,GAAA,CAAIC,OAAO;gBAAA;gBAAA,IAAA,GAAA,IAAI6N;gBAAAA;aAAAA,KAAAA,KAAAA;kBACpDjP,MAAAA,IAAUhC,GAAA,CAAIoD,OAAQ8N,CAAAA,EAAA,CAAIF,KAAAA;gBAAAA;gBAAAA;gBAAAA;gBAAAA;aAAAA,KAAAA,KAAAA;gBAC5B,UAAA,gBAAA,QAAA;gBAAA;gBAAA;gBAAA;aAAA,KAAA,KAAA;gBAEAG,GAAAA,QAAAA,CAAAA,IAAI/N,KAAA,EAAe4N,IAAAA,IAAA,IAAA;0BACjBhP;uBAAAA,iBAAAA,UAAUhC,GAAA,CAAIoD,oBAAdpB,qCAAAA,eAAsBgO,MAAA,CAAOgB;kBAC/B;kBAEAI,0BAAAA,SAAAA,yBAAyB1E,KAAA,EAAgB3K,MAAA;sBACvC,IAAMsP,aACJ,OAAOtP,WAAW,YAAY,CAAC6J,OAAO0F,KAAA,CAAMvP,UACxCH,KAAKC,GAAA,CAAI,GAAGD,KAAKE,GAAA,CAAI,GAAGC,WACxBJ;sBACNiD,QAAQC,GAAA,CACN,2DAAoF6H,OAAzBhL,oBAAkB,QAAyBC,OAAlB+K,OAAK,cAAkC2E,OAArB1P,gBAAc,QAAiB,OAAV0P,YAAU;sBAEvI3P,qBAAqBgL;sBACrB/K,iBAAiB0P;kBACnB;kBAEAE,uBAAAA,SAAAA;sBACE,OAAO7P;gBACT,EAAA,KAAA;gBACA8P,CAAAA,cAAAA,CAAAA,GAAAA,SAAAA,CAAAA,SAAAA,CAAAA,SAAAA;kBACE,OAAO7P,MAAAA,gBAAAA,QAAAA;kBACT;kBAEA8P,aAAAA,SAAAA,YAAY1P,MAAA;sBACV,IAAIO,kBAAkBb,WAAW;0BAC/B,IAAMiQ,UAAU9P,KAAKC,GAAA,CAAI,GAAGD,KAAKE,GAAA,CAAI,GAAGC;wBACxCO,eAAeP,MAAA,GAAS2P;sBACxBpP,YAAAA,GAAeoK,KAAA,GAAQgF,OAAAA,KAAY,GAAA;sBACrC;kBACF;kBAEAC,aAAAA,SAAAA;sBACE,IAAIrP,kBAAkBb,WAAW;wBAC/B,OAAOa,eAAeP,MAAA;oBACxB,qBACA,OAAO,GAAA;gBAAA,YAAA;YAAA,IAAA,CAAA,GACT,QAAA;gBAAA,OAAA;YAAA,IAAA,CAAA,GACA6P,UAAAA;gBAAAA,SAAAA,IAAAA;YAAAA,IAAAA,CAAAA,MACErQ,QAAAA;gBAAAA,UAAAA,GAAa6K,KAAA;YAAMoE,IAAAA,CAAAA,EAAA,GAAU,CAC7BjP,SAAAA,IAAa6K,KAAA,CAAMmE,KAAAA;gBAAAA,cAAAA,GAAA,GAAa;YAAA,IAAA,CAAA,MAEhC,IAAI,CAAC/N,IAAAA,WAAe,QAAA,OAAA;gBAAA,iBAAA;YAAA,IAAA,CAAA;sBAClB,IAAM4M,YAAYlD,SAASC,aAAA,CAAc;;;;;;;;;;;;;;;kBACzCiD,UAAUhD,KAAA,CAAMC,QAAA,GAAW;gBAC3B+C,UAAUhD,KAAA,CAAME,IAAA,GAAO;gBACvB8C,SAAAA,CAAUhD,KAAA,CAAMG,CAAAA,EAAA,EAAA,CAAM;;;4BACtB6C,iIAAUhD,KAAA,CAAMiD,KAAA,GAAQ;mBAAxBD;sBACAA,EAAAA,mBAAAA,6BAAAA,MAAUhD,CAAAA,IAAA,CAAMkD,MAAA,GAAS;wBACzBF,SAAAA,CAAUhD,KAAA,CAAM2C,KAAAA,EAAA,GAAU,EAAA;0BAC1BK,UAAUhD,KAAA,CAAMmD,UAAA,GAAa;wBAC7BH,UAAUhD,KAAA,CAAMoD,cAAA,GAAiB;wBACjCJ,SAAAA,CAAUhD,KAAA,CAAM4C,KAAAA,QAAA,GAAgB;0BAChCI,UAAUhD,KAAA,CAAMqD,MAAA,GAAS;0BACzBL,OAAAA,GAAUhD,GAAAA,EAAA,CAAMI,CAAAA,CAAAA,aAAA,GAAkB;6BAElCjL,EAAAA,WAAAA,YAAAA,KAAAA,GAAAA,UAAamO,aAAA,cAAbnO,kDAAAA,4BAA4BoO,WAAA,CAAYP;8BACxC5M,CAAAA,eAAgB4M;wBAClB;sBAEA,WAAA,EAAI5M,SACFA,MADiB,QACH4J,KAAA,CAAM2C,OAAA,GAAU;wBAC9BvM,cAAc4J,KAAA,CAAM4C,aAAA,GAAgB;kBACtC;;;;;;;;;;;;;;;UACF,CAAA,KAAA;QACA6C,iBAAAA,SAAAA;YACE,IAAIrP,WAAAA,IAAe,EAAA,EAAA,IAAA;;;4BACjBA,iIAAAA,IAAc4J,KAAA,CAAM2C,OAAA,GAAU;mBAA9BvM;sBACAA,EAAAA,mBAAAA,6BAAAA,MAAAA,CAAAA,GAAc4J,CAAAA,IAAA,CAAM4C,aAAA,GAAgB;kBACtC,WAAA,iBAAA;oBAEA,IAAI,CAACvN,KAAAA,MAAW;0BACdF,aAAa6K,KAAA,CAAMmE,UAAA,GAAa;wBAChChP,aAAa6K,KAAA,CAAMoE,OAAA,GAAU;oBAC/B,GAAA,UAAA,YAAA;kBACF,EAAA;oBACAsB,IAAAA,SAAAA,MAAAA,SAAAA,EAAAA,MAAAA,IAAAA,CAAAA;wBACE,OAAOrP,GAAAA,MAAAA,aAAAA,gCAAAA,UAAWiH,QAAA;wBACpB,OAAA;oBACAqI,eAAAA,SAAAA;sBACE,WAAA,GACF,EADStP,sBAAAA,gCAAAA,UAAWyH,EAAA;gBAEpB8H,eAAAA,SAAAA;kBACE,OAAOtP,OAAO4C,MAAA;;;;;;;;;;;;;;;UAChB,CAAA,KAAA;QACA2M,uBAAAA,SAAAA;YACE,OAAOvP,OAAOwP,MAAA,CACZ,SAACC,OAAOlI;;;+BAAOkI,QAASlI,CAAAA,GAAGP,QAAA,4HAAA,EAAW,IAAIO,GAAGP,QAAA,GAAW,MAAO,CAAA;;qBAC/D,GAAA,iBAAA;gBAEJ,OAAA;gBACF,OAAA;YACF;QFvPA,eAAiB;;;;;;;;;;;;;;;IGj/BjB,EAAM0I,KAAAA,KAAAA,IACJ;AAEF,IAAIC;AACJ,IAAIC,KAAAA,iBAAAA,GAAAA;IAEJ,IAAA,GAASC,IAAAA,WAAAA,aAAAA;YAC8BC,GAAAA,KAAAA;MAArC,IAAI,OAAOA,WAAW,iBAAeA,eAAAA,OAAOC,IAAA,cAAPD,mCAAAA,aAAaE,GAAA,GAAK;UACrD,OAAOzC,QAAQE,OAAA;YACjB;QAAA,IAAA,SAAA,uBAAA,OAAA,YAAA,cAAA,2CAAA,qBAAA,OAAA,CAAA;QAEA,IAAImC,GAAAA,SAAAA,KAAiB,OAAOA;MAE5BA,eAAAA,YAAkB,IAAIrC,QAAc,SAACE,SAASD;YAC5C,GAAA,CAAMyC,IAAAA,OAAWzG,SAASnD,aAAA,CACxB;UAGF,IAAI4J,UAAU;gBACRH;YAAJ,KAAIA,eAAAA,OAAOC,IAAA,cAAPD,mCAAAA,aAAaE,GAAA,EAAK;kBACpBvC,sBACA,KAAA,sBAAA,iBAAA,wBAAA,iBAAA;YAEF,IAAMyC,UAAUC,WACd;uBAAM3C,GAAAA,IAAO,CAAA,GAAI3K,MAAM;iBACvB,QAAA,WAAA;gBAEFoN,SAAS/F,gBAAA,CAAiB,QAAQ;kBAChC6D,aAAamC;kBACbzC,OAAAA,UAAAA;gBACF,SAAA;cACAwC,SAAS/F,gBAAA,CAAiB,SAAS;kBACjC6D,OAAAA,MAAamC,IAAAA;kBACb1C,OAAO,IAAI3K,EAAAA,IAAM,OAAA;gBACnB,WAAA,OAAA,eAAA,UAAA,eAAA,OAAA;kBACA,CAAA;YACF;YAEA,IAAMuN,SAAS5G,EAAAA,OAASC,aAAA,CAAc,CAAA,WAAA,eAAA,MAAA;cACtC2G,KAAAA,EAAOnO,GAAA,GAAMyN;YACbU,OAAOC,KAAA,GAAQ;UACfD,OAAOE,YAAA,CAAa,YAAY;UAChCF,CAAAA,KAAAA,CAAOG,MAAA,GAAS;mBAAM9C;QACtB2C,OAAOI,OAAA,EAAA,CAAU;mBAAMhD,GAAAA,IAAO,IAAI3K,MAAM;;QACxC2G,SAASiH,CAAAA,CAAAA,EAAA,CAAKxD,WAAA,CAAYmD;MAC5B,EAAA,OAAA,aAAA,EAAA;QAEA,OAAOR,CAAAA,aAAAA,GAAAA;IACT;IAEA,IAAA,GAASc,IAAAA,YAAAA,KAAAA,KAAAA,GAAAA;QACP,IAAIf,IAAAA,UAAc,KAAA,EAAOA,CAAAA,OAAAA,YAAAA,GAAAA,SAAAA;MACzB,IAAMI,OAAOD,OAAOC,IAAA;MACpB,IAAMY,CAAAA,iBAAkB,IAAIZ,KAAKC,GAAA,CAAIY,eAAA;IACrCD,gBAAgBE,YAAA,GAAe;IAC/BlB,KAAAA,UAAe,IAAII,KAAKC,GAAA,CAAIc,WAAA,CAAYH;iGA0HlCI,UAIJC,4BAAAA,gBHi9BJ;MG9kCE,EAAA,GAAOrB,EAAAA,UAAAA,SAAAA;IACT,IAAA,WAAA,UAAA,QAAA;IAgCO,IAAA,CAASsB,QAAAA,UAAAA,MAAAA,IAAAA;MACd,EAAIC,eAAe,EAAA,UAAA,cAAA,IAAA;MACnB,EAAIH,SAAAA,UAAAA,YAAAA,IAAAA;MAEJ,EAAA,GAAO,mBAAA,UAAA,mBAAA,IAAA;QACCI,aAAAA,EAAN,SAAMA;;wFAAcrS,MAAAA,GAQSA,yBACCA,0BAExBA,uBAC2BA,6BARvBsS,QACArB,MAEAsB,SAuCAC,SAMCxQ;;;;;8BApDShC,UAAAA,oEAA2B,CAAC;;;;;;;;;8BAE5C;;oCAAM+Q;;;8BAAN,GAAA,CAAA;+BAEMuB,OAASV,OAATU,GAASV,OAAAA,CAAAA,EAAAA,IAAAA;8BACTX,OAAOD,OAAOC,IAAA;gCAEdsB,UAAU,IAAItB,KAAKC,GAAA,CAAIuB,YAAA;gCAC7BF,QAAQG,cAAA,IAAiB1S,0BAAAA,QAAQ0S,cAAA,cAAR1S,qCAAAA,0BAA0B;gCACnDuS,QAAQI,eAAA,IAAkB3S,2BAAAA,QAAQ2S,eAAA,cAAR3S,sCAAAA,2BAA2B;gCACrDuS,QAAQK,YAAA,IACN5S,wBAAAA,QAAQ4S,YAAA,cAAR5S,mCAAAA,wBAAyBuS,QAAQI,eAAA,GAAkB,IAAI;8BACzDJ,GAAAA,CAAAA,IAAQM,kBAAA,IAAqB7S,8BAAAA,QAAQ6S,kBAAA,cAAR7S,yCAAAA,8BAA8B;8BAC3DuS,CAAAA,OAAQO,cAAA,GACN9S,OAAAA,CAAQ8S,YAAAA,EAAA,IACP,CAAA,OAAO9B,WAAW,cAAcA,OAAO+B,QAAA,CAASC,IAAA,GAAO,EAAA;+BAC1DT,OAAQ,EAAiB,KAAzBA,EAAQU,QAAAA,CAAAA,EAAAA,EAAAA,EAAA,GAAiB,OAAjB,SAAiB,IAAA,KAAA;8BACzBV,QAAQW,CAAAA,SAAA,GAAa;gCACrBX,QAAQY,aAAA,GAAgB;gCACxBZ,QAAQa,sBAAA,GAAyB;gCACjCb,QAAQ7P,GAAA,GACN1C,QAAQ8S,cAAA,IACP,CAAA,OAAO9B,WAAW,cAAcA,OAAO+B,QAAA,CAASC,IAAA,GAAO,EAAA;gCAC1DT,QAAQc,UAAA,GAAarT,QAAQqT,UAAA,IAAc;8BAC3Cd,QAAQe,CAAAA,GAAAA,OAAA,CAAA,CAAA,CAActT,QAAQsT,CAAAA,UAAA,IAAe;gCAE7C,IAAItT,QAAQuT,IAAA,EAAMhB,QAAQgB,IAAA,GAAOvT,QAAQuT,IAAA;gCACzC,IAAIvT,QAAQW,SAAA,EAAW4R,QAAQ5R,SAAA,GAAYX,QAAQW,SAAA;gCAEnDyC,QAAQC,GAAA,CAAI,4CAA4C;oCACtDqP,gBAAgBH,QAAQG,cAAA;kCACxBC,OAAAA,CAAAA,GAAAA,MAAiBJ,EAAAA,CAAAA,KAAQI,MAAAA,OAAAA,EAAA,MAAA,CAAA,OAAA,GAAA;oCACzBC,cAAcL,QAAQK,YAAA;oCACtBC,oBAAoBN,QAAQM,kBAAA;oCAC5BC,gBAAgBP,QAAQO,cAAA;oCACxBG,gBAAgBV,QAAQU,cAAA;kCACxBC,OAAAA,CAAAA,GAAAA,CAAYX,OAAAA,CAAQW,UAAA,IAAA,GAAA,QAAA,CAAA,KAAA,GAAA;oCACpBC,eAAeZ,QAAQY,aAAA;oCACvBC,wBAAwBb,QAAQa,sBAAA;oCAChC1Q,KAAK6P,QAAQ7P,GAAA;oCACb2Q,YAAYd,QAAQc,UAAA;kCACpBC,KAAAA,GAAAA,KAAaf,GAAAA,CAAAA,IAAQe,MAAAA,KAAA;oCACrBC,MAAMhB,QAAQgB,IAAA;oCACd5S,WAAW4R,QAAQ5R,SAAA;gCACrB;gCAEgB;;oCAAM2R,OAAOkB,gBAAA,CAAiBjB;;;gCAAxCC,UAAU;8BAChBP,sBAAsBO;8BACtBJ,EAAAA,aAAeI,QAAQiB,QAAA;gCAEvBrQ,QAAQC,GAAA,CAAI;gCACZ;;oCAAO+O,EAAAA,CAAAA,mBAAAA,KAAAA,GAAAA,QAAAA,CAAAA,gBAAAA,GAAAA,QAAAA,CAAAA,SAAAA,GAAAA;;;kCACApQ,QAAAA,eAAAA;gCACPoB,QAAQE,IAAA,CAAK,mCAAmCtB;8BAChDoQ,EAAAA,GAAAA,KAAAA,CAAAA,IAAe;gCACfH,CAAAA,iBAAAA,CAAAA,EAAAA,CAAsB,CAAA,IAAA;kCACtB,GAAA,CAAA,EAAA;;kCAAO;;;;;;;;cAEX;;YAEAyB,GAAAA,QAAAA,CAAAA,KAAAA,OAAAA,EAAAA;kBACE,OAAOtB;cACT,WAAA;YAEAuB,GAAAA,IAAAA,GAAAA,GAAAA,KAAAA,CAAAA,GAAAA,OAAAA,CAAAA,IAAY9K,KAAAA,IAAAA,CAAA,KAAA;kBACV,IAAI,CAACuJ,gBAAgB,CAACvJ,YAAY,OAAOA;kBAEzC,IAAI,GAAA;sBACF,IAAMnG,MAAM,CAAA,GAAIkR,IAAI/K,SAAAA;oBACpBnG,EAAAA,EAAImR,MAAAA,CAAAA,KAAA,CAAarF,IAAAA,EAAA,CAAO;sBACxB9L,IAAImR,YAAA,CAAalS,GAAA,CAAI,QAAQyQ;sBAC7B,GAAA,IAAO1P,IAAIH,QAAA;gBACb,EAAA,eAAQ;kBACN,IAAIuR,OAAOjL,WACRkL,OAAA,CAAQ,qBAAqB,IAC7BA,OAAA,CAAQ,SAAS;kBACpB,IAAMC,MAAMF,CAAAA,IAAKlR,QAAA,CAAS,OAAO,MAAM;oBACvC,OAAO,CAAA,EAAUoR,OAAPF,IAAAA,EAAkBG,CAAAA,MAAXD,EAAAA,CAAAA,EAAG,SAAwC,OAAhCC,CAAAA,kBAAmB7B;gBACjD,GAAA,QAAA,CAAA,UAAA,QAAA;YACF,OAAA,QAAA,CAAA,cAAA,GAAA,QAAA,CAAA,QAAA,QAAA;UAEA8B,mBAAAA,SAAAA;cACE,EAAA,EAAI,qBAAA,IAAA,CAAA;gFACFjC,SAAAA,MAAAA,KAAAA,EAAAA,WAAAA,oBAAAA,+BAAAA,SAAAA,KAAAA,KAAAA,MAAAA,GAAAA,6BAAAA,oBAAqBiC,iBAAA;gBACvB,EAAA,EAAA,aAAQ,CAAC;UACX;UAEAhC,KAAAA,OAAAA,KAAAA,KAAAA,CAAAA,GAAAA,2BAAAA,OAAAA,IAAAA,OAAAA,SAAAA,CAAAA,UAAAA,KAAAA,QAAAA,EAAAA,iBAAAA,OAAAA,MAAAA,cAAAA,sCAAAA,6BAAAA,eAAAA,WAAAA,cAAAA,iDAAAA,2BAAAA,KAAAA,MAAAA,KAAAA;cACE,IAAI;oBACFD,gCAAAA,0CAAAA,oBAAqBC,eAAA;gBACvB,EAAA,eAAQ,CAAC;YACX,GAAA,SAAA,GAAA,SAAA,CAAA,GAAA,MAAA;YAEAiC,aAAAA,SAAAA;2BACE,IAAI;+BACFlC,gCAAAA,0CAAAA,oBAAqBkC,WAAA;gBACvB,EAAA,eAAQ,CAAC;sBACX;YAEAC,IAAAA,OAAAA,EAAAA,MAAAA,CAAAA,EAAAA,MAAAA,MAAYxS,KAAA;gBACV,IAAI,GAAA,QAAA,CAAA,MAAA;oBACFqQ,CAAAA,QAAAA,CAAAA,QAAAA,cAAAA,0CAAAA,oBAAqBmC,WAAA,CAAYxS;gBACnC,EAAA,CAAA,cAAQ,CAAC;oBACX;YAEAyS,OAAAA,SAAAA;gBACEjC,eAAe;qCACfH,sBAAsB,KAAA;YACxB,UAAA;wBACF;QACF,UAAA,UAAA,QAAA;QH07BA,WAAA,EAAA,uBAAA,UAAA,CAA0B,QAAA,cAA1B,2CAAA,qBAA0B,IAAA,CAAA,SAAA;QI9nCbqC,eAAAA,OAAkC,GAAA,aAAA;QAC7CC,SAAS,GAAA,UAAA,UAAA,IAAA;QACTC,UAAAA,KAAe,IAAA,QAAA;QACfC,YAAY,KAAA,SAAA,eAAA;MACZC,QAAQ;IACRC,UAAU;IACVC,KAAU,KAAA,KAAA,KAAA;;YACG,gBAIFC,OAAyB,MAUtBC,MACVD,KAAWE,EAX0BT,CAYlC,GJ8nCT,AI9nC8CO,oBCC5CG,MAEMC,IAEF,UAIAL,UAAUC,eAEVK;;;;yBD3BJC,CAAAA,OAAAA,IAAa,OAAA,iBAAA,iBAAA,OAAA,MAAA,cAAA,qCAAA,eAAA,MAAA,CAAA,GAAbA;;;;;;;;;;;;oBAEF;;wBAAA,OAAA,MAAA,CAAA,MAAA,CAAA,WAAA,IAAA;4BAAA;4BAAA;4BAAA;;;;oBAAA;oBAQO,GAASC,CAAAA,OAAAA,gBAAAA,aAAAA;wBACd,GAAOP,WAAWN,IAAAA,GAAA,WAAA,MAAA,CAAA;oBACpB,OAAA;wBAEgBO,OAAAA,SAAAA,mBAAAA;wBACVD,SAAWE,IAAAA,CAAA,EAAW,OAAOF,CAAAA,KAAAA,KAAWE,CAAAA,QAAA;wBAC5C,GAAO,CAAA,IAAqCF,GAAAA,GAA5BA,CAAAA,KAAAA,KAAWL,CAAAA,EAAAA,IAAAA,KAAa,EAAA,KAAqB,OAAjBK,WAAWH,MAAM,EAAA;4BAC/D,MAAA,CAAA,EAAA,GAAA,KAAA,UAAA,CAAA;wBAEO,CAASW,iBACd3U,UAAA,EACA4U,OAAA;wBAEA,GAAO,GAA6B5U,OAA1BmU,CAAAA,UAAWM,WAAW,EAAA,KAAkBG,OAAd5U,YAAU,KAAW,OAAP4U;oBACpD;oBJsnCA;;wBAA0B,OAAA,MAAA,CAAA,MAAA,CAAA,WAAA;;;oBAA1B,aAAA,CAA0B;oBKnqC1BC;;wBAAAA,KAAiBtW,CAAAA,IAAAA,CAAAA,EAAAU,EAAAA,MAAA,KAAA,IAAA,SAAA,GAAA,CAAA,SAAA;mCAAA,EAAA,QAAA,CAAA,IAAA,QAAA,CAAA,GAAA;2BAAA,IAAA,CAAA;;;;oBAcb6V,OAA4B,CAAA,IAAA,CAC5BR,KAAqB;;;;;;oBAuBvBA,OAAS;sBAET,EAAMC,EAAAA,GAAAA,GAAAA,CAAW,IAAA,MAAA,MAAA,EAAuD,KAAA,EAAtC7U,KAAKiC,MAAA,GAASE,QAAA,CAAS,IAAIkT,KAAA,CAAM,GAAG;wBAElE,OAAA,MAAA,UAAA,CAAA;4BACFD,GAAAA,CAAAA,KAASD,GAAAA,CAAAA,IAAAA,IAAAG,GAAAA,IAAAA,CAAKC,OAAA,CAAQjT,KAAK;gCACzBuS,MAAAA,IAAAA;8BACAN,UAAUE,WAAWF,QAAA;mCACXE,KAAAA,GAAAA,CAAAA,CAAWD,KAAAA,GAAA,KAAA,CAAA,IAAA,QAAA,CAAA,GAAA;wBACrBgB,QAAAA,GAAW,EAAA,GAAA,GAAA,QAAA,CAAA,IAAA,QAAA,CAAA,IAAA;6BACXV,EAAO,GAAA,MAAA,GAAA,QAAA,CAAA,IAAA,SAAA,CAAA,GAAA,IAAA,QAAA,CAAA,IAAA;;;2BACPW,aAAAA,IAAiB,QAAA,MAAA,EAAA,MAAA,CAAA,IAAA;;;;gBACjBC,gBAAgB;;YAChBC,cAAc,SAAA,UAAA;QAChB,iBAAA;MACF,EAAA,OAASC,KAAK,IAAA;YACZhB,GAAAA,KAAS,KAAA,OAAA;UACT5R,QAAQE,IAAA,CAAK,GAAM,OAAH2S,KAAG,sBAAqBD;QACxC,cAAA,sBAAA;MACF,EAAA,aAAA;QAEAR,OAAO7I,CAAA,CAAG,WAAW,OAAX,CAAW;UACnBqI,SAAS;UACT5R,CAAAA,MAAQ8S,IAAA,CAAK,IAAM,GAAoB,IAAHxT,GAAAA,EAAAA,EAApBuT,KAAG,EAAA,CAAA;IACrB;IAEAT,KAAU,EAAH7I,EAAA,CAAG,OAAa,CAAA,UAAA;;;;;0BACrBqI,SAAS,MAAA;4BACT5R;;4BAAAA,KAAQ8S,IAAA,CAAK,GAAM,OAAHD,KAAG;;sBACrB;oBAEU,KAAW;;wBAAA,UAAA,0BAAA;;;sBAArBT,OAAO7I,EAAA,CAAG,MAAA;0BACRqI;;wBAAAA,QAAS;;;;YACT5R,QAAQE,IAAA,CAAK,GAAM,OAAH2S,KAAG;;IACrB,KAAA,WAAA,UAAA;MAEAT,KAAAA,EAAO7I,EAAA,CAAG,GAAA,MAAS,SAACqJ,IAAAA;QAClBhB,SAAS;QACT5R,CAAAA,CAAQE,IAAA,CAAK,GAAM,OAAH2S,KAAG;;YAAA,gBAYnBE,mCAUF,iBArBA,YAEAX,GAAO7I,EAAA,CAAG,SAAS,AAInB;;;;;oBAPqB,UAAA,oEAAWqJ,CAAAA,GAAII,OAAO,qEAAA,CAAA;oBAC3C,aAAA;oBAEAZ,gBAAmB,CAAA,CAAA,QAAA,aAAA;0BACjB,IAAIR,SAAAA,EAAW,aAAa;gCAC1BA,GAAAA,CAAAA,KAAS,mCAAA,KAAA,SAAA,CAAA,YAAA,MAAA;0BACX;oBACF;;wBAAA,aAAA;;;oBAAA,WAAA;oBACF,IAAA,eAAA;wBAEO,KAASqB,GAAAA,GAAAA,CAAAA,sCAAAA;sBACd,IAAIjB,mBAAmB,CAACI,QAAQ;oBAC9BW,aAAAA,mBAAAA,MAAAA,SAAAA,cAAAA,8BAAAA,mBAAAA,aAAAA,GAAAA,IAAAA,OAAAA,WAAAA;sBACF;;wBAAA;4BACF,WAAA;4BAEO,KAASG,QAAAA,IACdC,KAAA,EACAxU,OAAA,GAAA;4BAEA,IAAI,CAACqT,UAAAA,EAAAA,CAAAA,IAAiB,OAAA;gCACpB,KAAA,qBAAO,MAAA,QAAA,6DAAA;4BACT,SAAA,GAAA,kBAAA,MAAA,QAAA,cAAA,6BAAA,kBAAA;4BAEAiB,YAAAA;2BAEA,CAAI,CAACb,MAAAA,EAAQ,aAAA,GAAA;4BAAA,mBAAA,QAAA,eAAA;wBAAA,IAAA,CAAA;;;;QAEb;;IAEA,IAAI,CAAA,gBAAA,UAAA,EAAA,OAAA,EAAA,IAAA;UACFA,OAAOgB,OAAA,CAAQD,OAAOE,KAAKC,SAAA,CAAU3U,UAAU;cAAE4U,EAAAA,GAAK9B,WAAW8B,GAAA,YAAA,UAAA;QAAI;QACrE,CAAO;wCAAA,UAAA;YAAA,SAGP,KAAO,QChGLC,YAAuB;;;;;oBD6FlB,UAAA,oEAAA,CAAA;sBACT,EAAA,CAAA,MAASZ,KAAK,aAAA;;;;;;;;;;;oBAEL;;wBAAA,uBAAA,SAAA;4BACT,UAAA;4BACF,UAAA;wBLwnCA,kCAAsC;;;oBK1nClC,cAAO;oBCnGLa,gBAAAA,MAAsB,MAAA,WAAA;wBACtBC,MAAAA;4BAAAA,SAAuB;;oBACvBC,oBAAuB;;;;;;oBACvBH;oBACAI,QAAAA,KAAAA,CACAC,EADgB,uBACW,uCAC3BC,wBAA0B;;;;;;;;;;;IAIhC,IAAMC,mBAAsB;;AAC5B,IAAMC,KAAAA,WAAsB;wCAAA,UAAA,EAAA,YAAA;YAAA,SAQnBC;;;;;oBARmB,UAAA,oEAAA,CAAA;;;;;;;;;oBAG5B,KAASC;;wBAAAA,cAAAA,YAAAA,SAAAA;4BACP,EAAI,CAACC,OAAAA,UAAiBA,kBAAkBC;4BACxC,KAAOD,MAAAA,aAAAA,SAAAA;wBACT;;;oBAHA;;;;;;oBAKSF;oBACP,IAAI,IAAA,GAAOI,EAAAA,CACX,KAAO,MADkB,aAAa,OAAO,UACFC,IAAA,CAAKD,UAAUE,KAC5D,IADqE;;;;;;;;;;;QAKnE,IAAMC,KAAKH,UAAUE,SAAA;;IACrB,IAAI,CAAA;wCAAA,QAAoCD,EAAAA,EAAA,CAAKE,KAAK,MAAA,CAAOd;YAAAA,SAOzD;;;;;oBAPyDA,UAAAA,oEAAAA,CAAAA;;;;;;;;;oBAEzD,IAAI;;wBAAA,MAAQY,IAAA,CAAKE,GAAAA,EAAoC,OAAOhB,GAAAA,SAAAA;4BAC5D,KAAOC,KAAAA;4BACT,WAAA,aAAA,SAAA;wBAEMgB,yBAAyB;;;;;;;;;oBAC7B;oBACA,QAAA,KAAA,CACA,6DACA;;;;;;;;;;;QAGA;;IACA,KAAA;wCAAA,UAAA,EAAA,gBAAA;YAAA,SAGF,aA6BMC;;;;;oBAhCJ,UAAA,oEAAA,CAAA;sBACA,EAAA,CAAA,WAAA,aAAA;;;;;;;;;;;oBAEF;;wBAAA,uBAAA,SAAA;4BAEMC,WAAAA,MAAmB,WAAA,EAAA,GAAA,IAAItI,IAAI;wBAAC;;;oBAFlC,cAAA;oBAE0C,gBAAA,YAAA,aAAA;oBAAO,gBAAA,YAAA,eAAA;wBAE1C,GAASuI,GAAAA,2BAA8BF,KAAA;4BAsBtCG;gCArBAC,WAAAA,GAAiBC,SAAAA,SAAAA;gCACjBC,eAAiBC,EAAAA;gCACjBC,GAAKR,KAAAA,IAAST,aAAAA,KAAAA;gCAEdkB,SACJL,GAAAA,WAAcK,MAAAA,EAAA,IACdC,GAAAA,qBACAJ,eAAeG,QAAA,IACdD,CAAAA,MAAMF,eAAeK,eAAA,KAAoB,OAAOnB,sBAAsB,KAAA,CAAA;4BACnEoB,eACJR,cAAcQ,YAAA,IACdC,iBAAiB,mBACjBA,iBAAiB,aACjBP,eAAeM,YAAA,IACfE,uBACCN,CAAAA,KAAK,WAAW,KAAA,CAAA;;oBAInB,IAAMG,kBACJF,YAAY,QACRN,OAAAA,wBAAAA,yBAAAA,cAAeY,yCAAfZ,kBAAAA,OAA8C,QAC9C,KAAA;;;;;;oBAEFH,IAAO;wBACT,IAAA,GAAO,EAAA,OACLA,OAAO,0DACPgB,YACEZ,cAAcY,UAAA,IACdH,iBAAiB,iBAChBL,CAAAA,KAAKlB,sBAAsBH,wBAAA;;;;;;;;;;;gBAW9BtW,WAAWoY;;SACPR,EAAAA,KAAW;wCAAA,UAAA;YAAA,SAAA,SACMG,cACWD,iBAAAA;;;;;oBAFjB,UAAA,oEAAA,CAAA,GAAA,QAAA,oEAAA,CAAA;8BAAEF,MAAAA,IAAAA,SAAAA;;;;;;;;;;;oBACIG;;wBAAAA,uBAAAA,SAAAA;;;;wBAAa,IAAI,CAAC,GACnCD,IAAAA,YAAAA,GAAmB,OAAO,GAAA;;;;;;;wBAAkB,IAAI,CAAC,IAAA,CAAA,oDAAA;;;;;;;;;;;;;IAKzD,OAAO,cAAA;QACLX,CAAAA,MAAO;SACHS,MAAAA,KAAW,eAAA,aAAA;YAAEA,UAAAA;MAAS,IAAI,CAAC,GAC3BG,eAAe;;yCACfD,IAAAA,WAAmB,OAAO;;oCADTC,cAAAA;cACWD,EAAAA,CAAAA,MAAAA,GAAAA,KAAAA,QAAAA,GAAAA,IAAAA;YAAgB,EAAI,CAAC,CAAA,OAAA,SAAA,UAAA;gBAEzD,IAAA,CAAA,gBAAA,CAAA;YAEO,GAASG,IAAAA,IAAAA,YAAAA,gCAAAA;gBACV,KAAA,EAAOnB,KAAAA,CAAAA,SAAAA,OAAc,aAAa;oBACpC,MAAO,KAAA,CAAA,CAAA,KAAA;gBACT;YAEA,EAAMG,KAAKH,UAAUE,SAAA;;;;;gCAErB,IAAI,aAAA,IAAiBD,CAAAA,GAAA,CAAKE,KAAK,OAAO;;oBACtC,EAAI,EAAA,aAAA,GAAoBF,GAAAA,CAAA,CAAKE,KAAK,GAAA,CAAA,GAAO,IAAA,MAAA,KAAA,CAAA,KAAA;oBACzC,EAAI,EAAA,CAAA,YAAA,OAAsBF,IAAA,CAAKE,KAAK,OAAO;oBAC3C,EAAI,SAAA,KAAA,CAAA,KAAA,OAAA,CAAA,SAAA,OAAoCF,IAAA,CAAKE,KAAK,OAAO;wBACrD,oCAAqBF,IAAA,CAAKE,CAAAA,IAAK,CAAA,CAAA,KAAO,KAAtC,uBAAA;wBACA,IAAA,KAAA,WAAoBF,IAAA,CAAKE,KAAK,OAAO;4BACzC,CAAO,GAAA,aAAA,MAAA,sBAAA,CAAA;4BACT,IAAA,eAAA,QAAA,MAAA,sBAAA,CAAA,SAAA;4BAEgBoB,MAAAA,MAAAA,CAAAA,YACdC,OAAA,EACAC,WAAA;wBAEI,CAACD,WAAW,CAACC,aAAa,OAAO;oBACrC,EAAMC,MAAMF,QAAQ7T,WAAA;gBACpB,IAAMgU,UAAUF,YAAY9T,WAAA;;;;gCAC5B,IAAI+T,QAAQC,SAAS,EAAA,GAAA,EAAO;oBAC5B,IAAA,CAAOrB,iBAAiBxJ,GAAA,CAAI4K,QAAQpB,iBAAiBxJ,GAAA,CAAI6K;wBAC3D,OAAA,mBAAA,IAAA,OAAA,CAAA,OAAA;oBAEO,EAAA,CAASC,MAAAA,GAAAA;wBACRnB,OAAAA,SAAgBC;oBACtB,EAAMC,iBAAiBC;gBACvB,IAAME,WACJL,cAAcK,QAAA,IACdC,wBACAJ,eAAeG,QAAA;;;;gCAEjB,IAAI,CAACA,EAAAA,IAAAA,EAAAA,IAAYe,CAAAA,kBAAmBf,aAAagB,aAAahB,WAAW;sBACvE,EAAA,GAAO,KAAA,CAAA,IAAA,CAAA,MAAA,CAAA,GAAA,CAAA,SAAA,EAAA;oBACT,OAAA,IAAA,CAAA,OAAA;oBAEA,IAAA,CAAOA,MAAAA,CAAAA,GAAAA,CAAAA,MAAAA;gBACT;;;gBAEO,KAAA;uBAAA,SAAA,KAASiB,GAAAA,IAAAA,gBAAsBC,UAAA;oBACpC,EAAI,EAAA,CAAA,IAAOzI,EAAAA,CAAAA,MAAAA,CAAAA,CAAW,aAAa;oBACjC,OAAO,KAAA;;;;gCACT,IAAA,IAAA;oBAEA,EAAMG,EAAAA,OAAWuI,EAAAA,IAAAA,CAAAA,MAAAA,CAAAA,GAAiBD,CAAAA;oBAClC,EAAItI,KAAAA,KAAU,KAAA,OAAA,MAAA,GAAA,KAAA,MAAA,CAAA,EAAA,KAAA,KAAA,IAAA,MAAA,CAAA,EAAA,GAAA;oBACZwI,kBAAkBF,YAAYtI;;;;oCAC9B,GAAA,IAAOA;oBACT,OAAA,IAAA,CAAA,MAAA,CAAA,GAAA,CAAA,SAAA,EAAA;gBAEA,IAAMzI,KAAK8O;;;;uBACXmC,aAAAA,IAAAA,UAAkBF,YAAY/Q;oBAC9B,KAAOA,EAAAA,IAAAA,CAAAA,MAAAA,CAAAA,GAAAA,CAAAA;gBACT;;;gBAEA,KAAA;uBAAA,SAAA,IAAA,CAASqQ,GAAAA,EAAAA,KAAAA;oBACP,EAAM5H,EAAAA,CAAAA,MAAAA,CAAAA,CAAWuI,EAAAA,CAAAA,MAAAA;wBAAAA,OAAiBxC;qBAAAA;gBAClC,IAAI/F,UAAU;;;oBACZwI;wCAAAA,QAAAA,MAAkBzC,yBAAyB/F;;sBAC3C,EAAA,CAAA,IAAOA,EAAAA,CAAAA,OAAAA,CAAAA,SAAAA,QAAAA;wBACT,OAAA,OAAA,CAAA,SAAA;4BAEMxQ,SAAAA,CAAY6W,MAAAA;wBAClBmC,cAAkBzC,yBAAyBvW;oBAC3C,KAAOA;gBACT;;;gBAEA,KAAA,AAAS+Y,iBAAiBD,UAAA;uBAA1B,SAAA;oBACE,IAAOd,CAAAA,OAAAA,EAAAA,MAAiBc,eAAeG,WAAWH;oBACpD,IAAA,CAAA,MAAA,CAAA,OAAA,CAAA,SAAA,QAAA;wBAEA,CAASE,MAAAA,OAAAA,CAAAA,SAAAA,GAAkBF,UAAA,EAAoBpa,KAAA;4BACzC,MAAA,IAAA,CAAA,GAAA,OAAA,mBAAA,MAAA,KAAA,OAAA,mBAAA;4BACF2R;uBAAAA,uBAAAA,OAAO6I,YAAA,cAAP7I,2CAAAA,qBAAqB8I,OAAA,CAAQL,YAAYpa;oBAC3C,OAAA,MAAA,EAAQ,CAAC,CAAA,CAAA;gBACT0a,YAAYN,YAAYpa;;;;;IAG1B,EAAM2a,KAAAA,eAAAA,GAAAA,QAA+B,KAAK,KAAK,KAAK,MAAM;AAE1D,SAASJ,WAAWrb,IAAA;IAClB,IAAI,CAAA,MAAOmM,aAAa,aAAa;UACnC,KAAA,EAAO,KAAA,SAAA,aAAA;QACT;MAEA,IAAI;;;oCACF,IAAMuP,SAAShG,mBAAmB1V,QAAQ;kBAE1C,OAAA,GAAA,wBAAA,2BAAA;;;;;wCAAA,EAAA,MAAA,YAAmB2b,0BAAnB,SAAA,6BAAA,QAAA,yBAAA,iCAA0B;4BAA1B,GAAA,CAAWC,CAAAA,MAAX;6BACE,GAAA,CAAMC,EAAAA,IAAAA,EAAQD,EAAAA,GAAK3T,GAAAA,CAAA,CAAA,IAAA;gCACnB,IAAI4T,GAAAA,GAAM9U,CAAAA,SAAA,CAAW2U,CAAAA,QAAS;oCAC5B,GAAA,IAAOI,CAAAA,kBAAmBD,MAAM3E,KAAA,CAAMwE,OAAOnW,MAAM,MAAM,KAAA;kCAC3D,GAAA,CAAA;4BACF,GAAA,IAAA,WAAA,MAAA;;4BALA,GAAA,IAAA,WAAA,SAAA,YAAA,OAAA;8BAAA,GAAA,IAAA,0DAAA,QAAA,qBAAA;;;sCAAA,CAAA,QAAA,CAAA,CAAA,WAAA,IAAA,KAAA,KAAA,IAAA,UAAA,CAAA,KAAA,IAAA;4CAAA,qEAMF,MAAA,GAAQ,CAAC,OAAA;wBAGX;oBAEA,GAASiW,YAAYxb,IAAA,EAAcc,KAAA;oBACjC,EAAI,KAAA,EAAOqL,EAAAA,WAAa,aAAa;oBACnC;;;;;MAGF,IAAI,CAAA,WAAA,GAAA;QACFA,SAAS4P,MAAA,GACPrG,mBAAmB1V,QACnB,MACA0V,mBAAmB5U,SACnB,qBACA2a,+BACA;IACJ,EAAA,GAAA,YAAQ,CAAC;IACX,IAAA,OAAA,YAAA,eAAA,CAAA,QAAA,SAAA,CAAA,OAAA,EAAA;QAEA,KAASxC,GAAAA,SAAAA,CAAAA,OAAAA,GAAAA,SAAAA,QAAAA;cAgBM+C,EAAAA,KACAA,SAAAA,IAAAA,CAAAA,WAAAA;YAhBb,EAAI,KAAA,EAAOC,EAAAA,CAAAA,IAAAA,CACT,GADoB,MACpB,MAAOA,GAD4B,OAAOA,OAAOC,UAAA,KAAe,YAAY;uBACrED,GAAOC,SAAAA,CAAA,MAAA,CAAA,YAAA,IAAA,CAAA;2BAAA;;eAChB,SAAA;uBAAA,YAAA,OAAA,CAAA,YAAA,IAAA,CAAA;oBAEMF,MAAQ,IAAIG,WAAW;gBACzB,OAAOF,WAAW,eAAe,OAAOA,OAAOG,eAAA,KAAoB,YAAY;;QAEnF,OAAO;UACL,IAAIC,OAAO1Y,KAAKC,GAAA,KAAQ/B,KAAKya,KAAA,CAAMC,mBAAmB;QACtD,IAAA,IAASC,IAAI,GAAGA,IAAI,IAAIA,IAAK;YAC3BH,OAAQA,OAAO,aAAa,QAAS;cACrCL,CAAAA,IAAA,CAAMQ,EAAC,GAAA,AAAKH,CAAAA,EAAAA,KAAOxa,KAAKya,KAAA,CAAMza,CAAAA,IAAKiC,MAAA,KAAW,IAAG,IAAK;YACxD,GAAA,MAAA,GAAA,SAAA,MAAA;YAAA,IAAA,IAAA,OAAA,UAAA,QAAA,UAAA,UAAA,OAAA,IAAA,OAAA,QAAA,OAAA,GAAA,OAAA,MAAA;gBAAA,QAAA,OAAA,KAAA,SAAA,CAAA,KAAA;;YACF,IAAA,UAAA,MAAA;gBAEAkY,CAAA,CAAM,EAAC,EAAA,CAAA,EAAMA,CAAAA,SAAAA,CAAAA,IAAA,CAAM,EAAC,cAAPA,qBAAAA,UAAY,KAAK,KAAQ;YACtCA,GAAA,CAAM,EAAC,GAAA,EAAMA,WAAAA,KAAA,CAAM,EAAC,cAAPA,sBAAAA,WAAY,KAAK,KAAQ;YAEtC,EAAIS,EAAAA,EAAM,GAAA,OAAA;YACV,EAAA,EAAA,CAASD,GAAAA,EAAI,EAAA,CAAGA,EAAAA,GAAI,CAAA,GAAIA,KAAK,MAAA,EAAA,IAAA;oBACnBR,aAAAA,OAAAA,CAAAA,EAAAA;gBAARS,IAAAA,GAAA,EAAQT,SAAAA,EAAAA,IAAAA,CAAA,CAAMQ,GAAC,cAAPR,sBAAAA,WAAY,GAAGhY,QAAA,CAAS,IAAI0Y,QAAA,CAAS,GAAG;oBAClD,IAAA,IAAA,WAAA,WAAA;wBAGED,GAAIvF,CAAAA,IAAA,CAAM,EAAA,CAAG,KACb,GAAA,CAAA,EACAuF,IAAIvF,KAAA,CAAM,EAAA,CAAG,IAAA,CAAA,CACb,MACAuF,IAAIvF,CAAAA,IAAA,CAAM,IAAI,CAAA,KACd,MACAuF,IAAIvF,KAAA,CAAM,IAAI,MACd,MACAuF,IAAIvF,KAAA,CAAM,IAAI;4BAElB,EAAA,CAAA,QAAA,GAAA,UAAA,CAAA,QAAA;wBAESqF;oBACH;gBACF,IAAI,OAAOI,gBAAgB,eAAe,OAAOA,YAAY/Y,GAAA,KAAQ,YAAY;kBAC/E,OAAO+Y,YAAY/Y,GAAA;cACrB,KAAA;QACF,EAAA,eAAQ,CAAC;MACT,OAAO;AACT;AAEA,SAASkW;MAKP,EAAA,CAAA,CAAI,KAAA,EAAOrH,EAAAA,EAAAA,OAAW,aAAa,OAAO,CAAC;QAE3C,IAAI,EAAA,IAAA,GAAA,SAAA,SAAA,EAAA,KAAA,EAAA,OAAA;gBACcA,QAAAA,OAAAA;cAAhB,EAAA,EAAMmK,UAAUnK,CAAAA,MAAAA,WAAAA,OAAeoK,OAAA,cAAfpK,sCAAAA,gBAAwBmK,MAAA;gBACxC,IAAIA,EAAAA,IAAAA,EAAQ,QAAA;kBACV,IAAME,OACJ,OAAOF,OAAOG,OAAA,KAAY,aAAaH,OAAOG,OAAA,KAAYH,OAAOE,IAAA;gBACnE,IAAI,EAAA,KAAOA,CAAAA,MAAAA,EAAS,GAAA,SAAYA,QAAQ,CAAC/B,mBAAmB+B,OAAO;oBACjE,IAAME,CAAAA,IAAAA,CACJ,KAAA,EAAOJ,OAAOK,YAAA,KAAiB,aAC3BL,OAAOK,YAAA,KACP,KAAA;qBACN,GAAA,GAAA,CAAO,GAAA,KAAA,IAAA;4BACLjD,UAAU8C;8BACV3C,EAAAA,MAAAA,IAAAA,CAAAA,CAAc,QAAA,KAAA,CAAA,EAAA,EAAA;2BACV,OAAO6C,QAAQ,YAAY;8BAAE9C,EAAAA,KAAAA,CAAAA,EAAAA,OAAiB8C;wBAAI,IAAI,CAAC;kBAE/D;cACF,KAAA;QACF,EAAA,eAAQ,CAAC;MAET,IAAI;QACF,IAAME,WAAYzK,OAAeyK,QAAA;QACjC,CAAA,GAAIA,UAAU;kBAINA,OAAAA,CAAAA,UAAAA,EAAAA;gBAHN,IAAMC,IAAAA,CAAAA,IACJ,MAAA,CAAOD,EAAAA,OAASE,EAAAA,IAAA,EAAA,EAAA,CAAW,EAAA,WACvBF,SAASE,MAAA,MACTF,mBAAAA,SAASC,MAAA,cAATD,8BAAAA,mBAAmBA,SAASE,MAAA;kBAClC,CAAA,GAAI,IAAA,GAAOD,GAAAA,IAAAA,IAAW,CAAA,WAAYA,QAAQ;sBACxC,CAAA,CAAA,EAAInC,OAAAA,CAAAA,KAAamC,MAAAA,GAAS,IAAA,MAAA,MAAA;wBACxB,OAAO;0BAAEhD,cAAc;wBAAUD,iBAAiB;oBAAK;kBACzD,OAAA,CAAA,QAAA,EAAA;oBACA,IAAI,CAACa,QAAAA,GAAAA,QAAmBoC,CAAAA,MAAAA,EAAS,MAAA;0BAC/B,CAAA,KAAA,CAAO,IAAA,SAAA,IAAA,CAAA,MAAA,EAAA;gCAAEnD,IAAAA,MAAUmD;8BAAQhD,cAAc;8BAAUD,GAAAA,CAAAA,SAAAA,IAAiB,GAAA,MAAA,EAAA,YAAA;wBAAM;kBAC5E;YACF;QACF,CAAA;MACF,EAAA,CAAA,OAAA,OAAQ,CAAC,CAAA,CAAA,QAAA,EAAA;QAET,IAAI,GAAA,SAAA,CAAA,QAAA,GAAA,SAAA,MAAA,EAAA,KAAA;cACF,EAAA,EAAMmD,KAAAA,EAAQ5K,OAAe6K,CAAAA,GAAA,OAAA;gBAC7B,IAAID,IAAAA,EAAM;kBACR,IAAME,OACJ,OAAOF,KAAKG,oBAAA,KAAyB,aACjCH,KAAKG,oBAAA,KACLH,KAAKE,IAAA;kBACX,IAAI,EAAA,KAAOA,EAAAA,MAAAA,CAAS,EAAA,IAAA,CAAA,KAAYA,CAAAA,EAAAA,KAAQ,CAACxC,mBAAmBwC,OAAO;wBACjE,OAAO;0BAAEvD,UAAUuD;0BAAMpD,KAAAA,CAAAA,QAAc,WAAA,CAAA;wBAAQD,iBAAiB;kBAAM;YACxE;QACF,CAAA;MACF,EAAA,eAAQ,CAAC;MAET,OAAO,CAAC;IACV;IAEA,EAAMuD,wBAA6C,aAAA,GAAA,IAAIvM,IAAI;MACzD;MACA;IACD;IAED,OAAS6J,mBAAmBja,KAAA;IAC1B,IAAM4c,IAAI5c,MAAMmH,IAAA;AAKlB,0BAAA;AAEA,IAAA,KAAS+S,aAAala,KAAA,IAAA;IACpB,OAAO2c,kBAAAA,IAAsBzN,GAAA,CAAIlP,MAAMmH,IAAA,GAAOpB,WAAA;AAChD,IAAA,kBAAA;AAEA,IAAA,KAAS+S,oBAAAA;MAQP,IAAI,OAAOnH,WAAW,aAAa;UACjC,OAAO,CAAC;MACV;MAEA,IAAMkL,aAAa;UAChBlL,OAAemL,0BAAA;UACfnL,OAAeoL,kBAAA;UACfpL,OAAeqL,aAAA;UACfrL,OAAesL,MAAA;UACftL,OAAeuL,OAAA;UACfvL,OAAewL,KAAA;UACfxL,OAAeyL,KAAA;QACfzL,OAAe0L,MAAA;KAClB,CAAEC,MAAA,CAAOC,0BAAAA;;YAET,KAAA;QAAA,UAAA,SAAA,SAAA,IAAA;mBAAA,IAAA,QAAA;;IAAA,UAAA;;;;;;;;YAAA,KAAA,GAAA,YAAqBV;QAAAA,UAArB,SAAqBA,KAArB,IAAA,GAAA;mBAAA,IAAA,QAAA;;IAAA,WAAA,QAAA,yBAAA,iCAAiC;;gBAAjC,CAAA,GAAWrV,SAAX;QAAA,UAAA,SAAA,SAAA;mBAAA,IAAA,QAAA;;IAAA;;gBACE,CAAA,GAAMiS;kBACJ+D,SAAAA,SAAAA,KAAgBhW;mBAAAA,IAAAA,CAAQ,WAAA;;IAAA;;oBAAC;QAAA,UAAA,SAAA,SAAA;mBAAA,IAAA,QAAA;;IAAA;;oBAAc;QAAA,UAAA,SAAA,SAAA;mBAAA,IAAA,QAAA;;IAAA;;oBAAO;QAAA,UAAA,SAAA,SAAA;mBAAA,IAAA,YAAA;;IAAA;;oBAAY;QAAA,UAAA,SAAA,SAAA;mBAAA,IAAA,QAAA;;IAAA;;iBAAe,KACzE,KAAA;QAAA,UAAA,SAAA,SAAA;mBAAA,IAAA,eAAA,IAAA,OAAA,IAAA,eAAA,GAAA,MAAA,MAAA,KAAA;;IAAA;;gBACF,CAAA,GAAMiW,QACJD,gBAAgBhW;QAAAA,UAAQ,SAARA,MAAQ,GAAA;mBAAA,IAAA,YAAA;;IAAA;;oBAAC;QAAA,UAAA,SAAA,SAAA;mBAAA,IAAA,QAAA;;IAAA;;oBAAS;QAAA,UAAA,SAAA,SAAA;mBAAA,IAAA,eAAA,IAAA,OAAA,IAAA,eAAA,GAAA,MAAA,MAAA,KAAA;;IAAA;;oBAAQ;QAAA,UAAA,SAAA,SAAA;mBAAA,IAAA,KAAA;;IAAA;;oBAAiB;QAAA,UAAA,SAAA,SAAA;mBAAA,IAAA,OAAA;;IAAA;;iBAAc,KACzE,KAAA;QAAA,UAAA,SAAA,SAAA;mBAAA,IAAA,SAAA;;IAAA;;gBACF,CAAA,GAAMkW,UACJF;QAAAA,UAAgBhW,SAAhBgW,SAAgBhW,MAAQ;mBAAA,IAAA,UAAA;;IAAA;gBAAC;gBAAW,aAAA,KAAA;kBAAM,KAAA,OAAA;aAAkB,KAAK,KAAA,CAAA,IAAA;cACnE,IAAM0R,OAAAA,IACJsE,gBAAgBhW,QAAQ;kBACtB,eAAA,IAAA,CAAA,UAAA,OAAA;kBACA,6CAAA,IAAA,CAAA;gBACA;gBACA;kBACA,QAAA,eAAA,OAAA,eAAA,EAAA;oBACA;gBAGA,OAAA;oBAFA,EAAA,IAAA,YAAA;sBACA,YAAA,CAAA;oBACA,IAAA,EAAA,QAAA,GAAA,CAAA,EAAA,cAAA,mBAAA,QAAA,KAAA,UAAA,CAAA,EAAA,SAAA,GAAA,CAAA,EAAA,cAAA,oBAAA,SAAA,KAAA,OAAA;sBACA,EAAA,GAAA;wBACA,MAAA;mBACD,KAAK,KAAA;yBAER,IAAI,CAACiS,IAEL,IAAMJ,MAFa,CAACH,QAGlBsE,IAH8B,CAACC,SAAS,CAACC,CAGzBlW,QAHkC,AAG1B;kBACtB;kBACA,KAAA,KAAA,CAAA,KAAA,MAAA,KAAA,OAAA,gBAAA,IAAA;gBACA;gBACA,uBAAA,OAAA,EAAA,GAAA;eACD,KAAK+R;;;4BACgBoE,cAAkBnW,QAAQ,kFAAlD,qDAAkD;2CAAlD,sBAAA,CAAM4R,QAAAA,uBAAAA,UAAkBuE;sBACtB,EAAA,SAAA;wBACA,CAAA,QAAA,UAAA,IAAA;0BACA,OAAA,CAAA,SAAA,mBAAA;wBACA;mBACD;;;;;;;;;;;;;;;cAED,OAAO,mBACDlE,aAAa;gBAAEA,YAAAA;YAAW,IAAI,CAAC,GAC/BgE,QAAQ,OAAA,MAAA,EAAA,GAAA;QAAEA,eACVC;gBADUD,KAAAA,gBAAAA,IAAAA,QAAAA,cAAAA,oCAAAA,GAAAA,WAAAA,IAAAA;YAAM,IAAI,CAAC,GACrBC,EAAAA,EAAAA,oBAAAA,IAAAA,IAAU,QAAA,cAAVA,wCAAAA,kBAAU,IAAA,OAAA;gBAAEA,EAAAA,OAAAA,GAAAA,CAAAA;YAAQ,IAAI,CAAC,CAAA,EACzBxE,KAAAA,GAAAA,CAAAA,EAAW;gBAAEA,CAAAA,OAAAA,EAAAA,CAAAA,CAAAA;YAAS,IAAI,CAAC,EAAA,CAC3BA,GAAAA,SAAYG,MAAAA,IAAAA,KAAe,EAAA,IAAA,eAAA,GAAA,MAAA,MAAA,KAAA;kBAAEA,CAAAA,aAAAA;gBAAa,EAAA,CAAA,CAAI,CAAC,GAC/CH,GAAAA,SAAYE,mBAAmB,OAAO;oBAAEA,SAAAA,QAAAA,OAAAA,WAAAA;gBAAgB,EAAA,CAAA,CAAI,CAAC,QAAA,qBAAA,sBAAA,WAAA,oBAAA,UAAA,MAAA;YAErE;;QAhDA,eAAA,QAAA,WAAA,CAAA,oBAAA;QAAA,eAAA,QAAA,WAAA,CAAA,oBAAA;;;qBAAA,CAAA,4BAAA;oBAAA,CAAA,CAAA;;;kBAAA,IAAA;0BAAA,MAAA,YAAA,aAAA;;;;YAkDA,KAAO,CAAC,CAAA,GAAA,CAAA,UAAA,qBAAA,sBAAA,WAAA;QACV;QAEA,KAASoE,gBAAgBhW,MAAA,EAAaC,IAAA;UACpC,kCAAA,2BAAA;;UAAA,CAAA,MAAA,CAAA,YAAkBA,yBAAlB,SAAA,6BAAA,QAAA,yBAAA,iCAAwB;cAAxB,GAAA,CAAW/H,MAAX;YACE,IAAMM,QAAQwH,mBAAAA,6BAAAA,MAAA,CAAS9H,IAAG;YAC1B,IAAI,OAAOM,UAAU,GAAA,MAAA,EAAA,CAAYA,MAAAA,CAAO;gBACtC,GAAA,EAAA,EAAOA;cACT,IAAA,CAAA,SAAA,QAAA;gBACA,IAAI,OAAOA,UAAU,MAAA,IAAA,CAAA,CAAY,KAAA;sBAC/B,GAAA,CAAI;wBACF,IAAM4d,SAAS5d,MAAML,IAAA,CAAK6H;sBAC1B,IAAI,OAAOoW,WAAW,YAAYA,QAAQ;0BACxC,CAAA,MAAOA,EAAAA,CAAAA,MAAAA;;;gCACT,QAAA,KAAA,CAAA,KAAA,KAAA,CAAA,+HAAA;yBAAA;wBACF,EAAA,IAAA,OAAA,IAAQ,CAAC,IAAA;sBACX,QAAA;kBACF,OAAA,IAAA,CAAA,QAAA,IAAA,OAAA,UAAA;;;;;;;;;;;;;;;;UAbA;;;iBAAA,YAAA,IAAA,IAAA,2IAAA;gBAAA;;;;;;;;;;;;;;;;;iBAAA,6BAAA;gBAAA,aAAA,GAAA;;;kBAAA,IAAA,IAAA;wBAAA,EAAA,YAAA,CAAA,GAAA,CAAA;;;;gBAcA,GAAO,CAAA,IAAA,GAAA,uBAAA,IAAA,CAAA,MAAA;oBACT,gBAAA,IAAA,CAAA,IAAA,IAAA;gBAEA,CAASD,kBAAkBnW,MAAA,EAAaC,IAAA;cACtC,kCAAA,2BAAA;;gBAAA,IAAA,EAAA,YAAkBA,EAAAA;oBAAAA,QAAAA,OAAAA;iBAAlB,CAAkBA,OAAAA,qBAAlB,SAAA,SAAA,MAAA,CAAA,SAAA,IAAA,CAAA,QAAA,yBAAA,iCAAwB;oBAAxB,IAAW/H,MAAX,EAAA,CAAA,OAAA,CAAA,SAAA,QAAA;sBACE,EAAA,EAAMM,KAAAA,GAAQwH,mBAAAA,CAAAA,IAAAA,CAAAA,MAAAA,iBAAAA,MAAA,CAAS9H,IAAG;wBAC1B,IAAMme,YAAAA,CAAaC,MAAAA,CAAAA,UAAiB9d;sBACpC,IAAI6d,cAAc,MAAM;wBACtB,OAAOA;oBACT,YAAA,CAAA,GAAA,CAAA,MAAA;oBACA,GAAA,CAAI,GAAA,IAAO7d,IAAAA,GAAAA,GAAU,IAAA,OACnB,CAD+B,GAC3B,4BACF,IAAM4d,GAAAA,MAASE;2BAAAA,SAAAA,IAAAA,EAAiB9d,KAAAA,CAAML,IAAA,CAAK6H,EAAAA;;8BAEzC,OAAOoW;wBACT;oBACF,EAAA,aAAA,EAAQ,CAAC,CAAA,YAAA;gBACX,GAAA,QAAA;UACF,WAAA;;UAdA;QAAA;;;mBAAA,6BAAA;kBAAA;;;oBAAA,qBAAA,aAAA,IAAA,UAAA;wBAAA;;;;MAeA,KAAA,EAAO,CAAA,CAAA,GAAA,KAAA,IAAA,gBAAA;IACT,IAAA,IAAA,KAAA,EAAA;;;YAEA,oBAASzE,iFAAAA,kEAAAA;oBAAAA;kBACP,KAAA,MAAA,CAAA,sBAAA,2BAAA;;;;;;;;;;;;;;;;UAAA,QAAA,YAAkBX,2CAAlB,SAAA,6BAAA,QAAA,yBAAA,iCAA0C;cAA1C,CAAA,GAAW9Y,CAAAA,KAAX,CAAA;gBACE,EAAA,CAAA,CAAMM,MAAAA,EAAQsZ,KAAAA,IAAAA,GAAAA,KAAiB5Z;cAC/B,IAAIM,OAAO;kBACT,OAAOA;cACT,GAAA,CAAA;UACF,EAAA,gBAAA,IAAA,MAAA;;UALA;UAAA,EAAA,gBAAA,IAAA,MAAA;;;mBAAA,EAAA,IAAA,MAAA,iBAAA;oBAAA,OAAA,OAAA,KAAA,GAAA,CAAA,GAAA,KAAA,KAAA,CAAA,IAAA,SAAA;;;kBAAA,EAAA;0BAAA;;;;MAMA,KAAA,EAAO,KAAA;QACT,IAAA,cAAA,OAAA,GAAA,CAAA,UAAA;QAEA,IAAA,CAASsZ,eAAAA,EAAiB5Z,EAAAA,CAAA,cAAA;YACxB,EAAI,KAAA,EAAOiS,IAAAA,CAAAA,MAAW,aAAa;cACjC,KAAA,EAAO,IAAA,CAAA;QACT;MAEA,IAAI;cACYA,aAAAA,IAAAA,MAAAA;YAAd,GAAA,CAAM3R,EAAAA,CAAAA,MAAQ2R,IAAAA,IAAAA,eAAAA,GAAAA,IAAO6I,EAAAA,UAAA,cAAP7I,2CAAAA,qBAAqBoM,OAAA,CAAQre;UAC3C,OAAOM,SAAS,KAAA;MAClB,EAAA,IAAA,WAAQ,GAAA,IAAA,MAAA;YACN,GAAA,GAAA,CAAO,KAAA,EAAA,IAAA,cAAA,GAAA,SAAA;MACT;IACF,IAAA,IAAA,KAAA,EAAA;QAEA,KAASwZ,EAAAA,GAAAA,CAAAA,QAAAA,IAAAA,KAAAA;MACP,OAAOsE,iBACLxE,iBAAiB,sBACfA,iBAAiB,wBACjBA,iBAAiB;IAEvB,IAAA,IAAA,OAAA,EAAA;QAEA,KAASwE,iBAAiB9d,KAAA,QAAA,IAAA,OAAA;QACxB,IAAI,GAAA,GAAA,CAAOA,MAAAA,IAAU,OAAA,IAAW;UAC9B,OAAOA;MACT,EAAA,IAAA,SAAA,EAAA;QACA,IAAI,GAAA,GAAA,CAAOA,OAAAA,GAAU,CAAA,SAAU;UAC7B,OAAOA,UAAU;MACnB,EAAA,IAAA,cAAA,IAAA,MAAA;QACA,IAAI,GAAA,GAAA,CAAOA,OAAAA,GAAU,IAAA,IAAA,EAAU,YAAA;UAC7B,CAAA,GAAM6d,CAAAA,IAAAA,KAAAA,EAAAA,CAAa7d,MAAM+F,WAAA;YACzB,GAAA,CAAI8X,EAAAA,CAAAA,OAAAA,KAAe,OAAOA,eAAe,UAAUA,eAAe,OAAO;cACvE,OAAO;UACT,oBAAA,QAAA;UACA,GAAA,CAAIA,IAAAA,EAAAA,SAAe,OAAOA,eAAe,WAAWA,eAAe,MAAM;cACvE,OAAO,CAAA,IAAA,OAAA;+DACT,QAAA,IAAA,KAAA,MAAA;YACF,OAAA,GAAA,CAAA,QAAA,QAAA,IAAA;QACA,OAAO,KAAA;QACT,IAAA,CAAA,oBAAA,8BAAA,QAAA,WAAA,KAAA,MAAA;YN+lCA,OAAA,GAAA,CAAA,OAAwB,SAAA,QAAA,WAAA;QOtlDpBG,kBAAiC;QAE9B,IAAA,CAAA,AAASC,oBAAT,8BAAA,QAASA,SAAAA,KAAAA,CACdC,KAAAA,CAAA;YAEA,EAAMC,KAAAA,GAAAA,CAAAA,CAAkC,CAAC,YAAA,QAAA,SAAA;QACzC,IAAID,OAAOE,aAAA,EAAe;UACxBD,QAAQC,aAAA,GAAgB;MAC1B,EAAA,IAAA,MAAA,EAAA;QACA,IAAIF,GAAAA,GAAAA,CAAOG,UAAAA,EAAA,KAAiB,KAAA,GAAW;UACrCF,QAAQG,eAAA,GAAkBJ,OAAOG,YAAA,GAAe,SAAS;MAC3D,EAAA,YAAA,EAAA;MACA,KAAA,EAAOF,KAAAA,CAAAA,SAAAA,OAAAA;QACT,IAAA,oBAAA,QAAA;YAEO,GAASI,OAAAA,IAAAA,CAAAA;YASLC,SACCA,UACIA,UACCA,UACCA,qBAAAA,UACFA,UAwHV7M,SAA6BA,UAO/BA,4BAAAA,gBAsBWyG;MAlKb,IAAMG,KAAKH,UAAUE,SAAA;QACrB,mCAAA,4BAAA;;UAAA,MAAA,aAAiBF,SAAUqG,qBAA3B,UAAA,8BAAA,CAAMA,QAAN,0BAAA,kCAA2BA,MAAA;YAA3B,IAAMA,MAAWrG,CAAjB;YACA,IAAMsG,GAAAA,MAAStG,CAAAA,SAAUsG,MAAA,IAAU;UACnC,IAAMC,iBAAiBvG,UAAUuG,cAAA,IAAkB;;QAFnD;QAAA;;;iBAAA,8BAAA;gBAAA;;;gBAAA;sBAAA;;;;MAGA,IAAMC,SAAUxG,UAAkByG,EAAAA,QAAAA,EAAA,EAAA,EAAgB,KAAA;MAClD,IAAMC,CAAAA,IAAAA,QAAAA,SAAsB1G,UAAU0G,mBAAA,IAAuB;IAE7D,IAAMC,aAAa;QACjBpb,CAAAA,IAAA,GAAO6a,UAAAA,SAAAA,OAAAA,EAAAA,EAAAA,QAAAA,sBAAAA,QAAQ7a,KAAA;QACfU,MAAA,GAAQma,SAAAA,EAAAA,oBAAAA,+BAAAA,SAAQna,MAAA;UAChB2a,UAAA,GAAYR,CAAAA,IAAAA,CAAAA,KAAAA,KAAAA,eAAAA,+BAAAA,SAAQQ,UAAA;YACpBC,GAAAA,QAAA,GAAaT,IAAAA,CAAAA,MAAAA,WAAAA,QAAAA,QAAAA,OAAAA,MAAAA,SAAQS,WAAA;UACrBC,aAAcV,EAAAA,WAAAA,oBAAAA,gCAAAA,sBAAAA,SAAQU,WAAA,cAARV,0CAAAA,oBAA6B1Y,IAAA,KAAQ;QACnDqZ,MAAAA,IAAA,GAAYX,CAAAA,QAAAA,CAAAA,CAAAA,MAAAA,MAAAA,QAAAA,+BAAAA,SAAQW,UAAA;MACtB,KAAA,GAAA,OAAA,SAAA,OAAA,KAAA,eAAA,OAAA;IAEA,IAAIC,aAAqD;IACzD,IAAIC,CAAAA,OAAQ;QAAA,YAAA,iEAAA;MACZ,EAAIC,KAAK,KAAA,CAAA;MACT,EAAA,EAAIC,KAAAA,GAAQ,QAAA,aAAA;QACZ,IAAIC,GAAAA,QAAAA,CAAY,MAAA,CAAA;MAChB,IAAIC,YAAY;MAChB,EAAIC,QAAAA,EAAAA,EAAY;MAChB,EAAIC,SAAAA,EAAW,KAAA,QAAA;MAEf,EAAA,EAAIpH,GAAGhV,EAAAA,MAAA,CAAS,IAAA,MAAU,MAAA;YACxB8b,EAAAA,IAAAA,EAAQ,CACRC,EAAAA,GAAK,KAAA,SAAA;YACLE,IAAAA,QAAY,EAAA;YACZJ,IAAAA,SAAa;gBACb,EAAMQ,KAAAA,QAAarH,GAAGsH,KAAA,CAAM,GAAA,GAAA,SAAA,QAAA;oBAC5BN,IAAQK,SAAAA,IAAa,SAAsB,OAAbA,UAAA,CAAW,EAAE,IAAK;oBAClD,GAAWrH,CAAAA,EAAGhV,QAAA,CAAS,UAAU,CAAA,OAAA,WAAA,KAAA,cAAA,OAAA,WAAA,KAAA,oBAAA,GAAA;wBAC/B8b,EAAQ,QAAA;wBACH,QAAA,IAAA,GAAA,OAAA,WAAA,GAAA,MAAA;wBACLG,IAAAA,EAAY,KAAA,OAAA,QAAA,KAAA,YAAA,OAAA,QAAA,EAAA;4BACZJ,KAAa,GAAA,WAAA,GAAA,OAAA,QAAA;wBACPU,WAAavH,GAAGsH,KAAA,CAAM;wBACtBE,IAAAA,IAAUxH,GAAGsH,KAAA,CAAM,+BAA+B,aAAa;4BAC7DC,OAAAA,MACJ,SAA0BC,OAAjBD,CAAAA,GAAAA,MAAA,CAAW,EAAE,EAAA,CAEjBvH,EAAGhV,CAAAA,CAFyB,MAEzB,CAFkBwc,AAET,SAFmB5Y,AAEnB,GAAY,CAFO,KACpC;wBAEJkY,EAAQ,eAAA,CACH;wBACLG,MAAY;oBACZJ,SAAa;gBACf,CAAA,IAAW7G,GAAGhV,QAAA,CAAS,YAAYgV,GAAGhV,QAAA,CAAS,UAAU;YACvD8b,EAAAA,eAAQ;gBACRC,GAAK;YACLE,YAAY;YACZJ,WAAAA,EAAa;gBACf,CAAA,GAAA,CACE7G,GAAGhV,MAAAA,EAAA,CAAS,cACXgV,CAAAA,GAAGhV,QAAA,CAAS,WAAWmb,OAAOnb,QAAA,CAAS,OAAM,GAC9C;oBACA8b,IAAQ,MAAA;oBACRC,CAAK;gBACLE,UAAY;YACZJ,GAAAA,UAAa;QACf,KAAA,IACE7G,GAAGhV,QAAA,CAAS,cACXgV,CAAAA,GAAGhV,QAAA,CAAS,cAAcgV,GAAGhV,QAAA,CAAS,KAAI,GAC3C;UAEA+b,KAAK;QACLE,SAAAA,GAAY,IAAA,QAAA;UACZJ,KAAAA,QAAa,GAAA,YAAA;QACf,MAAA,CAAA,GAAA,CAAW7G,EACT8G,CADY9b,CACZ8b,MAAQ,CADI,CAAS,AACb,SAAA,GADyB9G,GAAGhV,QAAA,CAAS,UAAU;YAEvD+b,IAAAA,CAAK;gBACLE,OAAAA,GAAY,WAAA,GAAA,SAAA,MAAA;oBACZJ,IAAAA,KAAa,MAAA,QAAA,iBAAA,2BAAA,KAAA,SAAA,MAAA,YAAA,KAAA,SAAA,EAAA;wBACf,CAAW7G,GAAGhV,IAAAA,IAAA,CAAS,IAAA,GAAA,KAAY,SAAA;oBACjC8b,IAAQ;oBACRC,CAAK;gBACLE,UAAY;YACZJ,EAAAA,eAAAA,KAAa;gBACf;YAEI7G,GAAGhV,QAAA,CAAS,YAAY;YAC1Bkc,WAAAA,CAAY,QAAA;UACZH,KAAK;UAGL,IACE/G,GAAGhV,QAAA,CAAS,cACXob,CAAAA,mBAAmB,KAClBpG,GAAGhV,QAAA,CAAS,gBACZgV,GAAGhV,QAAA,CAAS,SAAQ,GACtB;cACA6b,MAAAA,KAAAA,EAAa,CAAA;gBACbI,OAAAA,KAAY,EAAA,CAAA;cACZH,QAAQA,UAAU,YAAY,eAAeA;UAC/C,CAAA,QAAA,GAAA,CAAA,OAAA,IAAA,CAAA;eAAA;;QAEA,IAAMW,oBAAoBzH,GAAGsH,KAAA,CAAM;YAEjCN,QAAQS,SAAAA,QAAA,CAAkB,EAAC;QAC7B,CAAA,iBAAA,EAAA;MACF,EAAA,QAAA,GAAA,KAAA,CAAA;MAEA,IAAI,CAAA,SAAA,KAAA,CAAA,EAAA,CAAmB3H,EAAAA,EAAA,CAAKE,KAAK,CAAA,KAAA,CAAA,EAAA,EAAA,MAAA;QAC/B+G,KAAK;QACLF,CAAAA,YAAa,KAAA,EAAA;QACbC,QAAQ,GAAA,KAAA,CAAA;UACR,CAAA,GAAIjH,MAAAA,IAAUuG,CAAAA,CAAAA,EAAAA,GAAAA,OAAA,EAAA,CAAiB,IAAA,CAAK,EAAA,EAAA,GAAOtG,GAAAA,CAAA,CAAKE,KAAK;YACnD6G,aAAa;QACf,CAAA;QACF;MAAA,EAAA,mBAAA,eAAA,2BAAA,UAAA,aAAA,cAAA,+CAAA,yBAAA,QAAA,GAAA;QAEA,IAAI,CAACK,EAAAA,UAAAA,CAAa,CAACD,WAAAA,CAAAA,CAAa,CAAC,MAAA,GAASnH,IAAA,CAAKE,KAAK;UAClD,IAAIA,GAAGhV,QAAA,CAAS,YAAY;YAC1B+b,CAAAA,IAAK,MAAA,SAAA;cACLF,aAAa,KAAA,IAAA,CAAA,KAAA;YACf,GAAA,IAAA,IAAW7G,GAAGhV,QAAA,CAAS,IAAA,CAAA,KAAU,CAAC,SAAS8U,EAAAA,EAAA,CAAKE,KAAK;cACnD+G,KAAK;cACLF,CAAAA,IAAAA,CAAAA,KAAAA,EAAa;gBACb,IAAIT,iBAAiB,GAAGS,aAAa;UACvC,OAAA,IAAW7G,GAAGhV,QAAA,CAAS,UAAU;cAC/B+b,GAAAA,EAAK,EAAA,CAAA,KAAA;gBACLF,UAAAA,GAAa,CAAA,CAAA,MAAA,iBAAA;UACf;MACF,EAAA,QAAA,IAAA,CAAA,KAAA;QAEA,IAAIC,GAAAA,OAAU,WAAW;UACvB,IAAIX,OAAOnb,QAAA,CAAS,aAAagV,GAAGhV,QAAA,CAAS,WAAW8b,QAAQ;UAChE,CAAA,GAAIX,OAAOnb,QAAA,CAAS,GAAA,OAAU8b,QAAQ;QACtC,IAAIX,OAAOnb,QAAA,CAAS,cAAcgV,GAAGhV,QAAA,CAAS,QAAQ8b,QAAQ;IAChE,KAAA;MAEAK,EAAAA,KAAAA,GAAY,OAAA,SAAA,OAAuBrH,IAAA,CAAKE;MAExC,EAAI5G,EAAAA,SAAAA,CAAAA,oBAAAA,8BAAAA,QAAQsO,WAAA,MAAgB,KAAKtO,EAAAA,WAAAA,oBAAAA,+BAAAA,SAAQuO,UAAA,MAAe,GAAG;UACzDR,KAAAA,OAAY;MACd,EAAA,UAAA;MAEAC,EAAAA,SACEhO,MAAAA,CAAOwO,UAAA,CAAW,8BAA8BC,OAAA,IAC/CzO,OAAOyG,SAAA,CAAkBiI,UAAA,KAAe,QACzC1O,EAAAA,iBAAAA,OAAO6M,MAAA,cAAP7M,sCAAAA,6BAAAA,eAAeuN,WAAA,cAAfvN,iDAAAA,2BAA4B2O,KAAA,MAAU,KAAA;MAExC,EAAA,KAAO,OAAA;UACLjB,OAAAA,IAAAA;UACAC,IAAAA,aAAAA;UACAC,OAAOA,SAAShH,GAAGhO,SAAA,CAAU,GAAG,MAAM;UACtC6U,YAAAA;UACAI,WAAAA;QACAC,WAAAA,KAAAA,iBAAAA;QACAC,WAAAA,KAAAA,iBAAAA;UACAC,UAAAA,GAAAA,gBAAAA,IAAAA,gBAAAA,KAAAA;UACAY,QAAQ5O,OAAO+B,QAAA,CAAS8M,MAAAA,EAAA,EAAA,CAAA,KAAA;YACxBC,GAAAA,KAAQ9O,OAAO+B,QAAA,CAAS+M,MAAA;YACxBC,MAAM/O,EAAAA,KAAO+B,QAAA,CAASiN,QAAA;YACtBrI,QAAAA,GAAWC,KAAAA,CAAAA,2BAAAA,GAAAA,KAAAA,CAAAA;YACXmG,CAAAA,OAAAA,EAAAA,CAAAA,KAAAA,CAAAA,EAAAA,EAAAA;cACAD,MAAAA,GAAAA,CAAAA,IAAAA,CAAAA,8BAAAA,GAAAA,KAAAA,CAAAA;YACAD,QAAQO;YACRD,SAAAA,KAAAA,CAAAA,EAAAA,EAAAA,EAAAA;cACAD,QAAAA,KAAAA,CAAcD,EAAAA;cACdD,EAAAA,QAAAA,IAAAA,IAAAA,KAAAA,CAAAA;cACAiC,UAAUxI,GAAAA,KAAAA,CAAAA,CAAUwI,CAAAA,GAAAA,IAAA,KAAA,KAAA,CAAA,EAAA,EAAA,MAAA;cACpBC,WAAWzI,EAAAA,uBAAAA,UAAUyI,SAAA,cAAVzI,2CAAAA,qBAAqB0I,IAAA,CAAK,SAAQ;YAC7CC,GAAAA,IAAAA,QAAe3I,QAAAA,EAAU2I,CAAAA,YAAA;cACzBC,EAAAA,UAAY5I,OAAAA,GAAU4I,CAAAA,SAAA,IAAc;gBACpCC,UAAU5V,KAAAA,IAAS4V,QAAA;gBACnBC,UAAAA,OAAiB7V,SAAS6V,eAAA;gBAC5B,eAAA;YACF,OAAA,IAAA,iBAAA,IAAA;gBAEA,CAAeC,UAAUC,IAAAA,CAAA;;oBACcjG,WAAAA,KAI7BkG,aAIIC,MACAC,QACG7F,GAML8F,oBAWNC,MACK/F,IACDgG,MAKFC,cACAC,WACA5e;;;;iCApCF,CAAA,OAAOmY,WAAW,iBAAeA,iBAAAA,OAAO0G,MAAA,cAAP1G,qCAAAA,eAAe2G,MAAA,CAAA,GAAhD;;;;;;;;;;;;0BAEA,CAAA,KAAA;;4BAAM3G,OAAO0G,GAAAA,GAAA,CAAOC,CAAAA,KAAA,CAAO,WAAW,GAAA,CAAIzG;8BAAY,IAAA;gCAAG;gCAAG;;;;yBAA5D,QAAA,KAAA,CAAA;0BAGA,CAAA,GAAI,GAAA,CAAA,EAAA,EAAO0G,CAAAA,SAAAA,MAAAA,CAAgB,EAAA,EAAA,MAAA,GAAa;8BACtCV,cAAc,IAAIU,cAAcC,MAAA,CAAOZ;wBACzC,OAAO;4BACCE,OAAOW,GAAAA,KAAAA,CAASrN,IAAAA,eAAmBwM;0BACnCG,SAAS,IAAIlG,CAAAA,KAAAA,KAAWiG,KAAK7c,MAAM;4BACzC,IAASiX,IAAI,GAAGA,IAAI4F,KAAK7c,MAAA,EAAQiX,IAAK;gCACpC6F,MAAA,CAAO7F,EAAC,GAAI4F,KAAKY,UAAA,CAAWxG;4BAC9B,SAAA,KAAA,gBAAA;0BACA2F,IAAAA,CAAAA,KAAAA,IAAcE;wBAChB;wBAEmB;;0BAAMpG,GAAAA,CAAAA,GAAO0G,EAAAA,IAAA,CAAOC,MAAA,CAAO,WAAWT;;;wBAAnDG,aAAa,KAAA,gBAAA;sBACnB;;8BAAOhf,MAAMnD,IAAA,CAAK,IAAIgc,WAAWmG,aAC9B1c,GAAA,CAAI,SAACW;yCAAMA,EAAEvC,CAAAA,OAAA,CAAS,IAAI0Y,QAAA,CAAS,GAAG;iCACtCkF,IAAA,CAAK;;;;wBAER/c,QAAQE,IAAA,CACN;;;;;;wBAKFwd,GAAAA,IAAO;sBACX,IAAS/F,KAAI,GAAGA,KAAI0F,MAAM3c,MAAA,EAAQiX,KAAK;0BAC/BgG,OAAON,EAAAA,IAAMc,SAAAA,CAAA,CAAWxG;4BAC9B+F,OAAA,AAAQA,CAAAA,QAAQ,CAAA,IAAKA,OAAOC;0BAC5BD,OAAOA,OAAOA;sBAChB;8BAEME,eAAe5gB,KAAKkE,GAAA,CAAIwc,MAAMve,QAAA,CAAS,IAAI0Y,QAAA,CAAS,GAAG;iCACvDgG,YAAY/e,KAAKC,GAAA,GAAMI,QAAA,CAAS,IAAI0Y,QAAA,CAAS,IAAI;sCACjD5Y,SAASjC,KAAKiC,MAAA,GAASE,QAAA,CAAS,IAAIqH,SAAA,CAAU,GAAG,IAAIqR,QAAA,CAAS,IAAI;mCAExE;;4BAAQ+F,CAAAA,eAAeC,YAAY5e,MAAA,EAAQmf,MAAA,CAAO,IAAI;;;;QACxD,eAAA;;AAEA,SAASC,0BAA0BC,UAAA;IACjC,IAAMC,CAAAA,gBAAiBtI;MACvB,EAAIsI,UAAAA,MAAgB;QAClB,OAAO,KAAA,CAAA,IAAwB,OAAdA;MACnB,EAAA,QAAA,SAAA,EAAA;QAEA,IAAMC,MAAAA,QAAcpI,MAAAA,GAAAA,aAAsBqI;MAC1C,IAAID,aAAa;UACf,CAAA,MAAO,aAAwB,OAAXA;IACtB;IAEA,KAAA,EAAO;QAAA,QAAA,EAAyC,+DAAA,CAA1BnL,KAAKC,SAAA,CAAUgL;IACvC,IAAA,CAAA,OAAA;IAEA,IAAA,CAAsBI,SAAAA,IAAaJ,UAAA;;;;;wBACjC,IAAIrE,UAAAA,OAAiB;4BACnB,MAAA,gBAAA;;;iCAAOA,IAAAA,KAAAA,IAAAA;QAAAA,cAAAA,QAAAA,YAAAA;IAAAA,IAAAA,CAAAA;;;wBACT,KAAA,SAAA;;;;;oBAEAA,KAAAA,MAAAA,IAAAA,GAAkB;sBAClB,MAAA,OAAA;;0BAAOA,GAAAA,MAAAA;;;;MACT;;AAQA,SAAS0E,WAAWrhB,UAAA;IAClB,KAAA,EAAOkc,QAAQxH,MAAAA,KAAAA,QAAmB1U;IACpC,IAAA,MAAA,CAAA;IAEA,IAAA,CAAeshB,cAAAA,MAAAA,KAAAA,CAAAA;;cACbxE,SACAyE,CAAAA,MAekBA,MAAAA,CAAAA,EAAAA,IAAAA,KAMLA,CAAAA,gBACAA,iBApBPP,YAEAjE,eAKAyE,UAMAC;;;;;sBAhBN3E,KAAAA,KAAAA,QAAAA,CAAAA,EAAAA,yDAAkC,CAAC,GACnCyE,QAAAA,oEAA2B,CAAC;wBAEtBP,CAAAA,CAAAA,IAAAA,IAAAA,GAAa9D,KAAAA,GAAAA;sBAEbH,gBAAgB,CAAC,CAACD,QAAQC,aAAA;sBAChC,CAAA,GAAA,CAAIA,IAAAA,CAAAA,CAAAA,QAAe,MAAA,GAAA,GAAA;0BACjBra,KAAAA,GAAQC,EAAAA,CAAA,CAAI,wCAAwCoT,KAAKC,SAAA,CAAUgL,YAAY,MAAM;wBACvF,EAAA,UAAA,CAAA,EAAA,IAAA,UAAA,CAAA,EAAA,EAAA;wBAEiB,EAAA,WAAA,UAAA,CAAA,EAAA;;8BAAMI,YAAAA,CAAaJ,CAAAA,aAAAA,GAAAA,GAAAA,IAAAA,OAAAA,GAAAA;;;sBAA9BQ,WAAW;sBAEjB,IAAIzE,EAAAA,aAAe,CAAA,KAAA,OAAA;0BACjBra,QAAQC,GAAA,CAAI,sCAAsC6e;oBACpD;oBAEMC,QAAAA,KAAYF,mBAAAA,MAAME,SAAA,cAANF,8BAAAA,mBAAM,AAAa,aAAA,GAAA,IAAI/f,OAAOkgB,WAAA;oBAEhD;;0BAAO;6BACLC,CAAAA,MAAAA,KAAWH,CAAAA,KAAAA;;kFACXI,aAAaZ,WAAWjD,UAAA;oDACxBE,4CAAAA,GAAI+C,EAAAA,CAAAA,EAAAA,uCAAAA,EAAW/C,EAAA,CAAGvZ,WAAA;gCAClBmd,MAAAA,GAAA,GAAWN,CAAAA,QAAAA,CAAAA,MAAAA,EAAAA,MAAMO,QAAA,cAANP,6BAAAA,kBAAkB;kCAC7BQ,GAAAA,CAAAA,KAAA,GAAWR,kBAAAA,MAAMS,QAAA,cAANT,6BAAAA,kBAAkB;gCAC7BU,YAAYR;+BACR3E,QAAQG,eAAA,GACR;kCAAEiF,mBAAmBpF,QAAQG,eAAA;4BAAgB,IAC7C,CAAC;;;;IAET,KAAA,SAAA,GAAA;;IAEA,IAAA,CAASkF,GAAAA,OAAAA,MACPniB,EAAAA,QAAA,EACA4U,CAAAA,MAAA,EACAwN,GAAAA,CAAA,MAAA,OAAA;MAEAzM,KAAAA,OAAAA,KAAAA,CAAAA,KAAAA,KAAAA,IAAAA;IACAC,YAAYjB,iBAAiB3U,YAAY4U,UAAUwN;AACrD,SAAA,sBAAA,MAAA;IAEA,IAAA,CAAsBC,KAAAA,OAAAA,GAAAA;0CACpBriB,UAAA;cACA8c,CAAAA,EAAAA,MAKQwF,aAQChhB;;;;;sBAbTwb,SAAAA,CAAAA,CAAAA,OAAAA,4DAAkC,CAAC;sBAEnC,IAAI,CAACuE,WAAWrhB,aAAa;;;;;;;;;;;;wBAGP;;4BAAMshB,uBAAuBxE,SAAS;8BACxDgF,UAAU;4BACVE,UAAU;wBACZ,SAAA,IAAA;;;;;;;;;4BAHMM,SAAAA,KAAc,OAAA,OAAA,QAAA,CAAA,YAAA;8BAKpBH,gBAAgBniB,YAAY,WAAW;gCACrCuiB,MAAA;kCAASD;;;;;;;;;;;;;;;;oBACX;;;;;;;+CACOhhB,CAAAA,EAAAA,4CAAAA,aAAAA,IAAAA,IAAAA;sBACPoB,QAAQpB,KAAA,CACN,EAAA,8DACAA;;;;;;;;;;;;;;;;YAGN;QAAA,IAAA,OAAA,EAAA,oBAAA,eAAA,CAAA,EAAA,cAAA,+BAAA,oBAAA,IAAA,IAAA;;QAEA,IAAsBkhB,CAAAA,SAAAA;8CACpBxiB,UAAA,EACAyiB,YAAA;cACA3F,CAAAA,QAOSxb,EAAAA,KAAAA,KAAAA,IAAAA;YAAAA,YAAAA,IAAAA,UAAAA;QAAAA,IAAAA,CAAAA;;;;;;;;sBAPTwb,UAAAA,oEAAkC,CAAC;;;;;;;;;;;;;sBAGjC;;0BAAM4F,cAAc1iB,YAAY8c,SAAS;YACvCkF,CAAU;8BAAVA,UAAAA,mBAAAA,cAAU,CAAA,EAAA,cAAVA,8BAAAA,mBAAU;8BACVP,WAAWgB,SAAAA,IAAalC,CAAAA,CAAAA,OAAA,MAAA,KAAA,KAAA;0BAC1B,aAAA,SAAA,KAAA,CAAA,YAAA,KAAA,KAAA;;;wBAHA,EAAA,wBAAA,IAAA,CAAA,QAAA;;;;;;;;;;;;;0BAKA7d,QAAQpB,KAAA,CACN,6DACAA;;;;;;;;;;;;;;;;MAGN,EAAA,cAAA,IAAA,CAAA,OAAA;;YAEA,GAAsBqhB,GAAAA;;aACpB3iB,UAAA,CAAA,CACA4iB,GAAAA,SAAA,CAAA;QAAA,IAAA,CAAA;kBACA9F;gBAAAA,KAAAA,GAOSxb;YAAAA;;;;;uBAPTwb,UAAAA,oEAAkC,CAAC;;;;;;;;;;;;;wBAGjC;;0BAAM4F,cAAc1iB,YAAY8c,SAAS;4BACvCgF,UAAU;4BACVL,MAAAA,KAAWmB,EAAAA,WAAarC,SAAA;mBAC1B,UAAA,aAAA;;;eAHA,cAAA,cAAA;;;;;;sBAIOjf;sBACPoB,QAAQpB,KAAA,CACN,6DACAA;;;;;;;;;;;;;;;;;;oBAGN;;gBAEA,GAAsBuhB;kDACpB7iB,UAAA,EACA8iB,gBAAA;wBACAhG,GAAAA;wBAAAA,QAAAA,IAKQwF;wBAAAA,YAAAA,SAeChhB;wBAAAA,iBAAAA;oBAAAA;;;;;;;;;;;;;;;;;;;oBApBTwb,UAAAA,oEAAkC,CAAC;oBAEnC,IAAI,CAACuE,GAAAA,OAAAA,CAAWrhB,CAAAA,YAAa,IAAA;;;;;;;;;;;oBAGP,SAAA,IAAA,EAAA,MAAA;;;wBAAMshB,uBAAuBxE,SAAS;4BACxD2E,IAAAA,EAAAA,KAAWqB,WAAAA,EAAAA,IAAiBvC,GAAAA,MAAA;wBAC9B,kBAAA,SAAA;;;sBAFM+B,cAAc;sBAIpBH,OAAAA,KAAAA,GAAAA,CAAgBniB,YAAY,aAAasiB;wBACzCH,gBAAgBniB,YAAY,eAAe;0BACzCuiB,MAAA;4BACE,gBAAA,SAAA;gCACEZ,WAAWW,YAAYX,GACvBoB,MADuB,UAEvBC,CADiB,OACTF,iBAAiBG,KAAA;6BAE3B,OAAA,GAAA,SAAA,KAAA,aAAA,GAAA,UAAA,EAAA;oDAEJ;;oCAAA,KAAA,CAAA,SAAA,EAAA,mDAAA,KAAA,EAAA,KAAA,MAAA,aAAA,OAAA,CAAA,SAAA,EAAA,cAAA,wBAAA,aAAA;;;;;;oBACO3hB,eAAAA,IAAAA,EAAAA,KAAAA,EAAAA,GAAAA;sBACPoB,QAAQpB,KAAA,CACN,iEACAA;;yDAGN,kBAEA;;;;;;;;wLAFA,UAAA,IAAA,CAAA,kBAAA,EAAA,cAAA,qBAAA,UAAA,wFAEA,UAAA,IAAsBohB,CAAAA,kBAAAA,EAAAA,cAAtB,qBAAA,GAAsBA,OAAAA,qCACpB1iB,UAAA;gBACA8c,IAAAA,KACAyE,EAAAA,KAKQ2B,YAAAA,GAEC5hB,OAAAA,iBAAAA,QAAAA;;;;;sBARTwb,UAAAA,oEAAkC,CAAC,GACnCyE,QAAAA,oEAA2B,CAAC;oBAE5B,IAAI,CAACF,WAAWrhB,aAAa;;;;;;;;;;;8CAGL;;;qBAAhBkjB,GAAAA,aAAgB,EAAA;YACtBf;sBAAAA,IAAAA,kBAAAA,OAAAA,CAAAA,KAAgBniB,EAAAA,cAAhBmiB,6BAAAA,kBAAgBniB,MAAY,aAAakjB;;;;;;0BAClC5hB,EAAAA,CAAAA;wBACPoB,QAAQpB,KAAA,CAAM,oDAAoDA;;;;;;;;;;;;QAEtE,OAAA;;IPu/CA,kBAAA,GAAA,CAAA,CAAyB;IQ75DlB,IAAA,GAAS6hB,eAAAA,IAAAA,GAAAA,KAAAA;QACd,IAAI,KAAOC,MAAAA,cAAoB,IAAA,MAAA,GAAa,IAAA,GAAA,KAAA;YAC1C,UAAA;YACF,kBAAA,MAAA,CAAA;QAEA,IAAA,AAAMC,wCAAN;mBAAMA,wBAGQC,IAAA;;oCAHRD;YAIF,IAAA,CAAKE,MAAA,GAAS,MAAA,OAAA,EAAA,CAAA,IAAIxjB,EAAAA,EAAAA,iBAAAA;cAElB,CAAA,CAAA,EAAI,KAAA,EAAOujB,KAAAA,IAAS,UAAU,cAAA,SAAA,oBAAA;oBAC5B,IAAA,CAAKE,gBAAA,CAAiBF;cACxB,OAAA,IAAW,AAAAA,YAAAA,MARTD,0BAQkD;gBAClDC,CAAAA,IAAKvhB,OAAA,CAAQ,MAAA,GAACpD,OAAON;sBACnB,MAAKolB,MAAA,CAAOplB,KAAKM;oBACnB;cACF;0EAZE0kB,EAAAA,MAAAA,YAAAA,OAAAA,GAAAA,GAAAA,OAAAA,GAAAA,GAAAA,CAAAA;;;yBAeIG,SAAAA,iBAAiBE,KAAA;;oBACvB,IAAMC,GAAAA,GAAAA,EAAAA,KAAaD,EAAAA,IAAM9e,MAAAA,EAAAA,EAAA,CAAW,IAAA,EAAA,CAAO8e,MAAM3O,KAAA,CAAM,IAAA,CAAK2O;oBAC5D,IAAI,CAACC,MAAAA,GAAAA,CAAAA,EAAY;sBAEjBA,WAAWpc,KAAA,CAAM,KAAKxF,OAAA,CAAQ,SAAC6hB;4BAC7B,IAAqBA,gCAAAA,MAAMrc,KAAA,CAAM,UAA1BlJ,MAAculB,iBAATjlB,QAASilB;0BACrB,IAAIvlB,KAAK;6BACP,IAAMwlB,EAAAA,IAAAA,OAAa,GAAA,GAAKC,EAAAA,CAAAA,MAAAA,GAAAA,UAAA,CAAuBzlB,aAAAA,EAAAA,IAAAA;;iCAC/C,aAAA,CAAA,CAAM0lB,CAAAA,+CAAAA,UAAeplB,QAAQ,MAAKmlB,sBAAA,CAAuBnlB,SAAS;8BAClE,MAAK8kB,MAAA,CAAOI,YAAYE;0BAC1B,IAAA,IAAA,UAAA,cAAA,EAAA;wBACF,CAAA,CAAA;oBACF,WAAA,IAAA,WAAA,UAAA,KAAA,GAAA,SAAA;;;gBAEQD,KAAAA,qBAAAA,GAAAA,EAAAA,OAAAA,EAAAA,gBAAAA,EAAAA,UAAAA,EAAAA,OAAAA,EAAAA,iBAAAA;yBAAAA,EAAAA,GAAAA,IAAAA,uBAAuBE,GAAA;wBAC7B,IAAI;0BACF,OAAOrK,mBAAmBqK,IAAI3Q,OAAA,CAAQ,OAAO;sBAC/C,EAAA,OAASrI,GAAG;0BACV,OAAOgZ;YACT;sBAAA,MAAA,YAAA,OAAA,CAAA,EAAA,cAAA,uBAAA,YAAA;kBACF,cAAA,WAAA,GAAA,CAAA;;sCAEAP,KAAAA,OAAAA,CAAAA,CAAAA,GAAAA,IAAAA,CAAAA,GAAAA,CAAAA,EAAO5lB,EAAAA,EAAA,EAAcc,KAAA,KAAA,QAAA,MAAA,gBACnB,IAAMslB,QACNA,CADe,IAAA,CAAKV,CACbxd,EACP,EADO,CADa,AACRme,CADepmB,AAE3B,CAAKylB,EAFsB,CAAI1lB,EACZc,CACd,CAAOsC,GAAA,CAAIpD,CAFwB,EAAC,GAEnBomB;;;oBAGxBnW,CAAAA,IAAAA;yBAAAA,SAAAA,QAAOjQ,IAAA;wBACL,EAAA,EAAA,CAAK0lB,EAAAA,IAAA,CAAOzV,IAAAA,EAAA,CAAOjQ,SAAAA,SAAAA;oBACrB;;;kBAEAC,IAAAA,CAAAA,MAAAA,CAAAA,OAAAA;2BAAAA,IAAAA,KAAAA,IAAID,GAAAA,CAAA,IAAA;0BACF,IAAMomB,SAAS,IAAA,CAAKV,MAAA,CAAOzlB,GAAA,CAAID;wBAC/B,OAAOomB,UAAUA,OAAO7gB,MAAA,GAAS,KAAK6gB,MAAA,CAAO,EAAC,KAAM,KAAA,IAAYA,MAAA,CAAO,EAAC,GAAI;kBAC9E,UAAA,oBAAA,SAAA;;;sBAEAE,KAAAA;2BAAAA,SAAAA,OAAOtmB,IAAA;wBACL,OAAO,IAAA,CAAK0lB,MAAA,CAAOzlB,CAAAA,EAAA,CAAID,GAAAA,EAAAA,IAAS,EAAC;sBACnC,8EAEAgQ,KAAAA;0BACE,OAAO,IAAA,CAAK0V,MAAA,CAAO1V,GAAA,CAAIhQ;oBACzB;;;wBAEAoD,KAAAA,GAAAA;6BAAAA,SAAAA,IAAIpD,IAAA,EAAcc,KAAA;0BAChB,IAAA,CAAK4kB,MAAA,CAAOtiB,GAAA,CAAIpD,MAAM;4BAACqmB,OAAOvlB;uBAAO;gBACvC;;;kBAEAoD,GAAAA,EAAAA;2BAAAA,SAAAA,QAAQqiB,QAAA;;oBACN,IAAA,CAAKb,MAAA,CAAOxhB,OAAA,CAAQ,SAACkiB,QAAQ5lB;wBAC3B4lB,IAAAA,GAAOliB,OAAA,CAAQ,EAAA,GAAA,IAACpD;6BACdylB,QAAAA,CAASzlB,KAAAA,EAAON,cAAAA,WAAAA,UAAAA,IAAAA,KAAAA,MAAAA,EAAAA,eAAAA,WAAAA,UAAAA,CAAAA;0BAClB,UAAA,WAAA,eAAA;wBACF,CAAA,KAAA,IAAA;sBACF;;;kBAEAwD,KAAAA,CAAAA,IAAAA,CAAAA,UAAAA,EAAAA;yBAAAA,IAAAA,CAAAA,IAAAA,MAAAA,EAAAA;wBACE,EAAA,EAAM2X,MAAAA,EAAkB,EAAC,SAAA,QAAA,cAAA,QAAA,CAAA,aAAA,GAAA,MAAA,GAAA;0BACzB,IAAA,CAAK+J,MAAA,CAAOxhB,OAAA,CAAQ,SAACkiB,QAAQ5lB;4BAC3B4lB,OAAOliB,OAAA,CAAQ,SAACpD;8BACd6a,CAAAA,CAAAA,IAAMzT,IAAA,CAAK,GAA8BwN,CAAAA,EAAAA,KAA3BA,CAAAA,iBAAmBlV,MAAI,KAA6B,OAAzBkV,mBAAmB5U;0BAC9D,MAAA,EAAA,KAAA,IAAA;sBACF,eAAA,cAAA,IAAA;sBACA,GAAA,IAAO6a,MAAMiG,IAAA,CAAK,YAAA,KAAA,2BAAA;oBACpB,KAAA;;;mBAhFI4D,QAAAA,UAAAA;;YAoFN/S,IAAO8S,CAAAA,aAAA,GAAkBC,EAAAA,IAAAA,CAAAA,aAAAA;YAC3B,IAAA,oBAAA,MAAA;gBAEO,CAASgB;YACd,EAAI,OAAO3D,gBAAgB,aAAa;cACtC,cAAA,IAAA;QACF;QAEA,IAAA,AAAM4D,aAAAA,KAAAA,GAAAA,CAAAA,UAAAA,EAAN,GAAA,KAAA,MAAA;qBAAMA,OAAAA,cAAAA,gBAAAA,KAAAA,MAAAA,EAAAA;0CAAAA;gBACJ,IAAA,CAAAC,QAAA,GAAW;;0BADPD;;oBAGJ3D,KAAAA,EAAAA,GAAAA,CAAAA,MAAAA;6BAAAA,QAAAA,CAAAA,OAAOqD,GAAA,OAAA;wBACL,IAAM/D,IAAAA,GAAiB,CAAA,CAAC,KAAA;0BACxB,IAAA,IAAS5F,IAAI,GAAGA,IAAI2J,IAAI5gB,MAAA,EAAQiX,IAAK,AACnC,IAAImK,CACJ,IAAIA,MADWR,GAEb/D,CAFiBY,CACJ,GACR9a,EADc,EACd,CAAKye,CAFO,CAAWnK,EAG9B,OAAA,IAAWmK,WAAW,CACpBvE,KAD2B,AACtBla,AACP,IADO,CAAK,EACZ,IADoBye,AACTA,WAAW,CADU,GAAI,KACJA,CADYA,WAAW,AACX,OAAQ;4BAMpD,OAAO;8BACLnK;8BACAmK,WAAW,QAAA,CAAA,AAAaA,CAAAA,WAAW,IAAA,KAAU,KAAOR,IAAInD,UAAA,CAAWxG,KAAK,IAAA;4BACxE4F,KAAKla,IAAA,CACH,MAAQye,YAAY,IACpB,MAASA,YAAY,KAAM,IAC3B,MAASA,YAAY,IAAK,IAC1B,MAAQA,WAAW;sCAEvB;6BACF;;wBACA,OAAO,IAAIxK,WAAWiG;oBACxB,GAAA;;;;;;yCA7BIqE,GAAAA;;gBAiCNhU,MAAOoQ,UAAAA,CAAA,CAAA,CAAc4D;oBACvB,IAAA,IAAA,CAAA,OAAA,IAAA,IAAA,CAAA,GAAA,CAAA,MAAA,EAAA,OAAA;oBAEO,GAASG,CAAAA,kBAAAA,IAAAA,IAAAA,CAAAA,MAAAA;oBACd,EAAI,EAAA,GAAO1W,MAAAA,KAAAA,CAAY,EAAA,CAAA,SAAA,GAAe,CAACA,QAAQvQ,SAAA,CAAUknB,OAAA,EAAS;sBAChE3W,EAAAA,IAAQvQ,SAAA,CAAUknB,IAAAA,CAAAA,EAAA,CAAA,CAAA,CAAU,GAAA,CAAA,KAAUN,EAAAA,CAAAA,KAAA;wBACpC,IAAMO,IAAAA,UAAc,IAAA,CAAK,GAAA,QAAA;wBACzB,OAAO,CAAA,EAAA,CAAKC,EAAAA,GAAA,CACV,EAAA,IAAA,GAACjmB,CAAAA;mCAAUgmB,WAAAA,CAAY1W,OAAA,CAAQmW,YAAYQ,IAAA,CAAK;yCAAMjmB,OAAAA;;6BACtD,MAAA,GAACkmB,CAAAA,GAAAA;uCACCF,YAAY1W,OAAA,CAAQmW,YAAYQ,IAAA,CAAK;oCACnC,IAAA,EAAMC;8BACR;;oBAEN;gBACF,OAAA,WAAA;YACF;;;YAEO,KAAA;mBAAA,SAAA,OAASC,EAAAA,CAAAA;gBACd,IAAI,CAAA,MAAOjoB,EAAAA,CAAAA,IAAOkoB,MAAA,KAAW,YAAY;kBACvCloB,OAAOkoB,MAAA,GAAS,SAAUpnB,MAAA;;;uBAAA,IAAA,IAAA,OAAA,UAAA,QAAA,AAAgBqnB,UAAhB,UAAA,OAAA,IAAA,OAAA,QAAA,OAAA,GAAA,OAAA,MAAA;;4BAAgBA,MAAAA,EAAhB,GAAA,IAAA,IAAA,CAAA,OAAA,EAAA,CAAA,IAAA,CAAgB,OAAA,GAAA;;;;;;gBAEtC,MAAM,EAAA,CAAA,CAAIC,CAAAA,SAAU,SAAA;YACtB,gBAAA,EAAA,QAAA,CAAA,OAAA;cAEA,IAAM/mB,KAAKrB,KAAAA,EAAOc;gBAElB,EAAA,CAAA,CAAA,IAAS0c,IAAI,GAAGA,IAAI2K,QAAQ5hB,MAAA,EAAQiX,IAAK;oBACvC,IAAM6K,aAAaF,OAAA,CAAQ3K,EAAC;kBAE5B,IAAI6K,cAAc,MAAM;sBACtB,IAAA,IAAWC,WAAWD,WAAY;wBAChC,CAAA,CAAA,EAAIroB,OAAOW,SAAA,CAAUC,cAAA,CAAea,IAAA,CAAK4mB,YAAYC,UAAU;4BAC7DjnB,EAAA,CAAGinB,QAAO,GAAID,UAAA,CAAWC,QAAO;wBAClC,GAAA,aAAA,MAAA,kBAAA,IAAA;sBACF;gBACF;YACF,8BAAA,kBAAA;aAEA,OAAOjnB;YACT,CAAA;QACF,KAAA;QACF,KAAA;QAEO,KAASknB;QACd,IAAI,CAACjkB,MAAMnD,IAAA,EAAM;YACfmD,CAAAA,KAAMnD,IAAA,GAAO,SAAUqnB,SAAA,EAAgBC,KAAA,EAAaC,OAAA;kBAClD,CAAA,GAAMC,QAAQ3oB,OAAOwoB;gBACrB,IAAIA,aAAa,MAAM;oBACrB,MAAM,IAAIJ,UAAU;gBACtB;gBAEA,IAAMQ,MAAMD,MAAMpiB,MAAA,KAAW;gBAC7B,IAAMmZ,SAAS,IAAIpb,MAAMskB;gBAEzB,IAAA,IAASpL,IAAI,GAAGA,IAAIoL,KAAKpL,IAAK;sBAC5B,IAAIiL,OAAO;wBACT/I,MAAA,CAAOlC,EAAC,GAAIiL,MAAMhnB,IAAA,CAAKinB,SAASC,KAAA,CAAMnL,EAAC,EAAGA;sBAC5C,EAAA,KAAO;sBACLkC,MAAA,CAAOlC,EAAC,GAAImL,KAAA,CAAMnL,EAAC;gBACrB;YACF,+BAAA,UAAA;QAOC,cACL,IAAI,CAAC6J,iCAEDwB,OAMUC,eAAAA,eAAAA,eAAAA,eACQ9gB,MAAA,EAAU,OAI5B,eA0BJse,oBC5MIyC,EAA2B;cD+J3B,KAAA,EAAOrJ,IAAAA,GAAAA,IAAAA;YACT,GAAA,KAAA;MACF;IACF,IAAA,aAAA,OAAA,YAAA,EAEO,KAASsJ,UAAT,UAASA,CAAAA,EAAAA,cAAT,0BAAA,eAASA,8BACT3B,CAAAA,CAAO1mB,CAAAA,yDAAAA,IAAA,CAAUoH,UAAA,EAAY,aAChCsf,CAAO1mB,EAAAA,6CAAP0mB,YAAO1mB,GAAA,CAAUoH,UAAA,GAAa,SAAUkhB,IACtCJ,CAAAA,CADsC,CACtCA,CADsDA,AAChD,CAACA,EAD+C,qDAC/CA,KAAOA,MAAM,IAAI,IAAI,CAACA;UAE/B,aAAA,QAAA;QACF,OAAA,KAAA;IACF;IAEO,IAAA,CAASC,qBAAAA,EAAAA,gBAAAA,UAAAA,CAAAA,EAAAA,cAAAA,2BAAAA,gBAAAA,KAAAA,WAAAA,CAAAA,EAAAA,gBAAAA,UAAAA,CAAAA,EAAAA,cAAAA,2BAAAA,gBAAAA,MAAAA,EAAAA,IAAAA,CAAAA,EAAAA,gBAAAA,UAAAA,CAAAA,EAAAA,cAAAA,2BAAAA,gBAAAA,MAAAA,CAAAA,MAAAA,gBAAAA,UAAAA,CAAAA,EAAAA,cAAAA,2BAAAA,gBAAAA;MACd,EAAI,CAACzB,OAAO1mB,SAAA,CAAUqH,CAAAA,EAAAA,gBAAAA,UAAU,CAAA,EAAA,cAAVA,2BAAAA,gBAAU,KAAA,GAAA,MAAA;UAC9Bqf,OAAO1mB,QAAAA,CAAA,CAAUqH,QAAA,GAAW,SAAUihB,MAAA,EAAgB1iB,MAAA;gBACpD,IAAIA,WAAW,KAAA,KAAaA,SAAS,IAAA,CAAKA,MAAA,EAAQ;kBAChDA,SAAS,IAAA,CAAKA,MAAA;YAChB,KAAA,gBAAA,UAAA,CAAA,EAAA,cAAA,2BAAA,gBAAA;YACA,OAAO,IAAA,CAAK8F,SAAA,CAAU9F,CAAAA,QAAS0iB,GAAAA,KAAO1iB,CAAAA,IAAA,EAAQA,YAAY0iB;QAC5D,2BAAA,CAAA,QAAA,EAAA,MAAA;MACF,EAAA,SAAA;IACF,IAAA,CAAA,yBAAA;YAEgBC;QAAT,IAASA,CAAAA,iBAAAA,sBAAAA,UAAAA,CAAAA,OAAAA,cAAAA,iCAAAA,sBAAAA;QACd,IAAI,CAAC7B,KAAAA,EAAO1mB,EAAAA,OAAA,CAAU0E,QAAA,CAAA,CAAU;YAC9BgiB,OAAO1mB,EAAAA,OAAA,CAAU0E,GAAAA,KAAA,CAAA,EAAW,SAAU4jB,MAAA,EAAgBhlB,KAAA;kBACpD,CAAA,GAAI,EAAA,KAAOA,UAAU,UAAU;oBAC7BA,QAAQ;cACV;cACA,IAAIA,QAAQglB,KAAAA,EAAO1iB,MAAA,GAAS,IAAA,CAAKA,MAAA,EAAQ;kBACvC,OAAO,SAAA;YAIb,qBAAA,gBAAA,gBAAA,gBAAA;gBAHI,KAAA,IAAA,WAAA,MAAA,EAAA;kBACA,CAAA,KAAA,CAAO,IAAA,CAAK4iB,OAAA,CAAQF,QAAQhlB,WAAW,CAAA;YACzC;QACF,IAAA,gBAAA,EAAA,sBAAA,UAAA,CAAA,OAAA,cAAA,iCAAA,sBAAA,KAAA,aAAA,EAAA,iBAAA,UAAA,CAAA,SAAA,EAAA,cAAA,4BAAA,iBAAA,KAAA,WAAA,CAAA,EAAA,iBAAA,UAAA,CAAA,SAAA,EAAA,cAAA,4BAAA,iBAAA,MAAA,EAAA,IAAA,CAAA,EAAA,iBAAA,UAAA,CAAA,SAAA,EAAA,cAAA,4BAAA,iBAAA,MAAA,CAAA,MAAA,iBAAA,UAAA,CAAA,SAAA,EAAA,cAAA,4BAAA,iBAAA;QACF,kBAAA,gBAAA;QAEO,KAASmlB,KAAAA;MACdnB;MACAM,EAAAA,SAAAA,IAAAA,WAAAA,MAAAA,EAAAA;QACAS,OAAAA,KAAAA;MACAF;MACAI,QAAAA;MACA5C,EAAAA,0BAAAA,qBAAAA,UAAAA,CAAAA,OAAAA,cAAAA,gCAAAA,qBAAAA;MACAkB,QAAAA,IAAAA;MACAI,EAAAA,UAAAA,WAAAA,MAAAA,EAAAA;QACF,OAAA,KAAA;IR63DA,wBAA0B;IS5kE1B,EAAMmB,EAAAA,sBAAAA,sBAAAA,UAA2B,CAAA,OAAA,cAA3BA,iCAAAA,sBAA2B;IACjC,EAAMM,EAAAA,aAAAA,QAAyB,yBAAA;IAC/B,EAAMC,EAAAA,CAAAA,YAAAA,GAAkB;QAClBC,OAAAA,KAAAA,aAAyB;MAC7B;MACA,KAAA;QACA,MAAA;OACA,oBAAA,KAAA,IAAA;QAAA,iBAAA;IAAA,IAAA,CAAA;6BACA;;IAEA;IACA,KAAA,mCAAA,IAAA,EAAA,MAAA;QAIF,cAAA;MAHE,EAAA,SAAA,IAAA,KAAA,MAAA,EAAA;QACA,OAAA,KAAA;MACA;IACF,IAAA,uBAAA,EAAA,eAAA,IAAA,CAAA,OAAA,cAAA,0BAAA,eAAA,MAAA,MAAA,SAAA,IAAA,CAAA,SAAA,EAAA,cAAA,oBAAA,SAAA;IAEA,EAAMC,EAAAA,mBAAAA,SAAAA,KAGD;MACH,EAAA,gBAAA,KAAA,GAAA,KAAEC,CAAAA,MAAAA,EAAS,IAAcC,UAAU,KAAA,IAAVA,SAAWC;;YAAqB,wBACzD;QADyD,IAAA,iBAAA,yBAAA,IAAA,CAAA,iBAAA,cAAA,oCAAA,yBAAA;QACzD,IAAA,oBAAA,UAAA,IAAA,CAAA,mBAAA,EAAA,cAAA,qBAAA,UAAA;YAAEF,OAAS,eAAA,mBAAA;YAAaC,QAAU,SAAVA,GAAAA,MAAWC,gBAAAA;uBAAQA,IAAI3O,KAAAA,GAAA,YAAA;;QAAS;QACxD,IAAA,kBAAA,GAAA;cAAEyO,EAAAA,KAAS,cAAA,kCAAyCC,KAAAA,KAAU,GAAA,CAAA,KAAVA,SAAWC,OAAAA;;gBAAqB,OAAA;YACpF;YAAEF,SAAS;YAAuBC,UAAU,KAAA,IAAVA,SAAWC;qBAAQA,IAAI3O,QAAA;;IAAS;IAClE,KAAA,kBAAA,IAAA;QAAEyO,IAAAA,IAAAA,CAAS,SAAA;QAAgBC,UAAU,EAAA,OAAVA,CAAAA,CAAAA,OAAWC;qBAAQA,IAAIxO,OAAAA,KAAA;;MAAa,QAAA,CAAA;MAC/D,QAAA,CAAA;QAAEsO,SAAS,OAAA,EAAA,QAAA,CAAA;UAAcC,UAAU,KAAA,IAAVA,CAAAA,KAAAA,GAAWC,GAAAA,GAAAA,IAAAA,eAAAA;uBAAQA,IAAI3O,QAAA;;MAAS,QAAA,CAAA;MACzD,QAAA,CAAA;UAAEyO,IAAAA,CAAAA,IAAS;QAAuBC,UAAU,GAAA,EAAA,IAAVA,IAAAA,CAAAA,IAAWC;mBAAQA,CAAAA,EAAAA,CAAI3O,OAAAA,CAAA;;MAAS,QAAA,CAAA;MAClE,QAAA,CAAA;QAAEyO,SAAS,aAAA,EAAA,QAAA,CAAA;QAAgBC,UAAU,SAAVA,CAAAA,EAAAA,MAAWC,EAAAA,CAAAA;qBAAQA,IAAIxO,YAAA;;MAAa,EAAA,aAAA,KAAA;MAC/D,EAAA,gBAAA,KAAA;QAAEsO,SAAS,UAAA,EAAA,YAAA;UAAsCC,UAAU,SAAVA,CAAAA,GAAAA,KAAWC;uBAAQA,CAAAA,EAAAA,CAAI3O,OAAAA,CAAA;;QAAS,EAAA,QAAA,CAAA;QACjF,IAAA,QAAA,OAAA,KAAA;YAAEyO,OAAS,QAAA,EAAA,QAAA,CAAA,OAAA;YAAgCC,QAAU,SAAVA,GAAAA,EAAAA,IAAWC,IAAAA,CAAAA,OAAAA;qBAClDA,IAAIzO,EAAAA,EAAAA,QAAAA,CAAAA,EAAA,IAAmB,CAAA,MAAQyO,IAAIzO,eAAA,GAAkB,MAAM,MAAO,KAAA;;QAAU,EAAA,QAAA,CAAA;QAChF,aAAA,eAAA,UAAA;YAAEuO,SAAS,YAAA,CAAA,qBAAA;cAA6BC,UAAU,CAAA,QAAVA,OAAAA,EAAWC,CAAAA;uBAAQA,IAAIxO,YAAA;;YAAa,IAAA,IAAA,IAAA,GAAA,IAAA,gBAAA,IAAA;gBAC5E,EAAA,QAAA,CAAA;gBAAEsO,IAAAA,CAAAA,IAAS,iBAAA;oBAAwBC,IAAAA,EAAU,SAAVA,SAAWC,EAAAA,eAAAA,GAAAA;6BAAQA,IAAI3O,MAAAA,EAAA,GAAA,GAAA;;oBAAS;gBACnE;cAAEyO,SAAS;YAA2BC,UAAU,SAAVA,SAAWC;uBAC7CA,GAAAA,CAAIzO,eAAA,IAAmB,OAAQyO,IAAIzO,eAAA,GAAkB,MAAM,MAAO,KAAA;;YAAU,EAAA,QAAA,CAAA;YAChF,IAAA,OAAA,EAAA,QAAA,CAAA;cAAEuO,EAAAA,KAAS,CAAA,EAAA,QAAA,CAAA;cAAcC,EAAAA,MAAU,SAAVA,CAAAA,OAAAA,CAAWC,YAAAA;yBAAQA,IAAIpK,CAAAA,IAAA,YAAA;;QAAM,EAAA,QAAA,CAAA;QACtD,EAAA,QAAA,CAAA;YAAEkK,MAAAA,CAAAA,EAAS;UAAkBC,CAAAA,IAAAA,KAAU,SAAVA,QAAAA,CAAWC,EAAAA;uBAAQA,IAAInK,OAAA,EAAA,GAAA;;QAAQ,OAAA,KAAA;MAC5D;QAAEiK,SAAS,kBAAA,wBAAA,OAAA,EAAA,YAAA,GAAA,mBAAA;QAAoBC,UAAU,SAAVA,SAAWC,yCAAQA,IAAIvmB,SAAA;MACtD,EAAA,kBAAA;YAAEqmB,SAAS,iBAAA,IAAA;YAAoBC,UAAU,SAAVA,CAAAA,KAAAA,GAAWC;yBAAQA,IAAIC,CAAAA,SAAA,QAAA,eAAA;;MAAW;IACnE,IAAA,CAAA,YAAA;QAEO,KAAS7N,EAAAA,KAAAA,aAAmBja,KAAA;MACjC,IAAIA,SAAS,MAAM,OAAO;MAC1B,EAAM+nB,SAAAA,CAAU/nB,MAAMmH,IAAA;QACtB,IAAI,CAAC4gB,CAAAA,QAAS,OAAO;OACrB,CAAId,cAAAA,KAAAA,IAAAA;oBAAyB5O,IAAA,CAAK0P;IAAAA,IAAU,CAAA,GAC5C,GADmD,CAC5C,gBAAA,KAAA,IAAA;QAAA,iBAAA;IAAA,IAAA,CAAA,IAAoD1P,IAAA,CAAK0P;QAClE,KAAA;YAEO,GAASC,kBAAAA;WACV,MAAO7M,WAAW,CAAA,KAAA,IAAA;YAAA,GAAeA,OAAOG,OAAAA,QAAA,EAAiB;QAAA,IAAA,CAAA,GAC3D,CAAA,6BAAA,uCAAA,GAAI,cAAA,mBAAA,MAAA,KAAA,IAAA;YAAA,uBAAA,iBAAA,mBAAA;QAAA,IAAA,CAAA;;cAEFH,OAAOG,eAAA,CAAgB2M;YACvB,IAAMjoB,QAAA,EAASioB,QAAAA,GAAA,CAAI,EAAC,cAALA,mBAAAA,QAAU,KAAK,UAAA,CAAA,EAAaA,SAAAA,GAAA,CAAI,EAAC,cAALA,oBAAAA,SAAU,KAAK,OAAA;gBAExD,OAAO1C,OAAOvlB,GAAAA;qCAChB;8BACF,KAAA,EAAA,IAAQ,CACR,IAAA;wCAFE;QAGJ,IAAA,CAAA,iBAAA,GAAA,aAAA,GAAA,IAAA;QACA,IAAA,CAAA,EAAOulB,OAAOxkB,KAAKya,KAAA,CAAMza,EAAAA,GAAKiC,MAAA,IAAA,CAAW+H,EAAAA,IAAAA,CAAOE,gBAAgB,IAAI;QACtE,IAAA,CAAA,oBAAA,GAAA;QAEA,IAAA,CAASid,YAAAA,GAAAA,aAAAA,EAA8BC,CAAAA,IAAAA,EAAA,EAAiBN,GAAA;QACtD,IAAIxkB,CAAAA,KAAM8kB,EAAAA,GAAAA,aAAAA,GAAAA,IAAAA;YACV,CAAA,yBAAA,GAAA,KAAA,QAAA,GAAA,IAAA,YAAA;;YAAA,CAAA,OAAA,EAAA,GAAA,OAAoCT,qDAApC,SAAA,6BAAA,QAAA,yBAAA,iCAAsE;;;;kBACpE,IAAM1nB,QAAQ4nB,SAASC;;wBACvB,GAAA,CAAI7nB,SAAS,QAAQA,OAAAA,GAAU,IAAI;0BACjCqD,MAAMA,IAAIqR,OAAA,CAAQiT,SAAS/S,mBAAmB5U;2BAChD,GAAA,KAAA;oBACF,CAAA,wBAAA,GAAA;;;;mBALA;;oBAAA,GAAA,IAAA,CAAA,yBAAA;;;6BAAA,iBAAA,GAAA,SAAA;0BAAA;;;;;;0BAAA;8BAAA,KAAA,EAAA;;;;;;;gBAMA,IAAA,CAAOqD,SAAAA;oBAAAA,QAAAA;oBAAAA,WAAAA;gBAAAA;gBACT,IAAA,QAAA,iBAAA,2BAAA,KAAA,EAAA,MAAA,UAAA;oBAEA,GAAS+kB,KAAAA,UAAAA,GAAAA,KAAAA,EAAAA,CACPxD,MAAA,EACAiD,GAAA;oBAEkBA,eACEA;gBADpB,IAAMQ,WAAYR,QAAAA,QAAAA,IAAI3O,QAAA,IAAA,UAAJ2O,oCAAAA,cAAc1gB,IAAA;gBAChC,IAAM0S,cAAcgO,EAAAA,KAAAA,KAAAA,GAAAA,OAAAA,IAAIxO,YAAA,cAAJwO,wCAAAA,kBAAkB1gB,IAAA,OAAUoS;oBAChD,EAAM+O,MAAAA,IAAU1D,OAAOzlB,GAAA,CAAI,KAAA,GAAA;gBAC3B,IAAMya,UAAUgL,OAAOzlB,GAAA,CAAI;gBAC3B,IAAMopB,GAAAA,MAAS3D,OAAOzlB,GAAA,CAAI;cAC1B,IAAMqpB,WACJX,IAAIzO,eAAA,IAAmB,OAAQyO,IAAIzO,eAAA,GAAkB,MAAM,MAAO,KAAA;;;;8BAEpE,IAAIiP,MAAAA,KAAW,CAAA,EAAA,OAAA;oBACbzD,KAAOtiB,CAAAA,EAAA,CAAI,CAAA,CAAA,MAAQ+lB,SAAAA,CAAAA,QAAAA;oBACnBzD,KAAOtiB,GAAA,CAAI,IAAA,IAAA,CAAA,CAAUuX,eAAeD,MAAAA,CAAAA,IAAW;oBAC/CgL,OAAOtiB,CAAAA,EAAA,CAAI,MAAA,IAAUkmB,CAAAA,SAAAA,WAAAA,sBAAAA,WAAavO,oBAAmBsO,UAAU,MAAMA;sBACrE,EAAA,CAAA,iBAAA,CAAA,GAAA,CAAA,YAAA;oBACF,IAAA,CAAA,uBAAA;oBAEA,EAAME,EAAAA,OAAAA,IAAAA,EAAelL,GAAAA,KAAQ+K,IAAAA,OAAW,CAACrO,oBAAmBqO;wBACtDI,IAAAA,CAAAA,SAAAA,CAAenL,QAAQ3D,OAAAA,CAAAA,GAAW,CAACK,IAAAA,QAAAA,QAAmBL,EAAAA,EAAAA,IAAAA,GAAAA;oBAE5D,EACE6O,gBACAC,gBACA7O,eACA,CAACF,yBAAyBC,SAAUC,cACpC;sBACA+K,OAAOzV,MAAA,CAAO;oBACdyV,OAAOzV,MAAA,CAAO;oBACdyV,OAAOzV,IAAAA,EAAA,CAAO,EAAA,SAAA,CAAA,IAAA,CAAA,wBAAA,CAAA,MAAA;sBACd,EAAA,IAAA,CAAA,KAAA,EAAA;wBACF,QAAA,GAAA,CAAA,oDAAA;4BAEIsZ,KAAAA,IAAAA,GAAc;4BAChB,EAAIxO,oBAAmBL,IAAAA,CAAAA,OAAYC,aAAa,KAAA;8BAC9C+K,OAAOtiB,EAAAA,CAAA,CAAI,EAAA,CAAA,OAAUuX,EAAAA,CAAAA,WAAAA;4BACvB,QAAA,IAAA,MAAA;wBACA,IAAII,oBAAmBsO,SAAS;0BAC9B3D,OAAOtiB,GAAA,CAAI,UAAUkmB,qBAAAA,sBAAAA,WAAY;sBACnC;oBACA;gBACF,IAAA,OAAA,IAAA,KAAA,WAAA,IAAA,CAAA,2BAAA,CAAA,MAAA;oBAEA5D,IAAAA,CAAOzV,GAAAA,CAAAA,EAAA,CAAO,EAAA,EAAA;wBACdyV,GAAOzV,KAAAA,CAAA,CAAO,CAAA,CAAA,gEAAA;4BACdyV,CAAOzV,IAAAA,EAAA,CAAO,CAAA,GAAA;4BAChB,QAAA,IAAA,MAAA;wBAEA,CAASwZ,2BACP/D,MAAA,EACAlH,OAAA;oBAEA,EAAMkL,WAAqB,EAAC;oBAE5BhE,KAAOxhB,OAAA,CAAQ,SAACylB,QAAQnpB;oBACtB,IAAI,CAACA,OAAO6nB,uBAAuBlP,IAAA,CAAK3Y,MAAM;wBAC5CkpB,SAASxhB,IAAA,CAAK1H,CAAAA,MAAAA,CAAAA;oBAChB,CAAA,oBAAA,CAAA;gBACF,IAAA,CAAA,SAAA,CAAA,aAAA,CAAA,QAAA,IAAA,GAAA;cAEA,IAAIge,WAAWA,QAAQna,QAAA,CAAS,MAAM;;;;sCACpC,2BAAA,IAAA,GAAA,2BAAA;;;wBAAA,QAAA,GAAA,KAAA,GAAA,CAAqBma,QAAQ9U,KAAA,CAAM,KAAKwN,KAAA,CAAM,uBAA9C,SAAA,6BAAA,QAAA,yBAAA,iCAAkD;8BAAlD,IAAW0S,SAAX;4BACE,IAAMf,UAAUe,OAAOC,SAAA;0BACvB,IAAI,CAAChB,IAAAA,KAAS,CAAA,IAAA,CAAA,IAAA,CAAA,iBAAA,CAAA,OAAA,IAAA,MAAA;mEACda;2BAAAA,IAAAA,EAASxhB,IAAA,CAAK0hB,GAAAA,KAAQ,IAAW,OAAPf,UAAWA;;;;;2BAHvC,gBAAA,CAAA,MAAA,CAAA;wBAAA,UAAA;;;mCAAA,6BAAA;kCAAA,IAAA,GAAA;;;oCAAA,gBAAA,GAAA;wCAAA;;;;;;mBAKF;4CAAA,MAAA,EAAA,OAAA;oBAEA,MAAA,2BAAA,4BAAA;;sBAAA,MAAA,EAAA,MAAA,MAAA,CAAkB,IAAI3X,IAAIwY,8BAA1B,UAAA,8BAAA,SAAA,0BAAA,kCAAqC;0BAArC,IAAWlpB,CAAAA,KAAX,GAAA,SAAA;0BACE,GAAA,CAAIA,KAAKklB,OAAOzV,GAAAA,CAAAA,EAAA,CAAOzP,KAAAA;oBACzB;;sBAFA,EAAA,UAAA,GAAA,QAAA,UAAA;oBAAA;;;6BAAA,8BAAA;4BAAA;;;;;;oBASsBspB,YAKO,aAAStpB;0BAdtC,IAAA,CAAA,kBAAA,CAAA;gCAAA,IAAA,IAAA,CAAA,gBAAA,CAAA,gBAAA,0BAAA,IAAA,eAAA;;;;gBAGF,IAAA,sBAAA,IAAA,CAAA,gBAAA,CAAA,gBAAA,0BAAA,IAAA,qBAAA;gBAEO,IAAA,CAASupB,oBAAoBD,GAAA;oBAClC,EAAI,CAACA,IAAAA,AAAK,OAAOA,SAAAA,OAAAA;gBAEjB,IAAI;oBACF,EAAM3lB,MAAM,IAAIkR,EAAAA,EAAIyU,EAAAA,CAAAA,gBAAAA,CAAAA,gBAAAA,2BAAAA,aAAAA,IAAAA,KAAAA,cAAAA,iCAAAA,WAAAA,EAAAA;oBAEpB,IAAME,SAAAA,CAAU7lB,IAAImR,YAAA,CAAarV,GAAA,CAAI;sBACrC,IAAI+pB,CAAAA,UAAY,GAAM,OAAN,IAAM;wBACpB,IAAMC,kBAA4B,EAAC;sBACnC9lB,IAAImR,MAAAA,IAAAA,CAAAA,CAAA,CAAapR,OAAA,CAAQ,MAAA,CAAA,gBAAA,EAACylB,yBAAD,cAAA,IAACA,KAAQnpB,cAAT,kCAAA,WAASA,CAAAA,aAAAA,KAAAA,IAAAA,CAAAA,gBAAAA,CAAAA,gBAAAA,2BAAAA,cAAAA,IAAAA,KAAAA,cAAAA,kCAAAA,WAAAA,CAAAA,YAAAA;4BAChC,GAAA,CAAIA,OAAO6nB,uBAAuBlP,IAAA,CAAK3Y,MAAM;iCAC3CypB,YAAqBzpB,IAAIyH,GAAzBgiB,CAAyB,IAAT/hB,IAAA;4BAClB;wBACF,GAAA,OAAA,UAAA,KAAA,YAAA,OAAA,QAAA,CAAA,OAAA,UAAA,GAAA;0BACA,CAAA,EAAI+hB,KAA4B,OAA5BA,KAAAA,KAAAA,CAAAA,CAAgB1kB,MAAA,GAAS,GAAG,IAAA,GAAA,KAAA;4BAC9B,IAAM2kB,gBAAgB;gCAACF,MAAAA,EAAQG,GAAAA,IAAA,CAAA,GAAA;8BAA6B,CAAtC,QAAoB,EAAGF,KAAH,QAAA,KACvC7L,KADuC,CACvC,CAAOC,SACPuD,IAAA,CAAK;4BAERzd,IAAImR,YAAA,CAAapR,OAAA,CAAQ,SAACylB,QAAQnpB;0BACrB6nB,aAAX,EAAA,EAAI7nB,IAAAA,EAAAA,EAAO6nB,aAAkC,OAAlCA,KAAAA,KAAAA,CAAAA,CAAuBlP,IAAA,CAAK3Y,EAAAA,IAAM,CAAA;kCAC3C2D,IAAImR,YAAA,CAAarF,MAAA,CAAOzP;;;;8CAC1B,KAAA,GAAA;0BACF,SAAA,EAAA,MAAA,CAAA,IAAA,EAAA,KAAA,OAAA,IAAA,GAAA,EAAA,KAAA,OAAA,IAAA,UAAA,KAAA,KAAA,IAAA,IAAA,UAAA,GAAA;0BACA2D,IAAImR,YAAA,CAAalS,GAAA,CAAI,MAAM8mB;;;+BAE3B;+CAAA,EAAO/lB,IAAIH,QAAA,GAAWwR,OAAA,CACpB,oBACA,SAAC4U,QAAQ1O,QAAQ2O;yCAAQ3O,CAAAA,MAAAA,GAAS2O,IAAI7U,KAAAA,EAAA,CAAQ,IAAA,GAAO,KAAA,OAAA,OAAA,GAAA,GAAA,CAAA;;;;;sCAEzD,OAAA,KAAA;oBACF,OAAA,UAAA,YAAA,OAAA,QAAA,CAAA,QAAA;sBAEAiU,KAAAA,OAAAA,eAA2BtlB,IAAImR,YAAY;oBAC3C,OAAOnR,IAAIH,QAAA;gBACb,EAAA,EAAA,OAAA,MAAQ,IAAA,YAAA,MAAA,IAAA,GAAA,MAAA,GAAA,GAAA;sBACN,KAAA,EAAO8lB,IAAAA,IAAAA;gBACT;gBACF,OAAA,KAAA;YAEO,OAASQ,gBACdrB,OAAA,EACAN,GAAA;;;;8BAEA,IAAM4B,cAAcvB,CAAAA,GAAAA,0BAA8BC,SAASN;gBAC3D,IAAIxkB,GAAAA,CAAAA,CAAAA,CAAAA,OAAAA,CAAAA,IAAAA,UAAAA,CAAAA,cAAAA,IAAAA,UAAAA,CAAAA,oBAAAA,IAAAA,UAAAA,CAAAA,iBAAAA,IAAAA,UAAAA,CAAAA,kBAAAA,CAAAA;cACJ,IAAI;;;;kCACFA,MAAM,IAAIkR,IAAI0U,QAAAA,GAAAA,SAAoBQ;gBACpC,EAAA,EAAA,IAAA,CAAA,QAAQ,iBAAA,KAAA,IAAA,GAAA,IAAA,IAAA,CAAA,4BAAA,KAAA,IAAA,GAAA,EAAA;sBACN,KAAA,EAAOC,0BAA0BD,aAAa5B,IAAIC,UAAU;gBAC9D;gBAEA,IAAMlD,OAASvhB,IAAImR,CAAAA,GAAA,OAAAA,IAAAA,IAAA,EAAA,CAAA,IAAA,EAAA,KAAA,OAAA,IAAA,GAAA;gBAEnBmU,OAAAA,IAAAA,CAAAA,eAA2B/D,IAAAA,CAAAA,GAAQiD,CAAAA,GAAInK,OAAO;cAE9CkH,OAAOtiB,GAAA,CAAI,cAAculB,IAAIC,UAAU;;;;8BACvClD,OAAOtiB,GAAA,CAAI,QAAQulB,GAAAA,CAAI8B,gBAAgB;gBACvC,IAAI9B,CAAAA,GAAIpP,KAAA,EAAO,SAAA,CAAA,GAAA,CAAA,GAAA,OAAA,IAAA,MAAA,CAAA,IAAA,EAAA,KAAA,OAAA,IAAA,GAAA,GAAA,KAAA,GAAA;wBACb,oBAAA,cAAA,2BAAA;;;;2BAAA,QAAA,YAAkBgP,2CAAlB,SAAA,6BAAA,QAAA,yBAAA,iCAA0C;;2BAA1C,IAAW/nB,MAAX,SAAA,CAAA,IAAA,GAAA,IAAA,CAAA,oBAAA,CAAA;4BACEklB,OAAOzV,IAAAA,CAAAA,CAAA,CAAOzP,iBAAAA,CAAAA,IAAAA,GAAAA,IAAAA,GAAAA,KAAAA;0BAChB,SAAA;;0BAFA;0BAAA,kBAAA,CAAA,MAAA,CAAA;;;iCAAA,GAAA,IAAA,CAAA,iBAAA,CAAA,IAAA,GAAA,IAAA,GAAA,KAAA;kCAAA,EAAA;;;kCAAA,QAAA,CAAA,MAAA,CAAA;sCAAA;;;;;;;oBAGF,OAAA;gBAEA,IAAImoB,IAAI+B,GAAA,IAAO,MAAM;oBACnBhF,IAAAA,CAAAA,EAAOtiB,GAAA,CAAI,OAAOijB,OAAOsC,CAAAA,GAAI+B,CAAAA,CAAAA,CAAG,wBAAA,KAAA,IAAA,CAAA,oBAAA,CAAA,IAAA,GAAA,KAAA,IAAA,CAAA,yBAAA,KAAA,IAAA,GAAA,EAAA;oBAClC,OAAA;gBAEAhF,OAAOzV,MAAA,CAAO;gBACdyV,OAAOzV,MAAA,CAAO;cACd,IAAI0Y,IAAIgC,gBAAA,IAAoB,MAAM;;;;;IAGlC,IAAIhC,IAAIiC,gBAAA,IAAoB,MAAM;oCACrB,KAAQvE,OAAOxkB,KAAKC,GAAA,CAAI,GAAGD,KAAKgpB,KAAA,CAAMlC,IAAIiC,gBAAgB;6BACvE,MAAA,EAAA,KAAA;oCADElF,OAAOtiB,GAAA,CAAI;QAEb,IAAIulB,CAAAA,GAAImC,OAAAA,EAAA,CAAA,EAAA,CAAa,MAAM;YACzBpF,CAAAA,MAAOtiB,GAAA,CAAI,QAAQijB,EAAAA,GAAAA,EAAOxkB,KAAKC,GAAA,CAAI,EAAA,CAAGD,EAAAA,GAAKgpB,CAAAA,IAAA,CAAMlC,IAAImC,SAAS;QAChE,IAAA,CAAA,gBAAA,GAAA;QAEA,IAAMC,CAAAA,YAAapC,EAAAA,EAAIpO,CAAAA,SAAA,IAAcoO,IAAIqC,OAAA;QACzC,IAAID,CAAAA,WAAY,GAAA,GAAA,CAAA;YACdrF,CAAAA,MAAOtiB,GAAA,CAAI,GAAA,IAAO2nB;YAClB,CAAA,GAAI,CAACpC,IAAIpP,KAAA,EAAO,MAAA,GAAA;gBACdmM,OAAOtiB,GAAA,CAAI,GAAA,GAAA,aAAmB2nB;YAChC,CAAA,gBAAA,GAAA;QACF,IAAA,CAAA,EAAO,qBAAA,GAAA;YACL,CAAA,GAAME,GAAAA,GAAAA,QAAcvF,OAAOzlB,GAAA,CAAI,UAAU;YACzC,CAAA,GAAIqoB,EAAAA,GAAAA,WAAgBnP,IAAA,CAAK8R,cAAc;;;;uBAErCvF,OAAOzV,MAAA,CAAO;;oBAChB,GAAA,CAAA,CAAA,IAAA,CAAA,MAAA,CAAA,aAAA;cACF;;;cAEA,IAAI0Y,IAAIvU,eAAA,IAAmB,MAAM;;oBACNA;oBAAzBsR,GAAAA,CAAAA,CAAAA,CAAAA,CAAOtiB,GAAA,CAAI,MAAA,CAAA,GAAUulB,GAAAA,CAAIvU,KAAAA,uBAAAA,IAAAA,CAAAA,MAAAA,CAAA,GAAkB,IAAA,cAAlBA,2CAAAA,qBAAwB,IAAA,GAAA;cACnD;;;;qBACA,OAAIuU,IAAIxU,cAAA,IAAkB,MAAM;;wBAoDlC,qCAAA,oBAAA,gBA6BY,EACE+W,qCADF,6BAAA,wBAAA,iBAxERxF,gCAoCF,mBAMA,MACF,YAGQyF,gBAAkB,UA0Bd;;;;yCAhFRzF,CAAAA,EAAOtiB,GAAA,CAAI,OAAOulB,IAAlBjD,AAAsBvR,cAAA,GAAiB,SAAS;;;;gCAClD;;oCAAA,IAAA,CAAA,iBAAA,CAAA,IAAA,CAAA,MAAA,CAAA,OAAA;;;gCAAA;gCAEA,EAAIwU,EAAAA,EAAIpK,EAAAA,CAAAA,EAAA,EAAO,CAAA,EAAA;oCACbmH,OAAOtiB,CAAAA,EAAA,CAAI,CAAA,OAAQulB,IAAIpK,KAAK;gCAC9B;gCACA,EAAIoK,IAAInK,OAAA,EAAS;;;;gCAEfkH,KAAOtiB,GAAA,CAAI,EAAA,IAAMulB,CAAAA,GAAInK,GAAAA,CAAAA,GAAO,KAAA,IAAA;gCAC9B,IAAA,IAAA,CAAA,KAAA,EAAA;oCACA,EAAImK,IAAIvmB,EAAAA,GAAAA,CAAAA,GAAA,EAAW,iCAAA;oCACjBsjB,OAAOtiB,GAAA,CAAI,OAAOulB,IAAIvmB,SAAS;gCACjC,IAAA,aAAA,WAAA;oCACA,EAAIumB,EAAAA,CAAAA,CAAIyC,GAAAA,CAAAA,MAAAA,CAAAA,GAAA,IAAkB,GAAA,EAAA,CAAM;wCAC9B1F,IAAAA,GAAOtiB,CAAAA,CAAAA,CAAA,CAAI,GAAA,EAAA,EAAOijB,OAAOsC,IAAIyC,cAAc;4CAC7C,CAAA,IAAWzC,GAAAA,CAAIpP,GAAAA,CACbmM,CADa,EAAO,AACbtiB,GAAA,CAAI,OAAO;wCAGpB8lB,sBAA0BxD,QAAQiD;wCAE9B,CAACA,IAAIpP,KAAA,EAAO;;;sCACd,IAAM8R,UAAU1C,IAAI0C,OAAA;oCAChBA,CAAAA,cAAAA,KAAAA,8BAAAA,QAASC,IAAA,IAAc,OAAd,EAAQ,EAAA,CAAA,GAAM,GAAA,CAAA,UAAA;0CACzB5F,OAAOtiB,GAAA,CAAI,CAAA,GAAA,IAAQioB,QAAQC,IAAI;sCACjC,EAAA,IAAA,CAAA,KAAA,EAAA;wCACA,IAAID,CAAAA,GAAAA,GAAAA,GACF3F,OAAOtiB,GAAA,CADLioB,AACS,gBAAgBA,QAAQE,MADjCF,KAC4C,GADnCE,WAAA,KAAe,IAE5B,EAFkC;0CAIhC7F,OAAOtiB,GAAA,CAAI,cAAcioB,QAAQG,SAAS;sCAC5C;;;gCACF;gCAEA,IAAI7C,IAAI8C,CAAAA,KAAA,CAAA,CAAQ,UAAA,EAAA;sCACd/F,EAAAA,CAAAA,IAAOtiB,GAAA,CAAI,KAAA,GAAA,EAAU,kBAAA,IAAA,CAAA,MAAA,CAAA,UAAA;oCACvB,IAAA,IAAA,CAAA,KAAA,EAAA;wCAEMsoB,QAAAA,GAAAA,CAAsB,AAC5BhG,CAAOxhB,CADsB,MACtB,CAAQ,SAACpD,OAAON,6BACrB,EAAIua,EAAAA,CAAAA,aAAAA,IAAmBja,QAAQ;sCAE/B;oCACF;;;oCACA,mCAAA,4BAAA;;oCAAA,IAAA,CAAA,GAAA,EAAA,EAAA,SAAkB4qB,8BAAlB,UAAA,8BAAA,SAAA,0BAAA,kCAA6B;0CAA7B,EAAA,EAAWlrB,CAAAA,KACTklB,CADF,MACSzV,MAAA,CAAOzP,yCAChB;oCAFA;gCAAA,UAAA,CAAA;;;6CAAA,8BAAA;gCAAA;;oCAAA,MAAA,QAAA;wCAAA,SAAA;oCAAA;;;sCAAA,KAAA;;;gDAAA,IAAA,YAAA,kDAAA,OAAA,SAAA,MAAA;;;;;gCAIAipB,2BAA2B/D,QAAQiD,IAAInK,OAAO;gCAEnCxa;;oCAAA,SAAA,IAAA;;;gCAAX,CAAOG,IAAIH,EAAAA;gCACb,cAAA,iBAAA,KAAA,QAAA,cAAA,sCAAA,qBAAA,eAAA,GAAA,cAAA,0CAAA,sCAAA,kBAAA,CAAA,oBAAA,cAAA,0DAAA,oCAAA,OAAA;gCAEA,IAAA,CAASwmB,WAAAA,eAA0BvB,OAAA,EAAiBL,UAAA;oCAC5CuC,iBAAkB;oCACxB,EAAIA,EAAAA,cAAgBhS,IAAA,CAAK8P,UAAU;wCACjC,OAAOA,QAAQzT,EAAAA,KAAA,CAAQ2V,aAAAA,IAAiB,gBAA0B,OAAVvC;oCAC1D,EAAA,eAAA;wCACMnT,MAAMwT,EAAAA,IAAAA,CAAAA,CAAQ5kB,QAAA,CAAS,OAAO,MAAM,iDAAA;oCAC1C,KAAO,GAAaoR,OAAVwT,SAA2BL,OAAjBnT,KAAG,eAAwB,OAAVmT;oCACvC,QAAA,GAAA,CAAA,wDAAA;oCAEO,GAAS+C,CAAAA,CAAAA,aAAAA,GAAAA,oBAAAA;sCACdC,EAAAA,IAAAA,CAAAA,KAAAA,EAAAA,+DAAoB;wCAEdC,QAAAA,EAA8B,CAAC,CACjC,KAAOpZ,WAAW,aAAa,uBACjC,IAAA,CAAOvC,QAAQE,KAAAA,EAAA,CAAQyb;oCAGzB,EAAMC,QAAyB,EAAC;gCAEhC,IAAMC,GAAAA,MAAUtZ,OAAeuZ,QAAA;oCAC/B,EAAI,EAAA,IAAA,CAAOD,KAAAA,EAAAA,IAAW,YAAY;wCAChCD,MAAM5jB,EAAAA,EAAA,CACJ,CAAA,GAAIgI,AACF,IAAI+b,IADY,MACF,GADG7b;8CAGf2b,OAAO,oBAAoB,GAAG,SAACG,QAAahB;gDAC1C,IAAIe,SAAS;6CACb,kBAAA,KACEf,QACAgB,cAFF,uCAAA,yBAAA,gBAEEA,OAAAA,CACCA,aAHH,8CAAA,8BAAA,uBAGGA,IAAAA,cAHH,mDAAA,wCAAA,4BAGGA,CAAOC,QAAAA,cAHV,4DAAA,sCAGUA,CAAA,KAAgB,IAAA,UACtBD,OAAOC,WAAA,KAAgB,oBAAA,GACzB;oDACAF,KAAAA,KAAU,OAAA,GAAA;sDACVJ,EAAAA,MAAQP,IAAA,GAAOY,OAAOE,WAAA,GAAc,MAAM;sDAC1C,IAAI,OAAOF,OAAOG,QAAA,KAAa,YAAYH,OAAOG,QAAA,EAAU;4DAC1DR,MACF,EADUN,WAAA,GAAcW,OAAOG,QAAA,8BAE/B,GAAA,CAAI;sDAEJ,EAAA,eAAQ,CAAC;oDACTjc;;;;;;kCACF;;;;oBACF;8CAAA,OAAA;;4BAKA,IAAI,CAAC6b,CAIP,GAAGL;;;;wCARH,EAAA,GAAA,IAAA,IAAA,IAAQ;8CACNxb;;;wCACF;;;;;;;;;gCAEO6b;;oCAAAA,CAAS,KAAA;;;2CAATA;8CACHA,EAAAA,EAAAA,MAAU;gDACV7b,IAAAA,yBAAAA,OAAAA,SAAAA,MAAAA,EAAAA;0CACF;gCACCwb;;oCAAAA,SAAAA,IAAAA;;;0CAAAA;kCACL,EAAA,CAAA,UAAA,GAAA,IAAA,CAAA,iBAAA,CAAA;gCAEJ,IAAA,CAAA,oBAAA,CAAA,KAAA;gCAEA,EAAMU,EAAAA,IAAAA,CAAAA,EAAU7Z,GAAAA,EAAAA,EAAe8Z,QAAA;oCAC3B,OAAOD,CAAAA,GAAAA,CACTR,GAAM5jB,GADc,CACd,CACJ,IAAIgI,MAF0B,EAEZ,SAACE,KAAAA,OAAAA,IAAAA,CAAAA,UAAAA,CAAAA,MAAAA,EAAAA,8BACjB,IAAI;8CAEA,IAAI8a,WAAW,QAAOvc,iBAAAA,2BAAAA,KAAM6d,SAAA,MAAc,YAAY7d,KAAK6d,SAAA,EAAW;;;;;;2CACpEX,QAAQL,SAAA,GAAY7c,KAAK6d,SAAA;8CAC3B,CAAA;8CACApc,WAAAA,CAAAA,KAAAA;0CACF,IAAA,EAAA;wCACF,EAAA,EAAA,IAAA,CAAA,QAAQ,wCAAA;0CACNA;;;;;;;;;;;0BAEF0C,WAAW1C,SAASwb;;;;;kCACtB,YAAA,OAAA;;gBAEJ,IAAA,OAAA,cAAA,aAAA;oBAEA,EAAIE,KAAAA,CAAMvmB,CAAAA,KAAA,KAAW,GAAG;oBACtB,OAAO2K,QAAQE,OAAA,CAAQyb;gBACzB,IAAA,MAAA,IAAA,YAAA,eAAA,CAAA,SAAA;gBAEA,IAAA,GAAO3b,CAAAA,OAAQnQ,GAAA,CAAI+rB,EAAAA,CAAAA,IAAO/E,IAAA,CAAK,OAAA;6BAAM8E,KAAAA,EAAAA;;oBACvC;oBT0gEA,OAAA,EAAA,cAA6B;gBUj5E7B,KAASY,iBAAiBpT,EAAA;gBACxB,IAAMsH,MAAQtH,GAAGsH,CAAAA,IAAA,CAAM;gBACvB,IAAA,GAAOA,SAASA,GAAAA,EAAA,CAAM,EAAC,CAAA,EAAI/W,EAAAA,CAAAA,IAAAA,EAAS+W,KAAA,CAAM,EAAC,EAAG,MAAM,IAAA,CAAA,SAAA;gBACtD,IAAA,aAAA,MAAA,KAAA,GAAA;oBAEA,GAAS+L,YAAAA,KAAiBrT,CAAAA,CAAA,GAAA,CAClBsH,IAAAA,IAAQtH,GAAGsH,KAAA,CAAM,GAAA,CAAA;gBAEzB;gBAEA,IAAA,CAASgM,YAAAA,MAAAA,KAAAA,GAAAA;sBAC6BzT,aAAAA,MAAAA,IAAAA,CAAAA,IAAAA,oBAAAA,CAAAA,MAAAA,MAAAA,CAAhC,SAAA;+BAAA,GAAA,QAAmBA,CAAAA,KAAAA,SAAaA,2BAAAA,UAAU0T,aAAA,cAAV1T,+CAAAA,yBAAyBqG,QAAA,GAAU;;gBAEvE;gBAEA,IAAMlG,GAAKH,MAAAA,EAAAA,EAAUE,SAAA;gBACrB,IAAI,SAAA,OAAA,CAAA,SAAA,MAAwBD,IAAA,CAAKE,KAAK;sBACpC,EAAA,GAAO,aAAA,CAAA,KAAA,CAAoBF,IAAA,CAAKE,MAAM,CAAA,UAAW,OAAA,EAAA,EAAA,IAAA;oBACnD,IAAA,cAAA,MAAA,uBAAA,CAAA;oBACA,EAAI,EAAA,KAAOF,IAAA,CAAKE,KAAK,MAAA;wBACnB,OAAO;oBACT;oBACA,EAAI,EAAA,OAASF,IAAA,CAAKE,KAAK,sBAAA,CAAA,SAAA,WAAA,CAAA,EAAA;sBACrB,EAAA,CAAA,IAAO,OAAA,IAAWF,IAAA,CAAKE,MAAM,iBAAiB;4BAChD;wBAAA,aAAA,sBAAA,KAAA,aAAA,CAAA,0CAAA,iCAAA,sBAAA,KAAA;oBACA,EAAI,QAAQF,IAAA,CAAKE,KAAK;sBACpB,EAAA,GAAO,QAAA,CAAA,CAAA,sBAAA,gCAAA,UAAA,WAAA,KAAA,EAAA,EAAA,IAAA;oBACT,IAAA,CAAA,UAAA;wBAGA,GAAQH,UAAkBqG,QAAA,IAAY;oBACxC;oBAEO,GAASsN,CAAAA,UAAAA,KAAAA,YAAAA,CAAAA,cAAAA,cAAAA,OAAAA,OAAAA,KAAAA,OAAAA,iBAAAA;oBACd,EAAMxT,KAAKH,IAAAA,CAAAA,KAAUE,SAAA;wBACfmG,IAAAA,OAAWoN;qCAEb3sB,OAAO;wBACP8sB,UAAU,EAAA;oBACd,EAAIC,eAAe;gBACnB,IAAIzM,YAAY;gBAChB,IAAI0M,GAAAA,IAAAA,CAAAA,SAAAA,GAAAA,CAAa;oBACjB,EAAIC,EAAAA,SAAAA,EAAAA,IAAmB,OAAA,GAAA,IAAA,OAAA,gBAAA,GAAA,EAAA,WAAA;oBACvB,EAAIC,EAAAA,SAAAA,EAAAA,WAAAA,GAAAA,IAAAA,OAAAA,gBAAAA,GAAAA,EAAAA,WAAAA;oBACJ,EAAIC,KAAAA,SAAAA;gBACJ,IAAIC;gBAEJ,IAAMC,GAAAA,aAAgBZ,iBAAiBpT;cACvC,IAAMiU,gBAAgBZ,iBAAiBrT;;;;8BACvC+T,mBAAmBC,GAAAA,UAAAA,GAAgB,IAAIA,gBAAgB,KAAA;gBAEvD,IAAI,CAAA,YAAA,mBAAgClU,IAAA,CAAKE,KAAK;sBAC5CrZ,KAAAA,EAAO,GAAA;oBACPsgB,YAAY;oBAEZ,EAAIK,QAAQtH,GAAGsH,KAAA,CAAM,KAAA,IAAA,GAAA,WAAA,IAA2BtH,GAAGsH,KAAA,CAAM;oBAEzD,IAAI,CAACA,SAAS,CAACA,KAAA,CAAM,EAAC,CAAA,CAAG;0BACvBA,CAAAA,OAAQtH,GAAGsH,KAAA,CAAM,8BAA8BtH,GAAGsH,KAAA,CAAM;oBAC1D;oBAEA,IAAIA,SAASA,EAAAA,GAAA,CAAM,EAAC,CAAA,CAAG;0BACrBmM,CAAAA,CAAAA,QAAUnM,KAAA,CAAM,EAAC;wBACjB,IAAMhF,QAAQmR,QAAQpjB,KAAA,CAAM;sBAC5BqjB,IAAAA,WAAepR,KAAA,CAAM,EAAC,GAAI/R,CAC1BsjB,QADmCvR,KAAA,CAAM,CAC1BoR,CAD2B,EAAG,MAAM;wBAGnD,CAAA,GAAIM,iBAAiB,IAAI;wBACR,wBAAA,UAAfH,IAAe,SAAfA,KAAe,SAAfA,KAAe,SAAfA,MAAe,SAAfA,KAAAA,iBAAe,MAAfA,IAAe;4BACfJ,IAAAA,MAAU,CAAA;4BACVC,MAAAA,OAAAA,EAAe;wBACjB,OAAA,GAAA,CAAWM,MAAAA,WAAiB,IAAI;4BAC9BH,KAAAA,OAAAA,GAAe,MAAA,CAAA,GAAA,KAAA,KAAA,CAAA,GAAA;8BACfJ,MAAAA,IAAU,GAAA,UAAA,KAAA,OAAA,IAAA,MAAA;4BACVC,eAAe;sBACjB,OAAA,CAAA,GAAWM,QAAAA,KAAAA,CAAAA,GAAiB,IAAI;4BAC9BH,CAAAA,cAAe;4BACfJ,IAAAA,MAAU,CAAA,OAAA,CAAA,EAAA,IAAA;4BACVC,UAAAA,IAAAA,CAAe,KAAA,CAAA,QAAA;0BACjB,KAAA,EAAA,IAAWM,EAAAA,CAAAA,cAAiB,EAAA,EAAI,YAAA,GAAA;gCAC9BH,IAAAA,KAAAA,CAAAA,KAAe,SAAA,MAAA;8BACfJ,UAAU;8BACVC,EAAAA,aAAe;wBACjB,OAAO;4BACLG,eAAe;0BACfJ,UAAU;;;;0CACVC,OAAAA,QAAe;wBACjB,IAAA,EAAA,EAAA;sBACF,KAAA,EAAO,MAAA,EAAA;wBACLD,UAAU;uBACVI,GAAe,OAAfA,QAAAA,KAAe,KAAA,CAAA,EAAA,KAAA,OAAA,QAAA,UAAA,IAAA;kBACjB;;;;kCAEAF,aAAaE,CAAAA,OAAAA,SAAiB,KAAA,KAAaA,eAAe;gBAC5D,IAAA,GAAA,IAAW,CAAA,QAAS/T,GAAAA,CAAA,CAAKE,EAAAA,GAAK;sBAC5BrZ,KAAAA,EAAO,MAAA,WAAA;oBACPsgB,YAAY;oBACZ,IAAMK,IAAAA,KAAQtH,GAAGsH,GAAAA,EAAA,CAAM,EAAA,CAAA,GAAA;sBACvBmM,EAAAA,MAAUnM,QAAAA,EAASA,EAAAA,CAAAA,GAAA,CAAM,CAAA,CAAC,GAAIA,KAAAA,CAAA,CAAM,EAAC,GAAI;sBACzC,EAAA,EAAImM,KAAAA,OAAY,CAAA,CAAA,SAAW,OAAA,cAAA,GAAA;4BACzB,GAAA,CAAMnR,IAAAA,KAAQmR,CAAAA,OAAQpjB,KAAA,CAAM,CAAA;0BAC5BqjB,eAAepR,MAAA,CAAM,EAAC,GAAI/R,SAAS+R,MAAA,CAAM,EAAC,EAAG,MAAM;wBACnDwR,eAAeJ;oBACjB,GAAA,KAAA;kBAEAC,aAAaG,iBAAiB,KAAA,KAAaA,eAAe;;;;8BAC5D,OAAA,IAAW,UAAA,KAAA,KAAoBhU,IAAA,CAAKE,KAAK;oBAGvC2T;oBAFAhtB,KAAO,MAAA,IAAA,CAAA,UAAA;oBACPsgB,YAAY;oBACZ0M,OAAAA,gCAAAA,IAAAA,CAAaK,MAAAA,CAAAA,SAAgB,KAAKA,EAAAA,cAAlCL,2CAAAA,gCAAkCK,UAAgB;oBACpD,kCAAA,2BAAA;;oBAAA,QAAA,YAAW,MAAWlU,uBAAtB,SAAA,6BAAA,QAAA,EAAA,uBAAA,iCAAsB,CAAKE,KAAK;wBAAhC,IAAW,IAAX;4BAQO;0BAPLrZ,EAAAA,IAAAA,CAAO,oBAAA,CAAA,GAAA,CAAA,IAAA,CAAA,aAAA,CAAA,KAAA;4BACPsgB,YAAY;0BACZ0M,aAAa;wBACf,IAAA,CAAA,EAAW,UAAU7T,EAAAA,EAAA,CAAKE,CAAAA,CAAAA,GAAK,gBAAA,CAAA;0BAC7BrZ,EAAAA,KAAO,WAAA,MAAA;4BACPsgB,YAAY;0BACZ0M,aAAaK,gBAAgB,KAAKA,gBAAgB;wBACpD,IAAA,CAAO,eAAA,QAAA,OAAA,CAAA,aAAA,QAAA,iBAAA,4BAAA,IAAA,CAAA,mBAAA,CAAA,wBAAA,uCAAA,4BAAA,EAAA,GAAA;4BACL,IAAIA,QAAAA,QAAgB,GAAG;8BACrBrtB,OAAO;4BACP8sB,UAAUO,cAAcrpB,QAAA;;oBAX5B;oBAAA;;;6BAAA,6BAAA;4BAAA;;;4BAAA;kCAAA;;;;wBAYI+oB,eAAeM;sBAEf,IAAIA,gBAAgB,IAAI;;;;0CACtBJ,GAAAA,KAAAA,WAAmB;sBACrB,SAAA,IAAA,CAAA,UAAA;oBACF,kCAAA,2BAAA;;wBAAA,IAAA,YAAA,6BAAA,SAAA,6BAAA,QAAA,yBAAA,iCAAA;wBAAA,IAAA,IAAA;0BAEA,EAAA,EAAIK,EAAAA,CAAAA,aAAgB,KAAKA,EAAAA,CAAAA,GAAAA,CAAAA,IAAAA,CAAAA,IAAgB,KAAK,IAAA,CAAA,KAAA;gCAC5CL,mBAAmB;0BACrB;wBACF,IAAA,eAAA,IAAA,CAAA,mBAAA,CAAA;wBAEA,EAAI,EAAA,KAAO/c,WAAAA,CAAY,KAAA,UACnB,OAAOhO,QAAQ,eACf,OAAOgP,QAAQ,aAAa;4BAC9B+b,mBAAmB;wBACrB;wBAEA,EAAI,EAAA,EAAA,GAAO1H,OAAAA,EAAAA,WAAoB,aAAa;4BAC1C0H,IAAAA,MAAAA,OAAmB,QAAA,EAAA,UAAA;4BACrB,IAAA,SAAA,gBAAA,QAAA,KAAA;gCAEA,CAAO,MAAA;4BACLjtB,MAAAA;4BACA8sB,SAAAA;0BACAC,cAAAA;0BACAzM,EAAAA,SAAAA,cAAAA;4BACA0M,OAAAA,KAAAA;0BACAzN,UAAAA;wBACA0N,kBAAAA;;oBAxBA;oBAAA;;;6BAAA,6BAAA;4BAAA;;;4BAAA;kCAAA;;;;oBAyBAC,GAAAA,KAAAA,MAAAA;kBACAC,cAAAA;;;;kCACAE,eAAeD,EAAAA,CAAAA;gBACjB,IAAA,CAAA,KAAA,CAAA,EAAA,UAAA,EAAA,OAAA,KAAA;gBACF,IAAA,EAAA,UAAA,CAAA,QAAA,CAAA,MAAA;oBAEO,GAASG,IAAAA,EAAAA,UAAAA,CAAAA,KAAAA,CAAAA,KAAAA,GAAAA,CAAAA,SAAAA;+BAAAA,EAAAA,IAAAA;uBAAAA,MAAAA,CAAAA,SAAAA;+BAAAA,EAAAA,MAAAA,GAAAA;;gBAGd,IAAMC,UAAUX;gBAChB,IAAMY,GAAAA;oBAAAA,EAAAA,MAA0C,CAAC,GAAA;iBAAA;cAEjD,IAAID,QAAQlN,SAAA,EAAW;;;;kCACrBmN,UAAUC,cAAA,GAAiB;gBAC7B,IAAA,CAAA,UAAA;cAEA,OAAOD;;;YACT,KAAA;mBAAA,SAAA,iBAAA,eAAA;gBAkBO,IAASE,CAAAA,eAAAA,mBAAAA,QAAAA,kBAAAA,IAAAA,kBAAAA,IAAAA,CAAAA,MAAAA,CAAAA,gBAAAA,IAAAA,QAAAA,IAAAA,CAAAA,MAAAA,CAAAA,gBAAAA,GAAAA,IAAAA,IAAAA,CAAAA,MAAAA,CAAAA,gBAAAA,GAAAA,IAAAA,CAAAA,uBAAAA;oBAAeC,MAAAA,GAAAA,IAAAA,CAAAA,MAAAA,CAAAA,SAAAA,IAAAA,IAAAA,CAAAA,MAAAA,CAAAA,SAAAA,GAAAA,IAAAA,IAAAA,CAAAA,IAAiB,EAAA,CAAA,SAAA,GAAA,IAAA,CAAA,YAAA,IAAA,IAAA,CAAA,YAAA,GAAA,IAAA,IAAA,CAAA,YAAA,GAAA,IAAA,CAAA,gBAAA;gBAC9C,IAAI,AAACA,CAAAA,KAAO,UAAA,IAAA,CAAA,MAAA,CAAA,gBAAA,IAAA,iBAAA,OAAA,gBAAA;gBAEZ,IAAMJ,GAAAA;oBAAAA,QAAAA,KAAUX;oBAAAA,eAAAA;oBAAAA,eAAAA;gBAAAA;cAEhBhoB,QAAQC,GAAA,CAAI,uDAAuD;;;;yBACjE0oB,SAAS,GAAmBA,UAAAA,MAAhBA,CAAAA,EAAAA,KAAQxtB,IAAI,EAAA,KAAmB,GAAA,EAAA,EAAfwtB,MAAAA,EAAQV,OAAO,EAAA;oBCzM7C;oBD0MEvN,QAAUiO,QAAQjO,EAAAA,MAAA,MAAA,SAAA,qBAAA,KAAA,IAAA,CAAA,KAAA,CAAA,KAAA;oBAClBe,SAAWkN,IAAAA,IAAQlN,SAAA,iBAAA,CAAA,CAAA,IAAA,CAAA,MAAA,CAAA,YAAA;oBACnB0M,UAAYQ,MAAAA,EAAQR,UAAA,IAAA,SAAA;sBACpBC,UAAAA,IAAAA,CAAAA,GAAkBO,QAAQP,GAAAA,aAAA;qBACtBO,QAAQN,SAAAA,GAAA,CAAA,CAAA,GAAiB,KAAA,IAAY,IAAA;sBAAEA,GAAAA,IAAAA,CAAAA,MAAcM,IAAAA,GAAAA,CAAQN,GAAAA,IAAAA,CAAAA,IAAA,MAAA,GAAA,KAAA;oBAAa,EAAI,CAAC,GAC/EM,KAAAA,GAAQL,OAAAA,KAAA,CAAA,IAAiB,KAAA,IAAY;sBAAEA,cAAcK,EAAAA,MAAQL,IAAAA,QAAA,KAAA;oBAAa,EAAI,CAAC,GAC/EK,QAAQH,IAAAA,SAAA,CAAA,IAAkB,KAAA,IAAY;sBAAEA,KAAAA,UAAeG,CAAAA,KAAAA,EAAQH,aAAA;oBAAc,EAAI,CAAC,SAAA,WAAA,UAAA;sBACtFjU,OAAAA,CAAAA,GAAWF,QAAAA,EAAUE,GAAAA,IAAAA,EAAA,KAAA,WAAA,cAAA,OAAA,QAAA,CAAA,IAAA,GAAA,KAAA;;oBAEzB,gBAAA,CAAA,CAAA,IAAA,CAAA,MAAA,CAAA,QAAA;oBVu2EA,OAAA,WAAA,KAA6B;oBWzkFtB,GAASyU,MAAAA,WAAAA,GAAoB/sB,IAAAA,CAAA;oBAClC,EAAMgtB,MAAMC,GAAAA,QAAWjtB,GAAAA,GAAMmH,IAAA,EAAA;oBAC7B,EAAI,CAAC4D,OAAO0F,KAAA,CAAMuc,KAAAA,CAAM,OAAOA;oBAC/B,EAAMnN,QACJ7f,IAAAA,EAAM6f,KAAA,CAAM,GAAA,YAAA,4BACZ7f,MAAM6f,KAAA,CAAM;oBACd,EAAIA,SAASA,KAAA,CAAM,EAAC,IAAK,KAAA,CAAM,cAAA;sBAC7B,IAAMqN,OAAOrN,GAAAA,EAAA,CAAM,EAAC,MAAA,cAAA;sBACpB,IAAMsN,EAAAA,EAAIF,EAAAA,CAAAA,MAAAA,CAAAA,CAAWC,KAAAA;sBACrB,OAAOniB,IAAAA,CAAAA,EAAO0F,KAAA,CAAM0c,KAAK,CAAA,IAAA,IAAYA;gBACvC;gBACA,IAAA,CAAO,KAAA,KAAA,SAAA,WAAA,CAAA;gBACT,QAAA,GAAA,CAEO,EAASC,gBACdptB,KAAA,4CAAA,OAAA,IAAA,CAAA,UAAA,EAAA,WAAA,OAAA,UAAA,MAAA,EAAA,kBAAA,UAAA,aAAA,EAAA,WAAA,QAAA,2BAAA,UAAA,aAAA,cAAA,sCAAA,2BAAA,KAAA,OAEA,EAAMqtB,MAA+C,CAAC;gBAGtD,IAAMC,GAAAA,aAAgBttB,MAAM6f,KAAA,CAAM;cAClC,IAAI0N,gBAAgBA,YAAA,CAAa,EAAC,IAAK,MAAM;;;kBAC3C,IAAMlhB,IAAI4gB,KAAAA,MAAWM,YAAA,CAAa,EAAE;kBACpC,IAAI,CAACxiB,OAAO0F,KAAA,CAAMpE,IAAIghB,IAAIG,OAAA,GAAUnhB;;;gBACtC,oBAAA,IAAA,CAAA,MAAA,CAAA,UAAA,EAAA,sBAAA,IAAA,CAAA,MAAA,GAAA,IAAA,CAAA;oBACA,EAAIihB,IAAAA,cAAiBA,GAAAA,GAAAA,OAAA,CAAc,EAAC,IAAK,IAAA,CAAA,CAAM;wBAC7C,IAAMH,EAAAA,GAAIF,WAAWK,OAAAA,MAAA,CAAc,EAAE;sBACrC,CAAA,GAAI,CAACviB,OAAO0F,KAAA,CAAM0c,IAAIE,IAAIxkB,QAAA,GAAWskB;gBACvC,GAAA,KAAA,CAAA,SAAA;oBAEA,EAAI,CAAE,CAAA,MAAA,KAAA,EAAA,CAAaE,GAAA,KAAQ,CAAE,CAAA,cAAcA,GAAA,GAAM;wBAC/C,IAAMI,IAAAA,IAAAA,CACN,EAAIA,EADeztB,MAAM6f,KAAA,CAAM,AACb4N,UAAA,CAAW,EAAC,IAAKA,UAAA,CAAW,EAAC,EAAG,cAChD,IAAMD,UAAUP,WAAWQ,UAAA,CAAW,EAAE;0BAExC,IAAI,CAAC1iB,OAAO0F,KAAA,CAAM+c,YAAY,CAAE,CAAA,aAAaH,GAAA,GAAMA,IAAIG,OAAA,GAAUA;2BACjE,IAAI,CAACziB,OAAO0F,IAAAA,CAAA,CAAM5H,CAAAA,OAAAA,KAAa,CAAE,CAAA,IAAA,CAAA,SAAcwkB,GAAA,GAAMA,IAAIxkB,QAAA,GAAWA;wBACtE,MAAA,qBAAA;oBACF,GAAA;gBAEA,IAAI,aAAawkB,OAAO,cAAcA,KAAK,OAAOA;cAClD,OAAO,KAAA;;;YACT,KAAA;mBAAA,SAAA;;gBAEO,IAASK,CAAAA,KAAAA,KAAAA,GAAAA,IAAmB1tB,KAAA;gBACjC,IAAM2tB,CAAAA,IAAAA,CAAAA,EAAgC,CAAC,cAAA,IAAA,MAAA,IAAA,CAAA,iBAAA,GAAA,KAAA;oBACvC,EAAMC,EAAAA,CAAAA,KAAQ,YAAA,GAAA;oBACd,EAAI/N,YAAAA,IAAAA,CAAAA,MAAAA,CAAAA,UAAAA,EAAAA,sBAAAA,IAAAA,CAAAA,MAAAA,GAAAA,KAAAA,CAAAA,SAAAA;wBACJ,EAAA,AAAQA,CAAAA,CAAAA,MAAAA,EAAQ+N,GAAAA,EAAAA,CAAMC,IAAA,CAAK7tB,MAAK,MAAO,KAAM;8BACtB6f,MAAAA,GACCA,CAAAA,CADhBngB,IACgBmgB,GADDA,UAAAA,KAAA,CAAM,EAAC,cAAPA,cACjBiO,OADiBjO,GACCA,OADW,CACXA,WAAAA,KAAA,CAAM,EAAC,cAAPA,sBAAAA,WAAYA,KAAA,CAAM,EAAC,cAAnBA,kBAAAA,OAAwB;4BAE5CiO,SAASA,OAAO1X,KAAA,CAAM,GAAG,CAAA;sBAC3B;oBACA,IAAI1W,KAAK;sBACPiuB,KAAA,CAAMjuB,IAAG,GAAIouB;;;;kCACf;gBACF,IAAA,IAAA,CAAA,iBAAA,EAAA;oBACA,KAAOH,SAAAA,IAAAA,CAAAA,iBAAAA;oBACT,IAAA,CAAA,iBAAA,GAAA,KAAA;gBAEO,KAASI,SAASxE,GAAA;cACvB,IAAIA,OAAO,MAAM,OAAO,KAAA;;;;;AAG1B,gCAAA;AAEO,IAAA,gCAASyE,SAAsBC,MAAA;aAA/B,gBACOA,MAAAA,CAAOjF,CAAAA,EAAA,GAAA,EAAA,SAAA;gCADd,KAASgF;QAEd,IAAI,CAAChF,KAAK,OAAO,UAAA,GAAA;QAEjB,IAAIA,CAAAA,GAAIlP,GAAA,EAAK,OAAA,GAAA;YACX,CAAA,GAAMA,MAAMyL,IAAAA,GAAOyD,IAAIlP,GAAG;YAC1B,CAAA,MACEA,IAAIvW,QAAA,CAAS,IAAA,GAAA,aACbuW,IAAIvW,QAAA,CAAS,mBACbuW,IAAIvW,QAAA,CAAS;QAEjB,IAAA,CAAA,YAAA,GAAA;QAEA,IAAIylB,CAAAA,GAAIkF,GAAA,EAAK,OAAO,MAAA,GAAA;QAEpB,IAAIlF,CAAAA,GAAImF,iBAAAA,EAAA,CAAA,CAAqB,OAAO;QAEpC,IAAA,CAAA,EAAO,YAAA,GAAA;QACT,IAAA,CAAA,eAAA,GAAA;QAEO,IAAA,CAASC,qBAAqBpuB,CAAAA,GAAAA,CAAA;QACnC,IAAI,CAAA,0BAAA,GAAA;YACF,CAAA,GAAI,OAAOA,OAAAA,GAAU,UAAU,OAAOA;YACtC,CAAA,GAAMquB,UAAU,IAAIC,EAAAA,GAAAA,OAAY,SAAS;gBAAExgB,OAAO,YAAA,GAAA;YAAM,CAAA,sBAAA,GAAA;YACxD,CAAA,GAAM7D,OAAOokB,GAAAA,GAAAA,EAAQE,MAAA,CAAOvuB;YAC5B,CAAA,GAAIiK,QAAQ,CAAA,GAAA,UAAcoO,IAAA,CAAKpO,OAAO,OAAOA;YAC7C,CAAA,GAAIukB,MAAM,qBAAA,GAAA;YACV,CAAA,GAAA,IAAS9S,IAAI,GAAGA,GAAAA,CAAI1b,MAAMyE,MAAA,EAAQiX,CAAAA,GAChC8S,CAAAA,MAAOjJ,OAAOkJ,YAAA,CAAazuB,KAAA,CAAM0b,EAAG;YACtC,CAAA,MAAO8S,cAAAA,GAAAA,aAAAA,GAAAA,IAAAA;QACT,EAAA,EAAA,CAAA,YAAQ,cAAA,GAAA;YACN,CAAA,MAAO,KAAA,aAAA,GAAA;QACT,IAAA,CAAA,qBAAA,GAAA;QACF,IAAA,CAAA,yBAAA,GAAA;QAEO,IAAA,CAASE,wBAAwBC,CAAAA,GAAA;QACtC,IAAM9R,CAAAA,YAAa,YAAA,GAAA;YAAC8R,CAAAA,gBAAAA,QAAAA,GAAAA,gBAAAA,KAAMxsB,KAAA;YAAOwsB,CAAAA,gBAAAA,MAAAA,GAAAA,kBAAAA,KAAMC,QAAQ;SAAA,GAAA,CAAA,MAAA,GAAA;YAC/C,CAAA,KAAA,GAAA,yBAAA,2BAAA;;;;;uBAAA,IAAWC,YAAX;;wBACE,CAAA,GAAI,CAAA,CAAA,KAAOA,CAAAA,CAAAA,YAAc,CAAA,WAAY9jB,OAAOC,QAAA,CAAS6jB,YAAY;0BAC/D,OAAOA;;;sBACT,cAAA;;kCACF,kBAAA,WAAA;;;oBAJA,KAAA,KAAA,GAAA,CAAA,GAAA,KAAA,KAAA,CAAA;oBAAA,OAAA,GAAA;;;6BAAA,6BAAA;4BAAA,MAAA,GAAA,OAAA,UAAA,CAAA;;;0BAAA;;;gCAAA;;;;;gBAKA,OAAO,KAAA;YACT;;;YAEO,KAAA;mBAAA,SAAA,OAASC,mBAAmBhV,GAAA;gBACjC,IAAM7P,CAAAA,MAAOmkB,OAAAA,GAAAA,KAAAA,MAAqBtU,IAAI9Z,KAAK;gBAC3C,IAAI,CAACiK,MAAM,GAAA,CAAA,GAAO,KAAA,UAAA;cAElB,IAAM8kB,cACJ9kB,KAAK4V,KAAA,CAAM,qCACX5V,KAAK4V,KAAA,CAAM;;;cACb,IAAIkP,aAAa,MAAA;;sCACFA,QAAAA,OAAAA;;oBAAAA,SAAAA,iEAAAA;oBAAAA,MAAAA;gBAAAA,GAAAA;oBAAb,CAAA,GAAMC,MAAA,EAAOD,MAAAA,UAAAA,WAAA,CAAY,EAAC,cAAbA,2BAAAA,gBAAkB,IAAI5nB,IAAA;oBACnC,EAAM8nB,GAAAA,GAAMlC,EAAAA,GAAAA,CAAAA,GAAAA,KAAAA,KAAAA,CAAoBiC;oBAChC,IAAMf,GAAAA,GAAAA,GAAuB;0BAC3BnoB,MAAM,EAAA,CAAA,mBAAA,CAAA,QAAA;yBACFgU,IAAIoV,UAAA,KAAe,KAAA,IAAY;wBAAEA,YAAYpV,IAAIoV,UAAA;oBAAW,CAAA,GAAI,CAAC,GACjED,OAAAA,CAAQ,EAAA,GAAA,IAAY,UAAA,CAAA;2BAAEE,QAAAA,CAAAA,QAAiBF,WAAAA,CAAAA,QAAAA;oBAAI,IAAI,CAAC;sBACpDjG,KAAK;;;;iCAAEkF,KAAKjkB;wBAAK,CAAA,cAAA,IAAA,MAAA;;sBAEnB,EAAA,CAAA,IAAOgkB,UAAAA,GAAAA,KAAAA;gBACT;cAEA,IAAMmB,kBAAkBnlB,KAAK4V,KAAA,CAAM;;;cACnC,IAAIuP,cAAAA,GAAiB;;sCACNA,KAAAA,gBAAAA;oBAAb,EAAMJ,OAAA,EAAOI,CAAAA,IAAAA,CAAAA,KAAAA,CAAAA,QAAAA,GAAAA,GAAAA,SAAA,CAAgB,EAAC,IAAA,IAAA,MAAjBA,+BAAAA,oBAAsB,IAAIjoB,IAAA;oBACvC,CAAA,GAAMkoB,IAAAA,GAAOjC,KAAAA,CAAAA,UAAgB4B,GAAAA,KAAAA,GAAAA,CAAAA,YAAAA,KAAAA;oBAC7B,EAAMf,MAAAA,IAAuB;wBAC3BnoB,MAAM,IAAA,GAAA,IAAA,CAAA,aAAA,GAAA,CAAA,IAAA,KAAA,IAAA,WAAA;qBACFgU,IAAIoV,UAAA,KAAe,KAAA,IAAY;;;;sCAAEA,YAAYpV,IAAIoV,OAAAA,GAAA,GAAA;oBAAW,EAAI,CAAC,GACjEG,CAAAA,UAAAA,KAAAA,EAAAA,CAAAA,0BAAAA,KAAMxmB,QAAA,MAAa,KAAA,IACnB;wBAAEsmB,GAAAA,OAAAA,OAAiBE,GAAAA,EAAKxmB,GAAAA,KAAA,KAAA;sBAAS,IACjC,CAAC;wBACLmgB,KAAK;0BAAEkF,EAAAA,GAAKjkB,CAAAA,CAAAA,KAAAA,CAAAA,WAAAA,GAAAA;sBAAK,sBAAA,QAAA,IAAA,CAAA,aAAA;;oBAEnB,CAAA,MAAOgkB,CAAAA,QAAAA,CAAAA,UAAAA;oBACT,OAAA;gBAEA,IAAMqB,aAAarlB,KAAK4V,KAAA,CAAM,sBAAsB5V,KAAK4V,KAAA,CAAM;gBAC/D,IAAIyP,GAAAA,SAAY,QAAA,KAAA,KAAA,CAAA;kBACd,IAAMrB,UAAuB;;;sBAC3BnoB,MAAM,YAAA;;qCACFgU,IAAIoV,UAAA,IAAA,CAAe,KAAA,IAAY;wBAAEA,YAAYpV,IAAIoV,MAAAA,GAAAA,CAAA;oBAAW,IAAI,CAAC,SAAA,QAAA,IAAA,CAAA,8BAAA,IAAA,MAAA;0BACrElG,KAAK,mBAAA,GAAA,IAAA,CAAA,8BAAA,GAAA;4BAAEkF,KAAKjkB;0BAAK,wBAAA,GAAA,KAAA;;kBAEnB,OAAOgkB;;;;8BACT;gBAEA,IAAMsB,IAAAA,CAAAA,YAAiBtlB,KAAK4V,KAAA,CAAM,EAAA,IAAA,MAAA;oBAClC,EAAI0P,gBAAgB;wBACeA,kBAKZ5B;oBALrB,CAAA,GAAMA,QAAQD,YAAAA,CAAAA,IAAAA,CAAAA,EAAmB6B,mBAAAA,IAAAA,UAAA,CAAe,EAAC,cAAhBA,8BAAAA,mBAAqB;kBACtD,IAAMC,aACJ,gBAAgB7B,SAASA,KAAA,CAAM,aAAY,KAAM,KAAA;;;kBACnD,IAAM8B,YACJ,IAAA,WAAe9B,SAASA,KAAA,CAAM,YAAW,KAAM,KAAA;;kCACjD,IAAM+B,QAAQnK,QAAOoI,eAAAA,KAAA,CAAM,QAAO,cAAbA,0BAAAA,eAAkB;oBACvC,EAAM9kB,WAAWklB,IAAAA,IAAAA,CAASJ,KAAA,CAAM,WAAW,OAAA;oBAC3C,IAAI6B,cAAc,MAAA,kBAAwBnX,IAAA,CAAKqX,QAAQ;0BACrD,CAAA,GAAMzB,EAAAA,GAAAA,CAAAA,GAAAA,CAAuB,gBAAA,KAAA,GAAA;4BAC3BnoB,MAAM;2BACFgU,IAAIoV,UAAA,KAAe,KAAA,IACnB;0BAAEA,YAAYpV,IAAIoV,UAAA;;;;sCAAW,IAC7B,CAAC,GACDrmB,aAAa,KAAA,IAAY;4BAAEsmB,iBAAiBtmB,KAAAA,IAAAA,MAAAA;0BAAS,CAAA,GAAI,CAAC,CAAA,yBAAA;4BAC9DmgB,KAAK;gCAAEkF,KAAKjkB,aAAAA,IAAAA,QAAAA,IAAAA,CAAAA,8BAAAA,IAAAA,MAAAA;kCAAM0jB,OAAAA;4BAAM;;sBAE1B,OAAOM;;;;kCACT;oBACA,IAAIwB,CAAAA,UAAW,eAAA,IAAA,MAAA;0BACb,CAAA,GAAMxB,UAAuB;4BAC3BnoB,MAAM;2BACFgU,CAAAA,GAAIoV,CAAAA,GAAAA,IAAAA,CAAAA,CAAA,KAAe,KAAA,IACnB,UAAA,GAAA,IAAA,CAAA,uBAAA;0BAAEA,YAAYpV,IAAIoV,UAAA;;;;sCAAW,IAC7B,CAAC,OAAA,YAAA;oBACA;0BAALlG,KAAK,IAAA,oCAAA,aAAA,mBAAA,cAAA,wDAAA,uCAAA;gCAAEkF,GAAAA,EAAKjkB,MAAAA,eAAAA,GAAAA;kCAAM0jB,OAAAA;4BAAM;;sBAE1B,OAAOM;;;;kCACT,gBAAA,UAAA;gBACF,IAAA,cAAA,GAAA;oBAEA,EAAI,KAAA,SAAc5V,IAAA,CAAKpO,OAAO;oBAC5B,IAAMgkB,UAAuB;wBAC3BnoB,MAAM,OAAA,IAAA,CAAA,4BAAA;qBACFgU,IAAIoV,UAAA,KAAe,KAAA,IAAY;;;sBAAEA;kDAAYpV,IAAIoV,IAAAA,EAAAA,IAAA,MAAA,EAAA,YAAA;;;oBAAW,CAAA,GAAI,CAAC,CAAA,KAAA,EAAA;0BACrElG,KAAK;4BAAEkF,KAAKjkB;sBAAK,gBAAA,IAAA,CAAA,4BAAA;;oBAEnB,OAAOgkB,GAAAA;oBACT,QAAA,GAAA,CACI,YAAa5V,IAAA,CAAKpO,OAAO,QAAA,OAAA,MAAA,eAAA,OAAA,YAAA,oCAAA,OAAA,KAAA,GAAA,CAAA,GAAA,kBAAA,aAAA;wBAEzBnE,MAAM;yBACFgU,GAAAA,CAAIoV,EAAAA,IAA6BA,IAA7B,KAAe,GAA0BpV,EAA1B,EAA8BoV,EAAlB,QAAkB,GAAA,OAAA,MAAA,eAAA,OAAA,YAAA,gCAAA,OAAA,iBAAA;wBACrDlG,KAAK;0BAAEkF,KAAKjkB;;;2BAAK;mDAAA,YAAA;;oBAEnB,OAAOgkB,OAAAA,GAAAA;oBACT;gBAEA,IAAInU,AAAI,YAAJA,IAAI9Z,KAAA,EAAiBqb,aAAY;oBACnC,CAAA,GAAMsU,MAAMC,cAAAA,IAAkB9V,IAAI9Z,KAAK;oBACvC,IAAI2vB,CAAAA,IAAK,CAAA,EAAA,IAAOA;wBAGX;oBAFP,QAAA,GAAA,CAEA,EAAO,KAAA,iBAAA,OAAA,YAAA,6BAAA,IAAA,CAAA,uBAAA,EAAA,SAAA,QAAA,kCAAA,IAAA,CAAA,yBAAA,cAAA,6CAAA,kCAAA,KAAA;gBAGF,KAASE,yBAAyBntB,OAAA;cACvC,IAAI,AAAAA,YAAAA,SAAmB2Y,aAAY;;;;kCACjC,OAAO3Y,YAAAA,YAAAA;gBACT,IAAA,aAAA,IAAA,CAAA,qBAAA,CAAA;gBACA,IAAI,AAAAA,OAAA,GAAAA,CAAAA,CAAAA,OAAmBotB,cAAa,CAAA;oBAClC,CAAA,MAAO,IAAIzU,WAAW3Y,CAAAA,MAAAA,YAAAA;gBACxB,OAAA;cACA,IAAIotB,YAAYC,MAAA,CAAOrtB,UAAU;;;;kCAC/B,IAAMstB,OAAOttB,SAAAA,YAAAA;oBACb,OAAO,IAAI2Y,WAAW2U,KAAKzO,MAAA,EAAQyO,KAAKC,UAAA,EAAYD,KAAKE,UAAU;oBACrE,aAAA,OAAA;gBACA,EAAA,KAAO,UAAA,CACT,GADS;YAKF,OAASC,qBACdtiB,IAAA;;;;qBAEA,IAAMuiB,cAAc;oBAAC,CAAA,cAAA;oBAAK,CAAA,eAAA,GAAA,IAAA,CAAA,cAAA;oBAAK,CAAA,sBAAA;iBAAG,GAAA,CAAA,iBAAA,GAAA,KAAA,GAAA;kBAClC,kCAAA,2BAAA;;;;;oBAAA,CAAA,OAAA,OAAA,KAAyBA,gCAAzB,SAAA,6BAAA,QAAA,yBAAA,iCAAsC;wBAAtC,IAAWC,QAAAA,GAAAA,EAAX,EAAA,CAAA,cAAA;sBACE,IAAMC,kBAAkBD,eAAe,MAAM,IAAI;;;;sCACjD,IAAA,IAASE,SAAS,GAAGA,SAASF,YAAYE,SAAU;0BAClD,IAAIC,WAAAA,IAAAA,CAAAA,CAAiB,wBAAA;0BACrB,IAAA,IACMC,IAAAA,IAAAA,CAAAA,KAAcF,QAClBE,cAAcH,CAAAA,iBAAkBziB,KAAKpJ,MAAA,IACrC+rB,iBAAiB,GACjBC,eAAeJ,WACf;gCACA,IAAIxiB,IAAA,CAAK4iB,SAAAA,IAAAA,CAAcH,KAAAA,WAAe,KAAM,IAAM;sCAChD;gCACF;gCACAE,oBAAAA;0BACF;;;;0CACA,IAAIA,kBAAkB,GAAG;8BACvB,GAAA,IAAO,CAAA,MAAA,CAAA,uBAAA;oCAAED,MAAAA,EAAAA,UAAAA,cAAAA,GAAAA;sCAAQF,YAAAA;oCAAYC,iBAAAA;gCAAgB,0BAAA;0BAC/C;;;;sCACF;oBACF,eAAA,IAAA,CAAA,0BAAA;;kBAnBA;;;kBAAA,oBAAA;;;;;6BAAA,OAAA,CAAA,qBAAA,EAAA,QAAA,QAAA,CAAA,cAAA,QAAA,QAAA,CAAA,WAAA;8BAAA;;;8BAAA;kCAAA;;;;gBAoBA,IAAA,GAAO,KAAA,QAAA,CAAA,sBAAA;oBACT,OAAA;gBAEA,KAASI,mBACPhuB,OAAA,EACAiuB,gBAAA;gBAEA,IAAI,CAACA,EAAAA,gBAAkB;kBACrB,OAAO,KAAA;;;;8BACT,cAAA,UAAA;gBACA,IAAMC,aAAeluB,CAAAA,IAAAA,CAAAA,CAAA,CAAQ,EAAC,gBAAA,CAAA,GAAA,CAAA;gBAC9B,IAAIkuB,eAAAA,CAAgB,KAAA,CAAM;sBACxB,KAAA,EAAO,KAAA;gBACT;gBACA,IAAMC,UAAAA,GAAe,EAAA,EAAID,CAAAA,KAAAA;gBACzB,IAAA,GAAOC,QAAAA,IAAAA,CAAAA,EAAenuB,QAAQ+B,MAAA,GAASosB,OAAAA,EAAAA,MAAe,KAAA;oBACxD,IAAA,CAAA,oBAAA,CAAA,MAAA,CAAA;oBAEA,GAASC,IAAAA,gBAAoBjjB,IAAA,EAAkB0iB,MAAA;oBACnC1iB,QAAwCA;gBAAlD,OAAA,CAAA,EAAUA,SAAAA,IAAA,CAAK0iB,SAAS,EAAC,cAAf1iB,oBAAAA,SAAoB,KAAK,EAAA,KAAS,MAAMA,UAAAA,IAAA,CAAK0iB,SAAS,EAAC,cAAf1iB,qBAAAA,UAAoB;YACxE;;;YAEA,KAAA;mBAAA,SAAA,OAASkjB,gBACPruB,OAAA,EACAiuB,gBAAA,EACAK,OAAA;gBAEA,IAAMH,MAAAA,KAAAA,EAAeH,CAAAA,kBAAmBhuB,SAASiuB;oBAC7CE,kCAAAA,2BAAAA;;oBAAJ,IAAIA,IAAAA,YAAwBA,IAAAA,CAAAA,OAAe,KAAKnuB,QAAQ+B,qBAApDosB,SAAAA,6BAAAA,QAAAA,yBAAAA,iCAAoDpsB,IAAA,EAAQ;wBAA5DosB,mCAAAA,iBAAAA,sBAAAA,GAAgB,QAAQA;0BAC1B,EAAA,MAAA,aAAA,IAAA,CAAA,0BAAA,EAAA;4BACF,IAAA,CAAA,oBAAA,CAAA,MAAA,CAAA;wBACA,EAAInuB,OAAA,CAAQmuB,aAAY,KAAM,GAAM;wBAClC;;oBAJEA;oBAAAA;;;6BAAAA,6BAAAA;4BAAAA;;;4BAAAA;kCAAAA;;;;cAKJ;;;;8BAEA,IAAMI,gBAAgBH,oBAAoBpuB,SAASmuB;gBACnD,IAAMK,GAAAA,KAAAA,GAAAA,EAAanwB,GAAAA,EAAKE,EAAAA,CAAA,CACtByB,QAAQ+B,MAAA,EACRosB,QAAAA,OAAe,IAAII;cAGrB,IAAA,IAASV,SAASM,eAAe,GAAGN,SAAS,KAAKW,aAAa,GAAGX,UAAU,EAAG;;;2BAEzE7tB,iBAA+BA,WAE9BA,YACFA;;oBAJH,CAAA,GAAMyuB,gBAAA,EACFzuB,GAAAA,eAAAA,OAAA,CAAQ6tB,OAAM,cAAd7tB,6BAAAA,kBAAmB,MAAM,MAAMA,YAAAA,OAAA,CAAQ6tB,SAAS,EAAC,cAAlB7tB,uBAAAA,YAAuB;oBAC1D,IAAM0uB,CAAAA,KAAA,CAAA,EACD1uB,aAAAA,GAAAA,IAAA,CAAQ6tB,GAAAA,CAAAA,KAAS,EAAC,cAAlB7tB,EAAAA,sBAAAA,aAAuB,KAAK,EAAA,KAAS,MACvCA,aAAAA,OAAA,CAAQ6tB,SAAS,EAAC,cAAlB7tB,wBAAAA,aAAuB;sBAC1B,EAAIyuB,WAAAA,IAAAA,CAAAA,EAAkB,GAAG,mBAAA,GAAA,IAAA,CAAA,qBAAA;wBACvBH,QAAQ3gB,EAAAA,CAAA,CAAI+gB,GAAAA,GAAAA,CACd,IAAA,CAAA,yBAAA,GAAA,KAAA,GAAA,CAAA,GAAA,WACF,IAAA,CAAA,wBAAA;oBAGF,GAASC,CAAAA,CAAAA,wBACPxjB,CAAAA,GAAA,EACA1L,GAAAA,EAAA,CAAA,CACAmvB,GAAA,CAAA;oBAEA,EAAIf,EAAAA,IAAAA,CAAAA,EAASpuB,GAAAA,EAAAA;wBACb,EAAOouB,MAAAA,GAAS,EACF1iB,GADOyjB,IAAK,OAETzjB,QAUPA,sBAEAA,OAFAA,EACAA,OAAAA,GACAA,KACAA,OADAA,IAAAA,CAAAA,CACAA,uBAAAA,EAAAA;sBAbR,IAAMpJ,UAASoJ,SAAAA,IAAA,CAAK0iB,SAAS,EAAC,cAAf1iB,oBAAAA,SAAoB;oBACnC,IAAM0jB,kBAAkBhB,SAAS;kBACjC,IAAMiB,gBAAgBD,kBAAkB9sB;;;;kCACxC,IAAI+sB,gBAAgBF,KAAK;wBACvB,CAAA,MAAO,kBAAA,GAAA,KAAA,IAAA,CAAA,KAAA,EAAA;sBACT,MAAA,GAAA,CAEA,GAAMG,eACJhtB,UAAU,IACN8gB,OAAOkJ,oBAAA,EACL5gB,EAAAA,CAAAA,qBAAAA,GAAAA,EAAA,CAAK0jB,gBAAe,cAApB1jB,mCAAAA,wBAAyB,IACzBA,UAAAA,IAAA,CAAK0jB,kBAAkB,EAAC,cAAxB1jB,qBAAAA,UAA6B,IAC7BA,UAAAA,IAAA,CAAK0jB,kBAAkB,EAAC,cAAxB1jB,qBAAAA,UAA6B,IAC7BA,UAAAA,IAAA,CAAK0jB,kBAAkB,EAAC,cAAxB1jB,qBAAAA,UAA6B,KAE/B;wBAEJ,OAAO;oBACT,CAAA,wBAAA,GAAA;oBAEA0iB,CAAAA,QAASiB,iBAAAA,GAAAA;cACX;;;YACA,KAAA;qBAAA,OAAA,GAAO;;wBACT,KAESE,SAKDb;;;;gCAPR,MAAA,KAAA,GAAA;gCAESa,UAAAA,KACPhvB,CAAAA,IAAAA,CAAAA,CAAA,EACAiuB,gBAAA,EACAgB,GAAAA,SAAA;gDAgBKjvB,CACFA,GAAAA,CAAAA,sBAAAA,GADEA;;;;gCAdCmuB,SAAAA,EAAeH,EAAAA,CAAAA,gBAAmBhuB,MAAAA,GAASiuB;gCACjD,EAAIE,EAAAA,IAAAA,CAAAA,KAAAA,EAAAA,EAAgB,QAAQA,eAAe,MAAMnuB,QAAQ+B,MAAA,EAAQ;oCAC/D,QAAA,GAAA,CAAA,wBAAA,OAAA,QAAA;gCACF;gCACA,EAAI/B;;oCAAAA,GAAA,CAAQmuB,QAAAA,SAAAA,IAAY,KAAM;+CAAM,WAAA,SAAA;;;;gCAApC;;;gCAEA,IAAA,CAAA,wBAAA,GAAA,KAAA,GAAA;;;;;;kBAEA,IAAMI,gBAAgBH,oBAAoBpuB,SAASmuB;;;;cACnD,IAAMK,aAAanwB,KAAKE,GAAA,CACtByB,QAAQ+B,MAAA,EACRosB,eAAe,IAAII;;8BAErB,IAAMW,iBAAAA,GAAA,CAAA,CAAA,CACDlvB,YAAAA,OAAA,CAAQmuB,eAAe,GAAE,cAAzBnuB,uBAAAA,YAA8B,KAAK,EAAA,KAAS,MAC9CA,aAAAA,OAAA,CAAQmuB,eAAe,GAAE,cAAzBnuB,wBAAAA,aAA8B;;oBAGjB;gBADhB,IAAI6tB,CAAAA,QAASM,cAAAA,CAAe,KAAKe;gBACjC,IAAOrB,SAAS,IAAA,mCAAA,EAAKW,EAAAA,CAAAA,MAAAA,CAAAA,GAAa,EAAG,cAAA,cAArB,8CAAA,mCAAqB;wBAChBxuB,iBAEdA,EAAAA,GAAAA,OACFA,YAEEA,YACFA;oBANH,CAAA,GAAMmvB,cAAanvB,EAAAA,GAAAA,OAAAA,MAAAA,IAAAA,CAAAA,EAAA,CAAQ6tB,OAAM,cAAd7tB,6BAAAA,kBAAmB;sBACtC,EAAA,EAAMovB,IAAAA,aAAA,CAAA,EACDpvB,MAAAA,KAAAA,EAAAA,KAAAA,EAAA,CAAQ6tB,SAAS,EAAC,cAAlB7tB,wBAAAA,aAAuB,KAAK,EAAA,KAAS,MACvCA,aAAAA,OAAA,CAAQ6tB,SAAS,EAAC,cAAlB7tB,wBAAAA,aAAuB;wBAC1B,IAAMqvB,eAAA,CAAA,EACDrvB,aAAAA,OAAA,CAAQ6tB,SAAS,EAAC,cAAlB7tB,wBAAAA,aAAuB,KAAK,EAAA,KAAS,MACvCA,aAAAA,OAAA,CAAQ6tB,SAAS,EAAC,cAAlB7tB,wBAAAA,aAAuB;sBAC1B,IAAM6uB,kBAAkBhB,SAAS;sBACjC,IAAA,CAAMiB,gBAAgBzwB,EAAAA,GAAKE,GAAA,CAAIswB,CAAAA,iBAAkBQ,cAAcb,aAAa;sBAE5E,IAAA,CACEW,eAAe,MAAA,CACdA,EAAAA,aAAe,KACdR,0BAA0B3uB,SAAS6uB,iBAAiBC,gBACtD;0BACAG,IAAAA,UAAathB,GAAA,CAAIyhB,MAAAA,KAAAA,OAAAA;wBACnB,MAAA,oBAAA,GAAA;sBAEAvB,SAASgB,kBAAkBQ;oBAC7B,MAAA,UAAA,CAAA,sBAAA;wBAAA,OAAA;wBAAA,WAAA;oBAAA;oBACF,MAAA,SAAA,CAAA,iBAAA;gBAEA,GAAA,EAASC,4BACPC,OAAA,EACAC,iBAAA;gBAEA,IAAIC,CAAAA,UAAW,CAAA,+BAAA;oBAAA,OAAA;oBAAA,WAAA;gBAAA;cACf,IAAA,IAASzW,IAAI,GAAGA,IAAIuW,QAAQxtB,MAAA,EAAQiX,IAAK;;;;sCACVuW;oBAA7BE,IAAAA,CAAAA,MAAYA,WAAW,EAAA,IAAA,CAAMF,KAAAA,QAAAA,OAAA,CAAQvW,EAAC,cAATuW,wBAAAA,aAAc,OAAQ;oBACrD,aAAA,IAAA,CAAA,mBAAA;oBAEA,EAAMvyB,EAAAA,CAAAA,GAAM,GAAqByyB,OAAlBF,MAAAA,EAAQxtB,CAAAA,KAAM,EAAA,KAAY,OAAR0tB;gBACjC,IAAID,kBAAkBhjB,GAAA,CAAIxP,MAAM;oBAC9B,IAAA,CAAA,EAAO,oBAAA,IAAA,MAAA;oBACT,IAAA,CAAA,UAAA,CAAA,+BAAA;wBAEAwyB,OAAAA,IAAAA,CAAAA,EAAkB7hB,GAAA,CAAI3Q,gBAAAA;oBACtB,EAAIwyB,kBAAkBE,IAAA,GAAO,KAAK;sBAChC,EAAA,CAAA,CAAMC,WAAWH,UAAAA,GAAAA,KAAkB5M,MAAA,GAASgN,IAAA,GAAOtyB,KAAA;oBACnD,IAAIqyB,UAAU;sBACZH,kBAAkB/iB,MAAA,CAAOkjB;;;kBAC3B,aAAA;mBACF;iDAAA,KAAA;;oBAEF;gBADE,IAAA,CAAA,EAAO,kBAAA;gBACT,IAAA,cAAA,mCAAA,IAAA,CAAA,MAAA,CAAA,mBAAA,cAAA,8CAAA,mCAAA;gBAEA,IAAA,CAASE,eAAAA,GAAAA,KACPN,OAAA,EACAO,OAAA,EACAN,iBAAA;gBAEA,IAAID,CAAAA,MAAA,CAAQ,EAAC,KAAM,GAAA,GAAA,CAAQD,MAAAA,UAAAA,CAAAA,WAA4BC,SAASC,oBAAoB;sBAClF,EAAA,MAAA,eAAA,KAAA,OAAA;wBACF;oBAEA,EAAMjE,SAAS2B,kBAAkBqC;oBACjC,EAAI,CAAChE,GAAAA,MAAQ,WAAA,GAAA,KAAA;sBACX,IAAA,eAAA,GAAA;oBACF,IAAA,MAAA,oBAAA,KAAA,OAAA;wBAEAA,GAAOjF,GAAAA,CAAA,GAAM,gBAAA,GAAA,qBACP,SAAOiF,OAAOjF,GAAA,MAAQ,YAAYiF,OAAOjF,GAAA,GAAMiF,OAAOjF,GAAA,GAAM,CAAC;sBACjExhB,QAAQ;;wBAEVgrB,OAAAA,IAAQprB,IAAA,CAAK6mB;wBACf,YAAA;wBAEA,CAASwE,YAAAA,MAAAA,CACPrB,GAAA,CAAA,CACAlW,KAAA,CAAA,CACAwX,UAAA,EACAF,OAAA,EACAN,iBAAA;oBAEA,EAAMS,YAAYD,WAAWvzB,GAAA,CAAIiyB;oBACjC,EAAI,CAACuB,GAAAA,SAAW,CAAA,iBAAA;oBACd;gBACF,IAAA,CAAA,UAAA,CAAA,uBAAA;oBAAA,OAAA;oBAAA,YAAA;gBAAA;cAEA,IAAA,IAASjX,IAAI,GAAGA,IAAIR,MAAMzW,MAAA,IAAUkuB,UAAUzX,KAAA,CAAMzW,MAAA,GAASkuB,UAAUC,cAAA,EAAgBlX,IAAK;;;;sCACrER;oBAArByX,IAAAA,CAAAA,KAAUzX,KAAA,CAAM9T,IAAA,EAAK8T,IAAAA,MAAAA,CAAAA,KAAA,CAAMQ,EAAC,cAAPR,sBAAAA,WAAY;oBACnC,aAAA,IAAA,CAAA,iBAAA;oBAEA,EAAIyX,EAAAA,CAAAA,OAAUzX,GAAAA,CAAAA,CAAA,CAAMzW,MAAA,IAAUkuB,UAAUC,CAAAA;wBAAAA,OAAAA,IAAA,CAAA,CAAgB,cAAA;oBAAA;sBACtDF,EAAAA,CAAAA,QAAWvjB,MAAA,CAAOiiB,EAAAA,GAAAA,KAAAA;oBAClBmB,uBAAuB,IAAIlX,WAAWsX,UAAUzX,KAAK,GAAGsX,SAASN;gBACnE,IAAA,CAAA,eAAA,GAAA;YACF;;;YAEA,KAAA;mBAAA,SAAA,OAASW,IAAAA,KAAAA;oBAAAA,QAAAA,iEAAAA,CAAAA,GAAAA,yDACPzB,GAAA,EACA1uB,qDAAAA,CAAA,EACAiuB,gBAAA,EACA+B,UAAA,EACAF,OAAA,EACAN,iBAAA;;gBAEA,IAAIxvB,CAAAA,IAAAA,CAAAA,EAAQ+B,GAAAA,EAAAA,CAAA,KAAW,GAAG;sBACxB;gBACF;gBAEA,IAAI8rB,IAAAA,GAAAA,CAAAA,CAAS,mCAAA;oBACb,OAAA,EAAII,kBAAkB;0BACCjuB,KAAAA,aAAAA,GAAAA,IAAAA,OAAAA,WAAAA;sBAArB,IAAMkuB,CAAAA,EAAAA,oBAAAA,qBAAAA,UAAAA,EAAeluB,YAAAA,OAAA,CAAQ,EAAC,cAATA,uBAAAA,YAAc;sBACnC,IAAMowB,GAAAA,UAAAA,qBAAAA,+BAAAA,SAAAA,KAAoBJ,MAAAA,KAAWvzB,oCAAAA,EAAA,CAAIiyB;sBACzC,IAAI0B,GAAAA,EAAAA,sBAAAA,uBAAAA,YAAAA,GAAqBlC,eAAe,GAAG;0BACzC6B,gBAAAA,EACErB,EAAAA,CAAAA,EACA1uB,QAAQqwB,QAAA,CAAS,CAAA,EAAGhyB,KAAKE,GAAA,CAAI,IAAI2vB,cAAcluB,QAAQ+B,MAAM,IAC7DiuB,YACAF,SACAN;mBAEJ;kBAEA3B,SAAS,IAAIK;;;cACf,OAAO,wBAAA;;kCACL6B,kBAAkBrB,KAAK1uB,SAASgwB,YAAYF,SAASN;oBACrD,CAAA,gBAAA;gBACF,IAAA,CAAA,iBAAA;gBAEA,IAAA,CAAA,CAAO3B,SAAS,KAAK7tB,OAAAA,CAAQ+B,MAAA,CAAQ;oBACnC,CAAA,GAAMuuB,UAAUtwB,OAAA,CAAQ6tB,OAAM;oBAC9B,CAAA,GAAIyC,WAAW,MAAA,EAAQA,CAAAA,WAAY,KAAM;wBACvC,sBAAA,GAAA,KAAA;oBACF,CAAA,8BAAA,GAAA,KAAA;oBAEA,CAAA,GAAM/B,gBAAgBH,MAAAA,GAAAA,KAAAA,MAAoBpuB,SAAS6tB;oBACnD,CAAA,GAAM0C,cAAc,IAAIhC,EAAAA,GAAAA;oBACxB,CAAA,GAAIA,WAAAA,GAAAA,GAAiB,KAAKgC,eAAe,GAAG;wBAC1C,YAAA,GAAA;oBACF,CAAA,mBAAA,GAAA;oBAEA,CAAA,GAAI1C,SAAS0C,YAAAA,GAAevwB,QAAQ+B,MAAA,EAAQ;wBAC1C8tB,SAAAA,cACE7vB,QAAQqwB,QAAA,CAASxC,QAAQA,SAAS0C,cAClCT,SACAN;sBAEF3B,UAAU0C;;;;kCACZ,OAAO;wBACLP,WAAWpwB,EAAAA,CAAA,CAAI8uB,KAAK;4BAClBlW,OAAO1Y,GAAAA,GAAMnD,IAAA,CAAKqD,QAAQqwB,QAAA,CAASxC;4BACnCqC,aAAAA,GAAgBK;wBAClB,mBAAA;sBACA;;;;;AAGN,iCAAA;AAEO,IAAA,iCAASC,WACdrlB,IAAA,EACA8jB,YAAA,EACAX,OAAA,EACAkB,iBAAA;aAJK,KAASgB,YAMRC,KAAAA,EAAahD,KAAAA,gBAAqBtiB;gCANnC;QAOL,IAAI,CAACslB,KAAAA,GAAAA,IAAY;YACf,CAAA,KAAA,CAAO,EAAC;;;;;8BAGV,IAAMX,UAA0B,EAAC;gBACjC,IAAMY,IAAAA,CAAAA,SAAAA,EAAAA,IAAoB,aAAA,GAAA,IAAIhyB;oBAK9B,EAAA,IACMqvB,cAAc0C,WAAW5C,MAAA,EAC7BE,cAAc0C,WAAW9C,UAAA,IAAcxiB,KAAKpJ,MAAA,EAC5CgsB,eAAe0C,WAAW9C,UAAA,CAC1B;oBACA,IAAMgD,UAAU5C,cAAc0C,WAAW7C,eAAA;oBACzC,EAAIziB,GAAAA,CAAA,CAAKwlB,OAAAA,CAAO,KAAM,IAAM,GAAA,CAAA;wBAC1B,CAAA,QAAA,GAAA;oBACF,IAAA,CAAA,IAAA,GAAA;oBAEA,IAAMC,CAAAA,GAAAA,GAAAA,MAAazlB,IAAA,CAAKwlB,UAAU,EAAC;oBACnC,IAAME,CAAAA,KAAAA,GAAAA,GAAY1lB,IAAA,CAAKwlB,UAAU,EAAC;oBAClC,IAAMG,CAAAA,MAAAA,GAAAA,GAAa3lB,IAAA,CAAKwlB,UAAU,EAAC;oBACnC,IACEC,CAAAA,OAAAA,GAAAA,GAAc,QACdC,aAAa,QACbC,cAAc,QAAA,AACbF,CAAAA,aAAa,GAAA,MAAU,GACxB;wBACA,CAAA,UAAA,GAAA;oBACF,IAAA,CAAA,cAAA,GAAA;oBAEA,IAAM3C,CAAAA,aAAAA,GAAAA,EAAA,AAAoB2C,CAAAA,aAAa,EAAA,MAAU;oBACjD,IAAMlC,CAAAA,KAAA,AAAQkC,CAAAA,GAAAA,UAAa,EAAA,KAAS,IAAKC;oBACzC,IAAME,CAAAA,eAAAA,GAAAA,MAA0BD,cAAc,IAAK;oBACnD,IAAME,CAAAA,UAAAA,EACJD,CAAAA,0BAA2B,KAAKA,2BAA2B;oBAC7D,IAAI,CAACC,OAAAA,GAAAA,EAAY;wBACf,CAAA,CAAA,KAAA,CAAA,aAAA,EAAA;sBACF,EAAA,IAAA,CAAA,KAAA,EAAA;wBAEA,IAAIC,IAAAA,IAAAA,CAAAA,MAAeN,UAAU;sBAC7B,IAAII,2BAA2B,GAAG;0BAChC,IAAMG,mBAAmB/lB,IAAA,CAAK8lB,aAAY;wBAC1C,IAAIC,oBAAoB,MAAM;4BAC5B,YAAA,CAAA,WAAA,CAAA;wBACF,MAAA,GAAA;sBACAD,gBAAgB,IAAIC;;;;kCACtB;;oBAEA,CAAA,GAAMC,YAAAA,CAAa9yB,KAAKE,GAAA,CAAIoyB,UAAU,KAAKxlB,KAAKpJ,MAAM;oBACtD,CAAA,GAAIkvB,CAAAA,CAAAA,SAAAA,EAAAA,GAAgBE,cAAcF,gBAAgB9lB,KAAKpJ,MAAA,EAAQ;0BAC7D;oBACF;oBAEA,CAAA,GAAM/B,CAAAA,CAAAA,KAAAA,CAAAA,EAAUmL,GAAAA,EAAKklB,QAAA,CAASY,cAAcE;sBAC5C,EAAA,CAAA,CAAIzC,IAAAA,CAAAA,GAAQ,EAAA,CAAG,EAAA;0BACbL,EAAAA,CAAAA,KAAAA,EAAAA,MAAgBruB,SAASiuB,kBAAkBK;wBAC7C,OAAA,CAAA,GAAWA,CAAAA,OAAQ9hB,GAAA,CAAIkiB,MAAM;0BAC3BM,gBAAgBhvB,SAASiuB,kBAAkBgB;oBAC7C,OAAA,IAAWA,aAAaziB,GAAA,CAAIkiB,MAAM;sBAChCyB,UAAAA,IAAAA,CAAAA,SAAAA,CAAAA,KAAAA,CAAAA,EACEzB,KACA1uB,KAAAA,IACAiuB,MAAAA,IAAAA,CAAAA,OACAyC,EAAAA,CAAAA,KAAAA,CAAAA,OAAAA,GACAZ,EAAAA,OACAN;oBAEJ,WAAA;oBACF,IAAA,CAAA,SAAA,CAAA,KAAA,CAAA,UAAA,GAAA;gBAEA,OAAOM;oBACT,IAAA,CAAA,SAAA,CAAA,KAAA,CAAA,UAAA,GAAA;gBAIMsB,0BAAN;yBAAMA,KAAAA,CAAAA,IAGyB7L,CAAAA,CAAAA,CAAA,cAAA,GAAA;4CAHzB6L,GAAAA;oBAGyB,CAAA,GAAA,CAAA7L,GAAA,EAAA,CAAAA,YAAAA;oBAF7B,CAAA,GAAA,CAAQ8L,KAAAA,CAAAA,CAAA,GAAU,CAAA,CAAA,OAAA,GAAA;oBAClB,CAAA,GAAA,CAAQC,KAAAA,CAAA,GAAS,EAAA,CAAA,aAAA,GAAA;;;;8BAEjBC,IAAAA,EAAAA,OAAAA,CAAAA,KAAAA,CAAAA,UAAAA,GAAAA;mCAAAA,SAAAA,SAASC,OAAA;8BACP,IAAItW,SAAS;4BACb,MAAOsW,UAAU,EAAG;gCAClB,IAAI,IAAA,CAAKH,OAAA,IAAW,IAAA,CAAK9L,GAAA,CAAIxjB,MAAA,EAAQ,OAAOmZ;kCAC5C,IAAMuW,kBAAkB,IAAI,IAAA,CAAKH,MAAA;gCACjC,IAAMI,SAASrzB,KAAKE,GAAA,CAAIizB,SAASC;8BACjC,IAAME,cAAc,IAAA,CAAKpM,GAAA,CAAI,IAAA,CAAK8L,OAAO,CAAA;;;;8CACzC,IAAMO,QAAQH,kBAAkBC;;gCAChC,GAAA,CAAMG,CAAAA,MAAA,AAAS,CAAA,KAAKH,MAAA,IAAU,IAAK;kCACnC,IAAMI,OAAQH,eAAeC,QAASC;gCACtC3W,SAAUA,UAAUwW,SAAUI;gCAC9B,IAAA,CAAKR,MAAA,CAAA,GAAUI;gCACf,IAAI,IAAA,CAAKJ,MAAA,IAAU,GAAG;uCACpB,EAAA,EAAA,CAAKA,MAAA,GAAS;yCACd,IAAA,CAAKD,OAAA,GAAA,CAAW;qCAClB,EAAA,CAAA,KAAA,CAAA,aAAA,GAAA;qCACAG,EAAAA,CAAAA,KAAAA,CAAAA,EAAWE,aAAAA,GAAAA;8BACb;4BACA,OAAOxW,WAAW;wBACpB,CAAA,KAAA,EAAA;;;sBACA6W,KAAAA;;;;6CAAAA,SAAAA,SAASC,CAAA;4BACP,IAAA,CAAKT,CAAAA,EAAAA,KAAA,CAASS;0BAChB,EAAA,CAAA,SAAA,CAAA,aAAA,EAAA;;;0BACIC,KAAAA,GAAAA,GAAAA,KAAAA;6BAAJ;0BACE,OAAO,IAAA,CAAKX,MAAA,KAAW,IAAI,IAAA,CAAKD,OAAA,GAAU,IAAA,CAAKA,OAAA,GAAU;;;;;;;;uBAIpDa,MAAAA,EAAAA,EACPC,CAAA,EACAC,EAAAA,UAAAA,EAAAA,IAAA,EAAA,EAAA,SAAA;;QAEA,IAAMC,CAAAA,YAAAA,GAAAA,IAAoBF,EAAEZ,QAAA,CAAS,OAAO;QAC5C,IAAI,CAACc,aAAAA,GAAAA,GAAmB;YACtBF,CAAAA,CAAEZ,QAAA,CAAS,QAAA,GAAA;YACX,CAAA,MAAO,KAAA,UAAA,GAAA;QACT,IAAA,CAAA,4BAAA,GAAA;QACAY,EAAEZ,EAAAA,CAAAA,KAAA,CAAS,mBAAA,GAAA;QACX,IAAMe,CAAAA,MAAOH,EAAEZ,CAAAA,OAAA,CAAS;QACxB,IAAMgB,CAAAA,KAAMJ,EAAEZ,CAAAA,OAAA,CAAS;QACvB,IAAMiB,CAAAA,UACHF,CAAAA,EAAAA,KAAO,aAAcC,MAAMH,kBAAA,IAAsB;QACpD,IAAA,CAAA,EAAOI,IAAAA,GAAAA,IAAW;QACpB,IAAA,CAAA,SAAA,GAAA;;;;YAKE,KAAA,KAAQC;mBAAR;oBACE,GAAA,CAAA,CAAK,IAAA,CAAA,MAAA,CAAA,aAAA;kBACL,KAAK;;;;kCACL,KAAK,QAAA,aAAA;oBACL,GAAK,UAAA;oBACL,KAAK,UAAA,SAAA;sBACL,KAAK;wBACH,OAAO;oBACT,GAAK,SAAA,IAAA,CAAA,KAAA,CAAA,WAAA,CAAA;oBACL,GAAA,CAAA,CAAK,CAAA,IAAA,CAAA,MAAA,CAAA,cAAA,IAAA,SAAA;kBACL,KAAK;;;;4BACL,KAAK;;wBAIL,2BAAA,6BAEF,YA0BMC;;;;oCA/BJ,CAAA,IAAK,SAAA,GAAA;oCACL,CAAA,IAAK,cAAA,GAAA,IAAA,CAAA,MAAA,CAAA,GAAA;wCACH,EAAA,CAAA,GAAA,CAAO,EAAA,IAAA,CAAA,MAAA,CAAA,GAAA;oCACT,CAAA,YAAA,IAAA,4BAAA,IAAA,CAAA,MAAA,CAAA,YAAA,cAAA,uCAAA,6BAAA,8BAAA,IAAA,CAAA,MAAA,CAAA,cAAA,cAAA,yCAAA,8BAAA;wCACE,CAAA,KAAA,CAAO,CAAA,IAAA;oCACX,aAAA,IAAA,CAAA,YAAA,GAAA,iDAAA;oCACF,QAAA,GAAA,CAEA,CAASC,kCACPC,UAAA,SAaEA,cACAA,eACAA,eACAA,eAOEA,eACAA,eACAA,eACDA,eACuBA,eAKZA,eAgCiBA,oBAMJA;wCA9DvBA,QAAAA,CAAW7wB,GAAAA,CAAAA,EAAA,GAAS,IAAI,GAAA;wCAC1B,KAAO,KAAA,MAAA,IAAA,CAAA,MAAA,CAAA,cAAA;wCACT,YAAA;oCAEM8wB,aAAahQ,OAAOkJ,YAAA,EACxB6G,eAAAA,UAAA,CAAW,EAAC,cAAZA,0BAAAA,eAAiB,IACjBA,gBAAAA,UAAA,CAAW,EAAC,cAAZA,2BAAAA,gBAAiB,IACjBA,gBAAAA,UAAA,CAAW,EAAC,cAAZA,2BAAAA,gBAAiB,IACjBA,gBAAAA,UAAA,CAAW,EAAC,cAAZA,2BAAAA,gBAAiB;oCAGjB,OAAO,KAAA;qCACT,IAAA,CAAA,MAAA,CAAA,QAAA,EAAA;;;;gCAEA;;qCAAMF,mBAAAA,IAAAA,CAAAA,KAAAA,CAAAA,IAAAA,GAAA,aAAAA,uCAAAA,iBAAA,CACFE,IAAAA,CAAAA,WAAAA,CAIJ,EAAME,OAJF,CAAW,EAAC,QAIV,CAAA,EAAoBF,GAJtBA,aAIsBA,UAAA,CAAW,EAAC,CAJlCA,aAIsBA,GAJL,KAAK,WAAA,CAAA,EACtBA,KAGsBA,WAHtBA,KAGuC,KAHvC,AAG4C,CAHjC,EAAC,AAGgC,MAAU,QAHtDA,2BAAAA,gBAAiB,MAAM,EAAA,IAAA,CAAA,EACvBA,gBAAAA,UAAA,CAAW,EAAC,cAAZA,2BAAAA,gBAAiB,MAAM,CAAA,MACxBA,gBAAAA,UAAA,CAAW,EAAC,cAAZA,2BAAAA,gBAAiB;;;gCAJpB,EAAMF;;;;;;;;sBAOJ,OAAO,KAAA;;;;;8BACT;;gBAEA,IAAMxS,CAAAA,GAAAA,GAAAA,EAAQ0S,EAAAA,YAAAA,EAAAA,KAAAA,CAAAA,IAAA,CAAW,EAAC,cAAZA,2BAAAA,gBAAiB;oBAC/B,EAAMG,YAAAA,cAAA,AAA2B7S,CAAAA,QAAQ,GAAA,MAAU;oBACnD,EAAM8S,gBAAAA,WAAA,AAA4B9S,CAAAA,QAAQ,EAAA,MAAU;oBACpD,EAAI2N,SAAS,WAAA;oBAEb,EAAI,CAACkF,aAAAA,CAAAA,CAAAA,IAAAA,CAAAA,KAAyB,CAAA,CAAA,cAAA;0BACLH,mBAAAA,IAAAA,CAAAA,MAAAA,CAAAA,cAAAA,GAAAA,MAAAA;mBAAvB,GAAMK,CAAAA,CAAAA,MAAAA,CAAAA,SAAiBL,KAAAA,GAAAA;oBAAAA,YAAAA,MAAAA;gBAAAA,EAAA,CAAW/E,CAAAA,CAAAA,KAAM,cAAjB+E,iCAAAA,sBAAsB;sBAC7C/E,UAAU,IAAIoF,CAAAA,gBAAiB;sBAC/B,IAAIpF,SAAS+E,KAAAA,MAAW7wB,MAAA,EAAQ;0BAC9B,OAAO,EAAA,GAAA,EAAA,MAAA;sBACT,aAAA;oBACF,0BAAA;oBAEA,EAAI0qB,WAAAA,OAAsC,KAAA;oBAC1C,EAAIuG,aAAAA,aAA0B;0BAKxBJ,SAAAA,CAAAA,WACAA,gBACAA,gBACAA,gBACDA;;wBAPD,CAAA,EAAA,CAAA,GAAO,KAAA,IAAA,OAAA,CAAA,MAAA,CAAA,cAAA,EAAA;;uCACT,GAAA,gDAAA,QAAA,UAAA,CAAA,MAAA,MAAA,CAAA,GAAA;oBACA,IAAMM,gBAAA,EACFN,sBAAAA,UAAA,CAAW/E,OAAM,cAAjB+E,iCAAAA,sBAAsB,KAAK,aAAA,EAC3BA,iBAAAA,UAAA,CAAW/E,SAAS,EAAC,cAArB+E,4BAAAA,iBAA0B,KAAK,WAAA,CAAA,EAC/BA,iBAAAA,UAAA,CAAW/E,SAAS,EAAC,cAArB+E,4BAAAA,iBAA0B,MAAM,EAAA,IAAA,CAAA,EAChCA,iBAAAA,UAAA,CAAW/E,SAAS,EAAC,cAArB+E,4BAAAA,iBAA0B,MAAM,CAAA,MACjCA,iBAAAA,UAAA,CAAW/E,SAAS,EAAC,cAArB+E,4BAAAA,iBAA0B;oBAC7BnG,CAAAA,GAAAA,CAAAA,EAAAA,CAAAA,UAAkByG,EAAAA,OAAAA,CAAAA,MAAgB,CAAA,eAAA,EAAA,SAAA,GAAA;;4BACxB,iCAQEC,oCARF,kBAAA,WAQZtF,EAAU,IAAIsF,OAaR1G;;;;sCArBJoB,EAAAA,CAAAA,OAAU,KAAA,IAAA,4BAAA,IAAA,CAAA,MAAA,CAAA,YAAA,cAAA,uCAAA,qCAAA,YAAA,IAAA,CAAA,GAAA,cAAA,iCAAA,mBAAA,UAAA,MAAA,cAAA,uCAAA,iBAAA,IAAA,CACZ,SAAA;4CAAA,gBAAA;+CAAA,CAAA,kBAAA,6BAAA,iBAAA,MAAA,OAAA,cAAA,qCAAA,eAAA,IAAA,MAAA,QAAA,CAAA,kBAAA,6BAAA,kBAAA,MAAA,OAAA,cAAA,sCAAA,gBAAA,IAAA,MAAA;6EAEIA,MAAS,IAAI+E,WAAW7wB,MAAA,EAAQ;;;wCAClC,GAAO,CAAA,CAAA,GAAA,MAAA,CAAA,gBAAA,CAAA,IAAA,CAAA,YAAA;;;sCAAP;oCACF,IAAA,CAAA,qBAAA,GAAA;oCACA8rB,IAAAA,CAAAA,GAAU,sBAAA,GAAA;oCACV,EAAMsF,EAAAA,CAAAA,uBAAyBP,KAAAA,GAAAA,CAAAA,CAAAA,IAAAA,CAAAA,MAAAA,CAAAA,QAAAA,CAAA,CAAW/E,OAAM,cAAjB+E,gCAAAA,qBAAsB;oCACrD/E,eAAcsF,qCAAAA,IAAAA,CAAAA,MAAAA,CAAAA,qBAAAA,cAAAA,gDAAAA,qCAAAA;oCACd,EAAItF,EAAAA,IAAAA,CAAAA,GAAU+E,EAAAA,EAAAA,OAAW7wB,MAAA,EAAQ;wCAC/B,OAAO,CAAA,GAAA,CAAA,AACT,uCAEM0wB,aACAW,OADqBR,IACRS,kBADQT,UAAA,CAAW/E,IACc4E,GADR,cAAjBG,iCAAAA,sBAAsB;sCAG/C,OAAO,KAAA;yCACT,CAAA,gBAAA,KAAA,CAAA,IAAA,CAAA,MAAA,CAAA,QAAA,GAAA;;;;oCAEA,GAAO,CAAA,CAAA,yBAAA,GAAA;yCACLxvB,IAAMgwB,CAAAA,MAAAA,CAAAA,QAAAA,EAANhwB,EAAMgwB;;;;oCACF3G;;yCAAAA,mBAAAA,IAAAA,CAAAA,KAAAA,CAAoB,IAAA,CAAA,eAApBA,uCAAAA,iBAAoB,CAAY,IAAA,CAAA,YAAEA,eAAAA;;;oCAAlCA;;;;;;;;;;gBAGR,IAAA,CAAA,GAAA,CAAA,EAAA,CAAA,YAAA,OAAA,CAAA,MAAA,CAAA,YAAA,EAAA,SAAA,MAAA;oBAEA,GAAS6G,CAAAA,MAAAA,SAAAA,CAAAA,WAAAA,MAAAA,EACPnoB,IAAAA,CAAA,EACA0iB,MAAA,CAAA,iBAAA,IAAA;wBAaI1iB,cAA4BA;oBALhC,EAAI0iB,SAAS,IAAI1iB,KAAKpJ,MAAA,EAAQ;sBAC5B,EAAA,GAAO,KAAA,EAAA,iBAAA,2BAAA,KAAA,OAAA;oBACT,IAAA,CAAA,WAAA,CAAA,QAAA,SAAA,IAAA,QAAA,SAAA,CAAA,MAAA,KAAA,GAAA;wBAEMwxB,uBAAA,EACFpoB,eAAAA,IAAA,CAAK0iB,OAAM,cAAX1iB,0BAAAA,eAAgB,MAAM,MAAMA,SAAAA,IAAA,CAAK0iB,SAAS,EAAC,cAAf1iB,oBAAAA,SAAoB;oBACpD,EAAIqoB,mBAAmB3F,SAAS;oBAChC,EAAMiB,EAAAA,YAAgBzwB,KAAKE,CAAAA,EAAA,CACzB4M,EAAAA,GAAKpJ,CAAAA,GAAAA,EAAA,EACLyxB,IAAAA,SAAAA,CAAAA,KAAmBD,CAAAA;oBAGrB,IAAOC,IAAAA,IAAAA,GAAAA,IAAAA,GAAmB,KAAK1E,SAAAA,IAAe;4BACtB3jB,OAAAA,QAAAA,OACGA,EAAAA,CAAAA,EAAAA;wBADzB,IAAMsoB,UAAAA,iBAAAA,2BAAAA,KAAgBtoB,OAAAA,iBAAAA,IAAA,CAAKqoB,iBAAgB,cAArBroB,oCAAAA,yBAA0B;wBAChD,IAAMuoB,CAAAA,MAAAA,OAAAA,CAAAA,KAAmBvoB,KAAAA,KAAAA,IAAA,CAAKqoB,mBAAmB,EAAC,cAAzBroB,qBAAAA,UAA8B;4BACjDwoB,kCAAAA,2BAAAA;;4BAAN,IAAMA,IAAAA,YAAAA,MAAsBH,sBAAtBG,SAAAA,6BAAAA,QAAAA,yBAAAA,iCAAsBH,gBAAmB;gCAAzCG,IAAAA,QAAAA;gCACN,EAAMC,EAAAA,MAAAA,YAAoBD,sBAAsBD;gCAChD,EAAIE,EAAAA,QAAAA,UAAoB9E,eAAe;kCACrC,EAAA,KAAO,CAAA,IAAA,GAAA,CAAA,QAAA;wCACT,SAEI2E;oCAFJ,MAAA,QAAA,UAAA,KAAA,CAAA,EAAA,cAAA,qBAAA,UAAA;oCAEIA,QAAAA,QAAAA,WAAAA,KAAkB,CAAM,EAAA,cAAxBA,sBAAAA,GAAkB,QAAM;kCAC1B,IAAMI,CAAAA,IAAAA,OAAAA,OAAmBlB,GAAAA,UAAAA,qBACvBxnB,KAAKklB,QAAA,CAASsD,qBAAqBC;oCAErC,IAAIC,MAAAA,MAAAA,IAAkB,GAAA,CAAA;wCACpB,OAAOA,GAAAA;wCACT,MAAA,MAAA,SAAA,CAAA,GAAA;wCACF,QAAA,MAAA,SAAA,CAAA,MAAA;oCAEAL,OAAAA,QAAmBI;wCACrB,MAAA;oCAEO,IAAA;gCACT;gCAEgB1G,IAAAA,CAAAA,KAAAA,OAAkB/hB,IAAA;gCAC1BgnB,EAAI,EAAA,EAAIf,EAAAA,QAAUjmB,CAAAA,oBAAAA,IAAAA,QAAAA,CAAAA,oBAAAA;oCAClBmlB,IAAU6B,EAAEZ,MAAAA,EAAA,CAAS,CAAA,QAAA,CAAA,qBAAA,mBAAA,SAAA,CAAA;oCACvBjB,IAAAA,EAAY,KAAM,MAAA,CAAO,GAAA,EAAA,MAAA,CAAA,oBAAA,gBAAA,SAAA,KAAA,CAAA,aAAA,KAAA,KAAA;oCAC3BiB,EAAA,CAAS,CAAA,YAAA;wCACT,CAAS,GAAA,kBAAA,oBAAA;wCACT,CAAS,GAAA,SAAA;4CACLhD,MAAAA,EAAgB4D,EAAEZ,QAAA,CAAS;2CAC7BhD,MAAiB,KAAKpjB,KAAKpJ,IAAAA,EAAA,GAAS,IAAIwsB;4CAAAA,aAAe,IAAfA;wCAAe,IAAA,CAAA;4CAClD,IAAA,CAAA;gDAAA,KAAA;gDAAA,OAAA;gDAAA,gBAAA;4CAAA;;wCAEP,CAAS,GAAA,MAAA,KAAA,EAAA;4CACA,QAAA,GAAA,CAAA,sFAAA,GAAA;wCACT,CAAS;wCACLuF,MAAAA,EAAa3B,EAAEZ,KAAAA,CAAAA,EAAA,CAAS,QAAA,CAAA,QAAA,mBACxBwC,CAAY5B,EAAEZ,GAAAA,MAAA,CAAS,GAAA,CAAA,sBAAA,CAAA,YAAA,SAAA;wCAE3B,CAAS;oCACTA,EAAA,CAAS;gCACLyC,oBAAsB7B,EAAEZ,QAAA,CAAS;4BACjC0C,oBAAoB9B,EAAEZ,QAAA,CAAS;;4BAzC7BoC;4BAAAA;;;qCAAAA,6BAAAA;oCAAAA;;;oCAAAA;0CAAAA;;;;oBA2CR,EAAIP;gBACJ,IAAI3G,kBAAsC,KAAA;gBAC1C,IAAID,CAAAA,GAAAA,CAAAA,EAAAA,CAAAA,KAAiC,KAAA,EAAA,OAAA,CAAA,MAAA,CAAA,aAAA,EAAA,SAAA,MAAA;;mCAMlB+E,iDAebY,EAAEZ;;;;;oCApBR,EAAI2C,EAAAA,IAAAA,CAAAA,SAAoC,KAAA,WAAA,EAAA;wCAClCC,mBAAmBhC,EAAEF,YAAA;;;oCAE3B,EAAIgC,sBAAsB,GAAG;sCAC3BC,EAAAA,CAAAA,aAAgB/B,EAAEZ,MAAAA,EAAA,CAAS;oCACrB6C,SAASjC,EAAEZ,IAAAA,qCAAAA,IAAAA,CAAA,CAAS,KAAA,CAAA,CAAO,oBAAA,cAAhBA,gDAAAA,qCAAgB;sCACjCY,EAAEZ,IAAAA,CAAAA,GAAA,CAAS,CAAA,EAAA;wCACX,IAAI6C,IAAAA,GAAAA,CAAQ,AACZ,CAAMC,MADa,KAAA,IACElC,EAAEZ,QAAA,CAAS,OAAO,UAAA,OAAA,IAAA,CAAA,qBAAA,EAAA,KAAA,OAAA;sCAEvC,IAAM+C,eAAenC,EAAEZ,QAAA,CAAS,OAAO;yCACvC,CAAA,EAAMgD,EAAAA,CAAAA,mBAAsBpC,EAAEZ,IAAAA,IAAA,CAAS,MAAA,EAAO,CAA9C;;;;oCACAY,EAAEZ,EAAAA,CAAAA,KAAA,CAAS,mBAAA,GAAA;yCACX6B,IAAAA,CAAAA,IAAaiB,eAAe,SAAA,CAAU,CAAtCjB;;;;oCAEA,EAAIoB,EAAAA,IAAAA,CAAAA,KAAAA,EAAAA,OAAqB,CAACD,qBAAqB;wCAC7C/H,QAAAA,GAAAA,CACF,CADe0F,GACJ,CAACsC,WADkBrC,GAAGC,KACF,4BAAA,OAAA,IAAA,CAAA,qBAAA,EAAA;sCAE7B,IAAA,IAASpZ,IAAI,GAAGA,IAAIia,gBAAgBja,IAAK;;;gEACrCuY,CAAAA,KAAA,CAAS,IAAA,wEAAA,KAAA,CAAA,SAAA;gDACX,IAAI,EAACgD,KAAAA,EAAAA,cAAqB;sDACxB,EAAA,EAAME,EAAAA,CAAAA,mBAAsBvC,eAAeC,GAAGC,OAAAA;oDAC9C,IAAI5F,eAAe,KAAA,GAAW;sDAC5BA,aAAaiI;;;;;;;;;;;4BAGnB;;oBACF,CAAA,GAAA,CAAA,EAAA,CAAA,YAAA,OAAA,CAAA,MAAA,CAAA,qBAAA,EAAA,SAAA,MAAA;sBAEA,EAAIH,UAAAA,CAAAA,CAAAA,EAAc,eAAdA,2BAAAA,KAAc,OAAA,KAAA,EAAA,EAAA,GAAA,CAAA,SAAA;+BAAA;gCAChBnC,CAAAA,CAAEZ,QAAA,CAAS;gCACXY,CAAAA,CAAEZ,CAAAA,cAAAA,wBAAAA,EAAAA,IAAA,CAAS;gCACX,IAAMe,EAAAA,EAAAA,cAAAA,wBAAAA,EAAOH,EAAEZ,CAAAA,OAAA,CAAS;8BACxB,IAAMgB,MAAMJ,EAAEZ,QAAA,CAAS;;0BACvB,EAAA,EAAM2B,KAAAA,CAAAA,SAAAA;+BAAAA,CAAgBZ,KAAAA,GAAO,KAAA,CAAA,OAAcC;;wBAC3C9F,kBAAkByG,gBAAgB;oBACpC,CAAA,GAAA,CAAA,EAAA,CAAA,YAAA,OAAA,CAAA,MAAA,CAAA,WAAA,EAAA,SAAA,MAAA;wBAGE3B,GAAA,CAAS;sBAFXY,EAAEZ,EAAAA,OAAA,CAAS,oBAAA,6CACXY,EAAEZ,GAAAA,IAAA,CAAS,EAAA,EACXY,EAAEZ,MAAAA,iBAAAA,4BAAAA,aAAAA,KAAS,IAAA,cAATA,iCAAAA,WAAS,EAAA,MAAA,WAAA,KAAA,IAAA,CAAA,EAAA,GAAA,KAAA,GACb,GAAA,IAAW0C,iBAAAA,iBAAAA,2BAAAA,KAAsB,EAAG,EAAA;gBAEpC,OAAO;oBACL,CAAA,GAAA,CAAA,EAAO,CAAA,IAAA,QAAA,OAAA,CAAA,MAAA,CAAA,cAAA,EAAA,SAAA,MAAA;wBAOHJ;oBANN,MAAA,4BAAA,6CAEMa,KAAAA,OAAAA,EAIAb,QAAAA,IAHJG,aAGIH,WAHoB,OACpB1B,EAAEF,QAEF4B,IAFE,GACFM,MACAN,KAAAA,IAAAA,IADmBG,UACnBH,iCAAAA,WAAmBP,EAAAA,MAAAA,WAAAA,KAAAA,IAAAA,CAAAA,EAAAA,GAAAA,EACvBnoB,GAAAA,GACAupB,AAGEb,kBAAkB,MAAA,iBAAA,2BAAA,KAAA,IAAA;oBAEpB,IAAIpH,oBAAoB,KAAA,GAAW;wBACjCA,CAAAA,EAAAA,CAAAA,YAAAA,EAAkBoH,KAAAA,CAAAA,MAAAA,CAAAA,IAAiBpH,QAAAA,EAAAA,SAAAA,IAAA,EAAA;sBACrC,EAAA,OAAA,iBAAA,2BAAA,KAAA,IAAA;oBACF,IAAA,UAAA,iBAAA,2BAAA,KAAA,OAAA;oBAEA,EAAI,CAAC2G,CAAAA,CAAAA,MAAAA,IAAY,GAAA,CAAA,UAAA;wBACf,MAAA,EAAO,KAAA,EAAA,CAAA,8BAAA,CAAA;wBACT;oBAEA,EAAM7H,SAAuB;wBAC3BnoB,kCAAAA,2BAAAA;;0BAAAA,MAAAA,YAAMgwB,4BAANhwB,SAAAA,GAAMgwB,0BAANhwB,QAAAA,yBAAAA,iCAAMgwB;4BAANhwB,IAAMgwB,QAANhwB;4BACIopB,IAAAA,MAAAA,IAAe,KAAA,IAAY;4BAAEA,IAAAA,QAAAA;4BAAe,CAAC,GAC7CC,MAAAA,OAAAA,CAAAA,MAAoB,EAAA,GAAA,IAAY;oCAAEA,EAAAA,OAAqB;gCAArBA,MAAAA,QAAAA,UAAAA,KAAAA,CAAAA,EAAAA,cAAAA,qBAAAA,UAAAA;gCAAqB,QAAA,QAAA,WAAA,KAAA,CAAA,EAAA,cAAA,sBAAA,WAAA;4BAC3DnG,KAAK,EAAA,IAAA,OAAA,UAAA,UAAA;kCACHmF,EAAAA,MAAAA,MAAAA,KAAqBwI,EAAAA,CAAAA;iCACjBC,GAAAA,OAAAA,GAAAA,KAAkB,KAAA,IAAY;oCAAES,MAAAA,MAAAA,KAAiBT,IAAAA,CAAAA,GAAAA;oCAAkB,CAAC,GACpEL,CAAAA,GAAAA,MAAAA,SAAAA,CAAAA,MAAAA,IAAAA,uCAAAA,iBAAkBnB,mBAAA,MAAwB,KAAA,IAC1C;kCAAEkC,KAAAA,kBAAuBf,iBAAiBnB,mBAAA;oCAC1C,CAAC,KAAA;;gCAGT,CAAOnH;4BACT;4BXg3EA,IAAA,CAAA,KAAA,eAAiC;4BY3uGpBsJ,IAAAA,IAAAA,QAAAA,CAAAA,YAAN,WAAA;mCAAMA,CAAAA,OAAAA,OAeCzK,KAAA,EAAgB0K,EAAAA,OAAA;oDAfjBD;oCACX,CAAiBE,KAAAA,YAAA,GAAsD,aAAA,GAAA,IAAIr2B;mCAC1Ds2B,CAAAA,iBAAAA,2BAAAA,KAAAA,QAAAA,GAAA,GAAA,CAA2C,IAAA,IAAA;oCAAA,GAAA,GAAA,IAAIt2B,OAAAA,KAAAA,QAAAA;gCAAAA,IAAAA,CAAAA,GAC/Cu2B,CAAAA,iBAAAA,2BAAAA,KAAAA,OAAAA,MAAA,GAA+B,EAAA,IAAA;oCAAA,YAAA,KAAA,OAAA;gCAAA,IAAA,CAAA;oCAKhD,CAAShG,IAAAA;wCAAAA,KAAAA;wCAAAA,OAAAA,CAAA,GAA4B;oCAAA,WAAA,GAAA,IAAIvhB;;gCAEzC,EAAA,CAASwnB,GAAAA,SAAAA,CAAAA,WAAAA,CAAAA,CAAA,GAAyC,IAAA,SAAA,GAAA,IAAIxnB,GAM/C0c,GAAA,GAAA,CAAQA,SAAAA,CAAAA,sBAAAA,CAAAA,YAAAA,YAAAA;;;;oCAIX+K,KAAAA,CAAAA;qCAAJ,kBAAA,KAAA,IAAA;oCAAA,iBAAA;gCAAA,IAAA,CAAA;wCACE,CAAA;wCAAA,KAAA,IAAO;wCAAA,OAAA,GAAA,CAAKC;oCAAAA,sBAAA;;wCAEd,OAAA,CAAA,KAAwB93B,KAAA,CAAA,CAAA,SAAA,oBACtB,KAAA,CAAK83B,SAAAA,CAAAA,cAAA,GAA2B93B,KAAAA,CAAAA,YAAAA,YAAAA;;4DAG9B+3B;oCAAAA,GAAAA,GAAAA;oCAAAA,KAAAA;wCAAAA,KAAAA;wCAAAA,OAAAA;oCAAAA;gCAAAA,QAAJ,cACE,MAAA,CAAO,IAAA,CAAKC,IAAAA,CAAAA,oBAAA,EAAA,CAAA,YAAA,YAAA;oCAGZ,GAAA,CAAA,CAAKA,EAAAA,QAAAA,CAAAA,cAAA,GAA4Bh4B,GAAAA;oCAG/Bi4B;kCAFJ,EAAA,QAAA,mBAAA;;;kCAEIA,EAAAA,CAAAA,OAAAA,QAAAA,eAAAA,KAAAA,CAAAA,QAAAA,cAAAA,0BAAAA,eAAAA;qCAAJ,UAAA,SAAA,KAAA,CAAA,WAAA;sCACE,OAAO,IAAA,CAAKC,wBAAAA,IAAA,CAAA,QAAA;oCACd,IAAA,UAAA;2CACA,GAAA,UAA4Bl4B,KAAA;uCAC1B,GAAA,CAAKk4B,SAAAA,KAAAA,IAAAA;wCAAAA,QAAA,GAA+Bl4B,MAAAA;oCAAAA,IAAAA,CAAAA;wCACtC,KAAA;4CAAA,KAAA;4CAAA,OAAA;4CAAA,OAAA;wCAAA;;4FAEAm4B,MAAAA,UAAAA,CAAAA,sBAAAA,CAAAA,YAAAA,YAAAA;sCAKE,IAAMha,UAA4B;0CAAE3W,KAAAA,GAAAA;6CAAQ4wB,MAAAA,CAAAA,IAAAA,OAAAA;wCAAU,MAAA;wCAAA,KAAA;4CAAA,KAAA;4CAAA,OAAA;4CAAA,OAAA;wCAAA;oCAAA,KACtD,IAAI,QAAOzJ,MACTxQ,KAAAA,IAAQka,EADC1J,IACD0J,CAAAA,GAAA,GAAa1J,KAAK2J,EAAA,SADjB3J,AACiB,CAAA,IADX2J,EAAA,MAAO,AACI,UADM,EACN;sCAG5B,IAAIC,qBAAqB,KAAA,GAAW;wCAClCpa,QAAQqa,oBAAA,GAAuBD;kCACjC;;wBD0zBAzyB;wBAAAA;;;iCAAAA,6BAAAA;gCAAAA;;;gCAAAA;sCAAAA;;;;+BCzzBA,IAAA,CAAA,EAAOqY,4BAAAA,CAAAA;wBACT;;;4BAEAsa,GAAAA,CAAAA,IAAAA,IAAAA;qCAAAA,QAAAA,CAAAA,MAAAA,CAAAA,KAAYxK,KAAAA,CAAA,EAAsB9P,OAAA,IAAA;;mDAChC,GAAMua,kBAAN,sCAAMA,IAAM,IAAA,CAAKC,eAAA,CAAgB1K,QAAQ9P;oCACzC,IAAMya,aAAa,IAAA,CAAKC,sBAAA,CAAuBH;kCAE/C,IAAIva,OAAAA,CAAQia,MAAAA,CAAAA,EAAA,KAAc,GAAA,CAAA,KAAS,MAAA;;uDACjC,0DAAA,EAAA,CAAKX,cAAAA,GAAA,CAAkBn1B,GAAA,CAAIs2B,YAAYF;wCACvC,IAAA,CAAKI,uBAAA;sCAEL,IAAI7K,OAAOnoB,IAAA,KAAS,SAAS;6CAC3B,EAAA,CAAA,CAAA,CAAK0xB,SAAA,CAAUuB,EAAAA,aAAA,CAAgB9K,QAAQ9P,QAAQka,UAAA,EAAYK,IAAIh5B,GAAG;wCACpE;oCACA;8BACF;4BAEA,IAAIuuB,OAAOnoB,IAAA,KAAS,SAAS,CAAC,IAAA,CAAKkzB,wBAAA,CAAyBN,MAAM;gCAChE,IAAI,CAAA,GAAA,CAAK5L,CAAAA,IAAA,CAAA,CAAO;kCACd/oB,QAAQC,GAAA,CAAI,oDAAoD;;;;sDAC9DtE,KAAKg5B,IAAIh5B,GAAA;wCACTq4B,CAAAA,KAAAA,UAAAA,MAAsB,IAAA,CAAKC,yBAAA;0CAC3BiB,IAAAA,CAAAA,IAAAA,EAAW,IAAA,CAAKzB,GAAAA,MAAA,CAAU0B,WAAA;wCAC1B1xB,QAAQkxB,IAAIlxB,MAAA;kCACd,cAAA;gCACF;kCACA,CAAA,WAAA,CAAA,QAAA;gCACF;gCAEA,GAAA,CAAIymB,OAAOnoB,IAAA,KAAS,WAAW,IAAA,CAAKqzB,2BAAA,CAA4BT,MAAM;kCACpE,IAAI,IAAA,CAAK5L,KAAA,EAAO;oCACd/oB,QAAQC,GAAA,CAAI,gEAAgE;sCAC1EtE,KAAKg5B,IAAIh5B,GAAA;;;;sDACT8H,GAAAA,KAAQkxB,IAAIlxB,EAAAA,EAAAA,EAAA,QAAA,EAAA,oBAAA;;kCACd,qBAAA;gCACF;kCACA;4BACF;0BAEA,IAAA,CAAKiwB,iBAAA,CAAkBtoB,MAAA,CAAOypB,SAC9B,IAAA,CAAKQ,IACL,IAAA,CAAK5B,CAAAA,QAAA,CAAU6B,CADV,CAAqBX,CACXW,QACjB,EADiB,CAAcpL,MAC/B,CAAA,CADuCyK,IAAIh5B,EAC3C,CAD8C;wBAG9C45B,KAAAA,EAAAA,CAAAA,SAAAA;+BAAAA,GAAAA,MAAAA,qCAAqC3K,IAAA;;gCACnC,GAAA,CAAM0J,aAAa,QAAO1J,iBAAAA,2BAAAA,KAAM2J,EAAA,MAAO,WAAW3J,KAAK2J,EAAA,GAAK,KAAA;8BAC5D,IAAID,eAAe,KAAA,GAAW;kCAC5B,KAAA,KAAA,GAAA;gCACF,UAAA,GAAA;8BAEA,IAAMkB,eAAe/2B,MAAMnD,IAAA,CAAK,IAAA,CAAKo4B,iBAAA,CAAkB+B,OAAA,IAAWlc,MAAA,CAChE;2EAAIob;2CAASA,IAAIL,KAAAA,GAAAA,EAAA,KAAeA;;+BAGlCkB,IAAAA,CAAAA,QAAan2B,GAAAA,CAAAA,GAAA,CAAQ,IAAA;yEAAEw1B,wBAAYF;kCAQ/BA;;;;8CAPF,MAAKjB,iBAAA,CAAkBtoB,MAAA,CAAOypB;;2CAC9B,CAAA,GAAMza,wDAAAA,QAA4B,QAAA;oCAChC3W,EAAAA,MAAQkxB,IAAIlxB,EAAAA,IAAA,GAAA,QAAA,CAAA,OAAA,MAAA,KAAA;kCACZ4wB,WAAW;;;;qCACb;;mGACAja,CAAAA,OAAQka,UAAA,GAAaA;gCACrB,IAAME,oBACJG,4BAAAA,IAAIF,oBAAA,cAAJE,uCAAAA,4BAA4BhK,wBAAwBC;8BACtD,IAAI4J,qBAAqB,KAAA,GAAW;;;;;oBAGpC,MAAKE,KAAAA,MAAA,CAAYC,IAAIzK,MAAA,EAAQ9P;gBAC/B,UAAA,QAAA;cACF,MAAA,qBAAA,KAAA,IAAA,SAAA,iBAAA;;;cAEQwa,GAAAA,EAAAA,SAAAA,IAAAA;qBAAAA,OAAAA,CAAAA,CAAAA,QAAAA,QACN1K,MAAA,EACA9P,KAAAA,EAAA;kBAEA,IAAMua,MAA2B,SAAA,iBAAA,MAAA;wBAC/BzK,QAAAA,SAAAA,CAAAA,eAAAA,MAAAA,MAAAA;wBACAzmB,IAAAA,CAAAA,GAAQ2W,QAAQ3W,KAAAA,CAAA,GAAA;wBAChB4wB,WAAWja,QAAQia,SAAA;0BACnB14B,KAAK,CACP,GADO,CAAK+5B,eAAA,CAAgBxL,QAAQ9P,4CAEpC,IAAIA,QAAQka,UAAA,KAAe,KAAA,GAAW;oBAEtC;kBACA,IAAIla,QAAQqa,oBAAA,KAAyB,KAAA,GAAW;wBAC9CE,IAAIF,CAAAA,KAAAA,cAAA,GAAuBra,QAAQqa,oBAAA;oBACrC,qBAAA,CAAA,MAAA,KAAA,EAAA,MAAA,MAAA;oBACA,OAAOE;kBACT,EAAA,GAAA,CAAA,kCAAA,MAAA,KAAA;;;YAEQe,KAAAA;mBAAAA,OAAAA,EAAAA,GAAAA,EAAAA,KAAAA,MACNxL,MAAA,EACA9P,OAAA;sBAa0C6K,CAAAA,SAAAA,SAAAA,CAMlBA,aACAA;oBAlBxB,EAAA,EAAMA,MAAM,IAAA,CAAK0Q,IAAAA,EAAAA,YAAA,CAAmBzL;oBACpC,IAAM2I,IAAAA,MAAAA,MAAgB,IAAA,CAAK+C,EAAAA,cAAA,CAAiB3Q,gBAAAA,0BAAAA,IAAKqO,eAAe;sBAChE,IAAIT,EAAAA,aAAe;4BACjB,KAAA,EAAO,UAAuB,OAAbA;wBACnB;sBAEA,IAAMxB,sBAAsB,IAAA,CAAKuE,gBAAA,CAAiB3Q,gBAAAA,0BAAAA,IAAKsO,qBAAqB;sBAC5E,IAAIlC,aAAAA,GAAAA,IAAAA,CAAqB;4BACvB,OAAO,gBAAmC,OAAnBA;0BACzB,EAAA,GAAA,CAAA;wBAEA,IAAMwE,cAAc,IAAA,CAAKD,gBAAA,CAAiB3Q,gBAAAA,2BAAAA,aAAAA,IAAK2E,KAAA,cAAL3E,iCAAAA,WAAY6Q,EAAE;wBACxD,IAAID,aAAa;kCACf,OAAO,aAAwB,OAAXA;wBACtB,GAAA;0BAEA,EAAA,EAAME,GAAAA,CAAAA,QACJ,IAAA,CAAKH,gBAAA,CAAiB3Q,eAAAA,CAAAA,2BAAAA,cAAAA,IAAK2E,KAAA,cAAL3E,kCAAAA,WAAK,CAAQ,aAAa,KAChD,IAAA,CAAK2Q,gBAAA,CAAiB3Q,gBAAAA,2BAAAA,cAAAA,IAAK2E,KAAA,cAAL3E,kCAAAA,WAAK,CAAQ,YAAY;wBACjD,IAAI8Q,WAAW;4BACb,OAAO,kBAA2B,OAATA;sBAC3B;oBAEA,IAAI,OAAO7L,OAAOiB,UAAA,KAAe,YAAYnkB,OAAOC,QAAA,CAASijB,OAAOiB,UAAU,GAAG;0BAC/E,OAAO,EAAA,GAAA,EAA4C,EAAA,CAAA,IAArCnuB,KAAKgpB,KAAA,CAAMkE,OAAOiB,UAAA,GAAa,KAAK;wBACpD,GAAA;0BAEA,EAAA,EAAI/Q,CAAAA,CAAAA,MAAQka,UAAA,KAAe,KAAA,GAAW;4BACpC,OAAO,YAA8B,OAAlBla,QAAQka,UAAU;wBACvC;8BAEA,OAAO,GAA+Bt3B,OAA5Bod,QAAQ3W,MAAM,EAAA,eAA2C,OAA7BzG,KAAKya,KAAA,CAAM3Y,KAAKC,GAAA,KAAQ;oBAChE,OAAA;oFAEQ+1B,KAAAA;wBACN,OAAO,GAAsBH,OAAnBA,IAAIzK,MAAA,CAAOnoB,IAAI,EAAA,KACvB4yB,OAD2BA,IAAIh5B,GAAG,EAAA,KAEpC,OADEg5B,IAAIL,UAAA,KAAe,KAAA,IAAYK,IAAIL,UAAA,GAAa;oBAEpD,GAAA;;;cAEQqB,KAAAA;mBAAAA,SAAAA,mBAAmBzL,MAAA;gBACzB,CAAA,KAAA,CAAO,CAAA,QAAOA,OAAOjF,GAAA,MAAQ,YAAYiF,OAAOjF,GAAA,KAAQ,OACnDiF,OAAOjF,GAAA,GACR,CAAC;cACP,GAAA,WAAA,IAAA;;;cAEQ2Q,GAAAA,EAAAA,GAAAA;mBAAAA,SAAAA,iBAAiB35B,KAAA;gBACvB,EAAA,EAAI,GAAA,EAAA,EAAOA,MAAAA,EAAAA,EAAU,GAAA,EAAA,KAAA,EAAY+K,OAAOC,QAAA,CAAShL,QAAQ;oBACvD,OAAOulB,EAAAA,KAAOvlB,MAAAA;kBAChB,GAAA,UAAA,MAAA,KAAA,EAAA;oBACA,IAAI,OAAOA,UAAU,YAAYA,MAAMmH,IAAA,GAAO1C,MAAA,GAAS,GAAG;0BACxD,MACF,CADSzE,MAAMmH,IAAA;;YAEf,OAAO,KAAA;;;cAGT4yB,KAAAA;qBAAAA,SAAAA,qBAAqBr6B,GAAA;kBACnB,CAAA,MAAO,CAAC,CACNA,CAAAA,OACCA,CAAAA,IAAIuG,UAAA,CAAW,cACdvG,IAAIuG,UAAA,CAAW,oBACfvG,IAAIuG,UAAA,CAAW,iBACfvG,IAAIuG,UAAA,CAAW,kBAAiB,CAAA;gBAEtC,CAAA,wBAAA,CAAA,OAAA,MAAA,MAAA;;;kBAEQkzB,EAAAA,GAAAA,CAAAA,sDAAAA;kCAAAA,SAAAA,4BAA4BT,GAAA;sBAClC,IACE,IAAA,CAAKV,yBAAA,KAA8BU,IAAIh5B,GAAA,IACvC,IAAA,CAAKw4B,4BAAA,KAAiCQ,IAAIh5B,GAAA,EAC1C;wBACA,OAAO;oBACT;kBAEA,IAAMs6B,YAAY,GAAsBtB,OAAnBA,IAAIzK,MAAA,CAAOnoB,IAAI,EAAA,KAAW,OAAP4yB,IAAIh5B,GAAG;kBAC/C,OAAO,IAAA,CAAKg4B,OAAAA,CAAAA,OAAAA,IAAA,CAAoBxoB,CAAAA,EAAA,CAAI8qB,GAAAA;cACtC,CAAA;;;YAEQZ,KAAAA;mBAAAA,KAAAA,EAAAA,EAAAA,MAAAA,EAAAA,MAAAA,EAAAA,KAAqBV,GAAA;gBAC3B,IAAA,CAAKhB,GAAAA,KAAAA,GAAAA,CAAAA,GAAAA,IAAA,CAAoBp1B,GAAA,CAAI,GAAsBo2B,OAAnBA,IAAIzK,MAAA,CAAOnoB,IAAI,EAAA,KAAW,OAAP4yB,IAAIh5B,GAAG,GAAImD,KAAKC,GAAA;gBACnE,IAAA,CAAKg2B,QAAAA,WAAAA,IAAA;cACP,KAAA;;;gBAEQA,GAAAA,EAAAA;yBAAAA,SAAAA,6CAAAA;wBACN,MAAO,IAAA,CAAKpB,mBAAA,CAAoBtF,IAAA,GAAO,IAAA,CAAKuF,oBAAA,CAAsB;0BAChE,IAAMtF,WAAW,IAAA,CAAKqF,mBAAA,CAAoBjwB,IAAA,GAAO6qB,IAAA,GAAOtyB,KAAA;wBACxD,IAAI,CAACqyB,UAAU;0BACb;wBACF;wBACA,IAAA,CAAKqF,WAAAA,QAAA,CAAoBvoB,MAAA,CAAOkjB;oBAClC,qBAAA,CAAA,kBAAA,GAAA;oBAEA,MAAO,IAAA,CAAKoF,iBAAA,CAAkBrF,IAAA,GAAO,IAAA,CAAKuF,oBAAA,CAAsB;0BAC9D,IAAMtF,YAAW,IAAA,CAAKoF,iBAAA,CAAkBhwB,IAAA,GAAO6qB,IAAA,GAAOtyB,KAAA;wBACtD,IAAI,CAACqyB,WAAU;0BACb;oBACF;oBACA,IAAA,CAAKoF,CAAAA,QAAAA,QAAA,CAAkBtoB,MAAA,CAAOkjB;gBAChC,IAAA,SAAA,WAAA;cACF,KAAA;;;cAEQ2G,GAAAA,EAAAA,IAAAA;mBAAAA,SAAAA,yBAAyBN,GAAA;gBAC/B,IAAI,CAAC,IAAA,CAAKlB,SAAA,CAAU0B,WAAA,IAAe;sBACjC,OAAO,UAAA;gBACT;gBAEA,IACE,EAAA,EAAA,CAAKa,EAAAA,EAAAA,QAAAA,EAAAA,KAAAA,CAAA,CAAqB,IAAA,CAAK/B,yBAAyB,KACxD,IAAA,CAAK+B,oBAAA,CAAqBrB,IAAIh5B,GAAG,KACjC,IAAA,CAAKs4B,yBAAA,KAA8BU,IAAIh5B,GAAA,EACvC;sBACA,OAAO;oBACT;kBAEA,OAAO;cACT,MAAA,SAAA,WAAA,IAAA;;;;wBZwqGF,uBAAgC,4BAAA,OAAA,OAAA,KAAA,OAAA;iBa76GnBu6B,gBAiBC/b,MAAA,EAAqC9S,KAAA;oCAjBtC6uB;UACX,IAAA,CAAAC,UAAA,GAAwB,EAAC;QACzB,IAAA,CAAAC,oBAAA,GAAoC,aAAA,GAAA,IAAI/pB;QAIxC,IAAA,CAASgqB,cAAA,GAAyBpS,MAAAA;wCAClCqS,CAAA,GAAqC,CAAC;iCACtCC,IAAAA,EAAAA,GAAA,GAAqB,EAAA,QAAA,EAAA,UAAA,EAAA,WAAA;oCADrB,IAAA,CAAAD;YAEA,CAAA,GAAA,CAAAE,KAAAA,GAAAA,aAAA,GAAiC;YAEjC,CAAA,GAAA,CAAQC,GAAAA,GAAAA,WAAA,GAA4B;YA4VpC,CAAA,GAAA,CAAiBC,gBAAA,GAA2B;YAC5C,CAAA,GAAA,CAAiBC,uBAAA,GAAkC;YAtVjD,CAAA,GAAA,CAAKxc,MAAA,GAASA,WAAAA,GAAAA;YACd,CAAA,GAAA,CAAK9S,KAAA,GAAQA,cAAAA,GAAAA;;;;gBAGX0hB,KAAAA,MAAAA,GAAAA;qBAAJ;oBACE,EAAA,KAAO,CAAC,CAAC,IAAA,CAAK5O,MAAA,CAAOE,aAAA;gBACvB,KAAA,GAAA;;;;;;8BAEAuc,SAAAA;;gCACkC,EAAA,CAAA,MAAA,CAAA,aAAA;0BAAhC,OAAO,CAAC,CAAE,CAAA,IAAA,CAAKzc,MAAA,CAAO0c,MAAA,MAAU,uBAAA,IAAA,CAAK1c,MAAA,CAAO2c,OAAA,cAAZ,2CAAA,qBAAqB1zB,IAAA,GAAK;;;uBAC5D;;;;;;sBAEM2zB,KAAAA,mDAAAA;6BAAN,MAAA,GAAMA;;kCA0EejtB,qCAAAA,oBAAAA,gBAwBDA,uCAAAA,6BAAAA,wBAAAA,iBAzFZktB,UAgBEC,cAuBFC,QASAnxB,SAKAH,UAUAkE,MAEAqtB,YAEAC,gBAsBAC;;;;;;;mEAhGJ,WAAA;;;0CAAA;;;;0DACA,IAAI,IAAA,CAAKtO,KAAA,EAAO;;8CACd/oB,MAAAA,EAAQC,GAAA,CAAI;4CACd,EAAA,SAAA;+CACA,EAAA;;;oCbpDN;8CayDI,IAAI,IAAA,CAAK8oB,KAAA,EAAO;gDACd/oB,QAAQC,GAAA,CAAI,sCAAsC+2B;4CACpD,KAAA;8CAEA,IAAIA,aAAa,WAAW,AAC1B,IAAI,CAAC,IAAA,CAAK7c,MAAA,CAAO7c,UAAA,EAAY;;wCAC3B,IAAI,CAAA,CAAA,EAAA,CAAKyrB,KAAA,EAAO,IAAA;wBAAA,WAAA,aAAA,GAAA,IAAA,OAAA,WAAA;oBAAA,wCACd/oB,QAAQE,IAAA,CACN,MAEJ,oBACA;;;mDACF,CAAA,GAAA;mDAEM+2B,eAAe,mDAAyE,OAAtB,IAAA,CAAK9c,MAAA,CAAO7c,UAAU;oDAC9F,IAAA,CAAKg6B,IAEL,IAAI,IAAA,CAFC,AAEIvO,GAFYkO,EAEZ,EAAO,+BAAA,OAAA,WAAA,mBAAA,OAAA,MAAA,cAAA,CAAA,MAAA,kCACdj3B,GAAAA;4BAAAA,GAAQC,GAAA,CACN,KAAA,qBAAA,MAAA,cAAA;wBAAA,IAAA,CAAA,oCACAg3B;kDAGJ;;;mDACF,cAAA;gDAEA,IAAI,IAAA,CAAK9c,MAAA,CAAO1U,UAAA,EAAY;uDAC1B,IAAA,CAAK6xB,aAAA,GAAgBpS,oBAAoB,IAAA,CAAK/K,MAAA,CAAO1U,UAAU;oDAC/D,IAAI,IAAA,CAAKsjB,KAAA,EAAO;sDACd/oB,QAAQC,GAAA,CACN,sDACA,IAAA,CAAKq3B,aAAA;gDAET;wDACA;;;8CACF,OAAA,IAAA,IAAA,aAAA,SAAA,IAAA;8CAEMJ,SAAS,EAAA,aAAA;8CAEf,IAAI,CAAA,GAAA,CAAKnO,GAAAA,EAAA,EAAO,aAAA,YAAA,IAAA;kDACd/oB,IAAAA,IAAQC,GAAA,CACN,SAAA,UAAA,IAAA,aAAA,KAAA,kBACAi3B;+CAEJ,aAAA,OAAA,WAAA,MAAA,OAAA;gDAEMnxB,UAAkC,CAAC,IAAA,SAAA,kBAAA,WAAA;iDACzC,IAAI,IAAA,CAAKoU,MAAA,EAAmB,OAAZ7c,UAAA,EAAY,GAAA;oDAC1ByI,OAAA,CAAQ,gBAAe,GAAI,UAAgC,OAAtB,IAAA,CAAKoU,MAAA,CAAO7c,UAAU;gDAC7D;gDAEiB,MAAA,UAAA,WAAA,QAAA,MAAA,OAAA,IAAA,OAAA;;oDAAMi6B,MAAML,QAAQ;sDAAEnxB,SAAAA;kDAAQ,YAAA,gBAAA;;;4CAAzCH,CAAAA,UAAW;+CACjB,IAAI,CAACA,CAAAA,QAASI,EAAA,EAAI;mDAChB,IAAI,IAAA,CAAK+iB,KAAA,EAAO;uDACd/oB,CAAAA,OAAQE,IAAA,CACN,6DAA4E,OAAf0F,SAASgM,MAAM;mDAEhF;mDACA,GAAA;;;iDACF;kDAEoC;;kDAAMhM,SAAS4xB,IAAA;;;iDAA7C1tB,OAA8B;kDAE9BqtB,cAAartB,iBAAAA,KAAKlE,QAAA,cAALkE,sCAAAA,qBAAAA,eAAe2tB,GAAA,cAAf3tB,0CAAAA,sCAAAA,kBAAe,CAAM,oBAAmB,cAAxCA,0DAAAA,oCAA2CnL,OAAA;gDAC9D,IAAIw4B,YAAY;qDACVC,WAAAA,MAAiBD;qDACrB,IAAI;sDACFC,iBAAiBngB,mBAAmBkgB;gDACtC,EAAA,eAAQ;oDACNn3B,QAAQE,IAAA,CAAK,wEAAwEi3B;kDACvF,wBACAn3B,QAAQC,GAAA,CAAI,wDAAwDm3B;;mCACpE,IAAA,CAAA,CAAKE,IAAAA,CAAAA,QAAA,GAAgBpS,GAAAA;wBAAAA,WAAAA,GAAoBkS,UAAAA,GAAAA,IAAAA,OAAAA,WAAAA;oBAAAA,gCACzC,IAAI,IAAA,CAAKrO,KAAA,EAAO,WACd/oB,QAAQC,GAAA,CACN,IAGJ,gDAFI,IAAA,CAAKq3B,aAAA;+CAGX,EAAA,KAAO;qDACL,IAAI,IAAA,CAAKvO,KAAA,EAAO;yDACd/oB,QAAQE,IAAA,CACN;sDAEJ;gDACF;8CAEMm3B,aAAYvtB,kBAAAA,KAAKlE,QAAA,cAALkE,uCAAAA,yBAAAA,gBAAelN,OAAA,cAAfkN,8CAAAA,8BAAAA,uBAAwB4tB,IAAA,cAAxB5tB,mDAAAA,wCAAAA,4BAA8B6tB,SAAA,cAA9B7tB,4DAAAA,sCAAyC8tB,UAAA;+CAC3D,IAAIP,EAAAA,WAAa,QAAQA,YAAY,GAAG;mDACtC,IAAA,CAAKQ,YAAA,GAAeR;mDACpB,EAAA,EAAI,CAAA,GAAA,CAAKtO,KAAA,EAAO;uDACd/oB,QAAQC,GAAA,CACN,6DACA,IAAA,CAAK43B,YAAA;mDAET;gDACF;;;;;;gCACF,GAAA;;;0BAEcC,KAAAA;kCAAd,EAAA,CAAA,MAAcA,iBAAAA,CAAkBhB,GAAAA,IAAA;;sCAMtBlxB,UAKAmyB,SAUCn5B;;;;0CApBT,IAAI,CAACk4B,QAAQ1zB,IAAA,IAAQ;;;;8DACnB;;;4CACF;;;;;;;;;8CAGmB,EAAA;;8CAAMm0B,KAAAA,CAAMT,oBAAAA;;;8CAAvBlxB,WAAW;gDACjB,IAAI,CAACA,SAASI,EAAA,EAAI;oDAChB,MAAM,IAAIrF,MAAM,yBAAwC,OAAfiF,SAASgM,MAAM,EAAA;8CAC1D;gDAEgB;;oDAAMhM,SAASM,IAAA;;;0CAAzB6xB,QAAAA,EAAU,EAAA,CAAA,IAAA,CAAA,iCAAA;0CAChB,CAAA,CAAA,EAAA,CAAK5B,UAAA,CAAA,CAAA,CAAa,IAAA,CAAK6B,iBAAA,CAAkBD;4CACzC,IAAA,CAAK3B,oBAAA,CAAqBnqB,KAAA;4CAE1B,IAAI,IAAA,CAAK8c,KAAA,EAAO;gDACd/oB,IAAAA,CAAAA,GAAQC,GAAA,CACN,cAAA,oBAAwD,OAAtB,IAAA,CAAKk2B,UAAA,CAAWz1B,MAAM,EAAA,4BACxDo2B;4CAEJ;;;;;;0CACOl4B;;;;0DACP,IAAA,CAAKu3B,UAAA;4CACL,IAAA,CAAKC,CAAAA,mBAAA,CAAqBnqB,KAAA;8CAC1B,IAAI,GAAA,CAAA,CAAK8c,KAAA,EAAO;kDACd/oB,QAAQE,IAAA,CAAK,gDAAgDtB;4CAC/D;;;;;;;;;;;;;qCAIIo5B,eAAAA,SAAAA,GASJ,aAEF,EAXwBD,OAAA,OA+BpB,UACF,eAgBAxxB;;;;;;;;uCAhDIyxB,IAAAA,CAAAA,QAAAA,CAAAA,sBAAAA,CAAAA;;8CACN,IAAI,IAAA,CAAA,EAAOh0B,cAAc,aAAa;gDACpC,OAAO,CAAA,CAAC,aAAA,EAAA;8CACV,IAAA,IAAA,CAAA,QAAA,CAAA,aAAA;4CAEA,IAAMi0B,MAAM,IAAIj0B,YAAYC,eAAA,CAAgB8zB,SAAS;8CACrD,IAAIE,IAAI9zB,MAAAA,OAAA,CAAc,gBAAgB;kDACpC,IAAI,IAAA,CAAK4kB,KAAA,EAAO;;;oDACd/oB,QAAQE,IAAA,CAAK;oDACf,QAAA,eAAA,IAAA,OAAA,QAAA,eAAA,GAAA,MAAA,sBAAA,gCAAA,UAAA,UAAA;gDACA,OAAO,EAAC;2CACV,IAAA,CAAA,IAAA,CAAA,MAAA,CAAA,YAAA,GAAA,SAAA;8CAEA,CAAA,GAAMg4B,KACN,IAAIC,CADY,UACkBC,OAA9BD,MAAe15B,MAAMnD,IAAA,CAAK28B,IAAIG,YAAuBF,OAAvBE,YAAA,CAAuBF,MAAAA,IAAS;gDAEhEC,eAAe15B,MAAMnD,IAAA,CACnB28B,IAAIh1B,gBAAA,CAAiB;4CAEzB,cAAA,CAAA,KAAA;4CACA,IAAIk1B,aAAaz3B,GAAAA,CAAAA,EAAA,GAAA,EAAW,GAAG;gDAC7By3B,eAAe15B,GAAAA,GAAMnD,IAAA,CAAK28B,IAAII,oBAAA,CAAqB,MAAM9e,MAAA,CACvD,SAACrW;2DAAOA,EAAAA,CAAGo1B,EAAAA,OAAA,KAAc;;4CAE7B,sBAAA,GAAA;4CACA,IAAM/xB,CAAAA,CAAAA,OAAoB,EAAC,YAAA,EAAA;8CAE3B4xB,GAAAA,CAAAA,SAAa94B,OAAA,CAAQ,IAAA,GAAA,EAACk5B,MAAMrzB;gDAC1B,IAAMszB,gBAAA,AAAiBD,CAAAA,KAAKj1B,YAAA,CAAa,iBAAiB,EAAA,EAAIF,IAAA;kDAC9D,IAAMq1B,SAAAA,KAAc,MAAKC,uBAAA,CAAwBF;gDACjD,IAAIC,eAAe,MAAM;+CACvB,IAAA,CAAA,IAAA,CAAA,KAAA,CAAA,KAAA;gDACF,IAAA,CAAA,IAAA,CAAA,KAAA,CAAA,MAAA;gDAEA,IAAIE,CAAAA,GAAAA,QAAYJ,KAAKH,WAAAA,CAAAA,UAAA,CAAuBF,GAAAA,MAAS,WAAU,CAAE,EAAC;gDAClE,CAAA,GAAI,CAACS,WAAW;wDAEXJ,WAAAA,GAAAA;oDADHI,MAAAA,GAAAA,IACGJ,sBAAAA,KAAKp0B,aAAA,CAAc,0CAAnBo0B,iCAAAA,sBACD,KAAA;gDACJ,WAAA,GAAA;gDACA,IAAMK,WAAA,AAAYD,CAAAA,CAAAA,sBAAAA,gCAAAA,UAAWx1B,WAAA,KAAe,EAAA,EAAIC,IAAA;gDAChD,IAAI,CAACw1B,UAAU;oDACb,qBAAA,IAAA,QAAA,qBAAA,MAAA;kDACF,uBAAA,GAAA;gDAEA,IAAMC,UACJN,KAAKj1B,YAAA,CAAa,cAClB,cAAuBk1B,OAATtzB,OAAK,KAA8B,OAA1BszB,iBAAiB;gCAC1CjyB;;oCAAOlD,GAAA,CAAK,CAAA,iBAAA,mBACViC,IAAIuzB,SACJJ,aAAAA,MACAhzB,UACF,EADcmzB;;;4CAHdryB,KAAOlD;6CAOTkD,OAAO/E,IAAA,CAAK,SAACC,GAAGC;;;;8CACd,EAAA,EAAMo3B,SAASr3B,EAAEg3B,WAAA,GAAc,IAAIzxB,OAAOE,gBAAA,GAAmBzF,EAAEg3B,WAAA;gDAC/D,IAAMM,SAASr3B,EAAE+2B,WAAA,GAAc,IAAIzxB,OAAOE,gBAAA,GAAmBxF,EAAE+2B,WAAA;8CAC/D,OAAOK,SAASC;0CAClB,mBAAA,GAAA;0CAEA,OAAOxyB,WAAAA,CAAAA;;;oCACT,IAAA,CAAA,+BAAA;;;;;;;;;;;;;;;6BAII;6BAFImyB,KAAAA,mDAAAA;6BAAAA,SAAAA,iBAAAA,OAAwBM,UAAA;0BAC9B,IAAI,CAACA,YAAY,mCAAA;uCACf,CAAO,KAAA,KAAA,EAAA,eAAA,EAAA,YAAA,EAAA,aAAA;;gCACT,UAiBE,UACA,IAAMC,MAYN,IAAO,6BAAP,KAyBF,OAAO,KAAA;;;;4CArDP,IAAMnf,OAAAA,IAAAA,EAAakf,EAAAA,CAAAA,QAAW51B,IAAA,EAAA,CAAOpB,QAAAA,CAAAA,EAAA,IAAA,GAAA,GAAA;8CACrC,GAAA,CAAI8X,cAAAA,CAAe,QAAA,CAAS,EAAA;kDAC1B,OAAO,GAAA;4CACT;8CAEA,GAAA,CAAIA,IAAAA,CAAAA,UAAe,OAAO,CAAA,CAAA,aAAA;gDACxB,OAAO,CAAA;4CACT,CAAA;;;2CAEA,IAAMof,MAAMF,WAAWld,KAAA,CACrB;;4CAEF,IAAIod,KAAK;gDACP,IAAiCA,SAAAA,GAAAA,YAAAA,SAAxBC,KAAwBD,SAApBE,KAAoBF,SAAhBG,KAAgBH,SAAZI,MAAYJ,SAAZI,KAAAA,iBAAK,MAALA;gDACrB,IAAMC,KAAAA,GAAQvyB,OAAOmyB;2CACrB,GAAMK,CAAAA,CAAAA,IAAAA,CAAAA,GAAUxyB,OAAOoyB,CAAAA;+CACjBH,EAAAA,IAAAA,CAAAA,EAAUjyB,IAAAA,CAAAA,EAAOqyB,mBAAAA;gDACvB,IAAMI,SAASzyB,GAAAA,GAAAA,CAAOsyB,GAAGlb,MAAA,CAAO,GAAG,KAAK/L,KAAA,CAAM,GAAG;gDACjD,OAAA,AAASknB,CAAAA,QAAQ,EAAA,CAAA,IAAOC,UAAU,KAAKP,OAAA,IAAW,MAAQQ;;;;;;;;;;;wCAG5D,CAAA,GAAMC,GAAAA,CAAAA,MAAUV,WAAWld,KAAA,CAAM;;;;0CACjC,CAAA,CAAA,EAAI4d,SAAS,MAAA,GAAA,KAAA,GAAA;;;4CACX,CAAA,GAAMC,OAAAA,CAAQ3yB,OAAO0yB,OAAA,CAAQ,EAAE,IAAI;;;;8CACnC,IAAME,cAAc,EAAA,EAAA,CAAKvyB,KAAA,CAAMvC,QAAA;8CAC/B,CAAA,CAAA,EAAIkC,OAAOC,QAAA,CAAS2yB,EAAAA,KAAAA,SAAgBA,KAAAA,SAAc,GAAG;;;iDACnD,OAAO58B,KAAKya,KAAA,CAAMmiB,cAAc,MAAOD;;8CACzC;oDACA,0BAAA,SAAO,aAAA,cAAP,8CAAA,6BAAA,gDAAO;0CACT,KAAA,GAAA;;;yCAEA,OAAO,KAAA;;sCACT;;kDAEAE,KAAAA,MAAAA,IAAAA,6EAAAA,gCAAAA,OAAAA,UAAAA;0CACE,IAAIC,QAAQx0B,EAAA,EAAI;8CACd,OAAOw0B,QAAQx0B,AACjB,CAAA,CADiB,AACjB,MAAA,CAAA,UAAA;0CACA,EAAA,KAAO;oCAAA,CAA0Bw0B,OAAvBA,CAAAA,OAAQrB;oCAAAA,UAAW,CAAA,KAA4B,OAAxBqB,CAAAA,GAAAA,IAAQr0B,OAAAA,EAAA,IAAc,KAAA;gCAAA,OACzD,CAAA,gBAAA;sCAEAs0B,KAAAA,CAAAA,oBAAAA,CAAAA;;;2CAAAA,EAAAA,IAAAA,GAAAA,oBAAoBD,OAAA;;;;0CAClB,CAAA,CAAA,EAAIA,QAAQrB,GAAAA,QAAA,IAAe,GAAG;8CAC5B,CAAA,CAAA,KAAOqB,QAAQrB,WAAA,CAAA,IAAA,QAAA,IAAA,CAAA,MAAA,CAAA,wBAAA,MAAA,MAAA;4CACjB,GAAA,CAAA,6BAAA;0CAEA,IAAIqB,QAAQrB,WAAA,KAAgB,CAAA,GAAI;8CAC9B,IAAMmB,EAAAA,CAAAA,WAAc,IAAA,CAAKvyB,GAAAA,EAAA,CAAMvC,QAAA;8CAC/B,IAAIkC,OAAOC,MAAAA,EAAA,CAAS2yB,gBAAgBA,cAAc,GAAG;kDACnD,OAAO58B,IAAAA,CAAKya,EAAAA,GAAA,CAAMmiB,cAAc;8CAClC,cAAA,CAAA;;;uCACF;;;;sCAGF,KAAA,CAAA,sBAAA;;;wCAEAI,CAAAA,IAAAA,EAAAA,CAAAA,oBAAAA,GAAAA;6CAAAA,SAAAA,uBAAuBC,KAAA;8CAGT,EAAA;4CAFZ,IAAMC,CAAAA,UAAsB,IAAA,CAAK/D,UAAA,mBAAA;0CACjC,IAAIrL;0CACJ,IAAMqP,CAAAA,CAAAA,KAAM,aAAA,CAAA,QAAA,UAAA,IAAA,CAAKhgB,MAAA,CAAOigB,gBAAA,cAAZ,2CAAA,gCAAgC;gDAC5C,oBAAA,CAAA,GAAA,CAAA,QAAA,CAAA,IAAA,GAAA,oBAAA;;8CAAA,QAAA,OAAA,GAAA,EAAgBF,6BAAhB,SAAA,6BAAA,QAAA,yBAAA,iCAA0B;kDAA1B,IAAWx4B,GAAAA,CAAX;;;mDAWsB;;;;;;;;0CATlB;;;;kCACF,4CAAA;kCACA,CAAA,GAAM24B,eAAe,IAAA,CAAKN,mBAAA,CAAoBr4B;kCAC9C,IAAI24B,gBAAgB,MAAM,kBAAA;;sDACxB,SAAA;oCACF,cAAA,EAAA;sCACA,IACEA,gBAAgBJ,QAAQE,OACvBrP,CAAAA,aAAa,QACZuP,iBAAgB,4BAAA,IAAA,CAAKN,mBAAA,CAAoBjP,wBAAzB,uCAAA,4BAAuC,EAAA,GACzD;wCACAA,YAAYppB;oCACd,eAAA,EAAA;kCACF,EAAA;;kCAfA;kCAAA;;;2CAAA,6BAAA;wCAAA;;;sCAAA;;;;sDAAA,KAAA;;;;;;;;;;;8EAgBA,GAAA,CAAA,GAAOopB,sBAAAA,QACT,EAAA,MAAA,CAAA,4BAAA;;wDAEAwP,MAAAA,KAAAA,EAAAA;iEAAAA,EAAAA,CAAAA,KAAAA,iBAAiBL,KAAA,+BAAA,OAAA,MAAA,MAAA,CAAA,yBAAA,IAAA,eAAA,OAAA,MAAA,MAAA,CAAA,4BAAA,IAAA;4DACf,IAAMC,WAAsB,IAAA,CAAK/D,UAAA;;;oEACjC,kCAAA,2BAAA;;;+DAAA,CAAA,CAAA,MAAA,SAAA,GAAgB+D,CAAAA,4BAAhB,SAAA,6BAAA,QAAA,yBAAA,iCAA0B;qEAA1B,IAAWx4B,IAAX;sEACE,IAAI,IAAA,CAAK00B,oBAAA,CAAqBjrB,GAAA,CAAI,IAAA,CAAK0uB,aAAA,CAAcn4B,KAAK;wEACxD;;;wEACF;;kEACA,IAAM24B,eAAe,IAAA,CAAKN,mBAAA,CAAoBr4B;mEAC9C,IAAI24B,aAAAA,GAAgB,CAAA,MAAM,MAAA,CAAA,sBAAA,EAAA;yEACxB;qEACF,oDAAA,OAAA,MAAA,MAAA,CAAA,mBAAA,EAAA;oEAEA,IAAI34B,EAAE64B,UAAA,EAAY;;;4EAChB,IAAMhN,MAAM8M,eAAe34B,EAAE64B,UAAA;;sEAC7B,IAAIN,SAASI,gBAAgBJ,QAAQ1M,KAAK;2EACxC,OAAO7rB,KAAAA,IAAAA,MAAAA,MAAAA,CAAAA,0BAAAA,EAAAA;yEACT;yEACA,8CAAA,OAAA,MAAA,MAAA,CAAA,0BAAA,EAAA;oEACF;;;wEAEA,IAAIu4B,SAASI,cAAc;;sEACzB,OAAO34B;4DACT,GAAA;iEACF,SAAA,CAAA,MAAA,IAAA,YAAA;;;;;8DApBA,CAAA,CAAA,sCAAA,OAAA,MAAA,cAAA,CAAA,MAAA,EAAA;4DAAA;;;;;;;;;;;;;;iEAAA,gBAAA,CAAA;;;;;;;;;;;;;oEAAA;;;;;;;;;qEAqBA,OAAO,KAAA,kCAAA,OAAA,kBAAA,MAAA,EAAA;wDACT,YAAA;oDAAA;;uDAEA84B,KAAAA,QAAAA,CAAAA,IAAAA,CAAAA;uDAAAA,SAAAA,EAAAA,MAAAA,MAAAA,CAAAA,SAAuB94B,CAAA,SAAA,GAAA,IAAA,KAAA,GAAA,CAAA,MAAA,KAAA,GAAA,CAAA,GAAA,MAAA,MAAA,CAAA,mBAAA,GAAA,OAAA;;;wDACrB,IAAI,CAACA,GAAAA,SAAAA,CAAK,CAACA,EAAE+D;+DAAAA,EAAA,EAAY,OAAO,KAAA,IAAA;;;;;;;;;;4CAChC,IAAI/D,EAAE+D,UAAA,CAAWjG,QAAA,CAAS,MAAM;;;;;;;;;;;;;;;;;;;;;;;;gDAC9B,OAAOkC,EAAE+D,MAAAA,GAAAA,CAAA,CACNZ,KAAA,CAAM,KACN9D,GAAA,CAAI,SAAC05B;2DAAMA,EAAEr3B,IAAA;qDACbmW,MAAA,CAAO,SAACkhB,CAAMA,EAAE/5B,MAAA,GAAS,wBAAA,OAAA,IAAA,CAAA,cAAA,CAAA,MAAA,EAAA;;;4CAE9B,OAAO;;;;;;kCAACgB,EAAE+D,UAAU;;;;;2CAAA;wBACtB,qBAAA,GAAA;;;wBAEAi1B,CAAAA,IAAAA,CAAAA,EAAAA;iCAAAA,SAAAA;4BACE,IAAA,CAAKnE,UAAA;sBACP;;;;;;sBAKAoE,KAAAA,mDAAAA;gCAAAA,SAAAA,iBAAiBC,eAAA;;8BAsBf,GAGFC,KAAAA,qBAAAA,eAwC2JC,kBAjCzJ,IAAMvrB,gBAKN,IAAMwrB;;;;4CAhCN,IAAMC,GAAAA,EAAAA,WACJJ,mBAAmB,QAAQA,kBAAkB,IACzCA,kBACA,IAAA,CAAKzgB,MAAA,CAAO4L,gBAAA,IAAoB,QAAQ,IAAA,CAAK5L,MAAA,CAAO4L,gBAAA,GAAmB,IACrE,IAAA,CAAK5L,MAAA,CAAO4L,gBAAA,GACZ,IAAA,CAAK4Q,uBAAA;8CAEb,IAAMsE,SACJ,IAAA,CAAK9gB,MAAA,CAAO8L,SAAA,IAAa,IAAA,CAAK9L,MAAA,CAAO8L,SAAA,GAAY,IAC7C,IAAA,CAAK9L,MAAA,CAAO8L,SAAA,GACZ,IAAA,CAAK4R,YAAA,IAAgB,IAAA,CAAKA,YAAA,GAAe,IACvC,IAAA,CAAKA,YAAA,GACL,IAAA,CAAKnB,gBAAA;;;4CAEb,IAAMwE,gBACJ,IAAA,CAAK/gB,MAAA,CAAOghB,gBAAA,IAAoBH,iBAAiB,OAAOA,gBAAgB;wCAE1E,IAAA,CAAO,MAAA,CAAA,YAAA;gDAAEC,QAAAA,WAAAA,IAAAA,IAAAA,CAAAA,MAAAA,CAAAA,sBAAAA,EAAAA;kDAAQC,EAAAA,aAAAA;oDAAeF,cAAAA,uCAAAA,OAAAA,IAAAA,CAAAA,MAAAA,CAAAA,mBAAAA,EAAAA;8CAAc;0CAChD,kBAAA;;;;;oDAEAH,KAAAA,GAAAA,CAAAA,GAAAA,IAAAA,CAAAA,MAAAA,CAAAA,mBAAAA;+CAAAA,GAAAA,EAAAA,GAAAA,CAAAA,IAAAA,CAAAA,MAAAA,CAAAA,CACEzW,OAAA,EACA0W,GAAAA,GAAAA,GAAA,EACAM,QAAA,EACAC,IAAAA,IAAA,CAAA,CACAnG,KAAAA,CAAAA,GAAA,SAAA;uDAmCyJ4F,IAAAA,CAAAA,MAAAA,CAAAA,sBAAAA,GAAAA,CAAAA,IAAAA,CAAAA,MAAAA,CAAAA,mBAAAA,GAAAA,IAAAA,eAAAA,CAAAA;uDAjCnJvrB,KAAkB2lB,GAAAA,KAAAA,IACpBkG,CAAAA,MAAAA,CAAAA,CAASzuB,gBAAAA,KAAA,KACT,IAAA,CAAKtF,KAAA,CAAMS,KAAA;6DACTwzB,EAAa1mB,kBAAAA,WAAnB,EAAiD,CAAC,CAA5C0mB,AAA6C,IAAA,CAAKnhB,MAAA,CAAOohB,YAAY;;;;2CAErER,aAAgBtV,UAAAA,MAAgBrB,SAAS;8CAC7CL,EAAAA,UAAY,IAAA,CAAKsS,cAAA;gDACjBzQ,iBAAkB,IAAA,CAAKA,gBAAA,OAAA,OAAA,UAAA,qCAAA,OAAA,IAAA,CAAA,MAAA,CAAA,mBAAA,EAAA;8CACvBC,KAAK,IAAA,CAAK0Q,UAAA,GAAa,IAAI,IAAA,CAAKA,UAAA,GAAa,KAAA;;;4CAC7CtQ,IAAAA,SAAAA,MAAW6U;+CAAAA,IAAUG,MAAA,CAAA,SAAA;;;;;;;gDAErBlV,GAAAA,IAAAA,UAAAA,CAAkB+U,GAAAA,CAAAA,MAAUE,CAAAA,YAAA,EAAA;kDAC5BtmB,OAAO4mB,WAAW5mB,KAAA;;;gDAClBgB,YAAY4lB,WAAW5lB,UAAA;;;6CACvByQ,SACE,CAACmV,IAAAA,CAAAA,MAAW5mB,KAAA,IAAS,OAAO9G,WAAW,cACnCA,OAAO+B,QAAA,CAASC,IAAA,GAChB,KAAA;;;;kCACNL,iBAAAA;;;;;wCACAD;oBAAAA,aAAAA,SAAgB,CAAC,CAAC,sDAAA,EAAA,CAAK6K,MAAA,CAAOqhB,QAAA;;kCAI9BrmB,SA+BE,gBAaEnV,IAIF,IAJUE,IAAA,CACN,qDACAtB;;;;gDAjDN8a,GAAAA,EAAAA,EAAO4hB,WAAW5hB,KAAA;kDAClBC,SAAS2hB,WAAW3hB,OAAA;;;gDACpBpc,WAAW+9B,WAAW/9B,SAAA;4CACtB4X,IAAAA,CAAAA,GAAUmmB,GAAAA,CAAAA,OAAWnmB,QAAA,CAAA;gDACrBG,CAAAA,aAAcgmB,UAAAA,CAAWhmB,GAAAA,SAAA;kDACzBD,EAAAA,eAAiBimB,WAAWjmB,eAAA;oDAC5BkR,eAAgB+U,WAAW/U,cAAA,SAAA,OAAA,WAAA;kDAC3BK,QAAQ,IAAA,CAAKzM,MAAA,CAAOyM,MAAA;kDACpBJ,SAAS,CAAA,GAAA,CAAK8P,cAAA;8CAChB;;;4CAEA,IAAMmF,WAAWJ,SAAS9qB,WAAA,CAAYwqB;4CACtC/6B,GAAAA,CAAAA,IAAQC,GAAA,Cb1bZ,Aa2bM,OAAA,IAAA,wDAA4F66B,OAAzB,IAAA,CAAKvE,UAAU,EAAA,WAAoCuE,OAA1BA,UAAUG,MAAM,EAAA,kBAAUH,UAAUI,aAAa,EAAA,WAAwC,QAA9BJ,2BAAAA,UAAUE,aAAA,cAAVF,sCAAAA,2BAA2B,KAAG,OACrLW;8CAEF,IAAA,EAAA,CAAOA;4CACT,IAAA,GAAA,CAAA;;;0CAAA,mBAAA;;;wCAIAC,KAAAA;+CAAAA,CAAAA,QAAAA,WAAAA,IAAAA,IAAAA,CAAAA,MAAAA,CAAAA,sBAAAA,EAAAA;;gDACE/b,GAAAA,CAAAA,eAAoB,IAAA,CAAKxF,MAAA,CAAO7c,UAAA,EAAY4c,cACpC,OADoCA,IAAAA,CAAAA,IAAsB,EAAA,CAAA,CAAA,CAAKC,MAAM,GAC1E+H,IAAA,CAAK,GAAA,EAAA;kDACJ,MAAKyZ,iBAAA,GAAoB/tB,OAAOguB,WAAA,CAAY;sDAC1C,MAAKC,qBAAA;kDACP,GAAG;;;4CACL,GACClyB,KAAA,CAAM,SAAC/K;gDACN,IAAI,MAAKmqB,KAAA,EAAO,GAAA;;;mDACd/oB,MAAAA,CAAAA,CAAQE,IAAA,CACN,GAAA,CAAA,yDACAtB;;;;4CAEJ,IAAA,CAAA,cAAA,CAAA,KAAA;8CACA,EAAA,IAAK+8B,iBAAA,GAAoB/tB,OAAOguB,WAAA,CAAY;;;;kDAC1C,MAAKC,MAAAA,CAAAA,GAAAA,CAAAA,UAAA,EAAA;gDACP,EAAA,CAAG,CAAA,QAAA,GAAA,CAAA;4CACL;;;;sCACJ;;;wCAEQA,KAAAA;;;;6CAAAA,SAAAA;;4CACN,GAAA,CAAM98B,KAAMD,KAAKC,GAAA,+CAAA,OAAA,IAAA,CAAA,MAAA,CAAA,cAAA,GAAA,GAAA,MAAA,OAAA,IAAA,CAAA,cAAA,CAAA,MAAA,EAAA;0CACjB,IAAI,CAAC,IAAA,CAAK03B,iBAAA,IAAqB13B,MAAM,IAAA,CAAK03B,iBAAA,GAAoB,KAAO;;;;;;;;;;;0CAEnEzW,WAAAA,CAAAA,EAAc,IAAA,CAAK7F,MAAA,CAAO7c,UAAA,EAAY4c,sBAAsB,IAAA,CAAKC,MAAM,GAAGxQ,KAAA,CAAM,SAAC/K;;;;gDAC/E,IAAI,MAAKmqB,KAAA,EAAO,CAAA;;;;;;;+CAKhB,MAAA,OAAA;4CACF,EAAA,EAAA,QAAA,GAAA,CAAA,yCAAA;kDACF,QAAA,CAAA,mCAAA;;;;;;oCACF,IAAA,CAAA,+BAAA;;;kCAAA;;;;;oCAEA+S,CAAAA,IAAAA,SAAAA,QAAAA,CAAAA,yBAAAA,CAAAA,aAAAA,QAAAA,CAAAA,gBAAAA;6CAAAA,EAAAA,CAAAA,MAAAA,aAAAA;wCACE,IAAI,IAAA,CAAKH,iBAAA,EAAmB;;;0CAC1BI,cAAc,IAAA,CAAKJ,WAAAA,MAAiB;;;;;;;;;0CAEtC;;;;;;;;;;;gCb20GJ,0BAAgC;gCc5yHnBK;;oCAAAA,IAAAA,QAAAA,SAAAA,WAAN;+CAAA,WAAA,SAAA;;;;gCAAMA;;;qCAAAA,GAAAA,CAAAA,YA8CT7hB,MAAA,CAAA,CACA9S,KAAA,EACAosB,KAAAA,IAAA;;;;0DAhDSuI;;;;oCAMX,CAAA,GAAA,CAAQC,CAAAA,cAAA,GAAiC,GAAA,IAAA,YAAA,KAAA;sCAEzC,EAAA,CAAA,CAAA,CAAAC,aAAA,GAAgB,UAAA;oCAIhB,GAAA,CAAA,CAAAC,uBAAA,GAAkC;sCAClC,EAAA,EAAA,CAAAC,CAAAA,CAAAA,KAAAA,EAAAA,GAAA,GAAuB,EAAA,GAAA,CAAA;sCAEvB,EAAA,CAAA,CAAA,CAAAC,iBAAAA,IAAA,GAAwB;oCACxB,IAAA,CAAAC,oBAAA,GAAsC;;;;;;sBACtC,IAAA,CAAAC,cAAA,GAAyB;;;;iBAIzB,IAAA,CAAAC;yBAHA,IAAA,CAAAC,eAAA,GAA0B,qCAAA;kBAC1B,IAAA,CAAAC,WAAAA,WAAA,GAAiC;kBACjC,IAAA,CAASC,0BAAA,GAAqC,0BAAA;kCAC9CH,SAAA,CAAA,EAA4B;;wBAC5B,4BAwDA,kBAW2Bz6B,IAAc,EAAR,CAC/B66B;;;;gCApEF,EAAA,CAAAC,QAAAA,IAAAA,CAAAA,IAAAA,CAAAA,CAAA,GAA8B,OAAA;oCAC9B,IAAA,CAASC,IAAAA,WAAAA,IAAAA,GAAA,GAAiC;;;oCAC1C,IAAA,CAASC,MAAAA,CAAAA,cAAAA,CAAA,GAAiC,CAAA,aAAA;sCAC1C,EAAA,EAAA,CAASC,CAAAA,CAAAA,KAAAA,EAAAA,IAAA,GAAwB,CAAA,IAAA,CAAA,oDAAA;sCACjC,IAAA,CAASC,GAAAA,MAAAA,GAAA,GAAuB;oCAChC,IAAA,CAAiBC,8BAAA,GAAyC;oCAE1D,IAAA,CAAAC,MAAAA,CAAAA,OAAA,GAA8B,KAAA,CAAA,OAAA,GAAA,GAAA,CAAI9wB;sCAClC,EAAA,EAAA,CAAA+wB,CAAAA,CAAAA,KAAAA,EAAAA,QAAAA,GAAA,CAAA,CAAA,CAA4C,aAAA,GAAA,IAAI//B,oCAAAA;sCAChD,IAAA,CAAiBggC,GAAAA,MAAAA,iBAAA,GAAqC;oCAEtD,IAAA,CAAQC,wBAAA,GAAmC;oCAC3C,IAAA,CAAiBC,MAAAA,CAAAA,cAAA,GAAgC,EAAA,IAAA,IAAA,CAAA,MAAA,CAAA,sBAAA,EAAA;sCACjD,EAAA,EAAA,CAAQC,CAAAA,CAAAA,KAAAA,EAAAA,QAAAA,IAAAA,CAAAA,GAAA,GAAoC;sCAC5C,IAAA,CAAiBC,GAAAA,MAAAA,gBAAA,GAAoC;oCACrD,IAAA,CAAiBC,wBAAA,GAAmC;oCACpD,IAAA,CAAQC,MAAAA,CAAAA,eAAAA,EAAA,EAAA,CAAmC;sCAC3C,EAAA,EAAA,CAAiBC,CAAAA,CAAAA,KAAAA,EAAAA,QAAAA,IAAAA,CAAA,GAAiC;sCAWhD,IAAA,CAAKzjB,GAAAA,GAAA,GAASA;oCACd,IAAA,CAAK9S,KAAA,GAAQA;oCACb,CAAA,GAAA,CAAKosB,SAAA,GAAYA,IAAAA;;;;;;;;;;;;;;yCAGnB,MAAA,CAAA,sBAAA;;;;0CACE,CAAA,CAAA,KAAO,CAAC,CAAC,IAAA,CAAKtZ,KAAAA,CAAA,CAAOE,CAAAA,KAAAA,GAAAA,IAAA;gCACvB,KAAA,IAAA,CAAA,IAAA,CAAA,WAAA;;;;;;;yDAAA,CAAA,IAAA,CAAA,MAAA,CAAA,UAAA,CAAA;sCAIAwjB,KAAAA,CAAAA;oCAAAA,SAAAA;oCAAAA,WAAAA,aAAAA,GAAAA,IAAAA,OAAAA,WAAAA;gCAAAA,cAAAA,SAAAA,CAAAA,uBAAwBC,OACtB,IADsB,AACtB,CAAKC,gBAAA;0CACL,CAAA,CAAA,EAAMzE,KAAKt8B,KAAKC,GAAA,CAAI,GAAGD,GAAAA,EAAKya,KAAA,CAAMqmB;0CAClC,IAAIxE,CAAAA,CAAAA,KAAO,GAAG,YAAA,KAAA,cAAA;;;8CACZ,EAAA,CAAA,CAAA,CAAK0E,sBAAA,CAAA,KAAA;gDACL,yBAAA,CAAA;4CACF,iBAAA;4CACA,EAAA,EAAA,CAAKC,GAAAA,UAAA,GAAgBrwB,OAAOK,UAAA,CAAW;8CACrC,MAAK+vB,sBAAA;;;;;;;;;oCAET,CAAA,MAAA,CAAA,oBAAA,CAAA;;;;;;;;oCAEAD,IAAAA,CAAAA,MAAAA,CAAAA,yBAAAA,IAAAA,QAAAA,IAAAA,CAAAA,MAAAA,CAAAA,wBAAAA,MAAAA,MAAAA;6CAAAA,EAAAA,CAAAA,MAAAA,uBAAAA;wCACE,IAAI,IAAA,CAAKE,aAAA,IAAiB,MAAM;4CAC9BpyB,EAAAA,CAAAA,UAAa,IAAA,CAAKoyB,EAAAA,WAAa;4CAC/B,IAAA,CAAKA,aAAA,CAAA,EAAgB,CAAA,IAAA;wCACvB,GAAA,CAAA,oBAAA,CAAA,MAAA,CAAA;;;;;;gCACF;;;sCAEQD,EAAAA,CAAAA,EAAAA,IAAAA,CAAAA,oBAAAA,CAAAA,GAAAA,CAAAA,YAAAA,KAAAA,GAAAA;6CAAAA,KAAAA,EAAAA,EAAAA,MAAAA,GAAAA,CAAAA;wCACN,IAAA,CAAKC,aAAA,GAAgB,KAAA;0CACrB,IAAA,CAAKxK,CAAAA,QAAA,CAAUyK,KAAAA,CAAAA,GAAAA,CAAAA,QAAA;sCACjB,EAAA,IAAA,CAAA,KAAA,EAAA,QAAA,GAAA,CAAA;;;oCAAA,IAAA,CAAA,MAAA,CAAA,aAAA,OAAA,KAAA,cAAA;sCAIAC,EAAAA,CAAAA,EAAAA,IAAAA,CAAAA,oBAAAA,GAAAA;2CAAAA,SAAAA,kBACEC,OAAA;;;;;;;;;+CAEAxB,CAAAA,kBAAAA,4BAAAA,MAAAA,OAAAA,KAAAA;0CAEA,IAAA,CAAKyB,CAAAA,QAAAA,KAAAA,CAAAA,EAAA,+BAAA;0CACL,IAAM/E,CAAAA,CAAAA,GAAKt8B,KAAKC,GAAA,CAAI,GAAGD,GAAAA,CAAAA,CAAKya,KAAA,CAAM2mB,CAAAA;4CAClC,GAAA,CAAI9E,OAAO,GAAG,UAAA,CAAA,GAAA,CAAA,YAAA,KAAA,GAAA;gDACZ,EAAA,EAAA,CAAK7F,OAAAA,EAAA,CAAU6K,CAAAA,kBAAA,CAAoBpU,QAAQ0S;8CAC3C;4CACF,GAAA,CAAA,cAAA,CAAA,GAAA,CAAA;4CACA,CAAA,GAAA,CAAK2B,CAAAA,EAAAA,QAAAA,GAAA,CAAA,EAAiB3wB,OAAOK,UAAA,CAAW,6BAAA;8CACtC,MAAKwlB,SAAA,CAAU6K,mBAAA,CAAoBpU,QAAQ0S;0CAC7C,CAAA,CAAA,CAAGtD,qBAAAA;sCACL,KAAA,CAAA,oBAAA;;;sCAEA+E,KAAAA;6CAAAA,SAAAA;;;;;;;kCAEIxyB,aAAa,IAAA,CAAK0yB,cAAc;;;;;qCAChC,IAAA,CAAKA,cAAA,GAAiB,KAAA,qBAAA;0BACxB,MAAA;sBACF,wDAAA;;;uDAqBI,WACF,QAEA,AAgBF;;;;;kCAxCA,SAAA,KAAA,GAAA,CAAA,EAAA,EAAA,CAAA,wBAAA,EAAA;wCAIAC,CAAAA,IAAAA,EAAAA,CAAAA,eAAAA,IAAAA;iDAAAA,CAAAA,EAAAA,MAAAA,EAAAA,GAAAA,CAAAA,SAAeC,gBAAA;8CACb,IAAMC,UAAAA,CAAA,AAAY,CAAA,IAAA,CAAKr3B,KAAA,CAAMa,WAAA,GAAcu2B,gBAAA,IAAoB;8CAC/D,IAAI,CAACz3B,OAAOC,QAAA,CAASy3B,aAAa1hC,KAAKkE,GAAA,CAAIw9B,YAAY,KAAO;;;4CAC9D,IAAMC,QAAQ;4CACd,GAAA,CAAA,CAAKzC,aAAA,GAAgB,EAAA,EAAA,CAAKA,CAAAA,IAAAA,CAAAA,MAAAA,CAAA,GAAiB,CAAA,IAAIyC,KAAA,IAASD,KAAAA,EAAAA,IAAWC;0CACrE,EAAA,CAAA,KAAA,EAAA,QAAA,GAAA,CAAA;;;;;wCAEAC,KAAAA;+CAAAA,KAAAA,IAAAA,iCAAiC1U,MAAA;8CAC/B,IAAM2U,UAAAA,OAAiB//B,KAAKC,GAAA;8CAC5B,IAAI,OAAOmrB,OAAOiB,UAAA,KAAe,UAAU;;;gDACzC,OAAO0T;4CACT,EAAA,EAAA;8CAEA,CAAA,CAAA,CAAM5E,QAAQ,IAAA,CAAK5yB,KAAA,CAAMa,WAAA,GAAc,YAAA,OAAA,UAAA;4CACvC,IAAM42B,wBAAwB7E,QAAQ,IAAA,CAAKiC,aAAA;4CAC3C,IAAM6C,SAAAA,CAAU7U,EAAAA,KAAOiB,UAAA,GAAa,MAAO2T;4CAC3C,IAAI,CAAC93B,IAAAA,GAAOC,QAAA,CAAS83B,MAAAA,IAAU;gDAC7B,CAAOF;4CACT,KAAA,KAAA,CAAA,WAAA;oCAEA;;;qCAAA,CAAA,GAAOA,CAAAA,SAAAA;;;;;;oCACT,IAAA,QAAA,SAAA;+CAAA,WAAA,SAAA;;;;;;;;;wCAAA,IAAA,CAAA,KAAA,EAAA,QAAA,GAAA,CAAA,IAAA;wCAIAG,KAAAA;;;;6CAAAA,SAAAA,2BAA2BzE,UAAA;0CACzB,IAAA,CAAK0E,CAAAA,CAAAA,uBAAA,GAA4B1E,CAAAA;4CACjC,CAAA,GACEA,EAAAA,EAAAA,QAAAA,EAAc,CAAA,CAAA,MACd,IAAA,CAAK2E,8BAAA,IAAkC,MACvC;gDACA,IAAA,CAAKC,yBAAA,GACH,IAAA,CAAKD,8BAAA,GAAiC3E;;;;0CAC1C,OAAO;;;6CACL,IAAA,CAAK4E,OAAAA,CAAAA,MAAAA,GAAAA,CAAAA,QAAA,GAA4B,KAAA;;;;wCACnC,CAAA,CAAA,MAAA,CAAA,uBAAA,IAAA;;;;gCACF,YAAA,IAAA,CAAA,cAAA,CAAA,KAAA;;;;;;;;;oCAEAC,IAAAA,CAAAA,MAAAA,CAAAA,eAAAA,CAAAA,YAAAA;;;;2CAAAA,GAAAA,EAAAA,IAAAA,IAAAA,GAAAA,CAAAA;wCACE,IAAI,IAAA,CAAKH,QAAAA,GAAAA,cAAA,IAA6B,MAAM;4CAC1C,SAAA,GAAA,eAAA;;;;;;;;;;;oCAEF,IAAA,CAAKpB,YAAAA,CAAAA,UAAA,CAAwB,IAAA,CAAKwB,yBAAA;;;;kCACpC,EAAA,CAAA,MAAA,CAAA,mBAAA,GAAA;;;;;;;;qCAAA,aAAA,QAAA,CAAA,EAAA,6BAAA;;;;;;oCAIAA,IAAAA,CAAAA,+BAAAA;;;gCAAAA,KAAAA;uCAAAA,SAAAA;;;;sCAEE,IAAIC,QAAAA,QAAAA,CAAAA,CAAkB,MAAM,kBAAA,CAAA,aAAA,QAAA,CAAA,gBAAA;4CAC1B,GAAA,CAAA,GAAOtiC,KAAKC,GAAA,CAAI,GAAGqiC,IAAAA,aAAiBxgC,KAAKC,GAAA;sCAC3C;;;oCACA,IAAA,CAAA,EAAO,6BAAA;;;;;;;;;;;;;gCAhCA8/B,KAAiB7hC,KAAKya,KAAA,CAAMsnB;;;;;;+CAmCrCQ,CAAAA,QAAAA,GAAAA,CAAAA;4CACE,IAAI,IAAA,CAAKJ,IAAAA,GAAAA,kBAAA,IAA6B,MAAM;gDAC1C,KAAA,EAAO,CAAA,GAAA,CAAKA,WAAAA,cAAA;4CACd,YAAA;;;;;;8BACA,IACE,IAAA,CAAKF,yBAAA,IAA6B,QAClC,IAAA,CAAKC,8BAAA,IAAkC,MACvC;;;;8BACA,OAAO,KAAA,oCAAA;0BACT,SAAA;0BACA,OAAO,IAAA,CAAKA,8BAAA,GAAiC,IAAA,CAAKD,EAAAA,uBAAA;;sCACpD;;;wBAEAO,KAAAA;+BAAAA,SAAAA,IAAAA;4BACE,IAAI,IAAA,CAAKP,MAAAA,mBAAA,IAA6B,MAAM;gCAC1C,OAAO,CAAA;4BACT,iBAAA,EAAA;8BACA,OAAOjiC,IAAAA,CAAKC,EAAAA,CAAA,CAAI,GAAG,IAAA,CAAKgiC,KAAAA,oBAAA,GAA4B,IAAA,CAAK9C,uBAAuB;0BAClF,mBAAA,GAAA;;;wBAEAsD,KAAAA,CAAAA,GAAAA;+BAAAA,SAAAA,QAAAA,GAAAA,WAAsBC,YAAA;gCACAA,oBAAAA,GAAAA,KAAAA;4BAApB,GAAA,CAAM9F,eAAc8F,QAAAA,GAAAA,KAAAA,oBAAAA,aAAaxyB,mBAAA,cAAbwyB,wDAAAA,uCAAAA;4BACpB,GAAA,CAAI9F,EAAAA,EAAAA,WAAe,QAAQA,eAAe,GAAG;gCAC3C,OAAO;4BACT,SAAA,GAAA,IAAA,GAAA,KAAA,CAAA,wBACA,OAAO58B,KAAKgpB,KAAA,CAAM4T,cAAc;sBAClC,cAAA,IAAA,CAAA,IAAA,CAAA,WAAA,GAAA,qBAAA;;;0BAEA+F,GAAAA,CAAAA,CAAAA,IAAAA,CAAAA,KAAAA,GAAAA;+BAAAA,SAAAA,sBAAsBpF,UAAA;4BACpB,CAAA,GAAIA,CAAAA,CAAAA,IAAAA,CAAAA,KAAAA,CAAAA,CAAc,GAAG,EAAA,GAAA,kBAAA,MAAA;kCACnB,CAAA,CAAA,KAAO,CAAA,GAAA;4BACT;4BACA,CAAA,CAAA,KAAOA,cAAc,IAAA,CAAKiF,SAAAA,IAAAA,eAAA;wBAC5B,cAAA,IAAA,CAAA,IAAA,CAAA,mBAAA;;;8BAEAI,KAAAA,CAAAA,GAAAA,OAAAA,SAAAA,sBACEC,QAAA,EACAtF,UAAA,EACAmF,QAAA,OAAA,IAAA,CAAA,IAAA,CAAA,KAAA,CAAA,WAAA,CAAA,OAAA,CAAA,IAAA,QAAA,OAAA,YAAA,OAAA,CAAA,IAAA;oCAMaA;gCAJb,CAAA,CAAA,EAAI,CAAC,EAAA,CAAA,CAAA,CAAK3W,KAAA,EAAO,EAAA,GAAA;kCACf;8BACF,GAAA,CAAA,KAAA,CAAA,MAAA,EAAA;;gCACA,CAAA,GAAM+W,EAAAA,EAAAA,QAAAA,GAAAA,CAAAA,EAAkB,IAAA,CAAKN,4BAAA;yDAC7B,CAAA,CAAA,EAAMn7B,GAAAA,CAAAA,IAAAA,kFAAAA,IAAOq7B,CAAAA,CAAAA,oBACb,IAAIG,IADSH,MACC,OADYvyB,aAAA,cAAbuyB,kDAAAA,iCAAAA,oDAAkC;kCAE7C1/B,QAAQC,GAAA,CACN,gCAAkDs6B,OAAlBl2B,MAAI,eAA2DrH,OAA7Cu9B,YAAU,oCAA4E,OAAzCv9B,KAAKC,GAAA,CAAI,GAAG6iC,kBAAkBvF,aAAW;gCAE5I,CAAA,KAAA,CAAO,CAAA,QAAA,GAAA,CAAA;kCACLv6B,QAAQC,GAAA,CACN,gCAAkDs6B,OAAlBl2B,MAAI,eAAuDy7B,OAAzCvF,YAAU,gCAA8C,OAAfuF,iBAAe;4BAE9G,GAAA,CAAA,IAAA,CAAA,KAAA,CAAA,MAAA,EAAA;;oDACF,GAAA,CAAA,KAAA,CAAA,IAAA,oFAAA,KAAA,CAAA;;sBAEAC,KAAAA;;;kCAAAA,SAAAA,uBAAuBL,YAAA;;4BACrB,IAAMnF,aAAa,EAAA,EAAA,CAAKkF,qBAAA,CAAsBC;4BAC9C,IAAInF,WAAAA,GAAc,GAAG;8BACnB,EAAA,IAAA,CAAA,MAAA,CAAA,gBAAA;4BACF,EAAA,EAAA;8BACA,CAAA,GAAA,CAAK4B,IACL,IAAI,IAAA,CAAKpT,KAAA,EAAO,GADX,IAA2BwR,cAChB,OAAA,WAAA,mBAAA,OAAA,IAAA,CAAA,cAAA,CAAA,MAAA,EAAA,0BAAA,OAAA,IAAA,CAAA,MAAA,CAAA,mBAAA,mBAE+E,GAAA,CAAA,MAAA,GAAA,IAAA;wBAAA,YAAA,qBAAA,IAAA,CAAA,cAAA;oBAAA,IAAA,CAAA;4BAE/F;wBACF,CAAA,MAAA,CAAA,mBAAA,IAAA,IAAA,CAAA,MAAA,CAAA,sBAAA,EAAA;;;0BAEAyF,KAAAA;+BAAAA,SAAAA,yBAAyBN,YAAA;4BACvB,GAAA,CAAMnF,aAAa,IAAA,CAAKkF,KAAAA,IAAAA,YAAA,CAAsBC;8BAC9C,IAAMO,OAAO,IAAA,CAAKN,UAAAA,WAAA,CAAsBpF;4BACxC,IAAA,CAAKqF,qBAAA,CAAsBK,MAAM1F,YAAYmF;8BAC7C,IAAA,EAAA,CAAOO,OAAAA,GAAAA,CAAAA,mFAAAA,IAAAA,CAAAA,MAAAA,CAAAA,cAAAA,CAAAA,IAAAA;0BACT,kBAAA;;;;;;;gBAGE,IAAI,kBAAA;0CACFP,KAAax2B,OAAA;qCACf,EAAA,EAAA,aAAQ,CAAC;;gDADPw2B;gBAEJ,KAAA,GAAA;;;cAEAQ,KAAAA,YAAAA;uBAAAA,kBAAAA,KAAAA,aAAAA;oBACE,CAAA,GAAA,CAAK3D,GAAAA,WAAA,CAAA;oBACL,GAAA,CAAA,CAAKE,KAAAA,UAAA,GAAkB,IAAA,CAAKF,cAAA;oBAC5B,CAAA,GAAA,CAAKG,GAAAA,CAAAA,cAAAA,CAAAA,GAAA;oBACL,CAAA,GAAA,CAAKF,iBAAA,GAAoB19B,KAAKC,GAAA;gBAChC,OAAA,GAAA,IAAA,iBAAA,CAAA,CAAA,IAAA,CAAA,MAAA,CAAA,aAAA,EAAA;;;kBAEAohC,KAAAA;2BAAAA,sBAAAA,CAAAA,MAAAA,EAAAA;yBACE,IAAA,CAAK5D,MAAAA,CAAAA,OAAA,CAAA;sBACL,IAAA,CAAKE,eAAA,GAAkB,IAAA,CAAKF,cAAA;yBAC9B,eAAA;uBAAA,MAAA,OAAA,CAAA,SAAA;;;;gBAEA6D,GAAAA,EAAAA,CAAAA,IAAAA,gBAAAA,IAAAA,CAAAA,MAAAA,EAAAA,IAAAA,CAAAA,KAAAA,EAAAA;gCAAAA,EAAAA,oBAAAA;uBAAAA,MAAAA,kBAAAA;;iCACQC,mBAAN,IAAMA,MAAAA,QAAAA,KAAqB,IAAA,CAAKhB,yBAAA;yBAChC,IAAMiB,WAAAA,OAAkB,AACxB,IADwB,AACpB,CADyBd,GACzB,CAAKP,GACP,IACF,CAAA,EADSoB,aACT,CAH6B,CACpB,EAET,EAFsC,KAEtC,CAF4C,MAE5C,eAAA,GAAA,MAAA,MAAA,MAAA,CAAA,yBAAA;kBAEF;;;;;;;gBAEAE,KAAAA;uBAAAA,CAAAA,GAAAA,IAAAA,CAAAA,gBAAAA,IAAAA,CAAAA,KAAAA,EAAAA,CAAAA,CAAAA,IAAAA,CAAAA,MAAAA,CAAAA,aAAAA;oBACE,EAAA,EAAMC,CAAAA,IAAAA,QAAa,EAAA,EAAA,CAAKrmB,CAAAA,CAAAA,IAAA,CAAOsmB,CAAAA,EAAAA,IAAAA,CAAAA,KAAAA,EAAAA,IAAAA,CAAAA,GAAA,OAAA,EAAA,IAAA,CAAA,MAAA,EAAA;8BAC3B,GAAOD,gBAAX,IAAI,GAAOA;;;;;4BAAe,IAAA,CAAA,OAAYA,SAAAA,CAAAA,IAAc,GAAG;;;;;8CACrD,OAAOA,CAAAA;uBAAAA,MAAAA,UAAAA,CAAAA,WAAAA,CAAAA,QAAAA;;4CACT,mBAAA,qBAAA;uBAAA,MAAA,UAAA,CAAA,oCAAA,CAAA;;4BACA,CAAO,IAAA,cAAP;uBAAYtD,MAAAA,OAAAA,kBAAA;;kBACd,OAAA;uBAAA,MAAA,OAAA,CAAA,SAAA;;;;;;gBAEAwD,IAAAA,CAAAA,EAAAA,IAAAA,iCAAAA,SAAAA;oBACE,IAAMC,CAAAA,MAAAA,QAAe,IAAA,CAAKJ,0BAAA;oBAC1B,GAAA,CAAA,GACE,EAAA,EAAA,CAAKlB,yBAAA,KAA8BsB,gBACnC,IAAA,CAAKnB,4BAAA,KAAiCmB;yBAE1C,aAAA;uBAAA,MAAA,QAAA;;;;gBAAA,0BAAA;gBAIAC,KAAAA,OAAAA,wBAAAA;uBAAAA,MAAAA,cAAAA,CAAAA;;+CAAAA,IAAmBhiC,gBAAnBgiC,SAAAA;uBAAmBhiC,GAAA,GAAA,iCAAA;;iCACDA,qBAAAA;uBAAAA,MAAAA,SAAAA,CAAAA,mBAAAA;;gCAAVoU,iBAAN,IAAMA,OAAAA,CAAUpU,CAAAA,IAAAA,cAAAA;uBAAAA,MAAAA,kBAAAA,CAAAA,MAAAA,UAAAA,MAAOoU,OAAA,cAAPpU,qCAAAA,eAAgBoD,WAAA,OAAiB;;kBAEjD,IAAIgR,GACF,KADUxT,EACH,EACT,GAAA,CAFY,CAAS,UAGrB,IAAIwT,CAAAA,OAAQxT,CAHgCwT,OAGhC,CAHwCxT,AAG/B,AACnB,EAAA,KAAO,CAJ2C,CAAS,GAG5B,WAH0CwT,QAAQxT,QAAA,CAAS,WAAW;;;;+BAOrG,OAAO;;4BACT,CAAA,CAAA,MAAA,CAAA,aAAA;0BACA,IAAIwT,QAAQxT,QAAA,CAAS,sBAAsB;;;;8CACzC,OAAO,iBAAA;;4BACT,EAAA,EAAA;8BACA,CAAA,CAAA,KAAO;wBACT;;;sBAEAqhC,CAAAA,CAAAA,GAAAA,GAAAA,CAAAA,UAAAA,GAAAA;oBAAAA,YAAAA,IAAAA,CAAAA,MAAAA,CAAAA,UAAAA;gBAAAA,IAAAA,CAAAA,iCAAAA,IAAAA,oEAAAA,GAAAA,IAAAA;oBAAAA,WAAgBp7B,MAAAA,IAAA,CAAA,SAAA,CAAA,GAAA;gBAAA,IAAA,CAAA;0BAEd,IAAIq7B,eAAe,MAAM;;;;8CACvB,CAAA,MAAO,CAAA,EAAA,eAAA;0BACT,MAAA,IAAA,CAAA,QAAA,CAAA,gBAAA,CAAA;4BAEA,IAAMrX,IAAAA,CAAAA,KAAU3qB,KAAKC,GAAA,KAAQ+hC,WAC7B,IAAIrX,SACF,EADa,EACb,CAAK2T,CADQ,CAAKC,IAElB,OAAO,IACT,GAFO,AAEP,CAF4BjyB,MAAA,CADR,AACe3F,EADa,EAKhD,EAAA,CAAA,IAAO,KAAA;;;;;;sBAGTs7B,GAAAA,EAAAA;6BAAAA,SAAAA,wCAAAA;6BACE,IAAMhiC,MAAMD,KAAKC,GAAA;;2EAGb,IAAA,CAAKq+B,oBAAA,CAAqBhyB,MAAA,CAAO9L;;;;;gDAFrC,EAAA,EAAA,8BAAA,2BAAA;;gDAAA,QAAA,YAA+B,IAAA,CAAK89B,oBAAA,qBAApC,SAAA,6BAAA,QAAA,yBAAA,iCAA0D;;;;;;;;;;;gDACxD,CAAA,CAAA,EAAIr+B,MAAM8e,YAAAA,CAAa,IAAA,CAAKwf,0BAAA,EAA4B;;;;;;;;;;kDAExD;gDACF,wEAJA;;;;;;;yDAAA,EAAA,CAAA,0BAAA;0DAAA,CAAA,WAAA,IAAA,IAAA,CAAA,KAAA,CAAA,WAAA,IAAA;;;0DAAA;gEAAA;;;wCAKF,cAAA,IAAA,CAAA,SAAA;;6DAEA2D,KAAAA;+CAAAA,SAAAA,QAAAA;6CACE,MAAA,CAAOliC,KAAKC,GAAA,KAAQ,IAAA,CAAKy+B,CAAAA;2CAAAA,MAAAA,aAAA;;;;;;;oCAC3B,IAAA,CAAA,SAAA,CAAA,cAAA;;;;;;wCAEAyD,IAAAA,CAAAA,EAAAA,CAAAA,mDAAAA;iDAAAA,GAAAA,CAAAA,KAAAA,IAAAA,CAAAA,YAAAA;2EACE,IAAA,CAAK3D,wBAAA;4CAEL,IAAI,IAAA,CAAKA,wBAAA,IAA4B,IAAA,CAAKC,qBAAA,EAAuB;8CAC/D,IAAM2D,WAAW,IAAA,CAAK5D,wBAAA,GAA2B,IAAA,CAAKC,qBAAA;8CACtD,IAAM4D,GAAAA,OAAUnkC,KAAKE,GAAA,CACnB,IAAA,CAAKugC,yBAAA,GAA4BzgC,KAAKokC,GAAA,CAAI,GAAGF,WAC7C,IAAA,CAAKxD,wBAAA;8CAEP,EAAA,EAAA,CAAKF,CAAAA,CAAAA,cAAAA,CAAAA,QAAA,GAA4B1+B,KAAKC,GAAA,KAAQoiC;8CAE9C,IAAI,IAAA,CAAKpY,CAAAA,IAAA,EAAO;kDACd/oB,QAAQC,GAAA,CACN,6CAA2D,OAAdkhC,SAAO,QAAoC,OAA7B,IAAA,CAAK7D,wBAAwB,EAAA;;;;4CAG9F,EAAA,CAAA,QAAA;;;;;;0BACF;;;;;;;wBAEA+D,KAAAA,mBAWQtiC;;;yCAXRsiC;yCAAAA,KAAAA,CAAAA,GAAAA,iBAAAA,CAAAA,GAAAA,CAAAA,aAAAA;wCACE,IAAI,CAAA,CAAA,EAAA,CAAK/D,OAAAA,iBAAA,GAA2B,KAAK,IAAA,CAAKvU,KAAA,EAAO;;gDACnD/oB;wCAAQC,GAAA,CACN,SAAA;wCAAA,YAAA,IAAA,CAAA,QAAA,CAAA,aAAA;oCAAiF,OAA7B,IAAA,CAAKq9B,wBAAwB,EAAA;;wCAGrF,CAAA,GAAA,CAAKA,CAAAA,EAAAA,qBAAA,GAA2B;0CAChC,EAAA,EAAA,CAAKE,CACP,wBADO,GAA4B;;kCAG7B8D,KAAAA;uCAAN,SAAMA;;yCACEviC,IACA0qB,CAAAA,QAEE8X,yBAAAA,KAAAA,iDAAAA;;;;wDAHFxiC,MAAMD,KAAKC,GAAA;sDACX0qB,UAAU1qB,MAAM,IAAA,CAAK4+B,wBAAA;yDACvBlU,CAAAA,UAAU,IAAA,CAAKmU,sBAAA,GAAfnU;;;;;;;;8CACI8X,SAAS,IAAA,CAAK3D,sBAAA,GAAyBnU;;;;0CAC7C,IAAI,IAAA,CAAKV,KAAA,EAAO;;;gDACd/oB,QAAQC,GAAA,CAAI,wBAA8B,OAANshC,QAAM;4CAC5C;4CACA,CAAA,MAAA,CAAA,QAAA;;gDAAM,IAAIl2B,QAAQ,SAAAE;2DAAW0C,CAAAA,KAAAA,CAAAA,IAAW1C,CAAAA,EAAAA,IAAAA,CAAAA,CAASg2B,IAAAA,CAAAA,MAAAA;;;;iDAAjD,EAAA;;;4CAEF,IAAA,CAAK5D,wBAAA,GAA2B7+B,KAAKC,GAAA;;;;;;+BACvC,OAAA;;;;2BAAA,OAAA,CAAA,WAAA,CAAA;wBAIAyiC,KAAAA;+BAAAA,SAAAA,GAAAA,CAAAA,cAAAA,SAAAA,IAAuBC,KAAA;;gCAGH;4BAFlB,IAAA,CAAKC,KAAAA,GAAAA,cAAA;+BAEL,IAAM3a,GAAAA,CAAAA,MAAAA,IAAY,CAAA,CAAA,WAAA,sBAAA,IAAA,CAAK5M,MAAA,CAAOwnB,mBAAA,cAAZ,8CAAA,mCAAmC;4BACrD,IAAA,CAAKC,sBAAA,GAAyBH;4BAC9B,IAAA,CAAKI,UAAAA,CAAAA,QAAA,GAAsBj0B,GAAAA,IAAOK,CAAAA,SAAA,CAAW,OAAA;gCAC3C,GAAA,CAAI,EAAA,IAAK2zB,sBAAA,KAA2BH,OAAO;uCACzC,CAAA,aAAA,IAAA,MAAA,SAAA,CAAA,kBAAA,IAAA,CAAA,MAAA,QAAA,CAAA,WAAA,IAAA;qCACF,EAAA,EAAA;sCAEA,CAAA,KAAKI,IACL,MAAKD,SADA,GAAsB,KAAA,KACtB,GAAyB,+BAC9B,IAAI,EAAA,CAAA,GAAKtF,eAAAA,KAAA,KAAyBmF,OAAO;oCAEzC;kCAEA,MAAKK,EAAAA,MAAAA,GAAA,CAAW,CAAA,CAAA,WAAA,SAAsB;sCAAEL,EAAAA,MAAAA,KAAAA,CAAAA,MAAAA;yCAAO1a,CAAAA,MAAAA,KAAAA,IAAAA,CAAAA,kBAAAA;qCAAU,UAAA,GAAA;oCACzD,IAAA,EAAK0M,SAAA,CAAUsO,iBAAA;mCACjB,GAAGhb,CAAAA,CAAAA,IAAAA,GAAAA,KAAAA,CAAAA,kBAEH,IAAA,CAAK+a,UAAA,CAAW,+BAA+B;oCAAEL,OAAAA;kCAAO1a,WAAAA;4BAAU;wBACpE,EAAA,CAAA,gBAAA,CAAA,WAAA,IAAA,CAAA,cAAA;;;;;;wBAEA2a,CAAAA,IAAAA,KAAAA,CAAAA,YAAAA,EAAAA;iCAAAA,SAAAA;4BACE,IAAI,IAAA,CAAKG,mBAAA,IAAuB,MAAM;8BACpCh2B,CAAAA,IAAAA,CAAAA,KAAAA,CAAAA,CAAa,IAAA,CAAKg2B,EAAAA,iBAAmB;gCACrC,IAAA,CAAKA,aAAAA,MAAA,GAAsB,IAAA,CAAA,SAAA;8BAC7B;4BAEA,IAAI,IAAA,CAAKD,sBAAA,IAA0B,MAAM;gCACvC,IAAA,CAAKE,UAAA,CAAW,+BAA+B;kCAC7CL,OAAO,IAAA,CAAKG,sBAAA;;;8BACd,gDAAA;8BACA,IAAA,CAAKA,SAAAA,aAAA,GAAyB;0BAChC,oDAAA;;sCACF,KAAA,MAAA,EAAA,MAAA;;;4BAAA,EAAA,OAAA,IAAA,MAAA;4BAIAI,KAAAA,GAAAA,OAAAA,UAAAA;mCAAAA,MAAAA,GAAAA,IAAAA,eAAAA,EAAqBP,KAAA;;oCAGA,GAAA;gCAFnB,IAAA,CAAKQ,MAAAA,CAAAA,CAAAA,IAAAA,CAAAA,OAAA,CAAA,cAAA;8BAEL,IAAMC,cAAa,mCAAA,IAAA,CAAK/nB,MAAA,CAAOwnB,mBAAA,cAAZ,8CAAA,mCAAmC;4BACtD,IAAA,CAAK1F,eAAA,GAAkBwF;4BAEvB,GAAA,CAAA,CAAKU,GAAAA,SAAAA,KAAA,GAAoBv0B,OAAOK,UAAA,CAAW;wBA2BpC6zB;wBAF6B;kCAxBlC,EAAA,CAAA,CAAI,MAAK7F,EAAAA,EAAAA,WAAA,KAAoBwF,OAAO;wCAClC,UAAA,IAAA,MAAA;oCACF,YAAA,OAAA,eAAA,GAAA;sCAEA,KAAA,CAAKU,iBAAA,GAAoB,KAAA,IAAA,QAAA,gBAAA,IAAA,CAAA,MAAA,CAAA,yBAAA,EAAA;wCACzB,GAAA,CAAA,EAAKlG,eAAA,GAAkB,MAAA,CAAA;wCAEvB,GAAA,CAAI,MAAKK,oBAAA,GAAA,EAAyBmF,OAAO;4CACvC,EAAA,EAAA,EAAKnF,oBAAA,GAAuB;0CAC9B,EAAA,GAAA,IAEA,MAAKwF,UAAA,CAAW,yBAAyB,gCAAA,OAAA,eAAA,mBAAA,OAAA,IAAA,CAAA,MAAA,CAAA,yBAAA,IAAA;4CAEvCI,YAAAA;0CACAE,aAAa,MAAK/6B,KAAA,CAAMiD,MAAA;oCAC1B;oCAEA,MAAKmpB,SAAA,CAAU4O,iBAAA;8BACjB,GAAGH;8BAEH,IAAA,CAAKJ,EAAAA,CAAAA,OAAA,CAAW,mBAAA,EAAA,EAAuB;oCAAEL,CAAAA,MAAAA,qBAAAA,GAAAA;kCAAOS,UAAAA,CAAAA,CAAAA;gCAAW,GAAA,eAAA,IAAA,MAAA,cAAA,eAAA,GAAA,OAAA,eAAA;4BAC7D,OAAA,UAAA,IAAA,MAAA,cAAA,UAAA,GAAA,OAAA,UAAA;;;;;0BAEAD,KAAAA;+BAAAA,SAAAA,GAAAA,IAAAA,CAAAA,OAAAA,CAAAA,cAAAA,IAAAA,IAAAA,CAAAA,OAAAA,CAAAA,cAAAA,CAAAA,QAAAA,CAAAA,MAAAA,GAAAA;4BACE,IAAI,IAAA,CAAKE,OAAAA,UAAA,IAAqB,CAAA,IAAA,CAAM,MAAA,OAAA,eAAA,GAAA,MAAA,EAAA,+BAAA,IAAA,CAAA,OAAA,CAAA,cAAA,cAAA,mDAAA,6BAAA,MAAA,CAAA,eAAA,KAAA,OAAA,IAAA,CAAA,OAAA,CAAA,cAAA,CAAA,MAAA,CAAA,eAAA,GAAA,MAAA,KAAA;gCAClCt2B,KAAAA,QAAa,IAAA,CAAKs2B,SAAAA,QAAiB;gCACnC,IAAA,CAAKL,KAAAA,oCAAAA,IAAAA,CAAAA,CAAA,CAAW,IAAA,CAAA,kBAAuB,EAAA,cAAlCA,+CAAAA,oCAAkC;sCAAEL,OAAO,IAAA,CAAKxF,eAAA;oCAAgB,8CAAA;sCACrE,IAAA,CAAKkG,GAAAA,cAAA,GAAoB,KAAA;kCAC3B;kCAEA,EAAA,EAAA,CAAKlG,IAAAA,OAAAA,IAAA,GAAkB,GAAA,KAAA;gDACzB;;;0BAEA6F,KAAAA,OAAAA,gBAAAA;mCAAAA,GAAAA,EAAAA,IAAAA,WAAWtjC,KAAA;sCAAe8jC,CAAAA,OAAAA,iEAAiC,CAAC,GAAGlH,yDAAyBlG,0DAAqBqN;oCAEzG;gCACF,GAAA,CAAA,iBAAA;gCAEAviC,QAAQC,GAAA,CAAI,GAAA,CAAA,QAAA,QAAA,gBAAoC;kCAC9CzB,IAAAA,GAAAA,IAAAA,UAAAA,KAAAA,UAAAA;4BACAqf;uEAAAA,CAAAA,MAAW,CAAA,YAAA,GAAA,CAAA,GAAI/e,sFAAAA,MAAOkgB,WAAA;kCACtBujB,EAAAA,IAAAA,CAAA,EAASA,GAAAA,CAAAA,WAAAA,GAAAA,EAAAA,qBAAAA,UAAW;kCACpB1lC,SAAA,GAAA,OAAWu+B,CAAAA,IAAAA,CAAAA,MAAAA,CAAAA,QAAAA,KAAAA,0BAAAA,SAAUlvB,WAAA,yCAAiB;kCACtCgpB,IAAAA,KAAA,EAAWA,GAAAA,CAAAA,OAAAA,UAAAA,CAAAA,EAAAA,MAAAA,eAAAA,YAAa;oCACxBoH,EAAAA,EAAAA,kBAAsB,IAAA,CAAKA,oBAAA;qCACxBgG,EAAAA,CAAAA,yDAAAA;uCAEP;;;yCAAA,iCAAA;gCAIAE,KAAAA,MAAAA;qCAAAA,SAAAA;gCACE,IAAA,CAAKzE,gBAAA;gCACL,IAAA,CAAKM,CAAAA,KAAAA,WAAA;kCACL,EAAA,CAAA,CAAA,CAAKqD,GAAAA,EAAAA,iBAAA;oCACL,IAAA,CAAKO,EAAAA,CAAAA,gBAAA,kCAAA,OAAA,SAAA;kCACL,IAAA,CAAK3F,oBAAA,GAAuB;kCAC5B,IAAA,CAAK2C,CAAAA,wBAAA,CAAA,EAA4B,CAAA,IAAA;kCACjC,IAAA,CAAKC,IAAAA,CAAAA,uBAAAA,EAAA,CAAA,EAAiC,KAAA;kCACtC,IAAA,CAAKC,CAAAA,iBAAAA,CAAAA,MAAA,GAA4B,KAAA,GAAA;gCACjC,IAAA,CAAKhD,uBAAA,GAA0B;kCAC/B,EAAA,CAAA,CAAA,CAAKI,GAAAA,EAAAA,SAAA,GAAiB;oCACtB,IAAA,CAAKE,EAAAA,CAAAA,YAAA,GAAkB;kCACvB,IAAA,CAAKI,mBAAA,GAAsB;kCAC3B,IAAA,CAAKS,CAAAA,iBAAAA,MAAA,GAA2B;kCAChC,IAAA,CAAKlB,YAAA,CAAA,QAAA,QAAA;4BACP;;;8BAEAlzB,KAAAA,CAAAA,GAAAA,CAAAA;mCAAAA,SAAAA;gCACE,GAAA,CAAA,CAAK60B,gBAAA;gCACL,IAAA,CAAKM,UAAAA,CAAAA,MAAA,EAAA,QAAA;8BACL,IAAA,CAAK4D,oBAAA;8BACL,IAAA,CAAKP,sBAAA;wBACP;;;;;oBdusHF,IAAA,CAAA,MAAA,CAAA,eAAiC,cAAA;oBejsIpBe,IAAAA,CAAAA,IAAAA,CAAAA,QAAAA,CAAAA,WAAAA,CAAN,KAAA,IAAA,CAAA,MAAA,CAAA,oBAAA,KAAA,QAAA,IAAA,CAAA,OAAA,CAAA,cAAA,CAAA,MAAA,GAAA,KAAA,IAAA,CAAA,MAAA,CAAA,uBAAA,IAAA;6BAAMA,OAAAA,CAAAA,SAKCp7B,KAAA,EAAyB0hB,KAAA,UAAA;8CAL1B0Z;sBAMT,IAAA,CAAKp7B,KAAA,GAAQA;oBACb,IAAA,CAAK0hB,KAAA,GAAQA;;;;4BAGP2Z,IAAAA,CAAAA,KAAAA,EAAAA;qCAAAA,EAAAA,CAAAA,MAAAA;gCACN,IAAI,IAAA,CAAKl4B,SAAA,EAAW;kCAClB;4BACF,QAAA,IAAA,CAAA,MAAA,CAAA,gBAAA;4BAEA,IAAMtH,IAAAA,CAAKoE,GAAAA,CAAAA,KAASC,GAAAA,CAAAA,SAAA,CAAc,CAAA;4BAClCrE,GAAGsE,KAAA,CAAMC,EAAAA,IAAAA,CAAAA,CAAA,GAAW,GAAA,CAAA,cAAA,CAAA,MAAA,GAAA;8BACpBvE,GAAGsE,CAAAA,EAAAA,EAAA,CAAME,IAAA,GAAO;gCAChBxE,GAAGsE,CAAAA,IAAA,CAAMG,GAAA,GAAM,6CAAA;kCACfzE,GAAGsE,KAAA,CAAMiD,KAAA,GAAQ;kCACjBvH,GAAGsE,KAAA,CAAMkD,MAAA,GAAS;gDAClBxH,GAAGsE,KAAA,CAAM2C,OAAA,GAAU;kCACnBjH,GAAGsE,KAAA,CAAMmD,EAAAA,IAAAA,CAAAA,GAAA,GAAa,CAAA,oBAAA,KAAA;gCACtBzH,GAAGsE,KAAA,CAAMoD,cAAA,GAAiB;8BAC1B1H,GAAGsE,KAAA,CAAM4C,aAAA,GAAgB;8BACzBlH,CAAAA,CAAAA,CAAGsE,KAAA,CAAMqD,MAAA,GAAS,SAAA,GAAA,KAAA,GAAA;8BAClB3H,CAAAA,CAAAA,CAAGsE,KAAA,CAAMI,UAAAA,KAAA,GAAkB;8BAC3B1E,CAAAA,CAAAA,CAAGsE,KAAA,CAAMm7B,SAAAA,CAAA,GAAa;8BACtBz/B,GAAGsE,EAAAA,GAAA,CAAMoE,OAAA,GAAU;gCAEnB,IAAI,CAAC,CAAA,GAAA,CAAKvE,GAAAA,EAAA,CAAMyD,EAAAA,CAAAA,UAAA,EAAe,YAC7B,IAAI,IAAA,CAAKie,KAAA,EAAO;sCACd/oB,QAAQE,IAAA,CAAK;kCACf,kBAAA;kCACA;4BACF;0BAEA,IAAA,CAAKmH,KAAA,CAAMyD,aAAA,CAAcC,WAAA,CAAY7H;;;;0CACrC,IAAA,CAAKsH,MAAAA,EAAAA,CAAA,GAAYtH,EAAAA,EAAAA,UAAAA;wBACnB,IAAA,CAAA,SAAA,GAAA;;;wBAEA0/B,GAAAA,CAAAA,CAAAA,6BAAAA,GAAAA,IAAAA,CAAAA,MAAAA,CAAAA,gCAAAA,CAAAA;+BAAAA,SAAAA,cAAAA,CAAAA;;4BACE,IAAA,CAAKF,eAAA,SAAA;0BAEL,IAAI,CAAC,IAAA,CAAKl4B,SAAA,EAAW;;;;8CACnB;yDAWEq4B;4BAVJ,KAAA,CAAA,SAAA,EAAA;0BAEA,IAAI,CAAC,CAAA,GAAA,CAAKx7B,CAAAA,IAAA,CAAMS,GAAAA,CAAAA,CAAA,EAAO,QAAA;8BACrB,IAAA,CAAKT,GAAAA,EAAA,CAAMS,EAAAA,GAAA,GAAQ,YACnB,IAAI,IAAA,CAAKihB,KAAA,EAAO,gCACd/oB,IAAAA,CAAAA,GAAQC,GAAA,CAAI,eAAA,qGAAA;0BAEhB,iBAAA,IAAA,CAAA,MAAA,CAAA,qBAAA;0BAEA,IAAM4iC,OAAAA,KAAY,EAAA,EAAA,CAAKr4B,SAAA,CAAUhD,KAAA,CAAM2C,MAAAA,CAAA,KAAY,MAAA,IAAU,IAAA,CAAKK,SAAA,CAAUhD,IAAAA,CAAA,CAAMoE,EAAAA,KAAA,KAAY,aAAA;0BAC9F,IAAIi3B,QAAAA,wCAAAA,IAAW,CAAA,MAAA,CAAA,wBAAA,gBAAXA,mDAAAA,wCAAW,KAAA,GAAA;8BACb,EAAA,EAAA,CAAKr4B,EAAAA,GAAAA,CAAAA,GAAA,CAAUhD,IAAAA,CAAA,CAAMm7B,CAAAA,KAAAA,IAAA,GAAa;0BACpC,OAAO,SAAA,aAAA,YAAA;gCACL,IAAA,CAAKn4B,IAAAA,KAAA,CAAUhD,KAAA,CAAMm7B,UAAA,GAAa;8BACpC,CAAA,CAAA,uBAAA,CAAA;8BAEA,IAAA,CAAKn4B,SAAA,CAAUhD,KAAA,CAAMI,eAAA,GAAkB;4BACvC,IAAA,CAAK4C,SAAA,CAAUhD,KAAA,CAAM2C,OAAA,GAAU;4BAC/B,EAAA,EAAA,CAAKK,SAAA,CAAUs4B,YAAA;8BACf,CAAA,GAAA,CAAKt4B,IACL,IAAA,CADK,AACAA,CADUhD,KAAA,CAAMoE,EAChB,CAAUpE,IADM,CACN,CAAM4C,CADU,YACV,GAAgB,kBAAA,OAAA,WAAA;gCAGnC24B,sBAAsB;oCACpB,IAAI,MAAKv4B,SAAA,EAAW;0CAClB,IAAA,CAAA,CAAKA,SAAA,CAAUhD,KAAA,CAAMm7B,UAAA,GAAa,AACpC;gCACF;4BACF,CAAA,mBAAA;0BAEA,IAAI,IAAA,CAAK5Z,KAAA,EAAO;;;8BACd/oB,QAAQC,GAAA,CAAI,oCAAA;0BACd,CAAA;sBACF,wDAAA;;;;sBAEA+iC,KAAAA,KAAAA,IAAAA,CAAAA,QAAAA,CAAAA,sBAAAA,CAAAA,IAAAA,CAAAA,KAAAA,CAAAA,WAAAA,GAAAA;6BAAAA,EAAAA,CAAAA,MAAAA,EAAAA,CAAAA,sBAAAA,CAAAA;;4BACE,IAAI,CAAC,IAAA,CAAKx4B,CAAAA,GAAAA,KAAA,EAAW,EAAA,CAAA,EAAA,EAAA;kCACnB,IAAA,CAAA,EAAA;4BACF,GAAA,CAAA,QAAA,CAAA,aAAA,EAAA;8BAEA,IAAA,CAAKA,GAAAA,CAAAA,KAAA,CAAUhD,EAAAA,CAAAA,EAAA,CAAMoE,OAAA,GAAU;4BAC/BqC,WAAW;kCACT,EAAA,EAAI,MAAKzD,IAAAA,CAAAA,IAAA,EAAW;sCAClB,MAAKA,SAAA,CAAUhD,KAAA,CAAM2C,OAAA,GAAU;oCAC/B,MAAKK,SAAA,CAAUhD,KAAA,CAAM4C,aAAA,GAAgB;oCACrC,MAAKI,CAAAA,QAAA,CAAUhD,KAAA,CAAMI,eAAA,GAAkB;gCACzC,mBAAA,GAAA;0BACF,GAAG,SAAA,OAAA,eAAA,IAAA,OAAA,OAAA,eAAA,GAAA,MAAA,KAAA;0BAEH,IAAI,IAAA,CAAKmhB,CAAAA;oBAAAA,GAAA,CAAA,CAAO,kBAAA,CAAA,aAAA;iBAAA;gCACd/oB,QAAQC,GAAA,CAAI,EAAA;sCACd;sBACF,YAAA,KAAA,IAAA;oBAAA,sBAAA;gBAAA,IAAA,CAAA;;;0BAEAiJ,KAAAA,KAAAA,KAAAA,GAAAA;;4BACE,GAAA,CAAI,IAAA,CAAKsB,SAAA,EAAW,GAAA,GAAA;gCAClB,IAAI,IAAA,CAAKA,SAAA,CAAUM,KAAAA,GAAAA,KAAA,EAAe;kCAChC,EAAA,CAAA,CAAA,CAAKN,SAAA,CAAUM,aAAA,CAAckB,WAAA,CAAY,IAAA,CAAKxB,SAAS;gCACzD,UAAA,IAAA,MAAA,cAAA,eAAA,GAAA,OAAA,eAAA;gCACA,IAAA,CAAKA,IAAAA,KAAA,CAAA,EAAY,KAAA,OAAA,UAAA,GAAA,OAAA,UAAA;4BACnB,OAAA,KAAA,GAAA,cAAA,oBAAA,GAAA;wBACF,aAAA,IAAA,CAAA,MAAA,CAAA,UAAA,EAAA;oBAAA,QAAA;oBAAA,WAAA,aAAA,GAAA,IAAA,OAAA,WAAA;mBAAA,gBAAA,sBAAA,IAAA,CAAA,MAAA,GAAA,KAAA,CAAA;;;;gBfkrIF,sBAA0B;YgB7xI1B,EAAAhO,cAAgBX,QAAAU,QAAA,WAAA;;;YA6BT,EAAM0mC,0BAAN,sCAAA;uBAAMA,UAiBT9oB,MAAA,EACA9S,KAAA,EACA67B,UAAA,EACAC,MAAA,EACA1P,SAAA;0CArBSwP,oCAAAA;;kCAEX,IAAA,CAAA3oB,EAAAA,UAAA,GAAwB,CAAA;;oBACxB,CAAA,GAAA,CAAA8oB,CAAAA,QAAAA,CAAAA,GAAA,GAAyB,OAAA,MAAA,IAAA,CAAA,QAAA,CAAA,UAAA,CAAA,MAAA,KAAA,GAAA;oBACzB,IAAA,CAAAC,QAAAA,CAAAA,SAAA,EAAA,CAAoC,KAAA,IAAA,CAAA,OAAA,CAAA,SAAA,EAAA;oBAEpC,EAAA,CAAQC,KAAAA,gBAAA,CAAA,EAAgC;oBACxC,EAAA,CAAQC,WAAAA,IAAAA,CAAAA,QAAAA,CAAAA,GAAA,GAAwC,UAAA,CAAA;oBAChD,IAAA,CAAQC,QAAAA,iBAAA,GAAqC;sBAe3C,GAAA,CAAA,CAAKrpB,EAAAA,CAAAA,GAAA,GAASA,WAAAA,CAAAA,aAAAA,OAAAA,KAAAA,CAAAA,SAAAA;wBACd,IAAA,CAAK9S,KAAAA,CAAA,GAAQA,CAAAA,EAAAA;4BACb,EAAA,CAAK67B,KAAAA,IAAAA,CAAA,GAAaA,yDAAAA;wBAClB,IAAA,CAAKC,MAAA,GAASA;sBACd,IAAA,CAAK1P,SAAA,GAAYA;;;;;;;;wBAGP1K,CAAAA,CAAAA,GAAAA,KAAAA,CAAAA,aAAAA,MAAAA,IAAAA,CAAAA,QAAAA,CAAAA,UAAAA,CAAAA,MAAAA,KAAAA,GAAAA;6BAAZ,IAAA,CAAA,WAAA,MAAA,IAAA,CAAA,OAAA,CAAA,SAAA,EAAA;0BACE,OAAO,CAAC,CAAC,IAAA,CAAK5O,MAAA,CAAOE,CAAAA,CAAAA,IAAAA,CAAAA,KAAAA,CAAA,QAAA,IAAA,KAAA,KAAA,CAAA,IAAA,CAAA,KAAA,CAAA,QAAA,GAAA,OAAA;sBACvB,SAAA,IAAA,CAAA,QAAA,CAAA,UAAA,CAAA,IAAA;;;wBAEAopB,KAAAA,CAAAA;iCAAAA,SAAAA,KAAAA,CAAAA,UAAAA,GAAmBC,SAAAA,IAAA,CAAA,CAAA,SAAA;gCACjB,EAAA,GAAM5V,EAAAA,EAAAA,SAAa4V;kCACnB,EAAA,EAAI5V,EAAAA,CAAAA,YAAe,SAAS,wCAAA;oCAC1B,OAAO;8BACT;4BACA,IAAM6V,YAAY,IAAA,CAAKt8B,KAAA,CAAM2C,WAAA,CAAY;0BACzC,OAAO,CAAC,CAAE,CAAA,IAAA,CAAKmQ,MAAA,CAAO0O,cAAA,IAAkB8a,SAAA;;;;gCAC1C,cAAA,OAAA,EAAA,KAAA;;oDAEMC,KAAAA,wEAmBJ;;;;;;;;+CAnBIA,IAAAA,CAAAA,QAAAA,CAAAA,mBAAAA,CAAAA;+CAAN,KAAA,IAAMA,EAAAA;;;;8CAKgB,SAAA,kBAA6B,6BAGzCC,YAcA;;;;;;;oDArBR,CAAA,GAAA,CAAKT,aAAA,GAAgB,EAAA,CAAA;0DACrB,GAAA,CAAA,CAAKC,CAAAA,iBAAA,GAAqB,IAAA,CAAKlpB,MAAA,CAAOpa,GAAA;;;oDACtC,IAAA,CAAKsH,KAAA,CAAMtH,GAAA,GAAM,IAAA,CAAKoa,MAAA,CAAOpa,GAAA;oDAE7B,IAAA,CAAKua,YAAA,IAAe,4BAAA,IAAA,CAAKH,MAAA,CAAOG,YAAA,cAAZ,uCAAA,6BAA6B,8BAAA,IAAA,CAAKH,MAAA,CAAO/Q,cAAA,cAAZ,yCAAA,8BAA8B;0DAE/E,IAAI,IAAA,CAAK2f,KAAA,EAAO;8DACR8a,QAAAA,CAAAA,IAAa,CAAA,GAAA,CAAKvpB,CAAAA,CAAAA,KAAAA,EAAAA,GAAA,CAAA,CAAA,CACpB,IAAA,CAAA,MAAA,sCACA;8DACJta,QAAQC,GAAA,CACN,sDACA;kEACE6jC,QAAQ,IAAA,CAAKxpB,YAAA;kEACbuO,QAAAA,GAAAA,KAAgB,GAAA,CAAA,CAAK1O,MAAA,CAAO0O,cAAA;;;;;;;;;;;0DAE9B,GAAA,CAAA;;;;;;;;;;6DAIA,IAAA,CAAK1O,MAAA,CAAOqhB,QAAA,EAAZ;;;;0DACF,0CAAA;;;;;;;;;;;;;;;;0CAAA,oCAAA;;;;;;;;;;;;0BAEJ;;;;;;;;;;sCAEAuI,KAAAA;+BAAAA,IAAAA,CAAAA,IAAAA,KAAAA,IAAAA,IAAAA,CAAAA,QAAAA,CAAAA,WAAAA;;;;;0CACE,IAAA,CAAKC,GAAA,GAAM,IAAIC,YAAAj7B,OAAAA,CAAI;gCACjBG,GAAAA,CAAAA,OAAAA,GAAc;8BACd+6B,kBAAkB;;;;8CAClBC,sBAAsB;8BACtB/6B,CAAAA,MAAAA,CAAAA,GAAAA,CAAAA,IAAgB,CAAC,CAAC,IAAA,CAAK+Q,MAAA,CAAO/Q,cAAA;gCAC9Bg7B,CAAAA,YAAAA,IAAAA,QAAyB,CAAA,GAAA,CAAKjqB,MAAA,CAAO/Q,CAAAA,IAAAA,QAAAA,CAAA,GAAiB,MAAM,yBAAA;iCACxD,IAAA,CAAK+Q,MAAA,CAAO/Q,cAAA,GAAiB;gCAAEi7B,kBAAkB;4BAAE,IAAI,CAAC;8BAC5DC,iBAAiB;;;;8CACjBC,oBAAoB;oBAKL;8BAJfC,GAAAA,IAAAA,CAAAA,OAAe,KAAK,CAAA,KAAO;gCAC3BC,GAAAA,SAAAA,GAAe;;sEACfC,MAAAA,CAAAA,kBAAAA,CAA0B,8FAAA;gCAC1BC,aAAa;gCACbC,KAAAA,CAAAA,SAAe,KAAA,IAAA,GAAA,kCAAA,IAAA,CAAA,MAAA,CAAA,kBAAA,cAAA,6CAAA,kCAAA,MAAA;8BACfC,eAAe,CAAA;;;;;4BAGjB,IAAA,CAAKb,GAAA,CAAIz6B,CAAAA,CAAA,CAAG06B,UAAAA,EAAAj7B,OAAAA,CAAIQ,MAAA,CAAOs7B,cAAA,EAAgB;kCACrC;;;gCAAA,YAAA,MAAKd,GAAA,cAAL,gCAAA,UAAU36B,UAAA,CAAW,MAAK8Q,MAAA,CAAOpa,GAAG;;4BACtC,KAAA;0BAEA,IAAA,CAAKikC,GAAA,CAAIz6B,EAAA,CAAG06B,YAAAj7B,OAAAA,CAAIQ,MAAA,CAAOC,eAAA,EAAiB,SAAOs7B,GAAGC;;;;;wCAE9C,GAAA,CAAA,QAAA,EAAA,IAAA,CAAA,KAAA,SAYkB,oCAXjB,kBAAA,WAWGC,aAaI;;;;;;;8CA1BV,IAAA,CAAK3qB,YAAA,IACH,4BAAA,IAAA,CAAKH,MAAA,CAAOG,YAAA,cAAZ,uCAAA,qCACC,YAAA,IAAA,CAAK0pB,GAAA,cAAL,iCAAA,mBAAA,UAAUtkC,MAAA,cAAV,uCAAA,iBAAkBwlC,IAAA,CACjB,SAACzlC;;;;sEACCA,gBAAiCA;2DAAjCA,CAAAA,kBAAAA,6BAAAA,iBAAAA,MAAO0lC,OAAA,cAAP1lC,qCAAAA,eAAgB2lC,IAAA,MAAS,QAAQ3lC,CAAAA,kBAAAA,6BAAAA,kBAAAA,MAAO0lC,OAAA,cAAP1lC,sCAAAA,gBAAgBsC,IAAA,MAAS;uFACzD;;;;+DAEP;;kDAAM,IAAA,CAAK0xB,SAAA,CAAU4R,gBAAA,CAAiB,IAAA,CAAK/qB,YAAY;;;;;;8CAAvD;;;;qDAEA,IAAA,CAAKgpB,qBAAA,GAAwB;gDAC7B,CAAA,CAAA,EAAA,CAAKE,KAAAA,oBAAA,GAA4B;8CACjC,IAAA,CAAKD,4BAAA,GAA+B,CAAC,CAAC,IAAA,CAAKppB,MAAA,CAAOqhB,QAAA;;;;8DAE5CyJ,eAAc,qCAAA,IAAA,CAAK9qB,MAAA,CAAOmrB,qBAAA,cAAZ,gDAAA,qCAAqC;gDAEzD,IAAI,IAAA,CAAKvc,KAAA,EAAO;kDACd/oB,QAAQC,GAAA,CACN,uCACAglC,aACA;;;;qDAEJ;qDAEIA,CAAAA,EAAAA,IAAAA,CAAAA,KAAAA,IAAgB,KAAK,CAAC,IAAA,CAAK9qB,MAAA,CAAOqhB,QAAA,GAAlCyJ;;;;;;8CACF,IAAA,CAAKzB,yBAAA,EAAA,CAA4B;;mEAC7B,IAAA,CAAKrpB,MAAA,CAAOqhB,QAAA,EAAZ;;;;;gDACF;;uDAAM,UAAA,IAAA,CAAA,IAAA,IAAA,CAAKn0B,KAAA,CAAMqC,EAAAA,EAAA,gBAAX,uCAAA,iBAAmBC,KAAA,CAAM,YAAO;;;gDAAtC;;;;;;;;gCAGN,aAAA;;8CAEA,CAAA,kEAAA,CAAA,CAAKq6B,GAAA,CAAIz6B,CAAAA,CAAA,CAAG06B,YAAAj7B,OAAAA,CAAIQ,MAAA,CAAO+7B,YAAA,EAAc,SAACC,MAAM17B;gCAC1C,IAAI,MAAK2pB,CAAAA,EAAAA,MAAA,CAAU0B,WAAA,MAAiB,MAAK1B,SAAA,CAAUgS,iBAAA,IAAqB;sCACtE,KAAA,GAAA;kCACF,eAAA;gCAEA,IAAMN,UAAUr7B,iBAAAA,2BAAAA,KAAMq7B,OAAA;gCACtB,GAAA,CAAI,CAACA,WAAW,CAACA,QAAQO,SAAA,IAAaP,QAAQO,SAAA,CAAUhlC,MAAA,KAAW,GAAG;oCACpE,OAAA,GAAA,EAAA;gCACF,eAAA,GAAA;8BAEA,IAAMilC,kBAAkB3oC,KAAKE,GAAA,CAAI,GAAGioC,QAAQO,SAAA,CAAUhlC,MAAM;;;;;wBAI1D,IAAMklC,OAAAA,GAA6Bhb,iBAAAA,2BAAAA,KAAMgb,OAAA;wBAEzC,IAAI,CAACnnC,MAAMonC,OAAA,CAAQD,UAAU;4BAE7B,KAAA,6BAAA,2BAAA;;8BAAA,QAAA,YAAoBA,4BAApB,SAAA,6BAAA,QAAA,yBAAA,iCAA6B;kCAA7B,IAAW5uB,QAAX;kCACE,IAAIjB,MAAM;kCACV,IAAI9Z,QAAQ;kCAEZ,IAAIwC,MAAMonC,OAAA,CAAQ7uB,QAAQ;0CACXA,SACEA;sCADfjB,MAAMyL,QAAOxK,UAAAA,KAAA,CAAM,EAAC,cAAPA,qBAAAA,UAAY;sCACzB/a,QAAQulB,QAAOxK,WAAAA,KAAA,CAAM,EAAC,cAAPA,sBAAAA,WAAY;kCAC7B,OAAA,IAAW,OAAOA,UAAU,UAAU;sCACpC,IAAM8uB,MAAM9uB,MAAMsM,OAAA,CAAQ;oCAC1B,IAAIwiB,OAAO,GAAG;wCACZ/vB,MAAMiB,MAAMxQ,SAAA,CAAU,GAAGs/B;wCACzB7pC,QAAQ+a,MAAMxQ,SAAA,CAAUs/B,MAAM;oCAChC,CAAA,MAAO,OAAA,OAAA,CAAA,IAAA,+CACL/vB,MAAMiB;kCAEV,EADE,eAGF,IAAI,CAACjB,KAAK,+BAEV,IAAIA,IAAIvW,QAAA,CAAS,iBACf,GADmCuW,CAC7B6T,GADiCpqB,KACzBuW,GADyB,CAAS,AAC9BvW,QAAA,CAAS,WADyC,GAIpE,IAAMisB,GAFF9B,UAEe5T,IAAIvW,KAFAvD,GAEA,CAAS,KAD5B,CAAC,CAKL,IAAIwvB,SAHF,GAGc,aAHE7B,SAChBA,KAAA,AAGA,CAHM,GAGAwB,UAHY,KAAM,GAGApC,EAHA,kBAGoB/sB,KAC5C,IAAMiuB,SAAuB,mCAC3BnoB,MAAM,mCACFqpB,oBAAoB,KAAA,IAAY,qBAAEA,iBAAAA,wBAAgB,IAAI,CAAC,0CAC3DnG,KAAK,0CAAElP,KAAAA,2BAAK9Z,OAAAA,2BAAO8pC,gBAAgB,mBAAK,uCAG1C,IAAI,MAAKhd,KAAA,EAAO,yBACd/oB,MACF,EADUC,GAAA,CAAI,2CAGd,MAAKwzB,SAAA,CAAUiB,QAGf,GAHe,CAAYxK,QAAQ,CAvCzC,MAoC0GvS,EAOtG,CAPyG,SAIlG,MAAKurB,SAId,CAJc,CAAW9O,sBAAA,CAAuB,AAKlD,YAL8D,SAASxJ,mCAxCvE,wBAAA,uGAAA,6BAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kCAAA,aAAA,MAAA,EAAA;wCAAA,IAAA,MAAA,EAAA;;;;;;;;;QA8CF,mDAAA,aAAA,OAAA,CAAA,QAAA,CAAA,qBAAA,EAAA,oCAAA,aAAA;QACF,mDAAA,aAAA,OAAA,CAAA,QAAA,CAAA,iBAAA,WAAA,oCAAA,kBAAA;QAEYqZ,mDAAAA,aAAIz6B,GAAA,CAAOw8B,GAAAA,CAAAA,QAAAA,CAAA,EAAe,SAAOR,MAA7C,AAAmDR,IAAnD,CAAKhB,EAAOC,oCAAPD,EAAA,CAAIz6B,EAAA,CAAG06B,SAAAA,EAAAj7B,OAAAA,CAAIQ;;QAMM,mDAAA,aAAA,OAAA,CAAA,QAAA,CAAA,KAAdy7B,aAiBI,CAjBU,kDAAA;;;;;QALpB,oDAAA,aAASzB,OAAAA,CAAAA,QAAAA,CAAAA,EAAA,EAA2B,mBAApC,EAAI,IAAA,CAAKA,4CAAT,CAAA;QACE,oDAAA,aAAA,OAAA,CAAA,QAAA,CAAA,0BAAA,qDAAA,CAAA;;;QACF,oDAAA,aAAA,OAAA,CAAA,QAAA,CAAA,6BAAA,6CAAA,aAAA;QAEKF,oDAAAA,aAAAA,GAAA,IAAA,CAAA,QAAA,+BACC2B,EAAAA,OAAAA,MAAc,IAAA,GAAA,2BADf3B,GACe,IAAA,CAAKnpB,MAAA,CAAOmrB,qBAAA,WADhC,GACoB,CADpB,CAAKhC,IAAAA,0CACe,qCAAqC;yEAIrD,OAAA,CAAA,QAAA,2BAA0E2B,IAE9E,EAAA,CAFgD,IAAA,CAAK3B,CAErD,WAAA,GAAA,MAF0E,CAE1E,CAF0E,KAAe,IAEzF,GAF8E2B,AAE9E,8EAHEjlC,QAAQC,GAAA,CACN;;kCAKF,IAAA,CAAKujC,yBAAA,GAA4B;2CAE7B,IAAA,CAAKD,4BAAA,EAAL;;;;oCACF,IAAI,IAAA,CAAKxa,KAAA,EAAO;sCACd/oB,QAAQC,GAAA,CACN,oDAA8E,OAA1B,IAAA,CAAKqjC,qBAAqB,EAAA;kCAElF,YAAA,WAAA,EAAA;sCACA;;2CAAM,mBAAA,IAAA,CAAKj8B,KAAA,CAAMqC,IAAA,gBAAX,uCAAA,iBAAmBC,KAAA,CAAM,SAACiJ;8CAC9B,IAAI,MAAKmW,KAAA,EAAO;kDACd/oB,EAAAA,CAAAA,KAAQE,IAAA,CAAK,4CAA4C0S;gDAC3D,KAAA;8CACF;;;;;kBAJA;KAAA;;;;;;;;;;;oBAON;QAAA;KAAA;;kBAEA,IAAA,CAAKoxB,GAAA,CAAIz6B,EAAA,CAAG06B,EAAAA,OAAAA,GAAAj7B,OAAAA,CAAIQ,MAAA,CAAOy8B,qBAAA,EAAuB,SAACT,MAAM17B;oBACnD,IAAMo8B,CAAAA,KAAAA,CAAAA,GAAA,AAAyBp8B,CAAAA,CAAAA,KAAAA,YAAAA,2BAAAA,KAAMq8B,OAAA,KAAW,EAAC,EAAGplC,GAAA,CAAI,SAAC05B;+BAAY,CAAA,CAAA,UAAA,OAAA;4BACnE9+B,GAAAA,EAAK,GAAA,KAAA,CAAA,UAAA;qCACE8+B,UAAPx+B,KAAA,EAAOw+B,MAAAA,GAAAA,KAAAA,GAAAA,CAAAA,GAAAA,MAAAA,KAAG,OAAHA,SAAAA,EAAG3wB,IAAA,EAAA,QAAA,GAAA,QAAA,CAAA,GAAA;4BACVqhB,UAAA,EAAYsP,cAAAA,wBAAAA,EAAG2L,GAAA;sBACjB,IAAA;;wBACAF,CAAAA,OAAQ7mC,CAAAA,MAAA,CAAQ,CAAA,QAAC0W;mCAAQ,EAAA,IAAKswB,KAAAA,GAAA,CAAStwB,GAAAA,CAAAA,GAAAA,IAAAA,SAAAA,OAAAA,CAAAA,UAAAA,IAAAA,SAAAA,OAAAA,CAAAA,UAAAA,KAAAA,MAAAA,SAAAA,OAAAA,CAAAA,UAAAA,IAAAA;;;uDACzC,OAAA,CAAA,IAAA,iEAAA,mBAAA,KAAA,CAAA,SAAA;0BAEA,IAAA,CAAKiuB,CAAAA,EAAA,CAAIz6B,EAAA,CAAG06B,YAAAj7B,OAAAA,CAAIQ,MAAA,CAAO88B,WAAA,EAAa,GAAA,MAACd,MAAM17B;gCAGhCA;4BAFT,MAAKy8B,IAAAA,wBAAA,CACHz8B,iBAAAA,2BAAAA,KAAMnL,OAAA,EACN,QAAOmL,iBAAAA,4BAAAA,aAAAA,KAAM8gB,IAAA,cAAN9gB,iCAAAA,WAAYyqB,EAAA,MAAO,WAAWzqB,KAAK8gB,IAAA,CAAK2J,EAAA,GAAK,KAAA,GACpD5J,wBAAwB7gB,iBAAAA,2BAAAA,KAAM8gB,IAAI;sBAEtC,CAAA;wBAEA,IAAA,CAAKoZ,GAAA,CAAIz6B,EAAA,CAAG06B,OAGDn6B,KAHCd,OAAAA,CAAIQ,MAAA,CAAOg9B,cAAA,EAAgB,SAAChB,MAAM17B;sBAM9C;oBAEA,IAAA,CAAKk6B,GAAA,CAAIz6B,EAAA,CAAG06B,YAAAj7B,OAAAA,CAAIQ,MAAA,CAAOi9B,YAAA,EAAc,SAACjB,MAAM17B;0BAC1C,IAAM8gB,EAAAA,CAAAA,IAAO9gB,CAAAA,gBAAAA,2BAAAA,KAAM8gB,IAAA;0BACnB,IAAMgb,IAAAA,MAA6Bhb,iBAAAA,2BAAAA,KAAMgb,OAAA;wBACzC,IAAI,CAACnnC,MAAMonC,OAAA,CAAQD,UAAU;0BAC3B,MAAKnS,SAAA,CAAUiT,8BAAA,CAA+B9b;0BAC9C;oBACF;sBAEA,UAAA,wBAAA,2BAAA;;0BAAA,OAAA,CAAA,QAAA,IAAoBgb,GAAAA,CAAAA,GAAAA,IAAAA,SAAAA,OAAAA,CAApB,SAAA,CAAA,IAAA,SAAA,OAAA,CAAA,OAAA,GAAA,KAAA,MAAA,SAAA,OAAA,CAAA,EAAA,QAAA,IAAA,qBAA6B;gCAA7B,IAAW5uB,QAAX;;4DACE,GAAA,CAAIjB,mFAAAA,GAAM,EAAA,CAAA,SAAA;oCACV,IAAI9Z,QAAQ,6BAAA;kCACZ,IAAIwC,MAAMonC,OAAA,CAAQ7uB,QAAQ;0CACXA,SACEA;oCADfjB,MAAMyL,QAAOxK,UAAAA,KAAA,CAAM,EAAC,cAAPA,qBAAAA,UAAY;sCACzB/a,OACF,CADUulB,MACV,EADiBxK,EACN,OAAOA,EADDA,KAAA,CAAM,EAAC,AACI,UAAU,IADrBA,sBAAAA,WAAY;oCAG3B,IAAI8uB,OAAO,GAAG;sCACZ/vB,MAAMiB,MAAMxQ,SAAA,CAAU,GAAGs/B;oCACzB7pC,QAAQ+a,MAAMxQ,SAAA,CAAUs/B,MAAM;yDAChC,OAAO;sCACL/vB,KAAAA,CAAMiB,IAAAA,SAAAA,WAAAA;sCACN/a,CAAAA,OAAQ,cAAA;kCACV,GAAA,KAAA,IAAA;8BACF,EAAA,GAAA,CAAA,GAAA,KAAA,GAAA,CAAA,GAAA,SAAA,KAAA,KAAA;8BAEA,IAAI,CAAC8Z,EAAAA,GAAK;gCACV,IAAIA,CAAAA,GAAIvW,QAAA,CAAS,IAAA,WAAA,QAAuB,EAAA;sCACtC,IAAMmnC,EAAAA,GAAAA,EAAOtd,gBAAgBptB;oCAC7B,IAAMiuB,SAAuB;sCAC3BnoB,MAAM;qCACF4kC,CAAAA,iBAAAA,2BAAAA,KAAM7hC,QAAA,MAAa,KAAA,IACnB;oCAAEsmB,iBAAiBub,KAAK7hC,QAAA;yDAAS,IACjC,CAAC,GACD6hC,CAAAA,iBAAAA,2BAAAA,KAAMld,OAAA,MAAY,KAAA,IAClB;sCAAE0B,IAAAA,QAAYwb,IAAAA,CAAKld,OAAA;kCAAQ,GAAA,CAC3B,CAAC,CAAA,CAAA,GAAA,KAAA,GAAA,CAAA,GAAA;wCACLxE,KAAK;0CAAElP,KAAAA;wCAAK9Z,OAAAA;kCAAM,CAAA,kCAAA;;oCAEpB,KAAA,CAAKw3B,EAAAA,OAAA,CAAUiB,WAAA,CAAYxK,QAAQ,mBAC9B,MAAKgZ,UAAA,CAAW9O,sBAAA,CAAuB,YAAY,YAAYxJ;8BAEtE,OAAA,IAAW7U,IAAIvW,QAAA,CAAS,kBAAkB;kCACxC,IAAM4rB,kBAAkBpC,oBAAoB/sB;gCAC5C,IAAMiuB,UAAuB;4EAC3BnoB,IAAAA,EAAM,CAAA,QAAA,CAAA,cAAA,gBAAA,0BAAA,IAAA,WAAA,GAAA,QAAA,CAAA;iCACFqpB,OAAAA,aAAoB,KAAA,IAAY;kCAAEA,GAAAA,cAAAA,QAAAA,CAAAA,cAAAA,CAAAA,eAAAA,IAAAA;6BAAgB,EAAA,GAAI,CAAC,SAAA,OAAA,EAAA;8CAC3DnG,KAAK;mBAAA,GAAA,OAAA,MAAA,KAAA,OAAA,KAAA,CAAA,KAAA;WAAA,IAAA,CAAA;wCAAElP,KAAAA;0CAAK9Z,OAAAA;sCAAM;;kCAEpB,MAAKw3B,SAAA,CAAUiB,WAAA,CAAYxK,SAAQ,mBAC9B,MAAKgZ,UAAA,CAAW9O,sBAAA,CAAuB,YAAY,YAAYxJ;8BAEtE,OAAA,IAAW7U,IAAIvW,QAAA,CAAS,iBAAiB;kCACvC,MAAKi0B,SAAA,CAAUiB,WAAA,CACb;sCAAE3yB,MAAM;sCAAOkjB,KAAK;0CAAElP,KAAAA;wCAAK9Z,OAAAA;oCAAM;kCAAE,GACnC,MAAA,aACK,MAAKinC,UAAA,CAAW9O,sBAAA,CAAuB,YAAY,YAAYxJ;4BAGxE,KAAA,EAAA,IAAW7U,IAAIvW,QAAA,CAAS,oBAAoB;sCAMrBoqB;kCALrB,IAAMA,QAAQD,mBAAmB1tB;oCACjC,IAAMwvB,aACJ,gBAAgB7B,SAASA,KAAA,CAAM,aAAY,KAAM,KAAA;oCACnD,IAAM8B,YACJ,eAAe9B,SAASA,KAAA,CAAM,YAAW,KAAM,KAAA;oCACjD,IAAM+B,OACN,CADcnK,GACR1c,KADe8kB,MACJI,SADIJ,AACKA,KADL,AACK,CADC,AACK,QADE,GACS,WADtBA,0BAAAA,eAAkB;wCAIrC,IAAMM,UAAuB;0CAC3BnoB,MAAM;yCACF+C,aAAa,KAAA,IAAY;0CAAEsmB,iBAAiBtmB;wCAAS,IAAI,CAAC;0CAC9DmgB,KAAK;8CAAElP,KAAAA;gDAAK9Z,OAAAA;kDAAO2tB,OAAAA;qDAAM;wCAE3B,MAAK6J,SAAA,CAAUiB,WAAA,CAAYxK,SAAQ,mBAC9B,MAAKgZ,UAAA,CAAW9O,sBAAA,CAAuB,YAAY,YAAYxJ;kCAEtE;gCACA,IAAIc,WAAW;6CACb,MAAK+H,SAAA,CAAUiB,WAAA,CACb;4CAAE3yB,MAAM;0CAAOkjB,KAAK;8CAAElP,EAAAA,GAAAA;8CAAK9Z,OAAAA;8CAAO2tB,OAAAA,IAAAA,GAAAA;0CAAM,CAAA,cAAA,GAAA;sCAAE,GAC1C,YAAA,GAAA,IACK,MAAKsZ,UAAA,CAAW9O,sBAAA,CAAuB,YAAY,YAAYxJ;kCAGxE,IAAA,uBACF,GAAA;0BACF,WAAA,KAAA;0BA9EA,IAAA,KAAA,GAAA,IAAA,aAAA,GAAA;0BAAA,SAAA,KAAA;;mCAAA,KAAA,wBAAA,GAAA,CAAA;;;kCAAA,GAAA,QAAA,GAAA;wCAAA,SAAA,GAAA;;;0DA+EA,MAAK6I,OAAAA,EAAA,CAAUiT,8BAAA,CAA+B9b;kBAChD,WAAA,KAAA,GAAA,IAAA,YAAA,GAAA;gBAEA,IAAA,CAAKoZ,GAAA,CAAIz6B,EAAA,CAAG06B,YAAAj7B,OAAAA,CAAIQ,MAAA,CAAOI,KAAA,EAAO,SAAC47B,MAAM17B;sBACnC,GAAA,CAAIA,EAAAA,eAAAA,2BAAAA,KAAMC,KAAA,EAAO;0BACf,CAAA,MAAQD,KAAK/H,IAAA;8BACX,KAAKkiC,CAAAA,WAAAj7B,OAAAA,CAAI49B,KAAAA,KAAA,CAAWC,aAAA;wCAClB;qCAAA,YAAA,MAAK7C,GAAA,cAAL,gCAAA,UAAU8C,SAAA;sCACV,MACF,KAAK7C,YAAAj7B,OAAAA,CAAI49B,UAAA,CAAWG,WAAA;qCAClB,aAAA,MAAK/C,GAAA,cAAL,iCAAA,WAAUgD,iBAAA;oFACV;sCACF;oCACE,MAAKvT,MACL,GADK,CAAUwT,cAAA,uBAEnB;oBAEJ,KAAA;sEAEA,EAAA,CAAKjD,GAAA,CAAI16B,WAAA,CAAY,IAAA,CAAKjC,KAAK;cACjC;;;kBAEQg/B,KAAAA,OAAAA;gCAAAA,MACN,GADMA,CACF,OAAOtwB,CADIA,GAAA,AACAoV,UAAA,KAAe,UAAU;wBACtC,IAAA,CAAKgY,GAAAA,GAAA,CAAO3E,cAAA,CAAezoB,IAAIoV,UAAU;kBAC3C;;gBACA,IAAMjB;KAAAA,IAASa,mBAAmBhV;gBAClC,IAAImU,CAAAA,OAAQ,EAAA,EAAA;sBACV,CAAA,GAAA,CAAKuJ,GAAAA,EAAAA,IAAA,CAAUiB,WAAA,CAAYxK,QAAQ;0BACjCzmB,QAAQ;4BACR4wB,CAAAA,KAAAA,KAAW,UAAA,OAAA,CAAA,YAAA,EAAA;0BACb,OAAA,CAAA,YAAA,CAAA,QAAA,GAAA;oBACF;gBACF,UAAA,KAAA,KAAA,CAAA,UAAA,OAAA,CAAA,YAAA,IAAA;;;cAEQkS,GAAAA,EAAAA,KAAAA;uBAAAA,CAAAA,CAAAA,OAAAA,6BACNW,GAAAA,QAAA,EACA5S,UAAA,EACAG,oBAAA;;;gBAEA;QAAA,EAAM91B;KAAAA,MAAUmtB,yBAAyBob;gBACzC,IAAI,CAACvoC,SAAAA,AAAS,EAAA;sBACZ,CAAA,OAAA,EAAA;gBACF,YAAA;oBAEA,IAAM8vB,EAAAA,OAAAA,CAAUU,CAAAA,wBACdxwB,SACA,IAAA,CAAKukC,UAAA,CAAWtV,YAAA,EAChB,IAAA,CAAKsV,UAAA,CAAWjW,OAAA,EAChB,IAAA,CAAKiW,UAAA,CAAWrP,yBAAA;oBAGkB,2BAAA;oBADpCpF,QAAQpvB,OAAA,CAAQ,IAAA,KAAC6qB,KAAAA,OAAAA,CAAAA,YAAAA;wBACf,IAAM9P,UAA4B,KAAA,EAAA,oBAAA,SAAA,OAAA,cAAA,yCAAA,4BAAA,kBAAA,OAAA,cAAA,gDAAA,0BAAA,mBAAA,MAAA;4BAChC3W,EAAAA,MAAQ,eAAA;4BACR4wB,OAAAA,IAAW,MAAA,OAAA,CAAA,iBAAA;wBACb,OAAA,UAAA,OAAA,CAAA,kBAAA;wBACA,IAAIC,MAAAA,SAAe,CAAA,IAAA,GAAW,CAAA,gBAAA;4BAC5Bla,QAAQka,GAAAA,OAAA,GAAaA,KAAAA,GAAAA,CAAAA,GAAAA,KAAAA,IAAAA,CAAAA,cAAAA,QAAAA;0BACvB,EAAA,SAAA;4BACA,CAAA,GAAIG,IAAAA,KAAAA,WAAAA,KAAyB,KAAA,GAAW,IAAA,KAAA,gBAAA,KAAA,QAAA,KAAA,YAAA,KAAA,gBAAA,KAAA,kBAAA;kCACtCra,KAAAA,CAAAA,EAAQqa,GAAAA,OAAAA,EAAAA,QAAA,GAAuBA;gCACjC,cAAA;8BACA,MAAKhB,SAAA,CAAUiB,WAAA,CAAYxK,QAAQ9P;0BACrC,KAAA;4BAAA,SAAA;4BAAA,cAAA;4BAAA,UAAA;4BAAA,kBAAA;wBAAA;oBACF;;;gBAEA+sB,KAAAA;qBAAAA,SAAAA;oBACc,GAAA,YAAA,eAAA;kBAAZ;mBAAA,CAAMnkB,OAAM,MAAA,MAAA,IAAA,CAAKghB,GAAA,cAAL,gCAAA,UAAUoD,gBAAA;;gBACtB,OAAO,OAAOpkB,QAAQ,YAAYhc,OAAOC,QAAA,CAAS+b,OAAOA,MAAM,KAAA;YACjE,SAAA,SAAA,EAAA;;;gBAEA9Z,KAAAA,KAAAA,OAAAA,IAAAA,SAAAA,OAAAA,EAAAA;yBAAAA,EAAAA,OAAAA,GAAAA,OAAAA,CAAAA,MAAAA,KAAAA,YAAAA;4BACE,EAAA,OAAA,CAAA,MAAA;uBAAA,YAAA,IAAA,CAAK86B,GAAA,cAAL,gCAAA,UAAU96B,OAAA;oBACV,IAAA,CAAK86B,GAAA,GAAM,KAAA;gBACb,aAAA,OAAA,UAAA;;;;;;;IhBwrIF,GAAA,EAAA,sBAA+B;IiB3mJxB,CAAA,GAAA,CAASqD,YAAAA,KAAiBjM,IAAAA,EAAAA,EAAA;QAC/B,IAAA,CAAOA,SAASzuB,CAAAA,OAAAA,IAAAA,CAAAA,QAAA,CAAA,IAA0B,GAAA,CAAIyuB,CAAAA,QAASxuB,iBAAA;QACzD,IAAA,eAAA;YAEO,CAAS06B,GAAAA,QACdjgC,EAAAA,GAAA,EACA+zB,EAAAA,IAAAA,EAAA,EACArS,KAAA,OAAA,EAAA;gBAEIqS,OAASlvB,IAAAA,OAAA,GAAA,CAAe,MAAA,CAAA,OAAA;gBAC1B,EAAMq7B,WAAAA,CAAAA,IAAgB,CAACnM,IAAAA,KAASzuB,EAAAA,CAAAA,MAAAA,YAAA;gBAChC,EAAM66B,EAAAA,YAAgBpM,OAAAA,EAASxuB,OAAAA,OAAAA,CAAAA,EAAA,MAAuB,GAAA;gBAEtDwuB,OAAS5uB,QAAAA,SAAAA,OAAA,CAAyB+6B,YAAAA,GAAelgC,MAAMlK,MAAM,IAAA;gBAC7Di+B,IAAAA,CAASvuB,WAAA,CAAY06B,GAAAA,SAAAA,IAAgB,GAAA,CAAIC,QAAAA;gBAEzC,EAAIze,OAAO,GAAA,SAAA,iBAAA,gBAAA;kBACT/oB,EAAAA,IAAQC,GAAA,CACN,MAAA,UAAA,OAAA,CAAA,SAAA,uCACAsnC;gBAEJ,WACK,SAAA,eAAA,KAAA,GAAA,CAAA,GAAA,KAAA,GAAA,CAAA,GAAA,gBAAA;gBAELnM,IAAAA,CAAS5uB,WAAAA,SAAAA,IAAA,CAAyBnF,EAAAA,CAAAA,GAAMS,KAAA,EAAOT,EAAAA,IAAMlK,MAAM;gBAC3D,EAAI4rB,OAAO,OACT/oB,QAAQC,CAAAA,EAAA,CAAI,WAAA,YAAA,IAAA,OAAkCoH,KAAAA,CAAMS,KAAK;YAE7D;YACF,gBAEgB2/B,SAAAA,OACdpgC,KAAA,EACA0hB,GAAAA,EAAA,GAAA,WAAA,OAAA;UAGE,IAAI,CAACzhB,SAASogC,iBAAA,EAAmB;YAC/B,IAAMl9B,OAAAA,KAAYnD,MAAMyD,CAAAA,YAAA,EAAA;YACxB,IAAI,CAACN,WAAW,SAAA;oBACdc,OAAO,IAAI3K,GACX,GADiB,AACjB,iBAAA,KAAA,WAAA,OAAA;cAEF6J,UACGm9B,iBAAA,GACAzlB,IAAA,CAAK;kBACJ,IAAI6G,OAAO,IAAA,CAAA,oBAAA;sBACT/oB,QAAQC,GAAA,CAAI;oBACd,MAAA;oBACAsL,CAAAA,mBAAAA,GACF,GACC5B,KAAA,CAAM,SAACiJ,MACN,IAAImW,OAAO;kBAEX;gBACAzd,OAAOsH;YACT,SAAA,SAAA,EAAA;UACJ,EAAA,CAAA,IAAO,KAAA,OAAA,EAAA;YACLtL,SACG1E,cAAA,GACAsf,IAAA,CAAK;kBACJ,IAAI6G,GAAAA,IAAO,KAAA,OAAA;wBACT/oB,QAAQC,GAAA,CAAI;sBACd,KAAA,UAAA,GAAA,KAAA,OAAA,WAAA,GAAA,GAAA;wBACAsL,iBAAAA,OAAAA,UAAAA,GAAAA,OAAAA,WAAAA;kBACF,GACC5B,KAAA,CAAM,SAACiJ;sBACN,IAAImW,EAAAA,KAAO,OAAA;wBACT/oB,QAAQpB,KAAA,CACN,kDACAgU;oBAEJ,WAAA;oBAGN;sBAFMtH,EAAAA,GAAAA,CACF,CADSsH,2DAEb,oBAAA,SAAA,OAAA,cAAA,wCAAA,kBAAA,UAAA;YAEJ;QAEO,GAASg1B,QACdvgC,KAAA,EACA+zB,QAAA;QAEA,EAAIA,EAAAA,KAASlvB,WAAA,GAAA,CAAe;YAC1B,IAAA,GAAOkvB,SAASzuB,GAAAA,kBAAA;oBAGpB;gBAFE,QAAA,GAAA,CACOtF,KAAMS,KAAA,8CACf,oBAAA,SAAA,OAAA,cAAA,wCAAA,kBAAA,UAAA;YAQQjL,YAAYu+B,SAASlvB,WAAA;QAE3B,EAAIrP,aAAaiL,UAAUT,MAAMS,KAAA,EAAO;UACtC,EAAIihB,OAAO,WAAA;gBACT/oB,QAAQC,GAAA,CACN,GAAA,qEACA;oBAEJ;sBAFM6H,EAAAA,GAAAA,CAAM,CAANA,sDAEN,oBAAA,SAAA,OAAA,cAAA,wCAAA,kBAAA,UAAA;YAEF;QAEAT,IAAMS,KAAA,GAAQA;QAEd,EAAIjL,EAAAA,OAAW,SAAA;YACbu+B,SAAS5uB,IAAAA,oBAAA,CAAyB1E,OAAOT,MAAMlK,MAAM;YACrDi+B,IAAAA,KAASvuB,WAAA,CAAY/E,GAAAA,KAAQ,EAAA,EAAI;gBACjC,EAAIihB,OAAO,IAAA,oBAAA,OAAA;kBACT/oB,QAAQC,GAAA,CAAI,MAAA,OAAA,GAAA,sCAAsD;oBAChE6H,OAAAA;gBACF,WAAA;YACF,IAAA,eAAA;oBAIFszB;gBAHE,QAAA,GAAA,CACF,qDAEAA,oBAAAA,SAAS5uB,OAAAA,cAAT4uB,wCAAAA,CAAS5uB,iBAAAA,OAAA,CAAyB1E,EAAAA,EAC9BihB,GADqC1hB,AAC9B,MADoClK,MAAM;YAGrD;QACF;QAEO,GAAS0qC,CAAAA,OACdxgC,KAAA,EACA+zB,QAAA,CAAA,CACAj+B,MAAA,EACA4rB,KAAA;YAEM+e,aAAAA,GAAgB9qC,KAAKC,GAAA,CAAI,GAAGD,KAAKE,GAAA,CAAI,GAAGC;YACxCN,IAAAA,QAAYu+B,SAASlvB,GAAAA,OAAAA,CAAA,CAAA;gBAEvBrP,SAAW,IAAA,oBAAA,OAAA;gBACbu+B,OAASvuB,WAAA,CAAYi7B,CAAAA,OAAAA,GAAAA;YACrB1M,SAAS5uB,wBAAA,CAAyBs7B,kBAAkB,GAAGA;YACvD,IAAI/e,OAAO,IAAA;gBACT/oB,QAAQC,GAAA,CAAI,GAAA,oDAAuD;oBAGrE;sBAFI9C,EAAAA,GAAAA,CACF,EADU2qC,0DAEZ,oBAAA,SAAA,OAAA,cAAA,wCAAA,kBAAA,UAAA,EACK;YAELzgC,MAAMS,KAAA,GAAQggC,kBAAkB;UAChC1M,SAAS5uB,wBAAA,CAAyBs7B,kBAAkB,GAAGA;UACvD,EAAI/e,OAAO,SAAA;gBACT/oB,QAAQC,GAAA,CAAI,QAAA,OAAA,EAAA,4BAA6C6nC;gBAC3D,aAAA,oBAAA,OAAA;YACF;YACF,oBAAA,OAAA,GAAA,OAAA,UAAA,CAAA;gBAEgBC,SACd1gC,KAAA,CAAA,CACA+zB,QAAA;gBAEMv+B,IAAAA,MAAYu+B,SAASlvB,WAAA;wBAG3B;oBAFIrP,OAAW,CAAA,GAAA,CACb,CAAOu+B,SAASruB,WAAA,wDAClB,oBAAA,SAAA,OAAA,cAAA,wCAAA,kBAAA,UAAA,EACO1F,GAAMlK,MAAA;gBAGC6qC;YACd,GAAO,CAAC,CAAC1gC,SAASogC,iBAAA;YACpB,IAAA,eAAA;oBAQI1nC;gBANYioC,QAAAA,GAAAA,CACd5gC,AAII0hB,GAAO,EAJX,EACAqS,QAAA,EACArS,KAAA,+BAGE/oB,oBAAAA,SAAY,OAAA,cAAZA,wCAAAA,IAAQC,GAAA,CAAI,UAAA,UAAA,EACd;YAGE,IAAML,QAAQyH,MAAM6gC,WAAA,IAAe;UACnC,IAAM5nC,SAAS+G,MAAM8gC,YAAA,IAAgB;UAErC,EAAIpf,OAAO,SAAA;gBACT/oB,QAAQC,CAAAA,EAAA,CACN,mDAA4DK,OAATV,OAAK,KAAU,OAANU;YAEhE,IAAA,oBAAA,OAAA,EAAA;gBAEA86B,OAASjvB,MAAA,CAAOvM,OAAOU,YAAAA,OAAAA;gBACzB,oBAAA,OAAA,GAAA;YACF;YjB2jJA,eAAA,aAAoC;YkB9tJvB8nC,kBAAAA,cAAN;iBAAMA,cAAAA,MA4BTC,IAAA,EACAlF,MAAA,EACAmF,QAAA,EACApF,UAAA,EACAqF,WAAA;;4BA/BF,CAAArT,SADWkT,AACX,GAAY,wCACZ,CAAA7F,OAAA,qBAAA,EAAmB,KAAA,wEAAA,UAAA,EACnB,CAAAiG,oBAAA,GAAgC;YAGhC,IAAA,CAAQC,wBAAA,GAAoC;UAC5C,IAAA,CAAQC,0BAAA,GAA6B;UACrC,EAAA,CAAAC,aAAAA,CAAA,GAA2B,EAAC;gBACL,oBAAC,2BAAA;YAAxB,IAAA,AAAAC,CAAAA,QAAA,GAAuB,CAAA,CAAC,CAAD,qBAAA,UAAC,OAAA,cAAD,yCAAA,mBAAC,YAAA,OAAA,EAAA,oBAAA,SAAA,OAAA,cAAA,yCAAA,4BAAA,kBAAA,OAAA,cAAA,gDAAA,0BAAA,mBAAA,MAAA;YACxB,IAAA,CAAiBC,SAAAA,OAAAA,IAAAA,CAAAA,GAAA,GAAmC,MAAA;gBAEpD,EAAA,CAAAC,cAAA,CAAA,EAMW;YAgBT,IAAA,CAAKT,EAAAA,EAAA,GAAOA;gBACZ,EAAA,CAAKlF,MAAA,GAASA,MAAAA;YACd,IAAA,CAAKmF,QAAA,GAAWA;UAChB,IAAA,CAAKpF,UAAA,GAAaA;UAClB,EAAA,CAAKqF,WAAA,EAAA,CAAcA;;;;cAGTxf,KAAAA,WAAAA,CAAAA,aAAAA;mBAAZ,WAAA,CAAA,kBAAA;kBACE,OAAO,CAAC,CAAC,GAAA,CAAA,CAAKsf,IAAA,CAAKluB,MAAA,CAAOE,CAAAA,YAAA;cAC5B,gBAAA,CAAA,WAAA;;;cAEY0uB,KAAAA,WAAAA,CAAAA,WAAAA;mBAAZ,WAAA,CAAA,SAAA;kBACE,OAAO7uB,KAAAA,CAAAA,SAAAA,OAAsB,IAAA,CAAKmuB,IAAA,CAAKluB,MAAM;cAC/C,IAAA,MAAA,EAAA;;;cAAA,CAAA,iEAAA;gBAAA,oBAAA,GAAA,IAAA,EAAA;kBAAA,WAAA,oBAAA,OAAA,4BAAA;kBAAA,kBAAA,OAAA,GAAA;;;;;YAYQ6uB,GAAAA,GAAAA,mBAAAA,CAAAA,WAAAA;uBAAAA,SAAAA,KAAAA,CAAAA,WAAiBC,OAAAA,IAAA;oBACvB,IAAMC,YAAYlsC,CAAAA,CAAAA,GAAKE,GAAA,CACrB,IAAA,CAAKimC,MAAA,CAAO9D,yBAAA,IACZ,IAAA,CAAK8D,MAAA,CAAO3D,4BAAA;oBAEd,IAAM5E,aAAAA,CAAAA,IAAkBsO,OAAAA,KAAY,IAAIA,YAAY,KAAA;oBACpD,OAAO,IAAA,CAAKb,IAAA,CAAKxN,CAAAA,SAAAA,QAAA,CAAmBoO,aAAarO;gBACnD,EAAA,mBAAA,CAAA,SAAA;;;;;YAEAuO,KAAAA,IAAAA,SAAAA,EAAAA;qBAAAA,QAAAA,CAAAA;;;;gBACE,IAAM/N,CAAAA,SAAAA,CAAW,CAAA,GAAA,CAAKiN,IAAA,CAAKe,WAAA;kBAC3BhO,SAAS7xB,EAAA,CAAG,kBAAkB,SAAC5K;wBAC7B,MAAKwkC,GAAAA,GAAA,CAAOhD,GAAAA,EAAAA,WAAA;0BACZ,GAAA,CAAI,MAAKpX,KAAA,EAAO,GAAA,OAAA;;0BACd/oB,QAAQC,GAAA,ClBpGhB,AkBqGU,+BAAwBtB,CAAAA,oBAAAA,8BAAAA,QAASuG,KAAA,KAAS,OAAOvG,QAAQuG,KAAA,GAAQ,IAAI,KAAG,KAAyB,eAArBvG,oBAAAA,8BAAAA,QAAS4O,KAAA,uCAAS;oBAElG;cACF,YAAA,WAAA,IAAA,cAAA,WAAA,MAAA;cACA6tB,OAAAA,EAAS7xB,EAAA,CAAG,OAAA,WAAA,GAAqB,CAAA,UAAA,YAAA,GAAA,SAAA,MAAA,UAAA,YAAA,GAAA,UAAA,UAAA;WAC/B4W,SAAAA,IAAAA,GAAAA,CAAAA,GAAAA,cACE,KAAA,CAAKkoB,GAAAA,CAAA,CAAKluB,MAAA,CAAO7c,UAAA,EACjB,QAAA,EAAA;QAAA,UAAA;8BAAEmG,EAAAA,MAAQ,aAAA,GAAA,EAAA,SAAA;gBAAA,UAAA;sBA2EO4lC,SAAS,MAAKlG,MAAA,CAAO5G,cAAA;8BAAgB1e,EAAAA,SAAA,AAAW,UAAA,IAAA,EAAA,IAAI/e,OAAOkgB,CAAc,GAC1F,IAGF,EAHO+pB,CADuE,CAI1E,CAAC,MAAKV,IAAA,CAAKhhC,EAHR,EACLsC,CAEa,CAAM7B,GAFnB,CAAM,CAEa,EAAO,SAFb;8BAGb,MAAKugC,IAAA,CAAKhhC,KAAA,CAAMS,KAAA,GAAQ;6BACxB,IAAI,MAAKihB,EAAO,OAAPA,IAAA,EAAO,cAAA;kCACd/oB,QAAQC,GAAA,CAAI;8BACd;0BACF;4BAEA,CAAA,KAAKkjC,MAAA,CAAOlB,oBAAA;4BACZ,IAAA,EAAKkB,MAAA,CAAOzB,sBAAA;4BACZ,MAAKyB,EAAAA,IAAA,CAAO7G,oBAAA,GAAuB;4BACnC,EAAA,IAAKiG,OAAA,GAAU,EAAA,UAAA;4BAEf,IAAI,CAAC,MAAKrN,EAAAA,IAAAA,GAAA,EAAW;gCACnB,UAAA,IAAA,KAAA;4BACF,EAAA;4BAEA,MAAKiO,MAAA,CAAOtG,EAAAA,UAAAA,OAAA,GAAsB;4BAElC,MAAKsG,MAAA,CAAOpD,GAAAA,UAAAA,SAAA,CAAuB,MAAKsI,IAAA,CAAKe,WAAA;4BAC7C,GAAA,CAAMF,YAAY,GAAA,GAAK/F,MAAA,CAAO/C,gBAAA;4BAE9B,IAAI,CAAA,KAAKrX,KAAA,EAAO,IAAA,KAAA,IAAA;gCACd/oB,QAAQC,GAAA,CACN,EAAA,UAAA,0CAAiF,OAA3BipC,WAAS,mBAA4C,OAA1B,MAAKP,cAAA,CAAejoC,MAAM,GAC3G,MAAKioC,cAAA,CAAejoC,MAAA,GAAS,IAAI;oCAAE4oC,WAAAA,CAAa,SAAA,YAAG,MAAKX,cAAc;gCAAE,IAAI,CAAC,OAAA,SAAA,KAAA;4BAEjF,SAAA;4BAEA,IAAI,EAAA,IAAKxF,MAAA,CAAOzC,KAAAA,IAAAA,KAAAA,SAAA,IAA2B;gCACzC,MAAK6I,SAAAA,SAAAA,KAAAA,QAAA;wBACP,OAAO;0BAEP;wBACF,SAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EACF;;wBAEAC,WAAAA,CAAAA;2BAAAA,IAAAA,KAAAA;4BACE,EAAI,IAAA,CAAKzgB,EAAAA,GAAA,EAAO;8BACd/oB,KAAAA,GAAQC,GAAA,CAAI;4BACd,QAAA;4BAEA,EAAMwpC,QAAAA,gBAAwB,IAAA,CAAKvU,SAAA,IAAa,IAAA,CAAKqN,OAAA;4BACrD,EAAMnH,SAAAA,EAAW,IAAA,CAAKiN,IAAA,CAAKe,IAAAA,OAAA,EAAA;4BAC3B,EAAIK,SAAAA,gBAAyBrO,UAAU;8BACrC,IAAI,IAAA,CAAKrS,KAAA,CAAA,CAAO;kCACd/oB,OAAAA,CAAQC,GAAA,CAAI,WAAA,UAAA,KAAA;2BACd;4BAEAm7B,MAAAA,GAASpuB,eAAA,UAAA,YAAA,CAAA;yCACT,IAAA,CAAKw7B,oBAAA,GAAuB;iCAC9B;gCAEA,IAAMkB,sBAAsBtO,SAASzuB,qBAAA;uBACrC,CAAMg9B,uBAAuBvO,SAASxuB,iBAAA;kCAEtC,IAAIwuB,UAAU;;gCAGV,EAAA,EAAA,CAAKiN,IAAA,CAAKhhC,GAAAA,GAAA,CAAMS,CAAAA,CAAAA,EAAA,GAAQ,mBAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,IAAA,QAC1B,EAAA,OAASlJ,EACP,IAAI,CADU,GACV,CAAKmqB,KAAA,EAAO;oCACd/oB,QAAQE,IAAA,CAAK,8DAA8DtB;gCAC7E;8BACF,QAAA;4BACF,KAAA;4BAEA,EAAMyL,IAAAA,0BAA8B,IAAA,CAAKg+B,IAAA,CAAKuB,iCAAA;4BAC9C,EAAMC,SAAAA,KAAc,IAAA,CAAKxB,IAAA,CAAKyB,cAAA,CAAez/B;4BAC7C,EAAA,CAAKg+B,IAAA,CAAK0B,WAAA,CAAYF;4BAEtBA,OAAAA,GAAY,OAAAt/B,KAAAA,GAAAA,CAAAA,CAAA,GAAA,KAAA,kBAAA;4BACZs/B,QAAAA,CAAYr9B,EAAyBk9B,OAAzBl9B,KAAAA,GAAAA,CAAAA,IAAAA,KAAAA,KAAA,CAAyBk9B,YAAAA,UAAqBC;4BAC1D,EAAA,CAAKR,MAAAA,iBAAA;4BAEL,EAAIM,UAAAA,aAAuB;8BACzB,IAAA,CAAKlB,SAAAA,EAAA,CAAY3F,IAAA;8BACjBiH,SAAAA,GAAY78B,eAAA;8BACZ,IAAA,CAAKw7B,CAAAA,mBAAA,GAAuB;wBAC9B;wBACF,UAAA;+EAEAwB;gCAAAA,MAAAA,CAAAA;oCACM,CAAKC,SAAAA,MAAA,IAAmB,MAAM;oCAChCp+B,OAAAA,EAAa,IAAA,CAAKo+B,eAAe;oCACjC,CAAKA,aAAAA,EAAA,GAAkB,KAAA;oCACzB,QAAA;oCACKnB,WAAA,GAAiB,EAAA;oCACjB5F,OAAA,CAAWpP,UAAAA,SAAA,GAAsB,KAAA;oCACjCwU,KAAA,CAAS9R,KAAAA,gBAAA,GAAwB;gCACxC;;4BAMM0T,aAAAA,GAAAA,CAAAA,GAAAA,mBAAAA,GAAAA,EAAN,OANA,UAAA,gDAAA;gCAAA,OAAA,iDAAA;oCAMMA,OAAAA,IAAcC,OAAA;;oCACZC,WAMAC,GAAAA,GAEFpB,aAWEqB,mBAMExkC,MAmBFykC,cACAC,eAqBAC;;;;wCAlEAL,YAAY,IAAA,CAAK9B,QAAA,CAAStO,sBAAA,CAC9B,IAAA,CAAKqO,IAAA,CAAKhhC,KAAA,CAAMa,WAAA,GAAc;4CAG9B,IAAA,CAAKogC,QAAA,CAASlS,oBAAA,CAAqB9pB,GAAA,CAAI,IAAA,CAAKg8B,QAAA,CAASzO,aAAA,CAAcuQ;sCACrE;wCAKA,EAAA,AAAiB1pC,EAAb2pC,QAAQA,GAAAA,EAAK3pC,CAAAA,CAAAA,GAAAA,CAAA,GAAS,KAAK2pC,IAAA,CAAK,EAAC,EAAG,CAAA,IAAA,wBACtCpB,GACF,OAAA,IADgBoB,AACL,IADK,AACL,CADU,AACL/B,EADM,MACN,CAAShR,aAAA,EAAe;4CACtC2R,cAAc,IAAA,CAAKX,QAAA,CAAShR,aAAA;0CAC9B,OAAO;8CACL,IAAA,CAAK0S,mBAAA;8CACL;;;0CACF;0CAEMM,EAAAA,kBACJH,QAAQ/e,eAAA,IAAmB,OACvB+e,QAAQ/e,eAAA,GAAkB,MAC1Bgf,sBAAAA,gCAAAA,UAAW7P,UAAA;0CAEjB,IAAI,IAAA,CAAKxR,KAAA,EAAO;8CACRjjB,OAAO,IAAA,CAAKuiC,IAAA,CAAKluB,MAAA,CAAOG,YAAA,GAAe,SAAS;8CACtDta,QAAQC,GAAA,CACN,sBAAoDqqC,OAA9BxkC,MAAI,2BAA2C,OAAjBwkC,mBAAiB;0CAEzE;0CAEA,IAAA,CAAKnH,MAAA,CAAOhG,cAAA,CAAelxB,KAAA;0CAC3B,IAAA,CAAKk3B,MAAA,CAAO/F,oBAAA,CAAqBnxB,KAAA;0CACjC,IAAA,CAAKk3B,MAAA,CAAOtG,mBAAA,GAAsB;0CAClC,IAAA,CAAK4L,wBAAA,GAA2B;wCAChC,IAAA,CAAKD,oBAAA,GAAuB;wCAC5B,IAAA,CAAKrF,MAAA,CAAOzG,sBAAA,GAAyB;0CAErC,EAAA,CAAA,CAAI,EAAA,EAAA,CAAK4L,QAAA,CAAS9R,OAAAA,GAAAA,EAAAA,OAAAA;gCAAA,EAAuB,KAAA;oCAAA,UAAA;oCAAA,YAAA;oCAAA,cAAA;oCAAA,eAAA;gCAAA;gCAAA,UAAA;4BAAA;6CACvC,GAAA,EAAA,CAAK8R,QAAA,CAAS9R,OAAAA,IAAAA,EAAAA,OAAAA,CAAA;gCAAA,EAAwB,KAAA;oCAAA,UAAA;oCAAA,YAAA;oCAAA,OAAA;gCAAA;gCAAA,UAAA;gDACxC,OAAO;oDACL,CAAA,GAAA,CAAK8R,QAAA,CAAS5N,SAAAA,GAAAA,CAAA,CAAA,MAAA,CAAA;gDAChB;;wCAEM6P,eAAe,IAAA,CAAKlC,IAAA,CAAKhhC,KAAA,CAAMS,KAAA;wCAC/B0iC,gBAAgB,IAAA,CAAKnC,IAAA,CAAKhhC,KAAA,CAAMlK,MAAA;sCACtC,IAAA,CAAKkrC,IAAA,CAAKe,WAAA,GAAc58B,wBAAA,CAAyB+9B,cAAcC;wCAG/D,AAAYrO,IAAZ,CAAKgH,MAAA,CAAOhH,CAAAA,GAAAA,CAAAA,GAAAA,eAAA,GAA0B,CAAA,GAAA,oBACtC,IAAA,CAAKgH,EACL,IADK,AACL,CADY5G,AACP4G,MAAA,CAAO1G,OADA,GAAiB,KACjB,GAAkB;wCAC9B,IAAA,CAAKmM,UAAA;0CACL,IAAA,CAAKrG,OAAA,GAAU;iDAEf,IACE,IAAA,CAAKY,OAAA,CAAOlE,yBAAA,IAA6B,QACzCqL,qBAAqB,MACrB;qDACA,IAAA,CAAKnH,MAAA,EAAOlE,yBAAA,GAA4BqL;0CAC1C;0CAMkB;;8CAAM,IAAA,CAAKI,iBAAA,CAC3BzB,aACAqB,mBACAC,cACAC;;;wCAJIC,YAAY;kCAObA,WAAD,CAACA,CAAAA,GAAAA,CAAAA,GAAAA,GAAD,gBAAA,GAAA;;0CACF,EAAA,EAAI,IAAA,CAAK1hB,KAAA,EAAO;8CACd/oB,QAAQC,GAAA,CAAI;yCACd,GAAA,OAAA,IAAA,iBAAA,OAAA,OAAA,KAAA,iBAAA;0CACA,IAAA,CAAKwoC,wBAAA,GAA2B;0CAChC,GAAKkC,OAAL,CAAA,CAAKA,GAAAA,iBAAAA,IAAA,CAAwB1B;0CAC7B,EAAA;;8CAAM,CAAA,GAAA,CAAKM,+BAAA;;;uCAAX,KAAA,OAAA,KAAA,GAAA,CAAA,GAAA,SAAA,YAAA;;;;wBAEJ,SAAA;;;;4BAMcmB,MAAAA;6BANd,AAMA,UAAA,wDANA;4BAAA,QAAA,6BAAA;4BAAA,QAAA,oDAAA;4BAMA,GAAcA,SAAAA,SACZzB,WAAA,EACArO,eAAA,EACA2P,YAAA,EACAC,aAAA;;kCAEII,QAgBExP,UACAyP,oBAcazP,yBAAX0P,UAuCClsC;;;;0CArET,IAAI,IAAA,CAAKkqC,cAAA,IAAkB,IAAA,CAAKA,cAAA,CAAeiC,QAAA,CAASrqC,MAAA,GAAS,GAAG;8CAClEkqC,SAAS,IAAA,CAAK9B,cAAA,CAAeiC,QAAA,CAAS,EAAC;8CACvC,IAAA,CAAKf,mBAAA;0CACP,OAAO;4CACLY,SAAS,IAAA,CAAKvC,IAAA,CAAKxN,kBAAA,CAAmBoO,aAAarO;6DACrD;0CAEA,CAAA,CAAA,EAAI,CAACgQ,EAAAA,CAAAA,KAAQ,KAAA,GAAA;8CACX,GAAA,CAAA,SAAA,GAAA;;qEAAO;;0CACT,CAAA,CAAA,KAAA,CAAA,SAAA,GAAA;wCAEA,IAAA,CAAKnC,wBAAA,GAA2B;wCAEhC,IAAA,CAAKe,oBAAA;kCAECpO,MAAAA,OAAAA,IAAW,GAAA,CAAA,CAAKiN,IAAA,CAAKe,WAAA,CAAA,GAAA,gBACrByB,EAAAA,aAAe,EAAE,CACvB,GADuB,CAAK1H,AAC5B,CAAKA,KADuB,CAAO9G,AAC9B,CAAOC,oBADuB,AACvB,GAAuBuO;wCACnC,EAAA,CAAA,CAAA,CAAK1H,EAAAA,IAAA,CAAO3B,sBAAA,CAAuBqJ;;;;;;;8IAGjC;;4CAAM,IAAA,CAAK1H,MAAA,CAAO7B,sBAAA;;;0CAAlB;0CACA,IAAA,CAAK6B,MAAA,CAAO3G,iBAAA,GAAoB19B,KAAKC,GAAA;0CACrC;;8CAAMq8B,SAASpwB,UAAA,CAAW4/B;;;0CAA1B,CAAA,mBAAA,SAAA,OAAA,GAAA,SAAA;wCACA,IAAA,CAAKzH,MAAA,CAAOzB,sBAAA;wCAEZ,IAAI,IAAA,CAAKyB,MAAA,CAAO7G,oBAAA,KAAyBuO,cAAc;8CACrD,EAAA,mBAAA,IAAA,6BAAO;;0CACT;4CAEMC,oBAAW1P,0BAAAA,SAAShuB,aAAA,cAATguB,8CAAAA,6BAAAA,gDAA8B;4CAC/C,IAAI0P,WAAW,GAAG;gDAChB;;mDAAO,EAAA,OAAA,IAAA,iBAAA;;4CACT,EAAA;4CAEA,IAAI,IAAA,CAAK/hB,KAAA,EAAO;8CACd/oB,QAAQC,GAAA,CACN6qC,aAAa,IACT,6EACA,gCAAwC,OAARA,UAAQ;0CAEhD;8CAEA7qB,mBAAAA,GAAAA,gBACE,IAAA,CAAKooB,IAAA,CAAKluB,MAAA,CAAO7c,UAAA,EACjB;gDAAEmG,GAAAA,CAAAA,IAAQ,CAAA,CAAA,MAAA,GAAA;8CAAOunC,SAASJ;8CAAQ/sB,sBAAAA,UAAA,AAAW,aAAA,GAAA,IAAI/e,OAAOkgB,WAAA;4CAAc,GACtE,IAAA,CAAK+pB,KAAAA,CAAAA,MAAAA,GAAAA,CAAA,EACLp/B,KAAA,CAAM,YAAO;0CAEf,IAAA,CAAKw5B,MAAA,CAAOnB,oBAAA,CAAqB6I;0CACjC;0FAAMzP,SAAS1xB,IAAA;;8CAAf,QAAA;8CACA,GAAA,CAAA,CAAKy5B,MAAA,CAAOjD,aAAA;8CAEZ,IACE,IAAA,CAAKiD,MAAA,CAAOlE,yBAAA,IAA6B,QACzC,IAAA,CAAKkE,MAAA,CAAO5D,wBAAA,MAA8B,MAC1C;kDACA,EAAA,EAAA,CAAK4D,MAAA,CAAO/D,6BAAA;8CACd,UAAA,SAAA,OAAA,GAAA,YAAA;8CAEAhE,SAASvuB,GAAAA,QAAA,CAAY09B,eAAe,IAAIC;8CACxC,IAAA,CAAKrH,GAAOtG,OAAPsG,GAAA,CAAOtG,aAAAA,OAAA,GAAsB;8CAIlC,IAAA,CAAK4L,KAAAA,mBAAA,GAA2B;4CAChC,IAAA,CAAKkC,uBAAA,CAAwB1B;0CAE7B;gDAAO,CAAA,GAAA,CAAA,GAAA,mBAAA,GAAA;4CACArqC,OAAAA;4CACP,GAAA,CAAA,CAAKukC,MAAA,CAAOzB,sBAAA;8CACZ,IAAA,CAAKyB,GAAAA,GAAA,CAAOlB,oBAAA;8CACZ,GAAA,CAAI,IAAA,CAAKkB,MAAA,CAAO7G,oBAAA,KAAyBuO,cAAc;kDACrD,GAAYvO,OAAZ,CAAA,CAAK6G,MAAA,CAAO7G,QAAAA,aAAA,GAAuB;8CACrC,SAAA;8CACA,IAAI,CAAA,GAAA,CAAKvT,KAAA,EAAO;kDACd/oB,EAAAA,MAAQE,IAAA,CAAK,4CAA4CtB;8CAC3D,UAAA,SAAA,OAAA,GAAA,YAAA;8CAEA,IAAI,IAAA,CAAKukC,GAAAA,GAAA,CAAOvC,kBAAA,CAAmBhiC,QAAiB;kDAClD,IAAA,CAAKukC,MAAA,CAAO/F,oBAAA,CAAqB7+B,GAAA,CAAIqsC,QAAQ9rC,KAAKC,GAAA;8CACpD,UAAA;4CAEA,IAAA,CAAK0pC,wBAAA,GAA2B;0CAChC,IAAA,CAAKe,oBAAA;;4CACE;;;;;oCAEX,gBAAA;;;;gCAAA,UAAA,8CAAA;oCAAA,WAAA,EAAA,GAAA,CAAA,GAAA,mBAAA,IAAA,EAAA,OAMQmB,6CANR;wCAMQA,OAAAA,iBAAwB1B,WAAA;4CACpBR,SAAAA,WAAA,EAA0B;4CAClC,YAAA;4CACF,KAAA,GAAA,OAAA,IAAA,iBAAA;wCAESC,uBAAA,EAA4B;wCAC/B,CAAK3f,KAAA,EAAO,EAAA;4CACd/oB,EAAQC,GAAA,CAAI,OAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EACd,UACA;gDACF,WAAA;gDAEgB,SAAA;gDACF,OAAA;oDACd,SAAA,GAAA,OAAA,IAAA,iBAAA;oDAEKyoC,WAAA,GAA6B;oDAC7BuC,IAAA,CAAoBhC,KAAAA,GAAAA,OAAAA,KAAAA,iBAAAA;oDAC3B,WAAA,GAAA,OAAA,KAAA,iBAAA;;;gDAEcgC,UAAAA,YAAAA,aAAAA,GAAAA,CAAAA,GAAAA,mBAAAA,GAAAA,EAAAA,UAAAA,OAAAA,EAAAA;oDAAAA,MAAAA,KAAAA,GAAAA,CAAAA,IAAAA,KAAAA;gDAAAA,KAAAA,aAAAA,GAAAA,CAAAA,GAAAA,mBAAAA,GAAAA,EAAAA,UAAAA,MAAAA,EAAAA;oDAAAA,MAAAA,KAAAA,GAAAA,CAAAA,IAAAA,KAAAA;oDAAAA,OAAAA;wDAAAA,YAAAA;oDAAAA;gDAAAA;4CAAAA,gBAAoBhC,WAAA;oDAC1BiC,KAAAA,GAAAA,CAAAA,GAAAA,mBAAAA,IAAAA;;;wDAMEhC,QAAAA,GAiCAiC,cASAC,UAQEC,mBASFC;;;;;;8DA3DApC;2DAAAA,MAAYlsC,KAAKE,GAAA,CACrB,KAAA,CAAKimC,MAAA,CAAO9D,yBAAA,IACZ,MAAK8D,MAAA,CAAO3D,4BAAA;;8DAGd,IAAI0J,aAAa,MAAK/F,MAAA,CAAO5C,0BAAA,IAA8B;oEACzD,CAAA,GAAI,MAAKxX,KAAA,EAAO,MAAA,GAAA,oBACd/oB,MACF,EADUC,GAAA,CAAI,0DAA+G,OAArD,MAAKkjC,MAAA,CAAO9D,yBAAA,IAA2B,eAAwD,OAA1C,MAAK8D,MAAA,CAAO3D,4BAAA,IAA8B;oEAEvK;;0EAAA,OAAA,EAAA,UAAA,OAAA,CAAA,UAAA;;kEACF;gEAEA,IAAI,MAAK2D,MAAA,CAAOnC,eAAA,IAAmB;oEACjC,IAAI,MAAKjY,KAAA,EAAO;wEACF,SAAZ/oB,EAAAA,MAAQC,GAAA,CAAI,OAAA;sEACd,IAAA;sEACA,GAAA,OAAA,KAAA,iBAAA;;wEAAA;;gEACF,EAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,YAAA;4DAAA,MAAA,KAAA,GAAA,CAAA,IAAA,KAAA;wDAAA;8DAEA,IAAI,MAAKkjC,MAAA,CAAOtG,mBAAA,IAAuB,MAAKsG,MAAA,CAAOrG,sBAAA,EAAwB;wEAEvE98B,QAAQC,GAAA,CAAI,OAAA,GAAA,gBACd,OACA,oBAFkG,OAA/B,MAAKkjC,MAAA,CAAOtG,mBAAmB,EAAA;;0EAElG,YAAA,GAAA,OAAA,KAAA,iBAAA,QAAA;;kEACF,MAAA;kEAEA,GAAA,CAAI,MAAKsG,MAAA,CAAOzG,sBAAA,IAA0B,MAAKyG,MAAA,CAAOxG,0BAAA,EAA4B;sEAChF,EAAA,EAAI,MAAK5T,KAAA,EAAO;0EACd/oB,QAAQC,GAAA,CAAI,MAAA,GAAA,OAAA,IAAA,iBAAA,QAAA,gBAAyF,OAAtC,MAAKkjC,MAAA,CAAOxG,0BAA0B,EAAA;sEACvG,IAAA,mBAAA,GAAA,OAAA,IAAA,iBAAA,QAAA;oEACA;6HAAA;gEACF,GAAA;kEAEMwO,QAAAA,OAAe;uEACjB,GAAoBzqC,OAApB,IAAKioC,CAAAA,aAAA,CAAejoC,GAAAA,IAAA,IAAUyqC,YAAA,GAA9B;;;;gEACF,IAAI,MAAKpiB,KAAA,EAAO;yEACd/oB,iBAAAA,IAAAA,EAAQC,GAAA,CAAI,sCAAgE,OAA1B,MAAK0oC,cAAA,CAAejoC,MAAM,EAAA;kEAC9E,cAAA;kEACA,EAAA,KAAA,EAAA,aAAA;;wEAAM,EAAI2K,GAAAA,GAAAA,EAAQ,SAAAE,UAAAA;mFAAW0C,IAAAA,KAAAA,EAAW1C,CAAAA,CAAAA,GAAAA,IAAS,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,OAAA,GAAA,GAAA,IAAA,IAAA,GAAA,KAAA;;;;oEAAjD,SAAA,mBAAA,CAAA,WAAA;kEACA;;sEAAA,GAAA,gBAAA,CAAA,WAAA;;;gEAGI6/B,WAAW,MAAKpC,gBAAA,CAAiBC;qEAEnC,iBAAA,CAACmC,YAAY,MAAKjI,MAAA,CAAOhG,cAAA,CAAehyB,GAAA,CAAIigC,aAAa,MAAKjI,MAAA,CAAOtC,eAAA,CAAgBuK,SAAQ,GAA7F;;;;gEACF;;sEAAM,IAAI//B,GAAAA,GAAAA,CAAAA,AAAQ,GAAA,OAAAE,YAAAA,GAAAA,EAAAA,OAAAA;oEAAAA,OAAAA;wEAAAA,UAAAA;wEAAAA,OAAAA;wEAAAA,YAAAA;wEAAAA,cAAAA;oEAAAA;gEAAAA;gFAAW0C,IAAAA,QAAW1C,SAAS,EAAA,GAAA;;wEAAjD,UAAA;wEACA,KAAA;;wEAAA,QAAA;;;wEAGE,MAAKwd,KAAA,EAAO,CAAA;wEACRsiB,YAAAA,QAAoB,AAAC,qBAAG,MAAK1C,cAAA;0EAAgByC;;0EAG/C9B,GAAAA,GAAAA,CAAAA,GAAAA,EAAY+B,iBAAAA,GAAAA,MAAkB,GAEpC;oEAEA,IAAK1C,GAAAA,WAAA,CAAetlC,IAAA,CAAK+nC;wEAEnBE,UAAAA,IAAkB,MAAKnI,MAAA,CAAOtG,mBAAA,GAAsB,IACtD7/B,KAAKE,GAAA,CAAI,MAAOF,KAAKokC,GAAA,CAAI,GAAG,MAAK+B,MAAA,CAAOtG,mBAAmB,GAAG,OAC9D;wEACJ,KAAA;;wEAAM,IAAIxxB,OAAAA,CAAQ,SAAAE;mFAAW0C,WAAW1C,SAAS+/B;;;;wEAAjD,WAAA;;;;;wDACF;;mDAnEE,CAAA,IAAA,CAAK7C,wBAAA,IACL,IAAA,CAAKvT,SAAA,IACLgW,UAAU,IAAA,CAAK/H,MAAA,CAAO/G,YAAA;;;;;;;;;;;;;;;;;;;;;;oDAmExB,CAAKsM,UAAAA,gBAAA,GAA6B;iDAElC,CAAI,IAAA,CAAK3f,KAAA,EAAO;gDACd/oB,QAAQC,GAAA,CACN,yDAAmF,OAA1B,IAAA,CAAK0oC,cAAA,CAAejoC,MAAM,EAAA,MACnF,IAAA,CAAKioC,cAAA,CAAejoC,MAAA,GAAS,IAAI;gDAAuC,IAAI,CAAC;0CAEjF;;;4CACF,SAAA;;;;wCAEA6qC,UAAAA;4CAAAA,aAAAA,GAAAA,CAAAA,GAAAA,mBAAAA,IAAAA,EAAAA,OAAAA;gDAAAA,OAAAA;oDAAAA,UAAAA;oDAAAA,SAAAA,gBAAAA,MAAAA,SAAAA;gDAAAA;gDAAAA,UAAAA;oDACO9C,aAAA,GAA2B,CAAA,GAAA,mBAAA,IAAA,EAC3BC,UAEY1F,GAFZ,AAEY,GAFiB;wDAIlB,WAAA;wDACF,SAAA,SAAA;4DACd,iBAAA,CAAA;4DACF;;;4DAMMuG,SAAAA,GAAAA,OAAAA,IAAAA,iBAAAA,OAAAA,OAAAA,KAAAA,iBAAAA;4DAAN,cAAA,GAAA,OAAA,IAAA,iBAAA,UANA;4DAAA,UAAA,GAAA,OAAA,KAAA,iBAAA;4DAAA,YAAA,4BAAA;4DAMMA,YAAAA;;wDAeEiC,cACAC,cACAC,sBAEAC,sBAEEC;;;;4DApBH,GAAA,CAAK1W,SAAA,EAAW;yDACnB;;oDACF,iBAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAEMgW,MAAQ,CAEd,EAAI,CAFU,CAAK/H,EAEf,CAAKA,GAFU,CAAO/G,EAEjB,CAAOS,SAFU,UAEV,IAAuB,IAAA,CAAKsG,MAAA,CAAOrG,sBAAA,EAAwB;wDACzE,IAAI,GAAA,CAAA,CAAK/T,KAAA,EAAO;8DACd/oB,QAAQC,GAAA,CAAI,qDAAoF,OAA/B,IAAA,CAAKkjC,MAAA,CAAOtG,mBAAmB,EAAA;4DAClG,QAAA;4DACA,EAAA,CAAKgP,IAAAA,eAAA;4DACL,cAAA;;;4DACF,sBAAA;4DAEML,cAAoBxuC,KAAKokC,GAAA,CAAI,GAAG,IAAA,CAAK+B,MAAA,CAAOtG,mBAAmB;4DAC/D4O,QAAAA,CAAezuC,KAAKE,GAAA,CAAI,IAAA,CAAKimC,MAAA,CAAOnG,aAAA,GAAgBwO,mBAAmB,IAAA,CAAKrI,MAAA,CAAOlG,YAAY;4DAC/FyO,UAAAA,OAAuB,IAAA,CAAKvI,MAAA,CAAOpG,sBAAA,GAA0B,CAAA,IAAA,CAAKoG,MAAA,CAAOtG,mBAAA,GAAsB,IAAI4O,eAAe,CAAA;4DAElHE,UAAAA,OAAuB7sC,KAAKC,GAAA,KAAQ,IAAA,CAAKokC,MAAA,CAAO3G,iBAAA;4DAClDmP,WAAAA,YAAuBD,oBAAA,GAAvBC;;;;;;;;;;;;;gHACIC,KAAWF,KACb,EAAA,CAAK3iB,KAAA,EAAO,QADwB4iB;gEAEtC3rC,SAAY,SAAZA,IAAQC,GAAA,CAAI;2EAAA,yBAAA,aAAyF,OAA5C2rC,UAAQ,qCAAmE,OAA/B,IAAA,CAAKzI,MAAA,CAAOtG,mBAAmB,EAAA;;gEACtI,OAAA;oEACA,SAAA;;oEAAUxxB,MAAQ,GAAA,GAAAE,OAAA,GAAAA,CAAAA,iBAAAA,OAAAA,OAAAA,KAAAA,iBAAAA;yEAAW0C,OAAAA,IAAW1C,SAASqgC,IAAAA,QAAAA,8BAAAA;;;;oEAAjD,UAAA,GAAA,OAAA,KAAA,iBAAA;;;oEAGQ1W,SAAA,EAAA,EAAagW,UAAU,IAAA,CAAK/H,MAAA,CAAO/G,YAAA,EAAc;oEACzD,YAAA;;;oEACF,IAAA,iBAAA,OAAA;wEAEA,EAAA,MAAA,CAAA,KAAA,CAAA,UAAA,GAAA;;oEAAY0P,iBAAA,CAAmB;;;;wEACjC,EAAA,MAAA,CAAA,KAAA,CAAA,UAAA,GAAA;;;;gEAEcA,UAAAA;oEAAAA;oEAAmBC,wDAAqB;;4DAkC5CC,QAqBGptC,OACDqtC,cAiBJC;;;;gDAvEJ;kGACF;gDAEMhD,UAAY,CAAA,GAAA,CAAK/F,MAAA,CAAO/C,gBAAA;gDAE9B,SAAU+C,KAAA,CAAOzC,GAAjB,EAAI,CAAC,IAAA,CAAKyC,YAAO,IAA2B;oDAC1C,IAAI,IAAA,CAAKpa,KAAA,EAAO,QAAA;0DACd/oB,QAAQC,GAAA,CAAI,iDAA0D,OAATipC,WAAS;oDACxE,OAAA,IAAA,WAAA,OAAA,EAAA;wDACA,EAAA,CAAK2C,CAAAA,CAAAA,SAAAA,QAAA,SAAA,EAAA;4DACL,WAAA,OAAA,CAAA,iBAAA,GAAA,KAAA,CAAA;;4DACF,SAAA,cAAA,GAAA,KAAA,CAAA,YAEI,CAAK1I,MAAA,CAAOnC,eAAA,IAAmB;wDACjC,EAAI,IAAA,CAAKjY,KAAA,EAAO;wDACd/oB,QAAQC,GAAA,CAAI;oDACd;kDACA,IAAA,CAAK4rC,mBAAA;kDACL,KAAA;;;oDACF,UAAA,GAAA,OAAA,KAAA,iBAAA;oDAEI,IAAA,CAAK1I,MAAA,AAAOtG,UAAAA,KAAAA,YAAA,KAAuB,IAAA,CAAKsG,MAAA,CAAOrG,sBAAA,EAAwB;kDACzE,IAAI,IAAA,CAAK/T,KAAA,EAAO;sDACd/oB,CAAAA,OAAQC,GAAA,CAAI,KAAA,oBAAA,4BAAoF,OAA/B,IAAA,CAAKkjC,MAAA,CAAOtG,mBAAmB,EAAA;kDAClG,QAAA,gBAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,UAAA,UAAA,EAAA;oDAAA,MAAA,KAAA,GAAA,CAAA,IAAA,KAAA;gDAAA,KAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,UAAA,QAAA,EAAA;oDAAA,MAAA,KAAA,GAAA,CAAA,IAAA,KAAA;gDAAA;gDACA,IAAA,CAAKgP,mBAAA;;;0CAIP,IAAA,CAAK1I,MAAA,CAAOpC,wBAAA;;6CAEL,CAAA,IAAA,CAAK4H,cAAA,CAAejoC,MAAA,GAAS,CAAA;;;yFAC5BsrC,OAEN,IAAI,CAFc,AAEbA,IAFa,CAAKrD,MAEP,QAFO,CAAepY,KAAA;;;;6CAItB4M,UAAhB,EAAA,EAAI,IAAA,CAAKgG,MAAA,CAAOhG,GAAAA,YAAA,CAAehyB,GAAA,CAAI6gC,YAAY;oDAC7C,IAAI,IAAA,CAAKjjB,KAAA,EAAO/oB,QAAQC,GAAA,CAAI;oDAC5B;;;;gDACF;8CAEA,IAAI,IAAA,CAAKkjC,MAAA,CAAOtC,eAAA,CAAgBmL,YAAY;kDAC1C,IAAI,IAAA,CAAKjjB,KAAA,EAAO/oB,QAAQC,GAAA,CAAI;oDAC5B,CAAA,GAAA,mBAAA,GAAA;;kDACF,CAAA;kDAEA,EAAA,EAAI,IAAA,CAAK8oB,KAAA,EAAO;sDACd/oB,IAAAA,IAAQC,GAAA,CAAI,4DAA+F,OAAnC,IAAA,CAAKkjC,MAAA,CAAO5G,cAAA,GAAiB,GAAC,MAA+B,OAA1B,IAAA,CAAKoM,cAAA,CAAejoC,MAAM,EAAA;kDACvI,MAAA;;;;;;gDAGE;;sDAAM,EAAA,EAAA,CAAKyrC,YAAA,CAAaH;;;kDAAxB,CAAA;kDACA,IAAA,CAAK7I,CAAAA,KAAA,CAAOtG,mBAAA,GAAsB;;;;;8CAC3Bj+B;4CACDqtC,eAAgBrtC,MAAgBoU,OAAA;mDAGlCi5B,aAAazsC,GAAAA,IAAAA,CAAA,CAAS,+BAAtBysC;;8CACF;;+CAAW1C,YAAL,IAAA,CAAKA,YAAAA,oBAAA;;;gDAAX,GAAA,aAAA,WAAA;gDACA,aAAA,aAAA;;;;gDAGF,IAAI,CAAC0C,YAAAA,CAAazsC,QAAA,CAAS,QAAA,iBAAyB,CAACysC,aAAazsC,QAAA,CAAS,gBAAgB;oDACzF,IAAA,CAAK2jC,MAAA,CAAOtG,KAAAA,SAAAA,KAAA;8CACd;8CAEA;+FAAM,IAAA,CAAK0M,+BAAA;;kDAAX,GAAA;;;;;;gDAEF;;;;;;;;kDAGI2C,OAAAA,GAAAA,CAAAA,EAAa,CAAA,mBAAA,GAAA,WACf,CAAA,IAAA,CAAKzD,wBAAA,IAA4BsD,aAAaG,cAAchD,YAAY,GAAA,GAAxE;;;oDACF,IAAI,IAAA,CAAKngB,KAAA,EAAO,KAAA,EAAA,UAAA,OAAA,CAAA,UAAA;wHACd/oB,QAAQC,GAAA,CAAI,wDAA0EisC,OAAlBH,aAAa,GAAC,KAAc,OAAVG,YAAU;oDAClG;kDACA;;wDAAM,IAAI7gC,CAAAA,GAAQE,OAARF,IAAQ,SAAAE,QAAAA;mEAAW0C,WAAW1C,SAAS;;;;kDAAjD,KAAA,WAAA,WAAA;kDACA,QAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,YAAA;oDAAA,MAAA,KAAA,GAAA,CAAA,IAAA,KAAA;gDAAA;;mGAAA;kDACA,KAAA;;;;oDAGF,IAAI,CAAC,IAAA,CAAKi9B,oBAAA,IAAwBU,YAAY,KAAM;wDAClD,IAAA,CAAKkD,GAAAA,yBAAA;oDACP,OAAO,MAAA,mBAAA,GAAA,OAAA,IAAA,iBAAA,QAAA;wDACL,IAAI,IAAA,CAAKrjB,CAAAA,IAAA,EAAO/oB,QAAQC,GAAA,CAAI,CAAA,GAAA,OAAA,KAAA,iBAAA,QAAA;sDAC5B,IAAA,CAAK4rC,mBAAA;kDACP,QAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,IAAA;;;;wDACF,QAAA;;;;oDAMMM,aAAAA,SAAAA,YAAAA;wDAAN,EAAA,cAAA,iCANA;wDAAA,IAAA,KAAA,EAAA,aAAA;wDAAA,IAAA,OAAA,cAAA,4BAAA;4DAMmB1mC,IAAA,KAAA,GAAA,qBAAA;;wDA0BXolC,YAOEwB,IA8BGC,WAiBF1tC,OACDqtC;;;;wDAhFF7Q,OAAW,IAAA,CAAKiN,IAAA,CAAKe,WAAA;wDACvBhO,SAASlvB,WAAA,IAAe,CAAA,CAAA,aAAA;;;wDAExB,IAAA,CAAKi3B,MAAA,CAAOhG,OAAAA,KAAAA,EAAA,CAAehyB,CAAAA,EAAA,CAAI1F,KAAAA,GAAAA,CAAAA,GAAAA,CAAa,EAAA,OAAA,GAAA,EAAA,IAAA,IAAA,EAAA,KAAA;sDAC9C,IAAI,IAAA,CAAKsjB,KAAA,EAAO/oB,QAAQE,IAAA,CAAK,oDAAoDuF;6DAC3E,WAAN,MAAM,EAAI9E,MAAM;wDAClB,EAAA,eAAA;wDAEI,IAAA,AAAKwiC,CAAAA,GAAAA,CAAA,CAAOtC,aAAAA,CAAAA,CAAA,CAAgBp7B,aAAa,MAAA;wDAC3C,IAAI,IAAA,CAAKsjB,KAAA,EAAO/oB,GAAAA,KAAQE,GAAAA,CAAA,CAAK,EAAA,KAAA,GAAA,CAAA,GAAA,CAAA,EAAA,OAAA,GAAA,EAAA,IAAA,IAAA,EAAA,KAAA,aAAyDuF;sDACtF,MAAM,IAAI9E,MAAM;oDAClB,UAAA;wDAEI,IAAA,CAAKwiC,MAAA,CAAOtG,CAAAA,GAAAA,CAAAA,GAAAA,WAAA,IAAuB,IAAA,CAAKsG,EAAAA,EAAAA,EAAA,CAAOrG,IAAAA;4DAAAA,OAAAA;gEAAAA,OAAA,EAAwB,CAAA;gEAAA,OAAA;gEAAA,YAAA;gEAAA,cAAA;4DAAA;wDAAA;wDACzE,IAAI,IAAA,CAAK/T,IAAAA,CAAA,EAAO/oB,CAAAA,GAAAA,IAAQE,IAAA,CAAK,UAAA,GAAA,EAC7B,IAAM,GACR,CADYS,MAAM;4DAGd,CAAKwiC,MAAA,CAAOnC,eAAA,IAAmB;gEAC7B,EAAA,CAAKjY,KAAA,EAAO/oB,QAAQE,IAAA,CAAK;gEACvB,IAAIS,CAAAA,KAAM;gEAClB,MAAA;gEAEK6oC,QAAAA,OAAA;gEAECqB,KAAe,EAAE,GAAY,OAAZ,CAAA,CAAK1H,MAAA,CAAO9G,GAAAA,IAAAA,MAAAA,IAAAA;gEAC9B8G,CAAA,CAAO7G,UAAAA,UAAA,GAAuBuO;gEAC9B1H,CAAA,CAAO3B,YAAAA,UAAA,CAAuBqJ;;;;;;gEAGjC,UAAA;;gEAAW1H,KAAA,CAAO7B,GAAA,OAAAA,CAAAA,WAAAA,IAAAA,GAAA,GAAA,IAAA,KAAA;;;gEAAlB,QAAA;gEACK6B,CAAA,CAAO3G,UAAAA,OAAA,GAAoB19B,KAAKC,GAAA;gEACrBspC,IAAA,CAAKe,SAAAA,EAAA;gEACrB,WAAA;;4DAASp+B,SAAA,CAAWvF;;qDAApB;gDACAwa,qBACE,IAAA,CAAKooB,IAAA,CAAKluB,MAAA,CAAO7c,UAAA,EACjB;oDAAiB0tC,SAASvlC;gDAAgD,GAC1E,IAAA,CAAKsjC,gBAAA,EACLp/B,KAAA,CAAM,YAAO;8CAEf,IAAA,CAAKw5B,MAAA,CAAOzB,sBAAA;oGAIZ,IAAI,CAAC,IAAA,CAAKyB,MAAA,CAAOnD,wBAAA,CAAyBqM,KAAK;oDAC7C,IAAA,CAAKlJ,MAAA,CAAOoJ,yBAAA,CAA0BF;oDACtC,IAAA,CAAK7C,oBAAA;sDACL,MAAM,IAAI7oC,IAAAA,EAAM;oDAClB;;;;;;;kDAGE,IAAA,CAAKwiC,MAAA,CAAOnB,oBAAA,CAAqB6I;kDACjC;;oDAAMwB,GAAG3iC,IAAA;;;kDAAT,IAAA,GAAA,OAAA,KAAA,iBAAA;kDACA,IAAA,CAAKy5B,GAAO,OAAPA,GAAA,CAAOjD,CAAAA,YAAA,KAAA;kDAEZ,IAAI,EAAA,EAAA,CAAKiD,MAAA,CAAOlE,yBAAA,IAA6B,QAAQ,IAAA,CAAKkE,MAAA,CAAO5D,wBAAA,MAA8B,MAAM;oDACnG,IAAA,CAAK4D,MAAA,CAAO/D,6BAAA;gDACd,eAAA,oBAAA;gDAEAiN,EAAAA,CAAGx/B,WAAA,CAAYw6B,GAAAA,AAAiBgF,aAAjBhF,CAAiBgF,EAAAA,CAAAA,GAAAA,mBAAAA,GAAAA,EAAAA,UAAAA,UAAAA,EAAAA;4CAAAA,MAAAA,KAAAA,GAAAA,CAAAA,IAAAA,KAAAA;wCAAAA,KAAAA,aAAAA,GAAAA,CAAAA,GAAAA,mBAAAA,GAAAA,EAAAA,UAAAA,QAAAA,EAAAA;4CAAAA,MAAAA,KAAAA,GAAAA,CAAAA,IAAAA,KAAAA;wCAAAA;8CAChC,IAAA,CAAKlJ,MAAA,CAAOtG,mBAAA,GAAsB;;;;;oGAE3ByP,OACP,IAAI,IAAA,CAAKvjB,KAAA,EAAO/oB,QAAQpB,KAAA,CAAM,iCAAiC0tC;wCAE/D,IAAI,IAAA,CAAKnJ,MAAA,CAAOvC,kBAAA,CAAmB0L,YAAqB;4CACtD,IAAA,CAAKnJ,MAAA,CAAO/F,oBAAA,CAAqB7+B,GAAA,CAAIkH,YAAY3G,KAAKC,GAAA;8CACtD,IAAI,IAAA,CAAKgqB,KAAA,EAAO/oB,QAAQC,GAAA,CAAI;0CAC9B,OAAO;8CACL,IAAA,CAAKkjC,MAAA,CAAOhG,cAAA,CAAe7wB,GAAA,CAAI7G;8CAC/B,IAAI,IAAA,CAAKsjB,KAAA,EAAO/oB,QAAQC,GAAA,CAAI;0CAC9B;0CAEA,IAAA,CAAKkjC,MAAA,CAAOlB,oBAAA;0CACZ,IAAI,IAAA,CAAKkB,MAAA,CAAO7G,oBAAA,KAAyBuO,cAAc;4CACrD,IAAA,CAAK1H,MAAA,CAAO7G,oBAAA,GAAuB;sCACrC;;;;;;;;qCAGK19B,kIAAAA;;sCACDqtC,OAAAA,CAAAA,KAAAA,EAAgBrtC,CAAAA,kBAAAA,4BAAAA,MAAiBoU,OAAA,KAAW;wCAClD,IAAI,IAAA,CAAK+V,KAAA,EAAO/oB,QAAQpB,KAAA,CAAM,iCAAiCqtC;sCAE/D,IAAI,IAAA,CAAK9I,MAAA,CAAOvC,kBAAA,CAAmBhiC,QAAiB;wCAClD,IAAA,CAAKukC,MAAA,CAAO/F,oBAAA,CAAqB7+B,GAAA,CAAIkH,YAAY3G,KAAKC,GAAA;;;;;;;;;;;;;;;kCACtD,IAAI,IAAA,CAAKgqB,KAAA,EAAO/oB,QAAQC,GAAA,CAAI;kCAC9B,OAAO;sCACL,IAAA,CAAKkjC,MAAA,CAAOhG,cAAA,CAAe7wB,GAAA,CAAI7G;sCAC/B,IAAI,IAAA,CAAKsjB,KAAA,EAAO/oB,QAAQC,GAAA,CAAI,iDAAiDgsC;kCAC/E;kCAEA,IAAA,CAAK9I,MAAA,CAAOzB,sBAAA;kCACZ,IAAA,CAAKyB,MAAA,CAAOlB,oBAAA;kCACZ,IAAI,IAAA,CAAKkB,MAAA,CAAO7G,oBAAA,KAAyBuO,cAAc;sCACrD,IAAA,CAAK1H,MAAA,CAAO7G,oBAAA,GAAuB;kCACrC;kCACA,MAAM19B;;;;;;;;;;sBAEV;;;;;;;;;;;;;;;;;;cAMcwtC,KAAAA;qBANd,AAMA,kEANA;cAAA,oBAAA;YAAA,kEAAA;;;6BAMcA,+IAAAA;gBAAd,MAAcA;;gCACNlD,WACA0C,UA0BAY,eACAC,WAEG90B,GAkBCq0B,WAaGptC,OACDqtC;;;;;;;;;;;;;yBA/Dd;;;;;8BACQ/C,YAAY,IAAA,CAAK/F,MAAA,CAAO/C,gBAAA;gCAG9B,IAAI,IAAA,CAAK+C,MAAA,CAAOnC,aAAAA,EAAA,IAAmB;oCACjC,IAAI,IAAA,CAAKjY,KAAA,EAAO/oB,QAAQC,GAAA,CAAI;sEAC5B,IAAA,CAAK4rC,mBAAA;qCACL","sourcesContent":["\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n  for (var name in all)\n    __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n  if (from && typeof from === \"object\" || typeof from === \"function\") {\n    for (let key of __getOwnPropNames(from))\n      if (!__hasOwnProp.call(to, key) && key !== except)\n        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n  }\n  return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n  // If the importer is in node compatibility mode or this is not an ESM\n  // file that has been converted to a CommonJS file using a Babel-\n  // compatible transform (i.e. \"__esModule\" has not been set), then set\n  // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n  isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n  mod\n));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/ui/StormcloudVideoPlayer.tsx\nvar StormcloudVideoPlayer_exports = {};\n__export(StormcloudVideoPlayer_exports, {\n  StormcloudVideoPlayerComponent: () => StormcloudVideoPlayerComponent\n});\nmodule.exports = __toCommonJS(StormcloudVideoPlayer_exports);\nvar import_react = __toESM(require(\"react\"), 1);\n\n// src/sdk/hlsAdPlayer.ts\nvar import_hls = __toESM(require(\"hls.js\"), 1);\nvar MAX_VAST_WRAPPER_DEPTH = 5;\nfunction createHlsAdPlayer(contentVideo, options) {\n  let adPlaying = false;\n  let originalMutedState = false;\n  let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n  const listeners = /* @__PURE__ */ new Map();\n  const licenseKey = options?.licenseKey;\n  const mainHlsInstance = options?.mainHlsInstance;\n  let adVideoElement;\n  let adHls;\n  let adContainerEl;\n  let currentAd;\n  let podAds = [];\n  let podIndex = 0;\n  let sessionId;\n  const preloadedAds = /* @__PURE__ */ new Map();\n  const preloadingAds = /* @__PURE__ */ new Map();\n  let destroyed = false;\n  let pendingTimeouts = [];\n  let trackingFired = {\n    impression: false,\n    start: false,\n    firstQuartile: false,\n    midpoint: false,\n    thirdQuartile: false,\n    complete: false\n  };\n  function emit(event, payload) {\n    const set = listeners.get(event);\n    if (!set) return;\n    for (const fn of Array.from(set)) {\n      try {\n        fn(payload);\n      } catch (error) {\n        console.warn(\n          `[HlsAdPlayer] Error in event listener for ${event}:`,\n          error\n        );\n      }\n    }\n  }\n  function generateSessionId() {\n    return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n  }\n  function fireTrackingPixels(urls) {\n    if (!urls || urls.length === 0) return;\n    urls.forEach((url) => {\n      try {\n        let trackingUrl = url;\n        if (sessionId) {\n          trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}session_id=${sessionId}`;\n        }\n        if (licenseKey) {\n          trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}license_key=${licenseKey}`;\n        }\n        const img = new Image(1, 1);\n        img.src = trackingUrl;\n        console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n      } catch (error) {\n        console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n      }\n    });\n  }\n  function getMainStreamQuality() {\n    if (!mainHlsInstance || !mainHlsInstance.levels) {\n      return null;\n    }\n    const currentLevel = mainHlsInstance.currentLevel;\n    if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n      const autoLevel = mainHlsInstance.loadLevel;\n      if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n        const level2 = mainHlsInstance.levels[autoLevel];\n        return {\n          width: level2.width || 1920,\n          height: level2.height || 1080,\n          bitrate: level2.bitrate || 5e6\n        };\n      }\n      return null;\n    }\n    const level = mainHlsInstance.levels[currentLevel];\n    return {\n      width: level.width || 1920,\n      height: level.height || 1080,\n      bitrate: level.bitrate || 5e6\n    };\n  }\n  function selectBestMediaFile(mediaFiles) {\n    if (mediaFiles.length === 0) {\n      throw new Error(\"No media files available\");\n    }\n    const firstFile = mediaFiles[0];\n    if (!firstFile) {\n      throw new Error(\"No media files available\");\n    }\n    if (mediaFiles.length === 1) {\n      return firstFile;\n    }\n    const mainQuality = getMainStreamQuality();\n    if (!mainQuality) {\n      console.log(\n        \"[HlsAdPlayer] No main stream quality info, using first media file\"\n      );\n      return firstFile;\n    }\n    console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\n    const scoredFiles = mediaFiles.map((file) => {\n      const widthDiff = Math.abs(file.width - mainQuality.width);\n      const heightDiff = Math.abs(file.height - mainQuality.height);\n      const resolutionDiff = widthDiff + heightDiff;\n      const fileBitrate = (file.bitrate || 5e3) * 1e3;\n      const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n      const score = resolutionDiff * 2 + bitrateDiff / 1e3;\n      return { file, score, resolutionDiff, bitrateDiff };\n    });\n    scoredFiles.sort((a, b) => a.score - b.score);\n    const bestMatch = scoredFiles[0];\n    if (!bestMatch) {\n      console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n      return firstFile;\n    }\n    console.log(\"[HlsAdPlayer] Selected media file:\", {\n      url: bestMatch.file.url,\n      resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n      bitrate: bestMatch.file.bitrate,\n      score: bestMatch.score,\n      resolutionDiff: bestMatch.resolutionDiff,\n      bitrateDiff: bestMatch.bitrateDiff\n    });\n    return bestMatch.file;\n  }\n  function isHlsMediaFile(mediaFile) {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return type === \"application/x-mpegurl\" || type === \"application/vnd.apple.mpegurl\" || type.includes(\"mpegurl\") || url.includes(\".m3u8\");\n  }\n  function isProgressiveMediaFile(mediaFile) {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return type.startsWith(\"video/\") || url.endsWith(\".mp4\") || url.includes(\".mp4?\");\n  }\n  function createEmptyTrackingUrls() {\n    return {\n      impression: [],\n      start: [],\n      firstQuartile: [],\n      midpoint: [],\n      thirdQuartile: [],\n      complete: [],\n      mute: [],\n      unmute: [],\n      pause: [],\n      resume: [],\n      fullscreen: [],\n      exitFullscreen: [],\n      skip: [],\n      error: []\n    };\n  }\n  function extractTrackingUrls(scope) {\n    const trackingUrls = createEmptyTrackingUrls();\n    scope.querySelectorAll(\"Impression\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.impression.push(url);\n    });\n    scope.querySelectorAll(\"Tracking\").forEach((el) => {\n      const event = el.getAttribute(\"event\");\n      const url = el.textContent?.trim();\n      if (event && url) {\n        const eventKey = event;\n        if (trackingUrls[eventKey]) {\n          trackingUrls[eventKey].push(url);\n        }\n      }\n    });\n    scope.querySelectorAll(\"Error\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.error.push(url);\n    });\n    return trackingUrls;\n  }\n  function mergeTrackingUrls(target, source) {\n    Object.keys(target).forEach((key) => {\n      if (source[key] && source[key].length > 0) {\n        target[key] = target[key].concat(source[key]);\n      }\n    });\n    return target;\n  }\n  function parseVastXml(xmlString) {\n    try {\n      const parser = new DOMParser();\n      const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n      const parserError = xmlDoc.querySelector(\"parsererror\");\n      if (parserError) {\n        console.error(\n          \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n          parserError.textContent\n        );\n        return { type: \"empty\" };\n      }\n      const adElement = xmlDoc.querySelector(\"Ad\");\n      if (!adElement) {\n        console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n        return { type: \"empty\" };\n      }\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n      const clickThrough = xmlDoc.querySelector(\"ClickThrough\")?.textContent?.trim();\n      const wrapperUri = xmlDoc.querySelector(\"VASTAdTagURI\")?.textContent?.trim();\n      if (wrapperUri) {\n        console.log(\n          `[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ${wrapperUri}`\n        );\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough\n        };\n      }\n      const isNoAdAvailable = adId === \"empty\" || title.toLowerCase().includes(\"no ad available\") || title.toLowerCase() === \"no ad available\";\n      const durationText = xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n      const durationParts = durationText.split(\":\");\n      const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + parseInt(durationParts[2] || \"0\", 10);\n      const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n      const mediaFiles = [];\n      console.log(\n        `[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n      );\n      mediaFileElements.forEach((mf, index) => {\n        const type = mf.getAttribute(\"type\") || \"\";\n        const url = mf.textContent?.trim() || \"\";\n        const width = mf.getAttribute(\"width\") || \"\";\n        const height = mf.getAttribute(\"height\") || \"\";\n        console.log(\n          `[HlsAdPlayer] MediaFile ${index}: type=\"${type}\", url=\"${url}\", width=\"${width}\", height=\"${height}\"`\n        );\n        const mediaFile = {\n          url,\n          type,\n          width: parseInt(width || \"1920\", 10),\n          height: parseInt(height || \"1080\", 10),\n          bitrate: void 0\n        };\n        if (!url) {\n          console.warn(`[HlsAdPlayer] MediaFile ${index} has empty URL`);\n          return;\n        }\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n        mediaFile.bitrate = bitrateValue && bitrateValue > 0 ? bitrateValue : void 0;\n        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n          console.log(\n            `[HlsAdPlayer] Added ${isHlsMediaFile(mediaFile) ? \"HLS\" : \"progressive\"} MediaFile: ${url}`\n          );\n        } else {\n          console.log(\n            `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not supported)`\n          );\n        }\n      });\n      if (mediaFiles.length === 0) {\n        if (isNoAdAvailable) {\n          console.warn(\n            \"[HlsAdPlayer] No ads available (VAST response indicates no ads)\"\n          );\n        } else {\n          console.warn(\"[HlsAdPlayer] No supported media files found in VAST XML\");\n        }\n        return { type: \"empty\" };\n      }\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough\n        }\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n      return { type: \"empty\" };\n    }\n  }\n  function parseAdElement(adElement) {\n    try {\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n      const clickThrough = adElement.querySelector(\"ClickThrough\")?.textContent?.trim();\n      const wrapperUri = adElement.querySelector(\"VASTAdTagURI\")?.textContent?.trim();\n      if (wrapperUri) {\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough\n        };\n      }\n      const isNoAdAvailable = adId === \"empty\" || title.toLowerCase().includes(\"no ad available\") || title.toLowerCase() === \"no ad available\";\n      const durationText = adElement.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n      const durationParts = durationText.split(\":\");\n      const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + parseInt(durationParts[2] || \"0\", 10);\n      const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n      const mediaFiles = [];\n      mediaFileElements.forEach((mf) => {\n        const type = mf.getAttribute(\"type\") || \"\";\n        const url = mf.textContent?.trim() || \"\";\n        const width = mf.getAttribute(\"width\") || \"\";\n        const height = mf.getAttribute(\"height\") || \"\";\n        if (!url) return;\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n        const mediaFile = {\n          url,\n          type,\n          width: parseInt(width || \"1920\", 10),\n          height: parseInt(height || \"1080\", 10),\n          bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0\n        };\n        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n        }\n      });\n      if (mediaFiles.length === 0) {\n        if (isNoAdAvailable) {\n          console.warn(\n            \"[HlsAdPlayer] Pod <Ad> indicates no ad available\"\n          );\n        } else {\n          console.warn(\"[HlsAdPlayer] No supported media files in pod <Ad>\");\n        }\n        return { type: \"empty\" };\n      }\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough\n        }\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing pod <Ad> element:\", error);\n      return { type: \"empty\" };\n    }\n  }\n  async function fetchVastXml(vastTagUrl, credentials = \"include\") {\n    const requestVast = (creds) => fetch(vastTagUrl, {\n      mode: \"cors\",\n      credentials: creds,\n      headers: {\n        \"Accept\": \"application/xml, text/xml, */*\"\n      },\n      referrerPolicy: \"no-referrer-when-downgrade\"\n    });\n    let response;\n    try {\n      response = await requestVast(credentials);\n    } catch (error) {\n      if (credentials !== \"omit\") {\n        console.warn(\n          `[HlsAdPlayer] VAST fetch failed with credentials=\"${credentials}\", retrying without credentials:`,\n          error\n        );\n        response = await requestVast(\"omit\");\n      } else {\n        throw error;\n      }\n    }\n    if (!response.ok) {\n      throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n    }\n    return response.text();\n  }\n  async function fetchAndParseVastAd(vastTagUrl, depth = 0, accumulatedTracking = createEmptyTrackingUrls()) {\n    const vastXml = await fetchVastXml(\n      vastTagUrl,\n      depth === 0 ? \"include\" : \"omit\"\n    );\n    console.log(\"[HlsAdPlayer] VAST XML received\");\n    console.log(\n      \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n      vastXml.substring(0, 2e3)\n    );\n    const parsed = parseVastXml(vastXml);\n    if (parsed.type === \"empty\") {\n      return null;\n    }\n    if (parsed.type === \"wrapper\") {\n      if (depth >= MAX_VAST_WRAPPER_DEPTH) {\n        console.warn(\n          `[HlsAdPlayer] VAST wrapper depth limit (${MAX_VAST_WRAPPER_DEPTH}) reached, aborting redirect chain`\n        );\n        return null;\n      }\n      mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);\n      return fetchAndParseVastAd(\n        parsed.vastAdTagUri,\n        depth + 1,\n        accumulatedTracking\n      );\n    }\n    mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);\n    return parsed.ad;\n  }\n  async function fetchAndParsePod(vastTagUrl) {\n    const vastXml = await fetchVastXml(vastTagUrl);\n    console.log(\"[HlsAdPlayer] Pod VAST XML received\");\n    const parser = new DOMParser();\n    const xmlDoc = parser.parseFromString(vastXml, \"text/xml\");\n    if (xmlDoc.querySelector(\"parsererror\")) {\n      console.error(\"[HlsAdPlayer] Pod VAST XML parsing error (malformed)\");\n      return [];\n    }\n    const adElements = Array.from(xmlDoc.querySelectorAll(\"Ad\"));\n    if (adElements.length === 0) {\n      console.warn(\"[HlsAdPlayer] No <Ad> elements found in pod VAST response\");\n      return [];\n    }\n    adElements.sort((a, b) => {\n      const aSeq = parseInt(a.getAttribute(\"sequence\") || \"\", 10);\n      const bSeq = parseInt(b.getAttribute(\"sequence\") || \"\", 10);\n      const aVal = Number.isFinite(aSeq) ? aSeq : Number.MAX_SAFE_INTEGER;\n      const bVal = Number.isFinite(bSeq) ? bSeq : Number.MAX_SAFE_INTEGER;\n      return aVal - bVal;\n    });\n    const ads = [];\n    for (const adElement of adElements) {\n      const parsed = parseAdElement(adElement);\n      if (parsed.type === \"inline\") {\n        ads.push(parsed.ad);\n      } else if (parsed.type === \"wrapper\") {\n        try {\n          const resolved = await fetchAndParseVastAd(\n            parsed.vastAdTagUri,\n            1,\n            parsed.trackingUrls\n          );\n          if (resolved) {\n            ads.push(resolved);\n          }\n        } catch (error) {\n          console.warn(\n            \"[HlsAdPlayer] Failed to resolve wrapper <Ad> in pod:\",\n            error\n          );\n        }\n      }\n    }\n    console.log(`[HlsAdPlayer] Parsed ${ads.length} ad(s) from pod VAST response`);\n    return ads;\n  }\n  function createAdVideoElement() {\n    const video = document.createElement(\"video\");\n    video.style.position = \"absolute\";\n    video.style.left = \"0\";\n    video.style.top = \"0\";\n    video.style.width = \"100%\";\n    video.style.height = \"100%\";\n    video.style.objectFit = \"contain\";\n    video.style.backgroundColor = \"#000\";\n    video.playsInline = true;\n    video.muted = false;\n    video.volume = 1;\n    console.log(\n      `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n    );\n    return video;\n  }\n  function setupAdEventListeners() {\n    if (!adVideoElement || !currentAd) return;\n    adVideoElement.addEventListener(\"timeupdate\", () => {\n      if (!currentAd || !adVideoElement) return;\n      const progress = adVideoElement.currentTime / currentAd.duration;\n      if (progress >= 0.25 && !trackingFired.firstQuartile) {\n        trackingFired.firstQuartile = true;\n        fireTrackingPixels(currentAd.trackingUrls.firstQuartile);\n      }\n      if (progress >= 0.5 && !trackingFired.midpoint) {\n        trackingFired.midpoint = true;\n        fireTrackingPixels(currentAd.trackingUrls.midpoint);\n      }\n      if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n        trackingFired.thirdQuartile = true;\n        fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);\n      }\n    });\n    adVideoElement.addEventListener(\"playing\", () => {\n      if (!currentAd || trackingFired.start) return;\n      trackingFired.start = true;\n      fireTrackingPixels(currentAd.trackingUrls.start);\n      console.log(\"[HlsAdPlayer] Ad started playing\");\n    });\n    adVideoElement.addEventListener(\"ended\", () => {\n      if (!currentAd || trackingFired.complete) return;\n      trackingFired.complete = true;\n      fireTrackingPixels(currentAd.trackingUrls.complete);\n      console.log(\"[HlsAdPlayer] Ad completed\");\n      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\n      }\n      handleAdComplete();\n    });\n    adVideoElement.addEventListener(\"error\", (e) => {\n      if (!adPlaying) return;\n      console.error(\"[HlsAdPlayer] Ad video error:\", e);\n      if (currentAd) {\n        fireTrackingPixels(currentAd.trackingUrls.error);\n      }\n      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\n      }\n      handleAdError();\n    });\n    adVideoElement.addEventListener(\"volumechange\", () => {\n      if (!currentAd) return;\n      if (adVideoElement.muted) {\n        fireTrackingPixels(currentAd.trackingUrls.mute);\n      } else {\n        fireTrackingPixels(currentAd.trackingUrls.unmute);\n      }\n    });\n    adVideoElement.addEventListener(\"pause\", () => {\n      if (currentAd && !adVideoElement.ended) {\n        fireTrackingPixels(currentAd.trackingUrls.pause);\n      }\n    });\n    adVideoElement.addEventListener(\"play\", () => {\n      if (currentAd && adVideoElement.currentTime > 0) {\n        fireTrackingPixels(currentAd.trackingUrls.resume);\n      }\n    });\n  }\n  function setAdPlayingFlag(isPlaying) {\n    if (isPlaying) {\n      contentVideo.dataset.stormcloudAdPlaying = \"true\";\n    } else {\n      delete contentVideo.dataset.stormcloudAdPlaying;\n    }\n  }\n  function resetQuartileTracking(preserveImpression) {\n    trackingFired = {\n      impression: preserveImpression ? trackingFired.impression : false,\n      start: false,\n      firstQuartile: false,\n      midpoint: false,\n      thirdQuartile: false,\n      complete: false\n    };\n  }\n  function loadCurrentAdMedia() {\n    if (!adVideoElement || !currentAd) {\n      throw new Error(\"No ad video element or ad to load\");\n    }\n    const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n    if (!mediaFile) {\n      throw new Error(\"No media file available for ad\");\n    }\n    const isHlsAd = isHlsMediaFile(mediaFile);\n    console.log(\n      `[HlsAdPlayer] Loading ${isHlsAd ? \"HLS\" : \"progressive\"} ad (pod ${podIndex + 1}/${podAds.length || 1}) from: ${mediaFile.url}`\n    );\n    if (isHlsAd && import_hls.default.isSupported()) {\n      if (adHls) {\n        adHls.destroy();\n      }\n      adHls = new import_hls.default({\n        enableWorker: true,\n        lowLatencyMode: false\n      });\n      adHls.loadSource(mediaFile.url);\n      adHls.attachMedia(adVideoElement);\n      adHls.on(import_hls.default.Events.MANIFEST_PARSED, () => {\n        console.log(\"[HlsAdPlayer] HLS manifest parsed, starting playback\");\n        adVideoElement.play().catch((error) => {\n          console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n          handleAdError();\n        });\n      });\n      adHls.on(import_hls.default.Events.ERROR, (_event, data) => {\n        console.error(\"[HlsAdPlayer] HLS error:\", data);\n        if (data.fatal) {\n          handleAdError();\n        }\n      });\n    } else if (isHlsAd && adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")) {\n      adVideoElement.src = mediaFile.url;\n      adVideoElement.play().catch((error) => {\n        console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n        handleAdError();\n      });\n    } else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {\n      if (adHls) {\n        adHls.destroy();\n        adHls = void 0;\n      }\n      adVideoElement.src = mediaFile.url;\n      adVideoElement.load();\n      adVideoElement.play().catch((error) => {\n        console.error(\"[HlsAdPlayer] Error starting progressive ad playback:\", error);\n        handleAdError();\n      });\n    } else {\n      throw new Error(`Unsupported ad media file type: ${mediaFile.type}`);\n    }\n  }\n  function advanceToNextPodAd() {\n    if (podIndex >= podAds.length - 1) {\n      return false;\n    }\n    podIndex++;\n    currentAd = podAds[podIndex];\n    resetQuartileTracking(false);\n    if (currentAd) {\n      fireTrackingPixels(currentAd.trackingUrls.impression);\n      trackingFired.impression = true;\n      console.log(\n        `[HlsAdPlayer] Advancing to next pod ad (${podIndex + 1}/${podAds.length}): ${currentAd.title}, duration: ${currentAd.duration}s`\n      );\n    }\n    try {\n      loadCurrentAdMedia();\n      emit(\"pod_ad_started\", { index: podIndex, total: podAds.length });\n      return true;\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Failed to load next pod ad:\", error);\n      return false;\n    }\n  }\n  function handleAdComplete() {\n    console.log(\"[HlsAdPlayer] Handling ad completion\");\n    adPlaying = false;\n    setAdPlayingFlag(false);\n    contentVideo.muted = true;\n    if (adContainerEl) {\n      adContainerEl.style.display = \"none\";\n      adContainerEl.style.pointerEvents = \"none\";\n    }\n    if (options?.continueLiveStreamDuringAds) {\n      if (contentVideo.paused) {\n        console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback\");\n        contentVideo.play().catch(() => {\n        });\n      } else {\n        console.log(\"[HlsAdPlayer] Content video already playing in live mode\");\n      }\n    }\n    emit(\"content_resume\");\n  }\n  function handleAdError() {\n    console.log(\"[HlsAdPlayer] Handling ad error\");\n    adPlaying = false;\n    setAdPlayingFlag(false);\n    contentVideo.muted = true;\n    if (adContainerEl) {\n      adContainerEl.style.display = \"none\";\n      adContainerEl.style.pointerEvents = \"none\";\n    }\n    emit(\"ad_error\");\n  }\n  return {\n    initialize() {\n      console.log(\"[HlsAdPlayer] Initializing\");\n      if (!adContainerEl) {\n        const container = document.createElement(\"div\");\n        container.style.position = \"absolute\";\n        container.style.left = \"0\";\n        container.style.top = \"0\";\n        container.style.right = \"0\";\n        container.style.bottom = \"0\";\n        container.style.display = \"none\";\n        container.style.alignItems = \"center\";\n        container.style.justifyContent = \"center\";\n        container.style.pointerEvents = \"none\";\n        container.style.zIndex = \"30\";\n        container.style.backgroundColor = \"#000\";\n        contentVideo.parentElement?.appendChild(container);\n        adContainerEl = container;\n      }\n    },\n    async requestAds(vastTagUrl) {\n      console.log(\"[HlsAdPlayer] Requesting ads:\", vastTagUrl);\n      if (adPlaying) {\n        console.warn(\n          \"[HlsAdPlayer] Cannot request new ads while an ad is playing\"\n        );\n        return Promise.reject(new Error(\"Ad already playing\"));\n      }\n      try {\n        sessionId = generateSessionId();\n        let ads = [];\n        if (preloadedAds.has(vastTagUrl)) {\n          const preloaded = preloadedAds.get(vastTagUrl);\n          preloadedAds.delete(vastTagUrl);\n          if (preloaded) {\n            ads = [preloaded];\n          }\n          console.log(\n            \"[HlsAdPlayer] Using preloaded VAST response:\",\n            vastTagUrl\n          );\n        } else {\n          ads = await fetchAndParsePod(vastTagUrl);\n        }\n        if (!ads.length) {\n          console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n          emit(\"ad_error\");\n          return Promise.reject(new Error(\"No ads available from VAST response\"));\n        }\n        podAds = ads;\n        podIndex = 0;\n        currentAd = ads[0];\n        console.log(\n          `[HlsAdPlayer] Pod parsed: ${ads.length} ad(s), first=\"${currentAd?.title}\", duration=${currentAd?.duration}s`\n        );\n        if (currentAd) {\n          fireTrackingPixels(currentAd.trackingUrls.impression);\n          trackingFired.impression = true;\n        }\n        return Promise.resolve();\n      } catch (error) {\n        console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n        emit(\"ad_error\");\n        return Promise.reject(error);\n      }\n    },\n    async play() {\n      if (!currentAd) {\n        console.warn(\n          \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n        );\n        return Promise.reject(new Error(\"No ad loaded\"));\n      }\n      console.log(\"[HlsAdPlayer] Starting ad playback\");\n      try {\n        if (!adVideoElement) {\n          adVideoElement = createAdVideoElement();\n          adContainerEl?.appendChild(adVideoElement);\n          setupAdEventListeners();\n        }\n        resetQuartileTracking(true);\n        const contentVolume = contentVideo.volume;\n        originalVolume = Math.max(\n          0,\n          Math.min(1, contentVolume || originalVolume)\n        );\n        if (!options?.continueLiveStreamDuringAds) {\n          contentVideo.pause();\n          console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n        } else {\n          console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n        }\n        console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n        contentVideo.muted = true;\n        adPlaying = true;\n        setAdPlayingFlag(true);\n        if (adVideoElement) {\n          adVideoElement.volume = Math.max(0, Math.min(1, originalVolume));\n          adVideoElement.muted = originalMutedState;\n          console.log(\n            `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`\n          );\n        }\n        if (adContainerEl) {\n          adContainerEl.style.display = \"flex\";\n          adContainerEl.style.pointerEvents = \"auto\";\n        }\n        emit(\"content_pause\");\n        loadCurrentAdMedia();\n        return Promise.resolve();\n      } catch (error) {\n        console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n        handleAdError();\n        return Promise.reject(error);\n      }\n    },\n    pause() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n      try {\n        if (adVideoElement && !adVideoElement.paused) {\n          adVideoElement.pause();\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error pausing ad:\", error);\n      }\n    },\n    resume() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n      try {\n        if (adVideoElement && adVideoElement.paused) {\n          adVideoElement.play().catch(() => {\n          });\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error resuming ad:\", error);\n      }\n    },\n    async stop() {\n      console.log(\"[HlsAdPlayer] Stopping ad\");\n      adPlaying = false;\n      setAdPlayingFlag(false);\n      const previousMutedState = contentVideo.muted;\n      contentVideo.muted = originalMutedState;\n      contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n      console.log(\n        `[HlsAdPlayer] Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}, volume: ${contentVideo.volume}`\n      );\n      if (adContainerEl) {\n        adContainerEl.style.display = \"none\";\n        adContainerEl.style.pointerEvents = \"none\";\n      }\n      contentVideo.style.visibility = \"visible\";\n      contentVideo.style.opacity = \"1\";\n      if (options?.continueLiveStreamDuringAds) {\n        if (contentVideo.paused) {\n          console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback on stop\");\n          contentVideo.play().catch(() => {\n          });\n        }\n      }\n      if (adHls) {\n        adHls.destroy();\n        adHls = void 0;\n      }\n      if (adVideoElement) {\n        adVideoElement.pause();\n        adVideoElement.src = \"\";\n      }\n      currentAd = void 0;\n      podAds = [];\n      podIndex = 0;\n    },\n    destroy() {\n      console.log(\"[HlsAdPlayer] Destroying\");\n      destroyed = true;\n      for (const timeoutId of pendingTimeouts) {\n        clearTimeout(timeoutId);\n      }\n      pendingTimeouts = [];\n      adPlaying = false;\n      setAdPlayingFlag(false);\n      contentVideo.muted = originalMutedState;\n      contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n      if (adHls) {\n        adHls.destroy();\n        adHls = void 0;\n      }\n      if (adVideoElement) {\n        adVideoElement.pause();\n        adVideoElement.src = \"\";\n        adVideoElement.remove();\n        adVideoElement = void 0;\n      }\n      if (adContainerEl?.parentElement) {\n        adContainerEl.parentElement.removeChild(adContainerEl);\n      }\n      adContainerEl = void 0;\n      currentAd = void 0;\n      podAds = [];\n      podIndex = 0;\n      listeners.clear();\n      preloadedAds.clear();\n      preloadingAds.clear();\n    },\n    isAdPlaying() {\n      return adPlaying;\n    },\n    resize(width, height) {\n      console.log(`[HlsAdPlayer] Resizing to ${width}x${height}`);\n      if (adContainerEl) {\n        adContainerEl.style.width = `${width}px`;\n        adContainerEl.style.height = `${height}px`;\n      }\n      if (adVideoElement) {\n        adVideoElement.style.width = `${width}px`;\n        adVideoElement.style.height = `${height}px`;\n      }\n    },\n    on(event, listener) {\n      if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());\n      listeners.get(event).add(listener);\n    },\n    off(event, listener) {\n      listeners.get(event)?.delete(listener);\n    },\n    updateOriginalMutedState(muted, volume) {\n      const nextVolume = typeof volume === \"number\" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;\n      console.log(\n        `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n      );\n      originalMutedState = muted;\n      originalVolume = nextVolume;\n    },\n    getOriginalMutedState() {\n      return originalMutedState;\n    },\n    getOriginalVolume() {\n      return originalVolume;\n    },\n    setAdVolume(volume) {\n      if (adVideoElement && adPlaying) {\n        const clamped = Math.max(0, Math.min(1, volume));\n        adVideoElement.volume = clamped;\n        adVideoElement.muted = clamped === 0;\n      }\n    },\n    getAdVolume() {\n      if (adVideoElement && adPlaying) {\n        return adVideoElement.volume;\n      }\n      return 1;\n    },\n    showPlaceholder() {\n      contentVideo.style.opacity = \"0\";\n      contentVideo.style.visibility = \"hidden\";\n      if (!adContainerEl) {\n        const container = document.createElement(\"div\");\n        container.style.position = \"absolute\";\n        container.style.left = \"0\";\n        container.style.top = \"0\";\n        container.style.right = \"0\";\n        container.style.bottom = \"0\";\n        container.style.display = \"none\";\n        container.style.alignItems = \"center\";\n        container.style.justifyContent = \"center\";\n        container.style.pointerEvents = \"none\";\n        container.style.zIndex = \"10\";\n        container.style.backgroundColor = \"#000\";\n        contentVideo.parentElement?.appendChild(container);\n        adContainerEl = container;\n      }\n      if (adContainerEl) {\n        adContainerEl.style.display = \"flex\";\n        adContainerEl.style.pointerEvents = \"auto\";\n      }\n    },\n    hidePlaceholder() {\n      if (adContainerEl) {\n        adContainerEl.style.display = \"none\";\n        adContainerEl.style.pointerEvents = \"none\";\n      }\n      if (!adPlaying) {\n        contentVideo.style.visibility = \"visible\";\n        contentVideo.style.opacity = \"1\";\n      }\n    },\n    getLoadedAdDuration() {\n      return currentAd?.duration;\n    },\n    getLoadedAdId() {\n      return currentAd?.id;\n    },\n    getPodAdCount() {\n      return podAds.length;\n    },\n    getPodTotalDurationMs() {\n      return podAds.reduce(\n        (total, ad) => total + (ad.duration > 0 ? ad.duration * 1e3 : 0),\n        0\n      );\n    }\n  };\n}\n\n// src/sdk/pal.ts\nvar PAL_SDK_URL = \"https://imasdk.googleapis.com/pal/sdkloader/pal.js\";\nvar _nonceLoader;\nvar _palLoadPromise;\nfunction loadPalSdk() {\n  if (typeof window !== \"undefined\" && window.goog?.pal) {\n    return Promise.resolve();\n  }\n  if (_palLoadPromise) return _palLoadPromise;\n  _palLoadPromise = new Promise((resolve, reject) => {\n    const existing = document.querySelector(\n      'script[data-pal=\"true\"]'\n    );\n    if (existing) {\n      if (window.goog?.pal) {\n        resolve();\n        return;\n      }\n      const timeout = setTimeout(\n        () => reject(new Error(\"PAL SDK load timeout\")),\n        1e4\n      );\n      existing.addEventListener(\"load\", () => {\n        clearTimeout(timeout);\n        resolve();\n      });\n      existing.addEventListener(\"error\", () => {\n        clearTimeout(timeout);\n        reject(new Error(\"PAL SDK load failed\"));\n      });\n      return;\n    }\n    const script = document.createElement(\"script\");\n    script.src = PAL_SDK_URL;\n    script.async = true;\n    script.setAttribute(\"data-pal\", \"true\");\n    script.onload = () => resolve();\n    script.onerror = () => reject(new Error(\"PAL SDK load failed\"));\n    document.head.appendChild(script);\n  });\n  return _palLoadPromise;\n}\nfunction getOrCreateNonceLoader() {\n  if (_nonceLoader) return _nonceLoader;\n  const goog = window.goog;\n  const consentSettings = new goog.pal.ConsentSettings();\n  consentSettings.allowStorage = true;\n  _nonceLoader = new goog.pal.NonceLoader(consentSettings);\n  return _nonceLoader;\n}\nfunction createPalNonceManager() {\n  let currentNonce = \"\";\n  let currentNonceManager;\n  return {\n    async generateNonce(options = {}) {\n      try {\n        await loadPalSdk();\n        const loader = getOrCreateNonceLoader();\n        const goog = window.goog;\n        const request = new goog.pal.NonceRequest();\n        request.adWillAutoPlay = options.adWillAutoPlay ?? true;\n        request.adWillPlayMuted = options.adWillPlayMuted ?? false;\n        request.playerVolume = options.playerVolume ?? (request.adWillPlayMuted ? 0 : 1);\n        request.continuousPlayback = options.continuousPlayback ?? true;\n        request.descriptionUrl = options.descriptionUrl || (typeof window !== \"undefined\" ? window.location.href : \"\");\n        request.iconsSupported = true;\n        request.playerType = \"StormcloudVideoPlayer\";\n        request.playerVersion = \"1.0\";\n        request.supportedApiFrameworks = \"2,7,9\";\n        request.url = options.descriptionUrl || (typeof window !== \"undefined\" ? window.location.href : \"\");\n        request.videoWidth = options.videoWidth || 640;\n        request.videoHeight = options.videoHeight || 480;\n        if (options.ppid) request.ppid = options.ppid;\n        if (options.sessionId) request.sessionId = options.sessionId;\n        console.log(\"[PAL] NonceRequest before generateNonce:\", {\n          adWillAutoPlay: request.adWillAutoPlay,\n          adWillPlayMuted: request.adWillPlayMuted,\n          playerVolume: request.playerVolume,\n          continuousPlayback: request.continuousPlayback,\n          descriptionUrl: request.descriptionUrl,\n          iconsSupported: request.iconsSupported,\n          playerType: request.playerType,\n          playerVersion: request.playerVersion,\n          supportedApiFrameworks: request.supportedApiFrameworks,\n          url: request.url,\n          videoWidth: request.videoWidth,\n          videoHeight: request.videoHeight,\n          ppid: request.ppid,\n          sessionId: request.sessionId\n        });\n        const manager = await loader.loadNonceManager(request);\n        currentNonceManager = manager;\n        currentNonce = manager.getNonce();\n        console.log(\"[PAL] Nonce generated successfully\");\n        return currentNonce;\n      } catch (error) {\n        console.warn(\"[PAL] Failed to generate nonce:\", error);\n        currentNonce = \"\";\n        currentNonceManager = void 0;\n        return \"\";\n      }\n    },\n    getCurrentNonce() {\n      return currentNonce;\n    },\n    injectNonce(vastTagUrl) {\n      if (!currentNonce || !vastTagUrl) return vastTagUrl;\n      try {\n        const url = new URL(vastTagUrl);\n        url.searchParams.delete(\"paln\");\n        url.searchParams.set(\"givn\", currentNonce);\n        return url.toString();\n      } catch {\n        let base = vastTagUrl.replace(/([?&])paln=[^&]*/g, \"\").replace(/[?&]$/, \"\");\n        const sep = base.includes(\"?\") ? \"&\" : \"?\";\n        return `${base}${sep}givn=${encodeURIComponent(currentNonce)}`;\n      }\n    },\n    sendPlaybackStart() {\n      try {\n        currentNonceManager?.sendPlaybackStart();\n      } catch {\n      }\n    },\n    sendPlaybackEnd() {\n      try {\n        currentNonceManager?.sendPlaybackEnd();\n      } catch {\n      }\n    },\n    sendAdClick() {\n      try {\n        currentNonceManager?.sendAdClick();\n      } catch {\n      }\n    },\n    sendAdTouch(event) {\n      try {\n        currentNonceManager?.sendAdTouch(event);\n      } catch {\n      }\n    },\n    reset() {\n      currentNonce = \"\";\n      currentNonceManager = void 0;\n    }\n  };\n}\n\n// src/utils/mqttConfig.ts\nvar DEFAULT_MQTT_CONFIG = {\n  enabled: true,\n  brokerAddress: \"vecbae77.ala.us-east-1.emqxsl.com\",\n  brokerPort: 8883,\n  wsPort: 8084,\n  username: \"for-sonifi\",\n  password: \"sonifi-mqtt\",\n  topicPrefix: \"adstorm/players\",\n  qos: 1\n};\nvar mqttConfig = { ...DEFAULT_MQTT_CONFIG };\nfunction isMQTTEnabled() {\n  return mqttConfig.enabled;\n}\nfunction buildMQTTBrokerUrl() {\n  if (mqttConfig.brokerUrl) return mqttConfig.brokerUrl;\n  return `wss://${mqttConfig.brokerAddress}:${mqttConfig.wsPort}/mqtt`;\n}\nfunction buildPlayerTopic(licenseKey, channel) {\n  return `${mqttConfig.topicPrefix}/${licenseKey}/${channel}`;\n}\n\n// src/utils/mqttClient.ts\nvar import_mqtt = __toESM(require(\"mqtt\"), 1);\nvar LOG = \"[StormcloudVideoPlayer][MQTT]\";\nvar client = null;\nvar status = \"disconnected\";\nfunction initMQTTClient() {\n  if (client || !isMQTTEnabled()) return;\n  const url = buildMQTTBrokerUrl();\n  status = \"connecting\";\n  const clientId = `stormcloud-vp-${Math.random().toString(36).slice(2, 9)}`;\n  try {\n    client = import_mqtt.default.connect(url, {\n      clientId,\n      username: mqttConfig.username,\n      password: mqttConfig.password,\n      keepalive: 60,\n      clean: true,\n      reconnectPeriod: 5e3,\n      connectTimeout: 1e4,\n      queueQoSZero: false\n    });\n  } catch (err) {\n    status = \"error\";\n    console.warn(`${LOG} connect() threw:`, err);\n    return;\n  }\n  client.on(\"connect\", () => {\n    status = \"connected\";\n    console.info(`${LOG} connected to ${url}`);\n  });\n  client.on(\"reconnect\", () => {\n    status = \"connecting\";\n    console.info(`${LOG} reconnecting\\u2026`);\n  });\n  client.on(\"offline\", () => {\n    status = \"disconnected\";\n    console.warn(`${LOG} offline`);\n  });\n  client.on(\"error\", (err) => {\n    status = \"error\";\n    console.warn(`${LOG} error:`, err.message);\n  });\n  client.on(\"close\", () => {\n    if (status === \"connected\") {\n      status = \"disconnected\";\n    }\n  });\n}\nfunction ensureMQTTClient() {\n  if (isMQTTEnabled() && !client) {\n    initMQTTClient();\n  }\n}\nfunction publishMQTT(topic, payload) {\n  if (!isMQTTEnabled()) {\n    return false;\n  }\n  ensureMQTTClient();\n  if (!client) {\n    return false;\n  }\n  try {\n    client.publish(topic, JSON.stringify(payload), { qos: mqttConfig.qos });\n    return true;\n  } catch (err) {\n    console.warn(`${LOG} publish failed on ${topic}:`, err);\n    return false;\n  }\n}\n\n// src/utils/vastEnvironmentSignals.ts\nvar AIRY_ANDROID_APP_ID = \"com.freeairytv.android\";\nvar AIRY_WEBOS_APP_ID = \"com.freeairytv.webos\";\nvar AIRY_TIZEN_APP_ID = \"com.freeairytv.samsung\";\nvar AIRY_ROKU_APP_ID = \"com.freeairytv.roku\";\nvar AIRY_APP_NAME = \"AiryTV Movies & TV\";\nvar AIRY_DEFAULT_CONTENT_URL = \"https://live.airy.tv\";\nvar CTV_SESSION_STORAGE_KEY = \"stormcloud.ctv.sid\";\nvar PLAYER_ID_STORAGE_KEY = \"stormcloud.player.id\";\nvar LG_TEST_APP_ID = \"com.hulu.plus\";\nvar LG_TEST_APP_NAME = \"Hulu\";\nvar LG_TEST_CONTENT_URL = \"https://www.hulu.com/live-tv\";\nvar _lgTestDeviceId;\nfunction getLgTestDeviceId() {\n  if (!_lgTestDeviceId) _lgTestDeviceId = createUuid();\n  return _lgTestDeviceId;\n}\nfunction isLgWebOS() {\n  if (typeof navigator === \"undefined\") return false;\n  return /Web0S|webOS|LG Browser|LGSTB|LGE/i.test(navigator.userAgent);\n}\nfunction getDefaultAppId() {\n  if (typeof navigator === \"undefined\") return AIRY_ANDROID_APP_ID;\n  const ua = navigator.userAgent;\n  if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;\n  if (/Tizen|Samsung/i.test(ua)) return AIRY_TIZEN_APP_ID;\n  if (/Roku/i.test(ua)) return AIRY_ROKU_APP_ID;\n  return AIRY_ANDROID_APP_ID;\n}\nvar DEVICE_ID_STORAGE_KEYS = [\n  \"rdid\",\n  \"ifa\",\n  \"advertisingId\",\n  \"advertising_id\",\n  \"deviceAdvertisingId\",\n  \"aaid\",\n  \"adid\",\n  \"rida\",\n  \"tifa\",\n  \"lgudid\"\n];\nvar ANDROID_ID_TYPES = /* @__PURE__ */ new Set([\"aaid\", \"adid\"]);\nfunction resolveVastEnvironmentSignals(isCtv) {\n  const bridgeSignals = readNativeBridgeSignals();\n  const platformDevice = readPlatformNativeDeviceId();\n  const lg = isCtv && isLgWebOS();\n  const deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId || (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : void 0);\n  const deviceIdType = bridgeSignals.deviceIdType || readStoredString(\"deviceIdType\") || readStoredString(\"idtype\") || platformDevice.deviceIdType || inferDeviceIdType() || (lg ? \"lgudid\" : void 0);\n  const platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;\n  const limitAdTracking = deviceId != null ? platformLat ?? readStoredLimitAdTracking() ?? false : void 0;\n  if (isCtv) {\n    return {\n      isCtv: true,\n      contentUrl: bridgeSignals.contentUrl || readStoredString(\"contentUrl\") || (lg ? LG_TEST_CONTENT_URL : AIRY_DEFAULT_CONTENT_URL),\n      appId: bridgeSignals.appId || readStoredString(\"appId\") || readStoredString(\"msid\") || (lg ? LG_TEST_APP_ID : getDefaultAppId()),\n      appName: bridgeSignals.appName || readStoredString(\"appName\") || readStoredString(\"an\") || (lg ? LG_TEST_APP_NAME : AIRY_APP_NAME),\n      sessionId: getOrCreateCtvSessionId(),\n      ...deviceId ? { deviceId } : {},\n      ...deviceIdType ? { deviceIdType } : {},\n      ...limitAdTracking != null ? { limitAdTracking } : {},\n      deviceTypeHint: 5\n    };\n  }\n  return {\n    isCtv: false,\n    ...deviceId ? { deviceId } : {},\n    ...deviceIdType ? { deviceIdType } : {},\n    ...limitAdTracking != null ? { limitAdTracking } : {}\n  };\n}\nfunction inferDeviceIdType() {\n  if (typeof navigator === \"undefined\") {\n    return void 0;\n  }\n  const ua = navigator.userAgent;\n  if (/Roku/i.test(ua)) return \"rida\";\n  if (/Tizen|Samsung/i.test(ua)) return \"tifa\";\n  if (/AppleTV|Apple TV/i.test(ua)) return \"tvOS\";\n  if (/AFT|Fire TV|Amazon/i.test(ua)) return \"afai\";\n  if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return \"lgudid\";\n  if (/Android|Google TV/i.test(ua)) return \"aaid\";\n  if (/iPhone|iPad|iPod/i.test(ua)) return \"idfa\";\n  return void 0;\n}\nfunction isEquivalentDeviceIdType(tagType, runtimeType) {\n  if (!tagType || !runtimeType) return false;\n  const tag = tagType.toLowerCase();\n  const runtime = runtimeType.toLowerCase();\n  if (tag === runtime) return true;\n  return ANDROID_ID_TYPES.has(tag) && ANDROID_ID_TYPES.has(runtime);\n}\nfunction resolveNativeDeviceId() {\n  const bridgeSignals = readNativeBridgeSignals();\n  const platformDevice = readPlatformNativeDeviceId();\n  const deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId;\n  if (!deviceId || isMacroPlaceholder(deviceId) || isZeroedAdId(deviceId)) {\n    return void 0;\n  }\n  return deviceId;\n}\nfunction getOrCreateStoredUuid(storageKey) {\n  if (typeof window === \"undefined\") {\n    return void 0;\n  }\n  const existing = readPersistentId(storageKey);\n  if (existing) {\n    writePersistentId(storageKey, existing);\n    return existing;\n  }\n  const id = createUuid();\n  writePersistentId(storageKey, id);\n  return id;\n}\nfunction getOrCreateCtvSessionId() {\n  const existing = readPersistentId(CTV_SESSION_STORAGE_KEY);\n  if (existing) {\n    writePersistentId(CTV_SESSION_STORAGE_KEY, existing);\n    return existing;\n  }\n  const sessionId = createUuid();\n  writePersistentId(CTV_SESSION_STORAGE_KEY, sessionId);\n  return sessionId;\n}\nfunction readPersistentId(storageKey) {\n  return readStoredString(storageKey) || readCookie(storageKey);\n}\nfunction writePersistentId(storageKey, value) {\n  try {\n    window.localStorage?.setItem(storageKey, value);\n  } catch {\n  }\n  writeCookie(storageKey, value);\n}\nvar PERSISTENT_ID_COOKIE_MAX_AGE = 60 * 60 * 24 * 365 * 5;\nfunction readCookie(name) {\n  if (typeof document === \"undefined\") {\n    return void 0;\n  }\n  try {\n    const prefix = encodeURIComponent(name) + \"=\";\n    const parts = document.cookie ? document.cookie.split(\";\") : [];\n    for (const part of parts) {\n      const entry = part.trim();\n      if (entry.startsWith(prefix)) {\n        return decodeURIComponent(entry.slice(prefix.length)) || void 0;\n      }\n    }\n  } catch {\n  }\n  return void 0;\n}\nfunction writeCookie(name, value) {\n  if (typeof document === \"undefined\") {\n    return;\n  }\n  try {\n    document.cookie = encodeURIComponent(name) + \"=\" + encodeURIComponent(value) + \";path=/;max-age=\" + PERSISTENT_ID_COOKIE_MAX_AGE + \";SameSite=Lax\";\n  } catch {\n  }\n}\nfunction createUuid() {\n  if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n    return crypto.randomUUID();\n  }\n  const bytes = new Uint8Array(16);\n  if (typeof crypto !== \"undefined\" && typeof crypto.getRandomValues === \"function\") {\n    crypto.getRandomValues(bytes);\n  } else {\n    let seed = Date.now() ^ Math.floor(performanceNow() * 1e3);\n    for (let i = 0; i < 16; i++) {\n      seed = seed * 1103515245 + 12345 & 2147483647;\n      bytes[i] = (seed ^ Math.floor(Math.random() * 256)) & 255;\n    }\n  }\n  bytes[6] = (bytes[6] ?? 0) & 15 | 64;\n  bytes[8] = (bytes[8] ?? 0) & 63 | 128;\n  let hex = \"\";\n  for (let i = 0; i < 16; i++) {\n    hex += (bytes[i] ?? 0).toString(16).padStart(2, \"0\");\n  }\n  return hex.slice(0, 8) + \"-\" + hex.slice(8, 12) + \"-\" + hex.slice(12, 16) + \"-\" + hex.slice(16, 20) + \"-\" + hex.slice(20, 32);\n}\nfunction performanceNow() {\n  try {\n    if (typeof performance !== \"undefined\" && typeof performance.now === \"function\") {\n      return performance.now();\n    }\n  } catch {\n  }\n  return 0;\n}\nfunction readPlatformNativeDeviceId() {\n  if (typeof window === \"undefined\") return {};\n  try {\n    const adinfo = window.webapis?.adinfo;\n    if (adinfo) {\n      const tifa = typeof adinfo.getTIFA === \"function\" ? adinfo.getTIFA() : adinfo.tifa;\n      if (typeof tifa === \"string\" && tifa && !isMacroPlaceholder(tifa)) {\n        const lat = typeof adinfo.isLATEnabled === \"function\" ? adinfo.isLATEnabled() : void 0;\n        return {\n          deviceId: tifa,\n          deviceIdType: \"tifa\",\n          ...typeof lat === \"boolean\" ? { limitAdTracking: lat } : {}\n        };\n      }\n    }\n  } catch {\n  }\n  try {\n    const webOSDev = window.webOSDev;\n    if (webOSDev) {\n      const lgudid = typeof webOSDev.LGUDID === \"function\" ? webOSDev.LGUDID() : webOSDev.lgudid ?? webOSDev.LGUDID;\n      if (typeof lgudid === \"string\" && lgudid) {\n        if (isZeroedAdId(lgudid)) {\n          return { deviceIdType: \"lgudid\", limitAdTracking: true };\n        }\n        if (!isMacroPlaceholder(lgudid)) {\n          return { deviceId: lgudid, deviceIdType: \"lgudid\", limitAdTracking: false };\n        }\n      }\n    }\n  } catch {\n  }\n  try {\n    const roku = window.Roku;\n    if (roku) {\n      const rida = typeof roku.getPublisherUniqueId === \"function\" ? roku.getPublisherUniqueId() : roku.rida;\n      if (typeof rida === \"string\" && rida && !isMacroPlaceholder(rida)) {\n        return { deviceId: rida, deviceIdType: \"rida\", limitAdTracking: false };\n      }\n    }\n  } catch {\n  }\n  return {};\n}\nvar ZEROED_AD_ID_PATTERNS = /* @__PURE__ */ new Set([\n  \"38400000-8cf0-11bd-b23e-10b96e40000d\",\n  \"00000000-0000-0000-0000-000000000000\"\n]);\nfunction isMacroPlaceholder(value) {\n  const t = value.trim();\n  return !t || /^(\\[[^\\]]*\\]|\\{[^}]*\\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\\/a|\\$\\{[^}]+\\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());\n}\nfunction isZeroedAdId(value) {\n  return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());\n}\nfunction readNativeBridgeSignals() {\n  if (typeof window === \"undefined\") {\n    return {};\n  }\n  const candidates = [\n    window.__STORMCLOUD_CTV_AD_INFO__,\n    window.__STORMCLOUD_CTV__,\n    window.stormcloudCtv,\n    window.AiryTV,\n    window.Android,\n    window.webOS,\n    window.tizen,\n    window.amazon\n  ].filter(Boolean);\n  for (const source of candidates) {\n    const contentUrl = readBridgeValue(source, [\"contentUrl\", \"url\", \"videoUrl\", \"canonicalUrl\"]) || void 0;\n    const appId = readBridgeValue(source, [\"appId\", \"msid\", \"applicationId\", \"packageName\"]) || void 0;\n    const appName = readBridgeValue(source, [\"appName\", \"an\", \"applicationName\"]) || void 0;\n    const deviceId = readBridgeValue(source, [\n      \"rdid\",\n      \"ifa\",\n      \"advertisingId\",\n      \"adId\",\n      \"deviceId\",\n      \"lgudid\",\n      \"LGUDID\",\n      \"tifa\",\n      \"rida\",\n      \"afai\",\n      \"aaid\"\n    ]) || void 0;\n    if (!contentUrl && !deviceId && !appId && !appName) continue;\n    const deviceIdType = readBridgeValue(source, [\n      \"idtype\",\n      \"deviceIdType\",\n      \"advertisingIdType\",\n      \"idType\"\n    ]) || inferDeviceIdType();\n    const limitAdTracking = readBridgeBoolean(source, [\n      \"is_lat\",\n      \"limitAdTracking\",\n      \"limitedAdTracking\",\n      \"lat\"\n    ]);\n    return {\n      ...contentUrl ? { contentUrl } : {},\n      ...appId ? { appId } : {},\n      ...appName ? { appName } : {},\n      ...deviceId ? { deviceId } : {},\n      ...deviceId && deviceIdType ? { deviceIdType } : {},\n      ...deviceId && limitAdTracking != null ? { limitAdTracking } : {}\n    };\n  }\n  return {};\n}\nfunction readBridgeValue(source, keys) {\n  for (const key of keys) {\n    const value = source?.[key];\n    if (typeof value === \"string\" && value) {\n      return value;\n    }\n    if (typeof value === \"function\") {\n      try {\n        const result = value.call(source);\n        if (typeof result === \"string\" && result) {\n          return result;\n        }\n      } catch {\n      }\n    }\n  }\n  return void 0;\n}\nfunction readBridgeBoolean(source, keys) {\n  for (const key of keys) {\n    const value = source?.[key];\n    const normalized = normalizeBoolean(value);\n    if (normalized != null) {\n      return normalized;\n    }\n    if (typeof value === \"function\") {\n      try {\n        const result = normalizeBoolean(value.call(source));\n        if (result != null) {\n          return result;\n        }\n      } catch {\n      }\n    }\n  }\n  return void 0;\n}\nfunction readStoredDeviceId() {\n  for (const key of DEVICE_ID_STORAGE_KEYS) {\n    const value = readStoredString(key);\n    if (value) {\n      return value;\n    }\n  }\n  return void 0;\n}\nfunction readStoredString(key) {\n  if (typeof window === \"undefined\") {\n    return void 0;\n  }\n  try {\n    const value = window.localStorage?.getItem(key);\n    return value || void 0;\n  } catch {\n    return void 0;\n  }\n}\nfunction readStoredLimitAdTracking() {\n  return normalizeBoolean(\n    readStoredString(\"limitAdTracking\") || readStoredString(\"limitedAdTracking\") || readStoredString(\"is_lat\")\n  );\n}\nfunction normalizeBoolean(value) {\n  if (typeof value === \"boolean\") {\n    return value;\n  }\n  if (typeof value === \"number\") {\n    return value === 1;\n  }\n  if (typeof value === \"string\") {\n    const normalized = value.toLowerCase();\n    if (normalized === \"1\" || normalized === \"true\" || normalized === \"yes\") {\n      return true;\n    }\n    if (normalized === \"0\" || normalized === \"false\" || normalized === \"no\") {\n      return false;\n    }\n  }\n  return void 0;\n}\n\n// src/utils/tracking.ts\nvar cachedBrowserId = null;\nfunction buildAnalyticsContext(config) {\n  const context = {};\n  if (config.debugAdTiming) {\n    context.debugAdTiming = true;\n  }\n  if (config.isLiveStream !== void 0) {\n    context.inputStreamType = config.isLiveStream ? \"live\" : \"vod\";\n  }\n  return context;\n}\nfunction getClientInfo() {\n  const ua = navigator.userAgent;\n  const platform = navigator.platform;\n  const vendor = navigator.vendor || \"\";\n  const maxTouchPoints = navigator.maxTouchPoints || 0;\n  const memory = navigator.deviceMemory || null;\n  const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n  const screenInfo = {\n    width: screen?.width,\n    height: screen?.height,\n    availWidth: screen?.availWidth,\n    availHeight: screen?.availHeight,\n    orientation: screen?.orientation?.type || \"\",\n    pixelDepth: screen?.pixelDepth\n  };\n  let deviceType = \"desktop\";\n  let brand = \"Unknown\";\n  let os = \"Unknown\";\n  let model = \"\";\n  let isSmartTV = false;\n  let isAndroid = false;\n  let isWebView = false;\n  let isWebApp = false;\n  if (ua.includes(\"Web0S\")) {\n    brand = \"LG\";\n    os = \"webOS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n    const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n    model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n  } else if (ua.includes(\"Tizen\")) {\n    brand = \"Samsung\";\n    os = \"Tizen\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n    const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n    const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n    model = tizenMatch ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim() : \"Tizen TV\";\n  } else if (ua.includes(\"Philips\")) {\n    brand = \"Philips\";\n    os = \"Saphi\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n    brand = \"Sharp\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"Android\") && (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))) {\n    brand = \"Sony\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"Android\") && (ua.includes(\"NetCast\") || ua.includes(\"LG\"))) {\n    brand = \"LG\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n    brand = \"Roku\";\n    os = \"Roku OS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"AppleTV\")) {\n    brand = \"Apple\";\n    os = \"tvOS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  }\n  if (ua.includes(\"Android\")) {\n    isAndroid = true;\n    os = \"Android\";\n    deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n    if (ua.includes(\"Android\") && (maxTouchPoints === 0 || ua.includes(\"Google TV\") || ua.includes(\"XiaoMi\"))) {\n      deviceType = \"tv\";\n      isSmartTV = true;\n      brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n    }\n    const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n    if (androidModelMatch && androidModelMatch[1]) {\n      model = androidModelMatch[1];\n    }\n  }\n  if (/iPad|iPhone|iPod/.test(ua)) {\n    os = \"iOS\";\n    deviceType = \"mobile\";\n    brand = \"Apple\";\n    if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n      deviceType = \"tablet\";\n    }\n  }\n  if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n    if (ua.includes(\"Windows\")) {\n      os = \"Windows\";\n      deviceType = \"desktop\";\n    } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n      os = \"macOS\";\n      deviceType = \"desktop\";\n      if (maxTouchPoints > 1) deviceType = \"tablet\";\n    } else if (ua.includes(\"Linux\")) {\n      os = \"Linux\";\n      deviceType = \"desktop\";\n    }\n  }\n  if (brand === \"Unknown\") {\n    if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n    if (vendor.includes(\"Apple\")) brand = \"Apple\";\n    if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n  }\n  isWebView = /wv|WebView|Linux; U;/.test(ua);\n  if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n    isWebView = true;\n  }\n  isWebApp = window.matchMedia(\"(display-mode: standalone)\").matches || window.navigator.standalone === true || window.screen?.orientation?.angle !== void 0;\n  return {\n    brand,\n    os,\n    model: model || ua.substring(0, 50) + \"...\",\n    deviceType,\n    isSmartTV,\n    isAndroid,\n    isWebView,\n    isWebApp,\n    domain: window.location.hostname,\n    origin: window.location.origin,\n    path: window.location.pathname,\n    userAgent: ua,\n    vendor,\n    platform,\n    screen: screenInfo,\n    hardwareConcurrency,\n    deviceMemory: memory,\n    maxTouchPoints,\n    language: navigator.language,\n    languages: navigator.languages?.join(\",\") || \"\",\n    cookieEnabled: navigator.cookieEnabled,\n    doNotTrack: navigator.doNotTrack || \"\",\n    referrer: document.referrer,\n    visibilityState: document.visibilityState\n  };\n}\nasync function sha256Hex(input) {\n  if (typeof crypto !== \"undefined\" && crypto.subtle?.digest) {\n    try {\n      await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n      let encodedData;\n      if (typeof TextEncoder !== \"undefined\") {\n        encodedData = new TextEncoder().encode(input);\n      } else {\n        const utf8 = unescape(encodeURIComponent(input));\n        const buffer = new Uint8Array(utf8.length);\n        for (let i = 0; i < utf8.length; i++) {\n          buffer[i] = utf8.charCodeAt(i);\n        }\n        encodedData = buffer;\n      }\n      const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n      return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n    } catch {\n      console.warn(\n        \"[StormcloudVideoPlayer] crypto.subtle not supported, using fallback hash\"\n      );\n    }\n  }\n  let hash = 0;\n  for (let i = 0; i < input.length; i++) {\n    const char = input.charCodeAt(i);\n    hash = (hash << 5) - hash + char;\n    hash = hash & hash;\n  }\n  const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n  const timestamp = Date.now().toString(16).padStart(12, \"0\");\n  const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n  return (fallbackHash + timestamp + random).padEnd(64, \"0\");\n}\nfunction resolvePlayerIdentitySeed(clientInfo) {\n  const nativeDeviceId = resolveNativeDeviceId();\n  if (nativeDeviceId) {\n    return `device:${nativeDeviceId}`;\n  }\n  const persistedId = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);\n  if (persistedId) {\n    return `persisted:${persistedId}`;\n  }\n  return `fingerprint:${JSON.stringify(clientInfo)}`;\n}\nasync function getBrowserID(clientInfo) {\n  if (cachedBrowserId) {\n    return cachedBrowserId;\n  }\n  cachedBrowserId = await sha256Hex(resolvePlayerIdentitySeed(clientInfo));\n  return cachedBrowserId;\n}\nfunction canPublish(licenseKey) {\n  return Boolean(isMQTTEnabled() && licenseKey);\n}\nasync function buildPlayerMetricEvent(context = {}, flags = {}) {\n  const clientInfo = getClientInfo();\n  const debugAdTiming = !!context.debugAdTiming;\n  if (debugAdTiming) {\n    console.log(\"[StormcloudVideoPlayer] clientInfo: \", JSON.stringify(clientInfo, null, 2));\n  }\n  const playerId = await getBrowserID(clientInfo);\n  if (debugAdTiming) {\n    console.log(\"[StormcloudVideoPlayer] playerId: \", playerId);\n  }\n  const captureAt = flags.captureAt ?? (/* @__PURE__ */ new Date()).toISOString();\n  return {\n    player_id: playerId,\n    device_type: clientInfo.deviceType,\n    os: clientInfo.os.toLowerCase(),\n    ad_loaded: flags.adLoaded ?? false,\n    ad_detect: flags.adDetect ?? false,\n    capture_at: captureAt,\n    ...context.inputStreamType ? { input_stream_type: context.inputStreamType } : {}\n  };\n}\nfunction publishTracking(licenseKey, channel, body) {\n  ensureMQTTClient();\n  publishMQTT(buildPlayerTopic(licenseKey, channel), body);\n}\nasync function sendInitialTracking(licenseKey, context = {}) {\n  if (!canPublish(licenseKey)) return;\n  try {\n    const metricEvent = await buildPlayerMetricEvent(context, {\n      adLoaded: false,\n      adDetect: false\n    });\n    publishTracking(licenseKey, \"metrics\", {\n      events: [metricEvent]\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n      error\n    );\n  }\n}\nasync function sendAdDetectTracking(licenseKey, adDetectInfo, context = {}) {\n  try {\n    await sendHeartbeat(licenseKey, context, {\n      adDetect: true,\n      captureAt: adDetectInfo.timestamp\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n      error\n    );\n  }\n}\nasync function sendAdLoadedTracking(licenseKey, adLoadedInfo, context = {}) {\n  try {\n    await sendHeartbeat(licenseKey, context, {\n      adLoaded: true,\n      captureAt: adLoadedInfo.timestamp\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n      error\n    );\n  }\n}\nasync function sendAdImpressionTracking(licenseKey, adImpressionInfo, context = {}) {\n  if (!canPublish(licenseKey)) return;\n  try {\n    const metricEvent = await buildPlayerMetricEvent(context, {\n      captureAt: adImpressionInfo.timestamp\n    });\n    publishTracking(licenseKey, \"heartbeat\", metricEvent);\n    publishTracking(licenseKey, \"impressions\", {\n      events: [\n        {\n          player_id: metricEvent.player_id,\n          ad_played_count: 1,\n          ad_url: adImpressionInfo.adUrl,\n          capture_at: adImpressionInfo.timestamp\n        }\n      ]\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n      error\n    );\n  }\n}\nasync function sendHeartbeat(licenseKey, context = {}, flags = {}) {\n  if (!canPublish(licenseKey)) return;\n  try {\n    const heartbeatData = await buildPlayerMetricEvent(context, flags);\n    publishTracking(licenseKey, \"heartbeat\", heartbeatData);\n  } catch (error) {\n    console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n  }\n}\n\n// src/utils/polyfills.ts\nfunction polyfillURLSearchParams() {\n  if (typeof URLSearchParams !== \"undefined\") {\n    return;\n  }\n  class URLSearchParamsPolyfill {\n    constructor(init) {\n      this.params = /* @__PURE__ */ new Map();\n      if (typeof init === \"string\") {\n        this.parseQueryString(init);\n      } else if (init instanceof URLSearchParamsPolyfill) {\n        init.forEach((value, key) => {\n          this.append(key, value);\n        });\n      }\n    }\n    parseQueryString(query) {\n      const cleanQuery = query.startsWith(\"?\") ? query.slice(1) : query;\n      if (!cleanQuery) return;\n      cleanQuery.split(\"&\").forEach((param) => {\n        const [key, value] = param.split(\"=\");\n        if (key) {\n          const decodedKey = this.safeDecodeURIComponent(key);\n          const decodedValue = value ? this.safeDecodeURIComponent(value) : \"\";\n          this.append(decodedKey, decodedValue);\n        }\n      });\n    }\n    safeDecodeURIComponent(str) {\n      try {\n        return decodeURIComponent(str.replace(/\\+/g, \" \"));\n      } catch (e) {\n        return str;\n      }\n    }\n    append(name, value) {\n      const values = this.params.get(name) || [];\n      values.push(String(value));\n      this.params.set(name, values);\n    }\n    delete(name) {\n      this.params.delete(name);\n    }\n    get(name) {\n      const values = this.params.get(name);\n      return values && values.length > 0 && values[0] !== void 0 ? values[0] : null;\n    }\n    getAll(name) {\n      return this.params.get(name) || [];\n    }\n    has(name) {\n      return this.params.has(name);\n    }\n    set(name, value) {\n      this.params.set(name, [String(value)]);\n    }\n    forEach(callback) {\n      this.params.forEach((values, key) => {\n        values.forEach((value) => {\n          callback(value, key, this);\n        });\n      });\n    }\n    toString() {\n      const parts = [];\n      this.params.forEach((values, key) => {\n        values.forEach((value) => {\n          parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\n        });\n      });\n      return parts.join(\"&\");\n    }\n  }\n  window.URLSearchParams = URLSearchParamsPolyfill;\n}\nfunction polyfillTextEncoder() {\n  if (typeof TextEncoder !== \"undefined\") {\n    return;\n  }\n  class TextEncoderPolyfill {\n    constructor() {\n      this.encoding = \"utf-8\";\n    }\n    encode(str) {\n      const utf8 = [];\n      for (let i = 0; i < str.length; i++) {\n        let charcode = str.charCodeAt(i);\n        if (charcode < 128) {\n          utf8.push(charcode);\n        } else if (charcode < 2048) {\n          utf8.push(192 | charcode >> 6, 128 | charcode & 63);\n        } else if (charcode < 55296 || charcode >= 57344) {\n          utf8.push(\n            224 | charcode >> 12,\n            128 | charcode >> 6 & 63,\n            128 | charcode & 63\n          );\n        } else {\n          i++;\n          charcode = 65536 + ((charcode & 1023) << 10 | str.charCodeAt(i) & 1023);\n          utf8.push(\n            240 | charcode >> 18,\n            128 | charcode >> 12 & 63,\n            128 | charcode >> 6 & 63,\n            128 | charcode & 63\n          );\n        }\n      }\n      return new Uint8Array(utf8);\n    }\n  }\n  window.TextEncoder = TextEncoderPolyfill;\n}\nfunction polyfillPromiseFinally() {\n  if (typeof Promise !== \"undefined\" && !Promise.prototype.finally) {\n    Promise.prototype.finally = function(callback) {\n      const constructor = this.constructor;\n      return this.then(\n        (value) => constructor.resolve(callback()).then(() => value),\n        (reason) => constructor.resolve(callback()).then(() => {\n          throw reason;\n        })\n      );\n    };\n  }\n}\nfunction polyfillObjectAssign() {\n  if (typeof Object.assign !== \"function\") {\n    Object.assign = function(target, ...sources) {\n      if (target == null) {\n        throw new TypeError(\"Cannot convert undefined or null to object\");\n      }\n      const to = Object(target);\n      for (let i = 0; i < sources.length; i++) {\n        const nextSource = sources[i];\n        if (nextSource != null) {\n          for (const nextKey in nextSource) {\n            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n              to[nextKey] = nextSource[nextKey];\n            }\n          }\n        }\n      }\n      return to;\n    };\n  }\n}\nfunction polyfillArrayFrom() {\n  if (!Array.from) {\n    Array.from = function(arrayLike, mapFn, thisArg) {\n      const items = Object(arrayLike);\n      if (arrayLike == null) {\n        throw new TypeError(\"Array.from requires an array-like object\");\n      }\n      const len = items.length >>> 0;\n      const result = new Array(len);\n      for (let i = 0; i < len; i++) {\n        if (mapFn) {\n          result[i] = mapFn.call(thisArg, items[i], i);\n        } else {\n          result[i] = items[i];\n        }\n      }\n      return result;\n    };\n  }\n}\nfunction polyfillStringStartsWith() {\n  if (!String.prototype.startsWith) {\n    String.prototype.startsWith = function(search, pos) {\n      pos = !pos || pos < 0 ? 0 : +pos;\n      return this.substring(pos, pos + search.length) === search;\n    };\n  }\n}\nfunction polyfillStringEndsWith() {\n  if (!String.prototype.endsWith) {\n    String.prototype.endsWith = function(search, length) {\n      if (length === void 0 || length > this.length) {\n        length = this.length;\n      }\n      return this.substring(length - search.length, length) === search;\n    };\n  }\n}\nfunction polyfillStringIncludes() {\n  if (!String.prototype.includes) {\n    String.prototype.includes = function(search, start) {\n      if (typeof start !== \"number\") {\n        start = 0;\n      }\n      if (start + search.length > this.length) {\n        return false;\n      }\n      return this.indexOf(search, start) !== -1;\n    };\n  }\n}\nfunction initializePolyfills() {\n  polyfillObjectAssign();\n  polyfillArrayFrom();\n  polyfillStringStartsWith();\n  polyfillStringEndsWith();\n  polyfillStringIncludes();\n  polyfillURLSearchParams();\n  polyfillTextEncoder();\n  polyfillPromiseFinally();\n}\n\n// src/utils/vastMacros.ts\nvar UNEXPANDED_MACRO_PATTERN = /^(\\[[^\\]]*\\]|\\{[^}]*\\}|%%[^%]*%%)$/;\nvar INVALID_VAST_PARAM_KEY = /^\\s|\\s$/;\nvar EXAMPLE_COM_URL = /example\\.com/i;\nvar CTV_UNSUPPORTED_PARAMS = [\n  \"description_url\",\n  \"tfcd\",\n  \"npa\",\n  \"min_ad_duration\",\n  \"max_ad_duration\",\n  \"unviewed_position_start\",\n  \"impl\",\n  \"vad_type\",\n  \"gdpr\",\n  \"gdpr_consent\",\n  \"us_privacy\"\n];\nvar INLINE_DEVICE_MACRO_REPLACEMENTS = [\n  { pattern: /\\[RDID\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[IFA\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[ADVERTISING[_-]?ID(?:ENTIFIER)?\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[DEVICE[_-]?ID\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[IDTYPE\\]/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /\\{rdid\\}/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\{device[_-]?id\\}/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\{idtype\\}/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /%%ADVERTISING_IDENTIFIER_PLAIN%%/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /%%ADVERTISING_ID_OPT_OUT%%/gi, getValue: (ctx) => ctx.limitAdTracking != null ? ctx.limitAdTracking ? \"1\" : \"0\" : void 0 },\n  { pattern: /%%ADVERTISING_ID_TYPE%%/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /%%ADVERTISING_ID%%/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /%%LIMIT_AD_TRACKING%%/gi, getValue: (ctx) => ctx.limitAdTracking != null ? ctx.limitAdTracking ? \"1\" : \"0\" : void 0 },\n  { pattern: /%%MSID%%/gi, getValue: (ctx) => ctx.appId },\n  { pattern: /%%APP_NAME%%/gi, getValue: (ctx) => ctx.appName },\n  { pattern: /%%SESSION_ID%%/gi, getValue: (ctx) => ctx.sessionId },\n  { pattern: /%%CORRELATOR%%/gi, getValue: (ctx) => ctx.correlator }\n];\nfunction isMacroPlaceholder2(value) {\n  if (value == null) return true;\n  const trimmed = value.trim();\n  if (!trimmed) return true;\n  if (UNEXPANDED_MACRO_PATTERN.test(trimmed)) return true;\n  return /^(unknown|null|undefined|none|n\\/a|\\$\\{[^}]+\\})$/i.test(trimmed);\n}\nfunction generateCorrelator() {\n  if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n    try {\n      const buf = new Uint32Array(2);\n      crypto.getRandomValues(buf);\n      const value = (buf[0] ?? 0) * 2097152 + ((buf[1] ?? 0) & 2097151);\n      if (value > 0) {\n        return String(value);\n      }\n    } catch {\n    }\n  }\n  return String(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER) + 1);\n}\nfunction expandInlineMacroPlaceholders(baseUrl, ctx) {\n  let url = baseUrl;\n  for (const { pattern, getValue } of INLINE_DEVICE_MACRO_REPLACEMENTS) {\n    const value = getValue(ctx);\n    if (value != null && value !== \"\") {\n      url = url.replace(pattern, encodeURIComponent(value));\n    }\n  }\n  return url;\n}\nfunction applyDeviceIdentityParams(params, ctx) {\n  const runtimeId = ctx.deviceId?.trim();\n  const runtimeType = ctx.deviceIdType?.trim() || inferDeviceIdType();\n  const tagRdid = params.get(\"rdid\");\n  const tagType = params.get(\"idtype\");\n  const tagLat = params.get(\"is_lat\");\n  const latValue = ctx.limitAdTracking != null ? ctx.limitAdTracking ? \"1\" : \"0\" : void 0;\n  if (runtimeId) {\n    params.set(\"rdid\", runtimeId);\n    params.set(\"idtype\", runtimeType || tagType || \"aaid\");\n    params.set(\"is_lat\", latValue ?? (isMacroPlaceholder2(tagLat) ? \"0\" : tagLat));\n    return;\n  }\n  const tagRdidValid = Boolean(tagRdid && !isMacroPlaceholder2(tagRdid));\n  const tagTypeValid = Boolean(tagType && !isMacroPlaceholder2(tagType));\n  if (tagRdidValid && tagTypeValid && runtimeType && !isEquivalentDeviceIdType(tagType, runtimeType)) {\n    params.delete(\"rdid\");\n    params.delete(\"idtype\");\n    params.delete(\"is_lat\");\n    return;\n  }\n  if (tagRdidValid) {\n    if (isMacroPlaceholder2(tagType) && runtimeType) {\n      params.set(\"idtype\", runtimeType);\n    }\n    if (isMacroPlaceholder2(tagLat)) {\n      params.set(\"is_lat\", latValue ?? \"0\");\n    }\n    return;\n  }\n  params.delete(\"rdid\");\n  params.delete(\"idtype\");\n  params.delete(\"is_lat\");\n}\nfunction removeBrokenAppNameOrphans(params, appName) {\n  const toDelete = [];\n  params.forEach((_value, key) => {\n    if (!key || INVALID_VAST_PARAM_KEY.test(key)) {\n      toDelete.push(key);\n    }\n  });\n  if (appName && appName.includes(\"&\")) {\n    for (const suffix of appName.split(\"&\").slice(1)) {\n      const trimmed = suffix.trimStart();\n      if (!trimmed) continue;\n      toDelete.push(suffix, ` ${trimmed}`, trimmed);\n    }\n  }\n  for (const key of new Set(toDelete)) {\n    if (key) params.delete(key);\n  }\n}\nfunction normalizeVastTagUrl(raw) {\n  if (!raw) return raw;\n  try {\n    const url = new URL(raw);\n    const anValue = url.searchParams.get(\"an\");\n    if (anValue !== null) {\n      const orphanFragments = [];\n      url.searchParams.forEach((_value, key) => {\n        if (key && INVALID_VAST_PARAM_KEY.test(key)) {\n          orphanFragments.push(key.trim());\n        }\n      });\n      if (orphanFragments.length > 0) {\n        const reconstructed = [anValue.trimEnd(), ...orphanFragments].filter(Boolean).join(\" & \");\n        url.searchParams.forEach((_value, key) => {\n          if (key && INVALID_VAST_PARAM_KEY.test(key)) {\n            url.searchParams.delete(key);\n          }\n        });\n        url.searchParams.set(\"an\", reconstructed);\n        return url.toString().replace(\n          /([?&]an=)([^&]*)/,\n          (_match, prefix, val) => prefix + val.replace(/\\+/g, \"%20\")\n        );\n      }\n    }\n    removeBrokenAppNameOrphans(url.searchParams);\n    return url.toString();\n  } catch {\n    return raw;\n  }\n}\nfunction applyVastMacros(baseUrl, ctx) {\n  const expandedUrl = expandInlineMacroPlaceholders(baseUrl, ctx);\n  let url;\n  try {\n    url = new URL(normalizeVastTagUrl(expandedUrl));\n  } catch {\n    return replaceCorrelatorFallback(expandedUrl, ctx.correlator);\n  }\n  const params = url.searchParams;\n  removeBrokenAppNameOrphans(params, ctx.appName);\n  params.set(\"correlator\", ctx.correlator);\n  params.set(\"scor\", ctx.streamCorrelator);\n  if (ctx.isCtv) {\n    for (const key of CTV_UNSUPPORTED_PARAMS) {\n      params.delete(key);\n    }\n  }\n  if (ctx.pod != null) {\n    params.set(\"pod\", String(ctx.pod));\n  }\n  params.delete(\"ppos\");\n  params.delete(\"lip\");\n  if (ctx.podMinDurationMs != null) {\n    params.set(\"pmnd\", String(Math.max(0, Math.round(ctx.podMinDurationMs))));\n  }\n  if (ctx.podMaxDurationMs != null) {\n    params.set(\"pmxd\", String(Math.max(0, Math.round(ctx.podMaxDurationMs))));\n  }\n  if (ctx.podMaxAds != null) {\n    params.set(\"pmad\", String(Math.max(1, Math.round(ctx.podMaxAds))));\n  }\n  const requestUrl = ctx.contentUrl || ctx.pageUrl;\n  if (requestUrl) {\n    params.set(\"url\", requestUrl);\n    if (!ctx.isCtv) {\n      params.set(\"description_url\", requestUrl);\n    }\n  } else {\n    const existingUrl = params.get(\"url\") || \"\";\n    if (EXAMPLE_COM_URL.test(existingUrl)) {\n      params.delete(\"url\");\n      params.delete(\"description_url\");\n    }\n  }\n  if (ctx.adWillPlayMuted != null) {\n    params.set(\"vpmute\", ctx.adWillPlayMuted ? \"1\" : \"0\");\n  }\n  if (ctx.adWillAutoPlay != null) {\n    params.set(\"vpa\", ctx.adWillAutoPlay ? \"auto\" : \"click\");\n  }\n  if (ctx.appId) {\n    params.set(\"msid\", ctx.appId);\n  }\n  if (ctx.appName) {\n    removeBrokenAppNameOrphans(params, ctx.appName);\n    params.set(\"an\", ctx.appName);\n  }\n  if (ctx.sessionId) {\n    params.set(\"sid\", ctx.sessionId);\n  }\n  if (ctx.deviceTypeHint != null) {\n    params.set(\"dth\", String(ctx.deviceTypeHint));\n  } else if (ctx.isCtv) {\n    params.set(\"dth\", \"5\");\n  }\n  applyDeviceIdentityParams(params, ctx);\n  if (!ctx.isCtv) {\n    const consent = ctx.consent;\n    if (consent?.gdpr != null) {\n      params.set(\"gdpr\", consent.gdpr);\n    }\n    if (consent?.gdprConsent != null) {\n      params.set(\"gdpr_consent\", consent.gdprConsent);\n    }\n    if (consent?.usPrivacy != null) {\n      params.set(\"us_privacy\", consent.usPrivacy);\n    }\n  }\n  if (ctx.adTest) {\n    params.set(\"adtest\", \"on\");\n  }\n  const staleKeys = [];\n  params.forEach((value, key) => {\n    if (isMacroPlaceholder2(value)) {\n      staleKeys.push(key);\n    }\n  });\n  for (const key of staleKeys) {\n    params.delete(key);\n  }\n  removeBrokenAppNameOrphans(params, ctx.appName);\n  return url.toString();\n}\nfunction replaceCorrelatorFallback(baseUrl, correlator) {\n  const correlatorRegex = /([?&])correlator=([^&]*)/;\n  if (correlatorRegex.test(baseUrl)) {\n    return baseUrl.replace(correlatorRegex, `$1correlator=${correlator}`);\n  }\n  const sep = baseUrl.includes(\"?\") ? \"&\" : \"?\";\n  return `${baseUrl}${sep}correlator=${correlator}`;\n}\nfunction fetchConsentSignals(timeoutMs = 1500) {\n  const signals = {};\n  if (typeof window === \"undefined\") {\n    return Promise.resolve(signals);\n  }\n  const tasks = [];\n  const tcfApi = window.__tcfapi;\n  if (typeof tcfApi === \"function\") {\n    tasks.push(\n      new Promise((resolve) => {\n        let settled = false;\n        try {\n          tcfApi(\"addEventListener\", 2, (tcData, success) => {\n            if (settled) return;\n            if (success && tcData && (tcData.eventStatus === \"tcloaded\" || tcData.eventStatus === \"useractioncomplete\")) {\n              settled = true;\n              signals.gdpr = tcData.gdprApplies ? \"1\" : \"0\";\n              if (typeof tcData.tcString === \"string\" && tcData.tcString) {\n                signals.gdprConsent = tcData.tcString;\n              }\n              try {\n                tcfApi(\"removeEventListener\", 2, () => {\n                }, tcData.listenerId);\n              } catch {\n              }\n              resolve();\n            }\n          });\n        } catch {\n          resolve();\n        }\n        setTimeout(() => {\n          if (!settled) {\n            settled = true;\n            resolve();\n          }\n        }, timeoutMs);\n      })\n    );\n  }\n  const uspApi = window.__uspapi;\n  if (typeof uspApi === \"function\") {\n    tasks.push(\n      new Promise((resolve) => {\n        try {\n          uspApi(\"getUSPData\", 1, (data, success) => {\n            if (success && typeof data?.uspString === \"string\" && data.uspString) {\n              signals.usPrivacy = data.uspString;\n            }\n            resolve();\n          });\n        } catch {\n          resolve();\n        }\n        setTimeout(resolve, timeoutMs);\n      })\n    );\n  }\n  if (tasks.length === 0) {\n    return Promise.resolve(signals);\n  }\n  return Promise.all(tasks).then(() => signals);\n}\n\n// src/utils/browserCompat.ts\nfunction getChromeVersion(ua) {\n  const match = ua.match(/Chrome\\/(\\d+)/);\n  return match && match[1] ? parseInt(match[1], 10) : 0;\n}\nfunction getWebKitVersion(ua) {\n  const match = ua.match(/AppleWebKit\\/(\\d+)/);\n  return match && match[1] ? parseInt(match[1], 10) : 0;\n}\nfunction getPlatform() {\n  if (\"userAgentData\" in navigator && navigator.userAgentData?.platform) {\n    return navigator.userAgentData.platform;\n  }\n  const ua = navigator.userAgent;\n  if (/Mac|iPhone|iPad|iPod/i.test(ua)) {\n    return /iPhone|iPad|iPod/i.test(ua) ? \"iPhone\" : \"MacIntel\";\n  }\n  if (/Win/i.test(ua)) {\n    return \"Win32\";\n  }\n  if (/Linux/i.test(ua)) {\n    return /Android/i.test(ua) ? \"Linux armv8l\" : \"Linux x86_64\";\n  }\n  if (/CrOS/i.test(ua)) {\n    return \"CrOS\";\n  }\n  return navigator.platform || \"Unknown\";\n}\nfunction detectBrowser() {\n  const ua = navigator.userAgent;\n  const platform = getPlatform();\n  let name = \"Unknown\";\n  let version = \"0\";\n  let majorVersion = 0;\n  let isSmartTV = false;\n  let isLegacyTV = false;\n  let supportsModernJS = true;\n  let webOSVersion;\n  let tizenVersion;\n  let chromeVersionNum;\n  const chromeVersion = getChromeVersion(ua);\n  const webkitVersion = getWebKitVersion(ua);\n  chromeVersionNum = chromeVersion > 0 ? chromeVersion : void 0;\n  if (/Web0S|webOS|LG Browser|LGSTB/i.test(ua)) {\n    name = \"LG WebOS\";\n    isSmartTV = true;\n    let match = ua.match(/Web0S[/\\s]*([\\d.]+)/i) || ua.match(/webOS[/\\s]*([\\d.]+)/i);\n    if (!match || !match[1]) {\n      match = ua.match(/webOSTV[/\\s-]*([\\d.]+)/i) || ua.match(/webOS\\.TV[/\\s-]*([\\d.]+)/i);\n    }\n    if (match && match[1]) {\n      version = match[1];\n      const parts = version.split(\".\");\n      majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n      webOSVersion = majorVersion;\n    } else if (chromeVersion > 0) {\n      if (chromeVersion >= 79) {\n        webOSVersion = 6;\n        version = \"6.0\";\n        majorVersion = 6;\n      } else if (chromeVersion >= 68) {\n        webOSVersion = 5;\n        version = \"5.0\";\n        majorVersion = 5;\n      } else if (chromeVersion >= 53) {\n        webOSVersion = 4;\n        version = \"4.0\";\n        majorVersion = 4;\n      } else if (chromeVersion >= 38) {\n        webOSVersion = 3;\n        version = \"3.0\";\n        majorVersion = 3;\n      } else {\n        webOSVersion = 2;\n        version = \"2.0\";\n        majorVersion = 2;\n      }\n    } else {\n      version = \"Unknown\";\n      webOSVersion = void 0;\n    }\n    isLegacyTV = webOSVersion !== void 0 && webOSVersion < 3;\n  } else if (/Tizen/i.test(ua)) {\n    name = \"Samsung Tizen\";\n    isSmartTV = true;\n    const match = ua.match(/Tizen[/\\s]*([\\d.]+)/i);\n    version = match && match[1] ? match[1] : \"Unknown\";\n    if (version !== \"Unknown\") {\n      const parts = version.split(\".\");\n      majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n      tizenVersion = majorVersion;\n    }\n    isLegacyTV = tizenVersion !== void 0 && tizenVersion < 3;\n  } else if (/SMART-TV|SmartTV/i.test(ua)) {\n    name = \"Smart TV\";\n    isSmartTV = true;\n    isLegacyTV = chromeVersion > 0 && chromeVersion < 53;\n  } else if (/NetCast/i.test(ua)) {\n    name = \"LG NetCast\";\n    isSmartTV = true;\n    isLegacyTV = true;\n  } else if (/BRAVIA/i.test(ua)) {\n    name = \"Sony BRAVIA\";\n    isSmartTV = true;\n    isLegacyTV = chromeVersion > 0 && chromeVersion < 53;\n  } else {\n    if (chromeVersion > 0) {\n      name = \"Chrome\";\n      version = chromeVersion.toString();\n      majorVersion = chromeVersion;\n      if (chromeVersion < 50) {\n        supportsModernJS = false;\n      }\n    }\n    if (webkitVersion > 0 && webkitVersion < 600) {\n      supportsModernJS = false;\n    }\n  }\n  if (typeof Promise === \"undefined\" || typeof Map === \"undefined\" || typeof Set === \"undefined\") {\n    supportsModernJS = false;\n  }\n  if (typeof URLSearchParams === \"undefined\") {\n    supportsModernJS = false;\n  }\n  return {\n    name,\n    version,\n    majorVersion,\n    isSmartTV,\n    isLegacyTV,\n    platform,\n    supportsModernJS,\n    webOSVersion,\n    tizenVersion,\n    chromeVersion: chromeVersionNum\n  };\n}\nfunction getBrowserConfigOverrides() {\n  const browser = detectBrowser();\n  const overrides = {};\n  if (browser.isSmartTV) {\n    overrides.allowNativeHls = true;\n  }\n  return overrides;\n}\nfunction logBrowserInfo(debug = false) {\n  if (!debug) return;\n  const browser = detectBrowser();\n  console.log(\"[StormcloudVideoPlayer] Browser Compatibility Info:\", {\n    browser: `${browser.name} ${browser.version}`,\n    platform: browser.platform,\n    isSmartTV: browser.isSmartTV,\n    isLegacyTV: browser.isLegacyTV,\n    supportsModernJS: browser.supportsModernJS,\n    ...browser.webOSVersion !== void 0 ? { webOSVersion: browser.webOSVersion } : {},\n    ...browser.tizenVersion !== void 0 ? { tizenVersion: browser.tizenVersion } : {},\n    ...browser.chromeVersion !== void 0 ? { chromeVersion: browser.chromeVersion } : {},\n    userAgent: navigator.userAgent\n  });\n}\n\n// src/player/Scte35Parser.ts\nfunction parseCueOutDuration(value) {\n  const num = parseFloat(value.trim());\n  if (!Number.isNaN(num)) return num;\n  const match = value.match(/(?:^|[,\\s])DURATION\\s*=\\s*([0-9.]+)/i) || value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n  if (match && match[1] != null) {\n    const dStr = match[1];\n    const d = parseFloat(dStr);\n    return Number.isNaN(d) ? void 0 : d;\n  }\n  return void 0;\n}\nfunction parseCueOutCont(value) {\n  const res = {};\n  const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n  const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n  if (elapsedMatch && elapsedMatch[1] != null) {\n    const e = parseFloat(elapsedMatch[1]);\n    if (!Number.isNaN(e)) res.elapsed = e;\n  }\n  if (durationMatch && durationMatch[1] != null) {\n    const d = parseFloat(durationMatch[1]);\n    if (!Number.isNaN(d)) res.duration = d;\n  }\n  if (!(\"elapsed\" in res) || !(\"duration\" in res)) {\n    const slashMatch = value.match(/([0-9.]+)\\s*\\/\\s*([0-9.]+)/);\n    if (slashMatch && slashMatch[1] && slashMatch[2]) {\n      const elapsed = parseFloat(slashMatch[1]);\n      const duration = parseFloat(slashMatch[2]);\n      if (!Number.isNaN(elapsed) && !(\"elapsed\" in res)) res.elapsed = elapsed;\n      if (!Number.isNaN(duration) && !(\"duration\" in res)) res.duration = duration;\n    }\n  }\n  if (\"elapsed\" in res || \"duration\" in res) return res;\n  return void 0;\n}\nfunction parseAttributeList(value) {\n  const attrs = {};\n  const regex = /([A-Z0-9-]+)=((\"[^\"]*\")|([^\",]*))(?:,|$)/gi;\n  let match;\n  while ((match = regex.exec(value)) !== null) {\n    const key = match[1] ?? \"\";\n    let rawVal = match[3] ?? match[4] ?? \"\";\n    if (rawVal.startsWith('\"') && rawVal.endsWith('\"')) {\n      rawVal = rawVal.slice(1, -1);\n    }\n    if (key) {\n      attrs[key] = rawVal;\n    }\n  }\n  return attrs;\n}\nfunction toNumber(val) {\n  if (val == null) return void 0;\n  const n = typeof val === \"string\" ? parseFloat(val) : Number(val);\n  return Number.isNaN(n) ? void 0 : n;\n}\nfunction isManifestBasedMarker(marker) {\n  const raw = marker.raw;\n  if (!raw) return false;\n  if (raw.tag) {\n    const tag = String(raw.tag);\n    return tag.includes(\"EXT-X-CUE-OUT\") || tag.includes(\"EXT-X-CUE-IN\") || tag.includes(\"EXT-X-DATERANGE\");\n  }\n  if (raw.id3) return false;\n  if (raw.splice_command_type) return false;\n  return false;\n}\nfunction decodeId3ValueToText(value) {\n  try {\n    if (typeof value === \"string\") return value;\n    const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n    const text = decoder.decode(value);\n    if (text && /[\\x20-\\x7E]/.test(text)) return text;\n    let out = \"\";\n    for (let i = 0; i < value.length; i++)\n      out += String.fromCharCode(value[i]);\n    return out;\n  } catch {\n    return void 0;\n  }\n}\nfunction getFragmentStartSeconds(frag) {\n  const candidates = [frag?.start, frag?.startPTS];\n  for (const candidate of candidates) {\n    if (typeof candidate === \"number\" && Number.isFinite(candidate)) {\n      return candidate;\n    }\n  }\n  return void 0;\n}\nfunction parseScte35FromId3(tag) {\n  const text = decodeId3ValueToText(tag.value);\n  if (!text) return void 0;\n  const cueOutMatch = text.match(/EXT-X-CUE-OUT(?::([^\\r\\n]*))?/i) || text.match(/CUE-OUT(?::([^\\r\\n]*))?/i);\n  if (cueOutMatch) {\n    const arg = (cueOutMatch[1] ?? \"\").trim();\n    const dur = parseCueOutDuration(arg);\n    const marker = {\n      type: \"start\",\n      ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n      ...dur !== void 0 ? { durationSeconds: dur } : {},\n      raw: { id3: text }\n    };\n    return marker;\n  }\n  const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\\r\\n]*)/i);\n  if (cueOutContMatch) {\n    const arg = (cueOutContMatch[1] ?? \"\").trim();\n    const cont = parseCueOutCont(arg);\n    const marker = {\n      type: \"progress\",\n      ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n      ...cont?.duration !== void 0 ? { durationSeconds: cont.duration } : {},\n      raw: { id3: text }\n    };\n    return marker;\n  }\n  const cueInMatch = text.match(/EXT-X-CUE-IN\\b/i) || text.match(/CUE-IN\\b/i);\n  if (cueInMatch) {\n    const marker = {\n      type: \"end\",\n      ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n      raw: { id3: text }\n    };\n    return marker;\n  }\n  const daterangeMatch = text.match(/EXT-X-DATERANGE:([^\\r\\n]*)/i);\n  if (daterangeMatch) {\n    const attrs = parseAttributeList(daterangeMatch[1] ?? \"\");\n    const hasScteOut = \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== void 0;\n    const hasScteIn = \"SCTE35-IN\" in attrs || attrs[\"SCTE35-IN\"] !== void 0;\n    const klass = String(attrs[\"CLASS\"] ?? \"\");\n    const duration = toNumber(attrs[\"DURATION\"]);\n    if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n      const marker = {\n        type: \"start\",\n        ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n        ...duration !== void 0 ? { durationSeconds: duration } : {},\n        raw: { id3: text, attrs }\n      };\n      return marker;\n    }\n    if (hasScteIn) {\n      const marker = {\n        type: \"end\",\n        ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n        raw: { id3: text, attrs }\n      };\n      return marker;\n    }\n  }\n  if (/SCTE35-OUT/i.test(text)) {\n    const marker = {\n      type: \"start\",\n      ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n      raw: { id3: text }\n    };\n    return marker;\n  }\n  if (/SCTE35-IN/i.test(text)) {\n    const marker = {\n      type: \"end\",\n      ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n      raw: { id3: text }\n    };\n    return marker;\n  }\n  if (tag.value instanceof Uint8Array) {\n    const bin = parseScte35Binary(tag.value);\n    if (bin) return bin;\n  }\n  return void 0;\n}\nfunction normalizeFragmentPayload(payload) {\n  if (payload instanceof Uint8Array) {\n    return payload;\n  }\n  if (payload instanceof ArrayBuffer) {\n    return new Uint8Array(payload);\n  }\n  if (ArrayBuffer.isView(payload)) {\n    const view = payload;\n    return new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n  }\n  return void 0;\n}\nfunction detectTsPacketFormat(data) {\n  const packetSizes = [188, 192, 204];\n  for (const packetSize of packetSizes) {\n    const tsPayloadOffset = packetSize === 192 ? 4 : 0;\n    for (let offset = 0; offset < packetSize; offset++) {\n      let matchedPackets = 0;\n      for (let packetStart = offset; packetStart + tsPayloadOffset < data.length && matchedPackets < 5; packetStart += packetSize) {\n        if (data[packetStart + tsPayloadOffset] !== 71) {\n          break;\n        }\n        matchedPackets++;\n      }\n      if (matchedPackets >= 2) {\n        return { offset, packetSize, tsPayloadOffset };\n      }\n    }\n  }\n  return void 0;\n}\nfunction getPsiSectionStart(payload, payloadUnitStart) {\n  if (!payloadUnitStart) {\n    return void 0;\n  }\n  const pointerField = payload[0];\n  if (pointerField == null) {\n    return void 0;\n  }\n  const sectionStart = 1 + pointerField;\n  return sectionStart < payload.length ? sectionStart : void 0;\n}\nfunction getPsiSectionLength(data, offset) {\n  return ((data[offset + 1] ?? 0) & 15) << 8 | (data[offset + 2] ?? 0);\n}\nfunction parsePatSection(payload, payloadUnitStart, pmtPids) {\n  const sectionStart = getPsiSectionStart(payload, payloadUnitStart);\n  if (sectionStart == null || sectionStart + 8 >= payload.length) {\n    return;\n  }\n  if (payload[sectionStart] !== 0) {\n    return;\n  }\n  const sectionLength = getPsiSectionLength(payload, sectionStart);\n  const sectionEnd = Math.min(\n    payload.length,\n    sectionStart + 3 + sectionLength\n  );\n  for (let offset = sectionStart + 8; offset + 4 <= sectionEnd - 4; offset += 4) {\n    const programNumber = (payload[offset] ?? 0) << 8 | (payload[offset + 1] ?? 0);\n    const pid = ((payload[offset + 2] ?? 0) & 31) << 8 | (payload[offset + 3] ?? 0);\n    if (programNumber !== 0) {\n      pmtPids.add(pid);\n    }\n  }\n}\nfunction descriptorsIdentifyScte35(data, start, end) {\n  let offset = start;\n  while (offset + 2 <= end) {\n    const tag = data[offset] ?? 0;\n    const length = data[offset + 1] ?? 0;\n    const descriptorStart = offset + 2;\n    const descriptorEnd = descriptorStart + length;\n    if (descriptorEnd > end) {\n      return false;\n    }\n    const registration = length >= 4 ? String.fromCharCode(\n      data[descriptorStart] ?? 0,\n      data[descriptorStart + 1] ?? 0,\n      data[descriptorStart + 2] ?? 0,\n      data[descriptorStart + 3] ?? 0\n    ) : \"\";\n    if (tag === 138 || registration === \"CUEI\" || registration === \"SCTE\") {\n      return true;\n    }\n    offset = descriptorEnd;\n  }\n  return false;\n}\nfunction parsePmtSection(payload, payloadUnitStart, tsScte35Pids) {\n  const sectionStart = getPsiSectionStart(payload, payloadUnitStart);\n  if (sectionStart == null || sectionStart + 12 >= payload.length) {\n    return;\n  }\n  if (payload[sectionStart] !== 2) {\n    return;\n  }\n  const sectionLength = getPsiSectionLength(payload, sectionStart);\n  const sectionEnd = Math.min(\n    payload.length,\n    sectionStart + 3 + sectionLength\n  );\n  const programInfoLength = ((payload[sectionStart + 10] ?? 0) & 15) << 8 | (payload[sectionStart + 11] ?? 0);\n  let offset = sectionStart + 12 + programInfoLength;\n  while (offset + 5 <= sectionEnd - 4) {\n    const streamType = payload[offset] ?? 0;\n    const elementaryPid = ((payload[offset + 1] ?? 0) & 31) << 8 | (payload[offset + 2] ?? 0);\n    const esInfoLength = ((payload[offset + 3] ?? 0) & 15) << 8 | (payload[offset + 4] ?? 0);\n    const descriptorStart = offset + 5;\n    const descriptorEnd = Math.min(descriptorStart + esInfoLength, sectionEnd - 4);\n    if (streamType === 134 || streamType === 6 && descriptorsIdentifyScte35(payload, descriptorStart, descriptorEnd)) {\n      tsScte35Pids.add(elementaryPid);\n    }\n    offset = descriptorStart + esInfoLength;\n  }\n}\nfunction hasProcessedTsScte35Section(section, processedSections) {\n  let checksum = 0;\n  for (let i = 0; i < section.length; i++) {\n    checksum = checksum * 31 + (section[i] ?? 0) >>> 0;\n  }\n  const key = `${section.length}:${checksum}`;\n  if (processedSections.has(key)) {\n    return true;\n  }\n  processedSections.add(key);\n  if (processedSections.size > 200) {\n    const firstKey = processedSections.values().next().value;\n    if (firstKey) {\n      processedSections.delete(firstKey);\n    }\n  }\n  return false;\n}\nfunction addScte35SectionMarker(section, markers, processedSections) {\n  if (section[0] !== 252 || hasProcessedTsScte35Section(section, processedSections)) {\n    return;\n  }\n  const marker = parseScte35Binary(section);\n  if (!marker) {\n    return;\n  }\n  marker.raw = {\n    ...typeof marker.raw === \"object\" && marker.raw ? marker.raw : {},\n    source: \"ts-packet\"\n  };\n  markers.push(marker);\n}\nfunction appendScte35Bytes(pid, bytes, assemblers, markers, processedSections) {\n  const assembler = assemblers.get(pid);\n  if (!assembler) {\n    return;\n  }\n  for (let i = 0; i < bytes.length && assembler.bytes.length < assembler.expectedLength; i++) {\n    assembler.bytes.push(bytes[i] ?? 0);\n  }\n  if (assembler.bytes.length >= assembler.expectedLength) {\n    assemblers.delete(pid);\n    addScte35SectionMarker(new Uint8Array(assembler.bytes), markers, processedSections);\n  }\n}\nfunction collectScte35SectionsFromPayload(pid, payload, payloadUnitStart, assemblers, markers, processedSections) {\n  if (payload.length === 0) {\n    return;\n  }\n  let offset = 0;\n  if (payloadUnitStart) {\n    const pointerField = payload[0] ?? 0;\n    const previousAssembler = assemblers.get(pid);\n    if (previousAssembler && pointerField > 0) {\n      appendScte35Bytes(\n        pid,\n        payload.subarray(1, Math.min(1 + pointerField, payload.length)),\n        assemblers,\n        markers,\n        processedSections\n      );\n    }\n    assemblers.delete(pid);\n    offset = 1 + pointerField;\n  } else {\n    appendScte35Bytes(pid, payload, assemblers, markers, processedSections);\n    return;\n  }\n  while (offset + 3 <= payload.length) {\n    const tableId = payload[offset];\n    if (tableId == null || tableId === 255) {\n      return;\n    }\n    const sectionLength = getPsiSectionLength(payload, offset);\n    const totalLength = 3 + sectionLength;\n    if (sectionLength <= 0 || totalLength <= 3) {\n      return;\n    }\n    if (offset + totalLength <= payload.length) {\n      addScte35SectionMarker(\n        payload.subarray(offset, offset + totalLength),\n        markers,\n        processedSections\n      );\n      offset += totalLength;\n    } else {\n      assemblers.set(pid, {\n        bytes: Array.from(payload.subarray(offset)),\n        expectedLength: totalLength\n      });\n      return;\n    }\n  }\n}\nfunction parseScte35FromTsPackets(data, tsScte35Pids, pmtPids, processedSections) {\n  const packetInfo = detectTsPacketFormat(data);\n  if (!packetInfo) {\n    return [];\n  }\n  const markers = [];\n  const sectionAssemblers = /* @__PURE__ */ new Map();\n  for (let packetStart = packetInfo.offset; packetStart + packetInfo.packetSize <= data.length; packetStart += packetInfo.packetSize) {\n    const tsStart = packetStart + packetInfo.tsPayloadOffset;\n    if (data[tsStart] !== 71) {\n      continue;\n    }\n    const secondByte = data[tsStart + 1];\n    const thirdByte = data[tsStart + 2];\n    const fourthByte = data[tsStart + 3];\n    if (secondByte == null || thirdByte == null || fourthByte == null || (secondByte & 128) !== 0) {\n      continue;\n    }\n    const payloadUnitStart = (secondByte & 64) !== 0;\n    const pid = (secondByte & 31) << 8 | thirdByte;\n    const adaptationFieldControl = fourthByte >> 4 & 3;\n    const hasPayload = adaptationFieldControl === 1 || adaptationFieldControl === 3;\n    if (!hasPayload) {\n      continue;\n    }\n    let payloadStart = tsStart + 4;\n    if (adaptationFieldControl === 3) {\n      const adaptationLength = data[payloadStart];\n      if (adaptationLength == null) {\n        continue;\n      }\n      payloadStart += 1 + adaptationLength;\n    }\n    const payloadEnd = Math.min(tsStart + 188, data.length);\n    if (payloadStart >= payloadEnd || payloadStart >= data.length) {\n      continue;\n    }\n    const payload = data.subarray(payloadStart, payloadEnd);\n    if (pid === 0) {\n      parsePatSection(payload, payloadUnitStart, pmtPids);\n    } else if (pmtPids.has(pid)) {\n      parsePmtSection(payload, payloadUnitStart, tsScte35Pids);\n    } else if (tsScte35Pids.has(pid)) {\n      collectScte35SectionsFromPayload(\n        pid,\n        payload,\n        payloadUnitStart,\n        sectionAssemblers,\n        markers,\n        processedSections\n      );\n    }\n  }\n  return markers;\n}\nvar BitReader = class {\n  constructor(buf) {\n    this.buf = buf;\n    this.bytePos = 0;\n    this.bitPos = 0;\n  }\n  readBits(numBits) {\n    let result = 0;\n    while (numBits > 0) {\n      if (this.bytePos >= this.buf.length) return result;\n      const remainingInByte = 8 - this.bitPos;\n      const toRead = Math.min(numBits, remainingInByte);\n      const currentByte = this.buf[this.bytePos];\n      const shift = remainingInByte - toRead;\n      const mask = (1 << toRead) - 1 & 255;\n      const bits = currentByte >> shift & mask;\n      result = result << toRead | bits;\n      this.bitPos += toRead;\n      if (this.bitPos >= 8) {\n        this.bitPos = 0;\n        this.bytePos += 1;\n      }\n      numBits -= toRead;\n    }\n    return result >>> 0;\n  }\n  skipBits(n) {\n    this.readBits(n);\n  }\n  get bytePosition() {\n    return this.bitPos === 0 ? this.bytePos : this.bytePos + 1;\n  }\n};\nfunction readSpliceTime(r, ptsAdjustmentTicks) {\n  const timeSpecifiedFlag = r.readBits(1) === 1;\n  if (!timeSpecifiedFlag) {\n    r.readBits(7);\n    return void 0;\n  }\n  r.readBits(6);\n  const high = r.readBits(1);\n  const low = r.readBits(32);\n  const ptsTicks = (high * 4294967296 + low + ptsAdjustmentTicks) % 8589934592;\n  return ptsTicks / 9e4;\n}\nfunction markerTypeFromSegmentationTypeId(segmentationTypeId) {\n  switch (segmentationTypeId) {\n    case 16:\n    case 34:\n    case 48:\n    case 50:\n    case 52:\n    case 54:\n      return \"start\";\n    case 17:\n    case 35:\n    case 49:\n    case 51:\n    case 53:\n    case 55:\n      return \"end\";\n    default:\n      return void 0;\n  }\n}\nfunction parseScte35SegmentationDescriptor(descriptor) {\n  if (descriptor.length < 11) {\n    return void 0;\n  }\n  const identifier = String.fromCharCode(\n    descriptor[0] ?? 0,\n    descriptor[1] ?? 0,\n    descriptor[2] ?? 0,\n    descriptor[3] ?? 0\n  );\n  if (identifier !== \"CUEI\") {\n    return void 0;\n  }\n  const segmentationEventId = (descriptor[4] ?? 0) * 16777216 + ((descriptor[5] ?? 0) << 16) + ((descriptor[6] ?? 0) << 8) + (descriptor[7] ?? 0);\n  const cancelIndicator = ((descriptor[8] ?? 0) & 128) !== 0;\n  if (cancelIndicator) {\n    return void 0;\n  }\n  const flags = descriptor[9] ?? 0;\n  const programSegmentationFlag = (flags & 128) !== 0;\n  const segmentationDurationFlag = (flags & 64) !== 0;\n  let offset = 10;\n  if (!programSegmentationFlag) {\n    const componentCount = descriptor[offset] ?? 0;\n    offset += 1 + componentCount * 6;\n    if (offset > descriptor.length) {\n      return void 0;\n    }\n  }\n  let durationSeconds = void 0;\n  if (segmentationDurationFlag) {\n    if (offset + 5 > descriptor.length) {\n      return void 0;\n    }\n    const durationTicks = (descriptor[offset] ?? 0) * 4294967296 + (descriptor[offset + 1] ?? 0) * 16777216 + ((descriptor[offset + 2] ?? 0) << 16) + ((descriptor[offset + 3] ?? 0) << 8) + (descriptor[offset + 4] ?? 0);\n    durationSeconds = durationTicks / 9e4;\n    offset += 5;\n  }\n  if (offset + 2 > descriptor.length) {\n    return void 0;\n  }\n  offset += 1;\n  const segmentationUpidLength = descriptor[offset] ?? 0;\n  offset += 1 + segmentationUpidLength;\n  if (offset >= descriptor.length) {\n    return void 0;\n  }\n  const segmentationTypeId = descriptor[offset] ?? 0;\n  const markerType = markerTypeFromSegmentationTypeId(segmentationTypeId);\n  if (!markerType) {\n    return void 0;\n  }\n  return {\n    type: markerType,\n    ...durationSeconds !== void 0 ? { durationSeconds } : {},\n    segmentationEventId\n  };\n}\nfunction parseScte35SegmentationDescriptors(data, offset) {\n  if (offset + 2 > data.length) {\n    return void 0;\n  }\n  const descriptorLoopLength = (data[offset] ?? 0) << 8 | (data[offset + 1] ?? 0);\n  let descriptorOffset = offset + 2;\n  const descriptorEnd = Math.min(\n    data.length,\n    descriptorOffset + descriptorLoopLength\n  );\n  while (descriptorOffset + 2 <= descriptorEnd) {\n    const descriptorTag = data[descriptorOffset] ?? 0;\n    const descriptorLength = data[descriptorOffset + 1] ?? 0;\n    const descriptorDataStart = descriptorOffset + 2;\n    const descriptorDataEnd = descriptorDataStart + descriptorLength;\n    if (descriptorDataEnd > descriptorEnd) {\n      return void 0;\n    }\n    if (descriptorTag === 2) {\n      const descriptorMarker = parseScte35SegmentationDescriptor(\n        data.subarray(descriptorDataStart, descriptorDataEnd)\n      );\n      if (descriptorMarker) {\n        return descriptorMarker;\n      }\n    }\n    descriptorOffset = descriptorDataEnd;\n  }\n  return void 0;\n}\nfunction parseScte35Binary(data) {\n  const r = new BitReader(data);\n  const tableId = r.readBits(8);\n  if (tableId !== 252) return void 0;\n  r.readBits(1);\n  r.readBits(1);\n  r.readBits(2);\n  const sectionLength = r.readBits(12);\n  if (sectionLength <= 0 || data.length < 3 + sectionLength) {\n    return void 0;\n  }\n  r.readBits(8);\n  r.readBits(1);\n  r.readBits(6);\n  const ptsAdjHigh = r.readBits(1);\n  const ptsAdjLow = r.readBits(32);\n  const ptsAdjustmentTicks = ptsAdjHigh * 4294967296 + ptsAdjLow;\n  r.readBits(8);\n  r.readBits(12);\n  const spliceCommandLength = r.readBits(12);\n  const spliceCommandType = r.readBits(8);\n  let markerType;\n  let durationSeconds = void 0;\n  let ptsSeconds = void 0;\n  let spliceEventId = void 0;\n  const commandBodyStart = r.bytePosition;\n  if (spliceCommandType === 5) {\n    spliceEventId = r.readBits(32);\n    const cancel = r.readBits(1) === 1;\n    r.readBits(7);\n    if (cancel) return void 0;\n    const outOfNetwork = r.readBits(1) === 1;\n    const programSpliceFlag = r.readBits(1) === 1;\n    const durationFlag = r.readBits(1) === 1;\n    const spliceImmediateFlag = r.readBits(1) === 1;\n    r.readBits(4);\n    markerType = outOfNetwork ? \"start\" : \"end\";\n    if (programSpliceFlag && !spliceImmediateFlag) {\n      ptsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n    } else if (!programSpliceFlag) {\n      const componentCount = r.readBits(8);\n      for (let i = 0; i < componentCount; i++) {\n        r.readBits(8);\n        if (!spliceImmediateFlag) {\n          const componentPtsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n          if (ptsSeconds === void 0) {\n            ptsSeconds = componentPtsSeconds;\n          }\n        }\n      }\n    }\n    if (durationFlag) {\n      r.readBits(6);\n      r.readBits(1);\n      const high = r.readBits(1);\n      const low = r.readBits(32);\n      const durationTicks = high * 4294967296 + low;\n      durationSeconds = durationTicks / 9e4;\n    }\n    r.readBits(16);\n    r.readBits(8);\n    r.readBits(8);\n  } else if (spliceCommandType === 6) {\n    ptsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n  } else {\n    return void 0;\n  }\n  const expectedDescriptorOffset = spliceCommandLength === 4095 ? r.bytePosition : commandBodyStart + spliceCommandLength;\n  const descriptorMarker = parseScte35SegmentationDescriptors(\n    data,\n    expectedDescriptorOffset\n  );\n  if (descriptorMarker) {\n    markerType = descriptorMarker.type;\n    if (durationSeconds === void 0) {\n      durationSeconds = descriptorMarker.durationSeconds;\n    }\n  }\n  if (!markerType) {\n    return void 0;\n  }\n  const marker = {\n    type: markerType,\n    ...ptsSeconds !== void 0 ? { ptsSeconds } : {},\n    ...durationSeconds !== void 0 ? { durationSeconds } : {},\n    raw: {\n      splice_command_type: spliceCommandType,\n      ...spliceEventId !== void 0 ? { splice_event_id: spliceEventId } : {},\n      ...descriptorMarker?.segmentationEventId !== void 0 ? { segmentation_event_id: descriptorMarker.segmentationEventId } : {}\n    }\n  };\n  return marker;\n}\n\n// src/player/Scte35CueManager.ts\nvar Scte35CueManager = class {\n  constructor(debug, callbacks) {\n    this.pendingScte35Cues = /* @__PURE__ */ new Map();\n    this.recentScte35CueKeys = /* @__PURE__ */ new Map();\n    this.recentScte35CueLimit = 200;\n    this.tsScte35Pids = /* @__PURE__ */ new Set();\n    this.pmtPids = /* @__PURE__ */ new Set();\n    this.processedTsScte35Sections = /* @__PURE__ */ new Set();\n    this.debug = debug;\n    this.callbacks = callbacks;\n  }\n  get pendingScte35CueKey() {\n    return this.pendingScte35CueKeyValue;\n  }\n  set pendingScte35CueKey(value) {\n    this.pendingScte35CueKeyValue = value;\n  }\n  get activeScte35BreakKey() {\n    return this.activeScte35BreakKeyValue;\n  }\n  set activeScte35BreakKey(value) {\n    this.activeScte35BreakKeyValue = value;\n  }\n  get scheduledScte35BreakKey() {\n    return this.scheduledScte35BreakKeyValue;\n  }\n  set scheduledScte35BreakKey(value) {\n    this.scheduledScte35BreakKeyValue = value;\n  }\n  createScte35CueContext(source, readiness, frag) {\n    const context = { source, readiness };\n    if (typeof frag?.sn === \"number\") {\n      context.fragmentSn = frag.sn;\n    }\n    const fragmentStartSec = getFragmentStartSeconds(frag);\n    if (fragmentStartSec !== void 0) {\n      context.fragmentStartSeconds = fragmentStartSec;\n    }\n    return context;\n  }\n  onScte35Cue(marker, context) {\n    const cue = this.createScte35Cue(marker, context);\n    const pendingKey = this.getPendingScte35CueKey(cue);\n    if (context.readiness === \"early\") {\n      this.pendingScte35Cues.set(pendingKey, cue);\n      this.trimRecentScte35CueMaps();\n      if (marker.type === \"start\") {\n        this.callbacks.onEarlyStartCue(marker, context.fragmentSn, cue.key);\n      }\n      return;\n    }\n    if (marker.type === \"end\" && !this.shouldAcceptScte35EndCue(cue)) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ignoring SCTE-35 end cue\", {\n          key: cue.key,\n          activeScte35BreakKey: this.activeScte35BreakKeyValue,\n          inAdBreak: this.callbacks.isInAdBreak(),\n          source: cue.source\n        });\n      }\n      return;\n    }\n    if (marker.type === \"start\" && this.hasRecentlyHandledScte35Cue(cue)) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ignoring duplicate SCTE-35 start cue\", {\n          key: cue.key,\n          source: cue.source\n        });\n      }\n      return;\n    }\n    this.pendingScte35Cues.delete(pendingKey);\n    this.markScte35CueHandled(cue);\n    this.callbacks.onPlaybackCue(marker, cue.key);\n  }\n  activatePendingScte35CuesForFragment(frag) {\n    const fragmentSn = typeof frag?.sn === \"number\" ? frag.sn : void 0;\n    if (fragmentSn === void 0) {\n      return;\n    }\n    const matchingCues = Array.from(this.pendingScte35Cues.entries()).filter(\n      ([, cue]) => cue.fragmentSn === fragmentSn\n    );\n    matchingCues.forEach(([pendingKey, cue]) => {\n      this.pendingScte35Cues.delete(pendingKey);\n      const context = {\n        source: cue.source,\n        readiness: \"playback\"\n      };\n      context.fragmentSn = fragmentSn;\n      const fragmentStartSec = cue.fragmentStartSeconds ?? getFragmentStartSeconds(frag);\n      if (fragmentStartSec !== void 0) {\n        context.fragmentStartSeconds = fragmentStartSec;\n      }\n      this.onScte35Cue(cue.marker, context);\n    });\n  }\n  createScte35Cue(marker, context) {\n    const cue = {\n      marker,\n      source: context.source,\n      readiness: context.readiness,\n      key: this.getScte35CueKey(marker, context)\n    };\n    if (context.fragmentSn !== void 0) {\n      cue.fragmentSn = context.fragmentSn;\n    }\n    if (context.fragmentStartSeconds !== void 0) {\n      cue.fragmentStartSeconds = context.fragmentStartSeconds;\n    }\n    return cue;\n  }\n  getScte35CueKey(marker, context) {\n    const raw = this.getScte35MarkerRaw(marker);\n    const spliceEventId = this.toIdentityString(raw?.splice_event_id);\n    if (spliceEventId) {\n      return `splice:${spliceEventId}`;\n    }\n    const segmentationEventId = this.toIdentityString(raw?.segmentation_event_id);\n    if (segmentationEventId) {\n      return `segmentation:${segmentationEventId}`;\n    }\n    const daterangeId = this.toIdentityString(raw?.attrs?.ID);\n    if (daterangeId) {\n      return `daterange:${daterangeId}`;\n    }\n    const scteValue = this.toIdentityString(raw?.attrs?.[\"SCTE35-OUT\"]) || this.toIdentityString(raw?.attrs?.[\"SCTE35-IN\"]);\n    if (scteValue) {\n      return `daterange-scte:${scteValue}`;\n    }\n    if (typeof marker.ptsSeconds === \"number\" && Number.isFinite(marker.ptsSeconds)) {\n      return `pts:${Math.round(marker.ptsSeconds * 2) / 2}`;\n    }\n    if (context.fragmentSn !== void 0) {\n      return `fragment:${context.fragmentSn}`;\n    }\n    return `${context.source}:wallclock:${Math.floor(Date.now() / 1e3)}`;\n  }\n  getPendingScte35CueKey(cue) {\n    return `${cue.marker.type}:${cue.key}:${cue.fragmentSn !== void 0 ? cue.fragmentSn : \"unknown\"}`;\n  }\n  getScte35MarkerRaw(marker) {\n    return typeof marker.raw === \"object\" && marker.raw !== null ? marker.raw : {};\n  }\n  toIdentityString(value) {\n    if (typeof value === \"number\" && Number.isFinite(value)) {\n      return String(value);\n    }\n    if (typeof value === \"string\" && value.trim().length > 0) {\n      return value.trim();\n    }\n    return void 0;\n  }\n  isStrongScte35CueKey(key) {\n    return !!(key && (key.startsWith(\"splice:\") || key.startsWith(\"segmentation:\") || key.startsWith(\"daterange:\") || key.startsWith(\"daterange-scte:\")));\n  }\n  hasRecentlyHandledScte35Cue(cue) {\n    if (this.activeScte35BreakKeyValue === cue.key || this.scheduledScte35BreakKeyValue === cue.key) {\n      return true;\n    }\n    const recentKey = `${cue.marker.type}:${cue.key}`;\n    return this.recentScte35CueKeys.has(recentKey);\n  }\n  markScte35CueHandled(cue) {\n    this.recentScte35CueKeys.set(`${cue.marker.type}:${cue.key}`, Date.now());\n    this.trimRecentScte35CueMaps();\n  }\n  trimRecentScte35CueMaps() {\n    while (this.recentScte35CueKeys.size > this.recentScte35CueLimit) {\n      const firstKey = this.recentScte35CueKeys.keys().next().value;\n      if (!firstKey) {\n        break;\n      }\n      this.recentScte35CueKeys.delete(firstKey);\n    }\n    while (this.pendingScte35Cues.size > this.recentScte35CueLimit) {\n      const firstKey = this.pendingScte35Cues.keys().next().value;\n      if (!firstKey) {\n        break;\n      }\n      this.pendingScte35Cues.delete(firstKey);\n    }\n  }\n  shouldAcceptScte35EndCue(cue) {\n    if (!this.callbacks.isInAdBreak()) {\n      return false;\n    }\n    if (this.isStrongScte35CueKey(this.activeScte35BreakKeyValue) && this.isStrongScte35CueKey(cue.key) && this.activeScte35BreakKeyValue !== cue.key) {\n      return false;\n    }\n    return true;\n  }\n};\n\n// src/player/AdConfigManager.ts\nvar AdConfigManager = class {\n  constructor(config, video) {\n    this.vmapBreaks = [];\n    this.consumedVmapBreakIds = /* @__PURE__ */ new Set();\n    this.streamCorrelator = generateCorrelator();\n    this.viewCorrelator = generateCorrelator();\n    this.consentSignals = {};\n    this.podCounter = 0;\n    this.podAssignedByPrefetch = false;\n    this.lastHeartbeatTime = 0;\n    this.defaultPodMaxAds = 6;\n    this.defaultPodMaxDurationMs = 12e4;\n    this.config = config;\n    this.video = video;\n  }\n  get debug() {\n    return !!this.config.debugAdTiming;\n  }\n  isVmapEnabled() {\n    return !!(this.config.isVmap && this.config.vmapUrl?.trim());\n  }\n  async fetchAdConfiguration() {\n    if (this.isVmapEnabled()) {\n      await this.fetchAndParseVmap(this.config.vmapUrl);\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] VMAP mode enabled\");\n      }\n      return;\n    }\n    const vastMode = this.config.vastMode || \"default\";\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] VAST mode:\", vastMode);\n    }\n    if (vastMode === \"adstorm\") {\n      if (!this.config.licenseKey) {\n        if (this.debug) {\n          console.warn(\n            \"[StormcloudVideoPlayer] AdStorm mode requires a license key\"\n          );\n        }\n        return;\n      }\n      const vastEndpoint = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${this.config.licenseKey}`;\n      this.apiVastTagUrl = vastEndpoint;\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):\",\n          vastEndpoint\n        );\n      }\n      return;\n    }\n    if (this.config.vastTagUrl) {\n      this.apiVastTagUrl = normalizeVastTagUrl(this.config.vastTagUrl);\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Using custom VAST tag URL:\",\n          this.apiVastTagUrl\n        );\n      }\n      return;\n    }\n    const apiUrl = \"https://adstorm.co/api-adstorm-dev/adstorm/ads/web\";\n    if (this.debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] Fetching ad configuration from:\",\n        apiUrl\n      );\n    }\n    const headers = {};\n    if (this.config.licenseKey) {\n      headers[\"Authorization\"] = `Bearer ${this.config.licenseKey}`;\n    }\n    const response = await fetch(apiUrl, { headers });\n    if (!response.ok) {\n      if (this.debug) {\n        console.warn(\n          `[StormcloudVideoPlayer] Failed to fetch ad configuration: ${response.status}`\n        );\n      }\n      return;\n    }\n    const data = await response.json();\n    const imaPayload = data.response?.ima?.[\"publisherdesk.ima\"]?.payload;\n    if (imaPayload) {\n      let decodedPayload = imaPayload;\n      try {\n        decodedPayload = decodeURIComponent(imaPayload);\n      } catch {\n        console.warn(\"[StormcloudVideoPlayer] imaPayload was not URI-encoded; using as-is:\", imaPayload);\n      }\n      console.log(\"[StormcloudVideoPlayer] Raw VAST tag URL (from API):\", decodedPayload);\n      this.apiVastTagUrl = normalizeVastTagUrl(decodedPayload);\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Normalized VAST tag URL:\",\n          this.apiVastTagUrl\n        );\n      }\n    } else {\n      if (this.debug) {\n        console.warn(\n          \"[StormcloudVideoPlayer] No VAST tag URL found in /ads/web response\"\n        );\n      }\n    }\n    const numberAds = data.response?.options?.vast?.cue_tones?.number_ads;\n    if (numberAds != null && numberAds > 0) {\n      this.apiNumberAds = numberAds;\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Number of ads per break from API:\",\n          this.apiNumberAds\n        );\n      }\n    }\n  }\n  async fetchAndParseVmap(vmapUrl) {\n    if (!vmapUrl.trim()) {\n      return;\n    }\n    try {\n      const response = await fetch(vmapUrl);\n      if (!response.ok) {\n        throw new Error(`Failed to fetch VMAP (${response.status})`);\n      }\n      const vmapXml = await response.text();\n      this.vmapBreaks = this.parseVmapToBreaks(vmapXml);\n      this.consumedVmapBreakIds.clear();\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] Loaded ${this.vmapBreaks.length} VMAP ad break(s) from:`,\n          vmapUrl\n        );\n      }\n    } catch (error) {\n      this.vmapBreaks = [];\n      this.consumedVmapBreakIds.clear();\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Failed to load VMAP:\", error);\n      }\n    }\n  }\n  parseVmapToBreaks(vmapXml) {\n    if (typeof DOMParser === \"undefined\") {\n      return [];\n    }\n    const doc = new DOMParser().parseFromString(vmapXml, \"application/xml\");\n    if (doc.querySelector(\"parsererror\")) {\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Invalid VMAP XML received\");\n      }\n      return [];\n    }\n    const VMAP_NS = \"http://www.iab.net/videosuite/vmap\";\n    let adBreakNodes = Array.from(doc.getElementsByTagNameNS(VMAP_NS, \"AdBreak\"));\n    if (adBreakNodes.length === 0) {\n      adBreakNodes = Array.from(\n        doc.querySelectorAll(\"AdBreak, vmap\\\\:AdBreak\")\n      );\n    }\n    if (adBreakNodes.length === 0) {\n      adBreakNodes = Array.from(doc.getElementsByTagName(\"*\")).filter(\n        (el) => el.localName === \"AdBreak\"\n      );\n    }\n    const parsed = [];\n    adBreakNodes.forEach((node, index) => {\n      const timeOffsetRaw = (node.getAttribute(\"timeOffset\") || \"\").trim();\n      const startTimeMs = this.parseVmapTimeOffsetToMs(timeOffsetRaw);\n      if (startTimeMs == null) {\n        return;\n      }\n      let adTagNode = node.getElementsByTagNameNS(VMAP_NS, \"AdTagURI\")[0];\n      if (!adTagNode) {\n        adTagNode = node.querySelector(\"AdTagURI, vmap\\\\:AdTagURI\") ?? void 0;\n      }\n      const adTagUrl = (adTagNode?.textContent || \"\").trim();\n      if (!adTagUrl) {\n        return;\n      }\n      const breakId = node.getAttribute(\"breakId\") || `vmap-break-${index}-${timeOffsetRaw || \"unknown\"}`;\n      parsed.push({\n        id: breakId,\n        startTimeMs,\n        vastTagUrl: adTagUrl\n      });\n    });\n    parsed.sort((a, b) => {\n      const aStart = a.startTimeMs < 0 ? Number.MAX_SAFE_INTEGER : a.startTimeMs;\n      const bStart = b.startTimeMs < 0 ? Number.MAX_SAFE_INTEGER : b.startTimeMs;\n      return aStart - bStart;\n    });\n    return parsed;\n  }\n  parseVmapTimeOffsetToMs(timeOffset) {\n    if (!timeOffset) {\n      return void 0;\n    }\n    const normalized = timeOffset.trim().toLowerCase();\n    if (normalized === \"start\") {\n      return 0;\n    }\n    if (normalized === \"end\") {\n      return -1;\n    }\n    const hms = timeOffset.match(\n      /^(\\d{1,2}):(\\d{2}):(\\d{2})(?:\\.(\\d{1,3}))?$/\n    );\n    if (hms) {\n      const [, hh, mm, ss, ms = \"0\"] = hms;\n      const hours = Number(hh);\n      const minutes = Number(mm);\n      const seconds = Number(ss);\n      const millis = Number(ms.padEnd(3, \"0\").slice(0, 3));\n      return (hours * 3600 + minutes * 60 + seconds) * 1e3 + millis;\n    }\n    const percent = timeOffset.match(/^(\\d+(?:\\.\\d+)?)%$/);\n    if (percent) {\n      const ratio = Number(percent[1]) / 100;\n      const durationSec = this.video.duration;\n      if (Number.isFinite(durationSec) && durationSec > 0) {\n        return Math.floor(durationSec * 1e3 * ratio);\n      }\n      return void 0;\n    }\n    return void 0;\n  }\n  getAdBreakKey(adBreak) {\n    if (adBreak.id) {\n      return adBreak.id;\n    }\n    return `${adBreak.startTimeMs}-${adBreak.vastTagUrl || \"\"}`;\n  }\n  resolveBreakStartMs(adBreak) {\n    if (adBreak.startTimeMs >= 0) {\n      return adBreak.startTimeMs;\n    }\n    if (adBreak.startTimeMs === -1) {\n      const durationSec = this.video.duration;\n      if (Number.isFinite(durationSec) && durationSec > 0) {\n        return Math.floor(durationSec * 1e3);\n      }\n    }\n    return void 0;\n  }\n  findCurrentOrNextBreak(nowMs) {\n    const schedule = this.vmapBreaks;\n    let candidate;\n    const tol = this.config.driftToleranceMs ?? 1e3;\n    for (const b of schedule) {\n      if (this.consumedVmapBreakIds.has(this.getAdBreakKey(b))) {\n        continue;\n      }\n      const breakStartMs = this.resolveBreakStartMs(b);\n      if (breakStartMs == null) {\n        continue;\n      }\n      if (breakStartMs <= nowMs + tol && (candidate == null || breakStartMs > (this.resolveBreakStartMs(candidate) ?? 0))) {\n        candidate = b;\n      }\n    }\n    return candidate;\n  }\n  findBreakForTime(nowMs) {\n    const schedule = this.vmapBreaks;\n    for (const b of schedule) {\n      if (this.consumedVmapBreakIds.has(this.getAdBreakKey(b))) {\n        continue;\n      }\n      const breakStartMs = this.resolveBreakStartMs(b);\n      if (breakStartMs == null) {\n        continue;\n      }\n      if (b.durationMs) {\n        const end = breakStartMs + b.durationMs;\n        if (nowMs >= breakStartMs && nowMs < end) {\n          return b;\n        }\n        continue;\n      }\n      if (nowMs >= breakStartMs) {\n        return b;\n      }\n    }\n    return void 0;\n  }\n  selectVastTagsForBreak(b) {\n    if (!b || !b.vastTagUrl) return void 0;\n    if (b.vastTagUrl.includes(\",\")) {\n      return b.vastTagUrl.split(\",\").map((s) => s.trim()).filter((s) => s.length > 0);\n    }\n    return [b.vastTagUrl];\n  }\n  beginNewAdPod() {\n    this.podCounter++;\n  }\n  resolvePodParams(breakDurationMs) {\n    const maxDurationMs = breakDurationMs != null && breakDurationMs > 0 ? breakDurationMs : this.config.podMaxDurationMs != null && this.config.podMaxDurationMs > 0 ? this.config.podMaxDurationMs : this.defaultPodMaxDurationMs;\n    const maxAds = this.config.podMaxAds && this.config.podMaxAds > 0 ? this.config.podMaxAds : this.apiNumberAds && this.apiNumberAds > 0 ? this.apiNumberAds : this.defaultPodMaxAds;\n    const minDurationMs = this.config.podExactDuration && maxDurationMs != null ? maxDurationMs : 0;\n    return { maxAds, minDurationMs, maxDurationMs };\n  }\n  generatePodVastUrl(baseUrl, podParams, adPlayer, palNonce, inAdBreak) {\n    const adWillPlayMuted = inAdBreak ? adPlayer.getOriginalMutedState() : this.video.muted;\n    const envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);\n    const urlWithMacros = applyVastMacros(baseUrl, {\n      correlator: this.viewCorrelator,\n      streamCorrelator: this.streamCorrelator,\n      pod: this.podCounter > 0 ? this.podCounter : void 0,\n      podMaxAds: podParams.maxAds,\n      podMinDurationMs: podParams.minDurationMs,\n      podMaxDurationMs: podParams.maxDurationMs,\n      isCtv: envSignals.isCtv,\n      contentUrl: envSignals.contentUrl,\n      pageUrl: !envSignals.isCtv && typeof window !== \"undefined\" ? window.location.href : void 0,\n      adWillPlayMuted,\n      adWillAutoPlay: !!this.config.autoplay,\n      appId: envSignals.appId,\n      appName: envSignals.appName,\n      sessionId: envSignals.sessionId,\n      deviceId: envSignals.deviceId,\n      deviceIdType: envSignals.deviceIdType,\n      limitAdTracking: envSignals.limitAdTracking,\n      deviceTypeHint: envSignals.deviceTypeHint,\n      adTest: this.config.adTest,\n      consent: this.consentSignals\n    });\n    const finalUrl = palNonce.injectNonce(urlWithMacros);\n    console.log(\n      `[StormcloudVideoPlayer] Resolved optimized-pod request URL (pod=${this.podCounter}, pmad=${podParams.maxAds}, pmnd=${podParams.minDurationMs}, pmxd=${podParams.maxDurationMs ?? \"?\"}):`,\n      finalUrl\n    );\n    return finalUrl;\n  }\n  // --- Tracking ---\n  initializeTracking() {\n    sendInitialTracking(this.config.licenseKey, buildAnalyticsContext(this.config)).then(() => {\n      this.heartbeatInterval = window.setInterval(() => {\n        this.sendHeartbeatIfNeeded();\n      }, 5e3);\n    }).catch((error) => {\n      if (this.debug) {\n        console.warn(\n          \"[StormcloudVideoPlayer] Failed to send initial tracking:\",\n          error\n        );\n      }\n      this.heartbeatInterval = window.setInterval(() => {\n        this.sendHeartbeatIfNeeded();\n      }, 5e3);\n    });\n  }\n  sendHeartbeatIfNeeded() {\n    const now = Date.now();\n    if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 3e4) {\n      this.lastHeartbeatTime = now;\n      sendHeartbeat(this.config.licenseKey, buildAnalyticsContext(this.config)).catch((error) => {\n        if (this.debug) {\n          console.warn(\n            \"[StormcloudVideoPlayer] Failed to send heartbeat:\",\n            error\n          );\n        }\n      });\n    }\n  }\n  destroyTracking() {\n    if (this.heartbeatInterval) {\n      clearInterval(this.heartbeatInterval);\n      this.heartbeatInterval = void 0;\n    }\n  }\n};\n\n// src/player/AdTimingService.ts\nvar AdTimingService = class {\n  constructor(config, video, callbacks) {\n    this.adRequestWatchdogToken = null;\n    this.adFailsafeToken = null;\n    this.ptsDriftEmaMs = 0;\n    this.adBreakPlayedDurationMs = 0;\n    this.adBreakEpoch = 0;\n    this.adRequestTokenCounter = 0;\n    this.activeAdRequestToken = null;\n    this.currentAdIndex = 0;\n    this.totalAdsInBreak = 0;\n    this.totalAdRequestsInBreak = 0;\n    this.maxTotalAdRequestsPerBreak = 10;\n    this.lastAdRequestTime = 0;\n    this.consecutiveFailures = 0;\n    this.maxConsecutiveFailures = 5;\n    this.minAdRequestIntervalMs = 3e3;\n    this.backoffBaseMs = 1e3;\n    this.maxBackoffMs = 15e3;\n    this.defaultMinRemainingMsToStartAd = 4e3;\n    this.failedVastUrls = /* @__PURE__ */ new Set();\n    this.temporaryFailureUrls = /* @__PURE__ */ new Map();\n    this.temporaryFailureCooldownMs = 3e4;\n    this.globalConsecutiveNoFills = 0;\n    this.globalNoFillThreshold = 3;\n    this.globalNoFillCooldownUntil = 0;\n    this.globalNoFillBackoffBaseMs = 5e3;\n    this.globalNoFillBackoffMaxMs = 6e4;\n    this.globalLastGamRequestTime = 0;\n    this.globalMinGamIntervalMs = 3e3;\n    this.config = config;\n    this.video = video;\n    this.callbacks = callbacks;\n  }\n  get debug() {\n    return !!this.config.debugAdTiming;\n  }\n  // --- Ad stop timer ---\n  scheduleAdStopCountdown(remainingMs) {\n    this.clearAdStopTimer();\n    const ms = Math.max(0, Math.floor(remainingMs));\n    if (ms === 0) {\n      this.ensureAdStoppedByTimer();\n      return;\n    }\n    this.adStopTimerId = window.setTimeout(() => {\n      this.ensureAdStoppedByTimer();\n    }, ms);\n  }\n  clearAdStopTimer() {\n    if (this.adStopTimerId != null) {\n      clearTimeout(this.adStopTimerId);\n      this.adStopTimerId = void 0;\n    }\n  }\n  ensureAdStoppedByTimer() {\n    this.adStopTimerId = void 0;\n    this.callbacks.onAdStopTimerFired();\n  }\n  // --- Ad start timer ---\n  scheduleAdStartIn(delayMs, marker = { type: \"start\" }, cueKey) {\n    this.clearAdStartTimer();\n    const ms = Math.max(0, Math.floor(delayMs));\n    if (ms === 0) {\n      this.callbacks.onAdStartTimerFired(marker, cueKey);\n      return;\n    }\n    this.adStartTimerId = window.setTimeout(() => {\n      this.callbacks.onAdStartTimerFired(marker, cueKey);\n    }, ms);\n  }\n  clearAdStartTimer() {\n    if (this.adStartTimerId != null) {\n      clearTimeout(this.adStartTimerId);\n      this.adStartTimerId = void 0;\n    }\n  }\n  // --- PTS drift ---\n  updatePtsDrift(ptsSecondsSample) {\n    const sampleMs = (this.video.currentTime - ptsSecondsSample) * 1e3;\n    if (!Number.isFinite(sampleMs) || Math.abs(sampleMs) > 6e4) return;\n    const alpha = 0.1;\n    this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;\n  }\n  resolveScteBreakStartWallClockMs(marker) {\n    const nowWallClockMs = Date.now();\n    if (typeof marker.ptsSeconds !== \"number\") {\n      return nowWallClockMs;\n    }\n    const nowMs = this.video.currentTime * 1e3;\n    const estimatedCurrentPtsMs = nowMs - this.ptsDriftEmaMs;\n    const deltaMs = marker.ptsSeconds * 1e3 - estimatedCurrentPtsMs;\n    if (!Number.isFinite(deltaMs)) {\n      return nowWallClockMs;\n    }\n    return nowWallClockMs + Math.floor(deltaMs);\n  }\n  // --- Duration boundary ---\n  setAdBreakDurationBoundary(durationMs) {\n    this.expectedAdBreakDurationMs = durationMs;\n    if (durationMs != null && this.currentAdBreakStartWallClockMs != null) {\n      this.scteAdBreakEndWallClockMs = this.currentAdBreakStartWallClockMs + durationMs;\n    } else {\n      this.scteAdBreakEndWallClockMs = void 0;\n    }\n  }\n  scheduleAdStopAtBreakBoundary() {\n    if (this.expectedAdBreakDurationMs == null) {\n      return;\n    }\n    this.scheduleAdStopCountdown(this.getWallClockRemainingAdMs());\n  }\n  // --- Duration budget ---\n  getWallClockRemainingAdMs() {\n    const endWallClockMs = this.getAdBreakEndWallClockMs();\n    if (endWallClockMs != null) {\n      return Math.max(0, endWallClockMs - Date.now());\n    }\n    return 0;\n  }\n  getAdBreakEndWallClockMs() {\n    if (this.scteAdBreakEndWallClockMs != null) {\n      return this.scteAdBreakEndWallClockMs;\n    }\n    if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null) {\n      return void 0;\n    }\n    return this.currentAdBreakStartWallClockMs + this.expectedAdBreakDurationMs;\n  }\n  getDurationBudgetRemainingMs() {\n    if (this.expectedAdBreakDurationMs == null) {\n      return 0;\n    }\n    return Math.max(0, this.expectedAdBreakDurationMs - this.adBreakPlayedDurationMs);\n  }\n  getLoadedAdDurationMs(adController) {\n    const durationSec = adController.getLoadedAdDuration?.();\n    if (durationSec == null || durationSec <= 0) {\n      return 0;\n    }\n    return Math.round(durationSec * 1e3);\n  }\n  adFitsRemainingBudget(durationMs) {\n    if (durationMs <= 0) {\n      return true;\n    }\n    return durationMs <= this.getDurationBudgetRemainingMs();\n  }\n  logAdDurationDecision(accepted, durationMs, adController) {\n    if (!this.debug) {\n      return;\n    }\n    const remainingBudget = this.getDurationBudgetRemainingMs();\n    const adId = adController.getLoadedAdId?.() ?? \"unknown\";\n    if (accepted) {\n      console.log(\n        `[AD-DURATION] Accepted ad id=${adId}, duration=${durationMs}ms, budget remaining after play=${Math.max(0, remainingBudget - durationMs)}ms`\n      );\n    } else {\n      console.log(\n        `[AD-DURATION] Rejected ad id=${adId}, duration=${durationMs}ms exceeds remaining budget=${remainingBudget}ms \\u2014 requesting another ad`\n      );\n    }\n  }\n  recordPlayedAdDuration(adController) {\n    const durationMs = this.getLoadedAdDurationMs(adController);\n    if (durationMs <= 0) {\n      return;\n    }\n    this.adBreakPlayedDurationMs += durationMs;\n    if (this.debug) {\n      console.log(\n        `[AD-DURATION] Played ${durationMs}ms \\u2014 total played=${this.adBreakPlayedDurationMs}ms / ${this.expectedAdBreakDurationMs ?? \"?\"}ms`\n      );\n    }\n  }\n  ensureLoadedAdFitsBudget(adController) {\n    const durationMs = this.getLoadedAdDurationMs(adController);\n    const fits = this.adFitsRemainingBudget(durationMs);\n    this.logAdDurationDecision(fits, durationMs, adController);\n    return fits;\n  }\n  rejectLoadedAdForDuration(adController) {\n    try {\n      adController.destroy();\n    } catch {\n    }\n  }\n  markAdStarted() {\n    this.currentAdIndex++;\n    this.totalAdsInBreak = this.currentAdIndex;\n    this.totalAdRequestsInBreak++;\n    this.lastAdRequestTime = Date.now();\n  }\n  notePodAdStarted() {\n    this.currentAdIndex++;\n    this.totalAdsInBreak = this.currentAdIndex;\n  }\n  getRemainingAdMs() {\n    const wallClockRemaining = this.getWallClockRemainingAdMs();\n    const budgetRemaining = this.getDurationBudgetRemainingMs();\n    if (this.expectedAdBreakDurationMs == null) {\n      return wallClockRemaining;\n    }\n    return Math.min(wallClockRemaining, budgetRemaining);\n  }\n  getMinRemainingMsToStartAd() {\n    const configured = this.config.minRemainingMsToStartAd;\n    if (typeof configured === \"number\" && configured >= 0) {\n      return configured;\n    }\n    return this.defaultMinRemainingMsToStartAd;\n  }\n  hasTimeToStartAnotherAd() {\n    const minRemaining = this.getMinRemainingMsToStartAd();\n    return this.getWallClockRemainingAdMs() > minRemaining && this.getDurationBudgetRemainingMs() > minRemaining;\n  }\n  // --- Circuit breaker ---\n  isTemporaryAdError(error) {\n    const message = error?.message?.toLowerCase() || \"\";\n    if (message.includes(\"no ads available\") || message.includes(\"no fill\") || message.includes(\"nofill\")) {\n      return true;\n    }\n    if (message.includes(\"timeout\")) {\n      return true;\n    }\n    if (message.includes(\"rate limit\") || message.includes(\"too many requests\")) {\n      return true;\n    }\n    if (message.includes(\"ad playback error\")) {\n      return true;\n    }\n    return false;\n  }\n  isUrlInCooldown(vastTagUrl) {\n    const failureTime = this.temporaryFailureUrls.get(vastTagUrl);\n    if (failureTime == null) {\n      return false;\n    }\n    const elapsed = Date.now() - failureTime;\n    if (elapsed >= this.temporaryFailureCooldownMs) {\n      this.temporaryFailureUrls.delete(vastTagUrl);\n      return false;\n    }\n    return true;\n  }\n  cleanupTemporaryFailures() {\n    const now = Date.now();\n    for (const [url, timestamp] of this.temporaryFailureUrls) {\n      if (now - timestamp >= this.temporaryFailureCooldownMs) {\n        this.temporaryFailureUrls.delete(url);\n      }\n    }\n  }\n  isGamInCooldown() {\n    return Date.now() < this.globalNoFillCooldownUntil;\n  }\n  recordGamNoFill() {\n    this.globalConsecutiveNoFills++;\n    if (this.globalConsecutiveNoFills >= this.globalNoFillThreshold) {\n      const exponent = this.globalConsecutiveNoFills - this.globalNoFillThreshold;\n      const backoff = Math.min(\n        this.globalNoFillBackoffBaseMs * Math.pow(2, exponent),\n        this.globalNoFillBackoffMaxMs\n      );\n      this.globalNoFillCooldownUntil = Date.now() + backoff;\n      if (this.debug) {\n        console.log(\n          `[CIRCUIT-BREAKER] GAM cooldown activated: ${backoff}ms (${this.globalConsecutiveNoFills} consecutive no-fills)`\n        );\n      }\n    }\n  }\n  resetGamNoFillCounter() {\n    if (this.globalConsecutiveNoFills > 0 && this.debug) {\n      console.log(\n        `[CIRCUIT-BREAKER] Resetting no-fill counter (was ${this.globalConsecutiveNoFills})`\n      );\n    }\n    this.globalConsecutiveNoFills = 0;\n    this.globalNoFillCooldownUntil = 0;\n  }\n  async enforceGlobalRateLimit() {\n    const now = Date.now();\n    const elapsed = now - this.globalLastGamRequestTime;\n    if (elapsed < this.globalMinGamIntervalMs) {\n      const waitMs = this.globalMinGamIntervalMs - elapsed;\n      if (this.debug) {\n        console.log(`[RATE-LIMIT] Waiting ${waitMs}ms before next GAM request`);\n      }\n      await new Promise((resolve) => setTimeout(resolve, waitMs));\n    }\n    this.globalLastGamRequestTime = Date.now();\n  }\n  // --- Watchdog ---\n  startAdRequestWatchdog(token) {\n    this.clearAdRequestWatchdog();\n    const timeoutMs = this.config.adFailsafeTimeoutMs ?? 1e4;\n    this.adRequestWatchdogToken = token;\n    this.adRequestWatchdogId = window.setTimeout(() => {\n      if (this.adRequestWatchdogToken !== token) {\n        return;\n      }\n      this.adRequestWatchdogId = void 0;\n      this.adRequestWatchdogToken = null;\n      if (this.activeAdRequestToken === token) {\n        this.activeAdRequestToken = null;\n      }\n      this.logAdState(\"ad_request_timeout\", { token, timeoutMs });\n      this.callbacks.onWatchdogTimeout();\n    }, timeoutMs);\n    this.logAdState(\"ad_request_watchdog_started\", { token, timeoutMs });\n  }\n  clearAdRequestWatchdog() {\n    if (this.adRequestWatchdogId != null) {\n      clearTimeout(this.adRequestWatchdogId);\n      this.adRequestWatchdogId = void 0;\n    }\n    if (this.adRequestWatchdogToken != null) {\n      this.logAdState(\"ad_request_watchdog_cleared\", {\n        token: this.adRequestWatchdogToken\n      });\n      this.adRequestWatchdogToken = null;\n    }\n  }\n  // --- Failsafe ---\n  startAdFailsafeTimer(token) {\n    this.clearAdFailsafeTimer();\n    const failsafeMs = this.config.adFailsafeTimeoutMs ?? 1e4;\n    this.adFailsafeToken = token;\n    this.adFailsafeTimerId = window.setTimeout(() => {\n      if (this.adFailsafeToken !== token) {\n        return;\n      }\n      this.adFailsafeTimerId = void 0;\n      this.adFailsafeToken = null;\n      if (this.activeAdRequestToken === token) {\n        this.activeAdRequestToken = null;\n      }\n      this.logAdState(\"ad_failsafe_triggered\", {\n        token,\n        failsafeMs,\n        videoPaused: this.video.paused\n      });\n      this.callbacks.onFailsafeTimeout();\n    }, failsafeMs);\n    this.logAdState(\"ad_failsafe_started\", { token, failsafeMs });\n  }\n  clearAdFailsafeTimer() {\n    if (this.adFailsafeTimerId != null) {\n      clearTimeout(this.adFailsafeTimerId);\n      this.logAdState(\"ad_failsafe_cleared\", { token: this.adFailsafeToken });\n      this.adFailsafeTimerId = void 0;\n    }\n    this.adFailsafeToken = null;\n  }\n  logAdState(event, extra = {}, adPlayer, inAdBreak, showAds) {\n    if (!this.debug) {\n      return;\n    }\n    console.log(\"[StormcloudVideoPlayer][AdState]\", {\n      event,\n      timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n      showAds: showAds ?? false,\n      adPlaying: adPlayer?.isAdPlaying() ?? false,\n      inAdBreak: inAdBreak ?? false,\n      activeAdRequestToken: this.activeAdRequestToken,\n      ...extra\n    });\n  }\n  // --- Reset for ad break end ---\n  resetForBreakEnd() {\n    this.clearAdStopTimer();\n    this.clearAdStartTimer();\n    this.clearAdRequestWatchdog();\n    this.clearAdFailsafeTimer();\n    this.activeAdRequestToken = null;\n    this.expectedAdBreakDurationMs = void 0;\n    this.currentAdBreakStartWallClockMs = void 0;\n    this.scteAdBreakEndWallClockMs = void 0;\n    this.adBreakPlayedDurationMs = 0;\n    this.currentAdIndex = 0;\n    this.totalAdsInBreak = 0;\n    this.consecutiveFailures = 0;\n    this.globalConsecutiveNoFills = 0;\n    this.adBreakEpoch++;\n  }\n  destroy() {\n    this.clearAdStopTimer();\n    this.clearAdStartTimer();\n    this.clearAdFailsafeTimer();\n    this.clearAdRequestWatchdog();\n  }\n};\n\n// src/player/PlaceholderLayer.ts\nvar PlaceholderLayer = class {\n  constructor(video, debug) {\n    this.video = video;\n    this.debug = debug;\n  }\n  ensureContainer() {\n    if (this.container) {\n      return;\n    }\n    const el = document.createElement(\"div\");\n    el.style.position = \"absolute\";\n    el.style.left = \"0\";\n    el.style.top = \"0\";\n    el.style.right = \"0\";\n    el.style.bottom = \"0\";\n    el.style.display = \"none\";\n    el.style.alignItems = \"center\";\n    el.style.justifyContent = \"center\";\n    el.style.pointerEvents = \"none\";\n    el.style.zIndex = \"5\";\n    el.style.backgroundColor = \"#000\";\n    el.style.transition = \"opacity 0.3s ease-in-out\";\n    el.style.opacity = \"0\";\n    if (!this.video.parentElement) {\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Video element has no parent for placeholder container\");\n      }\n      return;\n    }\n    this.video.parentElement.appendChild(el);\n    this.container = el;\n  }\n  show() {\n    this.ensureContainer();\n    if (!this.container) {\n      return;\n    }\n    if (!this.video.muted) {\n      this.video.muted = true;\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Muted video when showing placeholder\");\n      }\n    }\n    const wasHidden = this.container.style.display === \"none\" || this.container.style.opacity === \"0\";\n    if (wasHidden) {\n      this.container.style.transition = \"none\";\n    } else {\n      this.container.style.transition = \"opacity 0.3s ease-in-out\";\n    }\n    this.container.style.backgroundColor = \"#000\";\n    this.container.style.display = \"flex\";\n    this.container.offsetHeight;\n    this.container.style.opacity = \"1\";\n    this.container.style.pointerEvents = \"auto\";\n    if (wasHidden) {\n      requestAnimationFrame(() => {\n        if (this.container) {\n          this.container.style.transition = \"opacity 0.3s ease-in-out\";\n        }\n      });\n    }\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Showing placeholder layer (between content and ad layer)\");\n    }\n  }\n  hide() {\n    if (!this.container) {\n      return;\n    }\n    this.container.style.opacity = \"0\";\n    setTimeout(() => {\n      if (this.container) {\n        this.container.style.display = \"none\";\n        this.container.style.pointerEvents = \"none\";\n        this.container.style.backgroundColor = \"#000\";\n      }\n    }, 300);\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Hiding placeholder layer\");\n    }\n  }\n  destroy() {\n    if (this.container) {\n      if (this.container.parentElement) {\n        this.container.parentElement.removeChild(this.container);\n      }\n      this.container = void 0;\n    }\n  }\n};\n\n// src/player/HlsEngine.ts\nvar import_hls2 = __toESM(require(\"hls.js\"), 1);\nvar HlsEngine = class {\n  constructor(config, video, cueManager, timing, callbacks) {\n    this.isLiveStream = false;\n    this.nativeHlsMode = false;\n    this.videoSrcProtection = null;\n    this.bufferedSegmentsCount = 0;\n    this.shouldAutoplayAfterBuffering = false;\n    this.hasInitialBufferCompleted = false;\n    this.config = config;\n    this.video = video;\n    this.cueManager = cueManager;\n    this.timing = timing;\n    this.callbacks = callbacks;\n  }\n  get debug() {\n    return !!this.config.debugAdTiming;\n  }\n  shouldUseNativeHls(getStreamType) {\n    const streamType = getStreamType();\n    if (streamType === \"other\") {\n      return true;\n    }\n    const canNative = this.video.canPlayType(\"application/vnd.apple.mpegurl\");\n    return !!(this.config.allowNativeHls && canNative);\n  }\n  async setupNativeHls() {\n    this.nativeHlsMode = true;\n    this.videoSrcProtection = this.config.src;\n    this.video.src = this.config.src;\n    this.isLiveStream = this.config.isLiveStream ?? (this.config.lowLatencyMode ?? false);\n    if (this.debug) {\n      const adBehavior = this.isLiveStream ? \"live (main video continues muted during ads)\" : \"vod (main video pauses during ads)\";\n      console.log(\n        \"[StormcloudVideoPlayer] Using native HLS playback:\",\n        {\n          isLive: this.isLiveStream,\n          allowNativeHls: this.config.allowNativeHls,\n          adBehavior\n        }\n      );\n    }\n    if (this.config.autoplay) {\n      await this.video.play()?.catch(() => {\n      });\n    }\n  }\n  setupHls() {\n    this.hls = new import_hls2.default({\n      enableWorker: true,\n      backBufferLength: 30,\n      liveDurationInfinity: true,\n      lowLatencyMode: !!this.config.lowLatencyMode,\n      maxLiveSyncPlaybackRate: this.config.lowLatencyMode ? 1.5 : 1,\n      ...this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {},\n      maxBufferLength: 30,\n      maxMaxBufferLength: 600,\n      maxBufferSize: 60 * 1e3 * 1e3,\n      maxBufferHole: 0.5,\n      highBufferWatchdogPeriod: 2,\n      nudgeOffset: 0.1,\n      nudgeMaxRetry: 3,\n      startPosition: -1\n    });\n    this.hls.on(import_hls2.default.Events.MEDIA_ATTACHED, () => {\n      this.hls?.loadSource(this.config.src);\n    });\n    this.hls.on(import_hls2.default.Events.MANIFEST_PARSED, async (_, _data) => {\n      this.isLiveStream = this.config.isLiveStream ?? (this.hls?.levels?.some(\n        (level) => level?.details?.live === true || level?.details?.type === \"LIVE\"\n      ) ?? false);\n      await this.callbacks.onManifestParsed(this.isLiveStream);\n      this.bufferedSegmentsCount = 0;\n      this.hasInitialBufferCompleted = false;\n      this.shouldAutoplayAfterBuffering = !!this.config.autoplay;\n      const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Waiting for\",\n          minSegments,\n          \"segments to buffer before playback\"\n        );\n      }\n      if (minSegments === 0 || !this.config.autoplay) {\n        this.hasInitialBufferCompleted = true;\n        if (this.config.autoplay) {\n          await this.video.play()?.catch(() => {\n          });\n        }\n      }\n    });\n    this.hls.on(import_hls2.default.Events.LEVEL_LOADED, (_evt, data) => {\n      if (this.callbacks.isInAdBreak() || this.callbacks.hasPendingAdBreak()) {\n        return;\n      }\n      const details = data?.details;\n      if (!details || !details.fragments || details.fragments.length === 0) {\n        return;\n      }\n      const fragmentsToScan = Math.min(5, details.fragments.length);\n      for (let i = 0; i < fragmentsToScan; i++) {\n        const frag = details.fragments[i];\n        const tagList = frag?.tagList;\n        if (!Array.isArray(tagList)) continue;\n        for (const entry of tagList) {\n          let tag = \"\";\n          let value = \"\";\n          if (Array.isArray(entry)) {\n            tag = String(entry[0] ?? \"\");\n            value = String(entry[1] ?? \"\");\n          } else if (typeof entry === \"string\") {\n            const idx = entry.indexOf(\":\");\n            if (idx >= 0) {\n              tag = entry.substring(0, idx);\n              value = entry.substring(idx + 1);\n            } else {\n              tag = entry;\n            }\n          }\n          if (!tag) continue;\n          if (tag.includes(\"EXT-X-CUE-OUT\") || tag.includes(\"EXT-X-DATERANGE\")) {\n            const attrs = tag.includes(\"EXT-X-DATERANGE\") ? parseAttributeList(value) : {};\n            const hasScteOut = tag.includes(\"EXT-X-CUE-OUT\") || \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== void 0;\n            if (hasScteOut) {\n              const durationSeconds = parseCueOutDuration(value);\n              const marker = {\n                type: \"start\",\n                ...durationSeconds !== void 0 ? { durationSeconds } : {},\n                raw: { tag, value, earlyDetection: true }\n              };\n              if (this.debug) {\n                console.log(\"[StormcloudVideoPlayer] EARLY SCTE-35 DETECTION: Ad break marker found in fragment\", i, \"- starting pre-fetch (NOT playing yet)\");\n              }\n              this.callbacks.onScte35Cue(marker, {\n                ...this.cueManager.createScte35CueContext(\"manifest\", \"early\", frag)\n              });\n              return;\n            }\n          }\n        }\n      }\n    });\n    this.hls.on(import_hls2.default.Events.FRAG_BUFFERED, async (_evt, _data) => {\n      if (this.hasInitialBufferCompleted) {\n        return;\n      }\n      this.bufferedSegmentsCount++;\n      const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] Buffered segment ${this.bufferedSegmentsCount}/${minSegments}`\n        );\n      }\n      if (this.bufferedSegmentsCount >= minSegments) {\n        this.hasInitialBufferCompleted = true;\n        if (this.shouldAutoplayAfterBuffering) {\n          if (this.debug) {\n            console.log(\n              `[StormcloudVideoPlayer] Initial buffer complete (${this.bufferedSegmentsCount} segments). Starting playback.`\n            );\n          }\n          await this.video.play()?.catch((err) => {\n            if (this.debug) {\n              console.warn(\"[StormcloudVideoPlayer] Autoplay failed:\", err);\n            }\n          });\n        }\n      }\n    });\n    this.hls.on(import_hls2.default.Events.FRAG_PARSING_METADATA, (_evt, data) => {\n      const id3Tags = (data?.samples || []).map((s) => ({\n        key: \"ID3\",\n        value: s?.data,\n        ptsSeconds: s?.pts\n      }));\n      id3Tags.forEach((tag) => this.onId3Tag(tag));\n    });\n    this.hls.on(import_hls2.default.Events.FRAG_LOADED, (_evt, data) => {\n      this.processFragmentScte35Payload(\n        data?.payload,\n        typeof data?.frag?.sn === \"number\" ? data.frag.sn : void 0,\n        getFragmentStartSeconds(data?.frag)\n      );\n    });\n    this.hls.on(import_hls2.default.Events.FRAG_DECRYPTED, (_evt, data) => {\n      this.processFragmentScte35Payload(\n        data?.payload,\n        typeof data?.frag?.sn === \"number\" ? data.frag.sn : void 0,\n        getFragmentStartSeconds(data?.frag)\n      );\n    });\n    this.hls.on(import_hls2.default.Events.FRAG_CHANGED, (_evt, data) => {\n      const frag = data?.frag;\n      const tagList = frag?.tagList;\n      if (!Array.isArray(tagList)) {\n        this.callbacks.activatePendingCuesForFragment(frag);\n        return;\n      }\n      for (const entry of tagList) {\n        let tag = \"\";\n        let value = \"\";\n        if (Array.isArray(entry)) {\n          tag = String(entry[0] ?? \"\");\n          value = String(entry[1] ?? \"\");\n        } else if (typeof entry === \"string\") {\n          const idx = entry.indexOf(\":\");\n          if (idx >= 0) {\n            tag = entry.substring(0, idx);\n            value = entry.substring(idx + 1);\n          } else {\n            tag = entry;\n            value = \"\";\n          }\n        }\n        if (!tag) continue;\n        if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n          const prog = parseCueOutCont(value);\n          const marker = {\n            type: \"progress\",\n            ...prog?.duration !== void 0 ? { durationSeconds: prog.duration } : {},\n            ...prog?.elapsed !== void 0 ? { ptsSeconds: prog.elapsed } : {},\n            raw: { tag, value }\n          };\n          this.callbacks.onScte35Cue(marker, {\n            ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag)\n          });\n        } else if (tag.includes(\"EXT-X-CUE-OUT\")) {\n          const durationSeconds = parseCueOutDuration(value);\n          const marker = {\n            type: \"start\",\n            ...durationSeconds !== void 0 ? { durationSeconds } : {},\n            raw: { tag, value }\n          };\n          this.callbacks.onScte35Cue(marker, {\n            ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag)\n          });\n        } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n          this.callbacks.onScte35Cue(\n            { type: \"end\", raw: { tag, value } },\n            {\n              ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag)\n            }\n          );\n        } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n          const attrs = parseAttributeList(value);\n          const hasScteOut = \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== void 0;\n          const hasScteIn = \"SCTE35-IN\" in attrs || attrs[\"SCTE35-IN\"] !== void 0;\n          const klass = String(attrs[\"CLASS\"] ?? \"\");\n          const duration = toNumber(attrs[\"DURATION\"]);\n          if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n            const marker = {\n              type: \"start\",\n              ...duration !== void 0 ? { durationSeconds: duration } : {},\n              raw: { tag, value, attrs }\n            };\n            this.callbacks.onScte35Cue(marker, {\n              ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag)\n            });\n          }\n          if (hasScteIn) {\n            this.callbacks.onScte35Cue(\n              { type: \"end\", raw: { tag, value, attrs } },\n              {\n                ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag)\n              }\n            );\n          }\n        }\n      }\n      this.callbacks.activatePendingCuesForFragment(frag);\n    });\n    this.hls.on(import_hls2.default.Events.ERROR, (_evt, data) => {\n      if (data?.fatal) {\n        switch (data.type) {\n          case import_hls2.default.ErrorTypes.NETWORK_ERROR:\n            this.hls?.startLoad();\n            break;\n          case import_hls2.default.ErrorTypes.MEDIA_ERROR:\n            this.hls?.recoverMediaError();\n            break;\n          default:\n            this.callbacks.onFatalDestroy();\n            break;\n        }\n      }\n    });\n    this.hls.attachMedia(this.video);\n  }\n  onId3Tag(tag) {\n    if (typeof tag.ptsSeconds === \"number\") {\n      this.timing.updatePtsDrift(tag.ptsSeconds);\n    }\n    const marker = parseScte35FromId3(tag);\n    if (marker) {\n      this.callbacks.onScte35Cue(marker, {\n        source: \"id3\",\n        readiness: \"playback\"\n      });\n    }\n  }\n  processFragmentScte35Payload(payloadData, fragmentSn, fragmentStartSeconds) {\n    const payload = normalizeFragmentPayload(payloadData);\n    if (!payload) {\n      return;\n    }\n    const markers = parseScte35FromTsPackets(\n      payload,\n      this.cueManager.tsScte35Pids,\n      this.cueManager.pmtPids,\n      this.cueManager.processedTsScte35Sections\n    );\n    markers.forEach((marker) => {\n      const context = {\n        source: \"ts\",\n        readiness: \"early\"\n      };\n      if (fragmentSn !== void 0) {\n        context.fragmentSn = fragmentSn;\n      }\n      if (fragmentStartSeconds !== void 0) {\n        context.fragmentStartSeconds = fragmentStartSeconds;\n      }\n      this.callbacks.onScte35Cue(marker, context);\n    });\n  }\n  getLiveSyncPosition() {\n    const pos = this.hls?.liveSyncPosition;\n    return typeof pos === \"number\" && Number.isFinite(pos) ? pos : void 0;\n  }\n  destroy() {\n    this.hls?.destroy();\n    this.hls = void 0;\n  }\n};\n\n// src/player/PlayerControls.ts\nfunction getAdAudioVolume(adPlayer) {\n  return adPlayer.getOriginalMutedState() ? 0 : adPlayer.getOriginalVolume();\n}\nfunction toggleMute(video, adPlayer, debug) {\n  if (adPlayer.isAdPlaying()) {\n    const newMutedState = !adPlayer.getOriginalMutedState();\n    const restoreVolume = adPlayer.getOriginalVolume() || 1;\n    adPlayer.updateOriginalMutedState(newMutedState, video.volume);\n    adPlayer.setAdVolume(newMutedState ? 0 : restoreVolume);\n    if (debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] Mute toggle during ad - immediately applied:\",\n        newMutedState\n      );\n    }\n  } else {\n    video.muted = !video.muted;\n    adPlayer.updateOriginalMutedState(video.muted, video.volume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] Muted:\", video.muted);\n    }\n  }\n}\nfunction toggleFullscreen(video, debug) {\n  return new Promise((resolve, reject) => {\n    if (!document.fullscreenElement) {\n      const container = video.parentElement;\n      if (!container) {\n        reject(new Error(\"No parent container found for fullscreen\"));\n        return;\n      }\n      container.requestFullscreen().then(() => {\n        if (debug) {\n          console.log(\"[StormcloudVideoPlayer] Entered fullscreen\");\n        }\n        resolve();\n      }).catch((err) => {\n        if (debug) {\n          console.error(\"[StormcloudVideoPlayer] Fullscreen error:\", err);\n        }\n        reject(err);\n      });\n    } else {\n      document.exitFullscreen().then(() => {\n        if (debug) {\n          console.log(\"[StormcloudVideoPlayer] Exited fullscreen\");\n        }\n        resolve();\n      }).catch((err) => {\n        if (debug) {\n          console.error(\n            \"[StormcloudVideoPlayer] Exit fullscreen error:\",\n            err\n          );\n        }\n        reject(err);\n      });\n    }\n  });\n}\nfunction isMuted(video, adPlayer) {\n  if (adPlayer.isAdPlaying()) {\n    return adPlayer.getOriginalMutedState();\n  }\n  return video.muted;\n}\nfunction setMuted(video, adPlayer, muted, debug) {\n  const adPlaying = adPlayer.isAdPlaying();\n  if (adPlaying && muted === video.muted) {\n    if (debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] setMuted reflective update during ad ignored\",\n        { muted }\n      );\n    }\n    return;\n  }\n  video.muted = muted;\n  if (adPlaying) {\n    adPlayer.updateOriginalMutedState(muted, video.volume);\n    adPlayer.setAdVolume(muted ? 0 : 1);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setMuted applied during ad\", {\n        muted\n      });\n    }\n    return;\n  }\n  adPlayer.updateOriginalMutedState(muted, video.volume);\n  if (debug) {\n    console.log(\"[StormcloudVideoPlayer] setMuted called:\", muted);\n  }\n}\nfunction setVolume(video, adPlayer, volume, debug) {\n  const clampedVolume = Math.max(0, Math.min(1, volume));\n  const adPlaying = adPlayer.isAdPlaying();\n  if (adPlaying) {\n    adPlayer.setAdVolume(clampedVolume);\n    adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setVolume applied during ad\", {\n        volume: clampedVolume\n      });\n    }\n  } else {\n    video.volume = clampedVolume;\n    video.muted = clampedVolume === 0;\n    adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setVolume called:\", clampedVolume);\n    }\n  }\n}\nfunction getVolume(video, adPlayer) {\n  const adPlaying = adPlayer.isAdPlaying();\n  if (adPlaying) {\n    return adPlayer.getAdVolume();\n  }\n  return video.volume;\n}\nfunction isFullscreen() {\n  return !!document.fullscreenElement;\n}\nfunction resizePlayer(video, adPlayer, debug) {\n  if (debug) {\n    console.log(\"[StormcloudVideoPlayer] Resizing player\");\n  }\n  if (adPlayer && adPlayer.isAdPlaying()) {\n    const width = video.clientWidth || 640;\n    const height = video.clientHeight || 480;\n    if (debug) {\n      console.log(\n        `[StormcloudVideoPlayer] Resizing ads manager to ${width}x${height}`\n      );\n    }\n    adPlayer.resize(width, height);\n  }\n}\n\n// src/player/AdBreakOrchestrator.ts\nvar AdBreakOrchestrator = class {\n  constructor(host, timing, adConfig, cueManager, placeholder) {\n    this.inAdBreak = false;\n    this.showAds = false;\n    this.isShowingPlaceholder = false;\n    this.adDetectSentForCurrentBreak = false;\n    this.continuousFetchingActive = false;\n    this.continuousFetchLoopRunning = false;\n    this.adRequestQueue = [];\n    this.adPodQueue = [];\n    this.maxPlaceholderDurationMs = 5e3;\n    this.pendingAdBreak = null;\n    this.host = host;\n    this.timing = timing;\n    this.adConfig = adConfig;\n    this.cueManager = cueManager;\n    this.placeholder = placeholder;\n  }\n  get debug() {\n    return !!this.host.config.debugAdTiming;\n  }\n  get analyticsContext() {\n    return buildAnalyticsContext(this.host.config);\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  IMA event listeners\n  // ───────────────────────────────────────────────────────────────\n  /**\n   * Produces the next pod ad-request URL for the current break. Every request\n   * (initial and continuous-fetch top-up) carries pod macros (pmad/pmnd/pmxd,\n   * no ppos); pmxd tracks the remaining break time so top-up pods only ask for\n   * what still fits.\n   */\n  nextAdRequestUrl(baseVastUrl) {\n    const remaining = Math.min(\n      this.timing.getWallClockRemainingAdMs(),\n      this.timing.getDurationBudgetRemainingMs()\n    );\n    const breakDurationMs = remaining > 0 ? remaining : void 0;\n    return this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);\n  }\n  attachImaEventListeners() {\n    const adPlayer = this.host.getAdPlayer();\n    adPlayer.on(\"pod_ad_started\", (payload) => {\n      this.timing.notePodAdStarted();\n      if (this.debug) {\n        console.log(\n          `[POD] Playing pod ad ${payload?.index != null ? payload.index + 1 : \"?\"}/${payload?.total ?? \"?\"}`\n        );\n      }\n    });\n    adPlayer.on(\"all_ads_completed\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n      this.timing.consecutiveFailures = 0;\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] all_ads_completed event received - remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n      if (this.inAdBreak) {\n        if (this.timing.hasTimeToStartAnotherAd()) {\n          this.tryNextAvailableAdWithRateLimit();\n        } else {\n          this.handleAdPodComplete();\n        }\n      }\n    });\n    adPlayer.on(\"ad_error\", (errorPayload) => {\n      let errorMessage = \"Ad playback failed\";\n      if (errorPayload) {\n        const errorCode = errorPayload.code || errorPayload.errorCode || \"unknown\";\n        const vastErrorCode = errorPayload.vastErrorCode;\n        const message = errorPayload.message || errorPayload.errorMessage || \"Unknown error\";\n        const cause = errorPayload.cause || errorPayload.innerError || errorPayload.error;\n        errorMessage = `Ad error: AdError ${errorCode}: ${message}`;\n        if (vastErrorCode && vastErrorCode !== \"N/A\" && vastErrorCode !== errorCode) {\n          errorMessage += ` (VAST Error Code: ${vastErrorCode})`;\n        }\n        if (cause) {\n          const causeMessage = typeof cause === \"string\" ? cause : cause.message || String(cause);\n          errorMessage += `. Caused by: ${causeMessage}`;\n        }\n      }\n      console.error(\"[AD-ERROR]\", errorMessage, errorPayload || \"\");\n      this.handleAdFailure();\n    });\n    adPlayer.on(\"content_pause\", () => {\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = true;\n      this.timing.resetGamNoFillCounter();\n      if (this.inAdBreak && this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)\");\n        }\n      }\n      this.host.getAdPlayer().setAdVolume(getAdAudioVolume(this.host.getAdPlayer()));\n      if (this.isShowingPlaceholder) {\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Hiding placeholder - new ads starting\");\n        }\n        this.host.getAdPlayer().hidePlaceholder();\n        this.isShowingPlaceholder = false;\n      }\n    });\n    adPlayer.on(\"content_resume\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      if (!this.host.video.muted) {\n        this.host.video.muted = true;\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Muted video on content_resume (ad ended, gap between ads)\");\n        }\n      }\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = false;\n      if (!this.inAdBreak) {\n        return;\n      }\n      this.timing.consecutiveFailures = 0;\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n      if (this.debug) {\n        console.log(\n          `[CONTINUOUS-FETCH] content_resume event: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n      if (this.timing.hasTimeToStartAnotherAd()) {\n        this.tryNextAvailableAdWithRateLimit();\n      } else {\n        this.handleAdPodComplete();\n      }\n    });\n  }\n  recreateAdController() {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Recreating AdController for new ad\");\n    }\n    const shouldShowPlaceholder = this.inAdBreak && this.showAds;\n    const adPlayer = this.host.getAdPlayer();\n    if (shouldShowPlaceholder && adPlayer) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Showing placeholder before destroying old AdController\");\n      }\n      this.placeholder.show();\n      adPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n    const preservedMutedState = adPlayer.getOriginalMutedState();\n    const preservedVolumeState = adPlayer.getOriginalVolume();\n    if (adPlayer) {\n      try {\n        adPlayer.destroy();\n        this.host.video.muted = true;\n      } catch (error) {\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] Error destroying old AdController:\", error);\n        }\n      }\n    }\n    const continueLiveStreamDuringAds = this.host.shouldContinueLiveStreamDuringAds();\n    const newAdPlayer = this.host.createAdPlayer(continueLiveStreamDuringAds);\n    this.host.setAdPlayer(newAdPlayer);\n    newAdPlayer.initialize();\n    newAdPlayer.updateOriginalMutedState(preservedMutedState, preservedVolumeState);\n    this.attachImaEventListeners();\n    if (shouldShowPlaceholder) {\n      this.placeholder.show();\n      newAdPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n  }\n  clearPendingAdBreak() {\n    if (this.prefetchTimerId != null) {\n      clearTimeout(this.prefetchTimerId);\n      this.prefetchTimerId = void 0;\n    }\n    this.pendingAdBreak = null;\n    this.cueManager.pendingScte35CueKey = void 0;\n    this.adConfig.podAssignedByPrefetch = false;\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Ad break start\n  // ───────────────────────────────────────────────────────────────\n  async handleAdStart(_marker) {\n    const scheduled = this.adConfig.findCurrentOrNextBreak(\n      this.host.video.currentTime * 1e3\n    );\n    if (scheduled) {\n      this.adConfig.consumedVmapBreakIds.add(this.adConfig.getAdBreakKey(scheduled));\n    }\n    const tags = this.adConfig.selectVastTagsForBreak(scheduled);\n    let baseVastUrl;\n    if (tags && tags.length > 0 && tags[0]) {\n      baseVastUrl = tags[0];\n    } else if (this.adConfig.apiVastTagUrl) {\n      baseVastUrl = this.adConfig.apiVastTagUrl;\n    } else {\n      this.clearPendingAdBreak();\n      return;\n    }\n    const adBreakDurationMs = _marker.durationSeconds != null ? _marker.durationSeconds * 1e3 : scheduled?.durationMs;\n    if (this.debug) {\n      const mode = this.host.config.isLiveStream ? \"LIVE\" : \"VOD\";\n      console.log(\n        `[CONTINUOUS-FETCH] ${mode} MODE: Target duration=${adBreakDurationMs}ms`\n      );\n    }\n    this.timing.failedVastUrls.clear();\n    this.timing.temporaryFailureUrls.clear();\n    this.timing.consecutiveFailures = 0;\n    this.continuousFetchingActive = true;\n    this.isShowingPlaceholder = false;\n    this.timing.totalAdRequestsInBreak = 0;\n    if (this.adConfig.podAssignedByPrefetch) {\n      this.adConfig.podAssignedByPrefetch = false;\n    } else {\n      this.adConfig.beginNewAdPod();\n    }\n    const currentMuted = this.host.video.muted;\n    const currentVolume = this.host.video.volume;\n    this.host.getAdPlayer().updateOriginalMutedState(currentMuted, currentVolume);\n    this.inAdBreak = true;\n    this.timing.adBreakPlayedDurationMs = 0;\n    this.timing.currentAdIndex = 0;\n    this.timing.totalAdsInBreak = 0;\n    this.adPodQueue = [];\n    this.showAds = false;\n    if (this.timing.expectedAdBreakDurationMs == null && adBreakDurationMs != null) {\n      this.timing.expectedAdBreakDurationMs = adBreakDurationMs;\n    }\n    const podPlayed = await this.startOptimizedPod(\n      baseVastUrl,\n      adBreakDurationMs,\n      currentMuted,\n      currentVolume\n    );\n    if (!podPlayed) {\n      if (this.debug) {\n        console.log(\"[POD] Initial pod request did not fill; attempting top-up pod request\");\n      }\n      this.continuousFetchingActive = true;\n      this.startContinuousFetching(baseVastUrl);\n      await this.tryNextAvailableAdWithRateLimit();\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Optimized pod (single multi-ad request)\n  // ───────────────────────────────────────────────────────────────\n  async startOptimizedPod(baseVastUrl, breakDurationMs, currentMuted, currentVolume) {\n    let podUrl;\n    if (this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0) {\n      podUrl = this.pendingAdBreak.vastUrls[0];\n      this.clearPendingAdBreak();\n    } else {\n      podUrl = this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);\n    }\n    if (!podUrl) {\n      return false;\n    }\n    this.continuousFetchingActive = false;\n    this.recreateAdController();\n    const adPlayer = this.host.getAdPlayer();\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      await adPlayer.requestAds(podUrl);\n      this.timing.clearAdRequestWatchdog();\n      if (this.timing.activeAdRequestToken !== requestToken) {\n        return true;\n      }\n      const podCount = adPlayer.getPodAdCount?.() ?? 1;\n      if (podCount < 1) {\n        return false;\n      }\n      if (this.debug) {\n        console.log(\n          podCount === 1 ? \"[POD] Response contained a single ad; playing it and enabling pod top-up\" : `[POD] Optimized pod returned ${podCount} ads; playing pod in one controller`\n        );\n      }\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: podUrl, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      this.timing.startAdFailsafeTimer(requestToken);\n      await adPlayer.play();\n      this.timing.markAdStarted();\n      if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n      }\n      adPlayer.setAdVolume(currentMuted ? 0 : currentVolume);\n      this.timing.consecutiveFailures = 0;\n      this.continuousFetchingActive = true;\n      this.startContinuousFetching(baseVastUrl);\n      return true;\n    } catch (error) {\n      this.timing.clearAdRequestWatchdog();\n      this.timing.clearAdFailsafeTimer();\n      if (this.timing.activeAdRequestToken === requestToken) {\n        this.timing.activeAdRequestToken = null;\n      }\n      if (this.debug) {\n        console.warn(\"[POD] Optimized pod request/play failed:\", error);\n      }\n      if (this.timing.isTemporaryAdError(error)) {\n        this.timing.temporaryFailureUrls.set(podUrl, Date.now());\n      }\n      this.continuousFetchingActive = true;\n      this.recreateAdController();\n      return false;\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Continuous fetching\n  // ───────────────────────────────────────────────────────────────\n  startContinuousFetching(baseVastUrl) {\n    if (!this.continuousFetchingActive) {\n      return;\n    }\n    if (this.continuousFetchLoopRunning) {\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Fetch loop already running, skipping duplicate start\");\n      }\n      return;\n    }\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] Starting continuous ad fetching loop\");\n    }\n    this.continuousFetchLoopRunning = true;\n    this.continuousFetchLoop(baseVastUrl);\n  }\n  async continuousFetchLoop(baseVastUrl) {\n    const epoch = this.timing.adBreakEpoch;\n    while (this.continuousFetchingActive && this.inAdBreak && epoch === this.timing.adBreakEpoch) {\n      const remaining = Math.min(\n        this.timing.getWallClockRemainingAdMs(),\n        this.timing.getDurationBudgetRemainingMs()\n      );\n      if (remaining <= this.timing.getMinRemainingMsToStartAd()) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Not enough ad break time left (wall=${this.timing.getWallClockRemainingAdMs()}ms, budget=${this.timing.getDurationBudgetRemainingMs()}ms), stopping URL generation`);\n        }\n        break;\n      }\n      if (this.timing.isGamInCooldown()) {\n        if (this.debug) {\n          console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, stopping URL generation\");\n        }\n        break;\n      }\n      if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), stopping URL generation`);\n        }\n        break;\n      }\n      if (this.timing.totalAdRequestsInBreak >= this.timing.maxTotalAdRequestsPerBreak) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Maximum ad requests reached (${this.timing.maxTotalAdRequestsPerBreak}), stopping`);\n        }\n        break;\n      }\n      const maxQueueSize = 5;\n      if (this.adRequestQueue.length >= maxQueueSize) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] URL queue full (${this.adRequestQueue.length}), waiting...`);\n        }\n        await new Promise((resolve) => setTimeout(resolve, 1e3));\n        continue;\n      }\n      const newAdUrl = this.nextAdRequestUrl(baseVastUrl);\n      if (!newAdUrl || this.timing.failedVastUrls.has(newAdUrl) || this.timing.isUrlInCooldown(newAdUrl)) {\n        await new Promise((resolve) => setTimeout(resolve, 500));\n        continue;\n      }\n      if (this.debug) {\n        const queuedUrlsPreview = [...this.adRequestQueue, newAdUrl];\n        console.log(\n          `[CONTINUOUS-FETCH] Queued VAST URL (queue size: ${queuedUrlsPreview.length})`,\n          { queuedUrls: queuedUrlsPreview }\n        );\n      }\n      this.adRequestQueue.push(newAdUrl);\n      const generationDelay = this.timing.consecutiveFailures > 0 ? Math.min(1e3 * Math.pow(2, this.timing.consecutiveFailures), 5e3) : 500;\n      await new Promise((resolve) => setTimeout(resolve, generationDelay));\n    }\n    this.continuousFetchLoopRunning = false;\n    if (this.debug) {\n      console.log(\n        `[CONTINUOUS-FETCH] URL generation loop ended (queued: ${this.adRequestQueue.length})`,\n        this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n      );\n    }\n  }\n  stopContinuousFetching() {\n    this.continuousFetchingActive = false;\n    this.continuousFetchLoopRunning = false;\n    this.placeholder.hide();\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] Stopping continuous ad fetching\");\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Ad iteration\n  // ───────────────────────────────────────────────────────────────\n  async tryNextAvailableAdWithRateLimit() {\n    if (!this.inAdBreak) {\n      return;\n    }\n    const epoch = this.timing.adBreakEpoch;\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), ending ad break gracefully`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n    const backoffMultiplier = Math.pow(2, this.timing.consecutiveFailures);\n    const backoffDelay = Math.min(this.timing.backoffBaseMs * backoffMultiplier, this.timing.maxBackoffMs);\n    const effectiveMinInterval = this.timing.minAdRequestIntervalMs + (this.timing.consecutiveFailures > 0 ? backoffDelay : 0);\n    const timeSinceLastRequest = Date.now() - this.timing.lastAdRequestTime;\n    if (timeSinceLastRequest < effectiveMinInterval) {\n      const waitTime = effectiveMinInterval - timeSinceLastRequest;\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Rate limiting: waiting ${waitTime}ms before next request (backoff: ${this.timing.consecutiveFailures} failures)`);\n      }\n      await new Promise((resolve) => setTimeout(resolve, waitTime));\n    }\n    if (!this.inAdBreak || epoch !== this.timing.adBreakEpoch) {\n      return;\n    }\n    return this.tryNextAvailableAd(0);\n  }\n  async tryNextAvailableAd(retryCount = 0) {\n    if (!this.inAdBreak) {\n      return;\n    }\n    const remaining = this.timing.getRemainingAdMs();\n    if (!this.timing.hasTimeToStartAnotherAd()) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Not enough time remaining (${remaining}ms) to start another ad, ending ad break`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) {\n        console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, ending ad break gracefully\");\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), ending ad break`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n    this.timing.cleanupTemporaryFailures();\n    while (this.adRequestQueue.length > 0) {\n      const nextAdUrl = this.adRequestQueue.shift();\n      if (!nextAdUrl) continue;\n      if (this.timing.failedVastUrls.has(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping permanently-failed URL, trying next...\");\n        continue;\n      }\n      if (this.timing.isUrlInCooldown(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping URL in cooldown (recent no-fill), trying next...\");\n        continue;\n      }\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Requesting next ad via HLS ad player (${this.timing.currentAdIndex + 1}, ${this.adRequestQueue.length} remaining in queue)`);\n      }\n      try {\n        await this.playSingleAd(nextAdUrl);\n        this.timing.consecutiveFailures = 0;\n      } catch (error) {\n        const errorMessage = error.message;\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Ad request failed:\", errorMessage);\n        if (errorMessage.includes(\"ad_duration_exceeds_budget\")) {\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n        if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n          this.timing.consecutiveFailures++;\n        }\n        await this.tryNextAvailableAdWithRateLimit();\n      }\n      return;\n    }\n    const maxRetries = 3;\n    if (this.continuousFetchingActive && retryCount < maxRetries && remaining > 2e3) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Queue empty, waiting for URLs... (${retryCount + 1}/${maxRetries})`);\n      }\n      await new Promise((resolve) => setTimeout(resolve, 500));\n      await this.tryNextAvailableAd(retryCount + 1);\n      return;\n    }\n    if (!this.isShowingPlaceholder && remaining > 1e3) {\n      this.showPlaceholderAndWaitForAds();\n    } else {\n      if (this.debug) console.log(\"[CONTINUOUS-FETCH] No more ads available, ending ad break\");\n      this.handleAdPodComplete();\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Single ad playback\n  // ───────────────────────────────────────────────────────────────\n  async playSingleAd(vastTagUrl) {\n    const adPlayer = this.host.getAdPlayer();\n    if (adPlayer.isAdPlaying()) return;\n    if (this.timing.failedVastUrls.has(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping permanently-failed VAST URL:\", vastTagUrl);\n      throw new Error(\"VAST URL permanently failed\");\n    }\n    if (this.timing.isUrlInCooldown(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping URL in cooldown (recent no-fill):\", vastTagUrl);\n      throw new Error(\"VAST URL in cooldown after no-fill\");\n    }\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.warn(\"[AD-ERROR] Too many consecutive failures, not requesting more ads\");\n      throw new Error(\"Too many consecutive failures\");\n    }\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) console.warn(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping ad request\");\n      throw new Error(\"GAM in cooldown\");\n    }\n    this.recreateAdController();\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      const ap = this.host.getAdPlayer();\n      await ap.requestAds(vastTagUrl);\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: vastTagUrl, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      this.timing.clearAdRequestWatchdog();\n      if (this.timing.activeAdRequestToken !== requestToken) return;\n      if (!this.timing.ensureLoadedAdFitsBudget(ap)) {\n        this.timing.rejectLoadedAdForDuration(ap);\n        this.recreateAdController();\n        throw new Error(\"ad_duration_exceeds_budget\");\n      }\n      try {\n        this.timing.startAdFailsafeTimer(requestToken);\n        await ap.play();\n        this.timing.markAdStarted();\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n        ap.setAdVolume(getAdAudioVolume(ap));\n        this.timing.consecutiveFailures = 0;\n        this.timing.temporaryFailureUrls.delete(vastTagUrl);\n      } catch (playError) {\n        if (this.debug) console.error(\"[AD-ERROR] Failed to play ad:\", playError);\n        if (this.timing.isTemporaryAdError(playError)) {\n          this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());\n          if (this.debug) console.log(\"[AD-ERROR] Temporary play error - URL can be retried after cooldown\");\n        } else {\n          this.timing.failedVastUrls.add(vastTagUrl);\n          if (this.debug) console.log(\"[AD-ERROR] Permanent play error - URL blacklisted\");\n        }\n        this.timing.clearAdFailsafeTimer();\n        if (this.timing.activeAdRequestToken === requestToken) {\n          this.timing.activeAdRequestToken = null;\n        }\n        throw playError;\n      }\n    } catch (error) {\n      const errorMessage = error?.message || \"\";\n      if (this.debug) console.error(\"[AD-ERROR] Ad request failed:\", errorMessage);\n      if (this.timing.isTemporaryAdError(error)) {\n        this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());\n        if (this.debug) console.log(\"[AD-ERROR] Temporary error (no-fill/timeout) - URL can be retried after cooldown\");\n      } else {\n        this.timing.failedVastUrls.add(vastTagUrl);\n        if (this.debug) console.log(\"[AD-ERROR] Permanent error - URL blacklisted:\", errorMessage);\n      }\n      this.timing.clearAdRequestWatchdog();\n      this.timing.clearAdFailsafeTimer();\n      if (this.timing.activeAdRequestToken === requestToken) {\n        this.timing.activeAdRequestToken = null;\n      }\n      throw error;\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Placeholder wait\n  // ───────────────────────────────────────────────────────────────\n  async showPlaceholderAndWaitForAds() {\n    const remaining = this.timing.getRemainingAdMs();\n    const waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping placeholder wait\");\n      this.handleAdPodComplete();\n      return;\n    }\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping placeholder - too many consecutive failures\");\n      this.handleAdPodComplete();\n      return;\n    }\n    if (waitTime < 1e3) {\n      this.handleAdPodComplete();\n      return;\n    }\n    if (this.debug) {\n      console.log(`[CONTINUOUS-FETCH] Showing placeholder for ${waitTime}ms while waiting for ad URLs`);\n    }\n    this.isShowingPlaceholder = true;\n    this.host.getAdPlayer().showPlaceholder();\n    const checkInterval = 300;\n    const maxChecks = Math.floor(waitTime / checkInterval);\n    for (let i = 0; i < maxChecks; i++) {\n      await new Promise((resolve) => setTimeout(resolve, checkInterval));\n      if (!this.inAdBreak) return;\n      if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Too many failures during placeholder wait\");\n        break;\n      }\n      if (!this.timing.hasTimeToStartAnotherAd()) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Not enough time remaining during placeholder wait, ending ad break\");\n        break;\n      }\n      while (this.adRequestQueue.length > 0) {\n        if (!this.timing.hasTimeToStartAnotherAd()) break;\n        const nextAdUrl = this.adRequestQueue.shift();\n        if (!nextAdUrl) continue;\n        if (this.timing.failedVastUrls.has(nextAdUrl)) continue;\n        if (this.timing.isUrlInCooldown(nextAdUrl)) continue;\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Ad URL available, requesting via HLS ad player\");\n        this.isShowingPlaceholder = false;\n        this.host.getAdPlayer().hidePlaceholder();\n        try {\n          await this.playSingleAd(nextAdUrl);\n          this.timing.consecutiveFailures = 0;\n        } catch (error) {\n          const errorMessage = error.message;\n          if (errorMessage.includes(\"ad_duration_exceeds_budget\")) {\n            await this.tryNextAvailableAdWithRateLimit();\n            return;\n          }\n          if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n            this.timing.consecutiveFailures++;\n          }\n          await this.tryNextAvailableAdWithRateLimit();\n        }\n        return;\n      }\n    }\n    if (this.debug) console.log(\"[CONTINUOUS-FETCH] Placeholder timeout, ending ad break\");\n    this.isShowingPlaceholder = false;\n    this.host.getAdPlayer().hidePlaceholder();\n    this.handleAdPodComplete();\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Ad break completion\n  // ───────────────────────────────────────────────────────────────\n  handleAdPodComplete() {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Ad pod complete - cleaning up\");\n    }\n    this.timing.resetForBreakEnd();\n    this.stopContinuousFetching();\n    this.clearPendingAdBreak();\n    if (this.isShowingPlaceholder) {\n      this.host.getAdPlayer().hidePlaceholder();\n      this.isShowingPlaceholder = false;\n    }\n    this.adRequestQueue = [];\n    this.inAdBreak = false;\n    this.adDetectSentForCurrentBreak = false;\n    this.cueManager.activeScte35BreakKey = void 0;\n    this.cueManager.scheduledScte35BreakKey = void 0;\n    this.adPodQueue = [];\n    this.showAds = false;\n    this.host.getAdPlayer().stop().catch(() => {\n    });\n    const restoredMuted = this.host.getAdPlayer().getOriginalMutedState();\n    const restoredVolume = this.host.getAdPlayer().getOriginalVolume();\n    if (this.host.video.muted !== restoredMuted) {\n      this.host.video.muted = restoredMuted;\n    }\n    if (Math.abs(this.host.video.volume - restoredVolume) > 0.01) {\n      this.host.video.volume = restoredVolume;\n    }\n    if (this.host.shouldContinueLiveStreamDuringAds()) {\n      const liveSyncPos = this.host.getLiveSyncPosition();\n      if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {\n        if (this.debug) {\n          console.log(\n            `[StormcloudVideoPlayer] Live break end \\u2014 snapping to live edge: ${this.host.video.currentTime.toFixed(2)}s \\u2192 ${liveSyncPos.toFixed(2)}s`\n          );\n        }\n        this.host.video.currentTime = liveSyncPos;\n      }\n      if (this.host.video.paused) {\n        if (this.debug) console.log(\"[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback\");\n        this.host.video.play()?.catch(() => {\n        });\n      } else {\n        if (this.debug) console.log(\"[StormcloudVideoPlayer] Content video already playing in live mode after ads\");\n      }\n    } else if (this.host.video.paused) {\n      this.host.video.play()?.catch(() => {\n      });\n    }\n  }\n  handleAdFailure() {\n    this.timing.consecutiveFailures++;\n    this.timing.recordGamNoFill();\n    const remaining = this.timing.getRemainingAdMs();\n    if (this.debug) {\n      console.log(\n        `[CONTINUOUS-FETCH] Ad failure: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}, consecutiveFailures=${this.timing.consecutiveFailures}`,\n        this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n      );\n    }\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.log(`[CONTINUOUS-FETCH] Max consecutive failures reached (${this.timing.consecutiveFailures}), ending ad break gracefully`);\n      this.handleAdPodComplete();\n      return;\n    }\n    if (this.timing.hasTimeToStartAnotherAd()) {\n      this.tryNextAvailableAdWithRateLimit();\n    } else {\n      if (this.debug) console.log(\"[AD-ERROR] Ad failed and not enough time remaining for another ad. Failed URLs:\", this.timing.failedVastUrls.size);\n      this.handleAdPodComplete();\n    }\n  }\n};\n\n// src/player/StormcloudVideoPlayer.ts\nvar StormcloudVideoPlayer = class {\n  constructor(config) {\n    this.attached = false;\n    this.palPlaybackStarted = false;\n    initializePolyfills();\n    const browserOverrides = getBrowserConfigOverrides();\n    this.config = { ...browserOverrides, ...config };\n    this.video = config.videoElement;\n    logBrowserInfo(config.debugAdTiming);\n    this.adPlayer = this.createAdPlayer(false);\n    this.palNonce = createPalNonceManager();\n    this.cueManager = new Scte35CueManager(!!this.config.debugAdTiming, {\n      onEarlyStartCue: (marker, fragmentSn, cueKey) => {\n        this.startAdPrefetch(marker, fragmentSn, cueKey);\n      },\n      onPlaybackCue: (marker, cueKey) => {\n        this.onScte35Marker(marker, cueKey);\n      },\n      isInAdBreak: () => this.adBreak.inAdBreak\n    });\n    this.adConfig = new AdConfigManager(this.config, this.video);\n    this.timing = new AdTimingService(this.config, this.video, {\n      onAdStopTimerFired: () => this.onAdStopTimerFired(),\n      onAdStartTimerFired: (marker, cueKey) => {\n        this.startScte35AdBreak(\n          marker,\n          cueKey,\n          marker.durationSeconds != null ? marker.durationSeconds * 1e3 : this.timing.expectedAdBreakDurationMs\n        );\n      },\n      onWatchdogTimeout: () => this.adBreak.handleAdFailure(),\n      onFailsafeTimeout: () => this.adBreak.handleAdFailure()\n    });\n    this.placeholder = new PlaceholderLayer(this.video, !!this.config.debugAdTiming);\n    this.hlsEngine = new HlsEngine(this.config, this.video, this.cueManager, this.timing, {\n      onManifestParsed: async (isLive) => this.onManifestParsed(isLive),\n      onScte35Cue: (marker, context) => this.cueManager.onScte35Cue(marker, context),\n      activatePendingCuesForFragment: (frag) => this.cueManager.activatePendingScte35CuesForFragment(frag),\n      onFatalDestroy: () => this.destroy(),\n      isInAdBreak: () => this.adBreak.inAdBreak,\n      hasPendingAdBreak: () => this.adBreak.pendingAdBreak !== null\n    });\n    this.adBreak = new AdBreakOrchestrator(\n      {\n        config: this.config,\n        video: this.video,\n        getAdPlayer: () => this.adPlayer,\n        setAdPlayer: (p) => {\n          this.adPlayer = p;\n        },\n        createAdPlayer: (c) => this.createAdPlayer(c),\n        shouldContinueLiveStreamDuringAds: () => this.shouldContinueLiveStreamDuringAds(),\n        getLiveSyncPosition: () => this.hlsEngine.getLiveSyncPosition(),\n        generatePodVastUrl: (base, breakDurationMs) => this.generatePodVastUrl(base, breakDurationMs)\n      },\n      this.timing,\n      this.adConfig,\n      this.cueManager,\n      this.placeholder\n    );\n  }\n  get debug() {\n    return !!this.config.debugAdTiming;\n  }\n  createAdPlayer(continueLiveStreamDuringAds) {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Creating HLS ad player\");\n    }\n    return createHlsAdPlayer(this.video, {\n      continueLiveStreamDuringAds,\n      ...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {},\n      ...this.hlsEngine?.hls ? { mainHlsInstance: this.hlsEngine.hls } : {}\n    });\n  }\n  generatePodVastUrl(baseUrl, breakDurationMs) {\n    const podParams = this.adConfig.resolvePodParams(breakDurationMs);\n    return this.adConfig.generatePodVastUrl(\n      baseUrl,\n      podParams,\n      this.adPlayer,\n      this.palNonce,\n      this.adBreak.inAdBreak\n    );\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Lifecycle\n  // ───────────────────────────────────────────────────────────────\n  async load() {\n    if (!this.attached) {\n      this.attach();\n    }\n    try {\n      await this.adConfig.fetchAdConfiguration();\n    } catch (error) {\n      if (this.debug) {\n        console.warn(\n          \"[StormcloudVideoPlayer] Failed to fetch ad configuration:\",\n          error\n        );\n      }\n    }\n    this.palNonce.generateNonce({\n      videoWidth: this.video.offsetWidth || this.video.clientWidth || 640,\n      videoHeight: this.video.offsetHeight || this.video.clientHeight || 480,\n      adWillAutoPlay: !!this.config.autoplay,\n      adWillPlayMuted: true,\n      playerVolume: 0,\n      continuousPlayback: this.config.lowLatencyMode ?? false\n    }).catch(() => {\n    });\n    fetchConsentSignals().then((signals) => {\n      this.adConfig.consentSignals = signals;\n    }).catch(() => {\n    });\n    this.adConfig.initializeTracking();\n    if (this.hlsEngine.shouldUseNativeHls(() => this.getStreamType())) {\n      await this.hlsEngine.setupNativeHls();\n      const continueLiveStreamDuringAds = this.shouldContinueLiveStreamDuringAds();\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Native HLS ad behavior:\", {\n          isLive: this.hlsEngine.isLiveStream,\n          continueLiveStreamDuringAds\n        });\n      }\n      this.adPlayer.destroy();\n      this.adPlayer = this.createAdPlayer(continueLiveStreamDuringAds);\n      this.adPlayer.initialize();\n      return;\n    }\n    this.hlsEngine.setupHls();\n  }\n  async onManifestParsed(isLive) {\n    if (!this.adConfig.isVmapEnabled() && !isLive && this.adConfig.vmapBreaks.length === 0 && this.adConfig.apiVastTagUrl) {\n      const prerollKey = \"synthetic-vod-preroll\";\n      if (!this.adConfig.consumedVmapBreakIds.has(prerollKey)) {\n        this.adConfig.vmapBreaks = [\n          { id: prerollKey, startTimeMs: 0, vastTagUrl: this.adConfig.apiVastTagUrl }\n        ];\n        if (this.debug) {\n          console.log(\n            \"[StormcloudVideoPlayer] Injected synthetic VOD preroll from apiVastTagUrl\"\n          );\n        }\n      }\n    }\n    if (this.debug) {\n      const adBehavior = this.shouldContinueLiveStreamDuringAds() ? \"live (main video continues muted during ads)\" : \"vod (main video pauses during ads)\";\n      console.log(\"[StormcloudVideoPlayer] Stream type detected:\", {\n        isLive,\n        allowNativeHls: this.config.allowNativeHls,\n        adBehavior\n      });\n    }\n    this.adPlayer.destroy();\n    this.adPlayer = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());\n    this.adPlayer.initialize();\n  }\n  attach() {\n    if (this.attached) return;\n    this.attached = true;\n    this.video.autoplay = !!this.config.autoplay;\n    this.video.muted = !!this.config.muted;\n    this.adPlayer.initialize();\n    this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n    this.adBreak.attachImaEventListeners();\n    this.video.addEventListener(\"play\", () => {\n      if (!this.palPlaybackStarted && !this.adPlayer.isAdPlaying()) {\n        this.palPlaybackStarted = true;\n        this.palNonce.sendPlaybackStart();\n      }\n    });\n    this.endedHandler = () => {\n      if (this.palPlaybackStarted) {\n        this.palPlaybackStarted = false;\n        this.palNonce.sendPlaybackEnd();\n      }\n      this.onVideoEnded();\n    };\n    this.video.addEventListener(\"ended\", this.endedHandler);\n    this.video.addEventListener(\"mousedown\", (e) => {\n      this.palNonce.sendAdTouch(e);\n    });\n    this.video.addEventListener(\"touchstart\", (e) => {\n      this.palNonce.sendAdTouch(e);\n    });\n    this.timeUpdateHandler = () => {\n      this.onTimeUpdate(this.video.currentTime);\n    };\n    this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n    this.emptiedHandler = () => {\n      if (this.hlsEngine.nativeHlsMode && this.hlsEngine.videoSrcProtection && !this.adPlayer.isAdPlaying()) {\n        if (this.debug) {\n          console.log(\n            \"[StormcloudVideoPlayer] Video src was cleared, restoring:\",\n            this.hlsEngine.videoSrcProtection\n          );\n        }\n        const currentTime = this.video.currentTime;\n        const wasPaused = this.video.paused;\n        this.video.src = this.hlsEngine.videoSrcProtection;\n        this.video.currentTime = currentTime;\n        if (!wasPaused) {\n          this.video.play().catch(() => {\n          });\n        }\n      }\n    };\n    this.video.addEventListener(\"emptied\", this.emptiedHandler);\n  }\n  shouldContinueLiveStreamDuringAds() {\n    if (this.hlsEngine.isLiveStream) {\n      return true;\n    }\n    const duration = this.video.duration;\n    if (!Number.isFinite(duration) || duration === Infinity) {\n      return true;\n    }\n    return false;\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  SCTE-35 marker orchestration\n  // ───────────────────────────────────────────────────────────────\n  onScte35Marker(marker, cueKey) {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] SCTE-35 marker detected:\", {\n        type: marker.type,\n        ptsSeconds: marker.ptsSeconds,\n        durationSeconds: marker.durationSeconds,\n        currentTime: this.video.currentTime,\n        raw: marker.raw,\n        hasPendingAdBreak: !!this.adBreak.pendingAdBreak\n      });\n    }\n    if (marker.type === \"start\") {\n      if (this.adBreak.inAdBreak) {\n        if (marker.durationSeconds != null) {\n          const newDurationMs = marker.durationSeconds * 1e3;\n          if (this.timing.expectedAdBreakDurationMs == null || newDurationMs > this.timing.expectedAdBreakDurationMs) {\n            this.timing.setAdBreakDurationBoundary(newDurationMs);\n            this.timing.scheduleAdStopAtBreakBoundary();\n            if (this.debug) {\n              console.log(\n                `[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ${newDurationMs}ms, remaining: ${this.timing.getWallClockRemainingAdMs()}ms`\n              );\n            }\n          }\n        }\n        return;\n      }\n      if (!this.adBreak.adDetectSentForCurrentBreak) {\n        this.adBreak.adDetectSentForCurrentBreak = true;\n        const detectPayload = {};\n        if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;\n        if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;\n        sendAdDetectTracking(this.config.licenseKey, { source: \"scte35\", timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...detectPayload }, buildAnalyticsContext(this.config)).catch(() => {\n        });\n      }\n      const hasPrefetchedAds = this.adBreak.pendingAdBreak && this.adBreak.pendingAdBreak.vastUrls.length > 0;\n      const durationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : this.adBreak.pendingAdBreak?.marker.durationSeconds != null ? this.adBreak.pendingAdBreak.marker.durationSeconds * 1e3 : void 0;\n      const isManifest = isManifestBasedMarker(marker);\n      const forceImmediate = this.config.immediateManifestAds ?? true;\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ad start decision:\", {\n          isManifestMarker: isManifest,\n          forceImmediate,\n          hasPts: typeof marker.ptsSeconds === \"number\",\n          hasPrefetchedAds\n        });\n      }\n      if (isManifest && forceImmediate) {\n        if (this.debug) {\n          console.log(\n            `[StormcloudVideoPlayer] Starting ad immediately (manifest-based)${hasPrefetchedAds ? \" with prefetched ads\" : \"\"}`\n          );\n        }\n        this.timing.clearAdStartTimer();\n        this.startScte35AdBreak(marker, cueKey, durationMs);\n      } else if (typeof marker.ptsSeconds === \"number\") {\n        const tol = this.config.driftToleranceMs ?? 1e3;\n        const nowMs = this.video.currentTime * 1e3;\n        const estCurrentPtsMs = nowMs - this.timing.ptsDriftEmaMs;\n        const deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] PTS-based timing calculation:\", {\n            nowMs,\n            estCurrentPtsMs,\n            markerPtsMs: marker.ptsSeconds * 1e3,\n            deltaMs,\n            tolerance: tol\n          });\n        }\n        if (deltaMs > tol) {\n          if (this.debug) {\n            console.log(`[StormcloudVideoPlayer] Scheduling ad start in ${deltaMs}ms`);\n          }\n          this.timing.expectedAdBreakDurationMs = durationMs;\n          this.cueManager.scheduledScte35BreakKey = cueKey;\n          this.timing.scheduleAdStartIn(deltaMs, marker, cueKey);\n        } else {\n          if (this.debug) {\n            console.log(\"[StormcloudVideoPlayer] Starting ad immediately (within tolerance)\");\n          }\n          this.timing.clearAdStartTimer();\n          this.startScte35AdBreak(marker, cueKey, durationMs);\n        }\n      } else {\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Starting ad immediately (fallback)\");\n        }\n        this.timing.clearAdStartTimer();\n        this.startScte35AdBreak(marker, cueKey, durationMs);\n      }\n      return;\n    }\n    if (marker.type === \"progress\" && this.adBreak.inAdBreak) {\n      if (marker.durationSeconds != null) {\n        this.timing.setAdBreakDurationBoundary(marker.durationSeconds * 1e3);\n      }\n      this.timing.scheduleAdStopAtBreakBoundary();\n      if (!this.adPlayer.isAdPlaying() && this.timing.activeAdRequestToken === null && this.adBreak.adRequestQueue.length > 0 && this.timing.hasTimeToStartAnotherAd()) {\n        this.adBreak.tryNextAvailableAdWithRateLimit();\n      }\n      return;\n    }\n    if (marker.type === \"end\") {\n      if (!this.video.muted) {\n        this.video.muted = true;\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Muted video on SCTE end marker\");\n        }\n      }\n      const remaining = this.timing.getRemainingAdMs();\n      const adPlaying = this.adPlayer.isAdPlaying();\n      const hasQueuedAds = this.adBreak.adRequestQueue.length > 0;\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] SCTE-35 end marker received:\", {\n          remaining,\n          adPlaying,\n          hasQueuedAds,\n          activeAdRequest: this.timing.activeAdRequestToken !== null\n        });\n      }\n      this.timing.scteAdBreakEndWallClockMs = Date.now();\n      this.timing.clearAdStartTimer();\n      this.timing.clearAdStopTimer();\n      if (adPlaying) {\n        this.adPlayer.stop().catch(() => {\n        });\n      }\n      this.adBreak.handleAdPodComplete();\n      return;\n    }\n  }\n  startScte35AdBreak(marker, cueKey, durationMs) {\n    this.adBreak.inAdBreak = true;\n    this.cueManager.activeScte35BreakKey = cueKey ?? this.cueManager.pendingScte35CueKey;\n    this.cueManager.scheduledScte35BreakKey = void 0;\n    this.timing.currentAdBreakStartWallClockMs = this.timing.resolveScteBreakStartWallClockMs(marker);\n    this.timing.setAdBreakDurationBoundary(durationMs);\n    this.adBreak.handleAdStart(marker);\n    this.timing.scheduleAdStopAtBreakBoundary();\n  }\n  onAdStopTimerFired() {\n    if (!this.adBreak.inAdBreak) return;\n    const adPlaying = this.adPlayer.isAdPlaying();\n    const checkIntervalMs = Math.max(\n      250,\n      Math.floor(this.config.adBreakCheckIntervalMs ?? 1e3)\n    );\n    const maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;\n    const maxExtensionMs = typeof maxExtensionMsConfig === \"number\" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 0;\n    const endWallClockMs = this.timing.getAdBreakEndWallClockMs() ?? Date.now();\n    const overrunMs = Math.max(0, Date.now() - endWallClockMs);\n    const shouldExtendAdBreak = adPlaying && overrunMs < maxExtensionMs;\n    if (shouldExtendAdBreak) {\n      this.timing.scheduleAdStopCountdown(checkIntervalMs);\n      return;\n    }\n    if (this.debug) {\n      console.log(\n        `[StormcloudVideoPlayer] Ad break boundary reached (overrun=${overrunMs}ms) - hard-stopping ads and resuming stream`\n      );\n    }\n    if (adPlaying) {\n      this.adPlayer.stop().catch(() => {\n      });\n    }\n    this.adBreak.handleAdPodComplete();\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Ad prefetch\n  // ───────────────────────────────────────────────────────────────\n  startAdPrefetch(marker, fragmentSn, cueKey) {\n    if (this.adBreak.pendingAdBreak || this.adBreak.inAdBreak) return;\n    const scheduled = this.adConfig.findCurrentOrNextBreak(this.video.currentTime * 1e3);\n    const tags = this.adConfig.selectVastTagsForBreak(scheduled);\n    let baseVastUrl;\n    if (tags && tags.length > 0 && tags[0]) {\n      baseVastUrl = tags[0];\n    } else if (this.adConfig.apiVastTagUrl) {\n      baseVastUrl = this.adConfig.apiVastTagUrl;\n    } else {\n      if (this.debug) console.warn(\"[StormcloudVideoPlayer] No VAST URL available for prefetch\");\n      return;\n    }\n    this.adConfig.beginNewAdPod();\n    this.adConfig.podAssignedByPrefetch = true;\n    const breakDurationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : void 0;\n    const generatedUrls = [this.generatePodVastUrl(baseVastUrl, breakDurationMs)];\n    this.adBreak.pendingAdBreak = {\n      marker,\n      ...fragmentSn !== void 0 ? { detectedAtFragmentSn: fragmentSn } : {},\n      vastUrls: generatedUrls,\n      isFetching: false,\n      fetchStartTime: Date.now()\n    };\n    this.cueManager.pendingScte35CueKey = cueKey;\n    this.adBreak.adDetectSentForCurrentBreak = true;\n    const detectPayload = {};\n    if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;\n    if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;\n    if (fragmentSn !== void 0) detectPayload.detectedAtFragmentSn = fragmentSn;\n    sendAdDetectTracking(this.config.licenseKey, { source: \"scte35\", timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...detectPayload }, buildAnalyticsContext(this.config)).catch(() => {\n    });\n    if (this.debug) {\n      console.log(\"[PREFETCH] Starting ad prefetch for upcoming ad break\");\n      console.log(`[PREFETCH] Pre-generated pod request URL`);\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  VMAP time-based ad breaks\n  // ───────────────────────────────────────────────────────────────\n  onTimeUpdate(currentTimeSec) {\n    if (!this.adConfig.isVmapEnabled() || this.adConfig.vmapBreaks.length === 0) return;\n    if (this.adPlayer.isAdPlaying() || this.adBreak.inAdBreak) return;\n    const nowMs = currentTimeSec * 1e3;\n    const breakToPlay = this.adConfig.findBreakForTime(nowMs);\n    if (breakToPlay) {\n      void this.handleVmapAdBreak(breakToPlay, nowMs).catch((error) => {\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] VMAP ad break failed gracefully:\", error);\n        }\n      });\n    }\n  }\n  onVideoEnded() {\n    if (!this.adConfig.isVmapEnabled() || this.adConfig.vmapBreaks.length === 0) return;\n    if (this.adPlayer.isAdPlaying() || this.adBreak.inAdBreak) return;\n    const durationMs = Number.isFinite(this.video.duration) ? Math.floor(this.video.duration * 1e3) : 0;\n    const postroll = this.adConfig.vmapBreaks.find(\n      (b) => b.startTimeMs === -1 && !this.adConfig.consumedVmapBreakIds.has(this.adConfig.getAdBreakKey(b))\n    );\n    if (postroll) {\n      void this.handleVmapAdBreak(postroll, durationMs).catch((error) => {\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] VMAP post-roll failed gracefully:\", error);\n        }\n      });\n    }\n  }\n  async handleVmapAdBreak(adBreak, nowMs) {\n    const key = this.adConfig.getAdBreakKey(adBreak);\n    if (this.adConfig.consumedVmapBreakIds.has(key)) return;\n    const breakStartMs = this.adConfig.resolveBreakStartMs(adBreak);\n    if (breakStartMs == null) return;\n    const durationMs = adBreak.durationMs ?? 0;\n    const endMs = breakStartMs + durationMs;\n    const inWindow = durationMs > 0 ? nowMs >= breakStartMs && nowMs < endMs : nowMs >= breakStartMs;\n    if (inWindow) {\n      this.adConfig.consumedVmapBreakIds.add(key);\n      const tags = this.adConfig.selectVastTagsForBreak(adBreak);\n      if (!tags || tags.length === 0) return;\n      const first = tags[0];\n      const rest = tags.slice(1);\n      this.adBreak.adPodQueue = rest;\n      this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n      this.adBreak.showAds = true;\n      this.adBreak.inAdBreak = true;\n      this.timing.currentAdBreakStartWallClockMs = Date.now();\n      try {\n        await this.adBreak.playSingleAd(first);\n      } catch (error) {\n        this.adBreak.adPodQueue = [];\n        this.adBreak.inAdBreak = false;\n        this.adBreak.showAds = false;\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] VMAP ad request failed:\", error);\n        }\n      }\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Public API\n  // ───────────────────────────────────────────────────────────────\n  getCurrentAdIndex() {\n    return this.timing.currentAdIndex;\n  }\n  getTotalAdsInBreak() {\n    return this.timing.totalAdsInBreak;\n  }\n  getAdRemainingMs() {\n    return this.timing.getRemainingAdMs();\n  }\n  isAdPlaying() {\n    return this.adBreak.inAdBreak && this.adPlayer.isAdPlaying();\n  }\n  isShowingAds() {\n    return this.adBreak.showAds;\n  }\n  getStreamType() {\n    const url = this.config.src.toLowerCase();\n    if (url.includes(\".m3u8\") || url.includes(\"/hls/\") || url.includes(\"application/vnd.apple.mpegurl\")) {\n      return \"hls\";\n    }\n    return \"other\";\n  }\n  shouldShowNativeControls() {\n    const streamType = this.getStreamType();\n    if (streamType === \"other\") {\n      return !(this.config.showCustomControls ?? false);\n    }\n    return !!(this.config.allowNativeHls && !(this.config.showCustomControls ?? false));\n  }\n  isLive() {\n    return this.hlsEngine.isLiveStream;\n  }\n  get videoElement() {\n    return this.video;\n  }\n  toggleMute() {\n    toggleMute(this.video, this.adPlayer, this.debug);\n  }\n  toggleFullscreen() {\n    return toggleFullscreen(this.video, this.debug);\n  }\n  isMuted() {\n    return isMuted(this.video, this.adPlayer);\n  }\n  setMuted(muted) {\n    setMuted(this.video, this.adPlayer, muted, this.debug);\n  }\n  setVolume(volume) {\n    setVolume(this.video, this.adPlayer, volume, this.debug);\n  }\n  getVolume() {\n    return getVolume(this.video, this.adPlayer);\n  }\n  isFullscreen() {\n    return isFullscreen();\n  }\n  resize() {\n    resizePlayer(this.video, this.adPlayer, this.debug);\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Destroy\n  // ───────────────────────────────────────────────────────────────\n  destroy() {\n    this.adBreak.stopContinuousFetching();\n    this.timing.destroy();\n    this.adBreak.clearPendingAdBreak();\n    this.placeholder.destroy();\n    if (this.timeUpdateHandler) {\n      this.video.removeEventListener(\"timeupdate\", this.timeUpdateHandler);\n      delete this.timeUpdateHandler;\n    }\n    if (this.endedHandler) {\n      this.video.removeEventListener(\"ended\", this.endedHandler);\n      delete this.endedHandler;\n    }\n    if (this.emptiedHandler) {\n      this.video.removeEventListener(\"emptied\", this.emptiedHandler);\n      delete this.emptiedHandler;\n    }\n    this.adConfig.destroyTracking();\n    this.hlsEngine.destroy();\n    this.adPlayer?.destroy();\n    if (this.palPlaybackStarted) {\n      this.palPlaybackStarted = false;\n      this.palNonce.sendPlaybackEnd();\n    }\n    this.palNonce.reset();\n    this.adBreak.adRequestQueue = [];\n    this.timing.consecutiveFailures = 0;\n  }\n};\n\n// src/ui/StormcloudVideoPlayer.tsx\nvar import_fa = require(\"react-icons/fa\");\nvar import_jsx_runtime = require(\"react/jsx-runtime\");\nvar CRITICAL_PROPS = [\n  \"src\",\n  \"allowNativeHls\",\n  \"isLiveStream\",\n  \"licenseKey\",\n  \"isVmap\",\n  \"vmapUrl\",\n  \"lowLatencyMode\",\n  \"driftToleranceMs\",\n  \"vastMode\",\n  \"ctvAdRequest\"\n];\nvar CONTROLS_HIDE_DELAY = 3e3;\nvar DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;\nvar StormcloudVideoPlayerComponent = import_react.default.memo(\n  (props) => {\n    const {\n      src,\n      autoplay,\n      muted,\n      lowLatencyMode,\n      allowNativeHls,\n      isLiveStream,\n      driftToleranceMs,\n      immediateManifestAds,\n      debugAdTiming,\n      showCustomControls,\n      hideLoadingIndicator,\n      onVolumeToggle,\n      onFullscreenToggle,\n      onControlClick,\n      onReady,\n      wrapperClassName,\n      wrapperStyle,\n      className,\n      style,\n      controls,\n      playsInline,\n      preload,\n      poster,\n      children,\n      licenseKey,\n      vastMode,\n      vastTagUrl,\n      isVmap,\n      vmapUrl,\n      minSegmentsBeforePlay,\n      ctvAdRequest,\n      ...restVideoAttrs\n    } = props;\n    const videoRef = (0, import_react.useRef)(null);\n    const playerRef = (0, import_react.useRef)(null);\n    const bufferingTimeoutRef = (0, import_react.useRef)(null);\n    const controlsTimerRef = (0, import_react.useRef)(null);\n    const wrapperRef = (0, import_react.useRef)(null);\n    const [adStatus, setAdStatus] = import_react.default.useState({ showAds: false, currentIndex: 0, totalAds: 0, remainingSeconds: 0 });\n    const [shouldShowNativeControls, setShouldShowNativeControls] = import_react.default.useState(true);\n    const [isMuted2, setIsMuted] = import_react.default.useState(false);\n    const [isFullscreen2, setIsFullscreen] = import_react.default.useState(false);\n    const [isPlaying, setIsPlaying] = import_react.default.useState(false);\n    const [currentTime, setCurrentTime] = import_react.default.useState(0);\n    const [duration, setDuration] = import_react.default.useState(0);\n    const [volume, setVolume2] = import_react.default.useState(1);\n    const [playbackRate, setPlaybackRate] = import_react.default.useState(1);\n    const [showVolumeSlider, setShowVolumeSlider] = import_react.default.useState(false);\n    const [showSpeedMenu, setShowSpeedMenu] = import_react.default.useState(false);\n    const [isLoading, setIsLoading] = import_react.default.useState(true);\n    const [isBuffering, setIsBuffering] = import_react.default.useState(false);\n    const [showCenterPlay, setShowCenterPlay] = import_react.default.useState(false);\n    const [showLicenseWarning, setShowLicenseWarning] = import_react.default.useState(false);\n    const [controlsVisible, setControlsVisible] = import_react.default.useState(true);\n    const [viewportWidth, setViewportWidth] = import_react.default.useState(\n      typeof window !== \"undefined\" ? window.innerWidth : 1920\n    );\n    const [isPortrait, setIsPortrait] = import_react.default.useState(\n      typeof window !== \"undefined\" ? window.innerHeight > window.innerWidth : false\n    );\n    const [playerAspectRatio, setPlayerAspectRatio] = import_react.default.useState(\n      DEFAULT_PLAYER_ASPECT_RATIO\n    );\n    const getResponsiveScale = () => {\n      if (viewportWidth < 480) return 0.7;\n      if (viewportWidth < 768) return 0.8;\n      if (viewportWidth < 1024) return 0.9;\n      return 1;\n    };\n    const responsiveScale = getResponsiveScale();\n    const resetControlsTimer = (0, import_react.useCallback)(() => {\n      if (controlsTimerRef.current) {\n        clearTimeout(controlsTimerRef.current);\n      }\n      setControlsVisible(true);\n      controlsTimerRef.current = window.setTimeout(() => {\n        if (!showVolumeSlider && !showSpeedMenu) {\n          setControlsVisible(false);\n        }\n      }, CONTROLS_HIDE_DELAY);\n    }, [showVolumeSlider, showSpeedMenu]);\n    const handleWrapperMouseMove = (0, import_react.useCallback)(() => {\n      resetControlsTimer();\n    }, [resetControlsTimer]);\n    const handleWrapperMouseLeave = (0, import_react.useCallback)(() => {\n      if (!showVolumeSlider && !showSpeedMenu) {\n        setControlsVisible(false);\n      }\n    }, [showVolumeSlider, showSpeedMenu]);\n    const formatTime = (seconds) => {\n      if (!isFinite(seconds)) return \"0:00:00\";\n      const hours = Math.floor(seconds / 3600);\n      const minutes = Math.floor(seconds % 3600 / 60);\n      const remainingSeconds = Math.floor(seconds % 60);\n      return `${hours}:${minutes.toString().padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n    };\n    const handlePlayPause = () => {\n      if (videoRef.current) {\n        if (videoRef.current.paused) {\n          const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n          if (hasValidSource) {\n            videoRef.current.play()?.catch((error) => {\n              console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n            });\n            setShowCenterPlay(false);\n          } else {\n            console.warn(\n              \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n            );\n          }\n        } else {\n          videoRef.current.pause();\n          setShowCenterPlay(true);\n        }\n      }\n      resetControlsTimer();\n    };\n    const handleCenterPlayClick = () => {\n      if (videoRef.current && videoRef.current.paused) {\n        const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n        if (hasValidSource) {\n          videoRef.current.play()?.catch((error) => {\n            console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n          });\n          setShowCenterPlay(false);\n        } else {\n          console.warn(\n            \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n          );\n        }\n      }\n    };\n    const handleTimelineSeek = (e) => {\n      if (videoRef.current && duration > 0 && isFinite(duration)) {\n        const rect = e.currentTarget.getBoundingClientRect();\n        const clickX = e.clientX - rect.left;\n        const progress = Math.max(0, Math.min(1, clickX / rect.width));\n        const newTime = progress * duration;\n        if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n          videoRef.current.currentTime = newTime;\n        }\n      }\n      resetControlsTimer();\n    };\n    const handleVolumeChange = (newVolume) => {\n      if (playerRef.current && isFinite(newVolume)) {\n        const clampedVolume = Math.max(0, Math.min(1, newVolume));\n        playerRef.current.setVolume(clampedVolume);\n      }\n    };\n    const handlePlaybackRateChange = (rate) => {\n      if (videoRef.current && isFinite(rate) && rate > 0) {\n        videoRef.current.playbackRate = rate;\n      }\n      setShowSpeedMenu(false);\n    };\n    const isHlsStream = src?.toLowerCase().includes(\".m3u8\") || src?.toLowerCase().includes(\"/hls/\");\n    const isLiveUiMode = isLiveStream === true;\n    const shouldShowEnhancedControls = showCustomControls && (isHlsStream ? !isLiveUiMode : true);\n    const criticalPropsKey = (0, import_react.useMemo)(() => {\n      return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n    }, [\n      src,\n      allowNativeHls,\n      isLiveStream,\n      licenseKey,\n      isVmap,\n      vmapUrl,\n      lowLatencyMode,\n      driftToleranceMs,\n      vastMode\n    ]);\n    (0, import_react.useEffect)(() => {\n      if (typeof window === \"undefined\") return;\n      const el = videoRef.current;\n      if (!el || !src) return;\n      if (!licenseKey) {\n        setShowLicenseWarning(true);\n        setIsLoading(false);\n        console.warn(\n          \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n        );\n        return;\n      }\n      setShowLicenseWarning(false);\n      if (debugAdTiming) {\n        console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n      }\n      if (playerRef.current) {\n        try {\n          playerRef.current.destroy();\n        } catch {\n        }\n        playerRef.current = null;\n      }\n      const cfg = {\n        src,\n        videoElement: el\n      };\n      if (autoplay !== void 0) cfg.autoplay = autoplay;\n      if (muted !== void 0) cfg.muted = muted;\n      if (lowLatencyMode !== void 0) cfg.lowLatencyMode = lowLatencyMode;\n      if (allowNativeHls !== void 0) cfg.allowNativeHls = allowNativeHls;\n      if (isLiveStream !== void 0) cfg.isLiveStream = isLiveStream;\n      if (driftToleranceMs !== void 0)\n        cfg.driftToleranceMs = driftToleranceMs;\n      if (immediateManifestAds !== void 0)\n        cfg.immediateManifestAds = immediateManifestAds;\n      if (debugAdTiming !== void 0) cfg.debugAdTiming = debugAdTiming;\n      if (showCustomControls !== void 0)\n        cfg.showCustomControls = showCustomControls;\n      if (onVolumeToggle !== void 0) cfg.onVolumeToggle = onVolumeToggle;\n      if (onFullscreenToggle !== void 0)\n        cfg.onFullscreenToggle = onFullscreenToggle;\n      if (onControlClick !== void 0) cfg.onControlClick = onControlClick;\n      if (licenseKey !== void 0) cfg.licenseKey = licenseKey;\n      if (vastMode !== void 0) cfg.vastMode = vastMode;\n      if (vastTagUrl !== void 0) cfg.vastTagUrl = vastTagUrl;\n      if (isVmap !== void 0) cfg.isVmap = isVmap;\n      if (vmapUrl !== void 0) cfg.vmapUrl = vmapUrl;\n      if (minSegmentsBeforePlay !== void 0)\n        cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n      if (ctvAdRequest !== void 0) cfg.ctvAdRequest = ctvAdRequest;\n      const player = new StormcloudVideoPlayer(cfg);\n      playerRef.current = player;\n      player.load().then(() => {\n        const showNative = player.shouldShowNativeControls();\n        setShouldShowNativeControls(showNative);\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n          );\n        }\n        onReady?.(player);\n      }).catch((error) => {\n        console.error(\n          \"StormcloudVideoPlayer: Failed to load player:\",\n          error\n        );\n        setIsLoading(false);\n        onReady?.(player);\n      });\n      return () => {\n        try {\n          player.destroy();\n        } catch {\n        }\n        playerRef.current = null;\n      };\n    }, [criticalPropsKey]);\n    (0, import_react.useEffect)(() => {\n      if (!playerRef.current) return;\n      try {\n        if (autoplay !== void 0 && playerRef.current.videoElement) {\n          playerRef.current.videoElement.autoplay = autoplay;\n        }\n        if (muted !== void 0 && !playerRef.current.isShowingAds()) {\n          playerRef.current.setMuted(muted);\n        }\n      } catch (error) {\n        console.warn(\"Failed to update player properties:\", error);\n      }\n    }, [autoplay, muted]);\n    (0, import_react.useEffect)(() => {\n      if (!playerRef.current) return;\n      const checkAdStatus = () => {\n        if (playerRef.current) {\n          const showAdsFromMethod = playerRef.current.isShowingAds();\n          const showAdsFromAttribute = videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n          const showAds = showAdsFromMethod || showAdsFromAttribute;\n          const currentIndex = playerRef.current.getCurrentAdIndex();\n          const totalAds = playerRef.current.getTotalAdsInBreak();\n          const remainingMs = playerRef.current.getAdRemainingMs();\n          const remainingSeconds = showAds ? Math.max(0, Math.ceil(remainingMs / 1e3)) : 0;\n          setAdStatus((prev) => {\n            if (prev.showAds !== showAds || prev.currentIndex !== currentIndex || prev.totalAds !== totalAds || prev.remainingSeconds !== remainingSeconds) {\n              if (showAds && !prev.showAds) {\n                setShowCenterPlay(false);\n              }\n              return { showAds, currentIndex, totalAds, remainingSeconds };\n            }\n            return prev;\n          });\n        }\n      };\n      const interval = setInterval(checkAdStatus, 50);\n      return () => clearInterval(interval);\n    }, []);\n    (0, import_react.useEffect)(() => {\n      if (typeof window === \"undefined\" || !playerRef.current) return;\n      const handleResize = () => {\n        if (playerRef.current && videoRef.current) {\n          if (typeof playerRef.current.resize === \"function\") {\n            playerRef.current.resize();\n          }\n        }\n        setViewportWidth(window.innerWidth);\n        setIsPortrait(window.innerHeight > window.innerWidth);\n      };\n      window.addEventListener(\"resize\", handleResize);\n      return () => window.removeEventListener(\"resize\", handleResize);\n    }, []);\n    (0, import_react.useEffect)(() => {\n      if (!playerRef.current || !videoRef.current) return;\n      const updateStates = () => {\n        if (playerRef.current && videoRef.current) {\n          setIsMuted(playerRef.current.isMuted());\n          setIsPlaying(!videoRef.current.paused);\n          const currentTimeValue = videoRef.current.currentTime;\n          setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n          const durationValue = videoRef.current.duration;\n          setDuration(isFinite(durationValue) ? durationValue : 0);\n          const volumeValue = playerRef.current.getVolume();\n          setVolume2(\n            isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n          );\n          const rateValue = videoRef.current.playbackRate;\n          setPlaybackRate(\n            isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n          );\n        }\n        setIsFullscreen(\n          document.fullscreenElement === wrapperRef.current\n        );\n      };\n      const interval = setInterval(updateStates, 200);\n      const handleFullscreenChange = () => {\n        setIsFullscreen(\n          document.fullscreenElement === wrapperRef.current\n        );\n      };\n      document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n      return () => {\n        clearInterval(interval);\n        document.removeEventListener(\n          \"fullscreenchange\",\n          handleFullscreenChange\n        );\n      };\n    }, []);\n    (0, import_react.useEffect)(() => {\n      if (!videoRef.current) return;\n      const handleLoadedMetadata = () => {\n        const video2 = videoRef.current;\n        if (video2) {\n          if (video2.videoWidth > 0 && video2.videoHeight > 0) {\n            setPlayerAspectRatio(video2.videoWidth / video2.videoHeight);\n          }\n          void video2.offsetHeight;\n        }\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n            videoRef.current?.readyState\n          );\n        }\n      };\n      const handleLoadedData = () => {\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: loadeddata, readyState:\",\n            videoRef.current?.readyState\n          );\n        }\n      };\n      const handleLoadStart = () => {\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: loadstart, readyState:\",\n            videoRef.current?.readyState\n          );\n        }\n      };\n      const handleCanPlay = () => {\n        setIsLoading(false);\n        if (bufferingTimeoutRef.current) {\n          clearTimeout(bufferingTimeoutRef.current);\n          bufferingTimeoutRef.current = null;\n        }\n        setIsBuffering(false);\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: canplay, readyState:\",\n            videoRef.current?.readyState,\n            \"- clearing loading state, isLoading=false\"\n          );\n        }\n      };\n      const handleCanPlayThrough = () => {\n        setIsLoading(false);\n        if (bufferingTimeoutRef.current) {\n          clearTimeout(bufferingTimeoutRef.current);\n          bufferingTimeoutRef.current = null;\n        }\n        setIsBuffering(false);\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n            videoRef.current?.readyState,\n            \"- clearing loading state, isLoading=false\"\n          );\n        }\n      };\n      const handleWaiting = () => {\n        if (bufferingTimeoutRef.current) {\n          clearTimeout(bufferingTimeoutRef.current);\n        }\n        bufferingTimeoutRef.current = window.setTimeout(() => {\n          setIsBuffering(true);\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n              videoRef.current?.readyState,\n              \"- showing spinner, isBuffering=true\"\n            );\n          }\n        }, 300);\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: waiting, readyState:\",\n            videoRef.current?.readyState,\n            \"- buffering delay started (300ms)\"\n          );\n        }\n      };\n      const handlePlaying = () => {\n        setIsLoading(false);\n        if (bufferingTimeoutRef.current) {\n          clearTimeout(bufferingTimeoutRef.current);\n          bufferingTimeoutRef.current = null;\n        }\n        setIsBuffering(false);\n        setShowCenterPlay(false);\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: playing, readyState:\",\n            videoRef.current?.readyState,\n            \"- playback started, isLoading=false, isBuffering=false\"\n          );\n        }\n      };\n      const handlePause = () => {\n        const isAdActive = playerRef.current?.isShowingAds() || videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n        if (playerRef.current && !isAdActive) {\n          setShowCenterPlay(true);\n        } else {\n          setShowCenterPlay(false);\n        }\n      };\n      const handleEnded = () => {\n        setShowCenterPlay(true);\n      };\n      const video = videoRef.current;\n      video.addEventListener(\"loadstart\", handleLoadStart);\n      video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n      video.addEventListener(\"loadeddata\", handleLoadedData);\n      video.addEventListener(\"canplay\", handleCanPlay);\n      video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n      video.addEventListener(\"waiting\", handleWaiting);\n      video.addEventListener(\"playing\", handlePlaying);\n      video.addEventListener(\"pause\", handlePause);\n      video.addEventListener(\"ended\", handleEnded);\n      if (video.paused) {\n        setShowCenterPlay(true);\n      }\n      return () => {\n        if (bufferingTimeoutRef.current) {\n          clearTimeout(bufferingTimeoutRef.current);\n          bufferingTimeoutRef.current = null;\n        }\n        video.removeEventListener(\"loadstart\", handleLoadStart);\n        video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n        video.removeEventListener(\"loadeddata\", handleLoadedData);\n        video.removeEventListener(\"canplay\", handleCanPlay);\n        video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n        video.removeEventListener(\"waiting\", handleWaiting);\n        video.removeEventListener(\"playing\", handlePlaying);\n        video.removeEventListener(\"pause\", handlePause);\n        video.removeEventListener(\"ended\", handleEnded);\n      };\n    }, [debugAdTiming]);\n    (0, import_react.useEffect)(() => {\n      setPlayerAspectRatio(DEFAULT_PLAYER_ASPECT_RATIO);\n    }, [src]);\n    (0, import_react.useEffect)(() => {\n      return () => {\n        if (controlsTimerRef.current) {\n          clearTimeout(controlsTimerRef.current);\n        }\n      };\n    }, []);\n    const progressPercent = duration > 0 ? currentTime / duration * 100 : 0;\n    const VolumeIcon = isMuted2 || volume === 0 ? import_fa.FaVolumeMute : volume < 0.5 ? import_fa.FaVolumeDown : import_fa.FaVolumeUp;\n    return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n      /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"style\", { children: `\n              @keyframes sc-spin {\n                from { transform: rotate(0deg); }\n                to { transform: rotate(360deg); }\n              }\n              @keyframes sc-loading-glow {\n                0%, 100% { opacity: 0.85; transform: scale(1); }\n                50% { opacity: 1; transform: scale(1.05); }\n              }\n              @keyframes sc-pulse {\n                0%, 100% { opacity: 1; }\n                50% { opacity: 0.6; }\n              }\n              @keyframes sc-fade-in {\n                from { opacity: 0; transform: translateY(8px); }\n                to { opacity: 1; transform: translateY(0); }\n              }\n              .sc-wrapper:fullscreen,\n              .sc-wrapper:has(*:fullscreen) {\n                border-radius: 0 !important;\n                box-shadow: none !important;\n                width: 100vw !important;\n                height: 100vh !important;\n                max-width: 100vw !important;\n                max-height: 100vh !important;\n                position: fixed !important;\n                top: 0 !important;\n                left: 0 !important;\n                z-index: 999999 !important;\n                background: #000 !important;\n                display: flex !important;\n                align-items: center !important;\n                justify-content: center !important;\n              }\n              .sc-ctrl-btn {\n                background: none;\n                border: none;\n                color: #fff;\n                cursor: pointer;\n                display: flex;\n                align-items: center;\n                justify-content: center;\n                border-radius: 50%;\n                padding: 8px;\n                transition: background 0.15s ease, opacity 0.15s ease;\n                opacity: 0.9;\n              }\n              .sc-ctrl-btn:hover {\n                opacity: 1;\n                background: rgba(255, 255, 255, 0.1);\n              }\n              .sc-ctrl-btn:active {\n                opacity: 0.7;\n              }\n              .sc-controls-bar {\n                transition: opacity 0.35s ease, transform 0.35s ease;\n              }\n              .sc-progress-track:hover .sc-progress-thumb {\n                transform: translate(-50%, -50%) scale(1) !important;\n              }\n              .sc-loading-hidden .sc-loading-indicator {\n                display: none !important;\n              }\n            ` }),\n      /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n        \"div\",\n        {\n          ref: wrapperRef,\n          className: `sc-wrapper ${wrapperClassName || \"\"}`,\n          onMouseMove: handleWrapperMouseMove,\n          onMouseLeave: handleWrapperMouseLeave,\n          style: {\n            display: \"flex\",\n            alignItems: \"center\",\n            justifyContent: \"center\",\n            position: isFullscreen2 ? \"fixed\" : \"relative\",\n            top: isFullscreen2 ? 0 : void 0,\n            left: isFullscreen2 ? 0 : void 0,\n            overflow: \"hidden\",\n            width: isFullscreen2 ? \"100vw\" : \"100%\",\n            height: isFullscreen2 ? \"100vh\" : \"auto\",\n            minHeight: isFullscreen2 ? \"100vh\" : \"auto\",\n            aspectRatio: isFullscreen2 ? void 0 : playerAspectRatio,\n            maxWidth: isFullscreen2 ? \"100vw\" : \"100%\",\n            maxHeight: isFullscreen2 ? \"100vh\" : \"none\",\n            zIndex: isFullscreen2 ? 999999 : void 0,\n            backgroundColor: \"#000\",\n            borderRadius: isFullscreen2 ? 0 : void 0,\n            boxShadow: isFullscreen2 ? \"none\" : void 0,\n            ...wrapperStyle\n          },\n          children: [\n            /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n              \"video\",\n              {\n                ref: videoRef,\n                className,\n                style: {\n                  display: \"block\",\n                  width: \"100%\",\n                  height: \"100%\",\n                  maxWidth: \"100%\",\n                  maxHeight: isFullscreen2 ? \"100%\" : \"none\",\n                  objectFit: isFullscreen2 ? \"cover\" : \"contain\",\n                  backgroundColor: \"#000\",\n                  aspectRatio: isFullscreen2 ? \"unset\" : void 0,\n                  ...style\n                },\n                controls: shouldShowNativeControls && controls && !showCustomControls,\n                playsInline,\n                preload,\n                poster,\n                ...restVideoAttrs,\n                children\n              }\n            ),\n            (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n              \"div\",\n              {\n                className: \"sc-loading-indicator\",\n                style: {\n                  position: \"absolute\",\n                  top: \"50%\",\n                  left: \"50%\",\n                  transform: \"translate(-50%, -50%)\",\n                  zIndex: 20,\n                  width: `${Math.max(34, 38 * responsiveScale)}px`,\n                  height: `${Math.max(34, 38 * responsiveScale)}px`,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  justifyContent: \"center\",\n                  animation: \"sc-loading-glow 1.4s ease-in-out infinite\",\n                  filter: \"drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55))\"\n                },\n                children: [\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                    \"div\",\n                    {\n                      style: {\n                        position: \"absolute\",\n                        inset: 0,\n                        borderRadius: \"50%\",\n                        border: \"3px solid rgba(255, 255, 255, 0.25)\",\n                        borderTopColor: \"#ff0000\",\n                        borderRightColor: \"rgba(255, 255, 255, 0.85)\",\n                        animation: \"sc-spin 0.8s linear infinite\"\n                      }\n                    }\n                  ),\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                    \"div\",\n                    {\n                      style: {\n                        width: \"7px\",\n                        height: \"7px\",\n                        borderRadius: \"50%\",\n                        background: \"#ff0000\",\n                        boxShadow: \"0 0 10px rgba(255, 0, 0, 0.65)\"\n                      }\n                    }\n                  )\n                ]\n              }\n            ),\n            showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n              \"div\",\n              {\n                style: {\n                  position: \"absolute\",\n                  top: \"50%\",\n                  left: \"50%\",\n                  transform: \"translate(-50%, -50%)\",\n                  zIndex: 25,\n                  background: \"rgba(220, 38, 38, 0.92)\",\n                  backdropFilter: \"blur(24px)\",\n                  color: \"white\",\n                  padding: \"28px 36px\",\n                  borderRadius: \"14px\",\n                  border: \"1px solid rgba(255, 255, 255, 0.15)\",\n                  boxShadow: \"0 24px 64px rgba(0, 0, 0, 0.5)\",\n                  textAlign: \"center\",\n                  maxWidth: \"400px\",\n                  margin: \"0 16px\"\n                },\n                children: [\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"18px\", fontWeight: \"700\", marginBottom: \"10px\", letterSpacing: \"-0.02em\" }, children: \"License Key Required\" }),\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { fontSize: \"13px\", lineHeight: \"1.6\", color: \"rgba(255, 255, 255, 0.85)\" }, children: [\n                    \"Please provide a valid license key to use the Stormcloud Video Player.\",\n                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"br\", {}),\n                    \"Contact your administrator for licensing information.\"\n                  ] })\n                ]\n              }\n            ),\n            adStatus.showAds && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n              \"div\",\n              {\n                style: {\n                  position: \"absolute\",\n                  top: `${12 * responsiveScale}px`,\n                  left: `${12 * responsiveScale}px`,\n                  zIndex: 50,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  gap: \"8px\",\n                  pointerEvents: \"none\",\n                  animation: \"sc-fade-in 0.3s ease\"\n                },\n                children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                  \"div\",\n                  {\n                    style: {\n                      background: \"rgba(234, 179, 8, 0.95)\",\n                      color: \"#111\",\n                      padding: `${4 * responsiveScale}px ${12 * responsiveScale}px`,\n                      borderRadius: \"6px\",\n                      fontSize: `${11 * responsiveScale}px`,\n                      fontWeight: 700,\n                      letterSpacing: \"0.08em\",\n                      textTransform: \"uppercase\",\n                      boxShadow: \"0 2px 12px rgba(234, 179, 8, 0.35)\"\n                    },\n                    children: `Ad ${Math.max(1, adStatus.currentIndex)}`\n                  }\n                )\n              }\n            ),\n            showCenterPlay && !isLoading && !isBuffering && !showLicenseWarning && !adStatus.showAds && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n              \"div\",\n              {\n                onClick: handleCenterPlayClick,\n                style: {\n                  position: \"absolute\",\n                  top: \"50%\",\n                  left: \"50%\",\n                  transform: \"translate(-50%, -50%)\",\n                  zIndex: 15,\n                  cursor: \"pointer\",\n                  background: \"rgba(0, 0, 0, 0.55)\",\n                  backdropFilter: \"blur(8px)\",\n                  borderRadius: \"50%\",\n                  width: `${92 * responsiveScale}px`,\n                  height: `${92 * responsiveScale}px`,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  justifyContent: \"center\",\n                  transition: \"background 0.2s ease, transform 0.2s ease\",\n                  animation: \"sc-fade-in 0.2s ease\"\n                },\n                onMouseEnter: (e) => {\n                  e.currentTarget.style.background = \"rgba(0, 0, 0, 0.72)\";\n                  e.currentTarget.style.transform = \"translate(-50%, -50%) scale(1.06)\";\n                },\n                onMouseLeave: (e) => {\n                  e.currentTarget.style.background = \"rgba(0, 0, 0, 0.55)\";\n                  e.currentTarget.style.transform = \"translate(-50%, -50%) scale(1)\";\n                },\n                title: \"Play\",\n                children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                  import_fa.FaPlay,\n                  {\n                    size: Math.max(24, 32 * responsiveScale),\n                    color: \"white\",\n                    style: { marginLeft: \"4px\" }\n                  }\n                )\n              }\n            ),\n            shouldShowEnhancedControls && !showLicenseWarning ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n              \"div\",\n              {\n                className: \"sc-controls-bar\",\n                style: {\n                  position: \"absolute\",\n                  bottom: 0,\n                  left: 0,\n                  right: 0,\n                  background: \"linear-gradient(0deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.35) 60%, transparent 100%)\",\n                  padding: `${20 * responsiveScale}px ${12 * responsiveScale}px ${8 * responsiveScale}px`,\n                  zIndex: 10,\n                  opacity: controlsVisible || adStatus.showAds ? 1 : 0,\n                  transform: controlsVisible || adStatus.showAds ? \"translateY(0)\" : \"translateY(6px)\",\n                  pointerEvents: controlsVisible || adStatus.showAds ? \"auto\" : \"none\"\n                },\n                children: [\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                    \"div\",\n                    {\n                      className: \"sc-progress-track\",\n                      style: {\n                        width: \"100%\",\n                        height: \"3px\",\n                        background: \"rgba(255, 255, 255, 0.2)\",\n                        borderRadius: \"1.5px\",\n                        marginBottom: `${8 * responsiveScale}px`,\n                        cursor: \"pointer\",\n                        position: \"relative\",\n                        transition: \"height 0.1s ease\"\n                      },\n                      onClick: handleTimelineSeek,\n                      onMouseEnter: (e) => {\n                        e.currentTarget.style.height = \"5px\";\n                      },\n                      onMouseLeave: (e) => {\n                        e.currentTarget.style.height = \"3px\";\n                      },\n                      children: [\n                        /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                          \"div\",\n                          {\n                            style: {\n                              position: \"absolute\",\n                              top: 0,\n                              left: 0,\n                              bottom: 0,\n                              background: adStatus.showAds ? \"#f5c518\" : \"#ff0000\",\n                              borderRadius: \"1.5px\",\n                              width: `${progressPercent}%`,\n                              transition: \"width 0.15s linear\"\n                            }\n                          }\n                        ),\n                        /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                          \"div\",\n                          {\n                            className: \"sc-progress-thumb\",\n                            style: {\n                              position: \"absolute\",\n                              top: \"50%\",\n                              left: `${progressPercent}%`,\n                              transform: \"translate(-50%, -50%) scale(0)\",\n                              width: \"13px\",\n                              height: \"13px\",\n                              background: adStatus.showAds ? \"#f5c518\" : \"#ff0000\",\n                              borderRadius: \"50%\",\n                              boxShadow: \"0 0 4px rgba(0, 0, 0, 0.3)\",\n                              transition: \"transform 0.1s ease, left 0.15s linear\"\n                            }\n                          }\n                        )\n                      ]\n                    }\n                  ),\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                    \"div\",\n                    {\n                      style: {\n                        display: \"flex\",\n                        alignItems: \"center\",\n                        justifyContent: \"space-between\",\n                        color: \"white\",\n                        gap: `${8 * responsiveScale}px`\n                      },\n                      children: [\n                        /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                          \"div\",\n                          {\n                            style: {\n                              display: \"flex\",\n                              alignItems: \"center\",\n                              gap: `${8 * responsiveScale}px`\n                            },\n                            children: [\n                              /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                \"button\",\n                                {\n                                  className: \"sc-ctrl-btn\",\n                                  onClick: handlePlayPause,\n                                  style: {\n                                    padding: `${8 * responsiveScale}px`,\n                                    borderRadius: \"50%\",\n                                    minWidth: `${36 * responsiveScale}px`,\n                                    minHeight: `${36 * responsiveScale}px`\n                                  },\n                                  title: isPlaying ? \"Pause\" : \"Play\",\n                                  children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaPause, { size: Math.max(14, 18 * responsiveScale) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaPlay, { size: Math.max(14, 18 * responsiveScale), style: { marginLeft: \"2px\" } })\n                                }\n                              ),\n                              /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                \"div\",\n                                {\n                                  style: {\n                                    display: \"flex\",\n                                    alignItems: \"center\",\n                                    paddingRight: `${6 * responsiveScale}px`\n                                  },\n                                  onMouseEnter: () => setShowVolumeSlider(true),\n                                  onMouseLeave: () => setShowVolumeSlider(false),\n                                  children: [\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                      \"button\",\n                                      {\n                                        className: \"sc-ctrl-btn\",\n                                        onClick: () => {\n                                          if (playerRef.current) playerRef.current.toggleMute();\n                                          onVolumeToggle?.();\n                                          resetControlsTimer();\n                                        },\n                                        style: {\n                                          padding: `${8 * responsiveScale}px`,\n                                          borderRadius: \"50%\",\n                                          minWidth: `${36 * responsiveScale}px`,\n                                          minHeight: `${36 * responsiveScale}px`\n                                        },\n                                        title: isMuted2 ? \"Unmute\" : \"Mute\",\n                                        children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VolumeIcon, { size: Math.max(14, 18 * responsiveScale) })\n                                      }\n                                    ),\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                      \"div\",\n                                      {\n                                        style: {\n                                          width: showVolumeSlider ? `${68 * responsiveScale}px` : \"0px\",\n                                          overflow: \"hidden\",\n                                          transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n                                          display: \"flex\",\n                                          alignItems: \"center\",\n                                          paddingLeft: showVolumeSlider ? `${3 * responsiveScale}px` : \"0\",\n                                          paddingRight: showVolumeSlider ? `${8 * responsiveScale}px` : \"0\"\n                                        },\n                                        children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                          \"div\",\n                                          {\n                                            style: {\n                                              position: \"relative\",\n                                              width: `${56 * responsiveScale}px`,\n                                              height: \"3px\",\n                                              cursor: \"pointer\",\n                                              borderRadius: \"1.5px\"\n                                            },\n                                            onMouseDown: (e) => {\n                                              e.preventDefault();\n                                              const el = e.currentTarget;\n                                              const move = (ev) => {\n                                                const r2 = el.getBoundingClientRect();\n                                                handleVolumeChange(Math.max(0, Math.min(1, (ev.clientX - r2.left) / r2.width)));\n                                              };\n                                              const up = () => {\n                                                document.removeEventListener(\"mousemove\", move);\n                                                document.removeEventListener(\"mouseup\", up);\n                                              };\n                                              document.addEventListener(\"mousemove\", move);\n                                              document.addEventListener(\"mouseup\", up);\n                                              const r = el.getBoundingClientRect();\n                                              handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                                            },\n                                            onClick: (e) => {\n                                              e.stopPropagation();\n                                              const r = e.currentTarget.getBoundingClientRect();\n                                              handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                                            },\n                                            children: [\n                                              /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { position: \"absolute\", inset: 0, background: \"rgba(255, 255, 255, 0.2)\", borderRadius: \"1.5px\" } }),\n                                              /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                                \"div\",\n                                                {\n                                                  style: {\n                                                    position: \"absolute\",\n                                                    top: 0,\n                                                    left: 0,\n                                                    bottom: 0,\n                                                    width: `${(isMuted2 ? 0 : volume) * 100}%`,\n                                                    background: \"#fff\",\n                                                    borderRadius: \"1.5px\",\n                                                    transition: \"width 0.1s ease-out\"\n                                                  }\n                                                }\n                                              ),\n                                              /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                                \"div\",\n                                                {\n                                                  style: {\n                                                    position: \"absolute\",\n                                                    top: \"50%\",\n                                                    left: `${(isMuted2 ? 0 : volume) * 100}%`,\n                                                    transform: \"translate(-50%, -50%)\",\n                                                    width: \"12px\",\n                                                    height: \"12px\",\n                                                    background: \"#fff\",\n                                                    borderRadius: \"50%\",\n                                                    boxShadow: \"0 0 3px rgba(0, 0, 0, 0.3)\",\n                                                    transition: \"left 0.1s ease-out\"\n                                                  }\n                                                }\n                                              )\n                                            ]\n                                          }\n                                        )\n                                      }\n                                    )\n                                  ]\n                                }\n                              ),\n                              /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                \"div\",\n                                {\n                                  style: {\n                                    fontSize: `${13 * responsiveScale}px`,\n                                    fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\",\n                                    color: \"rgba(255, 255, 255, 0.9)\",\n                                    display: viewportWidth < 480 ? \"none\" : \"block\",\n                                    fontVariantNumeric: \"tabular-nums\",\n                                    userSelect: \"none\",\n                                    marginLeft: `${4 * responsiveScale}px`\n                                  },\n                                  children: [\n                                    formatTime(currentTime),\n                                    \" \",\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { color: \"rgba(255,255,255,0.5)\" }, children: \"/\" }),\n                                    \" \",\n                                    formatTime(duration)\n                                  ]\n                                }\n                              )\n                            ]\n                          }\n                        ),\n                        /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                          \"div\",\n                          {\n                            style: {\n                              display: \"flex\",\n                              alignItems: \"center\",\n                              gap: `${8 * responsiveScale}px`\n                            },\n                            children: [\n                              /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { position: \"relative\", display: viewportWidth < 600 ? \"none\" : \"block\" }, children: [\n                                /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                  \"button\",\n                                  {\n                                    className: \"sc-ctrl-btn\",\n                                    onClick: () => {\n                                      setShowSpeedMenu(!showSpeedMenu);\n                                      resetControlsTimer();\n                                    },\n                                    style: {\n                                      padding: `${6 * responsiveScale}px ${10 * responsiveScale}px`,\n                                      borderRadius: `${6 * responsiveScale}px`,\n                                      fontSize: `${13 * responsiveScale}px`,\n                                      fontFamily: \"'SF Mono', 'Cascadia Code', monospace\",\n                                      fontWeight: \"600\",\n                                      minHeight: `${32 * responsiveScale}px`\n                                    },\n                                    title: \"Playback Speed\",\n                                    children: [\n                                      playbackRate,\n                                      \"x\"\n                                    ]\n                                  }\n                                ),\n                                showSpeedMenu && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                  \"div\",\n                                  {\n                                    style: {\n                                      position: \"absolute\",\n                                      bottom: \"100%\",\n                                      right: 0,\n                                      marginBottom: \"8px\",\n                                      background: \"rgba(0, 0, 0, 0.8)\",\n                                      backdropFilter: \"blur(24px)\",\n                                      WebkitBackdropFilter: \"blur(24px)\",\n                                      borderRadius: \"10px\",\n                                      border: \"1px solid rgba(255, 255, 255, 0.1)\",\n                                      overflow: \"hidden\",\n                                      minWidth: \"80px\",\n                                      boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.5)\",\n                                      animation: \"sc-fade-in 0.15s ease\"\n                                    },\n                                    children: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map((speed) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                      \"button\",\n                                      {\n                                        onClick: () => handlePlaybackRateChange(speed),\n                                        style: {\n                                          display: \"block\",\n                                          width: \"100%\",\n                                          padding: `${8 * responsiveScale}px ${14 * responsiveScale}px`,\n                                          background: playbackRate === speed ? \"rgba(255, 255, 255, 0.12)\" : \"transparent\",\n                                          border: \"none\",\n                                          color: playbackRate === speed ? \"#fff\" : \"rgba(255, 255, 255, 0.7)\",\n                                          cursor: \"pointer\",\n                                          fontSize: `${12 * responsiveScale}px`,\n                                          fontFamily: \"'SF Mono', monospace\",\n                                          fontWeight: playbackRate === speed ? \"700\" : \"500\",\n                                          textAlign: \"center\",\n                                          transition: \"background 0.15s ease, color 0.15s ease\"\n                                        },\n                                        onMouseEnter: (e) => {\n                                          if (playbackRate !== speed) {\n                                            e.target.style.background = \"rgba(255, 255, 255, 0.08)\";\n                                            e.target.style.color = \"#fff\";\n                                          }\n                                        },\n                                        onMouseLeave: (e) => {\n                                          if (playbackRate !== speed) {\n                                            e.target.style.background = \"transparent\";\n                                            e.target.style.color = \"rgba(255, 255, 255, 0.7)\";\n                                          }\n                                        },\n                                        children: [\n                                          speed,\n                                          \"x\"\n                                        ]\n                                      },\n                                      speed\n                                    ))\n                                  }\n                                )\n                              ] }),\n                              /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                \"button\",\n                                {\n                                  className: \"sc-ctrl-btn\",\n                                  onClick: () => {\n                                    if (onFullscreenToggle) {\n                                      onFullscreenToggle();\n                                    } else if (wrapperRef.current) {\n                                      if (!document.fullscreenElement) {\n                                        wrapperRef.current.requestFullscreen().catch(() => {\n                                        });\n                                      } else {\n                                        document.exitFullscreen().catch(() => {\n                                        });\n                                      }\n                                    }\n                                    resetControlsTimer();\n                                  },\n                                  style: {\n                                    padding: `${8 * responsiveScale}px`,\n                                    borderRadius: \"50%\",\n                                    minWidth: `${36 * responsiveScale}px`,\n                                    minHeight: `${36 * responsiveScale}px`\n                                  },\n                                  title: isFullscreen2 ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n                                  children: isFullscreen2 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaCompress, { size: Math.max(14, 18 * responsiveScale) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaExpand, { size: Math.max(14, 18 * responsiveScale) })\n                                }\n                              )\n                            ]\n                          }\n                        )\n                      ]\n                    }\n                  )\n                ]\n              }\n            ) : showCustomControls && !showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n              /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                \"div\",\n                {\n                  style: {\n                    position: \"absolute\",\n                    top: `${10 * responsiveScale}px`,\n                    left: `${10 * responsiveScale}px`,\n                    display: \"flex\",\n                    alignItems: \"center\",\n                    gap: \"6px\",\n                    zIndex: 10,\n                    opacity: controlsVisible ? 1 : 0,\n                    transition: \"opacity 0.35s ease\"\n                  },\n                  children: [\n                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                      \"div\",\n                      {\n                        style: {\n                          width: \"8px\",\n                          height: \"8px\",\n                          borderRadius: \"50%\",\n                          background: \"#ff3b30\",\n                          animation: \"sc-pulse 1.5s ease-in-out infinite\",\n                          flexShrink: 0\n                        }\n                      }\n                    ),\n                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                      \"span\",\n                      {\n                        style: {\n                          fontSize: `${12 * responsiveScale}px`,\n                          fontFamily: \"'SF Pro Display', 'Segoe UI', Arial, sans-serif\",\n                          fontWeight: 700,\n                          letterSpacing: \"0.08em\",\n                          color: \"#fff\",\n                          textShadow: \"0 1px 3px rgba(0,0,0,0.6)\",\n                          userSelect: \"none\"\n                        },\n                        children: \"LIVE\"\n                      }\n                    )\n                  ]\n                }\n              ),\n              /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                \"div\",\n                {\n                  className: \"sc-controls-bar\",\n                  style: {\n                    position: \"absolute\",\n                    bottom: `${10 * responsiveScale}px`,\n                    right: `${10 * responsiveScale}px`,\n                    display: \"flex\",\n                    flexDirection: isPortrait ? \"column\" : \"row\",\n                    alignItems: isPortrait ? \"flex-end\" : \"center\",\n                    gap: `${8 * responsiveScale}px`,\n                    zIndex: 10,\n                    opacity: controlsVisible ? 1 : 0,\n                    transform: controlsVisible ? \"translateY(0)\" : \"translateY(4px)\",\n                    pointerEvents: controlsVisible ? \"auto\" : \"none\"\n                  },\n                  children: [\n                    /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                      \"div\",\n                      {\n                        style: {\n                          display: \"flex\",\n                          alignItems: \"center\",\n                          background: \"rgba(0, 0, 0, 0.6)\",\n                          borderRadius: `${18 * responsiveScale}px`,\n                          padding: \"2px\",\n                          paddingRight: `${8 * responsiveScale}px`\n                        },\n                        onMouseEnter: () => setShowVolumeSlider(true),\n                        onMouseLeave: () => setShowVolumeSlider(false),\n                        children: [\n                          /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                            \"button\",\n                            {\n                              className: \"sc-ctrl-btn\",\n                              onClick: () => {\n                                if (playerRef.current) playerRef.current.toggleMute();\n                                onVolumeToggle?.();\n                                resetControlsTimer();\n                              },\n                              style: {\n                                padding: `${8 * responsiveScale}px`,\n                                borderRadius: \"50%\",\n                                minWidth: `${36 * responsiveScale}px`,\n                                minHeight: `${36 * responsiveScale}px`\n                              },\n                              title: isMuted2 ? \"Unmute\" : \"Mute\",\n                              children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VolumeIcon, { size: Math.max(14, 18 * responsiveScale) })\n                            }\n                          ),\n                          /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                            \"div\",\n                            {\n                              style: {\n                                width: showVolumeSlider ? `${68 * responsiveScale}px` : \"0px\",\n                                overflow: \"hidden\",\n                                transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n                                display: \"flex\",\n                                alignItems: \"center\",\n                                paddingLeft: showVolumeSlider ? `${3 * responsiveScale}px` : \"0\",\n                                paddingRight: showVolumeSlider ? `${10 * responsiveScale}px` : \"0\"\n                              },\n                              children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                \"div\",\n                                {\n                                  style: {\n                                    position: \"relative\",\n                                    width: `${56 * responsiveScale}px`,\n                                    height: \"3px\",\n                                    cursor: \"pointer\",\n                                    borderRadius: \"1.5px\"\n                                  },\n                                  onMouseDown: (e) => {\n                                    e.preventDefault();\n                                    const el = e.currentTarget;\n                                    const move = (ev) => {\n                                      const r2 = el.getBoundingClientRect();\n                                      handleVolumeChange(Math.max(0, Math.min(1, (ev.clientX - r2.left) / r2.width)));\n                                    };\n                                    const up = () => {\n                                      document.removeEventListener(\"mousemove\", move);\n                                      document.removeEventListener(\"mouseup\", up);\n                                    };\n                                    document.addEventListener(\"mousemove\", move);\n                                    document.addEventListener(\"mouseup\", up);\n                                    const r = el.getBoundingClientRect();\n                                    handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                                  },\n                                  onClick: (e) => {\n                                    e.stopPropagation();\n                                    const r = e.currentTarget.getBoundingClientRect();\n                                    handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                                  },\n                                  children: [\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { position: \"absolute\", inset: 0, background: \"rgba(255, 255, 255, 0.2)\", borderRadius: \"1.5px\" } }),\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                      \"div\",\n                                      {\n                                        style: {\n                                          position: \"absolute\",\n                                          top: 0,\n                                          left: 0,\n                                          bottom: 0,\n                                          width: `${(isMuted2 ? 0 : volume) * 100}%`,\n                                          background: \"#fff\",\n                                          borderRadius: \"1.5px\",\n                                          transition: \"width 0.1s ease-out\"\n                                        }\n                                      }\n                                    ),\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                      \"div\",\n                                      {\n                                        style: {\n                                          position: \"absolute\",\n                                          top: \"50%\",\n                                          left: `${(isMuted2 ? 0 : volume) * 100}%`,\n                                          transform: \"translate(-50%, -50%)\",\n                                          width: \"12px\",\n                                          height: \"12px\",\n                                          background: \"#fff\",\n                                          borderRadius: \"50%\",\n                                          boxShadow: \"0 0 3px rgba(0, 0, 0, 0.3)\",\n                                          transition: \"left 0.1s ease-out\"\n                                        }\n                                      }\n                                    )\n                                  ]\n                                }\n                              )\n                            }\n                          )\n                        ]\n                      }\n                    ),\n                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                      \"button\",\n                      {\n                        className: \"sc-ctrl-btn\",\n                        onClick: () => {\n                          if (onFullscreenToggle) {\n                            onFullscreenToggle();\n                          } else if (wrapperRef.current) {\n                            if (!document.fullscreenElement) {\n                              wrapperRef.current.requestFullscreen().catch(() => {\n                              });\n                            } else {\n                              document.exitFullscreen().catch(() => {\n                              });\n                            }\n                          }\n                          resetControlsTimer();\n                        },\n                        style: {\n                          padding: `${8 * responsiveScale}px`,\n                          borderRadius: \"50%\",\n                          minWidth: `${36 * responsiveScale}px`,\n                          minHeight: `${36 * responsiveScale}px`,\n                          background: \"rgba(0, 0, 0, 0.6)\"\n                        },\n                        title: isFullscreen2 ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n                        children: isFullscreen2 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaCompress, { size: Math.max(14, 18 * responsiveScale) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaExpand, { size: Math.max(14, 18 * responsiveScale) })\n                      }\n                    )\n                  ]\n                }\n              )\n            ] }),\n            onControlClick && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n              \"div\",\n              {\n                onClick: onControlClick,\n                style: {\n                  position: \"absolute\",\n                  top: 0,\n                  left: 0,\n                  right: 0,\n                  bottom: 0,\n                  zIndex: 1,\n                  cursor: \"pointer\"\n                }\n              }\n            )\n          ]\n        }\n      )\n    ] });\n  },\n  (prevProps, nextProps) => {\n    for (const prop of CRITICAL_PROPS) {\n      if (prevProps[prop] !== nextProps[prop]) {\n        return false;\n      }\n    }\n    const uiProps = [\n      \"autoplay\",\n      \"muted\",\n      \"controls\",\n      \"showCustomControls\",\n      \"className\",\n      \"style\",\n      \"wrapperClassName\",\n      \"wrapperStyle\",\n      \"playsInline\",\n      \"preload\",\n      \"poster\",\n      \"children\"\n    ];\n    for (const prop of uiProps) {\n      if (prevProps[prop] !== nextProps[prop]) {\n        return false;\n      }\n    }\n    const callbackProps = [\n      \"onReady\",\n      \"onVolumeToggle\",\n      \"onFullscreenToggle\",\n      \"onControlClick\"\n    ];\n    for (const prop of callbackProps) {\n      if (prevProps[prop] !== nextProps[prop]) {\n        return false;\n      }\n    }\n    return true;\n  }\n);\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n  StormcloudVideoPlayerComponent\n});\n","import React, { useEffect, useRef, useMemo, useCallback } from \"react\";\nimport { StormcloudVideoPlayer } from \"../player/StormcloudVideoPlayer\";\nimport type { StormcloudVideoPlayerConfig } from \"../types\";\nimport {\n  FaPlay,\n  FaPause,\n  FaVolumeUp,\n  FaVolumeMute,\n  FaVolumeDown,\n  FaExpand,\n  FaCompress,\n} from \"react-icons/fa\";\n\nexport type StormcloudVideoPlayerProps = Omit<\n  StormcloudVideoPlayerConfig,\n  \"videoElement\"\n> &\n  React.VideoHTMLAttributes<HTMLVideoElement> & {\n    onReady?: (player: StormcloudVideoPlayer) => void;\n    wrapperClassName?: string;\n    wrapperStyle?: React.CSSProperties;\n    licenseKey?: string;\n  };\n\nconst CRITICAL_PROPS = [\n  \"src\",\n  \"allowNativeHls\",\n  \"isLiveStream\",\n  \"licenseKey\",\n  \"isVmap\",\n  \"vmapUrl\",\n  \"lowLatencyMode\",\n  \"driftToleranceMs\",\n  \"vastMode\",\n  \"ctvAdRequest\",\n] as const;\n\nconst CONTROLS_HIDE_DELAY = 3000;\nconst DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;\n\nexport const StormcloudVideoPlayerComponent: React.FC<StormcloudVideoPlayerProps> =\n  React.memo(\n    (props) => {\n      const {\n        src,\n        autoplay,\n        muted,\n        lowLatencyMode,\n        allowNativeHls,\n        isLiveStream,\n        driftToleranceMs,\n        immediateManifestAds,\n        debugAdTiming,\n        showCustomControls,\n        hideLoadingIndicator,\n        onVolumeToggle,\n        onFullscreenToggle,\n        onControlClick,\n        onReady,\n        wrapperClassName,\n        wrapperStyle,\n        className,\n        style,\n        controls,\n        playsInline,\n        preload,\n        poster,\n        children,\n        licenseKey,\n        vastMode,\n        vastTagUrl,\n        isVmap,\n        vmapUrl,\n        minSegmentsBeforePlay,\n        ctvAdRequest,\n        ...restVideoAttrs\n      } = props;\n\n      const videoRef = useRef<HTMLVideoElement | null>(null);\n      const playerRef = useRef<StormcloudVideoPlayer | null>(null);\n      const bufferingTimeoutRef = useRef<number | null>(null);\n      const controlsTimerRef = useRef<number | null>(null);\n      const wrapperRef = useRef<HTMLDivElement | null>(null);\n      const [adStatus, setAdStatus] = React.useState<{\n        showAds: boolean;\n        currentIndex: number;\n        totalAds: number;\n        remainingSeconds: number;\n      }>({ showAds: false, currentIndex: 0, totalAds: 0, remainingSeconds: 0 });\n\n      const [shouldShowNativeControls, setShouldShowNativeControls] =\n        React.useState(true);\n\n      const [isMuted, setIsMuted] = React.useState(false);\n      const [isFullscreen, setIsFullscreen] = React.useState(false);\n      const [isPlaying, setIsPlaying] = React.useState(false);\n      const [currentTime, setCurrentTime] = React.useState(0);\n      const [duration, setDuration] = React.useState(0);\n      const [volume, setVolume] = React.useState(1);\n      const [playbackRate, setPlaybackRate] = React.useState(1);\n      const [showVolumeSlider, setShowVolumeSlider] = React.useState(false);\n      const [showSpeedMenu, setShowSpeedMenu] = React.useState(false);\n      const [isLoading, setIsLoading] = React.useState(true);\n      const [isBuffering, setIsBuffering] = React.useState(false);\n      const [showCenterPlay, setShowCenterPlay] = React.useState(false);\n      const [showLicenseWarning, setShowLicenseWarning] = React.useState(false);\n      const [controlsVisible, setControlsVisible] = React.useState(true);\n      const [viewportWidth, setViewportWidth] = React.useState(\n        typeof window !== \"undefined\" ? window.innerWidth : 1920\n      );\n      const [isPortrait, setIsPortrait] = React.useState(\n        typeof window !== \"undefined\"\n          ? window.innerHeight > window.innerWidth\n          : false\n      );\n      const [playerAspectRatio, setPlayerAspectRatio] = React.useState(\n        DEFAULT_PLAYER_ASPECT_RATIO\n      );\n\n      const getResponsiveScale = () => {\n        if (viewportWidth < 480) return 0.7;\n        if (viewportWidth < 768) return 0.8;\n        if (viewportWidth < 1024) return 0.9;\n        return 1;\n      };\n\n      const responsiveScale = getResponsiveScale();\n\n      const resetControlsTimer = useCallback(() => {\n        if (controlsTimerRef.current) {\n          clearTimeout(controlsTimerRef.current);\n        }\n        setControlsVisible(true);\n        controlsTimerRef.current = window.setTimeout(() => {\n          if (!showVolumeSlider && !showSpeedMenu) {\n            setControlsVisible(false);\n          }\n        }, CONTROLS_HIDE_DELAY);\n      }, [showVolumeSlider, showSpeedMenu]);\n\n      const handleWrapperMouseMove = useCallback(() => {\n        resetControlsTimer();\n      }, [resetControlsTimer]);\n\n      const handleWrapperMouseLeave = useCallback(() => {\n        if (!showVolumeSlider && !showSpeedMenu) {\n          setControlsVisible(false);\n        }\n      }, [showVolumeSlider, showSpeedMenu]);\n\n      const formatTime = (seconds: number): string => {\n        if (!isFinite(seconds)) return \"0:00:00\";\n        const hours = Math.floor(seconds / 3600);\n        const minutes = Math.floor((seconds % 3600) / 60);\n        const remainingSeconds = Math.floor(seconds % 60);\n        return `${hours}:${minutes\n          .toString()\n          .padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n      };\n\n      const handlePlayPause = () => {\n        if (videoRef.current) {\n          if (videoRef.current.paused) {\n            const hasValidSource =\n              videoRef.current.src ||\n              (videoRef.current.currentSrc &&\n                videoRef.current.currentSrc !== \"\") ||\n              videoRef.current.readyState >= 1;\n\n            if (hasValidSource) {\n              videoRef.current.play()?.catch((error) => {\n                console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n              });\n              setShowCenterPlay(false);\n            } else {\n              console.warn(\n                \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n              );\n            }\n          } else {\n            videoRef.current.pause();\n            setShowCenterPlay(true);\n          }\n        }\n        resetControlsTimer();\n      };\n\n      const handleCenterPlayClick = () => {\n        if (videoRef.current && videoRef.current.paused) {\n          const hasValidSource =\n            videoRef.current.src ||\n            (videoRef.current.currentSrc &&\n              videoRef.current.currentSrc !== \"\") ||\n            videoRef.current.readyState >= 1;\n\n          if (hasValidSource) {\n            videoRef.current.play()?.catch((error) => {\n              console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n            });\n            setShowCenterPlay(false);\n          } else {\n            console.warn(\n              \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n            );\n          }\n        }\n      };\n\n      const handleTimelineSeek = (e: React.MouseEvent<HTMLDivElement>) => {\n        if (videoRef.current && duration > 0 && isFinite(duration)) {\n          const rect = e.currentTarget.getBoundingClientRect();\n          const clickX = e.clientX - rect.left;\n          const progress = Math.max(0, Math.min(1, clickX / rect.width));\n          const newTime = progress * duration;\n\n          if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n            videoRef.current.currentTime = newTime;\n          }\n        }\n        resetControlsTimer();\n      };\n\n      const handleVolumeChange = (newVolume: number) => {\n        if (playerRef.current && isFinite(newVolume)) {\n          const clampedVolume = Math.max(0, Math.min(1, newVolume));\n          playerRef.current.setVolume(clampedVolume);\n        }\n      };\n\n      const handlePlaybackRateChange = (rate: number) => {\n        if (videoRef.current && isFinite(rate) && rate > 0) {\n          videoRef.current.playbackRate = rate;\n        }\n        setShowSpeedMenu(false);\n      };\n\n      const isHlsStream =\n        src?.toLowerCase().includes(\".m3u8\") ||\n        src?.toLowerCase().includes(\"/hls/\");\n      const isLiveUiMode = isLiveStream === true;\n      const shouldShowEnhancedControls =\n        showCustomControls &&\n        (isHlsStream ? !isLiveUiMode : true);\n\n      const criticalPropsKey = useMemo(() => {\n        return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n      }, [\n        src,\n        allowNativeHls,\n        isLiveStream,\n        licenseKey,\n        isVmap,\n        vmapUrl,\n        lowLatencyMode,\n        driftToleranceMs,\n        vastMode,\n      ]);\n\n      useEffect(() => {\n        if (typeof window === \"undefined\") return;\n        const el = videoRef.current;\n        if (!el || !src) return;\n\n        if (!licenseKey) {\n          setShowLicenseWarning(true);\n          setIsLoading(false);\n          console.warn(\n            \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n          );\n          return;\n        }\n\n        setShowLicenseWarning(false);\n\n        if (debugAdTiming) {\n          console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n        }\n\n        if (playerRef.current) {\n          try {\n            playerRef.current.destroy();\n          } catch {}\n          playerRef.current = null;\n        }\n\n        const cfg: StormcloudVideoPlayerConfig = {\n          src,\n          videoElement: el,\n        } as StormcloudVideoPlayerConfig;\n        if (autoplay !== undefined) cfg.autoplay = autoplay;\n        if (muted !== undefined) cfg.muted = muted;\n        if (lowLatencyMode !== undefined) cfg.lowLatencyMode = lowLatencyMode;\n        if (allowNativeHls !== undefined) cfg.allowNativeHls = allowNativeHls;\n        if (isLiveStream !== undefined) cfg.isLiveStream = isLiveStream;\n        if (driftToleranceMs !== undefined)\n          cfg.driftToleranceMs = driftToleranceMs;\n        if (immediateManifestAds !== undefined)\n          cfg.immediateManifestAds = immediateManifestAds;\n        if (debugAdTiming !== undefined) cfg.debugAdTiming = debugAdTiming;\n        if (showCustomControls !== undefined)\n          cfg.showCustomControls = showCustomControls;\n        if (onVolumeToggle !== undefined) cfg.onVolumeToggle = onVolumeToggle;\n        if (onFullscreenToggle !== undefined)\n          cfg.onFullscreenToggle = onFullscreenToggle;\n        if (onControlClick !== undefined) cfg.onControlClick = onControlClick;\n        if (licenseKey !== undefined) cfg.licenseKey = licenseKey;\n        if (vastMode !== undefined) cfg.vastMode = vastMode;\n        if (vastTagUrl !== undefined) cfg.vastTagUrl = vastTagUrl;\n        if (isVmap !== undefined) cfg.isVmap = isVmap;\n        if (vmapUrl !== undefined) cfg.vmapUrl = vmapUrl;\n        if (minSegmentsBeforePlay !== undefined)\n          cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n        if (ctvAdRequest !== undefined) cfg.ctvAdRequest = ctvAdRequest;\n\n        const player = new StormcloudVideoPlayer(cfg);\n        playerRef.current = player;\n        player\n          .load()\n          .then(() => {\n            const showNative = player.shouldShowNativeControls();\n            setShouldShowNativeControls(showNative);\n            if (debugAdTiming) {\n              console.log(\n                \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n              );\n            }\n            onReady?.(player);\n          })\n          .catch((error) => {\n            console.error(\n              \"StormcloudVideoPlayer: Failed to load player:\",\n              error\n            );\n            setIsLoading(false);\n            onReady?.(player);\n          });\n\n        return () => {\n          try {\n            player.destroy();\n          } catch {}\n          playerRef.current = null;\n        };\n      }, [criticalPropsKey]);\n\n      useEffect(() => {\n        if (!playerRef.current) return;\n\n        try {\n          if (autoplay !== undefined && playerRef.current.videoElement) {\n            playerRef.current.videoElement.autoplay = autoplay;\n          }\n          if (muted !== undefined && !playerRef.current.isShowingAds()) {\n            playerRef.current.setMuted(muted);\n          }\n        } catch (error) {\n          console.warn(\"Failed to update player properties:\", error);\n        }\n      }, [autoplay, muted]);\n\n      useEffect(() => {\n        if (!playerRef.current) return;\n\n        const checkAdStatus = () => {\n          if (playerRef.current) {\n            const showAdsFromMethod = playerRef.current.isShowingAds();\n            const showAdsFromAttribute = videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n            const showAds = showAdsFromMethod || showAdsFromAttribute;\n            const currentIndex = playerRef.current.getCurrentAdIndex();\n            const totalAds = playerRef.current.getTotalAdsInBreak();\n            const remainingMs = playerRef.current.getAdRemainingMs();\n            const remainingSeconds = showAds\n              ? Math.max(0, Math.ceil(remainingMs / 1000))\n              : 0;\n\n            setAdStatus((prev) => {\n              if (\n                prev.showAds !== showAds ||\n                prev.currentIndex !== currentIndex ||\n                prev.totalAds !== totalAds ||\n                prev.remainingSeconds !== remainingSeconds\n              ) {\n                if (showAds && !prev.showAds) {\n                  setShowCenterPlay(false);\n                }\n                return { showAds, currentIndex, totalAds, remainingSeconds };\n              }\n              return prev;\n            });\n          }\n        };\n\n        const interval = setInterval(checkAdStatus, 50);\n        return () => clearInterval(interval);\n      }, []);\n\n      useEffect(() => {\n        if (typeof window === \"undefined\" || !playerRef.current) return;\n\n        const handleResize = () => {\n          if (playerRef.current && videoRef.current) {\n            if (typeof playerRef.current.resize === \"function\") {\n              playerRef.current.resize();\n            }\n          }\n          setViewportWidth(window.innerWidth);\n          setIsPortrait(window.innerHeight > window.innerWidth);\n        };\n\n        window.addEventListener(\"resize\", handleResize);\n        return () => window.removeEventListener(\"resize\", handleResize);\n      }, []);\n\n      useEffect(() => {\n        if (!playerRef.current || !videoRef.current) return;\n\n        const updateStates = () => {\n          if (playerRef.current && videoRef.current) {\n            setIsMuted(playerRef.current.isMuted());\n            setIsPlaying(!videoRef.current.paused);\n\n            const currentTimeValue = videoRef.current.currentTime;\n            setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n\n            const durationValue = videoRef.current.duration;\n            setDuration(isFinite(durationValue) ? durationValue : 0);\n\n            const volumeValue = playerRef.current.getVolume();\n            setVolume(\n              isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n            );\n\n            const rateValue = videoRef.current.playbackRate;\n            setPlaybackRate(\n              isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n            );\n          }\n          setIsFullscreen(\n            document.fullscreenElement === wrapperRef.current\n          );\n        };\n\n        const interval = setInterval(updateStates, 200);\n\n        const handleFullscreenChange = () => {\n          setIsFullscreen(\n            document.fullscreenElement === wrapperRef.current\n          );\n        };\n\n        document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n\n        return () => {\n          clearInterval(interval);\n          document.removeEventListener(\n            \"fullscreenchange\",\n            handleFullscreenChange\n          );\n        };\n      }, []);\n\n      useEffect(() => {\n        if (!videoRef.current) return;\n\n        const handleLoadedMetadata = () => {\n          const video = videoRef.current;\n          if (video) {\n            if (video.videoWidth > 0 && video.videoHeight > 0) {\n              setPlayerAspectRatio(video.videoWidth / video.videoHeight);\n            }\n            void video.offsetHeight;\n          }\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n              videoRef.current?.readyState\n            );\n          }\n        };\n\n        const handleLoadedData = () => {\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: loadeddata, readyState:\",\n              videoRef.current?.readyState\n            );\n          }\n        };\n\n        const handleLoadStart = () => {\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: loadstart, readyState:\",\n              videoRef.current?.readyState\n            );\n          }\n        };\n\n        const handleCanPlay = () => {\n          setIsLoading(false);\n          if (bufferingTimeoutRef.current) {\n            clearTimeout(bufferingTimeoutRef.current);\n            bufferingTimeoutRef.current = null;\n          }\n          setIsBuffering(false);\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: canplay, readyState:\",\n              videoRef.current?.readyState,\n              \"- clearing loading state, isLoading=false\"\n            );\n          }\n        };\n\n        const handleCanPlayThrough = () => {\n          setIsLoading(false);\n          if (bufferingTimeoutRef.current) {\n            clearTimeout(bufferingTimeoutRef.current);\n            bufferingTimeoutRef.current = null;\n          }\n          setIsBuffering(false);\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n              videoRef.current?.readyState,\n              \"- clearing loading state, isLoading=false\"\n            );\n          }\n        };\n\n        const handleWaiting = () => {\n          if (bufferingTimeoutRef.current) {\n            clearTimeout(bufferingTimeoutRef.current);\n          }\n\n          bufferingTimeoutRef.current = window.setTimeout(() => {\n            setIsBuffering(true);\n            if (debugAdTiming) {\n              console.log(\n                \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n                videoRef.current?.readyState,\n                \"- showing spinner, isBuffering=true\"\n              );\n            }\n          }, 300);\n\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: waiting, readyState:\",\n              videoRef.current?.readyState,\n              \"- buffering delay started (300ms)\"\n            );\n          }\n        };\n\n        const handlePlaying = () => {\n          setIsLoading(false);\n          if (bufferingTimeoutRef.current) {\n            clearTimeout(bufferingTimeoutRef.current);\n            bufferingTimeoutRef.current = null;\n          }\n          setIsBuffering(false);\n          setShowCenterPlay(false);\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: playing, readyState:\",\n              videoRef.current?.readyState,\n              \"- playback started, isLoading=false, isBuffering=false\"\n            );\n          }\n        };\n\n      const handlePause = () => {\n        const isAdActive = playerRef.current?.isShowingAds() || \n          videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n        \n        if (playerRef.current && !isAdActive) {\n          setShowCenterPlay(true);\n        } else {\n          setShowCenterPlay(false);\n        }\n      };\n\n        const handleEnded = () => {\n          setShowCenterPlay(true);\n        };\n\n        const video = videoRef.current;\n        video.addEventListener(\"loadstart\", handleLoadStart);\n        video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n        video.addEventListener(\"loadeddata\", handleLoadedData);\n        video.addEventListener(\"canplay\", handleCanPlay);\n        video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n        video.addEventListener(\"waiting\", handleWaiting);\n        video.addEventListener(\"playing\", handlePlaying);\n        video.addEventListener(\"pause\", handlePause);\n        video.addEventListener(\"ended\", handleEnded);\n\n        if (video.paused) {\n          setShowCenterPlay(true);\n        }\n\n        return () => {\n          if (bufferingTimeoutRef.current) {\n            clearTimeout(bufferingTimeoutRef.current);\n            bufferingTimeoutRef.current = null;\n          }\n\n          video.removeEventListener(\"loadstart\", handleLoadStart);\n          video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n          video.removeEventListener(\"loadeddata\", handleLoadedData);\n          video.removeEventListener(\"canplay\", handleCanPlay);\n          video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n          video.removeEventListener(\"waiting\", handleWaiting);\n          video.removeEventListener(\"playing\", handlePlaying);\n          video.removeEventListener(\"pause\", handlePause);\n          video.removeEventListener(\"ended\", handleEnded);\n        };\n      }, [debugAdTiming]);\n\n      useEffect(() => {\n        setPlayerAspectRatio(DEFAULT_PLAYER_ASPECT_RATIO);\n      }, [src]);\n\n      useEffect(() => {\n        return () => {\n          if (controlsTimerRef.current) {\n            clearTimeout(controlsTimerRef.current);\n          }\n        };\n      }, []);\n\n      const progressPercent = duration > 0 ? (currentTime / duration) * 100 : 0;\n\n      const VolumeIcon = isMuted || volume === 0\n        ? FaVolumeMute\n        : volume < 0.5\n          ? FaVolumeDown\n          : FaVolumeUp;\n\n      return (\n        <>\n          <style>\n            {`\n              @keyframes sc-spin {\n                from { transform: rotate(0deg); }\n                to { transform: rotate(360deg); }\n              }\n              @keyframes sc-loading-glow {\n                0%, 100% { opacity: 0.85; transform: scale(1); }\n                50% { opacity: 1; transform: scale(1.05); }\n              }\n              @keyframes sc-pulse {\n                0%, 100% { opacity: 1; }\n                50% { opacity: 0.6; }\n              }\n              @keyframes sc-fade-in {\n                from { opacity: 0; transform: translateY(8px); }\n                to { opacity: 1; transform: translateY(0); }\n              }\n              .sc-wrapper:fullscreen,\n              .sc-wrapper:has(*:fullscreen) {\n                border-radius: 0 !important;\n                box-shadow: none !important;\n                width: 100vw !important;\n                height: 100vh !important;\n                max-width: 100vw !important;\n                max-height: 100vh !important;\n                position: fixed !important;\n                top: 0 !important;\n                left: 0 !important;\n                z-index: 999999 !important;\n                background: #000 !important;\n                display: flex !important;\n                align-items: center !important;\n                justify-content: center !important;\n              }\n              .sc-ctrl-btn {\n                background: none;\n                border: none;\n                color: #fff;\n                cursor: pointer;\n                display: flex;\n                align-items: center;\n                justify-content: center;\n                border-radius: 50%;\n                padding: 8px;\n                transition: background 0.15s ease, opacity 0.15s ease;\n                opacity: 0.9;\n              }\n              .sc-ctrl-btn:hover {\n                opacity: 1;\n                background: rgba(255, 255, 255, 0.1);\n              }\n              .sc-ctrl-btn:active {\n                opacity: 0.7;\n              }\n              .sc-controls-bar {\n                transition: opacity 0.35s ease, transform 0.35s ease;\n              }\n              .sc-progress-track:hover .sc-progress-thumb {\n                transform: translate(-50%, -50%) scale(1) !important;\n              }\n              .sc-loading-hidden .sc-loading-indicator {\n                display: none !important;\n              }\n            `}\n          </style>\n          <div\n            ref={wrapperRef}\n            className={`sc-wrapper ${wrapperClassName || \"\"}`}\n            onMouseMove={handleWrapperMouseMove}\n            onMouseLeave={handleWrapperMouseLeave}\n            style={{\n              display: \"flex\",\n              alignItems: \"center\",\n              justifyContent: \"center\",\n              position: isFullscreen ? \"fixed\" : \"relative\",\n              top: isFullscreen ? 0 : undefined,\n              left: isFullscreen ? 0 : undefined,\n              overflow: \"hidden\",\n              width: isFullscreen ? \"100vw\" : \"100%\",\n              height: isFullscreen ? \"100vh\" : \"auto\",\n              minHeight: isFullscreen ? \"100vh\" : \"auto\",\n              aspectRatio: isFullscreen ? undefined : playerAspectRatio,\n              maxWidth: isFullscreen ? \"100vw\" : \"100%\",\n              maxHeight: isFullscreen ? \"100vh\" : \"none\",\n              zIndex: isFullscreen ? 999999 : undefined,\n              backgroundColor: \"#000\",\n              borderRadius: isFullscreen ? 0 : undefined,\n              boxShadow: isFullscreen ? \"none\" : undefined,\n              ...wrapperStyle,\n            }}\n          >\n            <video\n              ref={videoRef}\n              className={className}\n              style={{\n                display: \"block\",\n                width: \"100%\",\n                height: \"100%\",\n                maxWidth: \"100%\",\n                maxHeight: isFullscreen ? \"100%\" : \"none\",\n                objectFit: isFullscreen ? \"cover\" : \"contain\",\n                backgroundColor: \"#000\",\n                aspectRatio: isFullscreen ? \"unset\" : undefined,\n                ...style,\n              }}\n              controls={\n                shouldShowNativeControls && controls && !showCustomControls\n              }\n              playsInline={playsInline}\n              preload={preload}\n              poster={poster}\n              {...restVideoAttrs}\n            >\n              {children}\n            </video>\n\n            {(isLoading || isBuffering) && !hideLoadingIndicator && (\n              <div\n                className=\"sc-loading-indicator\"\n                style={{\n                  position: \"absolute\",\n                  top: \"50%\",\n                  left: \"50%\",\n                  transform: \"translate(-50%, -50%)\",\n                  zIndex: 20,\n                  width: `${Math.max(34, 38 * responsiveScale)}px`,\n                  height: `${Math.max(34, 38 * responsiveScale)}px`,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  justifyContent: \"center\",\n                  animation: \"sc-loading-glow 1.4s ease-in-out infinite\",\n                  filter: \"drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55))\",\n                }}\n              >\n                <div\n                  style={{\n                    position: \"absolute\",\n                    inset: 0,\n                    borderRadius: \"50%\",\n                    border: \"3px solid rgba(255, 255, 255, 0.25)\",\n                    borderTopColor: \"#ff0000\",\n                    borderRightColor: \"rgba(255, 255, 255, 0.85)\",\n                    animation: \"sc-spin 0.8s linear infinite\",\n                  }}\n                />\n                <div\n                  style={{\n                    width: \"7px\",\n                    height: \"7px\",\n                    borderRadius: \"50%\",\n                    background: \"#ff0000\",\n                    boxShadow: \"0 0 10px rgba(255, 0, 0, 0.65)\",\n                  }}\n                />\n              </div>\n            )}\n\n            {showLicenseWarning && (\n              <div\n                style={{\n                  position: \"absolute\",\n                  top: \"50%\",\n                  left: \"50%\",\n                  transform: \"translate(-50%, -50%)\",\n                  zIndex: 25,\n                  background: \"rgba(220, 38, 38, 0.92)\",\n                  backdropFilter: \"blur(24px)\",\n                  color: \"white\",\n                  padding: \"28px 36px\",\n                  borderRadius: \"14px\",\n                  border: \"1px solid rgba(255, 255, 255, 0.15)\",\n                  boxShadow: \"0 24px 64px rgba(0, 0, 0, 0.5)\",\n                  textAlign: \"center\",\n                  maxWidth: \"400px\",\n                  margin: \"0 16px\",\n                }}\n              >\n                <div style={{ fontSize: \"18px\", fontWeight: \"700\", marginBottom: \"10px\", letterSpacing: \"-0.02em\" }}>\n                  License Key Required\n                </div>\n                <div style={{ fontSize: \"13px\", lineHeight: \"1.6\", color: \"rgba(255, 255, 255, 0.85)\" }}>\n                  Please provide a valid license key to use the Stormcloud Video\n                  Player.\n                  <br />\n                  Contact your administrator for licensing information.\n                </div>\n              </div>\n            )}\n\n            {adStatus.showAds && (\n              <div\n                style={{\n                  position: \"absolute\",\n                  top: `${12 * responsiveScale}px`,\n                  left: `${12 * responsiveScale}px`,\n                  zIndex: 50,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  gap: \"8px\",\n                  pointerEvents: \"none\",\n                  animation: \"sc-fade-in 0.3s ease\",\n                }}\n              >\n                <div\n                  style={{\n                    background: \"rgba(234, 179, 8, 0.95)\",\n                    color: \"#111\",\n                    padding: `${4 * responsiveScale}px ${12 * responsiveScale}px`,\n                    borderRadius: \"6px\",\n                    fontSize: `${11 * responsiveScale}px`,\n                    fontWeight: 700,\n                    letterSpacing: \"0.08em\",\n                    textTransform: \"uppercase\" as const,\n                    boxShadow: \"0 2px 12px rgba(234, 179, 8, 0.35)\",\n                  }}\n                >\n                  {`Ad ${Math.max(1, adStatus.currentIndex)}`}\n                </div>\n              </div>\n            )}\n\n            {showCenterPlay &&\n              !isLoading &&\n              !isBuffering &&\n              !showLicenseWarning &&\n              !adStatus.showAds && (\n                <div\n                  onClick={handleCenterPlayClick}\n                  style={{\n                    position: \"absolute\",\n                    top: \"50%\",\n                    left: \"50%\",\n                    transform: \"translate(-50%, -50%)\",\n                    zIndex: 15,\n                    cursor: \"pointer\",\n                    background: \"rgba(0, 0, 0, 0.55)\",\n                    backdropFilter: \"blur(8px)\",\n                    borderRadius: \"50%\",\n                    width: `${92 * responsiveScale}px`,\n                    height: `${92 * responsiveScale}px`,\n                    display: \"flex\",\n                    alignItems: \"center\",\n                    justifyContent: \"center\",\n                    transition: \"background 0.2s ease, transform 0.2s ease\",\n                    animation: \"sc-fade-in 0.2s ease\",\n                  }}\n                  onMouseEnter={(e) => {\n                    (e.currentTarget as HTMLElement).style.background = \"rgba(0, 0, 0, 0.72)\";\n                    (e.currentTarget as HTMLElement).style.transform = \"translate(-50%, -50%) scale(1.06)\";\n                  }}\n                  onMouseLeave={(e) => {\n                    (e.currentTarget as HTMLElement).style.background = \"rgba(0, 0, 0, 0.55)\";\n                    (e.currentTarget as HTMLElement).style.transform = \"translate(-50%, -50%) scale(1)\";\n                  }}\n                  title=\"Play\"\n                >\n                  <FaPlay\n                    size={Math.max(24, 32 * responsiveScale)}\n                    color=\"white\"\n                    style={{ marginLeft: \"4px\" }}\n                  />\n                </div>\n              )}\n\n            {shouldShowEnhancedControls && !showLicenseWarning ? (\n              <div\n                className=\"sc-controls-bar\"\n                style={{\n                  position: \"absolute\",\n                  bottom: 0,\n                  left: 0,\n                  right: 0,\n                  background: \"linear-gradient(0deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.35) 60%, transparent 100%)\",\n                  padding: `${20 * responsiveScale}px ${12 * responsiveScale}px ${8 * responsiveScale}px`,\n                  zIndex: 10,\n                  opacity: controlsVisible || adStatus.showAds ? 1 : 0,\n                  transform: controlsVisible || adStatus.showAds ? \"translateY(0)\" : \"translateY(6px)\",\n                  pointerEvents: controlsVisible || adStatus.showAds ? \"auto\" : \"none\",\n                }}\n              >\n                {/* Progress Bar */}\n                <div\n                  className=\"sc-progress-track\"\n                  style={{\n                    width: \"100%\",\n                    height: \"3px\",\n                    background: \"rgba(255, 255, 255, 0.2)\",\n                    borderRadius: \"1.5px\",\n                    marginBottom: `${8 * responsiveScale}px`,\n                    cursor: \"pointer\",\n                    position: \"relative\",\n                    transition: \"height 0.1s ease\",\n                  }}\n                  onClick={handleTimelineSeek}\n                  onMouseEnter={(e) => { e.currentTarget.style.height = \"5px\"; }}\n                  onMouseLeave={(e) => { e.currentTarget.style.height = \"3px\"; }}\n                >\n                  <div\n                    style={{\n                      position: \"absolute\",\n                      top: 0, left: 0, bottom: 0,\n                      background: adStatus.showAds ? \"#f5c518\" : \"#ff0000\",\n                      borderRadius: \"1.5px\",\n                      width: `${progressPercent}%`,\n                      transition: \"width 0.15s linear\",\n                    }}\n                  />\n                  <div\n                    className=\"sc-progress-thumb\"\n                    style={{\n                      position: \"absolute\",\n                      top: \"50%\",\n                      left: `${progressPercent}%`,\n                      transform: \"translate(-50%, -50%) scale(0)\",\n                      width: \"13px\",\n                      height: \"13px\",\n                      background: adStatus.showAds ? \"#f5c518\" : \"#ff0000\",\n                      borderRadius: \"50%\",\n                      boxShadow: \"0 0 4px rgba(0, 0, 0, 0.3)\",\n                      transition: \"transform 0.1s ease, left 0.15s linear\",\n                    }}\n                  />\n                </div>\n\n                {/* Controls Row */}\n                <div\n                  style={{\n                    display: \"flex\",\n                    alignItems: \"center\",\n                    justifyContent: \"space-between\",\n                    color: \"white\",\n                    gap: `${8 * responsiveScale}px`,\n                  }}\n                >\n                  {/* Left Group */}\n                  <div\n                    style={{\n                      display: \"flex\",\n                      alignItems: \"center\",\n                      gap: `${8 * responsiveScale}px`,\n                    }}\n                  >\n                    {/* Play/Pause */}\n                    <button\n                      className=\"sc-ctrl-btn\"\n                      onClick={handlePlayPause}\n                      style={{\n                        padding: `${8 * responsiveScale}px`,\n                        borderRadius: \"50%\",\n                        minWidth: `${36 * responsiveScale}px`,\n                        minHeight: `${36 * responsiveScale}px`,\n                      }}\n                      title={isPlaying ? \"Pause\" : \"Play\"}\n                    >\n                      {isPlaying ? (\n                        <FaPause size={Math.max(14, 18 * responsiveScale)} />\n                      ) : (\n                        <FaPlay size={Math.max(14, 18 * responsiveScale)} style={{ marginLeft: \"2px\" }} />\n                      )}\n                    </button>\n\n                    {/* Volume Group - YouTube Style */}\n                    <div\n                      style={{\n                        display: \"flex\",\n                        alignItems: \"center\",\n                        paddingRight: `${6 * responsiveScale}px`,\n                      }}\n                      onMouseEnter={() => setShowVolumeSlider(true)}\n                      onMouseLeave={() => setShowVolumeSlider(false)}\n                    >\n                      <button\n                        className=\"sc-ctrl-btn\"\n                        onClick={() => {\n                          if (playerRef.current) playerRef.current.toggleMute();\n                          onVolumeToggle?.();\n                          resetControlsTimer();\n                        }}\n                        style={{\n                          padding: `${8 * responsiveScale}px`,\n                          borderRadius: \"50%\",\n                          minWidth: `${36 * responsiveScale}px`,\n                          minHeight: `${36 * responsiveScale}px`,\n                        }}\n                        title={isMuted ? \"Unmute\" : \"Mute\"}\n                      >\n                        <VolumeIcon size={Math.max(14, 18 * responsiveScale)} />\n                      </button>\n                      <div\n                        style={{\n                          width: showVolumeSlider ? `${68 * responsiveScale}px` : \"0px\",\n                          overflow: \"hidden\",\n                          transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n                          display: \"flex\",\n                          alignItems: \"center\",\n                          paddingLeft: showVolumeSlider ? `${3 * responsiveScale}px` : \"0\",\n                          paddingRight: showVolumeSlider ? `${8 * responsiveScale}px` : \"0\",\n                        }}\n                      >\n                        <div\n                          style={{\n                            position: \"relative\",\n                            width: `${56 * responsiveScale}px`,\n                            height: \"3px\",\n                            cursor: \"pointer\",\n                            borderRadius: \"1.5px\",\n                          }}\n                          onMouseDown={(e) => {\n                            e.preventDefault();\n                            const el = e.currentTarget;\n                            const move = (ev: MouseEvent) => {\n                              const r = el.getBoundingClientRect();\n                              handleVolumeChange(Math.max(0, Math.min(1, (ev.clientX - r.left) / r.width)));\n                            };\n                            const up = () => { document.removeEventListener(\"mousemove\", move); document.removeEventListener(\"mouseup\", up); };\n                            document.addEventListener(\"mousemove\", move);\n                            document.addEventListener(\"mouseup\", up);\n                            const r = el.getBoundingClientRect();\n                            handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                          }}\n                          onClick={(e) => {\n                            e.stopPropagation();\n                            const r = e.currentTarget.getBoundingClientRect();\n                            handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                          }}\n                        >\n                          <div style={{ position: \"absolute\", inset: 0, background: \"rgba(255, 255, 255, 0.2)\", borderRadius: \"1.5px\" }} />\n                          <div\n                            style={{\n                              position: \"absolute\",\n                              top: 0, left: 0, bottom: 0,\n                              width: `${(isMuted ? 0 : volume) * 100}%`,\n                              background: \"#fff\",\n                              borderRadius: \"1.5px\",\n                              transition: \"width 0.1s ease-out\",\n                            }}\n                          />\n                          <div\n                            style={{\n                              position: \"absolute\",\n                              top: \"50%\",\n                              left: `${(isMuted ? 0 : volume) * 100}%`,\n                              transform: \"translate(-50%, -50%)\",\n                              width: \"12px\",\n                              height: \"12px\",\n                              background: \"#fff\",\n                              borderRadius: \"50%\",\n                              boxShadow: \"0 0 3px rgba(0, 0, 0, 0.3)\",\n                              transition: \"left 0.1s ease-out\",\n                            }}\n                          />\n                        </div>\n                      </div>\n                    </div>\n\n                    {/* Time Display */}\n                    <div\n                      style={{\n                        fontSize: `${13 * responsiveScale}px`,\n                        fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\",\n                        color: \"rgba(255, 255, 255, 0.9)\",\n                        display: viewportWidth < 480 ? \"none\" : \"block\",\n                        fontVariantNumeric: \"tabular-nums\",\n                        userSelect: \"none\",\n                        marginLeft: `${4 * responsiveScale}px`,\n                      }}\n                    >\n                      {formatTime(currentTime)}{\" \"}\n                      <span style={{ color: \"rgba(255,255,255,0.5)\" }}>/</span>{\" \"}\n                      {formatTime(duration)}\n                    </div>\n                  </div>\n\n                  {/* Right Group */}\n                  <div\n                    style={{\n                      display: \"flex\",\n                      alignItems: \"center\",\n                      gap: `${8 * responsiveScale}px`,\n                    }}\n                  >\n                    {/* Speed Selector */}\n                    <div style={{ position: \"relative\", display: viewportWidth < 600 ? \"none\" : \"block\" }}>\n                      <button\n                        className=\"sc-ctrl-btn\"\n                        onClick={() => { setShowSpeedMenu(!showSpeedMenu); resetControlsTimer(); }}\n                        style={{\n                          padding: `${6 * responsiveScale}px ${10 * responsiveScale}px`,\n                          borderRadius: `${6 * responsiveScale}px`,\n                          fontSize: `${13 * responsiveScale}px`,\n                          fontFamily: \"'SF Mono', 'Cascadia Code', monospace\",\n                          fontWeight: \"600\",\n                          minHeight: `${32 * responsiveScale}px`,\n                        }}\n                        title=\"Playback Speed\"\n                      >\n                        {playbackRate}x\n                      </button>\n\n                      {showSpeedMenu && (\n                        <div\n                          style={{\n                            position: \"absolute\",\n                            bottom: \"100%\",\n                            right: 0,\n                            marginBottom: \"8px\",\n                            background: \"rgba(0, 0, 0, 0.8)\",\n                            backdropFilter: \"blur(24px)\",\n                            WebkitBackdropFilter: \"blur(24px)\",\n                            borderRadius: \"10px\",\n                            border: \"1px solid rgba(255, 255, 255, 0.1)\",\n                            overflow: \"hidden\",\n                            minWidth: \"80px\",\n                            boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.5)\",\n                            animation: \"sc-fade-in 0.15s ease\",\n                          }}\n                        >\n                          {[0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map((speed) => (\n                            <button\n                              key={speed}\n                              onClick={() => handlePlaybackRateChange(speed)}\n                              style={{\n                                display: \"block\",\n                                width: \"100%\",\n                                padding: `${8 * responsiveScale}px ${14 * responsiveScale}px`,\n                                background: playbackRate === speed\n                                  ? \"rgba(255, 255, 255, 0.12)\"\n                                  : \"transparent\",\n                                border: \"none\",\n                                color: playbackRate === speed ? \"#fff\" : \"rgba(255, 255, 255, 0.7)\",\n                                cursor: \"pointer\",\n                                fontSize: `${12 * responsiveScale}px`,\n                                fontFamily: \"'SF Mono', monospace\",\n                                fontWeight: playbackRate === speed ? \"700\" : \"500\",\n                                textAlign: \"center\",\n                                transition: \"background 0.15s ease, color 0.15s ease\",\n                              }}\n                              onMouseEnter={(e) => {\n                                if (playbackRate !== speed) {\n                                  (e.target as HTMLElement).style.background = \"rgba(255, 255, 255, 0.08)\";\n                                  (e.target as HTMLElement).style.color = \"#fff\";\n                                }\n                              }}\n                              onMouseLeave={(e) => {\n                                if (playbackRate !== speed) {\n                                  (e.target as HTMLElement).style.background = \"transparent\";\n                                  (e.target as HTMLElement).style.color = \"rgba(255, 255, 255, 0.7)\";\n                                }\n                              }}\n                            >\n                              {speed}x\n                            </button>\n                          ))}\n                        </div>\n                      )}\n                    </div>\n\n                    {/* Fullscreen */}\n                    <button\n                      className=\"sc-ctrl-btn\"\n                      onClick={() => {\n                        if (onFullscreenToggle) {\n                          onFullscreenToggle();\n                        } else if (wrapperRef.current) {\n                          if (!document.fullscreenElement) {\n                            wrapperRef.current.requestFullscreen().catch(() => {});\n                          } else {\n                            document.exitFullscreen().catch(() => {});\n                          }\n                        }\n                        resetControlsTimer();\n                      }}\n                      style={{\n                        padding: `${8 * responsiveScale}px`,\n                        borderRadius: \"50%\",\n                        minWidth: `${36 * responsiveScale}px`,\n                        minHeight: `${36 * responsiveScale}px`,\n                      }}\n                      title={isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"}\n                    >\n                      {isFullscreen ? (\n                        <FaCompress size={Math.max(14, 18 * responsiveScale)} />\n                      ) : (\n                        <FaExpand size={Math.max(14, 18 * responsiveScale)} />\n                      )}\n                    </button>\n                  </div>\n                </div>\n              </div>\n            ) : (\n              showCustomControls && !showLicenseWarning && (\n                <>\n                  <div\n                    style={{\n                      position: \"absolute\",\n                      top: `${10 * responsiveScale}px`,\n                      left: `${10 * responsiveScale}px`,\n                      display: \"flex\",\n                      alignItems: \"center\",\n                      gap: \"6px\",\n                      zIndex: 10,\n                      opacity: controlsVisible ? 1 : 0,\n                      transition: \"opacity 0.35s ease\",\n                    }}\n                  >\n                    <div\n                      style={{\n                        width: \"8px\",\n                        height: \"8px\",\n                        borderRadius: \"50%\",\n                        background: \"#ff3b30\",\n                        animation: \"sc-pulse 1.5s ease-in-out infinite\",\n                        flexShrink: 0,\n                      }}\n                    />\n                    <span\n                      style={{\n                        fontSize: `${12 * responsiveScale}px`,\n                        fontFamily: \"'SF Pro Display', 'Segoe UI', Arial, sans-serif\",\n                        fontWeight: 700,\n                        letterSpacing: \"0.08em\",\n                        color: \"#fff\",\n                        textShadow: \"0 1px 3px rgba(0,0,0,0.6)\",\n                        userSelect: \"none\",\n                      }}\n                    >\n                      LIVE\n                    </span>\n                  </div>\n\n                  <div\n                  className=\"sc-controls-bar\"\n                  style={{\n                    position: \"absolute\",\n                    bottom: `${10 * responsiveScale}px`,\n                    right: `${10 * responsiveScale}px`,\n                    display: \"flex\",\n                    flexDirection: isPortrait ? \"column\" : \"row\",\n                    alignItems: isPortrait ? \"flex-end\" : \"center\",\n                    gap: `${8 * responsiveScale}px`,\n                    zIndex: 10,\n                    opacity: controlsVisible ? 1 : 0,\n                    transform: controlsVisible ? \"translateY(0)\" : \"translateY(4px)\",\n                    pointerEvents: controlsVisible ? \"auto\" : \"none\",\n                  }}\n                >\n                  <div\n                    style={{\n                      display: \"flex\",\n                      alignItems: \"center\",\n                      background: \"rgba(0, 0, 0, 0.6)\",\n                      borderRadius: `${18 * responsiveScale}px`,\n                      padding: \"2px\",\n                      paddingRight: `${8 * responsiveScale}px`,\n                    }}\n                    onMouseEnter={() => setShowVolumeSlider(true)}\n                    onMouseLeave={() => setShowVolumeSlider(false)}\n                  >\n                    <button\n                      className=\"sc-ctrl-btn\"\n                      onClick={() => {\n                        if (playerRef.current) playerRef.current.toggleMute();\n                        onVolumeToggle?.();\n                        resetControlsTimer();\n                      }}\n                      style={{\n                        padding: `${8 * responsiveScale}px`,\n                        borderRadius: \"50%\",\n                        minWidth: `${36 * responsiveScale}px`,\n                        minHeight: `${36 * responsiveScale}px`,\n                      }}\n                      title={isMuted ? \"Unmute\" : \"Mute\"}\n                    >\n                      <VolumeIcon size={Math.max(14, 18 * responsiveScale)} />\n                    </button>\n                    <div\n                      style={{\n                        width: showVolumeSlider ? `${68 * responsiveScale}px` : \"0px\",\n                        overflow: \"hidden\",\n                        transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n                        display: \"flex\",\n                        alignItems: \"center\",\n                        paddingLeft: showVolumeSlider ? `${3 * responsiveScale}px` : \"0\",\n                        paddingRight: showVolumeSlider ? `${10 * responsiveScale}px` : \"0\",\n                      }}\n                    >\n                      <div\n                        style={{\n                          position: \"relative\",\n                          width: `${56 * responsiveScale}px`,\n                          height: \"3px\",\n                          cursor: \"pointer\",\n                          borderRadius: \"1.5px\",\n                        }}\n                        onMouseDown={(e) => {\n                          e.preventDefault();\n                          const el = e.currentTarget;\n                          const move = (ev: MouseEvent) => {\n                            const r = el.getBoundingClientRect();\n                            handleVolumeChange(Math.max(0, Math.min(1, (ev.clientX - r.left) / r.width)));\n                          };\n                          const up = () => { document.removeEventListener(\"mousemove\", move); document.removeEventListener(\"mouseup\", up); };\n                          document.addEventListener(\"mousemove\", move);\n                          document.addEventListener(\"mouseup\", up);\n                          const r = el.getBoundingClientRect();\n                          handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                        }}\n                        onClick={(e) => {\n                          e.stopPropagation();\n                          const r = e.currentTarget.getBoundingClientRect();\n                          handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                        }}\n                      >\n                        <div style={{ position: \"absolute\", inset: 0, background: \"rgba(255, 255, 255, 0.2)\", borderRadius: \"1.5px\" }} />\n                        <div\n                          style={{\n                            position: \"absolute\",\n                            top: 0, left: 0, bottom: 0,\n                            width: `${(isMuted ? 0 : volume) * 100}%`,\n                            background: \"#fff\",\n                            borderRadius: \"1.5px\",\n                            transition: \"width 0.1s ease-out\",\n                          }}\n                        />\n                        <div\n                          style={{\n                            position: \"absolute\",\n                            top: \"50%\",\n                            left: `${(isMuted ? 0 : volume) * 100}%`,\n                            transform: \"translate(-50%, -50%)\",\n                            width: \"12px\",\n                            height: \"12px\",\n                            background: \"#fff\",\n                            borderRadius: \"50%\",\n                            boxShadow: \"0 0 3px rgba(0, 0, 0, 0.3)\",\n                            transition: \"left 0.1s ease-out\",\n                          }}\n                        />\n                      </div>\n                    </div>\n                  </div>\n\n                  <button\n                    className=\"sc-ctrl-btn\"\n                    onClick={() => {\n                      if (onFullscreenToggle) {\n                        onFullscreenToggle();\n                      } else if (wrapperRef.current) {\n                        if (!document.fullscreenElement) {\n                          wrapperRef.current.requestFullscreen().catch(() => {});\n                        } else {\n                          document.exitFullscreen().catch(() => {});\n                        }\n                      }\n                      resetControlsTimer();\n                    }}\n                    style={{\n                      padding: `${8 * responsiveScale}px`,\n                      borderRadius: \"50%\",\n                      minWidth: `${36 * responsiveScale}px`,\n                      minHeight: `${36 * responsiveScale}px`,\n                      background: \"rgba(0, 0, 0, 0.6)\",\n                    }}\n                    title={isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"}\n                  >\n                    {isFullscreen ? (\n                      <FaCompress size={Math.max(14, 18 * responsiveScale)} />\n                    ) : (\n                      <FaExpand size={Math.max(14, 18 * responsiveScale)} />\n                    )}\n                  </button>\n                  </div>\n                </>\n              )\n            )}\n\n            {onControlClick && (\n              <div\n                onClick={onControlClick}\n                style={{\n                  position: \"absolute\",\n                  top: 0,\n                  left: 0,\n                  right: 0,\n                  bottom: 0,\n                  zIndex: 1,\n                  cursor: \"pointer\",\n                }}\n              />\n            )}\n          </div>\n        </>\n      );\n    },\n    (prevProps, nextProps) => {\n      for (const prop of CRITICAL_PROPS) {\n        if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n          return false;\n        }\n      }\n\n      const uiProps = [\n        \"autoplay\",\n        \"muted\",\n        \"controls\",\n        \"showCustomControls\",\n        \"className\",\n        \"style\",\n        \"wrapperClassName\",\n        \"wrapperStyle\",\n        \"playsInline\",\n        \"preload\",\n        \"poster\",\n        \"children\",\n      ] as const;\n\n      for (const prop of uiProps) {\n        if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n          return false;\n        }\n      }\n\n      const callbackProps = [\n        \"onReady\",\n        \"onVolumeToggle\",\n        \"onFullscreenToggle\",\n        \"onControlClick\",\n      ] as const;\n      for (const prop of callbackProps) {\n        if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n          return false;\n        }\n      }\n\n      return true;\n    }\n  );\n","import type { AdController } from \"../types\";\nimport Hls from \"hls.js\";\n\ninterface VastMediaFile {\n  url: string;\n  type: string;\n  width: number;\n  height: number;\n  bitrate?: number | undefined;\n}\n\ninterface VastTrackingUrls {\n  impression: string[];\n  start: string[];\n  firstQuartile: string[];\n  midpoint: string[];\n  thirdQuartile: string[];\n  complete: string[];\n  mute: string[];\n  unmute: string[];\n  pause: string[];\n  resume: string[];\n  fullscreen: string[];\n  exitFullscreen: string[];\n  skip: string[];\n  error: string[];\n}\n\ninterface VastAd {\n  id: string;\n  title: string;\n  duration: number;\n  mediaFiles: VastMediaFile[];\n  trackingUrls: VastTrackingUrls;\n  clickThrough?: string | undefined;\n}\n\ntype VastParseResult =\n  | { type: \"inline\"; ad: VastAd }\n  | {\n      type: \"wrapper\";\n      vastAdTagUri: string;\n      trackingUrls: VastTrackingUrls;\n      clickThrough?: string | undefined;\n    }\n  | { type: \"empty\" };\n\nconst MAX_VAST_WRAPPER_DEPTH = 5;\n\nexport function createHlsAdPlayer(\n  contentVideo: HTMLVideoElement,\n  options?: {\n    continueLiveStreamDuringAds?: boolean;\n    licenseKey?: string;\n    mainHlsInstance?: Hls;\n  }\n): AdController {\n  let adPlaying = false;\n  let originalMutedState = false;\n  let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n  const listeners = new Map<string, Set<(payload?: any) => void>>();\n  const licenseKey = options?.licenseKey;\n  const mainHlsInstance = options?.mainHlsInstance;\n\n  let adVideoElement: HTMLVideoElement | undefined;\n  let adHls: Hls | undefined;\n  let adContainerEl: HTMLDivElement | undefined;\n  let currentAd: VastAd | undefined;\n  let podAds: VastAd[] = [];\n  let podIndex = 0;\n  let sessionId: string | undefined;\n  const preloadedAds = new Map<string, VastAd>();\n  const preloadingAds = new Map<string, Promise<void>>();\n  let destroyed = false;\n  let pendingTimeouts: number[] = [];\n\n  let trackingFired = {\n    impression: false,\n    start: false,\n    firstQuartile: false,\n    midpoint: false,\n    thirdQuartile: false,\n    complete: false,\n  };\n\n  function emit(event: string, payload?: any): void {\n    const set = listeners.get(event);\n    if (!set) return;\n    for (const fn of Array.from(set)) {\n      try {\n        fn(payload);\n      } catch (error) {\n        console.warn(\n          `[HlsAdPlayer] Error in event listener for ${event}:`,\n          error\n        );\n      }\n    }\n  }\n\n  function generateSessionId(): string {\n    return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n  }\n\n  function fireTrackingPixels(urls: string[]): void {\n    if (!urls || urls.length === 0) return;\n\n    urls.forEach((url) => {\n      try {\n        let trackingUrl = url;\n\n        if (sessionId) {\n          trackingUrl = `${trackingUrl}${\n            trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n          }session_id=${sessionId}`;\n        }\n\n        if (licenseKey) {\n          trackingUrl = `${trackingUrl}${\n            trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n          }license_key=${licenseKey}`;\n        }\n\n        const img = new Image(1, 1);\n        img.src = trackingUrl;\n        console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n      } catch (error) {\n        console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n      }\n    });\n  }\n\n  function getMainStreamQuality(): {\n    width: number;\n    height: number;\n    bitrate: number;\n  } | null {\n    if (!mainHlsInstance || !mainHlsInstance.levels) {\n      return null;\n    }\n\n    const currentLevel = mainHlsInstance.currentLevel;\n    if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n      const autoLevel = mainHlsInstance.loadLevel;\n      if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n        const level = mainHlsInstance.levels[autoLevel];\n        return {\n          width: level.width || 1920,\n          height: level.height || 1080,\n          bitrate: level.bitrate || 5000000,\n        };\n      }\n      return null;\n    }\n\n    const level = mainHlsInstance.levels[currentLevel];\n    return {\n      width: level.width || 1920,\n      height: level.height || 1080,\n      bitrate: level.bitrate || 5000000,\n    };\n  }\n\n  function selectBestMediaFile(mediaFiles: VastMediaFile[]): VastMediaFile {\n    if (mediaFiles.length === 0) {\n      throw new Error(\"No media files available\");\n    }\n\n    const firstFile = mediaFiles[0];\n    if (!firstFile) {\n      throw new Error(\"No media files available\");\n    }\n\n    if (mediaFiles.length === 1) {\n      return firstFile;\n    }\n\n    const mainQuality = getMainStreamQuality();\n    if (!mainQuality) {\n      console.log(\n        \"[HlsAdPlayer] No main stream quality info, using first media file\"\n      );\n      return firstFile;\n    }\n\n    console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\n\n    const scoredFiles = mediaFiles.map((file) => {\n      const widthDiff = Math.abs(file.width - mainQuality.width);\n      const heightDiff = Math.abs(file.height - mainQuality.height);\n      const resolutionDiff = widthDiff + heightDiff;\n\n      const fileBitrate = (file.bitrate || 5000) * 1000;\n      const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n\n      const score = resolutionDiff * 2 + bitrateDiff / 1000;\n\n      return { file, score, resolutionDiff, bitrateDiff };\n    });\n\n    scoredFiles.sort((a, b) => a.score - b.score);\n\n    const bestMatch = scoredFiles[0];\n    if (!bestMatch) {\n      console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n      return firstFile;\n    }\n\n    console.log(\"[HlsAdPlayer] Selected media file:\", {\n      url: bestMatch.file.url,\n      resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n      bitrate: bestMatch.file.bitrate,\n      score: bestMatch.score,\n      resolutionDiff: bestMatch.resolutionDiff,\n      bitrateDiff: bestMatch.bitrateDiff,\n    });\n\n    return bestMatch.file;\n  }\n\n  function isHlsMediaFile(mediaFile: VastMediaFile): boolean {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return (\n      type === \"application/x-mpegurl\" ||\n      type === \"application/vnd.apple.mpegurl\" ||\n      type.includes(\"mpegurl\") ||\n      url.includes(\".m3u8\")\n    );\n  }\n\n  function isProgressiveMediaFile(mediaFile: VastMediaFile): boolean {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return (\n      type.startsWith(\"video/\") ||\n      url.endsWith(\".mp4\") ||\n      url.includes(\".mp4?\")\n    );\n  }\n\n  function createEmptyTrackingUrls(): VastTrackingUrls {\n    return {\n      impression: [],\n      start: [],\n      firstQuartile: [],\n      midpoint: [],\n      thirdQuartile: [],\n      complete: [],\n      mute: [],\n      unmute: [],\n      pause: [],\n      resume: [],\n      fullscreen: [],\n      exitFullscreen: [],\n      skip: [],\n      error: [],\n    };\n  }\n\n  function extractTrackingUrls(scope: Document | Element): VastTrackingUrls {\n    const trackingUrls = createEmptyTrackingUrls();\n\n    scope.querySelectorAll(\"Impression\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.impression.push(url);\n    });\n\n    scope.querySelectorAll(\"Tracking\").forEach((el) => {\n      const event = el.getAttribute(\"event\");\n      const url = el.textContent?.trim();\n      if (event && url) {\n        const eventKey = event as keyof VastTrackingUrls;\n        if (trackingUrls[eventKey]) {\n          trackingUrls[eventKey].push(url);\n        }\n      }\n    });\n\n    scope.querySelectorAll(\"Error\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.error.push(url);\n    });\n\n    return trackingUrls;\n  }\n\n  function mergeTrackingUrls(\n    target: VastTrackingUrls,\n    source: VastTrackingUrls\n  ): VastTrackingUrls {\n    (Object.keys(target) as Array<keyof VastTrackingUrls>).forEach((key) => {\n      if (source[key] && source[key].length > 0) {\n        target[key] = target[key].concat(source[key]);\n      }\n    });\n    return target;\n  }\n\n  function parseVastXml(xmlString: string): VastParseResult {\n    try {\n      const parser = new DOMParser();\n      const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n\n      const parserError = xmlDoc.querySelector(\"parsererror\");\n      if (parserError) {\n        console.error(\n          \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n          parserError.textContent\n        );\n        return { type: \"empty\" };\n      }\n\n      const adElement = xmlDoc.querySelector(\"Ad\");\n      if (!adElement) {\n        console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n        return { type: \"empty\" };\n      }\n\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n      const clickThrough = xmlDoc\n        .querySelector(\"ClickThrough\")\n        ?.textContent?.trim();\n\n      const wrapperUri = xmlDoc\n        .querySelector(\"VASTAdTagURI\")\n        ?.textContent?.trim();\n      if (wrapperUri) {\n        console.log(\n          `[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ${wrapperUri}`\n        );\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough,\n        };\n      }\n\n      const isNoAdAvailable =\n        adId === \"empty\" ||\n        title.toLowerCase().includes(\"no ad available\") ||\n        title.toLowerCase() === \"no ad available\";\n\n      const durationText =\n        xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n      const durationParts = durationText.split(\":\");\n      const duration =\n        parseInt(durationParts[0] || \"0\", 10) * 3600 +\n        parseInt(durationParts[1] || \"0\", 10) * 60 +\n        parseInt(durationParts[2] || \"0\", 10);\n\n      const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n      const mediaFiles: VastMediaFile[] = [];\n\n      console.log(\n        `[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n      );\n\n      mediaFileElements.forEach((mf, index) => {\n        const type = mf.getAttribute(\"type\") || \"\";\n        const url = mf.textContent?.trim() || \"\";\n        const width = mf.getAttribute(\"width\") || \"\";\n        const height = mf.getAttribute(\"height\") || \"\";\n\n        console.log(\n          `[HlsAdPlayer] MediaFile ${index}: type=\"${type}\", url=\"${url}\", width=\"${width}\", height=\"${height}\"`\n        );\n\n        const mediaFile: VastMediaFile = {\n          url,\n          type,\n          width: parseInt(width || \"1920\", 10),\n          height: parseInt(height || \"1080\", 10),\n          bitrate: undefined,\n        };\n\n        if (!url) {\n          console.warn(`[HlsAdPlayer] MediaFile ${index} has empty URL`);\n          return;\n        }\n\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr\n          ? parseInt(bitrateAttr, 10)\n          : undefined;\n        mediaFile.bitrate =\n          bitrateValue && bitrateValue > 0 ? bitrateValue : undefined;\n\n        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n          console.log(\n            `[HlsAdPlayer] Added ${isHlsMediaFile(mediaFile) ? \"HLS\" : \"progressive\"} MediaFile: ${url}`\n          );\n        } else {\n          console.log(\n            `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not supported)`\n          );\n        }\n      });\n\n      if (mediaFiles.length === 0) {\n        if (isNoAdAvailable) {\n          console.warn(\n            \"[HlsAdPlayer] No ads available (VAST response indicates no ads)\"\n          );\n        } else {\n          console.warn(\"[HlsAdPlayer] No supported media files found in VAST XML\");\n        }\n        return { type: \"empty\" };\n      }\n\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough,\n        },\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n      return { type: \"empty\" };\n    }\n  }\n\n  function parseAdElement(adElement: Element): VastParseResult {\n    try {\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n      const clickThrough = adElement\n        .querySelector(\"ClickThrough\")\n        ?.textContent?.trim();\n\n      const wrapperUri = adElement\n        .querySelector(\"VASTAdTagURI\")\n        ?.textContent?.trim();\n      if (wrapperUri) {\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough,\n        };\n      }\n\n      const isNoAdAvailable =\n        adId === \"empty\" ||\n        title.toLowerCase().includes(\"no ad available\") ||\n        title.toLowerCase() === \"no ad available\";\n\n      const durationText =\n        adElement.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n      const durationParts = durationText.split(\":\");\n      const duration =\n        parseInt(durationParts[0] || \"0\", 10) * 3600 +\n        parseInt(durationParts[1] || \"0\", 10) * 60 +\n        parseInt(durationParts[2] || \"0\", 10);\n\n      const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n      const mediaFiles: VastMediaFile[] = [];\n\n      mediaFileElements.forEach((mf) => {\n        const type = mf.getAttribute(\"type\") || \"\";\n        const url = mf.textContent?.trim() || \"\";\n        const width = mf.getAttribute(\"width\") || \"\";\n        const height = mf.getAttribute(\"height\") || \"\";\n\n        if (!url) return;\n\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : undefined;\n\n        const mediaFile: VastMediaFile = {\n          url,\n          type,\n          width: parseInt(width || \"1920\", 10),\n          height: parseInt(height || \"1080\", 10),\n          bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : undefined,\n        };\n\n        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n        }\n      });\n\n      if (mediaFiles.length === 0) {\n        if (isNoAdAvailable) {\n          console.warn(\n            \"[HlsAdPlayer] Pod <Ad> indicates no ad available\"\n          );\n        } else {\n          console.warn(\"[HlsAdPlayer] No supported media files in pod <Ad>\");\n        }\n        return { type: \"empty\" };\n      }\n\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough,\n        },\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing pod <Ad> element:\", error);\n      return { type: \"empty\" };\n    }\n  }\n\n  async function fetchVastXml(\n    vastTagUrl: string,\n    credentials: RequestCredentials = \"include\"\n  ): Promise<string> {\n    const requestVast = (creds: RequestCredentials) =>\n      fetch(vastTagUrl, {\n        mode: \"cors\",\n        credentials: creds,\n        headers: {\n          \"Accept\": \"application/xml, text/xml, */*\",\n        },\n        referrerPolicy: \"no-referrer-when-downgrade\",\n      });\n\n    let response: Response;\n    try {\n      response = await requestVast(credentials);\n    } catch (error) {\n      if (credentials !== \"omit\") {\n        console.warn(\n          `[HlsAdPlayer] VAST fetch failed with credentials=\"${credentials}\", retrying without credentials:`,\n          error\n        );\n        response = await requestVast(\"omit\");\n      } else {\n        throw error;\n      }\n    }\n\n    if (!response.ok) {\n      throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n    }\n    return response.text();\n  }\n\n  async function fetchAndParseVastAd(\n    vastTagUrl: string,\n    depth = 0,\n    accumulatedTracking: VastTrackingUrls = createEmptyTrackingUrls()\n  ): Promise<VastAd | null> {\n    const vastXml = await fetchVastXml(\n      vastTagUrl,\n      depth === 0 ? \"include\" : \"omit\"\n    );\n    console.log(\"[HlsAdPlayer] VAST XML received\");\n    console.log(\n      \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n      vastXml.substring(0, 2000)\n    );\n\n    const parsed = parseVastXml(vastXml);\n\n    if (parsed.type === \"empty\") {\n      return null;\n    }\n\n    if (parsed.type === \"wrapper\") {\n      if (depth >= MAX_VAST_WRAPPER_DEPTH) {\n        console.warn(\n          `[HlsAdPlayer] VAST wrapper depth limit (${MAX_VAST_WRAPPER_DEPTH}) reached, aborting redirect chain`\n        );\n        return null;\n      }\n\n      mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);\n      return fetchAndParseVastAd(\n        parsed.vastAdTagUri,\n        depth + 1,\n        accumulatedTracking\n      );\n    }\n\n    mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);\n    return parsed.ad;\n  }\n\n  async function fetchAndParsePod(vastTagUrl: string): Promise<VastAd[]> {\n    const vastXml = await fetchVastXml(vastTagUrl);\n    console.log(\"[HlsAdPlayer] Pod VAST XML received\");\n\n    const parser = new DOMParser();\n    const xmlDoc = parser.parseFromString(vastXml, \"text/xml\");\n\n    if (xmlDoc.querySelector(\"parsererror\")) {\n      console.error(\"[HlsAdPlayer] Pod VAST XML parsing error (malformed)\");\n      return [];\n    }\n\n    const adElements = Array.from(xmlDoc.querySelectorAll(\"Ad\"));\n    if (adElements.length === 0) {\n      console.warn(\"[HlsAdPlayer] No <Ad> elements found in pod VAST response\");\n      return [];\n    }\n\n    adElements.sort((a, b) => {\n      const aSeq = parseInt(a.getAttribute(\"sequence\") || \"\", 10);\n      const bSeq = parseInt(b.getAttribute(\"sequence\") || \"\", 10);\n      const aVal = Number.isFinite(aSeq) ? aSeq : Number.MAX_SAFE_INTEGER;\n      const bVal = Number.isFinite(bSeq) ? bSeq : Number.MAX_SAFE_INTEGER;\n      return aVal - bVal;\n    });\n\n    const ads: VastAd[] = [];\n    for (const adElement of adElements) {\n      const parsed = parseAdElement(adElement);\n\n      if (parsed.type === \"inline\") {\n        ads.push(parsed.ad);\n      } else if (parsed.type === \"wrapper\") {\n        try {\n          const resolved = await fetchAndParseVastAd(\n            parsed.vastAdTagUri,\n            1,\n            parsed.trackingUrls\n          );\n          if (resolved) {\n            ads.push(resolved);\n          }\n        } catch (error) {\n          console.warn(\n            \"[HlsAdPlayer] Failed to resolve wrapper <Ad> in pod:\",\n            error\n          );\n        }\n      }\n    }\n\n    console.log(`[HlsAdPlayer] Parsed ${ads.length} ad(s) from pod VAST response`);\n    return ads;\n  }\n\n  function createAdVideoElement(): HTMLVideoElement {\n    const video = document.createElement(\"video\");\n    video.style.position = \"absolute\";\n    video.style.left = \"0\";\n    video.style.top = \"0\";\n    video.style.width = \"100%\";\n    video.style.height = \"100%\";\n    video.style.objectFit = \"contain\";\n    video.style.backgroundColor = \"#000\";\n    video.playsInline = true;\n    video.muted = false;\n\n    video.volume = 1.0;\n    console.log(\n      `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n    );\n\n    return video;\n  }\n\n  function setupAdEventListeners(): void {\n    if (!adVideoElement || !currentAd) return;\n\n    adVideoElement.addEventListener(\"timeupdate\", () => {\n      if (!currentAd || !adVideoElement) return;\n\n      const progress = adVideoElement.currentTime / currentAd.duration;\n\n      if (progress >= 0.25 && !trackingFired.firstQuartile) {\n        trackingFired.firstQuartile = true;\n        fireTrackingPixels(currentAd.trackingUrls.firstQuartile);\n      }\n\n      if (progress >= 0.5 && !trackingFired.midpoint) {\n        trackingFired.midpoint = true;\n        fireTrackingPixels(currentAd.trackingUrls.midpoint);\n      }\n\n      if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n        trackingFired.thirdQuartile = true;\n        fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);\n      }\n    });\n\n    adVideoElement.addEventListener(\"playing\", () => {\n      if (!currentAd || trackingFired.start) return;\n      trackingFired.start = true;\n      fireTrackingPixels(currentAd.trackingUrls.start);\n      console.log(\"[HlsAdPlayer] Ad started playing\");\n    });\n\n    adVideoElement.addEventListener(\"ended\", () => {\n      if (!currentAd || trackingFired.complete) return;\n      trackingFired.complete = true;\n      fireTrackingPixels(currentAd.trackingUrls.complete);\n      console.log(\"[HlsAdPlayer] Ad completed\");\n\n      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\n      }\n\n      handleAdComplete();\n    });\n\n    adVideoElement.addEventListener(\"error\", (e) => {\n      if (!adPlaying) return;\n      console.error(\"[HlsAdPlayer] Ad video error:\", e);\n      if (currentAd) {\n        fireTrackingPixels(currentAd.trackingUrls.error);\n      }\n\n      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\n      }\n\n      handleAdError();\n    });\n\n    adVideoElement.addEventListener(\"volumechange\", () => {\n      if (!currentAd) return;\n      if (adVideoElement!.muted) {\n        fireTrackingPixels(currentAd.trackingUrls.mute);\n      } else {\n        fireTrackingPixels(currentAd.trackingUrls.unmute);\n      }\n    });\n\n    adVideoElement.addEventListener(\"pause\", () => {\n      if (currentAd && !adVideoElement!.ended) {\n        fireTrackingPixels(currentAd.trackingUrls.pause);\n      }\n    });\n\n    adVideoElement.addEventListener(\"play\", () => {\n      if (currentAd && adVideoElement!.currentTime > 0) {\n        fireTrackingPixels(currentAd.trackingUrls.resume);\n      }\n    });\n  }\n\n  function setAdPlayingFlag(isPlaying: boolean): void {\n    if (isPlaying) {\n      contentVideo.dataset.stormcloudAdPlaying = \"true\";\n    } else {\n      delete contentVideo.dataset.stormcloudAdPlaying;\n    }\n  }\n\n  function resetQuartileTracking(preserveImpression: boolean): void {\n    trackingFired = {\n      impression: preserveImpression ? trackingFired.impression : false,\n      start: false,\n      firstQuartile: false,\n      midpoint: false,\n      thirdQuartile: false,\n      complete: false,\n    };\n  }\n\n  function loadCurrentAdMedia(): void {\n    if (!adVideoElement || !currentAd) {\n      throw new Error(\"No ad video element or ad to load\");\n    }\n\n    const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n    if (!mediaFile) {\n      throw new Error(\"No media file available for ad\");\n    }\n\n    const isHlsAd = isHlsMediaFile(mediaFile);\n    console.log(\n      `[HlsAdPlayer] Loading ${isHlsAd ? \"HLS\" : \"progressive\"} ad (pod ${podIndex + 1}/${podAds.length || 1}) from: ${mediaFile.url}`\n    );\n\n    if (isHlsAd && Hls.isSupported()) {\n      if (adHls) {\n        adHls.destroy();\n      }\n\n      adHls = new Hls({\n        enableWorker: true,\n        lowLatencyMode: false,\n      });\n\n      adHls.loadSource(mediaFile.url);\n      adHls.attachMedia(adVideoElement);\n\n      adHls.on(Hls.Events.MANIFEST_PARSED, () => {\n        console.log(\"[HlsAdPlayer] HLS manifest parsed, starting playback\");\n        adVideoElement!.play().catch((error) => {\n          console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n          handleAdError();\n        });\n      });\n\n      adHls.on(Hls.Events.ERROR, (_event, data) => {\n        console.error(\"[HlsAdPlayer] HLS error:\", data);\n        if (data.fatal) {\n          handleAdError();\n        }\n      });\n    } else if (\n      isHlsAd &&\n      adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")\n    ) {\n      adVideoElement.src = mediaFile.url;\n      adVideoElement.play().catch((error) => {\n        console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n        handleAdError();\n      });\n    } else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {\n      if (adHls) {\n        adHls.destroy();\n        adHls = undefined;\n      }\n\n      adVideoElement.src = mediaFile.url;\n      adVideoElement.load();\n      adVideoElement.play().catch((error) => {\n        console.error(\"[HlsAdPlayer] Error starting progressive ad playback:\", error);\n        handleAdError();\n      });\n    } else {\n      throw new Error(`Unsupported ad media file type: ${mediaFile.type}`);\n    }\n  }\n\n  function advanceToNextPodAd(): boolean {\n    if (podIndex >= podAds.length - 1) {\n      return false;\n    }\n\n    podIndex++;\n    currentAd = podAds[podIndex];\n    resetQuartileTracking(false);\n\n    if (currentAd) {\n      fireTrackingPixels(currentAd.trackingUrls.impression);\n      trackingFired.impression = true;\n      console.log(\n        `[HlsAdPlayer] Advancing to next pod ad (${podIndex + 1}/${podAds.length}): ${currentAd.title}, duration: ${currentAd.duration}s`\n      );\n    }\n\n    try {\n      loadCurrentAdMedia();\n      emit(\"pod_ad_started\", { index: podIndex, total: podAds.length });\n      return true;\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Failed to load next pod ad:\", error);\n      return false;\n    }\n  }\n\n  function handleAdComplete(): void {\n    console.log(\"[HlsAdPlayer] Handling ad completion\");\n    adPlaying = false;\n    setAdPlayingFlag(false);\n\n    contentVideo.muted = true;\n\n    if (adContainerEl) {\n      adContainerEl.style.display = \"none\";\n      adContainerEl.style.pointerEvents = \"none\";\n    }\n    \n    if (options?.continueLiveStreamDuringAds) {\n      if (contentVideo.paused) {\n        console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback\");\n        contentVideo.play().catch(() => {});\n      } else {\n        console.log(\"[HlsAdPlayer] Content video already playing in live mode\");\n      }\n    }\n\n    emit(\"content_resume\");\n  }\n\n  function handleAdError(): void {\n    console.log(\"[HlsAdPlayer] Handling ad error\");\n    adPlaying = false;\n    setAdPlayingFlag(false);\n\n    contentVideo.muted = true;\n\n    if (adContainerEl) {\n      adContainerEl.style.display = \"none\";\n      adContainerEl.style.pointerEvents = \"none\";\n    }\n\n    emit(\"ad_error\");\n  }\n\n  return {\n    initialize() {\n      console.log(\"[HlsAdPlayer] Initializing\");\n\n      if (!adContainerEl) {\n        const container = document.createElement(\"div\");\n        container.style.position = \"absolute\";\n        container.style.left = \"0\";\n        container.style.top = \"0\";\n        container.style.right = \"0\";\n        container.style.bottom = \"0\";\n        container.style.display = \"none\";\n        container.style.alignItems = \"center\";\n        container.style.justifyContent = \"center\";\n        container.style.pointerEvents = \"none\";\n        container.style.zIndex = \"30\";\n        container.style.backgroundColor = \"#000\";\n\n        contentVideo.parentElement?.appendChild(container);\n        adContainerEl = container;\n      }\n    },\n\n    async requestAds(vastTagUrl: string) {\n      console.log(\"[HlsAdPlayer] Requesting ads:\", vastTagUrl);\n\n      if (adPlaying) {\n        console.warn(\n          \"[HlsAdPlayer] Cannot request new ads while an ad is playing\"\n        );\n        return Promise.reject(new Error(\"Ad already playing\"));\n      }\n\n      try {\n        sessionId = generateSessionId();\n        let ads: VastAd[] = [];\n\n        if (preloadedAds.has(vastTagUrl)) {\n          const preloaded = preloadedAds.get(vastTagUrl);\n          preloadedAds.delete(vastTagUrl);\n          if (preloaded) {\n            ads = [preloaded];\n          }\n          console.log(\n            \"[HlsAdPlayer] Using preloaded VAST response:\",\n            vastTagUrl\n          );\n        } else {\n          ads = await fetchAndParsePod(vastTagUrl);\n        }\n\n        if (!ads.length) {\n          console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n          emit(\"ad_error\");\n          return Promise.reject(new Error(\"No ads available from VAST response\"));\n        }\n\n        podAds = ads;\n        podIndex = 0;\n        currentAd = ads[0];\n        console.log(\n          `[HlsAdPlayer] Pod parsed: ${ads.length} ad(s), first=\"${currentAd?.title}\", duration=${currentAd?.duration}s`\n        );\n\n        if (currentAd) {\n          fireTrackingPixels(currentAd.trackingUrls.impression);\n          trackingFired.impression = true;\n        }\n\n        return Promise.resolve();\n      } catch (error) {\n        console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n        emit(\"ad_error\");\n        return Promise.reject(error);\n      }\n    },\n    async play() {\n      if (!currentAd) {\n        console.warn(\n          \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n        );\n        return Promise.reject(new Error(\"No ad loaded\"));\n      }\n\n      console.log(\"[HlsAdPlayer] Starting ad playback\");\n\n      try {\n        if (!adVideoElement) {\n          adVideoElement = createAdVideoElement();\n          adContainerEl?.appendChild(adVideoElement);\n          setupAdEventListeners();\n        }\n\n        resetQuartileTracking(true);\n\n        const contentVolume = contentVideo.volume;\n        originalVolume = Math.max(\n          0,\n          Math.min(1, contentVolume || originalVolume)\n        );\n\n        if (!options?.continueLiveStreamDuringAds) {\n          contentVideo.pause();\n          console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n        } else {\n          console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n        }\n\n        console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n        contentVideo.muted = true;\n        adPlaying = true;\n        setAdPlayingFlag(true);\n\n        if (adVideoElement) {\n          adVideoElement.volume = Math.max(0, Math.min(1, originalVolume));\n          adVideoElement.muted = originalMutedState;\n          console.log(\n            `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`\n          );\n        }\n\n        if (adContainerEl) {\n          adContainerEl.style.display = \"flex\";\n          adContainerEl.style.pointerEvents = \"auto\";\n        }\n\n        emit(\"content_pause\");\n\n        loadCurrentAdMedia();\n\n        return Promise.resolve();\n      } catch (error) {\n        console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n        handleAdError();\n        return Promise.reject(error);\n      }\n    },\n    pause() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n\n      try {\n        if (adVideoElement && !adVideoElement.paused) {\n          adVideoElement.pause();\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error pausing ad:\", error);\n      }\n    },\n    resume() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n\n      try {\n        if (adVideoElement && adVideoElement.paused) {\n          adVideoElement.play().catch(() => {});\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error resuming ad:\", error);\n      }\n    },\n    async stop() {\n      console.log(\"[HlsAdPlayer] Stopping ad\");\n      adPlaying = false;\n      setAdPlayingFlag(false);\n\n      const previousMutedState = contentVideo.muted;\n      contentVideo.muted = originalMutedState;\n      contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n      console.log(\n        `[HlsAdPlayer] Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}, volume: ${contentVideo.volume}`\n      );\n\n      if (adContainerEl) {\n        adContainerEl.style.display = \"none\";\n        adContainerEl.style.pointerEvents = \"none\";\n      }\n\n      contentVideo.style.visibility = \"visible\";\n      contentVideo.style.opacity = \"1\";\n\n      if (options?.continueLiveStreamDuringAds) {\n        if (contentVideo.paused) {\n          console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback on stop\");\n          contentVideo.play().catch(() => {});\n        }\n      }\n\n      if (adHls) {\n        adHls.destroy();\n        adHls = undefined;\n      }\n\n      if (adVideoElement) {\n        adVideoElement.pause();\n        adVideoElement.src = \"\";\n      }\n\n      currentAd = undefined;\n      podAds = [];\n      podIndex = 0;\n    },\n\n    destroy() {\n      console.log(\"[HlsAdPlayer] Destroying\");\n      destroyed = true;\n      \n      for (const timeoutId of pendingTimeouts) {\n        clearTimeout(timeoutId);\n      }\n      pendingTimeouts = [];\n      \n      adPlaying = false;\n      setAdPlayingFlag(false);\n      contentVideo.muted = originalMutedState;\n      contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n\n      if (adHls) {\n        adHls.destroy();\n        adHls = undefined;\n      }\n\n      if (adVideoElement) {\n        adVideoElement.pause();\n        adVideoElement.src = \"\";\n        adVideoElement.remove();\n        adVideoElement = undefined;\n      }\n\n      if (adContainerEl?.parentElement) {\n        adContainerEl.parentElement.removeChild(adContainerEl);\n      }\n\n      adContainerEl = undefined;\n      currentAd = undefined;\n      podAds = [];\n      podIndex = 0;\n      listeners.clear();\n      preloadedAds.clear();\n      preloadingAds.clear();\n    },\n\n    isAdPlaying() {\n      return adPlaying;\n    },\n\n    resize(width: number, height: number) {\n      console.log(`[HlsAdPlayer] Resizing to ${width}x${height}`);\n\n      if (adContainerEl) {\n        adContainerEl.style.width = `${width}px`;\n        adContainerEl.style.height = `${height}px`;\n      }\n\n      if (adVideoElement) {\n        adVideoElement.style.width = `${width}px`;\n        adVideoElement.style.height = `${height}px`;\n      }\n    },\n\n    on(event: string, listener: (payload?: any) => void) {\n      if (!listeners.has(event)) listeners.set(event, new Set());\n      listeners.get(event)!.add(listener);\n    },\n\n    off(event: string, listener: (payload?: any) => void) {\n      listeners.get(event)?.delete(listener);\n    },\n\n    updateOriginalMutedState(muted: boolean, volume?: number) {\n      const nextVolume =\n        typeof volume === \"number\" && !Number.isNaN(volume)\n          ? Math.max(0, Math.min(1, volume))\n          : originalVolume;\n      console.log(\n        `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n      );\n      originalMutedState = muted;\n      originalVolume = nextVolume;\n    },\n\n    getOriginalMutedState() {\n      return originalMutedState;\n    },\n    getOriginalVolume() {\n      return originalVolume;\n    },\n\n    setAdVolume(volume: number) {\n      if (adVideoElement && adPlaying) {\n        const clamped = Math.max(0, Math.min(1, volume));\n        adVideoElement.volume = clamped;\n        adVideoElement.muted = clamped === 0;\n      }\n    },\n\n    getAdVolume(): number {\n      if (adVideoElement && adPlaying) {\n        return adVideoElement.volume;\n      }\n      return 1;\n    },\n    showPlaceholder() {\n      contentVideo.style.opacity = \"0\";\n      contentVideo.style.visibility = \"hidden\";\n      \n      if (!adContainerEl) {\n        const container = document.createElement(\"div\");\n        container.style.position = \"absolute\";\n        container.style.left = \"0\";\n        container.style.top = \"0\";\n        container.style.right = \"0\";\n        container.style.bottom = \"0\";\n        container.style.display = \"none\";\n        container.style.alignItems = \"center\";\n        container.style.justifyContent = \"center\";\n        container.style.pointerEvents = \"none\";\n        container.style.zIndex = \"10\";\n        container.style.backgroundColor = \"#000\";\n\n        contentVideo.parentElement?.appendChild(container);\n        adContainerEl = container;\n      }\n\n      if (adContainerEl) {\n        adContainerEl.style.display = \"flex\";\n        adContainerEl.style.pointerEvents = \"auto\";\n      }\n    },\n    hidePlaceholder() {\n      if (adContainerEl) {\n        adContainerEl.style.display = \"none\";\n        adContainerEl.style.pointerEvents = \"none\";\n      }\n      \n      if (!adPlaying) {\n        contentVideo.style.visibility = \"visible\";\n        contentVideo.style.opacity = \"1\";\n      }\n    },\n    getLoadedAdDuration() {\n      return currentAd?.duration;\n    },\n    getLoadedAdId() {\n      return currentAd?.id;\n    },\n    getPodAdCount() {\n      return podAds.length;\n    },\n    getPodTotalDurationMs() {\n      return podAds.reduce(\n        (total, ad) => total + (ad.duration > 0 ? ad.duration * 1000 : 0),\n        0\n      );\n    },\n  };\n}\n","declare global {\n  interface Window {\n    goog?: any;\n  }\n}\n\nconst PAL_SDK_URL =\n  \"https://imasdk.googleapis.com/pal/sdkloader/pal.js\";\n\nlet _nonceLoader: any | undefined;\nlet _palLoadPromise: Promise<void> | undefined;\n\nfunction loadPalSdk(): Promise<void> {\n  if (typeof window !== \"undefined\" && window.goog?.pal) {\n    return Promise.resolve();\n  }\n\n  if (_palLoadPromise) return _palLoadPromise;\n\n  _palLoadPromise = new Promise<void>((resolve, reject) => {\n    const existing = document.querySelector(\n      'script[data-pal=\"true\"]'\n    ) as HTMLScriptElement | null;\n\n    if (existing) {\n      if (window.goog?.pal) {\n        resolve();\n        return;\n      }\n      const timeout = setTimeout(\n        () => reject(new Error(\"PAL SDK load timeout\")),\n        10000\n      );\n      existing.addEventListener(\"load\", () => {\n        clearTimeout(timeout);\n        resolve();\n      });\n      existing.addEventListener(\"error\", () => {\n        clearTimeout(timeout);\n        reject(new Error(\"PAL SDK load failed\"));\n      });\n      return;\n    }\n\n    const script = document.createElement(\"script\");\n    script.src = PAL_SDK_URL;\n    script.async = true;\n    script.setAttribute(\"data-pal\", \"true\");\n    script.onload = () => resolve();\n    script.onerror = () => reject(new Error(\"PAL SDK load failed\"));\n    document.head.appendChild(script);\n  });\n\n  return _palLoadPromise;\n}\n\nfunction getOrCreateNonceLoader(): any {\n  if (_nonceLoader) return _nonceLoader;\n  const goog = window.goog;\n  const consentSettings = new goog.pal.ConsentSettings();\n  consentSettings.allowStorage = true;\n  _nonceLoader = new goog.pal.NonceLoader(consentSettings);\n  return _nonceLoader;\n}\n\nexport interface PalNonceOptions {\n  videoWidth?: number;\n  videoHeight?: number;\n  descriptionUrl?: string;\n  ppid?: string;\n  sessionId?: string;\n  adWillAutoPlay?: boolean;\n  adWillPlayMuted?: boolean;\n  playerVolume?: number;\n  continuousPlayback?: boolean;\n}\n\nexport interface PalNonceManager {\n  generateNonce(options?: PalNonceOptions): Promise<string>;\n\n  getCurrentNonce(): string;\n\n  injectNonce(vastTagUrl: string): string;\n\n  sendPlaybackStart(): void;\n\n  sendPlaybackEnd(): void;\n\n  sendAdClick(): void;\n\n  sendAdTouch(event: MouseEvent | TouchEvent): void;\n\n  reset(): void;\n}\n\nexport function createPalNonceManager(): PalNonceManager {\n  let currentNonce = \"\";\n  let currentNonceManager: any | undefined;\n\n  return {\n    async generateNonce(options: PalNonceOptions = {}): Promise<string> {\n      try {\n        await loadPalSdk();\n\n        const loader = getOrCreateNonceLoader();\n        const goog = window.goog;\n\n        const request = new goog.pal.NonceRequest();\n        request.adWillAutoPlay = options.adWillAutoPlay ?? true;\n        request.adWillPlayMuted = options.adWillPlayMuted ?? false;\n        request.playerVolume =\n          options.playerVolume ?? (request.adWillPlayMuted ? 0 : 1);\n        request.continuousPlayback = options.continuousPlayback ?? true;\n        request.descriptionUrl =\n          options.descriptionUrl ||\n          (typeof window !== \"undefined\" ? window.location.href : \"\");\n        request.iconsSupported = true;\n        request.playerType = \"StormcloudVideoPlayer\";\n        request.playerVersion = \"1.0\";\n        request.supportedApiFrameworks = \"2,7,9\";\n        request.url =\n          options.descriptionUrl ||\n          (typeof window !== \"undefined\" ? window.location.href : \"\");\n        request.videoWidth = options.videoWidth || 640;\n        request.videoHeight = options.videoHeight || 480;\n\n        if (options.ppid) request.ppid = options.ppid;\n        if (options.sessionId) request.sessionId = options.sessionId;\n\n        console.log(\"[PAL] NonceRequest before generateNonce:\", {\n          adWillAutoPlay: request.adWillAutoPlay,\n          adWillPlayMuted: request.adWillPlayMuted,\n          playerVolume: request.playerVolume,\n          continuousPlayback: request.continuousPlayback,\n          descriptionUrl: request.descriptionUrl,\n          iconsSupported: request.iconsSupported,\n          playerType: request.playerType,\n          playerVersion: request.playerVersion,\n          supportedApiFrameworks: request.supportedApiFrameworks,\n          url: request.url,\n          videoWidth: request.videoWidth,\n          videoHeight: request.videoHeight,\n          ppid: request.ppid,\n          sessionId: request.sessionId,\n        });\n\n        const manager = await loader.loadNonceManager(request);\n        currentNonceManager = manager;\n        currentNonce = manager.getNonce() as string;\n\n        console.log(\"[PAL] Nonce generated successfully\");\n        return currentNonce;\n      } catch (error) {\n        console.warn(\"[PAL] Failed to generate nonce:\", error);\n        currentNonce = \"\";\n        currentNonceManager = undefined;\n        return \"\";\n      }\n    },\n\n    getCurrentNonce(): string {\n      return currentNonce;\n    },\n\n    injectNonce(vastTagUrl: string): string {\n      if (!currentNonce || !vastTagUrl) return vastTagUrl;\n\n      try {\n        const url = new URL(vastTagUrl);\n        url.searchParams.delete(\"paln\");\n        url.searchParams.set(\"givn\", currentNonce);\n        return url.toString();\n      } catch {\n        let base = vastTagUrl\n          .replace(/([?&])paln=[^&]*/g, \"\")\n          .replace(/[?&]$/, \"\");\n        const sep = base.includes(\"?\") ? \"&\" : \"?\";\n        return `${base}${sep}givn=${encodeURIComponent(currentNonce)}`;\n      }\n    },\n\n    sendPlaybackStart(): void {\n      try {\n        currentNonceManager?.sendPlaybackStart();\n      } catch {}\n    },\n\n    sendPlaybackEnd(): void {\n      try {\n        currentNonceManager?.sendPlaybackEnd();\n      } catch {}\n    },\n\n    sendAdClick(): void {\n      try {\n        currentNonceManager?.sendAdClick();\n      } catch {}\n    },\n\n    sendAdTouch(event: MouseEvent | TouchEvent): void {\n      try {\n        currentNonceManager?.sendAdTouch(event);\n      } catch {}\n    },\n\n    reset(): void {\n      currentNonce = \"\";\n      currentNonceManager = undefined;\n    },\n  };\n}\n","export const MQTT_CA_CERT_FILE = \"src/certs/emqxsl-ca.crt\";\n\nexport type MQTTConfig = {\n  enabled: boolean;\n  brokerAddress: string;\n  brokerPort: number;\n  wsPort: number;\n  username: string;\n  password: string;\n  topicPrefix: string;\n  qos: 0 | 1 | 2;\n  brokerUrl?: string;\n};\n\nexport const DEFAULT_MQTT_CONFIG: MQTTConfig = {\n  enabled: true,\n  brokerAddress: \"vecbae77.ala.us-east-1.emqxsl.com\",\n  brokerPort: 8883,\n  wsPort: 8084,\n  username: \"for-sonifi\",\n  password: \"sonifi-mqtt\",\n  topicPrefix: \"adstorm/players\",\n  qos: 1,\n};\n\nexport const mqttConfig: MQTTConfig = { ...DEFAULT_MQTT_CONFIG };\n\nexport function applyMQTTConfig(overrides: Partial<MQTTConfig>): void {\n  Object.assign(mqttConfig, overrides);\n}\n\nexport function isMQTTEnabled(): boolean {\n  return mqttConfig.enabled;\n}\n\nexport function buildMQTTBrokerUrl(): string {\n  if (mqttConfig.brokerUrl) return mqttConfig.brokerUrl;\n  return `wss://${mqttConfig.brokerAddress}:${mqttConfig.wsPort}/mqtt`;\n}\n\nexport function buildPlayerTopic(\n  licenseKey: string,\n  channel: \"metrics\" | \"impressions\" | \"heartbeat\"\n): string {\n  return `${mqttConfig.topicPrefix}/${licenseKey}/${channel}`;\n}\n","import mqtt from \"mqtt\";\nimport type { MqttClient } from \"mqtt\";\nimport {\n  applyMQTTConfig,\n  buildMQTTBrokerUrl,\n  isMQTTEnabled,\n  mqttConfig,\n} from \"./mqttConfig\";\nimport type { MQTTConfig } from \"./mqttConfig\";\n\nconst LOG = \"[StormcloudVideoPlayer][MQTT]\";\n\nexport type MQTTStatus = \"disconnected\" | \"connecting\" | \"connected\" | \"error\";\n\nlet client: MqttClient | null = null;\nlet status: MQTTStatus = \"disconnected\";\n\nexport function getMQTTStatus(): MQTTStatus {\n  return status;\n}\n\nexport function isMQTTConnected(): boolean {\n  return status === \"connected\" && client !== null && client.connected;\n}\n\nexport function isMQTTConfigured(): boolean {\n  return isMQTTEnabled();\n}\n\nexport function configureMQTT(overrides: Partial<MQTTConfig>): void {\n  applyMQTTConfig(overrides);\n  disconnectMQTT();\n}\n\nexport function initMQTTClient(): void {\n  if (client || !isMQTTEnabled()) return;\n\n  const url = buildMQTTBrokerUrl();\n  status = \"connecting\";\n\n  const clientId = `stormcloud-vp-${Math.random().toString(36).slice(2, 9)}`;\n\n  try {\n    client = mqtt.connect(url, {\n      clientId,\n      username: mqttConfig.username,\n      password: mqttConfig.password,\n      keepalive: 60,\n      clean: true,\n      reconnectPeriod: 5000,\n      connectTimeout: 10_000,\n      queueQoSZero: false,\n    });\n  } catch (err) {\n    status = \"error\";\n    console.warn(`${LOG} connect() threw:`, err);\n    return;\n  }\n\n  client.on(\"connect\", () => {\n    status = \"connected\";\n    console.info(`${LOG} connected to ${url}`);\n  });\n\n  client.on(\"reconnect\", () => {\n    status = \"connecting\";\n    console.info(`${LOG} reconnecting…`);\n  });\n\n  client.on(\"offline\", () => {\n    status = \"disconnected\";\n    console.warn(`${LOG} offline`);\n  });\n\n  client.on(\"error\", (err) => {\n    status = \"error\";\n    console.warn(`${LOG} error:`, err.message);\n  });\n\n  client.on(\"close\", () => {\n    if (status === \"connected\") {\n      status = \"disconnected\";\n    }\n  });\n}\n\nexport function ensureMQTTClient(): void {\n  if (isMQTTEnabled() && !client) {\n    initMQTTClient();\n  }\n}\n\nexport function publishMQTT(\n  topic: string,\n  payload: Record<string, unknown>\n): boolean {\n  if (!isMQTTEnabled()) {\n    return false;\n  }\n\n  ensureMQTTClient();\n\n  if (!client) {\n    return false;\n  }\n\n  try {\n    client.publish(topic, JSON.stringify(payload), { qos: mqttConfig.qos });\n    return true;\n  } catch (err) {\n    console.warn(`${LOG} publish failed on ${topic}:`, err);\n    return false;\n  }\n}\n\nexport function disconnectMQTT(): void {\n  if (client) {\n    client.end(true);\n    client = null;\n    status = \"disconnected\";\n  }\n}\n","export interface VastEnvironmentSignals {\n  isCtv: boolean;\n  contentUrl?: string;\n  appId?: string;\n  appName?: string;\n  sessionId?: string;\n  deviceId?: string;\n  deviceIdType?: string;\n  limitAdTracking?: boolean;\n  deviceTypeHint?: number;\n}\n\nconst AIRY_ANDROID_APP_ID = \"com.freeairytv.android\";\nconst AIRY_WEBOS_APP_ID    = \"com.freeairytv.webos\";\nconst AIRY_TIZEN_APP_ID    = \"com.freeairytv.samsung\";\nconst AIRY_ROKU_APP_ID     = \"com.freeairytv.roku\";\nconst AIRY_APP_NAME = \"AiryTV Movies & TV\";\nconst AIRY_DEFAULT_CONTENT_URL = \"https://live.airy.tv\";\nconst CTV_SESSION_STORAGE_KEY = \"stormcloud.ctv.sid\";\nexport const PLAYER_ID_STORAGE_KEY = \"stormcloud.player.id\";\n\nconst LG_TEST_APP_ID      = \"com.hulu.plus\";\nconst LG_TEST_APP_NAME    = \"Hulu\";\nconst LG_TEST_CONTENT_URL = \"https://www.hulu.com/live-tv\";\n\nlet _lgTestDeviceId: string | undefined;\nfunction getLgTestDeviceId(): string {\n  if (!_lgTestDeviceId) _lgTestDeviceId = createUuid();\n  return _lgTestDeviceId;\n}\n\nfunction isLgWebOS(): boolean {\n  if (typeof navigator === \"undefined\") return false;\n  return /Web0S|webOS|LG Browser|LGSTB|LGE/i.test(navigator.userAgent);\n}\n\nfunction getDefaultAppId(): string {\n  if (typeof navigator === \"undefined\") return AIRY_ANDROID_APP_ID;\n  const ua = navigator.userAgent;\n  if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;\n  if (/Tizen|Samsung/i.test(ua))                       return AIRY_TIZEN_APP_ID;\n  if (/Roku/i.test(ua))                                return AIRY_ROKU_APP_ID;\n  return AIRY_ANDROID_APP_ID;\n}\n\nconst DEVICE_ID_STORAGE_KEYS = [\n  \"rdid\",\n  \"ifa\",\n  \"advertisingId\",\n  \"advertising_id\",\n  \"deviceAdvertisingId\",\n  \"aaid\",\n  \"adid\",\n  \"rida\",\n  \"tifa\",\n  \"lgudid\",\n];\n\nconst ANDROID_ID_TYPES = new Set([\"aaid\", \"adid\"]);\n\nexport function resolveVastEnvironmentSignals(isCtv: boolean): VastEnvironmentSignals {\n  const bridgeSignals  = readNativeBridgeSignals();\n  const platformDevice = readPlatformNativeDeviceId();\n  const lg = isCtv && isLgWebOS();\n\n  const deviceId =\n    bridgeSignals.deviceId  ||\n    readStoredDeviceId()    ||\n    platformDevice.deviceId ||\n    (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : undefined);\n  const deviceIdType =\n    bridgeSignals.deviceIdType  ||\n    readStoredString(\"deviceIdType\") ||\n    readStoredString(\"idtype\") ||\n    platformDevice.deviceIdType ||\n    inferDeviceIdType() ||\n    (lg ? \"lgudid\" : undefined);\n  const platformLat = bridgeSignals.deviceId\n    ? bridgeSignals.limitAdTracking\n    : platformDevice.limitAdTracking;\n  const limitAdTracking =\n    deviceId != null\n      ? platformLat ?? readStoredLimitAdTracking() ?? false\n      : undefined;\n\n  if (isCtv) {\n    return {\n      isCtv: true,\n      contentUrl:\n        bridgeSignals.contentUrl ||\n        readStoredString(\"contentUrl\") ||\n        (lg ? LG_TEST_CONTENT_URL : AIRY_DEFAULT_CONTENT_URL),\n      appId:\n        bridgeSignals.appId ||\n        readStoredString(\"appId\") ||\n        readStoredString(\"msid\") ||\n        (lg ? LG_TEST_APP_ID : getDefaultAppId()),\n      appName:\n        bridgeSignals.appName ||\n        readStoredString(\"appName\") ||\n        readStoredString(\"an\") ||\n        (lg ? LG_TEST_APP_NAME : AIRY_APP_NAME),\n      sessionId: getOrCreateCtvSessionId(),\n      ...(deviceId ? { deviceId } : {}),\n      ...(deviceIdType ? { deviceIdType } : {}),\n      ...(limitAdTracking != null ? { limitAdTracking } : {}),\n      deviceTypeHint: 5,\n    };\n  }\n\n  return {\n    isCtv: false,\n    ...(deviceId ? { deviceId } : {}),\n    ...(deviceIdType ? { deviceIdType } : {}),\n    ...(limitAdTracking != null ? { limitAdTracking } : {}),\n  };\n}\n\nexport function inferDeviceIdType(): string | undefined {\n  if (typeof navigator === \"undefined\") {\n    return undefined;\n  }\n\n  const ua = navigator.userAgent;\n  if (/Roku/i.test(ua)) return \"rida\";\n  if (/Tizen|Samsung/i.test(ua)) return \"tifa\";\n  if (/AppleTV|Apple TV/i.test(ua)) return \"tvOS\";\n  if (/AFT|Fire TV|Amazon/i.test(ua)) return \"afai\";\n  if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return \"lgudid\";\n  if (/Android|Google TV/i.test(ua)) return \"aaid\";\n  if (/iPhone|iPad|iPod/i.test(ua)) return \"idfa\";\n  return undefined;\n}\n\nexport function isEquivalentDeviceIdType(\n  tagType: string | undefined,\n  runtimeType: string | undefined\n): boolean {\n  if (!tagType || !runtimeType) return false;\n  const tag = tagType.toLowerCase();\n  const runtime = runtimeType.toLowerCase();\n  if (tag === runtime) return true;\n  return ANDROID_ID_TYPES.has(tag) && ANDROID_ID_TYPES.has(runtime);\n}\n\nexport function resolveNativeDeviceId(): string | undefined {\n  const bridgeSignals = readNativeBridgeSignals();\n  const platformDevice = readPlatformNativeDeviceId();\n  const deviceId =\n    bridgeSignals.deviceId ||\n    readStoredDeviceId() ||\n    platformDevice.deviceId;\n\n  if (!deviceId || isMacroPlaceholder(deviceId) || isZeroedAdId(deviceId)) {\n    return undefined;\n  }\n\n  return deviceId;\n}\n\nexport function getOrCreateStoredUuid(storageKey: string): string | undefined {\n  if (typeof window === \"undefined\") {\n    return undefined;\n  }\n\n  const existing = readPersistentId(storageKey);\n  if (existing) {\n    writePersistentId(storageKey, existing);\n    return existing;\n  }\n\n  const id = createUuid();\n  writePersistentId(storageKey, id);\n  return id;\n}\n\nfunction getOrCreateCtvSessionId(): string {\n  const existing = readPersistentId(CTV_SESSION_STORAGE_KEY);\n  if (existing) {\n    writePersistentId(CTV_SESSION_STORAGE_KEY, existing);\n    return existing;\n  }\n\n  const sessionId = createUuid();\n  writePersistentId(CTV_SESSION_STORAGE_KEY, sessionId);\n  return sessionId;\n}\n\nfunction readPersistentId(storageKey: string): string | undefined {\n  return readStoredString(storageKey) || readCookie(storageKey);\n}\n\nfunction writePersistentId(storageKey: string, value: string): void {\n  try {\n    window.localStorage?.setItem(storageKey, value);\n  } catch {}\n  writeCookie(storageKey, value);\n}\n\nconst PERSISTENT_ID_COOKIE_MAX_AGE = 60 * 60 * 24 * 365 * 5; // ~5 years\n\nfunction readCookie(name: string): string | undefined {\n  if (typeof document === \"undefined\") {\n    return undefined;\n  }\n\n  try {\n    const prefix = encodeURIComponent(name) + \"=\";\n    const parts = document.cookie ? document.cookie.split(\";\") : [];\n    for (const part of parts) {\n      const entry = part.trim();\n      if (entry.startsWith(prefix)) {\n        return decodeURIComponent(entry.slice(prefix.length)) || undefined;\n      }\n    }\n  } catch {}\n\n  return undefined;\n}\n\nfunction writeCookie(name: string, value: string): void {\n  if (typeof document === \"undefined\") {\n    return;\n  }\n\n  try {\n    document.cookie =\n      encodeURIComponent(name) +\n      \"=\" +\n      encodeURIComponent(value) +\n      \";path=/;max-age=\" +\n      PERSISTENT_ID_COOKIE_MAX_AGE +\n      \";SameSite=Lax\";\n  } catch {}\n}\n\nfunction createUuid(): string {\n  if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n    return crypto.randomUUID();\n  }\n\n  const bytes = new Uint8Array(16);\n  if (typeof crypto !== \"undefined\" && typeof crypto.getRandomValues === \"function\") {\n    crypto.getRandomValues(bytes);\n  } else {\n    let seed = Date.now() ^ Math.floor(performanceNow() * 1e3);\n    for (let i = 0; i < 16; i++) {\n      seed = (seed * 1103515245 + 12345) & 0x7fffffff;\n      bytes[i] = (seed ^ Math.floor(Math.random() * 256)) & 0xff;\n    }\n  }\n\n  bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;\n  bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;\n\n  let hex = \"\";\n  for (let i = 0; i < 16; i++) {\n    hex += (bytes[i] ?? 0).toString(16).padStart(2, \"0\");\n  }\n\n  return (\n    hex.slice(0, 8) +\n    \"-\" +\n    hex.slice(8, 12) +\n    \"-\" +\n    hex.slice(12, 16) +\n    \"-\" +\n    hex.slice(16, 20) +\n    \"-\" +\n    hex.slice(20, 32)\n  );\n}\n\nfunction performanceNow(): number {\n  try {\n    if (typeof performance !== \"undefined\" && typeof performance.now === \"function\") {\n      return performance.now();\n    }\n  } catch {}\n  return 0;\n}\n\nfunction readPlatformNativeDeviceId(): {\n  deviceId?: string;\n  deviceIdType?: string;\n  limitAdTracking?: boolean;\n} {\n  if (typeof window === \"undefined\") return {};\n\n  try {\n    const adinfo = (window as any).webapis?.adinfo;\n    if (adinfo) {\n      const tifa: unknown =\n        typeof adinfo.getTIFA === \"function\" ? adinfo.getTIFA() : adinfo.tifa;\n      if (typeof tifa === \"string\" && tifa && !isMacroPlaceholder(tifa)) {\n        const lat: unknown =\n          typeof adinfo.isLATEnabled === \"function\"\n            ? adinfo.isLATEnabled()\n            : undefined;\n        return {\n          deviceId: tifa,\n          deviceIdType: \"tifa\",\n          ...(typeof lat === \"boolean\" ? { limitAdTracking: lat } : {}),\n        };\n      }\n    }\n  } catch {}\n\n  try {\n    const webOSDev = (window as any).webOSDev;\n    if (webOSDev) {\n      const lgudid: unknown =\n        typeof webOSDev.LGUDID === \"function\"\n          ? webOSDev.LGUDID()\n          : webOSDev.lgudid ?? webOSDev.LGUDID;\n      if (typeof lgudid === \"string\" && lgudid) {\n        if (isZeroedAdId(lgudid)) {\n          return { deviceIdType: \"lgudid\", limitAdTracking: true };\n        }\n        if (!isMacroPlaceholder(lgudid)) {\n          return { deviceId: lgudid, deviceIdType: \"lgudid\", limitAdTracking: false };\n        }\n      }\n    }\n  } catch {}\n\n  try {\n    const roku = (window as any).Roku;\n    if (roku) {\n      const rida: unknown =\n        typeof roku.getPublisherUniqueId === \"function\"\n          ? roku.getPublisherUniqueId()\n          : roku.rida;\n      if (typeof rida === \"string\" && rida && !isMacroPlaceholder(rida)) {\n        return { deviceId: rida, deviceIdType: \"rida\", limitAdTracking: false };\n      }\n    }\n  } catch {}\n\n  return {};\n}\n\nconst ZEROED_AD_ID_PATTERNS: ReadonlySet<string> = new Set([\n  \"38400000-8cf0-11bd-b23e-10b96e40000d\",\n  \"00000000-0000-0000-0000-000000000000\",\n]);\n\nfunction isMacroPlaceholder(value: string): boolean {\n  const t = value.trim();\n  return !t ||\n    /^(\\[[^\\]]*\\]|\\{[^}]*\\}|%%[^%]*%%)$/.test(t) ||\n    /^(unknown|null|undefined|none|n\\/a|\\$\\{[^}]+\\})$/i.test(t) ||\n    ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());\n}\n\nfunction isZeroedAdId(value: string): boolean {\n  return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());\n}\n\nfunction readNativeBridgeSignals(): {\n  contentUrl?: string;\n  appId?: string;\n  appName?: string;\n  deviceId?: string;\n  deviceIdType?: string;\n  limitAdTracking?: boolean;\n} {\n  if (typeof window === \"undefined\") {\n    return {};\n  }\n\n  const candidates = [\n    (window as any).__STORMCLOUD_CTV_AD_INFO__,\n    (window as any).__STORMCLOUD_CTV__,\n    (window as any).stormcloudCtv,\n    (window as any).AiryTV,\n    (window as any).Android,\n    (window as any).webOS,\n    (window as any).tizen,\n    (window as any).amazon,\n  ].filter(Boolean);\n\n  for (const source of candidates) {\n    const contentUrl =\n      readBridgeValue(source, [\"contentUrl\", \"url\", \"videoUrl\", \"canonicalUrl\"]) ||\n      undefined;\n    const appId =\n      readBridgeValue(source, [\"appId\", \"msid\", \"applicationId\", \"packageName\"]) ||\n      undefined;\n    const appName =\n      readBridgeValue(source, [\"appName\", \"an\", \"applicationName\"]) || undefined;\n    const deviceId =\n      readBridgeValue(source, [\n        \"rdid\",\n        \"ifa\",\n        \"advertisingId\",\n        \"adId\",\n        \"deviceId\",\n        \"lgudid\",\n        \"LGUDID\",\n        \"tifa\",\n        \"rida\",\n        \"afai\",\n        \"aaid\",\n      ]) || undefined;\n\n    if (!contentUrl && !deviceId && !appId && !appName) continue;\n\n    const deviceIdType =\n      readBridgeValue(source, [\n        \"idtype\",\n        \"deviceIdType\",\n        \"advertisingIdType\",\n        \"idType\",\n      ]) || inferDeviceIdType();\n    const limitAdTracking = readBridgeBoolean(source, [\n      \"is_lat\",\n      \"limitAdTracking\",\n      \"limitedAdTracking\",\n      \"lat\",\n    ]);\n\n    return {\n      ...(contentUrl ? { contentUrl } : {}),\n      ...(appId ? { appId } : {}),\n      ...(appName ? { appName } : {}),\n      ...(deviceId ? { deviceId } : {}),\n      ...(deviceId && deviceIdType ? { deviceIdType } : {}),\n      ...(deviceId && limitAdTracking != null ? { limitAdTracking } : {}),\n    };\n  }\n\n  return {};\n}\n\nfunction readBridgeValue(source: any, keys: string[]): string | undefined {\n  for (const key of keys) {\n    const value = source?.[key];\n    if (typeof value === \"string\" && value) {\n      return value;\n    }\n    if (typeof value === \"function\") {\n      try {\n        const result = value.call(source);\n        if (typeof result === \"string\" && result) {\n          return result;\n        }\n      } catch {}\n    }\n  }\n  return undefined;\n}\n\nfunction readBridgeBoolean(source: any, keys: string[]): boolean | undefined {\n  for (const key of keys) {\n    const value = source?.[key];\n    const normalized = normalizeBoolean(value);\n    if (normalized != null) {\n      return normalized;\n    }\n    if (typeof value === \"function\") {\n      try {\n        const result = normalizeBoolean(value.call(source));\n        if (result != null) {\n          return result;\n        }\n      } catch {}\n    }\n  }\n  return undefined;\n}\n\nfunction readStoredDeviceId(): string | undefined {\n  for (const key of DEVICE_ID_STORAGE_KEYS) {\n    const value = readStoredString(key);\n    if (value) {\n      return value;\n    }\n  }\n  return undefined;\n}\n\nfunction readStoredString(key: string): string | undefined {\n  if (typeof window === \"undefined\") {\n    return undefined;\n  }\n\n  try {\n    const value = window.localStorage?.getItem(key);\n    return value || undefined;\n  } catch {\n    return undefined;\n  }\n}\n\nfunction readStoredLimitAdTracking(): boolean | undefined {\n  return normalizeBoolean(\n    readStoredString(\"limitAdTracking\") ||\n      readStoredString(\"limitedAdTracking\") ||\n      readStoredString(\"is_lat\")\n  );\n}\n\nfunction normalizeBoolean(value: unknown): boolean | undefined {\n  if (typeof value === \"boolean\") {\n    return value;\n  }\n  if (typeof value === \"number\") {\n    return value === 1;\n  }\n  if (typeof value === \"string\") {\n    const normalized = value.toLowerCase();\n    if (normalized === \"1\" || normalized === \"true\" || normalized === \"yes\") {\n      return true;\n    }\n    if (normalized === \"0\" || normalized === \"false\" || normalized === \"no\") {\n      return false;\n    }\n  }\n  return undefined;\n}\n","import type {\n  ClientInfo,\n  AdDetectInfo,\n  AdLoadedInfo,\n  AdImpressionInfo,\n  PlayerAnalyticsContext,\n  StormcloudVideoPlayerConfig,\n} from \"../types\";\n\nimport { buildPlayerTopic, isMQTTEnabled } from \"./mqttConfig\";\nimport { ensureMQTTClient, publishMQTT } from \"./mqttClient\";\nimport {\n  getOrCreateStoredUuid,\n  PLAYER_ID_STORAGE_KEY,\n  resolveNativeDeviceId,\n} from \"./vastEnvironmentSignals\";\n\nlet cachedBrowserId: string | null = null;\n\nexport function buildAnalyticsContext(\n  config: Pick<StormcloudVideoPlayerConfig, \"debugAdTiming\" | \"isLiveStream\">\n): PlayerAnalyticsContext {\n  const context: PlayerAnalyticsContext = {};\n  if (config.debugAdTiming) {\n    context.debugAdTiming = true;\n  }\n  if (config.isLiveStream !== undefined) {\n    context.inputStreamType = config.isLiveStream ? \"live\" : \"vod\";\n  }\n  return context;\n}\n\nexport function getClientInfo(): ClientInfo {\n  const ua = navigator.userAgent;\n  const platform = navigator.platform;\n  const vendor = navigator.vendor || \"\";\n  const maxTouchPoints = navigator.maxTouchPoints || 0;\n  const memory = (navigator as any).deviceMemory || null;\n  const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n\n  const screenInfo = {\n    width: screen?.width,\n    height: screen?.height,\n    availWidth: screen?.availWidth,\n    availHeight: screen?.availHeight,\n    orientation: (screen?.orientation as any)?.type || \"\",\n    pixelDepth: screen?.pixelDepth,\n  };\n\n  let deviceType: \"tv\" | \"mobile\" | \"tablet\" | \"desktop\" = \"desktop\";\n  let brand = \"Unknown\";\n  let os = \"Unknown\";\n  let model = \"\";\n  let isSmartTV = false;\n  let isAndroid = false;\n  let isWebView = false;\n  let isWebApp = false;\n\n  if (ua.includes(\"Web0S\")) {\n    brand = \"LG\";\n    os = \"webOS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n    const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n    model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n  } else if (ua.includes(\"Tizen\")) {\n    brand = \"Samsung\";\n    os = \"Tizen\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n    const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n    const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n    model = tizenMatch\n      ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim()\n      : \"Tizen TV\";\n  } else if (ua.includes(\"Philips\")) {\n    brand = \"Philips\";\n    os = \"Saphi\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n    brand = \"Sharp\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (\n    ua.includes(\"Android\") &&\n    (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))\n  ) {\n    brand = \"Sony\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (\n    ua.includes(\"Android\") &&\n    (ua.includes(\"NetCast\") || ua.includes(\"LG\"))\n  ) {\n    brand = \"LG\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n    brand = \"Roku\";\n    os = \"Roku OS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"AppleTV\")) {\n    brand = \"Apple\";\n    os = \"tvOS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  }\n\n  if (ua.includes(\"Android\")) {\n    isAndroid = true;\n    os = \"Android\";\n    deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n\n    if (\n      ua.includes(\"Android\") &&\n      (maxTouchPoints === 0 ||\n        ua.includes(\"Google TV\") ||\n        ua.includes(\"XiaoMi\"))\n    ) {\n      deviceType = \"tv\";\n      isSmartTV = true;\n      brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n    }\n\n    const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n    if (androidModelMatch && androidModelMatch[1]) {\n      model = androidModelMatch[1];\n    }\n  }\n\n  if (/iPad|iPhone|iPod/.test(ua)) {\n    os = \"iOS\";\n    deviceType = \"mobile\";\n    brand = \"Apple\";\n    if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n      deviceType = \"tablet\";\n    }\n  }\n\n  if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n    if (ua.includes(\"Windows\")) {\n      os = \"Windows\";\n      deviceType = \"desktop\";\n    } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n      os = \"macOS\";\n      deviceType = \"desktop\";\n      if (maxTouchPoints > 1) deviceType = \"tablet\";\n    } else if (ua.includes(\"Linux\")) {\n      os = \"Linux\";\n      deviceType = \"desktop\";\n    }\n  }\n\n  if (brand === \"Unknown\") {\n    if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n    if (vendor.includes(\"Apple\")) brand = \"Apple\";\n    if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n  }\n\n  isWebView = /wv|WebView|Linux; U;/.test(ua);\n\n  if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n    isWebView = true;\n  }\n\n  isWebApp =\n    window.matchMedia(\"(display-mode: standalone)\").matches ||\n    (window.navigator as any).standalone === true ||\n    window.screen?.orientation?.angle !== undefined;\n\n  return {\n    brand,\n    os,\n    model: model || ua.substring(0, 50) + \"...\",\n    deviceType,\n    isSmartTV,\n    isAndroid,\n    isWebView,\n    isWebApp,\n    domain: window.location.hostname,\n    origin: window.location.origin,\n    path: window.location.pathname,\n    userAgent: ua,\n    vendor,\n    platform,\n    screen: screenInfo,\n    hardwareConcurrency,\n    deviceMemory: memory,\n    maxTouchPoints,\n    language: navigator.language,\n    languages: navigator.languages?.join(\",\") || \"\",\n    cookieEnabled: navigator.cookieEnabled,\n    doNotTrack: navigator.doNotTrack || \"\",\n    referrer: document.referrer,\n    visibilityState: document.visibilityState,\n  };\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n  if (typeof crypto !== \"undefined\" && crypto.subtle?.digest) {\n    try {\n      await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n\n      let encodedData: BufferSource;\n      if (typeof TextEncoder !== \"undefined\") {\n        encodedData = new TextEncoder().encode(input);\n      } else {\n        const utf8 = unescape(encodeURIComponent(input));\n        const buffer = new Uint8Array(utf8.length);\n        for (let i = 0; i < utf8.length; i++) {\n          buffer[i] = utf8.charCodeAt(i);\n        }\n        encodedData = buffer;\n      }\n\n      const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n      return Array.from(new Uint8Array(hashBuffer))\n        .map((b) => b.toString(16).padStart(2, \"0\"))\n        .join(\"\");\n    } catch {\n      console.warn(\n        \"[StormcloudVideoPlayer] crypto.subtle not supported, using fallback hash\"\n      );\n    }\n  }\n\n  let hash = 0;\n  for (let i = 0; i < input.length; i++) {\n    const char = input.charCodeAt(i);\n    hash = (hash << 5) - hash + char;\n    hash = hash & hash;\n  }\n\n  const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n  const timestamp = Date.now().toString(16).padStart(12, \"0\");\n  const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n\n  return (fallbackHash + timestamp + random).padEnd(64, \"0\");\n}\n\nfunction resolvePlayerIdentitySeed(clientInfo: ClientInfo): string {\n  const nativeDeviceId = resolveNativeDeviceId();\n  if (nativeDeviceId) {\n    return `device:${nativeDeviceId}`;\n  }\n\n  const persistedId = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);\n  if (persistedId) {\n    return `persisted:${persistedId}`;\n  }\n\n  return `fingerprint:${JSON.stringify(clientInfo)}`;\n}\n\nexport async function getBrowserID(clientInfo: ClientInfo): Promise<string> {\n  if (cachedBrowserId) {\n    return cachedBrowserId;\n  }\n\n  cachedBrowserId = await sha256Hex(resolvePlayerIdentitySeed(clientInfo));\n  return cachedBrowserId;\n}\n\ntype PlayerMetricFlags = {\n  adLoaded?: boolean;\n  adDetect?: boolean;\n  captureAt?: string;\n};\n\nfunction canPublish(licenseKey: string | undefined): licenseKey is string {\n  return Boolean(isMQTTEnabled() && licenseKey);\n}\n\nasync function buildPlayerMetricEvent(\n  context: PlayerAnalyticsContext = {},\n  flags: PlayerMetricFlags = {}\n): Promise<Record<string, unknown>> {\n  const clientInfo = getClientInfo();\n\n  const debugAdTiming = !!context.debugAdTiming;\n  if (debugAdTiming) {\n    console.log(\"[StormcloudVideoPlayer] clientInfo: \", JSON.stringify(clientInfo, null, 2));\n  }\n\n  const playerId = await getBrowserID(clientInfo);\n\n  if (debugAdTiming) {\n    console.log(\"[StormcloudVideoPlayer] playerId: \", playerId);\n  }\n\n  const captureAt = flags.captureAt ?? new Date().toISOString();\n\n  return {\n    player_id: playerId,\n    device_type: clientInfo.deviceType,\n    os: clientInfo.os.toLowerCase(),\n    ad_loaded: flags.adLoaded ?? false,\n    ad_detect: flags.adDetect ?? false,\n    capture_at: captureAt,\n    ...(context.inputStreamType\n      ? { input_stream_type: context.inputStreamType }\n      : {}),\n  };\n}\n\nfunction publishTracking(\n  licenseKey: string,\n  channel: \"metrics\" | \"impressions\" | \"heartbeat\",\n  body: Record<string, unknown>\n): void {\n  ensureMQTTClient();\n  publishMQTT(buildPlayerTopic(licenseKey, channel), body);\n}\n\nexport async function sendInitialTracking(\n  licenseKey?: string,\n  context: PlayerAnalyticsContext = {}\n): Promise<void> {\n  if (!canPublish(licenseKey)) return;\n\n  try {\n    const metricEvent = await buildPlayerMetricEvent(context, {\n      adLoaded: false,\n      adDetect: false,\n    });\n\n    publishTracking(licenseKey, \"metrics\", {\n      events: [metricEvent],\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n      error\n    );\n  }\n}\n\nexport async function sendAdDetectTracking(\n  licenseKey: string | undefined,\n  adDetectInfo: AdDetectInfo,\n  context: PlayerAnalyticsContext = {}\n): Promise<void> {\n  try {\n    await sendHeartbeat(licenseKey, context, {\n      adDetect: true,\n      captureAt: adDetectInfo.timestamp,\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n      error\n    );\n  }\n}\n\nexport async function sendAdLoadedTracking(\n  licenseKey: string | undefined,\n  adLoadedInfo: AdLoadedInfo,\n  context: PlayerAnalyticsContext = {}\n): Promise<void> {\n  try {\n    await sendHeartbeat(licenseKey, context, {\n      adLoaded: true,\n      captureAt: adLoadedInfo.timestamp,\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n      error\n    );\n  }\n}\n\nexport async function sendAdImpressionTracking(\n  licenseKey: string | undefined,\n  adImpressionInfo: AdImpressionInfo,\n  context: PlayerAnalyticsContext = {}\n): Promise<void> {\n  if (!canPublish(licenseKey)) return;\n\n  try {\n    const metricEvent = await buildPlayerMetricEvent(context, {\n      captureAt: adImpressionInfo.timestamp,\n    });\n\n    publishTracking(licenseKey, \"heartbeat\", metricEvent);\n    publishTracking(licenseKey, \"impressions\", {\n      events: [\n        {\n          player_id: metricEvent.player_id,\n          ad_played_count: 1,\n          ad_url: adImpressionInfo.adUrl,\n          capture_at: adImpressionInfo.timestamp,\n        },\n      ],\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n      error\n    );\n  }\n}\n\nexport async function sendHeartbeat(\n  licenseKey?: string,\n  context: PlayerAnalyticsContext = {},\n  flags: PlayerMetricFlags = {}\n): Promise<void> {\n  if (!canPublish(licenseKey)) return;\n\n  try {\n    const heartbeatData = await buildPlayerMetricEvent(context, flags);\n    publishTracking(licenseKey, \"heartbeat\", heartbeatData);\n  } catch (error) {\n    console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n  }\n}\n","export function polyfillURLSearchParams(): void {\n  if (typeof URLSearchParams !== 'undefined') {\n    return;\n  }\n\n  class URLSearchParamsPolyfill {\n    private params: Map<string, string[]>;\n\n    constructor(init?: string | URLSearchParamsPolyfill) {\n      this.params = new Map();\n\n      if (typeof init === 'string') {\n        this.parseQueryString(init);\n      } else if (init instanceof URLSearchParamsPolyfill) {\n        init.forEach((value, key) => {\n          this.append(key, value);\n        });\n      }\n    }\n\n    private parseQueryString(query: string): void {\n      const cleanQuery = query.startsWith('?') ? query.slice(1) : query;\n      if (!cleanQuery) return;\n\n      cleanQuery.split('&').forEach((param) => {\n        const [key, value] = param.split('=');\n        if (key) {\n          const decodedKey = this.safeDecodeURIComponent(key);\n          const decodedValue = value ? this.safeDecodeURIComponent(value) : '';\n          this.append(decodedKey, decodedValue);\n        }\n      });\n    }\n\n    private safeDecodeURIComponent(str: string): string {\n      try {\n        return decodeURIComponent(str.replace(/\\+/g, ' '));\n      } catch (e) {\n        return str;\n      }\n    }\n\n    append(name: string, value: string): void {\n      const values = this.params.get(name) || [];\n      values.push(String(value));\n      this.params.set(name, values);\n    }\n\n    delete(name: string): void {\n      this.params.delete(name);\n    }\n\n    get(name: string): string | null {\n      const values = this.params.get(name);\n      return values && values.length > 0 && values[0] !== undefined ? values[0] : null;\n    }\n\n    getAll(name: string): string[] {\n      return this.params.get(name) || [];\n    }\n\n    has(name: string): boolean {\n      return this.params.has(name);\n    }\n\n    set(name: string, value: string): void {\n      this.params.set(name, [String(value)]);\n    }\n\n    forEach(callback: (value: string, key: string, parent: URLSearchParamsPolyfill) => void): void {\n      this.params.forEach((values, key) => {\n        values.forEach((value) => {\n          callback(value, key, this);\n        });\n      });\n    }\n\n    toString(): string {\n      const parts: string[] = [];\n      this.params.forEach((values, key) => {\n        values.forEach((value) => {\n          parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\n        });\n      });\n      return parts.join('&');\n    }\n  }\n\n  // @ts-ignore\n  window.URLSearchParams = URLSearchParamsPolyfill;\n}\n\nexport function polyfillTextEncoder(): void {\n  if (typeof TextEncoder !== 'undefined') {\n    return;\n  }\n\n  class TextEncoderPolyfill {\n    encoding = 'utf-8';\n\n    encode(str: string): Uint8Array {\n      const utf8: number[] = [];\n      for (let i = 0; i < str.length; i++) {\n        let charcode = str.charCodeAt(i);\n        if (charcode < 0x80) {\n          utf8.push(charcode);\n        } else if (charcode < 0x800) {\n          utf8.push(0xc0 | (charcode >> 6), 0x80 | (charcode & 0x3f));\n        } else if (charcode < 0xd800 || charcode >= 0xe000) {\n          utf8.push(\n            0xe0 | (charcode >> 12),\n            0x80 | ((charcode >> 6) & 0x3f),\n            0x80 | (charcode & 0x3f)\n          );\n        } else {\n          i++;\n          charcode = 0x10000 + (((charcode & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff));\n          utf8.push(\n            0xf0 | (charcode >> 18),\n            0x80 | ((charcode >> 12) & 0x3f),\n            0x80 | ((charcode >> 6) & 0x3f),\n            0x80 | (charcode & 0x3f)\n          );\n        }\n      }\n      return new Uint8Array(utf8);\n    }\n  }\n\n  // @ts-ignore\n  window.TextEncoder = TextEncoderPolyfill;\n}\n\nexport function polyfillPromiseFinally(): void {\n  if (typeof Promise !== 'undefined' && !Promise.prototype.finally) {\n    Promise.prototype.finally = function (callback: () => void) {\n      const constructor = this.constructor as PromiseConstructor;\n      return this.then(\n        (value) => constructor.resolve(callback()).then(() => value),\n        (reason) =>\n          constructor.resolve(callback()).then(() => {\n            throw reason;\n          })\n      );\n    };\n  }\n}\n\nexport function polyfillObjectAssign(): void {\n  if (typeof Object.assign !== 'function') {\n    Object.assign = function (target: any, ...sources: any[]) {\n      if (target == null) {\n        throw new TypeError('Cannot convert undefined or null to object');\n      }\n\n      const to = Object(target);\n\n      for (let i = 0; i < sources.length; i++) {\n        const nextSource = sources[i];\n\n        if (nextSource != null) {\n          for (const nextKey in nextSource) {\n            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n              to[nextKey] = nextSource[nextKey];\n            }\n          }\n        }\n      }\n\n      return to;\n    };\n  }\n}\n\nexport function polyfillArrayFrom(): void {\n  if (!Array.from) {\n    Array.from = function (arrayLike: any, mapFn?: any, thisArg?: any) {\n      const items = Object(arrayLike);\n      if (arrayLike == null) {\n        throw new TypeError('Array.from requires an array-like object');\n      }\n\n      const len = items.length >>> 0;\n      const result = new Array(len);\n\n      for (let i = 0; i < len; i++) {\n        if (mapFn) {\n          result[i] = mapFn.call(thisArg, items[i], i);\n        } else {\n          result[i] = items[i];\n        }\n      }\n\n      return result;\n    };\n  }\n}\n\nexport function polyfillStringStartsWith(): void {\n  if (!String.prototype.startsWith) {\n    String.prototype.startsWith = function (search: string, pos?: number) {\n      pos = !pos || pos < 0 ? 0 : +pos;\n      return this.substring(pos, pos + search.length) === search;\n    };\n  }\n}\n\nexport function polyfillStringEndsWith(): void {\n  if (!String.prototype.endsWith) {\n    String.prototype.endsWith = function (search: string, length?: number) {\n      if (length === undefined || length > this.length) {\n        length = this.length;\n      }\n      return this.substring(length - search.length, length) === search;\n    };\n  }\n}\n\nexport function polyfillStringIncludes(): void {\n  if (!String.prototype.includes) {\n    String.prototype.includes = function (search: string, start?: number) {\n      if (typeof start !== 'number') {\n        start = 0;\n      }\n      if (start + search.length > this.length) {\n        return false;\n      }\n      return this.indexOf(search, start) !== -1;\n    };\n  }\n}\n\nexport function initializePolyfills(): void {\n  polyfillObjectAssign();\n  polyfillArrayFrom();\n  polyfillStringStartsWith();\n  polyfillStringEndsWith();\n  polyfillStringIncludes();\n  polyfillURLSearchParams();\n  polyfillTextEncoder();\n  polyfillPromiseFinally();\n}\n\n","import {\n  inferDeviceIdType,\n  isEquivalentDeviceIdType,\n} from \"./vastEnvironmentSignals\";\n\nexport interface VastConsentSignals {\n  gdpr?: string | undefined;\n  gdprConsent?: string | undefined;\n  usPrivacy?: string | undefined;\n}\n\nexport interface VastMacroContext {\n  correlator: string;\n  streamCorrelator: string;\n  pod?: number | undefined;\n  podMaxAds?: number | undefined;\n  podMinDurationMs?: number | undefined;\n  podMaxDurationMs?: number | undefined;\n  isCtv?: boolean | undefined;\n  contentUrl?: string | undefined;\n  pageUrl?: string | undefined;\n  adWillPlayMuted?: boolean | undefined;\n  adWillAutoPlay?: boolean | undefined;\n  appId?: string | undefined;\n  appName?: string | undefined;\n  sessionId?: string | undefined;\n  deviceId?: string | undefined;\n  deviceIdType?: string | undefined;\n  limitAdTracking?: boolean | undefined;\n  deviceTypeHint?: number | undefined;\n  adTest?: boolean | undefined;\n  consent?: VastConsentSignals | undefined;\n}\n\nconst UNEXPANDED_MACRO_PATTERN = /^(\\[[^\\]]*\\]|\\{[^}]*\\}|%%[^%]*%%)$/;\nconst INVALID_VAST_PARAM_KEY = /^\\s|\\s$/;\nconst EXAMPLE_COM_URL = /example\\.com/i;\nconst CTV_UNSUPPORTED_PARAMS = [\n  \"description_url\",\n  \"tfcd\",\n  \"npa\",\n  \"min_ad_duration\",\n  \"max_ad_duration\",\n  \"unviewed_position_start\",\n  \"impl\",\n  \"vad_type\",\n  \"gdpr\",\n  \"gdpr_consent\",\n  \"us_privacy\",\n];\n\nconst INLINE_DEVICE_MACRO_REPLACEMENTS: Array<{\n  pattern: RegExp;\n  getValue: (ctx: VastMacroContext) => string | undefined;\n}> = [\n  { pattern: /\\[RDID\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[IFA\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[ADVERTISING[_-]?ID(?:ENTIFIER)?\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[DEVICE[_-]?ID\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[IDTYPE\\]/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /\\{rdid\\}/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\{device[_-]?id\\}/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\{idtype\\}/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /%%ADVERTISING_IDENTIFIER_PLAIN%%/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /%%ADVERTISING_ID_OPT_OUT%%/gi, getValue: (ctx) =>\n      ctx.limitAdTracking != null ? (ctx.limitAdTracking ? \"1\" : \"0\") : undefined },\n  { pattern: /%%ADVERTISING_ID_TYPE%%/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /%%ADVERTISING_ID%%/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /%%LIMIT_AD_TRACKING%%/gi, getValue: (ctx) =>\n      ctx.limitAdTracking != null ? (ctx.limitAdTracking ? \"1\" : \"0\") : undefined },\n  { pattern: /%%MSID%%/gi, getValue: (ctx) => ctx.appId },\n  { pattern: /%%APP_NAME%%/gi, getValue: (ctx) => ctx.appName },\n  { pattern: /%%SESSION_ID%%/gi, getValue: (ctx) => ctx.sessionId },\n  { pattern: /%%CORRELATOR%%/gi, getValue: (ctx) => ctx.correlator },\n];\n\nexport function isMacroPlaceholder(value: string | null | undefined): boolean {\n  if (value == null) return true;\n  const trimmed = value.trim();\n  if (!trimmed) return true;\n  if (UNEXPANDED_MACRO_PATTERN.test(trimmed)) return true;\n  return /^(unknown|null|undefined|none|n\\/a|\\$\\{[^}]+\\})$/i.test(trimmed);\n}\n\nexport function generateCorrelator(): string {\n  if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n    try {\n      const buf = new Uint32Array(2);\n      crypto.getRandomValues(buf);\n      const value = (buf[0] ?? 0) * 0x200000 + ((buf[1] ?? 0) & 0x1fffff);\n      if (value > 0) {\n        return String(value);\n      }\n    } catch {\n    }\n  }\n  return String(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER) + 1);\n}\n\nfunction expandInlineMacroPlaceholders(baseUrl: string, ctx: VastMacroContext): string {\n  let url = baseUrl;\n  for (const { pattern, getValue } of INLINE_DEVICE_MACRO_REPLACEMENTS) {\n    const value = getValue(ctx);\n    if (value != null && value !== \"\") {\n      url = url.replace(pattern, encodeURIComponent(value));\n    }\n  }\n  return url;\n}\n\nfunction applyDeviceIdentityParams(\n  params: URLSearchParams,\n  ctx: VastMacroContext\n): void {\n  const runtimeId = ctx.deviceId?.trim();\n  const runtimeType = ctx.deviceIdType?.trim() || inferDeviceIdType();\n  const tagRdid = params.get(\"rdid\");\n  const tagType = params.get(\"idtype\");\n  const tagLat = params.get(\"is_lat\");\n  const latValue =\n    ctx.limitAdTracking != null ? (ctx.limitAdTracking ? \"1\" : \"0\") : undefined;\n\n  if (runtimeId) {\n    params.set(\"rdid\", runtimeId);\n    params.set(\"idtype\", runtimeType || tagType || \"aaid\");\n    params.set(\"is_lat\", latValue ?? (isMacroPlaceholder(tagLat) ? \"0\" : tagLat!));\n    return;\n  }\n\n  const tagRdidValid = Boolean(tagRdid && !isMacroPlaceholder(tagRdid));\n  const tagTypeValid = Boolean(tagType && !isMacroPlaceholder(tagType));\n\n  if (\n    tagRdidValid &&\n    tagTypeValid &&\n    runtimeType &&\n    !isEquivalentDeviceIdType(tagType!, runtimeType)\n  ) {\n    params.delete(\"rdid\");\n    params.delete(\"idtype\");\n    params.delete(\"is_lat\");\n    return;\n  }\n\n  if (tagRdidValid) {\n    if (isMacroPlaceholder(tagType) && runtimeType) {\n      params.set(\"idtype\", runtimeType);\n    }\n    if (isMacroPlaceholder(tagLat)) {\n      params.set(\"is_lat\", latValue ?? \"0\");\n    }\n    return;\n  }\n\n  params.delete(\"rdid\");\n  params.delete(\"idtype\");\n  params.delete(\"is_lat\");\n}\n\nfunction removeBrokenAppNameOrphans(\n  params: URLSearchParams,\n  appName?: string\n): void {\n  const toDelete: string[] = [];\n\n  params.forEach((_value, key) => {\n    if (!key || INVALID_VAST_PARAM_KEY.test(key)) {\n      toDelete.push(key);\n    }\n  });\n\n  if (appName && appName.includes(\"&\")) {\n    for (const suffix of appName.split(\"&\").slice(1)) {\n      const trimmed = suffix.trimStart();\n      if (!trimmed) continue;\n      toDelete.push(suffix, ` ${trimmed}`, trimmed);\n    }\n  }\n\n  for (const key of new Set(toDelete)) {\n    if (key) params.delete(key);\n  }\n}\n\nexport function normalizeVastTagUrl(raw: string): string {\n  if (!raw) return raw;\n\n  try {\n    const url = new URL(raw);\n\n    const anValue = url.searchParams.get(\"an\");\n    if (anValue !== null) {\n      const orphanFragments: string[] = [];\n      url.searchParams.forEach((_value, key) => {\n        if (key && INVALID_VAST_PARAM_KEY.test(key)) {\n          orphanFragments.push(key.trim());\n        }\n      });\n      if (orphanFragments.length > 0) {\n        const reconstructed = [anValue.trimEnd(), ...orphanFragments]\n          .filter(Boolean)\n          .join(\" & \");\n\n        url.searchParams.forEach((_value, key) => {\n          if (key && INVALID_VAST_PARAM_KEY.test(key)) {\n            url.searchParams.delete(key);\n          }\n        });\n        url.searchParams.set(\"an\", reconstructed);\n\n        return url.toString().replace(\n          /([?&]an=)([^&]*)/,\n          (_match, prefix, val) => prefix + val.replace(/\\+/g, \"%20\")\n        );\n      }\n    }\n\n    removeBrokenAppNameOrphans(url.searchParams);\n    return url.toString();\n  } catch {\n    return raw;\n  }\n}\n\nexport function applyVastMacros(\n  baseUrl: string,\n  ctx: VastMacroContext\n): string {\n  const expandedUrl = expandInlineMacroPlaceholders(baseUrl, ctx);\n  let url: URL;\n  try {\n    url = new URL(normalizeVastTagUrl(expandedUrl));\n  } catch {\n    return replaceCorrelatorFallback(expandedUrl, ctx.correlator);\n  }\n\n  const params = url.searchParams;\n\n  removeBrokenAppNameOrphans(params, ctx.appName);\n\n  params.set(\"correlator\", ctx.correlator);\n  params.set(\"scor\", ctx.streamCorrelator);\n  if (ctx.isCtv) {\n    for (const key of CTV_UNSUPPORTED_PARAMS) {\n      params.delete(key);\n    }\n  }\n\n  if (ctx.pod != null) {\n    params.set(\"pod\", String(ctx.pod));\n  }\n\n  params.delete(\"ppos\");\n  params.delete(\"lip\");\n  if (ctx.podMinDurationMs != null) {\n    params.set(\"pmnd\", String(Math.max(0, Math.round(ctx.podMinDurationMs))));\n  }\n  if (ctx.podMaxDurationMs != null) {\n    params.set(\"pmxd\", String(Math.max(0, Math.round(ctx.podMaxDurationMs))));\n  }\n  if (ctx.podMaxAds != null) {\n    params.set(\"pmad\", String(Math.max(1, Math.round(ctx.podMaxAds))));\n  }\n\n  const requestUrl = ctx.contentUrl || ctx.pageUrl;\n  if (requestUrl) {\n    params.set(\"url\", requestUrl);\n    if (!ctx.isCtv) {\n      params.set(\"description_url\", requestUrl);\n    }\n  } else {\n    const existingUrl = params.get(\"url\") || \"\";\n    if (EXAMPLE_COM_URL.test(existingUrl)) {\n      params.delete(\"url\");\n      params.delete(\"description_url\");\n    }\n  }\n\n  if (ctx.adWillPlayMuted != null) {\n    params.set(\"vpmute\", ctx.adWillPlayMuted ? \"1\" : \"0\");\n  }\n  if (ctx.adWillAutoPlay != null) {\n    params.set(\"vpa\", ctx.adWillAutoPlay ? \"auto\" : \"click\");\n  }\n\n  if (ctx.appId) {\n    params.set(\"msid\", ctx.appId);\n  }\n  if (ctx.appName) {\n    removeBrokenAppNameOrphans(params, ctx.appName);\n    params.set(\"an\", ctx.appName);\n  }\n  if (ctx.sessionId) {\n    params.set(\"sid\", ctx.sessionId);\n  }\n  if (ctx.deviceTypeHint != null) {\n    params.set(\"dth\", String(ctx.deviceTypeHint));\n  } else if (ctx.isCtv) {\n    params.set(\"dth\", \"5\");\n  }\n\n  applyDeviceIdentityParams(params, ctx);\n\n  if (!ctx.isCtv) {\n    const consent = ctx.consent;\n    if (consent?.gdpr != null) {\n      params.set(\"gdpr\", consent.gdpr);\n    }\n    if (consent?.gdprConsent != null) {\n      params.set(\"gdpr_consent\", consent.gdprConsent);\n    }\n    if (consent?.usPrivacy != null) {\n      params.set(\"us_privacy\", consent.usPrivacy);\n    }\n  }\n\n  if (ctx.adTest) {\n    params.set(\"adtest\", \"on\");\n  }\n\n  const staleKeys: string[] = [];\n  params.forEach((value, key) => {\n    if (isMacroPlaceholder(value)) {\n      staleKeys.push(key);\n    }\n  });\n  for (const key of staleKeys) {\n    params.delete(key);\n  }\n\n  removeBrokenAppNameOrphans(params, ctx.appName);\n\n  return url.toString();\n}\n\nfunction replaceCorrelatorFallback(baseUrl: string, correlator: string): string {\n  const correlatorRegex = /([?&])correlator=([^&]*)/;\n  if (correlatorRegex.test(baseUrl)) {\n    return baseUrl.replace(correlatorRegex, `$1correlator=${correlator}`);\n  }\n  const sep = baseUrl.includes(\"?\") ? \"&\" : \"?\";\n  return `${baseUrl}${sep}correlator=${correlator}`;\n}\n\nexport function fetchConsentSignals(\n  timeoutMs: number = 1500\n): Promise<VastConsentSignals> {\n  const signals: VastConsentSignals = {};\n  if (typeof window === \"undefined\") {\n    return Promise.resolve(signals);\n  }\n\n  const tasks: Promise<void>[] = [];\n\n  const tcfApi = (window as any).__tcfapi;\n  if (typeof tcfApi === \"function\") {\n    tasks.push(\n      new Promise<void>((resolve) => {\n        let settled = false;\n        try {\n          tcfApi(\"addEventListener\", 2, (tcData: any, success: boolean) => {\n            if (settled) return;\n            if (\n              success &&\n              tcData &&\n              (tcData.eventStatus === \"tcloaded\" ||\n                tcData.eventStatus === \"useractioncomplete\")\n            ) {\n              settled = true;\n              signals.gdpr = tcData.gdprApplies ? \"1\" : \"0\";\n              if (typeof tcData.tcString === \"string\" && tcData.tcString) {\n                signals.gdprConsent = tcData.tcString;\n              }\n              try {\n                tcfApi(\"removeEventListener\", 2, () => {}, tcData.listenerId);\n              } catch {}\n              resolve();\n            }\n          });\n        } catch {\n          resolve();\n        }\n        setTimeout(() => {\n          if (!settled) {\n            settled = true;\n            resolve();\n          }\n        }, timeoutMs);\n      })\n    );\n  }\n\n  const uspApi = (window as any).__uspapi;\n  if (typeof uspApi === \"function\") {\n    tasks.push(\n      new Promise<void>((resolve) => {\n        try {\n          uspApi(\"getUSPData\", 1, (data: any, success: boolean) => {\n            if (success && typeof data?.uspString === \"string\" && data.uspString) {\n              signals.usPrivacy = data.uspString;\n            }\n            resolve();\n          });\n        } catch {\n          resolve();\n        }\n        setTimeout(resolve, timeoutMs);\n      })\n    );\n  }\n\n  if (tasks.length === 0) {\n    return Promise.resolve(signals);\n  }\n\n  return Promise.all(tasks).then(() => signals);\n}\n","interface NavigatorUAData {\n  platform?: string;\n  brands?: Array<{ brand: string; version: string }>;\n  mobile?: boolean;\n}\n\ndeclare global {\n  interface Navigator {\n    userAgentData?: NavigatorUAData;\n  }\n}\n\nexport interface BrowserInfo {\n  name: string;\n  version: string;\n  majorVersion: number;\n  isSmartTV: boolean;\n  isLegacyTV: boolean;\n  platform: string;\n  supportsModernJS: boolean;\n  webOSVersion?: number | undefined;\n  tizenVersion?: number | undefined;\n  chromeVersion?: number | undefined;\n}\n\nfunction getChromeVersion(ua: string): number {\n  const match = ua.match(/Chrome\\/(\\d+)/);\n  return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getWebKitVersion(ua: string): number {\n  const match = ua.match(/AppleWebKit\\/(\\d+)/);\n  return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getPlatform(): string {\n  if ('userAgentData' in navigator && navigator.userAgentData?.platform) {\n    return navigator.userAgentData.platform;\n  }\n\n  const ua = navigator.userAgent;\n  if (/Mac|iPhone|iPad|iPod/i.test(ua)) {\n    return /iPhone|iPad|iPod/i.test(ua) ? 'iPhone' : 'MacIntel';\n  }\n  if (/Win/i.test(ua)) {\n    return 'Win32';\n  }\n  if (/Linux/i.test(ua)) {\n    return /Android/i.test(ua) ? 'Linux armv8l' : 'Linux x86_64';\n  }\n  if (/CrOS/i.test(ua)) {\n    return 'CrOS';\n  }\n\n  // eslint-disable-next-line deprecation/deprecation\n  return (navigator as any).platform || 'Unknown';\n}\n\nexport function detectBrowser(): BrowserInfo {\n  const ua = navigator.userAgent;\n  const platform = getPlatform();\n\n  let name = 'Unknown';\n  let version = '0';\n  let majorVersion = 0;\n  let isSmartTV = false;\n  let isLegacyTV = false;\n  let supportsModernJS = true;\n  let webOSVersion: number | undefined;\n  let tizenVersion: number | undefined;\n  let chromeVersionNum: number | undefined;\n\n  const chromeVersion = getChromeVersion(ua);\n  const webkitVersion = getWebKitVersion(ua);\n  chromeVersionNum = chromeVersion > 0 ? chromeVersion : undefined;\n\n  if (/Web0S|webOS|LG Browser|LGSTB/i.test(ua)) {\n    name = 'LG WebOS';\n    isSmartTV = true;\n\n    let match = ua.match(/Web0S[/\\s]*([\\d.]+)/i) || ua.match(/webOS[/\\s]*([\\d.]+)/i);\n\n    if (!match || !match[1]) {\n      match = ua.match(/webOSTV[/\\s-]*([\\d.]+)/i) || ua.match(/webOS\\.TV[/\\s-]*([\\d.]+)/i);\n    }\n\n    if (match && match[1]) {\n      version = match[1];\n      const parts = version.split('.');\n      majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n      webOSVersion = majorVersion;\n    } else if (chromeVersion > 0) {\n      if (chromeVersion >= 79) {\n        webOSVersion = 6;\n        version = '6.0';\n        majorVersion = 6;\n      } else if (chromeVersion >= 68) {\n        webOSVersion = 5;\n        version = '5.0';\n        majorVersion = 5;\n      } else if (chromeVersion >= 53) {\n        webOSVersion = 4;\n        version = '4.0';\n        majorVersion = 4;\n      } else if (chromeVersion >= 38) {\n        webOSVersion = 3;\n        version = '3.0';\n        majorVersion = 3;\n      } else {\n        webOSVersion = 2;\n        version = '2.0';\n        majorVersion = 2;\n      }\n    } else {\n      version = 'Unknown';\n      webOSVersion = undefined;\n    }\n\n    isLegacyTV = webOSVersion !== undefined && webOSVersion < 3;\n  } else if (/Tizen/i.test(ua)) {\n    name = 'Samsung Tizen';\n    isSmartTV = true;\n    const match = ua.match(/Tizen[/\\s]*([\\d.]+)/i);\n    version = match && match[1] ? match[1] : 'Unknown';\n    if (version !== 'Unknown') {\n      const parts = version.split('.');\n      majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n      tizenVersion = majorVersion;\n    }\n\n    isLegacyTV = tizenVersion !== undefined && tizenVersion < 3;\n  } else if (/SMART-TV|SmartTV/i.test(ua)) {\n    name = 'Smart TV';\n    isSmartTV = true;\n    isLegacyTV = chromeVersion > 0 && chromeVersion < 53;\n  } else if (/NetCast/i.test(ua)) {\n    name = 'LG NetCast';\n    isSmartTV = true;\n    isLegacyTV = true;\n  } else if (/BRAVIA/i.test(ua)) {\n    name = 'Sony BRAVIA';\n    isSmartTV = true;\n    isLegacyTV = chromeVersion > 0 && chromeVersion < 53;\n  } else {\n    if (chromeVersion > 0) {\n      name = 'Chrome';\n      version = chromeVersion.toString();\n      majorVersion = chromeVersion;\n\n      if (chromeVersion < 50) {\n        supportsModernJS = false;\n      }\n    }\n\n    if (webkitVersion > 0 && webkitVersion < 600) {\n      supportsModernJS = false;\n    }\n  }\n\n  if (typeof Promise === 'undefined' ||\n      typeof Map === 'undefined' ||\n      typeof Set === 'undefined') {\n    supportsModernJS = false;\n  }\n\n  if (typeof URLSearchParams === 'undefined') {\n    supportsModernJS = false;\n  }\n\n  return {\n    name,\n    version,\n    majorVersion,\n    isSmartTV,\n    isLegacyTV,\n    platform,\n    supportsModernJS,\n    webOSVersion,\n    tizenVersion,\n    chromeVersion: chromeVersionNum,\n  };\n}\n\nexport function getBrowserConfigOverrides(): {\n  allowNativeHls?: boolean;\n} {\n  const browser = detectBrowser();\n  const overrides: { allowNativeHls?: boolean } = {};\n\n  if (browser.isSmartTV) {\n    overrides.allowNativeHls = true;\n  }\n\n  return overrides;\n}\n\nexport function supportsModernJS(): boolean {\n  try {\n    return (\n      typeof Promise !== 'undefined' &&\n      typeof Map !== 'undefined' &&\n      typeof Set !== 'undefined' &&\n      typeof Array.from !== 'undefined' &&\n      typeof Object.assign !== 'undefined' &&\n      typeof Array.prototype.forEach !== 'undefined' &&\n      typeof String.prototype.includes !== 'undefined'\n    );\n  } catch (e) {\n    return false;\n  }\n}\n\nexport function logBrowserInfo(debug: boolean = false): void {\n  if (!debug) return;\n\n  const browser = detectBrowser();\n\n  console.log('[StormcloudVideoPlayer] Browser Compatibility Info:', {\n    browser: `${browser.name} ${browser.version}`,\n    platform: browser.platform,\n    isSmartTV: browser.isSmartTV,\n    isLegacyTV: browser.isLegacyTV,\n    supportsModernJS: browser.supportsModernJS,\n    ...(browser.webOSVersion !== undefined ? { webOSVersion: browser.webOSVersion } : {}),\n    ...(browser.tizenVersion !== undefined ? { tizenVersion: browser.tizenVersion } : {}),\n    ...(browser.chromeVersion !== undefined ? { chromeVersion: browser.chromeVersion } : {}),\n    userAgent: navigator.userAgent,\n  });\n}\n\nexport function supportsFeature(feature: string): boolean {\n  switch (feature) {\n    case 'urlsearchparams':\n      return typeof URLSearchParams !== 'undefined';\n    case 'textencoder':\n      return typeof TextEncoder !== 'undefined';\n    case 'promises':\n      return typeof Promise !== 'undefined';\n    case 'fetch':\n      return typeof fetch !== 'undefined';\n    case 'crypto':\n      return typeof crypto !== 'undefined' && typeof crypto.subtle !== 'undefined';\n    default:\n      return false;\n  }\n}\n","import type { Scte35Marker, Id3TagInfo } from \"../types\";\n\nexport function parseCueOutDuration(value: string): number | undefined {\n  const num = parseFloat(value.trim());\n  if (!Number.isNaN(num)) return num;\n  const match =\n    value.match(/(?:^|[,\\s])DURATION\\s*=\\s*([0-9.]+)/i) ||\n    value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n  if (match && match[1] != null) {\n    const dStr = match[1];\n    const d = parseFloat(dStr);\n    return Number.isNaN(d) ? undefined : d;\n  }\n  return undefined;\n}\n\nexport function parseCueOutCont(\n  value: string\n): { elapsed?: number; duration?: number } | undefined {\n  const res: { elapsed?: number; duration?: number } = {};\n\n  const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n  const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n  if (elapsedMatch && elapsedMatch[1] != null) {\n    const e = parseFloat(elapsedMatch[1]);\n    if (!Number.isNaN(e)) res.elapsed = e;\n  }\n  if (durationMatch && durationMatch[1] != null) {\n    const d = parseFloat(durationMatch[1]);\n    if (!Number.isNaN(d)) res.duration = d;\n  }\n\n  if (!(\"elapsed\" in res) || !(\"duration\" in res)) {\n    const slashMatch = value.match(/([0-9.]+)\\s*\\/\\s*([0-9.]+)/);\n    if (slashMatch && slashMatch[1] && slashMatch[2]) {\n      const elapsed = parseFloat(slashMatch[1]);\n      const duration = parseFloat(slashMatch[2]);\n      if (!Number.isNaN(elapsed) && !(\"elapsed\" in res)) res.elapsed = elapsed;\n      if (!Number.isNaN(duration) && !(\"duration\" in res)) res.duration = duration;\n    }\n  }\n\n  if (\"elapsed\" in res || \"duration\" in res) return res;\n  return undefined;\n}\n\nexport function parseAttributeList(value: string): Record<string, string> {\n  const attrs: Record<string, string> = {};\n  const regex = /([A-Z0-9-]+)=((\"[^\"]*\")|([^\",]*))(?:,|$)/gi;\n  let match: RegExpExecArray | null;\n  while ((match = regex.exec(value)) !== null) {\n    const key: string = (match[1] ?? \"\") as string;\n    let rawVal: string = (match[3] ?? match[4] ?? \"\") as string;\n    if (rawVal.startsWith('\"') && rawVal.endsWith('\"')) {\n      rawVal = rawVal.slice(1, -1);\n    }\n    if (key) {\n      attrs[key] = rawVal;\n    }\n  }\n  return attrs;\n}\n\nexport function toNumber(val: unknown): number | undefined {\n  if (val == null) return undefined;\n  const n = typeof val === \"string\" ? parseFloat(val) : Number(val);\n  return Number.isNaN(n) ? undefined : n;\n}\n\nexport function isManifestBasedMarker(marker: Scte35Marker): boolean {\n  const raw = marker.raw as any;\n  if (!raw) return false;\n\n  if (raw.tag) {\n    const tag = String(raw.tag);\n    return (\n      tag.includes(\"EXT-X-CUE-OUT\") ||\n      tag.includes(\"EXT-X-CUE-IN\") ||\n      tag.includes(\"EXT-X-DATERANGE\")\n    );\n  }\n\n  if (raw.id3) return false;\n\n  if (raw.splice_command_type) return false;\n\n  return false;\n}\n\nexport function decodeId3ValueToText(value: string | Uint8Array): string | undefined {\n  try {\n    if (typeof value === \"string\") return value;\n    const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n    const text = decoder.decode(value);\n    if (text && /[\\x20-\\x7E]/.test(text)) return text;\n    let out = \"\";\n    for (let i = 0; i < value.length; i++)\n      out += String.fromCharCode(value[i]!);\n    return out;\n  } catch {\n    return undefined;\n  }\n}\n\nexport function getFragmentStartSeconds(frag: any): number | undefined {\n  const candidates = [frag?.start, frag?.startPTS];\n  for (const candidate of candidates) {\n    if (typeof candidate === \"number\" && Number.isFinite(candidate)) {\n      return candidate;\n    }\n  }\n  return undefined;\n}\n\nexport function parseScte35FromId3(tag: Id3TagInfo): Scte35Marker | undefined {\n  const text = decodeId3ValueToText(tag.value);\n  if (!text) return undefined;\n\n  const cueOutMatch =\n    text.match(/EXT-X-CUE-OUT(?::([^\\r\\n]*))?/i) ||\n    text.match(/CUE-OUT(?::([^\\r\\n]*))?/i);\n  if (cueOutMatch) {\n    const arg = (cueOutMatch[1] ?? \"\").trim();\n    const dur = parseCueOutDuration(arg);\n    const marker: Scte35Marker = {\n      type: \"start\",\n      ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n      ...(dur !== undefined ? { durationSeconds: dur } : {}),\n      raw: { id3: text },\n    } as Scte35Marker;\n    return marker;\n  }\n\n  const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\\r\\n]*)/i);\n  if (cueOutContMatch) {\n    const arg = (cueOutContMatch[1] ?? \"\").trim();\n    const cont = parseCueOutCont(arg);\n    const marker: Scte35Marker = {\n      type: \"progress\",\n      ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n      ...(cont?.duration !== undefined\n        ? { durationSeconds: cont.duration }\n        : {}),\n      raw: { id3: text },\n    } as Scte35Marker;\n    return marker;\n  }\n\n  const cueInMatch = text.match(/EXT-X-CUE-IN\\b/i) || text.match(/CUE-IN\\b/i);\n  if (cueInMatch) {\n    const marker: Scte35Marker = {\n      type: \"end\",\n      ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n      raw: { id3: text },\n    } as Scte35Marker;\n    return marker;\n  }\n\n  const daterangeMatch = text.match(/EXT-X-DATERANGE:([^\\r\\n]*)/i);\n  if (daterangeMatch) {\n    const attrs = parseAttributeList(daterangeMatch[1] ?? \"\");\n    const hasScteOut =\n      \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== undefined;\n    const hasScteIn =\n      \"SCTE35-IN\" in attrs || attrs[\"SCTE35-IN\"] !== undefined;\n    const klass = String(attrs[\"CLASS\"] ?? \"\");\n    const duration = toNumber(attrs[\"DURATION\"]);\n    if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n      const marker: Scte35Marker = {\n        type: \"start\",\n        ...(tag.ptsSeconds !== undefined\n          ? { ptsSeconds: tag.ptsSeconds }\n          : {}),\n        ...(duration !== undefined ? { durationSeconds: duration } : {}),\n        raw: { id3: text, attrs },\n      } as Scte35Marker;\n      return marker;\n    }\n    if (hasScteIn) {\n      const marker: Scte35Marker = {\n        type: \"end\",\n        ...(tag.ptsSeconds !== undefined\n          ? { ptsSeconds: tag.ptsSeconds }\n          : {}),\n        raw: { id3: text, attrs },\n      } as Scte35Marker;\n      return marker;\n    }\n  }\n\n  if (/SCTE35-OUT/i.test(text)) {\n    const marker: Scte35Marker = {\n      type: \"start\",\n      ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n      raw: { id3: text },\n    } as Scte35Marker;\n    return marker;\n  }\n  if (/SCTE35-IN/i.test(text)) {\n    const marker: Scte35Marker = {\n      type: \"end\",\n      ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n      raw: { id3: text },\n    } as Scte35Marker;\n    return marker;\n  }\n\n  if (tag.value instanceof Uint8Array) {\n    const bin = parseScte35Binary(tag.value);\n    if (bin) return bin;\n  }\n\n  return undefined;\n}\n\nexport function normalizeFragmentPayload(payload: unknown): Uint8Array | undefined {\n  if (payload instanceof Uint8Array) {\n    return payload;\n  }\n  if (payload instanceof ArrayBuffer) {\n    return new Uint8Array(payload);\n  }\n  if (ArrayBuffer.isView(payload)) {\n    const view = payload as ArrayBufferView;\n    return new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n  }\n  return undefined;\n}\n\n// --- Transport Stream SCTE-35 parsing ---\n\nexport function detectTsPacketFormat(\n  data: Uint8Array\n): { offset: number; packetSize: number; tsPayloadOffset: number } | undefined {\n  const packetSizes = [188, 192, 204];\n  for (const packetSize of packetSizes) {\n    const tsPayloadOffset = packetSize === 192 ? 4 : 0;\n    for (let offset = 0; offset < packetSize; offset++) {\n      let matchedPackets = 0;\n      for (\n        let packetStart = offset;\n        packetStart + tsPayloadOffset < data.length &&\n        matchedPackets < 5;\n        packetStart += packetSize\n      ) {\n        if (data[packetStart + tsPayloadOffset] !== 0x47) {\n          break;\n        }\n        matchedPackets++;\n      }\n      if (matchedPackets >= 2) {\n        return { offset, packetSize, tsPayloadOffset };\n      }\n    }\n  }\n  return undefined;\n}\n\nfunction getPsiSectionStart(\n  payload: Uint8Array,\n  payloadUnitStart: boolean\n): number | undefined {\n  if (!payloadUnitStart) {\n    return undefined;\n  }\n  const pointerField = payload[0];\n  if (pointerField == null) {\n    return undefined;\n  }\n  const sectionStart = 1 + pointerField;\n  return sectionStart < payload.length ? sectionStart : undefined;\n}\n\nfunction getPsiSectionLength(data: Uint8Array, offset: number): number {\n  return (((data[offset + 1] ?? 0) & 0x0f) << 8) | (data[offset + 2] ?? 0);\n}\n\nfunction parsePatSection(\n  payload: Uint8Array,\n  payloadUnitStart: boolean,\n  pmtPids: Set<number>\n): void {\n  const sectionStart = getPsiSectionStart(payload, payloadUnitStart);\n  if (sectionStart == null || sectionStart + 8 >= payload.length) {\n    return;\n  }\n  if (payload[sectionStart] !== 0x00) {\n    return;\n  }\n\n  const sectionLength = getPsiSectionLength(payload, sectionStart);\n  const sectionEnd = Math.min(\n    payload.length,\n    sectionStart + 3 + sectionLength\n  );\n\n  for (let offset = sectionStart + 8; offset + 4 <= sectionEnd - 4; offset += 4) {\n    const programNumber =\n      ((payload[offset] ?? 0) << 8) | (payload[offset + 1] ?? 0);\n    const pid =\n      (((payload[offset + 2] ?? 0) & 0x1f) << 8) |\n      (payload[offset + 3] ?? 0);\n    if (programNumber !== 0) {\n      pmtPids.add(pid);\n    }\n  }\n}\n\nfunction descriptorsIdentifyScte35(\n  data: Uint8Array,\n  start: number,\n  end: number\n): boolean {\n  let offset = start;\n  while (offset + 2 <= end) {\n    const tag = data[offset] ?? 0;\n    const length = data[offset + 1] ?? 0;\n    const descriptorStart = offset + 2;\n    const descriptorEnd = descriptorStart + length;\n    if (descriptorEnd > end) {\n      return false;\n    }\n\n    const registration =\n      length >= 4\n        ? String.fromCharCode(\n            data[descriptorStart] ?? 0,\n            data[descriptorStart + 1] ?? 0,\n            data[descriptorStart + 2] ?? 0,\n            data[descriptorStart + 3] ?? 0\n          )\n        : \"\";\n    if (tag === 0x8a || registration === \"CUEI\" || registration === \"SCTE\") {\n      return true;\n    }\n\n    offset = descriptorEnd;\n  }\n  return false;\n}\n\nfunction parsePmtSection(\n  payload: Uint8Array,\n  payloadUnitStart: boolean,\n  tsScte35Pids: Set<number>\n): void {\n  const sectionStart = getPsiSectionStart(payload, payloadUnitStart);\n  if (sectionStart == null || sectionStart + 12 >= payload.length) {\n    return;\n  }\n  if (payload[sectionStart] !== 0x02) {\n    return;\n  }\n\n  const sectionLength = getPsiSectionLength(payload, sectionStart);\n  const sectionEnd = Math.min(\n    payload.length,\n    sectionStart + 3 + sectionLength\n  );\n  const programInfoLength =\n    (((payload[sectionStart + 10] ?? 0) & 0x0f) << 8) |\n    (payload[sectionStart + 11] ?? 0);\n\n  let offset = sectionStart + 12 + programInfoLength;\n  while (offset + 5 <= sectionEnd - 4) {\n    const streamType = payload[offset] ?? 0;\n    const elementaryPid =\n      (((payload[offset + 1] ?? 0) & 0x1f) << 8) |\n      (payload[offset + 2] ?? 0);\n    const esInfoLength =\n      (((payload[offset + 3] ?? 0) & 0x0f) << 8) |\n      (payload[offset + 4] ?? 0);\n    const descriptorStart = offset + 5;\n    const descriptorEnd = Math.min(descriptorStart + esInfoLength, sectionEnd - 4);\n\n    if (\n      streamType === 0x86 ||\n      (streamType === 0x06 &&\n        descriptorsIdentifyScte35(payload, descriptorStart, descriptorEnd))\n    ) {\n      tsScte35Pids.add(elementaryPid);\n    }\n\n    offset = descriptorStart + esInfoLength;\n  }\n}\n\nfunction hasProcessedTsScte35Section(\n  section: Uint8Array,\n  processedSections: Set<string>\n): boolean {\n  let checksum = 0;\n  for (let i = 0; i < section.length; i++) {\n    checksum = (checksum * 31 + (section[i] ?? 0)) >>> 0;\n  }\n\n  const key = `${section.length}:${checksum}`;\n  if (processedSections.has(key)) {\n    return true;\n  }\n\n  processedSections.add(key);\n  if (processedSections.size > 200) {\n    const firstKey = processedSections.values().next().value;\n    if (firstKey) {\n      processedSections.delete(firstKey);\n    }\n  }\n  return false;\n}\n\nfunction addScte35SectionMarker(\n  section: Uint8Array,\n  markers: Scte35Marker[],\n  processedSections: Set<string>\n): void {\n  if (section[0] !== 0xfc || hasProcessedTsScte35Section(section, processedSections)) {\n    return;\n  }\n\n  const marker = parseScte35Binary(section);\n  if (!marker) {\n    return;\n  }\n\n  marker.raw = {\n    ...(typeof marker.raw === \"object\" && marker.raw ? marker.raw : {}),\n    source: \"ts-packet\",\n  };\n  markers.push(marker);\n}\n\nfunction appendScte35Bytes(\n  pid: number,\n  bytes: Uint8Array,\n  assemblers: Map<number, { bytes: number[]; expectedLength: number }>,\n  markers: Scte35Marker[],\n  processedSections: Set<string>\n): void {\n  const assembler = assemblers.get(pid);\n  if (!assembler) {\n    return;\n  }\n\n  for (let i = 0; i < bytes.length && assembler.bytes.length < assembler.expectedLength; i++) {\n    assembler.bytes.push(bytes[i] ?? 0);\n  }\n\n  if (assembler.bytes.length >= assembler.expectedLength) {\n    assemblers.delete(pid);\n    addScte35SectionMarker(new Uint8Array(assembler.bytes), markers, processedSections);\n  }\n}\n\nfunction collectScte35SectionsFromPayload(\n  pid: number,\n  payload: Uint8Array,\n  payloadUnitStart: boolean,\n  assemblers: Map<number, { bytes: number[]; expectedLength: number }>,\n  markers: Scte35Marker[],\n  processedSections: Set<string>\n): void {\n  if (payload.length === 0) {\n    return;\n  }\n\n  let offset = 0;\n  if (payloadUnitStart) {\n    const pointerField = payload[0] ?? 0;\n    const previousAssembler = assemblers.get(pid);\n    if (previousAssembler && pointerField > 0) {\n      appendScte35Bytes(\n        pid,\n        payload.subarray(1, Math.min(1 + pointerField, payload.length)),\n        assemblers,\n        markers,\n        processedSections\n      );\n    }\n    assemblers.delete(pid);\n    offset = 1 + pointerField;\n  } else {\n    appendScte35Bytes(pid, payload, assemblers, markers, processedSections);\n    return;\n  }\n\n  while (offset + 3 <= payload.length) {\n    const tableId = payload[offset];\n    if (tableId == null || tableId === 0xff) {\n      return;\n    }\n\n    const sectionLength = getPsiSectionLength(payload, offset);\n    const totalLength = 3 + sectionLength;\n    if (sectionLength <= 0 || totalLength <= 3) {\n      return;\n    }\n\n    if (offset + totalLength <= payload.length) {\n      addScte35SectionMarker(\n        payload.subarray(offset, offset + totalLength),\n        markers,\n        processedSections\n      );\n      offset += totalLength;\n    } else {\n      assemblers.set(pid, {\n        bytes: Array.from(payload.subarray(offset)),\n        expectedLength: totalLength,\n      });\n      return;\n    }\n  }\n}\n\nexport function parseScte35FromTsPackets(\n  data: Uint8Array,\n  tsScte35Pids: Set<number>,\n  pmtPids: Set<number>,\n  processedSections: Set<string>\n): Scte35Marker[] {\n  const packetInfo = detectTsPacketFormat(data);\n  if (!packetInfo) {\n    return [];\n  }\n\n  const markers: Scte35Marker[] = [];\n  const sectionAssemblers = new Map<\n    number,\n    { bytes: number[]; expectedLength: number }\n  >();\n\n  for (\n    let packetStart = packetInfo.offset;\n    packetStart + packetInfo.packetSize <= data.length;\n    packetStart += packetInfo.packetSize\n  ) {\n    const tsStart = packetStart + packetInfo.tsPayloadOffset;\n    if (data[tsStart] !== 0x47) {\n      continue;\n    }\n\n    const secondByte = data[tsStart + 1];\n    const thirdByte = data[tsStart + 2];\n    const fourthByte = data[tsStart + 3];\n    if (\n      secondByte == null ||\n      thirdByte == null ||\n      fourthByte == null ||\n      (secondByte & 0x80) !== 0\n    ) {\n      continue;\n    }\n\n    const payloadUnitStart = (secondByte & 0x40) !== 0;\n    const pid = ((secondByte & 0x1f) << 8) | thirdByte;\n    const adaptationFieldControl = (fourthByte >> 4) & 0x03;\n    const hasPayload =\n      adaptationFieldControl === 1 || adaptationFieldControl === 3;\n    if (!hasPayload) {\n      continue;\n    }\n\n    let payloadStart = tsStart + 4;\n    if (adaptationFieldControl === 3) {\n      const adaptationLength = data[payloadStart];\n      if (adaptationLength == null) {\n        continue;\n      }\n      payloadStart += 1 + adaptationLength;\n    }\n\n    const payloadEnd = Math.min(tsStart + 188, data.length);\n    if (payloadStart >= payloadEnd || payloadStart >= data.length) {\n      continue;\n    }\n\n    const payload = data.subarray(payloadStart, payloadEnd);\n    if (pid === 0) {\n      parsePatSection(payload, payloadUnitStart, pmtPids);\n    } else if (pmtPids.has(pid)) {\n      parsePmtSection(payload, payloadUnitStart, tsScte35Pids);\n    } else if (tsScte35Pids.has(pid)) {\n      collectScte35SectionsFromPayload(\n        pid,\n        payload,\n        payloadUnitStart,\n        sectionAssemblers,\n        markers,\n        processedSections\n      );\n    }\n  }\n\n  return markers;\n}\n\n// --- Binary SCTE-35 parsing ---\n\nclass BitReader {\n  private bytePos = 0;\n  private bitPos = 0;\n  constructor(private readonly buf: Uint8Array) {}\n  readBits(numBits: number): number {\n    let result = 0;\n    while (numBits > 0) {\n      if (this.bytePos >= this.buf.length) return result;\n      const remainingInByte = 8 - this.bitPos;\n      const toRead = Math.min(numBits, remainingInByte);\n      const currentByte = this.buf[this.bytePos]!;\n      const shift = remainingInByte - toRead;\n      const mask = ((1 << toRead) - 1) & 0xff;\n      const bits = (currentByte >> shift) & mask;\n      result = (result << toRead) | bits;\n      this.bitPos += toRead;\n      if (this.bitPos >= 8) {\n        this.bitPos = 0;\n        this.bytePos += 1;\n      }\n      numBits -= toRead;\n    }\n    return result >>> 0;\n  }\n  skipBits(n: number): void {\n    this.readBits(n);\n  }\n  get bytePosition(): number {\n    return this.bitPos === 0 ? this.bytePos : this.bytePos + 1;\n  }\n}\n\nfunction readSpliceTime(\n  r: BitReader,\n  ptsAdjustmentTicks: number\n): number | undefined {\n  const timeSpecifiedFlag = r.readBits(1) === 1;\n  if (!timeSpecifiedFlag) {\n    r.readBits(7);\n    return undefined;\n  }\n  r.readBits(6);\n  const high = r.readBits(1);\n  const low = r.readBits(32);\n  const ptsTicks =\n    (high * 0x100000000 + low + ptsAdjustmentTicks) % 0x200000000;\n  return ptsTicks / 90000;\n}\n\nfunction markerTypeFromSegmentationTypeId(\n  segmentationTypeId: number\n): Scte35Marker[\"type\"] | undefined {\n  switch (segmentationTypeId) {\n    case 0x10:\n    case 0x22:\n    case 0x30:\n    case 0x32:\n    case 0x34:\n    case 0x36:\n      return \"start\";\n    case 0x11:\n    case 0x23:\n    case 0x31:\n    case 0x33:\n    case 0x35:\n    case 0x37:\n      return \"end\";\n    default:\n      return undefined;\n  }\n}\n\nfunction parseScte35SegmentationDescriptor(\n  descriptor: Uint8Array\n):\n  | {\n      type: Scte35Marker[\"type\"];\n      durationSeconds?: number;\n      segmentationEventId?: number;\n    }\n  | undefined {\n  if (descriptor.length < 11) {\n    return undefined;\n  }\n\n  const identifier = String.fromCharCode(\n    descriptor[0] ?? 0,\n    descriptor[1] ?? 0,\n    descriptor[2] ?? 0,\n    descriptor[3] ?? 0\n  );\n  if (identifier !== \"CUEI\") {\n    return undefined;\n  }\n\n  const segmentationEventId =\n    ((descriptor[4] ?? 0) * 0x1000000) +\n    ((descriptor[5] ?? 0) << 16) +\n    ((descriptor[6] ?? 0) << 8) +\n    (descriptor[7] ?? 0);\n  const cancelIndicator = ((descriptor[8] ?? 0) & 0x80) !== 0;\n  if (cancelIndicator) {\n    return undefined;\n  }\n\n  const flags = descriptor[9] ?? 0;\n  const programSegmentationFlag = (flags & 0x80) !== 0;\n  const segmentationDurationFlag = (flags & 0x40) !== 0;\n  let offset = 10;\n\n  if (!programSegmentationFlag) {\n    const componentCount = descriptor[offset] ?? 0;\n    offset += 1 + componentCount * 6;\n    if (offset > descriptor.length) {\n      return undefined;\n    }\n  }\n\n  let durationSeconds: number | undefined = undefined;\n  if (segmentationDurationFlag) {\n    if (offset + 5 > descriptor.length) {\n      return undefined;\n    }\n    const durationTicks =\n      ((descriptor[offset] ?? 0) * 0x100000000) +\n      ((descriptor[offset + 1] ?? 0) * 0x1000000) +\n      ((descriptor[offset + 2] ?? 0) << 16) +\n      ((descriptor[offset + 3] ?? 0) << 8) +\n      (descriptor[offset + 4] ?? 0);\n    durationSeconds = durationTicks / 90000;\n    offset += 5;\n  }\n\n  if (offset + 2 > descriptor.length) {\n    return undefined;\n  }\n  offset += 1;\n  const segmentationUpidLength = descriptor[offset] ?? 0;\n  offset += 1 + segmentationUpidLength;\n  if (offset >= descriptor.length) {\n    return undefined;\n  }\n\n  const segmentationTypeId = descriptor[offset] ?? 0;\n  const markerType = markerTypeFromSegmentationTypeId(segmentationTypeId);\n  if (!markerType) {\n    return undefined;\n  }\n\n  return {\n    type: markerType,\n    ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n    segmentationEventId,\n  };\n}\n\nfunction parseScte35SegmentationDescriptors(\n  data: Uint8Array,\n  offset: number\n):\n  | {\n      type: Scte35Marker[\"type\"];\n      durationSeconds?: number;\n      segmentationEventId?: number;\n    }\n  | undefined {\n  if (offset + 2 > data.length) {\n    return undefined;\n  }\n\n  const descriptorLoopLength =\n    ((data[offset] ?? 0) << 8) | (data[offset + 1] ?? 0);\n  let descriptorOffset = offset + 2;\n  const descriptorEnd = Math.min(\n    data.length,\n    descriptorOffset + descriptorLoopLength\n  );\n\n  while (descriptorOffset + 2 <= descriptorEnd) {\n    const descriptorTag = data[descriptorOffset] ?? 0;\n    const descriptorLength = data[descriptorOffset + 1] ?? 0;\n    const descriptorDataStart = descriptorOffset + 2;\n    const descriptorDataEnd = descriptorDataStart + descriptorLength;\n    if (descriptorDataEnd > descriptorEnd) {\n      return undefined;\n    }\n\n    if (descriptorTag === 0x02) {\n      const descriptorMarker = parseScte35SegmentationDescriptor(\n        data.subarray(descriptorDataStart, descriptorDataEnd)\n      );\n      if (descriptorMarker) {\n        return descriptorMarker;\n      }\n    }\n\n    descriptorOffset = descriptorDataEnd;\n  }\n\n  return undefined;\n}\n\nexport function parseScte35Binary(data: Uint8Array): Scte35Marker | undefined {\n  const r = new BitReader(data);\n  const tableId = r.readBits(8);\n  if (tableId !== 0xfc) return undefined;\n  r.readBits(1);\n  r.readBits(1);\n  r.readBits(2);\n  const sectionLength = r.readBits(12);\n  if (sectionLength <= 0 || data.length < 3 + sectionLength) {\n    return undefined;\n  }\n  r.readBits(8);\n  r.readBits(1);\n  r.readBits(6);\n  const ptsAdjHigh = r.readBits(1);\n  const ptsAdjLow = r.readBits(32);\n  const ptsAdjustmentTicks = ptsAdjHigh * 0x100000000 + ptsAdjLow;\n  r.readBits(8);\n  r.readBits(12);\n  const spliceCommandLength = r.readBits(12);\n  const spliceCommandType = r.readBits(8);\n\n  let markerType: Scte35Marker[\"type\"] | undefined;\n  let durationSeconds: number | undefined = undefined;\n  let ptsSeconds: number | undefined = undefined;\n  let spliceEventId: number | undefined = undefined;\n  const commandBodyStart = r.bytePosition;\n\n  if (spliceCommandType === 5) {\n    spliceEventId = r.readBits(32);\n    const cancel = r.readBits(1) === 1;\n    r.readBits(7);\n    if (cancel) return undefined;\n    const outOfNetwork = r.readBits(1) === 1;\n    const programSpliceFlag = r.readBits(1) === 1;\n    const durationFlag = r.readBits(1) === 1;\n    const spliceImmediateFlag = r.readBits(1) === 1;\n    r.readBits(4);\n    markerType = outOfNetwork ? \"start\" : \"end\";\n\n    if (programSpliceFlag && !spliceImmediateFlag) {\n      ptsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n    } else if (!programSpliceFlag) {\n      const componentCount = r.readBits(8);\n      for (let i = 0; i < componentCount; i++) {\n        r.readBits(8);\n        if (!spliceImmediateFlag) {\n          const componentPtsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n          if (ptsSeconds === undefined) {\n            ptsSeconds = componentPtsSeconds;\n          }\n        }\n      }\n    }\n\n    if (durationFlag) {\n      r.readBits(6);\n      r.readBits(1);\n      const high = r.readBits(1);\n      const low = r.readBits(32);\n      const durationTicks = high * 0x100000000 + low;\n      durationSeconds = durationTicks / 90000;\n    }\n    r.readBits(16);\n    r.readBits(8);\n    r.readBits(8);\n  } else if (spliceCommandType === 6) {\n    ptsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n  } else {\n    return undefined;\n  }\n\n  const expectedDescriptorOffset =\n    spliceCommandLength === 0x0fff\n      ? r.bytePosition\n      : commandBodyStart + spliceCommandLength;\n  const descriptorMarker = parseScte35SegmentationDescriptors(\n    data,\n    expectedDescriptorOffset\n  );\n\n  if (descriptorMarker) {\n    markerType = descriptorMarker.type;\n    if (durationSeconds === undefined) {\n      durationSeconds = descriptorMarker.durationSeconds;\n    }\n  }\n\n  if (!markerType) {\n    return undefined;\n  }\n\n  const marker: Scte35Marker = {\n    type: markerType,\n    ...(ptsSeconds !== undefined ? { ptsSeconds } : {}),\n    ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n    raw: {\n      splice_command_type: spliceCommandType,\n      ...(spliceEventId !== undefined ? { splice_event_id: spliceEventId } : {}),\n      ...(descriptorMarker?.segmentationEventId !== undefined\n        ? { segmentation_event_id: descriptorMarker.segmentationEventId }\n        : {}),\n    },\n  } as Scte35Marker;\n  return marker;\n}\n","import type { Scte35Marker } from \"../types\";\nimport type {\n  NormalizedScte35Cue,\n  Scte35CueContext,\n  Scte35CueSource,\n  Scte35CueReadiness,\n} from \"./playerTypes\";\nimport { getFragmentStartSeconds } from \"./Scte35Parser\";\n\nexport interface Scte35CueManagerCallbacks {\n  onEarlyStartCue(marker: Scte35Marker, fragmentSn: number | undefined, cueKey: string): void;\n  onPlaybackCue(marker: Scte35Marker, cueKey?: string): void;\n  isInAdBreak(): boolean;\n}\n\nexport class Scte35CueManager {\n  private readonly pendingScte35Cues: Map<string, NormalizedScte35Cue> = new Map();\n  private readonly recentScte35CueKeys: Map<string, number> = new Map();\n  private readonly recentScte35CueLimit: number = 200;\n  private pendingScte35CueKeyValue: string | undefined;\n  private activeScte35BreakKeyValue: string | undefined;\n  private scheduledScte35BreakKeyValue: string | undefined;\n\n  readonly tsScte35Pids: Set<number> = new Set();\n  readonly pmtPids: Set<number> = new Set();\n  readonly processedTsScte35Sections: Set<string> = new Set();\n\n  private debug: boolean;\n  private callbacks: Scte35CueManagerCallbacks;\n\n  constructor(debug: boolean, callbacks: Scte35CueManagerCallbacks) {\n    this.debug = debug;\n    this.callbacks = callbacks;\n  }\n\n  get pendingScte35CueKey(): string | undefined {\n    return this.pendingScte35CueKeyValue;\n  }\n  set pendingScte35CueKey(value: string | undefined) {\n    this.pendingScte35CueKeyValue = value;\n  }\n\n  get activeScte35BreakKey(): string | undefined {\n    return this.activeScte35BreakKeyValue;\n  }\n  set activeScte35BreakKey(value: string | undefined) {\n    this.activeScte35BreakKeyValue = value;\n  }\n\n  get scheduledScte35BreakKey(): string | undefined {\n    return this.scheduledScte35BreakKeyValue;\n  }\n  set scheduledScte35BreakKey(value: string | undefined) {\n    this.scheduledScte35BreakKeyValue = value;\n  }\n\n  createScte35CueContext(\n    source: Scte35CueSource,\n    readiness: Scte35CueReadiness,\n    frag?: any\n  ): Scte35CueContext {\n    const context: Scte35CueContext = { source, readiness };\n    if (typeof frag?.sn === \"number\") {\n      context.fragmentSn = frag.sn;\n    }\n    const fragmentStartSec = getFragmentStartSeconds(frag);\n    if (fragmentStartSec !== undefined) {\n      context.fragmentStartSeconds = fragmentStartSec;\n    }\n    return context;\n  }\n\n  onScte35Cue(marker: Scte35Marker, context: Scte35CueContext): void {\n    const cue = this.createScte35Cue(marker, context);\n    const pendingKey = this.getPendingScte35CueKey(cue);\n\n    if (context.readiness === \"early\") {\n      this.pendingScte35Cues.set(pendingKey, cue);\n      this.trimRecentScte35CueMaps();\n\n      if (marker.type === \"start\") {\n        this.callbacks.onEarlyStartCue(marker, context.fragmentSn, cue.key);\n      }\n      return;\n    }\n\n    if (marker.type === \"end\" && !this.shouldAcceptScte35EndCue(cue)) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ignoring SCTE-35 end cue\", {\n          key: cue.key,\n          activeScte35BreakKey: this.activeScte35BreakKeyValue,\n          inAdBreak: this.callbacks.isInAdBreak(),\n          source: cue.source,\n        });\n      }\n      return;\n    }\n\n    if (marker.type === \"start\" && this.hasRecentlyHandledScte35Cue(cue)) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ignoring duplicate SCTE-35 start cue\", {\n          key: cue.key,\n          source: cue.source,\n        });\n      }\n      return;\n    }\n\n    this.pendingScte35Cues.delete(pendingKey);\n    this.markScte35CueHandled(cue);\n    this.callbacks.onPlaybackCue(marker, cue.key);\n  }\n\n  activatePendingScte35CuesForFragment(frag: any): void {\n    const fragmentSn = typeof frag?.sn === \"number\" ? frag.sn : undefined;\n    if (fragmentSn === undefined) {\n      return;\n    }\n\n    const matchingCues = Array.from(this.pendingScte35Cues.entries()).filter(\n      ([, cue]) => cue.fragmentSn === fragmentSn\n    );\n\n    matchingCues.forEach(([pendingKey, cue]) => {\n      this.pendingScte35Cues.delete(pendingKey);\n      const context: Scte35CueContext = {\n        source: cue.source,\n        readiness: \"playback\",\n      };\n      context.fragmentSn = fragmentSn;\n      const fragmentStartSec =\n        cue.fragmentStartSeconds ?? getFragmentStartSeconds(frag);\n      if (fragmentStartSec !== undefined) {\n        context.fragmentStartSeconds = fragmentStartSec;\n      }\n      this.onScte35Cue(cue.marker, context);\n    });\n  }\n\n  private createScte35Cue(\n    marker: Scte35Marker,\n    context: Scte35CueContext\n  ): NormalizedScte35Cue {\n    const cue: NormalizedScte35Cue = {\n      marker,\n      source: context.source,\n      readiness: context.readiness,\n      key: this.getScte35CueKey(marker, context),\n    };\n    if (context.fragmentSn !== undefined) {\n      cue.fragmentSn = context.fragmentSn;\n    }\n    if (context.fragmentStartSeconds !== undefined) {\n      cue.fragmentStartSeconds = context.fragmentStartSeconds;\n    }\n    return cue;\n  }\n\n  private getScte35CueKey(\n    marker: Scte35Marker,\n    context: Scte35CueContext\n  ): string {\n    const raw = this.getScte35MarkerRaw(marker);\n    const spliceEventId = this.toIdentityString(raw?.splice_event_id);\n    if (spliceEventId) {\n      return `splice:${spliceEventId}`;\n    }\n\n    const segmentationEventId = this.toIdentityString(raw?.segmentation_event_id);\n    if (segmentationEventId) {\n      return `segmentation:${segmentationEventId}`;\n    }\n\n    const daterangeId = this.toIdentityString(raw?.attrs?.ID);\n    if (daterangeId) {\n      return `daterange:${daterangeId}`;\n    }\n\n    const scteValue =\n      this.toIdentityString(raw?.attrs?.[\"SCTE35-OUT\"]) ||\n      this.toIdentityString(raw?.attrs?.[\"SCTE35-IN\"]);\n    if (scteValue) {\n      return `daterange-scte:${scteValue}`;\n    }\n\n    if (typeof marker.ptsSeconds === \"number\" && Number.isFinite(marker.ptsSeconds)) {\n      return `pts:${Math.round(marker.ptsSeconds * 2) / 2}`;\n    }\n\n    if (context.fragmentSn !== undefined) {\n      return `fragment:${context.fragmentSn}`;\n    }\n\n    return `${context.source}:wallclock:${Math.floor(Date.now() / 1000)}`;\n  }\n\n  private getPendingScte35CueKey(cue: NormalizedScte35Cue): string {\n    return `${cue.marker.type}:${cue.key}:${\n      cue.fragmentSn !== undefined ? cue.fragmentSn : \"unknown\"\n    }`;\n  }\n\n  private getScte35MarkerRaw(marker: Scte35Marker): any {\n    return typeof marker.raw === \"object\" && marker.raw !== null\n      ? (marker.raw as any)\n      : {};\n  }\n\n  private toIdentityString(value: unknown): string | undefined {\n    if (typeof value === \"number\" && Number.isFinite(value)) {\n      return String(value);\n    }\n    if (typeof value === \"string\" && value.trim().length > 0) {\n      return value.trim();\n    }\n    return undefined;\n  }\n\n  isStrongScte35CueKey(key: string | undefined): boolean {\n    return !!(\n      key &&\n      (key.startsWith(\"splice:\") ||\n        key.startsWith(\"segmentation:\") ||\n        key.startsWith(\"daterange:\") ||\n        key.startsWith(\"daterange-scte:\"))\n    );\n  }\n\n  private hasRecentlyHandledScte35Cue(cue: NormalizedScte35Cue): boolean {\n    if (\n      this.activeScte35BreakKeyValue === cue.key ||\n      this.scheduledScte35BreakKeyValue === cue.key\n    ) {\n      return true;\n    }\n\n    const recentKey = `${cue.marker.type}:${cue.key}`;\n    return this.recentScte35CueKeys.has(recentKey);\n  }\n\n  private markScte35CueHandled(cue: NormalizedScte35Cue): void {\n    this.recentScte35CueKeys.set(`${cue.marker.type}:${cue.key}`, Date.now());\n    this.trimRecentScte35CueMaps();\n  }\n\n  private trimRecentScte35CueMaps(): void {\n    while (this.recentScte35CueKeys.size > this.recentScte35CueLimit) {\n      const firstKey = this.recentScte35CueKeys.keys().next().value;\n      if (!firstKey) {\n        break;\n      }\n      this.recentScte35CueKeys.delete(firstKey);\n    }\n\n    while (this.pendingScte35Cues.size > this.recentScte35CueLimit) {\n      const firstKey = this.pendingScte35Cues.keys().next().value;\n      if (!firstKey) {\n        break;\n      }\n      this.pendingScte35Cues.delete(firstKey);\n    }\n  }\n\n  private shouldAcceptScte35EndCue(cue: NormalizedScte35Cue): boolean {\n    if (!this.callbacks.isInAdBreak()) {\n      return false;\n    }\n\n    if (\n      this.isStrongScte35CueKey(this.activeScte35BreakKeyValue) &&\n      this.isStrongScte35CueKey(cue.key) &&\n      this.activeScte35BreakKeyValue !== cue.key\n    ) {\n      return false;\n    }\n\n    return true;\n  }\n}\n","import type {\n  StormcloudVideoPlayerConfig,\n  AdBreak,\n  StormcloudApiResponse,\n  AdController,\n} from \"../types\";\nimport type { PalNonceManager } from \"../sdk/pal\";\nimport { applyVastMacros, generateCorrelator, normalizeVastTagUrl } from \"../utils/vastMacros\";\nimport type { VastConsentSignals } from \"../utils/vastMacros\";\nimport { resolveVastEnvironmentSignals } from \"../utils/vastEnvironmentSignals\";\nimport {\n  buildAnalyticsContext,\n  sendHeartbeat,\n  sendInitialTracking,\n} from \"../utils/tracking\";\n\nexport class AdConfigManager {\n  vmapBreaks: AdBreak[] = [];\n  consumedVmapBreakIds: Set<string> = new Set();\n  apiVastTagUrl: string | undefined;\n  apiNumberAds: number | undefined;\n  readonly streamCorrelator: string = generateCorrelator();\n  readonly viewCorrelator: string = generateCorrelator();\n  consentSignals: VastConsentSignals = {};\n  podCounter: number = 0;\n  podAssignedByPrefetch: boolean = false;\n\n  private lastHeartbeatTime: number = 0;\n  private heartbeatInterval: number | undefined;\n\n  private config: StormcloudVideoPlayerConfig;\n  private video: HTMLVideoElement;\n\n  constructor(config: StormcloudVideoPlayerConfig, video: HTMLVideoElement) {\n    this.config = config;\n    this.video = video;\n  }\n\n  get debug(): boolean {\n    return !!this.config.debugAdTiming;\n  }\n\n  isVmapEnabled(): boolean {\n    return !!(this.config.isVmap && this.config.vmapUrl?.trim());\n  }\n\n  async fetchAdConfiguration(): Promise<void> {\n    if (this.isVmapEnabled()) {\n      await this.fetchAndParseVmap(this.config.vmapUrl!);\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] VMAP mode enabled\");\n      }\n      return;\n    }\n\n    const vastMode = this.config.vastMode || \"default\";\n\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] VAST mode:\", vastMode);\n    }\n\n    if (vastMode === \"adstorm\") {\n      if (!this.config.licenseKey) {\n        if (this.debug) {\n          console.warn(\n            \"[StormcloudVideoPlayer] AdStorm mode requires a license key\"\n          );\n        }\n        return;\n      }\n\n      const vastEndpoint = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${this.config.licenseKey}`;\n      this.apiVastTagUrl = vastEndpoint;\n\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):\",\n          vastEndpoint\n        );\n      }\n      return;\n    }\n\n    if (this.config.vastTagUrl) {\n      this.apiVastTagUrl = normalizeVastTagUrl(this.config.vastTagUrl);\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Using custom VAST tag URL:\",\n          this.apiVastTagUrl\n        );\n      }\n      return;\n    }\n\n    const apiUrl = \"https://adstorm.co/api-adstorm-dev/adstorm/ads/web\";\n\n    if (this.debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] Fetching ad configuration from:\",\n        apiUrl\n      );\n    }\n\n    const headers: Record<string, string> = {};\n    if (this.config.licenseKey) {\n      headers[\"Authorization\"] = `Bearer ${this.config.licenseKey}`;\n    }\n\n    const response = await fetch(apiUrl, { headers });\n    if (!response.ok) {\n      if (this.debug) {\n        console.warn(\n          `[StormcloudVideoPlayer] Failed to fetch ad configuration: ${response.status}`\n        );\n      }\n      return;\n    }\n\n    const data: StormcloudApiResponse = await response.json();\n\n    const imaPayload = data.response?.ima?.[\"publisherdesk.ima\"]?.payload;\n    if (imaPayload) {\n      let decodedPayload = imaPayload;\n      try {\n        decodedPayload = decodeURIComponent(imaPayload);\n      } catch {\n        console.warn(\"[StormcloudVideoPlayer] imaPayload was not URI-encoded; using as-is:\", imaPayload);\n      }\n      console.log(\"[StormcloudVideoPlayer] Raw VAST tag URL (from API):\", decodedPayload);\n      this.apiVastTagUrl = normalizeVastTagUrl(decodedPayload);\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Normalized VAST tag URL:\",\n          this.apiVastTagUrl\n        );\n      }\n    } else {\n      if (this.debug) {\n        console.warn(\n          \"[StormcloudVideoPlayer] No VAST tag URL found in /ads/web response\"\n        );\n      }\n    }\n\n    const numberAds = data.response?.options?.vast?.cue_tones?.number_ads;\n    if (numberAds != null && numberAds > 0) {\n      this.apiNumberAds = numberAds;\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Number of ads per break from API:\",\n          this.apiNumberAds\n        );\n      }\n    }\n  }\n\n  private async fetchAndParseVmap(vmapUrl: string): Promise<void> {\n    if (!vmapUrl.trim()) {\n      return;\n    }\n\n    try {\n      const response = await fetch(vmapUrl);\n      if (!response.ok) {\n        throw new Error(`Failed to fetch VMAP (${response.status})`);\n      }\n\n      const vmapXml = await response.text();\n      this.vmapBreaks = this.parseVmapToBreaks(vmapXml);\n      this.consumedVmapBreakIds.clear();\n\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] Loaded ${this.vmapBreaks.length} VMAP ad break(s) from:`,\n          vmapUrl\n        );\n      }\n    } catch (error) {\n      this.vmapBreaks = [];\n      this.consumedVmapBreakIds.clear();\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Failed to load VMAP:\", error);\n      }\n    }\n  }\n\n  private parseVmapToBreaks(vmapXml: string): AdBreak[] {\n    if (typeof DOMParser === \"undefined\") {\n      return [];\n    }\n\n    const doc = new DOMParser().parseFromString(vmapXml, \"application/xml\");\n    if (doc.querySelector(\"parsererror\")) {\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Invalid VMAP XML received\");\n      }\n      return [];\n    }\n\n    const VMAP_NS = \"http://www.iab.net/videosuite/vmap\";\n    let adBreakNodes = Array.from(doc.getElementsByTagNameNS(VMAP_NS, \"AdBreak\"));\n    if (adBreakNodes.length === 0) {\n      adBreakNodes = Array.from(\n        doc.querySelectorAll(\"AdBreak, vmap\\\\:AdBreak\")\n      );\n    }\n    if (adBreakNodes.length === 0) {\n      adBreakNodes = Array.from(doc.getElementsByTagName(\"*\")).filter(\n        (el) => el.localName === \"AdBreak\"\n      );\n    }\n    const parsed: AdBreak[] = [];\n\n    adBreakNodes.forEach((node, index) => {\n      const timeOffsetRaw = (node.getAttribute(\"timeOffset\") || \"\").trim();\n      const startTimeMs = this.parseVmapTimeOffsetToMs(timeOffsetRaw);\n      if (startTimeMs == null) {\n        return;\n      }\n\n      let adTagNode = node.getElementsByTagNameNS(VMAP_NS, \"AdTagURI\")[0];\n      if (!adTagNode) {\n        adTagNode =\n          (node.querySelector(\"AdTagURI, vmap\\\\:AdTagURI\") as Element | null) ??\n          undefined;\n      }\n      const adTagUrl = (adTagNode?.textContent || \"\").trim();\n      if (!adTagUrl) {\n        return;\n      }\n\n      const breakId =\n        node.getAttribute(\"breakId\") ||\n        `vmap-break-${index}-${timeOffsetRaw || \"unknown\"}`;\n      parsed.push({\n        id: breakId,\n        startTimeMs,\n        vastTagUrl: adTagUrl,\n      });\n    });\n\n    parsed.sort((a, b) => {\n      const aStart = a.startTimeMs < 0 ? Number.MAX_SAFE_INTEGER : a.startTimeMs;\n      const bStart = b.startTimeMs < 0 ? Number.MAX_SAFE_INTEGER : b.startTimeMs;\n      return aStart - bStart;\n    });\n\n    return parsed;\n  }\n\n  private parseVmapTimeOffsetToMs(timeOffset: string): number | undefined {\n    if (!timeOffset) {\n      return undefined;\n    }\n\n    const normalized = timeOffset.trim().toLowerCase();\n    if (normalized === \"start\") {\n      return 0;\n    }\n\n    if (normalized === \"end\") {\n      return -1;\n    }\n\n    const hms = timeOffset.match(\n      /^(\\d{1,2}):(\\d{2}):(\\d{2})(?:\\.(\\d{1,3}))?$/\n    );\n    if (hms) {\n      const [, hh, mm, ss, ms = \"0\"] = hms;\n      const hours = Number(hh);\n      const minutes = Number(mm);\n      const seconds = Number(ss);\n      const millis = Number(ms.padEnd(3, \"0\").slice(0, 3));\n      return ((hours * 3600 + minutes * 60 + seconds) * 1000) + millis;\n    }\n\n    const percent = timeOffset.match(/^(\\d+(?:\\.\\d+)?)%$/);\n    if (percent) {\n      const ratio = Number(percent[1]) / 100;\n      const durationSec = this.video.duration;\n      if (Number.isFinite(durationSec) && durationSec > 0) {\n        return Math.floor(durationSec * 1000 * ratio);\n      }\n      return undefined;\n    }\n\n    return undefined;\n  }\n\n  getAdBreakKey(adBreak: AdBreak): string {\n    if (adBreak.id) {\n      return adBreak.id;\n    }\n    return `${adBreak.startTimeMs}-${adBreak.vastTagUrl || \"\"}`;\n  }\n\n  resolveBreakStartMs(adBreak: AdBreak): number | undefined {\n    if (adBreak.startTimeMs >= 0) {\n      return adBreak.startTimeMs;\n    }\n\n    if (adBreak.startTimeMs === -1) {\n      const durationSec = this.video.duration;\n      if (Number.isFinite(durationSec) && durationSec > 0) {\n        return Math.floor(durationSec * 1000);\n      }\n    }\n\n    return undefined;\n  }\n\n  findCurrentOrNextBreak(nowMs: number): AdBreak | undefined {\n    const schedule: AdBreak[] = this.vmapBreaks;\n    let candidate: AdBreak | undefined;\n    const tol = this.config.driftToleranceMs ?? 1000;\n    for (const b of schedule) {\n      if (this.consumedVmapBreakIds.has(this.getAdBreakKey(b))) {\n        continue;\n      }\n      const breakStartMs = this.resolveBreakStartMs(b);\n      if (breakStartMs == null) {\n        continue;\n      }\n      if (\n        breakStartMs <= nowMs + tol &&\n        (candidate == null ||\n          breakStartMs > (this.resolveBreakStartMs(candidate) ?? 0))\n      ) {\n        candidate = b;\n      }\n    }\n    return candidate;\n  }\n\n  findBreakForTime(nowMs: number): AdBreak | undefined {\n    const schedule: AdBreak[] = this.vmapBreaks;\n    for (const b of schedule) {\n      if (this.consumedVmapBreakIds.has(this.getAdBreakKey(b))) {\n        continue;\n      }\n      const breakStartMs = this.resolveBreakStartMs(b);\n      if (breakStartMs == null) {\n        continue;\n      }\n\n      if (b.durationMs) {\n        const end = breakStartMs + b.durationMs;\n        if (nowMs >= breakStartMs && nowMs < end) {\n          return b;\n        }\n        continue;\n      }\n\n      if (nowMs >= breakStartMs) {\n        return b;\n      }\n    }\n    return undefined;\n  }\n\n  selectVastTagsForBreak(b?: AdBreak): string[] | undefined {\n    if (!b || !b.vastTagUrl) return undefined;\n    if (b.vastTagUrl.includes(\",\")) {\n      return b.vastTagUrl\n        .split(\",\")\n        .map((s) => s.trim())\n        .filter((s) => s.length > 0);\n    }\n    return [b.vastTagUrl];\n  }\n\n  beginNewAdPod(): void {\n    this.podCounter++;\n  }\n\n  private readonly defaultPodMaxAds: number = 6;\n  private readonly defaultPodMaxDurationMs: number = 120000;\n\n  resolvePodParams(breakDurationMs?: number): {\n    maxAds: number;\n    minDurationMs: number;\n    maxDurationMs: number;\n  } {\n    const maxDurationMs =\n      breakDurationMs != null && breakDurationMs > 0\n        ? breakDurationMs\n        : this.config.podMaxDurationMs != null && this.config.podMaxDurationMs > 0\n          ? this.config.podMaxDurationMs\n          : this.defaultPodMaxDurationMs;\n\n    const maxAds =\n      this.config.podMaxAds && this.config.podMaxAds > 0\n        ? this.config.podMaxAds\n        : this.apiNumberAds && this.apiNumberAds > 0\n          ? this.apiNumberAds\n          : this.defaultPodMaxAds;\n\n    const minDurationMs =\n      this.config.podExactDuration && maxDurationMs != null ? maxDurationMs : 0;\n\n    return { maxAds, minDurationMs, maxDurationMs };\n  }\n\n  generatePodVastUrl(\n    baseUrl: string,\n    podParams: { maxAds: number; minDurationMs: number; maxDurationMs: number },\n    adPlayer: AdController,\n    palNonce: PalNonceManager,\n    inAdBreak: boolean\n  ): string {\n    const adWillPlayMuted = inAdBreak\n      ? adPlayer.getOriginalMutedState()\n      : this.video.muted;\n    const envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);\n\n    const urlWithMacros = applyVastMacros(baseUrl, {\n      correlator: this.viewCorrelator,\n      streamCorrelator: this.streamCorrelator,\n      pod: this.podCounter > 0 ? this.podCounter : undefined,\n      podMaxAds: podParams.maxAds,\n      podMinDurationMs: podParams.minDurationMs,\n      podMaxDurationMs: podParams.maxDurationMs,\n      isCtv: envSignals.isCtv,\n      contentUrl: envSignals.contentUrl,\n      pageUrl:\n        !envSignals.isCtv && typeof window !== \"undefined\"\n          ? window.location.href\n          : undefined,\n      adWillPlayMuted,\n      adWillAutoPlay: !!this.config.autoplay,\n      appId: envSignals.appId,\n      appName: envSignals.appName,\n      sessionId: envSignals.sessionId,\n      deviceId: envSignals.deviceId,\n      deviceIdType: envSignals.deviceIdType,\n      limitAdTracking: envSignals.limitAdTracking,\n      deviceTypeHint: envSignals.deviceTypeHint,\n      adTest: this.config.adTest,\n      consent: this.consentSignals,\n    });\n\n    const finalUrl = palNonce.injectNonce(urlWithMacros);\n    console.log(\n      `[StormcloudVideoPlayer] Resolved optimized-pod request URL (pod=${this.podCounter}, pmad=${podParams.maxAds}, pmnd=${podParams.minDurationMs}, pmxd=${podParams.maxDurationMs ?? \"?\"}):`,\n      finalUrl\n    );\n    return finalUrl;\n  }\n\n  // --- Tracking ---\n\n  initializeTracking(): void {\n    sendInitialTracking(this.config.licenseKey, buildAnalyticsContext(this.config))\n      .then(() => {\n        this.heartbeatInterval = window.setInterval(() => {\n          this.sendHeartbeatIfNeeded();\n        }, 5000);\n      })\n      .catch((error) => {\n        if (this.debug) {\n          console.warn(\n            \"[StormcloudVideoPlayer] Failed to send initial tracking:\",\n            error\n          );\n        }\n        this.heartbeatInterval = window.setInterval(() => {\n          this.sendHeartbeatIfNeeded();\n        }, 5000);\n      });\n  }\n\n  private sendHeartbeatIfNeeded(): void {\n    const now = Date.now();\n    if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 30000) {\n      this.lastHeartbeatTime = now;\n      sendHeartbeat(this.config.licenseKey, buildAnalyticsContext(this.config)).catch((error) => {\n        if (this.debug) {\n          console.warn(\n            \"[StormcloudVideoPlayer] Failed to send heartbeat:\",\n            error\n          );\n        }\n      });\n    }\n  }\n\n  destroyTracking(): void {\n    if (this.heartbeatInterval) {\n      clearInterval(this.heartbeatInterval);\n      this.heartbeatInterval = undefined;\n    }\n  }\n}\n","import type { AdController, StormcloudVideoPlayerConfig, Scte35Marker } from \"../types\";\n\nexport interface AdTimingCallbacks {\n  onAdStopTimerFired(): void;\n  onAdStartTimerFired(marker: Scte35Marker, cueKey: string | undefined): void;\n  onWatchdogTimeout(): void;\n  onFailsafeTimeout(): void;\n}\n\nexport class AdTimingService {\n  private adStopTimerId: number | undefined;\n  private adStartTimerId: number | undefined;\n  private adFailsafeTimerId: number | undefined;\n  private adRequestWatchdogId: number | undefined;\n  private adRequestWatchdogToken: number | null = null;\n  private adFailsafeToken: number | null = null;\n\n  ptsDriftEmaMs = 0;\n  expectedAdBreakDurationMs: number | undefined;\n  currentAdBreakStartWallClockMs: number | undefined;\n  scteAdBreakEndWallClockMs: number | undefined;\n  adBreakPlayedDurationMs: number = 0;\n  adBreakEpoch: number = 0;\n\n  adRequestTokenCounter = 0;\n  activeAdRequestToken: number | null = null;\n  currentAdIndex: number = 0;\n  totalAdsInBreak: number = 0;\n  totalAdRequestsInBreak: number = 0;\n  readonly maxTotalAdRequestsPerBreak: number = 10;\n  lastAdRequestTime: number = 0;\n  consecutiveFailures: number = 0;\n  readonly maxConsecutiveFailures: number = 5;\n  readonly minAdRequestIntervalMs: number = 3000;\n  readonly backoffBaseMs: number = 1000;\n  readonly maxBackoffMs: number = 15000;\n  private readonly defaultMinRemainingMsToStartAd: number = 4000;\n\n  failedVastUrls: Set<string> = new Set();\n  temporaryFailureUrls: Map<string, number> = new Map();\n  private readonly temporaryFailureCooldownMs: number = 30000;\n\n  private globalConsecutiveNoFills: number = 0;\n  private readonly globalNoFillThreshold: number = 3;\n  private globalNoFillCooldownUntil: number = 0;\n  private readonly globalNoFillBackoffBaseMs: number = 5000;\n  private readonly globalNoFillBackoffMaxMs: number = 60000;\n  private globalLastGamRequestTime: number = 0;\n  private readonly globalMinGamIntervalMs: number = 3000;\n\n  private config: StormcloudVideoPlayerConfig;\n  private video: HTMLVideoElement;\n  private callbacks: AdTimingCallbacks;\n\n  constructor(\n    config: StormcloudVideoPlayerConfig,\n    video: HTMLVideoElement,\n    callbacks: AdTimingCallbacks\n  ) {\n    this.config = config;\n    this.video = video;\n    this.callbacks = callbacks;\n  }\n\n  get debug(): boolean {\n    return !!this.config.debugAdTiming;\n  }\n\n  // --- Ad stop timer ---\n\n  scheduleAdStopCountdown(remainingMs: number): void {\n    this.clearAdStopTimer();\n    const ms = Math.max(0, Math.floor(remainingMs));\n    if (ms === 0) {\n      this.ensureAdStoppedByTimer();\n      return;\n    }\n    this.adStopTimerId = window.setTimeout(() => {\n      this.ensureAdStoppedByTimer();\n    }, ms) as unknown as number;\n  }\n\n  clearAdStopTimer(): void {\n    if (this.adStopTimerId != null) {\n      clearTimeout(this.adStopTimerId);\n      this.adStopTimerId = undefined;\n    }\n  }\n\n  private ensureAdStoppedByTimer(): void {\n    this.adStopTimerId = undefined;\n    this.callbacks.onAdStopTimerFired();\n  }\n\n  // --- Ad start timer ---\n\n  scheduleAdStartIn(\n    delayMs: number,\n    marker: Scte35Marker = { type: \"start\" } as Scte35Marker,\n    cueKey?: string\n  ): void {\n    this.clearAdStartTimer();\n    const ms = Math.max(0, Math.floor(delayMs));\n    if (ms === 0) {\n      this.callbacks.onAdStartTimerFired(marker, cueKey);\n      return;\n    }\n    this.adStartTimerId = window.setTimeout(() => {\n      this.callbacks.onAdStartTimerFired(marker, cueKey);\n    }, ms) as unknown as number;\n  }\n\n  clearAdStartTimer(): void {\n    if (this.adStartTimerId != null) {\n      clearTimeout(this.adStartTimerId);\n      this.adStartTimerId = undefined;\n    }\n  }\n\n  // --- PTS drift ---\n\n  updatePtsDrift(ptsSecondsSample: number): void {\n    const sampleMs = (this.video.currentTime - ptsSecondsSample) * 1000;\n    if (!Number.isFinite(sampleMs) || Math.abs(sampleMs) > 60000) return;\n    const alpha = 0.1;\n    this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;\n  }\n\n  resolveScteBreakStartWallClockMs(marker: Scte35Marker): number {\n    const nowWallClockMs = Date.now();\n    if (typeof marker.ptsSeconds !== \"number\") {\n      return nowWallClockMs;\n    }\n\n    const nowMs = this.video.currentTime * 1000;\n    const estimatedCurrentPtsMs = nowMs - this.ptsDriftEmaMs;\n    const deltaMs = marker.ptsSeconds * 1000 - estimatedCurrentPtsMs;\n    if (!Number.isFinite(deltaMs)) {\n      return nowWallClockMs;\n    }\n\n    return nowWallClockMs + Math.floor(deltaMs);\n  }\n\n  // --- Duration boundary ---\n\n  setAdBreakDurationBoundary(durationMs: number | undefined): void {\n    this.expectedAdBreakDurationMs = durationMs;\n    if (\n      durationMs != null &&\n      this.currentAdBreakStartWallClockMs != null\n    ) {\n      this.scteAdBreakEndWallClockMs =\n        this.currentAdBreakStartWallClockMs + durationMs;\n    } else {\n      this.scteAdBreakEndWallClockMs = undefined;\n    }\n  }\n\n  scheduleAdStopAtBreakBoundary(): void {\n    if (this.expectedAdBreakDurationMs == null) {\n      return;\n    }\n    this.scheduleAdStopCountdown(this.getWallClockRemainingAdMs());\n  }\n\n  // --- Duration budget ---\n\n  getWallClockRemainingAdMs(): number {\n    const endWallClockMs = this.getAdBreakEndWallClockMs();\n    if (endWallClockMs != null) {\n      return Math.max(0, endWallClockMs - Date.now());\n    }\n    return 0;\n  }\n\n  getAdBreakEndWallClockMs(): number | undefined {\n    if (this.scteAdBreakEndWallClockMs != null) {\n      return this.scteAdBreakEndWallClockMs;\n    }\n    if (\n      this.expectedAdBreakDurationMs == null ||\n      this.currentAdBreakStartWallClockMs == null\n    ) {\n      return undefined;\n    }\n    return this.currentAdBreakStartWallClockMs + this.expectedAdBreakDurationMs;\n  }\n\n  getDurationBudgetRemainingMs(): number {\n    if (this.expectedAdBreakDurationMs == null) {\n      return 0;\n    }\n    return Math.max(0, this.expectedAdBreakDurationMs - this.adBreakPlayedDurationMs);\n  }\n\n  getLoadedAdDurationMs(adController: AdController): number {\n    const durationSec = adController.getLoadedAdDuration?.();\n    if (durationSec == null || durationSec <= 0) {\n      return 0;\n    }\n    return Math.round(durationSec * 1000);\n  }\n\n  adFitsRemainingBudget(durationMs: number): boolean {\n    if (durationMs <= 0) {\n      return true;\n    }\n    return durationMs <= this.getDurationBudgetRemainingMs();\n  }\n\n  logAdDurationDecision(\n    accepted: boolean,\n    durationMs: number,\n    adController: AdController\n  ): void {\n    if (!this.debug) {\n      return;\n    }\n    const remainingBudget = this.getDurationBudgetRemainingMs();\n    const adId = adController.getLoadedAdId?.() ?? \"unknown\";\n    if (accepted) {\n      console.log(\n        `[AD-DURATION] Accepted ad id=${adId}, duration=${durationMs}ms, budget remaining after play=${Math.max(0, remainingBudget - durationMs)}ms`\n      );\n    } else {\n      console.log(\n        `[AD-DURATION] Rejected ad id=${adId}, duration=${durationMs}ms exceeds remaining budget=${remainingBudget}ms — requesting another ad`\n      );\n    }\n  }\n\n  recordPlayedAdDuration(adController: AdController): void {\n    const durationMs = this.getLoadedAdDurationMs(adController);\n    if (durationMs <= 0) {\n      return;\n    }\n    this.adBreakPlayedDurationMs += durationMs;\n    if (this.debug) {\n      console.log(\n        `[AD-DURATION] Played ${durationMs}ms — total played=${this.adBreakPlayedDurationMs}ms / ${this.expectedAdBreakDurationMs ?? \"?\"}ms`\n      );\n    }\n  }\n\n  ensureLoadedAdFitsBudget(adController: AdController): boolean {\n    const durationMs = this.getLoadedAdDurationMs(adController);\n    const fits = this.adFitsRemainingBudget(durationMs);\n    this.logAdDurationDecision(fits, durationMs, adController);\n    return fits;\n  }\n\n  rejectLoadedAdForDuration(adController: AdController): void {\n    try {\n      adController.destroy();\n    } catch {}\n  }\n\n  markAdStarted(): void {\n    this.currentAdIndex++;\n    this.totalAdsInBreak = this.currentAdIndex;\n    this.totalAdRequestsInBreak++;\n    this.lastAdRequestTime = Date.now();\n  }\n\n  notePodAdStarted(): void {\n    this.currentAdIndex++;\n    this.totalAdsInBreak = this.currentAdIndex;\n  }\n\n  getRemainingAdMs(): number {\n    const wallClockRemaining = this.getWallClockRemainingAdMs();\n    const budgetRemaining = this.getDurationBudgetRemainingMs();\n    if (this.expectedAdBreakDurationMs == null) {\n      return wallClockRemaining;\n    }\n    return Math.min(wallClockRemaining, budgetRemaining);\n  }\n\n  getMinRemainingMsToStartAd(): number {\n    const configured = this.config.minRemainingMsToStartAd;\n    if (typeof configured === \"number\" && configured >= 0) {\n      return configured;\n    }\n    return this.defaultMinRemainingMsToStartAd;\n  }\n\n  hasTimeToStartAnotherAd(): boolean {\n    const minRemaining = this.getMinRemainingMsToStartAd();\n    return (\n      this.getWallClockRemainingAdMs() > minRemaining &&\n      this.getDurationBudgetRemainingMs() > minRemaining\n    );\n  }\n\n  // --- Circuit breaker ---\n\n  isTemporaryAdError(error: Error): boolean {\n    const message = error?.message?.toLowerCase() || \"\";\n\n    if (message.includes(\"no ads available\") || message.includes(\"no fill\") || message.includes(\"nofill\")) {\n      return true;\n    }\n    if (message.includes(\"timeout\")) {\n      return true;\n    }\n    if (message.includes(\"rate limit\") || message.includes(\"too many requests\")) {\n      return true;\n    }\n    if (message.includes(\"ad playback error\")) {\n      return true;\n    }\n    return false;\n  }\n\n  isUrlInCooldown(vastTagUrl: string): boolean {\n    const failureTime = this.temporaryFailureUrls.get(vastTagUrl);\n    if (failureTime == null) {\n      return false;\n    }\n\n    const elapsed = Date.now() - failureTime;\n    if (elapsed >= this.temporaryFailureCooldownMs) {\n      this.temporaryFailureUrls.delete(vastTagUrl);\n      return false;\n    }\n\n    return true;\n  }\n\n  cleanupTemporaryFailures(): void {\n    const now = Date.now();\n    for (const [url, timestamp] of this.temporaryFailureUrls) {\n      if (now - timestamp >= this.temporaryFailureCooldownMs) {\n        this.temporaryFailureUrls.delete(url);\n      }\n    }\n  }\n\n  isGamInCooldown(): boolean {\n    return Date.now() < this.globalNoFillCooldownUntil;\n  }\n\n  recordGamNoFill(): void {\n    this.globalConsecutiveNoFills++;\n\n    if (this.globalConsecutiveNoFills >= this.globalNoFillThreshold) {\n      const exponent = this.globalConsecutiveNoFills - this.globalNoFillThreshold;\n      const backoff = Math.min(\n        this.globalNoFillBackoffBaseMs * Math.pow(2, exponent),\n        this.globalNoFillBackoffMaxMs\n      );\n      this.globalNoFillCooldownUntil = Date.now() + backoff;\n\n      if (this.debug) {\n        console.log(\n          `[CIRCUIT-BREAKER] GAM cooldown activated: ${backoff}ms (${this.globalConsecutiveNoFills} consecutive no-fills)`\n        );\n      }\n    }\n  }\n\n  resetGamNoFillCounter(): void {\n    if (this.globalConsecutiveNoFills > 0 && this.debug) {\n      console.log(\n        `[CIRCUIT-BREAKER] Resetting no-fill counter (was ${this.globalConsecutiveNoFills})`\n      );\n    }\n    this.globalConsecutiveNoFills = 0;\n    this.globalNoFillCooldownUntil = 0;\n  }\n\n  async enforceGlobalRateLimit(): Promise<void> {\n    const now = Date.now();\n    const elapsed = now - this.globalLastGamRequestTime;\n    if (elapsed < this.globalMinGamIntervalMs) {\n      const waitMs = this.globalMinGamIntervalMs - elapsed;\n      if (this.debug) {\n        console.log(`[RATE-LIMIT] Waiting ${waitMs}ms before next GAM request`);\n      }\n      await new Promise(resolve => setTimeout(resolve, waitMs));\n    }\n    this.globalLastGamRequestTime = Date.now();\n  }\n\n  // --- Watchdog ---\n\n  startAdRequestWatchdog(token: number): void {\n    this.clearAdRequestWatchdog();\n\n    const timeoutMs = this.config.adFailsafeTimeoutMs ?? 10000;\n    this.adRequestWatchdogToken = token;\n    this.adRequestWatchdogId = window.setTimeout(() => {\n      if (this.adRequestWatchdogToken !== token) {\n        return;\n      }\n\n      this.adRequestWatchdogId = undefined;\n      this.adRequestWatchdogToken = null;\n      if (this.activeAdRequestToken === token) {\n        this.activeAdRequestToken = null;\n      }\n\n      this.logAdState(\"ad_request_timeout\", { token, timeoutMs });\n      this.callbacks.onWatchdogTimeout();\n    }, timeoutMs) as unknown as number;\n\n    this.logAdState(\"ad_request_watchdog_started\", { token, timeoutMs });\n  }\n\n  clearAdRequestWatchdog(): void {\n    if (this.adRequestWatchdogId != null) {\n      clearTimeout(this.adRequestWatchdogId);\n      this.adRequestWatchdogId = undefined;\n    }\n\n    if (this.adRequestWatchdogToken != null) {\n      this.logAdState(\"ad_request_watchdog_cleared\", {\n        token: this.adRequestWatchdogToken,\n      });\n      this.adRequestWatchdogToken = null;\n    }\n  }\n\n  // --- Failsafe ---\n\n  startAdFailsafeTimer(token: number): void {\n    this.clearAdFailsafeTimer();\n\n    const failsafeMs = this.config.adFailsafeTimeoutMs ?? 10000;\n    this.adFailsafeToken = token;\n\n    this.adFailsafeTimerId = window.setTimeout(() => {\n      if (this.adFailsafeToken !== token) {\n        return;\n      }\n\n      this.adFailsafeTimerId = undefined;\n      this.adFailsafeToken = null;\n\n      if (this.activeAdRequestToken === token) {\n        this.activeAdRequestToken = null;\n      }\n\n      this.logAdState(\"ad_failsafe_triggered\", {\n        token,\n        failsafeMs,\n        videoPaused: this.video.paused,\n      });\n\n      this.callbacks.onFailsafeTimeout();\n    }, failsafeMs) as unknown as number;\n\n    this.logAdState(\"ad_failsafe_started\", { token, failsafeMs });\n  }\n\n  clearAdFailsafeTimer(): void {\n    if (this.adFailsafeTimerId != null) {\n      clearTimeout(this.adFailsafeTimerId);\n      this.logAdState(\"ad_failsafe_cleared\", { token: this.adFailsafeToken });\n      this.adFailsafeTimerId = undefined;\n    }\n\n    this.adFailsafeToken = null;\n  }\n\n  logAdState(event: string, extra: Record<string, unknown> = {}, adPlayer?: AdController, inAdBreak?: boolean, showAds?: boolean): void {\n    if (!this.debug) {\n      return;\n    }\n\n    console.log(\"[StormcloudVideoPlayer][AdState]\", {\n      event,\n      timestamp: new Date().toISOString(),\n      showAds: showAds ?? false,\n      adPlaying: adPlayer?.isAdPlaying() ?? false,\n      inAdBreak: inAdBreak ?? false,\n      activeAdRequestToken: this.activeAdRequestToken,\n      ...extra,\n    });\n  }\n\n  // --- Reset for ad break end ---\n\n  resetForBreakEnd(): void {\n    this.clearAdStopTimer();\n    this.clearAdStartTimer();\n    this.clearAdRequestWatchdog();\n    this.clearAdFailsafeTimer();\n    this.activeAdRequestToken = null;\n    this.expectedAdBreakDurationMs = undefined;\n    this.currentAdBreakStartWallClockMs = undefined;\n    this.scteAdBreakEndWallClockMs = undefined;\n    this.adBreakPlayedDurationMs = 0;\n    this.currentAdIndex = 0;\n    this.totalAdsInBreak = 0;\n    this.consecutiveFailures = 0;\n    this.globalConsecutiveNoFills = 0;\n    this.adBreakEpoch++;\n  }\n\n  destroy(): void {\n    this.clearAdStopTimer();\n    this.clearAdStartTimer();\n    this.clearAdFailsafeTimer();\n    this.clearAdRequestWatchdog();\n  }\n}\n","export class PlaceholderLayer {\n  private container: HTMLDivElement | undefined;\n  private debug: boolean;\n  private video: HTMLVideoElement;\n\n  constructor(video: HTMLVideoElement, debug: boolean) {\n    this.video = video;\n    this.debug = debug;\n  }\n\n  private ensureContainer(): void {\n    if (this.container) {\n      return;\n    }\n\n    const el = document.createElement(\"div\");\n    el.style.position = \"absolute\";\n    el.style.left = \"0\";\n    el.style.top = \"0\";\n    el.style.right = \"0\";\n    el.style.bottom = \"0\";\n    el.style.display = \"none\";\n    el.style.alignItems = \"center\";\n    el.style.justifyContent = \"center\";\n    el.style.pointerEvents = \"none\";\n    el.style.zIndex = \"5\";\n    el.style.backgroundColor = \"#000\";\n    el.style.transition = \"opacity 0.3s ease-in-out\";\n    el.style.opacity = \"0\";\n\n    if (!this.video.parentElement) {\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Video element has no parent for placeholder container\");\n      }\n      return;\n    }\n\n    this.video.parentElement.appendChild(el);\n    this.container = el;\n  }\n\n  show(): void {\n    this.ensureContainer();\n\n    if (!this.container) {\n      return;\n    }\n\n    if (!this.video.muted) {\n      this.video.muted = true;\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Muted video when showing placeholder\");\n      }\n    }\n\n    const wasHidden = this.container.style.display === \"none\" || this.container.style.opacity === \"0\";\n    if (wasHidden) {\n      this.container.style.transition = \"none\";\n    } else {\n      this.container.style.transition = \"opacity 0.3s ease-in-out\";\n    }\n\n    this.container.style.backgroundColor = \"#000\";\n    this.container.style.display = \"flex\";\n    this.container.offsetHeight;\n    this.container.style.opacity = \"1\";\n    this.container.style.pointerEvents = \"auto\";\n\n    if (wasHidden) {\n      requestAnimationFrame(() => {\n        if (this.container) {\n          this.container.style.transition = \"opacity 0.3s ease-in-out\";\n        }\n      });\n    }\n\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Showing placeholder layer (between content and ad layer)\");\n    }\n  }\n\n  hide(): void {\n    if (!this.container) {\n      return;\n    }\n\n    this.container.style.opacity = \"0\";\n    setTimeout(() => {\n      if (this.container) {\n        this.container.style.display = \"none\";\n        this.container.style.pointerEvents = \"none\";\n        this.container.style.backgroundColor = \"#000\";\n      }\n    }, 300);\n\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Hiding placeholder layer\");\n    }\n  }\n\n  destroy(): void {\n    if (this.container) {\n      if (this.container.parentElement) {\n        this.container.parentElement.removeChild(this.container);\n      }\n      this.container = undefined;\n    }\n  }\n}\n","import Hls from \"hls.js\";\nimport type {\n  StormcloudVideoPlayerConfig,\n  Scte35Marker,\n  Id3TagInfo,\n} from \"../types\";\nimport type { Scte35CueContext } from \"./playerTypes\";\nimport {\n  parseScte35FromId3,\n  parseScte35FromTsPackets,\n  normalizeFragmentPayload,\n  getFragmentStartSeconds,\n  parseCueOutDuration,\n  parseCueOutCont,\n  parseAttributeList,\n  toNumber,\n} from \"./Scte35Parser\";\nimport type { Scte35CueManager } from \"./Scte35CueManager\";\nimport type { AdTimingService } from \"./AdTimingService\";\n\nexport interface HlsEngineCallbacks {\n  onManifestParsed(isLive: boolean): Promise<void>;\n  onScte35Cue(marker: Scte35Marker, context: Scte35CueContext): void;\n  activatePendingCuesForFragment(frag: any): void;\n  onFatalDestroy(): void;\n  isInAdBreak(): boolean;\n  hasPendingAdBreak(): boolean;\n}\n\nexport class HlsEngine {\n  hls: Hls | undefined;\n  isLiveStream: boolean = false;\n  nativeHlsMode: boolean = false;\n  videoSrcProtection: string | null = null;\n\n  private bufferedSegmentsCount: number = 0;\n  private shouldAutoplayAfterBuffering: boolean = false;\n  private hasInitialBufferCompleted: boolean = false;\n\n  private readonly config: StormcloudVideoPlayerConfig;\n  private readonly video: HTMLVideoElement;\n  private readonly cueManager: Scte35CueManager;\n  private readonly timing: AdTimingService;\n  private readonly callbacks: HlsEngineCallbacks;\n\n  constructor(\n    config: StormcloudVideoPlayerConfig,\n    video: HTMLVideoElement,\n    cueManager: Scte35CueManager,\n    timing: AdTimingService,\n    callbacks: HlsEngineCallbacks\n  ) {\n    this.config = config;\n    this.video = video;\n    this.cueManager = cueManager;\n    this.timing = timing;\n    this.callbacks = callbacks;\n  }\n\n  private get debug(): boolean {\n    return !!this.config.debugAdTiming;\n  }\n\n  shouldUseNativeHls(getStreamType: () => \"hls\" | \"other\"): boolean {\n    const streamType = getStreamType();\n    if (streamType === \"other\") {\n      return true;\n    }\n    const canNative = this.video.canPlayType(\"application/vnd.apple.mpegurl\");\n    return !!(this.config.allowNativeHls && canNative);\n  }\n\n  async setupNativeHls(): Promise<void> {\n    this.nativeHlsMode = true;\n    this.videoSrcProtection = this.config.src;\n    this.video.src = this.config.src;\n\n    this.isLiveStream = this.config.isLiveStream ?? (this.config.lowLatencyMode ?? false);\n\n    if (this.debug) {\n      const adBehavior = this.isLiveStream\n        ? \"live (main video continues muted during ads)\"\n        : \"vod (main video pauses during ads)\";\n      console.log(\n        \"[StormcloudVideoPlayer] Using native HLS playback:\",\n        {\n          isLive: this.isLiveStream,\n          allowNativeHls: this.config.allowNativeHls,\n          adBehavior,\n        }\n      );\n    }\n\n    if (this.config.autoplay) {\n      await this.video.play()?.catch(() => {});\n    }\n  }\n\n  setupHls(): void {\n    this.hls = new Hls({\n      enableWorker: true,\n      backBufferLength: 30,\n      liveDurationInfinity: true,\n      lowLatencyMode: !!this.config.lowLatencyMode,\n      maxLiveSyncPlaybackRate: this.config.lowLatencyMode ? 1.5 : 1.0,\n      ...(this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {}),\n      maxBufferLength: 30,\n      maxMaxBufferLength: 600,\n      maxBufferSize: 60 * 1000 * 1000,\n      maxBufferHole: 0.5,\n      highBufferWatchdogPeriod: 2,\n      nudgeOffset: 0.1,\n      nudgeMaxRetry: 3,\n      startPosition: -1,\n    });\n\n    this.hls.on(Hls.Events.MEDIA_ATTACHED, () => {\n      this.hls?.loadSource(this.config.src);\n    });\n\n    this.hls.on(Hls.Events.MANIFEST_PARSED, async (_, _data: any) => {\n      this.isLiveStream =\n        this.config.isLiveStream ??\n        (this.hls?.levels?.some(\n          (level) =>\n            level?.details?.live === true || level?.details?.type === \"LIVE\"\n        ) ?? false);\n\n      await this.callbacks.onManifestParsed(this.isLiveStream);\n\n      this.bufferedSegmentsCount = 0;\n      this.hasInitialBufferCompleted = false;\n      this.shouldAutoplayAfterBuffering = !!this.config.autoplay;\n\n      const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Waiting for\",\n          minSegments,\n          \"segments to buffer before playback\"\n        );\n      }\n\n      if (minSegments === 0 || !this.config.autoplay) {\n        this.hasInitialBufferCompleted = true;\n        if (this.config.autoplay) {\n          await this.video.play()?.catch(() => {});\n        }\n      }\n    });\n\n    this.hls.on(Hls.Events.LEVEL_LOADED, (_evt, data: any) => {\n      if (this.callbacks.isInAdBreak() || this.callbacks.hasPendingAdBreak()) {\n        return;\n      }\n\n      const details = data?.details;\n      if (!details || !details.fragments || details.fragments.length === 0) {\n        return;\n      }\n\n      const fragmentsToScan = Math.min(5, details.fragments.length);\n\n      for (let i = 0; i < fragmentsToScan; i++) {\n        const frag = details.fragments[i];\n        const tagList: any[] | undefined = frag?.tagList;\n\n        if (!Array.isArray(tagList)) continue;\n\n        for (const entry of tagList) {\n          let tag = \"\";\n          let value = \"\";\n\n          if (Array.isArray(entry)) {\n            tag = String(entry[0] ?? \"\");\n            value = String(entry[1] ?? \"\");\n          } else if (typeof entry === \"string\") {\n            const idx = entry.indexOf(\":\");\n            if (idx >= 0) {\n              tag = entry.substring(0, idx);\n              value = entry.substring(idx + 1);\n            } else {\n              tag = entry;\n            }\n          }\n\n          if (!tag) continue;\n\n          if (tag.includes(\"EXT-X-CUE-OUT\") || tag.includes(\"EXT-X-DATERANGE\")) {\n            const attrs = tag.includes(\"EXT-X-DATERANGE\")\n              ? parseAttributeList(value)\n              : {};\n            const hasScteOut = tag.includes(\"EXT-X-CUE-OUT\") ||\n              \"SCTE35-OUT\" in attrs ||\n              attrs[\"SCTE35-OUT\"] !== undefined;\n\n            if (hasScteOut) {\n              const durationSeconds = parseCueOutDuration(value);\n              const marker: Scte35Marker = {\n                type: \"start\",\n                ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n                raw: { tag, value, earlyDetection: true },\n              } as Scte35Marker;\n\n              if (this.debug) {\n                console.log(\"[StormcloudVideoPlayer] EARLY SCTE-35 DETECTION: Ad break marker found in fragment\", i, \"- starting pre-fetch (NOT playing yet)\");\n              }\n\n              this.callbacks.onScte35Cue(marker, {\n                ...this.cueManager.createScte35CueContext(\"manifest\", \"early\", frag),\n              });\n              return;\n            }\n          }\n        }\n      }\n    });\n\n    this.hls.on(Hls.Events.FRAG_BUFFERED, async (_evt, _data: any) => {\n      if (this.hasInitialBufferCompleted) {\n        return;\n      }\n\n      this.bufferedSegmentsCount++;\n      const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] Buffered segment ${this.bufferedSegmentsCount}/${minSegments}`\n        );\n      }\n\n      if (this.bufferedSegmentsCount >= minSegments) {\n        this.hasInitialBufferCompleted = true;\n\n        if (this.shouldAutoplayAfterBuffering) {\n          if (this.debug) {\n            console.log(\n              `[StormcloudVideoPlayer] Initial buffer complete (${this.bufferedSegmentsCount} segments). Starting playback.`\n            );\n          }\n          await this.video.play()?.catch((err) => {\n            if (this.debug) {\n              console.warn(\"[StormcloudVideoPlayer] Autoplay failed:\", err);\n            }\n          });\n        }\n      }\n    });\n\n    this.hls.on(Hls.Events.FRAG_PARSING_METADATA, (_evt, data: any) => {\n      const id3Tags: Id3TagInfo[] = (data?.samples || []).map((s: any) => ({\n        key: \"ID3\",\n        value: s?.data,\n        ptsSeconds: s?.pts,\n      }));\n      id3Tags.forEach((tag) => this.onId3Tag(tag));\n    });\n\n    this.hls.on(Hls.Events.FRAG_LOADED, (_evt, data: any) => {\n      this.processFragmentScte35Payload(\n        data?.payload,\n        typeof data?.frag?.sn === \"number\" ? data.frag.sn : undefined,\n        getFragmentStartSeconds(data?.frag)\n      );\n    });\n\n    this.hls.on(Hls.Events.FRAG_DECRYPTED, (_evt, data: any) => {\n      this.processFragmentScte35Payload(\n        data?.payload,\n        typeof data?.frag?.sn === \"number\" ? data.frag.sn : undefined,\n        getFragmentStartSeconds(data?.frag)\n      );\n    });\n\n    this.hls.on(Hls.Events.FRAG_CHANGED, (_evt, data: any) => {\n      const frag = data?.frag;\n      const tagList: any[] | undefined = frag?.tagList;\n      if (!Array.isArray(tagList)) {\n        this.callbacks.activatePendingCuesForFragment(frag);\n        return;\n      }\n\n      for (const entry of tagList) {\n        let tag = \"\";\n        let value = \"\";\n        if (Array.isArray(entry)) {\n          tag = String(entry[0] ?? \"\");\n          value = String(entry[1] ?? \"\");\n        } else if (typeof entry === \"string\") {\n          const idx = entry.indexOf(\":\");\n          if (idx >= 0) {\n            tag = entry.substring(0, idx);\n            value = entry.substring(idx + 1);\n          } else {\n            tag = entry;\n            value = \"\";\n          }\n        }\n\n        if (!tag) continue;\n        if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n          const prog = parseCueOutCont(value);\n          const marker: Scte35Marker = {\n            type: \"progress\",\n            ...(prog?.duration !== undefined\n              ? { durationSeconds: prog.duration }\n              : {}),\n            ...(prog?.elapsed !== undefined\n              ? { ptsSeconds: prog.elapsed }\n              : {}),\n            raw: { tag, value },\n          } as Scte35Marker;\n          this.callbacks.onScte35Cue(marker, {\n            ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag),\n          });\n        } else if (tag.includes(\"EXT-X-CUE-OUT\")) {\n          const durationSeconds = parseCueOutDuration(value);\n          const marker: Scte35Marker = {\n            type: \"start\",\n            ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n            raw: { tag, value },\n          } as Scte35Marker;\n          this.callbacks.onScte35Cue(marker, {\n            ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag),\n          });\n        } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n          this.callbacks.onScte35Cue(\n            { type: \"end\", raw: { tag, value } },\n            {\n              ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag),\n            }\n          );\n        } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n          const attrs = parseAttributeList(value);\n          const hasScteOut =\n            \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== undefined;\n          const hasScteIn =\n            \"SCTE35-IN\" in attrs || attrs[\"SCTE35-IN\"] !== undefined;\n          const klass = String(attrs[\"CLASS\"] ?? \"\");\n          const duration = toNumber(attrs[\"DURATION\"]);\n\n          if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n            const marker: Scte35Marker = {\n              type: \"start\",\n              ...(duration !== undefined ? { durationSeconds: duration } : {}),\n              raw: { tag, value, attrs },\n            } as Scte35Marker;\n            this.callbacks.onScte35Cue(marker, {\n              ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag),\n            });\n          }\n          if (hasScteIn) {\n            this.callbacks.onScte35Cue(\n              { type: \"end\", raw: { tag, value, attrs } },\n              {\n                ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag),\n              }\n            );\n          }\n        }\n      }\n      this.callbacks.activatePendingCuesForFragment(frag);\n    });\n\n    this.hls.on(Hls.Events.ERROR, (_evt, data) => {\n      if (data?.fatal) {\n        switch (data.type) {\n          case Hls.ErrorTypes.NETWORK_ERROR:\n            this.hls?.startLoad();\n            break;\n          case Hls.ErrorTypes.MEDIA_ERROR:\n            this.hls?.recoverMediaError();\n            break;\n          default:\n            this.callbacks.onFatalDestroy();\n            break;\n        }\n      }\n    });\n\n    this.hls.attachMedia(this.video);\n  }\n\n  private onId3Tag(tag: Id3TagInfo): void {\n    if (typeof tag.ptsSeconds === \"number\") {\n      this.timing.updatePtsDrift(tag.ptsSeconds);\n    }\n    const marker = parseScte35FromId3(tag);\n    if (marker) {\n      this.callbacks.onScte35Cue(marker, {\n        source: \"id3\",\n        readiness: \"playback\",\n      });\n    }\n  }\n\n  private processFragmentScte35Payload(\n    payloadData: unknown,\n    fragmentSn?: number,\n    fragmentStartSeconds?: number\n  ): void {\n    const payload = normalizeFragmentPayload(payloadData);\n    if (!payload) {\n      return;\n    }\n\n    const markers = parseScte35FromTsPackets(\n      payload,\n      this.cueManager.tsScte35Pids,\n      this.cueManager.pmtPids,\n      this.cueManager.processedTsScte35Sections\n    );\n    markers.forEach((marker) => {\n      const context: Scte35CueContext = {\n        source: \"ts\",\n        readiness: \"early\",\n      };\n      if (fragmentSn !== undefined) {\n        context.fragmentSn = fragmentSn;\n      }\n      if (fragmentStartSeconds !== undefined) {\n        context.fragmentStartSeconds = fragmentStartSeconds;\n      }\n      this.callbacks.onScte35Cue(marker, context);\n    });\n  }\n\n  getLiveSyncPosition(): number | undefined {\n    const pos = this.hls?.liveSyncPosition;\n    return typeof pos === \"number\" && Number.isFinite(pos) ? pos : undefined;\n  }\n\n  destroy(): void {\n    this.hls?.destroy();\n    this.hls = undefined;\n  }\n}\n","import type { AdController } from \"../types\";\n\nexport function getAdAudioVolume(adPlayer: AdController): number {\n  return adPlayer.getOriginalMutedState() ? 0 : adPlayer.getOriginalVolume();\n}\n\nexport function toggleMute(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  debug: boolean\n): void {\n  if (adPlayer.isAdPlaying()) {\n    const newMutedState = !adPlayer.getOriginalMutedState();\n    const restoreVolume = adPlayer.getOriginalVolume() || 1;\n\n    adPlayer.updateOriginalMutedState(newMutedState, video.volume);\n    adPlayer.setAdVolume(newMutedState ? 0 : restoreVolume);\n\n    if (debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] Mute toggle during ad - immediately applied:\",\n        newMutedState\n      );\n    }\n  } else {\n    video.muted = !video.muted;\n    adPlayer.updateOriginalMutedState(video.muted, video.volume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] Muted:\", video.muted);\n    }\n  }\n}\n\nexport function toggleFullscreen(\n  video: HTMLVideoElement,\n  debug: boolean\n): Promise<void> {\n  return new Promise((resolve, reject) => {\n    if (!document.fullscreenElement) {\n      const container = video.parentElement;\n      if (!container) {\n        reject(new Error(\"No parent container found for fullscreen\"));\n        return;\n      }\n      container\n        .requestFullscreen()\n        .then(() => {\n          if (debug) {\n            console.log(\"[StormcloudVideoPlayer] Entered fullscreen\");\n          }\n          resolve();\n        })\n        .catch((err) => {\n          if (debug) {\n            console.error(\"[StormcloudVideoPlayer] Fullscreen error:\", err);\n          }\n          reject(err);\n        });\n    } else {\n      document\n        .exitFullscreen()\n        .then(() => {\n          if (debug) {\n            console.log(\"[StormcloudVideoPlayer] Exited fullscreen\");\n          }\n          resolve();\n        })\n        .catch((err) => {\n          if (debug) {\n            console.error(\n              \"[StormcloudVideoPlayer] Exit fullscreen error:\",\n              err\n            );\n          }\n          reject(err);\n        });\n    }\n  });\n}\n\nexport function isMuted(\n  video: HTMLVideoElement,\n  adPlayer: AdController\n): boolean {\n  if (adPlayer.isAdPlaying()) {\n    return adPlayer.getOriginalMutedState();\n  }\n  return video.muted;\n}\n\nexport function setMuted(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  muted: boolean,\n  debug: boolean\n): void {\n  const adPlaying = adPlayer.isAdPlaying();\n\n  if (adPlaying && muted === video.muted) {\n    if (debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] setMuted reflective update during ad ignored\",\n        { muted }\n      );\n    }\n    return;\n  }\n\n  video.muted = muted;\n\n  if (adPlaying) {\n    adPlayer.updateOriginalMutedState(muted, video.volume);\n    adPlayer.setAdVolume(muted ? 0 : 1);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setMuted applied during ad\", {\n        muted,\n      });\n    }\n    return;\n  }\n\n  adPlayer.updateOriginalMutedState(muted, video.volume);\n  if (debug) {\n    console.log(\"[StormcloudVideoPlayer] setMuted called:\", muted);\n  }\n}\n\nexport function setVolume(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  volume: number,\n  debug: boolean\n): void {\n  const clampedVolume = Math.max(0, Math.min(1, volume));\n  const adPlaying = adPlayer.isAdPlaying();\n\n  if (adPlaying) {\n    adPlayer.setAdVolume(clampedVolume);\n    adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setVolume applied during ad\", {\n        volume: clampedVolume,\n      });\n    }\n  } else {\n    video.volume = clampedVolume;\n    video.muted = clampedVolume === 0;\n    adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setVolume called:\", clampedVolume);\n    }\n  }\n}\n\nexport function getVolume(\n  video: HTMLVideoElement,\n  adPlayer: AdController\n): number {\n  const adPlaying = adPlayer.isAdPlaying();\n  if (adPlaying) {\n    return adPlayer.getAdVolume();\n  }\n  return video.volume;\n}\n\nexport function isFullscreen(): boolean {\n  return !!document.fullscreenElement;\n}\n\nexport function resizePlayer(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  debug: boolean\n): void {\n  if (debug) {\n    console.log(\"[StormcloudVideoPlayer] Resizing player\");\n  }\n\n  if (adPlayer && adPlayer.isAdPlaying()) {\n    const width = video.clientWidth || 640;\n    const height = video.clientHeight || 480;\n\n    if (debug) {\n      console.log(\n        `[StormcloudVideoPlayer] Resizing ads manager to ${width}x${height}`\n      );\n    }\n\n    adPlayer.resize(width, height);\n  }\n}\n","import type {\n  StormcloudVideoPlayerConfig,\n  Scte35Marker,\n  AdController,\n} from \"../types\";\nimport {\n  buildAnalyticsContext,\n  sendAdLoadedTracking,\n  sendAdImpressionTracking,\n} from \"../utils/tracking\";\nimport type { AdTimingService } from \"./AdTimingService\";\nimport type { AdConfigManager } from \"./AdConfigManager\";\nimport type { Scte35CueManager } from \"./Scte35CueManager\";\nimport type { PlaceholderLayer } from \"./PlaceholderLayer\";\nimport { getAdAudioVolume } from \"./PlayerControls\";\n\nexport interface AdBreakOrchestratorHost {\n  readonly config: StormcloudVideoPlayerConfig;\n  readonly video: HTMLVideoElement;\n  getAdPlayer(): AdController;\n  setAdPlayer(player: AdController): void;\n  createAdPlayer(continueLiveStreamDuringAds: boolean): AdController;\n  shouldContinueLiveStreamDuringAds(): boolean;\n  getLiveSyncPosition(): number | undefined;\n  generatePodVastUrl(baseUrl: string, breakDurationMs?: number): string;\n}\n\nexport class AdBreakOrchestrator {\n  inAdBreak = false;\n  showAds: boolean = false;\n  isShowingPlaceholder: boolean = false;\n  adDetectSentForCurrentBreak: boolean = false;\n\n  private continuousFetchingActive: boolean = false;\n  private continuousFetchLoopRunning = false;\n  adRequestQueue: string[] = [];\n  adPodQueue: string[] = [];\n  private readonly maxPlaceholderDurationMs: number = 5000;\n\n  pendingAdBreak: {\n    marker: Scte35Marker;\n    detectedAtFragmentSn?: number;\n    vastUrls: string[];\n    isFetching: boolean;\n    fetchStartTime?: number;\n  } | null = null;\n  prefetchTimerId: number | undefined;\n\n  private readonly host: AdBreakOrchestratorHost;\n  private readonly timing: AdTimingService;\n  private readonly adConfig: AdConfigManager;\n  private readonly cueManager: Scte35CueManager;\n  private readonly placeholder: PlaceholderLayer;\n\n  constructor(\n    host: AdBreakOrchestratorHost,\n    timing: AdTimingService,\n    adConfig: AdConfigManager,\n    cueManager: Scte35CueManager,\n    placeholder: PlaceholderLayer\n  ) {\n    this.host = host;\n    this.timing = timing;\n    this.adConfig = adConfig;\n    this.cueManager = cueManager;\n    this.placeholder = placeholder;\n  }\n\n  private get debug(): boolean {\n    return !!this.host.config.debugAdTiming;\n  }\n\n  private get analyticsContext() {\n    return buildAnalyticsContext(this.host.config);\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  IMA event listeners\n  // ───────────────────────────────────────────────────────────────\n\n  /**\n   * Produces the next pod ad-request URL for the current break. Every request\n   * (initial and continuous-fetch top-up) carries pod macros (pmad/pmnd/pmxd,\n   * no ppos); pmxd tracks the remaining break time so top-up pods only ask for\n   * what still fits.\n   */\n  private nextAdRequestUrl(baseVastUrl: string): string {\n    const remaining = Math.min(\n      this.timing.getWallClockRemainingAdMs(),\n      this.timing.getDurationBudgetRemainingMs()\n    );\n    const breakDurationMs = remaining > 0 ? remaining : undefined;\n    return this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);\n  }\n\n  attachImaEventListeners(): void {\n    const adPlayer = this.host.getAdPlayer();\n    adPlayer.on(\"pod_ad_started\", (payload?: any) => {\n      this.timing.notePodAdStarted();\n      if (this.debug) {\n        console.log(\n          `[POD] Playing pod ad ${payload?.index != null ? payload.index + 1 : \"?\"}/${payload?.total ?? \"?\"}`\n        );\n      }\n    });\n    adPlayer.on(\"all_ads_completed\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n\n      this.timing.consecutiveFailures = 0;\n\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] all_ads_completed event received - remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n\n      if (this.inAdBreak) {\n        if (this.timing.hasTimeToStartAnotherAd()) {\n          this.tryNextAvailableAdWithRateLimit();\n        } else {\n          this.handleAdPodComplete();\n        }\n      }\n    });\n    adPlayer.on(\"ad_error\", (errorPayload?: any) => {\n      let errorMessage = \"Ad playback failed\";\n\n      if (errorPayload) {\n        const errorCode = errorPayload.code || errorPayload.errorCode || \"unknown\";\n        const vastErrorCode = errorPayload.vastErrorCode;\n        const message = errorPayload.message || errorPayload.errorMessage || \"Unknown error\";\n        const cause = errorPayload.cause || errorPayload.innerError || errorPayload.error;\n\n        errorMessage = `Ad error: AdError ${errorCode}: ${message}`;\n\n        if (vastErrorCode && vastErrorCode !== \"N/A\" && vastErrorCode !== errorCode) {\n          errorMessage += ` (VAST Error Code: ${vastErrorCode})`;\n        }\n\n        if (cause) {\n          const causeMessage = typeof cause === \"string\" ? cause : (cause.message || String(cause));\n          errorMessage += `. Caused by: ${causeMessage}`;\n        }\n      }\n\n      console.error(\"[AD-ERROR]\", errorMessage, errorPayload || \"\");\n      this.handleAdFailure();\n    });\n    adPlayer.on(\"content_pause\", () => {\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = true;\n      this.timing.resetGamNoFillCounter();\n\n      if (this.inAdBreak && this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)\");\n        }\n      }\n\n      this.host.getAdPlayer().setAdVolume(getAdAudioVolume(this.host.getAdPlayer()));\n\n      if (this.isShowingPlaceholder) {\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Hiding placeholder - new ads starting\");\n        }\n        this.host.getAdPlayer().hidePlaceholder();\n        this.isShowingPlaceholder = false;\n      }\n    });\n    adPlayer.on(\"content_resume\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      if (!this.host.video.muted) {\n        this.host.video.muted = true;\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Muted video on content_resume (ad ended, gap between ads)\");\n        }\n      }\n\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = false;\n\n      if (!this.inAdBreak) {\n        return;\n      }\n\n      this.timing.consecutiveFailures = 0;\n\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n\n      if (this.debug) {\n        console.log(\n          `[CONTINUOUS-FETCH] content_resume event: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n\n      if (this.timing.hasTimeToStartAnotherAd()) {\n        this.tryNextAvailableAdWithRateLimit();\n      } else {\n        this.handleAdPodComplete();\n      }\n    });\n  }\n\n  recreateAdController(): void {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Recreating AdController for new ad\");\n    }\n\n    const shouldShowPlaceholder = this.inAdBreak && this.showAds;\n    const adPlayer = this.host.getAdPlayer();\n    if (shouldShowPlaceholder && adPlayer) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Showing placeholder before destroying old AdController\");\n      }\n      this.placeholder.show();\n      adPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n\n    const preservedMutedState = adPlayer.getOriginalMutedState();\n    const preservedVolumeState = adPlayer.getOriginalVolume();\n\n    if (adPlayer) {\n      try {\n        adPlayer.destroy();\n        this.host.video.muted = true;\n      } catch (error) {\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] Error destroying old AdController:\", error);\n        }\n      }\n    }\n\n    const continueLiveStreamDuringAds = this.host.shouldContinueLiveStreamDuringAds();\n    const newAdPlayer = this.host.createAdPlayer(continueLiveStreamDuringAds);\n    this.host.setAdPlayer(newAdPlayer);\n\n    newAdPlayer.initialize();\n    newAdPlayer.updateOriginalMutedState(preservedMutedState, preservedVolumeState);\n    this.attachImaEventListeners();\n\n    if (shouldShowPlaceholder) {\n      this.placeholder.show();\n      newAdPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n  }\n\n  clearPendingAdBreak(): void {\n    if (this.prefetchTimerId != null) {\n      clearTimeout(this.prefetchTimerId);\n      this.prefetchTimerId = undefined;\n    }\n    this.pendingAdBreak = null;\n    this.cueManager.pendingScte35CueKey = undefined;\n    this.adConfig.podAssignedByPrefetch = false;\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Ad break start\n  // ───────────────────────────────────────────────────────────────\n\n  async handleAdStart(_marker: Scte35Marker): Promise<void> {\n    const scheduled = this.adConfig.findCurrentOrNextBreak(\n      this.host.video.currentTime * 1000\n    );\n    if (scheduled) {\n      this.adConfig.consumedVmapBreakIds.add(this.adConfig.getAdBreakKey(scheduled));\n    }\n    const tags = this.adConfig.selectVastTagsForBreak(scheduled);\n\n    let baseVastUrl: string;\n\n    if (tags && tags.length > 0 && tags[0]) {\n      baseVastUrl = tags[0];\n    } else if (this.adConfig.apiVastTagUrl) {\n      baseVastUrl = this.adConfig.apiVastTagUrl;\n    } else {\n      this.clearPendingAdBreak();\n      return;\n    }\n\n    const adBreakDurationMs =\n      _marker.durationSeconds != null\n        ? _marker.durationSeconds * 1000\n        : scheduled?.durationMs;\n\n    if (this.debug) {\n      const mode = this.host.config.isLiveStream ? \"LIVE\" : \"VOD\";\n      console.log(\n        `[CONTINUOUS-FETCH] ${mode} MODE: Target duration=${adBreakDurationMs}ms`\n      );\n    }\n\n    this.timing.failedVastUrls.clear();\n    this.timing.temporaryFailureUrls.clear();\n    this.timing.consecutiveFailures = 0;\n    this.continuousFetchingActive = true;\n    this.isShowingPlaceholder = false;\n    this.timing.totalAdRequestsInBreak = 0;\n\n    if (this.adConfig.podAssignedByPrefetch) {\n      this.adConfig.podAssignedByPrefetch = false;\n    } else {\n      this.adConfig.beginNewAdPod();\n    }\n\n    const currentMuted = this.host.video.muted;\n    const currentVolume = this.host.video.volume;\n    this.host.getAdPlayer().updateOriginalMutedState(currentMuted, currentVolume);\n\n    this.inAdBreak = true;\n    this.timing.adBreakPlayedDurationMs = 0;\n    this.timing.currentAdIndex = 0;\n    this.timing.totalAdsInBreak = 0;\n    this.adPodQueue = [];\n    this.showAds = false;\n\n    if (\n      this.timing.expectedAdBreakDurationMs == null &&\n      adBreakDurationMs != null\n    ) {\n      this.timing.expectedAdBreakDurationMs = adBreakDurationMs;\n    }\n\n    // Pod-only serving: open the break with a single optimized-pod request.\n    // On success, startOptimizedPod starts the continuous-fetch loop, which\n    // tops up with further pod requests (pmxd = remaining time) if the first\n    // pod under-fills the break.\n    const podPlayed = await this.startOptimizedPod(\n      baseVastUrl,\n      adBreakDurationMs,\n      currentMuted,\n      currentVolume\n    );\n\n    if (!podPlayed) {\n      if (this.debug) {\n        console.log(\"[POD] Initial pod request did not fill; attempting top-up pod request\");\n      }\n      this.continuousFetchingActive = true;\n      this.startContinuousFetching(baseVastUrl);\n      await this.tryNextAvailableAdWithRateLimit();\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Optimized pod (single multi-ad request)\n  // ───────────────────────────────────────────────────────────────\n\n  private async startOptimizedPod(\n    baseVastUrl: string,\n    breakDurationMs: number | undefined,\n    currentMuted: boolean,\n    currentVolume: number\n  ): Promise<boolean> {\n    let podUrl: string | undefined;\n    if (this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0) {\n      podUrl = this.pendingAdBreak.vastUrls[0];\n      this.clearPendingAdBreak();\n    } else {\n      podUrl = this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);\n    }\n\n    if (!podUrl) {\n      return false;\n    }\n\n    this.continuousFetchingActive = false;\n\n    this.recreateAdController();\n\n    const adPlayer = this.host.getAdPlayer();\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      await adPlayer.requestAds(podUrl);\n      this.timing.clearAdRequestWatchdog();\n\n      if (this.timing.activeAdRequestToken !== requestToken) {\n        return true;\n      }\n\n      const podCount = adPlayer.getPodAdCount?.() ?? 1;\n      if (podCount < 1) {\n        return false;\n      }\n\n      if (this.debug) {\n        console.log(\n          podCount === 1\n            ? \"[POD] Response contained a single ad; playing it and enabling pod top-up\"\n            : `[POD] Optimized pod returned ${podCount} ads; playing pod in one controller`\n        );\n      }\n\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: podUrl, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      this.timing.startAdFailsafeTimer(requestToken);\n      await adPlayer.play();\n      this.timing.markAdStarted();\n\n      if (\n        this.timing.expectedAdBreakDurationMs != null &&\n        this.timing.getAdBreakEndWallClockMs() == null\n      ) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n      }\n\n      adPlayer.setAdVolume(currentMuted ? 0 : currentVolume);\n      this.timing.consecutiveFailures = 0;\n\n      // Always keep topping up with further pod requests so the rest of the\n      // break fills if this pod was shorter than the available time.\n      this.continuousFetchingActive = true;\n      this.startContinuousFetching(baseVastUrl);\n\n      return true;\n    } catch (error) {\n      this.timing.clearAdRequestWatchdog();\n      this.timing.clearAdFailsafeTimer();\n      if (this.timing.activeAdRequestToken === requestToken) {\n        this.timing.activeAdRequestToken = null;\n      }\n      if (this.debug) {\n        console.warn(\"[POD] Optimized pod request/play failed:\", error);\n      }\n\n      if (this.timing.isTemporaryAdError(error as Error)) {\n        this.timing.temporaryFailureUrls.set(podUrl, Date.now());\n      }\n\n      this.continuousFetchingActive = true;\n      this.recreateAdController();\n      return false;\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Continuous fetching\n  // ───────────────────────────────────────────────────────────────\n\n  private startContinuousFetching(baseVastUrl: string): void {\n    if (!this.continuousFetchingActive) {\n      return;\n    }\n\n    if (this.continuousFetchLoopRunning) {\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Fetch loop already running, skipping duplicate start\");\n      }\n      return;\n    }\n\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] Starting continuous ad fetching loop\");\n    }\n\n    this.continuousFetchLoopRunning = true;\n    this.continuousFetchLoop(baseVastUrl);\n  }\n\n  private async continuousFetchLoop(baseVastUrl: string): Promise<void> {\n    const epoch = this.timing.adBreakEpoch;\n    while (\n      this.continuousFetchingActive &&\n      this.inAdBreak &&\n      epoch === this.timing.adBreakEpoch\n    ) {\n      const remaining = Math.min(\n        this.timing.getWallClockRemainingAdMs(),\n        this.timing.getDurationBudgetRemainingMs()\n      );\n\n      if (remaining <= this.timing.getMinRemainingMsToStartAd()) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Not enough ad break time left (wall=${this.timing.getWallClockRemainingAdMs()}ms, budget=${this.timing.getDurationBudgetRemainingMs()}ms), stopping URL generation`);\n        }\n        break;\n      }\n\n      if (this.timing.isGamInCooldown()) {\n        if (this.debug) {\n          console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, stopping URL generation\");\n        }\n        break;\n      }\n\n      if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), stopping URL generation`);\n        }\n        break;\n      }\n\n      if (this.timing.totalAdRequestsInBreak >= this.timing.maxTotalAdRequestsPerBreak) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Maximum ad requests reached (${this.timing.maxTotalAdRequestsPerBreak}), stopping`);\n        }\n        break;\n      }\n\n      const maxQueueSize = 5;\n      if (this.adRequestQueue.length >= maxQueueSize) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] URL queue full (${this.adRequestQueue.length}), waiting...`);\n        }\n        await new Promise(resolve => setTimeout(resolve, 1000));\n        continue;\n      }\n\n      const newAdUrl = this.nextAdRequestUrl(baseVastUrl);\n\n      if (!newAdUrl || this.timing.failedVastUrls.has(newAdUrl) || this.timing.isUrlInCooldown(newAdUrl)) {\n        await new Promise(resolve => setTimeout(resolve, 500));\n        continue;\n      }\n\n      if (this.debug) {\n        const queuedUrlsPreview = [...this.adRequestQueue, newAdUrl];\n        console.log(\n          `[CONTINUOUS-FETCH] Queued VAST URL (queue size: ${queuedUrlsPreview.length})`,\n          { queuedUrls: queuedUrlsPreview }\n        );\n      }\n\n      this.adRequestQueue.push(newAdUrl);\n\n      const generationDelay = this.timing.consecutiveFailures > 0\n        ? Math.min(1000 * Math.pow(2, this.timing.consecutiveFailures), 5000)\n        : 500;\n      await new Promise(resolve => setTimeout(resolve, generationDelay));\n    }\n\n    this.continuousFetchLoopRunning = false;\n\n    if (this.debug) {\n      console.log(\n        `[CONTINUOUS-FETCH] URL generation loop ended (queued: ${this.adRequestQueue.length})`,\n        this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n      );\n    }\n  }\n\n  stopContinuousFetching(): void {\n    this.continuousFetchingActive = false;\n    this.continuousFetchLoopRunning = false;\n\n    this.placeholder.hide();\n\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] Stopping continuous ad fetching\");\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Ad iteration\n  // ───────────────────────────────────────────────────────────────\n\n  async tryNextAvailableAdWithRateLimit(): Promise<void> {\n    if (!this.inAdBreak) {\n      return;\n    }\n\n    const epoch = this.timing.adBreakEpoch;\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), ending ad break gracefully`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    const backoffMultiplier = Math.pow(2, this.timing.consecutiveFailures);\n    const backoffDelay = Math.min(this.timing.backoffBaseMs * backoffMultiplier, this.timing.maxBackoffMs);\n    const effectiveMinInterval = this.timing.minAdRequestIntervalMs + (this.timing.consecutiveFailures > 0 ? backoffDelay : 0);\n\n    const timeSinceLastRequest = Date.now() - this.timing.lastAdRequestTime;\n    if (timeSinceLastRequest < effectiveMinInterval) {\n      const waitTime = effectiveMinInterval - timeSinceLastRequest;\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Rate limiting: waiting ${waitTime}ms before next request (backoff: ${this.timing.consecutiveFailures} failures)`);\n      }\n      await new Promise(resolve => setTimeout(resolve, waitTime));\n    }\n\n    if (!this.inAdBreak || epoch !== this.timing.adBreakEpoch) {\n      return;\n    }\n\n    return this.tryNextAvailableAd(0);\n  }\n\n  private async tryNextAvailableAd(retryCount: number = 0): Promise<void> {\n    if (!this.inAdBreak) {\n      return;\n    }\n\n    const remaining = this.timing.getRemainingAdMs();\n\n    if (!this.timing.hasTimeToStartAnotherAd()) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Not enough time remaining (${remaining}ms) to start another ad, ending ad break`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) {\n        console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, ending ad break gracefully\");\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), ending ad break`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    this.timing.cleanupTemporaryFailures();\n\n    while (this.adRequestQueue.length > 0) {\n      const nextAdUrl = this.adRequestQueue.shift();\n\n      if (!nextAdUrl) continue;\n\n      if (this.timing.failedVastUrls.has(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping permanently-failed URL, trying next...\");\n        continue;\n      }\n\n      if (this.timing.isUrlInCooldown(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping URL in cooldown (recent no-fill), trying next...\");\n        continue;\n      }\n\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Requesting next ad via HLS ad player (${this.timing.currentAdIndex + 1}, ${this.adRequestQueue.length} remaining in queue)`);\n      }\n\n      try {\n        await this.playSingleAd(nextAdUrl);\n        this.timing.consecutiveFailures = 0;\n      } catch (error) {\n        const errorMessage = (error as Error).message;\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Ad request failed:\", errorMessage);\n\n        if (errorMessage.includes(\"ad_duration_exceeds_budget\")) {\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n\n        if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n          this.timing.consecutiveFailures++;\n        }\n\n        await this.tryNextAvailableAdWithRateLimit();\n      }\n      return;\n    }\n\n    const maxRetries = 3;\n    if (this.continuousFetchingActive && retryCount < maxRetries && remaining > 2000) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Queue empty, waiting for URLs... (${retryCount + 1}/${maxRetries})`);\n      }\n      await new Promise(resolve => setTimeout(resolve, 500));\n      await this.tryNextAvailableAd(retryCount + 1);\n      return;\n    }\n\n    if (!this.isShowingPlaceholder && remaining > 1000) {\n      this.showPlaceholderAndWaitForAds();\n    } else {\n      if (this.debug) console.log(\"[CONTINUOUS-FETCH] No more ads available, ending ad break\");\n      this.handleAdPodComplete();\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Single ad playback\n  // ───────────────────────────────────────────────────────────────\n\n  async playSingleAd(vastTagUrl: string): Promise<void> {\n    const adPlayer = this.host.getAdPlayer();\n    if (adPlayer.isAdPlaying()) return;\n\n    if (this.timing.failedVastUrls.has(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping permanently-failed VAST URL:\", vastTagUrl);\n      throw new Error(\"VAST URL permanently failed\");\n    }\n\n    if (this.timing.isUrlInCooldown(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping URL in cooldown (recent no-fill):\", vastTagUrl);\n      throw new Error(\"VAST URL in cooldown after no-fill\");\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.warn(\"[AD-ERROR] Too many consecutive failures, not requesting more ads\");\n      throw new Error(\"Too many consecutive failures\");\n    }\n\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) console.warn(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping ad request\");\n      throw new Error(\"GAM in cooldown\");\n    }\n\n    this.recreateAdController();\n\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      const ap = this.host.getAdPlayer();\n      await ap.requestAds(vastTagUrl);\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: vastTagUrl, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      this.timing.clearAdRequestWatchdog();\n\n      if (this.timing.activeAdRequestToken !== requestToken) return;\n\n      if (!this.timing.ensureLoadedAdFitsBudget(ap)) {\n        this.timing.rejectLoadedAdForDuration(ap);\n        this.recreateAdController();\n        throw new Error(\"ad_duration_exceeds_budget\");\n      }\n\n      try {\n        this.timing.startAdFailsafeTimer(requestToken);\n        await ap.play();\n        this.timing.markAdStarted();\n\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n\n        ap.setAdVolume(getAdAudioVolume(ap));\n        this.timing.consecutiveFailures = 0;\n        this.timing.temporaryFailureUrls.delete(vastTagUrl);\n      } catch (playError) {\n        if (this.debug) console.error(\"[AD-ERROR] Failed to play ad:\", playError);\n\n        if (this.timing.isTemporaryAdError(playError as Error)) {\n          this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());\n          if (this.debug) console.log(\"[AD-ERROR] Temporary play error - URL can be retried after cooldown\");\n        } else {\n          this.timing.failedVastUrls.add(vastTagUrl);\n          if (this.debug) console.log(\"[AD-ERROR] Permanent play error - URL blacklisted\");\n        }\n\n        this.timing.clearAdFailsafeTimer();\n        if (this.timing.activeAdRequestToken === requestToken) {\n          this.timing.activeAdRequestToken = null;\n        }\n        throw playError;\n      }\n    } catch (error) {\n      const errorMessage = (error as Error)?.message || \"\";\n      if (this.debug) console.error(\"[AD-ERROR] Ad request failed:\", errorMessage);\n\n      if (this.timing.isTemporaryAdError(error as Error)) {\n        this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());\n        if (this.debug) console.log(\"[AD-ERROR] Temporary error (no-fill/timeout) - URL can be retried after cooldown\");\n      } else {\n        this.timing.failedVastUrls.add(vastTagUrl);\n        if (this.debug) console.log(\"[AD-ERROR] Permanent error - URL blacklisted:\", errorMessage);\n      }\n\n      this.timing.clearAdRequestWatchdog();\n      this.timing.clearAdFailsafeTimer();\n      if (this.timing.activeAdRequestToken === requestToken) {\n        this.timing.activeAdRequestToken = null;\n      }\n      throw error;\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Placeholder wait\n  // ───────────────────────────────────────────────────────────────\n\n  private async showPlaceholderAndWaitForAds(): Promise<void> {\n    const remaining = this.timing.getRemainingAdMs();\n    const waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);\n\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping placeholder wait\");\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping placeholder - too many consecutive failures\");\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (waitTime < 1000) {\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.debug) {\n      console.log(`[CONTINUOUS-FETCH] Showing placeholder for ${waitTime}ms while waiting for ad URLs`);\n    }\n\n    this.isShowingPlaceholder = true;\n    this.host.getAdPlayer().showPlaceholder();\n\n    const checkInterval = 300;\n    const maxChecks = Math.floor(waitTime / checkInterval);\n\n    for (let i = 0; i < maxChecks; i++) {\n      await new Promise(resolve => setTimeout(resolve, checkInterval));\n\n      if (!this.inAdBreak) return;\n\n      if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Too many failures during placeholder wait\");\n        break;\n      }\n\n      if (!this.timing.hasTimeToStartAnotherAd()) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Not enough time remaining during placeholder wait, ending ad break\");\n        break;\n      }\n\n      while (this.adRequestQueue.length > 0) {\n        if (!this.timing.hasTimeToStartAnotherAd()) break;\n\n        const nextAdUrl = this.adRequestQueue.shift();\n        if (!nextAdUrl) continue;\n        if (this.timing.failedVastUrls.has(nextAdUrl)) continue;\n        if (this.timing.isUrlInCooldown(nextAdUrl)) continue;\n\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Ad URL available, requesting via HLS ad player\");\n\n        this.isShowingPlaceholder = false;\n        this.host.getAdPlayer().hidePlaceholder();\n\n        try {\n          await this.playSingleAd(nextAdUrl);\n          this.timing.consecutiveFailures = 0;\n        } catch (error) {\n          const errorMessage = (error as Error).message;\n          if (errorMessage.includes(\"ad_duration_exceeds_budget\")) {\n            await this.tryNextAvailableAdWithRateLimit();\n            return;\n          }\n          if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n            this.timing.consecutiveFailures++;\n          }\n          await this.tryNextAvailableAdWithRateLimit();\n        }\n        return;\n      }\n    }\n\n    if (this.debug) console.log(\"[CONTINUOUS-FETCH] Placeholder timeout, ending ad break\");\n\n    this.isShowingPlaceholder = false;\n    this.host.getAdPlayer().hidePlaceholder();\n    this.handleAdPodComplete();\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Ad break completion\n  // ───────────────────────────────────────────────────────────────\n\n  handleAdPodComplete(): void {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Ad pod complete - cleaning up\");\n    }\n\n    this.timing.resetForBreakEnd();\n\n    this.stopContinuousFetching();\n    this.clearPendingAdBreak();\n\n    if (this.isShowingPlaceholder) {\n      this.host.getAdPlayer().hidePlaceholder();\n      this.isShowingPlaceholder = false;\n    }\n\n    this.adRequestQueue = [];\n\n    this.inAdBreak = false;\n    this.adDetectSentForCurrentBreak = false;\n    this.cueManager.activeScte35BreakKey = undefined;\n    this.cueManager.scheduledScte35BreakKey = undefined;\n    this.adPodQueue = [];\n    this.showAds = false;\n\n    this.host.getAdPlayer().stop().catch(() => {});\n\n    const restoredMuted = this.host.getAdPlayer().getOriginalMutedState();\n    const restoredVolume = this.host.getAdPlayer().getOriginalVolume();\n\n    if (this.host.video.muted !== restoredMuted) {\n      this.host.video.muted = restoredMuted;\n    }\n    if (Math.abs(this.host.video.volume - restoredVolume) > 0.01) {\n      this.host.video.volume = restoredVolume;\n    }\n\n    if (this.host.shouldContinueLiveStreamDuringAds()) {\n      const liveSyncPos = this.host.getLiveSyncPosition();\n      if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {\n        if (this.debug) {\n          console.log(\n            `[StormcloudVideoPlayer] Live break end — snapping to live edge: ${this.host.video.currentTime.toFixed(2)}s → ${liveSyncPos.toFixed(2)}s`\n          );\n        }\n        this.host.video.currentTime = liveSyncPos;\n      }\n\n      if (this.host.video.paused) {\n        if (this.debug) console.log(\"[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback\");\n        this.host.video.play()?.catch(() => {});\n      } else {\n        if (this.debug) console.log(\"[StormcloudVideoPlayer] Content video already playing in live mode after ads\");\n      }\n    } else if (this.host.video.paused) {\n      this.host.video.play()?.catch(() => {});\n    }\n  }\n\n  handleAdFailure(): void {\n    this.timing.consecutiveFailures++;\n    this.timing.recordGamNoFill();\n    const remaining = this.timing.getRemainingAdMs();\n\n    if (this.debug) {\n      console.log(\n        `[CONTINUOUS-FETCH] Ad failure: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}, consecutiveFailures=${this.timing.consecutiveFailures}`,\n        this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n      );\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.log(`[CONTINUOUS-FETCH] Max consecutive failures reached (${this.timing.consecutiveFailures}), ending ad break gracefully`);\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.hasTimeToStartAnotherAd()) {\n      this.tryNextAvailableAdWithRateLimit();\n    } else {\n      if (this.debug) console.log(\"[AD-ERROR] Ad failed and not enough time remaining for another ad. Failed URLs:\", this.timing.failedVastUrls.size);\n      this.handleAdPodComplete();\n    }\n  }\n}\n"]}