UNPKG

micro-lottie-react

Version:

The smallest React Lottie player. 15KB. Zero deps. Supports .lottie files.

2 lines (1 loc) 33.7 kB
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react/jsx-runtime"),require("react")):"function"==typeof define&&define.amd?define(["exports","react/jsx-runtime","react"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).MicroLottieReact={},t.jsxRuntime,t.React)}(this,function(t,e,r){"use strict";class i{static async load(t,e={}){const r=this.getCacheKey(t,e);if(!1!==e.cache&&this.cache.has(r))return this.cache.get(r);const i=this.performLoad(t,{url:t,method:"GET",timeout:this.DEFAULT_TIMEOUT,retry:this.DEFAULT_RETRY,cache:!0,...e});return!1!==e.cache&&this.cache.set(r,i),i}static async loadFromSource(t){const e=performance.now();if("string"==typeof t)return this.isUrl(t)?this.load(t):{data:t,format:"json",size:t.length,loadTime:performance.now()-e};if(t instanceof ArrayBuffer)return{data:t,format:"lottie",size:t.byteLength,loadTime:performance.now()-e};if("object"==typeof t){const r=JSON.stringify(t);return{data:r,format:"json",size:r.length,loadTime:performance.now()-e}}throw new Error("Unsupported source type")}static async preload(t,e={}){const r=t.map(t=>this.load(t,e));return Promise.all(r)}static clearCache(){this.cache.clear()}static getCacheInfo(){return{size:this.cache.size,keys:Array.from(this.cache.keys())}}static removeCacheItem(t,e={}){const r=this.getCacheKey(t,e);return this.cache.delete(r)}static async performLoad(t,e){const r=performance.now();let i=null;const s=e.retry||this.DEFAULT_RETRY;for(let n=0;n<s;n++)try{const i=await this.fetchWithTimeout(t,e);if(!i.ok)throw new Error(`HTTP ${i.status}: ${i.statusText}`);const s=this.detectFormat(t,i);let n,a;return"lottie"===s?(n=await i.arrayBuffer(),a=n.byteLength):(n=await i.text(),a=n.length),{data:n,format:s,size:a,loadTime:performance.now()-r}}catch(t){if(i=t,this.isNonRetryableError(t))break;n<s-1&&await this.delay(100*Math.pow(2,n))}throw i||new Error("Failed to load animation")}static async fetchWithTimeout(t,e){const r=new AbortController,i=setTimeout(()=>r.abort(),e.timeout);try{const s=await fetch(t,{method:e.method,headers:e.headers,signal:r.signal});return clearTimeout(i),s}catch(t){if(clearTimeout(i),t instanceof Error&&"AbortError"===t.name)throw new Error(`Request timeout after ${e.timeout}ms`);throw t}}static detectFormat(t,e){const r=t.toLowerCase();if(r.endsWith(".lottie"))return"lottie";if(r.endsWith(".json"))return"json";const i=e.headers.get("content-type")||"";return i.includes("application/json")?"json":i.includes("application/octet-stream")||i.includes("application/zip")?"lottie":"json"}static isUrl(t){try{return new URL(t),!0}catch(e){return t.startsWith("/")||t.startsWith("./")||t.startsWith("../")}}static isNonRetryableError(t){const e=t.message.toLowerCase();return e.includes("404")||e.includes("403")||e.includes("401")||e.includes("syntax error")||e.includes("invalid json")}static getCacheKey(t,e){const r={method:e.method||"GET",headers:e.headers||{}};return`${t}:${JSON.stringify(r)}`}static delay(t){return new Promise(e=>setTimeout(e,t))}static validateAnimationData(t,e){try{if("json"===e){const e=JSON.parse(t);return this.isValidLottieJson(e)}return this.isValidLottieFile(t)}catch(t){return!1}}static isValidLottieJson(t){return"object"==typeof t&&null!==t&&"string"==typeof t.v&&"number"==typeof t.w&&"number"==typeof t.h&&Array.isArray(t.layers)}static isValidLottieFile(t){if(t.byteLength<4)return!1;const e=new Uint8Array(t.slice(0,4)),r=new Uint8Array([80,75,3,4]);return e.every((t,e)=>t===r[e])}static formatFileSize(t){const e=["B","KB","MB","GB"];let r=t,i=0;for(;r>=1024&&i<e.length-1;)r/=1024,i++;return`${r.toFixed(1)} ${e[i]}`}static estimateComplexity(t){if("string"==typeof t)try{t=JSON.parse(t)}catch(t){return"low"}if(!t||!Array.isArray(t.layers))return"low";const e=t.layers.length,r=t.layers.reduce((t,e)=>t+(e.shapes?e.shapes.length:0),0);return e<5&&r<10?"low":e<20&&r<50?"medium":"high"}static optimizeForPerformance(t){if("string"==typeof t)try{t=JSON.parse(t)}catch(e){return t}const e=JSON.parse(JSON.stringify(t));if(e.assets){const t=new Set,r=e=>{e.forEach(e=>{e.refId&&t.add(e.refId),e.layers&&r(e.layers)})};r(e.layers),e.assets=e.assets.filter(e=>t.has(e.id))}return this.roundNumbers(e,2),e}static roundNumbers(t,e=2){if("number"==typeof t)return Math.round(t*Math.pow(10,e))/Math.pow(10,e);Array.isArray(t)?t.forEach((r,i)=>{"number"==typeof r?t[i]=Math.round(r*Math.pow(10,e))/Math.pow(10,e):"object"==typeof r&&null!==r&&this.roundNumbers(r,e)}):"object"==typeof t&&null!==t&&Object.keys(t).forEach(r=>{"number"==typeof t[r]?t[r]=Math.round(t[r]*Math.pow(10,e))/Math.pow(10,e):"object"==typeof t[r]&&this.roundNumbers(t[r],e)})}}i.cache=new Map,i.DEFAULT_TIMEOUT=1e4,i.DEFAULT_RETRY=3;class s{static async parse(t){try{let e;return e="lottie"===t.format||this.isLottieFormat(t.data)?await this.parseLottieFile(t.data):this.parseJSON(t.data),{data:e,duration:this.calculateDuration(e),frameRate:e.fr||30,totalFrames:e.op-e.ip||0,width:e.w||512,height:e.h||512}}catch(t){const e=t instanceof Error?t.message:"Unknown error";throw new Error(`Failed to parse Lottie animation: ${e}`)}}static isLottieFormat(t){if(!(t&&t instanceof ArrayBuffer))return!1;const e=new Uint8Array(t.slice(0,4));return this.arrayEquals(e,this.LOTTIE_MAGIC)}static async parseLottieFile(t){if(t.byteLength>this.MAX_FILE_SIZE)throw new Error("File too large");const e=new DataView(t),r=this.findCentralDirectory(e);if(-1===r)throw new Error("Invalid .lottie file format");const i=this.extractAnimationJson(e,r);return JSON.parse(i)}static parseJSON(t){try{const e=JSON.parse(t);return this.validateLottieData(e),e}catch(t){const e=t instanceof Error?t.message:"Unknown error";throw new Error(`Invalid JSON format: ${e}`)}}static findCentralDirectory(t){for(let e=t.byteLength-22;e>=0;e--)if(101010256===t.getUint32(e,!0)){return t.getUint32(e+16,!0)}return-1}static extractAnimationJson(t,e){if(33639248!==t.getUint32(e,!0))throw new Error("Invalid central directory");const r=t.getUint16(e+28,!0);if(!this.readString(t,e+46,r).includes("animation.json"))throw new Error("animation.json not found in .lottie file");const i=t.getUint32(e+42,!0),s=t.getUint32(e+20,!0),n=i+30+t.getUint16(i+26,!0)+t.getUint16(i+28,!0);return this.readString(t,n,s)}static readString(t,e,r){const i=new Uint8Array(t.buffer,e,r);return(new TextDecoder).decode(i)}static validateLottieData(t){if(!t||"object"!=typeof t)throw new Error("Invalid Lottie data structure");const e=["v","w","h","layers"];for(const r of e)if(!(r in t))throw new Error(`Missing required field: ${r}`);if(!Array.isArray(t.layers))throw new Error("Layers must be an array");if("number"!=typeof t.w||"number"!=typeof t.h)throw new Error("Width and height must be numbers")}static calculateDuration(t){const e=t.fr||30;return((t.op||0)-(t.ip||0))/e*1e3}static arrayEquals(t,e){if(t.length!==e.length)return!1;for(let r=0;r<t.length;r++)if(t[r]!==e[r])return!1;return!0}static optimize(t){const e=JSON.parse(JSON.stringify(t));return this.removeUnusedAssets(e),this.simplifyPaths(e),this.roundNumbers(e),e}static removeUnusedAssets(t){if(!t.assets||!Array.isArray(t.assets))return;const e=new Set,r=t=>{t.forEach(t=>{t.refId&&e.add(t.refId),t.layers&&r(t.layers)})};r(t.layers),t.assets=t.assets.filter(t=>e.has(t.id))}static simplifyPaths(t){const e=t=>{t.shapes&&t.shapes.forEach(t=>{t.it&&this.simplifyShapeItems(t.it)}),t.layers&&t.layers.forEach(e)};t.layers.forEach(e)}static simplifyShapeItems(t){t.forEach(t=>{if("sh"===t.ty&&t.ks&&t.ks.k&&t.ks.k.v){const e=t.ks.k.v;e.length>100&&(t.ks.k.v=this.reducePathComplexity(e))}})}static reducePathComplexity(t){if(t.length<=3)return t;const e=[t[0]];for(let r=1;r<t.length-1;r++){const i=t[r-1],s=t[r],n=t[r+1];this.pointToLineDistance(s,i,n)>.5&&e.push(s)}return e.push(t[t.length-1]),e}static pointToLineDistance(t,e,r){const[i,s]=t,[n,a]=e,[o,h]=r,c=i-n,l=s-a,u=o-n,d=h-a,f=c*u+l*d,m=u*u+d*d;if(0===m)return Math.sqrt(c*c+l*l);const p=f/m,y=i-(p<0?n:p>1?o:n+p*u),w=s-(p<0?a:p>1?h:a+p*d);return Math.sqrt(y*y+w*w)}static roundNumbers(t,e=3){if("number"==typeof t)return Math.round(t*Math.pow(10,e))/Math.pow(10,e);Array.isArray(t)?t.forEach((r,i)=>{"number"==typeof r?t[i]=Math.round(r*Math.pow(10,e))/Math.pow(10,e):"object"==typeof r&&this.roundNumbers(r,e)}):"object"==typeof t&&null!==t&&Object.keys(t).forEach(r=>{"number"==typeof t[r]?t[r]=Math.round(t[r]*Math.pow(10,e))/Math.pow(10,e):"object"==typeof t[r]&&this.roundNumbers(t[r],e)})}}s.LOTTIE_MAGIC=new Uint8Array([80,75,3,4]),s.MAX_FILE_SIZE=52428800;class n{constructor(t,e){if(this.currentFrame=0,this.scaleFactor=1,this.isDestroyed=!1,this.animationData=e,this.canvas=document.createElement("canvas"),this.ctx=this.canvas.getContext("2d"),!this.ctx)throw new Error("Canvas 2D context not supported");this.setupCanvas(t),this.transformMatrix=new DOMMatrix}setupCanvas(t){const{w:e,h:r}=this.animationData;this.canvas.width=e,this.canvas.height=r,this.canvas.style.width="100%",this.canvas.style.height="100%",this.canvas.style.display="block";const i=window.devicePixelRatio||1;this.scaleFactor=i,this.canvas.width=e*i,this.canvas.height=r*i,this.ctx.scale(i,i),this.ctx.imageSmoothingEnabled=!0,this.ctx.imageSmoothingQuality="high",t.appendChild(this.canvas)}render(t){if(!this.isDestroyed){this.currentFrame=t,this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.save();try{this.renderLayers(this.animationData.layers,t)}catch(t){}finally{this.ctx.restore()}}}renderLayers(t,e){const r=[...t].sort((t,e)=>t.ind-e.ind);for(const t of r)this.isLayerVisible(t,e)&&this.renderLayer(t,e)}isLayerVisible(t,e){return e>=t.ip&&e<t.op}renderLayer(t,e){this.ctx.save();try{this.applyTransform(t.ks,e);const r=this.getAnimatedValue(t.ks.o,e);switch(void 0!==r&&(this.ctx.globalAlpha*=r/100),t.ty){case 4:this.renderShapeLayer(t,e);break;case 0:this.renderPrecompLayer(t,e);break;case 1:this.renderSolidLayer(t,e);break;case 2:this.renderImageLayer(t,e);break;case 5:this.renderTextLayer(t,e)}}finally{this.ctx.restore()}}applyTransform(t,e){const r=this.getAnimatedValue(t.a,e)||[0,0],i=this.getAnimatedValue(t.p,e)||[0,0],s=this.getAnimatedValue(t.s,e)||[100,100],n=this.getAnimatedValue(t.r,e)||0;this.ctx.translate(i[0],i[1]),this.ctx.rotate(n*Math.PI/180),this.ctx.scale(s[0]/100,s[1]/100),this.ctx.translate(-r[0],-r[1])}renderShapeLayer(t,e){if(t.shapes)for(const r of t.shapes)this.renderShape(r,e)}renderShape(t,e){if(!t.hd){this.ctx.save();try{switch(t.ty){case"gr":this.renderShapeGroup(t,e);break;case"rc":this.renderRectangle(t,e);break;case"el":this.renderEllipse(t,e);break;case"sh":this.renderPath(t,e);break;case"fl":this.applyFill(t,e);break;case"st":this.applyStroke(t,e);break;case"tr":this.applyShapeTransform(t,e)}}finally{this.ctx.restore()}}}renderShapeGroup(t,e){if(t.it)for(const r of t.it)this.renderShape(r,e)}renderRectangle(t,e){const r=this.getAnimatedValue(t.s,e)||[100,100],i=this.getAnimatedValue(t.p,e)||[0,0],s=this.getAnimatedValue(t.r,e)||0,[n,a]=r,[o,h]=i;this.ctx.beginPath(),s>0?this.ctx.roundRect(o-n/2,h-a/2,n,a,s):this.ctx.rect(o-n/2,h-a/2,n,a)}renderEllipse(t,e){const r=this.getAnimatedValue(t.s,e)||[100,100],i=this.getAnimatedValue(t.p,e)||[0,0],[s,n]=r,[a,o]=i;this.ctx.beginPath(),this.ctx.ellipse(a,o,s/2,n/2,0,0,2*Math.PI)}renderPath(t,e){const r=this.getAnimatedValue(t.pt,e);if(!r||!r.v)return;const i=r.v,s=r.i||[],n=r.o||[],a=r.c||!1;if(this.ctx.beginPath(),i.length>0){this.ctx.moveTo(i[0][0],i[0][1]);for(let t=1;t<i.length;t++){const e=i[t-1],r=i[t],a=n[t-1]||[0,0],o=s[t]||[0,0];this.ctx.bezierCurveTo(e[0]+a[0],e[1]+a[1],r[0]+o[0],r[1]+o[1],r[0],r[1])}if(a&&i.length>2){const t=i[i.length-1],e=i[0],r=n[i.length-1]||[0,0],a=s[0]||[0,0];this.ctx.bezierCurveTo(t[0]+r[0],t[1]+r[1],e[0]+a[0],e[1]+a[1],e[0],e[1]),this.ctx.closePath()}}}applyFill(t,e){const r=this.getAnimatedValue(t.c,e),i=this.getAnimatedValue(t.o,e);if(r){const[t,e,s]=r.map(t=>Math.round(255*t)),n=i?i/100:1;this.ctx.fillStyle=`rgba(${t}, ${e}, ${s}, ${n})`,this.ctx.fill()}}applyStroke(t,e){const r=this.getAnimatedValue(t.c,e),i=this.getAnimatedValue(t.o,e),s=this.getAnimatedValue(t.w,e);if(r&&s){const[e,n,a]=r.map(t=>Math.round(255*t)),o=i?i/100:1;this.ctx.strokeStyle=`rgba(${e}, ${n}, ${a}, ${o})`,this.ctx.lineWidth=s,this.ctx.lineCap=this.getLineCap(t.lc),this.ctx.lineJoin=this.getLineJoin(t.lj),t.ml&&(this.ctx.miterLimit=t.ml),this.ctx.stroke()}}applyShapeTransform(t,e){const r=this.getAnimatedValue(t.p,e)||[0,0],i=this.getAnimatedValue(t.s,e)||[100,100],s=this.getAnimatedValue(t.r,e)||0;this.ctx.translate(r[0],r[1]),this.ctx.rotate(s*Math.PI/180),this.ctx.scale(i[0]/100,i[1]/100)}renderPrecompLayer(t,e){var r;const i=null===(r=this.animationData.assets)||void 0===r?void 0:r.find(e=>e.id===t.refId);i&&i.layers&&this.renderLayers(i.layers,e)}renderSolidLayer(t,e){const r=t.sc||"#ff0000",i=t.sw||t.w||100,s=t.sh||t.h||100;this.ctx.fillStyle=r,this.ctx.fillRect(0,0,i,s)}renderImageLayer(t,e){}renderTextLayer(t,e){}getAnimatedValue(t,e){if(!t)return;if(!t.a)return t.k;const r=t.k;if(!Array.isArray(r))return r;let i=r[0],s=r[r.length-1];for(let t=0;t<r.length-1;t++)if(e>=r[t].t&&e<r[t+1].t){i=r[t],s=r[t+1];break}const n=(e-i.t)/(s.t-i.t);return this.interpolateValue(i.s,s.s,Math.max(0,Math.min(1,n)))}interpolateValue(t,e,r){return"number"==typeof t&&"number"==typeof e?t+(e-t)*r:Array.isArray(t)&&Array.isArray(e)?t.map((t,i)=>{const s=e[i]||t;return"number"==typeof t?t+(s-t)*r:t}):r<.5?t:e}getLineCap(t){switch(t){case 1:default:return"butt";case 2:return"round";case 3:return"square"}}getLineJoin(t){switch(t){case 1:default:return"miter";case 2:return"round";case 3:return"bevel"}}resize(){if(this.isDestroyed)return;const t=this.canvas.parentElement;if(!t)return;const e=t.getBoundingClientRect(),r=window.devicePixelRatio||1;this.canvas.width=e.width*r,this.canvas.height=e.height*r,this.ctx.scale(r,r),this.render(this.currentFrame)}destroy(){this.isDestroyed=!0,this.canvas.parentElement&&this.canvas.parentElement.removeChild(this.canvas)}getCanvas(){return this.canvas}}class a{constructor(t,e){this.currentFrame=0,this.layerElements=new Map,this.isDestroyed=!1,this.container=t,this.animationData=e,this.setupSVG(),this.createLayerElements()}setupSVG(){const{w:t,h:e}=this.animationData;this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.setAttribute("viewBox",`0 0 ${t} ${e}`),this.svg.setAttribute("width","100%"),this.svg.setAttribute("height","100%"),this.svg.style.display="block",this.container.appendChild(this.svg)}createLayerElements(){const t=[...this.animationData.layers].sort((t,e)=>t.ind-e.ind);for(const e of t){const t=this.createLayerGroup(e);this.layerElements.set(e.ind,t),this.svg.appendChild(t)}}createLayerGroup(t){const e=document.createElementNS("http://www.w3.org/2000/svg","g");return e.setAttribute("data-layer-index",t.ind.toString()),e.setAttribute("data-layer-name",t.nm||""),e}render(t){if(!this.isDestroyed){this.currentFrame=t;for(const e of this.animationData.layers)this.updateLayer(e,t)}}updateLayer(t,e){const r=this.layerElements.get(t.ind);if(!r)return;const i=e>=t.ip&&e<t.op;if(r.style.display=i?"block":"none",!i)return;const s=this.getTransformString(t.ks,e);r.setAttribute("transform",s);const n=this.getAnimatedValue(t.ks.o,e);switch(void 0!==n&&r.setAttribute("opacity",(n/100).toString()),t.ty){case 4:this.updateShapeLayer(t,r,e);break;case 0:this.updatePrecompLayer(t,r,e);break;case 1:this.updateSolidLayer(t,r,e);break;case 2:this.renderImageLayer(t,r,e);break;case 5:this.renderTextLayer(t,r,e)}}getTransformString(t,e){const r=[],i=this.getAnimatedValue(t.a,e)||[0,0],s=this.getAnimatedValue(t.p,e)||[0,0],n=this.getAnimatedValue(t.s,e)||[100,100],a=this.getAnimatedValue(t.r,e)||0;return 0===s[0]&&0===s[1]||r.push(`translate(${s[0]}, ${s[1]})`),0!==a&&r.push(`rotate(${a})`),100===n[0]&&100===n[1]||r.push(`scale(${n[0]/100}, ${n[1]/100})`),0===i[0]&&0===i[1]||r.push(`translate(${-i[0]}, ${-i[1]})`),r.join(" ")}updateShapeLayer(t,e,r){if(t.shapes){e.innerHTML="";for(const i of t.shapes){const t=this.createShapeElement(i,r);t&&e.appendChild(t)}}}createShapeElement(t,e){if(t.hd)return null;switch(t.ty){case"gr":return this.createShapeGroup(t,e);case"rc":return this.createRectangle(t,e);case"el":return this.createEllipse(t,e);case"sh":return this.createPath(t,e);default:return null}}createShapeGroup(t,e){if(!t.it)return null;const r=document.createElementNS("http://www.w3.org/2000/svg","g"),i=[];let s=null,n=null,a=null,o=null;for(const r of t.it)switch(r.ty){case"sh":case"rc":case"el":{const t=this.createShapeElement(r,e);t&&i.push(t);break}case"fl":s=this.getFillStyle(r,e);break;case"st":{const t=this.getStrokeStyle(r,e);n=t.style,a=t.width;break}case"tr":o=this.getShapeTransformString(r,e)}for(const t of i)s?t.setAttribute("fill",s):t.setAttribute("fill","none"),n&&a&&(t.setAttribute("stroke",n),t.setAttribute("stroke-width",a.toString()));o&&r.setAttribute("transform",o);for(const t of i)r.appendChild(t);return r}createRectangle(t,e){const r=document.createElementNS("http://www.w3.org/2000/svg","rect"),i=this.getAnimatedValue(t.s,e)||[100,100],s=this.getAnimatedValue(t.p,e)||[0,0],n=this.getAnimatedValue(t.r,e)||0,[a,o]=i,[h,c]=s;return r.setAttribute("x",(h-a/2).toString()),r.setAttribute("y",(c-o/2).toString()),r.setAttribute("width",a.toString()),r.setAttribute("height",o.toString()),n>0&&(r.setAttribute("rx",n.toString()),r.setAttribute("ry",n.toString())),r}createEllipse(t,e){const r=document.createElementNS("http://www.w3.org/2000/svg","ellipse"),i=this.getAnimatedValue(t.s,e)||[100,100],s=this.getAnimatedValue(t.p,e)||[0,0],[n,a]=i,[o,h]=s;return r.setAttribute("cx",o.toString()),r.setAttribute("cy",h.toString()),r.setAttribute("rx",(n/2).toString()),r.setAttribute("ry",(a/2).toString()),r}createPath(t,e){const r=document.createElementNS("http://www.w3.org/2000/svg","path"),i=this.getAnimatedValue(t.pt,e);if(i&&i.v){const t=this.buildPathString(i);r.setAttribute("d",t)}return r}buildPathString(t){const e=t.v||[],r=t.i||[],i=t.o||[],s=t.c||!1;if(0===e.length)return"";const n=[];n.push(`M ${e[0][0]} ${e[0][1]}`);for(let t=1;t<e.length;t++){const s=e[t-1],a=e[t],o=i[t-1]||[0,0],h=r[t]||[0,0],c=s[0]+o[0],l=s[1]+o[1],u=a[0]+h[0],d=a[1]+h[1];n.push(`C ${c} ${l} ${u} ${d} ${a[0]} ${a[1]}`)}if(s&&e.length>2){const t=e[e.length-1],s=e[0],a=i[e.length-1]||[0,0],o=r[0]||[0,0],h=t[0]+a[0],c=t[1]+a[1],l=s[0]+o[0],u=s[1]+o[1];n.push(`C ${h} ${c} ${l} ${u} ${s[0]} ${s[1]}`),n.push("Z")}return n.join(" ")}getFillStyle(t,e){const r=this.getAnimatedValue(t.c,e),i=this.getAnimatedValue(t.o,e);if(!r)return null;const[s,n,a]=r.map(t=>Math.round(255*t));return`rgba(${s}, ${n}, ${a}, ${i?i/100:1})`}getStrokeStyle(t,e){const r=this.getAnimatedValue(t.c,e),i=this.getAnimatedValue(t.o,e),s=this.getAnimatedValue(t.w,e);if(!r||!s)return{style:null,width:null};const[n,a,o]=r.map(t=>Math.round(255*t));return{style:`rgba(${n}, ${a}, ${o}, ${i?i/100:1})`,width:s}}getShapeTransformString(t,e){const r=[],i=this.getAnimatedValue(t.p,e)||[0,0],s=this.getAnimatedValue(t.s,e)||[100,100],n=this.getAnimatedValue(t.r,e)||0;return 0===i[0]&&0===i[1]||r.push(`translate(${i[0]}, ${i[1]})`),0!==n&&r.push(`rotate(${n})`),100===s[0]&&100===s[1]||r.push(`scale(${s[0]/100}, ${s[1]/100})`),r.join(" ")}updatePrecompLayer(t,e,r){var i;const s=null===(i=this.animationData.assets)||void 0===i?void 0:i.find(e=>e.id===t.refId);s&&s.layers}updateSolidLayer(t,e,r){e.innerHTML="";const i=document.createElementNS("http://www.w3.org/2000/svg","rect");i.setAttribute("x","0"),i.setAttribute("y","0"),i.setAttribute("width",(t.w||100).toString()),i.setAttribute("height",(t.h||100).toString()),i.setAttribute("fill","#000000"),e.appendChild(i)}renderImageLayer(t,e,r){}renderTextLayer(t,e,r){}getAnimatedValue(t,e){if(!t)return;if(!t.a)return t.k;const r=t.k;if(!Array.isArray(r))return r;let i=r[0],s=r[r.length-1];for(let t=0;t<r.length-1;t++)if(e>=r[t].t&&e<r[t+1].t){i=r[t],s=r[t+1];break}const n=(e-i.t)/(s.t-i.t);return this.interpolateValue(i.s,s.s,Math.max(0,Math.min(1,n)))}interpolateValue(t,e,r){return"number"==typeof t&&"number"==typeof e?t+(e-t)*r:Array.isArray(t)&&Array.isArray(e)?t.map((t,i)=>{const s=e[i]||t;return"number"==typeof t?t+(s-t)*r:t}):r<.5?t:e}resize(){}destroy(){this.isDestroyed=!0,this.layerElements.clear(),this.svg.parentElement&&this.svg.parentElement.removeChild(this.svg)}getSVG(){return this.svg}}class o{constructor(t){this.currentFrame=0,this.l=!1,this.u=!1,this.m=!0,this.direction=1,this.speed=1,this.loop=!0,this.autoplay=!0,this.useSubFrames=!1,this.segments=null,this.animationId=null,this.lastFrameTime=0,this.eventListeners=new Map,this.animationData=t.animationData,this.loop=t.loop,this.autoplay=t.autoplay,this.frameRate=this.animationData.fr||30,this.inPoint=this.animationData.ip||0,this.outPoint=this.animationData.op||60,this.totalFrames=this.outPoint-this.inPoint,this.frameInterval=1e3/this.frameRate,"svg"===t.renderer?this.renderer=new a(t.container,this.animationData):this.renderer=new n(t.container,this.animationData),this.currentFrame=this.inPoint,this.autoplay?this.play():this.renderFrame()}play(){this.l||(this.l=!0,this.u=!1,this.m=!1,this.lastFrameTime=performance.now(),this.startAnimation(),this.dispatchEvent("complete"))}pause(){this.l&&(this.l=!1,this.u=!0,this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null),this.dispatchEvent("complete"))}stop(){this.l=!1,this.u=!1,this.m=!0,this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null),this.currentFrame=this.inPoint,this.renderFrame(),this.dispatchEvent("complete")}seek(t){const e=Math.max(0,Math.min(1,t)),r=this.segments?this.segments[0]:this.inPoint,i=(this.segments?this.segments[1]:this.outPoint)-r;this.currentFrame=r+i*e,this.renderFrame(),this.dispatchEvent("enterFrame")}goToAndPlay(t){this.currentFrame=Math.max(this.inPoint,Math.min(this.outPoint,t)),this.renderFrame(),this.play()}goToAndStop(t){this.currentFrame=Math.max(this.inPoint,Math.min(this.outPoint,t)),this.renderFrame(),this.pause()}playSegments(t,e=!1){this.segments=[Math.max(this.inPoint,t[0]),Math.min(this.outPoint,t[1])],!e&&this.l||(this.currentFrame=this.segments[0],this.play())}setSpeed(t){this.speed=Math.max(.1,Math.min(5,t))}setDirection(t){this.direction=t}setSubframe(t){this.useSubFrames=t}resize(){this.renderer.resize()}destroy(){this.stop(),this.renderer.destroy(),this.eventListeners.clear(),this.dispatchEvent("destroy")}addEventListener(t,e){this.eventListeners.has(t)||this.eventListeners.set(t,[]),this.eventListeners.get(t).push(e)}removeEventListener(t,e){const r=this.eventListeners.get(t);if(r){const t=r.indexOf(e);t>-1&&r.splice(t,1)}}getCurrentFrame(){return this.currentFrame}getTotalFrames(){return this.totalFrames}getFrameRate(){return this.frameRate}getDuration(){return this.totalFrames/this.frameRate*1e3}getProgress(){const t=this.segments?this.segments[0]:this.inPoint,e=(this.segments?this.segments[1]:this.outPoint)-t;return 0===e?0:(this.currentFrame-t)/e}isPlaying(){return this.l}isPaused(){return this.u}isStopped(){return this.m}startAnimation(){const t=e=>{if(!this.l)return;const r=e-this.lastFrameTime,i=this.frameInterval/this.speed;r>=i&&(this.updateFrame(),this.renderFrame(),this.lastFrameTime=e-r%i),this.animationId=requestAnimationFrame(t)};this.animationId=requestAnimationFrame(t)}updateFrame(){const t=this.segments?this.segments[0]:this.inPoint,e=this.segments?this.segments[1]:this.outPoint;this.useSubFrames?this.currentFrame+=this.direction*this.speed:this.currentFrame+=this.direction,this.direction>0&&this.currentFrame>=e?this.loop?(this.currentFrame=t,this.dispatchEvent("loopComplete")):(this.currentFrame=e-1,this.pause(),this.dispatchEvent("complete")):this.direction<0&&this.currentFrame<=t&&(this.loop?(this.currentFrame=e-1,this.dispatchEvent("loopComplete")):(this.currentFrame=t,this.pause(),this.dispatchEvent("complete"))),this.dispatchEvent("enterFrame")}renderFrame(){try{this.renderer.render(this.currentFrame)}catch(t){this.dispatchEvent("error",{error:t})}}dispatchEvent(t,e){const r=this.eventListeners.get(t);if(!r)return;const i={type:t,currentTime:this.currentFrame,totalTime:this.totalFrames,direction:this.direction,...e};r.forEach(t=>{try{t(i)}catch(t){}})}getAnimationData(){return this.animationData}isLoaded(){return!!this.animationData}getRendererType(){return this.renderer instanceof n?"canvas":"svg"}setLoop(t){this.loop=t}getLoop(){return this.loop}getSpeed(){return this.speed}getDirection(){return this.direction}getSegments(){return this.segments}clearSegments(){this.segments=null}getInPoint(){return this.inPoint}getOutPoint(){return this.outPoint}}class h{constructor(){this.performanceClass=null}static getInstance(){return h.instance||(h.instance=new h),h.instance}async detectPerformance(){if(this.performanceClass)return this.performanceClass;const t=(await this.testRenderPerformance()+this.getDeviceScore())/2;return this.performanceClass=t>=.8?"high":t>=.5?"medium":"low",this.performanceClass}async testRenderPerformance(){return new Promise(t=>{const e=document.createElement("canvas");e.width=300,e.height=300;const r=e.getContext("2d"),i=performance.now();let s=0;const n=()=>{if(r.clearRect(0,0,300,300),r.fillStyle=`hsl(${10*s}, 50%, 50%)`,r.fillRect(s%300,50,50,50),s++,performance.now()-i<100)requestAnimationFrame(n);else{const e=s/.1,r=Math.min(e/60,1);t(r)}};requestAnimationFrame(n)})}getDeviceScore(){let t=.5;if("hardwareConcurrency"in navigator){const e=navigator.hardwareConcurrency;t+=Math.min(e/8,.3)}if("memory"in performance){const e=performance.memory.jsHeapSizeLimit/1024/1024;t+=Math.min(e/1024,.2)}const e=window.devicePixelRatio||1;return e<=1?t+=.1:e>=3&&(t-=.1),Math.max(0,Math.min(1,t))}isMobile(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)}supportsHardwareAcceleration(){const t=document.createElement("canvas");return!!(t.getContext("webgl")||t.getContext("experimental-webgl"))}getRecommendedSettings(){const t=this.performanceClass||"medium",e=this.isMobile();switch(t){case"high":return{renderer:"canvas",quality:"high",maxFps:60,enableSubFrames:!0};case"medium":return{renderer:"canvas",quality:"medium",maxFps:e?30:45,enableSubFrames:!1};default:return{renderer:"svg",quality:"low",maxFps:24,enableSubFrames:!1}}}}class c{static debounce(t,e){let r;return(...i)=>{clearTimeout(r),r=setTimeout(()=>t(...i),e)}}static throttle(t,e){let r;return(...i)=>{r||(t(...i),r=!0,setTimeout(()=>r=!1,e))}}static requestIdleCallback(t,e=5e3){return"requestIdleCallback"in window?window.requestIdleCallback(t,{timeout:e}):setTimeout(t,16)}static cancelIdleCallback(t){"cancelIdleCallback"in window?window.cancelIdleCallback(t):clearTimeout(t)}static prefersReducedMotion(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}static isInPowerSaveMode(){const t=performance.now();let e=0;return new Promise(r=>{const i=()=>{if(e++,performance.now()-t<100)requestAnimationFrame(i);else{r(e/.1<30)}};requestAnimationFrame(i)})}}const l=r.forwardRef(({src:t,autoplay:n=!0,loop:a=!0,renderer:l="canvas",speed:u=1,direction:d=1,segments:f,style:m,className:p,onComplete:y,onProgress:w,onError:g,onLoad:b,preserveAspectRatio:v="xMidYMid meet",rendererSettings:M={}},S)=>{const $=r.useRef(null),A=r.useRef(null),[F,L]=r.useState(!1),[k,E]=r.useState(null),[T,P]=r.useState(!1);r.useImperativeHandle(S,()=>({play:()=>{var t;return null===(t=A.current)||void 0===t?void 0:t.play()},pause:()=>{var t;return null===(t=A.current)||void 0===t?void 0:t.pause()},stop:()=>{var t;return null===(t=A.current)||void 0===t?void 0:t.stop()},seek:t=>{var e;return null===(e=A.current)||void 0===e?void 0:e.seek(t)},getCurrentFrame:()=>{var t;return(null===(t=A.current)||void 0===t?void 0:t.getCurrentFrame())||0},getTotalFrames:()=>{var t;return(null===(t=A.current)||void 0===t?void 0:t.getTotalFrames())||0},getProgress:()=>{var t;return(null===(t=A.current)||void 0===t?void 0:t.getProgress())||0},isPlaying:()=>{var t;return(null===(t=A.current)||void 0===t?void 0:t.isPlaying())||!1},isPaused:()=>{var t;return(null===(t=A.current)||void 0===t?void 0:t.isPaused())||!1},isStopped:()=>{var t;return(null===(t=A.current)||void 0===t?void 0:t.isStopped())||!0}}),[]),r.useEffect(()=>{if(!$.current)return;const t=new IntersectionObserver(([e])=>{e.isIntersecting&&(P(!0),t.disconnect())},{rootMargin:"50px",threshold:.1});return t.observe($.current),()=>t.disconnect()},[]),r.useEffect(()=>{if(!T||!$.current)return;let e=!1;return(async()=>{try{E(null);const r=await i.loadFromSource(t);if(e)return;const c=await s.parse({data:r.data,format:r.format});if(e)return;const m=h.getInstance(),p=await m.detectPerformance(),g=m.getRecommendedSettings(),v="low"===p?g.renderer:l,S=new o({container:$.current,renderer:v,loop:a,autoplay:n,animationData:c.data,rendererSettings:M});if(e)return void S.destroy();S.setSpeed(u),S.setDirection(d),f&&S.playSegments(f),y&&S.addEventListener("complete",y),w&&S.addEventListener("enterFrame",()=>{w(S.getProgress())}),A.current=S,L(!0),b&&b()}catch(t){if(!e){const e=t instanceof Error?t:new Error("Failed to load animation");E(e),g&&g(e)}}})(),()=>{e=!0,A.current&&(A.current.destroy(),A.current=null)}},[T,t,n,a,l,M,b,g]),r.useEffect(()=>{A.current&&A.current.setSpeed(u)},[u]),r.useEffect(()=>{A.current&&A.current.setDirection(d)},[d]),r.useEffect(()=>{A.current&&(f?A.current.playSegments(f):A.current.clearSegments())},[f]),r.useEffect(()=>{const t=c.debounce(()=>{A.current&&A.current.resize()},100);return window.addEventListener("resize",t),()=>window.removeEventListener("resize",t)},[]),r.useEffect(()=>{const t=()=>{A.current&&(document.hidden?A.current.isPlaying()&&A.current.pause():n&&A.current.isPaused()&&A.current.play())};return document.addEventListener("visibilitychange",t),()=>document.removeEventListener("visibilitychange",t)},[n]),r.useEffect(()=>{c.prefersReducedMotion()&&A.current&&A.current.pause()},[]);const x={display:"block",width:"100%",height:"100%",overflow:"hidden",...m};return k?e.jsx("div",{ref:$,className:p,style:x,role:"img","aria-label":"Animation failed to load",children:e.jsx("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",width:"100%",height:"100%",color:"#999",fontSize:"14px",textAlign:"center"},children:"Failed to load animation"})}):!F&&T?e.jsx("div",{ref:$,className:p,style:x,role:"img","aria-label":"Animation loading",children:e.jsx("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",width:"100%",height:"100%",color:"#999",fontSize:"14px"},children:"Loading animation..."})}):e.jsx("div",{ref:$,className:p,style:x,role:"img","aria-label":"Lottie animation"})});l.displayName="LottiePlayer",t.LottiePlayer=l,t.default=l,t.useLottie=function(t){const{container:e,src:n,renderer:a="canvas",autoplay:l=!0,loop:u=!0,speed:d=1,direction:f=1,segments:m,onComplete:p,onProgress:y,onError:w,onLoad:g,rendererSettings:b={}}=t,v=r.useRef(null),[M,S]=r.useState(!1),[$,A]=r.useState(!1),[F,L]=r.useState(!1),[k,E]=r.useState(!0),[T,P]=r.useState(0),[x,j]=r.useState(0),[C,O]=r.useState(0),[I,N]=r.useState(0),[z,D]=r.useState(30),[q,J]=r.useState(null),[R,U]=r.useState(null);r.useEffect(()=>{if(!e.current||!n)return;let t=!1;return(async()=>{try{U(null);const r=await i.loadFromSource(n);if(t)return;const c=await s.parse({data:r.data,format:r.format});if(t)return;const w=h.getInstance(),M=await w.detectPerformance(),$=w.getRecommendedSettings(),F="low"===M?$.renderer:a,k=new o({container:e.current,renderer:F,loop:u,autoplay:l,animationData:c.data,rendererSettings:b});if(t)return void k.destroy();k.setSpeed(d),k.setDirection(f),m&&k.playSegments(m),k.addEventListener("complete",()=>{A(!1),L(!1),E(!0),p&&p()}),k.addEventListener("enterFrame",()=>{const t=k.getCurrentFrame(),e=k.getProgress();j(t),P(e),y&&y(e)}),v.current=k,J(c.data),O(k.getTotalFrames()),N(k.getDuration()),D(k.getFrameRate()),S(!0),A(k.isPlaying()),L(k.isPaused()),E(k.isStopped()),g&&g()}catch(e){if(!t){const t=e instanceof Error?e:new Error("Failed to load animation");U(t),w&&w(t)}}})(),()=>{t=!0,v.current&&(v.current.destroy(),v.current=null)}},[e,n,a,l,u,b,g,w]),r.useEffect(()=>{v.current&&v.current.setSpeed(d)},[d]),r.useEffect(()=>{v.current&&v.current.setDirection(f)},[f]),r.useEffect(()=>{v.current&&(m?v.current.playSegments(m):v.current.clearSegments())},[m]);const V=r.useCallback(()=>{v.current&&(v.current.play(),A(!0),L(!1),E(!1))},[]),B=r.useCallback(()=>{v.current&&(v.current.pause(),A(!1),L(!0),E(!1))},[]),G=r.useCallback(()=>{v.current&&(v.current.stop(),A(!1),L(!1),E(!0),P(0),j(0))},[]),H=r.useCallback(t=>{if(v.current){const e=Math.max(0,Math.min(1,t));v.current.seek(e),P(e);const r=Math.round(e*C);j(r)}},[C]),K=r.useCallback(t=>{v.current&&v.current.setSpeed(t)},[]),W=r.useCallback(t=>{v.current&&v.current.setDirection(t)},[]),_=r.useCallback(t=>{if(v.current){v.current.goToAndPlay(t),A(!0),L(!1),E(!1);P(C>0?t/C:0),j(t)}},[C]),Y=r.useCallback(t=>{if(v.current){v.current.goToAndStop(t),A(!1),L(!0),E(!1);P(C>0?t/C:0),j(t)}},[C]),Z=r.useCallback((t,e=!1)=>{v.current&&(v.current.playSegments(t,e),A(!0),L(!1),E(!1))},[]),Q=r.useCallback(t=>{v.current&&v.current.setSubframe(t)},[]);return r.useEffect(()=>{const t=c.debounce(()=>{v.current&&v.current.resize()},100);return window.addEventListener("resize",t),()=>window.removeEventListener("resize",t)},[]),{play:V,pause:B,stop:G,seek:H,setSpeed:K,setDirection:W,goToAndPlay:_,goToAndStop:Y,playSegments:Z,setSubframe:Q,isPlaying:$,isPaused:F,isStopped:k,progress:T,currentFrame:x,totalFrames:C,duration:I,frameRate:z,animationData:q,isLoaded:M,error:R}},Object.defineProperty(t,"M",{value:!0})});