From 7368b57721d55ffa7408d3617c9e1e5c00a66723 Mon Sep 17 00:00:00 2001 From: ukyo Date: Sun, 19 Jan 2014 12:30:50 +0900 Subject: [PATCH] add ZipArchiveWrite.js --- Gruntfile.coffee | 2 + README.md | 75 ++++++++++++- bower.json | 2 +- jsziptools.js | 4 +- package.json | 2 +- src/ZipArchiveWriter.js | 235 ++++++++++++++++++++++++++++++++++++++++ src/stream/zip.pack.js | 187 ++------------------------------ test/test.js | 42 +++++++ test/worker.js | 1 + 9 files changed, 369 insertions(+), 181 deletions(-) create mode 100644 src/ZipArchiveWriter.js diff --git a/Gruntfile.coffee b/Gruntfile.coffee index e8a5cc9..5481e0d 100644 --- a/Gruntfile.coffee +++ b/Gruntfile.coffee @@ -10,6 +10,7 @@ module.exports = (grunt) -> 'src/algorithms/crc32.js' 'src/algorithms/deflate.js' 'src/algorithms/inflate.js' + 'src/ZipArchiveWriter.js' 'src/stream/algorithms/deflate.js' 'src/stream/algorithms/inflate.js' 'src/stream/zlib.compress.js' @@ -60,6 +61,7 @@ module.exports = (grunt) -> 'src/algorithms/crc32.js' 'src/algorithms/deflate.js' 'src/algorithms/inflate.js' + 'src/ZipArchiveWriter.js' 'src/stream/algorithms/deflate.js' 'src/stream/algorithms/inflate.js' 'src/stream/zlib.compress.js' diff --git a/README.md b/README.md index 586065e..885d568 100644 --- a/README.md +++ b/README.md @@ -390,4 +390,77 @@ It gets filenames in the zip archive. #### ZipArchiveReader#readFileAsDataURLSync(filename) * @param {string} filename -* @return {string} \ No newline at end of file +* @return {string} + +### jz.zip.ZipArchiveWriter({shareMemory, chunkSize}) + +Low level zip archive writer. + +* @param {boolean} shareMemory - optional (default is `false`) +* @param {number} chunkSize - optional (default is `0x8000`) + +```js + var writer = new jz.zip.ZipArchiveWriter({shareMemory: true, chunkSize: 0xf000}); + writer + .on('data', function(chunk) { + // chunk is Uint8Array. + }) + .on('end', function() { + // ... + }); + .write('foo/bar/baz.txt', buffer) + .write('a.mp3', mp3Buff) + .writeEnd(); +``` + +#### #on(name, callback) + +* @param {string} name +* @param {function} callback +* @return {jz.zip.ZipArchiveWriter} this + +#### #write(path, buffer, level) + +Write the file. Directories are created automatically. + +* @param {string} path +* @param {Uint8Array} buffer +* @param {number} level - optional (default is `6`) +* @return {jz.zip.ZipArchiveWriter} this + +```js +writer.write('a/b/c/d/foo.txt', buffer, 7); +``` + +#### #writeDir(path) + +* @param {string} path +* @return {jz.zip.ZipArchiveWriter} this + +```js +writer.writeDir('foo/'); +// or +writer.writeDir('bar/'); +``` + +#### #writeFile(path, buffer, level) + +* @param {string} path +* @param {Uint8Array} buffer +* @param {number} level - optional (default is `6`) +* @return {jz.zip.ZipArchiveWriter} this + +```js +writer.writeDir('a/'); +writer.writeDir('a/b/'); +writer.writeDir('a/b/c/'); +writer.writeFile('a/b/c/foo.txt', buffer, 7); +``` + +#### #writeEnd() + +Write central directory headers and the end central dirctory header. + +```js +writer.writeEnd(); +``` \ No newline at end of file diff --git a/bower.json b/bower.json index 480a51c..1837658 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "jsziptools", "main": "jsziptools.js", - "version": "2.4.0", + "version": "2.4.1", "homepage": "https://github.com/ukyo/jsziptools", "authors": [ "ukyo " diff --git a/jsziptools.js b/jsziptools.js index a9dfae9..72ee8b4 100644 --- a/jsziptools.js +++ b/jsziptools.js @@ -213,5 +213,5 @@ function Rc(a){var b=a.map(function(a){return a.length}).reduce(function(a,b){re function Vc(a,b){var c;c=b.level;var d=b.chunkSize;Nc(b.input,b.streamFn,b.shareMemory);c=Cc(c||Oc,a,d||Pc);Mc(c)}function Wc(a,b){var c;c=b.chunkSize;Nc(b.input,b.streamFn,b.shareMemory);c=Dc(a,c||Pc);Mc(c)}Uc.deflate=Vc.bind(k,1);Uc.rawDeflate=Vc.bind(k,-1);Uc.inflate=Wc.bind(k,1);Uc.rawInflate=Wc.bind(k,-1);"undefined"!==typeof define&&define.amd?define("zlib",function(){return Qc}):s&&(module.exports=Qc); }).call(zlib); -function expose(a,b){var c=a.split("."),d=c.pop(),e=global;c.forEach(function(a){e[a]=e[a]||{},e=e[a]}),e[d]=b}function exposeProperty(a,b,c){b.prototype[a]=c}function createEndCentDirHeader(a,b,c){var d=new DataView(new ArrayBuffer(22));return d.setUint32(0,zip.END_SIGNATURE,!0),d.setUint16(4,0,!0),d.setUint16(6,0,!0),d.setUint16(8,a,!0),d.setUint16(10,a,!0),d.setUint32(12,b,!0),d.setUint32(16,c,!0),d.setUint16(20,0,!0),new Uint8Array(d.buffer)}function createCentralDirHeader(a,b,c,d,e,f){var g=new DataView(new ArrayBuffer(46+b.length)),h=new Uint8Array(g.buffer),i=0;return g.setUint32(i,zip.CENTRAL_DIR_SIGNATURE,!0),i+=4,g.setUint16(i,20,!0),i+=2,g.setUint16(i,20,!0),i+=2,g.setUint16(i,8),i+=2,g.setUint16(i,d?8:0,!0),i+=2,g.setUint16(i,createDosFileTime(c),!0),i+=2,g.setUint16(i,createDosFileDate(c),!0),i+=2,h.set(f,i),i+=12,g.setUint16(i,b.length,!0),i+=2,i+=12,g.setUint32(i,e,!0),i+=4,h.set(b,i),h}function createLocalFileHeader(a,b,c,d){var e=new DataView(new ArrayBuffer(30+b.length)),f=new Uint8Array(e.buffer),g=0;return e.setUint32(g,zip.LOCAL_FILE_SIGNATURE,!0),g+=4,e.setUint16(g,20,!0),g+=2,e.setUint16(g,8),g+=2,e.setUint16(g,d?8:0,!0),g+=2,e.setUint16(g,createDosFileTime(c),!0),g+=2,e.setUint16(g,createDosFileDate(c),!0),g+=2,g+=12,e.setUint16(g,b.length,!0),g+=2,g+=2,f.set(b,g),f}function createDataDescriptor(a,b,c){var d=new DataView(new ArrayBuffer(12));return d.setUint32(0,c,!0),d.setUint32(4,b,!0),d.setUint32(8,a,!0),new Uint8Array(d.buffer)}function createDosFileDate(a){return a.getFullYear()-1980<<9|a.getMonth()+1<<5|a.getDay()}function createDosFileTime(a){return a.getHours()<<11|a.getMinutes()<<5|a.getSeconds()>>1}function ZipArchiveReader(a){this.bytes=utils.toBytes(a.buffer),this.buffer=this.bytes.buffer,this.params=a}function ZipArchiveReaderBlob(a){this.blob=a.buffer,this.params=a}var utils={},algorithms={},gz={},zip={},env={},zpipe={},stream={algorithms:{},zlib:{},gz:{},zip:{}},global=this;zip.LOCAL_FILE_SIGNATURE=67324752,zip.CENTRAL_DIR_SIGNATURE=33639248,zip.END_SIGNATURE=101010256,env.isWorker="function"==typeof importScripts,expose("jz.algos",algorithms),expose("jz.stream.algos",stream.algorithms),utils.toArray=function(a){return Array.prototype.slice.call(a)},utils.getParams=function(a,b){if("[object Object]"===Object.prototype.toString.call(a[0]))return a[0];var c={};return b.forEach(function(b,d){c[b]=a[d]}),c},utils.toBytes=function(a){switch(Object.prototype.toString.call(a)){case"[object String]":return utils.stringToBytes(a);case"[object Array]":case"[object ArrayBuffer]":return new Uint8Array(a);case"[object Uint8Array]":return a;case"[object Int8Array]":case"[object Uint8ClampedArray]":case"[object CanvasPixelArray]":return new Uint8Array(a.buffer,a.byteOffset,a.byteLength);default:throw new Error("jz.utils.toBytes: not supported type.")}},expose("jz.utils.toBytes",utils.toBytes),utils.readFileAs=function(a,b,c){var d;return d=env.isWorker?function(d){var e=new FileReaderSync;d(e["readAs"+a].call(e,b,c))}:function(d,e){var f=new FileReader;f.onload=function(){d(f.result)},f.onerror=e,f["readAs"+a].call(f,b,c)},new Promise(d)},utils.readFileAsText=function(a,b){return utils.readFileAs("Text",a,b||"UTF-8")},utils.readFileAsArrayBuffer=utils.readFileAs.bind(null,"ArrayBuffer"),utils.readFileAsDataURL=utils.readFileAs.bind(null,"DataURL"),utils.readFileAsBinaryString=utils.readFileAs.bind(null,"BinaryString"),expose("jz.utils.readFileAsArrayBuffer",utils.readFileAsArrayBuffer),expose("jz.utils.readFileAsText",utils.readFileAsText),expose("jz.utils.readFileAsDataURL",utils.readFileAsDataURL),expose("jz.utils.readFileAsBinaryString",utils.readFileAsBinaryString),utils.stringToBytes=function(a){var b,c,d,e=a.length,f=-1,g=32,h=new Uint8Array(g);for(b=0;e>b;++b)c=a.charCodeAt(b),127>=c?h[++f]=c:2047>=c?(h[++f]=192|c>>>6,h[++f]=128|63&c):65535>=c?(h[++f]=224|c>>>12,h[++f]=128|c>>>6&63,h[++f]=128|63&c):(h[++f]=240|c>>>18,h[++f]=128|c>>>12&63,h[++f]=128|c>>>6&63,h[++f]=128|63&c),4>=g-f&&(d=h,g*=2,h=new Uint8Array(g),h.set(d));return h.subarray(0,++f)},utils.bytesToString=function(a,b){return utils.readFileAsText(new Blob([utils.toBytes(a)]),b)},expose("jz.utils.bytesToString",utils.bytesToString),utils.bytesToStringSync=null,env.isWorker&&(utils.bytesToStringSync=function(a,b){return(new FileReaderSync).readAsText(new Blob([utils.toBytes(a)]),b||"UTF-8")},expose("jz.utils.bytesToStringSync",utils.bytesToStringSync)),utils.detectEncoding=function(a){a=utils.toBytes(a);for(var b=0,c=a.length;c>b;++b)if(!(a[b]<128))if(192===(224&a[b])){if(128===(192&a[++b]))continue}else if(224===(240&a[b])){if(128===(192&a[++b])&&128===(192&a[++b]))continue}else{if(240!==(248&a[b]))return"Shift_JIS";if(128===(192&a[++b])&&128===(192&a[++b])&&128===(192&a[++b]))continue}return"UTF-8"},expose("jz.utils.detectEncoding",utils.detectEncoding),Promise.prototype.spread=function(a,b){return Promise.prototype.then.call(this,Function.prototype.apply.bind(a,null),b)},utils.load=function(a){return a=Array.isArray(a)?a:utils.toArray(arguments),Promise.all(a.map(function(a){return new Promise(function(b,c){var d=new XMLHttpRequest;d.open("GET",a),d.responseType="arraybuffer",d.onloadend=function(){var e=d.status;200===e||206===e||0===e?b(new Uint8Array(d.response)):c(new Error("Load Error: "+e+" "+a))},d.onerror=c,d.send()})}))},expose("jz.utils.load",utils.load),utils.concatBytes=function(a){var b,c,d,a=Array.isArray(a)?a:utils.toArray(arguments),e=0,f=0;for(b=0,c=a.length;c>b;++b)e+=a[b].length;for(d=new Uint8Array(e),b=0;c>b;++b)d.set(a[b],f),f+=a[b].length;return d},expose("jz.utils.concatBytes",utils.concatBytes),algorithms.adler32=function(a){for(var b,a=utils.toBytes(a),c=1,d=0,e=0,f=65521,g=a.length;g>0;){b=g>5550?5550:g,g-=b;do c+=a[e++],d+=c;while(--b);c%=f,d%=f}return(d<<16|c)>>>0},expose("jz.algorithms.adler32",algorithms.adler32),algorithms.crc32=function(){var a=function(){var a,b,c,d=3988292384,e=new Uint32Array(256);for(b=0;256>b;++b){for(a=b,c=0;8>c;++c)a=1&a?a>>>1^d:a>>>1;e[b]=a>>>0}return e}();return function(b,c){for(var d=utils.getParams(arguments,["buffer","crc"]),e=utils.toBytes(d.buffer),c=null==d.crc?4294967295:~d.crc>>>0,f=0,g=e.length,h=a;g>f;++f)c=c>>>8^h[e[f]^255&c];return~c>>>0}}(),expose("jz.algorithms.crc32",algorithms.crc32),algorithms.deflate=function(){var a=utils.getParams(arguments,["buffer","level","chunkSize"]);return zlib.rawDeflate(utils.toBytes(a.buffer),a.level,a.chunkSize)},expose("jz.algorithms.deflate",algorithms.deflate),algorithms.inflate=function(){var a=utils.getParams(arguments,["buffer","chunkSize"]);return zlib.rawInflate(utils.toBytes(a.buffer),a.chunkSize)},expose("jz.algorithms.inflate",algorithms.inflate),stream.algorithms.deflate=function(){var a=utils.getParams(arguments,["buffer","streamFn","level","shareMemory","chunkSize"]);a.input=utils.toBytes(a.buffer),zlib.stream.rawDeflate(a)},expose("jz.stream.algorithms.deflate",stream.algorithms.deflate),stream.algorithms.inflate=function(){var a=utils.getParams(arguments,["buffer","streamFn","shareMemory","chunkSize"]);a.input=utils.toBytes(a.buffer),zlib.stream.rawInflate(a)},expose("jz.stream.algorithms.inflate",stream.algorithms.inflate),stream.zlib.compress=function(){var a=utils.getParams(arguments,["buffer","streamFn","level","shareMemory","chunkSize"]);a.input=utils.toBytes(a.buffer),zlib.stream.deflate(a)},expose("jz.stream.zlib.compress",stream.zlib.compress),stream.zlib.decompress=function(){var a=utils.getParams(arguments,["buffer","streamFn","shareMemory","chunkSize"]);a.input=utils.toBytes(a.buffer),zlib.stream.inflate(a)},expose("jz.stream.zlib.decompress",stream.zlib.decompress),stream.gz.compress=function(a,b,c,d,e,f,g){var h,i,j,k=utils.getParams(arguments,["buffer","streamFn","level","shareMemory","chunkSize","fname","fcomment"]),l=utils.toBytes(k.buffer),b=(k.level,k.streamFn),d=k.shareMemory,e=k.chunkSize,f=k.fname&&utils.toBytes(k.fname),g=k.fcomment&&utils.toBytes(k.fcomment),m=0,n=10,o=0,p=Date.now();f&&(n+=f.length+1,m|=8),g&&(n+=g.length+1,m|=16),h=new Uint8Array(n),j=new DataView(h.buffer),j.setUint32(o,529205248|m),o+=4,j.setUint32(o,p,!0),o+=4,j.setUint16(o,1279),o+=2,f&&(h.set(f,o),o+=f.length,h[o++]=0),g&&(h.set(g,o),o+=g.length,h[o++]=0),b(h),stream.algorithms.deflate({buffer:l,streamFn:b,shareMemory:d,chunkSize:e}),i=new Uint8Array(8),j=new DataView(i.buffer),j.setUint32(0,algorithms.crc32(l),!0),j.setUint32(4,l.length,!0),b(i)},expose("jz.stream.gz.compress",stream.gz.compress),stream.gz.decompress=function(a,b,c,d){var e,f,g=utils.getParams(arguments,["buffer","streamFn","shareMemory","chunkSize"]),h=utils.toBytes(g.buffer),b=g.streamFn,c=g.shareMemory,d=g.chunkSize,i=10,j=new DataView(h.buffer,h.byteOffset,h.byteLength);if(8075!==j.getUint16(0))throw new Error("jz.gz.decompress: invalid gzip file.");if(8!==h[2])throw new Error("jz.gz.decompress: not deflate.");if(e=h[3],4&e&&(i+=j.getUint16(i,!0)+2),8&e)for(;h[i++];);if(16&e)for(;h[i++];);if(2&e&&(i+=2),stream.algorithms.inflate({buffer:h.subarray(i,h.length-8),streamFn:function(a){f=algorithms.crc32(a,f),b(a)},shareMemory:c,chunkSize:d}),f!==j.getUint32(h.length-8,!0))throw new Error("js.stream.gz.decompress: file is broken.")},expose("jz.stream.gz.decompress",stream.gz.decompress),stream.zip.pack=function(a,b,c,d,e){function f(a,c,g){var h,l,m,n,o,p,q=g.children||g.dir||g.folder;if(a="number"==typeof g.level?g.level:a,q)h=new ArrayBuffer(0),c+=g.name+(/.+\/$/.test(g.name)?"":"/");else{if(null!=g.buffer&&(h=g.buffer),null!=g.str&&(h=g.str),null==h)throw new Error("jz.zip.pack: This type is not supported.");c+=g.name}h=utils.toBytes(h),l=!q&&a,m=utils.toBytes(c),n=createLocalFileHeader(h,m,k,l),b(n),o=0,l?stream.algorithms.deflate({buffer:h,shareMemory:d,chunkSize:e,streamFn:function(a){o+=a.length,b(a)}}):(b(h),o=h.length),dataDescriptor=createDataDescriptor(h.length,o,algorithms.crc32(h)),p=createCentralDirHeader(h,m,k,l,i,dataDescriptor),j.push(p),i+=n.length+o,q&&q.forEach(f.bind(null,a,c))}function g(a){var b=a.children||a.dir||a.folder;b?b.forEach(g):a.url&&l.push(utils.load(a.url).then(function(b){a.buffer=b[0],a.url=null}))}var h=utils.getParams(arguments,["files","streamFn","level","shareMemory","chunkSize"]),i=0,j=[],k=new Date,a=h.files,c=h.level="number"==typeof h.level?h.level:6,e=h.chunkSize,d=h.shareMemory,b=h.streamFn,l=[];return a.forEach(g),Promise.all(l).then(function(){a.forEach(f.bind(null,c,""));var d=utils.concatBytes(j);b(d),b(createEndCentDirHeader(j.length,d.length,i))})},expose("jz.stream.zip.pack",stream.zip.pack),expose("jz.zlib.compress",function(){var a=utils.getParams(arguments,["buffer","level","chunkSize"]);return zlib.deflate(utils.toBytes(a.buffer),a.level,a.chunkSize)}),expose("jz.zlib.decompress",function(){var a=utils.getParams(arguments,["buffer","chunkSize"]);return zlib.inflate(utils.toBytes(a.buffer),a.chunkSize)}),gz.compress=function(){var a=utils.getParams(arguments,["buffer","level","chunkSize","fname","fcomment"]),b=[];return stream.gz.compress({buffer:a.buffer,level:a.level,chunkSize:a.chunkSize,fname:a.fname,fcomment:a.fcomments,streamFn:function(a){b.push(a)}}),utils.concatBytes(b)},expose("jz.gz.compress",gz.compress),gz.decompress=function(){var a=utils.getParams(arguments,["buffer","chunkSize"]),b=[];return stream.gz.decompress({buffer:a.buffer,streamFn:function(a){b.push(a)},shareMemory:!1,chunkSize:a.chunkSize}),utils.concatBytes(b)},expose("jz.gz.decompress",gz.decompress),zip.pack=function(){var a=utils.getParams(arguments,["files","level","chunkSize"]),b=[];return stream.zip.pack({files:a.files,shareMemory:!1,level:a.level,chunkSize:a.chunkSize,streamFn:function(a){b.push(a)}}).then(function(){return utils.concatBytes(b)})},expose("jz.zip.pack",zip.pack);var mimetypes=function(){var a="application/epub+zip epub\napplication/x-gzip gz\napplication/andrew-inset ez\napplication/annodex anx\napplication/atom+xml atom\napplication/atomcat+xml atomcat\napplication/atomserv+xml atomsrv\napplication/bbolin lin\napplication/cap cap pcap\napplication/cu-seeme cu\napplication/davmount+xml davmount\napplication/dsptype tsp\napplication/ecmascript es\napplication/futuresplash spl\napplication/hta hta\napplication/java-archive jar\napplication/java-serialized-object ser\napplication/java-vm class\napplication/javascript js\napplication/json json\napplication/m3g m3g\napplication/mac-binhex40 hqx\napplication/mac-compactpro cpt\napplication/mathematica nb nbp\napplication/msaccess mdb\napplication/msword doc dot\napplication/mxf mxf\napplication/octet-stream bin\napplication/oda oda\napplication/ogg ogx\napplication/onenote one onetoc2 onetmp onepkg\napplication/pdf pdf\napplication/pgp-keys key\napplication/pgp-signature pgp\napplication/pics-rules prf\napplication/postscript ps ai eps epsi epsf eps2 eps3\napplication/rar rar\napplication/rdf+xml rdf\napplication/rss+xml rss\napplication/rtf rtf\napplication/sla stl\napplication/smil smi smil\napplication/xhtml+xml xhtml xht\napplication/xml xml xsl xsd\napplication/xspf+xml xspf\napplication/zip zip\napplication/vnd.android.package-archive apk\napplication/vnd.cinderella cdy\napplication/vnd.google-earth.kml+xml kml\napplication/vnd.google-earth.kmz kmz\napplication/vnd.mozilla.xul+xml xul\napplication/vnd.ms-excel xls xlb xlt\napplication/vnd.ms-excel.addin.macroEnabled.12 xlam\napplication/vnd.ms-excel.sheet.binary.macroEnabled.12 xlsb\napplication/vnd.ms-excel.sheet.macroEnabled.12 xlsm\napplication/vnd.ms-excel.template.macroEnabled.12 xltm\napplication/vnd.ms-officetheme thmx\napplication/vnd.ms-pki.seccat cat\napplication/vnd.ms-powerpoint ppt pps\napplication/vnd.ms-powerpoint.addin.macroEnabled.12 ppam\napplication/vnd.ms-powerpoint.presentation.macroEnabled.12 pptm\napplication/vnd.ms-powerpoint.slide.macroEnabled.12 sldm\napplication/vnd.ms-powerpoint.slideshow.macroEnabled.12 ppsm\napplication/vnd.ms-powerpoint.template.macroEnabled.12 potm\napplication/vnd.ms-word.document.macroEnabled.12 docm\napplication/vnd.ms-word.template.macroEnabled.12 dotm\napplication/vnd.oasis.opendocument.chart odc\napplication/vnd.oasis.opendocument.database odb\napplication/vnd.oasis.opendocument.formula odf\napplication/vnd.oasis.opendocument.graphics odg\napplication/vnd.oasis.opendocument.graphics-template otg\napplication/vnd.oasis.opendocument.image odi\napplication/vnd.oasis.opendocument.presentation odp\napplication/vnd.oasis.opendocument.presentation-template otp\napplication/vnd.oasis.opendocument.spreadsheet ods\napplication/vnd.oasis.opendocument.spreadsheet-template ots\napplication/vnd.oasis.opendocument.text odt\napplication/vnd.oasis.opendocument.text-master odm\napplication/vnd.oasis.opendocument.text-template ott\napplication/vnd.oasis.opendocument.text-web oth\napplication/vnd.openxmlformats-officedocument.presentationml.presentation pptx\napplication/vnd.openxmlformats-officedocument.presentationml.slide sldx\napplication/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx\napplication/vnd.openxmlformats-officedocument.presentationml.template potx\napplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx\napplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx\napplication/vnd.openxmlformats-officedocument.spreadsheetml.template xltx\napplication/vnd.openxmlformats-officedocument.spreadsheetml.template xltx\napplication/vnd.openxmlformats-officedocument.wordprocessingml.document docx\napplication/vnd.openxmlformats-officedocument.wordprocessingml.template dotx\napplication/vnd.rim.cod cod\napplication/vnd.smaf mmf\napplication/vnd.stardivision.calc sdc\napplication/vnd.stardivision.chart sds\napplication/vnd.stardivision.draw sda\napplication/vnd.stardivision.impress sdd\napplication/vnd.stardivision.math sdf\napplication/vnd.stardivision.writer sdw\napplication/vnd.stardivision.writer-global sgl\napplication/vnd.sun.xml.calc sxc\napplication/vnd.sun.xml.calc.template stc\napplication/vnd.sun.xml.draw sxd\napplication/vnd.sun.xml.draw.template std\napplication/vnd.sun.xml.impress sxi\napplication/vnd.sun.xml.impress.template sti\napplication/vnd.sun.xml.math sxm\napplication/vnd.sun.xml.writer sxw\napplication/vnd.sun.xml.writer.global sxg\napplication/vnd.sun.xml.writer.template stw\napplication/vnd.symbian.install sis\napplication/vnd.visio vsd\napplication/vnd.wap.wbxml wbxml\napplication/vnd.wap.wmlc wmlc\napplication/vnd.wap.wmlscriptc wmlsc\napplication/vnd.wordperfect wpd\napplication/vnd.wordperfect5.1 wp5\napplication/x-123 wk\napplication/x-7z-compressed 7z\napplication/x-abiword abw\napplication/x-apple-diskimage dmg\napplication/x-bcpio bcpio\napplication/x-bittorrent torrent\napplication/x-cab cab\napplication/x-cbr cbr\napplication/x-cbz cbz\napplication/x-cdf cdf cda\napplication/x-cdlink vcd\napplication/x-chess-pgn pgn\napplication/x-comsol mph\napplication/x-cpio cpio\napplication/x-csh csh\napplication/x-debian-package deb udeb\napplication/x-director dcr dir dxr\napplication/x-dms dms\napplication/x-doom wad\napplication/x-dvi dvi\napplication/x-font pfa pfb gsf pcf pcf.Z\napplication/x-freemind mm\napplication/x-futuresplash spl\napplication/x-ganttproject gan\napplication/x-gnumeric gnumeric\napplication/x-go-sgf sgf\napplication/x-graphing-calculator gcf\napplication/x-gtar gtar\napplication/x-gtar-compressed tgz taz\napplication/x-hdf hdf\napplication/x-httpd-eruby rhtml\napplication/x-httpd-php phtml pht php\napplication/x-httpd-php-source phps\napplication/x-httpd-php3 php3\napplication/x-httpd-php3-preprocessed php3p\napplication/x-httpd-php4 php4\napplication/x-httpd-php5 php5\napplication/x-ica ica\napplication/x-info info\napplication/x-internet-signup ins isp\napplication/x-iphone iii\napplication/x-iso9660-image iso\napplication/x-jam jam\napplication/x-java-jnlp-file jnlp\napplication/x-jmol jmz\napplication/x-kchart chrt\napplication/x-killustrator kil\napplication/x-koan skp skd skt skm\napplication/x-kpresenter kpr kpt\napplication/x-kspread ksp\napplication/x-kword kwd kwt\napplication/x-latex latex\napplication/x-lha lha\napplication/x-lyx lyx\napplication/x-lzh lzh\napplication/x-lzx lzx\napplication/x-maker frm maker frame fm fb book fbdoc\napplication/x-mif mif\napplication/x-mpegURL m3u8\napplication/x-ms-wmd wmd\napplication/x-ms-wmz wmz\napplication/x-msdos-program com exe bat dll\napplication/x-msi msi\napplication/x-netcdf nc\napplication/x-ns-proxy-autoconfig pac dat\napplication/x-nwc nwc\napplication/x-object o\napplication/x-oz-application oza\napplication/x-pkcs7-certreqresp p7r\napplication/x-pkcs7-crl crl\napplication/x-python-code pyc pyo\napplication/x-qgis qgs shp shx\napplication/x-quicktimeplayer qtl\napplication/x-rdp rdp\napplication/x-redhat-package-manager rpm\napplication/x-ruby rb\napplication/x-scilab sci sce\napplication/x-sh sh\napplication/x-shar shar\napplication/x-shockwave-flash swf swfl\napplication/x-silverlight scr\napplication/x-sql sql\napplication/x-stuffit sit sitx\napplication/x-sv4cpio sv4cpio\napplication/x-sv4crc sv4crc\napplication/x-tar tar\napplication/x-tcl tcl\napplication/x-tex-gf gf\napplication/x-tex-pk pk\napplication/x-texinfo texinfo texi\napplication/x-trash ~ % bak old sik\napplication/x-troff t tr roff\napplication/x-troff-man man\napplication/x-troff-me me\napplication/x-troff-ms ms\napplication/x-ustar ustar\napplication/x-wais-source src\napplication/x-wingz wz\napplication/x-x509-ca-cert crt\napplication/x-xcf xcf\napplication/x-xfig fig\napplication/x-xpinstall xpi\naudio/amr amr\naudio/amr-wb awb\naudio/amr amr\naudio/amr-wb awb\naudio/annodex axa\naudio/basic au snd\naudio/csound csd orc sco\naudio/flac flac\naudio/midi mid midi kar\naudio/mpeg mpga mpega mp2 mp3 m4a\naudio/mpegurl m3u\naudio/ogg oga ogg spx\naudio/prs.sid sid\naudio/x-aiff aif aiff aifc\naudio/x-gsm gsm\naudio/x-mpegurl m3u\naudio/x-ms-wma wma\naudio/x-ms-wax wax\naudio/x-pn-realaudio ra rm ram\naudio/x-realaudio ra\naudio/x-scpls pls\naudio/x-sd2 sd2\naudio/x-wav wav\nchemical/x-alchemy alc\nchemical/x-cache cac cache\nchemical/x-cache-csf csf\nchemical/x-cactvs-binary cbin cascii ctab\nchemical/x-cdx cdx\nchemical/x-cerius cer\nchemical/x-chem3d c3d\nchemical/x-chemdraw chm\nchemical/x-cif cif\nchemical/x-cmdf cmdf\nchemical/x-cml cml\nchemical/x-compass cpa\nchemical/x-crossfire bsd\nchemical/x-csml csml csm\nchemical/x-ctx ctx\nchemical/x-cxf cxf cef\nchemical/x-embl-dl-nucleotide emb embl\nchemical/x-galactic-spc spc\nchemical/x-gamess-input inp gam gamin\nchemical/x-gaussian-checkpoint fch fchk\nchemical/x-gaussian-cube cub\nchemical/x-gaussian-input gau gjc gjf\nchemical/x-gaussian-log gal\nchemical/x-gcg8-sequence gcg\nchemical/x-genbank gen\nchemical/x-hin hin\nchemical/x-isostar istr ist\nchemical/x-jcamp-dx jdx dx\nchemical/x-kinemage kin\nchemical/x-macmolecule mcm\nchemical/x-macromodel-input mmd mmod\nchemical/x-mdl-molfile mol\nchemical/x-mdl-rdfile rd\nchemical/x-mdl-rxnfile rxn\nchemical/x-mdl-sdfile sd sdf\nchemical/x-mdl-tgf tgf\nchemical/x-mmcif mcif\nchemical/x-mol2 mol2\nchemical/x-molconn-Z b\nchemical/x-mopac-graph gpt\nchemical/x-mopac-input mop mopcrt mpc zmt\nchemical/x-mopac-out moo\nchemical/x-mopac-vib mvb\nchemical/x-ncbi-asn1 asn\nchemical/x-ncbi-asn1-ascii prt ent\nchemical/x-ncbi-asn1-binary val aso\nchemical/x-ncbi-asn1-spec asn\nchemical/x-pdb pdb ent\nchemical/x-rosdal ros\nchemical/x-swissprot sw\nchemical/x-vamas-iso14976 vms\nchemical/x-vmd vmd\nchemical/x-xtel xtel\nchemical/x-xyz xyz\nimage/gif gif\nimage/ief ief\nimage/jpeg jpeg jpg jpe\nimage/pcx pcx\nimage/png png\nimage/svg+xml svg svgz\nimage/tiff tiff tif\nimage/vnd.djvu djvu djv\nimage/vnd.wap.wbmp wbmp\nimage/x-canon-cr2 cr2\nimage/x-canon-crw crw\nimage/x-cmu-raster ras\nimage/x-coreldraw cdr\nimage/x-coreldrawpattern pat\nimage/x-coreldrawtemplate cdt\nimage/x-corelphotopaint cpt\nimage/x-epson-erf erf\nimage/x-icon ico\nimage/x-jg art\nimage/x-jng jng\nimage/x-ms-bmp bmp\nimage/x-nikon-nef nef\nimage/x-olympus-orf orf\nimage/x-photoshop psd\nimage/x-portable-anymap pnm\nimage/x-portable-bitmap pbm\nimage/x-portable-graymap pgm\nimage/x-portable-pixmap ppm\nimage/x-rgb rgb\nimage/x-xbitmap xbm\nimage/x-xpixmap xpm\nimage/x-xwindowdump xwd\nmessage/rfc822 eml\nmodel/iges igs iges\nmodel/mesh msh mesh silo\nmodel/vrml wrl vrml\nmodel/x3d+vrml x3dv\nmodel/x3d+xml x3d\nmodel/x3d+binary x3db\ntext/cache-manifest manifest\ntext/calendar ics icz\ntext/css css\ntext/csv csv\ntext/h323 323\ntext/html html htm shtml\ntext/iuls uls\ntext/mathml mml\ntext/plain asc txt text pot brf\ntext/richtext rtx\ntext/scriptlet sct wsc\ntext/texmacs tm\ntext/tab-separated-values tsv\ntext/vnd.sun.j2me.app-descriptor jad\ntext/vnd.wap.wml wml\ntext/vnd.wap.wmlscript wmls\ntext/x-bibtex bib\ntext/x-boo boo\ntext/x-c++hdr h++ hpp hxx hh\ntext/x-c++src c++ cpp cxx cc\ntext/x-chdr h\ntext/x-component htc\ntext/x-csh csh\ntext/x-csrc c\ntext/x-dsrc d\ntext/x-diff diff patch\ntext/x-haskell hs\ntext/x-java java\ntext/x-literate-haskell lhs\ntext/x-moc moc\ntext/x-pascal p pas\ntext/x-pcs-gcd gcd\ntext/x-perl pl pm\ntext/x-python py\ntext/x-scala scala\ntext/x-setext etx\ntext/x-sfv sfv\ntext/x-sh sh\ntext/x-tcl tcl tk\ntext/x-tex tex ltx sty cls\ntext/x-vcalendar vcs\ntext/x-vcard vcf\nvideo/3gpp 3gp\nvideo/annodex axv\nvideo/dl dl\nvideo/dv dif dv\nvideo/fli fli\nvideo/gl gl\nvideo/mpeg mpeg mpg mpe\nvideo/MP2T ts\nvideo/mp4 mp4\nvideo/quicktime qt mov\nvideo/ogg ogv\nvideo/webm webm\nvideo/vnd.mpegurl mxu\nvideo/x-flv flv\nvideo/x-la-asf lsf lsx\nvideo/x-mng mng\nvideo/x-ms-asf asf asx\nvideo/x-ms-wm wm\nvideo/x-ms-wmv wmv\nvideo/x-ms-wmx wmx\nvideo/x-ms-wvx wvx\nvideo/x-msvideo avi\nvideo/x-sgi-movie movie\nvideo/x-matroska mpv mkv\nx-conference/x-cooltalk ice\nx-epoc/x-sisx-app sisx\nx-world/x-vrml vrm vrml wrl",b=a.split("\n"),c={};return b.forEach(function(a){var b=a.split(" "),d=b[0],e=b[1].split(" ");e.forEach(function(a){c[a]=d})}),{set:function(a,b){"object"==typeof a?Object.keys(a).forEach(function(b){c[b]=a[b]}):c[a]=b},guess:function(a){return c[a.split(".").pop()]||"aplication/octet-stream"}}}();ZipArchiveReader.prototype.init=function(){{var a,b,c,d,e=this.bytes,f=[],g=[],h=[],i=[],j=e.byteLength-4,k=new DataView(e.buffer,e.byteOffset,e.byteLength),l=this;this.params}if(this.files=h,this.folders=i,this.localFileHeaders=f,this.centralDirHeaders=g,k.getUint32(0,!0)!==zip.LOCAL_FILE_SIGNATURE)throw new Error("zip.unpack: invalid zip file");for(;;){if(k.getUint32(j,!0)===zip.END_SIGNATURE){b=l._getEndCentDirHeader(j);break}if(j--,0===j)throw new Error("zip.unpack: invalid zip file")}for(j=b.startpos,c=0,d=b.direntry;d>c;++c)a=l._getCentralDirHeader(j),g.push(a),j+=a.allsize;for(c=0;d>c;++c)j=g[c].headerpos,a=l._getLocalFileHeader(j),a.crc32=g[c].crc32,a.compsize=g[c].compsize,a.uncompsize=g[c].uncompsize,f.push(a);return this._completeInit()},ZipArchiveReader.prototype._completeInit=function(){var a=this.files,b=this.folders,c=this.params,d=this.localFileHeaders,e=this;return d.forEach(function(c){(47!==c.filename[c.filename.length-1]?a:b).push(c)}),null==c.encoding&&Promise.resolve(d.map(function(a){return a.filename})).then(utils.concatBytes).then(utils.detectEncoding).then(function(a){c.encoding=a}),Promise.all(d.map(function(a){return utils.bytesToString(a.filename,c.encoding).then(function(b){a.filename=b})})).then(function(){return e})},ZipArchiveReader.prototype._getLocalFileHeader=function(a){var b=new DataView(this.buffer,a),c=new Uint8Array(this.buffer,a),d={};return d.signature=b.getUint32(0,!0),d.needver=b.getUint16(4,!0),d.option=b.getUint16(6,!0),d.comptype=b.getUint16(8,!0),d.filetime=b.getUint16(10,!0),d.filedate=b.getUint16(12,!0),d.crc32=b.getUint32(14,!0),d.compsize=b.getUint32(18,!0),d.uncompsize=b.getUint32(22,!0),d.fnamelen=b.getUint16(26,!0),d.extralen=b.getUint16(28,!0),d.headersize=30+d.fnamelen+d.extralen,d.allsize=d.headersize+d.compsize,d.filename=c.subarray(30,30+d.fnamelen),d},ZipArchiveReader.prototype._getCentralDirHeader=function(a){var b=new DataView(this.buffer,a),c={};return c.signature=b.getUint32(0,!0),c.madever=b.getUint16(4,!0),c.needver=b.getUint16(6,!0),c.option=b.getUint16(8,!0),c.comptype=b.getUint16(10,!0),c.filetime=b.getUint16(12,!0),c.filedate=b.getUint16(14,!0),c.crc32=b.getUint32(16,!0),c.compsize=b.getUint32(20,!0),c.uncompsize=b.getUint32(24,!0),c.fnamelen=b.getUint16(28,!0),c.extralen=b.getUint16(30,!0),c.commentlen=b.getUint16(32,!0),c.disknum=b.getUint16(34,!0),c.inattr=b.getUint16(36,!0),c.outattr=b.getUint32(38,!0),c.headerpos=b.getUint32(42,!0),c.allsize=46+c.fnamelen+c.extralen+c.commentlen,c},ZipArchiveReader.prototype._getEndCentDirHeader=function(a){var b=new DataView(this.buffer,a);return{signature:b.getUint32(0,!0),disknum:b.getUint16(4,!0),startdisknum:b.getUint16(6,!0),diskdirentry:b.getUint16(8,!0),direntry:b.getUint16(10,!0),dirsize:b.getUint32(12,!0),startpos:b.getUint32(16,!0),commentlen:b.getUint16(20,!0)}},ZipArchiveReader.prototype.getFileNames=function(){return this.files.map(function(a){return a.filename})},ZipArchiveReader.prototype._getFileIndex=function(a){for(var b=0,c=this.localFileHeaders.length;c>b;++b)if(a===this.localFileHeaders[b].filename)return b;throw new Error("File is not found.")},ZipArchiveReader.prototype._getFileInfo=function(a){var b=this._getFileIndex(a),c=this.centralDirHeaders[b],d=this.localFileHeaders[b];return{offset:c.headerpos+d.headersize,length:d.compsize,isCompressed:d.comptype}},ZipArchiveReader.prototype._decompress=function(a,b){return b?algorithms.inflate(a):a},ZipArchiveReader.prototype._decompressFile=function(a){var b=this._getFileInfo(a);return this._decompress(new Uint8Array(this.buffer,b.offset,b.length),b.isCompressed)},ZipArchiveReader.prototype.readFileAsArrayBuffer=function(a){return new Promise(function(b){b(this._decompressFile(a).buffer)}.bind(this))},ZipArchiveReader.prototype._readFileAs=function(a,b,c){return this.readFileAsBlob(b).then(function(b){return utils.readFileAs.call(null,a,b,c)})},ZipArchiveReader.prototype.readFileAsText=function(a,b){return this._readFileAs("Text",a,b||"UTF-8")},ZipArchiveReader.prototype.readFileAsBinaryString=function(a){return this._readFileAs("BinaryString",a)},ZipArchiveReader.prototype.readFileAsDataURL=function(a){return this._readFileAs("DataURL",a)},ZipArchiveReader.prototype.readFileAsBlob=function(a,b){return new Promise(function(c){c(new Blob([this._decompressFile(a,!1)],{type:b||mimetypes.guess(a)}))}.bind(this))},env.isWorker&&(ZipArchiveReader.prototype.readFileAsArrayBufferSync=function(a){return this._decompressFile(a,!0).buffer},ZipArchiveReader.prototype.readFileAsBlobSync=function(a,b){return new Blob([this._decompressFile(a,!1)],{type:b||mimetypes.guess(a)})},ZipArchiveReader.prototype.readFileAsTextSync=function(a,b){return(new FileReaderSync).readAsText(this.readFileAsBlobSync(a),b||"UTF-8")},ZipArchiveReader.prototype.readFileAsBinaryStringSync=function(a){return(new FileReaderSync).readAsBinaryString(this.readFileAsBlobSync(a))},ZipArchiveReader.prototype.readFileAsDataURLSync=function(a){return(new FileReaderSync).readAsDataURL(this.readFileAsBlobSync(a))},exposeProperty("readFileAsArrayBufferSync",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsArrayBufferSync),exposeProperty("readFileAsBlobSync",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsBlobSync),exposeProperty("readFileAsTextSync",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsTextSync),exposeProperty("readFileAsBinaryStringSync",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsBinaryStringSync),exposeProperty("readFileAsDataURLSync",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsDataURLSync)),exposeProperty("getFileNames",ZipArchiveReader,ZipArchiveReader.prototype.getFileNames),exposeProperty("readFileAsArrayBuffer",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsArrayBuffer),exposeProperty("readFileAsText",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsText),exposeProperty("readFileAsBinaryString",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsBinaryString),exposeProperty("readFileAsDataURL",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsDataURL),exposeProperty("readFileAsBlob",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsBlob),ZipArchiveReaderBlob.prototype=Object.create(ZipArchiveReader.prototype),ZipArchiveReaderBlob.prototype.constructor=ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.init=function(){function a(a,b){return utils.readFileAsArrayBuffer(c.slice(a,b))}var b,c=this.blob,d=(this.params,[]),e=[],f=[],g=[];return this.files=f,this.folders=g,this.localFileHeaders=e,this.centralDirHeaders=d,function(){return a(0,4).then(function(a){if(new DataView(a).getUint32(0,!0)===zip.LOCAL_FILE_SIGNATURE)return Math.max(0,c.size-32768);throw new Error("zip.unpack: invalid zip file.")})}().then(function h(b){return a(b,Math.min(c.size,b+32768)).then(function(a){var c,d=new DataView(a);for(c=a.byteLength-4;c--;)if(d.getUint32(c,!0)===zip.END_SIGNATURE)return b+c;if(b)return h(Math.max(b-32768+3,0));throw new Error("zip.unpack: invalid zip file.")})}).then(function(d){return a(d,c.size).then(function(a){return b=ZipArchiveReader.prototype._getEndCentDirHeader.call({buffer:a},0),d})}).then(function(c){return a(b.startpos,c).then(function(a){var c,e,f,g=0,h={buffer:a};for(c=0,e=b.direntry;e>c;++c)f=ZipArchiveReader.prototype._getCentralDirHeader.call(h,g),d.push(f),g+=f.allsize})}).then(function i(b){if(b!==d.length){var c=d[b].headerpos;return a(c+26,c+30).then(function(b){var d=new DataView(b),e=d.getUint16(0,!0),f=d.getUint16(2,!0);return a(c,c+30+e+f)}).then(function(a){var c=ZipArchiveReader.prototype._getLocalFileHeader.call({buffer:a},0);return c.crc32=d[b].crc32,c.compsize=d[b].compsize,c.uncompsize=d[b].uncompsize,e.push(c),i(b+1)})}}.bind(null,0)).then(this._completeInit.bind(this))},ZipArchiveReaderBlob.prototype.readFileAsArrayBuffer=function(a){return this._readFileAs("ArrayBuffer",a)},ZipArchiveReaderBlob.prototype.readFileAsBlob=function(a,b){b=b||mimetypes.guess(a);var c=this._getFileInfo(a),d=this.blob.slice(c.offset,c.offset+c.length,{type:b}); -return c.isCompressed?utils.readFileAsArrayBuffer(d).then(function(a){return new Blob([algorithms.inflate(new Uint8Array(a))],{type:b})}):Promise.resolve(d)},env.isWorker&&(ZipArchiveReaderBlob.prototype._decompressFile=function(a,b){var c=this._getFileInfo(a),d=this.blob.slice(c.offset,c.offset+c.length),e=new Uint8Array((new FileReaderSync).readAsArrayBuffer(d));return this._decompress(e,c.isCompressed,b)},ZipArchiveReaderBlob.prototype.readFileAsArrayBufferSync=function(a){return this._decompressFile(a,!0).buffer},ZipArchiveReaderBlob.prototype.readFileAsBlobSync=function(a,b){return new Blob([this._decompressFile(a,!1)],{type:b||mimetypes.guess(a)})},exposeProperty("readFileAsArrayBufferSync",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsArrayBufferSync),exposeProperty("readFileAsBlobSync",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsBlobSync),exposeProperty("readFileAsTextSync",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsTextSync),exposeProperty("readFileAsBinaryStringSync",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsBinaryStringSync),exposeProperty("readFileAsDataURLSync",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsDataURLSync)),exposeProperty("readFileAsArrayBuffer",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsArrayBuffer),exposeProperty("readFileAsText",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsText),exposeProperty("readFileAsBinaryString",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsBinaryString),exposeProperty("readFileAsDataURL",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsDataURL),exposeProperty("readFileAsBlob",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsBlob),exposeProperty("readFileAsTextSync",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsTextSync),exposeProperty("readFileAsBinaryStringSync",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsBinaryStringSync),exposeProperty("readFileAsDataURLSync",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsDataURLSync),zip.unpack=function(){var a=utils.getParams(arguments,["buffer","encoding","chunkSize"]);return new(a.buffer instanceof Blob?ZipArchiveReaderBlob:ZipArchiveReader)(a).init()},expose("jz.zip.unpack",zip.unpack);}).call(this); \ No newline at end of file +function expose(a,b){var c=a.split("."),d=c.pop(),e=global;c.forEach(function(a){e[a]=e[a]||{},e=e[a]}),e[d]=b}function exposeProperty(a,b,c){b.prototype[a]=c}function ZipArchiveWriter(){var a=utils.getParams(arguments,["shareMemory","chunkSize"]);this.shareMemory=a.shareMemory,this.chunkSize=a.chunkSize,this.dirs={},this.centralDirHeaders=[],this.offset=0,this.date=new Date,this.listners={}}function createLocalFileHeader(a,b,c){var d=new DataView(new ArrayBuffer(30+a.length)),e=new Uint8Array(d.buffer),f=0;return d.setUint32(f,zip.LOCAL_FILE_SIGNATURE,!0),f+=4,d.setUint16(f,20,!0),f+=2,d.setUint16(f,8),f+=2,d.setUint16(f,c?8:0,!0),f+=2,d.setUint16(f,createDosFileTime(b),!0),f+=2,d.setUint16(f,createDosFileDate(b),!0),f+=2,f+=12,d.setUint16(f,a.length,!0),f+=2,f+=2,e.set(a,f),e}function createCentralDirHeader(a,b,c,d,e,f,g){var h=new DataView(new ArrayBuffer(46+a.length)),i=new Uint8Array(h.buffer),j=0;return h.setUint32(j,zip.CENTRAL_DIR_SIGNATURE,!0),j+=4,h.setUint16(j,20,!0),j+=2,h.setUint16(j,20,!0),j+=2,h.setUint16(j,8),j+=2,h.setUint16(j,c?8:0,!0),j+=2,h.setUint16(j,createDosFileTime(b),!0),j+=2,h.setUint16(j,createDosFileDate(b),!0),j+=2,h.setUint32(j,g,!0),j+=4,h.setUint32(j,f,!0),j+=4,h.setUint32(j,e,!0),j+=4,h.setUint16(j,a.length,!0),j+=2,j+=12,h.setUint32(j,d,!0),j+=4,i.set(a,j),i}function createEndCentDirHeader(a,b,c){var d=new DataView(new ArrayBuffer(22));return d.setUint32(0,zip.END_SIGNATURE,!0),d.setUint16(4,0,!0),d.setUint16(6,0,!0),d.setUint16(8,a,!0),d.setUint16(10,a,!0),d.setUint32(12,b,!0),d.setUint32(16,c,!0),d.setUint16(20,0,!0),new Uint8Array(d.buffer)}function createDosFileDate(a){return a.getFullYear()-1980<<9|a.getMonth()+1<<5|a.getDay()}function createDosFileTime(a){return a.getHours()<<11|a.getMinutes()<<5|a.getSeconds()>>1}function ZipArchiveReader(a){this.bytes=utils.toBytes(a.buffer),this.buffer=this.bytes.buffer,this.params=a}function ZipArchiveReaderBlob(a){this.blob=a.buffer,this.params=a}var utils={},algorithms={},gz={},zip={},env={},zpipe={},stream={algorithms:{},zlib:{},gz:{},zip:{}},global=this;zip.LOCAL_FILE_SIGNATURE=67324752,zip.CENTRAL_DIR_SIGNATURE=33639248,zip.END_SIGNATURE=101010256,env.isWorker="function"==typeof importScripts,expose("jz.algos",algorithms),expose("jz.stream.algos",stream.algorithms),utils.toArray=function(a){return Array.prototype.slice.call(a)},utils.getParams=function(a,b){if("[object Object]"===Object.prototype.toString.call(a[0]))return a[0];var c={};return b.forEach(function(b,d){c[b]=a[d]}),c},utils.toBytes=function(a){switch(Object.prototype.toString.call(a)){case"[object String]":return utils.stringToBytes(a);case"[object Array]":case"[object ArrayBuffer]":return new Uint8Array(a);case"[object Uint8Array]":return a;case"[object Int8Array]":case"[object Uint8ClampedArray]":case"[object CanvasPixelArray]":return new Uint8Array(a.buffer,a.byteOffset,a.byteLength);default:throw new Error("jz.utils.toBytes: not supported type.")}},expose("jz.utils.toBytes",utils.toBytes),utils.readFileAs=function(a,b,c){var d;return d=env.isWorker?function(d){var e=new FileReaderSync;d(e["readAs"+a].call(e,b,c))}:function(d,e){var f=new FileReader;f.onload=function(){d(f.result)},f.onerror=e,f["readAs"+a].call(f,b,c)},new Promise(d)},utils.readFileAsText=function(a,b){return utils.readFileAs("Text",a,b||"UTF-8")},utils.readFileAsArrayBuffer=utils.readFileAs.bind(null,"ArrayBuffer"),utils.readFileAsDataURL=utils.readFileAs.bind(null,"DataURL"),utils.readFileAsBinaryString=utils.readFileAs.bind(null,"BinaryString"),expose("jz.utils.readFileAsArrayBuffer",utils.readFileAsArrayBuffer),expose("jz.utils.readFileAsText",utils.readFileAsText),expose("jz.utils.readFileAsDataURL",utils.readFileAsDataURL),expose("jz.utils.readFileAsBinaryString",utils.readFileAsBinaryString),utils.stringToBytes=function(a){var b,c,d,e=a.length,f=-1,g=32,h=new Uint8Array(g);for(b=0;e>b;++b)c=a.charCodeAt(b),127>=c?h[++f]=c:2047>=c?(h[++f]=192|c>>>6,h[++f]=128|63&c):65535>=c?(h[++f]=224|c>>>12,h[++f]=128|c>>>6&63,h[++f]=128|63&c):(h[++f]=240|c>>>18,h[++f]=128|c>>>12&63,h[++f]=128|c>>>6&63,h[++f]=128|63&c),4>=g-f&&(d=h,g*=2,h=new Uint8Array(g),h.set(d));return h.subarray(0,++f)},utils.bytesToString=function(a,b){return utils.readFileAsText(new Blob([utils.toBytes(a)]),b)},expose("jz.utils.bytesToString",utils.bytesToString),utils.bytesToStringSync=null,env.isWorker&&(utils.bytesToStringSync=function(a,b){return(new FileReaderSync).readAsText(new Blob([utils.toBytes(a)]),b||"UTF-8")},expose("jz.utils.bytesToStringSync",utils.bytesToStringSync)),utils.detectEncoding=function(a){a=utils.toBytes(a);for(var b=0,c=a.length;c>b;++b)if(!(a[b]<128))if(192===(224&a[b])){if(128===(192&a[++b]))continue}else if(224===(240&a[b])){if(128===(192&a[++b])&&128===(192&a[++b]))continue}else{if(240!==(248&a[b]))return"Shift_JIS";if(128===(192&a[++b])&&128===(192&a[++b])&&128===(192&a[++b]))continue}return"UTF-8"},expose("jz.utils.detectEncoding",utils.detectEncoding),Promise.prototype.spread=function(a,b){return Promise.prototype.then.call(this,Function.prototype.apply.bind(a,null),b)},utils.load=function(a){return a=Array.isArray(a)?a:utils.toArray(arguments),Promise.all(a.map(function(a){return new Promise(function(b,c){var d=new XMLHttpRequest;d.open("GET",a),d.responseType="arraybuffer",d.onloadend=function(){var e=d.status;200===e||206===e||0===e?b(new Uint8Array(d.response)):c(new Error("Load Error: "+e+" "+a))},d.onerror=c,d.send()})}))},expose("jz.utils.load",utils.load),utils.concatBytes=function(a){var b,c,d,a=Array.isArray(a)?a:utils.toArray(arguments),e=0,f=0;for(b=0,c=a.length;c>b;++b)e+=a[b].length;for(d=new Uint8Array(e),b=0;c>b;++b)d.set(a[b],f),f+=a[b].length;return d},expose("jz.utils.concatBytes",utils.concatBytes),algorithms.adler32=function(a){for(var b,a=utils.toBytes(a),c=1,d=0,e=0,f=65521,g=a.length;g>0;){b=g>5550?5550:g,g-=b;do c+=a[e++],d+=c;while(--b);c%=f,d%=f}return(d<<16|c)>>>0},expose("jz.algorithms.adler32",algorithms.adler32),algorithms.crc32=function(){var a=function(){var a,b,c,d=3988292384,e=new Uint32Array(256);for(b=0;256>b;++b){for(a=b,c=0;8>c;++c)a=1&a?a>>>1^d:a>>>1;e[b]=a>>>0}return e}();return function(b,c){for(var d=utils.getParams(arguments,["buffer","crc"]),e=utils.toBytes(d.buffer),c=null==d.crc?4294967295:~d.crc>>>0,f=0,g=e.length,h=a;g>f;++f)c=c>>>8^h[e[f]^255&c];return~c>>>0}}(),expose("jz.algorithms.crc32",algorithms.crc32),algorithms.deflate=function(){var a=utils.getParams(arguments,["buffer","level","chunkSize"]);return zlib.rawDeflate(utils.toBytes(a.buffer),a.level,a.chunkSize)},expose("jz.algorithms.deflate",algorithms.deflate),algorithms.inflate=function(){var a=utils.getParams(arguments,["buffer","chunkSize"]);return zlib.rawInflate(utils.toBytes(a.buffer),a.chunkSize)},expose("jz.algorithms.inflate",algorithms.inflate),ZipArchiveWriter.prototype.write=function(a,b,c){var d=this;return a.split("/").reduce(function(a,b){return d.writeDir(a+"/"),a+"/"+b}),this.writeFile(a,b,c),this},ZipArchiveWriter.prototype.writeDir=function(a){var b;return this.dirs[a]||(this.dirs[a]=!0,a=utils.toBytes(a),b=createLocalFileHeader(a,this.date,!1),this.centralDirHeaders.push(createCentralDirHeader(a,this.date,!1,this.offset,0,0,0)),this.trigger("data",b),this.offset+=b.length),this},ZipArchiveWriter.prototype.writeFile=function(a,b,c){a=utils.toBytes(a);var d=this.offset,e=createLocalFileHeader(a,this.date,c),f=0,g=this;return this.trigger("data",e),c?stream.algorithms.deflate({buffer:b,level:c,streamFn:function(a){f+=a.length,g.trigger("data",a)},shareMemory:this.shareMemory,chunkSize:this.chunkSize}):(f=b.length,this.trigger("data",b)),this.centralDirHeaders.push(createCentralDirHeader(a,this.date,c,d,b.length,f,algorithms.crc32(b))),this.offset+=e.length+f,this},ZipArchiveWriter.prototype.writeEnd=function(){var a=0,b=this;this.centralDirHeaders.forEach(function(c){a+=c.length,b.trigger("data",c)}),this.trigger("data",createEndCentDirHeader(this.centralDirHeaders.length,a,this.offset)),this.trigger("end",null)},ZipArchiveWriter.prototype.on=function(a,b){return this.listners[a]||(this.listners[a]=[]),this.listners[a].push(b),this},ZipArchiveWriter.prototype.trigger=function(a,b){this.listners[a]&&this.listners[a].forEach(function(a){a(b)})},expose("jz.zip.ZipArchiveWriter",ZipArchiveWriter),exposeProperty("write",ZipArchiveWriter,ZipArchiveWriter.prototype.write),exposeProperty("writeDir",ZipArchiveWriter,ZipArchiveWriter.prototype.writeDir),exposeProperty("writeFile",ZipArchiveWriter,ZipArchiveWriter.prototype.writeFile),exposeProperty("writeEnd",ZipArchiveWriter,ZipArchiveWriter.prototype.writeEnd),exposeProperty("on",ZipArchiveWriter,ZipArchiveWriter.prototype.on),stream.algorithms.deflate=function(){var a=utils.getParams(arguments,["buffer","streamFn","level","shareMemory","chunkSize"]);a.input=utils.toBytes(a.buffer),zlib.stream.rawDeflate(a)},expose("jz.stream.algorithms.deflate",stream.algorithms.deflate),stream.algorithms.inflate=function(){var a=utils.getParams(arguments,["buffer","streamFn","shareMemory","chunkSize"]);a.input=utils.toBytes(a.buffer),zlib.stream.rawInflate(a)},expose("jz.stream.algorithms.inflate",stream.algorithms.inflate),stream.zlib.compress=function(){var a=utils.getParams(arguments,["buffer","streamFn","level","shareMemory","chunkSize"]);a.input=utils.toBytes(a.buffer),zlib.stream.deflate(a)},expose("jz.stream.zlib.compress",stream.zlib.compress),stream.zlib.decompress=function(){var a=utils.getParams(arguments,["buffer","streamFn","shareMemory","chunkSize"]);a.input=utils.toBytes(a.buffer),zlib.stream.inflate(a)},expose("jz.stream.zlib.decompress",stream.zlib.decompress),stream.gz.compress=function(a,b,c,d,e,f,g){var h,i,j,k=utils.getParams(arguments,["buffer","streamFn","level","shareMemory","chunkSize","fname","fcomment"]),l=utils.toBytes(k.buffer),b=(k.level,k.streamFn),d=k.shareMemory,e=k.chunkSize,f=k.fname&&utils.toBytes(k.fname),g=k.fcomment&&utils.toBytes(k.fcomment),m=0,n=10,o=0,p=Date.now();f&&(n+=f.length+1,m|=8),g&&(n+=g.length+1,m|=16),h=new Uint8Array(n),j=new DataView(h.buffer),j.setUint32(o,529205248|m),o+=4,j.setUint32(o,p,!0),o+=4,j.setUint16(o,1279),o+=2,f&&(h.set(f,o),o+=f.length,h[o++]=0),g&&(h.set(g,o),o+=g.length,h[o++]=0),b(h),stream.algorithms.deflate({buffer:l,streamFn:b,shareMemory:d,chunkSize:e}),i=new Uint8Array(8),j=new DataView(i.buffer),j.setUint32(0,algorithms.crc32(l),!0),j.setUint32(4,l.length,!0),b(i)},expose("jz.stream.gz.compress",stream.gz.compress),stream.gz.decompress=function(a,b,c,d){var e,f,g=utils.getParams(arguments,["buffer","streamFn","shareMemory","chunkSize"]),h=utils.toBytes(g.buffer),b=g.streamFn,c=g.shareMemory,d=g.chunkSize,i=10,j=new DataView(h.buffer,h.byteOffset,h.byteLength);if(8075!==j.getUint16(0))throw new Error("jz.gz.decompress: invalid gzip file.");if(8!==h[2])throw new Error("jz.gz.decompress: not deflate.");if(e=h[3],4&e&&(i+=j.getUint16(i,!0)+2),8&e)for(;h[i++];);if(16&e)for(;h[i++];);if(2&e&&(i+=2),stream.algorithms.inflate({buffer:h.subarray(i,h.length-8),streamFn:function(a){f=algorithms.crc32(a,f),b(a)},shareMemory:c,chunkSize:d}),f!==j.getUint32(h.length-8,!0))throw new Error("js.stream.gz.decompress: file is broken.")},expose("jz.stream.gz.decompress",stream.gz.decompress),stream.zip.pack=function(){function a(b,c,d){var f,g=d.children||d.dir||d.folder;if(b="number"==typeof d.level?d.level:b,g)c+=d.name+(/.+\/$/.test(d.name)?"":"/"),e.writeDir(c),g.forEach(a.bind(null,b,c));else{if(null!=d.buffer&&(f=d.buffer),null!=d.str&&(f=d.str),null==f)throw new Error("jz.zip.pack: This type is not supported.");c+=d.name,e.writeFile(c,utils.toBytes(f),b)}}function b(a){var c=a.children||a.dir||a.folder;c?c.forEach(b):a.url&&d.push(utils.load(a.url).then(function(b){a.buffer=b[0],a.url=null}))}var c=utils.getParams(arguments,["files","streamFn","level","shareMemory","chunkSize"]),d=[],e=new ZipArchiveWriter(c);return e.on("data",c.streamFn),c.files.forEach(b),Promise.all(d).then(function(){c.files.forEach(a.bind(null,c.level,"")),e.writeEnd()})},expose("jz.stream.zip.pack",stream.zip.pack),expose("jz.zlib.compress",function(){var a=utils.getParams(arguments,["buffer","level","chunkSize"]);return zlib.deflate(utils.toBytes(a.buffer),a.level,a.chunkSize)}),expose("jz.zlib.decompress",function(){var a=utils.getParams(arguments,["buffer","chunkSize"]);return zlib.inflate(utils.toBytes(a.buffer),a.chunkSize)}),gz.compress=function(){var a=utils.getParams(arguments,["buffer","level","chunkSize","fname","fcomment"]),b=[];return stream.gz.compress({buffer:a.buffer,level:a.level,chunkSize:a.chunkSize,fname:a.fname,fcomment:a.fcomments,streamFn:function(a){b.push(a)}}),utils.concatBytes(b)},expose("jz.gz.compress",gz.compress),gz.decompress=function(){var a=utils.getParams(arguments,["buffer","chunkSize"]),b=[];return stream.gz.decompress({buffer:a.buffer,streamFn:function(a){b.push(a)},shareMemory:!1,chunkSize:a.chunkSize}),utils.concatBytes(b)},expose("jz.gz.decompress",gz.decompress),zip.pack=function(){var a=utils.getParams(arguments,["files","level","chunkSize"]),b=[];return stream.zip.pack({files:a.files,shareMemory:!1,level:a.level,chunkSize:a.chunkSize,streamFn:function(a){b.push(a)}}).then(function(){return utils.concatBytes(b)})},expose("jz.zip.pack",zip.pack);var mimetypes=function(){var a="application/epub+zip epub\napplication/x-gzip gz\napplication/andrew-inset ez\napplication/annodex anx\napplication/atom+xml atom\napplication/atomcat+xml atomcat\napplication/atomserv+xml atomsrv\napplication/bbolin lin\napplication/cap cap pcap\napplication/cu-seeme cu\napplication/davmount+xml davmount\napplication/dsptype tsp\napplication/ecmascript es\napplication/futuresplash spl\napplication/hta hta\napplication/java-archive jar\napplication/java-serialized-object ser\napplication/java-vm class\napplication/javascript js\napplication/json json\napplication/m3g m3g\napplication/mac-binhex40 hqx\napplication/mac-compactpro cpt\napplication/mathematica nb nbp\napplication/msaccess mdb\napplication/msword doc dot\napplication/mxf mxf\napplication/octet-stream bin\napplication/oda oda\napplication/ogg ogx\napplication/onenote one onetoc2 onetmp onepkg\napplication/pdf pdf\napplication/pgp-keys key\napplication/pgp-signature pgp\napplication/pics-rules prf\napplication/postscript ps ai eps epsi epsf eps2 eps3\napplication/rar rar\napplication/rdf+xml rdf\napplication/rss+xml rss\napplication/rtf rtf\napplication/sla stl\napplication/smil smi smil\napplication/xhtml+xml xhtml xht\napplication/xml xml xsl xsd\napplication/xspf+xml xspf\napplication/zip zip\napplication/vnd.android.package-archive apk\napplication/vnd.cinderella cdy\napplication/vnd.google-earth.kml+xml kml\napplication/vnd.google-earth.kmz kmz\napplication/vnd.mozilla.xul+xml xul\napplication/vnd.ms-excel xls xlb xlt\napplication/vnd.ms-excel.addin.macroEnabled.12 xlam\napplication/vnd.ms-excel.sheet.binary.macroEnabled.12 xlsb\napplication/vnd.ms-excel.sheet.macroEnabled.12 xlsm\napplication/vnd.ms-excel.template.macroEnabled.12 xltm\napplication/vnd.ms-officetheme thmx\napplication/vnd.ms-pki.seccat cat\napplication/vnd.ms-powerpoint ppt pps\napplication/vnd.ms-powerpoint.addin.macroEnabled.12 ppam\napplication/vnd.ms-powerpoint.presentation.macroEnabled.12 pptm\napplication/vnd.ms-powerpoint.slide.macroEnabled.12 sldm\napplication/vnd.ms-powerpoint.slideshow.macroEnabled.12 ppsm\napplication/vnd.ms-powerpoint.template.macroEnabled.12 potm\napplication/vnd.ms-word.document.macroEnabled.12 docm\napplication/vnd.ms-word.template.macroEnabled.12 dotm\napplication/vnd.oasis.opendocument.chart odc\napplication/vnd.oasis.opendocument.database odb\napplication/vnd.oasis.opendocument.formula odf\napplication/vnd.oasis.opendocument.graphics odg\napplication/vnd.oasis.opendocument.graphics-template otg\napplication/vnd.oasis.opendocument.image odi\napplication/vnd.oasis.opendocument.presentation odp\napplication/vnd.oasis.opendocument.presentation-template otp\napplication/vnd.oasis.opendocument.spreadsheet ods\napplication/vnd.oasis.opendocument.spreadsheet-template ots\napplication/vnd.oasis.opendocument.text odt\napplication/vnd.oasis.opendocument.text-master odm\napplication/vnd.oasis.opendocument.text-template ott\napplication/vnd.oasis.opendocument.text-web oth\napplication/vnd.openxmlformats-officedocument.presentationml.presentation pptx\napplication/vnd.openxmlformats-officedocument.presentationml.slide sldx\napplication/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx\napplication/vnd.openxmlformats-officedocument.presentationml.template potx\napplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx\napplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx\napplication/vnd.openxmlformats-officedocument.spreadsheetml.template xltx\napplication/vnd.openxmlformats-officedocument.spreadsheetml.template xltx\napplication/vnd.openxmlformats-officedocument.wordprocessingml.document docx\napplication/vnd.openxmlformats-officedocument.wordprocessingml.template dotx\napplication/vnd.rim.cod cod\napplication/vnd.smaf mmf\napplication/vnd.stardivision.calc sdc\napplication/vnd.stardivision.chart sds\napplication/vnd.stardivision.draw sda\napplication/vnd.stardivision.impress sdd\napplication/vnd.stardivision.math sdf\napplication/vnd.stardivision.writer sdw\napplication/vnd.stardivision.writer-global sgl\napplication/vnd.sun.xml.calc sxc\napplication/vnd.sun.xml.calc.template stc\napplication/vnd.sun.xml.draw sxd\napplication/vnd.sun.xml.draw.template std\napplication/vnd.sun.xml.impress sxi\napplication/vnd.sun.xml.impress.template sti\napplication/vnd.sun.xml.math sxm\napplication/vnd.sun.xml.writer sxw\napplication/vnd.sun.xml.writer.global sxg\napplication/vnd.sun.xml.writer.template stw\napplication/vnd.symbian.install sis\napplication/vnd.visio vsd\napplication/vnd.wap.wbxml wbxml\napplication/vnd.wap.wmlc wmlc\napplication/vnd.wap.wmlscriptc wmlsc\napplication/vnd.wordperfect wpd\napplication/vnd.wordperfect5.1 wp5\napplication/x-123 wk\napplication/x-7z-compressed 7z\napplication/x-abiword abw\napplication/x-apple-diskimage dmg\napplication/x-bcpio bcpio\napplication/x-bittorrent torrent\napplication/x-cab cab\napplication/x-cbr cbr\napplication/x-cbz cbz\napplication/x-cdf cdf cda\napplication/x-cdlink vcd\napplication/x-chess-pgn pgn\napplication/x-comsol mph\napplication/x-cpio cpio\napplication/x-csh csh\napplication/x-debian-package deb udeb\napplication/x-director dcr dir dxr\napplication/x-dms dms\napplication/x-doom wad\napplication/x-dvi dvi\napplication/x-font pfa pfb gsf pcf pcf.Z\napplication/x-freemind mm\napplication/x-futuresplash spl\napplication/x-ganttproject gan\napplication/x-gnumeric gnumeric\napplication/x-go-sgf sgf\napplication/x-graphing-calculator gcf\napplication/x-gtar gtar\napplication/x-gtar-compressed tgz taz\napplication/x-hdf hdf\napplication/x-httpd-eruby rhtml\napplication/x-httpd-php phtml pht php\napplication/x-httpd-php-source phps\napplication/x-httpd-php3 php3\napplication/x-httpd-php3-preprocessed php3p\napplication/x-httpd-php4 php4\napplication/x-httpd-php5 php5\napplication/x-ica ica\napplication/x-info info\napplication/x-internet-signup ins isp\napplication/x-iphone iii\napplication/x-iso9660-image iso\napplication/x-jam jam\napplication/x-java-jnlp-file jnlp\napplication/x-jmol jmz\napplication/x-kchart chrt\napplication/x-killustrator kil\napplication/x-koan skp skd skt skm\napplication/x-kpresenter kpr kpt\napplication/x-kspread ksp\napplication/x-kword kwd kwt\napplication/x-latex latex\napplication/x-lha lha\napplication/x-lyx lyx\napplication/x-lzh lzh\napplication/x-lzx lzx\napplication/x-maker frm maker frame fm fb book fbdoc\napplication/x-mif mif\napplication/x-mpegURL m3u8\napplication/x-ms-wmd wmd\napplication/x-ms-wmz wmz\napplication/x-msdos-program com exe bat dll\napplication/x-msi msi\napplication/x-netcdf nc\napplication/x-ns-proxy-autoconfig pac dat\napplication/x-nwc nwc\napplication/x-object o\napplication/x-oz-application oza\napplication/x-pkcs7-certreqresp p7r\napplication/x-pkcs7-crl crl\napplication/x-python-code pyc pyo\napplication/x-qgis qgs shp shx\napplication/x-quicktimeplayer qtl\napplication/x-rdp rdp\napplication/x-redhat-package-manager rpm\napplication/x-ruby rb\napplication/x-scilab sci sce\napplication/x-sh sh\napplication/x-shar shar\napplication/x-shockwave-flash swf swfl\napplication/x-silverlight scr\napplication/x-sql sql\napplication/x-stuffit sit sitx\napplication/x-sv4cpio sv4cpio\napplication/x-sv4crc sv4crc\napplication/x-tar tar\napplication/x-tcl tcl\napplication/x-tex-gf gf\napplication/x-tex-pk pk\napplication/x-texinfo texinfo texi\napplication/x-trash ~ % bak old sik\napplication/x-troff t tr roff\napplication/x-troff-man man\napplication/x-troff-me me\napplication/x-troff-ms ms\napplication/x-ustar ustar\napplication/x-wais-source src\napplication/x-wingz wz\napplication/x-x509-ca-cert crt\napplication/x-xcf xcf\napplication/x-xfig fig\napplication/x-xpinstall xpi\naudio/amr amr\naudio/amr-wb awb\naudio/amr amr\naudio/amr-wb awb\naudio/annodex axa\naudio/basic au snd\naudio/csound csd orc sco\naudio/flac flac\naudio/midi mid midi kar\naudio/mpeg mpga mpega mp2 mp3 m4a\naudio/mpegurl m3u\naudio/ogg oga ogg spx\naudio/prs.sid sid\naudio/x-aiff aif aiff aifc\naudio/x-gsm gsm\naudio/x-mpegurl m3u\naudio/x-ms-wma wma\naudio/x-ms-wax wax\naudio/x-pn-realaudio ra rm ram\naudio/x-realaudio ra\naudio/x-scpls pls\naudio/x-sd2 sd2\naudio/x-wav wav\nchemical/x-alchemy alc\nchemical/x-cache cac cache\nchemical/x-cache-csf csf\nchemical/x-cactvs-binary cbin cascii ctab\nchemical/x-cdx cdx\nchemical/x-cerius cer\nchemical/x-chem3d c3d\nchemical/x-chemdraw chm\nchemical/x-cif cif\nchemical/x-cmdf cmdf\nchemical/x-cml cml\nchemical/x-compass cpa\nchemical/x-crossfire bsd\nchemical/x-csml csml csm\nchemical/x-ctx ctx\nchemical/x-cxf cxf cef\nchemical/x-embl-dl-nucleotide emb embl\nchemical/x-galactic-spc spc\nchemical/x-gamess-input inp gam gamin\nchemical/x-gaussian-checkpoint fch fchk\nchemical/x-gaussian-cube cub\nchemical/x-gaussian-input gau gjc gjf\nchemical/x-gaussian-log gal\nchemical/x-gcg8-sequence gcg\nchemical/x-genbank gen\nchemical/x-hin hin\nchemical/x-isostar istr ist\nchemical/x-jcamp-dx jdx dx\nchemical/x-kinemage kin\nchemical/x-macmolecule mcm\nchemical/x-macromodel-input mmd mmod\nchemical/x-mdl-molfile mol\nchemical/x-mdl-rdfile rd\nchemical/x-mdl-rxnfile rxn\nchemical/x-mdl-sdfile sd sdf\nchemical/x-mdl-tgf tgf\nchemical/x-mmcif mcif\nchemical/x-mol2 mol2\nchemical/x-molconn-Z b\nchemical/x-mopac-graph gpt\nchemical/x-mopac-input mop mopcrt mpc zmt\nchemical/x-mopac-out moo\nchemical/x-mopac-vib mvb\nchemical/x-ncbi-asn1 asn\nchemical/x-ncbi-asn1-ascii prt ent\nchemical/x-ncbi-asn1-binary val aso\nchemical/x-ncbi-asn1-spec asn\nchemical/x-pdb pdb ent\nchemical/x-rosdal ros\nchemical/x-swissprot sw\nchemical/x-vamas-iso14976 vms\nchemical/x-vmd vmd\nchemical/x-xtel xtel\nchemical/x-xyz xyz\nimage/gif gif\nimage/ief ief\nimage/jpeg jpeg jpg jpe\nimage/pcx pcx\nimage/png png\nimage/svg+xml svg svgz\nimage/tiff tiff tif\nimage/vnd.djvu djvu djv\nimage/vnd.wap.wbmp wbmp\nimage/x-canon-cr2 cr2\nimage/x-canon-crw crw\nimage/x-cmu-raster ras\nimage/x-coreldraw cdr\nimage/x-coreldrawpattern pat\nimage/x-coreldrawtemplate cdt\nimage/x-corelphotopaint cpt\nimage/x-epson-erf erf\nimage/x-icon ico\nimage/x-jg art\nimage/x-jng jng\nimage/x-ms-bmp bmp\nimage/x-nikon-nef nef\nimage/x-olympus-orf orf\nimage/x-photoshop psd\nimage/x-portable-anymap pnm\nimage/x-portable-bitmap pbm\nimage/x-portable-graymap pgm\nimage/x-portable-pixmap ppm\nimage/x-rgb rgb\nimage/x-xbitmap xbm\nimage/x-xpixmap xpm\nimage/x-xwindowdump xwd\nmessage/rfc822 eml\nmodel/iges igs iges\nmodel/mesh msh mesh silo\nmodel/vrml wrl vrml\nmodel/x3d+vrml x3dv\nmodel/x3d+xml x3d\nmodel/x3d+binary x3db\ntext/cache-manifest manifest\ntext/calendar ics icz\ntext/css css\ntext/csv csv\ntext/h323 323\ntext/html html htm shtml\ntext/iuls uls\ntext/mathml mml\ntext/plain asc txt text pot brf\ntext/richtext rtx\ntext/scriptlet sct wsc\ntext/texmacs tm\ntext/tab-separated-values tsv\ntext/vnd.sun.j2me.app-descriptor jad\ntext/vnd.wap.wml wml\ntext/vnd.wap.wmlscript wmls\ntext/x-bibtex bib\ntext/x-boo boo\ntext/x-c++hdr h++ hpp hxx hh\ntext/x-c++src c++ cpp cxx cc\ntext/x-chdr h\ntext/x-component htc\ntext/x-csh csh\ntext/x-csrc c\ntext/x-dsrc d\ntext/x-diff diff patch\ntext/x-haskell hs\ntext/x-java java\ntext/x-literate-haskell lhs\ntext/x-moc moc\ntext/x-pascal p pas\ntext/x-pcs-gcd gcd\ntext/x-perl pl pm\ntext/x-python py\ntext/x-scala scala\ntext/x-setext etx\ntext/x-sfv sfv\ntext/x-sh sh\ntext/x-tcl tcl tk\ntext/x-tex tex ltx sty cls\ntext/x-vcalendar vcs\ntext/x-vcard vcf\nvideo/3gpp 3gp\nvideo/annodex axv\nvideo/dl dl\nvideo/dv dif dv\nvideo/fli fli\nvideo/gl gl\nvideo/mpeg mpeg mpg mpe\nvideo/MP2T ts\nvideo/mp4 mp4\nvideo/quicktime qt mov\nvideo/ogg ogv\nvideo/webm webm\nvideo/vnd.mpegurl mxu\nvideo/x-flv flv\nvideo/x-la-asf lsf lsx\nvideo/x-mng mng\nvideo/x-ms-asf asf asx\nvideo/x-ms-wm wm\nvideo/x-ms-wmv wmv\nvideo/x-ms-wmx wmx\nvideo/x-ms-wvx wvx\nvideo/x-msvideo avi\nvideo/x-sgi-movie movie\nvideo/x-matroska mpv mkv\nx-conference/x-cooltalk ice\nx-epoc/x-sisx-app sisx\nx-world/x-vrml vrm vrml wrl",b=a.split("\n"),c={};return b.forEach(function(a){var b=a.split(" "),d=b[0],e=b[1].split(" ");e.forEach(function(a){c[a]=d})}),{set:function(a,b){"object"==typeof a?Object.keys(a).forEach(function(b){c[b]=a[b]}):c[a]=b},guess:function(a){return c[a.split(".").pop()]||"aplication/octet-stream"}}}();ZipArchiveReader.prototype.init=function(){{var a,b,c,d,e=this.bytes,f=[],g=[],h=[],i=[],j=e.byteLength-4,k=new DataView(e.buffer,e.byteOffset,e.byteLength),l=this;this.params}if(this.files=h,this.folders=i,this.localFileHeaders=f,this.centralDirHeaders=g,k.getUint32(0,!0)!==zip.LOCAL_FILE_SIGNATURE)throw new Error("zip.unpack: invalid zip file");for(;;){if(k.getUint32(j,!0)===zip.END_SIGNATURE){b=l._getEndCentDirHeader(j);break}if(j--,0===j)throw new Error("zip.unpack: invalid zip file")}for(j=b.startpos,c=0,d=b.direntry;d>c;++c)a=l._getCentralDirHeader(j),g.push(a),j+=a.allsize;for(c=0;d>c;++c)j=g[c].headerpos,a=l._getLocalFileHeader(j),a.crc32=g[c].crc32,a.compsize=g[c].compsize,a.uncompsize=g[c].uncompsize,f.push(a);return this._completeInit()},ZipArchiveReader.prototype._completeInit=function(){var a=this.files,b=this.folders,c=this.params,d=this.localFileHeaders,e=this;return d.forEach(function(c){(47!==c.filename[c.filename.length-1]?a:b).push(c)}),null==c.encoding&&Promise.resolve(d.map(function(a){return a.filename})).then(utils.concatBytes).then(utils.detectEncoding).then(function(a){c.encoding=a}),Promise.all(d.map(function(a){return utils.bytesToString(a.filename,c.encoding).then(function(b){a.filename=b})})).then(function(){return e})},ZipArchiveReader.prototype._getLocalFileHeader=function(a){var b=new DataView(this.buffer,a),c=new Uint8Array(this.buffer,a),d={};return d.signature=b.getUint32(0,!0),d.needver=b.getUint16(4,!0),d.option=b.getUint16(6,!0),d.comptype=b.getUint16(8,!0),d.filetime=b.getUint16(10,!0),d.filedate=b.getUint16(12,!0),d.crc32=b.getUint32(14,!0),d.compsize=b.getUint32(18,!0),d.uncompsize=b.getUint32(22,!0),d.fnamelen=b.getUint16(26,!0),d.extralen=b.getUint16(28,!0),d.headersize=30+d.fnamelen+d.extralen,d.allsize=d.headersize+d.compsize,d.filename=c.subarray(30,30+d.fnamelen),d},ZipArchiveReader.prototype._getCentralDirHeader=function(a){var b=new DataView(this.buffer,a),c={};return c.signature=b.getUint32(0,!0),c.madever=b.getUint16(4,!0),c.needver=b.getUint16(6,!0),c.option=b.getUint16(8,!0),c.comptype=b.getUint16(10,!0),c.filetime=b.getUint16(12,!0),c.filedate=b.getUint16(14,!0),c.crc32=b.getUint32(16,!0),c.compsize=b.getUint32(20,!0),c.uncompsize=b.getUint32(24,!0),c.fnamelen=b.getUint16(28,!0),c.extralen=b.getUint16(30,!0),c.commentlen=b.getUint16(32,!0),c.disknum=b.getUint16(34,!0),c.inattr=b.getUint16(36,!0),c.outattr=b.getUint32(38,!0),c.headerpos=b.getUint32(42,!0),c.allsize=46+c.fnamelen+c.extralen+c.commentlen,c},ZipArchiveReader.prototype._getEndCentDirHeader=function(a){var b=new DataView(this.buffer,a);return{signature:b.getUint32(0,!0),disknum:b.getUint16(4,!0),startdisknum:b.getUint16(6,!0),diskdirentry:b.getUint16(8,!0),direntry:b.getUint16(10,!0),dirsize:b.getUint32(12,!0),startpos:b.getUint32(16,!0),commentlen:b.getUint16(20,!0)}},ZipArchiveReader.prototype.getFileNames=function(){return this.files.map(function(a){return a.filename})},ZipArchiveReader.prototype._getFileIndex=function(a){for(var b=0,c=this.localFileHeaders.length;c>b;++b)if(a===this.localFileHeaders[b].filename)return b;throw new Error("File is not found.")},ZipArchiveReader.prototype._getFileInfo=function(a){var b=this._getFileIndex(a),c=this.centralDirHeaders[b],d=this.localFileHeaders[b];return{offset:c.headerpos+d.headersize,length:d.compsize,isCompressed:d.comptype}},ZipArchiveReader.prototype._decompress=function(a,b){return b?algorithms.inflate(a):a},ZipArchiveReader.prototype._decompressFile=function(a){var b=this._getFileInfo(a);return this._decompress(new Uint8Array(this.buffer,b.offset,b.length),b.isCompressed)},ZipArchiveReader.prototype.readFileAsArrayBuffer=function(a){return new Promise(function(b){b(this._decompressFile(a).buffer)}.bind(this))},ZipArchiveReader.prototype._readFileAs=function(a,b,c){return this.readFileAsBlob(b).then(function(b){return utils.readFileAs.call(null,a,b,c)})},ZipArchiveReader.prototype.readFileAsText=function(a,b){return this._readFileAs("Text",a,b||"UTF-8")},ZipArchiveReader.prototype.readFileAsBinaryString=function(a){return this._readFileAs("BinaryString",a)},ZipArchiveReader.prototype.readFileAsDataURL=function(a){return this._readFileAs("DataURL",a)},ZipArchiveReader.prototype.readFileAsBlob=function(a,b){return new Promise(function(c){c(new Blob([this._decompressFile(a,!1)],{type:b||mimetypes.guess(a)}))}.bind(this))},env.isWorker&&(ZipArchiveReader.prototype.readFileAsArrayBufferSync=function(a){return this._decompressFile(a,!0).buffer},ZipArchiveReader.prototype.readFileAsBlobSync=function(a,b){return new Blob([this._decompressFile(a,!1)],{type:b||mimetypes.guess(a)})},ZipArchiveReader.prototype.readFileAsTextSync=function(a,b){return(new FileReaderSync).readAsText(this.readFileAsBlobSync(a),b||"UTF-8")},ZipArchiveReader.prototype.readFileAsBinaryStringSync=function(a){return(new FileReaderSync).readAsBinaryString(this.readFileAsBlobSync(a))},ZipArchiveReader.prototype.readFileAsDataURLSync=function(a){return(new FileReaderSync).readAsDataURL(this.readFileAsBlobSync(a))},exposeProperty("readFileAsArrayBufferSync",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsArrayBufferSync),exposeProperty("readFileAsBlobSync",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsBlobSync),exposeProperty("readFileAsTextSync",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsTextSync),exposeProperty("readFileAsBinaryStringSync",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsBinaryStringSync),exposeProperty("readFileAsDataURLSync",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsDataURLSync)),exposeProperty("getFileNames",ZipArchiveReader,ZipArchiveReader.prototype.getFileNames),exposeProperty("readFileAsArrayBuffer",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsArrayBuffer),exposeProperty("readFileAsText",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsText),exposeProperty("readFileAsBinaryString",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsBinaryString),exposeProperty("readFileAsDataURL",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsDataURL),exposeProperty("readFileAsBlob",ZipArchiveReader,ZipArchiveReader.prototype.readFileAsBlob),ZipArchiveReaderBlob.prototype=Object.create(ZipArchiveReader.prototype),ZipArchiveReaderBlob.prototype.constructor=ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.init=function(){function a(a,b){return utils.readFileAsArrayBuffer(c.slice(a,b))}var b,c=this.blob,d=(this.params,[]),e=[],f=[],g=[]; +return this.files=f,this.folders=g,this.localFileHeaders=e,this.centralDirHeaders=d,function(){return a(0,4).then(function(a){if(new DataView(a).getUint32(0,!0)===zip.LOCAL_FILE_SIGNATURE)return Math.max(0,c.size-32768);throw new Error("zip.unpack: invalid zip file.")})}().then(function h(b){return a(b,Math.min(c.size,b+32768)).then(function(a){var c,d=new DataView(a);for(c=a.byteLength-4;c--;)if(d.getUint32(c,!0)===zip.END_SIGNATURE)return b+c;if(b)return h(Math.max(b-32768+3,0));throw new Error("zip.unpack: invalid zip file.")})}).then(function(d){return a(d,c.size).then(function(a){return b=ZipArchiveReader.prototype._getEndCentDirHeader.call({buffer:a},0),d})}).then(function(c){return a(b.startpos,c).then(function(a){var c,e,f,g=0,h={buffer:a};for(c=0,e=b.direntry;e>c;++c)f=ZipArchiveReader.prototype._getCentralDirHeader.call(h,g),d.push(f),g+=f.allsize})}).then(function i(b){if(b!==d.length){var c=d[b].headerpos;return a(c+26,c+30).then(function(b){var d=new DataView(b),e=d.getUint16(0,!0),f=d.getUint16(2,!0);return a(c,c+30+e+f)}).then(function(a){var c=ZipArchiveReader.prototype._getLocalFileHeader.call({buffer:a},0);return c.crc32=d[b].crc32,c.compsize=d[b].compsize,c.uncompsize=d[b].uncompsize,e.push(c),i(b+1)})}}.bind(null,0)).then(this._completeInit.bind(this))},ZipArchiveReaderBlob.prototype.readFileAsArrayBuffer=function(a){return this._readFileAs("ArrayBuffer",a)},ZipArchiveReaderBlob.prototype.readFileAsBlob=function(a,b){b=b||mimetypes.guess(a);var c=this._getFileInfo(a),d=this.blob.slice(c.offset,c.offset+c.length,{type:b});return c.isCompressed?utils.readFileAsArrayBuffer(d).then(function(a){return new Blob([algorithms.inflate(new Uint8Array(a))],{type:b})}):Promise.resolve(d)},env.isWorker&&(ZipArchiveReaderBlob.prototype._decompressFile=function(a){var b=this._getFileInfo(a),c=this.blob.slice(b.offset,b.offset+b.length),d=new Uint8Array((new FileReaderSync).readAsArrayBuffer(c));return this._decompress(d,b.isCompressed)},ZipArchiveReaderBlob.prototype.readFileAsArrayBufferSync=function(a){return this._decompressFile(a,!0).buffer},ZipArchiveReaderBlob.prototype.readFileAsBlobSync=function(a,b){return new Blob([this._decompressFile(a,!1)],{type:b||mimetypes.guess(a)})},exposeProperty("readFileAsArrayBufferSync",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsArrayBufferSync),exposeProperty("readFileAsBlobSync",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsBlobSync),exposeProperty("readFileAsTextSync",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsTextSync),exposeProperty("readFileAsBinaryStringSync",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsBinaryStringSync),exposeProperty("readFileAsDataURLSync",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsDataURLSync)),exposeProperty("readFileAsArrayBuffer",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsArrayBuffer),exposeProperty("readFileAsText",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsText),exposeProperty("readFileAsBinaryString",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsBinaryString),exposeProperty("readFileAsDataURL",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsDataURL),exposeProperty("readFileAsBlob",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsBlob),exposeProperty("readFileAsTextSync",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsTextSync),exposeProperty("readFileAsBinaryStringSync",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsBinaryStringSync),exposeProperty("readFileAsDataURLSync",ZipArchiveReaderBlob,ZipArchiveReaderBlob.prototype.readFileAsDataURLSync),zip.unpack=function(){var a=utils.getParams(arguments,["buffer","encoding","chunkSize"]);return new(a.buffer instanceof Blob?ZipArchiveReaderBlob:ZipArchiveReader)(a).init()},expose("jz.zip.unpack",zip.unpack);}).call(this); \ No newline at end of file diff --git a/package.json b/package.json index 118c410..794915e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jsziptools", - "version": "2.4.0", + "version": "2.4.1", "description": "It's a utility of zlib, gzip and zip format binary data.", "main": "jsziptools.js", "directories": { diff --git a/src/ZipArchiveWriter.js b/src/ZipArchiveWriter.js new file mode 100644 index 0000000..e1a5a86 --- /dev/null +++ b/src/ZipArchiveWriter.js @@ -0,0 +1,235 @@ +/** + * @constructor + * @param {boolean} shareMemory + * @param {number} chunkSize + * @example + * var writer = new jz.zip.ZipArchiveWriter({shareMemory: true, chunkSize: 0xf000}); + * writer + * .on('data', function(chunk) { + * // ... + * }) + * .on('end', function() { + * // ... + * }); + * .write('foo/bar/baz.txt', buffer) + * .write('a.mp3', mp3Buff) + * .writeEnd(); + */ +function ZipArchiveWriter(shareMemory, chunkSize) { + var params = utils.getParams(arguments, ['shareMemory', 'chunkSize']); + this.shareMemory = params.shareMemory; + this.chunkSize = params.chunkSize; + this.dirs = {}; + this.centralDirHeaders = []; + this.offset = 0; + this.date = new Date; + this.listners = {}; +} + +/** + * @param {string} path + * @param {Uint8Array} buffer + * @param {number} level + * @return {ZipArchiveWriter} return this + */ +ZipArchiveWriter.prototype.write = function(path, buffer, level) { + var self = this; + path.split('/').reduce(function(parent, child) { + self.writeDir(parent + '/'); + return parent + '/' + child; + }); + this.writeFile(path, buffer, level); + return this; +}; + +/** + * @param {string} path + * @return {ZipArchiveWriter} return this + */ +ZipArchiveWriter.prototype.writeDir = function(path) { + var localFileHeader; + path += (/.+\/$/.test(path) ? '' : '/'); + if (!this.dirs[path]) { + this.dirs[path] = true; + path = utils.toBytes(path); + localFileHeader = createLocalFileHeader(path, this.date, false); + this.centralDirHeaders.push(createCentralDirHeader(path, this.date, false, this.offset, 0, 0, 0)); + this.trigger('data', localFileHeader); + this.offset += localFileHeader.length; + } + return this; +}; + +/** + * @param {string} path + * @param {Uint8Array} buffer + * @param {number} level + * @return {ZipArchiveWriter} return this + */ +ZipArchiveWriter.prototype.writeFile = function(path, buffer, level) { + path = utils.toBytes(path); + var offset = this.offset, + localFileHeader = createLocalFileHeader(path, this.date, level), + compressedSize = 0, + self = this; + this.trigger('data', localFileHeader); + if (level) { + stream.algorithms.deflate({ + buffer: buffer, + level: level, + streamFn: function(chunk) { + compressedSize += chunk.length; + self.trigger('data', chunk); + }, + shareMemory: this.shareMemory, + chunkSize: this.chunkSize, + }); + } else { + compressedSize = buffer.length; + this.trigger('data', buffer); + } + this.centralDirHeaders.push(createCentralDirHeader(path, this.date, level, offset, buffer.length, compressedSize, algorithms.crc32(buffer))); + this.offset += localFileHeader.length + compressedSize; + return this; +}; + +ZipArchiveWriter.prototype.writeEnd = function() { + var centralDirHeaderSize = 0, + self = this; + this.centralDirHeaders.forEach(function(header) { + centralDirHeaderSize += header.length; + self.trigger('data', header); + }); + this.trigger('data', createEndCentDirHeader(this.centralDirHeaders.length, centralDirHeaderSize, this.offset)); + this.trigger('end', null); +}; + +/** + * @param {string} name + * @param {Function} callback + * @return {ZipArchiveWriter} return this + */ +ZipArchiveWriter.prototype.on = function(name, callback) { + if (!this.listners[name]) this.listners[name] = []; + this.listners[name].push(callback); + return this; +}; + +/** + * @param {string} name + * @param {*} data + */ +ZipArchiveWriter.prototype.trigger = function(name, data) { + this.listners[name] && this.listners[name].forEach(function(listner) { + listner(data); + }); +}; + +expose('jz.zip.ZipArchiveWriter', ZipArchiveWriter); +exposeProperty('write', ZipArchiveWriter, ZipArchiveWriter.prototype.write); +exposeProperty('writeDir', ZipArchiveWriter, ZipArchiveWriter.prototype.writeDir); +exposeProperty('writeFile', ZipArchiveWriter, ZipArchiveWriter.prototype.writeFile); +exposeProperty('writeEnd', ZipArchiveWriter, ZipArchiveWriter.prototype.writeEnd); +exposeProperty('on', ZipArchiveWriter, ZipArchiveWriter.prototype.on); + +/** + * local file header + * @param {string} fileName + * @param {Date} date + * @param {boolean} isDeflated + * @return {Uint8Array} + */ +function createLocalFileHeader(fileName, date, isDeflated) { + var view = new DataView(new ArrayBuffer(30 + fileName.length)), + bytes = new Uint8Array(view.buffer), + offset = 0; + view.setUint32(offset, zip.LOCAL_FILE_SIGNATURE, true); offset += 4; // local file header signature + view.setUint16(offset, 20, true); offset += 2; // version needed to extract + view.setUint16(offset, 0x0008); offset += 2; // general purpose bit flag + view.setUint16(offset, isDeflated ? 8 : 0, true); offset += 2; // compression method + view.setUint16(offset, createDosFileTime(date), true); offset += 2; // last mod file time + view.setUint16(offset, createDosFileDate(date), true); offset += 2; // last mod file date + // skip below + // crc-32 4bytes + // compressed size 4bytes + // uncompressed size 4bytes + offset += 12; + view.setUint16(offset, fileName.length, true); offset += 2; // file name length + offset += 2; // skip extra field length + bytes.set(fileName, offset); + return bytes; +} + +/** + * central directory + * @param {string} fileName + * @param {Date} date + * @param {boolean} isDeflated + * @param {number} fileOffset + * @param {Uint8Array} dataDescriptor + * @return {Uint8Array} + */ +function createCentralDirHeader(fileName, date, isDeflated, fileOffset, uncompressedSize, compressedSize, crc) { + var view = new DataView(new ArrayBuffer(46 + fileName.length)), + bytes = new Uint8Array(view.buffer), + offset = 0; + view.setUint32(offset, zip.CENTRAL_DIR_SIGNATURE, true); offset += 4; // central file header signature + view.setUint16(offset, 20, true); offset += 2; // version made by (2.0) + view.setUint16(offset, 20, true); offset += 2; // version needed to extract + view.setUint16(offset, 0x0008); offset += 2; // general purpose bit flag (use utf8, data discriptor) + view.setUint16(offset, isDeflated ? 8 : 0, true); offset += 2; // compression method + view.setUint16(offset, createDosFileTime(date), true); offset += 2; // last mod file time + view.setUint16(offset, createDosFileDate(date), true); offset += 2; // last mod file date + view.setUint32(offset, crc, true); offset += 4; // crc-32 + view.setUint32(offset, compressedSize, true); offset += 4; // compressed size + view.setUint32(offset, uncompressedSize, true); offset += 4; // uncompressed size + view.setUint16(offset, fileName.length, true); offset += 2; // file name length + // skip below + // extra field length 2bytes + // file comment length 2bytes + // disk number start 2bytes + // internal file attributes 2bytes + // external file attributes 4bytes + offset += 12; + view.setUint32(offset, fileOffset, true); offset += 4; // relative offset of local header + bytes.set(fileName, offset); // file name + return bytes; +} + +/** + * end of central dirctory + * @param {number} numberOfCentralDirs + * @param {number} centralDirHeaderSize + * @param {number} centralDirStartOffset + * @return {Uint8Array} + */ +function createEndCentDirHeader(numberOfCentralDirs, centralDirHeaderSize, centralDirStartOffset) { + var view = new DataView(new ArrayBuffer(22)); + view.setUint32(0, zip.END_SIGNATURE, true); // end of central dir signature + view.setUint16(4, 0, true); // number of this disk + view.setUint16(6, 0, true); // number of the disk with the start of the central directory + view.setUint16(8, numberOfCentralDirs, true); // total number of entries in the central directory on this disk + view.setUint16(10, numberOfCentralDirs, true); // total number of entries in the central directory + view.setUint32(12, centralDirHeaderSize, true); // size of the central directory + view.setUint32(16, centralDirStartOffset, true); // offset of start of central directory with respect to the starting disk number + view.setUint16(20, 0, true); // .ZIP file comment length + return new Uint8Array(view.buffer); +} + +/** + * create DOS style Date(year, month, day). + * @param {Date} date + * @return {number} + */ +function createDosFileDate(date) { + return ((date.getFullYear() - 1980) << 9) | ((date.getMonth() + 1) << 5) | (date.getDay()); +} + +/** + * create DOS style Time(hour, minute, second). + * @param {Date} date + * @return {number} + */ +function createDosFileTime(date) { + return (date.getHours() << 11) | (date.getMinutes() << 5) | (date.getSeconds() >> 1); +} diff --git a/src/stream/zip.pack.js b/src/stream/zip.pack.js index b895f8d..b249607 100644 --- a/src/stream/zip.pack.js +++ b/src/stream/zip.pack.js @@ -1,124 +1,3 @@ -/** - * end of central dirctory - * @param {number} numberOfCentralDirs - * @param {number} centralDirHeaderSize - * @param {number} centralDirStartOffset - * @return {Uint8Array} - */ -function createEndCentDirHeader(numberOfCentralDirs, centralDirHeaderSize, centralDirStartOffset) { - var view = new DataView(new ArrayBuffer(22)); - view.setUint32(0, zip.END_SIGNATURE, true); // end of central dir signature - view.setUint16(4, 0, true); // number of this disk - view.setUint16(6, 0, true); // number of the disk with the start of the central directory - view.setUint16(8, numberOfCentralDirs, true); // total number of entries in the central directory on this disk - view.setUint16(10, numberOfCentralDirs, true); // total number of entries in the central directory - view.setUint32(12, centralDirHeaderSize, true); // size of the central directory - view.setUint32(16, centralDirStartOffset, true); // offset of start of central directory with respect to the starting disk number - view.setUint16(20, 0, true); // .ZIP file comment length - return new Uint8Array(view.buffer); -} - -/** - * central directory - * @param {Uint8Array} buffer - * @param {Uint8Array} fileName - * @param {Date} date - * @param {boolean} isDeflated - * @param {number} fileOffset - * @param {Uint8Array} dataDescriptor - * @return {Uint8Array} - */ -function createCentralDirHeader(buffer, fileName, date, isDeflated, fileOffset, dataDescriptor) { - var view = new DataView(new ArrayBuffer(46 + fileName.length)), - bytes = new Uint8Array(view.buffer), - offset = 0; - view.setUint32(offset, zip.CENTRAL_DIR_SIGNATURE, true); offset += 4; // central file header signature - view.setUint16(offset, 20, true); offset += 2; // version made by (2.0) - view.setUint16(offset, 20, true); offset += 2; // version needed to extract - view.setUint16(offset, 0x0008); offset += 2; // general purpose bit flag (use utf8, data discriptor) - view.setUint16(offset, isDeflated ? 8 : 0, true); offset += 2; // compression method - view.setUint16(offset, createDosFileTime(date), true); offset += 2; // last mod file time - view.setUint16(offset, createDosFileDate(date), true); offset += 2; // last mod file date - // crc-32 - // compressed size - // uncompressed size - bytes.set(dataDescriptor, offset); offset += 12; - view.setUint16(offset, fileName.length, true); offset += 2; // file name length - // skip below - // extra field length 2bytes - // file comment length 2bytes - // disk number start 2bytes - // internal file attributes 2bytes - // external file attributes 4bytes - offset += 12; - view.setUint32(offset, fileOffset, true); offset += 4; // relative offset of local header - bytes.set(fileName, offset); // file name - return bytes; -} - -/** - * local file header - * @param {Uint8Array} buffer - * @param {Uint8Array} fileName - * @param {Date} date - * @param {boolean} isDeflated - * @return {Uint8Array} - */ -function createLocalFileHeader(buffer, fileName, date, isDeflated) { - var view = new DataView(new ArrayBuffer(30 + fileName.length)), - bytes = new Uint8Array(view.buffer), - offset = 0; - view.setUint32(offset, zip.LOCAL_FILE_SIGNATURE, true); offset += 4; // local file header signature - view.setUint16(offset, 20, true); offset += 2; // version needed to extract - view.setUint16(offset, 0x0008); offset += 2; // general purpose bit flag - view.setUint16(offset, isDeflated ? 8 : 0, true); offset += 2; // compression method - view.setUint16(offset, createDosFileTime(date), true); offset += 2; // last mod file time - view.setUint16(offset, createDosFileDate(date), true); offset += 2; // last mod file date - // skip below - // crc-32 4bytes - // compressed size 4bytes - // uncompressed size 4bytes - offset += 12; - view.setUint16(offset, fileName.length, true); offset += 2; // file name length - offset += 2; // skip extra field length - bytes.set(fileName, offset); - return bytes; -} - -/** - * data discriptor - * @param {number} uncompressedSize - * @param {number} compressedSize - * @param {number} crc - * @return {Uint8Array} - */ -function createDataDescriptor(uncompressedSize, compressedSize, crc) { - var view = new DataView(new ArrayBuffer(12)); - view.setUint32(0, crc, true); - view.setUint32(4, compressedSize, true); - view.setUint32(8, uncompressedSize, true); - return new Uint8Array(view.buffer); -} - -/** - * create DOS style Date(year, month, day). - * @param {Date} date - * @return {number} - */ -function createDosFileDate(date) { - return ((date.getFullYear() - 1980) << 9) | ((date.getMonth() + 1) << 5) | (date.getDay()); -} - -/** - * create DOS style Time(hour, minute, second). - * @param {Date} date - * @return {number} - */ -function createDosFileTime(date) { - return (date.getHours() << 11) | (date.getMinutes() << 5) | (date.getSeconds() >> 1); -} - - /** * @param {Array} files * @param {function(chunk: Uint8Array)} streamFn @@ -153,31 +32,19 @@ function createDosFileTime(date) { */ stream.zip.pack = function(files, streamFn, level, shareMemory, chunkSize) { var params = utils.getParams(arguments, ['files', 'streamFn', 'level', 'shareMemory', 'chunkSize']), - offset = 0, - centralDirHeaders = [], - date = new Date(), - files = params.files, - level = params.level = typeof params.level === 'number' ? params.level : 6, - chunkSize = params.chunkSize, - shareMemory = params.shareMemory, - streamFn = params.streamFn, - promises = []; + promises = [], + writer = new ZipArchiveWriter(params); + writer.on('data', params.streamFn); function packItem(level, path, item) { - var buffer, - isDeflated, - fileNameBytes, - localFileHeader, - compressedSize, - dataDiscriptor, - centralDirHeader, - dir = item.children || item.dir || item.folder; - + var dir = item.children || item.dir || item.folder, + buffer; level = typeof item.level === 'number' ? item.level : level; // init buffer and file path. if (dir) { - buffer = new ArrayBuffer(0); path += item.name + (/.+\/$/.test(item.name) ? '' : '/'); + writer.writeDir(path); + dir.forEach(packItem.bind(null, level, path)); } else { if (item.buffer != null) buffer = item.buffer; if (item.str != null) buffer = item.str; @@ -186,39 +53,9 @@ stream.zip.pack = function(files, streamFn, level, shareMemory, chunkSize) { } else { throw new Error('jz.zip.pack: This type is not supported.'); } + writer.writeFile(path, utils.toBytes(buffer), level); } - buffer = utils.toBytes(buffer); - isDeflated = !dir && level; - fileNameBytes = utils.toBytes(path); - - localFileHeader = createLocalFileHeader(buffer, fileNameBytes, date, isDeflated); - streamFn(localFileHeader); - // compress bufer - compressedSize = 0; - if (isDeflated) { - stream.algorithms.deflate({ - buffer: buffer, - shareMemory: shareMemory, - chunkSize: chunkSize, - streamFn: function(chunk) { - compressedSize += chunk.length; - streamFn(chunk); - } - }); - } else { - streamFn(buffer); - compressedSize = buffer.length; - } - - dataDescriptor = createDataDescriptor(buffer.length, compressedSize, algorithms.crc32(buffer)); - centralDirHeader = createCentralDirHeader(buffer, fileNameBytes, date, isDeflated, offset, dataDescriptor); - centralDirHeaders.push(centralDirHeader); - - offset += localFileHeader.length + compressedSize; - - if (dir) dir.forEach(packItem.bind(null, level, path)); } - // load files with ajax(async). function loadFile(item) { var dir = item.children || item.dir || item.folder; @@ -232,12 +69,10 @@ stream.zip.pack = function(files, streamFn, level, shareMemory, chunkSize) { } } - files.forEach(loadFile); + params.files.forEach(loadFile); return Promise.all(promises).then(function() { - files.forEach(packItem.bind(null, level, '')); - var centralDir = utils.concatBytes(centralDirHeaders); - streamFn(centralDir); - streamFn(createEndCentDirHeader(centralDirHeaders.length, centralDir.length, offset)); + params.files.forEach(packItem.bind(null, params.level, '')); + writer.writeEnd(); }); }; diff --git a/test/test.js b/test/test.js index 9cbc715..870bedc 100644 --- a/test/test.js +++ b/test/test.js @@ -438,6 +438,48 @@ describe('jz.zip', function() { }); }); + describe('jz.zip.ZipArchiveWriter', function() { + var writer = new jz.zip.ZipArchiveWriter({ + shareMemory: true, + chunkSize: 0x8000 + }); + + it('has params.', function() { + expect(writer.shareMemory).toBe(true); + expect(writer.chunkSize).toBe(0x8000); + }); + + describe('#write', function() { + it('exists.', function() { + expect(writer.write).toBeDefined(); + }); + }); + + describe('#writeDir', function() { + it('exists.', function() { + expect(writer.writeDir).toBeDefined(); + }); + }); + + describe('#writeFile', function() { + it('exists.', function() { + expect(writer.writeFile).toBeDefined(); + }); + }); + + describe('#writeEnd', function() { + it('exists.', function() { + expect(writer.writeEnd).toBeDefined(); + }); + }); + + describe('#on', function() { + it('exists.', function() { + expect(writer.on).toBeDefined(); + }); + }); + }); + describe('jz.zip.pack({files, level, chunkSize})', function() { it('pack to the zip archive (buffer).', function() { var files = [ diff --git a/test/worker.js b/test/worker.js index eb9f64c..2272b0f 100644 --- a/test/worker.js +++ b/test/worker.js @@ -7,6 +7,7 @@ importScripts( '../src/algorithms/crc32.js', '../src/algorithms/deflate.js', '../src/algorithms/inflate.js', + '../src/ZipArchiveWriter.js', '../src/stream/algorithms/deflate.js', '../src/stream/algorithms/inflate.js', '../src/stream/zlib.compress.js',