mapshaper 0.6.15 → 0.6.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/www/zip.js DELETED
@@ -1,969 +0,0 @@
1
- /*
2
- Copyright (c) 2013 Gildas Lormeau. All rights reserved.
3
-
4
- Redistribution and use in source and binary forms, with or without
5
- modification, are permitted provided that the following conditions are met:
6
-
7
- 1. Redistributions of source code must retain the above copyright notice,
8
- this list of conditions and the following disclaimer.
9
-
10
- 2. Redistributions in binary form must reproduce the above copyright
11
- notice, this list of conditions and the following disclaimer in
12
- the documentation and/or other materials provided with the distribution.
13
-
14
- 3. The names of the authors may not be used to endorse or promote products
15
- derived from this software without specific prior written permission.
16
-
17
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
18
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
20
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
21
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
- */
28
-
29
- (function(obj) {
30
- "use strict";
31
-
32
- var ERR_BAD_FORMAT = "File format is not recognized.";
33
- var ERR_CRC = "CRC failed.";
34
- var ERR_ENCRYPTED = "File contains encrypted entry.";
35
- var ERR_ZIP64 = "File is using Zip64 (4gb+ file size).";
36
- var ERR_READ = "Error while reading zip file.";
37
- var ERR_WRITE = "Error while writing zip file.";
38
- var ERR_WRITE_DATA = "Error while writing file data.";
39
- var ERR_READ_DATA = "Error while reading file data.";
40
- var ERR_DUPLICATED_NAME = "File already exists.";
41
- var CHUNK_SIZE = 512 * 1024;
42
-
43
- var TEXT_PLAIN = "text/plain";
44
-
45
- var appendABViewSupported;
46
- try {
47
- // Using the generic DataView contructor throws InvalidStateError in IE 11.
48
- // Using a specific view like Uint8Array works.
49
- // appendABViewSupported = new Blob([ new DataView(new ArrayBuffer(0)) ]).size === 0;
50
- appendABViewSupported = new Blob([ new Uint8Array(new ArrayBuffer(0)) ]).size === 0;
51
- } catch (e) {
52
- }
53
-
54
- function Crc32() {
55
- this.crc = -1;
56
- }
57
- Crc32.prototype.append = function append(data) {
58
- var crc = this.crc | 0, table = this.table;
59
- for (var offset = 0, len = data.length | 0; offset < len; offset++)
60
- crc = (crc >>> 8) ^ table[(crc ^ data[offset]) & 0xFF];
61
- this.crc = crc;
62
- };
63
- Crc32.prototype.get = function get() {
64
- return ~this.crc;
65
- };
66
- Crc32.prototype.table = (function() {
67
- var i, j, t, table = []; // Uint32Array is actually slower than []
68
- for (i = 0; i < 256; i++) {
69
- t = i;
70
- for (j = 0; j < 8; j++)
71
- if (t & 1)
72
- t = (t >>> 1) ^ 0xEDB88320;
73
- else
74
- t = t >>> 1;
75
- table[i] = t;
76
- }
77
- return table;
78
- })();
79
-
80
- // "no-op" codec
81
- function NOOP() {}
82
- NOOP.prototype.append = function append(bytes, onprogress) {
83
- return bytes;
84
- };
85
- NOOP.prototype.flush = function flush() {};
86
-
87
- function blobSlice(blob, index, length) {
88
- if (index < 0 || length < 0 || index + length > blob.size)
89
- throw new RangeError('offset:' + index + ', length:' + length + ', size:' + blob.size);
90
- if (blob.slice)
91
- return blob.slice(index, index + length);
92
- else if (blob.webkitSlice)
93
- return blob.webkitSlice(index, index + length);
94
- else if (blob.mozSlice)
95
- return blob.mozSlice(index, index + length);
96
- else if (blob.msSlice)
97
- return blob.msSlice(index, index + length);
98
- }
99
-
100
- function getDataHelper(byteLength, bytes) {
101
- var dataBuffer, dataArray;
102
- dataBuffer = new ArrayBuffer(byteLength);
103
- dataArray = new Uint8Array(dataBuffer);
104
- if (bytes)
105
- dataArray.set(bytes, 0);
106
- return {
107
- buffer : dataBuffer,
108
- array : dataArray,
109
- view : new DataView(dataBuffer)
110
- };
111
- }
112
-
113
- // Readers
114
- function Reader() {
115
- }
116
-
117
- function TextReader(text) {
118
- var that = this, blobReader;
119
-
120
- function init(callback, onerror) {
121
- var blob = new Blob([ text ], {
122
- type : TEXT_PLAIN
123
- });
124
- blobReader = new BlobReader(blob);
125
- blobReader.init(function() {
126
- that.size = blobReader.size;
127
- callback();
128
- }, onerror);
129
- }
130
-
131
- function readUint8Array(index, length, callback, onerror) {
132
- blobReader.readUint8Array(index, length, callback, onerror);
133
- }
134
-
135
- that.size = 0;
136
- that.init = init;
137
- that.readUint8Array = readUint8Array;
138
- }
139
- TextReader.prototype = new Reader();
140
- TextReader.prototype.constructor = TextReader;
141
-
142
- function Data64URIReader(dataURI) {
143
- var that = this, dataStart;
144
-
145
- function init(callback) {
146
- var dataEnd = dataURI.length;
147
- while (dataURI.charAt(dataEnd - 1) == "=")
148
- dataEnd--;
149
- dataStart = dataURI.indexOf(",") + 1;
150
- that.size = Math.floor((dataEnd - dataStart) * 0.75);
151
- callback();
152
- }
153
-
154
- function readUint8Array(index, length, callback) {
155
- var i, data = getDataHelper(length);
156
- var start = Math.floor(index / 3) * 4;
157
- var end = Math.ceil((index + length) / 3) * 4;
158
- var bytes = obj.atob(dataURI.substring(start + dataStart, end + dataStart));
159
- var delta = index - Math.floor(start / 4) * 3;
160
- for (i = delta; i < delta + length; i++)
161
- data.array[i - delta] = bytes.charCodeAt(i);
162
- callback(data.array);
163
- }
164
-
165
- that.size = 0;
166
- that.init = init;
167
- that.readUint8Array = readUint8Array;
168
- }
169
- Data64URIReader.prototype = new Reader();
170
- Data64URIReader.prototype.constructor = Data64URIReader;
171
-
172
- function BlobReader(blob) {
173
- var that = this;
174
-
175
- function init(callback) {
176
- that.size = blob.size;
177
- callback();
178
- }
179
-
180
- function readUint8Array(index, length, callback, onerror) {
181
- var reader = new FileReader();
182
- reader.onload = function(e) {
183
- callback(new Uint8Array(e.target.result));
184
- };
185
- reader.onerror = onerror;
186
- try {
187
- reader.readAsArrayBuffer(blobSlice(blob, index, length));
188
- } catch (e) {
189
- onerror(e);
190
- }
191
- }
192
-
193
- that.size = 0;
194
- that.init = init;
195
- that.readUint8Array = readUint8Array;
196
- }
197
- BlobReader.prototype = new Reader();
198
- BlobReader.prototype.constructor = BlobReader;
199
-
200
- // Writers
201
-
202
- function Writer() {
203
- }
204
- Writer.prototype.getData = function(callback) {
205
- callback(this.data);
206
- };
207
-
208
- function TextWriter(encoding) {
209
- var that = this, blob;
210
-
211
- function init(callback) {
212
- blob = new Blob([], {
213
- type : TEXT_PLAIN
214
- });
215
- callback();
216
- }
217
-
218
- function writeUint8Array(array, callback) {
219
- blob = new Blob([ blob, appendABViewSupported ? array : array.buffer ], {
220
- type : TEXT_PLAIN
221
- });
222
- callback();
223
- }
224
-
225
- function getData(callback, onerror) {
226
- var reader = new FileReader();
227
- reader.onload = function(e) {
228
- callback(e.target.result);
229
- };
230
- reader.onerror = onerror;
231
- reader.readAsText(blob, encoding);
232
- }
233
-
234
- that.init = init;
235
- that.writeUint8Array = writeUint8Array;
236
- that.getData = getData;
237
- }
238
- TextWriter.prototype = new Writer();
239
- TextWriter.prototype.constructor = TextWriter;
240
-
241
- function Data64URIWriter(contentType) {
242
- var that = this, data = "", pending = "";
243
-
244
- function init(callback) {
245
- data += "data:" + (contentType || "") + ";base64,";
246
- callback();
247
- }
248
-
249
- function writeUint8Array(array, callback) {
250
- var i, delta = pending.length, dataString = pending;
251
- pending = "";
252
- for (i = 0; i < (Math.floor((delta + array.length) / 3) * 3) - delta; i++)
253
- dataString += String.fromCharCode(array[i]);
254
- for (; i < array.length; i++)
255
- pending += String.fromCharCode(array[i]);
256
- if (dataString.length > 2)
257
- data += obj.btoa(dataString);
258
- else
259
- pending = dataString;
260
- callback();
261
- }
262
-
263
- function getData(callback) {
264
- callback(data + obj.btoa(pending));
265
- }
266
-
267
- that.init = init;
268
- that.writeUint8Array = writeUint8Array;
269
- that.getData = getData;
270
- }
271
- Data64URIWriter.prototype = new Writer();
272
- Data64URIWriter.prototype.constructor = Data64URIWriter;
273
-
274
- function BlobWriter(contentType) {
275
- var blob, that = this;
276
-
277
- function init(callback) {
278
- blob = new Blob([], {
279
- type : contentType
280
- });
281
- callback();
282
- }
283
-
284
- function writeUint8Array(array, callback) {
285
- blob = new Blob([ blob, appendABViewSupported ? array : array.buffer ], {
286
- type : contentType
287
- });
288
- callback();
289
- }
290
-
291
- function getData(callback) {
292
- callback(blob);
293
- }
294
-
295
- that.init = init;
296
- that.writeUint8Array = writeUint8Array;
297
- that.getData = getData;
298
- }
299
- BlobWriter.prototype = new Writer();
300
- BlobWriter.prototype.constructor = BlobWriter;
301
-
302
- /**
303
- * inflate/deflate core functions
304
- * @param worker {Worker} web worker for the task.
305
- * @param initialMessage {Object} initial message to be sent to the worker. should contain
306
- * sn(serial number for distinguishing multiple tasks sent to the worker), and codecClass.
307
- * This function may add more properties before sending.
308
- */
309
- function launchWorkerProcess(worker, initialMessage, reader, writer, offset, size, onprogress, onend, onreaderror, onwriteerror) {
310
- var chunkIndex = 0, index, outputSize, sn = initialMessage.sn, crc;
311
-
312
- function onflush() {
313
- worker.removeEventListener('message', onmessage, false);
314
- onend(outputSize, crc);
315
- }
316
-
317
- function onmessage(event) {
318
- var message = event.data, data = message.data, err = message.error;
319
- if (err) {
320
- err.toString = function () { return 'Error: ' + this.message; };
321
- onreaderror(err);
322
- return;
323
- }
324
- if (message.sn !== sn)
325
- return;
326
- if (typeof message.codecTime === 'number')
327
- worker.codecTime += message.codecTime; // should be before onflush()
328
- if (typeof message.crcTime === 'number')
329
- worker.crcTime += message.crcTime;
330
-
331
- switch (message.type) {
332
- case 'append':
333
- if (data) {
334
- outputSize += data.length;
335
- writer.writeUint8Array(data, function() {
336
- step();
337
- }, onwriteerror);
338
- } else
339
- step();
340
- break;
341
- case 'flush':
342
- crc = message.crc;
343
- if (data) {
344
- outputSize += data.length;
345
- writer.writeUint8Array(data, function() {
346
- onflush();
347
- }, onwriteerror);
348
- } else
349
- onflush();
350
- break;
351
- case 'progress':
352
- if (onprogress)
353
- onprogress(index + message.loaded, size);
354
- break;
355
- case 'importScripts': //no need to handle here
356
- case 'newTask':
357
- case 'echo':
358
- break;
359
- default:
360
- console.warn('zip.js:launchWorkerProcess: unknown message: ', message);
361
- }
362
- }
363
-
364
- function step() {
365
- index = chunkIndex * CHUNK_SIZE;
366
- // use `<=` instead of `<`, because `size` may be 0.
367
- if (index <= size) {
368
- reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(array) {
369
- if (onprogress)
370
- onprogress(index, size);
371
- var msg = index === 0 ? initialMessage : {sn : sn};
372
- msg.type = 'append';
373
- msg.data = array;
374
-
375
- // posting a message with transferables will fail on IE10
376
- try {
377
- worker.postMessage(msg, [array.buffer]);
378
- } catch(ex) {
379
- worker.postMessage(msg); // retry without transferables
380
- }
381
- chunkIndex++;
382
- }, onreaderror);
383
- } else {
384
- worker.postMessage({
385
- sn: sn,
386
- type: 'flush'
387
- });
388
- }
389
- }
390
-
391
- outputSize = 0;
392
- worker.addEventListener('message', onmessage, false);
393
- step();
394
- }
395
-
396
- function launchProcess(process, reader, writer, offset, size, crcType, onprogress, onend, onreaderror, onwriteerror) {
397
- var chunkIndex = 0, index, outputSize = 0,
398
- crcInput = crcType === 'input',
399
- crcOutput = crcType === 'output',
400
- crc = new Crc32();
401
- function step() {
402
- var outputData;
403
- index = chunkIndex * CHUNK_SIZE;
404
- if (index < size)
405
- reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(inputData) {
406
- var outputData;
407
- try {
408
- outputData = process.append(inputData, function(loaded) {
409
- if (onprogress)
410
- onprogress(index + loaded, size);
411
- });
412
- } catch (e) {
413
- onreaderror(e);
414
- return;
415
- }
416
- if (outputData) {
417
- outputSize += outputData.length;
418
- writer.writeUint8Array(outputData, function() {
419
- chunkIndex++;
420
- setTimeout(step, 1);
421
- }, onwriteerror);
422
- if (crcOutput)
423
- crc.append(outputData);
424
- } else {
425
- chunkIndex++;
426
- setTimeout(step, 1);
427
- }
428
- if (crcInput)
429
- crc.append(inputData);
430
- if (onprogress)
431
- onprogress(index, size);
432
- }, onreaderror);
433
- else {
434
- try {
435
- outputData = process.flush();
436
- } catch (e) {
437
- onreaderror(e);
438
- return;
439
- }
440
- if (outputData) {
441
- if (crcOutput)
442
- crc.append(outputData);
443
- outputSize += outputData.length;
444
- writer.writeUint8Array(outputData, function() {
445
- onend(outputSize, crc.get());
446
- }, onwriteerror);
447
- } else
448
- onend(outputSize, crc.get());
449
- }
450
- }
451
-
452
- step();
453
- }
454
-
455
- function inflate(worker, sn, reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) {
456
- var crcType = computeCrc32 ? 'output' : 'none';
457
- if (obj.zip.useWebWorkers) {
458
- var initialMessage = {
459
- sn: sn,
460
- codecClass: 'Inflater',
461
- crcType: crcType,
462
- };
463
- launchWorkerProcess(worker, initialMessage, reader, writer, offset, size, onprogress, onend, onreaderror, onwriteerror);
464
- } else
465
- launchProcess(new obj.zip.Inflater(), reader, writer, offset, size, crcType, onprogress, onend, onreaderror, onwriteerror);
466
- }
467
-
468
- function deflate(worker, sn, reader, writer, level, onend, onprogress, onreaderror, onwriteerror) {
469
- var crcType = 'input';
470
- if (obj.zip.useWebWorkers) {
471
- var initialMessage = {
472
- sn: sn,
473
- options: {level: level},
474
- codecClass: 'Deflater',
475
- crcType: crcType,
476
- };
477
- launchWorkerProcess(worker, initialMessage, reader, writer, 0, reader.size, onprogress, onend, onreaderror, onwriteerror);
478
- } else
479
- launchProcess(new obj.zip.Deflater(), reader, writer, 0, reader.size, crcType, onprogress, onend, onreaderror, onwriteerror);
480
- }
481
-
482
- function copy(worker, sn, reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) {
483
- var crcType = 'input';
484
- if (obj.zip.useWebWorkers && computeCrc32) {
485
- var initialMessage = {
486
- sn: sn,
487
- codecClass: 'NOOP',
488
- crcType: crcType,
489
- };
490
- launchWorkerProcess(worker, initialMessage, reader, writer, offset, size, onprogress, onend, onreaderror, onwriteerror);
491
- } else
492
- launchProcess(new NOOP(), reader, writer, offset, size, crcType, onprogress, onend, onreaderror, onwriteerror);
493
- }
494
-
495
- // ZipReader
496
-
497
- function decodeASCII(str) {
498
- var i, out = "", charCode, extendedASCII = [ '\u00C7', '\u00FC', '\u00E9', '\u00E2', '\u00E4', '\u00E0', '\u00E5', '\u00E7', '\u00EA', '\u00EB',
499
- '\u00E8', '\u00EF', '\u00EE', '\u00EC', '\u00C4', '\u00C5', '\u00C9', '\u00E6', '\u00C6', '\u00F4', '\u00F6', '\u00F2', '\u00FB', '\u00F9',
500
- '\u00FF', '\u00D6', '\u00DC', '\u00F8', '\u00A3', '\u00D8', '\u00D7', '\u0192', '\u00E1', '\u00ED', '\u00F3', '\u00FA', '\u00F1', '\u00D1',
501
- '\u00AA', '\u00BA', '\u00BF', '\u00AE', '\u00AC', '\u00BD', '\u00BC', '\u00A1', '\u00AB', '\u00BB', '_', '_', '_', '\u00A6', '\u00A6',
502
- '\u00C1', '\u00C2', '\u00C0', '\u00A9', '\u00A6', '\u00A6', '+', '+', '\u00A2', '\u00A5', '+', '+', '-', '-', '+', '-', '+', '\u00E3',
503
- '\u00C3', '+', '+', '-', '-', '\u00A6', '-', '+', '\u00A4', '\u00F0', '\u00D0', '\u00CA', '\u00CB', '\u00C8', 'i', '\u00CD', '\u00CE',
504
- '\u00CF', '+', '+', '_', '_', '\u00A6', '\u00CC', '_', '\u00D3', '\u00DF', '\u00D4', '\u00D2', '\u00F5', '\u00D5', '\u00B5', '\u00FE',
505
- '\u00DE', '\u00DA', '\u00DB', '\u00D9', '\u00FD', '\u00DD', '\u00AF', '\u00B4', '\u00AD', '\u00B1', '_', '\u00BE', '\u00B6', '\u00A7',
506
- '\u00F7', '\u00B8', '\u00B0', '\u00A8', '\u00B7', '\u00B9', '\u00B3', '\u00B2', '_', ' ' ];
507
- for (i = 0; i < str.length; i++) {
508
- charCode = str.charCodeAt(i) & 0xFF;
509
- if (charCode > 127)
510
- out += extendedASCII[charCode - 128];
511
- else
512
- out += String.fromCharCode(charCode);
513
- }
514
- return out;
515
- }
516
-
517
- function decodeUTF8(string) {
518
- return decodeURIComponent(escape(string));
519
- }
520
-
521
- function getString(bytes) {
522
- var i, str = "";
523
- for (i = 0; i < bytes.length; i++)
524
- str += String.fromCharCode(bytes[i]);
525
- return str;
526
- }
527
-
528
- function getDate(timeRaw) {
529
- var date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & 0x0000ffff;
530
- try {
531
- return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5,
532
- (time & 0x001F) * 2, 0);
533
- } catch (e) {
534
- }
535
- }
536
-
537
- function readCommonHeader(entry, data, index, centralDirectory, onerror) {
538
- entry.version = data.view.getUint16(index, true);
539
- entry.bitFlag = data.view.getUint16(index + 2, true);
540
- entry.compressionMethod = data.view.getUint16(index + 4, true);
541
- entry.lastModDateRaw = data.view.getUint32(index + 6, true);
542
- entry.lastModDate = getDate(entry.lastModDateRaw);
543
- if ((entry.bitFlag & 0x01) === 0x01) {
544
- onerror(ERR_ENCRYPTED);
545
- return;
546
- }
547
- if (centralDirectory || (entry.bitFlag & 0x0008) != 0x0008) {
548
- entry.crc32 = data.view.getUint32(index + 10, true);
549
- entry.compressedSize = data.view.getUint32(index + 14, true);
550
- entry.uncompressedSize = data.view.getUint32(index + 18, true);
551
- }
552
- if (entry.compressedSize === 0xFFFFFFFF || entry.uncompressedSize === 0xFFFFFFFF) {
553
- onerror(ERR_ZIP64);
554
- return;
555
- }
556
- entry.filenameLength = data.view.getUint16(index + 22, true);
557
- entry.extraFieldLength = data.view.getUint16(index + 24, true);
558
- }
559
-
560
- function createZipReader(reader, callback, onerror) {
561
- var inflateSN = 0;
562
-
563
- function Entry() {
564
- }
565
-
566
- Entry.prototype.getData = function(writer, onend, onprogress, checkCrc32) {
567
- var that = this;
568
-
569
- function testCrc32(crc32) {
570
- var dataCrc32 = getDataHelper(4);
571
- dataCrc32.view.setUint32(0, crc32);
572
- return that.crc32 == dataCrc32.view.getUint32(0);
573
- }
574
-
575
- function getWriterData(uncompressedSize, crc32) {
576
- if (checkCrc32 && !testCrc32(crc32))
577
- onerror(ERR_CRC);
578
- else
579
- writer.getData(function(data) {
580
- onend(data);
581
- });
582
- }
583
-
584
- function onreaderror(err) {
585
- onerror(err || ERR_READ_DATA);
586
- }
587
-
588
- function onwriteerror(err) {
589
- onerror(err || ERR_WRITE_DATA);
590
- }
591
-
592
- reader.readUint8Array(that.offset, 30, function(bytes) {
593
- var data = getDataHelper(bytes.length, bytes), dataOffset;
594
- if (data.view.getUint32(0) != 0x504b0304) {
595
- onerror(ERR_BAD_FORMAT);
596
- return;
597
- }
598
- readCommonHeader(that, data, 4, false, onerror);
599
- dataOffset = that.offset + 30 + that.filenameLength + that.extraFieldLength;
600
- writer.init(function() {
601
- if (that.compressionMethod === 0)
602
- copy(that._worker, inflateSN++, reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror);
603
- else
604
- inflate(that._worker, inflateSN++, reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror);
605
- }, onwriteerror);
606
- }, onreaderror);
607
- };
608
-
609
- function seekEOCDR(eocdrCallback) {
610
- // "End of central directory record" is the last part of a zip archive, and is at least 22 bytes long.
611
- // Zip file comment is the last part of EOCDR and has max length of 64KB,
612
- // so we only have to search the last 64K + 22 bytes of a archive for EOCDR signature (0x06054b50).
613
- var EOCDR_MIN = 22;
614
- if (reader.size < EOCDR_MIN) {
615
- onerror(ERR_BAD_FORMAT);
616
- return;
617
- }
618
- var ZIP_COMMENT_MAX = 256 * 256, EOCDR_MAX = EOCDR_MIN + ZIP_COMMENT_MAX;
619
-
620
- // In most cases, the EOCDR is EOCDR_MIN bytes long
621
- doSeek(EOCDR_MIN, function() {
622
- // If not found, try within EOCDR_MAX bytes
623
- doSeek(Math.min(EOCDR_MAX, reader.size), function() {
624
- onerror(ERR_BAD_FORMAT);
625
- });
626
- });
627
-
628
- // seek last length bytes of file for EOCDR
629
- function doSeek(length, eocdrNotFoundCallback) {
630
- reader.readUint8Array(reader.size - length, length, function(bytes) {
631
- for (var i = bytes.length - EOCDR_MIN; i >= 0; i--) {
632
- if (bytes[i] === 0x50 && bytes[i + 1] === 0x4b && bytes[i + 2] === 0x05 && bytes[i + 3] === 0x06) {
633
- eocdrCallback(new DataView(bytes.buffer, i, EOCDR_MIN));
634
- return;
635
- }
636
- }
637
- eocdrNotFoundCallback();
638
- }, function() {
639
- onerror(ERR_READ);
640
- });
641
- }
642
- }
643
-
644
- var zipReader = {
645
- getEntries : function(callback) {
646
- var worker = this._worker;
647
- // look for End of central directory record
648
- seekEOCDR(function(dataView) {
649
- var datalength, fileslength;
650
- datalength = dataView.getUint32(16, true);
651
- fileslength = dataView.getUint16(8, true);
652
- if (datalength < 0 || datalength >= reader.size) {
653
- onerror(ERR_BAD_FORMAT);
654
- return;
655
- }
656
- reader.readUint8Array(datalength, reader.size - datalength, function(bytes) {
657
- var i, index = 0, entries = [], entry, filename, comment, data = getDataHelper(bytes.length, bytes);
658
- for (i = 0; i < fileslength; i++) {
659
- entry = new Entry();
660
- entry._worker = worker;
661
- if (data.view.getUint32(index) != 0x504b0102) {
662
- onerror(ERR_BAD_FORMAT);
663
- return;
664
- }
665
- readCommonHeader(entry, data, index + 6, true, onerror);
666
- entry.commentLength = data.view.getUint16(index + 32, true);
667
- entry.directory = ((data.view.getUint8(index + 38) & 0x10) == 0x10);
668
- entry.offset = data.view.getUint32(index + 42, true);
669
- filename = getString(data.array.subarray(index + 46, index + 46 + entry.filenameLength));
670
- entry.filename = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(filename) : decodeASCII(filename);
671
- if (!entry.directory && entry.filename.charAt(entry.filename.length - 1) == "/")
672
- entry.directory = true;
673
- comment = getString(data.array.subarray(index + 46 + entry.filenameLength + entry.extraFieldLength, index + 46
674
- + entry.filenameLength + entry.extraFieldLength + entry.commentLength));
675
- entry.comment = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(comment) : decodeASCII(comment);
676
- entries.push(entry);
677
- index += 46 + entry.filenameLength + entry.extraFieldLength + entry.commentLength;
678
- }
679
- callback(entries);
680
- }, function() {
681
- onerror(ERR_READ);
682
- });
683
- });
684
- },
685
- close : function(callback) {
686
- if (this._worker) {
687
- this._worker.terminate();
688
- this._worker = null;
689
- }
690
- if (callback)
691
- callback();
692
- },
693
- _worker: null
694
- };
695
-
696
- if (!obj.zip.useWebWorkers)
697
- callback(zipReader);
698
- else {
699
- createWorker('inflater',
700
- function(worker) {
701
- zipReader._worker = worker;
702
- callback(zipReader);
703
- },
704
- function(err) {
705
- onerror(err);
706
- }
707
- );
708
- }
709
- }
710
-
711
- // ZipWriter
712
-
713
- function encodeUTF8(string) {
714
- return unescape(encodeURIComponent(string));
715
- }
716
-
717
- function getBytes(str) {
718
- var i, array = [];
719
- for (i = 0; i < str.length; i++)
720
- array.push(str.charCodeAt(i));
721
- return array;
722
- }
723
-
724
- function createZipWriter(writer, callback, onerror, dontDeflate) {
725
- var files = {}, filenames = [], datalength = 0;
726
- var deflateSN = 0;
727
-
728
- function onwriteerror(err) {
729
- onerror(err || ERR_WRITE);
730
- }
731
-
732
- function onreaderror(err) {
733
- onerror(err || ERR_READ_DATA);
734
- }
735
-
736
- var zipWriter = {
737
- add : function(name, reader, onend, onprogress, options) {
738
- var header, filename, date;
739
- var worker = this._worker;
740
-
741
- function writeHeader(callback) {
742
- var data;
743
- date = options.lastModDate || new Date();
744
- header = getDataHelper(26);
745
- files[name] = {
746
- headerArray : header.array,
747
- directory : options.directory,
748
- filename : filename,
749
- offset : datalength,
750
- comment : getBytes(encodeUTF8(options.comment || ""))
751
- };
752
- header.view.setUint32(0, 0x14000808);
753
- if (options.version)
754
- header.view.setUint8(0, options.version);
755
- if (!dontDeflate && options.level !== 0 && !options.directory)
756
- header.view.setUint16(4, 0x0800);
757
- header.view.setUint16(6, (((date.getHours() << 6) | date.getMinutes()) << 5) | date.getSeconds() / 2, true);
758
- header.view.setUint16(8, ((((date.getFullYear() - 1980) << 4) | (date.getMonth() + 1)) << 5) | date.getDate(), true);
759
- header.view.setUint16(22, filename.length, true);
760
- data = getDataHelper(30 + filename.length);
761
- data.view.setUint32(0, 0x504b0304);
762
- data.array.set(header.array, 4);
763
- data.array.set(filename, 30);
764
- datalength += data.array.length;
765
- writer.writeUint8Array(data.array, callback, onwriteerror);
766
- }
767
-
768
- function writeFooter(compressedLength, crc32) {
769
- var footer = getDataHelper(16);
770
- datalength += compressedLength || 0;
771
- footer.view.setUint32(0, 0x504b0708);
772
- if (typeof crc32 != "undefined") {
773
- header.view.setUint32(10, crc32, true);
774
- footer.view.setUint32(4, crc32, true);
775
- }
776
- if (reader) {
777
- footer.view.setUint32(8, compressedLength, true);
778
- header.view.setUint32(14, compressedLength, true);
779
- footer.view.setUint32(12, reader.size, true);
780
- header.view.setUint32(18, reader.size, true);
781
- }
782
- writer.writeUint8Array(footer.array, function() {
783
- datalength += 16;
784
- onend();
785
- }, onwriteerror);
786
- }
787
-
788
- function writeFile() {
789
- options = options || {};
790
- name = name.trim();
791
- if (options.directory && name.charAt(name.length - 1) != "/")
792
- name += "/";
793
- if (files.hasOwnProperty(name)) {
794
- onerror(ERR_DUPLICATED_NAME);
795
- return;
796
- }
797
- filename = getBytes(encodeUTF8(name));
798
- filenames.push(name);
799
- writeHeader(function() {
800
- if (reader)
801
- if (dontDeflate || options.level === 0)
802
- copy(worker, deflateSN++, reader, writer, 0, reader.size, true, writeFooter, onprogress, onreaderror, onwriteerror);
803
- else
804
- deflate(worker, deflateSN++, reader, writer, options.level, writeFooter, onprogress, onreaderror, onwriteerror);
805
- else
806
- writeFooter();
807
- }, onwriteerror);
808
- }
809
-
810
- if (reader)
811
- reader.init(writeFile, onreaderror);
812
- else
813
- writeFile();
814
- },
815
- close : function(callback) {
816
- if (this._worker) {
817
- this._worker.terminate();
818
- this._worker = null;
819
- }
820
-
821
- var data, length = 0, index = 0, indexFilename, file;
822
- for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) {
823
- file = files[filenames[indexFilename]];
824
- length += 46 + file.filename.length + file.comment.length;
825
- }
826
- data = getDataHelper(length + 22);
827
- for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) {
828
- file = files[filenames[indexFilename]];
829
- data.view.setUint32(index, 0x504b0102);
830
- data.view.setUint16(index + 4, 0x1400);
831
- data.array.set(file.headerArray, index + 6);
832
- data.view.setUint16(index + 32, file.comment.length, true);
833
- if (file.directory)
834
- data.view.setUint8(index + 38, 0x10);
835
- data.view.setUint32(index + 42, file.offset, true);
836
- data.array.set(file.filename, index + 46);
837
- data.array.set(file.comment, index + 46 + file.filename.length);
838
- index += 46 + file.filename.length + file.comment.length;
839
- }
840
- data.view.setUint32(index, 0x504b0506);
841
- data.view.setUint16(index + 8, filenames.length, true);
842
- data.view.setUint16(index + 10, filenames.length, true);
843
- data.view.setUint32(index + 12, length, true);
844
- data.view.setUint32(index + 16, datalength, true);
845
- writer.writeUint8Array(data.array, function() {
846
- writer.getData(callback);
847
- }, onwriteerror);
848
- },
849
- _worker: null
850
- };
851
-
852
- if (!obj.zip.useWebWorkers)
853
- callback(zipWriter);
854
- else {
855
- createWorker('deflater',
856
- function(worker) {
857
- zipWriter._worker = worker;
858
- callback(zipWriter);
859
- },
860
- function(err) {
861
- onerror(err);
862
- }
863
- );
864
- }
865
- }
866
-
867
- function resolveURLs(urls) {
868
- var a = document.createElement('a');
869
- return urls.map(function(url) {
870
- a.href = url;
871
- return a.href;
872
- });
873
- }
874
-
875
- var DEFAULT_WORKER_SCRIPTS = {
876
- deflater: ['z-worker.js', 'deflate.js'],
877
- inflater: ['z-worker.js', 'inflate.js']
878
- };
879
- function createWorker(type, callback, onerror) {
880
- if (obj.zip.workerScripts !== null && obj.zip.workerScriptsPath !== null) {
881
- onerror(new Error('Either zip.workerScripts or zip.workerScriptsPath may be set, not both.'));
882
- return;
883
- }
884
- var scripts;
885
- if (obj.zip.workerScripts) {
886
- scripts = obj.zip.workerScripts[type];
887
- if (!Array.isArray(scripts)) {
888
- onerror(new Error('zip.workerScripts.' + type + ' is not an array!'));
889
- return;
890
- }
891
- scripts = resolveURLs(scripts);
892
- } else {
893
- scripts = DEFAULT_WORKER_SCRIPTS[type].slice(0);
894
- scripts[0] = (obj.zip.workerScriptsPath || '') + scripts[0];
895
- }
896
- var worker = new Worker(scripts[0]);
897
- // record total consumed time by inflater/deflater/crc32 in this worker
898
- worker.codecTime = worker.crcTime = 0;
899
- worker.postMessage({ type: 'importScripts', scripts: scripts.slice(1) });
900
- worker.addEventListener('message', onmessage);
901
- function onmessage(ev) {
902
- var msg = ev.data;
903
- if (msg.error) {
904
- worker.terminate(); // should before onerror(), because onerror() may throw.
905
- onerror(msg.error);
906
- return;
907
- }
908
- if (msg.type === 'importScripts') {
909
- worker.removeEventListener('message', onmessage);
910
- worker.removeEventListener('error', errorHandler);
911
- callback(worker);
912
- }
913
- }
914
- // catch entry script loading error and other unhandled errors
915
- worker.addEventListener('error', errorHandler);
916
- function errorHandler(err) {
917
- worker.terminate();
918
- onerror(err);
919
- }
920
- }
921
-
922
- function onerror_default(error) {
923
- console.error(error);
924
- }
925
- obj.zip = {
926
- Reader : Reader,
927
- Writer : Writer,
928
- BlobReader : BlobReader,
929
- Data64URIReader : Data64URIReader,
930
- TextReader : TextReader,
931
- BlobWriter : BlobWriter,
932
- Data64URIWriter : Data64URIWriter,
933
- TextWriter : TextWriter,
934
- createReader : function(reader, callback, onerror) {
935
- onerror = onerror || onerror_default;
936
-
937
- reader.init(function() {
938
- createZipReader(reader, callback, onerror);
939
- }, onerror);
940
- },
941
- createWriter : function(writer, callback, onerror, dontDeflate) {
942
- onerror = onerror || onerror_default;
943
- dontDeflate = !!dontDeflate;
944
-
945
- writer.init(function() {
946
- createZipWriter(writer, callback, onerror, dontDeflate);
947
- }, onerror);
948
- },
949
- useWebWorkers : true,
950
- /**
951
- * Directory containing the default worker scripts (z-worker.js, deflate.js, and inflate.js), relative to current base url.
952
- * E.g.: zip.workerScripts = './';
953
- */
954
- workerScriptsPath : null,
955
- /**
956
- * Advanced option to control which scripts are loaded in the Web worker. If this option is specified, then workerScriptsPath must not be set.
957
- * workerScripts.deflater/workerScripts.inflater should be arrays of urls to scripts for deflater/inflater, respectively.
958
- * Scripts in the array are executed in order, and the first one should be z-worker.js, which is used to start the worker.
959
- * All urls are relative to current base url.
960
- * E.g.:
961
- * zip.workerScripts = {
962
- * deflater: ['z-worker.js', 'deflate.js'],
963
- * inflater: ['z-worker.js', 'inflate.js']
964
- * };
965
- */
966
- workerScripts : null,
967
- };
968
-
969
- })(this);