vidply 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/dist/vidply.esm.js +157 -362
- package/dist/vidply.esm.js.map +3 -3
- package/dist/vidply.esm.min.js +3 -3
- package/dist/vidply.esm.min.meta.json +9 -43
- package/dist/vidply.js +157 -362
- package/dist/vidply.js.map +3 -3
- package/dist/vidply.min.js +3 -3
- package/dist/vidply.min.meta.json +9 -43
- package/package.json +1 -1
- package/src/controls/CaptionManager.js +216 -218
- package/src/controls/ControlBar.js +144 -26
- package/src/controls/KeyboardManager.js +50 -13
- package/src/core/Player.js +994 -1004
package/dist/vidply.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/renderers/HTML5Renderer.js", "../src/index.js", "../src/utils/EventEmitter.js", "../src/utils/DOMUtils.js", "../src/utils/TimeUtils.js", "../src/icons/Icons.js", "../src/i18n/translations.js", "../src/i18n/i18n.js", "../src/controls/ControlBar.js", "../src/controls/CaptionManager.js", "../src/controls/KeyboardManager.js", "../src/controls/
|
|
4
|
-
"sourcesContent": ["/**\n * HTML5 Media Renderer\n */\n\nexport class HTML5Renderer {\n constructor(player) {\n this.player = player;\n this.media = player.element;\n }\n\n async init() {\n // Hide native controls\n this.media.controls = false;\n this.media.removeAttribute('controls');\n \n this.attachEvents();\n \n // Set preload\n this.media.preload = this.player.options.preload;\n \n // Load media\n this.media.load();\n }\n\n attachEvents() {\n // Playback events\n this.media.addEventListener('loadedmetadata', () => {\n this.player.state.duration = this.media.duration;\n this.player.emit('loadedmetadata');\n });\n\n this.media.addEventListener('play', () => {\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.emit('play');\n \n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n \n // Pause other players if enabled\n if (this.player.options.pauseOthersOnPlay) {\n this.pauseOtherPlayers();\n }\n });\n\n this.media.addEventListener('pause', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n \n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n });\n\n this.media.addEventListener('ended', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n \n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n \n // Handle loop\n if (this.player.options.loop) {\n this.player.seek(0);\n this.player.play();\n }\n });\n\n this.media.addEventListener('timeupdate', () => {\n this.player.state.currentTime = this.media.currentTime;\n this.player.emit('timeupdate', this.media.currentTime);\n \n if (this.player.options.onTimeUpdate) {\n this.player.options.onTimeUpdate.call(this.player, this.media.currentTime);\n }\n });\n\n this.media.addEventListener('volumechange', () => {\n this.player.state.volume = this.media.volume;\n this.player.state.muted = this.media.muted;\n this.player.emit('volumechange', this.media.volume);\n \n if (this.player.options.onVolumeChange) {\n this.player.options.onVolumeChange.call(this.player, this.media.volume);\n }\n });\n\n this.media.addEventListener('seeking', () => {\n this.player.state.seeking = true;\n this.player.emit('seeking');\n });\n\n this.media.addEventListener('seeked', () => {\n this.player.state.seeking = false;\n this.player.emit('seeked');\n });\n\n this.media.addEventListener('waiting', () => {\n this.player.state.buffering = true;\n this.player.emit('waiting');\n });\n\n this.media.addEventListener('canplay', () => {\n this.player.state.buffering = false;\n this.player.emit('canplay');\n });\n\n this.media.addEventListener('progress', () => {\n if (this.media.buffered.length > 0) {\n const buffered = this.media.buffered.end(this.media.buffered.length - 1);\n this.player.emit('progress', buffered);\n }\n });\n\n this.media.addEventListener('error', (e) => {\n this.player.handleError(this.media.error);\n });\n\n this.media.addEventListener('ratechange', () => {\n this.player.state.playbackSpeed = this.media.playbackRate;\n this.player.emit('ratechange', this.media.playbackRate);\n });\n }\n\n pauseOtherPlayers() {\n // Pause other VidPly instances\n const allPlayers = document.querySelectorAll('.vidply-player');\n allPlayers.forEach(playerEl => {\n if (playerEl !== this.player.container) {\n const video = playerEl.querySelector('video, audio');\n if (video && !video.paused) {\n video.pause();\n }\n }\n });\n }\n\n play() {\n const promise = this.media.play();\n \n if (promise !== undefined) {\n promise.catch(error => {\n this.player.log('Play failed:', error, 'warn');\n \n // If autoplay failed, try muted autoplay\n if (this.player.options.autoplay && !this.player.state.muted) {\n this.player.log('Retrying play with muted audio', 'info');\n this.media.muted = true;\n this.media.play().catch(err => {\n this.player.handleError(err);\n });\n }\n });\n }\n }\n\n pause() {\n this.media.pause();\n }\n\n seek(time) {\n this.media.currentTime = time;\n }\n\n setVolume(volume) {\n this.media.volume = volume;\n }\n\n setMuted(muted) {\n this.media.muted = muted;\n }\n\n setPlaybackSpeed(speed) {\n this.media.playbackRate = speed;\n }\n\n /**\n * Get available quality levels from source elements\n * @returns {Array} Array of quality objects with index, height, width, and src\n */\n getQualities() {\n const sources = Array.from(this.media.querySelectorAll('source'));\n \n if (sources.length <= 1) {\n return [];\n }\n\n return sources.map((source, index) => {\n // Try to extract quality from data attributes or label\n const label = source.getAttribute('data-quality') || source.getAttribute('label') || '';\n const height = source.getAttribute('data-height') || this.extractHeightFromLabel(label);\n const width = source.getAttribute('data-width') || '';\n \n return {\n index,\n height: height ? parseInt(height) : 0,\n width: width ? parseInt(width) : 0,\n src: source.src,\n type: source.type,\n name: label || (height ? `${height}p` : `Quality ${index + 1}`)\n };\n }).filter(q => q.height > 0); // Only return qualities with valid height\n }\n\n /**\n * Extract height from quality label (e.g., \"1080p\" -> 1080)\n * @param {string} label \n * @returns {number}\n */\n extractHeightFromLabel(label) {\n const match = label.match(/(\\d+)p/i);\n return match ? parseInt(match[1]) : 0;\n }\n\n /**\n * Switch to a specific quality level\n * @param {number} qualityIndex - Index of the quality level (-1 for auto, not applicable for HTML5)\n */\n switchQuality(qualityIndex) {\n const qualities = this.getQualities();\n \n if (qualityIndex < 0 || qualityIndex >= qualities.length) {\n this.player.log('Invalid quality index', 'warn');\n return;\n }\n\n const quality = qualities[qualityIndex];\n const currentTime = this.media.currentTime;\n const wasPlaying = !this.media.paused;\n\n // Store the current source for comparison\n const currentSrc = this.media.currentSrc;\n \n // Don't switch if already at this quality\n if (currentSrc === quality.src) {\n this.player.log('Already at this quality level', 'info');\n return;\n }\n\n this.player.log(`Switching to quality: ${quality.name}`, 'info');\n\n // Update the src\n this.media.src = quality.src;\n \n // Wait for the new source to load, then restore playback state\n const onLoadedMetadata = () => {\n this.media.removeEventListener('loadedmetadata', onLoadedMetadata);\n \n // Restore playback position\n this.media.currentTime = currentTime;\n \n // Resume playback if it was playing\n if (wasPlaying) {\n this.media.play().catch(err => {\n this.player.log('Failed to resume playback after quality switch', 'warn');\n });\n }\n \n // Emit quality change event\n this.player.emit('qualitychange', { quality: quality.name, index: qualityIndex });\n };\n\n this.media.addEventListener('loadedmetadata', onLoadedMetadata);\n this.media.load();\n }\n\n /**\n * Get current quality index\n * @returns {number}\n */\n getCurrentQuality() {\n const qualities = this.getQualities();\n const currentSrc = this.media.currentSrc;\n \n for (let i = 0; i < qualities.length; i++) {\n if (qualities[i].src === currentSrc) {\n return i;\n }\n }\n \n return 0; // Default to first quality if not found\n }\n\n destroy() {\n // Remove event listeners\n this.media.removeEventListener('loadedmetadata', () => {});\n this.media.removeEventListener('play', () => {});\n this.media.removeEventListener('pause', () => {});\n // ... (other listeners would be removed in a real implementation)\n }\n}\n\n", "/**\n * VidPly - Universal Video Player\n * Main Entry Point\n */\n\nimport { Player } from './core/Player.js';\nimport { PlaylistManager } from './features/PlaylistManager.js';\n\n// Auto-initialize players\nfunction initializePlayers() {\n const elements = document.querySelectorAll('[data-vidply]');\n \n elements.forEach(element => {\n // Parse options from data attribute (JSON format)\n const options = element.dataset.vidplyOptions \n ? JSON.parse(element.dataset.vidplyOptions)\n : {};\n \n // Parse individual data attributes and merge with options\n // This allows for easier HTML-based configuration\n const dataOptions = parseDataAttributes(element.dataset);\n const mergedOptions = { ...dataOptions, ...options };\n \n // Create player instance\n new Player(element, mergedOptions);\n });\n}\n\n// Helper function to parse data attributes into options\nfunction parseDataAttributes(dataset) {\n const options = {};\n \n // Map of data attribute names to option keys (camelCase conversion)\n const attributeMap = {\n // Sign Language\n 'signLanguageSrc': 'signLanguageSrc',\n 'signLanguageButton': 'signLanguageButton',\n 'signLanguagePosition': 'signLanguagePosition',\n \n // Audio Description\n 'audioDescriptionSrc': 'audioDescriptionSrc',\n 'audioDescriptionButton': 'audioDescriptionButton',\n \n // Other common options\n 'autoplay': 'autoplay',\n 'loop': 'loop',\n 'muted': 'muted',\n 'controls': 'controls',\n 'poster': 'poster',\n 'width': 'width',\n 'height': 'height',\n 'language': 'language',\n 'captions': 'captions',\n 'captionsDefault': 'captionsDefault',\n 'transcript': 'transcript',\n 'transcriptButton': 'transcriptButton',\n 'keyboard': 'keyboard',\n 'responsive': 'responsive',\n 'pipButton': 'pipButton',\n 'fullscreenButton': 'fullscreenButton'\n };\n \n // Parse each data attribute\n Object.keys(attributeMap).forEach(dataKey => {\n const optionKey = attributeMap[dataKey];\n const value = dataset[dataKey];\n \n if (value !== undefined) {\n // Convert string values to appropriate types\n if (value === 'true') {\n options[optionKey] = true;\n } else if (value === 'false') {\n options[optionKey] = false;\n } else if (!isNaN(value) && value !== '') {\n options[optionKey] = Number(value);\n } else {\n options[optionKey] = value;\n }\n }\n });\n \n return options;\n}\n\n// Auto-initialize on DOM ready\nif (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', initializePlayers);\n} else {\n initializePlayers();\n}\n\n// Export for manual initialization\nexport { Player, PlaylistManager };\nexport default Player;\n\n", "/**\n * Simple EventEmitter implementation\n */\n\nexport class EventEmitter {\n constructor() {\n this.events = {};\n }\n\n on(event, listener) {\n if (!this.events[event]) {\n this.events[event] = [];\n }\n this.events[event].push(listener);\n return this;\n }\n\n once(event, listener) {\n const onceListener = (...args) => {\n listener(...args);\n this.off(event, onceListener);\n };\n return this.on(event, onceListener);\n }\n\n off(event, listener) {\n if (!this.events[event]) return this;\n \n if (!listener) {\n delete this.events[event];\n } else {\n this.events[event] = this.events[event].filter(l => l !== listener);\n }\n \n return this;\n }\n\n emit(event, ...args) {\n if (!this.events[event]) return this;\n \n this.events[event].forEach(listener => {\n listener(...args);\n });\n \n return this;\n }\n\n removeAllListeners() {\n this.events = {};\n return this;\n }\n}\n\n", "/**\n * DOM manipulation utilities\n */\n\nexport const DOMUtils = {\n createElement(tag, options = {}) {\n const element = document.createElement(tag);\n \n if (options.className) {\n element.className = options.className;\n }\n \n if (options.attributes) {\n Object.entries(options.attributes).forEach(([key, value]) => {\n element.setAttribute(key, value);\n });\n }\n \n if (options.innerHTML) {\n element.innerHTML = options.innerHTML;\n }\n \n if (options.textContent) {\n element.textContent = options.textContent;\n }\n \n if (options.style) {\n Object.assign(element.style, options.style);\n }\n \n if (options.children) {\n options.children.forEach(child => {\n if (child) element.appendChild(child);\n });\n }\n \n return element;\n },\n\n addClass(element, className) {\n if (element && className) {\n element.classList.add(className);\n }\n },\n\n removeClass(element, className) {\n if (element && className) {\n element.classList.remove(className);\n }\n },\n\n toggleClass(element, className) {\n if (element && className) {\n element.classList.toggle(className);\n }\n },\n\n hasClass(element, className) {\n return element && element.classList.contains(className);\n },\n\n show(element) {\n if (element) {\n element.style.display = '';\n }\n },\n\n hide(element) {\n if (element) {\n element.style.display = 'none';\n }\n },\n\n fadeIn(element, duration = 300) {\n if (!element) return;\n \n element.style.opacity = '0';\n element.style.display = '';\n \n let start = null;\n const animate = (timestamp) => {\n if (!start) start = timestamp;\n const progress = timestamp - start;\n const opacity = Math.min(progress / duration, 1);\n \n element.style.opacity = opacity;\n \n if (progress < duration) {\n requestAnimationFrame(animate);\n }\n };\n \n requestAnimationFrame(animate);\n },\n\n fadeOut(element, duration = 300) {\n if (!element) return;\n \n const startOpacity = parseFloat(getComputedStyle(element).opacity) || 1;\n let start = null;\n \n const animate = (timestamp) => {\n if (!start) start = timestamp;\n const progress = timestamp - start;\n const opacity = Math.max(startOpacity - (progress / duration), 0);\n \n element.style.opacity = opacity;\n \n if (progress < duration) {\n requestAnimationFrame(animate);\n } else {\n element.style.display = 'none';\n }\n };\n \n requestAnimationFrame(animate);\n },\n\n offset(element) {\n if (!element) return { top: 0, left: 0 };\n \n const rect = element.getBoundingClientRect();\n return {\n top: rect.top + window.pageYOffset,\n left: rect.left + window.pageXOffset,\n width: rect.width,\n height: rect.height\n };\n },\n\n escapeHTML(str) {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n },\n\n sanitizeHTML(html) {\n // Basic HTML sanitization - allow safe tags for VTT captions\n // Since we control the HTML (from VTT parsing), we can safely allow these tags\n const temp = document.createElement('div');\n \n // Strip out any potentially dangerous tags/attributes\n // Allow: strong, em, u, span, b, i with class and data-voice attributes\n const safeHtml = html\n .replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '')\n .replace(/<iframe\\b[^<]*(?:(?!<\\/iframe>)<[^<]*)*<\\/iframe>/gi, '')\n .replace(/on\\w+\\s*=/gi, '') // Remove event handlers\n .replace(/javascript:/gi, ''); // Remove javascript: protocol\n \n temp.innerHTML = safeHtml;\n return temp.innerHTML;\n }\n};\n\n", "/**\n * Time formatting and conversion utilities\n */\n\nexport const TimeUtils = {\n /**\n * Format seconds to time string (HH:MM:SS or MM:SS)\n */\n formatTime(seconds, alwaysShowHours = false) {\n if (!isFinite(seconds) || seconds < 0) {\n return alwaysShowHours ? '00:00:00' : '00:00';\n }\n \n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = Math.floor(seconds % 60);\n \n const pad = (num) => String(num).padStart(2, '0');\n \n if (hours > 0 || alwaysShowHours) {\n return `${pad(hours)}:${pad(minutes)}:${pad(secs)}`;\n }\n \n return `${pad(minutes)}:${pad(secs)}`;\n },\n\n /**\n * Parse time string to seconds\n */\n parseTime(timeString) {\n const parts = timeString.split(':').map(p => parseInt(p, 10));\n \n if (parts.length === 3) {\n // HH:MM:SS\n return parts[0] * 3600 + parts[1] * 60 + parts[2];\n } else if (parts.length === 2) {\n // MM:SS\n return parts[0] * 60 + parts[1];\n } else if (parts.length === 1) {\n // SS\n return parts[0];\n }\n \n return 0;\n },\n\n /**\n * Format seconds to readable duration\n */\n formatDuration(seconds) {\n if (!isFinite(seconds) || seconds < 0) {\n return '0 seconds';\n }\n \n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = Math.floor(seconds % 60);\n \n const parts = [];\n \n if (hours > 0) {\n parts.push(`${hours} hour${hours !== 1 ? 's' : ''}`);\n }\n if (minutes > 0) {\n parts.push(`${minutes} minute${minutes !== 1 ? 's' : ''}`);\n }\n if (secs > 0 || parts.length === 0) {\n parts.push(`${secs} second${secs !== 1 ? 's' : ''}`);\n }\n \n return parts.join(', ');\n },\n\n /**\n * Format percentage\n */\n formatPercentage(value, total) {\n if (total === 0) return 0;\n return Math.round((value / total) * 100);\n }\n};\n\n", "/**\n * SVG Icon Library for VidPly\n * Optimized with common viewBox and fill attributes\n */\n\n// SVG paths only (viewBox and fill added by wrapper)\nconst iconPaths = {\n play: `<path d=\"M8 5v14l11-7z\"/>`,\n\n pause: `<path d=\"M6 4h4v16H6V4zm8 0h4v16h-4V4z\"/>`,\n\n stop: `<rect x=\"6\" y=\"6\" width=\"12\" height=\"12\"/>`,\n\n rewind: `<path d=\"M11 18V6l-8.5 6 8.5 6zm.5-6l8.5 6V6l-8.5 6z\"/>`,\n\n forward: `<path d=\"M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z\"/>`,\n\n skipPrevious: `<path d=\"M6 6h2v12H6V6zm3 6l8.5 6V6L9 12z\"/>`,\n\n skipNext: `<path d=\"M16 6h2v12h-2V6zM6 6l8.5 6L6 18V6z\"/>`,\n\n restart: `<path d=\"M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z\"/>`,\n\n volumeHigh: `<path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z\"/>`,\n\n volumeMedium: `<path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z\"/>`,\n\n volumeLow: `<path d=\"M7 9v6h4l5 5V4l-5 5H7z\"/>`,\n\n volumeMuted: `<path d=\"M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z\"/>`,\n\n fullscreen: `<path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\"/>`,\n\n fullscreenExit: `<path d=\"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z\"/>`,\n\n settings: `<path d=\"M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94L14.4 2.81c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z\"/>`,\n\n captions: `<path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z\"/>`,\n\n captionsOff: `<path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z\"/><path d=\"M0 0h24v24H0z\" fill=\"none\"/>`,\n\n pip: `<path d=\"M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98V5c0-1.1-.9-2-2-2zm0 16.01H3V4.98h18v14.03z\"/>`,\n\n speed: `<path d=\"M20.38 8.57l-1.23 1.85a8 8 0 0 1-.22 7.58H5.07A8 8 0 0 1 15.58 6.85l1.85-1.23A10 10 0 0 0 3.35 19a2 2 0 0 0 1.72 1h13.85a2 2 0 0 0 1.74-1 10 10 0 0 0-.27-10.44z\"/><path d=\"M10.59 15.41a2 2 0 0 0 2.83 0l5.66-8.49-8.49 5.66a2 2 0 0 0 0 2.83z\"/>`,\n\n close: `<path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"/>`,\n\n check: `<path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"/>`,\n\n arrowUp: `<path d=\"M7 14l5-5 5 5z\"/>`,\n\n arrowDown: `<path d=\"M7 10l5 5 5-5z\"/>`,\n\n arrowLeft: `<path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"/>`,\n\n arrowRight: `<path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"/>`,\n\n loading: `<path d=\"M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z\"/>`,\n\n error: `<path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"/>`,\n\n download: `<path d=\"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z\"/>`,\n\n link: `<path d=\"M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z\"/>`,\n\n playlist: `<path d=\"M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z\"/>`,\n\n language: `<path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z\"/>`,\n\n hd: `<path d=\"M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-8 12H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm7-1c0 .55-.45 1-1 1h-.75v1.5h-1.5V15H14c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v4zm-3.5-.5h2v-3h-2v3z\"/>`,\n\n transcript: `<path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z\"/>`,\n\n audioDescription: `<path d=\"M12 3v9.28c-.47-.17-.97-.28-1.5-.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7z\"/><path d=\"M10.5 19c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\"/>`,\n\n audioDescriptionOn: `<path d=\"M12 3v9.28c-.47-.17-.97-.28-1.5-.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7z\"/><path d=\"M10.5 19c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\"/><circle cx=\"19\" cy=\"16\" r=\"3\" fill=\"#3b82f6\"/><path d=\"M18.5 17.5l1-1 1.5 1.5\" stroke=\"white\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`,\n\n signLanguage: `<g transform=\"scale(1.5)\"><path d=\"M16 11.3c-.1-.9-4.8 1.3-5.4 1.1-2.6-1 5.8-1.3 5.1-2.9s-5.1 1.5-6 1.4C6.5 9.4 16.5 9.1 13.5 8c-1.9-.6-8.8 2.9-6.8.4.7-.6.7-1.9-.7-1.7-9.7 7.2-.7 12.2 8.8 7 0-1.3-3.5.4-4.1.4-2.6 0 5.6-2 5.4-3ZM3.9 7.8c3.2-4.2 3.7 1.2 6 .1s.2-.2.2-.3c.7-2.7 2.5-7.5-1.5-1.3-1.6 0 1.1-4 1-4.6C8.9-1 7.3 4.4 7.2 4.9c-1.6.7-.9-1.4-.7-1.5 3-6-.6-3.1-.9.4-2.5 1.8 0-2.8 0-3.5C2.8-.9 4 9.4 1.1 4.9S.1 4.6 0 5c-.4 2.7 2.6 7.2 3.9 2.8Z\"/></g>`,\n\n signLanguageOn: `<g transform=\"scale(1.5)\"><path d=\"M16 11.3c-.1-.9-4.8 1.3-5.4 1.1-2.6-1 5.8-1.3 5.1-2.9s-5.1 1.5-6 1.4C6.5 9.4 16.5 9.1 13.5 8c-1.9-.6-8.8 2.9-6.8.4.7-.6.7-1.9-.7-1.7-9.7 7.2-.7 12.2 8.8 7 0-1.3-3.5.4-4.1.4-2.6 0 5.6-2 5.4-3ZM3.9 7.8c3.2-4.2 3.7 1.2 6 .1s.2-.2.2-.3c.7-2.7 2.5-7.5-1.5-1.3-1.6 0 1.1-4 1-4.6C8.9-1 7.3 4.4 7.2 4.9c-1.6.7-.9-1.4-.7-1.5 3-6-.6-3.1-.9.4-2.5 1.8 0-2.8 0-3.5C2.8-.9 4 9.4 1.1 4.9S.1 4.6 0 5c-.4 2.7 2.6 7.2 3.9 2.8Z\"/></g>`,\n\n speaker: `<path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z\"/>`,\n\n music: `<path d=\"M12 3v9.28c-.47-.17-.97-.28-1.5-.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7zm-1.5 16c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\"/>`,\n\n moreVertical: `<path d=\"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"/>`,\n\n moreHorizontal: `<path d=\"M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"/>`\n};\n\n// Optimized wrapper that adds common SVG attributes\nconst svgWrapper = (paths) => `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\">${paths}</svg>`;\n\n// Export Icons object with SVG wrappers\nexport const Icons = Object.fromEntries(\n Object.entries(iconPaths).map(([key, value]) => [key, svgWrapper(value)])\n);\n\nexport function getIcon(name) {\n return Icons[name] || Icons.play;\n}\n\nexport function createIconElement(name, className = '') {\n const wrapper = document.createElement('span');\n wrapper.className = `vidply-icon ${className}`.trim();\n wrapper.innerHTML = getIcon(name);\n wrapper.setAttribute('aria-hidden', 'true');\n return wrapper;\n}\n\n/**\n * Create the large centered play button overlay (complete SVG)\n * @returns {SVGElement} Complete SVG element with circle background and play icon\n */\nexport function createPlayOverlay() {\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svg.setAttribute('class', 'vidply-play-overlay');\n svg.setAttribute('viewBox', '0 0 80 80');\n svg.setAttribute('width', '80');\n svg.setAttribute('height', '80');\n svg.setAttribute('aria-hidden', 'true');\n svg.setAttribute('role', 'presentation');\n svg.style.cursor = 'pointer';\n\n // Create filter for drop shadow\n const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n const filterId = `vidply-play-shadow-${Math.random().toString(36).substr(2, 9)}`;\n const filter = document.createElementNS('http://www.w3.org/2000/svg', 'filter');\n filter.setAttribute('id', filterId);\n filter.setAttribute('x', '-50%');\n filter.setAttribute('y', '-50%');\n filter.setAttribute('width', '200%');\n filter.setAttribute('height', '200%');\n\n const feGaussianBlur = document.createElementNS('http://www.w3.org/2000/svg', 'feGaussianBlur');\n feGaussianBlur.setAttribute('in', 'SourceAlpha');\n feGaussianBlur.setAttribute('stdDeviation', '3');\n\n const feOffset = document.createElementNS('http://www.w3.org/2000/svg', 'feOffset');\n feOffset.setAttribute('dx', '0');\n feOffset.setAttribute('dy', '2');\n feOffset.setAttribute('result', 'offsetblur');\n\n const feComponentTransfer = document.createElementNS('http://www.w3.org/2000/svg', 'feComponentTransfer');\n const feFuncA = document.createElementNS('http://www.w3.org/2000/svg', 'feFuncA');\n feFuncA.setAttribute('type', 'linear');\n feFuncA.setAttribute('slope', '0.3');\n feComponentTransfer.appendChild(feFuncA);\n\n const feMerge = document.createElementNS('http://www.w3.org/2000/svg', 'feMerge');\n const feMergeNode1 = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');\n const feMergeNode2 = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');\n feMergeNode2.setAttribute('in', 'SourceGraphic');\n feMerge.appendChild(feMergeNode1);\n feMerge.appendChild(feMergeNode2);\n\n filter.appendChild(feGaussianBlur);\n filter.appendChild(feOffset);\n filter.appendChild(feComponentTransfer);\n filter.appendChild(feMerge);\n defs.appendChild(filter);\n svg.appendChild(defs);\n\n // White circle background\n const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n circle.setAttribute('cx', '40');\n circle.setAttribute('cy', '40');\n circle.setAttribute('r', '40');\n circle.setAttribute('fill', 'rgba(255, 255, 255, 0.95)');\n circle.setAttribute('filter', `url(#${filterId})`);\n circle.setAttribute('class', 'vidply-play-overlay-bg');\n svg.appendChild(circle);\n\n // Play icon triangle (centered with optical adjustment)\n const playTriangle = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');\n playTriangle.setAttribute('points', '32,28 32,52 54,40');\n playTriangle.setAttribute('fill', '#0a406e');\n playTriangle.setAttribute('class', 'vidply-play-overlay-icon');\n svg.appendChild(playTriangle);\n\n return svg;\n}\n\n", "/**\n * Translation strings for VidPly\n */\n\nexport const translations = {\n en: {\n player: {\n label: 'Video Player',\n play: 'Play',\n pause: 'Pause',\n stop: 'Stop',\n restart: 'Restart from beginning',\n rewind: 'Rewind',\n forward: 'Forward',\n rewindSeconds: 'Rewind {seconds} seconds',\n forwardSeconds: 'Forward {seconds} seconds',\n previous: 'Previous track',\n next: 'Next track',\n volume: 'Volume',\n mute: 'Mute',\n unmute: 'Unmute',\n fullscreen: 'Fullscreen',\n exitFullscreen: 'Exit Fullscreen',\n captions: 'Captions',\n chapters: 'Chapters',\n quality: 'Quality',\n captionStyling: 'Caption styling',\n transcript: 'Toggle transcript',\n audioDescription: 'Audio description',\n signLanguage: 'Sign language video',\n settings: 'Settings',\n speed: 'Playback Speed',\n pip: 'Picture in Picture',\n currentTime: 'Current time',\n duration: 'Duration',\n progress: 'Progress',\n seekForward: 'Seek forward {seconds} seconds',\n seekBackward: 'Seek backward {seconds} seconds',\n volumeUp: 'Volume up',\n volumeDown: 'Volume down',\n loading: 'Loading...',\n loadingChapters: 'Loading chapters...',\n error: 'Error loading media',\n buffering: 'Buffering...',\n signLanguageVideo: 'Sign Language Video',\n noChapters: 'No chapters available',\n noCaptions: 'No captions available',\n auto: 'Auto',\n autoQuality: 'Auto (no quality selection available)',\n noQuality: 'Quality selection not available'\n },\n captions: {\n off: 'Off',\n select: 'Select captions',\n fontSize: 'Font Size',\n fontFamily: 'Font Family',\n color: 'Text Color',\n backgroundColor: 'Background Color',\n opacity: 'Opacity'\n },\n fontSizes: {\n small: 'Small',\n medium: 'Medium',\n large: 'Large',\n xlarge: 'X-Large'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Text Color',\n background: 'Background',\n font: 'Font',\n fontSize: 'Font Size',\n opacity: 'Opacity'\n },\n audioDescription: {\n enable: 'Enable audio description',\n disable: 'Disable audio description'\n },\n signLanguage: {\n show: 'Show sign language video',\n hide: 'Hide sign language video'\n },\n transcript: {\n title: 'Transcript',\n close: 'Close transcript',\n loading: 'Loading transcript...',\n noTranscript: 'No transcript available for this video.'\n },\n settings: {\n title: 'Settings',\n quality: 'Quality',\n speed: 'Speed',\n captions: 'Captions',\n language: 'Language',\n reset: 'Reset to defaults',\n close: 'Close'\n },\n speeds: {\n normal: 'Normal'\n }\n },\n \n de: {\n player: {\n label: 'Videoplayer',\n play: 'Abspielen',\n pause: 'Pause',\n stop: 'Stopp',\n restart: 'Von vorne beginnen',\n rewind: 'Zur\u00FCckspulen',\n forward: 'Vorspulen',\n rewindSeconds: '{seconds} Sekunden zur\u00FCckspulen',\n forwardSeconds: '{seconds} Sekunden vorspulen',\n previous: 'Vorheriger Titel',\n next: 'N\u00E4chster Titel',\n volume: 'Lautst\u00E4rke',\n mute: 'Stumm',\n unmute: 'Ton ein',\n fullscreen: 'Vollbild',\n exitFullscreen: 'Vollbild beenden',\n captions: 'Untertitel',\n chapters: 'Kapitel',\n quality: 'Qualit\u00E4t',\n captionStyling: 'Untertitel-Stil',\n transcript: 'Transkript umschalten',\n audioDescription: 'Audiodeskription',\n signLanguage: 'Geb\u00E4rdensprache-Video',\n settings: 'Einstellungen',\n speed: 'Wiedergabegeschwindigkeit',\n pip: 'Bild-in-Bild',\n currentTime: 'Aktuelle Zeit',\n duration: 'Dauer',\n progress: 'Fortschritt',\n seekForward: '{seconds} Sekunden vorspulen',\n seekBackward: '{seconds} Sekunden zur\u00FCckspulen',\n volumeUp: 'Lauter',\n volumeDown: 'Leiser',\n loading: 'L\u00E4dt...',\n loadingChapters: 'Kapitel werden geladen...',\n error: 'Fehler beim Laden',\n buffering: 'Puffern...',\n signLanguageVideo: 'Geb\u00E4rdensprache-Video',\n noChapters: 'Keine Kapitel verf\u00FCgbar',\n noCaptions: 'Keine Untertitel verf\u00FCgbar',\n auto: 'Automatisch',\n autoQuality: 'Automatisch (keine Qualit\u00E4tsauswahl verf\u00FCgbar)',\n noQuality: 'Qualit\u00E4tsauswahl nicht verf\u00FCgbar'\n },\n captions: {\n off: 'Aus',\n select: 'Untertitel ausw\u00E4hlen',\n fontSize: 'Schriftgr\u00F6\u00DFe',\n fontFamily: 'Schriftart',\n color: 'Textfarbe',\n backgroundColor: 'Hintergrundfarbe',\n opacity: 'Deckkraft'\n },\n fontSizes: {\n small: 'Klein',\n medium: 'Mittel',\n large: 'Gro\u00DF',\n xlarge: 'Sehr gro\u00DF'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Textfarbe',\n background: 'Hintergrund',\n font: 'Schrift',\n fontSize: 'Schriftgr\u00F6\u00DFe',\n opacity: 'Deckkraft'\n },\n audioDescription: {\n enable: 'Audiodeskription aktivieren',\n disable: 'Audiodeskription deaktivieren'\n },\n signLanguage: {\n show: 'Geb\u00E4rdensprache-Video anzeigen',\n hide: 'Geb\u00E4rdensprache-Video ausblenden'\n },\n transcript: {\n title: 'Transkript',\n close: 'Transkript schlie\u00DFen',\n loading: 'Transkript wird geladen...',\n noTranscript: 'Kein Transkript f\u00FCr dieses Video verf\u00FCgbar.'\n },\n settings: {\n title: 'Einstellungen',\n quality: 'Qualit\u00E4t',\n speed: 'Geschwindigkeit',\n captions: 'Untertitel',\n language: 'Sprache',\n reset: 'Zur\u00FCcksetzen',\n close: 'Schlie\u00DFen'\n },\n speeds: {\n normal: 'Normal'\n }\n },\n\n es: {\n player: {\n label: 'Reproductor de video',\n play: 'Reproducir',\n pause: 'Pausa',\n stop: 'Detener',\n restart: 'Reiniciar desde el principio',\n rewind: 'Retroceder',\n forward: 'Avanzar',\n rewindSeconds: 'Retroceder {seconds} segundos',\n forwardSeconds: 'Avanzar {seconds} segundos',\n previous: 'Pista anterior',\n next: 'Siguiente pista',\n volume: 'Volumen',\n mute: 'Silenciar',\n unmute: 'Activar sonido',\n fullscreen: 'Pantalla completa',\n exitFullscreen: 'Salir de pantalla completa',\n captions: 'Subt\u00EDtulos',\n chapters: 'Cap\u00EDtulos',\n quality: 'Calidad',\n captionStyling: 'Estilo de subt\u00EDtulos',\n transcript: 'Alternar transcripci\u00F3n',\n audioDescription: 'Audiodescripci\u00F3n',\n signLanguage: 'Video en lengua de se\u00F1as',\n settings: 'Configuraci\u00F3n',\n speed: 'Velocidad de reproducci\u00F3n',\n pip: 'Imagen en imagen',\n currentTime: 'Tiempo actual',\n duration: 'Duraci\u00F3n',\n progress: 'Progreso',\n seekForward: 'Avanzar {seconds} segundos',\n seekBackward: 'Retroceder {seconds} segundos',\n volumeUp: 'Subir volumen',\n volumeDown: 'Bajar volumen',\n loading: 'Cargando...',\n loadingChapters: 'Cargando cap\u00EDtulos...',\n error: 'Error al cargar',\n buffering: 'Almacenando en b\u00FAfer...',\n signLanguageVideo: 'Video en Lengua de Se\u00F1as',\n noChapters: 'No hay cap\u00EDtulos disponibles',\n noCaptions: 'No hay subt\u00EDtulos disponibles',\n auto: 'Autom\u00E1tico',\n autoQuality: 'Autom\u00E1tico (selecci\u00F3n de calidad no disponible)',\n noQuality: 'Selecci\u00F3n de calidad no disponible'\n },\n captions: {\n off: 'Desactivado',\n select: 'Seleccionar subt\u00EDtulos',\n fontSize: 'Tama\u00F1o de fuente',\n fontFamily: 'Familia de fuente',\n color: 'Color de texto',\n backgroundColor: 'Color de fondo',\n opacity: 'Opacidad'\n },\n fontSizes: {\n small: 'Peque\u00F1o',\n medium: 'Mediano',\n large: 'Grande',\n xlarge: 'Muy grande'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Color de texto',\n background: 'Fondo',\n font: 'Fuente',\n fontSize: 'Tama\u00F1o de fuente',\n opacity: 'Opacidad'\n },\n audioDescription: {\n enable: 'Activar audiodescripci\u00F3n',\n disable: 'Desactivar audiodescripci\u00F3n'\n },\n signLanguage: {\n show: 'Mostrar video en lengua de se\u00F1as',\n hide: 'Ocultar video en lengua de se\u00F1as'\n },\n transcript: {\n title: 'Transcripci\u00F3n',\n close: 'Cerrar transcripci\u00F3n',\n loading: 'Cargando transcripci\u00F3n...',\n noTranscript: 'No hay transcripci\u00F3n disponible para este video.'\n },\n settings: {\n title: 'Configuraci\u00F3n',\n quality: 'Calidad',\n speed: 'Velocidad',\n captions: 'Subt\u00EDtulos',\n language: 'Idioma',\n reset: 'Restablecer',\n close: 'Cerrar'\n },\n speeds: {\n normal: 'Normal'\n }\n },\n\n fr: {\n player: {\n label: 'Lecteur vid\u00E9o',\n play: 'Lecture',\n pause: 'Pause',\n stop: 'Arr\u00EAt',\n restart: 'Red\u00E9marrer du d\u00E9but',\n rewind: 'Reculer',\n forward: 'Avancer',\n rewindSeconds: 'Reculer de {seconds} secondes',\n forwardSeconds: 'Avancer de {seconds} secondes',\n previous: 'Piste pr\u00E9c\u00E9dente',\n next: 'Piste suivante',\n volume: 'Volume',\n mute: 'Muet',\n unmute: 'Activer le son',\n fullscreen: 'Plein \u00E9cran',\n exitFullscreen: 'Quitter le plein \u00E9cran',\n captions: 'Sous-titres',\n chapters: 'Chapitres',\n quality: 'Qualit\u00E9',\n captionStyling: 'Style des sous-titres',\n transcript: 'Activer/d\u00E9sactiver la transcription',\n audioDescription: 'Audiodescription',\n signLanguage: 'Vid\u00E9o en langue des signes',\n settings: 'Param\u00E8tres',\n speed: 'Vitesse de lecture',\n pip: 'Image dans l\\'image',\n currentTime: 'Temps actuel',\n duration: 'Dur\u00E9e',\n progress: 'Progression',\n seekForward: 'Avancer de {seconds} secondes',\n seekBackward: 'Reculer de {seconds} secondes',\n volumeUp: 'Augmenter le volume',\n volumeDown: 'Diminuer le volume',\n loading: 'Chargement...',\n loadingChapters: 'Chargement des chapitres...',\n error: 'Erreur de chargement',\n buffering: 'Mise en m\u00E9moire tampon...',\n signLanguageVideo: 'Vid\u00E9o en Langue des Signes',\n noChapters: 'Aucun chapitre disponible',\n noCaptions: 'Aucun sous-titre disponible',\n auto: 'Automatique',\n autoQuality: 'Automatique (s\u00E9lection de qualit\u00E9 non disponible)',\n noQuality: 'S\u00E9lection de qualit\u00E9 non disponible'\n },\n captions: {\n off: 'D\u00E9sactiv\u00E9',\n select: 'S\u00E9lectionner les sous-titres',\n fontSize: 'Taille de police',\n fontFamily: 'Police',\n color: 'Couleur du texte',\n backgroundColor: 'Couleur de fond',\n opacity: 'Opacit\u00E9'\n },\n fontSizes: {\n small: 'Petit',\n medium: 'Moyen',\n large: 'Grand',\n xlarge: 'Tr\u00E8s grand'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Couleur du texte',\n background: 'Arri\u00E8re-plan',\n font: 'Police',\n fontSize: 'Taille de police',\n opacity: 'Opacit\u00E9'\n },\n audioDescription: {\n enable: 'Activer l\\'audiodescription',\n disable: 'D\u00E9sactiver l\\'audiodescription'\n },\n signLanguage: {\n show: 'Afficher la vid\u00E9o en langue des signes',\n hide: 'Masquer la vid\u00E9o en langue des signes'\n },\n transcript: {\n title: 'Transcription',\n close: 'Fermer la transcription',\n loading: 'Chargement de la transcription...',\n noTranscript: 'Aucune transcription disponible pour cette vid\u00E9o.'\n },\n settings: {\n title: 'Param\u00E8tres',\n quality: 'Qualit\u00E9',\n speed: 'Vitesse',\n captions: 'Sous-titres',\n language: 'Langue',\n reset: 'R\u00E9initialiser',\n close: 'Fermer'\n },\n speeds: {\n normal: 'Normal'\n }\n },\n\n ja: {\n player: {\n label: '\u30D3\u30C7\u30AA\u30D7\u30EC\u30FC\u30E4\u30FC',\n play: '\u518D\u751F',\n pause: '\u4E00\u6642\u505C\u6B62',\n stop: '\u505C\u6B62',\n restart: '\u6700\u521D\u304B\u3089\u518D\u751F',\n rewind: '\u5DFB\u304D\u623B\u3057',\n forward: '\u65E9\u9001\u308A',\n rewindSeconds: '{seconds}\u79D2\u623B\u3059',\n forwardSeconds: '{seconds}\u79D2\u9032\u3081\u308B',\n previous: '\u524D\u306E\u30C8\u30E9\u30C3\u30AF',\n next: '\u6B21\u306E\u30C8\u30E9\u30C3\u30AF',\n volume: '\u97F3\u91CF',\n mute: '\u30DF\u30E5\u30FC\u30C8',\n unmute: '\u30DF\u30E5\u30FC\u30C8\u89E3\u9664',\n fullscreen: '\u5168\u753B\u9762\u8868\u793A',\n exitFullscreen: '\u5168\u753B\u9762\u8868\u793A\u3092\u7D42\u4E86',\n captions: '\u5B57\u5E55',\n chapters: '\u30C1\u30E3\u30D7\u30BF\u30FC',\n quality: '\u753B\u8CEA',\n captionStyling: '\u5B57\u5E55\u30B9\u30BF\u30A4\u30EB',\n transcript: '\u6587\u5B57\u8D77\u3053\u3057\u5207\u308A\u66FF\u3048',\n audioDescription: '\u97F3\u58F0\u89E3\u8AAC',\n signLanguage: '\u624B\u8A71\u52D5\u753B',\n settings: '\u8A2D\u5B9A',\n speed: '\u518D\u751F\u901F\u5EA6',\n pip: '\u30D4\u30AF\u30C1\u30E3\u30FC\u30A4\u30F3\u30D4\u30AF\u30C1\u30E3\u30FC',\n currentTime: '\u73FE\u5728\u306E\u6642\u9593',\n duration: '\u518D\u751F\u6642\u9593',\n progress: '\u9032\u884C\u72B6\u6CC1',\n seekForward: '{seconds}\u79D2\u9032\u3081\u308B',\n seekBackward: '{seconds}\u79D2\u623B\u3059',\n volumeUp: '\u97F3\u91CF\u3092\u4E0A\u3052\u308B',\n volumeDown: '\u97F3\u91CF\u3092\u4E0B\u3052\u308B',\n loading: '\u8AAD\u307F\u8FBC\u307F\u4E2D...',\n loadingChapters: '\u30C1\u30E3\u30D7\u30BF\u30FC\u8AAD\u307F\u8FBC\u307F\u4E2D...',\n error: '\u8AAD\u307F\u8FBC\u307F\u30A8\u30E9\u30FC',\n buffering: '\u30D0\u30C3\u30D5\u30A1\u30EA\u30F3\u30B0\u4E2D...',\n signLanguageVideo: '\u624B\u8A71\u52D5\u753B',\n noChapters: '\u30C1\u30E3\u30D7\u30BF\u30FC\u304C\u3042\u308A\u307E\u305B\u3093',\n noCaptions: '\u5B57\u5E55\u304C\u3042\u308A\u307E\u305B\u3093',\n auto: '\u81EA\u52D5',\n autoQuality: '\u81EA\u52D5\uFF08\u753B\u8CEA\u9078\u629E\u4E0D\u53EF\uFF09',\n noQuality: '\u753B\u8CEA\u9078\u629E\u4E0D\u53EF'\n },\n captions: {\n off: '\u30AA\u30D5',\n select: '\u5B57\u5E55\u3092\u9078\u629E',\n fontSize: '\u30D5\u30A9\u30F3\u30C8\u30B5\u30A4\u30BA',\n fontFamily: '\u30D5\u30A9\u30F3\u30C8',\n color: '\u30C6\u30AD\u30B9\u30C8\u306E\u8272',\n backgroundColor: '\u80CC\u666F\u8272',\n opacity: '\u4E0D\u900F\u660E\u5EA6'\n },\n fontSizes: {\n small: '\u5C0F',\n medium: '\u4E2D',\n large: '\u5927',\n xlarge: '\u7279\u5927'\n },\n fontFamilies: {\n sansSerif: '\u30B5\u30F3\u30BB\u30EA\u30D5',\n serif: '\u30BB\u30EA\u30D5',\n monospace: '\u7B49\u5E45'\n },\n styleLabels: {\n textColor: '\u30C6\u30AD\u30B9\u30C8\u306E\u8272',\n background: '\u80CC\u666F',\n font: '\u30D5\u30A9\u30F3\u30C8',\n fontSize: '\u30D5\u30A9\u30F3\u30C8\u30B5\u30A4\u30BA',\n opacity: '\u4E0D\u900F\u660E\u5EA6'\n },\n audioDescription: {\n enable: '\u97F3\u58F0\u89E3\u8AAC\u3092\u6709\u52B9\u306B\u3059\u308B',\n disable: '\u97F3\u58F0\u89E3\u8AAC\u3092\u7121\u52B9\u306B\u3059\u308B'\n },\n signLanguage: {\n show: '\u624B\u8A71\u52D5\u753B\u3092\u8868\u793A',\n hide: '\u624B\u8A71\u52D5\u753B\u3092\u975E\u8868\u793A'\n },\n transcript: {\n title: '\u6587\u5B57\u8D77\u3053\u3057',\n close: '\u6587\u5B57\u8D77\u3053\u3057\u3092\u9589\u3058\u308B',\n loading: '\u6587\u5B57\u8D77\u3053\u3057\u3092\u8AAD\u307F\u8FBC\u307F\u4E2D...',\n noTranscript: '\u3053\u306E\u30D3\u30C7\u30AA\u306E\u6587\u5B57\u8D77\u3053\u3057\u306F\u3042\u308A\u307E\u305B\u3093\u3002'\n },\n settings: {\n title: '\u8A2D\u5B9A',\n quality: '\u753B\u8CEA',\n speed: '\u901F\u5EA6',\n captions: '\u5B57\u5E55',\n language: '\u8A00\u8A9E',\n reset: '\u30EA\u30BB\u30C3\u30C8',\n close: '\u9589\u3058\u308B'\n },\n speeds: {\n normal: '\u901A\u5E38'\n }\n }\n};\n\n", "/**\n * Internationalization system\n */\n\nimport { translations } from './translations.js';\n\nclass I18n {\n constructor() {\n this.currentLanguage = 'en';\n this.translations = translations;\n }\n\n setLanguage(lang) {\n if (this.translations[lang]) {\n this.currentLanguage = lang;\n } else {\n console.warn(`Language \"${lang}\" not found, falling back to English`);\n this.currentLanguage = 'en';\n }\n }\n\n getLanguage() {\n return this.currentLanguage;\n }\n\n t(key, replacements = {}) {\n const keys = key.split('.');\n let value = this.translations[this.currentLanguage];\n \n for (const k of keys) {\n if (value && typeof value === 'object' && k in value) {\n value = value[k];\n } else {\n // Fallback to English\n value = this.translations.en;\n for (const fallbackKey of keys) {\n if (value && typeof value === 'object' && fallbackKey in value) {\n value = value[fallbackKey];\n } else {\n return key; // Return key if not found\n }\n }\n break;\n }\n }\n \n // Replace placeholders\n if (typeof value === 'string') {\n Object.entries(replacements).forEach(([placeholder, replacement]) => {\n value = value.replace(new RegExp(`{${placeholder}}`, 'g'), replacement);\n });\n }\n \n return value;\n }\n\n addTranslation(lang, translations) {\n if (!this.translations[lang]) {\n this.translations[lang] = {};\n }\n Object.assign(this.translations[lang], translations);\n }\n}\n\nexport const i18n = new I18n();\n\n", "/**\n * Control Bar Component\n */\n\nimport {DOMUtils} from '../utils/DOMUtils.js';\nimport {TimeUtils} from '../utils/TimeUtils.js';\nimport {createIconElement} from '../icons/Icons.js';\nimport {i18n} from '../i18n/i18n.js';\n\nexport class ControlBar {\n constructor(player) {\n this.player = player;\n this.element = null;\n this.controls = {};\n this.hideTimeout = null;\n this.isDraggingProgress = false;\n this.isDraggingVolume = false;\n\n this.init();\n }\n\n init() {\n this.createElement();\n this.createControls();\n this.attachEvents();\n this.setupAutoHide();\n }\n\n // Helper method to check if we're on a mobile device\n isMobile() {\n return window.innerWidth < 640;\n }\n\n // Smart menu positioning to avoid overflow\n positionMenu(menu, button) {\n const isMobile = this.isMobile();\n \n if (isMobile) {\n // Use bottom sheet on mobile - already styled via CSS\n return;\n }\n\n // Desktop: Smart positioning\n setTimeout(() => {\n const buttonRect = button.getBoundingClientRect();\n const menuRect = menu.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n \n const spaceAbove = buttonRect.top;\n const spaceBelow = viewportHeight - buttonRect.bottom;\n \n // Prefer above, but switch to below if not enough space\n if (spaceAbove < menuRect.height + 20 && spaceBelow > spaceAbove) {\n menu.style.bottom = 'auto';\n menu.style.top = 'calc(100% + 8px)';\n menu.classList.add('vidply-menu-below');\n }\n \n // Check horizontal overflow\n const menuLeft = buttonRect.left + buttonRect.width / 2 - menuRect.width / 2;\n if (menuLeft < 10) {\n // Too far left, align to left edge\n menu.style.right = 'auto';\n menu.style.left = '0';\n menu.style.transform = 'translateX(0)';\n } else if (menuLeft + menuRect.width > viewportWidth - 10) {\n // Too far right, align to right edge\n menu.style.left = 'auto';\n menu.style.right = '0';\n menu.style.transform = 'translateX(0)';\n }\n }, 0);\n }\n\n\n // Helper method to attach close-on-outside-click behavior to menus\n attachMenuCloseHandler(menu, button, preventCloseOnInteraction = false) {\n // Position menu smartly\n this.positionMenu(menu, button);\n \n setTimeout(() => {\n const closeMenu = (e) => {\n // If this menu has form controls, don't close when clicking inside\n if (preventCloseOnInteraction && menu.contains(e.target)) {\n return;\n }\n\n // Check if click is outside menu and button\n if (!menu.contains(e.target) && !button.contains(e.target)) {\n menu.remove();\n document.removeEventListener('click', closeMenu);\n document.removeEventListener('keydown', handleEscape);\n }\n };\n\n const handleEscape = (e) => {\n if (e.key === 'Escape') {\n menu.remove();\n document.removeEventListener('click', closeMenu);\n document.removeEventListener('keydown', handleEscape);\n // Return focus to button\n button.focus();\n }\n };\n\n document.addEventListener('click', closeMenu);\n document.addEventListener('keydown', handleEscape);\n }, 100);\n }\n\n createElement() {\n this.element = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-controls`,\n attributes: {\n 'role': 'region',\n 'aria-label': i18n.t('player.label') + ' controls'\n }\n });\n }\n\n createControls() {\n // Progress bar container\n if (this.player.options.progressBar) {\n this.createProgressBar();\n }\n\n // Button container\n const buttonContainer = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-controls-buttons`\n });\n\n // Left buttons\n const leftButtons = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-controls-left`\n });\n\n // Previous track button (if playlist)\n if (this.player.playlistManager) {\n leftButtons.appendChild(this.createPreviousButton());\n }\n\n // Play/Pause button\n if (this.player.options.playPauseButton) {\n leftButtons.appendChild(this.createPlayPauseButton());\n }\n\n // Restart button (right beside play button)\n leftButtons.appendChild(this.createRestartButton());\n\n // Next track button (if playlist)\n if (this.player.playlistManager) {\n leftButtons.appendChild(this.createNextButton());\n }\n\n // Rewind button (not shown in playlist mode)\n if (!this.player.playlistManager) {\n leftButtons.appendChild(this.createRewindButton());\n }\n\n // Forward button (not shown in playlist mode)\n if (!this.player.playlistManager) {\n leftButtons.appendChild(this.createForwardButton());\n }\n\n // Volume control\n if (this.player.options.volumeControl) {\n leftButtons.appendChild(this.createVolumeControl());\n }\n\n // Time display\n if (this.player.options.currentTime || this.player.options.duration) {\n leftButtons.appendChild(this.createTimeDisplay());\n }\n\n // Right buttons\n this.rightButtons = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-controls-right`\n });\n\n // Check for available features\n const hasChapters = this.hasChapterTracks();\n const hasCaptions = this.hasCaptionTracks();\n const hasQualityLevels = this.hasQualityLevels();\n const hasAudioDescription = this.hasAudioDescription();\n\n // Chapters button - only show if chapters are available\n if (this.player.options.chaptersButton && hasChapters) {\n this.rightButtons.appendChild(this.createChaptersButton());\n }\n\n // Quality button - only show if quality levels are available\n if (this.player.options.qualityButton && hasQualityLevels) {\n this.rightButtons.appendChild(this.createQualityButton());\n }\n\n // Caption styling button (font, size, color) - only show if captions are available\n if (this.player.options.captionStyleButton && hasCaptions) {\n this.rightButtons.appendChild(this.createCaptionStyleButton());\n }\n\n // Speed button - always available\n if (this.player.options.speedButton) {\n this.rightButtons.appendChild(this.createSpeedButton());\n }\n\n // Captions language selector button - only show if captions are available\n if (this.player.options.captionsButton && hasCaptions) {\n this.rightButtons.appendChild(this.createCaptionsButton());\n }\n\n // Transcript button - only show if captions/subtitles are available\n if (this.player.options.transcriptButton && hasCaptions) {\n this.rightButtons.appendChild(this.createTranscriptButton());\n }\n\n // Audio Description button - only show if audio description source is available\n if (this.player.options.audioDescriptionButton && hasAudioDescription) {\n this.rightButtons.appendChild(this.createAudioDescriptionButton());\n }\n\n // Sign Language button - only show if sign language source is available\n const hasSignLanguage = this.hasSignLanguage();\n if (this.player.options.signLanguageButton && hasSignLanguage) {\n this.rightButtons.appendChild(this.createSignLanguageButton());\n }\n\n // PiP button\n if (this.player.options.pipButton && 'pictureInPictureEnabled' in document) {\n this.rightButtons.appendChild(this.createPipButton());\n }\n\n // Fullscreen button\n if (this.player.options.fullscreenButton) {\n this.rightButtons.appendChild(this.createFullscreenButton());\n }\n\n buttonContainer.appendChild(leftButtons);\n buttonContainer.appendChild(this.rightButtons);\n this.element.appendChild(buttonContainer);\n }\n\n // Helper methods to check for available features\n hasChapterTracks() {\n const textTracks = this.player.element.textTracks;\n for (let i = 0; i < textTracks.length; i++) {\n if (textTracks[i].kind === 'chapters') {\n return true;\n }\n }\n return false;\n }\n\n hasCaptionTracks() {\n const textTracks = this.player.element.textTracks;\n for (let i = 0; i < textTracks.length; i++) {\n if (textTracks[i].kind === 'captions' || textTracks[i].kind === 'subtitles') {\n return true;\n }\n }\n return false;\n }\n\n hasQualityLevels() {\n // Check if renderer supports quality selection\n if (this.player.renderer && this.player.renderer.getQualities) {\n const qualities = this.player.renderer.getQualities();\n return qualities && qualities.length > 1;\n }\n return false;\n }\n\n hasAudioDescription() {\n return this.player.audioDescriptionSrc && this.player.audioDescriptionSrc.length > 0;\n }\n\n hasSignLanguage() {\n return this.player.signLanguageSrc && this.player.signLanguageSrc.length > 0;\n }\n\n createProgressBar() {\n const progressContainer = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-container`,\n attributes: {\n 'role': 'slider',\n 'aria-label': i18n.t('player.progress'),\n 'aria-valuemin': '0',\n 'aria-valuemax': '100',\n 'aria-valuenow': '0',\n 'tabindex': '0'\n }\n });\n\n // Buffered progress\n this.controls.buffered = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-buffered`\n });\n\n // Played progress\n this.controls.played = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-played`\n });\n\n // Progress handle\n this.controls.progressHandle = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-handle`\n });\n\n // Tooltip\n this.controls.progressTooltip = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-tooltip`\n });\n\n progressContainer.appendChild(this.controls.buffered);\n progressContainer.appendChild(this.controls.played);\n this.controls.played.appendChild(this.controls.progressHandle);\n progressContainer.appendChild(this.controls.progressTooltip);\n\n this.controls.progress = progressContainer;\n this.element.appendChild(progressContainer);\n\n // Progress bar events\n this.setupProgressBarEvents();\n }\n\n setupProgressBarEvents() {\n const progress = this.controls.progress;\n\n const updateProgress = (clientX) => {\n const rect = progress.getBoundingClientRect();\n const percent = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));\n const time = percent * this.player.state.duration;\n return {percent, time};\n };\n\n // Mouse events\n progress.addEventListener('mousedown', (e) => {\n this.isDraggingProgress = true;\n const {time} = updateProgress(e.clientX);\n this.player.seek(time);\n });\n\n document.addEventListener('mousemove', (e) => {\n if (this.isDraggingProgress) {\n const {time} = updateProgress(e.clientX);\n this.player.seek(time);\n }\n });\n\n document.addEventListener('mouseup', () => {\n this.isDraggingProgress = false;\n });\n\n // Hover tooltip\n progress.addEventListener('mousemove', (e) => {\n if (!this.isDraggingProgress) {\n const {time} = updateProgress(e.clientX);\n this.controls.progressTooltip.textContent = TimeUtils.formatTime(time);\n this.controls.progressTooltip.style.left = `${e.clientX - progress.getBoundingClientRect().left}px`;\n this.controls.progressTooltip.style.display = 'block';\n }\n });\n\n progress.addEventListener('mouseleave', () => {\n this.controls.progressTooltip.style.display = 'none';\n });\n\n // Keyboard navigation\n progress.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') {\n e.preventDefault();\n this.player.seekBackward(5);\n } else if (e.key === 'ArrowRight') {\n e.preventDefault();\n this.player.seekForward(5);\n }\n });\n\n // Touch events\n progress.addEventListener('touchstart', (e) => {\n this.isDraggingProgress = true;\n const touch = e.touches[0];\n const {time} = updateProgress(touch.clientX);\n this.player.seek(time);\n });\n\n progress.addEventListener('touchmove', (e) => {\n if (this.isDraggingProgress) {\n e.preventDefault();\n const touch = e.touches[0];\n const {time} = updateProgress(touch.clientX);\n this.player.seek(time);\n }\n });\n\n progress.addEventListener('touchend', () => {\n this.isDraggingProgress = false;\n });\n }\n\n createPlayPauseButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-play-pause`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.play')\n }\n });\n\n button.appendChild(createIconElement('play'));\n\n button.addEventListener('click', () => {\n this.player.toggle();\n });\n\n this.controls.playPause = button;\n return button;\n }\n\n createRestartButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-restart`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.restart')\n }\n });\n\n button.appendChild(createIconElement('restart'));\n\n button.addEventListener('click', () => {\n this.player.seek(0);\n this.player.play();\n });\n\n return button;\n }\n\n createPreviousButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-previous`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.previous')\n }\n });\n\n button.appendChild(createIconElement('skipPrevious'));\n\n button.addEventListener('click', () => {\n if (this.player.playlistManager) {\n this.player.playlistManager.previous();\n }\n });\n\n // Update button state\n const updateState = () => {\n if (this.player.playlistManager) {\n button.disabled = !this.player.playlistManager.hasPrevious() && !this.player.playlistManager.options.loop;\n }\n };\n this.player.on('playlisttrackchange', updateState);\n updateState();\n\n this.controls.previous = button;\n return button;\n }\n\n createNextButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-next`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.next')\n }\n });\n\n button.appendChild(createIconElement('skipNext'));\n\n button.addEventListener('click', () => {\n if (this.player.playlistManager) {\n this.player.playlistManager.next();\n }\n });\n\n // Update button state\n const updateState = () => {\n if (this.player.playlistManager) {\n button.disabled = !this.player.playlistManager.hasNext() && !this.player.playlistManager.options.loop;\n }\n };\n this.player.on('playlisttrackchange', updateState);\n updateState();\n\n this.controls.next = button;\n return button;\n }\n\n createRewindButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-rewind`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.rewindSeconds', { seconds: 15 })\n }\n });\n\n button.appendChild(createIconElement('rewind'));\n\n button.addEventListener('click', () => {\n this.player.seekBackward(15);\n });\n\n return button;\n }\n\n createForwardButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-forward`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.forwardSeconds', { seconds: 15 })\n }\n });\n\n button.appendChild(createIconElement('forward'));\n\n button.addEventListener('click', () => {\n this.player.seekForward(15);\n });\n\n return button;\n }\n\n createVolumeControl() {\n // Mute/Volume button\n const muteButton = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-mute`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.volume'),\n 'aria-haspopup': 'true'\n }\n });\n\n muteButton.appendChild(createIconElement('volumeHigh'));\n\n // Toggle mute on right click, show volume slider on left click\n muteButton.addEventListener('contextmenu', (e) => {\n e.preventDefault();\n this.player.toggleMute();\n });\n\n muteButton.addEventListener('click', () => {\n this.showVolumeSlider(muteButton);\n });\n\n this.controls.mute = muteButton;\n\n return muteButton;\n }\n\n showVolumeSlider(button) {\n // Remove existing slider if any\n const existingSlider = document.querySelector(`.${this.player.options.classPrefix}-volume-menu`);\n if (existingSlider) {\n existingSlider.remove();\n return;\n }\n\n // Volume menu container\n const volumeMenu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-menu ${this.player.options.classPrefix}-menu`\n });\n\n const volumeSlider = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-slider`,\n attributes: {\n 'role': 'slider',\n 'aria-label': i18n.t('player.volume'),\n 'aria-valuemin': '0',\n 'aria-valuemax': '100',\n 'aria-valuenow': String(Math.round(this.player.state.volume * 100)),\n 'tabindex': '0'\n }\n });\n\n const volumeTrack = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-track`\n });\n\n const volumeFill = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-fill`\n });\n\n const volumeHandle = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-handle`\n });\n\n volumeTrack.appendChild(volumeFill);\n volumeFill.appendChild(volumeHandle);\n volumeSlider.appendChild(volumeTrack);\n volumeMenu.appendChild(volumeSlider);\n\n // Volume slider events\n const updateVolume = (clientY) => {\n const rect = volumeTrack.getBoundingClientRect();\n const percent = Math.max(0, Math.min(1, 1 - ((clientY - rect.top) / rect.height)));\n this.player.setVolume(percent);\n };\n\n volumeSlider.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n this.isDraggingVolume = true;\n updateVolume(e.clientY);\n });\n\n document.addEventListener('mousemove', (e) => {\n if (this.isDraggingVolume) {\n updateVolume(e.clientY);\n }\n });\n\n document.addEventListener('mouseup', () => {\n this.isDraggingVolume = false;\n });\n\n // Keyboard volume control\n volumeSlider.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n this.player.setVolume(Math.min(1, this.player.state.volume + 0.1));\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n this.player.setVolume(Math.max(0, this.player.state.volume - 0.1));\n }\n });\n\n // Prevent menu from closing when interacting with slider\n volumeMenu.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n // Append menu to button\n button.appendChild(volumeMenu);\n\n this.controls.volumeSlider = volumeSlider;\n this.controls.volumeFill = volumeFill;\n\n // Close menu on outside click\n this.attachMenuCloseHandler(volumeMenu, button, true);\n }\n\n createTimeDisplay() {\n const container = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-time`\n });\n\n this.controls.currentTimeDisplay = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-current-time`,\n textContent: '00:00'\n });\n\n const separator = DOMUtils.createElement('span', {\n textContent: ' / ',\n attributes: {\n 'aria-hidden': 'true'\n }\n });\n\n this.controls.durationDisplay = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-duration`,\n textContent: '00:00'\n });\n\n container.appendChild(this.controls.currentTimeDisplay);\n container.appendChild(separator);\n container.appendChild(this.controls.durationDisplay);\n\n return container;\n }\n\n createChaptersButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-chapters`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.chapters'),\n 'aria-haspopup': 'menu'\n }\n });\n\n button.appendChild(createIconElement('playlist'));\n\n button.addEventListener('click', () => {\n this.showChaptersMenu(button);\n });\n\n this.controls.chapters = button;\n return button;\n }\n\n showChaptersMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-chapters-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-chapters-menu ${this.player.options.classPrefix}-menu`,\n attributes: {\n 'role': 'menu',\n 'aria-label': i18n.t('player.chapters')\n }\n });\n\n // Get chapter tracks\n const chapterTracks = Array.from(this.player.element.textTracks).filter(\n track => track.kind === 'chapters'\n );\n\n if (chapterTracks.length === 0) {\n // No chapters available\n const noChaptersItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.noChapters'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(noChaptersItem);\n } else {\n const chapterTrack = chapterTracks[0];\n\n // Ensure track is in 'hidden' mode to load cues\n if (chapterTrack.mode === 'disabled') {\n chapterTrack.mode = 'hidden';\n }\n\n if (!chapterTrack.cues || chapterTrack.cues.length === 0) {\n // Cues not loaded yet - wait for them to load\n const loadingItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.loadingChapters'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(loadingItem);\n\n // Listen for track load event\n const onTrackLoad = () => {\n // Remove loading message and rebuild menu\n menu.remove();\n this.showChaptersMenu(button);\n };\n\n chapterTrack.addEventListener('load', onTrackLoad, {once: true});\n\n // Also try again after a short delay as fallback\n setTimeout(() => {\n if (chapterTrack.cues && chapterTrack.cues.length > 0 && document.contains(menu)) {\n menu.remove();\n this.showChaptersMenu(button);\n }\n }, 500);\n } else {\n // Display chapters\n const cues = chapterTrack.cues;\n for (let i = 0; i < cues.length; i++) {\n const cue = cues[i];\n const item = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n attributes: {\n 'type': 'button',\n 'role': 'menuitem'\n }\n });\n\n const timeLabel = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-chapter-time`,\n textContent: TimeUtils.formatTime(cue.startTime)\n });\n\n const titleLabel = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-chapter-title`,\n textContent: cue.text\n });\n\n item.appendChild(timeLabel);\n item.appendChild(document.createTextNode(' '));\n item.appendChild(titleLabel);\n\n item.addEventListener('click', () => {\n this.player.seek(cue.startTime);\n menu.remove();\n });\n\n menu.appendChild(item);\n }\n }\n }\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n }\n\n createQualityButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-quality`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.quality'),\n 'aria-haspopup': 'menu'\n }\n });\n\n button.appendChild(createIconElement('hd'));\n\n // Add quality indicator text\n const qualityText = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-quality-text`,\n textContent: ''\n });\n button.appendChild(qualityText);\n\n button.addEventListener('click', () => {\n this.showQualityMenu(button);\n });\n\n this.controls.quality = button;\n this.controls.qualityText = qualityText;\n \n // Update quality indicator after a short delay to ensure renderer is ready\n setTimeout(() => this.updateQualityIndicator(), 500);\n \n return button;\n }\n\n showQualityMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-quality-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-quality-menu ${this.player.options.classPrefix}-menu`,\n attributes: {\n 'role': 'menu',\n 'aria-label': i18n.t('player.quality')\n }\n });\n\n // Check if renderer supports quality selection\n if (this.player.renderer && this.player.renderer.getQualities) {\n const qualities = this.player.renderer.getQualities();\n const currentQuality = this.player.renderer.getCurrentQuality ? this.player.renderer.getCurrentQuality() : -1;\n const isHLS = this.player.renderer.hls !== undefined;\n\n if (qualities.length === 0) {\n // No qualities available\n const noQualityItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.autoQuality'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(noQualityItem);\n } else {\n // Auto quality option (only for HLS)\n if (isHLS) {\n const autoItem = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.auto'),\n attributes: {\n 'type': 'button',\n 'role': 'menuitem'\n }\n });\n\n // Check if auto is currently selected\n const isAuto = this.player.renderer.hls && this.player.renderer.hls.currentLevel === -1;\n if (isAuto) {\n autoItem.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n autoItem.appendChild(createIconElement('check'));\n }\n\n autoItem.addEventListener('click', () => {\n if (this.player.renderer.switchQuality) {\n this.player.renderer.switchQuality(-1); // -1 for auto\n }\n menu.remove();\n });\n\n menu.appendChild(autoItem);\n }\n\n // Quality options\n qualities.forEach(quality => {\n const item = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: quality.name || `${quality.height}p`,\n attributes: {\n 'type': 'button',\n 'role': 'menuitem'\n }\n });\n\n // Highlight current quality\n if (quality.index === currentQuality) {\n item.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n item.appendChild(createIconElement('check'));\n }\n\n item.addEventListener('click', () => {\n if (this.player.renderer.switchQuality) {\n this.player.renderer.switchQuality(quality.index);\n }\n menu.remove();\n });\n\n menu.appendChild(item);\n });\n }\n } else {\n // No quality support\n const noSupportItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.noQuality'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(noSupportItem);\n }\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n }\n\n createCaptionStyleButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-caption-style`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.captionStyling'),\n 'aria-haspopup': 'menu',\n 'title': i18n.t('player.captionStyling')\n }\n });\n\n // Create \"Aa\" text icon for styling\n const textIcon = DOMUtils.createElement('span', {\n textContent: 'Aa',\n style: {\n fontSize: '14px',\n fontWeight: 'bold'\n }\n });\n button.appendChild(textIcon);\n\n button.addEventListener('click', () => {\n this.showCaptionStyleMenu(button);\n });\n\n this.controls.captionStyle = button;\n return button;\n }\n\n showCaptionStyleMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-caption-style-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-caption-style-menu ${this.player.options.classPrefix}-menu ${this.player.options.classPrefix}-settings-menu`,\n attributes: {\n 'role': 'menu',\n 'aria-label': i18n.t('player.captionStyling')\n }\n });\n\n // Prevent menu from closing when clicking inside\n menu.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n // Check if there are any caption tracks\n if (!this.player.captionManager || this.player.captionManager.tracks.length === 0) {\n // Show \"No captions available\" message\n const noTracksItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.noCaptions'),\n style: {opacity: '0.5', cursor: 'default', padding: '12px 16px'}\n });\n menu.appendChild(noTracksItem);\n\n // Append menu to button\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button, true);\n return;\n }\n\n // Font Size\n const fontSizeGroup = this.createStyleControl(\n i18n.t('styleLabels.fontSize'),\n 'captionsFontSize',\n [\n {label: i18n.t('fontSizes.small'), value: '80%'},\n {label: i18n.t('fontSizes.medium'), value: '100%'},\n {label: i18n.t('fontSizes.large'), value: '120%'},\n {label: i18n.t('fontSizes.xlarge'), value: '150%'}\n ]\n );\n menu.appendChild(fontSizeGroup);\n\n // Font Family\n const fontFamilyGroup = this.createStyleControl(\n i18n.t('styleLabels.font'),\n 'captionsFontFamily',\n [\n {label: i18n.t('fontFamilies.sansSerif'), value: 'sans-serif'},\n {label: i18n.t('fontFamilies.serif'), value: 'serif'},\n {label: i18n.t('fontFamilies.monospace'), value: 'monospace'}\n ]\n );\n menu.appendChild(fontFamilyGroup);\n\n // Text Color\n const colorGroup = this.createColorControl(i18n.t('styleLabels.textColor'), 'captionsColor');\n menu.appendChild(colorGroup);\n\n // Background Color\n const bgColorGroup = this.createColorControl(i18n.t('styleLabels.background'), 'captionsBackgroundColor');\n menu.appendChild(bgColorGroup);\n\n // Opacity\n const opacityGroup = this.createOpacityControl(i18n.t('styleLabels.opacity'), 'captionsOpacity');\n menu.appendChild(opacityGroup);\n\n // Set min-width for caption style menu\n menu.style.minWidth = '220px';\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click (but not when interacting with controls)\n this.attachMenuCloseHandler(menu, button, true);\n }\n\n createStyleControl(label, property, options) {\n const group = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-style-group`\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n style: {\n display: 'block',\n fontSize: '12px',\n marginBottom: '4px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n group.appendChild(labelEl);\n\n const select = DOMUtils.createElement('select', {\n className: `${this.player.options.classPrefix}-style-select`,\n style: {\n width: '100%',\n padding: '6px',\n background: 'var(--vidply-white)',\n border: '1px solid var(--vidply-white-10)',\n borderRadius: '4px',\n color: 'var(--vidply-black)',\n fontSize: '13px'\n }\n });\n\n const currentValue = this.player.options[property];\n options.forEach(opt => {\n const option = DOMUtils.createElement('option', {\n textContent: opt.label,\n attributes: {value: opt.value}\n });\n if (opt.value === currentValue) {\n option.selected = true;\n }\n select.appendChild(option);\n });\n\n // Prevent clicks from closing the menu\n select.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n });\n\n select.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n select.addEventListener('change', (e) => {\n e.stopPropagation();\n this.player.options[property] = e.target.value;\n if (this.player.captionManager) {\n this.player.captionManager.setCaptionStyle(\n property.replace('captions', '').charAt(0).toLowerCase() + property.replace('captions', '').slice(1),\n e.target.value\n );\n }\n });\n\n group.appendChild(select);\n return group;\n }\n\n createColorControl(label, property) {\n const group = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-style-group`\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n style: {\n display: 'block',\n fontSize: '12px',\n marginBottom: '4px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n group.appendChild(labelEl);\n\n const input = DOMUtils.createElement('input', {\n attributes: {\n type: 'color',\n value: this.player.options[property]\n },\n style: {\n width: '100%',\n height: '32px',\n padding: '2px',\n background: 'rgba(255,255,255,0.1)',\n border: '1px solid rgba(255,255,255,0.2)',\n borderRadius: '4px',\n cursor: 'pointer'\n }\n });\n\n // Prevent clicks from closing the menu\n input.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('change', (e) => {\n e.stopPropagation();\n this.player.options[property] = e.target.value;\n if (this.player.captionManager) {\n this.player.captionManager.setCaptionStyle(\n property.replace('captions', '').charAt(0).toLowerCase() + property.replace('captions', '').slice(1),\n e.target.value\n );\n }\n });\n\n group.appendChild(input);\n return group;\n }\n\n createOpacityControl(label, property) {\n const group = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-style-group`\n });\n\n const labelContainer = DOMUtils.createElement('div', {\n style: {\n display: 'flex',\n justifyContent: 'space-between',\n marginBottom: '4px'\n }\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n style: {\n fontSize: '12px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n\n const valueEl = DOMUtils.createElement('span', {\n textContent: Math.round(this.player.options[property] * 100) + '%',\n style: {\n fontSize: '12px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n\n labelContainer.appendChild(labelEl);\n labelContainer.appendChild(valueEl);\n group.appendChild(labelContainer);\n\n const input = DOMUtils.createElement('input', {\n attributes: {\n type: 'range',\n min: '0',\n max: '1',\n step: '0.1',\n value: String(this.player.options[property])\n },\n style: {\n width: '100%',\n cursor: 'pointer'\n }\n });\n\n // Prevent clicks from closing the menu\n input.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('input', (e) => {\n e.stopPropagation();\n const value = parseFloat(e.target.value);\n valueEl.textContent = Math.round(value * 100) + '%';\n this.player.options[property] = value;\n if (this.player.captionManager) {\n this.player.captionManager.setCaptionStyle(\n property.replace('captions', '').charAt(0).toLowerCase() + property.replace('captions', '').slice(1),\n value\n );\n }\n });\n\n group.appendChild(input);\n return group;\n }\n\n createSpeedButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-speed`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.speed'),\n 'aria-haspopup': 'menu'\n }\n });\n\n button.appendChild(createIconElement('speed'));\n\n const speedText = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-speed-text`,\n textContent: '1x'\n });\n button.appendChild(speedText);\n\n button.addEventListener('click', () => {\n this.showSpeedMenu(button);\n });\n\n this.controls.speed = button;\n this.controls.speedText = speedText;\n return button;\n }\n\n formatSpeedLabel(speed) {\n // Special case: 1x is \"Normal\" (translated)\n if (speed === 1) {\n return i18n.t('speeds.normal');\n }\n \n // For other speeds, format with locale-specific decimal separator\n const speedStr = speed.toLocaleString(i18n.getLanguage(), {\n minimumFractionDigits: 0,\n maximumFractionDigits: 2\n });\n \n return `${speedStr}\u00D7`;\n }\n\n showSpeedMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-speed-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-speed-menu ${this.player.options.classPrefix}-menu`,\n attributes: {\n 'role': 'menu'\n }\n });\n\n const speeds = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];\n\n speeds.forEach(speed => {\n const item = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: this.formatSpeedLabel(speed),\n attributes: {\n 'type': 'button',\n 'role': 'menuitem'\n }\n });\n\n if (speed === this.player.state.playbackSpeed) {\n item.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n item.appendChild(createIconElement('check'));\n }\n\n item.addEventListener('click', () => {\n this.player.setPlaybackSpeed(speed);\n menu.remove();\n });\n\n menu.appendChild(item);\n });\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n }\n\n createCaptionsButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-captions-button`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.captions'),\n 'aria-pressed': 'false',\n 'aria-haspopup': 'menu'\n }\n });\n\n button.appendChild(createIconElement('captionsOff'));\n\n button.addEventListener('click', () => {\n this.showCaptionsMenu(button);\n });\n\n this.controls.captions = button;\n return button;\n }\n\n showCaptionsMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-captions-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-captions-menu ${this.player.options.classPrefix}-menu`,\n attributes: {\n 'role': 'menu',\n 'aria-label': i18n.t('captions.select')\n }\n });\n\n // Check if there are any caption tracks\n if (!this.player.captionManager || this.player.captionManager.tracks.length === 0) {\n // Show \"No captions available\" message\n const noTracksItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.noCaptions'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(noTracksItem);\n\n // Append menu to button\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n return;\n }\n\n // Off option\n const offItem = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('captions.off'),\n attributes: {\n 'type': 'button',\n 'role': 'menuitem'\n }\n });\n\n if (!this.player.state.captionsEnabled) {\n offItem.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n offItem.appendChild(createIconElement('check'));\n }\n\n offItem.addEventListener('click', () => {\n this.player.disableCaptions();\n this.updateCaptionsButton();\n menu.remove();\n });\n\n menu.appendChild(offItem);\n\n // Available tracks\n const tracks = this.player.captionManager.getAvailableTracks();\n tracks.forEach(track => {\n const item = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: track.label,\n attributes: {\n 'type': 'button',\n 'role': 'menuitem',\n 'lang': track.language\n }\n });\n\n // Check if this is the current track\n if (this.player.state.captionsEnabled &&\n this.player.captionManager.currentTrack === this.player.captionManager.tracks[track.index]) {\n item.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n item.appendChild(createIconElement('check'));\n }\n\n item.addEventListener('click', () => {\n this.player.captionManager.switchTrack(track.index);\n this.updateCaptionsButton();\n menu.remove();\n });\n\n menu.appendChild(item);\n });\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n }\n\n updateCaptionsButton() {\n if (!this.controls.captions) return;\n\n const icon = this.controls.captions.querySelector('.vidply-icon');\n const isEnabled = this.player.state.captionsEnabled;\n\n icon.innerHTML = isEnabled ?\n createIconElement('captions').innerHTML :\n createIconElement('captionsOff').innerHTML;\n\n this.controls.captions.setAttribute('aria-pressed', isEnabled ? 'true' : 'false');\n }\n\n createTranscriptButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-transcript`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.transcript'),\n 'aria-pressed': 'false'\n }\n });\n\n button.appendChild(createIconElement('transcript'));\n\n button.addEventListener('click', () => {\n if (this.player.transcriptManager) {\n this.player.transcriptManager.toggleTranscript();\n this.updateTranscriptButton();\n }\n });\n\n this.controls.transcript = button;\n return button;\n }\n\n updateTranscriptButton() {\n if (!this.controls.transcript) return;\n\n const isVisible = this.player.transcriptManager && this.player.transcriptManager.isVisible;\n this.controls.transcript.setAttribute('aria-pressed', isVisible ? 'true' : 'false');\n }\n\n createAudioDescriptionButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-audio-description`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.audioDescription'),\n 'aria-pressed': 'false',\n 'title': i18n.t('player.audioDescription')\n }\n });\n\n button.appendChild(createIconElement('audioDescription'));\n\n button.addEventListener('click', async () => {\n await this.player.toggleAudioDescription();\n this.updateAudioDescriptionButton();\n });\n\n this.controls.audioDescription = button;\n return button;\n }\n\n updateAudioDescriptionButton() {\n if (!this.controls.audioDescription) return;\n\n const icon = this.controls.audioDescription.querySelector('.vidply-icon');\n const isEnabled = this.player.state.audioDescriptionEnabled;\n\n icon.innerHTML = isEnabled ?\n createIconElement('audioDescriptionOn').innerHTML :\n createIconElement('audioDescription').innerHTML;\n\n this.controls.audioDescription.setAttribute('aria-pressed', isEnabled ? 'true' : 'false');\n this.controls.audioDescription.setAttribute('aria-label',\n isEnabled ? i18n.t('audioDescription.disable') : i18n.t('audioDescription.enable')\n );\n }\n\n createSignLanguageButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-sign-language`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.signLanguage'),\n 'aria-pressed': 'false',\n 'title': i18n.t('player.signLanguage')\n }\n });\n\n button.appendChild(createIconElement('signLanguage'));\n\n button.addEventListener('click', () => {\n this.player.toggleSignLanguage();\n this.updateSignLanguageButton();\n });\n\n this.controls.signLanguage = button;\n return button;\n }\n\n updateSignLanguageButton() {\n if (!this.controls.signLanguage) return;\n\n const icon = this.controls.signLanguage.querySelector('.vidply-icon');\n const isEnabled = this.player.state.signLanguageEnabled;\n\n icon.innerHTML = isEnabled ?\n createIconElement('signLanguageOn').innerHTML :\n createIconElement('signLanguage').innerHTML;\n\n this.controls.signLanguage.setAttribute('aria-pressed', isEnabled ? 'true' : 'false');\n this.controls.signLanguage.setAttribute('aria-label',\n isEnabled ? i18n.t('signLanguage.hide') : i18n.t('signLanguage.show')\n );\n }\n\n createSettingsButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-settings`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.settings')\n }\n });\n\n button.appendChild(createIconElement('settings'));\n\n button.addEventListener('click', () => {\n this.player.showSettings();\n });\n\n return button;\n }\n\n createPipButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-pip`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.pip')\n }\n });\n\n button.appendChild(createIconElement('pip'));\n\n button.addEventListener('click', () => {\n this.player.togglePiP();\n });\n\n return button;\n }\n\n createFullscreenButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-fullscreen`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.fullscreen')\n }\n });\n\n button.appendChild(createIconElement('fullscreen'));\n\n button.addEventListener('click', () => {\n this.player.toggleFullscreen();\n });\n\n this.controls.fullscreen = button;\n return button;\n }\n\n attachEvents() {\n // Update controls based on player state\n this.player.on('play', () => this.updatePlayPauseButton());\n this.player.on('pause', () => this.updatePlayPauseButton());\n this.player.on('timeupdate', () => this.updateProgress());\n this.player.on('loadedmetadata', () => {\n this.updateDuration();\n this.ensureQualityButton();\n this.updateQualityIndicator();\n });\n this.player.on('volumechange', () => this.updateVolumeDisplay());\n this.player.on('progress', () => this.updateBuffered());\n this.player.on('playbackspeedchange', () => this.updateSpeedDisplay());\n this.player.on('fullscreenchange', () => this.updateFullscreenButton());\n this.player.on('captionsenabled', () => this.updateCaptionsButton());\n this.player.on('captionsdisabled', () => this.updateCaptionsButton());\n this.player.on('audiodescriptionenabled', () => this.updateAudioDescriptionButton());\n this.player.on('audiodescriptiondisabled', () => this.updateAudioDescriptionButton());\n this.player.on('signlanguageenabled', () => this.updateSignLanguageButton());\n this.player.on('signlanguagedisabled', () => this.updateSignLanguageButton());\n this.player.on('qualitychange', () => this.updateQualityIndicator());\n this.player.on('hlslevelswitched', () => this.updateQualityIndicator());\n this.player.on('hlsmanifestparsed', () => {\n this.ensureQualityButton();\n this.updateQualityIndicator();\n });\n }\n\n updatePlayPauseButton() {\n if (!this.controls.playPause) return;\n\n const icon = this.controls.playPause.querySelector('.vidply-icon');\n const isPlaying = this.player.state.playing;\n\n icon.innerHTML = isPlaying ?\n createIconElement('pause').innerHTML :\n createIconElement('play').innerHTML;\n\n this.controls.playPause.setAttribute('aria-label',\n isPlaying ? i18n.t('player.pause') : i18n.t('player.play')\n );\n }\n\n updateProgress() {\n if (!this.controls.played) return;\n\n const percent = (this.player.state.currentTime / this.player.state.duration) * 100;\n this.controls.played.style.width = `${percent}%`;\n this.controls.progress.setAttribute('aria-valuenow', String(Math.round(percent)));\n\n if (this.controls.currentTimeDisplay) {\n this.controls.currentTimeDisplay.textContent = TimeUtils.formatTime(this.player.state.currentTime);\n }\n }\n\n updateDuration() {\n if (this.controls.durationDisplay) {\n this.controls.durationDisplay.textContent = TimeUtils.formatTime(this.player.state.duration);\n }\n }\n\n updateVolumeDisplay() {\n if (!this.controls.volumeFill) return;\n\n const percent = this.player.state.volume * 100;\n this.controls.volumeFill.style.height = `${percent}%`;\n\n // Update mute button icon\n if (this.controls.mute) {\n const icon = this.controls.mute.querySelector('.vidply-icon');\n let iconName;\n\n if (this.player.state.muted || this.player.state.volume === 0) {\n iconName = 'volumeMuted';\n } else if (this.player.state.volume < 0.3) {\n iconName = 'volumeLow';\n } else if (this.player.state.volume < 0.7) {\n iconName = 'volumeMedium';\n } else {\n iconName = 'volumeHigh';\n }\n\n icon.innerHTML = createIconElement(iconName).innerHTML;\n\n this.controls.mute.setAttribute('aria-label',\n this.player.state.muted ? i18n.t('player.unmute') : i18n.t('player.mute')\n );\n }\n\n if (this.controls.volumeSlider) {\n this.controls.volumeSlider.setAttribute('aria-valuenow', String(Math.round(percent)));\n }\n }\n\n updateBuffered() {\n if (!this.controls.buffered || !this.player.element.buffered || this.player.element.buffered.length === 0) return;\n\n const buffered = this.player.element.buffered.end(this.player.element.buffered.length - 1);\n const percent = (buffered / this.player.state.duration) * 100;\n this.controls.buffered.style.width = `${percent}%`;\n }\n\n updateSpeedDisplay() {\n if (this.controls.speedText) {\n this.controls.speedText.textContent = `${this.player.state.playbackSpeed}x`;\n }\n }\n\n updateFullscreenButton() {\n if (!this.controls.fullscreen) return;\n\n const icon = this.controls.fullscreen.querySelector('.vidply-icon');\n const isFullscreen = this.player.state.fullscreen;\n\n icon.innerHTML = isFullscreen ?\n createIconElement('fullscreenExit').innerHTML :\n createIconElement('fullscreen').innerHTML;\n\n this.controls.fullscreen.setAttribute('aria-label',\n isFullscreen ? i18n.t('player.exitFullscreen') : i18n.t('player.fullscreen')\n );\n }\n\n /**\n * Ensure quality button exists if qualities are available\n * This is called after renderer initialization to dynamically add the button\n */\n ensureQualityButton() {\n // Skip if quality button is disabled\n if (!this.player.options.qualityButton) return;\n \n // Skip if button already exists\n if (this.controls.quality) return;\n \n // Check if qualities are now available\n if (!this.hasQualityLevels()) return;\n \n // Create and insert the quality button before the speed button\n const qualityButton = this.createQualityButton();\n \n // Find the speed button or caption style button to insert before\n const speedButton = this.rightButtons.querySelector(`.${this.player.options.classPrefix}-speed`);\n const captionStyleButton = this.rightButtons.querySelector(`.${this.player.options.classPrefix}-caption-style`);\n const insertBefore = captionStyleButton || speedButton;\n \n if (insertBefore) {\n this.rightButtons.insertBefore(qualityButton, insertBefore);\n } else {\n // If no reference button, add it at the beginning of right buttons\n this.rightButtons.insertBefore(qualityButton, this.rightButtons.firstChild);\n }\n \n this.player.log('Quality button added dynamically', 'info');\n }\n\n updateQualityIndicator() {\n if (!this.controls.qualityText) return;\n if (!this.player.renderer || !this.player.renderer.getQualities) return;\n\n const qualities = this.player.renderer.getQualities();\n if (qualities.length === 0) {\n this.controls.qualityText.textContent = '';\n return;\n }\n\n // Get current quality\n let currentQualityText = '';\n \n // Check if it's HLS with auto mode\n if (this.player.renderer.hls && this.player.renderer.hls.currentLevel === -1) {\n currentQualityText = 'Auto';\n } else if (this.player.renderer.getCurrentQuality) {\n const currentIndex = this.player.renderer.getCurrentQuality();\n const currentQuality = qualities.find(q => q.index === currentIndex);\n if (currentQuality) {\n currentQualityText = currentQuality.height ? `${currentQuality.height}p` : '';\n }\n }\n\n this.controls.qualityText.textContent = currentQualityText;\n }\n\n setupAutoHide() {\n if (this.player.element.tagName !== 'VIDEO') return;\n\n const showControls = () => {\n this.element.classList.add(`${this.player.options.classPrefix}-controls-visible`);\n this.player.container.classList.add(`${this.player.options.classPrefix}-controls-visible`);\n this.player.state.controlsVisible = true;\n\n clearTimeout(this.hideTimeout);\n\n if (this.player.state.playing) {\n this.hideTimeout = setTimeout(() => {\n this.element.classList.remove(`${this.player.options.classPrefix}-controls-visible`);\n this.player.container.classList.remove(`${this.player.options.classPrefix}-controls-visible`);\n this.player.state.controlsVisible = false;\n }, this.player.options.hideControlsDelay);\n }\n };\n\n this.player.container.addEventListener('mousemove', showControls);\n this.player.container.addEventListener('touchstart', showControls);\n this.player.container.addEventListener('click', showControls);\n\n // Show controls on focus\n this.element.addEventListener('focusin', showControls);\n\n // Always show when paused\n this.player.on('pause', () => {\n showControls();\n clearTimeout(this.hideTimeout);\n });\n\n this.player.on('play', () => {\n showControls();\n });\n\n // Initial state\n showControls();\n }\n\n show() {\n this.element.style.display = '';\n }\n\n hide() {\n this.element.style.display = 'none';\n }\n\n destroy() {\n if (this.hideTimeout) {\n clearTimeout(this.hideTimeout);\n }\n\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n }\n}\n\n", "/**\n * Caption/Subtitle Manager\n */\n\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { i18n } from '../i18n/i18n.js';\n\nexport class CaptionManager {\n constructor(player) {\n this.player = player;\n this.element = null;\n this.tracks = [];\n this.currentTrack = null;\n this.currentCue = null;\n \n this.init();\n }\n\n init() {\n this.createElement();\n this.loadTracks();\n this.attachEvents();\n \n if (this.player.options.captionsDefault && this.tracks.length > 0) {\n this.enable();\n }\n }\n\n createElement() {\n this.element = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-captions`,\n attributes: {\n 'aria-live': 'polite',\n 'aria-atomic': 'true',\n 'role': 'region',\n 'aria-label': i18n.t('player.captions')\n }\n });\n\n // Apply caption styles\n this.updateStyles();\n \n // Append to videoWrapper if it exists, otherwise to container\n const target = this.player.videoWrapper || this.player.container;\n target.appendChild(this.element);\n }\n\n loadTracks() {\n const textTracks = this.player.element.textTracks;\n \n for (let i = 0; i < textTracks.length; i++) {\n const track = textTracks[i];\n \n if (track.kind === 'subtitles' || track.kind === 'captions') {\n this.tracks.push({\n track: track,\n language: track.language,\n label: track.label,\n kind: track.kind,\n index: i\n });\n \n // Disable all tracks initially\n track.mode = 'hidden';\n }\n }\n }\n\n attachEvents() {\n this.player.on('timeupdate', () => {\n this.updateCaptions();\n });\n\n this.player.on('captionschange', () => {\n this.updateStyles();\n });\n }\n\n enable(trackIndex = 0) {\n if (this.tracks.length === 0) {\n return;\n }\n\n // Disable current track\n if (this.currentTrack) {\n this.currentTrack.track.mode = 'hidden';\n }\n\n // Enable selected track\n const selectedTrack = this.tracks[trackIndex];\n \n if (selectedTrack) {\n // Set to 'hidden' not 'showing' to prevent browser from displaying native captions\n // We'll handle the display ourselves\n selectedTrack.track.mode = 'hidden';\n this.currentTrack = selectedTrack;\n this.player.state.captionsEnabled = true;\n \n // Remove any existing cuechange listener\n if (this.cueChangeHandler) {\n selectedTrack.track.removeEventListener('cuechange', this.cueChangeHandler);\n }\n \n // Add event listener for cue changes\n this.cueChangeHandler = () => {\n this.updateCaptions();\n };\n selectedTrack.track.addEventListener('cuechange', this.cueChangeHandler);\n \n this.element.style.display = 'block';\n \n this.player.emit('captionsenabled', selectedTrack);\n }\n }\n\n disable() {\n if (this.currentTrack) {\n this.currentTrack.track.mode = 'hidden';\n this.currentTrack = null;\n }\n\n this.element.style.display = 'none';\n this.element.innerHTML = '';\n this.currentCue = null;\n this.player.state.captionsEnabled = false;\n this.player.emit('captionsdisabled');\n }\n\n updateCaptions() {\n if (!this.currentTrack) {\n return;\n }\n \n if (!this.currentTrack.track.activeCues) {\n return;\n }\n\n const activeCues = this.currentTrack.track.activeCues;\n \n if (activeCues.length > 0) {\n const cue = activeCues[0];\n \n // Only update if the cue has changed\n if (this.currentCue !== cue) {\n this.currentCue = cue;\n \n // Parse and display cue text\n let text = cue.text;\n \n // Handle VTT formatting\n text = this.parseVTTFormatting(text);\n \n this.element.innerHTML = DOMUtils.sanitizeHTML(text);\n \n // Make sure it's visible when there's content\n this.element.style.display = 'block';\n \n this.player.emit('captionchange', cue);\n }\n } else if (this.currentCue) {\n // Clear caption\n this.element.innerHTML = '';\n this.element.style.display = 'none';\n this.currentCue = null;\n }\n }\n\n parseVTTFormatting(text) {\n // Basic VTT tag support\n text = text.replace(/<c[^>]*>(.*?)<\\/c>/g, '<span class=\"caption-class\">$1</span>');\n text = text.replace(/<b>(.*?)<\\/b>/g, '<strong>$1</strong>');\n text = text.replace(/<i>(.*?)<\\/i>/g, '<em>$1</em>');\n text = text.replace(/<u>(.*?)<\\/u>/g, '<u>$1</u>');\n \n // Voice tags\n text = text.replace(/<v\\s+([^>]+)>(.*?)<\\/v>/g, '<span class=\"caption-voice\" data-voice=\"$1\">$2</span>');\n \n return text;\n }\n\n updateStyles() {\n if (!this.element) return;\n\n const options = this.player.options;\n \n this.element.style.fontSize = options.captionsFontSize;\n this.element.style.fontFamily = options.captionsFontFamily;\n this.element.style.color = options.captionsColor;\n this.element.style.backgroundColor = this.hexToRgba(\n options.captionsBackgroundColor, \n options.captionsOpacity\n );\n }\n\n hexToRgba(hex, alpha) {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n if (result) {\n return `rgba(${parseInt(result[1], 16)}, ${parseInt(result[2], 16)}, ${parseInt(result[3], 16)}, ${alpha})`;\n }\n return hex;\n }\n\n setCaptionStyle(property, value) {\n switch (property) {\n case 'fontSize':\n this.player.options.captionsFontSize = value;\n break;\n case 'fontFamily':\n this.player.options.captionsFontFamily = value;\n break;\n case 'color':\n this.player.options.captionsColor = value;\n break;\n case 'backgroundColor':\n this.player.options.captionsBackgroundColor = value;\n break;\n case 'opacity':\n this.player.options.captionsOpacity = value;\n break;\n }\n \n this.updateStyles();\n this.player.emit('captionschange');\n }\n\n getAvailableTracks() {\n return this.tracks.map((t, index) => ({\n index,\n language: t.language,\n label: t.label || t.language,\n kind: t.kind\n }));\n }\n\n switchTrack(trackIndex) {\n if (trackIndex >= 0 && trackIndex < this.tracks.length) {\n this.disable();\n this.enable(trackIndex);\n }\n }\n\n destroy() {\n this.disable();\n \n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n }\n}\n\n", "/**\n * Keyboard Accessibility Manager\n */\n\nexport class KeyboardManager {\n constructor(player) {\n this.player = player;\n this.shortcuts = player.options.keyboardShortcuts;\n \n this.init();\n }\n\n init() {\n this.attachEvents();\n }\n\n attachEvents() {\n // Listen for keyboard events on the player container\n this.player.container.addEventListener('keydown', (e) => {\n this.handleKeydown(e);\n });\n\n // Make player container focusable\n if (!this.player.container.hasAttribute('tabindex')) {\n this.player.container.setAttribute('tabindex', '0');\n }\n }\n\n handleKeydown(e) {\n // Don't handle if target is an input element\n if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.tagName === 'SELECT') {\n return;\n }\n\n const key = e.key;\n let handled = false;\n\n // Check each shortcut category\n for (const [action, keys] of Object.entries(this.shortcuts)) {\n if (keys.includes(key)) {\n handled = this.executeAction(action, e);\n if (handled) {\n e.preventDefault();\n e.stopPropagation();\n this.announceAction(action);\n break;\n }\n }\n }\n }\n\n executeAction(action, event) {\n switch (action) {\n case 'play-pause':\n this.player.toggle();\n return true;\n\n case 'volume-up':\n this.player.setVolume(Math.min(1, this.player.state.volume + 0.1));\n return true;\n\n case 'volume-down':\n this.player.setVolume(Math.max(0, this.player.state.volume - 0.1));\n return true;\n\n case 'seek-forward':\n this.player.seekForward();\n return true;\n\n case 'seek-backward':\n this.player.seekBackward();\n return true;\n\n case 'seek-forward-large':\n this.player.seekForward(this.player.options.seekIntervalLarge);\n return true;\n\n case 'seek-backward-large':\n this.player.seekBackward(this.player.options.seekIntervalLarge);\n return true;\n\n case 'mute':\n this.player.toggleMute();\n return true;\n\n case 'fullscreen':\n this.player.toggleFullscreen();\n return true;\n\n case 'captions':\n // If only one caption track, toggle on/off\n // If multiple tracks, open caption menu\n if (this.player.captionManager && this.player.captionManager.tracks.length > 1) {\n const captionsButton = document.querySelector('.vidply-captions');\n if (captionsButton && this.player.controlBar) {\n this.player.controlBar.showCaptionsMenu(captionsButton);\n }\n } else {\n this.player.toggleCaptions();\n }\n return true;\n\n case 'speed-up':\n this.player.setPlaybackSpeed(\n Math.min(2, this.player.state.playbackSpeed + 0.25)\n );\n return true;\n\n case 'speed-down':\n this.player.setPlaybackSpeed(\n Math.max(0.25, this.player.state.playbackSpeed - 0.25)\n );\n return true;\n\n case 'settings':\n this.player.showSettings();\n return true;\n\n default:\n return false;\n }\n }\n\n announceAction(action) {\n if (!this.player.options.screenReaderAnnouncements) return;\n\n let message = '';\n\n switch (action) {\n case 'play-pause':\n message = this.player.state.playing ? 'Playing' : 'Paused';\n break;\n case 'volume-up':\n message = `Volume ${Math.round(this.player.state.volume * 100)}%`;\n break;\n case 'volume-down':\n message = `Volume ${Math.round(this.player.state.volume * 100)}%`;\n break;\n case 'mute':\n message = this.player.state.muted ? 'Muted' : 'Unmuted';\n break;\n case 'fullscreen':\n message = this.player.state.fullscreen ? 'Fullscreen' : 'Exit fullscreen';\n break;\n case 'captions':\n message = this.player.state.captionsEnabled ? 'Captions on' : 'Captions off';\n break;\n case 'speed-up':\n case 'speed-down':\n message = `Speed ${this.player.state.playbackSpeed}x`;\n break;\n }\n\n if (message) {\n this.announce(message);\n }\n }\n\n announce(message, priority = 'polite') {\n // Create or get announcement element\n let announcer = document.getElementById('vidply-announcer');\n \n if (!announcer) {\n announcer = document.createElement('div');\n announcer.id = 'vidply-announcer';\n announcer.className = 'vidply-sr-only';\n announcer.setAttribute('aria-live', priority);\n announcer.setAttribute('aria-atomic', 'true');\n announcer.style.cssText = `\n position: absolute;\n left: -10000px;\n width: 1px;\n height: 1px;\n overflow: hidden;\n `;\n document.body.appendChild(announcer);\n }\n\n // Clear and set new message\n announcer.textContent = '';\n setTimeout(() => {\n announcer.textContent = message;\n }, 100);\n }\n\n updateShortcut(action, keys) {\n if (Array.isArray(keys)) {\n this.shortcuts[action] = keys;\n }\n }\n\n destroy() {\n // Event listeners are automatically removed when the container is destroyed\n }\n}\n\n", "/**\n * Settings Dialog Component\n */\n\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { createIconElement } from '../icons/Icons.js';\nimport { i18n } from '../i18n/i18n.js';\n\nexport class SettingsDialog {\n constructor(player) {\n this.player = player;\n this.element = null;\n this.isOpen = false;\n \n this.init();\n }\n\n init() {\n this.createElement();\n }\n\n createElement() {\n // Create overlay\n this.overlay = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-overlay`,\n attributes: {\n 'role': 'dialog',\n 'aria-modal': 'true',\n 'aria-label': i18n.t('settings.title')\n }\n });\n\n this.overlay.style.display = 'none';\n\n // Create dialog\n this.element = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-dialog`\n });\n\n // Header\n const header = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-header`\n });\n\n const title = DOMUtils.createElement('h2', {\n textContent: i18n.t('settings.title'),\n attributes: {\n 'id': `${this.player.options.classPrefix}-settings-title`\n }\n });\n\n const closeButton = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-settings-close`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('settings.close')\n }\n });\n closeButton.appendChild(createIconElement('close'));\n closeButton.addEventListener('click', () => this.hide());\n\n header.appendChild(title);\n header.appendChild(closeButton);\n\n // Content\n const content = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-content`\n });\n\n content.appendChild(this.createSpeedSettings());\n \n if (this.player.captionManager && this.player.captionManager.tracks.length > 0) {\n content.appendChild(this.createCaptionSettings());\n }\n\n // Footer\n const footer = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-footer`\n });\n\n const resetButton = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button`,\n textContent: i18n.t('settings.reset'),\n attributes: {\n 'type': 'button'\n }\n });\n resetButton.addEventListener('click', () => this.resetSettings());\n\n footer.appendChild(resetButton);\n\n // Assemble dialog\n this.element.appendChild(header);\n this.element.appendChild(content);\n this.element.appendChild(footer);\n\n this.overlay.appendChild(this.element);\n this.player.container.appendChild(this.overlay);\n\n // Attach events\n this.overlay.addEventListener('click', (e) => {\n if (e.target === this.overlay) {\n this.hide();\n }\n });\n\n // Escape key to close\n document.addEventListener('keydown', (e) => {\n if (e.key === 'Escape' && this.isOpen) {\n this.hide();\n }\n });\n }\n\n formatSpeedLabel(speed) {\n // Special case: 1x is \"Normal\" (translated)\n if (speed === 1) {\n return i18n.t('speeds.normal');\n }\n \n // For other speeds, format with locale-specific decimal separator\n const speedStr = speed.toLocaleString(i18n.getLanguage(), {\n minimumFractionDigits: 0,\n maximumFractionDigits: 2\n });\n \n return `${speedStr}\u00D7`;\n }\n\n createSpeedSettings() {\n const section = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-section`\n });\n\n const label = DOMUtils.createElement('label', {\n textContent: i18n.t('settings.speed'),\n attributes: {\n 'for': `${this.player.options.classPrefix}-speed-select`\n }\n });\n\n const select = DOMUtils.createElement('select', {\n className: `${this.player.options.classPrefix}-settings-select`,\n attributes: {\n 'id': `${this.player.options.classPrefix}-speed-select`\n }\n });\n\n const speeds = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];\n \n speeds.forEach(speed => {\n const option = DOMUtils.createElement('option', {\n textContent: this.formatSpeedLabel(speed),\n attributes: {\n 'value': String(speed)\n }\n });\n \n if (speed === this.player.state.playbackSpeed) {\n option.selected = true;\n }\n \n select.appendChild(option);\n });\n\n select.addEventListener('change', (e) => {\n this.player.setPlaybackSpeed(parseFloat(e.target.value));\n });\n\n section.appendChild(label);\n section.appendChild(select);\n\n return section;\n }\n\n createCaptionSettings() {\n const section = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-section`\n });\n\n const heading = DOMUtils.createElement('h3', {\n textContent: i18n.t('settings.captions')\n });\n\n section.appendChild(heading);\n\n // Caption track selection\n const trackLabel = DOMUtils.createElement('label', {\n textContent: i18n.t('captions.select'),\n attributes: {\n 'for': `${this.player.options.classPrefix}-caption-track-select`\n }\n });\n\n const trackSelect = DOMUtils.createElement('select', {\n className: `${this.player.options.classPrefix}-settings-select`,\n attributes: {\n 'id': `${this.player.options.classPrefix}-caption-track-select`\n }\n });\n\n // Off option\n const offOption = DOMUtils.createElement('option', {\n textContent: i18n.t('captions.off'),\n attributes: { 'value': '-1' }\n });\n trackSelect.appendChild(offOption);\n\n // Available tracks\n const tracks = this.player.captionManager.getAvailableTracks();\n tracks.forEach(track => {\n const option = DOMUtils.createElement('option', {\n textContent: track.label,\n attributes: { 'value': String(track.index) }\n });\n trackSelect.appendChild(option);\n });\n\n trackSelect.addEventListener('change', (e) => {\n const index = parseInt(e.target.value);\n if (index === -1) {\n this.player.disableCaptions();\n } else {\n this.player.captionManager.switchTrack(index);\n }\n });\n\n section.appendChild(trackLabel);\n section.appendChild(trackSelect);\n\n // Font size\n section.appendChild(this.createCaptionStyleControl('fontSize', i18n.t('captions.fontSize'), [\n { label: i18n.t('fontSizes.small'), value: '80%' },\n { label: i18n.t('fontSizes.medium'), value: '100%' },\n { label: i18n.t('fontSizes.large'), value: '120%' },\n { label: i18n.t('fontSizes.xlarge'), value: '150%' }\n ]));\n\n // Font family\n section.appendChild(this.createCaptionStyleControl('fontFamily', i18n.t('captions.fontFamily'), [\n { label: i18n.t('fontFamilies.sansSerif'), value: 'sans-serif' },\n { label: i18n.t('fontFamilies.serif'), value: 'serif' },\n { label: i18n.t('fontFamilies.monospace'), value: 'monospace' }\n ]));\n\n // Color controls\n section.appendChild(this.createColorControl('color', i18n.t('captions.color')));\n section.appendChild(this.createColorControl('backgroundColor', i18n.t('captions.backgroundColor')));\n\n // Opacity\n section.appendChild(this.createRangeControl('opacity', i18n.t('captions.opacity'), 0, 1, 0.1));\n\n return section;\n }\n\n createCaptionStyleControl(property, label, options) {\n const wrapper = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-control`\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n attributes: {\n 'for': `${this.player.options.classPrefix}-caption-${property}`\n }\n });\n\n const select = DOMUtils.createElement('select', {\n className: `${this.player.options.classPrefix}-settings-select`,\n attributes: {\n 'id': `${this.player.options.classPrefix}-caption-${property}`\n }\n });\n\n options.forEach(opt => {\n const option = DOMUtils.createElement('option', {\n textContent: opt.label,\n attributes: { 'value': opt.value }\n });\n \n if (opt.value === this.player.options[`captions${property.charAt(0).toUpperCase() + property.slice(1)}`]) {\n option.selected = true;\n }\n \n select.appendChild(option);\n });\n\n select.addEventListener('change', (e) => {\n this.player.captionManager.setCaptionStyle(property, e.target.value);\n });\n\n wrapper.appendChild(labelEl);\n wrapper.appendChild(select);\n\n return wrapper;\n }\n\n createColorControl(property, label) {\n const wrapper = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-control`\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n attributes: {\n 'for': `${this.player.options.classPrefix}-caption-${property}`\n }\n });\n\n const input = DOMUtils.createElement('input', {\n className: `${this.player.options.classPrefix}-settings-color`,\n attributes: {\n 'type': 'color',\n 'id': `${this.player.options.classPrefix}-caption-${property}`,\n 'value': this.player.options[`captions${property.charAt(0).toUpperCase() + property.slice(1)}`]\n }\n });\n\n input.addEventListener('change', (e) => {\n this.player.captionManager.setCaptionStyle(property, e.target.value);\n });\n\n wrapper.appendChild(labelEl);\n wrapper.appendChild(input);\n\n return wrapper;\n }\n\n createRangeControl(property, label, min, max, step) {\n const wrapper = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-control`\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n attributes: {\n 'for': `${this.player.options.classPrefix}-caption-${property}`\n }\n });\n\n const input = DOMUtils.createElement('input', {\n className: `${this.player.options.classPrefix}-settings-range`,\n attributes: {\n 'type': 'range',\n 'id': `${this.player.options.classPrefix}-caption-${property}`,\n 'min': String(min),\n 'max': String(max),\n 'step': String(step),\n 'value': String(this.player.options[`captions${property.charAt(0).toUpperCase() + property.slice(1)}`])\n }\n });\n\n const valueDisplay = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-settings-value`,\n textContent: String(this.player.options[`captions${property.charAt(0).toUpperCase() + property.slice(1)}`])\n });\n\n input.addEventListener('input', (e) => {\n const value = parseFloat(e.target.value);\n valueDisplay.textContent = value.toFixed(1);\n this.player.captionManager.setCaptionStyle(property, value);\n });\n\n wrapper.appendChild(labelEl);\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n\n return wrapper;\n }\n\n resetSettings() {\n // Reset to default values\n this.player.setPlaybackSpeed(1);\n \n if (this.player.captionManager) {\n this.player.captionManager.setCaptionStyle('fontSize', '100%');\n this.player.captionManager.setCaptionStyle('fontFamily', 'sans-serif');\n this.player.captionManager.setCaptionStyle('color', '#FFFFFF');\n this.player.captionManager.setCaptionStyle('backgroundColor', '#000000');\n this.player.captionManager.setCaptionStyle('opacity', 0.8);\n }\n\n // Refresh dialog\n this.hide();\n setTimeout(() => this.show(), 100);\n }\n\n show() {\n this.overlay.style.display = 'flex';\n this.isOpen = true;\n \n // Focus the close button\n const closeButton = this.element.querySelector(`.${this.player.options.classPrefix}-settings-close`);\n if (closeButton) {\n closeButton.focus();\n }\n \n this.player.emit('settingsopen');\n }\n\n hide() {\n this.overlay.style.display = 'none';\n this.isOpen = false;\n \n // Return focus to settings button\n this.player.container.focus();\n \n this.player.emit('settingsclose');\n }\n\n destroy() {\n if (this.overlay && this.overlay.parentNode) {\n this.overlay.parentNode.removeChild(this.overlay);\n }\n }\n}\n\n", "/**\n * Transcript Manager Component\n * Manages transcript display and interaction\n */\n\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { TimeUtils } from '../utils/TimeUtils.js';\nimport { createIconElement } from '../icons/Icons.js';\nimport { i18n } from '../i18n/i18n.js';\n\nexport class TranscriptManager {\n constructor(player) {\n this.player = player;\n this.transcriptWindow = null;\n this.transcriptEntries = [];\n this.currentActiveEntry = null;\n this.isVisible = false;\n \n // Dragging state\n this.isDragging = false;\n this.dragOffsetX = 0;\n this.dragOffsetY = 0;\n \n // Store event handlers for cleanup\n this.handlers = {\n timeupdate: () => this.updateActiveEntry(),\n resize: null,\n mousemove: null,\n mouseup: null,\n touchmove: null,\n touchend: null,\n mousedown: null,\n touchstart: null,\n keydown: null\n };\n \n this.init();\n }\n\n init() {\n // Listen for time updates to highlight active transcript entry\n this.player.on('timeupdate', this.handlers.timeupdate);\n \n // Reposition transcript when entering/exiting fullscreen\n this.player.on('fullscreenchange', () => {\n if (this.isVisible) {\n // Add a small delay to ensure DOM has updated after fullscreen transition\n setTimeout(() => this.positionTranscript(), 100);\n }\n });\n }\n\n /**\n * Toggle transcript window visibility\n */\n toggleTranscript() {\n if (this.isVisible) {\n this.hideTranscript();\n } else {\n this.showTranscript();\n }\n }\n\n /**\n * Show transcript window\n */\n showTranscript() {\n if (this.transcriptWindow) {\n this.transcriptWindow.style.display = 'flex';\n this.isVisible = true;\n return;\n }\n\n // Create transcript window\n this.createTranscriptWindow();\n this.loadTranscriptData();\n \n // Show the window\n if (this.transcriptWindow) {\n this.transcriptWindow.style.display = 'flex';\n // Re-position after showing (in case window was resized while hidden)\n setTimeout(() => this.positionTranscript(), 0);\n }\n this.isVisible = true;\n }\n\n /**\n * Hide transcript window\n */\n hideTranscript() {\n if (this.transcriptWindow) {\n this.transcriptWindow.style.display = 'none';\n this.isVisible = false;\n }\n }\n\n /**\n * Create the transcript window UI\n */\n createTranscriptWindow() {\n this.transcriptWindow = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-window`,\n attributes: {\n 'role': 'dialog',\n 'aria-label': 'Video Transcript',\n 'tabindex': '-1'\n }\n });\n\n // Header (draggable)\n this.transcriptHeader = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-header`,\n attributes: {\n 'aria-label': 'Drag to reposition transcript. Use arrow keys to move, Home to reset position, Escape to close.',\n 'tabindex': '0'\n }\n });\n\n const title = DOMUtils.createElement('h3', {\n textContent: i18n.t('transcript.title')\n });\n\n const closeButton = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-transcript-close`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('transcript.close')\n }\n });\n closeButton.appendChild(createIconElement('close'));\n closeButton.addEventListener('click', () => this.hideTranscript());\n\n this.transcriptHeader.appendChild(title);\n this.transcriptHeader.appendChild(closeButton);\n\n // Content container\n this.transcriptContent = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-content`\n });\n\n this.transcriptWindow.appendChild(this.transcriptHeader);\n this.transcriptWindow.appendChild(this.transcriptContent);\n\n // Append to player container\n this.player.container.appendChild(this.transcriptWindow);\n \n // Position it next to the video wrapper\n this.positionTranscript();\n \n // Setup drag functionality\n this.setupDragAndDrop();\n \n // Re-position on window resize (debounced)\n let resizeTimeout;\n this.handlers.resize = () => {\n clearTimeout(resizeTimeout);\n resizeTimeout = setTimeout(() => this.positionTranscript(), 100);\n };\n window.addEventListener('resize', this.handlers.resize);\n }\n \n /**\n * Position transcript window next to video\n */\n positionTranscript() {\n if (!this.transcriptWindow || !this.player.videoWrapper || !this.isVisible) return;\n \n const isMobile = window.innerWidth < 640;\n const videoRect = this.player.videoWrapper.getBoundingClientRect();\n \n // Check if player is in fullscreen mode\n const isFullscreen = this.player.state.fullscreen;\n \n if (isMobile && !isFullscreen) {\n // Mobile: Position underneath the video and controls as part of the layout\n this.transcriptWindow.style.position = 'relative';\n this.transcriptWindow.style.left = '0';\n this.transcriptWindow.style.right = '0';\n this.transcriptWindow.style.bottom = 'auto';\n this.transcriptWindow.style.top = 'auto';\n this.transcriptWindow.style.width = '100%';\n this.transcriptWindow.style.maxWidth = '100%';\n this.transcriptWindow.style.maxHeight = '400px';\n this.transcriptWindow.style.height = 'auto';\n this.transcriptWindow.style.borderRadius = '0';\n this.transcriptWindow.style.transform = 'none';\n this.transcriptWindow.style.border = 'none';\n this.transcriptWindow.style.borderTop = '1px solid var(--vidply-border-light)';\n this.transcriptWindow.style.boxShadow = 'none';\n // Disable dragging on mobile\n if (this.transcriptHeader) {\n this.transcriptHeader.style.cursor = 'default';\n }\n \n // Ensure transcript is at the container level for proper stacking\n if (this.transcriptWindow.parentNode !== this.player.container) {\n this.player.container.appendChild(this.transcriptWindow);\n }\n } else if (isFullscreen) {\n // In fullscreen: position in bottom right corner inside the video\n this.transcriptWindow.style.position = 'fixed';\n this.transcriptWindow.style.left = 'auto';\n this.transcriptWindow.style.right = '20px';\n this.transcriptWindow.style.bottom = '80px'; // Above controls\n this.transcriptWindow.style.top = 'auto';\n this.transcriptWindow.style.maxHeight = 'calc(100vh - 180px)'; // Leave space for controls\n this.transcriptWindow.style.height = 'auto';\n this.transcriptWindow.style.width = '400px';\n this.transcriptWindow.style.maxWidth = '400px';\n this.transcriptWindow.style.borderRadius = '8px';\n this.transcriptWindow.style.border = '1px solid var(--vidply-border)';\n this.transcriptWindow.style.borderTop = '';\n \n // Move back to container for fullscreen\n if (this.transcriptWindow.parentNode !== this.player.container) {\n this.player.container.appendChild(this.transcriptWindow);\n }\n } else {\n // Desktop mode: position next to video\n this.transcriptWindow.style.position = 'absolute';\n this.transcriptWindow.style.left = `${videoRect.width + 8}px`;\n this.transcriptWindow.style.right = 'auto';\n this.transcriptWindow.style.bottom = 'auto';\n this.transcriptWindow.style.top = '0';\n this.transcriptWindow.style.height = `${videoRect.height}px`;\n this.transcriptWindow.style.maxHeight = 'none';\n this.transcriptWindow.style.width = '400px';\n this.transcriptWindow.style.maxWidth = '400px';\n this.transcriptWindow.style.borderRadius = '8px';\n this.transcriptWindow.style.border = '1px solid var(--vidply-border)';\n this.transcriptWindow.style.borderTop = '';\n // Enable dragging on desktop\n if (this.transcriptHeader) {\n this.transcriptHeader.style.cursor = 'move';\n }\n \n // Move back to container for desktop\n if (this.transcriptWindow.parentNode !== this.player.container) {\n this.player.container.appendChild(this.transcriptWindow);\n }\n }\n }\n\n /**\n * Load transcript data from caption/subtitle tracks\n */\n loadTranscriptData() {\n this.transcriptEntries = [];\n this.transcriptContent.innerHTML = '';\n\n // Get caption/subtitle tracks\n const textTracks = Array.from(this.player.element.textTracks);\n const transcriptTrack = textTracks.find(\n track => track.kind === 'captions' || track.kind === 'subtitles'\n );\n\n if (!transcriptTrack) {\n this.showNoTranscriptMessage();\n return;\n }\n\n // Enable track to load cues\n if (transcriptTrack.mode === 'disabled') {\n transcriptTrack.mode = 'hidden';\n }\n\n if (!transcriptTrack.cues || transcriptTrack.cues.length === 0) {\n // Wait for cues to load\n const loadingMessage = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-loading`,\n textContent: i18n.t('transcript.loading')\n });\n this.transcriptContent.appendChild(loadingMessage);\n\n const onLoad = () => {\n this.loadTranscriptData();\n };\n\n transcriptTrack.addEventListener('load', onLoad, { once: true });\n\n // Fallback timeout\n setTimeout(() => {\n if (transcriptTrack.cues && transcriptTrack.cues.length > 0) {\n this.loadTranscriptData();\n }\n }, 500);\n \n return;\n }\n\n // Build transcript from cues\n const cues = Array.from(transcriptTrack.cues);\n cues.forEach((cue, index) => {\n const entry = this.createTranscriptEntry(cue, index);\n this.transcriptEntries.push({\n element: entry,\n cue: cue,\n startTime: cue.startTime,\n endTime: cue.endTime\n });\n this.transcriptContent.appendChild(entry);\n });\n }\n\n /**\n * Create a single transcript entry element\n */\n createTranscriptEntry(cue, index) {\n const entry = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-entry`,\n attributes: {\n 'data-start': String(cue.startTime),\n 'data-end': String(cue.endTime),\n 'role': 'button',\n 'tabindex': '0'\n }\n });\n\n const timestamp = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-transcript-time`,\n textContent: TimeUtils.formatTime(cue.startTime)\n });\n\n const text = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-transcript-text`,\n textContent: this.stripVTTFormatting(cue.text)\n });\n\n entry.appendChild(timestamp);\n entry.appendChild(text);\n\n // Click to seek\n const seekToTime = () => {\n this.player.seek(cue.startTime);\n if (this.player.state.paused) {\n this.player.play();\n }\n };\n\n entry.addEventListener('click', seekToTime);\n entry.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n seekToTime();\n }\n });\n\n return entry;\n }\n\n /**\n * Strip VTT formatting tags from text\n */\n stripVTTFormatting(text) {\n // Remove VTT tags like <v Speaker>, <c>, etc.\n return text\n .replace(/<[^>]+>/g, '')\n .replace(/\\n/g, ' ')\n .trim();\n }\n\n /**\n * Show message when no transcript is available\n */\n showNoTranscriptMessage() {\n const message = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-empty`,\n textContent: i18n.t('transcript.noTranscript')\n });\n this.transcriptContent.appendChild(message);\n }\n\n /**\n * Update active transcript entry based on current time\n */\n updateActiveEntry() {\n if (!this.isVisible || this.transcriptEntries.length === 0) return;\n\n const currentTime = this.player.state.currentTime;\n \n // Find the entry that matches current time\n const activeEntry = this.transcriptEntries.find(\n entry => currentTime >= entry.startTime && currentTime < entry.endTime\n );\n\n if (activeEntry && activeEntry !== this.currentActiveEntry) {\n // Remove previous active class\n if (this.currentActiveEntry) {\n this.currentActiveEntry.element.classList.remove(\n `${this.player.options.classPrefix}-transcript-entry-active`\n );\n }\n\n // Add active class to current entry\n activeEntry.element.classList.add(\n `${this.player.options.classPrefix}-transcript-entry-active`\n );\n \n // Scroll to active entry\n this.scrollToEntry(activeEntry.element);\n \n this.currentActiveEntry = activeEntry;\n } else if (!activeEntry && this.currentActiveEntry) {\n // No active entry, remove active class\n this.currentActiveEntry.element.classList.remove(\n `${this.player.options.classPrefix}-transcript-entry-active`\n );\n this.currentActiveEntry = null;\n }\n }\n\n /**\n * Scroll transcript window to show active entry\n */\n scrollToEntry(entryElement) {\n if (!this.transcriptContent) return;\n\n const contentRect = this.transcriptContent.getBoundingClientRect();\n const entryRect = entryElement.getBoundingClientRect();\n\n // Check if entry is out of view\n if (entryRect.top < contentRect.top || entryRect.bottom > contentRect.bottom) {\n // Scroll to center the entry\n const scrollTop = entryElement.offsetTop - (this.transcriptContent.clientHeight / 2) + (entryElement.clientHeight / 2);\n this.transcriptContent.scrollTo({\n top: scrollTop,\n behavior: 'smooth'\n });\n }\n }\n\n /**\n * Setup drag and drop functionality\n */\n setupDragAndDrop() {\n if (!this.transcriptHeader || !this.transcriptWindow) return;\n\n // Create and store handler functions\n this.handlers.mousedown = (e) => {\n // Don't drag if clicking on close button\n if (e.target.closest(`.${this.player.options.classPrefix}-transcript-close`)) {\n return;\n }\n \n this.startDragging(e.clientX, e.clientY);\n e.preventDefault();\n };\n\n this.handlers.mousemove = (e) => {\n if (this.isDragging) {\n this.drag(e.clientX, e.clientY);\n }\n };\n\n this.handlers.mouseup = () => {\n if (this.isDragging) {\n this.stopDragging();\n }\n };\n\n this.handlers.touchstart = (e) => {\n if (e.target.closest(`.${this.player.options.classPrefix}-transcript-close`)) {\n return;\n }\n \n const isMobile = window.innerWidth < 640;\n const isFullscreen = this.player.state.fullscreen;\n const touch = e.touches[0];\n \n if (isMobile && !isFullscreen) {\n // Mobile (not fullscreen): No dragging/swiping, transcript is part of layout\n return;\n } else {\n // Desktop or fullscreen: Normal dragging\n this.startDragging(touch.clientX, touch.clientY);\n }\n };\n\n this.handlers.touchmove = (e) => {\n const isMobile = window.innerWidth < 640;\n const isFullscreen = this.player.state.fullscreen;\n \n if (isMobile && !isFullscreen) {\n // Mobile (not fullscreen): No dragging/swiping\n return;\n } else if (this.isDragging) {\n // Desktop or fullscreen: Normal drag\n const touch = e.touches[0];\n this.drag(touch.clientX, touch.clientY);\n e.preventDefault();\n }\n };\n\n this.handlers.touchend = () => {\n if (this.isDragging) {\n // Stop dragging\n this.stopDragging();\n }\n };\n\n this.handlers.keydown = (e) => {\n // Check if this is a navigation key\n if (!['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'Escape'].includes(e.key)) {\n return;\n }\n \n // Prevent default behavior and stop event from bubbling to transcript entries\n e.preventDefault();\n e.stopPropagation();\n \n // Handle special keys first\n if (e.key === 'Home') {\n this.resetPosition();\n return;\n }\n \n if (e.key === 'Escape') {\n this.hideTranscript();\n return;\n }\n \n const step = e.shiftKey ? 50 : 10; // Larger steps with Shift key\n \n // Get current position\n let currentLeft = parseFloat(this.transcriptWindow.style.left) || 0;\n let currentTop = parseFloat(this.transcriptWindow.style.top) || 0;\n \n // If window is still centered with transform, convert to absolute position first\n const computedStyle = window.getComputedStyle(this.transcriptWindow);\n if (computedStyle.transform !== 'none') {\n const rect = this.transcriptWindow.getBoundingClientRect();\n currentLeft = rect.left;\n currentTop = rect.top;\n this.transcriptWindow.style.transform = 'none';\n this.transcriptWindow.style.left = `${currentLeft}px`;\n this.transcriptWindow.style.top = `${currentTop}px`;\n }\n \n // Calculate new position based on arrow key\n let newX = currentLeft;\n let newY = currentTop;\n\n switch(e.key) {\n case 'ArrowLeft':\n newX -= step;\n break;\n case 'ArrowRight':\n newX += step;\n break;\n case 'ArrowUp':\n newY -= step;\n break;\n case 'ArrowDown':\n newY += step;\n break;\n }\n\n // Set new position directly\n this.transcriptWindow.style.left = `${newX}px`;\n this.transcriptWindow.style.top = `${newY}px`;\n };\n\n // Add event listeners using stored handlers\n this.transcriptHeader.addEventListener('mousedown', this.handlers.mousedown);\n document.addEventListener('mousemove', this.handlers.mousemove);\n document.addEventListener('mouseup', this.handlers.mouseup);\n \n this.transcriptHeader.addEventListener('touchstart', this.handlers.touchstart);\n document.addEventListener('touchmove', this.handlers.touchmove);\n document.addEventListener('touchend', this.handlers.touchend);\n \n this.transcriptHeader.addEventListener('keydown', this.handlers.keydown);\n }\n\n /**\n * Start dragging\n */\n startDragging(clientX, clientY) {\n // Get current rendered position (this is where it actually appears on screen)\n const rect = this.transcriptWindow.getBoundingClientRect();\n \n // Get the parent container position (player container)\n const containerRect = this.player.container.getBoundingClientRect();\n \n // Calculate position RELATIVE to container (not viewport)\n const relativeLeft = rect.left - containerRect.left;\n const relativeTop = rect.top - containerRect.top;\n \n // If window is centered with transform, convert to absolute position\n const computedStyle = window.getComputedStyle(this.transcriptWindow);\n if (computedStyle.transform !== 'none') {\n // Remove transform and set position relative to container\n this.transcriptWindow.style.transform = 'none';\n this.transcriptWindow.style.left = `${relativeLeft}px`;\n this.transcriptWindow.style.top = `${relativeTop}px`;\n }\n \n // Calculate offset based on viewport coordinates (where user clicked)\n this.dragOffsetX = clientX - rect.left;\n this.dragOffsetY = clientY - rect.top;\n \n this.isDragging = true;\n this.transcriptWindow.classList.add(`${this.player.options.classPrefix}-transcript-dragging`);\n document.body.style.cursor = 'grabbing';\n document.body.style.userSelect = 'none';\n }\n\n /**\n * Perform drag\n */\n drag(clientX, clientY) {\n if (!this.isDragging) return;\n\n // Calculate new viewport position based on mouse position minus the offset\n const newViewportX = clientX - this.dragOffsetX;\n const newViewportY = clientY - this.dragOffsetY;\n \n // Convert to position relative to container\n const containerRect = this.player.container.getBoundingClientRect();\n const newX = newViewportX - containerRect.left;\n const newY = newViewportY - containerRect.top;\n \n // During drag, set position relative to container\n this.transcriptWindow.style.left = `${newX}px`;\n this.transcriptWindow.style.top = `${newY}px`;\n }\n\n /**\n * Stop dragging\n */\n stopDragging() {\n this.isDragging = false;\n this.transcriptWindow.classList.remove(`${this.player.options.classPrefix}-transcript-dragging`);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n }\n\n /**\n * Set window position with boundary constraints\n */\n setPosition(x, y) {\n const rect = this.transcriptWindow.getBoundingClientRect();\n \n // Use document dimensions for fixed positioning\n const viewportWidth = document.documentElement.clientWidth;\n const viewportHeight = document.documentElement.clientHeight;\n \n // Very relaxed boundaries - allow window to go mostly off-screen\n // Just keep a small part visible so user can always drag it back\n const minVisible = 100; // Keep at least 100px visible\n const minX = -(rect.width - minVisible); // Can go way off-screen to the left\n const minY = -(rect.height - minVisible); // Can go way off-screen to the top\n const maxX = viewportWidth - minVisible; // Can go way off-screen to the right\n const maxY = viewportHeight - minVisible; // Can go way off-screen to the bottom\n \n // Clamp position to boundaries (very loose)\n x = Math.max(minX, Math.min(x, maxX));\n y = Math.max(minY, Math.min(y, maxY));\n \n this.transcriptWindow.style.left = `${x}px`;\n this.transcriptWindow.style.top = `${y}px`;\n this.transcriptWindow.style.transform = 'none';\n }\n\n /**\n * Reset position to center\n */\n resetPosition() {\n this.transcriptWindow.style.left = '50%';\n this.transcriptWindow.style.top = '50%';\n this.transcriptWindow.style.transform = 'translate(-50%, -50%)';\n }\n\n /**\n * Cleanup\n */\n destroy() {\n // Remove timeupdate listener from player\n if (this.handlers.timeupdate) {\n this.player.off('timeupdate', this.handlers.timeupdate);\n }\n\n // Remove drag event listeners\n if (this.transcriptHeader) {\n if (this.handlers.mousedown) {\n this.transcriptHeader.removeEventListener('mousedown', this.handlers.mousedown);\n }\n if (this.handlers.touchstart) {\n this.transcriptHeader.removeEventListener('touchstart', this.handlers.touchstart);\n }\n if (this.handlers.keydown) {\n this.transcriptHeader.removeEventListener('keydown', this.handlers.keydown);\n }\n }\n\n // Remove document-level listeners\n if (this.handlers.mousemove) {\n document.removeEventListener('mousemove', this.handlers.mousemove);\n }\n if (this.handlers.mouseup) {\n document.removeEventListener('mouseup', this.handlers.mouseup);\n }\n if (this.handlers.touchmove) {\n document.removeEventListener('touchmove', this.handlers.touchmove);\n }\n if (this.handlers.touchend) {\n document.removeEventListener('touchend', this.handlers.touchend);\n }\n \n // Remove window-level listeners\n if (this.handlers.resize) {\n window.removeEventListener('resize', this.handlers.resize);\n }\n\n // Clear handlers\n this.handlers = null;\n\n // Remove DOM element\n if (this.transcriptWindow && this.transcriptWindow.parentNode) {\n this.transcriptWindow.parentNode.removeChild(this.transcriptWindow);\n }\n \n this.transcriptWindow = null;\n this.transcriptHeader = null;\n this.transcriptContent = null;\n this.transcriptEntries = [];\n }\n}\n", "/**\n * VidPly - Universal Video Player\n * Main Player Class\n */\n\nimport { EventEmitter } from '../utils/EventEmitter.js';\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { TimeUtils } from '../utils/TimeUtils.js';\nimport { ControlBar } from '../controls/ControlBar.js';\nimport { CaptionManager } from '../controls/CaptionManager.js';\nimport { KeyboardManager } from '../controls/KeyboardManager.js';\nimport { SettingsDialog } from '../controls/SettingsDialog.js';\nimport { TranscriptManager } from '../controls/TranscriptManager.js';\nimport { HTML5Renderer } from '../renderers/HTML5Renderer.js';\nimport { YouTubeRenderer } from '../renderers/YouTubeRenderer.js';\nimport { VimeoRenderer } from '../renderers/VimeoRenderer.js';\nimport { HLSRenderer } from '../renderers/HLSRenderer.js';\nimport { createPlayOverlay } from '../icons/Icons.js';\nimport { i18n } from '../i18n/i18n.js';\n\nexport class Player extends EventEmitter {\n constructor(element, options = {}) {\n super();\n \n this.element = typeof element === 'string' ? document.querySelector(element) : element;\n if (!this.element) {\n throw new Error('VidPly: Element not found');\n }\n\n // Auto-create media element if a non-media element is provided\n if (this.element.tagName !== 'VIDEO' && this.element.tagName !== 'AUDIO') {\n const mediaType = options.mediaType || 'video';\n const mediaElement = document.createElement(mediaType);\n \n // Copy attributes from the div to the media element\n Array.from(this.element.attributes).forEach(attr => {\n if (attr.name !== 'id' && attr.name !== 'class' && !attr.name.startsWith('data-')) {\n mediaElement.setAttribute(attr.name, attr.value);\n }\n });\n \n // Copy any track elements from the div\n const tracks = this.element.querySelectorAll('track');\n tracks.forEach(track => {\n mediaElement.appendChild(track.cloneNode(true));\n });\n \n // Clear the div and insert the media element\n this.element.innerHTML = '';\n this.element.appendChild(mediaElement);\n \n // Update element reference to the actual media element\n this.element = mediaElement;\n }\n\n // Default options\n this.options = {\n // Display\n width: null,\n height: null,\n poster: null,\n responsive: true,\n fillContainer: false,\n \n // Playback\n autoplay: false,\n loop: false,\n muted: false,\n volume: 0.8,\n playbackSpeed: 1.0,\n preload: 'metadata',\n startTime: 0,\n \n // Controls\n controls: true,\n hideControlsDelay: 3000,\n playPauseButton: true,\n progressBar: true,\n currentTime: true,\n duration: true,\n volumeControl: true,\n muteButton: true,\n chaptersButton: true,\n qualityButton: true,\n captionStyleButton: true,\n speedButton: true,\n captionsButton: true,\n transcriptButton: true,\n fullscreenButton: true,\n pipButton: true,\n \n // Seeking\n seekInterval: 10,\n seekIntervalLarge: 30,\n \n // Captions\n captions: true,\n captionsDefault: false,\n captionsFontSize: '100%',\n captionsFontFamily: 'sans-serif',\n captionsColor: '#FFFFFF',\n captionsBackgroundColor: '#000000',\n captionsOpacity: 0.8,\n \n // Audio Description\n audioDescription: true,\n audioDescriptionSrc: null, // URL to audio-described version\n audioDescriptionButton: true,\n \n // Sign Language\n signLanguage: true,\n signLanguageSrc: null, // URL to sign language video\n signLanguageButton: true,\n signLanguagePosition: 'bottom-right', // Position: 'bottom-right', 'bottom-left', 'top-right', 'top-left'\n \n // Transcripts\n transcript: false,\n transcriptPosition: 'external',\n transcriptContainer: null,\n \n // Keyboard\n keyboard: true,\n keyboardShortcuts: {\n 'play-pause': [' ', 'p', 'k'],\n 'volume-up': ['ArrowUp'],\n 'volume-down': ['ArrowDown'],\n 'seek-forward': ['ArrowRight', 'f'],\n 'seek-backward': ['ArrowLeft', 'r'],\n 'seek-forward-large': ['l'],\n 'seek-backward-large': ['j'],\n 'mute': ['m'],\n 'fullscreen': ['f'],\n 'captions': ['c'],\n 'speed-up': ['>'],\n 'speed-down': ['<'],\n 'settings': ['s']\n },\n \n // Accessibility\n ariaLabels: {},\n screenReaderAnnouncements: true,\n highContrast: false,\n focusHighlight: true,\n \n // Languages\n language: 'en',\n languages: ['en'],\n \n // Advanced\n debug: false,\n classPrefix: 'vidply',\n iconType: 'svg',\n pauseOthersOnPlay: true,\n \n // Callbacks\n onReady: null,\n onPlay: null,\n onPause: null,\n onEnded: null,\n onTimeUpdate: null,\n onVolumeChange: null,\n onError: null,\n \n ...options\n };\n\n // State\n this.state = {\n ready: false,\n playing: false,\n paused: true,\n ended: false,\n buffering: false,\n seeking: false,\n muted: this.options.muted,\n volume: this.options.volume,\n currentTime: 0,\n duration: 0,\n playbackSpeed: this.options.playbackSpeed,\n fullscreen: false,\n pip: false,\n captionsEnabled: this.options.captionsDefault,\n currentCaption: null,\n controlsVisible: true,\n audioDescriptionEnabled: false,\n signLanguageEnabled: false\n };\n \n // Store original source for toggling\n this.originalSrc = null;\n this.audioDescriptionSrc = this.options.audioDescriptionSrc;\n this.signLanguageSrc = this.options.signLanguageSrc;\n this.signLanguageVideo = null;\n\n // Components\n this.container = null;\n this.renderer = null;\n this.controlBar = null;\n this.captionManager = null;\n this.keyboardManager = null;\n this.settingsDialog = null;\n\n // Initialize\n this.init();\n }\n\n async init() {\n try {\n this.log('Initializing VidPly player');\n \n // Auto-detect language from HTML lang attribute if not explicitly set\n if (!this.options.language || this.options.language === 'en') {\n const htmlLang = this.detectHtmlLanguage();\n if (htmlLang) {\n this.options.language = htmlLang;\n this.log(`Auto-detected language from HTML: ${htmlLang}`);\n }\n }\n \n // Set language\n i18n.setLanguage(this.options.language);\n \n // Create container\n this.createContainer();\n \n // Detect and initialize renderer (only if source exists)\n const src = this.element.src || this.element.querySelector('source')?.src;\n if (src) {\n await this.initializeRenderer();\n } else {\n this.log('No initial source - waiting for playlist or manual load');\n }\n \n // Create controls\n if (this.options.controls) {\n this.controlBar = new ControlBar(this);\n this.videoWrapper.appendChild(this.controlBar.element);\n }\n \n // Initialize captions\n if (this.options.captions) {\n this.captionManager = new CaptionManager(this);\n }\n \n // Initialize transcript\n if (this.options.transcript || this.options.transcriptButton) {\n this.transcriptManager = new TranscriptManager(this);\n }\n \n // Initialize keyboard controls\n if (this.options.keyboard) {\n this.keyboardManager = new KeyboardManager(this);\n }\n \n // Initialize settings dialog\n if (this.options.settingsButton) {\n this.settingsDialog = new SettingsDialog(this);\n }\n \n // Setup responsive handlers\n this.setupResponsiveHandlers();\n \n // Set initial state\n if (this.options.startTime > 0) {\n this.seek(this.options.startTime);\n }\n \n if (this.options.muted) {\n this.mute();\n }\n \n if (this.options.volume !== 0.8) {\n this.setVolume(this.options.volume);\n }\n \n // Mark as ready\n this.state.ready = true;\n this.emit('ready');\n \n if (this.options.onReady) {\n this.options.onReady.call(this);\n }\n \n // Autoplay if enabled\n if (this.options.autoplay) {\n this.play();\n }\n \n this.log('Player initialized successfully');\n } catch (error) {\n this.handleError(error);\n }\n }\n\n /**\n * Detect language from HTML lang attribute\n * @returns {string|null} Language code if available in translations, null otherwise\n */\n detectHtmlLanguage() {\n // Try to get lang from html element\n const htmlLang = document.documentElement.lang || document.documentElement.getAttribute('lang');\n \n if (!htmlLang) {\n return null;\n }\n \n // Normalize the language code (e.g., \"en-US\" -> \"en\", \"de-DE\" -> \"de\")\n const normalizedLang = htmlLang.toLowerCase().split('-')[0];\n \n // Check if this language is available in our translations\n const availableLanguages = ['en', 'de', 'es', 'fr', 'ja'];\n \n if (availableLanguages.includes(normalizedLang)) {\n return normalizedLang;\n }\n \n // Language not available, will fallback to English\n this.log(`Language \"${htmlLang}\" not available, using English as fallback`);\n return 'en';\n }\n\n createContainer() {\n // Create main container\n this.container = DOMUtils.createElement('div', {\n className: `${this.options.classPrefix}-player`,\n attributes: {\n 'role': 'region',\n 'aria-label': i18n.t('player.label'),\n 'tabindex': '0'\n }\n });\n\n // Add media type class\n const mediaType = this.element.tagName.toLowerCase();\n this.container.classList.add(`${this.options.classPrefix}-${mediaType}`);\n\n // Add responsive class\n if (this.options.responsive) {\n this.container.classList.add(`${this.options.classPrefix}-responsive`);\n }\n\n // Create video wrapper (for proper positioning of controls)\n this.videoWrapper = DOMUtils.createElement('div', {\n className: `${this.options.classPrefix}-video-wrapper`\n });\n\n // Wrap original element\n this.element.parentNode.insertBefore(this.container, this.element);\n this.container.appendChild(this.videoWrapper);\n this.videoWrapper.appendChild(this.element);\n \n // Hide native controls and set dimensions\n this.element.controls = false;\n this.element.removeAttribute('controls');\n this.element.setAttribute('tabindex', '-1'); // Remove from tab order\n this.element.style.width = '100%';\n this.element.style.height = '100%';\n \n // Set dimensions\n if (this.options.width) {\n this.container.style.width = typeof this.options.width === 'number' \n ? `${this.options.width}px` \n : this.options.width;\n }\n \n if (this.options.height) {\n this.container.style.height = typeof this.options.height === 'number'\n ? `${this.options.height}px`\n : this.options.height;\n }\n \n // Set poster\n if (this.options.poster && this.element.tagName === 'VIDEO') {\n this.element.poster = this.options.poster;\n }\n \n // Create centered play button overlay (only for video)\n if (this.element.tagName === 'VIDEO') {\n this.createPlayButtonOverlay();\n }\n \n // Make video/audio element clickable to toggle play/pause\n this.element.style.cursor = 'pointer';\n this.element.addEventListener('click', (e) => {\n // Prevent if clicking on native controls (shouldn't happen but just in case)\n if (e.target === this.element) {\n this.toggle();\n }\n });\n }\n\n createPlayButtonOverlay() {\n // Create complete SVG play button from Icons.js\n this.playButtonOverlay = createPlayOverlay();\n \n // Add click handler\n this.playButtonOverlay.addEventListener('click', () => {\n this.toggle();\n });\n \n // Add to video wrapper\n this.videoWrapper.appendChild(this.playButtonOverlay);\n \n // Show/hide based on play state\n this.on('play', () => {\n this.playButtonOverlay.style.opacity = '0';\n this.playButtonOverlay.style.pointerEvents = 'none';\n });\n \n this.on('pause', () => {\n this.playButtonOverlay.style.opacity = '1';\n this.playButtonOverlay.style.pointerEvents = 'auto';\n });\n \n this.on('ended', () => {\n this.playButtonOverlay.style.opacity = '1';\n this.playButtonOverlay.style.pointerEvents = 'auto';\n });\n }\n\n async initializeRenderer() {\n const src = this.element.src || this.element.querySelector('source')?.src;\n \n if (!src) {\n throw new Error('No media source found');\n }\n\n // Store original source for audio description toggling\n if (!this.originalSrc) {\n this.originalSrc = src;\n }\n\n // Detect media type\n let renderer;\n \n if (src.includes('youtube.com') || src.includes('youtu.be')) {\n renderer = YouTubeRenderer;\n } else if (src.includes('vimeo.com')) {\n renderer = VimeoRenderer;\n } else if (src.includes('.m3u8')) {\n renderer = HLSRenderer;\n } else {\n renderer = HTML5Renderer;\n }\n\n this.log(`Using ${renderer.name} renderer`);\n this.renderer = new renderer(this);\n await this.renderer.init();\n }\n\n /**\n * Load new media source (for playlists)\n * @param {Object} config - Media configuration\n * @param {string} config.src - Media source URL\n * @param {string} config.type - Media MIME type\n * @param {string} [config.poster] - Poster image URL\n * @param {Array} [config.tracks] - Text tracks (captions, chapters, etc.)\n */\n async load(config) {\n try {\n this.log('Loading new media:', config.src);\n \n // Pause current playback\n if (this.renderer) {\n this.pause();\n }\n \n // Clear existing text tracks\n const existingTracks = this.element.querySelectorAll('track');\n existingTracks.forEach(track => track.remove());\n \n // Update media element\n this.element.src = config.src;\n \n if (config.type) {\n this.element.type = config.type;\n }\n \n if (config.poster && this.element.tagName === 'VIDEO') {\n this.element.poster = config.poster;\n }\n \n // Add new text tracks\n if (config.tracks && config.tracks.length > 0) {\n config.tracks.forEach(trackConfig => {\n const track = document.createElement('track');\n track.src = trackConfig.src;\n track.kind = trackConfig.kind || 'captions';\n track.srclang = trackConfig.srclang || 'en';\n track.label = trackConfig.label || trackConfig.srclang;\n \n if (trackConfig.default) {\n track.default = true;\n }\n \n this.element.appendChild(track);\n });\n }\n \n // Check if we need to change renderer type\n const shouldChangeRenderer = this.shouldChangeRenderer(config.src);\n \n // Destroy old renderer if changing types\n if (shouldChangeRenderer && this.renderer) {\n this.renderer.destroy();\n this.renderer = null;\n }\n \n // Initialize or reinitialize renderer\n if (!this.renderer || shouldChangeRenderer) {\n await this.initializeRenderer();\n } else {\n // Just reload the current renderer with the updated element\n this.renderer.media = this.element; // Update media reference\n this.element.load();\n }\n \n // Reinitialize caption manager to pick up new tracks\n if (this.captionManager) {\n this.captionManager.destroy();\n this.captionManager = new CaptionManager(this);\n }\n \n this.emit('sourcechange', config);\n this.log('Media loaded successfully');\n \n } catch (error) {\n this.handleError(error);\n }\n }\n\n /**\n * Check if we need to change renderer type\n * @param {string} src - New source URL\n * @returns {boolean}\n */\n shouldChangeRenderer(src) {\n if (!this.renderer) return true;\n \n const isYouTube = src.includes('youtube.com') || src.includes('youtu.be');\n const isVimeo = src.includes('vimeo.com');\n const isHLS = src.includes('.m3u8');\n \n const currentRendererName = this.renderer.constructor.name;\n \n if (isYouTube && currentRendererName !== 'YouTubeRenderer') return true;\n if (isVimeo && currentRendererName !== 'VimeoRenderer') return true;\n if (isHLS && currentRendererName !== 'HLSRenderer') return true;\n if (!isYouTube && !isVimeo && !isHLS && currentRendererName !== 'HTML5Renderer') return true;\n \n return false;\n }\n\n // Playback controls\n play() {\n if (this.renderer) {\n this.renderer.play();\n }\n }\n\n pause() {\n if (this.renderer) {\n this.renderer.pause();\n }\n }\n\n stop() {\n this.pause();\n this.seek(0);\n }\n\n toggle() {\n if (this.state.playing) {\n this.pause();\n } else {\n this.play();\n }\n }\n\n seek(time) {\n if (this.renderer) {\n this.renderer.seek(time);\n }\n }\n\n seekForward(interval = this.options.seekInterval) {\n this.seek(Math.min(this.state.currentTime + interval, this.state.duration));\n }\n\n seekBackward(interval = this.options.seekInterval) {\n this.seek(Math.max(this.state.currentTime - interval, 0));\n }\n\n // Volume controls\n setVolume(volume) {\n const newVolume = Math.max(0, Math.min(1, volume));\n if (this.renderer) {\n this.renderer.setVolume(newVolume);\n }\n this.state.volume = newVolume;\n \n if (newVolume > 0 && this.state.muted) {\n this.state.muted = false;\n }\n }\n\n getVolume() {\n return this.state.volume;\n }\n\n mute() {\n if (this.renderer) {\n this.renderer.setMuted(true);\n }\n this.state.muted = true;\n }\n\n unmute() {\n if (this.renderer) {\n this.renderer.setMuted(false);\n }\n this.state.muted = false;\n }\n\n toggleMute() {\n if (this.state.muted) {\n this.unmute();\n } else {\n this.mute();\n }\n }\n\n // Playback speed\n setPlaybackSpeed(speed) {\n const newSpeed = Math.max(0.25, Math.min(2, speed));\n if (this.renderer) {\n this.renderer.setPlaybackSpeed(newSpeed);\n }\n this.state.playbackSpeed = newSpeed;\n this.emit('playbackspeedchange', newSpeed);\n }\n\n getPlaybackSpeed() {\n return this.state.playbackSpeed;\n }\n\n // Fullscreen\n enterFullscreen() {\n const elem = this.container;\n \n if (elem.requestFullscreen) {\n elem.requestFullscreen();\n } else if (elem.webkitRequestFullscreen) {\n elem.webkitRequestFullscreen();\n } else if (elem.mozRequestFullScreen) {\n elem.mozRequestFullScreen();\n } else if (elem.msRequestFullscreen) {\n elem.msRequestFullscreen();\n }\n \n this.state.fullscreen = true;\n this.container.classList.add(`${this.options.classPrefix}-fullscreen`);\n this.emit('fullscreenchange', true);\n }\n\n exitFullscreen() {\n if (document.exitFullscreen) {\n document.exitFullscreen();\n } else if (document.webkitExitFullscreen) {\n document.webkitExitFullscreen();\n } else if (document.mozCancelFullScreen) {\n document.mozCancelFullScreen();\n } else if (document.msExitFullscreen) {\n document.msExitFullscreen();\n }\n \n this.state.fullscreen = false;\n this.container.classList.remove(`${this.options.classPrefix}-fullscreen`);\n this.emit('fullscreenchange', false);\n }\n\n toggleFullscreen() {\n if (this.state.fullscreen) {\n this.exitFullscreen();\n } else {\n this.enterFullscreen();\n }\n }\n\n // Picture-in-Picture\n enterPiP() {\n if (this.element.requestPictureInPicture) {\n this.element.requestPictureInPicture();\n this.state.pip = true;\n this.emit('pipchange', true);\n }\n }\n\n exitPiP() {\n if (document.pictureInPictureElement) {\n document.exitPictureInPicture();\n this.state.pip = false;\n this.emit('pipchange', false);\n }\n }\n\n togglePiP() {\n if (this.state.pip) {\n this.exitPiP();\n } else {\n this.enterPiP();\n }\n }\n\n // Captions\n enableCaptions() {\n if (this.captionManager) {\n this.captionManager.enable();\n this.state.captionsEnabled = true;\n }\n }\n\n disableCaptions() {\n if (this.captionManager) {\n this.captionManager.disable();\n this.state.captionsEnabled = false;\n }\n }\n\n toggleCaptions() {\n if (this.state.captionsEnabled) {\n this.disableCaptions();\n } else {\n this.enableCaptions();\n }\n }\n\n // Audio Description\n async enableAudioDescription() {\n if (!this.audioDescriptionSrc) {\n console.warn('VidPly: No audio description source provided');\n return;\n }\n\n // Store current playback state\n const currentTime = this.state.currentTime;\n const wasPlaying = this.state.playing;\n\n // Switch to audio-described version\n this.element.src = this.audioDescriptionSrc;\n \n // Wait for new source to load\n await new Promise((resolve) => {\n const onLoadedMetadata = () => {\n this.element.removeEventListener('loadedmetadata', onLoadedMetadata);\n resolve();\n };\n this.element.addEventListener('loadedmetadata', onLoadedMetadata);\n });\n\n // Restore playback position\n this.seek(currentTime);\n \n if (wasPlaying) {\n this.play();\n }\n\n this.state.audioDescriptionEnabled = true;\n this.emit('audiodescriptionenabled');\n }\n\n async disableAudioDescription() {\n if (!this.originalSrc) {\n return;\n }\n\n // Store current playback state\n const currentTime = this.state.currentTime;\n const wasPlaying = this.state.playing;\n\n // Switch back to original version\n this.element.src = this.originalSrc;\n \n // Wait for new source to load\n await new Promise((resolve) => {\n const onLoadedMetadata = () => {\n this.element.removeEventListener('loadedmetadata', onLoadedMetadata);\n resolve();\n };\n this.element.addEventListener('loadedmetadata', onLoadedMetadata);\n });\n\n // Restore playback position\n this.seek(currentTime);\n \n if (wasPlaying) {\n this.play();\n }\n\n this.state.audioDescriptionEnabled = false;\n this.emit('audiodescriptiondisabled');\n }\n\n async toggleAudioDescription() {\n if (this.state.audioDescriptionEnabled) {\n await this.disableAudioDescription();\n } else {\n await this.enableAudioDescription();\n }\n }\n\n // Sign Language\n enableSignLanguage() {\n if (!this.signLanguageSrc) {\n console.warn('No sign language video source provided');\n return;\n }\n\n if (this.signLanguageVideo) {\n // Already exists, just show it\n this.signLanguageVideo.style.display = 'block';\n this.state.signLanguageEnabled = true;\n this.emit('signlanguageenabled');\n return;\n }\n\n // Create sign language video element\n this.signLanguageVideo = document.createElement('video');\n this.signLanguageVideo.className = 'vidply-sign-language-video';\n this.signLanguageVideo.src = this.signLanguageSrc;\n this.signLanguageVideo.setAttribute('aria-label', i18n.t('player.signLanguage'));\n \n // Set position based on options\n const position = this.options.signLanguagePosition || 'bottom-right';\n this.signLanguageVideo.classList.add(`vidply-sign-position-${position}`);\n \n // Sync with main video\n this.signLanguageVideo.muted = true; // Sign language video should be muted\n this.signLanguageVideo.currentTime = this.state.currentTime;\n if (!this.state.paused) {\n this.signLanguageVideo.play();\n }\n\n // Add to video wrapper (so it overlays the video, not the entire container)\n this.videoWrapper.appendChild(this.signLanguageVideo);\n\n // Create bound handlers to store references for cleanup\n this.signLanguageHandlers = {\n play: () => {\n if (this.signLanguageVideo) {\n this.signLanguageVideo.play();\n }\n },\n pause: () => {\n if (this.signLanguageVideo) {\n this.signLanguageVideo.pause();\n }\n },\n timeupdate: () => {\n if (this.signLanguageVideo && Math.abs(this.signLanguageVideo.currentTime - this.state.currentTime) > 0.5) {\n this.signLanguageVideo.currentTime = this.state.currentTime;\n }\n },\n ratechange: () => {\n if (this.signLanguageVideo) {\n this.signLanguageVideo.playbackRate = this.state.playbackSpeed;\n }\n }\n };\n\n // Sync playback\n this.on('play', this.signLanguageHandlers.play);\n this.on('pause', this.signLanguageHandlers.pause);\n this.on('timeupdate', this.signLanguageHandlers.timeupdate);\n this.on('ratechange', this.signLanguageHandlers.ratechange);\n\n this.state.signLanguageEnabled = true;\n this.emit('signlanguageenabled');\n }\n\n disableSignLanguage() {\n if (this.signLanguageVideo) {\n this.signLanguageVideo.style.display = 'none';\n }\n this.state.signLanguageEnabled = false;\n this.emit('signlanguagedisabled');\n }\n\n toggleSignLanguage() {\n if (this.state.signLanguageEnabled) {\n this.disableSignLanguage();\n } else {\n this.enableSignLanguage();\n }\n }\n\n cleanupSignLanguage() {\n // Remove event listeners\n if (this.signLanguageHandlers) {\n this.off('play', this.signLanguageHandlers.play);\n this.off('pause', this.signLanguageHandlers.pause);\n this.off('timeupdate', this.signLanguageHandlers.timeupdate);\n this.off('ratechange', this.signLanguageHandlers.ratechange);\n this.signLanguageHandlers = null;\n }\n\n // Remove video element\n if (this.signLanguageVideo && this.signLanguageVideo.parentNode) {\n this.signLanguageVideo.pause();\n this.signLanguageVideo.src = '';\n this.signLanguageVideo.parentNode.removeChild(this.signLanguageVideo);\n this.signLanguageVideo = null;\n }\n }\n\n // Settings\n showSettings() {\n if (this.settingsDialog) {\n this.settingsDialog.show();\n }\n }\n\n hideSettings() {\n if (this.settingsDialog) {\n this.settingsDialog.hide();\n }\n }\n\n // Utility methods\n getCurrentTime() {\n return this.state.currentTime;\n }\n\n getDuration() {\n return this.state.duration;\n }\n\n isPlaying() {\n return this.state.playing;\n }\n\n isPaused() {\n return this.state.paused;\n }\n\n isEnded() {\n return this.state.ended;\n }\n\n isMuted() {\n return this.state.muted;\n }\n\n isFullscreen() {\n return this.state.fullscreen;\n }\n\n // Error handling\n handleError(error) {\n this.log('Error:', error, 'error');\n this.emit('error', error);\n \n if (this.options.onError) {\n this.options.onError.call(this, error);\n }\n }\n\n // Logging\n log(message, type = 'log') {\n if (this.options.debug) {\n console[type](`[VidPly]`, message);\n }\n }\n\n // Setup responsive handlers\n setupResponsiveHandlers() {\n // Use ResizeObserver for efficient resize tracking\n if (typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const width = entry.contentRect.width;\n \n // Update control bar for viewport\n if (this.controlBar && typeof this.controlBar.updateControlsForViewport === 'function') {\n this.controlBar.updateControlsForViewport(width);\n }\n \n // Update transcript positioning\n if (this.transcriptManager && this.transcriptManager.isVisible) {\n this.transcriptManager.positionTranscript();\n }\n }\n });\n \n this.resizeObserver.observe(this.container);\n } else {\n // Fallback to window resize event\n this.resizeHandler = () => {\n const width = this.container.clientWidth;\n \n if (this.controlBar && typeof this.controlBar.updateControlsForViewport === 'function') {\n this.controlBar.updateControlsForViewport(width);\n }\n \n if (this.transcriptManager && this.transcriptManager.isVisible) {\n this.transcriptManager.positionTranscript();\n }\n };\n \n window.addEventListener('resize', this.resizeHandler);\n }\n \n // Also listen for orientation changes on mobile\n if (window.matchMedia) {\n this.orientationHandler = (e) => {\n // Wait for layout to settle\n setTimeout(() => {\n if (this.transcriptManager && this.transcriptManager.isVisible) {\n this.transcriptManager.positionTranscript();\n }\n }, 100);\n };\n \n const orientationQuery = window.matchMedia('(orientation: portrait)');\n if (orientationQuery.addEventListener) {\n orientationQuery.addEventListener('change', this.orientationHandler);\n } else if (orientationQuery.addListener) {\n // Fallback for older browsers\n orientationQuery.addListener(this.orientationHandler);\n }\n \n this.orientationQuery = orientationQuery;\n }\n }\n\n // Cleanup\n destroy() {\n this.log('Destroying player');\n \n if (this.renderer) {\n this.renderer.destroy();\n }\n \n if (this.controlBar) {\n this.controlBar.destroy();\n }\n \n if (this.captionManager) {\n this.captionManager.destroy();\n }\n \n if (this.keyboardManager) {\n this.keyboardManager.destroy();\n }\n \n if (this.settingsDialog) {\n this.settingsDialog.destroy();\n }\n \n if (this.transcriptManager) {\n this.transcriptManager.destroy();\n }\n \n // Cleanup sign language video and listeners\n this.cleanupSignLanguage();\n \n // Cleanup play overlay button\n if (this.playButtonOverlay && this.playButtonOverlay.parentNode) {\n this.playButtonOverlay.remove();\n this.playButtonOverlay = null;\n }\n \n // Cleanup resize observer\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n \n // Cleanup window resize handler\n if (this.resizeHandler) {\n window.removeEventListener('resize', this.resizeHandler);\n this.resizeHandler = null;\n }\n \n // Cleanup orientation change handler\n if (this.orientationQuery && this.orientationHandler) {\n if (this.orientationQuery.removeEventListener) {\n this.orientationQuery.removeEventListener('change', this.orientationHandler);\n } else if (this.orientationQuery.removeListener) {\n this.orientationQuery.removeListener(this.orientationHandler);\n }\n this.orientationQuery = null;\n this.orientationHandler = null;\n }\n \n // Remove container\n if (this.container && this.container.parentNode) {\n this.container.parentNode.insertBefore(this.element, this.container);\n this.container.parentNode.removeChild(this.container);\n }\n \n this.removeAllListeners();\n }\n}\n\n// Static instances tracker for pause others functionality\nPlayer.instances = [];\n\n", "/**\n * YouTube Renderer\n */\n\nexport class YouTubeRenderer {\n constructor(player) {\n this.player = player;\n this.youtube = null;\n this.videoId = null;\n this.isReady = false;\n this.iframe = null;\n }\n\n async init() {\n // Extract video ID from URL\n this.videoId = this.extractVideoId(this.player.element.src);\n \n if (!this.videoId) {\n throw new Error('Invalid YouTube URL');\n }\n\n // Load YouTube IFrame API\n await this.loadYouTubeAPI();\n\n // Create iframe\n this.createIframe();\n\n // Initialize player\n await this.initializePlayer();\n }\n\n extractVideoId(url) {\n const patterns = [\n /(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/)([^&\\s]+)/,\n /youtube\\.com\\/embed\\/([^&\\s]+)/\n ];\n\n for (const pattern of patterns) {\n const match = url.match(pattern);\n if (match && match[1]) {\n return match[1];\n }\n }\n\n return null;\n }\n\n async loadYouTubeAPI() {\n // Check if API is already loaded\n if (window.YT && window.YT.Player) {\n return Promise.resolve();\n }\n\n return new Promise((resolve, reject) => {\n // Check if script is already being loaded\n if (window.onYouTubeIframeAPIReady) {\n const originalCallback = window.onYouTubeIframeAPIReady;\n window.onYouTubeIframeAPIReady = () => {\n originalCallback();\n resolve();\n };\n return;\n }\n\n // Load the API script\n const tag = document.createElement('script');\n tag.src = 'https://www.youtube.com/iframe_api';\n \n window.onYouTubeIframeAPIReady = () => {\n resolve();\n };\n\n tag.onerror = () => reject(new Error('Failed to load YouTube API'));\n \n const firstScriptTag = document.getElementsByTagName('script')[0];\n firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n });\n }\n\n createIframe() {\n // Hide original element\n this.player.element.style.display = 'none';\n\n // Create container for iframe\n this.iframe = document.createElement('div');\n this.iframe.id = `youtube-player-${Math.random().toString(36).substr(2, 9)}`;\n this.iframe.style.width = '100%';\n this.iframe.style.height = '100%';\n \n this.player.element.parentNode.insertBefore(this.iframe, this.player.element);\n }\n\n async initializePlayer() {\n return new Promise((resolve) => {\n this.youtube = new window.YT.Player(this.iframe.id, {\n videoId: this.videoId,\n width: '100%',\n height: '100%',\n playerVars: {\n controls: 0,\n disablekb: 1,\n fs: 0,\n modestbranding: 1,\n rel: 0,\n showinfo: 0,\n iv_load_policy: 3,\n autoplay: this.player.options.autoplay ? 1 : 0,\n mute: this.player.options.muted ? 1 : 0,\n start: this.player.options.startTime || 0\n },\n events: {\n onReady: (event) => {\n this.isReady = true;\n this.attachEvents();\n resolve();\n },\n onStateChange: (event) => this.handleStateChange(event),\n onError: (event) => this.handleError(event)\n }\n });\n });\n }\n\n attachEvents() {\n // Set up polling for time updates (YouTube doesn't provide timeupdate events)\n this.timeUpdateInterval = setInterval(() => {\n if (this.isReady && this.youtube) {\n const currentTime = this.youtube.getCurrentTime();\n const duration = this.youtube.getDuration();\n \n this.player.state.currentTime = currentTime;\n this.player.state.duration = duration;\n \n this.player.emit('timeupdate', currentTime);\n }\n }, 250);\n\n // Initial metadata\n if (this.youtube.getDuration) {\n this.player.state.duration = this.youtube.getDuration();\n this.player.emit('loadedmetadata');\n }\n }\n\n handleStateChange(event) {\n const states = window.YT.PlayerState;\n\n switch (event.data) {\n case states.PLAYING:\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.state.buffering = false;\n this.player.emit('play');\n this.player.emit('playing');\n \n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n break;\n\n case states.PAUSED:\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n \n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n break;\n\n case states.ENDED:\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n \n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n \n if (this.player.options.loop) {\n this.youtube.seekTo(0);\n this.youtube.playVideo();\n }\n break;\n\n case states.BUFFERING:\n this.player.state.buffering = true;\n this.player.emit('waiting');\n break;\n\n case states.CUED:\n this.player.emit('loadedmetadata');\n break;\n }\n }\n\n handleError(event) {\n const errors = {\n 2: 'Invalid video ID',\n 5: 'HTML5 player error',\n 100: 'Video not found',\n 101: 'Video not allowed to be played in embedded players',\n 150: 'Video not allowed to be played in embedded players'\n };\n\n const error = new Error(errors[event.data] || 'YouTube player error');\n this.player.handleError(error);\n }\n\n play() {\n if (this.isReady && this.youtube) {\n this.youtube.playVideo();\n }\n }\n\n pause() {\n if (this.isReady && this.youtube) {\n this.youtube.pauseVideo();\n }\n }\n\n seek(time) {\n if (this.isReady && this.youtube) {\n this.youtube.seekTo(time, true);\n }\n }\n\n setVolume(volume) {\n if (this.isReady && this.youtube) {\n this.youtube.setVolume(volume * 100);\n this.player.state.volume = volume;\n }\n }\n\n setMuted(muted) {\n if (this.isReady && this.youtube) {\n if (muted) {\n this.youtube.mute();\n } else {\n this.youtube.unMute();\n }\n this.player.state.muted = muted;\n }\n }\n\n setPlaybackSpeed(speed) {\n if (this.isReady && this.youtube) {\n this.youtube.setPlaybackRate(speed);\n this.player.state.playbackSpeed = speed;\n }\n }\n\n destroy() {\n if (this.timeUpdateInterval) {\n clearInterval(this.timeUpdateInterval);\n }\n\n if (this.youtube && this.youtube.destroy) {\n this.youtube.destroy();\n }\n\n if (this.iframe && this.iframe.parentNode) {\n this.iframe.parentNode.removeChild(this.iframe);\n }\n\n // Show original element\n if (this.player.element) {\n this.player.element.style.display = '';\n }\n }\n}\n\n", "/**\n * Vimeo Renderer\n */\n\nexport class VimeoRenderer {\n constructor(player) {\n this.player = player;\n this.vimeo = null;\n this.videoId = null;\n this.isReady = false;\n this.iframe = null;\n }\n\n async init() {\n // Extract video ID from URL\n this.videoId = this.extractVideoId(this.player.element.src);\n \n if (!this.videoId) {\n throw new Error('Invalid Vimeo URL');\n }\n\n // Load Vimeo Player API\n await this.loadVimeoAPI();\n\n // Create iframe\n this.createIframe();\n\n // Initialize player\n await this.initializePlayer();\n }\n\n extractVideoId(url) {\n const patterns = [\n /vimeo\\.com\\/(\\d+)/,\n /vimeo\\.com\\/video\\/(\\d+)/,\n /player\\.vimeo\\.com\\/video\\/(\\d+)/\n ];\n\n for (const pattern of patterns) {\n const match = url.match(pattern);\n if (match && match[1]) {\n return match[1];\n }\n }\n\n return null;\n }\n\n async loadVimeoAPI() {\n // Check if API is already loaded\n if (window.Vimeo && window.Vimeo.Player) {\n return Promise.resolve();\n }\n\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://player.vimeo.com/api/player.js';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load Vimeo API'));\n document.head.appendChild(script);\n });\n }\n\n createIframe() {\n // Hide original element\n this.player.element.style.display = 'none';\n\n // Create container for iframe\n this.iframe = document.createElement('div');\n this.iframe.id = `vimeo-player-${Math.random().toString(36).substr(2, 9)}`;\n this.iframe.style.width = '100%';\n this.iframe.style.height = '100%';\n \n this.player.element.parentNode.insertBefore(this.iframe, this.player.element);\n }\n\n async initializePlayer() {\n const options = {\n id: this.videoId,\n width: '100%',\n height: '100%',\n controls: false,\n autoplay: this.player.options.autoplay,\n muted: this.player.options.muted,\n loop: this.player.options.loop,\n keyboard: false\n };\n\n if (this.player.options.startTime > 0) {\n options.startTime = this.player.options.startTime;\n }\n\n this.vimeo = new window.Vimeo.Player(this.iframe.id, options);\n\n // Wait for player to be ready\n await this.vimeo.ready();\n this.isReady = true;\n\n this.attachEvents();\n\n // Get initial duration\n try {\n const duration = await this.vimeo.getDuration();\n this.player.state.duration = duration;\n this.player.emit('loadedmetadata');\n } catch (error) {\n this.player.log('Error getting duration:', error, 'warn');\n }\n }\n\n attachEvents() {\n this.vimeo.on('play', () => {\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.emit('play');\n \n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n });\n\n this.vimeo.on('pause', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n \n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n });\n\n this.vimeo.on('ended', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n \n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n });\n\n this.vimeo.on('timeupdate', (data) => {\n this.player.state.currentTime = data.seconds;\n this.player.state.duration = data.duration;\n this.player.emit('timeupdate', data.seconds);\n \n if (this.player.options.onTimeUpdate) {\n this.player.options.onTimeUpdate.call(this.player, data.seconds);\n }\n });\n\n this.vimeo.on('volumechange', (data) => {\n this.player.state.volume = data.volume;\n this.player.emit('volumechange', data.volume);\n });\n\n this.vimeo.on('bufferstart', () => {\n this.player.state.buffering = true;\n this.player.emit('waiting');\n });\n\n this.vimeo.on('bufferend', () => {\n this.player.state.buffering = false;\n this.player.emit('canplay');\n });\n\n this.vimeo.on('seeking', () => {\n this.player.state.seeking = true;\n this.player.emit('seeking');\n });\n\n this.vimeo.on('seeked', () => {\n this.player.state.seeking = false;\n this.player.emit('seeked');\n });\n\n this.vimeo.on('playbackratechange', (data) => {\n this.player.state.playbackSpeed = data.playbackRate;\n this.player.emit('ratechange', data.playbackRate);\n });\n\n this.vimeo.on('error', (error) => {\n this.player.handleError(new Error(`Vimeo error: ${error.message}`));\n });\n }\n\n play() {\n if (this.isReady && this.vimeo) {\n this.vimeo.play().catch(error => {\n this.player.log('Play error:', error, 'warn');\n });\n }\n }\n\n pause() {\n if (this.isReady && this.vimeo) {\n this.vimeo.pause().catch(error => {\n this.player.log('Pause error:', error, 'warn');\n });\n }\n }\n\n seek(time) {\n if (this.isReady && this.vimeo) {\n this.vimeo.setCurrentTime(time).catch(error => {\n this.player.log('Seek error:', error, 'warn');\n });\n }\n }\n\n setVolume(volume) {\n if (this.isReady && this.vimeo) {\n this.vimeo.setVolume(volume).catch(error => {\n this.player.log('Volume error:', error, 'warn');\n });\n this.player.state.volume = volume;\n }\n }\n\n setMuted(muted) {\n if (this.isReady && this.vimeo) {\n if (muted) {\n this.vimeo.setVolume(0);\n } else {\n this.vimeo.setVolume(this.player.state.volume);\n }\n this.player.state.muted = muted;\n }\n }\n\n setPlaybackSpeed(speed) {\n if (this.isReady && this.vimeo) {\n this.vimeo.setPlaybackRate(speed).catch(error => {\n this.player.log('Playback rate error:', error, 'warn');\n });\n this.player.state.playbackSpeed = speed;\n }\n }\n\n destroy() {\n if (this.vimeo && this.vimeo.destroy) {\n this.vimeo.destroy();\n }\n\n if (this.iframe && this.iframe.parentNode) {\n this.iframe.parentNode.removeChild(this.iframe);\n }\n\n // Show original element\n if (this.player.element) {\n this.player.element.style.display = '';\n }\n }\n}\n\n", "/**\n * HLS Streaming Renderer\n * Uses hls.js for browsers that don't natively support HLS\n */\n\nexport class HLSRenderer {\n constructor(player) {\n this.player = player;\n this.media = player.element;\n this.hls = null;\n }\n\n async init() {\n // Check if browser natively supports HLS (Safari)\n if (this.canPlayNatively()) {\n this.player.log('Using native HLS support');\n await this.initNative();\n } else {\n this.player.log('Using hls.js for HLS support');\n await this.initHlsJs();\n }\n }\n\n canPlayNatively() {\n const video = document.createElement('video');\n return video.canPlayType('application/vnd.apple.mpegurl') !== '';\n }\n\n async initNative() {\n // Use HTML5 renderer for native HLS support\n const HTML5Renderer = (await import('./HTML5Renderer.js')).HTML5Renderer;\n const renderer = new HTML5Renderer(this.player);\n await renderer.init();\n \n // Copy methods\n Object.getOwnPropertyNames(Object.getPrototypeOf(renderer)).forEach(method => {\n if (method !== 'constructor' && typeof renderer[method] === 'function') {\n this[method] = renderer[method].bind(renderer);\n }\n });\n }\n\n async initHlsJs() {\n // Hide native controls\n this.media.controls = false;\n this.media.removeAttribute('controls');\n \n // Load hls.js if not already loaded\n if (!window.Hls) {\n await this.loadHlsJs();\n }\n\n if (!window.Hls.isSupported()) {\n throw new Error('HLS is not supported in this browser');\n }\n\n // Create hls.js instance with better error recovery\n this.hls = new window.Hls({\n debug: this.player.options.debug,\n enableWorker: true,\n lowLatencyMode: false,\n backBufferLength: 90,\n maxBufferLength: 30,\n maxMaxBufferLength: 600,\n maxBufferSize: 60 * 1000 * 1000,\n maxBufferHole: 0.5,\n // Network retry settings\n manifestLoadingTimeOut: 10000,\n manifestLoadingMaxRetry: 4,\n manifestLoadingRetryDelay: 1000,\n manifestLoadingMaxRetryTimeout: 64000,\n levelLoadingTimeOut: 10000,\n levelLoadingMaxRetry: 4,\n levelLoadingRetryDelay: 1000,\n levelLoadingMaxRetryTimeout: 64000,\n fragLoadingTimeOut: 20000,\n fragLoadingMaxRetry: 6,\n fragLoadingRetryDelay: 1000,\n fragLoadingMaxRetryTimeout: 64000\n });\n\n // Attach media element\n this.hls.attachMedia(this.media);\n\n // Load source - Get from attribute to avoid blob URL conversion\n let src;\n const sourceElement = this.player.element.querySelector('source');\n if (sourceElement) {\n // Use getAttribute to get the original URL, not the blob-converted one\n src = sourceElement.getAttribute('src');\n } else {\n // Fallback to element's src attribute\n src = this.player.element.getAttribute('src') || this.player.element.src;\n }\n \n this.player.log(`Loading HLS source: ${src}`, 'log');\n \n if (!src) {\n throw new Error('No HLS source found');\n }\n \n this.hls.loadSource(src);\n\n // Attach events\n this.attachHlsEvents();\n this.attachMediaEvents();\n }\n\n async loadHlsJs() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://cdn.jsdelivr.net/npm/hls.js@latest';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load hls.js'));\n document.head.appendChild(script);\n });\n }\n\n attachHlsEvents() {\n this.hls.on(window.Hls.Events.MANIFEST_PARSED, (event, data) => {\n this.player.log('HLS manifest loaded, found ' + data.levels.length + ' quality levels');\n this.player.emit('hlsmanifestparsed', data);\n });\n\n this.hls.on(window.Hls.Events.LEVEL_SWITCHED, (event, data) => {\n this.player.log('HLS level switched to ' + data.level);\n this.player.emit('hlslevelswitched', data);\n });\n\n this.hls.on(window.Hls.Events.ERROR, (event, data) => {\n this.handleHlsError(data);\n });\n\n this.hls.on(window.Hls.Events.FRAG_BUFFERED, () => {\n this.player.state.buffering = false;\n });\n }\n\n attachMediaEvents() {\n // Use same events as HTML5 renderer\n this.media.addEventListener('loadedmetadata', () => {\n this.player.state.duration = this.media.duration;\n this.player.emit('loadedmetadata');\n });\n\n this.media.addEventListener('play', () => {\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.emit('play');\n \n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n });\n\n this.media.addEventListener('pause', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n \n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n });\n\n this.media.addEventListener('ended', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n \n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n \n if (this.player.options.loop) {\n this.player.seek(0);\n this.player.play();\n }\n });\n\n this.media.addEventListener('timeupdate', () => {\n this.player.state.currentTime = this.media.currentTime;\n this.player.emit('timeupdate', this.media.currentTime);\n \n if (this.player.options.onTimeUpdate) {\n this.player.options.onTimeUpdate.call(this.player, this.media.currentTime);\n }\n });\n\n this.media.addEventListener('volumechange', () => {\n this.player.state.volume = this.media.volume;\n this.player.state.muted = this.media.muted;\n this.player.emit('volumechange', this.media.volume);\n });\n\n this.media.addEventListener('waiting', () => {\n this.player.state.buffering = true;\n this.player.emit('waiting');\n });\n\n this.media.addEventListener('canplay', () => {\n this.player.state.buffering = false;\n this.player.emit('canplay');\n });\n\n this.media.addEventListener('error', () => {\n this.player.handleError(this.media.error);\n });\n }\n\n handleHlsError(data) {\n // Log detailed error info\n this.player.log(`HLS Error - Type: ${data.type}, Details: ${data.details}, Fatal: ${data.fatal}`, 'warn');\n if (data.response) {\n this.player.log(`Response code: ${data.response.code}, URL: ${data.response.url}`, 'warn');\n }\n \n if (data.fatal) {\n switch (data.type) {\n case window.Hls.ErrorTypes.NETWORK_ERROR:\n this.player.log('Fatal network error, trying to recover...', 'error');\n this.player.log(`Network error details: ${data.details}`, 'error');\n setTimeout(() => {\n this.hls.startLoad();\n }, 1000);\n break;\n \n case window.Hls.ErrorTypes.MEDIA_ERROR:\n this.player.log('Fatal media error, trying to recover...', 'error');\n this.hls.recoverMediaError();\n break;\n \n default:\n this.player.log('Fatal error, cannot recover', 'error');\n this.player.handleError(new Error(`HLS Error: ${data.type} - ${data.details}`));\n this.hls.destroy();\n break;\n }\n } else {\n this.player.log('Non-fatal HLS error: ' + data.details, 'warn');\n }\n }\n\n play() {\n const promise = this.media.play();\n \n if (promise !== undefined) {\n promise.catch(error => {\n this.player.log('Play failed:', error, 'warn');\n });\n }\n }\n\n pause() {\n this.media.pause();\n }\n\n seek(time) {\n this.media.currentTime = time;\n }\n\n setVolume(volume) {\n this.media.volume = volume;\n }\n\n setMuted(muted) {\n this.media.muted = muted;\n }\n\n setPlaybackSpeed(speed) {\n this.media.playbackRate = speed;\n }\n\n switchQuality(levelIndex) {\n if (this.hls) {\n this.hls.currentLevel = levelIndex;\n }\n }\n\n getQualities() {\n if (this.hls && this.hls.levels) {\n return this.hls.levels.map((level, index) => ({\n index,\n height: level.height,\n width: level.width,\n bitrate: level.bitrate,\n name: `${level.height}p`\n }));\n }\n return [];\n }\n\n destroy() {\n if (this.hls) {\n this.hls.destroy();\n this.hls = null;\n }\n }\n}\n\n", "/**\n * VidPly Playlist Manager\n * Manages playlists for audio and video content\n */\n\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { createIconElement } from '../icons/Icons.js';\n\nexport class PlaylistManager {\n constructor(player, options = {}) {\n this.player = player;\n this.tracks = [];\n this.currentIndex = -1;\n \n // Options\n this.options = {\n autoAdvance: options.autoAdvance !== false, // Default true\n loop: options.loop || false,\n showPanel: options.showPanel !== false, // Default true\n ...options\n };\n \n // UI elements\n this.container = null;\n this.playlistPanel = null;\n this.trackInfoElement = null;\n \n // Bind methods\n this.handleTrackEnd = this.handleTrackEnd.bind(this);\n this.handleTrackError = this.handleTrackError.bind(this);\n \n // Initialize\n this.init();\n }\n \n init() {\n // Listen for track end\n this.player.on('ended', this.handleTrackEnd);\n this.player.on('error', this.handleTrackError);\n \n // Create UI if needed\n if (this.options.showPanel) {\n this.createUI();\n }\n }\n \n /**\n * Load a playlist\n * @param {Array} tracks - Array of track objects\n */\n loadPlaylist(tracks) {\n this.tracks = tracks;\n this.currentIndex = -1;\n \n // Add playlist class to container\n if (this.container) {\n this.container.classList.add('vidply-has-playlist');\n }\n \n // Update UI\n if (this.playlistPanel) {\n this.renderPlaylist();\n }\n \n // Auto-play first track\n if (tracks.length > 0) {\n this.play(0);\n }\n }\n \n /**\n * Play a specific track\n * @param {number} index - Track index\n */\n play(index) {\n if (index < 0 || index >= this.tracks.length) {\n console.warn('VidPly Playlist: Invalid track index', index);\n return;\n }\n \n const track = this.tracks[index];\n \n // Update current index\n this.currentIndex = index;\n \n // Load track into player\n this.player.load({\n src: track.src,\n type: track.type,\n poster: track.poster,\n tracks: track.tracks || []\n });\n \n // Update UI\n this.updateTrackInfo(track);\n this.updatePlaylistUI();\n \n // Emit event\n this.player.emit('playlisttrackchange', {\n index: index,\n item: track,\n total: this.tracks.length\n });\n \n // Auto-play\n setTimeout(() => {\n this.player.play();\n }, 100);\n }\n \n /**\n * Play next track\n */\n next() {\n let nextIndex = this.currentIndex + 1;\n \n if (nextIndex >= this.tracks.length) {\n if (this.options.loop) {\n nextIndex = 0;\n } else {\n return;\n }\n }\n \n this.play(nextIndex);\n }\n \n /**\n * Play previous track\n */\n previous() {\n let prevIndex = this.currentIndex - 1;\n \n if (prevIndex < 0) {\n if (this.options.loop) {\n prevIndex = this.tracks.length - 1;\n } else {\n return;\n }\n }\n \n this.play(prevIndex);\n }\n \n /**\n * Handle track end\n */\n handleTrackEnd() {\n if (this.options.autoAdvance) {\n this.next();\n }\n }\n \n /**\n * Handle track error\n */\n handleTrackError(e) {\n console.error('VidPly Playlist: Track error', e);\n \n // Try next track\n if (this.options.autoAdvance) {\n setTimeout(() => {\n this.next();\n }, 1000);\n }\n }\n \n /**\n * Create playlist UI\n */\n createUI() {\n // Find player container\n this.container = this.player.container;\n \n if (!this.container) {\n console.warn('VidPly Playlist: No container found');\n return;\n }\n \n // Create track info element (shows current track)\n this.trackInfoElement = DOMUtils.createElement('div', {\n className: 'vidply-track-info'\n });\n this.trackInfoElement.style.display = 'none';\n \n this.container.appendChild(this.trackInfoElement);\n \n // Create playlist panel\n this.playlistPanel = DOMUtils.createElement('div', {\n className: 'vidply-playlist-panel'\n });\n this.playlistPanel.style.display = 'none';\n \n this.container.appendChild(this.playlistPanel);\n }\n \n /**\n * Update track info display\n */\n updateTrackInfo(track) {\n if (!this.trackInfoElement) return;\n \n const trackNumber = this.currentIndex + 1;\n const totalTracks = this.tracks.length;\n \n this.trackInfoElement.innerHTML = `\n <div class=\"vidply-track-number\">Track ${trackNumber} of ${totalTracks}</div>\n <div class=\"vidply-track-title\">${DOMUtils.escapeHTML(track.title || 'Untitled')}</div>\n ${track.artist ? `<div class=\"vidply-track-artist\">${DOMUtils.escapeHTML(track.artist)}</div>` : ''}\n `;\n \n this.trackInfoElement.style.display = 'block';\n }\n \n /**\n * Render playlist\n */\n renderPlaylist() {\n if (!this.playlistPanel) return;\n \n // Clear existing\n this.playlistPanel.innerHTML = '';\n \n // Create header\n const header = DOMUtils.createElement('div', {\n className: 'vidply-playlist-header'\n });\n header.textContent = `Playlist (${this.tracks.length})`;\n this.playlistPanel.appendChild(header);\n \n // Create list\n const list = DOMUtils.createElement('div', {\n className: 'vidply-playlist-list'\n });\n \n this.tracks.forEach((track, index) => {\n const item = this.createPlaylistItem(track, index);\n list.appendChild(item);\n });\n \n this.playlistPanel.appendChild(list);\n this.playlistPanel.style.display = 'block';\n }\n \n /**\n * Create playlist item element\n */\n createPlaylistItem(track, index) {\n const item = DOMUtils.createElement('div', {\n className: 'vidply-playlist-item',\n role: 'button',\n tabIndex: 0,\n 'aria-label': `Play ${track.title || 'Track ' + (index + 1)}`\n });\n \n // Add active class if current\n if (index === this.currentIndex) {\n item.classList.add('vidply-playlist-item-active');\n }\n \n // Thumbnail or icon\n const thumbnail = DOMUtils.createElement('div', {\n className: 'vidply-playlist-thumbnail'\n });\n \n if (track.poster) {\n thumbnail.style.backgroundImage = `url(${track.poster})`;\n } else {\n // Show music/speaker icon for audio tracks\n const icon = createIconElement('music');\n icon.classList.add('vidply-playlist-thumbnail-icon');\n thumbnail.appendChild(icon);\n }\n \n item.appendChild(thumbnail);\n \n // Info\n const info = DOMUtils.createElement('div', {\n className: 'vidply-playlist-item-info'\n });\n \n const title = DOMUtils.createElement('div', {\n className: 'vidply-playlist-item-title'\n });\n title.textContent = track.title || `Track ${index + 1}`;\n info.appendChild(title);\n \n if (track.artist) {\n const artist = DOMUtils.createElement('div', {\n className: 'vidply-playlist-item-artist'\n });\n artist.textContent = track.artist;\n info.appendChild(artist);\n }\n \n item.appendChild(info);\n \n // Play icon\n const playIcon = createIconElement('play');\n playIcon.classList.add('vidply-playlist-item-icon');\n item.appendChild(playIcon);\n \n // Click handler\n item.addEventListener('click', () => {\n this.play(index);\n });\n \n // Keyboard handler\n item.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this.play(index);\n }\n });\n \n return item;\n }\n \n /**\n * Update playlist UI (highlight current track)\n */\n updatePlaylistUI() {\n if (!this.playlistPanel) return;\n \n const items = this.playlistPanel.querySelectorAll('.vidply-playlist-item');\n \n items.forEach((item, index) => {\n if (index === this.currentIndex) {\n item.classList.add('vidply-playlist-item-active');\n \n // Scroll into view\n item.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n } else {\n item.classList.remove('vidply-playlist-item-active');\n }\n });\n }\n \n /**\n * Get current track\n */\n getCurrentTrack() {\n return this.tracks[this.currentIndex] || null;\n }\n \n /**\n * Get playlist info\n */\n getPlaylistInfo() {\n return {\n currentIndex: this.currentIndex,\n totalTracks: this.tracks.length,\n currentTrack: this.getCurrentTrack(),\n hasNext: this.currentIndex < this.tracks.length - 1,\n hasPrevious: this.currentIndex > 0\n };\n }\n \n /**\n * Add track to playlist\n */\n addTrack(track) {\n this.tracks.push(track);\n \n if (this.playlistPanel) {\n this.renderPlaylist();\n }\n }\n \n /**\n * Remove track from playlist\n */\n removeTrack(index) {\n if (index < 0 || index >= this.tracks.length) return;\n \n this.tracks.splice(index, 1);\n \n // Adjust current index if needed\n if (index < this.currentIndex) {\n this.currentIndex--;\n } else if (index === this.currentIndex) {\n // Current track was removed, play next or stop\n if (this.currentIndex >= this.tracks.length) {\n this.currentIndex = this.tracks.length - 1;\n }\n \n if (this.currentIndex >= 0) {\n this.play(this.currentIndex);\n }\n }\n \n if (this.playlistPanel) {\n this.renderPlaylist();\n }\n }\n \n /**\n * Clear playlist\n */\n clear() {\n this.tracks = [];\n this.currentIndex = -1;\n \n if (this.playlistPanel) {\n this.playlistPanel.innerHTML = '';\n this.playlistPanel.style.display = 'none';\n }\n \n if (this.trackInfoElement) {\n this.trackInfoElement.innerHTML = '';\n this.trackInfoElement.style.display = 'none';\n }\n }\n \n /**\n * Destroy playlist manager\n */\n destroy() {\n // Remove event listeners\n this.player.off('ended', this.handleTrackEnd);\n this.player.off('error', this.handleTrackError);\n \n // Remove UI\n if (this.trackInfoElement) {\n this.trackInfoElement.remove();\n }\n \n if (this.playlistPanel) {\n this.playlistPanel.remove();\n }\n \n // Clear data\n this.clear();\n }\n}\n\nexport default PlaylistManager;\n"],
|
|
5
|
-
"mappings": "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",
|
|
3
|
+
"sources": ["../src/renderers/HTML5Renderer.js", "../src/index.js", "../src/utils/EventEmitter.js", "../src/utils/DOMUtils.js", "../src/utils/TimeUtils.js", "../src/icons/Icons.js", "../src/i18n/translations.js", "../src/i18n/i18n.js", "../src/controls/ControlBar.js", "../src/controls/CaptionManager.js", "../src/controls/KeyboardManager.js", "../src/controls/TranscriptManager.js", "../src/core/Player.js", "../src/renderers/YouTubeRenderer.js", "../src/renderers/VimeoRenderer.js", "../src/renderers/HLSRenderer.js", "../src/features/PlaylistManager.js"],
|
|
4
|
+
"sourcesContent": ["/**\n * HTML5 Media Renderer\n */\n\nexport class HTML5Renderer {\n constructor(player) {\n this.player = player;\n this.media = player.element;\n }\n\n async init() {\n // Hide native controls\n this.media.controls = false;\n this.media.removeAttribute('controls');\n \n this.attachEvents();\n \n // Set preload\n this.media.preload = this.player.options.preload;\n \n // Load media\n this.media.load();\n }\n\n attachEvents() {\n // Playback events\n this.media.addEventListener('loadedmetadata', () => {\n this.player.state.duration = this.media.duration;\n this.player.emit('loadedmetadata');\n });\n\n this.media.addEventListener('play', () => {\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.emit('play');\n \n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n \n // Pause other players if enabled\n if (this.player.options.pauseOthersOnPlay) {\n this.pauseOtherPlayers();\n }\n });\n\n this.media.addEventListener('pause', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n \n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n });\n\n this.media.addEventListener('ended', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n \n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n \n // Handle loop\n if (this.player.options.loop) {\n this.player.seek(0);\n this.player.play();\n }\n });\n\n this.media.addEventListener('timeupdate', () => {\n this.player.state.currentTime = this.media.currentTime;\n this.player.emit('timeupdate', this.media.currentTime);\n \n if (this.player.options.onTimeUpdate) {\n this.player.options.onTimeUpdate.call(this.player, this.media.currentTime);\n }\n });\n\n this.media.addEventListener('volumechange', () => {\n this.player.state.volume = this.media.volume;\n this.player.state.muted = this.media.muted;\n this.player.emit('volumechange', this.media.volume);\n \n if (this.player.options.onVolumeChange) {\n this.player.options.onVolumeChange.call(this.player, this.media.volume);\n }\n });\n\n this.media.addEventListener('seeking', () => {\n this.player.state.seeking = true;\n this.player.emit('seeking');\n });\n\n this.media.addEventListener('seeked', () => {\n this.player.state.seeking = false;\n this.player.emit('seeked');\n });\n\n this.media.addEventListener('waiting', () => {\n this.player.state.buffering = true;\n this.player.emit('waiting');\n });\n\n this.media.addEventListener('canplay', () => {\n this.player.state.buffering = false;\n this.player.emit('canplay');\n });\n\n this.media.addEventListener('progress', () => {\n if (this.media.buffered.length > 0) {\n const buffered = this.media.buffered.end(this.media.buffered.length - 1);\n this.player.emit('progress', buffered);\n }\n });\n\n this.media.addEventListener('error', (e) => {\n this.player.handleError(this.media.error);\n });\n\n this.media.addEventListener('ratechange', () => {\n this.player.state.playbackSpeed = this.media.playbackRate;\n this.player.emit('ratechange', this.media.playbackRate);\n });\n }\n\n pauseOtherPlayers() {\n // Pause other VidPly instances\n const allPlayers = document.querySelectorAll('.vidply-player');\n allPlayers.forEach(playerEl => {\n if (playerEl !== this.player.container) {\n const video = playerEl.querySelector('video, audio');\n if (video && !video.paused) {\n video.pause();\n }\n }\n });\n }\n\n play() {\n const promise = this.media.play();\n \n if (promise !== undefined) {\n promise.catch(error => {\n this.player.log('Play failed:', error, 'warn');\n \n // If autoplay failed, try muted autoplay\n if (this.player.options.autoplay && !this.player.state.muted) {\n this.player.log('Retrying play with muted audio', 'info');\n this.media.muted = true;\n this.media.play().catch(err => {\n this.player.handleError(err);\n });\n }\n });\n }\n }\n\n pause() {\n this.media.pause();\n }\n\n seek(time) {\n this.media.currentTime = time;\n }\n\n setVolume(volume) {\n this.media.volume = volume;\n }\n\n setMuted(muted) {\n this.media.muted = muted;\n }\n\n setPlaybackSpeed(speed) {\n this.media.playbackRate = speed;\n }\n\n /**\n * Get available quality levels from source elements\n * @returns {Array} Array of quality objects with index, height, width, and src\n */\n getQualities() {\n const sources = Array.from(this.media.querySelectorAll('source'));\n \n if (sources.length <= 1) {\n return [];\n }\n\n return sources.map((source, index) => {\n // Try to extract quality from data attributes or label\n const label = source.getAttribute('data-quality') || source.getAttribute('label') || '';\n const height = source.getAttribute('data-height') || this.extractHeightFromLabel(label);\n const width = source.getAttribute('data-width') || '';\n \n return {\n index,\n height: height ? parseInt(height) : 0,\n width: width ? parseInt(width) : 0,\n src: source.src,\n type: source.type,\n name: label || (height ? `${height}p` : `Quality ${index + 1}`)\n };\n }).filter(q => q.height > 0); // Only return qualities with valid height\n }\n\n /**\n * Extract height from quality label (e.g., \"1080p\" -> 1080)\n * @param {string} label \n * @returns {number}\n */\n extractHeightFromLabel(label) {\n const match = label.match(/(\\d+)p/i);\n return match ? parseInt(match[1]) : 0;\n }\n\n /**\n * Switch to a specific quality level\n * @param {number} qualityIndex - Index of the quality level (-1 for auto, not applicable for HTML5)\n */\n switchQuality(qualityIndex) {\n const qualities = this.getQualities();\n \n if (qualityIndex < 0 || qualityIndex >= qualities.length) {\n this.player.log('Invalid quality index', 'warn');\n return;\n }\n\n const quality = qualities[qualityIndex];\n const currentTime = this.media.currentTime;\n const wasPlaying = !this.media.paused;\n\n // Store the current source for comparison\n const currentSrc = this.media.currentSrc;\n \n // Don't switch if already at this quality\n if (currentSrc === quality.src) {\n this.player.log('Already at this quality level', 'info');\n return;\n }\n\n this.player.log(`Switching to quality: ${quality.name}`, 'info');\n\n // Update the src\n this.media.src = quality.src;\n \n // Wait for the new source to load, then restore playback state\n const onLoadedMetadata = () => {\n this.media.removeEventListener('loadedmetadata', onLoadedMetadata);\n \n // Restore playback position\n this.media.currentTime = currentTime;\n \n // Resume playback if it was playing\n if (wasPlaying) {\n this.media.play().catch(err => {\n this.player.log('Failed to resume playback after quality switch', 'warn');\n });\n }\n \n // Emit quality change event\n this.player.emit('qualitychange', { quality: quality.name, index: qualityIndex });\n };\n\n this.media.addEventListener('loadedmetadata', onLoadedMetadata);\n this.media.load();\n }\n\n /**\n * Get current quality index\n * @returns {number}\n */\n getCurrentQuality() {\n const qualities = this.getQualities();\n const currentSrc = this.media.currentSrc;\n \n for (let i = 0; i < qualities.length; i++) {\n if (qualities[i].src === currentSrc) {\n return i;\n }\n }\n \n return 0; // Default to first quality if not found\n }\n\n destroy() {\n // Remove event listeners\n this.media.removeEventListener('loadedmetadata', () => {});\n this.media.removeEventListener('play', () => {});\n this.media.removeEventListener('pause', () => {});\n // ... (other listeners would be removed in a real implementation)\n }\n}\n\n", "/**\n * VidPly - Universal Video Player\n * Main Entry Point\n */\n\nimport { Player } from './core/Player.js';\nimport { PlaylistManager } from './features/PlaylistManager.js';\n\n// Auto-initialize players\nfunction initializePlayers() {\n const elements = document.querySelectorAll('[data-vidply]');\n \n elements.forEach(element => {\n // Parse options from data attribute (JSON format)\n const options = element.dataset.vidplyOptions \n ? JSON.parse(element.dataset.vidplyOptions)\n : {};\n \n // Parse individual data attributes and merge with options\n // This allows for easier HTML-based configuration\n const dataOptions = parseDataAttributes(element.dataset);\n const mergedOptions = { ...dataOptions, ...options };\n \n // Create player instance\n new Player(element, mergedOptions);\n });\n}\n\n// Helper function to parse data attributes into options\nfunction parseDataAttributes(dataset) {\n const options = {};\n \n // Map of data attribute names to option keys (camelCase conversion)\n const attributeMap = {\n // Sign Language\n 'signLanguageSrc': 'signLanguageSrc',\n 'signLanguageButton': 'signLanguageButton',\n 'signLanguagePosition': 'signLanguagePosition',\n \n // Audio Description\n 'audioDescriptionSrc': 'audioDescriptionSrc',\n 'audioDescriptionButton': 'audioDescriptionButton',\n \n // Other common options\n 'autoplay': 'autoplay',\n 'loop': 'loop',\n 'muted': 'muted',\n 'controls': 'controls',\n 'poster': 'poster',\n 'width': 'width',\n 'height': 'height',\n 'language': 'language',\n 'captions': 'captions',\n 'captionsDefault': 'captionsDefault',\n 'transcript': 'transcript',\n 'transcriptButton': 'transcriptButton',\n 'keyboard': 'keyboard',\n 'responsive': 'responsive',\n 'pipButton': 'pipButton',\n 'fullscreenButton': 'fullscreenButton'\n };\n \n // Parse each data attribute\n Object.keys(attributeMap).forEach(dataKey => {\n const optionKey = attributeMap[dataKey];\n const value = dataset[dataKey];\n \n if (value !== undefined) {\n // Convert string values to appropriate types\n if (value === 'true') {\n options[optionKey] = true;\n } else if (value === 'false') {\n options[optionKey] = false;\n } else if (!isNaN(value) && value !== '') {\n options[optionKey] = Number(value);\n } else {\n options[optionKey] = value;\n }\n }\n });\n \n return options;\n}\n\n// Auto-initialize on DOM ready\nif (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', initializePlayers);\n} else {\n initializePlayers();\n}\n\n// Export for manual initialization\nexport { Player, PlaylistManager };\nexport default Player;\n\n", "/**\n * Simple EventEmitter implementation\n */\n\nexport class EventEmitter {\n constructor() {\n this.events = {};\n }\n\n on(event, listener) {\n if (!this.events[event]) {\n this.events[event] = [];\n }\n this.events[event].push(listener);\n return this;\n }\n\n once(event, listener) {\n const onceListener = (...args) => {\n listener(...args);\n this.off(event, onceListener);\n };\n return this.on(event, onceListener);\n }\n\n off(event, listener) {\n if (!this.events[event]) return this;\n \n if (!listener) {\n delete this.events[event];\n } else {\n this.events[event] = this.events[event].filter(l => l !== listener);\n }\n \n return this;\n }\n\n emit(event, ...args) {\n if (!this.events[event]) return this;\n \n this.events[event].forEach(listener => {\n listener(...args);\n });\n \n return this;\n }\n\n removeAllListeners() {\n this.events = {};\n return this;\n }\n}\n\n", "/**\n * DOM manipulation utilities\n */\n\nexport const DOMUtils = {\n createElement(tag, options = {}) {\n const element = document.createElement(tag);\n \n if (options.className) {\n element.className = options.className;\n }\n \n if (options.attributes) {\n Object.entries(options.attributes).forEach(([key, value]) => {\n element.setAttribute(key, value);\n });\n }\n \n if (options.innerHTML) {\n element.innerHTML = options.innerHTML;\n }\n \n if (options.textContent) {\n element.textContent = options.textContent;\n }\n \n if (options.style) {\n Object.assign(element.style, options.style);\n }\n \n if (options.children) {\n options.children.forEach(child => {\n if (child) element.appendChild(child);\n });\n }\n \n return element;\n },\n\n addClass(element, className) {\n if (element && className) {\n element.classList.add(className);\n }\n },\n\n removeClass(element, className) {\n if (element && className) {\n element.classList.remove(className);\n }\n },\n\n toggleClass(element, className) {\n if (element && className) {\n element.classList.toggle(className);\n }\n },\n\n hasClass(element, className) {\n return element && element.classList.contains(className);\n },\n\n show(element) {\n if (element) {\n element.style.display = '';\n }\n },\n\n hide(element) {\n if (element) {\n element.style.display = 'none';\n }\n },\n\n fadeIn(element, duration = 300) {\n if (!element) return;\n \n element.style.opacity = '0';\n element.style.display = '';\n \n let start = null;\n const animate = (timestamp) => {\n if (!start) start = timestamp;\n const progress = timestamp - start;\n const opacity = Math.min(progress / duration, 1);\n \n element.style.opacity = opacity;\n \n if (progress < duration) {\n requestAnimationFrame(animate);\n }\n };\n \n requestAnimationFrame(animate);\n },\n\n fadeOut(element, duration = 300) {\n if (!element) return;\n \n const startOpacity = parseFloat(getComputedStyle(element).opacity) || 1;\n let start = null;\n \n const animate = (timestamp) => {\n if (!start) start = timestamp;\n const progress = timestamp - start;\n const opacity = Math.max(startOpacity - (progress / duration), 0);\n \n element.style.opacity = opacity;\n \n if (progress < duration) {\n requestAnimationFrame(animate);\n } else {\n element.style.display = 'none';\n }\n };\n \n requestAnimationFrame(animate);\n },\n\n offset(element) {\n if (!element) return { top: 0, left: 0 };\n \n const rect = element.getBoundingClientRect();\n return {\n top: rect.top + window.pageYOffset,\n left: rect.left + window.pageXOffset,\n width: rect.width,\n height: rect.height\n };\n },\n\n escapeHTML(str) {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n },\n\n sanitizeHTML(html) {\n // Basic HTML sanitization - allow safe tags for VTT captions\n // Since we control the HTML (from VTT parsing), we can safely allow these tags\n const temp = document.createElement('div');\n \n // Strip out any potentially dangerous tags/attributes\n // Allow: strong, em, u, span, b, i with class and data-voice attributes\n const safeHtml = html\n .replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '')\n .replace(/<iframe\\b[^<]*(?:(?!<\\/iframe>)<[^<]*)*<\\/iframe>/gi, '')\n .replace(/on\\w+\\s*=/gi, '') // Remove event handlers\n .replace(/javascript:/gi, ''); // Remove javascript: protocol\n \n temp.innerHTML = safeHtml;\n return temp.innerHTML;\n }\n};\n\n", "/**\n * Time formatting and conversion utilities\n */\n\nexport const TimeUtils = {\n /**\n * Format seconds to time string (HH:MM:SS or MM:SS)\n */\n formatTime(seconds, alwaysShowHours = false) {\n if (!isFinite(seconds) || seconds < 0) {\n return alwaysShowHours ? '00:00:00' : '00:00';\n }\n \n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = Math.floor(seconds % 60);\n \n const pad = (num) => String(num).padStart(2, '0');\n \n if (hours > 0 || alwaysShowHours) {\n return `${pad(hours)}:${pad(minutes)}:${pad(secs)}`;\n }\n \n return `${pad(minutes)}:${pad(secs)}`;\n },\n\n /**\n * Parse time string to seconds\n */\n parseTime(timeString) {\n const parts = timeString.split(':').map(p => parseInt(p, 10));\n \n if (parts.length === 3) {\n // HH:MM:SS\n return parts[0] * 3600 + parts[1] * 60 + parts[2];\n } else if (parts.length === 2) {\n // MM:SS\n return parts[0] * 60 + parts[1];\n } else if (parts.length === 1) {\n // SS\n return parts[0];\n }\n \n return 0;\n },\n\n /**\n * Format seconds to readable duration\n */\n formatDuration(seconds) {\n if (!isFinite(seconds) || seconds < 0) {\n return '0 seconds';\n }\n \n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = Math.floor(seconds % 60);\n \n const parts = [];\n \n if (hours > 0) {\n parts.push(`${hours} hour${hours !== 1 ? 's' : ''}`);\n }\n if (minutes > 0) {\n parts.push(`${minutes} minute${minutes !== 1 ? 's' : ''}`);\n }\n if (secs > 0 || parts.length === 0) {\n parts.push(`${secs} second${secs !== 1 ? 's' : ''}`);\n }\n \n return parts.join(', ');\n },\n\n /**\n * Format percentage\n */\n formatPercentage(value, total) {\n if (total === 0) return 0;\n return Math.round((value / total) * 100);\n }\n};\n\n", "/**\n * SVG Icon Library for VidPly\n * Optimized with common viewBox and fill attributes\n */\n\n// SVG paths only (viewBox and fill added by wrapper)\nconst iconPaths = {\n play: `<path d=\"M8 5v14l11-7z\"/>`,\n\n pause: `<path d=\"M6 4h4v16H6V4zm8 0h4v16h-4V4z\"/>`,\n\n stop: `<rect x=\"6\" y=\"6\" width=\"12\" height=\"12\"/>`,\n\n rewind: `<path d=\"M11 18V6l-8.5 6 8.5 6zm.5-6l8.5 6V6l-8.5 6z\"/>`,\n\n forward: `<path d=\"M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z\"/>`,\n\n skipPrevious: `<path d=\"M6 6h2v12H6V6zm3 6l8.5 6V6L9 12z\"/>`,\n\n skipNext: `<path d=\"M16 6h2v12h-2V6zM6 6l8.5 6L6 18V6z\"/>`,\n\n restart: `<path d=\"M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z\"/>`,\n\n volumeHigh: `<path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z\"/>`,\n\n volumeMedium: `<path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z\"/>`,\n\n volumeLow: `<path d=\"M7 9v6h4l5 5V4l-5 5H7z\"/>`,\n\n volumeMuted: `<path d=\"M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z\"/>`,\n\n fullscreen: `<path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\"/>`,\n\n fullscreenExit: `<path d=\"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z\"/>`,\n\n settings: `<path d=\"M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94L14.4 2.81c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z\"/>`,\n\n captions: `<path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z\"/>`,\n\n captionsOff: `<path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z\"/><path d=\"M0 0h24v24H0z\" fill=\"none\"/>`,\n\n pip: `<path d=\"M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98V5c0-1.1-.9-2-2-2zm0 16.01H3V4.98h18v14.03z\"/>`,\n\n speed: `<path d=\"M20.38 8.57l-1.23 1.85a8 8 0 0 1-.22 7.58H5.07A8 8 0 0 1 15.58 6.85l1.85-1.23A10 10 0 0 0 3.35 19a2 2 0 0 0 1.72 1h13.85a2 2 0 0 0 1.74-1 10 10 0 0 0-.27-10.44z\"/><path d=\"M10.59 15.41a2 2 0 0 0 2.83 0l5.66-8.49-8.49 5.66a2 2 0 0 0 0 2.83z\"/>`,\n\n close: `<path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"/>`,\n\n check: `<path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"/>`,\n\n arrowUp: `<path d=\"M7 14l5-5 5 5z\"/>`,\n\n arrowDown: `<path d=\"M7 10l5 5 5-5z\"/>`,\n\n arrowLeft: `<path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"/>`,\n\n arrowRight: `<path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"/>`,\n\n loading: `<path d=\"M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z\"/>`,\n\n error: `<path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"/>`,\n\n download: `<path d=\"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z\"/>`,\n\n link: `<path d=\"M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z\"/>`,\n\n playlist: `<path d=\"M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z\"/>`,\n\n language: `<path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z\"/>`,\n\n hd: `<path d=\"M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-8 12H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm7-1c0 .55-.45 1-1 1h-.75v1.5h-1.5V15H14c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v4zm-3.5-.5h2v-3h-2v3z\"/>`,\n\n transcript: `<path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z\"/>`,\n\n audioDescription: `<path d=\"M12 3v9.28c-.47-.17-.97-.28-1.5-.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7z\"/><path d=\"M10.5 19c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\"/>`,\n\n audioDescriptionOn: `<path d=\"M12 3v9.28c-.47-.17-.97-.28-1.5-.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7z\"/><path d=\"M10.5 19c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\"/><circle cx=\"19\" cy=\"16\" r=\"3\" fill=\"#3b82f6\"/><path d=\"M18.5 17.5l1-1 1.5 1.5\" stroke=\"white\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`,\n\n signLanguage: `<g transform=\"scale(1.5)\"><path d=\"M16 11.3c-.1-.9-4.8 1.3-5.4 1.1-2.6-1 5.8-1.3 5.1-2.9s-5.1 1.5-6 1.4C6.5 9.4 16.5 9.1 13.5 8c-1.9-.6-8.8 2.9-6.8.4.7-.6.7-1.9-.7-1.7-9.7 7.2-.7 12.2 8.8 7 0-1.3-3.5.4-4.1.4-2.6 0 5.6-2 5.4-3ZM3.9 7.8c3.2-4.2 3.7 1.2 6 .1s.2-.2.2-.3c.7-2.7 2.5-7.5-1.5-1.3-1.6 0 1.1-4 1-4.6C8.9-1 7.3 4.4 7.2 4.9c-1.6.7-.9-1.4-.7-1.5 3-6-.6-3.1-.9.4-2.5 1.8 0-2.8 0-3.5C2.8-.9 4 9.4 1.1 4.9S.1 4.6 0 5c-.4 2.7 2.6 7.2 3.9 2.8Z\"/></g>`,\n\n signLanguageOn: `<g transform=\"scale(1.5)\"><path d=\"M16 11.3c-.1-.9-4.8 1.3-5.4 1.1-2.6-1 5.8-1.3 5.1-2.9s-5.1 1.5-6 1.4C6.5 9.4 16.5 9.1 13.5 8c-1.9-.6-8.8 2.9-6.8.4.7-.6.7-1.9-.7-1.7-9.7 7.2-.7 12.2 8.8 7 0-1.3-3.5.4-4.1.4-2.6 0 5.6-2 5.4-3ZM3.9 7.8c3.2-4.2 3.7 1.2 6 .1s.2-.2.2-.3c.7-2.7 2.5-7.5-1.5-1.3-1.6 0 1.1-4 1-4.6C8.9-1 7.3 4.4 7.2 4.9c-1.6.7-.9-1.4-.7-1.5 3-6-.6-3.1-.9.4-2.5 1.8 0-2.8 0-3.5C2.8-.9 4 9.4 1.1 4.9S.1 4.6 0 5c-.4 2.7 2.6 7.2 3.9 2.8Z\"/></g>`,\n\n speaker: `<path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z\"/>`,\n\n music: `<path d=\"M12 3v9.28c-.47-.17-.97-.28-1.5-.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7zm-1.5 16c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\"/>`,\n\n moreVertical: `<path d=\"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"/>`,\n\n moreHorizontal: `<path d=\"M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"/>`\n};\n\n// Optimized wrapper that adds common SVG attributes\nconst svgWrapper = (paths) => `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\">${paths}</svg>`;\n\n// Export Icons object with SVG wrappers\nexport const Icons = Object.fromEntries(\n Object.entries(iconPaths).map(([key, value]) => [key, svgWrapper(value)])\n);\n\nexport function getIcon(name) {\n return Icons[name] || Icons.play;\n}\n\nexport function createIconElement(name, className = '') {\n const wrapper = document.createElement('span');\n wrapper.className = `vidply-icon ${className}`.trim();\n wrapper.innerHTML = getIcon(name);\n wrapper.setAttribute('aria-hidden', 'true');\n return wrapper;\n}\n\n/**\n * Create the large centered play button overlay (complete SVG)\n * @returns {SVGElement} Complete SVG element with circle background and play icon\n */\nexport function createPlayOverlay() {\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svg.setAttribute('class', 'vidply-play-overlay');\n svg.setAttribute('viewBox', '0 0 80 80');\n svg.setAttribute('width', '80');\n svg.setAttribute('height', '80');\n svg.setAttribute('aria-hidden', 'true');\n svg.setAttribute('role', 'presentation');\n svg.style.cursor = 'pointer';\n\n // Create filter for drop shadow\n const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n const filterId = `vidply-play-shadow-${Math.random().toString(36).substr(2, 9)}`;\n const filter = document.createElementNS('http://www.w3.org/2000/svg', 'filter');\n filter.setAttribute('id', filterId);\n filter.setAttribute('x', '-50%');\n filter.setAttribute('y', '-50%');\n filter.setAttribute('width', '200%');\n filter.setAttribute('height', '200%');\n\n const feGaussianBlur = document.createElementNS('http://www.w3.org/2000/svg', 'feGaussianBlur');\n feGaussianBlur.setAttribute('in', 'SourceAlpha');\n feGaussianBlur.setAttribute('stdDeviation', '3');\n\n const feOffset = document.createElementNS('http://www.w3.org/2000/svg', 'feOffset');\n feOffset.setAttribute('dx', '0');\n feOffset.setAttribute('dy', '2');\n feOffset.setAttribute('result', 'offsetblur');\n\n const feComponentTransfer = document.createElementNS('http://www.w3.org/2000/svg', 'feComponentTransfer');\n const feFuncA = document.createElementNS('http://www.w3.org/2000/svg', 'feFuncA');\n feFuncA.setAttribute('type', 'linear');\n feFuncA.setAttribute('slope', '0.3');\n feComponentTransfer.appendChild(feFuncA);\n\n const feMerge = document.createElementNS('http://www.w3.org/2000/svg', 'feMerge');\n const feMergeNode1 = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');\n const feMergeNode2 = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');\n feMergeNode2.setAttribute('in', 'SourceGraphic');\n feMerge.appendChild(feMergeNode1);\n feMerge.appendChild(feMergeNode2);\n\n filter.appendChild(feGaussianBlur);\n filter.appendChild(feOffset);\n filter.appendChild(feComponentTransfer);\n filter.appendChild(feMerge);\n defs.appendChild(filter);\n svg.appendChild(defs);\n\n // White circle background\n const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n circle.setAttribute('cx', '40');\n circle.setAttribute('cy', '40');\n circle.setAttribute('r', '40');\n circle.setAttribute('fill', 'rgba(255, 255, 255, 0.95)');\n circle.setAttribute('filter', `url(#${filterId})`);\n circle.setAttribute('class', 'vidply-play-overlay-bg');\n svg.appendChild(circle);\n\n // Play icon triangle (centered with optical adjustment)\n const playTriangle = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');\n playTriangle.setAttribute('points', '32,28 32,52 54,40');\n playTriangle.setAttribute('fill', '#0a406e');\n playTriangle.setAttribute('class', 'vidply-play-overlay-icon');\n svg.appendChild(playTriangle);\n\n return svg;\n}\n\n", "/**\n * Translation strings for VidPly\n */\n\nexport const translations = {\n en: {\n player: {\n label: 'Video Player',\n play: 'Play',\n pause: 'Pause',\n stop: 'Stop',\n restart: 'Restart from beginning',\n rewind: 'Rewind',\n forward: 'Forward',\n rewindSeconds: 'Rewind {seconds} seconds',\n forwardSeconds: 'Forward {seconds} seconds',\n previous: 'Previous track',\n next: 'Next track',\n volume: 'Volume',\n mute: 'Mute',\n unmute: 'Unmute',\n fullscreen: 'Fullscreen',\n exitFullscreen: 'Exit Fullscreen',\n captions: 'Captions',\n chapters: 'Chapters',\n quality: 'Quality',\n captionStyling: 'Caption styling',\n transcript: 'Toggle transcript',\n audioDescription: 'Audio description',\n signLanguage: 'Sign language video',\n settings: 'Settings',\n speed: 'Playback Speed',\n pip: 'Picture in Picture',\n currentTime: 'Current time',\n duration: 'Duration',\n progress: 'Progress',\n seekForward: 'Seek forward {seconds} seconds',\n seekBackward: 'Seek backward {seconds} seconds',\n volumeUp: 'Volume up',\n volumeDown: 'Volume down',\n loading: 'Loading...',\n loadingChapters: 'Loading chapters...',\n error: 'Error loading media',\n buffering: 'Buffering...',\n signLanguageVideo: 'Sign Language Video',\n noChapters: 'No chapters available',\n noCaptions: 'No captions available',\n auto: 'Auto',\n autoQuality: 'Auto (no quality selection available)',\n noQuality: 'Quality selection not available'\n },\n captions: {\n off: 'Off',\n select: 'Select captions',\n fontSize: 'Font Size',\n fontFamily: 'Font Family',\n color: 'Text Color',\n backgroundColor: 'Background Color',\n opacity: 'Opacity'\n },\n fontSizes: {\n small: 'Small',\n medium: 'Medium',\n large: 'Large',\n xlarge: 'X-Large'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Text Color',\n background: 'Background',\n font: 'Font',\n fontSize: 'Font Size',\n opacity: 'Opacity'\n },\n audioDescription: {\n enable: 'Enable audio description',\n disable: 'Disable audio description'\n },\n signLanguage: {\n show: 'Show sign language video',\n hide: 'Hide sign language video'\n },\n transcript: {\n title: 'Transcript',\n close: 'Close transcript',\n loading: 'Loading transcript...',\n noTranscript: 'No transcript available for this video.'\n },\n settings: {\n title: 'Settings',\n quality: 'Quality',\n speed: 'Speed',\n captions: 'Captions',\n language: 'Language',\n reset: 'Reset to defaults',\n close: 'Close'\n },\n speeds: {\n normal: 'Normal'\n }\n },\n \n de: {\n player: {\n label: 'Videoplayer',\n play: 'Abspielen',\n pause: 'Pause',\n stop: 'Stopp',\n restart: 'Von vorne beginnen',\n rewind: 'Zur\u00FCckspulen',\n forward: 'Vorspulen',\n rewindSeconds: '{seconds} Sekunden zur\u00FCckspulen',\n forwardSeconds: '{seconds} Sekunden vorspulen',\n previous: 'Vorheriger Titel',\n next: 'N\u00E4chster Titel',\n volume: 'Lautst\u00E4rke',\n mute: 'Stumm',\n unmute: 'Ton ein',\n fullscreen: 'Vollbild',\n exitFullscreen: 'Vollbild beenden',\n captions: 'Untertitel',\n chapters: 'Kapitel',\n quality: 'Qualit\u00E4t',\n captionStyling: 'Untertitel-Stil',\n transcript: 'Transkript umschalten',\n audioDescription: 'Audiodeskription',\n signLanguage: 'Geb\u00E4rdensprache-Video',\n settings: 'Einstellungen',\n speed: 'Wiedergabegeschwindigkeit',\n pip: 'Bild-in-Bild',\n currentTime: 'Aktuelle Zeit',\n duration: 'Dauer',\n progress: 'Fortschritt',\n seekForward: '{seconds} Sekunden vorspulen',\n seekBackward: '{seconds} Sekunden zur\u00FCckspulen',\n volumeUp: 'Lauter',\n volumeDown: 'Leiser',\n loading: 'L\u00E4dt...',\n loadingChapters: 'Kapitel werden geladen...',\n error: 'Fehler beim Laden',\n buffering: 'Puffern...',\n signLanguageVideo: 'Geb\u00E4rdensprache-Video',\n noChapters: 'Keine Kapitel verf\u00FCgbar',\n noCaptions: 'Keine Untertitel verf\u00FCgbar',\n auto: 'Automatisch',\n autoQuality: 'Automatisch (keine Qualit\u00E4tsauswahl verf\u00FCgbar)',\n noQuality: 'Qualit\u00E4tsauswahl nicht verf\u00FCgbar'\n },\n captions: {\n off: 'Aus',\n select: 'Untertitel ausw\u00E4hlen',\n fontSize: 'Schriftgr\u00F6\u00DFe',\n fontFamily: 'Schriftart',\n color: 'Textfarbe',\n backgroundColor: 'Hintergrundfarbe',\n opacity: 'Deckkraft'\n },\n fontSizes: {\n small: 'Klein',\n medium: 'Mittel',\n large: 'Gro\u00DF',\n xlarge: 'Sehr gro\u00DF'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Textfarbe',\n background: 'Hintergrund',\n font: 'Schrift',\n fontSize: 'Schriftgr\u00F6\u00DFe',\n opacity: 'Deckkraft'\n },\n audioDescription: {\n enable: 'Audiodeskription aktivieren',\n disable: 'Audiodeskription deaktivieren'\n },\n signLanguage: {\n show: 'Geb\u00E4rdensprache-Video anzeigen',\n hide: 'Geb\u00E4rdensprache-Video ausblenden'\n },\n transcript: {\n title: 'Transkript',\n close: 'Transkript schlie\u00DFen',\n loading: 'Transkript wird geladen...',\n noTranscript: 'Kein Transkript f\u00FCr dieses Video verf\u00FCgbar.'\n },\n settings: {\n title: 'Einstellungen',\n quality: 'Qualit\u00E4t',\n speed: 'Geschwindigkeit',\n captions: 'Untertitel',\n language: 'Sprache',\n reset: 'Zur\u00FCcksetzen',\n close: 'Schlie\u00DFen'\n },\n speeds: {\n normal: 'Normal'\n }\n },\n\n es: {\n player: {\n label: 'Reproductor de video',\n play: 'Reproducir',\n pause: 'Pausa',\n stop: 'Detener',\n restart: 'Reiniciar desde el principio',\n rewind: 'Retroceder',\n forward: 'Avanzar',\n rewindSeconds: 'Retroceder {seconds} segundos',\n forwardSeconds: 'Avanzar {seconds} segundos',\n previous: 'Pista anterior',\n next: 'Siguiente pista',\n volume: 'Volumen',\n mute: 'Silenciar',\n unmute: 'Activar sonido',\n fullscreen: 'Pantalla completa',\n exitFullscreen: 'Salir de pantalla completa',\n captions: 'Subt\u00EDtulos',\n chapters: 'Cap\u00EDtulos',\n quality: 'Calidad',\n captionStyling: 'Estilo de subt\u00EDtulos',\n transcript: 'Alternar transcripci\u00F3n',\n audioDescription: 'Audiodescripci\u00F3n',\n signLanguage: 'Video en lengua de se\u00F1as',\n settings: 'Configuraci\u00F3n',\n speed: 'Velocidad de reproducci\u00F3n',\n pip: 'Imagen en imagen',\n currentTime: 'Tiempo actual',\n duration: 'Duraci\u00F3n',\n progress: 'Progreso',\n seekForward: 'Avanzar {seconds} segundos',\n seekBackward: 'Retroceder {seconds} segundos',\n volumeUp: 'Subir volumen',\n volumeDown: 'Bajar volumen',\n loading: 'Cargando...',\n loadingChapters: 'Cargando cap\u00EDtulos...',\n error: 'Error al cargar',\n buffering: 'Almacenando en b\u00FAfer...',\n signLanguageVideo: 'Video en Lengua de Se\u00F1as',\n noChapters: 'No hay cap\u00EDtulos disponibles',\n noCaptions: 'No hay subt\u00EDtulos disponibles',\n auto: 'Autom\u00E1tico',\n autoQuality: 'Autom\u00E1tico (selecci\u00F3n de calidad no disponible)',\n noQuality: 'Selecci\u00F3n de calidad no disponible'\n },\n captions: {\n off: 'Desactivado',\n select: 'Seleccionar subt\u00EDtulos',\n fontSize: 'Tama\u00F1o de fuente',\n fontFamily: 'Familia de fuente',\n color: 'Color de texto',\n backgroundColor: 'Color de fondo',\n opacity: 'Opacidad'\n },\n fontSizes: {\n small: 'Peque\u00F1o',\n medium: 'Mediano',\n large: 'Grande',\n xlarge: 'Muy grande'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Color de texto',\n background: 'Fondo',\n font: 'Fuente',\n fontSize: 'Tama\u00F1o de fuente',\n opacity: 'Opacidad'\n },\n audioDescription: {\n enable: 'Activar audiodescripci\u00F3n',\n disable: 'Desactivar audiodescripci\u00F3n'\n },\n signLanguage: {\n show: 'Mostrar video en lengua de se\u00F1as',\n hide: 'Ocultar video en lengua de se\u00F1as'\n },\n transcript: {\n title: 'Transcripci\u00F3n',\n close: 'Cerrar transcripci\u00F3n',\n loading: 'Cargando transcripci\u00F3n...',\n noTranscript: 'No hay transcripci\u00F3n disponible para este video.'\n },\n settings: {\n title: 'Configuraci\u00F3n',\n quality: 'Calidad',\n speed: 'Velocidad',\n captions: 'Subt\u00EDtulos',\n language: 'Idioma',\n reset: 'Restablecer',\n close: 'Cerrar'\n },\n speeds: {\n normal: 'Normal'\n }\n },\n\n fr: {\n player: {\n label: 'Lecteur vid\u00E9o',\n play: 'Lecture',\n pause: 'Pause',\n stop: 'Arr\u00EAt',\n restart: 'Red\u00E9marrer du d\u00E9but',\n rewind: 'Reculer',\n forward: 'Avancer',\n rewindSeconds: 'Reculer de {seconds} secondes',\n forwardSeconds: 'Avancer de {seconds} secondes',\n previous: 'Piste pr\u00E9c\u00E9dente',\n next: 'Piste suivante',\n volume: 'Volume',\n mute: 'Muet',\n unmute: 'Activer le son',\n fullscreen: 'Plein \u00E9cran',\n exitFullscreen: 'Quitter le plein \u00E9cran',\n captions: 'Sous-titres',\n chapters: 'Chapitres',\n quality: 'Qualit\u00E9',\n captionStyling: 'Style des sous-titres',\n transcript: 'Activer/d\u00E9sactiver la transcription',\n audioDescription: 'Audiodescription',\n signLanguage: 'Vid\u00E9o en langue des signes',\n settings: 'Param\u00E8tres',\n speed: 'Vitesse de lecture',\n pip: 'Image dans l\\'image',\n currentTime: 'Temps actuel',\n duration: 'Dur\u00E9e',\n progress: 'Progression',\n seekForward: 'Avancer de {seconds} secondes',\n seekBackward: 'Reculer de {seconds} secondes',\n volumeUp: 'Augmenter le volume',\n volumeDown: 'Diminuer le volume',\n loading: 'Chargement...',\n loadingChapters: 'Chargement des chapitres...',\n error: 'Erreur de chargement',\n buffering: 'Mise en m\u00E9moire tampon...',\n signLanguageVideo: 'Vid\u00E9o en Langue des Signes',\n noChapters: 'Aucun chapitre disponible',\n noCaptions: 'Aucun sous-titre disponible',\n auto: 'Automatique',\n autoQuality: 'Automatique (s\u00E9lection de qualit\u00E9 non disponible)',\n noQuality: 'S\u00E9lection de qualit\u00E9 non disponible'\n },\n captions: {\n off: 'D\u00E9sactiv\u00E9',\n select: 'S\u00E9lectionner les sous-titres',\n fontSize: 'Taille de police',\n fontFamily: 'Police',\n color: 'Couleur du texte',\n backgroundColor: 'Couleur de fond',\n opacity: 'Opacit\u00E9'\n },\n fontSizes: {\n small: 'Petit',\n medium: 'Moyen',\n large: 'Grand',\n xlarge: 'Tr\u00E8s grand'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Couleur du texte',\n background: 'Arri\u00E8re-plan',\n font: 'Police',\n fontSize: 'Taille de police',\n opacity: 'Opacit\u00E9'\n },\n audioDescription: {\n enable: 'Activer l\\'audiodescription',\n disable: 'D\u00E9sactiver l\\'audiodescription'\n },\n signLanguage: {\n show: 'Afficher la vid\u00E9o en langue des signes',\n hide: 'Masquer la vid\u00E9o en langue des signes'\n },\n transcript: {\n title: 'Transcription',\n close: 'Fermer la transcription',\n loading: 'Chargement de la transcription...',\n noTranscript: 'Aucune transcription disponible pour cette vid\u00E9o.'\n },\n settings: {\n title: 'Param\u00E8tres',\n quality: 'Qualit\u00E9',\n speed: 'Vitesse',\n captions: 'Sous-titres',\n language: 'Langue',\n reset: 'R\u00E9initialiser',\n close: 'Fermer'\n },\n speeds: {\n normal: 'Normal'\n }\n },\n\n ja: {\n player: {\n label: '\u30D3\u30C7\u30AA\u30D7\u30EC\u30FC\u30E4\u30FC',\n play: '\u518D\u751F',\n pause: '\u4E00\u6642\u505C\u6B62',\n stop: '\u505C\u6B62',\n restart: '\u6700\u521D\u304B\u3089\u518D\u751F',\n rewind: '\u5DFB\u304D\u623B\u3057',\n forward: '\u65E9\u9001\u308A',\n rewindSeconds: '{seconds}\u79D2\u623B\u3059',\n forwardSeconds: '{seconds}\u79D2\u9032\u3081\u308B',\n previous: '\u524D\u306E\u30C8\u30E9\u30C3\u30AF',\n next: '\u6B21\u306E\u30C8\u30E9\u30C3\u30AF',\n volume: '\u97F3\u91CF',\n mute: '\u30DF\u30E5\u30FC\u30C8',\n unmute: '\u30DF\u30E5\u30FC\u30C8\u89E3\u9664',\n fullscreen: '\u5168\u753B\u9762\u8868\u793A',\n exitFullscreen: '\u5168\u753B\u9762\u8868\u793A\u3092\u7D42\u4E86',\n captions: '\u5B57\u5E55',\n chapters: '\u30C1\u30E3\u30D7\u30BF\u30FC',\n quality: '\u753B\u8CEA',\n captionStyling: '\u5B57\u5E55\u30B9\u30BF\u30A4\u30EB',\n transcript: '\u6587\u5B57\u8D77\u3053\u3057\u5207\u308A\u66FF\u3048',\n audioDescription: '\u97F3\u58F0\u89E3\u8AAC',\n signLanguage: '\u624B\u8A71\u52D5\u753B',\n settings: '\u8A2D\u5B9A',\n speed: '\u518D\u751F\u901F\u5EA6',\n pip: '\u30D4\u30AF\u30C1\u30E3\u30FC\u30A4\u30F3\u30D4\u30AF\u30C1\u30E3\u30FC',\n currentTime: '\u73FE\u5728\u306E\u6642\u9593',\n duration: '\u518D\u751F\u6642\u9593',\n progress: '\u9032\u884C\u72B6\u6CC1',\n seekForward: '{seconds}\u79D2\u9032\u3081\u308B',\n seekBackward: '{seconds}\u79D2\u623B\u3059',\n volumeUp: '\u97F3\u91CF\u3092\u4E0A\u3052\u308B',\n volumeDown: '\u97F3\u91CF\u3092\u4E0B\u3052\u308B',\n loading: '\u8AAD\u307F\u8FBC\u307F\u4E2D...',\n loadingChapters: '\u30C1\u30E3\u30D7\u30BF\u30FC\u8AAD\u307F\u8FBC\u307F\u4E2D...',\n error: '\u8AAD\u307F\u8FBC\u307F\u30A8\u30E9\u30FC',\n buffering: '\u30D0\u30C3\u30D5\u30A1\u30EA\u30F3\u30B0\u4E2D...',\n signLanguageVideo: '\u624B\u8A71\u52D5\u753B',\n noChapters: '\u30C1\u30E3\u30D7\u30BF\u30FC\u304C\u3042\u308A\u307E\u305B\u3093',\n noCaptions: '\u5B57\u5E55\u304C\u3042\u308A\u307E\u305B\u3093',\n auto: '\u81EA\u52D5',\n autoQuality: '\u81EA\u52D5\uFF08\u753B\u8CEA\u9078\u629E\u4E0D\u53EF\uFF09',\n noQuality: '\u753B\u8CEA\u9078\u629E\u4E0D\u53EF'\n },\n captions: {\n off: '\u30AA\u30D5',\n select: '\u5B57\u5E55\u3092\u9078\u629E',\n fontSize: '\u30D5\u30A9\u30F3\u30C8\u30B5\u30A4\u30BA',\n fontFamily: '\u30D5\u30A9\u30F3\u30C8',\n color: '\u30C6\u30AD\u30B9\u30C8\u306E\u8272',\n backgroundColor: '\u80CC\u666F\u8272',\n opacity: '\u4E0D\u900F\u660E\u5EA6'\n },\n fontSizes: {\n small: '\u5C0F',\n medium: '\u4E2D',\n large: '\u5927',\n xlarge: '\u7279\u5927'\n },\n fontFamilies: {\n sansSerif: '\u30B5\u30F3\u30BB\u30EA\u30D5',\n serif: '\u30BB\u30EA\u30D5',\n monospace: '\u7B49\u5E45'\n },\n styleLabels: {\n textColor: '\u30C6\u30AD\u30B9\u30C8\u306E\u8272',\n background: '\u80CC\u666F',\n font: '\u30D5\u30A9\u30F3\u30C8',\n fontSize: '\u30D5\u30A9\u30F3\u30C8\u30B5\u30A4\u30BA',\n opacity: '\u4E0D\u900F\u660E\u5EA6'\n },\n audioDescription: {\n enable: '\u97F3\u58F0\u89E3\u8AAC\u3092\u6709\u52B9\u306B\u3059\u308B',\n disable: '\u97F3\u58F0\u89E3\u8AAC\u3092\u7121\u52B9\u306B\u3059\u308B'\n },\n signLanguage: {\n show: '\u624B\u8A71\u52D5\u753B\u3092\u8868\u793A',\n hide: '\u624B\u8A71\u52D5\u753B\u3092\u975E\u8868\u793A'\n },\n transcript: {\n title: '\u6587\u5B57\u8D77\u3053\u3057',\n close: '\u6587\u5B57\u8D77\u3053\u3057\u3092\u9589\u3058\u308B',\n loading: '\u6587\u5B57\u8D77\u3053\u3057\u3092\u8AAD\u307F\u8FBC\u307F\u4E2D...',\n noTranscript: '\u3053\u306E\u30D3\u30C7\u30AA\u306E\u6587\u5B57\u8D77\u3053\u3057\u306F\u3042\u308A\u307E\u305B\u3093\u3002'\n },\n settings: {\n title: '\u8A2D\u5B9A',\n quality: '\u753B\u8CEA',\n speed: '\u901F\u5EA6',\n captions: '\u5B57\u5E55',\n language: '\u8A00\u8A9E',\n reset: '\u30EA\u30BB\u30C3\u30C8',\n close: '\u9589\u3058\u308B'\n },\n speeds: {\n normal: '\u901A\u5E38'\n }\n }\n};\n\n", "/**\n * Internationalization system\n */\n\nimport { translations } from './translations.js';\n\nclass I18n {\n constructor() {\n this.currentLanguage = 'en';\n this.translations = translations;\n }\n\n setLanguage(lang) {\n if (this.translations[lang]) {\n this.currentLanguage = lang;\n } else {\n console.warn(`Language \"${lang}\" not found, falling back to English`);\n this.currentLanguage = 'en';\n }\n }\n\n getLanguage() {\n return this.currentLanguage;\n }\n\n t(key, replacements = {}) {\n const keys = key.split('.');\n let value = this.translations[this.currentLanguage];\n \n for (const k of keys) {\n if (value && typeof value === 'object' && k in value) {\n value = value[k];\n } else {\n // Fallback to English\n value = this.translations.en;\n for (const fallbackKey of keys) {\n if (value && typeof value === 'object' && fallbackKey in value) {\n value = value[fallbackKey];\n } else {\n return key; // Return key if not found\n }\n }\n break;\n }\n }\n \n // Replace placeholders\n if (typeof value === 'string') {\n Object.entries(replacements).forEach(([placeholder, replacement]) => {\n value = value.replace(new RegExp(`{${placeholder}}`, 'g'), replacement);\n });\n }\n \n return value;\n }\n\n addTranslation(lang, translations) {\n if (!this.translations[lang]) {\n this.translations[lang] = {};\n }\n Object.assign(this.translations[lang], translations);\n }\n}\n\nexport const i18n = new I18n();\n\n", "/**\n * Control Bar Component\n */\n\nimport {DOMUtils} from '../utils/DOMUtils.js';\nimport {TimeUtils} from '../utils/TimeUtils.js';\nimport {createIconElement} from '../icons/Icons.js';\nimport {i18n} from '../i18n/i18n.js';\n\nexport class ControlBar {\n constructor(player) {\n this.player = player;\n this.element = null;\n this.controls = {};\n this.hideTimeout = null;\n this.isDraggingProgress = false;\n this.isDraggingVolume = false;\n\n this.init();\n }\n\n init() {\n this.createElement();\n this.createControls();\n this.attachEvents();\n this.setupAutoHide();\n }\n\n // Helper method to check if we're on a mobile device\n isMobile() {\n return window.innerWidth < 640;\n }\n\n // Smart menu positioning to avoid overflow\n positionMenu(menu, button) {\n const isMobile = this.isMobile();\n \n if (isMobile) {\n // Use bottom sheet on mobile - already styled via CSS\n return;\n }\n\n // Desktop: Smart positioning\n setTimeout(() => {\n const buttonRect = button.getBoundingClientRect();\n const menuRect = menu.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n \n const spaceAbove = buttonRect.top;\n const spaceBelow = viewportHeight - buttonRect.bottom;\n \n // Prefer above, but switch to below if not enough space\n if (spaceAbove < menuRect.height + 20 && spaceBelow > spaceAbove) {\n menu.style.bottom = 'auto';\n menu.style.top = 'calc(100% + 8px)';\n menu.classList.add('vidply-menu-below');\n }\n \n // Check horizontal overflow\n const menuLeft = buttonRect.left + buttonRect.width / 2 - menuRect.width / 2;\n if (menuLeft < 10) {\n // Too far left, align to left edge\n menu.style.right = 'auto';\n menu.style.left = '0';\n menu.style.transform = 'translateX(0)';\n } else if (menuLeft + menuRect.width > viewportWidth - 10) {\n // Too far right, align to right edge\n menu.style.left = 'auto';\n menu.style.right = '0';\n menu.style.transform = 'translateX(0)';\n }\n }, 0);\n }\n\n\n // Helper method to attach close-on-outside-click behavior to menus\n attachMenuCloseHandler(menu, button, preventCloseOnInteraction = false) {\n // Position menu smartly\n this.positionMenu(menu, button);\n \n setTimeout(() => {\n const closeMenu = (e) => {\n // If this menu has form controls, don't close when clicking inside\n if (preventCloseOnInteraction && menu.contains(e.target)) {\n return;\n }\n\n // Check if click is outside menu and button\n if (!menu.contains(e.target) && !button.contains(e.target)) {\n menu.remove();\n document.removeEventListener('click', closeMenu);\n document.removeEventListener('keydown', handleEscape);\n }\n };\n\n const handleEscape = (e) => {\n if (e.key === 'Escape') {\n menu.remove();\n document.removeEventListener('click', closeMenu);\n document.removeEventListener('keydown', handleEscape);\n // Return focus to button\n button.focus();\n }\n };\n\n document.addEventListener('click', closeMenu);\n document.addEventListener('keydown', handleEscape);\n }, 100);\n }\n\n // Helper method to add keyboard navigation to menus (arrow keys)\n attachMenuKeyboardNavigation(menu) {\n const menuItems = Array.from(menu.querySelectorAll(`.${this.player.options.classPrefix}-menu-item`));\n \n if (menuItems.length === 0) return;\n\n const handleKeyDown = (e) => {\n const currentIndex = menuItems.indexOf(document.activeElement);\n \n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n const nextIndex = (currentIndex + 1) % menuItems.length;\n menuItems[nextIndex].focus();\n break;\n \n case 'ArrowUp':\n e.preventDefault();\n const prevIndex = (currentIndex - 1 + menuItems.length) % menuItems.length;\n menuItems[prevIndex].focus();\n break;\n \n case 'Home':\n e.preventDefault();\n menuItems[0].focus();\n break;\n \n case 'End':\n e.preventDefault();\n menuItems[menuItems.length - 1].focus();\n break;\n \n case 'Enter':\n case ' ':\n e.preventDefault();\n if (document.activeElement && menuItems.includes(document.activeElement)) {\n document.activeElement.click();\n }\n break;\n }\n };\n\n menu.addEventListener('keydown', handleKeyDown);\n }\n\n createElement() {\n this.element = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-controls`,\n attributes: {\n 'role': 'region',\n 'aria-label': i18n.t('player.label') + ' controls'\n }\n });\n }\n\n createControls() {\n // Progress bar container\n if (this.player.options.progressBar) {\n this.createProgressBar();\n }\n\n // Button container\n const buttonContainer = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-controls-buttons`\n });\n\n // Left buttons\n const leftButtons = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-controls-left`\n });\n\n // Previous track button (if playlist)\n if (this.player.playlistManager) {\n leftButtons.appendChild(this.createPreviousButton());\n }\n\n // Play/Pause button\n if (this.player.options.playPauseButton) {\n leftButtons.appendChild(this.createPlayPauseButton());\n }\n\n // Restart button (right beside play button)\n leftButtons.appendChild(this.createRestartButton());\n\n // Next track button (if playlist)\n if (this.player.playlistManager) {\n leftButtons.appendChild(this.createNextButton());\n }\n\n // Rewind button (not shown in playlist mode)\n if (!this.player.playlistManager) {\n leftButtons.appendChild(this.createRewindButton());\n }\n\n // Forward button (not shown in playlist mode)\n if (!this.player.playlistManager) {\n leftButtons.appendChild(this.createForwardButton());\n }\n\n // Volume control\n if (this.player.options.volumeControl) {\n leftButtons.appendChild(this.createVolumeControl());\n }\n\n // Time display\n if (this.player.options.currentTime || this.player.options.duration) {\n leftButtons.appendChild(this.createTimeDisplay());\n }\n\n // Right buttons\n this.rightButtons = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-controls-right`\n });\n\n // Check for available features\n const hasChapters = this.hasChapterTracks();\n const hasCaptions = this.hasCaptionTracks();\n const hasQualityLevels = this.hasQualityLevels();\n const hasAudioDescription = this.hasAudioDescription();\n\n // Chapters button - only show if chapters are available\n if (this.player.options.chaptersButton && hasChapters) {\n this.rightButtons.appendChild(this.createChaptersButton());\n }\n\n // Quality button - only show if quality levels are available\n if (this.player.options.qualityButton && hasQualityLevels) {\n this.rightButtons.appendChild(this.createQualityButton());\n }\n\n // Caption styling button (font, size, color) - only show if captions are available\n if (this.player.options.captionStyleButton && hasCaptions) {\n this.rightButtons.appendChild(this.createCaptionStyleButton());\n }\n\n // Speed button - always available\n if (this.player.options.speedButton) {\n this.rightButtons.appendChild(this.createSpeedButton());\n }\n\n // Captions language selector button - only show if captions are available\n if (this.player.options.captionsButton && hasCaptions) {\n this.rightButtons.appendChild(this.createCaptionsButton());\n }\n\n // Transcript button - only show if captions/subtitles are available\n if (this.player.options.transcriptButton && hasCaptions) {\n this.rightButtons.appendChild(this.createTranscriptButton());\n }\n\n // Audio Description button - only show if audio description source is available\n if (this.player.options.audioDescriptionButton && hasAudioDescription) {\n this.rightButtons.appendChild(this.createAudioDescriptionButton());\n }\n\n // Sign Language button - only show if sign language source is available\n const hasSignLanguage = this.hasSignLanguage();\n if (this.player.options.signLanguageButton && hasSignLanguage) {\n this.rightButtons.appendChild(this.createSignLanguageButton());\n }\n\n // PiP button\n if (this.player.options.pipButton && 'pictureInPictureEnabled' in document) {\n this.rightButtons.appendChild(this.createPipButton());\n }\n\n // Fullscreen button\n if (this.player.options.fullscreenButton) {\n this.rightButtons.appendChild(this.createFullscreenButton());\n }\n\n buttonContainer.appendChild(leftButtons);\n buttonContainer.appendChild(this.rightButtons);\n this.element.appendChild(buttonContainer);\n }\n\n // Helper methods to check for available features\n hasChapterTracks() {\n const textTracks = this.player.element.textTracks;\n for (let i = 0; i < textTracks.length; i++) {\n if (textTracks[i].kind === 'chapters') {\n return true;\n }\n }\n return false;\n }\n\n hasCaptionTracks() {\n const textTracks = this.player.element.textTracks;\n for (let i = 0; i < textTracks.length; i++) {\n if (textTracks[i].kind === 'captions' || textTracks[i].kind === 'subtitles') {\n return true;\n }\n }\n return false;\n }\n\n hasQualityLevels() {\n // Check if renderer supports quality selection\n if (this.player.renderer && this.player.renderer.getQualities) {\n const qualities = this.player.renderer.getQualities();\n return qualities && qualities.length > 1;\n }\n return false;\n }\n\n hasAudioDescription() {\n return this.player.audioDescriptionSrc && this.player.audioDescriptionSrc.length > 0;\n }\n\n hasSignLanguage() {\n return this.player.signLanguageSrc && this.player.signLanguageSrc.length > 0;\n }\n\n createProgressBar() {\n const progressContainer = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-container`,\n attributes: {\n 'role': 'slider',\n 'aria-label': i18n.t('player.progress'),\n 'aria-valuemin': '0',\n 'aria-valuemax': '100',\n 'aria-valuenow': '0',\n 'tabindex': '0'\n }\n });\n\n // Buffered progress\n this.controls.buffered = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-buffered`\n });\n\n // Played progress\n this.controls.played = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-played`\n });\n\n // Progress handle\n this.controls.progressHandle = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-handle`\n });\n\n // Tooltip\n this.controls.progressTooltip = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-tooltip`\n });\n\n progressContainer.appendChild(this.controls.buffered);\n progressContainer.appendChild(this.controls.played);\n this.controls.played.appendChild(this.controls.progressHandle);\n progressContainer.appendChild(this.controls.progressTooltip);\n\n this.controls.progress = progressContainer;\n this.element.appendChild(progressContainer);\n\n // Progress bar events\n this.setupProgressBarEvents();\n }\n\n setupProgressBarEvents() {\n const progress = this.controls.progress;\n\n const updateProgress = (clientX) => {\n const rect = progress.getBoundingClientRect();\n const percent = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));\n const time = percent * this.player.state.duration;\n return {percent, time};\n };\n\n // Mouse events\n progress.addEventListener('mousedown', (e) => {\n this.isDraggingProgress = true;\n const {time} = updateProgress(e.clientX);\n this.player.seek(time);\n });\n\n document.addEventListener('mousemove', (e) => {\n if (this.isDraggingProgress) {\n const {time} = updateProgress(e.clientX);\n this.player.seek(time);\n }\n });\n\n document.addEventListener('mouseup', () => {\n this.isDraggingProgress = false;\n });\n\n // Hover tooltip\n progress.addEventListener('mousemove', (e) => {\n if (!this.isDraggingProgress) {\n const {time} = updateProgress(e.clientX);\n this.controls.progressTooltip.textContent = TimeUtils.formatTime(time);\n this.controls.progressTooltip.style.left = `${e.clientX - progress.getBoundingClientRect().left}px`;\n this.controls.progressTooltip.style.display = 'block';\n }\n });\n\n progress.addEventListener('mouseleave', () => {\n this.controls.progressTooltip.style.display = 'none';\n });\n\n // Keyboard navigation\n progress.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') {\n e.preventDefault();\n this.player.seekBackward(5);\n } else if (e.key === 'ArrowRight') {\n e.preventDefault();\n this.player.seekForward(5);\n }\n });\n\n // Touch events\n progress.addEventListener('touchstart', (e) => {\n this.isDraggingProgress = true;\n const touch = e.touches[0];\n const {time} = updateProgress(touch.clientX);\n this.player.seek(time);\n });\n\n progress.addEventListener('touchmove', (e) => {\n if (this.isDraggingProgress) {\n e.preventDefault();\n const touch = e.touches[0];\n const {time} = updateProgress(touch.clientX);\n this.player.seek(time);\n }\n });\n\n progress.addEventListener('touchend', () => {\n this.isDraggingProgress = false;\n });\n }\n\n createPlayPauseButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-play-pause`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.play')\n }\n });\n\n button.appendChild(createIconElement('play'));\n\n button.addEventListener('click', () => {\n this.player.toggle();\n });\n\n this.controls.playPause = button;\n return button;\n }\n\n createRestartButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-restart`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.restart')\n }\n });\n\n button.appendChild(createIconElement('restart'));\n\n button.addEventListener('click', () => {\n this.player.seek(0);\n this.player.play();\n });\n\n return button;\n }\n\n createPreviousButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-previous`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.previous')\n }\n });\n\n button.appendChild(createIconElement('skipPrevious'));\n\n button.addEventListener('click', () => {\n if (this.player.playlistManager) {\n this.player.playlistManager.previous();\n }\n });\n\n // Update button state\n const updateState = () => {\n if (this.player.playlistManager) {\n button.disabled = !this.player.playlistManager.hasPrevious() && !this.player.playlistManager.options.loop;\n }\n };\n this.player.on('playlisttrackchange', updateState);\n updateState();\n\n this.controls.previous = button;\n return button;\n }\n\n createNextButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-next`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.next')\n }\n });\n\n button.appendChild(createIconElement('skipNext'));\n\n button.addEventListener('click', () => {\n if (this.player.playlistManager) {\n this.player.playlistManager.next();\n }\n });\n\n // Update button state\n const updateState = () => {\n if (this.player.playlistManager) {\n button.disabled = !this.player.playlistManager.hasNext() && !this.player.playlistManager.options.loop;\n }\n };\n this.player.on('playlisttrackchange', updateState);\n updateState();\n\n this.controls.next = button;\n return button;\n }\n\n createRewindButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-rewind`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.rewindSeconds', { seconds: 15 })\n }\n });\n\n button.appendChild(createIconElement('rewind'));\n\n button.addEventListener('click', () => {\n this.player.seekBackward(15);\n });\n\n return button;\n }\n\n createForwardButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-forward`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.forwardSeconds', { seconds: 15 })\n }\n });\n\n button.appendChild(createIconElement('forward'));\n\n button.addEventListener('click', () => {\n this.player.seekForward(15);\n });\n\n return button;\n }\n\n createVolumeControl() {\n // Mute/Volume button\n const muteButton = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-mute`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.volume'),\n 'aria-haspopup': 'true'\n }\n });\n\n muteButton.appendChild(createIconElement('volumeHigh'));\n\n // Toggle mute on right click, show volume slider on left click\n muteButton.addEventListener('contextmenu', (e) => {\n e.preventDefault();\n this.player.toggleMute();\n });\n\n muteButton.addEventListener('click', () => {\n this.showVolumeSlider(muteButton);\n });\n\n this.controls.mute = muteButton;\n\n return muteButton;\n }\n\n showVolumeSlider(button) {\n // Remove existing slider if any\n const existingSlider = document.querySelector(`.${this.player.options.classPrefix}-volume-menu`);\n if (existingSlider) {\n existingSlider.remove();\n return;\n }\n\n // Volume menu container\n const volumeMenu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-menu ${this.player.options.classPrefix}-menu`\n });\n\n const volumeSlider = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-slider`,\n attributes: {\n 'role': 'slider',\n 'aria-label': i18n.t('player.volume'),\n 'aria-valuemin': '0',\n 'aria-valuemax': '100',\n 'aria-valuenow': String(Math.round(this.player.state.volume * 100)),\n 'tabindex': '0'\n }\n });\n\n const volumeTrack = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-track`\n });\n\n const volumeFill = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-fill`\n });\n\n const volumeHandle = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-handle`\n });\n\n volumeTrack.appendChild(volumeFill);\n volumeFill.appendChild(volumeHandle);\n volumeSlider.appendChild(volumeTrack);\n volumeMenu.appendChild(volumeSlider);\n\n // Volume slider events\n const updateVolume = (clientY) => {\n const rect = volumeTrack.getBoundingClientRect();\n const percent = Math.max(0, Math.min(1, 1 - ((clientY - rect.top) / rect.height)));\n this.player.setVolume(percent);\n };\n\n volumeSlider.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n this.isDraggingVolume = true;\n updateVolume(e.clientY);\n });\n\n document.addEventListener('mousemove', (e) => {\n if (this.isDraggingVolume) {\n updateVolume(e.clientY);\n }\n });\n\n document.addEventListener('mouseup', () => {\n this.isDraggingVolume = false;\n });\n\n // Keyboard volume control\n volumeSlider.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n this.player.setVolume(Math.min(1, this.player.state.volume + 0.1));\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n this.player.setVolume(Math.max(0, this.player.state.volume - 0.1));\n }\n });\n\n // Prevent menu from closing when interacting with slider\n volumeMenu.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n // Append menu to button\n button.appendChild(volumeMenu);\n\n this.controls.volumeSlider = volumeSlider;\n this.controls.volumeFill = volumeFill;\n\n // Close menu on outside click\n this.attachMenuCloseHandler(volumeMenu, button, true);\n }\n\n createTimeDisplay() {\n const container = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-time`\n });\n\n this.controls.currentTimeDisplay = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-current-time`,\n textContent: '00:00'\n });\n\n const separator = DOMUtils.createElement('span', {\n textContent: ' / ',\n attributes: {\n 'aria-hidden': 'true'\n }\n });\n\n this.controls.durationDisplay = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-duration`,\n textContent: '00:00'\n });\n\n container.appendChild(this.controls.currentTimeDisplay);\n container.appendChild(separator);\n container.appendChild(this.controls.durationDisplay);\n\n return container;\n }\n\n createChaptersButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-chapters`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.chapters'),\n 'aria-haspopup': 'menu'\n }\n });\n\n button.appendChild(createIconElement('playlist'));\n\n button.addEventListener('click', () => {\n this.showChaptersMenu(button);\n });\n\n this.controls.chapters = button;\n return button;\n }\n\n showChaptersMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-chapters-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-chapters-menu ${this.player.options.classPrefix}-menu`,\n attributes: {\n 'role': 'menu',\n 'aria-label': i18n.t('player.chapters')\n }\n });\n\n // Get chapter tracks\n const chapterTracks = Array.from(this.player.element.textTracks).filter(\n track => track.kind === 'chapters'\n );\n\n if (chapterTracks.length === 0) {\n // No chapters available\n const noChaptersItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.noChapters'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(noChaptersItem);\n } else {\n const chapterTrack = chapterTracks[0];\n\n // Ensure track is in 'hidden' mode to load cues\n if (chapterTrack.mode === 'disabled') {\n chapterTrack.mode = 'hidden';\n }\n\n if (!chapterTrack.cues || chapterTrack.cues.length === 0) {\n // Cues not loaded yet - wait for them to load\n const loadingItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.loadingChapters'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(loadingItem);\n\n // Listen for track load event\n const onTrackLoad = () => {\n // Remove loading message and rebuild menu\n menu.remove();\n this.showChaptersMenu(button);\n };\n\n chapterTrack.addEventListener('load', onTrackLoad, {once: true});\n\n // Also try again after a short delay as fallback\n setTimeout(() => {\n if (chapterTrack.cues && chapterTrack.cues.length > 0 && document.contains(menu)) {\n menu.remove();\n this.showChaptersMenu(button);\n }\n }, 500);\n } else {\n // Display chapters\n const cues = chapterTrack.cues;\n for (let i = 0; i < cues.length; i++) {\n const cue = cues[i];\n const item = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n attributes: {\n 'type': 'button',\n 'role': 'menuitem',\n 'tabindex': '-1'\n }\n });\n\n const timeLabel = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-chapter-time`,\n textContent: TimeUtils.formatTime(cue.startTime)\n });\n\n const titleLabel = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-chapter-title`,\n textContent: cue.text\n });\n\n item.appendChild(timeLabel);\n item.appendChild(document.createTextNode(' '));\n item.appendChild(titleLabel);\n\n item.addEventListener('click', () => {\n this.player.seek(cue.startTime);\n menu.remove();\n });\n\n menu.appendChild(item);\n }\n \n // Add keyboard navigation\n this.attachMenuKeyboardNavigation(menu);\n \n // Focus first item\n setTimeout(() => {\n const firstItem = menu.querySelector(`.${this.player.options.classPrefix}-menu-item`);\n if (firstItem) {\n firstItem.focus();\n }\n }, 0);\n }\n }\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n }\n\n createQualityButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-quality`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.quality'),\n 'aria-haspopup': 'menu'\n }\n });\n\n button.appendChild(createIconElement('hd'));\n\n // Add quality indicator text\n const qualityText = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-quality-text`,\n textContent: ''\n });\n button.appendChild(qualityText);\n\n button.addEventListener('click', () => {\n this.showQualityMenu(button);\n });\n\n this.controls.quality = button;\n this.controls.qualityText = qualityText;\n \n // Update quality indicator after a short delay to ensure renderer is ready\n setTimeout(() => this.updateQualityIndicator(), 500);\n \n return button;\n }\n\n showQualityMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-quality-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-quality-menu ${this.player.options.classPrefix}-menu`,\n attributes: {\n 'role': 'menu',\n 'aria-label': i18n.t('player.quality')\n }\n });\n\n // Check if renderer supports quality selection\n if (this.player.renderer && this.player.renderer.getQualities) {\n const qualities = this.player.renderer.getQualities();\n const currentQuality = this.player.renderer.getCurrentQuality ? this.player.renderer.getCurrentQuality() : -1;\n const isHLS = this.player.renderer.hls !== undefined;\n\n if (qualities.length === 0) {\n // No qualities available\n const noQualityItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.autoQuality'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(noQualityItem);\n } else {\n let activeItem = null;\n \n // Auto quality option (only for HLS)\n if (isHLS) {\n const autoItem = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.auto'),\n attributes: {\n 'type': 'button',\n 'role': 'menuitem',\n 'tabindex': '-1'\n }\n });\n\n // Check if auto is currently selected\n const isAuto = this.player.renderer.hls && this.player.renderer.hls.currentLevel === -1;\n if (isAuto) {\n autoItem.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n autoItem.appendChild(createIconElement('check'));\n activeItem = autoItem;\n }\n\n autoItem.addEventListener('click', () => {\n if (this.player.renderer.switchQuality) {\n this.player.renderer.switchQuality(-1); // -1 for auto\n }\n menu.remove();\n });\n\n menu.appendChild(autoItem);\n }\n\n // Quality options\n qualities.forEach(quality => {\n const item = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: quality.name || `${quality.height}p`,\n attributes: {\n 'type': 'button',\n 'role': 'menuitem',\n 'tabindex': '-1'\n }\n });\n\n // Highlight current quality\n if (quality.index === currentQuality) {\n item.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n item.appendChild(createIconElement('check'));\n activeItem = item;\n }\n\n item.addEventListener('click', () => {\n if (this.player.renderer.switchQuality) {\n this.player.renderer.switchQuality(quality.index);\n }\n menu.remove();\n });\n\n menu.appendChild(item);\n });\n \n // Add keyboard navigation\n this.attachMenuKeyboardNavigation(menu);\n \n // Focus active item or first item\n setTimeout(() => {\n const focusTarget = activeItem || menu.querySelector(`.${this.player.options.classPrefix}-menu-item`);\n if (focusTarget) {\n focusTarget.focus();\n }\n }, 0);\n }\n } else {\n // No quality support\n const noSupportItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.noQuality'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(noSupportItem);\n }\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n }\n\n createCaptionStyleButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-caption-style`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.captionStyling'),\n 'aria-haspopup': 'menu',\n 'title': i18n.t('player.captionStyling')\n }\n });\n\n // Create \"Aa\" text icon for styling\n const textIcon = DOMUtils.createElement('span', {\n textContent: 'Aa',\n style: {\n fontSize: '14px',\n fontWeight: 'bold'\n }\n });\n button.appendChild(textIcon);\n\n button.addEventListener('click', () => {\n this.showCaptionStyleMenu(button);\n });\n\n this.controls.captionStyle = button;\n return button;\n }\n\n showCaptionStyleMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-caption-style-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-caption-style-menu ${this.player.options.classPrefix}-menu ${this.player.options.classPrefix}-settings-menu`,\n attributes: {\n 'role': 'menu',\n 'aria-label': i18n.t('player.captionStyling')\n }\n });\n\n // Prevent menu from closing when clicking inside\n menu.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n // Check if there are any caption tracks\n if (!this.player.captionManager || this.player.captionManager.tracks.length === 0) {\n // Show \"No captions available\" message\n const noTracksItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.noCaptions'),\n style: {opacity: '0.5', cursor: 'default', padding: '12px 16px'}\n });\n menu.appendChild(noTracksItem);\n\n // Append menu to button\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button, true);\n return;\n }\n\n // Font Size\n const fontSizeGroup = this.createStyleControl(\n i18n.t('styleLabels.fontSize'),\n 'captionsFontSize',\n [\n {label: i18n.t('fontSizes.small'), value: '80%'},\n {label: i18n.t('fontSizes.medium'), value: '100%'},\n {label: i18n.t('fontSizes.large'), value: '120%'},\n {label: i18n.t('fontSizes.xlarge'), value: '150%'}\n ]\n );\n menu.appendChild(fontSizeGroup);\n\n // Font Family\n const fontFamilyGroup = this.createStyleControl(\n i18n.t('styleLabels.font'),\n 'captionsFontFamily',\n [\n {label: i18n.t('fontFamilies.sansSerif'), value: 'sans-serif'},\n {label: i18n.t('fontFamilies.serif'), value: 'serif'},\n {label: i18n.t('fontFamilies.monospace'), value: 'monospace'}\n ]\n );\n menu.appendChild(fontFamilyGroup);\n\n // Text Color\n const colorGroup = this.createColorControl(i18n.t('styleLabels.textColor'), 'captionsColor');\n menu.appendChild(colorGroup);\n\n // Background Color\n const bgColorGroup = this.createColorControl(i18n.t('styleLabels.background'), 'captionsBackgroundColor');\n menu.appendChild(bgColorGroup);\n\n // Opacity\n const opacityGroup = this.createOpacityControl(i18n.t('styleLabels.opacity'), 'captionsOpacity');\n menu.appendChild(opacityGroup);\n\n // Set min-width for caption style menu\n menu.style.minWidth = '220px';\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click (but not when interacting with controls)\n this.attachMenuCloseHandler(menu, button, true);\n\n // Auto-focus the first select element\n setTimeout(() => {\n const firstSelect = menu.querySelector('select');\n if (firstSelect) {\n firstSelect.focus();\n }\n }, 0);\n }\n\n createStyleControl(label, property, options) {\n const group = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-style-group`\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n style: {\n display: 'block',\n fontSize: '12px',\n marginBottom: '4px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n group.appendChild(labelEl);\n\n const select = DOMUtils.createElement('select', {\n className: `${this.player.options.classPrefix}-style-select`,\n style: {\n width: '100%',\n padding: '6px',\n background: 'var(--vidply-white)',\n border: '1px solid var(--vidply-white-10)',\n borderRadius: '4px',\n color: 'var(--vidply-black)',\n fontSize: '13px'\n }\n });\n\n const currentValue = this.player.options[property];\n options.forEach(opt => {\n const option = DOMUtils.createElement('option', {\n textContent: opt.label,\n attributes: {value: opt.value}\n });\n if (opt.value === currentValue) {\n option.selected = true;\n }\n select.appendChild(option);\n });\n\n // Prevent clicks from closing the menu\n select.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n });\n\n select.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n select.addEventListener('change', (e) => {\n e.stopPropagation();\n this.player.options[property] = e.target.value;\n if (this.player.captionManager) {\n this.player.captionManager.setCaptionStyle(\n property.replace('captions', '').charAt(0).toLowerCase() + property.replace('captions', '').slice(1),\n e.target.value\n );\n }\n });\n\n group.appendChild(select);\n return group;\n }\n\n createColorControl(label, property) {\n const group = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-style-group`\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n style: {\n display: 'block',\n fontSize: '12px',\n marginBottom: '4px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n group.appendChild(labelEl);\n\n const input = DOMUtils.createElement('input', {\n attributes: {\n type: 'color',\n value: this.player.options[property]\n },\n style: {\n width: '100%',\n height: '32px',\n padding: '2px',\n background: 'rgba(255,255,255,0.1)',\n border: '1px solid rgba(255,255,255,0.2)',\n borderRadius: '4px',\n cursor: 'pointer'\n }\n });\n\n // Prevent clicks from closing the menu\n input.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('change', (e) => {\n e.stopPropagation();\n this.player.options[property] = e.target.value;\n if (this.player.captionManager) {\n this.player.captionManager.setCaptionStyle(\n property.replace('captions', '').charAt(0).toLowerCase() + property.replace('captions', '').slice(1),\n e.target.value\n );\n }\n });\n\n group.appendChild(input);\n return group;\n }\n\n createOpacityControl(label, property) {\n const group = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-style-group`\n });\n\n const labelContainer = DOMUtils.createElement('div', {\n style: {\n display: 'flex',\n justifyContent: 'space-between',\n marginBottom: '4px'\n }\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n style: {\n fontSize: '12px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n\n const valueEl = DOMUtils.createElement('span', {\n textContent: Math.round(this.player.options[property] * 100) + '%',\n style: {\n fontSize: '12px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n\n labelContainer.appendChild(labelEl);\n labelContainer.appendChild(valueEl);\n group.appendChild(labelContainer);\n\n const input = DOMUtils.createElement('input', {\n attributes: {\n type: 'range',\n min: '0',\n max: '1',\n step: '0.1',\n value: String(this.player.options[property])\n },\n style: {\n width: '100%',\n cursor: 'pointer'\n }\n });\n\n // Prevent clicks from closing the menu\n input.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('input', (e) => {\n e.stopPropagation();\n const value = parseFloat(e.target.value);\n valueEl.textContent = Math.round(value * 100) + '%';\n this.player.options[property] = value;\n if (this.player.captionManager) {\n this.player.captionManager.setCaptionStyle(\n property.replace('captions', '').charAt(0).toLowerCase() + property.replace('captions', '').slice(1),\n value\n );\n }\n });\n\n group.appendChild(input);\n return group;\n }\n\n createSpeedButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-speed`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.speed'),\n 'aria-haspopup': 'menu'\n }\n });\n\n button.appendChild(createIconElement('speed'));\n\n const speedText = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-speed-text`,\n textContent: '1x'\n });\n button.appendChild(speedText);\n\n button.addEventListener('click', () => {\n this.showSpeedMenu(button);\n });\n\n this.controls.speed = button;\n this.controls.speedText = speedText;\n return button;\n }\n\n formatSpeedLabel(speed) {\n // Special case: 1x is \"Normal\" (translated)\n if (speed === 1) {\n return i18n.t('speeds.normal');\n }\n \n // For other speeds, format with locale-specific decimal separator\n const speedStr = speed.toLocaleString(i18n.getLanguage(), {\n minimumFractionDigits: 0,\n maximumFractionDigits: 2\n });\n \n return `${speedStr}\u00D7`;\n }\n\n showSpeedMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-speed-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-speed-menu ${this.player.options.classPrefix}-menu`,\n attributes: {\n 'role': 'menu'\n }\n });\n\n const speeds = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];\n let activeItem = null;\n\n speeds.forEach(speed => {\n const item = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: this.formatSpeedLabel(speed),\n attributes: {\n 'type': 'button',\n 'role': 'menuitem',\n 'tabindex': '-1'\n }\n });\n\n if (speed === this.player.state.playbackSpeed) {\n item.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n item.appendChild(createIconElement('check'));\n activeItem = item;\n }\n\n item.addEventListener('click', () => {\n this.player.setPlaybackSpeed(speed);\n menu.remove();\n });\n\n menu.appendChild(item);\n });\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Add keyboard navigation\n this.attachMenuKeyboardNavigation(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n\n // Focus the active item or first item\n setTimeout(() => {\n const focusTarget = activeItem || menu.querySelector(`.${this.player.options.classPrefix}-menu-item`);\n if (focusTarget) {\n focusTarget.focus();\n }\n }, 0);\n }\n\n createCaptionsButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-captions-button`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.captions'),\n 'aria-pressed': 'false',\n 'aria-haspopup': 'menu'\n }\n });\n\n button.appendChild(createIconElement('captionsOff'));\n\n button.addEventListener('click', () => {\n this.showCaptionsMenu(button);\n });\n\n this.controls.captions = button;\n return button;\n }\n\n showCaptionsMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-captions-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-captions-menu ${this.player.options.classPrefix}-menu`,\n attributes: {\n 'role': 'menu',\n 'aria-label': i18n.t('captions.select')\n }\n });\n\n // Check if there are any caption tracks\n if (!this.player.captionManager || this.player.captionManager.tracks.length === 0) {\n // Show \"No captions available\" message\n const noTracksItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.noCaptions'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(noTracksItem);\n\n // Append menu to button\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n return;\n }\n\n let activeItem = null;\n\n // Off option\n const offItem = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('captions.off'),\n attributes: {\n 'type': 'button',\n 'role': 'menuitem',\n 'tabindex': '-1'\n }\n });\n\n if (!this.player.state.captionsEnabled) {\n offItem.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n offItem.appendChild(createIconElement('check'));\n activeItem = offItem;\n }\n\n offItem.addEventListener('click', () => {\n this.player.disableCaptions();\n this.updateCaptionsButton();\n menu.remove();\n });\n\n menu.appendChild(offItem);\n\n // Available tracks\n const tracks = this.player.captionManager.getAvailableTracks();\n tracks.forEach(track => {\n const item = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: track.label,\n attributes: {\n 'type': 'button',\n 'role': 'menuitem',\n 'lang': track.language,\n 'tabindex': '-1'\n }\n });\n\n // Check if this is the current track\n if (this.player.state.captionsEnabled &&\n this.player.captionManager.currentTrack === this.player.captionManager.tracks[track.index]) {\n item.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n item.appendChild(createIconElement('check'));\n activeItem = item;\n }\n\n item.addEventListener('click', () => {\n this.player.captionManager.switchTrack(track.index);\n this.updateCaptionsButton();\n menu.remove();\n });\n\n menu.appendChild(item);\n });\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Add keyboard navigation for the menu\n this.attachMenuKeyboardNavigation(menu);\n\n // Close menu on outside click and Escape key\n this.attachMenuCloseHandler(menu, button);\n\n // Focus the active item or the first item\n setTimeout(() => {\n const focusTarget = activeItem || menu.querySelector(`.${this.player.options.classPrefix}-menu-item`);\n if (focusTarget) {\n focusTarget.focus();\n }\n }, 0);\n }\n\n updateCaptionsButton() {\n if (!this.controls.captions) return;\n\n const icon = this.controls.captions.querySelector('.vidply-icon');\n const isEnabled = this.player.state.captionsEnabled;\n\n icon.innerHTML = isEnabled ?\n createIconElement('captions').innerHTML :\n createIconElement('captionsOff').innerHTML;\n\n this.controls.captions.setAttribute('aria-pressed', isEnabled ? 'true' : 'false');\n }\n\n createTranscriptButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-transcript`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.transcript'),\n 'aria-pressed': 'false'\n }\n });\n\n button.appendChild(createIconElement('transcript'));\n\n button.addEventListener('click', () => {\n if (this.player.transcriptManager) {\n this.player.transcriptManager.toggleTranscript();\n this.updateTranscriptButton();\n }\n });\n\n this.controls.transcript = button;\n return button;\n }\n\n updateTranscriptButton() {\n if (!this.controls.transcript) return;\n\n const isVisible = this.player.transcriptManager && this.player.transcriptManager.isVisible;\n this.controls.transcript.setAttribute('aria-pressed', isVisible ? 'true' : 'false');\n }\n\n createAudioDescriptionButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-audio-description`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.audioDescription'),\n 'aria-pressed': 'false',\n 'title': i18n.t('player.audioDescription')\n }\n });\n\n button.appendChild(createIconElement('audioDescription'));\n\n button.addEventListener('click', async () => {\n await this.player.toggleAudioDescription();\n this.updateAudioDescriptionButton();\n });\n\n this.controls.audioDescription = button;\n return button;\n }\n\n updateAudioDescriptionButton() {\n if (!this.controls.audioDescription) return;\n\n const icon = this.controls.audioDescription.querySelector('.vidply-icon');\n const isEnabled = this.player.state.audioDescriptionEnabled;\n\n icon.innerHTML = isEnabled ?\n createIconElement('audioDescriptionOn').innerHTML :\n createIconElement('audioDescription').innerHTML;\n\n this.controls.audioDescription.setAttribute('aria-pressed', isEnabled ? 'true' : 'false');\n this.controls.audioDescription.setAttribute('aria-label',\n isEnabled ? i18n.t('audioDescription.disable') : i18n.t('audioDescription.enable')\n );\n }\n\n createSignLanguageButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-sign-language`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.signLanguage'),\n 'aria-pressed': 'false',\n 'title': i18n.t('player.signLanguage')\n }\n });\n\n button.appendChild(createIconElement('signLanguage'));\n\n button.addEventListener('click', () => {\n this.player.toggleSignLanguage();\n this.updateSignLanguageButton();\n });\n\n this.controls.signLanguage = button;\n return button;\n }\n\n updateSignLanguageButton() {\n if (!this.controls.signLanguage) return;\n\n const icon = this.controls.signLanguage.querySelector('.vidply-icon');\n const isEnabled = this.player.state.signLanguageEnabled;\n\n icon.innerHTML = isEnabled ?\n createIconElement('signLanguageOn').innerHTML :\n createIconElement('signLanguage').innerHTML;\n\n this.controls.signLanguage.setAttribute('aria-pressed', isEnabled ? 'true' : 'false');\n this.controls.signLanguage.setAttribute('aria-label',\n isEnabled ? i18n.t('signLanguage.hide') : i18n.t('signLanguage.show')\n );\n }\n\n createSettingsButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-settings`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.settings')\n }\n });\n\n button.appendChild(createIconElement('settings'));\n\n button.addEventListener('click', () => {\n this.player.showSettings();\n });\n\n return button;\n }\n\n createPipButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-pip`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.pip')\n }\n });\n\n button.appendChild(createIconElement('pip'));\n\n button.addEventListener('click', () => {\n this.player.togglePiP();\n });\n\n return button;\n }\n\n createFullscreenButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-fullscreen`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.fullscreen')\n }\n });\n\n button.appendChild(createIconElement('fullscreen'));\n\n button.addEventListener('click', () => {\n this.player.toggleFullscreen();\n });\n\n this.controls.fullscreen = button;\n return button;\n }\n\n attachEvents() {\n // Update controls based on player state\n this.player.on('play', () => this.updatePlayPauseButton());\n this.player.on('pause', () => this.updatePlayPauseButton());\n this.player.on('timeupdate', () => this.updateProgress());\n this.player.on('loadedmetadata', () => {\n this.updateDuration();\n this.ensureQualityButton();\n this.updateQualityIndicator();\n });\n this.player.on('volumechange', () => this.updateVolumeDisplay());\n this.player.on('progress', () => this.updateBuffered());\n this.player.on('playbackspeedchange', () => this.updateSpeedDisplay());\n this.player.on('fullscreenchange', () => this.updateFullscreenButton());\n this.player.on('captionsenabled', () => this.updateCaptionsButton());\n this.player.on('captionsdisabled', () => this.updateCaptionsButton());\n this.player.on('audiodescriptionenabled', () => this.updateAudioDescriptionButton());\n this.player.on('audiodescriptiondisabled', () => this.updateAudioDescriptionButton());\n this.player.on('signlanguageenabled', () => this.updateSignLanguageButton());\n this.player.on('signlanguagedisabled', () => this.updateSignLanguageButton());\n this.player.on('qualitychange', () => this.updateQualityIndicator());\n this.player.on('hlslevelswitched', () => this.updateQualityIndicator());\n this.player.on('hlsmanifestparsed', () => {\n this.ensureQualityButton();\n this.updateQualityIndicator();\n });\n }\n\n updatePlayPauseButton() {\n if (!this.controls.playPause) return;\n\n const icon = this.controls.playPause.querySelector('.vidply-icon');\n const isPlaying = this.player.state.playing;\n\n icon.innerHTML = isPlaying ?\n createIconElement('pause').innerHTML :\n createIconElement('play').innerHTML;\n\n this.controls.playPause.setAttribute('aria-label',\n isPlaying ? i18n.t('player.pause') : i18n.t('player.play')\n );\n }\n\n updateProgress() {\n if (!this.controls.played) return;\n\n const percent = (this.player.state.currentTime / this.player.state.duration) * 100;\n this.controls.played.style.width = `${percent}%`;\n this.controls.progress.setAttribute('aria-valuenow', String(Math.round(percent)));\n\n if (this.controls.currentTimeDisplay) {\n this.controls.currentTimeDisplay.textContent = TimeUtils.formatTime(this.player.state.currentTime);\n }\n }\n\n updateDuration() {\n if (this.controls.durationDisplay) {\n this.controls.durationDisplay.textContent = TimeUtils.formatTime(this.player.state.duration);\n }\n }\n\n updateVolumeDisplay() {\n const percent = this.player.state.volume * 100;\n\n // Update volume fill bar if it exists\n if (this.controls.volumeFill) {\n this.controls.volumeFill.style.height = `${percent}%`;\n }\n\n // Update mute button icon (should always work even if slider not shown)\n if (this.controls.mute) {\n const icon = this.controls.mute.querySelector('.vidply-icon');\n if (icon) {\n let iconName;\n\n if (this.player.state.muted || this.player.state.volume === 0) {\n iconName = 'volumeMuted';\n } else if (this.player.state.volume < 0.3) {\n iconName = 'volumeLow';\n } else if (this.player.state.volume < 0.7) {\n iconName = 'volumeMedium';\n } else {\n iconName = 'volumeHigh';\n }\n\n icon.innerHTML = createIconElement(iconName).innerHTML;\n\n this.controls.mute.setAttribute('aria-label',\n this.player.state.muted ? i18n.t('player.unmute') : i18n.t('player.mute')\n );\n }\n }\n\n // Update volume slider attribute if it exists\n if (this.controls.volumeSlider) {\n this.controls.volumeSlider.setAttribute('aria-valuenow', String(Math.round(percent)));\n }\n }\n\n updateBuffered() {\n if (!this.controls.buffered || !this.player.element.buffered || this.player.element.buffered.length === 0) return;\n\n const buffered = this.player.element.buffered.end(this.player.element.buffered.length - 1);\n const percent = (buffered / this.player.state.duration) * 100;\n this.controls.buffered.style.width = `${percent}%`;\n }\n\n updateSpeedDisplay() {\n if (this.controls.speedText) {\n this.controls.speedText.textContent = `${this.player.state.playbackSpeed}x`;\n }\n }\n\n updateFullscreenButton() {\n if (!this.controls.fullscreen) return;\n\n const icon = this.controls.fullscreen.querySelector('.vidply-icon');\n const isFullscreen = this.player.state.fullscreen;\n\n icon.innerHTML = isFullscreen ?\n createIconElement('fullscreenExit').innerHTML :\n createIconElement('fullscreen').innerHTML;\n\n this.controls.fullscreen.setAttribute('aria-label',\n isFullscreen ? i18n.t('player.exitFullscreen') : i18n.t('player.fullscreen')\n );\n }\n\n /**\n * Ensure quality button exists if qualities are available\n * This is called after renderer initialization to dynamically add the button\n */\n ensureQualityButton() {\n // Skip if quality button is disabled\n if (!this.player.options.qualityButton) return;\n \n // Skip if button already exists\n if (this.controls.quality) return;\n \n // Check if qualities are now available\n if (!this.hasQualityLevels()) return;\n \n // Create and insert the quality button before the speed button\n const qualityButton = this.createQualityButton();\n \n // Find the speed button or caption style button to insert before\n const speedButton = this.rightButtons.querySelector(`.${this.player.options.classPrefix}-speed`);\n const captionStyleButton = this.rightButtons.querySelector(`.${this.player.options.classPrefix}-caption-style`);\n const insertBefore = captionStyleButton || speedButton;\n \n if (insertBefore) {\n this.rightButtons.insertBefore(qualityButton, insertBefore);\n } else {\n // If no reference button, add it at the beginning of right buttons\n this.rightButtons.insertBefore(qualityButton, this.rightButtons.firstChild);\n }\n \n this.player.log('Quality button added dynamically', 'info');\n }\n\n updateQualityIndicator() {\n if (!this.controls.qualityText) return;\n if (!this.player.renderer || !this.player.renderer.getQualities) return;\n\n const qualities = this.player.renderer.getQualities();\n if (qualities.length === 0) {\n this.controls.qualityText.textContent = '';\n return;\n }\n\n // Get current quality\n let currentQualityText = '';\n \n // Check if it's HLS with auto mode\n if (this.player.renderer.hls && this.player.renderer.hls.currentLevel === -1) {\n currentQualityText = 'Auto';\n } else if (this.player.renderer.getCurrentQuality) {\n const currentIndex = this.player.renderer.getCurrentQuality();\n const currentQuality = qualities.find(q => q.index === currentIndex);\n if (currentQuality) {\n currentQualityText = currentQuality.height ? `${currentQuality.height}p` : '';\n }\n }\n\n this.controls.qualityText.textContent = currentQualityText;\n }\n\n setupAutoHide() {\n if (this.player.element.tagName !== 'VIDEO') return;\n\n const showControls = () => {\n this.element.classList.add(`${this.player.options.classPrefix}-controls-visible`);\n this.player.container.classList.add(`${this.player.options.classPrefix}-controls-visible`);\n this.player.state.controlsVisible = true;\n\n clearTimeout(this.hideTimeout);\n\n if (this.player.state.playing) {\n this.hideTimeout = setTimeout(() => {\n this.element.classList.remove(`${this.player.options.classPrefix}-controls-visible`);\n this.player.container.classList.remove(`${this.player.options.classPrefix}-controls-visible`);\n this.player.state.controlsVisible = false;\n }, this.player.options.hideControlsDelay);\n }\n };\n\n this.player.container.addEventListener('mousemove', showControls);\n this.player.container.addEventListener('touchstart', showControls);\n this.player.container.addEventListener('click', showControls);\n\n // Show controls on focus\n this.element.addEventListener('focusin', showControls);\n\n // Always show when paused\n this.player.on('pause', () => {\n showControls();\n clearTimeout(this.hideTimeout);\n });\n\n this.player.on('play', () => {\n showControls();\n });\n\n // Initial state\n showControls();\n }\n\n show() {\n this.element.style.display = '';\n }\n\n hide() {\n this.element.style.display = 'none';\n }\n\n destroy() {\n if (this.hideTimeout) {\n clearTimeout(this.hideTimeout);\n }\n\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n }\n}\n\n", "/**\n * Caption/Subtitle Manager\n */\n\nimport {DOMUtils} from '../utils/DOMUtils.js';\nimport {i18n} from '../i18n/i18n.js';\n\nexport class CaptionManager {\n constructor(player) {\n this.player = player;\n this.element = null;\n this.tracks = [];\n this.currentTrack = null;\n this.currentCue = null;\n\n this.init();\n }\n\n init() {\n this.createElement();\n this.loadTracks();\n this.attachEvents();\n\n if (this.player.options.captionsDefault && this.tracks.length > 0) {\n this.enable();\n }\n }\n\n createElement() {\n this.element = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-captions`,\n attributes: {\n 'aria-live': 'polite',\n 'aria-atomic': 'true',\n 'role': 'region',\n 'aria-label': i18n.t('player.captions')\n }\n });\n\n // Apply caption styles\n this.updateStyles();\n\n // Append to videoWrapper if it exists, otherwise to container\n const target = this.player.videoWrapper || this.player.container;\n target.appendChild(this.element);\n }\n\n loadTracks() {\n const textTracks = this.player.element.textTracks;\n\n for (let i = 0; i < textTracks.length; i++) {\n const track = textTracks[i];\n\n if (track.kind === 'subtitles' || track.kind === 'captions') {\n this.tracks.push({\n track: track,\n language: track.language,\n label: track.label,\n kind: track.kind,\n index: i\n });\n\n // Disable all tracks initially\n track.mode = 'hidden';\n }\n }\n }\n\n attachEvents() {\n this.player.on('timeupdate', () => {\n this.updateCaptions();\n });\n\n this.player.on('captionschange', () => {\n this.updateStyles();\n });\n }\n\n enable(trackIndex = 0) {\n if (this.tracks.length === 0) {\n return;\n }\n\n // Disable current track\n if (this.currentTrack) {\n this.currentTrack.track.mode = 'hidden';\n }\n\n // Enable selected track\n const selectedTrack = this.tracks[trackIndex];\n\n if (selectedTrack) {\n // Set to 'hidden' not 'showing' to prevent browser from displaying native captions\n // We'll handle the display ourselves\n selectedTrack.track.mode = 'hidden';\n this.currentTrack = selectedTrack;\n this.player.state.captionsEnabled = true;\n\n // Remove any existing cuechange listener\n if (this.cueChangeHandler) {\n selectedTrack.track.removeEventListener('cuechange', this.cueChangeHandler);\n }\n\n // Add event listener for cue changes\n this.cueChangeHandler = () => {\n this.updateCaptions();\n };\n selectedTrack.track.addEventListener('cuechange', this.cueChangeHandler);\n\n this.player.emit('captionsenabled', selectedTrack);\n }\n }\n\n disable() {\n if (this.currentTrack) {\n this.currentTrack.track.mode = 'hidden';\n this.currentTrack = null;\n }\n\n this.element.style.display = 'none';\n this.element.innerHTML = '';\n this.currentCue = null;\n this.player.state.captionsEnabled = false;\n this.player.emit('captionsdisabled');\n }\n\n updateCaptions() {\n if (!this.currentTrack) {\n return;\n }\n\n if (!this.currentTrack.track.activeCues) {\n return;\n }\n\n const activeCues = this.currentTrack.track.activeCues;\n\n if (activeCues.length > 0) {\n const cue = activeCues[0];\n\n // Only update if the cue has changed\n if (this.currentCue !== cue) {\n this.currentCue = cue;\n\n // Parse and display cue text\n let text = cue.text;\n\n // Handle VTT formatting\n text = this.parseVTTFormatting(text);\n\n this.element.innerHTML = DOMUtils.sanitizeHTML(text);\n\n // Make sure it's visible when there's content\n this.element.style.display = 'block';\n\n this.player.emit('captionchange', cue);\n }\n } else if (this.currentCue) {\n // Clear caption\n this.element.innerHTML = '';\n this.element.style.display = 'none';\n this.currentCue = null;\n }\n }\n\n parseVTTFormatting(text) {\n // Basic VTT tag support\n text = text.replace(/<c[^>]*>(.*?)<\\/c>/g, '<span class=\"caption-class\">$1</span>');\n text = text.replace(/<b>(.*?)<\\/b>/g, '<strong>$1</strong>');\n text = text.replace(/<i>(.*?)<\\/i>/g, '<em>$1</em>');\n text = text.replace(/<u>(.*?)<\\/u>/g, '<u>$1</u>');\n\n // Voice tags\n text = text.replace(/<v\\s+([^>]+)>(.*?)<\\/v>/g, '<span class=\"caption-voice\" data-voice=\"$1\">$2</span>');\n\n return text;\n }\n\n updateStyles() {\n if (!this.element) return;\n\n const options = this.player.options;\n\n this.element.style.fontSize = options.captionsFontSize;\n this.element.style.fontFamily = options.captionsFontFamily;\n this.element.style.color = options.captionsColor;\n this.element.style.backgroundColor = this.hexToRgba(\n options.captionsBackgroundColor,\n options.captionsOpacity\n );\n }\n\n hexToRgba(hex, alpha) {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n if (result) {\n return `rgba(${parseInt(result[1], 16)}, ${parseInt(result[2], 16)}, ${parseInt(result[3], 16)}, ${alpha})`;\n }\n return hex;\n }\n\n setCaptionStyle(property, value) {\n switch (property) {\n case 'fontSize':\n this.player.options.captionsFontSize = value;\n break;\n case 'fontFamily':\n this.player.options.captionsFontFamily = value;\n break;\n case 'color':\n this.player.options.captionsColor = value;\n break;\n case 'backgroundColor':\n this.player.options.captionsBackgroundColor = value;\n break;\n case 'opacity':\n this.player.options.captionsOpacity = value;\n break;\n }\n\n this.updateStyles();\n this.player.emit('captionschange');\n }\n\n getAvailableTracks() {\n return this.tracks.map((t, index) => ({\n index,\n language: t.language,\n label: t.label || t.language,\n kind: t.kind\n }));\n }\n\n switchTrack(trackIndex) {\n if (trackIndex >= 0 && trackIndex < this.tracks.length) {\n this.disable();\n this.enable(trackIndex);\n }\n }\n\n destroy() {\n this.disable();\n\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n }\n}\n\n", "/**\n * Keyboard Accessibility Manager\n */\n\nexport class KeyboardManager {\n constructor(player) {\n this.player = player;\n this.shortcuts = player.options.keyboardShortcuts;\n \n this.init();\n }\n\n init() {\n this.attachEvents();\n }\n\n attachEvents() {\n // Listen for keyboard events on the player container\n this.player.container.addEventListener('keydown', (e) => {\n this.handleKeydown(e);\n });\n\n // Make player container focusable\n if (!this.player.container.hasAttribute('tabindex')) {\n this.player.container.setAttribute('tabindex', '0');\n }\n }\n\n handleKeydown(e) {\n // Don't handle if target is an input element\n if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.tagName === 'SELECT') {\n return;\n }\n\n const key = e.key;\n let handled = false;\n\n // Check each shortcut category\n for (const [action, keys] of Object.entries(this.shortcuts)) {\n if (keys.includes(key)) {\n handled = this.executeAction(action, e);\n if (handled) {\n e.preventDefault();\n e.stopPropagation();\n this.announceAction(action);\n break;\n }\n }\n }\n \n // Log unhandled keys for debugging (in development)\n if (!handled && this.player.options.debug) {\n console.log('[VidPly] Unhandled key:', e.key, 'code:', e.code, 'shiftKey:', e.shiftKey);\n }\n }\n\n executeAction(action, event) {\n switch (action) {\n case 'play-pause':\n this.player.toggle();\n return true;\n\n case 'volume-up':\n this.player.setVolume(Math.min(1, this.player.state.volume + 0.1));\n return true;\n\n case 'volume-down':\n this.player.setVolume(Math.max(0, this.player.state.volume - 0.1));\n return true;\n\n case 'seek-forward':\n this.player.seekForward();\n return true;\n\n case 'seek-backward':\n this.player.seekBackward();\n return true;\n\n case 'mute':\n this.player.toggleMute();\n return true;\n\n case 'fullscreen':\n this.player.toggleFullscreen();\n return true;\n\n case 'captions':\n // If only one caption track, toggle on/off\n // If multiple tracks, open caption menu\n if (this.player.captionManager && this.player.captionManager.tracks.length > 1) {\n // Get captions button from control bar\n const captionsButton = this.player.controlBar && this.player.controlBar.controls.captions;\n if (captionsButton) {\n this.player.controlBar.showCaptionsMenu(captionsButton);\n } else {\n // Fallback to toggle if button doesn't exist\n this.player.toggleCaptions();\n }\n } else {\n this.player.toggleCaptions();\n }\n return true;\n\n case 'caption-style-menu':\n // Open caption style menu\n if (this.player.controlBar && this.player.controlBar.controls.captionStyle) {\n this.player.controlBar.showCaptionStyleMenu(this.player.controlBar.controls.captionStyle);\n return true;\n }\n return false;\n\n case 'speed-up':\n this.player.setPlaybackSpeed(\n Math.min(2, this.player.state.playbackSpeed + 0.25)\n );\n return true;\n\n case 'speed-down':\n this.player.setPlaybackSpeed(\n Math.max(0.25, this.player.state.playbackSpeed - 0.25)\n );\n return true;\n\n case 'speed-menu':\n // Open speed menu\n if (this.player.controlBar && this.player.controlBar.controls.speed) {\n this.player.controlBar.showSpeedMenu(this.player.controlBar.controls.speed);\n return true;\n }\n return false;\n\n case 'quality-menu':\n // Open quality menu\n if (this.player.controlBar && this.player.controlBar.controls.quality) {\n this.player.controlBar.showQualityMenu(this.player.controlBar.controls.quality);\n return true;\n }\n return false;\n\n case 'chapters-menu':\n // Open chapters menu\n if (this.player.controlBar && this.player.controlBar.controls.chapters) {\n this.player.controlBar.showChaptersMenu(this.player.controlBar.controls.chapters);\n return true;\n }\n return false;\n\n case 'transcript-toggle':\n // Toggle transcript\n if (this.player.transcriptManager) {\n this.player.transcriptManager.toggleTranscript();\n return true;\n }\n return false;\n\n default:\n return false;\n }\n }\n\n announceAction(action) {\n if (!this.player.options.screenReaderAnnouncements) return;\n\n let message = '';\n\n switch (action) {\n case 'play-pause':\n message = this.player.state.playing ? 'Playing' : 'Paused';\n break;\n case 'volume-up':\n message = `Volume ${Math.round(this.player.state.volume * 100)}%`;\n break;\n case 'volume-down':\n message = `Volume ${Math.round(this.player.state.volume * 100)}%`;\n break;\n case 'mute':\n message = this.player.state.muted ? 'Muted' : 'Unmuted';\n break;\n case 'fullscreen':\n message = this.player.state.fullscreen ? 'Fullscreen' : 'Exit fullscreen';\n break;\n case 'captions':\n message = this.player.state.captionsEnabled ? 'Captions on' : 'Captions off';\n break;\n case 'speed-up':\n case 'speed-down':\n message = `Speed ${this.player.state.playbackSpeed}x`;\n break;\n }\n\n if (message) {\n this.announce(message);\n }\n }\n\n announce(message, priority = 'polite') {\n // Create or get announcement element\n let announcer = document.getElementById('vidply-announcer');\n \n if (!announcer) {\n announcer = document.createElement('div');\n announcer.id = 'vidply-announcer';\n announcer.className = 'vidply-sr-only';\n announcer.setAttribute('aria-live', priority);\n announcer.setAttribute('aria-atomic', 'true');\n announcer.style.cssText = `\n position: absolute;\n left: -10000px;\n width: 1px;\n height: 1px;\n overflow: hidden;\n `;\n document.body.appendChild(announcer);\n }\n\n // Clear and set new message\n announcer.textContent = '';\n setTimeout(() => {\n announcer.textContent = message;\n }, 100);\n }\n\n updateShortcut(action, keys) {\n if (Array.isArray(keys)) {\n this.shortcuts[action] = keys;\n }\n }\n\n destroy() {\n // Event listeners are automatically removed when the container is destroyed\n }\n}\n\n", "/**\n * Transcript Manager Component\n * Manages transcript display and interaction\n */\n\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { TimeUtils } from '../utils/TimeUtils.js';\nimport { createIconElement } from '../icons/Icons.js';\nimport { i18n } from '../i18n/i18n.js';\n\nexport class TranscriptManager {\n constructor(player) {\n this.player = player;\n this.transcriptWindow = null;\n this.transcriptEntries = [];\n this.currentActiveEntry = null;\n this.isVisible = false;\n \n // Dragging state\n this.isDragging = false;\n this.dragOffsetX = 0;\n this.dragOffsetY = 0;\n \n // Store event handlers for cleanup\n this.handlers = {\n timeupdate: () => this.updateActiveEntry(),\n resize: null,\n mousemove: null,\n mouseup: null,\n touchmove: null,\n touchend: null,\n mousedown: null,\n touchstart: null,\n keydown: null\n };\n \n this.init();\n }\n\n init() {\n // Listen for time updates to highlight active transcript entry\n this.player.on('timeupdate', this.handlers.timeupdate);\n \n // Reposition transcript when entering/exiting fullscreen\n this.player.on('fullscreenchange', () => {\n if (this.isVisible) {\n // Add a small delay to ensure DOM has updated after fullscreen transition\n setTimeout(() => this.positionTranscript(), 100);\n }\n });\n }\n\n /**\n * Toggle transcript window visibility\n */\n toggleTranscript() {\n if (this.isVisible) {\n this.hideTranscript();\n } else {\n this.showTranscript();\n }\n }\n\n /**\n * Show transcript window\n */\n showTranscript() {\n if (this.transcriptWindow) {\n this.transcriptWindow.style.display = 'flex';\n this.isVisible = true;\n return;\n }\n\n // Create transcript window\n this.createTranscriptWindow();\n this.loadTranscriptData();\n \n // Show the window\n if (this.transcriptWindow) {\n this.transcriptWindow.style.display = 'flex';\n // Re-position after showing (in case window was resized while hidden)\n setTimeout(() => this.positionTranscript(), 0);\n }\n this.isVisible = true;\n }\n\n /**\n * Hide transcript window\n */\n hideTranscript() {\n if (this.transcriptWindow) {\n this.transcriptWindow.style.display = 'none';\n this.isVisible = false;\n }\n }\n\n /**\n * Create the transcript window UI\n */\n createTranscriptWindow() {\n this.transcriptWindow = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-window`,\n attributes: {\n 'role': 'dialog',\n 'aria-label': 'Video Transcript',\n 'tabindex': '-1'\n }\n });\n\n // Header (draggable)\n this.transcriptHeader = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-header`,\n attributes: {\n 'aria-label': 'Drag to reposition transcript. Use arrow keys to move, Home to reset position, Escape to close.',\n 'tabindex': '0'\n }\n });\n\n const title = DOMUtils.createElement('h3', {\n textContent: i18n.t('transcript.title')\n });\n\n const closeButton = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-transcript-close`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('transcript.close')\n }\n });\n closeButton.appendChild(createIconElement('close'));\n closeButton.addEventListener('click', () => this.hideTranscript());\n\n this.transcriptHeader.appendChild(title);\n this.transcriptHeader.appendChild(closeButton);\n\n // Content container\n this.transcriptContent = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-content`\n });\n\n this.transcriptWindow.appendChild(this.transcriptHeader);\n this.transcriptWindow.appendChild(this.transcriptContent);\n\n // Append to player container\n this.player.container.appendChild(this.transcriptWindow);\n \n // Position it next to the video wrapper\n this.positionTranscript();\n \n // Setup drag functionality\n this.setupDragAndDrop();\n \n // Re-position on window resize (debounced)\n let resizeTimeout;\n this.handlers.resize = () => {\n clearTimeout(resizeTimeout);\n resizeTimeout = setTimeout(() => this.positionTranscript(), 100);\n };\n window.addEventListener('resize', this.handlers.resize);\n }\n \n /**\n * Position transcript window next to video\n */\n positionTranscript() {\n if (!this.transcriptWindow || !this.player.videoWrapper || !this.isVisible) return;\n \n const isMobile = window.innerWidth < 640;\n const videoRect = this.player.videoWrapper.getBoundingClientRect();\n \n // Check if player is in fullscreen mode\n const isFullscreen = this.player.state.fullscreen;\n \n if (isMobile && !isFullscreen) {\n // Mobile: Position underneath the video and controls as part of the layout\n this.transcriptWindow.style.position = 'relative';\n this.transcriptWindow.style.left = '0';\n this.transcriptWindow.style.right = '0';\n this.transcriptWindow.style.bottom = 'auto';\n this.transcriptWindow.style.top = 'auto';\n this.transcriptWindow.style.width = '100%';\n this.transcriptWindow.style.maxWidth = '100%';\n this.transcriptWindow.style.maxHeight = '400px';\n this.transcriptWindow.style.height = 'auto';\n this.transcriptWindow.style.borderRadius = '0';\n this.transcriptWindow.style.transform = 'none';\n this.transcriptWindow.style.border = 'none';\n this.transcriptWindow.style.borderTop = '1px solid var(--vidply-border-light)';\n this.transcriptWindow.style.boxShadow = 'none';\n // Disable dragging on mobile\n if (this.transcriptHeader) {\n this.transcriptHeader.style.cursor = 'default';\n }\n \n // Ensure transcript is at the container level for proper stacking\n if (this.transcriptWindow.parentNode !== this.player.container) {\n this.player.container.appendChild(this.transcriptWindow);\n }\n } else if (isFullscreen) {\n // In fullscreen: position in bottom right corner inside the video\n this.transcriptWindow.style.position = 'fixed';\n this.transcriptWindow.style.left = 'auto';\n this.transcriptWindow.style.right = '20px';\n this.transcriptWindow.style.bottom = '80px'; // Above controls\n this.transcriptWindow.style.top = 'auto';\n this.transcriptWindow.style.maxHeight = 'calc(100vh - 180px)'; // Leave space for controls\n this.transcriptWindow.style.height = 'auto';\n this.transcriptWindow.style.width = '400px';\n this.transcriptWindow.style.maxWidth = '400px';\n this.transcriptWindow.style.borderRadius = '8px';\n this.transcriptWindow.style.border = '1px solid var(--vidply-border)';\n this.transcriptWindow.style.borderTop = '';\n \n // Move back to container for fullscreen\n if (this.transcriptWindow.parentNode !== this.player.container) {\n this.player.container.appendChild(this.transcriptWindow);\n }\n } else {\n // Desktop mode: position next to video\n this.transcriptWindow.style.position = 'absolute';\n this.transcriptWindow.style.left = `${videoRect.width + 8}px`;\n this.transcriptWindow.style.right = 'auto';\n this.transcriptWindow.style.bottom = 'auto';\n this.transcriptWindow.style.top = '0';\n this.transcriptWindow.style.height = `${videoRect.height}px`;\n this.transcriptWindow.style.maxHeight = 'none';\n this.transcriptWindow.style.width = '400px';\n this.transcriptWindow.style.maxWidth = '400px';\n this.transcriptWindow.style.borderRadius = '8px';\n this.transcriptWindow.style.border = '1px solid var(--vidply-border)';\n this.transcriptWindow.style.borderTop = '';\n // Enable dragging on desktop\n if (this.transcriptHeader) {\n this.transcriptHeader.style.cursor = 'move';\n }\n \n // Move back to container for desktop\n if (this.transcriptWindow.parentNode !== this.player.container) {\n this.player.container.appendChild(this.transcriptWindow);\n }\n }\n }\n\n /**\n * Load transcript data from caption/subtitle tracks\n */\n loadTranscriptData() {\n this.transcriptEntries = [];\n this.transcriptContent.innerHTML = '';\n\n // Get caption/subtitle tracks\n const textTracks = Array.from(this.player.element.textTracks);\n const transcriptTrack = textTracks.find(\n track => track.kind === 'captions' || track.kind === 'subtitles'\n );\n\n if (!transcriptTrack) {\n this.showNoTranscriptMessage();\n return;\n }\n\n // Enable track to load cues\n if (transcriptTrack.mode === 'disabled') {\n transcriptTrack.mode = 'hidden';\n }\n\n if (!transcriptTrack.cues || transcriptTrack.cues.length === 0) {\n // Wait for cues to load\n const loadingMessage = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-loading`,\n textContent: i18n.t('transcript.loading')\n });\n this.transcriptContent.appendChild(loadingMessage);\n\n const onLoad = () => {\n this.loadTranscriptData();\n };\n\n transcriptTrack.addEventListener('load', onLoad, { once: true });\n\n // Fallback timeout\n setTimeout(() => {\n if (transcriptTrack.cues && transcriptTrack.cues.length > 0) {\n this.loadTranscriptData();\n }\n }, 500);\n \n return;\n }\n\n // Build transcript from cues\n const cues = Array.from(transcriptTrack.cues);\n cues.forEach((cue, index) => {\n const entry = this.createTranscriptEntry(cue, index);\n this.transcriptEntries.push({\n element: entry,\n cue: cue,\n startTime: cue.startTime,\n endTime: cue.endTime\n });\n this.transcriptContent.appendChild(entry);\n });\n }\n\n /**\n * Create a single transcript entry element\n */\n createTranscriptEntry(cue, index) {\n const entry = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-entry`,\n attributes: {\n 'data-start': String(cue.startTime),\n 'data-end': String(cue.endTime),\n 'role': 'button',\n 'tabindex': '0'\n }\n });\n\n const timestamp = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-transcript-time`,\n textContent: TimeUtils.formatTime(cue.startTime)\n });\n\n const text = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-transcript-text`,\n textContent: this.stripVTTFormatting(cue.text)\n });\n\n entry.appendChild(timestamp);\n entry.appendChild(text);\n\n // Click to seek\n const seekToTime = () => {\n this.player.seek(cue.startTime);\n if (this.player.state.paused) {\n this.player.play();\n }\n };\n\n entry.addEventListener('click', seekToTime);\n entry.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n seekToTime();\n }\n });\n\n return entry;\n }\n\n /**\n * Strip VTT formatting tags from text\n */\n stripVTTFormatting(text) {\n // Remove VTT tags like <v Speaker>, <c>, etc.\n return text\n .replace(/<[^>]+>/g, '')\n .replace(/\\n/g, ' ')\n .trim();\n }\n\n /**\n * Show message when no transcript is available\n */\n showNoTranscriptMessage() {\n const message = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-empty`,\n textContent: i18n.t('transcript.noTranscript')\n });\n this.transcriptContent.appendChild(message);\n }\n\n /**\n * Update active transcript entry based on current time\n */\n updateActiveEntry() {\n if (!this.isVisible || this.transcriptEntries.length === 0) return;\n\n const currentTime = this.player.state.currentTime;\n \n // Find the entry that matches current time\n const activeEntry = this.transcriptEntries.find(\n entry => currentTime >= entry.startTime && currentTime < entry.endTime\n );\n\n if (activeEntry && activeEntry !== this.currentActiveEntry) {\n // Remove previous active class\n if (this.currentActiveEntry) {\n this.currentActiveEntry.element.classList.remove(\n `${this.player.options.classPrefix}-transcript-entry-active`\n );\n }\n\n // Add active class to current entry\n activeEntry.element.classList.add(\n `${this.player.options.classPrefix}-transcript-entry-active`\n );\n \n // Scroll to active entry\n this.scrollToEntry(activeEntry.element);\n \n this.currentActiveEntry = activeEntry;\n } else if (!activeEntry && this.currentActiveEntry) {\n // No active entry, remove active class\n this.currentActiveEntry.element.classList.remove(\n `${this.player.options.classPrefix}-transcript-entry-active`\n );\n this.currentActiveEntry = null;\n }\n }\n\n /**\n * Scroll transcript window to show active entry\n */\n scrollToEntry(entryElement) {\n if (!this.transcriptContent) return;\n\n const contentRect = this.transcriptContent.getBoundingClientRect();\n const entryRect = entryElement.getBoundingClientRect();\n\n // Check if entry is out of view\n if (entryRect.top < contentRect.top || entryRect.bottom > contentRect.bottom) {\n // Scroll to center the entry\n const scrollTop = entryElement.offsetTop - (this.transcriptContent.clientHeight / 2) + (entryElement.clientHeight / 2);\n this.transcriptContent.scrollTo({\n top: scrollTop,\n behavior: 'smooth'\n });\n }\n }\n\n /**\n * Setup drag and drop functionality\n */\n setupDragAndDrop() {\n if (!this.transcriptHeader || !this.transcriptWindow) return;\n\n // Create and store handler functions\n this.handlers.mousedown = (e) => {\n // Don't drag if clicking on close button\n if (e.target.closest(`.${this.player.options.classPrefix}-transcript-close`)) {\n return;\n }\n \n this.startDragging(e.clientX, e.clientY);\n e.preventDefault();\n };\n\n this.handlers.mousemove = (e) => {\n if (this.isDragging) {\n this.drag(e.clientX, e.clientY);\n }\n };\n\n this.handlers.mouseup = () => {\n if (this.isDragging) {\n this.stopDragging();\n }\n };\n\n this.handlers.touchstart = (e) => {\n if (e.target.closest(`.${this.player.options.classPrefix}-transcript-close`)) {\n return;\n }\n \n const isMobile = window.innerWidth < 640;\n const isFullscreen = this.player.state.fullscreen;\n const touch = e.touches[0];\n \n if (isMobile && !isFullscreen) {\n // Mobile (not fullscreen): No dragging/swiping, transcript is part of layout\n return;\n } else {\n // Desktop or fullscreen: Normal dragging\n this.startDragging(touch.clientX, touch.clientY);\n }\n };\n\n this.handlers.touchmove = (e) => {\n const isMobile = window.innerWidth < 640;\n const isFullscreen = this.player.state.fullscreen;\n \n if (isMobile && !isFullscreen) {\n // Mobile (not fullscreen): No dragging/swiping\n return;\n } else if (this.isDragging) {\n // Desktop or fullscreen: Normal drag\n const touch = e.touches[0];\n this.drag(touch.clientX, touch.clientY);\n e.preventDefault();\n }\n };\n\n this.handlers.touchend = () => {\n if (this.isDragging) {\n // Stop dragging\n this.stopDragging();\n }\n };\n\n this.handlers.keydown = (e) => {\n // Check if this is a navigation key\n if (!['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'Escape'].includes(e.key)) {\n return;\n }\n \n // Prevent default behavior and stop event from bubbling to transcript entries\n e.preventDefault();\n e.stopPropagation();\n \n // Handle special keys first\n if (e.key === 'Home') {\n this.resetPosition();\n return;\n }\n \n if (e.key === 'Escape') {\n this.hideTranscript();\n return;\n }\n \n const step = e.shiftKey ? 50 : 10; // Larger steps with Shift key\n \n // Get current position\n let currentLeft = parseFloat(this.transcriptWindow.style.left) || 0;\n let currentTop = parseFloat(this.transcriptWindow.style.top) || 0;\n \n // If window is still centered with transform, convert to absolute position first\n const computedStyle = window.getComputedStyle(this.transcriptWindow);\n if (computedStyle.transform !== 'none') {\n const rect = this.transcriptWindow.getBoundingClientRect();\n currentLeft = rect.left;\n currentTop = rect.top;\n this.transcriptWindow.style.transform = 'none';\n this.transcriptWindow.style.left = `${currentLeft}px`;\n this.transcriptWindow.style.top = `${currentTop}px`;\n }\n \n // Calculate new position based on arrow key\n let newX = currentLeft;\n let newY = currentTop;\n\n switch(e.key) {\n case 'ArrowLeft':\n newX -= step;\n break;\n case 'ArrowRight':\n newX += step;\n break;\n case 'ArrowUp':\n newY -= step;\n break;\n case 'ArrowDown':\n newY += step;\n break;\n }\n\n // Set new position directly\n this.transcriptWindow.style.left = `${newX}px`;\n this.transcriptWindow.style.top = `${newY}px`;\n };\n\n // Add event listeners using stored handlers\n this.transcriptHeader.addEventListener('mousedown', this.handlers.mousedown);\n document.addEventListener('mousemove', this.handlers.mousemove);\n document.addEventListener('mouseup', this.handlers.mouseup);\n \n this.transcriptHeader.addEventListener('touchstart', this.handlers.touchstart);\n document.addEventListener('touchmove', this.handlers.touchmove);\n document.addEventListener('touchend', this.handlers.touchend);\n \n this.transcriptHeader.addEventListener('keydown', this.handlers.keydown);\n }\n\n /**\n * Start dragging\n */\n startDragging(clientX, clientY) {\n // Get current rendered position (this is where it actually appears on screen)\n const rect = this.transcriptWindow.getBoundingClientRect();\n \n // Get the parent container position (player container)\n const containerRect = this.player.container.getBoundingClientRect();\n \n // Calculate position RELATIVE to container (not viewport)\n const relativeLeft = rect.left - containerRect.left;\n const relativeTop = rect.top - containerRect.top;\n \n // If window is centered with transform, convert to absolute position\n const computedStyle = window.getComputedStyle(this.transcriptWindow);\n if (computedStyle.transform !== 'none') {\n // Remove transform and set position relative to container\n this.transcriptWindow.style.transform = 'none';\n this.transcriptWindow.style.left = `${relativeLeft}px`;\n this.transcriptWindow.style.top = `${relativeTop}px`;\n }\n \n // Calculate offset based on viewport coordinates (where user clicked)\n this.dragOffsetX = clientX - rect.left;\n this.dragOffsetY = clientY - rect.top;\n \n this.isDragging = true;\n this.transcriptWindow.classList.add(`${this.player.options.classPrefix}-transcript-dragging`);\n document.body.style.cursor = 'grabbing';\n document.body.style.userSelect = 'none';\n }\n\n /**\n * Perform drag\n */\n drag(clientX, clientY) {\n if (!this.isDragging) return;\n\n // Calculate new viewport position based on mouse position minus the offset\n const newViewportX = clientX - this.dragOffsetX;\n const newViewportY = clientY - this.dragOffsetY;\n \n // Convert to position relative to container\n const containerRect = this.player.container.getBoundingClientRect();\n const newX = newViewportX - containerRect.left;\n const newY = newViewportY - containerRect.top;\n \n // During drag, set position relative to container\n this.transcriptWindow.style.left = `${newX}px`;\n this.transcriptWindow.style.top = `${newY}px`;\n }\n\n /**\n * Stop dragging\n */\n stopDragging() {\n this.isDragging = false;\n this.transcriptWindow.classList.remove(`${this.player.options.classPrefix}-transcript-dragging`);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n }\n\n /**\n * Set window position with boundary constraints\n */\n setPosition(x, y) {\n const rect = this.transcriptWindow.getBoundingClientRect();\n \n // Use document dimensions for fixed positioning\n const viewportWidth = document.documentElement.clientWidth;\n const viewportHeight = document.documentElement.clientHeight;\n \n // Very relaxed boundaries - allow window to go mostly off-screen\n // Just keep a small part visible so user can always drag it back\n const minVisible = 100; // Keep at least 100px visible\n const minX = -(rect.width - minVisible); // Can go way off-screen to the left\n const minY = -(rect.height - minVisible); // Can go way off-screen to the top\n const maxX = viewportWidth - minVisible; // Can go way off-screen to the right\n const maxY = viewportHeight - minVisible; // Can go way off-screen to the bottom\n \n // Clamp position to boundaries (very loose)\n x = Math.max(minX, Math.min(x, maxX));\n y = Math.max(minY, Math.min(y, maxY));\n \n this.transcriptWindow.style.left = `${x}px`;\n this.transcriptWindow.style.top = `${y}px`;\n this.transcriptWindow.style.transform = 'none';\n }\n\n /**\n * Reset position to center\n */\n resetPosition() {\n this.transcriptWindow.style.left = '50%';\n this.transcriptWindow.style.top = '50%';\n this.transcriptWindow.style.transform = 'translate(-50%, -50%)';\n }\n\n /**\n * Cleanup\n */\n destroy() {\n // Remove timeupdate listener from player\n if (this.handlers.timeupdate) {\n this.player.off('timeupdate', this.handlers.timeupdate);\n }\n\n // Remove drag event listeners\n if (this.transcriptHeader) {\n if (this.handlers.mousedown) {\n this.transcriptHeader.removeEventListener('mousedown', this.handlers.mousedown);\n }\n if (this.handlers.touchstart) {\n this.transcriptHeader.removeEventListener('touchstart', this.handlers.touchstart);\n }\n if (this.handlers.keydown) {\n this.transcriptHeader.removeEventListener('keydown', this.handlers.keydown);\n }\n }\n\n // Remove document-level listeners\n if (this.handlers.mousemove) {\n document.removeEventListener('mousemove', this.handlers.mousemove);\n }\n if (this.handlers.mouseup) {\n document.removeEventListener('mouseup', this.handlers.mouseup);\n }\n if (this.handlers.touchmove) {\n document.removeEventListener('touchmove', this.handlers.touchmove);\n }\n if (this.handlers.touchend) {\n document.removeEventListener('touchend', this.handlers.touchend);\n }\n \n // Remove window-level listeners\n if (this.handlers.resize) {\n window.removeEventListener('resize', this.handlers.resize);\n }\n\n // Clear handlers\n this.handlers = null;\n\n // Remove DOM element\n if (this.transcriptWindow && this.transcriptWindow.parentNode) {\n this.transcriptWindow.parentNode.removeChild(this.transcriptWindow);\n }\n \n this.transcriptWindow = null;\n this.transcriptHeader = null;\n this.transcriptContent = null;\n this.transcriptEntries = [];\n }\n}\n", "/**\n * VidPly - Universal Video Player\n * Main Player Class\n */\n\nimport {EventEmitter} from '../utils/EventEmitter.js';\nimport {DOMUtils} from '../utils/DOMUtils.js';\nimport {ControlBar} from '../controls/ControlBar.js';\nimport {CaptionManager} from '../controls/CaptionManager.js';\nimport {KeyboardManager} from '../controls/KeyboardManager.js';\nimport {TranscriptManager} from '../controls/TranscriptManager.js';\nimport {HTML5Renderer} from '../renderers/HTML5Renderer.js';\nimport {YouTubeRenderer} from '../renderers/YouTubeRenderer.js';\nimport {VimeoRenderer} from '../renderers/VimeoRenderer.js';\nimport {HLSRenderer} from '../renderers/HLSRenderer.js';\nimport {createPlayOverlay} from '../icons/Icons.js';\nimport {i18n} from '../i18n/i18n.js';\n\nexport class Player extends EventEmitter {\n constructor(element, options = {}) {\n super();\n\n this.element = typeof element === 'string' ? document.querySelector(element) : element;\n if (!this.element) {\n throw new Error('VidPly: Element not found');\n }\n\n // Auto-create media element if a non-media element is provided\n if (this.element.tagName !== 'VIDEO' && this.element.tagName !== 'AUDIO') {\n const mediaType = options.mediaType || 'video';\n const mediaElement = document.createElement(mediaType);\n\n // Copy attributes from the div to the media element\n Array.from(this.element.attributes).forEach(attr => {\n if (attr.name !== 'id' && attr.name !== 'class' && !attr.name.startsWith('data-')) {\n mediaElement.setAttribute(attr.name, attr.value);\n }\n });\n\n // Copy any track elements from the div\n const tracks = this.element.querySelectorAll('track');\n tracks.forEach(track => {\n mediaElement.appendChild(track.cloneNode(true));\n });\n\n // Clear the div and insert the media element\n this.element.innerHTML = '';\n this.element.appendChild(mediaElement);\n\n // Update element reference to the actual media element\n this.element = mediaElement;\n }\n\n // Default options\n this.options = {\n // Display\n width: null,\n height: null,\n poster: null,\n responsive: true,\n fillContainer: false,\n\n // Playback\n autoplay: false,\n loop: false,\n muted: false,\n volume: 0.8,\n playbackSpeed: 1.0,\n preload: 'metadata',\n startTime: 0,\n\n // Controls\n controls: true,\n hideControlsDelay: 3000,\n playPauseButton: true,\n progressBar: true,\n currentTime: true,\n duration: true,\n volumeControl: true,\n muteButton: true,\n chaptersButton: true,\n qualityButton: true,\n captionStyleButton: true,\n speedButton: true,\n captionsButton: true,\n transcriptButton: true,\n fullscreenButton: true,\n pipButton: true,\n\n // Seeking\n seekInterval: 10,\n seekIntervalLarge: 30,\n\n // Captions\n captions: true,\n captionsDefault: false,\n captionsFontSize: '100%',\n captionsFontFamily: 'sans-serif',\n captionsColor: '#FFFFFF',\n captionsBackgroundColor: '#000000',\n captionsOpacity: 0.8,\n\n // Audio Description\n audioDescription: true,\n audioDescriptionSrc: null, // URL to audio-described version\n audioDescriptionButton: true,\n\n // Sign Language\n signLanguage: true,\n signLanguageSrc: null, // URL to sign language video\n signLanguageButton: true,\n signLanguagePosition: 'bottom-right', // Position: 'bottom-right', 'bottom-left', 'top-right', 'top-left'\n\n // Transcripts\n transcript: false,\n transcriptPosition: 'external',\n transcriptContainer: null,\n\n // Keyboard\n keyboard: true,\n keyboardShortcuts: {\n 'play-pause': [' ', 'p', 'k'],\n 'volume-up': ['ArrowUp'],\n 'volume-down': ['ArrowDown'],\n 'seek-forward': ['ArrowRight'],\n 'seek-backward': ['ArrowLeft'],\n 'mute': ['m'],\n 'fullscreen': ['f'],\n 'captions': ['c'],\n 'caption-style-menu': ['a'],\n 'speed-up': ['>'],\n 'speed-down': ['<'],\n 'speed-menu': ['s'],\n 'quality-menu': ['q'],\n 'chapters-menu': ['j'],\n 'transcript-toggle': ['t']\n },\n\n // Accessibility\n ariaLabels: {},\n screenReaderAnnouncements: true,\n highContrast: false,\n focusHighlight: true,\n\n // Languages\n language: 'en',\n languages: ['en'],\n\n // Advanced\n debug: false,\n classPrefix: 'vidply',\n iconType: 'svg',\n pauseOthersOnPlay: true,\n\n // Callbacks\n onReady: null,\n onPlay: null,\n onPause: null,\n onEnded: null,\n onTimeUpdate: null,\n onVolumeChange: null,\n onError: null,\n\n ...options\n };\n\n // State\n this.state = {\n ready: false,\n playing: false,\n paused: true,\n ended: false,\n buffering: false,\n seeking: false,\n muted: this.options.muted,\n volume: this.options.volume,\n currentTime: 0,\n duration: 0,\n playbackSpeed: this.options.playbackSpeed,\n fullscreen: false,\n pip: false,\n captionsEnabled: this.options.captionsDefault,\n currentCaption: null,\n controlsVisible: true,\n audioDescriptionEnabled: false,\n signLanguageEnabled: false\n };\n\n // Store original source for toggling\n this.originalSrc = null;\n this.audioDescriptionSrc = this.options.audioDescriptionSrc;\n this.signLanguageSrc = this.options.signLanguageSrc;\n this.signLanguageVideo = null;\n\n // Components\n this.container = null;\n this.renderer = null;\n this.controlBar = null;\n this.captionManager = null;\n this.keyboardManager = null;\n this.settingsDialog = null;\n\n // Initialize\n this.init();\n }\n\n async init() {\n try {\n this.log('Initializing VidPly player');\n\n // Auto-detect language from HTML lang attribute if not explicitly set\n if (!this.options.language || this.options.language === 'en') {\n const htmlLang = this.detectHtmlLanguage();\n if (htmlLang) {\n this.options.language = htmlLang;\n this.log(`Auto-detected language from HTML: ${htmlLang}`);\n }\n }\n\n // Set language\n i18n.setLanguage(this.options.language);\n\n // Create container\n this.createContainer();\n\n // Detect and initialize renderer (only if source exists)\n const src = this.element.src || this.element.querySelector('source')?.src;\n if (src) {\n await this.initializeRenderer();\n } else {\n this.log('No initial source - waiting for playlist or manual load');\n }\n\n // Create controls\n if (this.options.controls) {\n this.controlBar = new ControlBar(this);\n this.videoWrapper.appendChild(this.controlBar.element);\n }\n\n // Initialize captions\n if (this.options.captions) {\n this.captionManager = new CaptionManager(this);\n }\n\n // Initialize transcript\n if (this.options.transcript || this.options.transcriptButton) {\n this.transcriptManager = new TranscriptManager(this);\n }\n\n // Initialize keyboard controls\n if (this.options.keyboard) {\n this.keyboardManager = new KeyboardManager(this);\n }\n\n // Setup responsive handlers\n this.setupResponsiveHandlers();\n\n // Set initial state\n if (this.options.startTime > 0) {\n this.seek(this.options.startTime);\n }\n\n if (this.options.muted) {\n this.mute();\n }\n\n if (this.options.volume !== 0.8) {\n this.setVolume(this.options.volume);\n }\n\n // Mark as ready\n this.state.ready = true;\n this.emit('ready');\n\n if (this.options.onReady) {\n this.options.onReady.call(this);\n }\n\n // Autoplay if enabled\n if (this.options.autoplay) {\n this.play();\n }\n\n this.log('Player initialized successfully');\n } catch (error) {\n this.handleError(error);\n }\n }\n\n /**\n * Detect language from HTML lang attribute\n * @returns {string|null} Language code if available in translations, null otherwise\n */\n detectHtmlLanguage() {\n // Try to get lang from html element\n const htmlLang = document.documentElement.lang || document.documentElement.getAttribute('lang');\n\n if (!htmlLang) {\n return null;\n }\n\n // Normalize the language code (e.g., \"en-US\" -> \"en\", \"de-DE\" -> \"de\")\n const normalizedLang = htmlLang.toLowerCase().split('-')[0];\n\n // Check if this language is available in our translations\n const availableLanguages = ['en', 'de', 'es', 'fr', 'ja'];\n\n if (availableLanguages.includes(normalizedLang)) {\n return normalizedLang;\n }\n\n // Language not available, will fallback to English\n this.log(`Language \"${htmlLang}\" not available, using English as fallback`);\n return 'en';\n }\n\n createContainer() {\n // Create main container\n this.container = DOMUtils.createElement('div', {\n className: `${this.options.classPrefix}-player`,\n attributes: {\n 'role': 'region',\n 'aria-label': i18n.t('player.label'),\n 'tabindex': '0'\n }\n });\n\n // Add media type class\n const mediaType = this.element.tagName.toLowerCase();\n this.container.classList.add(`${this.options.classPrefix}-${mediaType}`);\n\n // Add responsive class\n if (this.options.responsive) {\n this.container.classList.add(`${this.options.classPrefix}-responsive`);\n }\n\n // Create video wrapper (for proper positioning of controls)\n this.videoWrapper = DOMUtils.createElement('div', {\n className: `${this.options.classPrefix}-video-wrapper`\n });\n\n // Wrap original element\n this.element.parentNode.insertBefore(this.container, this.element);\n this.container.appendChild(this.videoWrapper);\n this.videoWrapper.appendChild(this.element);\n\n // Hide native controls and set dimensions\n this.element.controls = false;\n this.element.removeAttribute('controls');\n this.element.setAttribute('tabindex', '-1'); // Remove from tab order\n this.element.style.width = '100%';\n this.element.style.height = '100%';\n\n // Set dimensions\n if (this.options.width) {\n this.container.style.width = typeof this.options.width === 'number'\n ? `${this.options.width}px`\n : this.options.width;\n }\n\n if (this.options.height) {\n this.container.style.height = typeof this.options.height === 'number'\n ? `${this.options.height}px`\n : this.options.height;\n }\n\n // Set poster\n if (this.options.poster && this.element.tagName === 'VIDEO') {\n this.element.poster = this.options.poster;\n }\n\n // Create centered play button overlay (only for video)\n if (this.element.tagName === 'VIDEO') {\n this.createPlayButtonOverlay();\n }\n\n // Make video/audio element clickable to toggle play/pause\n this.element.style.cursor = 'pointer';\n this.element.addEventListener('click', (e) => {\n // Prevent if clicking on native controls (shouldn't happen but just in case)\n if (e.target === this.element) {\n this.toggle();\n }\n });\n }\n\n createPlayButtonOverlay() {\n // Create complete SVG play button from Icons.js\n this.playButtonOverlay = createPlayOverlay();\n\n // Add click handler\n this.playButtonOverlay.addEventListener('click', () => {\n this.toggle();\n });\n\n // Add to video wrapper\n this.videoWrapper.appendChild(this.playButtonOverlay);\n\n // Show/hide based on play state\n this.on('play', () => {\n this.playButtonOverlay.style.opacity = '0';\n this.playButtonOverlay.style.pointerEvents = 'none';\n });\n\n this.on('pause', () => {\n this.playButtonOverlay.style.opacity = '1';\n this.playButtonOverlay.style.pointerEvents = 'auto';\n });\n\n this.on('ended', () => {\n this.playButtonOverlay.style.opacity = '1';\n this.playButtonOverlay.style.pointerEvents = 'auto';\n });\n }\n\n async initializeRenderer() {\n const src = this.element.src || this.element.querySelector('source')?.src;\n\n if (!src) {\n throw new Error('No media source found');\n }\n\n // Store original source for audio description toggling\n if (!this.originalSrc) {\n this.originalSrc = src;\n }\n\n // Detect media type\n let renderer;\n\n if (src.includes('youtube.com') || src.includes('youtu.be')) {\n renderer = YouTubeRenderer;\n } else if (src.includes('vimeo.com')) {\n renderer = VimeoRenderer;\n } else if (src.includes('.m3u8')) {\n renderer = HLSRenderer;\n } else {\n renderer = HTML5Renderer;\n }\n\n this.log(`Using ${renderer.name} renderer`);\n this.renderer = new renderer(this);\n await this.renderer.init();\n }\n\n /**\n * Load new media source (for playlists)\n * @param {Object} config - Media configuration\n * @param {string} config.src - Media source URL\n * @param {string} config.type - Media MIME type\n * @param {string} [config.poster] - Poster image URL\n * @param {Array} [config.tracks] - Text tracks (captions, chapters, etc.)\n */\n async load(config) {\n try {\n this.log('Loading new media:', config.src);\n\n // Pause current playback\n if (this.renderer) {\n this.pause();\n }\n\n // Clear existing text tracks\n const existingTracks = this.element.querySelectorAll('track');\n existingTracks.forEach(track => track.remove());\n\n // Update media element\n this.element.src = config.src;\n\n if (config.type) {\n this.element.type = config.type;\n }\n\n if (config.poster && this.element.tagName === 'VIDEO') {\n this.element.poster = config.poster;\n }\n\n // Add new text tracks\n if (config.tracks && config.tracks.length > 0) {\n config.tracks.forEach(trackConfig => {\n const track = document.createElement('track');\n track.src = trackConfig.src;\n track.kind = trackConfig.kind || 'captions';\n track.srclang = trackConfig.srclang || 'en';\n track.label = trackConfig.label || trackConfig.srclang;\n\n if (trackConfig.default) {\n track.default = true;\n }\n\n this.element.appendChild(track);\n });\n }\n\n // Check if we need to change renderer type\n const shouldChangeRenderer = this.shouldChangeRenderer(config.src);\n\n // Destroy old renderer if changing types\n if (shouldChangeRenderer && this.renderer) {\n this.renderer.destroy();\n this.renderer = null;\n }\n\n // Initialize or reinitialize renderer\n if (!this.renderer || shouldChangeRenderer) {\n await this.initializeRenderer();\n } else {\n // Just reload the current renderer with the updated element\n this.renderer.media = this.element; // Update media reference\n this.element.load();\n }\n\n // Reinitialize caption manager to pick up new tracks\n if (this.captionManager) {\n this.captionManager.destroy();\n this.captionManager = new CaptionManager(this);\n }\n\n this.emit('sourcechange', config);\n this.log('Media loaded successfully');\n\n } catch (error) {\n this.handleError(error);\n }\n }\n\n /**\n * Check if we need to change renderer type\n * @param {string} src - New source URL\n * @returns {boolean}\n */\n shouldChangeRenderer(src) {\n if (!this.renderer) return true;\n\n const isYouTube = src.includes('youtube.com') || src.includes('youtu.be');\n const isVimeo = src.includes('vimeo.com');\n const isHLS = src.includes('.m3u8');\n\n const currentRendererName = this.renderer.constructor.name;\n\n if (isYouTube && currentRendererName !== 'YouTubeRenderer') return true;\n if (isVimeo && currentRendererName !== 'VimeoRenderer') return true;\n if (isHLS && currentRendererName !== 'HLSRenderer') return true;\n if (!isYouTube && !isVimeo && !isHLS && currentRendererName !== 'HTML5Renderer') return true;\n\n return false;\n }\n\n // Playback controls\n play() {\n if (this.renderer) {\n this.renderer.play();\n }\n }\n\n pause() {\n if (this.renderer) {\n this.renderer.pause();\n }\n }\n\n stop() {\n this.pause();\n this.seek(0);\n }\n\n toggle() {\n if (this.state.playing) {\n this.pause();\n } else {\n this.play();\n }\n }\n\n seek(time) {\n if (this.renderer) {\n this.renderer.seek(time);\n }\n }\n\n seekForward(interval = this.options.seekInterval) {\n this.seek(Math.min(this.state.currentTime + interval, this.state.duration));\n }\n\n seekBackward(interval = this.options.seekInterval) {\n this.seek(Math.max(this.state.currentTime - interval, 0));\n }\n\n // Volume controls\n setVolume(volume) {\n const newVolume = Math.max(0, Math.min(1, volume));\n if (this.renderer) {\n this.renderer.setVolume(newVolume);\n }\n this.state.volume = newVolume;\n\n if (newVolume > 0 && this.state.muted) {\n this.state.muted = false;\n }\n }\n\n getVolume() {\n return this.state.volume;\n }\n\n mute() {\n if (this.renderer) {\n this.renderer.setMuted(true);\n }\n this.state.muted = true;\n this.emit('volumechange');\n }\n\n unmute() {\n if (this.renderer) {\n this.renderer.setMuted(false);\n }\n this.state.muted = false;\n this.emit('volumechange');\n }\n\n toggleMute() {\n if (this.state.muted) {\n this.unmute();\n } else {\n this.mute();\n }\n }\n\n // Playback speed\n setPlaybackSpeed(speed) {\n const newSpeed = Math.max(0.25, Math.min(2, speed));\n if (this.renderer) {\n this.renderer.setPlaybackSpeed(newSpeed);\n }\n this.state.playbackSpeed = newSpeed;\n this.emit('playbackspeedchange', newSpeed);\n }\n\n getPlaybackSpeed() {\n return this.state.playbackSpeed;\n }\n\n // Fullscreen\n enterFullscreen() {\n const elem = this.container;\n\n if (elem.requestFullscreen) {\n elem.requestFullscreen();\n } else if (elem.webkitRequestFullscreen) {\n elem.webkitRequestFullscreen();\n } else if (elem.mozRequestFullScreen) {\n elem.mozRequestFullScreen();\n } else if (elem.msRequestFullscreen) {\n elem.msRequestFullscreen();\n }\n\n this.state.fullscreen = true;\n this.container.classList.add(`${this.options.classPrefix}-fullscreen`);\n this.emit('fullscreenchange', true);\n }\n\n exitFullscreen() {\n if (document.exitFullscreen) {\n document.exitFullscreen();\n } else if (document.webkitExitFullscreen) {\n document.webkitExitFullscreen();\n } else if (document.mozCancelFullScreen) {\n document.mozCancelFullScreen();\n } else if (document.msExitFullscreen) {\n document.msExitFullscreen();\n }\n\n this.state.fullscreen = false;\n this.container.classList.remove(`${this.options.classPrefix}-fullscreen`);\n this.emit('fullscreenchange', false);\n }\n\n toggleFullscreen() {\n if (this.state.fullscreen) {\n this.exitFullscreen();\n } else {\n this.enterFullscreen();\n }\n }\n\n // Picture-in-Picture\n enterPiP() {\n if (this.element.requestPictureInPicture) {\n this.element.requestPictureInPicture();\n this.state.pip = true;\n this.emit('pipchange', true);\n }\n }\n\n exitPiP() {\n if (document.pictureInPictureElement) {\n document.exitPictureInPicture();\n this.state.pip = false;\n this.emit('pipchange', false);\n }\n }\n\n togglePiP() {\n if (this.state.pip) {\n this.exitPiP();\n } else {\n this.enterPiP();\n }\n }\n\n // Captions\n enableCaptions() {\n if (this.captionManager) {\n this.captionManager.enable();\n this.state.captionsEnabled = true;\n }\n }\n\n disableCaptions() {\n if (this.captionManager) {\n this.captionManager.disable();\n this.state.captionsEnabled = false;\n }\n }\n\n toggleCaptions() {\n if (this.state.captionsEnabled) {\n this.disableCaptions();\n } else {\n this.enableCaptions();\n }\n }\n\n // Audio Description\n async enableAudioDescription() {\n if (!this.audioDescriptionSrc) {\n console.warn('VidPly: No audio description source provided');\n return;\n }\n\n // Store current playback state\n const currentTime = this.state.currentTime;\n const wasPlaying = this.state.playing;\n\n // Switch to audio-described version\n this.element.src = this.audioDescriptionSrc;\n\n // Wait for new source to load\n await new Promise((resolve) => {\n const onLoadedMetadata = () => {\n this.element.removeEventListener('loadedmetadata', onLoadedMetadata);\n resolve();\n };\n this.element.addEventListener('loadedmetadata', onLoadedMetadata);\n });\n\n // Restore playback position\n this.seek(currentTime);\n\n if (wasPlaying) {\n this.play();\n }\n\n this.state.audioDescriptionEnabled = true;\n this.emit('audiodescriptionenabled');\n }\n\n async disableAudioDescription() {\n if (!this.originalSrc) {\n return;\n }\n\n // Store current playback state\n const currentTime = this.state.currentTime;\n const wasPlaying = this.state.playing;\n\n // Switch back to original version\n this.element.src = this.originalSrc;\n\n // Wait for new source to load\n await new Promise((resolve) => {\n const onLoadedMetadata = () => {\n this.element.removeEventListener('loadedmetadata', onLoadedMetadata);\n resolve();\n };\n this.element.addEventListener('loadedmetadata', onLoadedMetadata);\n });\n\n // Restore playback position\n this.seek(currentTime);\n\n if (wasPlaying) {\n this.play();\n }\n\n this.state.audioDescriptionEnabled = false;\n this.emit('audiodescriptiondisabled');\n }\n\n async toggleAudioDescription() {\n if (this.state.audioDescriptionEnabled) {\n await this.disableAudioDescription();\n } else {\n await this.enableAudioDescription();\n }\n }\n\n // Sign Language\n enableSignLanguage() {\n if (!this.signLanguageSrc) {\n console.warn('No sign language video source provided');\n return;\n }\n\n if (this.signLanguageVideo) {\n // Already exists, just show it\n this.signLanguageVideo.style.display = 'block';\n this.state.signLanguageEnabled = true;\n this.emit('signlanguageenabled');\n return;\n }\n\n // Create sign language video element\n this.signLanguageVideo = document.createElement('video');\n this.signLanguageVideo.className = 'vidply-sign-language-video';\n this.signLanguageVideo.src = this.signLanguageSrc;\n this.signLanguageVideo.setAttribute('aria-label', i18n.t('player.signLanguage'));\n\n // Set position based on options\n const position = this.options.signLanguagePosition || 'bottom-right';\n this.signLanguageVideo.classList.add(`vidply-sign-position-${position}`);\n\n // Sync with main video\n this.signLanguageVideo.muted = true; // Sign language video should be muted\n this.signLanguageVideo.currentTime = this.state.currentTime;\n if (!this.state.paused) {\n this.signLanguageVideo.play();\n }\n\n // Add to video wrapper (so it overlays the video, not the entire container)\n this.videoWrapper.appendChild(this.signLanguageVideo);\n\n // Create bound handlers to store references for cleanup\n this.signLanguageHandlers = {\n play: () => {\n if (this.signLanguageVideo) {\n this.signLanguageVideo.play();\n }\n },\n pause: () => {\n if (this.signLanguageVideo) {\n this.signLanguageVideo.pause();\n }\n },\n timeupdate: () => {\n if (this.signLanguageVideo && Math.abs(this.signLanguageVideo.currentTime - this.state.currentTime) > 0.5) {\n this.signLanguageVideo.currentTime = this.state.currentTime;\n }\n },\n ratechange: () => {\n if (this.signLanguageVideo) {\n this.signLanguageVideo.playbackRate = this.state.playbackSpeed;\n }\n }\n };\n\n // Sync playback\n this.on('play', this.signLanguageHandlers.play);\n this.on('pause', this.signLanguageHandlers.pause);\n this.on('timeupdate', this.signLanguageHandlers.timeupdate);\n this.on('ratechange', this.signLanguageHandlers.ratechange);\n\n this.state.signLanguageEnabled = true;\n this.emit('signlanguageenabled');\n }\n\n disableSignLanguage() {\n if (this.signLanguageVideo) {\n this.signLanguageVideo.style.display = 'none';\n }\n this.state.signLanguageEnabled = false;\n this.emit('signlanguagedisabled');\n }\n\n toggleSignLanguage() {\n if (this.state.signLanguageEnabled) {\n this.disableSignLanguage();\n } else {\n this.enableSignLanguage();\n }\n }\n\n cleanupSignLanguage() {\n // Remove event listeners\n if (this.signLanguageHandlers) {\n this.off('play', this.signLanguageHandlers.play);\n this.off('pause', this.signLanguageHandlers.pause);\n this.off('timeupdate', this.signLanguageHandlers.timeupdate);\n this.off('ratechange', this.signLanguageHandlers.ratechange);\n this.signLanguageHandlers = null;\n }\n\n // Remove video element\n if (this.signLanguageVideo && this.signLanguageVideo.parentNode) {\n this.signLanguageVideo.pause();\n this.signLanguageVideo.src = '';\n this.signLanguageVideo.parentNode.removeChild(this.signLanguageVideo);\n this.signLanguageVideo = null;\n }\n }\n\n // Settings\n // Settings dialog removed - using individual control buttons instead\n showSettings() {\n console.warn('[VidPly] Settings dialog has been removed. Use individual control buttons (speed, captions, etc.)');\n }\n\n hideSettings() {\n // No-op - settings dialog removed\n }\n\n // Utility methods\n getCurrentTime() {\n return this.state.currentTime;\n }\n\n getDuration() {\n return this.state.duration;\n }\n\n isPlaying() {\n return this.state.playing;\n }\n\n isPaused() {\n return this.state.paused;\n }\n\n isEnded() {\n return this.state.ended;\n }\n\n isMuted() {\n return this.state.muted;\n }\n\n isFullscreen() {\n return this.state.fullscreen;\n }\n\n // Error handling\n handleError(error) {\n this.log('Error:', error, 'error');\n this.emit('error', error);\n\n if (this.options.onError) {\n this.options.onError.call(this, error);\n }\n }\n\n // Logging\n log(message, type = 'log') {\n if (this.options.debug) {\n console[type](`[VidPly]`, message);\n }\n }\n\n // Setup responsive handlers\n setupResponsiveHandlers() {\n // Use ResizeObserver for efficient resize tracking\n if (typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const width = entry.contentRect.width;\n\n // Update control bar for viewport\n if (this.controlBar && typeof this.controlBar.updateControlsForViewport === 'function') {\n this.controlBar.updateControlsForViewport(width);\n }\n\n // Update transcript positioning\n if (this.transcriptManager && this.transcriptManager.isVisible) {\n this.transcriptManager.positionTranscript();\n }\n }\n });\n\n this.resizeObserver.observe(this.container);\n } else {\n // Fallback to window resize event\n this.resizeHandler = () => {\n const width = this.container.clientWidth;\n\n if (this.controlBar && typeof this.controlBar.updateControlsForViewport === 'function') {\n this.controlBar.updateControlsForViewport(width);\n }\n\n if (this.transcriptManager && this.transcriptManager.isVisible) {\n this.transcriptManager.positionTranscript();\n }\n };\n\n window.addEventListener('resize', this.resizeHandler);\n }\n\n // Also listen for orientation changes on mobile\n if (window.matchMedia) {\n this.orientationHandler = (e) => {\n // Wait for layout to settle\n setTimeout(() => {\n if (this.transcriptManager && this.transcriptManager.isVisible) {\n this.transcriptManager.positionTranscript();\n }\n }, 100);\n };\n\n const orientationQuery = window.matchMedia('(orientation: portrait)');\n if (orientationQuery.addEventListener) {\n orientationQuery.addEventListener('change', this.orientationHandler);\n } else if (orientationQuery.addListener) {\n // Fallback for older browsers\n orientationQuery.addListener(this.orientationHandler);\n }\n\n this.orientationQuery = orientationQuery;\n }\n }\n\n // Cleanup\n destroy() {\n this.log('Destroying player');\n\n if (this.renderer) {\n this.renderer.destroy();\n }\n\n if (this.controlBar) {\n this.controlBar.destroy();\n }\n\n if (this.captionManager) {\n this.captionManager.destroy();\n }\n\n if (this.keyboardManager) {\n this.keyboardManager.destroy();\n }\n\n if (this.transcriptManager) {\n this.transcriptManager.destroy();\n }\n\n // Cleanup sign language video and listeners\n this.cleanupSignLanguage();\n\n // Cleanup play overlay button\n if (this.playButtonOverlay && this.playButtonOverlay.parentNode) {\n this.playButtonOverlay.remove();\n this.playButtonOverlay = null;\n }\n\n // Cleanup resize observer\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n\n // Cleanup window resize handler\n if (this.resizeHandler) {\n window.removeEventListener('resize', this.resizeHandler);\n this.resizeHandler = null;\n }\n\n // Cleanup orientation change handler\n if (this.orientationQuery && this.orientationHandler) {\n if (this.orientationQuery.removeEventListener) {\n this.orientationQuery.removeEventListener('change', this.orientationHandler);\n } else if (this.orientationQuery.removeListener) {\n this.orientationQuery.removeListener(this.orientationHandler);\n }\n this.orientationQuery = null;\n this.orientationHandler = null;\n }\n\n // Remove container\n if (this.container && this.container.parentNode) {\n this.container.parentNode.insertBefore(this.element, this.container);\n this.container.parentNode.removeChild(this.container);\n }\n\n this.removeAllListeners();\n }\n}\n\n// Static instances tracker for pause others functionality\nPlayer.instances = [];\n\n", "/**\n * YouTube Renderer\n */\n\nexport class YouTubeRenderer {\n constructor(player) {\n this.player = player;\n this.youtube = null;\n this.videoId = null;\n this.isReady = false;\n this.iframe = null;\n }\n\n async init() {\n // Extract video ID from URL\n this.videoId = this.extractVideoId(this.player.element.src);\n \n if (!this.videoId) {\n throw new Error('Invalid YouTube URL');\n }\n\n // Load YouTube IFrame API\n await this.loadYouTubeAPI();\n\n // Create iframe\n this.createIframe();\n\n // Initialize player\n await this.initializePlayer();\n }\n\n extractVideoId(url) {\n const patterns = [\n /(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/)([^&\\s]+)/,\n /youtube\\.com\\/embed\\/([^&\\s]+)/\n ];\n\n for (const pattern of patterns) {\n const match = url.match(pattern);\n if (match && match[1]) {\n return match[1];\n }\n }\n\n return null;\n }\n\n async loadYouTubeAPI() {\n // Check if API is already loaded\n if (window.YT && window.YT.Player) {\n return Promise.resolve();\n }\n\n return new Promise((resolve, reject) => {\n // Check if script is already being loaded\n if (window.onYouTubeIframeAPIReady) {\n const originalCallback = window.onYouTubeIframeAPIReady;\n window.onYouTubeIframeAPIReady = () => {\n originalCallback();\n resolve();\n };\n return;\n }\n\n // Load the API script\n const tag = document.createElement('script');\n tag.src = 'https://www.youtube.com/iframe_api';\n \n window.onYouTubeIframeAPIReady = () => {\n resolve();\n };\n\n tag.onerror = () => reject(new Error('Failed to load YouTube API'));\n \n const firstScriptTag = document.getElementsByTagName('script')[0];\n firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n });\n }\n\n createIframe() {\n // Hide original element\n this.player.element.style.display = 'none';\n\n // Create container for iframe\n this.iframe = document.createElement('div');\n this.iframe.id = `youtube-player-${Math.random().toString(36).substr(2, 9)}`;\n this.iframe.style.width = '100%';\n this.iframe.style.height = '100%';\n \n this.player.element.parentNode.insertBefore(this.iframe, this.player.element);\n }\n\n async initializePlayer() {\n return new Promise((resolve) => {\n this.youtube = new window.YT.Player(this.iframe.id, {\n videoId: this.videoId,\n width: '100%',\n height: '100%',\n playerVars: {\n controls: 0,\n disablekb: 1,\n fs: 0,\n modestbranding: 1,\n rel: 0,\n showinfo: 0,\n iv_load_policy: 3,\n autoplay: this.player.options.autoplay ? 1 : 0,\n mute: this.player.options.muted ? 1 : 0,\n start: this.player.options.startTime || 0\n },\n events: {\n onReady: (event) => {\n this.isReady = true;\n this.attachEvents();\n resolve();\n },\n onStateChange: (event) => this.handleStateChange(event),\n onError: (event) => this.handleError(event)\n }\n });\n });\n }\n\n attachEvents() {\n // Set up polling for time updates (YouTube doesn't provide timeupdate events)\n this.timeUpdateInterval = setInterval(() => {\n if (this.isReady && this.youtube) {\n const currentTime = this.youtube.getCurrentTime();\n const duration = this.youtube.getDuration();\n \n this.player.state.currentTime = currentTime;\n this.player.state.duration = duration;\n \n this.player.emit('timeupdate', currentTime);\n }\n }, 250);\n\n // Initial metadata\n if (this.youtube.getDuration) {\n this.player.state.duration = this.youtube.getDuration();\n this.player.emit('loadedmetadata');\n }\n }\n\n handleStateChange(event) {\n const states = window.YT.PlayerState;\n\n switch (event.data) {\n case states.PLAYING:\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.state.buffering = false;\n this.player.emit('play');\n this.player.emit('playing');\n \n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n break;\n\n case states.PAUSED:\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n \n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n break;\n\n case states.ENDED:\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n \n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n \n if (this.player.options.loop) {\n this.youtube.seekTo(0);\n this.youtube.playVideo();\n }\n break;\n\n case states.BUFFERING:\n this.player.state.buffering = true;\n this.player.emit('waiting');\n break;\n\n case states.CUED:\n this.player.emit('loadedmetadata');\n break;\n }\n }\n\n handleError(event) {\n const errors = {\n 2: 'Invalid video ID',\n 5: 'HTML5 player error',\n 100: 'Video not found',\n 101: 'Video not allowed to be played in embedded players',\n 150: 'Video not allowed to be played in embedded players'\n };\n\n const error = new Error(errors[event.data] || 'YouTube player error');\n this.player.handleError(error);\n }\n\n play() {\n if (this.isReady && this.youtube) {\n this.youtube.playVideo();\n }\n }\n\n pause() {\n if (this.isReady && this.youtube) {\n this.youtube.pauseVideo();\n }\n }\n\n seek(time) {\n if (this.isReady && this.youtube) {\n this.youtube.seekTo(time, true);\n }\n }\n\n setVolume(volume) {\n if (this.isReady && this.youtube) {\n this.youtube.setVolume(volume * 100);\n this.player.state.volume = volume;\n }\n }\n\n setMuted(muted) {\n if (this.isReady && this.youtube) {\n if (muted) {\n this.youtube.mute();\n } else {\n this.youtube.unMute();\n }\n this.player.state.muted = muted;\n }\n }\n\n setPlaybackSpeed(speed) {\n if (this.isReady && this.youtube) {\n this.youtube.setPlaybackRate(speed);\n this.player.state.playbackSpeed = speed;\n }\n }\n\n destroy() {\n if (this.timeUpdateInterval) {\n clearInterval(this.timeUpdateInterval);\n }\n\n if (this.youtube && this.youtube.destroy) {\n this.youtube.destroy();\n }\n\n if (this.iframe && this.iframe.parentNode) {\n this.iframe.parentNode.removeChild(this.iframe);\n }\n\n // Show original element\n if (this.player.element) {\n this.player.element.style.display = '';\n }\n }\n}\n\n", "/**\n * Vimeo Renderer\n */\n\nexport class VimeoRenderer {\n constructor(player) {\n this.player = player;\n this.vimeo = null;\n this.videoId = null;\n this.isReady = false;\n this.iframe = null;\n }\n\n async init() {\n // Extract video ID from URL\n this.videoId = this.extractVideoId(this.player.element.src);\n \n if (!this.videoId) {\n throw new Error('Invalid Vimeo URL');\n }\n\n // Load Vimeo Player API\n await this.loadVimeoAPI();\n\n // Create iframe\n this.createIframe();\n\n // Initialize player\n await this.initializePlayer();\n }\n\n extractVideoId(url) {\n const patterns = [\n /vimeo\\.com\\/(\\d+)/,\n /vimeo\\.com\\/video\\/(\\d+)/,\n /player\\.vimeo\\.com\\/video\\/(\\d+)/\n ];\n\n for (const pattern of patterns) {\n const match = url.match(pattern);\n if (match && match[1]) {\n return match[1];\n }\n }\n\n return null;\n }\n\n async loadVimeoAPI() {\n // Check if API is already loaded\n if (window.Vimeo && window.Vimeo.Player) {\n return Promise.resolve();\n }\n\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://player.vimeo.com/api/player.js';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load Vimeo API'));\n document.head.appendChild(script);\n });\n }\n\n createIframe() {\n // Hide original element\n this.player.element.style.display = 'none';\n\n // Create container for iframe\n this.iframe = document.createElement('div');\n this.iframe.id = `vimeo-player-${Math.random().toString(36).substr(2, 9)}`;\n this.iframe.style.width = '100%';\n this.iframe.style.height = '100%';\n \n this.player.element.parentNode.insertBefore(this.iframe, this.player.element);\n }\n\n async initializePlayer() {\n const options = {\n id: this.videoId,\n width: '100%',\n height: '100%',\n controls: false,\n autoplay: this.player.options.autoplay,\n muted: this.player.options.muted,\n loop: this.player.options.loop,\n keyboard: false\n };\n\n if (this.player.options.startTime > 0) {\n options.startTime = this.player.options.startTime;\n }\n\n this.vimeo = new window.Vimeo.Player(this.iframe.id, options);\n\n // Wait for player to be ready\n await this.vimeo.ready();\n this.isReady = true;\n\n this.attachEvents();\n\n // Get initial duration\n try {\n const duration = await this.vimeo.getDuration();\n this.player.state.duration = duration;\n this.player.emit('loadedmetadata');\n } catch (error) {\n this.player.log('Error getting duration:', error, 'warn');\n }\n }\n\n attachEvents() {\n this.vimeo.on('play', () => {\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.emit('play');\n \n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n });\n\n this.vimeo.on('pause', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n \n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n });\n\n this.vimeo.on('ended', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n \n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n });\n\n this.vimeo.on('timeupdate', (data) => {\n this.player.state.currentTime = data.seconds;\n this.player.state.duration = data.duration;\n this.player.emit('timeupdate', data.seconds);\n \n if (this.player.options.onTimeUpdate) {\n this.player.options.onTimeUpdate.call(this.player, data.seconds);\n }\n });\n\n this.vimeo.on('volumechange', (data) => {\n this.player.state.volume = data.volume;\n this.player.emit('volumechange', data.volume);\n });\n\n this.vimeo.on('bufferstart', () => {\n this.player.state.buffering = true;\n this.player.emit('waiting');\n });\n\n this.vimeo.on('bufferend', () => {\n this.player.state.buffering = false;\n this.player.emit('canplay');\n });\n\n this.vimeo.on('seeking', () => {\n this.player.state.seeking = true;\n this.player.emit('seeking');\n });\n\n this.vimeo.on('seeked', () => {\n this.player.state.seeking = false;\n this.player.emit('seeked');\n });\n\n this.vimeo.on('playbackratechange', (data) => {\n this.player.state.playbackSpeed = data.playbackRate;\n this.player.emit('ratechange', data.playbackRate);\n });\n\n this.vimeo.on('error', (error) => {\n this.player.handleError(new Error(`Vimeo error: ${error.message}`));\n });\n }\n\n play() {\n if (this.isReady && this.vimeo) {\n this.vimeo.play().catch(error => {\n this.player.log('Play error:', error, 'warn');\n });\n }\n }\n\n pause() {\n if (this.isReady && this.vimeo) {\n this.vimeo.pause().catch(error => {\n this.player.log('Pause error:', error, 'warn');\n });\n }\n }\n\n seek(time) {\n if (this.isReady && this.vimeo) {\n this.vimeo.setCurrentTime(time).catch(error => {\n this.player.log('Seek error:', error, 'warn');\n });\n }\n }\n\n setVolume(volume) {\n if (this.isReady && this.vimeo) {\n this.vimeo.setVolume(volume).catch(error => {\n this.player.log('Volume error:', error, 'warn');\n });\n this.player.state.volume = volume;\n }\n }\n\n setMuted(muted) {\n if (this.isReady && this.vimeo) {\n if (muted) {\n this.vimeo.setVolume(0);\n } else {\n this.vimeo.setVolume(this.player.state.volume);\n }\n this.player.state.muted = muted;\n }\n }\n\n setPlaybackSpeed(speed) {\n if (this.isReady && this.vimeo) {\n this.vimeo.setPlaybackRate(speed).catch(error => {\n this.player.log('Playback rate error:', error, 'warn');\n });\n this.player.state.playbackSpeed = speed;\n }\n }\n\n destroy() {\n if (this.vimeo && this.vimeo.destroy) {\n this.vimeo.destroy();\n }\n\n if (this.iframe && this.iframe.parentNode) {\n this.iframe.parentNode.removeChild(this.iframe);\n }\n\n // Show original element\n if (this.player.element) {\n this.player.element.style.display = '';\n }\n }\n}\n\n", "/**\n * HLS Streaming Renderer\n * Uses hls.js for browsers that don't natively support HLS\n */\n\nexport class HLSRenderer {\n constructor(player) {\n this.player = player;\n this.media = player.element;\n this.hls = null;\n }\n\n async init() {\n // Check if browser natively supports HLS (Safari)\n if (this.canPlayNatively()) {\n this.player.log('Using native HLS support');\n await this.initNative();\n } else {\n this.player.log('Using hls.js for HLS support');\n await this.initHlsJs();\n }\n }\n\n canPlayNatively() {\n const video = document.createElement('video');\n return video.canPlayType('application/vnd.apple.mpegurl') !== '';\n }\n\n async initNative() {\n // Use HTML5 renderer for native HLS support\n const HTML5Renderer = (await import('./HTML5Renderer.js')).HTML5Renderer;\n const renderer = new HTML5Renderer(this.player);\n await renderer.init();\n \n // Copy methods\n Object.getOwnPropertyNames(Object.getPrototypeOf(renderer)).forEach(method => {\n if (method !== 'constructor' && typeof renderer[method] === 'function') {\n this[method] = renderer[method].bind(renderer);\n }\n });\n }\n\n async initHlsJs() {\n // Hide native controls\n this.media.controls = false;\n this.media.removeAttribute('controls');\n \n // Load hls.js if not already loaded\n if (!window.Hls) {\n await this.loadHlsJs();\n }\n\n if (!window.Hls.isSupported()) {\n throw new Error('HLS is not supported in this browser');\n }\n\n // Create hls.js instance with better error recovery\n this.hls = new window.Hls({\n debug: this.player.options.debug,\n enableWorker: true,\n lowLatencyMode: false,\n backBufferLength: 90,\n maxBufferLength: 30,\n maxMaxBufferLength: 600,\n maxBufferSize: 60 * 1000 * 1000,\n maxBufferHole: 0.5,\n // Network retry settings\n manifestLoadingTimeOut: 10000,\n manifestLoadingMaxRetry: 4,\n manifestLoadingRetryDelay: 1000,\n manifestLoadingMaxRetryTimeout: 64000,\n levelLoadingTimeOut: 10000,\n levelLoadingMaxRetry: 4,\n levelLoadingRetryDelay: 1000,\n levelLoadingMaxRetryTimeout: 64000,\n fragLoadingTimeOut: 20000,\n fragLoadingMaxRetry: 6,\n fragLoadingRetryDelay: 1000,\n fragLoadingMaxRetryTimeout: 64000\n });\n\n // Attach media element\n this.hls.attachMedia(this.media);\n\n // Load source - Get from attribute to avoid blob URL conversion\n let src;\n const sourceElement = this.player.element.querySelector('source');\n if (sourceElement) {\n // Use getAttribute to get the original URL, not the blob-converted one\n src = sourceElement.getAttribute('src');\n } else {\n // Fallback to element's src attribute\n src = this.player.element.getAttribute('src') || this.player.element.src;\n }\n \n this.player.log(`Loading HLS source: ${src}`, 'log');\n \n if (!src) {\n throw new Error('No HLS source found');\n }\n \n this.hls.loadSource(src);\n\n // Attach events\n this.attachHlsEvents();\n this.attachMediaEvents();\n }\n\n async loadHlsJs() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://cdn.jsdelivr.net/npm/hls.js@latest';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load hls.js'));\n document.head.appendChild(script);\n });\n }\n\n attachHlsEvents() {\n this.hls.on(window.Hls.Events.MANIFEST_PARSED, (event, data) => {\n this.player.log('HLS manifest loaded, found ' + data.levels.length + ' quality levels');\n this.player.emit('hlsmanifestparsed', data);\n });\n\n this.hls.on(window.Hls.Events.LEVEL_SWITCHED, (event, data) => {\n this.player.log('HLS level switched to ' + data.level);\n this.player.emit('hlslevelswitched', data);\n });\n\n this.hls.on(window.Hls.Events.ERROR, (event, data) => {\n this.handleHlsError(data);\n });\n\n this.hls.on(window.Hls.Events.FRAG_BUFFERED, () => {\n this.player.state.buffering = false;\n });\n }\n\n attachMediaEvents() {\n // Use same events as HTML5 renderer\n this.media.addEventListener('loadedmetadata', () => {\n this.player.state.duration = this.media.duration;\n this.player.emit('loadedmetadata');\n });\n\n this.media.addEventListener('play', () => {\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.emit('play');\n \n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n });\n\n this.media.addEventListener('pause', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n \n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n });\n\n this.media.addEventListener('ended', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n \n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n \n if (this.player.options.loop) {\n this.player.seek(0);\n this.player.play();\n }\n });\n\n this.media.addEventListener('timeupdate', () => {\n this.player.state.currentTime = this.media.currentTime;\n this.player.emit('timeupdate', this.media.currentTime);\n \n if (this.player.options.onTimeUpdate) {\n this.player.options.onTimeUpdate.call(this.player, this.media.currentTime);\n }\n });\n\n this.media.addEventListener('volumechange', () => {\n this.player.state.volume = this.media.volume;\n this.player.state.muted = this.media.muted;\n this.player.emit('volumechange', this.media.volume);\n });\n\n this.media.addEventListener('waiting', () => {\n this.player.state.buffering = true;\n this.player.emit('waiting');\n });\n\n this.media.addEventListener('canplay', () => {\n this.player.state.buffering = false;\n this.player.emit('canplay');\n });\n\n this.media.addEventListener('error', () => {\n this.player.handleError(this.media.error);\n });\n }\n\n handleHlsError(data) {\n // Log detailed error info\n this.player.log(`HLS Error - Type: ${data.type}, Details: ${data.details}, Fatal: ${data.fatal}`, 'warn');\n if (data.response) {\n this.player.log(`Response code: ${data.response.code}, URL: ${data.response.url}`, 'warn');\n }\n \n if (data.fatal) {\n switch (data.type) {\n case window.Hls.ErrorTypes.NETWORK_ERROR:\n this.player.log('Fatal network error, trying to recover...', 'error');\n this.player.log(`Network error details: ${data.details}`, 'error');\n setTimeout(() => {\n this.hls.startLoad();\n }, 1000);\n break;\n \n case window.Hls.ErrorTypes.MEDIA_ERROR:\n this.player.log('Fatal media error, trying to recover...', 'error');\n this.hls.recoverMediaError();\n break;\n \n default:\n this.player.log('Fatal error, cannot recover', 'error');\n this.player.handleError(new Error(`HLS Error: ${data.type} - ${data.details}`));\n this.hls.destroy();\n break;\n }\n } else {\n this.player.log('Non-fatal HLS error: ' + data.details, 'warn');\n }\n }\n\n play() {\n const promise = this.media.play();\n \n if (promise !== undefined) {\n promise.catch(error => {\n this.player.log('Play failed:', error, 'warn');\n });\n }\n }\n\n pause() {\n this.media.pause();\n }\n\n seek(time) {\n this.media.currentTime = time;\n }\n\n setVolume(volume) {\n this.media.volume = volume;\n }\n\n setMuted(muted) {\n this.media.muted = muted;\n }\n\n setPlaybackSpeed(speed) {\n this.media.playbackRate = speed;\n }\n\n switchQuality(levelIndex) {\n if (this.hls) {\n this.hls.currentLevel = levelIndex;\n }\n }\n\n getQualities() {\n if (this.hls && this.hls.levels) {\n return this.hls.levels.map((level, index) => ({\n index,\n height: level.height,\n width: level.width,\n bitrate: level.bitrate,\n name: `${level.height}p`\n }));\n }\n return [];\n }\n\n destroy() {\n if (this.hls) {\n this.hls.destroy();\n this.hls = null;\n }\n }\n}\n\n", "/**\n * VidPly Playlist Manager\n * Manages playlists for audio and video content\n */\n\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { createIconElement } from '../icons/Icons.js';\n\nexport class PlaylistManager {\n constructor(player, options = {}) {\n this.player = player;\n this.tracks = [];\n this.currentIndex = -1;\n \n // Options\n this.options = {\n autoAdvance: options.autoAdvance !== false, // Default true\n loop: options.loop || false,\n showPanel: options.showPanel !== false, // Default true\n ...options\n };\n \n // UI elements\n this.container = null;\n this.playlistPanel = null;\n this.trackInfoElement = null;\n \n // Bind methods\n this.handleTrackEnd = this.handleTrackEnd.bind(this);\n this.handleTrackError = this.handleTrackError.bind(this);\n \n // Initialize\n this.init();\n }\n \n init() {\n // Listen for track end\n this.player.on('ended', this.handleTrackEnd);\n this.player.on('error', this.handleTrackError);\n \n // Create UI if needed\n if (this.options.showPanel) {\n this.createUI();\n }\n }\n \n /**\n * Load a playlist\n * @param {Array} tracks - Array of track objects\n */\n loadPlaylist(tracks) {\n this.tracks = tracks;\n this.currentIndex = -1;\n \n // Add playlist class to container\n if (this.container) {\n this.container.classList.add('vidply-has-playlist');\n }\n \n // Update UI\n if (this.playlistPanel) {\n this.renderPlaylist();\n }\n \n // Auto-play first track\n if (tracks.length > 0) {\n this.play(0);\n }\n }\n \n /**\n * Play a specific track\n * @param {number} index - Track index\n */\n play(index) {\n if (index < 0 || index >= this.tracks.length) {\n console.warn('VidPly Playlist: Invalid track index', index);\n return;\n }\n \n const track = this.tracks[index];\n \n // Update current index\n this.currentIndex = index;\n \n // Load track into player\n this.player.load({\n src: track.src,\n type: track.type,\n poster: track.poster,\n tracks: track.tracks || []\n });\n \n // Update UI\n this.updateTrackInfo(track);\n this.updatePlaylistUI();\n \n // Emit event\n this.player.emit('playlisttrackchange', {\n index: index,\n item: track,\n total: this.tracks.length\n });\n \n // Auto-play\n setTimeout(() => {\n this.player.play();\n }, 100);\n }\n \n /**\n * Play next track\n */\n next() {\n let nextIndex = this.currentIndex + 1;\n \n if (nextIndex >= this.tracks.length) {\n if (this.options.loop) {\n nextIndex = 0;\n } else {\n return;\n }\n }\n \n this.play(nextIndex);\n }\n \n /**\n * Play previous track\n */\n previous() {\n let prevIndex = this.currentIndex - 1;\n \n if (prevIndex < 0) {\n if (this.options.loop) {\n prevIndex = this.tracks.length - 1;\n } else {\n return;\n }\n }\n \n this.play(prevIndex);\n }\n \n /**\n * Handle track end\n */\n handleTrackEnd() {\n if (this.options.autoAdvance) {\n this.next();\n }\n }\n \n /**\n * Handle track error\n */\n handleTrackError(e) {\n console.error('VidPly Playlist: Track error', e);\n \n // Try next track\n if (this.options.autoAdvance) {\n setTimeout(() => {\n this.next();\n }, 1000);\n }\n }\n \n /**\n * Create playlist UI\n */\n createUI() {\n // Find player container\n this.container = this.player.container;\n \n if (!this.container) {\n console.warn('VidPly Playlist: No container found');\n return;\n }\n \n // Create track info element (shows current track)\n this.trackInfoElement = DOMUtils.createElement('div', {\n className: 'vidply-track-info'\n });\n this.trackInfoElement.style.display = 'none';\n \n this.container.appendChild(this.trackInfoElement);\n \n // Create playlist panel\n this.playlistPanel = DOMUtils.createElement('div', {\n className: 'vidply-playlist-panel'\n });\n this.playlistPanel.style.display = 'none';\n \n this.container.appendChild(this.playlistPanel);\n }\n \n /**\n * Update track info display\n */\n updateTrackInfo(track) {\n if (!this.trackInfoElement) return;\n \n const trackNumber = this.currentIndex + 1;\n const totalTracks = this.tracks.length;\n \n this.trackInfoElement.innerHTML = `\n <div class=\"vidply-track-number\">Track ${trackNumber} of ${totalTracks}</div>\n <div class=\"vidply-track-title\">${DOMUtils.escapeHTML(track.title || 'Untitled')}</div>\n ${track.artist ? `<div class=\"vidply-track-artist\">${DOMUtils.escapeHTML(track.artist)}</div>` : ''}\n `;\n \n this.trackInfoElement.style.display = 'block';\n }\n \n /**\n * Render playlist\n */\n renderPlaylist() {\n if (!this.playlistPanel) return;\n \n // Clear existing\n this.playlistPanel.innerHTML = '';\n \n // Create header\n const header = DOMUtils.createElement('div', {\n className: 'vidply-playlist-header'\n });\n header.textContent = `Playlist (${this.tracks.length})`;\n this.playlistPanel.appendChild(header);\n \n // Create list\n const list = DOMUtils.createElement('div', {\n className: 'vidply-playlist-list'\n });\n \n this.tracks.forEach((track, index) => {\n const item = this.createPlaylistItem(track, index);\n list.appendChild(item);\n });\n \n this.playlistPanel.appendChild(list);\n this.playlistPanel.style.display = 'block';\n }\n \n /**\n * Create playlist item element\n */\n createPlaylistItem(track, index) {\n const item = DOMUtils.createElement('div', {\n className: 'vidply-playlist-item',\n role: 'button',\n tabIndex: 0,\n 'aria-label': `Play ${track.title || 'Track ' + (index + 1)}`\n });\n \n // Add active class if current\n if (index === this.currentIndex) {\n item.classList.add('vidply-playlist-item-active');\n }\n \n // Thumbnail or icon\n const thumbnail = DOMUtils.createElement('div', {\n className: 'vidply-playlist-thumbnail'\n });\n \n if (track.poster) {\n thumbnail.style.backgroundImage = `url(${track.poster})`;\n } else {\n // Show music/speaker icon for audio tracks\n const icon = createIconElement('music');\n icon.classList.add('vidply-playlist-thumbnail-icon');\n thumbnail.appendChild(icon);\n }\n \n item.appendChild(thumbnail);\n \n // Info\n const info = DOMUtils.createElement('div', {\n className: 'vidply-playlist-item-info'\n });\n \n const title = DOMUtils.createElement('div', {\n className: 'vidply-playlist-item-title'\n });\n title.textContent = track.title || `Track ${index + 1}`;\n info.appendChild(title);\n \n if (track.artist) {\n const artist = DOMUtils.createElement('div', {\n className: 'vidply-playlist-item-artist'\n });\n artist.textContent = track.artist;\n info.appendChild(artist);\n }\n \n item.appendChild(info);\n \n // Play icon\n const playIcon = createIconElement('play');\n playIcon.classList.add('vidply-playlist-item-icon');\n item.appendChild(playIcon);\n \n // Click handler\n item.addEventListener('click', () => {\n this.play(index);\n });\n \n // Keyboard handler\n item.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this.play(index);\n }\n });\n \n return item;\n }\n \n /**\n * Update playlist UI (highlight current track)\n */\n updatePlaylistUI() {\n if (!this.playlistPanel) return;\n \n const items = this.playlistPanel.querySelectorAll('.vidply-playlist-item');\n \n items.forEach((item, index) => {\n if (index === this.currentIndex) {\n item.classList.add('vidply-playlist-item-active');\n \n // Scroll into view\n item.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n } else {\n item.classList.remove('vidply-playlist-item-active');\n }\n });\n }\n \n /**\n * Get current track\n */\n getCurrentTrack() {\n return this.tracks[this.currentIndex] || null;\n }\n \n /**\n * Get playlist info\n */\n getPlaylistInfo() {\n return {\n currentIndex: this.currentIndex,\n totalTracks: this.tracks.length,\n currentTrack: this.getCurrentTrack(),\n hasNext: this.currentIndex < this.tracks.length - 1,\n hasPrevious: this.currentIndex > 0\n };\n }\n \n /**\n * Add track to playlist\n */\n addTrack(track) {\n this.tracks.push(track);\n \n if (this.playlistPanel) {\n this.renderPlaylist();\n }\n }\n \n /**\n * Remove track from playlist\n */\n removeTrack(index) {\n if (index < 0 || index >= this.tracks.length) return;\n \n this.tracks.splice(index, 1);\n \n // Adjust current index if needed\n if (index < this.currentIndex) {\n this.currentIndex--;\n } else if (index === this.currentIndex) {\n // Current track was removed, play next or stop\n if (this.currentIndex >= this.tracks.length) {\n this.currentIndex = this.tracks.length - 1;\n }\n \n if (this.currentIndex >= 0) {\n this.play(this.currentIndex);\n }\n }\n \n if (this.playlistPanel) {\n this.renderPlaylist();\n }\n }\n \n /**\n * Clear playlist\n */\n clear() {\n this.tracks = [];\n this.currentIndex = -1;\n \n if (this.playlistPanel) {\n this.playlistPanel.innerHTML = '';\n this.playlistPanel.style.display = 'none';\n }\n \n if (this.trackInfoElement) {\n this.trackInfoElement.innerHTML = '';\n this.trackInfoElement.style.display = 'none';\n }\n }\n \n /**\n * Destroy playlist manager\n */\n destroy() {\n // Remove event listeners\n this.player.off('ended', this.handleTrackEnd);\n this.player.off('error', this.handleTrackError);\n \n // Remove UI\n if (this.trackInfoElement) {\n this.trackInfoElement.remove();\n }\n \n if (this.playlistPanel) {\n this.playlistPanel.remove();\n }\n \n // Clear data\n this.clear();\n }\n}\n\nexport default PlaylistManager;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["translations", "HTML5Renderer"]
|
|
7
7
|
}
|