@pokedemo/player 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class e{listeners=new Map;on(e,t){let r=this.listeners.get(e);return r||(r=new Set,this.listeners.set(e,r)),r.add(t),()=>this.off(e,t)}once(e,t){const r=(...i)=>{this.off(e,r),t(...i)};return this.on(e,r)}off(e,t){const r=this.listeners.get(e);r&&(r.delete(t),0===r.size&&this.listeners.delete(e))}removeAllListeners(e){void 0!==e?this.listeners.delete(e):this.listeners.clear()}emit(e,...t){const r=this.listeners.get(e);if(r)for(const i of r)try{i(...t)}catch{}}}const t={maxRetries:2,baseDelayMs:500,retryableStatuses:[408,429,500,502,503,504]};class r{fetchFn;retry;constructor(e){this.fetchFn=e?.fetch??globalThis.fetch.bind(globalThis),this.retry={maxRetries:e?.retry?.maxRetries??t.maxRetries,baseDelayMs:e?.retry?.baseDelayMs??t.baseDelayMs,retryableStatuses:e?.retry?.retryableStatuses??t.retryableStatuses}}async fetch(e,t){let r=null;for(let s=0;s<=this.retry.maxRetries;s++){if(t?.signal?.aborted)throw new DOMException("The operation was aborted.","AbortError");try{const i=await this.fetchFn(e,t);if(i.ok||!this.retry.retryableStatuses.includes(i.status))return i;r=new Error(`HTTP ${i.status}`),s<this.retry.maxRetries&&await this.delay(s,t?.signal)}catch(i){if(i instanceof DOMException&&"AbortError"===i.name)throw i;r=i instanceof Error?i:new Error(String(i)),s<this.retry.maxRetries&&await this.delay(s,t?.signal)}}throw r??new Error("Fetch failed after retries")}delay(e,t){const r=this.retry.baseDelayMs*Math.pow(2,e),i=Math.random()*r*.5,s=Math.min(r+i,1e4);return new Promise((e,r)=>{if(t?.aborted)return void r(new DOMException("The operation was aborted.","AbortError"));const i=()=>{clearTimeout(a),t?.removeEventListener("abort",i),r(new DOMException("The operation was aborted.","AbortError"))},a=setTimeout(()=>{t?.removeEventListener("abort",i),e()},s);t?.addEventListener("abort",i,{once:!0})})}}let i=null;async function s(e,t){return new((await async function(){return i||(i=Promise.resolve().then(()=>require("./replay-D0qUB_uv.cjs"))),i}()).Replayer)(e,t)}function a(e,t){e.addEvent(t)}function o(e){try{e.pause(),"function"==typeof e.destroy&&e.destroy()}catch{}}function n(e,t,r){if(!e||!Number.isFinite(r))return null;try{const t=e;if("function"==typeof t.getMirror){const e=t.getMirror(),i=e?.getNode?.(r);if(i instanceof HTMLElement)return i}const i=t?.mirror?.getNode?.(r);if(i instanceof HTMLElement)return i}catch{}try{const e=t?.querySelector(".replayer-wrapper"),i=e?.querySelector("iframe");if(i instanceof HTMLIFrameElement&&i.contentDocument){const e=i.contentDocument.querySelector(`[data-rr-id="${r}"]`);if(e instanceof HTMLElement)return e}}catch{}return null}function l(e){if(!e.viewport)return!1;const t=e.viewport.querySelector("iframe");return!!t&&(t.setAttribute("sandbox",e.sandbox),t.setAttribute("referrerpolicy","no-referrer"),e.documentBaseUrl&&t.setAttribute("data-pokeplayer-document-base-url",e.documentBaseUrl),function(e,t){if(!t)return!1;try{const r=e.contentDocument;if(!r)return!1;const i=r.head||r.getElementsByTagName("head")[0];if(!i)return!1;let s=i.querySelector('base[data-pokeplayer-base="1"]');return s||(s=r.createElement("base"),s.setAttribute("data-pokeplayer-base","1"),i.prepend(s)),s.setAttribute("href",t),function(e){const t=e.head||e.getElementsByTagName("head")[0];if(!t)return;let r=t.querySelector('style[data-pokeplayer-replay-style="1"]');r||(r=e.createElement("style"),r.setAttribute("data-pokeplayer-replay-style","1"),t.appendChild(r));r.textContent="\nhtml, body {\n scroll-behavior: auto !important;\n}\n\n* {\n scroll-behavior: auto !important;\n}\n"}(r),!0}catch{return!1}}(t,e.documentBaseUrl))}function p(e){const t=e.querySelector(".replayer-wrapper");if(!t)return null;const r=e.getBoundingClientRect(),i=t.getBoundingClientRect(),s=t.offsetWidth||t.clientWidth||0,a=t.offsetHeight||t.clientHeight||0;return{scaleX:s>0?i.width/s:1,scaleY:a>0?i.height/a:1,offsetX:i.left-r.left,offsetY:i.top-r.top,containerRect:r,wrapperRect:i,naturalWidth:s,naturalHeight:a}}function c(e,t,r){return Math.min(r,Math.max(t,e))}const h="pokeplayer-step-overlay",d="pokeplayer-anywhere-overlay",u="pokeplayer-overlay-scrim",y="pokeplayer-overlay-hint",m="pokeplayer-modal-overlay",f={click:"pokeplayer-step-overlay--click",input:"pokeplayer-step-overlay--input",drag:"pokeplayer-step-overlay--drag",scroll:"pokeplayer-step-overlay--scroll",navigation:"pokeplayer-step-overlay--navigation",initial:"pokeplayer-step-overlay--initial"},g={cyan:"pokeplayer-step-overlay--click",purple:"pokeplayer-step-overlay--input",amber:"pokeplayer-step-overlay--drag",emerald:"pokeplayer-step-overlay--scroll",slate:"pokeplayer-step-overlay--initial"};function v(e){const t=e.trim().replace("#","");if(6!==t.length)return null;const r=Number.parseInt(t.slice(0,2),16),i=Number.parseInt(t.slice(2,4),16),s=Number.parseInt(t.slice(4,6),16);return Number.isNaN(r)||Number.isNaN(i)||Number.isNaN(s)?null:{r:r,g:i,b:s}}function b(e){if("string"!=typeof e)return null;const t=e.trim();return t.length>0?t:null}function w(e,t){if("number"==typeof t.opacity&&Number.isFinite(t.opacity)){const r=c(t.opacity,0,1);1!==r?(e.style.setProperty("--pokeplayer-modal-backdrop-spot",String(.75*r)),e.style.setProperty("--pokeplayer-modal-backdrop-base",String(.85*r))):(e.style.removeProperty("--pokeplayer-modal-backdrop-spot"),e.style.removeProperty("--pokeplayer-modal-backdrop-base"))}const r=b(t.cardColor);if(r){const t=r.startsWith("#")?v(r):null,i=t?`rgba(${t.r}, ${t.g}, ${t.b}, 0.92)`:r;e.style.setProperty("--pokeplayer-modal-card-bg",i)}else e.style.removeProperty("--pokeplayer-modal-card-bg");"black"===t.textColor?(e.style.setProperty("--pokeplayer-modal-text-color","#0b1220"),e.style.setProperty("--pokeplayer-modal-link-color","rgba(2, 6, 23, 0.82)"),e.style.setProperty("--pokeplayer-modal-message-color","rgba(2, 6, 23, 0.75)")):"white"===t.textColor?(e.style.setProperty("--pokeplayer-modal-text-color","#e2e8f0"),e.style.setProperty("--pokeplayer-modal-link-color","rgba(226, 232, 240, 0.85)"),e.style.setProperty("--pokeplayer-modal-message-color","rgba(226, 232, 240, 0.85)")):(e.style.removeProperty("--pokeplayer-modal-text-color"),e.style.removeProperty("--pokeplayer-modal-link-color"),e.style.removeProperty("--pokeplayer-modal-message-color"));const i=b(t.buttonColor);if(i){const t=i.startsWith("#")?v(i):null;if(e.style.setProperty("--pokeplayer-modal-button-bg",i),t){const r=function(e){const t=e=>{const t=e/255;return t<=.03928?t/12.92:Math.pow((t+.055)/1.055,2.4)};return.2126*t(e.r)+.7152*t(e.g)+.0722*t(e.b)}(t),i=r<.42?"#f8fafc":"#0b1220";e.style.setProperty("--pokeplayer-modal-button-color",i),e.style.setProperty("--pokeplayer-modal-button-hover-shadow",`0 12px 22px rgba(${t.r}, ${t.g}, ${t.b}, 0.25)`),e.style.setProperty("--pokeplayer-modal-link-color",`rgba(${t.r}, ${t.g}, ${t.b}, 0.9)`)}else e.style.removeProperty("--pokeplayer-modal-button-color"),e.style.removeProperty("--pokeplayer-modal-button-hover-shadow")}else e.style.removeProperty("--pokeplayer-modal-button-bg"),e.style.removeProperty("--pokeplayer-modal-button-color"),e.style.removeProperty("--pokeplayer-modal-button-hover-shadow")}function k(e){const t=e.isCircle?"50%":"8px",r=function(e,t){const r="string"==typeof t?t.trim():"",i=!/^#[0-9a-fA-F]{6}$/.test(r)&&["cyan","purple","amber","emerald","slate"].includes(r)?r:void 0;return i?g[i]:f[e]||f.click}(e.kind,e.highlightColor),i=document.createElement("div");i.className=`${h} ${r}`,i.style.cssText=`\n left: ${e.left-4}px;\n top: ${e.top-4}px;\n width: ${e.width+8}px;\n height: ${e.height+8}px;\n border-radius: ${t};\n `;const s=document.createElement("div");return s.className=`pokeplayer-step-overlay-pulse ${r}`,s.style.cssText=`\n left: ${e.left-8}px;\n top: ${e.top-8}px;\n width: ${e.width+16}px;\n height: ${e.height+16}px;\n border-radius: ${e.isCircle?"50%":"12px"};\n `,function(e,t,r){if(!function(e){return"string"==typeof e&&/^#[0-9a-fA-F]{6}$/.test(e.trim())}(r))return;const i=v(r);i&&(e.style.borderColor=`rgb(${i.r}, ${i.g}, ${i.b})`,e.style.background=`rgba(${i.r}, ${i.g}, ${i.b}, 0.1)`,e.style.boxShadow=`0 0 0 4px rgba(${i.r}, ${i.g}, ${i.b}, 0.15), 0 0 20px rgba(${i.r}, ${i.g}, ${i.b}, 0.2)`,t.style.borderColor=`rgba(${i.r}, ${i.g}, ${i.b}, 0.4)`)}(i,s,e.highlightColor),{overlay:i,pulseRing:s}}function x(e){const t=document.createElement("div");t.className=`${y} pokeplayer-overlay-hint--centered-below`;const r=document.createElement("span");if(r.className="pokeplayer-overlay-hint-text",r.textContent=e.instruction,t.appendChild(r),"scroll"===e.gesture){const e=document.createElement("span");e.className="pokeplayer-overlay-gesture pokeplayer-overlay-gesture--scroll";const r="http://www.w3.org/2000/svg",i=document.createElementNS(r,"svg");i.setAttribute("viewBox","0 0 24 24"),i.setAttribute("width","24"),i.setAttribute("height","24"),i.setAttribute("aria-hidden","true");const s=document.createElementNS(r,"g");s.setAttribute("fill","none"),s.setAttribute("stroke","currentColor"),s.setAttribute("stroke-width","2"),s.setAttribute("stroke-linecap","round"),s.setAttribute("stroke-linejoin","round");const a=document.createElementNS(r,"path");a.setAttribute("d","M12 5v14"),s.appendChild(a);const o=document.createElementNS(r,"path");o.setAttribute("d","M8 9l4-4 4 4"),s.appendChild(o);const n=document.createElementNS(r,"path");n.setAttribute("d","M8 15l4 4 4-4"),s.appendChild(n),i.appendChild(s);const l=document.createElement("span");l.className="pokeplayer-overlay-gesture-finger",e.appendChild(i),e.appendChild(l),t.appendChild(e)}const i=b(e.styleOpts?.hintCardColor);if(i){const e=i.startsWith("#")?v(i):null,r=e?`rgba(${e.r}, ${e.g}, ${e.b}, 0.92)`:i;t.style.setProperty("--pokeplayer-hint-bg",r)}else t.style.removeProperty("--pokeplayer-hint-bg");"black"===e.styleOpts?.hintTextColor?t.style.setProperty("--pokeplayer-hint-color","#0b1220"):"white"===e.styleOpts?.hintTextColor?t.style.setProperty("--pokeplayer-hint-color","#e2e8f0"):t.style.removeProperty("--pokeplayer-hint-color");const s=e.absolutePos;return s&&e.container&&(t.style.position="absolute",t.style.left="0px",t.style.top="0px",t.style.right="auto",t.style.bottom="auto",requestAnimationFrame(()=>{if(!t.isConnected||!e.container)return;const r=e.container.getBoundingClientRect(),i=r.width,a=r.height,o=12,n=t.offsetWidth||0,l=t.offsetHeight||0,p=Math.max(o,i-n-o),h=Math.max(o,a-l-o);t.style.left=`${c(s.left,o,p)}px`,t.style.top=`${c(s.top,o,h)}px`})),t}function S(e){const{options:t,preview:r,addClickHandler:i}=e,s=document.createElement("div");s.className=m,r&&s.classList.add(`${m}--preview`),w(s,{opacity:t.opacity,cardColor:t.cardColor,buttonColor:t.buttonColor,textColor:t.textColor}),!r&&t.allowBackdropClick&&s.classList.add(`${m}--clickable`);const a=document.createElement("div");a.className="pokeplayer-modal-card";const o=document.createElement("div");if(o.className="pokeplayer-modal-title",o.textContent=t.title,a.appendChild(o),t.message){const e=document.createElement("div");e.className="pokeplayer-modal-message",e.textContent=t.message,a.appendChild(e)}const n=document.createElement("div");if(n.className="pokeplayer-modal-actions",t.ctaLabel){const e=document.createElement("button");e.type="button",e.className="pokeplayer-modal-button",e.textContent=t.ctaLabel,r?e.disabled=!0:i(e,e=>{e.preventDefault(),e.stopPropagation(),t.onPrimary?.()}),n.appendChild(e)}if(t.replayLabel&&(r||t.onReplay)){const e=document.createElement("button");e.type="button",e.className="pokeplayer-modal-link",e.textContent=t.replayLabel,r?e.disabled=!0:i(e,e=>{e.preventDefault(),e.stopPropagation(),t.onReplay?.()}),n.appendChild(e)}return n.childElementCount>0&&a.appendChild(n),s.appendChild(a),!r&&t.allowBackdropClick&&i(s,()=>{t.onPrimary?.()}),s}function C(e){const t=e.getBoundingClientRect(),r=e.ownerDocument,i=r?.defaultView?.frameElement;if(!(i instanceof HTMLElement))return t;const s=i.getBoundingClientRect(),a=i.clientWidth||0,o=i.clientHeight||0,n=a>0?s.width/a:1,l=o>0?s.height/o:1;return new DOMRect(s.left+t.left*n,s.top+t.top*l,t.width*n,t.height*l)}class E{replayer=null;container=null;overlay=null;pulseRing=null;scrim=null;modal=null;boundHandlers=[];setReplayer(e){this.replayer=e}setContainer(e){this.container=e}showStart(e){this.showModal({...e,allowBackdropClick:!0})}showEnd(e){this.showModal({...e,allowBackdropClick:!1})}showPreviewStart(e){this.showPreviewModal(e)}showPreviewEnd(e){this.showPreviewModal(e)}hidePreview(){this.hide()}showStep(e,t){if(this.hide(),!this.container)return"anywhere";const r=this.showStepInternal(e,t);return this.enableScrollAdvance(t),r}hide(){this.clearHandlers(),this.removeNode(this.overlay),this.removeNode(this.pulseRing),this.removeNode(this.scrim),this.removeNode(this.modal),this.overlay=null,this.pulseRing=null,this.scrim=null,this.modal=null}destroy(){this.hide(),this.replayer=null,this.container=null}getRuntimeElements(){const e=this.scrim?.querySelector(`.${y}`),t=this.overlay?.classList.contains(d)??!1;return{stepOverlay:this.overlay?.classList.contains(h)??!1?this.overlay:null,stepOverlayPulse:this.pulseRing,overlayScrim:this.scrim,overlayHint:e,anywhereOverlay:t?this.overlay:null,modalOverlay:this.modal}}showStepInternal(e,t){if("scroll"===e.kind)return this.addHintScrim(t),"step";if(t.highlightRect&&this.showRectOverlay(t.highlightRect,e.kind,t))return"step";const r="number"==typeof e.nodeId&&this.replayer?this.findTargetElement(e.nodeId):null;return r?(this.showElementOverlay(r,e.kind,t),"step"):void 0!==e.fallbackX&&void 0!==e.fallbackY&&this.tryShowOverlayFromPoint(e.fallbackX,e.fallbackY,e.kind,t)?"step":t.instruction?(this.showHintOnlyAnywhere(t),"anywhere"):(this.showAnywhereOverlay(t),"anywhere")}showHintOnlyAnywhere(e){if(!this.container)return;this.scrim=document.createElement("div"),this.scrim.className=u;const t=this.resolveHintAbsolutePosition(e.hintPos),r=x({instruction:e.instruction??"Click to continue",styleOpts:{hintCardColor:e.hintCardColor,hintTextColor:e.hintTextColor},gesture:e.gesture,absolutePos:t,container:this.container});this.scrim.appendChild(r),this.addStepClickHandler(r,t=>{t.preventDefault(),t.stopPropagation(),e.onAnywhereClick()}),this.container.appendChild(this.scrim)}tryShowOverlayFromPoint(e,t,r,i){if(!this.container)return!1;const s=function(e,t,r){try{const i=e.querySelector(".replayer-wrapper"),s=i?.querySelector("iframe");if(!(s instanceof HTMLIFrameElement&&s.contentDocument))return null;const a=s.contentDocument.elementFromPoint(t,r);if(!(a instanceof HTMLElement))return null;let o=a;for(let e=0;e<8&&o;e++){const e=o.tagName?.toLowerCase?.()??"";if("html"!==e&&"body"!==e)break;o=o.parentElement}if(!o)return null;let n=o;for(let e=0;e<6&&n.parentElement;e++){const e=n.getBoundingClientRect();if(!(e.width<10||e.height<10))break;n=n.parentElement}return n}catch{return null}}(this.container,e,t);if(s)return this.showElementOverlay(s,r,i),!0;const a={x:e-40,y:t-24,w:80,h:48};return this.showRectOverlay(a,r,i)}findTargetElement(e){return n(this.replayer,this.container,e)}showModal(e){if(this.hide(),!this.container)return;const t=S({options:e,preview:!1,addClickHandler:(e,t)=>this.addClickHandler(e,t)});this.modal=t,this.container.appendChild(t)}showPreviewModal(e){if(this.hide(),!this.container)return;const t=S({options:{title:e.title,message:e.message,ctaLabel:e.ctaLabel,replayLabel:e.replayLabel,allowBackdropClick:!1,opacity:e.opacity,cardColor:e.cardColor,buttonColor:e.buttonColor,textColor:e.textColor},preview:!0,addClickHandler:(e,t)=>this.addClickHandler(e,t)});this.modal=t,this.container.appendChild(t)}showElementOverlay(e,t,r){if(!this.container)return;const i=C(e),s=this.container.getBoundingClientRect(),a=i.left-s.left,o=i.top-s.top,n=i.width,l=i.height;this.addHintScrim(r),this.createOverlays(a,o,n,l,t,!1,r.onTargetClick,r.highlightColor)}showRectOverlay(e,t,r){if(!this.container)return!1;const i=this.getTransformInfo();if(!i)return!1;const s=e.x*i.scaleX+i.offsetX,a=e.y*i.scaleY+i.offsetY,o=e.w*i.scaleX,n=e.h*i.scaleY;return!!(Number.isFinite(s)&&Number.isFinite(a)&&Number.isFinite(o)&&Number.isFinite(n))&&(!(o<=0||n<=0)&&(this.addHintScrim(r),this.createOverlays(s,a,o,n,t,!1,r.onTargetClick,r.highlightColor),!0))}showAnywhereOverlay(e){if(!this.container)return;const t=function(e){const t=document.createElement("div");t.className=d;const r=document.createElement("div");return r.className="pokeplayer-anywhere-message",r.textContent=e.anywhereInstruction??e.instruction??"Click to continue",t.appendChild(r),t}(e);this.addStepClickHandler(t,t=>{t.preventDefault(),t.stopPropagation(),e.onAnywhereClick()}),this.overlay=t,this.container.appendChild(t)}createOverlays(e,t,r,i,s,a,o,n){if(!this.container)return;const l=k({left:e,top:t,width:r,height:i,kind:s,isCircle:a,highlightColor:n});this.overlay=l.overlay,this.pulseRing=l.pulseRing,this.addStepClickHandler(this.overlay,e=>{e.preventDefault(),e.stopPropagation(),o()}),this.container.appendChild(this.pulseRing),this.container.appendChild(this.overlay)}resolveHintAbsolutePosition(e){if(!e||!this.container)return null;const t=this.getTransformInfo();if(!t)return null;const r=e.x*t.scaleX+t.offsetX,i=e.y*t.scaleY+t.offsetY;return Number.isFinite(r)&&Number.isFinite(i)?{left:r,top:i}:null}getTransformInfo(){if(!this.container)return null;const e=p(this.container);return e?{scaleX:e.scaleX,scaleY:e.scaleY,offsetX:e.offsetX,offsetY:e.offsetY}:null}addHintScrim(e){if(this.container){if(this.scrim=document.createElement("div"),this.scrim.className=u,e.instruction){const t=this.resolveHintAbsolutePosition(e.hintPos),r=x({instruction:e.instruction,styleOpts:{hintCardColor:e.hintCardColor,hintTextColor:e.hintTextColor},gesture:e.gesture,absolutePos:t,container:this.container});this.scrim.appendChild(r)}this.container.appendChild(this.scrim)}}addClickHandler(e,t){this.addHandler(e,"click",t)}addStepClickHandler(e,t){let r=!1;this.addHandler(e,"pointerdown",e=>{0===e.button&&(r=!0)},{passive:!0}),this.addHandler(e,"pointercancel",()=>{r=!1}),this.addClickHandler(e,e=>{const i=0===e.detail&&e.isTrusted;(r||i)&&(r=!1,t(e))})}addWheelHandler(e,t){this.addHandler(e,"wheel",t,{passive:!1})}addTouchMoveHandler(e,t){this.addHandler(e,"touchmove",t,{passive:!1})}addHandler(e,t,r,i){e.addEventListener(t,r,i),this.boundHandlers.push({element:e,type:t,handler:r,options:i})}clearHandlers(){for(const{element:e,type:t,handler:r,options:i}of this.boundHandlers)e.removeEventListener(t,r,i);this.boundHandlers=[]}enableScrollAdvance(e){if(!e.onScroll||!this.container)return;const t=Date.now();let r=0;const i=i=>{"preventDefault"in i&&i.preventDefault(),"stopPropagation"in i&&i.stopPropagation();const s=Date.now();if(!(s-t<140||s-r<220)){if(i instanceof WheelEvent){if(Math.abs(i.deltaX)+Math.abs(i.deltaY)<8)return}r=s,e.onScroll?.()}};this.addWheelHandler(this.container,i),this.addTouchMoveHandler(this.container,i)}removeNode(e){e?.parentNode&&e.parentNode.removeChild(e)}}class N{replayer=null;container=null;cursorEl=null;lastPos=null;setReplayer(e){this.replayer=e}setContainer(e){this.container=e}destroy(){this.hide(),this.cursorEl?.parentElement&&this.cursorEl.parentElement.removeChild(this.cursorEl),this.cursorEl=null,this.container=null,this.replayer=null,this.lastPos=null}hide(){this.cursorEl&&(this.cursorEl.style.opacity="0")}showForStep(e,t={}){if(!this.container)return;if("initial"===e.kind||0===e.stepIndex)return void this.hide();if("scroll"===e.kind)return void this.hide();const r=this.resolveCursorTarget(e);if(!r)return void this.hide();if(this.ensureMounted(),!this.cursorEl)return;const i=Boolean(t.animate&&this.lastPos);this.cursorEl.style.transition=i?"transform 260ms cubic-bezier(0.22, 1, 0.36, 1), opacity 160ms ease-out":"none",this.cursorEl.style.transform=`translate3d(${Math.round(r.x)}px, ${Math.round(r.y)}px, 0)`,this.cursorEl.style.opacity="1",this.lastPos={x:r.x,y:r.y}}ensureMounted(){if(!this.container)return;if(this.cursorEl&&this.cursorEl.isConnected)return;const e=document.createElement("div");e.className="pokeplayer-cursor",e.setAttribute("aria-hidden","true"),e.style.opacity="0",e.style.transform="translate3d(0px, 0px, 0)",this.container.appendChild(e),this.cursorEl=e}resolveCursorTarget(e){if(!this.container)return null;const t=this.container.getBoundingClientRect(),r=t.width,i=t.height;if(!Number.isFinite(r)||!Number.isFinite(i)||r<=0||i<=0)return null;const s=this.resolveElementRect(e);if(s){const e=s.left-t.left,a=4,o=s.right-t.left+a,n=o+18<=r-2?o:e-a-18,l=s.top-t.top+Math.min(10,Math.max(2,s.height/2));return{x:c(n,2,Math.max(2,r-18-2)),y:c(l,2,Math.max(2,i-26-2))}}const a=e.targetX,o=e.targetY;if("number"==typeof a&&"number"==typeof o&&Number.isFinite(a)&&Number.isFinite(o)){if(0===a&&0===o)return null;const e=this.mapReplayCoordinatesToContainer(a,o);return e?{x:c(e.x+6,2,Math.max(2,r-18-2)),y:c(e.y+2,2,Math.max(2,i-26-2))}:null}return null}resolveElementRect(e){if(!this.container||!this.replayer)return null;if("number"!=typeof e.targetNodeId||!Number.isFinite(e.targetNodeId))return null;const t=n(this.replayer,this.container,e.targetNodeId);return t?C(t):null}mapReplayCoordinatesToContainer(e,t){if(!this.container)return null;const r=p(this.container);return r?{x:e*r.scaleX+r.offsetX,y:t*r.scaleY+r.offsetY}:null}}const M="data-pokedemo-player-styles";let I=0;function P(){return"undefined"!=typeof document&&!!document.head}function L(){return P()?document.head.querySelector(`style[${M}="1"]`):null}function T(){I+=1,function(){if(!P())return;if(L())return;const e=document.createElement("style");e.setAttribute(M,"1"),e.textContent='.pokeplayer-host{width:100%}.pokeplayer-shell{position:relative;border:var(--pokeplayer-shell-border, 1px solid #e4e7ec);border-radius:16px;overflow:hidden;box-shadow:var(--pokeplayer-shell-shadow, 0 15px 50px rgba(15, 23, 42, .08));background:var( --pokeplayer-shell-bg, radial-gradient(circle at 10% 20%, #f8fafc, #f1f5f9 50%, #e2e8f0) );display:flex;flex-direction:column;gap:0}.pokeplayer-progress{position:absolute;left:0;right:0;top:0;height:4px;background:var(--pokeplayer-progress-bg, linear-gradient(90deg, #22d3ee, #6366f1));transform-origin:left center;transform:scaleX(0);opacity:.85;transition:transform .25s ease-out;pointer-events:none;z-index:2}.pokeplayer-bar{display:flex;align-items:center;gap:12px;padding:12px 16px;background:var(--pokeplayer-bar-bg, linear-gradient(90deg, #0f172a, #111827));color:var(--pokeplayer-bar-color, #e2e8f0);border-bottom:var(--pokeplayer-bar-border, 1px solid rgba(255, 255, 255, .08))}.pokeplayer-bar__controls{display:inline-flex;align-items:center;gap:8px}.pokeplayer-bar__controls .dot{width:10px;height:10px;border-radius:50%;display:inline-block;box-shadow:var(--pokeplayer-controls-shadow, 0 0 0 1px rgba(15, 23, 42, .4))}.pokeplayer-bar__controls .red{background:var(--pokeplayer-control-red, #f87171)}.pokeplayer-bar__controls .amber{background:var(--pokeplayer-control-amber, #fbbf24)}.pokeplayer-bar__controls .green{background:var(--pokeplayer-control-green, #34d399)}.pokeplayer-bar__address{flex:1;max-width:480px;padding:6px 12px;border-radius:10px;background:var(--pokeplayer-address-bg, rgba(255, 255, 255, .08));border:var(--pokeplayer-address-border, 1px solid rgba(255, 255, 255, .1));font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:12px;color:var(--pokeplayer-address-color, #e5e7eb);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pokeplayer-viewport{position:relative;background:var(--pokeplayer-viewport-bg, #0b1220);width:100%;aspect-ratio:var(--pokeplayer-aspect-ratio, 16 / 9);min-height:420px;overflow:hidden;overscroll-behavior:contain;display:flex;align-items:center;justify-content:center}.pokeplayer-loader{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:var( --pokeplayer-loader-bg, radial-gradient(ellipse at 50% 30%, rgba(15, 23, 42, .85), rgba(2, 6, 23, .95)) );backdrop-filter:blur(6px);transition:opacity .2s ease,visibility .2s ease;opacity:1;visibility:visible;z-index:3;pointer-events:all;animation:pokeplayer-loader-fade-in .2s ease-out}.pokeplayer-loader.hidden{opacity:0;visibility:hidden;pointer-events:none}.pokeplayer-loader__content{display:flex;flex-direction:column;align-items:center;gap:12px;padding:20px 28px;border-radius:16px;background:var(--pokeplayer-loader-card-bg, rgba(15, 23, 42, .8));border:var(--pokeplayer-loader-card-border, 1px solid rgba(56, 189, 248, .15));box-shadow:var( --pokeplayer-loader-card-shadow, 0 8px 32px rgba(0, 0, 0, .4), 0 0 0 1px rgba(255, 255, 255, .05) inset )}.pokeplayer-loader__spinner{width:36px;height:36px;border-radius:50%;border:3px solid var(--pokeplayer-loader-spinner-track, rgba(56, 189, 248, .15));border-top-color:var(--pokeplayer-loader-spinner, #38bdf8);box-shadow:0 0 20px #38bdf84d;animation:pokeplayer-spin .9s linear infinite}.pokeplayer-loader__label{font-weight:600;color:var(--pokeplayer-loader-label, #e2e8f0);letter-spacing:.02em;font-size:14px}@keyframes pokeplayer-loader-fade-in{0%{opacity:0}to{opacity:1}}.replayer-wrapper{position:absolute;transform-origin:center center}.replayer-wrapper iframe{border:none;display:block}.replayer-mouse{display:none!important;position:absolute;width:20px;height:20px;transition:left .05s linear,top .05s linear;background-size:contain;background-position:50%;background-repeat:no-repeat;background-image:url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgd2lkdGg9IjMwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBkYXRhLW5hbWU9IkxheWVyIDEiIHZpZXdCb3g9IjAgMCA1MCA1MCI+PHBhdGggZD0iTTQ4LjcxIDQyLjkxTDM0LjA4IDI4LjI5IDQ0LjMzIDE4YTEgMSAwIDAwLS4zMy0xLjYxTDIuMzUgMS4wNmExIDEgMCAwMC0xLjI5IDEuMjlMMTYuMzkgNDRhMSAxIDAgMDAxLjY1LjM2bDEwLjI1LTEwLjI4IDE0LjYyIDE0LjYzYTEgMSAwIDAwMS40MSAwbDQuMzgtNC4zOGExIDEgMCAwMC4wMS0xLjQyem0tNS4wOSAzLjY3TDI5IDMyYTEgMSAwIDAwLTEuNDEgMGwtOS44NSA5Ljg1TDMuNjkgMy42OWwzOC4xMiAxNEwzMiAyNy41OEExIDEgMCAwMDMyIDI5bDE0LjU5IDE0LjYyeiIvPjwvc3ZnPg==);border-color:transparent}.replayer-mouse:after{content:"";display:inline-block;width:20px;height:20px;background:#4950f6;border-radius:100%;transform:translate(-50%,-50%);opacity:.3}.replayer-mouse.active:after{animation:click .2s ease-in-out 1}.replayer-mouse-tail{display:none!important;position:absolute;pointer-events:none}.pokeplayer-cursor{position:absolute;left:0;top:0;width:18px;height:26px;background-size:18px 26px;background-repeat:no-repeat;background-position:0 0;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyOCIgdmlld0JveD0iMCAwIDIwIDI4Ij4KICA8cGF0aCBkPSJNMiAyLjVsNy4xIDIwLjUgMi4xLTYuNSA1LjkgNS45IDMuMS0zLjEtNS45LTUuOSA2LjUtMi4xTDIgMi41eiIgZmlsbD0iI2Y4ZmFmYyIgc3Ryb2tlPSIjMDIwNjE3IiBzdHJva2Utb3BhY2l0eT0iMC44NSIgc3Ryb2tlLXdpZHRoPSIxLjI1IiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPg==);filter:drop-shadow(0 10px 18px rgba(0,0,0,.45));z-index:10003;pointer-events:none}@keyframes pokeplayer-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes click{0%{opacity:.3;width:20px;height:20px}50%{opacity:.5;width:10px;height:10px}}.pokeplayer-error{color:#fecdd3;font-weight:600;display:flex;align-items:center;justify-content:center;height:100%;background:#450a0a}.pokeplayer-watermark-lock{position:absolute;inset:0;z-index:10050;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;padding:24px;pointer-events:all;background:repeating-linear-gradient(-28deg,#b91c1c33 0px 26px,#0f172ae6 26px 52px),#020617eb;backdrop-filter:blur(2px)}.pokeplayer-watermark-lock__banner{font-size:clamp(26px,5vw,56px);font-weight:900;letter-spacing:.2em;text-transform:uppercase;color:#fecaca;background:#7f1d1dcc;border:3px solid #ef4444;padding:14px 20px;text-align:center;box-shadow:0 0 0 3px #111827cc,0 10px 28px #00000073}.pokeplayer-watermark-lock__detail{margin:0;max-width:560px;text-align:center;color:#fee2e2;font-weight:700;line-height:1.45;letter-spacing:.02em}@keyframes pokeplayer-pulse{0%{transform:scale(1);opacity:.6}50%{transform:scale(1.08);opacity:.3}to{transform:scale(1.15);opacity:0}}.pokeplayer-step-overlay{position:absolute;z-index:10002;pointer-events:auto;cursor:pointer;box-sizing:border-box;border:2px solid #67e8f9;background:#67e8f91a;box-shadow:0 0 0 4px #67e8f926,0 0 20px #67e8f933;transition:background .15s ease,box-shadow .15s ease}.pokeplayer-step-overlay:hover{background:#67e8f933;box-shadow:0 0 0 6px #67e8f940,0 0 30px #67e8f94d}.pokeplayer-step-overlay-pulse{position:absolute;z-index:10001;pointer-events:none;box-sizing:border-box;border:2px solid rgba(103,232,249,.4);animation:pokeplayer-pulse 1.5s ease-out infinite}.pokeplayer-step-overlay--click{border-color:#67e8f9;background:#67e8f91a;box-shadow:0 0 0 4px #67e8f926,0 0 20px #67e8f933}.pokeplayer-step-overlay--click:hover{background:#67e8f933}.pokeplayer-step-overlay-pulse.pokeplayer-step-overlay--click{border-color:#67e8f966}.pokeplayer-step-overlay--input{border-color:#c4b5fd;background:#c4b5fd1a;box-shadow:0 0 0 4px #c4b5fd26,0 0 20px #c4b5fd33}.pokeplayer-step-overlay--input:hover{background:#c4b5fd33}.pokeplayer-step-overlay-pulse.pokeplayer-step-overlay--input{border-color:#c4b5fd66}.pokeplayer-step-overlay--drag{border-color:#fcd34d;background:#fcd34d1a;box-shadow:0 0 0 4px #fcd34d26,0 0 20px #fcd34d33}.pokeplayer-step-overlay--drag:hover{background:#fcd34d33}.pokeplayer-step-overlay-pulse.pokeplayer-step-overlay--drag{border-color:#fcd34d66}.pokeplayer-step-overlay--scroll{border-color:#6ee7b7;background:#6ee7b71a;box-shadow:0 0 0 4px #6ee7b726,0 0 20px #6ee7b733}.pokeplayer-step-overlay--scroll:hover{background:#6ee7b733}.pokeplayer-step-overlay-pulse.pokeplayer-step-overlay--scroll{border-color:#6ee7b766}.pokeplayer-step-overlay--navigation{border-color:#6ee7b7;background:#6ee7b71a;box-shadow:0 0 0 4px #6ee7b726,0 0 20px #6ee7b733}.pokeplayer-step-overlay--navigation:hover{background:#6ee7b733}.pokeplayer-step-overlay-pulse.pokeplayer-step-overlay--navigation{border-color:#6ee7b766}.pokeplayer-step-overlay--initial{border-color:#cbd5e1;background:#cbd5e11a;box-shadow:0 0 0 4px #cbd5e126,0 0 20px #cbd5e133}.pokeplayer-step-overlay--initial:hover{background:#cbd5e133}.pokeplayer-step-overlay-pulse.pokeplayer-step-overlay--initial{border-color:#cbd5e166}.pokeplayer-anywhere-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:#0206178c;cursor:pointer;z-index:10000;transition:background .15s ease}.pokeplayer-anywhere-overlay:hover{background:#0006}.pokeplayer-anywhere-message{padding:14px 28px;background:#0f172ad9;border-radius:12px;color:#e2e8f0;font-size:14px;font-weight:600;letter-spacing:.01em;box-shadow:0 8px 24px #00000059}.pokeplayer-overlay-scrim{position:absolute;inset:0;z-index:10000;background:#02061773;pointer-events:auto;display:flex;align-items:flex-end;justify-content:center;padding:18px}.pokeplayer-overlay-hint{display:inline-flex;align-items:center;justify-content:center;gap:10px;padding:10px 18px;border-radius:999px;background:var(--pokeplayer-hint-bg, rgba(15, 23, 42, .9));border:1px solid rgba(255,255,255,.08);color:var(--pokeplayer-hint-color, #e2e8f0);font-size:13px;font-weight:600;box-shadow:0 10px 24px #00000059;max-width:280px;text-align:center;word-wrap:break-word;overflow-wrap:break-word;white-space:normal;min-width:100px}.pokeplayer-overlay-hint-text{display:inline-block;line-height:1.25}.pokeplayer-overlay-gesture{position:relative;width:26px;height:26px;flex:0 0 auto;color:var(--pokeplayer-hint-color, #e2e8f0)}.pokeplayer-overlay-gesture svg{display:block;width:26px;height:26px;opacity:.9;animation:pokeplayer-gesture-arrow-pulse 1.6s ease-in-out infinite}.pokeplayer-overlay-gesture-finger{position:absolute;left:50%;top:50%;width:8px;height:8px;margin-left:-4px;margin-top:-4px;border-radius:999px;background:currentColor;box-shadow:0 0 0 4px #00000038;animation:pokeplayer-gesture-swipe 1.6s ease-in-out infinite}@keyframes pokeplayer-gesture-swipe{0%{transform:translateY(7px);opacity:.75}50%{transform:translateY(-7px);opacity:1}to{transform:translateY(7px);opacity:.75}}@keyframes pokeplayer-gesture-arrow-pulse{0%{opacity:.65}50%{opacity:1}to{opacity:.65}}.pokeplayer-modal-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:24px;background:radial-gradient(circle at 50% 30%,rgba(30,41,59,var(--pokeplayer-modal-backdrop-spot, .75)),rgba(2,6,23,var(--pokeplayer-modal-backdrop-base, .85)));backdrop-filter:blur(6px);z-index:10000}.pokeplayer-modal-overlay--clickable{cursor:pointer}.pokeplayer-modal-overlay--preview{cursor:default}.pokeplayer-modal-overlay--preview .pokeplayer-modal-button,.pokeplayer-modal-overlay--preview .pokeplayer-modal-link{pointer-events:none;opacity:.8}.pokeplayer-modal-card{width:min(420px,100%);padding:22px 24px;border-radius:18px;background:var(--pokeplayer-modal-card-bg, rgba(15, 23, 42, .92));border:1px solid rgba(255,255,255,.08);box-shadow:0 20px 50px #00000059;text-align:center;color:var(--pokeplayer-modal-text-color, #e2e8f0)}.pokeplayer-modal-title{font-size:20px;font-weight:700;margin-bottom:8px}.pokeplayer-modal-message{font-size:14px;line-height:1.5;color:var(--pokeplayer-modal-message-color, rgba(226, 232, 240, .85))}.pokeplayer-modal-actions{margin-top:18px;display:flex;flex-direction:column;gap:10px;align-items:center}.pokeplayer-modal-button{border:1px solid rgba(255,255,255,.12);background:var(--pokeplayer-modal-button-bg, linear-gradient(90deg, #22d3ee, #6366f1));color:var(--pokeplayer-modal-button-color, #0b1220);border-radius:12px;padding:10px 18px;font-weight:700;font-size:14px;cursor:pointer;transition:transform .08s ease,box-shadow .08s ease}.pokeplayer-modal-button:hover{transform:translateY(-1px);box-shadow:var(--pokeplayer-modal-button-hover-shadow, 0 12px 22px rgba(99, 102, 241, .25))}.pokeplayer-modal-button:active{transform:translateY(0);box-shadow:none}.pokeplayer-modal-link{border:none;background:none;color:var(--pokeplayer-modal-link-color, rgba(226, 232, 240, .85));font-weight:600;font-size:13px;cursor:pointer;text-decoration:underline}\n',document.head.appendChild(e)}()}function A(){I>0&&(I-=1),I>0||L()?.remove()}function O(e){return"object"==typeof e&&null!==e}function R(e){return"number"==typeof e&&Number.isFinite(e)}function F(e){return null==e||R(e)}function D(e){return null==e||"string"==typeof e}function B(e){return!!O(e)&&("string"==typeof e.locale&&"string"==typeof e.src)}function $(e){if(!O(e))return!1;if(!("string"==typeof e.pageId&&"string"==typeof e.pageKey&&"string"==typeof e.url&&D(e.title)&&D(e.referrer)&&D(e.userAgent)&&R(e.eventCount)&&F(e.firstEventTs)&&F(e.lastEventTs)))return!1;if(!O(e.viewport))return!1;const t=e.viewport;return F(t.width)&&F(t.height)&&F(t.devicePixelRatio)}function H(e){return!!O(e)&&(R(e.index)&&"string"==typeof e.src&&R(e.offset)&&R(e.limit)&&"string"==typeof e.labelKey&&"string"==typeof e.messageKey)}const z=2e5;function j(e){return"object"==typeof e&&null!==e}function W(e){if(e.length>z)throw new Error("Step blob exceeds event count limit (200000)");const t=[];for(let r=0;r<e.length;r++){const i=e[r];if(!j(i))throw new Error(`Step event ${r} is not an object`);const s=Number(i.type),a=Number(i.timestamp);if(!Number.isFinite(s)||!Number.isFinite(a))throw new Error(`Step event ${r} is missing required fields`);const o=j(i.data)?i.data:{},n=i.delay,l="number"==typeof n&&Number.isFinite(n)?n:void 0;t.push({type:s,timestamp:a,data:o,delay:l})}return t}function _(e){if(!e)return[];if(e&&"object"==typeof e&&Array.isArray(e.events))return _(e.events);if(Array.isArray(e)){if(e.length>0&&e.every(e=>e&&"object"==typeof e&&"payload"in e)){return W(e.map(e=>e.payload))}return W(e)}throw new Error("Events file is not a valid array")}async function Z(e){if(e.byteLength>20971520)throw new Error("Step blob exceeds compressed size limit");!function(){if("function"!=typeof DecompressionStream)throw new Error("PokePlayer requires browser gzip decompression support (DecompressionStream). Please use a modern evergreen browser.")}();const t=new Uint8Array(e.byteLength);t.set(e);const r=new Blob([t.buffer]).stream().pipeThrough(new DecompressionStream("gzip")).getReader(),i=[];let s=0;for(;;){const{done:e,value:t}=await r.read();if(e)break;if(!t||0===t.byteLength)continue;if(s+=t.byteLength,s>67108864)throw new Error("Step blob exceeds decompressed size limit");const a=new Uint8Array(t.byteLength);a.set(t),i.push(a)}const a=new Uint8Array(s);let o=0;for(const l of i)a.set(l,o),o+=l.byteLength;const n=(new TextDecoder).decode(a);return JSON.parse(n)}const U="pokedemo.com",Y=new Set(["localhost",U]),q=`.${U}`;function G(e){return"object"==typeof e&&null!==e}function X(e){return e.trim().toLowerCase()}function V(e){if(!G(e))return!1;const t=e.token;return"string"==typeof t&&t.trim().length>0&&t.includes(".")}class K extends Error{constructor(e="This demo was not authorized for preview outside PokeDemo. If you believe this is a mistake, please contact us at support@pokedemo.com"){super(e),this.name="WatermarkEnforcementError"}}function J(e){if(0!==e.stepIndex)return;const t=X(e.hostname??"");if(t&&!function(e){const t=X(e);return!!t&&(!!Y.has(t)||t.endsWith(q))}(t)&&function(e){for(const t of e){if(5!==t.type)continue;const e=t.data;if(G(e)&&"pd.preview-watermark"===e.tag&&V(e.payload))return!0}return!1}(e.events))throw new K}class Q{current;constructor(e="idle"){this.current=e}get(){return this.current}set(e){this.current=e}}function ee(e){const t=e.ui?.startOverlay;if(t)return{...t}}function te(e){const t=e.ui?.endOverlay;if(t)return{...t}}function re(e){const t=e.ui?.stepOverlay;if(t)return{...t}}function ie(e){if(!e)throw new Error("PokePlayer requires a `baseUrl` option");const t=e.startsWith("http://")||e.startsWith("https://")?e:new URL(e,function(){if("undefined"==typeof window||!window.location)throw new Error("PokePlayer requires a browser environment (window.location). ");return window.location.origin}()).href;return(r=t).endsWith("/")?r:`${r}/`;var r}function se(e){if("undefined"==typeof window||!window.location)return!1;try{return new URL(e).origin===window.location.origin}catch{return!1}}const ae="Start demo",oe="Click anywhere to begin.",ne="Start demo",le="Demo complete",pe="You have reached the end of this walkthrough.",ce="Finish",he="Replay demo",de=!0,ue="Click the highlighted element",ye="Click to continue";function me(e){if("string"!=typeof e)return;const t=e.trim();return t.length>0?t:void 0}function fe(e){if("string"!=typeof e)return;const t=e.trim();if(!t)return;const r=Number.parseFloat(t);if(!Number.isFinite(r))return;const i=r<1?r:r/100;return Math.min(1,Math.max(0,i))}function ge(e){if("string"!=typeof e)return;const t=e.trim();return"white"===t||"black"===t?t:void 0}function ve(e,t,r){const i=e(`${t}.opacity`),s=e(`${t}.cardColor`),a=e(`${t}.buttonColor`),o=e(`${t}.textColor`);return{opacity:r?.opacity??fe(i),cardColor:me(r?.cardColor??s),buttonColor:me(r?.buttonColor??a),textColor:r?.textColor??ge(o)}}function be(e,t){return Array.isArray(e.steps)&&0!==e.steps.length?e.steps.map((r,i)=>{let s;const a=r.highlightColorKey;if(a){const e=t(a);e&&(["cyan","purple","amber","emerald","slate"].includes(o=e)||/^#[0-9a-fA-F]{6}$/.test(o))&&(s=e)}var o;let n;s||(s=function(e){switch(e){case"click":return"cyan";case"input":return"purple";case"drag":return"amber";case"scroll":case"navigation":return"emerald";default:return"slate"}}(r.kind));const l=r.hintCardColorKey;if(l){const e=t(l),r="string"==typeof e?e.trim():"";/^#[0-9a-fA-F]{6}$/.test(r)&&(n=r)}let p="white";const c=r.hintTextColorKey;if(c){const e=ge(t(c));e&&(p=e)}const h=r.highlightRectKey??`steps.${i}.highlightRect`,d=function(e){if("string"!=typeof e)return;const t=e.trim();if(t)try{const e=JSON.parse(t),r=Number(e.x),i=Number(e.y),s=Number(e.w),a=Number(e.h);if(!(Number.isFinite(r)&&Number.isFinite(i)&&Number.isFinite(s)&&Number.isFinite(a)))return;if(s<=0||a<=0)return;return{x:r,y:i,w:s,h:a}}catch{return}}(t(h)),u=r.hintPosKey??`steps.${i}.hintPos`,y=function(e){if("string"!=typeof e)return;const t=e.trim();if(t)try{const e=JSON.parse(t),r=Number(e.x),i=Number(e.y);if(!Number.isFinite(r)||!Number.isFinite(i))return;return{x:r,y:i}}catch{return}}(t(u)),m=t(`steps.${i}.skip`),f="string"==typeof m&&"true"===m.trim().toLowerCase(),g=r.stepZoomEnabledKey??`steps.${i}.stepZoomEnabled`,v=t(g);let b;if("string"==typeof v){const e=v.trim().toLowerCase();"true"===e?b=!0:"false"===e&&(b=!1)}return{stepIndex:i,startTimeMs:r.startTimeMs??0,endTimeMs:r.endTimeMs??(e.durationMs||0),kind:r.kind??"unknown",label:t(`steps.${i}.label`)??void 0,instruction:t(`steps.${i}.instruction`)??void 0,targetNodeId:r.targetNodeId,targetX:r.targetX,targetY:r.targetY,highlightColor:s,hintCardColor:n,hintTextColor:p,highlightRect:d,hintPos:y,skip:f,stepZoomEnabled:b}}):[{stepIndex:0,startTimeMs:0,endTimeMs:e.durationMs||0,kind:"initial"}]}const we=new class{maxConcurrency;activeCount=0;queue=[];constructor(e){this.maxConcurrency=Math.max(1,e)}async acquire(e){if(e?.aborted)throw new DOMException("The operation was aborted.","AbortError");this.activeCount<this.maxConcurrency?this.activeCount++:await new Promise((t,r)=>{const i=()=>{const e=this.queue.indexOf(s);e>=0&&this.queue.splice(e,1),r(new DOMException("The operation was aborted.","AbortError"))},s=()=>{e?.removeEventListener("abort",i),this.activeCount++,t()};this.queue.push(s),e?.addEventListener("abort",i,{once:!0})})}release(){this.activeCount=Math.max(0,this.activeCount-1);const e=this.queue.shift();e&&e()}async run(e,t){await this.acquire(t);try{return await e()}finally{this.release()}}}(2);function ke(e,t){return we.run(e,t)}function xe(e){return"object"==typeof e&&null!==e}const Se=/^(?:\.\/)?assets\//i,Ce=/url\(['"]?([^'")\s]+)['"]?\)/gi,Ee=/@import\s+(?:url\()?['"]?([^'";)\s]+)['"]?\)?\s*;?/gi;function Ne(e,t){const r=e.trim();if(!Se.test(r))return e;try{return new URL(r,t).href}catch{return e}}function Me(e,t){return e.split(",").map(e=>e.trim()).filter(Boolean).map(e=>{const r=e.split(/\s+/).filter(Boolean);if(0===r.length)return e;const i=r[0]??"",s=Ne(i,t);return s===i?e:[s,...r.slice(1)].join(" ")}).join(", ")}function Ie(e,t){let r=e;return r=r.replace(Ee,(e,r)=>{const i=Ne(r,t);return i===r?e:e.replace(r,i)}),r=r.replace(Ce,(e,r)=>{const i=Ne(r,t);return i===r?e:e.replace(r,i)}),r}function Pe(e,t){if(!xe(e))return;const r="string"==typeof e.tagName?e.tagName.toLowerCase():"";"style"===r&&"string"==typeof e.textContent&&(e.textContent=Ie(e.textContent,t));const i=e.attributes;if(xe(i)){for(const e of["src","href","poster","data","xlink:href"]){const r=i[e];"string"==typeof r&&r.trim()&&(i[e]=Ne(r,t))}"string"==typeof i.srcset&&i.srcset.trim()&&(i.srcset=Me(i.srcset,t)),"string"==typeof i.style&&i.style.trim()&&(i.style=Ie(i.style,t))}const s=e.childNodes;if(Array.isArray(s)){if("style"===r)for(const e of s)xe(e)&&"string"==typeof e.textContent&&(e.textContent=Ie(e.textContent,t));for(const e of s)Pe(e,t)}const a=e.data;if(!xe(a))return;a.node&&Pe(a.node,t);const o=a.adds;if(Array.isArray(o))for(const l of o)xe(l)&&l.node&&Pe(l.node,t);const n=a.attributes;if(Array.isArray(n))for(const l of n){if(!xe(l))continue;const e=l.attributes;if(xe(e)){for(const r of["src","href","poster","data","xlink:href"]){const i=e[r];"string"==typeof i&&i.trim()&&(e[r]=Ne(i,t))}"string"==typeof e.srcset&&e.srcset.trim()&&(e.srcset=Me(e.srcset,t)),"string"==typeof e.style&&e.style.trim()&&(e.style=Ie(e.style,t))}}}function Le(e){for(;e.firstChild;)e.removeChild(e.firstChild)}function Te(){if("undefined"==typeof window||"function"!=typeof window.matchMedia)return!1;try{return window.matchMedia("(prefers-reduced-motion: reduce)").matches}catch{return!1}}class Ae extends e{host;options;hostClassTokens=[];fetchClient;prefetchWindow;stylesAttached=!1;viewport=null;addressEl=null;loaderEl=null;progressBar=null;replayer=null;loaded=null;i18n=null;currentStepIndex=0;accumulatedEvents=[];stepLoadStates=new Map;stepLoadPromises=new Map;stepLastEventTimestamps=new Map;prefetchAbortController=null;fitCleanup=null;resizeObserver=null;replayWrapper=null;replayNaturalWidth=0;replayNaturalHeight=0;replayFitScale=1;stepZoomActive=!1;stepZoomTarget=null;stepZoomOutSettlesAtMs=0;stepAdvanceNonce=0;stepAdvanceInProgress=!1;overlayInteractionNonce=0;overlayInteractionArmedNonce=0;stepNavigationNonce=0;overlayPauseLock=null;overlayPauseLockNonce=0;overlayPauseReasserting=!1;loadedThroughStep=-1;stepTimeBounds=[];isPrefetching=!1;stepEndTimeout=null;activeStepSegment=null;activeStepRunNonce=0;stepSegmentEndAtWallMs=0;pausedStepSegment=null;overlayManager=null;cursorManager=null;hasStarted=!1;hasFinished=!1;scrollGuardCleanup=null;replayIframePrepared=!1;replayBaseTimestampMs=null;replayCastWaiters=new Set;endOverlayTimeout=null;debugEnabled=this.resolveDebugEnabled();playbackSessionNonce=0;readySettled=!1;stateStore=new Q("idle");_speed=1;get _state(){return this.stateStore.get()}ready;experimental;resolveReady;rejectReady;settleReadySuccess(){this.readySettled||(this.readySettled=!0,this.resolveReady())}settleReadyError(e){this.readySettled||(this.readySettled=!0,this.rejectReady(e))}constructor(e,t){super(),this.host=e;const i=function(e){return{baseUrl:e.source.baseUrl,className:e.ui?.className,injectCss:e.ui?.injectCss,startOverlay:ee(e),endOverlay:te(e),stepOverlay:re(e),fetch:e.network?.fetch,prefetch:e.advanced?.prefetch,retry:e.advanced?.retry,runtimeHooks:!0===e.advanced?.runtimeHooks}}(t);this.options=i,this.applyStylesPreference(i.injectCss),this.fetchClient=new r({fetch:i.fetch,retry:i.retry}),this.prefetchWindow=i.prefetch?.window??1,this.host.classList.add("pokeplayer-host"),this.applyHostClassName(this.options.className),this.ready=new Promise((e,t)=>{this.resolveReady=e,this.rejectReady=t}),this.ready.catch(()=>{}),this.experimental={updateConfig:e=>this.updateConfigInternal(e),getStepBounds:()=>this.getStepBoundsInternal(),getRuntimeElements:()=>this.getRuntimeElementsInternal(),showPreviewOverlay:(e,t)=>this.showPreviewOverlayInternal(e,t),hidePreviewOverlay:()=>this.hidePreviewOverlayInternal(),refreshI18n:()=>this.refreshI18nInternal()},this.init()}static async create(e,t){const r=new Ae(e,t);return await r.ready,r}async start(){this.loaded||await this.ready,this.loaded&&!this.hasStarted&&await this.startInteractivePlayback()}async nextStep(){if(this.loaded||await this.ready,!this.loaded||0===this.stepTimeBounds.length)return;if(!this.hasStarted)return void(await this.startInteractivePlayback());const e=Math.min(this.currentStepIndex+1,this.stepTimeBounds.length-1);e!==this.currentStepIndex?await this.goToStep(e):this.handleFinish()}async goToStep(e){if(this.loaded||await this.ready,!this.loaded||0===this.stepTimeBounds.length)return;const t=this.beginStepNavigation(),r=Math.max(0,Math.min(e,this.stepTimeBounds.length-1));if(this.debugLog("go-to-step-begin",{requestedStepIndex:e,clampedStepIndex:r,navigationNonce:t,currentStepIndex:this.currentStepIndex}),0===r)return void this.restart();const i=this.stepTimeBounds[r];r>0&&(this.hasStarted||(this.hasStarted=!0,this.setState("playing"),this.emit("start")),this.hasFinished=!1),this.clearStepEndTimer(),this.cancelPendingStepAdvance(),this.invalidateOverlayInteractionGate(),this.clearOverlayPauseLock("go-to-step"),this.clearEndOverlayTimer(),this.overlayManager?.hide(),this.zoomOutFromStep();const s=r>this.loadedThroughStep;s&&this.showLoading();let a=!1;try{if(this.currentStepIndex=r,r>this.loadedThroughStep&&(await this.loadStepsThrough(r),!this.isStepNavigationActive(t)))return void this.debugLog("go-to-step-stale-after-load",{navigationNonce:t,currentNavigationNonce:this.stepNavigationNonce});if(!this.replayer)return;const e=this.getPreStepTimeMs(i);if(this.replayer.pause(e),this.updateProgress(),await Promise.all([this.waitForStepZoomOut(),this.waitForReplayPauseSettle(),this.waitForReplayCast()]),!this.isStepNavigationActive(t))return void this.debugLog("go-to-step-stale-before-overlay",{navigationNonce:t,currentNavigationNonce:this.stepNavigationNonce});this.isOverlayActionableStep(i)?(this.setState("paused"),this.lockOverlayPause(i,e),this.cursorManager?.showForStep(i,{animate:!0}),this.showStepOverlay(i,t)):(this.clearOverlayPauseLock("non-actionable-step"),this.cursorManager?.hide(),this.replayer.pause(i.startTimeMs),this.playStepSegment(i)),this.emit("stepChange",r,i),a=!0,this.debugLog("go-to-step-end",{stepIndex:r,navigationNonce:t,state:this._state})}catch(o){const e=o instanceof Error?o:new Error("Unable to load step");this.showError(e),this.setState("error"),this.emit("error",e),this.debugLog("go-to-step-error",{stepIndex:r,navigationNonce:t,message:e.message})}finally{s&&this.hideLoading()}a&&this.isStepNavigationActive(t)&&this.prefetchNextSteps()}pause(){if(!this.replayer||"playing"!==this._state)return;if(this.stepEndTimeout&&this.activeStepSegment){const e=this.activeStepSegment,t=Math.max(0,this.stepSegmentEndAtWallMs-Date.now());clearTimeout(this.stepEndTimeout),this.stepEndTimeout=null;const r=this.activeStepRunNonce;this.activeStepSegment=null,this.stepSegmentEndAtWallMs=0,this.pausedStepSegment={step:e,remainingMs:t,runNonce:r}}this.replayer.pause(),this.setState("paused");const e=this.stepTimeBounds[this.currentStepIndex]??null;e&&this.emit("pause",this.currentStepIndex,e)}resume(){if(this.replayer&&"paused"===this._state){if(this.overlayPauseLock&&!this.pausedStepSegment)return this.debugLog("resume-blocked-overlay-pause-lock",{stepIndex:this.overlayPauseLock.stepIndex}),void this.reassertOverlayPauseLock("resume-blocked");if(this.pausedStepSegment){const{step:e,remainingMs:t,runNonce:r}=this.pausedStepSegment;if(this.pausedStepSegment=null,this.currentStepIndex===e.stepIndex){if(t<=0)return void this.finalizeStepEnd(e,r);this.activeStepSegment=e,this.activeStepRunNonce=r,this.stepSegmentEndAtWallMs=Date.now()+t,this.stepEndTimeout=setTimeout(()=>{this.finalizeStepEnd(e,r)},t)}}this.replayer.play(),this.setState("playing")}}getSpeed(){return this._speed}setSpeed(e){if(!(e<=0)&&(this._speed=e,this.replayer)){const t=this.replayer;"function"==typeof t.setConfig&&t.setConfig({speed:e})}}getCurrentStep(){return this.currentStepIndex}getTotalSteps(){return this.stepTimeBounds.length}getState(){return this._state}getStepBoundsInternal(){return[...this.stepTimeBounds]}getRuntimeElementsInternal(){if(!this.options.runtimeHooks)return null;const e=this.overlayManager?.getRuntimeElements();return{host:this.host,container:this.viewport,viewport:this.viewport,replayWrapper:this.replayWrapper,stepOverlay:e?.stepOverlay??null,stepOverlayPulse:e?.stepOverlayPulse??null,overlayScrim:e?.overlayScrim??null,overlayHint:e?.overlayHint??null,anywhereOverlay:e?.anywhereOverlay??null,modalOverlay:e?.modalOverlay??null}}updateConfigInternal(e){const t=this.options.className,i=this.options.injectCss,s=this.options.baseUrl,a=this.options.fetch,o=this.options.retry;var n,l;n=this.options,(l=e).source&&"baseUrl"in l.source&&l.source.baseUrl&&(n.baseUrl=l.source.baseUrl),l.ui&&"startOverlay"in l.ui&&(n.startOverlay=void 0===l.ui.startOverlay?void 0:{...n.startOverlay??{},...l.ui.startOverlay}),l.ui&&"endOverlay"in l.ui&&(n.endOverlay=void 0===l.ui.endOverlay?void 0:{...n.endOverlay??{},...l.ui.endOverlay}),l.ui&&"stepOverlay"in l.ui&&(n.stepOverlay=void 0===l.ui.stepOverlay?void 0:{...n.stepOverlay??{},...l.ui.stepOverlay}),l.ui&&"className"in l.ui&&(n.className=l.ui.className),l.ui&&"injectCss"in l.ui&&(n.injectCss=l.ui.injectCss),l.advanced&&"prefetch"in l.advanced&&(n.prefetch=void 0===l.advanced.prefetch?void 0:{...n.prefetch??{},...l.advanced.prefetch}),l.network&&"fetch"in l.network&&(n.fetch=l.network.fetch),l.advanced&&"retry"in l.advanced&&(n.retry=l.advanced.retry),l.advanced&&"runtimeHooks"in l.advanced&&(n.runtimeHooks=!0===l.advanced.runtimeHooks),this.prefetchWindow=this.options.prefetch?.window??1,this.options.className!==t&&this.applyHostClassName(this.options.className),this.options.injectCss!==i&&this.applyStylesPreference(this.options.injectCss),this.options.fetch===a&&this.options.retry===o||(this.fetchClient=new r({fetch:this.options.fetch,retry:this.options.retry})),this.options.baseUrl!==s&&this.reloadRecordingForUpdatedSource()}resetPlaybackSession(e){this.invalidatePlaybackSession(),this.resolveReplayCastWaiters(),this.clearEndOverlayTimer(),this.prefetchAbortController?.abort(),this.prefetchAbortController=null,this.clearStepEndTimer(),this.invalidateStepNavigation(),this.clearOverlayPauseLock(e),this.invalidateOverlayInteractionGate(),this.overlayManager?.hide(),this.cursorManager?.hide(),this.teardownReplayer(),this.replayIframePrepared=!1,this.loaded=null,this.i18n=null,this.currentStepIndex=0,this.accumulatedEvents=[],this.stepLoadStates.clear(),this.stepLoadPromises.clear(),this.stepLastEventTimestamps.clear(),this.loadedThroughStep=-1,this.stepTimeBounds=[],this.isPrefetching=!1,this.hasStarted=!1,this.hasFinished=!1,this.replayBaseTimestampMs=null}async reloadRecordingForUpdatedSource(){if(this.viewport){this.setState("loading"),this.showLoading(),this.resetPlaybackSession("reload-source");try{"ready"===await this.initializePlaybackSession()&&this.settleReadySuccess()}catch(e){const t=e instanceof Error?e:new Error("Unable to reload recording");this.showError(t),this.setState("error"),this.emit("error",t),this.hideLoading(),this.settleReadyError(t)}}}restart(){this.resetToStart()}showPreviewOverlayInternal(e,t){this.overlayManager&&("start"===e?this.overlayManager.showPreviewStart({title:t.title,message:t.message,ctaLabel:t.ctaLabel,opacity:t.opacity,cardColor:t.cardColor,buttonColor:t.buttonColor,textColor:t.textColor}):this.overlayManager.showPreviewEnd({title:t.title,message:t.message,ctaLabel:t.ctaLabel,replayLabel:t.replayLabel,opacity:t.opacity,cardColor:t.cardColor,buttonColor:t.buttonColor,textColor:t.textColor}))}hidePreviewOverlayInternal(){this.overlayManager?.hidePreview()}destroy(){this.resetPlaybackSession("destroy"),this.overlayManager&&(this.overlayManager.destroy(),this.overlayManager=null),this.cursorManager&&(this.cursorManager.destroy(),this.cursorManager=null),this.scrollGuardCleanup?.(),this.scrollGuardCleanup=null,Le(this.host),this.viewport=null,this.addressEl=null,this.loaderEl=null,this.progressBar=null,this.stylesAttached&&(A(),this.stylesAttached=!1),this.emit("destroy"),this.removeAllListeners()}resolveDebugEnabled(){try{if(!0===globalThis.__POKEPLAYER_DEBUG__)return!0}catch{}if("undefined"==typeof window)return!1;try{return"1"===window.localStorage.getItem("pokeplayer:debug")}catch{return!1}}debugLog(e,t){this.debugEnabled&&(t?console.debug("[pokeplayer]",e,t):console.debug("[pokeplayer]",e))}beginStepNavigation(){const e=this.stepNavigationNonce+1;return this.stepNavigationNonce=e,e}isPlaybackSessionActive(e){return this.playbackSessionNonce===e}invalidatePlaybackSession(){this.playbackSessionNonce++}invalidateStepNavigation(){this.stepNavigationNonce++}isStepNavigationActive(e){return this.stepNavigationNonce===e}lockOverlayPause(e,t){const r=this.overlayPauseLockNonce+1;this.overlayPauseLockNonce=r,this.overlayPauseLock={stepIndex:e.stepIndex,pauseAtMs:t,nonce:r},this.debugLog("pause-lock-enabled",{stepIndex:e.stepIndex,pauseAtMs:t,nonce:r})}clearOverlayPauseLock(e){if(!this.overlayPauseLock)return;const t=this.overlayPauseLock;this.overlayPauseLock=null,this.overlayPauseLockNonce++,this.debugLog("pause-lock-cleared",{reason:e,stepIndex:t.stepIndex,pauseAtMs:t.pauseAtMs})}reassertOverlayPauseLock(e,t){if(!this.replayer||!this.overlayPauseLock||this.overlayPauseReasserting)return;if(this.activeStepSegment)return;const r=this.overlayPauseLock;if(this.currentStepIndex===r.stepIndex){this.overlayPauseReasserting=!0;try{this.replayer.pause(r.pauseAtMs),"paused"!==this._state&&this.setState("paused"),this.debugLog("pause-lock-reassert",{reason:e,stepIndex:r.stepIndex,pauseAtMs:r.pauseAtMs,replayMs:t})}finally{this.overlayPauseReasserting=!1}}else this.clearOverlayPauseLock("step-mismatch")}maybeReassertOverlayPauseLock(e){this.overlayPauseLock&&(this.activeStepSegment||this.scheduleAfterNextPaint(()=>{this.reassertOverlayPauseLock(e)}))}maybeEnforceOverlayPauseLockFromEvent(e){if(!this.overlayPauseLock)return;if(this.activeStepSegment||this.stepAdvanceInProgress)return;const t=this.toReplayOffsetMs(e.timestamp);if(null==t)return;t>this.overlayPauseLock.pauseAtMs+8&&this.reassertOverlayPauseLock("event-cast-drift",t)}setState(e){const t=this._state;this.stateStore.set(e),t!==e&&this.debugLog("state-change",{from:t,to:e,currentStepIndex:this.currentStepIndex})}applyHostClassName(e){for(const r of this.hostClassTokens)this.host.classList.remove(r);const t=(e??"").split(/\s+/).filter(Boolean);for(const r of t)this.host.classList.add(r);this.hostClassTokens=t}applyStylesPreference(e){const t=!1!==e;if(t&&!this.stylesAttached)return T(),void(this.stylesAttached=!0);!t&&this.stylesAttached&&(A(),this.stylesAttached=!1)}assertRuntimeCapabilities(){if("undefined"==typeof window||"undefined"==typeof document)throw new Error("PokePlayer requires a browser runtime (window/document).")}async init(){try{this.assertRuntimeCapabilities(),this.setState("loading"),this.mount(),this.showLoading();"ready"===await this.initializePlaybackSession()&&this.settleReadySuccess()}catch(e){const t=e instanceof Error?e:new Error("Unable to load recording");this.showError(t),this.setState("error"),this.emit("error",t),this.hideLoading(),this.settleReadyError(t)}}async initializePlaybackSession(){const e=this.playbackSessionNonce,t=await this.loadRecording();if(!this.isPlaybackSessionActive(e))return"stale";this.loaded=t,this.stepTimeBounds=be(t.manifest,e=>this.i18nString(e));const r=await this.fetchStepEvents(0);if(!this.isPlaybackSessionActive(e))return"stale";if(0===r.length)throw new Error("No events available for playback");this.maybeSetReplayBaseTimestamp(r),this.accumulatedEvents=r,this.stepLoadStates.set(0,"loaded"),this.loadedThroughStep=0,this.currentStepIndex=0,this.hasStarted=!1,this.hasFinished=!1;if("stale"===await this.initializeReplayer(r,e))return"stale";const i=this.stepTimeBounds[0];return i&&this.replayer&&this.replayer.pause(i.startTimeMs),this.isPlaybackSessionActive(e)?(this.setState("ready"),this.updateProgress(),this.hideLoading(),this.emit("stepChange",0,i??null),this.isPlaybackSessionActive(e)?(this.emit("ready"),this.isPlaybackSessionActive(e)?(this.showStartOverlay(),this.prefetchNextSteps(),"ready"):"stale"):"stale"):"stale"}mount(){const e=function(e){e.innerHTML='<div class="pokeplayer-shell">\n <div class="pokeplayer-progress"></div>\n <div class="pokeplayer-bar">\n <div class="pokeplayer-bar__controls">\n <span class="dot red"></span>\n <span class="dot amber"></span>\n <span class="dot green"></span>\n </div>\n <div class="pokeplayer-bar__address">pokedemo / playback</div>\n </div>\n\n <div class="pokeplayer-viewport"></div>\n\n <div class="pokeplayer-loader hidden">\n <div class="pokeplayer-loader__content">\n <div class="pokeplayer-loader__spinner"></div>\n <div class="pokeplayer-loader__label">Loading step…</div>\n </div>\n </div>\n</div>\n';const t=e.querySelector(".pokeplayer-shell"),r=e.querySelector(".pokeplayer-viewport"),i=e.querySelector(".pokeplayer-bar__address"),s=e.querySelector(".pokeplayer-progress"),a=e.querySelector(".pokeplayer-loader");if(!(t&&r&&i&&s&&a))throw new Error("Failed to initialize player shell");return{host:t,viewport:r,address:i,progress:s,loader:a}}(this.host);this.viewport=e.viewport,this.loaderEl=e.loader,this.addressEl=e.address,this.progressBar=e.progress,this.overlayManager=new E,this.overlayManager.setContainer(e.viewport),this.cursorManager=new N,this.cursorManager.setContainer(e.viewport),this.installScrollGuard()}installScrollGuard(){if(!this.viewport||this.scrollGuardCleanup)return;const e={passive:!1,capture:!0},t=e=>{e.preventDefault()},r=e=>{e.preventDefault()};this.viewport.addEventListener("wheel",t,e),this.viewport.addEventListener("touchmove",r,e),this.scrollGuardCleanup=()=>{this.viewport?.removeEventListener("wheel",t,!0),this.viewport?.removeEventListener("touchmove",r,!0),this.scrollGuardCleanup=null}}async loadRecording(){const e=ie(this.options.baseUrl),t=new URL("manifest.json",e).href,r=await this.fetchClient.fetch(t,{credentials:se(t)?"include":"omit"});if(!r.ok)throw new Error(`Failed to fetch manifest: ${r.status}`);const i=await r.json();if(!function(e){if(!O(e))return!1;if(!R(e.version)||"string"!=typeof e.generatedAt||"string"!=typeof e.sessionId||"string"!=typeof e.projectId||!R(e.eventCount)||!R(e.durationMs)||"string"!=typeof e.assetsBase)return!1;if(!O(e.i18n))return!1;const t=e.i18n;return!!("string"==typeof t.defaultLocale&&Array.isArray(t.locales)&&0!==t.locales.length&&t.locales.every(B)&&Array.isArray(e.steps)&&e.steps.every(H)&&Array.isArray(e.pages)&&e.pages.every($))}(i))throw new Error("Manifest payload is invalid");const s=i;if(4!==s.version)throw new Error(`Unsupported manifest version: ${String(s.version)} (expected 4)`);const a=new URL("./",t).href;if(await this.loadI18n(s,a),this.addressEl){const e=s.pages?.[0]?.url??null;if(e)try{const t=new URL(e,a);this.addressEl.textContent=t.hostname||"pokedemo / playback"}catch{this.addressEl.textContent="pokedemo / playback"}else this.addressEl.textContent="pokedemo / playback"}if(this.applyViewportMeta(s),!Array.isArray(s.steps)||0===s.steps.length)throw new Error("Manifest is missing steps");const o=s.steps.map((e,t)=>{if(!xe(e))throw new Error(`Manifest step ${t} is invalid`);const r="string"==typeof e.src?e.src:"";if(!r.trim())throw new Error(`Manifest step ${t} is missing src`);const i=new URL(r,a).href;return{...e,src:i}});return{manifest:s,stepFiles:o,manifestBaseUrl:a,replayDocumentBaseUrl:a}}async loadI18n(e,t){this.i18n=null;const r=e.i18n;if(!r||"object"!=typeof r)return;const i="string"==typeof r.defaultLocale?r.defaultLocale:null,s=Array.isArray(r.locales)?r.locales:null;if(!i||!s||0===s.length)return;const a=s.find(e=>e&&"object"==typeof e&&e.locale===i)??s[0],o=a?.src;if("string"!=typeof o)return;const n=new URL(o,t).href;try{const e=await this.fetchClient.fetch(n,{credentials:se(n)?"include":"omit"});if(!e.ok)return;const t=await e.json();t&&"object"==typeof t&&(this.i18n=t)}catch(l){return void this.debugLog("i18n-load-failed",{message:l instanceof Error?l.message:String(l)})}}i18nString(e){if(!this.i18n)return null;const t=e.split(".").filter(Boolean);let r=this.i18n;for(const i of t){if(!r||"object"!=typeof r||!(i in r))return null;r=r[i]}return"string"==typeof r?r:null}getStepZoomDurationMs(e){return!e||Te()?0:240}computeStepZoomPan(e,t){if(!this.viewport)return{tx:0,ty:0};const r=this.replayNaturalWidth,i=this.replayNaturalHeight;if(r<=0||i<=0)return{tx:0,ty:0};const s=this.viewport.clientWidth,a=this.viewport.clientHeight;if(s<=0||a<=0)return{tx:0,ty:0};const o=-(c(e.x,0,r)-r/2)*t,n=-(c(e.y,0,i)-i/2)*t,l=r*t,p=i*t,h=Math.max(0,(l-s)/2),d=Math.max(0,(p-a)/2);return{tx:c(o,-h,h),ty:c(n,-d,d)}}computeReplayWrapperTransform(){const e=this.replayFitScale>0?this.replayFitScale:1;if(!this.stepZoomActive||!this.stepZoomTarget)return{scale:e,tx:0,ty:0};const t=1.12*e,r=this.computeStepZoomPan(this.stepZoomTarget,t);return{scale:t,tx:r.tx,ty:r.ty}}applyReplayWrapperTransform(e={}){const t=this.replayWrapper;if(!t)return;const r=e.animate??!0,i=this.getStepZoomDurationMs(r);t.style.transition=i>0?`transform ${i}ms cubic-bezier(0.2, 0.9, 0.2, 1)`:"none";const{scale:s,tx:a,ty:o}=this.computeReplayWrapperTransform();t.style.transform=`translate(-50%, -50%) translate(${Math.round(a)}px, ${Math.round(o)}px) scale(${s})`}resolveStepZoomTarget(e){if("number"==typeof e.targetX&&"number"==typeof e.targetY&&Number.isFinite(e.targetX)&&Number.isFinite(e.targetY))return{x:e.targetX,y:e.targetY};if("number"!=typeof e.targetNodeId||!Number.isFinite(e.targetNodeId))return null;const t=n(this.replayer,this.viewport,e.targetNodeId);if(!t)return null;const r=t.ownerDocument?.defaultView?.frameElement;if(!(r instanceof HTMLElement))return null;const i=t.getBoundingClientRect(),s=i.left+i.width/2,a=i.top+i.height/2;return Number.isFinite(s)&&Number.isFinite(a)?{x:s,y:a}:null}isStepZoomEnabled(e){if(Te())return!1;if("boolean"==typeof e.stepZoomEnabled)return e.stepZoomEnabled;const t=this.i18nString(`steps.${e.stepIndex}.stepZoomEnabled`);if("true"===t?.trim().toLowerCase())return!0;const r=this.i18nString("transitions.stepZoomEnabled");return"true"===r?.trim().toLowerCase()}zoomInToStep(e,t={}){if(!this.isStepZoomEnabled(e))return 0;const r=this.resolveStepZoomTarget(e);if(!r)return 0;const i=t.animate??!0;return this.stepZoomActive=!0,this.stepZoomTarget=r,this.stepZoomOutSettlesAtMs=0,this.applyReplayWrapperTransform({animate:i}),this.getStepZoomDurationMs(i)}zoomOutFromStep(e={}){if(!this.stepZoomActive&&!this.stepZoomTarget)return;const t=e.animate??!0,r=this.getStepZoomDurationMs(t);this.stepZoomActive=!1,this.stepZoomTarget=null,this.stepZoomOutSettlesAtMs=r>0?Date.now()+r:0,this.applyReplayWrapperTransform({animate:t})}async waitForStepZoomOut(){const e=this.stepZoomOutSettlesAtMs-Date.now();e<=0||await new Promise(t=>setTimeout(t,e))}async waitForReplayPauseSettle(){await this.scheduleAfterNextPaint(),await this.scheduleAfterNextPaint()}scheduleAfterNextPaint(e){return new Promise(t=>{const r=()=>{e?.(),t()};"function"!=typeof globalThis.requestAnimationFrame?setTimeout(r,0):globalThis.requestAnimationFrame(()=>r())})}applyViewportMeta(e){const t=e.pages?.find(e=>e.viewport?.width&&e.viewport?.height)?.viewport;if(this.viewport&&t?.width&&t?.height){const e=t.width/t.height;Number.isFinite(e)&&e>0&&this.viewport.style.setProperty("--pokeplayer-aspect-ratio",`${e}`)}}async fetchStepEvents(e,t){if(!this.loaded)throw new Error("Player not initialized");const r=this.loaded.stepFiles[e];if(!r)throw new Error(`Invalid step index: ${e}`);return 0===r.limit?[]:this.fetchStepBlob(e,t)}async fetchStepBlob(e,t){const r=this.loaded;if(!r)throw new Error("Player not initialized");const i=r.stepFiles[e];if(!i?.src)throw new Error(`Step src missing for step ${e}`);const s=await this.fetchClient.fetch(i.src,{credentials:se(i.src)?"include":"omit",signal:t});if(!s.ok)throw new Error(`Failed to fetch step ${e}: ${s.status}`);const a=await s.arrayBuffer(),o=new Uint8Array(a),n=_(await Z(o));return function(e,t){for(const r of e)Pe(r,t)}(n,r.replayDocumentBaseUrl),J({stepIndex:e,events:n,hostname:this.resolvePlaybackHostname()}),n.length>0&&this.stepLastEventTimestamps.set(e,n[n.length-1].timestamp),n}resolvePlaybackHostname(){return"undefined"!=typeof window&&window.location?.hostname?window.location.hostname:function(e){try{return new URL(e).hostname||null}catch{return null}}(this.options.baseUrl)}async initializeReplayer(e,t){if(!this.viewport)return"ready";if(!this.isPlaybackSessionActive(t))return"stale";if(this.teardownReplayer(),!this.isPlaybackSessionActive(t))return"stale";const r=await s(e,{root:this.viewport,mouseTail:!1,liveMode:!1,UNSAFE_replayCanvas:!1});return this.isPlaybackSessionActive(t)?(this.replayer=r,this.ensureReplayIframeReady(),this.applyFitToViewport(),this.overlayManager&&this.replayer&&this.overlayManager.setReplayer(this.replayer),this.cursorManager&&this.replayer&&this.cursorManager.setReplayer(this.replayer),this.bindFinishListener(),this.bindEventCastListener(),this.bindReplayLifecycleGuards(),this.updateProgress(),"ready"):(o(r),"stale")}ensureReplayIframeReady(){!function(e){if(l(e))return e.onPrepared?.(),!0;if(!e.viewport)return!1;if("function"!=typeof MutationObserver)return!1;const t=new MutationObserver(()=>{l(e)&&(e.onPrepared?.(),t.disconnect(),clearInterval(r))});t.observe(e.viewport,{childList:!0,subtree:!0});const r=setInterval(()=>{l(e)&&(e.onPrepared?.(),t.disconnect(),clearInterval(r))},50);setTimeout(()=>{t.disconnect(),clearInterval(r)},2e3)}({viewport:this.viewport,documentBaseUrl:this.loaded?.replayDocumentBaseUrl,sandbox:"allow-same-origin",onPrepared:()=>{this.replayIframePrepared=!0}})}bindFinishListener(){this.replayer&&function(e,t){const r=e;r.on?.("finish",t)}(this.replayer,()=>{this.debugLog("rrweb-finish"),this.maybeReassertOverlayPauseLock("rrweb-finish"),this.handleReplayerFinish()})}bindEventCastListener(){this.replayer&&function(e,t){const r=e;r.on?.("event-cast",e=>{t(e)})}(this.replayer,e=>{this.debugLog("rrweb-event-cast",{type:e?.type,source:3===e?.type&&"object"==typeof e?.data?e.data?.source:void 0,timestamp:e?.timestamp}),this.replayIframePrepared&&2!==e?.type||this.ensureReplayIframeReady(),this.maybeEndActiveStepFromEvent(e),this.maybeEnforceOverlayPauseLockFromEvent(e),this.resolveReplayCastWaiters()})}bindReplayLifecycleGuards(){if(!this.replayer)return;const e=this.replayer,t=(t,r)=>{e.on?.(t,()=>{this.debugLog(`rrweb-${t}`),r()})};t("start",()=>{this.maybeReassertOverlayPauseLock("rrweb-start")}),t("play-back",()=>{this.maybeReassertOverlayPauseLock("rrweb-play-back")}),t("load-stylesheet-start",()=>{this.maybeReassertOverlayPauseLock("rrweb-load-stylesheet-start")}),t("load-stylesheet-end",()=>{this.maybeReassertOverlayPauseLock("rrweb-load-stylesheet-end")}),t("pause",()=>{})}maybeSetReplayBaseTimestamp(e){if(null==this.replayBaseTimestampMs)for(const t of e)if("number"==typeof t?.timestamp&&t.timestamp>0)return void(this.replayBaseTimestampMs=t.timestamp)}maybeEndActiveStepFromEvent(e){const t=this.activeStepSegment;if(!t)return;if("number"!=typeof e?.timestamp||!Number.isFinite(e.timestamp))return;const r=this.toReplayOffsetMs(e.timestamp);null!=r&&r>=t.endTimeMs&&this.finalizeStepEnd(t,this.activeStepRunNonce)}toReplayOffsetMs(e){if(!Number.isFinite(e)||e<=0)return null;null==this.replayBaseTimestampMs&&(this.replayBaseTimestampMs=e);const t=this.replayBaseTimestampMs;return null==t?null:Math.max(0,e-t)}waitForReplayCast(e=120){return new Promise(t=>{let r=!1;const i=()=>{r||(r=!0,clearTimeout(s),this.replayCastWaiters.delete(i),t())},s=setTimeout(i,e);this.replayCastWaiters.add(i)})}resolveReplayCastWaiters(){if(0===this.replayCastWaiters.size)return;const e=[...this.replayCastWaiters];this.replayCastWaiters.clear();for(const t of e)t()}async handleReplayerFinish(){if(this.debugLog("handle-replayer-finish",{loadedThroughStep:this.loadedThroughStep,totalSteps:this.stepTimeBounds.length,hasOverlayPauseLock:Boolean(this.overlayPauseLock)}),this.maybeReassertOverlayPauseLock("handle-replayer-finish"),!this.loaded)return void this.handleFinish();const e=this.stepTimeBounds.length-1;if(this.loadedThroughStep<e){const t=Math.min(e,this.loadedThroughStep+Math.max(1,this.prefetchWindow));return void this.loadStepsThrough(t,void 0,{prefetch:!0}).catch(()=>{})}this.handleFinish()}async loadStepsThrough(e,t,r={}){const i=this.playbackSessionNonce;if(!this.loaded||!this.replayer)return;for(let s=this.loadedThroughStep+1;s<=e;s++){if(!this.isPlaybackSessionActive(i))return;if(t?.aborted)return;const e=this.stepLoadStates.get(s);if("loaded"===e)continue;if("loading"===e){const e=this.stepLoadPromises.get(s);if(e){if(await e,!this.isPlaybackSessionActive(i))return;continue}}const o=async()=>{this.stepLoadStates.set(s,"loading");try{const e=await this.fetchStepEvents(s,t);if(!this.isPlaybackSessionActive(i)||!this.replayer)return void this.stepLoadStates.set(s,"pending");const r=this.replayer;for(const t of e){if(!this.isPlaybackSessionActive(i))return void this.stepLoadStates.set(s,"pending");a(r,t)}if(!this.isPlaybackSessionActive(i))return void this.stepLoadStates.set(s,"pending");this.accumulatedEvents.push(...e),this.stepLoadStates.set(s,"loaded"),this.loadedThroughStep=s}catch(e){if(t?.aborted||e instanceof DOMException&&"AbortError"===e.name)return void this.stepLoadStates.set(s,"pending");throw this.stepLoadStates.set(s,"error"),e}finally{this.stepLoadPromises.delete(s)}},n=r.prefetch?ke(o,t):o();this.stepLoadPromises.set(s,n),await n}}playStepSegment(e){if(!this.replayer)return;this.clearStepEndTimer(),this.invalidateOverlayInteractionGate(),this.clearOverlayPauseLock("play-step-segment"),this.overlayManager?.hide(),this.cursorManager?.showForStep(e,{animate:!1}),this.setState("playing"),this.debugLog("step-segment-start",{stepIndex:e.stepIndex,startTimeMs:e.startTimeMs,endTimeMs:e.endTimeMs}),this.emit("stepStart",e.stepIndex,e),this.replayer.play(e.startTimeMs),this.updateProgress();const t=this.activeStepRunNonce+1;this.activeStepSegment=e,this.activeStepRunNonce=t;const r=e.endTimeMs-e.startTimeMs;r<=0?this.finalizeStepEnd(e,t):(this.stepSegmentEndAtWallMs=Date.now()+r,this.stepEndTimeout=setTimeout(()=>{this.finalizeStepEnd(e,t)},r))}finalizeStepEnd(e,t){if(!this.activeStepSegment)return;if(this.activeStepRunNonce!==t)return;if(this.activeStepSegment.stepIndex!==e.stepIndex)return;this.clearStepEndTimer(),this.clearOverlayPauseLock("step-finalized"),this.zoomOutFromStep(),this.replayer&&this.replayer.pause(e.endTimeMs),this.updateProgress(!0),this.debugLog("step-segment-end",{stepIndex:e.stepIndex,runNonce:t}),this.emit("stepEnd",e.stepIndex,e),this.emit("pause",e.stepIndex,e);const r=e.stepIndex+1;r<this.stepTimeBounds.length?this.goToStep(r):this.handleFinish()}async startInteractivePlayback(){if(this.hasStarted||!this.loaded)return;this.hasStarted=!0,this.hasFinished=!1,this.invalidateStepNavigation(),this.invalidateOverlayInteractionGate(),this.clearOverlayPauseLock("start-interactive-playback"),this.overlayManager?.hide(),this.setState("playing"),this.emit("start");const e=this.findFirstNonInitialStepIndex();await this.goToStep(e)}findFirstNonInitialStepIndex(){if(0===this.stepTimeBounds.length)return 0;for(let e=0;e<this.stepTimeBounds.length;e++){if("initial"!==this.stepTimeBounds[e].kind)return e}return 0}isOverlayActionableStep(e){return"initial"!==e.kind&&!e.skip}getPreStepTimeMs(e){return Math.max(0,e.startTimeMs-1)}showStartOverlay(){if(!this.overlayManager)return;this.clearOverlayPauseLock("show-start-overlay"),this.invalidateOverlayInteractionGate(),this.cursorManager?.hide();const e=function(e,t){const r=e("overlays.start.title"),i=e("overlays.start.message"),s=e("overlays.start.ctaLabel"),a=ve(e,"overlays.start",t);return{title:t?.title??r??ae,message:t?.message??i??oe,ctaLabel:t?.ctaLabel??s??ne,opacity:a.opacity,cardColor:a.cardColor,buttonColor:a.buttonColor,textColor:a.textColor}}(e=>this.i18nString(e),this.options.startOverlay);this.overlayManager.showStart({title:e.title,message:e.message,ctaLabel:e.ctaLabel,opacity:e.opacity,cardColor:e.cardColor,buttonColor:e.buttonColor,textColor:e.textColor,onPrimary:()=>{this.emitOverlayClick("start","primary"),this.startInteractivePlayback()}}),this.emitOverlayShown("start")}showEndOverlay(){if(!this.overlayManager)return;this.clearOverlayPauseLock("show-end-overlay"),this.invalidateOverlayInteractionGate(),this.cursorManager?.hide();const e=function(e,t){const r=e("overlays.end.title"),i=e("overlays.end.message"),s=e("overlays.end.ctaLabel"),a=e("overlays.end.replayLabel"),o=ve(e,"overlays.end",t);return{title:t?.title??r??le,message:t?.message??i??pe,ctaLabel:t?.ctaLabel??s??ce,replayLabel:t?.replayLabel??a??he,showReplay:t?.showReplay??de,opacity:o.opacity,cardColor:o.cardColor,buttonColor:o.buttonColor,textColor:o.textColor}}(e=>this.i18nString(e),this.options.endOverlay),t=e.showReplay&&Boolean(e.replayLabel);this.overlayManager.showEnd({title:e.title,message:e.message,ctaLabel:e.ctaLabel,replayLabel:t?e.replayLabel:void 0,opacity:e.opacity,cardColor:e.cardColor,buttonColor:e.buttonColor,textColor:e.textColor,onPrimary:()=>{this.emitOverlayClick("end","primary"),this.overlayManager?.hide()},onReplay:t?()=>{this.emitOverlayClick("end","replay"),this.resetToStart()}:void 0}),this.emitOverlayShown("end")}renderStepOverlay(e,t,r=this.stepNavigationNonce){if(!this.overlayManager)return;const i=(s=this.options.stepOverlay,{instruction:s?.instruction??ue,anywhereInstruction:s?.anywhereInstruction??ye});var s;const a="scroll"===e.kind,o=e.instruction??this.defaultInstructionForStep(e)??i.instruction,n=this.beginOverlayInteractionGate(),l=()=>{this.isStepNavigationActive(r)?this.isOverlayInteractionGateOpen(e,n)?this.advanceStepFromOverlay(e,r):this.debugLog("overlay-advance-blocked-gate",{stepIndex:e.stepIndex,interactionNonce:n}):this.debugLog("overlay-advance-blocked-stale-navigation",{stepIndex:e.stepIndex,navigationNonce:r,currentNavigationNonce:this.stepNavigationNonce})},p=!a&&"number"==typeof e.targetX&&"number"==typeof e.targetY&&Number.isFinite(e.targetX)&&Number.isFinite(e.targetY)&&!(0===e.targetX&&0===e.targetY),c=this.overlayManager.showStep({nodeId:e.targetNodeId,fallbackX:p?e.targetX:void 0,fallbackY:p?e.targetY:void 0,kind:e.kind},{instruction:o,anywhereInstruction:a?void 0:i.anywhereInstruction,onTargetClick:()=>{this.emitOverlayClick("step","target",e),l()},onAnywhereClick:()=>{this.emitOverlayClick("anywhere","anywhere",e),l()},onScroll:a?()=>{this.emitOverlayClick("anywhere","anywhere",e),l()}:void 0,gesture:a?"scroll":void 0,highlightColor:e.highlightColor,hintCardColor:e.hintCardColor,hintTextColor:e.hintTextColor,highlightRect:a?void 0:e.highlightRect,hintPos:e.hintPos});this.emitOverlayShown(c,e),this.armOverlayInteractionGate(n,r)}cancelPendingStepAdvance(){this.stepAdvanceNonce++,this.stepAdvanceInProgress=!1}beginOverlayInteractionGate(){const e=this.overlayInteractionNonce+1;return this.overlayInteractionNonce=e,this.overlayInteractionArmedNonce=0,this.debugLog("overlay-gate-begin",{nonce:e,stepIndex:this.currentStepIndex}),e}invalidateOverlayInteractionGate(){this.overlayInteractionNonce++,this.overlayInteractionArmedNonce=0,this.debugLog("overlay-gate-invalidate",{nonce:this.overlayInteractionNonce,stepIndex:this.currentStepIndex})}isOverlayInteractionGateOpen(e,t){return this.currentStepIndex===e.stepIndex&&(this.overlayInteractionNonce===t&&this.overlayInteractionArmedNonce===t)}armOverlayInteractionGate(e,t=this.stepNavigationNonce){this.scheduleAfterNextPaint(()=>{if(this.overlayInteractionNonce!==e)return;if(!this.isStepNavigationActive(t))return void this.debugLog("overlay-gate-arm-cancelled-stale-navigation",{nonce:e,navigationNonce:t,currentNavigationNonce:this.stepNavigationNonce});setTimeout(()=>{this.overlayInteractionNonce===e&&(this.isStepNavigationActive(t)?(this.overlayInteractionArmedNonce=e,this.debugLog("overlay-gate-armed",{nonce:e,stepIndex:this.currentStepIndex})):this.debugLog("overlay-gate-arm-timeout-stale-navigation",{nonce:e,navigationNonce:t,currentNavigationNonce:this.stepNavigationNonce}))},120)})}isOverlayAdvanceContextValid(e){return"paused"===this._state&&this.currentStepIndex===e.stepIndex}async advanceStepFromOverlay(e,t=this.stepNavigationNonce){if(!this.isStepNavigationActive(t))return;if(!this.isOverlayAdvanceContextValid(e)||this.stepAdvanceInProgress)return;this.stepAdvanceInProgress=!0;const r=++this.stepAdvanceNonce;this.invalidateOverlayInteractionGate(),this.overlayManager?.hide();const i=this.zoomInToStep(e,{animate:!0});i>0&&await new Promise(e=>setTimeout(e,i)),r===this.stepAdvanceNonce&&this.isStepNavigationActive(t)&&this.isOverlayAdvanceContextValid(e)?(this.stepAdvanceInProgress=!1,this.playStepSegment(e)):this.stepAdvanceInProgress=!1}showStepOverlay(e,t=this.stepNavigationNonce){this.renderStepOverlay(e,!0,t)}async refreshI18nInternal(){if(!this.loaded)return;await this.loadI18n(this.loaded.manifest,this.loaded.manifestBaseUrl),this.stepTimeBounds=be(this.loaded.manifest,e=>this.i18nString(e));const e=this.stepTimeBounds[this.currentStepIndex];e&&"paused"===this._state&&(this.lockOverlayPause(e,this.getPreStepTimeMs(e)),this.renderStepOverlay(e,!1))}defaultInstructionForStep(e){switch(e.kind){case"scroll":return"Scroll to continue";case"click":return"Click the highlighted element";default:return null}}handleFinish(){this.hasFinished||(this.zoomOutFromStep({animate:!1}),this.invalidateStepNavigation(),this.clearOverlayPauseLock("handle-finish"),this.hasFinished=!0,this.clearEndOverlayTimer(),this.setState("finished"),this.emit("finish"),this.showEndOverlay())}clearEndOverlayTimer(){this.endOverlayTimeout&&(clearTimeout(this.endOverlayTimeout),this.endOverlayTimeout=null)}resetToStart(){if(!this.replayer||0===this.stepTimeBounds.length)return;this.zoomOutFromStep({animate:!1}),this.invalidateStepNavigation(),this.clearEndOverlayTimer(),this.clearStepEndTimer(),this.clearOverlayPauseLock("reset-to-start"),this.invalidateOverlayInteractionGate(),this.overlayManager?.hide(),this.currentStepIndex=0,this.hasStarted=!1,this.hasFinished=!1;const e=this.stepTimeBounds[0];this.replayer.pause(e.startTimeMs),this.updateProgress(),this.emit("stepChange",0,e),this.setState("ready"),this.showStartOverlay()}clearStepEndTimer(){this.stepEndTimeout&&(clearTimeout(this.stepEndTimeout),this.stepEndTimeout=null),this.activeStepRunNonce++,this.activeStepSegment=null,this.stepSegmentEndAtWallMs=0,this.pausedStepSegment=null}emitOverlayShown(e,t){const r={kind:e,stepIndex:t?.stepIndex,step:t??null};this.emit("overlayShown",r)}emitOverlayClick(e,t,r){const i={kind:e,action:t,stepIndex:r?.stepIndex,step:r??null};this.emit("overlayClick",i)}prefetchNextSteps(){if(this.isPrefetching||!this.loaded)return;if(!1===this.options.prefetch?.enabled)return;const e=Math.min(this.currentStepIndex+this.prefetchWindow,this.stepTimeBounds.length-1);if(e<=this.loadedThroughStep)return;this.isPrefetching=!0,this.prefetchAbortController?.abort();const t=new AbortController;this.prefetchAbortController=t,this.loadStepsThrough(e,t.signal,{prefetch:!0}).catch(()=>{}).finally(()=>{this.isPrefetching=!1,this.prefetchAbortController===t&&(this.prefetchAbortController=null)})}applyFitToViewport(){if(!this.viewport||!this.replayer)return;const e=this.viewport.querySelector(".replayer-wrapper"),t=e?.querySelector("iframe");if(!e)return;const r=()=>{if(!this.viewport||!e)return;const r=this.loaded?.manifest.pages?.[0]?.viewport;let i=r?.width||t?.scrollWidth||e.scrollWidth||parseFloat(e.style.width||"0")||0,s=r?.height||t?.scrollHeight||e.scrollHeight||parseFloat(e.style.height||"0")||0;const a=this.viewport.clientWidth||e.scrollWidth||0,o=this.viewport.clientHeight||e.scrollHeight||0;if(i<50&&a&&(i=a),s<50&&o&&(s=o),!i||!s)return;const n=this.viewport.getBoundingClientRect(),l=n.width,p=n.height;if(!l||!p)return;const c=Math.min(l/i,p/s);this.replayWrapper=e,this.replayNaturalWidth=i,this.replayNaturalHeight=s,this.replayFitScale=c,e.style.transformOrigin="center center",e.style.left="50%",e.style.top="50%",i>0&&(e.style.width=`${i}px`,t&&(t.style.width=`${i}px`)),s>0&&(e.style.height=`${s}px`,t&&(t.style.height=`${s}px`)),this.applyReplayWrapperTransform({animate:!1})};r(),window.addEventListener("resize",r),"undefined"!=typeof ResizeObserver&&(this.resizeObserver=new ResizeObserver(()=>r()),this.resizeObserver.observe(this.viewport)),this.fitCleanup=()=>{window.removeEventListener("resize",r),this.resizeObserver?.disconnect(),this.resizeObserver=null}}teardownReplayer(){this.resolveReplayCastWaiters(),this.invalidateStepNavigation(),this.clearOverlayPauseLock("teardown-replayer"),this.stepAdvanceNonce++,this.stepAdvanceInProgress=!1,this.overlayInteractionNonce++,this.overlayInteractionArmedNonce=0,this.stepZoomActive=!1,this.stepZoomTarget=null,this.stepZoomOutSettlesAtMs=0,this.replayWrapper=null,this.replayNaturalWidth=0,this.replayNaturalHeight=0,this.replayFitScale=1,this.fitCleanup&&(this.fitCleanup(),this.fitCleanup=null),this.replayer&&o(this.replayer),this.viewport&&Le(this.viewport),this.replayer=null}showError(e){if(!this.viewport)return;if(e instanceof K)return void this.showWatermarkLock(e.message);const t="string"==typeof e?e:e.message;Le(this.viewport);const r=document.createElement("div");r.className="pokeplayer-error",r.textContent=t,this.viewport.appendChild(r)}showWatermarkLock(e){if(!this.viewport)return;this.replayer?.pause();const t=this.viewport.querySelector(".pokeplayer-watermark-lock");t&&t.remove();const r=document.createElement("div");r.className="pokeplayer-watermark-lock",r.setAttribute("role","alert"),r.setAttribute("aria-live","assertive");const i=document.createElement("div");i.className="pokeplayer-watermark-lock__banner",i.textContent="UNAUTHORIZED";const s=document.createElement("p");s.className="pokeplayer-watermark-lock__detail",s.textContent=e,r.appendChild(i),r.appendChild(s),this.viewport.appendChild(r)}showLoading(){this.loaderEl&&this.loaderEl.classList.remove("hidden")}hideLoading(){this.loaderEl&&this.loaderEl.classList.add("hidden")}updateProgress(e=!1){if(!this.progressBar||0===this.stepTimeBounds.length)return;const t=Math.max(1,this.stepTimeBounds.length-1),r=e?Math.max(0,this.currentStepIndex):Math.max(0,this.currentStepIndex-1),i=t>0?r/t:0;this.progressBar.style.transform=`scaleX(${Math.min(1,Math.max(0,i))})`}}exports.PokePlayer=Ae;
@@ -0,0 +1,452 @@
1
+ /**
2
+ * Generic typed event emitter.
3
+ */
4
+ type EventMap = Record<string, any[]>;
5
+ type Handler<Args extends unknown[]> = (...args: Args) => void;
6
+ declare class TypedEmitter<Events extends EventMap> {
7
+ private listeners;
8
+ /**
9
+ * Subscribe to an event. Returns an unsubscribe function.
10
+ */
11
+ on<K extends keyof Events>(event: K, handler: Handler<Events[K]>): () => void;
12
+ /**
13
+ * Subscribe to an event for a single invocation.
14
+ * Returns an unsubscribe function.
15
+ */
16
+ once<K extends keyof Events>(event: K, handler: Handler<Events[K]>): () => void;
17
+ /**
18
+ * Remove a specific handler for an event.
19
+ */
20
+ off<K extends keyof Events>(event: K, handler: Handler<Events[K]>): void;
21
+ /**
22
+ * Remove all listeners for a given event, or all events if no event specified.
23
+ */
24
+ removeAllListeners(event?: keyof Events): void;
25
+ /**
26
+ * Emit an event to all registered handlers.
27
+ */
28
+ protected emit<K extends keyof Events>(event: K, ...args: Events[K]): void;
29
+ }
30
+
31
+ /** Preset highlight colors for step overlays */
32
+ type PresetHighlightColor = 'cyan' | 'purple' | 'amber' | 'emerald' | 'slate';
33
+ /** Highlight colors for step overlays (preset token or custom hex) */
34
+ type HighlightColor = PresetHighlightColor | `#${string}`;
35
+ type PlayerState = 'idle' | 'loading' | 'ready' | 'playing' | 'paused' | 'finished' | 'error';
36
+ interface PokePlayerRuntimeElements {
37
+ host: HTMLElement;
38
+ container: HTMLElement | null;
39
+ viewport: HTMLElement | null;
40
+ replayWrapper: HTMLElement | null;
41
+ stepOverlay: HTMLElement | null;
42
+ stepOverlayPulse: HTMLElement | null;
43
+ overlayScrim: HTMLElement | null;
44
+ overlayHint: HTMLElement | null;
45
+ anywhereOverlay: HTMLElement | null;
46
+ modalOverlay: HTMLElement | null;
47
+ }
48
+ interface RetryOptions {
49
+ /** Maximum number of retry attempts (default: 2) */
50
+ maxRetries?: number;
51
+ /** Base delay in ms for exponential backoff (default: 500) */
52
+ baseDelayMs?: number;
53
+ /** HTTP status codes that trigger a retry (default: [408, 429, 500, 502, 503, 504]) */
54
+ retryableStatuses?: number[];
55
+ }
56
+ interface PrefetchOptions {
57
+ /** Number of steps to prefetch ahead (default: 1) */
58
+ window?: number;
59
+ /** Whether prefetching is enabled (default: true) */
60
+ enabled?: boolean;
61
+ }
62
+ interface PokePlayerSource {
63
+ baseUrl: string;
64
+ }
65
+ interface PokePlayerNetwork {
66
+ fetch?: typeof globalThis.fetch;
67
+ }
68
+ interface PokePlayerUi {
69
+ className?: string;
70
+ injectCss?: boolean;
71
+ startOverlay?: StartOverlayOptions;
72
+ endOverlay?: EndOverlayOptions;
73
+ stepOverlay?: StepOverlayOptions;
74
+ }
75
+ interface PokePlayerAdvanced {
76
+ retry?: RetryOptions;
77
+ prefetch?: PrefetchOptions;
78
+ runtimeHooks?: boolean;
79
+ }
80
+ interface PokePlayerConfig {
81
+ source: PokePlayerSource;
82
+ network?: PokePlayerNetwork;
83
+ ui?: PokePlayerUi;
84
+ advanced?: PokePlayerAdvanced;
85
+ }
86
+ interface PreviewOverlayConfig {
87
+ title: string;
88
+ message?: string;
89
+ ctaLabel?: string;
90
+ replayLabel?: string;
91
+ opacity?: number;
92
+ cardColor?: string;
93
+ buttonColor?: string;
94
+ textColor?: 'white' | 'black';
95
+ }
96
+ interface PokePlayerExperimentalApi {
97
+ updateConfig(partial: Partial<PokePlayerConfig>): void;
98
+ getStepBounds(): StepTimeBounds[];
99
+ getRuntimeElements(): PokePlayerRuntimeElements | null;
100
+ showPreviewOverlay(type: 'start' | 'end', config: PreviewOverlayConfig): void;
101
+ hidePreviewOverlay(): void;
102
+ refreshI18n(): Promise<void>;
103
+ }
104
+ interface PokePlayerApi {
105
+ readonly ready: Promise<void>;
106
+ readonly experimental: PokePlayerExperimentalApi;
107
+ start(): Promise<void>;
108
+ pause(): void;
109
+ resume(): void;
110
+ goToStep(stepIndex: number): Promise<void>;
111
+ nextStep(): Promise<void>;
112
+ restart(): void;
113
+ destroy(): void;
114
+ getState(): PlayerState;
115
+ getCurrentStep(): number;
116
+ getTotalSteps(): number;
117
+ getSpeed(): number;
118
+ setSpeed(speed: number): void;
119
+ on<K extends keyof PlayerEvents>(event: K, handler: (...args: PlayerEvents[K]) => void): () => void;
120
+ once<K extends keyof PlayerEvents>(event: K, handler: (...args: PlayerEvents[K]) => void): () => void;
121
+ off<K extends keyof PlayerEvents>(event: K, handler: (...args: PlayerEvents[K]) => void): void;
122
+ removeAllListeners(event?: keyof PlayerEvents): void;
123
+ }
124
+ type StepHighlightRect = {
125
+ x: number;
126
+ y: number;
127
+ w: number;
128
+ h: number;
129
+ };
130
+ type StepHintPos = {
131
+ x: number;
132
+ y: number;
133
+ };
134
+ /** Time boundaries for step-based seek navigation */
135
+ interface StepTimeBounds {
136
+ stepIndex: number;
137
+ startTimeMs: number;
138
+ endTimeMs: number;
139
+ kind: string;
140
+ label?: string;
141
+ instruction?: string;
142
+ /** rrweb node ID of the interacted element (for interactive overlays) */
143
+ targetNodeId?: number;
144
+ /** X coordinate of interaction (viewport-relative) */
145
+ targetX?: number;
146
+ /** Y coordinate of interaction (viewport-relative) */
147
+ targetY?: number;
148
+ /** Highlight color for step overlay */
149
+ highlightColor?: HighlightColor;
150
+ /** Hint bubble background color (hex) */
151
+ hintCardColor?: string;
152
+ /** Hint bubble text color (toggle) */
153
+ hintTextColor?: 'white' | 'black';
154
+ /** Optional manual override: highlight rectangle in replay viewport coords. */
155
+ highlightRect?: StepHighlightRect;
156
+ /** Optional manual override: hint position in replay viewport coords. */
157
+ hintPos?: StepHintPos;
158
+ /** If true, this step auto-advances once focused. */
159
+ skip?: boolean;
160
+ /** Zoom to target (pan+zoom) for this step */
161
+ stepZoomEnabled?: boolean;
162
+ }
163
+ type OverlayKind = 'start' | 'step' | 'anywhere' | 'end';
164
+ type OverlayAction = 'primary' | 'target' | 'anywhere' | 'replay';
165
+ interface OverlayEvent {
166
+ kind: OverlayKind;
167
+ action?: OverlayAction;
168
+ stepIndex?: number;
169
+ step?: StepTimeBounds | null;
170
+ }
171
+ interface StepOverlayOptions {
172
+ instruction?: string;
173
+ anywhereInstruction?: string;
174
+ }
175
+ interface StartOverlayOptions {
176
+ title?: string;
177
+ message?: string;
178
+ ctaLabel?: string;
179
+ /** Backdrop opacity multiplier for the overlay background (0..1). */
180
+ opacity?: number;
181
+ /** Modal card background color (CSS color value). */
182
+ cardColor?: string;
183
+ /** Primary button background color (CSS color value). */
184
+ buttonColor?: string;
185
+ /** Overlay text color (toggle). */
186
+ textColor?: 'white' | 'black';
187
+ }
188
+ interface EndOverlayOptions {
189
+ title?: string;
190
+ message?: string;
191
+ ctaLabel?: string;
192
+ replayLabel?: string;
193
+ showReplay?: boolean;
194
+ /** Backdrop opacity multiplier for the overlay background (0..1). */
195
+ opacity?: number;
196
+ /** Modal card background color (CSS color value). */
197
+ cardColor?: string;
198
+ /** Primary button background color (CSS color value). */
199
+ buttonColor?: string;
200
+ /** Overlay text color (toggle). */
201
+ textColor?: 'white' | 'black';
202
+ }
203
+ /** Events emitted by the player */
204
+ type PlayerEvents = {
205
+ ready: [];
206
+ start: [];
207
+ error: [Error];
208
+ stepChange: [number, StepTimeBounds | null];
209
+ stepStart: [number, StepTimeBounds];
210
+ stepEnd: [number, StepTimeBounds];
211
+ pause: [number, StepTimeBounds];
212
+ finish: [];
213
+ progress: [currentStep: number, totalSteps: number, timeMs: number];
214
+ overlayShown: [OverlayEvent];
215
+ overlayClick: [OverlayEvent];
216
+ destroy: [];
217
+ };
218
+
219
+ declare class PokePlayer extends TypedEmitter<PlayerEvents> implements PokePlayerApi {
220
+ private readonly host;
221
+ private readonly options;
222
+ private hostClassTokens;
223
+ private fetchClient;
224
+ private prefetchWindow;
225
+ private stylesAttached;
226
+ private viewport;
227
+ private addressEl;
228
+ private loaderEl;
229
+ private progressBar;
230
+ private replayer;
231
+ private loaded;
232
+ private i18n;
233
+ private currentStepIndex;
234
+ private accumulatedEvents;
235
+ private stepLoadStates;
236
+ private stepLoadPromises;
237
+ private stepLastEventTimestamps;
238
+ private prefetchAbortController;
239
+ private fitCleanup;
240
+ private resizeObserver;
241
+ private replayWrapper;
242
+ private replayNaturalWidth;
243
+ private replayNaturalHeight;
244
+ private replayFitScale;
245
+ private stepZoomActive;
246
+ private stepZoomTarget;
247
+ private stepZoomOutSettlesAtMs;
248
+ private stepAdvanceNonce;
249
+ private stepAdvanceInProgress;
250
+ private overlayInteractionNonce;
251
+ private overlayInteractionArmedNonce;
252
+ private stepNavigationNonce;
253
+ private overlayPauseLock;
254
+ private overlayPauseLockNonce;
255
+ private overlayPauseReasserting;
256
+ private loadedThroughStep;
257
+ private stepTimeBounds;
258
+ private isPrefetching;
259
+ private stepEndTimeout;
260
+ private activeStepSegment;
261
+ private activeStepRunNonce;
262
+ private stepSegmentEndAtWallMs;
263
+ private pausedStepSegment;
264
+ private overlayManager;
265
+ private cursorManager;
266
+ private hasStarted;
267
+ private hasFinished;
268
+ private scrollGuardCleanup;
269
+ private replayIframePrepared;
270
+ private replayBaseTimestampMs;
271
+ private replayCastWaiters;
272
+ private endOverlayTimeout;
273
+ private readonly debugEnabled;
274
+ private playbackSessionNonce;
275
+ private readySettled;
276
+ private readonly stateStore;
277
+ private _speed;
278
+ private get _state();
279
+ /**
280
+ * A Promise that resolves when the player is fully initialized and ready for interaction.
281
+ */
282
+ readonly ready: Promise<void>;
283
+ readonly experimental: PokePlayerExperimentalApi;
284
+ private resolveReady;
285
+ private rejectReady;
286
+ private settleReadySuccess;
287
+ private settleReadyError;
288
+ constructor(container: HTMLElement, config: PokePlayerConfig);
289
+ /**
290
+ * Async factory that returns a fully initialized player.
291
+ */
292
+ static create(container: HTMLElement, config: PokePlayerConfig): Promise<PokePlayer>;
293
+ start(): Promise<void>;
294
+ nextStep(): Promise<void>;
295
+ goToStep(stepIndex: number): Promise<void>;
296
+ /**
297
+ * Pause playback in any mode.
298
+ */
299
+ pause(): void;
300
+ /**
301
+ * Resume playback from the current position.
302
+ */
303
+ resume(): void;
304
+ /**
305
+ * Get the current playback speed multiplier.
306
+ */
307
+ getSpeed(): number;
308
+ /**
309
+ * Set playback speed multiplier.
310
+ */
311
+ setSpeed(speed: number): void;
312
+ /**
313
+ * Get the current step index.
314
+ */
315
+ getCurrentStep(): number;
316
+ /**
317
+ * Get total number of steps.
318
+ */
319
+ getTotalSteps(): number;
320
+ /**
321
+ * Get the current player state.
322
+ */
323
+ getState(): PlayerState;
324
+ /**
325
+ * Get all step bounds for editor integration.
326
+ */
327
+ private getStepBoundsInternal;
328
+ /**
329
+ * Get runtime DOM hooks for internal editor tooling.
330
+ * These hooks avoid coupling editor code to private CSS selectors.
331
+ */
332
+ private getRuntimeElementsInternal;
333
+ private updateConfigInternal;
334
+ private resetPlaybackSession;
335
+ private reloadRecordingForUpdatedSource;
336
+ restart(): void;
337
+ /**
338
+ * Show a non-interactive preview of the start overlay (for editor preview).
339
+ */
340
+ private showPreviewOverlayInternal;
341
+ /**
342
+ * Hide any preview overlay.
343
+ */
344
+ private hidePreviewOverlayInternal;
345
+ destroy(): void;
346
+ private resolveDebugEnabled;
347
+ private debugLog;
348
+ private beginStepNavigation;
349
+ private isPlaybackSessionActive;
350
+ private invalidatePlaybackSession;
351
+ private invalidateStepNavigation;
352
+ private isStepNavigationActive;
353
+ private lockOverlayPause;
354
+ private clearOverlayPauseLock;
355
+ private reassertOverlayPauseLock;
356
+ private maybeReassertOverlayPauseLock;
357
+ private maybeEnforceOverlayPauseLockFromEvent;
358
+ private setState;
359
+ private applyHostClassName;
360
+ private applyStylesPreference;
361
+ private assertRuntimeCapabilities;
362
+ private init;
363
+ private initializePlaybackSession;
364
+ private mount;
365
+ private installScrollGuard;
366
+ private loadRecording;
367
+ private loadI18n;
368
+ private i18nString;
369
+ private getStepZoomDurationMs;
370
+ private computeStepZoomPan;
371
+ private computeReplayWrapperTransform;
372
+ private applyReplayWrapperTransform;
373
+ private resolveStepZoomTarget;
374
+ private isStepZoomEnabled;
375
+ private zoomInToStep;
376
+ private zoomOutFromStep;
377
+ private waitForStepZoomOut;
378
+ private waitForReplayPauseSettle;
379
+ private scheduleAfterNextPaint;
380
+ private applyViewportMeta;
381
+ private fetchStepEvents;
382
+ private fetchStepBlob;
383
+ private resolvePlaybackHostname;
384
+ /**
385
+ * Initialize the Replayer with liveMode for incremental loading.
386
+ */
387
+ private initializeReplayer;
388
+ private ensureReplayIframeReady;
389
+ private bindFinishListener;
390
+ private bindEventCastListener;
391
+ private bindReplayLifecycleGuards;
392
+ private maybeSetReplayBaseTimestamp;
393
+ private maybeEndActiveStepFromEvent;
394
+ private toReplayOffsetMs;
395
+ private waitForReplayCast;
396
+ private resolveReplayCastWaiters;
397
+ private handleReplayerFinish;
398
+ /**
399
+ * Load steps sequentially through targetIndex using addEvent.
400
+ * Maintains the invariant that events are always loaded from step 0 forward.
401
+ */
402
+ private loadStepsThrough;
403
+ /**
404
+ * Play a step segment from startTimeMs, monitoring for step end.
405
+ */
406
+ private playStepSegment;
407
+ private finalizeStepEnd;
408
+ private startInteractivePlayback;
409
+ private findFirstNonInitialStepIndex;
410
+ private isOverlayActionableStep;
411
+ private getPreStepTimeMs;
412
+ private showStartOverlay;
413
+ private showEndOverlay;
414
+ private renderStepOverlay;
415
+ private cancelPendingStepAdvance;
416
+ private beginOverlayInteractionGate;
417
+ private invalidateOverlayInteractionGate;
418
+ private isOverlayInteractionGateOpen;
419
+ private armOverlayInteractionGate;
420
+ private isOverlayAdvanceContextValid;
421
+ private advanceStepFromOverlay;
422
+ private showStepOverlay;
423
+ /**
424
+ * Refresh i18n-driven UI (labels/instructions + overlay styling) without reloading the full player.
425
+ * Useful for editor preview after saving copy/styling.
426
+ */
427
+ private refreshI18nInternal;
428
+ private defaultInstructionForStep;
429
+ private handleFinish;
430
+ private clearEndOverlayTimer;
431
+ private resetToStart;
432
+ private clearStepEndTimer;
433
+ private emitOverlayShown;
434
+ private emitOverlayClick;
435
+ /**
436
+ * Prefetch next steps in background for instant forward navigation.
437
+ */
438
+ private prefetchNextSteps;
439
+ private applyFitToViewport;
440
+ private teardownReplayer;
441
+ /**
442
+ * Show an error message safely (no innerHTML with user content).
443
+ */
444
+ private showError;
445
+ private showWatermarkLock;
446
+ private showLoading;
447
+ private hideLoading;
448
+ private updateProgress;
449
+ }
450
+
451
+ export { PokePlayer };
452
+ export type { EndOverlayOptions, PlayerState, PokePlayerAdvanced, PokePlayerApi, PokePlayerConfig, PokePlayerExperimentalApi, PreviewOverlayConfig, StartOverlayOptions, StepOverlayOptions, StepTimeBounds };