UNPKG

saltfish

Version:

An interactive video-guided tour system for web applications

7 lines (6 loc) 274 kB
/*! * Saltfish playlist Player v0.3.75 * (c) 2026 * Released under the MIT License. */ !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);const n={},i=t=>{let e;const i=new Set,s=(t,n)=>{const s="function"==typeof t?t(e):t;if(!Object.is(s,e)){const t=e;e=(null!=n?n:"object"!=typeof s||null===s)?s:Object.assign({},e,s),i.forEach((n=>n(e,t)))}},r=()=>e,a={setState:s,getState:r,getInitialState:()=>o,subscribe:t=>(i.add(t),()=>i.delete(t)),destroy:()=>{"production"!==(n?"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."),i.clear()}},o=e=t(s,r,a);return a};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===m(t)?Reflect.ownKeys(t).forEach((n=>{e(n,t[n],t)})):t.forEach(((n,i)=>e(i,n,t)))}function m(t){const e=t[a];return e?e.type_:Array.isArray(t)?1:y(t)?2:v(t)?3:0}function g(t,e){return 2===m(t)?t.has(e):Object.prototype.hasOwnProperty.call(t,e)}function f(t,e,n){const i=m(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 M(t)||c(t)||!d(t)||(m(t)>1&&(t.set=t.add=t.clear=t.delete=E),Object.freeze(t),e&&Object.entries(t).forEach((([t,e])=>S(e,!0)))),t}function E(){o(2)}function M(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,e){e&&(P("Patches"),t.patches_=[],t.inversePatches_=[],t.patchListener_=e)}function k(t){T(t),t.drafts_.forEach(z),t.drafts_=null}function T(t){t===x&&(x=t.parent_)}function A(t){return x={drafts_:[],parent_:x,immer_:t,canAutoFreeze_:!0,unfinalizedDrafts_:0}}function z(t){const e=t[a];0===e.type_||1===e.type_?e.revoke_():e.revoked_=!0}function L(t,e){e.unfinalizedDrafts_=e.drafts_.length;const n=e.drafts_[0];return void 0!==t&&t!==n?(n[a].modified_&&(k(e),o(4)),d(t)&&(t=V(e,t),e.parent_||D(e,t)),e.patches_&&P("Patches").generateReplacementPatches_(n[a].base_,t,e.patches_,e.inversePatches_)):t=V(e,n,[]),k(e),e.patches_&&e.patchListener_(e.patches_,e.inversePatches_),t!==s?t:void 0}function V(t,e,n){if(M(e))return e;const i=e[a];if(!i)return p(e,((s,r)=>O(t,i,e,s,r,n))),e;if(i.scope_!==t)return e;if(!i.modified_)return D(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)=>O(t,i,e,s,a,n,r))),D(t,e,!1),n&&t.patches_&&P("Patches").generatePatches_(i,n,t.patches_,t.inversePatches_)}return i.copy_}function O(t,e,n,i,s,r,a){if(c(s)){const a=V(t,s,r&&e&&3!==e.type_&&!g(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)&&!M(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)||D(t,s)}}function D(t,e,n=!1){!t.parent_&&t.immer_.autoFreeze_&&t.canAutoFreeze_&&S(e,n)}var F={get(t,e){if(e===a)return t;const n=b(t);if(!g(n,e))return function(t,e,n){var i;const s=N(e,n);return s?"value"in s?s.value:null==(i=s.get)?void 0:i.call(t.draft_):void 0}(t,n,e);const i=n[e];return t.finalized_||!d(i)?i:i===U(t.base_,e)?(H(t),t.copy_[e]=$(i,t)):i},has:(t,e)=>e in b(t),ownKeys:t=>Reflect.ownKeys(b(t)),set(t,e,n){const i=N(b(t),e);if(null==i?void 0:i.set)return i.set.call(t.draft_,n),!0;if(!t.modified_){const i=U(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||g(t.base_,e)))return!0;H(t),R(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!==U(t.base_,e)||e in t.base_?(t.assigned_[e]=!1,H(t),R(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)}},B={};function U(t,e){const n=t[a];return(n?b(n):t)[e]}function N(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 R(t){t.modified_||(t.modified_=!0,t.parent_&&R(t.parent_))}function H(t){t.copy_||(t.copy_=w(t.base_,t.scope_.immer_.useStrictShallowCopy_))}p(F,((t,e)=>{B[t]=function(){return arguments[0]=arguments[0][0],e.apply(this,arguments)}})),B.deleteProperty=function(t,e){return B.set.call(this,t,e,void 0)},B.set=function(t,e,n){return F.set.call(this,t[0],e,n,t[0])};function $(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=F;n&&(s=[i],r=B);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 Y(t){if(!d(t)||M(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,Y(e))})),e&&(e.finalized_=!1),n}var X=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=A(this),r=$(t,void 0);let a=!0;try{i=e(r),a=!1}finally{a?k(s):T(s)}return _(s,n),L(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){c(t)||o(10);return Y(t)}(t));const e=A(this),n=$(t,void 0);return n[a].isManual_=!0,T(e),n}finishDraft(t,e){const n=t&&t[a];n&&n.isManual_||o(9);const{scope_:i}=n;return _(i,e),L(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=X.produce;X.produceWithPatches.bind(X),X.setAutoFreeze.bind(X),X.setUseStrictShallowCopy.bind(X),X.applyPatches.bind(X),X.createDraft.bind(X),X.finishDraft.bind(X);const j=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));function q(t,e){void 0!==e?console.info(t,e):console.info(t)}function Z(t,e){console.warn(t)}function G(t,e){void 0!==e?console.error(t,e):console.error(t)}class K{constructor(t,n){e(this,"currentState"),e(this,"config"),e(this,"context"),e(this,"actionHandlers",{}),this.config=t,this.currentState=t.initial,this.context=n,this.setupDefaultActions(),this.runEntryActions(this.currentState)}setupDefaultActions(){this.actionHandlers={...this.actionHandlers,logStateEntry:t=>{this.currentState},logErrorEvent:(t,e)=>{"ERROR"===(null==e?void 0:e.type)&&e.error.message},logStepTransition:(t,e)=>{"TRANSITION_TO_STEP"===(null==e?void 0:e.type)&&e.step.id},logErrorRecovery:()=>{}}}registerActions(t){this.actionHandlers={...this.actionHandlers,...t},Object.keys(t).join(", ")}executeAction(t,e){if("string"==typeof t){const n=this.actionHandlers[t];n&&n(this.context,e)}else t(this.context,e)}send(t){const e=this.config.states[this.currentState].on[t.type];if(!e)return t.type,this.currentState,this.currentState;this.currentState,e.target,t.type,this.runExitActions(this.currentState),this.updateContextFromEvent(t),e.actions&&e.actions.forEach((e=>this.executeAction(e,t)));this.currentState;return this.currentState=e.target,this.runEntryActions(this.currentState),this.currentState,this.currentState}updateContextFromEvent(t){"TRANSITION_TO_STEP"===t.type||"MANIFEST_LOADED"===t.type||"VIDEO_FINISHED_WAIT"===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 J={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","showLoadingState"],exit:["hideLoadingState"]},playing:{on:{PAUSE:{target:"paused"},MINIMIZE:{target:"minimized"},VIDEO_FINISHED_WAIT:{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","showVideoControls","hidePlayButton"],exit:["pauseVideoPlayback"]},paused:{on:{PLAY:{target:"playing"},START_IDLE_MODE:{target:"idleMode"},MINIMIZE:{target:"minimized"},TRANSITION_TO_STEP:{target:"playing",actions:["logStepTransition"]}},entry:["logStateEntry","pauseVideoPlayback","showPlayButton"]},minimized:{on:{MAXIMIZE:{target:"playing"},EXIT:{target:"closing"}},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","showPlayButton"]},autoplayBlocked:{on:{PLAY:{target:"playing"},TRANSITION_TO_STEP:{target:"playing"},MINIMIZE:{target:"minimized"}},entry:["logStateEntry","enterCompactMode","startMutedLoopedVideo","hideVideoControls","showPlayButton","enablePlayButtonProminent"],exit:["disablePlayButtonProminent","showVideoControls","exitCompactMode"]},idleMode:{on:{PLAY:{target:"playing"},TRANSITION_TO_STEP:{target:"playing"},MINIMIZE:{target:"minimized"}},entry:["logStateEntry","startIdleModeVideo","hideVideoControls","showPlayButton","enablePlayButtonProminent"],exit:["disablePlayButtonProminent","showVideoControls","exitCompactMode"]},error:{on:{INITIALIZE:{target:"idle"},PLAY:{target:"playing",actions:["logErrorRecovery"]},AUTOPLAY_FALLBACK:{target:"autoplayBlocked"}},entry:["logStateEntry","handleError","showPlayButton"],exit:["hideError"]},completedWaitingForInteraction:{on:{COMPLETE_PLAYLIST:{target:"completed"},INITIALIZE:{target:"idle"},TRANSITION_TO_STEP:{target:"playing",actions:["logStepTransition"]},PLAY:{target:"playing"},MINIMIZE:{target:"minimized"}},entry:["logStateEntry","showPlayButton"]},completed:{on:{INITIALIZE:{target:"idle"}},entry:["logStateEntry","trackPlaylistComplete"]},closing:{on:{},entry:["logStateEntry","triggerPlaylistDismissed"]}}},Q="saltfish_progress",tt="saltfish_session",et="saltfish_anonymous_user_data",nt="saltfish_pending_navigation",it="https://player.saltfish.ai",st="https://studio-api.saltfish.ai/studio/flows2/share",rt="sf-player",at="sf-player--minimized",ot="sf-controls-container",lt="sf-player__logo",ct="sf-error-display",dt="sf-error-display--visible",ht="sf-error-display__content",ut="sf-error-display__message",pt="sf-loading-spinner",mt=class t{constructor(){e(this,"isLocalStorageAvailable"),this.isLocalStorageAvailable=this.checkLocalStorageAvailability(),this.isLocalStorageAvailable}static getInstance(){return t.instance||(t.instance=new t),t.instance}static resetInstance(){t.instance=null}checkLocalStorageAvailability(){if("undefined"==typeof window)return!1;try{const t="__storage_test__";return localStorage.setItem(t,"test"),localStorage.removeItem(t),!0}catch(t){return!1}}safeGetItem(t){if(!this.isLocalStorageAvailable)return null;try{const e=localStorage.getItem(t);return null===e?null:JSON.parse(e)}catch(e){return this.safeClearItem(t),null}}safeSetItem(t,e){if(!this.isLocalStorageAvailable)return!1;try{return localStorage.setItem(t,JSON.stringify(e)),!0}catch(n){if(n instanceof DOMException&&22===n.code){this.clearOldData();try{return localStorage.setItem(t,JSON.stringify(e)),!0}catch(i){}}return!1}}safeClearItem(t){if(this.isLocalStorageAvailable)try{localStorage.removeItem(t)}catch(e){}}clearOldData(){this.safeClearItem(tt)}getProgress(t){const e=this.safeGetItem(Q);return e?t&&e.userId&&e.userId!==t?(e.userId,null):e.playlists||null:null}setProgress(t,e){const n={userId:e,playlists:t};return this.safeSetItem(Q,n)}clearProgress(){this.safeClearItem(Q)}getSession(){return this.safeGetItem(tt)}setSession(t){return this.safeSetItem(tt,t)}clearSession(){this.safeClearItem(tt)}getAnonymousUserData(){return this.safeGetItem(et)}setAnonymousUserData(t){return this.safeSetItem(et,t)}clearAnonymousUserData(){this.safeClearItem(et)}getPendingNavigation(){return this.safeGetItem(nt)}setPendingNavigation(t){return t.nextStepId,t.urlPattern,this.safeSetItem(nt,t)}clearPendingNavigation(){this.safeClearItem(nt)}clearAll(){this.clearProgress(),this.clearSession(),this.clearAnonymousUserData(),this.clearPendingNavigation()}};e(mt,"instance",null);let gt=mt;const ft=gt.getInstance(),yt=i(j(((t,e)=>{let n=new K(J,{currentStep:null,error:null});const i=t=>n.send(t);return{config:null,user:null,userData:null,currentState:n.getState(),manifest:null,currentStepId:null,isMinimized:!1,position:null,progress:{},error:null,playlistOptions:null,backendPlaylists:[],isAdmin:!1,isMuted:!1,abTests:[],abTestAssignments:{},initialize:async e=>{t((t=>{t.config=e,t.currentState=i({type:"INITIALIZE"})}))},setPlaylistOptions:e=>{t((t=>{if(t.playlistOptions=e,e.position){const n="bottom-left"===e.position||"bottom-right"===e.position?e.position:"bottom-right";t.position={x:0,y:0},t.playlistOptions={...e,position:n}}}))},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;const s=e.steps.find((t=>t.id===n));t.currentState=i(s?{type:"MANIFEST_LOADED",step:s}:{type:"ERROR",error:new Error(`Start step '${n}' not found in manifest`)})}))},play:()=>{const{currentState:n}=e();t((t=>{t.currentState=i({type:"PLAY"})}))},pause:()=>{const{currentState:n}=e();t((t=>{t.currentState=i({type:"PAUSE"})}))},minimize:()=>{const{currentState:n}=e();t((t=>{"playing"===t.currentState&&(t.currentState=i({type:"PAUSE"})),t.currentState=i({type:"MINIMIZE"}),t.isMinimized=!0}))},maximize:()=>{t((t=>{t.currentState=i({type:"MAXIMIZE"}),t.isMinimized=!1}))},goToStep:n=>{const{manifest:s}=e();if("completed"!==n){if(s&&s.steps.some((t=>t.id===n))){const e=s.steps.find((t=>t.id===n));t((t=>{var r,a,o;t.currentStepId=n,e&&(t.currentState=i({type:"TRANSITION_TO_STEP",step:e}),(t.position||(null==(r=t.playlistOptions)?void 0:r.position))&&(t.position={x:0,y:0})),t.progress[s.id]={...t.progress[s.id],lastStepId:n,lastVisited:(new Date).toISOString()};if((null==(a=t.playlistOptions)?void 0:a.persistence)??!0){const e=null==(o=t.user)?void 0:o.id;ft.setProgress(t.progress,e)}}))}}else t((t=>{t.currentState=i({type:"COMPLETE_PLAYLIST"})}))},reset:()=>{t((t=>{t.config=null,t.user=null,t.userData=null,t.currentState=n.getState(),t.manifest=null,t.currentStepId=null,t.isMinimized=!1,t.position=null,t.progress={},t.error=null,n=new K(J,{currentStep:null,error:null})}))},setError:e=>{t((t=>{t.currentState=i({type:"ERROR",error:e}),t.error=e}))},setAutoplayFallback:()=>{t((t=>{t.currentState=i({type:"AUTOPLAY_FALLBACK"})}))},setIdleMode:()=>{t((t=>{t.currentState=i({type:"START_IDLE_MODE"})}))},setMuted:e=>{t((t=>{t.isMuted=e}))},setBackendPlaylists:e=>{t((t=>{t.backendPlaylists=e}))},setIsAdmin:e=>{t((t=>{t.isAdmin=e}))},completePlaylist:()=>{t((t=>{t.currentState=i({type:"COMPLETE_PLAYLIST"})}))},resetForNewPlaylist:()=>{t((t=>{const e=t.config,i=t.user,s=t.userData,r=t.progress;t.manifest=null,t.currentStepId=null,t.isMinimized=!1,t.position=null,t.error=null,t.playlistOptions=null,n=new K(J,{currentStep:null,error:null}),t.currentState=n.getState(),t.config=e,t.user=i,t.userData=s,t.progress=r}))},loadPlaylistProgress:(e,n)=>{t((t=>{t.progress[e]=n}))},registerStateMachineActions:t=>{n.registerActions(t)},sendStateMachineEvent:e=>{t((t=>{t.currentState=i(e)}))},updateProgressWithCompletion:(e,n)=>{t((t=>{var s,r;t.currentState=i({type:"COMPLETE_PLAYLIST_WAITING_FOR_INTERACTION"}),t.progress[e]={...t.progress[e],lastStepId:n,lastVisited:(new Date).toISOString(),completedWaitingForInteraction:!0};if((null==(s=t.playlistOptions)?void 0:s.persistence)??!0){const e=null==(r=t.user)?void 0:r.id;ft.setProgress(t.progress,e)}}))},setABTests:e=>{t((t=>{t.abTests=e}))},setABTestAssignments:e=>{t((t=>{t.abTestAssignments=e}))},getFilteredPlaylists:()=>{const t=e(),n=t.backendPlaylists||[],i=t.abTests||[],s=t.abTestAssignments||{};if(0===i.length)return n;const r=new Set;for(const e of i){const t=s[e.id];t&&t.assigned||r.add(e.playlistId)}return n.filter((t=>!r.has(t.id)))}}}))),vt={getState:()=>yt.getState(),setState:yt.setState,subscribe:yt.subscribe,destroy:yt.destroy};function bt(){try{return vt.getState()}catch(t){throw new Error(`[storeUtils] Failed to access Saltfish store: ${t}`)}}function wt(t){if(!t)return null;if(t.lastProgressAt&&"object"==typeof t.lastProgressAt&&"_seconds"in t.lastProgressAt&&"_nanoseconds"in t.lastProgressAt){const e=t.lastProgressAt;return 1e3*e._seconds+Math.floor(e._nanoseconds/1e6)}return t.timestamp&&"number"==typeof t.timestamp?t.timestamp:t.lastProgressAt&&"number"==typeof t.lastProgressAt?t.lastProgressAt:null}function St(t,e=6e3){const n=wt(t);if(!n)return{isValid:!1,ageMs:null,timestampMs:null};const i=Date.now()-n;return{isValid:i<=e,ageMs:i,timestampMs:n}}class Et{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{bt().setError(t)}catch(e){console.error("Failed to update store with error:",e)}}static triggerErrorEvent(t,e,n){var i,s;try{const r=bt();if("undefined"!=typeof window&&window._saltfishPlayer){const a=window._saltfishPlayer;a&&a.eventManager&&a.eventManager.trigger("error",{timestamp:Date.now(),playlistId:e.playlistId||(null==(i=r.manifest)?void 0:i.id),stepId:e.stepId||r.currentStepId,error:t,errorType:e.errorType||n||(null==(s=e.component)?void 0:s.toLowerCase())||"unknown"})}}catch(r){console.error("Failed to trigger error event:",r)}}static destroyPlayer(){try{if("undefined"!=typeof window&&window._saltfishPlayer){const t=window._saltfishPlayer;t&&"function"==typeof t.destroy&&t.destroy()}}catch(t){console.error("Failed to destroy player during error handling:",t)}}static createError(t,e={}){const n=new Error(this.formatErrorMessage(new Error(t),e));return e.component&&(n.component=e.component),e.method&&(n.method=e.method),e.playlistId&&(n.playlistId=e.playlistId),e.stepId&&(n.stepId=e.stepId),n}static isRecoverable(t){if(t.message.includes("fetch")||t.message.includes("network")||t.message.includes("timeout"))return!0;return[/autoplay.*blocked/i,/video.*failed.*load/i,/manifest.*not.*found/i].some((e=>e.test(t.message)))}static async safeExecute(t,e={},n={}){try{return await t()}catch(i){return this.handle(i,e,n),null}}}e(Et,"DEFAULT_OPTIONS",{severity:"error",shouldLog:!0,shouldThrow:!1,shouldUpdateStore:!1,shouldTriggerEvent:!1,shouldDestroy:!1});class Mt{detectShareIdFromUrl(){try{const t=window.location.href,e=/saltfish-share-id=([^&#]*)/,n=t.match(e);if(n&&n[1]){const t=n[1];return t}return null}catch(t){return null}}async fetchShareData(t){try{const e=await fetch(`${st}/${t}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!e.ok)throw new Error(`Share API returned status ${e.status}`);const n=await e.json();if(!n.flowId)throw new Error("Share API response missing flowId");return n.shareId,n.flowId,n.createdBy,n}catch(e){throw Et.handleInitializationError(e,{component:"ShareLinkService",method:"fetchShareData",additionalData:{shareId:t}})}}async shouldAutoStartSharePlaylist(){try{const t=this.detectShareIdFromUrl();if(!t)return null;const e=await this.fetchShareData(t);return e.flowId,e.isGlobal,e}catch(t){return null}}}const xt=3e4,It=100,Pt=12e4,Ct=500,_t=500,kt=5e3,Tt=18e5,At=6e4,zt=10;function Lt(t){try{let e=t.replace(/[?&]saltfish-share-id=[^&#]*/g,((e,n)=>{if(e.startsWith("?")){return t.substring(n+e.length).startsWith("&")?"?":""}return""}));return e=e.replace(/\?&/g,"?"),e=e.replace(/&&/g,"&"),e=e.replace(/\?$/g,""),e=e.replace(/&$/g,""),e}catch(e){return t}}function Vt(t){const{pattern:e,matchType:n}=t;if(!e)return!0;const i=Lt(window.location.href),s=window.location.pathname;if("regex"===n)try{const t=new RegExp(e),n=t.test(i),r=t.test(s),a=n||r;return a}catch(r){return!1}if("contains"===n){return i.includes(e)||s.includes(e)}return i===e||s===e}class Ot{constructor(t){e(this,"managers"),e(this,"userManagementService"),e(this,"playlistOrchestrator"),e(this,"shareLinkService"),e(this,"lastConfig",null),this.managers=t,this.shareLinkService=new Mt}setUserManagementService(t){this.userManagementService=t}setPlaylistOrchestrator(t){this.playlistOrchestrator=t}getLastConfig(){return this.lastConfig}async initialize(t){var e;try{const n=await fetch(`${it}/validate-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:t.token,playerVersion:"0.2.73"})}),i=await n.json();if(!i.isValid)throw Et.handleInitializationError(i.error||"Token validation failed",{component:"PlayerInitializationService",method:"initialize",additionalData:{token:(null==(e=t.token)?void 0:e.substring(0,10))+"..."}});const s={...t,showLogo:!1!==i.showLogo};this.lastConfig=s;const r=bt();if(r.initialize(s),this.managers.analyticsManager.initialize(t,this.managers.sessionManager.getSessionId()),i.isAdmin&&r.setIsAdmin&&r.setIsAdmin(!0),i.playlists&&Array.isArray(i.playlists)&&r.setBackendPlaylists)i.playlists,r.setBackendPlaylists(i.playlists),i.playlists.length>0?this.managers.triggerManager.registerTriggers(i.playlists):i.isAdmin,i.abTests&&Array.isArray(i.abTests)&&(i.abTests,this.managers.abTestManager.initializeTests(i.abTests));else if(!i.isAdmin)throw Et.handleInitializationError("Backend validation successful, but no playlists array provided in the response. Cannot initialize player.",{component:"PlayerInitializationService",method:"initialize",additionalData:{responseData:i}});this.managers.eventManager.trigger("initialized",{timestamp:Date.now()})}catch(n){throw Et.handleInitializationError(n,{component:"PlayerInitializationService",method:"initialize"})}}async fetchUserData(t,e){var n;try{const i=bt();if(!(null==(n=i.config)?void 0:n.token))return void Et.handleWarning("Cannot fetch user data: Token not available",{component:"PlayerInitializationService",method:"fetchUserData",userId:t});const s=await fetch(`https://player.saltfish.ai/clients/${i.config.token}/users/${t}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userData:e})});if(!s.ok){await s.text();return s.status,void s.statusText}const r=await s.json();if(r.success){i.setUserData({watchedPlaylists:r.watchedPlaylists||{},language:r.language});const e=r.userListAssignments||{},n=r.abTestAssignments||{};this.managers.abTestManager.assignUserToTests(t,n,e),this.managers.eventManager.trigger("userDataLoaded",{timestamp:Date.now(),userId:t,userData:{watchedPlaylists:r.watchedPlaylists||{}}}),this.userManagementService&&this.userManagementService.resolveUserDataLoaded();const s=await this.checkAndResumeFromPendingNavigation();if(!(s||await this.checkAndResumeInProgressPlaylist(r.watchedPlaylists||{}))){const t=await this.shareLinkService.shouldAutoStartSharePlaylist();t&&this.playlistOrchestrator?(t.flowId,await this.playlistOrchestrator.startPlaylist(t.flowId,{once:!1,position:"bottom-right",_startedFromShareLink:!0,_isGlobalShare:t.isGlobal})):this.managers.triggerManager.startMonitoring()}}else this.userManagementService&&this.userManagementService.resolveUserDataLoaded()}catch(i){Et.handleNetworkError(i,{component:"PlayerInitializationService",method:"fetchUserData",userId:t}),this.userManagementService&&this.userManagementService.resolveUserDataLoaded()}}async loadAnonymousUserData(t,e){try{if("undefined"==typeof window)return;const n=this.managers.abTestManager.assignUserToTests(t,void 0,{}),i=this.managers.storageManager.getAnonymousUserData();let s={userId:t,userData:e||{},watchedPlaylists:{},abTestAssignments:n,timestamp:Date.now()};if(i){const n=i.abTestAssignments||{},r=this.managers.abTestManager.assignUserToTests(t,n);s={userId:t,userData:{...i.userData,...e},watchedPlaylists:i.watchedPlaylists||{},abTestAssignments:r,timestamp:Date.now()}}this.managers.storageManager.setAnonymousUserData(s);bt().setUserData({watchedPlaylists:s.watchedPlaylists||{},language:null==e?void 0:e.language}),this.managers.eventManager.trigger("userDataLoaded",{timestamp:Date.now(),userId:t,userData:{watchedPlaylists:s.watchedPlaylists||{}}});const r=await this.checkAndResumeFromPendingNavigation(),a=s.watchedPlaylists||{};if(!(r||await this.checkAndResumeInProgressPlaylist(a))){const t=await this.shareLinkService.shouldAutoStartSharePlaylist();t&&this.playlistOrchestrator?(t.flowId,await this.playlistOrchestrator.startPlaylist(t.flowId,{once:!1,position:"bottom-right",_startedFromShareLink:!0,_isGlobalShare:t.isGlobal})):this.managers.triggerManager.startMonitoring()}}catch(n){Et.handleNetworkError(n,{component:"PlayerInitializationService",method:"loadAnonymousUserData",userId:t})}}async checkAndResumeInProgressPlaylist(t){var e;if(!t)return!1;const n=bt(),i=null==(e=n.manifest)?void 0:e.id,s=n.currentState;if(i&&"idle"!==s&&"error"!==s)return!1;const r=Object.entries(t).find((([t,e])=>{if("in_progress"!==(null==e?void 0:e.status))return!1;const{isValid:n,ageMs:i}=St(e);return!!n}));if(r){const[t,e]=r;wt(e);try{if(this.playlistOrchestrator)return await this.playlistOrchestrator.startPlaylist(t),!0}catch(a){return!1}}return!1}async checkAndResumeFromPendingNavigation(){const t=this.managers.storageManager.getPendingNavigation();if(!t)return!1;if(Date.now()-t.timestamp>At)return this.managers.storageManager.clearPendingNavigation(),!1;if(!this.isURLPathMatch(t.urlPattern))return t.urlPattern,this.managers.storageManager.clearPendingNavigation(),!1;t.playlistId,t.nextStepId,this.managers.storageManager.clearPendingNavigation();try{if(this.playlistOrchestrator)return await this.playlistOrchestrator.startPlaylist(t.playlistId,{startNodeId:t.nextStepId}),!0}catch(e){return!1}return!1}isURLPathMatch(t){if(!t||"undefined"==typeof window)return!1;const e=Lt(window.location.href),n=window.location.pathname,i=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/\\\*/g,".*"),s=new RegExp(i);return s.test(e)||s.test(n)}getOrCreateAnonymousUserId(){if("undefined"==typeof window)return`anonymous_${Date.now()}_${Math.random().toString(36).substring(2,11)}`;const t=this.managers.storageManager.getAnonymousUserData();if(null==t?void 0:t.userId)return t.userId,t.userId;const e=`anonymous_${Date.now()}_${Math.random().toString(36).substring(2,11)}`;return this.managers.storageManager.setAnonymousUserData({userId:e,userData:{},watchedPlaylists:{},timestamp:Date.now()}),e}destroy(){this.lastConfig=null}}function Dt(t){if(!t)return;if("auto"===t){return function(){try{const t=navigator.language||navigator.userLanguage;if(!t)return;return t.split("-")[0].toLowerCase()}catch(t){return}}()}return t.split("-")[0].toLowerCase()}class Ft{constructor(t){e(this,"managers"),e(this,"playerInitializationService"),e(this,"userDataLoadedPromise",null),e(this,"userDataLoadedResolve",null),e(this,"lastUserIdentification",null),this.managers=t}setPlayerInitializationService(t){this.playerInitializationService=t}getLastUserIdentification(){return this.lastUserIdentification}getUserDataLoadedPromise(){return this.userDataLoadedPromise}identifyUser(t,e){let n=e;if(e&&"string"==typeof e.language){const t=Dt(e.language);n={...e,language:t},e.language}this.lastUserIdentification={userId:t,userData:n};const i=bt();i.identifyUser(t,n),this.managers.analyticsManager.setUser({id:t,...n});(i.abTests||[]).length>0&&(this.userDataLoadedPromise=new Promise((t=>{this.userDataLoadedResolve=t}))),this.playerInitializationService&&this.playerInitializationService.fetchUserData(t,n)}async identifyAnonymous(t){if(!this.playerInitializationService)throw new Error("PlayerInitializationService not set");let e=t;if(t&&"string"==typeof t.language){const n=Dt(t.language);e={...t,language:n},t.language}const n=this.playerInitializationService.getOrCreateAnonymousUserId();this.lastUserIdentification={userId:n,userData:e};bt().identifyUser(n,{...e,__isAnonymous:!0}),this.managers.analyticsManager.setUser({id:n,...e}),await this.playerInitializationService.loadAnonymousUserData(n,e)}async recordABTestAttempt(t){var e;try{const n=bt(),i=n.user;if(!i||!(null==(e=n.config)?void 0:e.token))return;const s=(n.abTests||[]).find((e=>e.playlistId===t));if(!s)return;const r=(n.abTestAssignments||{})[s.id];if(!r)return void s.id;s.name,r.assigned;const a=await fetch(`https://player.saltfish.ai/clients/${n.config.token}/users/${i.id}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({abTestAssignments:{[s.id]:r}})});a.ok?s.name:(a.status,a.statusText)}catch(n){}}resolveUserDataLoaded(){this.userDataLoadedResolve&&(this.userDataLoadedResolve(),this.userDataLoadedResolve=null,this.userDataLoadedPromise=null)}destroy(){this.userDataLoadedPromise=null,this.userDataLoadedResolve=null,this.lastUserIdentification=null}}class Bt{async validatePlaylistStart(t){const{playlistId:e,options:n,eventManager:i}=t;try{const t=bt();if(!t.config)return{isValid:!1,error:"Saltfish Player must be initialized before starting a playlist"};if(!0===t.isAdmin){return{isValid:!0,manifestPath:`https://storage.saltfish.ai/flows2/drafts/${e}.json`,updatedOptions:n}}if(!0===(null==n?void 0:n._startedFromShareLink)&&!0===(null==n?void 0:n._isGlobalShare)){return{isValid:!0,manifestPath:`https://storage.saltfish.ai/flows2/drafts/${e}.json`,updatedOptions:n}}!0===(null==n?void 0:n._startedFromShareLink)&&(null==n||n._isGlobalShare);const s=t.backendPlaylists;if(!s||0===s.length)return Et.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 Et.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((null==r?void 0:r.hasTriggers)??(null==r?void 0:r.autoStart)??!1){const t=await this.validateTriggerConditions(e,r,i);if(!t.isValid)return t}let a=n;if(null==n?void 0:n.once){const t=await this.validateOnceOptionConditions(e,n,i);if(!t.isValid)return t;a=t.updatedOptions||n}const o=await this.validateDeviceCompatibility(r,e);return o.isValid?{isValid:!0,manifestPath:r.path,updatedOptions:a}:o}catch(s){const t=s instanceof Error?s.message:"Unknown validation error";return Et.handlePlaylistError(`Playlist validation failed: ${t}`,{component:"PlaylistValidator",method:"validatePlaylistStart",playlistId:e,additionalData:{error:s}}),{isValid:!1,error:t}}}async validateTriggerConditions(t,e,n){var i,s;const r=bt();if(!r.user)return Et.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 triggered playlist"};r.userData||await this.waitForUserData(n);const a=(null==(i=bt().userData)?void 0:i.watchedPlaylists)||{},o=e.hasTriggers??e.autoStart??!1,l=a[t],c=null==(s=e.triggers)?void 0:s.maxVisits,d=(null==l?void 0:l.visitCount)??("completed"===(null==l?void 0:l.status)||"dismissed"===(null==l?void 0:l.status)?1:0);return o&&null!=c&&d>=c?(q(`Playlist ${t} has hasTriggers enabled with maxVisits:${c} and user has ${d} visits. Skipping playlist start.`,{watchedPlaylists:a,triggers:e.triggers}),{isValid:!1,error:`Playlist visit limit reached (${d}/${c})`}):{isValid:!0}}async validateOnceOptionConditions(t,e,n){var i;const s=bt();if(!s.user)return Et.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=bt().userData)?void 0:i.watchedPlaylists)||{},a=r[t];if(a&&("completed"===a.status||"dismissed"===a.status))return q(`Playlist ${t} has once option enabled and has already been ${a.status}. Skipping playlist start.`,{watchedPlaylists:r,playlistStatus:a.status}),{isValid:!1,error:`Playlist already ${a.status} with once option`};if(a&&"in_progress"===a.status&&!(null==e?void 0:e.startNodeId)&&a.currentStepId){return{isValid:!0,updatedOptions:{...e,startNodeId:a.currentStepId}}}return{isValid:!0}}async validateDeviceCompatibility(t,e){try{const n=t.deviceType||"both",{isDeviceCompatible:i}=await Promise.resolve().then((()=>jt));return i(n)?{isValid:!0}:(Et.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 Et.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),bt(),e()};t.on("userDataLoaded",s)}))}}class Ut{constructor(t){e(this,"managers"),e(this,"userManagementService"),e(this,"managerOrchestrator"),e(this,"playerInitializationService"),e(this,"stateMachineActionHandler"),this.managers=t}setUserManagementService(t){this.userManagementService=t}setManagerOrchestrator(t){this.managerOrchestrator=t}setPlayerInitializationService(t){this.playerInitializationService=t}setStateMachineActionHandler(t){this.stateMachineActionHandler=t}async startPlaylist(t,e){var n,i,s,r,a;try{const l=this.isInitialized()&&!this.managers.uiManager.getPlayerElement();if(!this.isInitialized()&&this.playerInitializationService){const e=this.playerInitializationService.getLastConfig();if(e)try{await this.playerInitializationService.initialize(e);const t=null==(n=this.userManagementService)?void 0:n.getLastUserIdentification();t&&this.userManagementService&&this.userManagementService.identifyUser(t.userId,t.userData),this.resetManagers(),this.stateMachineActionHandler&&this.stateMachineActionHandler.registerStateMachineActions()}catch(o){throw Et.handleInitializationError(`Failed to reinitialize player: ${o instanceof Error?o.message:"Unknown error"}`,{component:"PlaylistOrchestrator",method:"startPlaylist",playlistId:t,additionalData:{reinitError:o}})}}l&&(this.resetManagers(),this.managers.transitionManager.setTriggerManager(this.managers.triggerManager),this.stateMachineActionHandler&&this.stateMachineActionHandler.registerStateMachineActions());const c=bt();if(!c.config){if(!(null==(i=this.playerInitializationService)?void 0:i.getLastConfig()))throw Et.createError("Saltfish Player must be initialized at least once before starting a playlist",{component:"PlaylistOrchestrator",method:"startPlaylist",playlistId:t});throw Et.createError("Saltfish Player must be initialized before starting a playlist",{component:"PlaylistOrchestrator",method:"startPlaylist",playlistId:t})}c.manifest&&("playing"===c.currentState||"paused"===c.currentState||"loading"===c.currentState||"waitingForInteraction"===c.currentState||"autoplayBlocked"===c.currentState||"minimized"===c.currentState||"idleMode"===c.currentState)&&(this.managerOrchestrator&&this.managerOrchestrator.cleanupCurrentPlaylist(),c.resetForNewPlaylist(),this.stateMachineActionHandler&&this.stateMachineActionHandler.registerStateMachineActions()),"completed"!==c.currentState&&"closing"!==c.currentState||(c.currentState,c.resetForNewPlaylist(),this.stateMachineActionHandler&&this.stateMachineActionHandler.registerStateMachineActions());this.managers.sessionManager.startNewRun();this.managers.triggerManager.markPlaylistAsTriggered(t);const d=null==(s=this.userManagementService)?void 0:s.getUserDataLoadedPromise();if(d&&await d,this.userManagementService&&await this.userManagementService.recordABTestAttempt(t),!0!==(null==e?void 0:e._startedFromShareLink)){if(!this.managers.abTestManager.isPlaylistAvailable(t))return}else null==e||e._startedFromShareLink;const h=new Bt,u=await h.validatePlaylistStart({playlistId:t,options:e,eventManager:this.managers.eventManager});if(!u.isValid)return;e=u.updatedOptions||e;const p=u.manifestPath,m=e||{};m?(c.setPlaylistOptions(m),m.position||c.setPlaylistOptions({...m,position:"bottom-right"})):c.setPlaylistOptions({position:"bottom-right"}),this.managers.uiManager.createPlayerUI(this.managers.videoManager,this.managers.cursorManager,this.managers.interactionManager),this.managerOrchestrator&&this.managerOrchestrator.setupUpdaters(),this.managers.uiManager.updatePosition(),c.sendStateMachineEvent({type:"LOAD_MANIFEST"});const g=null==e?void 0:e.persistence;if("undefined"!=typeof window){const e=null==(r=c.user)?void 0:r.id,n=this.managers.storageManager.getProgress(e);if(n&&n[t])c.loadPlaylistProgress(t,n[t]);else if(c.progress[t]){const e={...c.progress};delete e[t],vt.setState((t=>{t.progress=e}))}}this.managers.cursorManager.resetFirstAnimation(),await this.managers.playlistManager.load(p,{...m,persistence:g});const f=bt();if(f.manifest){const t=m.persistence??f.manifest.isPersistent??!0,e=f.playlistOptions||{};f.setPlaylistOptions({...e,...m,persistence:t})}if(m.startNodeId&&f.manifest){f.manifest.steps.find((t=>t.id===m.startNodeId))?f.goToStep(m.startNodeId):console.warn(`[PlaylistOrchestrator] startNodeId '${m.startNodeId}' not found in manifest steps. Starting from default step.`)}if(f.manifest){f.manifest.cursorColor&&this.managers.cursorManager.setColor(f.manifest.cursorColor),f.manifest.cursorLabel&&this.managers.cursorManager.setLabel(f.manifest.cursorLabel);m._triggeredByTriggerManager;const t=f.currentStepId===(null==(a=f.manifest.steps[0])?void 0:a.id);if(f.manifest.idleMode&&t){if(f.manifest.compactFirstStep){const t=this.managers.uiManager.getPlayerElement();null==t||t.classList.add("sf-player--compact"),f.manifest.compactLabel&&this.managers.uiManager.showCompactLabel(f.manifest.compactLabel)}c.setIdleMode()}else c.play()}else c.play();q(`Playlist started: ${t}${f.manifest?` (${f.manifest.name})`:""}`)}catch(l){this.managers.uiManager.hideLoading();bt().sendStateMachineEvent({type:"ERROR",error:l instanceof Error?l:new Error(String(l))}),Et.handlePlaylistError(l,{component:"PlaylistOrchestrator",method:"startPlaylist",playlistId:t,errorType:"playlist_load_failed"})}}resetPlaylist(){const t=bt();t.manifest&&t.goToStep(t.manifest.startStep)}isInitialized(){return!!bt().config}resetManagers(){this.managers.videoManager.reset(),this.managers.cursorManager.reset(),this.managers.interactionManager.reset(),this.managers.transitionManager.reset(),this.managers.uiManager.reset(),this.managers.stepTimeoutManager.reset()}destroy(){}}class Nt{constructor(t){e(this,"managers"),e(this,"destroyCallback",null),e(this,"cursorAnimationListener",null),e(this,"cursorAnimationVideoElement",null),e(this,"cursorAnimationStepId",null),this.managers=t}setDestroyCallback(t){this.destroyCallback=t}registerStateMachineActions(){bt().registerStateMachineActions({startVideoPlayback:t=>{this.handleStartVideoPlayback(t)},pauseVideoPlayback:()=>{this.handlePauseVideoPlayback()},startMutedLoopedVideo:()=>{this.handleStartMutedLoopedVideo()},startIdleModeVideo:t=>{this.handleStartIdleModeVideo(t)},trackPlaylistComplete:()=>{this.handleTrackPlaylistComplete()},handleError:t=>{this.handleError(t)},hideError:()=>{this.handleHideError()},showLoadingState:()=>{this.handleShowLoadingState()},hideLoadingState:()=>{this.handleHideLoadingState()},hideVideoControls:()=>{this.handleHideVideoControls()},showVideoControls:()=>{this.handleShowVideoControls()},showPlayButton:()=>{this.handleShowPlayButton()},hidePlayButton:()=>{this.handleHidePlayButton()},enablePlayButtonProminent:()=>{this.handleEnablePlayButtonProminent()},disablePlayButtonProminent:()=>{this.handleDisablePlayButtonProminent()},enterCompactMode:()=>{this.handleEnterCompactMode()},exitCompactMode:()=>{this.handleExitCompactMode()},triggerPlaylistDismissed:()=>{this.handleTriggerPlaylistDismissed()},scheduleDestroy:()=>{this.handleScheduleDestroy()}})}getVideoUrl(t){var e;const n=null==(e=bt().userData)?void 0:e.language;let i;if(n&&t.translations&&t.translations[n]){i=t.translations[n].videoUrl}else i=t.compressedUrl||t.videoUrl;return i&&""!==i.trim()||!t.audioUrl||""===t.audioUrl.trim()?i:(t.id,t.audioUrl)}isUsingAudioFallback(t){var e;const n=null==(e=bt().userData)?void 0:e.language;let i;return i=n&&t.translations&&t.translations[n]?t.translations[n].videoUrl:t.compressedUrl||t.videoUrl,!(i&&""!==i.trim()||!t.audioUrl||""===t.audioUrl.trim())}findNextVideoUrl(t){const e=bt();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}destroy(){this.cleanupCursorAnimationListener()}cleanupCursorAnimationListener(t){t&&this.cursorAnimationStepId&&t!==this.cursorAnimationStepId?this.cursorAnimationStepId:this.cursorAnimationListener&&this.cursorAnimationVideoElement&&(this.cursorAnimationVideoElement.removeEventListener("timeupdate",this.cursorAnimationListener),this.cursorAnimationListener=null,this.cursorAnimationVideoElement=null,this.cursorAnimationStepId=null)}scheduleCursorAnimation(t,e){this.cleanupCursorAnimationListener();let n=t.showAtSeconds??0;if("number"==typeof n&&isFinite(n)||(n=0),n<0&&(n=0),n<=0)this.managers.cursorManager.animate(t);else{const i=this.managers.videoManager.getVideoElement();if(!i)return;let s=!1,r=!1;const a=()=>{if(s)return;const e=i.currentTime,a=i.duration;if(a&&!isNaN(a)&&n>a&&!r)return r=!0,s=!0,this.cleanupCursorAnimationListener(),void this.managers.cursorManager.animate(t);e>=n&&(s=!0,this.cleanupCursorAnimationListener(),this.managers.cursorManager.animate(t))},o=()=>{if(!s){const n=bt();if(n.currentStepId!==e)return n.currentStepId,void this.cleanupCursorAnimationListener(e);i.duration,s=!0,this.managers.cursorManager.animate(t),this.cleanupCursorAnimationListener()}};this.cursorAnimationListener=()=>{a()},this.cursorAnimationVideoElement=i,this.cursorAnimationStepId=e,i.addEventListener("timeupdate",this.cursorAnimationListener),i.addEventListener("ended",o,{once:!0})}}async validateStepUrlRequirement(t){if(!t.urlRequirement)return!0;t.id,this.managers.transitionManager.startStateMachineValidation();try{const e=await async function(t,e=20,n=100){if(!t)return!0;for(let i=0;i<e;i++){if(Vt(t))return!0;if(i<e-1&&(await new Promise((t=>setTimeout(t,n))),!window._saltfishPlayer))return!1}return t.pattern,t.matchType,!1}(t.urlRequirement);if(!e){t.id;const e=window._saltfishPlayer;e&&"function"==typeof e.destroy&&e.destroy()}return e}finally{this.managers.transitionManager.endStateMachineValidation()}}async handleStartVideoPlayback(t){if(!t.currentStep)return;const e=t.currentStep;if(e.urlRequirement){e.id;if(!(await this.validateStepUrlRequirement(e)))return}this.managers.uiManager.updatePosition(),this.managers.uiManager.showPlayer();const n=this.getVideoUrl(e),i=this.isUsingAudioFallback(e);if(i){const t=bt().manifest,n=e.gifUrl,i=null==t?void 0:t.avatarThumbnailUrl;this.managers.videoManager.showAudioFallbackOverlay(n,i)}else this.managers.videoManager.hideAudioFallbackOverlay();try{this.managers.interactionManager.clearButtons(),e.buttons&&this.managers.interactionManager.createButtons(e.buttons),e.cursorAnimations&&e.cursorAnimations.length;const t=e.buttons&&e.buttons.length>0||e.transitions.some((t=>"dom-click"===t.type||"url-path"===t.type||"dom-element-visible"===t.type)),s=t?"manual":"auto";t&&this.managers.transitionManager.setupTransitions(e,!1,!0),this.managers.videoManager.setCompletionPolicy(s,(()=>{var n;const i=bt();if(t){const t=e.transitions.find((t=>"timeout"===t.type)),s=null==(n=e.buttons)?void 0:n.some((t=>"goto"===t.action.type||"next"===t.action.type));if(t&&!s){const n=t.timeout||0;t.nextStep,setTimeout((()=>{var n;const i=bt();i.currentStepId!==e.id||"waitingForInteraction"!==i.currentState&&"playing"!==i.currentState?i.currentState:(t.nextStep,null==(n=i.goToStep)||n.call(i,t.nextStep))}),n),i.sendStateMachineEvent({type:"VIDEO_FINISHED_WAIT",step:e})}else i.sendStateMachineEvent({type:"VIDEO_FINISHED_WAIT",step:e})}else{const t=e.transitions.find((t=>"timeout"===t.type));t&&t.timeout&&t.timeout>0?(t.timeout