UNPKG

saltfish

Version:

An interactive video-guided tour system for web applications

6 lines 273 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={};var i=Symbol.for("immer-nothing"),s=Symbol.for("immer-draftable"),r=Symbol.for("immer-state");function a(t,...e){throw new Error(`[Immer] minified error nr: ${t}. Full error at: https://bit.ly/3cXEKWf`)}var o=Object.getPrototypeOf;function l(t){return!!t&&!!t[r]}function c(t){var e;return!!t&&(h(t)||Array.isArray(t)||!!t[s]||!!(null==(e=t.constructor)?void 0:e[s])||f(t)||y(t))}var d=Object.prototype.constructor.toString();function h(t){if(!t||"object"!=typeof t)return!1;const e=o(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)===d}function u(t,e){0===p(t)?Reflect.ownKeys(t).forEach((n=>{e(n,t[n],t)})):t.forEach(((n,i)=>e(i,n,t)))}function p(t){const e=t[r];return e?e.type_:Array.isArray(t)?1:f(t)?2:y(t)?3:0}function m(t,e){return 2===p(t)?t.has(e):Object.prototype.hasOwnProperty.call(t,e)}function g(t,e,n){const i=p(t);2===i?t.set(e,n):3===i?t.add(n):t[e]=n}function f(t){return t instanceof Map}function y(t){return t instanceof Set}function v(t){return t.copy_||t.base_}function b(t,e){if(f(t))return new Map(t);if(y(t))return new Set(t);if(Array.isArray(t))return Array.prototype.slice.call(t);const n=h(t);if(!0===e||"class_only"===e&&!n){const e=Object.getOwnPropertyDescriptors(t);delete e[r];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(o(t),e)}{const e=o(t);if(null!==e&&n)return{...t};const i=Object.create(e);return Object.assign(i,t)}}function w(t,e=!1){return E(t)||l(t)||!c(t)||(p(t)>1&&(t.set=t.add=t.clear=t.delete=S),Object.freeze(t),e&&Object.entries(t).forEach((([t,e])=>w(e,!0)))),t}function S(){a(2)}function E(t){return Object.isFrozen(t)}var M,x={};function I(t){const e=x[t];return e||a(0),e}function P(){return M}function C(t,e){e&&(I("Patches"),t.patches_=[],t.inversePatches_=[],t.patchListener_=e)}function _(t){k(t),t.drafts_.forEach(A),t.drafts_=null}function k(t){t===M&&(M=t.parent_)}function T(t){return M={drafts_:[],parent_:M,immer_:t,canAutoFreeze_:!0,unfinalizedDrafts_:0}}function A(t){const e=t[r];0===e.type_||1===e.type_?e.revoke_():e.revoked_=!0}function z(t,e){e.unfinalizedDrafts_=e.drafts_.length;const n=e.drafts_[0];return void 0!==t&&t!==n?(n[r].modified_&&(_(e),a(4)),c(t)&&(t=L(e,t),e.parent_||O(e,t)),e.patches_&&I("Patches").generateReplacementPatches_(n[r].base_,t,e.patches_,e.inversePatches_)):t=L(e,n,[]),_(e),e.patches_&&e.patchListener_(e.patches_,e.inversePatches_),t!==i?t:void 0}function L(t,e,n){if(E(e))return e;const i=e[r];if(!i)return u(e,((s,r)=>V(t,i,e,s,r,n))),e;if(i.scope_!==t)return e;if(!i.modified_)return O(t,i.base_,!0),i.base_;if(!i.finalized_){i.finalized_=!0,i.scope_.unfinalizedDrafts_--;const e=i.copy_;let s=e,r=!1;3===i.type_&&(s=new Set(e),e.clear(),r=!0),u(s,((s,a)=>V(t,i,e,s,a,n,r))),O(t,e,!1),n&&t.patches_&&I("Patches").generatePatches_(i,n,t.patches_,t.inversePatches_)}return i.copy_}function V(t,e,n,i,s,r,a){if(l(s)){const a=L(t,s,r&&e&&3!==e.type_&&!m(e.assigned_,i)?r.concat(i):void 0);if(g(n,i,a),!l(a))return;t.canAutoFreeze_=!1}else a&&n.add(s);if(c(s)&&!E(s)){if(!t.immer_.autoFreeze_&&t.unfinalizedDrafts_<1)return;L(t,s),e&&e.scope_.parent_||"symbol"==typeof i||!Object.prototype.propertyIsEnumerable.call(n,i)||O(t,s)}}function O(t,e,n=!1){!t.parent_&&t.immer_.autoFreeze_&&t.canAutoFreeze_&&w(e,n)}var D={get(t,e){if(e===r)return t;const n=v(t);if(!m(n,e))return function(t,e,n){var i;const s=U(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_||!c(i)?i:i===B(t.base_,e)?(R(t),t.copy_[e]=H(i,t)):i},has:(t,e)=>e in v(t),ownKeys:t=>Reflect.ownKeys(v(t)),set(t,e,n){const i=U(v(t),e);if(null==i?void 0:i.set)return i.set.call(t.draft_,n),!0;if(!t.modified_){const i=B(v(t),e),o=null==i?void 0:i[r];if(o&&o.base_===n)return t.copy_[e]=n,t.assigned_[e]=!1,!0;if(((s=n)===(a=i)?0!==s||1/s==1/a:s!=s&&a!=a)&&(void 0!==n||m(t.base_,e)))return!0;R(t),N(t)}var s,a;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!==B(t.base_,e)||e in t.base_?(t.assigned_[e]=!1,R(t),N(t)):delete t.assigned_[e],t.copy_&&delete t.copy_[e],!0),getOwnPropertyDescriptor(t,e){const n=v(t),i=Reflect.getOwnPropertyDescriptor(n,e);return i?{writable:!0,configurable:1!==t.type_||"length"!==e,enumerable:i.enumerable,value:n[e]}:i},defineProperty(){a(11)},getPrototypeOf:t=>o(t.base_),setPrototypeOf(){a(12)}},F={};function B(t,e){const n=t[r];return(n?v(n):t)[e]}function U(t,e){if(!(e in t))return;let n=o(t);for(;n;){const t=Object.getOwnPropertyDescriptor(n,e);if(t)return t;n=o(n)}}function N(t){t.modified_||(t.modified_=!0,t.parent_&&N(t.parent_))}function R(t){t.copy_||(t.copy_=b(t.base_,t.scope_.immer_.useStrictShallowCopy_))}function H(t,e){const n=f(t)?I("MapSet").proxyMap_(t,e):y(t)?I("MapSet").proxySet_(t,e):function(t,e){const n=Array.isArray(t),i={type_:n?1:0,scope_:e?e.scope_:P(),modified_:!1,finalized_:!1,assigned_:{},parent_:e,base_:t,draft_:null,copy_:null,revoke_:null,isManual_:!1};let s=i,r=D;n&&(s=[i],r=F);const{revoke:a,proxy:o}=Proxy.revocable(s,r);return i.draft_=o,i.revoke_=a,o}(t,e);return(e?e.scope_:P()).drafts_.push(n),n}function $(t){if(!c(t)||E(t))return t;const e=t[r];let n;if(e){if(!e.modified_)return e.base_;e.finalized_=!0,n=b(t,e.scope_.immer_.useStrictShallowCopy_)}else n=b(t,!0);return u(n,((t,e)=>{g(n,t,$(e))})),e&&(e.finalized_=!1),n}u(D,((t,e)=>{F[t]=function(){return arguments[0]=arguments[0][0],e.apply(this,arguments)}})),F.deleteProperty=function(t,e){return F.set.call(this,t,e,void 0)},F.set=function(t,e,n){return D.set.call(this,t[0],e,n,t[0])};var Y=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 s;if("function"!=typeof e&&a(6),void 0!==n&&"function"!=typeof n&&a(7),c(t)){const i=T(this),r=H(t,void 0);let a=!0;try{s=e(r),a=!1}finally{a?_(i):k(i)}return C(i,n),z(s,i)}if(!t||"object"!=typeof t){if(s=e(t),void 0===s&&(s=t),s===i&&(s=void 0),this.autoFreeze_&&w(s,!0),n){const e=[],i=[];I("Patches").generateReplacementPatches_(t,s,e,i),n(e,i)}return s}a(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){c(t)||a(8),l(t)&&(t=function(t){return l(t)||a(10),$(t)}(t));const e=T(this),n=H(t,void 0);return n[r].isManual_=!0,k(e),n}finishDraft(t,e){const n=t&&t[r];n&&n.isManual_||a(9);const{scope_:i}=n;return C(i,e),z(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=I("Patches").applyPatches_;return l(t)?i(t,e):this.produce(t,(t=>i(t,e)))}},X=Y.produce;Y.produceWithPatches.bind(Y),Y.setAutoFreeze.bind(Y),Y.setUseStrictShallowCopy.bind(Y),Y.applyPatches.bind(Y),Y.createDraft.bind(Y),Y.finishDraft.bind(Y);function W(t,e){void 0!==e?console.info(t,e):console.info(t)}function j(t,e){console.warn(t)}function q(t,e){void 0!==e?console.error(t,e):console.error(t)}class Z{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_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 G={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"]}}},K="saltfish_progress",J="saltfish_session",Q="saltfish_anonymous_user_data",tt="saltfish_pending_navigation",et="sf-player--minimized",nt="sf-error-display--visible",it="sf-error-display__message",st=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(t){}}return!1}}safeClearItem(t){if(this.isLocalStorageAvailable)try{localStorage.removeItem(t)}catch(t){}}clearOldData(){this.safeClearItem(J)}getProgress(t){const e=this.safeGetItem(K);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(K,n)}clearProgress(){this.safeClearItem(K)}getSession(){return this.safeGetItem(J)}setSession(t){return this.safeSetItem(J,t)}clearSession(){this.safeClearItem(J)}getAnonymousUserData(){return this.safeGetItem(Q)}setAnonymousUserData(t){return this.safeSetItem(Q,t)}clearAnonymousUserData(){this.safeClearItem(Q)}getPendingNavigation(){return this.safeGetItem(tt)}setPendingNavigation(t){return t.nextStepId,t.urlPattern,this.safeSetItem(tt,t)}clearPendingNavigation(){this.safeClearItem(tt)}clearAll(){this.clearProgress(),this.clearSession(),this.clearAnonymousUserData(),this.clearPendingNavigation()}};e(st,"instance",null);let rt=st;const at=rt.getInstance(),ot=(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})((t=>(e,n,i)=>(i.setState=(t,n,...i)=>{const s="function"==typeof t?X(t):t;return e(s,n,...i)},t(i.setState,n,i)))(((t,e)=>{let n=new Z(G,{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;if(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()},(null==(a=t.playlistOptions)?void 0:a.persistence)??1){const e=null==(o=t.user)?void 0:o.id;at.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 Z(G,{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 Z(G,{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;if(t.currentState=i({type:"COMPLETE_PLAYLIST_WAITING_FOR_INTERACTION"}),t.progress[e]={...t.progress[e],lastStepId:n,lastVisited:(new Date).toISOString(),completedWaitingForInteraction:!0},(null==(s=t.playlistOptions)?void 0:s.persistence)??1){const e=null==(r=t.user)?void 0:r.id;at.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 t of i){const e=s[t.id];e&&e.assigned||r.add(t.playlistId)}return n.filter((t=>!r.has(t.id)))}}}))),lt={getState:()=>ot.getState(),setState:ot.setState,subscribe:ot.subscribe,destroy:ot.destroy};function ct(){try{return lt.getState()}catch(t){throw new Error(`[storeUtils] Failed to access Saltfish store: ${t}`)}}function dt(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 ht(t,e=6e3){const n=dt(t);if(!n)return{isValid:!1,ageMs:null,timestampMs:null};const i=Date.now()-n;return{isValid:i<=e,ageMs:i,timestampMs:n}}class ut{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{ct().setError(t)}catch(t){console.error("Failed to update store with error:",t)}}static triggerErrorEvent(t,e,n){var i,s;try{const r=ct();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(ut,"DEFAULT_OPTIONS",{severity:"error",shouldLog:!0,shouldThrow:!1,shouldUpdateStore:!1,shouldTriggerEvent:!1,shouldDestroy:!1});class pt{detectShareIdFromUrl(){try{const t=window.location.href,e=/saltfish-share-id=([^&#]*)/,n=t.match(e);if(n&&n[1]){return n[1]}return null}catch(t){return null}}async fetchShareData(t){try{const e=await fetch(`https://studio-api.saltfish.ai/studio/flows2/share/${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 ut.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 mt=100;function gt(t){try{let e=t.replace(/[?&]saltfish-share-id=[^&#]*/g,((e,n)=>e.startsWith("?")&&t.substring(n+e.length).startsWith("&")?"?":""));return e=e.replace(/\?&/g,"?"),e=e.replace(/&&/g,"&"),e=e.replace(/\?$/g,""),e=e.replace(/&$/g,""),e}catch(e){return t}}function ft(t){const{pattern:e,matchType:n}=t;if(!e)return!0;const i=gt(window.location.href),s=window.location.pathname;if("regex"===n)try{const t=new RegExp(e),n=t.test(i),r=t.test(s);return n||r}catch(t){return!1}return"contains"===n?i.includes(e)||s.includes(e):i===e||s===e}class yt{constructor(t){e(this,"managers"),e(this,"userManagementService"),e(this,"playlistOrchestrator"),e(this,"shareLinkService"),e(this,"lastConfig",null),this.managers=t,this.shareLinkService=new pt}setUserManagementService(t){this.userManagementService=t}setPlaylistOrchestrator(t){this.playlistOrchestrator=t}getLastConfig(){return this.lastConfig}async initialize(t){var e;try{const n=await fetch("https://player.saltfish.ai/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 ut.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=ct();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 ut.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(t){throw ut.handleInitializationError(t,{component:"PlayerInitializationService",method:"initialize"})}}async fetchUserData(t,e){var n;try{const i=ct();if(!(null==(n=i.config)?void 0:n.token))return void ut.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)return await s.text(),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();if(!await this.checkAndResumeFromPendingNavigation()&&!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(e){ut.handleNetworkError(e,{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),ct().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(e){ut.handleNetworkError(e,{component:"PlayerInitializationService",method:"loadAnonymousUserData",userId:t})}}async checkAndResumeInProgressPlaylist(t){var e;if(!t)return!1;const n=ct(),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}=ht(e);return!!n}));if(r){const[t,e]=r;dt(e);try{if(this.playlistOrchestrator)return await this.playlistOrchestrator.startPlaylist(t),!0}catch(t){return!1}}return!1}async checkAndResumeFromPendingNavigation(){const t=this.managers.storageManager.getPendingNavigation();if(!t)return!1;if(Date.now()-t.timestamp>6e4)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(t){return!1}return!1}isURLPathMatch(t){if(!t||"undefined"==typeof window)return!1;const e=gt(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 vt(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()}class bt{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=vt(e.language);n={...e,language:t},e.language}this.lastUserIdentification={userId:t,userData:n};const i=ct();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=vt(t.language);e={...t,language:n},t.language}const n=this.playerInitializationService.getOrCreateAnonymousUserId();this.lastUserIdentification={userId:n,userData:e},ct().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=ct(),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(t){}}resolveUserDataLoaded(){this.userDataLoadedResolve&&(this.userDataLoadedResolve(),this.userDataLoadedResolve=null,this.userDataLoadedPromise=null)}destroy(){this.userDataLoadedPromise=null,this.userDataLoadedResolve=null,this.lastUserIdentification=null}}class wt{async validatePlaylistStart(t){const{playlistId:e,options:n,eventManager:i}=t;try{const t=ct();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 ut.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 ut.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)){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(t){const n=t instanceof Error?t.message:"Unknown validation error";return ut.handlePlaylistError(`Playlist validation failed: ${n}`,{component:"PlaylistValidator",method:"validatePlaylistStart",playlistId:e,additionalData:{error:t}}),{isValid:!1,error:n}}}async validateTriggerConditions(t,e,n){var i,s;const r=ct();if(!r.user)return ut.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=ct().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?(W(`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=ct();if(!s.user)return ut.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=ct().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}:(W(`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((()=>Ct));return i(n)?{isValid:!0}:(ut.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 ut.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),ct(),e()};t.on("userDataLoaded",s)}))}}class St{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 o=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(e){throw ut.handleInitializationError(`Failed to reinitialize player: ${e instanceof Error?e.message:"Unknown error"}`,{component:"PlaylistOrchestrator",method:"startPlaylist",playlistId:t,additionalData:{reinitError:e}})}}o&&(this.resetManagers(),this.managers.transitionManager.setTriggerManager(this.managers.triggerManager),this.stateMachineActionHandler&&this.stateMachineActionHandler.registerStateMachineActions());const l=ct();if(!l.config){if(!(null==(i=this.playerInitializationService)?void 0:i.getLastConfig()))throw ut.createError("Saltfish Player must be initialized at least once before starting a playlist",{component:"PlaylistOrchestrator",method:"startPlaylist",playlistId:t});throw ut.createError("Saltfish Player must be initialized before starting a playlist",{component:"PlaylistOrchestrator",method:"startPlaylist",playlistId:t})}l.manifest&&("playing"===l.currentState||"paused"===l.currentState||"loading"===l.currentState||"waitingForInteraction"===l.currentState||"autoplayBlocked"===l.currentState||"minimized"===l.currentState||"idleMode"===l.currentState)&&(this.managerOrchestrator&&this.managerOrchestrator.cleanupCurrentPlaylist(),l.resetForNewPlaylist(),this.stateMachineActionHandler&&this.stateMachineActionHandler.registerStateMachineActions()),"completed"!==l.currentState&&"closing"!==l.currentState||(l.currentState,l.resetForNewPlaylist(),this.stateMachineActionHandler&&this.stateMachineActionHandler.registerStateMachineActions()),this.managers.sessionManager.startNewRun(),this.managers.triggerManager.markPlaylistAsTriggered(t);const c=null==(s=this.userManagementService)?void 0:s.getUserDataLoadedPromise();if(c&&await c,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 d=new wt,h=await d.validatePlaylistStart({playlistId:t,options:e,eventManager:this.managers.eventManager});if(!h.isValid)return;e=h.updatedOptions||e;const u=h.manifestPath,p=e||{};p?(l.setPlaylistOptions(p),p.position||l.setPlaylistOptions({...p,position:"bottom-right"})):l.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(),l.sendStateMachineEvent({type:"LOAD_MANIFEST"});const m=null==e?void 0:e.persistence;if("undefined"!=typeof window){const e=null==(r=l.user)?void 0:r.id,n=this.managers.storageManager.getProgress(e);if(n&&n[t])l.loadPlaylistProgress(t,n[t]);else if(l.progress[t]){const e={...l.progress};delete e[t],lt.setState((t=>{t.progress=e}))}}this.managers.cursorManager.resetFirstAnimation(),await this.managers.playlistManager.load(u,{...p,persistence:m});const g=ct();if(g.manifest){const t=p.persistence??g.manifest.isPersistent??!0,e=g.playlistOptions||{};g.setPlaylistOptions({...e,...p,persistence:t})}if(p.startNodeId&&g.manifest&&(g.manifest.steps.find((t=>t.id===p.startNodeId))?g.goToStep(p.startNodeId):console.warn(`[PlaylistOrchestrator] startNodeId '${p.startNodeId}' not found in manifest steps. Starting from default step.`)),g.manifest){g.manifest.cursorColor&&this.managers.cursorManager.setColor(g.manifest.cursorColor),g.manifest.cursorLabel&&this.managers.cursorManager.setLabel(g.manifest.cursorLabel),p._triggeredByTriggerManager;const t=g.currentStepId===(null==(a=g.manifest.steps[0])?void 0:a.id);if(g.manifest.idleMode&&t){if(g.manifest.compactFirstStep){const t=this.managers.uiManager.getPlayerElement();null==t||t.classList.add("sf-player--compact"),g.manifest.compactLabel&&this.managers.uiManager.showCompactLabel(g.manifest.compactLabel)}l.setIdleMode()}else l.play()}else l.play();W(`Playlist started: ${t}${g.manifest?` (${g.manifest.name})`:""}`)}catch(e){this.managers.uiManager.hideLoading(),ct().sendStateMachineEvent({type:"ERROR",error:e instanceof Error?e:new Error(String(e))}),ut.handlePlaylistError(e,{component:"PlaylistOrchestrator",method:"startPlaylist",playlistId:t,errorType:"playlist_load_failed"})}}resetPlaylist(){const t=ct();t.manifest&&t.goToStep(t.manifest.startStep)}isInitialized(){return!!ct().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 Et{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(){ct().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=ct().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()?i:(t.id,t.audioUrl)}isUsingAudioFallback(t){var e;const n=null==(e=ct().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=ct();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=ct();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(ft(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,!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=ct().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=ct();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=ct();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,this.managers.transitionManager.setupTransitions(e,!1)):this.managers.transitionManager.setupTransitions(e,!0),e.transitions.some((t=>i.manifest.steps.some((e=>e.id===t.nextStep))))||i.sendStateMachineEvent({type:"COMPLETE_PLAYLIST"})}}));const r=()=>{var t,n;const i=ct(),s=(null==(t=i.manifest)?void 0:t.captions)??!0,r=null==(n=i.userData)?void 0:n.language;let a=e.tran