saltfish 0.1.21 → 0.1.23

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/player.js CHANGED
@@ -1,9 +1,9 @@
1
1
 
2
2
  /*!
3
- * Saltfish playlist Player v0.1.21
3
+ * Saltfish playlist Player v0.1.23
4
4
  * (c) 2025
5
5
  * Released under the MIT License.
6
6
 
7
7
  */
8
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).SaltfishplaylistPlayer=e()}(this,(function(){"use strict";var t=Object.defineProperty,e=(e,n,i)=>((e,n,i)=>n in e?t(e,n,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[n]=i)(e,"symbol"!=typeof n?n+"":n,i);class n{constructor(){e(this,"container",null),e(this,"shadowRoot",null),e(this,"styleElement",null)}create(){if(this.container)return;this.container=document.createElement("div"),this.container.id="saltfish-container",document.body.appendChild(this.container),this.shadowRoot=this.container.attachShadow({mode:"open"}),this.styleElement=document.createElement("style"),this.styleElement.textContent=this.getBaseStyles(),this.shadowRoot.appendChild(this.styleElement);const t=document.createElement("div");t.id="sf-player-root",this.shadowRoot.appendChild(t)}getShadowRoot(){return this.shadowRoot}getRootElement(){if(!this.shadowRoot)return null;return this.shadowRoot.getElementById("sf-player-root")}addStyles(t){this.styleElement&&(this.styleElement.textContent+=t)}remove(){this.container&&(document.body.removeChild(this.container),this.container=null,this.shadowRoot=null,this.styleElement=null)}getBaseStyles(){return"\n /* \n * CSS Reset for the Saltfish playlist Player\n * Minimal reset for the Shadow DOM to ensure consistent rendering\n */\n\n:host {\n all: initial;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;\n box-sizing: border-box;\n}\n\n:host *,\n:host *::before,\n:host *::after {\n box-sizing: inherit;\n margin: 0;\n padding: 0;\n}\n\nbutton {\n background: none;\n border: none;\n cursor: pointer;\n font: inherit;\n outline: none;\n padding: 0;\n} \n /* \n * Variables for the Saltfish playlist Player\n * Defines all design tokens used throughout the application\n */\n\n:host {\n /* Colors */\n --sf-primary-color: #4a9bff;\n --sf-secondary-color: #6ccfff;\n --sf-background-color: #1e1e1e;\n --sf-text-color: #ffffff;\n --sf-button-bg: rgba(0, 0, 0, 0.5);\n --sf-button-hover-bg: rgba(0, 0, 0, 0.7);\n --sf-overlay-gradient: linear-gradient(180deg, rgba(0, 0, 0, 0.7) 0%, transparent 30%, transparent 70%, rgba(0, 0, 0, 0.7) 100%);\n --sf-progress-gradient: linear-gradient(90deg, var(--sf-primary-color), var(--sf-secondary-color));\n --sf-error-color: #ff4d4d;\n --sf-error-bg: rgba(255, 77, 77, 0.1);\n \n /* Spacing */\n --sf-spacing-xs: 4px;\n --sf-spacing-sm: 8px;\n --sf-spacing-md: 12px;\n --sf-spacing-lg: 16px;\n --sf-spacing-xl: 24px;\n \n /* Sizes */\n --sf-player-width: 240px;\n --sf-player-height: 336px;\n --sf-player-min-width: 80px;\n --sf-player-min-height: 80px;\n --sf-control-button-size: 24px;\n --sf-play-button-size: 60px;\n --sf-minimize-button-size: 20px;\n --sf-mute-button-size: 32px;\n --sf-cc-button-size: 32px;\n --sf-cursor-size: 32px;\n \n /* Border radius */\n --sf-border-radius-sm: 4px;\n --sf-border-radius-md: 8px;\n --sf-border-radius-lg: 16px;\n --sf-border-radius-circle: 50%;\n \n /* Transitions */\n --sf-transition-fast: 0.1s ease;\n --sf-transition-normal: 0.2s ease;\n --sf-transition-slow: 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);\n \n /* Shadows */\n --sf-shadow-small: 0 2px 5px rgba(0, 0, 0, 0.2);\n --sf-shadow-medium: 0 4px 8px rgba(0, 0, 0, 0.15);\n --sf-shadow-large: 0 10px 25px rgba(0, 0, 0, 0.2);\n \n /* Z-index layering */\n --sf-z-index-base: 1;\n --sf-z-index-overlay: 2;\n --sf-z-index-controls: 10;\n --sf-z-index-cursor: 9999;\n --sf-z-index-player: 2147483648;\n \n /* Font sizes */\n --sf-font-size-sm: 14px;\n --sf-font-size-md: 16px;\n --sf-font-size-lg: 18px;\n --sf-font-size-xl: 24px;\n} \n\n/* Mobile device responsive adjustments - make player smaller for mobile screens */\n@media (max-width: 768px) {\n :host {\n /* Reduce player size on mobile for better space utilization */\n --sf-player-width: 180px; /* 25% smaller than desktop (240px -> 180px) */\n --sf-player-height: 252px; /* 25% smaller than desktop (336px -> 252px) */\n --sf-player-min-width: 60px; /* Smaller when minimized (80px -> 60px) */\n --sf-player-min-height: 60px; /* Smaller when minimized (80px -> 60px) */\n \n /* Keep controls touch-friendly despite smaller player size */\n --sf-play-button-size: 44px; /* Smaller but still touch-friendly (60px -> 44px) */\n --sf-control-button-size: 28px; /* Keep larger for touch targets (24px -> 28px) */\n --sf-mute-button-size: 26px; /* Smaller for mobile (32px -> 26px) */\n --sf-cc-button-size: 26px; /* Smaller for mobile (32px -> 26px) */\n --sf-minimize-button-size: 24px; /* Keep larger for touch interaction */\n }\n}\n\n/* Touch device specific adjustments (tablets and larger touch devices, excluding mobile) */\n@media (pointer: coarse) and (min-width: 769px) {\n :host {\n /* Ensure touch-friendly sizes even on larger touch devices */\n --sf-control-button-size: 28px;\n --sf-mute-button-size: 38px;\n --sf-cc-button-size: 38px;\n --sf-minimize-button-size: 24px; /* Larger touch target for minimize button */\n }\n} \n \n /* \n * Player component styles for the Saltfish playlist Player\n * Following BEM naming convention\n */\n\n/* Main player container */\n.sf-player {\n border-radius: var(--sf-border-radius-lg);\n box-shadow: 0 25px 50px rgba(0, 0, 0, 0.45), 0 10px 20px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(255, 255, 255, 0.08);\n transition: all var(--sf-transition-slow);\n position: relative;\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n}\n\n/* Dark gradient overlay at bottom of player */\n.sf-player::before {\n content: '';\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 33.33%; /* One third of player height */\n background: linear-gradient(to top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0) 100%);\n pointer-events: none;\n z-index: var(--sf-z-index-overlay);\n border-radius: 8px;\n}\n\n/* Hide gradient overlay when minimized */\n.sf-player--minimized::before {\n display: none;\n}\n\n/* Full-size player state */\n.sf-player:not(.sf-player--minimized) {\n width: var(--sf-player-width);\n height: var(--sf-player-height);\n}\n\n/* Autoplay fallback state - ensure play button is visible */\n.sf-player--waiting-for-user-interaction .sf-controls-container__play-button {\n display: flex !important;\n opacity: 1 !important;\n visibility: visible !important;\n}\n\n/* Also show the center play button in autoplay fallback state */\n.sf-player--waiting-for-user-interaction .sf-player__center-play-button {\n display: flex !important;\n opacity: 1 !important;\n z-index: calc(var(--sf-z-index-controls) + 20) !important; /* Higher z-index to appear above overlay */\n}\n\n/* Make the autoplay fallback state more prominent to indicate need for interaction */\n.sf-player--waiting-for-user-interaction::after {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n pointer-events: none;\n z-index: var(--sf-z-index-overlay);\n}\n\n/* Player state: minimized */\n.sf-player--minimized {\n /* Equal width and height are essential for maintaining a perfect circle when using border-radius: 50% */\n width: var(--sf-player-min-width);\n height: var(--sf-player-min-height);\n border-radius: var(--sf-border-radius-circle);\n box-shadow: 0 15px 30px rgba(0, 0, 0, 0.35), 0 5px 15px rgba(0, 0, 0, 0.25), 0 0 0 2px rgba(255, 255, 255, 0.08);\n cursor: pointer;\n /* Force overriding any inline styles that might be applied */\n max-width: var(--sf-player-min-width) !important;\n max-height: var(--sf-player-min-height) !important;\n min-width: var(--sf-player-min-width) !important;\n min-height: var(--sf-player-min-height) !important;\n}\n\n/* Hide controls when minimized */\n.sf-player--minimized .sf-controls-container {\n display: none;\n}\n\n/* Only show the minimize button when hovering on minimized player */\n.sf-player--minimized .sf-player__minimize-button {\n opacity: 0;\n}\n\n.sf-player--minimized:hover .sf-player__minimize-button {\n opacity: 1;\n}\n\n/* Player root element */\n#sf-player-root {\n position: fixed;\n z-index: var(--sf-z-index-player);\n}\n\n/* Player error message */\n.sf-player__error {\n padding: var(--sf-spacing-md);\n color: var(--sf-error-color);\n background-color: var(--sf-error-bg);\n border-radius: var(--sf-border-radius-md);\n margin: var(--sf-spacing-sm);\n font-size: var(--sf-font-size-sm);\n border-left: 4px solid var(--sf-error-color);\n}\n\n/* Minimize button */\n.sf-player__minimize-button {\n position: absolute;\n top: calc(var(--sf-spacing-xs) + var(--sf-spacing-md));\n right: var(--sf-spacing-md);\n width: var(--sf-minimize-button-size);\n height: var(--sf-minimize-button-size);\n background-color: transparent;\n border-radius: var(--sf-border-radius-circle);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n z-index: var(--sf-z-index-controls);\n color: white;\n border: none;\n font-size: calc(var(--sf-font-size-sm) + 4px);\n transition: all var(--sf-transition-normal);\n text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);\n opacity: 0;\n}\n\n/* Minimize button hover state */\n.sf-player__minimize-button:hover {\n transform: scale(1.1);\n}\n\n/* Show minimize button on player hover */\n.sf-player:hover .sf-player__minimize-button {\n opacity: 1;\n}\n\n/* Mobile and touch device overrides for minimize button visibility */\n/* Ensure minimize button is always visible on touch devices, even when minimized */\n@media (pointer: coarse) {\n .sf-player__minimize-button {\n opacity: 1 !important;\n z-index: calc(var(--sf-z-index-controls) + 50) !important; /* Much higher z-index for touch devices */\n }\n \n .sf-player--minimized .sf-player__minimize-button {\n opacity: 1 !important;\n z-index: calc(var(--sf-z-index-controls) + 50) !important; /* Much higher z-index for touch devices */\n }\n}\n\n/* Ensure minimize button is always visible on mobile screens under 768px */\n@media (max-width: 768px) {\n .sf-player__minimize-button {\n opacity: 1 !important;\n z-index: calc(var(--sf-z-index-controls) + 50) !important; /* Much higher z-index for mobile */\n /* Position closer to top right corner on mobile */\n top: var(--sf-spacing-xs) !important; /* 4px from top instead of 16px */\n right: var(--sf-spacing-xs) !important; /* 4px from right instead of 12px */\n }\n \n .sf-player--minimized .sf-player__minimize-button {\n opacity: 1 !important;\n z-index: calc(var(--sf-z-index-controls) + 50) !important; /* Much higher z-index for mobile */\n /* Position closer to top right corner on mobile */\n top: var(--sf-spacing-xs) !important; /* 4px from top instead of 16px */\n right: var(--sf-spacing-xs) !important; /* 4px from right instead of 12px */\n }\n}\n\n/* Player title */\n.sf-player__title {\n position: absolute;\n top: var(--sf-spacing-md);\n left: var(--sf-spacing-md);\n color: var(--sf-text-color);\n font-size: var(--sf-font-size-md);\n font-weight: 600;\n z-index: var(--sf-z-index-controls);\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);\n max-width: 70%;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Centered play/pause button overlay */\n.sf-player__center-play-button {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: var(--sf-play-button-size);\n height: var(--sf-play-button-size);\n background-color: rgba(0, 0, 0, 0.5);\n border-radius: var(--sf-border-radius-circle);\n display: none; /* Hidden by default */\n justify-content: center;\n align-items: center;\n z-index: calc(var(--sf-z-index-controls) + 10); /* Ensure higher z-index than other elements */\n color: white;\n border: none;\n font-size: var(--sf-control-button-size);\n cursor: pointer;\n transition: transform var(--sf-transition-normal), background-color var(--sf-transition-normal);\n backdrop-filter: blur(3px);\n -webkit-backdrop-filter: blur(3px);\n box-shadow: 0 15px 30px rgba(0, 0, 0, 0.5), 0 5px 15px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(255, 255, 255, 0.08);\n pointer-events: auto; /* Enable pointer events to capture clicks */\n}\n\n/* Center play button hover state */\n.sf-player__center-play-button:hover {\n transform: translate(-50%, -50%) scale(1.1);\n background-color: rgba(0, 0, 0, 0.7);\n}\n\n/* Hide center play button in minimized state */\n.sf-player--minimized .sf-player__center-play-button {\n display: none !important;\n}\n\n/* Exit button for minimized mode */\n.sf-player__exit-button {\n position: absolute;\n top: -22px; /* Position it above the player */\n right: 0;\n width: 20px;\n height: 20px;\n background-color: var(--sf-button-bg);\n border-radius: var(--sf-border-radius-circle);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n z-index: var(--sf-z-index-controls);\n color: white;\n border: none;\n font-size: var(--sf-font-size-md);\n transition: all var(--sf-transition-normal);\n text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.35);\n}\n\n/* Exit button hover state */\n.sf-player__exit-button:hover {\n transform: scale(1.1);\n background-color: var(--sf-button-hover-bg);\n}\n\n/* Show exit button on minimized player hover */\n.sf-player--minimized:hover .sf-player__exit-button {\n opacity: 1;\n}\n\n/* Saltfish logo */\n.sf-player__logo {\n position: absolute;\n bottom: var(--sf-spacing-xs);\n left: 50%;\n transform: translateX(-50%);\n width: 41px;\n height: 15px;\n z-index: var(--sf-z-index-controls);\n opacity: 0.7;\n transition: opacity var(--sf-transition-normal);\n cursor: pointer;\n}\n\n/* Logo hover state */\n.sf-player:hover .sf-player__logo {\n opacity: 0.9;\n}\n\n/* Hide logo when minimized */\n.sf-player--minimized .sf-player__logo {\n display: none;\n} \n /* \n * Video component styles for the Saltfish playlist Player\n * Following BEM naming convention\n */\n\n/* Video container */\n.sf-video-container {\n position: relative;\n width: 100%;\n height: 100%;\n border-radius: var(--sf-border-radius-md);\n overflow: hidden;\n pointer-events: auto; /* Ensure clicks on video container are captured */\n}\n\n/* Video element */\n.sf-video-container__video {\n width: 100%;\n height: 100%;\n object-fit: cover;\n /* Ensure video is visible on mobile */\n display: block;\n background-color: black;\n /* Add explicit positioning to ensure video is visible */\n position: relative;\n z-index: 1;\n}\n\n\n\n/* Mobile-specific video styles */\n@media (max-width: 768px) {\n \n .sf-video-container__video {\n /* Force video dimensions on mobile */\n width: 100% !important;\n height: 100% !important;\n object-fit: cover !important;\n /* Prevent video from being hidden */\n opacity: 1 !important;\n visibility: visible !important;\n /* Ensure video is above any potential overlays */\n z-index: 10 !important;\n position: relative !important;\n /* Ensure minimum dimensions */\n min-width: 100px !important;\n min-height: 100px !important;\n }\n \n /* Make controls more touch-friendly on mobile */\n .sf-video-container__controls {\n height: 5px; /* Thicker on mobile for easier touch */\n }\n \n .sf-video-container__mute-button {\n /* Use CSS variable for consistent sizing */\n min-width: var(--sf-mute-button-size) !important;\n min-height: var(--sf-mute-button-size) !important;\n opacity: 1; /* Always visible on mobile (no hover) */\n }\n \n .sf-video-container__cc-button {\n /* Use CSS variable for consistent sizing */\n min-width: var(--sf-cc-button-size) !important;\n min-height: var(--sf-cc-button-size) !important;\n opacity: 1; /* Always visible on mobile (no hover) */\n }\n}\n\n/* Touch device specific styles */\n@media (pointer: coarse) {\n .sf-video-container__controls:hover {\n height: 5px; /* Keep consistent height on touch devices */\n }\n \n .sf-video-container__mute-button {\n opacity: 1; /* Always show on touch devices */\n }\n \n .sf-video-container__cc-button {\n opacity: 1; /* Always show on touch devices */\n }\n \n .sf-video-container:hover .sf-video-container__mute-button {\n opacity: 1;\n }\n}\n\n/* Video in minimized state */\n.sf-player--minimized .sf-video-container {\n border-radius: var(--sf-border-radius-circle);\n cursor: pointer;\n z-index: var(--sf-z-index-base);\n width: 100%;\n height: 100%;\n}\n\n.sf-player--minimized .sf-video-container__video {\n border-radius: var(--sf-border-radius-circle);\n object-fit: cover;\n width: 100%;\n height: 100%;\n}\n\n/* Hide progress bar in minimized state */\n.sf-player--minimized .sf-video-container__controls {\n display: none !important;\n}\n\n/* Also hide mute button in minimized state */\n.sf-player--minimized .sf-video-container__mute-button {\n display: none !important;\n}\n\n/* Also hide CC button in minimized state */\n.sf-player--minimized .sf-video-container__cc-button {\n display: none !important;\n}\n\n/* Progress bar container */\n.sf-video-container__controls {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 3px;\n background-color: rgba(255, 255, 255, 0.25);\n z-index: var(--sf-z-index-controls);\n border-radius: var(--sf-border-radius-md) var(--sf-border-radius-md) 0 0;\n cursor: pointer;\n}\n\n/* Show slightly thicker progress bar on hover for better UX */\n.sf-video-container__controls:hover {\n height: 5px;\n}\n\n/* Progress indicator */\n.sf-video-container__progress {\n height: 100%;\n background: rgba(255, 255, 255, 0.8);\n width: 0%;\n transition: width 0.1s linear;\n border-radius: var(--sf-border-radius-md) 0 0 0;\n cursor: pointer;\n transform-origin: left;\n}\n\n/* Mute button */\n.sf-video-container__mute-button {\n position: absolute;\n top: calc(var(--sf-spacing-xl) + var(--sf-spacing-xl));\n right: var(--sf-spacing-xs);\n width: var(--sf-mute-button-size);\n height: var(--sf-mute-button-size);\n background-color: transparent;\n border-radius: var(--sf-border-radius-circle);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n z-index: var(--sf-z-index-controls);\n color: white;\n border: none;\n font-size: calc(var(--sf-font-size-md) + 2px);\n transition: all var(--sf-transition-normal);\n text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);\n opacity: 0;\n}\n\n/* Mute button hover state */\n.sf-video-container__mute-button:hover {\n transform: scale(1.1);\n}\n\n/* Show mute button on container hover */\n.sf-video-container:hover .sf-video-container__mute-button {\n opacity: 1;\n}\n\n/* CC button */\n.sf-video-container__cc-button {\n position: absolute;\n top: calc(var(--sf-spacing-xl) + var(--sf-spacing-xl) + var(--sf-mute-button-size) + var(--sf-spacing-xs));\n right: var(--sf-spacing-xs);\n width: var(--sf-cc-button-size);\n height: var(--sf-cc-button-size);\n background-color: transparent;\n border-radius: 50%; /* Ensure perfect circle */\n padding: 0; /* Remove default button padding */\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n z-index: var(--sf-z-index-controls);\n color: white;\n border: none;\n font-size: calc(var(--sf-font-size-md) + 2px);\n transition: all var(--sf-transition-normal);\n text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);\n opacity: 0;\n}\n\n.sf-video-container__cc-button svg {\n display: block;\n margin: auto;\n width: 60%;\n height: 60%;\n}\n\n/* CC button hover state */\n.sf-video-container__cc-button:hover {\n transform: scale(1.1);\n}\n\n/* Hide mute and cc buttons in autoplayBlocked state */\n.sf-player--autoplayBlocked .sf-video-container__mute-button,\n.sf-player--autoplayBlocked .sf-video-container__cc-button {\n display: none !important;\n}\n\n/* Show mute and cc buttons on hover in playing/paused states */\n.sf-player--playing .sf-video-container:hover .sf-video-container__mute-button,\n.sf-player--playing .sf-video-container:hover .sf-video-container__cc-button,\n.sf-player--paused .sf-video-container:hover .sf-video-container__mute-button,\n.sf-player--paused .sf-video-container:hover .sf-video-container__cc-button {\n opacity: 1;\n} \n /* \n * Controls component styles for the Saltfish playlist Player\n * Following BEM naming convention\n */\n\n/* Main controls container */\n.sf-controls-container {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n justify-content: center;\n align-items: center;\n background-color: transparent;\n z-index: var(--sf-z-index-controls);\n pointer-events: auto;\n}\n\n/* Play button */\n.sf-controls-container__play-button {\n background-color: rgba(0, 0, 0, 0.6);\n border: none;\n color: var(--sf-text-color);\n font-size: var(--sf-control-button-size);\n cursor: pointer;\n width: var(--sf-play-button-size);\n height: var(--sf-play-button-size);\n border-radius: var(--sf-border-radius-circle);\n display: flex;\n justify-content: center;\n align-items: center;\n transition: transform var(--sf-transition-normal), background-color var(--sf-transition-normal);\n padding-left: 4px; /* Optical centering for play icon */\n}\n\n/* Button hover state */\n.sf-controls-container__play-button:hover {\n background-color: rgba(0, 0, 0, 0.4);\n transform: scale(1.1);\n}\n\n/* Button container for interactive buttons */\n.sf-controls-container__buttons {\n display: flex;\n justify-content: center;\n align-items: center;\n gap: var(--sf-spacing-md);\n}\n\n/* Interactive button */\n.sf-controls-container__interactive-button {\n background-color: rgba(255, 255, 255, 0.2);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n color: white;\n border: none;\n border-radius: var(--sf-border-radius-md);\n padding: var(--sf-spacing-xs) var(--sf-spacing-md);\n font-size: var(--sf-font-size-sm);\n cursor: pointer;\n transition: background-color var(--sf-transition-normal), transform var(--sf-transition-fast);\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);\n}\n\n.sf-controls-container__interactive-button:hover {\n background-color: rgba(255, 255, 255, 0.3);\n transform: translateY(-2px);\n}\n\n/* \n * Choice buttons container and buttons - positioned inside player\n */\n\n/* Choice buttons container - positioned inside the player at the bottom */\n.sf-choice-buttons-container {\n position: absolute;\n bottom: var(--sf-spacing-xl);\n left: 50%;\n transform: translateX(-50%);\n width: calc(100% - var(--sf-spacing-lg));\n max-width: calc(100% - var(--sf-spacing-lg));\n z-index: calc(var(--sf-z-index-controls) + 1);\n display: flex;\n flex-direction: column;\n gap: var(--sf-spacing-sm);\n pointer-events: auto;\n justify-content: flex-end;\n align-items: center;\n}\n\n/* Choice button styles - solid rounded buttons matching the image */\n.sf-choice-button {\n width: 100%;\n max-width: none;\n background: rgba(0, 0, 0, 4);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n color: white;\n border: none;\n border-radius: 24px; /* More rounded for pill shape */\n padding: var(--sf-spacing-md) var(--sf-spacing-md);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.2s ease;\n text-align: center;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n outline: none;\n font-family: inherit;\n margin-bottom: 0;\n position: relative;\n overflow: hidden;\n opacity: 0; /* Start hidden for animation */\n animation: buttonFadeIn 0.3s ease-out forwards;\n}\n\n/* Hover state for buttons */\n.sf-choice-button:hover {\n background: rgba(0, 0, 0, 0.9);\n transform: translateY(-2px);\n box-shadow: 0 6px 16px rgba(0, 0, 0, 0.8);\n}\n\n/* Active state for all buttons */\n.sf-choice-button:active {\n transform: translateY(0) scale(0.98);\n transition: all 0.1s ease;\n}\n\n/* Remove specific action type styling - use consistent dark buttons */\n.sf-choice-button--goto,\n.sf-choice-button--url,\n.sf-choice-button--next,\n.sf-choice-button--dom,\n.sf-choice-button--function {\n background: rgba(0, 0, 0, 0.4);\n border: none;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n}\n\n.sf-choice-button--goto:hover,\n.sf-choice-button--url:hover,\n.sf-choice-button--next:hover,\n.sf-choice-button--dom:hover,\n.sf-choice-button--function:hover {\n background: rgba(0, 0, 0, 0.9);\n transform: translateY(-2px);\n box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);\n}\n\n/* Hide choice buttons in minimized state */\n.sf-player--minimized .sf-choice-buttons-container {\n display: none;\n}\n\n/* Smaller mobile screens - maintain same layout but with tighter spacing */\n@media (max-width: 480px) {\n .sf-choice-buttons-container {\n bottom: var(--sf-spacing-sm);\n width: calc(100% - var(--sf-spacing-md));\n max-width: calc(100% - var(--sf-spacing-md));\n gap: calc(var(--sf-spacing-xs) + 2px);\n }\n \n .sf-choice-button {\n padding: var(--sf-spacing-sm) var(--sf-spacing-sm);\n font-size: 11px;\n border-radius: 20px;\n }\n}\n\n/* Touch device specific adjustments */\n@media (pointer: coarse) {\n .sf-choice-buttons-container {\n gap: var(--sf-spacing-sm);\n }\n \n .sf-choice-button {\n min-height: 44px; /* Apple's recommended minimum touch target size */\n padding: var(--sf-spacing-md) var(--sf-spacing-md);\n }\n}\n\n/* Button fade-in animation */\n@keyframes buttonFadeIn {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Staggered animation delays for multiple buttons */\n.sf-choice-button:nth-child(1) {\n animation-delay: 1s;\n}\n\n.sf-choice-button:nth-child(2) {\n animation-delay: 1.15s;\n}\n\n.sf-choice-button:nth-child(3) {\n animation-delay: 1.3s;\n}\n\n.sf-choice-button:nth-child(4) {\n animation-delay: 1.45s;\n}\n\n.sf-choice-button:nth-child(5) {\n animation-delay: 1.6s;\n}\n\n.sf-choice-button:nth-child(6) {\n animation-delay: 1.75s;\n}\n\n.sf-choice-button:nth-child(7) {\n animation-delay: 1.9s;\n}\n\n.sf-choice-button:nth-child(8) {\n animation-delay: 2.05s;\n} \n /* \n * Transcript component styles for the Saltfish Playlist Player\n * Following BEM naming convention\n */\n\n/* Transcript container */\n.sf-transcript {\n position: absolute;\n bottom: 40px; /* Above the progress bar */\n left: 0;\n right: 0;\n max-height: 200px;\n background: rgba(0, 0, 0, 0.7);\n backdrop-filter: blur(8px);\n margin: 0 var(--sf-spacing-md);\n overflow: hidden;\n z-index: var(--sf-z-index-overlay);\n opacity: 0;\n transform: translateY(20px);\n transition: all 0.3s ease-out;\n pointer-events: none;\n}\n\n/* Visible state */\n.sf-transcript--visible {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n\n/* Transcript content */\n.sf-transcript__content {\n max-height: 180px;\n overflow-y: auto;\n padding: var(--sf-spacing-xs);\n scrollbar-width: thin;\n scrollbar-color: rgba(255, 255, 255, 0.3) transparent;\n}\n\n/* Webkit scrollbar styling */\n.sf-transcript__content::-webkit-scrollbar {\n width: 4px;\n}\n\n.sf-transcript__content::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.sf-transcript__content::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.3);\n border-radius: 2px;\n}\n\n.sf-transcript__content::-webkit-scrollbar-thumb:hover {\n background: rgba(255, 255, 255, 0.5);\n}\n\n/* Transcript segments */\n.sf-transcript__segment {\n color: rgba(255, 255, 255);\n font-size: var(--sf-font-size-sm);\n line-height: 1.4;\n padding: var(--sf-spacing-xs) 0;\n cursor: pointer;\n transition: all 0.2s ease;\n padding-left: var(--sf-spacing-xs);\n padding-right: var(--sf-spacing-xs);\n}\n\n/* CC button active state */\n.sf-video-container__cc-button--active {\n background: rgba(255, 255, 255, 0.2);\n color: #fff;\n}\n\n/* Mobile responsive styles */\n@media (max-width: 768px) {\n .sf-transcript {\n bottom: 50px; /* More space on mobile */\n margin: 0 var(--sf-spacing-sm);\n max-height: 150px; /* Smaller on mobile */\n }\n \n .sf-transcript__content {\n max-height: 130px;\n padding: var(--sf-spacing-sm);\n }\n \n .sf-transcript__segment {\n font-size: var(--sf-font-size-xs);\n padding: var(--sf-spacing-xs) var(--sf-spacing-sm);\n }\n}\n\n/* Touch device optimizations */\n@media (pointer: coarse) {\n .sf-transcript__segment {\n padding: var(--sf-spacing-sm) var(--sf-spacing-xs);\n min-height: 44px; /* Larger touch target */\n display: flex;\n align-items: center;\n }\n}\n\n/* Hide transcript in minimized state */\n.sf-player--minimized .sf-transcript {\n display: none !important;\n}\n\n/* Animation for transcript appearance */\n@keyframes transcriptFadeIn {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes transcriptFadeOut {\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(20px);\n }\n}\n \n /* \n * Transitions and animations for Saltfish playlist Player\n */\n\n/* Fade in animation */\n@keyframes sf-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.sf-fade-in {\n animation: sf-fade-in 0.3s ease-in-out forwards;\n}\n\n/* Slide in from bottom animation */\n@keyframes sf-slide-in-bottom {\n from { transform: translateY(100%); opacity: 0; }\n to { transform: translateY(0); opacity: 1; }\n}\n\n.sf-slide-in-bottom {\n animation: sf-slide-in-bottom 0.3s cubic-bezier(0.25, 0.8, 0.25, 1) forwards;\n}\n\n/* Slide in from right animation */\n@keyframes sf-slide-in-right {\n from { transform: translateX(100%); opacity: 0; }\n to { transform: translateX(0); opacity: 1; }\n}\n\n.sf-slide-in-right {\n animation: sf-slide-in-right 0.3s cubic-bezier(0.25, 0.8, 0.25, 1) forwards;\n}\n\n/* Scale in animation */\n@keyframes sf-scale-in {\n from { transform: scale(0.8); opacity: 0; }\n to { transform: scale(1); opacity: 1; }\n}\n\n.sf-scale-in {\n animation: sf-scale-in 0.3s cubic-bezier(0.25, 0.8, 0.25, 1) forwards;\n}\n\n/* Scale out animation */\n@keyframes sf-scale-out {\n from { transform: scale(1); opacity: 1; }\n to { transform: scale(0.8); opacity: 0; }\n}\n\n.sf-scale-out {\n animation: sf-scale-out 0.3s cubic-bezier(0.25, 0.8, 0.25, 1) forwards;\n} \n"}}const i={},s=t=>{let e;const n=new Set,s=(t,i)=>{const s="function"==typeof t?t(e):t;if(!Object.is(s,e)){const t=e;e=(null!=i?i:"object"!=typeof s||null===s)?s:Object.assign({},e,s),n.forEach((n=>n(e,t)))}},r=()=>e,a={setState:s,getState:r,getInitialState:()=>o,subscribe:t=>(n.add(t),()=>n.delete(t)),destroy:()=>{"production"!==(i?"production":void 0)&&console.warn("[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."),n.clear()}},o=e=t(s,r,a);return a};var r=Symbol.for("immer-nothing"),a=Symbol.for("immer-draftable"),o=Symbol.for("immer-state");function l(t,...e){throw new Error(`[Immer] minified error nr: ${t}. Full error at: https://bit.ly/3cXEKWf`)}var c=Object.getPrototypeOf;function d(t){return!!t&&!!t[o]}function h(t){var e;return!!t&&(p(t)||Array.isArray(t)||!!t[a]||!!(null==(e=t.constructor)?void 0:e[a])||v(t)||b(t))}var u=Object.prototype.constructor.toString();function p(t){if(!t||"object"!=typeof t)return!1;const e=c(t);if(null===e)return!0;const n=Object.hasOwnProperty.call(e,"constructor")&&e.constructor;return n===Object||"function"==typeof n&&Function.toString.call(n)===u}function g(t,e){0===m(t)?Reflect.ownKeys(t).forEach((n=>{e(n,t[n],t)})):t.forEach(((n,i)=>e(i,n,t)))}function m(t){const e=t[o];return e?e.type_:Array.isArray(t)?1:v(t)?2:b(t)?3:0}function f(t,e){return 2===m(t)?t.has(e):Object.prototype.hasOwnProperty.call(t,e)}function y(t,e,n){const i=m(t);2===i?t.set(e,n):3===i?t.add(n):t[e]=n}function v(t){return t instanceof Map}function b(t){return t instanceof Set}function w(t){return t.copy_||t.base_}function S(t,e){if(v(t))return new Map(t);if(b(t))return new Set(t);if(Array.isArray(t))return Array.prototype.slice.call(t);const n=p(t);if(!0===e||"class_only"===e&&!n){const e=Object.getOwnPropertyDescriptors(t);delete e[o];let n=Reflect.ownKeys(e);for(let i=0;i<n.length;i++){const s=n[i],r=e[s];!1===r.writable&&(r.writable=!0,r.configurable=!0),(r.get||r.set)&&(e[s]={configurable:!0,writable:!0,enumerable:r.enumerable,value:t[s]})}return Object.create(c(t),e)}{const e=c(t);if(null!==e&&n)return{...t};const i=Object.create(e);return Object.assign(i,t)}}function M(t,e=!1){return x(t)||d(t)||!h(t)||(m(t)>1&&(t.set=t.add=t.clear=t.delete=E),Object.freeze(t),e&&Object.entries(t).forEach((([t,e])=>M(e,!0)))),t}function E(){l(2)}function x(t){return Object.isFrozen(t)}var I,P={};function C(t){const e=P[t];return e||l(0),e}function T(){return I}function _(t,e){e&&(C("Patches"),t.patches_=[],t.inversePatches_=[],t.patchListener_=e)}function k(t){z(t),t.drafts_.forEach(D),t.drafts_=null}function z(t){t===I&&(I=t.parent_)}function A(t){return I={drafts_:[],parent_:I,immer_:t,canAutoFreeze_:!0,unfinalizedDrafts_:0}}function D(t){const e=t[o];0===e.type_||1===e.type_?e.revoke_():e.revoked_=!0}function V(t,e){e.unfinalizedDrafts_=e.drafts_.length;const n=e.drafts_[0];return void 0!==t&&t!==n?(n[o].modified_&&(k(e),l(4)),h(t)&&(t=L(e,t),e.parent_||O(e,t)),e.patches_&&C("Patches").generateReplacementPatches_(n[o].base_,t,e.patches_,e.inversePatches_)):t=L(e,n,[]),k(e),e.patches_&&e.patchListener_(e.patches_,e.inversePatches_),t!==r?t:void 0}function L(t,e,n){if(x(e))return e;const i=e[o];if(!i)return g(e,((s,r)=>B(t,i,e,s,r,n))),e;if(i.scope_!==t)return e;if(!i.modified_)return O(t,i.base_,!0),i.base_;if(!i.finalized_){i.finalized_=!0,i.scope_.unfinalizedDrafts_--;const e=i.copy_;let s=e,r=!1;3===i.type_&&(s=new Set(e),e.clear(),r=!0),g(s,((s,a)=>B(t,i,e,s,a,n,r))),O(t,e,!1),n&&t.patches_&&C("Patches").generatePatches_(i,n,t.patches_,t.inversePatches_)}return i.copy_}function B(t,e,n,i,s,r,a){if(d(s)){const a=L(t,s,r&&e&&3!==e.type_&&!f(e.assigned_,i)?r.concat(i):void 0);if(y(n,i,a),!d(a))return;t.canAutoFreeze_=!1}else a&&n.add(s);if(h(s)&&!x(s)){if(!t.immer_.autoFreeze_&&t.unfinalizedDrafts_<1)return;L(t,s),e&&e.scope_.parent_||"symbol"==typeof i||!Object.prototype.propertyIsEnumerable.call(n,i)||O(t,s)}}function O(t,e,n=!1){!t.parent_&&t.immer_.autoFreeze_&&t.canAutoFreeze_&&M(e,n)}var U={get(t,e){if(e===o)return t;const n=w(t);if(!f(n,e))return function(t,e,n){var i;const s=N(e,n);return s?"value"in s?s.value:null==(i=s.get)?void 0:i.call(t.draft_):void 0}(t,n,e);const i=n[e];return t.finalized_||!h(i)?i:i===R(t.base_,e)?(H(t),t.copy_[e]=X(i,t)):i},has:(t,e)=>e in w(t),ownKeys:t=>Reflect.ownKeys(w(t)),set(t,e,n){const i=N(w(t),e);if(null==i?void 0:i.set)return i.set.call(t.draft_,n),!0;if(!t.modified_){const i=R(w(t),e),a=null==i?void 0:i[o];if(a&&a.base_===n)return t.copy_[e]=n,t.assigned_[e]=!1,!0;if(((s=n)===(r=i)?0!==s||1/s==1/r:s!=s&&r!=r)&&(void 0!==n||f(t.base_,e)))return!0;H(t),Y(t)}var s,r;return t.copy_[e]===n&&(void 0!==n||e in t.copy_)||Number.isNaN(n)&&Number.isNaN(t.copy_[e])||(t.copy_[e]=n,t.assigned_[e]=!0),!0},deleteProperty:(t,e)=>(void 0!==R(t.base_,e)||e in t.base_?(t.assigned_[e]=!1,H(t),Y(t)):delete t.assigned_[e],t.copy_&&delete t.copy_[e],!0),getOwnPropertyDescriptor(t,e){const n=w(t),i=Reflect.getOwnPropertyDescriptor(n,e);return i?{writable:!0,configurable:1!==t.type_||"length"!==e,enumerable:i.enumerable,value:n[e]}:i},defineProperty(){l(11)},getPrototypeOf:t=>c(t.base_),setPrototypeOf(){l(12)}},F={};function R(t,e){const n=t[o];return(n?w(n):t)[e]}function N(t,e){if(!(e in t))return;let n=c(t);for(;n;){const t=Object.getOwnPropertyDescriptor(n,e);if(t)return t;n=c(n)}}function Y(t){t.modified_||(t.modified_=!0,t.parent_&&Y(t.parent_))}function H(t){t.copy_||(t.copy_=S(t.base_,t.scope_.immer_.useStrictShallowCopy_))}g(U,((t,e)=>{F[t]=function(){return arguments[0]=arguments[0][0],e.apply(this,arguments)}})),F.deleteProperty=function(t,e){return F.set.call(this,t,e,void 0)},F.set=function(t,e,n){return U.set.call(this,t[0],e,n,t[0])};function X(t,e){const n=v(t)?C("MapSet").proxyMap_(t,e):b(t)?C("MapSet").proxySet_(t,e):function(t,e){const n=Array.isArray(t),i={type_:n?1:0,scope_:e?e.scope_:T(),modified_:!1,finalized_:!1,assigned_:{},parent_:e,base_:t,draft_:null,copy_:null,revoke_:null,isManual_:!1};let s=i,r=U;n&&(s=[i],r=F);const{revoke:a,proxy:o}=Proxy.revocable(s,r);return i.draft_=o,i.revoke_=a,o}(t,e);return(e?e.scope_:T()).drafts_.push(n),n}function $(t){if(!h(t)||x(t))return t;const e=t[o];let n;if(e){if(!e.modified_)return e.base_;e.finalized_=!0,n=S(t,e.scope_.immer_.useStrictShallowCopy_)}else n=S(t,!0);return g(n,((t,e)=>{y(n,t,$(e))})),e&&(e.finalized_=!1),n}var W=new class{constructor(t){this.autoFreeze_=!0,this.useStrictShallowCopy_=!1,this.produce=(t,e,n)=>{if("function"==typeof t&&"function"!=typeof e){const n=e;e=t;const i=this;return function(t=n,...s){return i.produce(t,(t=>e.call(this,t,...s)))}}let i;if("function"!=typeof e&&l(6),void 0!==n&&"function"!=typeof n&&l(7),h(t)){const s=A(this),r=X(t,void 0);let a=!0;try{i=e(r),a=!1}finally{a?k(s):z(s)}return _(s,n),V(i,s)}if(!t||"object"!=typeof t){if(i=e(t),void 0===i&&(i=t),i===r&&(i=void 0),this.autoFreeze_&&M(i,!0),n){const e=[],s=[];C("Patches").generateReplacementPatches_(t,i,e,s),n(e,s)}return i}l(1)},this.produceWithPatches=(t,e)=>{if("function"==typeof t)return(e,...n)=>this.produceWithPatches(e,(e=>t(e,...n)));let n,i;return[this.produce(t,e,((t,e)=>{n=t,i=e})),n,i]},"boolean"==typeof(null==t?void 0:t.autoFreeze)&&this.setAutoFreeze(t.autoFreeze),"boolean"==typeof(null==t?void 0:t.useStrictShallowCopy)&&this.setUseStrictShallowCopy(t.useStrictShallowCopy)}createDraft(t){h(t)||l(8),d(t)&&(t=function(t){d(t)||l(10);return $(t)}(t));const e=A(this),n=X(t,void 0);return n[o].isManual_=!0,z(e),n}finishDraft(t,e){const n=t&&t[o];n&&n.isManual_||l(9);const{scope_:i}=n;return _(i,e),V(void 0,i)}setAutoFreeze(t){this.autoFreeze_=t}setUseStrictShallowCopy(t){this.useStrictShallowCopy_=t}applyPatches(t,e){let n;for(n=e.length-1;n>=0;n--){const i=e[n];if(0===i.path.length&&"replace"===i.op){t=i.value;break}}n>-1&&(e=e.slice(n+1));const i=C("Patches").applyPatches_;return d(t)?i(t,e):this.produce(t,(t=>i(t,e)))}},j=W.produce;W.produceWithPatches.bind(W),W.setAutoFreeze.bind(W),W.setUseStrictShallowCopy.bind(W),W.applyPatches.bind(W),W.createDraft.bind(W),W.finishDraft.bind(W);const q=t=>(e,n,i)=>(i.setState=(t,n,...i)=>{const s="function"==typeof t?j(t):t;return e(s,n,...i)},t(i.setState,n,i)),Z="bottom",J="left",K="right",Q="center",G="saltfish_progress",tt="saltfish_session",et="saltfish_anonymous_user_data",nt=20,it="-50%",st="-50%",rt="-100%",at=5,ot=300,lt=6e4,ct=18e5,dt="https://player.saltfish.ai",ht="sf-player",ut="sf-player--minimized",pt="sf-controls-container",gt="sf-player__logo";function mt(t,e){void 0!==e?console.info(t,e):console.info(t)}function ft(t,e){console.warn(t)}function yt(t,e){void 0!==e?console.error(t,e):console.error(t)}class vt{constructor(t,n){e(this,"currentState"),e(this,"config"),e(this,"context"),e(this,"actionHandlers",{}),this.config=t,this.currentState=t.initial,this.context=n,this.setupDefaultActions(),this.runEntryActions(this.currentState)}setupDefaultActions(){this.actionHandlers={...this.actionHandlers,logStateEntry:t=>{this.currentState},logErrorEvent:(t,e)=>{"ERROR"===(null==e?void 0:e.type)&&e.error.message},logStepTransition:(t,e)=>{"TRANSITION_TO_STEP"===(null==e?void 0:e.type)&&e.step.id},logErrorRecovery:()=>{}}}registerActions(t){this.actionHandlers={...this.actionHandlers,...t},Object.keys(t).join(", ")}executeAction(t,e){if("string"==typeof t){const n=this.actionHandlers[t];n&&n(this.context,e)}else t(this.context,e)}send(t){const e=this.config.states[this.currentState].on[t.type];if(!e)return t.type,this.currentState,this.currentState;this.currentState,e.target,t.type,this.runExitActions(this.currentState),this.updateContextFromEvent(t),e.actions&&e.actions.forEach((e=>this.executeAction(e,t)));this.currentState;return this.currentState=e.target,this.runEntryActions(this.currentState),this.currentState,this.currentState}updateContextFromEvent(t){"TRANSITION_TO_STEP"===t.type||"MANIFEST_LOADED"===t.type||"VIDEO_ENDED"===t.type?this.context.currentStep=t.step:"ERROR"===t.type&&(this.context.error=t.error)}getState(){return this.currentState}getContext(){return this.context}updateContext(t){const e=t(this.context);this.context={...this.context,...e}}runEntryActions(t){const e=this.config.states[t];e.entry&&e.entry.forEach((t=>this.executeAction(t)))}runExitActions(t){const e=this.config.states[t];e.exit&&e.exit.forEach((t=>this.executeAction(t)))}}const bt={initial:"idle",states:{idle:{on:{INITIALIZE:{target:"idle"},LOAD_MANIFEST:{target:"loading"}},entry:["logStateEntry"]},loading:{on:{MANIFEST_LOADED:{target:"paused"},ERROR:{target:"error",actions:["logErrorEvent"]}},entry:["logStateEntry"]},playing:{on:{PAUSE:{target:"paused"},MINIMIZE:{target:"minimized"},VIDEO_ENDED:{target:"waitingForInteraction"},AUTOPLAY_FALLBACK:{target:"autoplayBlocked"},TRANSITION_TO_STEP:{target:"playing",actions:["logStepTransition"]},ERROR:{target:"error"},COMPLETE_PLAYLIST:{target:"completed"},COMPLETE_PLAYLIST_WAITING_FOR_INTERACTION:{target:"completedWaitingForInteraction"}},entry:["logStateEntry","startVideoPlayback"],exit:["pauseVideoPlayback"]},paused:{on:{PLAY:{target:"playing"},MINIMIZE:{target:"minimized"},TRANSITION_TO_STEP:{target:"playing",actions:["logStepTransition"]}},entry:["logStateEntry","pauseVideoPlayback"]},minimized:{on:{MAXIMIZE:{target:"paused"}},entry:["logStateEntry","pauseVideoPlayback"]},waitingForInteraction:{on:{PLAY:{target:"playing"},PAUSE:{target:"paused"},MINIMIZE:{target:"minimized"},COMPLETE_PLAYLIST:{target:"completed"},COMPLETE_PLAYLIST_WAITING_FOR_INTERACTION:{target:"completedWaitingForInteraction"},TRANSITION_TO_STEP:{target:"playing",actions:["logStepTransition"]}},entry:["logStateEntry"]},autoplayBlocked:{on:{PLAY:{target:"playing"},TRANSITION_TO_STEP:{target:"playing"},MINIMIZE:{target:"minimized"}},entry:["logStateEntry","startMutedLoopedVideo"]},error:{on:{INITIALIZE:{target:"idle"},PLAY:{target:"playing",actions:["logErrorRecovery"]},AUTOPLAY_FALLBACK:{target:"autoplayBlocked"}},entry:["logStateEntry","handleError"]},completedWaitingForInteraction:{on:{COMPLETE_PLAYLIST:{target:"completed"},INITIALIZE:{target:"idle"}},entry:["logStateEntry"]},completed:{on:{INITIALIZE:{target:"idle"}},entry:["logStateEntry","trackPlaylistComplete"]}}},wt=20,St=()=>{const t=document.getElementById("saltfish-container");return t&&t.shadowRoot?t:document.documentElement},Mt=()=>{if("undefined"!=typeof window){const t=St(),e=getComputedStyle(t).getPropertyValue("--sf-player-width");return parseInt(e,10)||200}return 200},Et=t=>{const e=t?(()=>{if("undefined"!=typeof window){const t=St(),e=getComputedStyle(t);return parseInt(e.getPropertyValue("--sf-player-min-width"),10)||80}return 80})():Mt();return{width:e,minX:20,maxX:window.innerWidth-e-wt}};class xt{static calculatePosition(t){const{position:e,viewportWidth:n=window.innerWidth,viewportHeight:i=window.innerHeight,playerWidth:s=Mt()}=t;let r=nt,a=nt,o="0",l="0";e.includes(Z)&&(a=i-nt,l=rt),e.includes(J)?r=nt:e.includes(K)?r=n-s-wt:e.includes(Q)&&(r=n/2,a=i/2,o=it,l=st);return{...this.applyConstraints({x:r,y:a,position:e,viewportWidth:n,viewportHeight:i,playerWidth:s}),transformX:o,transformY:l}}static applyConstraints(t){const{x:e,y:n,position:i,viewportWidth:s,viewportHeight:r,playerWidth:a}=t;let o=e,l=n;return i.includes(Z)&&!i.includes(Q)&&(l=r-nt),i.includes(K)&&!i.includes(Q)&&(o=Math.max(nt,Math.min(o,s-a-wt))),o=Math.max(nt,Math.min(o,s-a-wt)),l=Math.max(nt,Math.min(l,r-nt)),{x:o,y:l}}static calculateDragPosition(t){const{x:e,y:n,position:i,viewportWidth:s=window.innerWidth,viewportHeight:r=window.innerHeight,playerWidth:a=Mt()}=t;let o=e,l=n;(null==i?void 0:i.includes(K))&&!i.includes(Q)&&(o=Math.min(o,s-a-wt));const c=nt,d=s-a-wt;return o=Math.max(c,Math.min(o,d)),l=Math.max(nt,Math.min(l,r-nt)),{x:o,y:l}}static getTransforms(t){let e="0",n="0";return t.includes(Q)?(e=it,n=st):t.includes(Z)&&(n=rt),{transformX:e,transformY:n}}static shouldForceReposition(t,e,n){return"bottom-left"===t&&!n&&(e===window.innerHeight-nt||Math.abs(e-(window.innerHeight-nt))<5)}static getPlayerDimensions(){const t=Mt();return{width:t,minX:nt,maxX:window.innerWidth-t-wt}}}const It=s(q(((t,e)=>{const n=new vt(bt,{currentStep:null,error:null});return{config:null,user:null,userData:null,currentState:n.getState(),manifest:null,currentStepId:null,isMinimized:!1,position:null,progress:{},error:null,stateMachine:n,playlistOptions:null,backendPlaylists:[],isMuted:!1,initialize:async e=>{t((t=>{t.config=e,t.currentState=t.stateMachine.send({type:"INITIALIZE"})}))},setPlaylistOptions:e=>{t((t=>{if(t.playlistOptions=e,e.position){const n=xt.calculatePosition({position:e.position});t.position={x:n.x,y:n.y}}}))},identifyUser:(e,n)=>{const i={id:e,...n};t((t=>{t.user=i}))},setUserData:e=>{t((t=>{t.userData=e}))},setManifest:(e,n)=>{t((t=>{t.manifest=e,t.currentStepId=n,t.currentState=t.stateMachine.send({type:"LOAD_MANIFEST"})}))},play:()=>{const{currentState:n}=e();t((t=>{t.currentState=t.stateMachine.send({type:"PLAY"})}))},pause:()=>{const{currentState:n}=e();t((t=>{t.currentState=t.stateMachine.send({type:"PAUSE"})}))},minimize:()=>{const{currentState:n}=e();t((t=>{"playing"===t.currentState&&(t.currentState=t.stateMachine.send({type:"PAUSE"})),t.currentState=t.stateMachine.send({type:"MINIMIZE"}),t.isMinimized=!0}))},maximize:()=>{t((t=>{t.currentState=t.stateMachine.send({type:"MAXIMIZE"}),t.isMinimized=!1}))},setPosition:(e,n)=>{t((t=>{t.position={x:e,y:n}}))},goToStep:n=>{const{manifest:i}=e();if("completed"!==n){if(i&&i.steps.some((t=>t.id===n))){const e=i.steps.find((t=>t.id===n));t((t=>{var s,r;if(t.currentStepId=n,e&&(t.currentState=t.stateMachine.send({type:"TRANSITION_TO_STEP",step:e}),t.position)){const n=e.position||(null==(s=t.playlistOptions)?void 0:s.position)||"bottom-right",i=xt.calculatePosition({position:n});t.position={x:i.x,y:i.y}}t.progress[i.id]={...t.progress[i.id],lastStepId:n,lastVisited:(new Date).toISOString()};((null==(r=t.playlistOptions)?void 0:r.persistence)??!0)&&"undefined"!=typeof window&&localStorage.setItem(G,JSON.stringify(t.progress))}))}}else t((t=>{var e;t.currentState=t.stateMachine.send({type:"COMPLETE_PLAYLIST"});const n=(null==(e=t.playlistOptions)?void 0:e.persistence)??!0;i&&n&&(delete t.progress[i.id],"undefined"!=typeof window&&localStorage.setItem(G,JSON.stringify(t.progress)),i.id)}))},reset:()=>{t((t=>{t.config=null,t.user=null,t.userData=null,t.currentState="idle",t.manifest=null,t.currentStepId=null,t.isMinimized=!1,t.position=null,t.progress={},t.error=null,t.stateMachine=new vt(bt,{currentStep:null,error:null})}))},setError:e=>{t((t=>{t.currentState=t.stateMachine.send({type:"ERROR",error:e}),t.error=e}))},setAutoplayFallback:()=>{t((t=>{t.currentState=t.stateMachine.send({type:"AUTOPLAY_FALLBACK"})}))},setMuted:e=>{t((t=>{t.isMuted=e}))},setBackendPlaylists:e=>{t((t=>{t.backendPlaylists=e}))},completePlaylist:()=>{t((t=>{var e;const{manifest:n}=t;t.currentState=t.stateMachine.send({type:"COMPLETE_PLAYLIST"});const i=(null==(e=t.playlistOptions)?void 0:e.persistence)??!0;n&&i&&(delete t.progress[n.id],"undefined"!=typeof window&&localStorage.setItem(G,JSON.stringify(t.progress)),n.id)}))},resetForNewPlaylist:()=>{t((t=>{const e=t.config,n=t.user,i=t.userData,s=t.progress;t.manifest=null,t.currentStepId=null,t.isMinimized=!1,t.position=null,t.error=null,t.playlistOptions=null,t.stateMachine=new vt(bt,{currentStep:null,error:null}),t.currentState=t.stateMachine.getState(),t.config=e,t.user=n,t.userData=i,t.progress=s}))},loadPlaylistProgress:(e,n)=>{t((t=>{t.progress[e]=n}))}}}))),Pt={getState:()=>It.getState(),setState:It.setState,subscribe:It.subscribe,destroy:It.destroy};class Ct{static isMobile(){return this.getDeviceInfo().isMobile}static isTablet(){return this.getDeviceInfo().isTablet}static isDesktop(){return this.getDeviceInfo().isDesktop}static isTouchDevice(){return this.getDeviceInfo().isTouchDevice}static getOrientation(){return this.getDeviceInfo().orientation}static getDeviceInfo(){if(this.cachedDeviceInfo)return this.cachedDeviceInfo.orientation=this.detectOrientation(),this.cachedDeviceInfo;const t="undefined"!=typeof navigator?navigator.userAgent:"",e=this.detectTouchSupport(),{width:n,height:i}=this.getScreenDimensions(),s=/iPad|Android(?!.*Mobile)|Tablet|tablet/i,r=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|mobile|CriOS/i.test(t)&&!s.test(t),a=s.test(t),o=this.getScreenSize(n,i),l="small"===o&&Math.min(n,i)<768,c=r||l&&e,d=a||"medium"===o&&!l&&e&&!c,h={isMobile:c,isTablet:d,isDesktop:!c&&!d,isTouchDevice:e,screenSize:o,orientation:this.detectOrientation(),userAgent:t};return this.cachedDeviceInfo=h,h}static detectTouchSupport(){return"undefined"!=typeof window&&("ontouchstart"in window||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0)}static getScreenDimensions(){return"undefined"==typeof window?{width:1920,height:1080}:{width:window.innerWidth||document.documentElement.clientWidth||1920,height:window.innerHeight||document.documentElement.clientHeight||1080}}static getScreenSize(t,e){const n=Math.min(t,e);return n<768?"small":n<1024?"medium":"large"}static detectOrientation(){if("undefined"==typeof window)return"landscape";const{width:t,height:e}=this.getScreenDimensions();return e>t?"portrait":"landscape"}static clearCache(){this.cachedDeviceInfo=null}static onDeviceChange(t){if("undefined"==typeof window)return()=>{};const e=()=>{try{this.clearCache(),t(this.getDeviceInfo())}catch(e){console.warn("DeviceDetector: Error in device change handler:",e)}};return window.addEventListener("orientationchange",e),window.addEventListener("resize",e),()=>{window.removeEventListener("orientationchange",e),window.removeEventListener("resize",e)}}}e(Ct,"cachedDeviceInfo",null);const Tt=Object.freeze(Object.defineProperty({__proto__:null,DeviceDetector:Ct,isDeviceCompatible:t=>{if(!t||"both"===t)return!0;const e=Ct.getDeviceInfo();return"mobile"===t?e.isMobile||e.isTablet:"desktop"===t&&e.isDesktop}},Symbol.toStringTag,{value:"Module"}));class _t{constructor(){e(this,"transcriptContainer",null),e(this,"transcriptContent",null),e(this,"ccButton",null),e(this,"isVisible",!1),e(this,"currentTranscript",null),e(this,"currentSegmentIndex",-1),e(this,"segments",[]),e(this,"videoElement",null),e(this,"timeUpdateListener",null)}setup(t,e){this.videoElement=t,this.ccButton=e,this.ccButton.addEventListener("click",this.handleCCButtonClick.bind(this)),this.timeUpdateListener=this.handleTimeUpdate.bind(this),this.videoElement.addEventListener("timeupdate",this.timeUpdateListener)}loadTranscript(t){this.currentTranscript=t,this.currentSegmentIndex=-1,t?(this.updateCCButtonState(!0),this.createTranscriptUI(),this.renderTranscriptSegments(),t.segments.length):(this.updateCCButtonState(!1),this.hideTranscript())}toggleVisibility(){this.currentTranscript&&(this.isVisible=!this.isVisible,this.isVisible?this.showTranscript():this.hideTranscript(),this.updateCCButtonState(!!this.currentTranscript),this.isVisible)}handleCCButtonClick(t){t.preventDefault(),t.stopPropagation(),this.toggleVisibility()}handleTimeUpdate(t){if(!this.currentTranscript||!this.isVisible||!this.videoElement)return;const e=this.videoElement.currentTime,n=this.findActiveSegmentIndex(e);n!==this.currentSegmentIndex&&(this.highlightSegment(n),this.currentSegmentIndex=n)}findActiveSegmentIndex(t){if(!this.currentTranscript)return-1;for(let e=0;e<this.currentTranscript.segments.length;e++){const n=this.currentTranscript.segments[e];if(t>=n.start&&t<=n.end)return e}return-1}highlightSegment(t){if(this.segments.forEach((t=>{t.classList.remove("sf-transcript__segment--active")})),t>=0&&t<this.segments.length){const e=this.segments[t];e.classList.add("sf-transcript__segment--active"),e.scrollIntoView({behavior:"smooth",block:"nearest"})}}createTranscriptUI(){var t;if(this.transcriptContainer)return;const e=null==(t=this.videoElement)?void 0:t.closest(".sf-video-container");e&&(this.transcriptContainer=document.createElement("div"),this.transcriptContainer.className="sf-transcript",this.transcriptContainer.style.display="none",this.transcriptContent=document.createElement("div"),this.transcriptContent.className="sf-transcript__content",this.transcriptContainer&&this.transcriptContent&&(this.transcriptContainer.appendChild(this.transcriptContent),e.appendChild(this.transcriptContainer)))}renderTranscriptSegments(){this.transcriptContent&&this.currentTranscript&&(this.transcriptContent.innerHTML="",this.segments=[],this.currentTranscript.segments.forEach((t=>{const e=document.createElement("div");e.className="sf-transcript__segment",e.textContent=t.text,e.addEventListener("click",(()=>{this.videoElement&&(this.videoElement.currentTime=t.start)})),this.transcriptContent&&(this.transcriptContent.appendChild(e),this.segments.push(e))})),this.segments.length)}showTranscript(){this.transcriptContainer&&(this.transcriptContainer.style.display="block",this.transcriptContainer.classList.add("sf-transcript--visible"))}hideTranscript(){this.transcriptContainer&&(this.transcriptContainer.style.display="none",this.transcriptContainer.classList.remove("sf-transcript--visible"))}updateCCButtonState(t){this.ccButton&&(t?(this.ccButton.style.display="block",this.ccButton.classList.toggle("sf-video-container__cc-button--active",this.isVisible)):this.ccButton.style.display="none")}reset(){this.currentTranscript=null,this.currentSegmentIndex=-1,this.segments=[],this.isVisible&&this.hideTranscript(),this.transcriptContent&&(this.transcriptContent.innerHTML=""),this.updateCCButtonState(!1)}async destroy(){this.timeUpdateListener&&this.videoElement&&this.videoElement.removeEventListener("timeupdate",this.timeUpdateListener),this.transcriptContainer&&this.transcriptContainer.parentNode&&this.transcriptContainer.parentNode.removeChild(this.transcriptContainer),this.transcriptContainer=null,this.transcriptContent=null,this.ccButton=null,this.videoElement=null,this.timeUpdateListener=null,this.currentTranscript=null,this.segments=[],this.currentSegmentIndex=-1,this.isVisible=!1}}class kt{constructor(t){e(this,"deviceInfo"),this.deviceInfo=t}updateDeviceInfo(t){this.deviceInfo=t}}class zt extends kt{getVideoElementConfig(){return{playsInline:!0,muted:!0,controls:!1,preload:"metadata",additionalAttributes:{"webkit-playsinline":"true",playsinline:"true","x-webkit-airplay":"allow"},styles:{width:"100%",height:"100%",objectFit:"cover",backgroundColor:"white"}}}getControlsConfig(){return{buttonMinSize:{width:"44px",height:"44px"},useTouch:!0,progressUpdateInterval:500}}getAutoplayConfig(t){return{shouldStartMuted:!t,enableFallbackLoop:!0,fallbackTimeout:3e3,requiresUserInteraction:!0}}configureVideoElement(t){const e=this.getVideoElementConfig();t.playsInline=e.playsInline,t.muted=e.muted,t.controls=e.controls,t.preload=e.preload,Object.entries(e.additionalAttributes).forEach((([e,n])=>{try{t.setAttribute(e,n)}catch(i){console.warn(`MobilePlaybackHandler: Failed to set attribute ${e}:`,i)}})),Object.entries(e.styles).forEach((([e,n])=>{try{t.style[e]=n}catch(i){console.warn(`MobilePlaybackHandler: Failed to set style ${e}:`,i)}}))}configureControlElement(t){const e=this.getControlsConfig();t.style.minWidth=e.buttonMinSize.width,t.style.minHeight=e.buttonMinSize.height}async handlePlayAttempt(t,e){const n=Pt.getState().isMuted;t.muted=n,t.loop=!1;try{return await t.play(),!0}catch(i){return t.muted,await this.handleAutoplayFallback(t),!1}}async handleAutoplayFallback(t){t.muted=!0,t.loop=!0,t.playsInline=!0,t.setAttribute("playsinline","true"),t.setAttribute("webkit-playsinline","true");try{await t.play()}catch(e){console.error("MobilePlaybackHandler: All autoplay attempts failed")}}destroy(){}getProgressUpdateFrequency(t){return t?500:16}}class At extends kt{getVideoElementConfig(){return{playsInline:!0,muted:!1,controls:!1,preload:"metadata",additionalAttributes:{},styles:{backgroundColor:"white"}}}getControlsConfig(){return{buttonMinSize:{width:"auto",height:"auto"},useTouch:!1,progressUpdateInterval:16}}getAutoplayConfig(t){return{shouldStartMuted:!1,enableFallbackLoop:!1,fallbackTimeout:5e3,requiresUserInteraction:!1}}configureVideoElement(t){const e=this.getVideoElementConfig();t.playsInline=e.playsInline,t.muted=e.muted,t.controls=e.controls,t.preload=e.preload,Object.entries(e.styles).forEach((([e,n])=>{t.style[e]=n}))}configureControlElement(t){}async handlePlayAttempt(t,e){const n=Pt.getState().isMuted;t.muted=n,t.loop=!1;try{return await t.play(),!0}catch(i){return t.muted,await this.handleAutoplayFallback(t),!1}}async handleAutoplayFallback(t){t.muted=!0,t.loop=!0;try{await t.play()}catch(e){throw console.error("DesktopPlaybackHandler: All autoplay attempts failed"),new Error("Desktop autoplay completely blocked")}}getProgressUpdateFrequency(t){return 16}destroy(){}}class Dt{constructor(){e(this,"currentVideo",null),e(this,"nextVideo",null),e(this,"activeVideoIndex",0),e(this,"container",null),e(this,"progressBar",null),e(this,"muteButton",null),e(this,"ccButton",null),e(this,"transcriptManager"),e(this,"preloadedVideos",new Map),e(this,"updateInterval",null),e(this,"animationFrameId",null),e(this,"lastTimeupdateEvent",0),e(this,"currentVideoUrl",""),e(this,"nextVideoUrl",""),e(this,"playbackPositions",new Map),e(this,"completionPolicy","auto"),e(this,"videoEndedCallback",null),e(this,"deviceHandler"),e(this,"deviceChangeCleanup",null),e(this,"hasUserInteracted",!1),e(this,"autoplayFallbackTimeout",null),e(this,"handleVideoEnded",(t=>{if(t.target!==this.getActiveVideo())return;"autoplayBlocked"!==Pt.getState().currentState&&(this.progressBar&&(this.progressBar.style.transition="width 0.2s ease-out",this.progressBar.style.width="100%"),"auto"===this.completionPolicy?this.handleAutoVideoEnded():this.handleManualVideoEnded())})),e(this,"handleTimeUpdate",(t=>{const e=t.target;e===this.getActiveVideo()&&Math.floor(e.currentTime)})),e(this,"handleVideoError",(t=>{const e=t.target;console.error("VideoManager: Video error",e.error)})),e(this,"handleDetailedTimeUpdate",(()=>{var t;this.lastTimeupdateEvent=Date.now(),this.progressBar&&!1===(null==(t=this.getActiveVideo())?void 0:t.paused)&&(this.progressBar.style.transition="width 0.1s linear")})),e(this,"handleAutoVideoEnded",(()=>{var t;const e=Pt.getState(),n=e.currentStepId;if(!n||!e.manifest)return;const i=e.manifest.steps.find((t=>t.id===n));if(!i)return;this.videoEndedCallback&&this.videoEndedCallback();const s=(null==(t=i.buttons)?void 0:t.some((t=>"url"===t.action.type)))??!1,r=e.manifest.steps.findIndex((t=>t.id===i.id))===e.manifest.steps.length-1,a=i.transitions.some((t=>e.manifest.steps.some((e=>e.id===t.nextStep)))),o=s||r||!a,l=i.transitions.some((t=>"url-path"===t.type)),c=i.transitions.some((t=>"dom-click"===t.type)),d=i.transitions.some((t=>"dom-element-visible"===t.type)),h=i.buttons&&i.buttons.length>0;if(l||c||d||h)o&&s&&Pt.setState((t=>{var i;t.currentState=t.stateMachine.send({type:"COMPLETE_PLAYLIST_WAITING_FOR_INTERACTION"}),t.progress[e.manifest.id]={...t.progress[e.manifest.id],lastStepId:n,lastVisited:(new Date).toISOString(),completedWaitingForInteraction:!0};((null==(i=t.playlistOptions)?void 0:i.persistence)??!0)&&"undefined"!=typeof window&&localStorage.setItem(G,JSON.stringify(t.progress))}));else if(i.transitions.length>0){const t=i.transitions[0].nextStep;e.goToStep(t)}else e.completePlaylist?e.completePlaylist():e.goToStep("completed")})),e(this,"handleManualVideoEnded",(()=>{var t;const e=Pt.getState(),n=e.currentStepId;if(n&&e.manifest&&e.manifest.steps){const i=e.manifest.steps.find((t=>t.id===n));if(i){const s=(null==(t=i.buttons)?void 0:t.some((t=>"url"===t.action.type)))??!1,r=e.manifest.steps.findIndex((t=>t.id===i.id))===e.manifest.steps.length-1,a=i.transitions.some((t=>e.manifest.steps.some((e=>e.id===t.nextStep))));if((s||r||!a)&&s)return Pt.setState((t=>{var i;t.currentState=t.stateMachine.send({type:"COMPLETE_PLAYLIST_WAITING_FOR_INTERACTION"}),t.progress[e.manifest.id]={...t.progress[e.manifest.id],lastStepId:n,lastVisited:(new Date).toISOString(),completedWaitingForInteraction:!0};((null==(i=t.playlistOptions)?void 0:i.persistence)??!0)&&"undefined"!=typeof window&&localStorage.setItem(G,JSON.stringify(t.progress))})),void(this.videoEndedCallback&&this.videoEndedCallback())}}this.videoEndedCallback&&this.videoEndedCallback()})),e(this,"handleProgressBarClick",(t=>{const e=t.currentTarget,n=this.getActiveVideo();if(!n||n.duration<=0)return;const i=e.getBoundingClientRect(),s=(t.clientX-i.left)/i.width,r=n.duration*s;this.progressBar&&(this.progressBar.style.transition="none",this.progressBar.style.width=100*s+"%"),this.seek(r),t.preventDefault(),t.stopPropagation()})),e(this,"handleSeeking",(()=>{this.progressBar&&(this.progressBar.style.transition="none",this.updateProgress())})),e(this,"handleSeeked",(()=>{if(this.progressBar){const t=this.getActiveVideo();t&&!t.paused&&(this.updateProgress(),this.progressBar.offsetWidth,this.progressBar.style.transition="width 0.1s linear")}}));const t=Ct.getDeviceInfo();this.deviceHandler=function(t){return t.isMobile?new zt(t):new At(t)}(t),this.transcriptManager=new _t,this.deviceChangeCleanup=Ct.onDeviceChange((t=>{this.deviceHandler.updateDeviceInfo(t),this.handleDeviceChange(t)}))}getDeviceInfo(){return Ct.getDeviceInfo()}isMobileDevice(){return this.getDeviceInfo().isMobile}handleDeviceChange(t){}create(t){this.container=document.createElement("div"),this.container.className="sf-video-container",t.appendChild(this.container),this.currentVideo=document.createElement("video"),this.currentVideo.className="sf-video-container__video sf-video-container__video--current",this.deviceHandler.configureVideoElement(this.currentVideo),this.container.appendChild(this.currentVideo),this.nextVideo=document.createElement("video"),this.nextVideo.className="sf-video-container__video sf-video-container__video--next",this.deviceHandler.configureVideoElement(this.nextVideo),this.nextVideo.style.backgroundColor="black",this.nextVideo.style.display="none",this.container.appendChild(this.nextVideo);Pt.getState().isMuted&&(this.currentVideo.muted=!0,this.nextVideo.muted=!0);const e=document.createElement("div");e.className="sf-video-container__controls",this.container.appendChild(e),this.progressBar=document.createElement("div"),this.progressBar.className="sf-video-container__progress",e.appendChild(this.progressBar);const n=this.deviceHandler.getControlsConfig();n.useTouch&&e.addEventListener("touchend",this.handleProgressBarClick),e.addEventListener("click",this.handleProgressBarClick),this.muteButton=document.createElement("button"),this.muteButton.className="sf-video-container__mute-button",this.deviceHandler.configureControlElement(this.muteButton),this.muteButton.innerHTML='\n <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">\n <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5" fill="none"></polygon>\n <path d="M15 9c0.8 0.8 1.5 1.9 1.5 3s-0.7 2.2-1.5 3" stroke="currentColor"></path>\n <path d="M19 7c1.6 1.6 2.5 3.8 2.5 6s-0.9 4.4-2.5 6" stroke="currentColor"></path>\n </svg>\n ',n.useTouch&&this.muteButton.addEventListener("touchend",(t=>{t.preventDefault(),this.toggleMute(t)})),this.muteButton.addEventListener("click",(t=>{this.toggleMute(t)})),this.container.appendChild(this.muteButton),this.updateMuteButtonIcon(),this.ccButton=document.createElement("button"),this.ccButton.className="sf-video-container__cc-button",this.deviceHandler.configureControlElement(this.ccButton),this.ccButton.innerHTML='\n <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">\n <rect x="2" y="6" width="20" height="12" rx="2" ry="2"></rect>\n <path d="M7 10h1v4H7z"></path>\n <path d="M11 10h1v4h-1z"></path>\n <path d="M15 10h1v4h-1z"></path>\n </svg>\n ',n.useTouch&&this.ccButton.addEventListener("touchend",(t=>{t.preventDefault()})),this.ccButton.addEventListener("click",(t=>{t.preventDefault()})),this.container.appendChild(this.ccButton),this.addEventListeners(),this.currentVideo&&this.ccButton&&this.transcriptManager.setup(this.currentVideo,this.ccButton)}getActiveVideo(){return 0===this.activeVideoIndex?this.currentVideo:this.nextVideo}getInactiveVideo(){return 0===this.activeVideoIndex?this.nextVideo:this.currentVideo}swapVideos(){const t=this.getActiveVideo(),e=this.getInactiveVideo();if(!t||!e)return;t.pause();const n=Pt.getState();e.muted=n.isMuted,t.style.display="none",e.style.display="block",this.activeVideoIndex=0===this.activeVideoIndex?1:0,this.currentVideoUrl=this.nextVideoUrl,this.nextVideoUrl=""}async loadVideo(t){var e;const n=this.getActiveVideo();if(!n)return;const i=Pt.getState();n.muted=i.isMuted;try{this.progressBar&&(this.progressBar.style.transition="none",this.progressBar.style.width="0%",setTimeout((()=>{this.progressBar&&(this.progressBar.style.transition="width 0.1s linear")}),50));const i=(null==(e=Pt.getState().playlistOptions)?void 0:e.persistence)??!0;if(this.currentVideoUrl===t&&n.src&&(n.src===t||n.src.endsWith(t))){if(i){const e=this.playbackPositions.get(t);void 0!==e&&e>0&&Math.abs(n.currentTime-e)>.5&&(n.currentTime=e)}return}i&&this.currentVideoUrl&&n.currentTime>0&&this.playbackPositions.set(this.currentVideoUrl,n.currentTime);if(this.getInactiveVideo()&&this.nextVideoUrl===t)return this.swapVideos(),void(await new Promise((t=>{const e=this.getActiveVideo();if(!e)return t();if(e.readyState>=3)t();else{const n=()=>{e.removeEventListener("canplay",n),t()};e.addEventListener("canplay",n)}})));this.currentVideoUrl=t;const s=this.preloadedVideos.get(t);if(s){const e=URL.createObjectURL(s);n.src=e,this.preloadedVideos.delete(t)}else n.src=t;n.load(),await new Promise(((e,s)=>{if(!n)return e(void 0);let r;const a=()=>{if(n){if(clearTimeout(r),i){const e=this.playbackPositions.get(t);if(void 0!==e&&e>0){const t=Math.min(e,n.duration-.5);n.currentTime=t}}else n.currentTime=0;n.removeEventListener("loadeddata",a),n.removeEventListener("error",o),e(void 0)}},o=t=>{var e,i,l;clearTimeout(r),console.error("VideoManager: Video load error:",null==(e=t.target)?void 0:e.error),n.removeEventListener("loadeddata",a),n.removeEventListener("error",o),s(new Error(`Video load failed: ${(null==(l=null==(i=t.target)?void 0:i.error)?void 0:l.message)||"Unknown error"}`))};r=window.setTimeout((()=>{console.error("VideoManager: Video load timeout after 10 seconds"),n.removeEventListener("loadeddata",a),n.removeEventListener("error",o),s(new Error("Video load timeout"))}),1e4),n.addEventListener("loadeddata",a),n.addEventListener("error",o)}))}catch(s){throw console.error("VideoManager: Failed to load video:",s),new Error("Failed to load video")}}preloadNextVideo(t){if(!t||this.preloadedVideos.has(t))return;if(this.currentVideoUrl===t)return;if(this.nextVideoUrl===t)return;const e=this.getInactiveVideo();if(e){this.nextVideoUrl=t,e.src=t,e.load(),e.preload="auto";const n=Pt.getState();e.muted=n.isMuted}else fetch(t).then((t=>{if(!t.ok)throw new Error(`Failed to fetch video: ${t.statusText}`);return t.blob()})).then((e=>{this.preloadedVideos.set(t,e)})).catch((e=>{console.error(`VideoManager: Error preloading video ${t}:`,e)}))}play(){var t;const e=this.getActiveVideo();if(!e)return void console.error("VideoManager: No active video element found");if(!e.paused)return;e.ended&&(e.currentTime=0);const n=Pt.getState();if(((null==(t=n.playlistOptions)?void 0:t.persistence)??!0)&&this.currentVideoUrl){const t=this.playbackPositions.get(this.currentVideoUrl);t&&Math.abs(e.currentTime-t)>.5&&(e.currentTime=t)}const i="autoplayBlocked"===n.currentState;i&&(e.currentTime=0,e.loop=!1,this.setMuted(!1),this.showProgressBar(),this.showMuteButton(),this.startProgressUpdates()),i||this.showProgressBar(),this.deviceHandler.handlePlayAttempt(e,this.hasUserInteracted).then((t=>{e&&(t?i||this.startProgressUpdates():(n.setAutoplayFallback(),this.isMobileDevice()&&(e.playsInline=!0,e.setAttribute("playsinline","true"),e.setAttribute("webkit-playsinline","true"),setTimeout((()=>{e.paused&&e.play().catch((()=>{}))}),200))))})).catch((()=>{console.warn("VideoManager: Autoplay handler threw error - browser has strict autoplay policy");Pt.getState().setAutoplayFallback()}))}pause(){const t=this.getActiveVideo();t&&(t.paused||(this.updateProgress(),this.progressBar&&(this.progressBar.style.transition="none"),t.pause(),this.stopProgressUpdates()))}seek(t){const e=this.getActiveVideo();if(e){if(this.progressBar){this.progressBar.style.transition="none";const n=t/e.duration*100;this.progressBar.style.width=`${n}%`}e.currentTime=t,this.updateProgress()}}getCurrentTime(){const t=this.getActiveVideo();return t?t.currentTime:0}getDuration(){const t=this.getActiveVideo();return t?t.duration:0}getVideoElement(){return this.getActiveVideo()}reset(){this.stopProgressUpdates(),this.preloadedVideos.clear(),this.playbackPositions.clear(),this.currentVideoUrl="",this.nextVideoUrl="",this.activeVideoIndex=0,this.hasUserInteracted=!1,this.lastTimeupdateEvent=0,null!==this.autoplayFallbackTimeout&&(window.clearTimeout(this.autoplayFallbackTimeout),this.autoplayFallbackTimeout=null),this.completionPolicy="auto",this.videoEndedCallback=null,this.transcriptManager.reset(),this.currentVideo&&(this.currentVideo.src="",this.currentVideo.currentTime=0,this.currentVideo.pause()),this.nextVideo&&(this.nextVideo.src="",this.nextVideo.currentTime=0,this.nextVideo.pause())}async destroy(){this.stopProgressUpdates(),this.removeEventListeners(),this.transcriptManager.destroy(),null!==this.autoplayFallbackTimeout&&(window.clearTimeout(this.autoplayFallbackTimeout),this.autoplayFallbackTimeout=null),this.deviceChangeCleanup&&(this.deviceChangeCleanup(),this.deviceChangeCleanup=null),this.container&&this.container.parentNode&&this.container.parentNode.removeChild(this.container),this.currentVideo=null,this.nextVideo=null,this.container=null,this.progressBar=null,this.muteButton=null,this.ccButton=null,this.currentVideoUrl="",this.nextVideoUrl="",this.videoEndedCallback=null}addEventListeners(){const t=this.currentVideo,e=this.nextVideo;if(t&&(t.addEventListener("ended",this.handleVideoEnded),t.addEventListener("timeupdate",this.handleDetailedTimeUpdate),t.addEventListener("error",this.handleVideoError),t.addEventListener("seeking",this.handleSeeking),t.addEventListener("seeked",this.handleSeeked)),e&&(e.addEventListener("ended",this.handleVideoEnded),e.addEventListener("timeupdate",this.handleDetailedTimeUpdate),e.addEventListener("error",this.handleVideoError),e.addEventListener("seeking",this.handleSeeking),e.addEventListener("seeked",this.handleSeeked)),this.container){const t=this.container.querySelector(".sf-video-container__controls");t&&t.addEventListener("click",this.handleProgressBarClick)}}removeEventListeners(){const t=this.currentVideo,e=this.nextVideo;if(t&&(t.removeEventListener("ended",this.handleVideoEnded),t.removeEventListener("timeupdate",this.handleDetailedTimeUpdate),t.removeEventListener("error",this.handleVideoError),t.removeEventListener("seeking",this.handleSeeking),t.removeEventListener("seeked",this.handleSeeked)),e&&(e.removeEventListener("ended",this.handleVideoEnded),e.removeEventListener("timeupdate",this.handleDetailedTimeUpdate),e.removeEventListener("error",this.handleVideoError),e.removeEventListener("seeking",this.handleSeeking),e.removeEventListener("seeked",this.handleSeeked)),this.container){const t=this.container.querySelector(".sf-video-container__controls");t&&t.removeEventListener("click",this.handleProgressBarClick)}}startProgressUpdates(){this.stopProgressUpdates();const t=this.getActiveVideo();if(!t)return;const e=t.loop&&t.muted,n=this.deviceHandler.getProgressUpdateFrequency(e);if(n>=16){const e=()=>{!t||t.paused||t.ended||this.updateProgress(),this.animationFrameId=requestAnimationFrame(e)};this.animationFrameId=requestAnimationFrame(e)}else{const e=()=>{null===this.updateInterval||!t||t.paused||t.ended||(this.updateProgress(),this.updateInterval=window.setTimeout(e,n))};this.updateInterval=window.setTimeout(e,n)}}stopProgressUpdates(){null!==this.updateInterval&&(window.clearInterval(this.updateInterval),this.updateInterval=null),null!==this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null)}updateProgress(){if(!this.progressBar)return;const t=this.getActiveVideo();if(!t)return;const e=t.currentTime||0,n=t.duration||0;if(n>0){const i=e/n*100,s="none"!==this.progressBar.style.transition,r=Date.now()-this.lastTimeupdateEvent;this.progressBar.style.transition="none",this.progressBar.style.width=`${i}%`,this.progressBar.offsetWidth,t.ended?this.progressBar.style.transition="width 0.2s ease-out":!t.paused&&!t.seeking&&s&&r<500&&(this.progressBar.style.transition="width 0.1s linear")}}setMuted(t){this.currentVideo&&(this.currentVideo.muted=t),this.nextVideo&&(this.nextVideo.muted=t);Pt.getState().setMuted(t),this.updateMuteButtonIcon()}toggleMute(t){const e=this.getActiveVideo();if(!e)return;const n=!e.muted;this.setMuted(n),t&&(t.preventDefault(),t.stopPropagation())}updateMuteButtonIcon(){if(!this.muteButton)return;const t=this.getActiveVideo(),e=!t||t.muted;this.muteButton.innerHTML=e?'\n <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">\n <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5" fill="none"></polygon>\n <line x1="23" y1="9" x2="17" y2="15"></line>\n <line x1="17" y1="9" x2="23" y2="15"></line>\n </svg>\n ':'\n <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">\n <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5" fill="none"></polygon>\n <path d="M15 9c0.8 0.8 1.5 1.9 1.5 3s-0.7 2.2-1.5 3" stroke="currentColor"></path>\n <path d="M19 7c1.6 1.6 2.5 3.8 2.5 6s-0.9 4.4-2.5 6" stroke="currentColor"></path>\n </svg>\n '}isMuted(){const t=this.getActiveVideo();return!t||t.muted}setCompletionPolicy(t,e){this.completionPolicy=t,this.videoEndedCallback=e||null,this.updateVideoEndedHandler()}updateVideoEndedHandler(){}hideProgressBar(){if(this.container){const t=this.container.querySelector(".sf-video-container__controls");t&&(t.style.display="none")}}showProgressBar(){if(this.container){const t=this.container.querySelector(".sf-video-container__controls");if(t){const e=t.closest(".sf-player"),n=null==e?void 0:e.classList.contains("sf-player--minimized");t.style.display=n?"":"block"}}this.progressBar&&(this.progressBar.style.transition="none",this.progressBar.style.width="0%",this.progressBar.offsetWidth,this.progressBar.style.transition="width 0.1s linear");const t=this.getActiveVideo();!t||t.paused||t.ended||this.startProgressUpdates()}hideMuteButton(){this.muteButton&&(this.muteButton.style.display="none")}showMuteButton(){this.muteButton&&(this.muteButton.style.display="block")}markUserInteraction(){this.hasUserInteracted||(this.hasUserInteracted=!0,null!==this.autoplayFallbackTimeout&&(window.clearTimeout(this.autoplayFallbackTimeout),this.autoplayFallbackTimeout=null))}hasUserInteractedWith(){return this.hasUserInteracted}resetUserInteraction(){this.hasUserInteracted=!1,null!==this.autoplayFallbackTimeout&&(window.clearTimeout(this.autoplayFallbackTimeout),this.autoplayFallbackTimeout=null)}handleAutoplayFallbackClick(t){this.markUserInteraction(),t.muted=!1,t.loop=!1,t.currentTime=0}loadTranscript(t){this.transcriptManager.loadTranscript(t)}}class Vt{constructor(){e(this,"cursor",null),e(this,"animationFrameId",null),e(this,"animationStartTime",null),e(this,"currentAnimation",null),e(this,"flashlightOverlay",null),e(this,"startX",null),e(this,"startY",null),e(this,"targetX",null),e(this,"targetY",null),e(this,"shouldShowCursor",!1),e(this,"lastCursorX",50),e(this,"lastCursorY",50),e(this,"isFirstAnimation",!0),e(this,"currentTargetElement",null),e(this,"scrollThrottleTimeout",null),e(this,"boundScrollHandler",null),e(this,"scrollableParents",[]),e(this,"parentScrollHandlers",new Map),e(this,"selectionElement",null),e(this,"isSelectionMode",!1),e(this,"selectionStartWidth",null),e(this,"selectionStartHeight",null),e(this,"selectionTargetWidth",null),e(this,"selectionTargetHeight",null),e(this,"selectionPadding",4),e(this,"dragStartX",null),e(this,"dragStartY",null),e(this,"dragEndX",null),e(this,"dragEndY",null),e(this,"dragPhase","move-to-start"),e(this,"dragAnimationStartTime",null),e(this,"cursorSpeed",.4),e(this,"totalDistance",0),e(this,"controlPointX",null),e(this,"controlPointY",null),e(this,"targetMutationObserver",null)}findScrollableParents(t){const e=[];let n=t.parentElement;for(;n&&n!==document.body;){const t=window.getComputedStyle(n),i=t.overflow,s=t.overflowX,r=t.overflowY;"scroll"!==i&&"auto"!==i&&"scroll"!==s&&"auto"!==s&&"scroll"!==r&&"auto"!==r||(n.scrollHeight>n.clientHeight||n.scrollWidth>n.clientWidth)&&e.push(n),n=n.parentElement}return e}addScrollListenersToParents(t){this.removeScrollListenersFromParents(),this.scrollableParents=this.findScrollableParents(t),this.scrollableParents.forEach((t=>{const e=this.handleScroll.bind(this);this.parentScrollHandlers.set(t,e),t.addEventListener("scroll",e,{passive:!0})}))}removeScrollListenersFromParents(){this.parentScrollHandlers.forEach(((t,e)=>{e.removeEventListener("scroll",t)})),this.parentScrollHandlers.clear(),this.scrollableParents=[]}findElement(t){const e=document.querySelector(t);return e||null}isElementInViewport(t){const e=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,i=window.innerWidth||document.documentElement.clientWidth;if(!(e.top>=0&&e.bottom<=n&&e.left>=0&&e.right<=i))return!1;const s=this.findScrollableParents(t);for(const r of s){const t=r.getBoundingClientRect();if(!(e.top>=t.top&&e.bottom<=t.bottom&&e.left>=t.left&&e.right<=t.right))return!1}return!0}async scrollElementIntoView(t){return new Promise((e=>{const n=this.findScrollableParents(t);if(0===n.length){t.scrollIntoView({behavior:"smooth",block:"center",inline:"center"});let n=null;const i=()=>{null!==n&&clearTimeout(n),n=window.setTimeout((()=>{window.removeEventListener("scroll",i),e()}),100)};window.addEventListener("scroll",i),setTimeout((()=>{window.removeEventListener("scroll",i),null!==n&&clearTimeout(n),e()}),1e3)}else this.scrollParentContainersToShowElement(t,n).then((()=>{this.isElementInViewport(t)||t.scrollIntoView({behavior:"smooth",block:"center",inline:"center"}),setTimeout((()=>{e()}),200)}))}))}async scrollParentContainersToShowElement(t,e){return new Promise((n=>{let i=0;const s=e.length;if(0===s)return void n();const r=()=>{i++,i>=s&&n()};e.forEach(((e,n)=>{const i=t.getBoundingClientRect(),s=e.getBoundingClientRect(),a=e.scrollTop,o=e.scrollLeft,l=a+(i.top-s.top)-s.height/2+i.height/2,c=o+(i.left-s.left)-s.width/2+i.width/2;e.scrollTo({top:Math.max(0,l),left:Math.max(0,c),behavior:"smooth"});let d=null;const h=()=>{null!==d&&clearTimeout(d),d=window.setTimeout((()=>{e.removeEventListener("scroll",h),r()}),100)};e.addEventListener("scroll",h),setTimeout((()=>{e.removeEventListener("scroll",h),null!==d&&clearTimeout(d),r()}),800)}))}))}async findElementAndScrollIntoView(t){const e=this.findElement(t);return e?(this.isElementInViewport(e)||await this.scrollElementIntoView(e),e):null}create(){this.cursor=document.createElement("div"),this.cursor.style.position="fixed",this.cursor.style.top="0",this.cursor.style.left="0",this.cursor.style.width="36px",this.cursor.style.height="36px",this.cursor.style.zIndex="9999999",this.cursor.style.pointerEvents="none",this.cursor.style.display="none",this.cursor.style.transform="translate(-50%, -50%)",this.cursor.innerHTML='\n <svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24" fill="none" stroke="#ff7614" stroke-width="2">\n <path d="M3 3L10.5 21L13.5 13.5L21 10.5L3 3Z" fill="#ff7614" />\n </svg>\n ',this.selectionElement=document.createElement("div"),this.selectionElement.style.position="fixed",this.selectionElement.style.pointerEvents="none",this.selectionElement.style.display="none",this.selectionElement.style.zIndex="9999998",document.body.appendChild(this.cursor),document.body.appendChild(this.selectionElement),this.flashlightOverlay=document.createElement("div"),this.flashlightOverlay.style.position="fixed",this.flashlightOverlay.style.top="0",this.flashlightOverlay.style.left="0",this.flashlightOverlay.style.width="100vw",this.flashlightOverlay.style.height="100vh",this.flashlightOverlay.style.pointerEvents="none",this.flashlightOverlay.style.zIndex="999997",this.flashlightOverlay.style.display="none",this.flashlightOverlay.style.background="radial-gradient(circle 150px at 50% 50%, transparent 0%, rgba(0, 0, 0, 0.4) 100%)",document.body.appendChild(this.flashlightOverlay),this.boundScrollHandler=this.handleScroll.bind(this),window.addEventListener("scroll",this.boundScrollHandler,{passive:!0})}handleScroll(){this.shouldShowCursor&&this.currentTargetElement&&null===this.scrollThrottleTimeout&&(this.scrollThrottleTimeout=window.setTimeout((()=>{var t,e,n,i;if(this.scrollThrottleTimeout=null,null!==this.animationFrameId||!this.currentTargetElement)return;const s=this.currentTargetElement.getBoundingClientRect(),r=s.left+s.width/2,a=s.top+s.height/2;if(this.show(r,a),this.lastCursorX=r,this.lastCursorY=a,this.selectionElement&&this.isSelectionMode){const r="number"==typeof(null==(e=null==(t=this.currentAnimation)?void 0:t.selectionStyles)?void 0:e.padding)?this.currentAnimation.selectionStyles.padding:(null==(i=null==(n=this.currentAnimation)?void 0:n.selectionStyles)?void 0:i.padding)?parseInt(this.currentAnimation.selectionStyles.padding,10):this.selectionPadding,a=Math.floor(s.left-r),o=Math.floor(s.top-r),l=Math.ceil(s.width+2*r),c=Math.ceil(s.height+2*r);this.selectionElement.style.setProperty("--sf-selection-left",`${a}px`),this.selectionElement.style.setProperty("--sf-selection-top",`${o}px`),this.selectionElement.style.setProperty("--sf-selection-width",`${l}px`),this.selectionElement.style.setProperty("--sf-selection-height",`${c}px`),this.dragStartX=a,this.dragStartY=o,this.dragEndX=a+l,this.dragEndY=o+c,this.updateFlashlightWithCutout(a,o,l,c)}}),100))}isAutoplayBlocked(){return"autoplayBlocked"===It.getState().currentState}setShouldShowCursor(t){if(this.isAutoplayBlocked())return this.shouldShowCursor=!1,void this.hide();this.shouldShowCursor=t,t?this.isFirstAnimation||this.show(this.lastCursorX,this.lastCursorY):this.hide()}show(t,e){this.shouldShowCursor&&(this.isAutoplayBlocked()||(this.lastCursorX=t,this.lastCursorY=e,this.cursor&&(this.cursor.style.display="block",this.cursor.style.top=`${e}px`,this.cursor.style.left=`${t}px`),this.flashlightOverlay&&(this.flashlightOverlay.style.display="block",this.flashlightOverlay.style.background=`radial-gradient(circle 150px at ${t}px ${e}px, transparent 0%, rgba(0, 0, 0, 0.4) 100%)`)))}hide(){this.cursor&&(this.cursor.style.display="none"),this.selectionElement&&(this.selectionElement.style.display="none"),this.flashlightOverlay&&(this.flashlightOverlay.style.display="none",this.resetFlashlightOverlay())}resetFlashlightOverlay(){if(!this.flashlightOverlay)return;this.flashlightOverlay.style.clipPath="none";const t=this.lastCursorX,e=this.lastCursorY;this.flashlightOverlay.style.background=`radial-gradient(circle 150px at ${t}px ${e}px, transparent 0%, rgba(0, 0, 0, 0.4) 100%)`}updateSelectionArea(t,e){if(!this.selectionElement)return;const n=t.getBoundingClientRect(),i="number"==typeof(null==e?void 0:e.padding)?e.padding:(null==e?void 0:e.padding)?parseInt(e.padding,10):this.selectionPadding;this.selectionElement.style.display="block",this.selectionElement.style.left=n.left-i+"px",this.selectionElement.style.top=n.top-i+"px",this.selectionElement.style.width=`${n.width+2*i}px`,this.selectionElement.style.height=`${n.height+2*i}px`,e&&(e.borderColor&&(this.selectionElement.style.borderColor=e.borderColor),e.borderWidth&&(this.selectionElement.style.borderWidth=e.borderWidth),e.borderRadius&&(this.selectionElement.style.borderRadius=e.borderRadius))}async animate(t){if(this.isAutoplayBlocked())return;if(this.setShouldShowCursor(!0),this.stopAnimation(),this.resetFlashlightOverlay(),this.selectionElement&&(this.selectionElement.style.display="none"),!(null==t?void 0:t.targetSelector))return void console.warn("CursorManager: No targetSelector provided in animation");this.targetMutationObserver&&(this.targetMutationObserver.disconnect(),this.targetMutationObserver=null);const e=await this.findElementAndScrollIntoView(t.targetSelector);if(!e){console.warn("CursorManager: Target element not found in animate:",t.targetSelector),this.targetMutationObserver=new MutationObserver((async(e,n)=>{await this.findElementAndScrollIntoView(t.targetSelector)&&(n.disconnect(),this.targetMutationObserver=null,await this.animate(t))})),this.targetMutationObserver.observe(document.body,{childList:!0,subtree:!0});const e=setInterval((()=>{if(!this.targetMutationObserver)return void clearInterval(e);this.findElement(t.targetSelector)&&(clearInterval(e),this.targetMutationObserver.disconnect(),this.targetMutationObserver=null,this.animate(t))}),1e3);return}this.currentTargetElement=e,this.addScrollListenersToParents(e);const n=e.getBoundingClientRect();this.isFirstAnimation?(this.startX=50,this.startY=50,this.isFirstAnimation=!1):(this.startX=this.lastCursorX,this.startY=this.lastCursorY);const i={...t,mode:t.mode||"selection"};if(this.isSelectionMode="selection"===i.mode,this.isSelectionMode)return void this.handleSelectionMode(i,n);{const t=16;this.targetX=n.left+n.width/2+t;const e=16;this.targetY=n.top+n.height/2+e,this.selectionElement&&(this.selectionElement.style.display="none")}null!==this.targetX&&null!==this.targetY&&null!==this.startX&&null!==this.startY?this.totalDistance=Math.sqrt(Math.pow(this.targetX-this.startX,2)+Math.pow(this.targetY-this.startY,2)):this.totalDistance=100,this.calculateControlPoint(),this.currentAnimation={...i};const s=null!==this.startX?this.startX:0,r=null!==this.startY?this.startY:0;this.show(s,r),this.animationStartTime=performance.now(),this.animationFrameId=requestAnimationFrame(this.animationFrame.bind(this))}handleSelectionMode(t,e){var n,i;const s="number"==typeof(null==(n=t.selectionStyles)?void 0:n.padding)?t.selectionStyles.padding:(null==(i=t.selectionStyles)?void 0:i.padding)?parseInt(t.selectionStyles.padding,10):this.selectionPadding;this.dragStartX=Math.floor(e.left-s),this.dragStartY=Math.floor(e.top-s),this.dragEndX=Math.ceil(e.right+s),this.dragEndY=Math.ceil(e.bottom+s),this.dragPhase="move-to-start";this.targetX=this.dragStartX+8,this.targetY=this.dragStartY+8,null!==this.targetX&&null!==this.targetY&&null!==this.startX&&null!==this.startY?this.totalDistance=Math.sqrt(Math.pow(this.targetX-this.startX,2)+Math.pow(this.targetY-this.startY,2)):this.totalDistance=100,this.selectionElement&&(t.selectionStyles&&(t.selectionStyles.borderColor&&this.selectionElement.style.setProperty("--sf-selection-border-color",t.selectionStyles.borderColor),t.selectionStyles.borderWidth&&this.selectionElement.style.setProperty("--sf-selection-border-width",t.selectionStyles.borderWidth),t.selectionStyles.borderRadius&&this.selectionElement.style.setProperty("--sf-selection-border-radius",t.selectionStyles.borderRadius)),this.selectionElement.style.display="none"),this.calculateControlPoint(),this.currentAnimation={...t};const r=null!==this.startX?this.startX:0,a=null!==this.startY?this.startY:0;this.show(r,a),this.animationStartTime=performance.now(),this.animationFrameId=requestAnimationFrame(this.dragAnimationFrame.bind(this))}dragAnimationFrame(t){var e,n;if(!this.animationStartTime||!this.currentAnimation)return void this.stopAnimation();const i=this.targetX||0,s=this.targetY||0;if(this.currentTargetElement&&"release"!==this.dragPhase){const t=this.currentTargetElement.getBoundingClientRect(),r="number"==typeof(null==(e=this.currentAnimation.selectionStyles)?void 0:e.padding)?this.currentAnimation.selectionStyles.padding:(null==(n=this.currentAnimation.selectionStyles)?void 0:n.padding)?parseInt(this.currentAnimation.selectionStyles.padding,10):this.selectionPadding;if(this.dragStartX=Math.floor(t.left-r),this.dragStartY=Math.floor(t.top-r),this.dragEndX=Math.ceil(t.right+r),this.dragEndY=Math.ceil(t.bottom+r),"move-to-start"===this.dragPhase){const t=8,e=8;this.targetX=this.dragStartX+t,this.targetY=this.dragStartY+e;const n=Math.abs(i-this.targetX),r=Math.abs(s-this.targetY);n>10||r>10?this.calculateControlPoint():null!==this.startX&&null!==this.startY&&(this.totalDistance=Math.sqrt(Math.pow(this.targetX-this.startX,2)+Math.pow(this.targetY-this.startY,2)))}}if("move-to-start"===this.dragPhase){if(!(this.startX&&this.startY&&this.targetX&&this.targetY&&this.controlPointX&&this.controlPointY))return void this.stopAnimation();const e=t-this.animationStartTime,n=this.cursorSpeed*e;if(n>=this.totalDistance)return this.show(this.targetX,this.targetY),this.lastCursorX=this.targetX,this.lastCursorY=this.targetY,this.dragPhase="dragging",this.dragAnimationStartTime=performance.now(),this.cursor&&(this.cursor.style.transform="scale(0.9) translate(-50%, -50%)",this.cursor.style.opacity="0.9"),this.selectionElement&&(this.selectionElement.style.left=`${this.dragStartX}px`,this.selectionElement.style.top=`${this.dragStartY}px`,this.selectionElement.style.width="0px",this.selectionElement.style.height="0px",this.selectionElement.style.display="block"),void(this.animationFrameId=requestAnimationFrame(this.dragAnimationFrame.bind(this)));let i=this.totalDistance>0?n/this.totalDistance:1;i=Math.min(i,1);const s=.5-.5*Math.cos(i*Math.PI),r=1-s,a=Math.pow(r,2)*this.startX+2*r*s*this.controlPointX+Math.pow(s,2)*this.targetX,o=Math.pow(r,2)*this.startY+2*r*s*this.controlPointY+Math.pow(s,2)*this.targetY;this.show(a,o)}else if("dragging"===this.dragPhase){if(!(this.dragAnimationStartTime&&this.dragStartX&&this.dragStartY&&this.dragEndX&&this.dragEndY))return void this.stopAnimation();const e=1e3,n=t-this.dragAnimationStartTime;let i=Math.min(n/e,1);const s=.5-.5*Math.cos(i*Math.PI),r=8,a=8,o=this.dragStartX+(this.dragEndX-this.dragStartX)*s+r,l=this.dragStartY+(this.dragEndY-this.dragStartY)*s+a;if(this.show(o,l),this.selectionElement){let t=Math.ceil(Math.abs(o-r-this.dragStartX)),e=Math.ceil(Math.abs(l-a-this.dragStartY)),n=Math.floor(Math.min(this.dragStartX,o-r)),i=Math.floor(Math.min(this.dragStartY,l-a));this.selectionElement.style.left=`${n}px`,this.selectionElement.style.top=`${i}px`,this.selectionElement.style.width=`${t}px`,this.selectionElement.style.height=`${e}px`,this.selectionElement.style.display="block",this.updateFlashlightWithCutout(n,i,t,e)}i>=1&&(this.dragPhase="release",this.cursor&&(this.cursor.style.transform="translate(-50%, -50%)",this.cursor.style.opacity="1"),null!==this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.animationStartTime=null,this.dragAnimationStartTime=null)}"release"!==this.dragPhase&&(this.animationFrameId=requestAnimationFrame(this.dragAnimationFrame.bind(this)))}updateFlashlightWithCutout(t,e,n,i){if(!this.flashlightOverlay)return;const s=`\n polygon(\n 0% 0%, /* Top-left of screen */\n 100% 0%, /* Top-right of screen */\n 100% 100%, /* Bottom-right of screen */\n 0% 100%, /* Bottom-left of screen */\n 0% ${e}px, /* Begin cutout: bottom-left of cutout */\n ${t}px ${e}px, /* Bottom-left of cutout */\n ${t}px ${e+i}px, /* Top-left of cutout */\n ${t+n}px ${e+i}px, /* Top-right of cutout */\n ${t+n}px ${e}px, /* Bottom-right of cutout */\n 0% ${e}px /* Close cutout path */\n )\n `;this.flashlightOverlay.style.clipPath=s;const r=this.lastCursorX,a=this.lastCursorY;this.flashlightOverlay.style.background=`radial-gradient(circle 150px at ${r}px ${a}px, transparent 0%, rgba(0, 0, 0, 0.4) 100%)`}calculateControlPoint(){if(!(this.startX&&this.startY&&this.targetX&&this.targetY))return void console.warn("CursorManager: Missing start or target position for control point calculation",{startX:this.startX,startY:this.startY,targetX:this.targetX,targetY:this.targetY});const t=(this.startX+this.targetX)/2,e=(this.startY+this.targetY)/2,n=Math.sqrt(Math.pow(this.targetX-this.startX,2)+Math.pow(this.targetY-this.startY,2));this.totalDistance=n;const i=.2*n,s=(Math.random()-.5)*i*2,r=this.targetX-this.startX,a=-(this.targetY-this.startY),o=r,l=Math.sqrt(a*a+o*o);if(0===l)this.controlPointX=t+5,this.controlPointY=e+5;else{const n=a/l,i=o/l;this.controlPointX=t+n*s,this.controlPointY=e+i*s}}async moveToElement(t,e,n){if(this.isAutoplayBlocked())return;if(!this.shouldShowCursor)return;this.stopAnimation(),this.resetFlashlightOverlay(),this.targetMutationObserver&&(this.targetMutationObserver.disconnect(),this.targetMutationObserver=null);const i=await this.findElementAndScrollIntoView(t);if(!i){console.warn("CursorManager: Target element not found:",t),this.targetMutationObserver=new MutationObserver((async(i,s)=>{await this.findElementAndScrollIntoView(t)&&(s.disconnect(),this.targetMutationObserver=null,await this.moveToElement(t,e,n))})),this.targetMutationObserver.observe(document.body,{childList:!0,subtree:!0});const i=setInterval((()=>{if(!this.targetMutationObserver)return void clearInterval(i);this.findElement(t)&&(clearInterval(i),this.targetMutationObserver.disconnect(),this.targetMutationObserver=null,this.moveToElement(t,e,n))}),1e3);return}i.getBoundingClientRect(),this.currentTargetElement=i,this.addScrollListenersToParents(i);const s={targetSelector:t,mode:e||"selection",selectionStyles:n};this.animate(s)}click(){this.isAutoplayBlocked()||this.shouldShowCursor&&(this.cursor?(this.cursor.style.transform="scale(0.8) translate(-50%, -50%)",this.cursor.style.opacity="0.8",setTimeout((()=>{if(this.cursor){if(!this.shouldShowCursor||this.isAutoplayBlocked())return void this.hide();this.cursor.style.transform="translate(-50%, -50%)",this.cursor.style.opacity="1"}else console.warn("CursorManager: Cursor element was removed during click animation")}),300)):console.warn("CursorManager: Cannot apply click animation - cursor element is null"))}stopAnimation(){null!==this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.animationStartTime=null,this.currentAnimation=null,this.controlPointX=null,this.controlPointY=null,this.selectionStartWidth=null,this.selectionStartHeight=null,this.selectionTargetWidth=null,this.selectionTargetHeight=null,this.dragPhase="move-to-start",this.dragAnimationStartTime=null,this.cursor&&(this.cursor.style.transform="translate(-50%, -50%)",this.cursor.style.opacity="1"),this.resetFlashlightOverlay(),this.selectionElement&&(this.selectionElement.style.display="none")}getCursorX(){if(this.cursor){const t=this.cursor.style.transform.match(/translate\((\d+)px, \d+px\)/);return t?parseInt(t[1],10):this.lastCursorX}return this.lastCursorX}getCursorY(){if(this.cursor){const t=this.cursor.style.transform.match(/translate\(\d+px, (\d+)px\)/);return t?parseInt(t[1],10):this.lastCursorY}return this.lastCursorY}resetFirstAnimation(){this.isFirstAnimation=!0}reset(){this.stopAnimation(),this.currentAnimation=null,this.animationStartTime=null,this.startX=null,this.startY=null,this.targetX=null,this.targetY=null,this.currentTargetElement=null,this.isFirstAnimation=!0,this.shouldShowCursor=!1,this.cursor&&(this.cursor.style.display="none"),this.isSelectionMode=!1,this.selectionElement&&(this.selectionElement.style.display="none"),this.dragStartX=null,this.dragStartY=null,this.dragEndX=null,this.dragEndY=null,this.dragPhase="move-to-start",this.dragAnimationStartTime=null,null!==this.scrollThrottleTimeout&&(window.clearTimeout(this.scrollThrottleTimeout),this.scrollThrottleTimeout=null),this.removeScrollListenersFromParents(),this.scrollableParents=[]}async destroy(){this.stopAnimation(),this.boundScrollHandler&&(window.removeEventListener("scroll",this.boundScrollHandler),this.boundScrollHandler=null),this.removeScrollListenersFromParents(),null!==this.scrollThrottleTimeout&&(window.clearTimeout(this.scrollThrottleTimeout),this.scrollThrottleTimeout=null),this.cursor&&this.cursor.parentNode&&(this.cursor.remove(),this.cursor=null),this.selectionElement&&this.selectionElement.parentNode&&(this.selectionElement.remove(),this.selectionElement=null),this.flashlightOverlay&&this.flashlightOverlay.parentNode&&(this.flashlightOverlay.remove(),this.flashlightOverlay=null),this.isFirstAnimation=!0,this.shouldShowCursor=!1,this.currentTargetElement=null,this.isSelectionMode=!1,this.targetMutationObserver&&(this.targetMutationObserver.disconnect(),this.targetMutationObserver=null),document.documentElement.style.removeProperty("--sf-cursor-x"),document.documentElement.style.removeProperty("--sf-cursor-y")}animationFrame(t){var e,n,i;if(!(this.animationStartTime&&this.currentAnimation&&this.startX&&this.startY&&this.targetX&&this.targetY&&this.controlPointX&&this.controlPointY))return console.warn("CursorManager: Animation frame missing essential data, stopping animation"),void this.stopAnimation();const s=this.targetX||0,r=this.targetY||0;if(this.currentTargetElement){const t=this.currentTargetElement.getBoundingClientRect();if(this.isSelectionMode){const i="number"==typeof(null==(e=this.currentAnimation.selectionStyles)?void 0:e.padding)?this.currentAnimation.selectionStyles.padding:(null==(n=this.currentAnimation.selectionStyles)?void 0:n.padding)?parseInt(this.currentAnimation.selectionStyles.padding,10):this.selectionPadding;this.dragStartX=Math.floor(t.left-i),this.dragStartY=Math.floor(t.top-i),this.dragEndX=Math.ceil(t.right+i),this.dragEndY=Math.ceil(t.bottom+i)}else{const e=16,n=16;this.targetX=t.left+t.width/2+e,this.targetY=t.top+t.height/2+n;const i=Math.abs(s-this.targetX),a=Math.abs(r-this.targetY);i>10||a>10?this.calculateControlPoint():null!==this.startX&&null!==this.startY&&(this.totalDistance=Math.sqrt(Math.pow(this.targetX-this.startX,2)+Math.pow(this.targetY-this.startY,2)))}}const a=t-this.animationStartTime,o=this.cursorSpeed*a;if(o>=this.totalDistance)return this.show(this.targetX,this.targetY),this.lastCursorX=this.targetX,this.lastCursorY=this.targetY,this.isSelectionMode&&this.currentTargetElement&&this.selectionElement?this.updateSelectionArea(this.currentTargetElement,this.currentAnimation.selectionStyles):this.click(),void setTimeout((()=>{this.stopAnimation()}),400);let l=this.totalDistance>0?o/this.totalDistance:1;l=Math.min(l,1);const c=.5-.5*Math.cos(l*Math.PI),d=c,h=1-d,u=Math.pow(h,2)*this.startX+2*h*d*this.controlPointX+Math.pow(d,2)*this.targetX,p=Math.pow(h,2)*this.startY+2*h*d*this.controlPointY+Math.pow(d,2)*this.targetY;if(this.show(u,p),this.isSelectionMode&&this.selectionElement&&null!==this.selectionStartWidth&&null!==this.selectionStartHeight&&null!==this.selectionTargetWidth&&null!==this.selectionTargetHeight){const t=this.selectionStartWidth+(this.selectionTargetWidth-this.selectionStartWidth)*c,e=this.selectionStartHeight+(this.selectionTargetHeight-this.selectionStartHeight)*c,n=null==(i=this.currentTargetElement)?void 0:i.getBoundingClientRect();n&&this.currentTargetElement&&(this.selectionElement.style.left=n.left+n.width/2-t/2+"px",this.selectionElement.style.top=n.top+n.height/2-e/2+"px",this.selectionElement.style.width=`${t}px`,this.selectionElement.style.height=`${e}px`,c>.9&&this.updateSelectionArea(this.currentTargetElement,this.currentAnimation.selectionStyles))}this.animationFrameId=requestAnimationFrame(this.animationFrame.bind(this))}setColor(t){if(this.cursor){const e=this.cursor.querySelector("svg");if(e){e.setAttribute("stroke",t);const n=e.querySelector("path");n?n.setAttribute("fill",t):console.warn("[CursorManager.setColor] No path found in SVG")}else console.warn("[CursorManager.setColor] No SVG found in cursor")}else console.warn("[CursorManager.setColor] No cursor element")}}class Lt{constructor(){e(this,"container",null),e(this,"buttons",[]),e(this,"buttonContainer",null),e(this,"domEventListeners",new Map),e(this,"storeUnsubscribe",null)}create(t){this.container=t,this.storeUnsubscribe=Pt.subscribe(((t,e)=>{t.isMinimized!==(null==e?void 0:e.isMinimized)&&this.updateButtonPositions()}))}createButtons(t){if(!this.container)return;this.clearButtons(),this.buttonContainer=document.createElement("div"),this.buttonContainer.className="sf-choice-buttons-container",this.container.appendChild(this.buttonContainer),t.forEach((t=>{const e=document.createElement("button");e.textContent=t.text,e.dataset.buttonId=t.id,e.className=`sf-choice-button sf-choice-button--${t.action.type}`,t.style&&Object.entries(t.style).forEach((([t,n])=>{e.style.setProperty(`--custom-${t}`,String(n))})),e.addEventListener("click",(async e=>{await this.handleButtonClick(e,t)})),this.buttonContainer&&(this.buttonContainer.appendChild(e),this.buttons.push(e),t.id)}));Pt.getState().isMinimized&&(this.buttonContainer.style.display="none")}clearButtons(){this.buttons.forEach((t=>{t.parentElement&&t.parentElement.removeChild(t)})),this.buttonContainer&&this.buttonContainer.parentElement&&this.buttonContainer.parentElement.removeChild(this.buttonContainer),this.buttons=[],this.buttonContainer=null}updateButtonPositions(){if(!this.buttonContainer||0===this.buttons.length)return;Pt.getState().isMinimized?this.buttonContainer.style.display="none":(this.buttonContainer.style.display="flex",this.buttonContainer.className="sf-choice-buttons-container")}setupDOMInteractions(t){this.clearDOMInteractions(),t.forEach(((t,e)=>{try{const n=document.querySelectorAll(t.selector);if(0===n.length)return void t.selector;n.length,t.selector,n.forEach(((n,i)=>{const s=n,r=`dom-interaction-${e}-${i}-${Date.now()}`,a=e=>{this.handleDOMInteraction(e,t)};s.addEventListener(t.action,a),this.domEventListeners.set(r,{element:s,listener:a,type:t.action}),t.action,t.selector}))}catch(n){console.error(`InteractionManager: Error setting up DOM interaction for selector "${t.selector}":`,n)}}))}clearDOMInteractions(){this.domEventListeners.forEach((({element:t,listener:e,type:n})=>{try{t.removeEventListener(n,e)}catch(i){console.error("InteractionManager: Error removing event listener:",i)}})),this.domEventListeners.clear()}async handleButtonClick(t,e){e.id,t.preventDefault(),t.stopPropagation();const n=Pt.getState();switch(e.action.type){case"next":n.play();break;case"goto":e.action.target,n.goToStep(e.action.target);break;case"url":if(e.action.target,await this.flushAnalytics(),"completedWaitingForInteraction"===n.currentState){const t=n.stateMachine.send({type:"COMPLETE_PLAYLIST"});n.currentState=t,await new Promise((t=>setTimeout(t,100)))}else{this.isCurrentStepLast(n)&&(n.goToStep("completed"),await new Promise((t=>setTimeout(t,100))))}window.open(e.action.target,"_blank");const{SaltfishPlayer:t}=await Promise.resolve().then((()=>ae)),s=t.getInstance();s&&s.destroy();break;case"dom":e.action.target;const r=document.querySelector(e.action.target);r?r.click():e.action.target;break;case"function":e.action.target;try{const t=new Function(`return ${e.action.target}`)();"function"==typeof t?t():e.action.target}catch(i){console.error(`InteractionManager: Error calling function "${e.action.target}":`,i)}break;default:e.action.type}if(n.manifest){const t={buttonId:e.id,actionType:e.action.type,actionTarget:e.action.target};JSON.stringify(t)}}handleDOMInteraction(t,e){if(e.action,e.selector,e.waitFor&&(t.preventDefault(),t.stopPropagation(),e.selector),"input"===e.action&&e.value){const n=t.target;n&&(n.value=e.value,e.value)}if(Pt.getState().manifest){const t={selector:e.selector,action:e.action,value:e.value};JSON.stringify(t)}}isCurrentStepLast(t){if(!t.manifest||!t.currentStepId||!t.manifest.steps)return!1;const e=t.manifest.steps;return e.findIndex((e=>e.id===t.currentStepId))===e.length-1}async flushAnalytics(){try{const{SaltfishPlayer:t}=await Promise.resolve().then((()=>ae)),e=t.getInstance();if(e&&e.analyticsManager){const t=e.analyticsManager;"function"==typeof t.flush&&await t.flush()}}catch(t){}}destroy(){this.storeUnsubscribe&&(this.storeUnsubscribe(),this.storeUnsubscribe=null),this.clearButtons(),this.clearDOMInteractions(),this.container=null}}class Bt{constructor(t){e(this,"config",null),e(this,"user",null),e(this,"eventQueue",[]),e(this,"isSending",!1),e(this,"flushInterval",null),e(this,"eventManager",null),e(this,"sessionId",null),e(this,"analyticsEnabled",!0),t&&this.setEventManager(t)}setEventManager(t){this.eventManager=t,this.subscribeToEvents()}subscribeToEvents(){this.eventManager&&(this.eventManager.on("playerPaused",(t=>{const e=this.getStore(),n=this.getRunId();(null==e?void 0:e.manifest)&&e.currentStepId&&n&&this.trackEvent({type:"playerPaused",playlistId:e.manifest.id,stepId:e.currentStepId,runId:n,timestamp:Date.now()})})),this.eventManager.on("playerResumed",(t=>{const e=this.getStore(),n=this.getRunId();(null==e?void 0:e.manifest)&&e.currentStepId&&n&&this.trackEvent({type:"playerResumed",playlistId:e.manifest.id,stepId:e.currentStepId,runId:n,timestamp:Date.now()})})),this.eventManager.on("stepStarted",(t=>{t.step.id,this.trackStepStarted(t.playlist.id,t.step.id)})),this.eventManager.on("stepEnded",(t=>{t.step.id,this.trackStepComplete(t.playlist.id,t.step.id)})),this.eventManager.on("playlistEnded",(t=>{t.playlist.id,this.trackPlaylistComplete(t.playlist.id)})),this.eventManager.on("error",(t=>{t.playlistId&&this.trackError(t.playlistId,t.error,t.stepId,t.errorType)})),this.eventManager.on("playerMinimized",(t=>{const e=this.getStore(),n=this.getRunId();(null==e?void 0:e.manifest)&&e.currentStepId&&n&&this.trackEvent({type:"playerMinimized",playlistId:e.manifest.id,stepId:e.currentStepId,runId:n,timestamp:Date.now()})})),this.eventManager.on("playerMaximized",(t=>{const e=this.getStore(),n=this.getRunId();(null==e?void 0:e.manifest)&&e.currentStepId&&n&&this.trackEvent({type:"playerMaximized",playlistId:e.manifest.id,stepId:e.currentStepId,runId:n,timestamp:Date.now()})})))}getStore(){try{return Pt.getState()}catch(t){return console.error("Failed to access store:",t),null}}initialize(t,e){this.config=t,this.analyticsEnabled=!1!==t.enableAnalytics,e&&(this.sessionId=e),this.analyticsEnabled&&(this.flushInterval=window.setInterval((()=>{this.flushEvents()}),3e4))}setUser(t){this.user=t}trackPlaylistStart(t){if(!this.analyticsEnabled)return;const e=this.getRunId();e&&this.trackEvent({type:"playlistStart",playlistId:t,runId:e,timestamp:Date.now()})}trackPlaylistComplete(t){if(!this.analyticsEnabled)return;const e=this.getRunId();e&&this.trackEvent({type:"playlistComplete",playlistId:t,runId:e,timestamp:Date.now()})}trackStepStarted(t,e){if(!this.analyticsEnabled)return;const n=this.getRunId();n&&this.trackEvent({type:"stepStarted",playlistId:t,stepId:e,runId:n,timestamp:Date.now()})}trackStepComplete(t,e){if(!this.analyticsEnabled)return;const n=this.getRunId();n&&this.trackEvent({type:"stepComplete",playlistId:t,stepId:e,runId:n,timestamp:Date.now()})}trackInteraction(t,e,n){if(!this.analyticsEnabled)return;const i=this.getRunId();i&&this.trackEvent({type:"interaction",playlistId:t,stepId:e,runId:i,timestamp:Date.now(),data:n})}trackError(t,e,n,i){if(!this.analyticsEnabled)return;const s=this.getRunId();s&&this.trackEvent({type:"error",playlistId:t,stepId:n,runId:s,timestamp:Date.now(),data:{message:e.message,stack:e.stack,errorType:i||"unknown"}})}trackEvent(t){this.analyticsEnabled&&(this.eventQueue.push(t),this.eventQueue.length>=10&&this.flushEvents())}async flush(){await this.flushEvents()}async flushEvents(){if(!this.isSending&&0!==this.eventQueue.length&&this.config&&this.analyticsEnabled){this.isSending=!0;try{const t=[...this.eventQueue];this.eventQueue=[];const e={token:this.config.token,sessionId:this.sessionId,user:this.user,events:t},n=await fetch("https://player.saltfish.ai/analytics",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!n.ok)throw this.eventQueue=[...t,...this.eventQueue],new Error(`Failed to send analytics events: ${n.statusText}`)}catch(t){console.error("Failed to send analytics events:",t)}finally{this.isSending=!1}}}destroy(){this.analyticsEnabled&&this.flushEvents(),null!==this.flushInterval&&(clearInterval(this.flushInterval),this.flushInterval=null),this.eventManager&&(this.eventManager=null),this.config=null,this.user=null,this.eventQueue=[],this.sessionId=null,this.analyticsEnabled=!0}getRunId(){try{return re.getInstance().getRunId()}catch(t){return null}}}class Ot{constructor(){e(this,"initialized",!1),e(this,"sessionId",null),e(this,"userId",null),e(this,"clientId",null),e(this,"isRecording",!1)}initialize(t,e,n){this.sessionId=e,this.userId=n||null,this.clientId=t.token,this.clientId,t.sessionRecording&&!this.initialized&&this.loadSaltfishRecordingScript().then((()=>{this.startRecording()})).catch((t=>{}))}loadSaltfishRecordingScript(){return new Promise(((t,e)=>{if("undefined"!=typeof window&&window.saltfishRecording)t();else try{if("undefined"!=typeof window){const n=document.createElement("script");n.type="text/javascript",n.crossOrigin="anonymous",n.async=!0,n.src="https://storage.saltfish.ai/recording/recorder.js",n.onload=()=>{this.initialized=!0,t()},n.onerror=t=>{e(t)},document.head.appendChild(n)}else e(new Error("Window is not defined"))}catch(n){e(n)}}))}startRecording(){if(this.initialized&&this.sessionId&&!this.isRecording&&"undefined"!=typeof window&&window.saltfishRecording){this.sessionId,this.userId,this.clientId;const t={sessionId:this.sessionId,clientId:this.clientId};this.userId&&(t.userId=this.userId),window.saltfishRecording.start(t),this.isRecording=!0}}identifyUser(t){if(this.userId=t.id,this.initialized){if(t.id,this.sessionId,this.isRecording&&"undefined"!=typeof window&&window.saltfishRecording){window.saltfishRecording.stop(),this.isRecording=!1;const t={sessionId:this.sessionId,clientId:this.clientId,userId:this.userId};window.saltfishRecording.start(t),this.isRecording=!0,this.sessionId,this.userId,this.clientId}}else t.id}stopRecording(){this.isRecording&&"undefined"!=typeof window&&window.saltfishRecording&&(window.saltfishRecording.stop(),this.isRecording=!1)}isCurrentlyRecording(){return this.isRecording}}class Ut{constructor(){e(this,"sessionId"),e(this,"currentRunId",null),this.sessionId=this.getOrCreateSession(),this.sessionId}getOrCreateSession(){if("undefined"==typeof window)return this.generateUniqueId();try{const t=localStorage.getItem(tt);if(t){const e=JSON.parse(t);if(Date.now()-e.lastActivity<ct)return e.sessionId,this.updateSessionActivity(e.sessionId),e.sessionId}}catch(e){}const t=this.generateUniqueId();return this.updateSessionActivity(t),t}updateSessionActivity(t){if("undefined"!=typeof window)try{const e={sessionId:t,lastActivity:Date.now()};localStorage.setItem(tt,JSON.stringify(e))}catch(e){}}generateUniqueId(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(t){const e=16*Math.random()|0;return("x"===t?e:3&e|8).toString(16)}))}getSessionId(){return this.updateSessionActivity(this.sessionId),this.sessionId}startNewRun(){return this.currentRunId=this.generateUniqueId(),this.currentRunId,this.updateSessionActivity(this.sessionId),this.currentRunId}getCurrentRunId(){return this.currentRunId}endCurrentRun(){this.currentRunId&&(this.currentRunId,this.currentRunId=null)}expireSession(){"undefined"!=typeof window&&(localStorage.removeItem(tt),this.sessionId),this.sessionId=this.generateUniqueId(),this.updateSessionActivity(this.sessionId),this.currentRunId=null,this.sessionId}destroy(){this.updateSessionActivity(this.sessionId),this.endCurrentRun()}}class Ft{constructor(){e(this,"playbackButtonsVisible",!1),e(this,"rootElement",null),e(this,"playButton",null),e(this,"centerPlayButton",null),e(this,"videoManager",null),e(this,"storeUnsubscribe",null)}initialize(t,e){t?(this.rootElement=t,this.videoManager=e,this.storeUnsubscribe=Pt.subscribe((t=>{this.updatePlayPauseButton(t.currentState)})),this.playButton=t.querySelector(".sf-controls-container__play-button"),this.centerPlayButton=t.querySelector(".sf-player__center-play-button"),this.centerPlayButton||(this.centerPlayButton=document.createElement("button"),this.centerPlayButton.className="sf-player__center-play-button",this.centerPlayButton.innerHTML='\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M8 5v14l11-7z" fill="currentColor"/>\n </svg>\n ',t.appendChild(this.centerPlayButton),this.centerPlayButton.addEventListener("click",(t=>{var e;t.stopPropagation(),t.preventDefault();const n=Pt.getState();if("autoplayBlocked"===n.currentState)if(this.videoManager){this.videoManager.markUserInteraction(),this.videoManager.setMuted(!1);const t=this.videoManager.getVideoElement();t&&(t.loop=!1,t.currentTime=0)}else{const t=null==(e=this.rootElement)?void 0:e.querySelector(".sf-video-container__video");t&&(t.muted=!1,t.loop=!1,t.currentTime=0)}else this.videoManager&&this.videoManager.markUserInteraction();"paused"!==n.currentState&&"waitingForInteraction"!==n.currentState&&"autoplayBlocked"!==n.currentState&&"error"!==n.currentState||n.play()}))),this.playButton||console.error("ButtonManager: Failed to find play button during initialization"),this.centerPlayButton):console.error("ButtonManager: Cannot initialize with null element")}displayPlaybackButtons(t){this.playbackButtonsVisible!==t&&(this.playbackButtonsVisible=t)}updatePlayPauseButton(t){if(this.playButton&&(this.playButton.style.display="none"),!this.centerPlayButton){if(!this.rootElement)return;this.centerPlayButton=this.rootElement.querySelector(".sf-player__center-play-button"),this.centerPlayButton||(this.centerPlayButton=document.createElement("button"),this.centerPlayButton.className="sf-player__center-play-button",this.centerPlayButton.innerHTML='\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M8 5v14l11-7z" fill="currentColor"/>\n </svg>\n ',this.rootElement.appendChild(this.centerPlayButton),this.centerPlayButton.addEventListener("click",(t=>{var e;t.stopPropagation(),t.preventDefault();const n=Pt.getState();if("autoplayBlocked"===n.currentState)if(this.videoManager){this.videoManager.markUserInteraction(),this.videoManager.setMuted(!1);const t=this.videoManager.getVideoElement();t&&(t.loop=!1,t.currentTime=0)}else{const t=null==(e=this.rootElement)?void 0:e.querySelector(".sf-video-container__video");t&&(t.muted=!1,t.loop=!1,t.currentTime=0)}else this.videoManager&&this.videoManager.markUserInteraction();"paused"!==n.currentState&&"waitingForInteraction"!==n.currentState&&"autoplayBlocked"!==n.currentState&&"error"!==n.currentState||n.play()})))}"playing"===t?this.centerPlayButton.style.display="none":(this.centerPlayButton.style.display="flex","autoplayBlocked"===t&&(this.centerPlayButton.style.opacity="1",this.centerPlayButton.style.pointerEvents="auto"))}destroy(){this.storeUnsubscribe&&(this.storeUnsubscribe(),this.storeUnsubscribe=null),this.playbackButtonsVisible=!1,this.rootElement=null,this.playButton=null,this.centerPlayButton=null,this.videoManager=null}}class Rt{constructor(){e(this,"activeTransitions",new Map),e(this,"waitingForInteraction",!1),e(this,"triggerManager",null),e(this,"handleURLChange",(()=>{this.triggerManager&&this.triggerManager.evaluateAllTriggers();const t=Array.from(this.activeTransitions.entries()).filter((([t,e])=>{var n;return"url-path"===(null==(n=e.data)?void 0:n.type)}));if(0!==t.length)for(const[e,n]of t){if(!n.data)continue;const{pattern:t,nextStepId:e}=n.data;if(this.isURLPathMatch(t)){this.triggerTransition(e);break}}})),window.addEventListener("popstate",this.handleURLChange),this.monitorHistoryChanges()}setTriggerManager(t){this.triggerManager=t}monitorHistoryChanges(){const t=history.pushState,e=history.replaceState;history.pushState=(...e)=>{t.apply(history,e),this.handleURLChange()},history.replaceState=(...t)=>{e.apply(history,t),this.handleURLChange()}}setupTransitions(t,e=!1){this.cleanupTransitions(),t.id,t.transitions.forEach((t=>{switch(t.type){case"dom-click":this.setupDOMClickTransition(t);break;case"timeout":this.setupTimeoutTransition(t,e);break;case"url-path":this.setupURLPathTransition(t);break;case"dom-element-visible":this.setupDOMElementVisibleTransition(t);break;default:t.type}}))}setupDOMClickTransition(t){if(!t.target)return;const e=t.target,n=t.nextStep,i=`dom-click-${e}-${Date.now()}`,s=new Map;let r=null;const a=t=>{0!==t.length&&(t.length,t.forEach((t=>{if(s.has(t))return;const e=t=>{this.triggerTransition(n)};s.set(t,e),t.addEventListener("click",e)})))},o=document.querySelectorAll(e);a(o),r=new MutationObserver((t=>{for(const n of t)"childList"===n.type&&n.addedNodes.forEach((t=>{if(t.nodeType===Node.ELEMENT_NODE){const n=t;n.matches(e)&&a([n]);const i=n.querySelectorAll(e);i.length>0&&(i.length,a(i))}}))})),r.observe(document.body,{childList:!0,subtree:!0}),this.activeTransitions.set(i,{handlers:s,cleanup:()=>{s.forEach(((t,e)=>{e.removeEventListener("click",t)})),s.clear(),r&&(r.disconnect(),r=null)},data:{type:"dom-click",pattern:e,nextStepId:n}})}setupTimeoutTransition(t,e){const n=t.nextStep,i=t.timeout||0,s=`timeout-${i}-${Date.now()}`;let r=null;e?this.triggerTransition(n):i>0&&(r=window.setTimeout((()=>{this.triggerTransition(n)}),i)),this.activeTransitions.set(s,{handlers:new Map,cleanup:()=>{null!==r&&(clearTimeout(r),r=null)},data:{type:"timeout",pattern:"",nextStepId:n}})}setupURLPathTransition(t){if(!t.target)return;const e=t.target,n=t.nextStep;if(this.isURLPathMatch(e)){this.triggerTransition(n);const t=5;let e=0;const i=()=>{if(e>=t)return;e++;const s=Pt.getState();"waitingForInteraction"===s.currentState||"playing"===s.currentState?(s.currentState,this.triggerTransition(n)):e<t&&(s.currentState,setTimeout(i,500))};setTimeout(i,500)}const i=`url-path-${Date.now()}`,s=window.setInterval((()=>{this.isURLPathMatch(e)&&(clearInterval(s),this.triggerTransition(n))}),5e3);this.activeTransitions.set(i,{handlers:new Map,cleanup:()=>{clearInterval(s)},data:{type:"url-path",pattern:e,nextStepId:n}})}isURLPathMatch(t){if(!t)return!1;const e=window.location.href.split("#")[0],n=window.location.pathname,i=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/\\\*/g,".*"),s=new RegExp(i),r=s.test(e),a=s.test(n);return r||a}triggerTransition(t){var e;const n=Pt.getState(),i=n.currentState;n.currentStepId;const s=n.isMinimized;"playing"!==i&&"waitingForInteraction"!==i||s||(this.cleanupTransitions(),n.goToStep?n.goToStep(t):null==(e=n.goToStep)||e.call(n,t))}cleanupTransitions(){this.activeTransitions.forEach((t=>{t.cleanup()})),this.activeTransitions.clear(),this.waitingForInteraction=!1}setWaitingForInteraction(t){this.waitingForInteraction=t}isWaitingForInteraction(){return this.waitingForInteraction}destroy(){this.cleanupTransitions(),window.removeEventListener("popstate",this.handleURLChange)}setupDOMElementVisibleTransition(t){if(!t.target)return;const e=t.target,n=t.nextStep,i=`dom-visible-${e}-${Date.now()}`;let s=null,r=null,a=null,o=null;const l=t=>{s||(a=t,s=new IntersectionObserver((t=>{t.forEach((t=>{var e;if(t.isIntersecting,t.intersectionRatio.toFixed(2),t.target.outerHTML.substring(0,100),t.isIntersecting&&t.target===a){const s=window.getComputedStyle(t.target);if(!("0"!==s.opacity&&"none"!==s.display&&"visible"===s.visibility&&"none"!==s.pointerEvents))return;this.triggerTransition(n),null==(e=this.activeTransitions.get(i))||e.cleanup(),this.activeTransitions.delete(i)}else if(t.target===a){const e=t.target.getBoundingClientRect();e.top.toFixed(0),e.left.toFixed(0),e.bottom.toFixed(0),e.right.toFixed(0),e.width.toFixed(0),e.height.toFixed(0)}}))}),{root:null,rootMargin:"0px",threshold:0}),s.observe(t),r&&(r.disconnect(),r=null))},c=document.querySelector(e);c?l(c):(r=new MutationObserver((t=>{for(const n of t)if("childList"===n.type&&n.addedNodes.forEach((t=>{if(t.nodeType===Node.ELEMENT_NODE){const n=t;if(n.matches(e))return void l(n);const i=n.querySelector(e);if(i)return void l(i)}})),!r)break})),r.observe(document.body,{childList:!0,subtree:!0}),o=window.setInterval((()=>{if(!r)return void(o&&clearInterval(o));const t=document.querySelector(e);t&&t.offsetWidth>0&&t.offsetHeight>0&&(o&&clearInterval(o),o=null,l(t))}),1e3)),this.activeTransitions.set(i,{handlers:new Map,cleanup:()=>{s&&(s.disconnect(),s=null),r&&(r.disconnect(),r=null),o&&(clearInterval(o),o=null),a=null},data:{type:"dom-element-visible",pattern:e,nextStepId:n}})}}class Nt{constructor(){e(this,"autoStartPlaylists",[]),e(this,"triggeredPlaylists",new Set),e(this,"isMonitoring",!1)}registerTriggers(t){this.autoStartPlaylists=t.filter((t=>t.autoStart&&t.triggers&&t.isLive)),this.autoStartPlaylists.length,this.autoStartPlaylists.forEach((t=>{var e,n;t.id,null==(e=t.triggers)||e.url,null==(n=t.triggers)||n.once}))}startMonitoring(){this.isMonitoring||(this.isMonitoring=!0,this.evaluateAllTriggers())}stopMonitoring(){this.isMonitoring=!1}evaluateAllTriggers(){if(this.isMonitoring&&0!==this.autoStartPlaylists.length)for(const t of this.autoStartPlaylists)this.evaluatePlaylistTrigger(t)}evaluatePlaylistTrigger(t){var e,n,i;if(!t.triggers)return;const{triggers:s}=t,r=t.id;if(this.triggeredPlaylists.has(r))return;const a=Pt.getState();if(!a.user)return;const o=[],l=this.evaluateOnceCondition(s.once,r,null==(e=a.userData)?void 0:e.watchedPlaylists);o.push(l);const c=this.evaluateURLCondition(s.url);o.push(c),s.url;const d=this.evaluatePlaylistSeenCondition(s.playlistSeen,null==(n=a.userData)?void 0:n.watchedPlaylists);o.push(d),JSON.stringify(s.playlistSeen);const h=this.evaluatePlaylistNotSeenCondition(s.playlistNotSeen,null==(i=a.userData)?void 0:i.watchedPlaylists);o.push(h),JSON.stringify(s.playlistNotSeen);const u=this.applyOperators(o,s.operators);s.operators.join(", "),u&&this.triggerPlaylist(r)}evaluateOnceCondition(t,e,n){if(!t)return!0;return!(n&&n[e])}evaluateURLCondition(t){if(!t)return!0;const e=window.location.href.split("#")[0],n=window.location.pathname,i=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/\\\*/g,".*"),s=new RegExp(i),r=s.test(e),a=s.test(n);return r||a}evaluatePlaylistSeenCondition(t,e){if(!t||0===t.length)return!0;if(!e)return!1;for(const n of t){const t=e[n];if(!t||"completed"!==t.status&&"in_progress"!==t.status)return!1}return!0}evaluatePlaylistNotSeenCondition(t,e){if(!t||0===t.length)return!0;if(!e)return!0;for(const n of t){const t=e[n];if(t&&("completed"===t.status||"in_progress"===t.status))return!1}return!0}applyOperators(t,e){return 0!==t.length&&(1===t.length?t[0]:e&&0!==e.length&&e.includes("OR")?t.some((t=>t)):t.every((t=>t)))}async triggerPlaylist(t){this.triggeredPlaylists.add(t);try{const e=window._saltfishPlayer;e&&"function"==typeof e.startPlaylist&&await e.startPlaylist(t)}catch(e){this.triggeredPlaylists.delete(t)}}resetTriggeredPlaylists(){this.triggeredPlaylists.clear()}getTriggeredPlaylists(){return Array.from(this.triggeredPlaylists)}destroy(){this.stopMonitoring(),this.autoStartPlaylists=[],this.triggeredPlaylists.clear()}}class Yt{constructor(){e(this,"listeners",new Map)}on(t,e){this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(e)}off(t,e){const n=this.listeners.get(t);return!!n&&n.delete(e)}trigger(t,e){const n=this.listeners.get(t);n&&0!==n.size&&("timestamp"in e||(e.timestamp=Date.now()),n.forEach((n=>{try{n(e)}catch(i){console.error(`Error in ${t} event handler:`,i)}})))}removeAllListeners(){this.listeners.clear()}getListenerCount(t){const e=this.listeners.get(t);return e?e.size:0}}class Ht{async loadManifest(t){const{manifestPath:e,playlistOptions:n,savedProgress:i}=t;try{const t=await this.fetchManifest(e);this.validateManifest(t);const s=this.determineStartStep(t,n,i);return t.id,{manifest:t,startStepId:s}}catch(s){const t=s instanceof Error?s.message:"Unknown error";throw yt("[PlaylistLoader] Failed to load manifest:",s),new Error(`Unable to load playlist manifest: ${t}`)}}async fetchManifest(t){const e=t.includes("/")&&t.split("/").pop()||t;if("undefined"!=typeof window&&window.demoManifest)return window.demoManifest;try{const e=await fetch(t);if(e.status,e.statusText,!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);return await e.json()}catch(n){throw yt("[PlaylistLoader] Fetch/parse failed:",n),yt("[PlaylistLoader] Manifest path:",t),yt("[PlaylistLoader] Manifest identifier:",e),new Error(`Failed to fetch manifest from "${t}": ${n instanceof Error?n.message:"Unknown error"}`)}}validateManifest(t){if(!t)throw new Error("Manifest is null or undefined");if("object"!=typeof t)throw new Error("Manifest must be an object");const e=["id","startStep","steps"];for(const n of e)if(!(n in t))throw new Error(`Manifest missing required field: ${n}`);if(!Array.isArray(t.steps))throw new Error("Manifest steps must be an array");if(0===t.steps.length)throw new Error("Manifest must contain at least one step");if(!t.steps.some((e=>e.id===t.startStep)))throw new Error(`Start step '${t.startStep}' not found in steps array`);for(const n of t.steps){if(!n.id)throw new Error("Each step must have an id");if(!n.videoUrl)throw new Error(`Step '${n.id}' must have a videoUrl`);if(!n.transitions||!Array.isArray(n.transitions))throw new Error(`Step '${n.id}' must have transitions array`)}}determineStartStep(t,e,n){var i;const s=e.persistence??!0,r=t.id;let a=t.startStep;if(e.startNodeId){t.steps.find((t=>t.id===e.startNodeId))?(e.startNodeId,a=e.startNodeId):e.startNodeId}else if(s&&n&&(null==(i=n[r])?void 0:i.lastStepId)){const e=n[r],i=e.lastStepId;if(e.completedWaitingForInteraction)a=t.startStep;else{t.steps.find((t=>t.id===i))&&(a=i)}}return a}}class Xt{constructor(t){e(this,"eventManager",null),e(this,"isUpdatingWatchedPlaylists",!1),e(this,"playlistLoader"),this.playlistLoader=new Ht,t&&this.setEventManager(t)}setEventManager(t){this.eventManager=t,this.subscribeToEvents()}subscribeToEvents(){this.eventManager&&(this.eventManager.on("playlistStarted",(t=>{t.playlist.id,this.updateWatchedPlaylistStatus(t.playlist.id,"in_progress")})),this.eventManager.on("playlistEnded",(t=>{t.playlist.id,this.updateWatchedPlaylistStatus(t.playlist.id,"completed").catch((e=>{console.error(`PlaylistManager: Error in updateWatchedPlaylistStatus for playlist ${t.playlist.id}:`,e)}))})),this.eventManager.on("playlistDismissed",(t=>{t.playlist.id,this.updateWatchedPlaylistStatus(t.playlist.id,"dismissed")})),this.eventManager.on("stepStarted",(t=>{t.step.id,this.updateWatchedPlaylistStatus(t.playlist.id,"in_progress",t.step.id)})))}getStore(){try{return Pt.getState()}catch(t){return console.error("Failed to access store:",t),null}}async updateWatchedPlaylistStatus(t,e,n){var i,s,r,a,o,l;if(!this.isUpdatingWatchedPlaylists){this.isUpdatingWatchedPlaylists=!0;try{const d=this.getStore();if(!d)return;const h=d.userData||{},u=h.watchedPlaylists||{},p={status:e,currentStepId:n||d.currentStepId||null,lastProgressAt:Date.now()},g={...u,[t]:p};if(d.setUserData({...h,watchedPlaylists:g}),!(null==(i=null==d?void 0:d.config)?void 0:i.token)||!(null==(s=null==d?void 0:d.user)?void 0:s.id)||(null==(r=null==d?void 0:d.user)?void 0:r.__isAnonymous))return null==(a=null==d?void 0:d.config)||a.token,null==(o=null==d?void 0:d.user)||o.id,null==(l=null==d?void 0:d.user)||l.__isAnonymous,void this.updateAnonymousUserWatchedPlaylists(t,e,n||d.currentStepId||null);const m=`https://player.saltfish.ai/clients/${d.config.token}/users/${d.user.id}/playlists/${t}`;try{const t=await fetch(m,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({status:e,currentStepId:n||d.currentStepId||null})});if(!t.ok)throw new Error(`Failed to update watched playlist status: ${t.statusText} (${t.status})`)}catch(c){console.error(`PlaylistManager: Error updating watched playlist status for ${t}:`,c)}}finally{this.isUpdatingWatchedPlaylists=!1}}}updateAnonymousUserWatchedPlaylists(t,e,n){if("undefined"!=typeof window)try{const s=localStorage.getItem(et);let r={userId:"anonymous",userData:{},watchedPlaylists:{},timestamp:Date.now()};if(s)try{r=JSON.parse(s)}catch(i){}r.watchedPlaylists||(r.watchedPlaylists={}),r.watchedPlaylists[t]={status:e,currentStepId:n||null,lastProgressAt:Date.now()},r.timestamp=Date.now(),localStorage.setItem(et,JSON.stringify(r))}catch(s){console.error("PlaylistManager: Error updating anonymous user watched playlists:",s)}}async load(t,e){try{const n=Pt.getState(),i=await this.playlistLoader.loadManifest({manifestPath:t,playlistOptions:e,savedProgress:n.progress}),{manifest:s,startStepId:r}=i,a=s.steps.find((t=>t.id===r));n.setManifest(s,r),a&&n.stateMachine.send({type:"MANIFEST_LOADED",step:a})}catch(n){const t=Pt.getState(),e=n instanceof Error?n:new Error("Unknown error loading manifest");t.stateMachine.send({type:"ERROR",error:e}),t.setError(e)}}destroy(){this.eventManager&&(this.eventManager=null)}}class $t{constructor(){e(this,"playerElement",null)}create(t){return this.playerElement?(console.warn("PlayerView: Player element already exists, returning existing element"),this.playerElement):(this.playerElement=document.createElement("div"),this.playerElement.className=ht,t.appendChild(this.playerElement),this.playerElement)}createControlsContainer(t){const e=document.createElement("div");return e.className=pt,t.appendChild(e),e}createSaltfishLogo(t){var e;if(!1===(null==(e=Pt.getState().config)?void 0:e.showLogo))return;const n=document.createElement("div");n.className=gt,n.innerHTML='\n <svg width="41" height="15" viewBox="0 0 41 15" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M8.42034 7.49991C8.42034 9.67502 6.65707 11.4383 4.48196 11.4383C2.30685 11.4383 4.00664 9.67502 4.00664 7.49991C4.00664 5.3248 2.30685 3.56152 4.48196 3.56152C6.65707 3.56152 8.42034 5.3248 8.42034 7.49991Z" fill="white"/>\n <path d="M3.53097 7.43198C3.53097 8.96956 2.29707 10.216 0.774969 10.216C-0.747128 10.216 0.442349 8.96956 0.442349 7.43198C0.442349 5.8944 -0.747128 4.64795 0.774969 4.64795C2.29707 4.64795 3.53097 5.8944 3.53097 7.43198Z" fill="white"/>\n <path d="M15.0603 10.628C13.8603 10.628 12.9803 9.892 12.9803 8.372L13.6043 8.292C13.6043 9.492 14.1803 10.044 15.0603 10.044C15.8603 10.044 16.3243 9.612 16.3243 8.972C16.3243 8.252 15.8363 7.988 15.0603 7.788C13.7003 7.436 13.2523 6.996 13.2523 6.196C13.2523 5.396 13.9403 4.772 14.9803 4.772C16.0203 4.772 16.6923 5.396 16.6923 6.436L16.0683 6.516C16.0683 5.796 15.6203 5.356 14.9803 5.356C14.3403 5.356 13.8763 5.636 13.8763 6.196C13.8763 6.756 14.2843 7.004 15.0603 7.204C16.3723 7.548 16.9483 8.012 16.9483 8.972C16.9483 9.932 16.2603 10.628 15.0603 10.628ZM19.182 10.628C18.542 10.628 17.83 10.228 17.83 9.428C17.83 8.548 18.462 8.212 19.494 8.076C19.966 8.012 20.638 7.956 20.414 7.38C20.27 7.004 19.734 6.956 19.494 6.956C18.854 6.956 18.534 7.236 18.534 7.716L17.91 7.636C17.91 6.756 18.774 6.372 19.494 6.372C20.214 6.372 21.022 6.692 21.022 7.652V10.5H20.438V9.7C20.262 10.22 19.798 10.628 19.182 10.628ZM18.454 9.46C18.454 9.78 18.782 10.044 19.182 10.044C19.822 10.044 20.438 9.596 20.438 8.476V8.26C20.286 8.476 19.91 8.596 19.374 8.66C18.742 8.748 18.454 9.06 18.454 9.46ZM22.3044 10.5V4.82H22.9284V10.5H22.3044ZM25.6789 10.5C24.9909 10.5 24.6469 10.204 24.6469 9.508V7.084H23.9669V6.5H24.6469V5.292L25.1909 5.212V6.5H26.2309V7.084H25.1909V9.34C25.1909 9.836 25.3829 9.916 25.7749 9.916H26.2309V10.5H25.6789ZM27.7094 6.052C27.7094 5.116 28.0934 4.82 28.7814 4.82H29.3334V5.404H28.8774C28.4454 5.404 28.2934 5.484 28.2934 6.22V6.5H29.3334V7.084H28.2934V10.5H27.7094V7.084H27.0294V6.5H27.7094V6.052ZM30.2805 10.5V6.5H30.9045V10.5H30.2805ZM30.2165 5.86V5.108H30.9685V5.86H30.2165ZM33.7678 10.628C32.8078 10.628 32.0078 10.06 32.0078 9.02L32.5918 8.94C32.5918 9.66 33.2078 10.044 33.7678 10.044C34.3278 10.044 34.7678 9.86 34.7678 9.38C34.7678 8.9 34.4558 8.772 33.9998 8.708L33.2958 8.612C32.6638 8.524 32.2318 8.092 32.2318 7.532C32.2318 6.812 32.8478 6.372 33.7278 6.372C34.6078 6.372 35.1678 6.892 35.1678 7.612L34.5838 7.692C34.5838 7.212 34.2878 6.956 33.7278 6.956C33.2478 6.956 32.8558 7.132 32.8558 7.532C32.8558 7.852 33.0718 7.996 33.5438 8.068L34.1518 8.156C34.8558 8.26 35.3918 8.66 35.3918 9.38C35.3918 10.1 34.7278 10.628 33.7678 10.628ZM38.9252 7.868C38.9252 7.148 38.5812 6.956 38.1012 6.956C37.6212 6.956 36.9812 7.276 36.9812 8.636V10.5H36.3572V4.9H36.9812V7.364C37.1092 6.812 37.5652 6.372 38.3012 6.372C39.1812 6.372 39.5492 6.988 39.5492 7.868V10.5H38.9252V7.868Z" fill="white"/>\n </svg>\n ',t.appendChild(n),n.addEventListener("click",(t=>{var e;t.stopPropagation();const n=null==(e=Pt.getState().config)?void 0:e.token;n?window.open(`https://www.saltfish.ai/demos?clientId=${n}`,"_blank"):(console.warn("PlayerView: No token available, falling back to saltfish.ai homepage"),window.open("https://www.saltfish.ai/","_blank"))}))}getPlayerElement(){return this.playerElement}destroy(){this.playerElement&&this.playerElement.parentElement&&this.playerElement.parentElement.removeChild(this.playerElement),this.playerElement=null}}class Wt{constructor(){e(this,"playerElement",null),e(this,"playerRoot",null),e(this,"isDragging",!1),e(this,"dragOffset",{x:0,y:0}),e(this,"justFinishedDragging",!1),e(this,"dragStartPosition",{x:0,y:0}),e(this,"hasMoved",!1),e(this,"resizeListener",null),e(this,"onDragStateChange",null)}initialize(t,e,n){this.playerElement=t,this.playerRoot=e,this.onDragStateChange=n||null,this.setupDragHandlers()}setupDragHandlers(){if(!this.playerElement)return;const t=t=>{var e;if(!this.isDragging)return;const n=Math.abs(t.clientX-this.dragStartPosition.x),i=Math.abs(t.clientY-this.dragStartPosition.y);(n>at||i>at)&&(this.hasMoved=!0);const s=Pt.getState();let r=t.clientX-this.dragOffset.x,a=t.clientY-this.dragOffset.y,o=null==(e=s.playlistOptions)?void 0:e.position;if(s.currentStepId&&s.manifest){const t=s.manifest.steps.find((t=>t.id===s.currentStepId));(null==t?void 0:t.position)&&(o=t.position)}const l=xt.calculateDragPosition({x:r,y:a,position:o});this.updatePlayerPosition(l,o||"bottom-right"),t.preventDefault()},e=n=>{var i;if(this.isDragging){const t=Pt.getState();let e=n.clientX-this.dragOffset.x,s=n.clientY-this.dragOffset.y,r=null==(i=t.playlistOptions)?void 0:i.position;if(t.currentStepId&&t.manifest){const e=t.manifest.steps.find((e=>e.id===t.currentStepId));(null==e?void 0:e.position)&&(r=e.position)}const a=xt.calculateDragPosition({x:e,y:s,position:r});t.setPosition(a.x,a.y),this.onDragStateChange&&this.onDragStateChange(),this.hasMoved&&(this.justFinishedDragging=!0,setTimeout((()=>{this.justFinishedDragging=!1}),ot))}this.isDragging=!1,document.removeEventListener("mousemove",t),document.removeEventListener("mouseup",e)};this.playerElement.addEventListener("mousedown",(t=>{var e,n;if(!this.playerElement)return;if("BUTTON"===t.target.tagName)return;this.isDragging=!0,this.justFinishedDragging=!1,this.hasMoved=!1,this.dragStartPosition={x:t.clientX,y:t.clientY};const i=Pt.getState(),s=this.playerElement.getBoundingClientRect();this.dragOffset={x:t.clientX-((null==(e=i.position)?void 0:e.x)||s.left),y:t.clientY-((null==(n=i.position)?void 0:n.y)||s.top)},t.preventDefault()})),this.playerElement.addEventListener("mousedown",(()=>{document.addEventListener("mousemove",t),document.addEventListener("mouseup",e)})),this.resizeListener=()=>{setTimeout((()=>{this.onDragStateChange&&this.onDragStateChange()}),100)},window.addEventListener("resize",this.resizeListener)}updatePlayerPosition(t,e){if(!this.playerRoot)return;const n=xt.getTransforms(e);this.playerRoot.style.left=`${t.x}px`,this.playerRoot.style.top=`${t.y}px`,this.playerRoot.style.transform=`translate(${n.transformX}, ${n.transformY})`}isCurrentlyDragging(){return this.isDragging}hasJustFinishedDragging(){return this.justFinishedDragging}resetDragState(){this.isDragging=!1,this.justFinishedDragging=!1,this.hasMoved=!1}destroy(){this.resizeListener&&(window.removeEventListener("resize",this.resizeListener),this.resizeListener=null),this.resetDragState(),this.playerElement=null,this.playerRoot=null,this.onDragStateChange=null}}class jt{constructor(t){e(this,"button"),e(this,"playerElement"),this.playerElement=t,this.button=document.createElement("button"),this.button.className="sf-player__minimize-button",this.button.innerHTML='\n <svg width="30" height="30" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n ',this.button.addEventListener("click",this.handleClick.bind(this)),this.playerElement.appendChild(this.button),this.updateVisibility(Pt.getState().isMinimized)}handleClick(){const t=Pt.getState(),e=!t.isMinimized;e?(t.minimize(),"playing"===t.currentState&&t.pause()):t.maximize(),e?this.minimize():this.maximize()}minimize(){this.button.innerHTML='\n <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n '}maximize(){this.button.innerHTML='\n <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n '}updateVisibility(t){this.button.style.display=t?"none":""}destroy(){this.button.removeEventListener("click",this.handleClick.bind(this)),this.button.remove()}}class qt{constructor(t,n){e(this,"playButton"),e(this,"container"),e(this,"videoManager",null),this.container=t,this.videoManager=n||null,this.createButton()}createButton(){this.playButton=document.createElement("button"),this.playButton.className="sf-controls-container__play-button",this.playButton.innerHTML='\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M8 5v14l11-7z" fill="currentColor"/>\n </svg>\n ',this.playButton.addEventListener("click",this.handlePlayClick.bind(this)),this.container.appendChild(this.playButton)}handlePlayClick(t){t&&t.stopPropagation();const e=Pt.getState();if("autoplayBlocked"===e.currentState)if(this.videoManager){this.videoManager.markUserInteraction(),this.videoManager.setMuted(!1);const t=this.videoManager.getVideoElement();t&&(t.loop=!1,t.currentTime=0)}else{const t=this.playButton.closest(".sf-player");if(t){const e=t.querySelector(".sf-video-container__video");e&&(e.muted=!1,e.loop=!1,e.currentTime=0)}}else this.videoManager?this.videoManager.markUserInteraction():console.warn("PlayPauseButton: VideoManager not available, falling back to store play");"paused"!==e.currentState&&"waitingForInteraction"!==e.currentState&&"autoplayBlocked"!==e.currentState||e.play()}updateState(t){if("playing"===t)this.playButton.style.display="none";else this.playButton.style.display="flex"}destroy(){this.playButton.removeEventListener("click",this.handlePlayClick.bind(this)),this.playButton.remove()}}class Zt{constructor(t){e(this,"button"),e(this,"playerElement"),this.playerElement=t,this.button=document.createElement("button"),this.button.className="sf-player__exit-button",this.button.innerHTML='\n <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n ',this.button.addEventListener("click",this.handleClick.bind(this)),this.playerElement.appendChild(this.button),this.updateVisibility(Pt.getState().isMinimized)}handleClick(t){t.stopPropagation();const e=Pt.getState();if(e.manifest){re.getInstance().eventManager.trigger("playlistDismissed",{timestamp:Date.now(),playlist:{id:e.manifest.id,title:e.manifest.name}})}re.getInstance().destroy()}updateVisibility(t){this.button.style.display=t?"flex":"none"}destroy(){this.button.removeEventListener("click",this.handleClick.bind(this)),this.button.remove()}}class Jt{constructor(t){e(this,"shadowDOMManager"),e(this,"playerView"),e(this,"dragManager"),e(this,"playerRoot",null),e(this,"playerElement",null),e(this,"minimizeButton",null),e(this,"exitButton",null),e(this,"playPauseButton",null),this.shadowDOMManager=t,this.playerView=new $t,this.dragManager=new Wt}createPlayerUI(t,e,n,i){if(!this.playerRoot&&(this.shadowDOMManager.create(),this.playerRoot=this.shadowDOMManager.getRootElement(),!this.playerRoot))return void console.error("Failed to create player root element");if(this.playerElement)return;this.playerElement=this.playerView.create(this.playerRoot),this.minimizeButton=new jt(this.playerElement),this.exitButton=new Zt(this.playerElement),t.create(this.playerElement);const s=this.playerView.createControlsContainer(this.playerElement);this.playPauseButton=new qt(s,t),this.playerView.createSaltfishLogo(this.playerElement),this.setupVideoContainerClickHandler(),e.create(),n.create(this.playerElement),i.initialize(this.playerElement,t);const r=Pt.getState();this.updateControlsVisibility(r.currentState),this.handleMinimizeStateChange(r.isMinimized),this.dragManager.initialize(this.playerElement,this.playerRoot,(()=>n.updateButtonPositions()))}setupVideoContainerClickHandler(){var t;const e=null==(t=this.playerElement)?void 0:t.querySelector(".sf-video-container");e&&e.addEventListener("click",(t=>{const e=Pt.getState();if(e.isMinimized)return t.stopPropagation(),void this.handleMinimizeClick();if(this.dragManager.hasJustFinishedDragging())return;const n=t.target;"BUTTON"===n.tagName||n.closest("button")||n.closest(".sf-controls-container")||"playing"===e.currentState&&e.pause()}))}updatePosition(){var t;if(!this.playerRoot||!this.playerElement)return void console.warn("UIManager: updatePosition called but playerRoot or playerElement is null",{playerRoot:!!this.playerRoot,playerElement:!!this.playerElement});const e=Pt.getState();if(e.position){let{x:n,y:i}=e.position,s=null==(t=e.playlistOptions)?void 0:t.position;if(e.currentStepId&&e.manifest){const t=e.manifest.steps.find((t=>t.id===e.currentStepId));(null==t?void 0:t.position)&&(s=t.position,xt.shouldForceReposition(s,i,this.dragManager.isCurrentlyDragging())&&(n=nt))}const r=xt.applyConstraints({x:n,y:i,position:s||"bottom-right",viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,playerWidth:Et(e.isMinimized).width}),a=xt.getTransforms(s||"bottom-right");this.playerRoot.style.left=`${r.x}px`,this.playerRoot.style.top=`${r.y}px`,this.playerRoot.style.transform=`translate(${a.transformX}, ${a.transformY})`,e.isMinimized?this.playerElement.classList.add(ut):this.playerElement.classList.remove(ut)}}handleMinimizeClick(){if(!this.playerElement)return;const t=Pt.getState(),e=!t.isMinimized;e?(t.minimize(),"playing"===t.currentState&&t.pause()):t.maximize(),e?this.minimizeButton.minimize():this.minimizeButton.maximize()}handleMinimizeStateChange(t){this.exitButton&&this.exitButton.updateVisibility(t),this.minimizeButton&&this.minimizeButton.updateVisibility(t)}updateControlsVisibility(t){this.playPauseButton&&this.playPauseButton.updateState(t)}getPlayerElement(){return this.playerElement}getPlayerRoot(){return this.playerRoot}isCurrentlyDragging(){return this.dragManager.isCurrentlyDragging()}hasJustFinishedDragging(){return this.dragManager.hasJustFinishedDragging()}resetDragState(){this.dragManager.resetDragState()}destroy(){this.minimizeButton&&(this.minimizeButton.destroy(),this.minimizeButton=null),this.exitButton&&(this.exitButton.destroy(),this.exitButton=null),this.playPauseButton&&(this.playPauseButton.destroy(),this.playPauseButton=null),this.playerView.destroy(),this.dragManager.destroy(),this.shadowDOMManager.remove(),this.playerRoot=null,this.playerElement=null}}function Kt(t,e){let n=null;const i=()=>{n=t.querySelector(".sf-player__minimize-button")};i();let s={currentState:"",isMinimized:!1,currentStepId:null};function r(t,n){var i;if(!e)return;const s=null==(i=null==n?void 0:n.steps)?void 0:i.find((e=>e.id===t));s&&s.cursorAnimations&&s.cursorAnimations.length>0&&e.setShouldShowCursor(!0)}return Pt.subscribe((a=>{var o,l,c,d;n||i(),a.currentState!==s.currentState&&(o=a.currentState,["sf-player--idle","sf-player--loading","sf-player--playing","sf-player--paused","sf-player--waitingForInteraction","sf-player--autoplayBlocked","sf-player--error","sf-player--completed"].forEach((e=>{t.classList.remove(e)})),t.classList.add(`sf-player--${o}`)),a.isMinimized!==s.isMinimized&&(l=a.isMinimized,c=a.currentStepId,d=a.manifest,l?(t.classList.add("sf-player--minimized"),e&&e.setShouldShowCursor(!1)):(t.classList.remove("sf-player--minimized"),r(c,d)),function(t){if(!n)return;n.innerHTML=t?'\n <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n ':'\n <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n '}(a.isMinimized)),a.currentStepId!==s.currentStepId&&(a.isMinimized||r(a.currentStepId,a.manifest)),s={currentState:a.currentState,isMinimized:a.isMinimized,currentStepId:a.currentStepId}}))}function Qt(t){let e=null,n=null,i=null;const s=Pt.subscribe((s=>{var r;const a={previousState:e,currentState:s.currentState,currentStepId:s.currentStepId,isMinimized:s.isMinimized};e===s.currentState&&n===s.isMinimized&&i===s.currentStepId||(null==(r=s.manifest)||r.id,function(t,e,n){const{previousState:i,currentState:s}=t;"playing"===s&&"playing"!==i&&"paused"!==i&&e.manifest&&n.trigger("playlistStarted",{timestamp:Date.now(),playlist:{id:e.manifest.id,title:e.manifest.name}});"paused"===i&&"playing"===s?n.trigger("playerResumed",{timestamp:Date.now(),previousState:i,currentState:s}):"playing"===i&&"paused"===s?n.trigger("playerPaused",{timestamp:Date.now(),previousState:i,currentState:s}):("completed"===s&&"completed"!==i||"completedWaitingForInteraction"===s&&"completedWaitingForInteraction"!==i)&&e.manifest&&(e.manifest.id,n.trigger("playlistEnded",{timestamp:Date.now(),playlist:{id:e.manifest.id,title:e.manifest.name}}))}(a,s,t),function(t,e,n,i){const{previousState:s,currentState:r,isMinimized:a}=t,o=i||!1;!a&&o?n.trigger("playerMaximized",{timestamp:Date.now(),previousState:s,currentState:r}):a&&!o&&n.trigger("playerMinimized",{timestamp:Date.now(),previousState:s,currentState:r})}(a,0,t,n),function(t,e,n,i){var s,r,a;const{currentStepId:o,currentState:l,previousState:c}=t,d=e.currentStepId?((null==(s=e.manifest)?void 0:s.steps)||[]).find((t=>t.id===e.currentStepId)):null;null==d||d.id,null==(r=e.manifest)||r.id,e.manifest;const h=i&&e.manifest&&(i!==o||"waitingForInteraction"===l||"autoplayBlocked"===l||"completed"===l);if(e.manifest,h){const t=((null==(a=e.manifest)?void 0:a.steps)||[]).find((t=>t.id===i));null==t||t.id,t&&(t.id,n.trigger("stepEnded",{timestamp:Date.now(),step:{id:t.id,title:t.title||t.id},playlist:{id:e.manifest.id,title:e.manifest.name}}))}const u=o!==i&&"playing"===l,p=("paused"===c||"autoplayBlocked"===c)&&"playing"===l&&i===o,g=d&&e.manifest&&(u||p);null==d||d.id,e.manifest,g&&(d.id,n.trigger("stepStarted",{timestamp:Date.now(),step:{id:d.id,title:d.title||d.id},playlist:{id:e.manifest.id,title:e.manifest.name}}))}(a,s,t,i),function(t,e,n){var i;const{currentState:s,previousState:r}=t;"error"===s&&"error"!==r&&e.error&&n.trigger("error",{timestamp:Date.now(),playlistId:null==(i=e.manifest)?void 0:i.id,stepId:e.currentStepId,error:e.error,errorType:"state"})}(a,s,t),e=s.currentState,n=s.isMinimized,i=s.currentStepId)}));return s}class Gt{static handle(t,e={},n={}){var i;const s={...this.DEFAULT_OPTIONS,...n},r=this.normalizeError(t,e);if(s.shouldLog&&this.logError(r,e,s.severity),s.shouldUpdateStore&&this.updateStore(r),s.shouldTriggerEvent&&this.triggerErrorEvent(r,e,null==(i=e.component)?void 0:i.toLowerCase()),s.shouldDestroy&&this.destroyPlayer(),s.shouldThrow)throw r;return r}static handleInitializationError(t,e={}){return this.handle(t,{...e,component:"Initialization"},{severity:"critical",shouldLog:!0,shouldUpdateStore:!0,shouldDestroy:!0,shouldThrow:!0})}static handlePlaylistError(t,e={}){return this.handle(t,{...e,component:"Playlist"},{severity:"error",shouldLog:!0,shouldUpdateStore:!0,shouldTriggerEvent:!0})}static handleVideoError(t,e={}){return this.handle(t,{...e,component:"Video"},{severity:"error",shouldLog:!0,shouldUpdateStore:!0,shouldTriggerEvent:!0})}static handleNetworkError(t,e={}){return this.handle(t,{...e,component:"Network"},{severity:"warning",shouldLog:!0,shouldTriggerEvent:!0})}static handleWarning(t,e={}){return this.handle(t,e,{severity:"warning",shouldLog:!0,shouldThrow:!1})}static handleCleanupError(t,e={}){return this.handle(t,{...e,component:"Cleanup"},{severity:"warning",shouldLog:!0,shouldThrow:!1})}static normalizeError(t,e){if(t instanceof Error)return t;if("string"==typeof t)return new Error(t);const n=String(t&&"object"==typeof t&&"message"in t?t.message:t);return new Error(`Unknown error in ${e.component||"application"}: ${n}`)}static formatErrorMessage(t,e){const n=[];return e.component&&n.push(`[${e.component}]`),e.method&&n.push(`${e.method}:`),n.push(t.message),n.join(" ")}static logError(t,e,n){const i=this.formatErrorMessage(t,e),s={error:{name:t.name,message:t.message,stack:t.stack},context:e,severity:n,timestamp:(new Date).toISOString()};switch(n){case"info":break;case"warning":console.warn(i,s);break;case"error":case"critical":console.error(i,s)}}static updateStore(t){try{Pt.getState().setError(t)}catch(e){console.error("Failed to update store with error:",e)}}static triggerErrorEvent(t,e,n){var i,s;try{const r=Pt.getState();if("undefined"!=typeof window&&window._saltfishPlayer){const a=window._saltfishPlayer;a&&a.eventManager&&a.eventManager.trigger("error",{timestamp:Date.now(),playlistId:e.playlistId||(null==(i=r.manifest)?void 0:i.id),stepId:e.stepId||r.currentStepId,error:t,errorType:e.errorType||n||(null==(s=e.component)?void 0:s.toLowerCase())||"unknown"})}}catch(r){console.error("Failed to trigger error event:",r)}}static destroyPlayer(){try{if("undefined"!=typeof window&&window._saltfishPlayer){const t=window._saltfishPlayer;t&&"function"==typeof t.destroy&&t.destroy()}}catch(t){console.error("Failed to destroy player during error handling:",t)}}static createError(t,e={}){const n=new Error(this.formatErrorMessage(new Error(t),e));return e.component&&(n.component=e.component),e.method&&(n.method=e.method),e.playlistId&&(n.playlistId=e.playlistId),e.stepId&&(n.stepId=e.stepId),n}static isRecoverable(t){if(t.message.includes("fetch")||t.message.includes("network")||t.message.includes("timeout"))return!0;return[/autoplay.*blocked/i,/video.*failed.*load/i,/manifest.*not.*found/i].some((e=>e.test(t.message)))}static async safeExecute(t,e={},n={}){try{return await t()}catch(i){return this.handle(i,e,n),null}}}e(Gt,"DEFAULT_OPTIONS",{severity:"error",shouldLog:!0,shouldThrow:!1,shouldUpdateStore:!1,shouldTriggerEvent:!1,shouldDestroy:!1});const te=class t{constructor(t){e(this,"currentStepId",null),e(this,"stepTimeoutId",null),e(this,"destroyCallback",null),this.destroyCallback=t}update(t){const{currentStepId:e,currentState:n}=t;this.currentStepId;if(!("playing"===n||"waitingForInteraction"===n||"paused"===n||"autoplayBlocked"===n))return this.stepTimeoutId,void this.clearStepTimeout();const i=e!==this.currentStepId,s=null===this.stepTimeoutId;(i||s)&&(i&&this.currentStepId,this.setStepTimeout(e))}setStepTimeout(e){this.clearStepTimeout(),e&&(this.currentStepId=e,this.stepTimeoutId=window.setTimeout((()=>{this.destroyPlayer()}),t.STEP_TIMEOUT_MS))}clearStepTimeout(){null!==this.stepTimeoutId&&(this.currentStepId,window.clearTimeout(this.stepTimeoutId),this.stepTimeoutId=null)}destroyPlayer(){if(this.destroyCallback)try{this.destroyCallback()}catch(t){}}reset(){this.clearStepTimeout(),this.currentStepId=null}destroy(){this.clearStepTimeout(),this.currentStepId=null,this.destroyCallback=null}};e(te,"STEP_TIMEOUT_MS",lt);let ee=te;function ne(t){if(!t)return;if("auto"===t){return function(){try{const t=navigator.language||navigator.userLanguage;if(!t)return;return t.split("-")[0].toLowerCase()}catch(t){return}}()}return t.split("-")[0].toLowerCase()}class ie{async validatePlaylistStart(t){const{playlistId:e,options:n,eventManager:i}=t;try{const t=Pt.getState();if(!t.config)return{isValid:!1,error:"Saltfish Player must be initialized before starting a playlist"};const s=t.backendPlaylists;if(!s||0===s.length)return Gt.handlePlaylistError("No playlist list available from backend validation",{component:"PlaylistValidator",method:"validatePlaylistStart",playlistId:e,errorType:"playlist_backend_unavailable"}),{isValid:!1,error:"No backend playlists available"};const r=s.find((t=>t.id===e));if(!r)return Gt.handlePlaylistError(`Playlist ID '${e}' not found in the list provided by backend validation`,{component:"PlaylistValidator",method:"validatePlaylistStart",playlistId:e,errorType:"playlist_not_found",additionalData:{backendPlaylists:s}}),{isValid:!1,error:"Playlist not found in backend list"};if(!r.isLive)return Gt.handlePlaylistError(`Cannot start playlist '${e}' - playlist is not currently live`,{playlistId:e,additionalData:{isLive:r.isLive,triggers:r.triggers}}),{isValid:!1,error:"Playlist is not live"};if(null==r?void 0:r.autoStart){const t=await this.validateAutoStartConditions(e,r,i);if(!t.isValid)return t}let a=n;if(null==n?void 0:n.once){const t=await this.validateOnceOptionConditions(e,n,i);if(!t.isValid)return t;a=t.updatedOptions||n}const o=await this.validateDeviceCompatibility(r,e);return o.isValid?{isValid:!0,manifestPath:r.path,updatedOptions:a}:o}catch(s){const t=s instanceof Error?s.message:"Unknown validation error";return Gt.handlePlaylistError(`Playlist validation failed: ${t}`,{component:"PlaylistValidator",method:"validatePlaylistStart",playlistId:e,additionalData:{error:s}}),{isValid:!1,error:t}}}async validateAutoStartConditions(t,e,n){var i,s;const r=Pt.getState();if(!r.user)return Gt.handlePlaylistError("User must be identified before starting auto-start playlist",{component:"PlaylistValidator",method:"validateAutoStartConditions",playlistId:t,errorType:"playlist_user_required"}),{isValid:!1,error:"User identification required for autoStart playlist"};r.userData||await this.waitForUserData(n);const a=(null==(i=Pt.getState().userData)?void 0:i.watchedPlaylists)||{};return(null==(s=e.triggers)?void 0:s.once)&&a[t]?(mt(`Playlist ${t} has autoStart enabled with once:true and has already been watched. Skipping playlist start.`,{watchedPlaylists:a,triggers:e.triggers}),{isValid:!1,error:"Playlist already watched with once=true policy"}):{isValid:!0}}async validateOnceOptionConditions(t,e,n){var i;const s=Pt.getState();if(!s.user)return Gt.handlePlaylistError("User must be identified before starting playlist with once option",{component:"PlaylistValidator",method:"validateOnceOptionConditions",playlistId:t,errorType:"playlist_auth_required"}),{isValid:!1,error:"User identification required for once option"};s.userData||await this.waitForUserData(n);const r=(null==(i=Pt.getState().userData)?void 0:i.watchedPlaylists)||{},a=r[t];if(a&&("completed"===a.status||"dismissed"===a.status))return mt(`Playlist ${t} has once option enabled and has already been ${a.status}. Skipping playlist start.`,{watchedPlaylists:r,playlistStatus:a.status}),{isValid:!1,error:`Playlist already ${a.status} with once option`};if(a&&"in_progress"===a.status&&!(null==e?void 0:e.startNodeId)&&a.currentStepId){return{isValid:!0,updatedOptions:{...e,startNodeId:a.currentStepId}}}return{isValid:!0}}async validateDeviceCompatibility(t,e){try{const n=t.deviceType||"both",{isDeviceCompatible:i}=await Promise.resolve().then((()=>Tt));return i(n)?{isValid:!0}:(Gt.handlePlaylistError(`Playlist '${e}' is not compatible with this device. Required: ${n}`,{component:"PlaylistValidator",method:"validateDeviceCompatibility",playlistId:e,errorType:"playlist_device_incompatible",additionalData:{requiredDeviceType:n,manifestPath:t.path}}),{isValid:!1,error:`Device incompatible. Required: ${n}`})}catch(n){const i=n instanceof Error?n.message:"Unknown error";return Gt.handlePlaylistError(`Device compatibility check failed: ${i}`,{component:"PlaylistValidator",method:"validateDeviceCompatibility",playlistId:e,additionalData:{error:n,manifestPath:t.path}}),{isValid:!1,error:`Device compatibility check failed: ${i}`}}}async waitForUserData(t){return new Promise(((e,n)=>{const i=setTimeout((()=>{t.off("userDataLoaded",s),n(new Error("Timeout waiting for user data"))}),5e3),s=()=>{clearTimeout(i),Pt.getState(),e()};t.on("userDataLoaded",s)}))}}const se=class t{constructor(){if(e(this,"shadowDOMManager"),e(this,"videoManager"),e(this,"cursorManager"),e(this,"interactionManager"),e(this,"analyticsManager"),e(this,"sessionRecordingManager"),e(this,"sessionManager"),e(this,"buttonManager"),e(this,"transitionManager"),e(this,"triggerManager"),e(this,"eventManager"),e(this,"playlistManager"),e(this,"stepTimeoutManager"),e(this,"uiManager"),e(this,"playerView"),e(this,"dragManager"),e(this,"uiUpdaterUnsubscribe",null),e(this,"eventUpdaterUnsubscribe",null),e(this,"isInitialized",!1),e(this,"lastConfig",null),e(this,"lastUserIdentification",null),e(this,"handleStoreChanges",(()=>{if(!this.isInitialized)return;const e=Pt.getState();e.currentState===t.prevState.currentState&&e.currentStepId===t.prevState.currentStepId&&e.isMinimized===t.prevState.isMinimized||(t.prevState.currentState,e.currentState,t.prevState.currentStepId,e.currentStepId,t.prevState.isMinimized,e.isMinimized,this.uiManager.getPlayerRoot()&&this.uiManager.getPlayerElement()&&this.uiManager.updatePosition(),this.updateControlsVisibility(e.currentState),"autoplayBlocked"===e.currentState?this.buttonManager.updatePlayPauseButton("autoplayBlocked"):"completed"===e.currentState&&this.handleCompletedState(),e.isMinimized!==t.prevState.isMinimized&&this.uiManager.handleMinimizeStateChange(e.isMinimized),t.prevState={currentState:e.currentState,currentStepId:e.currentStepId,isMinimized:e.isMinimized})})),t.instance)throw new Error("SaltfishPlayer is a singleton. Use getInstance()");this.sessionManager=new Ut,this.shadowDOMManager=new n,this.videoManager=new Dt,this.eventManager=new Yt,this.analyticsManager=new Bt(this.eventManager),this.sessionRecordingManager=new Ot,this.playlistManager=new Xt(this.eventManager),this.cursorManager=new Vt,this.interactionManager=new Lt,this.buttonManager=new Ft,this.transitionManager=new Rt,this.triggerManager=new Nt,this.stepTimeoutManager=new ee((()=>this.destroy())),this.playerView=new $t,this.dragManager=new Wt,this.transitionManager.setTriggerManager(this.triggerManager),this.uiManager=new Jt(this.shadowDOMManager),Pt.subscribe(this.handleStoreChanges.bind(this)),this.registerStateMachineActions()}static getInstance(){return t.instance||(t.instance=new t),t.instance}getSessionId(){return this.sessionManager.getSessionId()}getRunId(){return this.sessionManager.getCurrentRunId()}async initialize(t){var e,n,i;if(this.isInitialized)console.warn("Saltfish playlist Player is already initialized");else try{const s=await fetch(`${dt}/validate-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:t.token})}),r=await s.json();if(!r.isValid)throw Gt.handleInitializationError(r.error||"Token validation failed",{component:"SaltfishPlayer",method:"initialize",additionalData:{token:(null==(e=t.token)?void 0:e.substring(0,10))+"..."}});const a=ne(t.language),o={...t,language:a,showLogo:!1!==r.showLogo};this.lastConfig=o;const l=Pt.getState();l.initialize(o);const c=(null==(n=l.user)?void 0:n.id)||(null==(i=this.lastUserIdentification)?void 0:i.userId);if(this.analyticsManager.initialize(t,this.sessionManager.getSessionId()),this.sessionRecordingManager.initialize(t,this.sessionManager.getSessionId(),c),!(r.playlists&&Array.isArray(r.playlists)&&l.setBackendPlaylists))throw Gt.handleInitializationError("Backend validation successful, but no playlists array provided in the response. Cannot initialize player.",{component:"SaltfishPlayer",method:"initialize",additionalData:{responseData:r}});r.playlists,l.setBackendPlaylists(r.playlists),this.triggerManager.registerTriggers(r.playlists),this.isInitialized=!0,window._saltfishPlayer=this,window._cursorManager=this.cursorManager,this.eventManager.trigger("initialized",{timestamp:Date.now()})}catch(s){throw Gt.handleInitializationError(s,{component:"SaltfishPlayer",method:"initialize"})}}identifyUser(t,e){this.lastUserIdentification={userId:t,userData:e};Pt.getState().identifyUser(t,e),this.analyticsManager.setUser({id:t,...e}),this.sessionRecordingManager.identifyUser({id:t,...e}),this.fetchUserData(t,e)}identifyAnonymous(t){const e=this.getOrCreateAnonymousUserId();this.lastUserIdentification={userId:e,userData:t};Pt.getState().identifyUser(e,{...t,__isAnonymous:!0}),this.analyticsManager.setUser({id:e,...t}),this.sessionRecordingManager.identifyUser({id:e,...t}),this.loadAnonymousUserData(e,t)}async fetchUserData(t,e){var n;try{const i=Pt.getState();if(!(null==(n=i.config)?void 0:n.token))return void Gt.handleWarning("Cannot fetch user data: Token not available",{component:"SaltfishPlayer",method:"fetchUserData",userId:t});const s=await fetch(`https://player.saltfish.ai/clients/${i.config.token}/users/${t}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userData:e})});if(!s.ok){await s.text();return s.status,void s.statusText}const r=await s.json();r.success&&(i.setUserData({watchedPlaylists:r.watchedPlaylists||{}}),this.eventManager.trigger("userDataLoaded",{timestamp:Date.now(),userId:t,userData:{watchedPlaylists:r.watchedPlaylists||{}}}),this.triggerManager.startMonitoring())}catch(i){Gt.handleNetworkError(i,{component:"SaltfishPlayer",method:"fetchUserData",userId:t})}}loadAnonymousUserData(t,e){try{if("undefined"==typeof window)return;const i=localStorage.getItem(et);let s={userId:t,userData:e||{},watchedPlaylists:{},timestamp:Date.now()};if(i)try{const n=JSON.parse(i);s={userId:t,userData:{...n.userData,...e},watchedPlaylists:n.watchedPlaylists||{},timestamp:Date.now()}}catch(n){}localStorage.setItem(et,JSON.stringify(s));Pt.getState().setUserData({watchedPlaylists:s.watchedPlaylists||{}}),this.eventManager.trigger("userDataLoaded",{timestamp:Date.now(),userId:t,userData:{watchedPlaylists:s.watchedPlaylists||{}}}),this.triggerManager.startMonitoring()}catch(i){Gt.handleNetworkError(i,{component:"SaltfishPlayer",method:"loadAnonymousUserData",userId:t})}}getOrCreateAnonymousUserId(){if("undefined"==typeof window)return`anonymous_${Date.now()}_${Math.random().toString(36).substring(2,11)}`;const t="saltfish_anonymous_user_id";try{let e=localStorage.getItem(t);return e||(e=`anonymous_${Date.now()}_${Math.random().toString(36).substring(2,11)}`,localStorage.setItem(t,e)),e}catch(e){return console.warn("SaltfishPlayer: localStorage not available, using session-only anonymous ID"),`anonymous_session_${Date.now()}_${Math.random().toString(36).substring(2,11)}`}}async startPlaylist(t,e){try{const s=this.isInitialized&&!this.uiManager.getPlayerElement();if(!this.isInitialized&&this.lastConfig)try{await this.initialize(this.lastConfig),this.lastUserIdentification&&this.identifyUser(this.lastUserIdentification.userId,this.lastUserIdentification.userData),this.videoManager.reset(),this.cursorManager.reset(),this.interactionManager=new Lt,this.buttonManager=new Ft,this.transitionManager=new Rt,this.playerView=new $t,this.dragManager=new Wt,this.uiManager=new Jt(this.shadowDOMManager),this.registerStateMachineActions()}catch(n){throw Gt.handleInitializationError(`Failed to reinitialize player: ${n instanceof Error?n.message:"Unknown error"}`,{component:"SaltfishPlayer",method:"startPlaylist",playlistId:t,additionalData:{reinitError:n}})}s&&(this.videoManager.reset(),this.cursorManager.reset(),this.interactionManager=new Lt,this.buttonManager=new Ft,this.transitionManager=new Rt,this.playerView=new $t,this.dragManager=new Wt,this.uiManager=new Jt(this.shadowDOMManager),this.stepTimeoutManager=new ee((()=>this.cleanupPlaylist())),this.transitionManager.setTriggerManager(this.triggerManager),this.registerStateMachineActions());const r=Pt.getState();if(!r.config){if(!this.lastConfig)throw Gt.createError("Saltfish Player must be initialized at least once before starting a playlist",{component:"SaltfishPlayer",method:"startPlaylist",playlistId:t});throw Gt.createError("Saltfish Player must be initialized before starting a playlist",{component:"SaltfishPlayer",method:"startPlaylist",playlistId:t})}r.manifest&&("playing"===r.currentState||"paused"===r.currentState||"loading"===r.currentState||"waitingForInteraction"===r.currentState||"autoplayBlocked"===r.currentState||"minimized"===r.currentState)&&(this.cleanupCurrentPlaylist(),r.resetForNewPlaylist(),this.registerStateMachineActions()),"completed"===r.currentState&&this.registerStateMachineActions();this.sessionManager.startNewRun();const a=new ie,o=await a.validatePlaylistStart({playlistId:t,options:e,eventManager:this.eventManager});if(!o.isValid)return;e=o.updatedOptions||e;const l=o.manifestPath,c=e||{};c?(r.setPlaylistOptions(c),c.position||r.setPlaylistOptions({...c,position:"bottom-right"}),this.uiManager.updatePosition()):(r.setPlaylistOptions({position:"bottom-right",allowDrag:!0}),this.uiManager.updatePosition());const d=(null==e?void 0:e.persistence)??!0;if(d&&"undefined"!=typeof window){const e=localStorage.getItem("saltfish_progress");if(e)try{const n=JSON.parse(e);n[t]&&r.loadPlaylistProgress(t,n[t])}catch(i){console.warn("Failed to parse saved progress for playlist:",t)}}this.analyticsManager.trackPlaylistStart(t),this.cursorManager.resetFirstAnimation(),this.uiManager.createPlayerUI(this.videoManager,this.cursorManager,this.interactionManager,this.buttonManager),this.setupUpdaters(),await this.playlistManager.load(l,{...c,persistence:d});const h=Pt.getState();if(c.startNodeId&&h.manifest){h.manifest.steps.find((t=>t.id===c.startNodeId))?h.goToStep(c.startNodeId):console.warn(`[SaltfishPlayer] startNodeId '${c.startNodeId}' not found in manifest steps. Starting from default step.`)}else h.manifest;h.manifest&&(h.manifest.cursorColor&&this.cursorManager.setColor(h.manifest.cursorColor),this.eventManager.trigger("playlistStarted",{timestamp:Date.now(),playlist:{id:t,title:h.manifest.name}})),r.play(),mt(`Playlist started: ${t}${h.manifest?` (${h.manifest.name})`:""}`)}catch(s){Gt.handlePlaylistError(s,{component:"SaltfishPlayer",method:"startPlaylist",playlistId:t,errorType:"playlist_load_failed"})}}registerStateMachineActions(){const t=Pt.getState();t.stateMachine.registerActions({startVideoPlayback:e=>{if(!e.currentStep)return;const n=this.getVideoUrl(e.currentStep);try{this.videoManager.showProgressBar(),this.videoManager.showMuteButton(),this.interactionManager.clearButtons(),this.interactionManager.clearDOMInteractions(),e.currentStep.domInteractions&&this.interactionManager.setupDOMInteractions(e.currentStep.domInteractions),e.currentStep.buttons&&this.interactionManager.createButtons(e.currentStep.buttons),e.currentStep.id,e.currentStep.cursorAnimations&&e.currentStep.cursorAnimations.length,e.currentStep.cursorAnimations&&e.currentStep.cursorAnimations.length>0?(e.currentStep.id,this.cursorManager.setShouldShowCursor(!0),e.currentStep.id,e.currentStep.cursorAnimations[0].targetSelector,this.cursorManager.animate(e.currentStep.cursorAnimations[0])):(e.currentStep.id,this.cursorManager.setShouldShowCursor(!1));const i=e.currentStep.buttons&&e.currentStep.buttons.length>0||e.currentStep.transitions.some((t=>"dom-click"===t.type||"url-path"===t.type)),s=i?"manual":"auto";i&&this.transitionManager.setupTransitions(e.currentStep,!1),this.videoManager.setCompletionPolicy(s,(()=>{e.currentStep&&(i||this.transitionManager.setupTransitions(e.currentStep,!0),t.stateMachine.send({type:"VIDEO_ENDED",step:e.currentStep}))})),this.videoManager.loadVideo(n).then((()=>{var t;if(e.currentStep){const n=null==(t=Pt.getState().config)?void 0:t.language;let i=e.currentStep.transcript;if(n&&e.currentStep.translations&&e.currentStep.translations[n]){const t=e.currentStep.translations[n].transcript;t&&(i=t,e.currentStep.id)}i?(e.currentStep.id,this.videoManager.loadTranscript(i)):(e.currentStep.id,this.videoManager.loadTranscript(null))}else this.videoManager.loadTranscript(null);if(this.videoManager.play(),e.currentStep){const t=this.findNextVideoUrl(e.currentStep);t&&this.videoManager.preloadNextVideo(t)}})).catch((n=>{var i,s;this.eventManager.trigger("error",{timestamp:Date.now(),playlistId:(null==(i=t.manifest)?void 0:i.id)||void 0,stepId:null==(s=e.currentStep)?void 0:s.id,error:n instanceof Error?n:new Error(`Failed to load video: ${n}`),errorType:"video"})}))}catch(i){}},pauseVideoPlayback:()=>{this.videoManager.pause()},startMutedLoopedVideo:()=>{const t=this.videoManager.getVideoElement();t&&(t.muted=!0,t.loop=!0,t.play().catch((()=>{}))),this.videoManager.hideProgressBar(),this.videoManager.hideMuteButton()},trackPlaylistComplete:()=>{this.handleCompletedState()},handleError:e=>{var n,i;if(null==(n=e.error)||n.message,e.error&&this.uiManager.getPlayerElement()){const n=document.createElement("div");n.className="saltfish-error",n.textContent=`Error: ${e.error.message}`;const s=this.uiManager.getPlayerElement();s&&(s.innerHTML="",s.appendChild(n)),this.eventManager.trigger("error",{timestamp:Date.now(),playlistId:(null==(i=t.manifest)?void 0:i.id)||void 0,stepId:t.currentStepId||void 0,error:e.error,errorType:"player"})}}})}findNextVideoUrl(t){const e=Pt.getState();if(!e.manifest||!t)return null;if(t.transitions.length>0){const n=t.transitions[0];if("url-path"===n.type||"dom-click"===n.type)return null;const i=n.nextStep,s=e.manifest.steps.find((t=>t.id===i));if(s)return this.getVideoUrl(s)}const n=e.manifest.steps.findIndex((e=>e.id===t.id));return n>=0&&n<e.manifest.steps.length-1?this.getVideoUrl(e.manifest.steps[n+1]):null}getVideoUrl(t){var e;const n=null==(e=Pt.getState().config)?void 0:e.language;if(n&&t.translations&&t.translations[n]){return t.translations[n].videoUrl}return t.compressedVideoUrl||t.videoUrl}setupUpdaters(){this.uiUpdaterUnsubscribe&&this.uiUpdaterUnsubscribe(),this.eventUpdaterUnsubscribe&&this.eventUpdaterUnsubscribe();const t=this.uiManager.getPlayerElement();t&&(this.uiUpdaterUnsubscribe=Kt(t,this.cursorManager)),this.eventUpdaterUnsubscribe=Qt(this.eventManager);const e=Pt.subscribe((t=>{this.stepTimeoutManager.update({currentState:t.currentState,currentStepId:t.currentStepId,isMinimized:t.isMinimized,previousState:void 0})})),n=this.eventUpdaterUnsubscribe;this.eventUpdaterUnsubscribe=()=>{n&&n(),e()}}destroy(){var t;if(this.isInitialized)try{const e=Pt.getState();e.currentState,e.currentStepId,e.isMinimized,null==(t=e.manifest)||t.id,this.uiUpdaterUnsubscribe&&(this.uiUpdaterUnsubscribe(),this.uiUpdaterUnsubscribe=null),this.eventUpdaterUnsubscribe&&(this.eventUpdaterUnsubscribe(),this.eventUpdaterUnsubscribe=null),this.transitionManager.destroy(),this.triggerManager.destroy(),this.videoManager.destroy(),this.cursorManager.destroy(),this.interactionManager.destroy(),this.buttonManager.destroy(),this.analyticsManager.destroy(),this.sessionManager.destroy(),this.playlistManager.destroy(),this.stepTimeoutManager.destroy(),this.playerView.destroy(),this.dragManager.destroy(),this.uiManager.destroy(),this.isInitialized=!1,e.reset()}catch(e){Gt.handleCleanupError(e,{component:"SaltfishPlayer",method:"destroy"});try{this.isInitialized=!1;Pt.getState().reset()}catch(n){Gt.handleCleanupError(n,{component:"SaltfishPlayer",method:"destroy",additionalData:{originalError:e}})}}else console.warn("Saltfish playlist Player is not initialized")}handleCompletedState(){null!==t.destroyTimeoutId&&(t.destroyTimeoutId,window.clearTimeout(t.destroyTimeoutId),t.destroyTimeoutId=null);const e=Pt.getState();e.manifest&&this.eventManager.trigger("playlistEnded",{timestamp:Date.now(),playlist:{id:e.manifest.id,title:e.manifest.name}}),this.cleanupPlaylist()}on(t,e){this.eventManager.on(t,e)}off(t,e){return this.eventManager.off(t,e)}resetPlaylist(){const t=Pt.getState();t.manifest&&t.goToStep(t.manifest.startStep)}cleanupCurrentPlaylist(){try{this.stepTimeoutManager&&this.stepTimeoutManager.reset(),this.videoManager&&this.videoManager.pause(),this.cursorManager&&(this.cursorManager.stopAnimation(),this.cursorManager.setShouldShowCursor(!1)),this.transitionManager&&this.transitionManager.cleanupTransitions(),this.interactionManager&&(this.interactionManager.clearButtons(),this.interactionManager.clearDOMInteractions()),this.uiManager.resetDragState()}catch(t){Gt.handleCleanupError(t,{component:"SaltfishPlayer",method:"cleanupCurrentPlaylist"})}}cleanupPlaylist(){var t;if(this.isInitialized)try{const e=Pt.getState();e.currentState,e.currentStepId,e.isMinimized,null==(t=e.manifest)||t.id,this.uiUpdaterUnsubscribe&&(this.uiUpdaterUnsubscribe(),this.uiUpdaterUnsubscribe=null),this.eventUpdaterUnsubscribe&&(this.eventUpdaterUnsubscribe(),this.eventUpdaterUnsubscribe=null),this.transitionManager.destroy(),this.videoManager.destroy(),this.cursorManager.destroy(),this.interactionManager.destroy(),this.buttonManager.destroy(),this.playlistManager.destroy(),this.stepTimeoutManager.destroy(),this.playerView.destroy(),this.dragManager.destroy(),this.uiManager.destroy(),e.resetForNewPlaylist()}catch(e){Gt.handleCleanupError(e,{component:"SaltfishPlayer",method:"cleanupPlaylist"})}else console.warn("Saltfish playlist Player is not initialized")}updateControlsVisibility(t){this.uiManager.updateControlsVisibility(t)}};e(se,"instance",null),e(se,"prevState",{currentState:null,currentStepId:null,isMinimized:!1}),e(se,"destroyTimeoutId",null);let re=se;const ae=Object.freeze(Object.defineProperty({__proto__:null,SaltfishPlayer:re},Symbol.toStringTag,{value:"Module"})),oe={id:"default_mock_playlist",name:"Default playlist Demo",version:"1.0.0",position:"bottom-right",startStep:"intro",steps:[{id:"intro",videoUrl:"https://storage.saltfish.ai/videos/QSWY4Wc8pcBVYHNQM12P.mp4",transitions:[{type:"timeout",timeout:0,nextStep:"dashboard_overview"},{type:"dom-element-visible",target:"body",nextStep:"dashboard_overview"}]},{id:"dashboard_overview",videoUrl:"https://storage.saltfish.ai/videos/rEWoNbKLAUQSvLmzHGmv.mp4",position:"bottom-left",domInteractions:[{selector:"#feature-chart",action:"hover",waitFor:!1}],buttons:[{id:"skip_button",text:"Skip",action:{type:"goto",target:"user_settings"}}],transitions:[]},{id:"user_settings",videoUrl:"https://storage.saltfish.ai/codeformer/oNcN4ZoQXFFnMmaOwEC3/result.mp4",position:"top-right",buttons:[{id:"finish_button",text:"Finish Tour",action:{type:"goto",target:"conclusion"}},{id:"finish_two",text:"Finish Tour",action:{type:"goto",target:"conclusion"}}],transitions:[{type:"dom-click",target:"div:nth-of-type(3) > h2",nextStep:"conclusion"}],cursorAnimations:[{easing:"ease-out",targetSelector:"div:nth-of-type(3) > h2"}]},{id:"conclusion",videoUrl:"https://storage.saltfish.ai/memo/5z5IDHYzuGDjx41hpvSo/result.mp4",transitions:[]}],cursorColor:"#ff7614"},le={id:"second_mock_playlist",name:"Second Playlist Demo",version:"1.0.0",position:"bottom-right",startStep:"step1",steps:[{id:"step1",videoUrl:"https://storage.saltfish.ai/videos/7e07f378-3059-4694-8659-8a4c1f04442d.mp4",transcript:{text:"Welcome to this demo video. We will show you how to use the transcript feature.",segments:[{text:"Welcome to this demo video.",start:0,end:2.5},{text:"We will show you how to use the transcript feature.",start:2.5,end:5}]},transitions:[{type:"dom-element-visible",target:"#root > div > main > div.PreviewPage_footer__Ynnux > button",nextStep:"step2"}]},{id:"step2",videoUrl:"https://storage.saltfish.ai/videos/799b36f2-fc36-4864-8b6d-f8bf3d578140.mp4",position:"bottom-left",transitions:[{type:"dom-click",target:"#root > div > main > div.PreviewPage_footer__Ynnux > button",nextStep:"step3"}]},{id:"step3",videoUrl:"https://storage.saltfish.ai/videos/edb65857-e7c1-4edd-a4fc-67cf35880ac4.mp4",buttons:[{id:"continue_button",text:"Continue to Step 4",action:{type:"goto",target:"step4"}},{id:"skip_to_end",text:"Skip to End",action:{type:"goto",target:"step9"}}],transitions:[{type:"timeout",timeout:0,nextStep:"step4"}]},{id:"step4",videoUrl:"https://storage.saltfish.ai/videos/f25d8c5d-f7b6-48b1-ac39-4aae5124100a.mp4",position:"center",cursorAnimations:[{easing:"ease-out",targetSelector:"#audience-chat-messages-panel-0 > div > div > div._container_1juas_1.MessageInput_container__KdCLm > div > button"}],transitions:[{type:"dom-element-visible",target:"#audience-chat-messages-panel-0 > div > div > div._container_vk4n0_1 > div.str-chat__virtual-list > div > div > div:nth-child(2) > div > div > div",nextStep:"step5"}]},{id:"step5",videoUrl:"https://storage.saltfish.ai/videos/e89abe5e-b83f-4ba5-8286-ee6e307bcf43.mp4",cursorAnimations:[{easing:"ease-out",targetSelector:"#audience-chat-messages-panel-0 > div > div > div._container_vk4n0_1 > div.str-chat__virtual-list > div > div > div:nth-child(2) > div > div > div > div._container_4oo5p_1 > div:nth-child(2) > button"}],transitions:[{type:"dom-click",target:"#root > div > main > div.PreviewPage_footer__Ynnux > button",nextStep:"step6"}]},{id:"step6",videoUrl:"https://storage.saltfish.ai/videos/0ec59567-e865-4f9b-9ecd-7e4c5f2638a4.mp4",transitions:[{type:"timeout",timeout:0,nextStep:"step7"}]},{id:"step7",videoUrl:"https://storage.saltfish.ai/videos/38593171-53ac-426b-a6a8-0a3182c5947d.mp4",position:"top-left",cursorAnimations:[{easing:"ease-out",targetSelector:"#root > div > main > section > div.SideButtons_container__jqcKh > div:nth-child(1)"}],transitions:[{type:"dom-click",target:"#root > div > main > section > div.SideButtons_container__jqcKh > div:nth-child(1)",nextStep:"step3"}]},{id:"step8",videoUrl:"https://storage.saltfish.ai/videos/91441f25-2ffa-46dc-92fd-711be8512d27.mp4",transitions:[{type:"timeout",timeout:0,nextStep:"step9"}]},{id:"step9",videoUrl:"https://storage.saltfish.ai/videos/ecf26de5-c94c-4bef-b88c-6773420e01f4.mp4",transitions:[]}],cursorColor:"#ff7614"};function ce(t,e=!1){const n=e?oe:le;return{...n,...t,steps:t.steps||n.steps}}const de=function(){const t=re.getInstance();let e=!1,n=!1,i=null;const s=[],r={init:r=>{if(n)return mt("Saltfish already initialized"),Promise.resolve();if(e&&i)return i;const a={sessionRecording:!1,enableAnalytics:!0,..."string"==typeof r?{token:r}:r};return mt(`Saltfish initialized: analytics=${a.enableAnalytics}, language=${a.language||"default"}`),e=!0,i=t.initialize(a).then((()=>(n=!0,e=!1,(async()=>{if(0!==s.length)for(;s.length>0;){const e=s.shift();if(e)try{await e()}catch(t){yt("Error executing queued command:",t)}}})()))).catch((t=>{throw e=!1,t("Saltfish initialization failed:",t),t})),i},identify:(i,r)=>{n||!e?t.identifyUser(i,r):s.push((async()=>{t.identifyUser(i,r)}))},identifyAnonymous:i=>{n||!e?t.identifyAnonymous(i):s.push((async()=>{t.identifyAnonymous(i)}))},startPlaylist:(r,a)=>!n&&e?new Promise(((e,n)=>{s.push((async()=>{try{await t.startPlaylist(r,a),e()}catch(i){n(i)}})),i&&i.catch(n)})):t.startPlaylist(r,a),on:(e,n)=>{t.on(e,n)},off:(e,n)=>t.off(e,n),resetPlaylist:()=>{n||e?n||!e?t.resetPlaylist():s.push((async()=>{t.resetPlaylist()})):ft("Cannot reset playlist - Saltfish not initialized")},destroy:()=>{n||e?(e||(n=!1,e=!1,i=null,s.length=0),t.destroy(),n=!1,e=!1,i=null):ft("Cannot destroy - Saltfish not initialized")},getSessionId:()=>t.getSessionId(),getRunId:()=>t.getRunId()};return r.__dev__={setMockManifest:t=>{"undefined"!=typeof window&&(window.demoManifest=t)},createMockManifest:ce,defaultMockManifest:le,getDeviceInfo:()=>Ct.getDeviceInfo()},r}();return"undefined"!=typeof window&&(window.saltfish=de),de}));
8
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).SaltfishplaylistPlayer=e()}(this,(function(){"use strict";var t=Object.defineProperty,e=(e,n,i)=>((e,n,i)=>n in e?t(e,n,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[n]=i)(e,"symbol"!=typeof n?n+"":n,i);class n{constructor(){e(this,"container",null),e(this,"shadowRoot",null),e(this,"styleElement",null)}create(){if(this.container)return;this.container=document.createElement("div"),this.container.id="saltfish-container",document.body.appendChild(this.container),this.shadowRoot=this.container.attachShadow({mode:"open"}),this.styleElement=document.createElement("style"),this.styleElement.textContent=this.getBaseStyles(),this.shadowRoot.appendChild(this.styleElement);const t=document.createElement("div");t.id="sf-player-root",this.shadowRoot.appendChild(t)}getShadowRoot(){return this.shadowRoot}getRootElement(){if(!this.shadowRoot)return null;return this.shadowRoot.getElementById("sf-player-root")}addStyles(t){this.styleElement&&(this.styleElement.textContent+=t)}remove(){this.container&&(document.body.removeChild(this.container),this.container=null,this.shadowRoot=null,this.styleElement=null)}getBaseStyles(){return"\n /* \n * CSS Reset for the Saltfish playlist Player\n * Minimal reset for the Shadow DOM to ensure consistent rendering\n */\n\n:host {\n all: initial;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;\n box-sizing: border-box;\n}\n\n:host *,\n:host *::before,\n:host *::after {\n box-sizing: inherit;\n margin: 0;\n padding: 0;\n}\n\nbutton {\n background: none;\n border: none;\n cursor: pointer;\n font: inherit;\n outline: none;\n padding: 0;\n} \n /* \n * Variables for the Saltfish playlist Player\n * Defines all design tokens used throughout the application\n */\n\n:host {\n /* Colors */\n --sf-primary-color: #4a9bff;\n --sf-secondary-color: #6ccfff;\n --sf-background-color: #1e1e1e;\n --sf-text-color: #ffffff;\n --sf-button-bg: rgba(0, 0, 0, 0.5);\n --sf-button-hover-bg: rgba(0, 0, 0, 0.7);\n --sf-overlay-gradient: linear-gradient(180deg, rgba(0, 0, 0, 0.7) 0%, transparent 30%, transparent 70%, rgba(0, 0, 0, 0.7) 100%);\n --sf-progress-gradient: linear-gradient(90deg, var(--sf-primary-color), var(--sf-secondary-color));\n --sf-error-color: #ff4d4d;\n --sf-error-bg: rgba(255, 77, 77, 0.1);\n \n /* Spacing */\n --sf-spacing-xs: 4px;\n --sf-spacing-sm: 8px;\n --sf-spacing-md: 12px;\n --sf-spacing-lg: 16px;\n --sf-spacing-xl: 24px;\n \n /* Sizes */\n --sf-player-width: 240px;\n --sf-player-height: 336px;\n --sf-player-min-width: 80px;\n --sf-player-min-height: 80px;\n --sf-control-button-size: 24px;\n --sf-play-button-size: 60px;\n --sf-minimize-button-size: 20px;\n --sf-mute-button-size: 32px;\n --sf-cc-button-size: 32px;\n --sf-cursor-size: 32px;\n \n /* Border radius */\n --sf-border-radius-sm: 4px;\n --sf-border-radius-md: 8px;\n --sf-border-radius-lg: 16px;\n --sf-border-radius-circle: 50%;\n \n /* Transitions */\n --sf-transition-fast: 0.1s ease;\n --sf-transition-normal: 0.2s ease;\n --sf-transition-slow: 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);\n \n /* Shadows */\n --sf-shadow-small: 0 2px 5px rgba(0, 0, 0, 0.2);\n --sf-shadow-medium: 0 4px 8px rgba(0, 0, 0, 0.15);\n --sf-shadow-large: 0 10px 25px rgba(0, 0, 0, 0.2);\n \n /* Z-index layering */\n --sf-z-index-base: 1;\n --sf-z-index-overlay: 2;\n --sf-z-index-controls: 10;\n --sf-z-index-cursor: 9999;\n --sf-z-index-player: 2147483648;\n \n /* Font sizes */\n --sf-font-size-sm: 14px;\n --sf-font-size-md: 16px;\n --sf-font-size-lg: 18px;\n --sf-font-size-xl: 24px;\n} \n\n/* Mobile device responsive adjustments - make player smaller for mobile screens */\n@media (max-width: 768px) {\n :host {\n /* Reduce player size on mobile for better space utilization */\n --sf-player-width: 180px; /* 25% smaller than desktop (240px -> 180px) */\n --sf-player-height: 252px; /* 25% smaller than desktop (336px -> 252px) */\n --sf-player-min-width: 60px; /* Smaller when minimized (80px -> 60px) */\n --sf-player-min-height: 60px; /* Smaller when minimized (80px -> 60px) */\n \n /* Keep controls touch-friendly despite smaller player size */\n --sf-play-button-size: 44px; /* Smaller but still touch-friendly (60px -> 44px) */\n --sf-control-button-size: 28px; /* Keep larger for touch targets (24px -> 28px) */\n --sf-mute-button-size: 26px; /* Smaller for mobile (32px -> 26px) */\n --sf-cc-button-size: 26px; /* Smaller for mobile (32px -> 26px) */\n --sf-minimize-button-size: 24px; /* Keep larger for touch interaction */\n }\n}\n\n/* Touch device specific adjustments (tablets and larger touch devices, excluding mobile) */\n@media (pointer: coarse) and (min-width: 769px) {\n :host {\n /* Ensure touch-friendly sizes even on larger touch devices */\n --sf-control-button-size: 28px;\n --sf-mute-button-size: 38px;\n --sf-cc-button-size: 38px;\n --sf-minimize-button-size: 24px; /* Larger touch target for minimize button */\n }\n} \n \n /* \n * Player component styles for the Saltfish playlist Player\n * Following BEM naming convention\n */\n\n/* Main player container */\n.sf-player {\n border-radius: var(--sf-border-radius-lg);\n box-shadow: 0 25px 50px rgba(0, 0, 0, 0.45), 0 10px 20px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(255, 255, 255, 0.08);\n transition: all var(--sf-transition-slow);\n position: relative;\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n}\n\n/* Dark gradient overlay at bottom of player */\n.sf-player::before {\n content: '';\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 33.33%; /* One third of player height */\n background: linear-gradient(to top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0) 100%);\n pointer-events: none;\n z-index: var(--sf-z-index-overlay);\n border-radius: 8px;\n}\n\n/* Hide gradient overlay when minimized */\n.sf-player--minimized::before {\n display: none;\n}\n\n/* Full-size player state */\n.sf-player:not(.sf-player--minimized) {\n width: var(--sf-player-width);\n height: var(--sf-player-height);\n}\n\n/* Autoplay fallback state - ensure play button is visible */\n.sf-player--waiting-for-user-interaction .sf-controls-container__play-button {\n display: flex !important;\n opacity: 1 !important;\n visibility: visible !important;\n}\n\n/* Also show the center play button in autoplay fallback state */\n.sf-player--waiting-for-user-interaction .sf-player__center-play-button {\n display: flex !important;\n opacity: 1 !important;\n z-index: calc(var(--sf-z-index-controls) + 20) !important; /* Higher z-index to appear above overlay */\n}\n\n/* Make the autoplay fallback state more prominent to indicate need for interaction */\n.sf-player--waiting-for-user-interaction::after {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n pointer-events: none;\n z-index: var(--sf-z-index-overlay);\n}\n\n/* Player state: minimized */\n.sf-player--minimized {\n /* Equal width and height are essential for maintaining a perfect circle when using border-radius: 50% */\n width: var(--sf-player-min-width);\n height: var(--sf-player-min-height);\n border-radius: var(--sf-border-radius-circle);\n box-shadow: 0 15px 30px rgba(0, 0, 0, 0.35), 0 5px 15px rgba(0, 0, 0, 0.25), 0 0 0 2px rgba(255, 255, 255, 0.08);\n cursor: pointer;\n /* Force overriding any inline styles that might be applied */\n max-width: var(--sf-player-min-width) !important;\n max-height: var(--sf-player-min-height) !important;\n min-width: var(--sf-player-min-width) !important;\n min-height: var(--sf-player-min-height) !important;\n}\n\n/* Hide controls when minimized */\n.sf-player--minimized .sf-controls-container {\n display: none;\n}\n\n/* Only show the minimize button when hovering on minimized player */\n.sf-player--minimized .sf-player__minimize-button {\n opacity: 0;\n}\n\n.sf-player--minimized:hover .sf-player__minimize-button {\n opacity: 1;\n}\n\n/* Player root element */\n#sf-player-root {\n position: fixed;\n z-index: var(--sf-z-index-player);\n}\n\n/* Player error message */\n.sf-player__error {\n padding: var(--sf-spacing-md);\n color: var(--sf-error-color);\n background-color: var(--sf-error-bg);\n border-radius: var(--sf-border-radius-md);\n margin: var(--sf-spacing-sm);\n font-size: var(--sf-font-size-sm);\n border-left: 4px solid var(--sf-error-color);\n}\n\n/* Minimize button */\n.sf-player__minimize-button {\n position: absolute;\n top: calc(var(--sf-spacing-xs) + var(--sf-spacing-md));\n right: var(--sf-spacing-md);\n width: var(--sf-minimize-button-size);\n height: var(--sf-minimize-button-size);\n background-color: transparent;\n border-radius: var(--sf-border-radius-circle);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n z-index: var(--sf-z-index-controls);\n color: white;\n border: none;\n font-size: calc(var(--sf-font-size-sm) + 4px);\n transition: all var(--sf-transition-normal);\n text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);\n opacity: 0;\n}\n\n/* Minimize button hover state */\n.sf-player__minimize-button:hover {\n transform: scale(1.1);\n}\n\n/* Show minimize button on player hover */\n.sf-player:hover .sf-player__minimize-button {\n opacity: 1;\n}\n\n/* Mobile and touch device overrides for minimize button visibility */\n/* Ensure minimize button is always visible on touch devices, even when minimized */\n@media (pointer: coarse) {\n .sf-player__minimize-button {\n opacity: 1 !important;\n z-index: calc(var(--sf-z-index-controls) + 50) !important; /* Much higher z-index for touch devices */\n }\n \n .sf-player--minimized .sf-player__minimize-button {\n opacity: 1 !important;\n z-index: calc(var(--sf-z-index-controls) + 50) !important; /* Much higher z-index for touch devices */\n }\n}\n\n/* Ensure minimize button is always visible on mobile screens under 768px */\n@media (max-width: 768px) {\n .sf-player__minimize-button {\n opacity: 1 !important;\n z-index: calc(var(--sf-z-index-controls) + 50) !important; /* Much higher z-index for mobile */\n /* Position closer to top right corner on mobile */\n top: var(--sf-spacing-xs) !important; /* 4px from top instead of 16px */\n right: var(--sf-spacing-xs) !important; /* 4px from right instead of 12px */\n }\n \n .sf-player--minimized .sf-player__minimize-button {\n opacity: 1 !important;\n z-index: calc(var(--sf-z-index-controls) + 50) !important; /* Much higher z-index for mobile */\n /* Position closer to top right corner on mobile */\n top: var(--sf-spacing-xs) !important; /* 4px from top instead of 16px */\n right: var(--sf-spacing-xs) !important; /* 4px from right instead of 12px */\n }\n}\n\n/* Player title */\n.sf-player__title {\n position: absolute;\n top: var(--sf-spacing-md);\n left: var(--sf-spacing-md);\n color: var(--sf-text-color);\n font-size: var(--sf-font-size-md);\n font-weight: 600;\n z-index: var(--sf-z-index-controls);\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);\n max-width: 70%;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Centered play/pause button overlay */\n.sf-player__center-play-button {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: var(--sf-play-button-size);\n height: var(--sf-play-button-size);\n background-color: rgba(0, 0, 0, 0.5);\n border-radius: var(--sf-border-radius-circle);\n display: none; /* Hidden by default */\n justify-content: center;\n align-items: center;\n z-index: calc(var(--sf-z-index-controls) + 10); /* Ensure higher z-index than other elements */\n color: white;\n border: none;\n font-size: var(--sf-control-button-size);\n cursor: pointer;\n transition: transform var(--sf-transition-normal), background-color var(--sf-transition-normal);\n backdrop-filter: blur(3px);\n -webkit-backdrop-filter: blur(3px);\n box-shadow: 0 15px 30px rgba(0, 0, 0, 0.5), 0 5px 15px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(255, 255, 255, 0.08);\n pointer-events: auto; /* Enable pointer events to capture clicks */\n}\n\n/* Center play button hover state */\n.sf-player__center-play-button:hover {\n transform: translate(-50%, -50%) scale(1.1);\n background-color: rgba(0, 0, 0, 0.7);\n}\n\n/* Hide center play button in minimized state */\n.sf-player--minimized .sf-player__center-play-button {\n display: none !important;\n}\n\n/* Exit button for minimized mode */\n.sf-player__exit-button {\n position: absolute;\n top: -22px; /* Position it above the player */\n right: 0;\n width: 20px;\n height: 20px;\n background-color: var(--sf-button-bg);\n border-radius: var(--sf-border-radius-circle);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n z-index: var(--sf-z-index-controls);\n color: white;\n border: none;\n font-size: var(--sf-font-size-md);\n transition: all var(--sf-transition-normal);\n text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.35);\n}\n\n/* Exit button hover state */\n.sf-player__exit-button:hover {\n transform: scale(1.1);\n background-color: var(--sf-button-hover-bg);\n}\n\n/* Show exit button on minimized player hover */\n.sf-player--minimized:hover .sf-player__exit-button {\n opacity: 1;\n}\n\n/* Saltfish logo */\n.sf-player__logo {\n position: absolute;\n bottom: var(--sf-spacing-xs);\n left: 50%;\n transform: translateX(-50%);\n width: 41px;\n height: 15px;\n z-index: var(--sf-z-index-controls);\n opacity: 0.7;\n transition: opacity var(--sf-transition-normal);\n cursor: pointer;\n}\n\n/* Logo hover state */\n.sf-player:hover .sf-player__logo {\n opacity: 0.9;\n}\n\n/* Hide logo when minimized */\n.sf-player--minimized .sf-player__logo {\n display: none;\n} \n /* \n * Video component styles for the Saltfish playlist Player\n * Following BEM naming convention\n */\n\n/* Video container */\n.sf-video-container {\n position: relative;\n width: 100%;\n height: 100%;\n border-radius: var(--sf-border-radius-md);\n overflow: hidden;\n pointer-events: auto; /* Ensure clicks on video container are captured */\n}\n\n/* Video element */\n.sf-video-container__video {\n width: 100%;\n height: 100%;\n object-fit: cover;\n /* Ensure video is visible on mobile */\n display: block;\n background-color: black;\n /* Add explicit positioning to ensure video is visible */\n position: relative;\n z-index: 1;\n}\n\n\n\n/* Mobile-specific video styles */\n@media (max-width: 768px) {\n \n .sf-video-container__video {\n /* Force video dimensions on mobile */\n width: 100% !important;\n height: 100% !important;\n object-fit: cover !important;\n /* Prevent video from being hidden */\n opacity: 1 !important;\n visibility: visible !important;\n /* Ensure video is above any potential overlays */\n z-index: 10 !important;\n position: relative !important;\n /* Ensure minimum dimensions */\n min-width: 100px !important;\n min-height: 100px !important;\n }\n \n /* Make controls more touch-friendly on mobile */\n .sf-video-container__controls {\n height: 5px; /* Thicker on mobile for easier touch */\n }\n \n .sf-video-container__mute-button {\n /* Use CSS variable for consistent sizing */\n min-width: var(--sf-mute-button-size) !important;\n min-height: var(--sf-mute-button-size) !important;\n opacity: 1; /* Always visible on mobile (no hover) */\n }\n \n .sf-video-container__cc-button {\n /* Use CSS variable for consistent sizing */\n min-width: var(--sf-cc-button-size) !important;\n min-height: var(--sf-cc-button-size) !important;\n opacity: 1; /* Always visible on mobile (no hover) */\n }\n}\n\n/* Touch device specific styles */\n@media (pointer: coarse) {\n .sf-video-container__controls:hover {\n height: 5px; /* Keep consistent height on touch devices */\n }\n \n .sf-video-container__mute-button {\n opacity: 1; /* Always show on touch devices */\n }\n \n .sf-video-container__cc-button {\n opacity: 1; /* Always show on touch devices */\n }\n \n .sf-video-container:hover .sf-video-container__mute-button {\n opacity: 1;\n }\n}\n\n/* Video in minimized state */\n.sf-player--minimized .sf-video-container {\n border-radius: var(--sf-border-radius-circle);\n cursor: pointer;\n z-index: var(--sf-z-index-base);\n width: 100%;\n height: 100%;\n}\n\n.sf-player--minimized .sf-video-container__video {\n border-radius: var(--sf-border-radius-circle);\n object-fit: cover;\n width: 100%;\n height: 100%;\n}\n\n/* Hide progress bar in minimized state */\n.sf-player--minimized .sf-video-container__controls {\n display: none !important;\n}\n\n/* Also hide mute button in minimized state */\n.sf-player--minimized .sf-video-container__mute-button {\n display: none !important;\n}\n\n/* Also hide CC button in minimized state */\n.sf-player--minimized .sf-video-container__cc-button {\n display: none !important;\n}\n\n/* Progress bar container */\n.sf-video-container__controls {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 3px;\n background-color: rgba(255, 255, 255, 0.25);\n z-index: var(--sf-z-index-controls);\n border-radius: var(--sf-border-radius-md) var(--sf-border-radius-md) 0 0;\n cursor: pointer;\n}\n\n/* Show slightly thicker progress bar on hover for better UX */\n.sf-video-container__controls:hover {\n height: 5px;\n}\n\n/* Progress indicator */\n.sf-video-container__progress {\n height: 100%;\n background: rgba(255, 255, 255, 0.8);\n width: 0%;\n transition: width 0.1s linear;\n border-radius: var(--sf-border-radius-md) 0 0 0;\n cursor: pointer;\n transform-origin: left;\n}\n\n/* Mute button */\n.sf-video-container__mute-button {\n position: absolute;\n top: calc(var(--sf-spacing-xl) + var(--sf-spacing-xl));\n right: var(--sf-spacing-xs);\n width: var(--sf-mute-button-size);\n height: var(--sf-mute-button-size);\n background-color: transparent;\n border-radius: var(--sf-border-radius-circle);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n z-index: var(--sf-z-index-controls);\n color: white;\n border: none;\n font-size: calc(var(--sf-font-size-md) + 2px);\n transition: all var(--sf-transition-normal);\n text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);\n opacity: 0;\n}\n\n/* Mute button hover state */\n.sf-video-container__mute-button:hover {\n transform: scale(1.1);\n}\n\n/* Show mute button on container hover */\n.sf-video-container:hover .sf-video-container__mute-button {\n opacity: 1;\n}\n\n/* CC button */\n.sf-video-container__cc-button {\n position: absolute;\n top: calc(var(--sf-spacing-xl) + var(--sf-spacing-xl) + var(--sf-mute-button-size) + var(--sf-spacing-xs));\n right: var(--sf-spacing-xs);\n width: var(--sf-cc-button-size);\n height: var(--sf-cc-button-size);\n background-color: transparent;\n border-radius: 50%; /* Ensure perfect circle */\n padding: 0; /* Remove default button padding */\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n z-index: var(--sf-z-index-controls);\n color: white;\n border: none;\n font-size: calc(var(--sf-font-size-md) + 2px);\n transition: all var(--sf-transition-normal);\n text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);\n opacity: 0;\n}\n\n.sf-video-container__cc-button svg {\n display: block;\n margin: auto;\n width: 60%;\n height: 60%;\n}\n\n/* CC button hover state */\n.sf-video-container__cc-button:hover {\n transform: scale(1.1);\n}\n\n/* Hide mute and cc buttons in autoplayBlocked state */\n.sf-player--autoplayBlocked .sf-video-container__mute-button,\n.sf-player--autoplayBlocked .sf-video-container__cc-button {\n display: none !important;\n}\n\n/* Show mute and cc buttons on hover in playing/paused states */\n.sf-player--playing .sf-video-container:hover .sf-video-container__mute-button,\n.sf-player--playing .sf-video-container:hover .sf-video-container__cc-button,\n.sf-player--paused .sf-video-container:hover .sf-video-container__mute-button,\n.sf-player--paused .sf-video-container:hover .sf-video-container__cc-button {\n opacity: 1;\n} \n /* \n * Controls component styles for the Saltfish playlist Player\n * Following BEM naming convention\n */\n\n/* Main controls container */\n.sf-controls-container {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n justify-content: center;\n align-items: center;\n background-color: transparent;\n z-index: var(--sf-z-index-controls);\n pointer-events: auto;\n}\n\n/* Play button */\n.sf-controls-container__play-button {\n background-color: rgba(0, 0, 0, 0.6);\n border: none;\n color: var(--sf-text-color);\n font-size: var(--sf-control-button-size);\n cursor: pointer;\n width: var(--sf-play-button-size);\n height: var(--sf-play-button-size);\n border-radius: var(--sf-border-radius-circle);\n display: flex;\n justify-content: center;\n align-items: center;\n transition: transform var(--sf-transition-normal), background-color var(--sf-transition-normal);\n padding-left: 4px; /* Optical centering for play icon */\n}\n\n/* Button hover state */\n.sf-controls-container__play-button:hover {\n background-color: rgba(0, 0, 0, 0.4);\n transform: scale(1.1);\n}\n\n/* Button container for interactive buttons */\n.sf-controls-container__buttons {\n display: flex;\n justify-content: center;\n align-items: center;\n gap: var(--sf-spacing-md);\n}\n\n/* Interactive button */\n.sf-controls-container__interactive-button {\n background-color: rgba(255, 255, 255, 0.2);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n color: white;\n border: none;\n border-radius: var(--sf-border-radius-md);\n padding: var(--sf-spacing-xs) var(--sf-spacing-md);\n font-size: var(--sf-font-size-sm);\n cursor: pointer;\n transition: background-color var(--sf-transition-normal), transform var(--sf-transition-fast);\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);\n}\n\n.sf-controls-container__interactive-button:hover {\n background-color: rgba(255, 255, 255, 0.3);\n transform: translateY(-2px);\n}\n\n/* \n * Choice buttons container and buttons - positioned inside player\n */\n\n/* Choice buttons container - positioned inside the player at the bottom */\n.sf-choice-buttons-container {\n position: absolute;\n bottom: var(--sf-spacing-xl);\n left: 50%;\n transform: translateX(-50%);\n width: calc(100% - var(--sf-spacing-lg));\n max-width: calc(100% - var(--sf-spacing-lg));\n z-index: calc(var(--sf-z-index-controls) + 1);\n display: flex;\n flex-direction: column;\n gap: var(--sf-spacing-sm);\n pointer-events: auto;\n justify-content: flex-end;\n align-items: center;\n}\n\n/* Choice button styles - solid rounded buttons matching the image */\n.sf-choice-button {\n width: 100%;\n max-width: none;\n background: rgba(0, 0, 0, 4);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n color: white;\n border: none;\n border-radius: 24px; /* More rounded for pill shape */\n padding: var(--sf-spacing-md) var(--sf-spacing-md);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.2s ease;\n text-align: center;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n outline: none;\n font-family: inherit;\n margin-bottom: 0;\n position: relative;\n overflow: hidden;\n opacity: 0; /* Start hidden for animation */\n /* Animation will be triggered by JavaScript when video reaches 90% */\n}\n\n/* Hover state for buttons */\n.sf-choice-button:hover {\n background: rgba(0, 0, 0, 0.9);\n transform: translateY(-2px);\n box-shadow: 0 6px 16px rgba(0, 0, 0, 0.8);\n}\n\n/* Active state for all buttons */\n.sf-choice-button:active {\n transform: translateY(0) scale(0.98);\n transition: all 0.1s ease;\n}\n\n/* Remove specific action type styling - use consistent dark buttons */\n.sf-choice-button--goto,\n.sf-choice-button--url,\n.sf-choice-button--next,\n.sf-choice-button--dom,\n.sf-choice-button--function {\n background: rgba(0, 0, 0, 0.4);\n border: none;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n}\n\n.sf-choice-button--goto:hover,\n.sf-choice-button--url:hover,\n.sf-choice-button--next:hover,\n.sf-choice-button--dom:hover,\n.sf-choice-button--function:hover {\n background: rgba(0, 0, 0, 0.9);\n transform: translateY(-2px);\n box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);\n}\n\n/* Hide choice buttons in minimized state */\n.sf-player--minimized .sf-choice-buttons-container {\n display: none;\n}\n\n/* Smaller mobile screens - maintain same layout but with tighter spacing */\n@media (max-width: 480px) {\n .sf-choice-buttons-container {\n bottom: var(--sf-spacing-sm);\n width: calc(100% - var(--sf-spacing-md));\n max-width: calc(100% - var(--sf-spacing-md));\n gap: calc(var(--sf-spacing-xs) + 2px);\n }\n \n .sf-choice-button {\n padding: var(--sf-spacing-sm) var(--sf-spacing-sm);\n font-size: 11px;\n border-radius: 20px;\n }\n}\n\n/* Touch device specific adjustments */\n@media (pointer: coarse) {\n .sf-choice-buttons-container {\n gap: var(--sf-spacing-sm);\n }\n \n .sf-choice-button {\n min-height: 44px; /* Apple's recommended minimum touch target size */\n padding: var(--sf-spacing-md) var(--sf-spacing-md);\n }\n}\n\n/* Button fade-in animation */\n@keyframes buttonFadeIn {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Animation class that will be added by JavaScript at 90% video progress */\n.sf-choice-button.sf-show-button {\n animation: buttonFadeIn 0.3s ease-out forwards;\n}\n\n/* Staggered animation delays for multiple buttons when shown */\n.sf-choice-button.sf-show-button:nth-child(1) {\n animation-delay: 0s;\n}\n\n.sf-choice-button.sf-show-button:nth-child(2) {\n animation-delay: 0.15s;\n}\n\n.sf-choice-button.sf-show-button:nth-child(3) {\n animation-delay: 0.3s;\n}\n\n.sf-choice-button.sf-show-button:nth-child(4) {\n animation-delay: 0.45s;\n}\n\n.sf-choice-button.sf-show-button:nth-child(5) {\n animation-delay: 0.6s;\n}\n\n.sf-choice-button.sf-show-button:nth-child(6) {\n animation-delay: 0.75s;\n}\n\n.sf-choice-button.sf-show-button:nth-child(7) {\n animation-delay: 0.9s;\n}\n\n.sf-choice-button.sf-show-button:nth-child(8) {\n animation-delay: 1.05s;\n} \n /* \n * Transcript component styles for the Saltfish Playlist Player\n * Following BEM naming convention\n */\n\n/* Transcript container */\n.sf-transcript {\n position: absolute;\n bottom: 40px; /* Above the progress bar */\n left: 0;\n right: 0;\n max-height: 200px;\n background: rgba(0, 0, 0, 0.7);\n backdrop-filter: blur(8px);\n margin: 0 var(--sf-spacing-md);\n overflow: hidden;\n z-index: var(--sf-z-index-overlay);\n opacity: 0;\n transform: translateY(20px);\n transition: all 0.3s ease-out;\n pointer-events: none;\n}\n\n/* Visible state */\n.sf-transcript--visible {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n\n/* Transcript content */\n.sf-transcript__content {\n max-height: 180px;\n overflow-y: auto;\n padding: var(--sf-spacing-xs);\n scrollbar-width: thin;\n scrollbar-color: rgba(255, 255, 255, 0.3) transparent;\n}\n\n/* Webkit scrollbar styling */\n.sf-transcript__content::-webkit-scrollbar {\n width: 4px;\n}\n\n.sf-transcript__content::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.sf-transcript__content::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.3);\n border-radius: 2px;\n}\n\n.sf-transcript__content::-webkit-scrollbar-thumb:hover {\n background: rgba(255, 255, 255, 0.5);\n}\n\n/* Transcript segments */\n.sf-transcript__segment {\n color: rgba(255, 255, 255);\n font-size: var(--sf-font-size-sm);\n line-height: 1.4;\n padding: var(--sf-spacing-xs) 0;\n cursor: pointer;\n transition: all 0.2s ease;\n padding-left: var(--sf-spacing-xs);\n padding-right: var(--sf-spacing-xs);\n}\n\n/* CC button active state */\n.sf-video-container__cc-button--active {\n background: rgba(255, 255, 255, 0.2);\n color: #fff;\n}\n\n/* Mobile responsive styles */\n@media (max-width: 768px) {\n .sf-transcript {\n bottom: 50px; /* More space on mobile */\n margin: 0 var(--sf-spacing-sm);\n max-height: 150px; /* Smaller on mobile */\n }\n \n .sf-transcript__content {\n max-height: 130px;\n padding: var(--sf-spacing-sm);\n }\n \n .sf-transcript__segment {\n font-size: var(--sf-font-size-xs);\n padding: var(--sf-spacing-xs) var(--sf-spacing-sm);\n }\n}\n\n/* Touch device optimizations */\n@media (pointer: coarse) {\n .sf-transcript__segment {\n padding: var(--sf-spacing-sm) var(--sf-spacing-xs);\n min-height: 44px; /* Larger touch target */\n display: flex;\n align-items: center;\n }\n}\n\n/* Hide transcript in minimized state */\n.sf-player--minimized .sf-transcript {\n display: none !important;\n}\n\n/* Animation for transcript appearance */\n@keyframes transcriptFadeIn {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes transcriptFadeOut {\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(20px);\n }\n}\n \n /* \n * Transitions and animations for Saltfish playlist Player\n */\n\n/* Fade in animation */\n@keyframes sf-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.sf-fade-in {\n animation: sf-fade-in 0.3s ease-in-out forwards;\n}\n\n/* Slide in from bottom animation */\n@keyframes sf-slide-in-bottom {\n from { transform: translateY(100%); opacity: 0; }\n to { transform: translateY(0); opacity: 1; }\n}\n\n.sf-slide-in-bottom {\n animation: sf-slide-in-bottom 0.3s cubic-bezier(0.25, 0.8, 0.25, 1) forwards;\n}\n\n/* Slide in from right animation */\n@keyframes sf-slide-in-right {\n from { transform: translateX(100%); opacity: 0; }\n to { transform: translateX(0); opacity: 1; }\n}\n\n.sf-slide-in-right {\n animation: sf-slide-in-right 0.3s cubic-bezier(0.25, 0.8, 0.25, 1) forwards;\n}\n\n/* Scale in animation */\n@keyframes sf-scale-in {\n from { transform: scale(0.8); opacity: 0; }\n to { transform: scale(1); opacity: 1; }\n}\n\n.sf-scale-in {\n animation: sf-scale-in 0.3s cubic-bezier(0.25, 0.8, 0.25, 1) forwards;\n}\n\n/* Scale out animation */\n@keyframes sf-scale-out {\n from { transform: scale(1); opacity: 1; }\n to { transform: scale(0.8); opacity: 0; }\n}\n\n.sf-scale-out {\n animation: sf-scale-out 0.3s cubic-bezier(0.25, 0.8, 0.25, 1) forwards;\n} \n"}}const i={},s=t=>{let e;const n=new Set,s=(t,i)=>{const s="function"==typeof t?t(e):t;if(!Object.is(s,e)){const t=e;e=(null!=i?i:"object"!=typeof s||null===s)?s:Object.assign({},e,s),n.forEach((n=>n(e,t)))}},r=()=>e,a={setState:s,getState:r,getInitialState:()=>o,subscribe:t=>(n.add(t),()=>n.delete(t)),destroy:()=>{"production"!==(i?"production":void 0)&&console.warn("[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."),n.clear()}},o=e=t(s,r,a);return a};var r=Symbol.for("immer-nothing"),a=Symbol.for("immer-draftable"),o=Symbol.for("immer-state");function l(t,...e){throw new Error(`[Immer] minified error nr: ${t}. Full error at: https://bit.ly/3cXEKWf`)}var c=Object.getPrototypeOf;function d(t){return!!t&&!!t[o]}function h(t){var e;return!!t&&(p(t)||Array.isArray(t)||!!t[a]||!!(null==(e=t.constructor)?void 0:e[a])||v(t)||b(t))}var u=Object.prototype.constructor.toString();function p(t){if(!t||"object"!=typeof t)return!1;const e=c(t);if(null===e)return!0;const n=Object.hasOwnProperty.call(e,"constructor")&&e.constructor;return n===Object||"function"==typeof n&&Function.toString.call(n)===u}function g(t,e){0===m(t)?Reflect.ownKeys(t).forEach((n=>{e(n,t[n],t)})):t.forEach(((n,i)=>e(i,n,t)))}function m(t){const e=t[o];return e?e.type_:Array.isArray(t)?1:v(t)?2:b(t)?3:0}function f(t,e){return 2===m(t)?t.has(e):Object.prototype.hasOwnProperty.call(t,e)}function y(t,e,n){const i=m(t);2===i?t.set(e,n):3===i?t.add(n):t[e]=n}function v(t){return t instanceof Map}function b(t){return t instanceof Set}function w(t){return t.copy_||t.base_}function S(t,e){if(v(t))return new Map(t);if(b(t))return new Set(t);if(Array.isArray(t))return Array.prototype.slice.call(t);const n=p(t);if(!0===e||"class_only"===e&&!n){const e=Object.getOwnPropertyDescriptors(t);delete e[o];let n=Reflect.ownKeys(e);for(let i=0;i<n.length;i++){const s=n[i],r=e[s];!1===r.writable&&(r.writable=!0,r.configurable=!0),(r.get||r.set)&&(e[s]={configurable:!0,writable:!0,enumerable:r.enumerable,value:t[s]})}return Object.create(c(t),e)}{const e=c(t);if(null!==e&&n)return{...t};const i=Object.create(e);return Object.assign(i,t)}}function M(t,e=!1){return I(t)||d(t)||!h(t)||(m(t)>1&&(t.set=t.add=t.clear=t.delete=E),Object.freeze(t),e&&Object.entries(t).forEach((([t,e])=>M(e,!0)))),t}function E(){l(2)}function I(t){return Object.isFrozen(t)}var x,P={};function C(t){const e=P[t];return e||l(0),e}function T(){return x}function _(t,e){e&&(C("Patches"),t.patches_=[],t.inversePatches_=[],t.patchListener_=e)}function k(t){z(t),t.drafts_.forEach(D),t.drafts_=null}function z(t){t===x&&(x=t.parent_)}function A(t){return x={drafts_:[],parent_:x,immer_:t,canAutoFreeze_:!0,unfinalizedDrafts_:0}}function D(t){const e=t[o];0===e.type_||1===e.type_?e.revoke_():e.revoked_=!0}function V(t,e){e.unfinalizedDrafts_=e.drafts_.length;const n=e.drafts_[0];return void 0!==t&&t!==n?(n[o].modified_&&(k(e),l(4)),h(t)&&(t=L(e,t),e.parent_||O(e,t)),e.patches_&&C("Patches").generateReplacementPatches_(n[o].base_,t,e.patches_,e.inversePatches_)):t=L(e,n,[]),k(e),e.patches_&&e.patchListener_(e.patches_,e.inversePatches_),t!==r?t:void 0}function L(t,e,n){if(I(e))return e;const i=e[o];if(!i)return g(e,((s,r)=>B(t,i,e,s,r,n))),e;if(i.scope_!==t)return e;if(!i.modified_)return O(t,i.base_,!0),i.base_;if(!i.finalized_){i.finalized_=!0,i.scope_.unfinalizedDrafts_--;const e=i.copy_;let s=e,r=!1;3===i.type_&&(s=new Set(e),e.clear(),r=!0),g(s,((s,a)=>B(t,i,e,s,a,n,r))),O(t,e,!1),n&&t.patches_&&C("Patches").generatePatches_(i,n,t.patches_,t.inversePatches_)}return i.copy_}function B(t,e,n,i,s,r,a){if(d(s)){const a=L(t,s,r&&e&&3!==e.type_&&!f(e.assigned_,i)?r.concat(i):void 0);if(y(n,i,a),!d(a))return;t.canAutoFreeze_=!1}else a&&n.add(s);if(h(s)&&!I(s)){if(!t.immer_.autoFreeze_&&t.unfinalizedDrafts_<1)return;L(t,s),e&&e.scope_.parent_||"symbol"==typeof i||!Object.prototype.propertyIsEnumerable.call(n,i)||O(t,s)}}function O(t,e,n=!1){!t.parent_&&t.immer_.autoFreeze_&&t.canAutoFreeze_&&M(e,n)}var U={get(t,e){if(e===o)return t;const n=w(t);if(!f(n,e))return function(t,e,n){var i;const s=N(e,n);return s?"value"in s?s.value:null==(i=s.get)?void 0:i.call(t.draft_):void 0}(t,n,e);const i=n[e];return t.finalized_||!h(i)?i:i===R(t.base_,e)?(H(t),t.copy_[e]=X(i,t)):i},has:(t,e)=>e in w(t),ownKeys:t=>Reflect.ownKeys(w(t)),set(t,e,n){const i=N(w(t),e);if(null==i?void 0:i.set)return i.set.call(t.draft_,n),!0;if(!t.modified_){const i=R(w(t),e),a=null==i?void 0:i[o];if(a&&a.base_===n)return t.copy_[e]=n,t.assigned_[e]=!1,!0;if(((s=n)===(r=i)?0!==s||1/s==1/r:s!=s&&r!=r)&&(void 0!==n||f(t.base_,e)))return!0;H(t),Y(t)}var s,r;return t.copy_[e]===n&&(void 0!==n||e in t.copy_)||Number.isNaN(n)&&Number.isNaN(t.copy_[e])||(t.copy_[e]=n,t.assigned_[e]=!0),!0},deleteProperty:(t,e)=>(void 0!==R(t.base_,e)||e in t.base_?(t.assigned_[e]=!1,H(t),Y(t)):delete t.assigned_[e],t.copy_&&delete t.copy_[e],!0),getOwnPropertyDescriptor(t,e){const n=w(t),i=Reflect.getOwnPropertyDescriptor(n,e);return i?{writable:!0,configurable:1!==t.type_||"length"!==e,enumerable:i.enumerable,value:n[e]}:i},defineProperty(){l(11)},getPrototypeOf:t=>c(t.base_),setPrototypeOf(){l(12)}},F={};function R(t,e){const n=t[o];return(n?w(n):t)[e]}function N(t,e){if(!(e in t))return;let n=c(t);for(;n;){const t=Object.getOwnPropertyDescriptor(n,e);if(t)return t;n=c(n)}}function Y(t){t.modified_||(t.modified_=!0,t.parent_&&Y(t.parent_))}function H(t){t.copy_||(t.copy_=S(t.base_,t.scope_.immer_.useStrictShallowCopy_))}g(U,((t,e)=>{F[t]=function(){return arguments[0]=arguments[0][0],e.apply(this,arguments)}})),F.deleteProperty=function(t,e){return F.set.call(this,t,e,void 0)},F.set=function(t,e,n){return U.set.call(this,t[0],e,n,t[0])};function X(t,e){const n=v(t)?C("MapSet").proxyMap_(t,e):b(t)?C("MapSet").proxySet_(t,e):function(t,e){const n=Array.isArray(t),i={type_:n?1:0,scope_:e?e.scope_:T(),modified_:!1,finalized_:!1,assigned_:{},parent_:e,base_:t,draft_:null,copy_:null,revoke_:null,isManual_:!1};let s=i,r=U;n&&(s=[i],r=F);const{revoke:a,proxy:o}=Proxy.revocable(s,r);return i.draft_=o,i.revoke_=a,o}(t,e);return(e?e.scope_:T()).drafts_.push(n),n}function $(t){if(!h(t)||I(t))return t;const e=t[o];let n;if(e){if(!e.modified_)return e.base_;e.finalized_=!0,n=S(t,e.scope_.immer_.useStrictShallowCopy_)}else n=S(t,!0);return g(n,((t,e)=>{y(n,t,$(e))})),e&&(e.finalized_=!1),n}var W=new class{constructor(t){this.autoFreeze_=!0,this.useStrictShallowCopy_=!1,this.produce=(t,e,n)=>{if("function"==typeof t&&"function"!=typeof e){const n=e;e=t;const i=this;return function(t=n,...s){return i.produce(t,(t=>e.call(this,t,...s)))}}let i;if("function"!=typeof e&&l(6),void 0!==n&&"function"!=typeof n&&l(7),h(t)){const s=A(this),r=X(t,void 0);let a=!0;try{i=e(r),a=!1}finally{a?k(s):z(s)}return _(s,n),V(i,s)}if(!t||"object"!=typeof t){if(i=e(t),void 0===i&&(i=t),i===r&&(i=void 0),this.autoFreeze_&&M(i,!0),n){const e=[],s=[];C("Patches").generateReplacementPatches_(t,i,e,s),n(e,s)}return i}l(1)},this.produceWithPatches=(t,e)=>{if("function"==typeof t)return(e,...n)=>this.produceWithPatches(e,(e=>t(e,...n)));let n,i;return[this.produce(t,e,((t,e)=>{n=t,i=e})),n,i]},"boolean"==typeof(null==t?void 0:t.autoFreeze)&&this.setAutoFreeze(t.autoFreeze),"boolean"==typeof(null==t?void 0:t.useStrictShallowCopy)&&this.setUseStrictShallowCopy(t.useStrictShallowCopy)}createDraft(t){h(t)||l(8),d(t)&&(t=function(t){d(t)||l(10);return $(t)}(t));const e=A(this),n=X(t,void 0);return n[o].isManual_=!0,z(e),n}finishDraft(t,e){const n=t&&t[o];n&&n.isManual_||l(9);const{scope_:i}=n;return _(i,e),V(void 0,i)}setAutoFreeze(t){this.autoFreeze_=t}setUseStrictShallowCopy(t){this.useStrictShallowCopy_=t}applyPatches(t,e){let n;for(n=e.length-1;n>=0;n--){const i=e[n];if(0===i.path.length&&"replace"===i.op){t=i.value;break}}n>-1&&(e=e.slice(n+1));const i=C("Patches").applyPatches_;return d(t)?i(t,e):this.produce(t,(t=>i(t,e)))}},j=W.produce;W.produceWithPatches.bind(W),W.setAutoFreeze.bind(W),W.setUseStrictShallowCopy.bind(W),W.applyPatches.bind(W),W.createDraft.bind(W),W.finishDraft.bind(W);const q=t=>(e,n,i)=>(i.setState=(t,n,...i)=>{const s="function"==typeof t?j(t):t;return e(s,n,...i)},t(i.setState,n,i)),Z="bottom",J="left",K="right",Q="center",G="saltfish_progress",tt="saltfish_session",et="saltfish_anonymous_user_data",nt=20,it="-50%",st="-50%",rt="-100%",at=5,ot=300,lt=6e4,ct=18e5,dt="https://player.saltfish.ai",ht="sf-player",ut="sf-player--minimized",pt="sf-controls-container",gt="sf-player__logo";function mt(t,e){void 0!==e?console.info(t,e):console.info(t)}function ft(t,e){console.warn(t)}function yt(t,e){void 0!==e?console.error(t,e):console.error(t)}class vt{constructor(t,n){e(this,"currentState"),e(this,"config"),e(this,"context"),e(this,"actionHandlers",{}),this.config=t,this.currentState=t.initial,this.context=n,this.setupDefaultActions(),this.runEntryActions(this.currentState)}setupDefaultActions(){this.actionHandlers={...this.actionHandlers,logStateEntry:t=>{this.currentState},logErrorEvent:(t,e)=>{"ERROR"===(null==e?void 0:e.type)&&e.error.message},logStepTransition:(t,e)=>{"TRANSITION_TO_STEP"===(null==e?void 0:e.type)&&e.step.id},logErrorRecovery:()=>{}}}registerActions(t){this.actionHandlers={...this.actionHandlers,...t},Object.keys(t).join(", ")}executeAction(t,e){if("string"==typeof t){const n=this.actionHandlers[t];n&&n(this.context,e)}else t(this.context,e)}send(t){const e=this.config.states[this.currentState].on[t.type];if(!e)return t.type,this.currentState,this.currentState;this.currentState,e.target,t.type,this.runExitActions(this.currentState),this.updateContextFromEvent(t),e.actions&&e.actions.forEach((e=>this.executeAction(e,t)));this.currentState;return this.currentState=e.target,this.runEntryActions(this.currentState),this.currentState,this.currentState}updateContextFromEvent(t){"TRANSITION_TO_STEP"===t.type||"MANIFEST_LOADED"===t.type||"VIDEO_ENDED"===t.type?this.context.currentStep=t.step:"ERROR"===t.type&&(this.context.error=t.error)}getState(){return this.currentState}getContext(){return this.context}updateContext(t){const e=t(this.context);this.context={...this.context,...e}}runEntryActions(t){const e=this.config.states[t];e.entry&&e.entry.forEach((t=>this.executeAction(t)))}runExitActions(t){const e=this.config.states[t];e.exit&&e.exit.forEach((t=>this.executeAction(t)))}}const bt={initial:"idle",states:{idle:{on:{INITIALIZE:{target:"idle"},LOAD_MANIFEST:{target:"loading"}},entry:["logStateEntry"]},loading:{on:{MANIFEST_LOADED:{target:"paused"},ERROR:{target:"error",actions:["logErrorEvent"]}},entry:["logStateEntry"]},playing:{on:{PAUSE:{target:"paused"},MINIMIZE:{target:"minimized"},VIDEO_ENDED:{target:"waitingForInteraction"},AUTOPLAY_FALLBACK:{target:"autoplayBlocked"},TRANSITION_TO_STEP:{target:"playing",actions:["logStepTransition"]},ERROR:{target:"error"},COMPLETE_PLAYLIST:{target:"completed"},COMPLETE_PLAYLIST_WAITING_FOR_INTERACTION:{target:"completedWaitingForInteraction"}},entry:["logStateEntry","startVideoPlayback"],exit:["pauseVideoPlayback"]},paused:{on:{PLAY:{target:"playing"},MINIMIZE:{target:"minimized"},TRANSITION_TO_STEP:{target:"playing",actions:["logStepTransition"]}},entry:["logStateEntry","pauseVideoPlayback"]},minimized:{on:{MAXIMIZE:{target:"paused"}},entry:["logStateEntry","pauseVideoPlayback"]},waitingForInteraction:{on:{PLAY:{target:"playing"},PAUSE:{target:"paused"},MINIMIZE:{target:"minimized"},COMPLETE_PLAYLIST:{target:"completed"},COMPLETE_PLAYLIST_WAITING_FOR_INTERACTION:{target:"completedWaitingForInteraction"},TRANSITION_TO_STEP:{target:"playing",actions:["logStepTransition"]}},entry:["logStateEntry"]},autoplayBlocked:{on:{PLAY:{target:"playing"},TRANSITION_TO_STEP:{target:"playing"},MINIMIZE:{target:"minimized"}},entry:["logStateEntry","startMutedLoopedVideo"]},error:{on:{INITIALIZE:{target:"idle"},PLAY:{target:"playing",actions:["logErrorRecovery"]},AUTOPLAY_FALLBACK:{target:"autoplayBlocked"}},entry:["logStateEntry","handleError"]},completedWaitingForInteraction:{on:{COMPLETE_PLAYLIST:{target:"completed"},INITIALIZE:{target:"idle"},TRANSITION_TO_STEP:{target:"playing",actions:["logStepTransition"]},PLAY:{target:"playing"},MINIMIZE:{target:"minimized"}},entry:["logStateEntry"]},completed:{on:{INITIALIZE:{target:"idle"}},entry:["logStateEntry","trackPlaylistComplete"]}}},wt=20,St=()=>{const t=document.getElementById("saltfish-container");return t&&t.shadowRoot?t:document.documentElement},Mt=()=>{if("undefined"!=typeof window){const t=St(),e=getComputedStyle(t).getPropertyValue("--sf-player-width");return parseInt(e,10)||200}return 200},Et=t=>{const e=t?(()=>{if("undefined"!=typeof window){const t=St(),e=getComputedStyle(t);return parseInt(e.getPropertyValue("--sf-player-min-width"),10)||80}return 80})():Mt();return{width:e,minX:20,maxX:window.innerWidth-e-wt}};class It{static calculatePosition(t){const{position:e,viewportWidth:n=window.innerWidth,viewportHeight:i=window.innerHeight,playerWidth:s=Mt()}=t;let r=nt,a=nt,o="0",l="0";e.includes(Z)&&(a=i-nt,l=rt),e.includes(J)?r=nt:e.includes(K)?r=n-s-wt:e.includes(Q)&&(r=n/2,a=i/2,o=it,l=st);return{...this.applyConstraints({x:r,y:a,position:e,viewportWidth:n,viewportHeight:i,playerWidth:s}),transformX:o,transformY:l}}static applyConstraints(t){const{x:e,y:n,position:i,viewportWidth:s,viewportHeight:r,playerWidth:a}=t;let o=e,l=n;return i.includes(Z)&&!i.includes(Q)&&(l=r-nt),i.includes(K)&&!i.includes(Q)&&(o=Math.max(nt,Math.min(o,s-a-wt))),o=Math.max(nt,Math.min(o,s-a-wt)),l=Math.max(nt,Math.min(l,r-nt)),{x:o,y:l}}static calculateDragPosition(t){const{x:e,y:n,position:i,viewportWidth:s=window.innerWidth,viewportHeight:r=window.innerHeight,playerWidth:a=Mt()}=t;let o=e,l=n;(null==i?void 0:i.includes(K))&&!i.includes(Q)&&(o=Math.min(o,s-a-wt));const c=nt,d=s-a-wt;return o=Math.max(c,Math.min(o,d)),l=Math.max(nt,Math.min(l,r-nt)),{x:o,y:l}}static getTransforms(t){let e="0",n="0";return t.includes(Q)?(e=it,n=st):t.includes(Z)&&(n=rt),{transformX:e,transformY:n}}static shouldForceReposition(t,e,n){return"bottom-left"===t&&!n&&(e===window.innerHeight-nt||Math.abs(e-(window.innerHeight-nt))<5)}static getPlayerDimensions(){const t=Mt();return{width:t,minX:nt,maxX:window.innerWidth-t-wt}}}const xt=s(q(((t,e)=>{const n=new vt(bt,{currentStep:null,error:null});return{config:null,user:null,userData:null,currentState:n.getState(),manifest:null,currentStepId:null,isMinimized:!1,position:null,progress:{},error:null,stateMachine:n,playlistOptions:null,backendPlaylists:[],isMuted:!1,initialize:async e=>{t((t=>{t.config=e,t.currentState=t.stateMachine.send({type:"INITIALIZE"})}))},setPlaylistOptions:e=>{t((t=>{if(t.playlistOptions=e,e.position){const n=It.calculatePosition({position:e.position});t.position={x:n.x,y:n.y}}}))},identifyUser:(e,n)=>{const i={id:e,...n};t((t=>{t.user=i}))},setUserData:e=>{t((t=>{t.userData=e}))},setManifest:(e,n)=>{t((t=>{t.manifest=e,t.currentStepId=n,t.currentState=t.stateMachine.send({type:"LOAD_MANIFEST"})}))},play:()=>{const{currentState:n}=e();t((t=>{t.currentState=t.stateMachine.send({type:"PLAY"})}))},pause:()=>{const{currentState:n}=e();t((t=>{t.currentState=t.stateMachine.send({type:"PAUSE"})}))},minimize:()=>{const{currentState:n}=e();t((t=>{"playing"===t.currentState&&(t.currentState=t.stateMachine.send({type:"PAUSE"})),t.currentState=t.stateMachine.send({type:"MINIMIZE"}),t.isMinimized=!0}))},maximize:()=>{t((t=>{t.currentState=t.stateMachine.send({type:"MAXIMIZE"}),t.isMinimized=!1}))},setPosition:(e,n)=>{t((t=>{t.position={x:e,y:n}}))},goToStep:n=>{const{manifest:i}=e();if("completed"!==n){if(i&&i.steps.some((t=>t.id===n))){const e=i.steps.find((t=>t.id===n));t((t=>{var s,r;if(t.currentStepId=n,e&&(t.currentState=t.stateMachine.send({type:"TRANSITION_TO_STEP",step:e}),t.position)){const n=e.position||(null==(s=t.playlistOptions)?void 0:s.position)||"bottom-right",i=It.calculatePosition({position:n});t.position={x:i.x,y:i.y}}t.progress[i.id]={...t.progress[i.id],lastStepId:n,lastVisited:(new Date).toISOString()};((null==(r=t.playlistOptions)?void 0:r.persistence)??!0)&&"undefined"!=typeof window&&localStorage.setItem(G,JSON.stringify(t.progress))}))}}else t((t=>{var e;t.currentState=t.stateMachine.send({type:"COMPLETE_PLAYLIST"});const n=(null==(e=t.playlistOptions)?void 0:e.persistence)??!0;i&&n&&(delete t.progress[i.id],"undefined"!=typeof window&&localStorage.setItem(G,JSON.stringify(t.progress)),i.id)}))},reset:()=>{t((t=>{t.config=null,t.user=null,t.userData=null,t.currentState="idle",t.manifest=null,t.currentStepId=null,t.isMinimized=!1,t.position=null,t.progress={},t.error=null,t.stateMachine=new vt(bt,{currentStep:null,error:null})}))},setError:e=>{t((t=>{t.currentState=t.stateMachine.send({type:"ERROR",error:e}),t.error=e}))},setAutoplayFallback:()=>{t((t=>{t.currentState=t.stateMachine.send({type:"AUTOPLAY_FALLBACK"})}))},setMuted:e=>{t((t=>{t.isMuted=e}))},setBackendPlaylists:e=>{t((t=>{t.backendPlaylists=e}))},completePlaylist:()=>{t((t=>{var e;const{manifest:n}=t;t.currentState=t.stateMachine.send({type:"COMPLETE_PLAYLIST"});const i=(null==(e=t.playlistOptions)?void 0:e.persistence)??!0;n&&i&&(delete t.progress[n.id],"undefined"!=typeof window&&localStorage.setItem(G,JSON.stringify(t.progress)),n.id)}))},resetForNewPlaylist:()=>{t((t=>{const e=t.config,n=t.user,i=t.userData,s=t.progress;t.manifest=null,t.currentStepId=null,t.isMinimized=!1,t.position=null,t.error=null,t.playlistOptions=null,t.stateMachine=new vt(bt,{currentStep:null,error:null}),t.currentState=t.stateMachine.getState(),t.config=e,t.user=n,t.userData=i,t.progress=s}))},loadPlaylistProgress:(e,n)=>{t((t=>{t.progress[e]=n}))}}}))),Pt={getState:()=>xt.getState(),setState:xt.setState,subscribe:xt.subscribe,destroy:xt.destroy};class Ct{static isMobile(){return this.getDeviceInfo().isMobile}static isTablet(){return this.getDeviceInfo().isTablet}static isDesktop(){return this.getDeviceInfo().isDesktop}static isTouchDevice(){return this.getDeviceInfo().isTouchDevice}static getOrientation(){return this.getDeviceInfo().orientation}static getDeviceInfo(){if(this.cachedDeviceInfo)return this.cachedDeviceInfo.orientation=this.detectOrientation(),this.cachedDeviceInfo;const t="undefined"!=typeof navigator?navigator.userAgent:"",e=this.detectTouchSupport(),{width:n,height:i}=this.getScreenDimensions(),s=/iPad|Android(?!.*Mobile)|Tablet|tablet/i,r=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|mobile|CriOS/i.test(t)&&!s.test(t),a=s.test(t),o=this.getScreenSize(n,i),l="small"===o&&Math.min(n,i)<768,c=r||l&&e,d=a||"medium"===o&&!l&&e&&!c,h={isMobile:c,isTablet:d,isDesktop:!c&&!d,isTouchDevice:e,screenSize:o,orientation:this.detectOrientation(),userAgent:t};return this.cachedDeviceInfo=h,h}static detectTouchSupport(){return"undefined"!=typeof window&&("ontouchstart"in window||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0)}static getScreenDimensions(){return"undefined"==typeof window?{width:1920,height:1080}:{width:window.innerWidth||document.documentElement.clientWidth||1920,height:window.innerHeight||document.documentElement.clientHeight||1080}}static getScreenSize(t,e){const n=Math.min(t,e);return n<768?"small":n<1024?"medium":"large"}static detectOrientation(){if("undefined"==typeof window)return"landscape";const{width:t,height:e}=this.getScreenDimensions();return e>t?"portrait":"landscape"}static clearCache(){this.cachedDeviceInfo=null}static onDeviceChange(t){if("undefined"==typeof window)return()=>{};const e=()=>{try{this.clearCache(),t(this.getDeviceInfo())}catch(e){console.warn("DeviceDetector: Error in device change handler:",e)}};return window.addEventListener("orientationchange",e),window.addEventListener("resize",e),()=>{window.removeEventListener("orientationchange",e),window.removeEventListener("resize",e)}}}e(Ct,"cachedDeviceInfo",null);const Tt=Object.freeze(Object.defineProperty({__proto__:null,DeviceDetector:Ct,isDeviceCompatible:t=>{if(!t||"both"===t)return!0;const e=Ct.getDeviceInfo();return"mobile"===t?e.isMobile||e.isTablet:"desktop"===t&&e.isDesktop}},Symbol.toStringTag,{value:"Module"}));class _t{constructor(){e(this,"transcriptContainer",null),e(this,"transcriptContent",null),e(this,"ccButton",null),e(this,"isVisible",!1),e(this,"currentTranscript",null),e(this,"currentSegmentIndex",-1),e(this,"segments",[]),e(this,"videoElement",null),e(this,"timeUpdateListener",null)}setup(t,e){this.videoElement=t,this.ccButton=e,this.ccButton.addEventListener("click",this.handleCCButtonClick.bind(this)),this.timeUpdateListener=this.handleTimeUpdate.bind(this),this.videoElement.addEventListener("timeupdate",this.timeUpdateListener)}loadTranscript(t){this.currentTranscript=t,this.currentSegmentIndex=-1,t?(this.updateCCButtonState(!0),this.createTranscriptUI(),this.renderTranscriptSegments(),t.segments.length):(this.updateCCButtonState(!1),this.hideTranscript())}toggleVisibility(){this.currentTranscript&&(this.isVisible=!this.isVisible,this.isVisible?this.showTranscript():this.hideTranscript(),this.updateCCButtonState(!!this.currentTranscript),this.isVisible)}handleCCButtonClick(t){t.preventDefault(),t.stopPropagation(),this.toggleVisibility()}handleTimeUpdate(t){if(!this.currentTranscript||!this.isVisible||!this.videoElement)return;const e=this.videoElement.currentTime,n=this.findActiveSegmentIndex(e);n!==this.currentSegmentIndex&&(this.highlightSegment(n),this.currentSegmentIndex=n)}findActiveSegmentIndex(t){if(!this.currentTranscript)return-1;for(let e=0;e<this.currentTranscript.segments.length;e++){const n=this.currentTranscript.segments[e];if(t>=n.start&&t<=n.end)return e}return-1}highlightSegment(t){if(this.segments.forEach((t=>{t.classList.remove("sf-transcript__segment--active")})),t>=0&&t<this.segments.length){const e=this.segments[t];e.classList.add("sf-transcript__segment--active"),e.scrollIntoView({behavior:"smooth",block:"nearest"})}}createTranscriptUI(){var t;if(this.transcriptContainer)return;const e=null==(t=this.videoElement)?void 0:t.closest(".sf-video-container");e&&(this.transcriptContainer=document.createElement("div"),this.transcriptContainer.className="sf-transcript",this.transcriptContainer.style.display="none",this.transcriptContent=document.createElement("div"),this.transcriptContent.className="sf-transcript__content",this.transcriptContainer&&this.transcriptContent&&(this.transcriptContainer.appendChild(this.transcriptContent),e.appendChild(this.transcriptContainer)))}renderTranscriptSegments(){this.transcriptContent&&this.currentTranscript&&(this.transcriptContent.innerHTML="",this.segments=[],this.currentTranscript.segments.forEach((t=>{const e=document.createElement("div");e.className="sf-transcript__segment",e.textContent=t.text,e.addEventListener("click",(()=>{this.videoElement&&(this.videoElement.currentTime=t.start)})),this.transcriptContent&&(this.transcriptContent.appendChild(e),this.segments.push(e))})),this.segments.length)}showTranscript(){this.transcriptContainer&&(this.transcriptContainer.style.display="block",this.transcriptContainer.classList.add("sf-transcript--visible"))}hideTranscript(){this.transcriptContainer&&(this.transcriptContainer.style.display="none",this.transcriptContainer.classList.remove("sf-transcript--visible"))}updateCCButtonState(t){this.ccButton&&(t?(this.ccButton.style.display="block",this.ccButton.classList.toggle("sf-video-container__cc-button--active",this.isVisible)):this.ccButton.style.display="none")}reset(){this.currentTranscript=null,this.currentSegmentIndex=-1,this.segments=[],this.isVisible&&this.hideTranscript(),this.transcriptContent&&(this.transcriptContent.innerHTML=""),this.updateCCButtonState(!1)}async destroy(){this.timeUpdateListener&&this.videoElement&&this.videoElement.removeEventListener("timeupdate",this.timeUpdateListener),this.transcriptContainer&&this.transcriptContainer.parentNode&&this.transcriptContainer.parentNode.removeChild(this.transcriptContainer),this.transcriptContainer=null,this.transcriptContent=null,this.ccButton=null,this.videoElement=null,this.timeUpdateListener=null,this.currentTranscript=null,this.segments=[],this.currentSegmentIndex=-1,this.isVisible=!1}}class kt{constructor(t){e(this,"deviceInfo"),this.deviceInfo=t}updateDeviceInfo(t){this.deviceInfo=t}}class zt extends kt{getVideoElementConfig(){return{playsInline:!0,muted:!0,controls:!1,preload:"metadata",additionalAttributes:{"webkit-playsinline":"true",playsinline:"true","x-webkit-airplay":"allow"},styles:{width:"100%",height:"100%",objectFit:"cover",backgroundColor:"white"}}}getControlsConfig(){return{buttonMinSize:{width:"44px",height:"44px"},useTouch:!0,progressUpdateInterval:500}}getAutoplayConfig(t){return{shouldStartMuted:!t,enableFallbackLoop:!0,fallbackTimeout:3e3,requiresUserInteraction:!0}}configureVideoElement(t){const e=this.getVideoElementConfig();t.playsInline=e.playsInline,t.muted=e.muted,t.controls=e.controls,t.preload=e.preload,Object.entries(e.additionalAttributes).forEach((([e,n])=>{try{t.setAttribute(e,n)}catch(i){console.warn(`MobilePlaybackHandler: Failed to set attribute ${e}:`,i)}})),Object.entries(e.styles).forEach((([e,n])=>{try{t.style[e]=n}catch(i){console.warn(`MobilePlaybackHandler: Failed to set style ${e}:`,i)}}))}configureControlElement(t){const e=this.getControlsConfig();t.style.minWidth=e.buttonMinSize.width,t.style.minHeight=e.buttonMinSize.height}async handlePlayAttempt(t,e){const n=Pt.getState().isMuted;t.muted=n,t.loop=!1;try{return await t.play(),!0}catch(i){return t.muted,await this.handleAutoplayFallback(t),!1}}async handleAutoplayFallback(t){t.muted=!0,t.loop=!0,t.playsInline=!0,t.setAttribute("playsinline","true"),t.setAttribute("webkit-playsinline","true");try{await t.play()}catch(e){console.error("MobilePlaybackHandler: All autoplay attempts failed")}}destroy(){}getProgressUpdateFrequency(t){return t?500:16}}class At extends kt{getVideoElementConfig(){return{playsInline:!0,muted:!1,controls:!1,preload:"metadata",additionalAttributes:{},styles:{backgroundColor:"white"}}}getControlsConfig(){return{buttonMinSize:{width:"auto",height:"auto"},useTouch:!1,progressUpdateInterval:16}}getAutoplayConfig(t){return{shouldStartMuted:!1,enableFallbackLoop:!1,fallbackTimeout:5e3,requiresUserInteraction:!1}}configureVideoElement(t){const e=this.getVideoElementConfig();t.playsInline=e.playsInline,t.muted=e.muted,t.controls=e.controls,t.preload=e.preload,Object.entries(e.styles).forEach((([e,n])=>{t.style[e]=n}))}configureControlElement(t){}async handlePlayAttempt(t,e){const n=Pt.getState().isMuted;t.muted=n,t.loop=!1;try{return await t.play(),!0}catch(i){return t.muted,await this.handleAutoplayFallback(t),!1}}async handleAutoplayFallback(t){t.muted=!0,t.loop=!0;try{await t.play()}catch(e){throw console.error("DesktopPlaybackHandler: All autoplay attempts failed"),new Error("Desktop autoplay completely blocked")}}getProgressUpdateFrequency(t){return 16}destroy(){}}class Dt{constructor(){e(this,"currentVideo",null),e(this,"nextVideo",null),e(this,"activeVideoIndex",0),e(this,"container",null),e(this,"progressBar",null),e(this,"muteButton",null),e(this,"ccButton",null),e(this,"transcriptManager"),e(this,"preloadedVideos",new Map),e(this,"updateInterval",null),e(this,"animationFrameId",null),e(this,"lastTimeupdateEvent",0),e(this,"currentVideoUrl",""),e(this,"nextVideoUrl",""),e(this,"playbackPositions",new Map),e(this,"completionPolicy","auto"),e(this,"videoEndedCallback",null),e(this,"deviceHandler"),e(this,"deviceChangeCleanup",null),e(this,"hasUserInteracted",!1),e(this,"autoplayFallbackTimeout",null),e(this,"buttonsShownAt90Percent",!1),e(this,"handleVideoEnded",(t=>{const e=t.target,n=this.getActiveVideo();if(e!==n)return;"autoplayBlocked"!==Pt.getState().currentState&&(this.progressBar&&(this.progressBar.style.transition="width 0.2s ease-out",this.progressBar.style.width="100%"),n&&(n.style.filter="blur(3px)",n.style.transition="filter 0.3s ease-out"),"auto"===this.completionPolicy?this.handleAutoVideoEnded():this.handleManualVideoEnded())})),e(this,"handleTimeUpdate",(t=>{const e=t.target;e===this.getActiveVideo()&&Math.floor(e.currentTime)})),e(this,"handleVideoError",(t=>{const e=t.target;console.error("VideoManager: Video error",e.error)})),e(this,"handleDetailedTimeUpdate",(()=>{var t;this.lastTimeupdateEvent=Date.now(),this.progressBar&&!1===(null==(t=this.getActiveVideo())?void 0:t.paused)&&(this.progressBar.style.transition="width 0.1s linear");const e=this.getActiveVideo();if(e&&!this.buttonsShownAt90Percent&&e.duration>0){e.currentTime/e.duration>=.9&&(this.showButtonsAt90Percent(),this.buttonsShownAt90Percent=!0)}})),e(this,"handleAutoVideoEnded",(()=>{var t;const e=Pt.getState(),n=e.currentStepId;if(!n||!e.manifest)return;const i=e.manifest.steps.find((t=>t.id===n));if(!i)return;this.videoEndedCallback&&this.videoEndedCallback();const s=(null==(t=i.buttons)?void 0:t.some((t=>"url"===t.action.type)))??!1,r=e.manifest.steps.findIndex((t=>t.id===i.id))===e.manifest.steps.length-1,a=i.transitions.some((t=>e.manifest.steps.some((e=>e.id===t.nextStep)))),o=s||r||!a,l=i.transitions.some((t=>"url-path"===t.type)),c=i.transitions.some((t=>"dom-click"===t.type)),d=i.transitions.some((t=>"dom-element-visible"===t.type)),h=i.buttons&&i.buttons.length>0;if(l||c||d||h)o&&s&&Pt.setState((t=>{var i;t.currentState=t.stateMachine.send({type:"COMPLETE_PLAYLIST_WAITING_FOR_INTERACTION"}),t.progress[e.manifest.id]={...t.progress[e.manifest.id],lastStepId:n,lastVisited:(new Date).toISOString(),completedWaitingForInteraction:!0};((null==(i=t.playlistOptions)?void 0:i.persistence)??!0)&&"undefined"!=typeof window&&localStorage.setItem(G,JSON.stringify(t.progress))}));else if(i.transitions.length>0){const t=i.transitions[0].nextStep;e.goToStep(t)}else e.completePlaylist?e.completePlaylist():e.goToStep("completed")})),e(this,"handleManualVideoEnded",(()=>{var t;const e=Pt.getState(),n=e.currentStepId;if(n&&e.manifest&&e.manifest.steps){const i=e.manifest.steps.find((t=>t.id===n));if(i){const s=(null==(t=i.buttons)?void 0:t.some((t=>"url"===t.action.type)))??!1,r=e.manifest.steps.findIndex((t=>t.id===i.id))===e.manifest.steps.length-1,a=i.transitions.some((t=>e.manifest.steps.some((e=>e.id===t.nextStep))));if((s||r||!a)&&s)return Pt.setState((t=>{var i;t.currentState=t.stateMachine.send({type:"COMPLETE_PLAYLIST_WAITING_FOR_INTERACTION"}),t.progress[e.manifest.id]={...t.progress[e.manifest.id],lastStepId:n,lastVisited:(new Date).toISOString(),completedWaitingForInteraction:!0};((null==(i=t.playlistOptions)?void 0:i.persistence)??!0)&&"undefined"!=typeof window&&localStorage.setItem(G,JSON.stringify(t.progress))})),void(this.videoEndedCallback&&this.videoEndedCallback())}}this.videoEndedCallback&&this.videoEndedCallback()})),e(this,"handleProgressBarClick",(t=>{const e=t.currentTarget,n=this.getActiveVideo();if(!n||n.duration<=0)return;const i=e.getBoundingClientRect(),s=(t.clientX-i.left)/i.width,r=n.duration*s;this.progressBar&&(this.progressBar.style.transition="none",this.progressBar.style.width=100*s+"%"),this.seek(r),t.preventDefault(),t.stopPropagation()})),e(this,"handleSeeking",(()=>{this.progressBar&&(this.progressBar.style.transition="none",this.updateProgress())})),e(this,"handleSeeked",(()=>{if(this.progressBar){const t=this.getActiveVideo();t&&!t.paused&&(this.updateProgress(),this.progressBar.offsetWidth,this.progressBar.style.transition="width 0.1s linear")}}));const t=Ct.getDeviceInfo();this.deviceHandler=function(t){return t.isMobile?new zt(t):new At(t)}(t),this.transcriptManager=new _t,this.deviceChangeCleanup=Ct.onDeviceChange((t=>{this.deviceHandler.updateDeviceInfo(t),this.handleDeviceChange(t)}))}getDeviceInfo(){return Ct.getDeviceInfo()}isMobileDevice(){return this.getDeviceInfo().isMobile}handleDeviceChange(t){}create(t){this.container=document.createElement("div"),this.container.className="sf-video-container",t.appendChild(this.container),this.currentVideo=document.createElement("video"),this.currentVideo.className="sf-video-container__video sf-video-container__video--current",this.deviceHandler.configureVideoElement(this.currentVideo),this.container.appendChild(this.currentVideo),this.nextVideo=document.createElement("video"),this.nextVideo.className="sf-video-container__video sf-video-container__video--next",this.deviceHandler.configureVideoElement(this.nextVideo),this.nextVideo.style.backgroundColor="black",this.nextVideo.style.display="none",this.container.appendChild(this.nextVideo);Pt.getState().isMuted&&(this.currentVideo.muted=!0,this.nextVideo.muted=!0);const e=document.createElement("div");e.className="sf-video-container__controls",this.container.appendChild(e),this.progressBar=document.createElement("div"),this.progressBar.className="sf-video-container__progress",e.appendChild(this.progressBar);const n=this.deviceHandler.getControlsConfig();n.useTouch&&e.addEventListener("touchend",this.handleProgressBarClick),e.addEventListener("click",this.handleProgressBarClick),this.muteButton=document.createElement("button"),this.muteButton.className="sf-video-container__mute-button",this.deviceHandler.configureControlElement(this.muteButton),this.muteButton.innerHTML='\n <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">\n <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5" fill="none"></polygon>\n <path d="M15 9c0.8 0.8 1.5 1.9 1.5 3s-0.7 2.2-1.5 3" stroke="currentColor"></path>\n <path d="M19 7c1.6 1.6 2.5 3.8 2.5 6s-0.9 4.4-2.5 6" stroke="currentColor"></path>\n </svg>\n ',n.useTouch&&this.muteButton.addEventListener("touchend",(t=>{t.preventDefault(),this.toggleMute(t)})),this.muteButton.addEventListener("click",(t=>{this.toggleMute(t)})),this.container.appendChild(this.muteButton),this.updateMuteButtonIcon(),this.ccButton=document.createElement("button"),this.ccButton.className="sf-video-container__cc-button",this.deviceHandler.configureControlElement(this.ccButton),this.ccButton.innerHTML='\n <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">\n <rect x="2" y="6" width="20" height="12" rx="2" ry="2"></rect>\n <path d="M7 10h1v4H7z"></path>\n <path d="M11 10h1v4h-1z"></path>\n <path d="M15 10h1v4h-1z"></path>\n </svg>\n ',n.useTouch&&this.ccButton.addEventListener("touchend",(t=>{t.preventDefault()})),this.ccButton.addEventListener("click",(t=>{t.preventDefault()})),this.container.appendChild(this.ccButton),this.addEventListeners(),this.currentVideo&&this.ccButton&&this.transcriptManager.setup(this.currentVideo,this.ccButton)}getActiveVideo(){return 0===this.activeVideoIndex?this.currentVideo:this.nextVideo}getInactiveVideo(){return 0===this.activeVideoIndex?this.nextVideo:this.currentVideo}swapVideos(){const t=this.getActiveVideo(),e=this.getInactiveVideo();if(!t||!e)return;t.pause();const n=Pt.getState();e.muted=n.isMuted,t.style.display="none",e.style.display="block",this.activeVideoIndex=0===this.activeVideoIndex?1:0,this.currentVideoUrl=this.nextVideoUrl,this.nextVideoUrl=""}async loadVideo(t){var e;const n=this.getActiveVideo();if(!n)return;this.buttonsShownAt90Percent=!1;const i=Pt.getState();n.muted=i.isMuted;try{this.progressBar&&(this.progressBar.style.transition="none",this.progressBar.style.width="0%",setTimeout((()=>{this.progressBar&&(this.progressBar.style.transition="width 0.1s linear")}),50));const i=(null==(e=Pt.getState().playlistOptions)?void 0:e.persistence)??!0;if(this.currentVideoUrl===t&&n.src&&(n.src===t||n.src.endsWith(t))){if(i){const e=this.playbackPositions.get(t);void 0!==e&&e>0&&Math.abs(n.currentTime-e)>.5&&(n.currentTime=e)}return}i&&this.currentVideoUrl&&n.currentTime>0&&this.playbackPositions.set(this.currentVideoUrl,n.currentTime);if(this.getInactiveVideo()&&this.nextVideoUrl===t)return this.swapVideos(),void(await new Promise((t=>{const e=this.getActiveVideo();if(!e)return t();if(e.readyState>=3)t();else{const n=()=>{e.removeEventListener("canplay",n),t()};e.addEventListener("canplay",n)}})));this.currentVideoUrl=t;const s=this.preloadedVideos.get(t);if(s){const e=URL.createObjectURL(s);n.src=e,this.preloadedVideos.delete(t)}else n.src=t;n.load(),await new Promise(((e,s)=>{if(!n)return e(void 0);let r;const a=()=>{if(n){if(clearTimeout(r),i){const e=this.playbackPositions.get(t);if(void 0!==e&&e>0){const t=Math.min(e,n.duration-.5);n.currentTime=t}}else n.currentTime=0;n.removeEventListener("loadeddata",a),n.removeEventListener("error",o),e(void 0)}},o=t=>{var e,i,l;clearTimeout(r),console.error("VideoManager: Video load error:",null==(e=t.target)?void 0:e.error),n.removeEventListener("loadeddata",a),n.removeEventListener("error",o),s(new Error(`Video load failed: ${(null==(l=null==(i=t.target)?void 0:i.error)?void 0:l.message)||"Unknown error"}`))};r=window.setTimeout((()=>{console.error("VideoManager: Video load timeout after 10 seconds"),n.removeEventListener("loadeddata",a),n.removeEventListener("error",o),s(new Error("Video load timeout"))}),1e4),n.addEventListener("loadeddata",a),n.addEventListener("error",o)}))}catch(s){throw console.error("VideoManager: Failed to load video:",s),new Error("Failed to load video")}}preloadNextVideo(t){if(!t||this.preloadedVideos.has(t))return;if(this.currentVideoUrl===t)return;if(this.nextVideoUrl===t)return;const e=this.getInactiveVideo();if(e){this.nextVideoUrl=t,e.src=t,e.load(),e.preload="auto";const n=Pt.getState();e.muted=n.isMuted}else fetch(t).then((t=>{if(!t.ok)throw new Error(`Failed to fetch video: ${t.statusText}`);return t.blob()})).then((e=>{this.preloadedVideos.set(t,e)})).catch((e=>{console.error(`VideoManager: Error preloading video ${t}:`,e)}))}play(){var t;const e=this.getActiveVideo();if(!e)return void console.error("VideoManager: No active video element found");if(e.style.filter&&(e.style.filter="",e.style.transition=""),!e.paused)return;e.ended&&(e.currentTime=0);const n=Pt.getState();if(((null==(t=n.playlistOptions)?void 0:t.persistence)??!0)&&this.currentVideoUrl){const t=this.playbackPositions.get(this.currentVideoUrl);t&&Math.abs(e.currentTime-t)>.5&&(e.currentTime=t)}const i="autoplayBlocked"===n.currentState;i&&(e.currentTime=0,e.loop=!1,this.setMuted(!1),this.showProgressBar(),this.showMuteButton(),this.startProgressUpdates()),i||this.showProgressBar(),this.deviceHandler.handlePlayAttempt(e,this.hasUserInteracted).then((t=>{e&&(t?i||this.startProgressUpdates():(n.setAutoplayFallback(),this.isMobileDevice()&&(e.playsInline=!0,e.setAttribute("playsinline","true"),e.setAttribute("webkit-playsinline","true"),setTimeout((()=>{e.paused&&e.play().catch((()=>{}))}),200))))})).catch((()=>{console.warn("VideoManager: Autoplay handler threw error - browser has strict autoplay policy");Pt.getState().setAutoplayFallback()}))}pause(){const t=this.getActiveVideo();t&&(t.paused||(this.updateProgress(),this.progressBar&&(this.progressBar.style.transition="none"),t.pause(),this.stopProgressUpdates()))}seek(t){const e=this.getActiveVideo();if(e){if(this.progressBar){this.progressBar.style.transition="none";const n=t/e.duration*100;this.progressBar.style.width=`${n}%`}e.currentTime=t,this.updateProgress()}}getCurrentTime(){const t=this.getActiveVideo();return t?t.currentTime:0}getDuration(){const t=this.getActiveVideo();return t?t.duration:0}getVideoElement(){return this.getActiveVideo()}reset(){this.stopProgressUpdates(),this.preloadedVideos.clear(),this.playbackPositions.clear(),this.currentVideoUrl="",this.nextVideoUrl="",this.activeVideoIndex=0,this.hasUserInteracted=!1,this.lastTimeupdateEvent=0,null!==this.autoplayFallbackTimeout&&(window.clearTimeout(this.autoplayFallbackTimeout),this.autoplayFallbackTimeout=null),this.completionPolicy="auto",this.videoEndedCallback=null,this.transcriptManager.reset(),this.currentVideo&&(this.currentVideo.src="",this.currentVideo.currentTime=0,this.currentVideo.pause()),this.nextVideo&&(this.nextVideo.src="",this.nextVideo.currentTime=0,this.nextVideo.pause())}async destroy(){this.stopProgressUpdates(),this.removeEventListeners(),this.transcriptManager.destroy(),null!==this.autoplayFallbackTimeout&&(window.clearTimeout(this.autoplayFallbackTimeout),this.autoplayFallbackTimeout=null),this.deviceChangeCleanup&&(this.deviceChangeCleanup(),this.deviceChangeCleanup=null),this.container&&this.container.parentNode&&this.container.parentNode.removeChild(this.container),this.currentVideo=null,this.nextVideo=null,this.container=null,this.progressBar=null,this.muteButton=null,this.ccButton=null,this.currentVideoUrl="",this.nextVideoUrl="",this.videoEndedCallback=null}addEventListeners(){const t=this.currentVideo,e=this.nextVideo;if(t&&(t.addEventListener("ended",this.handleVideoEnded),t.addEventListener("timeupdate",this.handleDetailedTimeUpdate),t.addEventListener("error",this.handleVideoError),t.addEventListener("seeking",this.handleSeeking),t.addEventListener("seeked",this.handleSeeked)),e&&(e.addEventListener("ended",this.handleVideoEnded),e.addEventListener("timeupdate",this.handleDetailedTimeUpdate),e.addEventListener("error",this.handleVideoError),e.addEventListener("seeking",this.handleSeeking),e.addEventListener("seeked",this.handleSeeked)),this.container){const t=this.container.querySelector(".sf-video-container__controls");t&&t.addEventListener("click",this.handleProgressBarClick)}}removeEventListeners(){const t=this.currentVideo,e=this.nextVideo;if(t&&(t.removeEventListener("ended",this.handleVideoEnded),t.removeEventListener("timeupdate",this.handleDetailedTimeUpdate),t.removeEventListener("error",this.handleVideoError),t.removeEventListener("seeking",this.handleSeeking),t.removeEventListener("seeked",this.handleSeeked)),e&&(e.removeEventListener("ended",this.handleVideoEnded),e.removeEventListener("timeupdate",this.handleDetailedTimeUpdate),e.removeEventListener("error",this.handleVideoError),e.removeEventListener("seeking",this.handleSeeking),e.removeEventListener("seeked",this.handleSeeked)),this.container){const t=this.container.querySelector(".sf-video-container__controls");t&&t.removeEventListener("click",this.handleProgressBarClick)}}startProgressUpdates(){this.stopProgressUpdates();const t=this.getActiveVideo();if(!t)return;const e=t.loop&&t.muted,n=this.deviceHandler.getProgressUpdateFrequency(e);if(n>=16){const e=()=>{!t||t.paused||t.ended||this.updateProgress(),this.animationFrameId=requestAnimationFrame(e)};this.animationFrameId=requestAnimationFrame(e)}else{const e=()=>{null===this.updateInterval||!t||t.paused||t.ended||(this.updateProgress(),this.updateInterval=window.setTimeout(e,n))};this.updateInterval=window.setTimeout(e,n)}}stopProgressUpdates(){null!==this.updateInterval&&(window.clearInterval(this.updateInterval),this.updateInterval=null),null!==this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null)}updateProgress(){if(!this.progressBar)return;const t=this.getActiveVideo();if(!t)return;const e=t.currentTime||0,n=t.duration||0;if(n>0){const i=e/n*100,s="none"!==this.progressBar.style.transition,r=Date.now()-this.lastTimeupdateEvent;this.progressBar.style.transition="none",this.progressBar.style.width=`${i}%`,this.progressBar.offsetWidth,t.ended?this.progressBar.style.transition="width 0.2s ease-out":!t.paused&&!t.seeking&&s&&r<500&&(this.progressBar.style.transition="width 0.1s linear")}}showButtonsAt90Percent(){if(this.container){const t=new CustomEvent("video90PercentReached",{bubbles:!0,detail:{timestamp:Date.now()}});this.container.dispatchEvent(t)}}setMuted(t){this.currentVideo&&(this.currentVideo.muted=t),this.nextVideo&&(this.nextVideo.muted=t);Pt.getState().setMuted(t),this.updateMuteButtonIcon()}toggleMute(t){const e=this.getActiveVideo();if(!e)return;const n=!e.muted;this.setMuted(n),t&&(t.preventDefault(),t.stopPropagation())}updateMuteButtonIcon(){if(!this.muteButton)return;const t=this.getActiveVideo(),e=!t||t.muted;this.muteButton.innerHTML=e?'\n <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">\n <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5" fill="none"></polygon>\n <line x1="23" y1="9" x2="17" y2="15"></line>\n <line x1="17" y1="9" x2="23" y2="15"></line>\n </svg>\n ':'\n <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">\n <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5" fill="none"></polygon>\n <path d="M15 9c0.8 0.8 1.5 1.9 1.5 3s-0.7 2.2-1.5 3" stroke="currentColor"></path>\n <path d="M19 7c1.6 1.6 2.5 3.8 2.5 6s-0.9 4.4-2.5 6" stroke="currentColor"></path>\n </svg>\n '}isMuted(){const t=this.getActiveVideo();return!t||t.muted}setCompletionPolicy(t,e){this.completionPolicy=t,this.videoEndedCallback=e||null,this.updateVideoEndedHandler()}updateVideoEndedHandler(){}hideProgressBar(){if(this.container){const t=this.container.querySelector(".sf-video-container__controls");t&&(t.style.display="none")}}showProgressBar(){if(this.container){const t=this.container.querySelector(".sf-video-container__controls");if(t){const e=t.closest(".sf-player"),n=null==e?void 0:e.classList.contains("sf-player--minimized");t.style.display=n?"":"block"}}this.progressBar&&(this.progressBar.style.transition="none",this.progressBar.style.width="0%",this.progressBar.offsetWidth,this.progressBar.style.transition="width 0.1s linear");const t=this.getActiveVideo();!t||t.paused||t.ended||this.startProgressUpdates()}hideMuteButton(){this.muteButton&&(this.muteButton.style.display="none")}showMuteButton(){this.muteButton&&(this.muteButton.style.display="block")}markUserInteraction(){this.hasUserInteracted||(this.hasUserInteracted=!0,null!==this.autoplayFallbackTimeout&&(window.clearTimeout(this.autoplayFallbackTimeout),this.autoplayFallbackTimeout=null))}hasUserInteractedWith(){return this.hasUserInteracted}resetUserInteraction(){this.hasUserInteracted=!1,null!==this.autoplayFallbackTimeout&&(window.clearTimeout(this.autoplayFallbackTimeout),this.autoplayFallbackTimeout=null)}handleAutoplayFallbackClick(t){this.markUserInteraction(),t.muted=!1,t.loop=!1,t.currentTime=0}loadTranscript(t){this.transcriptManager.loadTranscript(t)}}class Vt{constructor(){e(this,"cursor",null),e(this,"animationFrameId",null),e(this,"animationStartTime",null),e(this,"currentAnimation",null),e(this,"flashlightOverlay",null),e(this,"startX",null),e(this,"startY",null),e(this,"targetX",null),e(this,"targetY",null),e(this,"shouldShowCursor",!1),e(this,"lastCursorX",50),e(this,"lastCursorY",50),e(this,"isFirstAnimation",!0),e(this,"currentTargetElement",null),e(this,"scrollThrottleTimeout",null),e(this,"boundScrollHandler",null),e(this,"scrollableParents",[]),e(this,"parentScrollHandlers",new Map),e(this,"selectionElement",null),e(this,"isSelectionMode",!1),e(this,"selectionStartWidth",null),e(this,"selectionStartHeight",null),e(this,"selectionTargetWidth",null),e(this,"selectionTargetHeight",null),e(this,"selectionPadding",4),e(this,"dragStartX",null),e(this,"dragStartY",null),e(this,"dragEndX",null),e(this,"dragEndY",null),e(this,"dragPhase","move-to-start"),e(this,"dragAnimationStartTime",null),e(this,"cursorSpeed",.4),e(this,"totalDistance",0),e(this,"controlPointX",null),e(this,"controlPointY",null),e(this,"targetMutationObserver",null)}findScrollableParents(t){const e=[];let n=t.parentElement;for(;n&&n!==document.body;){const t=window.getComputedStyle(n),i=t.overflow,s=t.overflowX,r=t.overflowY;"scroll"!==i&&"auto"!==i&&"scroll"!==s&&"auto"!==s&&"scroll"!==r&&"auto"!==r||(n.scrollHeight>n.clientHeight||n.scrollWidth>n.clientWidth)&&e.push(n),n=n.parentElement}return e}addScrollListenersToParents(t){this.removeScrollListenersFromParents(),this.scrollableParents=this.findScrollableParents(t),this.scrollableParents.forEach((t=>{const e=this.handleScroll.bind(this);this.parentScrollHandlers.set(t,e),t.addEventListener("scroll",e,{passive:!0})}))}removeScrollListenersFromParents(){this.parentScrollHandlers.forEach(((t,e)=>{e.removeEventListener("scroll",t)})),this.parentScrollHandlers.clear(),this.scrollableParents=[]}findElement(t){const e=document.querySelector(t);return e||null}isElementInViewport(t){const e=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,i=window.innerWidth||document.documentElement.clientWidth;if(!(e.top>=0&&e.bottom<=n&&e.left>=0&&e.right<=i))return!1;const s=this.findScrollableParents(t);for(const r of s){const t=r.getBoundingClientRect();if(!(e.top>=t.top&&e.bottom<=t.bottom&&e.left>=t.left&&e.right<=t.right))return!1}return!0}async scrollElementIntoView(t){return new Promise((e=>{const n=this.findScrollableParents(t);if(0===n.length){t.scrollIntoView({behavior:"smooth",block:"center",inline:"center"});let n=null;const i=()=>{null!==n&&clearTimeout(n),n=window.setTimeout((()=>{window.removeEventListener("scroll",i),e()}),100)};window.addEventListener("scroll",i),setTimeout((()=>{window.removeEventListener("scroll",i),null!==n&&clearTimeout(n),e()}),1e3)}else this.scrollParentContainersToShowElement(t,n).then((()=>{this.isElementInViewport(t)||t.scrollIntoView({behavior:"smooth",block:"center",inline:"center"}),setTimeout((()=>{e()}),200)}))}))}async scrollParentContainersToShowElement(t,e){return new Promise((n=>{let i=0;const s=e.length;if(0===s)return void n();const r=()=>{i++,i>=s&&n()};e.forEach(((e,n)=>{const i=t.getBoundingClientRect(),s=e.getBoundingClientRect(),a=e.scrollTop,o=e.scrollLeft,l=a+(i.top-s.top)-s.height/2+i.height/2,c=o+(i.left-s.left)-s.width/2+i.width/2;e.scrollTo({top:Math.max(0,l),left:Math.max(0,c),behavior:"smooth"});let d=null;const h=()=>{null!==d&&clearTimeout(d),d=window.setTimeout((()=>{e.removeEventListener("scroll",h),r()}),100)};e.addEventListener("scroll",h),setTimeout((()=>{e.removeEventListener("scroll",h),null!==d&&clearTimeout(d),r()}),800)}))}))}async findElementAndScrollIntoView(t){const e=this.findElement(t);return e?(this.isElementInViewport(e)||await this.scrollElementIntoView(e),e):null}create(){this.cursor=document.createElement("div"),this.cursor.style.position="fixed",this.cursor.style.top="0",this.cursor.style.left="0",this.cursor.style.width="36px",this.cursor.style.height="36px",this.cursor.style.zIndex="9999999",this.cursor.style.pointerEvents="none",this.cursor.style.display="none",this.cursor.style.transform="translate(-50%, -50%)",this.cursor.innerHTML='\n <svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24" fill="none" stroke="#ff7614" stroke-width="2">\n <path d="M3 3L10.5 21L13.5 13.5L21 10.5L3 3Z" fill="#ff7614" />\n </svg>\n ',this.selectionElement=document.createElement("div"),this.selectionElement.style.position="fixed",this.selectionElement.style.pointerEvents="none",this.selectionElement.style.display="none",this.selectionElement.style.zIndex="9999998",document.body.appendChild(this.cursor),document.body.appendChild(this.selectionElement),this.flashlightOverlay=document.createElement("div"),this.flashlightOverlay.style.position="fixed",this.flashlightOverlay.style.top="0",this.flashlightOverlay.style.left="0",this.flashlightOverlay.style.width="100vw",this.flashlightOverlay.style.height="100vh",this.flashlightOverlay.style.pointerEvents="none",this.flashlightOverlay.style.zIndex="999997",this.flashlightOverlay.style.display="none",this.flashlightOverlay.style.background="radial-gradient(circle 150px at 50% 50%, transparent 0%, rgba(0, 0, 0, 0.4) 100%)",document.body.appendChild(this.flashlightOverlay),this.boundScrollHandler=this.handleScroll.bind(this),window.addEventListener("scroll",this.boundScrollHandler,{passive:!0})}handleScroll(){this.shouldShowCursor&&this.currentTargetElement&&null===this.scrollThrottleTimeout&&(this.scrollThrottleTimeout=window.setTimeout((()=>{var t,e,n,i;if(this.scrollThrottleTimeout=null,null!==this.animationFrameId||!this.currentTargetElement)return;const s=this.currentTargetElement.getBoundingClientRect(),r=s.left+s.width/2,a=s.top+s.height/2;if(this.show(r,a),this.lastCursorX=r,this.lastCursorY=a,this.selectionElement&&this.isSelectionMode){const r="number"==typeof(null==(e=null==(t=this.currentAnimation)?void 0:t.selectionStyles)?void 0:e.padding)?this.currentAnimation.selectionStyles.padding:(null==(i=null==(n=this.currentAnimation)?void 0:n.selectionStyles)?void 0:i.padding)?parseInt(this.currentAnimation.selectionStyles.padding,10):this.selectionPadding,a=Math.floor(s.left-r),o=Math.floor(s.top-r),l=Math.ceil(s.width+2*r),c=Math.ceil(s.height+2*r);this.selectionElement.style.setProperty("--sf-selection-left",`${a}px`),this.selectionElement.style.setProperty("--sf-selection-top",`${o}px`),this.selectionElement.style.setProperty("--sf-selection-width",`${l}px`),this.selectionElement.style.setProperty("--sf-selection-height",`${c}px`),this.dragStartX=a,this.dragStartY=o,this.dragEndX=a+l,this.dragEndY=o+c,this.updateFlashlightWithCutout(a,o,l,c)}}),100))}isAutoplayBlocked(){return"autoplayBlocked"===xt.getState().currentState}setShouldShowCursor(t){if(this.isAutoplayBlocked())return this.shouldShowCursor=!1,void this.hide();this.shouldShowCursor=t,t?this.isFirstAnimation||this.show(this.lastCursorX,this.lastCursorY):this.hide()}show(t,e){this.shouldShowCursor&&(this.isAutoplayBlocked()||(this.lastCursorX=t,this.lastCursorY=e,this.cursor&&(this.cursor.style.display="block",this.cursor.style.top=`${e}px`,this.cursor.style.left=`${t}px`),this.flashlightOverlay&&(this.flashlightOverlay.style.display="block",this.flashlightOverlay.style.background=`radial-gradient(circle 150px at ${t}px ${e}px, transparent 0%, rgba(0, 0, 0, 0.4) 100%)`)))}hide(){this.cursor&&(this.cursor.style.display="none"),this.selectionElement&&(this.selectionElement.style.display="none"),this.flashlightOverlay&&(this.flashlightOverlay.style.display="none",this.resetFlashlightOverlay())}resetFlashlightOverlay(){if(!this.flashlightOverlay)return;this.flashlightOverlay.style.clipPath="none";const t=this.lastCursorX,e=this.lastCursorY;this.flashlightOverlay.style.background=`radial-gradient(circle 150px at ${t}px ${e}px, transparent 0%, rgba(0, 0, 0, 0.4) 100%)`}updateSelectionArea(t,e){if(!this.selectionElement)return;const n=t.getBoundingClientRect(),i="number"==typeof(null==e?void 0:e.padding)?e.padding:(null==e?void 0:e.padding)?parseInt(e.padding,10):this.selectionPadding;this.selectionElement.style.display="block",this.selectionElement.style.left=n.left-i+"px",this.selectionElement.style.top=n.top-i+"px",this.selectionElement.style.width=`${n.width+2*i}px`,this.selectionElement.style.height=`${n.height+2*i}px`,e&&(e.borderColor&&(this.selectionElement.style.borderColor=e.borderColor),e.borderWidth&&(this.selectionElement.style.borderWidth=e.borderWidth),e.borderRadius&&(this.selectionElement.style.borderRadius=e.borderRadius))}async animate(t){if(this.isAutoplayBlocked())return;if(this.setShouldShowCursor(!0),this.stopAnimation(),this.resetFlashlightOverlay(),this.selectionElement&&(this.selectionElement.style.display="none"),!(null==t?void 0:t.targetSelector))return void console.warn("CursorManager: No targetSelector provided in animation");this.targetMutationObserver&&(this.targetMutationObserver.disconnect(),this.targetMutationObserver=null);const e=await this.findElementAndScrollIntoView(t.targetSelector);if(!e){console.warn("CursorManager: Target element not found in animate:",t.targetSelector),this.targetMutationObserver=new MutationObserver((async(e,n)=>{await this.findElementAndScrollIntoView(t.targetSelector)&&(n.disconnect(),this.targetMutationObserver=null,await this.animate(t))})),this.targetMutationObserver.observe(document.body,{childList:!0,subtree:!0});const e=setInterval((()=>{if(!this.targetMutationObserver)return void clearInterval(e);this.findElement(t.targetSelector)&&(clearInterval(e),this.targetMutationObserver.disconnect(),this.targetMutationObserver=null,this.animate(t))}),1e3);return}this.currentTargetElement=e,this.addScrollListenersToParents(e);const n=e.getBoundingClientRect();this.isFirstAnimation?(this.startX=50,this.startY=50,this.isFirstAnimation=!1):(this.startX=this.lastCursorX,this.startY=this.lastCursorY);const i={...t,mode:t.mode||"selection"};if(this.isSelectionMode="selection"===i.mode,this.isSelectionMode)return void this.handleSelectionMode(i,n);{const t=16;this.targetX=n.left+n.width/2+t;const e=16;this.targetY=n.top+n.height/2+e,this.selectionElement&&(this.selectionElement.style.display="none")}null!==this.targetX&&null!==this.targetY&&null!==this.startX&&null!==this.startY?this.totalDistance=Math.sqrt(Math.pow(this.targetX-this.startX,2)+Math.pow(this.targetY-this.startY,2)):this.totalDistance=100,this.calculateControlPoint(),this.currentAnimation={...i};const s=null!==this.startX?this.startX:0,r=null!==this.startY?this.startY:0;this.show(s,r),this.animationStartTime=performance.now(),this.animationFrameId=requestAnimationFrame(this.animationFrame.bind(this))}handleSelectionMode(t,e){var n,i;const s="number"==typeof(null==(n=t.selectionStyles)?void 0:n.padding)?t.selectionStyles.padding:(null==(i=t.selectionStyles)?void 0:i.padding)?parseInt(t.selectionStyles.padding,10):this.selectionPadding;this.dragStartX=Math.floor(e.left-s),this.dragStartY=Math.floor(e.top-s),this.dragEndX=Math.ceil(e.right+s),this.dragEndY=Math.ceil(e.bottom+s),this.dragPhase="move-to-start";this.targetX=this.dragStartX+8,this.targetY=this.dragStartY+8,null!==this.targetX&&null!==this.targetY&&null!==this.startX&&null!==this.startY?this.totalDistance=Math.sqrt(Math.pow(this.targetX-this.startX,2)+Math.pow(this.targetY-this.startY,2)):this.totalDistance=100,this.selectionElement&&(t.selectionStyles&&(t.selectionStyles.borderColor&&this.selectionElement.style.setProperty("--sf-selection-border-color",t.selectionStyles.borderColor),t.selectionStyles.borderWidth&&this.selectionElement.style.setProperty("--sf-selection-border-width",t.selectionStyles.borderWidth),t.selectionStyles.borderRadius&&this.selectionElement.style.setProperty("--sf-selection-border-radius",t.selectionStyles.borderRadius)),this.selectionElement.style.display="none"),this.calculateControlPoint(),this.currentAnimation={...t};const r=null!==this.startX?this.startX:0,a=null!==this.startY?this.startY:0;this.show(r,a),this.animationStartTime=performance.now(),this.animationFrameId=requestAnimationFrame(this.dragAnimationFrame.bind(this))}dragAnimationFrame(t){var e,n;if(!this.animationStartTime||!this.currentAnimation)return void this.stopAnimation();const i=this.targetX||0,s=this.targetY||0;if(this.currentTargetElement&&"release"!==this.dragPhase){const t=this.currentTargetElement.getBoundingClientRect(),r="number"==typeof(null==(e=this.currentAnimation.selectionStyles)?void 0:e.padding)?this.currentAnimation.selectionStyles.padding:(null==(n=this.currentAnimation.selectionStyles)?void 0:n.padding)?parseInt(this.currentAnimation.selectionStyles.padding,10):this.selectionPadding;if(this.dragStartX=Math.floor(t.left-r),this.dragStartY=Math.floor(t.top-r),this.dragEndX=Math.ceil(t.right+r),this.dragEndY=Math.ceil(t.bottom+r),"move-to-start"===this.dragPhase){const t=8,e=8;this.targetX=this.dragStartX+t,this.targetY=this.dragStartY+e;const n=Math.abs(i-this.targetX),r=Math.abs(s-this.targetY);n>10||r>10?this.calculateControlPoint():null!==this.startX&&null!==this.startY&&(this.totalDistance=Math.sqrt(Math.pow(this.targetX-this.startX,2)+Math.pow(this.targetY-this.startY,2)))}}if("move-to-start"===this.dragPhase){if(!(this.startX&&this.startY&&this.targetX&&this.targetY&&this.controlPointX&&this.controlPointY))return void this.stopAnimation();const e=t-this.animationStartTime,n=this.cursorSpeed*e;if(n>=this.totalDistance)return this.show(this.targetX,this.targetY),this.lastCursorX=this.targetX,this.lastCursorY=this.targetY,this.dragPhase="dragging",this.dragAnimationStartTime=performance.now(),this.cursor&&(this.cursor.style.transform="scale(0.9) translate(-50%, -50%)",this.cursor.style.opacity="0.9"),this.selectionElement&&(this.selectionElement.style.left=`${this.dragStartX}px`,this.selectionElement.style.top=`${this.dragStartY}px`,this.selectionElement.style.width="0px",this.selectionElement.style.height="0px",this.selectionElement.style.display="block"),void(this.animationFrameId=requestAnimationFrame(this.dragAnimationFrame.bind(this)));let i=this.totalDistance>0?n/this.totalDistance:1;i=Math.min(i,1);const s=.5-.5*Math.cos(i*Math.PI),r=1-s,a=Math.pow(r,2)*this.startX+2*r*s*this.controlPointX+Math.pow(s,2)*this.targetX,o=Math.pow(r,2)*this.startY+2*r*s*this.controlPointY+Math.pow(s,2)*this.targetY;this.show(a,o)}else if("dragging"===this.dragPhase){if(!(this.dragAnimationStartTime&&this.dragStartX&&this.dragStartY&&this.dragEndX&&this.dragEndY))return void this.stopAnimation();const e=1e3,n=t-this.dragAnimationStartTime;let i=Math.min(n/e,1);const s=.5-.5*Math.cos(i*Math.PI),r=8,a=8,o=this.dragStartX+(this.dragEndX-this.dragStartX)*s+r,l=this.dragStartY+(this.dragEndY-this.dragStartY)*s+a;if(this.show(o,l),this.selectionElement){let t=Math.ceil(Math.abs(o-r-this.dragStartX)),e=Math.ceil(Math.abs(l-a-this.dragStartY)),n=Math.floor(Math.min(this.dragStartX,o-r)),i=Math.floor(Math.min(this.dragStartY,l-a));this.selectionElement.style.left=`${n}px`,this.selectionElement.style.top=`${i}px`,this.selectionElement.style.width=`${t}px`,this.selectionElement.style.height=`${e}px`,this.selectionElement.style.display="block",this.updateFlashlightWithCutout(n,i,t,e)}i>=1&&(this.dragPhase="release",this.cursor&&(this.cursor.style.transform="translate(-50%, -50%)",this.cursor.style.opacity="1"),null!==this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.animationStartTime=null,this.dragAnimationStartTime=null)}"release"!==this.dragPhase&&(this.animationFrameId=requestAnimationFrame(this.dragAnimationFrame.bind(this)))}updateFlashlightWithCutout(t,e,n,i){if(!this.flashlightOverlay)return;const s=`\n polygon(\n 0% 0%, /* Top-left of screen */\n 100% 0%, /* Top-right of screen */\n 100% 100%, /* Bottom-right of screen */\n 0% 100%, /* Bottom-left of screen */\n 0% ${e}px, /* Begin cutout: bottom-left of cutout */\n ${t}px ${e}px, /* Bottom-left of cutout */\n ${t}px ${e+i}px, /* Top-left of cutout */\n ${t+n}px ${e+i}px, /* Top-right of cutout */\n ${t+n}px ${e}px, /* Bottom-right of cutout */\n 0% ${e}px /* Close cutout path */\n )\n `;this.flashlightOverlay.style.clipPath=s;const r=this.lastCursorX,a=this.lastCursorY;this.flashlightOverlay.style.background=`radial-gradient(circle 150px at ${r}px ${a}px, transparent 0%, rgba(0, 0, 0, 0.4) 100%)`}calculateControlPoint(){if(!(this.startX&&this.startY&&this.targetX&&this.targetY))return void console.warn("CursorManager: Missing start or target position for control point calculation",{startX:this.startX,startY:this.startY,targetX:this.targetX,targetY:this.targetY});const t=(this.startX+this.targetX)/2,e=(this.startY+this.targetY)/2,n=Math.sqrt(Math.pow(this.targetX-this.startX,2)+Math.pow(this.targetY-this.startY,2));this.totalDistance=n;const i=.2*n,s=(Math.random()-.5)*i*2,r=this.targetX-this.startX,a=-(this.targetY-this.startY),o=r,l=Math.sqrt(a*a+o*o);if(0===l)this.controlPointX=t+5,this.controlPointY=e+5;else{const n=a/l,i=o/l;this.controlPointX=t+n*s,this.controlPointY=e+i*s}}async moveToElement(t,e,n){if(this.isAutoplayBlocked())return;if(!this.shouldShowCursor)return;this.stopAnimation(),this.resetFlashlightOverlay(),this.targetMutationObserver&&(this.targetMutationObserver.disconnect(),this.targetMutationObserver=null);const i=await this.findElementAndScrollIntoView(t);if(!i){console.warn("CursorManager: Target element not found:",t),this.targetMutationObserver=new MutationObserver((async(i,s)=>{await this.findElementAndScrollIntoView(t)&&(s.disconnect(),this.targetMutationObserver=null,await this.moveToElement(t,e,n))})),this.targetMutationObserver.observe(document.body,{childList:!0,subtree:!0});const i=setInterval((()=>{if(!this.targetMutationObserver)return void clearInterval(i);this.findElement(t)&&(clearInterval(i),this.targetMutationObserver.disconnect(),this.targetMutationObserver=null,this.moveToElement(t,e,n))}),1e3);return}i.getBoundingClientRect(),this.currentTargetElement=i,this.addScrollListenersToParents(i);const s={targetSelector:t,mode:e||"selection",selectionStyles:n};this.animate(s)}click(){this.isAutoplayBlocked()||this.shouldShowCursor&&(this.cursor?(this.cursor.style.transform="scale(0.8) translate(-50%, -50%)",this.cursor.style.opacity="0.8",setTimeout((()=>{if(this.cursor){if(!this.shouldShowCursor||this.isAutoplayBlocked())return void this.hide();this.cursor.style.transform="translate(-50%, -50%)",this.cursor.style.opacity="1"}else console.warn("CursorManager: Cursor element was removed during click animation")}),300)):console.warn("CursorManager: Cannot apply click animation - cursor element is null"))}stopAnimation(){null!==this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.animationStartTime=null,this.currentAnimation=null,this.controlPointX=null,this.controlPointY=null,this.selectionStartWidth=null,this.selectionStartHeight=null,this.selectionTargetWidth=null,this.selectionTargetHeight=null,this.dragPhase="move-to-start",this.dragAnimationStartTime=null,this.cursor&&(this.cursor.style.transform="translate(-50%, -50%)",this.cursor.style.opacity="1"),this.resetFlashlightOverlay(),this.selectionElement&&(this.selectionElement.style.display="none")}getCursorX(){if(this.cursor){const t=this.cursor.style.transform.match(/translate\((\d+)px, \d+px\)/);return t?parseInt(t[1],10):this.lastCursorX}return this.lastCursorX}getCursorY(){if(this.cursor){const t=this.cursor.style.transform.match(/translate\(\d+px, (\d+)px\)/);return t?parseInt(t[1],10):this.lastCursorY}return this.lastCursorY}resetFirstAnimation(){this.isFirstAnimation=!0}reset(){this.stopAnimation(),this.currentAnimation=null,this.animationStartTime=null,this.startX=null,this.startY=null,this.targetX=null,this.targetY=null,this.currentTargetElement=null,this.isFirstAnimation=!0,this.shouldShowCursor=!1,this.cursor&&(this.cursor.style.display="none"),this.isSelectionMode=!1,this.selectionElement&&(this.selectionElement.style.display="none"),this.dragStartX=null,this.dragStartY=null,this.dragEndX=null,this.dragEndY=null,this.dragPhase="move-to-start",this.dragAnimationStartTime=null,null!==this.scrollThrottleTimeout&&(window.clearTimeout(this.scrollThrottleTimeout),this.scrollThrottleTimeout=null),this.removeScrollListenersFromParents(),this.scrollableParents=[]}async destroy(){this.stopAnimation(),this.boundScrollHandler&&(window.removeEventListener("scroll",this.boundScrollHandler),this.boundScrollHandler=null),this.removeScrollListenersFromParents(),null!==this.scrollThrottleTimeout&&(window.clearTimeout(this.scrollThrottleTimeout),this.scrollThrottleTimeout=null),this.cursor&&this.cursor.parentNode&&(this.cursor.remove(),this.cursor=null),this.selectionElement&&this.selectionElement.parentNode&&(this.selectionElement.remove(),this.selectionElement=null),this.flashlightOverlay&&this.flashlightOverlay.parentNode&&(this.flashlightOverlay.remove(),this.flashlightOverlay=null),this.isFirstAnimation=!0,this.shouldShowCursor=!1,this.currentTargetElement=null,this.isSelectionMode=!1,this.targetMutationObserver&&(this.targetMutationObserver.disconnect(),this.targetMutationObserver=null),document.documentElement.style.removeProperty("--sf-cursor-x"),document.documentElement.style.removeProperty("--sf-cursor-y")}animationFrame(t){var e,n,i;if(!(this.animationStartTime&&this.currentAnimation&&this.startX&&this.startY&&this.targetX&&this.targetY&&this.controlPointX&&this.controlPointY))return console.warn("CursorManager: Animation frame missing essential data, stopping animation"),void this.stopAnimation();const s=this.targetX||0,r=this.targetY||0;if(this.currentTargetElement){const t=this.currentTargetElement.getBoundingClientRect();if(this.isSelectionMode){const i="number"==typeof(null==(e=this.currentAnimation.selectionStyles)?void 0:e.padding)?this.currentAnimation.selectionStyles.padding:(null==(n=this.currentAnimation.selectionStyles)?void 0:n.padding)?parseInt(this.currentAnimation.selectionStyles.padding,10):this.selectionPadding;this.dragStartX=Math.floor(t.left-i),this.dragStartY=Math.floor(t.top-i),this.dragEndX=Math.ceil(t.right+i),this.dragEndY=Math.ceil(t.bottom+i)}else{const e=16,n=16;this.targetX=t.left+t.width/2+e,this.targetY=t.top+t.height/2+n;const i=Math.abs(s-this.targetX),a=Math.abs(r-this.targetY);i>10||a>10?this.calculateControlPoint():null!==this.startX&&null!==this.startY&&(this.totalDistance=Math.sqrt(Math.pow(this.targetX-this.startX,2)+Math.pow(this.targetY-this.startY,2)))}}const a=t-this.animationStartTime,o=this.cursorSpeed*a;if(o>=this.totalDistance)return this.show(this.targetX,this.targetY),this.lastCursorX=this.targetX,this.lastCursorY=this.targetY,this.isSelectionMode&&this.currentTargetElement&&this.selectionElement?this.updateSelectionArea(this.currentTargetElement,this.currentAnimation.selectionStyles):this.click(),void setTimeout((()=>{this.stopAnimation()}),400);let l=this.totalDistance>0?o/this.totalDistance:1;l=Math.min(l,1);const c=.5-.5*Math.cos(l*Math.PI),d=c,h=1-d,u=Math.pow(h,2)*this.startX+2*h*d*this.controlPointX+Math.pow(d,2)*this.targetX,p=Math.pow(h,2)*this.startY+2*h*d*this.controlPointY+Math.pow(d,2)*this.targetY;if(this.show(u,p),this.isSelectionMode&&this.selectionElement&&null!==this.selectionStartWidth&&null!==this.selectionStartHeight&&null!==this.selectionTargetWidth&&null!==this.selectionTargetHeight){const t=this.selectionStartWidth+(this.selectionTargetWidth-this.selectionStartWidth)*c,e=this.selectionStartHeight+(this.selectionTargetHeight-this.selectionStartHeight)*c,n=null==(i=this.currentTargetElement)?void 0:i.getBoundingClientRect();n&&this.currentTargetElement&&(this.selectionElement.style.left=n.left+n.width/2-t/2+"px",this.selectionElement.style.top=n.top+n.height/2-e/2+"px",this.selectionElement.style.width=`${t}px`,this.selectionElement.style.height=`${e}px`,c>.9&&this.updateSelectionArea(this.currentTargetElement,this.currentAnimation.selectionStyles))}this.animationFrameId=requestAnimationFrame(this.animationFrame.bind(this))}setColor(t){if(this.cursor){const e=this.cursor.querySelector("svg");if(e){e.setAttribute("stroke",t);const n=e.querySelector("path");n?n.setAttribute("fill",t):console.warn("[CursorManager.setColor] No path found in SVG")}else console.warn("[CursorManager.setColor] No SVG found in cursor")}else console.warn("[CursorManager.setColor] No cursor element")}}class Lt{constructor(){e(this,"container",null),e(this,"buttons",[]),e(this,"buttonContainer",null),e(this,"domEventListeners",new Map),e(this,"storeUnsubscribe",null),e(this,"handleVideo90PercentReached",(t=>{this.showButtonsAt90Percent()}))}create(t){this.container=t,this.storeUnsubscribe=Pt.subscribe(((t,e)=>{t.isMinimized!==(null==e?void 0:e.isMinimized)&&this.updateButtonPositions()})),t.addEventListener("video90PercentReached",this.handleVideo90PercentReached)}createButtons(t){if(!this.container)return;this.clearButtons(),this.buttonContainer=document.createElement("div"),this.buttonContainer.className="sf-choice-buttons-container",this.container.appendChild(this.buttonContainer),t.forEach((t=>{const e=document.createElement("button");e.textContent=t.text,e.dataset.buttonId=t.id,e.className=`sf-choice-button sf-choice-button--${t.action.type}`,t.style&&Object.entries(t.style).forEach((([t,n])=>{e.style.setProperty(`--custom-${t}`,String(n))})),e.addEventListener("click",(async e=>{await this.handleButtonClick(e,t)})),this.buttonContainer&&(this.buttonContainer.appendChild(e),this.buttons.push(e),t.id)}));Pt.getState().isMinimized&&(this.buttonContainer.style.display="none")}showButtonsAt90Percent(){this.buttons.length>0&&this.buttons.forEach(((t,e)=>{t.classList.add("sf-show-button")}))}clearButtons(){this.buttons.forEach((t=>{t.parentElement&&t.parentElement.removeChild(t)})),this.buttonContainer&&this.buttonContainer.parentElement&&this.buttonContainer.parentElement.removeChild(this.buttonContainer),this.buttons=[],this.buttonContainer=null}updateButtonPositions(){if(!this.buttonContainer||0===this.buttons.length)return;Pt.getState().isMinimized?this.buttonContainer.style.display="none":(this.buttonContainer.style.display="flex",this.buttonContainer.className="sf-choice-buttons-container")}setupDOMInteractions(t){this.clearDOMInteractions(),t.forEach(((t,e)=>{try{const n=document.querySelectorAll(t.selector);if(0===n.length)return void t.selector;n.length,t.selector,n.forEach(((n,i)=>{const s=n,r=`dom-interaction-${e}-${i}-${Date.now()}`,a=e=>{this.handleDOMInteraction(e,t)};s.addEventListener(t.action,a),this.domEventListeners.set(r,{element:s,listener:a,type:t.action}),t.action,t.selector}))}catch(n){console.error(`InteractionManager: Error setting up DOM interaction for selector "${t.selector}":`,n)}}))}clearDOMInteractions(){this.domEventListeners.forEach((({element:t,listener:e,type:n})=>{try{t.removeEventListener(n,e)}catch(i){console.error("InteractionManager: Error removing event listener:",i)}})),this.domEventListeners.clear()}async handleButtonClick(t,e){e.id,t.preventDefault(),t.stopPropagation();const n=Pt.getState();switch(e.action.type){case"next":n.play();break;case"goto":e.action.target,n.goToStep(e.action.target);break;case"url":if(e.action.target,await this.flushAnalytics(),"completedWaitingForInteraction"===n.currentState){const t=n.stateMachine.send({type:"COMPLETE_PLAYLIST"});n.currentState=t,await new Promise((t=>setTimeout(t,100)))}else{this.isCurrentStepLast(n)&&(n.goToStep("completed"),await new Promise((t=>setTimeout(t,100))))}window.open(e.action.target,"_blank");const{SaltfishPlayer:t}=await Promise.resolve().then((()=>ae)),s=t.getInstance();s&&s.destroy();break;case"dom":e.action.target;const r=document.querySelector(e.action.target);r?r.click():e.action.target;break;case"function":e.action.target;try{const t=new Function(`return ${e.action.target}`)();"function"==typeof t?t():e.action.target}catch(i){console.error(`InteractionManager: Error calling function "${e.action.target}":`,i)}break;default:e.action.type}if(n.manifest){const t={buttonId:e.id,actionType:e.action.type,actionTarget:e.action.target};JSON.stringify(t)}}handleDOMInteraction(t,e){if(e.action,e.selector,e.waitFor&&(t.preventDefault(),t.stopPropagation(),e.selector),"input"===e.action&&e.value){const n=t.target;n&&(n.value=e.value,e.value)}if(Pt.getState().manifest){const t={selector:e.selector,action:e.action,value:e.value};JSON.stringify(t)}}isCurrentStepLast(t){if(!t.manifest||!t.currentStepId||!t.manifest.steps)return!1;const e=t.manifest.steps;return e.findIndex((e=>e.id===t.currentStepId))===e.length-1}async flushAnalytics(){try{const{SaltfishPlayer:t}=await Promise.resolve().then((()=>ae)),e=t.getInstance();if(e&&e.analyticsManager){const t=e.analyticsManager;"function"==typeof t.flush&&await t.flush()}}catch(t){}}destroy(){this.storeUnsubscribe&&(this.storeUnsubscribe(),this.storeUnsubscribe=null),this.container&&this.container.removeEventListener("video90PercentReached",this.handleVideo90PercentReached),this.clearButtons(),this.clearDOMInteractions(),this.container=null}}class Bt{constructor(t){e(this,"config",null),e(this,"user",null),e(this,"eventQueue",[]),e(this,"isSending",!1),e(this,"flushInterval",null),e(this,"eventManager",null),e(this,"sessionId",null),e(this,"analyticsEnabled",!0),t&&this.setEventManager(t)}setEventManager(t){this.eventManager=t,this.subscribeToEvents()}subscribeToEvents(){this.eventManager&&(this.eventManager.on("playerPaused",(t=>{const e=this.getStore(),n=this.getRunId();(null==e?void 0:e.manifest)&&e.currentStepId&&n&&this.trackEvent({type:"playerPaused",playlistId:e.manifest.id,stepId:e.currentStepId,runId:n,timestamp:Date.now()})})),this.eventManager.on("playerResumed",(t=>{const e=this.getStore(),n=this.getRunId();(null==e?void 0:e.manifest)&&e.currentStepId&&n&&this.trackEvent({type:"playerResumed",playlistId:e.manifest.id,stepId:e.currentStepId,runId:n,timestamp:Date.now()})})),this.eventManager.on("stepStarted",(t=>{t.step.id,this.trackStepStarted(t.playlist.id,t.step.id)})),this.eventManager.on("stepEnded",(t=>{t.step.id,this.trackStepComplete(t.playlist.id,t.step.id)})),this.eventManager.on("playlistEnded",(t=>{t.playlist.id,this.trackPlaylistComplete(t.playlist.id)})),this.eventManager.on("error",(t=>{t.playlistId&&this.trackError(t.playlistId,t.error,t.stepId,t.errorType)})),this.eventManager.on("playerMinimized",(t=>{const e=this.getStore(),n=this.getRunId();(null==e?void 0:e.manifest)&&e.currentStepId&&n&&this.trackEvent({type:"playerMinimized",playlistId:e.manifest.id,stepId:e.currentStepId,runId:n,timestamp:Date.now()})})),this.eventManager.on("playerMaximized",(t=>{const e=this.getStore(),n=this.getRunId();(null==e?void 0:e.manifest)&&e.currentStepId&&n&&this.trackEvent({type:"playerMaximized",playlistId:e.manifest.id,stepId:e.currentStepId,runId:n,timestamp:Date.now()})})))}getStore(){try{return Pt.getState()}catch(t){return console.error("Failed to access store:",t),null}}initialize(t,e){this.config=t,this.analyticsEnabled=!1!==t.enableAnalytics,e&&(this.sessionId=e),this.analyticsEnabled&&(this.flushInterval=window.setInterval((()=>{this.flushEvents()}),3e4))}setUser(t){this.user=t}trackPlaylistStart(t){if(!this.analyticsEnabled)return;const e=this.getRunId();e&&this.trackEvent({type:"playlistStart",playlistId:t,runId:e,timestamp:Date.now()})}trackPlaylistComplete(t){if(!this.analyticsEnabled)return;const e=this.getRunId();e&&this.trackEvent({type:"playlistComplete",playlistId:t,runId:e,timestamp:Date.now()})}trackStepStarted(t,e){if(!this.analyticsEnabled)return;const n=this.getRunId();n&&this.trackEvent({type:"stepStarted",playlistId:t,stepId:e,runId:n,timestamp:Date.now()})}trackStepComplete(t,e){if(!this.analyticsEnabled)return;const n=this.getRunId();n&&this.trackEvent({type:"stepComplete",playlistId:t,stepId:e,runId:n,timestamp:Date.now()})}trackInteraction(t,e,n){if(!this.analyticsEnabled)return;const i=this.getRunId();i&&this.trackEvent({type:"interaction",playlistId:t,stepId:e,runId:i,timestamp:Date.now(),data:n})}trackError(t,e,n,i){if(!this.analyticsEnabled)return;const s=this.getRunId();s&&this.trackEvent({type:"error",playlistId:t,stepId:n,runId:s,timestamp:Date.now(),data:{message:e.message,stack:e.stack,errorType:i||"unknown"}})}trackEvent(t){this.analyticsEnabled&&(this.eventQueue.push(t),this.eventQueue.length>=10&&this.flushEvents())}async flush(){await this.flushEvents()}async flushEvents(){if(!this.isSending&&0!==this.eventQueue.length&&this.config&&this.analyticsEnabled){this.isSending=!0;try{const t=[...this.eventQueue];this.eventQueue=[];const e={token:this.config.token,sessionId:this.sessionId,user:this.user,events:t},n=await fetch("https://player.saltfish.ai/analytics",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!n.ok)throw this.eventQueue=[...t,...this.eventQueue],new Error(`Failed to send analytics events: ${n.statusText}`)}catch(t){console.error("Failed to send analytics events:",t)}finally{this.isSending=!1}}}destroy(){this.analyticsEnabled&&this.flushEvents(),null!==this.flushInterval&&(clearInterval(this.flushInterval),this.flushInterval=null),this.eventManager&&(this.eventManager=null),this.config=null,this.user=null,this.eventQueue=[],this.sessionId=null,this.analyticsEnabled=!0}getRunId(){try{return re.getInstance().getRunId()}catch(t){return null}}}class Ot{constructor(){e(this,"initialized",!1),e(this,"sessionId",null),e(this,"userId",null),e(this,"clientId",null),e(this,"isRecording",!1)}initialize(t,e,n){this.sessionId=e,this.userId=n||null,this.clientId=t.token,this.clientId,t.sessionRecording&&!this.initialized&&this.loadSaltfishRecordingScript().then((()=>{this.startRecording()})).catch((t=>{}))}loadSaltfishRecordingScript(){return new Promise(((t,e)=>{if("undefined"!=typeof window&&window.saltfishRecording)t();else try{if("undefined"!=typeof window){const n=document.createElement("script");n.type="text/javascript",n.crossOrigin="anonymous",n.async=!0,n.src="https://storage.saltfish.ai/recording/recorder.js",n.onload=()=>{this.initialized=!0,t()},n.onerror=t=>{e(t)},document.head.appendChild(n)}else e(new Error("Window is not defined"))}catch(n){e(n)}}))}startRecording(){if(this.initialized&&this.sessionId&&!this.isRecording&&"undefined"!=typeof window&&window.saltfishRecording){this.sessionId,this.userId,this.clientId;const t={sessionId:this.sessionId,clientId:this.clientId};this.userId&&(t.userId=this.userId),window.saltfishRecording.start(t),this.isRecording=!0}}identifyUser(t){if(this.userId=t.id,this.initialized){if(t.id,this.sessionId,this.isRecording&&"undefined"!=typeof window&&window.saltfishRecording){window.saltfishRecording.stop(),this.isRecording=!1;const t={sessionId:this.sessionId,clientId:this.clientId,userId:this.userId};window.saltfishRecording.start(t),this.isRecording=!0,this.sessionId,this.userId,this.clientId}}else t.id}stopRecording(){this.isRecording&&"undefined"!=typeof window&&window.saltfishRecording&&(window.saltfishRecording.stop(),this.isRecording=!1)}isCurrentlyRecording(){return this.isRecording}}class Ut{constructor(){e(this,"sessionId"),e(this,"currentRunId",null),this.sessionId=this.getOrCreateSession(),this.sessionId}getOrCreateSession(){if("undefined"==typeof window)return this.generateUniqueId();try{const t=localStorage.getItem(tt);if(t){const e=JSON.parse(t);if(Date.now()-e.lastActivity<ct)return e.sessionId,this.updateSessionActivity(e.sessionId),e.sessionId}}catch(e){}const t=this.generateUniqueId();return this.updateSessionActivity(t),t}updateSessionActivity(t){if("undefined"!=typeof window)try{const e={sessionId:t,lastActivity:Date.now()};localStorage.setItem(tt,JSON.stringify(e))}catch(e){}}generateUniqueId(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(t){const e=16*Math.random()|0;return("x"===t?e:3&e|8).toString(16)}))}getSessionId(){return this.updateSessionActivity(this.sessionId),this.sessionId}startNewRun(){return this.currentRunId=this.generateUniqueId(),this.currentRunId,this.updateSessionActivity(this.sessionId),this.currentRunId}getCurrentRunId(){return this.currentRunId}endCurrentRun(){this.currentRunId&&(this.currentRunId,this.currentRunId=null)}expireSession(){"undefined"!=typeof window&&(localStorage.removeItem(tt),this.sessionId),this.sessionId=this.generateUniqueId(),this.updateSessionActivity(this.sessionId),this.currentRunId=null,this.sessionId}destroy(){this.updateSessionActivity(this.sessionId),this.endCurrentRun()}}class Ft{constructor(){e(this,"playbackButtonsVisible",!1),e(this,"rootElement",null),e(this,"playButton",null),e(this,"centerPlayButton",null),e(this,"videoManager",null),e(this,"storeUnsubscribe",null)}initialize(t,e){t?(this.rootElement=t,this.videoManager=e,this.storeUnsubscribe=Pt.subscribe((t=>{this.updatePlayPauseButton(t.currentState)})),this.playButton=t.querySelector(".sf-controls-container__play-button"),this.centerPlayButton=t.querySelector(".sf-player__center-play-button"),this.centerPlayButton||(this.centerPlayButton=document.createElement("button"),this.centerPlayButton.className="sf-player__center-play-button",this.centerPlayButton.innerHTML='\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M8 5v14l11-7z" fill="currentColor"/>\n </svg>\n ',t.appendChild(this.centerPlayButton),this.centerPlayButton.addEventListener("click",(t=>{var e;t.stopPropagation(),t.preventDefault();const n=Pt.getState();if("autoplayBlocked"===n.currentState)if(this.videoManager){this.videoManager.markUserInteraction(),this.videoManager.setMuted(!1);const t=this.videoManager.getVideoElement();t&&(t.loop=!1,t.currentTime=0)}else{const t=null==(e=this.rootElement)?void 0:e.querySelector(".sf-video-container__video");t&&(t.muted=!1,t.loop=!1,t.currentTime=0)}else this.videoManager&&this.videoManager.markUserInteraction();"paused"!==n.currentState&&"waitingForInteraction"!==n.currentState&&"autoplayBlocked"!==n.currentState&&"error"!==n.currentState||n.play()}))),this.playButton||console.error("ButtonManager: Failed to find play button during initialization"),this.centerPlayButton):console.error("ButtonManager: Cannot initialize with null element")}displayPlaybackButtons(t){this.playbackButtonsVisible!==t&&(this.playbackButtonsVisible=t)}updatePlayPauseButton(t){if(this.playButton&&(this.playButton.style.display="none"),!this.centerPlayButton){if(!this.rootElement)return;this.centerPlayButton=this.rootElement.querySelector(".sf-player__center-play-button"),this.centerPlayButton||(this.centerPlayButton=document.createElement("button"),this.centerPlayButton.className="sf-player__center-play-button",this.centerPlayButton.innerHTML='\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M8 5v14l11-7z" fill="currentColor"/>\n </svg>\n ',this.rootElement.appendChild(this.centerPlayButton),this.centerPlayButton.addEventListener("click",(t=>{var e;t.stopPropagation(),t.preventDefault();const n=Pt.getState();if("autoplayBlocked"===n.currentState)if(this.videoManager){this.videoManager.markUserInteraction(),this.videoManager.setMuted(!1);const t=this.videoManager.getVideoElement();t&&(t.loop=!1,t.currentTime=0)}else{const t=null==(e=this.rootElement)?void 0:e.querySelector(".sf-video-container__video");t&&(t.muted=!1,t.loop=!1,t.currentTime=0)}else this.videoManager&&this.videoManager.markUserInteraction();"paused"!==n.currentState&&"waitingForInteraction"!==n.currentState&&"autoplayBlocked"!==n.currentState&&"error"!==n.currentState||n.play()})))}"playing"===t||"completedWaitingForInteraction"===t||"completed"===t?this.centerPlayButton.style.display="none":(this.centerPlayButton.style.display="flex","autoplayBlocked"===t&&(this.centerPlayButton.style.opacity="1",this.centerPlayButton.style.pointerEvents="auto"))}destroy(){this.storeUnsubscribe&&(this.storeUnsubscribe(),this.storeUnsubscribe=null),this.playbackButtonsVisible=!1,this.rootElement=null,this.playButton=null,this.centerPlayButton=null,this.videoManager=null}}class Rt{constructor(){e(this,"activeTransitions",new Map),e(this,"waitingForInteraction",!1),e(this,"triggerManager",null),e(this,"handleURLChange",(()=>{this.triggerManager&&this.triggerManager.evaluateAllTriggers();const t=Array.from(this.activeTransitions.entries()).filter((([t,e])=>{var n;return"url-path"===(null==(n=e.data)?void 0:n.type)}));if(0!==t.length)for(const[e,n]of t){if(!n.data)continue;const{pattern:t,nextStepId:e}=n.data;if(this.isURLPathMatch(t)){this.triggerTransition(e);break}}})),window.addEventListener("popstate",this.handleURLChange),this.monitorHistoryChanges()}setTriggerManager(t){this.triggerManager=t}monitorHistoryChanges(){const t=history.pushState,e=history.replaceState;history.pushState=(...e)=>{t.apply(history,e),this.handleURLChange()},history.replaceState=(...t)=>{e.apply(history,t),this.handleURLChange()}}setupTransitions(t,e=!1){this.cleanupTransitions(),t.id,t.transitions.forEach((t=>{switch(t.type){case"dom-click":this.setupDOMClickTransition(t);break;case"timeout":this.setupTimeoutTransition(t,e);break;case"url-path":this.setupURLPathTransition(t);break;case"dom-element-visible":this.setupDOMElementVisibleTransition(t);break;default:t.type}}))}setupDOMClickTransition(t){if(!t.target)return;const e=t.target,n=t.nextStep,i=`dom-click-${e}-${Date.now()}`,s=new Map;let r=null;const a=t=>{0!==t.length&&(t.length,t.forEach((t=>{if(s.has(t))return;const e=t=>{this.triggerTransition(n)};s.set(t,e),t.addEventListener("click",e)})))},o=document.querySelectorAll(e);a(o),r=new MutationObserver((t=>{for(const n of t)"childList"===n.type&&n.addedNodes.forEach((t=>{if(t.nodeType===Node.ELEMENT_NODE){const n=t;n.matches(e)&&a([n]);const i=n.querySelectorAll(e);i.length>0&&(i.length,a(i))}}))})),r.observe(document.body,{childList:!0,subtree:!0}),this.activeTransitions.set(i,{handlers:s,cleanup:()=>{s.forEach(((t,e)=>{e.removeEventListener("click",t)})),s.clear(),r&&(r.disconnect(),r=null)},data:{type:"dom-click",pattern:e,nextStepId:n}})}setupTimeoutTransition(t,e){const n=t.nextStep,i=t.timeout||0,s=`timeout-${i}-${Date.now()}`;let r=null;e?this.triggerTransition(n):i>0&&(r=window.setTimeout((()=>{this.triggerTransition(n)}),i)),this.activeTransitions.set(s,{handlers:new Map,cleanup:()=>{null!==r&&(clearTimeout(r),r=null)},data:{type:"timeout",pattern:"",nextStepId:n}})}setupURLPathTransition(t){if(!t.target)return;const e=t.target,n=t.nextStep;if(this.isURLPathMatch(e)){this.triggerTransition(n);const t=5;let e=0;const i=()=>{if(e>=t)return;e++;const s=Pt.getState();"waitingForInteraction"===s.currentState||"playing"===s.currentState?(s.currentState,this.triggerTransition(n)):e<t&&(s.currentState,setTimeout(i,500))};setTimeout(i,500)}const i=`url-path-${Date.now()}`,s=window.setInterval((()=>{this.isURLPathMatch(e)&&(clearInterval(s),this.triggerTransition(n))}),5e3);this.activeTransitions.set(i,{handlers:new Map,cleanup:()=>{clearInterval(s)},data:{type:"url-path",pattern:e,nextStepId:n}})}isURLPathMatch(t){if(!t)return!1;const e=window.location.href.split("#")[0],n=window.location.pathname,i=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/\\\*/g,".*"),s=new RegExp(i),r=s.test(e),a=s.test(n);return r||a}triggerTransition(t){var e;const n=Pt.getState(),i=n.currentState;n.currentStepId;const s=n.isMinimized;"playing"!==i&&"waitingForInteraction"!==i||s||(this.cleanupTransitions(),n.goToStep?n.goToStep(t):null==(e=n.goToStep)||e.call(n,t))}cleanupTransitions(){this.activeTransitions.forEach((t=>{t.cleanup()})),this.activeTransitions.clear(),this.waitingForInteraction=!1}setWaitingForInteraction(t){this.waitingForInteraction=t}isWaitingForInteraction(){return this.waitingForInteraction}destroy(){this.cleanupTransitions(),window.removeEventListener("popstate",this.handleURLChange)}setupDOMElementVisibleTransition(t){if(!t.target)return;const e=t.target,n=t.nextStep,i=`dom-visible-${e}-${Date.now()}`;let s=null,r=null,a=null,o=null;const l=t=>{s||(a=t,s=new IntersectionObserver((t=>{t.forEach((t=>{var e;if(t.isIntersecting,t.intersectionRatio.toFixed(2),t.target.outerHTML.substring(0,100),t.isIntersecting&&t.target===a){const s=window.getComputedStyle(t.target);if(!("0"!==s.opacity&&"none"!==s.display&&"visible"===s.visibility&&"none"!==s.pointerEvents))return;this.triggerTransition(n),null==(e=this.activeTransitions.get(i))||e.cleanup(),this.activeTransitions.delete(i)}else if(t.target===a){const e=t.target.getBoundingClientRect();e.top.toFixed(0),e.left.toFixed(0),e.bottom.toFixed(0),e.right.toFixed(0),e.width.toFixed(0),e.height.toFixed(0)}}))}),{root:null,rootMargin:"0px",threshold:0}),s.observe(t),r&&(r.disconnect(),r=null))},c=document.querySelector(e);c?l(c):(r=new MutationObserver((t=>{for(const n of t)if("childList"===n.type&&n.addedNodes.forEach((t=>{if(t.nodeType===Node.ELEMENT_NODE){const n=t;if(n.matches(e))return void l(n);const i=n.querySelector(e);if(i)return void l(i)}})),!r)break})),r.observe(document.body,{childList:!0,subtree:!0}),o=window.setInterval((()=>{if(!r)return void(o&&clearInterval(o));const t=document.querySelector(e);t&&t.offsetWidth>0&&t.offsetHeight>0&&(o&&clearInterval(o),o=null,l(t))}),1e3)),this.activeTransitions.set(i,{handlers:new Map,cleanup:()=>{s&&(s.disconnect(),s=null),r&&(r.disconnect(),r=null),o&&(clearInterval(o),o=null),a=null},data:{type:"dom-element-visible",pattern:e,nextStepId:n}})}}class Nt{constructor(){e(this,"autoStartPlaylists",[]),e(this,"triggeredPlaylists",new Set),e(this,"isMonitoring",!1)}registerTriggers(t){this.autoStartPlaylists=t.filter((t=>t.autoStart&&t.triggers&&t.isLive)),this.autoStartPlaylists.length,this.autoStartPlaylists.forEach((t=>{var e,n;t.id,null==(e=t.triggers)||e.url,null==(n=t.triggers)||n.once}))}startMonitoring(){this.isMonitoring||(this.isMonitoring=!0,this.evaluateAllTriggers())}stopMonitoring(){this.isMonitoring=!1}evaluateAllTriggers(){if(this.isMonitoring&&0!==this.autoStartPlaylists.length)for(const t of this.autoStartPlaylists)this.evaluatePlaylistTrigger(t)}evaluatePlaylistTrigger(t){var e,n,i;if(!t.triggers)return;const{triggers:s}=t,r=t.id;if(this.triggeredPlaylists.has(r))return;const a=Pt.getState();if(!a.user)return;const o=[],l=this.evaluateOnceCondition(s.once,r,null==(e=a.userData)?void 0:e.watchedPlaylists);o.push(l);const c=this.evaluateURLCondition(s.url);o.push(c),s.url;const d=this.evaluatePlaylistSeenCondition(s.playlistSeen,null==(n=a.userData)?void 0:n.watchedPlaylists);o.push(d),JSON.stringify(s.playlistSeen);const h=this.evaluatePlaylistNotSeenCondition(s.playlistNotSeen,null==(i=a.userData)?void 0:i.watchedPlaylists);o.push(h),JSON.stringify(s.playlistNotSeen);const u=this.applyOperators(o,s.operators);s.operators.join(", "),u&&this.triggerPlaylist(r)}evaluateOnceCondition(t,e,n){if(!t)return!0;return!(n&&n[e])}evaluateURLCondition(t){if(!t)return!0;const e=window.location.href.split("#")[0],n=window.location.pathname,i=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/\\\*/g,".*"),s=new RegExp(i),r=s.test(e),a=s.test(n);return r||a}evaluatePlaylistSeenCondition(t,e){if(!t||0===t.length)return!0;if(!e)return!1;for(const n of t){const t=e[n];if(!t||"completed"!==t.status&&"in_progress"!==t.status)return!1}return!0}evaluatePlaylistNotSeenCondition(t,e){if(!t||0===t.length)return!0;if(!e)return!0;for(const n of t){const t=e[n];if(t&&("completed"===t.status||"in_progress"===t.status))return!1}return!0}applyOperators(t,e){return 0!==t.length&&(1===t.length?t[0]:e&&0!==e.length&&e.includes("OR")?t.some((t=>t)):t.every((t=>t)))}async triggerPlaylist(t){this.triggeredPlaylists.add(t);try{const e=window._saltfishPlayer;e&&"function"==typeof e.startPlaylist&&await e.startPlaylist(t)}catch(e){this.triggeredPlaylists.delete(t)}}resetTriggeredPlaylists(){this.triggeredPlaylists.clear()}getTriggeredPlaylists(){return Array.from(this.triggeredPlaylists)}destroy(){this.stopMonitoring(),this.autoStartPlaylists=[],this.triggeredPlaylists.clear()}}class Yt{constructor(){e(this,"listeners",new Map)}on(t,e){this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(e)}off(t,e){const n=this.listeners.get(t);return!!n&&n.delete(e)}trigger(t,e){const n=this.listeners.get(t);n&&0!==n.size&&("timestamp"in e||(e.timestamp=Date.now()),n.forEach((n=>{try{n(e)}catch(i){console.error(`Error in ${t} event handler:`,i)}})))}removeAllListeners(){this.listeners.clear()}getListenerCount(t){const e=this.listeners.get(t);return e?e.size:0}}class Ht{async loadManifest(t){const{manifestPath:e,playlistOptions:n,savedProgress:i}=t;try{const t=await this.fetchManifest(e);this.validateManifest(t);const s=this.determineStartStep(t,n,i);return t.id,{manifest:t,startStepId:s}}catch(s){const t=s instanceof Error?s.message:"Unknown error";throw yt("[PlaylistLoader] Failed to load manifest:",s),new Error(`Unable to load playlist manifest: ${t}`)}}async fetchManifest(t){const e=t.includes("/")&&t.split("/").pop()||t;if("undefined"!=typeof window&&window.demoManifest)return window.demoManifest;try{const e=await fetch(t);if(e.status,e.statusText,!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);return await e.json()}catch(n){throw yt("[PlaylistLoader] Fetch/parse failed:",n),yt("[PlaylistLoader] Manifest path:",t),yt("[PlaylistLoader] Manifest identifier:",e),new Error(`Failed to fetch manifest from "${t}": ${n instanceof Error?n.message:"Unknown error"}`)}}validateManifest(t){if(!t)throw new Error("Manifest is null or undefined");if("object"!=typeof t)throw new Error("Manifest must be an object");const e=["id","startStep","steps"];for(const n of e)if(!(n in t))throw new Error(`Manifest missing required field: ${n}`);if(!Array.isArray(t.steps))throw new Error("Manifest steps must be an array");if(0===t.steps.length)throw new Error("Manifest must contain at least one step");if(!t.steps.some((e=>e.id===t.startStep)))throw new Error(`Start step '${t.startStep}' not found in steps array`);for(const n of t.steps){if(!n.id)throw new Error("Each step must have an id");if(!n.videoUrl)throw new Error(`Step '${n.id}' must have a videoUrl`);if(!n.transitions||!Array.isArray(n.transitions))throw new Error(`Step '${n.id}' must have transitions array`)}}determineStartStep(t,e,n){var i;const s=e.persistence??!0,r=t.id;let a=t.startStep;if(e.startNodeId){t.steps.find((t=>t.id===e.startNodeId))?(e.startNodeId,a=e.startNodeId):e.startNodeId}else if(s&&n&&(null==(i=n[r])?void 0:i.lastStepId)){const e=n[r],i=e.lastStepId;if(e.completedWaitingForInteraction)a=t.startStep;else{t.steps.find((t=>t.id===i))&&(a=i)}}return a}}class Xt{constructor(t){e(this,"eventManager",null),e(this,"isUpdatingWatchedPlaylists",!1),e(this,"playlistLoader"),this.playlistLoader=new Ht,t&&this.setEventManager(t)}setEventManager(t){this.eventManager=t,this.subscribeToEvents()}subscribeToEvents(){this.eventManager&&(this.eventManager.on("playlistStarted",(t=>{t.playlist.id,this.updateWatchedPlaylistStatus(t.playlist.id,"in_progress")})),this.eventManager.on("playlistEnded",(t=>{t.playlist.id,this.updateWatchedPlaylistStatus(t.playlist.id,"completed").catch((e=>{console.error(`PlaylistManager: Error in updateWatchedPlaylistStatus for playlist ${t.playlist.id}:`,e)}))})),this.eventManager.on("playlistDismissed",(t=>{t.playlist.id,this.updateWatchedPlaylistStatus(t.playlist.id,"dismissed")})),this.eventManager.on("stepStarted",(t=>{t.step.id,this.updateWatchedPlaylistStatus(t.playlist.id,"in_progress",t.step.id)})))}getStore(){try{return Pt.getState()}catch(t){return console.error("Failed to access store:",t),null}}async updateWatchedPlaylistStatus(t,e,n){var i,s,r,a,o,l;if(!this.isUpdatingWatchedPlaylists){this.isUpdatingWatchedPlaylists=!0;try{const d=this.getStore();if(!d)return;const h=d.userData||{},u=h.watchedPlaylists||{},p={status:e,currentStepId:n||d.currentStepId||null,lastProgressAt:Date.now()},g={...u,[t]:p};if(d.setUserData({...h,watchedPlaylists:g}),!(null==(i=null==d?void 0:d.config)?void 0:i.token)||!(null==(s=null==d?void 0:d.user)?void 0:s.id)||(null==(r=null==d?void 0:d.user)?void 0:r.__isAnonymous))return null==(a=null==d?void 0:d.config)||a.token,null==(o=null==d?void 0:d.user)||o.id,null==(l=null==d?void 0:d.user)||l.__isAnonymous,void this.updateAnonymousUserWatchedPlaylists(t,e,n||d.currentStepId||null);const m=`https://player.saltfish.ai/clients/${d.config.token}/users/${d.user.id}/playlists/${t}`;try{const t=await fetch(m,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({status:e,currentStepId:n||d.currentStepId||null})});if(!t.ok)throw new Error(`Failed to update watched playlist status: ${t.statusText} (${t.status})`)}catch(c){console.error(`PlaylistManager: Error updating watched playlist status for ${t}:`,c)}}finally{this.isUpdatingWatchedPlaylists=!1}}}updateAnonymousUserWatchedPlaylists(t,e,n){if("undefined"!=typeof window)try{const s=localStorage.getItem(et);let r={userId:"anonymous",userData:{},watchedPlaylists:{},timestamp:Date.now()};if(s)try{r=JSON.parse(s)}catch(i){}r.watchedPlaylists||(r.watchedPlaylists={}),r.watchedPlaylists[t]={status:e,currentStepId:n||null,lastProgressAt:Date.now()},r.timestamp=Date.now(),localStorage.setItem(et,JSON.stringify(r))}catch(s){console.error("PlaylistManager: Error updating anonymous user watched playlists:",s)}}async load(t,e){try{const n=Pt.getState(),i=await this.playlistLoader.loadManifest({manifestPath:t,playlistOptions:e,savedProgress:n.progress}),{manifest:s,startStepId:r}=i,a=s.steps.find((t=>t.id===r));n.setManifest(s,r),a&&n.stateMachine.send({type:"MANIFEST_LOADED",step:a})}catch(n){const t=Pt.getState(),e=n instanceof Error?n:new Error("Unknown error loading manifest");t.stateMachine.send({type:"ERROR",error:e}),t.setError(e)}}destroy(){this.eventManager&&(this.eventManager=null)}}class $t{constructor(){e(this,"playerElement",null)}create(t){return this.playerElement?(console.warn("PlayerView: Player element already exists, returning existing element"),this.playerElement):(this.playerElement=document.createElement("div"),this.playerElement.className=ht,t.appendChild(this.playerElement),this.playerElement)}createControlsContainer(t){const e=document.createElement("div");return e.className=pt,t.appendChild(e),e}createSaltfishLogo(t){var e;if(!1===(null==(e=Pt.getState().config)?void 0:e.showLogo))return;const n=document.createElement("div");n.className=gt,n.innerHTML='\n <svg width="41" height="15" viewBox="0 0 41 15" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M8.42034 7.49991C8.42034 9.67502 6.65707 11.4383 4.48196 11.4383C2.30685 11.4383 4.00664 9.67502 4.00664 7.49991C4.00664 5.3248 2.30685 3.56152 4.48196 3.56152C6.65707 3.56152 8.42034 5.3248 8.42034 7.49991Z" fill="white"/>\n <path d="M3.53097 7.43198C3.53097 8.96956 2.29707 10.216 0.774969 10.216C-0.747128 10.216 0.442349 8.96956 0.442349 7.43198C0.442349 5.8944 -0.747128 4.64795 0.774969 4.64795C2.29707 4.64795 3.53097 5.8944 3.53097 7.43198Z" fill="white"/>\n <path d="M15.0603 10.628C13.8603 10.628 12.9803 9.892 12.9803 8.372L13.6043 8.292C13.6043 9.492 14.1803 10.044 15.0603 10.044C15.8603 10.044 16.3243 9.612 16.3243 8.972C16.3243 8.252 15.8363 7.988 15.0603 7.788C13.7003 7.436 13.2523 6.996 13.2523 6.196C13.2523 5.396 13.9403 4.772 14.9803 4.772C16.0203 4.772 16.6923 5.396 16.6923 6.436L16.0683 6.516C16.0683 5.796 15.6203 5.356 14.9803 5.356C14.3403 5.356 13.8763 5.636 13.8763 6.196C13.8763 6.756 14.2843 7.004 15.0603 7.204C16.3723 7.548 16.9483 8.012 16.9483 8.972C16.9483 9.932 16.2603 10.628 15.0603 10.628ZM19.182 10.628C18.542 10.628 17.83 10.228 17.83 9.428C17.83 8.548 18.462 8.212 19.494 8.076C19.966 8.012 20.638 7.956 20.414 7.38C20.27 7.004 19.734 6.956 19.494 6.956C18.854 6.956 18.534 7.236 18.534 7.716L17.91 7.636C17.91 6.756 18.774 6.372 19.494 6.372C20.214 6.372 21.022 6.692 21.022 7.652V10.5H20.438V9.7C20.262 10.22 19.798 10.628 19.182 10.628ZM18.454 9.46C18.454 9.78 18.782 10.044 19.182 10.044C19.822 10.044 20.438 9.596 20.438 8.476V8.26C20.286 8.476 19.91 8.596 19.374 8.66C18.742 8.748 18.454 9.06 18.454 9.46ZM22.3044 10.5V4.82H22.9284V10.5H22.3044ZM25.6789 10.5C24.9909 10.5 24.6469 10.204 24.6469 9.508V7.084H23.9669V6.5H24.6469V5.292L25.1909 5.212V6.5H26.2309V7.084H25.1909V9.34C25.1909 9.836 25.3829 9.916 25.7749 9.916H26.2309V10.5H25.6789ZM27.7094 6.052C27.7094 5.116 28.0934 4.82 28.7814 4.82H29.3334V5.404H28.8774C28.4454 5.404 28.2934 5.484 28.2934 6.22V6.5H29.3334V7.084H28.2934V10.5H27.7094V7.084H27.0294V6.5H27.7094V6.052ZM30.2805 10.5V6.5H30.9045V10.5H30.2805ZM30.2165 5.86V5.108H30.9685V5.86H30.2165ZM33.7678 10.628C32.8078 10.628 32.0078 10.06 32.0078 9.02L32.5918 8.94C32.5918 9.66 33.2078 10.044 33.7678 10.044C34.3278 10.044 34.7678 9.86 34.7678 9.38C34.7678 8.9 34.4558 8.772 33.9998 8.708L33.2958 8.612C32.6638 8.524 32.2318 8.092 32.2318 7.532C32.2318 6.812 32.8478 6.372 33.7278 6.372C34.6078 6.372 35.1678 6.892 35.1678 7.612L34.5838 7.692C34.5838 7.212 34.2878 6.956 33.7278 6.956C33.2478 6.956 32.8558 7.132 32.8558 7.532C32.8558 7.852 33.0718 7.996 33.5438 8.068L34.1518 8.156C34.8558 8.26 35.3918 8.66 35.3918 9.38C35.3918 10.1 34.7278 10.628 33.7678 10.628ZM38.9252 7.868C38.9252 7.148 38.5812 6.956 38.1012 6.956C37.6212 6.956 36.9812 7.276 36.9812 8.636V10.5H36.3572V4.9H36.9812V7.364C37.1092 6.812 37.5652 6.372 38.3012 6.372C39.1812 6.372 39.5492 6.988 39.5492 7.868V10.5H38.9252V7.868Z" fill="white"/>\n </svg>\n ',t.appendChild(n),n.addEventListener("click",(t=>{var e;t.stopPropagation();const n=null==(e=Pt.getState().config)?void 0:e.token;n?window.open(`https://www.saltfish.ai/demos?clientId=${n}`,"_blank"):(console.warn("PlayerView: No token available, falling back to saltfish.ai homepage"),window.open("https://www.saltfish.ai/","_blank"))}))}getPlayerElement(){return this.playerElement}destroy(){this.playerElement&&this.playerElement.parentElement&&this.playerElement.parentElement.removeChild(this.playerElement),this.playerElement=null}}class Wt{constructor(){e(this,"playerElement",null),e(this,"playerRoot",null),e(this,"isDragging",!1),e(this,"dragOffset",{x:0,y:0}),e(this,"justFinishedDragging",!1),e(this,"dragStartPosition",{x:0,y:0}),e(this,"hasMoved",!1),e(this,"resizeListener",null),e(this,"onDragStateChange",null)}initialize(t,e,n){this.playerElement=t,this.playerRoot=e,this.onDragStateChange=n||null,this.setupDragHandlers()}setupDragHandlers(){if(!this.playerElement)return;const t=t=>{var e;if(!this.isDragging)return;const n=Math.abs(t.clientX-this.dragStartPosition.x),i=Math.abs(t.clientY-this.dragStartPosition.y);(n>at||i>at)&&(this.hasMoved=!0);const s=Pt.getState();let r=t.clientX-this.dragOffset.x,a=t.clientY-this.dragOffset.y,o=null==(e=s.playlistOptions)?void 0:e.position;if(s.currentStepId&&s.manifest){const t=s.manifest.steps.find((t=>t.id===s.currentStepId));(null==t?void 0:t.position)&&(o=t.position)}const l=It.calculateDragPosition({x:r,y:a,position:o});this.updatePlayerPosition(l,o||"bottom-right"),t.preventDefault()},e=n=>{var i;if(this.isDragging){const t=Pt.getState();let e=n.clientX-this.dragOffset.x,s=n.clientY-this.dragOffset.y,r=null==(i=t.playlistOptions)?void 0:i.position;if(t.currentStepId&&t.manifest){const e=t.manifest.steps.find((e=>e.id===t.currentStepId));(null==e?void 0:e.position)&&(r=e.position)}const a=It.calculateDragPosition({x:e,y:s,position:r});t.setPosition(a.x,a.y),this.onDragStateChange&&this.onDragStateChange(),this.hasMoved&&(this.justFinishedDragging=!0,setTimeout((()=>{this.justFinishedDragging=!1}),ot))}this.isDragging=!1,document.removeEventListener("mousemove",t),document.removeEventListener("mouseup",e)};this.playerElement.addEventListener("mousedown",(t=>{var e,n;if(!this.playerElement)return;if("BUTTON"===t.target.tagName)return;this.isDragging=!0,this.justFinishedDragging=!1,this.hasMoved=!1,this.dragStartPosition={x:t.clientX,y:t.clientY};const i=Pt.getState(),s=this.playerElement.getBoundingClientRect();this.dragOffset={x:t.clientX-((null==(e=i.position)?void 0:e.x)||s.left),y:t.clientY-((null==(n=i.position)?void 0:n.y)||s.top)},t.preventDefault()})),this.playerElement.addEventListener("mousedown",(()=>{document.addEventListener("mousemove",t),document.addEventListener("mouseup",e)})),this.resizeListener=()=>{setTimeout((()=>{this.onDragStateChange&&this.onDragStateChange()}),100)},window.addEventListener("resize",this.resizeListener)}updatePlayerPosition(t,e){if(!this.playerRoot)return;const n=It.getTransforms(e);this.playerRoot.style.left=`${t.x}px`,this.playerRoot.style.top=`${t.y}px`,this.playerRoot.style.transform=`translate(${n.transformX}, ${n.transformY})`}isCurrentlyDragging(){return this.isDragging}hasJustFinishedDragging(){return this.justFinishedDragging}resetDragState(){this.isDragging=!1,this.justFinishedDragging=!1,this.hasMoved=!1}destroy(){this.resizeListener&&(window.removeEventListener("resize",this.resizeListener),this.resizeListener=null),this.resetDragState(),this.playerElement=null,this.playerRoot=null,this.onDragStateChange=null}}class jt{constructor(t){e(this,"button"),e(this,"playerElement"),this.playerElement=t,this.button=document.createElement("button"),this.button.className="sf-player__minimize-button",this.button.innerHTML='\n <svg width="30" height="30" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n ',this.button.addEventListener("click",this.handleClick.bind(this)),this.playerElement.appendChild(this.button),this.updateVisibility(Pt.getState().isMinimized)}handleClick(){const t=Pt.getState(),e=!t.isMinimized;e?(t.minimize(),"playing"===t.currentState&&t.pause()):t.maximize(),e?this.minimize():this.maximize()}minimize(){this.button.innerHTML='\n <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n '}maximize(){this.button.innerHTML='\n <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n '}updateVisibility(t){this.button.style.display=t?"none":""}destroy(){this.button.removeEventListener("click",this.handleClick.bind(this)),this.button.remove()}}class qt{constructor(t,n){e(this,"playButton"),e(this,"container"),e(this,"videoManager",null),this.container=t,this.videoManager=n||null,this.createButton()}createButton(){this.playButton=document.createElement("button"),this.playButton.className="sf-controls-container__play-button",this.playButton.innerHTML='\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M8 5v14l11-7z" fill="currentColor"/>\n </svg>\n ',this.playButton.addEventListener("click",this.handlePlayClick.bind(this)),this.container.appendChild(this.playButton)}handlePlayClick(t){t&&t.stopPropagation();const e=Pt.getState();if("autoplayBlocked"===e.currentState)if(this.videoManager){this.videoManager.markUserInteraction(),this.videoManager.setMuted(!1);const t=this.videoManager.getVideoElement();t&&(t.loop=!1,t.currentTime=0)}else{const t=this.playButton.closest(".sf-player");if(t){const e=t.querySelector(".sf-video-container__video");e&&(e.muted=!1,e.loop=!1,e.currentTime=0)}}else this.videoManager?this.videoManager.markUserInteraction():console.warn("PlayPauseButton: VideoManager not available, falling back to store play");"paused"!==e.currentState&&"waitingForInteraction"!==e.currentState&&"autoplayBlocked"!==e.currentState||e.play()}updateState(t){if("playing"===t)this.playButton.style.display="none";else this.playButton.style.display="flex"}destroy(){this.playButton.removeEventListener("click",this.handlePlayClick.bind(this)),this.playButton.remove()}}class Zt{constructor(t){e(this,"button"),e(this,"playerElement"),this.playerElement=t,this.button=document.createElement("button"),this.button.className="sf-player__exit-button",this.button.innerHTML='\n <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n ',this.button.addEventListener("click",this.handleClick.bind(this)),this.playerElement.appendChild(this.button),this.updateVisibility(Pt.getState().isMinimized)}handleClick(t){t.stopPropagation();const e=Pt.getState();if(e.manifest){re.getInstance().eventManager.trigger("playlistDismissed",{timestamp:Date.now(),playlist:{id:e.manifest.id,title:e.manifest.name}})}re.getInstance().destroy()}updateVisibility(t){this.button.style.display=t?"flex":"none"}destroy(){this.button.removeEventListener("click",this.handleClick.bind(this)),this.button.remove()}}class Jt{constructor(t){e(this,"shadowDOMManager"),e(this,"playerView"),e(this,"dragManager"),e(this,"playerRoot",null),e(this,"playerElement",null),e(this,"minimizeButton",null),e(this,"exitButton",null),e(this,"playPauseButton",null),this.shadowDOMManager=t,this.playerView=new $t,this.dragManager=new Wt}createPlayerUI(t,e,n,i){if(!this.playerRoot&&(this.shadowDOMManager.create(),this.playerRoot=this.shadowDOMManager.getRootElement(),!this.playerRoot))return void console.error("Failed to create player root element");if(this.playerElement)return;this.playerElement=this.playerView.create(this.playerRoot),this.minimizeButton=new jt(this.playerElement),this.exitButton=new Zt(this.playerElement),t.create(this.playerElement);const s=this.playerView.createControlsContainer(this.playerElement);this.playPauseButton=new qt(s,t),this.playerView.createSaltfishLogo(this.playerElement),this.setupVideoContainerClickHandler(),e.create(),n.create(this.playerElement),i.initialize(this.playerElement,t);const r=Pt.getState();this.updateControlsVisibility(r.currentState),this.handleMinimizeStateChange(r.isMinimized),this.dragManager.initialize(this.playerElement,this.playerRoot,(()=>n.updateButtonPositions()))}setupVideoContainerClickHandler(){var t;const e=null==(t=this.playerElement)?void 0:t.querySelector(".sf-video-container");e&&e.addEventListener("click",(t=>{const e=Pt.getState();if(e.isMinimized)return t.stopPropagation(),void this.handleMinimizeClick();if(this.dragManager.hasJustFinishedDragging())return;const n=t.target;"BUTTON"===n.tagName||n.closest("button")||n.closest(".sf-controls-container")||"playing"===e.currentState&&e.pause()}))}updatePosition(){var t;if(!this.playerRoot||!this.playerElement)return void console.warn("UIManager: updatePosition called but playerRoot or playerElement is null",{playerRoot:!!this.playerRoot,playerElement:!!this.playerElement});const e=Pt.getState();if(e.position){let{x:n,y:i}=e.position,s=null==(t=e.playlistOptions)?void 0:t.position;if(e.currentStepId&&e.manifest){const t=e.manifest.steps.find((t=>t.id===e.currentStepId));(null==t?void 0:t.position)&&(s=t.position,It.shouldForceReposition(s,i,this.dragManager.isCurrentlyDragging())&&(n=nt))}const r=It.applyConstraints({x:n,y:i,position:s||"bottom-right",viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,playerWidth:Et(e.isMinimized).width}),a=It.getTransforms(s||"bottom-right");this.playerRoot.style.left=`${r.x}px`,this.playerRoot.style.top=`${r.y}px`,this.playerRoot.style.transform=`translate(${a.transformX}, ${a.transformY})`,e.isMinimized?this.playerElement.classList.add(ut):this.playerElement.classList.remove(ut)}}handleMinimizeClick(){if(!this.playerElement)return;const t=Pt.getState(),e=!t.isMinimized;e?(t.minimize(),"playing"===t.currentState&&t.pause()):t.maximize(),e?this.minimizeButton.minimize():this.minimizeButton.maximize()}handleMinimizeStateChange(t){this.exitButton&&this.exitButton.updateVisibility(t),this.minimizeButton&&this.minimizeButton.updateVisibility(t)}updateControlsVisibility(t){this.playPauseButton&&this.playPauseButton.updateState(t)}getPlayerElement(){return this.playerElement}getPlayerRoot(){return this.playerRoot}isCurrentlyDragging(){return this.dragManager.isCurrentlyDragging()}hasJustFinishedDragging(){return this.dragManager.hasJustFinishedDragging()}resetDragState(){this.dragManager.resetDragState()}destroy(){this.minimizeButton&&(this.minimizeButton.destroy(),this.minimizeButton=null),this.exitButton&&(this.exitButton.destroy(),this.exitButton=null),this.playPauseButton&&(this.playPauseButton.destroy(),this.playPauseButton=null),this.playerView.destroy(),this.dragManager.destroy(),this.shadowDOMManager.remove(),this.playerRoot=null,this.playerElement=null}}function Kt(t,e){let n=null;const i=()=>{n=t.querySelector(".sf-player__minimize-button")};i();let s={currentState:"",isMinimized:!1,currentStepId:null};function r(t,n){var i;if(!e)return;const s=null==(i=null==n?void 0:n.steps)?void 0:i.find((e=>e.id===t));s&&s.cursorAnimations&&s.cursorAnimations.length>0&&e.setShouldShowCursor(!0)}return Pt.subscribe((a=>{var o,l,c,d;n||i(),a.currentState!==s.currentState&&(o=a.currentState,["sf-player--idle","sf-player--loading","sf-player--playing","sf-player--paused","sf-player--waitingForInteraction","sf-player--autoplayBlocked","sf-player--error","sf-player--completed","sf-player--completedWaitingForInteraction"].forEach((e=>{t.classList.remove(e)})),t.classList.add(`sf-player--${o}`)),a.isMinimized!==s.isMinimized&&(l=a.isMinimized,c=a.currentStepId,d=a.manifest,l?(t.classList.add("sf-player--minimized"),e&&e.setShouldShowCursor(!1)):(t.classList.remove("sf-player--minimized"),r(c,d)),function(t){if(!n)return;n.innerHTML=t?'\n <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n ':'\n <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n '}(a.isMinimized)),a.currentStepId!==s.currentStepId&&(a.isMinimized||r(a.currentStepId,a.manifest)),s={currentState:a.currentState,isMinimized:a.isMinimized,currentStepId:a.currentStepId}}))}function Qt(t){let e=null,n=null,i=null;const s=Pt.subscribe((s=>{var r;const a={previousState:e,currentState:s.currentState,currentStepId:s.currentStepId,isMinimized:s.isMinimized};e===s.currentState&&n===s.isMinimized&&i===s.currentStepId||(null==(r=s.manifest)||r.id,function(t,e,n){const{previousState:i,currentState:s}=t;"playing"===s&&"playing"!==i&&"paused"!==i&&e.manifest&&n.trigger("playlistStarted",{timestamp:Date.now(),playlist:{id:e.manifest.id,title:e.manifest.name}});"paused"===i&&"playing"===s?n.trigger("playerResumed",{timestamp:Date.now(),previousState:i,currentState:s}):"playing"===i&&"paused"===s?n.trigger("playerPaused",{timestamp:Date.now(),previousState:i,currentState:s}):("completed"===s&&"completed"!==i||"completedWaitingForInteraction"===s&&"completedWaitingForInteraction"!==i)&&e.manifest&&(e.manifest.id,n.trigger("playlistEnded",{timestamp:Date.now(),playlist:{id:e.manifest.id,title:e.manifest.name}}))}(a,s,t),function(t,e,n,i){const{previousState:s,currentState:r,isMinimized:a}=t,o=i||!1;!a&&o?n.trigger("playerMaximized",{timestamp:Date.now(),previousState:s,currentState:r}):a&&!o&&n.trigger("playerMinimized",{timestamp:Date.now(),previousState:s,currentState:r})}(a,0,t,n),function(t,e,n,i){var s,r,a;const{currentStepId:o,currentState:l,previousState:c}=t,d=e.currentStepId?((null==(s=e.manifest)?void 0:s.steps)||[]).find((t=>t.id===e.currentStepId)):null;null==d||d.id,null==(r=e.manifest)||r.id,e.manifest;const h=i&&e.manifest&&(i!==o||"waitingForInteraction"===l||"autoplayBlocked"===l||"completed"===l);if(e.manifest,h){const t=((null==(a=e.manifest)?void 0:a.steps)||[]).find((t=>t.id===i));null==t||t.id,t&&(t.id,n.trigger("stepEnded",{timestamp:Date.now(),step:{id:t.id,title:t.title||t.id},playlist:{id:e.manifest.id,title:e.manifest.name}}))}const u=o!==i&&"playing"===l,p=("paused"===c||"autoplayBlocked"===c)&&"playing"===l&&i===o,g=d&&e.manifest&&(u||p);null==d||d.id,e.manifest,g&&(d.id,n.trigger("stepStarted",{timestamp:Date.now(),step:{id:d.id,title:d.title||d.id},playlist:{id:e.manifest.id,title:e.manifest.name}}))}(a,s,t,i),function(t,e,n){var i;const{currentState:s,previousState:r}=t;"error"===s&&"error"!==r&&e.error&&n.trigger("error",{timestamp:Date.now(),playlistId:null==(i=e.manifest)?void 0:i.id,stepId:e.currentStepId,error:e.error,errorType:"state"})}(a,s,t),e=s.currentState,n=s.isMinimized,i=s.currentStepId)}));return s}class Gt{static handle(t,e={},n={}){var i;const s={...this.DEFAULT_OPTIONS,...n},r=this.normalizeError(t,e);if(s.shouldLog&&this.logError(r,e,s.severity),s.shouldUpdateStore&&this.updateStore(r),s.shouldTriggerEvent&&this.triggerErrorEvent(r,e,null==(i=e.component)?void 0:i.toLowerCase()),s.shouldDestroy&&this.destroyPlayer(),s.shouldThrow)throw r;return r}static handleInitializationError(t,e={}){return this.handle(t,{...e,component:"Initialization"},{severity:"critical",shouldLog:!0,shouldUpdateStore:!0,shouldDestroy:!0,shouldThrow:!0})}static handlePlaylistError(t,e={}){return this.handle(t,{...e,component:"Playlist"},{severity:"error",shouldLog:!0,shouldUpdateStore:!0,shouldTriggerEvent:!0})}static handleVideoError(t,e={}){return this.handle(t,{...e,component:"Video"},{severity:"error",shouldLog:!0,shouldUpdateStore:!0,shouldTriggerEvent:!0})}static handleNetworkError(t,e={}){return this.handle(t,{...e,component:"Network"},{severity:"warning",shouldLog:!0,shouldTriggerEvent:!0})}static handleWarning(t,e={}){return this.handle(t,e,{severity:"warning",shouldLog:!0,shouldThrow:!1})}static handleCleanupError(t,e={}){return this.handle(t,{...e,component:"Cleanup"},{severity:"warning",shouldLog:!0,shouldThrow:!1})}static normalizeError(t,e){if(t instanceof Error)return t;if("string"==typeof t)return new Error(t);const n=String(t&&"object"==typeof t&&"message"in t?t.message:t);return new Error(`Unknown error in ${e.component||"application"}: ${n}`)}static formatErrorMessage(t,e){const n=[];return e.component&&n.push(`[${e.component}]`),e.method&&n.push(`${e.method}:`),n.push(t.message),n.join(" ")}static logError(t,e,n){const i=this.formatErrorMessage(t,e),s={error:{name:t.name,message:t.message,stack:t.stack},context:e,severity:n,timestamp:(new Date).toISOString()};switch(n){case"info":break;case"warning":console.warn(i,s);break;case"error":case"critical":console.error(i,s)}}static updateStore(t){try{Pt.getState().setError(t)}catch(e){console.error("Failed to update store with error:",e)}}static triggerErrorEvent(t,e,n){var i,s;try{const r=Pt.getState();if("undefined"!=typeof window&&window._saltfishPlayer){const a=window._saltfishPlayer;a&&a.eventManager&&a.eventManager.trigger("error",{timestamp:Date.now(),playlistId:e.playlistId||(null==(i=r.manifest)?void 0:i.id),stepId:e.stepId||r.currentStepId,error:t,errorType:e.errorType||n||(null==(s=e.component)?void 0:s.toLowerCase())||"unknown"})}}catch(r){console.error("Failed to trigger error event:",r)}}static destroyPlayer(){try{if("undefined"!=typeof window&&window._saltfishPlayer){const t=window._saltfishPlayer;t&&"function"==typeof t.destroy&&t.destroy()}}catch(t){console.error("Failed to destroy player during error handling:",t)}}static createError(t,e={}){const n=new Error(this.formatErrorMessage(new Error(t),e));return e.component&&(n.component=e.component),e.method&&(n.method=e.method),e.playlistId&&(n.playlistId=e.playlistId),e.stepId&&(n.stepId=e.stepId),n}static isRecoverable(t){if(t.message.includes("fetch")||t.message.includes("network")||t.message.includes("timeout"))return!0;return[/autoplay.*blocked/i,/video.*failed.*load/i,/manifest.*not.*found/i].some((e=>e.test(t.message)))}static async safeExecute(t,e={},n={}){try{return await t()}catch(i){return this.handle(i,e,n),null}}}e(Gt,"DEFAULT_OPTIONS",{severity:"error",shouldLog:!0,shouldThrow:!1,shouldUpdateStore:!1,shouldTriggerEvent:!1,shouldDestroy:!1});const te=class t{constructor(t){e(this,"currentStepId",null),e(this,"stepTimeoutId",null),e(this,"destroyCallback",null),this.destroyCallback=t}update(t){const{currentStepId:e,currentState:n}=t;this.currentStepId;if(!("playing"===n||"waitingForInteraction"===n||"paused"===n||"autoplayBlocked"===n))return this.stepTimeoutId,void this.clearStepTimeout();const i=e!==this.currentStepId,s=null===this.stepTimeoutId;(i||s)&&(i&&this.currentStepId,this.setStepTimeout(e))}setStepTimeout(e){this.clearStepTimeout(),e&&(this.currentStepId=e,this.stepTimeoutId=window.setTimeout((()=>{this.destroyPlayer()}),t.STEP_TIMEOUT_MS))}clearStepTimeout(){null!==this.stepTimeoutId&&(this.currentStepId,window.clearTimeout(this.stepTimeoutId),this.stepTimeoutId=null)}destroyPlayer(){if(this.destroyCallback)try{this.destroyCallback()}catch(t){}}reset(){this.clearStepTimeout(),this.currentStepId=null}destroy(){this.clearStepTimeout(),this.currentStepId=null,this.destroyCallback=null}};e(te,"STEP_TIMEOUT_MS",lt);let ee=te;function ne(t){if(!t)return;if("auto"===t){return function(){try{const t=navigator.language||navigator.userLanguage;if(!t)return;return t.split("-")[0].toLowerCase()}catch(t){return}}()}return t.split("-")[0].toLowerCase()}class ie{async validatePlaylistStart(t){const{playlistId:e,options:n,eventManager:i}=t;try{const t=Pt.getState();if(!t.config)return{isValid:!1,error:"Saltfish Player must be initialized before starting a playlist"};const s=t.backendPlaylists;if(!s||0===s.length)return Gt.handlePlaylistError("No playlist list available from backend validation",{component:"PlaylistValidator",method:"validatePlaylistStart",playlistId:e,errorType:"playlist_backend_unavailable"}),{isValid:!1,error:"No backend playlists available"};const r=s.find((t=>t.id===e));if(!r)return Gt.handlePlaylistError(`Playlist ID '${e}' not found in the list provided by backend validation`,{component:"PlaylistValidator",method:"validatePlaylistStart",playlistId:e,errorType:"playlist_not_found",additionalData:{backendPlaylists:s}}),{isValid:!1,error:"Playlist not found in backend list"};if(!r.isLive)return Gt.handlePlaylistError(`Cannot start playlist '${e}' - playlist is not currently live`,{playlistId:e,additionalData:{isLive:r.isLive,triggers:r.triggers}}),{isValid:!1,error:"Playlist is not live"};if(null==r?void 0:r.autoStart){const t=await this.validateAutoStartConditions(e,r,i);if(!t.isValid)return t}let a=n;if(null==n?void 0:n.once){const t=await this.validateOnceOptionConditions(e,n,i);if(!t.isValid)return t;a=t.updatedOptions||n}const o=await this.validateDeviceCompatibility(r,e);return o.isValid?{isValid:!0,manifestPath:r.path,updatedOptions:a}:o}catch(s){const t=s instanceof Error?s.message:"Unknown validation error";return Gt.handlePlaylistError(`Playlist validation failed: ${t}`,{component:"PlaylistValidator",method:"validatePlaylistStart",playlistId:e,additionalData:{error:s}}),{isValid:!1,error:t}}}async validateAutoStartConditions(t,e,n){var i,s;const r=Pt.getState();if(!r.user)return Gt.handlePlaylistError("User must be identified before starting auto-start playlist",{component:"PlaylistValidator",method:"validateAutoStartConditions",playlistId:t,errorType:"playlist_user_required"}),{isValid:!1,error:"User identification required for autoStart playlist"};r.userData||await this.waitForUserData(n);const a=(null==(i=Pt.getState().userData)?void 0:i.watchedPlaylists)||{};return(null==(s=e.triggers)?void 0:s.once)&&a[t]?(mt(`Playlist ${t} has autoStart enabled with once:true and has already been watched. Skipping playlist start.`,{watchedPlaylists:a,triggers:e.triggers}),{isValid:!1,error:"Playlist already watched with once=true policy"}):{isValid:!0}}async validateOnceOptionConditions(t,e,n){var i;const s=Pt.getState();if(!s.user)return Gt.handlePlaylistError("User must be identified before starting playlist with once option",{component:"PlaylistValidator",method:"validateOnceOptionConditions",playlistId:t,errorType:"playlist_auth_required"}),{isValid:!1,error:"User identification required for once option"};s.userData||await this.waitForUserData(n);const r=(null==(i=Pt.getState().userData)?void 0:i.watchedPlaylists)||{},a=r[t];if(a&&("completed"===a.status||"dismissed"===a.status))return mt(`Playlist ${t} has once option enabled and has already been ${a.status}. Skipping playlist start.`,{watchedPlaylists:r,playlistStatus:a.status}),{isValid:!1,error:`Playlist already ${a.status} with once option`};if(a&&"in_progress"===a.status&&!(null==e?void 0:e.startNodeId)&&a.currentStepId){return{isValid:!0,updatedOptions:{...e,startNodeId:a.currentStepId}}}return{isValid:!0}}async validateDeviceCompatibility(t,e){try{const n=t.deviceType||"both",{isDeviceCompatible:i}=await Promise.resolve().then((()=>Tt));return i(n)?{isValid:!0}:(Gt.handlePlaylistError(`Playlist '${e}' is not compatible with this device. Required: ${n}`,{component:"PlaylistValidator",method:"validateDeviceCompatibility",playlistId:e,errorType:"playlist_device_incompatible",additionalData:{requiredDeviceType:n,manifestPath:t.path}}),{isValid:!1,error:`Device incompatible. Required: ${n}`})}catch(n){const i=n instanceof Error?n.message:"Unknown error";return Gt.handlePlaylistError(`Device compatibility check failed: ${i}`,{component:"PlaylistValidator",method:"validateDeviceCompatibility",playlistId:e,additionalData:{error:n,manifestPath:t.path}}),{isValid:!1,error:`Device compatibility check failed: ${i}`}}}async waitForUserData(t){return new Promise(((e,n)=>{const i=setTimeout((()=>{t.off("userDataLoaded",s),n(new Error("Timeout waiting for user data"))}),5e3),s=()=>{clearTimeout(i),Pt.getState(),e()};t.on("userDataLoaded",s)}))}}const se=class t{constructor(){if(e(this,"shadowDOMManager"),e(this,"videoManager"),e(this,"cursorManager"),e(this,"interactionManager"),e(this,"analyticsManager"),e(this,"sessionRecordingManager"),e(this,"sessionManager"),e(this,"buttonManager"),e(this,"transitionManager"),e(this,"triggerManager"),e(this,"eventManager"),e(this,"playlistManager"),e(this,"stepTimeoutManager"),e(this,"uiManager"),e(this,"playerView"),e(this,"dragManager"),e(this,"uiUpdaterUnsubscribe",null),e(this,"eventUpdaterUnsubscribe",null),e(this,"isInitialized",!1),e(this,"lastConfig",null),e(this,"lastUserIdentification",null),e(this,"handleStoreChanges",(()=>{if(!this.isInitialized)return;const e=Pt.getState();e.currentState===t.prevState.currentState&&e.currentStepId===t.prevState.currentStepId&&e.isMinimized===t.prevState.isMinimized||(t.prevState.currentState,e.currentState,t.prevState.currentStepId,e.currentStepId,t.prevState.isMinimized,e.isMinimized,this.uiManager.getPlayerRoot()&&this.uiManager.getPlayerElement()&&this.uiManager.updatePosition(),this.updateControlsVisibility(e.currentState),"autoplayBlocked"===e.currentState?this.buttonManager.updatePlayPauseButton("autoplayBlocked"):"completed"===e.currentState&&this.handleCompletedState(),e.isMinimized!==t.prevState.isMinimized&&this.uiManager.handleMinimizeStateChange(e.isMinimized),t.prevState={currentState:e.currentState,currentStepId:e.currentStepId,isMinimized:e.isMinimized})})),t.instance)throw new Error("SaltfishPlayer is a singleton. Use getInstance()");this.sessionManager=new Ut,this.shadowDOMManager=new n,this.videoManager=new Dt,this.eventManager=new Yt,this.analyticsManager=new Bt(this.eventManager),this.sessionRecordingManager=new Ot,this.playlistManager=new Xt(this.eventManager),this.cursorManager=new Vt,this.interactionManager=new Lt,this.buttonManager=new Ft,this.transitionManager=new Rt,this.triggerManager=new Nt,this.stepTimeoutManager=new ee((()=>this.destroy())),this.playerView=new $t,this.dragManager=new Wt,this.transitionManager.setTriggerManager(this.triggerManager),this.uiManager=new Jt(this.shadowDOMManager),Pt.subscribe(this.handleStoreChanges.bind(this)),this.registerStateMachineActions()}static getInstance(){return t.instance||(t.instance=new t),t.instance}getSessionId(){return this.sessionManager.getSessionId()}getRunId(){return this.sessionManager.getCurrentRunId()}async initialize(t){var e,n,i;if(this.isInitialized)console.warn("Saltfish playlist Player is already initialized");else try{const s=await fetch(`${dt}/validate-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:t.token})}),r=await s.json();if(!r.isValid)throw Gt.handleInitializationError(r.error||"Token validation failed",{component:"SaltfishPlayer",method:"initialize",additionalData:{token:(null==(e=t.token)?void 0:e.substring(0,10))+"..."}});const a=ne(t.language),o={...t,language:a,showLogo:!1!==r.showLogo};this.lastConfig=o;const l=Pt.getState();l.initialize(o);const c=(null==(n=l.user)?void 0:n.id)||(null==(i=this.lastUserIdentification)?void 0:i.userId);if(this.analyticsManager.initialize(t,this.sessionManager.getSessionId()),this.sessionRecordingManager.initialize(t,this.sessionManager.getSessionId(),c),!(r.playlists&&Array.isArray(r.playlists)&&l.setBackendPlaylists))throw Gt.handleInitializationError("Backend validation successful, but no playlists array provided in the response. Cannot initialize player.",{component:"SaltfishPlayer",method:"initialize",additionalData:{responseData:r}});r.playlists,l.setBackendPlaylists(r.playlists),this.triggerManager.registerTriggers(r.playlists),this.isInitialized=!0,window._saltfishPlayer=this,window._cursorManager=this.cursorManager,this.eventManager.trigger("initialized",{timestamp:Date.now()})}catch(s){throw Gt.handleInitializationError(s,{component:"SaltfishPlayer",method:"initialize"})}}identifyUser(t,e){this.lastUserIdentification={userId:t,userData:e};Pt.getState().identifyUser(t,e),this.analyticsManager.setUser({id:t,...e}),this.sessionRecordingManager.identifyUser({id:t,...e}),this.fetchUserData(t,e)}identifyAnonymous(t){const e=this.getOrCreateAnonymousUserId();this.lastUserIdentification={userId:e,userData:t};Pt.getState().identifyUser(e,{...t,__isAnonymous:!0}),this.analyticsManager.setUser({id:e,...t}),this.sessionRecordingManager.identifyUser({id:e,...t}),this.loadAnonymousUserData(e,t)}async fetchUserData(t,e){var n;try{const i=Pt.getState();if(!(null==(n=i.config)?void 0:n.token))return void Gt.handleWarning("Cannot fetch user data: Token not available",{component:"SaltfishPlayer",method:"fetchUserData",userId:t});const s=await fetch(`https://player.saltfish.ai/clients/${i.config.token}/users/${t}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userData:e})});if(!s.ok){await s.text();return s.status,void s.statusText}const r=await s.json();r.success&&(i.setUserData({watchedPlaylists:r.watchedPlaylists||{}}),this.eventManager.trigger("userDataLoaded",{timestamp:Date.now(),userId:t,userData:{watchedPlaylists:r.watchedPlaylists||{}}}),this.triggerManager.startMonitoring())}catch(i){Gt.handleNetworkError(i,{component:"SaltfishPlayer",method:"fetchUserData",userId:t})}}loadAnonymousUserData(t,e){try{if("undefined"==typeof window)return;const i=localStorage.getItem(et);let s={userId:t,userData:e||{},watchedPlaylists:{},timestamp:Date.now()};if(i)try{const n=JSON.parse(i);s={userId:t,userData:{...n.userData,...e},watchedPlaylists:n.watchedPlaylists||{},timestamp:Date.now()}}catch(n){}localStorage.setItem(et,JSON.stringify(s));Pt.getState().setUserData({watchedPlaylists:s.watchedPlaylists||{}}),this.eventManager.trigger("userDataLoaded",{timestamp:Date.now(),userId:t,userData:{watchedPlaylists:s.watchedPlaylists||{}}}),this.triggerManager.startMonitoring()}catch(i){Gt.handleNetworkError(i,{component:"SaltfishPlayer",method:"loadAnonymousUserData",userId:t})}}getOrCreateAnonymousUserId(){if("undefined"==typeof window)return`anonymous_${Date.now()}_${Math.random().toString(36).substring(2,11)}`;const t="saltfish_anonymous_user_id";try{let e=localStorage.getItem(t);return e||(e=`anonymous_${Date.now()}_${Math.random().toString(36).substring(2,11)}`,localStorage.setItem(t,e)),e}catch(e){return console.warn("SaltfishPlayer: localStorage not available, using session-only anonymous ID"),`anonymous_session_${Date.now()}_${Math.random().toString(36).substring(2,11)}`}}async startPlaylist(t,e){try{const s=this.isInitialized&&!this.uiManager.getPlayerElement();if(!this.isInitialized&&this.lastConfig)try{await this.initialize(this.lastConfig),this.lastUserIdentification&&this.identifyUser(this.lastUserIdentification.userId,this.lastUserIdentification.userData),this.videoManager.reset(),this.cursorManager.reset(),this.interactionManager=new Lt,this.buttonManager=new Ft,this.transitionManager=new Rt,this.playerView=new $t,this.dragManager=new Wt,this.uiManager=new Jt(this.shadowDOMManager),this.registerStateMachineActions()}catch(n){throw Gt.handleInitializationError(`Failed to reinitialize player: ${n instanceof Error?n.message:"Unknown error"}`,{component:"SaltfishPlayer",method:"startPlaylist",playlistId:t,additionalData:{reinitError:n}})}s&&(this.videoManager.reset(),this.cursorManager.reset(),this.interactionManager=new Lt,this.buttonManager=new Ft,this.transitionManager=new Rt,this.playerView=new $t,this.dragManager=new Wt,this.uiManager=new Jt(this.shadowDOMManager),this.stepTimeoutManager=new ee((()=>this.cleanupPlaylist())),this.transitionManager.setTriggerManager(this.triggerManager),this.registerStateMachineActions());const r=Pt.getState();if(!r.config){if(!this.lastConfig)throw Gt.createError("Saltfish Player must be initialized at least once before starting a playlist",{component:"SaltfishPlayer",method:"startPlaylist",playlistId:t});throw Gt.createError("Saltfish Player must be initialized before starting a playlist",{component:"SaltfishPlayer",method:"startPlaylist",playlistId:t})}r.manifest&&("playing"===r.currentState||"paused"===r.currentState||"loading"===r.currentState||"waitingForInteraction"===r.currentState||"autoplayBlocked"===r.currentState||"minimized"===r.currentState)&&(this.cleanupCurrentPlaylist(),r.resetForNewPlaylist(),this.registerStateMachineActions()),"completed"===r.currentState&&this.registerStateMachineActions();this.sessionManager.startNewRun();const a=new ie,o=await a.validatePlaylistStart({playlistId:t,options:e,eventManager:this.eventManager});if(!o.isValid)return;e=o.updatedOptions||e;const l=o.manifestPath,c=e||{};c?(r.setPlaylistOptions(c),c.position||r.setPlaylistOptions({...c,position:"bottom-right"}),this.uiManager.updatePosition()):(r.setPlaylistOptions({position:"bottom-right",allowDrag:!0}),this.uiManager.updatePosition());const d=(null==e?void 0:e.persistence)??!0;if(d&&"undefined"!=typeof window){const e=localStorage.getItem("saltfish_progress");if(e)try{const n=JSON.parse(e);n[t]&&r.loadPlaylistProgress(t,n[t])}catch(i){console.warn("Failed to parse saved progress for playlist:",t)}}this.analyticsManager.trackPlaylistStart(t),this.cursorManager.resetFirstAnimation(),this.uiManager.createPlayerUI(this.videoManager,this.cursorManager,this.interactionManager,this.buttonManager),this.setupUpdaters(),await this.playlistManager.load(l,{...c,persistence:d});const h=Pt.getState();if(c.startNodeId&&h.manifest){h.manifest.steps.find((t=>t.id===c.startNodeId))?h.goToStep(c.startNodeId):console.warn(`[SaltfishPlayer] startNodeId '${c.startNodeId}' not found in manifest steps. Starting from default step.`)}else h.manifest;h.manifest&&(h.manifest.cursorColor&&this.cursorManager.setColor(h.manifest.cursorColor),this.eventManager.trigger("playlistStarted",{timestamp:Date.now(),playlist:{id:t,title:h.manifest.name}})),r.play(),mt(`Playlist started: ${t}${h.manifest?` (${h.manifest.name})`:""}`)}catch(s){Gt.handlePlaylistError(s,{component:"SaltfishPlayer",method:"startPlaylist",playlistId:t,errorType:"playlist_load_failed"})}}registerStateMachineActions(){const t=Pt.getState();t.stateMachine.registerActions({startVideoPlayback:e=>{if(!e.currentStep)return;const n=this.getVideoUrl(e.currentStep);try{this.videoManager.showProgressBar(),this.videoManager.showMuteButton(),this.interactionManager.clearButtons(),this.interactionManager.clearDOMInteractions(),e.currentStep.domInteractions&&this.interactionManager.setupDOMInteractions(e.currentStep.domInteractions),e.currentStep.buttons&&this.interactionManager.createButtons(e.currentStep.buttons),e.currentStep.id,e.currentStep.cursorAnimations&&e.currentStep.cursorAnimations.length,e.currentStep.cursorAnimations&&e.currentStep.cursorAnimations.length>0?(e.currentStep.id,this.cursorManager.setShouldShowCursor(!0),e.currentStep.id,e.currentStep.cursorAnimations[0].targetSelector,this.cursorManager.animate(e.currentStep.cursorAnimations[0])):(e.currentStep.id,this.cursorManager.setShouldShowCursor(!1));const i=e.currentStep.buttons&&e.currentStep.buttons.length>0||e.currentStep.transitions.some((t=>"dom-click"===t.type||"url-path"===t.type)),s=i?"manual":"auto";i&&this.transitionManager.setupTransitions(e.currentStep,!1),this.videoManager.setCompletionPolicy(s,(()=>{e.currentStep&&(i||this.transitionManager.setupTransitions(e.currentStep,!0),t.stateMachine.send({type:"VIDEO_ENDED",step:e.currentStep}))})),this.videoManager.loadVideo(n).then((()=>{var t;if(e.currentStep){const n=null==(t=Pt.getState().config)?void 0:t.language;let i=e.currentStep.transcript;if(n&&e.currentStep.translations&&e.currentStep.translations[n]){const t=e.currentStep.translations[n].transcript;t&&(i=t,e.currentStep.id)}i?(e.currentStep.id,this.videoManager.loadTranscript(i)):(e.currentStep.id,this.videoManager.loadTranscript(null))}else this.videoManager.loadTranscript(null);if(this.videoManager.play(),e.currentStep){const t=this.findNextVideoUrl(e.currentStep);t&&this.videoManager.preloadNextVideo(t)}})).catch((n=>{var i,s;this.eventManager.trigger("error",{timestamp:Date.now(),playlistId:(null==(i=t.manifest)?void 0:i.id)||void 0,stepId:null==(s=e.currentStep)?void 0:s.id,error:n instanceof Error?n:new Error(`Failed to load video: ${n}`),errorType:"video"})}))}catch(i){}},pauseVideoPlayback:()=>{this.videoManager.pause()},startMutedLoopedVideo:()=>{const t=this.videoManager.getVideoElement();t&&(t.muted=!0,t.loop=!0,t.play().catch((()=>{}))),this.videoManager.hideProgressBar(),this.videoManager.hideMuteButton()},trackPlaylistComplete:()=>{this.handleCompletedState()},handleError:e=>{var n,i;if(null==(n=e.error)||n.message,e.error&&this.uiManager.getPlayerElement()){const n=document.createElement("div");n.className="saltfish-error",n.textContent=`Error: ${e.error.message}`;const s=this.uiManager.getPlayerElement();s&&(s.innerHTML="",s.appendChild(n)),this.eventManager.trigger("error",{timestamp:Date.now(),playlistId:(null==(i=t.manifest)?void 0:i.id)||void 0,stepId:t.currentStepId||void 0,error:e.error,errorType:"player"})}}})}findNextVideoUrl(t){const e=Pt.getState();if(!e.manifest||!t)return null;if(t.transitions.length>0){const n=t.transitions[0];if("url-path"===n.type||"dom-click"===n.type)return null;const i=n.nextStep,s=e.manifest.steps.find((t=>t.id===i));if(s)return this.getVideoUrl(s)}const n=e.manifest.steps.findIndex((e=>e.id===t.id));return n>=0&&n<e.manifest.steps.length-1?this.getVideoUrl(e.manifest.steps[n+1]):null}getVideoUrl(t){var e;const n=null==(e=Pt.getState().config)?void 0:e.language;if(n&&t.translations&&t.translations[n]){return t.translations[n].videoUrl}return t.compressedVideoUrl||t.videoUrl}setupUpdaters(){this.uiUpdaterUnsubscribe&&this.uiUpdaterUnsubscribe(),this.eventUpdaterUnsubscribe&&this.eventUpdaterUnsubscribe();const t=this.uiManager.getPlayerElement();t&&(this.uiUpdaterUnsubscribe=Kt(t,this.cursorManager)),this.eventUpdaterUnsubscribe=Qt(this.eventManager);const e=Pt.subscribe((t=>{this.stepTimeoutManager.update({currentState:t.currentState,currentStepId:t.currentStepId,isMinimized:t.isMinimized,previousState:void 0})})),n=this.eventUpdaterUnsubscribe;this.eventUpdaterUnsubscribe=()=>{n&&n(),e()}}destroy(){var t;if(this.isInitialized)try{const e=Pt.getState();e.currentState,e.currentStepId,e.isMinimized,null==(t=e.manifest)||t.id,this.uiUpdaterUnsubscribe&&(this.uiUpdaterUnsubscribe(),this.uiUpdaterUnsubscribe=null),this.eventUpdaterUnsubscribe&&(this.eventUpdaterUnsubscribe(),this.eventUpdaterUnsubscribe=null),this.transitionManager.destroy(),this.triggerManager.destroy(),this.videoManager.destroy(),this.cursorManager.destroy(),this.interactionManager.destroy(),this.buttonManager.destroy(),this.analyticsManager.destroy(),this.sessionManager.destroy(),this.playlistManager.destroy(),this.stepTimeoutManager.destroy(),this.playerView.destroy(),this.dragManager.destroy(),this.uiManager.destroy(),this.isInitialized=!1,e.reset()}catch(e){Gt.handleCleanupError(e,{component:"SaltfishPlayer",method:"destroy"});try{this.isInitialized=!1;Pt.getState().reset()}catch(n){Gt.handleCleanupError(n,{component:"SaltfishPlayer",method:"destroy",additionalData:{originalError:e}})}}else console.warn("Saltfish playlist Player is not initialized")}handleCompletedState(){null!==t.destroyTimeoutId&&(t.destroyTimeoutId,window.clearTimeout(t.destroyTimeoutId),t.destroyTimeoutId=null);const e=Pt.getState();e.manifest&&this.eventManager.trigger("playlistEnded",{timestamp:Date.now(),playlist:{id:e.manifest.id,title:e.manifest.name}}),this.cleanupPlaylist()}on(t,e){this.eventManager.on(t,e)}off(t,e){return this.eventManager.off(t,e)}resetPlaylist(){const t=Pt.getState();t.manifest&&t.goToStep(t.manifest.startStep)}cleanupCurrentPlaylist(){try{this.stepTimeoutManager&&this.stepTimeoutManager.reset(),this.videoManager&&this.videoManager.pause(),this.cursorManager&&(this.cursorManager.stopAnimation(),this.cursorManager.setShouldShowCursor(!1)),this.transitionManager&&this.transitionManager.cleanupTransitions(),this.interactionManager&&(this.interactionManager.clearButtons(),this.interactionManager.clearDOMInteractions()),this.uiManager.resetDragState()}catch(t){Gt.handleCleanupError(t,{component:"SaltfishPlayer",method:"cleanupCurrentPlaylist"})}}cleanupPlaylist(){var t;if(this.isInitialized)try{const e=Pt.getState();e.currentState,e.currentStepId,e.isMinimized,null==(t=e.manifest)||t.id,this.uiUpdaterUnsubscribe&&(this.uiUpdaterUnsubscribe(),this.uiUpdaterUnsubscribe=null),this.eventUpdaterUnsubscribe&&(this.eventUpdaterUnsubscribe(),this.eventUpdaterUnsubscribe=null),this.transitionManager.destroy(),this.videoManager.destroy(),this.cursorManager.destroy(),this.interactionManager.destroy(),this.buttonManager.destroy(),this.playlistManager.destroy(),this.stepTimeoutManager.destroy(),this.playerView.destroy(),this.dragManager.destroy(),this.uiManager.destroy(),e.resetForNewPlaylist()}catch(e){Gt.handleCleanupError(e,{component:"SaltfishPlayer",method:"cleanupPlaylist"})}else console.warn("Saltfish playlist Player is not initialized")}updateControlsVisibility(t){this.uiManager.updateControlsVisibility(t)}};e(se,"instance",null),e(se,"prevState",{currentState:null,currentStepId:null,isMinimized:!1}),e(se,"destroyTimeoutId",null);let re=se;const ae=Object.freeze(Object.defineProperty({__proto__:null,SaltfishPlayer:re},Symbol.toStringTag,{value:"Module"})),oe={id:"default_mock_playlist",name:"Default playlist Demo",version:"1.0.0",position:"bottom-right",startStep:"intro",steps:[{id:"intro",videoUrl:"https://storage.saltfish.ai/videos/QSWY4Wc8pcBVYHNQM12P.mp4",transitions:[{type:"timeout",timeout:0,nextStep:"dashboard_overview"},{type:"dom-element-visible",target:"body",nextStep:"dashboard_overview"}]},{id:"dashboard_overview",videoUrl:"https://storage.saltfish.ai/videos/rEWoNbKLAUQSvLmzHGmv.mp4",position:"bottom-left",domInteractions:[{selector:"#feature-chart",action:"hover",waitFor:!1}],buttons:[{id:"skip_button",text:"Skip",action:{type:"goto",target:"user_settings"}}],transitions:[]},{id:"user_settings",videoUrl:"https://storage.saltfish.ai/codeformer/oNcN4ZoQXFFnMmaOwEC3/result.mp4",position:"top-right",buttons:[{id:"finish_button",text:"Finish Tour",action:{type:"goto",target:"conclusion"}},{id:"finish_two",text:"Finish Tour",action:{type:"goto",target:"conclusion"}}],transitions:[{type:"dom-click",target:"div:nth-of-type(3) > h2",nextStep:"conclusion"}],cursorAnimations:[{easing:"ease-out",targetSelector:"div:nth-of-type(3) > h2"}]},{id:"conclusion",videoUrl:"https://storage.saltfish.ai/memo/5z5IDHYzuGDjx41hpvSo/result.mp4",transitions:[]}],cursorColor:"#ff7614"},le={id:"second_mock_playlist",name:"Second Playlist Demo",version:"1.0.0",position:"bottom-right",startStep:"step1",steps:[{id:"step1",videoUrl:"https://storage.saltfish.ai/videos/7e07f378-3059-4694-8659-8a4c1f04442d.mp4",transcript:{text:"Welcome to this demo video. We will show you how to use the transcript feature.",segments:[{text:"Welcome to this demo video.",start:0,end:2.5},{text:"We will show you how to use the transcript feature.",start:2.5,end:5}]},transitions:[{type:"dom-element-visible",target:"#root > div > main > div.PreviewPage_footer__Ynnux > button",nextStep:"step2"}]},{id:"step2",videoUrl:"https://storage.saltfish.ai/videos/799b36f2-fc36-4864-8b6d-f8bf3d578140.mp4",position:"bottom-left",transitions:[{type:"dom-click",target:"#root > div > main > div.PreviewPage_footer__Ynnux > button",nextStep:"step3"}]},{id:"step3",videoUrl:"https://storage.saltfish.ai/videos/edb65857-e7c1-4edd-a4fc-67cf35880ac4.mp4",buttons:[{id:"continue_button",text:"Continue to Step 4",action:{type:"goto",target:"step4"}},{id:"skip_to_end",text:"Skip to End",action:{type:"goto",target:"step9"}}],transitions:[{type:"timeout",timeout:0,nextStep:"step4"}]},{id:"step4",videoUrl:"https://storage.saltfish.ai/videos/f25d8c5d-f7b6-48b1-ac39-4aae5124100a.mp4",position:"center",cursorAnimations:[{easing:"ease-out",targetSelector:"#audience-chat-messages-panel-0 > div > div > div._container_1juas_1.MessageInput_container__KdCLm > div > button"}],transitions:[{type:"dom-element-visible",target:"#audience-chat-messages-panel-0 > div > div > div._container_vk4n0_1 > div.str-chat__virtual-list > div > div > div:nth-child(2) > div > div > div",nextStep:"step5"}]},{id:"step5",videoUrl:"https://storage.saltfish.ai/videos/e89abe5e-b83f-4ba5-8286-ee6e307bcf43.mp4",cursorAnimations:[{easing:"ease-out",targetSelector:"#audience-chat-messages-panel-0 > div > div > div._container_vk4n0_1 > div.str-chat__virtual-list > div > div > div:nth-child(2) > div > div > div > div._container_4oo5p_1 > div:nth-child(2) > button"}],transitions:[{type:"dom-click",target:"#root > div > main > div.PreviewPage_footer__Ynnux > button",nextStep:"step6"}]},{id:"step6",videoUrl:"https://storage.saltfish.ai/videos/0ec59567-e865-4f9b-9ecd-7e4c5f2638a4.mp4",transitions:[{type:"timeout",timeout:0,nextStep:"step7"}]},{id:"step7",videoUrl:"https://storage.saltfish.ai/videos/38593171-53ac-426b-a6a8-0a3182c5947d.mp4",position:"top-left",cursorAnimations:[{easing:"ease-out",targetSelector:"#root > div > main > section > div.SideButtons_container__jqcKh > div:nth-child(1)"}],transitions:[{type:"dom-click",target:"#root > div > main > section > div.SideButtons_container__jqcKh > div:nth-child(1)",nextStep:"step3"}]},{id:"step8",videoUrl:"https://storage.saltfish.ai/videos/91441f25-2ffa-46dc-92fd-711be8512d27.mp4",transitions:[{type:"timeout",timeout:0,nextStep:"step9"}]},{id:"step9",videoUrl:"https://storage.saltfish.ai/videos/ecf26de5-c94c-4bef-b88c-6773420e01f4.mp4",transitions:[]}],cursorColor:"#ff7614"};function ce(t,e=!1){const n=e?oe:le;return{...n,...t,steps:t.steps||n.steps}}const de=function(){const t=re.getInstance();let e=!1,n=!1,i=null;const s=[],r={init:r=>{if(n)return mt("Saltfish already initialized"),Promise.resolve();if(e&&i)return i;const a={sessionRecording:!1,enableAnalytics:!0,..."string"==typeof r?{token:r}:r};return mt(`Saltfish initialized: analytics=${a.enableAnalytics}, language=${a.language||"default"}`),e=!0,i=t.initialize(a).then((()=>(n=!0,e=!1,(async()=>{if(0!==s.length)for(;s.length>0;){const e=s.shift();if(e)try{await e()}catch(t){yt("Error executing queued command:",t)}}})()))).catch((t=>{throw e=!1,t("Saltfish initialization failed:",t),t})),i},identify:(i,r)=>{n||!e?t.identifyUser(i,r):s.push((async()=>{t.identifyUser(i,r)}))},identifyAnonymous:i=>{n||!e?t.identifyAnonymous(i):s.push((async()=>{t.identifyAnonymous(i)}))},startPlaylist:(r,a)=>!n&&e?new Promise(((e,n)=>{s.push((async()=>{try{await t.startPlaylist(r,a),e()}catch(i){n(i)}})),i&&i.catch(n)})):t.startPlaylist(r,a),on:(e,n)=>{t.on(e,n)},off:(e,n)=>t.off(e,n),resetPlaylist:()=>{n||e?n||!e?t.resetPlaylist():s.push((async()=>{t.resetPlaylist()})):ft("Cannot reset playlist - Saltfish not initialized")},destroy:()=>{n||e?(e||(n=!1,e=!1,i=null,s.length=0),t.destroy(),n=!1,e=!1,i=null):ft("Cannot destroy - Saltfish not initialized")},getSessionId:()=>t.getSessionId(),getRunId:()=>t.getRunId()};return r.__dev__={setMockManifest:t=>{"undefined"!=typeof window&&(window.demoManifest=t)},createMockManifest:ce,defaultMockManifest:le,getDeviceInfo:()=>Ct.getDeviceInfo()},r}();return"undefined"!=typeof window&&(window.saltfish=de),de}));
9
9