{"version":3,"file":"player.umd.cjs","names":["isRelative","API","flag","css","USER","USER","USER","USER","parseSubtitles","USER","PUBLIC","factory","global","exports","player_default","createLogger","args","enabled","prefix","createStore","state","initial","subs","evaluate","selector","log","call","sub","value","prev","patch","k","result","opts","createEventBus","handlers","anyHandlers","onceWrappers","safe","fn","e","name","forgetOnce","byCb","cb","bus","set","wrapper","off","data","INTERNAL","createCommandRegistry","hooks","h","handler","hook","list","current","x","ctx","createPluginHost","active","disposers","plugin","plugins","dispose","clamp","max","min","createInitialState","o","SUBTITLE_PREFIX","PAIR_RE","SEEK_RE","takeLabel","part","open","end","close","fileLabel","url","pickAlternative","link","options","s","random","extractInlineSubtitles","subtitles","rest","input","idx","inner","m","parseSource","labels","start","parseTrack","label","body","spec","i","t","q","parseSubtitleList","isRecord","v","isSourceSpecInput","isPlaylistInput","path","normalizeSpec","forceType","sourceKey","MEDIA_ERROR_KINDS","mediaErrorToPlayerError","err","isPlayerError","toPlayerError","QUARTILES","bufferedEnd","ranges","video","syncVolume","store","events","bindMediaEvents","d","offs","quartiles","endReached","suppressPause","endAt","duration","on","type","finish","unwait","status","pct","fullscreenElement","enterFullscreen","el","root","exitFullscreen","watchFullscreen","check","onChange","begin","isRelative$1","registerMediaCommands","playSafe","p","commands","target","raw","volume","r","rate","b","title","poster","fs","createMediaController","selection","lastInput","provider","providerQualities","providerAudio","token","attempt","chain","chainIndex","retriesUsed","pending","retryTimer","reloadStart","currentTracks","reloadOptions","contextFor","owner","fail","pickProvider","best","score","setError","error","a","tryUrl","time","resume","retries","delay","next","loading","startChain","switchSource","rejectInput","message","parsed","sel","transform","tracks","currentAudio","audio","extOf","match","resolveUrl","base","hasNativeHls","html5Provider","cancel","ext","cleanup","onMeta","onError","startTime","resolve","reject","loadHlsScript","w","script","src","integrity","levelLabels","levels","l","hlsProvider","hls","cleanupLoad","loadId","destroyHls","c","id","Hls","hlsUrl","hlsIntegrity","media","instance","networkRetried","mediaRetried","publishAudio","isNetwork","isMedia","index","API$1","NONE","isRelative","toNumber","flag$1","bit","SUBTITLE_RE","createApi","run","loadThenPlay","loads","load","table","arg","byLabel","player","cmd","SVG_NS","children","tag","key","attrs","child","ALLOWED_ELEMENTS","sanitizeAttributes","attr","sanitizeSvg","parseSvg","source","markup","doc","iconEl","span","svg","createRegistry","items","kind","item","simple","registerBuiltinHideRules","reg","n","compileHide","tests","specs","test","dictionaries","createTranslator","dict","lang","overrides","defaultIcons","createIconSet","createMenuHost","defs","panel","view","unsubscribe","previousFocus","visibleDefs","def","currentLabel","cur","signature","focusFirst","button","cls","onClick","render","host","hadFocus","focusIndex","option","buttons","cancelSwallow","swallowNextClick","timer","onOutside","playerRoot","inPlayer","onKey","step","ALIGNS","PATH_RE","BLOCKED_SEGMENTS","trimAll","parts","parseAction","align","resolveGlobal","self","createActionRunner","whole","fill","encode","execute","action","segment","toCssLength","applyBaseProps","props","playerId","text","createLayoutEngine","build","node","mounted","hidden","isHidden","built","parent","disposed","MAX_TIMEOUT","ACTIVATE","controlsVisible","createUserActivity","holds","canSchedule","setActive","poke","onLeave","hold","offMenu","offDrag","offUi","defaultLayout","pad","formatTime","seconds","total","reference","parseTimestamp","ms","rootComponent","overlayComponent","toolbarComponent","spacerComponent","groupComponent","PLACEHOLDER_RE","fillTemplate","template","textComponent","createIconButton","className","STEP_PX","createWheelStepper","acc","delta","up","bindWheelVolume","we","playComponent","bigPlayComponent","muteComponent","icon","muted","fullscreenComponent","settingsComponent","timeComponent","durationComponent","titleComponent","bufferingComponent","liveComponent","errorOverlayComponent","retry","mediaClickLayerComponent","revealOnly","reveal","round","createSlider","dragging","activePointerId","lastValue","valueAt","clientX","pointerOf","endDrag","pe","volumeComponent","slider","timelineComponent","buffered","progress","thumb","markers","dragTime","paint","position","rootX","live","inside","tick","commit","pos","BUILTIN_COMPONENTS","registerBuiltinComponents","registry","API","counter","livePlayers","resolveContainer","container","injectStyles","style","parseRatio","ratio","applyTheme","theme","createPlayerCore","previous","layerBelow","layoutLayer","layerAbove","providers","transforms","controller","components","hideRules","menus","activity","destroyed","destroying","alive","api","engine","layers","pluginContext","menu","rule","destroy","idle","pluginHost","layout","buildLayout","resizeObserver","width","height","onMetadata","USER$5","pickQuality","wanted","num","toList","qualityPlugin","forbidden","offTransform","USER$4","DEFAULT_SPEEDS","speedPlugin","speeds","defaultSpeed","USER$3","audioTracksPlugin","rename","display","parseCues","cues","block","lines","timing","line","left","right","shiftCues","shiftFromUrl","fallbackTenths","activeText","NAMED","decode","code","dec","hex","TAG_RE","cueNodes","fragment","stack","top","pushText","chunk","last","closing","USER$2","subtitlesPlugin","fetchText","optionList","defaultLabel","startOn","shiftTenths","lastEnabled","firstSource","generation","toTrack","ref","publish","track","gen","response","select","emit","initialIndex","ui","raised","refs","selectIt","parseThumbnails","hash","cue","rect","baseUrl","findThumb","lo","hi","thumbs","mid","FALLBACK_W","FALLBACK_H","thumbnailsPlugin","request","image","hgt","half","normalizePlaylist","wrapped","flattenPlaylist","flat","walk","depth","findIndex","byId","f","idOrIndex","loadPlaylistInput","trimmed","fetchFn","playlistPanelComponent","onClose","pl","indexOf","details","onSelect","playlistPlugin","startOpen","plstart","itemThumbs","internal","lastItemInput","epoch","cancelPlay","setOpen","playAfterLoad","playIndex","entry","autoplay","setItems","startIndex","neighbour","isOpen","added","merged","mark","USER$1","DEFAULTS","NO_WHEEL","TEXT_INPUT","hotkeysPlugin","cfg","hovered","user","stepWheel","actionFor","digit","onDocumentKey","onWheel","onEnter","isNotAllowed","autoplayPlugin","muteFallback","armed","mutedByAutoplay","fnv1a","str","KEYS","INDEX_KEY","DEFAULT_MAX_POSITIONS","SAVE_EVERY_SECONDS","shouldRestorePosition","saved","explicit","defaultStorage","memoryPlugin","storage","get","remove","readPosition","positionKey","lastSaved","maxPositions","readIndex","writeIndex","savePosition","USER","ACTIONS","mediaSessionPlugin","session","setHandler","lastState","publishMetadata","publishState","claim","defaultPlugins","PLAYERJS_EVENTS","PUBLIC$1","bridgeEvents","deliver","offAny","buffer","PUBLIC","bridgePostMessage","win","onMessage","answer","offEvents","flag","converted","convert","color","out","TABLE","COMPAT_ONLY","mapPlayerjsOptions","Playerjs","compat","createPlayer"],"sources":["../src/theme/player.css?inline","../src/core/logger.ts","../src/core/store.ts","../src/core/events.ts","../src/core/commands.ts","../src/core/plugin-host.ts","../src/shared/clamp.ts","../src/core/initial-state.ts","../src/source/parse.ts","../src/shared/errors.ts","../src/core/media-events.ts","../src/core/fullscreen.ts","../src/core/media-commands.ts","../src/core/media-controller.ts","../src/shared/url.ts","../src/providers/html5.ts","../src/providers/hls.ts","../src/api/api-map.ts","../src/ui/dom.ts","../src/ui/registry.ts","../src/ui/hide-rules.ts","../src/ui/i18n.ts","../src/ui/icons.ts","../src/ui/menu-host.ts","../src/ui/actions.ts","../src/ui/base-props.ts","../src/ui/layout.ts","../src/ui/activity.ts","../src/ui/default-layout.ts","../src/shared/time.ts","../src/components/containers.ts","../src/ui/button.ts","../src/ui/wheel.ts","../src/components/buttons.ts","../src/components/indicators.ts","../src/ui/slider.ts","../src/components/volume.ts","../src/components/timeline.ts","../src/components/index.ts","../src/player.ts","../src/plugins/quality.ts","../src/plugins/speed.ts","../src/plugins/audiotracks.ts","../src/shared/cues.ts","../src/plugins/subtitles/parse.ts","../src/plugins/subtitles/index.ts","../src/plugins/thumbnails/parse.ts","../src/plugins/thumbnails/index.ts","../src/plugins/playlist/model.ts","../src/plugins/playlist/panel.ts","../src/plugins/playlist/index.ts","../src/plugins/hotkeys.ts","../src/plugins/autoplay.ts","../src/shared/hash.ts","../src/plugins/memory.ts","../src/plugins/mediasession.ts","../src/plugins/index.ts","../src/api/events-list.ts","../src/compat/events.ts","../src/compat/postmessage.ts","../src/compat/options.ts","../src/compat/playerjs.ts","../src/create-player.ts","../src/umd.ts"],"sourcesContent":["/* ===== Root & theme variables ===== */\n/* Translucent tints are mixed from --vp-color-2 (foreground) and --vp-color-3 (surfaces), so light themes work. */\n.vp-root {\n  --vp-color-1: #00a3ff;\n  --vp-color-2: #ffffff;\n  --vp-color-3: rgba(18, 18, 18, 0.94);\n  --vp-toolbar-bg: linear-gradient(to top, rgba(0, 0, 0, 0.8), rgba(0, 0, 0, 0));\n  --vp-font: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n  --vp-font-size: 14px;\n  --vp-radius: 6px;\n  --vp-icon-size: 24px;\n  --vp-timeline-height: 4px;\n  --vp-sub-color: #ffffff;\n  --vp-sub-bg: rgba(0, 0, 0, 0.6);\n  --vp-sub-size: 1.4em;\n\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n  /* clip, unlike hidden, can't be scrolled by focus — off-canvas panels (playlist) stay put. */\n  overflow: clip;\n  background: #000;\n  color: var(--vp-color-2);\n  font-family: var(--vp-font);\n  font-size: var(--vp-font-size);\n  line-height: 1.25;\n  user-select: none;\n  -webkit-user-select: none;\n  -webkit-tap-highlight-color: transparent;\n  container-type: inline-size;\n  outline: none;\n}\n.vp-root *,\n.vp-root *::before,\n.vp-root *::after {\n  box-sizing: border-box;\n}\n.vp-root:fullscreen {\n  width: 100%;\n  height: 100%;\n  aspect-ratio: auto !important;\n}\n.vp-root:-webkit-full-screen {\n  width: 100%;\n  height: 100%;\n  aspect-ratio: auto !important;\n}\n.vp-root.vp-idle {\n  cursor: none;\n}\n.vp-root:focus-visible {\n  outline: 2px solid var(--vp-color-1);\n  outline-offset: -2px;\n}\n\n/* ===== Layers ===== */\n.vp-media,\n.vp-ui,\n.vp-layer-below,\n.vp-layout,\n.vp-layer-above,\n.vp-layout-root,\n.vp-overlay,\n.vp-click-layer {\n  position: absolute;\n  inset: 0;\n}\n.vp-media video {\n  display: block;\n  width: 100%;\n  height: 100%;\n  object-fit: contain;\n  background: #000;\n}\n.vp-layer-below,\n.vp-layer-above,\n.vp-overlay {\n  pointer-events: none;\n}\n.vp-layer-below > *,\n.vp-layer-above > *,\n.vp-overlay > * {\n  pointer-events: auto;\n}\n.vp-click-layer {\n  cursor: pointer;\n}\n\n.vp-ui {\n  font-size: var(--vp-font-size);\n}\n\n/* ===== Visibility ===== */\n.vp-toolbar,\n.vp-title,\n.vp-big-play,\n.vp-buffering,\n.vp-error,\n.vp-anchor {\n  transition: opacity 0.25s ease, visibility 0.25s ease;\n}\n.vp-hidden {\n  opacity: 0 !important;\n  visibility: hidden !important;\n  pointer-events: none !important;\n}\n/* Hidden items inside a row/column collapse instead of keeping their space. */\n.vp-group > .vp-hidden {\n  display: none !important;\n}\n\n/* ===== Anchors ===== */\n.vp-anchor {\n  position: absolute;\n}\n.vp-anchor-top-left { top: 12px; left: 12px; }\n.vp-anchor-top { top: 12px; left: 50%; translate: -50% 0; }\n.vp-anchor-top-right { top: 12px; right: 12px; }\n.vp-anchor-left { top: 50%; left: 12px; translate: 0 -50%; }\n.vp-anchor-center { top: 50%; left: 50%; translate: -50% -50%; }\n.vp-anchor-right { top: 50%; right: 12px; translate: 0 -50%; }\n.vp-anchor-bottom-left { bottom: 12px; left: 12px; }\n.vp-anchor-bottom { bottom: 12px; left: 50%; translate: -50% 0; }\n.vp-anchor-bottom-right { bottom: 12px; right: 12px; }\n\n/* ===== Toolbar & groups ===== */\n.vp-toolbar {\n  position: absolute;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  display: flex;\n  flex-direction: column;\n  gap: 2px;\n  padding: 28px 10px 6px;\n  background: var(--vp-toolbar-bg);\n}\n.vp-group {\n  display: flex;\n  align-items: center;\n  gap: 2px;\n  min-width: 0;\n}\n.vp-group-column {\n  flex-direction: column;\n  align-items: stretch;\n}\n.vp-spacer {\n  flex: 1 1 auto;\n}\n\n/* ===== Buttons & icons ===== */\n.vp-button {\n  appearance: none;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  margin: 0;\n  padding: 6px;\n  border: 0;\n  border-radius: var(--vp-radius);\n  background: none;\n  color: inherit;\n  font: inherit;\n  cursor: pointer;\n}\n.vp-button:hover {\n  background: color-mix(in srgb, var(--vp-color-2) 12%, transparent);\n}\n.vp-button:focus-visible,\n.vp-timeline:focus-visible,\n.vp-slider:focus-visible,\n.vp-menu button:focus-visible {\n  outline: 2px solid var(--vp-color-1);\n  outline-offset: 1px;\n}\n.vp-icon {\n  display: inline-flex;\n  width: var(--vp-icon-size);\n  height: var(--vp-icon-size);\n}\n.vp-icon svg {\n  width: 100%;\n  height: 100%;\n}\n.vp-big-play {\n  width: 76px;\n  height: 76px;\n  border-radius: 50%;\n  background: color-mix(in srgb, var(--vp-color-3) 60%, transparent);\n  --vp-icon-size: 44px;\n}\n.vp-big-play:hover {\n  background: var(--vp-color-1);\n}\n\n/* ===== Text indicators ===== */\n.vp-time,\n.vp-duration,\n.vp-text {\n  padding: 0 2px;\n  white-space: nowrap;\n  font-variant-numeric: tabular-nums;\n}\n.vp-title {\n  max-width: calc(100% - 24px);\n  overflow: hidden;\n  font-size: 1.15em;\n  font-weight: 600;\n  white-space: nowrap;\n  text-overflow: ellipsis;\n  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);\n}\n.vp-title:empty {\n  display: none;\n}\n.vp-live {\n  padding: 2px 6px;\n  font-size: 0.85em;\n  font-weight: 700;\n  letter-spacing: 0.05em;\n}\n.vp-live-dot {\n  color: #ff3b30;\n}\n.vp-buffering {\n  width: 52px;\n  height: 52px;\n  border: 4px solid color-mix(in srgb, var(--vp-color-2) 25%, transparent);\n  border-top-color: var(--vp-color-2);\n  border-radius: 50%;\n  animation: vp-spin 0.9s linear infinite;\n  pointer-events: none !important;\n}\n@keyframes vp-spin {\n  to {\n    rotate: 360deg;\n  }\n}\n.vp-error {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 12px;\n  max-width: 80%;\n  padding: 16px 20px;\n  border-radius: var(--vp-radius);\n  background: color-mix(in srgb, var(--vp-color-3) 83%, transparent);\n  text-align: center;\n}\n.vp-error-retry {\n  padding: 6px 14px;\n  border: 1px solid color-mix(in srgb, var(--vp-color-2) 40%, transparent);\n}\n\n/* ===== Timeline ===== */\n.vp-timeline-live {\n  display: none !important;\n}\n.vp-timeline {\n  position: relative;\n  display: flex;\n  align-items: center;\n  height: 18px;\n  cursor: pointer;\n  touch-action: none;\n}\n.vp-timeline-track {\n  position: relative;\n  width: 100%;\n  height: var(--vp-timeline-height);\n  border-radius: 999px;\n  background: color-mix(in srgb, var(--vp-color-2) 25%, transparent);\n  transition: height 0.15s ease;\n}\n.vp-timeline:hover .vp-timeline-track,\n.vp-timeline.vp-dragging .vp-timeline-track {\n  height: calc(var(--vp-timeline-height) * 1.6);\n}\n.vp-timeline-buffered,\n.vp-timeline-progress {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  border-radius: inherit;\n}\n.vp-timeline-buffered {\n  background: color-mix(in srgb, var(--vp-color-2) 35%, transparent);\n}\n.vp-timeline-progress {\n  background: var(--vp-color-1);\n}\n.vp-timeline-markers {\n  position: absolute;\n  inset: 0;\n  pointer-events: none;\n}\n/* A gap in the track, like chapter breaks. */\n.vp-timeline-marker {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  width: 3px;\n  translate: -50% 0;\n  background: var(--vp-color-3);\n}\n.vp-timeline-thumb {\n  position: absolute;\n  top: 50%;\n  width: 13px;\n  height: 13px;\n  margin: -6.5px 0 0 -6.5px;\n  border-radius: 50%;\n  background: var(--vp-color-1);\n  scale: 0;\n  transition: scale 0.15s ease;\n}\n.vp-timeline:hover .vp-timeline-thumb,\n.vp-timeline.vp-dragging .vp-timeline-thumb {\n  scale: 1;\n}\n\n/* ===== Slider (volume) ===== */\n.vp-slider {\n  position: relative;\n  display: flex;\n  align-items: center;\n  width: 72px;\n  height: 24px;\n  margin: 0 6px 0 2px;\n  cursor: pointer;\n  touch-action: none;\n}\n.vp-slider-track {\n  position: relative;\n  width: 100%;\n  height: 4px;\n  border-radius: 999px;\n  background: color-mix(in srgb, var(--vp-color-2) 30%, transparent);\n}\n.vp-slider-fill {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  border-radius: inherit;\n  background: var(--vp-color-2);\n}\n\n/* ===== Settings menu ===== */\n.vp-menu {\n  position: absolute;\n  right: 12px;\n  bottom: 64px;\n  min-width: 210px;\n  max-height: calc(100% - 80px);\n  overflow-y: auto;\n  padding: 6px 0;\n  border-radius: var(--vp-radius);\n  background: var(--vp-color-3);\n  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);\n  font-size: 0.95em;\n}\n.vp-menu-left {\n  right: auto;\n  left: 12px;\n}\n.vp-menu-center {\n  right: auto;\n  left: 50%;\n  translate: -50% 0;\n}\n.vp-menu button {\n  all: unset;\n  box-sizing: border-box;\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  width: 100%;\n  padding: 8px 14px;\n  cursor: pointer;\n}\n.vp-menu button:hover {\n  background: color-mix(in srgb, var(--vp-color-2) 10%, transparent);\n}\n.vp-menu-label {\n  flex: 1;\n}\n.vp-menu-value {\n  opacity: 0.7;\n}\n.vp-menu-check {\n  display: inline-flex;\n  width: 18px;\n  --vp-icon-size: 18px;\n}\n.vp-menu-item.vp-active {\n  color: var(--vp-color-1);\n}\n.vp-menu-back,\n.vp-menu-title {\n  margin-bottom: 4px;\n  border-bottom: 1px solid color-mix(in srgb, var(--vp-color-2) 12%, transparent);\n  font-weight: 600;\n  --vp-icon-size: 18px;\n}\n.vp-menu-title {\n  padding: 8px 14px;\n}\n\n/* ===== Small players ===== */\n@container (max-width: 480px) {\n  .vp-ui {\n    --vp-icon-size: 20px;\n    --vp-font-size: 13px;\n  }\n  .vp-toolbar {\n    padding: 18px 8px 2px;\n  }\n}\n\n/* ===== Utilities ===== */\n.vp-sr-only {\n  position: absolute !important;\n  width: 1px;\n  height: 1px;\n  margin: -1px;\n  padding: 0;\n  overflow: hidden;\n  clip: rect(0 0 0 0);\n  white-space: nowrap;\n  border: 0;\n}\n\n/* ===== Plugins (appended in chunk 7) ===== */\n\n/* subtitles */\n.vp-subtitles {\n  position: absolute;\n  left: 5%;\n  right: 5%;\n  bottom: 6%;\n  display: flex;\n  justify-content: center;\n  pointer-events: none !important;\n  transition: bottom 0.25s ease;\n}\n.vp-subtitles.vp-subtitles-raised {\n  bottom: calc(6% + 56px);\n}\n.vp-subtitles-text {\n  max-width: 100%;\n  padding: 0.1em 0.4em;\n  border-radius: 4px;\n  background: var(--vp-sub-bg);\n  color: var(--vp-sub-color);\n  font-size: var(--vp-sub-size);\n  line-height: 1.35;\n  text-align: center;\n  white-space: pre-line;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.vp-subtitles-text:empty {\n  display: none;\n}\n\n/* thumbnails */\n.vp-thumb {\n  position: absolute;\n  bottom: 72px;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 4px;\n  pointer-events: none !important;\n}\n.vp-thumb-image {\n  border: 2px solid color-mix(in srgb, var(--vp-color-2) 85%, transparent);\n  border-radius: 4px;\n  background-color: #000;\n  background-repeat: no-repeat;\n  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);\n}\n.vp-thumb-image[hidden] {\n  display: none;\n}\n.vp-thumb-time {\n  padding: 2px 6px;\n  border-radius: 4px;\n  background: color-mix(in srgb, var(--vp-color-3) 80%, transparent);\n  font-size: 0.85em;\n  font-variant-numeric: tabular-nums;\n}\n\n/* playlist */\n.vp-playlist {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  display: flex;\n  flex-direction: column;\n  width: min(320px, 85%);\n  background: var(--vp-color-3);\n  box-shadow: -6px 0 24px rgba(0, 0, 0, 0.4);\n  transition: opacity 0.2s ease, visibility 0.2s ease, translate 0.2s ease;\n}\n.vp-playlist.vp-hidden {\n  translate: 24px 0;\n}\n.vp-playlist-header {\n  display: flex;\n  align-items: center;\n  gap: 6px;\n  padding: 8px;\n  border-bottom: 1px solid color-mix(in srgb, var(--vp-color-2) 12%, transparent);\n  font-weight: 600;\n}\n.vp-playlist-list {\n  flex: 1;\n  overflow-y: auto;\n  padding: 6px 0;\n}\n.vp-playlist-folder > summary {\n  padding: 8px 14px;\n  cursor: pointer;\n  font-weight: 600;\n  opacity: 0.85;\n}\n.vp-playlist-folder .vp-playlist-item {\n  padding-left: 26px;\n}\n.vp-playlist-item {\n  all: unset;\n  box-sizing: border-box;\n  display: flex;\n  align-items: center;\n  gap: 10px;\n  width: 100%;\n  padding: 8px 14px;\n  cursor: pointer;\n}\n.vp-playlist-item:hover,\n.vp-playlist-item:focus-visible {\n  background: color-mix(in srgb, var(--vp-color-2) 10%, transparent);\n}\n.vp-playlist-item.vp-active {\n  color: var(--vp-color-1);\n}\n.vp-playlist-poster {\n  width: 64px;\n  height: 36px;\n  flex: none;\n  border-radius: 3px;\n  object-fit: cover;\n}\n.vp-playlist-title {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n","import type { Logger } from '../types.js';\n\nexport function createLogger(enabled: boolean, prefix = '[vp]'): Logger {\n  return {\n    debug: (...args) => {\n      if (enabled) console.log(prefix, ...args);\n    },\n    warn: (...args) => console.warn(prefix, ...args),\n    error: (...args) => console.error(prefix, ...args),\n  };\n}\n","import type { Logger, SelectOptions, Store } from '../types.js';\n\ninterface Subscription<S, T> {\n  selector: (s: S) => T;\n  cb: (value: T, prev: T) => void;\n  equals: (a: T, b: T) => boolean;\n  last: T;\n}\n\nexport function createStore<S extends object>(initial: S, log?: Logger): Store<S> {\n  let state: S = { ...initial };\n  const subs = new Set<Subscription<S, any>>();\n\n  // Selectors run plugin code (menus, hide rules): a throw must not escape into whoever called `set`.\n  const evaluate = <T>(selector: (s: S) => T): { ok: true; value: T } | { ok: false } => {\n    try {\n      return { ok: true, value: selector(state) };\n    } catch (e) {\n      log?.error('store selector failed', e);\n      return { ok: false };\n    }\n  };\n\n  const call = <T>(sub: Subscription<S, T>, value: T, prev: T) => {\n    try {\n      sub.cb(value, prev);\n    } catch (e) {\n      log?.error('store subscriber failed', e);\n    }\n  };\n\n  return {\n    get: () => state,\n\n    set(patch) {\n      const changed = (Object.keys(patch) as Array<keyof S>).some((k) => !Object.is(state[k], patch[k]));\n      if (!changed) return;\n      state = { ...state, ...patch };\n      for (const sub of [...subs]) {\n        if (!subs.has(sub)) continue;\n        const result = evaluate(sub.selector);\n        if (!result.ok) continue;\n        const value = result.value;\n        if (sub.equals(value, sub.last)) continue;\n        const prev = sub.last;\n        sub.last = value;\n        call(sub, value, prev);\n      }\n    },\n\n    select<T>(selector: (s: S) => T, cb: (value: T, prev: T) => void, opts: SelectOptions<T> = {}) {\n      const initial = evaluate(selector);\n      // A selector that throws up front starts from `undefined` and has nothing to report immediately.\n      const sub: Subscription<S, T> = { selector, cb, equals: opts.equals ?? Object.is, last: initial.ok ? initial.value : (undefined as T) };\n      subs.add(sub);\n      if (opts.immediate && initial.ok) call(sub, sub.last, sub.last);\n      return () => {\n        subs.delete(sub);\n      };\n    },\n  };\n}\n","import type { EventBus, EventHandler, EventName, Logger } from '../types.js';\n\ntype AnyHandler = (name: EventName, data: unknown) => void;\n\nexport function createEventBus(log?: Logger): EventBus {\n  const handlers = new Map<EventName, Set<(data: unknown) => void>>();\n  const anyHandlers = new Set<AnyHandler>();\n  const onceWrappers = new Map<EventName, Map<unknown, (data: unknown) => void>>();\n\n  const safe = (fn: () => void, name: EventName) => {\n    try {\n      fn();\n    } catch (e) {\n      log?.error(`event handler for \"${String(name)}\" failed`, e);\n    }\n  };\n\n  const forgetOnce = (name: EventName, cb: unknown) => {\n    const byCb = onceWrappers.get(name);\n    if (!byCb) return;\n    byCb.delete(cb);\n    if (byCb.size === 0) onceWrappers.delete(name);\n  };\n\n  const bus: EventBus = {\n    on(name, cb) {\n      let set = handlers.get(name);\n      if (!set) handlers.set(name, (set = new Set()));\n      set.add(cb as (data: unknown) => void);\n      return () => bus.off(name, cb);\n    },\n\n    once(name, cb) {\n      const wrapper = ((data: unknown) => {\n        off();\n        forgetOnce(name, cb);\n        (cb as (data: unknown) => void)(data);\n      }) as EventHandler<typeof name>;\n      const off = bus.on(name, wrapper);\n      let byCb = onceWrappers.get(name);\n      if (!byCb) onceWrappers.set(name, (byCb = new Map()));\n      byCb.set(cb, wrapper as (data: unknown) => void);\n      return () => {\n        off();\n        if (onceWrappers.get(name)?.get(cb) === wrapper) forgetOnce(name, cb);\n      };\n    },\n\n    off(name, cb) {\n      const set = handlers.get(name);\n      set?.delete(cb as (data: unknown) => void);\n      const wrapper = onceWrappers.get(name)?.get(cb);\n      if (wrapper && set?.delete(wrapper)) forgetOnce(name, cb);\n    },\n\n    emit(name, ...args) {\n      const data = args[0];\n      const set = handlers.get(name);\n      if (set) for (const cb of [...set]) safe(() => cb(data), name);\n      for (const cb of [...anyHandlers]) safe(() => cb(name, data), name);\n    },\n\n    onAny(cb) {\n      anyHandlers.add(cb);\n      return () => {\n        anyHandlers.delete(cb);\n      };\n    },\n  };\n  return bus;\n}\n","import type { BeforeHook, CommandContext, CommandHandler, CommandName, CommandRegistry, Logger } from '../types.js';\n\ntype AnyHandler = (args: unknown[], ctx: CommandContext) => unknown;\ntype AnyHook = (args: unknown[], ctx: CommandContext) => false | void | unknown[];\n\nconst INTERNAL: CommandContext = { source: 'internal' };\n\nexport function createCommandRegistry(log: Logger): CommandRegistry {\n  const handlers = new Map<string, AnyHandler>();\n  const hooks = new Map<string, AnyHook[]>();\n\n  return {\n    register<K extends CommandName>(name: K, handler: CommandHandler<K>) {\n      if (handlers.has(name)) log.warn(`command \"${name}\" handler replaced`);\n      const h = handler as unknown as AnyHandler;\n      handlers.set(name, h);\n      return () => {\n        if (handlers.get(name) === h) handlers.delete(name);\n      };\n    },\n\n    before<K extends CommandName>(name: K, hook: BeforeHook<K>) {\n      const h = hook as unknown as AnyHook;\n      const list = hooks.get(name) ?? [];\n      list.push(h);\n      hooks.set(name, list);\n      return () => {\n        const current = hooks.get(name);\n        if (current) hooks.set(name, current.filter((x) => x !== h));\n      };\n    },\n\n    run(name, args, ctx = INTERNAL) {\n      const handler = handlers.get(name);\n      if (!handler) {\n        log.warn(`unknown command \"${name}\"`);\n        return undefined;\n      }\n      let current = args as unknown[];\n      for (const hook of [...(hooks.get(name) ?? [])]) {\n        let result: false | void | unknown[];\n        try {\n          result = hook(current, ctx);\n        } catch (e) {\n          log.error(`before-hook for \"${name}\" failed`, e);\n          continue;\n        }\n        if (result === false) return undefined;\n        if (Array.isArray(result)) current = result;\n      }\n      try {\n        const result = handler(current, ctx);\n        // Keep returning the original promise, but never leave it unhandled.\n        if (result && typeof (result as Promise<unknown>).catch === 'function') {\n          (result as Promise<unknown>).catch((e) => log.debug(`command \"${name}\" rejected`, e));\n        }\n        return result as any;\n      } catch (e) {\n        log.error(`command \"${name}\" failed`, e);\n        return undefined;\n      }\n    },\n\n    has: (name) => handlers.has(name),\n  };\n}\n","import type { Logger, Plugin, PluginContext } from '../types.js';\n\nexport interface PluginHost {\n  setupAll(plugins: Plugin[], ctx: PluginContext): void;\n  disposeAll(): void;\n  has(name: string): boolean;\n}\n\nexport function createPluginHost(log: Logger): PluginHost {\n  const active = new Set<string>();\n  const disposers: Array<{ name: string; fn: () => void }> = [];\n\n  return {\n    setupAll(plugins, ctx) {\n      for (const plugin of plugins) {\n        if (active.has(plugin.name)) {\n          log.warn(`plugin \"${plugin.name}\" is already registered; duplicate ignored`);\n          continue;\n        }\n        try {\n          const dispose = plugin.setup(ctx);\n          active.add(plugin.name);\n          if (typeof dispose === 'function') disposers.push({ name: plugin.name, fn: dispose });\n        } catch (e) {\n          log.error(`plugin \"${plugin.name}\" failed to set up`, e);\n        }\n      }\n    },\n\n    disposeAll() {\n      for (const { name, fn } of disposers.reverse()) {\n        try {\n          fn();\n        } catch (e) {\n          log.error(`plugin \"${name}\" failed to dispose`, e);\n        }\n      }\n      disposers.length = 0;\n      active.clear();\n    },\n\n    has: (name) => active.has(name),\n  };\n}\n","export function clamp(value: number, min: number, max: number): number {\n  return Math.min(max, Math.max(min, value));\n}\n","import type { PlayerOptions, PlayerState } from '../types.js';\nimport { clamp } from '../shared/clamp.js';\n\nexport function createInitialState(o: PlayerOptions): PlayerState {\n  return {\n    status: 'idle',\n    started: false,\n    currentTime: 0,\n    duration: 0,\n    buffered: 0,\n    live: false,\n    waiting: false,\n    volume: clamp(o.volume ?? 1, 0, 1),\n    muted: !!o.muted,\n    rate: o.rate ?? 1,\n    fullscreen: false,\n    userActive: false,\n    controlsLocked: false,\n    width: 0,\n    height: 0,\n    url: '',\n    qualities: [],\n    quality: 0,\n    audioTracks: [],\n    audioTrack: 0,\n    textTracks: [],\n    textTrack: -1,\n    preferredSubtitle: null,\n    title: o.title ?? '',\n    poster: o.poster ?? '',\n    loop: !!o.loop,\n    error: null,\n    markers: [],\n  };\n}\n","import type { SourceInput, SourceSpec, SourceSpecInput, SourceTrack, SubtitleRef } from '../types.js';\n\nexport interface ParseOptions {\n  /** Labels for unlabeled comma-separated qualities, e.g. \"480p,720p\". */\n  qualities?: string;\n  random?: () => number;\n}\n\nconst SUBTITLE_PREFIX = '(subtitle:';\nconst PAIR_RE = /\\[([^\\]]*)\\]([^[,]+)/g;\nconst SEEK_RE = /\\[seek:(\\d+(?:\\.\\d+)?)\\]$/;\n\nfunction takeLabel(part: string, open: string, close: string): [string, string] {\n  if (part.startsWith(open)) {\n    const end = part.indexOf(close);\n    if (end > 0) return [part.slice(1, end).trim(), part.slice(end + 1).trim()];\n  }\n  return ['', part];\n}\n\nfunction fileLabel(url: string): string {\n  const name = url.split(/[?#]/)[0]!.split('/').pop() ?? '';\n  return name.replace(/\\.[^.]+$/, '');\n}\n\nfunction pickAlternative(link: string, random: () => number): string {\n  if (!link.includes(' and ')) return link;\n  const options = link.split(' and ').map((s) => s.trim()).filter(Boolean);\n  return options[Math.min(options.length - 1, Math.floor(random() * options.length))] ?? '';\n}\n\nfunction extractInlineSubtitles(input: string): { rest: string; subtitles: SubtitleRef[] } {\n  const subtitles: SubtitleRef[] = [];\n  let rest = input;\n  let idx = rest.indexOf(SUBTITLE_PREFIX);\n  while (idx >= 0) {\n    const end = rest.indexOf(')', idx);\n    if (end < 0) break;\n    const inner = rest.slice(idx + SUBTITLE_PREFIX.length, end);\n    for (const m of inner.matchAll(PAIR_RE)) subtitles.push({ label: m[1]!.trim(), url: m[2]!.trim() });\n    rest = rest.slice(0, idx) + rest.slice(end + 1);\n    idx = rest.indexOf(SUBTITLE_PREFIX);\n  }\n  return { rest, subtitles };\n}\n\nexport function parseSource(input: string, opts: ParseOptions = {}): SourceSpec {\n  const random = opts.random ?? Math.random;\n  const { rest, subtitles } = extractInlineSubtitles(input.trim());\n  const labels = opts.qualities?.split(',').map((s) => s.trim()) ?? [];\n  let start: number | undefined;\n\n  const parseTrack = (part: string): SourceTrack => {\n    const [label, body] = takeLabel(part, '{', '}');\n    const urls = body\n      .split(' or ')\n      .map((link) => pickAlternative(link.trim(), random))\n      .map((url) => {\n        const m = url.match(SEEK_RE);\n        if (!m) return url;\n        start ??= Number(m[1]);\n        return url.slice(0, m.index).trim();\n      })\n      .filter(Boolean);\n    return { label, urls };\n  };\n\n  const qualities = rest\n    .split(',')\n    .map((s) => s.trim())\n    .filter(Boolean)\n    .map((part) => takeLabel(part, '[', ']'))\n    .filter(([label]) => !label.startsWith('<<<'))\n    .map(([label, body], i) => ({\n      label: label || labels[i] || '',\n      tracks: body.split(';').map((s) => s.trim()).filter(Boolean).map(parseTrack).filter((t) => t.urls.length > 0),\n    }))\n    .filter((q) => q.tracks.length > 0);\n\n  const spec: SourceSpec = { qualities, subtitles, key: input.trim() };\n  if (start !== undefined) spec.start = start;\n  return spec;\n}\n\nexport function parseSubtitleList(value: string): SubtitleRef[] {\n  return value\n    .split(',')\n    .map((s) => s.trim())\n    .filter(Boolean)\n    .map((part) => {\n      const [label, url] = takeLabel(part, '[', ']');\n      return { label: label || fileLabel(url), url };\n    });\n}\n\nconst isRecord = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);\n\n/** A source spec object: the only non-string input the media controller can load itself. */\nexport function isSourceSpecInput(input: unknown): input is SourceSpecInput {\n  return isRecord(input) && Array.isArray(input.qualities);\n}\n\n/** A playlist: JSON or a .txt/.json url, an array of items, or an item / `{ playlist }` object. */\nexport function isPlaylistInput(input: SourceInput): boolean {\n  if (Array.isArray(input)) return input.length > 0 && input.every(isRecord);\n  if (isRecord(input)) return !isSourceSpecInput(input) && ('file' in input || 'folder' in input || 'playlist' in input);\n  if (typeof input !== 'string') return false;\n  const s = input.trim();\n  if (s.startsWith('[{') || s.startsWith('{')) {\n    try {\n      JSON.parse(s);\n      return true;\n    } catch {\n      return false;\n    }\n  }\n  const path = (s.split(/[?#]/)[0] ?? '').toLowerCase();\n  return path.endsWith('.txt') || path.endsWith('.json');\n}\n\nexport function normalizeSpec(input: SourceSpecInput, forceType?: 'hls'): SourceSpec {\n  return {\n    qualities: input.qualities,\n    subtitles: input.subtitles ?? [],\n    start: input.start,\n    forceType: input.forceType ?? forceType,\n    key: input.key,\n  };\n}\n\n/** Stable identity of a source: its `key` when known, else the first url of the first quality/track. */\nexport function sourceKey(spec: SourceSpec): string {\n  return spec.key ?? spec.qualities[0]?.tracks[0]?.urls[0] ?? '';\n}\n","import type { ErrorKind, PlayerError } from '../types.js';\n\nconst MEDIA_ERROR_KINDS: Record<number, ErrorKind> = { 1: 'unknown', 2: 'network', 3: 'decode', 4: 'unsupported' };\n\nexport function mediaErrorToPlayerError(err: MediaError | null): PlayerError {\n  if (!err) return { kind: 'unknown', message: 'Unknown media error' };\n  return { kind: MEDIA_ERROR_KINDS[err.code] ?? 'unknown', message: err.message || `MediaError ${err.code}` };\n}\n\nexport function isPlayerError(value: unknown): value is PlayerError {\n  return typeof value === 'object' && value !== null && 'kind' in value && 'message' in value;\n}\n\nexport function toPlayerError(value: unknown): PlayerError {\n  if (isPlayerError(value)) return { kind: value.kind, message: value.message };\n  if (value instanceof Error) return { kind: 'unknown', message: value.message };\n  return { kind: 'unknown', message: String(value) };\n}\n","import type { PlayerError } from '../types.js';\nimport type { MediaDeps } from './media-deps.js';\nimport { mediaErrorToPlayerError } from '../shared/errors.js';\n\nexport interface MediaEventHooks {\n  onMediaError(err: PlayerError): void;\n}\n\nconst QUARTILES = [25, 50, 75] as const;\n\nfunction bufferedEnd(video: HTMLVideoElement): number {\n  const ranges = video.buffered;\n  const t = video.currentTime;\n  for (let i = 0; i < ranges.length; i++) {\n    if (ranges.start(i) <= t + 0.5 && t <= ranges.end(i)) return ranges.end(i);\n  }\n  return 0;\n}\n\n/**\n * Copies volume/muted from the element into the store and emits change events once.\n * Commands call it directly: a media load drops queued `volumechange` tasks, so the event alone can be lost.\n */\nexport function syncVolume({ video, store, events }: Pick<MediaDeps, 'video' | 'store' | 'events'>): void {\n  const prev = store.get();\n  if (prev.volume === video.volume && prev.muted === video.muted) return;\n  store.set({ volume: video.volume, muted: video.muted });\n  if (prev.volume !== video.volume) events.emit('volume', video.volume);\n  if (prev.muted !== video.muted) events.emit(video.muted ? 'mute' : 'unmute');\n}\n\nexport function bindMediaEvents(d: MediaDeps, hooks: MediaEventHooks): () => void {\n  const { video, store, events, options } = d;\n  const offs: Array<() => void> = [];\n  const quartiles = new Set<number>();\n  /** The `end` option fired for this source; re-armed by `new` or a seek before the end point. */\n  let endReached = false;\n  /** Swallow the `pause` event caused by our own pause() at the end point. */\n  let suppressPause = false;\n\n  const endAt = () => {\n    const duration = video.duration;\n    if (options.end === undefined || !Number.isFinite(duration) || duration <= 0) return Infinity;\n    return options.end > 0 ? options.end : duration + options.end;\n  };\n\n  const on = (type: string, fn: () => void) => {\n    video.addEventListener(type, fn);\n    offs.push(() => video.removeEventListener(type, fn));\n  };\n\n  const finish = () => {\n    if (!quartiles.has(100)) {\n      quartiles.add(100);\n      events.emit('quartile', 100);\n    }\n    store.set({ status: 'ended' });\n    events.emit('end');\n    events.emit('finish');\n  };\n\n  const unwait = () => {\n    if (!store.get().waiting) return;\n    store.set({ waiting: false });\n    events.emit('buffered');\n  };\n\n  offs.push(\n    events.on('new', () => {\n      quartiles.clear();\n      endReached = false;\n      suppressPause = false;\n    }),\n  );\n\n  on('durationchange', () => {\n    const duration = video.duration;\n    store.set({ duration: Number.isFinite(duration) ? duration : 0, live: duration === Infinity });\n    if (Number.isFinite(duration)) events.emit('duration', duration);\n  });\n\n  on('play', () => {\n    store.set({ status: 'playing' });\n    events.emit('play');\n  });\n\n  on('playing', () => {\n    store.set({ status: 'playing' });\n    unwait();\n    if (!store.get().started) {\n      store.set({ started: true });\n      events.emit('start');\n    }\n  });\n\n  on('pause', () => {\n    if (suppressPause) {\n      suppressPause = false;\n      return;\n    }\n    const status = store.get().status;\n    if (video.ended || status === 'error' || status === 'loading') return;\n    store.set({ status: 'paused' });\n    events.emit('pause');\n  });\n\n  on('waiting', () => {\n    if (store.get().waiting) return;\n    store.set({ waiting: true });\n    events.emit('buffering');\n  });\n\n  on('canplay', unwait);\n\n  on('seeked', () => {\n    unwait();\n    const t = video.currentTime;\n    if (t < endAt()) endReached = false;\n    const duration = video.duration;\n    if (store.get().status === 'ended' && t < Math.min(endAt(), Number.isFinite(duration) ? duration : Infinity)) {\n      store.set({ status: 'paused' });\n    }\n    events.emit('seek', video.currentTime);\n  });\n\n  on('timeupdate', () => {\n    const t = video.currentTime;\n    store.set({ currentTime: t, buffered: bufferedEnd(video) });\n    events.emit('time', t);\n\n    const duration = video.duration;\n    if (Number.isFinite(duration) && duration > 0) {\n      const pct = (t / duration) * 100;\n      for (const q of QUARTILES) {\n        if (pct >= q && !quartiles.has(q)) {\n          quartiles.add(q);\n          events.emit('quartile', q);\n        }\n      }\n      if (!endReached && t >= endAt()) {\n        endReached = true;\n        if (!video.paused) {\n          suppressPause = true;\n          video.pause();\n        }\n        finish();\n      }\n    }\n  });\n\n  on('progress', () => store.set({ buffered: bufferedEnd(video) }));\n\n  on('volumechange', () => syncVolume(d));\n\n  on('ratechange', () => {\n    if (store.get().rate === video.playbackRate) return;\n    store.set({ rate: video.playbackRate });\n    events.emit('speed', video.playbackRate);\n  });\n\n  on('ended', () => {\n    if (!endReached) finish();\n    else store.set({ status: 'ended' });\n  });\n\n  on('error', () => hooks.onMediaError(mediaErrorToPlayerError(video.error)));\n\n  return () => offs.forEach((off) => off());\n}\n","import type { Logger } from '../types.js';\n\ntype FsDocument = Document & {\n  webkitFullscreenElement?: Element | null;\n  webkitExitFullscreen?: () => void;\n  webkitFullscreenEnabled?: boolean;\n};\ntype FsElement = HTMLElement & { webkitRequestFullscreen?: () => void };\ntype IOSVideo = HTMLVideoElement & {\n  webkitEnterFullscreen?: () => void;\n  webkitExitFullscreen?: () => void;\n};\n\nexport function fullscreenElement(): Element | null {\n  const d = document as FsDocument;\n  return d.fullscreenElement ?? d.webkitFullscreenElement ?? null;\n}\n\n/** Must be called from a user gesture, otherwise browsers reject. */\nexport function enterFullscreen(root: HTMLElement, video: HTMLVideoElement, log: Logger): void {\n  const el = root as FsElement;\n  const d = document as FsDocument;\n  const enabled = d.fullscreenEnabled ?? d.webkitFullscreenEnabled;\n  if (!enabled) {\n    (video as IOSVideo).webkitEnterFullscreen?.();\n  } else if (typeof el.requestFullscreen === 'function') {\n    Promise.resolve(el.requestFullscreen()).catch((e) => log.warn('fullscreen request rejected', e));\n  } else if (typeof el.webkitRequestFullscreen === 'function') {\n    el.webkitRequestFullscreen();\n  } else {\n    (video as IOSVideo).webkitEnterFullscreen?.();\n  }\n}\n\nexport function exitFullscreen(video: HTMLVideoElement): void {\n  const d = document as FsDocument;\n  if (fullscreenElement()) {\n    if (typeof d.exitFullscreen === 'function') Promise.resolve(d.exitFullscreen()).catch(() => {});\n    else d.webkitExitFullscreen?.();\n  } else {\n    (video as IOSVideo).webkitExitFullscreen?.();\n  }\n}\n\nexport function watchFullscreen(root: HTMLElement, video: HTMLVideoElement, onChange: (fs: boolean) => void): () => void {\n  const check = () => onChange(fullscreenElement() === root);\n  const begin = () => onChange(true);\n  const end = () => onChange(false);\n  document.addEventListener('fullscreenchange', check);\n  document.addEventListener('webkitfullscreenchange', check);\n  video.addEventListener('webkitbeginfullscreen', begin);\n  video.addEventListener('webkitendfullscreen', end);\n  return () => {\n    document.removeEventListener('fullscreenchange', check);\n    document.removeEventListener('webkitfullscreenchange', check);\n    video.removeEventListener('webkitbeginfullscreen', begin);\n    video.removeEventListener('webkitendfullscreen', end);\n  };\n}\n","import type { CommandContext } from '../types.js';\nimport type { MediaDeps } from './media-deps.js';\nimport { clamp } from '../shared/clamp.js';\nimport { enterFullscreen, exitFullscreen, watchFullscreen } from './fullscreen.js';\nimport { syncVolume } from './media-events.js';\n\nconst isRelative = (v: number | string): v is string => typeof v === 'string' && /^[+-]/.test(v.trim());\n\nexport function registerMediaCommands(d: MediaDeps): () => void {\n  const { video, store, events, commands, log, root } = d;\n\n  const playSafe = (ctx: CommandContext) => {\n    const p = commands.run('play', [], ctx);\n    if (p) p.catch((e) => log.warn('play() was rejected', e));\n  };\n\n  const offs: Array<() => void> = [\n    commands.register('play', (_args, ctx) => {\n      const p = video.play() ?? Promise.resolve();\n      if (ctx.source === 'user') events.emit('userplay');\n      return p;\n    }),\n\n    commands.register('pause', (_args, ctx) => {\n      video.pause();\n      if (ctx.source === 'user') events.emit('userpause');\n    }),\n\n    commands.register('toggle', (_args, ctx) => {\n      if (store.get().status === 'ended') {\n        video.currentTime = 0;\n        playSafe(ctx);\n      } else if (!video.paused) {\n        commands.run('pause', [], ctx);\n      } else {\n        playSafe(ctx);\n      }\n    }),\n\n    commands.register('stop', () => {\n      video.pause();\n      video.currentTime = 0;\n      events.emit('stop');\n    }),\n\n    commands.register('seek', ([t], ctx) => {\n      if (store.get().live) return;\n      let target = isRelative(t) ? video.currentTime + Number(t) : Number(t);\n      if (!Number.isFinite(target)) return;\n      const duration = video.duration;\n      target = Number.isFinite(duration) ? clamp(target, 0, duration) : Math.max(0, target);\n      video.currentTime = target;\n      store.set({ currentTime: target });\n      if (ctx.source === 'user') events.emit('userseek', target);\n    }),\n\n    commands.register('setVolume', ([v]) => {\n      const raw = isRelative(v) ? video.volume + Number(v) : Number(v);\n      if (!Number.isFinite(raw)) return;\n      const volume = clamp(raw, 0, 1);\n      video.volume = volume;\n      if (volume > 0 && video.muted) video.muted = false;\n      syncVolume(d);\n    }),\n\n    commands.register('mute', () => {\n      video.muted = true;\n      syncVolume(d);\n    }),\n    commands.register('unmute', () => {\n      video.muted = false;\n      syncVolume(d);\n    }),\n    commands.register('toggleMute', () => {\n      video.muted = !video.muted;\n      syncVolume(d);\n    }),\n\n    commands.register('setRate', ([r]) => {\n      if (!(r > 0)) return;\n      const rate = clamp(r, 0.0625, 16);\n      video.defaultPlaybackRate = rate;\n      video.playbackRate = rate;\n    }),\n\n    commands.register('setLoop', ([b]) => {\n      video.loop = b;\n      store.set({ loop: b });\n    }),\n    commands.register('setTitle', ([title]) => store.set({ title })),\n    commands.register('setPoster', ([poster]) => {\n      video.poster = poster;\n      store.set({ poster });\n    }),\n    commands.register('setControlsLocked', ([b]) => store.set({ controlsLocked: b })),\n\n    commands.register('fullscreen', () => enterFullscreen(root, video, log)),\n    commands.register('exitFullscreen', () => exitFullscreen(video)),\n    commands.register('toggleFullscreen', () => {\n      if (store.get().fullscreen) exitFullscreen(video);\n      else enterFullscreen(root, video, log);\n    }),\n\n    watchFullscreen(root, video, (fs) => {\n      if (store.get().fullscreen === fs) return;\n      store.set({ fullscreen: fs });\n      events.emit(fs ? 'fullscreen' : 'exitfullscreen');\n    }),\n  ];\n\n  return () => offs.forEach((off) => off());\n}\n","import type { MediaProvider, PlayerError, ProviderContext, Selection, SourceInput, SourceSpec } from '../types.js';\nimport type { MediaDeps } from './media-deps.js';\nimport { isPlaylistInput, isSourceSpecInput, normalizeSpec, parseSource } from '../source/parse.js';\nimport { toPlayerError } from '../shared/errors.js';\nimport { clamp } from '../shared/clamp.js';\nimport { bindMediaEvents } from './media-events.js';\nimport { registerMediaCommands } from './media-commands.js';\n\nexport interface MediaController {\n  readonly provider: MediaProvider | null;\n  destroy(): void;\n}\n\nexport function createMediaController(d: MediaDeps): MediaController {\n  const { video, store, events, commands, log, options } = d;\n\n  let spec: SourceSpec | null = null;\n  let selection: Selection = { quality: 0, audio: 0, start: 0 };\n  let lastInput: SourceInput | null = null;\n  let provider: MediaProvider | null = null;\n  let providerQualities = false;\n  let providerAudio = false;\n  let token = 0;\n  let attempt = 0;\n  let chain: string[] = [];\n  let chainIndex = 0;\n  let retriesUsed = 0;\n  let pending = false;\n  let retryTimer: ReturnType<typeof setTimeout> | undefined;\n  let reloadStart: number | undefined;\n\n  // Sync initial options/state onto the element.\n  const initial = store.get();\n  video.volume = initial.volume;\n  video.muted = initial.muted;\n  video.loop = initial.loop;\n  video.defaultPlaybackRate = initial.rate;\n  video.playbackRate = initial.rate;\n  if (initial.poster) video.poster = initial.poster;\n\n  const currentTracks = () => spec?.qualities[selection.quality]?.tracks ?? [];\n\n  const reloadOptions = () => options.reload ?? { retries: store.get().live ? 3 : 0, delay: 2000 };\n\n  const playSafe = () => {\n    const p = commands.run('play', []);\n    if (p) p.catch((e) => log.warn('play() was rejected', e));\n  };\n\n  const contextFor = (owner: MediaProvider): ProviderContext => ({\n    setQualities(list, current) {\n      if (provider !== owner || (spec && spec.qualities.length > 1)) return;\n      providerQualities = true;\n      store.set({ qualities: list, quality: clamp(current, 0, Math.max(0, list.length - 1)) });\n    },\n    setAudioTracks(list, current) {\n      if (provider !== owner || currentTracks().length > 1) return;\n      providerAudio = true;\n      store.set({ audioTracks: list, audioTrack: clamp(current, 0, Math.max(0, list.length - 1)) });\n    },\n    error(err) {\n      if (provider === owner) fail(token, attempt, store.get().url, err, video.currentTime, !video.paused);\n    },\n    log,\n    options,\n  });\n\n  const pickProvider = (url: string, s: SourceSpec): MediaProvider | null => {\n    let best: MediaProvider | null = null;\n    let score = 0;\n    for (const p of d.providers) {\n      const value = p.canPlay(url, s);\n      if (value > score) {\n        best = p;\n        score = value;\n      }\n    }\n    return best;\n  };\n\n  const setError = (error: PlayerError) => {\n    store.set({ status: 'error', error });\n    events.emit('error', error);\n  };\n\n  const fail = (t: number, a: number, url: string, error: PlayerError, time: number, resume: boolean) => {\n    if (t !== token || a !== attempt) return;\n    attempt++;\n    pending = false;\n    events.emit('loaderror', { url, error });\n    if (chainIndex < chain.length - 1) {\n      chainIndex++;\n      tryUrl(t, time, resume);\n      return;\n    }\n    const { retries, delay } = reloadOptions();\n    if (retriesUsed < retries) {\n      retriesUsed++;\n      clearTimeout(retryTimer);\n      retryTimer = setTimeout(() => {\n        if (t === token) tryUrl(t, time, resume);\n      }, delay);\n      return;\n    }\n    setError(error);\n  };\n\n  const tryUrl = (t: number, time: number, resume: boolean) => {\n    const url = chain[chainIndex]!;\n    const next = spec ? pickProvider(url, spec) : null;\n    if (!next) {\n      fail(t, attempt, url, { kind: 'unsupported', message: `No provider can play ${url}` }, time, resume);\n      return;\n    }\n    if (next !== provider) {\n      provider?.detach();\n      provider = next;\n      providerQualities = false;\n      providerAudio = false;\n      next.attach(video, contextFor(next));\n    }\n    store.set({ url });\n    pending = true;\n    const a = ++attempt;\n    let loading: Promise<void>;\n    try {\n      loading = next.load(url, time);\n    } catch (e) {\n      loading = Promise.reject(e);\n    }\n    loading.then(\n      () => {\n        if (t !== token || a !== attempt) return;\n        pending = false;\n        retriesUsed = 0;\n        if (store.get().status === 'loading') store.set({ status: 'ready' });\n        events.emit('metadata', { duration: video.duration });\n        if (resume) playSafe();\n      },\n      (err) => fail(t, a, url, toPlayerError(err), time, resume),\n    );\n  };\n\n  const startChain = (time: number, resume: boolean) => {\n    clearTimeout(retryTimer);\n    token++;\n    chain = currentTracks()[selection.audio]?.urls ?? [];\n    chainIndex = 0;\n    retriesUsed = 0;\n    if (!chain.length) {\n      setError({ kind: 'unsupported', message: 'Source has no urls' });\n      return;\n    }\n    tryUrl(token, time, resume);\n  };\n\n  const switchSource = () => {\n    const time = pending ? selection.start : video.currentTime;\n    store.set({ status: 'loading', error: null });\n    startChain(time, !video.paused);\n  };\n\n  const rejectInput = (input: SourceInput, message: string) => {\n    token++;\n    const error: PlayerError = { kind: 'unsupported', message };\n    log.error(message);\n    events.emit('loaderror', { url: typeof input === 'string' ? input : '', error });\n    setError(error);\n  };\n\n  const offs: Array<() => void> = [\n    bindMediaEvents(d, {\n      onMediaError(err) {\n        if (pending || !chain.length || store.get().status === 'error') return;\n        fail(token, attempt, store.get().url, err, video.currentTime, !video.paused);\n      },\n    }),\n    registerMediaCommands(d),\n\n    commands.register('load', ([input]) => {\n      // Rejected input must not replace `lastInput`: reload keeps replaying the last good source.\n      if (isPlaylistInput(input)) {\n        rejectInput(input, 'Playlist input requires the playlist plugin');\n        return;\n      }\n      if (typeof input !== 'string' && !isSourceSpecInput(input)) {\n        rejectInput(input, 'Invalid source: expected a string or an object with a qualities array');\n        return;\n      }\n      const parsed =\n        typeof input === 'string'\n          ? { ...parseSource(input, { qualities: options.qualities, random: d.random }), ...(options.forceType ? { forceType: options.forceType } : {}) }\n          : normalizeSpec(input, options.forceType);\n      if (!parsed.qualities.length) {\n        rejectInput(input, 'Source is empty');\n        return;\n      }\n      lastInput = input;\n\n      let sel: Selection = { quality: parsed.qualities.length - 1, audio: 0, start: parsed.start ?? options.start ?? 0 };\n      for (const transform of [...d.transforms]) {\n        try {\n          sel = { ...transform(parsed, sel) };\n        } catch (e) {\n          log.error('source transform failed', e);\n        }\n      }\n      if (reloadStart !== undefined) {\n        sel.start = reloadStart;\n        reloadStart = undefined;\n      }\n      sel.quality = clamp(Math.round(sel.quality) || 0, 0, parsed.qualities.length - 1);\n      const tracks = parsed.qualities[sel.quality]!.tracks;\n      sel.audio = clamp(Math.round(sel.audio) || 0, 0, tracks.length - 1);\n      sel.start = Math.max(0, Number(sel.start) || 0);\n\n      spec = parsed;\n      selection = sel;\n      providerQualities = false;\n      providerAudio = false;\n      store.set({\n        status: 'loading',\n        started: false,\n        currentTime: 0,\n        duration: 0,\n        buffered: 0,\n        live: false,\n        waiting: false,\n        error: null,\n        url: '',\n        qualities: parsed.qualities.map((q) => ({ label: q.label })),\n        quality: sel.quality,\n        audioTracks: tracks.map((t) => ({ label: t.label })),\n        audioTrack: sel.audio,\n      });\n      events.emit('new', { spec: parsed, selection: sel });\n      startChain(sel.start, false);\n    }),\n\n    commands.register('reload', () => {\n      if (lastInput === null) return;\n      reloadStart = store.get().currentTime || video.currentTime || 0;\n      commands.run('load', [lastInput]);\n      reloadStart = undefined; // consumed by load, or discarded if a before-hook cancelled it\n    }),\n\n    commands.register('setQuality', ([i]) => {\n      const s = store.get();\n      if (!Number.isInteger(i) || i < 0 || i >= s.qualities.length || i === s.quality) return;\n      const label = s.qualities[i]!.label;\n      if (providerQualities) {\n        provider?.setQuality?.(i);\n        store.set({ quality: i });\n        events.emit('quality', label);\n        return;\n      }\n      if (!spec) return;\n      const currentAudio = s.audioTracks[s.audioTrack]?.label;\n      const tracks = spec.qualities[i]!.tracks;\n      const audio = Math.max(0, tracks.findIndex((t) => t.label === currentAudio));\n      selection = { ...selection, quality: i, audio };\n      providerAudio = false;\n      store.set({ quality: i, audioTracks: tracks.map((t) => ({ label: t.label })), audioTrack: audio });\n      switchSource();\n      events.emit('quality', label);\n    }),\n\n    commands.register('setAudioTrack', ([i]) => {\n      const s = store.get();\n      if (!Number.isInteger(i) || i < 0 || i >= s.audioTracks.length || i === s.audioTrack) return;\n      const label = s.audioTracks[i]!.label;\n      if (providerAudio) {\n        provider?.setAudioTrack?.(i);\n        store.set({ audioTrack: i });\n        events.emit('audiotrack', label);\n        return;\n      }\n      if (!spec) return;\n      selection = { ...selection, audio: i };\n      store.set({ audioTrack: i });\n      switchSource();\n      events.emit('audiotrack', label);\n    }),\n  ];\n\n  return {\n    get provider() {\n      return provider;\n    },\n    destroy() {\n      clearTimeout(retryTimer);\n      token++;\n      offs.forEach((off) => off());\n      provider?.detach();\n      provider = null;\n    },\n  };\n}\n","export function extOf(url: string): string {\n  const path = url.split(/[?#]/)[0] ?? '';\n  const match = path.match(/\\.([a-z0-9]+)$/i);\n  return match ? match[1]!.toLowerCase() : '';\n}\n\nexport function resolveUrl(url: string, base: string): string {\n  try {\n    return new URL(url, new URL(base, typeof location !== 'undefined' ? location.href : undefined)).href;\n  } catch {\n    return url;\n  }\n}\n","import type { MediaProvider } from '../types.js';\nimport { extOf } from '../shared/url.js';\nimport { mediaErrorToPlayerError } from '../shared/errors.js';\n\nexport function hasNativeHls(): boolean {\n  if (typeof document === 'undefined') return false;\n  return document.createElement('video').canPlayType('application/vnd.apple.mpegurl') !== '';\n}\n\nexport function html5Provider(): MediaProvider {\n  let video: HTMLVideoElement | null = null;\n  let cancel: (() => void) | null = null;\n\n  return {\n    name: 'html5',\n\n    canPlay(url, spec) {\n      const ext = extOf(url);\n      if (ext === 'm3u8' || spec.forceType === 'hls') return hasNativeHls() ? 1 : 0;\n      if (ext === 'mpd') return 0;\n      return 1;\n    },\n\n    attach(v) {\n      video = v;\n    },\n\n    load(url, startTime) {\n      const v = video;\n      if (!v) return Promise.reject({ kind: 'unknown', message: 'html5 provider is not attached' });\n      cancel?.();\n      return new Promise<void>((resolve, reject) => {\n        const cleanup = () => {\n          v.removeEventListener('loadedmetadata', onMeta);\n          v.removeEventListener('error', onError);\n          cancel = null;\n        };\n        const onMeta = () => {\n          cleanup();\n          if (startTime > 0) v.currentTime = startTime;\n          resolve();\n        };\n        const onError = () => {\n          cleanup();\n          reject(mediaErrorToPlayerError(v.error));\n        };\n        cancel = cleanup;\n        v.addEventListener('loadedmetadata', onMeta);\n        v.addEventListener('error', onError);\n        v.src = url;\n      });\n    },\n\n    detach() {\n      cancel?.();\n      if (video) {\n        video.removeAttribute('src');\n        video.load();\n      }\n      video = null;\n    },\n  };\n}\n","import type { ErrorKind, MediaProvider, PlayerError, ProviderContext, Quality } from '../types.js';\nimport { extOf } from '../shared/url.js';\n\n/** The subset of the hls.js API this provider uses. */\nexport interface HlsInstance {\n  levels: Array<{ height?: number; bitrate: number }>;\n  audioTracks: Array<{ name?: string; lang?: string }>;\n  audioTrack: number;\n  currentLevel: number;\n  loadSource(url: string): void;\n  attachMedia(video: HTMLMediaElement): void;\n  startLoad(): void;\n  recoverMediaError(): void;\n  destroy(): void;\n  on(event: string, cb: (event: string, data: any) => void): void;\n}\nexport interface HlsConstructor {\n  new (config?: Record<string, unknown>): HlsInstance;\n  Events: Record<string, string>;\n  ErrorTypes: Record<string, string>;\n}\n\nexport const DEFAULT_HLS_URL = 'https://cdn.jsdelivr.net/npm/hls.js@1.7.3/dist/hls.min.js';\n/** Subresource Integrity hash of the pinned DEFAULT_HLS_URL bundle. */\nexport const DEFAULT_HLS_INTEGRITY = 'sha384-cciJ0zi8d1uMKC2zJd7jvPY4HQt7W4ByUI/FlMkltvBi31aW61rcpVBhpmW8/NwX';\n\nlet pending: Promise<HlsConstructor> | null = null;\n\n/** Loads the hls.js UMD bundle once (or reuses a page-provided window.Hls). */\nexport function loadHlsScript(src: string, integrity?: string): Promise<HlsConstructor> {\n  const w = window as unknown as { Hls?: HlsConstructor };\n  if (w.Hls) return Promise.resolve(w.Hls);\n  if (pending) return pending;\n  const loading = new Promise<HlsConstructor>((resolve, reject) => {\n    const script = document.createElement('script');\n    script.src = src;\n    script.async = true;\n    if (integrity) {\n      script.integrity = integrity;\n      script.crossOrigin = 'anonymous';\n    }\n    script.addEventListener('load', () => (w.Hls ? resolve(w.Hls) : reject(new Error(`${src} did not define window.Hls`))));\n    script.addEventListener('error', () => {\n      script.remove();\n      reject(new Error(`failed to load ${src}`));\n    });\n    document.head.append(script);\n  });\n  pending = loading;\n  loading.catch(() => {\n    if (pending === loading) pending = null;\n  });\n  return loading;\n}\n\n/** Test helper: forget a cached loader promise. */\nexport function resetHlsLoader(): void {\n  pending = null;\n}\n\nfunction levelLabels(levels: HlsInstance['levels']): Quality[] {\n  const base = levels.map((l) => (l.height ? `${l.height}p` : `${Math.round(l.bitrate / 1000)}kbps`));\n  return levels.map((l, i) => {\n    const duplicate = base.filter((b) => b === base[i]).length > 1;\n    const label = duplicate && l.height ? `${base[i]} ${Math.round(l.bitrate / 1000)}kbps` : base[i]!;\n    return { label, height: l.height, bitrate: l.bitrate };\n  });\n}\n\nexport interface HlsProviderOptions {\n  /** Override how the hls.js constructor is obtained (tests, bundlers). */\n  loader?: (src: string, integrity?: string) => Promise<HlsConstructor>;\n}\n\nexport function hlsProvider(o: HlsProviderOptions = {}): MediaProvider {\n  let video: HTMLVideoElement | null = null;\n  let ctx: ProviderContext | null = null;\n  let hls: HlsInstance | null = null;\n  let cleanupLoad: (() => void) | null = null;\n  let loadId = 0;\n\n  const destroyHls = () => {\n    cleanupLoad?.();\n    hls?.destroy();\n    hls = null;\n  };\n\n  return {\n    name: 'hls',\n\n    /**\n     * Prefer hls.js wherever MSE exists (desktop Chrome now reports native HLS but exposes no\n     * renditions, so there would be no quality menu). Without MSE (iPhone) html5 plays natively.\n     */\n    canPlay(url, spec) {\n      const isHls = extOf(url) === 'm3u8' || spec.forceType === 'hls';\n      if (!isHls) return 0;\n      return typeof window !== 'undefined' && 'MediaSource' in window ? 2 : 0;\n    },\n\n    attach(v, c) {\n      video = v;\n      ctx = c;\n    },\n\n    async load(url, startTime) {\n      const c = ctx;\n      const id = ++loadId;\n      if (!video || !c) throw { kind: 'unknown', message: 'hls provider is not attached' } satisfies PlayerError;\n      let Hls: HlsConstructor;\n      try {\n        const { hlsUrl, hlsIntegrity } = c.options;\n        Hls = await (o.loader ?? loadHlsScript)(hlsUrl ?? DEFAULT_HLS_URL, hlsUrl ? hlsIntegrity : (hlsIntegrity ?? DEFAULT_HLS_INTEGRITY));\n      } catch (e) {\n        throw { kind: 'unsupported', message: `hls.js failed to load: ${String(e)}` } satisfies PlayerError;\n      }\n      if (id !== loadId) throw { kind: 'unknown', message: 'superseded' } satisfies PlayerError;\n      const media = video;\n      if (!media) throw { kind: 'unknown', message: 'hls provider was detached' } satisfies PlayerError;\n      destroyHls();\n      // A user-provided startPosition wins unless the player asks for a specific start time.\n      const instance = new Hls({ startPosition: -1, ...(c.options.hlsConfig ?? {}), ...(startTime > 0 ? { startPosition: startTime } : {}) });\n      hls = instance;\n\n      return new Promise<void>((resolve, reject) => {\n        let state: 'loading' | 'loaded' | 'failed' = 'loading';\n        let networkRetried = false;\n        let mediaRetried = false;\n\n        const onMeta = () => {\n          if (state !== 'loading') return;\n          state = 'loaded';\n          cleanupLoad?.();\n          resolve();\n        };\n        media.addEventListener('loadedmetadata', onMeta);\n        cleanupLoad = () => {\n          media.removeEventListener('loadedmetadata', onMeta);\n          cleanupLoad = null;\n        };\n\n        const publishAudio = () => {\n          if (instance.audioTracks.length > 1) {\n            c.setAudioTracks(\n              instance.audioTracks.map((t, i) => ({ label: t.name || t.lang || String(i + 1), lang: t.lang })),\n              Math.max(0, instance.audioTrack),\n            );\n          }\n        };\n\n        instance.on(Hls.Events.MANIFEST_PARSED!, () => {\n          if (instance.levels.length > 1) c.setQualities([{ label: 'auto' }, ...levelLabels(instance.levels)], 0);\n          publishAudio();\n        });\n        if (Hls.Events.AUDIO_TRACKS_UPDATED) instance.on(Hls.Events.AUDIO_TRACKS_UPDATED, publishAudio);\n\n        instance.on(Hls.Events.ERROR!, (_event, data: { fatal?: boolean; type?: string; details?: string; response?: { code?: number } }) => {\n          if (!data.fatal || state === 'failed') return;\n          const isNetwork = data.type === Hls.ErrorTypes.NETWORK_ERROR;\n          const isMedia = data.type === Hls.ErrorTypes.MEDIA_ERROR;\n          // After metadata, try hls.js recovery once per kind. Before it, hls.js has already\n          // exhausted its own retries, so retrying here could hang the load forever.\n          if (state === 'loaded') {\n            if (isNetwork && !networkRetried) {\n              networkRetried = true;\n              instance.startLoad();\n              return;\n            }\n            if (isMedia && !mediaRetried) {\n              mediaRetried = true;\n              instance.recoverMediaError();\n              return;\n            }\n          }\n          const kind: ErrorKind = data.response?.code === 404 ? 'not-found' : isNetwork ? 'network' : isMedia ? 'decode' : 'unknown';\n          const error: PlayerError = { kind, message: data.details ?? 'hls.js error' };\n          if (state === 'loading') {\n            state = 'failed';\n            cleanupLoad?.();\n            reject(error);\n          } else {\n            c.error(error);\n          }\n        });\n\n        instance.loadSource(url);\n        instance.attachMedia(media);\n      });\n    },\n\n    detach() {\n      loadId++;\n      destroyHls();\n      video = null;\n    },\n\n    setQuality(index) {\n      if (hls) hls.currentLevel = index === 0 ? -1 : index - 1;\n    },\n\n    setAudioTrack(index) {\n      if (hls) hls.audioTrack = index;\n    },\n  };\n}\n","import type { CommandContext, CommandRegistry, EventBus, Logger, Player, PlayerOptions, PlayerState, Store } from '../types.js';\n\nexport interface ApiContext {\n  player: Player;\n  store: Store<PlayerState>;\n  commands: CommandRegistry;\n  events: EventBus;\n  options: PlayerOptions;\n  log: Logger;\n}\n\ntype ApiHandler = (arg: unknown) => unknown;\nconst API: CommandContext = { source: 'api' };\nconst NONE = Symbol('none');\n\nconst isRelative = (v: unknown) => typeof v === 'string' && /^[+-]/.test(v.trim());\nconst toNumber = (v: unknown) => (typeof v === 'number' ? v : Number(v));\nconst flag = (v: unknown) => v === true || v === 1 || v === '1' || v === 'true' || v === 'on';\nconst bit = (v: unknown) => (v ? 1 : 0);\nconst SUBTITLE_RE = /^\\[([^\\]]*)\\](.+)$/;\n\nexport function createApi(ctx: ApiContext): (cmd: string, arg?: unknown) => unknown {\n  const { store, commands, events, log, player } = ctx;\n  const state = () => store.get() as PlayerState & Record<string, unknown>;\n\n  /** Runs any command by name (plugin commands are not known to the type system here). */\n  const run = (name: string, ...args: unknown[]): unknown => {\n    if (!commands.has(name)) {\n      log.warn(`api: command \"${name}\" is not available`);\n      return undefined;\n    }\n    const result = (commands.run as unknown as (n: string, a: unknown[], c: CommandContext) => unknown)(name, args, API);\n    if (result instanceof Promise) result.catch((e) => log.warn(`api: \"${name}\" rejected`, e));\n    return undefined;\n  };\n\n  /**\n   * Spec §3.4: run `load`, then play on the first `metadata` that follows the load's own `new`.\n   * Listeners are registered *before* loading and count `new` events, so a load that a before-hook\n   * intercepts (the playlist plugin loads its first item asynchronously) still plays. Cancelled by a\n   * second `new` (another load), an `error`, or a `loaderror` before any `new` (e.g. a broken playlist).\n   */\n  const loadThenPlay = (load: () => void) => {\n    let loads = 0;\n    const offs: Array<() => void> = [];\n    const cleanup = () => offs.forEach((off) => off());\n    offs.push(\n      events.on('new', () => {\n        if (++loads > 1) cleanup();\n      }),\n      events.on('metadata', () => {\n        if (loads === 0) return;\n        cleanup();\n        run('play');\n      }),\n      events.on('error', cleanup),\n      events.on('loaderror', () => {\n        if (loads === 0) cleanup();\n      }),\n    );\n    load();\n  };\n\n  // getter when arg is NONE, setter/action otherwise\n  const table: Record<string, (arg: unknown) => unknown> = {\n    play: (arg) => {\n      if (arg === NONE) return run('play');\n      if (typeof arg === 'string' && arg.startsWith('id:')) return run('playItem', arg.slice(3), true);\n      loadThenPlay(() => run('load', arg));\n      return undefined;\n    },\n    pause: () => run('pause'),\n    toggle: () => run('toggle'),\n    stop: () => run('stop'),\n    seek: (arg) => (arg === NONE ? undefined : run('seek', isRelative(arg) ? String(arg).trim() : toNumber(arg))),\n    time: () => state().currentTime,\n    duration: () => state().duration,\n    buffered: () => state().buffered,\n    playing: () => state().status === 'playing',\n    started: () => state().started,\n    live: () => state().live,\n    muted: () => state().muted,\n    isfullscreen: () => state().fullscreen,\n    volume: (arg) => (arg === NONE ? state().volume : run('setVolume', isRelative(arg) ? String(arg).trim() : toNumber(arg))),\n    mute: () => run('mute'),\n    unmute: () => run('unmute'),\n    fullscreen: () => run('fullscreen'),\n    exitfullscreen: () => run('exitFullscreen'),\n    quality: (arg) => (arg === NONE ? state().qualities[state().quality]?.label : run('setQuality', toNumber(arg))),\n    qualities: () => state().qualities.map((q) => q.label),\n    audiotrack: (arg) => {\n      if (arg === NONE) return state().audioTracks[state().audioTrack]?.label;\n      const byLabel = state().audioTracks.findIndex((t) => t.label === arg);\n      return run('setAudioTrack', byLabel >= 0 ? byLabel : toNumber(arg));\n    },\n    audiotracks: () => state().audioTracks.map((t) => t.label),\n    speed: (arg) => (arg === NONE ? state().rate : run('setSpeedIndex', toNumber(arg))),\n    subtitle: (arg) => {\n      if (arg === NONE) return state().textTracks[state().textTrack]?.label ?? 'off';\n      const m = typeof arg === 'string' ? arg.match(SUBTITLE_RE) : null;\n      if (m) return run('addSubtitle', m[1], m[2], true);\n      if (arg === 'off') return run('setTextTrack', -1);\n      const byLabel = state().textTracks.findIndex((t) => t.label === arg);\n      return run('setTextTrack', byLabel >= 0 ? byLabel : toNumber(arg));\n    },\n    subtitles: () => state().textTracks.map((t) => t.label),\n    '+subtitle': (arg) => {\n      const m = typeof arg === 'string' ? arg.match(SUBTITLE_RE) : null;\n      return m ? run('addSubtitle', m[1], m[2], false) : undefined;\n    },\n    togglesubs: () => run('toggleSubtitles'),\n    file: (arg) => (arg === NONE ? state().url : run('load', arg)),\n    preload: (arg) => {\n      if (arg === NONE) return undefined;\n      player.video.preload = 'auto';\n      return run('load', arg);\n    },\n    playlist: (arg) => (arg === NONE ? (state().playlist as { items?: unknown } | undefined)?.items : run('setPlaylist', arg)),\n    next: () => run('next'),\n    prev: () => run('prev'),\n    find: (arg) => (arg === NONE ? undefined : run('playItem', String(arg), false)),\n    push: (arg) => (arg === NONE ? undefined : run('push', arg)),\n    autonext: (arg) => (arg === NONE ? bit(state().autonext) : run('setAutonext', flag(arg))),\n    playlistloop: (arg) => (arg === NONE ? bit(state().playlistLoop) : run('setPlaylistLoop', flag(arg))),\n    loop: (arg) => (arg === NONE ? bit(state().loop) : run('setLoop', flag(arg))),\n    title: (arg) => (arg === NONE ? state().title : run('setTitle', String(arg))),\n    poster: (arg) => (arg === NONE ? state().poster : run('setPoster', String(arg))),\n    thumbnails: (arg) => (arg === NONE ? undefined : run('setThumbnails', String(arg))),\n    toolbar: (arg) => (arg === NONE ? run('showControls') : run('setControlsLocked', arg === 'on' || arg === 1 || arg === true)),\n    menu: () => run('toggleMenu'),\n    cuid: (arg) => (arg === NONE ? state().cuid : run('setCuid', String(arg))),\n    id: () => player.id,\n    destroy: () => run('destroy'),\n  };\n\n  return (cmd, arg = NONE) => {\n    const handler: ApiHandler | undefined = Object.prototype.hasOwnProperty.call(table, cmd) ? table[cmd] : undefined;\n    if (!handler) {\n      log.warn(`api: unknown command \"${cmd}\"`);\n      return undefined;\n    }\n    return handler(arg);\n  };\n}\n","export type Attrs = Record<string, string | number | boolean | null | undefined>;\nexport type Child = Node | string | null | undefined | false;\n\nconst SVG_NS = 'http://www.w3.org/2000/svg';\n\nexport function h<K extends keyof HTMLElementTagNameMap>(tag: K, attrs: Attrs = {}, ...children: Child[]): HTMLElementTagNameMap[K] {\n  const el = document.createElement(tag);\n  for (const [key, value] of Object.entries(attrs)) {\n    if (value === undefined || value === null || value === false) continue;\n    if (key === 'class') el.className = String(value);\n    else el.setAttribute(key, value === true ? '' : String(value));\n  }\n  for (const child of children) if (child !== null && child !== undefined && child !== false) el.append(child);\n  return el;\n}\n\nconst ALLOWED_ELEMENTS = new Set([\n  'svg', 'g', 'path', 'circle', 'ellipse', 'rect', 'line', 'polyline', 'polygon', 'defs',\n  'linearGradient', 'radialGradient', 'stop', 'clipPath', 'mask', 'symbol', 'title', 'desc',\n]);\n\nfunction sanitizeAttributes(el: Element): void {\n  for (const attr of [...el.attributes]) {\n    const name = attr.localName.toLowerCase();\n    const unsafe =\n      name.startsWith('on') ||\n      name === 'href' ||\n      (name === 'style' && /url\\(/i.test(attr.value)) ||\n      /^javascript:/i.test(attr.value.replace(/[\\u0000- ]/g, ''));\n    if (unsafe) el.removeAttributeNode(attr);\n  }\n}\n\n/** Allowlist sanitizer: keeps only known SVG-namespace elements and strips dangerous attributes. */\nfunction sanitizeSvg(el: Element): void {\n  for (const child of [...el.children]) {\n    if (child.namespaceURI !== SVG_NS || !ALLOWED_ELEMENTS.has(child.localName)) child.remove();\n    else sanitizeSvg(child);\n  }\n  sanitizeAttributes(el);\n}\n\n/** Parses an SVG string (never as HTML) and returns it wrapped in a `.vp-icon` span. */\nexport function parseSvg(markup: string): SVGElement | null {\n  const source = /xmlns\\s*=/.test(markup) ? markup : markup.replace(/<svg\\b/, `<svg xmlns=\"${SVG_NS}\"`);\n  let doc: Document;\n  try {\n    doc = new DOMParser().parseFromString(source, 'image/svg+xml');\n  } catch {\n    return null;\n  }\n  const root = doc.documentElement;\n  if (!root || root.namespaceURI !== SVG_NS || root.localName !== 'svg' || doc.getElementsByTagName('parsererror').length) return null;\n  sanitizeSvg(root);\n  return document.importNode(root, true) as unknown as SVGElement;\n}\n\nexport function iconEl(markup: string): HTMLSpanElement {\n  const span = h('span', { class: 'vp-icon', 'aria-hidden': 'true' });\n  const svg = parseSvg(markup);\n  if (svg) span.append(svg);\n  return span;\n}\n","import type { Logger } from '../types.js';\n\nexport interface Registry<T> {\n  register(name: string, item: T): void;\n  get(name: string): T | undefined;\n  has(name: string): boolean;\n}\n\nexport function createRegistry<T>(kind: string, log: Logger): Registry<T> {\n  const items = new Map<string, T>();\n  return {\n    register(name, item) {\n      if (items.has(name)) log.warn(`${kind} \"${name}\" replaced`);\n      items.set(name, item);\n    },\n    get: (name) => items.get(name),\n    has: (name) => items.has(name),\n  };\n}\n","import type { HideRuleFactory, HideRuleSpec, Logger, PlayerState, UIContext } from '../types.js';\nimport type { Registry } from './registry.js';\n\nconst simple = (test: (s: PlayerState) => boolean): HideRuleFactory => () => ({ test });\n\nexport function registerBuiltinHideRules(reg: Registry<HideRuleFactory>): void {\n  reg.register('idle', simple((s) => !s.userActive && s.status === 'playing' && !s.controlsLocked));\n  reg.register('paused', simple((s) => s.status === 'paused'));\n  reg.register('playing', simple((s) => s.status === 'playing'));\n  reg.register('not-started', simple((s) => !s.started));\n  reg.register('started', simple((s) => s.started));\n  reg.register('fullscreen', simple((s) => s.fullscreen));\n  reg.register('not-fullscreen', simple((s) => !s.fullscreen));\n  reg.register('not-waiting', simple((s) => !s.waiting));\n  reg.register('live', simple((s) => s.live));\n  reg.register('not-live', simple((s) => !s.live));\n  reg.register('error', simple((s) => s.status === 'error'));\n  reg.register('not-error', simple((s) => s.status !== 'error'));\n  reg.register('minWidth', (arg) => {\n    const n = Number(arg);\n    return { test: (s) => s.width >= n };\n  });\n  reg.register('maxWidth', (arg) => {\n    const n = Number(arg);\n    return { test: (s) => s.width < n };\n  });\n  reg.register('no-menus', (_arg, ctx) => ({ test: (s) => !ctx.menus.hasVisible(s) }));\n  reg.register('command', (arg, ctx) => {\n    const name = String(arg);\n    return { test: () => !ctx.commands.has(name) };\n  });\n}\n\n/** Compiles hide specs into one predicate: hidden when ANY rule is true. */\nexport function compileHide(specs: HideRuleSpec[], reg: Registry<HideRuleFactory>, ctx: UIContext, log: Logger): (s: PlayerState) => boolean {\n  const tests = specs.map((spec) => {\n    const [name, arg] = typeof spec === 'string' ? [spec, undefined] : (Object.entries(spec)[0] ?? ['', undefined]);\n    const factory = reg.get(name);\n    if (!factory) {\n      log.warn(`unknown hide rule \"${name}\"`);\n      return () => false;\n    }\n    return factory(arg, ctx).test;\n  });\n  return (s) => tests.some((test) => test(s));\n}\n","export type Dictionary = Record<string, string>;\n\nexport const dictionaries: Record<'ru' | 'en', Dictionary> = {\n  ru: {\n    play: 'Воспроизвести',\n    pause: 'Пауза',\n    replay: 'Повторить',\n    mute: 'Выключить звук',\n    unmute: 'Включить звук',\n    volume: 'Громкость',\n    fullscreen: 'Полный экран',\n    exitFullscreen: 'Выйти из полноэкранного режима',\n    settings: 'Настройки',\n    playlist: 'Плейлист',\n    prev: 'Предыдущий',\n    next: 'Следующий',\n    timeline: 'Перемотка',\n    quality: 'Качество',\n    speed: 'Скорость',\n    subtitles: 'Субтитры',\n    audio: 'Аудио',\n    off: 'Выкл',\n    auto: 'Авто',\n    normal: 'Обычная',\n    back: 'Назад',\n    live: 'LIVE',\n    retry: 'Повторить',\n    close: 'Закрыть',\n    buffering: 'Загрузка',\n    'error.network': 'Ошибка сети',\n    'error.decode': 'Не удалось декодировать видео',\n    'error.not-found': 'Видео не найдено',\n    'error.unsupported': 'Формат не поддерживается',\n    'error.unknown': 'Ошибка воспроизведения',\n  },\n  en: {\n    play: 'Play',\n    pause: 'Pause',\n    replay: 'Replay',\n    mute: 'Mute',\n    unmute: 'Unmute',\n    volume: 'Volume',\n    fullscreen: 'Fullscreen',\n    exitFullscreen: 'Exit fullscreen',\n    settings: 'Settings',\n    playlist: 'Playlist',\n    prev: 'Previous',\n    next: 'Next',\n    timeline: 'Seek',\n    quality: 'Quality',\n    speed: 'Speed',\n    subtitles: 'Subtitles',\n    audio: 'Audio',\n    off: 'Off',\n    auto: 'Auto',\n    normal: 'Normal',\n    back: 'Back',\n    live: 'LIVE',\n    retry: 'Retry',\n    close: 'Close',\n    buffering: 'Loading',\n    'error.network': 'Network error',\n    'error.decode': 'The video could not be decoded',\n    'error.not-found': 'Video not found',\n    'error.unsupported': 'Format not supported',\n    'error.unknown': 'Playback error',\n  },\n};\n\nexport function createTranslator(lang: 'ru' | 'en' = 'en', overrides: Partial<Dictionary> = {}): (key: string) => string {\n  const dict: Dictionary = { ...(dictionaries[lang] ?? dictionaries.en) };\n  for (const [k, v] of Object.entries(overrides)) if (v !== undefined) dict[k] = v;\n  return (key) => (Object.prototype.hasOwnProperty.call(dict, key) ? (dict[key] as string) : key);\n}\n","import type { IconName } from '../types.js';\n\nconst svg = (path: string) => `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" focusable=\"false\">${path}</svg>`;\n\nexport const defaultIcons: Record<IconName, string> = {\n  play: svg('<path d=\"M8 5v14l11-7z\"/>'),\n  pause: svg('<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>'),\n  replay: svg('<path d=\"M12 5V1L7 6l5 5V7a6 6 0 1 1-6 6H4a8 8 0 1 0 8-8z\"/>'),\n  'volume-high': svg('<path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3A4.5 4.5 0 0 0 14 8v8a4.5 4.5 0 0 0 2.5-4zM14 3.2v2.1a7 7 0 0 1 0 13.4v2.1a9 9 0 0 0 0-17.6z\"/>'),\n  'volume-low': svg('<path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3A4.5 4.5 0 0 0 14 8v8a4.5 4.5 0 0 0 2.5-4z\"/>'),\n  'volume-mute': svg('<path d=\"M3 9v6h4l5 5V4L7 9H3zm13.6 3 2.7-2.7-1.4-1.4-2.7 2.7-2.7-2.7-1.4 1.4 2.7 2.7-2.7 2.7 1.4 1.4 2.7-2.7 2.7 2.7 1.4-1.4z\"/>'),\n  fullscreen: svg('<path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\"/>'),\n  'fullscreen-exit': svg('<path d=\"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z\"/>'),\n  settings: svg('<path d=\"M19.4 13a7.5 7.5 0 0 0 0-2l2.1-1.6-2-3.5-2.5 1a7.3 7.3 0 0 0-1.7-1L15 3.3h-4l-.4 2.6a7.3 7.3 0 0 0-1.7 1l-2.5-1-2 3.5L6.6 11a7.5 7.5 0 0 0 0 2l-2.1 1.6 2 3.5 2.5-1c.5.4 1.1.7 1.7 1l.4 2.6h4l.4-2.6c.6-.3 1.2-.6 1.7-1l2.5 1 2-3.5zM12 15.5a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7z\"/>'),\n  playlist: svg('<path d=\"M3 6h12v2H3zm0 5h12v2H3zm0 5h8v2H3zm14-5v6l5-3z\"/>'),\n  prev: svg('<path d=\"M6 6h2v12H6zm3.5 6 8.5 6V6z\"/>'),\n  next: svg('<path d=\"M16 6h2v12h-2zM6 18l8.5-6L6 6z\"/>'),\n  check: svg('<path d=\"M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z\"/>'),\n  back: svg('<path d=\"M15.4 7.4 14 6l-6 6 6 6 1.4-1.4L10.8 12z\"/>'),\n};\n\nexport function createIconSet(overrides: Partial<Record<IconName, string>> = {}): (name: IconName) => string {\n  return (name) => overrides[name] ?? defaultIcons[name];\n}\n","import type { EventBus, IconName, Logger, MenuDefinition, MenuHost, PlayerState, Store } from '../types.js';\nimport { h, iconEl } from './dom.js';\n\nexport interface MenuHostDeps {\n  layer: HTMLElement;\n  store: Store<PlayerState>;\n  events: EventBus;\n  t: (key: string) => string;\n  icon: (name: IconName) => string;\n  log: Logger;\n}\n\ntype OpenOptions = { only?: string[]; align?: 'left' | 'center' | 'right' };\n\nexport function createMenuHost(d: MenuHostDeps): MenuHost {\n  const defs: MenuDefinition[] = [];\n  let panel: HTMLElement | null = null;\n  let opts: OpenOptions = {};\n  let view: string | null = null;\n  let unsubscribe: (() => void) | null = null;\n  let previousFocus: HTMLElement | null = null;\n\n  const visibleDefs = (s: PlayerState) =>\n    defs\n      .filter((def) => (!opts.only || opts.only.includes(def.id)) && def.visible(s))\n      .sort((a, b) => (a.order ?? 100) - (b.order ?? 100));\n\n  const currentLabel = (def: MenuDefinition, s: PlayerState) => {\n    const cur = def.current(s);\n    return def.options(s).find((o) => Object.is(o.value, cur))?.label ?? '';\n  };\n\n  const signature = (s: PlayerState) =>\n    visibleDefs(s)\n      .map((def) => `${def.id}:${currentLabel(def, s)}:${def.options(s).map((o) => o.label).join(',')}`)\n      .join('|');\n\n  const focusFirst = () => panel?.querySelector<HTMLButtonElement>('button')?.focus();\n\n  const button = (cls: string, onClick: () => void, ...children: Array<Node | string>) => {\n    const b = h('button', { class: cls, type: 'button' }, ...children);\n    b.addEventListener('click', (e) => {\n      e.stopPropagation();\n      onClick();\n    });\n    return b;\n  };\n\n  const render = () => {\n    if (!panel) return;\n    const s = d.store.get();\n    const list = visibleDefs(s);\n    if (!list.length) {\n      host.close();\n      return;\n    }\n    if (view === null && list.length === 1) view = list[0]!.id;\n    const def = view ? list.find((x) => x.id === view) : undefined;\n    if (view && !def) view = null;\n\n    // Re-rendering replaces the buttons: remember which one had focus so keyboard users keep their place.\n    const hadFocus = panel.contains(document.activeElement);\n    const focusIndex = hadFocus ? [...panel.querySelectorAll('button')].indexOf(document.activeElement as HTMLButtonElement) : -1;\n\n    panel.replaceChildren();\n    if (def) {\n      if (list.length > 1) {\n        panel.append(\n          button(\n            'vp-menu-back',\n            () => {\n              view = null;\n              render();\n              focusFirst();\n            },\n            iconEl(d.icon('back')),\n            h('span', {}, d.t(def.label)),\n          ),\n        );\n      } else {\n        panel.append(h('div', { class: 'vp-menu-title' }, d.t(def.label)));\n      }\n      const cur = def.current(s);\n      for (const option of def.options(s)) {\n        const active = Object.is(option.value, cur);\n        const item = button(\n          `vp-menu-item${active ? ' vp-active' : ''}`,\n          () => {\n            def.select(option.value);\n            host.close();\n          },\n          h('span', { class: 'vp-menu-check' }, active ? iconEl(d.icon('check')) : ''),\n          h('span', { class: 'vp-menu-label' }, option.label),\n        );\n        item.setAttribute('role', 'menuitemradio');\n        item.setAttribute('aria-checked', String(active));\n        panel.append(item);\n      }\n    } else {\n      for (const x of list) {\n        const item = button(\n          'vp-menu-item vp-menu-main',\n          () => {\n            view = x.id;\n            render();\n            focusFirst();\n          },\n          h('span', { class: 'vp-menu-label' }, d.t(x.label)),\n          h('span', { class: 'vp-menu-value' }, currentLabel(x, s)),\n        );\n        item.setAttribute('role', 'menuitem');\n        panel.append(item);\n      }\n    }\n\n    if (hadFocus) {\n      const buttons = panel.querySelectorAll<HTMLButtonElement>('button');\n      buttons[Math.max(0, Math.min(focusIndex, buttons.length - 1))]?.focus();\n    }\n  };\n\n  let cancelSwallow: (() => void) | null = null;\n\n  /** Eats the click that completes a dismissing press, so it doesn't also hit the player (e.g. toggle playback). */\n  const swallowNextClick = () => {\n    cancelSwallow?.();\n    const onClick = (e: Event) => {\n      e.stopPropagation();\n      e.preventDefault();\n      cancelSwallow?.();\n    };\n    const timer = setTimeout(() => cancelSwallow?.(), 600);\n    cancelSwallow = () => {\n      clearTimeout(timer);\n      document.removeEventListener('click', onClick, true);\n      document.removeEventListener('pointerdown', cancelSwallow!, true);\n      cancelSwallow = null;\n    };\n    document.addEventListener('click', onClick, true);\n    document.addEventListener('pointerdown', cancelSwallow, true);\n  };\n\n  const onOutside = (e: Event) => {\n    const target = e.target as Element | null;\n    if (!panel || (target && (panel.contains(target) || target.closest?.('[data-vp-menu-toggle]')))) return;\n    const playerRoot = d.layer.closest('.vp-root') ?? d.layer.parentElement;\n    const inPlayer = !!(target && playerRoot?.contains(target));\n    host.close();\n    if (inPlayer) swallowNextClick();\n  };\n\n  const onKey = (e: KeyboardEvent) => {\n    if (!panel) return;\n    const buttons = [...panel.querySelectorAll<HTMLButtonElement>('button')];\n    const index = buttons.indexOf(document.activeElement as HTMLButtonElement);\n    if (e.key === 'Escape') {\n      host.close();\n    } else if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n      const step = e.key === 'ArrowDown' ? 1 : -1;\n      const next = index < 0 ? (step > 0 ? 0 : buttons.length - 1) : (index + step + buttons.length) % buttons.length;\n      buttons[next]?.focus();\n    } else if (e.key === 'ArrowLeft') {\n      panel.querySelector<HTMLButtonElement>('.vp-menu-back')?.click();\n    } else if (e.key !== 'ArrowRight') {\n      return;\n    }\n    // Handled (ArrowRight is swallowed): keep player hotkeys from also seeking/changing volume.\n    e.preventDefault();\n    e.stopPropagation();\n  };\n\n  const host: MenuHost = {\n    register(def) {\n      defs.push(def);\n      if (panel) render();\n      return () => {\n        const i = defs.indexOf(def);\n        if (i >= 0) defs.splice(i, 1);\n        if (panel) render();\n      };\n    },\n\n    open(o = {}) {\n      if (panel) host.close();\n      opts = o;\n      if (!visibleDefs(d.store.get()).length) return;\n      view = null;\n      previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n      panel = h('div', { class: `vp-menu vp-menu-${o.align ?? 'right'}`, role: 'menu' });\n      d.layer.append(panel);\n      render();\n      if (!panel) return;\n      unsubscribe = d.store.select(signature, render);\n      document.addEventListener('pointerdown', onOutside, true);\n      panel.addEventListener('keydown', onKey);\n      d.events.emit('ui:menu', { open: true });\n      focusFirst();\n    },\n\n    close() {\n      if (!panel) return;\n      const hadFocus = panel.contains(document.activeElement);\n      panel.removeEventListener('keydown', onKey);\n      panel.remove();\n      panel = null;\n      unsubscribe?.();\n      unsubscribe = null;\n      document.removeEventListener('pointerdown', onOutside, true);\n      d.events.emit('ui:menu', { open: false });\n      if (hadFocus && previousFocus?.isConnected) previousFocus.focus();\n      previousFocus = null;\n    },\n\n    toggle() {\n      if (panel) host.close();\n      else host.open();\n    },\n\n    get isOpen() {\n      return panel !== null;\n    },\n\n    hasVisible: (s) => defs.some((def) => def.visible(s)),\n\n    dispose() {\n      host.close();\n      cancelSwallow?.();\n      defs.length = 0;\n    },\n  };\n  return host;\n}\n","import type { Logger, MenuHost, Player, PlayerState, Store } from '../types.js';\n\nexport type Align = 'left' | 'center' | 'right';\nexport type Action =\n  | { type: 'api'; name: string; args: string[] }\n  | { type: 'js'; fn: string; args: string[] }\n  | { type: 'event'; name: string }\n  | { type: 'settings'; only: string[]; align: Align | undefined }\n  | { type: 'url'; url: string };\n\nconst ALIGNS: readonly string[] = ['left', 'center', 'right'];\nconst PATH_RE = /^[A-Za-z_$][\\w$]*(\\.[A-Za-z_$][\\w$]*)*$/;\nconst BLOCKED_SEGMENTS = new Set(['eval', 'Function', 'setTimeout', 'setInterval', 'execScript', 'constructor', '__proto__', 'prototype']);\nconst trimAll = (parts: string[]) => parts.map((p) => p.trim());\n\nexport function parseAction(input: string): Action[] {\n  const s = input.trim();\n  if (s.startsWith('api:')) {\n    return s\n      .slice(4)\n      .split(';')\n      .map((p) => p.trim())\n      .filter(Boolean)\n      .map((part) => {\n        const [name = '', ...args] = trimAll(part.split(','));\n        return { type: 'api' as const, name, args };\n      });\n  }\n  if (s.startsWith('js:')) {\n    const [fn = '', ...args] = trimAll(s.slice(3).split(','));\n    return [{ type: 'js', fn, args }];\n  }\n  if (s.startsWith('event:')) return [{ type: 'event', name: s.slice(6).trim() }];\n  if (s === 'settings' || s.startsWith('settings:')) {\n    const parts = trimAll(s.slice(9).split(',')).filter(Boolean);\n    const align = parts.find((p) => ALIGNS.includes(p)) as Align | undefined;\n    return [{ type: 'settings', only: parts.filter((p) => p !== align), align }];\n  }\n  if (/^(https?:)?\\/\\//.test(s)) return [{ type: 'url', url: s }];\n  return [];\n}\n\nexport interface ActionRunnerDeps {\n  player: Player;\n  store: Store<PlayerState>;\n  menus: MenuHost;\n  log: Logger;\n}\n\nfunction resolveGlobal(path: string): { fn: unknown; self: unknown } {\n  let self: unknown = window;\n  let value: unknown = window;\n  for (const key of path.split('.')) {\n    self = value;\n    value = value == null ? undefined : (value as Record<string, unknown>)[key];\n  }\n  return { fn: value, self };\n}\n\nexport function createActionRunner(d: ActionRunnerDeps): (action: string) => void {\n  const whole = (n: number) => String(Number.isFinite(n) ? Math.floor(n) : 0);\n  const fill = (value: string, encode = false) => {\n    const s = d.store.get();\n    return value.replace(/\\{(time|duration|title|file)\\}/g, (_m, key: string) => {\n      const raw = key === 'time' ? whole(s.currentTime) : key === 'duration' ? whole(s.duration) : key === 'title' ? s.title : s.url;\n      return encode ? encodeURIComponent(raw) : raw;\n    });\n  };\n\n  const execute = (action: Action) => {\n    switch (action.type) {\n      case 'api': {\n        const result = d.player.api(action.name, action.args[0] !== undefined ? fill(action.args[0]) : undefined);\n        if (result instanceof Promise) result.catch((e) => d.log.warn(`action api:${action.name} rejected`, e));\n        break;\n      }\n      case 'js': {\n        // `js:` actions are author-controlled code, equivalent to the page calling the function itself.\n        if (!PATH_RE.test(action.fn) || action.fn.split('.').some((segment) => BLOCKED_SEGMENTS.has(segment))) {\n          d.log.warn(`invalid js action \"${action.fn}\"`);\n          break;\n        }\n        const { fn, self } = resolveGlobal(action.fn);\n        if (typeof fn !== 'function') {\n          d.log.warn(`js action \"${action.fn}\" is not a function`);\n          break;\n        }\n        fn.apply(self, action.args.map((arg) => fill(arg)));\n        break;\n      }\n      case 'event':\n        d.player.container.dispatchEvent(new CustomEvent(action.name, { detail: d.store.get(), bubbles: true }));\n        break;\n      case 'settings':\n        d.menus.open({ only: action.only.length ? action.only : undefined, align: action.align });\n        break;\n      case 'url':\n        window.open(fill(action.url, true), '_blank', 'noopener');\n        break;\n    }\n  };\n\n  return (input) => {\n    for (const action of parseAction(input)) {\n      try {\n        execute(action);\n      } catch (e) {\n        d.log.error(`action \"${input}\" failed`, e);\n      }\n    }\n  };\n}\n","import type { BaseProps } from '../types.js';\n\nconst toCssLength = (v: string) => (/^-?\\d+(\\.\\d+)?$/.test(v) ? `${v}px` : v);\n\nexport function applyBaseProps(el: HTMLElement, props: BaseProps, playerId: string, t: (key: string) => string): void {\n  if (props.id) el.id = `${playerId}_control_${props.id}`;\n  if (props.hint) {\n    const text = t(props.hint);\n    el.title = text;\n    el.setAttribute('aria-label', text);\n    el.dataset.vpHint = '';\n  }\n  if (props.scale !== undefined) el.style.setProperty('scale', String(props.scale));\n  if (props.margin) el.style.margin = props.margin.trim().split(/\\s+/).map(toCssLength).join(' ');\n  if (props.opacity !== undefined) el.style.opacity = String(props.opacity);\n  if (props.bg) el.style.background = props.bg;\n  if (props.color) el.style.color = props.color;\n  if (props.flex !== undefined) el.style.flexGrow = String(props.flex);\n  if (props.anchor) el.classList.add('vp-anchor', `vp-anchor-${props.anchor}`);\n  if (props.className) el.classList.add(...props.className.split(/\\s+/).filter(Boolean));\n}\n","import type { ComponentFactory, ComponentInstance, HideRuleFactory, LayoutNode, Logger, UIContext } from '../types.js';\nimport type { Registry } from './registry.js';\nimport { applyBaseProps } from './base-props.js';\nimport { compileHide } from './hide-rules.js';\n\nexport type UIBase = Pick<UIContext, 'player' | 'store' | 'events' | 'commands' | 'options' | 'root' | 'log' | 't' | 'icon' | 'menus' | 'run'>;\n\nexport interface LayoutEngineDeps {\n  components: Registry<ComponentFactory<any>>;\n  hideRules: Registry<HideRuleFactory>;\n  base: UIBase;\n  playerId: string;\n  log: Logger;\n}\n\nexport interface Mounted {\n  el: HTMLElement;\n  dispose(): void;\n}\n\nexport interface LayoutEngine {\n  build(node: LayoutNode, parent: HTMLElement | null): Mounted | null;\n}\n\nexport function createLayoutEngine(d: LayoutEngineDeps): LayoutEngine {\n  const build = (node: LayoutNode, parent: HTMLElement | null): (Mounted & { instance: ComponentInstance }) | null => {\n    const factory = d.components.get(node.type);\n    if (!factory) {\n      if (!node.optional) d.log.warn(`unknown component \"${node.type}\"`);\n      return null;\n    }\n\n    const disposers: Array<() => void> = [];\n    const ctx: UIContext = {\n      ...d.base,\n      build(child) {\n        const mounted = build(child, null);\n        if (!mounted) return null;\n        disposers.push(mounted.dispose);\n        return mounted.instance;\n      },\n      select(selector, cb, opts) {\n        const off = d.base.store.select(selector, cb, opts);\n        disposers.push(off);\n        return off;\n      },\n      on(name, cb) {\n        const off = d.base.events.on(name, cb);\n        disposers.push(off);\n        return off;\n      },\n      listen(target, type, fn, opts) {\n        target.addEventListener(type, fn, opts);\n        disposers.push(() => target.removeEventListener(type, fn, opts));\n      },\n      user(name, ...args) {\n        const result = d.base.commands.run(name, args, { source: 'user' });\n        if (result instanceof Promise) result.catch((e) => d.log.warn(`command \"${name}\" rejected`, e));\n      },\n    };\n\n    const cleanup = () => {\n      for (const off of disposers.reverse()) off();\n      disposers.length = 0;\n    };\n\n    let instance: ComponentInstance;\n    try {\n      instance = factory(ctx, node);\n    } catch (e) {\n      d.log.error(`component \"${node.type}\" failed to build`, e);\n      cleanup();\n      return null;\n    }\n\n    try {\n      applyBaseProps(instance.el, node, d.playerId, d.base.t);\n\n      if (node.hide?.length) {\n        const hidden = compileHide(node.hide, d.hideRules, ctx, d.log);\n        ctx.select((s) => hidden(s), (isHidden) => instance.el.classList.toggle('vp-hidden', isHidden), { immediate: true });\n      }\n\n      if (node.action) {\n        // Capture on the root ancestor: fires before any listener on the element itself,\n        // and stopPropagation keeps the click from reaching the component's own handler.\n        const action = node.action;\n        instance.el.dataset.vpAction = '';\n        ctx.listen(\n          d.base.root,\n          'click',\n          (e) => {\n            // Only the innermost element with an action handles the click (nested actions).\n            if ((e.target as Element | null)?.closest?.('[data-vp-action]') !== instance.el) return;\n            e.stopPropagation();\n            e.preventDefault();\n            d.base.run(action);\n          },\n          { capture: true },\n        );\n      }\n\n      for (const child of node.children ?? []) {\n        const built = ctx.build(child);\n        if (built) (instance.slot ?? instance.el).append(built.el);\n      }\n\n      if (parent) parent.append(instance.el);\n    } catch (e) {\n      d.log.error(`component \"${node.type}\" failed to set up`, e);\n      try {\n        instance.dispose?.();\n      } catch (err) {\n        d.log.error(`component \"${node.type}\" failed to dispose`, err);\n      }\n      cleanup();\n      instance.el.remove();\n      return null;\n    }\n\n    let disposed = false;\n    return {\n      el: instance.el,\n      instance,\n      dispose() {\n        if (disposed) return;\n        disposed = true;\n        instance.el.remove();\n        // Children (registered as disposers via ctx.build) go before the component's own dispose.\n        cleanup();\n        try {\n          instance.dispose?.();\n        } catch (e) {\n          d.log.error(`component \"${node.type}\" failed to dispose`, e);\n        }\n      },\n    };\n  };\n\n  return {\n    build(node, parent) {\n      const mounted = build(node, parent);\n      return mounted ? { el: mounted.el, dispose: mounted.dispose } : null;\n    },\n  };\n}\n","import type { EventBus, PlayerState, Store } from '../types.js';\n\nexport interface UserActivityDeps {\n  root: HTMLElement;\n  store: Store<PlayerState>;\n  events: EventBus;\n  timeout: number;\n}\n\nexport interface UserActivity {\n  poke(): void;\n  dispose(): void;\n}\n\nconst MAX_TIMEOUT = 2_147_483_647;\nconst ACTIVATE = ['pointermove', 'pointerdown', 'keydown', 'focusin'] as const;\n\n/** Mirrors the default toolbar hide rule [idle] (toolbar is visible before the first play, like PlayerJS). */\nexport const controlsVisible = (s: PlayerState) => s.userActive || s.status !== 'playing' || s.controlsLocked;\n\nexport function createUserActivity(d: UserActivityDeps): UserActivity {\n  let timer: ReturnType<typeof setTimeout> | undefined;\n  let holds = 0;\n  // setTimeout overflows (fires immediately) above 2^31-1 ms; a non-finite timeout means \"never hide\".\n  const canSchedule = Number.isFinite(d.timeout) && d.timeout <= MAX_TIMEOUT;\n\n  const setActive = (active: boolean) => {\n    if (d.store.get().userActive !== active) d.store.set({ userActive: active });\n  };\n\n  const poke = () => {\n    clearTimeout(timer);\n    setActive(true);\n    if (holds === 0 && canSchedule) timer = setTimeout(() => setActive(false), d.timeout);\n  };\n\n  const onLeave = (e: Event) => {\n    if ((e as PointerEvent).pointerType !== 'mouse' || holds > 0) return;\n    clearTimeout(timer);\n    setActive(false);\n  };\n\n  for (const type of ACTIVATE) d.root.addEventListener(type, poke);\n  d.root.addEventListener('pointerleave', onLeave);\n\n  const hold = (active: boolean) => {\n    if (active) {\n      holds++;\n      clearTimeout(timer);\n      setActive(true);\n    } else {\n      holds = Math.max(0, holds - 1);\n      poke();\n    }\n  };\n  const offMenu = d.events.on('ui:menu', ({ open }) => hold(open));\n  const offDrag = d.events.on('ui:drag', ({ active }) => hold(active));\n\n  const offUi = d.store.select(controlsVisible, (visible) => d.events.emit('ui', visible ? 1 : 0));\n\n  return {\n    poke,\n    dispose() {\n      clearTimeout(timer);\n      for (const type of ACTIVATE) d.root.removeEventListener(type, poke);\n      d.root.removeEventListener('pointerleave', onLeave);\n      offMenu();\n      offDrag();\n      offUi();\n    },\n  };\n}\n","import type { LayoutNode } from '../types.js';\n\n/** The default PlayerJS-like layout. Copy and modify it to build your own. */\nexport const defaultLayout: LayoutNode = {\n  type: 'root',\n  children: [\n    { type: 'media-click-layer' },\n    {\n      type: 'overlay',\n      children: [\n        { type: 'title', anchor: 'top-left', hide: ['idle'] },\n        { type: 'buffering', anchor: 'center', hide: ['not-waiting'] },\n        { type: 'big-play', anchor: 'center', hide: ['started', 'error'] },\n        { type: 'error-overlay', anchor: 'center', hide: ['not-error'] },\n      ],\n    },\n    {\n      type: 'toolbar',\n      hide: ['idle'],\n      children: [\n        { type: 'timeline' },\n        {\n          type: 'group',\n          direction: 'row',\n          className: 'vp-controls',\n          children: [\n            { type: 'prev', optional: true, hide: ['first-item'] },\n            { type: 'play' },\n            { type: 'next', optional: true, hide: ['last-item'] },\n            { type: 'mute' },\n            { type: 'volume', hide: [{ maxWidth: 400 }] },\n            { type: 'time' },\n            { type: 'text', text: '/', className: 'vp-time-sep', hide: ['live'] },\n            { type: 'duration', hide: ['live'] },\n            { type: 'live', hide: ['not-live'] },\n            { type: 'spacer', flex: 1 },\n            { type: 'settings', hide: ['no-menus'] },\n            { type: 'playlist-button', optional: true, hide: ['no-playlist'] },\n            { type: 'fullscreen' },\n          ],\n        },\n      ],\n    },\n  ],\n};\n","const pad = (n: number) => String(n).padStart(2, '0');\n\n/** `m:ss`, or `h:mm:ss` when `reference` (usually duration) is at least an hour. */\nexport function formatTime(seconds: number, reference = seconds): string {\n  const total = Number.isFinite(seconds) && seconds > 0 ? Math.floor(seconds) : 0;\n  const h = Math.floor(total / 3600);\n  const m = Math.floor((total % 3600) / 60);\n  const s = total % 60;\n  if (h > 0 || (Number.isFinite(reference) && reference >= 3600)) return `${h}:${pad(m)}:${pad(s)}`;\n  return `${m}:${pad(s)}`;\n}\n\n/** Parses `hh:mm:ss.mmm`, `mm:ss.mmm` and SRT-style `hh:mm:ss,mmm`. */\nexport function parseTimestamp(value: string): number {\n  const match = value.trim().match(/^(?:(\\d+):)?(\\d{1,2}):(\\d{1,2})(?:[.,](\\d{1,3}))?$/);\n  if (!match) return NaN;\n  const [, h = '0', m, s, ms = '0'] = match;\n  return Number(h) * 3600 + Number(m) * 60 + Number(s) + Number(ms.padEnd(3, '0')) / 1000;\n}\n","import type { ComponentFactory, PlayerState } from '../types.js';\nimport { h } from '../ui/dom.js';\nimport { formatTime } from '../shared/time.js';\n\nexport const rootComponent: ComponentFactory = () => ({ el: h('div', { class: 'vp-layout-root' }) });\nexport const overlayComponent: ComponentFactory = () => ({ el: h('div', { class: 'vp-overlay' }) });\nexport const toolbarComponent: ComponentFactory = () => ({ el: h('div', { class: 'vp-toolbar' }) });\nexport const spacerComponent: ComponentFactory = () => ({ el: h('div', { class: 'vp-spacer' }) });\n\nexport const groupComponent: ComponentFactory<{ direction?: 'row' | 'column' }> = (_ctx, props) => ({\n  el: h('div', { class: `vp-group vp-group-${props.direction === 'column' ? 'column' : 'row'}` }),\n});\n\nconst PLACEHOLDER_RE = /\\{(time|duration|title)\\}/g;\n\nexport function fillTemplate(template: string, s: PlayerState): string {\n  return template.replace(PLACEHOLDER_RE, (_m, key: string) => {\n    if (key === 'time') return formatTime(s.currentTime, s.duration);\n    if (key === 'duration') return formatTime(s.duration, s.duration);\n    return s.title;\n  });\n}\n\nexport const textComponent: ComponentFactory<{ text?: string }> = (ctx, props) => {\n  const el = h('span', { class: 'vp-text' });\n  const template = String(props.text ?? '');\n  if (!/\\{(time|duration|title)\\}/.test(template)) {\n    el.textContent = ctx.t(template);\n  } else {\n    ctx.select((s) => fillTemplate(template, s), (text) => (el.textContent = text), { immediate: true });\n  }\n  return { el };\n};\n","import type { IconName, UIContext } from '../types.js';\nimport { h, iconEl } from './dom.js';\n\nexport interface IconButton {\n  el: HTMLButtonElement;\n  setIcon(name: IconName): void;\n  /** i18n key; ignored when the layout node set a `hint`. */\n  setLabel(key: string): void;\n}\n\nexport function createIconButton(ctx: UIContext, className: string, onClick: () => void): IconButton {\n  const el = h('button', { class: `vp-button ${className}`, type: 'button' });\n  let current: IconName | null = null;\n  ctx.listen(el, 'click', (e) => {\n    e.stopPropagation();\n    onClick();\n  });\n  return {\n    el,\n    setIcon(name) {\n      if (name === current) return;\n      current = name;\n      el.replaceChildren(iconEl(ctx.icon(name)));\n    },\n    setLabel(key) {\n      if (el.dataset.vpHint !== undefined) return;\n      const text = ctx.t(key);\n      el.setAttribute('aria-label', text);\n      el.title = text;\n    },\n  };\n}\n","import type { UIContext } from '../types.js';\n\nconst STEP_PX = 50;\n\n/**\n * Turns wheel events into discrete steps: normalizes `deltaMode`, ignores `deltaY === 0`,\n * accumulates 50px per step (so smooth-scrolling touchpads do not flood the player).\n * Returns +1 for up (negative `deltaY`), -1 for down, 0 while still accumulating.\n * At most one step is returned per event; the accumulator resets after a step (a mouse notch of\n * ~100-120px is always exactly one step) and whenever the scroll direction changes.\n */\nexport function createWheelStepper(): (e: WheelEvent) => -1 | 0 | 1 {\n  let acc = 0;\n  return (e) => {\n    if (!e.deltaY) return 0;\n    const delta = e.deltaY * (e.deltaMode === 1 ? 16 : e.deltaMode === 2 ? 400 : 1);\n    if (acc !== 0 && Math.sign(delta) !== Math.sign(acc)) acc = 0;\n    acc += delta;\n    if (Math.abs(acc) < STEP_PX) return 0;\n    const up = acc < 0;\n    acc = 0;\n    return up ? 1 : -1;\n  };\n}\n\n/**\n * Mouse-wheel volume control: one `setVolume` step per 50px of scrolling.\n * Downward steps are ignored while muted.\n */\nexport function bindWheelVolume(ctx: UIContext, el: HTMLElement): void {\n  const step = createWheelStepper();\n  ctx.listen(\n    el,\n    'wheel',\n    (e) => {\n      const we = e as WheelEvent;\n      if (!we.deltaY) return;\n      e.preventDefault();\n      const s = step(we);\n      if (s === 0 || (s === -1 && ctx.store.get().muted)) return;\n      ctx.user('setVolume', s === 1 ? '+0.05' : '-0.05');\n    },\n    { passive: false },\n  );\n}\n","import type { ComponentFactory, IconName } from '../types.js';\nimport { createIconButton } from '../ui/button.js';\nimport { bindWheelVolume } from '../ui/wheel.js';\n\nexport const playComponent: ComponentFactory = (ctx) => {\n  const b = createIconButton(ctx, 'vp-play', () => ctx.user('toggle'));\n  ctx.select(\n    (s) => s.status,\n    (status) => {\n      const key = status === 'playing' ? 'pause' : status === 'ended' ? 'replay' : 'play';\n      b.setIcon(key);\n      b.setLabel(key);\n    },\n    { immediate: true },\n  );\n  return { el: b.el };\n};\n\nexport const bigPlayComponent: ComponentFactory = (ctx) => {\n  const b = createIconButton(ctx, 'vp-big-play', () => ctx.user('play'));\n  b.setIcon('play');\n  b.setLabel('play');\n  return { el: b.el };\n};\n\nexport const muteComponent: ComponentFactory = (ctx) => {\n  const b = createIconButton(ctx, 'vp-mute', () => ctx.user('toggleMute'));\n  ctx.select(\n    (s): IconName => (s.muted || s.volume === 0 ? 'volume-mute' : s.volume < 0.5 ? 'volume-low' : 'volume-high'),\n    (icon) => b.setIcon(icon),\n    { immediate: true },\n  );\n  // The label describes what a click does (toggleMute), so it follows `muted`, not the level.\n  ctx.select((s) => s.muted, (muted) => b.setLabel(muted ? 'unmute' : 'mute'), { immediate: true });\n  bindWheelVolume(ctx, b.el);\n  return { el: b.el };\n};\n\nexport const fullscreenComponent: ComponentFactory = (ctx) => {\n  const b = createIconButton(ctx, 'vp-fullscreen', () => ctx.user('toggleFullscreen'));\n  ctx.select(\n    (s) => s.fullscreen,\n    (fs) => {\n      b.setIcon(fs ? 'fullscreen-exit' : 'fullscreen');\n      b.setLabel(fs ? 'exitFullscreen' : 'fullscreen');\n    },\n    { immediate: true },\n  );\n  return { el: b.el };\n};\n\nexport const settingsComponent: ComponentFactory = (ctx) => {\n  const b = createIconButton(ctx, 'vp-settings', () => ctx.menus.toggle());\n  b.setIcon('settings');\n  b.setLabel('settings');\n  b.el.dataset.vpMenuToggle = '';\n  b.el.setAttribute('aria-haspopup', 'menu');\n  b.el.setAttribute('aria-expanded', 'false');\n  ctx.on('ui:menu', ({ open }) => b.el.setAttribute('aria-expanded', String(open)));\n  return { el: b.el };\n};\n","import type { ComponentFactory } from '../types.js';\nimport { h } from '../ui/dom.js';\nimport { formatTime } from '../shared/time.js';\n\nexport const timeComponent: ComponentFactory = (ctx) => {\n  const el = h('span', { class: 'vp-time' });\n  ctx.select((s) => formatTime(s.currentTime, s.duration), (text) => (el.textContent = text), { immediate: true });\n  return { el };\n};\n\nexport const durationComponent: ComponentFactory = (ctx) => {\n  const el = h('span', { class: 'vp-duration' });\n  ctx.select((s) => formatTime(s.duration, s.duration), (text) => (el.textContent = text), { immediate: true });\n  return { el };\n};\n\nexport const titleComponent: ComponentFactory = (ctx) => {\n  const el = h('div', { class: 'vp-title' });\n  ctx.select((s) => s.title, (title) => (el.textContent = title), { immediate: true });\n  return { el };\n};\n\nexport const bufferingComponent: ComponentFactory = (ctx) => ({\n  el: h('div', { class: 'vp-buffering', role: 'status' }, h('span', { class: 'vp-sr-only' }, ctx.t('buffering'))),\n});\n\nexport const liveComponent: ComponentFactory = (ctx) => ({\n  el: h('span', { class: 'vp-live' }, h('span', { class: 'vp-live-dot', 'aria-hidden': 'true' }, '●'), ` ${ctx.t('live')}`),\n});\n\nexport const errorOverlayComponent: ComponentFactory = (ctx) => {\n  const message = h('div', { class: 'vp-error-message' });\n  const retry = h('button', { class: 'vp-button vp-error-retry', type: 'button' }, ctx.t('retry'));\n  const el = h('div', { class: 'vp-error', role: 'alert' }, message, retry);\n  ctx.listen(retry, 'click', (e) => {\n    e.stopPropagation();\n    ctx.user('reload');\n  });\n  ctx.select((s) => s.error?.kind ?? null, (kind) => (message.textContent = kind ? ctx.t(`error.${kind}`) : ''), { immediate: true });\n  return { el };\n};\n\n/**\n * Full-size layer over the video: click toggles playback, double click toggles fullscreen.\n * Accepted trade-off (same as YouTube/PlayerJS): a double click also delivers two clicks,\n * so playback toggles twice (net unchanged) before fullscreen; no single-click delay.\n */\nexport const mediaClickLayerComponent: ComponentFactory = (ctx) => {\n  const el = h('div', { class: 'vp-click-layer' });\n  let revealOnly = false;\n  ctx.listen(el, 'pointerdown', (e) => {\n    const s = ctx.store.get();\n    revealOnly = (e as PointerEvent).pointerType === 'touch' && s.status === 'playing' && !s.userActive;\n  });\n  ctx.listen(el, 'pointercancel', () => {\n    revealOnly = false;\n  });\n  ctx.listen(el, 'click', () => {\n    const reveal = revealOnly;\n    revealOnly = false;\n    if (reveal) return;\n    ctx.user('toggle');\n  });\n  ctx.listen(el, 'dblclick', () => ctx.user('toggleFullscreen'));\n  return { el };\n};\n","import type { UIContext } from '../types.js';\nimport { h } from './dom.js';\nimport { clamp } from '../shared/clamp.js';\n\nexport interface SliderOptions {\n  className: string;\n  label: string;\n  /** Called with a 0..1 value; `final` is true on release and keyboard steps. */\n  onInput(value: number, final: boolean): void;\n  step?: number;\n}\n\nexport interface Slider {\n  el: HTMLDivElement;\n  set(value: number, text?: string): void;\n  /** Ends an active drag (emits `ui:drag` inactive) without calling `onInput`. */\n  dispose(): void;\n}\n\nconst round = (v: number) => Math.round(v * 1000) / 1000;\n\nexport function createSlider(ctx: UIContext, o: SliderOptions): Slider {\n  const step = o.step ?? 0.05;\n  const fill = h('div', { class: 'vp-slider-fill' });\n  const el = h(\n    'div',\n    { class: `vp-slider ${o.className}`, role: 'slider', tabindex: 0, 'aria-label': o.label, 'aria-valuemin': 0, 'aria-valuemax': 1 },\n    h('div', { class: 'vp-slider-track' }, fill),\n  );\n  let value = 0;\n  let dragging = false;\n  let activePointerId: number | null = null;\n  let lastValue = 0;\n\n  const valueAt = (clientX: number) => {\n    const r = el.getBoundingClientRect();\n    return r.width > 0 ? round(clamp((clientX - r.left) / r.width, 0, 1)) : value;\n  };\n\n  const set = (v: number, text?: string) => {\n    value = clamp(v, 0, 1);\n    fill.style.width = `${value * 100}%`;\n    el.setAttribute('aria-valuenow', String(round(value)));\n    el.setAttribute('aria-valuetext', text ?? `${Math.round(value * 100)}%`);\n  };\n\n  const pointerOf = (e: Event) => (e as PointerEvent).pointerId ?? 1;\n  const endDrag = () => {\n    dragging = false;\n    activePointerId = null;\n    ctx.events.emit('ui:drag', { active: false });\n  };\n\n  ctx.listen(el, 'pointerdown', (e) => {\n    const pe = e as PointerEvent;\n    if (dragging || (pe.button !== undefined && pe.button !== 0)) return;\n    e.stopPropagation();\n    dragging = true;\n    activePointerId = pointerOf(e);\n    ctx.events.emit('ui:drag', { active: true });\n    try {\n      el.setPointerCapture?.(pe.pointerId);\n    } catch {\n      /* jsdom / synthetic events have no active pointer */\n    }\n    lastValue = valueAt(pe.clientX);\n    o.onInput(lastValue, false);\n  });\n  ctx.listen(el, 'pointermove', (e) => {\n    if (!dragging || pointerOf(e) !== activePointerId) return;\n    lastValue = valueAt((e as PointerEvent).clientX);\n    o.onInput(lastValue, false);\n  });\n  ctx.listen(el, 'pointerup', (e) => {\n    if (!dragging || pointerOf(e) !== activePointerId) return;\n    endDrag();\n    o.onInput(valueAt((e as PointerEvent).clientX), true);\n  });\n  ctx.listen(el, 'pointercancel', (e) => {\n    if (!dragging || pointerOf(e) !== activePointerId) return;\n    endDrag();\n  });\n  ctx.listen(el, 'lostpointercapture', (e) => {\n    if (!dragging || pointerOf(e) !== activePointerId) return;\n    endDrag();\n    o.onInput(lastValue, true);\n  });\n  ctx.listen(el, 'click', (e) => e.stopPropagation());\n  ctx.listen(el, 'keydown', (e) => {\n    const key = (e as KeyboardEvent).key;\n    const delta = key === 'ArrowRight' || key === 'ArrowUp' ? step : key === 'ArrowLeft' || key === 'ArrowDown' ? -step : 0;\n    if (!delta) return;\n    // No stopPropagation: the root activity tracker must still see the key; hotkeys skip defaultPrevented events.\n    e.preventDefault();\n    o.onInput(round(clamp(value + delta, 0, 1)), true);\n  });\n\n  set(0);\n\n  return {\n    el,\n    set,\n    dispose() {\n      if (dragging) endDrag();\n    },\n  };\n}\n","import type { ComponentFactory } from '../types.js';\nimport { createSlider } from '../ui/slider.js';\nimport { bindWheelVolume } from '../ui/wheel.js';\n\nexport const volumeComponent: ComponentFactory = (ctx) => {\n  const slider = createSlider(ctx, {\n    className: 'vp-volume',\n    label: ctx.t('volume'),\n    onInput: (value) => ctx.user('setVolume', value),\n  });\n  ctx.select((s) => (s.muted ? 0 : s.volume), (v) => slider.set(v, `${Math.round(v * 100)}%`), { immediate: true });\n  bindWheelVolume(ctx, slider.el);\n  return { el: slider.el, dispose: slider.dispose };\n};\n","import type { ComponentFactory } from '../types.js';\nimport { h } from '../ui/dom.js';\nimport { clamp } from '../shared/clamp.js';\nimport { formatTime } from '../shared/time.js';\n\nexport const timelineComponent: ComponentFactory = (ctx) => {\n  const buffered = h('div', { class: 'vp-timeline-buffered' });\n  const progress = h('div', { class: 'vp-timeline-progress' });\n  const thumb = h('div', { class: 'vp-timeline-thumb' });\n  const markers = h('div', { class: 'vp-timeline-markers' });\n  const el = h(\n    'div',\n    { class: 'vp-timeline', role: 'slider', tabindex: 0, 'aria-label': ctx.t('timeline'), 'aria-valuemin': 0 },\n    h('div', { class: 'vp-timeline-track' }, buffered, progress, markers, thumb),\n  );\n  let dragging = false;\n  let activePointerId: number | null = null;\n  let dragTime = 0;\n\n  const paint = (time: number, duration: number, bufferedEnd: number) => {\n    const pct = duration > 0 ? clamp(time / duration, 0, 1) * 100 : 0;\n    progress.style.width = `${pct}%`;\n    thumb.style.left = `${pct}%`;\n    buffered.style.width = duration > 0 ? `${clamp(bufferedEnd / duration, 0, 1) * 100}%` : '0%';\n    el.setAttribute('aria-valuemax', String(Math.floor(duration)));\n    el.setAttribute('aria-valuenow', String(Math.floor(time)));\n    el.setAttribute('aria-valuetext', `${formatTime(time, duration)} / ${formatTime(duration, duration)}`);\n  };\n\n  const position = (clientX: number) => {\n    const r = el.getBoundingClientRect();\n    const x = clamp(clientX - r.left, 0, r.width);\n    const duration = ctx.store.get().duration;\n    const rootX = r.left - ctx.root.getBoundingClientRect().left + x;\n    return { time: r.width > 0 ? (x / r.width) * duration : 0, x, rootX, width: r.width };\n  };\n\n  // No seeking on live streams, regardless of the layout's hide rules.\n  ctx.select((s) => s.live, (live) => el.classList.toggle('vp-timeline-live', live), { immediate: true });\n\n  ctx.select(\n    (s) => [s.currentTime, s.duration, s.buffered] as const,\n    ([t, d, b]) => {\n      if (!dragging) paint(t, d, b);\n    },\n    { immediate: true, equals: (a, b) => a[0] === b[0] && a[1] === b[1] && a[2] === b[2] },\n  );\n\n  ctx.select(\n    (s) => [s.markers, s.duration] as const,\n    ([list, duration]) => {\n      const inside = duration > 0 ? list.filter((m) => m.time > 0 && m.time < duration) : [];\n      markers.replaceChildren(\n        ...inside.map((m) => {\n          const tick = h('div', { class: 'vp-timeline-marker' });\n          tick.style.left = `${(m.time / duration) * 100}%`;\n          return tick;\n        }),\n      );\n    },\n    { immediate: true, equals: (a, b) => a[0] === b[0] && a[1] === b[1] },\n  );\n\n  const pointerOf = (e: Event) => (e as PointerEvent).pointerId ?? 1;\n  const endDrag = () => {\n    dragging = false;\n    activePointerId = null;\n    el.classList.remove('vp-dragging');\n    ctx.events.emit('ui:drag', { active: false });\n  };\n  const commit = () => {\n    ctx.events.emit('line', dragTime);\n    ctx.user('seek', dragTime);\n  };\n\n  ctx.listen(el, 'pointerdown', (e) => {\n    const pe = e as PointerEvent;\n    if (dragging || (pe.button !== undefined && pe.button !== 0)) return;\n    e.stopPropagation();\n    const s = ctx.store.get();\n    if (!(s.duration > 0)) return;\n    dragging = true;\n    activePointerId = pointerOf(e);\n    el.classList.add('vp-dragging');\n    ctx.events.emit('ui:drag', { active: true });\n    try {\n      el.setPointerCapture?.(pe.pointerId);\n    } catch {\n      /* synthetic events have no active pointer */\n    }\n    dragTime = position(pe.clientX).time;\n    paint(dragTime, s.duration, s.buffered);\n  });\n\n  ctx.listen(el, 'pointermove', (e) => {\n    const pos = position((e as PointerEvent).clientX);\n    ctx.events.emit('ui:timeline-hover', pos);\n    if (dragging && pointerOf(e) === activePointerId) {\n      dragTime = pos.time;\n      const s = ctx.store.get();\n      paint(dragTime, s.duration, s.buffered);\n    }\n  });\n\n  ctx.listen(el, 'pointerup', (e) => {\n    if (!dragging || pointerOf(e) !== activePointerId) return;\n    dragTime = position((e as PointerEvent).clientX).time;\n    endDrag();\n    commit();\n  });\n\n  ctx.listen(el, 'pointercancel', (e) => {\n    if (!dragging || pointerOf(e) !== activePointerId) return;\n    endDrag();\n    const s = ctx.store.get();\n    paint(s.currentTime, s.duration, s.buffered);\n  });\n\n  ctx.listen(el, 'lostpointercapture', (e) => {\n    if (!dragging || pointerOf(e) !== activePointerId) return;\n    endDrag();\n    commit();\n  });\n\n  ctx.listen(el, 'pointerleave', () => {\n    if (!dragging) ctx.events.emit('ui:timeline-leave');\n  });\n\n  ctx.listen(el, 'click', (e) => e.stopPropagation());\n\n  ctx.listen(el, 'keydown', (e) => {\n    const key = (e as KeyboardEvent).key;\n    const target = key === 'ArrowRight' ? '+5' : key === 'ArrowLeft' ? '-5' : key === 'Home' ? 0 : key === 'End' ? ctx.store.get().duration : null;\n    if (target === null) return;\n    // No stopPropagation: the root activity tracker must still see the key; hotkeys skip defaultPrevented events.\n    e.preventDefault();\n    ctx.user('seek', target);\n  });\n\n  return {\n    el,\n    dispose() {\n      if (dragging) endDrag();\n    },\n  };\n};\n","import type { ComponentFactory } from '../types.js';\nimport type { Registry } from '../ui/registry.js';\nimport { groupComponent, overlayComponent, rootComponent, spacerComponent, textComponent, toolbarComponent } from './containers.js';\nimport { bigPlayComponent, fullscreenComponent, muteComponent, playComponent, settingsComponent } from './buttons.js';\nimport { bufferingComponent, durationComponent, errorOverlayComponent, liveComponent, mediaClickLayerComponent, timeComponent, titleComponent } from './indicators.js';\nimport { volumeComponent } from './volume.js';\nimport { timelineComponent } from './timeline.js';\n\nexport const BUILTIN_COMPONENTS: Record<string, ComponentFactory<any>> = {\n  root: rootComponent,\n  overlay: overlayComponent,\n  toolbar: toolbarComponent,\n  group: groupComponent,\n  spacer: spacerComponent,\n  text: textComponent,\n  'media-click-layer': mediaClickLayerComponent,\n  play: playComponent,\n  'big-play': bigPlayComponent,\n  mute: muteComponent,\n  volume: volumeComponent,\n  timeline: timelineComponent,\n  time: timeComponent,\n  duration: durationComponent,\n  title: titleComponent,\n  buffering: bufferingComponent,\n  live: liveComponent,\n  fullscreen: fullscreenComponent,\n  settings: settingsComponent,\n  'error-overlay': errorOverlayComponent,\n};\n\nexport function registerBuiltinComponents(registry: Registry<ComponentFactory<any>>): void {\n  for (const [type, factory] of Object.entries(BUILTIN_COMPONENTS)) registry.register(type, factory);\n}\n\nexport * from './containers.js';\nexport * from './buttons.js';\nexport * from './indicators.js';\nexport * from './volume.js';\nexport * from './timeline.js';\n","import type {\n  CommandContext,\n  ComponentFactory,\n  HideRuleFactory,\n  LayoutNode,\n  MediaProvider,\n  Player,\n  PlayerOptions,\n  PluginContext,\n  SourceTransform,\n  ThemeVars,\n} from './types.js';\nimport css from './theme/player.css?inline';\nimport { createLogger } from './core/logger.js';\nimport { createStore } from './core/store.js';\nimport { createEventBus } from './core/events.js';\nimport { createCommandRegistry } from './core/commands.js';\nimport { createPluginHost } from './core/plugin-host.js';\nimport { createInitialState } from './core/initial-state.js';\nimport { createMediaController } from './core/media-controller.js';\nimport { html5Provider } from './providers/html5.js';\nimport { hlsProvider } from './providers/hls.js';\nimport { createApi } from './api/api-map.js';\nimport { h } from './ui/dom.js';\nimport { createRegistry } from './ui/registry.js';\nimport { registerBuiltinHideRules } from './ui/hide-rules.js';\nimport { createTranslator } from './ui/i18n.js';\nimport { createIconSet } from './ui/icons.js';\nimport { createMenuHost } from './ui/menu-host.js';\nimport { createActionRunner } from './ui/actions.js';\nimport { createLayoutEngine, type Mounted } from './ui/layout.js';\nimport { controlsVisible, createUserActivity } from './ui/activity.js';\nimport { defaultLayout } from './ui/default-layout.js';\nimport { registerBuiltinComponents } from './components/index.js';\n\nconst API: CommandContext = { source: 'api' };\nlet counter = 0;\n/** Live players by container, so reusing a container replaces the previous player. */\nconst livePlayers = new WeakMap<HTMLElement, Player>();\n\nfunction resolveContainer(container: HTMLElement | string): HTMLElement {\n  const el = typeof container === 'string' ? document.getElementById(container) : container;\n  if (!el) throw new Error(`[vp] container \"${String(container)}\" not found`);\n  return el;\n}\n\nfunction injectStyles(): void {\n  if (document.getElementById('vp-styles')) return;\n  const style = document.createElement('style');\n  style.id = 'vp-styles';\n  style.textContent = css;\n  document.head.append(style);\n}\n\nfunction parseRatio(ratio: string | undefined): string | null {\n  const match = (ratio ?? '16:9').match(/^\\s*(\\d+(?:\\.\\d+)?)\\s*[:/]\\s*(\\d+(?:\\.\\d+)?)\\s*$/);\n  return match ? `${match[1]} / ${match[2]}` : null;\n}\n\nfunction applyTheme(root: HTMLElement, theme: Partial<ThemeVars> = {}): void {\n  for (const [key, value] of Object.entries(theme)) {\n    if (value === undefined) continue;\n    const name = key.replace(/([A-Z])/g, '-$1').replace(/(\\d+)/g, '-$1').toLowerCase();\n    root.style.setProperty(`--vp-${name}`, value);\n  }\n}\n\n/** Composition root without default plugins: `options.plugins` defaults to `[]` (tree-shakable). */\nexport function createPlayerCore(options: PlayerOptions): Player {\n  // 1. DOM skeleton\n  const container = resolveContainer(options.container);\n  if (!container.id) container.id = `vp${++counter}`;\n  const id = container.id;\n  const log = createLogger(!!options.log);\n  const previous = livePlayers.get(container);\n  if (previous) {\n    log.warn(`container \"${id}\" already hosts a player; destroying the previous one`);\n    previous.destroy();\n  }\n  injectStyles();\n\n  const video = h('video', { playsinline: true, 'webkit-playsinline': true, preload: 'metadata' });\n  const layerBelow = h('div', { class: 'vp-layer-below' });\n  const layoutLayer = h('div', { class: 'vp-layout' });\n  const layerAbove = h('div', { class: 'vp-layer-above' });\n  const root = h('div', { class: 'vp-root', tabindex: 0 }, h('div', { class: 'vp-media' }, video), h('div', { class: 'vp-ui' }, layerBelow, layoutLayer, layerAbove));\n  const ratio = options.ratio === 'auto' ? parseRatio('16:9') : parseRatio(options.ratio);\n  if (ratio) root.style.aspectRatio = ratio;\n  applyTheme(root, options.theme);\n  container.replaceChildren(root);\n\n  // 2–3. Core, media, UI registries\n  const store = createStore(createInitialState(options), log);\n  const events = createEventBus(log);\n  const commands = createCommandRegistry(log);\n  const providers: MediaProvider[] = [html5Provider(), hlsProvider()];\n  const transforms: SourceTransform[] = [];\n  const controller = createMediaController({ video, root, store, events, commands, log, options, providers, transforms });\n\n  const components = createRegistry<ComponentFactory<any>>('component', log);\n  registerBuiltinComponents(components);\n  const hideRules = createRegistry<HideRuleFactory>('hide rule', log);\n  registerBuiltinHideRules(hideRules);\n  const t = createTranslator(options.lang ?? 'en', options.i18n);\n  const icon = createIconSet(options.icons);\n  const menus = createMenuHost({ layer: layerAbove, store, events, t, icon, log });\n  const activity = createUserActivity({ root, store, events, timeout: options.idleTimeout ?? 3000 });\n\n  let destroyed = false;\n  let destroying = false;\n  const alive = () => {\n    if (destroyed) log.warn('player is destroyed');\n    return !destroyed;\n  };\n\n  // 4. Player facade\n  const player: Player = {\n    id,\n    container,\n    root,\n    video,\n    get state() {\n      return store.get();\n    },\n    play: () => (alive() ? (commands.run('play', [], API) ?? Promise.resolve()) : Promise.resolve()),\n    pause: () => {\n      if (alive()) commands.run('pause', [], API);\n    },\n    seek: (time) => {\n      if (alive()) commands.run('seek', [time], API);\n    },\n    load: (source) => {\n      if (alive()) commands.run('load', [source], API);\n    },\n    on: events.on,\n    once: events.once,\n    off: events.off,\n    select: store.select,\n    command: (name, ...args) => (alive() ? commands.run(name, args, API) : undefined),\n    api: (cmd, arg) => (alive() ? api(cmd, arg) : undefined),\n    destroy,\n  };\n  const api = createApi({ player, store, commands, events, options, log });\n  const run = createActionRunner({ player, store, menus, log });\n  const engine = createLayoutEngine({ components, hideRules, playerId: id, log, base: { player, store, events, commands, options, root, log, t, icon, menus, run } });\n\n  // 5. Plugin context\n  const layers = new Set<Mounted>();\n  const pluginContext: PluginContext = {\n    player,\n    store,\n    events,\n    commands,\n    options,\n    video,\n    root,\n    log,\n    t,\n    registerProvider: (p) => void providers.push(p),\n    addSourceTransform(fn) {\n      transforms.push(fn);\n      return () => {\n        const i = transforms.indexOf(fn);\n        if (i >= 0) transforms.splice(i, 1);\n      };\n    },\n    registerComponent: (type, factory) => components.register(type, factory),\n    registerMenu: (menu) => menus.register(menu),\n    registerHideRule: (name, rule) => hideRules.register(name, rule),\n    addLayer(node, position) {\n      if (destroyed) {\n        log.warn('player is destroyed');\n        return () => {};\n      }\n      const mounted = engine.build(node, position === 'below-ui' ? layerBelow : layerAbove);\n      if (!mounted) return () => {};\n      layers.add(mounted);\n      return () => {\n        layers.delete(mounted);\n        mounted.dispose();\n      };\n    },\n  };\n\n  const offs: Array<() => void> = [\n    commands.register('showControls', () => activity.poke()),\n    commands.register('toggleMenu', () => menus.toggle()),\n    commands.register('destroy', () => destroy()),\n    store.select((s) => !controlsVisible(s), (idle) => root.classList.toggle('vp-idle', idle)),\n  ];\n\n  // 6. Plugins\n  const pluginHost = createPluginHost(log);\n  pluginHost.setupAll(options.plugins ?? [], pluginContext);\n\n  // 7. Layout\n  let layout: Mounted | null = null;\n  const buildLayout = (node: LayoutNode | false) => {\n    layout?.dispose();\n    layout = node === false ? null : engine.build(node, layoutLayer);\n  };\n  offs.push(commands.register('layout', ([node]) => buildLayout(node)));\n  buildLayout(options.layout === undefined ? defaultLayout : options.layout);\n\n  // Size tracking and ratio:auto\n  const measure = () => {\n    const width = Math.round(root.clientWidth);\n    const height = Math.round(root.clientHeight);\n    if (width === store.get().width && height === store.get().height) return;\n    store.set({ width, height });\n    events.emit('resize', { width, height });\n  };\n  const resizeObserver = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(measure) : null;\n  resizeObserver?.observe(root);\n  // Initial size without a `resize` event (that would precede `init`); later changes come from the observer.\n  store.set({ width: Math.round(root.clientWidth), height: Math.round(root.clientHeight) });\n  const onMetadata = () => {\n    if (video.videoWidth > 0 && video.videoHeight > 0) root.style.aspectRatio = `${video.videoWidth} / ${video.videoHeight}`;\n  };\n  if (options.ratio === 'auto') video.addEventListener('loadedmetadata', onMetadata);\n\n  // 8–9. Init, then load\n  livePlayers.set(container, player);\n  events.emit('init');\n  if (options.source !== undefined) player.load(options.source);\n  return player;\n\n  function destroy(): void {\n    if (destroying || destroyed) return;\n    destroying = true;\n    events.emit('destroy');\n    destroyed = true;\n    if (livePlayers.get(container) === player) livePlayers.delete(container);\n    layout?.dispose();\n    for (const mounted of [...layers].reverse()) mounted.dispose();\n    layers.clear();\n    menus.dispose();\n    activity.dispose();\n    pluginHost.disposeAll();\n    offs.forEach((off) => off());\n    controller.destroy();\n    resizeObserver?.disconnect();\n    video.removeEventListener('loadedmetadata', onMetadata);\n    // Stop media even if a third-party provider's detach() left it attached.\n    video.pause();\n    video.removeAttribute('src');\n    try {\n      video.load();\n    } catch {\n      /* jsdom: not implemented */\n    }\n    root.remove();\n  }\n}\n","import type { CommandContext, MenuOption, Plugin, PlayerState } from '../types.js';\n\ndeclare module '../types.js' {\n  interface PlayerOptions {\n    /** Label, `num:X` (zero-based) or `max`. PlayerJS: default_quality. */\n    defaultQuality?: string;\n    /** Comma-separated labels hidden from the menu. PlayerJS: forbidden_quality. */\n    forbiddenQuality?: string;\n  }\n}\n\nexport interface QualityPluginOptions {\n  defaultQuality?: string;\n  forbiddenQuality?: string | string[];\n}\n\nconst USER: CommandContext = { source: 'user' };\n\nexport function pickQuality(labels: string[], wanted: string | undefined): number | null {\n  if (!wanted) return null;\n  if (wanted === 'max') return labels.length ? labels.length - 1 : null;\n  const num = wanted.match(/^num:(\\d+)$/);\n  if (num) {\n    const i = Number(num[1]);\n    return i < labels.length ? i : null;\n  }\n  const i = labels.indexOf(wanted);\n  return i >= 0 ? i : null;\n}\n\nconst toList = (value: string | string[] | undefined) =>\n  (Array.isArray(value) ? value : (value ?? '').split(',')).map((s) => s.trim()).filter(Boolean);\n\nexport function qualityPlugin(o: QualityPluginOptions = {}): Plugin {\n  return {\n    name: 'quality',\n    setup(ctx) {\n      const wanted = o.defaultQuality ?? ctx.options.defaultQuality;\n      const forbidden = new Set(toList(o.forbiddenQuality ?? ctx.options.forbiddenQuality));\n\n      const options = (s: PlayerState): MenuOption[] =>\n        s.qualities\n          .map((q, i) => ({ label: q.label === 'auto' ? ctx.t('auto') : q.label || String(i + 1), value: i, raw: q.label }))\n          .filter((x) => !forbidden.has(x.raw))\n          .map(({ label, value }) => ({ label, value }));\n\n      const offTransform = ctx.addSourceTransform((spec, sel) => {\n        const labels = spec.qualities.map((q) => q.label);\n        let index = pickQuality(labels, wanted) ?? sel.quality;\n        if (forbidden.has(labels[index] ?? '')) {\n          // fall back to the highest allowed quality\n          for (let i = labels.length - 1; i >= 0; i--) {\n            if (!forbidden.has(labels[i]!)) {\n              index = i;\n              break;\n            }\n          }\n        }\n        return index === sel.quality ? sel : { ...sel, quality: index };\n      });\n\n      const offMenu = ctx.registerMenu({\n        id: 'quality',\n        label: 'quality',\n        order: 10,\n        visible: (s) => options(s).length > 1,\n        options,\n        current: (s) => s.quality,\n        select: (value) => ctx.commands.run('setQuality', [value as number], USER),\n      });\n\n      return () => {\n        offTransform();\n        offMenu();\n      };\n    },\n  };\n}\n","import type { CommandContext, Plugin } from '../types.js';\n\ndeclare module '../types.js' {\n  interface PlayerState {\n    speeds?: number[];\n  }\n  interface PlayerOptions {\n    speeds?: number[];\n    /** PlayerJS: default_speed. */\n    defaultSpeed?: number;\n  }\n  interface PlayerCommands {\n    /** Index into `state.speeds` (PlayerJS `api('speed', i)`). */\n    setSpeedIndex(index: number): void;\n  }\n}\n\nexport interface SpeedPluginOptions {\n  speeds?: number[];\n  defaultSpeed?: number;\n}\n\nconst USER: CommandContext = { source: 'user' };\nexport const DEFAULT_SPEEDS = [0.5, 0.75, 1, 1.25, 1.5, 2];\n\nexport function speedPlugin(o: SpeedPluginOptions = {}): Plugin {\n  return {\n    name: 'speed',\n    setup(ctx) {\n      const speeds = o.speeds ?? ctx.options.speeds ?? DEFAULT_SPEEDS;\n      const defaultSpeed = o.defaultSpeed ?? ctx.options.defaultSpeed;\n      ctx.store.set({ speeds });\n\n      const offs = [\n        ctx.commands.register('setSpeedIndex', ([index], c) => {\n          const rate = speeds[index];\n          if (rate) ctx.commands.run('setRate', [rate], c);\n        }),\n        ctx.registerMenu({\n          id: 'speed',\n          label: 'speed',\n          order: 20,\n          visible: () => speeds.length > 1,\n          options: () => speeds.map((rate) => ({ label: rate === 1 ? ctx.t('normal') : `${rate}x`, value: rate })),\n          current: (s) => s.rate,\n          select: (value) => ctx.commands.run('setRate', [value as number], USER),\n        }),\n        ctx.events.on('init', () => {\n          if (defaultSpeed && defaultSpeed > 0) ctx.commands.run('setRate', [defaultSpeed]);\n        }),\n      ];\n      return () => offs.forEach((off) => off());\n    },\n  };\n}\n","import type { CommandContext, Plugin } from '../types.js';\n\ndeclare module '../types.js' {\n  interface PlayerOptions {\n    /** Track label to start with. PlayerJS: default_audio. */\n    defaultAudio?: string;\n    /** Rename menu labels by original label or index. PlayerJS: rename_audio. */\n    renameAudio?: Record<string, string>;\n  }\n}\n\nexport interface AudioTracksPluginOptions {\n  defaultAudio?: string;\n  renameAudio?: Record<string | number, string>;\n}\n\nconst USER: CommandContext = { source: 'user' };\n\nexport function audioTracksPlugin(o: AudioTracksPluginOptions = {}): Plugin {\n  return {\n    name: 'audiotracks',\n    setup(ctx) {\n      const wanted = o.defaultAudio ?? ctx.options.defaultAudio;\n      const rename: Record<string, string> = { ...(ctx.options.renameAudio ?? {}), ...(o.renameAudio ?? {}) };\n      const display = (label: string, index: number) => rename[label] ?? rename[String(index)] ?? (label || String(index + 1));\n\n      const offTransform = ctx.addSourceTransform((spec, sel) => {\n        if (!wanted) return sel;\n        const index = (spec.qualities[sel.quality]?.tracks ?? []).findIndex((t) => t.label === wanted);\n        return index >= 0 ? { ...sel, audio: index } : sel;\n      });\n\n      const offMenu = ctx.registerMenu({\n        id: 'audio',\n        label: 'audio',\n        order: 40,\n        visible: (s) => s.audioTracks.length > 1,\n        options: (s) => s.audioTracks.map((t, i) => ({ label: display(t.label, i), value: i })),\n        current: (s) => s.audioTrack,\n        select: (value) => ctx.commands.run('setAudioTrack', [value as number], USER),\n      });\n\n      return () => {\n        offTransform();\n        offMenu();\n      };\n    },\n  };\n}\n","import { parseTimestamp } from './time.js';\n\nexport interface Cue {\n  start: number;\n  end: number;\n  text: string;\n}\n\n/** Parses WebVTT or SRT text into cues (blocks without a `-->` line are ignored). */\nexport function parseCues(input: string): Cue[] {\n  const text = input.replace(/^﻿/, '').replace(/\\r\\n?/g, '\\n');\n  const cues: Cue[] = [];\n  for (const block of text.split(/\\n(?:[ \\t]*\\n)+/)) {\n    const lines = block.split('\\n');\n    const timing = lines.findIndex((line) => line.includes('-->'));\n    if (timing < 0) continue;\n    const [left = '', right = ''] = lines[timing]!.split('-->');\n    const start = parseTimestamp(left.trim());\n    const end = parseTimestamp(right.trim().split(/\\s+/)[0] ?? '');\n    if (!Number.isFinite(start) || !Number.isFinite(end)) continue;\n    cues.push({ start, end, text: lines.slice(timing + 1).join('\\n').trim() });\n  }\n  return cues.sort((a, b) => a.start - b.start);\n}\n","import type { Cue } from '../../shared/cues.js';\n\nexport { parseCues as parseSubtitles, type Cue } from '../../shared/cues.js';\n\nexport function shiftCues(cues: Cue[], seconds: number): Cue[] {\n  if (!seconds) return cues;\n  return cues.map((c) => ({ ...c, start: c.start + seconds, end: c.end + seconds }));\n}\n\n/** PlayerJS shifts are in tenths of a second: `?shift=-5` or the `subshift` option. */\nexport function shiftFromUrl(url: string, fallbackTenths: number): number {\n  const match = url.match(/[?&]shift=(-?\\d+(?:\\.\\d+)?)/);\n  return (match ? Number(match[1]) : fallbackTenths) / 10;\n}\n\nexport function activeText(cues: Cue[], time: number): string {\n  return cues\n    .filter((c) => c.start <= time && time < c.end)\n    .map((c) => c.text)\n    .join('\\n');\n}\n\nconst NAMED: Record<string, string> = { amp: '&', lt: '<', gt: '>', quot: '\"', nbsp: '\\u00a0' };\nconst decode = (s: string) =>\n  s.replace(/&(?:(amp|lt|gt|quot|nbsp)|#(\\d+)|#x([0-9a-f]+));/gi, (match, name?: string, dec?: string, hex?: string) => {\n    if (name) return NAMED[name.toLowerCase()] ?? match;\n    const code = dec !== undefined ? Number(dec) : parseInt(hex ?? '', 16);\n    return Number.isInteger(code) && code >= 0 && code <= 0x10ffff && !(code >= 0xd800 && code <= 0xdfff) ? String.fromCodePoint(code) : match;\n  });\n/** `<b>`/`<i>`/`<u>` (any case) are kept; any other tag starting with a letter, and VTT timestamps like `<00:01.000>`, are stripped. */\nconst TAG_RE = /<(\\/?)([biu])>|<\\/?[a-z][^<>]*>|<\\d[\\d:.,]*>/gi;\n\n/** Builds DOM nodes for cue text: keeps <b>, <i>, <u> and newlines; strips everything else. */\nexport function cueNodes(raw: string): Node[] {\n  const text = raw.replace(/\\{\\\\[^}]*\\}/g, '');\n  const fragment = document.createDocumentFragment();\n  const stack: Node[] = [fragment];\n  const top = () => stack[stack.length - 1]!;\n  const pushText = (chunk: string) => {\n    decode(chunk)\n      .split('\\n')\n      .forEach((part, i) => {\n        if (i > 0) top().appendChild(document.createElement('br'));\n        if (part) top().appendChild(document.createTextNode(part));\n      });\n  };\n\n  let last = 0;\n  for (const match of text.matchAll(TAG_RE)) {\n    const index = match.index ?? 0;\n    pushText(text.slice(last, index));\n    last = index + match[0].length;\n    const [, closing, tag] = match;\n    if (!tag) continue;\n    if (closing) {\n      if (stack.length > 1) stack.pop();\n    } else {\n      const el = document.createElement(tag.toLowerCase());\n      top().appendChild(el);\n      stack.push(el);\n    }\n  }\n  pushText(text.slice(last));\n  return [...fragment.childNodes];\n}\n","import type { CommandContext, Plugin, SubtitleRef } from '../../types.js';\nimport { h } from '../../ui/dom.js';\nimport { controlsVisible } from '../../ui/activity.js';\nimport { parseSubtitleList } from '../../source/parse.js';\nimport { activeText, cueNodes, parseSubtitles, shiftCues, shiftFromUrl, type Cue } from './parse.js';\n\ndeclare module '../../types.js' {\n  interface PlayerOptions {\n    /** `[Label]url,[Label]url` for the first source. PlayerJS: subtitle. */\n    subtitle?: string;\n    /** Label to show initially. PlayerJS: default_subtitle. */\n    defaultSubtitle?: string;\n    /** `false` starts with subtitles off. PlayerJS: subtitle_start:0. */\n    subtitleStart?: boolean;\n    /** Shift in tenths of a second. PlayerJS: subshift. */\n    subshift?: number;\n  }\n  interface PlayerCommands {\n    setTextTrack(index: number): void;\n    toggleSubtitles(): void;\n    addSubtitle(label: string, url: string, select?: boolean): void;\n  }\n}\n\nexport interface SubtitlesPluginOptions {\n  subtitle?: string;\n  defaultSubtitle?: string;\n  subtitleStart?: boolean;\n  subshift?: number;\n  fetch?: typeof fetch;\n}\n\ninterface Track {\n  label: string;\n  url: string;\n  shift: number;\n  cues: Cue[] | null;\n  loading: Promise<void> | null;\n}\n\nconst USER: CommandContext = { source: 'user' };\n\nexport function subtitlesPlugin(o: SubtitlesPluginOptions = {}): Plugin {\n  return {\n    name: 'subtitles',\n    setup(ctx) {\n      const fetchText = o.fetch ?? fetch.bind(globalThis);\n      const optionList = o.subtitle ?? ctx.options.subtitle;\n      const defaultLabel = o.defaultSubtitle ?? ctx.options.defaultSubtitle;\n      const startOn = (o.subtitleStart ?? ctx.options.subtitleStart) !== false;\n      const shiftTenths = o.subshift ?? ctx.options.subshift ?? 0;\n\n      let tracks: Track[] = [];\n      let lastEnabled = 0;\n      let firstSource = true;\n      /** Bumped on every `new` and on dispose; in-flight loads from older generations are dropped. */\n      let generation = 0;\n\n      const toTrack = (ref: SubtitleRef): Track => ({ label: ref.label, url: ref.url, shift: shiftFromUrl(ref.url, shiftTenths), cues: null, loading: null });\n      const publish = () => ctx.store.set({ textTracks: tracks.map((t) => ({ label: t.label })) });\n\n      const load = (track: Track) => {\n        if (track.cues || track.loading) return;\n        const gen = generation;\n        track.loading = fetchText(track.url)\n          .then((response) => {\n            if (!response.ok) throw new Error(`HTTP ${response.status}`);\n            return response.text();\n          })\n          .then((text) => {\n            if (gen !== generation) return;\n            track.cues = shiftCues(parseSubtitles(text), track.shift);\n          })\n          .catch((e: unknown) => {\n            if (gen !== generation) return;\n            track.cues = [];\n            ctx.log.warn(`subtitles \"${track.url}\" failed to load`, e);\n            ctx.events.emit('loaderror', { url: track.url, error: { kind: 'network', message: String(e) } });\n          })\n          .finally(() => {\n            if (gen === generation) publish();\n          }); // new textTracks array → the layer re-renders\n      };\n\n      const select = (index: number, emit: boolean) => {\n        const i = index >= 0 && index < tracks.length ? index : -1;\n        if (i >= 0) {\n          lastEnabled = i;\n          load(tracks[i]!);\n        }\n        ctx.store.set({ textTrack: i });\n        if (emit) ctx.events.emit('subtitle', i >= 0 ? tracks[i]!.label : 'off');\n      };\n\n      /** Preference (memory) → default label → off if subtitleStart:false → first track. */\n      const initialIndex = () => {\n        for (const wanted of [ctx.store.get().preferredSubtitle, defaultLabel]) {\n          if (wanted === 'off') return -1;\n          const byLabel = wanted ? tracks.findIndex((t) => t.label === wanted) : -1;\n          if (byLabel >= 0) return byLabel;\n        }\n        return startOn && tracks.length ? 0 : -1;\n      };\n\n      ctx.registerComponent('subtitles-layer', (ui) => {\n        const line = h('div', { class: 'vp-subtitles-text' });\n        const el = h('div', { class: 'vp-subtitles', 'aria-live': 'polite' }, line);\n        ui.select(\n          (s) => {\n            const track = s.textTrack >= 0 ? tracks[s.textTrack] : undefined;\n            return track?.cues ? activeText(track.cues, s.currentTime) : '';\n          },\n          (text) => line.replaceChildren(...cueNodes(text)),\n          { immediate: true },\n        );\n        ui.select(controlsVisible, (raised) => el.classList.toggle('vp-subtitles-raised', raised), { immediate: true });\n        return { el };\n      });\n\n      const offs: Array<() => void> = [\n        ctx.addLayer({ type: 'subtitles-layer' }, 'below-ui'),\n\n        ctx.events.on('new', ({ spec }) => {\n          generation++;\n          const refs = [...spec.subtitles, ...(firstSource && optionList ? parseSubtitleList(optionList) : [])];\n          firstSource = false;\n          tracks = refs.map(toTrack);\n          lastEnabled = 0;\n          publish();\n          select(initialIndex(), false);\n        }),\n\n        ctx.commands.register('setTextTrack', ([index]) => select(index, true)),\n        ctx.commands.register('toggleSubtitles', () => {\n          if (!tracks.length) return;\n          if (ctx.store.get().textTrack >= 0) select(-1, true);\n          else select(lastEnabled < tracks.length ? lastEnabled : 0, true);\n        }),\n        ctx.commands.register('addSubtitle', ([label, url, selectIt]) => {\n          tracks.push(toTrack({ label, url }));\n          publish();\n          if (selectIt) select(tracks.length - 1, true);\n        }),\n\n        ctx.registerMenu({\n          id: 'subtitle',\n          label: 'subtitles',\n          order: 30,\n          visible: (s) => s.textTracks.length > 0,\n          options: (s) => [{ label: ctx.t('off'), value: -1 }, ...s.textTracks.map((t, i) => ({ label: t.label || String(i + 1), value: i }))],\n          current: (s) => s.textTrack,\n          select: (value) => ctx.commands.run('setTextTrack', [value as number], USER),\n        }),\n      ];\n      return () => {\n        generation++;\n        offs.forEach((off) => off());\n      };\n    },\n  };\n}\n","import { parseCues } from '../../shared/cues.js';\nimport { resolveUrl } from '../../shared/url.js';\n\nexport interface Thumb {\n  start: number;\n  end: number;\n  url: string;\n  /** Sprite rectangle; w/h are 0 for whole images. */\n  x: number;\n  y: number;\n  w: number;\n  h: number;\n}\n\nexport function parseThumbnails(text: string, baseUrl: string): Thumb[] {\n  return parseCues(text)\n    .map((cue) => {\n      const line = cue.text.split('\\n')[0]?.trim() ?? '';\n      const [path = '', hash = ''] = line.split('#');\n      const rect = hash.match(/xywh=(\\d+),(\\d+),(\\d+),(\\d+)/);\n      return {\n        start: cue.start,\n        end: cue.end,\n        url: path ? resolveUrl(path, baseUrl) : '',\n        x: rect ? Number(rect[1]) : 0,\n        y: rect ? Number(rect[2]) : 0,\n        w: rect ? Number(rect[3]) : 0,\n        h: rect ? Number(rect[4]) : 0,\n      };\n    })\n    .filter((t) => t.url);\n}\n\n/** Binary search over cues sorted by start. */\nexport function findThumb(thumbs: Thumb[], time: number): Thumb | null {\n  let lo = 0;\n  let hi = thumbs.length - 1;\n  while (lo <= hi) {\n    const mid = (lo + hi) >> 1;\n    const t = thumbs[mid]!;\n    if (time < t.start) hi = mid - 1;\n    else if (time >= t.end) lo = mid + 1;\n    else return t;\n  }\n  return null;\n}\n","import type { Plugin } from '../../types.js';\nimport { h } from '../../ui/dom.js';\nimport { clamp } from '../../shared/clamp.js';\nimport { formatTime } from '../../shared/time.js';\nimport { findThumb, parseThumbnails, type Thumb } from './parse.js';\n\ndeclare module '../../types.js' {\n  interface PlayerOptions {\n    /** WebVTT with sprite rectangles (`#xywh=`). PlayerJS: thumbnails. */\n    thumbnails?: string;\n  }\n  interface PlayerCommands {\n    /** Load a thumbnails VTT; an empty string clears them. */\n    setThumbnails(url: string): void;\n  }\n}\n\nexport interface ThumbnailsPluginOptions {\n  thumbnails?: string;\n  fetch?: typeof fetch;\n}\n\nconst FALLBACK_W = 160;\nconst FALLBACK_H = 90;\n\nexport function thumbnailsPlugin(o: ThumbnailsPluginOptions = {}): Plugin {\n  return {\n    name: 'thumbnails',\n    setup(ctx) {\n      const fetchText = o.fetch ?? fetch.bind(globalThis);\n      let thumbs: Thumb[] = [];\n      let request = 0;\n\n      const load = (url: string) => {\n        const id = ++request;\n        thumbs = [];\n        if (!url) return;\n        fetchText(url)\n          .then((r) => {\n            if (!r.ok) throw new Error(`HTTP ${r.status}`);\n            return r.text();\n          })\n          .then((text) => {\n            if (id === request) thumbs = parseThumbnails(text, url);\n          })\n          .catch((e: unknown) => {\n            if (id !== request) return;\n            ctx.log.warn(`thumbnails \"${url}\" failed to load`, e);\n            ctx.events.emit('loaderror', { url, error: { kind: 'network', message: String(e) } });\n          });\n      };\n\n      ctx.registerComponent('thumbnail-preview', (ui) => {\n        const image = h('div', { class: 'vp-thumb-image' });\n        const time = h('div', { class: 'vp-thumb-time' });\n        const el = h('div', { class: 'vp-thumb vp-hidden', 'aria-hidden': 'true' }, image, time);\n\n        ui.on('ui:timeline-hover', ({ time: t, rootX }) => {\n          const s = ui.store.get();\n          time.textContent = formatTime(t, s.duration);\n          const thumb = findThumb(thumbs, t);\n          let width = 0;\n          if (thumb) {\n            const w = thumb.w || FALLBACK_W;\n            const hgt = thumb.h || FALLBACK_H;\n            width = w;\n            image.hidden = false;\n            image.style.width = `${w}px`;\n            image.style.height = `${hgt}px`;\n            image.style.backgroundImage = `url(\"${thumb.url.replace(/\"/g, '%22')}\")`;\n            image.style.backgroundPosition = thumb.w ? `-${thumb.x}px -${thumb.y}px` : 'center';\n            image.style.backgroundSize = thumb.w ? 'auto' : 'cover';\n          } else {\n            image.hidden = true;\n          }\n          const half = (width || 48) / 2;\n          el.style.left = `${clamp(rootX - half, 4, Math.max(4, s.width - half * 2 - 4))}px`;\n          el.classList.remove('vp-hidden');\n        });\n        ui.on('ui:timeline-leave', () => el.classList.add('vp-hidden'));\n        return { el };\n      });\n\n      const offs: Array<() => void> = [\n        ctx.addLayer({ type: 'thumbnail-preview' }, 'above-ui'),\n        ctx.commands.register('setThumbnails', ([url]) => load(url)),\n      ];\n      const initial = o.thumbnails ?? ctx.options.thumbnails;\n      if (initial) load(initial);\n      return () => {\n        request++;\n        offs.forEach((off) => off());\n      };\n    },\n  };\n}\n","export interface PlaylistItem {\n  title?: string;\n  file?: string;\n  poster?: string;\n  /** `[Label]url,[Label]url` */\n  subtitle?: string;\n  thumbnails?: string;\n  id?: string;\n  /** Seconds, or 'continue' to keep the current position (e.g. switching dubs). */\n  start?: number | 'continue';\n  folder?: PlaylistItem[];\n  [key: string]: unknown;\n}\n\nexport interface FlatItem {\n  item: PlaylistItem;\n  index: number;\n  depth: number;\n}\n\nexport interface PlaylistState {\n  items: PlaylistItem[];\n  flat: FlatItem[];\n  index: number;\n  open: boolean;\n}\n\nexport function normalizePlaylist(data: unknown): PlaylistItem[] {\n  if (Array.isArray(data)) return data as PlaylistItem[];\n  if (data && typeof data === 'object') {\n    const wrapped = (data as { playlist?: unknown }).playlist;\n    if (Array.isArray(wrapped)) return wrapped as PlaylistItem[];\n    if ('file' in data || 'folder' in data) return [data as PlaylistItem];\n  }\n  throw new Error('Invalid playlist: expected an array of items');\n}\n\nexport function flattenPlaylist(items: PlaylistItem[]): FlatItem[] {\n  const flat: FlatItem[] = [];\n  const walk = (list: PlaylistItem[], depth: number) => {\n    for (const item of list) {\n      if (Array.isArray(item.folder)) walk(item.folder, depth + 1);\n      else if (item.file) flat.push({ item, index: flat.length, depth });\n    }\n  };\n  walk(items, 0);\n  return flat;\n}\n\n/** By id first (ids are often numeric strings in CMS data), then by index. */\nexport function findIndex(flat: FlatItem[], idOrIndex: string | number): number {\n  const byId = flat.findIndex((f) => f.item.id !== undefined && String(f.item.id) === String(idOrIndex));\n  if (byId >= 0) return byId;\n  if (typeof idOrIndex === 'number' || /^\\d+$/.test(idOrIndex)) {\n    const i = Number(idOrIndex);\n    return i >= 0 && i < flat.length ? i : -1;\n  }\n  return -1;\n}\n\n/** A JSON string, or a URL to a JSON (.txt/.json) playlist. */\nexport async function loadPlaylistInput(input: string, fetchFn: typeof fetch): Promise<PlaylistItem[]> {\n  const trimmed = input.trim();\n  if (trimmed.startsWith('[') || trimmed.startsWith('{')) return normalizePlaylist(JSON.parse(trimmed));\n  const response = await fetchFn(trimmed);\n  if (!response.ok) throw new Error(`HTTP ${response.status}`);\n  return normalizePlaylist(JSON.parse(await response.text()));\n}\n","import type { ComponentFactory } from '../../types.js';\nimport { h } from '../../ui/dom.js';\nimport { createIconButton } from '../../ui/button.js';\nimport type { PlaylistItem, PlaylistState } from './model.js';\n\nexport function playlistPanelComponent(onSelect: (index: number) => void, onClose: () => void): ComponentFactory {\n  return (ctx) => {\n    const list = h('div', { class: 'vp-playlist-list' });\n    const close = createIconButton(ctx, 'vp-playlist-close', onClose);\n    close.setIcon('back');\n    close.setLabel('close');\n    const el = h(\n      'div',\n      { class: 'vp-playlist', id: `${ctx.player.id}_playlist`, role: 'dialog', 'aria-label': ctx.t('playlist') },\n      h('div', { class: 'vp-playlist-header' }, close.el, h('span', { class: 'vp-playlist-heading' }, ctx.t('playlist'))),\n      list,\n    );\n    ctx.listen(el, 'click', (e) => e.stopPropagation());\n    ctx.listen(el, 'keydown', (e) => {\n      if ((e as KeyboardEvent).key !== 'Escape') return;\n      e.stopPropagation();\n      onClose();\n    });\n\n    const render = (pl: PlaylistState | undefined) => {\n      list.replaceChildren();\n      if (!pl) return;\n      const indexOf = new Map(pl.flat.map((f) => [f.item, f.index]));\n      const build = (items: PlaylistItem[], container: HTMLElement) => {\n        for (const item of items) {\n          if (Array.isArray(item.folder)) {\n            const details = h('details', { class: 'vp-playlist-folder', open: true }, h('summary', {}, String(item.title ?? '')));\n            build(item.folder, details);\n            container.append(details);\n          } else if (item.file) {\n            const index = indexOf.get(item)!;\n            const button = h(\n              'button',\n              { class: `vp-playlist-item${index === pl.index ? ' vp-active' : ''}`, type: 'button', 'aria-current': index === pl.index ? 'true' : undefined },\n              item.poster ? h('img', { class: 'vp-playlist-poster', src: String(item.poster), alt: '', loading: 'lazy' }) : null,\n              h('span', { class: 'vp-playlist-title' }, String(item.title ?? item.file)),\n            );\n            button.addEventListener('click', (e) => {\n              e.stopPropagation();\n              onSelect(index);\n            });\n            container.append(button);\n          }\n        }\n      };\n      build(pl.items, list);\n    };\n\n    ctx.select((s) => s.playlist, render, {\n      immediate: true,\n      equals: (a, b) => a?.items === b?.items && a?.index === b?.index,\n    });\n    // Keyboard focus follows the panel: into it on open (only if focus was in the player), back to the button on close.\n    ctx.select(\n      (s) => !!s.playlist?.open,\n      (open) => {\n        const active = el.ownerDocument.activeElement;\n        if (open) {\n          if (!active || !ctx.root.contains(active)) return;\n          // Deferred: the layout un-hides the panel in a later subscriber, and hidden elements can't take focus.\n          queueMicrotask(() => (list.querySelector<HTMLElement>('.vp-playlist-item.vp-active') ?? list.querySelector<HTMLElement>('.vp-playlist-item'))?.focus());\n        } else if (active && el.contains(active)) {\n          ctx.root.querySelector<HTMLElement>('.vp-playlist-button')?.focus();\n        }\n      },\n    );\n    return { el };\n  };\n}\n","import type { Plugin, SourceSpecInput } from '../../types.js';\nimport { isPlaylistInput, isSourceSpecInput, parseSource, parseSubtitleList } from '../../source/parse.js';\nimport { createIconButton } from '../../ui/button.js';\nimport { findIndex, flattenPlaylist, loadPlaylistInput, normalizePlaylist, type PlaylistItem, type PlaylistState } from './model.js';\nimport { playlistPanelComponent } from './panel.js';\n\nexport type { PlaylistItem, PlaylistState } from './model.js';\n\ndeclare module '../../types.js' {\n  interface PlayerState {\n    playlist?: PlaylistState;\n    autonext?: boolean;\n    playlistLoop?: boolean;\n  }\n  interface PlayerOptions {\n    /** Play the next item at the end (default true). */\n    autonext?: boolean;\n    /** Wrap around at the ends. PlayerJS: playlistloop. */\n    playlistLoop?: boolean;\n    /** Item id to start with. PlayerJS: plstart. */\n    plstart?: string;\n    /** Keep the panel closed initially (default true). PlayerJS: hideplaylist. */\n    hidePlaylist?: boolean;\n  }\n  interface PlayerCommands {\n    next(): void;\n    prev(): void;\n    playItem(idOrIndex: string | number, autoplay?: boolean): void;\n    push(items: PlaylistItem[]): void;\n    setPlaylist(input: string | PlaylistItem[]): void;\n    togglePlaylist(): void;\n    setAutonext(on: boolean): void;\n    setPlaylistLoop(on: boolean): void;\n  }\n}\n\nexport interface PlaylistPluginOptions {\n  autonext?: boolean;\n  playlistLoop?: boolean;\n  plstart?: string;\n  hidePlaylist?: boolean;\n  fetch?: typeof fetch;\n}\n\nexport function playlistPlugin(o: PlaylistPluginOptions = {}): Plugin {\n  return {\n    name: 'playlist',\n    setup(ctx) {\n      const fetchFn = o.fetch ?? fetch.bind(globalThis);\n      const startOpen = (o.hidePlaylist ?? ctx.options.hidePlaylist ?? true) === false;\n      let plstart = o.plstart ?? ctx.options.plstart;\n      let itemThumbs = false;\n      /** True while the plugin itself issues `load`, so the before-hook can tell it from a direct load. */\n      let internal = false;\n      /** The exact input `playIndex` last passed to `load`; `reload` replays it and must not drop the playlist. */\n      let lastItemInput: SourceSpecInput | null = null;\n      /** Bumped by every navigation or direct load; deferred steps (autonext) check it before running. */\n      let epoch = 0;\n      let cancelPlay: (() => void) | null = null;\n      ctx.store.set({ autonext: o.autonext ?? ctx.options.autonext ?? true, playlistLoop: o.playlistLoop ?? ctx.options.playlistLoop ?? false });\n\n      const current = () => ctx.store.get().playlist;\n      const setOpen = (open: boolean) => {\n        const pl = current();\n        if (pl) ctx.store.set({ playlist: { ...pl, open } });\n      };\n\n      /** Spec §3.4: play after the provider loaded the item; cancelled by the next load or an error. */\n      const playAfterLoad = () => {\n        cancelPlay?.();\n        const offs: Array<() => void> = [];\n        const cleanup = () => {\n          offs.forEach((off) => off());\n          if (cancelPlay === cleanup) cancelPlay = null;\n        };\n        cancelPlay = cleanup;\n        offs.push(\n          ctx.events.once('metadata', () => {\n            cleanup();\n            ctx.player.play().catch((e) => ctx.log.warn('playlist play rejected', e));\n          }),\n          ctx.events.once('new', cleanup),\n          ctx.events.once('error', cleanup),\n        );\n      };\n\n      const playIndex = (index: number, autoplay: boolean) => {\n        const pl = current();\n        const entry = pl?.flat[index];\n        if (!pl || !entry) return;\n        epoch++;\n        const item = entry.item;\n        const startTime = item.start === 'continue' ? ctx.store.get().currentTime : typeof item.start === 'number' ? item.start : undefined;\n        ctx.store.set({ playlist: { ...pl, index } });\n        ctx.commands.run('setTitle', [item.title !== undefined ? String(item.title) : '']);\n        ctx.commands.run('setPoster', [item.poster !== undefined ? String(item.poster) : '']);\n        if (ctx.commands.has('setThumbnails') && (item.thumbnails || itemThumbs)) {\n          itemThumbs = !!item.thumbnails;\n          ctx.commands.run('setThumbnails', [item.thumbnails ? String(item.thumbnails) : (ctx.options.thumbnails ?? '')]);\n        }\n        const spec = parseSource(String(item.file), { qualities: ctx.options.qualities });\n        const input: SourceSpecInput = {\n          ...spec,\n          subtitles: [...spec.subtitles, ...(item.subtitle ? parseSubtitleList(String(item.subtitle)) : [])],\n        };\n        const start = startTime ?? spec.start;\n        if (start !== undefined) input.start = start;\n        else delete input.start;\n        lastItemInput = input;\n        internal = true;\n        try {\n          ctx.commands.run('load', [input]);\n        } finally {\n          internal = false;\n        }\n        if (autoplay) playAfterLoad();\n      };\n\n      const setItems = (items: PlaylistItem[], load = true) => {\n        const flat = flattenPlaylist(items);\n        ctx.store.set({ playlist: { items, flat, index: -1, open: current()?.open ?? startOpen } });\n        ctx.events.emit('playlist', items);\n        if (!load || !flat.length) return;\n        const startIndex = plstart !== undefined ? Math.max(0, findIndex(flat, plstart)) : 0;\n        plstart = undefined;\n        playIndex(startIndex, false);\n      };\n\n      let request = 0;\n      const open = (input: string | PlaylistItem[]) => {\n        const id = ++request;\n        const loading = typeof input === 'string' ? loadPlaylistInput(input, fetchFn) : Promise.resolve().then(() => normalizePlaylist(input));\n        loading.then((items) => {\n          if (id === request) setItems(items);\n        }).catch((e: unknown) => {\n          ctx.log.warn('playlist failed to load', e);\n          ctx.events.emit('loaderror', { url: typeof input === 'string' ? input : '', error: { kind: 'network', message: String(e) } });\n        });\n      };\n\n      const neighbour = (step: 1 | -1): number | null => {\n        const pl = current();\n        if (!pl || !pl.flat.length) return null;\n        const next = pl.index + step;\n        if (next >= 0 && next < pl.flat.length) return next;\n        return ctx.store.get().playlistLoop ? (next + pl.flat.length) % pl.flat.length : null;\n      };\n\n      // Components\n      ctx.registerComponent('prev', (ui) => {\n        const b = createIconButton(ui, 'vp-prev', () => ui.user('prev'));\n        b.setIcon('prev');\n        b.setLabel('prev');\n        return { el: b.el };\n      });\n      ctx.registerComponent('next', (ui) => {\n        const b = createIconButton(ui, 'vp-next', () => ui.user('next'));\n        b.setIcon('next');\n        b.setLabel('next');\n        return { el: b.el };\n      });\n      ctx.registerComponent('playlist-button', (ui) => {\n        const b = createIconButton(ui, 'vp-playlist-button', () => ui.user('togglePlaylist'));\n        b.setIcon('playlist');\n        b.setLabel('playlist');\n        b.el.setAttribute('aria-controls', `${ui.player.id}_playlist`);\n        ui.select((s) => !!s.playlist?.open, (isOpen) => b.el.setAttribute('aria-expanded', String(isOpen)), { immediate: true });\n        return { el: b.el };\n      });\n      ctx.registerComponent(\n        'playlist-panel',\n        playlistPanelComponent(\n          (index) => {\n            setOpen(false);\n            playIndex(index, true);\n          },\n          () => setOpen(false),\n        ),\n      );\n\n      // Hide rules\n      ctx.registerHideRule('first-item', () => ({\n        test: (s) => !s.playlist || s.playlist.flat.length < 2 || (s.playlist.index <= 0 && !s.playlistLoop),\n      }));\n      ctx.registerHideRule('last-item', () => ({\n        test: (s) => !s.playlist || s.playlist.flat.length < 2 || (s.playlist.index >= s.playlist.flat.length - 1 && !s.playlistLoop),\n      }));\n      ctx.registerHideRule('no-playlist', () => ({ test: (s) => !s.playlist || s.playlist.flat.length < 2 }));\n      ctx.registerHideRule('playlist-closed', () => ({ test: (s) => !s.playlist?.open }));\n\n      const offs: Array<() => void> = [\n        ctx.addLayer({ type: 'playlist-panel', hide: ['playlist-closed'] }, 'above-ui'),\n\n        ctx.commands.before('load', ([input]) => {\n          if (!isPlaylistInput(input)) {\n            // Invalid input is rejected by the media controller and must not drop the playlist.\n            if (internal || input === lastItemInput || (typeof input !== 'string' && !isSourceSpecInput(input))) return;\n            // A direct load supersedes a playlist that is still loading, and makes the current one stale.\n            request++;\n            epoch++;\n            if (current()) ctx.store.set({ playlist: undefined });\n            return;\n          }\n          open(input as string | PlaylistItem[]); // normalizePlaylist also unwraps item / `{ playlist }` objects\n          return false;\n        }),\n\n        ctx.commands.register('setPlaylist', ([input]) => open(input)),\n        ctx.commands.register('playItem', ([idOrIndex, autoplay = true]) => {\n          const pl = current();\n          if (!pl) return;\n          const index = findIndex(pl.flat, idOrIndex);\n          if (index >= 0) playIndex(index, autoplay);\n        }),\n        ctx.commands.register('next', () => {\n          const index = neighbour(1);\n          if (index === null) return;\n          playIndex(index, true);\n          ctx.events.emit('next');\n        }),\n        ctx.commands.register('prev', () => {\n          const index = neighbour(-1);\n          if (index === null) return;\n          playIndex(index, true);\n          ctx.events.emit('previous');\n        }),\n        ctx.commands.register('push', ([items]) => {\n          request++; // supersedes an in-flight setPlaylist\n          const pl = current();\n          const added = normalizePlaylist(items);\n          if (!pl) {\n            // Don't hijack a player that already has a source.\n            setItems(added, ctx.store.get().status === 'idle');\n            return;\n          }\n          const merged = [...pl.items, ...added];\n          ctx.store.set({ playlist: { ...pl, items: merged, flat: flattenPlaylist(merged) } });\n          ctx.events.emit('playlist', merged);\n        }),\n        ctx.commands.register('togglePlaylist', () => setOpen(!current()?.open)),\n        ctx.commands.register('setAutonext', ([on]) => ctx.store.set({ autonext: on })),\n        ctx.commands.register('setPlaylistLoop', ([on]) => ctx.store.set({ playlistLoop: on })),\n\n        ctx.events.on('end', () => {\n          if (!ctx.store.get().autonext) return;\n          // Defer so every other `end` handler (e.g. memory forgetting the finished item) runs first.\n          const mark = epoch;\n          queueMicrotask(() => {\n            if (mark !== epoch || !ctx.store.get().autonext) return;\n            const index = neighbour(1);\n            if (index !== null) playIndex(index, true);\n          });\n        }),\n      ];\n\n      return () => {\n        request++;\n        epoch++;\n        cancelPlay?.();\n        offs.forEach((off) => off());\n      };\n    },\n  };\n}\n","import { createWheelStepper } from '../ui/wheel.js';\nimport type { CommandArgs, CommandContext, CommandName, Plugin } from '../types.js';\n\nexport interface HotkeysOptions {\n  seekStep?: number;\n  volumeStep?: number;\n  enter?: boolean;\n  numbers?: boolean;\n  wheel?: boolean;\n  /** Also handle keys on the document while the pointer is over the player. */\n  global?: boolean;\n}\n\ndeclare module '../types.js' {\n  interface PlayerOptions {\n    hotkeys?: HotkeysOptions | false;\n  }\n}\n\nconst USER: CommandContext = { source: 'user' };\nconst DEFAULTS: Required<HotkeysOptions> = { seekStep: 5, volumeStep: 0.1, enter: false, numbers: true, wheel: true, global: false };\nconst NO_WHEEL = '[role=\"menu\"], .vp-playlist, .vp-slider, .vp-timeline';\nconst TEXT_INPUT = 'input, textarea, select, [contenteditable=\"\"], [contenteditable=\"true\"]';\n\nexport function hotkeysPlugin(o?: HotkeysOptions | false): Plugin {\n  return {\n    name: 'hotkeys',\n    setup(ctx) {\n      if (o === false || ctx.options.hotkeys === false) return;\n      const cfg: Required<HotkeysOptions> = { ...DEFAULTS, ...(ctx.options.hotkeys || {}), ...(o ?? {}) };\n      let hovered = false;\n\n      const user = <K extends CommandName>(name: K, ...args: CommandArgs<K>) => {\n        const result = ctx.commands.run(name, args, USER);\n        if (result instanceof Promise) result.catch((e) => ctx.log.warn(`hotkey \"${name}\" rejected`, e));\n      };\n\n      const stepWheel = createWheelStepper();\n\n      const actionFor = (e: KeyboardEvent): (() => void) | null => {\n        const code = e.code || e.key;\n        switch (code) {\n          case 'Space':\n          case ' ':\n            return () => user('toggle');\n          case 'Enter':\n            return cfg.enter ? () => user('toggle') : null;\n          case 'KeyF':\n            return () => user('toggleFullscreen');\n          case 'KeyM':\n            return () => user('toggleMute');\n          case 'ArrowLeft':\n            return () => user('seek', `-${cfg.seekStep}`);\n          case 'ArrowRight':\n            return () => user('seek', `+${cfg.seekStep}`);\n          case 'ArrowUp':\n            return () => user('setVolume', `+${cfg.volumeStep}`);\n          case 'ArrowDown':\n            return () => user('setVolume', `-${cfg.volumeStep}`);\n        }\n        const digit = code.match(/^(?:Digit|Numpad)(\\d)$/);\n        if (digit && cfg.numbers) {\n          const duration = ctx.store.get().duration;\n          if (!(duration > 0)) return null;\n          const n = Number(digit[1]);\n          return () => user('seek', (duration * n) / 10);\n        }\n        return null;\n      };\n\n      const onKey = (e: KeyboardEvent) => {\n        if (e.defaultPrevented || e.ctrlKey || e.metaKey || e.altKey) return;\n        if (e.repeat && !(e.code || e.key).startsWith('Arrow')) return;\n        const target = e.target as Element | null;\n        if (target?.closest?.(TEXT_INPUT) || target?.closest?.('[role=\"menu\"]')) return;\n        const code = e.code || e.key;\n        if ((code === 'Space' || code === ' ' || code === 'Enter') && target?.closest?.('button')) return;\n        const action = actionFor(e);\n        if (!action) return;\n        e.preventDefault();\n        action();\n      };\n\n      const onDocumentKey = (e: KeyboardEvent) => {\n        if (!hovered || ctx.root.contains(e.target as Node)) return;\n        onKey(e);\n      };\n\n      const onWheel = (e: WheelEvent) => {\n        const state = ctx.store.get();\n        if (!cfg.wheel || !state.fullscreen || e.defaultPrevented || e.deltaY === 0) return;\n        if ((e.target as Element | null)?.closest?.(NO_WHEEL)) return;\n        e.preventDefault();\n        const step = stepWheel(e);\n        if (step === 1) user('setVolume', `+${cfg.volumeStep}`);\n        else if (step === -1 && !state.muted) user('setVolume', `-${cfg.volumeStep}`);\n      };\n\n      const onEnter = () => (hovered = true);\n      const onLeave = () => (hovered = false);\n\n      ctx.root.addEventListener('keydown', onKey);\n      ctx.root.addEventListener('wheel', onWheel, { passive: false });\n      ctx.root.addEventListener('pointerenter', onEnter);\n      ctx.root.addEventListener('pointerleave', onLeave);\n      if (cfg.global) document.addEventListener('keydown', onDocumentKey);\n\n      return () => {\n        ctx.root.removeEventListener('keydown', onKey);\n        ctx.root.removeEventListener('wheel', onWheel);\n        ctx.root.removeEventListener('pointerenter', onEnter);\n        ctx.root.removeEventListener('pointerleave', onLeave);\n        document.removeEventListener('keydown', onDocumentKey);\n      };\n    },\n  };\n}\n","import type { Plugin } from '../types.js';\n\ndeclare module '../types.js' {\n  interface PlayerOptions {\n    /** Retry muted when the browser blocks autoplay with sound (default true). */\n    autoplayMuteFallback?: boolean;\n  }\n}\n\nexport interface AutoplayPluginOptions {\n  muteFallback?: boolean;\n}\n\nconst isNotAllowed = (e: unknown) => (e as { name?: string } | null)?.name === 'NotAllowedError';\n\nexport function autoplayPlugin(o: AutoplayPluginOptions = {}): Plugin {\n  return {\n    name: 'autoplay',\n    setup(ctx) {\n      if (!ctx.options.autoplay) return;\n      const muteFallback = o.muteFallback ?? ctx.options.autoplayMuteFallback ?? true;\n      let armed = false;\n      let firstSource = true;\n      let mutedByAutoplay = false;\n\n      const attempt = () => {\n        ctx.player.play().catch((err) => {\n          if (muteFallback && isNotAllowed(err) && !ctx.store.get().muted) {\n            mutedByAutoplay = true;\n            ctx.commands.run('mute', []);\n            ctx.player.play().catch((e) => ctx.log.warn('muted autoplay failed', e));\n          } else {\n            ctx.log.warn('autoplay failed', err);\n          }\n        });\n      };\n\n      const offs = [\n        ctx.events.on('new', () => {\n          armed = firstSource;\n          firstSource = false;\n        }),\n        ctx.events.on('metadata', () => {\n          if (!armed) return;\n          armed = false;\n          attempt();\n        }),\n        ctx.events.on('unmute', () => {\n          mutedByAutoplay = false;\n        }),\n        ctx.commands.before('toggle', (_args, c) => {\n          if (!mutedByAutoplay || c.source !== 'user') return;\n          mutedByAutoplay = false;\n          const status = ctx.store.get().status;\n          if (status !== 'playing' && status !== 'loading') return; // e.g. paused: a plain toggle\n          ctx.commands.run('unmute', []);\n          return false;\n        }),\n      ];\n      return () => offs.forEach((off) => off());\n    },\n  };\n}\n","/** 32-bit FNV-1a hash of a string (UTF-16 code units), as 8 lowercase hex digits. */\nexport function fnv1a(str: string): string {\n  let h = 0x811c9dc5;\n  for (let i = 0; i < str.length; i++) {\n    h ^= str.charCodeAt(i);\n    h = Math.imul(h, 0x01000193);\n  }\n  return (h >>> 0).toString(16).padStart(8, '0');\n}\n","import type { CommandContext, Plugin } from '../types.js';\nimport { sourceKey } from '../source/parse.js';\nimport { fnv1a } from '../shared/hash.js';\n\nexport interface MemoryOptions {\n  position?: boolean;\n  volume?: boolean;\n  quality?: boolean;\n  speed?: boolean;\n  subtitle?: boolean;\n  audio?: boolean;\n  /** How many saved positions to keep (oldest are evicted). Default 100. */\n  maxPositions?: number;\n  /** Defaults to window.localStorage; `null` disables persistence. */\n  storage?: Storage | null;\n}\n\ndeclare module '../types.js' {\n  interface PlayerOptions {\n    memory?: Omit<MemoryOptions, 'storage'> | false;\n    /** Stable id for remembering the position. PlayerJS: cuid. */\n    cuid?: string;\n  }\n  interface PlayerState {\n    cuid?: string;\n  }\n  interface PlayerCommands {\n    setCuid(id: string): void;\n  }\n}\n\nconst KEYS = {\n  volume: 'vp:volume',\n  muted: 'vp:muted',\n  speed: 'vp:speed',\n  quality: 'vp:quality',\n  audio: 'vp:audio',\n  subtitle: 'vp:subtitle',\n} as const;\nconst INDEX_KEY = 'vp:t:index';\nconst DEFAULT_MAX_POSITIONS = 100;\nconst SAVE_EVERY_SECONDS = 5;\n\n/**\n * Whether to resume from a saved position.\n * @param saved    saved playback position, seconds\n * @param duration duration recorded with the position (NaN when unknown)\n */\nexport function shouldRestorePosition(saved: number, duration: number): boolean {\n  // Reference rule chosen by the project owner.\n  return saved > 5 && (!(duration > 0) || saved < duration - 10);\n}\n\nconst explicit = (c: CommandContext) => c.source !== 'internal';\n\n/** Reading `localStorage` itself throws SecurityError in opaque origins (sandboxed iframes, blocked storage). */\nfunction defaultStorage(): Storage | null {\n  try {\n    return typeof localStorage !== 'undefined' ? localStorage : null;\n  } catch {\n    return null;\n  }\n}\n\nexport function memoryPlugin(o: MemoryOptions = {}): Plugin {\n  return {\n    name: 'memory',\n    setup(ctx) {\n      if (ctx.options.memory === false) return;\n      const cfg = { position: true, volume: true, quality: true, speed: true, subtitle: true, audio: true, ...(ctx.options.memory || {}), ...o };\n      const storage = o.storage !== undefined ? o.storage : defaultStorage();\n\n      const get = (key: string): string | null => {\n        try {\n          return storage?.getItem(key) ?? null;\n        } catch {\n          return null;\n        }\n      };\n      const set = (key: string, value: string) => {\n        try {\n          storage?.setItem(key, value);\n        } catch {\n          /* private mode or quota exceeded */\n        }\n      };\n      const remove = (key: string) => {\n        try {\n          storage?.removeItem(key);\n        } catch {\n          /* ignore */\n        }\n      };\n      const num = (value: string | null) => {\n        if (value === null) return null;\n        const n = Number(value);\n        return Number.isFinite(n) ? n : null;\n      };\n      const readPosition = (key: string): { t: number; d: number } | null => {\n        try {\n          const value = JSON.parse(get(key) ?? 'null') as { t?: unknown; d?: unknown } | null;\n          return value && typeof value.t === 'number' ? { t: value.t, d: typeof value.d === 'number' ? value.d : NaN } : null;\n        } catch {\n          return null;\n        }\n      };\n\n      ctx.store.set({ cuid: ctx.options.cuid });\n      const saved = {\n        volume: num(get(KEYS.volume)),\n        muted: get(KEYS.muted),\n        speed: num(get(KEYS.speed)),\n        subtitle: get(KEYS.subtitle),\n      };\n      let positionKey: string | null = null;\n      let lastSaved = -Infinity;\n\n      const maxPositions = Math.max(1, Math.floor(cfg.maxPositions ?? DEFAULT_MAX_POSITIONS));\n      const readIndex = (): string[] => {\n        try {\n          const value: unknown = JSON.parse(get(INDEX_KEY) ?? '[]');\n          return Array.isArray(value) ? value.filter((k): k is string => typeof k === 'string') : [];\n        } catch {\n          return [];\n        }\n      };\n      const writeIndex = (index: string[]) => set(INDEX_KEY, JSON.stringify(index));\n\n      const savePosition = () => {\n        const s = ctx.store.get();\n        if (!positionKey || s.live || !(s.currentTime > 0)) return;\n        lastSaved = s.currentTime;\n        set(positionKey, JSON.stringify({ t: s.currentTime, d: s.duration }));\n        const index = readIndex().filter((k) => k !== positionKey);\n        index.push(positionKey);\n        while (index.length > maxPositions) remove(index.shift()!);\n        writeIndex(index);\n      };\n      const forgetPosition = () => {\n        if (!positionKey) return;\n        remove(positionKey);\n        const index = readIndex();\n        if (index.includes(positionKey)) writeIndex(index.filter((k) => k !== positionKey));\n      };\n\n      const offs: Array<() => void> = [\n        ctx.commands.register('setCuid', ([id]) => ctx.store.set({ cuid: id })),\n\n        ctx.events.on('init', () => {\n          // Apply the snapshot taken in setup: other plugins' init handlers (e.g. speed's defaultSpeed)\n          // may already have fired change events that this plugin persisted.\n          if (cfg.volume) {\n            if (saved.volume !== null) ctx.commands.run('setVolume', [saved.volume]);\n            if (saved.muted === '1') ctx.commands.run('mute', []);\n          }\n          if (cfg.speed && saved.speed !== null && saved.speed > 0) ctx.commands.run('setRate', [saved.speed]);\n          if (cfg.subtitle && saved.subtitle !== null) ctx.store.set({ preferredSubtitle: saved.subtitle });\n        }),\n\n        ctx.addSourceTransform((spec, sel) => {\n          let next = sel;\n          const cuid = ctx.store.get().cuid;\n          const id = cuid ?? `h${fnv1a(`${location.pathname}#${ctx.player.id}#${sourceKey(spec)}`)}`;\n          positionKey = cfg.position ? `vp:t:${id}` : null;\n          lastSaved = -Infinity;\n          if (positionKey) {\n            const saved = readPosition(positionKey);\n            if (saved && shouldRestorePosition(saved.t, saved.d)) next = { ...next, start: saved.t };\n          }\n          if (cfg.quality) {\n            const label = get(KEYS.quality);\n            const index = label === null ? -1 : spec.qualities.findIndex((q) => q.label === label);\n            if (index >= 0) next = { ...next, quality: index };\n          }\n          if (cfg.audio) {\n            const label = get(KEYS.audio);\n            const tracks = spec.qualities[next.quality]?.tracks ?? [];\n            const index = label === null ? -1 : tracks.findIndex((t) => t.label === label);\n            if (index >= 0) next = { ...next, audio: index };\n          }\n          return next;\n        }),\n\n        ctx.events.on('time', (t) => {\n          if (Math.abs(t - lastSaved) >= SAVE_EVERY_SECONDS) savePosition();\n        }),\n        ctx.events.on('pause', savePosition),\n        ctx.events.on('end', forgetPosition),\n\n        ctx.events.on('volume', (v) => {\n          if (cfg.volume) set(KEYS.volume, String(v));\n        }),\n        ctx.commands.before('mute', (_args, c) => {\n          if (cfg.volume && explicit(c)) set(KEYS.muted, '1');\n        }),\n        ctx.commands.before('toggleMute', (_args, c) => {\n          if (cfg.volume && explicit(c)) set(KEYS.muted, ctx.store.get().muted ? '0' : '1');\n        }),\n        ctx.events.on('unmute', () => {\n          if (cfg.volume) set(KEYS.muted, '0');\n        }),\n        ctx.events.on('speed', (rate) => {\n          if (cfg.speed) set(KEYS.speed, String(rate));\n        }),\n        ctx.events.on('quality', (label) => {\n          if (cfg.quality) set(KEYS.quality, label);\n        }),\n        ctx.events.on('audiotrack', (label) => {\n          if (cfg.audio) set(KEYS.audio, label);\n        }),\n        ctx.events.on('subtitle', (label) => {\n          if (cfg.subtitle) set(KEYS.subtitle, label);\n        }),\n      ];\n      return () => offs.forEach((off) => off());\n    },\n  };\n}\n","import type { CommandContext, CommandName, Plugin } from '../types.js';\n\ndeclare module '../types.js' {\n  interface PlayerOptions {\n    /** `false` disables lock-screen / media keys integration. */\n    mediasession?: boolean;\n  }\n}\n\ntype Handler = (details?: { seekTime?: number; seekOffset?: number }) => void;\nconst USER: CommandContext = { source: 'user' };\nconst ACTIONS = ['play', 'pause', 'seekto', 'seekbackward', 'seekforward', 'previoustrack', 'nexttrack'] as const;\n\n/** The plugin instance (player) that currently controls the page-wide media session. */\nlet owner: object | null = null;\n\nexport function mediaSessionPlugin(): Plugin {\n  return {\n    name: 'mediasession',\n    setup(ctx) {\n      if (ctx.options.mediasession === false || typeof navigator === 'undefined' || !('mediaSession' in navigator)) return;\n      const session = navigator.mediaSession;\n      const run = (name: CommandName, ...args: unknown[]) => {\n        const result = (ctx.commands.run as unknown as (n: string, a: unknown[], c: CommandContext) => unknown)(name, args, USER);\n        if (result instanceof Promise) result.catch((e) => ctx.log.warn('media session action rejected', e));\n      };\n      const handlers: Record<(typeof ACTIONS)[number], Handler | null> = {\n        play: () => run('play'),\n        pause: () => run('pause'),\n        seekto: (d) => {\n          if (typeof d?.seekTime === 'number') run('seek', d.seekTime);\n        },\n        seekbackward: (d) => run('seek', `-${d?.seekOffset ?? 10}`),\n        seekforward: (d) => run('seek', `+${d?.seekOffset ?? 10}`),\n        previoustrack: ctx.commands.has('prev') ? () => run('prev' as CommandName) : null,\n        nexttrack: ctx.commands.has('next') ? () => run('next' as CommandName) : null,\n      };\n      const setHandler = (name: string, fn: Handler | null) => {\n        try {\n          session.setActionHandler(name as MediaSessionAction, fn as MediaSessionActionHandler | null);\n        } catch {\n          /* action not supported by this browser */\n        }\n      };\n      const token = {};\n      let lastState: MediaSessionPlaybackState = 'none';\n\n      const publishMetadata = () => {\n        if (owner !== token) return;\n        const s = ctx.store.get();\n        try {\n          session.metadata = new MediaMetadata({ title: s.title, artwork: s.poster ? [{ src: s.poster }] : [] });\n        } catch {\n          /* MediaMetadata missing */\n        }\n      };\n      const publishState = () => {\n        if (owner === token) session.playbackState = lastState;\n      };\n      const claim = () => {\n        if (owner === token) return;\n        owner = token;\n        for (const name of ACTIONS) setHandler(name, handlers[name]);\n        publishMetadata();\n        publishState();\n      };\n      if (owner === null) claim();\n\n      const offs = [\n        ctx.events.on('play', claim),\n        ctx.store.select((s) => `${s.title}\\n${s.poster}`, publishMetadata, { immediate: true }),\n        ctx.store.select(\n          (s) => s.status,\n          (status) => {\n            // 'loading' (buffering, source switch) keeps the previous state so the lock screen doesn't flicker.\n            if (status === 'playing') lastState = 'playing';\n            else if (status === 'paused' || status === 'ended') lastState = 'paused';\n            else if (status !== 'loading') lastState = 'none';\n            publishState();\n          },\n          { immediate: true },\n        ),\n      ];\n      return () => {\n        offs.forEach((off) => off());\n        if (owner !== token) return;\n        for (const name of ACTIONS) setHandler(name, null);\n        try {\n          session.metadata = null;\n        } catch {\n          /* ignore */\n        }\n        session.playbackState = 'none';\n        owner = null;\n      };\n    },\n  };\n}\n","import type { Plugin } from '../types.js';\nimport { qualityPlugin } from './quality.js';\nimport { speedPlugin } from './speed.js';\nimport { audioTracksPlugin } from './audiotracks.js';\nimport { subtitlesPlugin } from './subtitles/index.js';\nimport { thumbnailsPlugin } from './thumbnails/index.js';\nimport { playlistPlugin } from './playlist/index.js';\nimport { hotkeysPlugin } from './hotkeys.js';\nimport { autoplayPlugin } from './autoplay.js';\nimport { memoryPlugin } from './memory.js';\nimport { mediaSessionPlugin } from './mediasession.js';\n\n/**\n * All v1 plugins. Order matters:\n * - memory after quality/speed/subtitles/audiotracks (its transforms and init run later, so saved values win);\n * - memory precedes autoplay so saved mute/position are restored before autoplay plays;\n * - mediasession after playlist (prev/next commands must exist at setup).\n */\nexport function defaultPlugins(): Plugin[] {\n  return [\n    qualityPlugin(),\n    speedPlugin(),\n    audioTracksPlugin(),\n    subtitlesPlugin(),\n    thumbnailsPlugin(),\n    playlistPlugin(),\n    hotkeysPlugin(),\n    memoryPlugin(),\n    autoplayPlugin(),\n    mediaSessionPlugin(),\n  ];\n}\n\nexport { qualityPlugin, pickQuality } from './quality.js';\nexport { speedPlugin, DEFAULT_SPEEDS } from './speed.js';\nexport { audioTracksPlugin } from './audiotracks.js';\nexport { subtitlesPlugin } from './subtitles/index.js';\nexport { thumbnailsPlugin } from './thumbnails/index.js';\nexport { playlistPlugin, type PlaylistItem, type PlaylistState } from './playlist/index.js';\nexport { hotkeysPlugin, type HotkeysOptions } from './hotkeys.js';\nexport { autoplayPlugin } from './autoplay.js';\nexport { memoryPlugin, shouldRestorePosition } from './memory.js';\nexport { mediaSessionPlugin } from './mediasession.js';\n","import type { EventName } from '../types.js';\n\n/** Events forwarded to PlayerJS-style listeners (internal `ui:*` events are excluded). */\nexport const PLAYERJS_EVENTS: readonly EventName[] = [\n  'init', 'start', 'new', 'metadata', 'play', 'userplay', 'pause', 'userpause', 'stop', 'end', 'finish',\n  'time', 'quartile', 'duration', 'seek', 'userseek', 'mute', 'unmute', 'volume', 'quality', 'audiotrack',\n  'subtitle', 'speed', 'fullscreen', 'exitfullscreen', 'resize', 'ui', 'buffering', 'buffered', 'loaderror',\n  'error', 'playlist', 'next', 'previous', 'line', 'destroy',\n];\n","import type { EventBus, EventName } from '../types.js';\nimport { PLAYERJS_EVENTS } from '../api/events-list.js';\n\nconst PUBLIC = new Set<EventName>(PLAYERJS_EVENTS);\n\n/**\n * PlayerJS-style events: global `PlayerjsEvents(event, id, data)` and DOM CustomEvents on the container.\n * `init` is delivered in a microtask so handlers can already use the `new Playerjs(...)` result.\n */\nexport function bridgeEvents(events: EventBus, container: HTMLElement, id: string): () => void {\n  let active = true;\n  const deliver = (name: EventName, data: unknown) => {\n    const handler = (window as unknown as { PlayerjsEvents?: unknown }).PlayerjsEvents;\n    if (typeof handler === 'function') {\n      try {\n        handler(name, id, data);\n      } catch (e) {\n        console.error('[vp] PlayerjsEvents handler failed', e);\n      }\n    }\n    container.dispatchEvent(new CustomEvent(name, { detail: data }));\n  };\n  let pending: Array<[EventName, unknown]> | null = null;\n  const offAny = events.onAny((name, data) => {\n    if (!PUBLIC.has(name)) return;\n    if (pending) {\n      pending.push([name, data]);\n    } else if (name === 'init') {\n      const buffer: Array<[EventName, unknown]> = (pending = [[name, data]]);\n      queueMicrotask(() => {\n        if (!active) return;\n        pending = null;\n        for (const [n, d] of buffer) deliver(n, d);\n      });\n    } else {\n      deliver(name, data);\n    }\n  });\n  return () => {\n    active = false;\n    pending = null;\n    offAny();\n  };\n}\n","import type { EventBus, EventName } from '../types.js';\nimport { PLAYERJS_EVENTS } from '../api/events-list.js';\n\nconst PUBLIC = new Set<EventName>(PLAYERJS_EVENTS);\n\nexport interface PostMessageBridgeOptions {\n  api: (cmd: string, arg?: unknown) => unknown;\n  events: EventBus;\n  id: string;\n  /** Accept commands only from this origin and post events only to it. */\n  origin?: string;\n  win?: Window;\n}\n\n/** Iframe embedding: `{ api, set }` commands from the parent, `{ event, id, data }` events to the parent. */\nexport function bridgePostMessage(o: PostMessageBridgeOptions): () => void {\n  const win = o.win ?? window;\n  const parent = win.parent;\n\n  const onMessage = (e: MessageEvent) => {\n    if (e.source !== parent) return;\n    if (o.origin && e.origin !== o.origin) return;\n    const data = e.data as { api?: unknown; set?: unknown; id?: unknown } | null;\n    if (!data || typeof data !== 'object' || typeof data.api !== 'string') return;\n    if (typeof data.id === 'string' && data.id !== o.id) return;\n    try {\n      const answer = 'set' in data ? o.api(data.api, data.set) : o.api(data.api);\n      if (answer !== undefined && !(answer instanceof Promise)) {\n        (e.source as Window).postMessage({ event: data.api, answer, id: o.id }, !e.origin || e.origin === 'null' ? '*' : e.origin);\n      }\n    } catch (err) {\n      console.warn('[vp]', `postMessage command \"${data.api}\" failed`, err);\n    }\n  };\n  win.addEventListener('message', onMessage as EventListener);\n\n  const offEvents =\n    parent && parent !== win\n      ? o.events.onAny((name, data) => {\n          if (!PUBLIC.has(name)) return;\n          try {\n            parent.postMessage({ event: name, id: o.id, data }, o.origin ?? '*');\n          } catch {\n            /* non-cloneable payload */\n          }\n        })\n      : () => {};\n\n  return () => {\n    win.removeEventListener('message', onMessage as EventListener);\n    offEvents();\n  };\n}\n","import type { Logger, PlayerOptions, SourceInput, ThemeVars } from '../types.js';\nimport type { PlaylistItem } from '../plugins/playlist/index.js';\n\nexport interface PlayerjsOptions {\n  id: string;\n  /** A source string, or a playlist (array of items / `{ playlist }` object). */\n  file?: string | PlaylistItem[] | { playlist: PlaylistItem[] };\n  poster?: string;\n  title?: string;\n  nocontrols?: 0 | 1 | boolean;\n  /** Name of a global function called with the player id after init. */\n  ready?: string;\n  postmessage?: 0 | 1 | boolean;\n  postmessageOrigin?: string;\n  [key: string]: unknown;\n}\n\nexport const flag = (v: unknown) => v === true || v === 1 || v === '1' || v === 'true';\nconst num = (v: unknown) => {\n  const n = Number(v);\n  return Number.isFinite(n) ? n : undefined;\n};\nconst str = (v: unknown) => String(v);\n\ntype Mapper = (value: unknown, out: Partial<PlayerOptions>) => void;\nconst set =\n  <K extends keyof PlayerOptions>(key: K, convert: (v: unknown) => PlayerOptions[K]): Mapper =>\n  (value, out) => {\n    const converted = convert(value);\n    if (converted !== undefined) out[key] = converted;\n  };\nconst color =\n  (key: keyof ThemeVars): Mapper =>\n  (value, out) => {\n    out.theme = { ...out.theme, [key]: String(value) };\n  };\n\n/** The only place that knows PlayerJS option names. */\nconst TABLE: Record<string, Mapper> = {\n  id: set('container', str),\n  // Playlist arrays/objects pass through for the playlist plugin's load hook.\n  file: set('source', (v) => (typeof v === 'object' && v !== null ? (v as SourceInput) : str(v))),\n  poster: set('poster', str),\n  title: set('title', str),\n  // Not PlayerJS options: let compat embeds switch the UI language (default 'ru') and override labels.\n  lang: set('lang', (v) => (v === 'en' || v === 'ru' ? v : undefined)),\n  i18n: set('i18n', (v) => (typeof v === 'object' && v !== null ? (v as Record<string, string>) : undefined)),\n  autoplay: set('autoplay', flag),\n  loop: set('loop', flag),\n  volume: set('volume', num),\n  start: set('start', num),\n  end: set('end', num),\n  ratio: set('ratio', str),\n  default_quality: set('defaultQuality', str),\n  forbidden_quality: set('forbiddenQuality', str),\n  qualities: set('qualities', str),\n  default_audio: set('defaultAudio', str),\n  rename_audio: set('renameAudio', (v) => v as Record<string, string>),\n  default_speed: set('defaultSpeed', num),\n  default_subtitle: set('defaultSubtitle', str),\n  subtitle: set('subtitle', str),\n  subtitle_start: set('subtitleStart', flag),\n  subshift: set('subshift', num),\n  thumbnails: set('thumbnails', str),\n  autonext: set('autonext', flag),\n  playlistloop: set('playlistLoop', flag),\n  plstart: set('plstart', str),\n  hideplaylist: set('hidePlaylist', flag),\n  cuid: set('cuid', str),\n  hls: (value, out) => {\n    if (flag(value)) out.forceType = 'hls';\n  },\n  hlsconfig: set('hlsConfig', (v) => {\n    let parsed = v;\n    if (typeof v === 'string') {\n      try {\n        parsed = JSON.parse(v);\n      } catch {\n        console.warn('[vp] Playerjs: hlsconfig is not valid JSON; ignored');\n        return undefined;\n      }\n    }\n    if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n      console.warn('[vp] Playerjs: hlsconfig must be an object; ignored');\n      return undefined;\n    }\n    return parsed as Record<string, unknown>;\n  }),\n  log: set('log', flag),\n  color1: color('color1'),\n  color2: color('color2'),\n  color3: color('color3'),\n};\n\n/** Handled by the Playerjs class itself, not mapped to PlayerOptions. */\nconst COMPAT_ONLY = new Set(['nocontrols', 'ready', 'postmessage', 'postmessageOrigin']);\n\nexport function mapPlayerjsOptions(input: PlayerjsOptions, log: Logger): PlayerOptions {\n  if (!input || !input.id) throw new Error('[vp] Playerjs: the \"id\" option is required');\n  const out: Partial<PlayerOptions> = {};\n  for (const [key, value] of Object.entries(input)) {\n    if (value === undefined || COMPAT_ONLY.has(key)) continue;\n    if (Object.prototype.hasOwnProperty.call(TABLE, key)) TABLE[key]!(value, out);\n    else log.warn(`Playerjs: unknown option \"${key}\" ignored`);\n  }\n  return out as PlayerOptions;\n}\n","import type { Player, Plugin } from '../types.js';\nimport { createPlayerCore } from '../player.js';\nimport { createLogger } from '../core/logger.js';\nimport { defaultPlugins } from '../plugins/index.js';\nimport { bridgeEvents } from './events.js';\nimport { bridgePostMessage } from './postmessage.js';\nimport { flag, mapPlayerjsOptions, type PlayerjsOptions } from './options.js';\n\nexport type { PlayerjsOptions } from './options.js';\n\n/** Drop-in style facade: `new Playerjs({ id, file, ... })` + `player.api(cmd, arg)`. */\nexport class Playerjs {\n  readonly player: Player;\n\n  constructor(opts: PlayerjsOptions) {\n    const log = createLogger(flag(opts.log));\n    const options = mapPlayerjsOptions(opts, log);\n\n    // Installed as the first plugin so the bridges see `init`.\n    const compat: Plugin = {\n      name: 'playerjs-compat',\n      setup(ctx) {\n        const offs: Array<() => void> = [bridgeEvents(ctx.events, ctx.player.container, ctx.player.id)];\n        if (flag(opts.postmessage)) {\n          if (!opts.postmessageOrigin) {\n            ctx.log.warn('Playerjs: postmessage is enabled without postmessageOrigin, so any embedding page can control the player; set postmessageOrigin to restrict it');\n          }\n          offs.push(bridgePostMessage({ api: (cmd, arg) => ctx.player.api(cmd, arg), events: ctx.events, id: ctx.player.id, origin: opts.postmessageOrigin }));\n        }\n        if (typeof opts.ready === 'string') {\n          const name = opts.ready;\n          let active = true;\n          offs.push(() => {\n            active = false;\n          });\n          offs.push(\n            ctx.events.once('init', () => {\n              // After the constructor returned, so `ready` can use `var player = new Playerjs(...)`.\n              queueMicrotask(() => {\n                if (!active) return;\n                const fn = (window as unknown as Record<string, unknown>)[name];\n                if (typeof fn === 'function') {\n                  try {\n                    fn(ctx.player.id);\n                  } catch (e) {\n                    console.error('[vp] ready callback failed', e);\n                  }\n                } else ctx.log.warn(`Playerjs: ready function \"${name}\" not found`);\n              });\n            }),\n          );\n        }\n        return () => offs.forEach((off) => off());\n      },\n    };\n\n    if (flag(opts.nocontrols)) options.layout = { type: 'root', children: [{ type: 'media-click-layer' }] };\n    this.player = createPlayerCore({ lang: 'ru', ...options, plugins: [compat, ...defaultPlugins()] });\n  }\n\n  api(cmd: string, arg?: unknown): unknown {\n    return this.player.api(cmd, arg);\n  }\n}\n","import type { Player, PlayerOptions } from './types.js';\nimport { createPlayerCore } from './player.js';\nimport { defaultPlugins } from './plugins/index.js';\n\n/** Creates a player with all v1 plugins unless `options.plugins` is given. */\nexport function createPlayer(options: PlayerOptions): Player {\n  return createPlayerCore({ ...options, plugins: options.plugins ?? defaultPlugins() });\n}\n","import { Playerjs } from './compat/playerjs.js';\n\nexport * from './index.js';\n\nif (typeof window !== 'undefined') {\n  const w = window as unknown as { Playerjs?: unknown; PlayerjsAsync?: unknown };\n  w.Playerjs = Playerjs;\n  if (typeof w.PlayerjsAsync === 'function') {\n    try {\n      (w.PlayerjsAsync as () => void)();\n    } catch (e) {\n      console.error('[vp] PlayerjsAsync failed', e);\n    }\n  }\n}\n"],"mappings":"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"}