@taole/giftstage 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -194,6 +194,7 @@ Promise<GiftHandle>
194
194
  - `y: number | \`${number}%\``
195
195
  - `width?: number`
196
196
  - `height?: number`
197
+ - `useOriginalSize?: boolean`
197
198
  - `objectFit?: 'contain' | 'fill'`
198
199
  - `loop?: number`
199
200
  - `0` 表示无限循环
@@ -215,8 +216,10 @@ Promise<GiftHandle>
215
216
  - 两个都传:按传入值显示
216
217
  - 只传 `width`:`height` 按礼物原始宽高比自动补全
217
218
  - 只传 `height`:`width` 按礼物原始宽高比自动补全
218
- - 两个都不传:默认使用礼物原始宽高
219
- - 如果两个都不传,且礼物原始宽高大于当前画布,则会按画布尺寸等比缩小后再显示
219
+ - 两个都不传:按当前画布尺寸做等比 `contain`
220
+ - 也就是会在画布内尽可能放大或缩小,并保持礼物原始宽高比
221
+ - 如果 `useOriginalSize: true`,且礼物原始尺寸本身小于画布,则优先使用礼物原始尺寸
222
+ - 如果 `useOriginalSize: true`,但礼物原始尺寸超出画布,则仍会按画布尺寸等比缩小
220
223
 
221
224
  例如:
222
225
 
@@ -230,7 +233,20 @@ await stage.addGift({
230
233
  });
