{"version":3,"file":"PlayerComponent-D_Vp2_gr.mjs","names":[],"sources":["../src/components/composable/player/usePlayerLive.ts","../src/helper/loadScript.ts","../src/components/composable/player/usePlayerVast.ts","../src/components/composable/player/usePlayerStitching.ts","../src/components/composable/player/usePlayerTranscript.ts","../src/stores/class/securisation/privateOrganisation.ts","../src/components/composable/player/usePlayerLogic.ts","../src/components/misc/player/PlayerComponent.vue","../src/components/misc/player/PlayerComponent.vue"],"sourcesContent":["import stringHelper from \"../../../helper/stringHelper\";\nimport { usePlayerLogicProgress } from \"./usePlayerLogicProgress\";\nimport { computed, Ref, ref } from \"vue\";\nimport { usePlayerStore, PlayerStatus } from \"../../../stores/PlayerStore\";\nimport { useApiStore } from \"../../../stores/ApiStore\";\nimport dayjs from \"dayjs\";\nimport { useAuthStore } from \"../../../stores/AuthStore\";\n/* eslint-disable*/\nlet Hls:any = null;\n/* eslint-enable*/\nconst maxMinutesSessionId = 1;\nexport const usePlayerLive = (hlsReady: Ref<boolean>)=>{\n\n  const { listenTime, initLiveDownloadId, setDownloadId, onTimeUpdateProgress } = usePlayerLogicProgress();\n\n  const audioElement: Ref<HTMLAudioElement | null>= ref(null);\n  const hls: Ref<any>= ref(null);\n  const hlsRetryTimeout: Ref<ReturnType<typeof setTimeout> | undefined>= ref(undefined);\n  const playPromise: Ref<Promise<void>|undefined>= ref(undefined);\n  const errorHls= ref(false);\n\n\n  const playerStore = usePlayerStore();\n  const apiStore = useApiStore();\n  const authStore = useAuthStore();\n\n  function needToAddToken(url: string): boolean { \n    if (authStore.authParam.accessToken && (\"SECURED\" === playerStore.playerLive?.organisation?.privacy || playerStore.playerRadio?.secured)) {\n      const baseDomain = apiStore.frontendUrl.replace(/^https?:\\/\\//, '');\n      // Add token only if request is on same domain\n      return url.includes(baseDomain);\n    }\n    return false;\n  }\n\n  function onPlay(): void {\n    playerStore.playerChangeStatus(PlayerStatus.PAUSED === playerStore.playerStatus);\n  }\n\n  function playRadio() {\n    if (!playerStore.playerRadio) {\n      return;\n    }\n    handleSessionIdRadio();\n    playerStore.playerUpdatePlayerHlsUrl(playerStore.playerRadio.url+\"?origin=octopus&sessionId=\"+playerStore.playerRadio.sessionId);\n    playHls();\n  }\n\n  function handleSessionIdRadio(){\n    if(!playerStore.playerRadio) {\n      return;\n    }\n    if(playerStore.playerRadio.sessionId && dayjs().diff(dayjs(playerStore.playerRadio.dateSessionId), 'm')<maxMinutesSessionId){\n      return;\n    }\n    playerStore.playerRadio.sessionId = stringHelper.uuidv4();\n  }\n\n  function playLive() {\n    if (!playerStore.playerHlsIdentifier) {\n      return;\n    }\n    playerStore.playerUpdatePlayerHlsUrl(`${apiStore.hlsUrl}live/${playerStore.playerHlsIdentifier}/index.m3u8`);\n    playHls();\n  }\n\n  async function playHls(): Promise<void> {\n    try {\n      if(null===audioElement.value){\n        audioElement.value = document.getElementById(\"audio-player\") as HTMLAudioElement;\n      }\n      if (null === audioElement.value || !playerStore.playerHlsUrl) {\n        setTimeout(playHls, 1000);\n        return;\n      }\n      const ua = navigator.userAgent.toLowerCase();\n      const isAndroid = ua.indexOf(\"android\") > -1; //&& ua.indexOf(\"mobile\");\n      const isChrome = ua.indexOf(\"chrome\") > -1;\n      if (\n        audioElement.value.canPlayType(\"application/vnd.apple.mpegurl\") &&\n        !isChrome &&\n        !isAndroid\n      ) {\n        let url = playerStore.playerHlsUrl;\n        if(needToAddToken(url)) {\n          if (url.includes('?')) {\n            url += \"&access_token=\"+authStore.authParam.accessToken;\n          } else {\n            url += \"?access_token=\"+authStore.authParam.accessToken;\n          }\n        }\n        audioElement.value.src = url;\n        await initLiveDownloadId();\n        hlsReady.value = true;\n        await audioElement.value.play();\n        onPlay();\n      } else {\n        await initHls();\n      }\n    } catch(e) {\n      console.error(e);\n      onHlsError();\n    }\n  }\n\n  function onHlsError(){\n    if(\"STOPPED\"!==playerStore.playerStatus && undefined===hlsRetryTimeout.value){\n      hlsRetryTimeout.value = setTimeout(() => {\n        errorHls.value = false;\n        playHls();\n        hlsRetryTimeout.value = undefined;\n      }, 5000);\n    }\n  }\n\n  async function initHls() {\n    if (null === Hls) {\n      await import(\"hls.js\").then((hlsLibrary) => {\n        Hls = hlsLibrary.default;\n      });\n    }\n    if (!Hls.isSupported()) {\n      throw new Error(\"Hls is not supported ! \");\n    }\n    hls.value = new Hls({\n      autoStartLoad: true,\n      liveDurationInfinity:true,\n      backBufferLength:10,\n      maxBufferLength:60,\n\n      xhrSetup: (xhr: XMLHttpRequest, url: string) => {\n        if (needToAddToken(url)) {\n          xhr.setRequestHeader(\"Authorization\", \"Bearer \" +authStore.authParam.accessToken);\n        }\n      }\n    });\n    hls.value.on(Hls.Events.MANIFEST_PARSED, async () => {\n      await initLiveDownloadId();\n      hlsReady.value = true;\n      if(true===errorHls.value){\n        return;\n      }\n      setTimeout(() => {\n        playPromise.value = (audioElement.value as HTMLAudioElement).play();\n        playPromise.value.then(() =>{\n          playPromise.value = undefined;\n          onPlay();\n        }).catch((e)=>{\n          console.error(e);\n          onHlsError();\n          playPromise.value = undefined;\n        });\n      }, 500);\n    });\n    hls.value.on(Hls.Events.ERROR, async (name: string, data:any) => {\n      // Stalling, we don't have enough data\n      if (data.details === 'bufferStalledError') {\n        // Some logs to be able to follow what's happening\n        console.warn('playback is stalling…');\n        playerStore.playerStatus = PlayerStatus.LOADING;\n        // Destroy current instance\n        hls.value.destroy();\n        // Wait a bit before restarting playback\n        setTimeout(initHls, 500);\n        return;\n      }\n      console.error('An error occured: ' + name + ' / ' + data.details);\n      console.error(data);\n      if (data.fatal && data.type === Hls.ErrorTypes.MEDIA_ERROR) {\n        console.warn('Trying to recover...');\n        hls.value.recoverMediaError();\n      }\n      errorHls.value = true;\n      if(undefined===playPromise.value && data.fatal){\n        onHlsError();\n      }\n    });\n    hls.value.loadSource(playerStore.playerHlsUrl);\n    hls.value.attachMedia(audioElement.value as HTMLAudioElement);\n  }\n\n  async function endingLive(): Promise<void> {\n    clearTimeout(hlsRetryTimeout.value);\n    hlsRetryTimeout.value = undefined;\n    if(null===audioElement.value){\n      return;\n    }\n    audioElement.value = null;\n    const audio: HTMLElement | null = document.getElementById(\"audio-player\");\n    if (audio && hls.value) {\n      hls.value.destroy();\n      hls.value = null;\n    }else{\n      (audio as HTMLAudioElement).pause();\n    }\n    (audio as HTMLAudioElement).src = \"\";\n  }\n\n\treturn {\n    listenTime,\n    setDownloadId,\n    onTimeUpdateProgress,\n    playLive,\n    endingLive,\n    playRadio,\n    onPlay\n\t}\n}\n","function loadScript(src: string, async:boolean, callback: (isLoaded:boolean) => void) {\n  const firstElement = document.getElementsByTagName('head')[0] || document.documentElement,\n  scriptElement = document.createElement('script');\n  scriptElement.type = 'text/javascript';\n  scriptElement.src = src;\n  scriptElement.async = async;\n  scriptElement.addEventListener('load', function() {\n    if(callback && typeof callback === 'function') {\n      callback(true);\n    }\n  }, false);\n  scriptElement.addEventListener('error', function() {\n    firstElement.removeChild(scriptElement);\n    if(callback && typeof callback === 'function') {\n      callback(false);\n    }\n  }, false);\n  firstElement.insertBefore(scriptElement, firstElement.firstChild);\n}\nexport {\n  loadScript\n}\n","import { usePlayerStore } from \"../../../stores/PlayerStore\";\nimport { useVastStore } from \"../../../stores/VastStore\";\nimport { loadScript } from \"../../../helper/loadScript\";\nimport {nextTick, Ref, ref, watch} from 'vue';\nimport dayjs from \"dayjs\";\nlet adsLoader: google.ima.AdsLoader;\nlet adsManager:google.ima.AdsManager;\nlet adDisplayContainer:google.ima.AdDisplayContainer;\nlet adsRequest: google.ima.AdsRequest;\nexport const usePlayerVast = ()=>{\n  const imaLoaded = ref(false);\n  const isContentFinished = ref(false);\n  const audioContainer : Ref<HTMLAudioElement|null>= ref(null);\n  const isAdRequested = ref(false);\n  const statusPlayerWhenLoaded = ref(\"\");\n  const dateForSessionId: Ref<string|undefined> = ref(undefined);\n\n  const playerStore = usePlayerStore();\n  const vastStore = useVastStore();\n\n  watch(() => vastStore.isAdPaused, () => {onAdChangePlayingStatus();});\n  watch(() => vastStore.isAdSkipped, () => {onAdSkipped();});\n\n  function prepareIMA(){\n    if(!imaLoaded.value){\n      imaLoaded.value = true;\n      loadIMA();\n    }else{\n      initializeIMA();\n    }\n  }\n\n  function loadIMA(){\n    loadScript('//imasdk.googleapis.com/js/sdkloader/ima3.js', true, (isIMALoaded:boolean) => {\n      if(isIMALoaded) {\n        initializeIMA();\n      }\n    });\n  }\n\n  function initializeIMA(): void {\n    console.log(\"Initialize IMA\");\n    initializeDisplayContainer();\n    if(!adDisplayContainer || !adsLoader){\n      return;\n    }\n  }\n\n  function onRequestAd(vastUrl: string){\n    isAdRequested.value = true;\n    console.log(\"Request ad \"+vastUrl);\n    initializeAdsRequest(vastUrl);\n    adsLoader.requestAds(adsRequest);\n  }\n\n  function initializeDisplayContainer():void{\n    if(adDisplayContainer){return};\n    audioContainer.value = (document.getElementById('audio-player') as HTMLAudioElement); \n    if(null===audioContainer.value){return;}\n    adDisplayContainer = new google.ima.AdDisplayContainer(document.getElementById('ad-container'), audioContainer.value);\n    adDisplayContainer.initialize();\n    initializeAdsLoader();\n  }\n\n  function initializeAdsLoader():void{\n    adsLoader = new google.ima.AdsLoader(adDisplayContainer);\n    adsManager = null;\n    adsLoader.addEventListener(\n      google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,\n      onAdsManagerLoaded,\n      false\n    );\n    adsLoader.addEventListener(\n      google.ima.AdErrorEvent.Type.AD_ERROR,\n      onAdError,\n      false\n    );\n  }\n\n  function initializeAdsRequest(vastUrl: string):void{\n    adsRequest = new google.ima.AdsRequest();\n    adsRequest.setAdWillAutoPlay(true);\n    adsRequest.adTagUrl = vastUrl;\n  }\n\n  function onAdsManagerLoaded(adsManagerLoadedEvent: google.ima.AdsManagerLoadedEvent) {\n    const adsRenderingSettings = new google.ima.AdsRenderingSettings();\n    adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true;\n    adsManager = adsManagerLoadedEvent.getAdsManager(audioContainer.value, adsRenderingSettings);\n    startAdManager();\n  }\n\n  function startAdManager(){\n    console.log(\"Start manager\");\n    initAdManagerEvents();\n    try {\n      adsManager.init(0, 0, google.ima.ViewMode.NORMAL);\n      adsManager.start();\n    } catch (adError) {\n      console.log(adError);\n      playerStore.playerChangeStatus(false);\n      destroyAdManager();\n    }\n  }\n\n  function initAdManagerEvents(){\n    adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR,onAdError);\n    adsManager.addEventListener(google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested);\n    adsManager.addEventListener(google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested);\n    const events = [\n      google.ima.AdEvent.Type.ALL_ADS_COMPLETED, google.ima.AdEvent.Type.AD_PROGRESS,\n      google.ima.AdEvent.Type.COMPLETE, google.ima.AdEvent.Type.LOADED, \n      google.ima.AdEvent.Type.PAUSED, google.ima.AdEvent.Type.STARTED,\n    ];\n    for (const index in events) {\n      adsManager.addEventListener(events[index], onAdEvent);\n    }\n  }\n\n  function onAdError(adErrorEvent: google.ima.AdErrorEvent) {\n    console.log(adErrorEvent.getError());\n    destroyAdManager();\n  }\n\n  function destroyAdManager(){\n    if(!adsManager){return;}\n    console.log(\"Destroy manager\");\n    adsManager?.destroy();\n    adsManager = null;\n    vastStore.restartVastData();\n    isContentFinished.value =false;\n    isAdRequested.value = false;\n  }\n\n  function onAdEvent(adEvent: google.ima.AdEvent) {\n    const ad = adEvent.getAd();\n    if(ad){\n      vastStore.updateCurrentAd(ad);\n    }\n    switch (adEvent.type) {\n      case google.ima.AdEvent.Type.LOADED:\n        statusPlayerWhenLoaded.value = playerStore.playerStatus;\n        if (!ad.isLinear()) {\n          playerStore.playerChangeStatus(false);\n          isAdRequested.value = false;\n        }\n        break;\n      case google.ima.AdEvent.Type.STARTED:\n        console.log(\"Launched status : \"+statusPlayerWhenLoaded.value);\n        if(\"PLAYING\"!==statusPlayerWhenLoaded.value){\n          vastStore.updateIsAdPaused(true);\n          adsManager.pause();\n        }\n        break;\n      case google.ima.AdEvent.Type.AD_PROGRESS:{\n        isAdRequested.value = false;\n        const adProgressData = adEvent.getAdData();\n        vastStore.updateProgressionData(adProgressData.duration,adProgressData.currentTime);\n        vastStore.updateSkippableData(\n          vastStore.currentAd.getSkipTimeOffset()!== -1,\n          adsManager.getAdSkippableState(),\n          Math.ceil(vastStore.currentAd.getSkipTimeOffset() - adProgressData.currentTime));\n        break;\n      }\n    }\n  }\n\n  function onContentPauseRequested() {\n    vastStore.updateIsAdPlaying(true);\n    playerStore.playerChangeStatus(true);\n  }\n\n  function onContentResumeRequested() {\n    if (!isContentFinished.value) {\n      playerStore.playerChangeStatus(false);\n    }\n    nextTick(() => {\n      vastStore.updateIsAdPlaying(false);\n      vastStore.updateResetSessionId(false);\n    });\n  }\n\n  function contentEndedAdsLoader():void{\n    if (vastStore.isAdPlaying) return;\n    isContentFinished.value = true;\n    adsLoader?.contentComplete();\n  }\n\n  function onAdChangePlayingStatus(){\n    if(!adsManager){return;}\n    if(vastStore.isAdPaused){\n      adsManager.pause();\n      dateForSessionId.value = dayjs().toISOString();\n    }else{\n      adsManager.resume();\n      if(!vastStore.resetSessionId &&dayjs().diff(dayjs(dateForSessionId.value), 'm')>1){\n        vastStore.updateResetSessionId(true);\n      }\n    }\n  }\n\n  function onAdSkipped(){\n    if(vastStore.isAdSkipped){\n      adsManager.skip();\n    }\n  }\n\n\n\treturn {\n    isAdRequested,\n    prepareIMA,\n    onRequestAd,\n    destroyAdManager,\n    contentEndedAdsLoader\n\t}\n}\n","import { usePlayerStore } from \"../../../stores/PlayerStore\";\nimport { useVastStore } from \"../../../stores/VastStore\";\nimport { useSaveFetchStore } from \"../../../stores/SaveFetchStore\";\nimport { usePlayerVast } from \"./usePlayerVast\";\nimport fetchHelper from \"../../../helper/fetchHelper\";\n\nimport {computed, onMounted, Ref, ref, watch} from 'vue';\nimport { useRoute } from \"vue-router\";\nimport dayjs from \"dayjs\";\nimport classicApi from \"../../../api/classicApi\";\nimport { AdserverOtherEmission } from \"@/stores/class/adserver/adserverOtherEmission\";\nimport { AdPosition } from \"@/stores/class/adserver/adPosition\";\nimport { AdserverTiming } from \"@/stores/class/adserver/adserverTiming\";\n\nexport const usePlayerStitching = ()=>{\n\n  const { isAdRequested, prepareIMA, onRequestAd,destroyAdManager, contentEndedAdsLoader } = usePlayerVast();\n\n  const radioInterval : Ref<ReturnType<typeof setTimeout> | undefined> = ref(undefined);\n\n  const route = useRoute()\n  const playerStore = usePlayerStore();\n  const vastStore = useVastStore();\n  const saveFetchStore= useSaveFetchStore();\n\n  const radioNextAdvertisingStartDate = computed(() => { \n    return playerStore.playerRadio?.nextAdvertising?.startDate;\n  });\n\n\n  watch(() => playerStore.playerCurrentChange, () => {\n    if(playerStore.playerCurrentChange && playerStore.playerCurrentChange > 0 && !checkUsePlayerPodcastStitching()){return;}\n    onPlayerChange();\n  });\n\n  //launch advertising for podcast\n  watch(() => playerStore.playerElapsedSeconds, () => {\n    if(!checkUsePlayerPodcastStitching()){return;}\n    if(!isAdRequested.value && checkAdNeedToBeLaunch()){\n      onRequestAd(vastStore.adPositionsPodcasts[playerStore.playerCurrentChange??0][vastStore.adPositionIndex].vastUrl);\n      vastStore.updateAdPositionIndex(vastStore.adPositionIndex+1); \n    }\n  });\n\n  // launch advertising for radio\n  watch(radioNextAdvertisingStartDate, () => {\n    if(!radioNextAdvertisingStartDate.value){\n      return;\n    }\n    defineRadioInterval();\n  }, { immediate: true });\n\n\n  onMounted(() => {\n    vastStore.updateuseVastPlayerPodcast(\"true\"===route.query.vast);\n  })\n\n  function checkUsePlayerPodcastStitching():boolean{\n    return vastStore.useVastPlayerPodcast;\n  }\n\n  function defineRadioInterval(){\n    clearRadioInterval();\n    const timeRemaining = dayjs(radioNextAdvertisingStartDate.value).diff(dayjs(), \"millisecond\");\n    console.log(\"TimeRemaining \"+timeRemaining);\n    if(timeRemaining < 0){\n      return;\n    }\n    radioInterval.value = setTimeout(() => {\n      radioIntervalExecute();\n    }, timeRemaining);\n  }\n\n  async function radioIntervalExecute(){\n    //If pause when ad needs to be played then skipped (TO THINK)\n    if(\"PAUSED\"===playerStore.playerStatus){return;}\n    const vastUrl = await getVastUrl(playerStore.playerRadio?.nextAdvertising?.tag ??\"5e385e1b51c86\", playerStore.playerRadio?.nextAdvertising?.adCount ?? 1);\n    console.log(\"vastUrl \"+vastUrl);\n    onRequestAd(vastUrl);\n  }\n\n  function clearRadioInterval() {\n    clearInterval(radioInterval.value as unknown as number);\n    radioInterval.value = undefined;\n  }\n\n  function checkAdNeedToBeLaunch(){\n    if(!playerStore.playerCurrentChange || !vastStore.adPositionsPodcasts[playerStore.playerCurrentChange]?.[vastStore.adPositionIndex]){return false;}\n    return vastStore.adPositionsPodcasts[playerStore.playerCurrentChange][vastStore.adPositionIndex]?.seconds <= playerStore.playerElapsedSeconds;\n  }\n\n  async function onPlayerChange(){\n    destroyAdManager();\n    if(null==playerStore.playerCurrentChange){return;}\n    prepareIMA();\n    await fetchPodcastAdConfig();\n  }\n\n  async function fetchPodcastAdConfig(){\n    if(!playerStore.playerCurrentChange || !playerStore.playerPodcast ||(playerStore.playerCurrentChange && vastStore.adPositionsPodcasts[playerStore.playerCurrentChange])){\n      return;\n    }\n    const adserverConfig = await classicApi.fetchData<AdserverOtherEmission>({\n      api:0,\n      path: `ad/test/podcast/${playerStore.playerCurrentChange}`,\n      isNotAuth:true\n    });\n    if(!adserverConfig || \"SOUNDCAST_VAST\"!==adserverConfig.config?.server){\n      vastStore.updateAdPositionsPodcasts(playerStore.playerCurrentChange, []);\n      return;\n    }\n    const podcastDurationSeconds = Math.round((playerStore.playerPodcast?.duration??0) / 1000);\n    const allAdPositions =generateAllAdPositions(adserverConfig.config.doublets, podcastDurationSeconds);\n    const selectedAdPositions = await selectCorrectAdPositions(allAdPositions, podcastDurationSeconds, adserverConfig.config.minIntervalDuration, adserverConfig.config.minTailDuration);\n    vastStore.updateAdPositionsPodcasts(playerStore.playerCurrentChange, selectedAdPositions);\n  }\n\n  function generateAllAdPositions(doublets: Array<AdserverTiming>, podcastDuration: number): Array<AdPosition>{\n    const adPositions: Array<AdPosition> = [];\n    if(doublets.some((element: AdserverTiming)=>{return \"TAG_NO_AD\"===element.tag})){\n      return [];\n    }\n    for (const doublet of doublets) {\n      if(!doublet.tag){continue;}\n      let seconds = 0;\n      if(\"post\"===doublet.timing.insertion){\n        seconds = podcastDuration;\n      }else if(\"mid\"===doublet.timing.insertion){\n        const mesure = doublet.timing.mesure ?? 0;\n        switch (doublet.timing.unit){\n          case \"MILLISECOND\": seconds = mesure * 1000; break;\n          case \"MINUTE\": seconds = Math.round(mesure / 60); break;\n          case \"PERCENT\": seconds = Math.round((mesure * podcastDuration) / 100); break;\n          default: seconds = mesure; break;\n        }\n      }\n      adPositions.push({\n        impressId: doublet.tag,\n        policy: doublet.timing.insertion,\n        seconds: seconds,\n        vastUrl: \"\"\n      });\n    }\n    return adPositions.sort((a: AdPosition, b: AdPosition) => {\n      if (a.seconds > b.seconds) {\n        return 1;\n      }\n      return b.seconds > a.seconds ? -1 : 0;\n    });\n  }\n\n  async function selectCorrectAdPositions(allAdPositions: Array<AdPosition>, podcastDuration: number, minIntervalDuration:number, minTailDuration:number): Promise<Array<AdPosition>>{\n    const adPositions: Array<AdPosition> = [];\n    let previousPosition = -1;\n    for(const adPosition of allAdPositions){\n      switch (adPosition.policy) {\n        case \"pre\":\n          adPositions.push(await defineVastUrl(adPosition));\n          previousPosition = 0;\n          break;\n        case \"mid\":\n          if (adPosition.seconds > podcastDuration - minTailDuration) {\n            //Too close to end\n            continue;\n          }\n          if (previousPosition >= 0 && adPosition.seconds < previousPosition + minIntervalDuration) {\n            //Too close to previous ad\n            continue;\n          }\n          adPositions.push(await defineVastUrl(adPosition));\n          previousPosition = adPosition.seconds;\n          break;\n        case \"post\":\n          if (previousPosition >= 0 && previousPosition > podcastDuration - minIntervalDuration) {\n            //Too close to previous ad\n            continue;\n          }\n          adPositions.push(await defineVastUrl(adPosition));\n          break;\n        default:break;\n      }\n    }\n    return adPositions;\n  }\n\n  async function defineVastUrl(adPosition: AdPosition): Promise<AdPosition>{\n    adPosition.vastUrl = await getVastUrl(adPosition.impressId, 1);\n    return adPosition;\n  }\n\n  async function getVastUrl(tag: string, adCount: number): Promise<string>{\n    const baseUrl = \"https://api.soundcast.io/v1/vast/\"+tag;\n    let keywords: Array<string> = [];\n    if(playerStore.playerPodcast?.tags?.length){\n      const attributes = await saveFetchStore.getOrgaAttributes(playerStore.playerPodcast.organisation.id);\n      if (\"true\"===attributes[\"AD_CONFIG_PODCAST_TAG\"]) {\n        keywords = playerStore.playerPodcast.tags.map((e) => {\n          return \"tag:\" + e;\n        });\n      }\n    }\n    const parameters = fetchHelper.getUriSearchParams({\n      adCount: adCount ?? 1,\n      pageUrl:document.referrer,\n      keywords:keywords\n    });\n    return baseUrl + '?' + parameters.toString();\n  }\n\n\treturn {\n    contentEndedAdsLoader\n\t}\n}\n","import { usePlayerStore } from \"../../../stores/PlayerStore\";\nimport { useVastStore } from \"../../../stores/VastStore\";\nimport classicApi from \"../../../api/classicApi\";\nimport { AdserverOtherEmission } from \"@/stores/class/adserver/adserverOtherEmission\";\nimport { useTranslation } from \"../useTranslation\";\nimport { transcriptionApi } from \"../../../api/transcriptionApi\";\nimport { ref } from \"vue\";\n\n/** Contains the language of the transcript being generated */\nconst generatingTranscriptLanguage = ref<string|null>(null);\n\nexport const usePlayerTranscript = ()=>{\n\n  const playerStore = usePlayerStore();\n  const vastStore = useVastStore();\n  const { getMostRelevantLanguage } = useTranslation();\n\n  async function checkDelaytWithStitching(){\n    playerStore.playerUpdateDelayStitching(0);\n    if(vastStore.useVastPlayerPodcast){\n      return;\n    }\n\n    const audioPlayer = document.querySelector(\"#audio-player\") as HTMLAudioElement;\n    if (!playerStore.playerTranscript || !audioPlayer || !playerStore.playerPodcast ||\n      audioPlayer.duration <= playerStore.playerPodcast.duration / 1000 + 5) {\n      return;\n    }\n\n    const adserverConfig = await classicApi.fetchData<AdserverOtherEmission>({\n      api:0,\n      path:`ad/test/podcast/${playerStore.playerPodcast.podcastId}`,\n      isNotAuth:true\n    });\n\n    // In case of midroll ads, we can't properly display transcription, so\n    // we disable it.\n    const hasOtherThanPreOrPost = adserverConfig.config.doublets\n      .filter(doublet => !([\"pre\", \"post\"].includes(doublet.timing.insertion)))\n      .length > 0;\n    if (hasOtherThanPreOrPost) {\n      console.warn(\"This episode's ad settings doesn't allow for transcription\");\n      playerStore.playerUpdateChaptering();\n      playerStore.playerUpdateTranscript();\n      return;\n    }\n\n    // In case of preroll ads, delay start of transcription\n    const hasPre = adserverConfig.config.doublets\n      .filter(doublet => doublet.timing.insertion === \"pre\")\n      .length > 0;\n    if(hasPre) {\n      // Since we have the expected time (from playerStore) and effective time\n      // (from audioPlayer, which include ads), we just delay by the delta\n      playerStore.playerUpdateDelayStitching( audioPlayer.duration - (playerStore.playerPodcast.duration / 1000));\n    }\n  }\n\n  async function getTranscription(): Promise<void> {\n    generatingTranscriptLanguage.value = null;\n    if (!playerStore.playerPodcast) {\n      playerStore.playerUpdateTranscript();\n      return;\n    }\n\n    // Retrieve best language for transcription\n    const podcastId = playerStore.playerPodcast.podcastId;\n    const translationData = await transcriptionApi.getTranslations(podcastId);\n    const { ready, available } = await getMostRelevantLanguage(translationData);\n\n    // Retrieve transcription\n    const result = await transcriptionApi.getTranslation(podcastId, ready);\n\n    const arrayTranscript = parseSrt(result);\n    const actualText =\n      arrayTranscript?.[0]?.startTime === 0 ? arrayTranscript[0].text : \"\";\n    if(!arrayTranscript){\n      return;\n    }\n    playerStore.playerUpdateTranscript({\n      actual: 0,\n      actualText: actualText,\n      value: arrayTranscript\n    });\n\n    if (available !== undefined && ready !== available) {\n      generatingTranscriptLanguage.value = available;\n\n      // If there's a better language available, trigger its generation\n      const result = await transcriptionApi.getTranslation(podcastId, available, true);\n\n      const arrayTranscript = parseSrt(result);\n      const actualText =\n        arrayTranscript?.[0]?.startTime === 0 ? arrayTranscript[0].text : \"\";\n      if(!arrayTranscript){\n        return;\n      }\n      playerStore.playerUpdateTranscript({\n        actual: playerStore.playerTranscript?.actual,\n        actualText: actualText,\n        value: arrayTranscript\n      });\n      generatingTranscriptLanguage.value = null;\n    }\n  }\n\n  function parseSrt(transcript: string) {\n    const result = [];\n    if (typeof transcript != \"string\") {\n      return;\n    }\n    if (transcript == null) {\n      return;\n    }\n    const pattern =\n    /(\\d+)\\n([\\d:,]+)\\s+-{2}>\\s+([\\d:,]+)\\n([\\s\\S]*?(?=\\n{2}|$))/gm;\n    transcript = transcript.replace(/\\r\\n|\\r|\\n|\\t/g, \"\\n\");\n    let matches;\n    while ((matches = pattern.exec(transcript)) != null) {\n      result.push({\n        startTime: srtTimeToSeconds(matches[2]),\n        endTime: srtTimeToSeconds(matches[3]),\n        text: matches[4],\n      });\n    }\n    return result;\n  }\n\n  function srtTimeToSeconds(time: string): number {\n    const a = time.split(\":\");\n    return +a[0] * 60 * 60 + +a[1] * 60 + +parseFloat(a[2]);\n  }\n\n  function onTimeUpdateTranscript(currentTime: number) {\n    if(!playerStore.playerTranscript?.value.length){\n      return;\n    }\n    const startTime = (playerStore.playerTranscript.value[playerStore.playerTranscript.actual]?.startTime ?? 0) + playerStore.playerDelayStitching;\n    if (startTime <= currentTime) {\n      playerStore.playerTranscript.actualText = playerStore.playerTranscript.value[playerStore.playerTranscript?.actual]?.text ??\"\";\n    }\n    if (\n      (playerStore.playerTranscript.value[playerStore.playerTranscript.actual]?.endTime ??Infinity) + playerStore.playerDelayStitching< currentTime\n    ) {\n      playerStore.playerTranscript.actual += 1;\n      playerStore.playerTranscript.actualText =\n        playerStore.playerTranscript?.value[playerStore.playerTranscript.actual]?.text ??\n        \"\";\n    }\n  }\n  \n  function onSeekedTranscript(currentTime: number) {\n    if (playerStore.playerTranscript) {\n      let newActual = 0;\n      while (currentTime >(playerStore.playerTranscript.value[newActual]?.endTime ?? Infinity) + playerStore.playerDelayStitching) {\n        newActual += 1;\n      }\n      playerStore.playerTranscript.actual = newActual;\n    }\n  }\n\n  return {\n    checkDelaytWithStitching,\n    getTranscription,\n    onTimeUpdateTranscript,\n    onSeekedTranscript,\n    generatingTranscriptLanguage\n  }\n}\n","export enum OrganisationPrivacy {\n  SECURED = 'SECURED',\n  PRIVATE = 'PRIVATE',\n  PUBLIC = 'PUBLIC'\n}\n\nexport interface PrivateOrganisation {\n  privacy: OrganisationPrivacy;\n  accountCreation: string; // ENABLED DISABLED\n  referrers: Array<string>;\n  cidrs: Array<string>;\n  mailDomains: Array<string>;\n}\n\nexport function emptyPrivateOrganisation(): PrivateOrganisation {\n  return {\n    privacy: OrganisationPrivacy.PUBLIC,\n    accountCreation: \"DISABLED\",\n    referrers: [],\n    cidrs: [],\n    mailDomains: [],\n  };\n}\n","\nimport { usePlayerLive } from \"./usePlayerLive\";\nimport { usePlayerStitching } from \"./usePlayerStitching\";\nimport { usePlayerTranscript } from \"./usePlayerTranscript\";\nimport { nextTick, Ref, ref, watch } from \"vue\";\nimport { usePlayerStore } from \"../../../stores/PlayerStore\";\nimport { useAuthStore } from \"../../../stores/AuthStore\";\nimport { useGeneralStore } from \"../../../stores/GeneralStore\";\nimport { useVastStore } from \"../../../stores/VastStore\";\nimport { state as sdkParams } from \"../../../stores/ParamSdkStore\";\nimport fetchHelper from \"../../../helper/fetchHelper\";\nimport dayjs from \"dayjs\";\nimport { FetchParam } from \"@/stores/class/general/fetchParam\";\nimport { podcastApi } from \"../../../api/podcastApi\";\nimport { Organisation } from \"../../../stores/class/general/organisation\";\nimport { organisationApi } from \"../../../api/organisationApi\";\nimport { OrganisationPrivacy } from \"../../../stores/class/securisation/privateOrganisation\";\n\nexport const usePlayerLogic = (forceHide: Ref<boolean, boolean>) => {\n  const hlsReady = ref(false);\n\n  const { listenTime, onPlay, setDownloadId, onTimeUpdateProgress, playLive, endingLive, playRadio} = usePlayerLive(hlsReady);\n  const { contentEndedAdsLoader } = usePlayerStitching();\n  const { getTranscription, onTimeUpdateTranscript, onSeekedTranscript, checkDelaytWithStitching } = usePlayerTranscript();\n\n  const playerError= ref(false);\n  const listenError= ref(false);\n  const percentLiveProgress= ref(0);\n  const durationLivePosition= ref(0);\n  const displayAlertBar= ref(false);\n  const audioUrlToPlay= ref(\"\");\n\n\n  const playerStore = usePlayerStore();\n  const generalStore = useGeneralStore();\n  const vastStore = useVastStore();\n  const authStore = useAuthStore();\n\n  watch(()=>getAudioUrl(), async () => {\n    playerError.value = false;\n\n    // In some cases, the audio does not go through normal download endpoint\n    // Mostly when the podcast is not available to users\n    let download = true;\n    if (\n      playerStore.playerMedia ||\n      !playerStore.playerPodcast ||\n      playerStore.playerVideo ||\n      !playerStore.playerPodcast.availability.visibility ||\n      listenError.value\n    ) {\n        download = false;\n\n        // Not yet available podcasts in secured organisations go through\n        // download if possible (see #14228)\n        const podcast = playerStore.playerPodcast;\n        if (podcast && !podcast.availability.visibility) {\n          let organisation: Organisation|null = null;\n          if (podcast.organisation) {\n            organisation = podcast.organisation;\n          } else if ('organisationId' in podcast) {\n            // Handle case of missing organisation (for example for SimplifiedPodcast)\n            organisation = await organisationApi.get(podcast.organisationId as string);\n          }\n          if (organisation.privacy === OrganisationPrivacy.SECURED) {\n            download = true;\n          }\n        }\n    }\n\n    if (download) {\n      const response = await podcastApi.downloadRegister(playerStore.playerPodcast.podcastId, getAudioUrlParameters());\n      setDownloadId(response.downloadId.toString());\n      audioUrlToPlay.value = response.location;\n    } else {\n      audioUrlToPlay.value = getAudioUrl();\n    }\n  });\n\n  watch(()=>playerStore.playerPodcast, async () => {\n    reInitPlayer();\n    getTranscription();\n  }, {deep:true});\n\n  watch(()=>playerStore.playerLive, async (_, oldLive) => {\n    if(playerStore.playerVideo){\n      return;\n    }\n    nextTick(async () => {\n      hlsReady.value = false;\n      reInitPlayer(oldLive!==undefined);\n      playLive();\n    });\n  }, {deep:true});\n\n  watch(()=>playerStore.playerRadio, async (_, oldRadio) => {\n    nextTick(async () => {\n      hlsReady.value = false;\n      reInitPlayer(oldRadio !== undefined);\n      playRadio();\n    });\n  });\n\n  watch(()=>playerStore.playerStatus, async () => {\n    const audioPlayer: HTMLAudioElement | null =\n      document.querySelector(\"#audio-player\");\n    if (!audioPlayer) return;\n    if (playerStore.playerLive && !hlsReady.value) {\n      /* audioPlayer.pause();\n      percentLiveProgress.value = 0;\n      durationLivePosition.value = 0; */\n      return;\n    }\n    if (\"PAUSED\" === playerStore.playerStatus && playerStore.playerRadio) {\n      playerStore.playerRadio.dateSessionId = dayjs().toISOString();\n      hlsReady.value = false;\n      reInitPlayer();\n      endingLive();\n    } else if (\"PAUSED\" === playerStore.playerStatus) {\n      audioPlayer.pause();\n    } else if (\"PLAYING\" === playerStore.playerStatus && playerStore.playerRadio) {\n      handlePlayRadio();\n    } else if (\"PLAYING\" === playerStore.playerStatus) {\n      audioPlayer.play();\n    }\n  });\n\n  function handlePlayRadio(){\n    if(!playerStore.playerRadio){\n      return;\n    }\n    if (playerStore.playerRadio.isInit) {\n      if(vastStore.isAdPlaying && !vastStore.resetSessionId){\n        playerStore.playerRadio.dateSessionId = dayjs().toISOString();\n      }\n      playRadio();\n    } else {\n      playerStore.playerRadio.isInit = true;\n    }\n  }\n\n  function getAudioUrlParameters(addToken?: boolean): FetchParam {\n    if (!playerStore.playerPodcast) {\n      return {};\n    }\n    \n    const parameters: FetchParam = {\n      origin: \"octopus\",\n      accepted: vastStore.useVastPlayerPodcast\n    };\n    if (authStore.authOrgaId) {\n      parameters.distributorId = authStore.authOrgaId;\n    }\n    if (generalStore.consentTcf) {\n      parameters.consent = generalStore.consentTcf;\n    }\n    if (\n      addToken &&\n      \"SECURED\" === playerStore.playerPodcast.organisation.privacy &&\n      authStore.authParam.accessToken\n    ) {\n      parameters.access_token = authStore.authParam.accessToken;\n    }\n    return parameters;\n  }\n\n  function getAudioUrl(): string {\n    if (playerStore.playerMedia){\n      return playerStore.playerMedia.audioUrl ?? \"\";\n    }\n    if (!playerStore.playerPodcast || playerStore.playerVideo) {\n      return \"\";\n    }\n    if (\n      !playerStore.playerPodcast.availability.visibility ||\n      \"PROCESSING\" === playerStore.playerPodcast.processingStatus\n    ) {\n      return playerStore.playerPodcast.audioStorageUrl;\n    }\n    if (listenError.value) {\n      return playerStore.playerPodcast.audioStorageUrl;\n    }\n    return playerStore.playerPodcast.podcastId + \".mp3?\"+fetchHelper.getUriSearchParams(getAudioUrlParameters(), true);\n  }\n\n  function reInitPlayer(force=false): void {\n    setDownloadId(null);\n    listenError.value = false;\n    if (force || playerStore.playerLive || playerStore.playerRadio) {\n      endingLive();\n    }\n  }\n\n  function stopPlayer(): void {\n    playerStore.playerPlay();\n  }\n\n  function onError(): void {\n    if (\n      playerStore.playerPodcast &&\n      \"\" !== audioUrlToPlay.value &&\n      !listenError.value\n    ) {\n      listenError.value = true;\n    } else if (\n      (playerStore.playerPodcast && \"\" !== audioUrlToPlay.value) ||\n      playerStore.playerMedia\n    ) {\n      playerError.value = true;\n    }\n  }\n\n  function streamDurationForSafari(mediaTarget: HTMLMediaElement) {\n    let streamDuration = mediaTarget.duration;\n    if (Infinity === streamDuration) {\n      const seekable = mediaTarget.seekable;\n      if (seekable && seekable.length > 0) {\n        try {\n          streamDuration = seekable.end(seekable.length - 1);\n        } catch (e) {\n          console.error(e);\n        }\n      } else {\n        streamDuration = mediaTarget.currentTime;\n      }\n    }\n    return streamDuration;\n  }\n\n  function onTimeUpdatePodcast(streamDuration: number, currentTime: number) {\n    displayAlertBar.value = false;\n    percentLiveProgress.value = 0;\n    playerStore.playerUpdateElapsed(currentTime / streamDuration, streamDuration);\n    onTimeUpdateTranscript(currentTime);\n  }\n\n  function onTimeUpdateLive(streamDuration: number, currentTime: number) {\n    if (!playerStore.playerLive) {\n      return;\n    }\n    const scheduledDuration = playerStore.playerLive.duration / 1000;\n    if (scheduledDuration > streamDuration) {\n      displayAlertBar.value = false;\n      percentLiveProgress.value = (streamDuration / scheduledDuration) * 100;\n      playerStore.playerUpdateElapsed(\n        currentTime / scheduledDuration,\n        scheduledDuration,\n      );\n    } else {\n      percentLiveProgress.value = 100;\n      displayAlertBar.value = true;\n      durationLivePosition.value = (scheduledDuration / streamDuration) * 100;\n      playerStore.playerUpdateElapsed(currentTime / streamDuration, streamDuration);\n    }\n  }\n\n  function onTimeUpdate(event: Event): void {\n    if (playerStore.playerRadio) {\n      return;\n    }\n    const mediaTarget = event.currentTarget as HTMLMediaElement;\n    if (playerStore.playerPodcast || playerStore.playerLive) {\n      onTimeUpdateProgress(mediaTarget.currentTime);\n    }\n    const streamDuration = streamDurationForSafari(mediaTarget);\n    if (!streamDuration) return;\n    if (!mediaTarget.currentTime) return;\n    if (!playerStore.playerLive) {\n      onTimeUpdatePodcast(streamDuration, mediaTarget.currentTime);\n      return;\n    }\n    onTimeUpdateLive(streamDuration, mediaTarget.currentTime);\n  }\n\n  function onSeeked(event: Event): void {\n    const mediaTarget = event.currentTarget as HTMLMediaElement;\n    const currentTime = mediaTarget.currentTime;\n    onSeekedTranscript(currentTime);\n  }\n\n  function onFinished(): void {\n    setDownloadId(null);\n    contentEndedAdsLoader();\n    if (playerStore.playerLive) {\n      endingLive();\n    }\n\n    if (sdkParams.player.stayOpenOnFinish !== true) {\n      forceHide.value = true;\n    }\n  }\n\n\n  return {\n    audioUrlToPlay,\n    listenTime,\n    playerError,\n    percentLiveProgress,\n    durationLivePosition,\n    displayAlertBar,\n    hlsReady,\n    checkDelaytWithStitching,\n    stopPlayer,\n    onError,\n    onTimeUpdate,\n    onSeeked,\n    onFinished,\n    onPlay\n  }\n}\n","<template>\n  <section\n    id=\"octopus-player-component\"\n    class=\"player-container\"\n    :class=\"{ \n      'player-video': playerStore.playerVideo,\n      'overflow-hidden': !display\n     }\"\n    :style=\"{ height: playerStore.playerHeight }\"\n    @transitionend=\"onHidden\"\n  >\n    <audio\n      id=\"audio-player\"\n      :src=\"!playerStore.playerLive && !playerStore.playerRadio ? audioUrlToPlay : undefined\"\n      autoplay\n      @timeupdate=\"onTimeUpdate\"\n      @ended=\"onFinished\"\n      @playing=\"onPlay\"\n      @durationChange=\"onTimeUpdate\"\n      @error=\"onError\"\n      @seeked=\"onSeeked\"\n      @pause=\"onPause\"\n      @loadedmetadata=\"checkDelaytWithStitching\"\n    />\n    <div id=\"ad-container\" />\n\n    <template v-if=\"displayWithTimeout\">\n\n      <slot name=\"above\" />\n    \n      <PlayerVideo v-if=\"playerStore.playerVideo && isNotVideoPage\" />\n      <template v-else-if=\"!playerStore.playerVideo\">\n        <PlayerCompact\n          v-if=\"!playerStore.playerLargeVersion\"\n          :player-error=\"playerError\"\n          :display-alert-bar=\"displayAlertBar\"\n          :percent-live-progress=\"percentLiveProgress\"\n          :duration-live-position=\"durationLivePosition\"\n          :listen-time=\"listenTime\"\n          :hls-ready=\"hlsReady\"\n          @stop-player=\"stopPlayer\"\n          @change-player-large-version=\"playerStore.playerUpdateLargeVersion(true)\"\n        />\n        <PlayerLarge\n          v-else\n          :player-error=\"playerError\"\n          :display-alert-bar=\"displayAlertBar\"\n          :percent-live-progress=\"percentLiveProgress\"\n          :duration-live-position=\"durationLivePosition\"\n          :listen-time=\"listenTime\"\n          :hls-ready=\"hlsReady\"\n          @stop-player=\"stopPlayer\"\n          @change-player-large-version=\"playerStore.playerUpdateLargeVersion(false)\"\n        />\n      </template>\n    </template>\n  </section>\n</template>\n\n<script setup lang=\"ts\">\nimport {usePlayerLogic} from \"../../composable/player/usePlayerLogic\";\nimport { usePlayerStore } from \"../../../stores/PlayerStore\";\nimport { defineAsyncComponent, ref, computed, watch } from \"vue\";\nimport { useRoute } from \"vue-router\";\nconst PlayerVideo = defineAsyncComponent(\n  () => import(\"./video/PlayerVideo.vue\"),\n);\nconst PlayerCompact = defineAsyncComponent(\n  () => import(\"../player/PlayerCompact.vue\"),\n);\nconst PlayerLarge = defineAsyncComponent(\n  () => import(\"../player/PlayerLarge.vue\"),\n);\n\n//Emits\nconst emit = defineEmits(['hide']);\n\n//Data\nconst displayWithTimeout= ref(false);\nconst forceHide= ref(false);\n\n//Composable\nconst {\n  audioUrlToPlay,\n  listenTime,\n  playerError,\n  percentLiveProgress, \n  durationLivePosition,\n  displayAlertBar,\n  hlsReady, \n  checkDelaytWithStitching, \n  stopPlayer, \n  onError, \n  onTimeUpdate, \n  onSeeked, \n  onFinished, \n  onPlay\n} = usePlayerLogic(forceHide);\nconst playerStore = usePlayerStore();\nconst route = useRoute();\n\n// Computed\nconst display = computed(() => { return \"STOPPED\" !== playerStore.playerStatus;});\nconst isNotVideoPage = computed(() => { return \"video\" !== route.name});\n\n// Watch\nwatch(()=>playerStore.playerHeight, async () => {\n  emit(\"hide\", 0 === playerStore.playerHeight);\n});\nwatch(display, async () => {\n  if (display.value) {\n    displayWithTimeout.value = display.value;\n  } else {\n    setTimeout(() => {\n      displayWithTimeout.value = display.value;\n    }, 3000);\n  }\n});\n\n//Methods\nfunction onHidden(): void {\n  if (forceHide.value) {\n    playerStore.playerPlay();\n    forceHide.value = false;\n  }\n}\nfunction onPause() {\n  if (\"PLAYING\" === playerStore.playerStatus) {\n    playerStore.playerChangeStatus(true);\n  }\n}\n</script>\n\n<style lang=\"scss\">\n.octopus-app {\n  .player-container {\n    max-height: 94%;\n    position: sticky;\n    overflow: visible;\n    z-index: 12;\n    width: 100%;\n    bottom: 0;\n    display: flex;\n    flex-direction: column;\n    transition: height 1s;\n    background: var(--octopus-player-color) !important;\n    font-size: 1rem;\n\n    .medium-text {\n      font-size: 0.65rem;\n    }\n\n    .small-text {\n      font-size: 0.5rem;\n    }\n\n    @media (width <= 960px) {\n      .d-flex {\n        flex-wrap: nowrap !important;\n      }\n    }\n  }\n\n  #ad-container {\n    display: none;\n  }\n}\n</style>\n","<template>\n  <section\n    id=\"octopus-player-component\"\n    class=\"player-container\"\n    :class=\"{ \n      'player-video': playerStore.playerVideo,\n      'overflow-hidden': !display\n     }\"\n    :style=\"{ height: playerStore.playerHeight }\"\n    @transitionend=\"onHidden\"\n  >\n    <audio\n      id=\"audio-player\"\n      :src=\"!playerStore.playerLive && !playerStore.playerRadio ? audioUrlToPlay : undefined\"\n      autoplay\n      @timeupdate=\"onTimeUpdate\"\n      @ended=\"onFinished\"\n      @playing=\"onPlay\"\n      @durationChange=\"onTimeUpdate\"\n      @error=\"onError\"\n      @seeked=\"onSeeked\"\n      @pause=\"onPause\"\n      @loadedmetadata=\"checkDelaytWithStitching\"\n    />\n    <div id=\"ad-container\" />\n\n    <template v-if=\"displayWithTimeout\">\n\n      <slot name=\"above\" />\n    \n      <PlayerVideo v-if=\"playerStore.playerVideo && isNotVideoPage\" />\n      <template v-else-if=\"!playerStore.playerVideo\">\n        <PlayerCompact\n          v-if=\"!playerStore.playerLargeVersion\"\n          :player-error=\"playerError\"\n          :display-alert-bar=\"displayAlertBar\"\n          :percent-live-progress=\"percentLiveProgress\"\n          :duration-live-position=\"durationLivePosition\"\n          :listen-time=\"listenTime\"\n          :hls-ready=\"hlsReady\"\n          @stop-player=\"stopPlayer\"\n          @change-player-large-version=\"playerStore.playerUpdateLargeVersion(true)\"\n        />\n        <PlayerLarge\n          v-else\n          :player-error=\"playerError\"\n          :display-alert-bar=\"displayAlertBar\"\n          :percent-live-progress=\"percentLiveProgress\"\n          :duration-live-position=\"durationLivePosition\"\n          :listen-time=\"listenTime\"\n          :hls-ready=\"hlsReady\"\n          @stop-player=\"stopPlayer\"\n          @change-player-large-version=\"playerStore.playerUpdateLargeVersion(false)\"\n        />\n      </template>\n    </template>\n  </section>\n</template>\n\n<script setup lang=\"ts\">\nimport {usePlayerLogic} from \"../../composable/player/usePlayerLogic\";\nimport { usePlayerStore } from \"../../../stores/PlayerStore\";\nimport { defineAsyncComponent, ref, computed, watch } from \"vue\";\nimport { useRoute } from \"vue-router\";\nconst PlayerVideo = defineAsyncComponent(\n  () => import(\"./video/PlayerVideo.vue\"),\n);\nconst PlayerCompact = defineAsyncComponent(\n  () => import(\"../player/PlayerCompact.vue\"),\n);\nconst PlayerLarge = defineAsyncComponent(\n  () => import(\"../player/PlayerLarge.vue\"),\n);\n\n//Emits\nconst emit = defineEmits(['hide']);\n\n//Data\nconst displayWithTimeout= ref(false);\nconst forceHide= ref(false);\n\n//Composable\nconst {\n  audioUrlToPlay,\n  listenTime,\n  playerError,\n  percentLiveProgress, \n  durationLivePosition,\n  displayAlertBar,\n  hlsReady, \n  checkDelaytWithStitching, \n  stopPlayer, \n  onError, \n  onTimeUpdate, \n  onSeeked, \n  onFinished, \n  onPlay\n} = usePlayerLogic(forceHide);\nconst playerStore = usePlayerStore();\nconst route = useRoute();\n\n// Computed\nconst display = computed(() => { return \"STOPPED\" !== playerStore.playerStatus;});\nconst isNotVideoPage = computed(() => { return \"video\" !== route.name});\n\n// Watch\nwatch(()=>playerStore.playerHeight, async () => {\n  emit(\"hide\", 0 === playerStore.playerHeight);\n});\nwatch(display, async () => {\n  if (display.value) {\n    displayWithTimeout.value = display.value;\n  } else {\n    setTimeout(() => {\n      displayWithTimeout.value = display.value;\n    }, 3000);\n  }\n});\n\n//Methods\nfunction onHidden(): void {\n  if (forceHide.value) {\n    playerStore.playerPlay();\n    forceHide.value = false;\n  }\n}\nfunction onPause() {\n  if (\"PLAYING\" === playerStore.playerStatus) {\n    playerStore.playerChangeStatus(true);\n  }\n}\n</script>\n\n<style lang=\"scss\">\n.octopus-app {\n  .player-container {\n    max-height: 94%;\n    position: sticky;\n    overflow: visible;\n    z-index: 12;\n    width: 100%;\n    bottom: 0;\n    display: flex;\n    flex-direction: column;\n    transition: height 1s;\n    background: var(--octopus-player-color) !important;\n    font-size: 1rem;\n\n    .medium-text {\n      font-size: 0.65rem;\n    }\n\n    .small-text {\n      font-size: 0.5rem;\n    }\n\n    @media (width <= 960px) {\n      .d-flex {\n        flex-wrap: nowrap !important;\n      }\n    }\n  }\n\n  #ad-container {\n    display: none;\n  }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;AAQA,IAAI,MAAU;AAEd,IAAM,sBAAsB;AAC5B,IAAa,iBAAiB,aAAyB;CAErD,MAAM,EAAE,YAAY,oBAAoB,eAAe,yBAAyB,uBAAuB;CAEvG,MAAM,eAA4C,IAAI,IAAI;CAC1D,MAAM,MAAe,IAAI,IAAI;CAC7B,MAAM,kBAAiE,IAAI,KAAA,CAAS;CACpF,MAAM,cAA2C,IAAI,KAAA,CAAS;CAC9D,MAAM,WAAU,IAAI,KAAK;CAGzB,MAAM,cAAc,eAAe;CACnC,MAAM,WAAW,YAAY;CAC7B,MAAM,YAAY,aAAa;CAE/B,SAAS,eAAe,KAAsB;EAC5C,IAAI,UAAU,UAAU,gBAAgB,cAAc,YAAY,YAAY,cAAc,WAAW,YAAY,aAAa,UAAU;GACxI,MAAM,aAAa,SAAS,YAAY,QAAQ,gBAAgB,EAAE;GAElE,OAAO,IAAI,SAAS,UAAU;EAChC;EACA,OAAO;CACT;CAEA,SAAS,SAAe;EACtB,YAAY,mBAAmB,aAAa,WAAW,YAAY,YAAY;CACjF;CAEA,SAAS,YAAY;EACnB,IAAI,CAAC,YAAY,aACf;EAEF,qBAAqB;EACrB,YAAY,yBAAyB,YAAY,YAAY,MAAI,+BAA6B,YAAY,YAAY,SAAS;EAC/H,QAAQ;CACV;CAEA,SAAS,uBAAsB;EAC7B,IAAG,CAAC,YAAY,aACd;EAEF,IAAG,YAAY,YAAY,aAAa,MAAM,EAAE,KAAK,MAAM,YAAY,YAAY,aAAa,GAAG,GAAG,IAAE,qBACtG;EAEF,YAAY,YAAY,YAAY,qBAAa,OAAO;CAC1D;CAEA,SAAS,WAAW;EAClB,IAAI,CAAC,YAAY,qBACf;EAEF,YAAY,yBAAyB,GAAG,SAAS,OAAO,OAAO,YAAY,oBAAoB,YAAY;EAC3G,QAAQ;CACV;CAEA,eAAe,UAAyB;EACtC,IAAI;GACF,IAAG,SAAO,aAAa,OACrB,aAAa,QAAQ,SAAS,eAAe,cAAc;GAE7D,IAAI,SAAS,aAAa,SAAS,CAAC,YAAY,cAAc;IAC5D,WAAW,SAAS,GAAI;IACxB;GACF;GACA,MAAM,KAAK,UAAU,UAAU,YAAY;GAC3C,MAAM,YAAY,GAAG,QAAQ,SAAS,IAAI;GAC1C,MAAM,WAAW,GAAG,QAAQ,QAAQ,IAAI;GACxC,IACE,aAAa,MAAM,YAAY,+BAA+B,KAC9D,CAAC,YACD,CAAC,WACD;IACA,IAAI,MAAM,YAAY;IACtB,IAAG,eAAe,GAAG,GACnB,IAAI,IAAI,SAAS,GAAG,GAClB,OAAO,mBAAiB,UAAU,UAAU;SAE5C,OAAO,mBAAiB,UAAU,UAAU;IAGhD,aAAa,MAAM,MAAM;IACzB,MAAM,mBAAmB;IACzB,SAAS,QAAQ;IACjB,MAAM,aAAa,MAAM,KAAK;IAC9B,OAAO;GACT,OACE,MAAM,QAAQ;EAElB,SAAQ,GAAG;GACT,QAAQ,MAAM,CAAC;GACf,WAAW;EACb;CACF;CAEA,SAAS,aAAY;EACnB,IAAG,cAAY,YAAY,gBAAgB,KAAA,MAAY,gBAAgB,OACrE,gBAAgB,QAAQ,iBAAiB;GACvC,SAAS,QAAQ;GACjB,QAAQ;GACR,gBAAgB,QAAQ,KAAA;EAC1B,GAAG,GAAI;CAEX;CAEA,eAAe,UAAU;EACvB,IAAI,SAAS,KACX,MAAM,OAAO,UAAU,MAAM,eAAe;GAC1C,MAAM,WAAW;EACnB,CAAC;EAEH,IAAI,CAAC,IAAI,YAAY,GACnB,MAAM,IAAI,MAAM,yBAAyB;EAE3C,IAAI,QAAQ,IAAI,IAAI;GAClB,eAAe;GACf,sBAAqB;GACrB,kBAAiB;GACjB,iBAAgB;GAEhB,WAAW,KAAqB,QAAgB;IAC9C,IAAI,eAAe,GAAG,GACpB,IAAI,iBAAiB,iBAAiB,YAAW,UAAU,UAAU,WAAW;GAEpF;EACF,CAAC;EACD,IAAI,MAAM,GAAG,IAAI,OAAO,iBAAiB,YAAY;GACnD,MAAM,mBAAmB;GACzB,SAAS,QAAQ;GACjB,IAAG,SAAO,SAAS,OACjB;GAEF,iBAAiB;IACf,YAAY,QAAS,aAAa,MAA2B,KAAK;IAClE,YAAY,MAAM,WAAU;KAC1B,YAAY,QAAQ,KAAA;KACpB,OAAO;IACT,CAAC,EAAE,OAAO,MAAI;KACZ,QAAQ,MAAM,CAAC;KACf,WAAW;KACX,YAAY,QAAQ,KAAA;IACtB,CAAC;GACH,GAAG,GAAG;EACR,CAAC;EACD,IAAI,MAAM,GAAG,IAAI,OAAO,OAAO,OAAO,MAAc,SAAa;GAE/D,IAAI,KAAK,YAAY,sBAAsB;IAEzC,QAAQ,KAAK,uBAAuB;IACpC,YAAY,eAAe,aAAa;IAExC,IAAI,MAAM,QAAQ;IAElB,WAAW,SAAS,GAAG;IACvB;GACF;GACA,QAAQ,MAAM,uBAAuB,OAAO,QAAQ,KAAK,OAAO;GAChE,QAAQ,MAAM,IAAI;GAClB,IAAI,KAAK,SAAS,KAAK,SAAS,IAAI,WAAW,aAAa;IAC1D,QAAQ,KAAK,sBAAsB;IACnC,IAAI,MAAM,kBAAkB;GAC9B;GACA,SAAS,QAAQ;GACjB,IAAG,KAAA,MAAY,YAAY,SAAS,KAAK,OACvC,WAAW;EAEf,CAAC;EACD,IAAI,MAAM,WAAW,YAAY,YAAY;EAC7C,IAAI,MAAM,YAAY,aAAa,KAAyB;CAC9D;CAEA,eAAe,aAA4B;EACzC,aAAa,gBAAgB,KAAK;EAClC,gBAAgB,QAAQ,KAAA;EACxB,IAAG,SAAO,aAAa,OACrB;EAEF,aAAa,QAAQ;EACrB,MAAM,QAA4B,SAAS,eAAe,cAAc;EACxE,IAAI,SAAS,IAAI,OAAO;GACtB,IAAI,MAAM,QAAQ;GAClB,IAAI,QAAQ;EACd,OACE,MAA4B,MAAM;EAEpC,MAA4B,MAAM;CACpC;CAED,OAAO;EACJ;EACA;EACA;EACA;EACA;EACA;EACA;CACH;AACD;;;AC/MA,SAAS,WAAW,KAAa,OAAe,UAAsC;CACpF,MAAM,eAAe,SAAS,qBAAqB,MAAM,EAAE,MAAM,SAAS,iBAC1E,gBAAgB,SAAS,cAAc,QAAQ;CAC/C,cAAc,OAAO;CACrB,cAAc,MAAM;CACpB,cAAc,QAAQ;CACtB,cAAc,iBAAiB,QAAQ,WAAW;EAChD,IAAG,YAAY,OAAO,aAAa,YACjC,SAAS,IAAI;CAEjB,GAAG,KAAK;CACR,cAAc,iBAAiB,SAAS,WAAW;EACjD,aAAa,YAAY,aAAa;EACtC,IAAG,YAAY,OAAO,aAAa,YACjC,SAAS,KAAK;CAElB,GAAG,KAAK;CACR,aAAa,aAAa,eAAe,aAAa,UAAU;AAClE;;;ACbA,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAa,sBAAoB;CAC/B,MAAM,YAAY,IAAI,KAAK;CAC3B,MAAM,oBAAoB,IAAI,KAAK;CACnC,MAAM,iBAA6C,IAAI,IAAI;CAC3D,MAAM,gBAAgB,IAAI,KAAK;CAC/B,MAAM,yBAAyB,IAAI,EAAE;CACrC,MAAM,mBAA0C,IAAI,KAAA,CAAS;CAE7D,MAAM,cAAc,eAAe;CACnC,MAAM,YAAY,aAAa;CAE/B,YAAY,UAAU,kBAAkB;EAAC,wBAAwB;CAAE,CAAC;CACpE,YAAY,UAAU,mBAAmB;EAAC,YAAY;CAAE,CAAC;CAEzD,SAAS,aAAY;EACnB,IAAG,CAAC,UAAU,OAAM;GAClB,UAAU,QAAQ;GAClB,QAAQ;EACV,OACE,cAAc;CAElB;CAEA,SAAS,UAAS;EAChB,WAAW,gDAAgD,OAAO,gBAAwB;GACxF,IAAG,aACD,cAAc;EAElB,CAAC;CACH;CAEA,SAAS,gBAAsB;EAC7B,QAAQ,IAAI,gBAAgB;EAC5B,2BAA2B;EAC3B,IAAG,CAAC,sBAAsB,CAAC,WACzB;CAEJ;CAEA,SAAS,YAAY,SAAgB;EACnC,cAAc,QAAQ;EACtB,QAAQ,IAAI,gBAAc,OAAO;EACjC,qBAAqB,OAAO;EAC5B,UAAU,WAAW,UAAU;CACjC;CAEA,SAAS,6BAAiC;EACxC,IAAG,oBAAoB;EACvB,eAAe,QAAS,SAAS,eAAe,cAAc;EAC9D,IAAG,SAAO,eAAe,OAAO;EAChC,qBAAqB,IAAI,OAAO,IAAI,mBAAmB,SAAS,eAAe,cAAc,GAAG,eAAe,KAAK;EACpH,mBAAmB,WAAW;EAC9B,oBAAoB;CACtB;CAEA,SAAS,sBAA0B;EACjC,YAAY,IAAI,OAAO,IAAI,UAAU,kBAAkB;EACvD,aAAa;EACb,UAAU,iBACR,OAAO,IAAI,sBAAsB,KAAK,oBACtC,oBACA,KACF;EACA,UAAU,iBACR,OAAO,IAAI,aAAa,KAAK,UAC7B,WACA,KACF;CACF;CAEA,SAAS,qBAAqB,SAAqB;EACjD,aAAa,IAAI,OAAO,IAAI,WAAW;EACvC,WAAW,kBAAkB,IAAI;EACjC,WAAW,WAAW;CACxB;CAEA,SAAS,mBAAmB,uBAAyD;EACnF,MAAM,uBAAuB,IAAI,OAAO,IAAI,qBAAqB;EACjE,qBAAqB,8CAA8C;EACnE,aAAa,sBAAsB,cAAc,eAAe,OAAO,oBAAoB;EAC3F,eAAe;CACjB;CAEA,SAAS,iBAAgB;EACvB,QAAQ,IAAI,eAAe;EAC3B,oBAAoB;EACpB,IAAI;GACF,WAAW,KAAK,GAAG,GAAG,OAAO,IAAI,SAAS,MAAM;GAChD,WAAW,MAAM;EACnB,SAAS,SAAS;GAChB,QAAQ,IAAI,OAAO;GACnB,YAAY,mBAAmB,KAAK;GACpC,iBAAiB;EACnB;CACF;CAEA,SAAS,sBAAqB;EAC5B,WAAW,iBAAiB,OAAO,IAAI,aAAa,KAAK,UAAS,SAAS;EAC3E,WAAW,iBAAiB,OAAO,IAAI,QAAQ,KAAK,yBAAyB,uBAAuB;EACpG,WAAW,iBAAiB,OAAO,IAAI,QAAQ,KAAK,0BAA0B,wBAAwB;EACtG,MAAM,SAAS;GACb,OAAO,IAAI,QAAQ,KAAK;GAAmB,OAAO,IAAI,QAAQ,KAAK;GACnE,OAAO,IAAI,QAAQ,KAAK;GAAU,OAAO,IAAI,QAAQ,KAAK;GAC1D,OAAO,IAAI,QAAQ,KAAK;GAAQ,OAAO,IAAI,QAAQ,KAAK;EAC1D;EACA,KAAK,MAAM,SAAS,QAClB,WAAW,iBAAiB,OAAO,QAAQ,SAAS;CAExD;CAEA,SAAS,UAAU,cAAuC;EACxD,QAAQ,IAAI,aAAa,SAAS,CAAC;EACnC,iBAAiB;CACnB;CAEA,SAAS,mBAAkB;EACzB,IAAG,CAAC,YAAY;EAChB,QAAQ,IAAI,iBAAiB;EAC7B,YAAY,QAAQ;EACpB,aAAa;EACb,UAAU,gBAAgB;EAC1B,kBAAkB,QAAO;EACzB,cAAc,QAAQ;CACxB;CAEA,SAAS,UAAU,SAA6B;EAC9C,MAAM,KAAK,QAAQ,MAAM;EACzB,IAAG,IACD,UAAU,gBAAgB,EAAE;EAE9B,QAAQ,QAAQ,MAAhB;GACE,KAAK,OAAO,IAAI,QAAQ,KAAK;IAC3B,uBAAuB,QAAQ,YAAY;IAC3C,IAAI,CAAC,GAAG,SAAS,GAAG;KAClB,YAAY,mBAAmB,KAAK;KACpC,cAAc,QAAQ;IACxB;IACA;GACF,KAAK,OAAO,IAAI,QAAQ,KAAK;IAC3B,QAAQ,IAAI,uBAAqB,uBAAuB,KAAK;IAC7D,IAAG,cAAY,uBAAuB,OAAM;KAC1C,UAAU,iBAAiB,IAAI;KAC/B,WAAW,MAAM;IACnB;IACA;GACF,KAAK,OAAO,IAAI,QAAQ,KAAK,aAAY;IACvC,cAAc,QAAQ;IACtB,MAAM,iBAAiB,QAAQ,UAAU;IACzC,UAAU,sBAAsB,eAAe,UAAS,eAAe,WAAW;IAClF,UAAU,oBACR,UAAU,UAAU,kBAAkB,MAAK,IAC3C,WAAW,oBAAoB,GAC/B,KAAK,KAAK,UAAU,UAAU,kBAAkB,IAAI,eAAe,WAAW,CAAC;IACjF;GACF;EACF;CACF;CAEA,SAAS,0BAA0B;EACjC,UAAU,kBAAkB,IAAI;EAChC,YAAY,mBAAmB,IAAI;CACrC;CAEA,SAAS,2BAA2B;EAClC,IAAI,CAAC,kBAAkB,OACrB,YAAY,mBAAmB,KAAK;EAEtC,eAAe;GACb,UAAU,kBAAkB,KAAK;GACjC,UAAU,qBAAqB,KAAK;EACtC,CAAC;CACH;CAEA,SAAS,wBAA4B;EACnC,IAAI,UAAU,aAAa;EAC3B,kBAAkB,QAAQ;EAC1B,WAAW,gBAAgB;CAC7B;CAEA,SAAS,0BAAyB;EAChC,IAAG,CAAC,YAAY;EAChB,IAAG,UAAU,YAAW;GACtB,WAAW,MAAM;GACjB,iBAAiB,QAAQ,MAAM,EAAE,YAAY;EAC/C,OAAK;GACH,WAAW,OAAO;GAClB,IAAG,CAAC,UAAU,kBAAiB,MAAM,EAAE,KAAK,MAAM,iBAAiB,KAAK,GAAG,GAAG,IAAE,GAC9E,UAAU,qBAAqB,IAAI;EAEvC;CACF;CAEA,SAAS,cAAa;EACpB,IAAG,UAAU,aACX,WAAW,KAAK;CAEpB;CAGD,OAAO;EACJ;EACA;EACA;EACA;EACA;CACH;AACD;;;ACzMA,IAAa,2BAAyB;CAEpC,MAAM,EAAE,eAAe,YAAY,aAAY,kBAAkB,0BAA0B,cAAc;CAEzG,MAAM,gBAAiE,IAAI,KAAA,CAAS;CAEpF,MAAM,QAAQ,SAAS;CACvB,MAAM,cAAc,eAAe;CACnC,MAAM,YAAY,aAAa;CAC/B,MAAM,iBAAgB,kBAAkB;CAExC,MAAM,gCAAgC,eAAe;EACnD,OAAO,YAAY,aAAa,iBAAiB;CACnD,CAAC;CAGD,YAAY,YAAY,2BAA2B;EACjD,IAAG,YAAY,uBAAuB,YAAY,sBAAsB,KAAK,CAAC,+BAA+B,GAAG;EAChH,eAAe;CACjB,CAAC;CAGD,YAAY,YAAY,4BAA4B;EAClD,IAAG,CAAC,+BAA+B,GAAG;EACtC,IAAG,CAAC,cAAc,SAAS,sBAAsB,GAAE;GACjD,YAAY,UAAU,oBAAoB,YAAY,uBAAqB,GAAG,UAAU,iBAAiB,OAAO;GAChH,UAAU,sBAAsB,UAAU,kBAAgB,CAAC;EAC7D;CACF,CAAC;CAGD,MAAM,qCAAqC;EACzC,IAAG,CAAC,8BAA8B,OAChC;EAEF,oBAAoB;CACtB,GAAG,EAAE,WAAW,KAAK,CAAC;CAGtB,gBAAgB;EACd,UAAU,2BAA2B,WAAS,MAAM,MAAM,IAAI;CAChE,CAAC;CAED,SAAS,iCAAwC;EAC/C,OAAO,UAAU;CACnB;CAEA,SAAS,sBAAqB;EAC5B,mBAAmB;EACnB,MAAM,gBAAgB,MAAM,8BAA8B,KAAK,EAAE,KAAK,MAAM,GAAG,aAAa;EAC5F,QAAQ,IAAI,mBAAiB,aAAa;EAC1C,IAAG,gBAAgB,GACjB;EAEF,cAAc,QAAQ,iBAAiB;GACrC,qBAAqB;EACvB,GAAG,aAAa;CAClB;CAEA,eAAe,uBAAsB;EAEnC,IAAG,aAAW,YAAY,cAAc;EACxC,MAAM,UAAU,MAAM,WAAW,YAAY,aAAa,iBAAiB,OAAM,iBAAiB,YAAY,aAAa,iBAAiB,WAAW,CAAC;EACxJ,QAAQ,IAAI,aAAW,OAAO;EAC9B,YAAY,OAAO;CACrB;CAEA,SAAS,qBAAqB;EAC5B,cAAc,cAAc,KAA0B;EACtD,cAAc,QAAQ,KAAA;CACxB;CAEA,SAAS,wBAAuB;EAC9B,IAAG,CAAC,YAAY,uBAAuB,CAAC,UAAU,oBAAoB,YAAY,uBAAuB,UAAU,kBAAkB,OAAO;EAC5I,OAAO,UAAU,oBAAoB,YAAY,qBAAqB,UAAU,kBAAkB,WAAW,YAAY;CAC3H;CAEA,eAAe,iBAAgB;EAC7B,iBAAiB;EACjB,IAAG,QAAM,YAAY,qBAAqB;EAC1C,WAAW;EACX,MAAM,qBAAqB;CAC7B;CAEA,eAAe,uBAAsB;EACnC,IAAG,CAAC,YAAY,uBAAuB,CAAC,YAAY,iBAAiB,YAAY,uBAAuB,UAAU,oBAAoB,YAAY,sBAChJ;EAEF,MAAM,iBAAiB,MAAM,mBAAW,UAAiC;GACvE,KAAI;GACJ,MAAM,mBAAmB,YAAY;GACrC,WAAU;EACZ,CAAC;EACD,IAAG,CAAC,kBAAkB,qBAAmB,eAAe,QAAQ,QAAO;GACrE,UAAU,0BAA0B,YAAY,qBAAqB,CAAC,CAAC;GACvE;EACF;EACA,MAAM,yBAAyB,KAAK,OAAO,YAAY,eAAe,YAAU,KAAK,GAAI;EAEzF,MAAM,sBAAsB,MAAM,yBADZ,uBAAuB,eAAe,OAAO,UAAU,sBAClB,GAAgB,wBAAwB,eAAe,OAAO,qBAAqB,eAAe,OAAO,eAAe;EACnL,UAAU,0BAA0B,YAAY,qBAAqB,mBAAmB;CAC1F;CAEA,SAAS,uBAAuB,UAAiC,iBAA2C;EAC1G,MAAM,cAAiC,CAAC;EACxC,IAAG,SAAS,MAAM,YAA0B;GAAC,OAAO,gBAAc,QAAQ;EAAG,CAAC,GAC5E,OAAO,CAAC;EAEV,KAAK,MAAM,WAAW,UAAU;GAC9B,IAAG,CAAC,QAAQ,KAAK;GACjB,IAAI,UAAU;GACd,IAAG,WAAS,QAAQ,OAAO,WACzB,UAAU;QACN,IAAG,UAAQ,QAAQ,OAAO,WAAU;IACxC,MAAM,SAAS,QAAQ,OAAO,UAAU;IACxC,QAAQ,QAAQ,OAAO,MAAvB;KACE,KAAK;MAAe,UAAU,SAAS;MAAM;KAC7C,KAAK;MAAU,UAAU,KAAK,MAAM,SAAS,EAAE;MAAG;KAClD,KAAK;MAAW,UAAU,KAAK,MAAO,SAAS,kBAAmB,GAAG;MAAG;KACxE;MAAS,UAAU;MAAQ;IAC7B;GACF;GACA,YAAY,KAAK;IACf,WAAW,QAAQ;IACnB,QAAQ,QAAQ,OAAO;IACd;IACT,SAAS;GACX,CAAC;EACH;EACA,OAAO,YAAY,MAAM,GAAe,MAAkB;GACxD,IAAI,EAAE,UAAU,EAAE,SAChB,OAAO;GAET,OAAO,EAAE,UAAU,EAAE,UAAU,KAAK;EACtC,CAAC;CACH;CAEA,eAAe,yBAAyB,gBAAmC,iBAAyB,qBAA4B,iBAAmD;EACjL,MAAM,cAAiC,CAAC;EACxC,IAAI,mBAAmB;EACvB,KAAI,MAAM,cAAc,gBACtB,QAAQ,WAAW,QAAnB;GACE,KAAK;IACH,YAAY,KAAK,MAAM,cAAc,UAAU,CAAC;IAChD,mBAAmB;IACnB;GACF,KAAK;IACH,IAAI,WAAW,UAAU,kBAAkB,iBAEzC;IAEF,IAAI,oBAAoB,KAAK,WAAW,UAAU,mBAAmB,qBAEnE;IAEF,YAAY,KAAK,MAAM,cAAc,UAAU,CAAC;IAChD,mBAAmB,WAAW;IAC9B;GACF,KAAK;IACH,IAAI,oBAAoB,KAAK,mBAAmB,kBAAkB,qBAEhE;IAEF,YAAY,KAAK,MAAM,cAAc,UAAU,CAAC;IAChD;GACF,SAAQ;EACV;EAEF,OAAO;CACT;CAEA,eAAe,cAAc,YAA4C;EACvE,WAAW,UAAU,MAAM,WAAW,WAAW,WAAW,CAAC;EAC7D,OAAO;CACT;CAEA,eAAe,WAAW,KAAa,SAAiC;EACtE,MAAM,UAAU,sCAAoC;EACpD,IAAI,WAA0B,CAAC;EAC/B,IAAG,YAAY,eAAe,MAAM;OAE9B,YAAS,MADY,eAAe,kBAAkB,YAAY,cAAc,aAAa,EAAE,GAC3E,0BACtB,WAAW,YAAY,cAAc,KAAK,KAAK,MAAM;IACnD,OAAO,SAAS;GAClB,CAAC;EAAA;EAGL,MAAM,aAAa,oBAAY,mBAAmB;GAChD,SAAS,WAAW;GACpB,SAAQ,SAAS;GACR;EACX,CAAC;EACD,OAAO,UAAU,MAAM,WAAW,SAAS;CAC7C;CAED,OAAO,EACJ,sBACH;AACD;;;;AC3MA,IAAM,+BAA+B,IAAiB,IAAI;AAE1D,IAAa,4BAA0B;CAErC,MAAM,cAAc,eAAe;CACnC,MAAM,YAAY,aAAa;CAC/B,MAAM,EAAE,4BAA4B,eAAe;CAEnD,eAAe,2BAA0B;EACvC,YAAY,2BAA2B,CAAC;EACxC,IAAG,UAAU,sBACX;EAGF,MAAM,cAAc,SAAS,cAAc,eAAe;EAC1D,IAAI,CAAC,YAAY,oBAAoB,CAAC,eAAe,CAAC,YAAY,iBAChE,YAAY,YAAY,YAAY,cAAc,WAAW,MAAO,GACpE;EAGF,MAAM,iBAAiB,MAAM,mBAAW,UAAiC;GACvE,KAAI;GACJ,MAAK,mBAAmB,YAAY,cAAc;GAClD,WAAU;EACZ,CAAC;EAOD,IAH8B,eAAe,OAAO,SACjD,QAAO,YAAW,CAAE,CAAC,OAAO,MAAM,EAAE,SAAS,QAAQ,OAAO,SAAS,CAAE,EACvE,SAAS,GACe;GACzB,QAAQ,KAAK,4DAA4D;GACzE,YAAY,uBAAuB;GACnC,YAAY,uBAAuB;GACnC;EACF;EAMA,IAHe,eAAe,OAAO,SAClC,QAAO,YAAW,QAAQ,OAAO,cAAc,KAAK,EACpD,SAAS,GAIV,YAAY,2BAA4B,YAAY,WAAY,YAAY,cAAc,WAAW,GAAK;CAE9G;CAEA,eAAe,mBAAkC;EAC/C,6BAA6B,QAAQ;EACrC,IAAI,CAAC,YAAY,eAAe;GAC9B,YAAY,uBAAuB;GACnC;EACF;EAGA,MAAM,YAAY,YAAY,cAAc;EAE5C,MAAM,EAAE,OAAO,cAAc,MAAM,wBAAwB,MAD7B,iBAAiB,gBAAgB,SAAS,CACE;EAK1E,MAAM,kBAAkB,SAAS,MAFZ,iBAAiB,eAAe,WAAW,KAAK,CAE9B;EACvC,MAAM,aACJ,kBAAkB,IAAI,cAAc,IAAI,gBAAgB,GAAG,OAAO;EACpE,IAAG,CAAC,iBACF;EAEF,YAAY,uBAAuB;GACjC,QAAQ;GACI;GACZ,OAAO;EACT,CAAC;EAED,IAAI,cAAc,KAAA,KAAa,UAAU,WAAW;GAClD,6BAA6B,QAAQ;GAKrC,MAAM,kBAAkB,SAAS,MAFZ,iBAAiB,eAAe,WAAW,WAAW,IAAI,CAExC;GACvC,MAAM,aACJ,kBAAkB,IAAI,cAAc,IAAI,gBAAgB,GAAG,OAAO;GACpE,IAAG,CAAC,iBACF;GAEF,YAAY,uBAAuB;IACjC,QAAQ,YAAY,kBAAkB;IAC1B;IACZ,OAAO;GACT,CAAC;GACD,6BAA6B,QAAQ;EACvC;CACF;CAEA,SAAS,SAAS,YAAoB;EACpC,MAAM,SAAS,CAAC;EAChB,IAAI,OAAO,cAAc,UACvB;EAEF,IAAI,cAAc,MAChB;EAEF,MAAM,UACN;EACA,aAAa,WAAW,QAAQ,kBAAkB,IAAI;EACtD,IAAI;EACJ,QAAQ,UAAU,QAAQ,KAAK,UAAU,MAAM,MAC7C,OAAO,KAAK;GACV,WAAW,iBAAiB,QAAQ,EAAE;GACtC,SAAS,iBAAiB,QAAQ,EAAE;GACpC,MAAM,QAAQ;EAChB,CAAC;EAEH,OAAO;CACT;CAEA,SAAS,iBAAiB,MAAsB;EAC9C,MAAM,IAAI,KAAK,MAAM,GAAG;EACxB,OAAO,CAAC,EAAE,KAAK,KAAK,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,WAAW,EAAE,EAAE;CACxD;CAEA,SAAS,uBAAuB,aAAqB;EACnD,IAAG,CAAC,YAAY,kBAAkB,MAAM,QACtC;EAGF,KADmB,YAAY,iBAAiB,MAAM,YAAY,iBAAiB,SAAS,aAAa,KAAK,YAAY,wBACzG,aACf,YAAY,iBAAiB,aAAa,YAAY,iBAAiB,MAAM,YAAY,kBAAkB,SAAS,QAAO;EAE7H,KACG,YAAY,iBAAiB,MAAM,YAAY,iBAAiB,SAAS,WAAU,YAAY,YAAY,uBAAsB,aAClI;GACA,YAAY,iBAAiB,UAAU;GACvC,YAAY,iBAAiB,aAC3B,YAAY,kBAAkB,MAAM,YAAY,iBAAiB,SAAS,QAC1E;EACJ;CACF;CAEA,SAAS,mBAAmB,aAAqB;EAC/C,IAAI,YAAY,kBAAkB;GAChC,IAAI,YAAY;GAChB,OAAO,eAAc,YAAY,iBAAiB,MAAM,YAAY,WAAW,YAAY,YAAY,sBACrG,aAAa;GAEf,YAAY,iBAAiB,SAAS;EACxC;CACF;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;CACF;AACF;;;ACxKA,IAAY,sBAAL,yBAAA,qBAAA;CACL,oBAAA,aAAA;CACA,oBAAA,aAAA;CACA,oBAAA,YAAA;;AACF,EAAA,CAAA,CAAA;;;ACcA,IAAa,kBAAkB,cAAqC;CAClE,MAAM,WAAW,IAAI,KAAK;CAE1B,MAAM,EAAE,YAAY,QAAQ,eAAe,sBAAsB,UAAU,YAAY,cAAa,cAAc,QAAQ;CAC1H,MAAM,EAAE,0BAA0B,mBAAmB;CACrD,MAAM,EAAE,kBAAkB,wBAAwB,oBAAoB,6BAA6B,oBAAoB;CAEvH,MAAM,cAAa,IAAI,KAAK;CAC5B,MAAM,cAAa,IAAI,KAAK;CAC5B,MAAM,sBAAqB,IAAI,CAAC;CAChC,MAAM,uBAAsB,IAAI,CAAC;CACjC,MAAM,kBAAiB,IAAI,KAAK;CAChC,MAAM,iBAAgB,IAAI,EAAE;CAG5B,MAAM,cAAc,eAAe;CACnC,MAAM,eAAe,gBAAgB;CACrC,MAAM,YAAY,aAAa;CAC/B,MAAM,YAAY,aAAa;CAE/B,YAAU,YAAY,GAAG,YAAY;EACnC,YAAY,QAAQ;EAIpB,IAAI,WAAW;EACf,IACE,YAAY,eACZ,CAAC,YAAY,iBACb,YAAY,eACZ,CAAC,YAAY,cAAc,aAAa,cACxC,YAAY,OACZ;GACE,WAAW;GAIX,MAAM,UAAU,YAAY;GAC5B,IAAI,WAAW,CAAC,QAAQ,aAAa,YAAY;IAC/C,IAAI,eAAkC;IACtC,IAAI,QAAQ,cACV,eAAe,QAAQ;SAClB,IAAI,oBAAoB,SAE7B,eAAe,MAAM,gBAAgB,IAAI,QAAQ,cAAwB;IAE3E,IAAI,aAAa,YAAY,oBAAoB,SAC/C,WAAW;GAEf;EACJ;EAEA,IAAI,UAAU;GACZ,MAAM,WAAW,MAAM,WAAW,iBAAiB,YAAY,cAAc,WAAW,sBAAsB,CAAC;GAC/G,cAAc,SAAS,WAAW,SAAS,CAAC;GAC5C,eAAe,QAAQ,SAAS;EAClC,OACE,eAAe,QAAQ,YAAY;CAEvC,CAAC;CAED,YAAU,YAAY,eAAe,YAAY;EAC/C,aAAa;EACb,iBAAiB;CACnB,GAAG,EAAC,MAAK,KAAI,CAAC;CAEd,YAAU,YAAY,YAAY,OAAO,GAAG,YAAY;EACtD,IAAG,YAAY,aACb;EAEF,SAAS,YAAY;GACnB,SAAS,QAAQ;GACjB,aAAa,YAAU,KAAA,CAAS;GAChC,SAAS;EACX,CAAC;CACH,GAAG,EAAC,MAAK,KAAI,CAAC;CAEd,YAAU,YAAY,aAAa,OAAO,GAAG,aAAa;EACxD,SAAS,YAAY;GACnB,SAAS,QAAQ;GACjB,aAAa,aAAa,KAAA,CAAS;GACnC,UAAU;EACZ,CAAC;CACH,CAAC;CAED,YAAU,YAAY,cAAc,YAAY;EAC9C,MAAM,cACJ,SAAS,cAAc,eAAe;EACxC,IAAI,CAAC,aAAa;EAClB,IAAI,YAAY,cAAc,CAAC,SAAS,OAItC;EAEF,IAAI,aAAa,YAAY,gBAAgB,YAAY,aAAa;GACpE,YAAY,YAAY,gBAAgB,MAAM,EAAE,YAAY;GAC5D,SAAS,QAAQ;GACjB,aAAa;GACb,WAAW;EACb,OAAO,IAAI,aAAa,YAAY,cAClC,YAAY,MAAM;OACb,IAAI,cAAc,YAAY,gBAAgB,YAAY,aAC/D,gBAAgB;OACX,IAAI,cAAc,YAAY,cACnC,YAAY,KAAK;CAErB,CAAC;CAED,SAAS,kBAAiB;EACxB,IAAG,CAAC,YAAY,aACd;EAEF,IAAI,YAAY,YAAY,QAAQ;GAClC,IAAG,UAAU,eAAe,CAAC,UAAU,gBACrC,YAAY,YAAY,gBAAgB,MAAM,EAAE,YAAY;GAE9D,UAAU;EACZ,OACE,YAAY,YAAY,SAAS;CAErC;CAEA,SAAS,sBAAsB,UAAgC;EAC7D,IAAI,CAAC,YAAY,eACf,OAAO,CAAC;EAGV,MAAM,aAAyB;GAC7B,QAAQ;GACR,UAAU,UAAU;EACtB;EACA,IAAI,UAAU,YACZ,WAAW,gBAAgB,UAAU;EAEvC,IAAI,aAAa,YACf,WAAW,UAAU,aAAa;EAEpC,IACE,YACA,cAAc,YAAY,cAAc,aAAa,WACrD,UAAU,UAAU,aAEpB,WAAW,eAAe,UAAU,UAAU;EAEhD,OAAO;CACT;CAEA,SAAS,cAAsB;EAC7B,IAAI,YAAY,aACd,OAAO,YAAY,YAAY,YAAY;EAE7C,IAAI,CAAC,YAAY,iBAAiB,YAAY,aAC5C,OAAO;EAET,IACE,CAAC,YAAY,cAAc,aAAa,cACxC,iBAAiB,YAAY,cAAc,kBAE3C,OAAO,YAAY,cAAc;EAEnC,IAAI,YAAY,OACd,OAAO,YAAY,cAAc;EAEnC,OAAO,YAAY,cAAc,YAAY,UAAQ,oBAAY,mBAAmB,sBAAsB,GAAG,IAAI;CACnH;CAEA,SAAS,aAAa,QAAM,OAAa;EACvC,cAAc,IAAI;EAClB,YAAY,QAAQ;EACpB,IAAI,SAAS,YAAY,cAAc,YAAY,aACjD,WAAW;CAEf;CAEA,SAAS,aAAmB;EAC1B,YAAY,WAAW;CACzB;CAEA,SAAS,UAAgB;EACvB,IACE,YAAY,iBACZ,OAAO,eAAe,SACtB,CAAC,YAAY,OAEb,YAAY,QAAQ;OACf,IACJ,YAAY,iBAAiB,OAAO,eAAe,SACpD,YAAY,aAEZ,YAAY,QAAQ;CAExB;CAEA,SAAS,wBAAwB,aAA+B;EAC9D,IAAI,iBAAiB,YAAY;EACjC,IAAI,aAAa,gBAAgB;GAC/B,MAAM,WAAW,YAAY;GAC7B,IAAI,YAAY,SAAS,SAAS,GAChC,IAAI;IACF,iBAAiB,SAAS,IAAI,SAAS,SAAS,CAAC;GACnD,SAAS,GAAG;IACV,QAAQ,MAAM,CAAC;GACjB;QAEA,iBAAiB,YAAY;EAEjC;EACA,OAAO;CACT;CAEA,SAAS,oBAAoB,gBAAwB,aAAqB;EACxE,gBAAgB,QAAQ;EACxB,oBAAoB,QAAQ;EAC5B,YAAY,oBAAoB,cAAc,gBAAgB,cAAc;EAC5E,uBAAuB,WAAW;CACpC;CAEA,SAAS,iBAAiB,gBAAwB,aAAqB;EACrE,IAAI,CAAC,YAAY,YACf;EAEF,MAAM,oBAAoB,YAAY,WAAW,WAAW;EAC5D,IAAI,oBAAoB,gBAAgB;GACtC,gBAAgB,QAAQ;GACxB,oBAAoB,QAAS,iBAAiB,oBAAqB;GACnE,YAAY,oBACV,cAAc,mBACd,iBACF;EACF,OAAO;GACL,oBAAoB,QAAQ;GAC5B,gBAAgB,QAAQ;GACxB,qBAAqB,QAAS,oBAAoB,iBAAkB;GACpE,YAAY,oBAAoB,cAAc,gBAAgB,cAAc;EAC9E;CACF;CAEA,SAAS,aAAa,OAAoB;EACxC,IAAI,YAAY,aACd;EAEF,MAAM,cAAc,MAAM;EAC1B,IAAI,YAAY,iBAAiB,YAAY,YAC3C,qBAAqB,YAAY,WAAW;EAE9C,MAAM,iBAAiB,wBAAwB,WAAW;EAC1D,IAAI,CAAC,gBAAgB;EACrB,IAAI,CAAC,YAAY,aAAa;EAC9B,IAAI,CAAC,YAAY,YAAY;GAC3B,oBAAoB,gBAAgB,YAAY,WAAW;GAC3D;EACF;EACA,iBAAiB,gBAAgB,YAAY,WAAW;CAC1D;CAEA,SAAS,SAAS,OAAoB;EAEpC,MAAM,cADc,MAAM,cACM;EAChC,mBAAmB,WAAW;CAChC;CAEA,SAAS,aAAmB;EAC1B,cAAc,IAAI;EAClB,sBAAsB;EACtB,IAAI,YAAY,YACd,WAAW;EAGb,IAAI,MAAU,OAAO,qBAAqB,MACxC,UAAU,QAAQ;CAEtB;CAGA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF;;;;;;;;ECrPA,MAAM,cAAc,2BACZ,OAAO,6BACf;EACA,MAAM,gBAAgB,2BACd,OAAO,+BACf;EACA,MAAM,cAAc,2BACZ,OAAO,6BACf;EAGA,MAAM,OAAO;EAGb,MAAM,qBAAoB,IAAI,KAAK;EACnC,MAAM,YAAW,IAAI,KAAK;EAG1B,MAAM,EACJ,gBACA,YACA,aACA,qBACA,sBACA,iBACA,UACA,0BACA,YACA,SACA,cACA,UACA,YACA,WACE,eAAe,SAAS;EAC5B,MAAM,cAAc,eAAe;EACnC,MAAM,QAAQ,SAAS;EAGvB,MAAM,UAAU,eAAe;GAAE,OAAO,cAAc,YAAY;EAAa,CAAC;EAChF,MAAM,iBAAiB,eAAe;GAAE,OAAO,YAAY,MAAM;EAAI,CAAC;EAGtE,YAAU,YAAY,cAAc,YAAY;GAC9C,KAAK,QAAQ,MAAM,YAAY,YAAY;EAC7C,CAAC;EACD,MAAM,SAAS,YAAY;GACzB,IAAI,QAAQ,OACV,mBAAmB,QAAQ,QAAQ;QAEnC,iBAAiB;IACf,mBAAmB,QAAQ,QAAQ;GACrC,GAAG,GAAI;EAEX,CAAC;EAGD,SAAS,WAAiB;GACxB,IAAI,UAAU,OAAO;IACnB,YAAY,WAAW;IACvB,UAAU,QAAQ;GACpB;EACF;EACA,SAAS,UAAU;GACjB,IAAI,cAAc,YAAY,cAC5B,YAAY,mBAAmB,IAAI;EAEvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBCjIE,mBAuDU,WAAA;EAtDR,IAAG;EACH,OAAK,eAAA,CAAC,oBAAkB;mBACS,OAAA,YAAY;uBAAuC,OAAA;;EAInF,OAAK,eAAA,EAAA,QAAY,OAAA,YAAY,aAAY,CAAA;EACzC,iBAAe,OAAA;;EAEhB,mBAYE,SAAA;GAXA,IAAG;GACF,KAAG,CAAG,OAAA,YAAY,cAAU,CAAK,OAAA,YAAY,cAAc,OAAA,iBAAiB,KAAA;GAC7E,UAAA;GACC,cAAU,OAAA,OAAA,OAAA,MAAA,GAAA,SAAE,OAAA,gBAAA,OAAA,aAAA,GAAA,IAAA;GACZ,SAAK,OAAA,OAAA,OAAA,MAAA,GAAA,SAAE,OAAA,cAAA,OAAA,WAAA,GAAA,IAAA;GACP,WAAO,OAAA,OAAA,OAAA,MAAA,GAAA,SAAE,OAAA,UAAA,OAAA,OAAA,GAAA,IAAA;GACT,qBAAc,OAAA,OAAA,OAAA,MAAA,GAAA,SAAE,OAAA,gBAAA,OAAA,aAAA,GAAA,IAAA;GAChB,SAAK,OAAA,OAAA,OAAA,MAAA,GAAA,SAAE,OAAA,WAAA,OAAA,QAAA,GAAA,IAAA;GACP,UAAM,OAAA,OAAA,OAAA,MAAA,GAAA,SAAE,OAAA,YAAA,OAAA,SAAA,GAAA,IAAA;GACR,SAAO,OAAA;GACP,kBAAc,OAAA,OAAA,OAAA,MAAA,GAAA,SAAE,OAAA,4BAAA,OAAA,yBAAA,GAAA,IAAA;;4BAEnB,mBAAyB,OAAA,EAApB,IAAG,eAAc,GAAA,MAAA,EAAA;EAEN,OAAA,sBAAA,UAAA,GAAhB,mBA6BW,UAAA,EAAA,KAAA,EAAA,GAAA,CA3BT,WAAqB,KAAA,QAAA,OAAA,GAEF,OAAA,YAAY,eAAe,OAAA,kBAAA,UAAA,GAA9C,YAAgE,OAAA,gBAAA,EAAA,KAAA,EAAA,CAAA,KAAA,CAC1C,OAAA,YAAY,eAAA,UAAA,GAAlC,mBAuBW,UAAA,EAAA,KAAA,EAAA,GAAA,CAAA,CArBA,OAAA,YAAY,sBAAA,UAAA,GADrB,YAUE,OAAA,kBAAA;;GARC,gBAAc,OAAA;GACd,qBAAmB,OAAA;GACnB,yBAAuB,OAAA;GACvB,0BAAwB,OAAA;GACxB,eAAa,OAAA;GACb,aAAW,OAAA;GACX,cAAa,OAAA;GACb,4BAA2B,OAAA,OAAA,OAAA,MAAA,WAAE,OAAA,YAAY,yBAAwB,IAAA;;;;;;;;;sBAEpE,YAUE,OAAA,gBAAA;;GARC,gBAAc,OAAA;GACd,qBAAmB,OAAA;GACnB,yBAAuB,OAAA;GACvB,0BAAwB,OAAA;GACxB,eAAa,OAAA;GACb,aAAW,OAAA;GACX,cAAa,OAAA;GACb,4BAA2B,OAAA,OAAA,OAAA,MAAA,WAAE,OAAA,YAAY,yBAAwB,KAAA"}