UNPKG

@blameitonyourisp/blurrid

Version:

Generate and render blurred placeholders for lazy loaded images.

2 lines (1 loc) 18.5 kB
class e extends Error{constructor(e){super();let t="";for(const a in e)switch(a){case"name":this.name=e[a];break;case"message":t=`${e[a]}\n${t}`;break;default:{const i=`${a}: ${e[a]}`;t=`${t}${r(i,"gray",1)}\n`}}this.message=t||""}}const t=(e,{modifiers:t=[],tabs:r=0,tabSize:i=4}={})=>{let s="";for(const e of t)s=`${s}${e}`;const n=a.decorations.reset;return`${s}${" ".repeat(r*i)}${e}${n}`},r=(e,r,i=0)=>{const s=a.fgColors[r];return t(e,s?{modifiers:[s],tabs:i}:{tabs:i})},a={fgColors:{black:"",red:"",green:"",yellow:"",blue:"",magenta:"",cyan:"",white:"",gray:""},bgColors:{black:"",red:"",green:"",yellow:"",blue:"",magenta:"",cyan:"",white:"",gray:""},decorations:{reset:"",bright:"",dim:"",underline:"",blink:"",reverse:"",hidden:""}},i=t=>{const r=t[0].length,a=[];for(const i of t){if(i.length!==r)throw new e({name:"ChannelError",message:"Channel row width does not match sample width","sample-width":length,"row-width":i.length});a.push(...i)}return a};class s{#e;#t;constructor({image:e,sample:t}){this.#e=e,this.#t={...t,max:Math.max(t.width,t.height)}}resize(e){this.#e.height=Math.round(this.#e.height*e/this.#e.width),this.#e.width=e}get image(){return this.#e}get sample(){return this.#t}}class n{#r;#a;#i;#s;#n;constructor({length:e=16,size:t=Math.floor(6*e/8),buffer:r=new ArrayBuffer(t)}={}){this.#r=r,this.#a=0,this.#i=0,this.#s=0,this.#n=0}write(e,{size:t=n.#o(e),offset:r=this.#s,signed:a=!1}={}){return this.#h().append(e,{size:t,offset:r,signed:a}).isWriteable?this.#l(e,{size:t,offset:r,signed:a}):NaN}writeAbsolute(e,{offset:t=this.#s,signed:r=!1}={}){const a={value:n.#o(e),size:5};if(!this.#h().append(a.value,{...a,offset:t}).append(e,{signed:r}).isWriteable)return NaN;this.#l(a.value,{...a,offset:t});return this.#l(e,{signed:r})}writeRelative(e,{offset:t=this.#s,signed:r=!1}={}){0===e&&(e=1);const a=n.#o(e)-this.#n,i={value:a>0?1<<a>>>0:0,size:Math.abs(a)+1};if(!this.#h().append(i.value,{...i,offset:t}).append(e,{signed:r}).isWriteable)return NaN;this.#l(i.value,{...i,offset:t});return this.#l(e,{signed:r})}writeString(e,{offset:t=this.#s}={}){const r={value:n.#o(e.length),size:5};let a=this.#h().append(r.value,{...r}).append(e.length);for(let t=0;t<e.length;t++)a=a.append(0,{size:8});if(!a.isWriteable)return"";this.#l(r.value,{...r,offset:t}),this.#l(e.length);for(const t of e)this.#l(t.charCodeAt(0),{size:8});return e}read(e,{offset:t=this.#a,signed:r=!1}={}){return this.#d().append(e,{offset:t,signed:r}).isReadable?this.#c(e,{offset:t,signed:r}):NaN}readAbsolute({offset:e=this.#a,signed:t=!1}={}){const r=this.#a,a=this.#i,i=this.#d().append(5,{offset:e});let s=0;return i.isReadable&&(s=this.#c(5,{offset:e}),i.append(s,{signed:t})),i.isReadable&&s?this.#c(s,{signed:t}):(this.#a=r,this.#i=a,NaN)}readRelative({offset:e=this.#a,signed:t=!1}={}){const r=this.#a,a=this.#i;let i=1;const s=this.#d().append(1,{offset:e});s.isReadable&&(i=this.#c(1,{offset:e})?1:-1);let n=0;for(;s.append(1).isReadable&&!this.#c(1);)n++;const o=a+i*n;return s.append(o,{signed:t}),s.isReadable&&o?(this.#a--,this.#c(o,{signed:t})):(this.#a=r,this.#i=a,NaN)}readString({offset:e=this.#a}={}){const t=this.#a,r=this.#i,a=this.#d().append(5,{offset:e});let i=0;a.isReadable&&(i=this.#c(5,{offset:e})),a.append(i);let s=0;if(a.isReadable&&(s=this.#c(i)),!a.isReadable||!s)return this.#a=t,this.#i=r,"";let n="";for(let e=0;e<s;e++){if(a.append(8),!a.isReadable)return this.#a=t,this.#i=r,"";n+=String.fromCharCode(this.#c(8))}return n}copy({target:t,targetStart:r=t?.writePointer||0,sourceStart:a=0,sourceEnd:i=this.bitLength}={}){if(a<0||i>this.bitLength)throw new e({name:"BitBufferError",message:"Requested bits out of source buffer range","source-start":a,"source-end":i,"source-bit-length":this.bitLength});const s=i-a,o=Math.ceil((s+r)/8);t??=new n({size:o});const h=t.bitLength-r;if(s>h)throw new e({name:"BitBufferError",message:"Source bits exceed bits available in target buffer","source-bits":s,"target-bits":h});for(let e=0;e<s;e++)t.write(this.#c(1,{offset:a+e}),{size:1,offset:r+e});return t}toString(){let e="",t=0,r=0;const a=new Uint8Array(this.#r);for(let i=0;i<3*Math.ceil(this.byteLength/3);i++){r=(r|(a[i]||0)<<16-8*t)>>>0,t=++t%3,t||(e+=n.#u(r),r=0)}return e}#h(){const e={writeable:!0,offset:this.#s},t=(r,{size:a=n.#o(r),offset:i=e.offset,signed:s=!1}={})=>{if(e.writeable){const t=Math.abs(r),o=this.bitLength-i;e.writeable=!(!s&&r<0)&&(!(n.#o(t)>a)&&(!!Number.isInteger(t)&&(!(a<0||a>32)&&!(a+(s?1:0)>o))))}return e.offset+=a,{append:t,get isWriteable(){return e.writeable}}};return{append:t,get isWriteable(){return e.writeable}}}#l(e,{size:t=n.#o(e),offset:r=this.#s,signed:a=!1}={}){const i=Math.abs(e),{view:s,byteLength:o,subBit:h}=this.#f(t,r);for(let e=0;e<o;e++){const r=s.getUint8(e);let a=0;for(let s=0;s<8;s++){const n=8*e+s;a|=(n<h||n>h+t?r<<24+s>>>31:i<<32-t+(n-h)>>>31)<<7-s}s.setUint8(e,a)}return this.#s=r+t,a&&this.#l(e>=0?1:0,{size:1}),this.#n=t,e}#d(){const e={readable:!0,offset:this.#a},t=(r,{offset:a=e.offset,signed:i=!1}={})=>{if(e.readable){const t=this.bitLength-a;e.readable=!(r<0||r>32)&&!(r+(i?1:0)>t)}return e.offset+=r,{append:t,get isReadable(){return e.readable}}};return{append:t,get isReadable(){return e.readable}}}#c(e,{offset:t=this.#a,signed:r=!1}={}){const{view:a,byteLength:i,subBit:s}=this.#f(e,t);let n=0;for(let e=0;e<i;e++){const t=24+s-8*e;n=t>=0?(n|a.getUint8(e)<<t)>>>0:(n|a.getUint8(e)>>>-t)>>>0}this.#a=t+e;const o=r&&0===this.#c(1)?-1:1;return this.#i=e,o*(n>>>32-e)}#f(e,t){const r=Math.floor(t/8),a=t-8*r,i=Math.ceil((a+e)/8);this.byteLength;return{view:new DataView(this.#r,r,i),byteLength:i,subBit:a}}get bitLength(){return this.byteLength<<3}get byteLength(){return this.#r.byteLength}get readPointer(){return this.#a}set readPointer(e){e<0||e>this.bitLength||(this.#a=e)}get lastReadSize(){return this.#i}set lastReadSize(e){e<0||e>32||(this.#i=e)}get writePointer(){return this.#s}set writePointer(e){e<0||e>this.bitLength||(this.#s=e)}get lastWriteSize(){return this.#n}set lastWriteSize(e){e<0||e>32||(this.#n=e)}static from(t){if(!t.match(/^[A-Za-z0-9\-_]*$/))throw new e({name:"BitBufferError",message:"Encoded string is not url-safe base 64 encoded","encoded-string":t});const r=new n({size:Math.ceil(3*t.length/4)}),a=/[A-Za-z0-9\-_]{1,4}/g;for(const e of t.match(a)||[]){const t=n.#m(e.padEnd(4,"A"));r.write(t,{size:24})}return r.writePointer=0,r.readPointer=0,r}static#m(e){let t=0;for(const[r,a]of e.split("").entries()){t=(t|n.#g.indexOf(a)<<18-6*r)>>>0}return t}static#u(e){let t="";for(let r=0;r<4;r++){const a=e>>>18-6*r<<26>>>26;t+=n.#g[a]}return t}static#o(e){return Math.abs(e).toString(2).length}static get#g(){return"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"}}class o{#b=[];#w=new Map;#p;#v;constructor(e,{limit:t=4}={}){this.#p=e,this.#v=t}addWorker(){const e=this.#p();return this.#w.set(e,NaN),e}postWorker(e,t,r){this.#w.set(e,NaN),e.onmessage=t=>{this.#L(e),r(t)},e.postMessage(t)}enqueue(e,t){let r;for(const[e,t]of this.#w)if(t){r=e;break}r?this.postWorker(r,e,t):this.#w.size<this.#v?(r=this.addWorker(),this.postWorker(r,e,t)):this.#b.push({message:e,callback:t})}#L(e){const{message:t,callback:r}=this.#b.shift()||{};t&&r?this.postWorker(e,t,r):(this.#w.set(e,Date.now()),setTimeout((()=>{const t=this.#w.get(e);Date.now()-t>1e3&&(e.terminate(),this.#w.delete(e))}),1050))}}class h{#A;#P;#R;#S;constructor(t){const{luma:r,chromaBlue:a,chromaRed:i}=t.match(/^(?<luma>[0-7]):(?<chromaBlue>[0-7]):(?<chromaRed>[0-7])$/)?.groups||{};if(!r||!a||!i)throw new e({name:"SubsamplingError",message:'Must be of form "x:y:z", digits from 0-7 inclusive',"subsampling-string":t});this.#A=parseInt(r),this.#P=parseInt(a),this.#R=parseInt(i),this.#S=this.#A+this.#P+this.#R}key(e){const t=e%this.#S;return t<this.#A?"luma":t<this.#A+this.#P?"chromaBlue":"chromaRed"}get luma(){return this.#A}get chromaBlue(){return this.#P}get chromaRed(){return this.#R}}function*l(e,t){const r=Array.from(Array.from({length:e}),(()=>Array.from({length:t}).fill(0)));let[a,i]=[0,0];for(;;)if(r[a][i]=yield r,0===i||a===e-1){const r=a+i+1;if(r>e+t-1)break;i=a>=t-1?t-1:a+1,a=r-i}else i--,a++}const d=(e,t=0,r=255,a=!0)=>(a&&(e=Math.round(e),t=Math.ceil(t),r=Math.floor(r)),Math.max(t,Math.min(r,e))),c=(e,t,r)=>{const a=[];for(let i=0;i<r.sample.width;i++){const r=e[i];a.push(f(r,t.y))}return f(a,t.x)},u=e=>{for(;e>=2*Math.PI;)e-=2*Math.PI;return e>Math.PI&&(e=2*Math.PI-e),e>Math.PI/2?5*(e=(e-Math.PI)*(e-Math.PI))/(e+Math.PI*Math.PI)-1:1-5*(e*=e)/(e+Math.PI*Math.PI)},f=(e,t)=>{let r=0;for(let a=0;a<e.length;a++){let i=e[a]*u((2*t+1)*Math.PI*a/(2*e.length));i*=0===a?Math.SQRT1_2:1,r+=i}return r*=Math.sqrt(2/e.length),r=Math.round(r),r},m=0,g=48,b=57,w=8;class p{#M;#r;#y;#z;constructor(t){if(!t.match(/^[A-Za-z0-9\-_]{16,}$/))throw new e({name:"BlurridDecoderError",message:"String minimum 16 url-safe base 64 encoded chars","serialized-dct":t});this.#M=t,this.#r=n.from(t),this.#y=new s(this.#_()),this.#z=this.#E()}toImageData(){const{luma:t,chromaBlue:r,chromaRed:a}=this.#z;return((e,t=255)=>{const r=[];for(let n=0;n<e.length;n+=3){const{red:o,green:h,blue:l}=(a=e[n],i=e[n+1],s=e[n+2],a=d(a),i=d(i),s=d(s),i-=128,{red:d(a+1.4*(s-=128)),green:d(a-.34*i-.71*s),blue:d(a+1.77*i)});r.push(o,h,l,t)}var a,i,s;return r})((t=>{const r=t.map((e=>i(e))),a=r[0].length,s=Array.from({length:r.length*a}).fill(0);for(const[t,i]of r.entries()){if(i.length!==a)throw new e({name:"ChannelError",message:"Sample channels not of same length","default-length":a,"channel-length":i.length});for(const[e,a]of i.entries())s[r.length*e+t]=a}return s})(((e,t)=>{const[r,a,i]=e,s=()=>Array.from(Array.from({length:t.image.height}),(()=>Array.from({length:t.image.width}).fill(0))),n=[s(),s(),s()],[o,h,l]=n;for(let e=0;e<t.image.height;e++)for(let s=0;s<t.image.width;s++){const n={x:s/t.image.width*t.sample.width,y:e/t.image.height*t.sample.height};o[e][s]=c(r,n,t),h[e][s]=c(a,n,t),l[e][s]=c(i,n,t)}return n})([t,r,a],this.#y)))}#_(){this.#r.readPointer=m;return{image:{width:this.#r.read(16),height:this.#r.read(16)},sample:{width:this.#r.read(8),height:this.#r.read(8)}}}#I(){this.#r.readPointer=g;const e=this.#r.read(3),t=this.#r.read(3),r=this.#r.read(3);return new h(`${e}:${t}:${r}`)}#E(){const e=this.#k();let[t,r,a]=e.next().value;for(this.#r.readPointer=b,this.#r.lastReadSize=w;;){const i=this.#r.readRelative({signed:!0});if(isNaN(i))break;[t,r,a]=e.next(i).value}return{luma:t,chromaBlue:r,chromaRed:a}}#k(){return function*(e,t,r){const a={luma:l(e,t),chromaBlue:l(e,t),chromaRed:l(e,t)},i=[a.luma.next().value,a.chromaBlue.next().value,a.chromaRed.next().value];let s=0;do{const e=yield i,t=r.key(s),n=a[t].next(e);if(n.done)break;"luma"===t?i[0]=n.value:"chromaBlue"===t?i[1]=n.value:i[2]=n.value}while(++s)}(this.#y.sample.width,this.#y.sample.height,this.#I())}get serializedDct(){return this.#M}get metadata(){return this.#y}get coefficients(){return this.#z}}const v=e=>{const t=document.createElement("canvas");t.width=e.image.width,t.height=e.image.height;const r=t.getContext("2d");return{canvas:t,context:r}},L=(e,t)=>{const r=e.createProgram();return e.attachShader(r,t.vertex),e.attachShader(r,t.fragment),e.linkProgram(r),e.getProgramParameter(r,e.LINK_STATUS)||(console.warn(e.getProgramInfoLog(r)),e.deleteProgram(r)),r},A=(e,t,r,a={})=>{for(const e in a){const t=new RegExp(`{{${e}}}`,"g");r=r.replaceAll(t,`${a[e]}`)}const i=e.createShader(t);return e.shaderSource(i,r),e.compileShader(i),e.getShaderParameter(i,e.COMPILE_STATUS)||(console.warn(e.getShaderInfoLog(i)),e.deleteShader(i)),i},P=e=>{const{metadata:t,coefficients:r}=e,{canvas:a,context:i,program:s}=(e=>{const t=document.createElement("canvas");t.width=e.image.width,t.height=e.image.height;const r=t.getContext("webgl"),a={vertex:A(r,r.VERTEX_SHADER,"#define GLSLIFY 1\nattribute vec4 a_position;void main(){gl_Position=a_position;}"),fragment:A(r,r.FRAGMENT_SHADER,"precision mediump float;\n#define GLSLIFY 1\nuniform vec4 u_color;uniform float u_image_width;uniform float u_image_height;uniform float u_lumaDct[{{SAMPLE_NORMALIZED_TOTAL}}];uniform float u_chromaBlueDct[{{SAMPLE_NORMALIZED_TOTAL}}];uniform float u_chromaRedDct[{{SAMPLE_NORMALIZED_TOTAL}}];float kFactor(int x){if(x==0){return 0.7071;}else{return 1.0;}}float decode1D(float array1D[{{SAMPLE_MAX}}],float point,int samples){float float_samples=float(samples);float result=0.0;for(int i=0;i<{{SAMPLE_MAX}};i++){if(float(array1D[i])==0.0||i>=samples){break;}float partial=float(array1D[i])*cos(((2.0*point+1.0)*3.14*float(i))/(2.0*float_samples));partial*=kFactor(i);result+=partial;}result*=sqrt(2.0/float_samples);return result;}float decode2D(float array2D[{{SAMPLE_NORMALIZED_TOTAL}}],vec2 uv){float row[{{SAMPLE_MAX}}];float x=uv.x*{{SAMPLE_WIDTH}}.0;float y=(1.0-uv.y)*{{SAMPLE_HEIGHT}}.0;for(int i=0;i<{{SAMPLE_MAX}};i++){float column[{{SAMPLE_MAX}}];for(int j=0;j<{{SAMPLE_MAX}};j++){column[j]=array2D[i*{{SAMPLE_MAX}}+j];}row[i]=decode1D(column,y,{{SAMPLE_HEIGHT}});}float result=decode1D(row,x,{{SAMPLE_WIDTH}});return result;}vec4 yCbCrToRgb(float luma,float chromaBlue,float chromaRed){float red=luma+1.40*(chromaRed-128.0);float green=luma-0.34*(chromaBlue-128.0)-0.71*(chromaRed-128.0);float blue=luma+1.77*(chromaBlue-128.0);red=floor(clamp(red,0.0,255.0)+0.5)/255.0;green=floor(clamp(green,0.0,255.0)+0.5)/255.0;blue=floor(clamp(blue,0.0,255.0)+0.5)/255.0;return vec4(red,green,blue,1.0);}void main(){vec2 uv=gl_FragCoord.xy;uv.x/=u_image_width;uv.y/=u_image_height;gl_FragColor=yCbCrToRgb(decode2D(u_lumaDct,uv),decode2D(u_chromaBlueDct,uv),decode2D(u_chromaRedDct,uv));}",{SAMPLE_WIDTH:e.sample.width,SAMPLE_HEIGHT:e.sample.height,SAMPLE_MAX:e.sample.max,SAMPLE_NORMALIZED_TOTAL:e.sample.max**2})},i=L(r,a),s={index:r.getAttribLocation(i,"a_position"),size:2,type:r.FLOAT,normalize:!1,stride:0,offset:0},n=r.createBuffer();r.bindBuffer(r.ARRAY_BUFFER,n),r.bufferData(r.ARRAY_BUFFER,new Float32Array([-1,1,1,1,1,-1,1,-1,-1,-1,-1,1]),r.STATIC_DRAW),r.clearColor(0,0,0,0),r.clear(r.COLOR_BUFFER_BIT),r.useProgram(i),r.enableVertexAttribArray(s.index);const{index:o,size:h,type:l,normalize:d,stride:c,offset:u}=s;return r.vertexAttribPointer(o,h,l,d,c,u),{canvas:t,context:r,program:i}})(t),n={u_color:{type:"uniform4fv",data:[1,0,0,1]},u_image_width:{type:"uniform1f",data:t.image.width},u_image_height:{type:"uniform1f",data:t.image.height},u_lumaDct:{type:"uniform1fv",data:R(r.luma,t)},u_chromaBlueDct:{type:"uniform1fv",data:R(r.chromaBlue,t)},u_chromaRedDct:{type:"uniform1fv",data:R(r.chromaRed,t)}};for(const e in n){const t=i.getUniformLocation(s,e);i[n[e].type](t,n[e].data)}const o={primitiveType:i.TRIANGLES,offset:0,count:6},{primitiveType:h,offset:l,count:d}=o;return i.drawArrays(h,l,d),a.toDataURL()},R=(e,t)=>{const r=t.sample.max;return Array.from({length:r**2},((t,a)=>e.flatMap((e=>Array.from({length:r},((t,r)=>e[r]||0))))[a]||0))},S=()=>new Worker(new URL("./worker.js",import.meta.url),{type:"module"});class M extends HTMLImageElement{decoder=new p(this.dataset.blurrid||"A".repeat(10));constructor(){super();const e=()=>{this.removeEventListener("load",e),this.blur(),"onclick"===this.dataset.loading?this.loadOnClick():"lazy"===this.dataset.loading?this.loadOnIntersection():this.loadImage()};this.addEventListener("load",e),this.#x&&this.decoder.metadata.resize(this.#x);const{canvas:t}=v(this.decoder.metadata);this.src=t.toDataURL()}blur(){const e=this.decoder.metadata.sample.max;!window.WebGLRenderingContext||e>16?(console.warn("<WARNING> BlurridImage:\nWebGL rendering context unavailable or too many uniforms, try worker fallback"),this.dataset.loading="eager"):this.src=P(this.decoder)}loadImage(){const e=document.createElement("img");for(const t of this.attributes){const{name:r,value:a}=t;this.#D.includes(r)||e.setAttribute(r,a)}const t=()=>{e.removeEventListener("load",t);const{width:r,height:a}=this.getBoundingClientRect();e.style.width=`${r}px`,e.style.height=`${a}px`;const i=[{opacity:1},{opacity:0}],s={easing:"ease-out",duration:500},n=e.cloneNode();n.style.opacity="0",n.style.position="absolute",this.before(n),this.animate(i,s),n.animate(i,{...s,direction:"reverse"}).addEventListener("finish",(()=>{this.replaceWith(e),n.remove()}))};e.addEventListener("load",t),this.dataset.srcset&&e.setAttribute("srcset",this.dataset.srcset),e.setAttribute("src",this.dataset.src||"")}loadOnClick(){const e=()=>{this.removeEventListener("click",e),this.loadImage()};this.addEventListener("click",e)}loadOnIntersection(){const e=new IntersectionObserver((t=>{t[0].isIntersecting&&(e.disconnect(),this.loadImage())}),{threshold:.5});e.observe(this)}get#x(){if(this.dataset.size)return parseInt(this.dataset.size);if(!this.sizes||!this.dataset.srcset)return;let e;const t=/(?<query>\(.*\))[\s\n]*(?<width>\d*)(?<unit>px|vw),/g,r=/(?<width>\d*)(?<unit>px|vw)[\s\n]*$/,a=/[\s\n](?<srcsetWidth>\d*)w,?/g;for(const r of this.sizes.matchAll(t)){const{query:t,width:a,unit:i}=r?.groups||{};if(matchMedia(t).matches){e={width:a,unit:i};break}}if(!e){const{width:t,unit:a}=this.sizes.match(r)?.groups||{};e={width:t,unit:a}}const i="vw"===e?.unit?parseInt(e?.width||"0")/100*window.innerWidth:parseInt(e?.width||"0");for(const e of this.dataset.srcset.matchAll(a)){const{srcsetWidth:t}=e?.groups||{};if(parseInt(t)>=i)return parseInt(t)}}get#D(){return["is","src","data-src","data-srcset","data-loading","data-blurrid","data-worker-start","data-worker-steps"]}}let y;class z extends M{#B=parseInt(this.dataset.workerStart||"16");#W=parseInt(this.dataset.workerSteps||"2");constructor(){super()}blur(){const e=this.decoder.metadata.sample.max;if(!window.WebGLRenderingContext||e>16){y||(y=new o(S));const e=v(this.decoder.metadata);this.stepWorker(e.canvas.toDataURL(),e)}else this.src=P(this.decoder)}stepWorker(e,t,r){if(this.src=e,r??=this.#B,r<this.#B*2**this.#W){const e={serializedDct:this.decoder.serializedDct,width:2*r};y?.enqueue(e,(e=>{const{imageData:r,imageData:{width:a}}=e.data;((e,t,r)=>new Promise((a=>{const i=document.createElement("img"),s=()=>{const{width:t,height:r}=e.canvas;e.context.drawImage(i,0,0,t,r),i.removeEventListener("load",s),i.remove(),a(e.canvas.toDataURL())};i.addEventListener("load",s),r.metadata.resize(t.width);const{canvas:n,context:o}=v(r.metadata);o.putImageData(t,0,0),i.src=n.toDataURL()})))(t,r,this.decoder).then((e=>{this.stepWorker(e,t,a)}))}))}}}export{M as BlurridImage,z as BlurridImageWorker,P as getDataUrl};