231
234
  ```
232
235
 
233
- 这时会使用该礼物的原始尺寸;如果原始尺寸超出舞台,则自动缩放到舞台内。
236
+ 这时会按舞台尺寸做等比适配,并保持礼物原始宽高比。
237
+
238
+ 如果你希望“小礼物保持原始尺寸,大礼物再缩小”,可以这样:
239
+
240
+ ```ts
241
+ await stage.addGift({
242
+ type: 'svga',
243
+ source: 'https://example.com/demo.svga',
244
+ x: '50%',
245
+ y: '50%',
246
+ useOriginalSize: true,
247
+ loop: 0,
248
+ });
249
+ ```
234
250
 
235
251
  ### 百分比坐标
236
252
 
@@ -8319,5 +8319,5 @@ async function xu(r) {
8319
8319
  v_texcoord = a_texCoord;
8320
8320
  v_alpha_texCoord = a_alpha_texCoord;
8321
8321
  }
8322
- `;function md(g,A,t,e){const i=new Float32Array(t.size*an),I=A.get(e);if(!I||I.length===0)return i;const[s,n]=g.info.rgbFrame;let B=0;for(const C of I){const Q=t.get(String(C.srcId));if(!Q)continue;if(B+an>i.length)break;const[a,o,r,E]=C.frame,[h,c,f,d]=C.mFrame,u=rn(a+s,o+n,r,E,g.info.videoW,g.info.videoH),p=rn(h,c,f,d,g.info.videoW,g.info.videoH);i[B++]=Q,i[B++]=u[0],i[B++]=u[1],i[B++]=u[2],i[B++]=u[3],i[B++]=p[0],i[B++]=p[1],i[B++]=p[2],i[B++]=p[3]}return i}class Gd{constructor(A,t,e,i,I){this.config=A,this.frameMap=t,oA(this,"canvas"),oA(this,"gl"),oA(this,"program"),oA(this,"vertexShader"),oA(this,"fragmentShader"),oA(this,"vertexBuffer"),oA(this,"videoTexture"),oA(this,"imagePosLoc"),oA(this,"resourceEntries"),oA(this,"textureUnitBySrcId",new Map);var s;if(e.size===0)throw new Error("VAP mix composer requires at least one slot resource");this.canvas=ud(i,I);const n=this.canvas.getContext("webgl2",{alpha:!0,antialias:!1,depth:!1,premultipliedAlpha:!1,preserveDrawingBuffer:!1,stencil:!1})||this.canvas.getContext("webgl",{alpha:!0,antialias:!1,depth:!1,premultipliedAlpha:!1,preserveDrawingBuffer:!1,stencil:!1})||this.canvas.getContext("experimental-webgl");if(!n)throw new Error("VAP mixed rendering requires WebGL support");this.gl=n;const B=Math.max(1,n.getParameter(n.MAX_TEXTURE_IMAGE_UNITS)),C=Math.max(0,B-1),Q=[];let a=1;for(const u of(s=A.src)!=null?s:[]){const p=e.get(String(u.srcId));if(!p)continue;if(a>C){console.warn("[GiftStage] VAP mixed resources exceed texture unit limit, skipping",{srcId:u.srcId,srcTag:u.srcTag,maxUnits:B});continue}const D=KB(n,a,p.source,!0),y={srcId:String(u.srcId),unit:a,texture:D};Q.push(y),this.textureUnitBySrcId.set(y.srcId,y.unit),a++}if(Q.length===0)throw new Error("VAP mixed rendering could not bind any slot resources");this.resourceEntries=Q;const o=wd(n,yd,pd(this.resourceEntries.length));this.program=o.program,this.vertexShader=o.vertexShader,this.fragmentShader=o.fragmentShader,this.imagePosLoc=n.getUniformLocation(this.program,"image_pos"),this.videoTexture=KB(n,0);const r=n.getUniformLocation(this.program,"u_image_video");r!==null&&n.uniform1i(r,0);for(const u of this.resourceEntries){const p=n.getUniformLocation(this.program,`u_image${u.unit}`);p!==null&&n.uniform1i(p,u.unit)}const E=n.createBuffer();if(!E)throw new Error("Failed to create VAP mix vertex buffer");this.vertexBuffer=E,n.bindBuffer(n.ARRAY_BUFFER,this.vertexBuffer),n.bufferData(n.ARRAY_BUFFER,Dd(A.info),n.STATIC_DRAW);const h=6*Float32Array.BYTES_PER_ELEMENT,c=n.getAttribLocation(this.program,"a_position"),f=n.getAttribLocation(this.program,"a_texCoord"),d=n.getAttribLocation(this.program,"a_alpha_texCoord");n.enableVertexAttribArray(c),n.vertexAttribPointer(c,2,n.FLOAT,!1,h,0),n.enableVertexAttribArray(f),n.vertexAttribPointer(f,2,n.FLOAT,!1,h,2*Float32Array.BYTES_PER_ELEMENT),n.enableVertexAttribArray(d),n.vertexAttribPointer(d,2,n.FLOAT,!1,h,4*Float32Array.BYTES_PER_ELEMENT),n.viewport(0,0,this.canvas.width,this.canvas.height),n.disable(n.BLEND),n.disable(n.DEPTH_TEST),n.clearColor(0,0,0,0),n.pixelStorei(n.UNPACK_PREMULTIPLY_ALPHA_WEBGL,0),n.pixelStorei(n.UNPACK_COLORSPACE_CONVERSION_WEBGL,n.NONE)}render(A,t){const e=this.gl;e.useProgram(this.program),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.videoTexture),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,1),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,A),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,0);const i=md(this.config,this.frameMap,this.textureUnitBySrcId,t);return this.imagePosLoc!==null&&e.uniform1fv(this.imagePosLoc,i),e.clear(e.COLOR_BUFFER_BIT),e.drawArrays(e.TRIANGLE_STRIP,0,4),this.canvas}destroy(){const A=this.gl;for(const e of this.resourceEntries)A.deleteTexture(e.texture);A.deleteTexture(this.videoTexture),A.deleteBuffer(this.vertexBuffer),A.deleteProgram(this.program),A.deleteShader(this.vertexShader),A.deleteShader(this.fragmentShader);const t=A.getExtension("WEBGL_lose_context");t==null||t.loseContext()}}var Sd=Object.defineProperty,Fd=(g,A,t)=>A in g?Sd(g,A,{enumerable:!0,configurable:!0,writable:!0,value:t}):g[A]=t,fA=(g,A,t)=>Fd(g,typeof A!="symbol"?A+"":A,t);const aQ=1397178947,rQ=2,Nd=8;class Rd{constructor(A=1024){fA(this,"buffer"),fA(this,"view"),fA(this,"bytes"),fA(this,"offset",0),fA(this,"encoder",new TextEncoder),this.buffer=new ArrayBuffer(A),this.view=new DataView(this.buffer),this.bytes=new Uint8Array(this.buffer)}ensure(A){const t=this.offset+A;if(t<=this.buffer.byteLength)return;let e=this.buffer.byteLength;for(;e<t;)e*=2;const i=new ArrayBuffer(e);new Uint8Array(i).set(this.bytes.subarray(0,this.offset)),this.buffer=i,this.view=new DataView(this.buffer),this.bytes=new Uint8Array(this.buffer)}u8(A){this.ensure(1),this.view.setUint8(this.offset,A),this.offset+=1}u16(A){this.ensure(2),this.view.setUint16(this.offset,A,!0),this.offset+=2}u32(A){this.ensure(4),this.view.setUint32(this.offset,A,!0),this.offset+=4}f32(A){this.ensure(4),this.view.setFloat32(this.offset,A,!0),this.offset+=4}bytesValue(A){this.u32(A.byteLength),this.ensure(A.byteLength),this.bytes.set(A,this.offset),this.offset+=A.byteLength}string(A){this.bytesValue(this.encoder.encode(A))}finish(){return this.buffer.slice(0,this.offset)}}class xd{constructor(A){fA(this,"view"),fA(this,"bytes"),fA(this,"offset",0),fA(this,"decoder",new TextDecoder),this.view=new DataView(A),this.bytes=new Uint8Array(A)}u8(){const A=this.view.getUint8(this.offset);return this.offset+=1,A}u16(){const A=this.view.getUint16(this.offset,!0);return this.offset+=2,A}u32(){const A=this.view.getUint32(this.offset,!0);return this.offset+=4,A}f32(){const A=this.view.getFloat32(this.offset,!0);return this.offset+=4,A}bytesValue(){const A=this.u32(),t=this.bytes.slice(this.offset,this.offset+A);return this.offset+=A,t}string(){return this.decoder.decode(this.bytesValue())}}function Ud(g){let A=g.atlasImageBytes.byteLength;for(const[t,e]of g.audioBlobs)A+=t.length*2+e.byteLength;for(const[t]of g.atlasRects)A+=t.length*2+16;for(const t of g.sprites){A+=t.imageKey.length*2+t.frames.length*64;for(const e of t.frames)A+=e.clipPath.length*2}return A}function TB(g){const A=new Uint8Array(g.byteLength);return A.set(g),A.buffer}function Md(g){const A=new Rd(Nd+g.atlasImageBytes.byteLength+g.sprites.length*64+g.audioBlobs.size*32+g.atlasRects.size*32);A.u32(aQ),A.u16(rQ),A.u16(0),A.f32(g.params.viewBoxWidth),A.f32(g.params.viewBoxHeight),A.f32(g.params.fps),A.u32(g.params.frames),A.u32(g.atlasWidth),A.u32(g.atlasHeight),A.bytesValue(new Uint8Array(g.atlasImageBytes)),A.u32(g.atlasRects.size);for(const[t,e]of g.atlasRects)A.string(t),A.f32(e.x),A.f32(e.y),A.f32(e.w),A.f32(e.h);A.u32(g.audios.length);for(const t of g.audios)A.string(t.audioKey),A.u32(t.startFrame),A.u32(t.endFrame),A.f32(t.startTime),A.f32(t.totalTime);A.u32(g.audioBlobs.size);for(const[t,e]of g.audioBlobs)A.string(t),A.bytesValue(new Uint8Array(e));A.u32(g.sprites.length);for(const t of g.sprites){A.string(t.imageKey),A.u32(t.frames.length);for(const e of t.frames){let i=0;e.layout&&(i|=1),e.transform&&(i|=2),e.clipPath&&(i|=4),A.u8(i),A.f32(e.alpha),e.layout&&(A.f32(e.layout.x),A.f32(e.layout.y),A.f32(e.layout.width),A.f32(e.layout.height)),e.transform&&(A.f32(e.transform.a),A.f32(e.transform.b),A.f32(e.transform.c),A.f32(e.transform.d),A.f32(e.transform.tx),A.f32(e.transform.ty)),e.clipPath&&A.string(e.clipPath)}}return A.finish()}function bd(g){const A=new xd(g);if(A.u32()!==aQ)throw new Error("Invalid SVGA cache binary magic");if(A.u16()!==rQ)throw new Error("Unsupported SVGA cache binary version");A.u16();const t={viewBoxWidth:A.f32(),viewBoxHeight:A.f32(),fps:A.f32(),frames:A.u32()},e=A.u32(),i=A.u32(),I=TB(A.bytesValue()),s=A.u32(),n=new Map;for(let E=0;E<s;E++){const h=A.string();n.set(h,{x:A.f32(),y:A.f32(),w:A.f32(),h:A.f32()})}const B=A.u32(),C=[];for(let E=0;E<B;E++)C.push({audioKey:A.string(),startFrame:A.u32(),endFrame:A.u32(),startTime:A.f32(),totalTime:A.f32()});const Q=A.u32(),a=new Map;for(let E=0;E<Q;E++){const h=A.string();a.set(h,TB(A.bytesValue()))}const o=A.u32(),r=[];for(let E=0;E<o;E++){const h=A.string(),c=A.u32(),f=[];for(let d=0;d<c;d++){const u=A.u8(),p=A.f32(),D=u&1?{x:A.f32(),y:A.f32(),width:A.f32(),height:A.f32()}:null,y=u&2?{a:A.f32(),b:A.f32(),c:A.f32(),d:A.f32(),tx:A.f32(),ty:A.f32()}:null,S=u&4?A.string():"";f.push({alpha:p,layout:D,transform:y,clipPath:S})}r.push({imageKey:h,frames:f})}return{params:t,sprites:r,audios:C,audioBlobs:a,atlasRects:n,atlasWidth:e,atlasHeight:i,atlasImageBytes:I}}function eB(g){return`svga-asset:${g}`}function iB(g){return`svga-asset-bin:${g}`}async function kd(g){const A=Ja(eB(g),"svga-asset");if(A)return A;const t=await Ha(iB(g));if(!t)return null;try{const e=bd(t);return IC(eB(g),"svga-asset",e,t.byteLength),e}catch(e){return Ka(iB(g)),null}}async function qB(g,A){const t=Md(A);IC(eB(g),"svga-asset",A,Math.max(t.byteLength,Ud(A))),await va(iB(g),t)}function WA(g){return typeof g=="number"&&Number.isFinite(g)&&g>0}function Yd(g,A,t,e){const i=WA(A.width)?A.width:void 0,I=WA(A.height)?A.height:void 0,s=WA(g.width)?g.width:void 0,n=WA(g.height)?g.height:void 0;if(s&&n)return{width:s,height:n};if(s)return i&&I?{width:s,height:s*I/i}:{width:s,height:s};if(n)return i&&I?{width:n*i/I,height:n}:{width:n,height:n};let B=i!=null?i:0,C=I!=null?I:0;if(B>0&&C>0&&WA(t)&&WA(e)&&(B>t||C>e)){const Q=Math.min(t/B,e/C);B*=Q,C*=Q}return{width:B,height:C}}var _d=Object.defineProperty,Ld=(g,A,t)=>A in g?_d(g,A,{enumerable:!0,configurable:!0,writable:!0,value:t}):g[A]=t,X=(g,A,t)=>Ld(g,typeof A!="symbol"?A+"":A,t);const hn=class In{constructor(A){X(this,"sharedSVGAEntities",new Map),X(this,"pendingSharedSVGAEntities",new Map),X(this,"sharedVideoSources",new Map),X(this,"sharedHtmlVideos",new Map),X(this,"sharedVideoTextures",new Map),X(this,"pendingSharedHtmlVideos",new Map),X(this,"canvas"),X(this,"backend",null),X(this,"manager",null),X(this,"options"),X(this,"ready"),X(this,"destroyed",!1),X(this,"resizeObserver",null),X(this,"onWindowLayout",()=>{this.destroyed||this.syncCanvasSize()}),this.options=A,this.canvas=document.createElement("canvas"),this.canvas.style.cssText="position:fixed;inset:0;width:100vw;height:100vh;pointer-events:none;z-index:9999;",A.container.appendChild(this.canvas),this.ready=this.init()}backingStoreDpr(){const A=this.options.resolution;return A!=null&&A>0&&Number.isFinite(A)?A:typeof window!="undefined"&&window.devicePixelRatio>0?window.devicePixelRatio:1}syncCanvasSize(){var A;PQ(this.canvas,this.backingStoreDpr()),(A=this.manager)==null||A.syncSlotLayoutFromOptions()}resourcePipelineConcurrency(){if(this.options.maxConcurrentParse!=null)return Math.max(1,Math.max(4,this.options.maxConcurrentParse));const A=typeof navigator!="undefined"&&typeof navigator.hardwareConcurrency=="number"?navigator.hardwareConcurrency/2:4;return Math.max(1,Math.max(4,A))}async init(){var A;this.syncCanvasSize(),await new Promise(I=>requestAnimationFrame(()=>I())),this.syncCanvasSize(),_a({maxConcurrent:this.resourcePipelineConcurrency(),maxMemoryBytes:In.DEFAULT_RESOURCE_CACHE_MEMORY_BYTES,maxPersistentBytes:In.DEFAULT_RESOURCE_CACHE_PERSISTENT_BYTES});const t=(A=this.options.preferWebGPU)!=null?A:!0,e=this.options.antialias,[i]=await Promise.all([jB(this.canvas,t,e,this.options.forceWebGL1===!0),tC()]);this.backend=i,this.manager=new hC(this.backend),this.resizeObserver=new ResizeObserver(()=>{this.destroyed||this.syncCanvasSize()}),this.resizeObserver.observe(this.canvas),window.addEventListener("resize",this.onWindowLayout),window.addEventListener("orientationchange",this.onWindowLayout)}currentCanvasCssSize(){const A=this.canvas.clientWidth||this.options.container.clientWidth||window.innerWidth||0,t=this.canvas.clientHeight||this.options.container.clientHeight||window.innerHeight||0;return{width:A,height:t}}async resolveGiftIntrinsicSize(A){switch(A.type){case"svga":{const t=await jr(A.source,{useWorker:this.options.svgaParseInWorker!==!1});return{width:t.viewBoxWidth,height:t.viewBoxHeight}}case"vap":{if(!A.config)throw new Error("VAP requires config");const t=await Wn(A.config),e=OA(t.info);return{width:e.w,height:e.h}}case"alphaVideo":return this.probeVideoNaturalSize(A.source)}}async normalizeAddGiftOptions(A){if(A.width!=null&&A.height!=null)return A;const t=await this.resolveGiftIntrinsicSize(A),e=this.currentCanvasCssSize(),i=Yd({width:A.width,height:A.height},t,e.width,e.height);return{...A,width:i.width,height:i.height}}async addGift(A){var t,e,i;if(console.info("[GiftStage] addGift await ready…",A.type),await this.ready,console.info("[GiftStage] addGift ready, loading…",A.type),this.destroyed)throw new Error("GiftStage is destroyed");const I=await this.normalizeAddGiftOptions(A),s=iC(),{sx:n,sy:B}=fs(this.canvas),C=EC(I.x,I.y,I.width,I.height,this.canvas.clientWidth,this.canvas.clientHeight),Q={id:s,type:I.type,state:"loading",options:I,x:C.x*n,y:C.y*B,width:I.width*n,height:I.height*B,scale:1,paused:!1,currentFrame:0,accumulatedTime:0,lastTickTime:0,loopCount:0,videoEntity:null,svgaSlotTextures:void 0,videoElement:null,releaseMediaSource:null,releaseSharedSVGAAsset:null,releaseSharedVideoPlayback:null,releaseSharedVideoTexture:null,webcodecsPlayback:null,wcPlaybackTime:0,videoTextureHandle:null,vapMixState:null,onComplete:I.onComplete,flyTo:I.flyTo,scaleTo:I.scaleTo,flyDuration:I.flyDuration,easing:(t=I.easing)!=null?t:xs,onFlyComplete:I.onFlyComplete},a={id:s,type:I.type,pause:()=>{Q.paused=!0},resume:()=>{Q.paused=!1},destroy:()=>{this.removeGift(s)}};this.manager.addSlot(Q,a);try{switch(I.type){case"svga":await this.loadSVGA(Q);break;case"vap":await this.loadVAP(Q,I);break;case"alphaVideo":await this.loadAlphaVideo(Q,I);break}Q.state="playing",Q.webcodecsPlayback&&console.info("[GiftStage:WC] gift playing",{giftId:Q.id,type:Q.type,layoutBufPx:{x:Q.x,y:Q.y,w:Q.width,h:Q.height}})}catch(o){Q.state="finished",(i=(e=this.options).onError)==null||i.call(e,o instanceof Error?o:new Error(String(o)))}return a}async loadSVGA(A){const t=typeof A.options.source=="string"?A.options.source:null;if(t){const B=await this.acquireSharedSVGAEntity(t);if(A.state==="finished"){B.release();return}A.releaseSharedSVGAAsset=B.release,await this.finishLoadSVGA(A,B.entity,B.audioBlobs);return}const{movie:e,imageBitmaps:i,audioBlobs:I}=await zn(A.options.source,{useWorker:this.options.svgaParseInWorker!==!1});if(A.state==="finished")return;const s=await Xn(i,this.backend,4096,2,{captureEncodedPng:!!t});if(A.state==="finished"){for(const B of i.values())B.close();return}const n={params:e.params,sprites:e.sprites,audios:e.audios,atlasTextureHandle:s.textureHandle,atlasRects:s.rects,audioBuffers:new Map};await this.finishLoadSVGA(A,n,I),t&&s.encodedPngBytesPromise&&s.encodedPngBytesPromise.then(B=>{B&&qB(t,{params:e.params,sprites:e.sprites,audios:e.audios,audioBlobs:I,atlasRects:s.rects,atlasWidth:s.atlasWidth,atlasHeight:s.atlasHeight,atlasImageBytes:B})});for(const B of i.values())B.close()}async acquireSharedSVGAEntity(A){const t=A,e=this.sharedSVGAEntities.get(t);if(e)return e.refs++,{entity:e.entity,audioBlobs:e.audioBlobs,release:()=>this.releaseSharedSVGAEntity(t)};let i=this.pendingSharedSVGAEntities.get(t);i||(i=this.buildSharedSVGAEntity(A),this.pendingSharedSVGAEntities.set(t,i));let I;try{I=await i}catch(n){throw this.pendingSharedSVGAEntities.delete(t),n}let s=this.sharedSVGAEntities.get(t);return s?s.refs++:(s={refs:1,entity:I.entity,audioBlobs:I.audioBlobs},this.sharedSVGAEntities.set(t,s)),this.pendingSharedSVGAEntities.delete(t),{entity:s.entity,audioBlobs:s.audioBlobs,release:()=>this.releaseSharedSVGAEntity(t)}}async buildSharedSVGAEntity(A){const t=await kd(A);if(t){const s=await createImageBitmap(new Blob([t.atlasImageBytes],{type:"image/png"}),{premultiplyAlpha:"none"}),n=this.backend.createTexture(s,{width:t.atlasWidth,height:t.atlasHeight,filter:"linear"});return s.close(),{entity:{params:t.params,sprites:t.sprites,audios:t.audios,atlasTextureHandle:n,atlasRects:t.atlasRects,audioBuffers:new Map},audioBlobs:t.audioBlobs}}const{movie:e,imageBitmaps:i,audioBlobs:I}=await zn(A,{useWorker:this.options.svgaParseInWorker!==!1});try{const s=await Xn(i,this.backend,4096,2,{captureEncodedPng:!0});return s.encodedPngBytesPromise&&s.encodedPngBytesPromise.then(n=>{n&&qB(A,{params:e.params,sprites:e.sprites,audios:e.audios,audioBlobs:I,atlasRects:s.rects,atlasWidth:s.atlasWidth,atlasHeight:s.atlasHeight,atlasImageBytes:n})}),{entity:{params:e.params,sprites:e.sprites,audios:e.audios,atlasTextureHandle:s.textureHandle,atlasRects:s.rects,audioBuffers:new Map},audioBlobs:I}}finally{for(const s of i.values())s.close()}}releaseSharedSVGAEntity(A){var t;const e=this.sharedSVGAEntities.get(A);e&&(e.refs=Math.max(0,e.refs-1),!(e.refs>0)&&(e.entity.atlasTextureHandle&&((t=this.backend)==null||t.deleteTexture(e.entity.atlasTextureHandle)),this.sharedSVGAEntities.delete(A)))}async finishLoadSVGA(A,t,e){let i=0;for(const[I,s]of e)await this.manager.audioManager.decodeAudio(I,s),i++,i<e.size&&await new Promise(n=>{if(typeof requestAnimationFrame=="function"){requestAnimationFrame(()=>n());return}setTimeout(n,0)});A.videoEntity=t,A.options.svgaSlots&&(A.svgaSlotTextures=await Pa(this.backend,A.videoEntity,A.options.svgaSlots))}shouldTryWebCodecs(){return this.options.preferWebCodecs===!0&&typeof VideoDecoder!="undefined"}logPlaybackBackend(A,t,e){const i=t==="webcodecs"?"WebCodecs (mp4box decode)":"HTMLVideoElement",I=e?` — ${e}`:"";console.info(`[GiftStage] ${A.type} [${A.id}]: ${i}${I}`)}async tryWebCodecsPlayback(A){if(!this.shouldTryWebCodecs())return null;try{const t=typeof A=="string"?await Rs(A):A;return await YA.create(t,void 0,{useWorker:this.options.webCodecsDecodeInWorker!==!1,maxDecodedFrames:this.options.webCodecsMaxDecodedFrames,decodeAheadFrames:this.options.webCodecsDecodeAheadFrames})}catch(t){const e=t instanceof Error?t.message:String(t);return console.warn(`[GiftStage] WebCodecs path failed, falling back to <video>: ${e}`),null}}async loadVAP(A,t){var e;if(!t.config)throw new Error("VAP requires config");const i=await Wn(t.config);A.vapConfig=i;const I=await er(i,t.vapSlots);if(I.size>0){const Q=OA(i.info),a=ir(i);let o=null,r=null;try{o=new Gd(i,a,I,Q.w,Q.h)}catch(E){console.warn("[GiftStage] VAP mixed rendering fell back to CPU compositor",E),r=gr(Q.w,Q.h)}A.vapMixState={texture:this.backend.createEmptyTexture(Q.w,Q.h,{filter:"linear"}),width:Q.w,height:Q.h,composer:o,frameMap:a,resources:I,lastFrameIndex:-1,lastSourceRef:null,...r!=null?r:{}},A.videoTextureHandle=A.vapMixState.texture}console.info("[GiftStage:WC] loadVAP: try WebCodecs / video…");const n=await this.tryWebCodecsPlayback(t.source);if(n){A.webcodecsPlayback=n,A.wcPlaybackTime=0;const Q=n.getFrameForTime(0);if(!Q)throw n.destroy(),A.webcodecsPlayback=null,new Error("WebCodecs: missing first frame");if(!A.vapMixState){const o=Q.displayWidth||Q.codedWidth,r=Q.displayHeight||Q.codedHeight,{w:E,h}=HB(A,o,r,"vap",i),c=this.manager.tryAllocateWebCodecsAtlas(A.id,E,h,this.options.webCodecsVideoAtlas);if(c)A.videoTextureHandle=c.handle,A.wcAtlasRect=c.rect,this.backend.updateTextureRegion(c.handle,Q,c.rect.x,c.rect.y,E,h);else{const f=this.backend.createTexture(Q,{width:o,height:r,filter:"linear"});A.videoTextureHandle=f}}A.videoElement=null;const a=A.videoTextureHandle;console.info("[GiftStage:WC] VAP texture",{giftId:A.id,atlas:!!A.wcAtlasRect&&!A.vapMixState,mixed:!!A.vapMixState,tex:`${a.width}x${a.height}`,frame0:`${Q.displayWidth}x${Q.displayHeight}`,atlasCell:A.wcAtlasRect?`${A.wcAtlasRect.w}x${A.wcAtlasRect.h}`:void 0}),this.logPlaybackBackend(A,"webcodecs");return}const B=await this.tryAcquireSharedHtmlVideo(A,t);if(B)A.videoElement=B.video,A.releaseSharedVideoPlayback=B.release;else{const Q=await this.acquireVideoPlaybackSource(t.source);A.releaseMediaSource=(e=Q.release)!=null?e:null;const a=this.createVideo(Q.src,t.loop===0);A.videoElement=a}const C=A.videoElement;if(B){await B.ready;const Q=this.acquireSharedVideoTexture(B.cacheKey,C);A.videoTextureHandle=Q.texture,A.releaseSharedVideoTexture=Q.release}else await this.waitVideoReady(C),A.vapMixState||(A.videoTextureHandle=this.backend.createTexture(C,{width:C.videoWidth,height:C.videoHeight,filter:"linear"}));A.releaseSharedVideoPlayback||this.bindVideoLoopOnEnded(A,C),this.logPlaybackBackend(A,"video",this.shouldTryWebCodecs()?"fallback after WebCodecs unavailable or failed":"preferWebCodecs off or no VideoDecoder")}async loadAlphaVideo(A,t){var e;console.info("[GiftStage:WC] loadAlphaVideo: try WebCodecs / video…");const i=await this.tryWebCodecsPlayback(t.source);if(i){A.webcodecsPlayback=i,A.wcPlaybackTime=0;const n=i.getFrameForTime(0);if(!n)throw i.destroy(),A.webcodecsPlayback=null,new Error("WebCodecs: missing first frame");const B=n.displayWidth||n.codedWidth,C=n.displayHeight||n.codedHeight,{w:Q,h:a}=HB(A,B,C,"alphaVideo",void 0),o=this.manager.tryAllocateWebCodecsAtlas(A.id,Q,a,this.options.webCodecsVideoAtlas);if(o)A.videoTextureHandle=o.handle,A.wcAtlasRect=o.rect,this.backend.updateTextureRegion(o.handle,n,o.rect.x,o.rect.y,Q,a);else{const E=this.backend.createTexture(n,{width:B,height:C,filter:"linear"});A.videoTextureHandle=E}A.videoElement=null;const r=A.videoTextureHandle;console.info("[GiftStage:WC] alphaVideo texture",{giftId:A.id,atlas:!!A.wcAtlasRect,tex:`${r.width}x${r.height}`,frame0:`${n.displayWidth}x${n.displayHeight}`,atlasCell:A.wcAtlasRect?`${A.wcAtlasRect.w}x${A.wcAtlasRect.h}`:void 0}),this.logPlaybackBackend(A,"webcodecs");return}const I=await this.tryAcquireSharedHtmlVideo(A,t);if(I)A.videoElement=I.video,A.releaseSharedVideoPlayback=I.release;else{const n=await this.acquireVideoPlaybackSource(t.source);A.releaseMediaSource=(e=n.release)!=null?e:null;const B=this.createVideo(n.src,t.loop===0);A.videoElement=B}const s=A.videoElement;if(I){await I.ready;const n=this.acquireSharedVideoTexture(I.cacheKey,s);A.videoTextureHandle=n.texture,A.releaseSharedVideoTexture=n.release}else await this.waitVideoReady(s),A.videoTextureHandle=this.backend.createTexture(s,{width:s.videoWidth,height:s.videoHeight,filter:"linear"});A.releaseSharedVideoPlayback||this.bindVideoLoopOnEnded(A,s),this.logPlaybackBackend(A,"video",this.shouldTryWebCodecs()?"fallback after WebCodecs unavailable or failed":"preferWebCodecs off or no VideoDecoder")}bindVideoLoopOnEnded(A,t){t.addEventListener("ended",()=>{var e,i,I,s,n;if(A.state!=="playing")return;const B=(e=A.options.loop)!=null?e:1;if(B===0){t.currentTime=0,t.play();return}if(A.loopCount++,A.loopCount>=B){const C={id:A.id,type:A.type,pause:()=>{},resume:()=>{},destroy:()=>this.removeGift(A.id)};if((i=A.onComplete)==null||i.call(A,C),A.flyTo){A.state="fly";const Q=fs(this.canvas);this.manager.postAnimator.startFly(A,A.flyTo.x*Q.sx,A.flyTo.y*Q.sy,(I=A.scaleTo)!=null?I:.3,(s=A.flyDuration)!=null?s:600,(n=A.easing)!=null?n:xs,()=>{var a;A.state="finished",(a=A.onFlyComplete)==null||a.call(A,C)})}else A.state="finished";return}t.currentTime=0,t.play()})}createVideo(A,t){const e=document.createElement("video");return e.crossOrigin="anonymous",e.autoplay=!0,e.preload="auto",e.muted=!0,e.playsInline=!0,e.setAttribute("playsinline",""),e.setAttribute("webkit-playsinline","true"),e.loop=t,e.style.cssText="display:none;",e.src=A,document.body.appendChild(e),e.load(),e}waitVideoMetadata(A){return new Promise((t,e)=>{const i=()=>{A.removeEventListener("loadedmetadata",I),A.removeEventListener("error",s)},I=()=>{i(),t()},s=()=>{i(),e(new Error("Video metadata load failed"))};A.addEventListener("loadedmetadata",I),A.addEventListener("error",s),A.readyState>=HTMLMediaElement.HAVE_METADATA&&(i(),t())})}async probeVideoNaturalSize(A){var t;const e=await this.acquireVideoPlaybackSource(A),i=document.createElement("video");i.crossOrigin="anonymous",i.preload="metadata",i.muted=!0,i.playsInline=!0,i.setAttribute("playsinline",""),i.setAttribute("webkit-playsinline","true"),i.style.cssText="display:none;",i.src=e.src,document.body.appendChild(i),i.load();try{return await this.waitVideoMetadata(i),{width:i.videoWidth,height:i.videoHeight}}finally{try{i.pause(),i.removeAttribute("src"),i.load(),i.remove()}catch(I){}(t=e.release)==null||t.call(e)}}async acquireVideoPlaybackSource(A){if(typeof A!="string"){const i=URL.createObjectURL(new Blob([A]));return{src:i,release:()=>URL.revokeObjectURL(i)}}const t=this.normalizeSharedVideoSourceKey(A);if(!t)return{src:A};let e=this.sharedVideoSources.get(t);e||(e={refs:0,objectUrl:null,promise:this.fetchSharedVideoSource(t)},this.sharedVideoSources.set(t,e)),e.refs++;try{return{src:await e.promise,release:()=>this.releaseSharedVideoSource(t)}}catch(i){return this.releaseSharedVideoSource(t),console.warn("[GiftStage] shared video prefetch failed, using original url",i),{src:A}}}normalizeSharedVideoSourceKey(A){try{const t=new URL(A,window.location.href);return t.protocol==="blob:"||t.protocol==="data:"?null:t.href}catch(t){return null}}async fetchSharedVideoSource(A){const t=new Blob([await Rs(A)]),e=this.sharedVideoSources.get(A),i=URL.createObjectURL(t);return e&&(e.objectUrl=i,e.refs===0&&(URL.revokeObjectURL(i),this.sharedVideoSources.delete(A))),i}releaseSharedVideoSource(A){const t=this.sharedVideoSources.get(A);t&&(t.refs=Math.max(0,t.refs-1),t.refs===0&&t.objectUrl&&(URL.revokeObjectURL(t.objectUrl),this.sharedVideoSources.delete(A)))}async tryAcquireSharedHtmlVideo(A,t){var e,i;if(this.options.shareIdenticalVideoPlayback===!1||t.loop!==0||typeof t.source!="string"||A.type==="vap"&&A.vapMixState)return null;const I=this.normalizeSharedVideoSourceKey(t.source);if(!I)return null;const s=(e=this.options.sharedVideoPlaybackWindowMs)!=null?e:In.DEFAULT_SHARED_VIDEO_PLAYBACK_WINDOW_MS,n=Math.max(0,s)/1e3,B=this.sharedHtmlVideos.get(I);if(B)return B.video.currentTime>n?null:(B.refs++,{cacheKey:I,video:B.video,ready:B.ready,release:()=>this.releaseSharedHtmlVideo(I)});let C=this.pendingSharedHtmlVideos.get(I);C||(C=(async()=>{var o;const r=await this.acquireVideoPlaybackSource(t.source),E=this.createVideo(r.src,!0),h=this.waitVideoReady(E);return{video:E,ready:h,releaseSource:(o=r.release)!=null?o:null}})(),this.pendingSharedHtmlVideos.set(I,C));let Q;try{Q=await C}catch(o){throw this.pendingSharedHtmlVideos.delete(I),o}let a=this.sharedHtmlVideos.get(I);return a?a.refs++:(a={refs:1,video:Q.video,ready:Q.ready,releaseSource:(i=Q.releaseSource)!=null?i:null},this.sharedHtmlVideos.set(I,a)),this.pendingSharedHtmlVideos.delete(I),{cacheKey:I,video:a.video,ready:a.ready,release:()=>this.releaseSharedHtmlVideo(I)}}acquireSharedVideoTexture(A,t){const e=this.sharedVideoTextures.get(A);if(e)return e.refs++,{texture:e.texture,release:()=>this.releaseSharedVideoTexture(A)};const i=this.backend.createTexture(t,{width:t.videoWidth,height:t.videoHeight,filter:"linear"});return this.sharedVideoTextures.set(A,{refs:1,texture:i}),{texture:i,release:()=>this.releaseSharedVideoTexture(A)}}releaseSharedVideoTexture(A){var t;const e=this.sharedVideoTextures.get(A);e&&(e.refs=Math.max(0,e.refs-1),!(e.refs>0)&&((t=this.backend)==null||t.deleteTexture(e.texture),this.sharedVideoTextures.delete(A)))}releaseSharedHtmlVideo(A){var t;const e=this.sharedHtmlVideos.get(A);if(e&&(e.refs=Math.max(0,e.refs-1),!(e.refs>0))){try{e.video.pause(),e.video.removeAttribute("src"),e.video.load(),e.video.remove()}catch(i){}(t=e.releaseSource)==null||t.call(e),this.sharedHtmlVideos.delete(A)}}waitForFirstVideoFrame(A){return new Promise(t=>{typeof A.requestVideoFrameCallback=="function"?A.requestVideoFrameCallback(()=>t()):requestAnimationFrame(()=>t())})}waitVideoReady(A){return new Promise((t,e)=>{const i=()=>{A.removeEventListener("canplay",s),A.removeEventListener("error",n)},I=async()=>{try{await A.play(),await this.waitForFirstVideoFrame(A),t()}catch(B){e(B)}},s=()=>{i(),I()},n=()=>{i(),e(new Error("Video load failed"))};A.addEventListener("canplay",s),A.addEventListener("error",n),A.readyState>=HTMLMediaElement.HAVE_FUTURE_DATA&&(i(),I())})}removeGift(A){var t;(t=this.manager)==null||t.removeSlot(A)}removeAll(){if(this.manager)for(const A of this.manager.getSlotIds())this.manager.removeSlot(A)}pause(){var A;(A=this.manager)==null||A.pause()}resume(){var A;(A=this.manager)==null||A.resume()}get activeCount(){var A,t;return(t=(A=this.manager)==null?void 0:A.activeCount)!=null?t:0}get backendType(){var A,t;return(t=(A=this.backend)==null?void 0:A.type)!=null?t:"webgl2"}destroy(){var A,t;this.destroyed=!0,(A=this.resizeObserver)==null||A.disconnect(),this.resizeObserver=null,window.removeEventListener("resize",this.onWindowLayout),window.removeEventListener("orientationchange",this.onWindowLayout),(t=this.manager)==null||t.destroy();for(const[e]of this.sharedHtmlVideos)this.releaseSharedHtmlVideo(e);for(const[e]of this.sharedSVGAEntities)this.releaseSharedSVGAEntity(e);for(const[e]of this.sharedVideoTextures)this.releaseSharedVideoTexture(e);this.pendingSharedSVGAEntities.clear(),this.pendingSharedHtmlVideos.clear();for(const[e,i]of this.sharedVideoSources)i.objectUrl&&URL.revokeObjectURL(i.objectUrl),this.sharedVideoSources.delete(e);this.canvas.remove(),this.backend=null,this.manager=null}};X(hn,"DEFAULT_SHARED_VIDEO_PLAYBACK_WINDOW_MS",100);X(hn,"DEFAULT_RESOURCE_CACHE_MEMORY_BYTES",128*1024*1024);X(hn,"DEFAULT_RESOURCE_CACHE_PERSISTENT_BYTES",2048*1024*1024);let Jd=hn;exports.AlphaVideoRenderer=aC;exports.AudioManager=oC;exports.BufferPool=eC;exports.GiftStage=Jd;exports.PostAnimator=rC;exports.RenderManager=hC;exports.SVGABatchRenderer=gC;exports.VAPRenderer=QC;exports.WebCodecsMp4Playback=YA;exports.WebGL1Backend=Kn;exports.WebGL2Backend=VB;exports.WebGPUBackend=ZB;exports.buildAtlas=Xn;exports.buildBatchVerticesJS=Ts;exports.canSharedArrayBuffer=XQ;exports.canWebGL1=zQ;exports.canWebGL2=jQ;exports.canWebGPU=WQ;exports.clamp=qn;exports.createBackend=jB;exports.decodeSVGAProto=lC;exports.easeInOutCubic=dr;exports.easeInOutQuad=lr;exports.easeInQuad=hr;exports.easeOutBack=fr;exports.easeOutCubic=xs;exports.easeOutQuad=cr;exports.generateId=iC;exports.inflateJS=cC;exports.initWasm=tC;exports.isWasmReady=XA;exports.lerp=Zs;exports.linear=Er;exports.ortho=_A;exports.parseSVGA=zn;exports.parseVAPConfig=Wn;
8322
+ `;function md(g,A,t,e){const i=new Float32Array(t.size*an),I=A.get(e);if(!I||I.length===0)return i;const[s,n]=g.info.rgbFrame;let B=0;for(const C of I){const Q=t.get(String(C.srcId));if(!Q)continue;if(B+an>i.length)break;const[a,o,r,E]=C.frame,[h,c,f,d]=C.mFrame,u=rn(a+s,o+n,r,E,g.info.videoW,g.info.videoH),p=rn(h,c,f,d,g.info.videoW,g.info.videoH);i[B++]=Q,i[B++]=u[0],i[B++]=u[1],i[B++]=u[2],i[B++]=u[3],i[B++]=p[0],i[B++]=p[1],i[B++]=p[2],i[B++]=p[3]}return i}class Gd{constructor(A,t,e,i,I){this.config=A,this.frameMap=t,oA(this,"canvas"),oA(this,"gl"),oA(this,"program"),oA(this,"vertexShader"),oA(this,"fragmentShader"),oA(this,"vertexBuffer"),oA(this,"videoTexture"),oA(this,"imagePosLoc"),oA(this,"resourceEntries"),oA(this,"textureUnitBySrcId",new Map);var s;if(e.size===0)throw new Error("VAP mix composer requires at least one slot resource");this.canvas=ud(i,I);const n=this.canvas.getContext("webgl2",{alpha:!0,antialias:!1,depth:!1,premultipliedAlpha:!1,preserveDrawingBuffer:!1,stencil:!1})||this.canvas.getContext("webgl",{alpha:!0,antialias:!1,depth:!1,premultipliedAlpha:!1,preserveDrawingBuffer:!1,stencil:!1})||this.canvas.getContext("experimental-webgl");if(!n)throw new Error("VAP mixed rendering requires WebGL support");this.gl=n;const B=Math.max(1,n.getParameter(n.MAX_TEXTURE_IMAGE_UNITS)),C=Math.max(0,B-1),Q=[];let a=1;for(const u of(s=A.src)!=null?s:[]){const p=e.get(String(u.srcId));if(!p)continue;if(a>C){console.warn("[GiftStage] VAP mixed resources exceed texture unit limit, skipping",{srcId:u.srcId,srcTag:u.srcTag,maxUnits:B});continue}const D=KB(n,a,p.source,!0),y={srcId:String(u.srcId),unit:a,texture:D};Q.push(y),this.textureUnitBySrcId.set(y.srcId,y.unit),a++}if(Q.length===0)throw new Error("VAP mixed rendering could not bind any slot resources");this.resourceEntries=Q;const o=wd(n,yd,pd(this.resourceEntries.length));this.program=o.program,this.vertexShader=o.vertexShader,this.fragmentShader=o.fragmentShader,this.imagePosLoc=n.getUniformLocation(this.program,"image_pos"),this.videoTexture=KB(n,0);const r=n.getUniformLocation(this.program,"u_image_video");r!==null&&n.uniform1i(r,0);for(const u of this.resourceEntries){const p=n.getUniformLocation(this.program,`u_image${u.unit}`);p!==null&&n.uniform1i(p,u.unit)}const E=n.createBuffer();if(!E)throw new Error("Failed to create VAP mix vertex buffer");this.vertexBuffer=E,n.bindBuffer(n.ARRAY_BUFFER,this.vertexBuffer),n.bufferData(n.ARRAY_BUFFER,Dd(A.info),n.STATIC_DRAW);const h=6*Float32Array.BYTES_PER_ELEMENT,c=n.getAttribLocation(this.program,"a_position"),f=n.getAttribLocation(this.program,"a_texCoord"),d=n.getAttribLocation(this.program,"a_alpha_texCoord");n.enableVertexAttribArray(c),n.vertexAttribPointer(c,2,n.FLOAT,!1,h,0),n.enableVertexAttribArray(f),n.vertexAttribPointer(f,2,n.FLOAT,!1,h,2*Float32Array.BYTES_PER_ELEMENT),n.enableVertexAttribArray(d),n.vertexAttribPointer(d,2,n.FLOAT,!1,h,4*Float32Array.BYTES_PER_ELEMENT),n.viewport(0,0,this.canvas.width,this.canvas.height),n.disable(n.BLEND),n.disable(n.DEPTH_TEST),n.clearColor(0,0,0,0),n.pixelStorei(n.UNPACK_PREMULTIPLY_ALPHA_WEBGL,0),n.pixelStorei(n.UNPACK_COLORSPACE_CONVERSION_WEBGL,n.NONE)}render(A,t){const e=this.gl;e.useProgram(this.program),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.videoTexture),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,1),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,A),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,0);const i=md(this.config,this.frameMap,this.textureUnitBySrcId,t);return this.imagePosLoc!==null&&e.uniform1fv(this.imagePosLoc,i),e.clear(e.COLOR_BUFFER_BIT),e.drawArrays(e.TRIANGLE_STRIP,0,4),this.canvas}destroy(){const A=this.gl;for(const e of this.resourceEntries)A.deleteTexture(e.texture);A.deleteTexture(this.videoTexture),A.deleteBuffer(this.vertexBuffer),A.deleteProgram(this.program),A.deleteShader(this.vertexShader),A.deleteShader(this.fragmentShader);const t=A.getExtension("WEBGL_lose_context");t==null||t.loseContext()}}var Sd=Object.defineProperty,Fd=(g,A,t)=>A in g?Sd(g,A,{enumerable:!0,configurable:!0,writable:!0,value:t}):g[A]=t,fA=(g,A,t)=>Fd(g,typeof A!="symbol"?A+"":A,t);const aQ=1397178947,rQ=2,Nd=8;class Rd{constructor(A=1024){fA(this,"buffer"),fA(this,"view"),fA(this,"bytes"),fA(this,"offset",0),fA(this,"encoder",new TextEncoder),this.buffer=new ArrayBuffer(A),this.view=new DataView(this.buffer),this.bytes=new Uint8Array(this.buffer)}ensure(A){const t=this.offset+A;if(t<=this.buffer.byteLength)return;let e=this.buffer.byteLength;for(;e<t;)e*=2;const i=new ArrayBuffer(e);new Uint8Array(i).set(this.bytes.subarray(0,this.offset)),this.buffer=i,this.view=new DataView(this.buffer),this.bytes=new Uint8Array(this.buffer)}u8(A){this.ensure(1),this.view.setUint8(this.offset,A),this.offset+=1}u16(A){this.ensure(2),this.view.setUint16(this.offset,A,!0),this.offset+=2}u32(A){this.ensure(4),this.view.setUint32(this.offset,A,!0),this.offset+=4}f32(A){this.ensure(4),this.view.setFloat32(this.offset,A,!0),this.offset+=4}bytesValue(A){this.u32(A.byteLength),this.ensure(A.byteLength),this.bytes.set(A,this.offset),this.offset+=A.byteLength}string(A){this.bytesValue(this.encoder.encode(A))}finish(){return this.buffer.slice(0,this.offset)}}class xd{constructor(A){fA(this,"view"),fA(this,"bytes"),fA(this,"offset",0),fA(this,"decoder",new TextDecoder),this.view=new DataView(A),this.bytes=new Uint8Array(A)}u8(){const A=this.view.getUint8(this.offset);return this.offset+=1,A}u16(){const A=this.view.getUint16(this.offset,!0);return this.offset+=2,A}u32(){const A=this.view.getUint32(this.offset,!0);return this.offset+=4,A}f32(){const A=this.view.getFloat32(this.offset,!0);return this.offset+=4,A}bytesValue(){const A=this.u32(),t=this.bytes.slice(this.offset,this.offset+A);return this.offset+=A,t}string(){return this.decoder.decode(this.bytesValue())}}function Ud(g){let A=g.atlasImageBytes.byteLength;for(const[t,e]of g.audioBlobs)A+=t.length*2+e.byteLength;for(const[t]of g.atlasRects)A+=t.length*2+16;for(const t of g.sprites){A+=t.imageKey.length*2+t.frames.length*64;for(const e of t.frames)A+=e.clipPath.length*2}return A}function TB(g){const A=new Uint8Array(g.byteLength);return A.set(g),A.buffer}function Md(g){const A=new Rd(Nd+g.atlasImageBytes.byteLength+g.sprites.length*64+g.audioBlobs.size*32+g.atlasRects.size*32);A.u32(aQ),A.u16(rQ),A.u16(0),A.f32(g.params.viewBoxWidth),A.f32(g.params.viewBoxHeight),A.f32(g.params.fps),A.u32(g.params.frames),A.u32(g.atlasWidth),A.u32(g.atlasHeight),A.bytesValue(new Uint8Array(g.atlasImageBytes)),A.u32(g.atlasRects.size);for(const[t,e]of g.atlasRects)A.string(t),A.f32(e.x),A.f32(e.y),A.f32(e.w),A.f32(e.h);A.u32(g.audios.length);for(const t of g.audios)A.string(t.audioKey),A.u32(t.startFrame),A.u32(t.endFrame),A.f32(t.startTime),A.f32(t.totalTime);A.u32(g.audioBlobs.size);for(const[t,e]of g.audioBlobs)A.string(t),A.bytesValue(new Uint8Array(e));A.u32(g.sprites.length);for(const t of g.sprites){A.string(t.imageKey),A.u32(t.frames.length);for(const e of t.frames){let i=0;e.layout&&(i|=1),e.transform&&(i|=2),e.clipPath&&(i|=4),A.u8(i),A.f32(e.alpha),e.layout&&(A.f32(e.layout.x),A.f32(e.layout.y),A.f32(e.layout.width),A.f32(e.layout.height)),e.transform&&(A.f32(e.transform.a),A.f32(e.transform.b),A.f32(e.transform.c),A.f32(e.transform.d),A.f32(e.transform.tx),A.f32(e.transform.ty)),e.clipPath&&A.string(e.clipPath)}}return A.finish()}function bd(g){const A=new xd(g);if(A.u32()!==aQ)throw new Error("Invalid SVGA cache binary magic");if(A.u16()!==rQ)throw new Error("Unsupported SVGA cache binary version");A.u16();const t={viewBoxWidth:A.f32(),viewBoxHeight:A.f32(),fps:A.f32(),frames:A.u32()},e=A.u32(),i=A.u32(),I=TB(A.bytesValue()),s=A.u32(),n=new Map;for(let E=0;E<s;E++){const h=A.string();n.set(h,{x:A.f32(),y:A.f32(),w:A.f32(),h:A.f32()})}const B=A.u32(),C=[];for(let E=0;E<B;E++)C.push({audioKey:A.string(),startFrame:A.u32(),endFrame:A.u32(),startTime:A.f32(),totalTime:A.f32()});const Q=A.u32(),a=new Map;for(let E=0;E<Q;E++){const h=A.string();a.set(h,TB(A.bytesValue()))}const o=A.u32(),r=[];for(let E=0;E<o;E++){const h=A.string(),c=A.u32(),f=[];for(let d=0;d<c;d++){const u=A.u8(),p=A.f32(),D=u&1?{x:A.f32(),y:A.f32(),width:A.f32(),height:A.f32()}:null,y=u&2?{a:A.f32(),b:A.f32(),c:A.f32(),d:A.f32(),tx:A.f32(),ty:A.f32()}:null,S=u&4?A.string():"";f.push({alpha:p,layout:D,transform:y,clipPath:S})}r.push({imageKey:h,frames:f})}return{params:t,sprites:r,audios:C,audioBlobs:a,atlasRects:n,atlasWidth:e,atlasHeight:i,atlasImageBytes:I}}function eB(g){return`svga-asset:${g}`}function iB(g){return`svga-asset-bin:${g}`}async function kd(g){const A=Ja(eB(g),"svga-asset");if(A)return A;const t=await Ha(iB(g));if(!t)return null;try{const e=bd(t);return IC(eB(g),"svga-asset",e,t.byteLength),e}catch(e){return Ka(iB(g)),null}}async function qB(g,A){const t=Md(A);IC(eB(g),"svga-asset",A,Math.max(t.byteLength,Ud(A))),await va(iB(g),t)}function WA(g){return typeof g=="number"&&Number.isFinite(g)&&g>0}function Yd(g,A,t,e){const i=WA(A.width)?A.width:void 0,I=WA(A.height)?A.height:void 0,s=WA(g.width)?g.width:void 0,n=WA(g.height)?g.height:void 0,B=g.useOriginalSize===!0;if(s&&n)return{width:s,height:n};if(s)return i&&I?{width:s,height:s*I/i}:{width:s,height:s};if(n)return i&&I?{width:n*i/I,height:n}:{width:n,height:n};let C=i!=null?i:0,Q=I!=null?I:0;if(C>0&&Q>0&&WA(t)&&WA(e)&&(!B||C>t||Q>e)){const a=Math.min(t/C,e/Q);C*=a,Q*=a}return{width:C,height:Q}}var _d=Object.defineProperty,Ld=(g,A,t)=>A in g?_d(g,A,{enumerable:!0,configurable:!0,writable:!0,value:t}):g[A]=t,X=(g,A,t)=>Ld(g,typeof A!="symbol"?A+"":A,t);const hn=class In{constructor(A){X(this,"sharedSVGAEntities",new Map),X(this,"pendingSharedSVGAEntities",new Map),X(this,"sharedVideoSources",new Map),X(this,"sharedHtmlVideos",new Map),X(this,"sharedVideoTextures",new Map),X(this,"pendingSharedHtmlVideos",new Map),X(this,"canvas"),X(this,"backend",null),X(this,"manager",null),X(this,"options"),X(this,"ready"),X(this,"destroyed",!1),X(this,"resizeObserver",null),X(this,"onWindowLayout",()=>{this.destroyed||this.syncCanvasSize()}),this.options=A,this.canvas=document.createElement("canvas"),this.canvas.style.cssText="position:fixed;inset:0;width:100vw;height:100vh;pointer-events:none;z-index:9999;",A.container.appendChild(this.canvas),this.ready=this.init()}backingStoreDpr(){const A=this.options.resolution;return A!=null&&A>0&&Number.isFinite(A)?A:typeof window!="undefined"&&window.devicePixelRatio>0?window.devicePixelRatio:1}syncCanvasSize(){var A;PQ(this.canvas,this.backingStoreDpr()),(A=this.manager)==null||A.syncSlotLayoutFromOptions()}resourcePipelineConcurrency(){if(this.options.maxConcurrentParse!=null)return Math.max(1,Math.max(4,this.options.maxConcurrentParse));const A=typeof navigator!="undefined"&&typeof navigator.hardwareConcurrency=="number"?navigator.hardwareConcurrency/2:4;return Math.max(1,Math.max(4,A))}async init(){var A;this.syncCanvasSize(),await new Promise(I=>requestAnimationFrame(()=>I())),this.syncCanvasSize(),_a({maxConcurrent:this.resourcePipelineConcurrency(),maxMemoryBytes:In.DEFAULT_RESOURCE_CACHE_MEMORY_BYTES,maxPersistentBytes:In.DEFAULT_RESOURCE_CACHE_PERSISTENT_BYTES});const t=(A=this.options.preferWebGPU)!=null?A:!0,e=this.options.antialias,[i]=await Promise.all([jB(this.canvas,t,e,this.options.forceWebGL1===!0),tC()]);this.backend=i,this.manager=new hC(this.backend),this.resizeObserver=new ResizeObserver(()=>{this.destroyed||this.syncCanvasSize()}),this.resizeObserver.observe(this.canvas),window.addEventListener("resize",this.onWindowLayout),window.addEventListener("orientationchange",this.onWindowLayout)}currentCanvasCssSize(){const A=this.canvas.clientWidth||this.options.container.clientWidth||window.innerWidth||0,t=this.canvas.clientHeight||this.options.container.clientHeight||window.innerHeight||0;return{width:A,height:t}}async resolveGiftIntrinsicSize(A){switch(A.type){case"svga":{const t=await jr(A.source,{useWorker:this.options.svgaParseInWorker!==!1});return{width:t.viewBoxWidth,height:t.viewBoxHeight}}case"vap":{if(!A.config)throw new Error("VAP requires config");const t=await Wn(A.config),e=OA(t.info);return{width:e.w,height:e.h}}case"alphaVideo":return this.probeVideoNaturalSize(A.source)}}async normalizeAddGiftOptions(A){if(A.width!=null&&A.height!=null)return A;const t=await this.resolveGiftIntrinsicSize(A),e=this.currentCanvasCssSize(),i=Yd({width:A.width,height:A.height,useOriginalSize:A.useOriginalSize},t,e.width,e.height);return{...A,width:i.width,height:i.height}}async addGift(A){var t,e,i;if(console.info("[GiftStage] addGift await ready…",A.type),await this.ready,console.info("[GiftStage] addGift ready, loading…",A.type),this.destroyed)throw new Error("GiftStage is destroyed");const I=await this.normalizeAddGiftOptions(A),s=iC(),{sx:n,sy:B}=fs(this.canvas),C=EC(I.x,I.y,I.width,I.height,this.canvas.clientWidth,this.canvas.clientHeight),Q={id:s,type:I.type,state:"loading",options:I,x:C.x*n,y:C.y*B,width:I.width*n,height:I.height*B,scale:1,paused:!1,currentFrame:0,accumulatedTime:0,lastTickTime:0,loopCount:0,videoEntity:null,svgaSlotTextures:void 0,videoElement:null,releaseMediaSource:null,releaseSharedSVGAAsset:null,releaseSharedVideoPlayback:null,releaseSharedVideoTexture:null,webcodecsPlayback:null,wcPlaybackTime:0,videoTextureHandle:null,vapMixState:null,onComplete:I.onComplete,flyTo:I.flyTo,scaleTo:I.scaleTo,flyDuration:I.flyDuration,easing:(t=I.easing)!=null?t:xs,onFlyComplete:I.onFlyComplete},a={id:s,type:I.type,pause:()=>{Q.paused=!0},resume:()=>{Q.paused=!1},destroy:()=>{this.removeGift(s)}};this.manager.addSlot(Q,a);try{switch(I.type){case"svga":await this.loadSVGA(Q);break;case"vap":await this.loadVAP(Q,I);break;case"alphaVideo":await this.loadAlphaVideo(Q,I);break}Q.state="playing",Q.webcodecsPlayback&&console.info("[GiftStage:WC] gift playing",{giftId:Q.id,type:Q.type,layoutBufPx:{x:Q.x,y:Q.y,w:Q.width,h:Q.height}})}catch(o){Q.state="finished",(i=(e=this.options).onError)==null||i.call(e,o instanceof Error?o:new Error(String(o)))}return a}async loadSVGA(A){const t=typeof A.options.source=="string"?A.options.source:null;if(t){const B=await this.acquireSharedSVGAEntity(t);if(A.state==="finished"){B.release();return}A.releaseSharedSVGAAsset=B.release,await this.finishLoadSVGA(A,B.entity,B.audioBlobs);return}const{movie:e,imageBitmaps:i,audioBlobs:I}=await zn(A.options.source,{useWorker:this.options.svgaParseInWorker!==!1});if(A.state==="finished")return;const s=await Xn(i,this.backend,4096,2,{captureEncodedPng:!!t});if(A.state==="finished"){for(const B of i.values())B.close();return}const n={params:e.params,sprites:e.sprites,audios:e.audios,atlasTextureHandle:s.textureHandle,atlasRects:s.rects,audioBuffers:new Map};await this.finishLoadSVGA(A,n,I),t&&s.encodedPngBytesPromise&&s.encodedPngBytesPromise.then(B=>{B&&qB(t,{params:e.params,sprites:e.sprites,audios:e.audios,audioBlobs:I,atlasRects:s.rects,atlasWidth:s.atlasWidth,atlasHeight:s.atlasHeight,atlasImageBytes:B})});for(const B of i.values())B.close()}async acquireSharedSVGAEntity(A){const t=A,e=this.sharedSVGAEntities.get(t);if(e)return e.refs++,{entity:e.entity,audioBlobs:e.audioBlobs,release:()=>this.releaseSharedSVGAEntity(t)};let i=this.pendingSharedSVGAEntities.get(t);i||(i=this.buildSharedSVGAEntity(A),this.pendingSharedSVGAEntities.set(t,i));let I;try{I=await i}catch(n){throw this.pendingSharedSVGAEntities.delete(t),n}let s=this.sharedSVGAEntities.get(t);return s?s.refs++:(s={refs:1,entity:I.entity,audioBlobs:I.audioBlobs},this.sharedSVGAEntities.set(t,s)),this.pendingSharedSVGAEntities.delete(t),{entity:s.entity,audioBlobs:s.audioBlobs,release:()=>this.releaseSharedSVGAEntity(t)}}async buildSharedSVGAEntity(A){const t=await kd(A);if(t){const s=await createImageBitmap(new Blob([t.atlasImageBytes],{type:"image/png"}),{premultiplyAlpha:"none"}),n=this.backend.createTexture(s,{width:t.atlasWidth,height:t.atlasHeight,filter:"linear"});return s.close(),{entity:{params:t.params,sprites:t.sprites,audios:t.audios,atlasTextureHandle:n,atlasRects:t.atlasRects,audioBuffers:new Map},audioBlobs:t.audioBlobs}}const{movie:e,imageBitmaps:i,audioBlobs:I}=await zn(A,{useWorker:this.options.svgaParseInWorker!==!1});try{const s=await Xn(i,this.backend,4096,2,{captureEncodedPng:!0});return s.encodedPngBytesPromise&&s.encodedPngBytesPromise.then(n=>{n&&qB(A,{params:e.params,sprites:e.sprites,audios:e.audios,audioBlobs:I,atlasRects:s.rects,atlasWidth:s.atlasWidth,atlasHeight:s.atlasHeight,atlasImageBytes:n})}),{entity:{params:e.params,sprites:e.sprites,audios:e.audios,atlasTextureHandle:s.textureHandle,atlasRects:s.rects,audioBuffers:new Map},audioBlobs:I}}finally{for(const s of i.values())s.close()}}releaseSharedSVGAEntity(A){var t;const e=this.sharedSVGAEntities.get(A);e&&(e.refs=Math.max(0,e.refs-1),!(e.refs>0)&&(e.entity.atlasTextureHandle&&((t=this.backend)==null||t.deleteTexture(e.entity.atlasTextureHandle)),this.sharedSVGAEntities.delete(A)))}async finishLoadSVGA(A,t,e){let i=0;for(const[I,s]of e)await this.manager.audioManager.decodeAudio(I,s),i++,i<e.size&&await new Promise(n=>{if(typeof requestAnimationFrame=="function"){requestAnimationFrame(()=>n());return}setTimeout(n,0)});A.videoEntity=t,A.options.svgaSlots&&(A.svgaSlotTextures=await Pa(this.backend,A.videoEntity,A.options.svgaSlots))}shouldTryWebCodecs(){return this.options.preferWebCodecs===!0&&typeof VideoDecoder!="undefined"}logPlaybackBackend(A,t,e){const i=t==="webcodecs"?"WebCodecs (mp4box decode)":"HTMLVideoElement",I=e?` — ${e}`:"";console.info(`[GiftStage] ${A.type} [${A.id}]: ${i}${I}`)}async tryWebCodecsPlayback(A){if(!this.shouldTryWebCodecs())return null;try{const t=typeof A=="string"?await Rs(A):A;return await YA.create(t,void 0,{useWorker:this.options.webCodecsDecodeInWorker!==!1,maxDecodedFrames:this.options.webCodecsMaxDecodedFrames,decodeAheadFrames:this.options.webCodecsDecodeAheadFrames})}catch(t){const e=t instanceof Error?t.message:String(t);return console.warn(`[GiftStage] WebCodecs path failed, falling back to <video>: ${e}`),null}}async loadVAP(A,t){var e;if(!t.config)throw new Error("VAP requires config");const i=await Wn(t.config);A.vapConfig=i;const I=await er(i,t.vapSlots);if(I.size>0){const Q=OA(i.info),a=ir(i);let o=null,r=null;try{o=new Gd(i,a,I,Q.w,Q.h)}catch(E){console.warn("[GiftStage] VAP mixed rendering fell back to CPU compositor",E),r=gr(Q.w,Q.h)}A.vapMixState={texture:this.backend.createEmptyTexture(Q.w,Q.h,{filter:"linear"}),width:Q.w,height:Q.h,composer:o,frameMap:a,resources:I,lastFrameIndex:-1,lastSourceRef:null,...r!=null?r:{}},A.videoTextureHandle=A.vapMixState.texture}console.info("[GiftStage:WC] loadVAP: try WebCodecs / video…");const n=await this.tryWebCodecsPlayback(t.source);if(n){A.webcodecsPlayback=n,A.wcPlaybackTime=0;const Q=n.getFrameForTime(0);if(!Q)throw n.destroy(),A.webcodecsPlayback=null,new Error("WebCodecs: missing first frame");if(!A.vapMixState){const o=Q.displayWidth||Q.codedWidth,r=Q.displayHeight||Q.codedHeight,{w:E,h}=HB(A,o,r,"vap",i),c=this.manager.tryAllocateWebCodecsAtlas(A.id,E,h,this.options.webCodecsVideoAtlas);if(c)A.videoTextureHandle=c.handle,A.wcAtlasRect=c.rect,this.backend.updateTextureRegion(c.handle,Q,c.rect.x,c.rect.y,E,h);else{const f=this.backend.createTexture(Q,{width:o,height:r,filter:"linear"});A.videoTextureHandle=f}}A.videoElement=null;const a=A.videoTextureHandle;console.info("[GiftStage:WC] VAP texture",{giftId:A.id,atlas:!!A.wcAtlasRect&&!A.vapMixState,mixed:!!A.vapMixState,tex:`${a.width}x${a.height}`,frame0:`${Q.displayWidth}x${Q.displayHeight}`,atlasCell:A.wcAtlasRect?`${A.wcAtlasRect.w}x${A.wcAtlasRect.h}`:void 0}),this.logPlaybackBackend(A,"webcodecs");return}const B=await this.tryAcquireSharedHtmlVideo(A,t);if(B)A.videoElement=B.video,A.releaseSharedVideoPlayback=B.release;else{const Q=await this.acquireVideoPlaybackSource(t.source);A.releaseMediaSource=(e=Q.release)!=null?e:null;const a=this.createVideo(Q.src,t.loop===0);A.videoElement=a}const C=A.videoElement;if(B){await B.ready;const Q=this.acquireSharedVideoTexture(B.cacheKey,C);A.videoTextureHandle=Q.texture,A.releaseSharedVideoTexture=Q.release}else await this.waitVideoReady(C),A.vapMixState||(A.videoTextureHandle=this.backend.createTexture(C,{width:C.videoWidth,height:C.videoHeight,filter:"linear"}));A.releaseSharedVideoPlayback||this.bindVideoLoopOnEnded(A,C),this.logPlaybackBackend(A,"video",this.shouldTryWebCodecs()?"fallback after WebCodecs unavailable or failed":"preferWebCodecs off or no VideoDecoder")}async loadAlphaVideo(A,t){var e;console.info("[GiftStage:WC] loadAlphaVideo: try WebCodecs / video…");const i=await this.tryWebCodecsPlayback(t.source);if(i){A.webcodecsPlayback=i,A.wcPlaybackTime=0;const n=i.getFrameForTime(0);if(!n)throw i.destroy(),A.webcodecsPlayback=null,new Error("WebCodecs: missing first frame");const B=n.displayWidth||n.codedWidth,C=n.displayHeight||n.codedHeight,{w:Q,h:a}=HB(A,B,C,"alphaVideo",void 0),o=this.manager.tryAllocateWebCodecsAtlas(A.id,Q,a,this.options.webCodecsVideoAtlas);if(o)A.videoTextureHandle=o.handle,A.wcAtlasRect=o.rect,this.backend.updateTextureRegion(o.handle,n,o.rect.x,o.rect.y,Q,a);else{const E=this.backend.createTexture(n,{width:B,height:C,filter:"linear"});A.videoTextureHandle=E}A.videoElement=null;const r=A.videoTextureHandle;console.info("[GiftStage:WC] alphaVideo texture",{giftId:A.id,atlas:!!A.wcAtlasRect,tex:`${r.width}x${r.height}`,frame0:`${n.displayWidth}x${n.displayHeight}`,atlasCell:A.wcAtlasRect?`${A.wcAtlasRect.w}x${A.wcAtlasRect.h}`:void 0}),this.logPlaybackBackend(A,"webcodecs");return}const I=await this.tryAcquireSharedHtmlVideo(A,t);if(I)A.videoElement=I.video,A.releaseSharedVideoPlayback=I.release;else{const n=await this.acquireVideoPlaybackSource(t.source);A.releaseMediaSource=(e=n.release)!=null?e:null;const B=this.createVideo(n.src,t.loop===0);A.videoElement=B}const s=A.videoElement;if(I){await I.ready;const n=this.acquireSharedVideoTexture(I.cacheKey,s);A.videoTextureHandle=n.texture,A.releaseSharedVideoTexture=n.release}else await this.waitVideoReady(s),A.videoTextureHandle=this.backend.createTexture(s,{width:s.videoWidth,height:s.videoHeight,filter:"linear"});A.releaseSharedVideoPlayback||this.bindVideoLoopOnEnded(A,s),this.logPlaybackBackend(A,"video",this.shouldTryWebCodecs()?"fallback after WebCodecs unavailable or failed":"preferWebCodecs off or no VideoDecoder")}bindVideoLoopOnEnded(A,t){t.addEventListener("ended",()=>{var e,i,I,s,n;if(A.state!=="playing")return;const B=(e=A.options.loop)!=null?e:1;if(B===0){t.currentTime=0,t.play();return}if(A.loopCount++,A.loopCount>=B){const C={id:A.id,type:A.type,pause:()=>{},resume:()=>{},destroy:()=>this.removeGift(A.id)};if((i=A.onComplete)==null||i.call(A,C),A.flyTo){A.state="fly";const Q=fs(this.canvas);this.manager.postAnimator.startFly(A,A.flyTo.x*Q.sx,A.flyTo.y*Q.sy,(I=A.scaleTo)!=null?I:.3,(s=A.flyDuration)!=null?s:600,(n=A.easing)!=null?n:xs,()=>{var a;A.state="finished",(a=A.onFlyComplete)==null||a.call(A,C)})}else A.state="finished";return}t.currentTime=0,t.play()})}createVideo(A,t){const e=document.createElement("video");return e.crossOrigin="anonymous",e.autoplay=!0,e.preload="auto",e.muted=!0,e.playsInline=!0,e.setAttribute("playsinline",""),e.setAttribute("webkit-playsinline","true"),e.loop=t,e.style.cssText="display:none;",e.src=A,document.body.appendChild(e),e.load(),e}waitVideoMetadata(A){return new Promise((t,e)=>{const i=()=>{A.removeEventListener("loadedmetadata",I),A.removeEventListener("error",s)},I=()=>{i(),t()},s=()=>{i(),e(new Error("Video metadata load failed"))};A.addEventListener("loadedmetadata",I),A.addEventListener("error",s),A.readyState>=HTMLMediaElement.HAVE_METADATA&&(i(),t())})}async probeVideoNaturalSize(A){var t;const e=await this.acquireVideoPlaybackSource(A),i=document.createElement("video");i.crossOrigin="anonymous",i.preload="metadata",i.muted=!0,i.playsInline=!0,i.setAttribute("playsinline",""),i.setAttribute("webkit-playsinline","true"),i.style.cssText="display:none;",i.src=e.src,document.body.appendChild(i),i.load();try{return await this.waitVideoMetadata(i),{width:i.videoWidth,height:i.videoHeight}}finally{try{i.pause(),i.removeAttribute("src"),i.load(),i.remove()}catch(I){}(t=e.release)==null||t.call(e)}}async acquireVideoPlaybackSource(A){if(typeof A!="string"){const i=URL.createObjectURL(new Blob([A]));return{src:i,release:()=>URL.revokeObjectURL(i)}}const t=this.normalizeSharedVideoSourceKey(A);if(!t)return{src:A};let e=this.sharedVideoSources.get(t);e||(e={refs:0,objectUrl:null,promise:this.fetchSharedVideoSource(t)},this.sharedVideoSources.set(t,e)),e.refs++;try{return{src:await e.promise,release:()=>this.releaseSharedVideoSource(t)}}catch(i){return this.releaseSharedVideoSource(t),console.warn("[GiftStage] shared video prefetch failed, using original url",i),{src:A}}}normalizeSharedVideoSourceKey(A){try{const t=new URL(A,window.location.href);return t.protocol==="blob:"||t.protocol==="data:"?null:t.href}catch(t){return null}}async fetchSharedVideoSource(A){const t=new Blob([await Rs(A)]),e=this.sharedVideoSources.get(A),i=URL.createObjectURL(t);return e&&(e.objectUrl=i,e.refs===0&&(URL.revokeObjectURL(i),this.sharedVideoSources.delete(A))),i}releaseSharedVideoSource(A){const t=this.sharedVideoSources.get(A);t&&(t.refs=Math.max(0,t.refs-1),t.refs===0&&t.objectUrl&&(URL.revokeObjectURL(t.objectUrl),this.sharedVideoSources.delete(A)))}async tryAcquireSharedHtmlVideo(A,t){var e,i;if(this.options.shareIdenticalVideoPlayback===!1||t.loop!==0||typeof t.source!="string"||A.type==="vap"&&A.vapMixState)return null;const I=this.normalizeSharedVideoSourceKey(t.source);if(!I)return null;const s=(e=this.options.sharedVideoPlaybackWindowMs)!=null?e:In.DEFAULT_SHARED_VIDEO_PLAYBACK_WINDOW_MS,n=Math.max(0,s)/1e3,B=this.sharedHtmlVideos.get(I);if(B)return B.video.currentTime>n?null:(B.refs++,{cacheKey:I,video:B.video,ready:B.ready,release:()=>this.releaseSharedHtmlVideo(I)});let C=this.pendingSharedHtmlVideos.get(I);C||(C=(async()=>{var o;const r=await this.acquireVideoPlaybackSource(t.source),E=this.createVideo(r.src,!0),h=this.waitVideoReady(E);return{video:E,ready:h,releaseSource:(o=r.release)!=null?o:null}})(),this.pendingSharedHtmlVideos.set(I,C));let Q;try{Q=await C}catch(o){throw this.pendingSharedHtmlVideos.delete(I),o}let a=this.sharedHtmlVideos.get(I);return a?a.refs++:(a={refs:1,video:Q.video,ready:Q.ready,releaseSource:(i=Q.releaseSource)!=null?i:null},this.sharedHtmlVideos.set(I,a)),this.pendingSharedHtmlVideos.delete(I),{cacheKey:I,video:a.video,ready:a.ready,release:()=>this.releaseSharedHtmlVideo(I)}}acquireSharedVideoTexture(A,t){const e=this.sharedVideoTextures.get(A);if(e)return e.refs++,{texture:e.texture,release:()=>this.releaseSharedVideoTexture(A)};const i=this.backend.createTexture(t,{width:t.videoWidth,height:t.videoHeight,filter:"linear"});return this.sharedVideoTextures.set(A,{refs:1,texture:i}),{texture:i,release:()=>this.releaseSharedVideoTexture(A)}}releaseSharedVideoTexture(A){var t;const e=this.sharedVideoTextures.get(A);e&&(e.refs=Math.max(0,e.refs-1),!(e.refs>0)&&((t=this.backend)==null||t.deleteTexture(e.texture),this.sharedVideoTextures.delete(A)))}releaseSharedHtmlVideo(A){var t;const e=this.sharedHtmlVideos.get(A);if(e&&(e.refs=Math.max(0,e.refs-1),!(e.refs>0))){try{e.video.pause(),e.video.removeAttribute("src"),e.video.load(),e.video.remove()}catch(i){}(t=e.releaseSource)==null||t.call(e),this.sharedHtmlVideos.delete(A)}}waitForFirstVideoFrame(A){return new Promise(t=>{typeof A.requestVideoFrameCallback=="function"?A.requestVideoFrameCallback(()=>t()):requestAnimationFrame(()=>t())})}waitVideoReady(A){return new Promise((t,e)=>{const i=()=>{A.removeEventListener("canplay",s),A.removeEventListener("error",n)},I=async()=>{try{await A.play(),await this.waitForFirstVideoFrame(A),t()}catch(B){e(B)}},s=()=>{i(),I()},n=()=>{i(),e(new Error("Video load failed"))};A.addEventListener("canplay",s),A.addEventListener("error",n),A.readyState>=HTMLMediaElement.HAVE_FUTURE_DATA&&(i(),I())})}removeGift(A){var t;(t=this.manager)==null||t.removeSlot(A)}removeAll(){if(this.manager)for(const A of this.manager.getSlotIds())this.manager.removeSlot(A)}pause(){var A;(A=this.manager)==null||A.pause()}resume(){var A;(A=this.manager)==null||A.resume()}get activeCount(){var A,t;return(t=(A=this.manager)==null?void 0:A.activeCount)!=null?t:0}get backendType(){var A,t;return(t=(A=this.backend)==null?void 0:A.type)!=null?t:"webgl2"}destroy(){var A,t;this.destroyed=!0,(A=this.resizeObserver)==null||A.disconnect(),this.resizeObserver=null,window.removeEventListener("resize",this.onWindowLayout),window.removeEventListener("orientationchange",this.onWindowLayout),(t=this.manager)==null||t.destroy();for(const[e]of this.sharedHtmlVideos)this.releaseSharedHtmlVideo(e);for(const[e]of this.sharedSVGAEntities)this.releaseSharedSVGAEntity(e);for(const[e]of this.sharedVideoTextures)this.releaseSharedVideoTexture(e);this.pendingSharedSVGAEntities.clear(),this.pendingSharedHtmlVideos.clear();for(const[e,i]of this.sharedVideoSources)i.objectUrl&&URL.revokeObjectURL(i.objectUrl),this.sharedVideoSources.delete(e);this.canvas.remove(),this.backend=null,this.manager=null}};X(hn,"DEFAULT_SHARED_VIDEO_PLAYBACK_WINDOW_MS",100);X(hn,"DEFAULT_RESOURCE_CACHE_MEMORY_BYTES",128*1024*1024);X(hn,"DEFAULT_RESOURCE_CACHE_PERSISTENT_BYTES",2048*1024*1024);let Jd=hn;exports.AlphaVideoRenderer=aC;exports.AudioManager=oC;exports.BufferPool=eC;exports.GiftStage=Jd;exports.PostAnimator=rC;exports.RenderManager=hC;exports.SVGABatchRenderer=gC;exports.VAPRenderer=QC;exports.WebCodecsMp4Playback=YA;exports.WebGL1Backend=Kn;exports.WebGL2Backend=VB;exports.WebGPUBackend=ZB;exports.buildAtlas=Xn;exports.buildBatchVerticesJS=Ts;exports.canSharedArrayBuffer=XQ;exports.canWebGL1=zQ;exports.canWebGL2=jQ;exports.canWebGPU=WQ;exports.clamp=qn;exports.createBackend=jB;exports.decodeSVGAProto=lC;exports.easeInOutCubic=dr;exports.easeInOutQuad=lr;exports.easeInQuad=hr;exports.easeOutBack=fr;exports.easeOutCubic=xs;exports.easeOutQuad=cr;exports.generateId=iC;exports.inflateJS=cC;exports.initWasm=tC;exports.isWasmReady=XA;exports.lerp=Zs;exports.linear=Er;exports.ortho=_A;exports.parseSVGA=zn;exports.parseVAPConfig=Wn;
8323
8323
  //# sourceMappingURL=gift-stage.cjs.js.map