scrolltube 2.0.15

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.
@@ -0,0 +1,14 @@
1
+ /*
2
+ Venovani:
3
+ Tento plugin je venovan me rodine - mamince Svetle,
4
+ manzelce Verce, detem Natalce a Alexovi
5
+ a nasi dceri Agatce, ktera navzdy zustane v nasich srdcich.
6
+
7
+ Dedication:
8
+ This plugin is dedicated to my family - my mother Svetla,
9
+ my wife Verca, my children Natalka and Alex,
10
+ and our daughter Agatka, who will forever remain in our hearts.
11
+ */
12
+
13
+
14
+ !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("react")):"function"==typeof define&&define.amd?define(["react"],e):"object"==typeof exports?exports.ScrollTubeReact=e(require("react")):t.ScrollTubeReact=e(t.react)}(this,t=>(()=>{"use strict";var e={197(t,e){var n=Symbol.for("react.transitional.element");function i(t,e,i){var s=null;if(void 0!==i&&(s=""+i),void 0!==e.key&&(s=""+e.key),"key"in e)for(var r in i={},e)"key"!==r&&(i[r]=e[r]);else i=e;return e=i.ref,{$$typeof:n,type:t,key:s,ref:void 0!==e?e:null,props:i}}Symbol.for("react.fragment"),e.jsx=i},85(t,e,n){t.exports=n(197)},155(e){e.exports=t}},n={};function i(t){var s=n[t];if(void 0!==s)return s.exports;var r=n[t]={exports:{}};return e[t](r,r.exports,i),r.exports}i.d=(t,e)=>{for(var n in e)i.o(e,n)&&!i.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),i.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var s={};i.r(s),i.d(s,{ScrollTubeCanvas:()=>rr,ScrollTubeLayer:()=>ar,ScrollTubeLayerTracking:()=>or,ScrollTubeProvider:()=>sr,SubjectLayer:()=>lr,useScrollTube:()=>hr});var r=i(85),a=i(155);class o{constructor(t,e={}){if(this.targetMouse={x:0,y:0},this.currentMouse={x:0,y:0},this.animationFrameId=0,this.depthTilt=.04,this.animate=()=>{if(this.currentMouse.x+=.1*(this.targetMouse.x-this.currentMouse.x),this.currentMouse.y+=.1*(this.targetMouse.y-this.currentMouse.y),this.gl&&this.program){this.gl.useProgram(this.program);const t=this.gl.getUniformLocation(this.program,"u_mouse");this.gl.uniform2f(t,this.currentMouse.x,this.currentMouse.y);const e=this.gl.getUniformLocation(this.program,"u_depthTilt");this.gl.uniform1f(e,this.depthTilt),this.draw()}this.animationFrameId=requestAnimationFrame(this.animate)},this.depthTilt=void 0!==e.depthTilt?e.depthTilt:4,this.gl=t.getContext("webgl",{alpha:!1,antialias:!1}),!this.gl)throw new Error("WebGL not supported");this.program=this.createProgram("\n attribute vec2 a_position;\n varying vec2 v_texCoord;\n void main() {\n gl_Position = vec4(a_position, 0.0, 1.0);\n // Convert -1 -> 1 to 0 -> 1 for UVs\n v_texCoord = a_position * 0.5 + 0.5;\n v_texCoord.y = 1.0 - v_texCoord.y;\n }\n ","\n precision mediump float;\n uniform sampler2D u_image;\n uniform sampler2D u_depthMap;\n uniform vec2 u_resolution;\n uniform vec2 u_imageResolution;\n uniform vec2 u_mouse;\n uniform float u_depthTilt;\n uniform bool u_hasDepth;\n varying vec2 v_texCoord;\n\n void main() {\n // object-fit: cover math\n vec2 ratio = vec2(\n min((u_resolution.x / u_resolution.y) / (u_imageResolution.x / u_imageResolution.y), 1.0),\n min((u_resolution.y / u_resolution.x) / (u_imageResolution.y / u_imageResolution.x), 1.0)\n );\n vec2 uv = vec2(\n v_texCoord.x * ratio.x + (1.0 - ratio.x) * 0.5,\n v_texCoord.y * ratio.y + (1.0 - ratio.y) * 0.5\n );\n\n if (u_hasDepth) {\n float depth = texture2D(u_depthMap, uv).r;\n // White is close (1), Black is far (0).\n // By making the background move and the foreground stay still (using 1.0 - depth)\n // and subtracting the parallax, the background pulls the foreground over itself,\n // expanding the edges and creating proper occlusion, instead of collapsing/tearing.\n // depthTilt is scaled by 0.01 internally (so 100 = 1.0 peak displacement)\n vec2 parallax = u_mouse * (1.0 - depth) * (u_depthTilt * 0.01);\n uv -= parallax;\n }\n \n gl_FragColor = texture2D(u_image, uv);\n }\n "),this.gl.useProgram(this.program),this.positionBuffer=this.gl.createBuffer(),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,-1,1,1,-1,1,1]),this.gl.STATIC_DRAW),this.texture=this.gl.createTexture(),this.depthTexture=this.gl.createTexture(),window.addEventListener("mousemove",t=>{this.targetMouse.x=t.clientX/window.innerWidth*2-1,this.targetMouse.y=t.clientY/window.innerHeight*2-1}),this.animate()}setDepthTilt(t){this.depthTilt=t}createProgram(t,e){const n=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(n,t),this.gl.compileShader(n);const i=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(i,e),this.gl.compileShader(i);const s=this.gl.createProgram();return this.gl.attachShader(s,n),this.gl.attachShader(s,i),this.gl.linkProgram(s),s}render(t,e,n,i){this.gl.useProgram(this.program),this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,this.texture),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.gl.RGBA,this.gl.UNSIGNED_BYTE,t),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR),this.gl.activeTexture(this.gl.TEXTURE1),this.gl.bindTexture(this.gl.TEXTURE_2D,this.depthTexture),e&&(this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.gl.RGBA,this.gl.UNSIGNED_BYTE,e),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR)),this.gl.uniform1i(this.gl.getUniformLocation(this.program,"u_image"),0),this.gl.uniform1i(this.gl.getUniformLocation(this.program,"u_depthMap"),1),this.gl.uniform1i(this.gl.getUniformLocation(this.program,"u_hasDepth"),e?1:0),this.gl.uniform2f(this.gl.getUniformLocation(this.program,"u_resolution"),n,i),this.gl.uniform2f(this.gl.getUniformLocation(this.program,"u_imageResolution"),t.naturalWidth,t.naturalHeight);const s=this.gl.getAttribLocation(this.program,"a_position");this.gl.enableVertexAttribArray(s),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),this.gl.vertexAttribPointer(s,2,this.gl.FLOAT,!1,0,0),this.gl.viewport(0,0,n,i),this.draw()}draw(){this.gl.drawArrays(this.gl.TRIANGLES,0,6)}destroy(){cancelAnimationFrame(this.animationFrameId)}}var l=function(t,e,n,i){return new(n||(n=Promise))(function(s,r){function a(t){try{l(i.next(t))}catch(t){r(t)}}function o(t){try{l(i.throw(t))}catch(t){r(t)}}function l(t){var e;t.done?s(t.value):(e=t.value,e instanceof n?e:new n(function(t){t(e)})).then(a,o)}l((i=i.apply(t,e||[])).next())})};class h{constructor(t,e={}){this.currentFrame=-1,this.activeVariant=null,this.canvas=null,this.ctx=null,this.renderer=null,this.basePath="",this.scrub=0,this.depthTilt=4,this.targetProgress=0,this.currentProgress=0,this.rafId=0,this.destroyed=!1,this.imageCache=new Map,this.depthCache=new Map,this.scrollTimeout=null,this.trackingDataCache=new Map,this.config=t,this.basePath=t.settings.basePath||"",this.scrub=void 0!==e.scrub?e.scrub:0,this.depthTilt=void 0!==e.depthTilt?e.depthTilt:4,this.detectBestVariant(),this.boundResize=()=>{this.detectBestVariant(),this.resizeCanvas(),this.render()},window.addEventListener("resize",this.boundResize),this.updateLoop=this.updateLoop.bind(this),this.rafId=requestAnimationFrame(this.updateLoop)}destroy(){this.destroyed=!0,this.rafId&&cancelAnimationFrame(this.rafId),window.removeEventListener("resize",this.boundResize),this.scrollTimeout&&clearTimeout(this.scrollTimeout),this.clearCache(),this.trackingDataCache.clear(),this.canvas=null,this.ctx=null,this.renderer=null,this.onFrameChange=void 0}static init(t,e){return l(this,void 0,void 0,function*(){const n=yield fetch(e);if(!n.ok)throw new Error(`Failed to load config: ${n.statusText}`);const i=yield n.json(),s=e.substring(0,e.lastIndexOf("/"));i.settings||(i.settings={baseResolution:{width:1920,height:1080},scrollMode:"vh"}),i.settings.basePath=i.settings.basePath||s;const r=new h(i,{scrub:"object"==typeof i.settings?i.settings.scrub:0});let a=t.querySelector("canvas");return a||(a=document.createElement("canvas"),a.style.width="100%",a.style.height="100%",a.style.display="block",a.style.objectFit="cover",t.appendChild(a)),r.attachCanvas(a),r})}attachCanvas(t){this.canvas=t;try{this.renderer=new o(t,{depthTilt:this.depthTilt})}catch(e){console.warn("WebGL failed, falling back to 2D",e),this.ctx=t.getContext("2d",{alpha:!1})}this.resizeCanvas(),this.render()}resizeCanvas(){if(!this.canvas)return;const t=this.canvas.getBoundingClientRect(),e=t.width,n=t.height,i=window.devicePixelRatio||1;this.canvas.width=e*i,this.canvas.height=n*i,this.ctx&&this.ctx.scale(i,i)}detectBestVariant(){var t;const e=this.config.assets[0];if(!e)return;const n=this.canvas?this.canvas.getBoundingClientRect():{width:window.innerWidth,height:window.innerHeight},i=n.height>n.width,s=n.width*(window.devicePixelRatio||1),r=e.variants.filter(t=>{const e="portrait"===t.orientation||parseInt(t.aspectRatio.split(":")[1])>parseInt(t.aspectRatio.split(":")[0]);return i===e});r.sort((t,e)=>t.frameCount-e.frameCount);const a=r.find(t=>t.width>=s)||r[r.length-1];a?(null===(t=this.activeVariant)||void 0===t?void 0:t.id)!==a.id&&(console.log(`🎯 Variant Switched: ${a.id} (${i?"Portrait":"Landscape"})`),this.activeVariant=a,this.clearCache(),this.preloadInitial()):console.warn("[CoreEngine] No suitable variant found")}clearCache(){this.imageCache.clear(),this.depthCache.clear()}preloadInitial(){for(let t=0;t<15;t++)this.getImage(t)}update(t){this.targetProgress=Math.max(0,Math.min(1,t))}setDepthTilt(t){this.depthTilt=t,this.renderer&&this.renderer.setDepthTilt(t)}updateLoop(){if(this.destroyed)return;this.rafId=requestAnimationFrame(this.updateLoop);const t=this.scrub;if(t>0){const e=Math.max(.01,1-t);this.currentProgress+=(this.targetProgress-this.currentProgress)*e}else this.currentProgress=this.targetProgress;Math.abs(this.targetProgress-this.currentProgress)<1e-4&&(this.currentProgress=this.targetProgress),this.onProgressUpdate&&this.onProgressUpdate(this.currentProgress),this.calculateFrame(this.currentProgress)}calculateFrame(t){const e=this.config.timeline.scenes[0];if(!e)return;const n=e.assetRange[1]-e.assetRange[0],i=Math.floor(e.assetRange[0]+t*n),s=Math.max(0,Math.min(i,e.assetRange[1]));s!==this.currentFrame&&(this.currentFrame=s,this.render(),this.getImage(this.currentFrame+5),this.getImage(this.currentFrame+10),this.scrollTimeout&&clearTimeout(this.scrollTimeout),this.scrollTimeout=setTimeout(()=>{this.loadDepthMap(this.currentFrame)},100),this.onFrameChange&&this.onFrameChange(this.currentFrame,t))}loadTrackingData(t){return l(this,void 0,void 0,function*(){var e;if(!this.activeVariant)return;if(!(null===(e=this.activeVariant.subjects)||void 0===e?void 0:e.includes(t)))return void console.warn(`[CoreEngine] Subject ${t} not found in active variant ${this.activeVariant.id}`);const n=`${this.activeVariant.id}_${t}`;if(!this.trackingDataCache.has(n))try{const e=`${this.basePath?`${this.basePath}/`:""}${this.activeVariant.path}/000_tracking-${t}.json`;console.log(`[CoreEngine] Fetching tracking data: ${e}`);const i=yield fetch(e);if(!i.ok)throw new Error(i.statusText);const s=yield i.json();this.trackingDataCache.set(n,s)}catch(e){console.error(`[CoreEngine] Failed to load tracking data for ${t}`,e)}})}getTrackedCoords(t,e){if(!this.activeVariant||!this.canvas)return{x:.5,y:.5};const n=`${this.activeVariant.id}_${t}`,i=this.trackingDataCache.get(n);if(!i)return{x:.5,y:.5};const s=i.find(t=>t.frame===e);if(!s)return{x:.5,y:.5};const r=this.canvas.clientWidth/this.canvas.clientHeight,a=this.activeVariant.width/this.activeVariant.height,o=Math.min(r/a,1),l=Math.min(1/r/(1/a),1);return{x:(s.x-.5)/o+.5,y:(s.y-.5)/l+.5,scale:s.scale}}render(){var t;if(!this.canvas||-1===this.currentFrame)return;const e=this.getImage(this.currentFrame);if(!e||!e.complete)return;const n=this.canvas.clientWidth,i=this.canvas.clientHeight;let s=null;if((null===(t=this.activeVariant)||void 0===t?void 0:t.hasDepthMap)&&(s=this.getDepthImage(this.currentFrame),s&&!s.complete&&(s=null)),this.renderer)this.renderer.render(e,s,n*(window.devicePixelRatio||1),i*(window.devicePixelRatio||1));else if(this.ctx){const t=e.naturalWidth/e.naturalHeight;let s,r,a,o;t>n/i?(r=i,s=i*t,a=(n-s)/2,o=0):(s=n,r=n/t,a=0,o=(i-r)/2),this.ctx.clearRect(0,0,n,i),this.ctx.drawImage(e,a,o,s,r)}}getImage(t){if(!this.activeVariant)return null;if(t<0||t>=this.activeVariant.frameCount)return null;const e=`${this.activeVariant.id}_${t}`;if(this.imageCache.has(e))return this.imageCache.get(e);const n=this.basePath?`${this.basePath}/`:"",i=new Image;return i.crossOrigin="anonymous",i.src=`${n}${this.activeVariant.path}/index_${t}.webp`,i.onload=()=>{this.currentFrame===t&&this.render()},this.imageCache.set(e,i),i}loadDepthMap(t){var e;if(!(null===(e=this.activeVariant)||void 0===e?void 0:e.hasDepthMap))return void console.log("[CoreEngine] activeVariant does not define hasDepthMap=true");console.log(`[CoreEngine] Lazy requesting depth map for frame: ${t}`);this.getDepthImage(t)}getDepthImage(t){var e;if(!(null===(e=this.activeVariant)||void 0===e?void 0:e.hasDepthMap))return null;if(t<0||t>=this.activeVariant.frameCount)return null;const n=`${this.activeVariant.id}_depth_${t}`;if(this.depthCache.has(n))return this.depthCache.get(n);const i=this.basePath?`${this.basePath}/`:"";console.log(`[CoreEngine] Downloading: ${i}${this.activeVariant.path}/index_${t}_depth.webp`);const s=new Image;return s.crossOrigin="anonymous",s.src=`${i}${this.activeVariant.path}/index_${t}_depth.webp`,s.onload=()=>{console.log(`[CoreEngine] Depth map loaded for frame: ${t}`),this.currentFrame===t&&this.render()},s.onerror=e=>{console.error(`[CoreEngine] Depth map failed to load for frame: ${t}`,e)},this.depthCache.set(n,s),s}}const c=t=>t,u={},d=["setup","read","resolveKeyframes","preUpdate","update","preRender","render","postRender"],p={value:null,addProjectionMetrics:null};function f(t,e){let n=!1,i=!0;const s={delta:0,timestamp:0,isProcessing:!1},r=()=>n=!0,a=d.reduce((t,n)=>(t[n]=function(t,e){let n=new Set,i=new Set,s=!1,r=!1;const a=new WeakSet;let o={delta:0,timestamp:0,isProcessing:!1},l=0;function h(e){a.has(e)&&(c.schedule(e),t()),l++,e(o)}const c={schedule:(t,e=!1,r=!1)=>{const o=r&&s?n:i;return e&&a.add(t),o.add(t),t},cancel:t=>{i.delete(t),a.delete(t)},process:t=>{if(o=t,s)return void(r=!0);s=!0;const a=n;n=i,i=a,n.forEach(h),e&&p.value&&p.value.frameloop[e].push(l),l=0,n.clear(),s=!1,r&&(r=!1,c.process(t))}};return c}(r,e?n:void 0),t),{}),{setup:o,read:l,resolveKeyframes:h,preUpdate:c,update:f,preRender:m,render:g,postRender:y}=a,v=()=>{const r=u.useManualTiming,a=r?s.timestamp:performance.now();n=!1,r||(s.delta=i?1e3/60:Math.max(Math.min(a-s.timestamp,40),1)),s.timestamp=a,s.isProcessing=!0,o.process(s),l.process(s),h.process(s),c.process(s),f.process(s),m.process(s),g.process(s),y.process(s),s.isProcessing=!1,n&&e&&(i=!1,t(v))};return{schedule:d.reduce((e,r)=>{const o=a[r];return e[r]=(e,r=!1,a=!1)=>(n||(n=!0,i=!0,s.isProcessing||t(v)),o.schedule(e,r,a)),e},{}),cancel:t=>{for(let e=0;e<d.length;e++)a[d[e]].cancel(t)},state:s,steps:a}}const{schedule:m,cancel:g,state:y,steps:v}=f("undefined"!=typeof requestAnimationFrame?requestAnimationFrame:c,!0);function b(t,e){let n;const i=()=>{const{currentTime:i}=e,s=(null===i?0:i.value)/100;n!==s&&t(s),n=s};return m.preUpdate(i,!0),()=>g(i)}function T(t){let e;return()=>(void 0===e&&(e=t()),e)}const w={};function x(t,e){const n=T(t);return()=>w[e]??n()}const M=x(()=>void 0!==window.ScrollTimeline,"scrollTimeline"),S=x(()=>void 0!==window.ViewTimeline,"viewTimeline");function A(t){return"undefined"!=typeof window&&(t?S():M())}function E(t){return"object"==typeof t&&null!==t}function C(t){return E(t)&&"ownerSVGElement"in t}function k(t,e,n){if(null==t)return[];if(t instanceof EventTarget)return[t];if("string"==typeof t){let i=document;e&&(i=e.current);const s=n?.[t]??i.querySelectorAll(t);return s?Array.from(s):[]}return Array.from(t).filter(t=>null!=t)}const V=new WeakMap;let P;const R=(t,e,n)=>(i,s)=>s&&s[0]?s[0][t+"Size"]:C(i)&&"getBBox"in i?i.getBBox()[e]:i[n],F=R("inline","width","offsetWidth"),D=R("block","height","offsetHeight");function _({target:t,borderBoxSize:e}){V.get(t)?.forEach(n=>{n(t,{get width(){return F(t,e)},get height(){return D(t,e)}})})}function B(t){t.forEach(_)}function O(t,e){P||"undefined"!=typeof ResizeObserver&&(P=new ResizeObserver(B));const n=k(t);return n.forEach(t=>{let n=V.get(t);n||(n=new Set,V.set(t,n)),n.add(e),P?.observe(t)}),()=>{n.forEach(t=>{const n=V.get(t);n?.delete(e),n?.size||P?.unobserve(t)})}}const I=new Set;let L;function j(t){return I.add(t),L||(L=()=>{const t={get width(){return window.innerWidth},get height(){return window.innerHeight}};I.forEach(e=>e(t))},window.addEventListener("resize",L)),()=>{I.delete(t),I.size||"function"!=typeof L||(window.removeEventListener("resize",L),L=void 0)}}const $=(t,e,n)=>{const i=e-t;return 0===i?1:(n-t)/i};function W(t,e){return e?t*(1e3/e):0}const N={x:{length:"Width",position:"Left"},y:{length:"Height",position:"Top"}};function U(t,e,n,i){const s=n[e],{length:r,position:a}=N[e],o=s.current,l=n.time;s.current=Math.abs(t[`scroll${a}`]),s.scrollLength=t[`scroll${r}`]-t[`client${r}`],s.offset.length=0,s.offset[0]=0,s.offset[1]=s.scrollLength,s.progress=$(0,s.scrollLength,s.current);const h=i-l;s.velocity=h>50?0:W(s.current-o,h)}const X=(t,e)=>n=>e(t(n)),z=(...t)=>t.reduce(X);const K=(t,e,n)=>n>e?e:n<t?t:n,H=t=>e=>"string"==typeof e&&e.startsWith(t),Y=H("--"),q=H("var(--"),G=t=>!!q(t)&&Z.test(t.split("/*")[0].trim()),Z=/var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;function J(t){return"string"==typeof t&&t.split("/*")[0].includes("var(--")}const Q={test:t=>"number"==typeof t,parse:parseFloat,transform:t=>t},tt={...Q,transform:t=>K(0,1,t)},et={...Q,default:1},nt=t=>Math.round(1e5*t)/1e5,it=/-?(?:\d+(?:\.\d+)?|\.\d+)/gu;const st=/^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu,rt=(t,e)=>n=>Boolean("string"==typeof n&&st.test(n)&&n.startsWith(t)||e&&!function(t){return null==t}(n)&&Object.prototype.hasOwnProperty.call(n,e)),at=(t,e,n)=>i=>{if("string"!=typeof i)return i;const[s,r,a,o]=i.match(it);return{[t]:parseFloat(s),[e]:parseFloat(r),[n]:parseFloat(a),alpha:void 0!==o?parseFloat(o):1}},ot={...Q,transform:t=>Math.round((t=>K(0,255,t))(t))},lt={test:rt("rgb","red"),parse:at("red","green","blue"),transform:({red:t,green:e,blue:n,alpha:i=1})=>"rgba("+ot.transform(t)+", "+ot.transform(e)+", "+ot.transform(n)+", "+nt(tt.transform(i))+")"};const ht={test:rt("#"),parse:function(t){let e="",n="",i="",s="";return t.length>5?(e=t.substring(1,3),n=t.substring(3,5),i=t.substring(5,7),s=t.substring(7,9)):(e=t.substring(1,2),n=t.substring(2,3),i=t.substring(3,4),s=t.substring(4,5),e+=e,n+=n,i+=i,s+=s),{red:parseInt(e,16),green:parseInt(n,16),blue:parseInt(i,16),alpha:s?parseInt(s,16)/255:1}},transform:lt.transform},ct=t=>({test:e=>"string"==typeof e&&e.endsWith(t)&&1===e.split(" ").length,parse:parseFloat,transform:e=>`${e}${t}`}),ut=ct("deg"),dt=ct("%"),pt=ct("px"),ft=ct("vh"),mt=ct("vw"),gt=(()=>({...dt,parse:t=>dt.parse(t)/100,transform:t=>dt.transform(100*t)}))(),yt={test:rt("hsl","hue"),parse:at("hue","saturation","lightness"),transform:({hue:t,saturation:e,lightness:n,alpha:i=1})=>"hsla("+Math.round(t)+", "+dt.transform(nt(e))+", "+dt.transform(nt(n))+", "+nt(tt.transform(i))+")"},vt={test:t=>lt.test(t)||ht.test(t)||yt.test(t),parse:t=>lt.test(t)?lt.parse(t):yt.test(t)?yt.parse(t):ht.parse(t),transform:t=>"string"==typeof t?t:t.hasOwnProperty("red")?lt.transform(t):yt.transform(t),getAnimatableNone:t=>{const e=vt.parse(t);return e.alpha=0,vt.transform(e)}},bt=/(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;const Tt="number",wt="color",xt=/var\s*\(\s*--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)|#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\)|-?(?:\d+(?:\.\d+)?|\.\d+)/giu;function Mt(t){const e=t.toString(),n=[],i={color:[],number:[],var:[]},s=[];let r=0;const a=e.replace(xt,t=>(vt.test(t)?(i.color.push(r),s.push(wt),n.push(vt.parse(t))):t.startsWith("var(")?(i.var.push(r),s.push("var"),n.push(t)):(i.number.push(r),s.push(Tt),n.push(parseFloat(t))),++r,"${}")).split("${}");return{values:n,split:a,indexes:i,types:s}}function St({split:t,types:e}){const n=t.length;return i=>{let s="";for(let r=0;r<n;r++)if(s+=t[r],void 0!==i[r]){const t=e[r];s+=t===Tt?nt(i[r]):t===wt?vt.transform(i[r]):i[r]}return s}}const At=(t,e)=>{return"number"==typeof t?e?.trim().endsWith("/")?t:0:"number"==typeof(n=t)?0:vt.test(n)?vt.getAnimatableNone(n):n;var n};const Et={test:function(t){return isNaN(t)&&"string"==typeof t&&(t.match(it)?.length||0)+(t.match(bt)?.length||0)>0},parse:function(t){return Mt(t).values},createTransformer:function(t){return St(Mt(t))},getAnimatableNone:function(t){const e=Mt(t);return St(e)(e.values.map((t,n)=>At(t,e.split[n])))}};function Ct(t,e,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?t+6*(e-t)*n:n<.5?e:n<2/3?t+(e-t)*(2/3-n)*6:t}function kt(t,e){return n=>n>0?e:t}const Vt=(t,e,n)=>t+(e-t)*n,Pt=(t,e,n)=>{const i=t*t,s=n*(e*e-i)+i;return s<0?0:Math.sqrt(s)},Rt=[ht,lt,yt];function Ft(t){const e=(n=t,Rt.find(t=>t.test(n)));var n;if(Boolean(e),!Boolean(e))return!1;let i=e.parse(t);return e===yt&&(i=function({hue:t,saturation:e,lightness:n,alpha:i}){t/=360,n/=100;let s=0,r=0,a=0;if(e/=100){const i=n<.5?n*(1+e):n+e-n*e,o=2*n-i;s=Ct(o,i,t+1/3),r=Ct(o,i,t),a=Ct(o,i,t-1/3)}else s=r=a=n;return{red:Math.round(255*s),green:Math.round(255*r),blue:Math.round(255*a),alpha:i}}(i)),i}const Dt=(t,e)=>{const n=Ft(t),i=Ft(e);if(!n||!i)return kt(t,e);const s={...n};return t=>(s.red=Pt(n.red,i.red,t),s.green=Pt(n.green,i.green,t),s.blue=Pt(n.blue,i.blue,t),s.alpha=Vt(n.alpha,i.alpha,t),lt.transform(s))},_t=new Set(["none","hidden"]);function Bt(t,e){return n=>Vt(t,e,n)}function Ot(t){return"number"==typeof t?Bt:"string"==typeof t?G(t)?kt:vt.test(t)?Dt:jt:Array.isArray(t)?It:"object"==typeof t?vt.test(t)?Dt:Lt:kt}function It(t,e){const n=[...t],i=n.length,s=t.map((t,n)=>Ot(t)(t,e[n]));return t=>{for(let e=0;e<i;e++)n[e]=s[e](t);return n}}function Lt(t,e){const n={...t,...e},i={};for(const s in n)void 0!==t[s]&&void 0!==e[s]&&(i[s]=Ot(t[s])(t[s],e[s]));return t=>{for(const e in i)n[e]=i[e](t);return n}}const jt=(t,e)=>{const n=Et.createTransformer(e),i=Mt(t),s=Mt(e);return i.indexes.var.length===s.indexes.var.length&&i.indexes.color.length===s.indexes.color.length&&i.indexes.number.length>=s.indexes.number.length?_t.has(t)&&!s.values.length||_t.has(e)&&!i.values.length?function(t,e){return _t.has(t)?n=>n<=0?t:e:n=>n>=1?e:t}(t,e):z(It(function(t,e){const n=[],i={color:0,var:0,number:0};for(let s=0;s<e.values.length;s++){const r=e.types[s],a=t.indexes[r][i[r]],o=t.values[a]??0;n[s]=o,i[r]++}return n}(i,s),s.values),n):kt(t,e)};function $t(t,e,n){if("number"==typeof t&&"number"==typeof e&&"number"==typeof n)return Vt(t,e,n);return Ot(t)(t,e)}function Wt(t,e,{clamp:n=!0,ease:i,mixer:s}={}){const r=t.length;if(e.length,1===r)return()=>e[0];if(2===r&&e[0]===e[1])return()=>e[1];const a=t[0]===t[1];t[0]>t[r-1]&&(t=[...t].reverse(),e=[...e].reverse());const o=function(t,e,n){const i=[],s=n||u.mix||$t,r=t.length-1;for(let n=0;n<r;n++){let r=s(t[n],t[n+1]);if(e){const t=Array.isArray(e)?e[n]||c:e;r=z(t,r)}i.push(r)}return i}(e,i,s),l=o.length,h=n=>{if(a&&n<t[0])return e[0];let i=0;if(l>1)for(;i<t.length-2&&!(n<t[i+1]);i++);const s=$(t[i],t[i+1],n);return o[i](s)};return n?e=>h(K(t[0],t[r-1],e)):h}function Nt(t,e){const n=t[t.length-1];for(let i=1;i<=e;i++){const s=$(0,e,i);t.push(Vt(n,1,s))}}function Ut(t){const e=[0];return Nt(e,t.length-1),e}function Xt(t){return E(t)&&"offsetHeight"in t&&!("ownerSVGElement"in t)}const zt={start:0,center:.5,end:1};function Kt(t,e,n=0){let i=0;if(t in zt&&(t=zt[t]),"string"==typeof t){const e=parseFloat(t);t.endsWith("px")?i=e:t.endsWith("%")?t=e/100:t.endsWith("vw")?i=e/100*document.documentElement.clientWidth:t.endsWith("vh")?i=e/100*document.documentElement.clientHeight:t=e}return"number"==typeof t&&(i=e*t),n+i}const Ht=[0,0];function Yt(t,e,n,i){let s=Array.isArray(t)?t:Ht,r=0,a=0;return"number"==typeof t?s=[t,t]:"string"==typeof t&&(s=(t=t.trim()).includes(" ")?t.split(" "):[t,zt[t]?t:"0"]),r=Kt(s[0],n,i),a=Kt(s[1],e),r-a}const qt={Enter:[[0,1],[1,1]],Exit:[[0,0],[1,0]],Any:[[1,0],[0,1]],All:[[0,0],[1,1]]},Gt={x:0,y:0};function Zt(t,e,n){const{offset:i=qt.All}=n,{target:s=t,axis:r="y"}=n,a="y"===r?"height":"width",o=s!==t?function(t,e){const n={x:0,y:0};let i=t;for(;i&&i!==e;)if(Xt(i))n.x+=i.offsetLeft,n.y+=i.offsetTop,i=i.offsetParent;else if("svg"===i.tagName){const t=i.getBoundingClientRect();i=i.parentElement;const e=i.getBoundingClientRect();n.x+=t.left-e.left,n.y+=t.top-e.top}else{if(!(i instanceof SVGGraphicsElement))break;{const{x:t,y:e}=i.getBBox();n.x+=t,n.y+=e;let s=null,r=i.parentNode;for(;!s;)"svg"===r.tagName&&(s=r),r=i.parentNode;i=s}}return n}(s,t):Gt,l=s===t?{width:t.scrollWidth,height:t.scrollHeight}:function(t){return"getBBox"in t&&"svg"!==t.tagName?t.getBBox():{width:t.clientWidth,height:t.clientHeight}}(s),h={width:t.clientWidth,height:t.clientHeight};e[r].offset.length=0;let c=!e[r].interpolate;const u=i.length;for(let t=0;t<u;t++){const n=Yt(i[t],h[a],l[a],o[r]);c||n===e[r].interpolatorOffsets[t]||(c=!0),e[r].offset[t]=n}c&&(e[r].interpolate=Wt(e[r].offset,Ut(i),{clamp:!1}),e[r].interpolatorOffsets=[...e[r].offset]),e[r].progress=K(0,1,e[r].interpolate(e[r].current))}function Jt(t,e,n,i={}){return{measure:e=>{!function(t,e=t,n){if(n.x.targetOffset=0,n.y.targetOffset=0,e!==t){let i=e;for(;i&&i!==t;)n.x.targetOffset+=i.offsetLeft,n.y.targetOffset+=i.offsetTop,i=i.offsetParent}n.x.targetLength=e===t?e.scrollWidth:e.clientWidth,n.y.targetLength=e===t?e.scrollHeight:e.clientHeight,n.x.containerLength=t.clientWidth,n.y.containerLength=t.clientHeight}(t,i.target,n),function(t,e,n){U(t,"x",e,n),U(t,"y",e,n),e.time=n}(t,n,e),(i.offset||i.target)&&Zt(t,n,i)},notify:()=>e(n)}}const Qt=new WeakMap,te=new WeakMap,ee=new WeakMap,ne=new WeakMap,ie=new WeakMap,se=t=>t===document.scrollingElement?window:t;function re(t,{container:e=document.scrollingElement,trackContentSize:n=!1,...i}={}){if(!e)return c;let s=ee.get(e);s||(s=new Set,ee.set(e,s));const r=Jt(e,t,{time:0,x:{current:0,offset:[],progress:0,scrollLength:0,targetOffset:0,targetLength:0,containerLength:0,velocity:0},y:{current:0,offset:[],progress:0,scrollLength:0,targetOffset:0,targetLength:0,containerLength:0,velocity:0}},i);if(s.add(r),!Qt.has(e)){const t=()=>{for(const t of s)t.measure(y.timestamp);m.preUpdate(n)},n=()=>{for(const t of s)t.notify()},i=()=>m.read(t);Qt.set(e,i);const r=se(e);window.addEventListener("resize",i),e!==document.documentElement&&te.set(e,(o=i,"function"==typeof(a=e)?j(a):O(a,o))),r.addEventListener("scroll",i),i()}var a,o;if(n&&!ie.has(e)){const t=Qt.get(e),n={width:e.scrollWidth,height:e.scrollHeight};ne.set(e,n);const i=()=>{const i=e.scrollWidth,s=e.scrollHeight;n.width===i&&n.height===s||(t(),n.width=i,n.height=s)},s=m.read(i,!0);ie.set(e,s)}const l=Qt.get(e);return m.read(l,!1,!0),()=>{g(l);const t=ee.get(e);if(!t)return;if(t.delete(r),t.size)return;const n=Qt.get(e);Qt.delete(e),n&&(se(e).removeEventListener("scroll",n),te.get(e)?.(),window.removeEventListener("resize",n));const i=ie.get(e);i&&(g(i),ie.delete(e)),ne.delete(e)}}const ae=[[qt.Enter,"entry"],[qt.Exit,"exit"],[qt.Any,"cover"],[qt.All,"contain"]];function oe(t,e){if(2!==t.length)return!1;for(let n=0;n<2;n++){const i=t[n],s=e[n];if(!Array.isArray(i)||2!==i.length||i[0]!==s[0]||i[1]!==s[1])return!1}return!0}function le(t){if(!t)return{rangeStart:"contain 0%",rangeEnd:"contain 100%"};for(const[e,n]of ae)if(oe(t,e))return{rangeStart:`${n} 0%`,rangeEnd:`${n} 100%`}}const he=new Map;function ce(t){const e={value:0},n=re(n=>{e.value=100*n[t.axis].progress},t);return{currentTime:e,cancel:n}}function ue({source:t,container:e,...n}){const{axis:i}=n;t&&(e=t);let s=he.get(e);s||(s=new Map,he.set(e,s));const r=n.target??"self";let a=s.get(r);a||(a={},s.set(r,a));const o=i+(n.offset??[]).join(",");if(!a[o])if(n.target&&A(n.target)){const t=le(n.offset);a[o]=t?new ViewTimeline({subject:n.target,axis:i}):ce({container:e,...n})}else A()?a[o]=new ScrollTimeline({source:e,axis:i}):a[o]=ce({container:e,...n});return a[o]}function de(t,{axis:e="y",container:n=document.scrollingElement,...i}={}){if(!n)return c;const s={axis:e,container:n,...i};return"function"==typeof t?function(t,e){return function(t){return 2===t.length}(t)?re(n=>{t(n[e.axis].progress,n)},e):b(t,ue(e))}(t,s):function(t,e){const n=ue(e),i=e.target?le(e.offset):void 0,s=e.target?A(e.target)&&!!i:A();return t.attachTimeline({timeline:s?n:void 0,...i&&s&&{rangeStart:i.rangeStart,rangeEnd:i.rangeEnd},observe:t=>(t.pause(),b(e=>{t.time=t.iterationDuration*e},n))})}(t,s)}class pe{constructor(t){this.stop=()=>this.runAll("stop"),this.animations=t.filter(Boolean)}get finished(){return Promise.all(this.animations.map(t=>t.finished))}getAll(t){return this.animations[0][t]}setAll(t,e){for(let n=0;n<this.animations.length;n++)this.animations[n][t]=e}attachTimeline(t){const e=this.animations.map(e=>e.attachTimeline(t));return()=>{e.forEach((t,e)=>{t&&t(),this.animations[e].stop()})}}get time(){return this.getAll("time")}set time(t){this.setAll("time",t)}get speed(){return this.getAll("speed")}set speed(t){this.setAll("speed",t)}get state(){return this.getAll("state")}get startTime(){return this.getAll("startTime")}get duration(){return fe(this.animations,"duration")}get iterationDuration(){return fe(this.animations,"iterationDuration")}runAll(t){this.animations.forEach(e=>e[t]())}play(){this.runAll("play")}pause(){this.runAll("pause")}cancel(){this.runAll("cancel")}complete(){this.runAll("complete")}}function fe(t,e){let n=0;for(let i=0;i<t.length;i++){const s=t[i][e];null!==s&&s>n&&(n=s)}return n}class me extends pe{then(t,e){return this.finished.finally(t).then(()=>{})}}function ge(t,e){const n=t.indexOf(e);n>-1&&t.splice(n,1)}class ye{constructor(){this.subscriptions=[]}add(t){var e,n;return e=this.subscriptions,n=t,-1===e.indexOf(n)&&e.push(n),()=>ge(this.subscriptions,t)}notify(t,e,n){const i=this.subscriptions.length;if(i)if(1===i)this.subscriptions[0](t,e,n);else for(let s=0;s<i;s++){const i=this.subscriptions[s];i&&i(t,e,n)}}getSize(){return this.subscriptions.length}clear(){this.subscriptions.length=0}}let ve;function be(){ve=void 0}const Te={now:()=>(void 0===ve&&Te.set(y.isProcessing||u.useManualTiming?y.timestamp:performance.now()),ve),set:t=>{ve=t,queueMicrotask(be)}},we={current:void 0};class xe{constructor(t,e={}){this.canTrackVelocity=null,this.events={},this.updateAndNotify=t=>{const e=Te.now();if(this.updatedAt!==e&&this.setPrevFrameValue(),this.prev=this.current,this.setCurrent(t),this.current!==this.prev&&(this.events.change?.notify(this.current),this.dependents))for(const t of this.dependents)t.dirty()},this.hasAnimated=!1,this.setCurrent(t),this.owner=e.owner}setCurrent(t){var e;this.current=t,this.updatedAt=Te.now(),null===this.canTrackVelocity&&void 0!==t&&(this.canTrackVelocity=(e=this.current,!isNaN(parseFloat(e))))}setPrevFrameValue(t=this.current){this.prevFrameValue=t,this.prevUpdatedAt=this.updatedAt}onChange(t){return this.on("change",t)}on(t,e){this.events[t]||(this.events[t]=new ye);const n=this.events[t].add(e);return"change"===t?()=>{n(),m.read(()=>{this.events.change.getSize()||this.stop()})}:n}clearListeners(){for(const t in this.events)this.events[t].clear()}attach(t,e){this.passiveEffect=t,this.stopPassiveEffect=e}set(t){this.passiveEffect?this.passiveEffect(t,this.updateAndNotify):this.updateAndNotify(t)}setWithVelocity(t,e,n){this.set(e),this.prev=void 0,this.prevFrameValue=t,this.prevUpdatedAt=this.updatedAt-n}jump(t,e=!0){this.updateAndNotify(t),this.prev=t,this.prevUpdatedAt=this.prevFrameValue=void 0,e&&this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}dirty(){this.events.change?.notify(this.current)}addDependent(t){this.dependents||(this.dependents=new Set),this.dependents.add(t)}removeDependent(t){this.dependents&&this.dependents.delete(t)}get(){return we.current&&we.current.push(this),this.current}getPrevious(){return this.prev}getVelocity(){const t=Te.now();if(!this.canTrackVelocity||void 0===this.prevFrameValue||t-this.updatedAt>30)return 0;const e=Math.min(this.updatedAt-this.prevUpdatedAt,30);return W(parseFloat(this.current)-parseFloat(this.prevFrameValue),e)}start(t){return this.stop(),new Promise(e=>{this.hasAnimated=!0,this.animation=t(e),this.events.animationStart&&this.events.animationStart.notify()}).then(()=>{this.events.animationComplete&&this.events.animationComplete.notify(),this.clearAnimation()})}stop(){this.animation&&(this.animation.stop(),this.events.animationCancel&&this.events.animationCancel.notify()),this.clearAnimation()}isAnimating(){return!!this.animation}clearAnimation(){delete this.animation}destroy(){this.dependents?.clear(),this.events.destroy?.notify(),this.clearListeners(),this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}}function Me(t,e){return new xe(t,e)}const Se=t=>1e3*t,Ae=t=>t/1e3,Ee=(t,e,n=10)=>{let i="";const s=Math.max(Math.round(e/n),2);for(let e=0;e<s;e++)i+=Math.round(1e4*t(e/(s-1)))/1e4+", ";return`linear(${i.substring(0,i.length-2)})`},Ce=2e4;function ke(t){let e=0;let n=t.next(e);for(;!n.done&&e<Ce;)e+=50,n=t.next(e);return e>=Ce?1/0:e}function Ve(t,e=100,n){const i=n({...t,keyframes:[0,e]}),s=Math.min(ke(i),Ce);return{type:"keyframes",ease:t=>i.next(s*t).value/e,duration:Ae(s)}}const Pe=100,Re=10,Fe=1,De=0,_e=800,Be=.3,Oe=.3,Ie={granular:.01,default:2},Le={granular:.005,default:.5},je=.01,$e=10,We=.05,Ne=1;function Ue(t,e){return t*Math.sqrt(1-e*e)}const Xe=.001;const ze=["duration","bounce"],Ke=["stiffness","damping","mass"];function He(t,e){return e.some(e=>void 0!==t[e])}function Ye(t){let e={velocity:De,stiffness:Pe,damping:Re,mass:Fe,isResolvedFromDuration:!1,...t};if(!He(t,Ke)&&He(t,ze))if(e.velocity=0,t.visualDuration){const n=t.visualDuration,i=2*Math.PI/(1.2*n),s=i*i,r=2*K(.05,1,1-(t.bounce||0))*Math.sqrt(s);e={...e,mass:Fe,stiffness:s,damping:r}}else{const n=function({duration:t=_e,bounce:e=Be,velocity:n=De,mass:i=Fe}){let s,r;Se($e);let a=1-e;a=K(We,Ne,a),t=K(je,$e,Ae(t)),a<1?(s=e=>{const i=e*a,s=i*t,r=i-n,o=Ue(e,a),l=Math.exp(-s);return Xe-r/o*l},r=e=>{const i=e*a*t,r=i*n+n,o=Math.pow(a,2)*Math.pow(e,2)*t,l=Math.exp(-i),h=Ue(Math.pow(e,2),a);return(-s(e)+Xe>0?-1:1)*((r-o)*l)/h}):(s=e=>Math.exp(-e*t)*((e-n)*t+1)-.001,r=e=>Math.exp(-e*t)*(t*t*(n-e)));const o=function(t,e,n){let i=n;for(let n=1;n<12;n++)i-=t(i)/e(i);return i}(s,r,5/t);if(t=Se(t),isNaN(o))return{stiffness:Pe,damping:Re,duration:t};{const e=Math.pow(o,2)*i;return{stiffness:e,damping:2*a*Math.sqrt(i*e),duration:t}}}({...t,velocity:0});e={...e,...n,mass:Fe},e.isResolvedFromDuration=!0}return e}function qe(t=Oe,e=Be){const n="object"!=typeof t?{visualDuration:t,keyframes:[0,1],bounce:e}:t;let{restSpeed:i,restDelta:s}=n;const r=n.keyframes[0],a=n.keyframes[n.keyframes.length-1],o={done:!1,value:r},{stiffness:l,damping:h,mass:c,duration:u,velocity:d,isResolvedFromDuration:p}=Ye({...n,velocity:-Ae(n.velocity||0)}),f=d||0,m=h/(2*Math.sqrt(l*c)),g=a-r,y=Ae(Math.sqrt(l/c)),v=Math.abs(g)<5;let b,T,w,x,M,S;if(i||(i=v?Ie.granular:Ie.default),s||(s=v?Le.granular:Le.default),m<1)w=Ue(y,m),x=(f+m*y*g)/w,b=t=>{const e=Math.exp(-m*y*t);return a-e*(x*Math.sin(w*t)+g*Math.cos(w*t))},M=m*y*x+g*w,S=m*y*g-x*w,T=t=>Math.exp(-m*y*t)*(M*Math.sin(w*t)+S*Math.cos(w*t));else if(1===m){b=t=>a-Math.exp(-y*t)*(g+(f+y*g)*t);const t=f+y*g;T=e=>Math.exp(-y*e)*(y*t*e-f)}else{const t=y*Math.sqrt(m*m-1);b=e=>{const n=Math.exp(-m*y*e),i=Math.min(t*e,300);return a-n*((f+m*y*g)*Math.sinh(i)+t*g*Math.cosh(i))/t};const e=(f+m*y*g)/t,n=m*y*e-g*t,i=m*y*g-e*t;T=e=>{const s=Math.exp(-m*y*e),r=Math.min(t*e,300);return s*(n*Math.sinh(r)+i*Math.cosh(r))}}const A={calculatedDuration:p&&u||null,velocity:t=>Se(T(t)),next:t=>{if(!p&&m<1){const e=Math.exp(-m*y*t),n=Math.sin(w*t),r=Math.cos(w*t),l=a-e*(x*n+g*r),h=Se(e*(M*n+S*r));return o.done=Math.abs(h)<=i&&Math.abs(a-l)<=s,o.value=o.done?a:l,o}const e=b(t);if(p)o.done=t>=u;else{const n=Se(T(t));o.done=Math.abs(n)<=i&&Math.abs(a-e)<=s}return o.value=o.done?a:e,o},toString:()=>{const t=Math.min(ke(A),Ce),e=Ee(e=>A.next(t*e).value,t,30);return t+"ms "+e},toTransition:()=>{}};return A}function Ge(t){return"function"==typeof t&&"applyToOptions"in t}qe.applyToOptions=t=>{const e=Ve(t,100,qe);return t.ease=e.ease,t.duration=Se(e.duration),t.type="keyframes",t};const Ze=t=>Boolean(t&&t.getVelocity),Je=t=>Array.isArray(t)&&"number"!=typeof t[0];function Qe(t,e){return Je(t)?t[((t,e,n)=>{const i=e-t;return((n-t)%i+i)%i+t})(0,t.length,e)]:t}function tn(t){return"object"==typeof t&&!Array.isArray(t)}function en(t,e,n,i){return null==t?[]:"string"==typeof t&&tn(e)?k(t,n,i):t instanceof NodeList?Array.from(t):Array.isArray(t)?t.filter(t=>null!=t):[t]}function nn(t,e,n){return t*(e+1)}function sn(t,e,n,i){return"number"==typeof e?e:e.startsWith("-")||e.startsWith("+")?Math.max(0,t+parseFloat(e)):"<"===e?n:e.startsWith("<")?Math.max(0,n+parseFloat(e.slice(1))):i.get(e)??t}function rn(t,e,n,i,s,r){!function(t,e,n){for(let i=0;i<t.length;i++){const s=t[i];s.at>e&&s.at<n&&(ge(t,s),i--)}}(t,s,r);for(let a=0;a<e.length;a++)t.push({value:e[a],at:Vt(s,r,i[a]),easing:Qe(n,a)})}function an(t,e){for(let n=0;n<t.length;n++)t[n]=t[n]/(e+1)}function on(t,e){return t.at===e.at?null===t.value?1:null===e.value?-1:0:t.at-e.at}function ln(t,e){return!e.has(t)&&e.set(t,{}),e.get(t)}function hn(t,e){return e[t]||(e[t]=[]),e[t]}function cn(t){return Array.isArray(t)?t:[t]}function un(t,e){return t&&t[e]?{...t,...t[e]}:{...t}}const dn=t=>"number"==typeof t,pn=t=>t.every(dn),fn={layout:0,mainThread:0,waapi:0},mn=t=>{const e=({timestamp:e})=>t(e);return{start:(t=!0)=>m.update(e,t),stop:()=>g(e),now:()=>y.isProcessing?y.timestamp:Te.now()}};function gn(t,e,n){const i=Math.max(e-5,0);return W(n-t(i),e-i)}function yn({keyframes:t,velocity:e=0,power:n=.8,timeConstant:i=325,bounceDamping:s=10,bounceStiffness:r=500,modifyTarget:a,min:o,max:l,restDelta:h=.5,restSpeed:c}){const u=t[0],d={done:!1,value:u},p=t=>void 0===o?l:void 0===l||Math.abs(o-t)<Math.abs(l-t)?o:l;let f=n*e;const m=u+f,g=void 0===a?m:a(m);g!==m&&(f=g-u);const y=t=>-f*Math.exp(-t/i),v=t=>g+y(t),b=t=>{const e=y(t),n=v(t);d.done=Math.abs(e)<=h,d.value=d.done?g:n};let T,w;const x=t=>{var e;(e=d.value,void 0!==o&&e<o||void 0!==l&&e>l)&&(T=t,w=qe({keyframes:[d.value,p(d.value)],velocity:gn(v,t,d.value),damping:s,stiffness:r,restDelta:h,restSpeed:c}))};return x(0),{calculatedDuration:null,next:t=>{let e=!1;return w||void 0!==T||(e=!0,b(t),x(t)),void 0!==T&&t>=T?w.next(t-T):(!e&&b(t),d)}}}const vn=(t,e,n)=>(((1-3*n+3*e)*t+(3*n-6*e))*t+3*e)*t;function bn(t,e,n,i){if(t===e&&n===i)return c;const s=e=>function(t,e,n,i,s){let r,a,o=0;do{a=e+(n-e)/2,r=vn(a,i,s)-t,r>0?n=a:e=a}while(Math.abs(r)>1e-7&&++o<12);return a}(e,0,1,t,n);return t=>0===t||1===t?t:vn(s(t),e,i)}const Tn=bn(.42,0,1,1),wn=bn(0,0,.58,1),xn=bn(.42,0,.58,1),Mn=t=>e=>e<=.5?t(2*e)/2:(2-t(2*(1-e)))/2,Sn=t=>e=>1-t(1-e),An=bn(.33,1.53,.69,.99),En=Sn(An),Cn=Mn(En),kn=t=>t>=1?1:(t*=2)<1?.5*En(t):.5*(2-Math.pow(2,-10*(t-1))),Vn=t=>1-Math.sin(Math.acos(t)),Pn=Sn(Vn),Rn=Mn(Vn),Fn=t=>Array.isArray(t)&&"number"==typeof t[0],Dn={linear:c,easeIn:Tn,easeInOut:xn,easeOut:wn,circIn:Vn,circInOut:Rn,circOut:Pn,backIn:En,backInOut:Cn,backOut:An,anticipate:kn},_n=t=>{if(Fn(t)){t.length;const[e,n,i,s]=t;return bn(e,n,i,s)}return"string"==typeof t?Dn[t]:t};function Bn({duration:t=300,keyframes:e,times:n,ease:i="easeInOut"}){const s=Je(i)?i.map(_n):_n(i),r={done:!1,value:e[0]},a=function(t,e){return t.map(t=>t*e)}(n&&n.length===e.length?n:Ut(e),t),o=Wt(a,e,{ease:Array.isArray(s)?s:(l=e,h=s,l.map(()=>h||xn).splice(0,l.length-1))});var l,h;return{calculatedDuration:t,next:e=>(r.value=o(e),r.done=e>=t,r)}}const On=t=>null!==t;function In(t,{repeat:e,repeatType:n="loop"},i,s=1){const r=t.filter(On),a=s<0||e&&"loop"!==n&&e%2==1?0:r.length-1;return a&&void 0!==i?i:r[a]}const Ln={decay:yn,inertia:yn,tween:Bn,keyframes:Bn,spring:qe};function jn(t){"string"==typeof t.type&&(t.type=Ln[t.type])}class $n{constructor(){this.updateFinished()}get finished(){return this._finished}updateFinished(){this._finished=new Promise(t=>{this.resolve=t})}notifyFinished(){this.resolve()}then(t,e){return this.finished.then(t,e)}}const Wn=t=>t/100;class Nn extends $n{constructor(t){super(),this.state="idle",this.startTime=null,this.isStopped=!1,this.currentTime=0,this.holdTime=null,this.playbackSpeed=1,this.stop=()=>{const{motionValue:t}=this.options;t&&t.updatedAt!==Te.now()&&this.tick(Te.now()),this.isStopped=!0,"idle"!==this.state&&(this.teardown(),this.options.onStop?.())},fn.mainThread++,this.options=t,this.initAnimation(),this.play(),!1===t.autoplay&&this.pause()}initAnimation(){const{options:t}=this;jn(t);const{type:e=Bn,repeat:n=0,repeatDelay:i=0,repeatType:s,velocity:r=0}=t;let{keyframes:a}=t;const o=e||Bn;o!==Bn&&"number"!=typeof a[0]&&(this.mixKeyframes=z(Wn,$t(a[0],a[1])),a=[0,100]);const l=o({...t,keyframes:a});"mirror"===s&&(this.mirroredGenerator=o({...t,keyframes:[...a].reverse(),velocity:-r})),null===l.calculatedDuration&&(l.calculatedDuration=ke(l));const{calculatedDuration:h}=l;this.calculatedDuration=h,this.resolvedDuration=h+i,this.totalDuration=this.resolvedDuration*(n+1)-i,this.generator=l}updateTime(t){const e=Math.round(t-this.startTime)*this.playbackSpeed;null!==this.holdTime?this.currentTime=this.holdTime:this.currentTime=e}tick(t,e=!1){const{generator:n,totalDuration:i,mixKeyframes:s,mirroredGenerator:r,resolvedDuration:a,calculatedDuration:o}=this;if(null===this.startTime)return n.next(0);const{delay:l=0,keyframes:h,repeat:c,repeatType:u,repeatDelay:d,type:p,onUpdate:f,finalKeyframe:m}=this.options;this.speed>0?this.startTime=Math.min(this.startTime,t):this.speed<0&&(this.startTime=Math.min(t-i/this.speed,this.startTime)),e?this.currentTime=t:this.updateTime(t);const g=this.currentTime-l*(this.playbackSpeed>=0?1:-1),y=this.playbackSpeed>=0?g<0:g>i;this.currentTime=Math.max(g,0),"finished"===this.state&&null===this.holdTime&&(this.currentTime=i);let v=this.currentTime,b=n;if(c){const t=Math.min(this.currentTime,i)/a;let e=Math.floor(t),n=t%1;!n&&t>=1&&(n=1),1===n&&e--,e=Math.min(e,c+1);Boolean(e%2)&&("reverse"===u?(n=1-n,d&&(n-=d/a)):"mirror"===u&&(b=r)),v=K(0,1,n)*a}const T=y?{done:!1,value:h[0]}:b.next(v);s&&!y&&(T.value=s(T.value));let{done:w}=T;y||null===o||(w=this.playbackSpeed>=0?this.currentTime>=i:this.currentTime<=0);const x=null===this.holdTime&&("finished"===this.state||"running"===this.state&&w);return x&&p!==yn&&(T.value=In(h,this.options,m,this.speed)),f&&f(T.value),x&&this.finish(),T}then(t,e){return this.finished.then(t,e)}get duration(){return Ae(this.calculatedDuration)}get iterationDuration(){const{delay:t=0}=this.options||{};return this.duration+Ae(t)}get time(){return Ae(this.currentTime)}set time(t){t=Se(t),this.currentTime=t,null===this.startTime||null!==this.holdTime||0===this.playbackSpeed?this.holdTime=t:this.driver&&(this.startTime=this.driver.now()-t/this.playbackSpeed),this.driver?this.driver.start(!1):(this.startTime=0,this.state="paused",this.holdTime=t,this.tick(t))}getGeneratorVelocity(){const t=this.currentTime;if(t<=0)return this.options.velocity||0;if(this.generator.velocity)return this.generator.velocity(t);return gn(t=>this.generator.next(t).value,t,this.generator.next(t).value)}get speed(){return this.playbackSpeed}set speed(t){const e=this.playbackSpeed!==t;e&&this.driver&&this.updateTime(Te.now()),this.playbackSpeed=t,e&&this.driver&&(this.time=Ae(this.currentTime))}play(){if(this.isStopped)return;const{driver:t=mn,startTime:e}=this.options;this.driver||(this.driver=t(t=>this.tick(t))),this.options.onPlay?.();const n=this.driver.now();"finished"===this.state?(this.updateFinished(),this.startTime=n):null!==this.holdTime?this.startTime=n-this.holdTime:this.startTime||(this.startTime=e??n),"finished"===this.state&&this.speed<0&&(this.startTime+=this.calculatedDuration),this.holdTime=null,this.state="running",this.driver.start()}pause(){this.state="paused",this.updateTime(Te.now()),this.holdTime=this.currentTime}complete(){"running"!==this.state&&this.play(),this.state="finished",this.holdTime=null}finish(){this.notifyFinished(),this.teardown(),this.state="finished",this.options.onComplete?.()}cancel(){this.holdTime=null,this.startTime=0,this.tick(0),this.teardown(),this.options.onCancel?.()}teardown(){this.state="idle",this.stopDriver(),this.startTime=this.holdTime=null,fn.mainThread--}stopDriver(){this.driver&&(this.driver.stop(),this.driver=void 0)}sample(t){return this.startTime=0,this.tick(t,!0)}attachTimeline(t){return this.options.allowFlatten&&(this.options.type="keyframes",this.options.ease="linear",this.initAnimation()),this.driver?.stop(),t.observe(this)}}const Un=t=>180*t/Math.PI,Xn=t=>{const e=Un(Math.atan2(t[1],t[0]));return Kn(e)},zn={x:4,y:5,translateX:4,translateY:5,scaleX:0,scaleY:3,scale:t=>(Math.abs(t[0])+Math.abs(t[3]))/2,rotate:Xn,rotateZ:Xn,skewX:t=>Un(Math.atan(t[1])),skewY:t=>Un(Math.atan(t[2])),skew:t=>(Math.abs(t[1])+Math.abs(t[2]))/2},Kn=t=>((t%=360)<0&&(t+=360),t),Hn=t=>Math.sqrt(t[0]*t[0]+t[1]*t[1]),Yn=t=>Math.sqrt(t[4]*t[4]+t[5]*t[5]),qn={x:12,y:13,z:14,translateX:12,translateY:13,translateZ:14,scaleX:Hn,scaleY:Yn,scale:t=>(Hn(t)+Yn(t))/2,rotateX:t=>Kn(Un(Math.atan2(t[6],t[5]))),rotateY:t=>Kn(Un(Math.atan2(-t[2],t[0]))),rotateZ:Xn,rotate:Xn,skewX:t=>Un(Math.atan(t[4])),skewY:t=>Un(Math.atan(t[1])),skew:t=>(Math.abs(t[1])+Math.abs(t[4]))/2};function Gn(t){return t.includes("scale")?1:0}function Zn(t,e){if(!t||"none"===t)return Gn(e);const n=t.match(/^matrix3d\(([-\d.e\s,]+)\)$/u);let i,s;if(n)i=qn,s=n;else{const e=t.match(/^matrix\(([-\d.e\s,]+)\)$/u);i=zn,s=e}if(!s)return Gn(e);const r=i[e],a=s[1].split(",").map(Jn);return"function"==typeof r?r(a):a[r]}function Jn(t){return parseFloat(t.trim())}const Qn=["transformPerspective","x","y","z","translateX","translateY","translateZ","scale","scaleX","scaleY","rotate","rotateX","rotateY","rotateZ","skew","skewX","skewY"],ti=(()=>new Set(Qn))(),ei=t=>t===Q||t===pt,ni=new Set(["x","y","z"]),ii=Qn.filter(t=>!ni.has(t));const si={width:({x:t},{paddingLeft:e="0",paddingRight:n="0",boxSizing:i})=>{const s=t.max-t.min;return"border-box"===i?s:s-parseFloat(e)-parseFloat(n)},height:({y:t},{paddingTop:e="0",paddingBottom:n="0",boxSizing:i})=>{const s=t.max-t.min;return"border-box"===i?s:s-parseFloat(e)-parseFloat(n)},top:(t,{top:e})=>parseFloat(e),left:(t,{left:e})=>parseFloat(e),bottom:({y:t},{top:e})=>parseFloat(e)+(t.max-t.min),right:({x:t},{left:e})=>parseFloat(e)+(t.max-t.min),x:(t,{transform:e})=>Zn(e,"x"),y:(t,{transform:e})=>Zn(e,"y")};si.translateX=si.x,si.translateY=si.y;const ri=new Set;let ai=!1,oi=!1,li=!1;function hi(){if(oi){const t=Array.from(ri).filter(t=>t.needsMeasurement),e=new Set(t.map(t=>t.element)),n=new Map;e.forEach(t=>{const e=function(t){const e=[];return ii.forEach(n=>{const i=t.getValue(n);void 0!==i&&(e.push([n,i.get()]),i.set(n.startsWith("scale")?1:0))}),e}(t);e.length&&(n.set(t,e),t.render())}),t.forEach(t=>t.measureInitialState()),e.forEach(t=>{t.render();const e=n.get(t);e&&e.forEach(([e,n])=>{t.getValue(e)?.set(n)})}),t.forEach(t=>t.measureEndState()),t.forEach(t=>{void 0!==t.suspendedScrollY&&window.scrollTo(0,t.suspendedScrollY)})}oi=!1,ai=!1,ri.forEach(t=>t.complete(li)),ri.clear()}function ci(){ri.forEach(t=>{t.readKeyframes(),t.needsMeasurement&&(oi=!0)})}class ui{constructor(t,e,n,i,s,r=!1){this.state="pending",this.isAsync=!1,this.needsMeasurement=!1,this.unresolvedKeyframes=[...t],this.onComplete=e,this.name=n,this.motionValue=i,this.element=s,this.isAsync=r}scheduleResolve(){this.state="scheduled",this.isAsync?(ri.add(this),ai||(ai=!0,m.read(ci),m.resolveKeyframes(hi))):(this.readKeyframes(),this.complete())}readKeyframes(){const{unresolvedKeyframes:t,name:e,element:n,motionValue:i}=this;if(null===t[0]){const s=i?.get(),r=t[t.length-1];if(void 0!==s)t[0]=s;else if(n&&e){const i=n.readValue(e,r);null!=i&&(t[0]=i)}void 0===t[0]&&(t[0]=r),i&&void 0===s&&i.set(t[0])}!function(t){for(let e=1;e<t.length;e++)t[e]??(t[e]=t[e-1])}(t)}setFinalKeyframe(){}measureInitialState(){}renderEndStyles(){}measureEndState(){}complete(t=!1){this.state="complete",this.onComplete(this.unresolvedKeyframes,this.finalKeyframe,t),ri.delete(this)}cancel(){"scheduled"===this.state&&(ri.delete(this),this.state="pending")}resume(){"pending"===this.state&&this.scheduleResolve()}}function di(t,e,n){(t=>t.startsWith("--"))(e)?t.style.setProperty(e,n):t.style[e]=n}const pi=x(()=>{try{document.createElement("div").animate({opacity:0},{easing:"linear(0, 1)"})}catch(t){return!1}return!0},"linearEasing"),fi=([t,e,n,i])=>`cubic-bezier(${t}, ${e}, ${n}, ${i})`,mi={linear:"linear",ease:"ease",easeIn:"ease-in",easeOut:"ease-out",easeInOut:"ease-in-out",circIn:fi([0,.65,.55,1]),circOut:fi([.55,0,1,.45]),backIn:fi([.31,.01,.66,-.59]),backOut:fi([.33,1.53,.69,.99])};function gi(t,e){return t?"function"==typeof t?pi()?Ee(t,e):"ease-out":Fn(t)?fi(t):Array.isArray(t)?t.map(t=>gi(t,e)||mi.easeOut):mi[t]:void 0}function yi(t,e,n,{delay:i=0,duration:s=300,repeat:r=0,repeatType:a="loop",ease:o="easeOut",times:l}={},h=void 0){const c={[e]:n};l&&(c.offset=l);const u=gi(o,s);Array.isArray(u)&&(c.easing=u),p.value&&fn.waapi++;const d={delay:i,duration:s,easing:Array.isArray(u)?"linear":u,fill:"both",iterations:r+1,direction:"reverse"===a?"alternate":"normal"};h&&(d.pseudoElement=h);const f=t.animate(c,d);return p.value&&f.finished.finally(()=>{fn.waapi--}),f}class vi extends $n{constructor(t){if(super(),this.finishedTime=null,this.isStopped=!1,this.manualStartTime=null,!t)return;const{element:e,name:n,keyframes:i,pseudoElement:s,allowFlatten:r=!1,finalKeyframe:a,onComplete:o}=t;this.isPseudoElement=Boolean(s),this.allowFlatten=r,this.options=t,t.type;const l=function({type:t,...e}){return Ge(t)&&pi()?t.applyToOptions(e):(e.duration??(e.duration=300),e.ease??(e.ease="easeOut"),e)}(t);this.animation=yi(e,n,i,l,s),!1===l.autoplay&&this.animation.pause(),this.animation.onfinish=()=>{if(this.finishedTime=this.time,!s){const t=In(i,this.options,a,this.speed);this.updateMotionValue&&this.updateMotionValue(t),di(e,n,t),this.animation.cancel()}o?.(),this.notifyFinished()}}play(){this.isStopped||(this.manualStartTime=null,this.animation.play(),"finished"===this.state&&this.updateFinished())}pause(){this.animation.pause()}complete(){this.animation.finish?.()}cancel(){try{this.animation.cancel()}catch(t){}}stop(){if(this.isStopped)return;this.isStopped=!0;const{state:t}=this;"idle"!==t&&"finished"!==t&&(this.updateMotionValue?this.updateMotionValue():this.commitStyles(),this.isPseudoElement||this.cancel())}commitStyles(){const t=this.options?.element;!this.isPseudoElement&&t?.isConnected&&this.animation.commitStyles?.()}get duration(){const t=this.animation.effect?.getComputedTiming?.().duration||0;return Ae(Number(t))}get iterationDuration(){const{delay:t=0}=this.options||{};return this.duration+Ae(t)}get time(){return Ae(Number(this.animation.currentTime)||0)}set time(t){const e=null!==this.finishedTime;this.manualStartTime=null,this.finishedTime=null,this.animation.currentTime=Se(t),e&&this.animation.pause()}get speed(){return this.animation.playbackRate}set speed(t){t<0&&(this.finishedTime=null),this.animation.playbackRate=t}get state(){return null!==this.finishedTime?"finished":this.animation.playState}get startTime(){return this.manualStartTime??Number(this.animation.startTime)}set startTime(t){this.manualStartTime=this.animation.startTime=t}attachTimeline({timeline:t,rangeStart:e,rangeEnd:n,observe:i}){return this.allowFlatten&&this.animation.effect?.updateTiming({easing:"linear"}),this.animation.onfinish=null,t&&M()?(this.animation.timeline=t,e&&(this.animation.rangeStart=e),n&&(this.animation.rangeEnd=n),c):i(this)}}const bi={anticipate:kn,backInOut:Cn,circInOut:Rn};function Ti(t){"string"==typeof t.ease&&t.ease in bi&&(t.ease=bi[t.ease])}class wi extends vi{constructor(t){Ti(t),jn(t),super(t),void 0!==t.startTime&&!1!==t.autoplay&&(this.startTime=t.startTime),this.options=t}updateMotionValue(t){const{motionValue:e,onUpdate:n,onComplete:i,element:s,...r}=this.options;if(!e)return;if(void 0!==t)return void e.set(t);const a=new Nn({...r,autoplay:!1}),o=Math.max(10,Te.now()-this.startTime),l=K(0,10,o-10),h=a.sample(o).value,{name:c}=this.options;s&&c&&di(s,c,h),e.setWithVelocity(a.sample(Math.max(0,o-l)).value,h,l),a.stop()}}const xi=(t,e)=>"zIndex"!==e&&(!("number"!=typeof t&&!Array.isArray(t))||!("string"!=typeof t||!Et.test(t)&&"0"!==t||t.startsWith("url(")));function Mi(t){t.duration=0,t.type="keyframes"}const Si=new Set(["opacity","clipPath","filter","transform"]),Ai=T(()=>Object.hasOwnProperty.call(Element.prototype,"animate"));class Ei extends $n{constructor({autoplay:t=!0,delay:e=0,type:n="keyframes",repeat:i=0,repeatDelay:s=0,repeatType:r="loop",keyframes:a,name:o,motionValue:l,element:h,...c}){super(),this.stop=()=>{this._animation&&(this._animation.stop(),this.stopTimeline?.()),this.keyframeResolver?.cancel()},this.createdAt=Te.now();const u={autoplay:t,delay:e,type:n,repeat:i,repeatDelay:s,repeatType:r,name:o,motionValue:l,element:h,...c},d=h?.KeyframeResolver||ui;this.keyframeResolver=new d(a,(t,e,n)=>this.onKeyframesResolved(t,e,u,!n),o,l,h),this.keyframeResolver?.scheduleResolve()}onKeyframesResolved(t,e,n,i){this.keyframeResolver=void 0;const{name:s,type:r,velocity:a,delay:o,isHandoff:l,onUpdate:h}=n;this.resolvedAt=Te.now();let d=!0;(function(t,e,n,i){const s=t[0];if(null===s)return!1;if("display"===e||"visibility"===e)return!0;const r=t[t.length-1],a=xi(s,e),o=xi(r,e);return!(!a||!o)&&(function(t){const e=t[0];if(1===t.length)return!0;for(let n=0;n<t.length;n++)if(t[n]!==e)return!0}(t)||("spring"===n||Ge(n))&&i)})(t,s,r,a)||(d=!1,!u.instantAnimations&&o||h?.(In(t,n,e)),t[0]=t[t.length-1],Mi(n),n.repeat=0);const p={startTime:i?this.resolvedAt&&this.resolvedAt-this.createdAt>40?this.resolvedAt:this.createdAt:void 0,finalKeyframe:e,...n,keyframes:t},f=d&&!l&&function(t){const{motionValue:e,name:n,repeatDelay:i,repeatType:s,damping:r,type:a}=t,o=e?.owner?.current;if(!(o instanceof HTMLElement))return!1;const{onUpdate:l,transformTemplate:h}=e.owner.getProps();return Ai()&&n&&Si.has(n)&&("transform"!==n||!h)&&!l&&!i&&"mirror"!==s&&0!==r&&"inertia"!==a}(p),m=p.motionValue?.owner?.current,g=f?new wi({...p,element:m}):new Nn(p);g.finished.then(()=>{this.notifyFinished()}).catch(c),this.pendingTimeline&&(this.stopTimeline=g.attachTimeline(this.pendingTimeline),this.pendingTimeline=void 0),this._animation=g}get finished(){return this._animation?this.animation.finished:this._finished}then(t,e){return this.finished.finally(t).then(()=>{})}get animation(){return this._animation||(this.keyframeResolver?.resume(),li=!0,ci(),hi(),li=!1),this._animation}get duration(){return this.animation.duration}get iterationDuration(){return this.animation.iterationDuration}get time(){return this.animation.time}set time(t){this.animation.time=t}get speed(){return this.animation.speed}get state(){return this.animation.state}set speed(t){this.animation.speed=t}get startTime(){return this.animation.startTime}attachTimeline(t){return this._animation?this.stopTimeline=this.animation.attachTimeline(t):this.pendingTimeline=t,()=>this.stop()}play(){this.animation.play()}pause(){this.animation.pause()}complete(){this.animation.complete()}cancel(){this._animation&&this.animation.cancel(),this.keyframeResolver?.cancel()}}function Ci(t,e){if(t?.inherit&&e){const{inherit:n,...i}=t;return{...e,...i}}return t}function ki(t,e){const n=t?.[e]??t?.default??t;return n!==t?Ci(n,t):n}const Vi={type:"spring",stiffness:500,damping:25,restSpeed:10},Pi={type:"keyframes",duration:.8},Ri={type:"keyframes",ease:[.25,.1,.35,1],duration:.3},Fi=(t,{keyframes:e})=>e.length>2?Pi:ti.has(t)?t.startsWith("scale")?{type:"spring",stiffness:550,damping:0===e[1]?2*Math.sqrt(550):30,restSpeed:10}:Vi:Ri,Di=t=>null!==t;const _i=(t,e,n,i={},s,r)=>a=>{const o=ki(i,t)||{},l=o.delay||i.delay||0;let{elapsed:h=0}=i;h-=Se(l);const c={keyframes:Array.isArray(n)?n:[null,n],ease:"easeOut",velocity:e.getVelocity(),...o,delay:-h,onUpdate:t=>{e.set(t),o.onUpdate&&o.onUpdate(t)},onComplete:()=>{a(),o.onComplete&&o.onComplete()},name:t,motionValue:e,element:r?void 0:s};(function({when:t,delay:e,delayChildren:n,staggerChildren:i,staggerDirection:s,repeat:r,repeatType:a,repeatDelay:o,from:l,elapsed:h,...c}){return!!Object.keys(c).length})(o)||Object.assign(c,Fi(t,c)),c.duration&&(c.duration=Se(c.duration)),c.repeatDelay&&(c.repeatDelay=Se(c.repeatDelay)),void 0!==c.from&&(c.keyframes[0]=c.from);let d=!1;if((!1===c.type||0===c.duration&&!c.repeatDelay)&&(Mi(c),0===c.delay&&(d=!0)),(u.instantAnimations||u.skipAnimations||s?.shouldSkipAnimations)&&(d=!0,Mi(c),c.delay=0),c.allowFlatten=!o.type&&!o.ease,d&&!r&&void 0!==e.get()){const t=function(t,{repeat:e,repeatType:n="loop"},i){const s=t.filter(Di),r=e&&"loop"!==n&&e%2==1?0:s.length-1;return r&&void 0!==i?i:s[r]}(c.keyframes,o);if(void 0!==t)return void m.update(()=>{c.onUpdate(t),c.onComplete()})}return o.isSync?new Nn(c):new Ei(c)};const Bi=new WeakMap,Oi=new Set(["width","height","top","left","right","bottom",...Qn]);function Ii(t){const e=[{},{}];return t?.values.forEach((t,n)=>{e[0][n]=t.get(),e[1][n]=t.getVelocity()}),e}function Li(t,e,n,i){if("function"==typeof e){const[s,r]=Ii(i);e=e(void 0!==n?n:t.custom,s,r)}if("string"==typeof e&&(e=t.variants&&t.variants[e]),"function"==typeof e){const[s,r]=Ii(i);e=e(void 0!==n?n:t.custom,s,r)}return e}function ji(t,e,n){t.hasValue(e)?t.getValue(e).set(n):t.addValue(e,Me(n))}function $i(t){return(t=>Array.isArray(t))(t)?t[t.length-1]||0:t}function Wi(t,e){const n=function(t,e,n){const i=t.getProps();return Li(i,e,void 0!==n?n:i.custom,t)}(t,e);let{transitionEnd:i={},transition:s={},...r}=n||{};r={...r,...i};for(const e in r){ji(t,e,$i(r[e]))}}function Ni(t,e){const n=t.getValue("willChange");if(i=n,Boolean(Ze(i)&&i.add))return n.add(e);if(!n&&u.WillChange){const n=new u.WillChange("auto");t.addValue("willChange",n),n.add(e)}var i}function Ui(t){return t.replace(/([A-Z])/g,t=>`-${t.toLowerCase()}`)}const Xi="data-"+Ui("framerAppearId");function zi(t){return t.props[Xi]}function Ki({protectedKeys:t,needsAnimating:e},n){const i=t.hasOwnProperty(n)&&!0!==e[n];return e[n]=!1,i}function Hi(t,e,{delay:n=0,transitionOverride:i,type:s}={}){let{transition:r,transitionEnd:a,...o}=e;const l=t.getDefaultTransition();r=r?Ci(r,l):l;const h=r?.reduceMotion;i&&(r=i);const c=[],u=s&&t.animationState&&t.animationState.getState()[s];for(const e in o){const i=t.getValue(e,t.latestValues[e]??null),s=o[e];if(void 0===s||u&&Ki(u,e))continue;const a={delay:n,...ki(r||{},e)},l=i.get();if(void 0!==l&&!i.isAnimating&&!Array.isArray(s)&&s===l&&!a.velocity)continue;let d=!1;if(window.MotionHandoffAnimation){const n=zi(t);if(n){const t=window.MotionHandoffAnimation(n,e,m);null!==t&&(a.startTime=t,d=!0)}}Ni(t,e);const p=h??t.shouldReduceMotion;i.start(_i(e,i,s,p&&Oi.has(e)?{type:!1}:a,t,d));const f=i.animation;f&&c.push(f)}if(a){const e=()=>m.update(()=>{a&&Wi(t,a)});c.length?Promise.all(c).then(e):e()}return c}const Yi=new Set(["brightness","contrast","saturate","opacity"]);function qi(t){const[e,n]=t.slice(0,-1).split("(");if("drop-shadow"===e)return t;const[i]=n.match(it)||[];if(!i)return t;const s=n.replace(i,"");let r=Yi.has(e)?1:0;return i!==n&&(r*=100),e+"("+r+s+")"}const Gi=/\b([a-z-]*)\(.*?\)/gu,Zi={...Et,getAnimatableNone:t=>{const e=t.match(Gi);return e?e.map(qi).join(" "):t}},Ji={...Et,getAnimatableNone:t=>{const e=Et.parse(t);return Et.createTransformer(t)(e.map(t=>"number"==typeof t?0:"object"==typeof t?{...t,alpha:1}:t))}},Qi={...Q,transform:Math.round},ts={borderWidth:pt,borderTopWidth:pt,borderRightWidth:pt,borderBottomWidth:pt,borderLeftWidth:pt,borderRadius:pt,borderTopLeftRadius:pt,borderTopRightRadius:pt,borderBottomRightRadius:pt,borderBottomLeftRadius:pt,width:pt,maxWidth:pt,height:pt,maxHeight:pt,top:pt,right:pt,bottom:pt,left:pt,inset:pt,insetBlock:pt,insetBlockStart:pt,insetBlockEnd:pt,insetInline:pt,insetInlineStart:pt,insetInlineEnd:pt,padding:pt,paddingTop:pt,paddingRight:pt,paddingBottom:pt,paddingLeft:pt,paddingBlock:pt,paddingBlockStart:pt,paddingBlockEnd:pt,paddingInline:pt,paddingInlineStart:pt,paddingInlineEnd:pt,margin:pt,marginTop:pt,marginRight:pt,marginBottom:pt,marginLeft:pt,marginBlock:pt,marginBlockStart:pt,marginBlockEnd:pt,marginInline:pt,marginInlineStart:pt,marginInlineEnd:pt,fontSize:pt,backgroundPositionX:pt,backgroundPositionY:pt,...{rotate:ut,rotateX:ut,rotateY:ut,rotateZ:ut,scale:et,scaleX:et,scaleY:et,scaleZ:et,skew:ut,skewX:ut,skewY:ut,distance:pt,translateX:pt,translateY:pt,translateZ:pt,x:pt,y:pt,z:pt,perspective:pt,transformPerspective:pt,opacity:tt,originX:gt,originY:gt,originZ:pt},zIndex:Qi,fillOpacity:tt,strokeOpacity:tt,numOctaves:Qi},es={...ts,color:vt,backgroundColor:vt,outlineColor:vt,fill:vt,stroke:vt,borderColor:vt,borderTopColor:vt,borderRightColor:vt,borderBottomColor:vt,borderLeftColor:vt,filter:Zi,WebkitFilter:Zi,mask:Ji,WebkitMask:Ji},ns=t=>es[t],is=()=>({x:{min:0,max:0},y:{min:0,max:0}}),ss=t=>e=>e.test(t),rs=[Q,pt,dt,ut,mt,ft,{test:t=>"auto"===t,parse:t=>t}],as=t=>rs.find(ss(t)),os=t=>/^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(t),ls=/^var\(--(?:([\w-]+)|([\w-]+), ?([a-zA-Z\d ()%#.,-]+))\)/u;function hs(t,e,n=1){const[i,s]=function(t){const e=ls.exec(t);if(!e)return[,];const[,n,i,s]=e;return[`--${n??i}`,s]}(t);if(!i)return;const r=window.getComputedStyle(e).getPropertyValue(i);if(r){const t=r.trim();return os(t)?parseFloat(t):t}return G(s)?hs(s,e,n+1):s}const cs=t=>/^0[^.\s]+$/u.test(t);function us(t){return"number"==typeof t?0===t:null===t||("none"===t||"0"===t||cs(t))}const ds=new Set([Zi,Ji]);function ps(t,e){let n=ns(t);return ds.has(n)||(n=Et),n.getAnimatableNone?n.getAnimatableNone(e):void 0}const fs=new Set(["auto","none","0"]);class ms extends ui{constructor(t,e,n,i,s){super(t,e,n,i,s,!0)}readKeyframes(){const{unresolvedKeyframes:t,element:e,name:n}=this;if(!e||!e.current)return;super.readKeyframes();for(let n=0;n<t.length;n++){let i=t[n];if("string"==typeof i&&(i=i.trim(),G(i))){const s=hs(i,e.current);void 0!==s&&(t[n]=s),n===t.length-1&&(this.finalKeyframe=i)}}if(this.resolveNoneKeyframes(),!Oi.has(n)||2!==t.length)return;const[i,s]=t,r=as(i),a=as(s);if(J(i)!==J(s)&&si[n])this.needsMeasurement=!0;else if(r!==a)if(ei(r)&&ei(a))for(let e=0;e<t.length;e++){const n=t[e];"string"==typeof n&&(t[e]=parseFloat(n))}else si[n]&&(this.needsMeasurement=!0)}resolveNoneKeyframes(){const{unresolvedKeyframes:t,name:e}=this,n=[];for(let e=0;e<t.length;e++)(null===t[e]||us(t[e]))&&n.push(e);n.length&&function(t,e,n){let i,s=0;for(;s<t.length&&!i;){const e=t[s];"string"==typeof e&&!fs.has(e)&&Mt(e).values.length&&(i=t[s]),s++}if(i&&n)for(const s of e)t[s]=ps(n,i)}(t,n,e)}measureInitialState(){const{element:t,unresolvedKeyframes:e,name:n}=this;if(!t||!t.current)return;"height"===n&&(this.suspendedScrollY=window.pageYOffset),this.measuredOrigin=si[n](t.measureViewportBox(),window.getComputedStyle(t.current)),e[0]=this.measuredOrigin;const i=e[e.length-1];void 0!==i&&t.getValue(n,i).jump(i,!1)}measureEndState(){const{element:t,name:e,unresolvedKeyframes:n}=this;if(!t||!t.current)return;const i=t.getValue(e);i&&i.jump(this.measuredOrigin,!1);const s=n.length-1,r=n[s];n[s]=si[e](t.measureViewportBox(),window.getComputedStyle(t.current)),null!==r&&void 0===this.finalKeyframe&&(this.finalKeyframe=r),this.removedTransforms?.length&&this.removedTransforms.forEach(([e,n])=>{t.getValue(e).set(n)}),this.resolveNoneKeyframes()}}const gs=new Set(["opacity","clipPath","filter","transform"]),{schedule:ys,cancel:vs}=f(queueMicrotask,!1),bs=[...rs,vt,Et];const Ts=["initial","animate","whileInView","whileFocus","whileHover","whileTap","whileDrag","exit"];function ws(t){return null!==(e=t.animate)&&"object"==typeof e&&"function"==typeof e.start||Ts.some(e=>function(t){return"string"==typeof t||Array.isArray(t)}(t[e]));var e}const xs={current:null},Ms={current:!1},Ss="undefined"!=typeof window;const As=["AnimationStart","AnimationComplete","Update","BeforeLayoutMeasure","LayoutMeasure","LayoutAnimationStart","LayoutAnimationComplete"];let Es={};class Cs{scrapeMotionValuesFromProps(t,e,n){return{}}constructor({parent:t,props:e,presenceContext:n,reducedMotionConfig:i,skipAnimations:s,blockInitialAnimation:r,visualState:a},o={}){this.current=null,this.children=new Set,this.isVariantNode=!1,this.isControllingVariants=!1,this.shouldReduceMotion=null,this.shouldSkipAnimations=!1,this.values=new Map,this.KeyframeResolver=ui,this.features={},this.valueSubscriptions=new Map,this.prevMotionValues={},this.hasBeenMounted=!1,this.events={},this.propEventSubscriptions={},this.notifyUpdate=()=>this.notify("Update",this.latestValues),this.render=()=>{this.current&&(this.triggerBuild(),this.renderInstance(this.current,this.renderState,this.props.style,this.projection))},this.renderScheduledAt=0,this.scheduleRender=()=>{const t=Te.now();this.renderScheduledAt<t&&(this.renderScheduledAt=t,m.render(this.render,!1,!0))};const{latestValues:l,renderState:h}=a;this.latestValues=l,this.baseTarget={...l},this.initialValues=e.initial?{...l}:{},this.renderState=h,this.parent=t,this.props=e,this.presenceContext=n,this.depth=t?t.depth+1:0,this.reducedMotionConfig=i,this.skipAnimationsConfig=s,this.options=o,this.blockInitialAnimation=Boolean(r),this.isControllingVariants=ws(e),this.isVariantNode=function(t){return Boolean(ws(t)||t.variants)}(e),this.isVariantNode&&(this.variantChildren=new Set),this.manuallyAnimateOnMount=Boolean(t&&t.current);const{willChange:c,...u}=this.scrapeMotionValuesFromProps(e,{},this);for(const t in u){const e=u[t];void 0!==l[t]&&Ze(e)&&e.set(l[t])}}mount(t){if(this.hasBeenMounted)for(const t in this.initialValues)this.values.get(t)?.jump(this.initialValues[t]),this.latestValues[t]=this.initialValues[t];this.current=t,Bi.set(t,this),this.projection&&!this.projection.instance&&this.projection.mount(t),this.parent&&this.isVariantNode&&!this.isControllingVariants&&(this.removeFromVariantTree=this.parent.addVariantChild(this)),this.values.forEach((t,e)=>this.bindToMotionValue(e,t)),"never"===this.reducedMotionConfig?this.shouldReduceMotion=!1:"always"===this.reducedMotionConfig?this.shouldReduceMotion=!0:(Ms.current||function(){if(Ms.current=!0,Ss)if(window.matchMedia){const t=window.matchMedia("(prefers-reduced-motion)"),e=()=>xs.current=t.matches;t.addEventListener("change",e),e()}else xs.current=!1}(),this.shouldReduceMotion=xs.current),this.shouldSkipAnimations=this.skipAnimationsConfig??!1,this.parent?.addChild(this),this.update(this.props,this.presenceContext),this.hasBeenMounted=!0}unmount(){this.projection&&this.projection.unmount(),g(this.notifyUpdate),g(this.render),this.valueSubscriptions.forEach(t=>t()),this.valueSubscriptions.clear(),this.removeFromVariantTree&&this.removeFromVariantTree(),this.parent?.removeChild(this);for(const t in this.events)this.events[t].clear();for(const t in this.features){const e=this.features[t];e&&(e.unmount(),e.isMounted=!1)}this.current=null}addChild(t){this.children.add(t),this.enteringChildren??(this.enteringChildren=new Set),this.enteringChildren.add(t)}removeChild(t){this.children.delete(t),this.enteringChildren&&this.enteringChildren.delete(t)}bindToMotionValue(t,e){if(this.valueSubscriptions.has(t)&&this.valueSubscriptions.get(t)(),e.accelerate&&gs.has(t)&&this.current instanceof HTMLElement){const{factory:n,keyframes:i,times:s,ease:r,duration:a}=e.accelerate,o=new vi({element:this.current,name:t,keyframes:i,times:s,ease:r,duration:Se(a)}),l=n(o);return void this.valueSubscriptions.set(t,()=>{l(),o.cancel()})}const n=ti.has(t);n&&this.onBindTransform&&this.onBindTransform();const i=e.on("change",e=>{this.latestValues[t]=e,this.props.onUpdate&&m.preRender(this.notifyUpdate),n&&this.projection&&(this.projection.isTransformDirty=!0),this.scheduleRender()});let s;"undefined"!=typeof window&&window.MotionCheckAppearSync&&(s=window.MotionCheckAppearSync(this,t,e)),this.valueSubscriptions.set(t,()=>{i(),s&&s(),e.owner&&e.stop()})}sortNodePosition(t){return this.current&&this.sortInstanceNodePosition&&this.type===t.type?this.sortInstanceNodePosition(this.current,t.current):0}updateFeatures(){let t="animation";for(t in Es){const e=Es[t];if(!e)continue;const{isEnabled:n,Feature:i}=e;if(!this.features[t]&&i&&n(this.props)&&(this.features[t]=new i(this)),this.features[t]){const e=this.features[t];e.isMounted?e.update():(e.mount(),e.isMounted=!0)}}}triggerBuild(){this.build(this.renderState,this.latestValues,this.props)}measureViewportBox(){return this.current?this.measureInstanceViewportBox(this.current,this.props):{x:{min:0,max:0},y:{min:0,max:0}}}getStaticValue(t){return this.latestValues[t]}setStaticValue(t,e){this.latestValues[t]=e}update(t,e){(t.transformTemplate||this.props.transformTemplate)&&this.scheduleRender(),this.prevProps=this.props,this.props=t,this.prevPresenceContext=this.presenceContext,this.presenceContext=e;for(let e=0;e<As.length;e++){const n=As[e];this.propEventSubscriptions[n]&&(this.propEventSubscriptions[n](),delete this.propEventSubscriptions[n]);const i=t["on"+n];i&&(this.propEventSubscriptions[n]=this.on(n,i))}this.prevMotionValues=function(t,e,n){for(const i in e){const s=e[i],r=n[i];if(Ze(s))t.addValue(i,s);else if(Ze(r))t.addValue(i,Me(s,{owner:t}));else if(r!==s)if(t.hasValue(i)){const e=t.getValue(i);!0===e.liveStyle?e.jump(s):e.hasAnimated||e.set(s)}else{const e=t.getStaticValue(i);t.addValue(i,Me(void 0!==e?e:s,{owner:t}))}}for(const i in n)void 0===e[i]&&t.removeValue(i);return e}(this,this.scrapeMotionValuesFromProps(t,this.prevProps||{},this),this.prevMotionValues),this.handleChildMotionValue&&this.handleChildMotionValue()}getProps(){return this.props}getVariant(t){return this.props.variants?this.props.variants[t]:void 0}getDefaultTransition(){return this.props.transition}getTransformPagePoint(){return this.props.transformPagePoint}getClosestVariantNode(){return this.isVariantNode?this:this.parent?this.parent.getClosestVariantNode():void 0}addVariantChild(t){const e=this.getClosestVariantNode();if(e)return e.variantChildren&&e.variantChildren.add(t),()=>e.variantChildren.delete(t)}addValue(t,e){const n=this.values.get(t);e!==n&&(n&&this.removeValue(t),this.bindToMotionValue(t,e),this.values.set(t,e),this.latestValues[t]=e.get())}removeValue(t){this.values.delete(t);const e=this.valueSubscriptions.get(t);e&&(e(),this.valueSubscriptions.delete(t)),delete this.latestValues[t],this.removeValueFromRenderState(t,this.renderState)}hasValue(t){return this.values.has(t)}getValue(t,e){if(this.props.values&&this.props.values[t])return this.props.values[t];let n=this.values.get(t);return void 0===n&&void 0!==e&&(n=Me(null===e?void 0:e,{owner:this}),this.addValue(t,n)),n}readValue(t,e){let n=void 0===this.latestValues[t]&&this.current?this.getBaseTargetFromProps(this.props,t)??this.readValueFromInstance(this.current,t,this.options):this.latestValues[t];var i;return null!=n&&("string"==typeof n&&(os(n)||cs(n))?n=parseFloat(n):(i=n,!bs.find(ss(i))&&Et.test(e)&&(n=ps(t,e))),this.setBaseTarget(t,Ze(n)?n.get():n)),Ze(n)?n.get():n}setBaseTarget(t,e){this.baseTarget[t]=e}getBaseTarget(t){const{initial:e}=this.props;let n;if("string"==typeof e||"object"==typeof e){const i=Li(this.props,e,this.presenceContext?.custom);i&&(n=i[t])}if(e&&void 0!==n)return n;const i=this.getBaseTargetFromProps(this.props,t);return void 0===i||Ze(i)?void 0!==this.initialValues[t]&&void 0===n?void 0:this.baseTarget[t]:i}on(t,e){return this.events[t]||(this.events[t]=new ye),this.events[t].add(e)}notify(t,...e){this.events[t]&&this.events[t].notify(...e)}scheduleRenderMicrotask(){ys.render(this.render)}}class ks extends Cs{constructor(){super(...arguments),this.KeyframeResolver=ms}sortInstanceNodePosition(t,e){return 2&t.compareDocumentPosition(e)?1:-1}getBaseTargetFromProps(t,e){const n=t.style;return n?n[e]:void 0}removeValueFromRenderState(t,{vars:e,style:n}){delete e[t],delete n[t]}handleChildMotionValue(){this.childSubscription&&(this.childSubscription(),delete this.childSubscription);const{children:t}=this.props;Ze(t)&&(this.childSubscription=t.on("change",t=>{this.current&&(this.current.textContent=`${t}`)}))}}const Vs=(t,e)=>e&&"number"==typeof t?e.transform(t):t,Ps={x:"translateX",y:"translateY",z:"translateZ",transformPerspective:"perspective"},Rs=Qn.length;function Fs(t,e,n){const{style:i,vars:s,transformOrigin:r}=t;let a=!1,o=!1;for(const t in e){const n=e[t];if(ti.has(t))a=!0;else if(Y(t))s[t]=n;else{const e=Vs(n,ts[t]);t.startsWith("origin")?(o=!0,r[t]=e):i[t]=e}}if(e.transform||(a||n?i.transform=function(t,e,n){let i="",s=!0;for(let r=0;r<Rs;r++){const a=Qn[r],o=t[a];if(void 0===o)continue;let l=!0;if("number"==typeof o)l=o===(a.startsWith("scale")?1:0);else{const t=parseFloat(o);l=a.startsWith("scale")?1===t:0===t}if(!l||n){const t=Vs(o,ts[a]);l||(s=!1,i+=`${Ps[a]||a}(${t}) `),n&&(e[a]=t)}}return i=i.trim(),n?i=n(e,s?"":i):s&&(i="none"),i}(e,t.transform,n):i.transform&&(i.transform="none")),o){const{originX:t="50%",originY:e="50%",originZ:n=0}=r;i.transformOrigin=`${t} ${e} ${n}`}}const Ds={offset:"stroke-dashoffset",array:"stroke-dasharray"},_s={offset:"strokeDashoffset",array:"strokeDasharray"};const Bs=["offsetDistance","offsetPath","offsetRotate","offsetAnchor"];function Os(t,{attrX:e,attrY:n,attrScale:i,pathLength:s,pathSpacing:r=1,pathOffset:a=0,...o},l,h,c){if(Fs(t,o,h),l)return void(t.style.viewBox&&(t.attrs.viewBox=t.style.viewBox));t.attrs=t.style,t.style={};const{attrs:u,style:d}=t;u.transform&&(d.transform=u.transform,delete u.transform),(d.transform||u.transformOrigin)&&(d.transformOrigin=u.transformOrigin??"50% 50%",delete u.transformOrigin),d.transform&&(d.transformBox=c?.transformBox??"fill-box",delete u.transformBox);for(const t of Bs)void 0!==u[t]&&(d[t]=u[t],delete u[t]);void 0!==e&&(u.x=e),void 0!==n&&(u.y=n),void 0!==i&&(u.scale=i),void 0!==s&&function(t,e,n=1,i=0,s=!0){t.pathLength=1;const r=s?Ds:_s;t[r.offset]=""+-i,t[r.array]=`${e} ${n}`}(u,s,r,a,!1)}const Is=new Set(["baseFrequency","diffuseConstant","kernelMatrix","kernelUnitLength","keySplines","keyTimes","limitingConeAngle","markerHeight","markerWidth","numOctaves","targetX","targetY","surfaceScale","specularConstant","specularExponent","stdDeviation","tableValues","viewBox","gradientTransform","pathLength","startOffset","textLength","lengthAdjust"]);function Ls(t,{style:e,vars:n},i,s){const r=t.style;let a;for(a in e)r[a]=e[a];for(a in s?.applyProjectionStyles(r,i),n)r.setProperty(a,n[a])}function js(t,e){return e.max===e.min?0:t/(e.max-e.min)*100}const $s={correct:(t,e)=>{if(!e.target)return t;if("string"==typeof t){if(!pt.test(t))return t;t=parseFloat(t)}return`${js(t,e.target.x)}% ${js(t,e.target.y)}%`}},Ws={correct:(t,{treeScale:e,projectionDelta:n})=>{const i=t,s=Et.parse(t);if(s.length>5)return i;const r=Et.createTransformer(t),a="number"!=typeof s[0]?1:0,o=n.x.scale*e.x,l=n.y.scale*e.y;s[0+a]/=o,s[1+a]/=l;const h=Vt(o,l,.5);return"number"==typeof s[2+a]&&(s[2+a]/=h),"number"==typeof s[3+a]&&(s[3+a]/=h),r(s)}};const Ns={borderRadius:{...$s,applyTo:["borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"]},borderTopLeftRadius:$s,borderTopRightRadius:$s,borderBottomLeftRadius:$s,borderBottomRightRadius:$s,boxShadow:Ws};function Us(t,{layout:e,layoutId:n}){return ti.has(t)||t.startsWith("origin")||(e||void 0!==n)&&(!!Ns[t]||"opacity"===t)}function Xs(t,e,n){const i=t.style,s=e?.style,r={};if(!i)return r;for(const e in i)(Ze(i[e])||s&&Ze(s[e])||Us(e,t)||void 0!==n?.getValue(e)?.liveStyle)&&(r[e]=i[e]);return r}class zs extends ks{constructor(){super(...arguments),this.type="svg",this.isSVGTag=!1,this.measureInstanceViewportBox=is}getBaseTargetFromProps(t,e){return t[e]}readValueFromInstance(t,e){if(ti.has(e)){const t=ns(e);return t&&t.default||0}return e=Is.has(e)?e:Ui(e),t.getAttribute(e)}scrapeMotionValuesFromProps(t,e,n){return function(t,e,n){const i=Xs(t,e,n);for(const n in t)(Ze(t[n])||Ze(e[n]))&&(i[-1!==Qn.indexOf(n)?"attr"+n.charAt(0).toUpperCase()+n.substring(1):n]=t[n]);return i}(t,e,n)}build(t,e,n){Os(t,e,this.isSVGTag,n.transformTemplate,n.style)}renderInstance(t,e,n,i){!function(t,e,n,i){Ls(t,e,void 0,i);for(const n in e.attrs)t.setAttribute(Is.has(n)?n:Ui(n),e.attrs[n])}(t,e,0,i)}mount(t){var e;this.isSVGTag="string"==typeof(e=t.tagName)&&"svg"===e.toLowerCase(),super.mount(t)}}function Ks(t,e){return function({top:t,left:e,right:n,bottom:i}){return{x:{min:e,max:n},y:{min:t,max:i}}}(function(t,e){if(!e)return t;const n=e({x:t.left,y:t.top}),i=e({x:t.right,y:t.bottom});return{top:n.y,left:n.x,bottom:i.y,right:i.x}}(t.getBoundingClientRect(),e))}class Hs extends ks{constructor(){super(...arguments),this.type="html",this.renderInstance=Ls}readValueFromInstance(t,e){if(ti.has(e))return this.projection?.isProjecting?Gn(e):((t,e)=>{const{transform:n="none"}=getComputedStyle(t);return Zn(n,e)})(t,e);{const i=(n=t,window.getComputedStyle(n)),s=(Y(e)?i.getPropertyValue(e):i[e])||0;return"string"==typeof s?s.trim():s}var n}measureInstanceViewportBox(t,{transformPagePoint:e}){return Ks(t,e)}build(t,e,n){Fs(t,e,n.transformTemplate)}scrapeMotionValuesFromProps(t,e,n){return Xs(t,e,n)}}class Ys extends Cs{constructor(){super(...arguments),this.type="object"}readValueFromInstance(t,e){if(function(t,e){return t in e}(e,t)){const n=t[e];if("string"==typeof n||"number"==typeof n)return n}}getBaseTargetFromProps(){}removeValueFromRenderState(t,e){delete e.output[t]}measureInstanceViewportBox(){return{x:{min:0,max:0},y:{min:0,max:0}}}build(t,e){Object.assign(t.output,e)}renderInstance(t,{output:e}){Object.assign(t,e)}sortInstanceNodePosition(){return 0}}function qs(t){const e={presenceContext:null,props:{},visualState:{renderState:{transform:{},transformOrigin:{},style:{},vars:{},attrs:{}},latestValues:{}}},n=C(t)&&!function(t){return C(t)&&"svg"===t.tagName}(t)?new zs(e):new Hs(e);n.mount(t),Bi.set(t,n)}function Gs(t){const e=new Ys({presenceContext:null,props:{},visualState:{renderState:{output:{}},latestValues:{}}});e.mount(t),Bi.set(t,e)}function Zs(t,e,n,i){const s=[];if(function(t,e){return Ze(t)||"number"==typeof t||"string"==typeof t&&!tn(e)}(t,e))s.push(function(t,e,n){const i=Ze(t)?t:Me(t);return i.start(_i("",i,e,n)),i.animation}(t,tn(e)&&e.default||e,n&&n.default||n));else{if(null==t)return s;const r=en(t,e,i),a=r.length;Boolean(a);for(let t=0;t<a;t++){const i=r[t],o=i instanceof Element?qs:Gs;Bi.has(i)||o(i);const l=Bi.get(i),h={...n};"delay"in h&&"function"==typeof h.delay&&(h.delay=h.delay(t,a)),s.push(...Hi(l,{...e,transition:h},{}))}}return s}function Js(t,e,n){const i=[],s=function(t,{defaultTransition:e={},...n}={},i,s){const r=e.duration||.3,a=new Map,o=new Map,l={},h=new Map;let c=0,u=0,d=0;for(let n=0;n<t.length;n++){const a=t[n];if("string"==typeof a){h.set(a,u);continue}if(!Array.isArray(a)){h.set(a.name,sn(u,a.at,c,h));continue}let[p,f,m={}]=a;void 0!==m.at&&(u=sn(u,m.at,c,h));let g=0;const y=(t,n,i,a=0,o=0)=>{const l=cn(t),{delay:h=0,times:c=Ut(l),type:p=e.type||"keyframes",repeat:f,repeatType:m,repeatDelay:y=0,...v}=n;let{ease:b=e.ease||"easeOut",duration:T}=n;const w="function"==typeof h?h(a,o):h,x=l.length,M=Ge(p)?p:s?.[p||"keyframes"];if(x<=2&&M){let t=100;if(2===x&&pn(l)){const e=l[1]-l[0];t=Math.abs(e)}const n={...e,...v};void 0!==T&&(n.duration=Se(T));const i=Ve(n,t,M);b=i.ease,T=i.duration}T??(T=r);const S=u+w;1===c.length&&0===c[0]&&(c[1]=1);const A=c.length-l.length;if(A>0&&Nt(c,A),1===l.length&&l.unshift(null),f){T=nn(T,f);const t=[...l],e=[...c];b=Array.isArray(b)?[...b]:[b];const n=[...b];for(let i=0;i<f;i++){l.push(...t);for(let s=0;s<t.length;s++)c.push(e[s]+(i+1)),b.push(0===s?"linear":Qe(n,s-1))}an(c,f)}const E=S+T;rn(i,l,b,c,S,E),g=Math.max(w+T,g),d=Math.max(E,d)};if(Ze(p))y(f,m,hn("default",ln(p,o)));else{const t=en(p,f,i,l),e=t.length;for(let n=0;n<e;n++){const i=ln(t[n],o);for(const t in f)y(f[t],un(m,t),hn(t,i),n,e)}}c=u,u+=g}return o.forEach((t,i)=>{for(const s in t){const r=t[s];r.sort(on);const o=[],l=[],h=[];for(let t=0;t<r.length;t++){const{at:e,value:n,easing:i}=r[t];o.push(n),l.push($(0,d,e)),h.push(i||"easeOut")}0!==l[0]&&(l.unshift(0),o.unshift(o[0]),h.unshift("easeInOut")),1!==l[l.length-1]&&(l.push(1),o.push(null)),a.has(i)||a.set(i,{keyframes:{},transition:{}});const c=a.get(i);c.keyframes[s]=o;const{type:u,...p}=e;c.transition[s]={...p,duration:d,ease:h,times:l,...n}}}),a}(t.map(t=>{if(Array.isArray(t)&&"function"==typeof t[0]){const e=t[0],n=Me(0);return n.on("change",e),1===t.length?[n,[0,1]]:2===t.length?[n,[0,1],t[1]]:[n,t[1],t[2]]}return t}),e,n,{spring:qe});return s.forEach(({keyframes:t,transition:e},n)=>{i.push(...Zs(n,t,e))}),i}const Qs=function(t={}){const{scope:e,reduceMotion:n}=t;return function(t,i,s){let r,a=[];if(o=t,Array.isArray(o)&&o.some(Array.isArray)){const{onComplete:s,...o}=i||{};"function"==typeof s&&(r=s),a=Js(t,void 0!==n?{reduceMotion:n,...o}:o,e)}else{const{onComplete:o,...l}=s||{};"function"==typeof o&&(r=o),a=Zs(t,i,void 0!==n?{reduceMotion:n,...l}:l,e)}var o;const l=new me(a);return r&&l.finished.then(r),e&&(e.animations.push(l),l.finished.then(()=>{ge(e.animations,l)})),l}}();var tr=function(t,e,n,i){return new(n||(n=Promise))(function(s,r){function a(t){try{l(i.next(t))}catch(t){r(t)}}function o(t){try{l(i.throw(t))}catch(t){r(t)}}function l(t){var e;t.done?s(t.value):(e=t.value,e instanceof n?e:new n(function(t){t(e)})).then(a,o)}l((i=i.apply(t,e||[])).next())})};class er{constructor(t,e={}){this.engine=null,this.syncedAnimations=[],this.destroyed=!1,this.container=t,this.options=Object.assign({scrub:0},e),this.injectStyles()}injectStyles(){if(er.stylesInjected)return;const t=document.createElement("style");t.id="stube-base-styles",t.innerHTML='\n .stube-layer {\n position: absolute;\n inset: 0;\n pointer-events: none;\n display: grid;\n grid-template-areas: "content";\n }\n .stube-layer > * {\n grid-area: content;\n pointer-events: auto;\n }\n /* Alignment Mappings */\n .stube-layer[data-stube-align^="top"] { align-items: start; }\n .stube-layer[data-stube-align^="center"] { align-items: center; }\n .stube-layer[data-stube-align^="bottom"] { align-items: end; }\n \n .stube-layer[data-stube-align$="left"] { justify-items: start; }\n .stube-layer[data-stube-align$="center"] { justify-items: center; }\n .stube-layer[data-stube-align$="right"] { justify-items: end; }\n ',document.head.appendChild(t),er.stylesInjected=!0}static initAll(){return tr(this,void 0,void 0,function*(){const t=document.querySelectorAll(".stube-container"),e=[];for(let n=0;n<t.length;n++){const i=t[n],s=new er(i,{scrub:.5});yield s.init(),e.push(s)}return e})}init(){return tr(this,void 0,void 0,function*(){if(this.destroyed)return;const t=this.container.querySelector(".stube-canvas");if(!t)return void console.warn("[CoreOrchestrator] No .stube-canvas found inside container.");const e=t.dataset.stubeCanvas||t.getAttribute("data-project");if(!e)return void console.warn('[CoreOrchestrator] No project URL found on .stube-canvas. Use data-stube-canvas="url"');const n=t.dataset.stubeDepthtilt||t.getAttribute("data-stube-depthtilt");null!=n&&(this.options.depthTilt=parseFloat(n)),this.engine=yield this.loadEngine(e,t),this.destroyed||(this.parseAnimatedElements(),this.setupScrollTracking(),this.engine.onFrameChange=(t,e)=>{this.syncTrackingLayers(t),this.onFrameChange&&this.onFrameChange(t,e)},this.engine.onProgressUpdate=t=>{this.syncAnimations(t)})})}loadEngine(t,e){return tr(this,void 0,void 0,function*(){let n;try{if(t.trim().startsWith("{"))n=JSON.parse(t);else{const e=yield fetch(t);if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);n=yield e.json()}}catch(t){throw console.error("[CoreOrchestrator] Failed to load configuration:",t),t}n.settings||(n.settings={baseResolution:{width:1920,height:1080},scrollMode:"vh"}),n.settings.basePath||t.trim().startsWith("{")||(n.settings.basePath=t.substring(0,t.lastIndexOf("/")));const i=new h(n,{scrub:this.options.scrub,depthTilt:this.options.depthTilt});let s=e.querySelector("canvas");return s||(s=document.createElement("canvas"),s.style.width="100%",s.style.height="100%",s.style.display="block",s.style.objectFit="cover",e.appendChild(s)),i.attachCanvas(s),i})}setupScrollTracking(){if(!this.engine)return;const t=this.container.dataset.stubeOffset;let e=["start end","end start"];try{t&&(e=JSON.parse(t))}catch(t){}this.motionScrollCancel=de(t=>{this.engine&&this.engine.update(t)},{target:this.container,offset:e})}parseAnimatedElements(){this.container.querySelectorAll("[data-stube-animate]").forEach(t=>{try{const e=t.getAttribute("data-stube-animate");if(!e)return;const n=JSON.parse(e),i=Qs(t,n,{duration:1,ease:"linear"});i.pause(),i.time=0,this.syncedAnimations.push(i)}catch(e){console.warn("[CoreOrchestrator] Failed to parse data-stube-animate on element",t,e)}})}syncAnimations(t){for(const e of this.syncedAnimations)e.time=t}syncTrackingLayers(t){if(!this.engine)return;this.container.querySelectorAll("[data-stube-layer-tracking]").forEach(e=>tr(this,void 0,void 0,function*(){const n=e.dataset.stubeLayerTracking;if(!n)return;yield this.engine.loadTrackingData(n);const i=this.engine.getTrackedCoords(n,t);e.style.left=100*i.x+"%",e.style.top=100*i.y+"%"}))}getEngine(){return this.engine}destroy(){this.destroyed=!0,this.motionScrollCancel&&(this.motionScrollCancel(),this.motionScrollCancel=void 0);for(const t of this.syncedAnimations)t.stop();this.syncedAnimations=[],this.engine&&(this.engine.destroy(),this.engine=null),this.onFrameChange=void 0}}er.stylesInjected=!1;Object.assign(h,{CoreOrchestrator:er});var nr=function(t,e,n,i){return new(n||(n=Promise))(function(s,r){function a(t){try{l(i.next(t))}catch(t){r(t)}}function o(t){try{l(i.throw(t))}catch(t){r(t)}}function l(t){var e;t.done?s(t.value):(e=t.value,e instanceof n?e:new n(function(t){t(e)})).then(a,o)}l((i=i.apply(t,e||[])).next())})};const ir=(0,a.createContext)(null),sr=({type:t="sticky",containerHeight:e="400vh",sceneHeight:n="100vh",sceneTop:i=0,offset:s=["start end","end start"],scrub:o=0,children:l})=>{var h;const[c,u]=(0,a.useState)({progress:0,frame:-1}),[d,p]=(0,a.useState)(!1),f=(0,a.useRef)(null),m=(0,a.useRef)(null),g=JSON.stringify(s);(0,a.useEffect)(()=>{let t=!0;if(!f.current)return;const e=setTimeout(()=>{nr(void 0,void 0,void 0,function*(){const e=new er(f.current,{scrub:o});m.current=e,e.onFrameChange=(e,n)=>{t&&u({frame:e,progress:n})},yield e.init(),t&&p(!0)})},0);return()=>{t=!1,clearTimeout(e),m.current&&(m.current.destroy(),m.current=null)}},[o,g]);const y=(null===(h=m.current)||void 0===h?void 0:h.getEngine())||null;return(0,r.jsx)(ir.Provider,{value:Object.assign(Object.assign({},c),{engine:y}),children:(0,r.jsx)("div",{ref:f,className:"stube-container",style:{position:"relative",height:e},"data-stube-offset":g,children:(0,r.jsx)("div",{className:"stube-container_inner_sticky",style:{position:"sticky",top:i,height:n,overflow:"hidden"},children:l})})})},rr=({project:t,depthtilt:e,width:n="100%",height:i="100%",style:s})=>{const{engine:o}=hr(),l=void 0!==e?Number(e):4;return(0,a.useEffect)(()=>{o&&o.setDepthTilt(l)},[o,l]),(0,r.jsx)("div",{className:"stube-canvas","data-stube-canvas":t,"data-stube-depthtilt":l,style:Object.assign({width:n,height:i,pointerEvents:"auto"},s)})},ar=({align:t,style:e,children:n})=>(0,r.jsx)("div",{className:"stube-layer","data-stube-align":t,style:e,children:n}),or=({id:t="main",offset:e={x:0,y:0},style:n,children:i})=>{const s=(0,a.useContext)(ir);if((0,a.useEffect)(()=>{(null==s?void 0:s.engine)&&s.engine.loadTrackingData(t)},[null==s?void 0:s.engine,t]),!s)return null;const o=Object.assign(Object.assign(Object.assign({position:"absolute",left:"50%",top:"50%",transform:"translate(-50%, -50%)",pointerEvents:"auto",zIndex:10},n),0!==e.x?{marginLeft:`${e.x}px`}:{}),0!==e.y?{marginTop:`${e.y}px`}:{});return(0,r.jsx)("div",{className:"stube-layer-tracking","data-stube-layer-tracking":t,style:o,children:i})},lr=or,hr=()=>{const t=(0,a.useContext)(ir);if(!t)throw new Error("useScrollTube must be used within a ScrollTubeProvider");return t};return s})());
@@ -0,0 +1,72 @@
1
+ # AI Agent Workflow
2
+
3
+ ScrollTube is built for **Agent-Led Development**. The goal is to move from "writing code" to "orchestrating workflows."
4
+
5
+ ## 1. The Two-Phase Workflow
6
+
7
+ For an AI to successfully build an experience, it must follow these two phases:
8
+
9
+ ### Phase A: Asset Intelligence (CLI Execution)
10
+ The agent should first use the CLI to process raw media into an intelligent ScrollTube project.
11
+ ```bash
12
+ # Example: Process a video with AI tracking and depth maps
13
+ npx stube create input.mp4 --name "my-project" --track "main product" --cloud --depth
14
+ ```
15
+ **Output:** A directory containing optimized frames, depth maps, and a `scrolltube.json` file.
16
+
17
+ ### Phase B: Immersive Implementation (React)
18
+ The agent then uses the generated JSON to build the UI components.
19
+
20
+ ```tsx
21
+ import project from './scrolltube-project/scrolltube.json';
22
+ import { ScrollTubeProvider, ScrollTubeCanvas, SubjectLayer } from 'scrolltube/react';
23
+
24
+ export const MyExperience = () => (
25
+ <ScrollTubeProvider project={project} scrub={0.1}>
26
+ <div style={{ height: '300vh' }}>
27
+ <div style={{ sticky: 'top-0', height: '100vh' }}>
28
+ <ScrollTubeCanvas />
29
+
30
+ {/* Pins content to the tracked subject automatically */}
31
+ <SubjectLayer offset={{ x: 10, y: -5 }}>
32
+ <div className="info-box">
33
+ Premium Tubesmanship
34
+ </div>
35
+ </SubjectLayer>
36
+ </div>
37
+ </div>
38
+ </ScrollTubeProvider>
39
+ );
40
+ ```
41
+
42
+ ## 2. Protocol for AI Agents (Claude/GPT)
43
+
44
+ Paste this into your chat to turn an AI into a ScrollTube specialist:
45
+
46
+ ```markdown
47
+ You are the ScrollTube Implementation Specialist. Your goal is to design immersive scroll experiences.
48
+
49
+ Workflow:
50
+ 1. CLI FIRST: Start by suggesting `npx stube create` to process assets.
51
+ 2. ENGINE AWARE: Use 'ScrollTubeProvider' to sync the engine with React state.
52
+ 3. SUBJECT PINS: Use 'SubjectLayer' to attach UI to the product coordinates found by the AI tracker.
53
+ 4. DYNAMIC UI: Use the 'progress' (0-1) or 'frame' count from 'useScrollTube' for custom triggers.
54
+
55
+ Guiding Principles:
56
+ - Don't hardcode animations; let the ScrollTube engine handle interpolation.
57
+ - Use 'Subject-Relative' coordinates wherever possible for perfect pinning.
58
+ - For Mobile, consider centering text layers ABOVE or BELOW the subject focal point.
59
+ - For Desktop, place text layers to the SIDES of the subject focal point.
60
+
61
+ ```
62
+
63
+ ---
64
+
65
+ ## 3. The "Intelligence-as-a-Service" Model
66
+
67
+ This workflow enables a powerful business model:
68
+ 1. **The CLI** handles the "hard" computer vision (tracking, depth, optimization).
69
+ 2. **The JSON** stores this intelligence.
70
+ 3. **The AI Agent** uses that intelligence to write the perfectly synced creative layer.
71
+
72
+ You provide the **SDK**, the AI provides the **Implementation**.
@@ -0,0 +1,55 @@
1
+ # Architecture: Declarative Animation
2
+
3
+ ScrollTube 2.0 is a **State-Snapshot Engine**. Unlike traditional animation libraries that rely on imperative callbacks, this engine treats the entire scroll project as a piece of data.
4
+
5
+ ## 1. The Project Configuration (`scrolltube.json`)
6
+
7
+ The heart of every project is a JSON file that describes the entire experience. This allows the state to be:
8
+ - **Portable**: Can be generated by an AI, a server, or a visual editor.
9
+ - **Serializable**: Can be stored in a database or passed via API.
10
+ - **Versioned**: Changes to the animation are tracked like code.
11
+
12
+ ### Core Schema Overview
13
+ The engine expects a `ProjectConfiguration` object (defined in `src/core/types.ts`):
14
+
15
+ - **`settings`**: Base resolutions, scroll modes, and base path.
16
+ - **`assets`**: An array of `SequenceAsset` with multiple `variants` (Mobile vs Desktop).
17
+ - **`timeline`**: A map of `scenes` and `layers`.
18
+
19
+ ---
20
+
21
+ ## 2. Decoupled Rendering Pipeline
22
+
23
+ State management is separated from pixels.
24
+
25
+ 1. **Core Engine**: A non-UI class that manages the `scroll -> frame` math, image preloading, and subject tracking coordinates.
26
+ 2. **React Provider**: Wraps the Engine in a reactive context.
27
+ 3. **UI Components**: `<ScrollTubeCanvas />` and `<SubjectLayer />` represent the "view." You can have multiple view layers tied to the same engine state.
28
+
29
+ ### How it works:
30
+ 1. **Detection**: On initialization and resize, the engine calculates the required **Physical Resolution** (`width * devicePixelRatio`) and checks the `canvas` element's own dimensions.
31
+ 2. **Selection**: It selects the variant that best matches or exceeds the required resolution for the current orientation (Portrait vs Landscape).
32
+ 3. **Hot-Swapping**: If the container size changes or the phone is rotated, the engine immediately swaps to the better-fit image folder without losing scroll place.
33
+
34
+ ---
35
+
36
+ ## 3. Subject-Relative Coordinates
37
+
38
+ This is the key technological shift:
39
+
40
+ - **Traditional**: Content is fixed at `x: 50vw`.
41
+ - **v2.0**: Content is anchored to a `Subject`.
42
+
43
+ Each Asset Variant can contain `subjectTracking` data—frame-by-frame (x,y) coordinates of the main object. The engine combines the image's "Local Coordinates" with your layer's "Relative Offset" to calculate the final screen position.
44
+
45
+ **Formula**:
46
+ `Screen Position = (Subject Center (x,y) + Relative Offset)`
47
+
48
+ This ensures the text follows the product even if the image is cropped or scaled for mobile.
49
+
50
+ ---
51
+
52
+ ## 4. 3D Parallax & Depth Maps
53
+
54
+ ScrollTube 2.0 introduces **Depth-Aware Rendering**.
55
+ By supplying a grayscale depth map (where white is closer and black is farther), the WebGL shader can apply a subtle displacement effect based on mouse or gyro movement. This gives the scroll sequence a premium "3D Parallax" feel without the weight of actual 3D models.
@@ -0,0 +1,105 @@
1
+ # Asset Pipeline: The Universal Engine
2
+
3
+
4
+ The ScrollTube Asset Pipeline is a platform-agnostic engine designed to do the "hard work" of segmentation, tracking, and optimization. It runs exactly the same logic whether you are in your terminal or a WordPress dashboard.
5
+
6
+ ## 1. Universal Architecture
7
+
8
+ The pipeline uses a **Strategy Pattern** with two primary drivers:
9
+
10
+ | Driver | Environment | Technology |
11
+ | :--- | :--- | :--- |
12
+ | **NodeDriver** | CLI / Backend | `sharp`, `ffmpeg-static` |
13
+ | **BrowserDriver** | CMS / Frontend | `ffmpeg.wasm`, `OffscreenCanvas` |
14
+
15
+ This means you have a single source of truth for your processing logic, while benefiting from the best native tools available to each platform.
16
+
17
+ ---
18
+
19
+ ## 2. CLI Usage
20
+
21
+ The `npx stube create` command is the primary wrapper for the pipeline on your local machine.
22
+
23
+ ```bash
24
+ npx stube create <input> [options]
25
+ ```
26
+
27
+ ### Options:
28
+ - `-n, --name <string>`: Project folder name.
29
+ - `-p, --track <text>`: Target object to track (e.g. "red car").
30
+ - `-v, --variants <string>`: Comma-separated target resolutions (e.g. `720,1080`).
31
+ - `-s, --step <number>`: Process every Nth frame. **VITAL for performance**.
32
+ - `--cloud`: Use Fal.ai for tracking (requires `FAL_KEY`).
33
+ - `--depth`: Generate a corresponding image sequence of depth maps for the 3D parallax effect.
34
+
35
+
36
+ ---
37
+
38
+ ## 3. Programmatic Usage (SDK)
39
+
40
+ For building your own CMS plugins or web-based authoring tools, you can import the pipeline directly:
41
+
42
+ ```typescript
43
+ import { AssetPipeline } from 'scrolltube/pipeline';
44
+
45
+ const pipeline = new AssetPipeline({
46
+ apiKey: '...',
47
+ onProgress: (p) => updateUI(p.percent)
48
+ });
49
+
50
+ // Returns a ZIP blob containing the entire project
51
+ const zip = await pipeline.create({
52
+ input: myFileObject,
53
+ name: 'project-name',
54
+ outputZip: true
55
+ });
56
+ ```
57
+
58
+ ### Core Pipeline Steps:
59
+ 1. **Auto-Upload**: If you provide a local `.mp4`, it's automatically uploaded to the cloud for processing.
60
+ 2. **Extraction**: Converts video files into high-quality image sequences.
61
+ 3. **AI Tracking**: Identifies the main subject (using **SAM 3**). Our engine now features **Sticky Tracking**—if the subject is obscured for a few frames, the coordinates hold their last known position.
62
+ 4. **Variant Generation**:
63
+ - **Smart Crop**: Centers the images based on the tracked subject.
64
+ - **Resolution Factory**: Creates Portrait (9:16) and Landscape (16:9) pairs for each target resolution (e.g. 720p, 1080p).
65
+ - **Compression**: Optimized `.webp` generation via Sharp (Node) or Canvas (Browser).
66
+ 5. **Metadata Export**: Generates the final `scrolltube.json` with **root-relative paths** for easier deployment.
67
+
68
+ ---
69
+
70
+ ## 2. Cloud vs Local Processing
71
+
72
+ The pipeline is split into a **Local Implementation** path and a **Cloud-Accelerated** path.
73
+
74
+ ### 🏠 Local Implementation (Free)
75
+ - Uses **FFmpeg** on your machine for extraction.
76
+ - Uses **Sharp** for resizing and cropping.
77
+ - Does **not** include automatic AI point-tracking (uses center-pinned defaults).
78
+
79
+ ### ☁️ Cloud-Accelerated Implementation (Paid)
80
+ - **Fal.ai Integration**: Triggers high-end GPUs to run SAM 3 tracking.
81
+ - **Refinement**: Can be configured to auto-remove backgrounds or upscale low-res sequences using ESRGAN.
82
+ - **CDN Ready**: Prepares assets for cloud hosting.
83
+
84
+ ## 4. Environment Drivers
85
+
86
+ ### 🏠 NodeDriver
87
+ - **Extraction**: Native FFmpeg binary.
88
+ - **Image Engine**: **Sharp** (C++).
89
+
90
+ ### 🌐 BrowserDriver
91
+ - **Extraction**: **ffmpeg.wasm**.
92
+ - **Image Engine**: **OffscreenCanvas** (Hardware-accelerated).
93
+ - **Output**: Persistent IndexedDB or a downloadable **ZIP**.
94
+
95
+ ---
96
+
97
+ ## 3. Configuration (.env.local)
98
+
99
+ To use the cloud features, you must provide your own API keys in your `.env.local`:
100
+
101
+ ```bash
102
+ FAL_KEY="your-fal-api-key"
103
+ ```
104
+
105
+ *Note: This mimics the Remotion "Bring Your Own Key" model for indie developers.*
@@ -0,0 +1,89 @@
1
+ # React Integration
2
+
3
+ The ScrollTube React library is a thin, high-performance wrapper around the Core Engine.
4
+
5
+ ## 1. The Provider Pattern
6
+
7
+ Everything starts with the `ScrollTubeProvider`. It initializes the engine and provides a reactive context for all child components.
8
+
9
+ ```tsx
10
+ import { ScrollTubeProvider } from 'scrolltube/react';
11
+ import projectConfig from './my-project.json';
12
+
13
+ function App() {
14
+ return (
15
+ <ScrollTubeProvider project={projectConfig} scrub={0.1}>
16
+ {/*
17
+ The actual canvas that renders the sequence.
18
+ Can be placed anywhere inside the provider.
19
+ */}
20
+ <ScrollTubeCanvas
21
+ style={{ width: '100%', height: '100vh', objectFit: 'cover' }}
22
+ />
23
+
24
+ <MyContent />
25
+ </ScrollTubeProvider>
26
+ );
27
+ }
28
+ ```
29
+ ### Provider Props:
30
+ - **`project`**: The JSON configuration file generated by the CLI.
31
+ - **`scrub`**: (Optional) Number between `0` and `1`. Sets the smoothing/interpolation factor. `0` is instant, `1` is smooth, `2`+ is heavy lag.
32
+ - **`basePath`**: (Optional) Override the base URL for asset loading.
33
+
34
+ ---
35
+
36
+ The rendering engine is decoupled from the provider. You must include a `<ScrollTubeCanvas />` to see your images.
37
+
38
+ ### Key Props:
39
+ - **`style`**: Standard React styles. Use `objectFit: 'cover'` to ensure the sequence behaves like a background.
40
+ - **`assetId`**: (Optional) Specify which asset from the JSON to render. Defaults to the first one.
41
+ - **`depthEnabled`**: (Optional) Boolean. If true (and if depth maps exist in the assets), enables the mouse-parallax displacement effect.
42
+
43
+ ---
44
+
45
+ ## 3. Using the `<SubjectLayer />`
46
+
47
+ The `<SubjectLayer>` is the primary way to add content that "sticks" to the product in your sequence.
48
+
49
+ ```tsx
50
+ import { SubjectLayer } from 'scrolltube/react';
51
+
52
+ <SubjectLayer offset={{ x: 15, y: -10 }}>
53
+ <div className="callout">
54
+ <h4>4K Ultra Wide</h4>
55
+ <p>Captured at 120fps.</p>
56
+ </div>
57
+ </SubjectLayer>
58
+ ```
59
+
60
+ ### Key Props:
61
+ - **`offset`**: `{ x: number, y: number }`. Positioning relative to the **Subject Center**. This is measured in viewport percentage units (0-100).
62
+ - **`zIndex`**: Control the depth of the layer.
63
+
64
+ ---
65
+
66
+ ## 4. The `useScrollTube` Hook
67
+
68
+ For custom components, you can hook directly into the engine's state.
69
+
70
+ ```tsx
71
+ import { useScrollTube } from 'scrolltube/react';
72
+
73
+ const MyCustomStats = () => {
74
+ const { progress, frame, subjectCoords } = useScrollTube();
75
+
76
+ return (
77
+ <div style={{ opacity: progress }}>
78
+ Current Frame: {frame}
79
+ </div>
80
+ );
81
+ };
82
+ ```
83
+
84
+ ---
85
+
86
+ ## 5. Context Properties
87
+ - `progress`: Number (0 to 1). The global scroll position.
88
+ - `frame`: Number. The current frame index of the active scene.
89
+ - `subjectCoords`: `{ x: number, y: number }`. The current normalized (0-1) position of the subject on the screen.