@glitchlab/vue-video-player 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -2
- package/dist/VideoPlayer.vue.d.ts +1 -1
- package/dist/VideoPlayer.vue.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +4 -2
- package/dist/index.mjs.map +1 -1
- package/dist/utils/types.d.ts +5 -4
- package/dist/utils/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/utils/audio-tracks.ts","../src/HLSPlayer.vue","../src/components/IconAudio.vue","../src/components/IconChevron.vue","../src/components/AudioTrackSwitcher.vue","../src/components/IconSpeed.vue","../src/components/SpeedSwitcher.vue","../src/components/IconCaptions.vue","../src/components/CaptionsSwitcher.vue","../src/components/IconPause.vue","../src/components/IconPlaySolid.vue","../src/components/IconVolumeHigh.vue","../src/components/IconVolumeLow.vue","../src/components/IconVolumeMuted.vue","../src/components/IconPiP.vue","../src/components/IconFullscreen.vue","../src/components/IconFullscreenExit.vue","../src/utils/format-time.ts","../src/components/ControlBar.vue","../src/components/IconDesktop.vue","../src/components/IconMobile.vue","../src/components/IconPlay.vue","../src/components/IconX.vue","../src/utils/youtube.ts","../src/VideoPlayer.vue"],"sourcesContent":["/**\n * A normalized audio-track descriptor, independent of whether the source plays\n * through hls.js or the native `<video>` element.\n */\nexport interface AudioTrackInfo {\n /** Stable index into the player's track list. */\n index: number;\n /** Human-readable label, e.g. \"English\", \"Español\", or a fallback. */\n label: string;\n /** BCP-47-ish language code if the source provides one. */\n lang?: string;\n}\n\n/** Build a display label for a track, falling back to language code or \"Audio N\". */\nexport function audioTrackLabel(\n name: string | undefined,\n lang: string | undefined,\n index: number\n): string {\n const trimmed = name?.trim();\n if (trimmed) return trimmed;\n if (lang) {\n try {\n const dn = new Intl.DisplayNames(undefined, { type: \"language\" });\n const resolved = dn.of(lang);\n if (resolved && resolved !== lang) return resolved;\n } catch {\n /* Intl.DisplayNames unavailable or bad code */\n }\n return lang;\n }\n return `Audio ${index + 1}`;\n}\n","<script setup lang=\"ts\">\nimport Hls from \"hls.js\";\nimport { onBeforeUnmount, onMounted, ref, watch } from \"vue\";\nimport type { HlsConfig } from \"hls.js\";\nimport { audioTrackLabel, type AudioTrackInfo } from \"./utils/audio-tracks\";\n\nconst props = withDefaults(\n defineProps<{\n src: string;\n hlsConfig?: HlsConfig;\n isHls?: boolean;\n muted?: boolean;\n loop?: boolean;\n controls?: boolean;\n autoPlay?: boolean;\n playsInline?: boolean;\n preload?: string;\n poster?: string;\n class?: string;\n /** Index of the audio track to activate; `-1` means \"leave at source default\". */\n audioTrackIndex?: number;\n }>(),\n {\n muted: true,\n loop: false,\n controls: false,\n autoPlay: false,\n playsInline: true,\n preload: \"metadata\",\n audioTrackIndex: -1\n }\n);\n\nconst emit = defineEmits<{\n play: [];\n pause: [];\n \"audio-tracks\": [tracks: AudioTrackInfo[]];\n}>();\n\nconst videoEl = ref<HTMLVideoElement | null>(null);\nconst hlsInstance = ref<Hls | null>(null);\nlet detachNative: (() => void) | undefined;\nlet detachLoadedMetadata: (() => void) | undefined;\n\nconst canUseHlsJs = globalThis.window !== undefined && Hls.isSupported();\nconst shouldUseHls = (src: string) =>\n Boolean(props.isHls) || (canUseHlsJs && src.endsWith(\".m3u8\"));\n\nfunction cleanup() {\n detachLoadedMetadata?.();\n detachLoadedMetadata = undefined;\n detachNative?.();\n detachNative = undefined;\n if (hlsInstance.value) {\n hlsInstance.value.destroy();\n hlsInstance.value = null;\n }\n const el = videoEl.value;\n if (!el) return;\n el.pause();\n el.removeAttribute(\"src\");\n while (el.firstChild) el.firstChild.remove();\n el.load();\n emit(\"audio-tracks\", []);\n}\n\nfunction initPlayer(src: string) {\n const el = videoEl.value;\n if (!el || !src) return;\n\n cleanup();\n\n // Tries to start playback once the stream is ready. Browsers only honor\n // sound-on autoplay after a user gesture, so this is best effort — silently\n // swallows the NotAllowedError when blocked.\n const tryAutoPlay = () => {\n if (!props.autoPlay) return;\n el.play().catch(() => {\n /* autoplay blocked; user gesture required */\n });\n };\n\n if (shouldUseHls(src)) {\n const hls = new Hls(props.hlsConfig);\n hlsInstance.value = hls;\n\n const reportHlsTracks = () => {\n const list: AudioTrackInfo[] = hls.audioTracks.map((t, i) => ({\n index: i,\n label: audioTrackLabel(t.name, t.lang, i),\n lang: t.lang || undefined\n }));\n emit(\"audio-tracks\", list);\n };\n\n hls.on(Hls.Events.MANIFEST_PARSED, tryAutoPlay);\n hls.on(Hls.Events.AUDIO_TRACKS_UPDATED, reportHlsTracks);\n hls.on(Hls.Events.AUDIO_TRACK_SWITCHED, reportHlsTracks);\n hls.on(Hls.Events.ERROR, (_evt, data) => {\n if (data.fatal) {\n hls.destroy();\n hlsInstance.value = null;\n }\n });\n\n hls.attachMedia(el);\n hls.loadSource(src);\n } else {\n el.src = src;\n el.load();\n\n // For a plain <video>, wait for metadata so play() has something to start.\n el.addEventListener(\"loadedmetadata\", tryAutoPlay, { once: true });\n detachLoadedMetadata = () => {\n el.removeEventListener(\"loadedmetadata\", tryAutoPlay);\n };\n\n // Native AudioTrackList (Safari, some Chromium). Most browsers don't\n // implement this, so the list stays empty and the wrapper renders no\n // switcher — no dead UI.\n const at = el.audioTracks;\n if (at) {\n const reportNativeTracks = () => {\n const list: AudioTrackInfo[] = [];\n for (let i = 0; i < at.length; i++) {\n const t = at[i];\n list.push({\n index: i,\n label: audioTrackLabel(t.label, t.language, i),\n lang: t.language || undefined\n });\n }\n emit(\"audio-tracks\", list);\n };\n at.addEventListener?.(\"addtrack\", reportNativeTracks);\n at.addEventListener?.(\"removetrack\", reportNativeTracks);\n at.addEventListener?.(\"change\", reportNativeTracks);\n if (at.length > 0) reportNativeTracks();\n detachNative = () => {\n at.removeEventListener?.(\"addtrack\", reportNativeTracks);\n at.removeEventListener?.(\"removetrack\", reportNativeTracks);\n at.removeEventListener?.(\"change\", reportNativeTracks);\n };\n }\n }\n}\n\nfunction applyAudioTrack(index: number) {\n if (index == null || index < 0) return;\n const hls = hlsInstance.value;\n if (hls) {\n if (hls.audioTrack !== index) hls.audioTrack = index;\n return;\n }\n const at = videoEl.value?.audioTracks;\n if (at) {\n for (let i = 0; i < at.length; i++) {\n at[i].enabled = i === index;\n }\n }\n}\n\nonMounted(() => {\n if (props.src) initPlayer(props.src);\n});\n\nwatch(\n () => props.src,\n (src) => {\n if (src) initPlayer(src);\n }\n);\n\nwatch(\n () => props.audioTrackIndex,\n (index) => applyAudioTrack(index)\n);\n\nonBeforeUnmount(cleanup);\n\ndefineExpose({ videoEl });\n</script>\n\n<template>\n <video\n ref=\"videoEl\"\n :muted=\"muted\"\n :loop=\"loop\"\n :controls=\"controls\"\n :autoplay=\"autoPlay\"\n :playsinline=\"playsInline\"\n :preload=\"preload\"\n :poster=\"poster\"\n :class=\"props.class\"\n @play=\"emit('play')\"\n @pause=\"emit('pause')\"\n >\n <slot />\n </video>\n</template>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M3 14V10C3 9.44772 3.44772 9 4 9H6.58579C6.851 9 7.10536 8.89464 7.29289 8.70711L11.2929 4.70711C11.9229 4.07714 13 4.52331 13 5.41421V18.5858C13 19.4767 11.9229 19.9229 11.2929 19.2929L7.29289 15.2929C7.10536 15.1054 6.851 15 6.58579 15H4C3.44772 15 3 14.5523 3 14Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M16.5 8C17.5 9 18 10.5 18 12C18 13.5 17.5 15 16.5 16M19 5.5C20.5 7 21.5 9.5 21.5 12C21.5 14.5 20.5 17 19 18.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconAudio\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 9L12 15L18 9\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconChevron\" };\n</script>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, watch } from \"vue\";\nimport IconAudio from \"./IconAudio.vue\";\nimport IconChevron from \"./IconChevron.vue\";\nimport type { AudioTrackInfo } from \"../utils/audio-tracks\";\n\nconst props = defineProps<{\n tracks: AudioTrackInfo[];\n activeIndex: number;\n}>();\n\nconst emit = defineEmits<{\n select: [index: number];\n}>();\n\nconst open = ref(false);\nconst rootEl = ref<HTMLElement | null>(null);\n\nconst active = computed(\n () => props.tracks.find((t) => t.index === props.activeIndex) ?? props.tracks[0]\n);\n\nfunction onDocClick(e: MouseEvent) {\n if (rootEl.value && !rootEl.value.contains(e.target as Node)) {\n open.value = false;\n }\n}\n\nfunction onEsc(e: KeyboardEvent) {\n if (e.key === \"Escape\") open.value = false;\n}\n\nwatch(open, (isOpen) => {\n if (isOpen) {\n document.addEventListener(\"mousedown\", onDocClick);\n document.addEventListener(\"keydown\", onEsc);\n } else {\n document.removeEventListener(\"mousedown\", onDocClick);\n document.removeEventListener(\"keydown\", onEsc);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener(\"mousedown\", onDocClick);\n document.removeEventListener(\"keydown\", onEsc);\n});\n\nfunction pick(index: number) {\n emit(\"select\", index);\n open.value = false;\n}\n</script>\n\n<template>\n <div ref=\"rootEl\" class=\"gvp-audio\">\n <button\n type=\"button\"\n class=\"gvp-audio-btn\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"open\"\n aria-label=\"Audio track\"\n @click=\"open = !open\"\n >\n <IconAudio />\n <span class=\"gvp-audio-label\">{{ active?.label }}</span>\n <IconChevron />\n </button>\n <!--\n A native <select> can't be styled to sit inside the player overlay\n (it renders the OS dropdown chrome), so this is a custom listbox.\n -->\n <ul\n v-if=\"open\"\n class=\"gvp-audio-menu\"\n role=\"listbox\"\n aria-label=\"Audio tracks\"\n >\n <li v-for=\"t in tracks\" :key=\"t.index\">\n <button\n type=\"button\"\n role=\"option\"\n :aria-selected=\"t.index === activeIndex\"\n :class=\"['gvp-audio-menu-item', { 'is-active': t.index === activeIndex }]\"\n @click=\"pick(t.index)\"\n >\n {{ t.label }}\n </button>\n </li>\n </ul>\n </div>\n</template>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n />\n <path\n d=\"M12 8V12L14.5 14.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconSpeed\" };\n</script>\n","<script setup lang=\"ts\">\nimport { onBeforeUnmount, ref, watch } from \"vue\";\nimport IconSpeed from \"./IconSpeed.vue\";\nimport IconChevron from \"./IconChevron.vue\";\n\nconst SPEED_OPTIONS = [0.5, 0.75, 1, 1.25, 1.5, 2];\n\nconst props = defineProps<{ speed: number }>();\nconst emit = defineEmits<{ select: [rate: number] }>();\n\nconst open = ref(false);\nconst rootEl = ref<HTMLElement | null>(null);\n\nfunction onDocClick(e: MouseEvent) {\n if (rootEl.value && !rootEl.value.contains(e.target as Node)) {\n open.value = false;\n }\n}\n\nfunction onEsc(e: KeyboardEvent) {\n if (e.key === \"Escape\") open.value = false;\n}\n\nwatch(open, (isOpen) => {\n if (isOpen) {\n document.addEventListener(\"mousedown\", onDocClick);\n document.addEventListener(\"keydown\", onEsc);\n } else {\n document.removeEventListener(\"mousedown\", onDocClick);\n document.removeEventListener(\"keydown\", onEsc);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener(\"mousedown\", onDocClick);\n document.removeEventListener(\"keydown\", onEsc);\n});\n\nfunction pick(rate: number) {\n emit(\"select\", rate);\n open.value = false;\n}\n</script>\n\n<template>\n <div ref=\"rootEl\" class=\"gvp-speed\">\n <button\n type=\"button\"\n class=\"gvp-speed-btn\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"open\"\n aria-label=\"`Playback speed: ${speed === 1 ? '1×' : speed + '×'}`\"\n @click=\"open = !open\"\n >\n <IconSpeed />\n <span class=\"gvp-speed-label\">{{ speed === 1 ? \"1×\" : `${speed}×` }}</span>\n <IconChevron />\n </button>\n <!--\n A native <select> can't be styled to sit inside the player overlay\n (it renders the OS dropdown chrome), so this is a custom listbox.\n -->\n <ul\n v-if=\"open\"\n class=\"gvp-speed-menu\"\n role=\"listbox\"\n aria-label=\"Playback speed\"\n >\n <li v-for=\"rate in SPEED_OPTIONS\" :key=\"rate\">\n <button\n type=\"button\"\n role=\"option\"\n :aria-selected=\"rate === speed\"\n :class=\"['gvp-speed-menu-item', { 'is-active': rate === speed }]\"\n @click=\"pick(rate)\"\n >\n {{ rate === 1 ? \"Normal\" : `${rate}×` }}\n </button>\n </li>\n </ul>\n </div>\n</template>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <rect x=\"2\" y=\"5\" width=\"20\" height=\"14\" rx=\"3\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n <path d=\"M7 12H11M13 12H17M7 15H9M11 15H13M15 15H17\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconCaptions\" };\n</script>\n","<script setup lang=\"ts\">\nimport { onBeforeUnmount, ref, watch } from \"vue\";\nimport IconCaptions from \"./IconCaptions.vue\";\n\ninterface TextTrackItem {\n index: number;\n label: string;\n}\n\nconst props = defineProps<{\n video: HTMLVideoElement | null;\n}>();\n\nconst tracks = ref<TextTrackItem[]>([]);\nconst activeIndex = ref(-1); // -1 = Off\nconst open = ref(false);\nconst rootEl = ref<HTMLElement | null>(null);\n\n// TextTrackList has indexed access but is not a true iterable in all envs.\nfunction snapshot(tl: TextTrackList) {\n const items: TextTrackItem[] = [];\n for (let i = 0; i < tl.length; i++) {\n const t = tl[i];\n if (t.kind === \"subtitles\" || t.kind === \"captions\") {\n items.push({ index: i, label: t.label || t.language || `Track ${i + 1}` });\n }\n }\n tracks.value = items;\n let active = -1;\n for (let i = 0; i < tl.length; i++) {\n if (tl[i].mode === \"showing\") { active = i; break; }\n }\n activeIndex.value = active;\n}\n\nlet cleanupTracks: (() => void) | null = null;\n\nwatch(() => props.video, (el) => {\n cleanupTracks?.();\n cleanupTracks = null;\n if (!el) { tracks.value = []; activeIndex.value = -1; return; }\n const tl = el.textTracks;\n snapshot(tl);\n const onChange = () => snapshot(tl);\n if (typeof tl.addEventListener === \"function\") {\n tl.addEventListener(\"addtrack\", onChange);\n tl.addEventListener(\"removetrack\", onChange);\n tl.addEventListener(\"change\", onChange);\n cleanupTracks = () => {\n tl.removeEventListener(\"addtrack\", onChange);\n tl.removeEventListener(\"removetrack\", onChange);\n tl.removeEventListener(\"change\", onChange);\n };\n }\n}, { immediate: true });\n\nonBeforeUnmount(() => {\n cleanupTracks?.();\n document.removeEventListener(\"mousedown\", onDocClick);\n document.removeEventListener(\"keydown\", onEsc);\n});\n\nfunction onDocClick(e: MouseEvent) {\n if (rootEl.value && !rootEl.value.contains(e.target as Node)) open.value = false;\n}\n\nfunction onEsc(e: KeyboardEvent) {\n if (e.key === \"Escape\") open.value = false;\n}\n\nwatch(open, (isOpen) => {\n if (isOpen) {\n document.addEventListener(\"mousedown\", onDocClick);\n document.addEventListener(\"keydown\", onEsc);\n } else {\n document.removeEventListener(\"mousedown\", onDocClick);\n document.removeEventListener(\"keydown\", onEsc);\n }\n});\n\nfunction pickOff() {\n if (!props.video) return;\n const tl = props.video.textTracks;\n for (let i = 0; i < tl.length; i++) tl[i].mode = \"hidden\";\n activeIndex.value = -1;\n open.value = false;\n}\n\nfunction pick(index: number) {\n if (!props.video) return;\n const tl = props.video.textTracks;\n for (let i = 0; i < tl.length; i++) {\n tl[i].mode = i === index ? \"showing\" : \"hidden\";\n }\n activeIndex.value = index;\n open.value = false;\n}\n</script>\n\n<template>\n <div v-if=\"tracks.length > 0\" ref=\"rootEl\" class=\"gvp-captions\">\n <button\n type=\"button\"\n :class=\"['gvp-captions-btn', { 'is-active': activeIndex >= 0 }]\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"open\"\n :aria-pressed=\"activeIndex >= 0\"\n aria-label=\"Captions\"\n @click=\"open = !open\"\n >\n <IconCaptions />\n </button>\n <!--\n A native <select> can't be styled to sit inside the player overlay\n (it renders the OS dropdown chrome), so this is a custom listbox.\n -->\n <ul\n v-if=\"open\"\n class=\"gvp-captions-menu\"\n role=\"listbox\"\n aria-label=\"Captions\"\n >\n <li>\n <button\n type=\"button\"\n role=\"option\"\n :aria-selected=\"activeIndex === -1\"\n :class=\"['gvp-captions-menu-item', { 'is-active': activeIndex === -1 }]\"\n @click=\"pickOff\"\n >\n Off\n </button>\n </li>\n <li v-for=\"t in tracks\" :key=\"t.index\">\n <button\n type=\"button\"\n role=\"option\"\n :aria-selected=\"t.index === activeIndex\"\n :class=\"['gvp-captions-menu-item', { 'is-active': t.index === activeIndex }]\"\n @click=\"pick(t.index)\"\n >\n {{ t.label }}\n </button>\n </li>\n </ul>\n </div>\n</template>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <rect x=\"6\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" fill=\"currentColor\" />\n <rect x=\"14\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" fill=\"currentColor\" />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconPause\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M7 5.5V18.5C7 19.2659 7.84856 19.7261 8.4899 19.3071L19.0801 12.4014C19.6644 12.0204 19.6644 11.9796 19.0801 11.5986L8.4899 4.69288C7.84856 4.27388 7 4.73408 7 5.5Z\"\n fill=\"currentColor\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconPlaySolid\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M3 14V10C3 9.44772 3.44772 9 4 9H6.58579C6.851 9 7.10536 8.89464 7.29289 8.70711L11.2929 4.70711C11.9229 4.07714 13 4.52331 13 5.41421V18.5858C13 19.4767 11.9229 19.9229 11.2929 19.2929L7.29289 15.2929C7.10536 15.1054 6.851 15 6.58579 15H4C3.44772 15 3 14.5523 3 14Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M16.5 8C17.5 9 18 10.5 18 12C18 13.5 17.5 15 16.5 16M19 5.5C20.5 7 21.5 9.5 21.5 12C21.5 14.5 20.5 17 19 18.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconVolumeHigh\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M3 14V10C3 9.44772 3.44772 9 4 9H6.58579C6.851 9 7.10536 8.89464 7.29289 8.70711L11.2929 4.70711C11.9229 4.07714 13 4.52331 13 5.41421V18.5858C13 19.4767 11.9229 19.9229 11.2929 19.2929L7.29289 15.2929C7.10536 15.1054 6.851 15 6.58579 15H4C3.44772 15 3 14.5523 3 14Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M16.5 8C17.5 9 18 10.5 18 12C18 13.5 17.5 15 16.5 16\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconVolumeLow\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M3 14V10C3 9.44772 3.44772 9 4 9H6.58579C6.851 9 7.10536 8.89464 7.29289 8.70711L11.2929 4.70711C11.9229 4.07714 13 4.52331 13 5.41421V18.5858C13 19.4767 11.9229 19.9229 11.2929 19.2929L7.29289 15.2929C7.10536 15.1054 6.851 15 6.58579 15H4C3.44772 15 3 14.5523 3 14Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M16 9L22 15M22 9L16 15\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconVolumeMuted\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n <rect x=\"12\" y=\"12\" width=\"8\" height=\"5\" rx=\"1\" fill=\"currentColor\" />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconPiP\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M4 9V4H9M15 4H20V9M20 15V20H15M9 20H4V15\"\n stroke=\"currentColor\"\n stroke-width=\"1.75\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconFullscreen\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M9 4V9H4M15 9V4H20M15 20V15H20M9 15H4V20\"\n stroke=\"currentColor\"\n stroke-width=\"1.75\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconFullscreenExit\" };\n</script>\n","export function formatTime(seconds: number): string {\n if (!Number.isFinite(seconds) || seconds < 0) return \"--:--\";\n const total = Math.floor(seconds);\n const h = Math.floor(total / 3600);\n const m = Math.floor((total % 3600) / 60);\n const s = total % 60;\n const ss = s.toString().padStart(2, \"0\");\n if (h > 0) {\n const mm = m.toString().padStart(2, \"0\");\n return `${h}:${mm}:${ss}`;\n }\n return `${m}:${ss}`;\n}\n","<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref, watch } from \"vue\";\nimport IconPause from \"./IconPause.vue\";\nimport IconPlaySolid from \"./IconPlaySolid.vue\";\nimport IconVolumeHigh from \"./IconVolumeHigh.vue\";\nimport IconVolumeLow from \"./IconVolumeLow.vue\";\nimport IconVolumeMuted from \"./IconVolumeMuted.vue\";\nimport IconSpeed from \"./IconSpeed.vue\";\nimport IconCaptions from \"./IconCaptions.vue\";\nimport IconPiP from \"./IconPiP.vue\";\nimport IconFullscreen from \"./IconFullscreen.vue\";\nimport IconFullscreenExit from \"./IconFullscreenExit.vue\";\nimport { formatTime } from \"../utils/format-time\";\n\n/**\n * On iOS, HTMLVideoElement.volume is read-only (hardware volume only),\n * so the slider has no effect. We detect iOS and show only the mute toggle.\n */\nconst isIOS = (() => {\n if (typeof navigator === \"undefined\") return false;\n const ua = navigator.userAgent;\n return /iPad|iPhone|iPod/.test(ua) || (ua.includes(\"Mac\") && navigator.maxTouchPoints > 1);\n})();\n\nconst isIPhone = (() => {\n if (typeof navigator === \"undefined\") return false;\n return /iPhone|iPod/.test(navigator.userAgent);\n})();\n\nconst AUTO_HIDE_MS = 3000;\nconst SPEED_OPTIONS = [0.5, 0.75, 1, 1.25, 1.5, 2];\n\nconst props = defineProps<{\n video: HTMLVideoElement | null;\n isPlaying: boolean;\n container: HTMLElement | null;\n onTogglePlay: () => void;\n}>();\n\n// ── Visibility / auto-hide ────────────────────────────────────────────────\n\nconst visible = ref(true);\nlet hideTimer: ReturnType<typeof setTimeout> | null = null;\n\nfunction clearHideTimer() {\n if (hideTimer !== null) { clearTimeout(hideTimer); hideTimer = null; }\n}\n\nfunction scheduleHide() {\n clearHideTimer();\n if (!props.isPlaying) return;\n hideTimer = setTimeout(() => { visible.value = false; }, AUTO_HIDE_MS);\n}\n\nfunction showAndScheduleHide() {\n visible.value = true;\n scheduleHide();\n}\n\nwatch(() => props.isPlaying, (playing) => {\n if (!playing) { clearHideTimer(); visible.value = true; }\n else scheduleHide();\n}, { immediate: true });\n\nwatch(() => props.container, (el) => {\n if (!el) return;\n const handler = () => showAndScheduleHide();\n el.addEventListener(\"mousemove\", handler);\n el.addEventListener(\"touchstart\", handler);\n el.addEventListener(\"focusin\", handler);\n}, { immediate: true });\n\n// ── Seek bar ──────────────────────────────────────────────────────────────\n\nconst currentTime = ref(0);\nconst duration = ref(0);\nconst buffered = ref(0);\n\nwatch(() => props.video, (el) => {\n if (!el) return;\n const onTime = () => { currentTime.value = el.currentTime; };\n const onDuration = () => { duration.value = Number.isFinite(el.duration) ? el.duration : 0; };\n const onProgress = () => {\n const ranges = el.buffered;\n if (!ranges || ranges.length === 0) { buffered.value = 0; return; }\n let end = ranges.end(ranges.length - 1);\n for (let i = 0; i < ranges.length; i++) {\n if (ranges.start(i) <= el.currentTime && el.currentTime <= ranges.end(i)) {\n end = ranges.end(i); break;\n }\n }\n buffered.value = end;\n };\n onTime(); onDuration(); onProgress();\n el.addEventListener(\"timeupdate\", onTime);\n el.addEventListener(\"durationchange\", onDuration);\n el.addEventListener(\"loadedmetadata\", onDuration);\n el.addEventListener(\"progress\", onProgress);\n el.addEventListener(\"timeupdate\", onProgress);\n}, { immediate: true });\n\nconst seekable = () => duration.value > 0;\nconst progressPct = () => seekable() ? (currentTime.value / duration.value) * 100 : 0;\nconst bufferedPct = () => seekable() ? (buffered.value / duration.value) * 100 : 0;\n\nfunction onSeekInput(e: Event) {\n const el = props.video;\n if (!el || !seekable()) return;\n const t = (Number((e.target as HTMLInputElement).value) / 100) * duration.value;\n el.currentTime = t;\n currentTime.value = t;\n}\n\n// ── Volume ────────────────────────────────────────────────────────────────\n\nconst volume = ref(1);\nconst muted = ref(false);\n\nwatch(() => props.video, (el) => {\n if (!el) return;\n const onChange = () => { volume.value = el.volume; muted.value = el.muted; };\n onChange();\n el.addEventListener(\"volumechange\", onChange);\n}, { immediate: true });\n\nfunction toggleMute() {\n if (props.video) props.video.muted = !props.video.muted;\n}\n\nfunction onVolumeInput(e: Event) {\n const el = props.video;\n if (!el) return;\n const v = Number((e.target as HTMLInputElement).value) / 100;\n el.volume = v;\n if (v > 0 && el.muted) el.muted = false;\n}\n\n// ── Speed ─────────────────────────────────────────────────────────────────\n\nconst speed = ref(1);\nconst speedOpen = ref(false);\nconst speedRootEl = ref<HTMLElement | null>(null);\n\nwatch(() => props.video, (el) => {\n if (!el) return;\n const onRate = () => { speed.value = el.playbackRate; };\n onRate();\n el.addEventListener(\"ratechange\", onRate);\n}, { immediate: true });\n\nfunction pickSpeed(rate: number) {\n if (props.video) props.video.playbackRate = rate;\n speed.value = rate;\n speedOpen.value = false;\n}\n\n// ── Captions ──────────────────────────────────────────────────────────────\n\ninterface TextTrackItem { index: number; label: string; }\n\nconst captionTracks = ref<TextTrackItem[]>([]);\nconst activeCaptionIndex = ref(-1);\nconst captionsOpen = ref(false);\nconst captionsRootEl = ref<HTMLElement | null>(null);\n\nfunction snapshotTracks(tl: TextTrackList) {\n const items: TextTrackItem[] = [];\n for (let i = 0; i < tl.length; i++) {\n const t = tl[i];\n if (t.kind === \"subtitles\" || t.kind === \"captions\") {\n items.push({ index: i, label: t.label || t.language || `Track ${i + 1}` });\n }\n }\n captionTracks.value = items;\n let active = -1;\n for (let i = 0; i < tl.length; i++) {\n if (tl[i].mode === \"showing\") { active = i; break; }\n }\n activeCaptionIndex.value = active;\n}\n\nwatch(() => props.video, (el) => {\n if (!el) { captionTracks.value = []; activeCaptionIndex.value = -1; return; }\n const tl = el.textTracks;\n snapshotTracks(tl);\n const onChange = () => snapshotTracks(tl);\n if (typeof tl.addEventListener === \"function\") {\n tl.addEventListener(\"addtrack\", onChange);\n tl.addEventListener(\"removetrack\", onChange);\n tl.addEventListener(\"change\", onChange);\n }\n}, { immediate: true });\n\nfunction pickCaption(index: number) {\n const tl = props.video?.textTracks;\n if (!tl) return;\n for (let i = 0; i < tl.length; i++) tl[i].mode = i === index ? \"showing\" : \"hidden\";\n activeCaptionIndex.value = index;\n captionsOpen.value = false;\n}\n\nfunction pickCaptionOff() {\n const tl = props.video?.textTracks;\n if (!tl) return;\n for (let i = 0; i < tl.length; i++) tl[i].mode = \"hidden\";\n activeCaptionIndex.value = -1;\n captionsOpen.value = false;\n}\n\n// ── PiP ───────────────────────────────────────────────────────────────────\n\nconst isPiP = ref(false);\nconst pipSupported = typeof document !== \"undefined\" && !!document.pictureInPictureEnabled;\n\nwatch(() => props.video, (el) => {\n if (!el) return;\n el.addEventListener(\"enterpictureinpicture\", () => { isPiP.value = true; });\n el.addEventListener(\"leavepictureinpicture\", () => { isPiP.value = false; });\n}, { immediate: true });\n\nfunction togglePiP() {\n if (!props.video) return;\n if (document.pictureInPictureElement) {\n document.exitPictureInPicture().catch(() => { /* ignore */ });\n } else {\n props.video.requestPictureInPicture().catch(() => { /* ignore */ });\n }\n}\n\n// ── Fullscreen ────────────────────────────────────────────────────────────\n\nconst isFs = ref(false);\n\nconst fullscreenSupported = (() => {\n if (typeof document === \"undefined\") return false;\n return Boolean(document.fullscreenEnabled || (document as Document & { webkitFullscreenEnabled?: boolean }).webkitFullscreenEnabled);\n})();\n\nfunction fsElement() {\n return (document.fullscreenElement ?? (document as Document & { webkitFullscreenElement?: Element | null }).webkitFullscreenElement ?? null);\n}\n\nfunction fsRequest(el: HTMLElement) {\n const r = el.requestFullscreen ?? (el as HTMLElement & { webkitRequestFullscreen?(): Promise<void> }).webkitRequestFullscreen;\n return r ? r.call(el) : Promise.reject(new Error(\"unsupported\"));\n}\n\nfunction fsExit() {\n const e = document.exitFullscreen ?? (document as Document & { webkitExitFullscreen?(): Promise<void> }).webkitExitFullscreen;\n return e ? e.call(document) : Promise.reject(new Error(\"unsupported\"));\n}\n\nfunction onFsChange() { isFs.value = fsElement() === props.container; }\n\nonMounted(() => {\n document.addEventListener(\"fullscreenchange\", onFsChange);\n document.addEventListener(\"webkitfullscreenchange\", onFsChange);\n});\nonBeforeUnmount(() => {\n clearHideTimer();\n document.removeEventListener(\"fullscreenchange\", onFsChange);\n document.removeEventListener(\"webkitfullscreenchange\", onFsChange);\n});\n\nfunction toggleFs() {\n if (isIPhone) {\n (props.video as HTMLVideoElement & { webkitEnterFullscreen?(): void })?.webkitEnterFullscreen?.();\n return;\n }\n if (isFs.value) { fsExit().catch(() => { /* ignore */ }); }\n else if (props.container) { fsRequest(props.container).catch(() => { /* ignore */ }); }\n}\n\nconst fsButtonSupported = fullscreenSupported ||\n (isIPhone && props.video !== null &&\n typeof (props.video as HTMLVideoElement & { webkitEnterFullscreen?(): void }).webkitEnterFullscreen === \"function\");\n\n// ── Click-outside for open menus ──────────────────────────────────────────\n\nfunction useClickOutside(openRef: { value: boolean }, rootRef: { value: HTMLElement | null }) {\n function onDocClick(e: MouseEvent) {\n if (rootRef.value && !rootRef.value.contains(e.target as Node)) openRef.value = false;\n }\n function onEsc(e: KeyboardEvent) { if (e.key === \"Escape\") openRef.value = false; }\n watch(openRef, (isOpen) => {\n if (isOpen) {\n document.addEventListener(\"mousedown\", onDocClick);\n document.addEventListener(\"keydown\", onEsc);\n } else {\n document.removeEventListener(\"mousedown\", onDocClick);\n document.removeEventListener(\"keydown\", onEsc);\n }\n });\n onBeforeUnmount(() => {\n document.removeEventListener(\"mousedown\", onDocClick);\n document.removeEventListener(\"keydown\", onEsc);\n });\n}\n\nuseClickOutside(speedOpen, speedRootEl);\nuseClickOutside(captionsOpen, captionsRootEl);\n</script>\n\n<template>\n <div\n role=\"toolbar\"\n aria-label=\"Video controls\"\n :class=\"['gvp-controls', !visible && 'is-hidden']\"\n @mouseenter=\"clearHideTimer\"\n @mouseleave=\"scheduleHide\"\n >\n <div class=\"gvp-controls-row\">\n\n <!-- Play / Pause -->\n <button\n type=\"button\"\n class=\"gvp-ctrl-btn\"\n :aria-label=\"isPlaying ? 'Pause' : 'Play'\"\n :aria-pressed=\"isPlaying\"\n @click=\"onTogglePlay\"\n >\n <IconPause v-if=\"isPlaying\" />\n <IconPlaySolid v-else />\n </button>\n\n <!-- Seek bar -->\n <div class=\"gvp-seek\">\n <div class=\"gvp-seek-track\">\n <div class=\"gvp-seek-buffered\" :style=\"{ width: `${bufferedPct()}%` }\" />\n <div class=\"gvp-seek-progress\" :style=\"{ width: `${progressPct()}%` }\" />\n </div>\n <input\n type=\"range\"\n class=\"gvp-seek-input\"\n :min=\"0\"\n :max=\"100\"\n :step=\"0.1\"\n :value=\"progressPct()\"\n :disabled=\"!seekable()\"\n aria-label=\"Seek\"\n :aria-valuemin=\"0\"\n :aria-valuemax=\"Math.floor(duration)\"\n :aria-valuenow=\"Math.floor(currentTime)\"\n @input=\"onSeekInput\"\n />\n </div>\n\n <!-- Time -->\n <span class=\"gvp-time\" aria-live=\"off\">\n {{ formatTime(currentTime) }} / {{ formatTime(duration) }}\n </span>\n\n <!-- Speed -->\n <div ref=\"speedRootEl\" class=\"gvp-speed\">\n <button\n type=\"button\"\n class=\"gvp-ctrl-btn gvp-speed-btn\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"speedOpen\"\n :aria-label=\"`Playback speed: ${speed === 1 ? '1×' : speed + '×'}`\"\n @click=\"speedOpen = !speedOpen\"\n >\n <IconSpeed />\n <span class=\"gvp-speed-label\">{{ speed === 1 ? \"1×\" : `${speed}×` }}</span>\n </button>\n <!-- NOSONAR: vue:S6819 -->\n <ul v-if=\"speedOpen\" class=\"gvp-speed-menu\" role=\"listbox\" aria-label=\"Playback speed\">\n <li v-for=\"rate in SPEED_OPTIONS\" :key=\"rate\">\n <button\n type=\"button\"\n role=\"option\"\n :aria-selected=\"rate === speed\"\n :class=\"['gvp-speed-menu-item', { 'is-active': rate === speed }]\"\n @click=\"pickSpeed(rate)\"\n >\n {{ rate === 1 ? \"Normal\" : `${rate}×` }}\n </button>\n </li>\n </ul>\n </div>\n\n <!-- Captions -->\n <div v-if=\"captionTracks.length > 0\" ref=\"captionsRootEl\" class=\"gvp-captions\">\n <button\n type=\"button\"\n :class=\"['gvp-ctrl-btn', activeCaptionIndex >= 0 && 'is-active']\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"captionsOpen\"\n aria-label=\"Captions\"\n :aria-pressed=\"activeCaptionIndex >= 0\"\n @click=\"captionsOpen = !captionsOpen\"\n >\n <IconCaptions />\n </button>\n <!-- NOSONAR: vue:S6819 -->\n <ul v-if=\"captionsOpen\" class=\"gvp-captions-menu\" role=\"listbox\" aria-label=\"Captions\">\n <li>\n <button\n type=\"button\"\n role=\"option\"\n :aria-selected=\"activeCaptionIndex === -1\"\n :class=\"['gvp-captions-menu-item', { 'is-active': activeCaptionIndex === -1 }]\"\n @click=\"pickCaptionOff\"\n >Off</button>\n </li>\n <li v-for=\"t in captionTracks\" :key=\"t.index\">\n <button\n type=\"button\"\n role=\"option\"\n :aria-selected=\"t.index === activeCaptionIndex\"\n :class=\"['gvp-captions-menu-item', { 'is-active': t.index === activeCaptionIndex }]\"\n @click=\"pickCaption(t.index)\"\n >{{ t.label }}</button>\n </li>\n </ul>\n </div>\n\n <!-- Volume -->\n <div :class=\"['gvp-volume', !isIOS && 'is-expandable']\">\n <button\n type=\"button\"\n class=\"gvp-ctrl-btn\"\n :aria-label=\"muted ? 'Unmute' : 'Mute'\"\n :aria-pressed=\"muted\"\n @click=\"toggleMute\"\n >\n <IconVolumeMuted v-if=\"muted || volume === 0\" />\n <IconVolumeLow v-else-if=\"volume < 0.5\" />\n <IconVolumeHigh v-else />\n </button>\n <div v-if=\"!isIOS\" class=\"gvp-volume-slider-wrap\">\n <div class=\"gvp-volume-track\">\n <div class=\"gvp-volume-fill\" :style=\"{ width: `${muted ? 0 : Math.round(volume * 100)}%` }\" />\n </div>\n <input\n type=\"range\"\n class=\"gvp-volume-input\"\n :min=\"0\"\n :max=\"100\"\n :step=\"1\"\n :value=\"muted ? 0 : Math.round(volume * 100)\"\n aria-label=\"Volume\"\n :aria-valuemin=\"0\"\n :aria-valuemax=\"100\"\n :aria-valuenow=\"muted ? 0 : Math.round(volume * 100)\"\n @input=\"onVolumeInput\"\n />\n </div>\n </div>\n\n <!-- PiP -->\n <button\n v-if=\"pipSupported\"\n type=\"button\"\n :class=\"['gvp-ctrl-btn', isPiP && 'is-active']\"\n :aria-label=\"isPiP ? 'Exit picture-in-picture' : 'Picture-in-picture'\"\n :aria-pressed=\"isPiP\"\n @click=\"togglePiP\"\n >\n <IconPiP />\n </button>\n\n <!-- Fullscreen -->\n <button\n v-if=\"fsButtonSupported\"\n type=\"button\"\n :class=\"['gvp-ctrl-btn', isFs && 'is-active']\"\n :aria-label=\"isFs ? 'Exit fullscreen' : 'Enter fullscreen'\"\n :aria-pressed=\"isFs\"\n @click=\"toggleFs\"\n >\n <IconFullscreenExit v-if=\"isFs\" />\n <IconFullscreen v-else />\n </button>\n\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M14 2H10C6.72077 2 5.08116 2 3.91891 2.81382C3.48891 3.1149 3.1149 3.48891 2.81382 3.91891C2 5.08116 2 6.72077 2 10C2 13.2792 2 14.9188 2.81382 16.0811C3.1149 16.5111 3.48891 16.8851 3.91891 17.1862C5.08116 18 6.72077 18 10 18H14C17.2792 18 18.9188 18 20.0811 17.1862C20.5111 16.8851 20.8851 16.5111 21.1862 16.0811C22 14.9188 22 13.2792 22 10C22 6.72077 22 5.08116 21.1862 3.91891C20.8851 3.48891 20.5111 3.1149 20.0811 2.81382C18.9188 2 17.2792 2 14 2Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n <path\n d=\"M11 15H13\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M14.5 22L14.1845 21.5811C13.4733 20.6369 13.2969 19.1944 13.7468 18M9.5 22L9.8155 21.5811C10.5267 20.6369 10.7031 19.1944 10.2532 18\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n <path\n d=\"M7 22H17\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconDesktop\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5 9C5 5.70017 5 4.05025 6.02513 3.02513C7.05025 2 8.70017 2 12 2C15.2998 2 16.9497 2 17.9749 3.02513C19 4.05025 19 5.70017 19 9V15C19 18.2998 19 19.9497 17.9749 20.9749C16.9497 22 15.2998 22 12 22C8.70017 22 7.05025 22 6.02513 20.9749C5 19.9497 5 18.2998 5 15V9Z\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n <path\n d=\"M11 19H13\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M9 2L9.089 2.53402C9.28188 3.69129 9.37832 4.26993 9.77519 4.62204C10.1892 4.98934 10.7761 5 12 5C13.2239 5 13.8108 4.98934 14.2248 4.62204C14.6217 4.26993 14.7181 3.69129 14.911 2.53402L15 2\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linejoin=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconMobile\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"22\"\n height=\"22\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5.3335 11.45V4.54997C5.3335 4.36108 5.40016 4.20275 5.5335 4.07497C5.66683 3.94719 5.82238 3.8833 6.00016 3.8833C6.05572 3.8833 6.11405 3.89163 6.17516 3.9083C6.23627 3.92497 6.29461 3.94997 6.35016 3.9833L11.7835 7.4333C11.8835 7.49997 11.9585 7.5833 12.0085 7.6833C12.0585 7.7833 12.0835 7.88886 12.0835 7.99997C12.0835 8.11108 12.0585 8.21663 12.0085 8.31663C11.9585 8.41663 11.8835 8.49997 11.7835 8.56663L6.35016 12.0166C6.29461 12.05 6.23627 12.075 6.17516 12.0916C6.11405 12.1083 6.05572 12.1166 6.00016 12.1166C5.82238 12.1166 5.66683 12.0527 5.5335 11.925C5.40016 11.7972 5.3335 11.6389 5.3335 11.45Z\"\n fill=\"currentColor\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconPlay\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6.94994 5.53594L12.1929 0.292938C12.5834 -0.0975275 13.2165 -0.0975279 13.6069 0.292938C13.9974 0.683403 13.9974 1.31647 13.6069 1.70694L8.36394 6.94994L13.6069 12.1929C13.9974 12.5834 13.9974 13.2165 13.6069 13.6069C13.2165 13.9974 12.5834 13.9974 12.1929 13.6069L6.94994 8.36394L1.70694 13.6069C1.31647 13.9974 0.683403 13.9974 0.292938 13.6069C-0.0975279 13.2165 -0.0975277 12.5834 0.292938 12.1929L5.53594 6.94994L0.292938 1.70694C-0.0975279 1.31647 -0.0975279 0.683403 0.292938 0.292938C0.683403 -0.0975279 1.31647 -0.0975277 1.70694 0.292938L6.94994 5.53594Z\"\n fill=\"currentColor\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconX\" };\n</script>\n","/**\n * Extract a YouTube video ID from any common URL form, or `null` if the URL\n * isn't a YouTube link.\n *\n * Recognised:\n * - https://www.youtube.com/watch?v=ID\n * - https://youtube.com/watch?v=ID&t=42\n * - https://youtu.be/ID\n * - https://youtu.be/ID?t=42\n * - https://www.youtube.com/embed/ID\n * - https://www.youtube.com/shorts/ID\n * - https://music.youtube.com/watch?v=ID\n * - bare 11-character video IDs\n */\nexport function parseYouTubeId(input: string): string | null {\n if (!input) return null;\n\n if (/^[A-Za-z0-9_-]{11}$/.test(input)) return input;\n\n let url: URL;\n try {\n url = new URL(input);\n } catch {\n return null;\n }\n\n const host = url.hostname.replace(/^www\\./, \"\");\n\n if (host === \"youtu.be\") {\n const id = url.pathname.slice(1).split(\"/\")[0];\n return /^[A-Za-z0-9_-]{11}$/.test(id) ? id : null;\n }\n\n if (\n host === \"youtube.com\" ||\n host === \"m.youtube.com\" ||\n host === \"music.youtube.com\" ||\n host === \"youtube-nocookie.com\"\n ) {\n const v = url.searchParams.get(\"v\");\n if (v && /^[A-Za-z0-9_-]{11}$/.test(v)) return v;\n\n const m = /^\\/(?:embed|shorts|v|live)\\/([A-Za-z0-9_-]{11})/.exec(\n url.pathname\n );\n if (m) return m[1];\n }\n\n return null;\n}\n\n/** Extract a `t`/`start` timestamp (in seconds) from a YouTube URL, if present. */\nexport function parseYouTubeStart(input: string): number | null {\n try {\n const url = new URL(input);\n const t = url.searchParams.get(\"t\") ?? url.searchParams.get(\"start\");\n if (!t) return null;\n if (/^\\d+s?$/.test(t)) return Number.parseInt(t, 10);\n const m = /^(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s)?$/.exec(t);\n if (m) {\n const h = Number.parseInt(m[1] ?? \"0\", 10);\n const min = Number.parseInt(m[2] ?? \"0\", 10);\n const s = Number.parseInt(m[3] ?? \"0\", 10);\n const total = h * 3600 + min * 60 + s;\n return total > 0 ? total : null;\n }\n } catch {\n /* not a URL */\n }\n return null;\n}\n\nexport interface YouTubeEmbedOptions {\n /** Start playback immediately. Forces `mute` on, since browsers block sound-on autoplay. */\n autoPlay?: boolean;\n /** Mute the player. */\n muted?: boolean;\n /** Loop the video. */\n loop?: boolean;\n /** Show YouTube's player controls. Defaults to `true`. */\n controls?: boolean;\n /** Start offset in seconds. */\n startSeconds?: number | null;\n}\n\n/**\n * Build a privacy-enhanced YouTube embed URL from a video ID and player options.\n *\n * Notes on YouTube's quirks:\n * - `autoplay=1` only takes effect if `mute=1` is also set (browser policy).\n * - single-video loop requires `loop=1` **and** `playlist=<id>`.\n */\nexport function youTubeEmbedUrl(\n id: string,\n opts: YouTubeEmbedOptions = {}\n): string {\n const {\n autoPlay = false,\n muted = true,\n loop = false,\n controls = true,\n startSeconds\n } = opts;\n\n const params = new URLSearchParams({\n rel: \"0\",\n modestbranding: \"1\",\n playsinline: \"1\",\n controls: controls ? \"1\" : \"0\"\n });\n\n if (autoPlay) {\n params.set(\"autoplay\", \"1\");\n params.set(\"mute\", \"1\"); // required for autoplay to actually fire\n } else if (muted) {\n params.set(\"mute\", \"1\");\n }\n\n if (loop) {\n params.set(\"loop\", \"1\");\n params.set(\"playlist\", id); // YouTube needs this for single-video loop\n }\n\n if (startSeconds && startSeconds > 0) {\n params.set(\"start\", String(startSeconds));\n }\n\n return `https://www.youtube-nocookie.com/embed/${id}?${params.toString()}`;\n}\n","<script lang=\"ts\" setup>\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from \"vue\";\nimport HLSPlayer from \"./HLSPlayer.vue\";\nimport AudioTrackSwitcher from \"./components/AudioTrackSwitcher.vue\";\nimport SpeedSwitcher from \"./components/SpeedSwitcher.vue\";\nimport CaptionsSwitcher from \"./components/CaptionsSwitcher.vue\";\nimport ControlBar from \"./components/ControlBar.vue\";\nimport IconDesktop from \"./components/IconDesktop.vue\";\nimport IconMobile from \"./components/IconMobile.vue\";\nimport IconPiP from \"./components/IconPiP.vue\";\nimport IconPlay from \"./components/IconPlay.vue\";\nimport IconX from \"./components/IconX.vue\";\nimport type { DeviceMode, VideoPlayerProps } from \"./utils/types\";\nimport type { AudioTrackInfo } from \"./utils/audio-tracks\";\nimport { parseYouTubeId, parseYouTubeStart, youTubeEmbedUrl } from \"./utils/youtube\";\n\nconst props = withDefaults(\n defineProps<VideoPlayerProps & { class?: string; closable?: boolean }>(),\n {\n showDeviceToggle: true,\n defaultDevice: \"desktop\",\n hoverPlay: false,\n muted: true,\n loop: false,\n controls: false,\n autoPlay: false,\n closable: false,\n class: \"\"\n }\n);\n\nconst emit = defineEmits<{\n close: [];\n play: [];\n pause: [];\n}>();\n\nconst hlsPlayerRef = ref<InstanceType<typeof HLSPlayer> | null>(null);\nconst device = ref<DeviceMode>(props.defaultDevice);\nconst isPlaying = ref(false);\nconst showTooltip = ref(false);\nconst playPromise = ref<Promise<void> | null>(null);\nconst audioTracks = ref<AudioTrackInfo[]>([]);\nconst audioTrackIndex = ref(-1);\nconst playbackSpeed = ref(1);\nconst isPiP = ref(false);\nconst isHovered = ref(false);\nconst rootEl = ref<HTMLElement | null>(null);\nconst pipSupported = typeof document !== \"undefined\" && !!document.pictureInPictureEnabled;\n\nconst isCustomControls = computed(() => props.controls === \"custom\");\nconst isNativeControls = computed(() => props.controls === true);\n\nconst youTubeId = computed(() => parseYouTubeId(props.src));\nconst isYouTube = computed(() => youTubeId.value !== null);\nconst youTubeSrc = computed(() =>\n youTubeId.value\n ? youTubeEmbedUrl(youTubeId.value, {\n autoPlay: props.autoPlay,\n muted: props.muted,\n loop: props.loop,\n controls: isCustomControls.value ? true : isNativeControls.value,\n startSeconds: parseYouTubeStart(props.src)\n })\n : null\n);\n\nfunction onAudioTracks(tracks: AudioTrackInfo[]) {\n audioTracks.value = tracks;\n audioTrackIndex.value = -1; // reset on new source / level switch\n}\n\nconst showAudioSwitcher = computed(\n () => !isYouTube.value && audioTracks.value.length > 1\n);\nconst activeAudioIndex = computed(() =>\n audioTrackIndex.value >= 0\n ? audioTrackIndex.value\n : (audioTracks.value[0]?.index ?? -1)\n);\n\nconst aspectRatio = computed(() =>\n device.value === \"mobile\"\n ? (props.aspectRatio?.mobile ?? \"9/16\")\n : (props.aspectRatio?.desktop ?? \"16/9\")\n);\n\nconst frameMaxWidth = computed(() =>\n device.value === \"mobile\"\n ? (props.frameMaxWidth?.mobile ?? \"420px\")\n : (props.frameMaxWidth?.desktop ?? \"960px\")\n);\n\nconst videoEl = computed(() => hlsPlayerRef.value?.videoEl ?? null);\n\nasync function safePlay() {\n const el = videoEl.value;\n if (!el) return;\n try {\n if (el.readyState < 2) el.load();\n const p = el.play();\n playPromise.value = p;\n await p;\n isPlaying.value = true;\n } catch {\n isPlaying.value = false;\n } finally {\n playPromise.value = null;\n }\n}\n\nasync function safePause() {\n const el = videoEl.value;\n if (!el) return;\n if (playPromise.value) {\n try {\n await playPromise.value;\n } catch {\n /* play was interrupted; nothing to await */\n }\n }\n el.pause();\n}\n\nasync function hoverStart() {\n if (!props.hoverPlay || isYouTube.value) return;\n await safePlay();\n}\n\nasync function hoverStop() {\n if (!props.hoverPlay || isYouTube.value) return;\n await safePause();\n isPlaying.value = false;\n}\n\nasync function togglePlay() {\n const el = videoEl.value;\n if (!el) return;\n if (el.paused) {\n await safePlay();\n } else {\n await safePause();\n isPlaying.value = false;\n }\n}\n\nfunction onMouseEnter() {\n showTooltip.value = true;\n void hoverStart();\n}\n\nfunction onMouseLeave() {\n showTooltip.value = false;\n void hoverStop();\n}\n\nfunction onSelectSpeed(rate: number) {\n playbackSpeed.value = rate;\n const el = videoEl.value;\n if (el) el.playbackRate = rate;\n}\n\n// Keep playbackSpeed + isPiP in sync from video element events.\nwatch(videoEl, (el) => {\n if (!el) return;\n el.addEventListener(\"ratechange\", () => { playbackSpeed.value = el.playbackRate; });\n el.addEventListener(\"enterpictureinpicture\", () => { isPiP.value = true; });\n el.addEventListener(\"leavepictureinpicture\", () => { isPiP.value = false; });\n});\n\nfunction togglePiP() {\n const el = videoEl.value;\n if (!el) return;\n if (document.pictureInPictureElement) {\n document.exitPictureInPicture().catch(() => { /* ignore */ });\n } else {\n el.requestPictureInPicture().catch(() => { /* ignore */ });\n }\n}\n\n// Keyboard shortcuts — active only while the cursor is over the player or\n// focus is inside it, so we don't steal global shortcuts from the page.\nfunction onKeyDown(e: KeyboardEvent) {\n const el = videoEl.value;\n if (!el) return;\n if (!isHovered.value && !rootEl.value?.contains(document.activeElement)) return;\n const tag = (e.target as HTMLElement).tagName;\n if (tag === \"INPUT\" && e.key !== \" \") return;\n\n switch (e.key) {\n case \" \":\n case \"k\":\n e.preventDefault();\n void togglePlay();\n break;\n case \"ArrowLeft\":\n e.preventDefault();\n el.currentTime = Math.max(0, el.currentTime - 5);\n break;\n case \"ArrowRight\":\n e.preventDefault();\n el.currentTime = Math.min(el.duration || 0, el.currentTime + 5);\n break;\n case \"ArrowUp\":\n e.preventDefault();\n el.volume = Math.min(1, el.volume + 0.1);\n if (el.muted) el.muted = false;\n break;\n case \"ArrowDown\":\n e.preventDefault();\n el.volume = Math.max(0, el.volume - 0.1);\n break;\n case \"m\":\n el.muted = !el.muted;\n break;\n case \"f\": {\n const fsEl = document.fullscreenElement ??\n (document as Document & { webkitFullscreenElement?: Element | null }).webkitFullscreenElement ?? null;\n const req = rootEl.value?.requestFullscreen ??\n (rootEl.value as HTMLElement & { webkitRequestFullscreen?(): Promise<void> })?.webkitRequestFullscreen;\n const exit = document.exitFullscreen ??\n (document as Document & { webkitExitFullscreen?(): Promise<void> }).webkitExitFullscreen;\n if (fsEl === rootEl.value) { exit?.call(document).catch(() => { /* ignore */ }); }\n else if (req && rootEl.value) { req.call(rootEl.value).catch(() => { /* ignore */ }); }\n break;\n }\n case \"p\":\n if (pipSupported) togglePiP();\n break;\n }\n}\n\nonMounted(() => { document.addEventListener(\"keydown\", onKeyDown); });\nonBeforeUnmount(() => { document.removeEventListener(\"keydown\", onKeyDown); });\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n :class=\"['gvp-root', props.class]\"\n :style=\"{ width: frameMaxWidth, aspectRatio }\"\n @mouseenter=\"isHovered = true; onMouseEnter()\"\n @mouseleave=\"isHovered = false; onMouseLeave()\"\n >\n <iframe\n v-if=\"isYouTube\"\n class=\"gvp-video gvp-youtube\"\n :src=\"youTubeSrc ?? undefined\"\n title=\"YouTube video player\"\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\"\n allowfullscreen\n referrerpolicy=\"strict-origin-when-cross-origin\"\n />\n <HLSPlayer\n v-else\n ref=\"hlsPlayerRef\"\n :controls=\"isNativeControls\"\n :hls-config=\"hlsConfig\"\n :is-hls=\"isHls\"\n :loop=\"loop\"\n :muted=\"muted\"\n :auto-play=\"autoPlay\"\n :audio-track-index=\"audioTrackIndex\"\n :plays-inline=\"true\"\n :poster=\"poster\"\n :src=\"src\"\n class=\"gvp-video\"\n preload=\"metadata\"\n @audio-tracks=\"onAudioTracks\"\n @pause=\"\n isPlaying = false;\n emit('pause');\n \"\n @play=\"\n isPlaying = true;\n emit('play');\n \"\n >\n <slot />\n </HLSPlayer>\n\n <div v-if=\"!isYouTube\" class=\"gvp-vignette\" />\n\n <div v-if=\"showDeviceToggle\" class=\"gvp-toggle\">\n <div class=\"gvp-toggle-pill\">\n <button\n :aria-pressed=\"device === 'desktop'\"\n :class=\"['gvp-toggle-btn', { 'is-active': device === 'desktop' }]\"\n aria-label=\"Desktop view\"\n type=\"button\"\n @click=\"device = 'desktop'\"\n >\n <IconDesktop />\n </button>\n\n <div class=\"gvp-toggle-divider\" />\n\n <button\n :aria-pressed=\"device === 'mobile'\"\n :class=\"['gvp-toggle-btn', { 'is-active': device === 'mobile' }]\"\n aria-label=\"Mobile view\"\n type=\"button\"\n @click=\"device = 'mobile'\"\n >\n <IconMobile />\n </button>\n </div>\n </div>\n\n <button\n v-if=\"closable\"\n aria-label=\"Close\"\n class=\"gvp-close\"\n type=\"button\"\n @click=\"emit('close')\"\n >\n <IconX />\n </button>\n\n <!-- Overlay badges — only shown outside custom-controls mode -->\n <AudioTrackSwitcher\n v-if=\"showAudioSwitcher && !isCustomControls\"\n :tracks=\"audioTracks\"\n :active-index=\"activeAudioIndex\"\n @select=\"audioTrackIndex = $event\"\n />\n\n <SpeedSwitcher\n v-if=\"!isYouTube && !isCustomControls\"\n :speed=\"playbackSpeed\"\n @select=\"onSelectSpeed\"\n />\n\n <CaptionsSwitcher v-if=\"!isYouTube && !isCustomControls\" :video=\"videoEl\" />\n\n <button\n v-if=\"!isYouTube && pipSupported && !isCustomControls\"\n type=\"button\"\n :class=\"['gvp-pip-btn', { 'is-active': isPiP }]\"\n :aria-label=\"isPiP ? 'Exit picture-in-picture' : 'Picture-in-picture'\"\n :aria-pressed=\"isPiP\"\n @click=\"togglePiP\"\n >\n <IconPiP />\n </button>\n\n <!-- Click-to-toggle layer in custom-controls mode -->\n <button\n v-if=\"!isYouTube && isCustomControls\"\n type=\"button\"\n class=\"gvp-click-layer\"\n :aria-label=\"isPlaying ? 'Pause' : 'Play'\"\n @click=\"togglePlay\"\n />\n\n <!-- Centered play button (non-custom, non-playing) -->\n <div v-if=\"!isYouTube && !isCustomControls && !isPlaying\" class=\"gvp-play-wrap\">\n <button\n aria-label=\"Play\"\n class=\"gvp-play\"\n type=\"button\"\n @click=\"togglePlay\"\n @mouseenter=\"showTooltip = true\"\n @mouseleave=\"showTooltip = false\"\n >\n <IconPlay />\n <span v-if=\"tooltipText && showTooltip\" class=\"gvp-tooltip\" role=\"tooltip\">\n {{ tooltipText }}\n </span>\n </button>\n </div>\n\n <!-- Custom control bar -->\n <ControlBar\n v-if=\"!isYouTube && isCustomControls\"\n :video=\"videoEl\"\n :is-playing=\"isPlaying\"\n :container=\"rootEl\"\n :on-toggle-play=\"togglePlay\"\n />\n\n <div v-if=\"!isYouTube && !isCustomControls\" class=\"gvp-bottom-fade\" />\n </div>\n</template>\n"],"names":["audioTrackLabel","name","lang","index","trimmed","resolved","props","__props","emit","__emit","videoEl","ref","hlsInstance","detachNative","detachLoadedMetadata","canUseHlsJs","Hls","shouldUseHls","src","cleanup","el","initPlayer","tryAutoPlay","hls","reportHlsTracks","list","t","i","_evt","data","at","reportNativeTracks","_a","_b","_c","applyAudioTrack","onMounted","watch","onBeforeUnmount","__expose","_createElementBlock","_normalizeClass","_renderSlot","_ctx","__default__","_createElementVNode","open","rootEl","active","computed","onDocClick","e","onEsc","isOpen","pick","_cache","$event","_createVNode","IconAudio","_hoisted_2","_toDisplayString","IconChevron","_openBlock","_hoisted_3","_Fragment","_renderList","_hoisted_4","SPEED_OPTIONS","rate","IconSpeed","tracks","activeIndex","snapshot","tl","items","cleanupTracks","onChange","pickOff","IconCaptions","formatTime","seconds","total","h","m","ss","mm","AUTO_HIDE_MS","isIOS","ua","isIPhone","visible","hideTimer","clearHideTimer","scheduleHide","showAndScheduleHide","playing","handler","currentTime","duration","buffered","onTime","onDuration","onProgress","ranges","end","seekable","progressPct","bufferedPct","onSeekInput","volume","muted","toggleMute","onVolumeInput","v","speed","speedOpen","speedRootEl","onRate","pickSpeed","captionTracks","activeCaptionIndex","captionsOpen","captionsRootEl","snapshotTracks","pickCaption","pickCaptionOff","isPiP","pipSupported","togglePiP","isFs","fullscreenSupported","fsElement","fsRequest","r","fsExit","onFsChange","toggleFs","fsButtonSupported","useClickOutside","openRef","rootRef","_hoisted_1","args","_createBlock","IconPause","IconPlaySolid","_hoisted_6","_unref","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_12","_hoisted_13","_hoisted_14","IconVolumeMuted","IconVolumeLow","IconVolumeHigh","_hoisted_16","_hoisted_17","IconPiP","IconFullscreenExit","IconFullscreen","parseYouTubeId","input","url","host","id","parseYouTubeStart","min","s","youTubeEmbedUrl","opts","autoPlay","loop","controls","startSeconds","params","hlsPlayerRef","device","isPlaying","showTooltip","playPromise","audioTracks","audioTrackIndex","playbackSpeed","isHovered","isCustomControls","isNativeControls","youTubeId","isYouTube","youTubeSrc","onAudioTracks","showAudioSwitcher","activeAudioIndex","aspectRatio","frameMaxWidth","safePlay","p","safePause","hoverStart","hoverStop","togglePlay","onMouseEnter","onMouseLeave","onSelectSpeed","onKeyDown","fsEl","req","exit","_normalizeStyle","HLSPlayer","IconDesktop","IconMobile","IconX","AudioTrackSwitcher","SpeedSwitcher","CaptionsSwitcher","IconPlay","ControlBar","_hoisted_11"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/utils/audio-tracks.ts","../src/HLSPlayer.vue","../src/components/IconAudio.vue","../src/components/IconChevron.vue","../src/components/AudioTrackSwitcher.vue","../src/components/IconSpeed.vue","../src/components/SpeedSwitcher.vue","../src/components/IconCaptions.vue","../src/components/CaptionsSwitcher.vue","../src/components/IconPause.vue","../src/components/IconPlaySolid.vue","../src/components/IconVolumeHigh.vue","../src/components/IconVolumeLow.vue","../src/components/IconVolumeMuted.vue","../src/components/IconPiP.vue","../src/components/IconFullscreen.vue","../src/components/IconFullscreenExit.vue","../src/utils/format-time.ts","../src/components/ControlBar.vue","../src/components/IconDesktop.vue","../src/components/IconMobile.vue","../src/components/IconPlay.vue","../src/components/IconX.vue","../src/utils/youtube.ts","../src/VideoPlayer.vue"],"sourcesContent":["/**\n * A normalized audio-track descriptor, independent of whether the source plays\n * through hls.js or the native `<video>` element.\n */\nexport interface AudioTrackInfo {\n /** Stable index into the player's track list. */\n index: number;\n /** Human-readable label, e.g. \"English\", \"Español\", or a fallback. */\n label: string;\n /** BCP-47-ish language code if the source provides one. */\n lang?: string;\n}\n\n/** Build a display label for a track, falling back to language code or \"Audio N\". */\nexport function audioTrackLabel(\n name: string | undefined,\n lang: string | undefined,\n index: number\n): string {\n const trimmed = name?.trim();\n if (trimmed) return trimmed;\n if (lang) {\n try {\n const dn = new Intl.DisplayNames(undefined, { type: \"language\" });\n const resolved = dn.of(lang);\n if (resolved && resolved !== lang) return resolved;\n } catch {\n /* Intl.DisplayNames unavailable or bad code */\n }\n return lang;\n }\n return `Audio ${index + 1}`;\n}\n","<script setup lang=\"ts\">\nimport Hls from \"hls.js\";\nimport { onBeforeUnmount, onMounted, ref, watch } from \"vue\";\nimport type { HlsConfig } from \"hls.js\";\nimport { audioTrackLabel, type AudioTrackInfo } from \"./utils/audio-tracks\";\n\nconst props = withDefaults(\n defineProps<{\n src: string;\n hlsConfig?: HlsConfig;\n isHls?: boolean;\n muted?: boolean;\n loop?: boolean;\n controls?: boolean;\n autoPlay?: boolean;\n playsInline?: boolean;\n preload?: string;\n poster?: string;\n class?: string;\n /** Index of the audio track to activate; `-1` means \"leave at source default\". */\n audioTrackIndex?: number;\n }>(),\n {\n muted: true,\n loop: false,\n controls: false,\n autoPlay: false,\n playsInline: true,\n preload: \"metadata\",\n audioTrackIndex: -1\n }\n);\n\nconst emit = defineEmits<{\n play: [];\n pause: [];\n \"audio-tracks\": [tracks: AudioTrackInfo[]];\n}>();\n\nconst videoEl = ref<HTMLVideoElement | null>(null);\nconst hlsInstance = ref<Hls | null>(null);\nlet detachNative: (() => void) | undefined;\nlet detachLoadedMetadata: (() => void) | undefined;\n\nconst canUseHlsJs = globalThis.window !== undefined && Hls.isSupported();\nconst shouldUseHls = (src: string) =>\n Boolean(props.isHls) || (canUseHlsJs && src.endsWith(\".m3u8\"));\n\nfunction cleanup() {\n detachLoadedMetadata?.();\n detachLoadedMetadata = undefined;\n detachNative?.();\n detachNative = undefined;\n if (hlsInstance.value) {\n hlsInstance.value.destroy();\n hlsInstance.value = null;\n }\n const el = videoEl.value;\n if (!el) return;\n el.pause();\n el.removeAttribute(\"src\");\n while (el.firstChild) el.firstChild.remove();\n el.load();\n emit(\"audio-tracks\", []);\n}\n\nfunction initPlayer(src: string) {\n const el = videoEl.value;\n if (!el || !src) return;\n\n cleanup();\n\n // Tries to start playback once the stream is ready. Browsers only honor\n // sound-on autoplay after a user gesture, so this is best effort — silently\n // swallows the NotAllowedError when blocked.\n const tryAutoPlay = () => {\n if (!props.autoPlay) return;\n el.play().catch(() => {\n /* autoplay blocked; user gesture required */\n });\n };\n\n if (shouldUseHls(src)) {\n const hls = new Hls(props.hlsConfig);\n hlsInstance.value = hls;\n\n const reportHlsTracks = () => {\n const list: AudioTrackInfo[] = hls.audioTracks.map((t, i) => ({\n index: i,\n label: audioTrackLabel(t.name, t.lang, i),\n lang: t.lang || undefined\n }));\n emit(\"audio-tracks\", list);\n };\n\n hls.on(Hls.Events.MANIFEST_PARSED, tryAutoPlay);\n hls.on(Hls.Events.AUDIO_TRACKS_UPDATED, reportHlsTracks);\n hls.on(Hls.Events.AUDIO_TRACK_SWITCHED, reportHlsTracks);\n hls.on(Hls.Events.ERROR, (_evt, data) => {\n if (data.fatal) {\n hls.destroy();\n hlsInstance.value = null;\n }\n });\n\n hls.attachMedia(el);\n hls.loadSource(src);\n } else {\n el.src = src;\n el.load();\n\n // For a plain <video>, wait for metadata so play() has something to start.\n el.addEventListener(\"loadedmetadata\", tryAutoPlay, { once: true });\n detachLoadedMetadata = () => {\n el.removeEventListener(\"loadedmetadata\", tryAutoPlay);\n };\n\n // Native AudioTrackList (Safari, some Chromium). Most browsers don't\n // implement this, so the list stays empty and the wrapper renders no\n // switcher — no dead UI.\n const at = el.audioTracks;\n if (at) {\n const reportNativeTracks = () => {\n const list: AudioTrackInfo[] = [];\n for (let i = 0; i < at.length; i++) {\n const t = at[i];\n list.push({\n index: i,\n label: audioTrackLabel(t.label, t.language, i),\n lang: t.language || undefined\n });\n }\n emit(\"audio-tracks\", list);\n };\n at.addEventListener?.(\"addtrack\", reportNativeTracks);\n at.addEventListener?.(\"removetrack\", reportNativeTracks);\n at.addEventListener?.(\"change\", reportNativeTracks);\n if (at.length > 0) reportNativeTracks();\n detachNative = () => {\n at.removeEventListener?.(\"addtrack\", reportNativeTracks);\n at.removeEventListener?.(\"removetrack\", reportNativeTracks);\n at.removeEventListener?.(\"change\", reportNativeTracks);\n };\n }\n }\n}\n\nfunction applyAudioTrack(index: number) {\n if (index == null || index < 0) return;\n const hls = hlsInstance.value;\n if (hls) {\n if (hls.audioTrack !== index) hls.audioTrack = index;\n return;\n }\n const at = videoEl.value?.audioTracks;\n if (at) {\n for (let i = 0; i < at.length; i++) {\n at[i].enabled = i === index;\n }\n }\n}\n\nonMounted(() => {\n if (props.src) initPlayer(props.src);\n});\n\nwatch(\n () => props.src,\n (src) => {\n if (src) initPlayer(src);\n }\n);\n\nwatch(\n () => props.audioTrackIndex,\n (index) => applyAudioTrack(index)\n);\n\nonBeforeUnmount(cleanup);\n\ndefineExpose({ videoEl });\n</script>\n\n<template>\n <video\n ref=\"videoEl\"\n :muted=\"muted\"\n :loop=\"loop\"\n :controls=\"controls\"\n :autoplay=\"autoPlay\"\n :playsinline=\"playsInline\"\n :preload=\"preload\"\n :poster=\"poster\"\n :class=\"props.class\"\n @play=\"emit('play')\"\n @pause=\"emit('pause')\"\n >\n <slot />\n </video>\n</template>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M3 14V10C3 9.44772 3.44772 9 4 9H6.58579C6.851 9 7.10536 8.89464 7.29289 8.70711L11.2929 4.70711C11.9229 4.07714 13 4.52331 13 5.41421V18.5858C13 19.4767 11.9229 19.9229 11.2929 19.2929L7.29289 15.2929C7.10536 15.1054 6.851 15 6.58579 15H4C3.44772 15 3 14.5523 3 14Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M16.5 8C17.5 9 18 10.5 18 12C18 13.5 17.5 15 16.5 16M19 5.5C20.5 7 21.5 9.5 21.5 12C21.5 14.5 20.5 17 19 18.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconAudio\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 9L12 15L18 9\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconChevron\" };\n</script>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, watch } from \"vue\";\nimport IconAudio from \"./IconAudio.vue\";\nimport IconChevron from \"./IconChevron.vue\";\nimport type { AudioTrackInfo } from \"../utils/audio-tracks\";\n\nconst props = defineProps<{\n tracks: AudioTrackInfo[];\n activeIndex: number;\n}>();\n\nconst emit = defineEmits<{\n select: [index: number];\n}>();\n\nconst open = ref(false);\nconst rootEl = ref<HTMLElement | null>(null);\n\nconst active = computed(\n () => props.tracks.find((t) => t.index === props.activeIndex) ?? props.tracks[0]\n);\n\nfunction onDocClick(e: MouseEvent) {\n if (rootEl.value && !rootEl.value.contains(e.target as Node)) {\n open.value = false;\n }\n}\n\nfunction onEsc(e: KeyboardEvent) {\n if (e.key === \"Escape\") open.value = false;\n}\n\nwatch(open, (isOpen) => {\n if (isOpen) {\n document.addEventListener(\"mousedown\", onDocClick);\n document.addEventListener(\"keydown\", onEsc);\n } else {\n document.removeEventListener(\"mousedown\", onDocClick);\n document.removeEventListener(\"keydown\", onEsc);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener(\"mousedown\", onDocClick);\n document.removeEventListener(\"keydown\", onEsc);\n});\n\nfunction pick(index: number) {\n emit(\"select\", index);\n open.value = false;\n}\n</script>\n\n<template>\n <div ref=\"rootEl\" class=\"gvp-audio\">\n <button\n type=\"button\"\n class=\"gvp-audio-btn\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"open\"\n aria-label=\"Audio track\"\n @click=\"open = !open\"\n >\n <IconAudio />\n <span class=\"gvp-audio-label\">{{ active?.label }}</span>\n <IconChevron />\n </button>\n <!--\n A native <select> can't be styled to sit inside the player overlay\n (it renders the OS dropdown chrome), so this is a custom listbox.\n -->\n <ul\n v-if=\"open\"\n class=\"gvp-audio-menu\"\n role=\"listbox\"\n aria-label=\"Audio tracks\"\n >\n <li v-for=\"t in tracks\" :key=\"t.index\">\n <button\n type=\"button\"\n role=\"option\"\n :aria-selected=\"t.index === activeIndex\"\n :class=\"['gvp-audio-menu-item', { 'is-active': t.index === activeIndex }]\"\n @click=\"pick(t.index)\"\n >\n {{ t.label }}\n </button>\n </li>\n </ul>\n </div>\n</template>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n />\n <path\n d=\"M12 8V12L14.5 14.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconSpeed\" };\n</script>\n","<script setup lang=\"ts\">\nimport { onBeforeUnmount, ref, watch } from \"vue\";\nimport IconSpeed from \"./IconSpeed.vue\";\nimport IconChevron from \"./IconChevron.vue\";\n\nconst SPEED_OPTIONS = [0.5, 0.75, 1, 1.25, 1.5, 2];\n\nconst props = defineProps<{ speed: number }>();\nconst emit = defineEmits<{ select: [rate: number] }>();\n\nconst open = ref(false);\nconst rootEl = ref<HTMLElement | null>(null);\n\nfunction onDocClick(e: MouseEvent) {\n if (rootEl.value && !rootEl.value.contains(e.target as Node)) {\n open.value = false;\n }\n}\n\nfunction onEsc(e: KeyboardEvent) {\n if (e.key === \"Escape\") open.value = false;\n}\n\nwatch(open, (isOpen) => {\n if (isOpen) {\n document.addEventListener(\"mousedown\", onDocClick);\n document.addEventListener(\"keydown\", onEsc);\n } else {\n document.removeEventListener(\"mousedown\", onDocClick);\n document.removeEventListener(\"keydown\", onEsc);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener(\"mousedown\", onDocClick);\n document.removeEventListener(\"keydown\", onEsc);\n});\n\nfunction pick(rate: number) {\n emit(\"select\", rate);\n open.value = false;\n}\n</script>\n\n<template>\n <div ref=\"rootEl\" class=\"gvp-speed\">\n <button\n type=\"button\"\n class=\"gvp-speed-btn\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"open\"\n aria-label=\"`Playback speed: ${speed === 1 ? '1×' : speed + '×'}`\"\n @click=\"open = !open\"\n >\n <IconSpeed />\n <span class=\"gvp-speed-label\">{{ speed === 1 ? \"1×\" : `${speed}×` }}</span>\n <IconChevron />\n </button>\n <!--\n A native <select> can't be styled to sit inside the player overlay\n (it renders the OS dropdown chrome), so this is a custom listbox.\n -->\n <ul\n v-if=\"open\"\n class=\"gvp-speed-menu\"\n role=\"listbox\"\n aria-label=\"Playback speed\"\n >\n <li v-for=\"rate in SPEED_OPTIONS\" :key=\"rate\">\n <button\n type=\"button\"\n role=\"option\"\n :aria-selected=\"rate === speed\"\n :class=\"['gvp-speed-menu-item', { 'is-active': rate === speed }]\"\n @click=\"pick(rate)\"\n >\n {{ rate === 1 ? \"Normal\" : `${rate}×` }}\n </button>\n </li>\n </ul>\n </div>\n</template>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <rect x=\"2\" y=\"5\" width=\"20\" height=\"14\" rx=\"3\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n <path d=\"M7 12H11M13 12H17M7 15H9M11 15H13M15 15H17\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconCaptions\" };\n</script>\n","<script setup lang=\"ts\">\nimport { onBeforeUnmount, ref, watch } from \"vue\";\nimport IconCaptions from \"./IconCaptions.vue\";\n\ninterface TextTrackItem {\n index: number;\n label: string;\n}\n\nconst props = defineProps<{\n video: HTMLVideoElement | null;\n}>();\n\nconst tracks = ref<TextTrackItem[]>([]);\nconst activeIndex = ref(-1); // -1 = Off\nconst open = ref(false);\nconst rootEl = ref<HTMLElement | null>(null);\n\n// TextTrackList has indexed access but is not a true iterable in all envs.\nfunction snapshot(tl: TextTrackList) {\n const items: TextTrackItem[] = [];\n for (let i = 0; i < tl.length; i++) {\n const t = tl[i];\n if (t.kind === \"subtitles\" || t.kind === \"captions\") {\n items.push({ index: i, label: t.label || t.language || `Track ${i + 1}` });\n }\n }\n tracks.value = items;\n let active = -1;\n for (let i = 0; i < tl.length; i++) {\n if (tl[i].mode === \"showing\") { active = i; break; }\n }\n activeIndex.value = active;\n}\n\nlet cleanupTracks: (() => void) | null = null;\n\nwatch(() => props.video, (el) => {\n cleanupTracks?.();\n cleanupTracks = null;\n if (!el) { tracks.value = []; activeIndex.value = -1; return; }\n const tl = el.textTracks;\n snapshot(tl);\n const onChange = () => snapshot(tl);\n if (typeof tl.addEventListener === \"function\") {\n tl.addEventListener(\"addtrack\", onChange);\n tl.addEventListener(\"removetrack\", onChange);\n tl.addEventListener(\"change\", onChange);\n cleanupTracks = () => {\n tl.removeEventListener(\"addtrack\", onChange);\n tl.removeEventListener(\"removetrack\", onChange);\n tl.removeEventListener(\"change\", onChange);\n };\n }\n}, { immediate: true });\n\nonBeforeUnmount(() => {\n cleanupTracks?.();\n document.removeEventListener(\"mousedown\", onDocClick);\n document.removeEventListener(\"keydown\", onEsc);\n});\n\nfunction onDocClick(e: MouseEvent) {\n if (rootEl.value && !rootEl.value.contains(e.target as Node)) open.value = false;\n}\n\nfunction onEsc(e: KeyboardEvent) {\n if (e.key === \"Escape\") open.value = false;\n}\n\nwatch(open, (isOpen) => {\n if (isOpen) {\n document.addEventListener(\"mousedown\", onDocClick);\n document.addEventListener(\"keydown\", onEsc);\n } else {\n document.removeEventListener(\"mousedown\", onDocClick);\n document.removeEventListener(\"keydown\", onEsc);\n }\n});\n\nfunction pickOff() {\n if (!props.video) return;\n const tl = props.video.textTracks;\n for (let i = 0; i < tl.length; i++) tl[i].mode = \"hidden\";\n activeIndex.value = -1;\n open.value = false;\n}\n\nfunction pick(index: number) {\n if (!props.video) return;\n const tl = props.video.textTracks;\n for (let i = 0; i < tl.length; i++) {\n tl[i].mode = i === index ? \"showing\" : \"hidden\";\n }\n activeIndex.value = index;\n open.value = false;\n}\n</script>\n\n<template>\n <div v-if=\"tracks.length > 0\" ref=\"rootEl\" class=\"gvp-captions\">\n <button\n type=\"button\"\n :class=\"['gvp-captions-btn', { 'is-active': activeIndex >= 0 }]\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"open\"\n :aria-pressed=\"activeIndex >= 0\"\n aria-label=\"Captions\"\n @click=\"open = !open\"\n >\n <IconCaptions />\n </button>\n <!--\n A native <select> can't be styled to sit inside the player overlay\n (it renders the OS dropdown chrome), so this is a custom listbox.\n -->\n <ul\n v-if=\"open\"\n class=\"gvp-captions-menu\"\n role=\"listbox\"\n aria-label=\"Captions\"\n >\n <li>\n <button\n type=\"button\"\n role=\"option\"\n :aria-selected=\"activeIndex === -1\"\n :class=\"['gvp-captions-menu-item', { 'is-active': activeIndex === -1 }]\"\n @click=\"pickOff\"\n >\n Off\n </button>\n </li>\n <li v-for=\"t in tracks\" :key=\"t.index\">\n <button\n type=\"button\"\n role=\"option\"\n :aria-selected=\"t.index === activeIndex\"\n :class=\"['gvp-captions-menu-item', { 'is-active': t.index === activeIndex }]\"\n @click=\"pick(t.index)\"\n >\n {{ t.label }}\n </button>\n </li>\n </ul>\n </div>\n</template>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <rect x=\"6\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" fill=\"currentColor\" />\n <rect x=\"14\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" fill=\"currentColor\" />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconPause\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M7 5.5V18.5C7 19.2659 7.84856 19.7261 8.4899 19.3071L19.0801 12.4014C19.6644 12.0204 19.6644 11.9796 19.0801 11.5986L8.4899 4.69288C7.84856 4.27388 7 4.73408 7 5.5Z\"\n fill=\"currentColor\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconPlaySolid\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M3 14V10C3 9.44772 3.44772 9 4 9H6.58579C6.851 9 7.10536 8.89464 7.29289 8.70711L11.2929 4.70711C11.9229 4.07714 13 4.52331 13 5.41421V18.5858C13 19.4767 11.9229 19.9229 11.2929 19.2929L7.29289 15.2929C7.10536 15.1054 6.851 15 6.58579 15H4C3.44772 15 3 14.5523 3 14Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M16.5 8C17.5 9 18 10.5 18 12C18 13.5 17.5 15 16.5 16M19 5.5C20.5 7 21.5 9.5 21.5 12C21.5 14.5 20.5 17 19 18.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconVolumeHigh\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M3 14V10C3 9.44772 3.44772 9 4 9H6.58579C6.851 9 7.10536 8.89464 7.29289 8.70711L11.2929 4.70711C11.9229 4.07714 13 4.52331 13 5.41421V18.5858C13 19.4767 11.9229 19.9229 11.2929 19.2929L7.29289 15.2929C7.10536 15.1054 6.851 15 6.58579 15H4C3.44772 15 3 14.5523 3 14Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M16.5 8C17.5 9 18 10.5 18 12C18 13.5 17.5 15 16.5 16\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconVolumeLow\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M3 14V10C3 9.44772 3.44772 9 4 9H6.58579C6.851 9 7.10536 8.89464 7.29289 8.70711L11.2929 4.70711C11.9229 4.07714 13 4.52331 13 5.41421V18.5858C13 19.4767 11.9229 19.9229 11.2929 19.2929L7.29289 15.2929C7.10536 15.1054 6.851 15 6.58579 15H4C3.44772 15 3 14.5523 3 14Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M16 9L22 15M22 9L16 15\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconVolumeMuted\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n <rect x=\"12\" y=\"12\" width=\"8\" height=\"5\" rx=\"1\" fill=\"currentColor\" />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconPiP\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M4 9V4H9M15 4H20V9M20 15V20H15M9 20H4V15\"\n stroke=\"currentColor\"\n stroke-width=\"1.75\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconFullscreen\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M9 4V9H4M15 9V4H20M15 20V15H20M9 15H4V20\"\n stroke=\"currentColor\"\n stroke-width=\"1.75\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconFullscreenExit\" };\n</script>\n","export function formatTime(seconds: number): string {\n if (!Number.isFinite(seconds) || seconds < 0) return \"--:--\";\n const total = Math.floor(seconds);\n const h = Math.floor(total / 3600);\n const m = Math.floor((total % 3600) / 60);\n const s = total % 60;\n const ss = s.toString().padStart(2, \"0\");\n if (h > 0) {\n const mm = m.toString().padStart(2, \"0\");\n return `${h}:${mm}:${ss}`;\n }\n return `${m}:${ss}`;\n}\n","<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref, watch } from \"vue\";\nimport IconPause from \"./IconPause.vue\";\nimport IconPlaySolid from \"./IconPlaySolid.vue\";\nimport IconVolumeHigh from \"./IconVolumeHigh.vue\";\nimport IconVolumeLow from \"./IconVolumeLow.vue\";\nimport IconVolumeMuted from \"./IconVolumeMuted.vue\";\nimport IconSpeed from \"./IconSpeed.vue\";\nimport IconCaptions from \"./IconCaptions.vue\";\nimport IconPiP from \"./IconPiP.vue\";\nimport IconFullscreen from \"./IconFullscreen.vue\";\nimport IconFullscreenExit from \"./IconFullscreenExit.vue\";\nimport { formatTime } from \"../utils/format-time\";\n\n/**\n * On iOS, HTMLVideoElement.volume is read-only (hardware volume only),\n * so the slider has no effect. We detect iOS and show only the mute toggle.\n */\nconst isIOS = (() => {\n if (typeof navigator === \"undefined\") return false;\n const ua = navigator.userAgent;\n return /iPad|iPhone|iPod/.test(ua) || (ua.includes(\"Mac\") && navigator.maxTouchPoints > 1);\n})();\n\nconst isIPhone = (() => {\n if (typeof navigator === \"undefined\") return false;\n return /iPhone|iPod/.test(navigator.userAgent);\n})();\n\nconst AUTO_HIDE_MS = 3000;\nconst SPEED_OPTIONS = [0.5, 0.75, 1, 1.25, 1.5, 2];\n\nconst props = defineProps<{\n video: HTMLVideoElement | null;\n isPlaying: boolean;\n container: HTMLElement | null;\n onTogglePlay: () => void;\n}>();\n\n// ── Visibility / auto-hide ────────────────────────────────────────────────\n\nconst visible = ref(true);\nlet hideTimer: ReturnType<typeof setTimeout> | null = null;\n\nfunction clearHideTimer() {\n if (hideTimer !== null) { clearTimeout(hideTimer); hideTimer = null; }\n}\n\nfunction scheduleHide() {\n clearHideTimer();\n if (!props.isPlaying) return;\n hideTimer = setTimeout(() => { visible.value = false; }, AUTO_HIDE_MS);\n}\n\nfunction showAndScheduleHide() {\n visible.value = true;\n scheduleHide();\n}\n\nwatch(() => props.isPlaying, (playing) => {\n if (!playing) { clearHideTimer(); visible.value = true; }\n else scheduleHide();\n}, { immediate: true });\n\nwatch(() => props.container, (el) => {\n if (!el) return;\n const handler = () => showAndScheduleHide();\n el.addEventListener(\"mousemove\", handler);\n el.addEventListener(\"touchstart\", handler);\n el.addEventListener(\"focusin\", handler);\n}, { immediate: true });\n\n// ── Seek bar ──────────────────────────────────────────────────────────────\n\nconst currentTime = ref(0);\nconst duration = ref(0);\nconst buffered = ref(0);\n\nwatch(() => props.video, (el) => {\n if (!el) return;\n const onTime = () => { currentTime.value = el.currentTime; };\n const onDuration = () => { duration.value = Number.isFinite(el.duration) ? el.duration : 0; };\n const onProgress = () => {\n const ranges = el.buffered;\n if (!ranges || ranges.length === 0) { buffered.value = 0; return; }\n let end = ranges.end(ranges.length - 1);\n for (let i = 0; i < ranges.length; i++) {\n if (ranges.start(i) <= el.currentTime && el.currentTime <= ranges.end(i)) {\n end = ranges.end(i); break;\n }\n }\n buffered.value = end;\n };\n onTime(); onDuration(); onProgress();\n el.addEventListener(\"timeupdate\", onTime);\n el.addEventListener(\"durationchange\", onDuration);\n el.addEventListener(\"loadedmetadata\", onDuration);\n el.addEventListener(\"progress\", onProgress);\n el.addEventListener(\"timeupdate\", onProgress);\n}, { immediate: true });\n\nconst seekable = () => duration.value > 0;\nconst progressPct = () => seekable() ? (currentTime.value / duration.value) * 100 : 0;\nconst bufferedPct = () => seekable() ? (buffered.value / duration.value) * 100 : 0;\n\nfunction onSeekInput(e: Event) {\n const el = props.video;\n if (!el || !seekable()) return;\n const t = (Number((e.target as HTMLInputElement).value) / 100) * duration.value;\n el.currentTime = t;\n currentTime.value = t;\n}\n\n// ── Volume ────────────────────────────────────────────────────────────────\n\nconst volume = ref(1);\nconst muted = ref(false);\n\nwatch(() => props.video, (el) => {\n if (!el) return;\n const onChange = () => { volume.value = el.volume; muted.value = el.muted; };\n onChange();\n el.addEventListener(\"volumechange\", onChange);\n}, { immediate: true });\n\nfunction toggleMute() {\n if (props.video) props.video.muted = !props.video.muted;\n}\n\nfunction onVolumeInput(e: Event) {\n const el = props.video;\n if (!el) return;\n const v = Number((e.target as HTMLInputElement).value) / 100;\n el.volume = v;\n if (v > 0 && el.muted) el.muted = false;\n}\n\n// ── Speed ─────────────────────────────────────────────────────────────────\n\nconst speed = ref(1);\nconst speedOpen = ref(false);\nconst speedRootEl = ref<HTMLElement | null>(null);\n\nwatch(() => props.video, (el) => {\n if (!el) return;\n const onRate = () => { speed.value = el.playbackRate; };\n onRate();\n el.addEventListener(\"ratechange\", onRate);\n}, { immediate: true });\n\nfunction pickSpeed(rate: number) {\n if (props.video) props.video.playbackRate = rate;\n speed.value = rate;\n speedOpen.value = false;\n}\n\n// ── Captions ──────────────────────────────────────────────────────────────\n\ninterface TextTrackItem { index: number; label: string; }\n\nconst captionTracks = ref<TextTrackItem[]>([]);\nconst activeCaptionIndex = ref(-1);\nconst captionsOpen = ref(false);\nconst captionsRootEl = ref<HTMLElement | null>(null);\n\nfunction snapshotTracks(tl: TextTrackList) {\n const items: TextTrackItem[] = [];\n for (let i = 0; i < tl.length; i++) {\n const t = tl[i];\n if (t.kind === \"subtitles\" || t.kind === \"captions\") {\n items.push({ index: i, label: t.label || t.language || `Track ${i + 1}` });\n }\n }\n captionTracks.value = items;\n let active = -1;\n for (let i = 0; i < tl.length; i++) {\n if (tl[i].mode === \"showing\") { active = i; break; }\n }\n activeCaptionIndex.value = active;\n}\n\nwatch(() => props.video, (el) => {\n if (!el) { captionTracks.value = []; activeCaptionIndex.value = -1; return; }\n const tl = el.textTracks;\n snapshotTracks(tl);\n const onChange = () => snapshotTracks(tl);\n if (typeof tl.addEventListener === \"function\") {\n tl.addEventListener(\"addtrack\", onChange);\n tl.addEventListener(\"removetrack\", onChange);\n tl.addEventListener(\"change\", onChange);\n }\n}, { immediate: true });\n\nfunction pickCaption(index: number) {\n const tl = props.video?.textTracks;\n if (!tl) return;\n for (let i = 0; i < tl.length; i++) tl[i].mode = i === index ? \"showing\" : \"hidden\";\n activeCaptionIndex.value = index;\n captionsOpen.value = false;\n}\n\nfunction pickCaptionOff() {\n const tl = props.video?.textTracks;\n if (!tl) return;\n for (let i = 0; i < tl.length; i++) tl[i].mode = \"hidden\";\n activeCaptionIndex.value = -1;\n captionsOpen.value = false;\n}\n\n// ── PiP ───────────────────────────────────────────────────────────────────\n\nconst isPiP = ref(false);\nconst pipSupported = typeof document !== \"undefined\" && !!document.pictureInPictureEnabled;\n\nwatch(() => props.video, (el) => {\n if (!el) return;\n el.addEventListener(\"enterpictureinpicture\", () => { isPiP.value = true; });\n el.addEventListener(\"leavepictureinpicture\", () => { isPiP.value = false; });\n}, { immediate: true });\n\nfunction togglePiP() {\n if (!props.video) return;\n if (document.pictureInPictureElement) {\n document.exitPictureInPicture().catch(() => { /* ignore */ });\n } else {\n props.video.requestPictureInPicture().catch(() => { /* ignore */ });\n }\n}\n\n// ── Fullscreen ────────────────────────────────────────────────────────────\n\nconst isFs = ref(false);\n\nconst fullscreenSupported = (() => {\n if (typeof document === \"undefined\") return false;\n return Boolean(document.fullscreenEnabled || (document as Document & { webkitFullscreenEnabled?: boolean }).webkitFullscreenEnabled);\n})();\n\nfunction fsElement() {\n return (document.fullscreenElement ?? (document as Document & { webkitFullscreenElement?: Element | null }).webkitFullscreenElement ?? null);\n}\n\nfunction fsRequest(el: HTMLElement) {\n const r = el.requestFullscreen ?? (el as HTMLElement & { webkitRequestFullscreen?(): Promise<void> }).webkitRequestFullscreen;\n return r ? r.call(el) : Promise.reject(new Error(\"unsupported\"));\n}\n\nfunction fsExit() {\n const e = document.exitFullscreen ?? (document as Document & { webkitExitFullscreen?(): Promise<void> }).webkitExitFullscreen;\n return e ? e.call(document) : Promise.reject(new Error(\"unsupported\"));\n}\n\nfunction onFsChange() { isFs.value = fsElement() === props.container; }\n\nonMounted(() => {\n document.addEventListener(\"fullscreenchange\", onFsChange);\n document.addEventListener(\"webkitfullscreenchange\", onFsChange);\n});\nonBeforeUnmount(() => {\n clearHideTimer();\n document.removeEventListener(\"fullscreenchange\", onFsChange);\n document.removeEventListener(\"webkitfullscreenchange\", onFsChange);\n});\n\nfunction toggleFs() {\n if (isIPhone) {\n (props.video as HTMLVideoElement & { webkitEnterFullscreen?(): void })?.webkitEnterFullscreen?.();\n return;\n }\n if (isFs.value) { fsExit().catch(() => { /* ignore */ }); }\n else if (props.container) { fsRequest(props.container).catch(() => { /* ignore */ }); }\n}\n\nconst fsButtonSupported = fullscreenSupported ||\n (isIPhone && props.video !== null &&\n typeof (props.video as HTMLVideoElement & { webkitEnterFullscreen?(): void }).webkitEnterFullscreen === \"function\");\n\n// ── Click-outside for open menus ──────────────────────────────────────────\n\nfunction useClickOutside(openRef: { value: boolean }, rootRef: { value: HTMLElement | null }) {\n function onDocClick(e: MouseEvent) {\n if (rootRef.value && !rootRef.value.contains(e.target as Node)) openRef.value = false;\n }\n function onEsc(e: KeyboardEvent) { if (e.key === \"Escape\") openRef.value = false; }\n watch(openRef, (isOpen) => {\n if (isOpen) {\n document.addEventListener(\"mousedown\", onDocClick);\n document.addEventListener(\"keydown\", onEsc);\n } else {\n document.removeEventListener(\"mousedown\", onDocClick);\n document.removeEventListener(\"keydown\", onEsc);\n }\n });\n onBeforeUnmount(() => {\n document.removeEventListener(\"mousedown\", onDocClick);\n document.removeEventListener(\"keydown\", onEsc);\n });\n}\n\nuseClickOutside(speedOpen, speedRootEl);\nuseClickOutside(captionsOpen, captionsRootEl);\n</script>\n\n<template>\n <div\n role=\"toolbar\"\n aria-label=\"Video controls\"\n :class=\"['gvp-controls', !visible && 'is-hidden']\"\n @mouseenter=\"clearHideTimer\"\n @mouseleave=\"scheduleHide\"\n >\n <div class=\"gvp-controls-row\">\n\n <!-- Play / Pause -->\n <button\n type=\"button\"\n class=\"gvp-ctrl-btn\"\n :aria-label=\"isPlaying ? 'Pause' : 'Play'\"\n :aria-pressed=\"isPlaying\"\n @click=\"onTogglePlay\"\n >\n <IconPause v-if=\"isPlaying\" />\n <IconPlaySolid v-else />\n </button>\n\n <!-- Seek bar -->\n <div class=\"gvp-seek\">\n <div class=\"gvp-seek-track\">\n <div class=\"gvp-seek-buffered\" :style=\"{ width: `${bufferedPct()}%` }\" />\n <div class=\"gvp-seek-progress\" :style=\"{ width: `${progressPct()}%` }\" />\n </div>\n <input\n type=\"range\"\n class=\"gvp-seek-input\"\n :min=\"0\"\n :max=\"100\"\n :step=\"0.1\"\n :value=\"progressPct()\"\n :disabled=\"!seekable()\"\n aria-label=\"Seek\"\n :aria-valuemin=\"0\"\n :aria-valuemax=\"Math.floor(duration)\"\n :aria-valuenow=\"Math.floor(currentTime)\"\n @input=\"onSeekInput\"\n />\n </div>\n\n <!-- Time -->\n <span class=\"gvp-time\" aria-live=\"off\">\n {{ formatTime(currentTime) }} / {{ formatTime(duration) }}\n </span>\n\n <!-- Speed -->\n <div ref=\"speedRootEl\" class=\"gvp-speed\">\n <button\n type=\"button\"\n class=\"gvp-ctrl-btn gvp-speed-btn\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"speedOpen\"\n :aria-label=\"`Playback speed: ${speed === 1 ? '1×' : speed + '×'}`\"\n @click=\"speedOpen = !speedOpen\"\n >\n <IconSpeed />\n <span class=\"gvp-speed-label\">{{ speed === 1 ? \"1×\" : `${speed}×` }}</span>\n </button>\n <!-- NOSONAR: vue:S6819 -->\n <ul v-if=\"speedOpen\" class=\"gvp-speed-menu\" role=\"listbox\" aria-label=\"Playback speed\">\n <li v-for=\"rate in SPEED_OPTIONS\" :key=\"rate\">\n <button\n type=\"button\"\n role=\"option\"\n :aria-selected=\"rate === speed\"\n :class=\"['gvp-speed-menu-item', { 'is-active': rate === speed }]\"\n @click=\"pickSpeed(rate)\"\n >\n {{ rate === 1 ? \"Normal\" : `${rate}×` }}\n </button>\n </li>\n </ul>\n </div>\n\n <!-- Captions -->\n <div v-if=\"captionTracks.length > 0\" ref=\"captionsRootEl\" class=\"gvp-captions\">\n <button\n type=\"button\"\n :class=\"['gvp-ctrl-btn', activeCaptionIndex >= 0 && 'is-active']\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"captionsOpen\"\n aria-label=\"Captions\"\n :aria-pressed=\"activeCaptionIndex >= 0\"\n @click=\"captionsOpen = !captionsOpen\"\n >\n <IconCaptions />\n </button>\n <!-- NOSONAR: vue:S6819 -->\n <ul v-if=\"captionsOpen\" class=\"gvp-captions-menu\" role=\"listbox\" aria-label=\"Captions\">\n <li>\n <button\n type=\"button\"\n role=\"option\"\n :aria-selected=\"activeCaptionIndex === -1\"\n :class=\"['gvp-captions-menu-item', { 'is-active': activeCaptionIndex === -1 }]\"\n @click=\"pickCaptionOff\"\n >Off</button>\n </li>\n <li v-for=\"t in captionTracks\" :key=\"t.index\">\n <button\n type=\"button\"\n role=\"option\"\n :aria-selected=\"t.index === activeCaptionIndex\"\n :class=\"['gvp-captions-menu-item', { 'is-active': t.index === activeCaptionIndex }]\"\n @click=\"pickCaption(t.index)\"\n >{{ t.label }}</button>\n </li>\n </ul>\n </div>\n\n <!-- Volume -->\n <div :class=\"['gvp-volume', !isIOS && 'is-expandable']\">\n <button\n type=\"button\"\n class=\"gvp-ctrl-btn\"\n :aria-label=\"muted ? 'Unmute' : 'Mute'\"\n :aria-pressed=\"muted\"\n @click=\"toggleMute\"\n >\n <IconVolumeMuted v-if=\"muted || volume === 0\" />\n <IconVolumeLow v-else-if=\"volume < 0.5\" />\n <IconVolumeHigh v-else />\n </button>\n <div v-if=\"!isIOS\" class=\"gvp-volume-slider-wrap\">\n <div class=\"gvp-volume-track\">\n <div class=\"gvp-volume-fill\" :style=\"{ width: `${muted ? 0 : Math.round(volume * 100)}%` }\" />\n </div>\n <input\n type=\"range\"\n class=\"gvp-volume-input\"\n :min=\"0\"\n :max=\"100\"\n :step=\"1\"\n :value=\"muted ? 0 : Math.round(volume * 100)\"\n aria-label=\"Volume\"\n :aria-valuemin=\"0\"\n :aria-valuemax=\"100\"\n :aria-valuenow=\"muted ? 0 : Math.round(volume * 100)\"\n @input=\"onVolumeInput\"\n />\n </div>\n </div>\n\n <!-- PiP -->\n <button\n v-if=\"pipSupported\"\n type=\"button\"\n :class=\"['gvp-ctrl-btn', isPiP && 'is-active']\"\n :aria-label=\"isPiP ? 'Exit picture-in-picture' : 'Picture-in-picture'\"\n :aria-pressed=\"isPiP\"\n @click=\"togglePiP\"\n >\n <IconPiP />\n </button>\n\n <!-- Fullscreen -->\n <button\n v-if=\"fsButtonSupported\"\n type=\"button\"\n :class=\"['gvp-ctrl-btn', isFs && 'is-active']\"\n :aria-label=\"isFs ? 'Exit fullscreen' : 'Enter fullscreen'\"\n :aria-pressed=\"isFs\"\n @click=\"toggleFs\"\n >\n <IconFullscreenExit v-if=\"isFs\" />\n <IconFullscreen v-else />\n </button>\n\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M14 2H10C6.72077 2 5.08116 2 3.91891 2.81382C3.48891 3.1149 3.1149 3.48891 2.81382 3.91891C2 5.08116 2 6.72077 2 10C2 13.2792 2 14.9188 2.81382 16.0811C3.1149 16.5111 3.48891 16.8851 3.91891 17.1862C5.08116 18 6.72077 18 10 18H14C17.2792 18 18.9188 18 20.0811 17.1862C20.5111 16.8851 20.8851 16.5111 21.1862 16.0811C22 14.9188 22 13.2792 22 10C22 6.72077 22 5.08116 21.1862 3.91891C20.8851 3.48891 20.5111 3.1149 20.0811 2.81382C18.9188 2 17.2792 2 14 2Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n <path\n d=\"M11 15H13\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M14.5 22L14.1845 21.5811C13.4733 20.6369 13.2969 19.1944 13.7468 18M9.5 22L9.8155 21.5811C10.5267 20.6369 10.7031 19.1944 10.2532 18\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n <path\n d=\"M7 22H17\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconDesktop\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5 9C5 5.70017 5 4.05025 6.02513 3.02513C7.05025 2 8.70017 2 12 2C15.2998 2 16.9497 2 17.9749 3.02513C19 4.05025 19 5.70017 19 9V15C19 18.2998 19 19.9497 17.9749 20.9749C16.9497 22 15.2998 22 12 22C8.70017 22 7.05025 22 6.02513 20.9749C5 19.9497 5 18.2998 5 15V9Z\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n <path\n d=\"M11 19H13\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M9 2L9.089 2.53402C9.28188 3.69129 9.37832 4.26993 9.77519 4.62204C10.1892 4.98934 10.7761 5 12 5C13.2239 5 13.8108 4.98934 14.2248 4.62204C14.6217 4.26993 14.7181 3.69129 14.911 2.53402L15 2\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linejoin=\"round\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconMobile\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"22\"\n height=\"22\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5.3335 11.45V4.54997C5.3335 4.36108 5.40016 4.20275 5.5335 4.07497C5.66683 3.94719 5.82238 3.8833 6.00016 3.8833C6.05572 3.8833 6.11405 3.89163 6.17516 3.9083C6.23627 3.92497 6.29461 3.94997 6.35016 3.9833L11.7835 7.4333C11.8835 7.49997 11.9585 7.5833 12.0085 7.6833C12.0585 7.7833 12.0835 7.88886 12.0835 7.99997C12.0835 8.11108 12.0585 8.21663 12.0085 8.31663C11.9585 8.41663 11.8835 8.49997 11.7835 8.56663L6.35016 12.0166C6.29461 12.05 6.23627 12.075 6.17516 12.0916C6.11405 12.1083 6.05572 12.1166 6.00016 12.1166C5.82238 12.1166 5.66683 12.0527 5.5335 11.925C5.40016 11.7972 5.3335 11.6389 5.3335 11.45Z\"\n fill=\"currentColor\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconPlay\" };\n</script>\n","<script setup lang=\"ts\">\nconst props = defineProps<{ class?: string }>();\n</script>\n\n<template>\n <svg\n :class=\"['gvp-icon', props.class]\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6.94994 5.53594L12.1929 0.292938C12.5834 -0.0975275 13.2165 -0.0975279 13.6069 0.292938C13.9974 0.683403 13.9974 1.31647 13.6069 1.70694L8.36394 6.94994L13.6069 12.1929C13.9974 12.5834 13.9974 13.2165 13.6069 13.6069C13.2165 13.9974 12.5834 13.9974 12.1929 13.6069L6.94994 8.36394L1.70694 13.6069C1.31647 13.9974 0.683403 13.9974 0.292938 13.6069C-0.0975279 13.2165 -0.0975277 12.5834 0.292938 12.1929L5.53594 6.94994L0.292938 1.70694C-0.0975279 1.31647 -0.0975279 0.683403 0.292938 0.292938C0.683403 -0.0975279 1.31647 -0.0975277 1.70694 0.292938L6.94994 5.53594Z\"\n fill=\"currentColor\"\n />\n </svg>\n</template>\n\n<script lang=\"ts\">\nexport default { name: \"IconX\" };\n</script>\n","/**\n * Extract a YouTube video ID from any common URL form, or `null` if the URL\n * isn't a YouTube link.\n *\n * Recognised:\n * - https://www.youtube.com/watch?v=ID\n * - https://youtube.com/watch?v=ID&t=42\n * - https://youtu.be/ID\n * - https://youtu.be/ID?t=42\n * - https://www.youtube.com/embed/ID\n * - https://www.youtube.com/shorts/ID\n * - https://music.youtube.com/watch?v=ID\n * - bare 11-character video IDs\n */\nexport function parseYouTubeId(input: string): string | null {\n if (!input) return null;\n\n if (/^[A-Za-z0-9_-]{11}$/.test(input)) return input;\n\n let url: URL;\n try {\n url = new URL(input);\n } catch {\n return null;\n }\n\n const host = url.hostname.replace(/^www\\./, \"\");\n\n if (host === \"youtu.be\") {\n const id = url.pathname.slice(1).split(\"/\")[0];\n return /^[A-Za-z0-9_-]{11}$/.test(id) ? id : null;\n }\n\n if (\n host === \"youtube.com\" ||\n host === \"m.youtube.com\" ||\n host === \"music.youtube.com\" ||\n host === \"youtube-nocookie.com\"\n ) {\n const v = url.searchParams.get(\"v\");\n if (v && /^[A-Za-z0-9_-]{11}$/.test(v)) return v;\n\n const m = /^\\/(?:embed|shorts|v|live)\\/([A-Za-z0-9_-]{11})/.exec(\n url.pathname\n );\n if (m) return m[1];\n }\n\n return null;\n}\n\n/** Extract a `t`/`start` timestamp (in seconds) from a YouTube URL, if present. */\nexport function parseYouTubeStart(input: string): number | null {\n try {\n const url = new URL(input);\n const t = url.searchParams.get(\"t\") ?? url.searchParams.get(\"start\");\n if (!t) return null;\n if (/^\\d+s?$/.test(t)) return Number.parseInt(t, 10);\n const m = /^(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s)?$/.exec(t);\n if (m) {\n const h = Number.parseInt(m[1] ?? \"0\", 10);\n const min = Number.parseInt(m[2] ?? \"0\", 10);\n const s = Number.parseInt(m[3] ?? \"0\", 10);\n const total = h * 3600 + min * 60 + s;\n return total > 0 ? total : null;\n }\n } catch {\n /* not a URL */\n }\n return null;\n}\n\nexport interface YouTubeEmbedOptions {\n /** Start playback immediately. Forces `mute` on, since browsers block sound-on autoplay. */\n autoPlay?: boolean;\n /** Mute the player. */\n muted?: boolean;\n /** Loop the video. */\n loop?: boolean;\n /** Show YouTube's player controls. Defaults to `true`. */\n controls?: boolean;\n /** Start offset in seconds. */\n startSeconds?: number | null;\n}\n\n/**\n * Build a privacy-enhanced YouTube embed URL from a video ID and player options.\n *\n * Notes on YouTube's quirks:\n * - `autoplay=1` only takes effect if `mute=1` is also set (browser policy).\n * - single-video loop requires `loop=1` **and** `playlist=<id>`.\n */\nexport function youTubeEmbedUrl(\n id: string,\n opts: YouTubeEmbedOptions = {}\n): string {\n const {\n autoPlay = false,\n muted = true,\n loop = false,\n controls = true,\n startSeconds\n } = opts;\n\n const params = new URLSearchParams({\n rel: \"0\",\n modestbranding: \"1\",\n playsinline: \"1\",\n controls: controls ? \"1\" : \"0\"\n });\n\n if (autoPlay) {\n params.set(\"autoplay\", \"1\");\n params.set(\"mute\", \"1\"); // required for autoplay to actually fire\n } else if (muted) {\n params.set(\"mute\", \"1\");\n }\n\n if (loop) {\n params.set(\"loop\", \"1\");\n params.set(\"playlist\", id); // YouTube needs this for single-video loop\n }\n\n if (startSeconds && startSeconds > 0) {\n params.set(\"start\", String(startSeconds));\n }\n\n return `https://www.youtube-nocookie.com/embed/${id}?${params.toString()}`;\n}\n","<script lang=\"ts\" setup>\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from \"vue\";\nimport HLSPlayer from \"./HLSPlayer.vue\";\nimport AudioTrackSwitcher from \"./components/AudioTrackSwitcher.vue\";\nimport SpeedSwitcher from \"./components/SpeedSwitcher.vue\";\nimport CaptionsSwitcher from \"./components/CaptionsSwitcher.vue\";\nimport ControlBar from \"./components/ControlBar.vue\";\nimport IconDesktop from \"./components/IconDesktop.vue\";\nimport IconMobile from \"./components/IconMobile.vue\";\nimport IconPiP from \"./components/IconPiP.vue\";\nimport IconPlay from \"./components/IconPlay.vue\";\nimport IconX from \"./components/IconX.vue\";\nimport type { DeviceMode, VideoPlayerProps } from \"./utils/types\";\nimport type { AudioTrackInfo } from \"./utils/audio-tracks\";\nimport { parseYouTubeId, parseYouTubeStart, youTubeEmbedUrl } from \"./utils/youtube\";\n\nconst props = withDefaults(\n defineProps<VideoPlayerProps & { class?: string; closable?: boolean }>(),\n {\n showDeviceToggle: true,\n defaultDevice: \"desktop\",\n hoverPlay: false,\n muted: true,\n loop: false,\n controls: true,\n autoPlay: false,\n closable: false,\n class: \"\"\n }\n);\n\nconst emit = defineEmits<{\n close: [];\n play: [];\n pause: [];\n}>();\n\nconst hlsPlayerRef = ref<InstanceType<typeof HLSPlayer> | null>(null);\nconst device = ref<DeviceMode>(props.defaultDevice);\nconst isPlaying = ref(false);\nconst showTooltip = ref(false);\nconst playPromise = ref<Promise<void> | null>(null);\nconst audioTracks = ref<AudioTrackInfo[]>([]);\nconst audioTrackIndex = ref(-1);\nconst playbackSpeed = ref(1);\nconst isPiP = ref(false);\nconst isHovered = ref(false);\nconst rootEl = ref<HTMLElement | null>(null);\nconst pipSupported = typeof document !== \"undefined\" && !!document.pictureInPictureEnabled;\n\n// `true` and `\"custom\"` both mean the branded control bar; `\"native\"` means\n// the browser's own controls; `false` means none.\nconst isCustomControls = computed(\n () => props.controls === true || props.controls === \"custom\"\n);\nconst isNativeControls = computed(() => props.controls === \"native\");\n\nconst youTubeId = computed(() => parseYouTubeId(props.src));\nconst isYouTube = computed(() => youTubeId.value !== null);\nconst youTubeSrc = computed(() =>\n youTubeId.value\n ? youTubeEmbedUrl(youTubeId.value, {\n autoPlay: props.autoPlay,\n muted: props.muted,\n loop: props.loop,\n controls: isCustomControls.value ? true : isNativeControls.value,\n startSeconds: parseYouTubeStart(props.src)\n })\n : null\n);\n\nfunction onAudioTracks(tracks: AudioTrackInfo[]) {\n audioTracks.value = tracks;\n audioTrackIndex.value = -1; // reset on new source / level switch\n}\n\nconst showAudioSwitcher = computed(\n () => !isYouTube.value && audioTracks.value.length > 1\n);\nconst activeAudioIndex = computed(() =>\n audioTrackIndex.value >= 0\n ? audioTrackIndex.value\n : (audioTracks.value[0]?.index ?? -1)\n);\n\nconst aspectRatio = computed(() =>\n device.value === \"mobile\"\n ? (props.aspectRatio?.mobile ?? \"9/16\")\n : (props.aspectRatio?.desktop ?? \"16/9\")\n);\n\nconst frameMaxWidth = computed(() =>\n device.value === \"mobile\"\n ? (props.frameMaxWidth?.mobile ?? \"420px\")\n : (props.frameMaxWidth?.desktop ?? \"960px\")\n);\n\nconst videoEl = computed(() => hlsPlayerRef.value?.videoEl ?? null);\n\nasync function safePlay() {\n const el = videoEl.value;\n if (!el) return;\n try {\n if (el.readyState < 2) el.load();\n const p = el.play();\n playPromise.value = p;\n await p;\n isPlaying.value = true;\n } catch {\n isPlaying.value = false;\n } finally {\n playPromise.value = null;\n }\n}\n\nasync function safePause() {\n const el = videoEl.value;\n if (!el) return;\n if (playPromise.value) {\n try {\n await playPromise.value;\n } catch {\n /* play was interrupted; nothing to await */\n }\n }\n el.pause();\n}\n\nasync function hoverStart() {\n if (!props.hoverPlay || isYouTube.value) return;\n await safePlay();\n}\n\nasync function hoverStop() {\n if (!props.hoverPlay || isYouTube.value) return;\n await safePause();\n isPlaying.value = false;\n}\n\nasync function togglePlay() {\n const el = videoEl.value;\n if (!el) return;\n if (el.paused) {\n await safePlay();\n } else {\n await safePause();\n isPlaying.value = false;\n }\n}\n\nfunction onMouseEnter() {\n showTooltip.value = true;\n void hoverStart();\n}\n\nfunction onMouseLeave() {\n showTooltip.value = false;\n void hoverStop();\n}\n\nfunction onSelectSpeed(rate: number) {\n playbackSpeed.value = rate;\n const el = videoEl.value;\n if (el) el.playbackRate = rate;\n}\n\n// Keep playbackSpeed + isPiP in sync from video element events.\nwatch(videoEl, (el) => {\n if (!el) return;\n el.addEventListener(\"ratechange\", () => { playbackSpeed.value = el.playbackRate; });\n el.addEventListener(\"enterpictureinpicture\", () => { isPiP.value = true; });\n el.addEventListener(\"leavepictureinpicture\", () => { isPiP.value = false; });\n});\n\nfunction togglePiP() {\n const el = videoEl.value;\n if (!el) return;\n if (document.pictureInPictureElement) {\n document.exitPictureInPicture().catch(() => { /* ignore */ });\n } else {\n el.requestPictureInPicture().catch(() => { /* ignore */ });\n }\n}\n\n// Keyboard shortcuts — active only while the cursor is over the player or\n// focus is inside it, so we don't steal global shortcuts from the page.\nfunction onKeyDown(e: KeyboardEvent) {\n const el = videoEl.value;\n if (!el) return;\n if (!isHovered.value && !rootEl.value?.contains(document.activeElement)) return;\n const tag = (e.target as HTMLElement).tagName;\n if (tag === \"INPUT\" && e.key !== \" \") return;\n\n switch (e.key) {\n case \" \":\n case \"k\":\n e.preventDefault();\n void togglePlay();\n break;\n case \"ArrowLeft\":\n e.preventDefault();\n el.currentTime = Math.max(0, el.currentTime - 5);\n break;\n case \"ArrowRight\":\n e.preventDefault();\n el.currentTime = Math.min(el.duration || 0, el.currentTime + 5);\n break;\n case \"ArrowUp\":\n e.preventDefault();\n el.volume = Math.min(1, el.volume + 0.1);\n if (el.muted) el.muted = false;\n break;\n case \"ArrowDown\":\n e.preventDefault();\n el.volume = Math.max(0, el.volume - 0.1);\n break;\n case \"m\":\n el.muted = !el.muted;\n break;\n case \"f\": {\n const fsEl = document.fullscreenElement ??\n (document as Document & { webkitFullscreenElement?: Element | null }).webkitFullscreenElement ?? null;\n const req = rootEl.value?.requestFullscreen ??\n (rootEl.value as HTMLElement & { webkitRequestFullscreen?(): Promise<void> })?.webkitRequestFullscreen;\n const exit = document.exitFullscreen ??\n (document as Document & { webkitExitFullscreen?(): Promise<void> }).webkitExitFullscreen;\n if (fsEl === rootEl.value) { exit?.call(document).catch(() => { /* ignore */ }); }\n else if (req && rootEl.value) { req.call(rootEl.value).catch(() => { /* ignore */ }); }\n break;\n }\n case \"p\":\n if (pipSupported) togglePiP();\n break;\n }\n}\n\nonMounted(() => { document.addEventListener(\"keydown\", onKeyDown); });\nonBeforeUnmount(() => { document.removeEventListener(\"keydown\", onKeyDown); });\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n :class=\"['gvp-root', props.class]\"\n :style=\"{ width: frameMaxWidth, aspectRatio }\"\n @mouseenter=\"isHovered = true; onMouseEnter()\"\n @mouseleave=\"isHovered = false; onMouseLeave()\"\n >\n <iframe\n v-if=\"isYouTube\"\n class=\"gvp-video gvp-youtube\"\n :src=\"youTubeSrc ?? undefined\"\n title=\"YouTube video player\"\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\"\n allowfullscreen\n referrerpolicy=\"strict-origin-when-cross-origin\"\n />\n <HLSPlayer\n v-else\n ref=\"hlsPlayerRef\"\n :controls=\"isNativeControls\"\n :hls-config=\"hlsConfig\"\n :is-hls=\"isHls\"\n :loop=\"loop\"\n :muted=\"muted\"\n :auto-play=\"autoPlay\"\n :audio-track-index=\"audioTrackIndex\"\n :plays-inline=\"true\"\n :poster=\"poster\"\n :src=\"src\"\n class=\"gvp-video\"\n preload=\"metadata\"\n @audio-tracks=\"onAudioTracks\"\n @pause=\"\n isPlaying = false;\n emit('pause');\n \"\n @play=\"\n isPlaying = true;\n emit('play');\n \"\n >\n <slot />\n </HLSPlayer>\n\n <div v-if=\"!isYouTube\" class=\"gvp-vignette\" />\n\n <div v-if=\"showDeviceToggle\" class=\"gvp-toggle\">\n <div class=\"gvp-toggle-pill\">\n <button\n :aria-pressed=\"device === 'desktop'\"\n :class=\"['gvp-toggle-btn', { 'is-active': device === 'desktop' }]\"\n aria-label=\"Desktop view\"\n type=\"button\"\n @click=\"device = 'desktop'\"\n >\n <IconDesktop />\n </button>\n\n <div class=\"gvp-toggle-divider\" />\n\n <button\n :aria-pressed=\"device === 'mobile'\"\n :class=\"['gvp-toggle-btn', { 'is-active': device === 'mobile' }]\"\n aria-label=\"Mobile view\"\n type=\"button\"\n @click=\"device = 'mobile'\"\n >\n <IconMobile />\n </button>\n </div>\n </div>\n\n <button\n v-if=\"closable\"\n aria-label=\"Close\"\n class=\"gvp-close\"\n type=\"button\"\n @click=\"emit('close')\"\n >\n <IconX />\n </button>\n\n <!-- Overlay badges — only shown outside custom-controls mode -->\n <AudioTrackSwitcher\n v-if=\"showAudioSwitcher && !isCustomControls\"\n :tracks=\"audioTracks\"\n :active-index=\"activeAudioIndex\"\n @select=\"audioTrackIndex = $event\"\n />\n\n <SpeedSwitcher\n v-if=\"!isYouTube && !isCustomControls\"\n :speed=\"playbackSpeed\"\n @select=\"onSelectSpeed\"\n />\n\n <CaptionsSwitcher v-if=\"!isYouTube && !isCustomControls\" :video=\"videoEl\" />\n\n <button\n v-if=\"!isYouTube && pipSupported && !isCustomControls\"\n type=\"button\"\n :class=\"['gvp-pip-btn', { 'is-active': isPiP }]\"\n :aria-label=\"isPiP ? 'Exit picture-in-picture' : 'Picture-in-picture'\"\n :aria-pressed=\"isPiP\"\n @click=\"togglePiP\"\n >\n <IconPiP />\n </button>\n\n <!-- Click-to-toggle layer in custom-controls mode -->\n <button\n v-if=\"!isYouTube && isCustomControls\"\n type=\"button\"\n class=\"gvp-click-layer\"\n :aria-label=\"isPlaying ? 'Pause' : 'Play'\"\n @click=\"togglePlay\"\n />\n\n <!-- Centered play button (non-custom, non-playing) -->\n <div v-if=\"!isYouTube && !isCustomControls && !isPlaying\" class=\"gvp-play-wrap\">\n <button\n aria-label=\"Play\"\n class=\"gvp-play\"\n type=\"button\"\n @click=\"togglePlay\"\n @mouseenter=\"showTooltip = true\"\n @mouseleave=\"showTooltip = false\"\n >\n <IconPlay />\n <span v-if=\"tooltipText && showTooltip\" class=\"gvp-tooltip\" role=\"tooltip\">\n {{ tooltipText }}\n </span>\n </button>\n </div>\n\n <!-- Custom control bar -->\n <ControlBar\n v-if=\"!isYouTube && isCustomControls\"\n :video=\"videoEl\"\n :is-playing=\"isPlaying\"\n :container=\"rootEl\"\n :on-toggle-play=\"togglePlay\"\n />\n\n <div v-if=\"!isYouTube && !isCustomControls\" class=\"gvp-bottom-fade\" />\n </div>\n</template>\n"],"names":["audioTrackLabel","name","lang","index","trimmed","resolved","props","__props","emit","__emit","videoEl","ref","hlsInstance","detachNative","detachLoadedMetadata","canUseHlsJs","Hls","shouldUseHls","src","cleanup","el","initPlayer","tryAutoPlay","hls","reportHlsTracks","list","t","i","_evt","data","at","reportNativeTracks","_a","_b","_c","applyAudioTrack","onMounted","watch","onBeforeUnmount","__expose","_createElementBlock","_normalizeClass","_renderSlot","_ctx","__default__","_createElementVNode","open","rootEl","active","computed","onDocClick","e","onEsc","isOpen","pick","_cache","$event","_createVNode","IconAudio","_hoisted_2","_toDisplayString","IconChevron","_openBlock","_hoisted_3","_Fragment","_renderList","_hoisted_4","SPEED_OPTIONS","rate","IconSpeed","tracks","activeIndex","snapshot","tl","items","cleanupTracks","onChange","pickOff","IconCaptions","formatTime","seconds","total","h","m","ss","mm","AUTO_HIDE_MS","isIOS","ua","isIPhone","visible","hideTimer","clearHideTimer","scheduleHide","showAndScheduleHide","playing","handler","currentTime","duration","buffered","onTime","onDuration","onProgress","ranges","end","seekable","progressPct","bufferedPct","onSeekInput","volume","muted","toggleMute","onVolumeInput","v","speed","speedOpen","speedRootEl","onRate","pickSpeed","captionTracks","activeCaptionIndex","captionsOpen","captionsRootEl","snapshotTracks","pickCaption","pickCaptionOff","isPiP","pipSupported","togglePiP","isFs","fullscreenSupported","fsElement","fsRequest","r","fsExit","onFsChange","toggleFs","fsButtonSupported","useClickOutside","openRef","rootRef","_hoisted_1","args","_createBlock","IconPause","IconPlaySolid","_hoisted_6","_unref","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_12","_hoisted_13","_hoisted_14","IconVolumeMuted","IconVolumeLow","IconVolumeHigh","_hoisted_16","_hoisted_17","IconPiP","IconFullscreenExit","IconFullscreen","parseYouTubeId","input","url","host","id","parseYouTubeStart","min","s","youTubeEmbedUrl","opts","autoPlay","loop","controls","startSeconds","params","hlsPlayerRef","device","isPlaying","showTooltip","playPromise","audioTracks","audioTrackIndex","playbackSpeed","isHovered","isCustomControls","isNativeControls","youTubeId","isYouTube","youTubeSrc","onAudioTracks","showAudioSwitcher","activeAudioIndex","aspectRatio","frameMaxWidth","safePlay","p","safePause","hoverStart","hoverStop","togglePlay","onMouseEnter","onMouseLeave","onSelectSpeed","onKeyDown","fsEl","req","exit","_normalizeStyle","HLSPlayer","IconDesktop","IconMobile","IconX","AudioTrackSwitcher","SpeedSwitcher","CaptionsSwitcher","IconPlay","ControlBar","_hoisted_11"],"mappings":";;AAcO,SAASA,GACZC,GACAC,GACAC,GACM;AACN,QAAMC,IAAUH,KAAA,gBAAAA,EAAM;AACtB,MAAIG,EAAS,QAAOA;AACpB,MAAIF,GAAM;AACN,QAAI;AAEA,YAAMG,IADK,IAAI,KAAK,aAAa,QAAW,EAAE,MAAM,YAAY,EAC5C,GAAGH,CAAI;AAC3B,UAAIG,KAAYA,MAAaH,EAAM,QAAOG;AAAA,IAC9C,QAAQ;AAAA,IAER;AACA,WAAOH;AAAA,EACX;AACA,SAAO,SAASC,IAAQ,CAAC;AAC7B;;;;;;;;;;;;;;;;;;;AC1BA,UAAMG,IAAQC,GA2BRC,IAAOC,GAMPC,IAAUC,EAA6B,IAAI,GAC3CC,IAAcD,EAAgB,IAAI;AACxC,QAAIE,GACAC;AAEJ,UAAMC,IAAc,WAAW,WAAW,UAAaC,GAAI,YAAA,GACrDC,IAAe,CAACC,MACpB,EAAQZ,EAAM,SAAWS,KAAeG,EAAI,SAAS,OAAO;AAE9D,aAASC,IAAU;AACjB,MAAAL,KAAA,QAAAA,KACAA,IAAuB,QACvBD,KAAA,QAAAA,KACAA,IAAe,QACXD,EAAY,UACdA,EAAY,MAAM,QAAA,GAClBA,EAAY,QAAQ;AAEtB,YAAMQ,IAAKV,EAAQ;AACnB,UAAKU,GAGL;AAAA,aAFAA,EAAG,MAAA,GACHA,EAAG,gBAAgB,KAAK,GACjBA,EAAG,aAAY,CAAAA,EAAG,WAAW,OAAA;AACpC,QAAAA,EAAG,KAAA,GACHZ,EAAK,gBAAgB,EAAE;AAAA;AAAA,IACzB;AAEA,aAASa,EAAWH,GAAa;;AAC/B,YAAME,IAAKV,EAAQ;AACnB,UAAI,CAACU,KAAM,CAACF,EAAK;AAEjB,MAAAC,EAAA;AAKA,YAAMG,IAAc,MAAM;AACxB,QAAKhB,EAAM,YACXc,EAAG,OAAO,MAAM,MAAM;AAAA,QAEtB,CAAC;AAAA,MACH;AAEA,UAAIH,EAAaC,CAAG,GAAG;AACrB,cAAMK,IAAM,IAAIP,GAAIV,EAAM,SAAS;AACnC,QAAAM,EAAY,QAAQW;AAEpB,cAAMC,IAAkB,MAAM;AAC5B,gBAAMC,IAAyBF,EAAI,YAAY,IAAI,CAACG,GAAGC,OAAO;AAAA,YAC5D,OAAOA;AAAA,YACP,OAAO3B,GAAgB0B,EAAE,MAAMA,EAAE,MAAMC,CAAC;AAAA,YACxC,MAAMD,EAAE,QAAQ;AAAA,UAAA,EAChB;AACF,UAAAlB,EAAK,gBAAgBiB,CAAI;AAAA,QAC3B;AAEA,QAAAF,EAAI,GAAGP,GAAI,OAAO,iBAAiBM,CAAW,GAC9CC,EAAI,GAAGP,GAAI,OAAO,sBAAsBQ,CAAe,GACvDD,EAAI,GAAGP,GAAI,OAAO,sBAAsBQ,CAAe,GACvDD,EAAI,GAAGP,GAAI,OAAO,OAAO,CAACY,GAAMC,MAAS;AACvC,UAAIA,EAAK,UACPN,EAAI,QAAA,GACJX,EAAY,QAAQ;AAAA,QAExB,CAAC,GAEDW,EAAI,YAAYH,CAAE,GAClBG,EAAI,WAAWL,CAAG;AAAA,MACpB,OAAO;AACL,QAAAE,EAAG,MAAMF,GACTE,EAAG,KAAA,GAGHA,EAAG,iBAAiB,kBAAkBE,GAAa,EAAE,MAAM,IAAM,GACjER,IAAuB,MAAM;AAC3B,UAAAM,EAAG,oBAAoB,kBAAkBE,CAAW;AAAA,QACtD;AAKA,cAAMQ,IAAKV,EAAG;AACd,YAAIU,GAAI;AACN,gBAAMC,IAAqB,MAAM;AAC/B,kBAAMN,IAAyB,CAAA;AAC/B,qBAASE,IAAI,GAAGA,IAAIG,EAAG,QAAQH,KAAK;AAClC,oBAAMD,IAAII,EAAGH,CAAC;AACd,cAAAF,EAAK,KAAK;AAAA,gBACR,OAAOE;AAAA,gBACP,OAAO3B,GAAgB0B,EAAE,OAAOA,EAAE,UAAUC,CAAC;AAAA,gBAC7C,MAAMD,EAAE,YAAY;AAAA,cAAA,CACrB;AAAA,YACH;AACA,YAAAlB,EAAK,gBAAgBiB,CAAI;AAAA,UAC3B;AACA,WAAAO,IAAAF,EAAG,qBAAH,QAAAE,EAAA,KAAAF,GAAsB,YAAYC,KAClCE,IAAAH,EAAG,qBAAH,QAAAG,EAAA,KAAAH,GAAsB,eAAeC,KACrCG,IAAAJ,EAAG,qBAAH,QAAAI,EAAA,KAAAJ,GAAsB,UAAUC,IAC5BD,EAAG,SAAS,KAAGC,EAAA,GACnBlB,IAAe,MAAM;;AACnB,aAAAmB,IAAAF,EAAG,wBAAH,QAAAE,EAAA,KAAAF,GAAyB,YAAYC,KACrCE,IAAAH,EAAG,wBAAH,QAAAG,EAAA,KAAAH,GAAyB,eAAeC,KACxCG,IAAAJ,EAAG,wBAAH,QAAAI,EAAA,KAAAJ,GAAyB,UAAUC;AAAA,UACrC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,aAASI,EAAgBhC,GAAe;;AACtC,UAAIA,KAAS,QAAQA,IAAQ,EAAG;AAChC,YAAMoB,IAAMX,EAAY;AACxB,UAAIW,GAAK;AACP,QAAIA,EAAI,eAAepB,MAAOoB,EAAI,aAAapB;AAC/C;AAAA,MACF;AACA,YAAM2B,KAAKE,IAAAtB,EAAQ,UAAR,gBAAAsB,EAAe;AAC1B,UAAIF;AACF,iBAASH,IAAI,GAAGA,IAAIG,EAAG,QAAQH;AAC7B,UAAAG,EAAGH,CAAC,EAAE,UAAUA,MAAMxB;AAAA,IAG5B;AAEA,WAAAiC,GAAU,MAAM;AACd,MAAI9B,EAAM,OAAKe,EAAWf,EAAM,GAAG;AAAA,IACrC,CAAC,GAED+B;AAAA,MACE,MAAM/B,EAAM;AAAA,MACZ,CAACY,MAAQ;AACP,QAAIA,OAAgBA,CAAG;AAAA,MACzB;AAAA,IAAA,GAGFmB;AAAA,MACE,MAAM/B,EAAM;AAAA,MACZ,CAACH,MAAUgC,EAAgBhC,CAAK;AAAA,IAAA,GAGlCmC,EAAgBnB,CAAO,GAEvBoB,EAAa,EAAE,SAAA7B,GAAS,mBAItB8B,EAcQ,SAAA;AAAA,eAbF;AAAA,MAAJ,KAAI9B;AAAA,MACH,OAAOH,EAAA;AAAA,MACP,MAAMA,EAAA;AAAA,MACN,UAAUA,EAAA;AAAA,MACV,UAAUA,EAAA;AAAA,MACV,aAAaA,EAAA;AAAA,MACb,SAASA,EAAA;AAAA,MACT,QAAQA,EAAA;AAAA,MACR,OAAKkC,EAAEnC,EAAM,KAAK;AAAA,MAClB,+BAAME,EAAI,MAAA;AAAA,MACV,gCAAOA,EAAI,OAAA;AAAA,IAAA;MAEZkC,GAAQC,EAAA,QAAA,SAAA;AAAA,IAAA;;ICvKZC,KAAe,EAAE,MAAM,YAAA;;;;;;AA7BvB,UAAMtC,IAAQC;2BAIZiC,EAqBM,OAAA;AAAA,MApBH,OAAKC,EAAA,CAAA,YAAenC,EAAM,KAAK,CAAA;AAAA,MAChC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,IAAA;MAEZuC,EAKE,QAAA;AAAA,QAJA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,mBAAgB;AAAA,MAAA;MAElBA,EAKE,QAAA;AAAA,QAJA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,kBAAe;AAAA,MAAA;;;ICCrBD,KAAe,EAAE,MAAM,cAAA;;;;;;AAxBvB,UAAMtC,IAAQC;2BAIZiC,EAgBM,OAAA;AAAA,MAfH,OAAKC,EAAA,CAAA,YAAenC,EAAM,KAAK,CAAA;AAAA,MAChC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,IAAA;MAEZuC,EAME,QAAA;AAAA,QALA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,kBAAe;AAAA,QACf,mBAAgB;AAAA,MAAA;;;;;;;;;;;;;;;;ACbtB,UAAMvC,IAAQC,GAKRC,IAAOC,GAIPqC,IAAOnC,EAAI,EAAK,GAChBoC,IAASpC,EAAwB,IAAI,GAErCqC,IAASC;AAAA,MACb,MAAM3C,EAAM,OAAO,KAAK,CAACoB,MAAMA,EAAE,UAAUpB,EAAM,WAAW,KAAKA,EAAM,OAAO,CAAC;AAAA,IAAA;AAGjF,aAAS4C,EAAWC,GAAe;AACjC,MAAIJ,EAAO,SAAS,CAACA,EAAO,MAAM,SAASI,EAAE,MAAc,MACzDL,EAAK,QAAQ;AAAA,IAEjB;AAEA,aAASM,EAAMD,GAAkB;AAC/B,MAAIA,EAAE,QAAQ,aAAUL,EAAK,QAAQ;AAAA,IACvC;AAEA,IAAAT,EAAMS,GAAM,CAACO,MAAW;AACtB,MAAIA,KACF,SAAS,iBAAiB,aAAaH,CAAU,GACjD,SAAS,iBAAiB,WAAWE,CAAK,MAE1C,SAAS,oBAAoB,aAAaF,CAAU,GACpD,SAAS,oBAAoB,WAAWE,CAAK;AAAA,IAEjD,CAAC,GAEDd,EAAgB,MAAM;AACpB,eAAS,oBAAoB,aAAaY,CAAU,GACpD,SAAS,oBAAoB,WAAWE,CAAK;AAAA,IAC/C,CAAC;AAED,aAASE,EAAKnD,GAAe;AAC3B,MAAAK,EAAK,UAAUL,CAAK,GACpB2C,EAAK,QAAQ;AAAA,IACf;;;kBAIEN,EAmCM,OAAA;AAAA,iBAnCG;AAAA,QAAJ,KAAIO;AAAA,QAAS,OAAM;AAAA,MAAA;QACtBF,EAWS,UAAA;AAAA,UAVP,MAAK;AAAA,UACL,OAAM;AAAA,UACN,iBAAc;AAAA,UACb,iBAAeC,EAAA;AAAA,UAChB,cAAW;AAAA,UACV,SAAKS,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAEV,EAAA,QAAI,CAAIA,EAAA;AAAA,QAAA;UAEhBW,EAAaC,EAAA;AAAA,UACbb,EAAwD,QAAxDc,IAAwDC,GAAvB5B,IAAAgB,EAAA,UAAA,gBAAAhB,EAAQ,KAAK,GAAA,CAAA;AAAA,UAC9CyB,EAAeI,EAAA;AAAA,QAAA;QAOTf,EAAA,SADRgB,EAAA,GAAAtB,EAiBK,MAjBLuB,IAiBK;AAAA,kBAXHvB,EAUKwB,IAAA,MAAAC,GAVW1D,EAAA,QAAM,CAAXmB,YAAXc,EAUK,MAAA;AAAA,YAVoB,KAAKd,EAAE;AAAA,UAAA;YAC9BmB,EAQS,UAAA;AAAA,cAPP,MAAK;AAAA,cACL,MAAK;AAAA,cACJ,iBAAenB,EAAE,UAAUnB,EAAA;AAAA,cAC3B,OAAKkC,EAAA,CAAA,uBAAA,EAAA,aAAyCf,EAAE,UAAUnB,EAAA,YAAA,CAAW,CAAA;AAAA,cACrE,SAAK,CAAAiD,MAAEF,EAAK5B,EAAE,KAAK;AAAA,YAAA,GAEjBkC,EAAAlC,EAAE,KAAK,GAAA,IAAAwC,EAAA;AAAA,UAAA;;;;;ICvDpBtB,KAAe,EAAE,MAAM,YAAA;;;;;;AA7BvB,UAAMtC,IAAQC;2BAIZiC,EAqBM,OAAA;AAAA,MApBH,OAAKC,EAAA,CAAA,YAAenC,EAAM,KAAK,CAAA;AAAA,MAChC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,IAAA;MAEZuC,EAIE,QAAA;AAAA,QAHA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,MAAA;MAEfA,EAME,QAAA;AAAA,QALA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,kBAAe;AAAA,QACf,mBAAgB;AAAA,MAAA;;;;;;;;;;;;;;;ACnBtB,UAAMsB,IAAgB,CAAC,KAAK,MAAM,GAAG,MAAM,KAAK,CAAC,GAG3C3D,IAAOC,GAEPqC,IAAOnC,EAAI,EAAK,GAChBoC,IAASpC,EAAwB,IAAI;AAE3C,aAASuC,EAAWC,GAAe;AACjC,MAAIJ,EAAO,SAAS,CAACA,EAAO,MAAM,SAASI,EAAE,MAAc,MACzDL,EAAK,QAAQ;AAAA,IAEjB;AAEA,aAASM,EAAMD,GAAkB;AAC/B,MAAIA,EAAE,QAAQ,aAAUL,EAAK,QAAQ;AAAA,IACvC;AAEA,IAAAT,EAAMS,GAAM,CAACO,MAAW;AACtB,MAAIA,KACF,SAAS,iBAAiB,aAAaH,CAAU,GACjD,SAAS,iBAAiB,WAAWE,CAAK,MAE1C,SAAS,oBAAoB,aAAaF,CAAU,GACpD,SAAS,oBAAoB,WAAWE,CAAK;AAAA,IAEjD,CAAC,GAEDd,EAAgB,MAAM;AACpB,eAAS,oBAAoB,aAAaY,CAAU,GACpD,SAAS,oBAAoB,WAAWE,CAAK;AAAA,IAC/C,CAAC;AAED,aAASE,EAAKc,GAAc;AAC1B,MAAA5D,EAAK,UAAU4D,CAAI,GACnBtB,EAAK,QAAQ;AAAA,IACf;2BAIEN,EAmCM,OAAA;AAAA,eAnCG;AAAA,MAAJ,KAAIO;AAAA,MAAS,OAAM;AAAA,IAAA;MACtBF,EAWS,UAAA;AAAA,QAVP,MAAK;AAAA,QACL,OAAM;AAAA,QACN,iBAAc;AAAA,QACb,iBAAeC,EAAA;AAAA,QAChB,cAAW;AAAA,QACV,SAAKS,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAEV,EAAA,QAAI,CAAIA,EAAA;AAAA,MAAA;QAEhBW,EAAaY,EAAA;AAAA,QACbxB,EAA2E,QAA3Ec,IAA2EC,EAA1CrD,EAAA,wBAAwBA,EAAA,KAAK,GAAA,GAAA,CAAA;AAAA,QAC9DkD,EAAeI,EAAA;AAAA,MAAA;MAOTf,EAAA,SADRgB,EAAA,GAAAtB,EAiBK,MAjBLuB,IAiBK;AAAA,cAXHvB,EAUKwB,IAAA,MAAAC,GAVcE,GAAa,CAArBC,MAAXvB,EAUK,MAAA,EAV8B,KAAKuB,KAAI;AAAA,UAC1CvB,EAQS,UAAA;AAAA,YAPP,MAAK;AAAA,YACL,MAAK;AAAA,YACJ,iBAAeuB,MAAS7D,EAAA;AAAA,YACxB,OAAKkC,EAAA,CAAA,uBAAA,EAAA,aAAyC2B,MAAS7D,EAAA,MAAA,CAAK,CAAA;AAAA,YAC5D,SAAK,CAAAiD,MAAEF,EAAKc,CAAI;AAAA,UAAA,GAEdR,EAAAQ,wBAA2BA,CAAI,GAAA,GAAA,IAAAF,EAAA;AAAA,QAAA;;;;ICxD5CtB,KAAe,EAAE,MAAM,eAAA;;;;;;AAnBvB,UAAMtC,IAAQC;2BAIZiC,EAWM,OAAA;AAAA,MAVH,OAAKC,EAAA,CAAA,YAAenC,EAAM,KAAK,CAAA;AAAA,MAChC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,IAAA;MAEZuC,EAA2F,QAAA;AAAA,QAArF,GAAE;AAAA,QAAI,GAAE;AAAA,QAAI,OAAM;AAAA,QAAK,QAAO;AAAA,QAAK,IAAG;AAAA,QAAI,QAAO;AAAA,QAAe,gBAAa;AAAA,MAAA;MACnFA,EAAuH,QAAA;AAAA,QAAjH,GAAE;AAAA,QAA6C,QAAO;AAAA,QAAe,gBAAa;AAAA,QAAM,kBAAe;AAAA,MAAA;;;;;;;;;;;;;;ACNjH,UAAMvC,IAAQC,GAIR+D,IAAS3D,EAAqB,EAAE,GAChC4D,IAAc5D,EAAI,EAAE,GACpBmC,IAAOnC,EAAI,EAAK,GAChBoC,IAASpC,EAAwB,IAAI;AAG3C,aAAS6D,EAASC,GAAmB;AACnC,YAAMC,IAAyB,CAAA;AAC/B,eAAS/C,IAAI,GAAGA,IAAI8C,EAAG,QAAQ9C,KAAK;AAClC,cAAMD,IAAI+C,EAAG9C,CAAC;AACd,SAAID,EAAE,SAAS,eAAeA,EAAE,SAAS,eACvCgD,EAAM,KAAK,EAAE,OAAO/C,GAAG,OAAOD,EAAE,SAASA,EAAE,YAAY,SAASC,IAAI,CAAC,IAAI;AAAA,MAE7E;AACA,MAAA2C,EAAO,QAAQI;AACf,UAAI1B,IAAS;AACb,eAASrB,IAAI,GAAGA,IAAI8C,EAAG,QAAQ9C;AAC7B,YAAI8C,EAAG9C,CAAC,EAAE,SAAS,WAAW;AAAE,UAAAqB,IAASrB;AAAG;AAAA,QAAO;AAErD,MAAA4C,EAAY,QAAQvB;AAAA,IACtB;AAEA,QAAI2B,IAAqC;AAEzC,IAAAtC,EAAM,MAAM/B,EAAM,OAAO,CAACc,MAAO;AAG/B,UAFAuD,KAAA,QAAAA,KACAA,IAAgB,MACZ,CAACvD,GAAI;AAAE,QAAAkD,EAAO,QAAQ,CAAA,GAAIC,EAAY,QAAQ;AAAI;AAAA,MAAQ;AAC9D,YAAME,IAAKrD,EAAG;AACd,MAAAoD,EAASC,CAAE;AACX,YAAMG,IAAW,MAAMJ,EAASC,CAAE;AAClC,MAAI,OAAOA,EAAG,oBAAqB,eACjCA,EAAG,iBAAiB,YAAYG,CAAQ,GACxCH,EAAG,iBAAiB,eAAeG,CAAQ,GAC3CH,EAAG,iBAAiB,UAAUG,CAAQ,GACtCD,IAAgB,MAAM;AACpB,QAAAF,EAAG,oBAAoB,YAAYG,CAAQ,GAC3CH,EAAG,oBAAoB,eAAeG,CAAQ,GAC9CH,EAAG,oBAAoB,UAAUG,CAAQ;AAAA,MAC3C;AAAA,IAEJ,GAAG,EAAE,WAAW,IAAM,GAEtBtC,EAAgB,MAAM;AACpB,MAAAqC,KAAA,QAAAA,KACA,SAAS,oBAAoB,aAAazB,CAAU,GACpD,SAAS,oBAAoB,WAAWE,CAAK;AAAA,IAC/C,CAAC;AAED,aAASF,EAAWC,GAAe;AACjC,MAAIJ,EAAO,SAAS,CAACA,EAAO,MAAM,SAASI,EAAE,MAAc,MAAGL,EAAK,QAAQ;AAAA,IAC7E;AAEA,aAASM,EAAMD,GAAkB;AAC/B,MAAIA,EAAE,QAAQ,aAAUL,EAAK,QAAQ;AAAA,IACvC;AAEA,IAAAT,EAAMS,GAAM,CAACO,MAAW;AACtB,MAAIA,KACF,SAAS,iBAAiB,aAAaH,CAAU,GACjD,SAAS,iBAAiB,WAAWE,CAAK,MAE1C,SAAS,oBAAoB,aAAaF,CAAU,GACpD,SAAS,oBAAoB,WAAWE,CAAK;AAAA,IAEjD,CAAC;AAED,aAASyB,IAAU;AACjB,UAAI,CAACvE,EAAM,MAAO;AAClB,YAAMmE,IAAKnE,EAAM,MAAM;AACvB,eAASqB,IAAI,GAAGA,IAAI8C,EAAG,QAAQ9C,IAAK,CAAA8C,EAAG9C,CAAC,EAAE,OAAO;AACjD,MAAA4C,EAAY,QAAQ,IACpBzB,EAAK,QAAQ;AAAA,IACf;AAEA,aAASQ,EAAKnD,GAAe;AAC3B,UAAI,CAACG,EAAM,MAAO;AAClB,YAAMmE,IAAKnE,EAAM,MAAM;AACvB,eAASqB,IAAI,GAAGA,IAAI8C,EAAG,QAAQ9C;AAC7B,QAAA8C,EAAG9C,CAAC,EAAE,OAAOA,MAAMxB,IAAQ,YAAY;AAEzC,MAAAoE,EAAY,QAAQpE,GACpB2C,EAAK,QAAQ;AAAA,IACf;qBAIawB,EAAA,MAAO,SAAM,UAAxB9B,EA6CM,OAAA;AAAA;eA7C4B;AAAA,MAAJ,KAAIO;AAAA,MAAS,OAAM;AAAA,IAAA;MAC/CF,EAUS,UAAA;AAAA,QATP,MAAK;AAAA,QACJ,6CAA2C0B,EAAA,SAAW,EAAA,CAAA,CAAA;AAAA,QACvD,iBAAc;AAAA,QACb,iBAAezB,EAAA;AAAA,QACf,gBAAcyB,EAAA,SAAW;AAAA,QAC1B,cAAW;AAAA,QACV,SAAKhB,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAEV,EAAA,QAAI,CAAIA,EAAA;AAAA,MAAA;QAEhBW,EAAgBqB,EAAA;AAAA,MAAA;MAOVhC,EAAA,SADRgB,EAAA,GAAAtB,EA4BK,MA5BLmB,IA4BK;AAAA,QAtBHd,EAUK,MAAA,MAAA;AAAA,UATHA,EAQS,UAAA;AAAA,YAPP,MAAK;AAAA,YACL,MAAK;AAAA,YACJ,iBAAe0B,EAAA,UAAW;AAAA,YAC1B,mDAAiDA,EAAA,UAAW,GAAA,CAAA,CAAA;AAAA,YAC5D,SAAOM;AAAA,UAAA,GACT,SAED,IAAAd,EAAA;AAAA,QAAA;gBAEFvB,EAUKwB,IAAA,MAAAC,GAVWK,EAAA,OAAM,CAAX5C,YAAXc,EAUK,MAAA;AAAA,UAVoB,KAAKd,EAAE;AAAA,QAAA;UAC9BmB,EAQS,UAAA;AAAA,YAPP,MAAK;AAAA,YACL,MAAK;AAAA,YACJ,iBAAenB,EAAE,UAAU6C,EAAA;AAAA,YAC3B,OAAK9B,EAAA,CAAA,0BAAA,EAAA,aAA4Cf,EAAE,UAAU6C,EAAA,MAAA,CAAW,CAAA;AAAA,YACxE,SAAK,CAAAf,MAAEF,EAAK5B,EAAE,KAAK;AAAA,UAAA,GAEjBkC,EAAAlC,EAAE,KAAK,GAAA,IAAAwC,EAAA;AAAA,QAAA;;;;ICzHpBtB,KAAe,EAAE,MAAM,YAAA;;;;;;AAnBvB,UAAMtC,IAAQC;2BAIZiC,EAWM,OAAA;AAAA,MAVH,OAAKC,EAAA,CAAA,YAAenC,EAAM,KAAK,CAAA;AAAA,MAChC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,IAAA;MAEZuC,EAAqE,QAAA;AAAA,QAA/D,GAAE;AAAA,QAAI,GAAE;AAAA,QAAI,OAAM;AAAA,QAAI,QAAO;AAAA,QAAK,IAAG;AAAA,QAAI,MAAK;AAAA,MAAA;MACpDA,EAAsE,QAAA;AAAA,QAAhE,GAAE;AAAA,QAAK,GAAE;AAAA,QAAI,OAAM;AAAA,QAAI,QAAO;AAAA,QAAK,IAAG;AAAA,QAAI,MAAK;AAAA,MAAA;;;ICOzDD,KAAe,EAAE,MAAM,gBAAA;;;;;;AArBvB,UAAMtC,IAAQC;2BAIZiC,EAaM,OAAA;AAAA,MAZH,OAAKC,EAAA,CAAA,YAAenC,EAAM,KAAK,CAAA;AAAA,MAChC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,IAAA;MAEZuC,EAGE,QAAA;AAAA,QAFA,GAAE;AAAA,QACF,MAAK;AAAA,MAAA;;;ICcXD,KAAe,EAAE,MAAM,iBAAA;;;;;;AA7BvB,UAAMtC,IAAQC;2BAIZiC,EAqBM,OAAA;AAAA,MApBH,OAAKC,EAAA,CAAA,YAAenC,EAAM,KAAK,CAAA;AAAA,MAChC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,IAAA;MAEZuC,EAKE,QAAA;AAAA,QAJA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,mBAAgB;AAAA,MAAA;MAElBA,EAKE,QAAA;AAAA,QAJA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,kBAAe;AAAA,MAAA;;;ICMrBD,KAAe,EAAE,MAAM,gBAAA;;;;;;AA7BvB,UAAMtC,IAAQC;2BAIZiC,EAqBM,OAAA;AAAA,MApBH,OAAKC,EAAA,CAAA,YAAenC,EAAM,KAAK,CAAA;AAAA,MAChC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,IAAA;MAEZuC,EAKE,QAAA;AAAA,QAJA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,mBAAgB;AAAA,MAAA;MAElBA,EAKE,QAAA;AAAA,QAJA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,kBAAe;AAAA,MAAA;;;ICMrBD,KAAe,EAAE,MAAM,kBAAA;;;;;;AA7BvB,UAAMtC,IAAQC;2BAIZiC,EAqBM,OAAA;AAAA,MApBH,OAAKC,EAAA,CAAA,YAAenC,EAAM,KAAK,CAAA;AAAA,MAChC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,IAAA;MAEZuC,EAKE,QAAA;AAAA,QAJA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,mBAAgB;AAAA,MAAA;MAElBA,EAKE,QAAA;AAAA,QAJA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,kBAAe;AAAA,MAAA;;;ICJrBD,KAAe,EAAE,MAAM,UAAA;;;;;;AAnBvB,UAAMtC,IAAQC;2BAIZiC,EAWM,OAAA;AAAA,MAVH,OAAKC,EAAA,CAAA,YAAenC,EAAM,KAAK,CAAA;AAAA,MAChC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,IAAA;MAEZuC,EAA2F,QAAA;AAAA,QAArF,GAAE;AAAA,QAAI,GAAE;AAAA,QAAI,OAAM;AAAA,QAAK,QAAO;AAAA,QAAK,IAAG;AAAA,QAAI,QAAO;AAAA,QAAe,gBAAa;AAAA,MAAA;MACnFA,EAAsE,QAAA;AAAA,QAAhE,GAAE;AAAA,QAAK,GAAE;AAAA,QAAK,OAAM;AAAA,QAAI,QAAO;AAAA,QAAI,IAAG;AAAA,QAAI,MAAK;AAAA,MAAA;;;ICUzDD,KAAe,EAAE,MAAM,iBAAA;;;;;;AAxBvB,UAAMtC,IAAQC;2BAIZiC,EAgBM,OAAA;AAAA,MAfH,OAAKC,EAAA,CAAA,YAAenC,EAAM,KAAK,CAAA;AAAA,MAChC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,IAAA;MAEZuC,EAME,QAAA;AAAA,QALA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,kBAAe;AAAA,QACf,mBAAgB;AAAA,MAAA;;;ICMtBD,KAAe,EAAE,MAAM,qBAAA;;;;;;AAxBvB,UAAMtC,IAAQC;2BAIZiC,EAgBM,OAAA;AAAA,MAfH,OAAKC,EAAA,CAAA,YAAenC,EAAM,KAAK,CAAA;AAAA,MAChC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,IAAA;MAEZuC,EAME,QAAA;AAAA,QALA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,kBAAe;AAAA,QACf,mBAAgB;AAAA,MAAA;;;;ACnBf,SAASkC,GAAWC,GAAyB;AAClD,MAAI,CAAC,OAAO,SAASA,CAAO,KAAKA,IAAU,EAAG,QAAO;AACrD,QAAMC,IAAQ,KAAK,MAAMD,CAAO,GAC1BE,IAAI,KAAK,MAAMD,IAAQ,IAAI,GAC3BE,IAAI,KAAK,MAAOF,IAAQ,OAAQ,EAAE,GAElCG,KADIH,IAAQ,IACL,SAAA,EAAW,SAAS,GAAG,GAAG;AACvC,MAAIC,IAAI,GAAG;AACT,UAAMG,IAAKF,EAAE,SAAA,EAAW,SAAS,GAAG,GAAG;AACvC,WAAO,GAAGD,CAAC,IAAIG,CAAE,IAAID,CAAE;AAAA,EACzB;AACA,SAAO,GAAGD,CAAC,IAAIC,CAAE;AACnB;;;;;;;;;;;;;;;;;kJCiBME,KAAe;;;;;;;;;AAXrB,UAAMC,KAAS,MAAM;AACnB,UAAI,OAAO,YAAc,IAAa,QAAO;AAC7C,YAAMC,IAAK,UAAU;AACrB,aAAO,mBAAmB,KAAKA,CAAE,KAAMA,EAAG,SAAS,KAAK,KAAK,UAAU,iBAAiB;AAAA,IAC1F,GAAA,GAEMC,IACA,OAAO,YAAc,MAAoB,KACtC,cAAc,KAAK,UAAU,SAAS,GAIzCtB,IAAgB,CAAC,KAAK,MAAM,GAAG,MAAM,KAAK,CAAC,GAE3C7D,IAAQC,GASRmF,IAAU/E,EAAI,EAAI;AACxB,QAAIgF,IAAkD;AAEtD,aAASC,IAAiB;AACxB,MAAID,MAAc,SAAQ,aAAaA,CAAS,GAAGA,IAAY;AAAA,IACjE;AAEA,aAASE,IAAe;AAEtB,MADAD,EAAA,GACKtF,EAAM,cACXqF,IAAY,WAAW,MAAM;AAAE,QAAAD,EAAQ,QAAQ;AAAA,MAAO,GAAGJ,EAAY;AAAA,IACvE;AAEA,aAASQ,IAAsB;AAC7B,MAAAJ,EAAQ,QAAQ,IAChBG,EAAA;AAAA,IACF;AAEA,IAAAxD,EAAM,MAAM/B,EAAM,WAAW,CAACyF,MAAY;AACxC,MAAKA,IACAF,EAAA,KADWD,EAAA,GAAkBF,EAAQ,QAAQ;AAAA,IAEpD,GAAG,EAAE,WAAW,IAAM,GAEtBrD,EAAM,MAAM/B,EAAM,WAAW,CAACc,MAAO;AACnC,UAAI,CAACA,EAAI;AACT,YAAM4E,IAAU,MAAMF,EAAA;AACtB,MAAA1E,EAAG,iBAAiB,aAAa4E,CAAO,GACxC5E,EAAG,iBAAiB,cAAc4E,CAAO,GACzC5E,EAAG,iBAAiB,WAAW4E,CAAO;AAAA,IACxC,GAAG,EAAE,WAAW,IAAM;AAItB,UAAMC,IAActF,EAAI,CAAC,GACnBuF,IAAWvF,EAAI,CAAC,GAChBwF,IAAWxF,EAAI,CAAC;AAEtB,IAAA0B,EAAM,MAAM/B,EAAM,OAAO,CAACc,MAAO;AAC/B,UAAI,CAACA,EAAI;AACT,YAAMgF,IAAS,MAAM;AAAE,QAAAH,EAAY,QAAQ7E,EAAG;AAAA,MAAa,GACrDiF,IAAa,MAAM;AAAE,QAAAH,EAAS,QAAQ,OAAO,SAAS9E,EAAG,QAAQ,IAAIA,EAAG,WAAW;AAAA,MAAG,GACtFkF,IAAa,MAAM;AACvB,cAAMC,IAASnF,EAAG;AAClB,YAAI,CAACmF,KAAUA,EAAO,WAAW,GAAG;AAAE,UAAAJ,EAAS,QAAQ;AAAG;AAAA,QAAQ;AAClE,YAAIK,KAAMD,EAAO,IAAIA,EAAO,SAAS,CAAC;AACtC,iBAAS5E,KAAI,GAAGA,KAAI4E,EAAO,QAAQ5E;AACjC,cAAI4E,EAAO,MAAM5E,EAAC,KAAKP,EAAG,eAAeA,EAAG,eAAemF,EAAO,IAAI5E,EAAC,GAAG;AACxE,YAAA6E,KAAMD,EAAO,IAAI5E,EAAC;AAAG;AAAA,UACvB;AAEF,QAAAwE,EAAS,QAAQK;AAAA,MACnB;AACA,MAAAJ,EAAA,GAAUC,EAAA,GAAcC,EAAA,GACxBlF,EAAG,iBAAiB,cAAcgF,CAAM,GACxChF,EAAG,iBAAiB,kBAAkBiF,CAAU,GAChDjF,EAAG,iBAAiB,kBAAkBiF,CAAU,GAChDjF,EAAG,iBAAiB,YAAYkF,CAAU,GAC1ClF,EAAG,iBAAiB,cAAckF,CAAU;AAAA,IAC9C,GAAG,EAAE,WAAW,IAAM;AAEtB,UAAMG,IAAW,MAAMP,EAAS,QAAQ,GAClCQ,IAAc,MAAMD,MAAcR,EAAY,QAAQC,EAAS,QAAS,MAAM,GAC9ES,IAAc,MAAMF,MAAcN,EAAS,QAAQD,EAAS,QAAS,MAAM;AAEjF,aAASU,EAAYzD,GAAU;AAC7B,YAAM/B,IAAKd,EAAM;AACjB,UAAI,CAACc,KAAM,CAACqF,IAAY;AACxB,YAAM/E,IAAK,OAAQyB,EAAE,OAA4B,KAAK,IAAI,MAAO+C,EAAS;AAC1E,MAAA9E,EAAG,cAAcM,GACjBuE,EAAY,QAAQvE;AAAA,IACtB;AAIA,UAAMmF,IAASlG,EAAI,CAAC,GACdmG,IAAQnG,EAAI,EAAK;AAEvB,IAAA0B,EAAM,MAAM/B,EAAM,OAAO,CAACc,MAAO;AAC/B,UAAI,CAACA,EAAI;AACT,YAAMwD,IAAW,MAAM;AAAE,QAAAiC,EAAO,QAAQzF,EAAG,QAAQ0F,EAAM,QAAQ1F,EAAG;AAAA,MAAO;AAC3E,MAAAwD,EAAA,GACAxD,EAAG,iBAAiB,gBAAgBwD,CAAQ;AAAA,IAC9C,GAAG,EAAE,WAAW,IAAM;AAEtB,aAASmC,IAAa;AACpB,MAAIzG,EAAM,UAAOA,EAAM,MAAM,QAAQ,CAACA,EAAM,MAAM;AAAA,IACpD;AAEA,aAAS0G,EAAc7D,GAAU;AAC/B,YAAM/B,IAAKd,EAAM;AACjB,UAAI,CAACc,EAAI;AACT,YAAM6F,IAAI,OAAQ9D,EAAE,OAA4B,KAAK,IAAI;AACzD,MAAA/B,EAAG,SAAS6F,GACRA,IAAI,KAAK7F,EAAG,YAAU,QAAQ;AAAA,IACpC;AAIA,UAAM8F,IAAQvG,EAAI,CAAC,GACbwG,IAAYxG,EAAI,EAAK,GACrByG,IAAczG,EAAwB,IAAI;AAEhD,IAAA0B,EAAM,MAAM/B,EAAM,OAAO,CAACc,MAAO;AAC/B,UAAI,CAACA,EAAI;AACT,YAAMiG,IAAS,MAAM;AAAE,QAAAH,EAAM,QAAQ9F,EAAG;AAAA,MAAc;AACtD,MAAAiG,EAAA,GACAjG,EAAG,iBAAiB,cAAciG,CAAM;AAAA,IAC1C,GAAG,EAAE,WAAW,IAAM;AAEtB,aAASC,EAAUlD,GAAc;AAC/B,MAAI9D,EAAM,UAAOA,EAAM,MAAM,eAAe8D,IAC5C8C,EAAM,QAAQ9C,GACd+C,EAAU,QAAQ;AAAA,IACpB;AAMA,UAAMI,IAAgB5G,EAAqB,EAAE,GACvC6G,IAAqB7G,EAAI,EAAE,GAC3B8G,IAAe9G,EAAI,EAAK,GACxB+G,KAAiB/G,EAAwB,IAAI;AAEnD,aAASgH,GAAelD,GAAmB;AACzC,YAAMC,IAAyB,CAAA;AAC/B,eAAS/C,IAAI,GAAGA,IAAI8C,EAAG,QAAQ9C,KAAK;AAClC,cAAMD,IAAI+C,EAAG9C,CAAC;AACd,SAAID,EAAE,SAAS,eAAeA,EAAE,SAAS,eACvCgD,EAAM,KAAK,EAAE,OAAO/C,GAAG,OAAOD,EAAE,SAASA,EAAE,YAAY,SAASC,IAAI,CAAC,IAAI;AAAA,MAE7E;AACA,MAAA4F,EAAc,QAAQ7C;AACtB,UAAI1B,IAAS;AACb,eAASrB,IAAI,GAAGA,IAAI8C,EAAG,QAAQ9C;AAC7B,YAAI8C,EAAG9C,CAAC,EAAE,SAAS,WAAW;AAAE,UAAAqB,IAASrB;AAAG;AAAA,QAAO;AAErD,MAAA6F,EAAmB,QAAQxE;AAAA,IAC7B;AAEA,IAAAX,EAAM,MAAM/B,EAAM,OAAO,CAACc,MAAO;AAC/B,UAAI,CAACA,GAAI;AAAE,QAAAmG,EAAc,QAAQ,CAAA,GAAIC,EAAmB,QAAQ;AAAI;AAAA,MAAQ;AAC5E,YAAM/C,IAAKrD,EAAG;AACd,MAAAuG,GAAelD,CAAE;AACjB,YAAMG,IAAW,MAAM+C,GAAelD,CAAE;AACxC,MAAI,OAAOA,EAAG,oBAAqB,eACjCA,EAAG,iBAAiB,YAAYG,CAAQ,GACxCH,EAAG,iBAAiB,eAAeG,CAAQ,GAC3CH,EAAG,iBAAiB,UAAUG,CAAQ;AAAA,IAE1C,GAAG,EAAE,WAAW,IAAM;AAEtB,aAASgD,GAAYzH,GAAe;;AAClC,YAAMsE,KAAKzC,IAAA1B,EAAM,UAAN,gBAAA0B,EAAa;AACxB,UAAKyC,GACL;AAAA,iBAAS9C,IAAI,GAAGA,IAAI8C,EAAG,QAAQ9C,IAAK,CAAA8C,EAAG9C,CAAC,EAAE,OAAOA,MAAMxB,IAAQ,YAAY;AAC3E,QAAAqH,EAAmB,QAAQrH,GAC3BsH,EAAa,QAAQ;AAAA;AAAA,IACvB;AAEA,aAASI,IAAiB;;AACxB,YAAMpD,KAAKzC,IAAA1B,EAAM,UAAN,gBAAA0B,EAAa;AACxB,UAAKyC,GACL;AAAA,iBAAS9C,IAAI,GAAGA,IAAI8C,EAAG,QAAQ9C,IAAK,CAAA8C,EAAG9C,CAAC,EAAE,OAAO;AACjD,QAAA6F,EAAmB,QAAQ,IAC3BC,EAAa,QAAQ;AAAA;AAAA,IACvB;AAIA,UAAMK,IAAQnH,EAAI,EAAK,GACjBoH,KAAe,OAAO,WAAa,OAAe,CAAC,CAAC,SAAS;AAEnE,IAAA1F,EAAM,MAAM/B,EAAM,OAAO,CAACc,MAAO;AAC/B,MAAKA,MACLA,EAAG,iBAAiB,yBAAyB,MAAM;AAAE,QAAA0G,EAAM,QAAQ;AAAA,MAAM,CAAC,GAC1E1G,EAAG,iBAAiB,yBAAyB,MAAM;AAAE,QAAA0G,EAAM,QAAQ;AAAA,MAAO,CAAC;AAAA,IAC7E,GAAG,EAAE,WAAW,IAAM;AAEtB,aAASE,KAAY;AACnB,MAAK1H,EAAM,UACP,SAAS,0BACX,SAAS,uBAAuB,MAAM,MAAM;AAAA,MAAe,CAAC,IAE5DA,EAAM,MAAM,wBAAA,EAA0B,MAAM,MAAM;AAAA,MAAe,CAAC;AAAA,IAEtE;AAIA,UAAM2H,IAAOtH,EAAI,EAAK,GAEhBuH,KACA,OAAO,WAAa,MAAoB,KACrC,GAAQ,SAAS,qBAAsB,SAA8D;AAG9G,aAASC,IAAY;AACnB,aAAQ,SAAS,qBAAsB,SAAqE,2BAA2B;AAAA,IACzI;AAEA,aAASC,EAAUhH,GAAiB;AAClC,YAAMiH,IAAIjH,EAAG,qBAAsBA,EAAmE;AACtG,aAAOiH,IAAIA,EAAE,KAAKjH,CAAE,IAAI,QAAQ,OAAO,IAAI,MAAM,aAAa,CAAC;AAAA,IACjE;AAEA,aAASkH,IAAS;AAChB,YAAMnF,IAAI,SAAS,kBAAmB,SAAmE;AACzG,aAAOA,IAAIA,EAAE,KAAK,QAAQ,IAAI,QAAQ,OAAO,IAAI,MAAM,aAAa,CAAC;AAAA,IACvE;AAEA,aAASoF,IAAa;AAAE,MAAAN,EAAK,QAAQE,EAAA,MAAgB7H,EAAM;AAAA,IAAW;AAEtE,IAAA8B,GAAU,MAAM;AACd,eAAS,iBAAiB,oBAAoBmG,CAAU,GACxD,SAAS,iBAAiB,0BAA0BA,CAAU;AAAA,IAChE,CAAC,GACDjG,EAAgB,MAAM;AACpB,MAAAsD,EAAA,GACA,SAAS,oBAAoB,oBAAoB2C,CAAU,GAC3D,SAAS,oBAAoB,0BAA0BA,CAAU;AAAA,IACnE,CAAC;AAED,aAASC,KAAW;;AAClB,UAAI/C,GAAU;AACX,SAAAxD,KAAAD,IAAA1B,EAAM,UAAN,gBAAA0B,EAAuE,0BAAvE,QAAAC,EAAA,KAAAD;AACD;AAAA,MACF;AACA,MAAIiG,EAAK,QAASK,EAAA,EAAS,MAAM,MAAM;AAAA,MAAe,CAAC,IAC9ChI,EAAM,aAAa8H,EAAU9H,EAAM,SAAS,EAAE,MAAM,MAAM;AAAA,MAAe,CAAC;AAAA,IACrF;AAEA,UAAMmI,KAAoBP,MACvBzC,KAAYnF,EAAM,UAAU,QAC3B,OAAQA,EAAM,MAAgE,yBAA0B;AAI5G,aAASoI,GAAgBC,GAA6BC,GAAwC;AAC5F,eAAS1F,EAAWC,GAAe;AACjC,QAAIyF,EAAQ,SAAS,CAACA,EAAQ,MAAM,SAASzF,EAAE,MAAc,MAAGwF,EAAQ,QAAQ;AAAA,MAClF;AACA,eAASvF,EAAMD,GAAkB;AAAE,QAAIA,EAAE,QAAQ,aAAUwF,EAAQ,QAAQ;AAAA,MAAO;AAClF,MAAAtG,EAAMsG,GAAS,CAACtF,MAAW;AACzB,QAAIA,KACF,SAAS,iBAAiB,aAAaH,CAAU,GACjD,SAAS,iBAAiB,WAAWE,CAAK,MAE1C,SAAS,oBAAoB,aAAaF,CAAU,GACpD,SAAS,oBAAoB,WAAWE,CAAK;AAAA,MAEjD,CAAC,GACDd,EAAgB,MAAM;AACpB,iBAAS,oBAAoB,aAAaY,CAAU,GACpD,SAAS,oBAAoB,WAAWE,CAAK;AAAA,MAC/C,CAAC;AAAA,IACH;AAEA,WAAAsF,GAAgBvB,GAAWC,CAAW,GACtCsB,GAAgBjB,GAAcC,EAAc,mBAI1ClF,EA4KM,OAAA;AAAA,MA3KJ,MAAK;AAAA,MACL,cAAW;AAAA,MACV,2BAAyBkD,EAAA,SAAO,WAAA,CAAA;AAAA,MAChC,cAAYE;AAAA,MACZ,cAAYC;AAAA,IAAA;MAEbhD,EAoKM,OApKNgG,IAoKM;AAAA,QAjKJhG,EASS,UAAA;AAAA,UARP,MAAK;AAAA,UACL,OAAM;AAAA,UACL,cAAYtC,EAAA,YAAS,UAAA;AAAA,UACrB,gBAAcA,EAAA;AAAA,UACd,SAAKgD,EAAA,CAAA,MAAAA,EAAA,CAAA;AAAA,oBAAEhD,EAAA,gBAAAA,EAAA,aAAA,GAAAuI,CAAA;AAAA,QAAA;UAESvI,EAAA,kBAAjBwI,EAA8BC,IAAA,EAAA,KAAA,EAAA,CAAA,WAC9BD,EAAwBE,IAAA,EAAA,KAAA,GAAA;AAAA,QAAA;QAI1BpG,EAmBM,OAnBNkB,IAmBM;AAAA,UAlBJlB,EAGM,OAHNqB,IAGM;AAAA,YAFJrB,EAAyE,OAAA;AAAA,cAApE,OAAM;AAAA,cAAqB,sBAAmB8D,EAAA,CAAW,KAAA;AAAA,YAAA;YAC9D9D,EAAyE,OAAA;AAAA,cAApE,OAAM;AAAA,cAAqB,sBAAmB6D,EAAA,CAAW,KAAA;AAAA,YAAA;;UAEhE7D,EAaE,SAAA;AAAA,YAZA,MAAK;AAAA,YACL,OAAM;AAAA,YACL,KAAK;AAAA,YACL,KAAK;AAAA,YACL,MAAM;AAAA,YACN,OAAO6D,EAAA;AAAA,YACP,WAAWD,EAAA;AAAA,YACZ,cAAW;AAAA,YACV,iBAAe;AAAA,YACf,iBAAe,KAAK,MAAMP,EAAA,KAAQ;AAAA,YAClC,iBAAe,KAAK,MAAMD,EAAA,KAAW;AAAA,YACrC,SAAOW;AAAA,UAAA;;QAKZ/D,EAEO,QAFPqG,IAEOtF,EADFuF,EAAApE,EAAA,EAAWkB,EAAA,KAAW,CAAA,IAAI,QAAGrC,EAAGuF,EAAApE,EAAA,EAAWmB,EAAA,KAAQ,CAAA,GAAA,CAAA;AAAA,QAIxDrD,EA0BM,OAAA;AAAA,mBA1BG;AAAA,UAAJ,KAAIuE;AAAA,UAAc,OAAM;AAAA,QAAA;UAC3BvE,EAUS,UAAA;AAAA,YATP,MAAK;AAAA,YACL,OAAM;AAAA,YACN,iBAAc;AAAA,YACb,iBAAesE,EAAA;AAAA,YACf,cAAU,mBAAqBD,EAAA,UAAK,IAAA,OAAgBA,EAAA,QAAK,GAAA;AAAA,YACzD,SAAK3D,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAE2D,EAAA,QAAS,CAAIA,EAAA;AAAA,UAAA;YAErB1D,EAAaY,EAAA;AAAA,YACbxB,EAA2E,QAA3EuG,IAA2ExF,EAA1CsD,EAAA,wBAAwBA,EAAA,KAAK,GAAA,GAAA,CAAA;AAAA,UAAA;UAGtDC,EAAA,SAAVrD,EAAA,GAAAtB,EAYK,MAZL6G,IAYK;AAAA,kBAXH7G,EAUKwB,IAAA,MAAAC,GAVcE,GAAa,CAArBC,MAAXvB,EAUK,MAAA,EAV8B,KAAKuB,KAAI;AAAA,cAC1CvB,EAQS,UAAA;AAAA,gBAPP,MAAK;AAAA,gBACL,MAAK;AAAA,gBACJ,iBAAeuB,MAAS8C,EAAA;AAAA,gBACxB,OAAKzE,EAAA,CAAA,uBAAA,EAAA,aAAyC2B,MAAS8C,EAAA,MAAA,CAAK,CAAA;AAAA,gBAC5D,SAAK,CAAA1D,MAAE8D,EAAUlD,CAAI;AAAA,cAAA,GAEnBR,EAAAQ,wBAA2BA,CAAI,GAAA,GAAA,IAAAkF,EAAA;AAAA,YAAA;;;QAO/B/B,EAAA,MAAc,SAAM,UAA/B/E,EAiCM,OAAA;AAAA;mBAjCmC;AAAA,UAAJ,KAAIkF;AAAA,UAAiB,OAAM;AAAA,QAAA;UAC9D7E,EAUS,UAAA;AAAA,YATP,MAAK;AAAA,YACJ,0BAAwB2E,EAAA,SAAkB,KAAA,WAAA,CAAA;AAAA,YAC3C,iBAAc;AAAA,YACb,iBAAeC,EAAA;AAAA,YAChB,cAAW;AAAA,YACV,gBAAcD,EAAA,SAAkB;AAAA,YAChC,SAAKjE,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAEiE,EAAA,QAAY,CAAIA,EAAA;AAAA,UAAA;YAExBhE,EAAgBqB,EAAA;AAAA,UAAA;UAGR2C,EAAA,SAAV3D,EAAA,GAAAtB,EAmBK,MAnBL+G,IAmBK;AAAA,YAlBH1G,EAQK,MAAA,MAAA;AAAA,cAPHA,EAMa,UAAA;AAAA,gBALX,MAAK;AAAA,gBACL,MAAK;AAAA,gBACJ,iBAAe2E,EAAA,UAAkB;AAAA,gBACjC,mDAAiDA,EAAA,UAAkB,GAAA,CAAA,CAAA;AAAA,gBACnE,SAAOK;AAAA,cAAA,GACT,OAAG,IAAA2B,EAAA;AAAA,YAAA;oBAENhH,EAQKwB,IAAA,MAAAC,GARWsD,EAAA,OAAa,CAAlB7F,YAAXc,EAQK,MAAA;AAAA,cAR2B,KAAKd,EAAE;AAAA,YAAA;cACrCmB,EAMuB,UAAA;AAAA,gBALrB,MAAK;AAAA,gBACL,MAAK;AAAA,gBACJ,iBAAenB,EAAE,UAAU8F,EAAA;AAAA,gBAC3B,OAAK/E,EAAA,CAAA,0BAAA,EAAA,aAA4Cf,EAAE,UAAU8F,EAAA,MAAA,CAAkB,CAAA;AAAA,gBAC/E,SAAK,CAAAhE,MAAEoE,GAAYlG,EAAE,KAAK;AAAA,cAAA,GACzBkC,EAAAlC,EAAE,KAAK,GAAA,IAAA+H,EAAA;AAAA,YAAA;;;QAMjB5G,EA8BM,OAAA;AAAA,UA9BA,yBAAuBsG,EAAA5D,CAAA,KAAK,eAAA,CAAA;AAAA,QAAA;UAChC1C,EAUS,UAAA;AAAA,YATP,MAAK;AAAA,YACL,OAAM;AAAA,YACL,cAAYiE,EAAA,QAAK,WAAA;AAAA,YACjB,gBAAcA,EAAA;AAAA,YACd,SAAOC;AAAA,UAAA;YAEeD,EAAA,SAASD,EAAA,UAAM,UAAtCkC,EAAgDW,IAAA,EAAA,KAAA,EAAA,CAAA,KACtB7C,EAAA,QAAM,YAAhCkC,EAA0CY,IAAA,EAAA,KAAA,EAAA,CAAA,WAC1CZ,EAAyBa,IAAA,EAAA,KAAA,GAAA;AAAA,UAAA;UAEfT,EAAA5D,CAAA,iBAAZzB,KAAAtB,EAiBM,OAjBNqH,IAiBM;AAAA,YAhBJhH,EAEM,OAFNiH,IAEM;AAAA,cADJjH,EAA8F,OAAA;AAAA,gBAAzF,OAAM;AAAA,gBAAmB,sBAAmBiE,EAAA,QAAK,IAAO,KAAK,MAAMD,EAAA,QAAM,GAAA,CAAA,KAAA;AAAA,cAAA;;YAEhFhE,EAYE,SAAA;AAAA,cAXA,MAAK;AAAA,cACL,OAAM;AAAA,cACL,KAAK;AAAA,cACL,KAAK;AAAA,cACL,MAAM;AAAA,cACN,OAAOiE,EAAA,QAAK,IAAO,KAAK,MAAMD,EAAA,QAAM,GAAA;AAAA,cACrC,cAAW;AAAA,cACV,iBAAe;AAAA,cACf,iBAAe;AAAA,cACf,iBAAeC,EAAA,QAAK,IAAO,KAAK,MAAMD,EAAA,QAAM,GAAA;AAAA,cAC5C,SAAOG;AAAA,YAAA;;;QAONmC,EAAApB,EAAA,UADRvF,EASS,UAAA;AAAA;UAPP,MAAK;AAAA,UACJ,0BAAwBsF,EAAA,SAAK,WAAA,CAAA;AAAA,UAC7B,cAAYA,EAAA,QAAK,4BAAA;AAAA,UACjB,gBAAcA,EAAA;AAAA,UACd,SAAOE;AAAA,QAAA;UAERvE,EAAWsG,EAAA;AAAA,QAAA;QAKLZ,EAAAV,EAAA,UADRjG,EAUS,UAAA;AAAA;UARP,MAAK;AAAA,UACJ,0BAAwByF,EAAA,SAAI,WAAA,CAAA;AAAA,UAC5B,cAAYA,EAAA,QAAI,oBAAA;AAAA,UAChB,gBAAcA,EAAA;AAAA,UACd,SAAOO;AAAA,QAAA;UAEkBP,EAAA,cAA1Bc,EAAkCiB,IAAA,EAAA,KAAA,EAAA,CAAA,WAClCjB,EAAyBkB,IAAA,EAAA,KAAA,GAAA;AAAA,QAAA;;;;IC7ajCrH,KAAe,EAAE,MAAM,cAAA;;;;;;AA1CvB,UAAMtC,IAAQC;2BAIZiC,EAkCM,OAAA;AAAA,MAjCH,OAAKC,EAAA,CAAA,YAAenC,EAAM,KAAK,CAAA;AAAA,MAChC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,IAAA;MAEZuC,EAKE,QAAA;AAAA,QAJA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,kBAAe;AAAA,MAAA;MAEjBA,EAME,QAAA;AAAA,QALA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,kBAAe;AAAA,QACf,mBAAgB;AAAA,MAAA;MAElBA,EAKE,QAAA;AAAA,QAJA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,kBAAe;AAAA,MAAA;MAEjBA,EAKE,QAAA;AAAA,QAJA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,kBAAe;AAAA,MAAA;;;ICArBD,KAAe,EAAE,MAAM,aAAA;;;;;;AApCvB,UAAMtC,IAAQC;2BAIZiC,EA4BM,OAAA;AAAA,MA3BH,OAAKC,EAAA,CAAA,YAAenC,EAAM,KAAK,CAAA;AAAA,MAChC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,IAAA;MAEZuC,EAKE,QAAA;AAAA,QAJA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,kBAAe;AAAA,MAAA;MAEjBA,EAME,QAAA;AAAA,QALA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,kBAAe;AAAA,QACf,mBAAgB;AAAA,MAAA;MAElBA,EAKE,QAAA;AAAA,QAJA,GAAE;AAAA,QACF,QAAO;AAAA,QACP,gBAAa;AAAA,QACb,mBAAgB;AAAA,MAAA;;;ICTtBD,KAAe,EAAE,MAAM,WAAA;;;;;;AArBvB,UAAMtC,IAAQC;2BAIZiC,EAaM,OAAA;AAAA,MAZH,OAAKC,EAAA,CAAA,YAAenC,EAAM,KAAK,CAAA;AAAA,MAChC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,IAAA;MAEZuC,EAGE,QAAA;AAAA,QAFA,GAAE;AAAA,QACF,MAAK;AAAA,MAAA;;;ICMXD,KAAe,EAAE,MAAM,QAAA;;;;;;AArBvB,UAAMtC,IAAQC;2BAIZiC,EAaM,OAAA;AAAA,MAZH,OAAKC,EAAA,CAAA,YAAenC,EAAM,KAAK,CAAA;AAAA,MAChC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,IAAA;MAEZuC,EAGE,QAAA;AAAA,QAFA,GAAE;AAAA,QACF,MAAK;AAAA,MAAA;;;;ACFJ,SAASqH,GAAeC,GAA8B;AAC3D,MAAI,CAACA,EAAO,QAAO;AAEnB,MAAI,sBAAsB,KAAKA,CAAK,EAAG,QAAOA;AAE9C,MAAIC;AACJ,MAAI;AACF,IAAAA,IAAM,IAAI,IAAID,CAAK;AAAA,EACrB,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,QAAME,IAAOD,EAAI,SAAS,QAAQ,UAAU,EAAE;AAE9C,MAAIC,MAAS,YAAY;AACvB,UAAMC,IAAKF,EAAI,SAAS,MAAM,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;AAC7C,WAAO,sBAAsB,KAAKE,CAAE,IAAIA,IAAK;AAAA,EAC/C;AAEA,MACED,MAAS,iBACTA,MAAS,mBACTA,MAAS,uBACTA,MAAS,wBACT;AACA,UAAMpD,IAAImD,EAAI,aAAa,IAAI,GAAG;AAClC,QAAInD,KAAK,sBAAsB,KAAKA,CAAC,EAAG,QAAOA;AAE/C,UAAM9B,IAAI,kDAAkD;AAAA,MAC1DiF,EAAI;AAAA,IAAA;AAEN,QAAIjF,EAAG,QAAOA,EAAE,CAAC;AAAA,EACnB;AAEA,SAAO;AACT;AAGO,SAASoF,GAAkBJ,GAA8B;AAC9D,MAAI;AACF,UAAMC,IAAM,IAAI,IAAID,CAAK,GACnBzI,IAAI0I,EAAI,aAAa,IAAI,GAAG,KAAKA,EAAI,aAAa,IAAI,OAAO;AACnE,QAAI,CAAC1I,EAAG,QAAO;AACf,QAAI,UAAU,KAAKA,CAAC,UAAU,OAAO,SAASA,GAAG,EAAE;AACnD,UAAMyD,IAAI,sCAAsC,KAAKzD,CAAC;AACtD,QAAIyD,GAAG;AACL,YAAMD,IAAI,OAAO,SAASC,EAAE,CAAC,KAAK,KAAK,EAAE,GACnCqF,IAAM,OAAO,SAASrF,EAAE,CAAC,KAAK,KAAK,EAAE,GACrCsF,IAAI,OAAO,SAAStF,EAAE,CAAC,KAAK,KAAK,EAAE,GACnCF,IAAQC,IAAI,OAAOsF,IAAM,KAAKC;AACpC,aAAOxF,IAAQ,IAAIA,IAAQ;AAAA,IAC7B;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAsBO,SAASyF,GACdJ,GACAK,IAA4B,IACpB;AACR,QAAM;AAAA,IACJ,UAAAC,IAAW;AAAA,IACX,OAAA9D,IAAQ;AAAA,IACR,MAAA+D,IAAO;AAAA,IACP,UAAAC,IAAW;AAAA,IACX,cAAAC;AAAA,EAAA,IACEJ,GAEEK,IAAS,IAAI,gBAAgB;AAAA,IACjC,KAAK;AAAA,IACL,gBAAgB;AAAA,IAChB,aAAa;AAAA,IACb,UAAUF,IAAW,MAAM;AAAA,EAAA,CAC5B;AAED,SAAIF,KACFI,EAAO,IAAI,YAAY,GAAG,GAC1BA,EAAO,IAAI,QAAQ,GAAG,KACblE,KACTkE,EAAO,IAAI,QAAQ,GAAG,GAGpBH,MACFG,EAAO,IAAI,QAAQ,GAAG,GACtBA,EAAO,IAAI,YAAYV,CAAE,IAGvBS,KAAgBA,IAAe,KACjCC,EAAO,IAAI,SAAS,OAAOD,CAAY,CAAC,GAGnC,0CAA0CT,CAAE,IAAIU,EAAO,UAAU;AAC1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChHA,UAAM1K,IAAQC,GAeRC,IAAOC,GAMPwK,IAAetK,EAA2C,IAAI,GAC9DuK,IAASvK,EAAgBL,EAAM,aAAa,GAC5C6K,IAAYxK,EAAI,EAAK,GACrByK,IAAczK,EAAI,EAAK,GACvB0K,IAAc1K,EAA0B,IAAI,GAC5C2K,IAAc3K,EAAsB,EAAE,GACtC4K,IAAkB5K,EAAI,EAAE,GACxB6K,IAAgB7K,EAAI,CAAC,GACrBmH,IAAQnH,EAAI,EAAK,GACjB8K,IAAY9K,EAAI,EAAK,GACrBoC,IAASpC,EAAwB,IAAI,GACrCoH,IAAe,OAAO,WAAa,OAAe,CAAC,CAAC,SAAS,yBAI7D2D,IAAmBzI;AAAA,MACvB,MAAM3C,EAAM,aAAa,MAAQA,EAAM,aAAa;AAAA,IAAA,GAEhDqL,IAAmB1I,EAAS,MAAM3C,EAAM,aAAa,QAAQ,GAE7DsL,IAAY3I,EAAS,MAAMiH,GAAe5J,EAAM,GAAG,CAAC,GACpDuL,IAAY5I,EAAS,MAAM2I,EAAU,UAAU,IAAI,GACnDE,IAAa7I;AAAA,MAAS,MAC1B2I,EAAU,QACNlB,GAAgBkB,EAAU,OAAO;AAAA,QAC/B,UAAUtL,EAAM;AAAA,QAChB,OAAOA,EAAM;AAAA,QACb,MAAMA,EAAM;AAAA,QACZ,UAAUoL,EAAiB,QAAQ,KAAOC,EAAiB;AAAA,QAC3D,cAAcpB,GAAkBjK,EAAM,GAAG;AAAA,MAAA,CAC1C,IACD;AAAA,IAAA;AAGN,aAASyL,EAAczH,GAA0B;AAC/C,MAAAgH,EAAY,QAAQhH,GACpBiH,EAAgB,QAAQ;AAAA,IAC1B;AAEA,UAAMS,IAAoB/I;AAAA,MACxB,MAAM,CAAC4I,EAAU,SAASP,EAAY,MAAM,SAAS;AAAA,IAAA,GAEjDW,IAAmBhJ;AAAA,MAAS;;AAChC,eAAAsI,EAAgB,SAAS,IACrBA,EAAgB,UACfvJ,IAAAsJ,EAAY,MAAM,CAAC,MAAnB,gBAAAtJ,EAAsB,UAAS;AAAA;AAAA,IAAA,GAGhCkK,IAAcjJ;AAAA,MAAS,MAAA;;AAC3B,eAAAiI,EAAO,UAAU,aACZlJ,IAAA1B,EAAM,gBAAN,gBAAA0B,EAAmB,WAAU,WAC7BC,IAAA3B,EAAM,gBAAN,gBAAA2B,EAAmB,YAAW;AAAA;AAAA,IAAA,GAG/BkK,IAAgBlJ;AAAA,MAAS,MAAA;;AAC7B,eAAAiI,EAAO,UAAU,aACZlJ,IAAA1B,EAAM,kBAAN,gBAAA0B,EAAqB,WAAU,YAC/BC,IAAA3B,EAAM,kBAAN,gBAAA2B,EAAqB,YAAW;AAAA;AAAA,IAAA,GAGjCvB,IAAUuC,EAAS,MAAA;;AAAM,eAAAjB,IAAAiJ,EAAa,UAAb,gBAAAjJ,EAAoB,YAAW;AAAA,KAAI;AAElE,mBAAeoK,IAAW;AACxB,YAAMhL,IAAKV,EAAQ;AACnB,UAAKU;AACL,YAAI;AACF,UAAIA,EAAG,aAAa,KAAGA,EAAG,KAAA;AAC1B,gBAAMiL,IAAIjL,EAAG,KAAA;AACb,UAAAiK,EAAY,QAAQgB,GACpB,MAAMA,GACNlB,EAAU,QAAQ;AAAA,QACpB,QAAQ;AACN,UAAAA,EAAU,QAAQ;AAAA,QACpB,UAAA;AACE,UAAAE,EAAY,QAAQ;AAAA,QACtB;AAAA,IACF;AAEA,mBAAeiB,KAAY;AACzB,YAAMlL,IAAKV,EAAQ;AACnB,UAAKU,GACL;AAAA,YAAIiK,EAAY;AACd,cAAI;AACF,kBAAMA,EAAY;AAAA,UACpB,QAAQ;AAAA,UAER;AAEF,QAAAjK,EAAG,MAAA;AAAA;AAAA,IACL;AAEA,mBAAemL,KAAa;AAC1B,MAAI,CAACjM,EAAM,aAAauL,EAAU,SAClC,MAAMO,EAAA;AAAA,IACR;AAEA,mBAAeI,KAAY;AACzB,MAAI,CAAClM,EAAM,aAAauL,EAAU,UAClC,MAAMS,GAAA,GACNnB,EAAU,QAAQ;AAAA,IACpB;AAEA,mBAAesB,IAAa;AAC1B,YAAMrL,IAAKV,EAAQ;AACnB,MAAKU,MACDA,EAAG,SACL,MAAMgL,EAAA,KAEN,MAAME,GAAA,GACNnB,EAAU,QAAQ;AAAA,IAEtB;AAEA,aAASuB,IAAe;AACtB,MAAAtB,EAAY,QAAQ,IACfmB,GAAA;AAAA,IACP;AAEA,aAASI,KAAe;AACtB,MAAAvB,EAAY,QAAQ,IACfoB,GAAA;AAAA,IACP;AAEA,aAASI,GAAcxI,GAAc;AACnC,MAAAoH,EAAc,QAAQpH;AACtB,YAAMhD,IAAKV,EAAQ;AACnB,MAAIU,QAAO,eAAegD;AAAA,IAC5B;AAGA,IAAA/B,EAAM3B,GAAS,CAACU,MAAO;AACrB,MAAKA,MACLA,EAAG,iBAAiB,cAAc,MAAM;AAAE,QAAAoK,EAAc,QAAQpK,EAAG;AAAA,MAAc,CAAC,GAClFA,EAAG,iBAAiB,yBAAyB,MAAM;AAAE,QAAA0G,EAAM,QAAQ;AAAA,MAAM,CAAC,GAC1E1G,EAAG,iBAAiB,yBAAyB,MAAM;AAAE,QAAA0G,EAAM,QAAQ;AAAA,MAAO,CAAC;AAAA,IAC7E,CAAC;AAED,aAASE,IAAY;AACnB,YAAM5G,IAAKV,EAAQ;AACnB,MAAKU,MACD,SAAS,0BACX,SAAS,uBAAuB,MAAM,MAAM;AAAA,MAAe,CAAC,IAE5DA,EAAG,0BAA0B,MAAM,MAAM;AAAA,MAAe,CAAC;AAAA,IAE7D;AAIA,aAASyL,GAAU1J,GAAkB;;AACnC,YAAM/B,IAAKV,EAAQ;AAInB,UAHI,GAACU,KACD,CAACqK,EAAU,SAAS,GAACzJ,IAAAe,EAAO,UAAP,QAAAf,EAAc,SAAS,SAAS,mBAC5CmB,EAAE,OAAuB,YAC1B,WAAWA,EAAE,QAAQ;AAEjC,gBAAQA,EAAE,KAAA;AAAA,UACR,KAAK;AAAA,UACL,KAAK;AACH,YAAAA,EAAE,eAAA,GACGsJ,EAAA;AACL;AAAA,UACF,KAAK;AACH,YAAAtJ,EAAE,eAAA,GACF/B,EAAG,cAAc,KAAK,IAAI,GAAGA,EAAG,cAAc,CAAC;AAC/C;AAAA,UACF,KAAK;AACH,YAAA+B,EAAE,eAAA,GACF/B,EAAG,cAAc,KAAK,IAAIA,EAAG,YAAY,GAAGA,EAAG,cAAc,CAAC;AAC9D;AAAA,UACF,KAAK;AACH,YAAA+B,EAAE,eAAA,GACF/B,EAAG,SAAS,KAAK,IAAI,GAAGA,EAAG,SAAS,GAAG,GACnCA,EAAG,UAAOA,EAAG,QAAQ;AACzB;AAAA,UACF,KAAK;AACH,YAAA+B,EAAE,eAAA,GACF/B,EAAG,SAAS,KAAK,IAAI,GAAGA,EAAG,SAAS,GAAG;AACvC;AAAA,UACF,KAAK;AACH,YAAAA,EAAG,QAAQ,CAACA,EAAG;AACf;AAAA,UACF,KAAK,KAAK;AACR,kBAAM0L,KAAO,SAAS,qBACnB,SAAqE,2BAA2B,MAC7FC,MAAM9K,KAAAc,EAAO,UAAP,gBAAAd,GAAc,wBACvBC,KAAAa,EAAO,UAAP,gBAAAb,GAA8E,0BAC3E8K,IAAO,SAAS,kBACnB,SAAmE;AACtE,YAAIF,OAAS/J,EAAO,QAASiK,KAAA,QAAAA,EAAM,KAAK,UAAU,MAAM,MAAM;AAAA,YAAe,KACpED,KAAOhK,EAAO,SAASgK,EAAI,KAAKhK,EAAO,KAAK,EAAE,MAAM,MAAM;AAAA,YAAe,CAAC;AACnF;AAAA,UACF;AAAA,UACA,KAAK;AACH,YAAIgF,KAAcC,EAAA;AAClB;AAAA,QAAA;AAAA,IAEN;AAEA,WAAA5F,GAAU,MAAM;AAAE,eAAS,iBAAiB,WAAWyK,EAAS;AAAA,IAAG,CAAC,GACpEvK,EAAgB,MAAM;AAAE,eAAS,oBAAoB,WAAWuK,EAAS;AAAA,IAAG,CAAC,mBAI3ErK,EAiJM,OAAA;AAAA,eAhJA;AAAA,MAAJ,KAAIO;AAAA,MACH,OAAKN,EAAA,CAAA,YAAenC,EAAM,KAAK,CAAA;AAAA,MAC/B,OAAK2M,GAAA,EAAA,OAAWd,EAAA,OAAa,aAAED,EAAA,OAAW;AAAA,MAC1C,cAAU3I,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAA;AAAE,QAAAiI,EAAA,QAAS,IAASiB,EAAA;AAAA,MAAY;AAAA,MAC1C,cAAUnJ,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAA;AAAE,QAAAiI,EAAA,QAAS,IAAUkB,GAAA;AAAA,MAAY;AAAA,IAAA;MAGpCd,EAAA,cADRrJ,EAQE,UAAA;AAAA;QANA,OAAM;AAAA,QACL,KAAKsJ,EAAA,SAAc;AAAA,QACpB,OAAM;AAAA,QACN,OAAM;AAAA,QACN,iBAAA;AAAA,QACA,gBAAe;AAAA,MAAA,yBAEjB/C,EA0BYmE,IAAA;AAAA;iBAxBN;AAAA,QAAJ,KAAIjC;AAAA,QACH,UAAUU,EAAA;AAAA,QACV,cAAYpL,EAAA;AAAA,QACZ,UAAQA,EAAA;AAAA,QACR,MAAMA,EAAA;AAAA,QACN,OAAOA,EAAA;AAAA,QACP,aAAWA,EAAA;AAAA,QACX,qBAAmBgL,EAAA;AAAA,QACnB,gBAAc;AAAA,QACd,QAAQhL,EAAA;AAAA,QACR,KAAKA,EAAA;AAAA,QACN,OAAM;AAAA,QACN,SAAQ;AAAA,QACP,eAAAwL;AAAA,QACA,SAAKxI,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAA;AAAW,UAAA2H,EAAA,QAAS,IAAkB3K,EAAI,OAAA;AAAA;QAI/C,QAAI+C,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAA;AAAW,UAAA2H,EAAA,QAAS,IAAiB3K,EAAI,MAAA;AAAA;;oBAK9C,MAAQ;AAAA,UAARkC,GAAQC,EAAA,QAAA,SAAA;AAAA,QAAA;;;MAGEkJ,EAAA,qBAAZ/H,EAAA,GAAAtB,EAA8C,OAA9CmB,EAA8C;AAAA,MAEnCpD,EAAA,oBAAXuD,EAAA,GAAAtB,EAwBM,OAxBNuB,IAwBM;AAAA,QAvBJlB,EAsBM,OAtBNqB,IAsBM;AAAA,UArBJrB,EAQS,UAAA;AAAA,YAPN,gBAAcqI,EAAA,UAAM;AAAA,YACpB,2CAAyCA,EAAA,UAAM,UAAA,CAAA,CAAA;AAAA,YAChD,cAAW;AAAA,YACX,MAAK;AAAA,YACJ,gCAAOA,EAAA,QAAM;AAAA,UAAA;YAEdzH,EAAe0J,EAAA;AAAA,UAAA;4BAGjBtK,EAAkC,OAAA,EAA7B,OAAM,qBAAA,GAAoB,MAAA,EAAA;AAAA,UAE/BA,EAQS,UAAA;AAAA,YAPN,gBAAcqI,EAAA,UAAM;AAAA,YACpB,2CAAyCA,EAAA,UAAM,SAAA,CAAA,CAAA;AAAA,YAChD,cAAW;AAAA,YACX,MAAK;AAAA,YACJ,gCAAOA,EAAA,QAAM;AAAA,UAAA;YAEdzH,EAAc2J,EAAA;AAAA,UAAA;;;MAMZ7M,EAAA,iBADRiC,EAQS,UAAA;AAAA;QANP,cAAW;AAAA,QACX,OAAM;AAAA,QACN,MAAK;AAAA,QACJ,gCAAOhC,EAAI,OAAA;AAAA,MAAA;QAEZiD,EAAS4J,EAAA;AAAA,MAAA;MAKHrB,EAAA,UAAsBN,EAAA,cAD9B3C,EAKEuE,IAAA;AAAA;QAHC,QAAQhC,EAAA;AAAA,QACR,gBAAcW,EAAA;AAAA,QACd,UAAM1I,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAE+H,EAAA,QAAkB/H;AAAA,MAAA;MAIpB,CAAAqI,EAAA,UAAcH,EAAA,cADvB3C,EAIEwE,IAAA;AAAA;QAFC,OAAO/B,EAAA;AAAA,QACP,UAAQoB;AAAA,MAAA;MAGc,CAAAf,EAAA,UAAcH,EAAA,cAAvC3C,EAA4EyE,IAAA;AAAA;QAAlB,OAAO9M,EAAA;AAAA,MAAA;OAGxDmL,EAAA,SAAa1C,EAAApB,CAAA,KAAY,CAAK2D,EAAA,cADvClJ,EASS,UAAA;AAAA;QAPP,MAAK;AAAA,QACJ,wCAAsCsF,EAAA,MAAA,CAAK,CAAA;AAAA,QAC3C,cAAYA,EAAA,QAAK,4BAAA;AAAA,QACjB,gBAAcA,EAAA;AAAA,QACd,SAAOE;AAAA,MAAA;QAERvE,EAAWsG,EAAA;AAAA,MAAA;MAKJ,CAAA8B,EAAA,SAAaH,EAAA,cADtBlJ,EAME,UAAA;AAAA;QAJA,MAAK;AAAA,QACL,OAAM;AAAA,QACL,cAAY2I,EAAA,QAAS,UAAA;AAAA,QACrB,SAAOsB;AAAA,MAAA;OAIEZ,EAAA,SAAS,CAAKH,EAAA,SAAgB,CAAKP,EAAA,SAA/CrH,EAAA,GAAAtB,EAcM,OAdN6G,IAcM;AAAA,QAbJxG,EAYS,UAAA;AAAA,UAXP,cAAW;AAAA,UACX,OAAM;AAAA,UACN,MAAK;AAAA,UACJ,SAAO4J;AAAA,UACP,qCAAYrB,EAAA,QAAW;AAAA,UACvB,qCAAYA,EAAA,QAAW;AAAA,QAAA;UAExB3H,EAAYgK,EAAA;AAAA,UACAlN,EAAA,eAAe6K,EAAA,cAA3B5I,EAEO,QAFP8G,IAEO1F,EADFrD,EAAA,WAAW,GAAA,CAAA;;;MAOX,CAAAsL,EAAA,SAAaH,EAAA,cADtB3C,EAME2E,IAAA;AAAA;QAJC,OAAOhN,EAAA;AAAA,QACP,cAAYyK,EAAA;AAAA,QACZ,WAAWpI,EAAA;AAAA,QACX,kBAAgB0J;AAAA,MAAA;MAGP,CAAAZ,EAAA,UAAcH,EAAA,SAA1B5H,EAAA,GAAAtB,EAAsE,OAAtEmL,EAAsE;;;;"}
|
package/dist/utils/types.d.ts
CHANGED
|
@@ -21,11 +21,12 @@ export interface VideoPlayerProps {
|
|
|
21
21
|
loop?: boolean;
|
|
22
22
|
/**
|
|
23
23
|
* Controls mode.
|
|
24
|
-
* - `
|
|
25
|
-
*
|
|
26
|
-
* - `"
|
|
24
|
+
* - `true` (default) / `"custom"`: branded custom control bar, consistent
|
|
25
|
+
* across browsers/OS. Auto-hides during playback.
|
|
26
|
+
* - `"native"`: native browser controls (look varies by browser/OS).
|
|
27
|
+
* - `false`: no controls — just the centered play overlay.
|
|
27
28
|
*/
|
|
28
|
-
controls?: boolean | "custom";
|
|
29
|
+
controls?: boolean | "custom" | "native";
|
|
29
30
|
/**
|
|
30
31
|
* Start playback as soon as the source loads. Defaults to `false`.
|
|
31
32
|
* Browsers block sound-on autoplay, so this only autoplays when `muted`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE9C,MAAM,MAAM,WAAW,GAAG,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;AAEhD,MAAM,WAAW,gBAAgB;IAC/B,8EAA8E;IAC9E,GAAG,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oDAAoD;IACpD,aAAa,CAAC,EAAE,UAAU,CAAC;IAE3B,gFAAgF;IAChF,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE9C,MAAM,MAAM,WAAW,GAAG,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;AAEhD,MAAM,WAAW,gBAAgB;IAC/B,8EAA8E;IAC9E,GAAG,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oDAAoD;IACpD,aAAa,CAAC,EAAE,UAAU,CAAC;IAE3B,gFAAgF;IAChF,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACzC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,uDAAuD;IACvD,aAAa,CAAC,EAAE;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IAEF,wCAAwC;IACxC,WAAW,CAAC,EAAE;QACZ,OAAO,CAAC,EAAE,WAAW,CAAC;QACtB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,CAAC;IAEF;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB,kEAAkE;IAClE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
|
package/package.json
CHANGED