vidply 1.0.27 → 1.0.29
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/dist/dev/{vidply.TranscriptManager-GZKY44ON.js → vidply.TranscriptManager-T677KF4N.js} +5 -6
- package/dist/dev/vidply.TranscriptManager-T677KF4N.js.map +7 -0
- package/dist/dev/{vidply.chunk-UH5MTGKF.js → vidply.chunk-GS2JX5RQ.js} +149 -100
- package/dist/dev/vidply.chunk-GS2JX5RQ.js.map +7 -0
- package/dist/dev/{vidply.de-THBIMP4S.js → vidply.de-SNL6AJ4D.js} +10 -2
- package/dist/dev/{vidply.de-THBIMP4S.js.map → vidply.de-SNL6AJ4D.js.map} +2 -2
- package/dist/dev/{vidply.es-6VWDNNNL.js → vidply.es-2QCQKZ4U.js} +10 -2
- package/dist/dev/{vidply.es-6VWDNNNL.js.map → vidply.es-2QCQKZ4U.js.map} +2 -2
- package/dist/dev/vidply.esm.js +1681 -317
- package/dist/dev/vidply.esm.js.map +4 -4
- package/dist/dev/{vidply.fr-WHTWCHWT.js → vidply.fr-FJAZRL4L.js} +10 -2
- package/dist/dev/{vidply.fr-WHTWCHWT.js.map → vidply.fr-FJAZRL4L.js.map} +2 -2
- package/dist/dev/{vidply.ja-BFQNPOFI.js → vidply.ja-2XQOW53T.js} +10 -2
- package/dist/dev/vidply.ja-2XQOW53T.js.map +7 -0
- package/dist/legacy/vidply.js +1829 -361
- package/dist/legacy/vidply.js.map +4 -4
- package/dist/legacy/vidply.min.js +1 -1
- package/dist/legacy/vidply.min.meta.json +103 -35
- package/dist/prod/vidply.TranscriptManager-WFZSW6NR.min.js +6 -0
- package/dist/prod/vidply.chunk-LGTJRPUL.min.js +6 -0
- package/dist/prod/vidply.de-FR3XX54P.min.js +6 -0
- package/dist/prod/vidply.es-3IJCQLJ7.min.js +6 -0
- package/dist/prod/vidply.esm.min.js +8 -8
- package/dist/prod/vidply.fr-NC4VEAPH.min.js +6 -0
- package/dist/prod/vidply.ja-4ZC6ZQLV.min.js +6 -0
- package/dist/vidply.esm.min.meta.json +115 -47
- package/package.json +1 -1
- package/src/controls/ControlBar.js +3 -7
- package/src/controls/TranscriptManager.js +8 -8
- package/src/core/AudioDescriptionManager.js +701 -0
- package/src/core/Player.js +4776 -4921
- package/src/core/SignLanguageManager.js +1134 -0
- package/src/features/PlaylistManager.js +12 -12
- package/src/i18n/languages/de.js +9 -1
- package/src/i18n/languages/en.js +9 -1
- package/src/i18n/languages/es.js +9 -1
- package/src/i18n/languages/fr.js +9 -1
- package/src/i18n/languages/ja.js +9 -1
- package/src/utils/DOMUtils.js +153 -114
- package/src/utils/MenuFactory.js +374 -0
- package/dist/dev/vidply.TranscriptManager-GZKY44ON.js.map +0 -7
- package/dist/dev/vidply.chunk-UH5MTGKF.js.map +0 -7
- package/dist/dev/vidply.ja-BFQNPOFI.js.map +0 -7
- package/dist/prod/vidply.TranscriptManager-UZ6DUFB6.min.js +0 -6
- package/dist/prod/vidply.chunk-MBUR3U5L.min.js +0 -6
- package/dist/prod/vidply.de-SWFW4HYT.min.js +0 -6
- package/dist/prod/vidply.es-7BJ2DJAY.min.js +0 -6
- package/dist/prod/vidply.fr-DPVR5DFY.min.js +0 -6
- package/dist/prod/vidply.ja-PEBVWKVH.min.js +0 -6
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/controls/TranscriptManager.js"],
|
|
4
|
-
"sourcesContent": ["/**\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';\nimport { StorageManager } from '../utils/StorageManager.js';\nimport { focusElement, focusFirstElement } from '../utils/FocusUtils.js';\nimport { createMenuItem, attachMenuKeyboardNavigation, focusFirstMenuItem } from '../utils/MenuUtils.js';\nimport { DraggableResizable } from '../utils/DraggableResizable.js';\nimport { createLabeledSelect, toggleLabeledSelect, preventDragOnElement } from '../utils/FormUtils.js';\n\nexport class TranscriptManager {\n constructor(player) {\n this.player = player;\n this.transcriptWindow = null;\n this.transcriptEntries = [];\n this.metadataCues = [];\n this.currentActiveEntry = null;\n this.isVisible = false;\n \n // Storage manager\n this.storage = new StorageManager('vidply');\n \n // Draggable/Resizable utility\n this.draggableResizable = null;\n \n // Settings menu state\n this.settingsMenuVisible = false;\n this.settingsMenu = null;\n this.settingsButton = null;\n this.settingsMenuJustOpened = false;\n \n // Resize mode state\n this.resizeOptionButton = null;\n this.resizeOptionText = null;\n this.dragOptionButton = null;\n this.dragOptionText = null;\n this.resizeModeIndicator = null;\n this.resizeModeIndicatorTimeout = null;\n this.transcriptResizeHandles = [];\n this.liveRegion = null;\n \n // Style dialog state\n this.styleDialog = null;\n this.styleDialogVisible = false;\n this.styleDialogJustOpened = false;\n \n // Language selector state\n this.languageSelector = null;\n this.languageLabel = null;\n this.currentTranscriptLanguage = null;\n this.availableTranscriptLanguages = [];\n this.languageSelectorHandler = null;\n \n // Load saved preferences from localStorage\n const savedPreferences = this.storage.getTranscriptPreferences();\n \n // Autoscroll state (default: true)\n this.autoscrollEnabled = savedPreferences?.autoscroll !== undefined ? savedPreferences.autoscroll : true;\n \n // Show timestamps state (default: false)\n this.showTimestamps = savedPreferences?.showTimestamps !== undefined ? savedPreferences.showTimestamps : false;\n \n // Transcript styling options (with defaults, then player options, then saved preferences)\n this.transcriptStyle = {\n fontSize: savedPreferences?.fontSize || this.player.options.transcriptFontSize || '100%',\n fontFamily: savedPreferences?.fontFamily || this.player.options.transcriptFontFamily || 'sans-serif',\n color: savedPreferences?.color || this.player.options.transcriptColor || '#ffffff',\n backgroundColor: savedPreferences?.backgroundColor || this.player.options.transcriptBackgroundColor || '#1e1e1e',\n opacity: savedPreferences?.opacity ?? this.player.options.transcriptOpacity ?? 0.98\n };\n \n // Store event handlers for cleanup\n this.handlers = {\n timeupdate: () => this.updateActiveEntry(),\n audiodescriptionenabled: () => {\n if (this.isVisible) {\n this.loadTranscriptData();\n }\n },\n audiodescriptiondisabled: () => {\n if (this.isVisible) {\n this.loadTranscriptData();\n }\n },\n resize: null,\n settingsClick: null,\n settingsKeydown: null,\n documentClick: null,\n styleDialogKeydown: null\n };\n \n // Timeout management (for cleanup)\n this.timeouts = new Set();\n \n this.init();\n }\n\n init() {\n // Set up metadata handling immediately (independent of transcript display)\n this.setupMetadataHandlingOnLoad();\n \n // Listen for time updates to highlight active transcript entry\n this.player.on('timeupdate', this.handlers.timeupdate);\n \n // Listen for audio description changes to reload transcript\n this.player.on('audiodescriptionenabled', this.handlers.audiodescriptionenabled);\n this.player.on('audiodescriptiondisabled', this.handlers.audiodescriptiondisabled);\n \n // Reposition transcript when entering/exiting fullscreen\n this.player.on('fullscreenchange', () => {\n if (this.isVisible) {\n // Re-setup drag/drop when entering/exiting fullscreen on mobile devices\n // This enables drag/resize when entering fullscreen on mobile\n const isMobile = window.innerWidth < 768;\n if (isMobile) {\n this.setupDragAndDrop();\n }\n \n // Only auto-position if user hasn't manually positioned it\n if (!this.draggableResizable || !this.draggableResizable.manuallyPositioned) {\n // Add a small delay to ensure DOM has updated after fullscreen transition\n this.setManagedTimeout(() => this.positionTranscript(), 100);\n }\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\n if (this.player.controlBar && typeof this.player.controlBar.updateTranscriptButton === 'function') {\n this.player.controlBar.updateTranscriptButton();\n }\n \n // Focus the settings button for keyboard accessibility\n focusElement(this.settingsButton, { delay: 150 });\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 \n // Only auto-position if user hasn't manually positioned it\n // This prevents overwriting saved positions from localStorage\n if (!this.draggableResizable || !this.draggableResizable.manuallyPositioned) {\n this.setManagedTimeout(() => this.positionTranscript(), 0);\n }\n \n // Focus the settings button for keyboard accessibility\n focusElement(this.settingsButton, { delay: 150 });\n }\n this.isVisible = true;\n }\n\n /**\n * Hide transcript window\n */\n hideTranscript({ focusButton = false } = {}) {\n if (this.transcriptWindow) {\n this.transcriptWindow.style.display = 'none';\n this.isVisible = false;\n }\n if (this.draggableResizable && this.draggableResizable.pointerResizeMode) {\n this.draggableResizable.disablePointerResizeMode();\n this.updateResizeOptionState();\n }\n this.hideResizeModeIndicator();\n this.announceLive('');\n\n // Update transcript button state in control bar\n if (this.player.controlBar && typeof this.player.controlBar.updateTranscriptButton === 'function') {\n this.player.controlBar.updateTranscriptButton();\n }\n\n if (focusButton) {\n const transcriptButton = this.player.controlBar?.controls?.transcript;\n if (transcriptButton && typeof transcriptButton.focus === 'function') {\n transcriptButton.focus({ preventScroll: true });\n }\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 'tabindex': '0'\n }\n });\n\n // Header left side (settings button + title)\n this.headerLeft = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-header-left`\n });\n\n // Settings button\n const settingsAriaLabel = i18n.t('transcript.settingsMenu');\n this.settingsButton = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-transcript-settings`,\n attributes: {\n 'type': 'button',\n 'aria-label': settingsAriaLabel,\n 'aria-expanded': 'false'\n }\n });\n this.settingsButton.appendChild(createIconElement('settings'));\n DOMUtils.attachTooltip(this.settingsButton, settingsAriaLabel, this.player.options.classPrefix);\n this.handlers.settingsClick = (e) => {\n e.preventDefault();\n e.stopPropagation();\n if (this.settingsMenuVisible) {\n this.hideSettingsMenu();\n } else {\n this.showSettingsMenu();\n }\n };\n this.settingsButton.addEventListener('click', this.handlers.settingsClick);\n \n // Keyboard handler for settings button\n this.handlers.settingsKeydown = (e) => {\n // D key to toggle keyboard drag mode\n if (e.key === 'd' || e.key === 'D') {\n e.preventDefault();\n e.stopPropagation();\n this.toggleKeyboardDragMode();\n }\n // R key to toggle resize mode\n else if (e.key === 'r' || e.key === 'R') {\n e.preventDefault();\n e.stopPropagation();\n this.toggleResizeMode();\n }\n // Escape to close menu if open\n else if (e.key === 'Escape' && this.settingsMenuVisible) {\n e.preventDefault();\n e.stopPropagation();\n this.hideSettingsMenu();\n }\n };\n this.settingsButton.addEventListener('keydown', this.handlers.settingsKeydown);\n\n const title = DOMUtils.createElement('h3', {\n textContent: `${i18n.t('transcript.title')}. ${i18n.t('transcript.dragResizePrompt')}`\n });\n\n // Autoscroll checkbox\n const autoscrollId = `${this.player.options.classPrefix}-transcript-autoscroll-${Date.now()}`;\n \n const autoscrollLabel = DOMUtils.createElement('label', {\n className: `${this.player.options.classPrefix}-transcript-autoscroll-label`,\n attributes: {\n 'for': autoscrollId\n }\n });\n \n this.autoscrollCheckbox = DOMUtils.createElement('input', {\n attributes: {\n 'id': autoscrollId,\n 'type': 'checkbox'\n }\n });\n // Set checked property directly (boolean attribute, not \"true\" string)\n if (this.autoscrollEnabled) {\n this.autoscrollCheckbox.checked = true;\n }\n \n const autoscrollText = DOMUtils.createElement('span', {\n textContent: i18n.t('transcript.autoscroll'),\n className: `${this.player.options.classPrefix}-transcript-autoscroll-text`\n });\n \n autoscrollLabel.appendChild(this.autoscrollCheckbox);\n autoscrollLabel.appendChild(autoscrollText);\n \n // Handle autoscroll checkbox change\n this.autoscrollCheckbox.addEventListener('change', (e) => {\n this.autoscrollEnabled = e.target.checked;\n this.saveAutoscrollPreference();\n });\n\n this.transcriptHeader.appendChild(title);\n this.headerLeft.appendChild(this.settingsButton);\n this.headerLeft.appendChild(autoscrollLabel);\n \n // Language selector (will be populated after tracks are loaded)\n const selectId = `${this.player.options.classPrefix}-transcript-language-select-${Date.now()}`;\n const { label: languageLabel, select: languageSelector } = createLabeledSelect({\n classPrefix: this.player.options.classPrefix,\n labelClass: `${this.player.options.classPrefix}-transcript-language-label`,\n selectClass: `${this.player.options.classPrefix}-transcript-language-select`,\n labelText: 'settings.language',\n selectId: selectId,\n hidden: false // Don't hide individual elements, we'll hide the wrapper instead\n });\n \n this.languageLabel = languageLabel;\n this.languageSelector = languageSelector;\n \n // Wrap label and select in a container for vertical stacking\n const languageSelectorWrapper = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-language-wrapper`,\n attributes: {\n 'style': 'display: none;' // Hidden until we detect multiple languages\n }\n });\n languageSelectorWrapper.appendChild(this.languageLabel);\n languageSelectorWrapper.appendChild(this.languageSelector);\n this.languageSelectorWrapper = languageSelectorWrapper;\n \n // Prevent drag when interacting with wrapper\n preventDragOnElement(languageSelectorWrapper);\n \n this.headerLeft.appendChild(languageSelectorWrapper);\n\n const closeAriaLabel = i18n.t('transcript.close');\n const closeButton = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-transcript-close`,\n attributes: {\n 'type': 'button',\n 'aria-label': closeAriaLabel\n }\n });\n closeButton.appendChild(createIconElement('close'));\n DOMUtils.attachTooltip(closeButton, closeAriaLabel, this.player.options.classPrefix);\n closeButton.addEventListener('click', () => this.hideTranscript({ focusButton: true }));\n\n this.transcriptHeader.appendChild(this.headerLeft);\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 this.createResizeHandles();\n\n // Live region for announcements (screen reader feedback)\n this.liveRegion = DOMUtils.createElement('div', {\n className: 'vidply-sr-only',\n attributes: {\n 'aria-live': 'polite',\n 'aria-atomic': 'true'\n }\n });\n this.transcriptWindow.appendChild(this.liveRegion);\n\n // Append to player container\n this.player.container.appendChild(this.transcriptWindow);\n \n // Setup drag functionality FIRST (this will restore saved position if it exists)\n this.setupDragAndDrop();\n \n // Then position it next to the video wrapper ONLY if user hasn't manually positioned it\n // This ensures we don't overwrite saved positions from localStorage\n if (!this.draggableResizable || !this.draggableResizable.manuallyPositioned) {\n this.positionTranscript();\n }\n \n // Setup document click handler to close settings menu and style dialog\n // DON'T add it yet - it will be added when the menu is first opened\n this.handlers.documentClick = (e) => {\n // Ignore if menu was just opened (prevents immediate closing)\n if (this.settingsMenuJustOpened) {\n return;\n }\n \n // Ignore if style dialog was just opened (prevents immediate closing)\n if (this.styleDialogJustOpened) {\n return;\n }\n \n // Ignore clicks on the settings button itself\n if (this.settingsButton && this.settingsButton.contains(e.target)) {\n return;\n }\n \n // Ignore clicks on the settings menu items\n if (this.settingsMenu && this.settingsMenu.contains(e.target)) {\n return;\n }\n \n // Close settings menu if clicking outside\n if (this.settingsMenuVisible) {\n this.hideSettingsMenu();\n }\n \n // Close style dialog if clicking outside (but not on settings button)\n if (this.styleDialogVisible && this.styleDialog && \n !this.styleDialog.contains(e.target)) {\n this.hideStyleDialog();\n }\n };\n // Store flag to track if handler has been added\n this.documentClickHandlerAdded = false;\n \n // Re-position on window resize (debounced) - but only if not manually positioned\n let resizeTimeout;\n this.handlers.resize = () => {\n if (resizeTimeout) {\n this.clearManagedTimeout(resizeTimeout);\n }\n resizeTimeout = this.setManagedTimeout(() => {\n // Only auto-position if user hasn't manually moved it\n if (!this.draggableResizable || !this.draggableResizable.manuallyPositioned) {\n this.positionTranscript();\n }\n }, 100);\n };\n window.addEventListener('resize', this.handlers.resize);\n }\n \n createResizeHandles() {\n if (!this.transcriptWindow) return;\n\n const directions = ['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw'];\n this.transcriptResizeHandles = directions.map(direction => {\n const handle = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-resize-handle ${this.player.options.classPrefix}-transcript-resize-${direction}`,\n attributes: {\n 'data-direction': direction,\n 'data-vidply-managed-resize': 'true',\n 'aria-hidden': 'true'\n }\n });\n\n handle.style.display = 'none';\n this.transcriptWindow.appendChild(handle);\n return handle;\n });\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 // Don't auto-position if user has manually positioned it\n if (this.draggableResizable && this.draggableResizable.manuallyPositioned) {\n return;\n }\n \n const isMobile = window.innerWidth < 768;\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 // Remove any empty border properties that might have been set\n this.transcriptWindow.style.removeProperty('border-right');\n this.transcriptWindow.style.removeProperty('border-bottom');\n this.transcriptWindow.style.removeProperty('border-left');\n // Remove border-image properties that can cause parse errors\n this.transcriptWindow.style.removeProperty('border-image');\n this.transcriptWindow.style.removeProperty('border-image-source');\n this.transcriptWindow.style.removeProperty('border-image-slice');\n this.transcriptWindow.style.removeProperty('border-image-width');\n this.transcriptWindow.style.removeProperty('border-image-outset');\n this.transcriptWindow.style.removeProperty('border-image-repeat');\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 const fullscreenMinWidth = 260;\n const fullscreenAvailable = Math.max(fullscreenMinWidth, window.innerWidth - 40);\n const fullscreenDesired = parseFloat(this.transcriptWindow.style.width) || 400;\n const fullscreenWidth = Math.max(fullscreenMinWidth, Math.min(fullscreenDesired, fullscreenAvailable));\n this.transcriptWindow.style.width = `${fullscreenWidth}px`;\n this.transcriptWindow.style.maxWidth = 'none';\n this.transcriptWindow.style.borderRadius = '8px';\n this.transcriptWindow.style.border = '1px solid var(--vidply-border)';\n // Remove borderTop and any other individual border properties to avoid empty values\n this.transcriptWindow.style.removeProperty('border-top');\n this.transcriptWindow.style.removeProperty('border-right');\n this.transcriptWindow.style.removeProperty('border-bottom');\n this.transcriptWindow.style.removeProperty('border-left');\n // Remove border-image properties that can cause parse errors\n this.transcriptWindow.style.removeProperty('border-image');\n this.transcriptWindow.style.removeProperty('border-image-source');\n this.transcriptWindow.style.removeProperty('border-image-slice');\n this.transcriptWindow.style.removeProperty('border-image-width');\n this.transcriptWindow.style.removeProperty('border-image-outset');\n this.transcriptWindow.style.removeProperty('border-image-repeat');\n // Enable dragging in fullscreen (including touch devices)\n if (this.transcriptHeader) {\n this.transcriptHeader.style.cursor = 'move';\n }\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 in right side of viewport\n const transcriptWidth = parseFloat(this.transcriptWindow.style.width) || 400;\n const padding = 20;\n const minWidth = 260;\n const containerRect = this.player.container.getBoundingClientRect();\n\n const ensureContainerPositioned = () => {\n const computed = window.getComputedStyle(this.player.container);\n if (computed.position === 'static') {\n this.player.container.style.position = 'relative';\n }\n };\n\n ensureContainerPositioned();\n\n const left = (videoRect.right - containerRect.left) + padding;\n const availableWidth = window.innerWidth - videoRect.right - padding;\n const appliedWidth = Math.max(minWidth, Math.min(transcriptWidth, availableWidth));\n const appliedHeight = videoRect.height;\n\n this.transcriptWindow.style.position = 'absolute';\n this.transcriptWindow.style.left = `${left}px`;\n this.transcriptWindow.style.right = 'auto';\n this.transcriptWindow.style.bottom = 'auto';\n this.transcriptWindow.style.top = '0';\n this.transcriptWindow.style.height = `${appliedHeight}px`;\n this.transcriptWindow.style.maxHeight = 'none';\n this.transcriptWindow.style.width = `${appliedWidth}px`;\n this.transcriptWindow.style.maxWidth = 'none';\n this.transcriptWindow.style.borderRadius = '8px';\n this.transcriptWindow.style.border = '1px solid var(--vidply-border)';\n // Remove borderTop and any other individual border properties to avoid empty values\n this.transcriptWindow.style.removeProperty('border-top');\n this.transcriptWindow.style.removeProperty('border-right');\n this.transcriptWindow.style.removeProperty('border-bottom');\n this.transcriptWindow.style.removeProperty('border-left');\n // Remove border-image properties that can cause parse errors\n this.transcriptWindow.style.removeProperty('border-image');\n this.transcriptWindow.style.removeProperty('border-image-source');\n this.transcriptWindow.style.removeProperty('border-image-slice');\n this.transcriptWindow.style.removeProperty('border-image-width');\n this.transcriptWindow.style.removeProperty('border-image-outset');\n this.transcriptWindow.style.removeProperty('border-image-repeat');\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 * Get available transcript languages from tracks\n */\n getAvailableTranscriptLanguages() {\n const textTracks = this.player.textTracks;\n const languages = new Map();\n \n // Collect all caption/subtitle tracks with their languages\n textTracks.forEach(track => {\n if ((track.kind === 'captions' || track.kind === 'subtitles') && track.language) {\n if (!languages.has(track.language)) {\n languages.set(track.language, {\n language: track.language,\n label: track.label || track.language,\n track: track\n });\n }\n }\n });\n \n return Array.from(languages.values());\n }\n\n /**\n * Update language selector dropdown\n */\n updateLanguageSelector() {\n if (!this.languageSelector) return;\n \n this.availableTranscriptLanguages = this.getAvailableTranscriptLanguages();\n \n // Clear existing options\n this.languageSelector.innerHTML = '';\n \n // Only show selector if there are 2+ languages\n if (this.availableTranscriptLanguages.length < 2) {\n if (this.languageSelectorWrapper) {\n this.languageSelectorWrapper.style.display = 'none';\n }\n return;\n }\n \n // Show selector wrapper\n if (this.languageSelectorWrapper) {\n this.languageSelectorWrapper.style.display = 'flex';\n }\n \n this.availableTranscriptLanguages.forEach((langInfo, index) => {\n const option = DOMUtils.createElement('option', {\n textContent: langInfo.label,\n attributes: {\n 'value': langInfo.language,\n 'lang': langInfo.language\n }\n });\n this.languageSelector.appendChild(option);\n });\n \n // Set current selection\n if (this.currentTranscriptLanguage) {\n this.languageSelector.value = this.currentTranscriptLanguage;\n } else if (this.availableTranscriptLanguages.length > 0) {\n // Default to first language or active track\n const activeTrack = this.player.textTracks.find(\n track => (track.kind === 'captions' || track.kind === 'subtitles') && track.mode === 'showing'\n );\n this.currentTranscriptLanguage = activeTrack ? activeTrack.language : this.availableTranscriptLanguages[0].language;\n this.languageSelector.value = this.currentTranscriptLanguage;\n }\n \n // Remove existing change listener if any\n if (this.languageSelectorHandler) {\n this.languageSelector.removeEventListener('change', this.languageSelectorHandler);\n }\n \n // Handle language change\n this.languageSelectorHandler = (e) => {\n this.currentTranscriptLanguage = e.target.value;\n this.loadTranscriptData();\n \n // Set lang attribute for screen readers to pronounce text correctly\n if (this.transcriptContent && this.currentTranscriptLanguage) {\n this.transcriptContent.setAttribute('lang', this.currentTranscriptLanguage);\n }\n };\n this.languageSelector.addEventListener('change', this.languageSelectorHandler);\n }\n\n /**\n * Load transcript data from caption/subtitle tracks\n */\n loadTranscriptData() {\n this.transcriptEntries = [];\n this.transcriptContent.innerHTML = '';\n\n // Get all text tracks\n const textTracks = this.player.textTracks;\n \n // Find track for selected language, or default to first available\n let captionTrack = null;\n if (this.currentTranscriptLanguage) {\n captionTrack = textTracks.find(\n track => (track.kind === 'captions' || track.kind === 'subtitles') && \n track.language === this.currentTranscriptLanguage\n );\n }\n \n // Fallback to first available caption/subtitle track\n if (!captionTrack) {\n captionTrack = textTracks.find(\n track => track.kind === 'captions' || track.kind === 'subtitles'\n );\n if (captionTrack) {\n this.currentTranscriptLanguage = captionTrack.language;\n }\n }\n \n // Find description track matching the selected language\n let descriptionTrack = null;\n if (this.currentTranscriptLanguage) {\n descriptionTrack = textTracks.find(\n track => track.kind === 'descriptions' && track.language === this.currentTranscriptLanguage\n );\n }\n // Fallback to first available description track if no match found\n if (!descriptionTrack) {\n descriptionTrack = textTracks.find(track => track.kind === 'descriptions');\n }\n \n const metadataTrack = textTracks.find(track => track.kind === 'metadata');\n\n // We need at least one track type available for display\n // Description tracks are only included if audio description is enabled\n const hasDescriptionTrack = descriptionTrack && this.player.state.audioDescriptionEnabled;\n if (!captionTrack && !hasDescriptionTrack && !metadataTrack) {\n this.showNoTranscriptMessage();\n return;\n }\n\n // Enable all tracks to load cues (even if we won't display descriptions)\n // This ensures descriptions are ready when audio description is enabled\n const tracksToLoad = [captionTrack, descriptionTrack, metadataTrack].filter(Boolean);\n tracksToLoad.forEach(track => {\n if (track.mode === 'disabled') {\n track.mode = 'hidden';\n }\n });\n\n // Check if any tracks are still loading\n const needsLoading = tracksToLoad.some(track => !track.cues || track.cues.length === 0);\n \n if (needsLoading) {\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 let loaded = 0;\n const onLoad = () => {\n loaded++;\n if (loaded >= tracksToLoad.length) {\n this.loadTranscriptData();\n }\n };\n\n tracksToLoad.forEach(track => {\n track.addEventListener('load', onLoad, { once: true });\n });\n\n // Fallback timeout\n this.setManagedTimeout(() => {\n this.loadTranscriptData();\n }, 500);\n \n return;\n }\n\n // Collect all cues from all tracks with their type\n const allCues = [];\n \n if (captionTrack && captionTrack.cues) {\n Array.from(captionTrack.cues).forEach(cue => {\n allCues.push({ cue, type: 'caption' });\n });\n }\n \n // Only include description cues if audio description is enabled\n if (descriptionTrack && descriptionTrack.cues && this.player.state.audioDescriptionEnabled) {\n Array.from(descriptionTrack.cues).forEach(cue => {\n allCues.push({ cue, type: 'description' });\n });\n }\n \n // Store metadata separately for programmatic use (don't display in transcript)\n if (metadataTrack && metadataTrack.cues) {\n this.metadataCues = Array.from(metadataTrack.cues);\n this.setupMetadataHandling();\n }\n\n // Sort all cues by start time\n allCues.sort((a, b) => a.cue.startTime - b.cue.startTime);\n\n // Build transcript from captions and descriptions only\n allCues.forEach((item, index) => {\n const entry = this.createTranscriptEntry(item.cue, index, item.type);\n this.transcriptEntries.push({\n element: entry,\n cue: item.cue,\n type: item.type,\n startTime: item.cue.startTime,\n endTime: item.cue.endTime\n });\n this.transcriptContent.appendChild(entry);\n });\n \n // Apply current styles to newly loaded entries\n this.applyTranscriptStyles();\n \n // Apply timestamp visibility preference\n this.updateTimestampVisibility();\n \n // Set lang attribute for screen readers to pronounce text correctly\n if (this.transcriptContent && this.currentTranscriptLanguage) {\n this.transcriptContent.setAttribute('lang', this.currentTranscriptLanguage);\n }\n \n // Update language selector after loading\n this.updateLanguageSelector();\n }\n\n /**\n * Setup metadata handling on player load\n * This runs independently of transcript loading\n */\n setupMetadataHandlingOnLoad() {\n // Wait for metadata to be loaded\n const setupMetadata = () => {\n const textTracks = this.player.textTracks;\n const metadataTrack = textTracks.find(track => track.kind === 'metadata');\n \n if (metadataTrack) {\n // Enable the metadata track so cuechange events fire\n // Use 'hidden' mode so it doesn't display anything, but events still work\n if (metadataTrack.mode === 'disabled') {\n metadataTrack.mode = 'hidden';\n }\n \n // Check if we already added the listener\n if (this.metadataCueChangeHandler) {\n metadataTrack.removeEventListener('cuechange', this.metadataCueChangeHandler);\n }\n \n // Add event listener for cue changes\n this.metadataCueChangeHandler = () => {\n const activeCues = Array.from(metadataTrack.activeCues || []);\n if (activeCues.length > 0) {\n // Debug logging (can be removed in production)\n if (this.player.options.debug) {\n console.log('[VidPly Metadata] Active cues:', activeCues.map(c => ({\n start: c.startTime,\n end: c.endTime,\n text: c.text\n })));\n }\n }\n activeCues.forEach(cue => {\n this.handleMetadataCue(cue);\n });\n };\n \n metadataTrack.addEventListener('cuechange', this.metadataCueChangeHandler);\n \n // Debug: Log metadata track setup\n if (this.player.options.debug) {\n const cueCount = metadataTrack.cues ? metadataTrack.cues.length : 0;\n console.log('[VidPly Metadata] Track enabled,', cueCount, 'cues available');\n }\n } else if (this.player.options.debug) {\n console.warn('[VidPly Metadata] No metadata track found');\n }\n };\n \n // Try immediately\n setupMetadata();\n \n // Also try after loadedmetadata event\n this.player.on('loadedmetadata', setupMetadata);\n }\n\n /**\n * Setup metadata handling\n * Metadata cues are not displayed but can be used programmatically\n * This is called when transcript data is loaded (for storing cues)\n */\n setupMetadataHandling() {\n if (!this.metadataCues || this.metadataCues.length === 0) {\n return;\n }\n\n // The actual event handling is set up in setupMetadataHandlingOnLoad()\n // This method just stores the cues for reference\n if (this.player.options.debug) {\n console.log('[VidPly Metadata]', this.metadataCues.length, 'cues stored from transcript load');\n }\n }\n\n /**\n * Handle individual metadata cues\n * Parses metadata text and emits events or triggers actions\n */\n handleMetadataCue(cue) {\n const text = cue.text.trim();\n \n // Debug logging\n if (this.player.options.debug) {\n console.log('[VidPly Metadata] Processing cue:', {\n time: cue.startTime,\n text: text\n });\n }\n \n // Emit a generic metadata event that developers can listen to\n this.player.emit('metadata', {\n time: cue.startTime,\n endTime: cue.endTime,\n text: text,\n cue: cue\n });\n\n // Parse for specific commands (examples based on wwa_meta.vtt format)\n if (text.includes('PAUSE')) {\n // Automatically pause the video\n if (!this.player.state.paused) {\n if (this.player.options.debug) {\n console.log('[VidPly Metadata] Pausing video at', cue.startTime);\n }\n this.player.pause();\n }\n // Also emit event for developers who want to listen\n this.player.emit('metadata:pause', { time: cue.startTime, text: text });\n }\n\n // Parse for focus directives\n const focusMatch = text.match(/FOCUS:([\\w#-]+)/);\n if (focusMatch) {\n const targetSelector = focusMatch[1];\n // Automatically focus the target element\n const targetElement = document.querySelector(targetSelector);\n if (targetElement) {\n if (this.player.options.debug) {\n console.log('[VidPly Metadata] Focusing element:', targetSelector);\n }\n // Use setTimeout to ensure DOM is ready\n this.setManagedTimeout(() => {\n targetElement.focus({ preventScroll: true });\n }, 10);\n } else if (this.player.options.debug) {\n console.warn('[VidPly Metadata] Element not found:', targetSelector);\n }\n // Also emit event for developers who want to listen\n this.player.emit('metadata:focus', { \n time: cue.startTime, \n target: targetSelector,\n element: targetElement,\n text: text \n });\n }\n\n // Parse for hashtag references\n const hashtags = text.match(/#[\\w-]+/g);\n if (hashtags) {\n if (this.player.options.debug) {\n console.log('[VidPly Metadata] Hashtags found:', hashtags);\n }\n this.player.emit('metadata:hashtags', {\n time: cue.startTime,\n hashtags: hashtags,\n text: text\n });\n }\n }\n\n /**\n * Create a single transcript entry element\n */\n createTranscriptEntry(cue, index, type = 'caption') {\n const entryText = this.stripVTTFormatting(cue.text);\n \n const entry = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-entry ${this.player.options.classPrefix}-transcript-${type}`,\n attributes: {\n 'tabindex': '0',\n 'data-start': String(cue.startTime),\n 'data-end': String(cue.endTime),\n 'data-type': type\n }\n });\n\n const timestamp = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-transcript-time`,\n textContent: TimeUtils.formatTime(cue.startTime),\n attributes: {\n 'aria-hidden': 'true' // Hide from screen readers - decorative timestamp\n }\n });\n\n const text = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-transcript-text`,\n textContent: entryText\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 || !this.autoscrollEnabled) 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 * Save autoscroll preference to localStorage\n */\n saveAutoscrollPreference() {\n const savedPreferences = this.storage.getTranscriptPreferences() || {};\n savedPreferences.autoscroll = this.autoscrollEnabled;\n this.storage.saveTranscriptPreferences(savedPreferences);\n }\n\n /**\n * Setup drag and drop functionality\n */\n setupDragAndDrop() {\n if (!this.transcriptHeader || !this.transcriptWindow) return;\n\n // Check if we're on mobile and not in fullscreen\n const isMobile = window.innerWidth < 768;\n const isFullscreen = this.player.state.fullscreen;\n \n // On mobile devices (< 768px), only enable drag/resize in fullscreen\n // On desktop/tablets (>= 768px), always enable drag/resize\n if (isMobile && !isFullscreen) {\n // Destroy existing instance if exiting fullscreen on mobile\n if (this.draggableResizable) {\n this.draggableResizable.destroy();\n this.draggableResizable = null;\n }\n return; // No drag/resize on mobile when not in fullscreen\n }\n\n // If already initialized, don't re-initialize\n if (this.draggableResizable) {\n return;\n }\n\n // Create DraggableResizable utility with touch support\n this.draggableResizable = new DraggableResizable(this.transcriptWindow, {\n dragHandle: this.transcriptHeader,\n resizeHandles: this.transcriptResizeHandles,\n constrainToViewport: true,\n classPrefix: `${this.player.options.classPrefix}-transcript`,\n keyboardDragKey: 'd',\n keyboardResizeKey: 'r',\n keyboardStep: 10,\n keyboardStepLarge: 50,\n minWidth: 300,\n minHeight: 200,\n maxWidth: () => Math.max(320, window.innerWidth - 40),\n maxHeight: () => Math.max(200, window.innerHeight - 120),\n pointerResizeIndicatorText: i18n.t('transcript.resizeModeHint'),\n onPointerResizeToggle: (enabled) => {\n // Update resize handles visibility\n this.transcriptResizeHandles.forEach(handle => {\n handle.style.display = enabled ? 'block' : 'none';\n });\n // Call the state change handler\n this.onPointerResizeModeChange(enabled);\n },\n onDragStart: (e) => {\n // Don't drag if clicking on certain elements\n const ignoreSelectors = [\n `.${this.player.options.classPrefix}-transcript-close`,\n `.${this.player.options.classPrefix}-transcript-settings`,\n `.${this.player.options.classPrefix}-transcript-language-select`,\n `.${this.player.options.classPrefix}-transcript-language-label`,\n `.${this.player.options.classPrefix}-transcript-settings-menu`,\n `.${this.player.options.classPrefix}-transcript-style-dialog`\n ];\n \n for (const selector of ignoreSelectors) {\n if (e.target.closest(selector)) {\n return false; // Prevent drag\n }\n }\n \n return true; // Allow drag\n }\n });\n\n // Add custom keyboard handler for special keys (Escape, Home)\n this.customKeyHandler = (e) => {\n const key = e.key.toLowerCase();\n const alreadyPrevented = e.defaultPrevented;\n\n // Don't handle keys if settings menu or style dialog is open (let them handle keys)\n if (this.settingsMenuVisible || this.styleDialogVisible) {\n return;\n }\n\n if (key === 'home') {\n e.preventDefault();\n e.stopPropagation();\n if (this.draggableResizable) {\n if (this.draggableResizable.pointerResizeMode) {\n this.draggableResizable.disablePointerResizeMode();\n }\n this.draggableResizable.manuallyPositioned = false;\n this.positionTranscript();\n this.updateResizeOptionState();\n this.announceLive(i18n.t('transcript.positionReset'));\n }\n return;\n }\n \n if (key === 'r') {\n if (alreadyPrevented) {\n return;\n }\n e.preventDefault();\n e.stopPropagation();\n const enabled = this.toggleResizeMode();\n if (enabled) {\n this.transcriptWindow.focus({ preventScroll: true });\n }\n return;\n }\n \n if (key === 'escape') {\n // Check priority: resize mode > drag mode > close transcript\n // (settings menu and style dialog already handled by early return above)\n if (this.draggableResizable && this.draggableResizable.pointerResizeMode) {\n e.preventDefault();\n e.stopPropagation();\n this.draggableResizable.disablePointerResizeMode();\n return;\n }\n if (this.draggableResizable && this.draggableResizable.keyboardDragMode) {\n e.preventDefault();\n e.stopPropagation();\n this.draggableResizable.disableKeyboardDragMode();\n this.announceLive(i18n.t('transcript.dragModeDisabled'));\n return;\n }\n // Only close transcript if nothing else is open\n e.preventDefault();\n e.stopPropagation();\n this.hideTranscript({ focusButton: true });\n return;\n }\n };\n \n this.transcriptWindow.addEventListener('keydown', this.customKeyHandler);\n }\n\n\n /**\n * Toggle keyboard drag mode\n */\n toggleKeyboardDragMode() {\n if (this.draggableResizable) {\n const wasEnabled = this.draggableResizable.keyboardDragMode;\n this.draggableResizable.toggleKeyboardDragMode();\n const isEnabled = this.draggableResizable.keyboardDragMode;\n if (!wasEnabled && isEnabled) {\n this.enableMoveMode();\n }\n \n // Update drag option state\n this.updateDragOptionState();\n \n // Hide settings menu if open\n if (this.settingsMenuVisible) {\n this.hideSettingsMenu();\n }\n \n // Focus the window for keyboard navigation\n this.transcriptWindow.focus({ preventScroll: true });\n }\n }\n\n /**\n * Toggle settings menu visibility\n */\n toggleSettingsMenu() {\n if (this.settingsMenuVisible) {\n this.hideSettingsMenu();\n } else {\n this.showSettingsMenu();\n }\n }\n\n /**\n * Show settings menu\n */\n showSettingsMenu() {\n // Set flag to prevent immediate closing\n this.settingsMenuJustOpened = true;\n setTimeout(() => {\n this.settingsMenuJustOpened = false;\n }, 350);\n \n // Add document click handler on FIRST menu open (not at window creation)\n if (!this.documentClickHandlerAdded) {\n setTimeout(() => {\n document.addEventListener('click', this.handlers.documentClick);\n this.documentClickHandlerAdded = true;\n }, 300);\n }\n \n if (this.settingsMenu) {\n this.settingsMenu.style.display = 'block';\n this.settingsMenuVisible = true;\n if (this.settingsButton) {\n this.settingsButton.setAttribute('aria-expanded', 'true');\n }\n // Re-attach keyboard navigation handler\n this.attachSettingsMenuKeyboardNavigation();\n // Position menu immediately\n this.positionSettingsMenuImmediate();\n this.updateResizeOptionState();\n // Focus first menu item after positioning\n setTimeout(() => {\n const menuItems = this.settingsMenu.querySelectorAll(`.${this.player.options.classPrefix}-transcript-settings-item`);\n if (menuItems.length > 0) {\n menuItems[0].setAttribute('tabindex', '0');\n for (let i = 1; i < menuItems.length; i++) {\n menuItems[i].setAttribute('tabindex', '-1');\n }\n menuItems[0].focus({ preventScroll: true });\n }\n }, 50);\n return;\n }\n // Create settings menu\n this.settingsMenu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-settings-menu`,\n attributes: {\n 'role': 'menu'\n }\n });\n\n // Keyboard drag option\n const keyboardDragOption = createMenuItem({\n classPrefix: this.player.options.classPrefix,\n itemClass: `${this.player.options.classPrefix}-transcript-settings-item`,\n icon: 'move',\n label: 'transcript.enableDragMode',\n hasTextClass: true,\n onClick: () => {\n this.toggleKeyboardDragMode();\n this.hideSettingsMenu();\n }\n });\n keyboardDragOption.setAttribute('role', 'switch');\n keyboardDragOption.setAttribute('aria-checked', 'false');\n // Remove any tooltips from menu items (they have visible text)\n const dragTooltip = keyboardDragOption.querySelector(`.${this.player.options.classPrefix}-tooltip`);\n if (dragTooltip) dragTooltip.remove();\n const dragButtonText = keyboardDragOption.querySelector(`.${this.player.options.classPrefix}-button-text`);\n if (dragButtonText) dragButtonText.remove();\n this.dragOptionButton = keyboardDragOption;\n this.dragOptionText = keyboardDragOption.querySelector(`.${this.player.options.classPrefix}-settings-text`);\n this.updateDragOptionState();\n \n // Style option\n const styleOption = createMenuItem({\n classPrefix: this.player.options.classPrefix,\n itemClass: `${this.player.options.classPrefix}-transcript-settings-item`,\n icon: 'settings',\n label: 'transcript.styleTranscript',\n onClick: (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.hideSettingsMenu();\n // Delay to ensure menu is fully closed before opening dialog\n setTimeout(() => {\n this.showStyleDialog();\n }, 50);\n }\n });\n // Remove any tooltips from menu items (they have visible text)\n const styleTooltip = styleOption.querySelector(`.${this.player.options.classPrefix}-tooltip`);\n if (styleTooltip) styleTooltip.remove();\n const styleButtonText = styleOption.querySelector(`.${this.player.options.classPrefix}-button-text`);\n if (styleButtonText) styleButtonText.remove();\n\n // Resize option\n const resizeOption = createMenuItem({\n classPrefix: this.player.options.classPrefix,\n itemClass: `${this.player.options.classPrefix}-transcript-settings-item`,\n icon: 'resize',\n label: 'transcript.enableResizeMode',\n hasTextClass: true,\n onClick: (event) => {\n event.preventDefault();\n event.stopPropagation();\n \n const enabled = this.toggleResizeMode({ focus: false });\n \n if (enabled) {\n this.hideSettingsMenu({ focusButton: false });\n // Focus transcript window after handles appear\n setTimeout(() => {\n if (this.transcriptWindow) {\n this.transcriptWindow.focus({ preventScroll: true });\n }\n }, 20);\n } else {\n this.hideSettingsMenu({ focusButton: true });\n }\n }\n });\n resizeOption.setAttribute('role', 'switch');\n resizeOption.setAttribute('aria-checked', 'false');\n // Remove any tooltips from menu items (they have visible text)\n const resizeTooltip = resizeOption.querySelector(`.${this.player.options.classPrefix}-tooltip`);\n if (resizeTooltip) resizeTooltip.remove();\n const resizeButtonText = resizeOption.querySelector(`.${this.player.options.classPrefix}-button-text`);\n if (resizeButtonText) resizeButtonText.remove();\n this.resizeOptionButton = resizeOption;\n this.resizeOptionText = resizeOption.querySelector(`.${this.player.options.classPrefix}-settings-text`);\n this.updateResizeOptionState();\n\n // Show timestamps option\n const showTimestampsOption = createMenuItem({\n classPrefix: this.player.options.classPrefix,\n itemClass: `${this.player.options.classPrefix}-transcript-settings-item`,\n icon: 'clock',\n label: 'transcript.showTimestamps',\n hasTextClass: true,\n onClick: () => {\n this.toggleShowTimestamps();\n }\n });\n showTimestampsOption.setAttribute('role', 'switch');\n showTimestampsOption.setAttribute('aria-checked', this.showTimestamps ? 'true' : 'false');\n // Remove any tooltips from menu items (they have visible text)\n const timestampsTooltip = showTimestampsOption.querySelector(`.${this.player.options.classPrefix}-tooltip`);\n if (timestampsTooltip) timestampsTooltip.remove();\n const timestampsButtonText = showTimestampsOption.querySelector(`.${this.player.options.classPrefix}-button-text`);\n if (timestampsButtonText) timestampsButtonText.remove();\n this.showTimestampsButton = showTimestampsOption;\n this.showTimestampsText = showTimestampsOption.querySelector(`.${this.player.options.classPrefix}-settings-text`);\n this.updateShowTimestampsState();\n\n // Close option\n const closeOption = createMenuItem({\n classPrefix: this.player.options.classPrefix,\n itemClass: `${this.player.options.classPrefix}-transcript-settings-item`,\n icon: 'close',\n label: 'transcript.closeMenu',\n onClick: () => {\n this.hideSettingsMenu();\n }\n });\n // Remove any tooltips from menu items (they have visible text)\n const closeTooltip = closeOption.querySelector(`.${this.player.options.classPrefix}-tooltip`);\n if (closeTooltip) closeTooltip.remove();\n const closeButtonText = closeOption.querySelector(`.${this.player.options.classPrefix}-button-text`);\n if (closeButtonText) closeButtonText.remove();\n\n this.settingsMenu.appendChild(keyboardDragOption);\n this.settingsMenu.appendChild(resizeOption);\n this.settingsMenu.appendChild(styleOption);\n this.settingsMenu.appendChild(showTimestampsOption);\n this.settingsMenu.appendChild(closeOption);\n\n // Position menu first (before it's visible) to prevent jumping\n // Set menu to invisible temporarily\n this.settingsMenu.style.visibility = 'hidden';\n this.settingsMenu.style.display = 'block';\n \n // Insert menu right after settings button for proper positioning\n if (this.settingsButton && this.settingsButton.parentNode) {\n this.settingsButton.insertAdjacentElement('afterend', this.settingsMenu);\n } else if (this.headerLeft) {\n this.headerLeft.appendChild(this.settingsMenu);\n } else if (this.transcriptHeader) {\n this.transcriptHeader.appendChild(this.settingsMenu);\n } else {\n this.transcriptWindow.appendChild(this.settingsMenu);\n }\n \n // Position the menu relative to the settings button (immediately while hidden)\n this.positionSettingsMenuImmediate();\n \n // Make menu visible after positioning\n requestAnimationFrame(() => {\n if (this.settingsMenu) {\n this.settingsMenu.style.visibility = 'visible';\n }\n });\n \n // Add keyboard navigation\n this.settingsMenuKeyHandler = attachMenuKeyboardNavigation(\n this.settingsMenu,\n this.settingsButton,\n `.${this.player.options.classPrefix}-transcript-settings-item`,\n () => this.hideSettingsMenu({ focusButton: true })\n );\n \n // Set the menu as visible and display it\n this.settingsMenuVisible = true;\n this.settingsMenu.style.display = 'block';\n \n // Update aria-expanded\n if (this.settingsButton) {\n this.settingsButton.setAttribute('aria-expanded', 'true');\n }\n this.updateResizeOptionState();\n \n // Focus first menu item after visibility is set\n setTimeout(() => {\n const menuItems = this.settingsMenu.querySelectorAll(`.${this.player.options.classPrefix}-transcript-settings-item`);\n if (menuItems.length > 0) {\n menuItems[0].setAttribute('tabindex', '0');\n for (let i = 1; i < menuItems.length; i++) {\n menuItems[i].setAttribute('tabindex', '-1');\n }\n menuItems[0].focus({ preventScroll: true });\n }\n }, 50);\n }\n\n /**\n * Position settings menu relative to settings button (immediate/synchronous)\n */\n positionSettingsMenuImmediate() {\n if (!this.settingsMenu || !this.settingsButton) return;\n \n // Get the parent container (header-left) which has position: relative\n const container = this.settingsButton.parentElement;\n if (!container) return;\n \n // Position immediately (synchronously) - used when menu is first shown\n const buttonRect = this.settingsButton.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect();\n const menuRect = this.settingsMenu.getBoundingClientRect();\n const viewportHeight = window.innerHeight;\n \n // Calculate position relative to the container\n const buttonLeft = buttonRect.left - containerRect.left;\n const buttonBottom = buttonRect.bottom - containerRect.top;\n const buttonTop = buttonRect.top - containerRect.top;\n \n const spaceBelow = viewportHeight - buttonRect.bottom;\n const spaceAbove = buttonRect.top;\n \n // Position menu below button by default (left-aligned with button)\n let menuTop = buttonBottom + 4;\n \n // Check if we should position above instead\n if (spaceBelow < menuRect.height + 20 && spaceAbove > spaceBelow) {\n // Position above the button\n menuTop = buttonTop - menuRect.height - 4;\n this.settingsMenu.classList.add('vidply-menu-above');\n } else {\n this.settingsMenu.classList.remove('vidply-menu-above');\n }\n \n // Apply positions (left-aligned with button)\n this.settingsMenu.style.top = `${menuTop}px`;\n this.settingsMenu.style.left = `${buttonLeft}px`;\n this.settingsMenu.style.right = 'auto';\n this.settingsMenu.style.bottom = 'auto';\n }\n \n /**\n * Position settings menu relative to settings button (async for repositioning)\n */\n positionSettingsMenu() {\n if (!this.settingsMenu || !this.settingsButton) return;\n \n // Use requestAnimationFrame to ensure layout is stable before positioning (for repositioning)\n requestAnimationFrame(() => {\n setTimeout(() => {\n this.positionSettingsMenuImmediate();\n }, 10); // Small delay to ensure layout is stable\n });\n }\n\n /**\n * Attach keyboard navigation to settings menu\n */\n attachSettingsMenuKeyboardNavigation() {\n if (!this.settingsMenu) return;\n \n // Remove existing handler if any\n if (this.settingsMenuKeyHandler) {\n this.settingsMenu.removeEventListener('keydown', this.settingsMenuKeyHandler, true);\n }\n \n const handler = attachMenuKeyboardNavigation(\n this.settingsMenu,\n this.settingsButton,\n `.${this.player.options.classPrefix}-transcript-settings-item`,\n () => this.hideSettingsMenu({ focusButton: true })\n );\n \n // Store the handler reference\n this.settingsMenuKeyHandler = handler;\n \n }\n\n /**\n * Hide settings menu\n */\n hideSettingsMenu({ focusButton = true } = {}) {\n if (this.settingsMenu) {\n this.settingsMenu.style.display = 'none';\n this.settingsMenuVisible = false;\n this.settingsMenuJustOpened = false;\n \n // Remove keyboard handler to prevent duplicate listeners\n if (this.settingsMenuKeyHandler) {\n this.settingsMenu.removeEventListener('keydown', this.settingsMenuKeyHandler, true);\n this.settingsMenuKeyHandler = null;\n }\n \n // Update aria-expanded\n if (this.settingsButton) {\n this.settingsButton.setAttribute('aria-expanded', 'false');\n if (focusButton) {\n // Return focus to settings button\n this.settingsButton.focus({ preventScroll: true });\n }\n }\n }\n }\n\n /**\n * Enable move mode (gives visual feedback)\n */\n enableMoveMode() {\n this.hideResizeModeIndicator();\n\n // Add visual feedback for move mode\n this.transcriptWindow.classList.add(`${this.player.options.classPrefix}-transcript-move-mode`);\n \n // Show tooltip about keyboard drag option\n const tooltip = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-move-tooltip`,\n textContent: 'Drag with mouse or press D for keyboard drag mode'\n });\n this.transcriptHeader.appendChild(tooltip);\n \n // Remove after 2 seconds\n setTimeout(() => {\n this.transcriptWindow.classList.remove(`${this.player.options.classPrefix}-transcript-move-mode`);\n if (tooltip.parentNode) {\n tooltip.remove();\n }\n }, 2000);\n }\n\n /**\n * Toggle resize mode\n */\n toggleResizeMode({ focus = true } = {}) {\n if (!this.draggableResizable) {\n return false;\n }\n\n if (this.draggableResizable.pointerResizeMode) {\n this.draggableResizable.disablePointerResizeMode({ focus });\n return false;\n }\n\n this.draggableResizable.enablePointerResizeMode({ focus });\n return true;\n }\n\n updateDragOptionState() {\n if (!this.dragOptionButton) {\n return;\n }\n \n const isEnabled = !!(this.draggableResizable && this.draggableResizable.keyboardDragMode);\n const text = isEnabled\n ? i18n.t('transcript.disableDragMode')\n : i18n.t('transcript.enableDragMode');\n const ariaLabel = isEnabled\n ? i18n.t('transcript.disableDragModeAria')\n : i18n.t('transcript.enableDragModeAria');\n\n this.dragOptionButton.setAttribute('aria-checked', isEnabled ? 'true' : 'false');\n this.dragOptionButton.setAttribute('aria-label', ariaLabel);\n\n if (this.dragOptionText) {\n this.dragOptionText.textContent = text;\n }\n }\n\n updateResizeOptionState() {\n if (!this.resizeOptionButton) {\n return;\n }\n \n const isEnabled = !!(this.draggableResizable && this.draggableResizable.pointerResizeMode);\n const text = isEnabled\n ? i18n.t('transcript.disableResizeMode')\n : i18n.t('transcript.enableResizeMode');\n const ariaLabel = isEnabled\n ? i18n.t('transcript.disableResizeModeAria')\n : i18n.t('transcript.enableResizeModeAria');\n\n this.resizeOptionButton.setAttribute('aria-checked', isEnabled ? 'true' : 'false');\n this.resizeOptionButton.setAttribute('aria-label', ariaLabel);\n\n if (this.resizeOptionText) {\n this.resizeOptionText.textContent = text;\n }\n }\n\n toggleShowTimestamps() {\n this.showTimestamps = !this.showTimestamps;\n this.updateShowTimestampsState();\n this.updateTimestampVisibility();\n this.saveTimestampsPreference();\n }\n\n updateShowTimestampsState() {\n if (!this.showTimestampsButton) {\n return;\n }\n \n const text = this.showTimestamps\n ? i18n.t('transcript.hideTimestamps')\n : i18n.t('transcript.showTimestamps');\n const ariaLabel = this.showTimestamps\n ? i18n.t('transcript.hideTimestampsAria')\n : i18n.t('transcript.showTimestampsAria');\n\n this.showTimestampsButton.setAttribute('aria-checked', this.showTimestamps ? 'true' : 'false');\n this.showTimestampsButton.setAttribute('aria-label', ariaLabel);\n\n if (this.showTimestampsText) {\n this.showTimestampsText.textContent = text;\n }\n }\n\n updateTimestampVisibility() {\n if (!this.transcriptContent) return;\n \n const timestamps = this.transcriptContent.querySelectorAll(`.${this.player.options.classPrefix}-transcript-time`);\n timestamps.forEach(timestamp => {\n timestamp.style.display = this.showTimestamps ? '' : 'none';\n });\n }\n\n saveTimestampsPreference() {\n const savedPreferences = this.storage.getTranscriptPreferences() || {};\n savedPreferences.showTimestamps = this.showTimestamps;\n this.storage.saveTranscriptPreferences(savedPreferences);\n }\n\n showResizeModeIndicator() {\n if (!this.transcriptHeader) {\n return;\n }\n\n this.hideResizeModeIndicator();\n\n const indicator = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-resize-tooltip`,\n textContent: i18n.t('transcript.resizeModeHint') || 'Resize handles enabled. Drag edges or corners to adjust. Press Esc or R to exit.'\n });\n\n this.transcriptHeader.appendChild(indicator);\n this.resizeModeIndicator = indicator;\n\n this.resizeModeIndicatorTimeout = this.setManagedTimeout(() => {\n this.hideResizeModeIndicator();\n }, 3000);\n }\n\n hideResizeModeIndicator() {\n if (this.resizeModeIndicatorTimeout) {\n this.clearManagedTimeout(this.resizeModeIndicatorTimeout);\n this.resizeModeIndicatorTimeout = null;\n }\n\n if (this.resizeModeIndicator && this.resizeModeIndicator.parentNode) {\n this.resizeModeIndicator.remove();\n }\n\n this.resizeModeIndicator = null;\n }\n\n onPointerResizeModeChange(enabled) {\n this.updateResizeOptionState();\n\n if (enabled) {\n this.showResizeModeIndicator();\n this.announceLive(i18n.t('transcript.resizeModeEnabled'));\n } else {\n this.hideResizeModeIndicator();\n this.announceLive(i18n.t('transcript.resizeModeDisabled'));\n }\n }\n\n /**\n * Show style dialog\n */\n showStyleDialog() {\n // If dialog already exists, just show it\n if (this.styleDialog) {\n this.styleDialog.style.display = 'block';\n this.styleDialogVisible = true;\n \n // Re-add keyboard handler\n if (this.handlers.styleDialogKeydown) {\n document.addEventListener('keydown', this.handlers.styleDialogKeydown);\n }\n \n // Set flag to prevent immediate closing from document click\n this.styleDialogJustOpened = true;\n setTimeout(() => {\n this.styleDialogJustOpened = false;\n }, 350);\n \n // Focus first control\n setTimeout(() => {\n const firstSelect = this.styleDialog.querySelector('select, input');\n if (firstSelect) {\n firstSelect.focus({ preventScroll: true });\n }\n }, 0);\n return;\n }\n\n // Create style dialog\n this.styleDialog = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-style-dialog`\n });\n\n // Dialog title\n const title = DOMUtils.createElement('h4', {\n textContent: i18n.t('transcript.styleTitle'),\n className: `${this.player.options.classPrefix}-transcript-style-title`\n });\n this.styleDialog.appendChild(title);\n\n // Font Size\n const fontSizeControl = this.createStyleSelectControl(\n i18n.t('captions.fontSize'),\n 'fontSize',\n [\n { label: i18n.t('fontSizes.small'), value: '90%' },\n { label: i18n.t('fontSizes.normal'), value: '100%' },\n { label: i18n.t('fontSizes.large'), value: '110%' },\n { label: i18n.t('fontSizes.xlarge'), value: '120%' }\n ]\n );\n this.styleDialog.appendChild(fontSizeControl);\n\n // Font Family\n const fontFamilyControl = this.createStyleSelectControl(\n i18n.t('captions.fontFamily'),\n 'fontFamily',\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 this.styleDialog.appendChild(fontFamilyControl);\n\n // Text Color\n const colorControl = this.createStyleColorControl(i18n.t('captions.color'), 'color');\n this.styleDialog.appendChild(colorControl);\n\n // Background Color\n const bgColorControl = this.createStyleColorControl(i18n.t('captions.backgroundColor'), 'backgroundColor');\n this.styleDialog.appendChild(bgColorControl);\n\n // Opacity\n const opacityControl = this.createStyleOpacityControl(i18n.t('captions.opacity'), 'opacity');\n this.styleDialog.appendChild(opacityControl);\n\n // Close button\n const closeBtn = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-transcript-style-close`,\n textContent: i18n.t('settings.close'),\n attributes: {\n 'type': 'button'\n }\n });\n closeBtn.addEventListener('click', () => this.hideStyleDialog());\n this.styleDialog.appendChild(closeBtn);\n\n // Keyboard navigation for style dialog\n this.handlers.styleDialogKeydown = (e) => {\n // Only handle keys when dialog is visible\n if (!this.styleDialogVisible) return;\n \n // ESC to close\n if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n this.hideStyleDialog();\n return;\n }\n \n // Tab navigation (allow default behavior but trap focus)\n if (e.key === 'Tab') {\n // Get all focusable elements\n const focusableElements = this.styleDialog.querySelectorAll(\n 'select, input, button'\n );\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n \n // Trap focus within dialog\n if (e.shiftKey && document.activeElement === firstElement) {\n e.preventDefault();\n lastElement.focus({ preventScroll: true });\n } else if (!e.shiftKey && document.activeElement === lastElement) {\n e.preventDefault();\n firstElement.focus({ preventScroll: true });\n }\n }\n };\n document.addEventListener('keydown', this.handlers.styleDialogKeydown);\n\n // Append to header left container (same as settings menu) for correct positioning\n if (this.headerLeft) {\n this.headerLeft.appendChild(this.styleDialog);\n } else {\n this.transcriptHeader.appendChild(this.styleDialog);\n }\n \n // Apply current styles\n this.applyTranscriptStyles();\n \n // Important: Set visible state and display before focusing\n this.styleDialogVisible = true;\n this.styleDialog.style.display = 'block';\n \n // Set flag to prevent immediate closing from document click\n this.styleDialogJustOpened = true;\n setTimeout(() => {\n this.styleDialogJustOpened = false;\n }, 350);\n \n // Focus first control for keyboard accessibility\n setTimeout(() => {\n const firstSelect = this.styleDialog.querySelector('select, input');\n if (firstSelect) {\n firstSelect.focus({ preventScroll: true });\n }\n }, 0);\n }\n\n /**\n * Hide style dialog\n */\n hideStyleDialog() {\n if (this.styleDialog) {\n this.styleDialog.style.display = 'none';\n this.styleDialogVisible = false;\n \n // Remove keyboard handler\n if (this.handlers.styleDialogKeydown) {\n document.removeEventListener('keydown', this.handlers.styleDialogKeydown);\n }\n \n // Return focus to settings button\n if (this.settingsButton) {\n this.settingsButton.focus({ preventScroll: true });\n }\n }\n }\n\n /**\n * Create style select control\n */\n createStyleSelectControl(label, property, options) {\n const group = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-style-group`\n });\n\n // Generate unique ID for the control\n const controlId = `${this.player.options.classPrefix}-transcript-${property}-${Date.now()}`;\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n attributes: {\n 'for': controlId\n }\n });\n group.appendChild(labelEl);\n\n const select = DOMUtils.createElement('select', {\n className: `${this.player.options.classPrefix}-transcript-style-select`,\n attributes: {\n 'id': controlId\n }\n });\n\n options.forEach(opt => {\n const option = DOMUtils.createElement('option', {\n textContent: opt.label,\n attributes: {\n 'value': opt.value\n }\n });\n if (this.transcriptStyle[property] === opt.value) {\n option.selected = true;\n }\n select.appendChild(option);\n });\n\n select.addEventListener('change', (e) => {\n this.transcriptStyle[property] = e.target.value;\n this.applyTranscriptStyles();\n this.savePreferences();\n });\n\n group.appendChild(select);\n return group;\n }\n\n /**\n * Create style color control\n */\n createStyleColorControl(label, property) {\n const group = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-style-group`\n });\n\n // Generate unique ID for the control\n const controlId = `${this.player.options.classPrefix}-transcript-${property}-${Date.now()}`;\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n attributes: {\n 'for': controlId\n }\n });\n group.appendChild(labelEl);\n\n const input = DOMUtils.createElement('input', {\n attributes: {\n 'id': controlId,\n 'type': 'color',\n 'value': this.transcriptStyle[property]\n },\n className: `${this.player.options.classPrefix}-transcript-style-color`\n });\n\n input.addEventListener('input', (e) => {\n this.transcriptStyle[property] = e.target.value;\n this.applyTranscriptStyles();\n this.savePreferences();\n });\n\n group.appendChild(input);\n return group;\n }\n\n /**\n * Create style opacity control\n */\n createStyleOpacityControl(label, property) {\n const group = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-style-group`\n });\n\n // Generate unique ID for the control\n const controlId = `${this.player.options.classPrefix}-transcript-${property}-${Date.now()}`;\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n attributes: {\n 'for': controlId\n }\n });\n group.appendChild(labelEl);\n\n const valueDisplay = DOMUtils.createElement('span', {\n textContent: Math.round(this.transcriptStyle[property] * 100) + '%',\n className: `${this.player.options.classPrefix}-transcript-style-value`\n });\n\n const input = DOMUtils.createElement('input', {\n attributes: {\n 'id': controlId,\n 'type': 'range',\n 'min': '0',\n 'max': '1',\n 'step': '0.1',\n 'value': String(this.transcriptStyle[property])\n },\n className: `${this.player.options.classPrefix}-transcript-style-range`\n });\n\n input.addEventListener('input', (e) => {\n const value = parseFloat(e.target.value);\n this.transcriptStyle[property] = value;\n valueDisplay.textContent = Math.round(value * 100) + '%';\n this.applyTranscriptStyles();\n this.savePreferences();\n });\n\n const inputContainer = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-style-range-container`\n });\n inputContainer.appendChild(input);\n inputContainer.appendChild(valueDisplay);\n\n group.appendChild(labelEl);\n group.appendChild(inputContainer);\n return group;\n }\n\n /**\n * Save transcript preferences to localStorage\n */\n savePreferences() {\n this.storage.saveTranscriptPreferences(this.transcriptStyle);\n }\n\n /**\n * Apply transcript styles\n */\n applyTranscriptStyles() {\n if (!this.transcriptWindow) return;\n\n // Apply to transcript window background\n this.transcriptWindow.style.backgroundColor = this.transcriptStyle.backgroundColor;\n this.transcriptWindow.style.opacity = String(this.transcriptStyle.opacity);\n\n // Apply to content area\n if (this.transcriptContent) {\n this.transcriptContent.style.fontSize = this.transcriptStyle.fontSize;\n this.transcriptContent.style.fontFamily = this.transcriptStyle.fontFamily;\n this.transcriptContent.style.color = this.transcriptStyle.color;\n }\n\n // Apply to all text entries (important: override CSS defaults)\n const textEntries = this.transcriptWindow.querySelectorAll(`.${this.player.options.classPrefix}-transcript-text`);\n textEntries.forEach(entry => {\n entry.style.fontSize = this.transcriptStyle.fontSize;\n entry.style.fontFamily = this.transcriptStyle.fontFamily;\n entry.style.color = this.transcriptStyle.color;\n });\n \n // Apply to timestamp entries as well\n const timeEntries = this.transcriptWindow.querySelectorAll(`.${this.player.options.classPrefix}-transcript-time`);\n timeEntries.forEach(entry => {\n entry.style.fontFamily = this.transcriptStyle.fontFamily;\n });\n }\n\n /**\n * Set a managed timeout that will be cleaned up on destroy\n * @param {Function} callback - Callback function\n * @param {number} delay - Delay in milliseconds\n * @returns {number} Timeout ID\n */\n setManagedTimeout(callback, delay) {\n const timeoutId = setTimeout(() => {\n this.timeouts.delete(timeoutId);\n callback();\n }, delay);\n this.timeouts.add(timeoutId);\n return timeoutId;\n }\n\n /**\n * Clear a managed timeout\n * @param {number} timeoutId - Timeout ID to clear\n */\n clearManagedTimeout(timeoutId) {\n if (timeoutId) {\n clearTimeout(timeoutId);\n this.timeouts.delete(timeoutId);\n }\n }\n\n /**\n * Cleanup\n */\n destroy() {\n this.hideResizeModeIndicator();\n \n // Destroy draggableResizable utility\n if (this.draggableResizable) {\n if (this.draggableResizable.pointerResizeMode) {\n this.draggableResizable.disablePointerResizeMode();\n this.updateResizeOptionState();\n }\n this.draggableResizable.destroy();\n this.draggableResizable = null;\n }\n \n // Remove custom key handler\n if (this.transcriptWindow && this.customKeyHandler) {\n this.transcriptWindow.removeEventListener('keydown', this.customKeyHandler);\n this.customKeyHandler = null;\n }\n\n // Remove timeupdate listener from player\n if (this.handlers.timeupdate) {\n this.player.off('timeupdate', this.handlers.timeupdate);\n }\n \n // Remove audio description listeners from player\n if (this.handlers.audiodescriptionenabled) {\n this.player.off('audiodescriptionenabled', this.handlers.audiodescriptionenabled);\n }\n if (this.handlers.audiodescriptiondisabled) {\n this.player.off('audiodescriptiondisabled', this.handlers.audiodescriptiondisabled);\n }\n \n // Remove settings button event listeners\n if (this.settingsButton) {\n if (this.handlers.settingsClick) {\n this.settingsButton.removeEventListener('click', this.handlers.settingsClick);\n }\n if (this.handlers.settingsKeydown) {\n this.settingsButton.removeEventListener('keydown', this.handlers.settingsKeydown);\n }\n }\n \n // Remove style dialog event listeners\n if (this.handlers.styleDialogKeydown) {\n document.removeEventListener('keydown', this.handlers.styleDialogKeydown);\n }\n\n // Remove document click listener\n if (this.handlers.documentClick) {\n document.removeEventListener('click', this.handlers.documentClick);\n }\n \n // Remove window-level listeners\n if (this.handlers.resize) {\n window.removeEventListener('resize', this.handlers.resize);\n }\n\n // Cleanup all managed timeouts\n this.timeouts.forEach(timeoutId => clearTimeout(timeoutId));\n this.timeouts.clear();\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 this.settingsMenu = null;\n this.styleDialog = null;\n this.transcriptResizeHandles = [];\n this.resizeOptionButton = null;\n this.resizeOptionText = null;\n this.liveRegion = null;\n }\n\n announceLive(message) {\n if (!this.liveRegion) return;\n this.liveRegion.textContent = message || '';\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/utils/DOMUtils.js", "../../src/i18n/languages/en.js", "../../src/i18n/translations.js", "../../src/i18n/i18n.js", "../../src/utils/TimeUtils.js", "../../src/icons/Icons.js", "../../src/utils/FocusUtils.js", "../../src/utils/StorageManager.js", "../../src/utils/DraggableResizable.js", "../../src/utils/MenuUtils.js", "../../src/utils/FormUtils.js"],
|
|
4
|
-
"sourcesContent": ["/**\r\n * DOM manipulation utilities\r\n */\r\n\r\nexport const DOMUtils = {\r\n createElement(tag, options = {}) {\r\n const element = document.createElement(tag);\r\n \r\n if (options.className) {\r\n element.className = options.className;\r\n }\r\n \r\n if (options.attributes) {\r\n Object.entries(options.attributes).forEach(([key, value]) => {\r\n element.setAttribute(key, value);\r\n });\r\n }\r\n \r\n if (options.innerHTML) {\r\n element.innerHTML = options.innerHTML;\r\n }\r\n \r\n if (options.textContent) {\r\n element.textContent = options.textContent;\r\n }\r\n \r\n if (options.style) {\r\n Object.assign(element.style, options.style);\r\n }\r\n \r\n if (options.children) {\r\n options.children.forEach(child => {\r\n if (child) element.appendChild(child);\r\n });\r\n }\r\n \r\n return element;\r\n },\r\n\r\n addClass(element, className) {\r\n if (element && className) {\r\n element.classList.add(className);\r\n }\r\n },\r\n\r\n removeClass(element, className) {\r\n if (element && className) {\r\n element.classList.remove(className);\r\n }\r\n },\r\n\r\n toggleClass(element, className) {\r\n if (element && className) {\r\n element.classList.toggle(className);\r\n }\r\n },\r\n\r\n hasClass(element, className) {\r\n return element && element.classList.contains(className);\r\n },\r\n\r\n show(element) {\r\n if (element) {\r\n element.style.display = '';\r\n }\r\n },\r\n\r\n hide(element) {\r\n if (element) {\r\n element.style.display = 'none';\r\n }\r\n },\r\n\r\n fadeIn(element, duration = 300) {\r\n if (!element) return;\r\n \r\n element.style.opacity = '0';\r\n element.style.display = '';\r\n \r\n let start = null;\r\n const animate = (timestamp) => {\r\n if (!start) start = timestamp;\r\n const progress = timestamp - start;\r\n const opacity = Math.min(progress / duration, 1);\r\n \r\n element.style.opacity = opacity;\r\n \r\n if (progress < duration) {\r\n requestAnimationFrame(animate);\r\n }\r\n };\r\n \r\n requestAnimationFrame(animate);\r\n },\r\n\r\n fadeOut(element, duration = 300) {\r\n if (!element) return;\r\n \r\n const startOpacity = parseFloat(getComputedStyle(element).opacity) || 1;\r\n let start = null;\r\n \r\n const animate = (timestamp) => {\r\n if (!start) start = timestamp;\r\n const progress = timestamp - start;\r\n const opacity = Math.max(startOpacity - (progress / duration), 0);\r\n \r\n element.style.opacity = opacity;\r\n \r\n if (progress < duration) {\r\n requestAnimationFrame(animate);\r\n } else {\r\n element.style.display = 'none';\r\n }\r\n };\r\n \r\n requestAnimationFrame(animate);\r\n },\r\n\r\n offset(element) {\r\n if (!element) return { top: 0, left: 0 };\r\n \r\n const rect = element.getBoundingClientRect();\r\n return {\r\n top: rect.top + window.pageYOffset,\r\n left: rect.left + window.pageXOffset,\r\n width: rect.width,\r\n height: rect.height\r\n };\r\n },\r\n\r\n escapeHTML(str) {\r\n const div = document.createElement('div');\r\n div.textContent = str;\r\n return div.innerHTML;\r\n },\r\n\r\n sanitizeHTML(html) {\r\n // Basic HTML sanitization - allow safe tags for VTT captions\r\n // Since we control the HTML (from VTT parsing), we can safely allow these tags\r\n const temp = document.createElement('div');\r\n \r\n // Strip out any potentially dangerous tags/attributes\r\n // Allow: strong, em, u, span, b, i with class and data-voice attributes\r\n const safeHtml = html\r\n .replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '')\r\n .replace(/<iframe\\b[^<]*(?:(?!<\\/iframe>)<[^<]*)*<\\/iframe>/gi, '')\r\n .replace(/on\\w+\\s*=/gi, '') // Remove event handlers\r\n .replace(/javascript:/gi, ''); // Remove javascript: protocol\r\n \r\n temp.innerHTML = safeHtml;\r\n return temp.innerHTML;\r\n },\r\n\r\n /**\r\n * Create a tooltip element that is aria-hidden (not read by screen readers)\r\n * @param {string} text - Tooltip text\r\n * @param {string} classPrefix - Class prefix for styling\r\n * @returns {HTMLElement} Tooltip element\r\n */\r\n createTooltip(text, classPrefix = 'vidply') {\r\n const tooltip = this.createElement('span', {\r\n className: `${classPrefix}-tooltip`,\r\n textContent: text,\r\n attributes: {\r\n 'aria-hidden': 'true'\r\n }\r\n });\r\n return tooltip;\r\n },\r\n\r\n /**\r\n * Attach a tooltip to an element\r\n * @param {HTMLElement} element - Element to attach tooltip to\r\n * @param {string} text - Tooltip text\r\n * @param {string} classPrefix - Class prefix for styling\r\n */\r\n attachTooltip(element, text, classPrefix = 'vidply') {\r\n if (!element || !text) return;\r\n \r\n // Remove existing tooltip if any\r\n const existingTooltip = element.querySelector(`.${classPrefix}-tooltip`);\r\n if (existingTooltip) {\r\n existingTooltip.remove();\r\n }\r\n \r\n const tooltip = this.createTooltip(text, classPrefix);\r\n element.appendChild(tooltip);\r\n \r\n // Show tooltip on hover/focus\r\n const showTooltip = () => {\r\n tooltip.classList.add(`${classPrefix}-tooltip-visible`);\r\n };\r\n \r\n const hideTooltip = () => {\r\n tooltip.classList.remove(`${classPrefix}-tooltip-visible`);\r\n };\r\n \r\n element.addEventListener('mouseenter', showTooltip);\r\n element.addEventListener('mouseleave', hideTooltip);\r\n element.addEventListener('focus', showTooltip);\r\n element.addEventListener('blur', hideTooltip);\r\n },\r\n\r\n /**\r\n * Create visible button text that is hidden by CSS but visible when CSS is disabled\r\n * @param {string} text - Button text\r\n * @param {string} classPrefix - Class prefix for styling\r\n * @returns {HTMLElement} Button text element\r\n */\r\n createButtonText(text, classPrefix = 'vidply') {\r\n const buttonText = this.createElement('span', {\r\n className: `${classPrefix}-button-text`,\r\n textContent: text,\r\n attributes: {\r\n 'aria-hidden': 'true'\r\n }\r\n });\r\n return buttonText;\r\n }\r\n};\r\n\r\n", "/**\r\n * English translations for VidPly\r\n */\r\n\r\nexport const en = {\r\n player: {\r\n label: 'Video Player',\r\n play: 'Play',\r\n pause: 'Pause',\r\n stop: 'Stop',\r\n restart: 'Restart from beginning',\r\n rewind: 'Rewind',\r\n forward: 'Forward',\r\n rewindSeconds: 'Rewind {seconds} seconds',\r\n forwardSeconds: 'Forward {seconds} seconds',\r\n previous: 'Previous track',\r\n next: 'Next track',\r\n playlist: 'Toggle playlist',\r\n volume: 'Volume',\r\n mute: 'Mute',\r\n unmute: 'Unmute',\r\n fullscreen: 'Fullscreen',\r\n exitFullscreen: 'Exit Fullscreen',\r\n captions: 'Captions',\r\n chapters: 'Chapters',\r\n quality: 'Quality',\r\n captionStyling: 'Caption styling',\r\n transcript: 'Toggle transcript',\r\n audioDescription: 'Audio description',\r\n signLanguage: 'Sign language video',\r\n settings: 'Settings',\r\n speed: 'Playback Speed',\r\n pip: 'Picture in Picture',\r\n currentTime: 'Current time',\r\n duration: 'Duration',\r\n progress: 'Progress',\r\n seekForward: 'Seek forward {seconds} seconds',\r\n seekBackward: 'Seek backward {seconds} seconds',\r\n volumeUp: 'Volume up',\r\n volumeDown: 'Volume down',\r\n loading: 'Loading...',\r\n loadingChapters: 'Loading chapters...',\r\n error: 'Error loading media',\r\n buffering: 'Buffering...',\r\n signLanguageVideo: 'Sign Language Video',\r\n closeSignLanguage: 'Close sign language video',\r\n signLanguageSettings: 'Sign language settings',\r\n noChapters: 'No chapters available',\r\n noCaptions: 'No captions available',\r\n auto: 'Auto',\r\n autoQuality: 'Auto (no quality selection available)',\r\n noQuality: 'Quality selection not available',\r\n signLanguageDragResize: 'Sign Language Video - Press D to drag with keyboard, R to resize',\r\n signLanguageDragActive: 'Sign Language Video - Drag mode active. Use arrow keys to move, Escape to exit.',\r\n signLanguageResizeActive: 'Sign Language Video - Resize mode active. Use left/right arrow keys to resize, Escape to exit.',\r\n enableSignDragMode: 'Enable drag mode. Shortcut: D key',\r\n disableSignDragMode: 'Disable drag mode. Shortcut: D key',\r\n enableSignDragModeAria: 'Enable toggle keyboard drag mode with arrow keys. Shortcut: D key',\r\n disableSignDragModeAria: 'Disable toggle keyboard drag mode with arrow keys. Shortcut: D key',\r\n enableSignResizeMode: 'Enable resize mode. Shortcut: R key',\r\n disableSignResizeMode: 'Disable resize mode. Shortcut: R key',\r\n enableSignResizeModeAria: 'Enable keyboard resize mode with arrow keys. Shortcut: R key',\r\n disableSignResizeModeAria: 'Disable keyboard resize mode with arrow keys. Shortcut: R key',\r\n resizeHandle: 'Resize {direction} corner',\r\n moreOptions: 'More options',\r\n noMoreOptions: 'No additional options available'\r\n },\r\n captions: {\r\n off: 'Off',\r\n select: 'Select captions',\r\n fontSize: 'Font Size',\r\n fontFamily: 'Font Family',\r\n color: 'Text Color',\r\n backgroundColor: 'Background Color',\r\n opacity: 'Opacity'\r\n },\r\n fontSizes: {\r\n small: 'Small',\r\n normal: 'Normal',\r\n large: 'Large',\r\n xlarge: 'X-Large'\r\n },\r\n fontFamilies: {\r\n sansSerif: 'Sans-serif',\r\n serif: 'Serif',\r\n monospace: 'Monospace'\r\n },\r\n styleLabels: {\r\n textColor: 'Text Color',\r\n background: 'Background',\r\n font: 'Font',\r\n fontSize: 'Font Size',\r\n opacity: 'Opacity'\r\n },\r\n audioDescription: {\r\n enable: 'Enable audio description',\r\n disable: 'Disable audio description'\r\n },\r\n signLanguage: {\r\n show: 'Show sign language video',\r\n hide: 'Hide sign language video'\r\n },\r\n transcript: {\r\n title: 'Transcript',\r\n close: 'Close transcript',\r\n loading: 'Loading transcript...',\r\n noTranscript: 'No transcript available for this video.',\r\n settings: 'Transcript settings. Press Enter to open menu, or D to enable drag mode',\r\n keyboardDragMode: 'Toggle keyboard drag mode with arrow keys. Shortcut: D key',\r\n keyboardDragActive: '⌨️ Keyboard Drag Mode Active (Arrow keys to move, Shift+Arrows for large steps, D or ESC to exit)',\r\n dragResizePrompt: 'Press D to drag or R to resize. Use Home to reset position, Esc to close.',\r\n dragModeEnabled: 'Keyboard drag mode enabled. Use arrow keys to move, Shift+Arrow for larger steps. Press D or Esc to exit.',\r\n dragModeDisabled: 'Keyboard drag mode disabled.',\r\n enableDragMode: 'Enable drag mode. Shortcut: D key',\r\n disableDragMode: 'Disable drag mode. Shortcut: D key',\r\n enableDragModeAria: 'Enable toggle keyboard drag mode with arrow keys. Shortcut: D key',\r\n disableDragModeAria: 'Disable toggle keyboard drag mode with arrow keys. Shortcut: D key',\r\n resizeWindow: 'Resize Window',\r\n disableResizeWindow: 'Disable Resize Mode',\r\n enableResizeMode: 'Enable resize mode. Shortcut: R key',\r\n disableResizeMode: 'Disable resize mode. Shortcut: R key',\r\n enableResizeModeAria: 'Enable keyboard resize mode with arrow keys. Shortcut: R key',\r\n disableResizeModeAria: 'Disable keyboard resize mode with arrow keys. Shortcut: R key',\r\n resizeModeHint: 'Resize handles enabled. Drag edges or corners to adjust. Press Esc or R to exit.',\r\n resizeModeEnabled: 'Resize mode enabled. Drag edges or corners to adjust. Press Esc or R to exit.',\r\n resizeModeDisabled: 'Resize mode disabled.',\r\n positionReset: 'Transcript position reset.',\r\n styleTranscript: 'Open transcript style settings',\r\n closeMenu: 'Close Menu',\r\n styleTitle: 'Transcript Style',\r\n autoscroll: 'Autoscroll',\r\n settingsMenu: 'Transcript dialog settings',\r\n showTimestamps: 'Show timestamps',\r\n hideTimestamps: 'Hide timestamps',\r\n showTimestampsAria: 'Show timestamps in transcript',\r\n hideTimestampsAria: 'Hide timestamps in transcript'\r\n },\r\n settings: {\r\n title: 'Settings',\r\n quality: 'Quality',\r\n speed: 'Speed',\r\n captions: 'Captions',\r\n language: 'Language',\r\n reset: 'Reset to defaults',\r\n close: 'Close'\r\n },\r\n speeds: {\r\n normal: 'Normal'\r\n },\r\n time: {\r\n display: 'Time display',\r\n durationPrefix: 'Duration: ',\r\n of: 'of',\r\n hour: '{count} hour',\r\n hours: '{count} hours',\r\n minute: '{count} minute',\r\n minutes: '{count} minutes',\r\n second: '{count} second',\r\n seconds: '{count} seconds'\r\n },\r\n playlist: {\r\n title: 'Playlist',\r\n trackOf: 'Track {current} of {total}',\r\n nowPlaying: 'Now playing: Track {current} of {total}. {title}{artist}',\r\n by: ' by ',\r\n untitled: 'Untitled',\r\n trackUntitled: 'Track {number}',\r\n currentlyPlaying: 'Currently playing',\r\n notPlaying: 'Not playing',\r\n pressEnterPlay: 'Press Enter to play',\r\n pressEnterRestart: 'Press Enter to restart'\r\n }\r\n};\r\n\r\n", "/**\r\n * Translation strings for VidPly\r\n * Lazily loads built-in language files to keep the base bundle small.\r\n */\r\n\r\nimport { en } from './languages/en.js';\r\n\r\nconst builtInLanguageLoaders = {\r\n de: () => import('./languages/de.js'),\r\n es: () => import('./languages/es.js'),\r\n fr: () => import('./languages/fr.js'),\r\n ja: () => import('./languages/ja.js')\r\n};\r\n\r\n/**\r\n * Returns the base translations that are always available in the bundle.\r\n * Currently this is English-only to minimize bundle size.\r\n */\r\nexport function getBaseTranslations() {\r\n return { en };\r\n}\r\n\r\n/**\r\n * Expose built-in language loaders so they can be loaded on demand.\r\n */\r\nexport function getBuiltInLanguageLoaders() {\r\n return builtInLanguageLoaders;\r\n}\r\n\r\n/**\r\n * Load a single built-in language asynchronously.\r\n * @param {string} lang Language code to load\r\n * @returns {Promise<Object|null>} Loaded translation object or null if unavailable\r\n */\r\nexport async function loadBuiltInTranslation(lang) {\r\n const loader = builtInLanguageLoaders[lang];\r\n if (!loader) return null;\r\n\r\n const module = await loader();\r\n return module[lang] || module.default || null;\r\n}\r\n\r\n/**\r\n * Legacy export for backwards compatibility (keeps API surface stable)\r\n * Note: Only English is included by default; other languages are loaded on demand.\r\n */\r\nexport const translations = getBaseTranslations();\r\n\r\n", "/**\r\n * Internationalization system\r\n */\r\n\r\nimport { getBaseTranslations, getBuiltInLanguageLoaders, loadBuiltInTranslation } from './translations.js';\r\n\r\nclass I18n {\r\n constructor() {\r\n this.currentLanguage = 'en';\r\n this.translations = getBaseTranslations();\r\n this.loadingPromises = new Map(); // Cache for loading promises\r\n this.builtInLanguageLoaders = getBuiltInLanguageLoaders();\r\n }\r\n\r\n setLanguage(lang) {\r\n if (this.translations[lang]) {\r\n this.currentLanguage = lang;\r\n } else {\r\n console.warn(`Language \"${lang}\" not found, falling back to English`);\r\n this.currentLanguage = 'en';\r\n }\r\n }\r\n\r\n getLanguage() {\r\n return this.currentLanguage;\r\n }\r\n\r\n /**\r\n * Ensure a language is available, loading built-ins on demand.\r\n * @param {string} lang Language code\r\n * @returns {Promise<string|null>} Normalized language code if available\r\n */\r\n async ensureLanguage(lang) {\r\n const normalizedLang = (lang || '').toLowerCase();\r\n if (!normalizedLang) return this.currentLanguage;\r\n\r\n if (this.translations[normalizedLang]) {\r\n return normalizedLang;\r\n }\r\n\r\n if (this.loadingPromises.has(normalizedLang)) {\r\n await this.loadingPromises.get(normalizedLang);\r\n return this.translations[normalizedLang] ? normalizedLang : null;\r\n }\r\n\r\n if (!this.builtInLanguageLoaders[normalizedLang]) {\r\n return null;\r\n }\r\n\r\n const loadPromise = (async () => {\r\n try {\r\n const loaded = await loadBuiltInTranslation(normalizedLang);\r\n if (loaded) {\r\n this.translations[normalizedLang] = loaded;\r\n }\r\n } catch (error) {\r\n console.warn(`Language \"${normalizedLang}\" failed to load:`, error);\r\n } finally {\r\n this.loadingPromises.delete(normalizedLang);\r\n }\r\n })();\r\n\r\n this.loadingPromises.set(normalizedLang, loadPromise);\r\n await loadPromise;\r\n\r\n return this.translations[normalizedLang] ? normalizedLang : null;\r\n }\r\n\r\n t(key, replacements = {}) {\r\n const keys = key.split('.');\r\n let value = this.translations[this.currentLanguage];\r\n \r\n for (const k of keys) {\r\n if (value && typeof value === 'object' && k in value) {\r\n value = value[k];\r\n } else {\r\n // Fallback to English\r\n value = this.translations.en;\r\n for (const fallbackKey of keys) {\r\n if (value && typeof value === 'object' && fallbackKey in value) {\r\n value = value[fallbackKey];\r\n } else {\r\n return key; // Return key if not found\r\n }\r\n }\r\n break;\r\n }\r\n }\r\n \r\n // Replace placeholders\r\n if (typeof value === 'string') {\r\n Object.entries(replacements).forEach(([placeholder, replacement]) => {\r\n value = value.replace(new RegExp(`{${placeholder}}`, 'g'), replacement);\r\n });\r\n }\r\n \r\n return value;\r\n }\r\n\r\n addTranslation(lang, translations) {\r\n if (!this.translations[lang]) {\r\n this.translations[lang] = {};\r\n }\r\n Object.assign(this.translations[lang], translations);\r\n }\r\n\r\n /**\r\n * Load a language file from a URL (JSON or YAML)\r\n * @param {string} langCode - Language code (e.g., 'pt', 'it')\r\n * @param {string} url - URL to the language file (JSON or YAML)\r\n * @returns {Promise<void>}\r\n */\r\n async loadLanguageFromUrl(langCode, url) {\r\n // Return cached promise if already loading\r\n if (this.loadingPromises.has(url)) {\r\n return this.loadingPromises.get(url);\r\n }\r\n\r\n const loadPromise = (async () => {\r\n try {\r\n const response = await fetch(url);\r\n if (!response.ok) {\r\n throw new Error(`Failed to load language file: ${response.statusText}`);\r\n }\r\n\r\n const contentType = response.headers.get('content-type') || '';\r\n let translations;\r\n\r\n const buffer = await response.arrayBuffer();\r\n const utf8Text = new TextDecoder('utf-8').decode(buffer);\r\n\r\n if (contentType.includes('application/json') || url.endsWith('.json')) {\r\n translations = JSON.parse(utf8Text);\r\n } else if (contentType.includes('text/yaml') || contentType.includes('application/x-yaml') || url.endsWith('.yaml') || url.endsWith('.yml')) {\r\n // For YAML, we'll need to parse it\r\n // Note: This requires a YAML parser library in production\r\n // For now, we'll try to parse as JSON first, then show a warning\r\n try {\r\n // Try JSON first (in case server sends JSON with YAML content-type)\r\n translations = JSON.parse(utf8Text);\r\n } catch (e) {\r\n // If JSON parsing fails, try to use a YAML parser if available\r\n if (typeof window !== 'undefined' && window.jsyaml) {\r\n translations = window.jsyaml.load(utf8Text);\r\n } else {\r\n console.warn('YAML parsing requires js-yaml library. Please include it or use JSON format.');\r\n throw new Error('YAML parsing not available. Please use JSON format or include js-yaml library.');\r\n }\r\n }\r\n } else {\r\n // Try to parse as JSON by default\r\n translations = JSON.parse(utf8Text);\r\n }\r\n\r\n this.addTranslation(langCode, translations);\r\n return translations;\r\n } catch (error) {\r\n console.error(`Error loading language file from ${url}:`, error);\r\n throw error;\r\n } finally {\r\n // Remove from cache after loading completes\r\n this.loadingPromises.delete(url);\r\n }\r\n })();\r\n\r\n this.loadingPromises.set(url, loadPromise);\r\n return loadPromise;\r\n }\r\n\r\n /**\r\n * Load multiple language files from URLs\r\n * @param {Object} languageMap - Object mapping language codes to URLs\r\n * @returns {Promise<void>}\r\n */\r\n async loadLanguagesFromUrls(languageMap) {\r\n const promises = Object.entries(languageMap).map(([langCode, url]) =>\r\n this.loadLanguageFromUrl(langCode, url)\r\n );\r\n await Promise.all(promises);\r\n }\r\n}\r\n\r\nexport const i18n = new I18n();\r\n\r\n", "/**\r\n * Time formatting and conversion utilities\r\n */\r\n\r\nimport {i18n} from '../i18n/i18n.js';\r\n\r\nexport const TimeUtils = {\r\n /**\r\n * Format seconds to time string (HH:MM:SS or MM:SS)\r\n */\r\n formatTime(seconds, alwaysShowHours = false) {\r\n if (!isFinite(seconds) || seconds < 0) {\r\n return alwaysShowHours ? '00:00:00' : '00:00';\r\n }\r\n \r\n const hours = Math.floor(seconds / 3600);\r\n const minutes = Math.floor((seconds % 3600) / 60);\r\n const secs = Math.floor(seconds % 60);\r\n \r\n const pad = (num) => String(num).padStart(2, '0');\r\n \r\n if (hours > 0 || alwaysShowHours) {\r\n return `${pad(hours)}:${pad(minutes)}:${pad(secs)}`;\r\n }\r\n \r\n return `${pad(minutes)}:${pad(secs)}`;\r\n },\r\n\r\n /**\r\n * Parse time string to seconds\r\n */\r\n parseTime(timeString) {\r\n const parts = timeString.split(':').map(p => parseInt(p, 10));\r\n \r\n if (parts.length === 3) {\r\n // HH:MM:SS\r\n return parts[0] * 3600 + parts[1] * 60 + parts[2];\r\n } else if (parts.length === 2) {\r\n // MM:SS\r\n return parts[0] * 60 + parts[1];\r\n } else if (parts.length === 1) {\r\n // SS\r\n return parts[0];\r\n }\r\n \r\n return 0;\r\n },\r\n\r\n /**\r\n * Format seconds to readable duration\r\n */\r\n formatDuration(seconds) {\r\n if (!isFinite(seconds) || seconds < 0) {\r\n return i18n.t('time.seconds', { count: 0 });\r\n }\r\n \r\n const hours = Math.floor(seconds / 3600);\r\n const minutes = Math.floor((seconds % 3600) / 60);\r\n const secs = Math.floor(seconds % 60);\r\n \r\n const parts = [];\r\n \r\n if (hours > 0) {\r\n const key = hours === 1 ? 'time.hour' : 'time.hours';\r\n parts.push(i18n.t(key, { count: hours }));\r\n }\r\n if (minutes > 0) {\r\n const key = minutes === 1 ? 'time.minute' : 'time.minutes';\r\n parts.push(i18n.t(key, { count: minutes }));\r\n }\r\n if (secs > 0 || parts.length === 0) {\r\n const key = secs === 1 ? 'time.second' : 'time.seconds';\r\n parts.push(i18n.t(key, { count: secs }));\r\n }\r\n \r\n return parts.join(', ');\r\n },\r\n\r\n /**\r\n * Format percentage\r\n */\r\n formatPercentage(value, total) {\r\n if (total === 0) return 0;\r\n return Math.round((value / total) * 100);\r\n }\r\n};\r\n\r\n", "/**\r\n * SVG Icon Library for VidPly\r\n * Optimized with common viewBox and fill attributes\r\n */\r\n\r\n// SVG paths only (viewBox and fill added by wrapper)\r\nconst iconPaths = {\r\n play: `<path d=\"M8 5v14l11-7z\"/>`,\r\n\r\n pause: `<path d=\"M6 4h4v16H6V4zm8 0h4v16h-4V4z\"/>`,\r\n\r\n stop: `<rect x=\"6\" y=\"6\" width=\"12\" height=\"12\"/>`,\r\n\r\n rewind: `<path d=\"M11 18V6l-8.5 6 8.5 6zm.5-6l8.5 6V6l-8.5 6z\"/>`,\r\n\r\n forward: `<path d=\"M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z\"/>`,\r\n\r\n skipPrevious: `<path d=\"M6 6h2v12H6V6zm3 6l8.5 6V6L9 12z\"/>`,\r\n\r\n skipNext: `<path d=\"M16 6h2v12h-2V6zM6 6l8.5 6L6 18V6z\"/>`,\r\n\r\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\"/>`,\r\n\r\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\"/>`,\r\n\r\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\"/>`,\r\n\r\n volumeLow: `<path d=\"M7 9v6h4l5 5V4l-5 5H7z\"/>`,\r\n\r\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\"/>`,\r\n\r\n fullscreen: `<path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\"/>`,\r\n\r\n fullscreenExit: `<path d=\"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z\"/>`,\r\n\r\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\"/>`,\r\n\r\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\"/>`,\r\n\r\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\"/>`,\r\n\r\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\"/>`,\r\n\r\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\"/>`,\r\n\r\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\"/>`,\r\n\r\n check: `<path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"/>`,\r\n\r\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\"/>`,\r\n\r\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\"/>`,\r\n\r\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\"/>`,\r\n\r\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\"/>`,\r\n\r\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\"/>`,\r\n\r\n chapters: `<path d=\"M3 5h2v2H3V5zm0 4h2v2H3V9zm0 4h2v2H3v-2zm0 4h2v2H3v-2zM7 5h14v2H7V5zm0 4h14v2H7V9zm0 4h14v2H7v-2zm0 4h14v2H7v-2z\"/>`,\r\n\r\n audioDescription: `<rect x=\"2\" y=\"5\" width=\"20\" height=\"14\" rx=\"2\" fill=\"#ffffff\" stroke=\"#ffffff\" stroke-width=\"2\"/><text x=\"12\" y=\"16\" font-family=\"Arial, sans-serif\" font-size=\"10\" font-weight=\"bold\" text-anchor=\"middle\" fill=\"#1a1a1a\">AD</text>`,\r\n \r\n audioDescriptionOn: `<rect x=\"2\" y=\"5\" width=\"20\" height=\"14\" rx=\"2\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"/><text x=\"12\" y=\"16\" font-family=\"Arial, sans-serif\" font-size=\"10\" font-weight=\"bold\" text-anchor=\"middle\" fill=\"currentColor\">AD</text>`,\r\n\r\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>`,\r\n\r\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>`,\r\n\r\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\"/>`,\r\n\r\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\"/>`,\r\n\r\n move: `<path d=\"M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z\"/>`,\r\n\r\n resize: `<path d=\"M21.71 11.29l-9-9c-.39-.39-1.02-.39-1.41 0l-9 9c-.39.39-.39 1.02 0 1.41l9 9c.39.39 1.02.39 1.41 0l9-9c.39-.38.39-1.01 0-1.41zM14 14.5V12h-4v2.5L7 11l3-3.5V10h4V7.5l3 3.5-3 3.5z\"/>`,\r\n\r\n clock: `<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 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z\"/><path d=\"M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z\"/>`\r\n};\r\n\r\n// Optimized wrapper that adds common SVG attributes\r\nconst svgWrapper = (paths) => `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\">${paths}</svg>`;\r\n\r\n// Export Icons object with SVG wrappers\r\nexport const Icons = Object.fromEntries(\r\n Object.entries(iconPaths).map(([key, value]) => [key, svgWrapper(value)])\r\n);\r\n\r\nexport function getIcon(name) {\r\n return Icons[name] || Icons.play;\r\n}\r\n\r\nexport function createIconElement(name, className = '') {\r\n const wrapper = document.createElement('span');\r\n wrapper.className = `vidply-icon ${className}`.trim();\r\n wrapper.innerHTML = getIcon(name);\r\n wrapper.setAttribute('aria-hidden', 'true');\r\n return wrapper;\r\n}\r\n\r\n/**\r\n * Create the large centered play button overlay (complete SVG)\r\n * @returns {SVGElement} Complete SVG element with circle background and play icon\r\n */\r\nexport function createPlayOverlay() {\r\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\r\n svg.setAttribute('class', 'vidply-play-overlay');\r\n svg.setAttribute('viewBox', '0 0 80 80');\r\n svg.setAttribute('width', '80');\r\n svg.setAttribute('height', '80');\r\n svg.setAttribute('aria-hidden', 'true');\r\n svg.setAttribute('role', 'presentation');\r\n svg.style.cursor = 'pointer';\r\n\r\n // Create filter for drop shadow\r\n const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\r\n const filterId = `vidply-play-shadow-${Math.random().toString(36).substr(2, 9)}`;\r\n const filter = document.createElementNS('http://www.w3.org/2000/svg', 'filter');\r\n filter.setAttribute('id', filterId);\r\n filter.setAttribute('x', '-50%');\r\n filter.setAttribute('y', '-50%');\r\n filter.setAttribute('width', '200%');\r\n filter.setAttribute('height', '200%');\r\n\r\n const feGaussianBlur = document.createElementNS('http://www.w3.org/2000/svg', 'feGaussianBlur');\r\n feGaussianBlur.setAttribute('in', 'SourceAlpha');\r\n feGaussianBlur.setAttribute('stdDeviation', '3');\r\n\r\n const feOffset = document.createElementNS('http://www.w3.org/2000/svg', 'feOffset');\r\n feOffset.setAttribute('dx', '0');\r\n feOffset.setAttribute('dy', '2');\r\n feOffset.setAttribute('result', 'offsetblur');\r\n\r\n const feComponentTransfer = document.createElementNS('http://www.w3.org/2000/svg', 'feComponentTransfer');\r\n const feFuncA = document.createElementNS('http://www.w3.org/2000/svg', 'feFuncA');\r\n feFuncA.setAttribute('type', 'linear');\r\n feFuncA.setAttribute('slope', '0.3');\r\n feComponentTransfer.appendChild(feFuncA);\r\n\r\n const feMerge = document.createElementNS('http://www.w3.org/2000/svg', 'feMerge');\r\n const feMergeNode1 = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');\r\n const feMergeNode2 = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');\r\n feMergeNode2.setAttribute('in', 'SourceGraphic');\r\n feMerge.appendChild(feMergeNode1);\r\n feMerge.appendChild(feMergeNode2);\r\n\r\n filter.appendChild(feGaussianBlur);\r\n filter.appendChild(feOffset);\r\n filter.appendChild(feComponentTransfer);\r\n filter.appendChild(feMerge);\r\n defs.appendChild(filter);\r\n svg.appendChild(defs);\r\n\r\n // White circle background\r\n const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\r\n circle.setAttribute('cx', '40');\r\n circle.setAttribute('cy', '40');\r\n circle.setAttribute('r', '40');\r\n circle.setAttribute('fill', 'rgba(255, 255, 255, 0.95)');\r\n circle.setAttribute('filter', `url(#${filterId})`);\r\n circle.setAttribute('class', 'vidply-play-overlay-bg');\r\n svg.appendChild(circle);\r\n\r\n // Play icon triangle (centered with optical adjustment)\r\n const playTriangle = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');\r\n playTriangle.setAttribute('points', '32,28 32,52 54,40');\r\n playTriangle.setAttribute('fill', '#0a406e');\r\n playTriangle.setAttribute('class', 'vidply-play-overlay-icon');\r\n svg.appendChild(playTriangle);\r\n\r\n return svg;\r\n}\r\n\r\n", "/**\r\n * Focus management utilities\r\n */\r\n\r\n/**\r\n * Safely focus an element after DOM updates\r\n * @param {HTMLElement} element - Element to focus\r\n * @param {Object} options - Focus options\r\n * @param {number} options.delay - Delay in milliseconds (default: 0)\r\n * @param {boolean} options.preventScroll - Prevent scroll on focus (default: true)\r\n */\r\nexport function focusElement(element, { delay = 0, preventScroll = true } = {}) {\r\n if (!element) return;\r\n \r\n requestAnimationFrame(() => {\r\n setTimeout(() => {\r\n if (element && document.contains(element)) {\r\n element.focus({ preventScroll });\r\n }\r\n }, delay);\r\n });\r\n}\r\n\r\n/**\r\n * Focus first element matching selector in container\r\n * @param {HTMLElement} container - Container to search in\r\n * @param {string} selector - CSS selector\r\n * @param {Object} options - Focus options\r\n */\r\nexport function focusFirstElement(container, selector, options = {}) {\r\n if (!container) return;\r\n const element = container.querySelector(selector);\r\n if (element) {\r\n focusElement(element, options);\r\n }\r\n}\r\n\r\n", "/**\r\n * StorageManager - Handles persistent storage of user preferences\r\n */\r\n\r\nexport class StorageManager {\r\n constructor(namespace = 'vidply') {\r\n this.namespace = namespace;\r\n this.storage = this.isStorageAvailable() ? localStorage : null;\r\n }\r\n\r\n /**\r\n * Check if localStorage is available\r\n */\r\n isStorageAvailable() {\r\n try {\r\n const test = '__storage_test__';\r\n localStorage.setItem(test, test);\r\n localStorage.removeItem(test);\r\n return true;\r\n } catch (e) {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Get a namespaced key\r\n */\r\n getKey(key) {\r\n return `${this.namespace}_${key}`;\r\n }\r\n\r\n /**\r\n * Save a value to storage\r\n */\r\n set(key, value) {\r\n if (!this.storage) return false;\r\n \r\n try {\r\n const namespacedKey = this.getKey(key);\r\n this.storage.setItem(namespacedKey, JSON.stringify(value));\r\n return true;\r\n } catch (e) {\r\n console.warn('Failed to save to localStorage:', e);\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Get a value from storage\r\n */\r\n get(key, defaultValue = null) {\r\n if (!this.storage) return defaultValue;\r\n \r\n try {\r\n const namespacedKey = this.getKey(key);\r\n const value = this.storage.getItem(namespacedKey);\r\n return value ? JSON.parse(value) : defaultValue;\r\n } catch (e) {\r\n console.warn('Failed to read from localStorage:', e);\r\n return defaultValue;\r\n }\r\n }\r\n\r\n /**\r\n * Remove a value from storage\r\n */\r\n remove(key) {\r\n if (!this.storage) return false;\r\n \r\n try {\r\n const namespacedKey = this.getKey(key);\r\n this.storage.removeItem(namespacedKey);\r\n return true;\r\n } catch (e) {\r\n console.warn('Failed to remove from localStorage:', e);\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Clear all namespaced values\r\n */\r\n clear() {\r\n if (!this.storage) return false;\r\n \r\n try {\r\n const keys = Object.keys(this.storage);\r\n keys.forEach(key => {\r\n if (key.startsWith(this.namespace)) {\r\n this.storage.removeItem(key);\r\n }\r\n });\r\n return true;\r\n } catch (e) {\r\n console.warn('Failed to clear localStorage:', e);\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Save transcript preferences\r\n */\r\n saveTranscriptPreferences(preferences) {\r\n return this.set('transcript_preferences', preferences);\r\n }\r\n\r\n /**\r\n * Get transcript preferences\r\n */\r\n getTranscriptPreferences() {\r\n return this.get('transcript_preferences', null);\r\n }\r\n\r\n /**\r\n * Save caption preferences\r\n */\r\n saveCaptionPreferences(preferences) {\r\n return this.set('caption_preferences', preferences);\r\n }\r\n\r\n /**\r\n * Get caption preferences\r\n */\r\n getCaptionPreferences() {\r\n return this.get('caption_preferences', null);\r\n }\r\n\r\n /**\r\n * Save player preferences (volume, speed, etc.)\r\n */\r\n savePlayerPreferences(preferences) {\r\n return this.set('player_preferences', preferences);\r\n }\r\n\r\n /**\r\n * Get player preferences\r\n */\r\n getPlayerPreferences() {\r\n return this.get('player_preferences', null);\r\n }\r\n\r\n /**\r\n * Save sign language preferences (position and size)\r\n */\r\n saveSignLanguagePreferences(preferences) {\r\n return this.set('sign_language_preferences', preferences);\r\n }\r\n\r\n /**\r\n * Get sign language preferences\r\n */\r\n getSignLanguagePreferences() {\r\n return this.get('sign_language_preferences', null);\r\n }\r\n}\r\n\r\n", "/**\r\n * DraggableResizable Utility\r\n * Provides shared drag and resize functionality for floating windows/elements\r\n */\r\n\r\nexport class DraggableResizable {\r\n constructor(element, options = {}) {\r\n this.element = element;\r\n this.options = {\r\n dragHandle: null, // Element to use as drag handle (defaults to element itself)\r\n resizeHandles: [], // Array of resize handle elements\r\n onDragStart: null,\r\n onDrag: null,\r\n onDragEnd: null,\r\n onResizeStart: null,\r\n onResize: null,\r\n onResizeEnd: null,\r\n constrainToViewport: true, // Allow movement outside viewport?\r\n minWidth: 150,\r\n minHeight: 100,\r\n maintainAspectRatio: false,\r\n keyboardDragKey: 'd',\r\n keyboardResizeKey: 'r',\r\n keyboardStep: 5,\r\n keyboardStepLarge: 10,\r\n maxWidth: null,\r\n maxHeight: null,\r\n pointerResizeIndicatorText: null,\r\n onPointerResizeToggle: null,\r\n classPrefix: 'draggable',\r\n storage: null, // StorageManager instance for saving position/size\r\n storageKey: null, // Key for localStorage (if storage is provided)\r\n ...options\r\n };\r\n\r\n // State\r\n this.isDragging = false;\r\n this.isResizing = false;\r\n this.resizeDirection = null;\r\n this.dragOffsetX = 0;\r\n this.dragOffsetY = 0;\r\n this.positionOffsetX = 0;\r\n this.positionOffsetY = 0;\r\n this.initialMouseX = 0;\r\n this.initialMouseY = 0;\r\n this.needsPositionConversion = false;\r\n this.resizeStartX = 0;\r\n this.resizeStartY = 0;\r\n this.resizeStartWidth = 0;\r\n this.resizeStartHeight = 0;\r\n this.resizeStartLeft = 0;\r\n this.resizeStartTop = 0;\r\n this.keyboardDragMode = false;\r\n this.keyboardResizeMode = false;\r\n this.pointerResizeMode = false;\r\n this.manuallyPositioned = false; // Flag to track if user has manually moved/resized\r\n this.resizeHandlesManaged = new Map();\r\n this.resizeIndicatorElement = null;\r\n\r\n // Event handlers\r\n this.handlers = {\r\n mousedown: this.onMouseDown.bind(this),\r\n mousemove: this.onMouseMove.bind(this),\r\n mouseup: this.onMouseUp.bind(this),\r\n touchstart: this.onTouchStart.bind(this),\r\n touchmove: this.onTouchMove.bind(this),\r\n touchend: this.onTouchEnd.bind(this),\r\n keydown: this.onKeyDown.bind(this),\r\n resizeHandleMousedown: this.onResizeHandleMouseDown.bind(this)\r\n };\r\n\r\n this.init();\r\n }\r\n\r\n hasManagedResizeHandles() {\r\n return Array.from(this.resizeHandlesManaged.values()).some(Boolean);\r\n }\r\n\r\n storeOriginalHandleDisplay(handle) {\r\n if (!handle.dataset.originalDisplay) {\r\n handle.dataset.originalDisplay = handle.style.display || '';\r\n }\r\n }\r\n\r\n hideResizeHandle(handle) {\r\n handle.style.display = 'none';\r\n handle.setAttribute('aria-hidden', 'true');\r\n }\r\n\r\n showResizeHandle(handle) {\r\n const original = handle.dataset.originalDisplay !== undefined ? handle.dataset.originalDisplay : '';\r\n handle.style.display = original;\r\n handle.removeAttribute('aria-hidden');\r\n }\r\n\r\n setManagedHandlesVisible(visible) {\r\n if (!this.options.resizeHandles || this.options.resizeHandles.length === 0) {\r\n return;\r\n }\r\n\r\n this.options.resizeHandles.forEach(handle => {\r\n if (!this.resizeHandlesManaged.get(handle)) {\r\n return;\r\n }\r\n\r\n if (visible) {\r\n this.showResizeHandle(handle);\r\n } else {\r\n this.hideResizeHandle(handle);\r\n }\r\n });\r\n }\r\n\r\n init() {\r\n const dragHandle = this.options.dragHandle || this.element;\r\n \r\n // Drag events\r\n dragHandle.addEventListener('mousedown', this.handlers.mousedown);\r\n dragHandle.addEventListener('touchstart', this.handlers.touchstart);\r\n \r\n // Document-level move/up events\r\n document.addEventListener('mousemove', this.handlers.mousemove);\r\n document.addEventListener('mouseup', this.handlers.mouseup);\r\n document.addEventListener('touchmove', this.handlers.touchmove, { passive: false });\r\n document.addEventListener('touchend', this.handlers.touchend);\r\n \r\n // Keyboard events\r\n this.element.addEventListener('keydown', this.handlers.keydown);\r\n \r\n // Resize handles\r\n if (this.options.resizeHandles && this.options.resizeHandles.length > 0) {\r\n this.options.resizeHandles.forEach(handle => {\r\n handle.addEventListener('mousedown', this.handlers.resizeHandleMousedown);\r\n handle.addEventListener('touchstart', this.handlers.resizeHandleMousedown);\r\n\r\n const managed = handle.dataset.vidplyManagedResize === 'true';\r\n this.resizeHandlesManaged.set(handle, managed);\r\n if (managed) {\r\n this.storeOriginalHandleDisplay(handle);\r\n this.hideResizeHandle(handle);\r\n }\r\n });\r\n }\r\n }\r\n\r\n onMouseDown(e) {\r\n // Don't drag if clicking on resize handle\r\n if (e.target.classList.contains(`${this.options.classPrefix}-resize-handle`)) {\r\n return;\r\n }\r\n \r\n // Call custom handler if provided\r\n if (this.options.onDragStart && !this.options.onDragStart(e)) {\r\n return;\r\n }\r\n\r\n this.startDragging(e.clientX, e.clientY);\r\n e.preventDefault();\r\n }\r\n\r\n onTouchStart(e) {\r\n // Don't drag if touching resize handle\r\n if (e.target.classList.contains(`${this.options.classPrefix}-resize-handle`)) {\r\n return;\r\n }\r\n \r\n // Call custom handler if provided\r\n if (this.options.onDragStart && !this.options.onDragStart(e)) {\r\n return;\r\n }\r\n\r\n const touch = e.touches[0];\r\n this.startDragging(touch.clientX, touch.clientY);\r\n }\r\n\r\n onResizeHandleMouseDown(e) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n \r\n const handle = e.target;\r\n this.resizeDirection = handle.getAttribute('data-direction');\r\n \r\n const clientX = e.clientX || e.touches?.[0]?.clientX;\r\n const clientY = e.clientY || e.touches?.[0]?.clientY;\r\n \r\n this.startResizing(clientX, clientY);\r\n }\r\n\r\n onMouseMove(e) {\r\n if (this.isDragging) {\r\n this.drag(e.clientX, e.clientY);\r\n e.preventDefault();\r\n } else if (this.isResizing) {\r\n this.resize(e.clientX, e.clientY);\r\n e.preventDefault();\r\n }\r\n }\r\n\r\n onTouchMove(e) {\r\n if (this.isDragging || this.isResizing) {\r\n const touch = e.touches[0];\r\n if (this.isDragging) {\r\n this.drag(touch.clientX, touch.clientY);\r\n } else {\r\n this.resize(touch.clientX, touch.clientY);\r\n }\r\n e.preventDefault();\r\n }\r\n }\r\n\r\n onMouseUp() {\r\n if (this.isDragging) {\r\n this.stopDragging();\r\n } else if (this.isResizing) {\r\n this.stopResizing();\r\n }\r\n }\r\n\r\n onTouchEnd() {\r\n if (this.isDragging) {\r\n this.stopDragging();\r\n } else if (this.isResizing) {\r\n this.stopResizing();\r\n }\r\n }\r\n\r\n onKeyDown(e) {\r\n // Toggle drag mode\r\n if (e.key.toLowerCase() === this.options.keyboardDragKey.toLowerCase()) {\r\n e.preventDefault();\r\n this.toggleKeyboardDragMode();\r\n return;\r\n }\r\n\r\n // Toggle resize mode\r\n if (e.key.toLowerCase() === this.options.keyboardResizeKey.toLowerCase()) {\r\n e.preventDefault();\r\n if (this.hasManagedResizeHandles()) {\r\n this.togglePointerResizeMode();\r\n } else {\r\n this.toggleKeyboardResizeMode();\r\n }\r\n return;\r\n }\r\n\r\n // Exit modes with Escape\r\n if (e.key === 'Escape') {\r\n if (this.pointerResizeMode) {\r\n e.preventDefault();\r\n this.disablePointerResizeMode();\r\n return;\r\n }\r\n if (this.keyboardDragMode || this.keyboardResizeMode) {\r\n e.preventDefault();\r\n this.disableKeyboardDragMode();\r\n this.disableKeyboardResizeMode();\r\n return;\r\n }\r\n }\r\n\r\n // Arrow keys for drag/resize\r\n if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(e.key)) {\r\n if (this.keyboardDragMode) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n this.keyboardDrag(e.key, e.shiftKey);\r\n } else if (this.keyboardResizeMode) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n this.keyboardResize(e.key, e.shiftKey);\r\n }\r\n }\r\n\r\n // Home key to reset position\r\n if (e.key === 'Home' && (this.keyboardDragMode || this.keyboardResizeMode)) {\r\n e.preventDefault();\r\n this.resetPosition();\r\n }\r\n }\r\n\r\n startDragging(clientX, clientY) {\r\n // Get current rendered position BEFORE any changes\r\n const rect = this.element.getBoundingClientRect();\r\n \r\n // Convert position to left/top IMMEDIATELY (before setting any state)\r\n // Check if element is using right/bottom/transform positioning\r\n const computedStyle = window.getComputedStyle(this.element);\r\n const needsConversion = computedStyle.right !== 'auto' || \r\n computedStyle.bottom !== 'auto' || \r\n computedStyle.transform !== 'none';\r\n \r\n this.positionOffsetX = 0;\r\n this.positionOffsetY = 0;\r\n\r\n if (needsConversion) {\r\n // Determine the correct left/top values based on position type\r\n let targetLeft, targetTop;\r\n \r\n if (computedStyle.position === 'absolute') {\r\n // position: absolute uses container-relative coordinates\r\n const offsetParent = this.element.offsetParent || document.body;\r\n const parentRect = offsetParent.getBoundingClientRect();\r\n targetLeft = rect.left - parentRect.left;\r\n targetTop = rect.top - parentRect.top;\r\n this.positionOffsetX = parentRect.left;\r\n this.positionOffsetY = parentRect.top;\r\n } else if (computedStyle.position === 'fixed') {\r\n const parsedLeft = parseFloat(computedStyle.left);\r\n const parsedTop = parseFloat(computedStyle.top);\r\n const hasLeft = Number.isFinite(parsedLeft);\r\n const hasTop = Number.isFinite(parsedTop);\r\n targetLeft = hasLeft ? parsedLeft : rect.left;\r\n targetTop = hasTop ? parsedTop : rect.top;\r\n this.positionOffsetX = rect.left - targetLeft;\r\n this.positionOffsetY = rect.top - targetTop;\r\n } else {\r\n // fallback: treat as viewport-relative\r\n targetLeft = rect.left;\r\n targetTop = rect.top;\r\n this.positionOffsetX = rect.left - targetLeft;\r\n this.positionOffsetY = rect.top - targetTop;\r\n }\r\n \r\n // Build complete style update atomically\r\n const currentCssText = this.element.style.cssText;\r\n let newCssText = currentCssText\r\n .split(';')\r\n .filter(rule => {\r\n const trimmed = rule.trim();\r\n // Filter out empty rules\r\n if (!trimmed) return false;\r\n \r\n const colonIndex = trimmed.indexOf(':');\r\n if (colonIndex === -1) return false;\r\n \r\n const property = trimmed.substring(0, colonIndex).trim();\r\n const value = trimmed.substring(colonIndex + 1).trim();\r\n \r\n // Skip if value is empty or just whitespace (this catches empty border properties)\r\n if (!value || value === '') return false;\r\n \r\n // Skip positioning properties\r\n if (property === 'right' || property === 'bottom' || property === 'transform' ||\r\n property === 'left' || property === 'top' || property === 'inset') {\r\n return false;\r\n }\r\n \r\n // Skip border-image properties (these can have empty values that cause parse errors)\r\n if (property.startsWith('border-image')) {\r\n return false;\r\n }\r\n \r\n return true;\r\n })\r\n .join('; ');\r\n \r\n if (newCssText) newCssText += '; ';\r\n newCssText += `left: ${targetLeft}px; top: ${targetTop}px; right: auto; bottom: auto; transform: none`;\r\n \r\n // Apply all at once\r\n this.element.style.cssText = newCssText;\r\n }\r\n \r\n // Now calculate offsets based on CURRENT position (after conversion)\r\n // Re-get rect after potential position change\r\n const finalRect = this.element.getBoundingClientRect();\r\n this.dragOffsetX = clientX - finalRect.left;\r\n this.dragOffsetY = clientY - finalRect.top;\r\n \r\n this.isDragging = true;\r\n this.element.classList.add(`${this.options.classPrefix}-dragging`);\r\n document.body.style.cursor = 'grabbing';\r\n document.body.style.userSelect = 'none';\r\n }\r\n\r\n drag(clientX, clientY) {\r\n if (!this.isDragging) return;\r\n\r\n // Calculate new position: current mouse position minus the offset where user clicked\r\n let newX = clientX - this.dragOffsetX - this.positionOffsetX;\r\n let newY = clientY - this.dragOffsetY - this.positionOffsetY;\r\n \r\n // Constrain to viewport if needed\r\n if (this.options.constrainToViewport) {\r\n const rect = this.element.getBoundingClientRect();\r\n const viewportWidth = document.documentElement.clientWidth;\r\n const viewportHeight = document.documentElement.clientHeight;\r\n \r\n // Keep at least 100px visible\r\n const minVisible = 100;\r\n const minX = -(rect.width - minVisible);\r\n const minY = -(rect.height - minVisible);\r\n const maxX = viewportWidth - minVisible;\r\n const maxY = viewportHeight - minVisible;\r\n \r\n newX = Math.max(minX, Math.min(newX, maxX));\r\n newY = Math.max(minY, Math.min(newY, maxY));\r\n }\r\n \r\n this.element.style.left = `${newX}px`;\r\n this.element.style.top = `${newY}px`;\r\n \r\n // Call custom handler if provided\r\n if (this.options.onDrag) {\r\n this.options.onDrag({ x: newX, y: newY });\r\n }\r\n }\r\n\r\n stopDragging() {\r\n this.isDragging = false;\r\n this.element.classList.remove(`${this.options.classPrefix}-dragging`);\r\n document.body.style.cursor = '';\r\n document.body.style.userSelect = '';\r\n \r\n // Mark as manually positioned\r\n this.manuallyPositioned = true;\r\n \r\n // Call custom handler if provided\r\n if (this.options.onDragEnd) {\r\n this.options.onDragEnd();\r\n }\r\n }\r\n\r\n startResizing(clientX, clientY) {\r\n this.isResizing = true;\r\n this.resizeStartX = clientX;\r\n this.resizeStartY = clientY;\r\n \r\n const rect = this.element.getBoundingClientRect();\r\n this.resizeStartWidth = rect.width;\r\n this.resizeStartHeight = rect.height;\r\n this.resizeStartLeft = rect.left;\r\n this.resizeStartTop = rect.top;\r\n \r\n this.element.classList.add(`${this.options.classPrefix}-resizing`);\r\n document.body.style.userSelect = 'none';\r\n \r\n // Call custom handler if provided\r\n if (this.options.onResizeStart) {\r\n this.options.onResizeStart();\r\n }\r\n }\r\n\r\n resize(clientX, clientY) {\r\n if (!this.isResizing) return;\r\n\r\n const deltaX = clientX - this.resizeStartX;\r\n const deltaY = clientY - this.resizeStartY;\r\n \r\n let newWidth = this.resizeStartWidth;\r\n let newHeight = this.resizeStartHeight;\r\n let newLeft = this.resizeStartLeft;\r\n let newTop = this.resizeStartTop;\r\n\r\n // Handle horizontal resizing\r\n if (this.resizeDirection.includes('e')) {\r\n newWidth = Math.max(this.options.minWidth, this.resizeStartWidth + deltaX);\r\n }\r\n if (this.resizeDirection.includes('w')) {\r\n const proposedWidth = Math.max(this.options.minWidth, this.resizeStartWidth - deltaX);\r\n newLeft = this.resizeStartLeft + (this.resizeStartWidth - proposedWidth);\r\n newWidth = proposedWidth;\r\n }\r\n\r\n const maxWidthOption = typeof this.options.maxWidth === 'function'\r\n ? this.options.maxWidth()\r\n : this.options.maxWidth;\r\n if (Number.isFinite(maxWidthOption)) {\r\n const clampedWidth = Math.min(newWidth, maxWidthOption);\r\n if (clampedWidth !== newWidth && this.resizeDirection.includes('w')) {\r\n newLeft += newWidth - clampedWidth;\r\n }\r\n newWidth = clampedWidth;\r\n }\r\n\r\n // Handle vertical resizing (if not maintaining aspect ratio)\r\n if (!this.options.maintainAspectRatio) {\r\n if (this.resizeDirection.includes('s')) {\r\n newHeight = Math.max(this.options.minHeight, this.resizeStartHeight + deltaY);\r\n }\r\n if (this.resizeDirection.includes('n')) {\r\n const proposedHeight = Math.max(this.options.minHeight, this.resizeStartHeight - deltaY);\r\n newTop = this.resizeStartTop + (this.resizeStartHeight - proposedHeight);\r\n newHeight = proposedHeight;\r\n }\r\n\r\n const maxHeightOption = typeof this.options.maxHeight === 'function'\r\n ? this.options.maxHeight()\r\n : this.options.maxHeight;\r\n if (Number.isFinite(maxHeightOption)) {\r\n const clampedHeight = Math.min(newHeight, maxHeightOption);\r\n if (clampedHeight !== newHeight && this.resizeDirection.includes('n')) {\r\n newTop += newHeight - clampedHeight;\r\n }\r\n newHeight = clampedHeight;\r\n }\r\n }\r\n\r\n // Apply new dimensions\r\n this.element.style.width = `${newWidth}px`;\r\n if (!this.options.maintainAspectRatio) {\r\n this.element.style.height = `${newHeight}px`;\r\n } else {\r\n this.element.style.height = 'auto';\r\n }\r\n \r\n // Apply new position if resizing from west or north\r\n if (this.resizeDirection.includes('w')) {\r\n this.element.style.left = `${newLeft}px`;\r\n }\r\n if (this.resizeDirection.includes('n') && !this.options.maintainAspectRatio) {\r\n this.element.style.top = `${newTop}px`;\r\n }\r\n \r\n // Call custom handler if provided\r\n if (this.options.onResize) {\r\n this.options.onResize({ width: newWidth, height: newHeight, left: newLeft, top: newTop });\r\n }\r\n }\r\n\r\n stopResizing() {\r\n this.isResizing = false;\r\n this.resizeDirection = null;\r\n this.element.classList.remove(`${this.options.classPrefix}-resizing`);\r\n document.body.style.userSelect = '';\r\n \r\n // Mark as manually positioned\r\n this.manuallyPositioned = true;\r\n \r\n // Call custom handler if provided\r\n if (this.options.onResizeEnd) {\r\n this.options.onResizeEnd();\r\n }\r\n }\r\n\r\n toggleKeyboardDragMode() {\r\n if (this.keyboardDragMode) {\r\n this.disableKeyboardDragMode();\r\n } else {\r\n this.enableKeyboardDragMode();\r\n }\r\n }\r\n\r\n enableKeyboardDragMode() {\r\n this.keyboardDragMode = true;\r\n this.keyboardResizeMode = false;\r\n this.element.classList.add(`${this.options.classPrefix}-keyboard-drag`);\r\n this.element.classList.remove(`${this.options.classPrefix}-keyboard-resize`);\r\n this.focusElement();\r\n }\r\n\r\n disableKeyboardDragMode() {\r\n this.keyboardDragMode = false;\r\n this.element.classList.remove(`${this.options.classPrefix}-keyboard-drag`);\r\n }\r\n\r\n toggleKeyboardResizeMode() {\r\n if (this.keyboardResizeMode) {\r\n this.disableKeyboardResizeMode();\r\n } else {\r\n this.enableKeyboardResizeMode();\r\n }\r\n }\r\n\r\n enableKeyboardResizeMode() {\r\n this.keyboardResizeMode = true;\r\n this.keyboardDragMode = false;\r\n this.element.classList.add(`${this.options.classPrefix}-keyboard-resize`);\r\n this.element.classList.remove(`${this.options.classPrefix}-keyboard-drag`);\r\n this.focusElement();\r\n }\r\n\r\n disableKeyboardResizeMode() {\r\n this.keyboardResizeMode = false;\r\n this.element.classList.remove(`${this.options.classPrefix}-keyboard-resize`);\r\n }\r\n\r\n enablePointerResizeMode({ focus = true } = {}) {\r\n if (!this.hasManagedResizeHandles()) {\r\n this.enableKeyboardResizeMode();\r\n return;\r\n }\r\n\r\n if (this.pointerResizeMode) {\r\n return;\r\n }\r\n\r\n this.pointerResizeMode = true;\r\n this.setManagedHandlesVisible(true);\r\n this.element.classList.add(`${this.options.classPrefix}-resizable`);\r\n this.enableKeyboardResizeMode();\r\n\r\n if (focus) {\r\n this.focusElement();\r\n }\r\n\r\n if (typeof this.options.onPointerResizeToggle === 'function') {\r\n this.options.onPointerResizeToggle(true);\r\n }\r\n }\r\n\r\n disablePointerResizeMode({ focus = false } = {}) {\r\n if (!this.pointerResizeMode) {\r\n return;\r\n }\r\n\r\n this.pointerResizeMode = false;\r\n this.setManagedHandlesVisible(false);\r\n this.element.classList.remove(`${this.options.classPrefix}-resizable`);\r\n this.disableKeyboardResizeMode();\r\n\r\n if (focus) {\r\n this.focusElement();\r\n }\r\n\r\n if (typeof this.options.onPointerResizeToggle === 'function') {\r\n this.options.onPointerResizeToggle(false);\r\n }\r\n }\r\n\r\n togglePointerResizeMode() {\r\n if (this.pointerResizeMode) {\r\n this.disablePointerResizeMode();\r\n } else {\r\n this.enablePointerResizeMode();\r\n }\r\n return this.pointerResizeMode;\r\n }\r\n\r\n focusElement() {\r\n if (typeof this.element.focus === 'function') {\r\n try {\r\n this.element.focus({ preventScroll: true });\r\n } catch (e) {\r\n // Some browsers do not support the preventScroll option; fallback without it\r\n this.element.focus();\r\n }\r\n }\r\n }\r\n\r\n keyboardDrag(key, shiftKey) {\r\n const step = shiftKey ? this.options.keyboardStepLarge : this.options.keyboardStep;\r\n \r\n // Get current position\r\n let currentLeft = parseFloat(this.element.style.left) || 0;\r\n let currentTop = parseFloat(this.element.style.top) || 0;\r\n \r\n // If element is still centered with transform, convert to absolute position first\r\n const computedStyle = window.getComputedStyle(this.element);\r\n if (computedStyle.transform !== 'none') {\r\n const rect = this.element.getBoundingClientRect();\r\n currentLeft = rect.left;\r\n currentTop = rect.top;\r\n this.element.style.transform = 'none';\r\n this.element.style.left = `${currentLeft}px`;\r\n this.element.style.top = `${currentTop}px`;\r\n }\r\n \r\n // Calculate new position\r\n let newX = currentLeft;\r\n let newY = currentTop;\r\n\r\n switch(key) {\r\n case 'ArrowLeft':\r\n newX -= step;\r\n break;\r\n case 'ArrowRight':\r\n newX += step;\r\n break;\r\n case 'ArrowUp':\r\n newY -= step;\r\n break;\r\n case 'ArrowDown':\r\n newY += step;\r\n break;\r\n }\r\n\r\n // Apply position\r\n this.element.style.left = `${newX}px`;\r\n this.element.style.top = `${newY}px`;\r\n \r\n // Call custom handler if provided\r\n if (this.options.onDrag) {\r\n this.options.onDrag({ x: newX, y: newY });\r\n }\r\n }\r\n\r\n keyboardResize(key, shiftKey) {\r\n const step = shiftKey ? this.options.keyboardStepLarge : this.options.keyboardStep;\r\n const rect = this.element.getBoundingClientRect();\r\n \r\n let width = rect.width;\r\n let height = rect.height;\r\n\r\n // Adjust width/height based on arrow key\r\n switch(key) {\r\n case 'ArrowLeft':\r\n width -= step;\r\n break;\r\n case 'ArrowRight':\r\n width += step;\r\n break;\r\n case 'ArrowUp':\r\n if (this.options.maintainAspectRatio) {\r\n width += step;\r\n } else {\r\n height -= step;\r\n }\r\n break;\r\n case 'ArrowDown':\r\n if (this.options.maintainAspectRatio) {\r\n width -= step;\r\n } else {\r\n height += step;\r\n }\r\n break;\r\n }\r\n\r\n // Constrain to minimum dimensions\r\n width = Math.max(this.options.minWidth, width);\r\n height = Math.max(this.options.minHeight, height);\r\n\r\n // Apply new dimensions\r\n this.element.style.width = `${width}px`;\r\n if (!this.options.maintainAspectRatio) {\r\n this.element.style.height = `${height}px`;\r\n } else {\r\n this.element.style.height = 'auto';\r\n }\r\n \r\n // Call custom handler if provided\r\n if (this.options.onResize) {\r\n this.options.onResize({ width, height });\r\n }\r\n }\r\n\r\n resetPosition() {\r\n this.element.style.left = '50%';\r\n this.element.style.top = '50%';\r\n this.element.style.transform = 'translate(-50%, -50%)';\r\n this.element.style.right = '';\r\n this.element.style.bottom = '';\r\n \r\n // Clear manual positioning flag\r\n this.manuallyPositioned = false;\r\n \r\n // Call custom handler if provided\r\n if (this.options.onDrag) {\r\n this.options.onDrag({ centered: true });\r\n }\r\n }\r\n\r\n destroy() {\r\n const dragHandle = this.options.dragHandle || this.element;\r\n \r\n this.disablePointerResizeMode();\r\n \r\n // Remove drag events\r\n dragHandle.removeEventListener('mousedown', this.handlers.mousedown);\r\n dragHandle.removeEventListener('touchstart', this.handlers.touchstart);\r\n \r\n // Remove document-level events\r\n document.removeEventListener('mousemove', this.handlers.mousemove);\r\n document.removeEventListener('mouseup', this.handlers.mouseup);\r\n document.removeEventListener('touchmove', this.handlers.touchmove);\r\n document.removeEventListener('touchend', this.handlers.touchend);\r\n \r\n // Remove keyboard events\r\n this.element.removeEventListener('keydown', this.handlers.keydown);\r\n \r\n // Remove resize handle events\r\n if (this.options.resizeHandles && this.options.resizeHandles.length > 0) {\r\n this.options.resizeHandles.forEach(handle => {\r\n handle.removeEventListener('mousedown', this.handlers.resizeHandleMousedown);\r\n handle.removeEventListener('touchstart', this.handlers.resizeHandleMousedown);\r\n });\r\n }\r\n \r\n // Clean up classes\r\n this.element.classList.remove(\r\n `${this.options.classPrefix}-dragging`,\r\n `${this.options.classPrefix}-resizing`,\r\n `${this.options.classPrefix}-keyboard-drag`,\r\n `${this.options.classPrefix}-keyboard-resize`\r\n );\r\n }\r\n}\r\n\r\n", "/**\r\n * Menu creation and management utilities\r\n */\r\n\r\nimport { DOMUtils } from './DOMUtils.js';\r\nimport { createIconElement } from '../icons/Icons.js';\r\nimport { i18n } from '../i18n/i18n.js';\r\nimport { focusElement } from './FocusUtils.js';\r\n\r\n/**\r\n * Create a menu item button with icon and text\r\n * @param {Object} options - Menu item options\r\n * @param {string} options.classPrefix - Class prefix\r\n * @param {string} options.itemClass - Menu item class name\r\n * @param {string} options.icon - Icon name\r\n * @param {string} options.label - Button label (i18n key or text)\r\n * @param {string} options.ariaLabel - ARIA label (optional, uses label if not provided)\r\n * @param {Function} options.onClick - Click handler\r\n * @param {boolean} options.hasTextClass - Whether to add text class to span\r\n * @returns {HTMLElement} Menu item button\r\n */\r\nexport function createMenuItem({ classPrefix, itemClass, icon, label, ariaLabel, onClick, hasTextClass = false }) {\r\n // Check if label is an i18n key for aria-label\r\n const isI18nKeyForAria = typeof label === 'string' && (label.startsWith('transcript.') || label.startsWith('player.') || label.startsWith('settings.'));\r\n const ariaLabelText = ariaLabel || (isI18nKeyForAria ? (i18n.t(label) || label) : label);\r\n \r\n const button = DOMUtils.createElement('button', {\r\n className: itemClass,\r\n attributes: {\r\n 'type': 'button',\r\n 'aria-label': ariaLabelText,\r\n 'tabindex': '-1'\r\n }\r\n });\r\n \r\n if (icon) {\r\n button.appendChild(createIconElement(icon));\r\n }\r\n \r\n // Check if label is an i18n key (starts with common prefixes)\r\n const isI18nKey = typeof label === 'string' && (label.startsWith('transcript.') || label.startsWith('player.') || label.startsWith('settings.'));\r\n const textContent = isI18nKey ? (i18n.t(label) || label) : label;\r\n \r\n const text = DOMUtils.createElement('span', {\r\n textContent: textContent,\r\n className: hasTextClass ? `${classPrefix}-settings-text` : undefined,\r\n attributes: {\r\n 'aria-hidden': 'true'\r\n }\r\n });\r\n button.appendChild(text);\r\n \r\n if (onClick) {\r\n button.addEventListener('click', onClick);\r\n }\r\n \r\n return button;\r\n}\r\n\r\n/**\r\n * Setup keyboard navigation for menu items\r\n * @param {HTMLElement} menu - Menu container\r\n * @param {HTMLElement} button - Trigger button\r\n * @param {string} itemSelector - Selector for menu items\r\n * @param {Function} onClose - Function to close menu\r\n */\r\nexport function attachMenuKeyboardNavigation(menu, button, itemSelector, onClose) {\r\n if (!menu) return;\r\n \r\n const menuItems = Array.from(menu.querySelectorAll(itemSelector));\r\n if (menuItems.length === 0) return;\r\n\r\n const handleKeyDown = (e) => {\r\n const currentIndex = menuItems.indexOf(document.activeElement);\r\n \r\n switch (e.key) {\r\n case 'ArrowDown':\r\n e.preventDefault();\r\n e.stopPropagation();\r\n const nextIndex = (currentIndex + 1) % menuItems.length;\r\n menuItems.forEach((item, idx) => {\r\n item.setAttribute('tabindex', idx === nextIndex ? '0' : '-1');\r\n });\r\n menuItems[nextIndex].focus({ preventScroll: false });\r\n menuItems[nextIndex].scrollIntoView({ behavior: 'smooth', block: 'nearest' });\r\n break;\r\n \r\n case 'ArrowUp':\r\n e.preventDefault();\r\n e.stopPropagation();\r\n const prevIndex = (currentIndex - 1 + menuItems.length) % menuItems.length;\r\n menuItems.forEach((item, idx) => {\r\n item.setAttribute('tabindex', idx === prevIndex ? '0' : '-1');\r\n });\r\n menuItems[prevIndex].focus({ preventScroll: false });\r\n menuItems[prevIndex].scrollIntoView({ behavior: 'smooth', block: 'nearest' });\r\n break;\r\n \r\n case 'Home':\r\n e.preventDefault();\r\n e.stopPropagation();\r\n menuItems.forEach((item, idx) => {\r\n item.setAttribute('tabindex', idx === 0 ? '0' : '-1');\r\n });\r\n menuItems[0].focus({ preventScroll: false });\r\n menuItems[0].scrollIntoView({ behavior: 'smooth', block: 'nearest' });\r\n break;\r\n \r\n case 'End':\r\n e.preventDefault();\r\n e.stopPropagation();\r\n const lastIndex = menuItems.length - 1;\r\n menuItems.forEach((item, idx) => {\r\n item.setAttribute('tabindex', idx === lastIndex ? '0' : '-1');\r\n });\r\n menuItems[lastIndex].focus({ preventScroll: false });\r\n menuItems[lastIndex].scrollIntoView({ behavior: 'smooth', block: 'nearest' });\r\n break;\r\n \r\n case 'Enter':\r\n case ' ':\r\n e.preventDefault();\r\n e.stopPropagation();\r\n if (document.activeElement && menuItems.includes(document.activeElement)) {\r\n document.activeElement.click();\r\n if (onClose) {\r\n setTimeout(() => {\r\n if (button && document.contains(button)) {\r\n button.focus();\r\n }\r\n }, 0);\r\n }\r\n }\r\n break;\r\n \r\n case 'Escape':\r\n e.preventDefault();\r\n e.stopPropagation();\r\n if (onClose) {\r\n onClose();\r\n }\r\n break;\r\n }\r\n };\r\n\r\n menu.addEventListener('keydown', handleKeyDown, true); // Use capture phase\r\n return handleKeyDown; // Return handler for cleanup\r\n}\r\n\r\n/**\r\n * Focus first menu item and set tabindex\r\n * @param {HTMLElement} menu - Menu container\r\n * @param {string} itemSelector - Selector for menu items\r\n * @param {number} delay - Delay in milliseconds\r\n */\r\nexport function focusFirstMenuItem(menu, itemSelector, delay = 0) {\r\n if (!menu) return;\r\n \r\n setTimeout(() => {\r\n const menuItems = Array.from(menu.querySelectorAll(itemSelector));\r\n if (menuItems.length > 0) {\r\n menuItems.forEach((item, index) => {\r\n item.setAttribute('tabindex', index === 0 ? '0' : '-1');\r\n });\r\n focusElement(menuItems[0], { delay: 0 });\r\n // Scroll into view for keyboard users\r\n menuItems[0].scrollIntoView({ behavior: 'smooth', block: 'nearest' });\r\n }\r\n }, delay);\r\n}\r\n\r\n", "/**\r\n * Form element creation utilities\r\n */\r\n\r\nimport { DOMUtils } from './DOMUtils.js';\r\nimport { i18n } from '../i18n/i18n.js';\r\n\r\n/**\r\n * Create a labeled select element with proper accessibility\r\n * @param {Object} options - Options for creating the labeled select\r\n * @param {string} options.classPrefix - Class prefix for styling\r\n * @param {string} options.labelClass - CSS class for the label\r\n * @param {string} options.selectClass - CSS class for the select\r\n * @param {string} options.labelText - Label text (i18n key or plain text)\r\n * @param {string} options.selectId - ID for the select element\r\n * @param {boolean} options.hidden - Whether to hide the label and select initially\r\n * @param {Function} options.onChange - Change event handler\r\n * @param {Array} options.options - Array of option objects {value, text, selected}\r\n * @returns {Object} Object with label and select elements\r\n */\r\nexport function createLabeledSelect({\r\n classPrefix,\r\n labelClass,\r\n selectClass,\r\n labelText,\r\n selectId,\r\n hidden = false,\r\n onChange = null,\r\n options = []\r\n}) {\r\n // Check if labelText is an i18n key\r\n const isI18nKey = typeof labelText === 'string' && \r\n (labelText.startsWith('transcript.') || \r\n labelText.startsWith('player.') || \r\n labelText.startsWith('settings.') ||\r\n labelText.startsWith('captions.'));\r\n const labelTextContent = isI18nKey ? (i18n.t(labelText) || labelText) : labelText;\r\n\r\n const label = DOMUtils.createElement('label', {\r\n className: labelClass,\r\n textContent: labelTextContent,\r\n attributes: {\r\n 'for': selectId,\r\n 'style': hidden ? 'display: none;' : undefined\r\n }\r\n });\r\n\r\n const select = DOMUtils.createElement('select', {\r\n className: selectClass,\r\n attributes: {\r\n 'id': selectId,\r\n 'style': hidden ? 'display: none;' : undefined\r\n }\r\n });\r\n\r\n // Add options\r\n options.forEach(opt => {\r\n const option = DOMUtils.createElement('option', {\r\n textContent: opt.text,\r\n attributes: {\r\n 'value': opt.value,\r\n 'selected': opt.selected ? 'selected' : undefined\r\n }\r\n });\r\n select.appendChild(option);\r\n });\r\n\r\n // Add change handler if provided\r\n if (onChange) {\r\n select.addEventListener('change', onChange);\r\n }\r\n\r\n return { label, select };\r\n}\r\n\r\n/**\r\n * Show or hide a labeled select element\r\n * @param {HTMLElement} label - Label element\r\n * @param {HTMLElement} select - Select element\r\n * @param {boolean} show - Whether to show (true) or hide (false)\r\n */\r\nexport function toggleLabeledSelect(label, select, show) {\r\n if (label) {\r\n label.style.display = show ? 'block' : 'none';\r\n }\r\n if (select) {\r\n select.style.display = show ? 'block' : 'none';\r\n }\r\n}\r\n\r\n/**\r\n * Prevent drag on element and its children\r\n * @param {HTMLElement} element - Element to prevent drag on\r\n */\r\nexport function preventDragOnElement(element) {\r\n if (!element) return;\r\n \r\n ['mousedown', 'click'].forEach(eventType => {\r\n element.addEventListener(eventType, (e) => {\r\n e.stopPropagation();\r\n });\r\n });\r\n}\r\n\r\n"],
|
|
5
|
-
"mappings": ";;;;;;;AAIO,IAAM,WAAW;AAAA,EACtB,cAAc,KAAK,UAAU,CAAC,GAAG;AAC/B,UAAM,UAAU,SAAS,cAAc,GAAG;AAE1C,QAAI,QAAQ,WAAW;AACrB,cAAQ,YAAY,QAAQ;AAAA,IAC9B;AAEA,QAAI,QAAQ,YAAY;AACtB,aAAO,QAAQ,QAAQ,UAAU,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAC3D,gBAAQ,aAAa,KAAK,KAAK;AAAA,MACjC,CAAC;AAAA,IACH;AAEA,QAAI,QAAQ,WAAW;AACrB,cAAQ,YAAY,QAAQ;AAAA,IAC9B;AAEA,QAAI,QAAQ,aAAa;AACvB,cAAQ,cAAc,QAAQ;AAAA,IAChC;AAEA,QAAI,QAAQ,OAAO;AACjB,aAAO,OAAO,QAAQ,OAAO,QAAQ,KAAK;AAAA,IAC5C;AAEA,QAAI,QAAQ,UAAU;AACpB,cAAQ,SAAS,QAAQ,WAAS;AAChC,YAAI,MAAO,SAAQ,YAAY,KAAK;AAAA,MACtC,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,SAAS,WAAW;AAC3B,QAAI,WAAW,WAAW;AACxB,cAAQ,UAAU,IAAI,SAAS;AAAA,IACjC;AAAA,EACF;AAAA,EAEA,YAAY,SAAS,WAAW;AAC9B,QAAI,WAAW,WAAW;AACxB,cAAQ,UAAU,OAAO,SAAS;AAAA,IACpC;AAAA,EACF;AAAA,EAEA,YAAY,SAAS,WAAW;AAC9B,QAAI,WAAW,WAAW;AACxB,cAAQ,UAAU,OAAO,SAAS;AAAA,IACpC;AAAA,EACF;AAAA,EAEA,SAAS,SAAS,WAAW;AAC3B,WAAO,WAAW,QAAQ,UAAU,SAAS,SAAS;AAAA,EACxD;AAAA,EAEA,KAAK,SAAS;AACZ,QAAI,SAAS;AACX,cAAQ,MAAM,UAAU;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,KAAK,SAAS;AACZ,QAAI,SAAS;AACX,cAAQ,MAAM,UAAU;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,OAAO,SAAS,WAAW,KAAK;AAC9B,QAAI,CAAC,QAAS;AAEd,YAAQ,MAAM,UAAU;AACxB,YAAQ,MAAM,UAAU;AAExB,QAAI,QAAQ;AACZ,UAAM,UAAU,CAAC,cAAc;AAC7B,UAAI,CAAC,MAAO,SAAQ;AACpB,YAAM,WAAW,YAAY;AAC7B,YAAM,UAAU,KAAK,IAAI,WAAW,UAAU,CAAC;AAE/C,cAAQ,MAAM,UAAU;AAExB,UAAI,WAAW,UAAU;AACvB,8BAAsB,OAAO;AAAA,MAC/B;AAAA,IACF;AAEA,0BAAsB,OAAO;AAAA,EAC/B;AAAA,EAEA,QAAQ,SAAS,WAAW,KAAK;AAC/B,QAAI,CAAC,QAAS;AAEd,UAAM,eAAe,WAAW,iBAAiB,OAAO,EAAE,OAAO,KAAK;AACtE,QAAI,QAAQ;AAEZ,UAAM,UAAU,CAAC,cAAc;AAC7B,UAAI,CAAC,MAAO,SAAQ;AACpB,YAAM,WAAW,YAAY;AAC7B,YAAM,UAAU,KAAK,IAAI,eAAgB,WAAW,UAAW,CAAC;AAEhE,cAAQ,MAAM,UAAU;AAExB,UAAI,WAAW,UAAU;AACvB,8BAAsB,OAAO;AAAA,MAC/B,OAAO;AACL,gBAAQ,MAAM,UAAU;AAAA,MAC1B;AAAA,IACF;AAEA,0BAAsB,OAAO;AAAA,EAC/B;AAAA,EAEA,OAAO,SAAS;AACd,QAAI,CAAC,QAAS,QAAO,EAAE,KAAK,GAAG,MAAM,EAAE;AAEvC,UAAM,OAAO,QAAQ,sBAAsB;AAC3C,WAAO;AAAA,MACL,KAAK,KAAK,MAAM,OAAO;AAAA,MACvB,MAAM,KAAK,OAAO,OAAO;AAAA,MACzB,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAAA,EAEA,WAAW,KAAK;AACd,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,cAAc;AAClB,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,aAAa,MAAM;AAGjB,UAAM,OAAO,SAAS,cAAc,KAAK;AAIzC,UAAM,WAAW,KACd,QAAQ,uDAAuD,EAAE,EACjE,QAAQ,uDAAuD,EAAE,EACjE,QAAQ,eAAe,EAAE,EACzB,QAAQ,iBAAiB,EAAE;AAE9B,SAAK,YAAY;AACjB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAc,MAAM,cAAc,UAAU;AAC1C,UAAM,UAAU,KAAK,cAAc,QAAQ;AAAA,MACzC,WAAW,GAAG,WAAW;AAAA,MACzB,aAAa;AAAA,MACb,YAAY;AAAA,QACV,eAAe;AAAA,MACjB;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAc,SAAS,MAAM,cAAc,UAAU;AACnD,QAAI,CAAC,WAAW,CAAC,KAAM;AAGvB,UAAM,kBAAkB,QAAQ,cAAc,IAAI,WAAW,UAAU;AACvE,QAAI,iBAAiB;AACnB,sBAAgB,OAAO;AAAA,IACzB;AAEA,UAAM,UAAU,KAAK,cAAc,MAAM,WAAW;AACpD,YAAQ,YAAY,OAAO;AAG3B,UAAM,cAAc,MAAM;AACxB,cAAQ,UAAU,IAAI,GAAG,WAAW,kBAAkB;AAAA,IACxD;AAEA,UAAM,cAAc,MAAM;AACxB,cAAQ,UAAU,OAAO,GAAG,WAAW,kBAAkB;AAAA,IAC3D;AAEA,YAAQ,iBAAiB,cAAc,WAAW;AAClD,YAAQ,iBAAiB,cAAc,WAAW;AAClD,YAAQ,iBAAiB,SAAS,WAAW;AAC7C,YAAQ,iBAAiB,QAAQ,WAAW;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,iBAAiB,MAAM,cAAc,UAAU;AAC7C,UAAM,aAAa,KAAK,cAAc,QAAQ;AAAA,MAC5C,WAAW,GAAG,WAAW;AAAA,MACzB,aAAa;AAAA,MACb,YAAY;AAAA,QACV,eAAe;AAAA,MACjB;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AACF;;;ACvNO,IAAM,KAAK;AAAA,EAChB,QAAQ;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,cAAc;AAAA,IACd,UAAU;AAAA,IACV,OAAO;AAAA,IACP,KAAK;AAAA,IACL,aAAa;AAAA,IACb,UAAU;AAAA,IACV,UAAU;AAAA,IACV,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,WAAW;AAAA,IACX,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,IACnB,sBAAsB;AAAA,IACtB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,WAAW;AAAA,IACX,wBAAwB;AAAA,IACxB,wBAAwB;AAAA,IACxB,0BAA0B;AAAA,IAC1B,oBAAoB;AAAA,IACpB,qBAAqB;AAAA,IACrB,wBAAwB;AAAA,IACxB,yBAAyB;AAAA,IACzB,sBAAsB;AAAA,IACtB,uBAAuB;AAAA,IACvB,0BAA0B;AAAA,IAC1B,2BAA2B;AAAA,IAC3B,cAAc;AAAA,IACd,aAAa;AAAA,IACb,eAAe;AAAA,EACjB;AAAA,EACA,UAAU;AAAA,IACR,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,SAAS;AAAA,EACX;AAAA,EACA,WAAW;AAAA,IACT,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA,cAAc;AAAA,IACZ,WAAW;AAAA,IACX,OAAO;AAAA,IACP,WAAW;AAAA,EACb;AAAA,EACA,aAAa;AAAA,IACX,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,EACX;AAAA,EACA,kBAAkB;AAAA,IAChB,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAAA,EACA,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,YAAY;AAAA,IACV,OAAO;AAAA,IACP,OAAO;AAAA,IACP,SAAS;AAAA,IACT,cAAc;AAAA,IACd,UAAU;AAAA,IACV,kBAAkB;AAAA,IAClB,oBAAoB;AAAA,IACpB,kBAAkB;AAAA,IAClB,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,oBAAoB;AAAA,IACpB,qBAAqB;AAAA,IACrB,cAAc;AAAA,IACd,qBAAqB;AAAA,IACrB,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,IACnB,sBAAsB;AAAA,IACtB,uBAAuB;AAAA,IACvB,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,IACnB,oBAAoB;AAAA,IACpB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,EACtB;AAAA,EACA,UAAU;AAAA,IACR,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,IACP,UAAU;AAAA,IACV,UAAU;AAAA,IACV,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA,QAAQ;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAAA,EACA,UAAU;AAAA,IACR,OAAO;AAAA,IACP,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,IAAI;AAAA,IACJ,UAAU;AAAA,IACV,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,EACrB;AACF;;;ACrKA,IAAM,yBAAyB;AAAA,EAC7B,IAAI,MAAM,OAAO,yBAAmB;AAAA,EACpC,IAAI,MAAM,OAAO,yBAAmB;AAAA,EACpC,IAAI,MAAM,OAAO,yBAAmB;AAAA,EACpC,IAAI,MAAM,OAAO,yBAAmB;AACtC;AAMO,SAAS,sBAAsB;AACpC,SAAO,EAAE,GAAG;AACd;AAKO,SAAS,4BAA4B;AAC1C,SAAO;AACT;AAOA,eAAsB,uBAAuB,MAAM;AACjD,QAAM,SAAS,uBAAuB,IAAI;AAC1C,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,SAAS,MAAM,OAAO;AAC5B,SAAO,OAAO,IAAI,KAAK,OAAO,WAAW;AAC3C;AAMO,IAAM,eAAe,oBAAoB;;;ACxChD,IAAM,OAAN,MAAW;AAAA,EACT,cAAc;AACZ,SAAK,kBAAkB;AACvB,SAAK,eAAe,oBAAoB;AACxC,SAAK,kBAAkB,oBAAI,IAAI;AAC/B,SAAK,yBAAyB,0BAA0B;AAAA,EAC1D;AAAA,EAEA,YAAY,MAAM;AAChB,QAAI,KAAK,aAAa,IAAI,GAAG;AAC3B,WAAK,kBAAkB;AAAA,IACzB,OAAO;AACL,cAAQ,KAAK,aAAa,IAAI,sCAAsC;AACpE,WAAK,kBAAkB;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,cAAc;AACZ,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eAAe,MAAM;AACzB,UAAM,kBAAkB,QAAQ,IAAI,YAAY;AAChD,QAAI,CAAC,eAAgB,QAAO,KAAK;AAEjC,QAAI,KAAK,aAAa,cAAc,GAAG;AACrC,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,gBAAgB,IAAI,cAAc,GAAG;AAC5C,YAAM,KAAK,gBAAgB,IAAI,cAAc;AAC7C,aAAO,KAAK,aAAa,cAAc,IAAI,iBAAiB;AAAA,IAC9D;AAEA,QAAI,CAAC,KAAK,uBAAuB,cAAc,GAAG;AAChD,aAAO;AAAA,IACT;AAEA,UAAM,eAAe,YAAY;AAC/B,UAAI;AACF,cAAM,SAAS,MAAM,uBAAuB,cAAc;AAC1D,YAAI,QAAQ;AACV,eAAK,aAAa,cAAc,IAAI;AAAA,QACtC;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,KAAK,aAAa,cAAc,qBAAqB,KAAK;AAAA,MACpE,UAAE;AACA,aAAK,gBAAgB,OAAO,cAAc;AAAA,MAC5C;AAAA,IACF,GAAG;AAEH,SAAK,gBAAgB,IAAI,gBAAgB,WAAW;AACpD,UAAM;AAEN,WAAO,KAAK,aAAa,cAAc,IAAI,iBAAiB;AAAA,EAC9D;AAAA,EAEA,EAAE,KAAK,eAAe,CAAC,GAAG;AACxB,UAAM,OAAO,IAAI,MAAM,GAAG;AAC1B,QAAI,QAAQ,KAAK,aAAa,KAAK,eAAe;AAElD,eAAW,KAAK,MAAM;AACpB,UAAI,SAAS,OAAO,UAAU,YAAY,KAAK,OAAO;AACpD,gBAAQ,MAAM,CAAC;AAAA,MACjB,OAAO;AAEL,gBAAQ,KAAK,aAAa;AAC1B,mBAAW,eAAe,MAAM;AAC9B,cAAI,SAAS,OAAO,UAAU,YAAY,eAAe,OAAO;AAC9D,oBAAQ,MAAM,WAAW;AAAA,UAC3B,OAAO;AACL,mBAAO;AAAA,UACT;AAAA,QACF;AACA;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,UAAU,UAAU;AAC7B,aAAO,QAAQ,YAAY,EAAE,QAAQ,CAAC,CAAC,aAAa,WAAW,MAAM;AACnE,gBAAQ,MAAM,QAAQ,IAAI,OAAO,IAAI,WAAW,KAAK,GAAG,GAAG,WAAW;AAAA,MACxE,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,MAAMA,eAAc;AACjC,QAAI,CAAC,KAAK,aAAa,IAAI,GAAG;AAC5B,WAAK,aAAa,IAAI,IAAI,CAAC;AAAA,IAC7B;AACA,WAAO,OAAO,KAAK,aAAa,IAAI,GAAGA,aAAY;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,oBAAoB,UAAU,KAAK;AAEvC,QAAI,KAAK,gBAAgB,IAAI,GAAG,GAAG;AACjC,aAAO,KAAK,gBAAgB,IAAI,GAAG;AAAA,IACrC;AAEA,UAAM,eAAe,YAAY;AAC/B,UAAI;AACF,cAAM,WAAW,MAAM,MAAM,GAAG;AAChC,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,IAAI,MAAM,iCAAiC,SAAS,UAAU,EAAE;AAAA,QACxE;AAEA,cAAM,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK;AAC5D,YAAIA;AAEJ,cAAM,SAAS,MAAM,SAAS,YAAY;AAC1C,cAAM,WAAW,IAAI,YAAY,OAAO,EAAE,OAAO,MAAM;AAEvD,YAAI,YAAY,SAAS,kBAAkB,KAAK,IAAI,SAAS,OAAO,GAAG;AACrE,UAAAA,gBAAe,KAAK,MAAM,QAAQ;AAAA,QACpC,WAAW,YAAY,SAAS,WAAW,KAAK,YAAY,SAAS,oBAAoB,KAAK,IAAI,SAAS,OAAO,KAAK,IAAI,SAAS,MAAM,GAAG;AAI3I,cAAI;AAEF,YAAAA,gBAAe,KAAK,MAAM,QAAQ;AAAA,UACpC,SAAS,GAAG;AAEV,gBAAI,OAAO,WAAW,eAAe,OAAO,QAAQ;AAClD,cAAAA,gBAAe,OAAO,OAAO,KAAK,QAAQ;AAAA,YAC5C,OAAO;AACL,sBAAQ,KAAK,8EAA8E;AAC3F,oBAAM,IAAI,MAAM,gFAAgF;AAAA,YAClG;AAAA,UACF;AAAA,QACF,OAAO;AAEL,UAAAA,gBAAe,KAAK,MAAM,QAAQ;AAAA,QACpC;AAEA,aAAK,eAAe,UAAUA,aAAY;AAC1C,eAAOA;AAAA,MACT,SAAS,OAAO;AACd,gBAAQ,MAAM,oCAAoC,GAAG,KAAK,KAAK;AAC/D,cAAM;AAAA,MACR,UAAE;AAEA,aAAK,gBAAgB,OAAO,GAAG;AAAA,MACjC;AAAA,IACF,GAAG;AAEH,SAAK,gBAAgB,IAAI,KAAK,WAAW;AACzC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,sBAAsB,aAAa;AACvC,UAAM,WAAW,OAAO,QAAQ,WAAW,EAAE;AAAA,MAAI,CAAC,CAAC,UAAU,GAAG,MAC9D,KAAK,oBAAoB,UAAU,GAAG;AAAA,IACxC;AACA,UAAM,QAAQ,IAAI,QAAQ;AAAA,EAC5B;AACF;AAEO,IAAM,OAAO,IAAI,KAAK;;;AChLtB,IAAM,YAAY;AAAA;AAAA;AAAA;AAAA,EAIvB,WAAW,SAAS,kBAAkB,OAAO;AAC3C,QAAI,CAAC,SAAS,OAAO,KAAK,UAAU,GAAG;AACrC,aAAO,kBAAkB,aAAa;AAAA,IACxC;AAEA,UAAM,QAAQ,KAAK,MAAM,UAAU,IAAI;AACvC,UAAM,UAAU,KAAK,MAAO,UAAU,OAAQ,EAAE;AAChD,UAAM,OAAO,KAAK,MAAM,UAAU,EAAE;AAEpC,UAAM,MAAM,CAAC,QAAQ,OAAO,GAAG,EAAE,SAAS,GAAG,GAAG;AAEhD,QAAI,QAAQ,KAAK,iBAAiB;AAChC,aAAO,GAAG,IAAI,KAAK,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC;AAAA,IACnD;AAEA,WAAO,GAAG,IAAI,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,YAAY;AACpB,UAAM,QAAQ,WAAW,MAAM,GAAG,EAAE,IAAI,OAAK,SAAS,GAAG,EAAE,CAAC;AAE5D,QAAI,MAAM,WAAW,GAAG;AAEtB,aAAO,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC;AAAA,IAClD,WAAW,MAAM,WAAW,GAAG;AAE7B,aAAO,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC;AAAA,IAChC,WAAW,MAAM,WAAW,GAAG;AAE7B,aAAO,MAAM,CAAC;AAAA,IAChB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,SAAS;AACtB,QAAI,CAAC,SAAS,OAAO,KAAK,UAAU,GAAG;AACrC,aAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;AAAA,IAC5C;AAEA,UAAM,QAAQ,KAAK,MAAM,UAAU,IAAI;AACvC,UAAM,UAAU,KAAK,MAAO,UAAU,OAAQ,EAAE;AAChD,UAAM,OAAO,KAAK,MAAM,UAAU,EAAE;AAEpC,UAAM,QAAQ,CAAC;AAEf,QAAI,QAAQ,GAAG;AACb,YAAM,MAAM,UAAU,IAAI,cAAc;AACxC,YAAM,KAAK,KAAK,EAAE,KAAK,EAAE,OAAO,MAAM,CAAC,CAAC;AAAA,IAC1C;AACA,QAAI,UAAU,GAAG;AACf,YAAM,MAAM,YAAY,IAAI,gBAAgB;AAC5C,YAAM,KAAK,KAAK,EAAE,KAAK,EAAE,OAAO,QAAQ,CAAC,CAAC;AAAA,IAC5C;AACA,QAAI,OAAO,KAAK,MAAM,WAAW,GAAG;AAClC,YAAM,MAAM,SAAS,IAAI,gBAAgB;AACzC,YAAM,KAAK,KAAK,EAAE,KAAK,EAAE,OAAO,KAAK,CAAC,CAAC;AAAA,IACzC;AAEA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,OAAO,OAAO;AAC7B,QAAI,UAAU,EAAG,QAAO;AACxB,WAAO,KAAK,MAAO,QAAQ,QAAS,GAAG;AAAA,EACzC;AACF;;;AC/EA,IAAM,YAAY;AAAA,EACd,MAAM;AAAA,EAEN,OAAO;AAAA,EAEP,MAAM;AAAA,EAEN,QAAQ;AAAA,EAER,SAAS;AAAA,EAET,cAAc;AAAA,EAEd,UAAU;AAAA,EAEV,SAAS;AAAA,EAET,YAAY;AAAA,EAEZ,cAAc;AAAA,EAEd,WAAW;AAAA,EAEX,aAAa;AAAA,EAEb,YAAY;AAAA,EAEZ,gBAAgB;AAAA,EAEhB,UAAU;AAAA,EAEV,UAAU;AAAA,EAEV,aAAa;AAAA,EAEb,KAAK;AAAA,EAEL,OAAO;AAAA,EAEP,OAAO;AAAA,EAEP,OAAO;AAAA,EAEP,SAAS;AAAA,EAET,OAAO;AAAA,EAEP,UAAU;AAAA,EAEV,IAAI;AAAA,EAEJ,YAAY;AAAA,EAEZ,UAAU;AAAA,EAEV,kBAAkB;AAAA,EAElB,oBAAoB;AAAA,EAEpB,cAAc;AAAA,EAEd,gBAAgB;AAAA,EAEhB,OAAO;AAAA,EAEP,cAAc;AAAA,EAEd,MAAM;AAAA,EAEN,QAAQ;AAAA,EAER,OAAO;AACX;AAGA,IAAM,aAAa,CAAC,UAAU,gDAAgD,KAAK;AAG5E,IAAM,QAAQ,OAAO;AAAA,EACxB,OAAO,QAAQ,SAAS,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,WAAW,KAAK,CAAC,CAAC;AAC5E;AAEO,SAAS,QAAQ,MAAM;AAC1B,SAAO,MAAM,IAAI,KAAK,MAAM;AAChC;AAEO,SAAS,kBAAkB,MAAM,YAAY,IAAI;AACpD,QAAM,UAAU,SAAS,cAAc,MAAM;AAC7C,UAAQ,YAAY,eAAe,SAAS,GAAG,KAAK;AACpD,UAAQ,YAAY,QAAQ,IAAI;AAChC,UAAQ,aAAa,eAAe,MAAM;AAC1C,SAAO;AACX;AAMO,SAAS,oBAAoB;AAChC,QAAM,MAAM,SAAS,gBAAgB,8BAA8B,KAAK;AACxE,MAAI,aAAa,SAAS,qBAAqB;AAC/C,MAAI,aAAa,WAAW,WAAW;AACvC,MAAI,aAAa,SAAS,IAAI;AAC9B,MAAI,aAAa,UAAU,IAAI;AAC/B,MAAI,aAAa,eAAe,MAAM;AACtC,MAAI,aAAa,QAAQ,cAAc;AACvC,MAAI,MAAM,SAAS;AAGnB,QAAM,OAAO,SAAS,gBAAgB,8BAA8B,MAAM;AAC1E,QAAM,WAAW,sBAAsB,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,OAAO,GAAG,CAAC,CAAC;AAC9E,QAAM,SAAS,SAAS,gBAAgB,8BAA8B,QAAQ;AAC9E,SAAO,aAAa,MAAM,QAAQ;AAClC,SAAO,aAAa,KAAK,MAAM;AAC/B,SAAO,aAAa,KAAK,MAAM;AAC/B,SAAO,aAAa,SAAS,MAAM;AACnC,SAAO,aAAa,UAAU,MAAM;AAEpC,QAAM,iBAAiB,SAAS,gBAAgB,8BAA8B,gBAAgB;AAC9F,iBAAe,aAAa,MAAM,aAAa;AAC/C,iBAAe,aAAa,gBAAgB,GAAG;AAE/C,QAAM,WAAW,SAAS,gBAAgB,8BAA8B,UAAU;AAClF,WAAS,aAAa,MAAM,GAAG;AAC/B,WAAS,aAAa,MAAM,GAAG;AAC/B,WAAS,aAAa,UAAU,YAAY;AAE5C,QAAM,sBAAsB,SAAS,gBAAgB,8BAA8B,qBAAqB;AACxG,QAAM,UAAU,SAAS,gBAAgB,8BAA8B,SAAS;AAChF,UAAQ,aAAa,QAAQ,QAAQ;AACrC,UAAQ,aAAa,SAAS,KAAK;AACnC,sBAAoB,YAAY,OAAO;AAEvC,QAAM,UAAU,SAAS,gBAAgB,8BAA8B,SAAS;AAChF,QAAM,eAAe,SAAS,gBAAgB,8BAA8B,aAAa;AACzF,QAAM,eAAe,SAAS,gBAAgB,8BAA8B,aAAa;AACzF,eAAa,aAAa,MAAM,eAAe;AAC/C,UAAQ,YAAY,YAAY;AAChC,UAAQ,YAAY,YAAY;AAEhC,SAAO,YAAY,cAAc;AACjC,SAAO,YAAY,QAAQ;AAC3B,SAAO,YAAY,mBAAmB;AACtC,SAAO,YAAY,OAAO;AAC1B,OAAK,YAAY,MAAM;AACvB,MAAI,YAAY,IAAI;AAGpB,QAAM,SAAS,SAAS,gBAAgB,8BAA8B,QAAQ;AAC9E,SAAO,aAAa,MAAM,IAAI;AAC9B,SAAO,aAAa,MAAM,IAAI;AAC9B,SAAO,aAAa,KAAK,IAAI;AAC7B,SAAO,aAAa,QAAQ,2BAA2B;AACvD,SAAO,aAAa,UAAU,QAAQ,QAAQ,GAAG;AACjD,SAAO,aAAa,SAAS,wBAAwB;AACrD,MAAI,YAAY,MAAM;AAGtB,QAAM,eAAe,SAAS,gBAAgB,8BAA8B,SAAS;AACrF,eAAa,aAAa,UAAU,mBAAmB;AACvD,eAAa,aAAa,QAAQ,SAAS;AAC3C,eAAa,aAAa,SAAS,0BAA0B;AAC7D,MAAI,YAAY,YAAY;AAE5B,SAAO;AACX;;;AChKO,SAAS,aAAa,SAAS,EAAE,QAAQ,GAAG,gBAAgB,KAAK,IAAI,CAAC,GAAG;AAC5E,MAAI,CAAC,QAAS;AAEd,wBAAsB,MAAM;AACxB,eAAW,MAAM;AACb,UAAI,WAAW,SAAS,SAAS,OAAO,GAAG;AACvC,gBAAQ,MAAM,EAAE,cAAc,CAAC;AAAA,MACnC;AAAA,IACJ,GAAG,KAAK;AAAA,EACZ,CAAC;AACL;AAQO,SAAS,kBAAkB,WAAW,UAAU,UAAU,CAAC,GAAG;AACjE,MAAI,CAAC,UAAW;AAChB,QAAM,UAAU,UAAU,cAAc,QAAQ;AAChD,MAAI,SAAS;AACT,iBAAa,SAAS,OAAO;AAAA,EACjC;AACJ;;;AC/BO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAAY,YAAY,UAAU;AAChC,SAAK,YAAY;AACjB,SAAK,UAAU,KAAK,mBAAmB,IAAI,eAAe;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA,EAKA,qBAAqB;AACnB,QAAI;AACF,YAAM,OAAO;AACb,mBAAa,QAAQ,MAAM,IAAI;AAC/B,mBAAa,WAAW,IAAI;AAC5B,aAAO;AAAA,IACT,SAAS,GAAG;AACV,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,KAAK;AACV,WAAO,GAAG,KAAK,SAAS,IAAI,GAAG;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,KAAK,OAAO;AACd,QAAI,CAAC,KAAK,QAAS,QAAO;AAE1B,QAAI;AACF,YAAM,gBAAgB,KAAK,OAAO,GAAG;AACrC,WAAK,QAAQ,QAAQ,eAAe,KAAK,UAAU,KAAK,CAAC;AACzD,aAAO;AAAA,IACT,SAAS,GAAG;AACV,cAAQ,KAAK,mCAAmC,CAAC;AACjD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,KAAK,eAAe,MAAM;AAC5B,QAAI,CAAC,KAAK,QAAS,QAAO;AAE1B,QAAI;AACF,YAAM,gBAAgB,KAAK,OAAO,GAAG;AACrC,YAAM,QAAQ,KAAK,QAAQ,QAAQ,aAAa;AAChD,aAAO,QAAQ,KAAK,MAAM,KAAK,IAAI;AAAA,IACrC,SAAS,GAAG;AACV,cAAQ,KAAK,qCAAqC,CAAC;AACnD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,KAAK;AACV,QAAI,CAAC,KAAK,QAAS,QAAO;AAE1B,QAAI;AACF,YAAM,gBAAgB,KAAK,OAAO,GAAG;AACrC,WAAK,QAAQ,WAAW,aAAa;AACrC,aAAO;AAAA,IACT,SAAS,GAAG;AACV,cAAQ,KAAK,uCAAuC,CAAC;AACrD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ;AACN,QAAI,CAAC,KAAK,QAAS,QAAO;AAE1B,QAAI;AACF,YAAM,OAAO,OAAO,KAAK,KAAK,OAAO;AACrC,WAAK,QAAQ,SAAO;AAClB,YAAI,IAAI,WAAW,KAAK,SAAS,GAAG;AAClC,eAAK,QAAQ,WAAW,GAAG;AAAA,QAC7B;AAAA,MACF,CAAC;AACD,aAAO;AAAA,IACT,SAAS,GAAG;AACV,cAAQ,KAAK,iCAAiC,CAAC;AAC/C,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,0BAA0B,aAAa;AACrC,WAAO,KAAK,IAAI,0BAA0B,WAAW;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKA,2BAA2B;AACzB,WAAO,KAAK,IAAI,0BAA0B,IAAI;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAuB,aAAa;AAClC,WAAO,KAAK,IAAI,uBAAuB,WAAW;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,wBAAwB;AACtB,WAAO,KAAK,IAAI,uBAAuB,IAAI;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB,aAAa;AACjC,WAAO,KAAK,IAAI,sBAAsB,WAAW;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAuB;AACrB,WAAO,KAAK,IAAI,sBAAsB,IAAI;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,4BAA4B,aAAa;AACvC,WAAO,KAAK,IAAI,6BAA6B,WAAW;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA,EAKA,6BAA6B;AAC3B,WAAO,KAAK,IAAI,6BAA6B,IAAI;AAAA,EACnD;AACF;;;ACrJO,IAAM,qBAAN,MAAyB;AAAA,EAC9B,YAAY,SAAS,UAAU,CAAC,GAAG;AACjC,SAAK,UAAU;AACf,SAAK,UAAU;AAAA,MACb,YAAY;AAAA;AAAA,MACZ,eAAe,CAAC;AAAA;AAAA,MAChB,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,eAAe;AAAA,MACf,UAAU;AAAA,MACV,aAAa;AAAA,MACb,qBAAqB;AAAA;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,qBAAqB;AAAA,MACrB,iBAAiB;AAAA,MACjB,mBAAmB;AAAA,MACnB,cAAc;AAAA,MACd,mBAAmB;AAAA,MACnB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,4BAA4B;AAAA,MAC5B,uBAAuB;AAAA,MACvB,aAAa;AAAA,MACb,SAAS;AAAA;AAAA,MACT,YAAY;AAAA;AAAA,MACZ,GAAG;AAAA,IACL;AAGA,SAAK,aAAa;AAClB,SAAK,aAAa;AAClB,SAAK,kBAAkB;AACvB,SAAK,cAAc;AACnB,SAAK,cAAc;AACnB,SAAK,kBAAkB;AACvB,SAAK,kBAAkB;AACvB,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AACrB,SAAK,0BAA0B;AAC/B,SAAK,eAAe;AACpB,SAAK,eAAe;AACpB,SAAK,mBAAmB;AACxB,SAAK,oBAAoB;AACzB,SAAK,kBAAkB;AACvB,SAAK,iBAAiB;AACtB,SAAK,mBAAmB;AACxB,SAAK,qBAAqB;AAC1B,SAAK,oBAAoB;AACzB,SAAK,qBAAqB;AAC1B,SAAK,uBAAuB,oBAAI,IAAI;AACpC,SAAK,yBAAyB;AAG9B,SAAK,WAAW;AAAA,MACd,WAAW,KAAK,YAAY,KAAK,IAAI;AAAA,MACrC,WAAW,KAAK,YAAY,KAAK,IAAI;AAAA,MACrC,SAAS,KAAK,UAAU,KAAK,IAAI;AAAA,MACjC,YAAY,KAAK,aAAa,KAAK,IAAI;AAAA,MACvC,WAAW,KAAK,YAAY,KAAK,IAAI;AAAA,MACrC,UAAU,KAAK,WAAW,KAAK,IAAI;AAAA,MACnC,SAAS,KAAK,UAAU,KAAK,IAAI;AAAA,MACjC,uBAAuB,KAAK,wBAAwB,KAAK,IAAI;AAAA,IAC/D;AAEA,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,0BAA0B;AACxB,WAAO,MAAM,KAAK,KAAK,qBAAqB,OAAO,CAAC,EAAE,KAAK,OAAO;AAAA,EACpE;AAAA,EAEA,2BAA2B,QAAQ;AACjC,QAAI,CAAC,OAAO,QAAQ,iBAAiB;AACnC,aAAO,QAAQ,kBAAkB,OAAO,MAAM,WAAW;AAAA,IAC3D;AAAA,EACF;AAAA,EAEA,iBAAiB,QAAQ;AACvB,WAAO,MAAM,UAAU;AACvB,WAAO,aAAa,eAAe,MAAM;AAAA,EAC3C;AAAA,EAEA,iBAAiB,QAAQ;AACvB,UAAM,WAAW,OAAO,QAAQ,oBAAoB,SAAY,OAAO,QAAQ,kBAAkB;AACjG,WAAO,MAAM,UAAU;AACvB,WAAO,gBAAgB,aAAa;AAAA,EACtC;AAAA,EAEA,yBAAyB,SAAS;AAChC,QAAI,CAAC,KAAK,QAAQ,iBAAiB,KAAK,QAAQ,cAAc,WAAW,GAAG;AAC1E;AAAA,IACF;AAEA,SAAK,QAAQ,cAAc,QAAQ,YAAU;AAC3C,UAAI,CAAC,KAAK,qBAAqB,IAAI,MAAM,GAAG;AAC1C;AAAA,MACF;AAEA,UAAI,SAAS;AACX,aAAK,iBAAiB,MAAM;AAAA,MAC9B,OAAO;AACL,aAAK,iBAAiB,MAAM;AAAA,MAC9B;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,OAAO;AACL,UAAM,aAAa,KAAK,QAAQ,cAAc,KAAK;AAGnD,eAAW,iBAAiB,aAAa,KAAK,SAAS,SAAS;AAChE,eAAW,iBAAiB,cAAc,KAAK,SAAS,UAAU;AAGlE,aAAS,iBAAiB,aAAa,KAAK,SAAS,SAAS;AAC9D,aAAS,iBAAiB,WAAW,KAAK,SAAS,OAAO;AAC1D,aAAS,iBAAiB,aAAa,KAAK,SAAS,WAAW,EAAE,SAAS,MAAM,CAAC;AAClF,aAAS,iBAAiB,YAAY,KAAK,SAAS,QAAQ;AAG5D,SAAK,QAAQ,iBAAiB,WAAW,KAAK,SAAS,OAAO;AAG9D,QAAI,KAAK,QAAQ,iBAAiB,KAAK,QAAQ,cAAc,SAAS,GAAG;AACvE,WAAK,QAAQ,cAAc,QAAQ,YAAU;AAC3C,eAAO,iBAAiB,aAAa,KAAK,SAAS,qBAAqB;AACxE,eAAO,iBAAiB,cAAc,KAAK,SAAS,qBAAqB;AAEzE,cAAM,UAAU,OAAO,QAAQ,wBAAwB;AACvD,aAAK,qBAAqB,IAAI,QAAQ,OAAO;AAC7C,YAAI,SAAS;AACX,eAAK,2BAA2B,MAAM;AACtC,eAAK,iBAAiB,MAAM;AAAA,QAC9B;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,YAAY,GAAG;AAEb,QAAI,EAAE,OAAO,UAAU,SAAS,GAAG,KAAK,QAAQ,WAAW,gBAAgB,GAAG;AAC5E;AAAA,IACF;AAGA,QAAI,KAAK,QAAQ,eAAe,CAAC,KAAK,QAAQ,YAAY,CAAC,GAAG;AAC5D;AAAA,IACF;AAEA,SAAK,cAAc,EAAE,SAAS,EAAE,OAAO;AACvC,MAAE,eAAe;AAAA,EACnB;AAAA,EAEA,aAAa,GAAG;AAEd,QAAI,EAAE,OAAO,UAAU,SAAS,GAAG,KAAK,QAAQ,WAAW,gBAAgB,GAAG;AAC5E;AAAA,IACF;AAGA,QAAI,KAAK,QAAQ,eAAe,CAAC,KAAK,QAAQ,YAAY,CAAC,GAAG;AAC5D;AAAA,IACF;AAEA,UAAM,QAAQ,EAAE,QAAQ,CAAC;AACzB,SAAK,cAAc,MAAM,SAAS,MAAM,OAAO;AAAA,EACjD;AAAA,EAEA,wBAAwB,GAAG;AACzB,MAAE,eAAe;AACjB,MAAE,gBAAgB;AAElB,UAAM,SAAS,EAAE;AACjB,SAAK,kBAAkB,OAAO,aAAa,gBAAgB;AAE3D,UAAM,UAAU,EAAE,WAAW,EAAE,UAAU,CAAC,GAAG;AAC7C,UAAM,UAAU,EAAE,WAAW,EAAE,UAAU,CAAC,GAAG;AAE7C,SAAK,cAAc,SAAS,OAAO;AAAA,EACrC;AAAA,EAEA,YAAY,GAAG;AACb,QAAI,KAAK,YAAY;AACnB,WAAK,KAAK,EAAE,SAAS,EAAE,OAAO;AAC9B,QAAE,eAAe;AAAA,IACnB,WAAW,KAAK,YAAY;AAC1B,WAAK,OAAO,EAAE,SAAS,EAAE,OAAO;AAChC,QAAE,eAAe;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,YAAY,GAAG;AACb,QAAI,KAAK,cAAc,KAAK,YAAY;AACtC,YAAM,QAAQ,EAAE,QAAQ,CAAC;AACzB,UAAI,KAAK,YAAY;AACnB,aAAK,KAAK,MAAM,SAAS,MAAM,OAAO;AAAA,MACxC,OAAO;AACL,aAAK,OAAO,MAAM,SAAS,MAAM,OAAO;AAAA,MAC1C;AACA,QAAE,eAAe;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,YAAY;AACV,QAAI,KAAK,YAAY;AACnB,WAAK,aAAa;AAAA,IACpB,WAAW,KAAK,YAAY;AAC1B,WAAK,aAAa;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,aAAa;AACX,QAAI,KAAK,YAAY;AACnB,WAAK,aAAa;AAAA,IACpB,WAAW,KAAK,YAAY;AAC1B,WAAK,aAAa;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,UAAU,GAAG;AAEX,QAAI,EAAE,IAAI,YAAY,MAAM,KAAK,QAAQ,gBAAgB,YAAY,GAAG;AACtE,QAAE,eAAe;AACjB,WAAK,uBAAuB;AAC5B;AAAA,IACF;AAGA,QAAI,EAAE,IAAI,YAAY,MAAM,KAAK,QAAQ,kBAAkB,YAAY,GAAG;AACxE,QAAE,eAAe;AACjB,UAAI,KAAK,wBAAwB,GAAG;AAClC,aAAK,wBAAwB;AAAA,MAC/B,OAAO;AACL,aAAK,yBAAyB;AAAA,MAChC;AACA;AAAA,IACF;AAGA,QAAI,EAAE,QAAQ,UAAU;AACtB,UAAI,KAAK,mBAAmB;AAC1B,UAAE,eAAe;AACjB,aAAK,yBAAyB;AAC9B;AAAA,MACF;AACA,UAAI,KAAK,oBAAoB,KAAK,oBAAoB;AACpD,UAAE,eAAe;AACjB,aAAK,wBAAwB;AAC7B,aAAK,0BAA0B;AAC/B;AAAA,MACF;AAAA,IACF;AAGA,QAAI,CAAC,aAAa,cAAc,WAAW,WAAW,EAAE,SAAS,EAAE,GAAG,GAAG;AACvE,UAAI,KAAK,kBAAkB;AACzB,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAClB,aAAK,aAAa,EAAE,KAAK,EAAE,QAAQ;AAAA,MACrC,WAAW,KAAK,oBAAoB;AAClC,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAClB,aAAK,eAAe,EAAE,KAAK,EAAE,QAAQ;AAAA,MACvC;AAAA,IACF;AAGA,QAAI,EAAE,QAAQ,WAAW,KAAK,oBAAoB,KAAK,qBAAqB;AAC1E,QAAE,eAAe;AACjB,WAAK,cAAc;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,cAAc,SAAS,SAAS;AAE9B,UAAM,OAAO,KAAK,QAAQ,sBAAsB;AAIhD,UAAM,gBAAgB,OAAO,iBAAiB,KAAK,OAAO;AAC1D,UAAM,kBAAkB,cAAc,UAAU,UACzB,cAAc,WAAW,UACzB,cAAc,cAAc;AAEnD,SAAK,kBAAkB;AACvB,SAAK,kBAAkB;AAEvB,QAAI,iBAAiB;AAEnB,UAAI,YAAY;AAEhB,UAAI,cAAc,aAAa,YAAY;AAEzC,cAAM,eAAe,KAAK,QAAQ,gBAAgB,SAAS;AAC3D,cAAM,aAAa,aAAa,sBAAsB;AACtD,qBAAa,KAAK,OAAO,WAAW;AACpC,oBAAY,KAAK,MAAM,WAAW;AAClC,aAAK,kBAAkB,WAAW;AAClC,aAAK,kBAAkB,WAAW;AAAA,MACpC,WAAW,cAAc,aAAa,SAAS;AAC7C,cAAM,aAAa,WAAW,cAAc,IAAI;AAChD,cAAM,YAAY,WAAW,cAAc,GAAG;AAC9C,cAAM,UAAU,OAAO,SAAS,UAAU;AAC1C,cAAM,SAAS,OAAO,SAAS,SAAS;AACxC,qBAAa,UAAU,aAAa,KAAK;AACzC,oBAAY,SAAS,YAAY,KAAK;AACtC,aAAK,kBAAkB,KAAK,OAAO;AACnC,aAAK,kBAAkB,KAAK,MAAM;AAAA,MACpC,OAAO;AAEL,qBAAa,KAAK;AAClB,oBAAY,KAAK;AACjB,aAAK,kBAAkB,KAAK,OAAO;AACnC,aAAK,kBAAkB,KAAK,MAAM;AAAA,MACpC;AAGA,YAAM,iBAAiB,KAAK,QAAQ,MAAM;AAC1C,UAAI,aAAa,eACd,MAAM,GAAG,EACT,OAAO,UAAQ;AACd,cAAM,UAAU,KAAK,KAAK;AAE1B,YAAI,CAAC,QAAS,QAAO;AAErB,cAAM,aAAa,QAAQ,QAAQ,GAAG;AACtC,YAAI,eAAe,GAAI,QAAO;AAE9B,cAAM,WAAW,QAAQ,UAAU,GAAG,UAAU,EAAE,KAAK;AACvD,cAAM,QAAQ,QAAQ,UAAU,aAAa,CAAC,EAAE,KAAK;AAGrD,YAAI,CAAC,SAAS,UAAU,GAAI,QAAO;AAGnC,YAAI,aAAa,WAAW,aAAa,YAAY,aAAa,eAC9D,aAAa,UAAU,aAAa,SAAS,aAAa,SAAS;AACrE,iBAAO;AAAA,QACT;AAGA,YAAI,SAAS,WAAW,cAAc,GAAG;AACvC,iBAAO;AAAA,QACT;AAEA,eAAO;AAAA,MACT,CAAC,EACA,KAAK,IAAI;AAEZ,UAAI,WAAY,eAAc;AAC9B,oBAAc,SAAS,UAAU,YAAY,SAAS;AAGtD,WAAK,QAAQ,MAAM,UAAU;AAAA,IAC/B;AAIA,UAAM,YAAY,KAAK,QAAQ,sBAAsB;AACrD,SAAK,cAAc,UAAU,UAAU;AACvC,SAAK,cAAc,UAAU,UAAU;AAEvC,SAAK,aAAa;AAClB,SAAK,QAAQ,UAAU,IAAI,GAAG,KAAK,QAAQ,WAAW,WAAW;AACjE,aAAS,KAAK,MAAM,SAAS;AAC7B,aAAS,KAAK,MAAM,aAAa;AAAA,EACnC;AAAA,EAEA,KAAK,SAAS,SAAS;AACrB,QAAI,CAAC,KAAK,WAAY;AAGtB,QAAI,OAAO,UAAU,KAAK,cAAc,KAAK;AAC7C,QAAI,OAAO,UAAU,KAAK,cAAc,KAAK;AAG7C,QAAI,KAAK,QAAQ,qBAAqB;AACpC,YAAM,OAAO,KAAK,QAAQ,sBAAsB;AAChD,YAAM,gBAAgB,SAAS,gBAAgB;AAC/C,YAAM,iBAAiB,SAAS,gBAAgB;AAGhD,YAAM,aAAa;AACnB,YAAM,OAAO,EAAE,KAAK,QAAQ;AAC5B,YAAM,OAAO,EAAE,KAAK,SAAS;AAC7B,YAAM,OAAO,gBAAgB;AAC7B,YAAM,OAAO,iBAAiB;AAE9B,aAAO,KAAK,IAAI,MAAM,KAAK,IAAI,MAAM,IAAI,CAAC;AAC1C,aAAO,KAAK,IAAI,MAAM,KAAK,IAAI,MAAM,IAAI,CAAC;AAAA,IAC5C;AAEA,SAAK,QAAQ,MAAM,OAAO,GAAG,IAAI;AACjC,SAAK,QAAQ,MAAM,MAAM,GAAG,IAAI;AAGhC,QAAI,KAAK,QAAQ,QAAQ;AACvB,WAAK,QAAQ,OAAO,EAAE,GAAG,MAAM,GAAG,KAAK,CAAC;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,eAAe;AACb,SAAK,aAAa;AAClB,SAAK,QAAQ,UAAU,OAAO,GAAG,KAAK,QAAQ,WAAW,WAAW;AACpE,aAAS,KAAK,MAAM,SAAS;AAC7B,aAAS,KAAK,MAAM,aAAa;AAGjC,SAAK,qBAAqB;AAG1B,QAAI,KAAK,QAAQ,WAAW;AAC1B,WAAK,QAAQ,UAAU;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,cAAc,SAAS,SAAS;AAC9B,SAAK,aAAa;AAClB,SAAK,eAAe;AACpB,SAAK,eAAe;AAEpB,UAAM,OAAO,KAAK,QAAQ,sBAAsB;AAChD,SAAK,mBAAmB,KAAK;AAC7B,SAAK,oBAAoB,KAAK;AAC9B,SAAK,kBAAkB,KAAK;AAC5B,SAAK,iBAAiB,KAAK;AAE3B,SAAK,QAAQ,UAAU,IAAI,GAAG,KAAK,QAAQ,WAAW,WAAW;AACjE,aAAS,KAAK,MAAM,aAAa;AAGjC,QAAI,KAAK,QAAQ,eAAe;AAC9B,WAAK,QAAQ,cAAc;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,OAAO,SAAS,SAAS;AACvB,QAAI,CAAC,KAAK,WAAY;AAEtB,UAAM,SAAS,UAAU,KAAK;AAC9B,UAAM,SAAS,UAAU,KAAK;AAE9B,QAAI,WAAW,KAAK;AACpB,QAAI,YAAY,KAAK;AACrB,QAAI,UAAU,KAAK;AACnB,QAAI,SAAS,KAAK;AAGlB,QAAI,KAAK,gBAAgB,SAAS,GAAG,GAAG;AACtC,iBAAW,KAAK,IAAI,KAAK,QAAQ,UAAU,KAAK,mBAAmB,MAAM;AAAA,IAC3E;AACA,QAAI,KAAK,gBAAgB,SAAS,GAAG,GAAG;AACtC,YAAM,gBAAgB,KAAK,IAAI,KAAK,QAAQ,UAAU,KAAK,mBAAmB,MAAM;AACpF,gBAAU,KAAK,mBAAmB,KAAK,mBAAmB;AAC1D,iBAAW;AAAA,IACb;AAEA,UAAM,iBAAiB,OAAO,KAAK,QAAQ,aAAa,aACpD,KAAK,QAAQ,SAAS,IACtB,KAAK,QAAQ;AACjB,QAAI,OAAO,SAAS,cAAc,GAAG;AACnC,YAAM,eAAe,KAAK,IAAI,UAAU,cAAc;AACtD,UAAI,iBAAiB,YAAY,KAAK,gBAAgB,SAAS,GAAG,GAAG;AACnE,mBAAW,WAAW;AAAA,MACxB;AACA,iBAAW;AAAA,IACb;AAGA,QAAI,CAAC,KAAK,QAAQ,qBAAqB;AACrC,UAAI,KAAK,gBAAgB,SAAS,GAAG,GAAG;AACtC,oBAAY,KAAK,IAAI,KAAK,QAAQ,WAAW,KAAK,oBAAoB,MAAM;AAAA,MAC9E;AACA,UAAI,KAAK,gBAAgB,SAAS,GAAG,GAAG;AACtC,cAAM,iBAAiB,KAAK,IAAI,KAAK,QAAQ,WAAW,KAAK,oBAAoB,MAAM;AACvF,iBAAS,KAAK,kBAAkB,KAAK,oBAAoB;AACzD,oBAAY;AAAA,MACd;AAEA,YAAM,kBAAkB,OAAO,KAAK,QAAQ,cAAc,aACtD,KAAK,QAAQ,UAAU,IACvB,KAAK,QAAQ;AACjB,UAAI,OAAO,SAAS,eAAe,GAAG;AACpC,cAAM,gBAAgB,KAAK,IAAI,WAAW,eAAe;AACzD,YAAI,kBAAkB,aAAa,KAAK,gBAAgB,SAAS,GAAG,GAAG;AACrE,oBAAU,YAAY;AAAA,QACxB;AACA,oBAAY;AAAA,MACd;AAAA,IACF;AAGA,SAAK,QAAQ,MAAM,QAAQ,GAAG,QAAQ;AACtC,QAAI,CAAC,KAAK,QAAQ,qBAAqB;AACrC,WAAK,QAAQ,MAAM,SAAS,GAAG,SAAS;AAAA,IAC1C,OAAO;AACL,WAAK,QAAQ,MAAM,SAAS;AAAA,IAC9B;AAGA,QAAI,KAAK,gBAAgB,SAAS,GAAG,GAAG;AACtC,WAAK,QAAQ,MAAM,OAAO,GAAG,OAAO;AAAA,IACtC;AACA,QAAI,KAAK,gBAAgB,SAAS,GAAG,KAAK,CAAC,KAAK,QAAQ,qBAAqB;AAC3E,WAAK,QAAQ,MAAM,MAAM,GAAG,MAAM;AAAA,IACpC;AAGA,QAAI,KAAK,QAAQ,UAAU;AACzB,WAAK,QAAQ,SAAS,EAAE,OAAO,UAAU,QAAQ,WAAW,MAAM,SAAS,KAAK,OAAO,CAAC;AAAA,IAC1F;AAAA,EACF;AAAA,EAEA,eAAe;AACb,SAAK,aAAa;AAClB,SAAK,kBAAkB;AACvB,SAAK,QAAQ,UAAU,OAAO,GAAG,KAAK,QAAQ,WAAW,WAAW;AACpE,aAAS,KAAK,MAAM,aAAa;AAGjC,SAAK,qBAAqB;AAG1B,QAAI,KAAK,QAAQ,aAAa;AAC5B,WAAK,QAAQ,YAAY;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,yBAAyB;AACvB,QAAI,KAAK,kBAAkB;AACzB,WAAK,wBAAwB;AAAA,IAC/B,OAAO;AACL,WAAK,uBAAuB;AAAA,IAC9B;AAAA,EACF;AAAA,EAEA,yBAAyB;AACvB,SAAK,mBAAmB;AACxB,SAAK,qBAAqB;AAC1B,SAAK,QAAQ,UAAU,IAAI,GAAG,KAAK,QAAQ,WAAW,gBAAgB;AACtE,SAAK,QAAQ,UAAU,OAAO,GAAG,KAAK,QAAQ,WAAW,kBAAkB;AAC3E,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,0BAA0B;AACxB,SAAK,mBAAmB;AACxB,SAAK,QAAQ,UAAU,OAAO,GAAG,KAAK,QAAQ,WAAW,gBAAgB;AAAA,EAC3E;AAAA,EAEA,2BAA2B;AACzB,QAAI,KAAK,oBAAoB;AAC3B,WAAK,0BAA0B;AAAA,IACjC,OAAO;AACL,WAAK,yBAAyB;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,2BAA2B;AACzB,SAAK,qBAAqB;AAC1B,SAAK,mBAAmB;AACxB,SAAK,QAAQ,UAAU,IAAI,GAAG,KAAK,QAAQ,WAAW,kBAAkB;AACxE,SAAK,QAAQ,UAAU,OAAO,GAAG,KAAK,QAAQ,WAAW,gBAAgB;AACzE,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,4BAA4B;AAC1B,SAAK,qBAAqB;AAC1B,SAAK,QAAQ,UAAU,OAAO,GAAG,KAAK,QAAQ,WAAW,kBAAkB;AAAA,EAC7E;AAAA,EAEA,wBAAwB,EAAE,QAAQ,KAAK,IAAI,CAAC,GAAG;AAC7C,QAAI,CAAC,KAAK,wBAAwB,GAAG;AACnC,WAAK,yBAAyB;AAC9B;AAAA,IACF;AAEA,QAAI,KAAK,mBAAmB;AAC1B;AAAA,IACF;AAEA,SAAK,oBAAoB;AACzB,SAAK,yBAAyB,IAAI;AAClC,SAAK,QAAQ,UAAU,IAAI,GAAG,KAAK,QAAQ,WAAW,YAAY;AAClE,SAAK,yBAAyB;AAE9B,QAAI,OAAO;AACT,WAAK,aAAa;AAAA,IACpB;AAEA,QAAI,OAAO,KAAK,QAAQ,0BAA0B,YAAY;AAC5D,WAAK,QAAQ,sBAAsB,IAAI;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,yBAAyB,EAAE,QAAQ,MAAM,IAAI,CAAC,GAAG;AAC/C,QAAI,CAAC,KAAK,mBAAmB;AAC3B;AAAA,IACF;AAEA,SAAK,oBAAoB;AACzB,SAAK,yBAAyB,KAAK;AACnC,SAAK,QAAQ,UAAU,OAAO,GAAG,KAAK,QAAQ,WAAW,YAAY;AACrE,SAAK,0BAA0B;AAE/B,QAAI,OAAO;AACT,WAAK,aAAa;AAAA,IACpB;AAEA,QAAI,OAAO,KAAK,QAAQ,0BAA0B,YAAY;AAC5D,WAAK,QAAQ,sBAAsB,KAAK;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,0BAA0B;AACxB,QAAI,KAAK,mBAAmB;AAC1B,WAAK,yBAAyB;AAAA,IAChC,OAAO;AACL,WAAK,wBAAwB;AAAA,IAC/B;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,eAAe;AACb,QAAI,OAAO,KAAK,QAAQ,UAAU,YAAY;AAC5C,UAAI;AACF,aAAK,QAAQ,MAAM,EAAE,eAAe,KAAK,CAAC;AAAA,MAC5C,SAAS,GAAG;AAEV,aAAK,QAAQ,MAAM;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,aAAa,KAAK,UAAU;AAC1B,UAAM,OAAO,WAAW,KAAK,QAAQ,oBAAoB,KAAK,QAAQ;AAGtE,QAAI,cAAc,WAAW,KAAK,QAAQ,MAAM,IAAI,KAAK;AACzD,QAAI,aAAa,WAAW,KAAK,QAAQ,MAAM,GAAG,KAAK;AAGvD,UAAM,gBAAgB,OAAO,iBAAiB,KAAK,OAAO;AAC1D,QAAI,cAAc,cAAc,QAAQ;AACtC,YAAM,OAAO,KAAK,QAAQ,sBAAsB;AAChD,oBAAc,KAAK;AACnB,mBAAa,KAAK;AAClB,WAAK,QAAQ,MAAM,YAAY;AAC/B,WAAK,QAAQ,MAAM,OAAO,GAAG,WAAW;AACxC,WAAK,QAAQ,MAAM,MAAM,GAAG,UAAU;AAAA,IACxC;AAGA,QAAI,OAAO;AACX,QAAI,OAAO;AAEX,YAAO,KAAK;AAAA,MACV,KAAK;AACH,gBAAQ;AACR;AAAA,MACF,KAAK;AACH,gBAAQ;AACR;AAAA,MACF,KAAK;AACH,gBAAQ;AACR;AAAA,MACF,KAAK;AACH,gBAAQ;AACR;AAAA,IACJ;AAGA,SAAK,QAAQ,MAAM,OAAO,GAAG,IAAI;AACjC,SAAK,QAAQ,MAAM,MAAM,GAAG,IAAI;AAGhC,QAAI,KAAK,QAAQ,QAAQ;AACvB,WAAK,QAAQ,OAAO,EAAE,GAAG,MAAM,GAAG,KAAK,CAAC;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,eAAe,KAAK,UAAU;AAC5B,UAAM,OAAO,WAAW,KAAK,QAAQ,oBAAoB,KAAK,QAAQ;AACtE,UAAM,OAAO,KAAK,QAAQ,sBAAsB;AAEhD,QAAI,QAAQ,KAAK;AACjB,QAAI,SAAS,KAAK;AAGlB,YAAO,KAAK;AAAA,MACV,KAAK;AACH,iBAAS;AACT;AAAA,MACF,KAAK;AACH,iBAAS;AACT;AAAA,MACF,KAAK;AACH,YAAI,KAAK,QAAQ,qBAAqB;AACpC,mBAAS;AAAA,QACX,OAAO;AACL,oBAAU;AAAA,QACZ;AACA;AAAA,MACF,KAAK;AACH,YAAI,KAAK,QAAQ,qBAAqB;AACpC,mBAAS;AAAA,QACX,OAAO;AACL,oBAAU;AAAA,QACZ;AACA;AAAA,IACJ;AAGA,YAAQ,KAAK,IAAI,KAAK,QAAQ,UAAU,KAAK;AAC7C,aAAS,KAAK,IAAI,KAAK,QAAQ,WAAW,MAAM;AAGhD,SAAK,QAAQ,MAAM,QAAQ,GAAG,KAAK;AACnC,QAAI,CAAC,KAAK,QAAQ,qBAAqB;AACrC,WAAK,QAAQ,MAAM,SAAS,GAAG,MAAM;AAAA,IACvC,OAAO;AACL,WAAK,QAAQ,MAAM,SAAS;AAAA,IAC9B;AAGA,QAAI,KAAK,QAAQ,UAAU;AACzB,WAAK,QAAQ,SAAS,EAAE,OAAO,OAAO,CAAC;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,gBAAgB;AACd,SAAK,QAAQ,MAAM,OAAO;AAC1B,SAAK,QAAQ,MAAM,MAAM;AACzB,SAAK,QAAQ,MAAM,YAAY;AAC/B,SAAK,QAAQ,MAAM,QAAQ;AAC3B,SAAK,QAAQ,MAAM,SAAS;AAG5B,SAAK,qBAAqB;AAG1B,QAAI,KAAK,QAAQ,QAAQ;AACvB,WAAK,QAAQ,OAAO,EAAE,UAAU,KAAK,CAAC;AAAA,IACxC;AAAA,EACF;AAAA,EAEA,UAAU;AACR,UAAM,aAAa,KAAK,QAAQ,cAAc,KAAK;AAEnD,SAAK,yBAAyB;AAG9B,eAAW,oBAAoB,aAAa,KAAK,SAAS,SAAS;AACnE,eAAW,oBAAoB,cAAc,KAAK,SAAS,UAAU;AAGrE,aAAS,oBAAoB,aAAa,KAAK,SAAS,SAAS;AACjE,aAAS,oBAAoB,WAAW,KAAK,SAAS,OAAO;AAC7D,aAAS,oBAAoB,aAAa,KAAK,SAAS,SAAS;AACjE,aAAS,oBAAoB,YAAY,KAAK,SAAS,QAAQ;AAG/D,SAAK,QAAQ,oBAAoB,WAAW,KAAK,SAAS,OAAO;AAGjE,QAAI,KAAK,QAAQ,iBAAiB,KAAK,QAAQ,cAAc,SAAS,GAAG;AACvE,WAAK,QAAQ,cAAc,QAAQ,YAAU;AAC3C,eAAO,oBAAoB,aAAa,KAAK,SAAS,qBAAqB;AAC3E,eAAO,oBAAoB,cAAc,KAAK,SAAS,qBAAqB;AAAA,MAC9E,CAAC;AAAA,IACH;AAGA,SAAK,QAAQ,UAAU;AAAA,MACrB,GAAG,KAAK,QAAQ,WAAW;AAAA,MAC3B,GAAG,KAAK,QAAQ,WAAW;AAAA,MAC3B,GAAG,KAAK,QAAQ,WAAW;AAAA,MAC3B,GAAG,KAAK,QAAQ,WAAW;AAAA,IAC7B;AAAA,EACF;AACF;;;AC7vBO,SAAS,eAAe,EAAE,aAAa,WAAW,MAAM,OAAO,WAAW,SAAS,eAAe,MAAM,GAAG;AAE9G,QAAM,mBAAmB,OAAO,UAAU,aAAa,MAAM,WAAW,aAAa,KAAK,MAAM,WAAW,SAAS,KAAK,MAAM,WAAW,WAAW;AACrJ,QAAM,gBAAgB,cAAc,mBAAoB,KAAK,EAAE,KAAK,KAAK,QAAS;AAElF,QAAM,SAAS,SAAS,cAAc,UAAU;AAAA,IAC5C,WAAW;AAAA,IACX,YAAY;AAAA,MACR,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,YAAY;AAAA,IAChB;AAAA,EACJ,CAAC;AAED,MAAI,MAAM;AACN,WAAO,YAAY,kBAAkB,IAAI,CAAC;AAAA,EAC9C;AAGA,QAAM,YAAY,OAAO,UAAU,aAAa,MAAM,WAAW,aAAa,KAAK,MAAM,WAAW,SAAS,KAAK,MAAM,WAAW,WAAW;AAC9I,QAAM,cAAc,YAAa,KAAK,EAAE,KAAK,KAAK,QAAS;AAE3D,QAAM,OAAO,SAAS,cAAc,QAAQ;AAAA,IACxC;AAAA,IACA,WAAW,eAAe,GAAG,WAAW,mBAAmB;AAAA,IAC3D,YAAY;AAAA,MACR,eAAe;AAAA,IACnB;AAAA,EACJ,CAAC;AACD,SAAO,YAAY,IAAI;AAEvB,MAAI,SAAS;AACT,WAAO,iBAAiB,SAAS,OAAO;AAAA,EAC5C;AAEA,SAAO;AACX;AASO,SAAS,6BAA6B,MAAM,QAAQ,cAAc,SAAS;AAC9E,MAAI,CAAC,KAAM;AAEX,QAAM,YAAY,MAAM,KAAK,KAAK,iBAAiB,YAAY,CAAC;AAChE,MAAI,UAAU,WAAW,EAAG;AAE5B,QAAM,gBAAgB,CAAC,MAAM;AACzB,UAAM,eAAe,UAAU,QAAQ,SAAS,aAAa;AAE7D,YAAQ,EAAE,KAAK;AAAA,MACX,KAAK;AACD,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAClB,cAAM,aAAa,eAAe,KAAK,UAAU;AACjD,kBAAU,QAAQ,CAAC,MAAM,QAAQ;AAC7B,eAAK,aAAa,YAAY,QAAQ,YAAY,MAAM,IAAI;AAAA,QAChE,CAAC;AACD,kBAAU,SAAS,EAAE,MAAM,EAAE,eAAe,MAAM,CAAC;AACnD,kBAAU,SAAS,EAAE,eAAe,EAAE,UAAU,UAAU,OAAO,UAAU,CAAC;AAC5E;AAAA,MAEJ,KAAK;AACD,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAClB,cAAM,aAAa,eAAe,IAAI,UAAU,UAAU,UAAU;AACpE,kBAAU,QAAQ,CAAC,MAAM,QAAQ;AAC7B,eAAK,aAAa,YAAY,QAAQ,YAAY,MAAM,IAAI;AAAA,QAChE,CAAC;AACD,kBAAU,SAAS,EAAE,MAAM,EAAE,eAAe,MAAM,CAAC;AACnD,kBAAU,SAAS,EAAE,eAAe,EAAE,UAAU,UAAU,OAAO,UAAU,CAAC;AAC5E;AAAA,MAEJ,KAAK;AACD,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAClB,kBAAU,QAAQ,CAAC,MAAM,QAAQ;AAC7B,eAAK,aAAa,YAAY,QAAQ,IAAI,MAAM,IAAI;AAAA,QACxD,CAAC;AACD,kBAAU,CAAC,EAAE,MAAM,EAAE,eAAe,MAAM,CAAC;AAC3C,kBAAU,CAAC,EAAE,eAAe,EAAE,UAAU,UAAU,OAAO,UAAU,CAAC;AACpE;AAAA,MAEJ,KAAK;AACD,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAClB,cAAM,YAAY,UAAU,SAAS;AACrC,kBAAU,QAAQ,CAAC,MAAM,QAAQ;AAC7B,eAAK,aAAa,YAAY,QAAQ,YAAY,MAAM,IAAI;AAAA,QAChE,CAAC;AACD,kBAAU,SAAS,EAAE,MAAM,EAAE,eAAe,MAAM,CAAC;AACnD,kBAAU,SAAS,EAAE,eAAe,EAAE,UAAU,UAAU,OAAO,UAAU,CAAC;AAC5E;AAAA,MAEJ,KAAK;AAAA,MACL,KAAK;AACD,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAClB,YAAI,SAAS,iBAAiB,UAAU,SAAS,SAAS,aAAa,GAAG;AACtE,mBAAS,cAAc,MAAM;AAC7B,cAAI,SAAS;AACT,uBAAW,MAAM;AACb,kBAAI,UAAU,SAAS,SAAS,MAAM,GAAG;AACrC,uBAAO,MAAM;AAAA,cACjB;AAAA,YACJ,GAAG,CAAC;AAAA,UACR;AAAA,QACJ;AACA;AAAA,MAEJ,KAAK;AACD,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAClB,YAAI,SAAS;AACT,kBAAQ;AAAA,QACZ;AACA;AAAA,IACR;AAAA,EACJ;AAEA,OAAK,iBAAiB,WAAW,eAAe,IAAI;AACpD,SAAO;AACX;AAQO,SAAS,mBAAmB,MAAM,cAAc,QAAQ,GAAG;AAC9D,MAAI,CAAC,KAAM;AAEX,aAAW,MAAM;AACb,UAAM,YAAY,MAAM,KAAK,KAAK,iBAAiB,YAAY,CAAC;AAChE,QAAI,UAAU,SAAS,GAAG;AACtB,gBAAU,QAAQ,CAAC,MAAM,UAAU;AAC/B,aAAK,aAAa,YAAY,UAAU,IAAI,MAAM,IAAI;AAAA,MAC1D,CAAC;AACD,mBAAa,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC;AAEvC,gBAAU,CAAC,EAAE,eAAe,EAAE,UAAU,UAAU,OAAO,UAAU,CAAC;AAAA,IACxE;AAAA,EACJ,GAAG,KAAK;AACZ;;;ACrJO,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,WAAW;AAAA,EACX,UAAU,CAAC;AACb,GAAG;AAED,QAAM,YAAY,OAAO,cAAc,aACpC,UAAU,WAAW,aAAa,KAClC,UAAU,WAAW,SAAS,KAC9B,UAAU,WAAW,WAAW,KAChC,UAAU,WAAW,WAAW;AACnC,QAAM,mBAAmB,YAAa,KAAK,EAAE,SAAS,KAAK,YAAa;AAExE,QAAM,QAAQ,SAAS,cAAc,SAAS;AAAA,IAC5C,WAAW;AAAA,IACX,aAAa;AAAA,IACb,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS,SAAS,mBAAmB;AAAA,IACvC;AAAA,EACF,CAAC;AAED,QAAM,SAAS,SAAS,cAAc,UAAU;AAAA,IAC9C,WAAW;AAAA,IACX,YAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS,SAAS,mBAAmB;AAAA,IACvC;AAAA,EACF,CAAC;AAGD,UAAQ,QAAQ,SAAO;AACrB,UAAM,SAAS,SAAS,cAAc,UAAU;AAAA,MAC9C,aAAa,IAAI;AAAA,MACjB,YAAY;AAAA,QACV,SAAS,IAAI;AAAA,QACb,YAAY,IAAI,WAAW,aAAa;AAAA,MAC1C;AAAA,IACF,CAAC;AACD,WAAO,YAAY,MAAM;AAAA,EAC3B,CAAC;AAGD,MAAI,UAAU;AACZ,WAAO,iBAAiB,UAAU,QAAQ;AAAA,EAC5C;AAEA,SAAO,EAAE,OAAO,OAAO;AACzB;AAqBO,SAAS,qBAAqB,SAAS;AAC5C,MAAI,CAAC,QAAS;AAEd,GAAC,aAAa,OAAO,EAAE,QAAQ,eAAa;AAC1C,YAAQ,iBAAiB,WAAW,CAAC,MAAM;AACzC,QAAE,gBAAgB;AAAA,IACpB,CAAC;AAAA,EACH,CAAC;AACH;",
|
|
6
|
-
"names": ["translations"]
|
|
7
|
-
}
|