akarisub 0.1.0 → 0.2.1

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.
Files changed (43) hide show
  1. package/README.md +17 -3
  2. package/dist/akarisub-worker.js +2 -2
  3. package/dist/akarisub-worker.wasm +0 -0
  4. package/dist/akarisub.umd.js +5 -5
  5. package/dist/index.js +5 -5
  6. package/dist/ts/index.d.ts +14 -0
  7. package/dist/ts/index.d.ts.map +1 -0
  8. package/dist/ts/index.js +17 -0
  9. package/dist/ts/index.js.map +1 -0
  10. package/dist/ts/ts/akarisub.d.ts +229 -0
  11. package/dist/ts/ts/akarisub.d.ts.map +1 -0
  12. package/dist/ts/ts/akarisub.js +1079 -0
  13. package/dist/ts/ts/akarisub.js.map +1 -0
  14. package/dist/ts/ts/types.d.ts +424 -0
  15. package/dist/ts/ts/types.d.ts.map +1 -0
  16. package/dist/ts/ts/types.js +5 -0
  17. package/dist/ts/ts/types.js.map +1 -0
  18. package/dist/ts/ts/utils.d.ts +78 -0
  19. package/dist/ts/ts/utils.d.ts.map +1 -0
  20. package/dist/ts/ts/utils.js +395 -0
  21. package/dist/ts/ts/utils.js.map +1 -0
  22. package/dist/ts/ts/webgl2-renderer.d.ts +51 -0
  23. package/dist/ts/ts/webgl2-renderer.d.ts.map +1 -0
  24. package/dist/ts/ts/webgl2-renderer.js +388 -0
  25. package/dist/ts/ts/webgl2-renderer.js.map +1 -0
  26. package/dist/ts/ts/webgpu-renderer.d.ts +64 -0
  27. package/dist/ts/ts/webgpu-renderer.d.ts.map +1 -0
  28. package/dist/ts/ts/webgpu-renderer.js +610 -0
  29. package/dist/ts/ts/webgpu-renderer.js.map +1 -0
  30. package/dist/ts/ts/worker.d.ts +6 -0
  31. package/dist/ts/ts/worker.d.ts.map +1 -0
  32. package/dist/ts/ts/worker.js +1695 -0
  33. package/dist/ts/ts/worker.js.map +1 -0
  34. package/dist/ts/wrapper.d.ts +8 -0
  35. package/dist/ts/wrapper.d.ts.map +1 -0
  36. package/dist/ts/wrapper.js +9 -0
  37. package/dist/ts/wrapper.js.map +1 -0
  38. package/package.json +7 -6
  39. package/src/ts/akarisub.ts +194 -75
  40. package/src/ts/types.ts +22 -17
  41. package/src/ts/webgl2-renderer.ts +7 -2
  42. package/src/ts/webgpu-renderer.ts +12 -4
  43. package/src/ts/worker.ts +207 -100
@@ -7,7 +7,7 @@
7
7
  root.AkariSub = factory();
8
8
  }
