amoosedweb-reader 0.25.1 → 0.27.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.
- package/LICENSE.txt +10 -5
- package/README.md +1 -1
- package/index.mjs +11 -2
- package/js-reader.mjs +2 -0
- package/native/AmoosedWebGameReaderC.dll +0 -0
- package/native/amoosedweb_native_reader.node +0 -0
- package/native/compat.mjs +87 -0
- package/native/index.mjs +339 -0
- package/package.json +3 -1
package/LICENSE.txt
CHANGED
|
@@ -3,11 +3,16 @@ AmoosedWeb Reader npm Package License
|
|
|
3
3
|
Copyright (c) 2026 Juhapekka Piiroinen <jp@1337.fi>
|
|
4
4
|
https://amoosed.com
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
If both the individual or organization and the product using this package have
|
|
7
|
+
annual revenue below EUR 1,000,000,000,000, permission is granted without a
|
|
8
|
+
license fee to download, install, and use the unmodified amoosedweb-reader
|
|
9
|
+
package in personal or commercial applications. If either has annual revenue
|
|
10
|
+
of EUR 1,000,000,000,000 or more, an enterprise agreement with the copyright
|
|
11
|
+
owner is required. Unless a different price is negotiated, the standard fee
|
|
12
|
+
is EUR 133,700,000 per year per product using this package. A licensed user may
|
|
13
|
+
distribute unmodified copies of the packaged reader module as part of
|
|
14
|
+
applications that use it, provided this license and copyright notice accompany
|
|
15
|
+
those copies.
|
|
11
16
|
|
|
12
17
|
This permission applies only to the amoosedweb-reader package. It does not
|
|
13
18
|
grant rights to the AmoosedWeb compiler, browser extension, website, source
|
package/README.md
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
# AmoosedWeb Reader
|
|
2
2
|
|
|
3
|
-
Install with `npm install amoosedweb-reader`. Import `openRemoteSite`, `listRemoteResources`, `downloadRemoteResource`, or `downloadRemoteSite` from `amoosedweb-reader`. A private index or members area requires the corresponding key file. See the [compiler guide](https://www.amoosed.com/compiler.html) for an example. Package use terms are in `LICENSE.txt`.
|
|
3
|
+
Install with `npm install amoosedweb-reader`. Import `openRemoteSite`, `listRemoteResources`, `downloadRemoteResource`, or `downloadRemoteSite` from `amoosedweb-reader`. Windows x64 uses the bundled native C/C++ Reader; other platforms retain the JavaScript Reader. A private index or members area requires the corresponding key file. See the [compiler guide](https://www.amoosed.com/compiler.html) for an example. Package use terms are in `LICENSE.txt`.
|
package/index.mjs
CHANGED
|
@@ -1,2 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
var yr=Object.create;var Pe=Object.defineProperty;var mr=Object.getOwnPropertyDescriptor;var _r=Object.getOwnPropertyNames;var br=Object.getPrototypeOf,Er=Object.prototype.hasOwnProperty;var E=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var m=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Ar=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of _r(t))!Er.call(e,i)&&i!==r&&Pe(e,i,{get:()=>t[i],enumerable:!(n=mr(t,i))||n.enumerable});return e};var Ue=(e,t,r)=>(r=e!=null?yr(br(e)):{},Ar(t||!e||!e.__esModule?Pe(r,"default",{value:e,enumerable:!0}):r,e));var le=m((Ni,et)=>{"use strict";var Ur=E("util"),Je=E("stream"),T=et.exports=function(){Je.call(this),this._buffers=[],this._buffered=0,this._reads=[],this._paused=!1,this._encoding="utf8",this.writable=!0};Ur.inherits(T,Je);T.prototype.read=function(e,t){this._reads.push({length:Math.abs(e),allowLess:e<0,func:t}),process.nextTick(function(){this._process(),this._paused&&this._reads&&this._reads.length>0&&(this._paused=!1,this.emit("drain"))}.bind(this))};T.prototype.write=function(e,t){if(!this.writable)return this.emit("error",new Error("Stream not writable")),!1;let r;return Buffer.isBuffer(e)?r=e:r=Buffer.from(e,t||this._encoding),this._buffers.push(r),this._buffered+=r.length,this._process(),this._reads&&this._reads.length===0&&(this._paused=!0),this.writable&&!this._paused};T.prototype.end=function(e,t){e&&this.write(e,t),this.writable=!1,this._buffers&&(this._buffers.length===0?this._end():(this._buffers.push(null),this._process()))};T.prototype.destroySoon=T.prototype.end;T.prototype._end=function(){this._reads.length>0&&this.emit("error",new Error("Unexpected end of input")),this.destroy()};T.prototype.destroy=function(){this._buffers&&(this.writable=!1,this._reads=null,this._buffers=null,this.emit("close"))};T.prototype._processReadAllowingLess=function(e){this._reads.shift();let t=this._buffers[0];t.length>e.length?(this._buffered-=e.length,this._buffers[0]=t.slice(e.length),e.func.call(this,t.slice(0,e.length))):(this._buffered-=t.length,this._buffers.shift(),e.func.call(this,t))};T.prototype._processRead=function(e){this._reads.shift();let t=0,r=0,n=Buffer.alloc(e.length);for(;t<e.length;){let i=this._buffers[r++],o=Math.min(i.length,e.length-t);i.copy(n,t,0,o),t+=o,o!==i.length&&(this._buffers[--r]=i.slice(o))}r>0&&this._buffers.splice(0,r),this._buffered-=e.length,e.func.call(this,n)};T.prototype._process=function(){try{for(;this._buffered>0&&this._reads&&this._reads.length>0;){let e=this._reads[0];if(e.allowLess)this._processReadAllowingLess(e);else if(this._buffered>=e.length)this._processRead(e);else break}this._buffers&&!this.writable&&this._end()}catch(e){this.emit("error",e)}}});var ce=m(he=>{"use strict";var v=[{x:[0],y:[0]},{x:[4],y:[0]},{x:[0,4],y:[4]},{x:[2,6],y:[0,4]},{x:[0,2,4,6],y:[2,6]},{x:[1,3,5,7],y:[0,2,4,6]},{x:[0,1,2,3,4,5,6,7],y:[1,3,5,7]}];he.getImagePasses=function(e,t){let r=[],n=e%8,i=t%8,o=(e-n)/8,s=(t-i)/8;for(let a=0;a<v.length;a++){let h=v[a],l=o*h.x.length,c=s*h.y.length;for(let f=0;f<h.x.length&&h.x[f]<n;f++)l++;for(let f=0;f<h.y.length&&h.y[f]<i;f++)c++;l>0&&c>0&&r.push({width:l,height:c,index:a})}return r};he.getInterlaceIterator=function(e){return function(t,r,n){let i=t%v[n].x.length,o=(t-i)/v[n].x.length*8+v[n].x[i],s=r%v[n].y.length,a=(r-s)/v[n].y.length*8+v[n].y[s];return o*4+a*e*4}}});var fe=m((Di,tt)=>{"use strict";tt.exports=function(t,r,n){let i=t+r-n,o=Math.abs(i-t),s=Math.abs(i-r),a=Math.abs(i-n);return o<=s&&o<=a?t:s<=a?r:n}});var ue=m((qi,nt)=>{"use strict";var Nr=ce(),Hr=fe();function rt(e,t,r){let n=e*t;return r!==8&&(n=Math.ceil(n/(8/r))),n}var N=nt.exports=function(e,t){let r=e.width,n=e.height,i=e.interlace,o=e.bpp,s=e.depth;if(this.read=t.read,this.write=t.write,this.complete=t.complete,this._imageIndex=0,this._images=[],i){let a=Nr.getImagePasses(r,n);for(let h=0;h<a.length;h++)this._images.push({byteWidth:rt(a[h].width,o,s),height:a[h].height,lineIndex:0})}else this._images.push({byteWidth:rt(r,o,s),height:n,lineIndex:0});s===8?this._xComparison=o:s===16?this._xComparison=o*2:this._xComparison=1};N.prototype.start=function(){this.read(this._images[this._imageIndex].byteWidth+1,this._reverseFilterLine.bind(this))};N.prototype._unFilterType1=function(e,t,r){let n=this._xComparison,i=n-1;for(let o=0;o<r;o++){let s=e[1+o],a=o>i?t[o-n]:0;t[o]=s+a}};N.prototype._unFilterType2=function(e,t,r){let n=this._lastLine;for(let i=0;i<r;i++){let o=e[1+i],s=n?n[i]:0;t[i]=o+s}};N.prototype._unFilterType3=function(e,t,r){let n=this._xComparison,i=n-1,o=this._lastLine;for(let s=0;s<r;s++){let a=e[1+s],h=o?o[s]:0,l=s>i?t[s-n]:0,c=Math.floor((l+h)/2);t[s]=a+c}};N.prototype._unFilterType4=function(e,t,r){let n=this._xComparison,i=n-1,o=this._lastLine;for(let s=0;s<r;s++){let a=e[1+s],h=o?o[s]:0,l=s>i?t[s-n]:0,c=s>i&&o?o[s-n]:0,f=Hr(l,h,c);t[s]=a+f}};N.prototype._reverseFilterLine=function(e){let t=e[0],r,n=this._images[this._imageIndex],i=n.byteWidth;if(t===0)r=e.slice(1,i+1);else switch(r=Buffer.alloc(i),t){case 1:this._unFilterType1(e,r,i);break;case 2:this._unFilterType2(e,r,i);break;case 3:this._unFilterType3(e,r,i);break;case 4:this._unFilterType4(e,r,i);break;default:throw new Error("Unrecognised filter type - "+t)}this.write(r),n.lineIndex++,n.lineIndex>=n.height?(this._lastLine=null,this._imageIndex++,n=this._images[this._imageIndex]):this._lastLine=r,n?this.read(n.byteWidth+1,this._reverseFilterLine.bind(this)):(this._lastLine=null,this.complete())}});var st=m((Fi,ot)=>{"use strict";var Dr=E("util"),it=le(),qr=ue(),Fr=ot.exports=function(e){it.call(this);let t=[],r=this;this._filter=new qr(e,{read:this.read.bind(this),write:function(n){t.push(n)},complete:function(){r.emit("complete",Buffer.concat(t))}}),this._filter.start()};Dr.inherits(Fr,it)});var H=m((Yi,at)=>{"use strict";at.exports={PNG_SIGNATURE:[137,80,78,71,13,10,26,10],TYPE_IHDR:1229472850,TYPE_IEND:1229278788,TYPE_IDAT:1229209940,TYPE_PLTE:1347179589,TYPE_tRNS:1951551059,TYPE_gAMA:1732332865,COLORTYPE_GRAYSCALE:0,COLORTYPE_PALETTE:1,COLORTYPE_COLOR:2,COLORTYPE_ALPHA:4,COLORTYPE_PALETTE_COLOR:3,COLORTYPE_COLOR_ALPHA:6,COLORTYPE_TO_BPP_MAP:{0:1,2:3,3:1,4:2,6:4},GAMMA_DIVISION:1e5}});var ge=m(($i,lt)=>{"use strict";var de=[];(function(){for(let e=0;e<256;e++){let t=e;for(let r=0;r<8;r++)t&1?t=3988292384^t>>>1:t=t>>>1;de[e]=t}})();var pe=lt.exports=function(){this._crc=-1};pe.prototype.write=function(e){for(let t=0;t<e.length;t++)this._crc=de[(this._crc^e[t])&255]^this._crc>>>8;return!0};pe.prototype.crc32=function(){return this._crc^-1};pe.crc32=function(e){let t=-1;for(let r=0;r<e.length;r++)t=de[(t^e[r])&255]^t>>>8;return t^-1}});var we=m((Wi,ht)=>{"use strict";var _=H(),Yr=ge(),b=ht.exports=function(e,t){this._options=e,e.checkCRC=e.checkCRC!==!1,this._hasIHDR=!1,this._hasIEND=!1,this._emittedHeadersFinished=!1,this._palette=[],this._colorType=0,this._chunks={},this._chunks[_.TYPE_IHDR]=this._handleIHDR.bind(this),this._chunks[_.TYPE_IEND]=this._handleIEND.bind(this),this._chunks[_.TYPE_IDAT]=this._handleIDAT.bind(this),this._chunks[_.TYPE_PLTE]=this._handlePLTE.bind(this),this._chunks[_.TYPE_tRNS]=this._handleTRNS.bind(this),this._chunks[_.TYPE_gAMA]=this._handleGAMA.bind(this),this.read=t.read,this.error=t.error,this.metadata=t.metadata,this.gamma=t.gamma,this.transColor=t.transColor,this.palette=t.palette,this.parsed=t.parsed,this.inflateData=t.inflateData,this.finished=t.finished,this.simpleTransparency=t.simpleTransparency,this.headersFinished=t.headersFinished||function(){}};b.prototype.start=function(){this.read(_.PNG_SIGNATURE.length,this._parseSignature.bind(this))};b.prototype._parseSignature=function(e){let t=_.PNG_SIGNATURE;for(let r=0;r<t.length;r++)if(e[r]!==t[r]){this.error(new Error("Invalid file signature"));return}this.read(8,this._parseChunkBegin.bind(this))};b.prototype._parseChunkBegin=function(e){let t=e.readUInt32BE(0),r=e.readUInt32BE(4),n="";for(let o=4;o<8;o++)n+=String.fromCharCode(e[o]);let i=!!(e[4]&32);if(!this._hasIHDR&&r!==_.TYPE_IHDR){this.error(new Error("Expected IHDR on beggining"));return}if(this._crc=new Yr,this._crc.write(Buffer.from(n)),this._chunks[r])return this._chunks[r](t);if(!i){this.error(new Error("Unsupported critical chunk type "+n));return}this.read(t+4,this._skipChunk.bind(this))};b.prototype._skipChunk=function(){this.read(8,this._parseChunkBegin.bind(this))};b.prototype._handleChunkEnd=function(){this.read(4,this._parseChunkEnd.bind(this))};b.prototype._parseChunkEnd=function(e){let t=e.readInt32BE(0),r=this._crc.crc32();if(this._options.checkCRC&&r!==t){this.error(new Error("Crc error - "+t+" - "+r));return}this._hasIEND||this.read(8,this._parseChunkBegin.bind(this))};b.prototype._handleIHDR=function(e){this.read(e,this._parseIHDR.bind(this))};b.prototype._parseIHDR=function(e){this._crc.write(e);let t=e.readUInt32BE(0),r=e.readUInt32BE(4),n=e[8],i=e[9],o=e[10],s=e[11],a=e[12];if(n!==8&&n!==4&&n!==2&&n!==1&&n!==16){this.error(new Error("Unsupported bit depth "+n));return}if(!(i in _.COLORTYPE_TO_BPP_MAP)){this.error(new Error("Unsupported color type"));return}if(o!==0){this.error(new Error("Unsupported compression method"));return}if(s!==0){this.error(new Error("Unsupported filter method"));return}if(a!==0&&a!==1){this.error(new Error("Unsupported interlace method"));return}this._colorType=i;let h=_.COLORTYPE_TO_BPP_MAP[this._colorType];this._hasIHDR=!0,this.metadata({width:t,height:r,depth:n,interlace:!!a,palette:!!(i&_.COLORTYPE_PALETTE),color:!!(i&_.COLORTYPE_COLOR),alpha:!!(i&_.COLORTYPE_ALPHA),bpp:h,colorType:i}),this._handleChunkEnd()};b.prototype._handlePLTE=function(e){this.read(e,this._parsePLTE.bind(this))};b.prototype._parsePLTE=function(e){this._crc.write(e);let t=Math.floor(e.length/3);for(let r=0;r<t;r++)this._palette.push([e[r*3],e[r*3+1],e[r*3+2],255]);this.palette(this._palette),this._handleChunkEnd()};b.prototype._handleTRNS=function(e){this.simpleTransparency(),this.read(e,this._parseTRNS.bind(this))};b.prototype._parseTRNS=function(e){if(this._crc.write(e),this._colorType===_.COLORTYPE_PALETTE_COLOR){if(this._palette.length===0){this.error(new Error("Transparency chunk must be after palette"));return}if(e.length>this._palette.length){this.error(new Error("More transparent colors than palette size"));return}for(let t=0;t<e.length;t++)this._palette[t][3]=e[t];this.palette(this._palette)}this._colorType===_.COLORTYPE_GRAYSCALE&&this.transColor([e.readUInt16BE(0)]),this._colorType===_.COLORTYPE_COLOR&&this.transColor([e.readUInt16BE(0),e.readUInt16BE(2),e.readUInt16BE(4)]),this._handleChunkEnd()};b.prototype._handleGAMA=function(e){this.read(e,this._parseGAMA.bind(this))};b.prototype._parseGAMA=function(e){this._crc.write(e),this.gamma(e.readUInt32BE(0)/_.GAMMA_DIVISION),this._handleChunkEnd()};b.prototype._handleIDAT=function(e){this._emittedHeadersFinished||(this._emittedHeadersFinished=!0,this.headersFinished()),this.read(-e,this._parseIDAT.bind(this,e))};b.prototype._parseIDAT=function(e,t){if(this._crc.write(t),this._colorType===_.COLORTYPE_PALETTE_COLOR&&this._palette.length===0)throw new Error("Expected palette not found");this.inflateData(t);let r=e-t.length;r>0?this._handleIDAT(r):this._handleChunkEnd()};b.prototype._handleIEND=function(e){this.read(e,this._parseIEND.bind(this))};b.prototype._parseIEND=function(e){this._crc.write(e),this._hasIEND=!0,this._handleChunkEnd(),this.finished&&this.finished()}});var ye=m(ft=>{"use strict";var ct=ce(),$r=[function(){},function(e,t,r,n){if(n===t.length)throw new Error("Ran out of data");let i=t[n];e[r]=i,e[r+1]=i,e[r+2]=i,e[r+3]=255},function(e,t,r,n){if(n+1>=t.length)throw new Error("Ran out of data");let i=t[n];e[r]=i,e[r+1]=i,e[r+2]=i,e[r+3]=t[n+1]},function(e,t,r,n){if(n+2>=t.length)throw new Error("Ran out of data");e[r]=t[n],e[r+1]=t[n+1],e[r+2]=t[n+2],e[r+3]=255},function(e,t,r,n){if(n+3>=t.length)throw new Error("Ran out of data");e[r]=t[n],e[r+1]=t[n+1],e[r+2]=t[n+2],e[r+3]=t[n+3]}],Wr=[function(){},function(e,t,r,n){let i=t[0];e[r]=i,e[r+1]=i,e[r+2]=i,e[r+3]=n},function(e,t,r){let n=t[0];e[r]=n,e[r+1]=n,e[r+2]=n,e[r+3]=t[1]},function(e,t,r,n){e[r]=t[0],e[r+1]=t[1],e[r+2]=t[2],e[r+3]=n},function(e,t,r){e[r]=t[0],e[r+1]=t[1],e[r+2]=t[2],e[r+3]=t[3]}];function Gr(e,t){let r=[],n=0;function i(){if(n===e.length)throw new Error("Ran out of data");let o=e[n];n++;let s,a,h,l,c,f,u,p;switch(t){default:throw new Error("unrecognised depth");case 16:u=e[n],n++,r.push((o<<8)+u);break;case 4:u=o&15,p=o>>4,r.push(p,u);break;case 2:c=o&3,f=o>>2&3,u=o>>4&3,p=o>>6&3,r.push(p,u,f,c);break;case 1:s=o&1,a=o>>1&1,h=o>>2&1,l=o>>3&1,c=o>>4&1,f=o>>5&1,u=o>>6&1,p=o>>7&1,r.push(p,u,f,c,l,h,a,s);break}}return{get:function(o){for(;r.length<o;)i();let s=r.slice(0,o);return r=r.slice(o),s},resetAfterLine:function(){r.length=0},end:function(){if(n!==e.length)throw new Error("extra data found")}}}function zr(e,t,r,n,i,o){let s=e.width,a=e.height,h=e.index;for(let l=0;l<a;l++)for(let c=0;c<s;c++){let f=r(c,l,h);$r[n](t,i,f,o),o+=n}return o}function jr(e,t,r,n,i,o){let s=e.width,a=e.height,h=e.index;for(let l=0;l<a;l++){for(let c=0;c<s;c++){let f=i.get(n),u=r(c,l,h);Wr[n](t,f,u,o)}i.resetAfterLine()}}ft.dataToBitMap=function(e,t){let r=t.width,n=t.height,i=t.depth,o=t.bpp,s=t.interlace,a;i!==8&&(a=Gr(e,i));let h;i<=8?h=Buffer.alloc(r*n*4):h=new Uint16Array(r*n*4);let l=Math.pow(2,i)-1,c=0,f,u;if(s)f=ct.getImagePasses(r,n),u=ct.getInterlaceIterator(r,n);else{let p=0;u=function(){let g=p;return p+=4,g},f=[{width:r,height:n}]}for(let p=0;p<f.length;p++)i===8?c=zr(f[p],h,u,o,e,c):jr(f[p],h,u,o,a,l);if(i===8){if(c!==e.length)throw new Error("extra data found")}else a.end();return h}});var me=m((zi,ut)=>{"use strict";function Vr(e,t,r,n,i){let o=0;for(let s=0;s<n;s++)for(let a=0;a<r;a++){let h=i[e[o]];if(!h)throw new Error("index "+e[o]+" not in palette");for(let l=0;l<4;l++)t[o+l]=h[l];o+=4}}function Zr(e,t,r,n,i){let o=0;for(let s=0;s<n;s++)for(let a=0;a<r;a++){let h=!1;if(i.length===1?i[0]===e[o]&&(h=!0):i[0]===e[o]&&i[1]===e[o+1]&&i[2]===e[o+2]&&(h=!0),h)for(let l=0;l<4;l++)t[o+l]=0;o+=4}}function Kr(e,t,r,n,i){let o=255,s=Math.pow(2,i)-1,a=0;for(let h=0;h<n;h++)for(let l=0;l<r;l++){for(let c=0;c<4;c++)t[a+c]=Math.floor(e[a+c]*o/s+.5);a+=4}}ut.exports=function(e,t){let r=t.depth,n=t.width,i=t.height,o=t.colorType,s=t.transColor,a=t.palette,h=e;return o===3?Vr(e,h,n,i,a):(s&&Zr(e,h,n,i,s),r!==8&&(r===16&&(h=Buffer.alloc(n*i*4)),Kr(e,h,n,i,r))),h}});var gt=m((ji,pt)=>{"use strict";var Xr=E("util"),_e=E("zlib"),dt=le(),Qr=st(),Jr=we(),en=ye(),tn=me(),B=pt.exports=function(e){dt.call(this),this._parser=new Jr(e,{read:this.read.bind(this),error:this._handleError.bind(this),metadata:this._handleMetaData.bind(this),gamma:this.emit.bind(this,"gamma"),palette:this._handlePalette.bind(this),transColor:this._handleTransColor.bind(this),finished:this._finished.bind(this),inflateData:this._inflateData.bind(this),simpleTransparency:this._simpleTransparency.bind(this),headersFinished:this._headersFinished.bind(this)}),this._options=e,this.writable=!0,this._parser.start()};Xr.inherits(B,dt);B.prototype._handleError=function(e){this.emit("error",e),this.writable=!1,this.destroy(),this._inflate&&this._inflate.destroy&&this._inflate.destroy(),this._filter&&(this._filter.destroy(),this._filter.on("error",function(){})),this.errord=!0};B.prototype._inflateData=function(e){if(!this._inflate)if(this._bitmapInfo.interlace)this._inflate=_e.createInflate(),this._inflate.on("error",this.emit.bind(this,"error")),this._filter.on("complete",this._complete.bind(this)),this._inflate.pipe(this._filter);else{let r=((this._bitmapInfo.width*this._bitmapInfo.bpp*this._bitmapInfo.depth+7>>3)+1)*this._bitmapInfo.height,n=Math.max(r,_e.Z_MIN_CHUNK);this._inflate=_e.createInflate({chunkSize:n});let i=r,o=this.emit.bind(this,"error");this._inflate.on("error",function(a){i&&o(a)}),this._filter.on("complete",this._complete.bind(this));let s=this._filter.write.bind(this._filter);this._inflate.on("data",function(a){i&&(a.length>i&&(a=a.slice(0,i)),i-=a.length,s(a))}),this._inflate.on("end",this._filter.end.bind(this._filter))}this._inflate.write(e)};B.prototype._handleMetaData=function(e){this._metaData=e,this._bitmapInfo=Object.create(e),this._filter=new Qr(this._bitmapInfo)};B.prototype._handleTransColor=function(e){this._bitmapInfo.transColor=e};B.prototype._handlePalette=function(e){this._bitmapInfo.palette=e};B.prototype._simpleTransparency=function(){this._metaData.alpha=!0};B.prototype._headersFinished=function(){this.emit("metadata",this._metaData)};B.prototype._finished=function(){this.errord||(this._inflate?this._inflate.end():this.emit("error","No Inflate block"))};B.prototype._complete=function(e){if(this.errord)return;let t;try{let r=en.dataToBitMap(e,this._bitmapInfo);t=tn(r,this._bitmapInfo),r=null}catch(r){this._handleError(r);return}this.emit("parsed",t)}});var yt=m((Vi,wt)=>{"use strict";var x=H();wt.exports=function(e,t,r,n){let i=[x.COLORTYPE_COLOR_ALPHA,x.COLORTYPE_ALPHA].indexOf(n.colorType)!==-1;if(n.colorType===n.inputColorType){let g=(function(){let w=new ArrayBuffer(2);return new DataView(w).setInt16(0,256,!0),new Int16Array(w)[0]!==256})();if(n.bitDepth===8||n.bitDepth===16&&g)return e}let o=n.bitDepth!==16?e:new Uint16Array(e.buffer),s=255,a=x.COLORTYPE_TO_BPP_MAP[n.inputColorType];a===4&&!n.inputHasAlpha&&(a=3);let h=x.COLORTYPE_TO_BPP_MAP[n.colorType];n.bitDepth===16&&(s=65535,h*=2);let l=Buffer.alloc(t*r*h),c=0,f=0,u=n.bgColor||{};u.red===void 0&&(u.red=s),u.green===void 0&&(u.green=s),u.blue===void 0&&(u.blue=s);function p(){let g,w,d,y=s;switch(n.inputColorType){case x.COLORTYPE_COLOR_ALPHA:y=o[c+3],g=o[c],w=o[c+1],d=o[c+2];break;case x.COLORTYPE_COLOR:g=o[c],w=o[c+1],d=o[c+2];break;case x.COLORTYPE_ALPHA:y=o[c+1],g=o[c],w=g,d=g;break;case x.COLORTYPE_GRAYSCALE:g=o[c],w=g,d=g;break;default:throw new Error("input color type:"+n.inputColorType+" is not supported at present")}return n.inputHasAlpha&&(i||(y/=s,g=Math.min(Math.max(Math.round((1-y)*u.red+y*g),0),s),w=Math.min(Math.max(Math.round((1-y)*u.green+y*w),0),s),d=Math.min(Math.max(Math.round((1-y)*u.blue+y*d),0),s))),{red:g,green:w,blue:d,alpha:y}}for(let g=0;g<r;g++)for(let w=0;w<t;w++){let d=p(o,c);switch(n.colorType){case x.COLORTYPE_COLOR_ALPHA:case x.COLORTYPE_COLOR:n.bitDepth===8?(l[f]=d.red,l[f+1]=d.green,l[f+2]=d.blue,i&&(l[f+3]=d.alpha)):(l.writeUInt16BE(d.red,f),l.writeUInt16BE(d.green,f+2),l.writeUInt16BE(d.blue,f+4),i&&l.writeUInt16BE(d.alpha,f+6));break;case x.COLORTYPE_ALPHA:case x.COLORTYPE_GRAYSCALE:{let y=(d.red+d.green+d.blue)/3;n.bitDepth===8?(l[f]=y,i&&(l[f+1]=d.alpha)):(l.writeUInt16BE(y,f),i&&l.writeUInt16BE(d.alpha,f+2));break}default:throw new Error("unrecognised color Type "+n.colorType)}c+=a,f+=h}return l}});var bt=m((Zi,_t)=>{"use strict";var mt=fe();function rn(e,t,r,n,i){for(let o=0;o<r;o++)n[i+o]=e[t+o]}function nn(e,t,r){let n=0,i=t+r;for(let o=t;o<i;o++)n+=Math.abs(e[o]);return n}function on(e,t,r,n,i,o){for(let s=0;s<r;s++){let a=s>=o?e[t+s-o]:0,h=e[t+s]-a;n[i+s]=h}}function sn(e,t,r,n){let i=0;for(let o=0;o<r;o++){let s=o>=n?e[t+o-n]:0,a=e[t+o]-s;i+=Math.abs(a)}return i}function an(e,t,r,n,i){for(let o=0;o<r;o++){let s=t>0?e[t+o-r]:0,a=e[t+o]-s;n[i+o]=a}}function ln(e,t,r){let n=0,i=t+r;for(let o=t;o<i;o++){let s=t>0?e[o-r]:0,a=e[o]-s;n+=Math.abs(a)}return n}function hn(e,t,r,n,i,o){for(let s=0;s<r;s++){let a=s>=o?e[t+s-o]:0,h=t>0?e[t+s-r]:0,l=e[t+s]-(a+h>>1);n[i+s]=l}}function cn(e,t,r,n){let i=0;for(let o=0;o<r;o++){let s=o>=n?e[t+o-n]:0,a=t>0?e[t+o-r]:0,h=e[t+o]-(s+a>>1);i+=Math.abs(h)}return i}function fn(e,t,r,n,i,o){for(let s=0;s<r;s++){let a=s>=o?e[t+s-o]:0,h=t>0?e[t+s-r]:0,l=t>0&&s>=o?e[t+s-(r+o)]:0,c=e[t+s]-mt(a,h,l);n[i+s]=c}}function un(e,t,r,n){let i=0;for(let o=0;o<r;o++){let s=o>=n?e[t+o-n]:0,a=t>0?e[t+o-r]:0,h=t>0&&o>=n?e[t+o-(r+n)]:0,l=e[t+o]-mt(s,a,h);i+=Math.abs(l)}return i}var dn={0:rn,1:on,2:an,3:hn,4:fn},pn={0:nn,1:sn,2:ln,3:cn,4:un};_t.exports=function(e,t,r,n,i){let o;if(!("filterType"in n)||n.filterType===-1)o=[0,1,2,3,4];else if(typeof n.filterType=="number")o=[n.filterType];else throw new Error("unrecognised filter types");n.bitDepth===16&&(i*=2);let s=t*i,a=0,h=0,l=Buffer.alloc((s+1)*r),c=o[0];for(let f=0;f<r;f++){if(o.length>1){let u=1/0;for(let p=0;p<o.length;p++){let g=pn[o[p]](e,h,s,i);g<u&&(c=o[p],u=g)}}l[a]=c,a++,dn[c](e,h,s,l,a,i),a+=s,h+=s}return l}});var be=m((Ki,Et)=>{"use strict";var A=H(),gn=ge(),wn=yt(),yn=bt(),mn=E("zlib"),R=Et.exports=function(e){if(this._options=e,e.deflateChunkSize=e.deflateChunkSize||32*1024,e.deflateLevel=e.deflateLevel!=null?e.deflateLevel:9,e.deflateStrategy=e.deflateStrategy!=null?e.deflateStrategy:3,e.inputHasAlpha=e.inputHasAlpha!=null?e.inputHasAlpha:!0,e.deflateFactory=e.deflateFactory||mn.createDeflate,e.bitDepth=e.bitDepth||8,e.colorType=typeof e.colorType=="number"?e.colorType:A.COLORTYPE_COLOR_ALPHA,e.inputColorType=typeof e.inputColorType=="number"?e.inputColorType:A.COLORTYPE_COLOR_ALPHA,[A.COLORTYPE_GRAYSCALE,A.COLORTYPE_COLOR,A.COLORTYPE_COLOR_ALPHA,A.COLORTYPE_ALPHA].indexOf(e.colorType)===-1)throw new Error("option color type:"+e.colorType+" is not supported at present");if([A.COLORTYPE_GRAYSCALE,A.COLORTYPE_COLOR,A.COLORTYPE_COLOR_ALPHA,A.COLORTYPE_ALPHA].indexOf(e.inputColorType)===-1)throw new Error("option input color type:"+e.inputColorType+" is not supported at present");if(e.bitDepth!==8&&e.bitDepth!==16)throw new Error("option bit depth:"+e.bitDepth+" is not supported at present")};R.prototype.getDeflateOptions=function(){return{chunkSize:this._options.deflateChunkSize,level:this._options.deflateLevel,strategy:this._options.deflateStrategy}};R.prototype.createDeflate=function(){return this._options.deflateFactory(this.getDeflateOptions())};R.prototype.filterData=function(e,t,r){let n=wn(e,t,r,this._options),i=A.COLORTYPE_TO_BPP_MAP[this._options.colorType];return yn(n,t,r,this._options,i)};R.prototype._packChunk=function(e,t){let r=t?t.length:0,n=Buffer.alloc(r+12);return n.writeUInt32BE(r,0),n.writeUInt32BE(e,4),t&&t.copy(n,8),n.writeInt32BE(gn.crc32(n.slice(4,n.length-4)),n.length-4),n};R.prototype.packGAMA=function(e){let t=Buffer.alloc(4);return t.writeUInt32BE(Math.floor(e*A.GAMMA_DIVISION),0),this._packChunk(A.TYPE_gAMA,t)};R.prototype.packIHDR=function(e,t){let r=Buffer.alloc(13);return r.writeUInt32BE(e,0),r.writeUInt32BE(t,4),r[8]=this._options.bitDepth,r[9]=this._options.colorType,r[10]=0,r[11]=0,r[12]=0,this._packChunk(A.TYPE_IHDR,r)};R.prototype.packIDAT=function(e){return this._packChunk(A.TYPE_IDAT,e)};R.prototype.packIEND=function(){return this._packChunk(A.TYPE_IEND,null)}});var Ct=m((Xi,kt)=>{"use strict";var _n=E("util"),At=E("stream"),bn=H(),En=be(),It=kt.exports=function(e){At.call(this);let t=e||{};this._packer=new En(t),this._deflate=this._packer.createDeflate(),this.readable=!0};_n.inherits(It,At);It.prototype.pack=function(e,t,r,n){this.emit("data",Buffer.from(bn.PNG_SIGNATURE)),this.emit("data",this._packer.packIHDR(t,r)),n&&this.emit("data",this._packer.packGAMA(n));let i=this._packer.filterData(e,t,r);this._deflate.on("error",this.emit.bind(this,"error")),this._deflate.on("data",function(o){this.emit("data",this._packer.packIDAT(o))}.bind(this)),this._deflate.on("end",function(){this.emit("data",this._packer.packIEND()),this.emit("end")}.bind(this)),this._deflate.end(i)}});var Bt=m((G,St)=>{"use strict";var xt=E("assert").ok,D=E("zlib"),An=E("util"),Lt=E("buffer").kMaxLength;function U(e){if(!(this instanceof U))return new U(e);e&&e.chunkSize<D.Z_MIN_CHUNK&&(e.chunkSize=D.Z_MIN_CHUNK),D.Inflate.call(this,e),this._offset=this._offset===void 0?this._outOffset:this._offset,this._buffer=this._buffer||this._outBuffer,e&&e.maxLength!=null&&(this._maxLength=e.maxLength)}function In(e){return new U(e)}function Tt(e,t){t&&process.nextTick(t),e._handle&&(e._handle.close(),e._handle=null)}U.prototype._processChunk=function(e,t,r){if(typeof r=="function")return D.Inflate._processChunk.call(this,e,t,r);let n=this,i=e&&e.length,o=this._chunkSize-this._offset,s=this._maxLength,a=0,h=[],l=0,c;this.on("error",function(g){c=g});function f(g,w){if(n._hadError)return;let d=o-w;if(xt(d>=0,"have should not go down"),d>0){let y=n._buffer.slice(n._offset,n._offset+d);if(n._offset+=d,y.length>s&&(y=y.slice(0,s)),h.push(y),l+=y.length,s-=y.length,s===0)return!1}return(w===0||n._offset>=n._chunkSize)&&(o=n._chunkSize,n._offset=0,n._buffer=Buffer.allocUnsafe(n._chunkSize)),w===0?(a+=i-g,i=g,!0):!1}xt(this._handle,"zlib binding closed");let u;do u=this._handle.writeSync(t,e,a,i,this._buffer,this._offset,o),u=u||this._writeState;while(!this._hadError&&f(u[0],u[1]));if(this._hadError)throw c;if(l>=Lt)throw Tt(this),new RangeError("Cannot create final Buffer. It would be larger than 0x"+Lt.toString(16)+" bytes");let p=Buffer.concat(h,l);return Tt(this),p};An.inherits(U,D.Inflate);function kn(e,t){if(typeof t=="string"&&(t=Buffer.from(t)),!(t instanceof Buffer))throw new TypeError("Not a string or buffer");let r=e._finishFlushFlag;return r==null&&(r=D.Z_FINISH),e._processChunk(t,r)}function Mt(e,t){return kn(new U(t),e)}St.exports=G=Mt;G.Inflate=U;G.createInflate=In;G.inflateSync=Mt});var Ee=m((Qi,vt)=>{"use strict";var Ot=vt.exports=function(e){this._buffer=e,this._reads=[]};Ot.prototype.read=function(e,t){this._reads.push({length:Math.abs(e),allowLess:e<0,func:t})};Ot.prototype.process=function(){for(;this._reads.length>0&&this._buffer.length;){let e=this._reads[0];if(this._buffer.length&&(this._buffer.length>=e.length||e.allowLess)){this._reads.shift();let t=this._buffer;this._buffer=t.slice(e.length),e.func.call(this,t.slice(0,e.length))}else break}if(this._reads.length>0)return new Error("There are some read requests waitng on finished stream");if(this._buffer.length>0)return new Error("unrecognised content at end of stream")}});var Pt=m(Rt=>{"use strict";var Cn=Ee(),xn=ue();Rt.process=function(e,t){let r=[],n=new Cn(e);return new xn(t,{read:n.read.bind(n),write:function(o){r.push(o)},complete:function(){}}).start(),n.process(),Buffer.concat(r)}});var Dt=m((eo,Ht)=>{"use strict";var Ut=!0,Nt=E("zlib"),Ln=Bt();Nt.deflateSync||(Ut=!1);var Tn=Ee(),Mn=Pt(),Sn=we(),Bn=ye(),On=me();Ht.exports=function(e,t){if(!Ut)throw new Error("To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0");let r;function n(C){r=C}let i;function o(C){i=C}function s(C){i.transColor=C}function a(C){i.palette=C}function h(){i.alpha=!0}let l;function c(C){l=C}let f=[];function u(C){f.push(C)}let p=new Tn(e);if(new Sn(t,{read:p.read.bind(p),error:n,metadata:o,gamma:c,palette:a,transColor:s,inflateData:u,simpleTransparency:h}).start(),p.process(),r)throw r;let w=Buffer.concat(f);f.length=0;let d;if(i.interlace)d=Nt.inflateSync(w);else{let Re=((i.width*i.bpp*i.depth+7>>3)+1)*i.height;d=Ln(w,{chunkSize:Re,maxLength:Re})}if(w=null,!d||!d.length)throw new Error("bad png - invalid inflate data response");let y=Mn.process(d,i);w=null;let k=Bn.dataToBitMap(y,i);y=null;let Q=On(k,i);return i.data=Q,i.gamma=l||0,i}});var $t=m((to,Yt)=>{"use strict";var qt=!0,Ft=E("zlib");Ft.deflateSync||(qt=!1);var vn=H(),Rn=be();Yt.exports=function(e,t){if(!qt)throw new Error("To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0");let r=t||{},n=new Rn(r),i=[];i.push(Buffer.from(vn.PNG_SIGNATURE)),i.push(n.packIHDR(e.width,e.height)),e.gamma&&i.push(n.packGAMA(e.gamma));let o=n.filterData(e.data,e.width,e.height),s=Ft.deflateSync(o,n.getDeflateOptions());if(o=null,!s||!s.length)throw new Error("bad png - invalid compressed data response");return i.push(n.packIDAT(s)),i.push(n.packIEND()),Buffer.concat(i)}});var Wt=m(Ae=>{"use strict";var Pn=Dt(),Un=$t();Ae.read=function(e,t){return Pn(e,t||{})};Ae.write=function(e,t){return Un(e,t)}});var Ie=m(zt=>{"use strict";var Nn=E("util"),Gt=E("stream"),Hn=gt(),Dn=Ct(),qn=Wt(),I=zt.PNG=function(e){Gt.call(this),e=e||{},this.width=e.width|0,this.height=e.height|0,this.data=this.width>0&&this.height>0?Buffer.alloc(4*this.width*this.height):null,e.fill&&this.data&&this.data.fill(0),this.gamma=0,this.readable=this.writable=!0,this._parser=new Hn(e),this._parser.on("error",this.emit.bind(this,"error")),this._parser.on("close",this._handleClose.bind(this)),this._parser.on("metadata",this._metadata.bind(this)),this._parser.on("gamma",this._gamma.bind(this)),this._parser.on("parsed",function(t){this.data=t,this.emit("parsed",t)}.bind(this)),this._packer=new Dn(e),this._packer.on("data",this.emit.bind(this,"data")),this._packer.on("end",this.emit.bind(this,"end")),this._parser.on("close",this._handleClose.bind(this)),this._packer.on("error",this.emit.bind(this,"error"))};Nn.inherits(I,Gt);I.sync=qn;I.prototype.pack=function(){return!this.data||!this.data.length?(this.emit("error","No data provided"),this):(process.nextTick(function(){this._packer.pack(this.data,this.width,this.height,this.gamma)}.bind(this)),this)};I.prototype.parse=function(e,t){if(t){let r,n;r=function(i){this.removeListener("error",n),this.data=i,t(null,this)}.bind(this),n=function(i){this.removeListener("parsed",r),t(i,null)}.bind(this),this.once("parsed",r),this.once("error",n)}return this.end(e),this};I.prototype.write=function(e){return this._parser.write(e),!0};I.prototype.end=function(e){this._parser.end(e)};I.prototype._metadata=function(e){this.width=e.width,this.height=e.height,this.emit("metadata",e)};I.prototype._gamma=function(e){this.gamma=e};I.prototype._handleClose=function(){!this._parser.writable&&!this._packer.readable&&this.emit("close")};I.bitblt=function(e,t,r,n,i,o,s,a){if(r|=0,n|=0,i|=0,o|=0,s|=0,a|=0,r>e.width||n>e.height||r+i>e.width||n+o>e.height)throw new Error("bitblt reading outside image");if(s>t.width||a>t.height||s+i>t.width||a+o>t.height)throw new Error("bitblt writing outside image");for(let h=0;h<o;h++)e.data.copy(t.data,(a+h)*t.width+s<<2,(n+h)*e.width+r<<2,(n+h)*e.width+r+i<<2)};I.prototype.bitblt=function(e,t,r,n,i,o,s){return I.bitblt(this,e,t,r,n,i,o,s),this};I.adjustGamma=function(e){if(e.gamma){for(let t=0;t<e.height;t++)for(let r=0;r<e.width;r++){let n=e.width*t+r<<2;for(let i=0;i<3;i++){let o=e.data[n+i]/255;o=Math.pow(o,1/2.2/e.gamma),e.data[n+i]=Math.round(o*255)}}e.gamma=0}};I.prototype.adjustGamma=function(){I.adjustGamma(this)}});import{createDecipheriv as hr,createHash as Oe,randomBytes as wi}from"node:crypto";import{open as Me,mkdir as ve,unlink as pr,readFile as cr,lstat as Se,realpath as fr}from"node:fs/promises";import{dirname as K,resolve as X,relative as gr,sep as wr,join as yi,isAbsolute as mi}from"node:path";async function S(e,t){if(!Number.isSafeInteger(t)||t<0)throw new Error("Invalid response limit");let r=e.headers.get("Content-Length");if(r!==null&&(!/^[0-9]+$/.test(r)||!Number.isSafeInteger(Number(r))||Number(r)>t))throw e.body&&await e.body.cancel().catch(()=>{}),new Error("Carrier response exceeds byte limit");if(!e.body)return new Uint8Array(0);let n=e.body.getReader(),i=[],o=0,s=!1;try{for(;;){let{done:l,value:c}=await n.read();if(l){s=!0;break}if(o+=c.byteLength,o>t)throw new Error("Carrier response exceeds byte limit");i.push(c)}}finally{s||await n.cancel().catch(()=>{}),n.releaseLock()}let a=new Uint8Array(o),h=0;for(let l of i)a.set(l,h),h+=l.byteLength;return a}var P=4096,L=128,Ne=1024*1024*1024,ee=16*1024*1024,Ir=new TextDecoder("utf-8",{fatal:!0}),Y=(e,t)=>e.length===t.length&&e.every((r,n)=>r===t[n]),F=async e=>new Uint8Array(await crypto.subtle.digest("SHA-256",e)),O=(e,t)=>{let r=Number(e.getBigUint64(t,!0));if(!Number.isSafeInteger(r))throw new Error("Unsafe offset");return r},He=(e,t)=>Y(e.slice(0,8),new TextEncoder().encode(t)),J=e=>JSON.parse(Ir.decode(e));function kr(e){if(e.length!==P||!He(e,"AMW1DOC\0"))throw new Error("Invalid AMW header");let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(t.getUint16(8,!0)!==1||t.getUint16(10,!0)!==P||e.slice(12,16).some(Boolean)||e.slice(120).some(Boolean))throw new Error("Unsupported AMW header");let r={total:O(t,16),manifestOffset:O(t,24),manifestLength:O(t,32),bootstrapOffset:O(t,40),bootstrapLength:O(t,48),manifestHash:e.slice(56,88),bootstrapHash:e.slice(88,120)};if(r.total>Ne||r.total<P||r.manifestOffset!==P||r.manifestLength>1024*1024)throw new Error("Invalid AMW bounds");return r}function Cr(e,t){if(e.length!==L||!He(e,"AMW1TAIL"))throw new Error("No AMW footer");let r=new DataView(e.buffer,e.byteOffset,e.byteLength),n=r.getUint16(8,!0);if(![1,2].includes(n)||r.getUint16(10,!0)!==L||e.slice(12,16).some(Boolean)||n===1&&e.slice(104).some(Boolean))throw new Error("Unsupported footer");let i={version:n,carrierLength:O(r,16),payloadOffset:O(r,24),payloadLength:O(r,32),payloadHash:e.slice(40,72),bootstrapPrefixHash:n===2?e.slice(104,128):null};if(i.carrierLength!==i.payloadOffset||i.payloadLength>Ne||i.payloadOffset+i.payloadLength+L!==t)throw new Error("Invalid carrier layout");return i}async function De(e,{onBootstrap:t=()=>{},fetcher:r=fetch}={}){let n=new URL(e,globalThis.location?.href);if(n.protocol!=="https:"&&!(n.protocol==="http:"&&["localhost","127.0.0.1"].includes(n.hostname)))throw new Error("HTTPS required");let i,o,s;return te(async(h,l,c=!1)=>{if(s)return c?s.slice(-L):s.slice(h,l+1);let f=await r(n,{headers:{Range:c?`bytes=-${L}`:`bytes=${h}-${l}`,...o?{"If-Range":o}:{}},cache:"no-store",credentials:"omit",redirect:"error"});if(f.status===404||f.status===410)throw new Error("No AMW footer");if(f.status===200){let k=f.headers.get("Content-Length");if(k!==null&&(!/^[0-9]+$/.test(k)||!Number.isSafeInteger(Number(k))))throw new Error("Invalid full response length");if(s=await S(f,ee),s.length<L&&c)throw new Error("No AMW footer");if(k!==null&&s.length!==Number(k)||i!==void 0&&i!==s.length)throw new Error("Full response length changed");return i=s.length,c?s.slice(-L):s.slice(h,l+1)}if(f.status!==206)throw new Error("Host must support HTTP byte ranges");let u=/^bytes (\d+)-(\d+)\/(\d+)$/.exec(f.headers.get("Content-Range")||"");if(!u)throw new Error("Invalid Content-Range");let[p,g,w]=u.slice(1).map(Number);if(Number.isSafeInteger(w)&&w<L)throw new Error("No AMW footer");if(!Number.isSafeInteger(w)||i!==void 0&&i!==w||(c?g!==w-1||g-p+1!==L:p!==h||g!==l))throw new Error("Range changed or mismatched");let d=f.headers.get("ETag");if(o&&d&&d!==o)throw new Error("ETag changed during load");!o&&d&&!d.startsWith("W/")&&(o=d),i=w;let y=await S(f,g-p+1);if(y.length!==g-p+1)throw new Error("Short range response");return y},()=>i,!n.pathname.endsWith(".amw"),t)}async function qe(e,{onBootstrap:t=()=>{}}={}){let r=e instanceof Uint8Array?e:new Uint8Array(e);if(r.length<L||r.length>ee)throw new Error("Invalid local index size");return te(async(i,o,s=!1)=>s?r.slice(-L):r.slice(i,o+1),()=>r.length,!0,t)}async function Fe(e){let t=e instanceof Uint8Array?e:new Uint8Array(e);if(t.length<P||t.length>ee)throw new Error("Invalid private index size");return te(async(n,i)=>t.slice(n,i+1),()=>t.length,!1,()=>{})}async function te(e,t,r,n){let i=r?Cr(await e(0,0,!0),t()):null,o=i?.payloadOffset||0,s=await e(o,o+P-1),a=kr(s);if(i&&a.total!==i.payloadLength)throw new Error("Payload length mismatch");if(!i&&t()!==a.total)throw new Error("AMW length mismatch");let h=await e(o+a.manifestOffset,o+a.manifestOffset+a.manifestLength-1);if(!Y(await F(h),a.manifestHash))throw new Error("Manifest integrity failure");let l=J(h);if(l.format!=="amw.sections.v1"||!Array.isArray(l.sections)||l.sections.length!==2)throw new Error("Invalid manifest");let c=P+a.manifestLength;for(let d of l.sections){if(d.offset!==c||!Number.isSafeInteger(d.length)||d.length<1||!/^[0-9a-f]{64}$/.test(d.sha256))throw new Error("Invalid section layout");c+=d.length}if(c!==a.total||l.sections[0].id!=="bootstrap"||l.sections[1].id!=="document"||l.sections.some(d=>d.type!=="amw.document.v1")||l.sections[0].offset!==a.bootstrapOffset||l.sections[0].length!==a.bootstrapLength)throw new Error("Invalid section layout");let f=new Uint8Array(a.total);f.set(s,0),f.set(h,a.manifestOffset);let u=async d=>{let y=await e(o+d.offset,o+d.offset+d.length-1);if([...await F(y)].map(Q=>Q.toString(16).padStart(2,"0")).join("")!==d.sha256)throw new Error("Section integrity failure");return f.set(y,d.offset),y},p=await u(l.sections[0]);if(!Y(await F(p),a.bootstrapHash))throw new Error("Bootstrap integrity failure");let g=J(p);if(i?.version===2){let d=await F(f.subarray(0,a.bootstrapOffset+a.bootstrapLength));if(!Y(d.subarray(0,24),i.bootstrapPrefixHash))throw new Error("Bootstrap prefix integrity failure");n(g)}let w=J(await u(l.sections[1]));if(i&&!Y(await F(f),i.payloadHash))throw new Error("Payload integrity failure");return(!i||i.version===1)&&n(g),w}var Ye=/^[0-9a-f]{64}$/,xr=/^[0-9a-f]{24}$/,Lr=16*1024*1024+16,Tr=e=>[...e].map(t=>t.toString(16).padStart(2,"0")).join("");function z(e){if(!e||typeof e!="object"||Array.isArray(e)||Object.keys(e).some(t=>!["algorithm","url","offset","length","sha256","nonce","key"].includes(t))||e.algorithm!=="AES-256-GCM"||typeof e.url!="string"||!/^\/(?!\/)[A-Za-z0-9._/-]+$/.test(e.url)||e.url==="/favicon.ico"||e.url.startsWith("/amoosed.com/")||e.url.slice(1).split("/").some(t=>!t||t==="."||t==="..")||!Number.isSafeInteger(e.offset)||e.offset<0||!Number.isSafeInteger(e.length)||e.length<17||e.length>Lr||!Ye.test(e.sha256)||!xr.test(e.nonce)||!Ye.test(e.key))throw new Error("Invalid private index locator");return e}async function $e(e,t=fetch,r=location.origin){if(!e?.privateIndex)return e;if(e.webApp)throw new Error("Ambiguous index file");let n=z(e.privateIndex),i=new URL(n.url,r);if(i.origin!==r)throw new Error("Private index changed origin");let o=await t(i.href,{headers:{Range:`bytes=${n.offset}-${n.offset+n.length-1}`},cache:"no-store",credentials:"omit",redirect:"error"});if(!o.ok||new URL(o.url,r).origin!==r)throw new Error("Private index carrier unavailable");let s;if(o.status===206){let u=/^bytes (\d+)-(\d+)\/(\d+)$/.exec(o.headers.get("Content-Range")||"");if(!u||Number(u[1])!==n.offset||Number(u[2])!==n.offset+n.length-1||!Number.isSafeInteger(Number(u[3])))throw new Error("Private index range mismatch");s=await S(o,n.length)}else if(o.status===200)s=(await S(o,16777216)).slice(n.offset,n.offset+n.length);else throw new Error("Private index carrier needs byte ranges");if(s.length!==n.length||Tr(new Uint8Array(await crypto.subtle.digest("SHA-256",s)))!==n.sha256)throw new Error("Private index integrity failure");let a=await crypto.subtle.importKey("raw",Uint8Array.from(n.key.match(/../g),u=>parseInt(u,16)),"AES-GCM",!1,["decrypt"]),h=Uint8Array.from(n.nonce.match(/../g),u=>parseInt(u,16)),l=new TextEncoder().encode(`AMW1-PRIVATE-INDEX\0${n.url}\0${n.offset}`),c;try{c=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:h,additionalData:l},a,s))}catch{throw new Error("Private index key or authentication failed")}let f=await Fe(c);if(f.privateIndex)throw new Error("Nested private index is not supported");return f}var Ge="AMQ1",j=93,We=new TextEncoder,ie=new TextDecoder("utf-8",{fatal:!0});function re(e){return Uint8Array.from(e.match(/../g),t=>Number.parseInt(t,16))}function ne(e){return[...e].map(t=>t.toString(16).padStart(2,"0")).join("")}function ze(e){return btoa(String.fromCharCode(...e)).replaceAll("+","-").replaceAll("/","_").replace(/=+$/,"")}function Mr(e){let t=z(e),r=We.encode(t.url);if(r.length>255)throw new Error("Private index carrier path is too long for a QR token");let n=new Uint8Array(j+r.length);n.set(We.encode(Ge)),n[4]=r.length;let i=new DataView(n.buffer);return i.setBigUint64(5,BigInt(t.offset)),i.setUint32(13,t.length),n.set(re(t.sha256),17),n.set(re(t.nonce),49),n.set(re(t.key),61),n.set(r,j),ze(n)}function oe(e){if(typeof e!="string"||!/^[A-Za-z0-9_-]{124,464}$/.test(e))throw new Error("Invalid Amoosed QR key");let t;try{t=Uint8Array.from(atob(e.replaceAll("-","+").replaceAll("_","/")),o=>o.charCodeAt(0))}catch{throw new Error("Invalid Amoosed QR key")}if(t.length!==j+t[4]||ie.decode(t.subarray(0,4))!==Ge||ze(t)!==e)throw new Error("Invalid Amoosed QR key");let r=new DataView(t.buffer),n=Number(r.getBigUint64(5)),i={algorithm:"AES-256-GCM",url:ie.decode(t.subarray(j)),offset:n,length:r.getUint32(13),sha256:ne(t.subarray(17,49)),nonce:ne(t.subarray(49,61)),key:ne(t.subarray(61,93))};if(z(i),Mr(i)!==e)throw new Error("Invalid Amoosed QR key");return i}function je(e){let t=typeof e=="string"?e:ie.decode(e),r=/^AMWKEY1:([A-Za-z0-9_-]{124,464})\r?\n?$/.exec(t);if(!r)throw new Error("Invalid Amoosed key file");return oe(r[1]),r[1]}var Sr="AMM1",se=new TextDecoder("utf-8",{fatal:!0}),Br=/^[a-z0-9][a-z0-9._-]{0,63}$/i;function Or(e){return btoa(String.fromCharCode(...e)).replaceAll("+","-").replaceAll("/","_").replace(/=+$/,"")}function ae(e){if(typeof e!="string"||!/^[A-Za-z0-9_-]{51,135}$/.test(e))throw new Error("Invalid Amoosed member key");let t;try{t=Uint8Array.from(atob(e.replaceAll("-","+").replaceAll("_","/")),i=>i.charCodeAt(0))}catch{throw new Error("Invalid Amoosed member key")}if(t.length<38||t.length!==37+t[4]||se.decode(t.subarray(0,4))!==Sr||Or(t)!==e)throw new Error("Invalid Amoosed member key");let r=se.decode(t.subarray(37)),n=t.slice(5,37);if(!Br.test(r))throw new Error("Invalid Amoosed member key");return{keyId:r,key:n}}function Ve(e){let t=typeof e=="string"?e:se.decode(e),r=/^AMWMEMBER1:([A-Za-z0-9_-]{51,135})\r?\n?$/.exec(t);if(!r)throw new Error("Invalid Amoosed member key file");return ae(r[1]),r[1]}var $=/^[0-9a-f]{64}$/,vr=/^\/amoosed\.com\/app\/[A-Za-z0-9._/-]+$/,Ze=/^\/(?!\/)[A-Za-z0-9._/-]+$/,Rr=/^[a-z0-9.+-]+\/[a-z0-9.+-]+(?:; charset=utf-8)?$/,Pr=/^[A-Za-z0-9._-]{1,64}$/;function Xe(e,t,r){return new TextEncoder().encode(`AMW1-SEALED\0${e.path}\0${e.mime}\0${t}\0${r}`)}function Ke(e){return typeof e=="string"&&vr.test(e)&&!e.slice(1).split("/").some(t=>t==="."||t===".."||t==="")&&!e.endsWith("/")}function W(e,t){return!!e.encryption&&t.access!=="public"}function Qe(e){if(!e||typeof e!="object"||Array.isArray(e)||Object.keys(e).some(s=>!["launch","entry","resources","encryption","encoding","identity","audioCarriers"].includes(s))||e.launch!=="/amoosed.com/boot.html"||!Ke(e.entry)||!Array.isArray(e.resources)||e.resources.length<1||e.resources.length>4096)throw new Error("Invalid web app manifest");let t=e.encryption!==void 0;if(e.encoding!==void 0&&(!e.encoding||typeof e.encoding!="object"||Array.isArray(e.encoding)||Object.keys(e.encoding).some(s=>!["algorithm","key"].includes(s))||e.encoding.algorithm!=="AES-256-CTR"||typeof e.encoding.key!="string"||!$.test(e.encoding.key)))throw new Error("Invalid web app encoding");if(e.identity!==void 0&&(!e.identity||typeof e.identity!="object"||Array.isArray(e.identity)||Object.keys(e.identity).some(s=>!["title","icon"].includes(s))||typeof e.identity.title!="string"||!e.identity.title||e.identity.title.length>200||e.identity.icon!=="/amoosed.com/app/favicon.ico"))throw new Error("Invalid app identity");if(t&&(!e.encryption||typeof e.encryption!="object"||Array.isArray(e.encryption)||Object.keys(e.encryption).some(s=>!["algorithm","keyId"].includes(s))||e.encryption.algorithm!=="AES-256-GCM"||typeof e.encryption.keyId!="string"||!Pr.test(e.encryption.keyId)))throw new Error("Invalid web app encryption");if(e.audioCarriers!==void 0){if(!e.audioCarriers||typeof e.audioCarriers!="object"||Array.isArray(e.audioCarriers)||Object.keys(e.audioCarriers).length>64)throw new Error("Invalid audio carrier map");for(let[s,a]of Object.entries(e.audioCarriers))if(!Ze.test(s)||!s.endsWith(".wav")||!a||a.format!=="amw.audio-carrier.v1"||!Number.isInteger(a.length)||a.length<1||a.length>4096||!$.test(a.sha256)||!Array.isArray(a.packets)||a.packets.length<1||a.packets.length>32||!Array.isArray(a.locations)||a.locations.length!==a.packets.length*3||a.packets.some((h,l)=>h.index!==l||!Number.isInteger(h.length)||h.length<1||h.length>128||!$.test(h.sha256))||a.packets.reduce((h,l)=>h+l.length,0)!==a.length||a.locations.some(h=>!Number.isInteger(h.packet)||h.packet<0||h.packet>=a.packets.length||!Number.isFinite(h.startSeconds)||h.startSeconds<0||!Number.isFinite(h.durationSeconds)||h.durationSeconds<=0))throw new Error("Invalid audio carrier map")}let r="",n=0,i=new Set;for(let s of e.resources){if(!s||typeof s!="object"||Array.isArray(s)||Object.keys(s).some(l=>!["path","mime","length","sha256","parts","access","delivery"].includes(l))||!Ke(s.path)||s.path<=r||s.access!==void 0&&(!t||!["public","members"].includes(s.access))||s.delivery!==void 0&&s.delivery!=="download"||typeof s.mime!="string"||!Rr.test(s.mime)||!Number.isSafeInteger(s.length)||s.length<1||s.length>1024*1024*1024||typeof s.sha256!="string"||!$.test(s.sha256)||!Array.isArray(s.parts)||s.parts.length<1||s.parts.length>16384)throw new Error("Invalid web app resource");r=s.path;let a=W(e,s);a&&n++;let h=0;for(let l of s.parts){if(!l||typeof l!="object"||Array.isArray(l)||Object.keys(l).some(c=>!["url","offset","length","sha256","codec",...a?["nonce","plainLength"]:[]].includes(c))||typeof l.url!="string"||typeof l.sha256!="string"||!$.test(l.sha256)||!Ze.test(l.url)||l.url.slice(1).split("/").some(c=>!c||c==="."||c==="..")||l.url==="/favicon.ico"||l.url.startsWith("/amoosed.com/")||l.codec!==void 0&&!(l.codec==="png-lsb1"&&l.url.endsWith(".png")||l.codec==="wav-4fsk1"&&l.url.endsWith(".wav")&&e.audioCarriers?.[l.url]||["frame-luma1","frame-luma2"].includes(l.codec)&&l.url.endsWith(".png")&&l.offset===0&&l.length<=21)||!Number.isSafeInteger(l.offset)||l.offset<0||!Number.isSafeInteger(l.length)||l.length<1||l.length>4*1024*1024+(a?16:0)||a&&(typeof l.nonce!="string"||!/^[0-9a-f]{24}$/.test(l.nonce)||!Number.isSafeInteger(l.plainLength)||l.plainLength<1||l.plainLength>4*1024*1024||l.length!==l.plainLength+16))throw new Error("Invalid web app shard");if(a){if(i.has(l.nonce))throw new Error("Repeated web app nonce");i.add(l.nonce)}h+=a?l.plainLength:l.length}if(h!==s.length)throw new Error("Web app resource length mismatch")}if(t&&n===0)throw new Error("Encrypted app has no member resources");let o=e.resources.find(s=>s.path===e.entry);if(!o||!o.mime.startsWith("text/html"))throw new Error("Web app entry must be HTML");if(o.delivery==="download")throw new Error("Web app entry cannot be a download");if(e.identity){let s=e.resources.find(a=>a.path===e.identity.icon);if(!s||s.mime!=="image/x-icon"||W(e,s)||s.delivery==="download")throw new Error("App identity favicon must be public")}return e}var Zt=Ue(Ie(),1);import{createHash as Fn,timingSafeEqual as Yn}from"node:crypto";var $n=Buffer.from("AMWPX1\0\0"),q=44,jt=16*1024*1024,Wn=16*1024*1024;function Gn(e,t){for(;t;)[e,t]=[t,e%t];return e}function zn(e){if(!Buffer.isBuffer(e)||e.length<33||!e.subarray(0,8).equals(Buffer.from("89504e470d0a1a0a","hex"))||e.toString("ascii",12,16)!=="IHDR")throw new Error("Expected a PNG image");let t=e.readUInt32BE(16),r=e.readUInt32BE(20);if(!t||!r||t*r>jt)throw new Error("PNG pixel count exceeds limit");let n=Zt.PNG.sync.read(e,{checkCRC:!0}),i=n.width*n.height;if(!Number.isSafeInteger(i)||i<1||i>jt)throw new Error("PNG pixel count exceeds limit");let o=[];for(let h=0;h<i;h++)n.data[h*4+3]===255&&o.push(h);let s=o.length*3;if(s<q*8)throw new Error("PNG has too few opaque pixels");let a=65537;for(;Gn(a,s)!==1;)a+=2;return{png:n,opaque:Uint32Array.from(o),slots:s,stride:a}}function Vt(e,t,r){if(t.length*8>e.slots)throw new Error("Pixel carrier capacity exceeded");let n=0;for(let i=0;i<t.length;i++){let o=r?t[i]:0;for(let s=7;s>=0;s--){let a=e.opaque[Math.floor(n/3)]*4+n%3;r?e.png.data[a]=e.png.data[a]&254|o>>>s&1:o=o<<1|e.png.data[a]&1,n=(n+e.stride)%e.slots}r||(t[i]=o)}}function ke(e){let t=zn(e),r=Buffer.alloc(q);if(Vt(t,r,!1),!r.subarray(0,8).equals($n))throw new Error("No AmoosedWeb pixel payload");let n=r.readUInt32LE(8);if(n<1||n>Wn||n+q>Math.floor(t.slots/8))throw new Error("Invalid pixel payload length");let i=Buffer.alloc(q+n);Vt(t,i,!1);let o=Fn("sha256").update(i.subarray(q)).digest();if(!Yn(o,r.subarray(12,44)))throw new Error("Pixel payload integrity failure");return i.subarray(q)}import{createHash as Xt,timingSafeEqual as Jn}from"node:crypto";var so=Buffer.from("AMW-MEDIA-TRANSPORT-V1");import{createHash as jn}from"node:crypto";var Vn=e=>jn("sha256").update(e).digest("hex");function Ce(e,t){return e.length===t.length&&Vn(e)===t.sha256}var ei=[1e3,1500,2e3,2500],Z=Array.from({length:16},(e,t)=>t&1?3:0),ti=Buffer.from("AWA1"),xe=128,V=54,Qt=4096,ri=128*1024*1024,ni=3,ii=e=>Xt("sha256").update(e).digest("hex");function oi(e){return Z.length+e.length*4}function si(e){if(!Buffer.isBuffer(e)||e.length<44||e.length>ri||e.toString("ascii",0,4)!=="RIFF"||e.toString("ascii",8,12)!=="WAVE")throw new Error("Expected a bounded PCM WAV file");let t,r;for(let a=12;a+8<=e.length;){let h=e.toString("ascii",a,a+4),l=e.readUInt32LE(a+4);if(a+8+l>e.length)throw new Error("Invalid WAV chunk");h==="fmt "&&(t=e.subarray(a+8,a+8+l)),h==="data"&&(r=e.subarray(a+8,a+8+l)),a+=8+l+(l&1)}if(!t||t.length<16||!r||t.readUInt16LE(0)!==1||![1,2].includes(t.readUInt16LE(2))||![16e3,44100,48e3].includes(t.readUInt32LE(4))||![8,16].includes(t.readUInt16LE(14)))throw new Error("Expected 16/44.1/48 kHz 8/16-bit PCM");let n=t.readUInt16LE(2),i=t.readUInt32LE(4),o=t.readUInt16LE(14)/8;if(r.length%(n*o))throw new Error("Invalid WAV sample length");let s=new Float32Array(r.length/(n*o));for(let a=0;a<s.length;a++){let h=0;for(let l=0;l<n;l++){let c=(a*n+l)*o;h+=o===1?(r[c]-128)/128:r.readInt16LE(c)/32768}s[a]=h/n}return{samples:s,rate:i}}function ai(e,t,r,n){let i=r+Math.round(t*.001),o=r+Math.round(t*.009);if(i<0||o>=e.length)return-1;let s=0,a=0,h=2*Math.PI*n/t;for(let l=i;l<o;l++)s+=e[l]*Math.cos(h*(l-i)),a+=e[l]*Math.sin(h*(l-i));return s*s+a*a}function Jt(e,t,r){let n=-1,i=0;for(let o=0;o<4;o++){let s=ai(e,t,r,ei[o]);s>n&&(n=s,i=o)}return i}function Kt(e,t,r,n){let i=Buffer.alloc(n),o=t/100;for(let s=0;s<n;s++)for(let a=0;a<4;a++)i[s]=i[s]<<2|Jt(e,t,Math.round(r+(Z.length+s*4+a)*o));return i}function Le(e,t,r,n){let i=t/100,o=-1,s=-1;for(let w=-2;w<=1;w+=.5){let d=r+Math.round(w*t/1e3);if(d<0)continue;let y=0;for(let k=0;k<Z.length;k++)Jt(e,t,Math.round(d+k*i))===Z[k]&&y++;y>s&&(s=y,o=d)}if(s<14)return null;let a=Kt(e,t,o,V);if(!a.subarray(0,4).equals(ti))return null;let h=a.readUInt32LE(4),l=a.readUInt16LE(8),c=a.readUInt16LE(10),f=a.readUInt16LE(12);if(h<1||h>Qt||l!==Math.ceil(h/xe)||c>=l||f!==Math.min(xe,h-c*xe)||o+oi(Buffer.alloc(V+f))*i>n+t*.004)return null;let p=Kt(e,t,o,V+f).subarray(V),g=Xt("sha256").update(p).digest().subarray(0,8);return Jn(g,a.subarray(46,54))?{total:h,count:l,index:c,sha256:a.subarray(14,46).toString("hex"),data:p}:null}function li(e,t=[]){let{samples:r,rate:n}=si(e),i=Math.round(n/1e3),o=[];for(let l of t){if(!Number.isFinite(l.startSeconds)||l.startSeconds<0)continue;let c=Math.round(l.startSeconds*n);for(let f=-3;f<=3;f+=.5){let u=Le(r,n,c+Math.round(f*n/1e3),r.length);if(u&&u.index===l.packet){o.push(u);break}}}if(o.length===t.length&&t.length)return o;let s=!1,a=0,h=0;for(let l=0;l<r.length;l+=i){let c=0;for(let u=l;u<Math.min(l+i,r.length);u++)c+=r[u]*r[u];let f=c/i>.002;if(f&&!s?(s=!0,a=l,h=0):f?h=0:s&&h++,s&&h>=20){s=!1;let u=Le(r,n,a,l-19*i);u&&o.push(u)}}if(s){let l=Le(r,n,a,r.length);l&&o.push(l)}return o}function er(e,t){if(!t||t.format!=="amw.audio-carrier.v1"||!Number.isInteger(t.length)||t.length<1||t.length>Qt||!/^[0-9a-f]{64}$/.test(t.sha256)||!Array.isArray(t.packets)||t.packets.length<1||t.packets.length>32||!Array.isArray(t.locations)||t.locations.length!==t.packets.length*ni||t.locations.some(i=>!Number.isInteger(i.packet)||i.packet<0||i.packet>=t.packets.length||!Number.isFinite(i.startSeconds)||i.startSeconds<0))throw new Error("Invalid audio carrier manifest");let r=new Map;for(let i of li(e,t.locations))i.total!==t.length||i.count!==t.packets.length||i.sha256!==t.sha256||!Ce(i.data,t.packets[i.index])||r.has(i.index)||r.set(i.index,i.data);if(r.size!==t.packets.length)throw new Error("Audio carrier recovery incomplete");let n=Buffer.concat(t.packets.map((i,o)=>r.get(o)));if(n.length!==t.length||ii(n)!==t.sha256)throw new Error("Audio carrier integrity failure");return n}var sr=Ue(Ie(),1);import{createHash as hi}from"node:crypto";function tr(e,t,r){let n=t*r;if(!Number.isSafeInteger(n)||t<256||r<128||n>16*1024*1024||e.length!==n*4)throw new Error("Invalid frame dimensions");let i=(c,f)=>{for(;f;)[c,f]=[f,c%f];return c},o=Math.floor(n*.61803398875)|1;for(;i(o,n)!==1;)o+=2;let s=((Math.imul(t,73856093)^Math.imul(r,19349663))>>>0)%n,a=new Uint32Array(768),h=c=>{let f=c*4;return(299*(e[f]&254)+587*(e[f+1]&254)+114*(e[f+2]&254))/1e3},l=c=>{let f=c%t,u=Math.floor(c/t),p=h(c),g=0;return f>0&&(g+=Math.abs(p-h(c-1))),f+1<t&&(g+=Math.abs(p-h(c+1))),u>0&&(g+=Math.abs(p-h(c-t))),u+1<r&&(g+=Math.abs(p-h(c+t))),g};for(let c=0,f=0;c<n&&f<a.length;){let u=-1,p=-1;for(let g=0;g<16&&c<n;g++,c++){let w=(s+c*o)%n;if(e[w*4+3]!==255)continue;let d=l(w);d>p&&(u=w,p=d)}if(u>=0&&(a[f++]=u),f===a.length)return a}throw new Error("Frame needs at least 768 opaque pixels")}var Co=Buffer.from("AWF1"),M=8,rr=32,nr=16,Te=11,ci=32-Te,ir=3;var fi=e=>hi("sha256").update(e).digest();function ui(e){if(!Buffer.isBuffer(e)||e.length<33||!e.subarray(0,8).equals(Buffer.from("89504e470d0a1a0a","hex"))||e.readUInt32BE(16)*e.readUInt32BE(20)>16*1024*1024)throw new Error("Expected a bounded PNG frame");let t=sr.PNG.sync.read(e,{checkCRC:!0});if(t.width<rr*M||t.height<nr*M)throw new Error("Frame must be at least 256 x 128 pixels");for(let r=0;r<nr*M;r++)for(let n=0;n<rr*M;n++)if(t.data[(r*t.width+n)*4+3]!==255)throw new Error("Frame data region must be opaque");return t}function or(e,t,r){let n=0;for(let i=0;i<M;i++)for(let o=0;o<M;o++){let s=((r+i)*e.width+t+o)*4;n+=(e.data[s]*299+e.data[s+1]*587+e.data[s+2]*114)/1e3}return n/(M*M)}function di(e){let t=Math.floor(e/16);return[e%16*2*M,t*M]}function pi(e){let t=Buffer.alloc(32);for(let r=0;r<t.length*8;r++){let[n,i]=di(r);or(e,n,i)>or(e,n+M,i)&&(t[r>>>3]|=1<<7-(r&7))}return t}function ar(e){let t=ui(e),r=tr(t.data,t.width,t.height),n=Buffer.alloc(32);for(let i=0;i<256;i++){let o=0;for(let s=0;s<ir;s++)o+=t.data[r[i*ir+s]*4]&1;o>=2&&(n[i>>>3]|=1<<7-(i&7))}return n.subarray(0,4).toString("ascii")!=="AWF2"?gi(t):lr(n,"AWF2")}function gi(e){return lr(pi(e),"AWF1")}function lr(e,t){if(e.subarray(0,4).toString("ascii")!==t||e.readUInt16LE(4)!==0||e[6]<1||e[6]>ci)throw new Error("Invalid luminance frame payload");let r=e.subarray(Te,Te+e[6]);if(!fi(r).subarray(0,4).equals(e.subarray(7,11)))throw new Error("Luminance frame integrity failure");return r}var _i=16*1024*1024,bi=e=>Oe("sha256").update(e).digest("hex"),ur=e=>Buffer.from(e,"hex");function Be(e,t){let r=gr(e,t);return r&&r!==".."&&!r.startsWith(`..${wr}`)&&!mi(r)&&!r.includes(":")}async function dr(e,t){if(t!==e&&!Be(e,t))throw new Error("Unsafe resource output path");let r=await Se(e);if(!r.isDirectory()||r.isSymbolicLink())throw new Error("Output root must be a real directory");let n=await fr(e);if(t===e)return;let i=e;for(let o of gr(e,t).split(wr)){i=yi(i,o);try{await ve(i)}catch(a){if(a.code!=="EEXIST")throw a}let s=await Se(i);if(!s.isDirectory()||s.isSymbolicLink()||!Be(n,await fr(i)))throw new Error("Output path traverses a symbolic link or junction")}}async function Ei(e,t){let r=await Me(e,"r"),n;try{n=await Me(t,"wx",384);let i=Buffer.allocUnsafe(64*1024);for(;;){let{bytesRead:o}=await r.read(i,0,i.length,null);if(!o)break;let s=0;for(;s<o;){let{bytesWritten:a}=await n.write(i,s,o-s,null);if(!a)throw new Error("Incomplete local write");s+=a}}}catch(i){throw n&&(await n.close(),n=null,await pr(t).catch(()=>{})),i}finally{n&&await n.close(),await r.close()}}function Ai(e){let t=new URL(e);if(t.username||t.password||!(t.protocol==="https:"||t.protocol==="http:"&&["localhost","127.0.0.1"].includes(t.hostname)))throw new Error("Remote site requires HTTPS or local HTTP");return t.origin}async function Ii(e,t,r){let n=new URL(t.url,e.origin);if(n.origin!==e.origin)throw new Error("Carrier changed origin");let i=t.codec==="png-lsb1"?["pixel",64*1024*1024]:t.codec==="wav-4fsk1"?["audio",128*1024*1024]:["frame-luma1","frame-luma2"].includes(t.codec)?["frame",64*1024*1024]:null;if(i){if(!r.has(t.url)){let h=await e.fetcher(n,{cache:"no-store",credentials:"omit",redirect:"error"});if(h.status!==200||new URL(h.url,e.origin).origin!==e.origin)throw new Error(`${t.url}: media carrier unavailable`);let l=Buffer.from(await S(h,i[1])),c=i[0]==="pixel"?ke(l):i[0]==="audio"?er(l,e.app.audioCarriers?.[t.url]):ar(l);r.set(t.url,c)}return r.get(t.url).subarray(t.offset,t.offset+t.length)}let o=t.offset+t.length-1,s=await e.fetcher(n,{headers:{Range:`bytes=${t.offset}-${o}`},cache:"no-store",credentials:"omit",redirect:"error"});if(![200,206].includes(s.status)||new URL(s.url,e.origin).origin!==e.origin)throw new Error(`${t.url}: carrier unavailable`);if(s.status===206){let h=/^bytes (\d+)-(\d+)\/(\d+)$/.exec(s.headers.get("Content-Range")||"");if(!h||Number(h[1])!==t.offset||Number(h[2])!==o||!Number.isSafeInteger(Number(h[3])))throw new Error(`${t.url}: invalid range`);return Buffer.from(await S(s,t.length))}return Buffer.from(await S(s,_i)).subarray(t.offset,o+1)}function ki(e,t,r,n,i){if(i.length!==n.length||bi(i)!==n.sha256)throw new Error(`${n.url}: chunk integrity failure`);let o=i;if(e.app.encoding){let s=Oe("sha256").update(`AMW1-SITE-CTR\0${t.path}\0${r}`).digest().subarray(0,16),a=hr("aes-256-ctr",ur(e.app.encoding.key),s);o=Buffer.concat([a.update(o),a.final()])}if(W(e.app,t)){if(!e.contentKey)throw new Error("Member content key required");try{let s=hr("aes-256-gcm",e.contentKey,ur(n.nonce));if(s.setAAD(Xe(t,r,n.plainLength)),s.setAuthTag(o.subarray(-16)),o=Buffer.concat([s.update(o.subarray(0,-16)),s.final()]),o.length!==n.plainLength)throw new Error("Plaintext length mismatch")}catch{throw new Error("Member key or chunk authentication failed")}}return o}async function Do(e,{credential:t,indexKeyFile:r,contentKey:n,memberKeyFile:i,fetcher:o=fetch}={}){let s=Ai(e);if(t&&r||n&&i)throw new Error("Supply one source for each key");if(r){let c=await cr(r);t=c.subarray(0,8).toString("ascii")==="AMWKEY1:"?{indexToken:je(c)}:{indexBytes:c}}let a;if(i){let c=await cr(i),f=c.toString("utf8").trim();if(/^[0-9a-fA-F]{64}$/.test(f))n=Buffer.from(f,"hex");else{let u=ae(Ve(c));a=u.keyId,n=Buffer.from(u.key)}}if(n&&(!(n instanceof Uint8Array)||n.length!==32))throw new Error("Invalid member content key");let h;t?.indexToken?h={privateIndex:oe(t.indexToken)}:t?.indexBytes?h=await qe(t.indexBytes):h=await De(`${s}/favicon.ico`,{fetcher:o}),h=await $e(h,o,s);let l=Qe(h.webApp);if(a&&l.encryption?.keyId!==a)throw new Error("Member key belongs to another edition");return{origin:s,app:l,contentKey:n&&Buffer.from(n),fetcher:o}}function qo(e){return e.app.resources.map(t=>({path:t.path,bytes:t.length,sha256:t.sha256,mime:t.mime,access:W(e.app,t)?"members":"public",delivery:t.delivery||"app"}))}async function Ci(e,t,r,{outputRoot:n}={}){let i=e.app.resources.find(f=>f.path===t);if(!i)throw new Error("Resource is absent from the verified index");let o=X(r);n?await dr(n,K(o)):await ve(K(o),{recursive:!0});let s=X(K(o),`.amw-download-${wi(12).toString("hex")}`),a=await Me(s,"wx",384),h=Oe("sha256"),l=new Map,c=0;try{try{for(let[f,u]of i.parts.entries()){let p=ki(e,i,f,u,await Ii(e,u,l));h.update(p),c+=p.length;let g=0;for(;g<p.length;){let{bytesWritten:w}=await a.write(p,g,p.length-g,null);if(!w)throw new Error("Incomplete local write");g+=w}}}finally{await a.close()}if(c!==i.length||h.digest("hex")!==i.sha256)throw new Error("Resource integrity failure");return n&&await dr(n,K(o)),await Ei(s,o),{path:o,bytes:c,sha256:i.sha256}}finally{await pr(s).catch(f=>{if(f.code!=="ENOENT")throw f})}}async function Fo(e,t){let r=X(t);await ve(r,{recursive:!0});let n=await Se(r);if(!n.isDirectory()||n.isSymbolicLink())throw new Error("Output root must be a real directory");let i=[];for(let o of e.app.resources){let s=o.path.slice(17),a=X(r,s);if(!Be(r,a))throw new Error("Unsafe resource output path");i.push(await Ci(e,o.path,a,{outputRoot:r}))}return i}export{Ci as downloadRemoteResource,Fo as downloadRemoteSite,qo as listRemoteResources,Do as openRemoteSite};
|
|
1
|
+
// Copyright (c) 2026 Juhapekka Piiroinen <jp@1337.fi>
|
|
2
|
+
// All Rights Reserved.
|
|
3
|
+
// AmoosedWeb project: https://amoosed.com
|
|
4
|
+
const reader = process.platform === 'win32' && process.arch === 'x64'
|
|
5
|
+
? await import('./native/compat.mjs')
|
|
6
|
+
: await import('./js-reader.mjs');
|
|
7
|
+
|
|
8
|
+
export const openRemoteSite = (...args) => reader.openRemoteSite(...args);
|
|
9
|
+
export const listRemoteResources = (...args) => reader.listRemoteResources(...args);
|
|
10
|
+
export const downloadRemoteResource = (...args) => reader.downloadRemoteResource(...args);
|
|
11
|
+
export const downloadRemoteSite = (...args) => reader.downloadRemoteSite(...args);
|
package/js-reader.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire as __amwCreateRequire } from 'node:module'; const require = __amwCreateRequire(import.meta.url);
|
|
2
|
+
var wr=Object.create;var Re=Object.defineProperty;var yr=Object.getOwnPropertyDescriptor;var mr=Object.getOwnPropertyNames;var _r=Object.getPrototypeOf,br=Object.prototype.hasOwnProperty;var E=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var m=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Er=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of mr(t))!br.call(e,i)&&i!==r&&Re(e,i,{get:()=>t[i],enumerable:!(n=yr(t,i))||n.enumerable});return e};var Pe=(e,t,r)=>(r=e!=null?wr(_r(e)):{},Er(t||!e||!e.__esModule?Re(r,"default",{value:e,enumerable:!0}):r,e));var le=m((Ni,Je)=>{"use strict";var Pr=E("util"),Qe=E("stream"),T=Je.exports=function(){Qe.call(this),this._buffers=[],this._buffered=0,this._reads=[],this._paused=!1,this._encoding="utf8",this.writable=!0};Pr.inherits(T,Qe);T.prototype.read=function(e,t){this._reads.push({length:Math.abs(e),allowLess:e<0,func:t}),process.nextTick(function(){this._process(),this._paused&&this._reads&&this._reads.length>0&&(this._paused=!1,this.emit("drain"))}.bind(this))};T.prototype.write=function(e,t){if(!this.writable)return this.emit("error",new Error("Stream not writable")),!1;let r;return Buffer.isBuffer(e)?r=e:r=Buffer.from(e,t||this._encoding),this._buffers.push(r),this._buffered+=r.length,this._process(),this._reads&&this._reads.length===0&&(this._paused=!0),this.writable&&!this._paused};T.prototype.end=function(e,t){e&&this.write(e,t),this.writable=!1,this._buffers&&(this._buffers.length===0?this._end():(this._buffers.push(null),this._process()))};T.prototype.destroySoon=T.prototype.end;T.prototype._end=function(){this._reads.length>0&&this.emit("error",new Error("Unexpected end of input")),this.destroy()};T.prototype.destroy=function(){this._buffers&&(this.writable=!1,this._reads=null,this._buffers=null,this.emit("close"))};T.prototype._processReadAllowingLess=function(e){this._reads.shift();let t=this._buffers[0];t.length>e.length?(this._buffered-=e.length,this._buffers[0]=t.slice(e.length),e.func.call(this,t.slice(0,e.length))):(this._buffered-=t.length,this._buffers.shift(),e.func.call(this,t))};T.prototype._processRead=function(e){this._reads.shift();let t=0,r=0,n=Buffer.alloc(e.length);for(;t<e.length;){let i=this._buffers[r++],o=Math.min(i.length,e.length-t);i.copy(n,t,0,o),t+=o,o!==i.length&&(this._buffers[--r]=i.slice(o))}r>0&&this._buffers.splice(0,r),this._buffered-=e.length,e.func.call(this,n)};T.prototype._process=function(){try{for(;this._buffered>0&&this._reads&&this._reads.length>0;){let e=this._reads[0];if(e.allowLess)this._processReadAllowingLess(e);else if(this._buffered>=e.length)this._processRead(e);else break}this._buffers&&!this.writable&&this._end()}catch(e){this.emit("error",e)}}});var ce=m(he=>{"use strict";var v=[{x:[0],y:[0]},{x:[4],y:[0]},{x:[0,4],y:[4]},{x:[2,6],y:[0,4]},{x:[0,2,4,6],y:[2,6]},{x:[1,3,5,7],y:[0,2,4,6]},{x:[0,1,2,3,4,5,6,7],y:[1,3,5,7]}];he.getImagePasses=function(e,t){let r=[],n=e%8,i=t%8,o=(e-n)/8,s=(t-i)/8;for(let a=0;a<v.length;a++){let h=v[a],l=o*h.x.length,c=s*h.y.length;for(let f=0;f<h.x.length&&h.x[f]<n;f++)l++;for(let f=0;f<h.y.length&&h.y[f]<i;f++)c++;l>0&&c>0&&r.push({width:l,height:c,index:a})}return r};he.getInterlaceIterator=function(e){return function(t,r,n){let i=t%v[n].x.length,o=(t-i)/v[n].x.length*8+v[n].x[i],s=r%v[n].y.length,a=(r-s)/v[n].y.length*8+v[n].y[s];return o*4+a*e*4}}});var fe=m((qi,et)=>{"use strict";et.exports=function(t,r,n){let i=t+r-n,o=Math.abs(i-t),s=Math.abs(i-r),a=Math.abs(i-n);return o<=s&&o<=a?t:s<=a?r:n}});var ue=m((Di,rt)=>{"use strict";var Ur=ce(),Nr=fe();function tt(e,t,r){let n=e*t;return r!==8&&(n=Math.ceil(n/(8/r))),n}var N=rt.exports=function(e,t){let r=e.width,n=e.height,i=e.interlace,o=e.bpp,s=e.depth;if(this.read=t.read,this.write=t.write,this.complete=t.complete,this._imageIndex=0,this._images=[],i){let a=Ur.getImagePasses(r,n);for(let h=0;h<a.length;h++)this._images.push({byteWidth:tt(a[h].width,o,s),height:a[h].height,lineIndex:0})}else this._images.push({byteWidth:tt(r,o,s),height:n,lineIndex:0});s===8?this._xComparison=o:s===16?this._xComparison=o*2:this._xComparison=1};N.prototype.start=function(){this.read(this._images[this._imageIndex].byteWidth+1,this._reverseFilterLine.bind(this))};N.prototype._unFilterType1=function(e,t,r){let n=this._xComparison,i=n-1;for(let o=0;o<r;o++){let s=e[1+o],a=o>i?t[o-n]:0;t[o]=s+a}};N.prototype._unFilterType2=function(e,t,r){let n=this._lastLine;for(let i=0;i<r;i++){let o=e[1+i],s=n?n[i]:0;t[i]=o+s}};N.prototype._unFilterType3=function(e,t,r){let n=this._xComparison,i=n-1,o=this._lastLine;for(let s=0;s<r;s++){let a=e[1+s],h=o?o[s]:0,l=s>i?t[s-n]:0,c=Math.floor((l+h)/2);t[s]=a+c}};N.prototype._unFilterType4=function(e,t,r){let n=this._xComparison,i=n-1,o=this._lastLine;for(let s=0;s<r;s++){let a=e[1+s],h=o?o[s]:0,l=s>i?t[s-n]:0,c=s>i&&o?o[s-n]:0,f=Nr(l,h,c);t[s]=a+f}};N.prototype._reverseFilterLine=function(e){let t=e[0],r,n=this._images[this._imageIndex],i=n.byteWidth;if(t===0)r=e.slice(1,i+1);else switch(r=Buffer.alloc(i),t){case 1:this._unFilterType1(e,r,i);break;case 2:this._unFilterType2(e,r,i);break;case 3:this._unFilterType3(e,r,i);break;case 4:this._unFilterType4(e,r,i);break;default:throw new Error("Unrecognised filter type - "+t)}this.write(r),n.lineIndex++,n.lineIndex>=n.height?(this._lastLine=null,this._imageIndex++,n=this._images[this._imageIndex]):this._lastLine=r,n?this.read(n.byteWidth+1,this._reverseFilterLine.bind(this)):(this._lastLine=null,this.complete())}});var ot=m((Fi,it)=>{"use strict";var Hr=E("util"),nt=le(),qr=ue(),Dr=it.exports=function(e){nt.call(this);let t=[],r=this;this._filter=new qr(e,{read:this.read.bind(this),write:function(n){t.push(n)},complete:function(){r.emit("complete",Buffer.concat(t))}}),this._filter.start()};Hr.inherits(Dr,nt)});var H=m((Yi,st)=>{"use strict";st.exports={PNG_SIGNATURE:[137,80,78,71,13,10,26,10],TYPE_IHDR:1229472850,TYPE_IEND:1229278788,TYPE_IDAT:1229209940,TYPE_PLTE:1347179589,TYPE_tRNS:1951551059,TYPE_gAMA:1732332865,COLORTYPE_GRAYSCALE:0,COLORTYPE_PALETTE:1,COLORTYPE_COLOR:2,COLORTYPE_ALPHA:4,COLORTYPE_PALETTE_COLOR:3,COLORTYPE_COLOR_ALPHA:6,COLORTYPE_TO_BPP_MAP:{0:1,2:3,3:1,4:2,6:4},GAMMA_DIVISION:1e5}});var ge=m(($i,at)=>{"use strict";var de=[];(function(){for(let e=0;e<256;e++){let t=e;for(let r=0;r<8;r++)t&1?t=3988292384^t>>>1:t=t>>>1;de[e]=t}})();var pe=at.exports=function(){this._crc=-1};pe.prototype.write=function(e){for(let t=0;t<e.length;t++)this._crc=de[(this._crc^e[t])&255]^this._crc>>>8;return!0};pe.prototype.crc32=function(){return this._crc^-1};pe.crc32=function(e){let t=-1;for(let r=0;r<e.length;r++)t=de[(t^e[r])&255]^t>>>8;return t^-1}});var we=m((Wi,lt)=>{"use strict";var _=H(),Fr=ge(),b=lt.exports=function(e,t){this._options=e,e.checkCRC=e.checkCRC!==!1,this._hasIHDR=!1,this._hasIEND=!1,this._emittedHeadersFinished=!1,this._palette=[],this._colorType=0,this._chunks={},this._chunks[_.TYPE_IHDR]=this._handleIHDR.bind(this),this._chunks[_.TYPE_IEND]=this._handleIEND.bind(this),this._chunks[_.TYPE_IDAT]=this._handleIDAT.bind(this),this._chunks[_.TYPE_PLTE]=this._handlePLTE.bind(this),this._chunks[_.TYPE_tRNS]=this._handleTRNS.bind(this),this._chunks[_.TYPE_gAMA]=this._handleGAMA.bind(this),this.read=t.read,this.error=t.error,this.metadata=t.metadata,this.gamma=t.gamma,this.transColor=t.transColor,this.palette=t.palette,this.parsed=t.parsed,this.inflateData=t.inflateData,this.finished=t.finished,this.simpleTransparency=t.simpleTransparency,this.headersFinished=t.headersFinished||function(){}};b.prototype.start=function(){this.read(_.PNG_SIGNATURE.length,this._parseSignature.bind(this))};b.prototype._parseSignature=function(e){let t=_.PNG_SIGNATURE;for(let r=0;r<t.length;r++)if(e[r]!==t[r]){this.error(new Error("Invalid file signature"));return}this.read(8,this._parseChunkBegin.bind(this))};b.prototype._parseChunkBegin=function(e){let t=e.readUInt32BE(0),r=e.readUInt32BE(4),n="";for(let o=4;o<8;o++)n+=String.fromCharCode(e[o]);let i=!!(e[4]&32);if(!this._hasIHDR&&r!==_.TYPE_IHDR){this.error(new Error("Expected IHDR on beggining"));return}if(this._crc=new Fr,this._crc.write(Buffer.from(n)),this._chunks[r])return this._chunks[r](t);if(!i){this.error(new Error("Unsupported critical chunk type "+n));return}this.read(t+4,this._skipChunk.bind(this))};b.prototype._skipChunk=function(){this.read(8,this._parseChunkBegin.bind(this))};b.prototype._handleChunkEnd=function(){this.read(4,this._parseChunkEnd.bind(this))};b.prototype._parseChunkEnd=function(e){let t=e.readInt32BE(0),r=this._crc.crc32();if(this._options.checkCRC&&r!==t){this.error(new Error("Crc error - "+t+" - "+r));return}this._hasIEND||this.read(8,this._parseChunkBegin.bind(this))};b.prototype._handleIHDR=function(e){this.read(e,this._parseIHDR.bind(this))};b.prototype._parseIHDR=function(e){this._crc.write(e);let t=e.readUInt32BE(0),r=e.readUInt32BE(4),n=e[8],i=e[9],o=e[10],s=e[11],a=e[12];if(n!==8&&n!==4&&n!==2&&n!==1&&n!==16){this.error(new Error("Unsupported bit depth "+n));return}if(!(i in _.COLORTYPE_TO_BPP_MAP)){this.error(new Error("Unsupported color type"));return}if(o!==0){this.error(new Error("Unsupported compression method"));return}if(s!==0){this.error(new Error("Unsupported filter method"));return}if(a!==0&&a!==1){this.error(new Error("Unsupported interlace method"));return}this._colorType=i;let h=_.COLORTYPE_TO_BPP_MAP[this._colorType];this._hasIHDR=!0,this.metadata({width:t,height:r,depth:n,interlace:!!a,palette:!!(i&_.COLORTYPE_PALETTE),color:!!(i&_.COLORTYPE_COLOR),alpha:!!(i&_.COLORTYPE_ALPHA),bpp:h,colorType:i}),this._handleChunkEnd()};b.prototype._handlePLTE=function(e){this.read(e,this._parsePLTE.bind(this))};b.prototype._parsePLTE=function(e){this._crc.write(e);let t=Math.floor(e.length/3);for(let r=0;r<t;r++)this._palette.push([e[r*3],e[r*3+1],e[r*3+2],255]);this.palette(this._palette),this._handleChunkEnd()};b.prototype._handleTRNS=function(e){this.simpleTransparency(),this.read(e,this._parseTRNS.bind(this))};b.prototype._parseTRNS=function(e){if(this._crc.write(e),this._colorType===_.COLORTYPE_PALETTE_COLOR){if(this._palette.length===0){this.error(new Error("Transparency chunk must be after palette"));return}if(e.length>this._palette.length){this.error(new Error("More transparent colors than palette size"));return}for(let t=0;t<e.length;t++)this._palette[t][3]=e[t];this.palette(this._palette)}this._colorType===_.COLORTYPE_GRAYSCALE&&this.transColor([e.readUInt16BE(0)]),this._colorType===_.COLORTYPE_COLOR&&this.transColor([e.readUInt16BE(0),e.readUInt16BE(2),e.readUInt16BE(4)]),this._handleChunkEnd()};b.prototype._handleGAMA=function(e){this.read(e,this._parseGAMA.bind(this))};b.prototype._parseGAMA=function(e){this._crc.write(e),this.gamma(e.readUInt32BE(0)/_.GAMMA_DIVISION),this._handleChunkEnd()};b.prototype._handleIDAT=function(e){this._emittedHeadersFinished||(this._emittedHeadersFinished=!0,this.headersFinished()),this.read(-e,this._parseIDAT.bind(this,e))};b.prototype._parseIDAT=function(e,t){if(this._crc.write(t),this._colorType===_.COLORTYPE_PALETTE_COLOR&&this._palette.length===0)throw new Error("Expected palette not found");this.inflateData(t);let r=e-t.length;r>0?this._handleIDAT(r):this._handleChunkEnd()};b.prototype._handleIEND=function(e){this.read(e,this._parseIEND.bind(this))};b.prototype._parseIEND=function(e){this._crc.write(e),this._hasIEND=!0,this._handleChunkEnd(),this.finished&&this.finished()}});var ye=m(ct=>{"use strict";var ht=ce(),Yr=[function(){},function(e,t,r,n){if(n===t.length)throw new Error("Ran out of data");let i=t[n];e[r]=i,e[r+1]=i,e[r+2]=i,e[r+3]=255},function(e,t,r,n){if(n+1>=t.length)throw new Error("Ran out of data");let i=t[n];e[r]=i,e[r+1]=i,e[r+2]=i,e[r+3]=t[n+1]},function(e,t,r,n){if(n+2>=t.length)throw new Error("Ran out of data");e[r]=t[n],e[r+1]=t[n+1],e[r+2]=t[n+2],e[r+3]=255},function(e,t,r,n){if(n+3>=t.length)throw new Error("Ran out of data");e[r]=t[n],e[r+1]=t[n+1],e[r+2]=t[n+2],e[r+3]=t[n+3]}],$r=[function(){},function(e,t,r,n){let i=t[0];e[r]=i,e[r+1]=i,e[r+2]=i,e[r+3]=n},function(e,t,r){let n=t[0];e[r]=n,e[r+1]=n,e[r+2]=n,e[r+3]=t[1]},function(e,t,r,n){e[r]=t[0],e[r+1]=t[1],e[r+2]=t[2],e[r+3]=n},function(e,t,r){e[r]=t[0],e[r+1]=t[1],e[r+2]=t[2],e[r+3]=t[3]}];function Wr(e,t){let r=[],n=0;function i(){if(n===e.length)throw new Error("Ran out of data");let o=e[n];n++;let s,a,h,l,c,f,u,g;switch(t){default:throw new Error("unrecognised depth");case 16:u=e[n],n++,r.push((o<<8)+u);break;case 4:u=o&15,g=o>>4,r.push(g,u);break;case 2:c=o&3,f=o>>2&3,u=o>>4&3,g=o>>6&3,r.push(g,u,f,c);break;case 1:s=o&1,a=o>>1&1,h=o>>2&1,l=o>>3&1,c=o>>4&1,f=o>>5&1,u=o>>6&1,g=o>>7&1,r.push(g,u,f,c,l,h,a,s);break}}return{get:function(o){for(;r.length<o;)i();let s=r.slice(0,o);return r=r.slice(o),s},resetAfterLine:function(){r.length=0},end:function(){if(n!==e.length)throw new Error("extra data found")}}}function Gr(e,t,r,n,i,o){let s=e.width,a=e.height,h=e.index;for(let l=0;l<a;l++)for(let c=0;c<s;c++){let f=r(c,l,h);Yr[n](t,i,f,o),o+=n}return o}function zr(e,t,r,n,i,o){let s=e.width,a=e.height,h=e.index;for(let l=0;l<a;l++){for(let c=0;c<s;c++){let f=i.get(n),u=r(c,l,h);$r[n](t,f,u,o)}i.resetAfterLine()}}ct.dataToBitMap=function(e,t){let r=t.width,n=t.height,i=t.depth,o=t.bpp,s=t.interlace,a;i!==8&&(a=Wr(e,i));let h;i<=8?h=Buffer.alloc(r*n*4):h=new Uint16Array(r*n*4);let l=Math.pow(2,i)-1,c=0,f,u;if(s)f=ht.getImagePasses(r,n),u=ht.getInterlaceIterator(r,n);else{let g=0;u=function(){let p=g;return g+=4,p},f=[{width:r,height:n}]}for(let g=0;g<f.length;g++)i===8?c=Gr(f[g],h,u,o,e,c):zr(f[g],h,u,o,a,l);if(i===8){if(c!==e.length)throw new Error("extra data found")}else a.end();return h}});var me=m((zi,ft)=>{"use strict";function jr(e,t,r,n,i){let o=0;for(let s=0;s<n;s++)for(let a=0;a<r;a++){let h=i[e[o]];if(!h)throw new Error("index "+e[o]+" not in palette");for(let l=0;l<4;l++)t[o+l]=h[l];o+=4}}function Vr(e,t,r,n,i){let o=0;for(let s=0;s<n;s++)for(let a=0;a<r;a++){let h=!1;if(i.length===1?i[0]===e[o]&&(h=!0):i[0]===e[o]&&i[1]===e[o+1]&&i[2]===e[o+2]&&(h=!0),h)for(let l=0;l<4;l++)t[o+l]=0;o+=4}}function Zr(e,t,r,n,i){let o=255,s=Math.pow(2,i)-1,a=0;for(let h=0;h<n;h++)for(let l=0;l<r;l++){for(let c=0;c<4;c++)t[a+c]=Math.floor(e[a+c]*o/s+.5);a+=4}}ft.exports=function(e,t){let r=t.depth,n=t.width,i=t.height,o=t.colorType,s=t.transColor,a=t.palette,h=e;return o===3?jr(e,h,n,i,a):(s&&Vr(e,h,n,i,s),r!==8&&(r===16&&(h=Buffer.alloc(n*i*4)),Zr(e,h,n,i,r))),h}});var pt=m((ji,dt)=>{"use strict";var Kr=E("util"),_e=E("zlib"),ut=le(),Xr=ot(),Qr=we(),Jr=ye(),en=me(),B=dt.exports=function(e){ut.call(this),this._parser=new Qr(e,{read:this.read.bind(this),error:this._handleError.bind(this),metadata:this._handleMetaData.bind(this),gamma:this.emit.bind(this,"gamma"),palette:this._handlePalette.bind(this),transColor:this._handleTransColor.bind(this),finished:this._finished.bind(this),inflateData:this._inflateData.bind(this),simpleTransparency:this._simpleTransparency.bind(this),headersFinished:this._headersFinished.bind(this)}),this._options=e,this.writable=!0,this._parser.start()};Kr.inherits(B,ut);B.prototype._handleError=function(e){this.emit("error",e),this.writable=!1,this.destroy(),this._inflate&&this._inflate.destroy&&this._inflate.destroy(),this._filter&&(this._filter.destroy(),this._filter.on("error",function(){})),this.errord=!0};B.prototype._inflateData=function(e){if(!this._inflate)if(this._bitmapInfo.interlace)this._inflate=_e.createInflate(),this._inflate.on("error",this.emit.bind(this,"error")),this._filter.on("complete",this._complete.bind(this)),this._inflate.pipe(this._filter);else{let r=((this._bitmapInfo.width*this._bitmapInfo.bpp*this._bitmapInfo.depth+7>>3)+1)*this._bitmapInfo.height,n=Math.max(r,_e.Z_MIN_CHUNK);this._inflate=_e.createInflate({chunkSize:n});let i=r,o=this.emit.bind(this,"error");this._inflate.on("error",function(a){i&&o(a)}),this._filter.on("complete",this._complete.bind(this));let s=this._filter.write.bind(this._filter);this._inflate.on("data",function(a){i&&(a.length>i&&(a=a.slice(0,i)),i-=a.length,s(a))}),this._inflate.on("end",this._filter.end.bind(this._filter))}this._inflate.write(e)};B.prototype._handleMetaData=function(e){this._metaData=e,this._bitmapInfo=Object.create(e),this._filter=new Xr(this._bitmapInfo)};B.prototype._handleTransColor=function(e){this._bitmapInfo.transColor=e};B.prototype._handlePalette=function(e){this._bitmapInfo.palette=e};B.prototype._simpleTransparency=function(){this._metaData.alpha=!0};B.prototype._headersFinished=function(){this.emit("metadata",this._metaData)};B.prototype._finished=function(){this.errord||(this._inflate?this._inflate.end():this.emit("error","No Inflate block"))};B.prototype._complete=function(e){if(this.errord)return;let t;try{let r=Jr.dataToBitMap(e,this._bitmapInfo);t=en(r,this._bitmapInfo),r=null}catch(r){this._handleError(r);return}this.emit("parsed",t)}});var wt=m((Vi,gt)=>{"use strict";var x=H();gt.exports=function(e,t,r,n){let i=[x.COLORTYPE_COLOR_ALPHA,x.COLORTYPE_ALPHA].indexOf(n.colorType)!==-1;if(n.colorType===n.inputColorType){let p=(function(){let w=new ArrayBuffer(2);return new DataView(w).setInt16(0,256,!0),new Int16Array(w)[0]!==256})();if(n.bitDepth===8||n.bitDepth===16&&p)return e}let o=n.bitDepth!==16?e:new Uint16Array(e.buffer),s=255,a=x.COLORTYPE_TO_BPP_MAP[n.inputColorType];a===4&&!n.inputHasAlpha&&(a=3);let h=x.COLORTYPE_TO_BPP_MAP[n.colorType];n.bitDepth===16&&(s=65535,h*=2);let l=Buffer.alloc(t*r*h),c=0,f=0,u=n.bgColor||{};u.red===void 0&&(u.red=s),u.green===void 0&&(u.green=s),u.blue===void 0&&(u.blue=s);function g(){let p,w,d,y=s;switch(n.inputColorType){case x.COLORTYPE_COLOR_ALPHA:y=o[c+3],p=o[c],w=o[c+1],d=o[c+2];break;case x.COLORTYPE_COLOR:p=o[c],w=o[c+1],d=o[c+2];break;case x.COLORTYPE_ALPHA:y=o[c+1],p=o[c],w=p,d=p;break;case x.COLORTYPE_GRAYSCALE:p=o[c],w=p,d=p;break;default:throw new Error("input color type:"+n.inputColorType+" is not supported at present")}return n.inputHasAlpha&&(i||(y/=s,p=Math.min(Math.max(Math.round((1-y)*u.red+y*p),0),s),w=Math.min(Math.max(Math.round((1-y)*u.green+y*w),0),s),d=Math.min(Math.max(Math.round((1-y)*u.blue+y*d),0),s))),{red:p,green:w,blue:d,alpha:y}}for(let p=0;p<r;p++)for(let w=0;w<t;w++){let d=g(o,c);switch(n.colorType){case x.COLORTYPE_COLOR_ALPHA:case x.COLORTYPE_COLOR:n.bitDepth===8?(l[f]=d.red,l[f+1]=d.green,l[f+2]=d.blue,i&&(l[f+3]=d.alpha)):(l.writeUInt16BE(d.red,f),l.writeUInt16BE(d.green,f+2),l.writeUInt16BE(d.blue,f+4),i&&l.writeUInt16BE(d.alpha,f+6));break;case x.COLORTYPE_ALPHA:case x.COLORTYPE_GRAYSCALE:{let y=(d.red+d.green+d.blue)/3;n.bitDepth===8?(l[f]=y,i&&(l[f+1]=d.alpha)):(l.writeUInt16BE(y,f),i&&l.writeUInt16BE(d.alpha,f+2));break}default:throw new Error("unrecognised color Type "+n.colorType)}c+=a,f+=h}return l}});var _t=m((Zi,mt)=>{"use strict";var yt=fe();function tn(e,t,r,n,i){for(let o=0;o<r;o++)n[i+o]=e[t+o]}function rn(e,t,r){let n=0,i=t+r;for(let o=t;o<i;o++)n+=Math.abs(e[o]);return n}function nn(e,t,r,n,i,o){for(let s=0;s<r;s++){let a=s>=o?e[t+s-o]:0,h=e[t+s]-a;n[i+s]=h}}function on(e,t,r,n){let i=0;for(let o=0;o<r;o++){let s=o>=n?e[t+o-n]:0,a=e[t+o]-s;i+=Math.abs(a)}return i}function sn(e,t,r,n,i){for(let o=0;o<r;o++){let s=t>0?e[t+o-r]:0,a=e[t+o]-s;n[i+o]=a}}function an(e,t,r){let n=0,i=t+r;for(let o=t;o<i;o++){let s=t>0?e[o-r]:0,a=e[o]-s;n+=Math.abs(a)}return n}function ln(e,t,r,n,i,o){for(let s=0;s<r;s++){let a=s>=o?e[t+s-o]:0,h=t>0?e[t+s-r]:0,l=e[t+s]-(a+h>>1);n[i+s]=l}}function hn(e,t,r,n){let i=0;for(let o=0;o<r;o++){let s=o>=n?e[t+o-n]:0,a=t>0?e[t+o-r]:0,h=e[t+o]-(s+a>>1);i+=Math.abs(h)}return i}function cn(e,t,r,n,i,o){for(let s=0;s<r;s++){let a=s>=o?e[t+s-o]:0,h=t>0?e[t+s-r]:0,l=t>0&&s>=o?e[t+s-(r+o)]:0,c=e[t+s]-yt(a,h,l);n[i+s]=c}}function fn(e,t,r,n){let i=0;for(let o=0;o<r;o++){let s=o>=n?e[t+o-n]:0,a=t>0?e[t+o-r]:0,h=t>0&&o>=n?e[t+o-(r+n)]:0,l=e[t+o]-yt(s,a,h);i+=Math.abs(l)}return i}var un={0:tn,1:nn,2:sn,3:ln,4:cn},dn={0:rn,1:on,2:an,3:hn,4:fn};mt.exports=function(e,t,r,n,i){let o;if(!("filterType"in n)||n.filterType===-1)o=[0,1,2,3,4];else if(typeof n.filterType=="number")o=[n.filterType];else throw new Error("unrecognised filter types");n.bitDepth===16&&(i*=2);let s=t*i,a=0,h=0,l=Buffer.alloc((s+1)*r),c=o[0];for(let f=0;f<r;f++){if(o.length>1){let u=1/0;for(let g=0;g<o.length;g++){let p=dn[o[g]](e,h,s,i);p<u&&(c=o[g],u=p)}}l[a]=c,a++,un[c](e,h,s,l,a,i),a+=s,h+=s}return l}});var be=m((Ki,bt)=>{"use strict";var A=H(),pn=ge(),gn=wt(),wn=_t(),yn=E("zlib"),R=bt.exports=function(e){if(this._options=e,e.deflateChunkSize=e.deflateChunkSize||32*1024,e.deflateLevel=e.deflateLevel!=null?e.deflateLevel:9,e.deflateStrategy=e.deflateStrategy!=null?e.deflateStrategy:3,e.inputHasAlpha=e.inputHasAlpha!=null?e.inputHasAlpha:!0,e.deflateFactory=e.deflateFactory||yn.createDeflate,e.bitDepth=e.bitDepth||8,e.colorType=typeof e.colorType=="number"?e.colorType:A.COLORTYPE_COLOR_ALPHA,e.inputColorType=typeof e.inputColorType=="number"?e.inputColorType:A.COLORTYPE_COLOR_ALPHA,[A.COLORTYPE_GRAYSCALE,A.COLORTYPE_COLOR,A.COLORTYPE_COLOR_ALPHA,A.COLORTYPE_ALPHA].indexOf(e.colorType)===-1)throw new Error("option color type:"+e.colorType+" is not supported at present");if([A.COLORTYPE_GRAYSCALE,A.COLORTYPE_COLOR,A.COLORTYPE_COLOR_ALPHA,A.COLORTYPE_ALPHA].indexOf(e.inputColorType)===-1)throw new Error("option input color type:"+e.inputColorType+" is not supported at present");if(e.bitDepth!==8&&e.bitDepth!==16)throw new Error("option bit depth:"+e.bitDepth+" is not supported at present")};R.prototype.getDeflateOptions=function(){return{chunkSize:this._options.deflateChunkSize,level:this._options.deflateLevel,strategy:this._options.deflateStrategy}};R.prototype.createDeflate=function(){return this._options.deflateFactory(this.getDeflateOptions())};R.prototype.filterData=function(e,t,r){let n=gn(e,t,r,this._options),i=A.COLORTYPE_TO_BPP_MAP[this._options.colorType];return wn(n,t,r,this._options,i)};R.prototype._packChunk=function(e,t){let r=t?t.length:0,n=Buffer.alloc(r+12);return n.writeUInt32BE(r,0),n.writeUInt32BE(e,4),t&&t.copy(n,8),n.writeInt32BE(pn.crc32(n.slice(4,n.length-4)),n.length-4),n};R.prototype.packGAMA=function(e){let t=Buffer.alloc(4);return t.writeUInt32BE(Math.floor(e*A.GAMMA_DIVISION),0),this._packChunk(A.TYPE_gAMA,t)};R.prototype.packIHDR=function(e,t){let r=Buffer.alloc(13);return r.writeUInt32BE(e,0),r.writeUInt32BE(t,4),r[8]=this._options.bitDepth,r[9]=this._options.colorType,r[10]=0,r[11]=0,r[12]=0,this._packChunk(A.TYPE_IHDR,r)};R.prototype.packIDAT=function(e){return this._packChunk(A.TYPE_IDAT,e)};R.prototype.packIEND=function(){return this._packChunk(A.TYPE_IEND,null)}});var kt=m((Xi,It)=>{"use strict";var mn=E("util"),Et=E("stream"),_n=H(),bn=be(),At=It.exports=function(e){Et.call(this);let t=e||{};this._packer=new bn(t),this._deflate=this._packer.createDeflate(),this.readable=!0};mn.inherits(At,Et);At.prototype.pack=function(e,t,r,n){this.emit("data",Buffer.from(_n.PNG_SIGNATURE)),this.emit("data",this._packer.packIHDR(t,r)),n&&this.emit("data",this._packer.packGAMA(n));let i=this._packer.filterData(e,t,r);this._deflate.on("error",this.emit.bind(this,"error")),this._deflate.on("data",function(o){this.emit("data",this._packer.packIDAT(o))}.bind(this)),this._deflate.on("end",function(){this.emit("data",this._packer.packIEND()),this.emit("end")}.bind(this)),this._deflate.end(i)}});var St=m((G,Mt)=>{"use strict";var Ct=E("assert").ok,q=E("zlib"),En=E("util"),xt=E("buffer").kMaxLength;function U(e){if(!(this instanceof U))return new U(e);e&&e.chunkSize<q.Z_MIN_CHUNK&&(e.chunkSize=q.Z_MIN_CHUNK),q.Inflate.call(this,e),this._offset=this._offset===void 0?this._outOffset:this._offset,this._buffer=this._buffer||this._outBuffer,e&&e.maxLength!=null&&(this._maxLength=e.maxLength)}function An(e){return new U(e)}function Lt(e,t){t&&process.nextTick(t),e._handle&&(e._handle.close(),e._handle=null)}U.prototype._processChunk=function(e,t,r){if(typeof r=="function")return q.Inflate._processChunk.call(this,e,t,r);let n=this,i=e&&e.length,o=this._chunkSize-this._offset,s=this._maxLength,a=0,h=[],l=0,c;this.on("error",function(p){c=p});function f(p,w){if(n._hadError)return;let d=o-w;if(Ct(d>=0,"have should not go down"),d>0){let y=n._buffer.slice(n._offset,n._offset+d);if(n._offset+=d,y.length>s&&(y=y.slice(0,s)),h.push(y),l+=y.length,s-=y.length,s===0)return!1}return(w===0||n._offset>=n._chunkSize)&&(o=n._chunkSize,n._offset=0,n._buffer=Buffer.allocUnsafe(n._chunkSize)),w===0?(a+=i-p,i=p,!0):!1}Ct(this._handle,"zlib binding closed");let u;do u=this._handle.writeSync(t,e,a,i,this._buffer,this._offset,o),u=u||this._writeState;while(!this._hadError&&f(u[0],u[1]));if(this._hadError)throw c;if(l>=xt)throw Lt(this),new RangeError("Cannot create final Buffer. It would be larger than 0x"+xt.toString(16)+" bytes");let g=Buffer.concat(h,l);return Lt(this),g};En.inherits(U,q.Inflate);function In(e,t){if(typeof t=="string"&&(t=Buffer.from(t)),!(t instanceof Buffer))throw new TypeError("Not a string or buffer");let r=e._finishFlushFlag;return r==null&&(r=q.Z_FINISH),e._processChunk(t,r)}function Tt(e,t){return In(new U(t),e)}Mt.exports=G=Tt;G.Inflate=U;G.createInflate=An;G.inflateSync=Tt});var Ee=m((Qi,Ot)=>{"use strict";var Bt=Ot.exports=function(e){this._buffer=e,this._reads=[]};Bt.prototype.read=function(e,t){this._reads.push({length:Math.abs(e),allowLess:e<0,func:t})};Bt.prototype.process=function(){for(;this._reads.length>0&&this._buffer.length;){let e=this._reads[0];if(this._buffer.length&&(this._buffer.length>=e.length||e.allowLess)){this._reads.shift();let t=this._buffer;this._buffer=t.slice(e.length),e.func.call(this,t.slice(0,e.length))}else break}if(this._reads.length>0)return new Error("There are some read requests waitng on finished stream");if(this._buffer.length>0)return new Error("unrecognised content at end of stream")}});var Rt=m(vt=>{"use strict";var kn=Ee(),Cn=ue();vt.process=function(e,t){let r=[],n=new kn(e);return new Cn(t,{read:n.read.bind(n),write:function(o){r.push(o)},complete:function(){}}).start(),n.process(),Buffer.concat(r)}});var Ht=m((eo,Nt)=>{"use strict";var Pt=!0,Ut=E("zlib"),xn=St();Ut.deflateSync||(Pt=!1);var Ln=Ee(),Tn=Rt(),Mn=we(),Sn=ye(),Bn=me();Nt.exports=function(e,t){if(!Pt)throw new Error("To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0");let r;function n(C){r=C}let i;function o(C){i=C}function s(C){i.transColor=C}function a(C){i.palette=C}function h(){i.alpha=!0}let l;function c(C){l=C}let f=[];function u(C){f.push(C)}let g=new Ln(e);if(new Mn(t,{read:g.read.bind(g),error:n,metadata:o,gamma:c,palette:a,transColor:s,inflateData:u,simpleTransparency:h}).start(),g.process(),r)throw r;let w=Buffer.concat(f);f.length=0;let d;if(i.interlace)d=Ut.inflateSync(w);else{let ve=((i.width*i.bpp*i.depth+7>>3)+1)*i.height;d=xn(w,{chunkSize:ve,maxLength:ve})}if(w=null,!d||!d.length)throw new Error("bad png - invalid inflate data response");let y=Tn.process(d,i);w=null;let k=Sn.dataToBitMap(y,i);y=null;let Q=Bn(k,i);return i.data=Q,i.gamma=l||0,i}});var Yt=m((to,Ft)=>{"use strict";var qt=!0,Dt=E("zlib");Dt.deflateSync||(qt=!1);var On=H(),vn=be();Ft.exports=function(e,t){if(!qt)throw new Error("To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0");let r=t||{},n=new vn(r),i=[];i.push(Buffer.from(On.PNG_SIGNATURE)),i.push(n.packIHDR(e.width,e.height)),e.gamma&&i.push(n.packGAMA(e.gamma));let o=n.filterData(e.data,e.width,e.height),s=Dt.deflateSync(o,n.getDeflateOptions());if(o=null,!s||!s.length)throw new Error("bad png - invalid compressed data response");return i.push(n.packIDAT(s)),i.push(n.packIEND()),Buffer.concat(i)}});var $t=m(Ae=>{"use strict";var Rn=Ht(),Pn=Yt();Ae.read=function(e,t){return Rn(e,t||{})};Ae.write=function(e,t){return Pn(e,t)}});var Ie=m(Gt=>{"use strict";var Un=E("util"),Wt=E("stream"),Nn=pt(),Hn=kt(),qn=$t(),I=Gt.PNG=function(e){Wt.call(this),e=e||{},this.width=e.width|0,this.height=e.height|0,this.data=this.width>0&&this.height>0?Buffer.alloc(4*this.width*this.height):null,e.fill&&this.data&&this.data.fill(0),this.gamma=0,this.readable=this.writable=!0,this._parser=new Nn(e),this._parser.on("error",this.emit.bind(this,"error")),this._parser.on("close",this._handleClose.bind(this)),this._parser.on("metadata",this._metadata.bind(this)),this._parser.on("gamma",this._gamma.bind(this)),this._parser.on("parsed",function(t){this.data=t,this.emit("parsed",t)}.bind(this)),this._packer=new Hn(e),this._packer.on("data",this.emit.bind(this,"data")),this._packer.on("end",this.emit.bind(this,"end")),this._parser.on("close",this._handleClose.bind(this)),this._packer.on("error",this.emit.bind(this,"error"))};Un.inherits(I,Wt);I.sync=qn;I.prototype.pack=function(){return!this.data||!this.data.length?(this.emit("error","No data provided"),this):(process.nextTick(function(){this._packer.pack(this.data,this.width,this.height,this.gamma)}.bind(this)),this)};I.prototype.parse=function(e,t){if(t){let r,n;r=function(i){this.removeListener("error",n),this.data=i,t(null,this)}.bind(this),n=function(i){this.removeListener("parsed",r),t(i,null)}.bind(this),this.once("parsed",r),this.once("error",n)}return this.end(e),this};I.prototype.write=function(e){return this._parser.write(e),!0};I.prototype.end=function(e){this._parser.end(e)};I.prototype._metadata=function(e){this.width=e.width,this.height=e.height,this.emit("metadata",e)};I.prototype._gamma=function(e){this.gamma=e};I.prototype._handleClose=function(){!this._parser.writable&&!this._packer.readable&&this.emit("close")};I.bitblt=function(e,t,r,n,i,o,s,a){if(r|=0,n|=0,i|=0,o|=0,s|=0,a|=0,r>e.width||n>e.height||r+i>e.width||n+o>e.height)throw new Error("bitblt reading outside image");if(s>t.width||a>t.height||s+i>t.width||a+o>t.height)throw new Error("bitblt writing outside image");for(let h=0;h<o;h++)e.data.copy(t.data,(a+h)*t.width+s<<2,(n+h)*e.width+r<<2,(n+h)*e.width+r+i<<2)};I.prototype.bitblt=function(e,t,r,n,i,o,s){return I.bitblt(this,e,t,r,n,i,o,s),this};I.adjustGamma=function(e){if(e.gamma){for(let t=0;t<e.height;t++)for(let r=0;r<e.width;r++){let n=e.width*t+r<<2;for(let i=0;i<3;i++){let o=e.data[n+i]/255;o=Math.pow(o,1/2.2/e.gamma),e.data[n+i]=Math.round(o*255)}}e.gamma=0}};I.prototype.adjustGamma=function(){I.adjustGamma(this)}});import{createDecipheriv as lr,createHash as Be,randomBytes as wi}from"node:crypto";import{open as Te,mkdir as Oe,unlink as dr,readFile as hr,lstat as Me,realpath as cr}from"node:fs/promises";import{dirname as K,resolve as X,relative as pr,sep as gr,join as yi,isAbsolute as mi}from"node:path";async function S(e,t){if(!Number.isSafeInteger(t)||t<0)throw new Error("Invalid response limit");let r=e.headers.get("Content-Length");if(r!==null&&(!/^[0-9]+$/.test(r)||!Number.isSafeInteger(Number(r))||Number(r)>t))throw e.body&&await e.body.cancel().catch(()=>{}),new Error("Carrier response exceeds byte limit");if(!e.body)return new Uint8Array(0);let n=e.body.getReader(),i=[],o=0,s=!1;try{for(;;){let{done:l,value:c}=await n.read();if(l){s=!0;break}if(o+=c.byteLength,o>t)throw new Error("Carrier response exceeds byte limit");i.push(c)}}finally{s||await n.cancel().catch(()=>{}),n.releaseLock()}let a=new Uint8Array(o),h=0;for(let l of i)a.set(l,h),h+=l.byteLength;return a}var P=4096,L=128,Ue=1024*1024*1024,ee=16*1024*1024,Ar=new TextDecoder("utf-8",{fatal:!0}),Y=(e,t)=>e.length===t.length&&e.every((r,n)=>r===t[n]),F=async e=>new Uint8Array(await crypto.subtle.digest("SHA-256",e)),O=(e,t)=>{let r=Number(e.getBigUint64(t,!0));if(!Number.isSafeInteger(r))throw new Error("Unsafe offset");return r},Ne=(e,t)=>Y(e.slice(0,8),new TextEncoder().encode(t)),J=e=>JSON.parse(Ar.decode(e));function Ir(e){if(e.length!==P||!Ne(e,"AMW1DOC\0"))throw new Error("Invalid AMW header");let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(t.getUint16(8,!0)!==1||t.getUint16(10,!0)!==P||e.slice(12,16).some(Boolean)||e.slice(120).some(Boolean))throw new Error("Unsupported AMW header");let r={total:O(t,16),manifestOffset:O(t,24),manifestLength:O(t,32),bootstrapOffset:O(t,40),bootstrapLength:O(t,48),manifestHash:e.slice(56,88),bootstrapHash:e.slice(88,120)};if(r.total>Ue||r.total<P||r.manifestOffset!==P||r.manifestLength>1024*1024)throw new Error("Invalid AMW bounds");return r}function kr(e,t){if(e.length!==L||!Ne(e,"AMW1TAIL"))throw new Error("No AMW footer");let r=new DataView(e.buffer,e.byteOffset,e.byteLength),n=r.getUint16(8,!0);if(![1,2].includes(n)||r.getUint16(10,!0)!==L||e.slice(12,16).some(Boolean)||n===1&&e.slice(104).some(Boolean))throw new Error("Unsupported footer");let i={version:n,carrierLength:O(r,16),payloadOffset:O(r,24),payloadLength:O(r,32),payloadHash:e.slice(40,72),bootstrapPrefixHash:n===2?e.slice(104,128):null};if(i.carrierLength!==i.payloadOffset||i.payloadLength>Ue||i.payloadOffset+i.payloadLength+L!==t)throw new Error("Invalid carrier layout");return i}async function He(e,{onBootstrap:t=()=>{},fetcher:r=fetch}={}){let n=new URL(e,globalThis.location?.href);if(n.protocol!=="https:"&&!(n.protocol==="http:"&&["localhost","127.0.0.1"].includes(n.hostname)))throw new Error("HTTPS required");let i,o,s;return te(async(h,l,c=!1)=>{if(s)return c?s.slice(-L):s.slice(h,l+1);let f=await r(n,{headers:{Range:c?`bytes=-${L}`:`bytes=${h}-${l}`,...o?{"If-Range":o}:{}},cache:"no-store",credentials:"omit",redirect:"error"});if(f.status===404||f.status===410)throw new Error("No AMW footer");if(f.status===200){let k=f.headers.get("Content-Length");if(k!==null&&(!/^[0-9]+$/.test(k)||!Number.isSafeInteger(Number(k))))throw new Error("Invalid full response length");if(s=await S(f,ee),s.length<L&&c)throw new Error("No AMW footer");if(k!==null&&s.length!==Number(k)||i!==void 0&&i!==s.length)throw new Error("Full response length changed");return i=s.length,c?s.slice(-L):s.slice(h,l+1)}if(f.status!==206)throw new Error("Host must support HTTP byte ranges");let u=/^bytes (\d+)-(\d+)\/(\d+)$/.exec(f.headers.get("Content-Range")||"");if(!u)throw new Error("Invalid Content-Range");let[g,p,w]=u.slice(1).map(Number);if(Number.isSafeInteger(w)&&w<L)throw new Error("No AMW footer");if(!Number.isSafeInteger(w)||i!==void 0&&i!==w||(c?p!==w-1||p-g+1!==L:g!==h||p!==l))throw new Error("Range changed or mismatched");let d=f.headers.get("ETag");if(o&&d&&d!==o)throw new Error("ETag changed during load");!o&&d&&!d.startsWith("W/")&&(o=d),i=w;let y=await S(f,p-g+1);if(y.length!==p-g+1)throw new Error("Short range response");return y},()=>i,!n.pathname.endsWith(".amw"),t)}async function qe(e,{onBootstrap:t=()=>{}}={}){let r=e instanceof Uint8Array?e:new Uint8Array(e);if(r.length<L||r.length>ee)throw new Error("Invalid local index size");return te(async(i,o,s=!1)=>s?r.slice(-L):r.slice(i,o+1),()=>r.length,!0,t)}async function De(e){let t=e instanceof Uint8Array?e:new Uint8Array(e);if(t.length<P||t.length>ee)throw new Error("Invalid private index size");return te(async(n,i)=>t.slice(n,i+1),()=>t.length,!1,()=>{})}async function te(e,t,r,n){let i=r?kr(await e(0,0,!0),t()):null,o=i?.payloadOffset||0,s=await e(o,o+P-1),a=Ir(s);if(i&&a.total!==i.payloadLength)throw new Error("Payload length mismatch");if(!i&&t()!==a.total)throw new Error("AMW length mismatch");let h=await e(o+a.manifestOffset,o+a.manifestOffset+a.manifestLength-1);if(!Y(await F(h),a.manifestHash))throw new Error("Manifest integrity failure");let l=J(h);if(l.format!=="amw.sections.v1"||!Array.isArray(l.sections)||l.sections.length!==2)throw new Error("Invalid manifest");let c=P+a.manifestLength;for(let d of l.sections){if(d.offset!==c||!Number.isSafeInteger(d.length)||d.length<1||!/^[0-9a-f]{64}$/.test(d.sha256))throw new Error("Invalid section layout");c+=d.length}if(c!==a.total||l.sections[0].id!=="bootstrap"||l.sections[1].id!=="document"||l.sections.some(d=>d.type!=="amw.document.v1")||l.sections[0].offset!==a.bootstrapOffset||l.sections[0].length!==a.bootstrapLength)throw new Error("Invalid section layout");let f=new Uint8Array(a.total);f.set(s,0),f.set(h,a.manifestOffset);let u=async d=>{let y=await e(o+d.offset,o+d.offset+d.length-1);if([...await F(y)].map(Q=>Q.toString(16).padStart(2,"0")).join("")!==d.sha256)throw new Error("Section integrity failure");return f.set(y,d.offset),y},g=await u(l.sections[0]);if(!Y(await F(g),a.bootstrapHash))throw new Error("Bootstrap integrity failure");let p=J(g);if(i?.version===2){let d=await F(f.subarray(0,a.bootstrapOffset+a.bootstrapLength));if(!Y(d.subarray(0,24),i.bootstrapPrefixHash))throw new Error("Bootstrap prefix integrity failure");n(p)}let w=J(await u(l.sections[1]));if(i&&!Y(await F(f),i.payloadHash))throw new Error("Payload integrity failure");return(!i||i.version===1)&&n(p),w}var Fe=/^[0-9a-f]{64}$/,Cr=/^[0-9a-f]{24}$/,xr=16*1024*1024+16,Lr=e=>[...e].map(t=>t.toString(16).padStart(2,"0")).join("");function z(e){if(!e||typeof e!="object"||Array.isArray(e)||Object.keys(e).some(t=>!["algorithm","url","offset","length","sha256","nonce","key"].includes(t))||e.algorithm!=="AES-256-GCM"||typeof e.url!="string"||!/^\/(?!\/)[A-Za-z0-9._/-]+$/.test(e.url)||e.url==="/favicon.ico"||e.url.startsWith("/amoosed.com/")||e.url.slice(1).split("/").some(t=>!t||t==="."||t==="..")||!Number.isSafeInteger(e.offset)||e.offset<0||!Number.isSafeInteger(e.length)||e.length<17||e.length>xr||!Fe.test(e.sha256)||!Cr.test(e.nonce)||!Fe.test(e.key))throw new Error("Invalid private index locator");return e}async function Ye(e,t=fetch,r=location.origin){if(!e?.privateIndex)return e;if(e.webApp)throw new Error("Ambiguous index file");let n=z(e.privateIndex),i=new URL(n.url,r);if(i.origin!==r)throw new Error("Private index changed origin");let o=await t(i.href,{headers:{Range:`bytes=${n.offset}-${n.offset+n.length-1}`},cache:"no-store",credentials:"omit",redirect:"error"});if(!o.ok||new URL(o.url,r).origin!==r)throw new Error("Private index carrier unavailable");let s;if(o.status===206){let u=/^bytes (\d+)-(\d+)\/(\d+)$/.exec(o.headers.get("Content-Range")||"");if(!u||Number(u[1])!==n.offset||Number(u[2])!==n.offset+n.length-1||!Number.isSafeInteger(Number(u[3])))throw new Error("Private index range mismatch");s=await S(o,n.length)}else if(o.status===200)s=(await S(o,16777216)).slice(n.offset,n.offset+n.length);else throw new Error("Private index carrier needs byte ranges");if(s.length!==n.length||Lr(new Uint8Array(await crypto.subtle.digest("SHA-256",s)))!==n.sha256)throw new Error("Private index integrity failure");let a=await crypto.subtle.importKey("raw",Uint8Array.from(n.key.match(/../g),u=>parseInt(u,16)),"AES-GCM",!1,["decrypt"]),h=Uint8Array.from(n.nonce.match(/../g),u=>parseInt(u,16)),l=new TextEncoder().encode(`AMW1-PRIVATE-INDEX\0${n.url}\0${n.offset}`),c;try{c=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:h,additionalData:l},a,s))}catch{throw new Error("Private index key or authentication failed")}let f=await De(c);if(f.privateIndex)throw new Error("Nested private index is not supported");return f}var We="AMQ1",j=93,$e=new TextEncoder,ie=new TextDecoder("utf-8",{fatal:!0});function re(e){return Uint8Array.from(e.match(/../g),t=>Number.parseInt(t,16))}function ne(e){return[...e].map(t=>t.toString(16).padStart(2,"0")).join("")}function Ge(e){return btoa(String.fromCharCode(...e)).replaceAll("+","-").replaceAll("/","_").replace(/=+$/,"")}function Tr(e){let t=z(e),r=$e.encode(t.url);if(r.length>255)throw new Error("Private index carrier path is too long for a QR token");let n=new Uint8Array(j+r.length);n.set($e.encode(We)),n[4]=r.length;let i=new DataView(n.buffer);return i.setBigUint64(5,BigInt(t.offset)),i.setUint32(13,t.length),n.set(re(t.sha256),17),n.set(re(t.nonce),49),n.set(re(t.key),61),n.set(r,j),Ge(n)}function oe(e){if(typeof e!="string"||!/^[A-Za-z0-9_-]{124,464}$/.test(e))throw new Error("Invalid Amoosed QR key");let t;try{t=Uint8Array.from(atob(e.replaceAll("-","+").replaceAll("_","/")),o=>o.charCodeAt(0))}catch{throw new Error("Invalid Amoosed QR key")}if(t.length!==j+t[4]||ie.decode(t.subarray(0,4))!==We||Ge(t)!==e)throw new Error("Invalid Amoosed QR key");let r=new DataView(t.buffer),n=Number(r.getBigUint64(5)),i={algorithm:"AES-256-GCM",url:ie.decode(t.subarray(j)),offset:n,length:r.getUint32(13),sha256:ne(t.subarray(17,49)),nonce:ne(t.subarray(49,61)),key:ne(t.subarray(61,93))};if(z(i),Tr(i)!==e)throw new Error("Invalid Amoosed QR key");return i}function ze(e){let t=typeof e=="string"?e:ie.decode(e),r=/^AMWKEY1:([A-Za-z0-9_-]{124,464})\r?\n?$/.exec(t);if(!r)throw new Error("Invalid Amoosed key file");return oe(r[1]),r[1]}var Mr="AMM1",se=new TextDecoder("utf-8",{fatal:!0}),Sr=/^[a-z0-9][a-z0-9._-]{0,63}$/i;function Br(e){return btoa(String.fromCharCode(...e)).replaceAll("+","-").replaceAll("/","_").replace(/=+$/,"")}function ae(e){if(typeof e!="string"||!/^[A-Za-z0-9_-]{51,135}$/.test(e))throw new Error("Invalid Amoosed member key");let t;try{t=Uint8Array.from(atob(e.replaceAll("-","+").replaceAll("_","/")),i=>i.charCodeAt(0))}catch{throw new Error("Invalid Amoosed member key")}if(t.length<38||t.length!==37+t[4]||se.decode(t.subarray(0,4))!==Mr||Br(t)!==e)throw new Error("Invalid Amoosed member key");let r=se.decode(t.subarray(37)),n=t.slice(5,37);if(!Sr.test(r))throw new Error("Invalid Amoosed member key");return{keyId:r,key:n}}function je(e){let t=typeof e=="string"?e:se.decode(e),r=/^AMWMEMBER1:([A-Za-z0-9_-]{51,135})\r?\n?$/.exec(t);if(!r)throw new Error("Invalid Amoosed member key file");return ae(r[1]),r[1]}var $=/^[0-9a-f]{64}$/,Or=/^\/amoosed\.com\/app\/[A-Za-z0-9._/-]+$/,Ve=/^\/(?!\/)[A-Za-z0-9._/-]+$/,vr=/^[a-z0-9.+-]+\/[a-z0-9.+-]+(?:; charset=utf-8)?$/,Rr=/^[A-Za-z0-9._-]{1,64}$/;function Ke(e,t,r){return new TextEncoder().encode(`AMW1-SEALED\0${e.path}\0${e.mime}\0${t}\0${r}`)}function Ze(e){return typeof e=="string"&&Or.test(e)&&!e.slice(1).split("/").some(t=>t==="."||t===".."||t==="")&&!e.endsWith("/")}function W(e,t){return!!e.encryption&&t.access!=="public"}function Xe(e){if(!e||typeof e!="object"||Array.isArray(e)||Object.keys(e).some(s=>!["launch","entry","resources","encryption","encoding","identity","audioCarriers"].includes(s))||e.launch!=="/amoosed.com/boot.html"||!Ze(e.entry)||!Array.isArray(e.resources)||e.resources.length<1||e.resources.length>4096)throw new Error("Invalid web app manifest");let t=e.encryption!==void 0;if(e.encoding!==void 0&&(!e.encoding||typeof e.encoding!="object"||Array.isArray(e.encoding)||Object.keys(e.encoding).some(s=>!["algorithm","key"].includes(s))||e.encoding.algorithm!=="AES-256-CTR"||typeof e.encoding.key!="string"||!$.test(e.encoding.key)))throw new Error("Invalid web app encoding");if(e.identity!==void 0&&(!e.identity||typeof e.identity!="object"||Array.isArray(e.identity)||Object.keys(e.identity).some(s=>!["title","icon"].includes(s))||typeof e.identity.title!="string"||!e.identity.title||e.identity.title.length>200||e.identity.icon!=="/amoosed.com/app/favicon.ico"))throw new Error("Invalid app identity");if(t&&(!e.encryption||typeof e.encryption!="object"||Array.isArray(e.encryption)||Object.keys(e.encryption).some(s=>!["algorithm","keyId"].includes(s))||e.encryption.algorithm!=="AES-256-GCM"||typeof e.encryption.keyId!="string"||!Rr.test(e.encryption.keyId)))throw new Error("Invalid web app encryption");if(e.audioCarriers!==void 0){if(!e.audioCarriers||typeof e.audioCarriers!="object"||Array.isArray(e.audioCarriers)||Object.keys(e.audioCarriers).length>64)throw new Error("Invalid audio carrier map");for(let[s,a]of Object.entries(e.audioCarriers))if(!Ve.test(s)||!s.endsWith(".wav")||!a||a.format!=="amw.audio-carrier.v1"||!Number.isInteger(a.length)||a.length<1||a.length>4096||!$.test(a.sha256)||!Array.isArray(a.packets)||a.packets.length<1||a.packets.length>32||!Array.isArray(a.locations)||a.locations.length!==a.packets.length*3||a.packets.some((h,l)=>h.index!==l||!Number.isInteger(h.length)||h.length<1||h.length>128||!$.test(h.sha256))||a.packets.reduce((h,l)=>h+l.length,0)!==a.length||a.locations.some(h=>!Number.isInteger(h.packet)||h.packet<0||h.packet>=a.packets.length||!Number.isFinite(h.startSeconds)||h.startSeconds<0||!Number.isFinite(h.durationSeconds)||h.durationSeconds<=0))throw new Error("Invalid audio carrier map")}let r="",n=0,i=new Set;for(let s of e.resources){if(!s||typeof s!="object"||Array.isArray(s)||Object.keys(s).some(l=>!["path","mime","length","sha256","parts","access","delivery"].includes(l))||!Ze(s.path)||s.path<=r||s.access!==void 0&&(!t||!["public","members"].includes(s.access))||s.delivery!==void 0&&s.delivery!=="download"||typeof s.mime!="string"||!vr.test(s.mime)||!Number.isSafeInteger(s.length)||s.length<1||s.length>1024*1024*1024||typeof s.sha256!="string"||!$.test(s.sha256)||!Array.isArray(s.parts)||s.parts.length<1||s.parts.length>16384)throw new Error("Invalid web app resource");r=s.path;let a=W(e,s);a&&n++;let h=0;for(let l of s.parts){if(!l||typeof l!="object"||Array.isArray(l)||Object.keys(l).some(c=>!["url","offset","length","sha256","codec",...a?["nonce","plainLength"]:[]].includes(c))||typeof l.url!="string"||typeof l.sha256!="string"||!$.test(l.sha256)||!Ve.test(l.url)||l.url.slice(1).split("/").some(c=>!c||c==="."||c==="..")||l.url==="/favicon.ico"||l.url.startsWith("/amoosed.com/")||l.codec!==void 0&&!(l.codec==="png-lsb1"&&l.url.endsWith(".png")||l.codec==="wav-4fsk1"&&l.url.endsWith(".wav")&&e.audioCarriers?.[l.url]||["frame-luma1","frame-luma2"].includes(l.codec)&&l.url.endsWith(".png")&&l.offset===0&&l.length<=21)||!Number.isSafeInteger(l.offset)||l.offset<0||!Number.isSafeInteger(l.length)||l.length<1||l.length>4*1024*1024+(a?16:0)||a&&(typeof l.nonce!="string"||!/^[0-9a-f]{24}$/.test(l.nonce)||!Number.isSafeInteger(l.plainLength)||l.plainLength<1||l.plainLength>4*1024*1024||l.length!==l.plainLength+16))throw new Error("Invalid web app shard");if(a){if(i.has(l.nonce))throw new Error("Repeated web app nonce");i.add(l.nonce)}h+=a?l.plainLength:l.length}if(h!==s.length)throw new Error("Web app resource length mismatch")}if(t&&n===0)throw new Error("Encrypted app has no member resources");let o=e.resources.find(s=>s.path===e.entry);if(!o||!o.mime.startsWith("text/html"))throw new Error("Web app entry must be HTML");if(o.delivery==="download")throw new Error("Web app entry cannot be a download");if(e.identity){let s=e.resources.find(a=>a.path===e.identity.icon);if(!s||s.mime!=="image/x-icon"||W(e,s)||s.delivery==="download")throw new Error("App identity favicon must be public")}return e}var Vt=Pe(Ie(),1);import{createHash as Dn,timingSafeEqual as Fn}from"node:crypto";var Yn=Buffer.from("AMWPX1\0\0"),D=44,zt=16*1024*1024,$n=16*1024*1024;function Wn(e,t){for(;t;)[e,t]=[t,e%t];return e}function Gn(e){if(!Buffer.isBuffer(e)||e.length<33||!e.subarray(0,8).equals(Buffer.from("89504e470d0a1a0a","hex"))||e.toString("ascii",12,16)!=="IHDR")throw new Error("Expected a PNG image");let t=e.readUInt32BE(16),r=e.readUInt32BE(20);if(!t||!r||t*r>zt)throw new Error("PNG pixel count exceeds limit");let n=Vt.PNG.sync.read(e,{checkCRC:!0}),i=n.width*n.height;if(!Number.isSafeInteger(i)||i<1||i>zt)throw new Error("PNG pixel count exceeds limit");let o=[];for(let h=0;h<i;h++)n.data[h*4+3]===255&&o.push(h);let s=o.length*3;if(s<D*8)throw new Error("PNG has too few opaque pixels");let a=65537;for(;Wn(a,s)!==1;)a+=2;return{png:n,opaque:Uint32Array.from(o),slots:s,stride:a}}function jt(e,t,r){if(t.length*8>e.slots)throw new Error("Pixel carrier capacity exceeded");let n=0;for(let i=0;i<t.length;i++){let o=r?t[i]:0;for(let s=7;s>=0;s--){let a=e.opaque[Math.floor(n/3)]*4+n%3;r?e.png.data[a]=e.png.data[a]&254|o>>>s&1:o=o<<1|e.png.data[a]&1,n=(n+e.stride)%e.slots}r||(t[i]=o)}}function ke(e){let t=Gn(e),r=Buffer.alloc(D);if(jt(t,r,!1),!r.subarray(0,8).equals(Yn))throw new Error("No AmoosedWeb pixel payload");let n=r.readUInt32LE(8);if(n<1||n>$n||n+D>Math.floor(t.slots/8))throw new Error("Invalid pixel payload length");let i=Buffer.alloc(D+n);jt(t,i,!1);let o=Dn("sha256").update(i.subarray(D)).digest();if(!Fn(o,r.subarray(12,44)))throw new Error("Pixel payload integrity failure");return i.subarray(D)}import{createHash as Kt,timingSafeEqual as Qn}from"node:crypto";var so=Buffer.from("AMW-MEDIA-TRANSPORT-V1");import{createHash as zn}from"node:crypto";var jn=e=>zn("sha256").update(e).digest("hex");function Ce(e,t){return e.length===t.length&&jn(e)===t.sha256}var Jn=[1e3,1500,2e3,2500],Z=Array.from({length:16},(e,t)=>t&1?3:0),ei=Buffer.from("AWA1"),ti=128,V=54,Xt=4096,ri=128*1024*1024,ni=3,ii=e=>Kt("sha256").update(e).digest("hex");function oi(e){return Z.length+e.length*4}function si(e){if(!Buffer.isBuffer(e)||e.length<44||e.length>ri||e.toString("ascii",0,4)!=="RIFF"||e.toString("ascii",8,12)!=="WAVE")throw new Error("Expected a bounded PCM WAV file");let t,r;for(let a=12;a+8<=e.length;){let h=e.toString("ascii",a,a+4),l=e.readUInt32LE(a+4);if(a+8+l>e.length)throw new Error("Invalid WAV chunk");h==="fmt "&&(t=e.subarray(a+8,a+8+l)),h==="data"&&(r=e.subarray(a+8,a+8+l)),a+=8+l+(l&1)}if(!t||t.length<16||!r||t.readUInt16LE(0)!==1||![1,2].includes(t.readUInt16LE(2))||![16e3,44100,48e3].includes(t.readUInt32LE(4))||![8,16].includes(t.readUInt16LE(14)))throw new Error("Expected 16/44.1/48 kHz 8/16-bit PCM");let n=t.readUInt16LE(2),i=t.readUInt32LE(4),o=t.readUInt16LE(14)/8;if(r.length%(n*o))throw new Error("Invalid WAV sample length");let s=new Float32Array(r.length/(n*o));for(let a=0;a<s.length;a++){let h=0;for(let l=0;l<n;l++){let c=(a*n+l)*o;h+=o===1?(r[c]-128)/128:r.readInt16LE(c)/32768}s[a]=h/n}return{samples:s,rate:i}}function ai(e,t,r,n){let i=r+Math.round(t*.001),o=r+Math.round(t*.009);if(i<0||o>=e.length)return-1;let s=0,a=0,h=2*Math.PI*n/t;for(let l=i;l<o;l++)s+=e[l]*Math.cos(h*(l-i)),a+=e[l]*Math.sin(h*(l-i));return s*s+a*a}function Qt(e,t,r){let n=-1,i=0;for(let o=0;o<4;o++){let s=ai(e,t,r,Jn[o]);s>n&&(n=s,i=o)}return i}function Zt(e,t,r,n){let i=Buffer.alloc(n),o=t/100;for(let s=0;s<n;s++)for(let a=0;a<4;a++)i[s]=i[s]<<2|Qt(e,t,Math.round(r+(Z.length+s*4+a)*o));return i}function xe(e,t,r,n){let i=t/100,o=-1,s=-1;for(let w=-2;w<=1;w+=.5){let d=r+Math.round(w*t/1e3);if(d<0)continue;let y=0;for(let k=0;k<Z.length;k++)Qt(e,t,Math.round(d+k*i))===Z[k]&&y++;y>s&&(s=y,o=d)}if(s<14)return null;let a=Zt(e,t,o,V);if(!a.subarray(0,4).equals(ei))return null;let h=a.readUInt32LE(4),l=a.readUInt16LE(8),c=a.readUInt16LE(10),f=a.readUInt16LE(12);if(h<1||h>Xt||l<1||l>32||c>=l||f<1||f>ti||f>h||o+oi(Buffer.alloc(V+f))*i>n+t*.004)return null;let g=Zt(e,t,o,V+f).subarray(V),p=Kt("sha256").update(g).digest().subarray(0,8);return Qn(p,a.subarray(46,54))?{total:h,count:l,index:c,sha256:a.subarray(14,46).toString("hex"),data:g}:null}function li(e,t=[]){let{samples:r,rate:n}=si(e),i=Math.round(n/1e3),o=[];for(let l of t){if(!Number.isFinite(l.startSeconds)||l.startSeconds<0)continue;let c=Math.round(l.startSeconds*n);for(let f=-3;f<=3;f+=.5){let u=xe(r,n,c+Math.round(f*n/1e3),r.length);if(u&&u.index===l.packet){o.push(u);break}}}if(o.length===t.length&&t.length)return o;let s=!1,a=0,h=0;for(let l=0;l<r.length;l+=i){let c=0;for(let u=l;u<Math.min(l+i,r.length);u++)c+=r[u]*r[u];let f=c/i>.002;if(f&&!s?(s=!0,a=l,h=0):f?h=0:s&&h++,s&&h>=20){s=!1;let u=xe(r,n,a,l-19*i);u&&o.push(u)}}if(s){let l=xe(r,n,a,r.length);l&&o.push(l)}return o}function Jt(e,t){if(!t||t.format!=="amw.audio-carrier.v1"||!Number.isInteger(t.length)||t.length<1||t.length>Xt||!/^[0-9a-f]{64}$/.test(t.sha256)||!Array.isArray(t.packets)||t.packets.length<1||t.packets.length>32||!Array.isArray(t.locations)||t.locations.length!==t.packets.length*ni||t.locations.some(i=>!Number.isInteger(i.packet)||i.packet<0||i.packet>=t.packets.length||!Number.isFinite(i.startSeconds)||i.startSeconds<0))throw new Error("Invalid audio carrier manifest");let r=new Map;for(let i of li(e,t.locations))i.total!==t.length||i.count!==t.packets.length||i.sha256!==t.sha256||!Ce(i.data,t.packets[i.index])||r.has(i.index)||r.set(i.index,i.data);if(r.size!==t.packets.length)throw new Error("Audio carrier recovery incomplete");let n=Buffer.concat(t.packets.map((i,o)=>r.get(o)));if(n.length!==t.length||ii(n)!==t.sha256)throw new Error("Audio carrier integrity failure");return n}var or=Pe(Ie(),1);import{createHash as hi}from"node:crypto";function er(e,t,r){let n=t*r;if(!Number.isSafeInteger(n)||t<256||r<128||n>16*1024*1024||e.length!==n*4)throw new Error("Invalid frame dimensions");let i=(c,f)=>{for(;f;)[c,f]=[f,c%f];return c},o=Math.floor(n*.61803398875)|1;for(;i(o,n)!==1;)o+=2;let s=((Math.imul(t,73856093)^Math.imul(r,19349663))>>>0)%n,a=new Uint32Array(768),h=c=>{let f=c*4;return(299*(e[f]&254)+587*(e[f+1]&254)+114*(e[f+2]&254))/1e3},l=c=>{let f=c%t,u=Math.floor(c/t),g=h(c),p=0;return f>0&&(p+=Math.abs(g-h(c-1))),f+1<t&&(p+=Math.abs(g-h(c+1))),u>0&&(p+=Math.abs(g-h(c-t))),u+1<r&&(p+=Math.abs(g-h(c+t))),p};for(let c=0,f=0;c<n&&f<a.length;){let u=-1,g=-1;for(let p=0;p<16&&c<n;p++,c++){let w=(s+c*o)%n;if(e[w*4+3]!==255)continue;let d=l(w);d>g&&(u=w,g=d)}if(u>=0&&(a[f++]=u),f===a.length)return a}throw new Error("Frame needs at least 768 opaque pixels")}var Co=Buffer.from("AWF1"),M=8,tr=32,rr=16,Le=11,ci=32-Le,nr=3;var fi=e=>hi("sha256").update(e).digest();function ui(e){if(!Buffer.isBuffer(e)||e.length<33||!e.subarray(0,8).equals(Buffer.from("89504e470d0a1a0a","hex"))||e.readUInt32BE(16)*e.readUInt32BE(20)>16*1024*1024)throw new Error("Expected a bounded PNG frame");let t=or.PNG.sync.read(e,{checkCRC:!0});if(t.width<tr*M||t.height<rr*M)throw new Error("Frame must be at least 256 x 128 pixels");for(let r=0;r<rr*M;r++)for(let n=0;n<tr*M;n++)if(t.data[(r*t.width+n)*4+3]!==255)throw new Error("Frame data region must be opaque");return t}function ir(e,t,r){let n=0;for(let i=0;i<M;i++)for(let o=0;o<M;o++){let s=((r+i)*e.width+t+o)*4;n+=(e.data[s]*299+e.data[s+1]*587+e.data[s+2]*114)/1e3}return n/(M*M)}function di(e){let t=Math.floor(e/16);return[e%16*2*M,t*M]}function pi(e){let t=Buffer.alloc(32);for(let r=0;r<t.length*8;r++){let[n,i]=di(r);ir(e,n,i)>ir(e,n+M,i)&&(t[r>>>3]|=1<<7-(r&7))}return t}function sr(e){let t=ui(e),r=er(t.data,t.width,t.height),n=Buffer.alloc(32);for(let i=0;i<256;i++){let o=0;for(let s=0;s<nr;s++)o+=t.data[r[i*nr+s]*4]&1;o>=2&&(n[i>>>3]|=1<<7-(i&7))}return n.subarray(0,4).equals(Buffer.from("AWF2"))?ar(n,"AWF2"):gi(t)}function gi(e){return ar(pi(e),"AWF1")}function ar(e,t){if(!e.subarray(0,4).equals(Buffer.from(t))||e.readUInt16LE(4)!==0||e[6]<1||e[6]>ci)throw new Error("Invalid luminance frame payload");let r=e.subarray(Le,Le+e[6]);if(!fi(r).subarray(0,4).equals(e.subarray(7,11)))throw new Error("Luminance frame integrity failure");return r}var _i=16*1024*1024,bi=e=>Be("sha256").update(e).digest("hex"),fr=e=>Buffer.from(e,"hex");function Se(e,t){let r=pr(e,t);return r&&r!==".."&&!r.startsWith(`..${gr}`)&&!mi(r)&&!r.includes(":")}async function ur(e,t){if(t!==e&&!Se(e,t))throw new Error("Unsafe resource output path");let r=await Me(e);if(!r.isDirectory()||r.isSymbolicLink())throw new Error("Output root must be a real directory");let n=await cr(e);if(t===e)return;let i=e;for(let o of pr(e,t).split(gr)){i=yi(i,o);try{await Oe(i)}catch(a){if(a.code!=="EEXIST")throw a}let s=await Me(i);if(!s.isDirectory()||s.isSymbolicLink()||!Se(n,await cr(i)))throw new Error("Output path traverses a symbolic link or junction")}}async function Ei(e,t){let r=await Te(e,"r"),n;try{n=await Te(t,"wx",384);let i=Buffer.allocUnsafe(64*1024);for(;;){let{bytesRead:o}=await r.read(i,0,i.length,null);if(!o)break;let s=0;for(;s<o;){let{bytesWritten:a}=await n.write(i,s,o-s,null);if(!a)throw new Error("Incomplete local write");s+=a}}}catch(i){throw n&&(await n.close(),n=null,await dr(t).catch(()=>{})),i}finally{n&&await n.close(),await r.close()}}function Ai(e){let t=new URL(e);if(t.username||t.password||!(t.protocol==="https:"||t.protocol==="http:"&&["localhost","127.0.0.1"].includes(t.hostname)))throw new Error("Remote site requires HTTPS or local HTTP");return t.origin}async function Ii(e,t,r){let n=new URL(t.url,e.origin);if(n.origin!==e.origin)throw new Error("Carrier changed origin");let i=t.codec==="png-lsb1"?["pixel",64*1024*1024]:t.codec==="wav-4fsk1"?["audio",128*1024*1024]:["frame-luma1","frame-luma2"].includes(t.codec)?["frame",64*1024*1024]:null;if(i){if(!r.has(t.url)){let h=await e.fetcher(n,{cache:"no-store",credentials:"omit",redirect:"error"});if(h.status!==200||new URL(h.url,e.origin).origin!==e.origin)throw new Error(`${t.url}: media carrier unavailable`);let l=Buffer.from(await S(h,i[1])),c=i[0]==="pixel"?ke(l):i[0]==="audio"?Jt(l,e.app.audioCarriers?.[t.url]):sr(l);r.set(t.url,c)}return r.get(t.url).subarray(t.offset,t.offset+t.length)}let o=t.offset+t.length-1,s=await e.fetcher(n,{headers:{Range:`bytes=${t.offset}-${o}`},cache:"no-store",credentials:"omit",redirect:"error"});if(![200,206].includes(s.status)||new URL(s.url,e.origin).origin!==e.origin)throw new Error(`${t.url}: carrier unavailable`);if(s.status===206){let h=/^bytes (\d+)-(\d+)\/(\d+)$/.exec(s.headers.get("Content-Range")||"");if(!h||Number(h[1])!==t.offset||Number(h[2])!==o||!Number.isSafeInteger(Number(h[3])))throw new Error(`${t.url}: invalid range`);return Buffer.from(await S(s,t.length))}return Buffer.from(await S(s,_i)).subarray(t.offset,o+1)}function ki(e,t,r,n,i){if(i.length!==n.length||bi(i)!==n.sha256)throw new Error(`${n.url}: chunk integrity failure`);let o=i;if(e.app.encoding){let s=Be("sha256").update(`AMW1-SITE-CTR\0${t.path}\0${r}`).digest().subarray(0,16),a=lr("aes-256-ctr",fr(e.app.encoding.key),s);o=Buffer.concat([a.update(o),a.final()])}if(W(e.app,t)){if(!e.contentKey)throw new Error("Member content key required");try{let s=lr("aes-256-gcm",e.contentKey,fr(n.nonce));if(s.setAAD(Ke(t,r,n.plainLength)),s.setAuthTag(o.subarray(-16)),o=Buffer.concat([s.update(o.subarray(0,-16)),s.final()]),o.length!==n.plainLength)throw new Error("Plaintext length mismatch")}catch{throw new Error("Member key or chunk authentication failed")}}return o}async function qo(e,{credential:t,indexKeyFile:r,contentKey:n,memberKeyFile:i,fetcher:o=fetch}={}){let s=Ai(e);if(t&&r||n&&i)throw new Error("Supply one source for each key");if(r){let c=await hr(r);t=c.subarray(0,8).toString("ascii")==="AMWKEY1:"?{indexToken:ze(c)}:{indexBytes:c}}let a;if(i){let c=await hr(i),f=c.toString("utf8").trim();if(/^[0-9a-fA-F]{64}$/.test(f))n=Buffer.from(f,"hex");else{let u=ae(je(c));a=u.keyId,n=Buffer.from(u.key)}}if(n&&(!(n instanceof Uint8Array)||n.length!==32))throw new Error("Invalid member content key");let h;t?.indexToken?h={privateIndex:oe(t.indexToken)}:t?.indexBytes?h=await qe(t.indexBytes):h=await He(`${s}/favicon.ico`,{fetcher:o}),h=await Ye(h,o,s);let l=Xe(h.webApp);if(a&&l.encryption?.keyId!==a)throw new Error("Member key belongs to another edition");return{origin:s,app:l,contentKey:n&&Buffer.from(n),fetcher:o}}function Do(e){return e.app.resources.map(t=>({path:t.path,bytes:t.length,sha256:t.sha256,mime:t.mime,access:W(e.app,t)?"members":"public",delivery:t.delivery||"app"}))}async function Ci(e,t,r,{outputRoot:n}={}){let i=e.app.resources.find(u=>u.path===t);if(!i)throw new Error("Resource is absent from the verified index");let o=X(r);n?await ur(n,K(o)):await Oe(K(o),{recursive:!0});let s=X(K(o),`.amw-download-${wi(12).toString("hex")}`),a=await Te(s,"wx",384),h=Be("sha256"),l=new Map,c=null,f=0;try{try{for(let[u,g]of i.parts.entries()){c!==g.url&&l.clear(),c=g.url;let p=ki(e,i,u,g,await Ii(e,g,l));h.update(p),f+=p.length;let w=0;for(;w<p.length;){let{bytesWritten:d}=await a.write(p,w,p.length-w,null);if(!d)throw new Error("Incomplete local write");w+=d}}}finally{await a.close()}if(f!==i.length||h.digest("hex")!==i.sha256)throw new Error("Resource integrity failure");return n&&await ur(n,K(o)),await Ei(s,o),{path:o,bytes:f,sha256:i.sha256}}finally{await dr(s).catch(u=>{if(u.code!=="ENOENT")throw u})}}async function Fo(e,t){let r=X(t);await Oe(r,{recursive:!0});let n=await Me(r);if(!n.isDirectory()||n.isSymbolicLink())throw new Error("Output root must be a real directory");let i=[];for(let o of e.app.resources){let s=o.path.slice(17),a=X(r,s);if(!Se(r,a))throw new Error("Unsafe resource output path");i.push(await Ci(e,o.path,a,{outputRoot:r}))}return i}export{Ci as downloadRemoteResource,Fo as downloadRemoteSite,Do as listRemoteResources,qo as openRemoteSite};
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Copyright (c) 2026 Juhapekka Piiroinen <jp@1337.fi>
|
|
2
|
+
// All Rights Reserved.
|
|
3
|
+
// AmoosedWeb project: https://amoosed.com
|
|
4
|
+
// Compatibility surface preserving the published JavaScript Reader API.
|
|
5
|
+
import { lstat, mkdir, realpath } from 'node:fs/promises';
|
|
6
|
+
import { dirname, isAbsolute, relative, resolve, sep } from 'node:path';
|
|
7
|
+
import { openSite } from './index.mjs';
|
|
8
|
+
|
|
9
|
+
function inside(root, target) {
|
|
10
|
+
const suffix = relative(root, target);
|
|
11
|
+
return suffix && suffix !== '..' && !suffix.startsWith(`..${sep}`) &&
|
|
12
|
+
!isAbsolute(suffix) && !suffix.includes(':');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function prepareParent(root, parent) {
|
|
16
|
+
if (parent !== root && !inside(root, parent)) throw new Error('Unsafe resource output path');
|
|
17
|
+
const info = await lstat(root);
|
|
18
|
+
if (!info.isDirectory() || info.isSymbolicLink())
|
|
19
|
+
throw new Error('Output root must be a real directory');
|
|
20
|
+
const actualRoot = await realpath(root);
|
|
21
|
+
let current = root;
|
|
22
|
+
if (parent === root) return;
|
|
23
|
+
for (const part of relative(root, parent).split(sep)) {
|
|
24
|
+
current = resolve(current, part);
|
|
25
|
+
try { await mkdir(current); }
|
|
26
|
+
catch (error) { if (error.code !== 'EEXIST') throw error; }
|
|
27
|
+
const row = await lstat(current);
|
|
28
|
+
if (!row.isDirectory() || row.isSymbolicLink() || !inside(actualRoot, await realpath(current)))
|
|
29
|
+
throw new Error('Output path traverses a symbolic link or junction');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function openRemoteSite(site, options = {}) {
|
|
34
|
+
const { credential, indexKeyFile, contentKey, memberKeyFile, fetcher } = options;
|
|
35
|
+
if (credential && indexKeyFile || contentKey && memberKeyFile)
|
|
36
|
+
throw new Error('Supply one source for each key');
|
|
37
|
+
if (contentKey != null && (!(contentKey instanceof Uint8Array) || contentKey.length !== 32))
|
|
38
|
+
throw new Error('Invalid member content key');
|
|
39
|
+
let indexCredential;
|
|
40
|
+
if (credential) {
|
|
41
|
+
if (credential.indexToken && !credential.indexBytes)
|
|
42
|
+
indexCredential = Buffer.from(`AMWKEY1:${credential.indexToken}\n`);
|
|
43
|
+
else if (credential.indexBytes && !credential.indexToken &&
|
|
44
|
+
credential.indexBytes instanceof Uint8Array)
|
|
45
|
+
indexCredential = Buffer.from(credential.indexBytes);
|
|
46
|
+
else throw new Error('Invalid index credential');
|
|
47
|
+
}
|
|
48
|
+
const memberKey = contentKey == null ? undefined : Buffer.from(contentKey);
|
|
49
|
+
let native;
|
|
50
|
+
try {
|
|
51
|
+
native = await openSite(new URL(site).origin, { indexCredential, indexKeyFile,
|
|
52
|
+
memberKey, memberKeyFile, fetcher });
|
|
53
|
+
const resources = await native.listResources();
|
|
54
|
+
return { native, resources, close: () => native.close() };
|
|
55
|
+
} catch (error) {
|
|
56
|
+
await native?.close();
|
|
57
|
+
throw error;
|
|
58
|
+
} finally {
|
|
59
|
+
indexCredential?.fill(0);
|
|
60
|
+
memberKey?.fill(0);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function listRemoteResources(session) {
|
|
65
|
+
return session.resources.map(row => ({ ...row }));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export async function downloadRemoteResource(session, resourcePath, output, { outputRoot } = {}) {
|
|
69
|
+
const resource = session.resources.find(row => row.path === resourcePath);
|
|
70
|
+
if (!resource) {
|
|
71
|
+
const error = new Error('Resource is absent from the verified index');
|
|
72
|
+
error.statusCode = 14;
|
|
73
|
+
error.operation = 'Download resource';
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
const target = resolve(output);
|
|
77
|
+
if (outputRoot) {
|
|
78
|
+
const root = resolve(outputRoot);
|
|
79
|
+
await prepareParent(root, dirname(target));
|
|
80
|
+
} else await mkdir(dirname(target), { recursive: true });
|
|
81
|
+
const result = await session.native.downloadResource(resourcePath, target);
|
|
82
|
+
return { path: target, bytes: result.bytes, sha256: resource.sha256 };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export async function downloadRemoteSite(session, outputDirectory) {
|
|
86
|
+
return session.native.downloadSite(outputDirectory);
|
|
87
|
+
}
|
package/native/index.mjs
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
// Copyright (c) 2026 Juhapekka Piiroinen <jp@1337.fi>
|
|
2
|
+
// All Rights Reserved.
|
|
3
|
+
// AmoosedWeb project: https://amoosed.com
|
|
4
|
+
import { createRequire } from 'node:module';
|
|
5
|
+
import { lstat, mkdir, readFile, realpath, stat } from 'node:fs/promises';
|
|
6
|
+
import { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
7
|
+
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
const native = require('./amoosedweb_native_reader.node');
|
|
10
|
+
const utf8 = new TextDecoder('utf-8', { fatal: true });
|
|
11
|
+
async function readLimited(path, maximum) {
|
|
12
|
+
if (typeof path !== 'string' || !path) throw new TypeError('Key file path must be a string');
|
|
13
|
+
if ((await stat(path)).size > maximum) throw new Error('Key file is too large');
|
|
14
|
+
const bytes = await readFile(path);
|
|
15
|
+
if (bytes.length > maximum) {
|
|
16
|
+
bytes.fill(0);
|
|
17
|
+
throw new Error('Key file is too large');
|
|
18
|
+
}
|
|
19
|
+
return bytes;
|
|
20
|
+
}
|
|
21
|
+
function decodeMemberFile(bytes) {
|
|
22
|
+
const text = utf8.decode(bytes);
|
|
23
|
+
if (/^[0-9a-fA-F]{64}$/.test(text.trim()))
|
|
24
|
+
return { key: Buffer.from(text.trim(), 'hex'), id: null };
|
|
25
|
+
const match = /^AMWMEMBER1:([A-Za-z0-9_-]{51,135})\r?\n?$/.exec(text);
|
|
26
|
+
if (!match) throw new Error('Invalid Amoosed member key file');
|
|
27
|
+
const decoded = Buffer.from(match[1], 'base64url');
|
|
28
|
+
try {
|
|
29
|
+
if (decoded.length < 38 || decoded.length !== 37 + decoded[4] ||
|
|
30
|
+
decoded.toString('ascii', 0, 4) !== 'AMM1' ||
|
|
31
|
+
decoded.toString('base64url') !== match[1])
|
|
32
|
+
throw new Error('Invalid Amoosed member key token');
|
|
33
|
+
const id = utf8.decode(decoded.subarray(37));
|
|
34
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(id))
|
|
35
|
+
throw new Error('Invalid Amoosed member key token');
|
|
36
|
+
return { key: Buffer.from(decoded.subarray(5, 37)), id };
|
|
37
|
+
} finally { decoded.fill(0); }
|
|
38
|
+
}
|
|
39
|
+
async function resolveKeys({ indexCredential, indexKeyFile, memberKey, memberKeyFile } = {}) {
|
|
40
|
+
if (indexCredential != null && indexKeyFile != null ||
|
|
41
|
+
memberKey != null && memberKeyFile != null)
|
|
42
|
+
throw new Error('Supply one source for each key');
|
|
43
|
+
if (indexCredential != null && !Buffer.isBuffer(indexCredential))
|
|
44
|
+
throw new TypeError('indexCredential must be a Buffer');
|
|
45
|
+
if (memberKey != null && (!Buffer.isBuffer(memberKey) || memberKey.length !== 32))
|
|
46
|
+
throw new TypeError('memberKey must be a 32-byte Buffer');
|
|
47
|
+
let ownedCredential, ownedMember, memberId = null;
|
|
48
|
+
try {
|
|
49
|
+
if (indexKeyFile != null) ownedCredential = await readLimited(indexKeyFile, 1024 * 1024);
|
|
50
|
+
if (memberKeyFile != null) {
|
|
51
|
+
const source = await readLimited(memberKeyFile, 512);
|
|
52
|
+
try {
|
|
53
|
+
const parsed = decodeMemberFile(source);
|
|
54
|
+
ownedMember = parsed.key;
|
|
55
|
+
memberId = parsed.id;
|
|
56
|
+
} finally { source.fill(0); }
|
|
57
|
+
}
|
|
58
|
+
return { credential: ownedCredential ?? indexCredential ?? null,
|
|
59
|
+
key: ownedMember ?? memberKey ?? null, memberId,
|
|
60
|
+
clear: () => { ownedCredential?.fill(0); ownedMember?.fill(0); } };
|
|
61
|
+
} catch (error) {
|
|
62
|
+
ownedCredential?.fill(0);
|
|
63
|
+
ownedMember?.fill(0);
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function validateSignal(signal) {
|
|
68
|
+
if (signal != null && !(signal instanceof AbortSignal))
|
|
69
|
+
throw new TypeError('signal must be an AbortSignal');
|
|
70
|
+
}
|
|
71
|
+
function withAbort(pending, signal) {
|
|
72
|
+
if (signal == null) return pending;
|
|
73
|
+
const abort = () => pending.cancel();
|
|
74
|
+
if (signal.aborted) abort();
|
|
75
|
+
else signal.addEventListener('abort', abort, { once: true });
|
|
76
|
+
return pending.catch(error => {
|
|
77
|
+
if (error.statusCode === 7) error.name = 'AbortError';
|
|
78
|
+
throw error;
|
|
79
|
+
}).finally(() => signal.removeEventListener('abort', abort));
|
|
80
|
+
}
|
|
81
|
+
function injectedFetchBridge(origin, fetcher) {
|
|
82
|
+
if (typeof fetcher !== 'function') throw new TypeError('fetcher must be a function');
|
|
83
|
+
return (request, done) => {
|
|
84
|
+
void (async () => {
|
|
85
|
+
const url = new URL(request.path, origin);
|
|
86
|
+
if (url.origin !== origin || url.pathname !== request.path)
|
|
87
|
+
throw new Error('Unsafe native fetch path');
|
|
88
|
+
const headers = request.kind === 1 ?
|
|
89
|
+
{ Range: `bytes=${request.first}-${request.last}` } : request.kind === 2 ?
|
|
90
|
+
{ Range: `bytes=-${request.first}` } : {};
|
|
91
|
+
const response = await fetcher(url, {
|
|
92
|
+
headers: { ...headers, 'Accept-Encoding': 'identity' },
|
|
93
|
+
cache: 'no-store', credentials: 'omit', redirect: 'error'
|
|
94
|
+
});
|
|
95
|
+
const encoding = response.headers?.get('Content-Encoding');
|
|
96
|
+
if (encoding && encoding.trim().toLowerCase() !== 'identity')
|
|
97
|
+
throw new Error('Injected fetch returned encoded carrier bytes');
|
|
98
|
+
let size = 0;
|
|
99
|
+
const chunks = [];
|
|
100
|
+
if (response.body) {
|
|
101
|
+
const reader = response.body.getReader();
|
|
102
|
+
try {
|
|
103
|
+
while (true) {
|
|
104
|
+
const { done: ended, value } = await reader.read();
|
|
105
|
+
if (ended) break;
|
|
106
|
+
size += value.byteLength;
|
|
107
|
+
if (size > request.maxBody) {
|
|
108
|
+
await reader.cancel();
|
|
109
|
+
throw new Error('Injected fetch exceeded native response bound');
|
|
110
|
+
}
|
|
111
|
+
chunks.push(Buffer.from(value));
|
|
112
|
+
}
|
|
113
|
+
} finally { reader.releaseLock(); }
|
|
114
|
+
} else {
|
|
115
|
+
const bytes = Buffer.from(await response.arrayBuffer());
|
|
116
|
+
if (bytes.length > request.maxBody)
|
|
117
|
+
throw new Error('Injected fetch exceeded native response bound');
|
|
118
|
+
size = bytes.length;
|
|
119
|
+
chunks.push(bytes);
|
|
120
|
+
}
|
|
121
|
+
done({ status: response.status, url: response.url || url.href,
|
|
122
|
+
contentRange: response.headers?.get('Content-Range') ?? null,
|
|
123
|
+
etag: response.headers?.get('ETag') ?? null,
|
|
124
|
+
contentEncoding: encoding ?? null, body: Buffer.concat(chunks, size) });
|
|
125
|
+
})().catch(() => done(null));
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function inside(root, target) {
|
|
129
|
+
const suffix = relative(root, target);
|
|
130
|
+
return suffix && suffix !== '..' && !suffix.startsWith(`..${sep}`) &&
|
|
131
|
+
!isAbsolute(suffix) && !suffix.includes(':');
|
|
132
|
+
}
|
|
133
|
+
function pullTarget(root, resourcePath) {
|
|
134
|
+
const prefix = '/amoosed.com/app/';
|
|
135
|
+
if (typeof resourcePath !== 'string' || !resourcePath.startsWith(prefix))
|
|
136
|
+
throw new Error('Unsafe resource output path');
|
|
137
|
+
const parts = resourcePath.slice(prefix.length).split('/');
|
|
138
|
+
if (parts.some(part => !part || part === '.' || part === '..' ||
|
|
139
|
+
!/^[^\\/:*?"<>|\x00-\x1f]+$/.test(part) || /[. ]$/.test(part) ||
|
|
140
|
+
/^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\..*)?$/i.test(part)))
|
|
141
|
+
throw new Error('Unsafe resource output path');
|
|
142
|
+
const target = resolve(root, ...parts);
|
|
143
|
+
if (!inside(root, target)) throw new Error('Unsafe resource output path');
|
|
144
|
+
return target;
|
|
145
|
+
}
|
|
146
|
+
async function preparePullParent(root, actualRoot, parent) {
|
|
147
|
+
if (parent !== root && !inside(root, parent))
|
|
148
|
+
throw new Error('Unsafe resource output path');
|
|
149
|
+
let current = root;
|
|
150
|
+
if (parent === root) return;
|
|
151
|
+
for (const part of relative(root, parent).split(sep)) {
|
|
152
|
+
current = join(current, part);
|
|
153
|
+
try { await mkdir(current); }
|
|
154
|
+
catch (error) { if (error.code !== 'EEXIST') throw error; }
|
|
155
|
+
const info = await lstat(current);
|
|
156
|
+
if (!info.isDirectory() || info.isSymbolicLink() ||
|
|
157
|
+
!inside(actualRoot, await realpath(current)))
|
|
158
|
+
throw new Error('Output path traverses a symbolic link or junction');
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Local review API. The native worker opens a verified index for each call.
|
|
163
|
+
// Key inputs remain in caller-owned Buffers; clear them after use.
|
|
164
|
+
export async function decodeStandaloneWav(wav, mediaKey) {
|
|
165
|
+
if (!Buffer.isBuffer(wav) || wav.length === 0 || wav.length > 64 * 1024 * 1024)
|
|
166
|
+
throw new TypeError('wav must be a Buffer of at most 64 MiB');
|
|
167
|
+
if (!Buffer.isBuffer(mediaKey) || mediaKey.length !== 32)
|
|
168
|
+
throw new TypeError('mediaKey must be a 32-byte Buffer');
|
|
169
|
+
return native.decodeStandaloneWavNative(wav, mediaKey);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export async function readBytes(origin, resourcePath, options = {}) {
|
|
173
|
+
const { signal } = options;
|
|
174
|
+
if (typeof origin !== 'string' || typeof resourcePath !== 'string')
|
|
175
|
+
throw new TypeError('origin and resourcePath must be strings');
|
|
176
|
+
validateSignal(signal);
|
|
177
|
+
if (options.fetcher !== undefined) {
|
|
178
|
+
const session = await openSite(origin, options);
|
|
179
|
+
try { return await session.readBytes(resourcePath, { signal }); }
|
|
180
|
+
finally { await session.close(); }
|
|
181
|
+
}
|
|
182
|
+
const keys = await resolveKeys(options);
|
|
183
|
+
try {
|
|
184
|
+
return await withAbort(native.readBytesNative(origin, resourcePath,
|
|
185
|
+
keys.credential, keys.key, keys.memberId), signal);
|
|
186
|
+
} finally { keys.clear(); }
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export async function listResources(origin, options = {}) {
|
|
190
|
+
const { signal } = options;
|
|
191
|
+
if (typeof origin !== 'string') throw new TypeError('origin must be a string');
|
|
192
|
+
validateSignal(signal);
|
|
193
|
+
if (options.fetcher !== undefined) {
|
|
194
|
+
const session = await openSite(origin, options);
|
|
195
|
+
try { return await session.listResources({ signal }); }
|
|
196
|
+
finally { await session.close(); }
|
|
197
|
+
}
|
|
198
|
+
const keys = await resolveKeys(options);
|
|
199
|
+
try {
|
|
200
|
+
return await withAbort(native.listResourcesNative(origin,
|
|
201
|
+
keys.credential, keys.memberId), signal);
|
|
202
|
+
} finally { keys.clear(); }
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export async function downloadResource(origin, resourcePath, outputPath, options = {}) {
|
|
206
|
+
const { signal } = options;
|
|
207
|
+
if (typeof origin !== 'string' || typeof resourcePath !== 'string' ||
|
|
208
|
+
typeof outputPath !== 'string')
|
|
209
|
+
throw new TypeError('origin, resourcePath, and outputPath must be strings');
|
|
210
|
+
validateSignal(signal);
|
|
211
|
+
if (options.fetcher !== undefined) {
|
|
212
|
+
const session = await openSite(origin, options);
|
|
213
|
+
try { return await session.downloadResource(resourcePath, outputPath, { signal }); }
|
|
214
|
+
finally { await session.close(); }
|
|
215
|
+
}
|
|
216
|
+
const keys = await resolveKeys(options);
|
|
217
|
+
try {
|
|
218
|
+
return await withAbort(native.downloadResourceNative(origin, resourcePath,
|
|
219
|
+
resolve(outputPath), keys.credential, keys.key, keys.memberId), signal);
|
|
220
|
+
} finally { keys.clear(); }
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Keep one verified index snapshot for several operations. Calls on the native
|
|
224
|
+
// site handle are serialized; close waits for accepted calls to finish.
|
|
225
|
+
export async function openSite(origin, options = {}) {
|
|
226
|
+
if (typeof origin !== 'string') throw new TypeError('origin must be a string');
|
|
227
|
+
validateSignal(options.signal);
|
|
228
|
+
const bridge = options.fetcher === undefined ? undefined :
|
|
229
|
+
injectedFetchBridge(new URL(origin).origin, options.fetcher);
|
|
230
|
+
const keys = await resolveKeys(options);
|
|
231
|
+
let defaultMember;
|
|
232
|
+
let handle;
|
|
233
|
+
try {
|
|
234
|
+
if (keys.key) defaultMember = Buffer.from(keys.key);
|
|
235
|
+
handle = await withAbort(bridge ? native.openSiteNative(origin, keys.credential, bridge) :
|
|
236
|
+
native.openSiteNative(origin, keys.credential), options.signal);
|
|
237
|
+
if (keys.memberId)
|
|
238
|
+
await withAbort(native.sessionListNative(handle, keys.memberId), options.signal);
|
|
239
|
+
} catch (error) {
|
|
240
|
+
if (handle) native.closeSiteNative(handle);
|
|
241
|
+
defaultMember?.fill(0);
|
|
242
|
+
throw error;
|
|
243
|
+
} finally { keys.clear(); }
|
|
244
|
+
const defaultId = keys.memberId;
|
|
245
|
+
let closed = false;
|
|
246
|
+
let closePromise;
|
|
247
|
+
let queue = Promise.resolve();
|
|
248
|
+
const schedule = work => {
|
|
249
|
+
if (closed) return Promise.reject(new Error('Native Reader session is closed'));
|
|
250
|
+
const result = queue.then(work);
|
|
251
|
+
queue = result.catch(() => {});
|
|
252
|
+
return result;
|
|
253
|
+
};
|
|
254
|
+
const memberFor = async callOptions => {
|
|
255
|
+
if (callOptions.indexCredential != null || callOptions.indexKeyFile != null)
|
|
256
|
+
throw new Error('Index credential is fixed when the session opens');
|
|
257
|
+
if (callOptions.memberKey == null && callOptions.memberKeyFile == null)
|
|
258
|
+
return { key: defaultMember, memberId: defaultId, clear: () => {} };
|
|
259
|
+
return resolveKeys({ memberKey: callOptions.memberKey,
|
|
260
|
+
memberKeyFile: callOptions.memberKeyFile });
|
|
261
|
+
};
|
|
262
|
+
return {
|
|
263
|
+
listResources(callOptions = {}) {
|
|
264
|
+
validateSignal(callOptions.signal);
|
|
265
|
+
return schedule(() => withAbort(native.sessionListNative(handle, defaultId),
|
|
266
|
+
callOptions.signal));
|
|
267
|
+
},
|
|
268
|
+
readBytes(resourcePath, callOptions = {}) {
|
|
269
|
+
if (typeof resourcePath !== 'string')
|
|
270
|
+
throw new TypeError('resourcePath must be a string');
|
|
271
|
+
validateSignal(callOptions.signal);
|
|
272
|
+
return schedule(async () => {
|
|
273
|
+
const member = await memberFor(callOptions);
|
|
274
|
+
try {
|
|
275
|
+
return await withAbort(native.sessionReadNative(handle, resourcePath,
|
|
276
|
+
member.key, member.memberId), callOptions.signal);
|
|
277
|
+
} finally { member.clear(); }
|
|
278
|
+
});
|
|
279
|
+
},
|
|
280
|
+
downloadResource(resourcePath, outputPath, callOptions = {}) {
|
|
281
|
+
if (typeof resourcePath !== 'string' || typeof outputPath !== 'string')
|
|
282
|
+
throw new TypeError('resourcePath and outputPath must be strings');
|
|
283
|
+
validateSignal(callOptions.signal);
|
|
284
|
+
return schedule(async () => {
|
|
285
|
+
const member = await memberFor(callOptions);
|
|
286
|
+
try {
|
|
287
|
+
return await withAbort(native.sessionDownloadNative(handle, resourcePath,
|
|
288
|
+
resolve(outputPath), member.key, member.memberId), callOptions.signal);
|
|
289
|
+
} finally { member.clear(); }
|
|
290
|
+
});
|
|
291
|
+
},
|
|
292
|
+
downloadSite(outputDirectory, callOptions = {}) {
|
|
293
|
+
if (typeof outputDirectory !== 'string' || !outputDirectory)
|
|
294
|
+
throw new TypeError('outputDirectory must be a nonempty string');
|
|
295
|
+
validateSignal(callOptions.signal);
|
|
296
|
+
return schedule(async () => {
|
|
297
|
+
const member = await memberFor(callOptions);
|
|
298
|
+
try {
|
|
299
|
+
const resources = await withAbort(native.sessionListNative(handle,
|
|
300
|
+
member.memberId), callOptions.signal);
|
|
301
|
+
const root = resolve(outputDirectory);
|
|
302
|
+
const seen = new Set();
|
|
303
|
+
const targets = resources.map(resource => {
|
|
304
|
+
const target = pullTarget(root, resource.path);
|
|
305
|
+
const identity = process.platform === 'win32' ? target.toLowerCase() : target;
|
|
306
|
+
if (seen.has(identity)) throw new Error('Duplicate resource output path');
|
|
307
|
+
seen.add(identity);
|
|
308
|
+
return target;
|
|
309
|
+
});
|
|
310
|
+
if (!member.key && resources.some(resource => resource.access === 'members'))
|
|
311
|
+
throw new Error('A member key is required to download the whole site');
|
|
312
|
+
await mkdir(root, { recursive: true });
|
|
313
|
+
const info = await lstat(root);
|
|
314
|
+
if (!info.isDirectory() || info.isSymbolicLink())
|
|
315
|
+
throw new Error('Output root must be a real directory');
|
|
316
|
+
const actualRoot = await realpath(root);
|
|
317
|
+
const downloaded = [];
|
|
318
|
+
for (let index = 0; index < resources.length; ++index) {
|
|
319
|
+
await preparePullParent(root, actualRoot, dirname(targets[index]));
|
|
320
|
+
const result = await withAbort(native.sessionDownloadNative(handle,
|
|
321
|
+
resources[index].path, targets[index], member.key, member.memberId),
|
|
322
|
+
callOptions.signal);
|
|
323
|
+
downloaded.push({ ...result, sha256: resources[index].sha256 });
|
|
324
|
+
}
|
|
325
|
+
return downloaded;
|
|
326
|
+
} finally { member.clear(); }
|
|
327
|
+
});
|
|
328
|
+
},
|
|
329
|
+
close() {
|
|
330
|
+
if (closePromise) return closePromise;
|
|
331
|
+
closed = true;
|
|
332
|
+
closePromise = queue.then(() => {
|
|
333
|
+
try { native.closeSiteNative(handle); }
|
|
334
|
+
finally { defaultMember?.fill(0); }
|
|
335
|
+
});
|
|
336
|
+
return closePromise;
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "amoosedweb-reader",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.1",
|
|
4
4
|
"description": "Verified AmoosedWeb remote resource reader for Node.js",
|
|
5
5
|
"homepage": "https://www.amoosed.com/",
|
|
6
6
|
"type": "module",
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
14
|
"index.mjs",
|
|
15
|
+
"js-reader.mjs",
|
|
16
|
+
"native/",
|
|
15
17
|
"COPYRIGHT.txt",
|
|
16
18
|
"LICENSE.txt"
|
|
17
19
|
],
|