saltfish 0.1.21 → 0.1.22
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/core/stateMachineConfig.d.ts.map +1 -1
- package/dist/managers/VideoManager.d.ts.map +1 -1
- package/dist/player.js +2 -2
- package/dist/player.min.js +2 -2
- package/dist/saltfish-playlist-player.es.js +18 -3
- package/dist/saltfish-playlist-player.umd.js +1 -1
- package/dist/updaters/UIUpdater.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/player.min.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Saltfish playlist Player v0.1.
|
|
2
|
+
* Saltfish playlist Player v0.1.22
|
|
3
3
|
* (c) 2025
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
|
|
6
6
|
*/
|
|
7
|
-
!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(){return this.shadowRoot?this.shadowRoot.getElementById("sf-player-root"):null}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={};var s=Symbol.for("immer-nothing"),r=Symbol.for("immer-draftable"),a=Symbol.for("immer-state");function o(t,...e){throw new Error(`[Immer] minified error nr: ${t}. Full error at: https://bit.ly/3cXEKWf`)}var l=Object.getPrototypeOf;function c(t){return!!t&&!!t[a]}function d(t){var e;return!!t&&(u(t)||Array.isArray(t)||!!t[r]||!!(null==(e=t.constructor)?void 0:e[r])||y(t)||v(t))}var h=Object.prototype.constructor.toString();function u(t){if(!t||"object"!=typeof t)return!1;const e=l(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)===h}function p(t,e){0===g(t)?Reflect.ownKeys(t).forEach((n=>{e(n,t[n],t)})):t.forEach(((n,i)=>e(i,n,t)))}function g(t){const e=t[a];return e?e.type_:Array.isArray(t)?1:y(t)?2:v(t)?3:0}function m(t,e){return 2===g(t)?t.has(e):Object.prototype.hasOwnProperty.call(t,e)}function f(t,e,n){const i=g(t);2===i?t.set(e,n):3===i?t.add(n):t[e]=n}function y(t){return t instanceof Map}function v(t){return t instanceof Set}function b(t){return t.copy_||t.base_}function w(t,e){if(y(t))return new Map(t);if(v(t))return new Set(t);if(Array.isArray(t))return Array.prototype.slice.call(t);const n=u(t);if(!0===e||"class_only"===e&&!n){const e=Object.getOwnPropertyDescriptors(t);delete e[a];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(l(t),e)}{const e=l(t);if(null!==e&&n)return{...t};const i=Object.create(e);return Object.assign(i,t)}}function S(t,e=!1){return E(t)||c(t)||!d(t)||(g(t)>1&&(t.set=t.add=t.clear=t.delete=M),Object.freeze(t),e&&Object.entries(t).forEach((([t,e])=>S(e,!0)))),t}function M(){o(2)}function E(t){return Object.isFrozen(t)}var x,I={};function P(t){const e=I[t];return e||o(0),e}function C(){return x}function T(t,e){e&&(P("Patches"),t.patches_=[],t.inversePatches_=[],t.patchListener_=e)}function _(t){k(t),t.drafts_.forEach(A),t.drafts_=null}function k(t){t===x&&(x=t.parent_)}function z(t){return x={drafts_:[],parent_:x,immer_:t,canAutoFreeze_:!0,unfinalizedDrafts_:0}}function A(t){const e=t[a];0===e.type_||1===e.type_?e.revoke_():e.revoked_=!0}function D(t,e){e.unfinalizedDrafts_=e.drafts_.length;const n=e.drafts_[0];return void 0!==t&&t!==n?(n[a].modified_&&(_(e),o(4)),d(t)&&(t=V(e,t),e.parent_||B(e,t)),e.patches_&&P("Patches").generateReplacementPatches_(n[a].base_,t,e.patches_,e.inversePatches_)):t=V(e,n,[]),_(e),e.patches_&&e.patchListener_(e.patches_,e.inversePatches_),t!==s?t:void 0}function V(t,e,n){if(E(e))return e;const i=e[a];if(!i)return p(e,((s,r)=>L(t,i,e,s,r,n))),e;if(i.scope_!==t)return e;if(!i.modified_)return B(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),p(s,((s,a)=>L(t,i,e,s,a,n,r))),B(t,e,!1),n&&t.patches_&&P("Patches").generatePatches_(i,n,t.patches_,t.inversePatches_)}return i.copy_}function L(t,e,n,i,s,r,a){if(c(s)){const a=V(t,s,r&&e&&3!==e.type_&&!m(e.assigned_,i)?r.concat(i):void 0);if(f(n,i,a),!c(a))return;t.canAutoFreeze_=!1}else a&&n.add(s);if(d(s)&&!E(s)){if(!t.immer_.autoFreeze_&&t.unfinalizedDrafts_<1)return;V(t,s),e&&e.scope_.parent_||"symbol"==typeof i||!Object.prototype.propertyIsEnumerable.call(n,i)||B(t,s)}}function B(t,e,n=!1){!t.parent_&&t.immer_.autoFreeze_&&t.canAutoFreeze_&&S(e,n)}var O={get(t,e){if(e===a)return t;const n=b(t);if(!m(n,e))return function(t,e,n){var i;const s=R(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_||!d(i)?i:i===F(t.base_,e)?(Y(t),t.copy_[e]=H(i,t)):i},has:(t,e)=>e in b(t),ownKeys:t=>Reflect.ownKeys(b(t)),set(t,e,n){const i=R(b(t),e);if(null==i?void 0:i.set)return i.set.call(t.draft_,n),!0;if(!t.modified_){const i=F(b(t),e),o=null==i?void 0:i[a];if(o&&o.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||m(t.base_,e)))return!0;Y(t),N(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!==F(t.base_,e)||e in t.base_?(t.assigned_[e]=!1,Y(t),N(t)):delete t.assigned_[e],t.copy_&&delete t.copy_[e],!0),getOwnPropertyDescriptor(t,e){const n=b(t),i=Reflect.getOwnPropertyDescriptor(n,e);return i?{writable:!0,configurable:1!==t.type_||"length"!==e,enumerable:i.enumerable,value:n[e]}:i},defineProperty(){o(11)},getPrototypeOf:t=>l(t.base_),setPrototypeOf(){o(12)}},U={};function F(t,e){const n=t[a];return(n?b(n):t)[e]}function R(t,e){if(!(e in t))return;let n=l(t);for(;n;){const t=Object.getOwnPropertyDescriptor(n,e);if(t)return t;n=l(n)}}function N(t){t.modified_||(t.modified_=!0,t.parent_&&N(t.parent_))}function Y(t){t.copy_||(t.copy_=w(t.base_,t.scope_.immer_.useStrictShallowCopy_))}function H(t,e){const n=y(t)?P("MapSet").proxyMap_(t,e):v(t)?P("MapSet").proxySet_(t,e):function(t,e){const n=Array.isArray(t),i={type_:n?1:0,scope_:e?e.scope_:C(),modified_:!1,finalized_:!1,assigned_:{},parent_:e,base_:t,draft_:null,copy_:null,revoke_:null,isManual_:!1};let s=i,r=O;n&&(s=[i],r=U);const{revoke:a,proxy:o}=Proxy.revocable(s,r);return i.draft_=o,i.revoke_=a,o}(t,e);return(e?e.scope_:C()).drafts_.push(n),n}function X(t){if(!d(t)||E(t))return t;const e=t[a];let n;if(e){if(!e.modified_)return e.base_;e.finalized_=!0,n=w(t,e.scope_.immer_.useStrictShallowCopy_)}else n=w(t,!0);return p(n,((t,e)=>{f(n,t,X(e))})),e&&(e.finalized_=!1),n}p(O,((t,e)=>{U[t]=function(){return arguments[0]=arguments[0][0],e.apply(this,arguments)}})),U.deleteProperty=function(t,e){return U.set.call(this,t,e,void 0)},U.set=function(t,e,n){return O.set.call(this,t[0],e,n,t[0])};var $=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&&o(6),void 0!==n&&"function"!=typeof n&&o(7),d(t)){const s=z(this),r=H(t,void 0);let a=!0;try{i=e(r),a=!1}finally{a?_(s):k(s)}return T(s,n),D(i,s)}if(!t||"object"!=typeof t){if(i=e(t),void 0===i&&(i=t),i===s&&(i=void 0),this.autoFreeze_&&S(i,!0),n){const e=[],s=[];P("Patches").generateReplacementPatches_(t,i,e,s),n(e,s)}return i}o(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){d(t)||o(8),c(t)&&(t=function(t){return c(t)||o(10),X(t)}(t));const e=z(this),n=H(t,void 0);return n[a].isManual_=!0,k(e),n}finishDraft(t,e){const n=t&&t[a];n&&n.isManual_||o(9);const{scope_:i}=n;return T(i,e),D(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=P("Patches").applyPatches_;return c(t)?i(t,e):this.produce(t,(t=>i(t,e)))}},W=$.produce;$.produceWithPatches.bind($),$.setAutoFreeze.bind($),$.setUseStrictShallowCopy.bind($),$.applyPatches.bind($),$.createDraft.bind($),$.finishDraft.bind($);const j="bottom",q="right",Z="center",J="saltfish_progress",K="saltfish_session",Q="saltfish_anonymous_user_data",G=20,tt="-50%",et="-50%",nt="-100%",it="sf-player--minimized";function st(t,e){void 0!==e?console.info(t,e):console.info(t)}function rt(t,e){console.warn(t)}function at(t,e){void 0!==e?console.error(t,e):console.error(t)}class ot{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];return e?(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,this.currentState=e.target,this.runEntryActions(this.currentState),this.currentState,this.currentState):(t.type,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 lt={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"]}}},ct=20,dt=()=>{const t=document.getElementById("saltfish-container");return t&&t.shadowRoot?t:document.documentElement},ht=()=>{if("undefined"!=typeof window){const t=dt(),e=getComputedStyle(t).getPropertyValue("--sf-player-width");return parseInt(e,10)||200}return 200},ut=t=>{const e=t?(()=>{if("undefined"!=typeof window){const t=dt(),e=getComputedStyle(t);return parseInt(e.getPropertyValue("--sf-player-min-width"),10)||80}return 80})():ht();return{width:e,minX:20,maxX:window.innerWidth-e-ct}};class pt{static calculatePosition(t){const{position:e,viewportWidth:n=window.innerWidth,viewportHeight:i=window.innerHeight,playerWidth:s=ht()}=t;let r=G,a=G,o="0",l="0";return e.includes(j)&&(a=i-G,l=nt),e.includes("left")?r=G:e.includes(q)?r=n-s-ct:e.includes(Z)&&(r=n/2,a=i/2,o=tt,l=et),{...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(j)&&!i.includes(Z)&&(l=r-G),i.includes(q)&&!i.includes(Z)&&(o=Math.max(G,Math.min(o,s-a-ct))),o=Math.max(G,Math.min(o,s-a-ct)),l=Math.max(G,Math.min(l,r-G)),{x:o,y:l}}static calculateDragPosition(t){const{x:e,y:n,position:i,viewportWidth:s=window.innerWidth,viewportHeight:r=window.innerHeight,playerWidth:a=ht()}=t;let o=e,l=n;(null==i?void 0:i.includes(q))&&!i.includes(Z)&&(o=Math.min(o,s-a-ct));const c=s-a-ct;return o=Math.max(20,Math.min(o,c)),l=Math.max(G,Math.min(l,r-G)),{x:o,y:l}}static getTransforms(t){let e="0",n="0";return t.includes(Z)?(e=tt,n=et):t.includes(j)&&(n=nt),{transformX:e,transformY:n}}static shouldForceReposition(t,e,n){return"bottom-left"===t&&!n&&(e===window.innerHeight-G||Math.abs(e-(window.innerHeight-G))<5)}static getPlayerDimensions(){const t=ht();return{width:t,minX:G,maxX:window.innerWidth-t-ct}}}const gt=(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})((t=>(e,n,i)=>(i.setState=(t,n,...i)=>{const s="function"==typeof t?W(t):t;return e(s,n,...i)},t(i.setState,n,i)))(((t,e)=>{const n=new ot(lt,{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=pt.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=pt.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)??1)&&"undefined"!=typeof window&&localStorage.setItem(J,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(J,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 ot(lt,{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(J,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 ot(lt,{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}))}}}))),mt={getState:()=>gt.getState(),setState:gt.setState,subscribe:gt.subscribe,destroy:gt.destroy};class ft{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(t){console.warn("DeviceDetector: Error in device change handler:",t)}};return window.addEventListener("orientationchange",e),window.addEventListener("resize",e),()=>{window.removeEventListener("orientationchange",e),window.removeEventListener("resize",e)}}}e(ft,"cachedDeviceInfo",null);const yt=Object.freeze(Object.defineProperty({__proto__:null,DeviceDetector:ft,isDeviceCompatible:t=>{if(!t||"both"===t)return!0;const e=ft.getDeviceInfo();return"mobile"===t?e.isMobile||e.isTablet:"desktop"===t&&e.isDesktop}},Symbol.toStringTag,{value:"Module"}));class vt{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 bt{constructor(t){e(this,"deviceInfo"),this.deviceInfo=t}updateDeviceInfo(t){this.deviceInfo=t}}class wt extends bt{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(t){console.warn(`MobilePlaybackHandler: Failed to set attribute ${e}:`,t)}})),Object.entries(e.styles).forEach((([e,n])=>{try{t.style[e]=n}catch(t){console.warn(`MobilePlaybackHandler: Failed to set style ${e}:`,t)}}))}configureControlElement(t){const e=this.getControlsConfig();t.style.minWidth=e.buttonMinSize.width,t.style.minHeight=e.buttonMinSize.height}async handlePlayAttempt(t,e){const n=mt.getState().isMuted;t.muted=n,t.loop=!1;try{return await t.play(),!0}catch(e){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(t){console.error("MobilePlaybackHandler: All autoplay attempts failed")}}destroy(){}getProgressUpdateFrequency(t){return t?500:16}}class St extends bt{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=mt.getState().isMuted;t.muted=n,t.loop=!1;try{return await t.play(),!0}catch(e){return t.muted,await this.handleAutoplayFallback(t),!1}}async handleAutoplayFallback(t){t.muted=!0,t.loop=!0;try{await t.play()}catch(t){throw console.error("DesktopPlaybackHandler: All autoplay attempts failed"),new Error("Desktop autoplay completely blocked")}}getProgressUpdateFrequency(t){return 16}destroy(){}}class Mt{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=>{t.target===this.getActiveVideo()&&"autoplayBlocked"!==mt.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=mt.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&&mt.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)??1)&&"undefined"!=typeof window&&localStorage.setItem(J,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=mt.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 mt.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)??1)&&"undefined"!=typeof window&&localStorage.setItem(J,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=ft.getDeviceInfo();this.deviceHandler=function(t){return t.isMobile?new wt(t):new St(t)}(t),this.transcriptManager=new vt,this.deviceChangeCleanup=ft.onDeviceChange((t=>{this.deviceHandler.updateDeviceInfo(t),this.handleDeviceChange(t)}))}getDeviceInfo(){return ft.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),mt.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=mt.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=mt.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=mt.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}if(i&&this.currentVideoUrl&&n.currentTime>0&&this.playbackPositions.set(this.currentVideoUrl,n.currentTime),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(t){throw console.error("VideoManager: Failed to load video:",t),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=mt.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=mt.getState();if(((null==(t=n.playlistOptions)?void 0:t.persistence)??1)&&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"),mt.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),mt.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 Et{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){return document.querySelector(t)||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 t of s){const n=t.getBoundingClientRect();if(!(e.top>=n.top&&e.bottom<=n.bottom&&e.left>=n.left&&e.right<=n.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"===gt.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((()=>{this.targetMutationObserver?this.findElement(t.targetSelector)&&(clearInterval(e),this.targetMutationObserver.disconnect(),this.targetMutationObserver=null,this.animate(t)):clearInterval(e)}),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((()=>{this.targetMutationObserver?this.findElement(t)&&(clearInterval(i),this.targetMutationObserver.disconnect(),this.targetMutationObserver=null,this.moveToElement(t,e,n)):clearInterval(i)}),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 xt{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=mt.subscribe(((t,e)=>{t.isMinimized!==(null==e?void 0:e.isMinimized)&&this.updateButtonPositions()}))}createButtons(t){this.container&&(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)})),mt.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(){this.buttonContainer&&0!==this.buttons.length&&(mt.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(e){console.error(`InteractionManager: Error setting up DOM interaction for selector "${t.selector}":`,e)}}))}clearDOMInteractions(){this.domEventListeners.forEach((({element:t,listener:e,type:n})=>{try{t.removeEventListener(n,e)}catch(t){console.error("InteractionManager: Error removing event listener:",t)}})),this.domEventListeners.clear()}async handleButtonClick(t,e){e.id,t.preventDefault(),t.stopPropagation();const n=mt.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((()=>Wt)),i=t.getInstance();i&&i.destroy();break;case"dom":e.action.target;const s=document.querySelector(e.action.target);s?s.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(t){console.error(`InteractionManager: Error calling function "${e.action.target}":`,t)}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(mt.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((()=>Wt)),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 It{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 mt.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 $t.getInstance().getRunId()}catch(t){return null}}}class Pt{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(t){e(t)}}))}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 Ct{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(K);if(t){const e=JSON.parse(t);if(Date.now()-e.lastActivity<18e5)return e.sessionId,this.updateSessionActivity(e.sessionId),e.sessionId}}catch(t){}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(K,JSON.stringify(e))}catch(t){}}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(K),this.sessionId),this.sessionId=this.generateUniqueId(),this.updateSessionActivity(this.sessionId),this.currentRunId=null,this.sessionId}destroy(){this.updateSessionActivity(this.sessionId),this.endCurrentRun()}}class Tt{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=mt.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=mt.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=mt.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 _t{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=mt.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=mt.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 kt{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=mt.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){return!t||!(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 zt{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(e){console.error(`Error in ${t} event handler:`,e)}})))}removeAllListeners(){this.listeners.clear()}getListenerCount(t){const e=this.listeners.get(t);return e?e.size:0}}class At{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(t){const e=t instanceof Error?t.message:"Unknown error";throw at("[PlaylistLoader] Failed to load manifest:",t),new Error(`Unable to load playlist manifest: ${e}`)}}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 at("[PlaylistLoader] Fetch/parse failed:",n),at("[PlaylistLoader] Manifest path:",t),at("[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 e of t.steps){if(!e.id)throw new Error("Each step must have an id");if(!e.videoUrl)throw new Error(`Step '${e.id}' must have a videoUrl`);if(!e.transitions||!Array.isArray(e.transitions))throw new Error(`Step '${e.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;e.completedWaitingForInteraction?a=t.startStep:t.steps.find((t=>t.id===i))&&(a=i)}return a}}class Dt{constructor(t){e(this,"eventManager",null),e(this,"isUpdatingWatchedPlaylists",!1),e(this,"playlistLoader"),this.playlistLoader=new At,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 mt.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 c=this.getStore();if(!c)return;const d=c.userData||{},h=d.watchedPlaylists||{},u={status:e,currentStepId:n||c.currentStepId||null,lastProgressAt:Date.now()},p={...h,[t]:u};if(c.setUserData({...d,watchedPlaylists:p}),!(null==(i=null==c?void 0:c.config)?void 0:i.token)||!(null==(s=null==c?void 0:c.user)?void 0:s.id)||(null==(r=null==c?void 0:c.user)?void 0:r.__isAnonymous))return null==(a=null==c?void 0:c.config)||a.token,null==(o=null==c?void 0:c.user)||o.id,null==(l=null==c?void 0:c.user)||l.__isAnonymous,void this.updateAnonymousUserWatchedPlaylists(t,e,n||c.currentStepId||null);const g=`https://player.saltfish.ai/clients/${c.config.token}/users/${c.user.id}/playlists/${t}`;try{const t=await fetch(g,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({status:e,currentStepId:n||c.currentStepId||null})});if(!t.ok)throw new Error(`Failed to update watched playlist status: ${t.statusText} (${t.status})`)}catch(e){console.error(`PlaylistManager: Error updating watched playlist status for ${t}:`,e)}}finally{this.isUpdatingWatchedPlaylists=!1}}}updateAnonymousUserWatchedPlaylists(t,e,n){if("undefined"!=typeof window)try{const i=localStorage.getItem(Q);let s={userId:"anonymous",userData:{},watchedPlaylists:{},timestamp:Date.now()};if(i)try{s=JSON.parse(i)}catch(t){}s.watchedPlaylists||(s.watchedPlaylists={}),s.watchedPlaylists[t]={status:e,currentStepId:n||null,lastProgressAt:Date.now()},s.timestamp=Date.now(),localStorage.setItem(Q,JSON.stringify(s))}catch(t){console.error("PlaylistManager: Error updating anonymous user watched playlists:",t)}}async load(t,e){try{const n=mt.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(t){const e=mt.getState(),n=t instanceof Error?t:new Error("Unknown error loading manifest");e.stateMachine.send({type:"ERROR",error:n}),e.setError(n)}}destroy(){this.eventManager&&(this.eventManager=null)}}class Vt{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="sf-player",t.appendChild(this.playerElement),this.playerElement)}createControlsContainer(t){const e=document.createElement("div");return e.className="sf-controls-container",t.appendChild(e),e}createSaltfishLogo(t){var e;if(!1===(null==(e=mt.getState().config)?void 0:e.showLogo))return;const n=document.createElement("div");n.className="sf-player__logo",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=mt.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 Lt{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>5||i>5)&&(this.hasMoved=!0);const s=mt.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=pt.calculateDragPosition({x:r,y:a,position:o});this.updatePlayerPosition(l,o||"bottom-right"),t.preventDefault()},e=n=>{var i;if(this.isDragging){const t=mt.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=pt.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}),300))}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=mt.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=pt.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 Bt{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(mt.getState().isMinimized)}handleClick(){const t=mt.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 Ot{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=mt.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){this.playButton.style.display="playing"===t?"none":"flex"}destroy(){this.playButton.removeEventListener("click",this.handlePlayClick.bind(this)),this.playButton.remove()}}class Ut{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(mt.getState().isMinimized)}handleClick(t){t.stopPropagation();const e=mt.getState();e.manifest&&$t.getInstance().eventManager.trigger("playlistDismissed",{timestamp:Date.now(),playlist:{id:e.manifest.id,title:e.manifest.name}}),$t.getInstance().destroy()}updateVisibility(t){this.button.style.display=t?"flex":"none"}destroy(){this.button.removeEventListener("click",this.handleClick.bind(this)),this.button.remove()}}class Ft{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 Vt,this.dragManager=new Lt}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 Bt(this.playerElement),this.exitButton=new Ut(this.playerElement),t.create(this.playerElement);const s=this.playerView.createControlsContainer(this.playerElement);this.playPauseButton=new Ot(s,t),this.playerView.createSaltfishLogo(this.playerElement),this.setupVideoContainerClickHandler(),e.create(),n.create(this.playerElement),i.initialize(this.playerElement,t);const r=mt.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=mt.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=mt.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,pt.shouldForceReposition(s,i,this.dragManager.isCurrentlyDragging())&&(n=G))}const r=pt.applyConstraints({x:n,y:i,position:s||"bottom-right",viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,playerWidth:ut(e.isMinimized).width}),a=pt.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(it):this.playerElement.classList.remove(it)}}handleMinimizeClick(){if(!this.playerElement)return;const t=mt.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}}class Rt{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{mt.getState().setError(t)}catch(t){console.error("Failed to update store with error:",t)}}static triggerErrorEvent(t,e,n){var i,s;try{const r=mt.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(t){console.error("Failed to trigger error event:",t)}}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){return!!(t.message.includes("fetch")||t.message.includes("network")||t.message.includes("timeout"))||[/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(t){return this.handle(t,e,n),null}}}e(Rt,"DEFAULT_OPTIONS",{severity:"error",shouldLog:!0,shouldThrow:!1,shouldUpdateStore:!1,shouldTriggerEvent:!1,shouldDestroy:!1});const Nt=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;if(this.currentStepId,"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(Nt,"STEP_TIMEOUT_MS",6e4);let Yt=Nt;class Ht{async validatePlaylistStart(t){const{playlistId:e,options:n,eventManager:i}=t;try{const t=mt.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 Rt.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 Rt.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 Rt.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(t){const n=t instanceof Error?t.message:"Unknown validation error";return Rt.handlePlaylistError(`Playlist validation failed: ${n}`,{component:"PlaylistValidator",method:"validatePlaylistStart",playlistId:e,additionalData:{error:t}}),{isValid:!1,error:n}}}async validateAutoStartConditions(t,e,n){var i,s;const r=mt.getState();if(!r.user)return Rt.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=mt.getState().userData)?void 0:i.watchedPlaylists)||{};return(null==(s=e.triggers)?void 0:s.once)&&a[t]?(st(`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=mt.getState();if(!s.user)return Rt.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=mt.getState().userData)?void 0:i.watchedPlaylists)||{},a=r[t];return!a||"completed"!==a.status&&"dismissed"!==a.status?a&&"in_progress"===a.status&&!(null==e?void 0:e.startNodeId)&&a.currentStepId?{isValid:!0,updatedOptions:{...e,startNodeId:a.currentStepId}}:{isValid:!0}:(st(`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`})}async validateDeviceCompatibility(t,e){try{const n=t.deviceType||"both",{isDeviceCompatible:i}=await Promise.resolve().then((()=>yt));return i(n)?{isValid:!0}:(Rt.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 Rt.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),mt.getState(),e()};t.on("userDataLoaded",s)}))}}const Xt=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=mt.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 Ct,this.shadowDOMManager=new n,this.videoManager=new Mt,this.eventManager=new zt,this.analyticsManager=new It(this.eventManager),this.sessionRecordingManager=new Pt,this.playlistManager=new Dt(this.eventManager),this.cursorManager=new Et,this.interactionManager=new xt,this.buttonManager=new Tt,this.transitionManager=new _t,this.triggerManager=new kt,this.stepTimeoutManager=new Yt((()=>this.destroy())),this.playerView=new Vt,this.dragManager=new Lt,this.transitionManager.setTriggerManager(this.triggerManager),this.uiManager=new Ft(this.shadowDOMManager),mt.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("https://player.saltfish.ai/validate-token",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:t.token})}),r=await s.json();if(!r.isValid)throw Rt.handleInitializationError(r.error||"Token validation failed",{component:"SaltfishPlayer",method:"initialize",additionalData:{token:(null==(e=t.token)?void 0:e.substring(0,10))+"..."}});const a=function(t){if(t)return"auto"===t?function(){try{const t=navigator.language||navigator.userLanguage;if(!t)return;return t.split("-")[0].toLowerCase()}catch(t){return}}():t.split("-")[0].toLowerCase()}(t.language),o={...t,language:a,showLogo:!1!==r.showLogo};this.lastConfig=o;const l=mt.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 Rt.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(t){throw Rt.handleInitializationError(t,{component:"SaltfishPlayer",method:"initialize"})}}identifyUser(t,e){this.lastUserIdentification={userId:t,userData:e},mt.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},mt.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=mt.getState();if(!(null==(n=i.config)?void 0:n.token))return void Rt.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)return await s.text(),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(e){Rt.handleNetworkError(e,{component:"SaltfishPlayer",method:"fetchUserData",userId:t})}}loadAnonymousUserData(t,e){try{if("undefined"==typeof window)return;const n=localStorage.getItem(Q);let i={userId:t,userData:e||{},watchedPlaylists:{},timestamp:Date.now()};if(n)try{const s=JSON.parse(n);i={userId:t,userData:{...s.userData,...e},watchedPlaylists:s.watchedPlaylists||{},timestamp:Date.now()}}catch(t){}localStorage.setItem(Q,JSON.stringify(i)),mt.getState().setUserData({watchedPlaylists:i.watchedPlaylists||{}}),this.eventManager.trigger("userDataLoaded",{timestamp:Date.now(),userId:t,userData:{watchedPlaylists:i.watchedPlaylists||{}}}),this.triggerManager.startMonitoring()}catch(e){Rt.handleNetworkError(e,{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(t){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 n=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 xt,this.buttonManager=new Tt,this.transitionManager=new _t,this.playerView=new Vt,this.dragManager=new Lt,this.uiManager=new Ft(this.shadowDOMManager),this.registerStateMachineActions()}catch(e){throw Rt.handleInitializationError(`Failed to reinitialize player: ${e instanceof Error?e.message:"Unknown error"}`,{component:"SaltfishPlayer",method:"startPlaylist",playlistId:t,additionalData:{reinitError:e}})}n&&(this.videoManager.reset(),this.cursorManager.reset(),this.interactionManager=new xt,this.buttonManager=new Tt,this.transitionManager=new _t,this.playerView=new Vt,this.dragManager=new Lt,this.uiManager=new Ft(this.shadowDOMManager),this.stepTimeoutManager=new Yt((()=>this.cleanupPlaylist())),this.transitionManager.setTriggerManager(this.triggerManager),this.registerStateMachineActions());const i=mt.getState();if(!i.config){if(!this.lastConfig)throw Rt.createError("Saltfish Player must be initialized at least once before starting a playlist",{component:"SaltfishPlayer",method:"startPlaylist",playlistId:t});throw Rt.createError("Saltfish Player must be initialized before starting a playlist",{component:"SaltfishPlayer",method:"startPlaylist",playlistId:t})}i.manifest&&("playing"===i.currentState||"paused"===i.currentState||"loading"===i.currentState||"waitingForInteraction"===i.currentState||"autoplayBlocked"===i.currentState||"minimized"===i.currentState)&&(this.cleanupCurrentPlaylist(),i.resetForNewPlaylist(),this.registerStateMachineActions()),"completed"===i.currentState&&this.registerStateMachineActions(),this.sessionManager.startNewRun();const s=new Ht,r=await s.validatePlaylistStart({playlistId:t,options:e,eventManager:this.eventManager});if(!r.isValid)return;e=r.updatedOptions||e;const a=r.manifestPath,o=e||{};o?(i.setPlaylistOptions(o),o.position||i.setPlaylistOptions({...o,position:"bottom-right"}),this.uiManager.updatePosition()):(i.setPlaylistOptions({position:"bottom-right",allowDrag:!0}),this.uiManager.updatePosition());const l=(null==e?void 0:e.persistence)??!0;if(l&&"undefined"!=typeof window){const e=localStorage.getItem("saltfish_progress");if(e)try{const n=JSON.parse(e);n[t]&&i.loadPlaylistProgress(t,n[t])}catch(e){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(a,{...o,persistence:l});const c=mt.getState();o.startNodeId&&c.manifest?c.manifest.steps.find((t=>t.id===o.startNodeId))?c.goToStep(o.startNodeId):console.warn(`[SaltfishPlayer] startNodeId '${o.startNodeId}' not found in manifest steps. Starting from default step.`):c.manifest,c.manifest&&(c.manifest.cursorColor&&this.cursorManager.setColor(c.manifest.cursorColor),this.eventManager.trigger("playlistStarted",{timestamp:Date.now(),playlist:{id:t,title:c.manifest.name}})),i.play(),st(`Playlist started: ${t}${c.manifest?` (${c.manifest.name})`:""}`)}catch(e){Rt.handlePlaylistError(e,{component:"SaltfishPlayer",method:"startPlaylist",playlistId:t,errorType:"playlist_load_failed"})}}registerStateMachineActions(){const t=mt.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=mt.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(t){}},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=mt.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=mt.getState().config)?void 0:e.language;return n&&t.translations&&t.translations[n]?t.translations[n].videoUrl:t.compressedVideoUrl||t.videoUrl}setupUpdaters(){this.uiUpdaterUnsubscribe&&this.uiUpdaterUnsubscribe(),this.eventUpdaterUnsubscribe&&this.eventUpdaterUnsubscribe();const t=this.uiManager.getPlayerElement();t&&(this.uiUpdaterUnsubscribe=function(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 mt.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){n&&(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}}))}(t,this.cursorManager)),this.eventUpdaterUnsubscribe=function(t){let e=null,n=null,i=null;const s=mt.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}(this.eventManager);const e=mt.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=mt.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(t){Rt.handleCleanupError(t,{component:"SaltfishPlayer",method:"destroy"});try{this.isInitialized=!1,mt.getState().reset()}catch(e){Rt.handleCleanupError(e,{component:"SaltfishPlayer",method:"destroy",additionalData:{originalError:t}})}}else console.warn("Saltfish playlist Player is not initialized")}handleCompletedState(){null!==t.destroyTimeoutId&&(t.destroyTimeoutId,window.clearTimeout(t.destroyTimeoutId),t.destroyTimeoutId=null);const e=mt.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=mt.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){Rt.handleCleanupError(t,{component:"SaltfishPlayer",method:"cleanupCurrentPlaylist"})}}cleanupPlaylist(){var t;if(this.isInitialized)try{const e=mt.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(t){Rt.handleCleanupError(t,{component:"SaltfishPlayer",method:"cleanupPlaylist"})}else console.warn("Saltfish playlist Player is not initialized")}updateControlsVisibility(t){this.uiManager.updateControlsVisibility(t)}};e(Xt,"instance",null),e(Xt,"prevState",{currentState:null,currentStepId:null,isMinimized:!1}),e(Xt,"destroyTimeoutId",null);let $t=Xt;const Wt=Object.freeze(Object.defineProperty({__proto__:null,SaltfishPlayer:$t},Symbol.toStringTag,{value:"Module"})),jt={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"},qt={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 Zt(t,e=!1){const n=e?jt:qt;return{...n,...t,steps:t.steps||n.steps}}const Jt=function(){const t=$t.getInstance();let e=!1,n=!1,i=null;const s=[],r={init:r=>{if(n)return st("Saltfish already initialized"),Promise.resolve();if(e&&i)return i;const a={sessionRecording:!1,enableAnalytics:!0,..."string"==typeof r?{token:r}:r};return st(`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 t=s.shift();if(t)try{await t()}catch(t){at("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(t){n(t)}})),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()})):rt("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):rt("Cannot destroy - Saltfish not initialized")},getSessionId:()=>t.getSessionId(),getRunId:()=>t.getRunId()};return r.__dev__={setMockManifest:t=>{"undefined"!=typeof window&&(window.demoManifest=t)},createMockManifest:Zt,defaultMockManifest:qt,getDeviceInfo:()=>ft.getDeviceInfo()},r}();return"undefined"!=typeof window&&(window.saltfish=Jt),Jt}));
|
|
7
|
+
!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(){return this.shadowRoot?this.shadowRoot.getElementById("sf-player-root"):null}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={};var s=Symbol.for("immer-nothing"),r=Symbol.for("immer-draftable"),a=Symbol.for("immer-state");function o(t,...e){throw new Error(`[Immer] minified error nr: ${t}. Full error at: https://bit.ly/3cXEKWf`)}var l=Object.getPrototypeOf;function c(t){return!!t&&!!t[a]}function d(t){var e;return!!t&&(u(t)||Array.isArray(t)||!!t[r]||!!(null==(e=t.constructor)?void 0:e[r])||y(t)||v(t))}var h=Object.prototype.constructor.toString();function u(t){if(!t||"object"!=typeof t)return!1;const e=l(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)===h}function p(t,e){0===g(t)?Reflect.ownKeys(t).forEach((n=>{e(n,t[n],t)})):t.forEach(((n,i)=>e(i,n,t)))}function g(t){const e=t[a];return e?e.type_:Array.isArray(t)?1:y(t)?2:v(t)?3:0}function m(t,e){return 2===g(t)?t.has(e):Object.prototype.hasOwnProperty.call(t,e)}function f(t,e,n){const i=g(t);2===i?t.set(e,n):3===i?t.add(n):t[e]=n}function y(t){return t instanceof Map}function v(t){return t instanceof Set}function b(t){return t.copy_||t.base_}function w(t,e){if(y(t))return new Map(t);if(v(t))return new Set(t);if(Array.isArray(t))return Array.prototype.slice.call(t);const n=u(t);if(!0===e||"class_only"===e&&!n){const e=Object.getOwnPropertyDescriptors(t);delete e[a];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(l(t),e)}{const e=l(t);if(null!==e&&n)return{...t};const i=Object.create(e);return Object.assign(i,t)}}function S(t,e=!1){return E(t)||c(t)||!d(t)||(g(t)>1&&(t.set=t.add=t.clear=t.delete=M),Object.freeze(t),e&&Object.entries(t).forEach((([t,e])=>S(e,!0)))),t}function M(){o(2)}function E(t){return Object.isFrozen(t)}var I,x={};function P(t){const e=x[t];return e||o(0),e}function C(){return I}function T(t,e){e&&(P("Patches"),t.patches_=[],t.inversePatches_=[],t.patchListener_=e)}function _(t){k(t),t.drafts_.forEach(A),t.drafts_=null}function k(t){t===I&&(I=t.parent_)}function z(t){return I={drafts_:[],parent_:I,immer_:t,canAutoFreeze_:!0,unfinalizedDrafts_:0}}function A(t){const e=t[a];0===e.type_||1===e.type_?e.revoke_():e.revoked_=!0}function D(t,e){e.unfinalizedDrafts_=e.drafts_.length;const n=e.drafts_[0];return void 0!==t&&t!==n?(n[a].modified_&&(_(e),o(4)),d(t)&&(t=V(e,t),e.parent_||B(e,t)),e.patches_&&P("Patches").generateReplacementPatches_(n[a].base_,t,e.patches_,e.inversePatches_)):t=V(e,n,[]),_(e),e.patches_&&e.patchListener_(e.patches_,e.inversePatches_),t!==s?t:void 0}function V(t,e,n){if(E(e))return e;const i=e[a];if(!i)return p(e,((s,r)=>L(t,i,e,s,r,n))),e;if(i.scope_!==t)return e;if(!i.modified_)return B(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),p(s,((s,a)=>L(t,i,e,s,a,n,r))),B(t,e,!1),n&&t.patches_&&P("Patches").generatePatches_(i,n,t.patches_,t.inversePatches_)}return i.copy_}function L(t,e,n,i,s,r,a){if(c(s)){const a=V(t,s,r&&e&&3!==e.type_&&!m(e.assigned_,i)?r.concat(i):void 0);if(f(n,i,a),!c(a))return;t.canAutoFreeze_=!1}else a&&n.add(s);if(d(s)&&!E(s)){if(!t.immer_.autoFreeze_&&t.unfinalizedDrafts_<1)return;V(t,s),e&&e.scope_.parent_||"symbol"==typeof i||!Object.prototype.propertyIsEnumerable.call(n,i)||B(t,s)}}function B(t,e,n=!1){!t.parent_&&t.immer_.autoFreeze_&&t.canAutoFreeze_&&S(e,n)}var O={get(t,e){if(e===a)return t;const n=b(t);if(!m(n,e))return function(t,e,n){var i;const s=R(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_||!d(i)?i:i===F(t.base_,e)?(Y(t),t.copy_[e]=H(i,t)):i},has:(t,e)=>e in b(t),ownKeys:t=>Reflect.ownKeys(b(t)),set(t,e,n){const i=R(b(t),e);if(null==i?void 0:i.set)return i.set.call(t.draft_,n),!0;if(!t.modified_){const i=F(b(t),e),o=null==i?void 0:i[a];if(o&&o.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||m(t.base_,e)))return!0;Y(t),N(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!==F(t.base_,e)||e in t.base_?(t.assigned_[e]=!1,Y(t),N(t)):delete t.assigned_[e],t.copy_&&delete t.copy_[e],!0),getOwnPropertyDescriptor(t,e){const n=b(t),i=Reflect.getOwnPropertyDescriptor(n,e);return i?{writable:!0,configurable:1!==t.type_||"length"!==e,enumerable:i.enumerable,value:n[e]}:i},defineProperty(){o(11)},getPrototypeOf:t=>l(t.base_),setPrototypeOf(){o(12)}},U={};function F(t,e){const n=t[a];return(n?b(n):t)[e]}function R(t,e){if(!(e in t))return;let n=l(t);for(;n;){const t=Object.getOwnPropertyDescriptor(n,e);if(t)return t;n=l(n)}}function N(t){t.modified_||(t.modified_=!0,t.parent_&&N(t.parent_))}function Y(t){t.copy_||(t.copy_=w(t.base_,t.scope_.immer_.useStrictShallowCopy_))}function H(t,e){const n=y(t)?P("MapSet").proxyMap_(t,e):v(t)?P("MapSet").proxySet_(t,e):function(t,e){const n=Array.isArray(t),i={type_:n?1:0,scope_:e?e.scope_:C(),modified_:!1,finalized_:!1,assigned_:{},parent_:e,base_:t,draft_:null,copy_:null,revoke_:null,isManual_:!1};let s=i,r=O;n&&(s=[i],r=U);const{revoke:a,proxy:o}=Proxy.revocable(s,r);return i.draft_=o,i.revoke_=a,o}(t,e);return(e?e.scope_:C()).drafts_.push(n),n}function X(t){if(!d(t)||E(t))return t;const e=t[a];let n;if(e){if(!e.modified_)return e.base_;e.finalized_=!0,n=w(t,e.scope_.immer_.useStrictShallowCopy_)}else n=w(t,!0);return p(n,((t,e)=>{f(n,t,X(e))})),e&&(e.finalized_=!1),n}p(O,((t,e)=>{U[t]=function(){return arguments[0]=arguments[0][0],e.apply(this,arguments)}})),U.deleteProperty=function(t,e){return U.set.call(this,t,e,void 0)},U.set=function(t,e,n){return O.set.call(this,t[0],e,n,t[0])};var $=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&&o(6),void 0!==n&&"function"!=typeof n&&o(7),d(t)){const s=z(this),r=H(t,void 0);let a=!0;try{i=e(r),a=!1}finally{a?_(s):k(s)}return T(s,n),D(i,s)}if(!t||"object"!=typeof t){if(i=e(t),void 0===i&&(i=t),i===s&&(i=void 0),this.autoFreeze_&&S(i,!0),n){const e=[],s=[];P("Patches").generateReplacementPatches_(t,i,e,s),n(e,s)}return i}o(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){d(t)||o(8),c(t)&&(t=function(t){return c(t)||o(10),X(t)}(t));const e=z(this),n=H(t,void 0);return n[a].isManual_=!0,k(e),n}finishDraft(t,e){const n=t&&t[a];n&&n.isManual_||o(9);const{scope_:i}=n;return T(i,e),D(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=P("Patches").applyPatches_;return c(t)?i(t,e):this.produce(t,(t=>i(t,e)))}},W=$.produce;$.produceWithPatches.bind($),$.setAutoFreeze.bind($),$.setUseStrictShallowCopy.bind($),$.applyPatches.bind($),$.createDraft.bind($),$.finishDraft.bind($);const j="bottom",q="right",Z="center",J="saltfish_progress",K="saltfish_session",Q="saltfish_anonymous_user_data",G=20,tt="-50%",et="-50%",nt="-100%",it="sf-player--minimized";function st(t,e){void 0!==e?console.info(t,e):console.info(t)}function rt(t,e){console.warn(t)}function at(t,e){void 0!==e?console.error(t,e):console.error(t)}class ot{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];return e?(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,this.currentState=e.target,this.runEntryActions(this.currentState),this.currentState,this.currentState):(t.type,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 lt={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"]}}},ct=20,dt=()=>{const t=document.getElementById("saltfish-container");return t&&t.shadowRoot?t:document.documentElement},ht=()=>{if("undefined"!=typeof window){const t=dt(),e=getComputedStyle(t).getPropertyValue("--sf-player-width");return parseInt(e,10)||200}return 200},ut=t=>{const e=t?(()=>{if("undefined"!=typeof window){const t=dt(),e=getComputedStyle(t);return parseInt(e.getPropertyValue("--sf-player-min-width"),10)||80}return 80})():ht();return{width:e,minX:20,maxX:window.innerWidth-e-ct}};class pt{static calculatePosition(t){const{position:e,viewportWidth:n=window.innerWidth,viewportHeight:i=window.innerHeight,playerWidth:s=ht()}=t;let r=G,a=G,o="0",l="0";return e.includes(j)&&(a=i-G,l=nt),e.includes("left")?r=G:e.includes(q)?r=n-s-ct:e.includes(Z)&&(r=n/2,a=i/2,o=tt,l=et),{...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(j)&&!i.includes(Z)&&(l=r-G),i.includes(q)&&!i.includes(Z)&&(o=Math.max(G,Math.min(o,s-a-ct))),o=Math.max(G,Math.min(o,s-a-ct)),l=Math.max(G,Math.min(l,r-G)),{x:o,y:l}}static calculateDragPosition(t){const{x:e,y:n,position:i,viewportWidth:s=window.innerWidth,viewportHeight:r=window.innerHeight,playerWidth:a=ht()}=t;let o=e,l=n;(null==i?void 0:i.includes(q))&&!i.includes(Z)&&(o=Math.min(o,s-a-ct));const c=s-a-ct;return o=Math.max(20,Math.min(o,c)),l=Math.max(G,Math.min(l,r-G)),{x:o,y:l}}static getTransforms(t){let e="0",n="0";return t.includes(Z)?(e=tt,n=et):t.includes(j)&&(n=nt),{transformX:e,transformY:n}}static shouldForceReposition(t,e,n){return"bottom-left"===t&&!n&&(e===window.innerHeight-G||Math.abs(e-(window.innerHeight-G))<5)}static getPlayerDimensions(){const t=ht();return{width:t,minX:G,maxX:window.innerWidth-t-ct}}}const gt=(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})((t=>(e,n,i)=>(i.setState=(t,n,...i)=>{const s="function"==typeof t?W(t):t;return e(s,n,...i)},t(i.setState,n,i)))(((t,e)=>{const n=new ot(lt,{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=pt.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=pt.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)??1)&&"undefined"!=typeof window&&localStorage.setItem(J,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(J,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 ot(lt,{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(J,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 ot(lt,{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}))}}}))),mt={getState:()=>gt.getState(),setState:gt.setState,subscribe:gt.subscribe,destroy:gt.destroy};class ft{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(t){console.warn("DeviceDetector: Error in device change handler:",t)}};return window.addEventListener("orientationchange",e),window.addEventListener("resize",e),()=>{window.removeEventListener("orientationchange",e),window.removeEventListener("resize",e)}}}e(ft,"cachedDeviceInfo",null);const yt=Object.freeze(Object.defineProperty({__proto__:null,DeviceDetector:ft,isDeviceCompatible:t=>{if(!t||"both"===t)return!0;const e=ft.getDeviceInfo();return"mobile"===t?e.isMobile||e.isTablet:"desktop"===t&&e.isDesktop}},Symbol.toStringTag,{value:"Module"}));class vt{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 bt{constructor(t){e(this,"deviceInfo"),this.deviceInfo=t}updateDeviceInfo(t){this.deviceInfo=t}}class wt extends bt{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(t){console.warn(`MobilePlaybackHandler: Failed to set attribute ${e}:`,t)}})),Object.entries(e.styles).forEach((([e,n])=>{try{t.style[e]=n}catch(t){console.warn(`MobilePlaybackHandler: Failed to set style ${e}:`,t)}}))}configureControlElement(t){const e=this.getControlsConfig();t.style.minWidth=e.buttonMinSize.width,t.style.minHeight=e.buttonMinSize.height}async handlePlayAttempt(t,e){const n=mt.getState().isMuted;t.muted=n,t.loop=!1;try{return await t.play(),!0}catch(e){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(t){console.error("MobilePlaybackHandler: All autoplay attempts failed")}}destroy(){}getProgressUpdateFrequency(t){return t?500:16}}class St extends bt{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=mt.getState().isMuted;t.muted=n,t.loop=!1;try{return await t.play(),!0}catch(e){return t.muted,await this.handleAutoplayFallback(t),!1}}async handleAutoplayFallback(t){t.muted=!0,t.loop=!0;try{await t.play()}catch(t){throw console.error("DesktopPlaybackHandler: All autoplay attempts failed"),new Error("Desktop autoplay completely blocked")}}getProgressUpdateFrequency(t){return 16}destroy(){}}class Mt{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=>{const e=t.target,n=this.getActiveVideo();e===n&&"autoplayBlocked"!==mt.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")})),e(this,"handleAutoVideoEnded",(()=>{var t;const e=mt.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&&mt.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)??1)&&"undefined"!=typeof window&&localStorage.setItem(J,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=mt.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 mt.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)??1)&&"undefined"!=typeof window&&localStorage.setItem(J,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=ft.getDeviceInfo();this.deviceHandler=function(t){return t.isMobile?new wt(t):new St(t)}(t),this.transcriptManager=new vt,this.deviceChangeCleanup=ft.onDeviceChange((t=>{this.deviceHandler.updateDeviceInfo(t),this.handleDeviceChange(t)}))}getDeviceInfo(){return ft.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),mt.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=mt.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=mt.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=mt.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}if(i&&this.currentVideoUrl&&n.currentTime>0&&this.playbackPositions.set(this.currentVideoUrl,n.currentTime),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(t){throw console.error("VideoManager: Failed to load video:",t),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=mt.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=mt.getState();if(((null==(t=n.playlistOptions)?void 0:t.persistence)??1)&&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"),mt.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),mt.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 Et{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){return document.querySelector(t)||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 t of s){const n=t.getBoundingClientRect();if(!(e.top>=n.top&&e.bottom<=n.bottom&&e.left>=n.left&&e.right<=n.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"===gt.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((()=>{this.targetMutationObserver?this.findElement(t.targetSelector)&&(clearInterval(e),this.targetMutationObserver.disconnect(),this.targetMutationObserver=null,this.animate(t)):clearInterval(e)}),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((()=>{this.targetMutationObserver?this.findElement(t)&&(clearInterval(i),this.targetMutationObserver.disconnect(),this.targetMutationObserver=null,this.moveToElement(t,e,n)):clearInterval(i)}),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 It{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=mt.subscribe(((t,e)=>{t.isMinimized!==(null==e?void 0:e.isMinimized)&&this.updateButtonPositions()}))}createButtons(t){this.container&&(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)})),mt.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(){this.buttonContainer&&0!==this.buttons.length&&(mt.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(e){console.error(`InteractionManager: Error setting up DOM interaction for selector "${t.selector}":`,e)}}))}clearDOMInteractions(){this.domEventListeners.forEach((({element:t,listener:e,type:n})=>{try{t.removeEventListener(n,e)}catch(t){console.error("InteractionManager: Error removing event listener:",t)}})),this.domEventListeners.clear()}async handleButtonClick(t,e){e.id,t.preventDefault(),t.stopPropagation();const n=mt.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((()=>Wt)),i=t.getInstance();i&&i.destroy();break;case"dom":e.action.target;const s=document.querySelector(e.action.target);s?s.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(t){console.error(`InteractionManager: Error calling function "${e.action.target}":`,t)}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(mt.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((()=>Wt)),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 xt{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 mt.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 $t.getInstance().getRunId()}catch(t){return null}}}class Pt{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(t){e(t)}}))}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 Ct{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(K);if(t){const e=JSON.parse(t);if(Date.now()-e.lastActivity<18e5)return e.sessionId,this.updateSessionActivity(e.sessionId),e.sessionId}}catch(t){}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(K,JSON.stringify(e))}catch(t){}}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(K),this.sessionId),this.sessionId=this.generateUniqueId(),this.updateSessionActivity(this.sessionId),this.currentRunId=null,this.sessionId}destroy(){this.updateSessionActivity(this.sessionId),this.endCurrentRun()}}class Tt{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=mt.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=mt.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=mt.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 _t{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=mt.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=mt.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 kt{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=mt.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){return!t||!(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 zt{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(e){console.error(`Error in ${t} event handler:`,e)}})))}removeAllListeners(){this.listeners.clear()}getListenerCount(t){const e=this.listeners.get(t);return e?e.size:0}}class At{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(t){const e=t instanceof Error?t.message:"Unknown error";throw at("[PlaylistLoader] Failed to load manifest:",t),new Error(`Unable to load playlist manifest: ${e}`)}}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 at("[PlaylistLoader] Fetch/parse failed:",n),at("[PlaylistLoader] Manifest path:",t),at("[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 e of t.steps){if(!e.id)throw new Error("Each step must have an id");if(!e.videoUrl)throw new Error(`Step '${e.id}' must have a videoUrl`);if(!e.transitions||!Array.isArray(e.transitions))throw new Error(`Step '${e.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;e.completedWaitingForInteraction?a=t.startStep:t.steps.find((t=>t.id===i))&&(a=i)}return a}}class Dt{constructor(t){e(this,"eventManager",null),e(this,"isUpdatingWatchedPlaylists",!1),e(this,"playlistLoader"),this.playlistLoader=new At,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 mt.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 c=this.getStore();if(!c)return;const d=c.userData||{},h=d.watchedPlaylists||{},u={status:e,currentStepId:n||c.currentStepId||null,lastProgressAt:Date.now()},p={...h,[t]:u};if(c.setUserData({...d,watchedPlaylists:p}),!(null==(i=null==c?void 0:c.config)?void 0:i.token)||!(null==(s=null==c?void 0:c.user)?void 0:s.id)||(null==(r=null==c?void 0:c.user)?void 0:r.__isAnonymous))return null==(a=null==c?void 0:c.config)||a.token,null==(o=null==c?void 0:c.user)||o.id,null==(l=null==c?void 0:c.user)||l.__isAnonymous,void this.updateAnonymousUserWatchedPlaylists(t,e,n||c.currentStepId||null);const g=`https://player.saltfish.ai/clients/${c.config.token}/users/${c.user.id}/playlists/${t}`;try{const t=await fetch(g,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({status:e,currentStepId:n||c.currentStepId||null})});if(!t.ok)throw new Error(`Failed to update watched playlist status: ${t.statusText} (${t.status})`)}catch(e){console.error(`PlaylistManager: Error updating watched playlist status for ${t}:`,e)}}finally{this.isUpdatingWatchedPlaylists=!1}}}updateAnonymousUserWatchedPlaylists(t,e,n){if("undefined"!=typeof window)try{const i=localStorage.getItem(Q);let s={userId:"anonymous",userData:{},watchedPlaylists:{},timestamp:Date.now()};if(i)try{s=JSON.parse(i)}catch(t){}s.watchedPlaylists||(s.watchedPlaylists={}),s.watchedPlaylists[t]={status:e,currentStepId:n||null,lastProgressAt:Date.now()},s.timestamp=Date.now(),localStorage.setItem(Q,JSON.stringify(s))}catch(t){console.error("PlaylistManager: Error updating anonymous user watched playlists:",t)}}async load(t,e){try{const n=mt.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(t){const e=mt.getState(),n=t instanceof Error?t:new Error("Unknown error loading manifest");e.stateMachine.send({type:"ERROR",error:n}),e.setError(n)}}destroy(){this.eventManager&&(this.eventManager=null)}}class Vt{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="sf-player",t.appendChild(this.playerElement),this.playerElement)}createControlsContainer(t){const e=document.createElement("div");return e.className="sf-controls-container",t.appendChild(e),e}createSaltfishLogo(t){var e;if(!1===(null==(e=mt.getState().config)?void 0:e.showLogo))return;const n=document.createElement("div");n.className="sf-player__logo",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=mt.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 Lt{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>5||i>5)&&(this.hasMoved=!0);const s=mt.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=pt.calculateDragPosition({x:r,y:a,position:o});this.updatePlayerPosition(l,o||"bottom-right"),t.preventDefault()},e=n=>{var i;if(this.isDragging){const t=mt.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=pt.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}),300))}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=mt.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=pt.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 Bt{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(mt.getState().isMinimized)}handleClick(){const t=mt.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 Ot{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=mt.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){this.playButton.style.display="playing"===t?"none":"flex"}destroy(){this.playButton.removeEventListener("click",this.handlePlayClick.bind(this)),this.playButton.remove()}}class Ut{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(mt.getState().isMinimized)}handleClick(t){t.stopPropagation();const e=mt.getState();e.manifest&&$t.getInstance().eventManager.trigger("playlistDismissed",{timestamp:Date.now(),playlist:{id:e.manifest.id,title:e.manifest.name}}),$t.getInstance().destroy()}updateVisibility(t){this.button.style.display=t?"flex":"none"}destroy(){this.button.removeEventListener("click",this.handleClick.bind(this)),this.button.remove()}}class Ft{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 Vt,this.dragManager=new Lt}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 Bt(this.playerElement),this.exitButton=new Ut(this.playerElement),t.create(this.playerElement);const s=this.playerView.createControlsContainer(this.playerElement);this.playPauseButton=new Ot(s,t),this.playerView.createSaltfishLogo(this.playerElement),this.setupVideoContainerClickHandler(),e.create(),n.create(this.playerElement),i.initialize(this.playerElement,t);const r=mt.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=mt.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=mt.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,pt.shouldForceReposition(s,i,this.dragManager.isCurrentlyDragging())&&(n=G))}const r=pt.applyConstraints({x:n,y:i,position:s||"bottom-right",viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,playerWidth:ut(e.isMinimized).width}),a=pt.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(it):this.playerElement.classList.remove(it)}}handleMinimizeClick(){if(!this.playerElement)return;const t=mt.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}}class Rt{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{mt.getState().setError(t)}catch(t){console.error("Failed to update store with error:",t)}}static triggerErrorEvent(t,e,n){var i,s;try{const r=mt.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(t){console.error("Failed to trigger error event:",t)}}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){return!!(t.message.includes("fetch")||t.message.includes("network")||t.message.includes("timeout"))||[/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(t){return this.handle(t,e,n),null}}}e(Rt,"DEFAULT_OPTIONS",{severity:"error",shouldLog:!0,shouldThrow:!1,shouldUpdateStore:!1,shouldTriggerEvent:!1,shouldDestroy:!1});const Nt=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;if(this.currentStepId,"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(Nt,"STEP_TIMEOUT_MS",6e4);let Yt=Nt;class Ht{async validatePlaylistStart(t){const{playlistId:e,options:n,eventManager:i}=t;try{const t=mt.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 Rt.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 Rt.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 Rt.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(t){const n=t instanceof Error?t.message:"Unknown validation error";return Rt.handlePlaylistError(`Playlist validation failed: ${n}`,{component:"PlaylistValidator",method:"validatePlaylistStart",playlistId:e,additionalData:{error:t}}),{isValid:!1,error:n}}}async validateAutoStartConditions(t,e,n){var i,s;const r=mt.getState();if(!r.user)return Rt.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=mt.getState().userData)?void 0:i.watchedPlaylists)||{};return(null==(s=e.triggers)?void 0:s.once)&&a[t]?(st(`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=mt.getState();if(!s.user)return Rt.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=mt.getState().userData)?void 0:i.watchedPlaylists)||{},a=r[t];return!a||"completed"!==a.status&&"dismissed"!==a.status?a&&"in_progress"===a.status&&!(null==e?void 0:e.startNodeId)&&a.currentStepId?{isValid:!0,updatedOptions:{...e,startNodeId:a.currentStepId}}:{isValid:!0}:(st(`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`})}async validateDeviceCompatibility(t,e){try{const n=t.deviceType||"both",{isDeviceCompatible:i}=await Promise.resolve().then((()=>yt));return i(n)?{isValid:!0}:(Rt.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 Rt.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),mt.getState(),e()};t.on("userDataLoaded",s)}))}}const Xt=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=mt.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 Ct,this.shadowDOMManager=new n,this.videoManager=new Mt,this.eventManager=new zt,this.analyticsManager=new xt(this.eventManager),this.sessionRecordingManager=new Pt,this.playlistManager=new Dt(this.eventManager),this.cursorManager=new Et,this.interactionManager=new It,this.buttonManager=new Tt,this.transitionManager=new _t,this.triggerManager=new kt,this.stepTimeoutManager=new Yt((()=>this.destroy())),this.playerView=new Vt,this.dragManager=new Lt,this.transitionManager.setTriggerManager(this.triggerManager),this.uiManager=new Ft(this.shadowDOMManager),mt.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("https://player.saltfish.ai/validate-token",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:t.token})}),r=await s.json();if(!r.isValid)throw Rt.handleInitializationError(r.error||"Token validation failed",{component:"SaltfishPlayer",method:"initialize",additionalData:{token:(null==(e=t.token)?void 0:e.substring(0,10))+"..."}});const a=function(t){if(t)return"auto"===t?function(){try{const t=navigator.language||navigator.userLanguage;if(!t)return;return t.split("-")[0].toLowerCase()}catch(t){return}}():t.split("-")[0].toLowerCase()}(t.language),o={...t,language:a,showLogo:!1!==r.showLogo};this.lastConfig=o;const l=mt.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 Rt.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(t){throw Rt.handleInitializationError(t,{component:"SaltfishPlayer",method:"initialize"})}}identifyUser(t,e){this.lastUserIdentification={userId:t,userData:e},mt.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},mt.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=mt.getState();if(!(null==(n=i.config)?void 0:n.token))return void Rt.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)return await s.text(),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(e){Rt.handleNetworkError(e,{component:"SaltfishPlayer",method:"fetchUserData",userId:t})}}loadAnonymousUserData(t,e){try{if("undefined"==typeof window)return;const n=localStorage.getItem(Q);let i={userId:t,userData:e||{},watchedPlaylists:{},timestamp:Date.now()};if(n)try{const s=JSON.parse(n);i={userId:t,userData:{...s.userData,...e},watchedPlaylists:s.watchedPlaylists||{},timestamp:Date.now()}}catch(t){}localStorage.setItem(Q,JSON.stringify(i)),mt.getState().setUserData({watchedPlaylists:i.watchedPlaylists||{}}),this.eventManager.trigger("userDataLoaded",{timestamp:Date.now(),userId:t,userData:{watchedPlaylists:i.watchedPlaylists||{}}}),this.triggerManager.startMonitoring()}catch(e){Rt.handleNetworkError(e,{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(t){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 n=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 It,this.buttonManager=new Tt,this.transitionManager=new _t,this.playerView=new Vt,this.dragManager=new Lt,this.uiManager=new Ft(this.shadowDOMManager),this.registerStateMachineActions()}catch(e){throw Rt.handleInitializationError(`Failed to reinitialize player: ${e instanceof Error?e.message:"Unknown error"}`,{component:"SaltfishPlayer",method:"startPlaylist",playlistId:t,additionalData:{reinitError:e}})}n&&(this.videoManager.reset(),this.cursorManager.reset(),this.interactionManager=new It,this.buttonManager=new Tt,this.transitionManager=new _t,this.playerView=new Vt,this.dragManager=new Lt,this.uiManager=new Ft(this.shadowDOMManager),this.stepTimeoutManager=new Yt((()=>this.cleanupPlaylist())),this.transitionManager.setTriggerManager(this.triggerManager),this.registerStateMachineActions());const i=mt.getState();if(!i.config){if(!this.lastConfig)throw Rt.createError("Saltfish Player must be initialized at least once before starting a playlist",{component:"SaltfishPlayer",method:"startPlaylist",playlistId:t});throw Rt.createError("Saltfish Player must be initialized before starting a playlist",{component:"SaltfishPlayer",method:"startPlaylist",playlistId:t})}i.manifest&&("playing"===i.currentState||"paused"===i.currentState||"loading"===i.currentState||"waitingForInteraction"===i.currentState||"autoplayBlocked"===i.currentState||"minimized"===i.currentState)&&(this.cleanupCurrentPlaylist(),i.resetForNewPlaylist(),this.registerStateMachineActions()),"completed"===i.currentState&&this.registerStateMachineActions(),this.sessionManager.startNewRun();const s=new Ht,r=await s.validatePlaylistStart({playlistId:t,options:e,eventManager:this.eventManager});if(!r.isValid)return;e=r.updatedOptions||e;const a=r.manifestPath,o=e||{};o?(i.setPlaylistOptions(o),o.position||i.setPlaylistOptions({...o,position:"bottom-right"}),this.uiManager.updatePosition()):(i.setPlaylistOptions({position:"bottom-right",allowDrag:!0}),this.uiManager.updatePosition());const l=(null==e?void 0:e.persistence)??!0;if(l&&"undefined"!=typeof window){const e=localStorage.getItem("saltfish_progress");if(e)try{const n=JSON.parse(e);n[t]&&i.loadPlaylistProgress(t,n[t])}catch(e){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(a,{...o,persistence:l});const c=mt.getState();o.startNodeId&&c.manifest?c.manifest.steps.find((t=>t.id===o.startNodeId))?c.goToStep(o.startNodeId):console.warn(`[SaltfishPlayer] startNodeId '${o.startNodeId}' not found in manifest steps. Starting from default step.`):c.manifest,c.manifest&&(c.manifest.cursorColor&&this.cursorManager.setColor(c.manifest.cursorColor),this.eventManager.trigger("playlistStarted",{timestamp:Date.now(),playlist:{id:t,title:c.manifest.name}})),i.play(),st(`Playlist started: ${t}${c.manifest?` (${c.manifest.name})`:""}`)}catch(e){Rt.handlePlaylistError(e,{component:"SaltfishPlayer",method:"startPlaylist",playlistId:t,errorType:"playlist_load_failed"})}}registerStateMachineActions(){const t=mt.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=mt.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(t){}},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=mt.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=mt.getState().config)?void 0:e.language;return n&&t.translations&&t.translations[n]?t.translations[n].videoUrl:t.compressedVideoUrl||t.videoUrl}setupUpdaters(){this.uiUpdaterUnsubscribe&&this.uiUpdaterUnsubscribe(),this.eventUpdaterUnsubscribe&&this.eventUpdaterUnsubscribe();const t=this.uiManager.getPlayerElement();t&&(this.uiUpdaterUnsubscribe=function(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 mt.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){n&&(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}}))}(t,this.cursorManager)),this.eventUpdaterUnsubscribe=function(t){let e=null,n=null,i=null;const s=mt.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}(this.eventManager);const e=mt.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=mt.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(t){Rt.handleCleanupError(t,{component:"SaltfishPlayer",method:"destroy"});try{this.isInitialized=!1,mt.getState().reset()}catch(e){Rt.handleCleanupError(e,{component:"SaltfishPlayer",method:"destroy",additionalData:{originalError:t}})}}else console.warn("Saltfish playlist Player is not initialized")}handleCompletedState(){null!==t.destroyTimeoutId&&(t.destroyTimeoutId,window.clearTimeout(t.destroyTimeoutId),t.destroyTimeoutId=null);const e=mt.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=mt.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){Rt.handleCleanupError(t,{component:"SaltfishPlayer",method:"cleanupCurrentPlaylist"})}}cleanupPlaylist(){var t;if(this.isInitialized)try{const e=mt.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(t){Rt.handleCleanupError(t,{component:"SaltfishPlayer",method:"cleanupPlaylist"})}else console.warn("Saltfish playlist Player is not initialized")}updateControlsVisibility(t){this.uiManager.updateControlsVisibility(t)}};e(Xt,"instance",null),e(Xt,"prevState",{currentState:null,currentStepId:null,isMinimized:!1}),e(Xt,"destroyTimeoutId",null);let $t=Xt;const Wt=Object.freeze(Object.defineProperty({__proto__:null,SaltfishPlayer:$t},Symbol.toStringTag,{value:"Module"})),jt={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"},qt={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 Zt(t,e=!1){const n=e?jt:qt;return{...n,...t,steps:t.steps||n.steps}}const Jt=function(){const t=$t.getInstance();let e=!1,n=!1,i=null;const s=[],r={init:r=>{if(n)return st("Saltfish already initialized"),Promise.resolve();if(e&&i)return i;const a={sessionRecording:!1,enableAnalytics:!0,..."string"==typeof r?{token:r}:r};return st(`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 t=s.shift();if(t)try{await t()}catch(t){at("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(t){n(t)}})),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()})):rt("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):rt("Cannot destroy - Saltfish not initialized")},getSessionId:()=>t.getSessionId(),getRunId:()=>t.getRunId()};return r.__dev__={setMockManifest:t=>{"undefined"!=typeof window&&(window.demoManifest=t)},createMockManifest:Zt,defaultMockManifest:qt,getDeviceInfo:()=>ft.getDeviceInfo()},r}();return"undefined"!=typeof window&&(window.saltfish=Jt),Jt}));
|