9
9
  }(typeof self !== 'undefined' ? self : this, function() {
10
- (()=>{var{defineProperty:h,getOwnPropertyNames:KJ,getOwnPropertyDescriptor:NJ}=Object,ZJ=Object.prototype.hasOwnProperty;function $J(J){return this[J]}var QJ=(J)=>{var K=(g??=new WeakMap).get(J),Z;if(K)return K;if(K=h({},"__esModule",{value:!0}),J&&typeof J==="object"||typeof J==="function"){for(var N of KJ(J))if(!ZJ.call(K,N))h(K,N,{get:$J.bind(J,N),enumerable:!(Z=NJ(J,N))||Z.enumerable})}return g.set(J,K),K},g;var OJ=(J)=>J;function FJ(J,K){this[J]=OJ.bind(null,K)}var UJ=(J,K)=>{for(var Z in K)h(J,Z,{get:K[Z],enumerable:!0,configurable:!0,set:FJ.bind(K,Z)})};var YJ={};UJ(YJ,{webYCbCrMap:()=>u,testImageBugs:()=>l,runFeatureTests:()=>a,parseAss:()=>r,libassYCbCrMap:()=>s,isWebGPUSupported:()=>f,isWebGL2Supported:()=>p,getVideoPosition:()=>c,getColorSpaceFilterUrl:()=>o,getBitmapBug:()=>e,getAlphaBug:()=>t,fixPlayRes:()=>i,fixAlpha:()=>m,dropBlur:()=>n,default:()=>R,computeCanvasSize:()=>w,colorMatrixConversionMap:()=>y,WebGPURenderer:()=>v,WebGL2Renderer:()=>x,AkariSub:()=>R});var u={bt709:"BT709",bt470bg:"BT601",smpte170m:"BT601"},y={BT601:{BT709:"1.0863 -0.0723 -0.014 0 0 0.0965 0.8451 0.0584 0 0 -0.0141 -0.0277 1.0418"},BT709:{BT601:"0.9137 0.0784 0.0079 0 0 -0.1049 1.1722 -0.0671 0 0 0.0096 0.0322 0.9582"},FCC:{BT709:"1.0873 -0.0736 -0.0137 0 0 0.0974 0.8494 0.0531 0 0 -0.0127 -0.0251 1.0378",BT601:"1.001 -0.0008 -0.0002 0 0 0.0009 1.005 -0.006 0 0 0.0013 0.0027 0.996"},SMPTE240M:{BT709:"0.9993 0.0006 0.0001 0 0 -0.0004 0.9812 0.0192 0 0 -0.0034 -0.0114 1.0148",BT601:"0.913 0.0774 0.0096 0 0 -0.1051 1.1508 -0.0456 0 0 0.0063 0.0207 0.973"}},s=[null,"BT601",null,"BT601","BT601","BT709","BT709","SMPTE240M","SMPTE240M","FCC","FCC"];function o(J,K){if(!J||!K)return null;if(J===K)return null;let Z=y[J]?.[K];if(!Z)return null;return`url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix type='matrix' values='${Z} 0 0 0 0 0 1 0'/></filter></svg>#f")`}function w(J,K,Z,N,Q){let F=Z<=0?1:Z,$=globalThis.devicePixelRatio||1;if(K<=0||J<=0)return{width:0,height:0};let U=F<1?-1:1,O=K*$;if(U*O*F<=U*N)O*=F;else if(U*O<U*N)O=N;if(Q>0&&O>Q)O=Q;return J*=O/K,K=O,{width:J,height:K}}function c(J,K=J.videoWidth,Z=J.videoHeight){let N=K/Z,{offsetWidth:Q,offsetHeight:F}=J,$=Q/F,U=Q,O=F;if($>N)U=Math.floor(F*N);else O=Math.floor(Q/N);let E=(Q-U)/2,q=(F-O)/2;return{width:U,height:O,x:E,y:q}}function m(J,K){if(!K)return J;let Z=J.length,N=Z-Z%16,Q=3;for(;Q<N;Q+=16){if(J[Q]<2)J[Q]=1;if(J[Q+4]<2)J[Q+4]=1;if(J[Q+8]<2)J[Q+8]=1;if(J[Q+12]<2)J[Q+12]=1}for(;Q<Z;Q+=4)if(J[Q]<2)J[Q]=1;return J}function r(J,K=!1){let Z=[],N=J.split(/[\r\n]+/g),Q=N.length,F=null,$=null;for(let U=0;U<Q;U++){let O=N[U];if(!O||/^\s*$/.test(O))continue;let E=O[0];if(E==="["){let q=O.match(/^\[(.*)\]$/);if(q){if(K&&q[1].toLowerCase()==="events")break;F=null,$={name:q[1],body:[]},Z.push($);continue}}if(!$)continue;if(E===";")$.body.push({type:"comment",value:O.substring(1)});else{let q=O.indexOf(":");if(q===-1)continue;let L=O.substring(0,q),_=O.substring(q+1).trim();if(F||L==="Format"){let Y=_.split(",");if(F&&Y.length>F.length){let z=Y.slice(F.length-1).join(",");Y=Y.slice(0,F.length-1),Y.push(z)}let T=Y.length;for(let z=0;z<T;z++)Y[z]=Y[z].trim();if(F){let z={},j=Math.min(F.length,T);for(let P=0;P<j;P++)z[F[P]]=Y[P];_=z}else _=Y}if(L==="Format")F=_;$.body.push({key:L,value:_})}}return Z}var EJ=/\\blur(?:[0-9]+\.)?[0-9]+/gm;function n(J){return J.replace(EJ,"")}var XJ=[{w:7680,h:4320},{w:3840,h:2160},{w:2560,h:1440},{w:1920,h:1080},{w:1280,h:720}];function qJ(J,K){let Z=[...XJ].sort((N,Q)=>N.w-Q.w);for(let N of Z)if(J<=N.w&&K<=N.h)return N;return{w:Math.ceil(J/100)*100,h:Math.ceil(K/100)*100}}function k(J,K){return K&&K.includes(".")?J.toFixed(2).replace(/\.?0+$/,""):Math.round(J)}function i(J){let K=J.match(/PlayResX:\s*(\d+)/i),Z=J.match(/PlayResY:\s*(\d+)/i),N=K?parseInt(K[1],10):1920,Q=Z?parseInt(Z[1],10):1080,F=/\\pos\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,$=/\\move\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)/g,U=/\\org\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,O=/\\i?clip\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,E=0,q=0,L=(M,X,V)=>{let I,D=new RegExp(M.source,"g");while((I=D.exec(J))!==null){for(let C of X)if(I[C]){let A=Math.abs(parseFloat(I[C]));if(A>E)E=A}for(let C of V)if(I[C]){let A=Math.abs(parseFloat(I[C]));if(A>q)q=A}}};if(L(F,[1],[2]),L($,[1,3],[2,4]),L(U,[1],[2]),L(O,[1,3],[2,4]),E<=N&&q<=Q)return J;let _=qJ(E,q),Y=N/_.w,T=Q/_.h,z=Math.min(Y,T),j=Math.max(Y,T),P=1,W=J,B=W.match(/(\[Events\][\s\S]*)/i);if(!B)return W;let G=B[1];return G=G.replace(F,(M,X,V)=>`\\pos(${k(parseFloat(X)*Y,X)},${k(parseFloat(V)*T,V)})`),G=G.replace(/\\move\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)(?:\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+))?\s*\)/g,(M,X,V,I,D,C,A)=>{let d=`\\move(${k(parseFloat(X)*Y,X)},${k(parseFloat(V)*T,V)},${k(parseFloat(I)*Y,I)},${k(parseFloat(D)*T,D)}`;return C?`${d},${C},${A})`:`${d})`}),G=G.replace(U,(M,X,V)=>`\\org(${k(parseFloat(X)*Y,X)},${k(parseFloat(V)*T,V)})`),G=G.replace(/\\(i?clip)\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,(M,X,V,I,D,C)=>`\\${X}(${k(parseFloat(V)*Y,V)},${k(parseFloat(I)*T,I)},${k(parseFloat(D)*Y,D)},${k(parseFloat(C)*T,C)})`),G=G.replace(/\\fs([\d.]+)/g,(M,X)=>`\\fs${k(parseFloat(X)*j,X)}`),G=G.replace(/\\fscx([\d.]+)/g,(M,X)=>`\\fscx${k(parseFloat(X)*P,X)}`),G=G.replace(/\\xbord([\d.]+)/g,(M,X)=>`\\xbord${k(parseFloat(X)*Y,X)}`),G=G.replace(/\\ybord([\d.]+)/g,(M,X)=>`\\ybord${k(parseFloat(X)*T,X)}`),G=G.replace(/\\xshad(-?[\d.]+)/g,(M,X)=>`\\xshad${k(parseFloat(X)*Y,X)}`),G=G.replace(/\\yshad(-?[\d.]+)/g,(M,X)=>`\\yshad${k(parseFloat(X)*T,X)}`),["fsp","bord","shad","be","blur"].forEach((M)=>{let X=new RegExp(`\\\\${M}(-?[\\d.]+)`,"g");G=G.replace(X,(V,I)=>`\\${M}${k(parseFloat(I)*z,I)}`)}),G=G.replace(/(\\i?clip\s*\([^,)]+m[^)]+\)|\\p[1-9][^}]*?)(?=[\\}]|$)/g,(M)=>{return M.replace(/(-?[\d.]+)\s+(-?[\d.]+)/g,(X,V,I)=>{return`${k(parseFloat(V)*Y,V)} ${k(parseFloat(I)*T,I)}`})}),W.substring(0,B.index)+G}var b=null,S=null;async function l(){if(b!==null&&S!==null)return{hasAlphaBug:b,hasBitmapBug:S};let J=document.createElement("canvas"),K=J.getContext("2d",{willReadFrequently:!0});if(!K)throw Error("Canvas rendering not supported");if(typeof ImageData.prototype.constructor==="function")try{new ImageData(new Uint8ClampedArray([0,0,0,0]),1,1)}catch{console.log("Detected that ImageData is not constructable despite browser saying so")}let Z=document.createElement("canvas"),N=Z.getContext("2d",{willReadFrequently:!0});if(!N)throw Error("Canvas rendering not supported");J.width=Z.width=1,J.height=Z.height=1,K.clearRect(0,0,1,1),N.clearRect(0,0,1,1);let Q=N.getImageData(0,0,1,1).data;K.putImageData(new ImageData(new Uint8ClampedArray([0,255,0,0]),1,1),0,0),N.drawImage(J,0,0);let F=N.getImageData(0,0,1,1).data;if(b=Q[1]!==F[1],b)console.log("Detected a browser having issue with transparent pixels, applying workaround");if(typeof createImageBitmap<"u"){let $=new Uint8ClampedArray([255,0,255,0,255]).subarray(1,5);N.drawImage(await createImageBitmap(new ImageData($,1)),0,0);let{data:U}=N.getImageData(0,0,1,1);S=!1;for(let O=0;O<U.length;O++)if(Math.abs($[O]-U[O])>15){S=!0,console.log("Detected a browser having issue with partial bitmaps, applying workaround");break}}else S=!1;return J.remove(),Z.remove(),{hasAlphaBug:b,hasBitmapBug:S}}async function a(){return l()}function t(){return b}function e(){return S}function f(){return typeof navigator<"u"&&"gpu"in navigator}class v{device=null;context=null;pipeline=null;bindGroupLayout=null;uniformBuffer=null;imageDataBuffer=null;textureArray=null;textureArrayView=null;textureArraySize=0;textureArrayWidth=0;textureArrayHeight=0;pendingDestroyTextures=[];imageDataArray;resolutionArray=new Float32Array(2);conversionBuffer=null;conversionBufferSize=0;bindGroup=null;bindGroupDirty=!0;lastCanvasWidth=0;lastCanvasHeight=0;format="bgra8unorm";_canvas=null;_initPromise=null;_initialized=!1;constructor(){this.imageDataArray=new Float32Array(2048)}async init(){if(this._initPromise)return this._initPromise;return this._initPromise=this._initDevice(),this._initPromise}async _initDevice(){if(!navigator.gpu)throw Error("WebGPU not supported");let J=await navigator.gpu.requestAdapter({powerPreference:"high-performance"});if(!J)throw Error("No WebGPU adapter found");this.device=await J.requestDevice(),this.format=navigator.gpu.getPreferredCanvasFormat();let K=this.device.createShaderModule({code:`
10
+ (()=>{var{defineProperty:h,getOwnPropertyNames:$J,getOwnPropertyDescriptor:QJ}=Object,KJ=Object.prototype.hasOwnProperty;function NJ(J){return this[J]}var OJ=(J)=>{var Z=(d??=new WeakMap).get(J),Q;if(Z)return Z;if(Z=h({},"__esModule",{value:!0}),J&&typeof J==="object"||typeof J==="function"){for(var $ of $J(J))if(!KJ.call(Z,$))h(Z,$,{get:NJ.bind(J,$),enumerable:!(Q=QJ(J,$))||Q.enumerable})}return d.set(J,Z),Z},d;var GJ=(J)=>J;function FJ(J,Z){this[J]=GJ.bind(null,Z)}var UJ=(J,Z)=>{for(var Q in Z)h(J,Q,{get:Z[Q],enumerable:!0,configurable:!0,set:FJ.bind(Z,Q)})};var PJ={};UJ(PJ,{webYCbCrMap:()=>u,testImageBugs:()=>l,runFeatureTests:()=>a,parseAss:()=>o,libassYCbCrMap:()=>s,isWebGPUSupported:()=>f,isWebGL2Supported:()=>p,getVideoPosition:()=>c,getColorSpaceFilterUrl:()=>r,getBitmapBug:()=>e,getAlphaBug:()=>t,fixPlayRes:()=>i,fixAlpha:()=>m,dropBlur:()=>n,default:()=>R,computeCanvasSize:()=>w,colorMatrixConversionMap:()=>y,WebGPURenderer:()=>v,WebGL2Renderer:()=>x,AkariSub:()=>R});var u={bt709:"BT709",bt470bg:"BT601",smpte170m:"BT601"},y={BT601:{BT709:"1.0863 -0.0723 -0.014 0 0 0.0965 0.8451 0.0584 0 0 -0.0141 -0.0277 1.0418"},BT709:{BT601:"0.9137 0.0784 0.0079 0 0 -0.1049 1.1722 -0.0671 0 0 0.0096 0.0322 0.9582"},FCC:{BT709:"1.0873 -0.0736 -0.0137 0 0 0.0974 0.8494 0.0531 0 0 -0.0127 -0.0251 1.0378",BT601:"1.001 -0.0008 -0.0002 0 0 0.0009 1.005 -0.006 0 0 0.0013 0.0027 0.996"},SMPTE240M:{BT709:"0.9993 0.0006 0.0001 0 0 -0.0004 0.9812 0.0192 0 0 -0.0034 -0.0114 1.0148",BT601:"0.913 0.0774 0.0096 0 0 -0.1051 1.1508 -0.0456 0 0 0.0063 0.0207 0.973"}},s=[null,"BT601",null,"BT601","BT601","BT709","BT709","SMPTE240M","SMPTE240M","FCC","FCC"];function r(J,Z){if(!J||!Z)return null;if(J===Z)return null;let Q=y[J]?.[Z];if(!Q)return null;return`url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix type='matrix' values='${Q} 0 0 0 0 0 1 0'/></filter></svg>#f")`}function w(J,Z,Q,$,O){let N=Q<=0?1:Q,K=globalThis.devicePixelRatio||1;if(Z<=0||J<=0)return{width:0,height:0};let F=N<1?-1:1,G=Z*K;if(F*G*N<=F*$)G*=N;else if(F*G<F*$)G=$;if(O>0&&G>O)G=O;return J*=G/Z,Z=G,{width:J,height:Z}}function c(J,Z=J.videoWidth,Q=J.videoHeight){let $=Z/Q,{offsetWidth:O,offsetHeight:N}=J,K=O/N,F=O,G=N;if(K>$)F=Math.floor(N*$);else G=Math.floor(O/$);let U=(O-F)/2,E=(N-G)/2;return{width:F,height:G,x:U,y:E}}function m(J,Z){if(!Z)return J;let Q=J.length,$=Q-Q%16,O=3;for(;O<$;O+=16){if(J[O]<2)J[O]=1;if(J[O+4]<2)J[O+4]=1;if(J[O+8]<2)J[O+8]=1;if(J[O+12]<2)J[O+12]=1}for(;O<Q;O+=4)if(J[O]<2)J[O]=1;return J}function o(J,Z=!1){let Q=[],$=J.split(/[\r\n]+/g),O=$.length,N=null,K=null;for(let F=0;F<O;F++){let G=$[F];if(!G||/^\s*$/.test(G))continue;let U=G[0];if(U==="["){let E=G.match(/^\[(.*)\]$/);if(E){if(Z&&E[1].toLowerCase()==="events")break;N=null,K={name:E[1],body:[]},Q.push(K);continue}}if(!K)continue;if(U===";")K.body.push({type:"comment",value:G.substring(1)});else{let E=G.indexOf(":");if(E===-1)continue;let T=G.substring(0,E),q=G.substring(E+1).trim();if(N||T==="Format"){let Y=q.split(",");if(N&&Y.length>N.length){let B=Y.slice(N.length-1).join(",");Y=Y.slice(0,N.length-1),Y.push(B)}let L=Y.length;for(let B=0;B<L;B++)Y[B]=Y[B].trim();if(N){let B={},j=Math.min(N.length,L);for(let P=0;P<j;P++)B[N[P]]=Y[P];q=B}else q=Y}if(T==="Format")N=q;K.body.push({key:T,value:q})}}return Q}var XJ=/\\blur(?:[0-9]+\.)?[0-9]+/gm;function n(J){return J.replace(XJ,"")}var qJ=[{w:7680,h:4320},{w:3840,h:2160},{w:2560,h:1440},{w:1920,h:1080},{w:1280,h:720}];function YJ(J,Z){let Q=[...qJ].sort(($,O)=>$.w-O.w);for(let $ of Q)if(J<=$.w&&Z<=$.h)return $;return{w:Math.ceil(J/100)*100,h:Math.ceil(Z/100)*100}}function k(J,Z){return Z&&Z.includes(".")?J.toFixed(2).replace(/\.?0+$/,""):Math.round(J)}function i(J){let Z=J.match(/PlayResX:\s*(\d+)/i),Q=J.match(/PlayResY:\s*(\d+)/i),$=Z?parseInt(Z[1],10):1920,O=Q?parseInt(Q[1],10):1080,N=/\\pos\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,K=/\\move\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)/g,F=/\\org\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,G=/\\i?clip\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,U=0,E=0,T=(M,X,V)=>{let H,D=new RegExp(M.source,"g");while((H=D.exec(J))!==null){for(let A of X)if(H[A]){let C=Math.abs(parseFloat(H[A]));if(C>U)U=C}for(let A of V)if(H[A]){let C=Math.abs(parseFloat(H[A]));if(C>E)E=C}}};if(T(N,[1],[2]),T(K,[1,3],[2,4]),T(F,[1],[2]),T(G,[1,3],[2,4]),U<=$&&E<=O)return J;let q=YJ(U,E),Y=$/q.w,L=O/q.h,B=Math.min(Y,L),j=Math.max(Y,L),P=1,z=J,W=z.match(/(\[Events\][\s\S]*)/i);if(!W)return z;let _=W[1];return _=_.replace(N,(M,X,V)=>`\\pos(${k(parseFloat(X)*Y,X)},${k(parseFloat(V)*L,V)})`),_=_.replace(/\\move\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)(?:\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+))?\s*\)/g,(M,X,V,H,D,A,C)=>{let g=`\\move(${k(parseFloat(X)*Y,X)},${k(parseFloat(V)*L,V)},${k(parseFloat(H)*Y,H)},${k(parseFloat(D)*L,D)}`;return A?`${g},${A},${C})`:`${g})`}),_=_.replace(F,(M,X,V)=>`\\org(${k(parseFloat(X)*Y,X)},${k(parseFloat(V)*L,V)})`),_=_.replace(/\\(i?clip)\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,(M,X,V,H,D,A)=>`\\${X}(${k(parseFloat(V)*Y,V)},${k(parseFloat(H)*L,H)},${k(parseFloat(D)*Y,D)},${k(parseFloat(A)*L,A)})`),_=_.replace(/\\fs([\d.]+)/g,(M,X)=>`\\fs${k(parseFloat(X)*j,X)}`),_=_.replace(/\\fscx([\d.]+)/g,(M,X)=>`\\fscx${k(parseFloat(X)*P,X)}`),_=_.replace(/\\xbord([\d.]+)/g,(M,X)=>`\\xbord${k(parseFloat(X)*Y,X)}`),_=_.replace(/\\ybord([\d.]+)/g,(M,X)=>`\\ybord${k(parseFloat(X)*L,X)}`),_=_.replace(/\\xshad(-?[\d.]+)/g,(M,X)=>`\\xshad${k(parseFloat(X)*Y,X)}`),_=_.replace(/\\yshad(-?[\d.]+)/g,(M,X)=>`\\yshad${k(parseFloat(X)*L,X)}`),["fsp","bord","shad","be","blur"].forEach((M)=>{let X=new RegExp(`\\\\${M}(-?[\\d.]+)`,"g");_=_.replace(X,(V,H)=>`\\${M}${k(parseFloat(H)*B,H)}`)}),_=_.replace(/(\\i?clip\s*\([^,)]+m[^)]+\)|\\p[1-9][^}]*?)(?=[\\}]|$)/g,(M)=>{return M.replace(/(-?[\d.]+)\s+(-?[\d.]+)/g,(X,V,H)=>{return`${k(parseFloat(V)*Y,V)} ${k(parseFloat(H)*L,H)}`})}),z.substring(0,W.index)+_}var b=null,S=null;async function l(){if(b!==null&&S!==null)return{hasAlphaBug:b,hasBitmapBug:S};let J=document.createElement("canvas"),Z=J.getContext("2d",{willReadFrequently:!0});if(!Z)throw Error("Canvas rendering not supported");if(typeof ImageData.prototype.constructor==="function")try{new ImageData(new Uint8ClampedArray([0,0,0,0]),1,1)}catch{console.log("Detected that ImageData is not constructable despite browser saying so")}let Q=document.createElement("canvas"),$=Q.getContext("2d",{willReadFrequently:!0});if(!$)throw Error("Canvas rendering not supported");J.width=Q.width=1,J.height=Q.height=1,Z.clearRect(0,0,1,1),$.clearRect(0,0,1,1);let O=$.getImageData(0,0,1,1).data;Z.putImageData(new ImageData(new Uint8ClampedArray([0,255,0,0]),1,1),0,0),$.drawImage(J,0,0);let N=$.getImageData(0,0,1,1).data;if(b=O[1]!==N[1],b)console.log("Detected a browser having issue with transparent pixels, applying workaround");if(typeof createImageBitmap<"u"){let K=new Uint8ClampedArray([255,0,255,0,255]).subarray(1,5);$.drawImage(await createImageBitmap(new ImageData(K,1)),0,0);let{data:F}=$.getImageData(0,0,1,1);S=!1;for(let G=0;G<F.length;G++)if(Math.abs(K[G]-F[G])>15){S=!0,console.log("Detected a browser having issue with partial bitmaps, applying workaround");break}}else S=!1;return J.remove(),Q.remove(),{hasAlphaBug:b,hasBitmapBug:S}}async function a(){return l()}function t(){return b}function e(){return S}function f(){return typeof navigator<"u"&&"gpu"in navigator}function EJ(J){if(J instanceof ArrayBuffer)return new Uint8Array(J);return new Uint8Array(J.buffer,J.byteOffset,J.byteLength)}class v{device=null;context=null;pipeline=null;bindGroupLayout=null;uniformBuffer=null;imageDataBuffer=null;textureArray=null;textureArrayView=null;textureArraySize=0;textureArrayWidth=0;textureArrayHeight=0;pendingDestroyTextures=[];imageDataArray;resolutionArray=new Float32Array(2);conversionBuffer=null;conversionBufferSize=0;bindGroup=null;bindGroupDirty=!0;lastCanvasWidth=0;lastCanvasHeight=0;format="bgra8unorm";_canvas=null;_initPromise=null;_initialized=!1;constructor(){this.imageDataArray=new Float32Array(2048)}async init(){if(this._initPromise)return this._initPromise;return this._initPromise=this._initDevice(),this._initPromise}async _initDevice(){if(!navigator.gpu)throw Error("WebGPU not supported");let J=await navigator.gpu.requestAdapter({powerPreference:"high-performance"});if(!J)throw Error("No WebGPU adapter found");this.device=await J.requestDevice(),this.format=navigator.gpu.getPreferredCanvasFormat();let Z=this.device.createShaderModule({code:`
11
11
  struct VertexOutput {
12
12
  @builtin(position) position: vec4f,
13
13
  @location(0) @interpolate(flat) instanceIndex: u32,
@@ -62,7 +62,7 @@ fn vertexMain(
62
62
 
63
63
  return output;
64
64
  }
65
- `}),Z=this.device.createShaderModule({code:`
65
+ `}),Q=this.device.createShaderModule({code:`
66
66
  @group(0) @binding(2) var texArray: texture_2d_array<f32>;
67
67
 
68
68
  struct ImageData {
@@ -100,7 +100,7 @@ fn fragmentMain(input: FragmentInput) -> @location(0) vec4f {
100
100
  // Premultiplied alpha output
101
101
  return vec4f(color.rgb * color.a, color.a);
102
102
  }
103
- `});this.uniformBuffer=this.device.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.imageDataBuffer=this.device.createBuffer({size:8192,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),this.createTextureArray(256,256,32),this.bindGroupLayout=this.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"unfilterable-float",viewDimension:"2d-array"}}]});let N=this.device.createPipelineLayout({bindGroupLayouts:[this.bindGroupLayout]});this.pipeline=this.device.createRenderPipeline({layout:N,vertex:{module:K,entryPoint:"vertexMain"},fragment:{module:Z,entryPoint:"fragmentMain",targets:[{format:this.format,blend:{color:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list"}}),this._initialized=!0}nextPowerOf2(J){return J--,J|=J>>1,J|=J>>2,J|=J>>4,J|=J>>8,J|=J>>16,J+1}createTextureArray(J,K,Z){if(this.textureArray)this.pendingDestroyTextures.push(this.textureArray);let N=this.nextPowerOf2(Math.max(J,64)),Q=this.nextPowerOf2(Math.max(K,64)),F=Math.min(this.nextPowerOf2(Math.max(Z,16)),256);this.textureArray=this.device.createTexture({size:[N,Q,F],format:this.format,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),this.textureArrayView=this.textureArray.createView({dimension:"2d-array"}),this.textureArrayWidth=N,this.textureArrayHeight=Q,this.textureArraySize=F,this.bindGroupDirty=!0;let $=this.device.createCommandEncoder();for(let U=0;U<F;U++){let O=this.textureArray.createView({dimension:"2d",baseArrayLayer:U,arrayLayerCount:1});$.beginRenderPass({colorAttachments:[{view:O,clearValue:{r:0,g:0,b:0,a:0},loadOp:"clear",storeOp:"store"}]}).end()}this.device.queue.submit([$.finish()])}ensureTextureArray(J,K,Z){let N=Math.min(Z,256);if(J<=this.textureArrayWidth&&K<=this.textureArrayHeight&&N<=this.textureArraySize)return!1;let Q=this.nextPowerOf2(Math.max(this.textureArrayWidth,J)),F=this.nextPowerOf2(Math.max(this.textureArrayHeight,K)),$=Math.min(this.nextPowerOf2(Math.max(this.textureArraySize,N,N+16)),256);return this.createTextureArray(Q,F,$),!0}updateBindGroup(){if(!this.bindGroupDirty||!this.device||!this.bindGroupLayout)return;this.bindGroup=this.device.createBindGroup({layout:this.bindGroupLayout,entries:[{binding:0,resource:{buffer:this.uniformBuffer}},{binding:1,resource:{buffer:this.imageDataBuffer}},{binding:2,resource:this.textureArrayView}]}),this.bindGroupDirty=!1}ensureConversionBuffer(J){if(this.conversionBufferSize<J)this.conversionBufferSize=Math.max(J,this.conversionBufferSize*1.5|0,65536),this.conversionBuffer=new Uint8Array(this.conversionBufferSize);return this.conversionBuffer}async setCanvas(J,K,Z){if(await this.init(),!this.device)throw Error("WebGPU device not initialized");if(K<=0||Z<=0)return;if(this._canvas=J,J.width=K,J.height=Z,!this.context){if(this.context=J.getContext("webgpu"),!this.context)throw Error("Could not get WebGPU context");this.context.configure({device:this.device,format:this.format,alphaMode:"premultiplied"})}this.resolutionArray[0]=K,this.resolutionArray[1]=Z,this.device.queue.writeBuffer(this.uniformBuffer,0,this.resolutionArray),this.lastCanvasWidth=K,this.lastCanvasHeight=Z}updateSize(J,K){if(!this.device||!this._canvas||J<=0||K<=0)return;if(J===this.lastCanvasWidth&&K===this.lastCanvasHeight)return;this._canvas.width=J,this._canvas.height=K,this.resolutionArray[0]=J,this.resolutionArray[1]=K,this.device.queue.writeBuffer(this.uniformBuffer,0,this.resolutionArray),this.lastCanvasWidth=J,this.lastCanvasHeight=K}renderBitmaps(J,K,Z){if(!this.device||!this.context||!this.pipeline)return;let N=J.length;if(N===0){this.clear();return}let Q=this.context.getCurrentTexture();if(Q.width===0||Q.height===0)return;let F=0,$=0,U=0;for(let j=0;j<N;j++){let{image:P}=J[j],W=P.width,B=P.height;if(W>0&&B>0){if(W>F)F=W;if(B>$)$=B;U++}}if(U===0){this.clear();return}let O=Math.min(U,256);this.ensureTextureArray(F,$,O),this.updateBindGroup();let E=this.device,q=E.queue,L=this.textureArray,_=this.imageDataArray,Y=Q.createView(),T=0,z=!0;while(T<N){let j=0;while(T<N&&j<256){let B=J[T++],G=B.image,H=G.width,M=G.height;if(H<=0||M<=0)continue;q.copyExternalImageToTexture({source:G,flipY:!1},{texture:L,origin:[0,0,j],premultipliedAlpha:!1},{width:H,height:M});let X=j<<3;_[X]=B.x,_[X+1]=B.y,_[X+2]=H,_[X+3]=M,_[X+4]=H,_[X+5]=M,_[X+6]=j,_[X+7]=0,j++}if(j===0)continue;q.writeBuffer(this.imageDataBuffer,0,_.buffer,0,j<<5);let P=E.createCommandEncoder(),W=P.beginRenderPass({colorAttachments:[{view:Y,clearValue:{r:0,g:0,b:0,a:0},loadOp:z?"clear":"load",storeOp:"store"}]});W.setPipeline(this.pipeline),W.setBindGroup(0,this.bindGroup),W.draw(6,j),W.end(),q.submit([P.finish()]),z=!1}this.cleanupPendingTextures()}render(J,K,Z){if(!this.device||!this.context||!this.pipeline)return;let N=J.length;if(N===0){this.clear();return}let Q=this.context.getCurrentTexture();if(Q.width===0||Q.height===0)return;let F=0,$=0,U=0;for(let P=0;P<N;P++){let{w:W,h:B}=J[P];if(W>0&&B>0){if(W>F)F=W;if(B>$)$=B;U++}}if(U===0){this.clear();return}let O=Math.min(U,256);this.ensureTextureArray(F,$,O),this.updateBindGroup();let E=this.device,q=E.queue,L=this.textureArray,_=this.imageDataArray,Y=this.format==="bgra8unorm",T=Q.createView(),z=0,j=!0;while(z<N){let P=0;while(z<N&&P<256){let G=J[z++],H=G.w,M=G.h;if(H<=0||M<=0)continue;let X=G.image;if(X instanceof ImageBitmap)q.copyExternalImageToTexture({source:X,flipY:!1},{texture:L,origin:[0,0,P],premultipliedAlpha:!1},{width:H,height:M});else if(X instanceof ArrayBuffer)this.uploadTextureData(P,X,H,M,Y);let V=P<<3;_[V]=G.x,_[V+1]=G.y,_[V+2]=H,_[V+3]=M,_[V+4]=H,_[V+5]=M,_[V+6]=P,_[V+7]=0,P++}if(P===0)continue;q.writeBuffer(this.imageDataBuffer,0,_.buffer,0,P<<5);let W=E.createCommandEncoder(),B=W.beginRenderPass({colorAttachments:[{view:T,clearValue:{r:0,g:0,b:0,a:0},loadOp:j?"clear":"load",storeOp:"store"}]});B.setPipeline(this.pipeline),B.setBindGroup(0,this.bindGroup),B.draw(6,P),B.end(),q.submit([W.finish()]),j=!1}this.cleanupPendingTextures()}uploadTextureData(J,K,Z,N,Q){let F=Z*N*4;if(Q){let $=this.ensureConversionBuffer(F),U=new Uint8Array(K);for(let O=0;O<F;O+=4)$[O]=U[O+2],$[O+1]=U[O+1],$[O+2]=U[O],$[O+3]=U[O+3];this.device.queue.writeTexture({texture:this.textureArray,origin:[0,0,J]},$.buffer,{bytesPerRow:Z*4},{width:Z,height:N})}else this.device.queue.writeTexture({texture:this.textureArray,origin:[0,0,J]},K,{bytesPerRow:Z*4},{width:Z,height:N})}cleanupPendingTextures(){let J=this.pendingDestroyTextures,K=J.length;if(K===0)return;for(let Z=0;Z<K;Z++)J[Z].destroy();J.length=0}clear(){if(!this.device||!this.context)return;try{let J=this.context.getCurrentTexture();if(J.width===0||J.height===0)return;let K=this.device.createCommandEncoder();K.beginRenderPass({colorAttachments:[{view:J.createView(),clearValue:{r:0,g:0,b:0,a:0},loadOp:"clear",storeOp:"store"}]}).end(),this.device.queue.submit([K.finish()])}catch{}}get initialized(){return this._initialized}destroy(){this.cleanupPendingTextures(),this.textureArray?.destroy(),this.textureArray=null,this.textureArrayView=null,this.uniformBuffer?.destroy(),this.uniformBuffer=null,this.imageDataBuffer?.destroy(),this.imageDataBuffer=null,this.bindGroup=null,this.conversionBuffer=null,this.conversionBufferSize=0,this.device?.destroy(),this.device=null,this.context=null,this._canvas=null,this._initialized=!1,this._initPromise=null}}function p(){if(typeof document>"u")return!1;try{return document.createElement("canvas").getContext("webgl2")!==null}catch{return!1}}function JJ(J,K,Z){let N=J.createShader(K);if(J.shaderSource(N,Z),J.compileShader(N),!J.getShaderParameter(N,J.COMPILE_STATUS)){let Q=J.getShaderInfoLog(N);throw J.deleteShader(N),Error(`WebGL2 shader compilation failed: ${Q}`)}return N}class x{_gl=null;_canvas=null;_program=null;_vao=null;_instanceBuffer=null;_texArray=null;_texWidth=0;_texHeight=0;_texLayers=0;_resolutionLoc=null;_texArraySizeLoc=null;_instanceData;_lastCanvasWidth=0;_lastCanvasHeight=0;_initialized=!1;_initPromise=null;constructor(){this._instanceData=new Float32Array(2048)}async init(){if(this._initPromise)return this._initPromise;return this._initPromise=this._checkSupport(),this._initPromise}async _checkSupport(){if(typeof document>"u")throw Error("WebGL2 requires a DOM environment");if(!document.createElement("canvas").getContext("webgl2"))throw Error("WebGL2 not supported")}_initGL(){if(!this._canvas)throw Error("Canvas not set before _initGL");if(this._gl)return;let J=this._canvas.getContext("webgl2",{alpha:!0,premultipliedAlpha:!0,antialias:!1});if(!J)throw Error("Failed to create WebGL2 context");this._gl=J;let K=JJ(J,J.VERTEX_SHADER,`#version 300 es
103
+ `});this.uniformBuffer=this.device.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.imageDataBuffer=this.device.createBuffer({size:8192,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),this.createTextureArray(256,256,32),this.bindGroupLayout=this.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"unfilterable-float",viewDimension:"2d-array"}}]});let $=this.device.createPipelineLayout({bindGroupLayouts:[this.bindGroupLayout]});this.pipeline=this.device.createRenderPipeline({layout:$,vertex:{module:Z,entryPoint:"vertexMain"},fragment:{module:Q,entryPoint:"fragmentMain",targets:[{format:this.format,blend:{color:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list"}}),this._initialized=!0}nextPowerOf2(J){return J--,J|=J>>1,J|=J>>2,J|=J>>4,J|=J>>8,J|=J>>16,J+1}createTextureArray(J,Z,Q){if(this.textureArray)this.pendingDestroyTextures.push(this.textureArray);let $=this.nextPowerOf2(Math.max(J,64)),O=this.nextPowerOf2(Math.max(Z,64)),N=Math.min(this.nextPowerOf2(Math.max(Q,16)),256);this.textureArray=this.device.createTexture({size:[$,O,N],format:this.format,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),this.textureArrayView=this.textureArray.createView({dimension:"2d-array"}),this.textureArrayWidth=$,this.textureArrayHeight=O,this.textureArraySize=N,this.bindGroupDirty=!0;let K=this.device.createCommandEncoder();for(let F=0;F<N;F++){let G=this.textureArray.createView({dimension:"2d",baseArrayLayer:F,arrayLayerCount:1});K.beginRenderPass({colorAttachments:[{view:G,clearValue:{r:0,g:0,b:0,a:0},loadOp:"clear",storeOp:"store"}]}).end()}this.device.queue.submit([K.finish()])}ensureTextureArray(J,Z,Q){let $=Math.min(Q,256);if(J<=this.textureArrayWidth&&Z<=this.textureArrayHeight&&$<=this.textureArraySize)return!1;let O=this.nextPowerOf2(Math.max(this.textureArrayWidth,J)),N=this.nextPowerOf2(Math.max(this.textureArrayHeight,Z)),K=Math.min(this.nextPowerOf2(Math.max(this.textureArraySize,$,$+16)),256);return this.createTextureArray(O,N,K),!0}updateBindGroup(){if(!this.bindGroupDirty||!this.device||!this.bindGroupLayout)return;this.bindGroup=this.device.createBindGroup({layout:this.bindGroupLayout,entries:[{binding:0,resource:{buffer:this.uniformBuffer}},{binding:1,resource:{buffer:this.imageDataBuffer}},{binding:2,resource:this.textureArrayView}]}),this.bindGroupDirty=!1}ensureConversionBuffer(J){if(this.conversionBufferSize<J)this.conversionBufferSize=Math.max(J,this.conversionBufferSize*1.5|0,65536),this.conversionBuffer=new Uint8Array(this.conversionBufferSize);return this.conversionBuffer}async setCanvas(J,Z,Q){if(await this.init(),!this.device)throw Error("WebGPU device not initialized");if(Z<=0||Q<=0)return;if(this._canvas=J,J.width=Z,J.height=Q,!this.context){if(this.context=J.getContext("webgpu"),!this.context)throw Error("Could not get WebGPU context");this.context.configure({device:this.device,format:this.format,alphaMode:"premultiplied"})}this.resolutionArray[0]=Z,this.resolutionArray[1]=Q,this.device.queue.writeBuffer(this.uniformBuffer,0,this.resolutionArray),this.lastCanvasWidth=Z,this.lastCanvasHeight=Q}updateSize(J,Z){if(!this.device||!this._canvas||J<=0||Z<=0)return;if(J===this.lastCanvasWidth&&Z===this.lastCanvasHeight)return;this._canvas.width=J,this._canvas.height=Z,this.resolutionArray[0]=J,this.resolutionArray[1]=Z,this.device.queue.writeBuffer(this.uniformBuffer,0,this.resolutionArray),this.lastCanvasWidth=J,this.lastCanvasHeight=Z}renderBitmaps(J,Z,Q){if(!this.device||!this.context||!this.pipeline)return;let $=J.length;if($===0){this.clear();return}let O=this.context.getCurrentTexture();if(O.width===0||O.height===0)return;let N=0,K=0,F=0;for(let j=0;j<$;j++){let{image:P}=J[j],z=P.width,W=P.height;if(z>0&&W>0){if(z>N)N=z;if(W>K)K=W;F++}}if(F===0){this.clear();return}let G=Math.min(F,256);this.ensureTextureArray(N,K,G),this.updateBindGroup();let U=this.device,E=U.queue,T=this.textureArray,q=this.imageDataArray,Y=O.createView(),L=0,B=!0;while(L<$){let j=0;while(L<$&&j<256){let W=J[L++],_=W.image,I=_.width,M=_.height;if(I<=0||M<=0)continue;E.copyExternalImageToTexture({source:_,flipY:!1},{texture:T,origin:[0,0,j],premultipliedAlpha:!1},{width:I,height:M});let X=j<<3;q[X]=W.x,q[X+1]=W.y,q[X+2]=I,q[X+3]=M,q[X+4]=I,q[X+5]=M,q[X+6]=j,q[X+7]=0,j++}if(j===0)continue;E.writeBuffer(this.imageDataBuffer,0,q.buffer,0,j<<5);let P=U.createCommandEncoder(),z=P.beginRenderPass({colorAttachments:[{view:Y,clearValue:{r:0,g:0,b:0,a:0},loadOp:B?"clear":"load",storeOp:"store"}]});z.setPipeline(this.pipeline),z.setBindGroup(0,this.bindGroup),z.draw(6,j),z.end(),E.submit([P.finish()]),B=!1}this.cleanupPendingTextures()}render(J,Z,Q){if(!this.device||!this.context||!this.pipeline)return;let $=J.length;if($===0){this.clear();return}let O=this.context.getCurrentTexture();if(O.width===0||O.height===0)return;let N=0,K=0,F=0;for(let P=0;P<$;P++){let{w:z,h:W}=J[P];if(z>0&&W>0){if(z>N)N=z;if(W>K)K=W;F++}}if(F===0){this.clear();return}let G=Math.min(F,256);this.ensureTextureArray(N,K,G),this.updateBindGroup();let U=this.device,E=U.queue,T=this.textureArray,q=this.imageDataArray,Y=this.format==="bgra8unorm",L=O.createView(),B=0,j=!0;while(B<$){let P=0;while(B<$&&P<256){let _=J[B++],I=_.w,M=_.h;if(I<=0||M<=0)continue;let X=_.image;if(X instanceof ImageBitmap)E.copyExternalImageToTexture({source:X,flipY:!1},{texture:T,origin:[0,0,P],premultipliedAlpha:!1},{width:I,height:M});else if(X instanceof ArrayBuffer||X instanceof Uint8Array||X instanceof Uint8ClampedArray)this.uploadTextureData(P,X,I,M,Y);let V=P<<3;q[V]=_.x,q[V+1]=_.y,q[V+2]=I,q[V+3]=M,q[V+4]=I,q[V+5]=M,q[V+6]=P,q[V+7]=0,P++}if(P===0)continue;E.writeBuffer(this.imageDataBuffer,0,q.buffer,0,P<<5);let z=U.createCommandEncoder(),W=z.beginRenderPass({colorAttachments:[{view:L,clearValue:{r:0,g:0,b:0,a:0},loadOp:j?"clear":"load",storeOp:"store"}]});W.setPipeline(this.pipeline),W.setBindGroup(0,this.bindGroup),W.draw(6,P),W.end(),E.submit([z.finish()]),j=!1}this.cleanupPendingTextures()}uploadTextureData(J,Z,Q,$,O){let N=Q*$*4,K=EJ(Z);if(O){let F=this.ensureConversionBuffer(N);for(let G=0;G<N;G+=4)F[G]=K[G+2],F[G+1]=K[G+1],F[G+2]=K[G],F[G+3]=K[G+3];this.device.queue.writeTexture({texture:this.textureArray,origin:[0,0,J]},F.buffer,{bytesPerRow:Q*4},{width:Q,height:$})}else this.device.queue.writeTexture({texture:this.textureArray,origin:[0,0,J]},K,{bytesPerRow:Q*4},{width:Q,height:$})}cleanupPendingTextures(){let J=this.pendingDestroyTextures,Z=J.length;if(Z===0)return;for(let Q=0;Q<Z;Q++)J[Q].destroy();J.length=0}clear(){if(!this.device||!this.context)return;try{let J=this.context.getCurrentTexture();if(J.width===0||J.height===0)return;let Z=this.device.createCommandEncoder();Z.beginRenderPass({colorAttachments:[{view:J.createView(),clearValue:{r:0,g:0,b:0,a:0},loadOp:"clear",storeOp:"store"}]}).end(),this.device.queue.submit([Z.finish()])}catch{}}get initialized(){return this._initialized}destroy(){this.cleanupPendingTextures(),this.textureArray?.destroy(),this.textureArray=null,this.textureArrayView=null,this.uniformBuffer?.destroy(),this.uniformBuffer=null,this.imageDataBuffer?.destroy(),this.imageDataBuffer=null,this.bindGroup=null,this.conversionBuffer=null,this.conversionBufferSize=0,this.device?.destroy(),this.device=null,this.context=null,this._canvas=null,this._initialized=!1,this._initPromise=null}}function p(){if(typeof document>"u")return!1;try{return document.createElement("canvas").getContext("webgl2")!==null}catch{return!1}}function _J(J){return J instanceof Uint8Array||J instanceof Uint8ClampedArray}function JJ(J,Z,Q){let $=J.createShader(Z);if(J.shaderSource($,Q),J.compileShader($),!J.getShaderParameter($,J.COMPILE_STATUS)){let O=J.getShaderInfoLog($);throw J.deleteShader($),Error(`WebGL2 shader compilation failed: ${O}`)}return $}class x{_gl=null;_canvas=null;_program=null;_vao=null;_instanceBuffer=null;_texArray=null;_texWidth=0;_texHeight=0;_texLayers=0;_resolutionLoc=null;_texArraySizeLoc=null;_instanceData;_lastCanvasWidth=0;_lastCanvasHeight=0;_initialized=!1;_initPromise=null;constructor(){this._instanceData=new Float32Array(2048)}async init(){if(this._initPromise)return this._initPromise;return this._initPromise=this._checkSupport(),this._initPromise}async _checkSupport(){if(typeof document>"u")throw Error("WebGL2 requires a DOM environment");if(!document.createElement("canvas").getContext("webgl2"))throw Error("WebGL2 not supported")}_initGL(){if(!this._canvas)throw Error("Canvas not set before _initGL");if(this._gl)return;let J=this._canvas.getContext("webgl2",{alpha:!0,premultipliedAlpha:!0,antialias:!1});if(!J)throw Error("Failed to create WebGL2 context");this._gl=J;let Z=JJ(J,J.VERTEX_SHADER,`#version 300 es
104
104
  precision highp float;
105
105
 
106
106
  in vec4 a_destRect;
@@ -134,7 +134,7 @@ void main() {
134
134
  v_texIndex = int(a_texInfo.z);
135
135
  v_texSize = a_texInfo.xy;
136
136
  }
137
- `),Z=JJ(J,J.FRAGMENT_SHADER,`#version 300 es
137
+ `),Q=JJ(J,J.FRAGMENT_SHADER,`#version 300 es
138
138
  precision highp float;
139
139
  precision highp sampler2DArray;
140
140
 
@@ -153,7 +153,7 @@ void main() {
153
153
  // Premultiplied alpha output (matches WebGPU renderer behaviour)
154
154
  fragColor = vec4(color.rgb * color.a, color.a);
155
155
  }
156
- `),N=J.createProgram();if(J.attachShader(N,K),J.attachShader(N,Z),J.linkProgram(N),!J.getProgramParameter(N,J.LINK_STATUS))throw Error(`WebGL2 program link failed: ${J.getProgramInfoLog(N)}`);J.deleteShader(K),J.deleteShader(Z),this._program=N,this._resolutionLoc=J.getUniformLocation(N,"u_resolution"),this._texArraySizeLoc=J.getUniformLocation(N,"u_texArraySize"),this._vao=J.createVertexArray(),J.bindVertexArray(this._vao),this._instanceBuffer=J.createBuffer(),J.bindBuffer(J.ARRAY_BUFFER,this._instanceBuffer),J.bufferData(J.ARRAY_BUFFER,8192,J.DYNAMIC_DRAW);let Q=J.getAttribLocation(N,"a_destRect");J.enableVertexAttribArray(Q),J.vertexAttribPointer(Q,4,J.FLOAT,!1,32,0),J.vertexAttribDivisor(Q,1);let F=J.getAttribLocation(N,"a_texInfo");J.enableVertexAttribArray(F),J.vertexAttribPointer(F,4,J.FLOAT,!1,32,16),J.vertexAttribDivisor(F,1),J.bindVertexArray(null),this._texArray=J.createTexture(),this._allocateTextureArray(256,256,32),J.enable(J.BLEND),J.blendEquation(J.FUNC_ADD),J.blendFunc(J.ONE,J.ONE_MINUS_SRC_ALPHA),this._initialized=!0}_nextPow2(J){return J--,J|=J>>1,J|=J>>2,J|=J>>4,J|=J>>8,J|=J>>16,J+1}_allocateTextureArray(J,K,Z){let N=this._gl,Q=this._nextPow2(Math.max(J,64)),F=this._nextPow2(Math.max(K,64)),$=Math.min(this._nextPow2(Math.max(Z,16)),256);N.bindTexture(N.TEXTURE_2D_ARRAY,this._texArray),N.texImage3D(N.TEXTURE_2D_ARRAY,0,N.RGBA8,Q,F,$,0,N.RGBA,N.UNSIGNED_BYTE,null),N.texParameteri(N.TEXTURE_2D_ARRAY,N.TEXTURE_MIN_FILTER,N.NEAREST),N.texParameteri(N.TEXTURE_2D_ARRAY,N.TEXTURE_MAG_FILTER,N.NEAREST),N.texParameteri(N.TEXTURE_2D_ARRAY,N.TEXTURE_WRAP_S,N.CLAMP_TO_EDGE),N.texParameteri(N.TEXTURE_2D_ARRAY,N.TEXTURE_WRAP_T,N.CLAMP_TO_EDGE),this._texWidth=Q,this._texHeight=F,this._texLayers=$}_ensureTextureArray(J,K,Z){let N=Math.min(Z,256);if(J<=this._texWidth&&K<=this._texHeight&&N<=this._texLayers)return;let Q=this._nextPow2(Math.max(this._texWidth,J)),F=this._nextPow2(Math.max(this._texHeight,K)),$=Math.min(this._nextPow2(Math.max(this._texLayers,N,N+16)),256);this._allocateTextureArray(Q,F,$)}async setCanvas(J,K,Z){if(await this.init(),K<=0||Z<=0)return;this._canvas=J,J.width=K,J.height=Z,this._initGL(),this._gl.viewport(0,0,K,Z),this._lastCanvasWidth=K,this._lastCanvasHeight=Z}updateSize(J,K){if(!this._gl||!this._canvas||J<=0||K<=0)return;if(J===this._lastCanvasWidth&&K===this._lastCanvasHeight)return;this._canvas.width=J,this._canvas.height=K,this._gl.viewport(0,0,J,K),this._lastCanvasWidth=J,this._lastCanvasHeight=K}renderBitmaps(J,K,Z){if(!this._gl||!this._initialized)return;let N=J.length;if(N===0){this.clear();return}let Q=0,F=0;for(let E=0;E<N;E++){let{image:q}=J[E];if(q.width>Q)Q=q.width;if(q.height>F)F=q.height}this._ensureTextureArray(Q,F,Math.min(N,256));let $=this._gl;$.clearColor(0,0,0,0),$.clear($.COLOR_BUFFER_BIT),$.useProgram(this._program),$.uniform2f(this._resolutionLoc,this._lastCanvasWidth,this._lastCanvasHeight),$.uniform2i(this._texArraySizeLoc,this._texWidth,this._texHeight),$.activeTexture($.TEXTURE0),$.bindTexture($.TEXTURE_2D_ARRAY,this._texArray),$.pixelStorei($.UNPACK_FLIP_Y_WEBGL,!1);let U=this._instanceData,O=0;while(O<N){let E=0;while(O<N&&E<256){let q=J[O++],L=q.image.width,_=q.image.height;if(L<=0||_<=0)continue;$.texSubImage3D($.TEXTURE_2D_ARRAY,0,0,0,E,L,_,1,$.RGBA,$.UNSIGNED_BYTE,q.image);let Y=E<<3;U[Y]=q.x,U[Y+1]=q.y,U[Y+2]=L,U[Y+3]=_,U[Y+4]=L,U[Y+5]=_,U[Y+6]=E,U[Y+7]=0,E++}if(E===0)continue;$.bindBuffer($.ARRAY_BUFFER,this._instanceBuffer),$.bufferSubData($.ARRAY_BUFFER,0,U,0,E<<3),$.bindVertexArray(this._vao),$.drawArraysInstanced($.TRIANGLES,0,6,E),$.bindVertexArray(null)}}render(J,K,Z){if(!this._gl||!this._initialized)return;let N=J.length;if(N===0){this.clear();return}let Q=0,F=0;for(let E=0;E<N;E++){let{w:q,h:L}=J[E];if(q>Q)Q=q;if(L>F)F=L}this._ensureTextureArray(Q,F,Math.min(N,256));let $=this._gl;$.clearColor(0,0,0,0),$.clear($.COLOR_BUFFER_BIT),$.useProgram(this._program),$.uniform2f(this._resolutionLoc,this._lastCanvasWidth,this._lastCanvasHeight),$.uniform2i(this._texArraySizeLoc,this._texWidth,this._texHeight),$.activeTexture($.TEXTURE0),$.bindTexture($.TEXTURE_2D_ARRAY,this._texArray),$.pixelStorei($.UNPACK_FLIP_Y_WEBGL,!1);let U=this._instanceData,O=0;while(O<N){let E=0;while(O<N&&E<256){let q=J[O++],L=q.w,_=q.h;if(L<=0||_<=0)continue;let Y=q.image;if(Y instanceof ImageBitmap)$.texSubImage3D($.TEXTURE_2D_ARRAY,0,0,0,E,L,_,1,$.RGBA,$.UNSIGNED_BYTE,Y);else if(Y instanceof ArrayBuffer)$.texSubImage3D($.TEXTURE_2D_ARRAY,0,0,0,E,L,_,1,$.RGBA,$.UNSIGNED_BYTE,new Uint8Array(Y));let T=E<<3;U[T]=q.x,U[T+1]=q.y,U[T+2]=L,U[T+3]=_,U[T+4]=L,U[T+5]=_,U[T+6]=E,U[T+7]=0,E++}if(E===0)continue;$.bindBuffer($.ARRAY_BUFFER,this._instanceBuffer),$.bufferSubData($.ARRAY_BUFFER,0,U,0,E<<3),$.bindVertexArray(this._vao),$.drawArraysInstanced($.TRIANGLES,0,6,E),$.bindVertexArray(null)}}clear(){if(!this._gl)return;this._gl.clearColor(0,0,0,0),this._gl.clear(this._gl.COLOR_BUFFER_BIT)}get initialized(){return this._initialized}destroy(){let J=this._gl;if(J)J.deleteProgram(this._program),J.deleteVertexArray(this._vao),J.deleteBuffer(this._instanceBuffer),J.deleteTexture(this._texArray);this._gl=null,this._program=null,this._vao=null,this._instanceBuffer=null,this._texArray=null,this._canvas=null,this._initialized=!1,this._initPromise=null}}class R extends EventTarget{static MAX_PENDING_DEMANDS=3;static _hasAlphaBug=null;static _hasBitmapBug=null;_loaded;_init;_onDemandRender;_offscreenRender;_video;_videoWidth=0;_videoHeight=0;_videoColorSpace=null;_canvas;_canvasParent;_bufferCanvas;_bufferCtx;_canvasctrl;_ctx=null;_lastRenderTime=0;_playstate=!0;_destroyed=!1;_workerReady=!1;_ro;_worker;_pendingDemandTimes=[];_boundResize;_boundTimeUpdate;_boundSetRate;_boundUpdateColorSpace;_boundHandleRVFC;_gpuRenderer=null;_rendererType="canvas2d";_onCanvasFallback;_lastRenderWidth=0;_lastRenderHeight=0;timeOffset;debug;prescaleFactor;prescaleHeightLimit;maxRenderHeight;busy=!1;renderAhead;constructor(J){super();if(!globalThis.Worker)throw this.destroy(Error("Worker not supported"));if(!J)throw this.destroy(Error("No options provided"));this._loaded=new Promise((Q)=>{this._init=Q});let K=R._test();this._onDemandRender="requestVideoFrameCallback"in HTMLVideoElement.prototype&&(J.onDemandRender??!0),this._onCanvasFallback=J.onCanvasFallback;let Z=!J.canvas&&(f()||p());if(this._offscreenRender="transferControlToOffscreen"in HTMLCanvasElement.prototype&&!J.canvas&&!Z&&(J.offscreenRender??!0),this.timeOffset=J.timeOffset||0,this._video=J.video,this._canvas=J.canvas,this._video&&!this._canvas)this._canvasParent=document.createElement("div"),this._canvasParent.className="AkariSub",this._canvasParent.style.position="relative",this._canvas=this._createCanvas(),this._video.insertAdjacentElement("afterend",this._canvasParent);else if(!this._canvas)throw this.destroy(Error("Don't know where to render: you should give video or canvas in options."));this._bufferCanvas=document.createElement("canvas");let N=this._bufferCanvas.getContext("2d");if(!N)throw this.destroy(Error("Canvas rendering not supported"));if(this._bufferCtx=N,Z)this._initGPURenderer();else if(!this._offscreenRender)this._ctx=this._canvas.getContext("2d");if(this._canvasctrl=this._offscreenRender?this._canvas.transferControlToOffscreen():this._canvas,this._lastRenderTime=0,this.debug=!!J.debug,this.prescaleFactor=J.prescaleFactor||1,this.prescaleHeightLimit=J.prescaleHeightLimit||1080,this.maxRenderHeight=J.maxRenderHeight||0,this.renderAhead=J.renderAhead??0,this._boundResize=this.resize.bind(this),this._boundTimeUpdate=this._timeupdate.bind(this),this._boundSetRate=()=>this.setRate(this._video.playbackRate),this._boundUpdateColorSpace=this._updateColorSpace.bind(this),this._boundHandleRVFC=this._handleRVFC.bind(this),this._video)this.setVideo(this._video);if(this._onDemandRender)this.busy=!1,this._pendingDemandTimes.length=0;this._worker=new Worker(J.workerUrl||"akarisub-worker.js"),this._worker.onmessage=(Q)=>this._onmessage(Q),this._worker.onerror=(Q)=>this._error(Q),K.then(()=>{if(this._worker.postMessage({target:"init",wasmUrl:J.wasmUrl??"akarisub-worker.wasm",asyncRender:typeof createImageBitmap<"u"&&(J.asyncRender??!0),onDemandRender:this._onDemandRender,initialTime:(this._video?.currentTime??0)+this.timeOffset,width:this._canvasctrl.width||0,height:this._canvasctrl.height||0,blendMode:J.blendMode??"wasm",subUrl:J.subUrl,subContent:J.subContent||null,fonts:J.fonts||[],availableFonts:J.availableFonts||{"liberation sans":"./default.woff2"},fallbackFonts:J.fallbackFonts||["liberation sans"],debug:this.debug,targetFps:J.targetFps||24,dropAllAnimations:J.dropAllAnimations,dropAllBlur:J.dropAllBlur,clampPos:J.clampPos,libassMemoryLimit:J.libassMemoryLimit??128,libassGlyphLimit:J.libassGlyphLimit??2048,useLocalFonts:typeof globalThis.queryLocalFonts<"u"&&(J.useLocalFonts??!0),hasBitmapBug:R._hasBitmapBug}),this._offscreenRender)this.sendMessage("offscreenCanvas",{},[this._canvasctrl])})}static async _testImageBugs(){if(R._hasBitmapBug!==null)return;let J=document.createElement("canvas"),K=J.getContext("2d",{willReadFrequently:!0});if(!K)throw Error("Canvas rendering not supported");if(typeof ImageData.prototype.constructor==="function")try{new ImageData(new Uint8ClampedArray([0,0,0,0]),1,1)}catch{console.log("Detected that ImageData is not constructable despite browser saying so")}let Z=document.createElement("canvas"),N=Z.getContext("2d",{willReadFrequently:!0});if(!N)throw Error("Canvas rendering not supported");J.width=Z.width=1,J.height=Z.height=1,K.clearRect(0,0,1,1),N.clearRect(0,0,1,1);let Q=N.getImageData(0,0,1,1).data;K.putImageData(new ImageData(new Uint8ClampedArray([0,255,0,0]),1,1),0,0),N.drawImage(J,0,0);let F=N.getImageData(0,0,1,1).data;if(R._hasAlphaBug=Q[1]!==F[1],R._hasAlphaBug)console.log("Detected a browser having issue with transparent pixels, applying workaround");if(typeof createImageBitmap<"u"){let $=new Uint8ClampedArray([255,0,255,0,255]).subarray(1,5);N.drawImage(await createImageBitmap(new ImageData($,1)),0,0);let{data:U}=N.getImageData(0,0,1,1);R._hasBitmapBug=!1;for(let O=0;O<U.length;O++)if(Math.abs($[O]-U[O])>15){R._hasBitmapBug=!0,console.log("Detected a browser having issue with partial bitmaps, applying workaround");break}}else R._hasBitmapBug=!1;J.remove(),Z.remove()}static async _test(){await R._testImageBugs()}async _initGPURenderer(){if(f())try{let J=new v;if(await J.init(),!this._canvas)return;await J.setCanvas(this._canvas,Math.max(1,this._canvas.width||1),Math.max(1,this._canvas.height||1)),this._gpuRenderer=J,this._rendererType="webgpu",console.log("[AkariSub] Using WebGPU renderer");return}catch(J){console.warn("[AkariSub] WebGPU init failed, trying WebGL2:",J)}if(p())try{let J=new x;if(await J.init(),!this._canvas)return;await J.setCanvas(this._canvas,Math.max(1,this._canvas.width||1),Math.max(1,this._canvas.height||1)),this._gpuRenderer=J,this._rendererType="webgl2",console.log("[AkariSub] Using WebGL2 renderer");return}catch(J){console.warn("[AkariSub] WebGL2 init failed, falling back to Canvas2D:",J)}if(this._rendererType="canvas2d",!this._offscreenRender&&!this._ctx)this._ctx=this._canvas.getContext("2d");this.sendMessage("setAsyncRender",{value:!1}),this._onCanvasFallback?.()}get rendererType(){return this._rendererType}get isUsingWebGPU(){return this._rendererType==="webgpu"}get isUsingGPURenderer(){return this._gpuRenderer!==null}_createCanvas(){return this._canvas=document.createElement("canvas"),this._canvas.style.display="block",this._canvas.style.position="absolute",this._canvas.style.pointerEvents="none",this._canvasParent.appendChild(this._canvas),this._canvas}resize(J=0,K=0,Z=0,N=0,Q=this._video?.paused??!1){if((!J||!K)&&this._video){let F=c(this._video),$;if(this._videoWidth){let U=this._video.videoWidth/this._videoWidth,O=this._video.videoHeight/this._videoHeight;$=w((F.width||0)/U,(F.height||0)/O,this.prescaleFactor,this.prescaleHeightLimit,this.maxRenderHeight)}else $=w(F.width||0,F.height||0,this.prescaleFactor,this.prescaleHeightLimit,this.maxRenderHeight);if(J=$.width,K=$.height,this._canvasParent)Z=F.y-(this._canvasParent.getBoundingClientRect().top-this._video.getBoundingClientRect().top),N=F.x;this._canvas.style.width=F.width+"px",this._canvas.style.height=F.height+"px"}if(this._canvas.style.top=Z+"px",this._canvas.style.left=N+"px",J>0&&K>0)this._canvasctrl.width=J,this._canvasctrl.height=K;if(this._gpuRenderer&&J>0&&K>0)this._gpuRenderer.updateSize(J,K);if(Q&&this.busy===!1)this.busy=!0;else Q=!1;this.sendMessage("canvas",{width:J,height:K,videoWidth:this._videoWidth||this._video?.videoWidth||0,videoHeight:this._videoHeight||this._video?.videoHeight||0,force:Q})}_timeupdate(J){let Z={seeking:!0,waiting:!0,playing:!1}[J.type];if(Z!=null)this._playstate=Z;this.setCurrentTime(this._video.paused||this._playstate,this._video.currentTime+this.timeOffset)}setVideo(J){if(J instanceof HTMLVideoElement){if(this._removeListeners(),this._video=J,this._onDemandRender){if(!this._destroyed&&this._video===J)J.requestVideoFrameCallback(this._boundHandleRVFC)}else this._playstate=J.paused,J.addEventListener("timeupdate",this._boundTimeUpdate,!1),J.addEventListener("progress",this._boundTimeUpdate,!1),J.addEventListener("waiting",this._boundTimeUpdate,!1),J.addEventListener("seeking",this._boundTimeUpdate,!1),J.addEventListener("playing",this._boundTimeUpdate,!1),J.addEventListener("ratechange",this._boundSetRate,!1),J.addEventListener("resize",this._boundResize,!1);if("VideoFrame"in window){if(J.addEventListener("loadedmetadata",this._boundUpdateColorSpace,!1),J.readyState>2)this._updateColorSpace()}if(J.videoWidth>0)this.resize();if(typeof ResizeObserver<"u"){if(!this._ro)this._ro=new ResizeObserver(()=>this.resize());this._ro.observe(J)}}else this._error(Error("Video element invalid!"))}runBenchmark(){this.sendMessage("runBenchmark")}setTrackByUrl(J){if(this.sendMessage("setTrackByUrl",{url:J}),this._reAttachOffscreen(),this._ctx)this._ctx.filter="none"}setTrack(J){if(this.sendMessage("setTrack",{content:J}),this._reAttachOffscreen(),this._ctx)this._ctx.filter="none"}freeTrack(){this.sendMessage("freeTrack")}setIsPaused(J){this.sendMessage("video",{isPaused:J})}setRate(J){this.sendMessage("video",{rate:J})}setCurrentTime(J,K,Z){this.sendMessage("video",{isPaused:J,currentTime:K,rate:Z,colorSpace:this._videoColorSpace})}createEvent(J){this.sendMessage("createEvent",{event:J})}setEvent(J,K){this.sendMessage("setEvent",{event:J,index:K})}removeEvent(J){this.sendMessage("removeEvent",{index:J})}async getEvents(){return(await this._fetchFromWorker({target:"getEvents"})).events??[]}styleOverride(J){this.sendMessage("styleOverride",{style:J})}disableStyleOverride(){this.sendMessage("disableStyleOverride")}createStyle(J){this.sendMessage("createStyle",{style:J})}setStyle(J,K){this.sendMessage("setStyle",{style:J,index:K})}removeStyle(J){this.sendMessage("removeStyle",{index:J})}async getStyles(){return(await this._fetchFromWorker({target:"getStyles"})).styles??[]}addFont(J){this.sendMessage("addFont",{font:J})}setDefaultFont(J){this.sendMessage("defaultFont",{font:J})}async getStats(){let K=(await this._fetchFromWorker({target:"getStats"})).stats;return{framesRendered:K.framesRendered??0,framesDropped:K.framesDropped??0,avgRenderTime:K.avgRenderTime??0,maxRenderTime:K.maxRenderTime??0,minRenderTime:K.minRenderTime??0,lastRenderTime:K.lastRenderTime??0,pendingRenders:K.pendingRenders??0,totalEvents:K.totalEvents??0,cacheHits:K.cacheHits??0,cacheMisses:K.cacheMisses??0,renderFps:K.avgRenderTime&&K.avgRenderTime>0?Math.round(1000/K.avgRenderTime):0,usingWorker:!0,offscreenRender:this._offscreenRender,onDemandRender:this._onDemandRender}}async resetStats(){await this._fetchFromWorker({target:"resetStats"})}async getEventCount(){return(await this._fetchFromWorker({target:"getEventCount"})).count}async getStyleCount(){return(await this._fetchFromWorker({target:"getStyleCount"})).count}_sendLocalFont(J){try{globalThis.queryLocalFonts().then((K)=>{let Z=K?.find((N)=>N.fullName.toLowerCase()===J);if(Z)Z.blob().then((N)=>{N.arrayBuffer().then((Q)=>{this.addFont(new Uint8Array(Q))})})})}catch(K){console.warn("Local fonts API:",K)}}_getLocalFont(J){try{if(navigator?.permissions?.query)navigator.permissions.query({name:"local-fonts"}).then((K)=>{if(K.state==="granted")this._sendLocalFont(J.font)});else this._sendLocalFont(J.font)}catch(K){console.warn("Local fonts API:",K)}}_unbusy(){if(this._pendingDemandTimes.length>0){if(this._pendingDemandTimes.length>1){let K=this._pendingDemandTimes[this._pendingDemandTimes.length-1];this._pendingDemandTimes.length=0,this._pendingDemandTimes.push(K)}let J=this._pendingDemandTimes.shift();if(J){this._demandRender(J);return}}this.busy=!1}_enqueueDemand(J){let K=this._pendingDemandTimes;if(K.length>0){let Z=K[K.length-1];if(Math.abs(Z.mediaTime-J.mediaTime)>0.25)K.length=0}if(K.length>=R.MAX_PENDING_DEMANDS)K.shift();K.push(J)}_handleRVFC(J,K){if(this._destroyed)return;let Z=this._video?.playbackRate??1,Q={mediaTime:K.mediaTime+this.renderAhead*Z,width:K.width,height:K.height};if(!this._workerReady){this._enqueueDemand(Q),this._video.requestVideoFrameCallback(this._boundHandleRVFC);return}if(this.busy)this._enqueueDemand(Q);else this.busy=!0,this._demandRender(Q);this._video.requestVideoFrameCallback(this._boundHandleRVFC)}_demandRender(J){if(J.width!==this._videoWidth||J.height!==this._videoHeight)this._videoWidth=J.width,this._videoHeight=J.height,this.resize();this.sendMessage("demand",{time:J.mediaTime+this.timeOffset})}_detachOffscreen(){if(!this._offscreenRender||this._ctx)return;this._canvas.remove(),this._createCanvas(),this._canvasctrl=this._canvas,this._ctx=this._canvasctrl.getContext("2d"),this.sendMessage("detachOffscreen"),this.busy=!1,this._pendingDemandTimes.length=0,this.resize(0,0,0,0,!0)}_reAttachOffscreen(){if(!this._offscreenRender||!this._ctx)return;this._canvas.remove(),this._createCanvas(),this._canvasctrl=this._canvas.transferControlToOffscreen(),this._ctx=!1,this.sendMessage("offscreenCanvas",{},[this._canvasctrl]),this.resize(0,0,0,0,!0)}_updateColorSpace(){this._video.requestVideoFrameCallback(()=>{try{let J=new globalThis.VideoFrame(this._video);this._videoColorSpace=u[J.colorSpace.matrix]??null,J.close(),this.sendMessage("getColorSpace")}catch(J){console.warn(J)}})}_verifyColorSpace(J){let{subtitleColorSpace:K,videoColorSpace:Z=this._videoColorSpace}=J;if(!K||!Z)return;if(K===Z)return;this._detachOffscreen();let N=y[K]?.[Z];if(N&&this._ctx)this._ctx.filter=`url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix type='matrix' values='${N} 0 0 0 0 0 1 0'/></filter></svg>#f")`}_render(J){this._unbusy();let{width:K,height:Z}=J;if(this.debug)J.times.IPCTime=Date.now()-(J.times.JSRenderTime||0);if(this._canvasctrl.width!==K||this._canvasctrl.height!==Z){if(this._canvasctrl.width=K,this._canvasctrl.height=Z,this._lastRenderWidth=K,this._lastRenderHeight=Z,this._gpuRenderer)this._gpuRenderer.updateSize(K,Z);this._verifyColorSpace({subtitleColorSpace:J.colorSpace})}if(this._gpuRenderer){this._renderGPU(J);return}if(!this._ctx)return;let Q=this._ctx,F=J.images,$=F.length;if(Q.clearRect(0,0,K,Z),J.asyncRender)for(let U=0;U<$;U++){let O=F[U];if(O.image)Q.drawImage(O.image,O.x,O.y),O.image.close()}else{let U=R._hasAlphaBug??!1;for(let O=0;O<$;O++){let E=F[O];if(E.image){let{w:q,h:L}=E,_=new Uint8ClampedArray(E.image),Y=m(_,U);Q.putImageData(new ImageData(Y,q,L),E.x,E.y)}}}if(this.debug){J.times.JSRenderTime=Date.now()-(J.times.JSRenderTime||0)-(J.times.IPCTime||0);let U=0,O=J.times.bitmaps||$;delete J.times.bitmaps;for(let E in J.times)U+=J.times[E]||0;console.log("Bitmaps: "+O+" Total: "+(U|0)+"ms",J.times)}}_renderGPU(J){let K=this._gpuRenderer;if(!K)return;if(J.images.length===0){K.clear();return}if(J.asyncRender){let Z=J.images.filter((N)=>N.image instanceof ImageBitmap).map((N)=>({image:N.image,x:N.x,y:N.y}));K.renderBitmaps(Z,this._canvasctrl.width,this._canvasctrl.height);for(let N of J.images)if(N.image instanceof ImageBitmap)N.image.close()}else K.render(J.images,this._canvasctrl.width,this._canvasctrl.height);if(this.debug){J.times.JSRenderTime=Date.now()-(J.times.JSRenderTime||0)-(J.times.IPCTime||0);let Z=0,N=J.times.bitmaps||J.images.length;delete J.times.bitmaps;for(let Q in J.times)Z+=J.times[Q]||0;console.log(`[${this._rendererType.toUpperCase()}] Bitmaps: `+N+" Total: "+(Z|0)+"ms",J.times)}}_ready(){if(this._workerReady=!0,this._init(),this._onDemandRender&&this._video){this.setCurrentTime(this._video.paused,this._video.currentTime+this.timeOffset,this._video.playbackRate);let J=this._pendingDemandTimes.length>0?this._pendingDemandTimes[this._pendingDemandTimes.length-1]:{mediaTime:this._video.currentTime+this.renderAhead*(this._video.playbackRate||1),width:this._video.videoWidth,height:this._video.videoHeight};this._pendingDemandTimes.length=0,this.busy=!0,this._demandRender(J)}this.dispatchEvent(new CustomEvent("ready"))}_partial_ready(){this.dispatchEvent(new CustomEvent("partial_ready"))}async sendMessage(J,K={},Z){if(await this._loaded,Z)this._worker.postMessage({target:J,transferable:Z,...K},[...Z]);else this._worker.postMessage({target:J,...K})}_fetchFromWorker(J){return new Promise((K,Z)=>{try{let N=J.target,Q=setTimeout(()=>{U(),Z(Error("Error: Timeout while trying to fetch "+N))},5000),F=(O)=>{if(O.data.target===N)U(),K(O.data)},$=(O)=>{U(),Z(O instanceof Error?O:O.error||Error("Worker error"))},U=()=>{this._worker.removeEventListener("message",F),this._worker.removeEventListener("error",$),clearTimeout(Q)};this._worker.addEventListener("message",F),this._worker.addEventListener("error",$),this._worker.postMessage(J)}catch(N){Z(N)}})}_console(J){console[J.command].apply(console,JSON.parse(J.content))}_onmessage(J){let K=J.data.target;if(K==="error"){this._error(J.data.error||"Unknown worker error");return}let Z=this["_"+K];if(Z)Z.call(this,J.data)}_error(J){let K=J instanceof Error?J:J instanceof ErrorEvent?J.error||Error(J.message):Error(String(J)),Z=J instanceof Event?new ErrorEvent(J.type,J):new ErrorEvent("error",{error:K});return this.dispatchEvent(Z),console.error(K),K}_removeListeners(){if(this._video){if(this._ro)this._ro.unobserve(this._video);if(this._ctx)this._ctx.filter="none";this._video.removeEventListener("timeupdate",this._boundTimeUpdate),this._video.removeEventListener("progress",this._boundTimeUpdate),this._video.removeEventListener("waiting",this._boundTimeUpdate),this._video.removeEventListener("seeking",this._boundTimeUpdate),this._video.removeEventListener("playing",this._boundTimeUpdate),this._video.removeEventListener("ratechange",this._boundSetRate),this._video.removeEventListener("resize",this._boundResize),this._video.removeEventListener("loadedmetadata",this._boundUpdateColorSpace)}}destroy(J){let K=J?this._error(J):void 0;if(this._video&&this._canvasParent)this._video.parentNode?.removeChild(this._canvasParent);if(this._gpuRenderer)this._gpuRenderer.destroy(),this._gpuRenderer=null,this._rendererType="canvas2d";return this._destroyed=!0,this._removeListeners(),this.sendMessage("destroy"),this._worker?.terminate(),K}}})();
156
+ `),$=J.createProgram();if(J.attachShader($,Z),J.attachShader($,Q),J.linkProgram($),!J.getProgramParameter($,J.LINK_STATUS))throw Error(`WebGL2 program link failed: ${J.getProgramInfoLog($)}`);J.deleteShader(Z),J.deleteShader(Q),this._program=$,this._resolutionLoc=J.getUniformLocation($,"u_resolution"),this._texArraySizeLoc=J.getUniformLocation($,"u_texArraySize"),this._vao=J.createVertexArray(),J.bindVertexArray(this._vao),this._instanceBuffer=J.createBuffer(),J.bindBuffer(J.ARRAY_BUFFER,this._instanceBuffer),J.bufferData(J.ARRAY_BUFFER,8192,J.DYNAMIC_DRAW);let O=J.getAttribLocation($,"a_destRect");J.enableVertexAttribArray(O),J.vertexAttribPointer(O,4,J.FLOAT,!1,32,0),J.vertexAttribDivisor(O,1);let N=J.getAttribLocation($,"a_texInfo");J.enableVertexAttribArray(N),J.vertexAttribPointer(N,4,J.FLOAT,!1,32,16),J.vertexAttribDivisor(N,1),J.bindVertexArray(null),this._texArray=J.createTexture(),this._allocateTextureArray(256,256,32),J.enable(J.BLEND),J.blendEquation(J.FUNC_ADD),J.blendFunc(J.ONE,J.ONE_MINUS_SRC_ALPHA),this._initialized=!0}_nextPow2(J){return J--,J|=J>>1,J|=J>>2,J|=J>>4,J|=J>>8,J|=J>>16,J+1}_allocateTextureArray(J,Z,Q){let $=this._gl,O=this._nextPow2(Math.max(J,64)),N=this._nextPow2(Math.max(Z,64)),K=Math.min(this._nextPow2(Math.max(Q,16)),256);$.bindTexture($.TEXTURE_2D_ARRAY,this._texArray),$.texImage3D($.TEXTURE_2D_ARRAY,0,$.RGBA8,O,N,K,0,$.RGBA,$.UNSIGNED_BYTE,null),$.texParameteri($.TEXTURE_2D_ARRAY,$.TEXTURE_MIN_FILTER,$.NEAREST),$.texParameteri($.TEXTURE_2D_ARRAY,$.TEXTURE_MAG_FILTER,$.NEAREST),$.texParameteri($.TEXTURE_2D_ARRAY,$.TEXTURE_WRAP_S,$.CLAMP_TO_EDGE),$.texParameteri($.TEXTURE_2D_ARRAY,$.TEXTURE_WRAP_T,$.CLAMP_TO_EDGE),this._texWidth=O,this._texHeight=N,this._texLayers=K}_ensureTextureArray(J,Z,Q){let $=Math.min(Q,256);if(J<=this._texWidth&&Z<=this._texHeight&&$<=this._texLayers)return;let O=this._nextPow2(Math.max(this._texWidth,J)),N=this._nextPow2(Math.max(this._texHeight,Z)),K=Math.min(this._nextPow2(Math.max(this._texLayers,$,$+16)),256);this._allocateTextureArray(O,N,K)}async setCanvas(J,Z,Q){if(await this.init(),Z<=0||Q<=0)return;this._canvas=J,J.width=Z,J.height=Q,this._initGL(),this._gl.viewport(0,0,Z,Q),this._lastCanvasWidth=Z,this._lastCanvasHeight=Q}updateSize(J,Z){if(!this._gl||!this._canvas||J<=0||Z<=0)return;if(J===this._lastCanvasWidth&&Z===this._lastCanvasHeight)return;this._canvas.width=J,this._canvas.height=Z,this._gl.viewport(0,0,J,Z),this._lastCanvasWidth=J,this._lastCanvasHeight=Z}renderBitmaps(J,Z,Q){if(!this._gl||!this._initialized)return;let $=J.length;if($===0){this.clear();return}let O=0,N=0;for(let U=0;U<$;U++){let{image:E}=J[U];if(E.width>O)O=E.width;if(E.height>N)N=E.height}this._ensureTextureArray(O,N,Math.min($,256));let K=this._gl;K.clearColor(0,0,0,0),K.clear(K.COLOR_BUFFER_BIT),K.useProgram(this._program),K.uniform2f(this._resolutionLoc,this._lastCanvasWidth,this._lastCanvasHeight),K.uniform2i(this._texArraySizeLoc,this._texWidth,this._texHeight),K.activeTexture(K.TEXTURE0),K.bindTexture(K.TEXTURE_2D_ARRAY,this._texArray),K.pixelStorei(K.UNPACK_FLIP_Y_WEBGL,!1);let F=this._instanceData,G=0;while(G<$){let U=0;while(G<$&&U<256){let E=J[G++],T=E.image.width,q=E.image.height;if(T<=0||q<=0)continue;K.texSubImage3D(K.TEXTURE_2D_ARRAY,0,0,0,U,T,q,1,K.RGBA,K.UNSIGNED_BYTE,E.image);let Y=U<<3;F[Y]=E.x,F[Y+1]=E.y,F[Y+2]=T,F[Y+3]=q,F[Y+4]=T,F[Y+5]=q,F[Y+6]=U,F[Y+7]=0,U++}if(U===0)continue;K.bindBuffer(K.ARRAY_BUFFER,this._instanceBuffer),K.bufferSubData(K.ARRAY_BUFFER,0,F,0,U<<3),K.bindVertexArray(this._vao),K.drawArraysInstanced(K.TRIANGLES,0,6,U),K.bindVertexArray(null)}}render(J,Z,Q){if(!this._gl||!this._initialized)return;let $=J.length;if($===0){this.clear();return}let O=0,N=0;for(let U=0;U<$;U++){let{w:E,h:T}=J[U];if(E>O)O=E;if(T>N)N=T}this._ensureTextureArray(O,N,Math.min($,256));let K=this._gl;K.clearColor(0,0,0,0),K.clear(K.COLOR_BUFFER_BIT),K.useProgram(this._program),K.uniform2f(this._resolutionLoc,this._lastCanvasWidth,this._lastCanvasHeight),K.uniform2i(this._texArraySizeLoc,this._texWidth,this._texHeight),K.activeTexture(K.TEXTURE0),K.bindTexture(K.TEXTURE_2D_ARRAY,this._texArray),K.pixelStorei(K.UNPACK_FLIP_Y_WEBGL,!1);let F=this._instanceData,G=0;while(G<$){let U=0;while(G<$&&U<256){let E=J[G++],T=E.w,q=E.h;if(T<=0||q<=0)continue;let Y=E.image;if(Y instanceof ImageBitmap)K.texSubImage3D(K.TEXTURE_2D_ARRAY,0,0,0,U,T,q,1,K.RGBA,K.UNSIGNED_BYTE,Y);else if(Y instanceof ArrayBuffer||_J(Y)){let B=Y instanceof ArrayBuffer?new Uint8Array(Y):Y;K.texSubImage3D(K.TEXTURE_2D_ARRAY,0,0,0,U,T,q,1,K.RGBA,K.UNSIGNED_BYTE,B)}let L=U<<3;F[L]=E.x,F[L+1]=E.y,F[L+2]=T,F[L+3]=q,F[L+4]=T,F[L+5]=q,F[L+6]=U,F[L+7]=0,U++}if(U===0)continue;K.bindBuffer(K.ARRAY_BUFFER,this._instanceBuffer),K.bufferSubData(K.ARRAY_BUFFER,0,F,0,U<<3),K.bindVertexArray(this._vao),K.drawArraysInstanced(K.TRIANGLES,0,6,U),K.bindVertexArray(null)}}clear(){if(!this._gl)return;this._gl.clearColor(0,0,0,0),this._gl.clear(this._gl.COLOR_BUFFER_BIT)}get initialized(){return this._initialized}destroy(){let J=this._gl;if(J)J.deleteProgram(this._program),J.deleteVertexArray(this._vao),J.deleteBuffer(this._instanceBuffer),J.deleteTexture(this._texArray);this._gl=null,this._program=null,this._vao=null,this._instanceBuffer=null,this._texArray=null,this._canvas=null,this._initialized=!1,this._initPromise=null}}var ZJ=0.008,LJ=ZJ*1000,TJ=16,MJ=()=>{if(typeof navigator>"u")return!1;let J=navigator.userAgent||"",Z=navigator.vendor||"",Q=/\b(iPhone|iPad|iPod)\b/i.test(J);if(!/AppleWebKit/i.test(J))return!1;if(Q)return!0;if(/\b(Chrome|Chromium|Edg|OPR|SamsungBrowser|Firefox)\b/i.test(J))return!1;return Z.includes("Apple")};class R extends EventTarget{static MAX_PENDING_DEMANDS=3;static _hasAlphaBug=null;static _hasBitmapBug=null;_loaded;_init;_onDemandRender;_offscreenRender;_video;_videoWidth=0;_videoHeight=0;_videoColorSpace=null;_canvas;_canvasParent;_bufferCanvas;_bufferCtx;_canvasctrl;_ctx=null;_lastRenderTime=0;_playstate=!0;_destroyed=!1;_workerReady=!1;_ro;_worker;_pendingDemandTimes=[];_isLikelyWebKit;_activeDemandStartedAt=0;_smoothedDemandLatencyMs;_boundResize;_boundTimeUpdate;_boundSetRate;_boundUpdateColorSpace;_boundHandleRVFC;_gpuRenderer=null;_rendererType="canvas2d";_onCanvasFallback;_lastRenderWidth=0;_lastRenderHeight=0;_gpuBitmapImages=[];timeOffset;debug;prescaleFactor;prescaleHeightLimit;maxRenderHeight;busy=!1;renderAhead;constructor(J){super();if(!globalThis.Worker)throw this.destroy(Error("Worker not supported"));if(!J)throw this.destroy(Error("No options provided"));this._loaded=new Promise((N)=>{this._init=N}),this._isLikelyWebKit=MJ(),this._smoothedDemandLatencyMs=this._isLikelyWebKit?TJ:LJ;let Z=R._test();this._onDemandRender="requestVideoFrameCallback"in HTMLVideoElement.prototype&&(J.onDemandRender??!0),this._onCanvasFallback=J.onCanvasFallback;let Q=!this._isLikelyWebKit&&!J.canvas&&(f()||p()),$=typeof createImageBitmap<"u"&&(J.asyncRender??!this._isLikelyWebKit);if(this._offscreenRender="transferControlToOffscreen"in HTMLCanvasElement.prototype&&!J.canvas&&!Q&&(J.offscreenRender??!0),this.timeOffset=J.timeOffset||0,this._video=J.video,this._canvas=J.canvas,this._video&&!this._canvas)this._canvasParent=document.createElement("div"),this._canvasParent.className="AkariSub",this._canvasParent.style.position="relative",this._canvas=this._createCanvas(),this._video.insertAdjacentElement("afterend",this._canvasParent);else if(!this._canvas)throw this.destroy(Error("Don't know where to render: you should give video or canvas in options."));this._bufferCanvas=document.createElement("canvas");let O=this._bufferCanvas.getContext("2d");if(!O)throw this.destroy(Error("Canvas rendering not supported"));if(this._bufferCtx=O,Q)this._initGPURenderer();else if(!this._offscreenRender)this._ctx=this._canvas.getContext("2d",{alpha:!0,desynchronized:!0});if(this._canvasctrl=this._offscreenRender?this._canvas.transferControlToOffscreen():this._canvas,this._lastRenderTime=0,this.debug=!!J.debug,this.prescaleFactor=J.prescaleFactor||1,this.prescaleHeightLimit=J.prescaleHeightLimit||1080,this.maxRenderHeight=J.maxRenderHeight||0,this.renderAhead=J.renderAhead??ZJ,this._boundResize=this.resize.bind(this),this._boundTimeUpdate=this._timeupdate.bind(this),this._boundSetRate=()=>this.setRate(this._video.playbackRate),this._boundUpdateColorSpace=this._updateColorSpace.bind(this),this._boundHandleRVFC=this._handleRVFC.bind(this),this._video)this.setVideo(this._video);if(this._onDemandRender)this.busy=!1,this._pendingDemandTimes.length=0;this._worker=new Worker(J.workerUrl||"akarisub-worker.js"),this._worker.onmessage=(N)=>this._onmessage(N),this._worker.onerror=(N)=>this._error(N),Z.then(()=>{let N={target:"init",wasmUrl:J.wasmUrl??"akarisub-worker.wasm",asyncRender:$,fullTrackWarmup:J.fullTrackWarmup??!1,onDemandRender:this._onDemandRender,initialTime:(this._video?.currentTime??0)+this.timeOffset,width:this._canvasctrl.width||0,height:this._canvasctrl.height||0,blendMode:J.blendMode??"wasm",subUrl:J.subUrl,subContent:J.subContent||null,encryptedSubContent:J.encryptedSubContent||null,fonts:J.fonts||[],availableFonts:J.availableFonts||{"liberation sans":"./default.woff2"},fallbackFonts:J.fallbackFonts||["liberation sans"],debug:this.debug,targetFps:J.targetFps||24,dropAllAnimations:J.dropAllAnimations,dropAllBlur:J.dropAllBlur,clampPos:J.clampPos,libassMemoryLimit:J.libassMemoryLimit??128,libassGlyphLimit:J.libassGlyphLimit??2048,useLocalFonts:typeof globalThis.queryLocalFonts<"u"&&(J.useLocalFonts??!0),hasBitmapBug:R._hasBitmapBug};if(this._worker.postMessage(N,R._getSubtitleTransfers(J.subContent,J.encryptedSubContent)),this._offscreenRender)this.sendMessage("offscreenCanvas",{},[this._canvasctrl])})}static async _testImageBugs(){if(R._hasBitmapBug!==null)return;let J=document.createElement("canvas"),Z=J.getContext("2d",{willReadFrequently:!0});if(!Z)throw Error("Canvas rendering not supported");if(typeof ImageData.prototype.constructor==="function")try{new ImageData(new Uint8ClampedArray([0,0,0,0]),1,1)}catch{console.log("Detected that ImageData is not constructable despite browser saying so")}let Q=document.createElement("canvas"),$=Q.getContext("2d",{willReadFrequently:!0});if(!$)throw Error("Canvas rendering not supported");J.width=Q.width=1,J.height=Q.height=1,Z.clearRect(0,0,1,1),$.clearRect(0,0,1,1);let O=$.getImageData(0,0,1,1).data;Z.putImageData(new ImageData(new Uint8ClampedArray([0,255,0,0]),1,1),0,0),$.drawImage(J,0,0);let N=$.getImageData(0,0,1,1).data;if(R._hasAlphaBug=O[1]!==N[1],R._hasAlphaBug)console.log("Detected a browser having issue with transparent pixels, applying workaround");if(typeof createImageBitmap<"u"){let K=new Uint8ClampedArray([255,0,255,0,255]).subarray(1,5);$.drawImage(await createImageBitmap(new ImageData(K,1)),0,0);let{data:F}=$.getImageData(0,0,1,1);R._hasBitmapBug=!1;for(let G=0;G<F.length;G++)if(Math.abs(K[G]-F[G])>15){R._hasBitmapBug=!0,console.log("Detected a browser having issue with partial bitmaps, applying workaround");break}}else R._hasBitmapBug=!1;J.remove(),Q.remove()}static async _test(){await R._testImageBugs()}static _getSubtitleTransfers(J,Z){let Q=[];if(J instanceof ArrayBuffer)Q.push(J);else if(J instanceof Uint8Array)Q.push(J.buffer);if(Z?.encrypted)Q.push(Z.encrypted);for(let $ of Z?.encryptedChunks||[])Q.push($);return Q}async _initGPURenderer(){if(f())try{let J=new v;if(await J.init(),!this._canvas)return;await J.setCanvas(this._canvas,Math.max(1,this._canvas.width||1),Math.max(1,this._canvas.height||1)),this._gpuRenderer=J,this._rendererType="webgpu",console.log("[AkariSub] Using WebGPU renderer");return}catch(J){console.warn("[AkariSub] WebGPU init failed, trying WebGL2:",J)}if(p())try{let J=new x;if(await J.init(),!this._canvas)return;await J.setCanvas(this._canvas,Math.max(1,this._canvas.width||1),Math.max(1,this._canvas.height||1)),this._gpuRenderer=J,this._rendererType="webgl2",console.log("[AkariSub] Using WebGL2 renderer");return}catch(J){console.warn("[AkariSub] WebGL2 init failed, falling back to Canvas2D:",J)}if(this._rendererType="canvas2d",!this._offscreenRender&&!this._ctx)this._ctx=this._canvas.getContext("2d",{alpha:!0,desynchronized:!0});this.sendMessage("setAsyncRender",{value:!1}),this._onCanvasFallback?.()}get rendererType(){return this._rendererType}get isUsingWebGPU(){return this._rendererType==="webgpu"}get isUsingGPURenderer(){return this._gpuRenderer!==null}_createCanvas(){return this._canvas=document.createElement("canvas"),this._canvas.style.display="block",this._canvas.style.position="absolute",this._canvas.style.pointerEvents="none",this._canvasParent.appendChild(this._canvas),this._canvas}resize(J=0,Z=0,Q=0,$=0,O=this._video?.paused??!1){if((!J||!Z)&&this._video){let N=c(this._video),K;if(this._videoWidth){let F=this._video.videoWidth/this._videoWidth,G=this._video.videoHeight/this._videoHeight;K=w((N.width||0)/F,(N.height||0)/G,this.prescaleFactor,this.prescaleHeightLimit,this.maxRenderHeight)}else K=w(N.width||0,N.height||0,this.prescaleFactor,this.prescaleHeightLimit,this.maxRenderHeight);if(J=K.width,Z=K.height,this._canvasParent)Q=N.y-(this._canvasParent.getBoundingClientRect().top-this._video.getBoundingClientRect().top),$=N.x;this._canvas.style.width=N.width+"px",this._canvas.style.height=N.height+"px"}if(this._canvas.style.top=Q+"px",this._canvas.style.left=$+"px",J>0&&Z>0)this._canvasctrl.width=J,this._canvasctrl.height=Z;if(this._gpuRenderer&&J>0&&Z>0)this._gpuRenderer.updateSize(J,Z);if(O&&this.busy===!1)this.busy=!0;else O=!1;this.sendMessage("canvas",{width:J,height:Z,videoWidth:this._videoWidth||this._video?.videoWidth||0,videoHeight:this._videoHeight||this._video?.videoHeight||0,force:O})}_timeupdate(J){let Q={seeking:!0,waiting:!0,playing:!1}[J.type];if(Q!=null)this._playstate=Q;this.setCurrentTime(this._video.paused||this._playstate,this._video.currentTime+this.timeOffset)}setVideo(J){if(J instanceof HTMLVideoElement){if(this._removeListeners(),this._video=J,this._onDemandRender){if(!this._destroyed&&this._video===J)J.requestVideoFrameCallback(this._boundHandleRVFC)}else this._playstate=J.paused,J.addEventListener("timeupdate",this._boundTimeUpdate,!1),J.addEventListener("progress",this._boundTimeUpdate,!1),J.addEventListener("waiting",this._boundTimeUpdate,!1),J.addEventListener("seeking",this._boundTimeUpdate,!1),J.addEventListener("playing",this._boundTimeUpdate,!1),J.addEventListener("ratechange",this._boundSetRate,!1),J.addEventListener("resize",this._boundResize,!1);if("VideoFrame"in window){if(J.addEventListener("loadedmetadata",this._boundUpdateColorSpace,!1),J.readyState>2)this._updateColorSpace()}if(J.videoWidth>0)this.resize();if(typeof ResizeObserver<"u"){if(!this._ro)this._ro=new ResizeObserver(()=>this.resize());this._ro.observe(J)}}else this._error(Error("Video element invalid!"))}runBenchmark(){this.sendMessage("runBenchmark")}setTrackByUrl(J){if(this.sendMessage("setTrackByUrl",{url:J}),this._reAttachOffscreen(),this._ctx)this._ctx.filter="none"}setTrack(J){if(this.sendMessage("setTrack",{content:J},R._getSubtitleTransfers(J)),this._reAttachOffscreen(),this._ctx)this._ctx.filter="none"}setEncryptedTrack(J){if(this.sendMessage("setEncryptedTrack",{content:J},R._getSubtitleTransfers(void 0,J)),this._reAttachOffscreen(),this._ctx)this._ctx.filter="none"}freeTrack(){this.sendMessage("freeTrack")}setIsPaused(J){this.sendMessage("video",{isPaused:J})}setRate(J){this.sendMessage("video",{rate:J})}setCurrentTime(J,Z,Q){this.sendMessage("video",{isPaused:J,currentTime:Z,rate:Q,colorSpace:this._videoColorSpace})}createEvent(J){this.sendMessage("createEvent",{event:J})}setEvent(J,Z){this.sendMessage("setEvent",{event:J,index:Z})}removeEvent(J){this.sendMessage("removeEvent",{index:J})}async getEvents(){return(await this._fetchFromWorker({target:"getEvents"})).events??[]}styleOverride(J){this.sendMessage("styleOverride",{style:J})}disableStyleOverride(){this.sendMessage("disableStyleOverride")}createStyle(J){this.sendMessage("createStyle",{style:J})}setStyle(J,Z){this.sendMessage("setStyle",{style:J,index:Z})}removeStyle(J){this.sendMessage("removeStyle",{index:J})}async getStyles(){return(await this._fetchFromWorker({target:"getStyles"})).styles??[]}addFont(J){this.sendMessage("addFont",{font:J})}setDefaultFont(J){this.sendMessage("defaultFont",{font:J})}async getStats(){let Z=(await this._fetchFromWorker({target:"getStats"})).stats;return{framesRendered:Z.framesRendered??0,framesDropped:Z.framesDropped??0,avgRenderTime:Z.avgRenderTime??0,maxRenderTime:Z.maxRenderTime??0,minRenderTime:Z.minRenderTime??0,lastRenderTime:Z.lastRenderTime??0,pendingRenders:Z.pendingRenders??0,totalEvents:Z.totalEvents??0,cacheHits:Z.cacheHits??0,cacheMisses:Z.cacheMisses??0,renderFps:Z.avgRenderTime&&Z.avgRenderTime>0?Math.round(1000/Z.avgRenderTime):0,usingWorker:!0,offscreenRender:this._offscreenRender,onDemandRender:this._onDemandRender}}async resetStats(){await this._fetchFromWorker({target:"resetStats"})}async getEventCount(){return(await this._fetchFromWorker({target:"getEventCount"})).count}async getStyleCount(){return(await this._fetchFromWorker({target:"getStyleCount"})).count}_sendLocalFont(J){try{globalThis.queryLocalFonts().then((Z)=>{let Q=Z?.find(($)=>$.fullName.toLowerCase()===J);if(Q)Q.blob().then(($)=>{$.arrayBuffer().then((O)=>{this.addFont(new Uint8Array(O))})})})}catch(Z){console.warn("Local fonts API:",Z)}}_getLocalFont(J){try{if(navigator?.permissions?.query)navigator.permissions.query({name:"local-fonts"}).then((Z)=>{if(Z.state==="granted")this._sendLocalFont(J.font)});else this._sendLocalFont(J.font)}catch(Z){console.warn("Local fonts API:",Z)}}_unbusy(){if(this._observeDemandCompletion(),this._pendingDemandTimes.length>0){if(this._pendingDemandTimes.length>1){let Z=this._pendingDemandTimes[this._pendingDemandTimes.length-1];this._pendingDemandTimes.length=0,this._pendingDemandTimes.push(Z)}let J=this._pendingDemandTimes.shift();if(J){this._demandRender(J);return}}this.busy=!1}_markDemandDispatched(){if(!this._onDemandRender)return;this._activeDemandStartedAt=performance.now()}_observeDemandCompletion(){if(!this._onDemandRender||this._activeDemandStartedAt===0)return;let J=performance.now()-this._activeDemandStartedAt;if(this._activeDemandStartedAt=0,!Number.isFinite(J)||J<=0)return;this._smoothedDemandLatencyMs=this._smoothedDemandLatencyMs<=0?J:this._smoothedDemandLatencyMs*0.75+J*0.25}_getDemandPipelineLeadSeconds(J,Z){let Q=Z.expectedDisplayTime??Z.presentationTime??J,$=Math.max(0,Q-J)/1000;return Math.max(0,this._smoothedDemandLatencyMs/1000-$)}_enqueueDemand(J){let Z=this._pendingDemandTimes;if(Z.length>0){let Q=Z[Z.length-1];if(Math.abs(Q.mediaTime-J.mediaTime)>0.25)Z.length=0}if(Z.length>=R.MAX_PENDING_DEMANDS)Z.shift();Z.push(J)}_handleRVFC(J,Z){if(this._destroyed)return;let Q=this._video?.playbackRate??1,$=this._getDemandPipelineLeadSeconds(J,Z),N={mediaTime:Z.mediaTime+($+this.renderAhead)*Q,width:Z.width,height:Z.height};if(!this._workerReady){this._enqueueDemand(N),this._video.requestVideoFrameCallback(this._boundHandleRVFC);return}if(this.busy)this._enqueueDemand(N);else this.busy=!0,this._demandRender(N);this._video.requestVideoFrameCallback(this._boundHandleRVFC)}_demandRender(J){if(J.width!==this._videoWidth||J.height!==this._videoHeight)this._videoWidth=J.width,this._videoHeight=J.height,this.resize();this._markDemandDispatched(),this.sendMessage("demand",{time:J.mediaTime+this.timeOffset})}_detachOffscreen(){if(!this._offscreenRender||this._ctx)return;this._canvas.remove(),this._createCanvas(),this._canvasctrl=this._canvas,this._ctx=this._canvasctrl.getContext("2d",{alpha:!0,desynchronized:!0}),this.sendMessage("detachOffscreen"),this.busy=!1,this._activeDemandStartedAt=0,this._pendingDemandTimes.length=0,this.resize(0,0,0,0,!0)}_reAttachOffscreen(){if(!this._offscreenRender||!this._ctx)return;this._canvas.remove(),this._createCanvas(),this._canvasctrl=this._canvas.transferControlToOffscreen(),this._ctx=!1,this.sendMessage("offscreenCanvas",{},[this._canvasctrl]),this.resize(0,0,0,0,!0)}_updateColorSpace(){this._video.requestVideoFrameCallback(()=>{try{let J=new globalThis.VideoFrame(this._video);this._videoColorSpace=u[J.colorSpace.matrix]??null,J.close(),this.sendMessage("getColorSpace")}catch(J){console.warn(J)}})}_verifyColorSpace(J){let{subtitleColorSpace:Z,videoColorSpace:Q=this._videoColorSpace}=J;if(!Z||!Q)return;if(Z===Q)return;this._detachOffscreen();let $=y[Z]?.[Q];if($&&this._ctx)this._ctx.filter=`url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix type='matrix' values='${$} 0 0 0 0 0 1 0'/></filter></svg>#f")`}_render(J){try{let{width:Z,height:Q}=J;if(this.debug)J.times.IPCTime=Date.now()-(J.times.JSRenderTime||0);if(this._canvasctrl.width!==Z||this._canvasctrl.height!==Q){if(this._canvasctrl.width=Z,this._canvasctrl.height=Q,this._lastRenderWidth=Z,this._lastRenderHeight=Q,this._gpuRenderer)this._gpuRenderer.updateSize(Z,Q);this._verifyColorSpace({subtitleColorSpace:J.colorSpace})}if(this._gpuRenderer){this._renderGPU(J);return}if(!this._ctx)return;let O=this._ctx,N=J.images,K=N.length;if(O.clearRect(0,0,Z,Q),J.asyncRender)for(let F=0;F<K;F++){let G=N[F];if(G.image)O.drawImage(G.image,G.x,G.y),G.image.close()}else{let F=R._hasAlphaBug??!1;for(let G=0;G<K;G++){let U=N[G];if(U.image){let{w:E,h:T,image:q}=U,Y=q instanceof Uint8ClampedArray?q:q instanceof Uint8Array?new Uint8ClampedArray(q.buffer,q.byteOffset,q.byteLength):new Uint8ClampedArray(q),L=m(Y,F);O.putImageData(new ImageData(L,E,T),U.x,U.y)}}}if(this.debug){J.times.JSRenderTime=Date.now()-(J.times.JSRenderTime||0)-(J.times.IPCTime||0);let F=0,G=J.times.bitmaps||K;delete J.times.bitmaps;for(let U in J.times)F+=J.times[U]||0;console.log("Bitmaps: "+G+" Total: "+(F|0)+"ms",J.times)}}finally{this._unbusy()}}_renderGPU(J){let Z=this._gpuRenderer;if(!Z)return;if(J.images.length===0){Z.clear();return}if(J.asyncRender){let Q=this._gpuBitmapImages,$=0;for(let O=0;O<J.images.length;O++){let N=J.images[O];if(!(N.image instanceof ImageBitmap))continue;let K=Q[$]||(Q[$]={image:N.image,x:0,y:0});K.image=N.image,K.x=N.x,K.y=N.y,$++}Q.length=$,Z.renderBitmaps(Q,this._canvasctrl.width,this._canvasctrl.height);for(let O of J.images)if(O.image instanceof ImageBitmap)O.image.close()}else Z.render(J.images,this._canvasctrl.width,this._canvasctrl.height);if(this.debug){J.times.JSRenderTime=Date.now()-(J.times.JSRenderTime||0)-(J.times.IPCTime||0);let Q=0,$=J.times.bitmaps||J.images.length;delete J.times.bitmaps;for(let O in J.times)Q+=J.times[O]||0;console.log(`[${this._rendererType.toUpperCase()}] Bitmaps: `+$+" Total: "+(Q|0)+"ms",J.times)}}_ready(){if(this._workerReady=!0,this._init(),this._onDemandRender&&this._video){this.setCurrentTime(this._video.paused,this._video.currentTime+this.timeOffset,this._video.playbackRate);let J=this._pendingDemandTimes.length>0?this._pendingDemandTimes[this._pendingDemandTimes.length-1]:{mediaTime:this._video.currentTime+this.renderAhead*(this._video.playbackRate||1),width:this._video.videoWidth,height:this._video.videoHeight};this._pendingDemandTimes.length=0,this.busy=!0,this._demandRender(J)}this.dispatchEvent(new CustomEvent("ready"))}_partial_ready(){this.dispatchEvent(new CustomEvent("partial_ready"))}_trackReady(){this.dispatchEvent(new CustomEvent("trackReady"))}async sendMessage(J,Z={},Q){if(await this._loaded,Q)this._worker.postMessage({target:J,transferable:Q,...Z},[...Q]);else this._worker.postMessage({target:J,...Z})}_fetchFromWorker(J){return new Promise((Z,Q)=>{try{let $=J.target,O=setTimeout(()=>{F(),Q(Error("Error: Timeout while trying to fetch "+$))},5000),N=(G)=>{if(G.data.target===$)F(),Z(G.data)},K=(G)=>{F(),Q(G instanceof Error?G:G.error||Error("Worker error"))},F=()=>{this._worker.removeEventListener("message",N),this._worker.removeEventListener("error",K),clearTimeout(O)};this._worker.addEventListener("message",N),this._worker.addEventListener("error",K),this._worker.postMessage(J)}catch($){Q($)}})}_console(J){console[J.command].apply(console,JSON.parse(J.content))}_onmessage(J){let Z=J.data.target;if(Z==="error"){this._error(J.data.error||"Unknown worker error");return}let Q=this["_"+Z];if(Q)Q.call(this,J.data)}_error(J){let Z=J instanceof Error?J:J instanceof ErrorEvent?J.error||Error(J.message):Error(String(J)),Q=J instanceof Event?new ErrorEvent(J.type,J):new ErrorEvent("error",{error:Z});return this.dispatchEvent(Q),console.error(Z),Z}_removeListeners(){if(this._video){if(this._ro)this._ro.unobserve(this._video);if(this._ctx)this._ctx.filter="none";this._video.removeEventListener("timeupdate",this._boundTimeUpdate),this._video.removeEventListener("progress",this._boundTimeUpdate),this._video.removeEventListener("waiting",this._boundTimeUpdate),this._video.removeEventListener("seeking",this._boundTimeUpdate),this._video.removeEventListener("playing",this._boundTimeUpdate),this._video.removeEventListener("ratechange",this._boundSetRate),this._video.removeEventListener("resize",this._boundResize),this._video.removeEventListener("loadedmetadata",this._boundUpdateColorSpace)}}destroy(J){let Z=J?this._error(J):void 0;if(this._video&&this._canvasParent)this._video.parentNode?.removeChild(this._canvasParent);if(this._gpuRenderer)this._gpuRenderer.destroy(),this._gpuRenderer=null,this._rendererType="canvas2d";return this._destroyed=!0,this._removeListeners(),this.sendMessage("destroy"),this._worker?.terminate(),Z}}})();
157
157
 
158
158
  return AkariSub;
159
159
  }));
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- var u={bt709:"BT709",bt470bg:"BT601",smpte170m:"BT601"},y={BT601:{BT709:"1.0863 -0.0723 -0.014 0 0 0.0965 0.8451 0.0584 0 0 -0.0141 -0.0277 1.0418"},BT709:{BT601:"0.9137 0.0784 0.0079 0 0 -0.1049 1.1722 -0.0671 0 0 0.0096 0.0322 0.9582"},FCC:{BT709:"1.0873 -0.0736 -0.0137 0 0 0.0974 0.8494 0.0531 0 0 -0.0127 -0.0251 1.0378",BT601:"1.001 -0.0008 -0.0002 0 0 0.0009 1.005 -0.006 0 0 0.0013 0.0027 0.996"},SMPTE240M:{BT709:"0.9993 0.0006 0.0001 0 0 -0.0004 0.9812 0.0192 0 0 -0.0034 -0.0114 1.0148",BT601:"0.913 0.0774 0.0096 0 0 -0.1051 1.1508 -0.0456 0 0 0.0063 0.0207 0.973"}},g=[null,"BT601",null,"BT601","BT601","BT709","BT709","SMPTE240M","SMPTE240M","FCC","FCC"];function s(J,K){if(!J||!K)return null;if(J===K)return null;let Z=y[J]?.[K];if(!Z)return null;return`url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix type='matrix' values='${Z} 0 0 0 0 0 1 0'/></filter></svg>#f")`}function w(J,K,Z,N,Q){let F=Z<=0?1:Z,$=globalThis.devicePixelRatio||1;if(K<=0||J<=0)return{width:0,height:0};let U=F<1?-1:1,O=K*$;if(U*O*F<=U*N)O*=F;else if(U*O<U*N)O=N;if(Q>0&&O>Q)O=Q;return J*=O/K,K=O,{width:J,height:K}}function c(J,K=J.videoWidth,Z=J.videoHeight){let N=K/Z,{offsetWidth:Q,offsetHeight:F}=J,$=Q/F,U=Q,O=F;if($>N)U=Math.floor(F*N);else O=Math.floor(Q/N);let E=(Q-U)/2,q=(F-O)/2;return{width:U,height:O,x:E,y:q}}function m(J,K){if(!K)return J;let Z=J.length,N=Z-Z%16,Q=3;for(;Q<N;Q+=16){if(J[Q]<2)J[Q]=1;if(J[Q+4]<2)J[Q+4]=1;if(J[Q+8]<2)J[Q+8]=1;if(J[Q+12]<2)J[Q+12]=1}for(;Q<Z;Q+=4)if(J[Q]<2)J[Q]=1;return J}function o(J,K=!1){let Z=[],N=J.split(/[\r\n]+/g),Q=N.length,F=null,$=null;for(let U=0;U<Q;U++){let O=N[U];if(!O||/^\s*$/.test(O))continue;let E=O[0];if(E==="["){let q=O.match(/^\[(.*)\]$/);if(q){if(K&&q[1].toLowerCase()==="events")break;F=null,$={name:q[1],body:[]},Z.push($);continue}}if(!$)continue;if(E===";")$.body.push({type:"comment",value:O.substring(1)});else{let q=O.indexOf(":");if(q===-1)continue;let L=O.substring(0,q),_=O.substring(q+1).trim();if(F||L==="Format"){let Y=_.split(",");if(F&&Y.length>F.length){let z=Y.slice(F.length-1).join(",");Y=Y.slice(0,F.length-1),Y.push(z)}let T=Y.length;for(let z=0;z<T;z++)Y[z]=Y[z].trim();if(F){let z={},j=Math.min(F.length,T);for(let P=0;P<j;P++)z[F[P]]=Y[P];_=z}else _=Y}if(L==="Format")F=_;$.body.push({key:L,value:_})}}return Z}var r=/\\blur(?:[0-9]+\.)?[0-9]+/gm;function n(J){return J.replace(r,"")}var i=[{w:7680,h:4320},{w:3840,h:2160},{w:2560,h:1440},{w:1920,h:1080},{w:1280,h:720}];function a(J,K){let Z=[...i].sort((N,Q)=>N.w-Q.w);for(let N of Z)if(J<=N.w&&K<=N.h)return N;return{w:Math.ceil(J/100)*100,h:Math.ceil(K/100)*100}}function k(J,K){return K&&K.includes(".")?J.toFixed(2).replace(/\.?0+$/,""):Math.round(J)}function t(J){let K=J.match(/PlayResX:\s*(\d+)/i),Z=J.match(/PlayResY:\s*(\d+)/i),N=K?parseInt(K[1],10):1920,Q=Z?parseInt(Z[1],10):1080,F=/\\pos\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,$=/\\move\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)/g,U=/\\org\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,O=/\\i?clip\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,E=0,q=0,L=(M,X,V)=>{let I,D=new RegExp(M.source,"g");while((I=D.exec(J))!==null){for(let C of X)if(I[C]){let A=Math.abs(parseFloat(I[C]));if(A>E)E=A}for(let C of V)if(I[C]){let A=Math.abs(parseFloat(I[C]));if(A>q)q=A}}};if(L(F,[1],[2]),L($,[1,3],[2,4]),L(U,[1],[2]),L(O,[1,3],[2,4]),E<=N&&q<=Q)return J;let _=a(E,q),Y=N/_.w,T=Q/_.h,z=Math.min(Y,T),j=Math.max(Y,T),P=1,W=J,B=W.match(/(\[Events\][\s\S]*)/i);if(!B)return W;let G=B[1];return G=G.replace(F,(M,X,V)=>`\\pos(${k(parseFloat(X)*Y,X)},${k(parseFloat(V)*T,V)})`),G=G.replace(/\\move\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)(?:\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+))?\s*\)/g,(M,X,V,I,D,C,A)=>{let h=`\\move(${k(parseFloat(X)*Y,X)},${k(parseFloat(V)*T,V)},${k(parseFloat(I)*Y,I)},${k(parseFloat(D)*T,D)}`;return C?`${h},${C},${A})`:`${h})`}),G=G.replace(U,(M,X,V)=>`\\org(${k(parseFloat(X)*Y,X)},${k(parseFloat(V)*T,V)})`),G=G.replace(/\\(i?clip)\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,(M,X,V,I,D,C)=>`\\${X}(${k(parseFloat(V)*Y,V)},${k(parseFloat(I)*T,I)},${k(parseFloat(D)*Y,D)},${k(parseFloat(C)*T,C)})`),G=G.replace(/\\fs([\d.]+)/g,(M,X)=>`\\fs${k(parseFloat(X)*j,X)}`),G=G.replace(/\\fscx([\d.]+)/g,(M,X)=>`\\fscx${k(parseFloat(X)*P,X)}`),G=G.replace(/\\xbord([\d.]+)/g,(M,X)=>`\\xbord${k(parseFloat(X)*Y,X)}`),G=G.replace(/\\ybord([\d.]+)/g,(M,X)=>`\\ybord${k(parseFloat(X)*T,X)}`),G=G.replace(/\\xshad(-?[\d.]+)/g,(M,X)=>`\\xshad${k(parseFloat(X)*Y,X)}`),G=G.replace(/\\yshad(-?[\d.]+)/g,(M,X)=>`\\yshad${k(parseFloat(X)*T,X)}`),["fsp","bord","shad","be","blur"].forEach((M)=>{let X=new RegExp(`\\\\${M}(-?[\\d.]+)`,"g");G=G.replace(X,(V,I)=>`\\${M}${k(parseFloat(I)*z,I)}`)}),G=G.replace(/(\\i?clip\s*\([^,)]+m[^)]+\)|\\p[1-9][^}]*?)(?=[\\}]|$)/g,(M)=>{return M.replace(/(-?[\d.]+)\s+(-?[\d.]+)/g,(X,V,I)=>{return`${k(parseFloat(V)*Y,V)} ${k(parseFloat(I)*T,I)}`})}),W.substring(0,B.index)+G}var b=null,S=null;async function l(){if(b!==null&&S!==null)return{hasAlphaBug:b,hasBitmapBug:S};let J=document.createElement("canvas"),K=J.getContext("2d",{willReadFrequently:!0});if(!K)throw Error("Canvas rendering not supported");if(typeof ImageData.prototype.constructor==="function")try{new ImageData(new Uint8ClampedArray([0,0,0,0]),1,1)}catch{console.log("Detected that ImageData is not constructable despite browser saying so")}let Z=document.createElement("canvas"),N=Z.getContext("2d",{willReadFrequently:!0});if(!N)throw Error("Canvas rendering not supported");J.width=Z.width=1,J.height=Z.height=1,K.clearRect(0,0,1,1),N.clearRect(0,0,1,1);let Q=N.getImageData(0,0,1,1).data;K.putImageData(new ImageData(new Uint8ClampedArray([0,255,0,0]),1,1),0,0),N.drawImage(J,0,0);let F=N.getImageData(0,0,1,1).data;if(b=Q[1]!==F[1],b)console.log("Detected a browser having issue with transparent pixels, applying workaround");if(typeof createImageBitmap<"u"){let $=new Uint8ClampedArray([255,0,255,0,255]).subarray(1,5);N.drawImage(await createImageBitmap(new ImageData($,1)),0,0);let{data:U}=N.getImageData(0,0,1,1);S=!1;for(let O=0;O<U.length;O++)if(Math.abs($[O]-U[O])>15){S=!0,console.log("Detected a browser having issue with partial bitmaps, applying workaround");break}}else S=!1;return J.remove(),Z.remove(),{hasAlphaBug:b,hasBitmapBug:S}}async function e(){return l()}function JJ(){return b}function KJ(){return S}function f(){return typeof navigator<"u"&&"gpu"in navigator}class v{device=null;context=null;pipeline=null;bindGroupLayout=null;uniformBuffer=null;imageDataBuffer=null;textureArray=null;textureArrayView=null;textureArraySize=0;textureArrayWidth=0;textureArrayHeight=0;pendingDestroyTextures=[];imageDataArray;resolutionArray=new Float32Array(2);conversionBuffer=null;conversionBufferSize=0;bindGroup=null;bindGroupDirty=!0;lastCanvasWidth=0;lastCanvasHeight=0;format="bgra8unorm";_canvas=null;_initPromise=null;_initialized=!1;constructor(){this.imageDataArray=new Float32Array(2048)}async init(){if(this._initPromise)return this._initPromise;return this._initPromise=this._initDevice(),this._initPromise}async _initDevice(){if(!navigator.gpu)throw Error("WebGPU not supported");let J=await navigator.gpu.requestAdapter({powerPreference:"high-performance"});if(!J)throw Error("No WebGPU adapter found");this.device=await J.requestDevice(),this.format=navigator.gpu.getPreferredCanvasFormat();let K=this.device.createShaderModule({code:`
1
+ var u={bt709:"BT709",bt470bg:"BT601",smpte170m:"BT601"},y={BT601:{BT709:"1.0863 -0.0723 -0.014 0 0 0.0965 0.8451 0.0584 0 0 -0.0141 -0.0277 1.0418"},BT709:{BT601:"0.9137 0.0784 0.0079 0 0 -0.1049 1.1722 -0.0671 0 0 0.0096 0.0322 0.9582"},FCC:{BT709:"1.0873 -0.0736 -0.0137 0 0 0.0974 0.8494 0.0531 0 0 -0.0127 -0.0251 1.0378",BT601:"1.001 -0.0008 -0.0002 0 0 0.0009 1.005 -0.006 0 0 0.0013 0.0027 0.996"},SMPTE240M:{BT709:"0.9993 0.0006 0.0001 0 0 -0.0004 0.9812 0.0192 0 0 -0.0034 -0.0114 1.0148",BT601:"0.913 0.0774 0.0096 0 0 -0.1051 1.1508 -0.0456 0 0 0.0063 0.0207 0.973"}},s=[null,"BT601",null,"BT601","BT601","BT709","BT709","SMPTE240M","SMPTE240M","FCC","FCC"];function r(J,Z){if(!J||!Z)return null;if(J===Z)return null;let Q=y[J]?.[Z];if(!Q)return null;return`url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix type='matrix' values='${Q} 0 0 0 0 0 1 0'/></filter></svg>#f")`}function w(J,Z,Q,$,O){let N=Q<=0?1:Q,K=globalThis.devicePixelRatio||1;if(Z<=0||J<=0)return{width:0,height:0};let F=N<1?-1:1,G=Z*K;if(F*G*N<=F*$)G*=N;else if(F*G<F*$)G=$;if(O>0&&G>O)G=O;return J*=G/Z,Z=G,{width:J,height:Z}}function c(J,Z=J.videoWidth,Q=J.videoHeight){let $=Z/Q,{offsetWidth:O,offsetHeight:N}=J,K=O/N,F=O,G=N;if(K>$)F=Math.floor(N*$);else G=Math.floor(O/$);let U=(O-F)/2,E=(N-G)/2;return{width:F,height:G,x:U,y:E}}function m(J,Z){if(!Z)return J;let Q=J.length,$=Q-Q%16,O=3;for(;O<$;O+=16){if(J[O]<2)J[O]=1;if(J[O+4]<2)J[O+4]=1;if(J[O+8]<2)J[O+8]=1;if(J[O+12]<2)J[O+12]=1}for(;O<Q;O+=4)if(J[O]<2)J[O]=1;return J}function o(J,Z=!1){let Q=[],$=J.split(/[\r\n]+/g),O=$.length,N=null,K=null;for(let F=0;F<O;F++){let G=$[F];if(!G||/^\s*$/.test(G))continue;let U=G[0];if(U==="["){let E=G.match(/^\[(.*)\]$/);if(E){if(Z&&E[1].toLowerCase()==="events")break;N=null,K={name:E[1],body:[]},Q.push(K);continue}}if(!K)continue;if(U===";")K.body.push({type:"comment",value:G.substring(1)});else{let E=G.indexOf(":");if(E===-1)continue;let T=G.substring(0,E),q=G.substring(E+1).trim();if(N||T==="Format"){let Y=q.split(",");if(N&&Y.length>N.length){let B=Y.slice(N.length-1).join(",");Y=Y.slice(0,N.length-1),Y.push(B)}let L=Y.length;for(let B=0;B<L;B++)Y[B]=Y[B].trim();if(N){let B={},j=Math.min(N.length,L);for(let P=0;P<j;P++)B[N[P]]=Y[P];q=B}else q=Y}if(T==="Format")N=q;K.body.push({key:T,value:q})}}return Q}var n=/\\blur(?:[0-9]+\.)?[0-9]+/gm;function i(J){return J.replace(n,"")}var a=[{w:7680,h:4320},{w:3840,h:2160},{w:2560,h:1440},{w:1920,h:1080},{w:1280,h:720}];function t(J,Z){let Q=[...a].sort(($,O)=>$.w-O.w);for(let $ of Q)if(J<=$.w&&Z<=$.h)return $;return{w:Math.ceil(J/100)*100,h:Math.ceil(Z/100)*100}}function k(J,Z){return Z&&Z.includes(".")?J.toFixed(2).replace(/\.?0+$/,""):Math.round(J)}function e(J){let Z=J.match(/PlayResX:\s*(\d+)/i),Q=J.match(/PlayResY:\s*(\d+)/i),$=Z?parseInt(Z[1],10):1920,O=Q?parseInt(Q[1],10):1080,N=/\\pos\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,K=/\\move\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)/g,F=/\\org\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,G=/\\i?clip\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,U=0,E=0,T=(M,X,V)=>{let H,D=new RegExp(M.source,"g");while((H=D.exec(J))!==null){for(let A of X)if(H[A]){let C=Math.abs(parseFloat(H[A]));if(C>U)U=C}for(let A of V)if(H[A]){let C=Math.abs(parseFloat(H[A]));if(C>E)E=C}}};if(T(N,[1],[2]),T(K,[1,3],[2,4]),T(F,[1],[2]),T(G,[1,3],[2,4]),U<=$&&E<=O)return J;let q=t(U,E),Y=$/q.w,L=O/q.h,B=Math.min(Y,L),j=Math.max(Y,L),P=1,z=J,W=z.match(/(\[Events\][\s\S]*)/i);if(!W)return z;let _=W[1];return _=_.replace(N,(M,X,V)=>`\\pos(${k(parseFloat(X)*Y,X)},${k(parseFloat(V)*L,V)})`),_=_.replace(/\\move\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)(?:\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+))?\s*\)/g,(M,X,V,H,D,A,C)=>{let h=`\\move(${k(parseFloat(X)*Y,X)},${k(parseFloat(V)*L,V)},${k(parseFloat(H)*Y,H)},${k(parseFloat(D)*L,D)}`;return A?`${h},${A},${C})`:`${h})`}),_=_.replace(F,(M,X,V)=>`\\org(${k(parseFloat(X)*Y,X)},${k(parseFloat(V)*L,V)})`),_=_.replace(/\\(i?clip)\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,(M,X,V,H,D,A)=>`\\${X}(${k(parseFloat(V)*Y,V)},${k(parseFloat(H)*L,H)},${k(parseFloat(D)*Y,D)},${k(parseFloat(A)*L,A)})`),_=_.replace(/\\fs([\d.]+)/g,(M,X)=>`\\fs${k(parseFloat(X)*j,X)}`),_=_.replace(/\\fscx([\d.]+)/g,(M,X)=>`\\fscx${k(parseFloat(X)*P,X)}`),_=_.replace(/\\xbord([\d.]+)/g,(M,X)=>`\\xbord${k(parseFloat(X)*Y,X)}`),_=_.replace(/\\ybord([\d.]+)/g,(M,X)=>`\\ybord${k(parseFloat(X)*L,X)}`),_=_.replace(/\\xshad(-?[\d.]+)/g,(M,X)=>`\\xshad${k(parseFloat(X)*Y,X)}`),_=_.replace(/\\yshad(-?[\d.]+)/g,(M,X)=>`\\yshad${k(parseFloat(X)*L,X)}`),["fsp","bord","shad","be","blur"].forEach((M)=>{let X=new RegExp(`\\\\${M}(-?[\\d.]+)`,"g");_=_.replace(X,(V,H)=>`\\${M}${k(parseFloat(H)*B,H)}`)}),_=_.replace(/(\\i?clip\s*\([^,)]+m[^)]+\)|\\p[1-9][^}]*?)(?=[\\}]|$)/g,(M)=>{return M.replace(/(-?[\d.]+)\s+(-?[\d.]+)/g,(X,V,H)=>{return`${k(parseFloat(V)*Y,V)} ${k(parseFloat(H)*L,H)}`})}),z.substring(0,W.index)+_}var b=null,S=null;async function l(){if(b!==null&&S!==null)return{hasAlphaBug:b,hasBitmapBug:S};let J=document.createElement("canvas"),Z=J.getContext("2d",{willReadFrequently:!0});if(!Z)throw Error("Canvas rendering not supported");if(typeof ImageData.prototype.constructor==="function")try{new ImageData(new Uint8ClampedArray([0,0,0,0]),1,1)}catch{console.log("Detected that ImageData is not constructable despite browser saying so")}let Q=document.createElement("canvas"),$=Q.getContext("2d",{willReadFrequently:!0});if(!$)throw Error("Canvas rendering not supported");J.width=Q.width=1,J.height=Q.height=1,Z.clearRect(0,0,1,1),$.clearRect(0,0,1,1);let O=$.getImageData(0,0,1,1).data;Z.putImageData(new ImageData(new Uint8ClampedArray([0,255,0,0]),1,1),0,0),$.drawImage(J,0,0);let N=$.getImageData(0,0,1,1).data;if(b=O[1]!==N[1],b)console.log("Detected a browser having issue with transparent pixels, applying workaround");if(typeof createImageBitmap<"u"){let K=new Uint8ClampedArray([255,0,255,0,255]).subarray(1,5);$.drawImage(await createImageBitmap(new ImageData(K,1)),0,0);let{data:F}=$.getImageData(0,0,1,1);S=!1;for(let G=0;G<F.length;G++)if(Math.abs(K[G]-F[G])>15){S=!0,console.log("Detected a browser having issue with partial bitmaps, applying workaround");break}}else S=!1;return J.remove(),Q.remove(),{hasAlphaBug:b,hasBitmapBug:S}}async function JJ(){return l()}function ZJ(){return b}function $J(){return S}function f(){return typeof navigator<"u"&&"gpu"in navigator}function QJ(J){if(J instanceof ArrayBuffer)return new Uint8Array(J);return new Uint8Array(J.buffer,J.byteOffset,J.byteLength)}class v{device=null;context=null;pipeline=null;bindGroupLayout=null;uniformBuffer=null;imageDataBuffer=null;textureArray=null;textureArrayView=null;textureArraySize=0;textureArrayWidth=0;textureArrayHeight=0;pendingDestroyTextures=[];imageDataArray;resolutionArray=new Float32Array(2);conversionBuffer=null;conversionBufferSize=0;bindGroup=null;bindGroupDirty=!0;lastCanvasWidth=0;lastCanvasHeight=0;format="bgra8unorm";_canvas=null;_initPromise=null;_initialized=!1;constructor(){this.imageDataArray=new Float32Array(2048)}async init(){if(this._initPromise)return this._initPromise;return this._initPromise=this._initDevice(),this._initPromise}async _initDevice(){if(!navigator.gpu)throw Error("WebGPU not supported");let J=await navigator.gpu.requestAdapter({powerPreference:"high-performance"});if(!J)throw Error("No WebGPU adapter found");this.device=await J.requestDevice(),this.format=navigator.gpu.getPreferredCanvasFormat();let Z=this.device.createShaderModule({code:`
2
2
  struct VertexOutput {
3
3
  @builtin(position) position: vec4f,
4
4
  @location(0) @interpolate(flat) instanceIndex: u32,
@@ -53,7 +53,7 @@ fn vertexMain(
53
53
 
54
54
  return output;
55
55
  }
56
- `}),Z=this.device.createShaderModule({code:`
56
+ `}),Q=this.device.createShaderModule({code:`
57
57
  @group(0) @binding(2) var texArray: texture_2d_array<f32>;
58
58
 
59
59
  struct ImageData {
@@ -91,7 +91,7 @@ fn fragmentMain(input: FragmentInput) -> @location(0) vec4f {
91
91
  // Premultiplied alpha output
92
92
  return vec4f(color.rgb * color.a, color.a);
93
93
  }
94
- `});this.uniformBuffer=this.device.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.imageDataBuffer=this.device.createBuffer({size:8192,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),this.createTextureArray(256,256,32),this.bindGroupLayout=this.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"unfilterable-float",viewDimension:"2d-array"}}]});let N=this.device.createPipelineLayout({bindGroupLayouts:[this.bindGroupLayout]});this.pipeline=this.device.createRenderPipeline({layout:N,vertex:{module:K,entryPoint:"vertexMain"},fragment:{module:Z,entryPoint:"fragmentMain",targets:[{format:this.format,blend:{color:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list"}}),this._initialized=!0}nextPowerOf2(J){return J--,J|=J>>1,J|=J>>2,J|=J>>4,J|=J>>8,J|=J>>16,J+1}createTextureArray(J,K,Z){if(this.textureArray)this.pendingDestroyTextures.push(this.textureArray);let N=this.nextPowerOf2(Math.max(J,64)),Q=this.nextPowerOf2(Math.max(K,64)),F=Math.min(this.nextPowerOf2(Math.max(Z,16)),256);this.textureArray=this.device.createTexture({size:[N,Q,F],format:this.format,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),this.textureArrayView=this.textureArray.createView({dimension:"2d-array"}),this.textureArrayWidth=N,this.textureArrayHeight=Q,this.textureArraySize=F,this.bindGroupDirty=!0;let $=this.device.createCommandEncoder();for(let U=0;U<F;U++){let O=this.textureArray.createView({dimension:"2d",baseArrayLayer:U,arrayLayerCount:1});$.beginRenderPass({colorAttachments:[{view:O,clearValue:{r:0,g:0,b:0,a:0},loadOp:"clear",storeOp:"store"}]}).end()}this.device.queue.submit([$.finish()])}ensureTextureArray(J,K,Z){let N=Math.min(Z,256);if(J<=this.textureArrayWidth&&K<=this.textureArrayHeight&&N<=this.textureArraySize)return!1;let Q=this.nextPowerOf2(Math.max(this.textureArrayWidth,J)),F=this.nextPowerOf2(Math.max(this.textureArrayHeight,K)),$=Math.min(this.nextPowerOf2(Math.max(this.textureArraySize,N,N+16)),256);return this.createTextureArray(Q,F,$),!0}updateBindGroup(){if(!this.bindGroupDirty||!this.device||!this.bindGroupLayout)return;this.bindGroup=this.device.createBindGroup({layout:this.bindGroupLayout,entries:[{binding:0,resource:{buffer:this.uniformBuffer}},{binding:1,resource:{buffer:this.imageDataBuffer}},{binding:2,resource:this.textureArrayView}]}),this.bindGroupDirty=!1}ensureConversionBuffer(J){if(this.conversionBufferSize<J)this.conversionBufferSize=Math.max(J,this.conversionBufferSize*1.5|0,65536),this.conversionBuffer=new Uint8Array(this.conversionBufferSize);return this.conversionBuffer}async setCanvas(J,K,Z){if(await this.init(),!this.device)throw Error("WebGPU device not initialized");if(K<=0||Z<=0)return;if(this._canvas=J,J.width=K,J.height=Z,!this.context){if(this.context=J.getContext("webgpu"),!this.context)throw Error("Could not get WebGPU context");this.context.configure({device:this.device,format:this.format,alphaMode:"premultiplied"})}this.resolutionArray[0]=K,this.resolutionArray[1]=Z,this.device.queue.writeBuffer(this.uniformBuffer,0,this.resolutionArray),this.lastCanvasWidth=K,this.lastCanvasHeight=Z}updateSize(J,K){if(!this.device||!this._canvas||J<=0||K<=0)return;if(J===this.lastCanvasWidth&&K===this.lastCanvasHeight)return;this._canvas.width=J,this._canvas.height=K,this.resolutionArray[0]=J,this.resolutionArray[1]=K,this.device.queue.writeBuffer(this.uniformBuffer,0,this.resolutionArray),this.lastCanvasWidth=J,this.lastCanvasHeight=K}renderBitmaps(J,K,Z){if(!this.device||!this.context||!this.pipeline)return;let N=J.length;if(N===0){this.clear();return}let Q=this.context.getCurrentTexture();if(Q.width===0||Q.height===0)return;let F=0,$=0,U=0;for(let j=0;j<N;j++){let{image:P}=J[j],W=P.width,B=P.height;if(W>0&&B>0){if(W>F)F=W;if(B>$)$=B;U++}}if(U===0){this.clear();return}let O=Math.min(U,256);this.ensureTextureArray(F,$,O),this.updateBindGroup();let E=this.device,q=E.queue,L=this.textureArray,_=this.imageDataArray,Y=Q.createView(),T=0,z=!0;while(T<N){let j=0;while(T<N&&j<256){let B=J[T++],G=B.image,H=G.width,M=G.height;if(H<=0||M<=0)continue;q.copyExternalImageToTexture({source:G,flipY:!1},{texture:L,origin:[0,0,j],premultipliedAlpha:!1},{width:H,height:M});let X=j<<3;_[X]=B.x,_[X+1]=B.y,_[X+2]=H,_[X+3]=M,_[X+4]=H,_[X+5]=M,_[X+6]=j,_[X+7]=0,j++}if(j===0)continue;q.writeBuffer(this.imageDataBuffer,0,_.buffer,0,j<<5);let P=E.createCommandEncoder(),W=P.beginRenderPass({colorAttachments:[{view:Y,clearValue:{r:0,g:0,b:0,a:0},loadOp:z?"clear":"load",storeOp:"store"}]});W.setPipeline(this.pipeline),W.setBindGroup(0,this.bindGroup),W.draw(6,j),W.end(),q.submit([P.finish()]),z=!1}this.cleanupPendingTextures()}render(J,K,Z){if(!this.device||!this.context||!this.pipeline)return;let N=J.length;if(N===0){this.clear();return}let Q=this.context.getCurrentTexture();if(Q.width===0||Q.height===0)return;let F=0,$=0,U=0;for(let P=0;P<N;P++){let{w:W,h:B}=J[P];if(W>0&&B>0){if(W>F)F=W;if(B>$)$=B;U++}}if(U===0){this.clear();return}let O=Math.min(U,256);this.ensureTextureArray(F,$,O),this.updateBindGroup();let E=this.device,q=E.queue,L=this.textureArray,_=this.imageDataArray,Y=this.format==="bgra8unorm",T=Q.createView(),z=0,j=!0;while(z<N){let P=0;while(z<N&&P<256){let G=J[z++],H=G.w,M=G.h;if(H<=0||M<=0)continue;let X=G.image;if(X instanceof ImageBitmap)q.copyExternalImageToTexture({source:X,flipY:!1},{texture:L,origin:[0,0,P],premultipliedAlpha:!1},{width:H,height:M});else if(X instanceof ArrayBuffer)this.uploadTextureData(P,X,H,M,Y);let V=P<<3;_[V]=G.x,_[V+1]=G.y,_[V+2]=H,_[V+3]=M,_[V+4]=H,_[V+5]=M,_[V+6]=P,_[V+7]=0,P++}if(P===0)continue;q.writeBuffer(this.imageDataBuffer,0,_.buffer,0,P<<5);let W=E.createCommandEncoder(),B=W.beginRenderPass({colorAttachments:[{view:T,clearValue:{r:0,g:0,b:0,a:0},loadOp:j?"clear":"load",storeOp:"store"}]});B.setPipeline(this.pipeline),B.setBindGroup(0,this.bindGroup),B.draw(6,P),B.end(),q.submit([W.finish()]),j=!1}this.cleanupPendingTextures()}uploadTextureData(J,K,Z,N,Q){let F=Z*N*4;if(Q){let $=this.ensureConversionBuffer(F),U=new Uint8Array(K);for(let O=0;O<F;O+=4)$[O]=U[O+2],$[O+1]=U[O+1],$[O+2]=U[O],$[O+3]=U[O+3];this.device.queue.writeTexture({texture:this.textureArray,origin:[0,0,J]},$.buffer,{bytesPerRow:Z*4},{width:Z,height:N})}else this.device.queue.writeTexture({texture:this.textureArray,origin:[0,0,J]},K,{bytesPerRow:Z*4},{width:Z,height:N})}cleanupPendingTextures(){let J=this.pendingDestroyTextures,K=J.length;if(K===0)return;for(let Z=0;Z<K;Z++)J[Z].destroy();J.length=0}clear(){if(!this.device||!this.context)return;try{let J=this.context.getCurrentTexture();if(J.width===0||J.height===0)return;let K=this.device.createCommandEncoder();K.beginRenderPass({colorAttachments:[{view:J.createView(),clearValue:{r:0,g:0,b:0,a:0},loadOp:"clear",storeOp:"store"}]}).end(),this.device.queue.submit([K.finish()])}catch{}}get initialized(){return this._initialized}destroy(){this.cleanupPendingTextures(),this.textureArray?.destroy(),this.textureArray=null,this.textureArrayView=null,this.uniformBuffer?.destroy(),this.uniformBuffer=null,this.imageDataBuffer?.destroy(),this.imageDataBuffer=null,this.bindGroup=null,this.conversionBuffer=null,this.conversionBufferSize=0,this.device?.destroy(),this.device=null,this.context=null,this._canvas=null,this._initialized=!1,this._initPromise=null}}function p(){if(typeof document>"u")return!1;try{return document.createElement("canvas").getContext("webgl2")!==null}catch{return!1}}function d(J,K,Z){let N=J.createShader(K);if(J.shaderSource(N,Z),J.compileShader(N),!J.getShaderParameter(N,J.COMPILE_STATUS)){let Q=J.getShaderInfoLog(N);throw J.deleteShader(N),Error(`WebGL2 shader compilation failed: ${Q}`)}return N}class x{_gl=null;_canvas=null;_program=null;_vao=null;_instanceBuffer=null;_texArray=null;_texWidth=0;_texHeight=0;_texLayers=0;_resolutionLoc=null;_texArraySizeLoc=null;_instanceData;_lastCanvasWidth=0;_lastCanvasHeight=0;_initialized=!1;_initPromise=null;constructor(){this._instanceData=new Float32Array(2048)}async init(){if(this._initPromise)return this._initPromise;return this._initPromise=this._checkSupport(),this._initPromise}async _checkSupport(){if(typeof document>"u")throw Error("WebGL2 requires a DOM environment");if(!document.createElement("canvas").getContext("webgl2"))throw Error("WebGL2 not supported")}_initGL(){if(!this._canvas)throw Error("Canvas not set before _initGL");if(this._gl)return;let J=this._canvas.getContext("webgl2",{alpha:!0,premultipliedAlpha:!0,antialias:!1});if(!J)throw Error("Failed to create WebGL2 context");this._gl=J;let K=d(J,J.VERTEX_SHADER,`#version 300 es
94
+ `});this.uniformBuffer=this.device.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.imageDataBuffer=this.device.createBuffer({size:8192,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),this.createTextureArray(256,256,32),this.bindGroupLayout=this.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"unfilterable-float",viewDimension:"2d-array"}}]});let $=this.device.createPipelineLayout({bindGroupLayouts:[this.bindGroupLayout]});this.pipeline=this.device.createRenderPipeline({layout:$,vertex:{module:Z,entryPoint:"vertexMain"},fragment:{module:Q,entryPoint:"fragmentMain",targets:[{format:this.format,blend:{color:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list"}}),this._initialized=!0}nextPowerOf2(J){return J--,J|=J>>1,J|=J>>2,J|=J>>4,J|=J>>8,J|=J>>16,J+1}createTextureArray(J,Z,Q){if(this.textureArray)this.pendingDestroyTextures.push(this.textureArray);let $=this.nextPowerOf2(Math.max(J,64)),O=this.nextPowerOf2(Math.max(Z,64)),N=Math.min(this.nextPowerOf2(Math.max(Q,16)),256);this.textureArray=this.device.createTexture({size:[$,O,N],format:this.format,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),this.textureArrayView=this.textureArray.createView({dimension:"2d-array"}),this.textureArrayWidth=$,this.textureArrayHeight=O,this.textureArraySize=N,this.bindGroupDirty=!0;let K=this.device.createCommandEncoder();for(let F=0;F<N;F++){let G=this.textureArray.createView({dimension:"2d",baseArrayLayer:F,arrayLayerCount:1});K.beginRenderPass({colorAttachments:[{view:G,clearValue:{r:0,g:0,b:0,a:0},loadOp:"clear",storeOp:"store"}]}).end()}this.device.queue.submit([K.finish()])}ensureTextureArray(J,Z,Q){let $=Math.min(Q,256);if(J<=this.textureArrayWidth&&Z<=this.textureArrayHeight&&$<=this.textureArraySize)return!1;let O=this.nextPowerOf2(Math.max(this.textureArrayWidth,J)),N=this.nextPowerOf2(Math.max(this.textureArrayHeight,Z)),K=Math.min(this.nextPowerOf2(Math.max(this.textureArraySize,$,$+16)),256);return this.createTextureArray(O,N,K),!0}updateBindGroup(){if(!this.bindGroupDirty||!this.device||!this.bindGroupLayout)return;this.bindGroup=this.device.createBindGroup({layout:this.bindGroupLayout,entries:[{binding:0,resource:{buffer:this.uniformBuffer}},{binding:1,resource:{buffer:this.imageDataBuffer}},{binding:2,resource:this.textureArrayView}]}),this.bindGroupDirty=!1}ensureConversionBuffer(J){if(this.conversionBufferSize<J)this.conversionBufferSize=Math.max(J,this.conversionBufferSize*1.5|0,65536),this.conversionBuffer=new Uint8Array(this.conversionBufferSize);return this.conversionBuffer}async setCanvas(J,Z,Q){if(await this.init(),!this.device)throw Error("WebGPU device not initialized");if(Z<=0||Q<=0)return;if(this._canvas=J,J.width=Z,J.height=Q,!this.context){if(this.context=J.getContext("webgpu"),!this.context)throw Error("Could not get WebGPU context");this.context.configure({device:this.device,format:this.format,alphaMode:"premultiplied"})}this.resolutionArray[0]=Z,this.resolutionArray[1]=Q,this.device.queue.writeBuffer(this.uniformBuffer,0,this.resolutionArray),this.lastCanvasWidth=Z,this.lastCanvasHeight=Q}updateSize(J,Z){if(!this.device||!this._canvas||J<=0||Z<=0)return;if(J===this.lastCanvasWidth&&Z===this.lastCanvasHeight)return;this._canvas.width=J,this._canvas.height=Z,this.resolutionArray[0]=J,this.resolutionArray[1]=Z,this.device.queue.writeBuffer(this.uniformBuffer,0,this.resolutionArray),this.lastCanvasWidth=J,this.lastCanvasHeight=Z}renderBitmaps(J,Z,Q){if(!this.device||!this.context||!this.pipeline)return;let $=J.length;if($===0){this.clear();return}let O=this.context.getCurrentTexture();if(O.width===0||O.height===0)return;let N=0,K=0,F=0;for(let j=0;j<$;j++){let{image:P}=J[j],z=P.width,W=P.height;if(z>0&&W>0){if(z>N)N=z;if(W>K)K=W;F++}}if(F===0){this.clear();return}let G=Math.min(F,256);this.ensureTextureArray(N,K,G),this.updateBindGroup();let U=this.device,E=U.queue,T=this.textureArray,q=this.imageDataArray,Y=O.createView(),L=0,B=!0;while(L<$){let j=0;while(L<$&&j<256){let W=J[L++],_=W.image,I=_.width,M=_.height;if(I<=0||M<=0)continue;E.copyExternalImageToTexture({source:_,flipY:!1},{texture:T,origin:[0,0,j],premultipliedAlpha:!1},{width:I,height:M});let X=j<<3;q[X]=W.x,q[X+1]=W.y,q[X+2]=I,q[X+3]=M,q[X+4]=I,q[X+5]=M,q[X+6]=j,q[X+7]=0,j++}if(j===0)continue;E.writeBuffer(this.imageDataBuffer,0,q.buffer,0,j<<5);let P=U.createCommandEncoder(),z=P.beginRenderPass({colorAttachments:[{view:Y,clearValue:{r:0,g:0,b:0,a:0},loadOp:B?"clear":"load",storeOp:"store"}]});z.setPipeline(this.pipeline),z.setBindGroup(0,this.bindGroup),z.draw(6,j),z.end(),E.submit([P.finish()]),B=!1}this.cleanupPendingTextures()}render(J,Z,Q){if(!this.device||!this.context||!this.pipeline)return;let $=J.length;if($===0){this.clear();return}let O=this.context.getCurrentTexture();if(O.width===0||O.height===0)return;let N=0,K=0,F=0;for(let P=0;P<$;P++){let{w:z,h:W}=J[P];if(z>0&&W>0){if(z>N)N=z;if(W>K)K=W;F++}}if(F===0){this.clear();return}let G=Math.min(F,256);this.ensureTextureArray(N,K,G),this.updateBindGroup();let U=this.device,E=U.queue,T=this.textureArray,q=this.imageDataArray,Y=this.format==="bgra8unorm",L=O.createView(),B=0,j=!0;while(B<$){let P=0;while(B<$&&P<256){let _=J[B++],I=_.w,M=_.h;if(I<=0||M<=0)continue;let X=_.image;if(X instanceof ImageBitmap)E.copyExternalImageToTexture({source:X,flipY:!1},{texture:T,origin:[0,0,P],premultipliedAlpha:!1},{width:I,height:M});else if(X instanceof ArrayBuffer||X instanceof Uint8Array||X instanceof Uint8ClampedArray)this.uploadTextureData(P,X,I,M,Y);let V=P<<3;q[V]=_.x,q[V+1]=_.y,q[V+2]=I,q[V+3]=M,q[V+4]=I,q[V+5]=M,q[V+6]=P,q[V+7]=0,P++}if(P===0)continue;E.writeBuffer(this.imageDataBuffer,0,q.buffer,0,P<<5);let z=U.createCommandEncoder(),W=z.beginRenderPass({colorAttachments:[{view:L,clearValue:{r:0,g:0,b:0,a:0},loadOp:j?"clear":"load",storeOp:"store"}]});W.setPipeline(this.pipeline),W.setBindGroup(0,this.bindGroup),W.draw(6,P),W.end(),E.submit([z.finish()]),j=!1}this.cleanupPendingTextures()}uploadTextureData(J,Z,Q,$,O){let N=Q*$*4,K=QJ(Z);if(O){let F=this.ensureConversionBuffer(N);for(let G=0;G<N;G+=4)F[G]=K[G+2],F[G+1]=K[G+1],F[G+2]=K[G],F[G+3]=K[G+3];this.device.queue.writeTexture({texture:this.textureArray,origin:[0,0,J]},F.buffer,{bytesPerRow:Q*4},{width:Q,height:$})}else this.device.queue.writeTexture({texture:this.textureArray,origin:[0,0,J]},K,{bytesPerRow:Q*4},{width:Q,height:$})}cleanupPendingTextures(){let J=this.pendingDestroyTextures,Z=J.length;if(Z===0)return;for(let Q=0;Q<Z;Q++)J[Q].destroy();J.length=0}clear(){if(!this.device||!this.context)return;try{let J=this.context.getCurrentTexture();if(J.width===0||J.height===0)return;let Z=this.device.createCommandEncoder();Z.beginRenderPass({colorAttachments:[{view:J.createView(),clearValue:{r:0,g:0,b:0,a:0},loadOp:"clear",storeOp:"store"}]}).end(),this.device.queue.submit([Z.finish()])}catch{}}get initialized(){return this._initialized}destroy(){this.cleanupPendingTextures(),this.textureArray?.destroy(),this.textureArray=null,this.textureArrayView=null,this.uniformBuffer?.destroy(),this.uniformBuffer=null,this.imageDataBuffer?.destroy(),this.imageDataBuffer=null,this.bindGroup=null,this.conversionBuffer=null,this.conversionBufferSize=0,this.device?.destroy(),this.device=null,this.context=null,this._canvas=null,this._initialized=!1,this._initPromise=null}}function p(){if(typeof document>"u")return!1;try{return document.createElement("canvas").getContext("webgl2")!==null}catch{return!1}}function KJ(J){return J instanceof Uint8Array||J instanceof Uint8ClampedArray}function g(J,Z,Q){let $=J.createShader(Z);if(J.shaderSource($,Q),J.compileShader($),!J.getShaderParameter($,J.COMPILE_STATUS)){let O=J.getShaderInfoLog($);throw J.deleteShader($),Error(`WebGL2 shader compilation failed: ${O}`)}return $}class x{_gl=null;_canvas=null;_program=null;_vao=null;_instanceBuffer=null;_texArray=null;_texWidth=0;_texHeight=0;_texLayers=0;_resolutionLoc=null;_texArraySizeLoc=null;_instanceData;_lastCanvasWidth=0;_lastCanvasHeight=0;_initialized=!1;_initPromise=null;constructor(){this._instanceData=new Float32Array(2048)}async init(){if(this._initPromise)return this._initPromise;return this._initPromise=this._checkSupport(),this._initPromise}async _checkSupport(){if(typeof document>"u")throw Error("WebGL2 requires a DOM environment");if(!document.createElement("canvas").getContext("webgl2"))throw Error("WebGL2 not supported")}_initGL(){if(!this._canvas)throw Error("Canvas not set before _initGL");if(this._gl)return;let J=this._canvas.getContext("webgl2",{alpha:!0,premultipliedAlpha:!0,antialias:!1});if(!J)throw Error("Failed to create WebGL2 context");this._gl=J;let Z=g(J,J.VERTEX_SHADER,`#version 300 es
95
95
  precision highp float;
96
96
 
97
97
  in vec4 a_destRect;
@@ -125,7 +125,7 @@ void main() {
125
125
  v_texIndex = int(a_texInfo.z);
126
126
  v_texSize = a_texInfo.xy;
127
127
  }
128
- `),Z=d(J,J.FRAGMENT_SHADER,`#version 300 es
128
+ `),Q=g(J,J.FRAGMENT_SHADER,`#version 300 es
129
129
  precision highp float;
130
130
  precision highp sampler2DArray;
131
131
 
@@ -144,4 +144,4 @@ void main() {
144
144
  // Premultiplied alpha output (matches WebGPU renderer behaviour)
145
145
  fragColor = vec4(color.rgb * color.a, color.a);
146
146
  }
147
- `),N=J.createProgram();if(J.attachShader(N,K),J.attachShader(N,Z),J.linkProgram(N),!J.getProgramParameter(N,J.LINK_STATUS))throw Error(`WebGL2 program link failed: ${J.getProgramInfoLog(N)}`);J.deleteShader(K),J.deleteShader(Z),this._program=N,this._resolutionLoc=J.getUniformLocation(N,"u_resolution"),this._texArraySizeLoc=J.getUniformLocation(N,"u_texArraySize"),this._vao=J.createVertexArray(),J.bindVertexArray(this._vao),this._instanceBuffer=J.createBuffer(),J.bindBuffer(J.ARRAY_BUFFER,this._instanceBuffer),J.bufferData(J.ARRAY_BUFFER,8192,J.DYNAMIC_DRAW);let Q=J.getAttribLocation(N,"a_destRect");J.enableVertexAttribArray(Q),J.vertexAttribPointer(Q,4,J.FLOAT,!1,32,0),J.vertexAttribDivisor(Q,1);let F=J.getAttribLocation(N,"a_texInfo");J.enableVertexAttribArray(F),J.vertexAttribPointer(F,4,J.FLOAT,!1,32,16),J.vertexAttribDivisor(F,1),J.bindVertexArray(null),this._texArray=J.createTexture(),this._allocateTextureArray(256,256,32),J.enable(J.BLEND),J.blendEquation(J.FUNC_ADD),J.blendFunc(J.ONE,J.ONE_MINUS_SRC_ALPHA),this._initialized=!0}_nextPow2(J){return J--,J|=J>>1,J|=J>>2,J|=J>>4,J|=J>>8,J|=J>>16,J+1}_allocateTextureArray(J,K,Z){let N=this._gl,Q=this._nextPow2(Math.max(J,64)),F=this._nextPow2(Math.max(K,64)),$=Math.min(this._nextPow2(Math.max(Z,16)),256);N.bindTexture(N.TEXTURE_2D_ARRAY,this._texArray),N.texImage3D(N.TEXTURE_2D_ARRAY,0,N.RGBA8,Q,F,$,0,N.RGBA,N.UNSIGNED_BYTE,null),N.texParameteri(N.TEXTURE_2D_ARRAY,N.TEXTURE_MIN_FILTER,N.NEAREST),N.texParameteri(N.TEXTURE_2D_ARRAY,N.TEXTURE_MAG_FILTER,N.NEAREST),N.texParameteri(N.TEXTURE_2D_ARRAY,N.TEXTURE_WRAP_S,N.CLAMP_TO_EDGE),N.texParameteri(N.TEXTURE_2D_ARRAY,N.TEXTURE_WRAP_T,N.CLAMP_TO_EDGE),this._texWidth=Q,this._texHeight=F,this._texLayers=$}_ensureTextureArray(J,K,Z){let N=Math.min(Z,256);if(J<=this._texWidth&&K<=this._texHeight&&N<=this._texLayers)return;let Q=this._nextPow2(Math.max(this._texWidth,J)),F=this._nextPow2(Math.max(this._texHeight,K)),$=Math.min(this._nextPow2(Math.max(this._texLayers,N,N+16)),256);this._allocateTextureArray(Q,F,$)}async setCanvas(J,K,Z){if(await this.init(),K<=0||Z<=0)return;this._canvas=J,J.width=K,J.height=Z,this._initGL(),this._gl.viewport(0,0,K,Z),this._lastCanvasWidth=K,this._lastCanvasHeight=Z}updateSize(J,K){if(!this._gl||!this._canvas||J<=0||K<=0)return;if(J===this._lastCanvasWidth&&K===this._lastCanvasHeight)return;this._canvas.width=J,this._canvas.height=K,this._gl.viewport(0,0,J,K),this._lastCanvasWidth=J,this._lastCanvasHeight=K}renderBitmaps(J,K,Z){if(!this._gl||!this._initialized)return;let N=J.length;if(N===0){this.clear();return}let Q=0,F=0;for(let E=0;E<N;E++){let{image:q}=J[E];if(q.width>Q)Q=q.width;if(q.height>F)F=q.height}this._ensureTextureArray(Q,F,Math.min(N,256));let $=this._gl;$.clearColor(0,0,0,0),$.clear($.COLOR_BUFFER_BIT),$.useProgram(this._program),$.uniform2f(this._resolutionLoc,this._lastCanvasWidth,this._lastCanvasHeight),$.uniform2i(this._texArraySizeLoc,this._texWidth,this._texHeight),$.activeTexture($.TEXTURE0),$.bindTexture($.TEXTURE_2D_ARRAY,this._texArray),$.pixelStorei($.UNPACK_FLIP_Y_WEBGL,!1);let U=this._instanceData,O=0;while(O<N){let E=0;while(O<N&&E<256){let q=J[O++],L=q.image.width,_=q.image.height;if(L<=0||_<=0)continue;$.texSubImage3D($.TEXTURE_2D_ARRAY,0,0,0,E,L,_,1,$.RGBA,$.UNSIGNED_BYTE,q.image);let Y=E<<3;U[Y]=q.x,U[Y+1]=q.y,U[Y+2]=L,U[Y+3]=_,U[Y+4]=L,U[Y+5]=_,U[Y+6]=E,U[Y+7]=0,E++}if(E===0)continue;$.bindBuffer($.ARRAY_BUFFER,this._instanceBuffer),$.bufferSubData($.ARRAY_BUFFER,0,U,0,E<<3),$.bindVertexArray(this._vao),$.drawArraysInstanced($.TRIANGLES,0,6,E),$.bindVertexArray(null)}}render(J,K,Z){if(!this._gl||!this._initialized)return;let N=J.length;if(N===0){this.clear();return}let Q=0,F=0;for(let E=0;E<N;E++){let{w:q,h:L}=J[E];if(q>Q)Q=q;if(L>F)F=L}this._ensureTextureArray(Q,F,Math.min(N,256));let $=this._gl;$.clearColor(0,0,0,0),$.clear($.COLOR_BUFFER_BIT),$.useProgram(this._program),$.uniform2f(this._resolutionLoc,this._lastCanvasWidth,this._lastCanvasHeight),$.uniform2i(this._texArraySizeLoc,this._texWidth,this._texHeight),$.activeTexture($.TEXTURE0),$.bindTexture($.TEXTURE_2D_ARRAY,this._texArray),$.pixelStorei($.UNPACK_FLIP_Y_WEBGL,!1);let U=this._instanceData,O=0;while(O<N){let E=0;while(O<N&&E<256){let q=J[O++],L=q.w,_=q.h;if(L<=0||_<=0)continue;let Y=q.image;if(Y instanceof ImageBitmap)$.texSubImage3D($.TEXTURE_2D_ARRAY,0,0,0,E,L,_,1,$.RGBA,$.UNSIGNED_BYTE,Y);else if(Y instanceof ArrayBuffer)$.texSubImage3D($.TEXTURE_2D_ARRAY,0,0,0,E,L,_,1,$.RGBA,$.UNSIGNED_BYTE,new Uint8Array(Y));let T=E<<3;U[T]=q.x,U[T+1]=q.y,U[T+2]=L,U[T+3]=_,U[T+4]=L,U[T+5]=_,U[T+6]=E,U[T+7]=0,E++}if(E===0)continue;$.bindBuffer($.ARRAY_BUFFER,this._instanceBuffer),$.bufferSubData($.ARRAY_BUFFER,0,U,0,E<<3),$.bindVertexArray(this._vao),$.drawArraysInstanced($.TRIANGLES,0,6,E),$.bindVertexArray(null)}}clear(){if(!this._gl)return;this._gl.clearColor(0,0,0,0),this._gl.clear(this._gl.COLOR_BUFFER_BIT)}get initialized(){return this._initialized}destroy(){let J=this._gl;if(J)J.deleteProgram(this._program),J.deleteVertexArray(this._vao),J.deleteBuffer(this._instanceBuffer),J.deleteTexture(this._texArray);this._gl=null,this._program=null,this._vao=null,this._instanceBuffer=null,this._texArray=null,this._canvas=null,this._initialized=!1,this._initPromise=null}}class R extends EventTarget{static MAX_PENDING_DEMANDS=3;static _hasAlphaBug=null;static _hasBitmapBug=null;_loaded;_init;_onDemandRender;_offscreenRender;_video;_videoWidth=0;_videoHeight=0;_videoColorSpace=null;_canvas;_canvasParent;_bufferCanvas;_bufferCtx;_canvasctrl;_ctx=null;_lastRenderTime=0;_playstate=!0;_destroyed=!1;_workerReady=!1;_ro;_worker;_pendingDemandTimes=[];_boundResize;_boundTimeUpdate;_boundSetRate;_boundUpdateColorSpace;_boundHandleRVFC;_gpuRenderer=null;_rendererType="canvas2d";_onCanvasFallback;_lastRenderWidth=0;_lastRenderHeight=0;timeOffset;debug;prescaleFactor;prescaleHeightLimit;maxRenderHeight;busy=!1;renderAhead;constructor(J){super();if(!globalThis.Worker)throw this.destroy(Error("Worker not supported"));if(!J)throw this.destroy(Error("No options provided"));this._loaded=new Promise((Q)=>{this._init=Q});let K=R._test();this._onDemandRender="requestVideoFrameCallback"in HTMLVideoElement.prototype&&(J.onDemandRender??!0),this._onCanvasFallback=J.onCanvasFallback;let Z=!J.canvas&&(f()||p());if(this._offscreenRender="transferControlToOffscreen"in HTMLCanvasElement.prototype&&!J.canvas&&!Z&&(J.offscreenRender??!0),this.timeOffset=J.timeOffset||0,this._video=J.video,this._canvas=J.canvas,this._video&&!this._canvas)this._canvasParent=document.createElement("div"),this._canvasParent.className="AkariSub",this._canvasParent.style.position="relative",this._canvas=this._createCanvas(),this._video.insertAdjacentElement("afterend",this._canvasParent);else if(!this._canvas)throw this.destroy(Error("Don't know where to render: you should give video or canvas in options."));this._bufferCanvas=document.createElement("canvas");let N=this._bufferCanvas.getContext("2d");if(!N)throw this.destroy(Error("Canvas rendering not supported"));if(this._bufferCtx=N,Z)this._initGPURenderer();else if(!this._offscreenRender)this._ctx=this._canvas.getContext("2d");if(this._canvasctrl=this._offscreenRender?this._canvas.transferControlToOffscreen():this._canvas,this._lastRenderTime=0,this.debug=!!J.debug,this.prescaleFactor=J.prescaleFactor||1,this.prescaleHeightLimit=J.prescaleHeightLimit||1080,this.maxRenderHeight=J.maxRenderHeight||0,this.renderAhead=J.renderAhead??0,this._boundResize=this.resize.bind(this),this._boundTimeUpdate=this._timeupdate.bind(this),this._boundSetRate=()=>this.setRate(this._video.playbackRate),this._boundUpdateColorSpace=this._updateColorSpace.bind(this),this._boundHandleRVFC=this._handleRVFC.bind(this),this._video)this.setVideo(this._video);if(this._onDemandRender)this.busy=!1,this._pendingDemandTimes.length=0;this._worker=new Worker(J.workerUrl||"akarisub-worker.js"),this._worker.onmessage=(Q)=>this._onmessage(Q),this._worker.onerror=(Q)=>this._error(Q),K.then(()=>{if(this._worker.postMessage({target:"init",wasmUrl:J.wasmUrl??"akarisub-worker.wasm",asyncRender:typeof createImageBitmap<"u"&&(J.asyncRender??!0),onDemandRender:this._onDemandRender,initialTime:(this._video?.currentTime??0)+this.timeOffset,width:this._canvasctrl.width||0,height:this._canvasctrl.height||0,blendMode:J.blendMode??"wasm",subUrl:J.subUrl,subContent:J.subContent||null,fonts:J.fonts||[],availableFonts:J.availableFonts||{"liberation sans":"./default.woff2"},fallbackFonts:J.fallbackFonts||["liberation sans"],debug:this.debug,targetFps:J.targetFps||24,dropAllAnimations:J.dropAllAnimations,dropAllBlur:J.dropAllBlur,clampPos:J.clampPos,libassMemoryLimit:J.libassMemoryLimit??128,libassGlyphLimit:J.libassGlyphLimit??2048,useLocalFonts:typeof globalThis.queryLocalFonts<"u"&&(J.useLocalFonts??!0),hasBitmapBug:R._hasBitmapBug}),this._offscreenRender)this.sendMessage("offscreenCanvas",{},[this._canvasctrl])})}static async _testImageBugs(){if(R._hasBitmapBug!==null)return;let J=document.createElement("canvas"),K=J.getContext("2d",{willReadFrequently:!0});if(!K)throw Error("Canvas rendering not supported");if(typeof ImageData.prototype.constructor==="function")try{new ImageData(new Uint8ClampedArray([0,0,0,0]),1,1)}catch{console.log("Detected that ImageData is not constructable despite browser saying so")}let Z=document.createElement("canvas"),N=Z.getContext("2d",{willReadFrequently:!0});if(!N)throw Error("Canvas rendering not supported");J.width=Z.width=1,J.height=Z.height=1,K.clearRect(0,0,1,1),N.clearRect(0,0,1,1);let Q=N.getImageData(0,0,1,1).data;K.putImageData(new ImageData(new Uint8ClampedArray([0,255,0,0]),1,1),0,0),N.drawImage(J,0,0);let F=N.getImageData(0,0,1,1).data;if(R._hasAlphaBug=Q[1]!==F[1],R._hasAlphaBug)console.log("Detected a browser having issue with transparent pixels, applying workaround");if(typeof createImageBitmap<"u"){let $=new Uint8ClampedArray([255,0,255,0,255]).subarray(1,5);N.drawImage(await createImageBitmap(new ImageData($,1)),0,0);let{data:U}=N.getImageData(0,0,1,1);R._hasBitmapBug=!1;for(let O=0;O<U.length;O++)if(Math.abs($[O]-U[O])>15){R._hasBitmapBug=!0,console.log("Detected a browser having issue with partial bitmaps, applying workaround");break}}else R._hasBitmapBug=!1;J.remove(),Z.remove()}static async _test(){await R._testImageBugs()}async _initGPURenderer(){if(f())try{let J=new v;if(await J.init(),!this._canvas)return;await J.setCanvas(this._canvas,Math.max(1,this._canvas.width||1),Math.max(1,this._canvas.height||1)),this._gpuRenderer=J,this._rendererType="webgpu",console.log("[AkariSub] Using WebGPU renderer");return}catch(J){console.warn("[AkariSub] WebGPU init failed, trying WebGL2:",J)}if(p())try{let J=new x;if(await J.init(),!this._canvas)return;await J.setCanvas(this._canvas,Math.max(1,this._canvas.width||1),Math.max(1,this._canvas.height||1)),this._gpuRenderer=J,this._rendererType="webgl2",console.log("[AkariSub] Using WebGL2 renderer");return}catch(J){console.warn("[AkariSub] WebGL2 init failed, falling back to Canvas2D:",J)}if(this._rendererType="canvas2d",!this._offscreenRender&&!this._ctx)this._ctx=this._canvas.getContext("2d");this.sendMessage("setAsyncRender",{value:!1}),this._onCanvasFallback?.()}get rendererType(){return this._rendererType}get isUsingWebGPU(){return this._rendererType==="webgpu"}get isUsingGPURenderer(){return this._gpuRenderer!==null}_createCanvas(){return this._canvas=document.createElement("canvas"),this._canvas.style.display="block",this._canvas.style.position="absolute",this._canvas.style.pointerEvents="none",this._canvasParent.appendChild(this._canvas),this._canvas}resize(J=0,K=0,Z=0,N=0,Q=this._video?.paused??!1){if((!J||!K)&&this._video){let F=c(this._video),$;if(this._videoWidth){let U=this._video.videoWidth/this._videoWidth,O=this._video.videoHeight/this._videoHeight;$=w((F.width||0)/U,(F.height||0)/O,this.prescaleFactor,this.prescaleHeightLimit,this.maxRenderHeight)}else $=w(F.width||0,F.height||0,this.prescaleFactor,this.prescaleHeightLimit,this.maxRenderHeight);if(J=$.width,K=$.height,this._canvasParent)Z=F.y-(this._canvasParent.getBoundingClientRect().top-this._video.getBoundingClientRect().top),N=F.x;this._canvas.style.width=F.width+"px",this._canvas.style.height=F.height+"px"}if(this._canvas.style.top=Z+"px",this._canvas.style.left=N+"px",J>0&&K>0)this._canvasctrl.width=J,this._canvasctrl.height=K;if(this._gpuRenderer&&J>0&&K>0)this._gpuRenderer.updateSize(J,K);if(Q&&this.busy===!1)this.busy=!0;else Q=!1;this.sendMessage("canvas",{width:J,height:K,videoWidth:this._videoWidth||this._video?.videoWidth||0,videoHeight:this._videoHeight||this._video?.videoHeight||0,force:Q})}_timeupdate(J){let Z={seeking:!0,waiting:!0,playing:!1}[J.type];if(Z!=null)this._playstate=Z;this.setCurrentTime(this._video.paused||this._playstate,this._video.currentTime+this.timeOffset)}setVideo(J){if(J instanceof HTMLVideoElement){if(this._removeListeners(),this._video=J,this._onDemandRender){if(!this._destroyed&&this._video===J)J.requestVideoFrameCallback(this._boundHandleRVFC)}else this._playstate=J.paused,J.addEventListener("timeupdate",this._boundTimeUpdate,!1),J.addEventListener("progress",this._boundTimeUpdate,!1),J.addEventListener("waiting",this._boundTimeUpdate,!1),J.addEventListener("seeking",this._boundTimeUpdate,!1),J.addEventListener("playing",this._boundTimeUpdate,!1),J.addEventListener("ratechange",this._boundSetRate,!1),J.addEventListener("resize",this._boundResize,!1);if("VideoFrame"in window){if(J.addEventListener("loadedmetadata",this._boundUpdateColorSpace,!1),J.readyState>2)this._updateColorSpace()}if(J.videoWidth>0)this.resize();if(typeof ResizeObserver<"u"){if(!this._ro)this._ro=new ResizeObserver(()=>this.resize());this._ro.observe(J)}}else this._error(Error("Video element invalid!"))}runBenchmark(){this.sendMessage("runBenchmark")}setTrackByUrl(J){if(this.sendMessage("setTrackByUrl",{url:J}),this._reAttachOffscreen(),this._ctx)this._ctx.filter="none"}setTrack(J){if(this.sendMessage("setTrack",{content:J}),this._reAttachOffscreen(),this._ctx)this._ctx.filter="none"}freeTrack(){this.sendMessage("freeTrack")}setIsPaused(J){this.sendMessage("video",{isPaused:J})}setRate(J){this.sendMessage("video",{rate:J})}setCurrentTime(J,K,Z){this.sendMessage("video",{isPaused:J,currentTime:K,rate:Z,colorSpace:this._videoColorSpace})}createEvent(J){this.sendMessage("createEvent",{event:J})}setEvent(J,K){this.sendMessage("setEvent",{event:J,index:K})}removeEvent(J){this.sendMessage("removeEvent",{index:J})}async getEvents(){return(await this._fetchFromWorker({target:"getEvents"})).events??[]}styleOverride(J){this.sendMessage("styleOverride",{style:J})}disableStyleOverride(){this.sendMessage("disableStyleOverride")}createStyle(J){this.sendMessage("createStyle",{style:J})}setStyle(J,K){this.sendMessage("setStyle",{style:J,index:K})}removeStyle(J){this.sendMessage("removeStyle",{index:J})}async getStyles(){return(await this._fetchFromWorker({target:"getStyles"})).styles??[]}addFont(J){this.sendMessage("addFont",{font:J})}setDefaultFont(J){this.sendMessage("defaultFont",{font:J})}async getStats(){let K=(await this._fetchFromWorker({target:"getStats"})).stats;return{framesRendered:K.framesRendered??0,framesDropped:K.framesDropped??0,avgRenderTime:K.avgRenderTime??0,maxRenderTime:K.maxRenderTime??0,minRenderTime:K.minRenderTime??0,lastRenderTime:K.lastRenderTime??0,pendingRenders:K.pendingRenders??0,totalEvents:K.totalEvents??0,cacheHits:K.cacheHits??0,cacheMisses:K.cacheMisses??0,renderFps:K.avgRenderTime&&K.avgRenderTime>0?Math.round(1000/K.avgRenderTime):0,usingWorker:!0,offscreenRender:this._offscreenRender,onDemandRender:this._onDemandRender}}async resetStats(){await this._fetchFromWorker({target:"resetStats"})}async getEventCount(){return(await this._fetchFromWorker({target:"getEventCount"})).count}async getStyleCount(){return(await this._fetchFromWorker({target:"getStyleCount"})).count}_sendLocalFont(J){try{globalThis.queryLocalFonts().then((K)=>{let Z=K?.find((N)=>N.fullName.toLowerCase()===J);if(Z)Z.blob().then((N)=>{N.arrayBuffer().then((Q)=>{this.addFont(new Uint8Array(Q))})})})}catch(K){console.warn("Local fonts API:",K)}}_getLocalFont(J){try{if(navigator?.permissions?.query)navigator.permissions.query({name:"local-fonts"}).then((K)=>{if(K.state==="granted")this._sendLocalFont(J.font)});else this._sendLocalFont(J.font)}catch(K){console.warn("Local fonts API:",K)}}_unbusy(){if(this._pendingDemandTimes.length>0){if(this._pendingDemandTimes.length>1){let K=this._pendingDemandTimes[this._pendingDemandTimes.length-1];this._pendingDemandTimes.length=0,this._pendingDemandTimes.push(K)}let J=this._pendingDemandTimes.shift();if(J){this._demandRender(J);return}}this.busy=!1}_enqueueDemand(J){let K=this._pendingDemandTimes;if(K.length>0){let Z=K[K.length-1];if(Math.abs(Z.mediaTime-J.mediaTime)>0.25)K.length=0}if(K.length>=R.MAX_PENDING_DEMANDS)K.shift();K.push(J)}_handleRVFC(J,K){if(this._destroyed)return;let Z=this._video?.playbackRate??1,Q={mediaTime:K.mediaTime+this.renderAhead*Z,width:K.width,height:K.height};if(!this._workerReady){this._enqueueDemand(Q),this._video.requestVideoFrameCallback(this._boundHandleRVFC);return}if(this.busy)this._enqueueDemand(Q);else this.busy=!0,this._demandRender(Q);this._video.requestVideoFrameCallback(this._boundHandleRVFC)}_demandRender(J){if(J.width!==this._videoWidth||J.height!==this._videoHeight)this._videoWidth=J.width,this._videoHeight=J.height,this.resize();this.sendMessage("demand",{time:J.mediaTime+this.timeOffset})}_detachOffscreen(){if(!this._offscreenRender||this._ctx)return;this._canvas.remove(),this._createCanvas(),this._canvasctrl=this._canvas,this._ctx=this._canvasctrl.getContext("2d"),this.sendMessage("detachOffscreen"),this.busy=!1,this._pendingDemandTimes.length=0,this.resize(0,0,0,0,!0)}_reAttachOffscreen(){if(!this._offscreenRender||!this._ctx)return;this._canvas.remove(),this._createCanvas(),this._canvasctrl=this._canvas.transferControlToOffscreen(),this._ctx=!1,this.sendMessage("offscreenCanvas",{},[this._canvasctrl]),this.resize(0,0,0,0,!0)}_updateColorSpace(){this._video.requestVideoFrameCallback(()=>{try{let J=new globalThis.VideoFrame(this._video);this._videoColorSpace=u[J.colorSpace.matrix]??null,J.close(),this.sendMessage("getColorSpace")}catch(J){console.warn(J)}})}_verifyColorSpace(J){let{subtitleColorSpace:K,videoColorSpace:Z=this._videoColorSpace}=J;if(!K||!Z)return;if(K===Z)return;this._detachOffscreen();let N=y[K]?.[Z];if(N&&this._ctx)this._ctx.filter=`url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix type='matrix' values='${N} 0 0 0 0 0 1 0'/></filter></svg>#f")`}_render(J){this._unbusy();let{width:K,height:Z}=J;if(this.debug)J.times.IPCTime=Date.now()-(J.times.JSRenderTime||0);if(this._canvasctrl.width!==K||this._canvasctrl.height!==Z){if(this._canvasctrl.width=K,this._canvasctrl.height=Z,this._lastRenderWidth=K,this._lastRenderHeight=Z,this._gpuRenderer)this._gpuRenderer.updateSize(K,Z);this._verifyColorSpace({subtitleColorSpace:J.colorSpace})}if(this._gpuRenderer){this._renderGPU(J);return}if(!this._ctx)return;let Q=this._ctx,F=J.images,$=F.length;if(Q.clearRect(0,0,K,Z),J.asyncRender)for(let U=0;U<$;U++){let O=F[U];if(O.image)Q.drawImage(O.image,O.x,O.y),O.image.close()}else{let U=R._hasAlphaBug??!1;for(let O=0;O<$;O++){let E=F[O];if(E.image){let{w:q,h:L}=E,_=new Uint8ClampedArray(E.image),Y=m(_,U);Q.putImageData(new ImageData(Y,q,L),E.x,E.y)}}}if(this.debug){J.times.JSRenderTime=Date.now()-(J.times.JSRenderTime||0)-(J.times.IPCTime||0);let U=0,O=J.times.bitmaps||$;delete J.times.bitmaps;for(let E in J.times)U+=J.times[E]||0;console.log("Bitmaps: "+O+" Total: "+(U|0)+"ms",J.times)}}_renderGPU(J){let K=this._gpuRenderer;if(!K)return;if(J.images.length===0){K.clear();return}if(J.asyncRender){let Z=J.images.filter((N)=>N.image instanceof ImageBitmap).map((N)=>({image:N.image,x:N.x,y:N.y}));K.renderBitmaps(Z,this._canvasctrl.width,this._canvasctrl.height);for(let N of J.images)if(N.image instanceof ImageBitmap)N.image.close()}else K.render(J.images,this._canvasctrl.width,this._canvasctrl.height);if(this.debug){J.times.JSRenderTime=Date.now()-(J.times.JSRenderTime||0)-(J.times.IPCTime||0);let Z=0,N=J.times.bitmaps||J.images.length;delete J.times.bitmaps;for(let Q in J.times)Z+=J.times[Q]||0;console.log(`[${this._rendererType.toUpperCase()}] Bitmaps: `+N+" Total: "+(Z|0)+"ms",J.times)}}_ready(){if(this._workerReady=!0,this._init(),this._onDemandRender&&this._video){this.setCurrentTime(this._video.paused,this._video.currentTime+this.timeOffset,this._video.playbackRate);let J=this._pendingDemandTimes.length>0?this._pendingDemandTimes[this._pendingDemandTimes.length-1]:{mediaTime:this._video.currentTime+this.renderAhead*(this._video.playbackRate||1),width:this._video.videoWidth,height:this._video.videoHeight};this._pendingDemandTimes.length=0,this.busy=!0,this._demandRender(J)}this.dispatchEvent(new CustomEvent("ready"))}_partial_ready(){this.dispatchEvent(new CustomEvent("partial_ready"))}async sendMessage(J,K={},Z){if(await this._loaded,Z)this._worker.postMessage({target:J,transferable:Z,...K},[...Z]);else this._worker.postMessage({target:J,...K})}_fetchFromWorker(J){return new Promise((K,Z)=>{try{let N=J.target,Q=setTimeout(()=>{U(),Z(Error("Error: Timeout while trying to fetch "+N))},5000),F=(O)=>{if(O.data.target===N)U(),K(O.data)},$=(O)=>{U(),Z(O instanceof Error?O:O.error||Error("Worker error"))},U=()=>{this._worker.removeEventListener("message",F),this._worker.removeEventListener("error",$),clearTimeout(Q)};this._worker.addEventListener("message",F),this._worker.addEventListener("error",$),this._worker.postMessage(J)}catch(N){Z(N)}})}_console(J){console[J.command].apply(console,JSON.parse(J.content))}_onmessage(J){let K=J.data.target;if(K==="error"){this._error(J.data.error||"Unknown worker error");return}let Z=this["_"+K];if(Z)Z.call(this,J.data)}_error(J){let K=J instanceof Error?J:J instanceof ErrorEvent?J.error||Error(J.message):Error(String(J)),Z=J instanceof Event?new ErrorEvent(J.type,J):new ErrorEvent("error",{error:K});return this.dispatchEvent(Z),console.error(K),K}_removeListeners(){if(this._video){if(this._ro)this._ro.unobserve(this._video);if(this._ctx)this._ctx.filter="none";this._video.removeEventListener("timeupdate",this._boundTimeUpdate),this._video.removeEventListener("progress",this._boundTimeUpdate),this._video.removeEventListener("waiting",this._boundTimeUpdate),this._video.removeEventListener("seeking",this._boundTimeUpdate),this._video.removeEventListener("playing",this._boundTimeUpdate),this._video.removeEventListener("ratechange",this._boundSetRate),this._video.removeEventListener("resize",this._boundResize),this._video.removeEventListener("loadedmetadata",this._boundUpdateColorSpace)}}destroy(J){let K=J?this._error(J):void 0;if(this._video&&this._canvasParent)this._video.parentNode?.removeChild(this._canvasParent);if(this._gpuRenderer)this._gpuRenderer.destroy(),this._gpuRenderer=null,this._rendererType="canvas2d";return this._destroyed=!0,this._removeListeners(),this.sendMessage("destroy"),this._worker?.terminate(),K}}export{u as webYCbCrMap,l as testImageBugs,e as runFeatureTests,o as parseAss,g as libassYCbCrMap,f as isWebGPUSupported,p as isWebGL2Supported,c as getVideoPosition,s as getColorSpaceFilterUrl,KJ as getBitmapBug,JJ as getAlphaBug,t as fixPlayRes,m as fixAlpha,n as dropBlur,R as default,w as computeCanvasSize,y as colorMatrixConversionMap,v as WebGPURenderer,x as WebGL2Renderer,R as AkariSub};
147
+ `),$=J.createProgram();if(J.attachShader($,Z),J.attachShader($,Q),J.linkProgram($),!J.getProgramParameter($,J.LINK_STATUS))throw Error(`WebGL2 program link failed: ${J.getProgramInfoLog($)}`);J.deleteShader(Z),J.deleteShader(Q),this._program=$,this._resolutionLoc=J.getUniformLocation($,"u_resolution"),this._texArraySizeLoc=J.getUniformLocation($,"u_texArraySize"),this._vao=J.createVertexArray(),J.bindVertexArray(this._vao),this._instanceBuffer=J.createBuffer(),J.bindBuffer(J.ARRAY_BUFFER,this._instanceBuffer),J.bufferData(J.ARRAY_BUFFER,8192,J.DYNAMIC_DRAW);let O=J.getAttribLocation($,"a_destRect");J.enableVertexAttribArray(O),J.vertexAttribPointer(O,4,J.FLOAT,!1,32,0),J.vertexAttribDivisor(O,1);let N=J.getAttribLocation($,"a_texInfo");J.enableVertexAttribArray(N),J.vertexAttribPointer(N,4,J.FLOAT,!1,32,16),J.vertexAttribDivisor(N,1),J.bindVertexArray(null),this._texArray=J.createTexture(),this._allocateTextureArray(256,256,32),J.enable(J.BLEND),J.blendEquation(J.FUNC_ADD),J.blendFunc(J.ONE,J.ONE_MINUS_SRC_ALPHA),this._initialized=!0}_nextPow2(J){return J--,J|=J>>1,J|=J>>2,J|=J>>4,J|=J>>8,J|=J>>16,J+1}_allocateTextureArray(J,Z,Q){let $=this._gl,O=this._nextPow2(Math.max(J,64)),N=this._nextPow2(Math.max(Z,64)),K=Math.min(this._nextPow2(Math.max(Q,16)),256);$.bindTexture($.TEXTURE_2D_ARRAY,this._texArray),$.texImage3D($.TEXTURE_2D_ARRAY,0,$.RGBA8,O,N,K,0,$.RGBA,$.UNSIGNED_BYTE,null),$.texParameteri($.TEXTURE_2D_ARRAY,$.TEXTURE_MIN_FILTER,$.NEAREST),$.texParameteri($.TEXTURE_2D_ARRAY,$.TEXTURE_MAG_FILTER,$.NEAREST),$.texParameteri($.TEXTURE_2D_ARRAY,$.TEXTURE_WRAP_S,$.CLAMP_TO_EDGE),$.texParameteri($.TEXTURE_2D_ARRAY,$.TEXTURE_WRAP_T,$.CLAMP_TO_EDGE),this._texWidth=O,this._texHeight=N,this._texLayers=K}_ensureTextureArray(J,Z,Q){let $=Math.min(Q,256);if(J<=this._texWidth&&Z<=this._texHeight&&$<=this._texLayers)return;let O=this._nextPow2(Math.max(this._texWidth,J)),N=this._nextPow2(Math.max(this._texHeight,Z)),K=Math.min(this._nextPow2(Math.max(this._texLayers,$,$+16)),256);this._allocateTextureArray(O,N,K)}async setCanvas(J,Z,Q){if(await this.init(),Z<=0||Q<=0)return;this._canvas=J,J.width=Z,J.height=Q,this._initGL(),this._gl.viewport(0,0,Z,Q),this._lastCanvasWidth=Z,this._lastCanvasHeight=Q}updateSize(J,Z){if(!this._gl||!this._canvas||J<=0||Z<=0)return;if(J===this._lastCanvasWidth&&Z===this._lastCanvasHeight)return;this._canvas.width=J,this._canvas.height=Z,this._gl.viewport(0,0,J,Z),this._lastCanvasWidth=J,this._lastCanvasHeight=Z}renderBitmaps(J,Z,Q){if(!this._gl||!this._initialized)return;let $=J.length;if($===0){this.clear();return}let O=0,N=0;for(let U=0;U<$;U++){let{image:E}=J[U];if(E.width>O)O=E.width;if(E.height>N)N=E.height}this._ensureTextureArray(O,N,Math.min($,256));let K=this._gl;K.clearColor(0,0,0,0),K.clear(K.COLOR_BUFFER_BIT),K.useProgram(this._program),K.uniform2f(this._resolutionLoc,this._lastCanvasWidth,this._lastCanvasHeight),K.uniform2i(this._texArraySizeLoc,this._texWidth,this._texHeight),K.activeTexture(K.TEXTURE0),K.bindTexture(K.TEXTURE_2D_ARRAY,this._texArray),K.pixelStorei(K.UNPACK_FLIP_Y_WEBGL,!1);let F=this._instanceData,G=0;while(G<$){let U=0;while(G<$&&U<256){let E=J[G++],T=E.image.width,q=E.image.height;if(T<=0||q<=0)continue;K.texSubImage3D(K.TEXTURE_2D_ARRAY,0,0,0,U,T,q,1,K.RGBA,K.UNSIGNED_BYTE,E.image);let Y=U<<3;F[Y]=E.x,F[Y+1]=E.y,F[Y+2]=T,F[Y+3]=q,F[Y+4]=T,F[Y+5]=q,F[Y+6]=U,F[Y+7]=0,U++}if(U===0)continue;K.bindBuffer(K.ARRAY_BUFFER,this._instanceBuffer),K.bufferSubData(K.ARRAY_BUFFER,0,F,0,U<<3),K.bindVertexArray(this._vao),K.drawArraysInstanced(K.TRIANGLES,0,6,U),K.bindVertexArray(null)}}render(J,Z,Q){if(!this._gl||!this._initialized)return;let $=J.length;if($===0){this.clear();return}let O=0,N=0;for(let U=0;U<$;U++){let{w:E,h:T}=J[U];if(E>O)O=E;if(T>N)N=T}this._ensureTextureArray(O,N,Math.min($,256));let K=this._gl;K.clearColor(0,0,0,0),K.clear(K.COLOR_BUFFER_BIT),K.useProgram(this._program),K.uniform2f(this._resolutionLoc,this._lastCanvasWidth,this._lastCanvasHeight),K.uniform2i(this._texArraySizeLoc,this._texWidth,this._texHeight),K.activeTexture(K.TEXTURE0),K.bindTexture(K.TEXTURE_2D_ARRAY,this._texArray),K.pixelStorei(K.UNPACK_FLIP_Y_WEBGL,!1);let F=this._instanceData,G=0;while(G<$){let U=0;while(G<$&&U<256){let E=J[G++],T=E.w,q=E.h;if(T<=0||q<=0)continue;let Y=E.image;if(Y instanceof ImageBitmap)K.texSubImage3D(K.TEXTURE_2D_ARRAY,0,0,0,U,T,q,1,K.RGBA,K.UNSIGNED_BYTE,Y);else if(Y instanceof ArrayBuffer||KJ(Y)){let B=Y instanceof ArrayBuffer?new Uint8Array(Y):Y;K.texSubImage3D(K.TEXTURE_2D_ARRAY,0,0,0,U,T,q,1,K.RGBA,K.UNSIGNED_BYTE,B)}let L=U<<3;F[L]=E.x,F[L+1]=E.y,F[L+2]=T,F[L+3]=q,F[L+4]=T,F[L+5]=q,F[L+6]=U,F[L+7]=0,U++}if(U===0)continue;K.bindBuffer(K.ARRAY_BUFFER,this._instanceBuffer),K.bufferSubData(K.ARRAY_BUFFER,0,F,0,U<<3),K.bindVertexArray(this._vao),K.drawArraysInstanced(K.TRIANGLES,0,6,U),K.bindVertexArray(null)}}clear(){if(!this._gl)return;this._gl.clearColor(0,0,0,0),this._gl.clear(this._gl.COLOR_BUFFER_BIT)}get initialized(){return this._initialized}destroy(){let J=this._gl;if(J)J.deleteProgram(this._program),J.deleteVertexArray(this._vao),J.deleteBuffer(this._instanceBuffer),J.deleteTexture(this._texArray);this._gl=null,this._program=null,this._vao=null,this._instanceBuffer=null,this._texArray=null,this._canvas=null,this._initialized=!1,this._initPromise=null}}var d=0.008,NJ=d*1000,OJ=16,GJ=()=>{if(typeof navigator>"u")return!1;let J=navigator.userAgent||"",Z=navigator.vendor||"",Q=/\b(iPhone|iPad|iPod)\b/i.test(J);if(!/AppleWebKit/i.test(J))return!1;if(Q)return!0;if(/\b(Chrome|Chromium|Edg|OPR|SamsungBrowser|Firefox)\b/i.test(J))return!1;return Z.includes("Apple")};class R extends EventTarget{static MAX_PENDING_DEMANDS=3;static _hasAlphaBug=null;static _hasBitmapBug=null;_loaded;_init;_onDemandRender;_offscreenRender;_video;_videoWidth=0;_videoHeight=0;_videoColorSpace=null;_canvas;_canvasParent;_bufferCanvas;_bufferCtx;_canvasctrl;_ctx=null;_lastRenderTime=0;_playstate=!0;_destroyed=!1;_workerReady=!1;_ro;_worker;_pendingDemandTimes=[];_isLikelyWebKit;_activeDemandStartedAt=0;_smoothedDemandLatencyMs;_boundResize;_boundTimeUpdate;_boundSetRate;_boundUpdateColorSpace;_boundHandleRVFC;_gpuRenderer=null;_rendererType="canvas2d";_onCanvasFallback;_lastRenderWidth=0;_lastRenderHeight=0;_gpuBitmapImages=[];timeOffset;debug;prescaleFactor;prescaleHeightLimit;maxRenderHeight;busy=!1;renderAhead;constructor(J){super();if(!globalThis.Worker)throw this.destroy(Error("Worker not supported"));if(!J)throw this.destroy(Error("No options provided"));this._loaded=new Promise((N)=>{this._init=N}),this._isLikelyWebKit=GJ(),this._smoothedDemandLatencyMs=this._isLikelyWebKit?OJ:NJ;let Z=R._test();this._onDemandRender="requestVideoFrameCallback"in HTMLVideoElement.prototype&&(J.onDemandRender??!0),this._onCanvasFallback=J.onCanvasFallback;let Q=!this._isLikelyWebKit&&!J.canvas&&(f()||p()),$=typeof createImageBitmap<"u"&&(J.asyncRender??!this._isLikelyWebKit);if(this._offscreenRender="transferControlToOffscreen"in HTMLCanvasElement.prototype&&!J.canvas&&!Q&&(J.offscreenRender??!0),this.timeOffset=J.timeOffset||0,this._video=J.video,this._canvas=J.canvas,this._video&&!this._canvas)this._canvasParent=document.createElement("div"),this._canvasParent.className="AkariSub",this._canvasParent.style.position="relative",this._canvas=this._createCanvas(),this._video.insertAdjacentElement("afterend",this._canvasParent);else if(!this._canvas)throw this.destroy(Error("Don't know where to render: you should give video or canvas in options."));this._bufferCanvas=document.createElement("canvas");let O=this._bufferCanvas.getContext("2d");if(!O)throw this.destroy(Error("Canvas rendering not supported"));if(this._bufferCtx=O,Q)this._initGPURenderer();else if(!this._offscreenRender)this._ctx=this._canvas.getContext("2d",{alpha:!0,desynchronized:!0});if(this._canvasctrl=this._offscreenRender?this._canvas.transferControlToOffscreen():this._canvas,this._lastRenderTime=0,this.debug=!!J.debug,this.prescaleFactor=J.prescaleFactor||1,this.prescaleHeightLimit=J.prescaleHeightLimit||1080,this.maxRenderHeight=J.maxRenderHeight||0,this.renderAhead=J.renderAhead??d,this._boundResize=this.resize.bind(this),this._boundTimeUpdate=this._timeupdate.bind(this),this._boundSetRate=()=>this.setRate(this._video.playbackRate),this._boundUpdateColorSpace=this._updateColorSpace.bind(this),this._boundHandleRVFC=this._handleRVFC.bind(this),this._video)this.setVideo(this._video);if(this._onDemandRender)this.busy=!1,this._pendingDemandTimes.length=0;this._worker=new Worker(J.workerUrl||"akarisub-worker.js"),this._worker.onmessage=(N)=>this._onmessage(N),this._worker.onerror=(N)=>this._error(N),Z.then(()=>{let N={target:"init",wasmUrl:J.wasmUrl??"akarisub-worker.wasm",asyncRender:$,fullTrackWarmup:J.fullTrackWarmup??!1,onDemandRender:this._onDemandRender,initialTime:(this._video?.currentTime??0)+this.timeOffset,width:this._canvasctrl.width||0,height:this._canvasctrl.height||0,blendMode:J.blendMode??"wasm",subUrl:J.subUrl,subContent:J.subContent||null,encryptedSubContent:J.encryptedSubContent||null,fonts:J.fonts||[],availableFonts:J.availableFonts||{"liberation sans":"./default.woff2"},fallbackFonts:J.fallbackFonts||["liberation sans"],debug:this.debug,targetFps:J.targetFps||24,dropAllAnimations:J.dropAllAnimations,dropAllBlur:J.dropAllBlur,clampPos:J.clampPos,libassMemoryLimit:J.libassMemoryLimit??128,libassGlyphLimit:J.libassGlyphLimit??2048,useLocalFonts:typeof globalThis.queryLocalFonts<"u"&&(J.useLocalFonts??!0),hasBitmapBug:R._hasBitmapBug};if(this._worker.postMessage(N,R._getSubtitleTransfers(J.subContent,J.encryptedSubContent)),this._offscreenRender)this.sendMessage("offscreenCanvas",{},[this._canvasctrl])})}static async _testImageBugs(){if(R._hasBitmapBug!==null)return;let J=document.createElement("canvas"),Z=J.getContext("2d",{willReadFrequently:!0});if(!Z)throw Error("Canvas rendering not supported");if(typeof ImageData.prototype.constructor==="function")try{new ImageData(new Uint8ClampedArray([0,0,0,0]),1,1)}catch{console.log("Detected that ImageData is not constructable despite browser saying so")}let Q=document.createElement("canvas"),$=Q.getContext("2d",{willReadFrequently:!0});if(!$)throw Error("Canvas rendering not supported");J.width=Q.width=1,J.height=Q.height=1,Z.clearRect(0,0,1,1),$.clearRect(0,0,1,1);let O=$.getImageData(0,0,1,1).data;Z.putImageData(new ImageData(new Uint8ClampedArray([0,255,0,0]),1,1),0,0),$.drawImage(J,0,0);let N=$.getImageData(0,0,1,1).data;if(R._hasAlphaBug=O[1]!==N[1],R._hasAlphaBug)console.log("Detected a browser having issue with transparent pixels, applying workaround");if(typeof createImageBitmap<"u"){let K=new Uint8ClampedArray([255,0,255,0,255]).subarray(1,5);$.drawImage(await createImageBitmap(new ImageData(K,1)),0,0);let{data:F}=$.getImageData(0,0,1,1);R._hasBitmapBug=!1;for(let G=0;G<F.length;G++)if(Math.abs(K[G]-F[G])>15){R._hasBitmapBug=!0,console.log("Detected a browser having issue with partial bitmaps, applying workaround");break}}else R._hasBitmapBug=!1;J.remove(),Q.remove()}static async _test(){await R._testImageBugs()}static _getSubtitleTransfers(J,Z){let Q=[];if(J instanceof ArrayBuffer)Q.push(J);else if(J instanceof Uint8Array)Q.push(J.buffer);if(Z?.encrypted)Q.push(Z.encrypted);for(let $ of Z?.encryptedChunks||[])Q.push($);return Q}async _initGPURenderer(){if(f())try{let J=new v;if(await J.init(),!this._canvas)return;await J.setCanvas(this._canvas,Math.max(1,this._canvas.width||1),Math.max(1,this._canvas.height||1)),this._gpuRenderer=J,this._rendererType="webgpu",console.log("[AkariSub] Using WebGPU renderer");return}catch(J){console.warn("[AkariSub] WebGPU init failed, trying WebGL2:",J)}if(p())try{let J=new x;if(await J.init(),!this._canvas)return;await J.setCanvas(this._canvas,Math.max(1,this._canvas.width||1),Math.max(1,this._canvas.height||1)),this._gpuRenderer=J,this._rendererType="webgl2",console.log("[AkariSub] Using WebGL2 renderer");return}catch(J){console.warn("[AkariSub] WebGL2 init failed, falling back to Canvas2D:",J)}if(this._rendererType="canvas2d",!this._offscreenRender&&!this._ctx)this._ctx=this._canvas.getContext("2d",{alpha:!0,desynchronized:!0});this.sendMessage("setAsyncRender",{value:!1}),this._onCanvasFallback?.()}get rendererType(){return this._rendererType}get isUsingWebGPU(){return this._rendererType==="webgpu"}get isUsingGPURenderer(){return this._gpuRenderer!==null}_createCanvas(){return this._canvas=document.createElement("canvas"),this._canvas.style.display="block",this._canvas.style.position="absolute",this._canvas.style.pointerEvents="none",this._canvasParent.appendChild(this._canvas),this._canvas}resize(J=0,Z=0,Q=0,$=0,O=this._video?.paused??!1){if((!J||!Z)&&this._video){let N=c(this._video),K;if(this._videoWidth){let F=this._video.videoWidth/this._videoWidth,G=this._video.videoHeight/this._videoHeight;K=w((N.width||0)/F,(N.height||0)/G,this.prescaleFactor,this.prescaleHeightLimit,this.maxRenderHeight)}else K=w(N.width||0,N.height||0,this.prescaleFactor,this.prescaleHeightLimit,this.maxRenderHeight);if(J=K.width,Z=K.height,this._canvasParent)Q=N.y-(this._canvasParent.getBoundingClientRect().top-this._video.getBoundingClientRect().top),$=N.x;this._canvas.style.width=N.width+"px",this._canvas.style.height=N.height+"px"}if(this._canvas.style.top=Q+"px",this._canvas.style.left=$+"px",J>0&&Z>0)this._canvasctrl.width=J,this._canvasctrl.height=Z;if(this._gpuRenderer&&J>0&&Z>0)this._gpuRenderer.updateSize(J,Z);if(O&&this.busy===!1)this.busy=!0;else O=!1;this.sendMessage("canvas",{width:J,height:Z,videoWidth:this._videoWidth||this._video?.videoWidth||0,videoHeight:this._videoHeight||this._video?.videoHeight||0,force:O})}_timeupdate(J){let Q={seeking:!0,waiting:!0,playing:!1}[J.type];if(Q!=null)this._playstate=Q;this.setCurrentTime(this._video.paused||this._playstate,this._video.currentTime+this.timeOffset)}setVideo(J){if(J instanceof HTMLVideoElement){if(this._removeListeners(),this._video=J,this._onDemandRender){if(!this._destroyed&&this._video===J)J.requestVideoFrameCallback(this._boundHandleRVFC)}else this._playstate=J.paused,J.addEventListener("timeupdate",this._boundTimeUpdate,!1),J.addEventListener("progress",this._boundTimeUpdate,!1),J.addEventListener("waiting",this._boundTimeUpdate,!1),J.addEventListener("seeking",this._boundTimeUpdate,!1),J.addEventListener("playing",this._boundTimeUpdate,!1),J.addEventListener("ratechange",this._boundSetRate,!1),J.addEventListener("resize",this._boundResize,!1);if("VideoFrame"in window){if(J.addEventListener("loadedmetadata",this._boundUpdateColorSpace,!1),J.readyState>2)this._updateColorSpace()}if(J.videoWidth>0)this.resize();if(typeof ResizeObserver<"u"){if(!this._ro)this._ro=new ResizeObserver(()=>this.resize());this._ro.observe(J)}}else this._error(Error("Video element invalid!"))}runBenchmark(){this.sendMessage("runBenchmark")}setTrackByUrl(J){if(this.sendMessage("setTrackByUrl",{url:J}),this._reAttachOffscreen(),this._ctx)this._ctx.filter="none"}setTrack(J){if(this.sendMessage("setTrack",{content:J},R._getSubtitleTransfers(J)),this._reAttachOffscreen(),this._ctx)this._ctx.filter="none"}setEncryptedTrack(J){if(this.sendMessage("setEncryptedTrack",{content:J},R._getSubtitleTransfers(void 0,J)),this._reAttachOffscreen(),this._ctx)this._ctx.filter="none"}freeTrack(){this.sendMessage("freeTrack")}setIsPaused(J){this.sendMessage("video",{isPaused:J})}setRate(J){this.sendMessage("video",{rate:J})}setCurrentTime(J,Z,Q){this.sendMessage("video",{isPaused:J,currentTime:Z,rate:Q,colorSpace:this._videoColorSpace})}createEvent(J){this.sendMessage("createEvent",{event:J})}setEvent(J,Z){this.sendMessage("setEvent",{event:J,index:Z})}removeEvent(J){this.sendMessage("removeEvent",{index:J})}async getEvents(){return(await this._fetchFromWorker({target:"getEvents"})).events??[]}styleOverride(J){this.sendMessage("styleOverride",{style:J})}disableStyleOverride(){this.sendMessage("disableStyleOverride")}createStyle(J){this.sendMessage("createStyle",{style:J})}setStyle(J,Z){this.sendMessage("setStyle",{style:J,index:Z})}removeStyle(J){this.sendMessage("removeStyle",{index:J})}async getStyles(){return(await this._fetchFromWorker({target:"getStyles"})).styles??[]}addFont(J){this.sendMessage("addFont",{font:J})}setDefaultFont(J){this.sendMessage("defaultFont",{font:J})}async getStats(){let Z=(await this._fetchFromWorker({target:"getStats"})).stats;return{framesRendered:Z.framesRendered??0,framesDropped:Z.framesDropped??0,avgRenderTime:Z.avgRenderTime??0,maxRenderTime:Z.maxRenderTime??0,minRenderTime:Z.minRenderTime??0,lastRenderTime:Z.lastRenderTime??0,pendingRenders:Z.pendingRenders??0,totalEvents:Z.totalEvents??0,cacheHits:Z.cacheHits??0,cacheMisses:Z.cacheMisses??0,renderFps:Z.avgRenderTime&&Z.avgRenderTime>0?Math.round(1000/Z.avgRenderTime):0,usingWorker:!0,offscreenRender:this._offscreenRender,onDemandRender:this._onDemandRender}}async resetStats(){await this._fetchFromWorker({target:"resetStats"})}async getEventCount(){return(await this._fetchFromWorker({target:"getEventCount"})).count}async getStyleCount(){return(await this._fetchFromWorker({target:"getStyleCount"})).count}_sendLocalFont(J){try{globalThis.queryLocalFonts().then((Z)=>{let Q=Z?.find(($)=>$.fullName.toLowerCase()===J);if(Q)Q.blob().then(($)=>{$.arrayBuffer().then((O)=>{this.addFont(new Uint8Array(O))})})})}catch(Z){console.warn("Local fonts API:",Z)}}_getLocalFont(J){try{if(navigator?.permissions?.query)navigator.permissions.query({name:"local-fonts"}).then((Z)=>{if(Z.state==="granted")this._sendLocalFont(J.font)});else this._sendLocalFont(J.font)}catch(Z){console.warn("Local fonts API:",Z)}}_unbusy(){if(this._observeDemandCompletion(),this._pendingDemandTimes.length>0){if(this._pendingDemandTimes.length>1){let Z=this._pendingDemandTimes[this._pendingDemandTimes.length-1];this._pendingDemandTimes.length=0,this._pendingDemandTimes.push(Z)}let J=this._pendingDemandTimes.shift();if(J){this._demandRender(J);return}}this.busy=!1}_markDemandDispatched(){if(!this._onDemandRender)return;this._activeDemandStartedAt=performance.now()}_observeDemandCompletion(){if(!this._onDemandRender||this._activeDemandStartedAt===0)return;let J=performance.now()-this._activeDemandStartedAt;if(this._activeDemandStartedAt=0,!Number.isFinite(J)||J<=0)return;this._smoothedDemandLatencyMs=this._smoothedDemandLatencyMs<=0?J:this._smoothedDemandLatencyMs*0.75+J*0.25}_getDemandPipelineLeadSeconds(J,Z){let Q=Z.expectedDisplayTime??Z.presentationTime??J,$=Math.max(0,Q-J)/1000;return Math.max(0,this._smoothedDemandLatencyMs/1000-$)}_enqueueDemand(J){let Z=this._pendingDemandTimes;if(Z.length>0){let Q=Z[Z.length-1];if(Math.abs(Q.mediaTime-J.mediaTime)>0.25)Z.length=0}if(Z.length>=R.MAX_PENDING_DEMANDS)Z.shift();Z.push(J)}_handleRVFC(J,Z){if(this._destroyed)return;let Q=this._video?.playbackRate??1,$=this._getDemandPipelineLeadSeconds(J,Z),N={mediaTime:Z.mediaTime+($+this.renderAhead)*Q,width:Z.width,height:Z.height};if(!this._workerReady){this._enqueueDemand(N),this._video.requestVideoFrameCallback(this._boundHandleRVFC);return}if(this.busy)this._enqueueDemand(N);else this.busy=!0,this._demandRender(N);this._video.requestVideoFrameCallback(this._boundHandleRVFC)}_demandRender(J){if(J.width!==this._videoWidth||J.height!==this._videoHeight)this._videoWidth=J.width,this._videoHeight=J.height,this.resize();this._markDemandDispatched(),this.sendMessage("demand",{time:J.mediaTime+this.timeOffset})}_detachOffscreen(){if(!this._offscreenRender||this._ctx)return;this._canvas.remove(),this._createCanvas(),this._canvasctrl=this._canvas,this._ctx=this._canvasctrl.getContext("2d",{alpha:!0,desynchronized:!0}),this.sendMessage("detachOffscreen"),this.busy=!1,this._activeDemandStartedAt=0,this._pendingDemandTimes.length=0,this.resize(0,0,0,0,!0)}_reAttachOffscreen(){if(!this._offscreenRender||!this._ctx)return;this._canvas.remove(),this._createCanvas(),this._canvasctrl=this._canvas.transferControlToOffscreen(),this._ctx=!1,this.sendMessage("offscreenCanvas",{},[this._canvasctrl]),this.resize(0,0,0,0,!0)}_updateColorSpace(){this._video.requestVideoFrameCallback(()=>{try{let J=new globalThis.VideoFrame(this._video);this._videoColorSpace=u[J.colorSpace.matrix]??null,J.close(),this.sendMessage("getColorSpace")}catch(J){console.warn(J)}})}_verifyColorSpace(J){let{subtitleColorSpace:Z,videoColorSpace:Q=this._videoColorSpace}=J;if(!Z||!Q)return;if(Z===Q)return;this._detachOffscreen();let $=y[Z]?.[Q];if($&&this._ctx)this._ctx.filter=`url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix type='matrix' values='${$} 0 0 0 0 0 1 0'/></filter></svg>#f")`}_render(J){try{let{width:Z,height:Q}=J;if(this.debug)J.times.IPCTime=Date.now()-(J.times.JSRenderTime||0);if(this._canvasctrl.width!==Z||this._canvasctrl.height!==Q){if(this._canvasctrl.width=Z,this._canvasctrl.height=Q,this._lastRenderWidth=Z,this._lastRenderHeight=Q,this._gpuRenderer)this._gpuRenderer.updateSize(Z,Q);this._verifyColorSpace({subtitleColorSpace:J.colorSpace})}if(this._gpuRenderer){this._renderGPU(J);return}if(!this._ctx)return;let O=this._ctx,N=J.images,K=N.length;if(O.clearRect(0,0,Z,Q),J.asyncRender)for(let F=0;F<K;F++){let G=N[F];if(G.image)O.drawImage(G.image,G.x,G.y),G.image.close()}else{let F=R._hasAlphaBug??!1;for(let G=0;G<K;G++){let U=N[G];if(U.image){let{w:E,h:T,image:q}=U,Y=q instanceof Uint8ClampedArray?q:q instanceof Uint8Array?new Uint8ClampedArray(q.buffer,q.byteOffset,q.byteLength):new Uint8ClampedArray(q),L=m(Y,F);O.putImageData(new ImageData(L,E,T),U.x,U.y)}}}if(this.debug){J.times.JSRenderTime=Date.now()-(J.times.JSRenderTime||0)-(J.times.IPCTime||0);let F=0,G=J.times.bitmaps||K;delete J.times.bitmaps;for(let U in J.times)F+=J.times[U]||0;console.log("Bitmaps: "+G+" Total: "+(F|0)+"ms",J.times)}}finally{this._unbusy()}}_renderGPU(J){let Z=this._gpuRenderer;if(!Z)return;if(J.images.length===0){Z.clear();return}if(J.asyncRender){let Q=this._gpuBitmapImages,$=0;for(let O=0;O<J.images.length;O++){let N=J.images[O];if(!(N.image instanceof ImageBitmap))continue;let K=Q[$]||(Q[$]={image:N.image,x:0,y:0});K.image=N.image,K.x=N.x,K.y=N.y,$++}Q.length=$,Z.renderBitmaps(Q,this._canvasctrl.width,this._canvasctrl.height);for(let O of J.images)if(O.image instanceof ImageBitmap)O.image.close()}else Z.render(J.images,this._canvasctrl.width,this._canvasctrl.height);if(this.debug){J.times.JSRenderTime=Date.now()-(J.times.JSRenderTime||0)-(J.times.IPCTime||0);let Q=0,$=J.times.bitmaps||J.images.length;delete J.times.bitmaps;for(let O in J.times)Q+=J.times[O]||0;console.log(`[${this._rendererType.toUpperCase()}] Bitmaps: `+$+" Total: "+(Q|0)+"ms",J.times)}}_ready(){if(this._workerReady=!0,this._init(),this._onDemandRender&&this._video){this.setCurrentTime(this._video.paused,this._video.currentTime+this.timeOffset,this._video.playbackRate);let J=this._pendingDemandTimes.length>0?this._pendingDemandTimes[this._pendingDemandTimes.length-1]:{mediaTime:this._video.currentTime+this.renderAhead*(this._video.playbackRate||1),width:this._video.videoWidth,height:this._video.videoHeight};this._pendingDemandTimes.length=0,this.busy=!0,this._demandRender(J)}this.dispatchEvent(new CustomEvent("ready"))}_partial_ready(){this.dispatchEvent(new CustomEvent("partial_ready"))}_trackReady(){this.dispatchEvent(new CustomEvent("trackReady"))}async sendMessage(J,Z={},Q){if(await this._loaded,Q)this._worker.postMessage({target:J,transferable:Q,...Z},[...Q]);else this._worker.postMessage({target:J,...Z})}_fetchFromWorker(J){return new Promise((Z,Q)=>{try{let $=J.target,O=setTimeout(()=>{F(),Q(Error("Error: Timeout while trying to fetch "+$))},5000),N=(G)=>{if(G.data.target===$)F(),Z(G.data)},K=(G)=>{F(),Q(G instanceof Error?G:G.error||Error("Worker error"))},F=()=>{this._worker.removeEventListener("message",N),this._worker.removeEventListener("error",K),clearTimeout(O)};this._worker.addEventListener("message",N),this._worker.addEventListener("error",K),this._worker.postMessage(J)}catch($){Q($)}})}_console(J){console[J.command].apply(console,JSON.parse(J.content))}_onmessage(J){let Z=J.data.target;if(Z==="error"){this._error(J.data.error||"Unknown worker error");return}let Q=this["_"+Z];if(Q)Q.call(this,J.data)}_error(J){let Z=J instanceof Error?J:J instanceof ErrorEvent?J.error||Error(J.message):Error(String(J)),Q=J instanceof Event?new ErrorEvent(J.type,J):new ErrorEvent("error",{error:Z});return this.dispatchEvent(Q),console.error(Z),Z}_removeListeners(){if(this._video){if(this._ro)this._ro.unobserve(this._video);if(this._ctx)this._ctx.filter="none";this._video.removeEventListener("timeupdate",this._boundTimeUpdate),this._video.removeEventListener("progress",this._boundTimeUpdate),this._video.removeEventListener("waiting",this._boundTimeUpdate),this._video.removeEventListener("seeking",this._boundTimeUpdate),this._video.removeEventListener("playing",this._boundTimeUpdate),this._video.removeEventListener("ratechange",this._boundSetRate),this._video.removeEventListener("resize",this._boundResize),this._video.removeEventListener("loadedmetadata",this._boundUpdateColorSpace)}}destroy(J){let Z=J?this._error(J):void 0;if(this._video&&this._canvasParent)this._video.parentNode?.removeChild(this._canvasParent);if(this._gpuRenderer)this._gpuRenderer.destroy(),this._gpuRenderer=null,this._rendererType="canvas2d";return this._destroyed=!0,this._removeListeners(),this.sendMessage("destroy"),this._worker?.terminate(),Z}}export{u as webYCbCrMap,l as testImageBugs,JJ as runFeatureTests,o as parseAss,s as libassYCbCrMap,f as isWebGPUSupported,p as isWebGL2Supported,c as getVideoPosition,r as getColorSpaceFilterUrl,$J as getBitmapBug,ZJ as getAlphaBug,e as fixPlayRes,m as fixAlpha,i as dropBlur,R as default,w as computeCanvasSize,y as colorMatrixConversionMap,v as WebGPURenderer,x as WebGL2Renderer,R as AkariSub};
@@ -0,0 +1,14 @@
1
+ /**
2
+ * AkariSub - JavaScript ASS/SSA Subtitle Renderer
3
+ *
4
+ * High-performance ASS/SSA subtitle renderer using libass compiled to WebAssembly.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ export { default } from './ts/akarisub';
9
+ export { default as AkariSub } from './ts/akarisub';
10
+ export type { ASSEvent, ASSStyle, AkariSubOptions, PerformanceStats, ASSEventCallback, ASSStyleCallback, PerformanceStatsCallback, ResetStatsCallback, RenderImage, RenderTimes, VideoFrameCallbackMetadata, SubtitleColorSpace, WebYCbCrColorSpace, EncryptedSubtitleContent } from './ts/types';
11
+ export { webYCbCrMap, colorMatrixConversionMap, libassYCbCrMap, computeCanvasSize, getVideoPosition, fixAlpha, parseAss, dropBlur, fixPlayRes, testImageBugs, runFeatureTests, getAlphaBug, getBitmapBug, getColorSpaceFilterUrl } from './ts/utils';
12
+ export { WebGPURenderer, isWebGPUSupported } from './ts/webgpu-renderer';
13
+ export { WebGL2Renderer, isWebGL2Supported } from './ts/webgl2-renderer';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAA;AAGnD,YAAY,EACV,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,wBAAwB,EACxB,kBAAkB,EAClB,WAAW,EACX,WAAW,EACX,0BAA0B,EAC1B,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,YAAY,CAAA;AAGnB,OAAO,EACL,WAAW,EACX,wBAAwB,EACxB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,aAAa,EACb,eAAe,EACf,WAAW,EACX,YAAY,EACZ,sBAAsB,EACvB,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAGxE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * AkariSub - JavaScript ASS/SSA Subtitle Renderer
3
+ *
4
+ * High-performance ASS/SSA subtitle renderer using libass compiled to WebAssembly.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ // Main AkariSub class
9
+ export { default } from './ts/akarisub';
10
+ export { default as AkariSub } from './ts/akarisub';
11
+ // Utility exports (for advanced usage)
12
+ export { webYCbCrMap, colorMatrixConversionMap, libassYCbCrMap, computeCanvasSize, getVideoPosition, fixAlpha, parseAss, dropBlur, fixPlayRes, testImageBugs, runFeatureTests, getAlphaBug, getBitmapBug, getColorSpaceFilterUrl } from './ts/utils';
13
+ // WebGPU renderer exports
14
+ export { WebGPURenderer, isWebGPUSupported } from './ts/webgpu-renderer';
15
+ // WebGL2 renderer exports
16
+ export { WebGL2Renderer, isWebGL2Supported } from './ts/webgl2-renderer';
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,sBAAsB;AACtB,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAA;AAoBnD,uCAAuC;AACvC,OAAO,EACL,WAAW,EACX,wBAAwB,EACxB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,aAAa,EACb,eAAe,EACf,WAAW,EACX,YAAY,EACZ,sBAAsB,EACvB,MAAM,YAAY,CAAA;AAEnB,0BAA0B;AAC1B,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAExE,0BAA0B;AAC1B,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA"}