diff --git a/style.css b/css/style.css similarity index 76% rename from style.css rename to css/style.css index 97d753a79b4a614fb3b6b58ccab975b4bcb97b8a..d7a4b83141a26120d1f65e14bb114a42522a35ef 100644 --- a/style.css +++ b/css/style.css @@ -66,4 +66,24 @@ height: 80vh; overflow-x: hidden; transition: 0.5s; +} + +#dialog { + display: none; +} + +#clickOpen { + font-family: monospace; + font-size: larger; + background-color: orangered; + color: white; + width: 20vw; + text-align: center; + border-color: white; + border-style: dotted; + border-width: 5px; + border-radius: 10px; + margin-left: 2vw; + margin-right: 2vw; + cursor: pointer; } \ No newline at end of file diff --git a/index.html b/index.html index 525d66b587b75259c86003a97f5b78a51a0d84ce..3984b521516649f1c73f7471469746f2cb41ba4d 100644 --- a/index.html +++ b/index.html @@ -3,11 +3,15 @@ <head> <title>ProgGIS</title> - <link rel="stylesheet" href="style.css" /> + <link rel="stylesheet" href="css/style.css"/> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="" /> <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script> + <script src="https://unpkg.com/shpjs@latest/dist/shp.js"></script> + <script src="javascript/catiline.js"></script> + <script src="javascript/leaflet.shpfile.js"></script> + </head> <body class="standard"> @@ -45,96 +49,105 @@ </svg> </div> - <div style="margin-left: 10px; font-size: 18px;"> - <p>Hei<br>pÃ¥<br>deg!<br><br>Hu<br>og<br>Hei :)</p> + <div style="margin-left: 10px; margin-top: 5px; margin-bottom: 5px;"> + <input type="file" none="dialog" id="dialog" multiple> + <button id="clickOpen" onclick="clickMe()">Click here to open new layers</button> + </div> + + <div style="margin-left: 10px; font-size: 18px; height: 50vh;"> + <p id="layers"></p> </div> </div> <div id="map" style="position: relative; z-index: 1; height: 80vh;"> - <div style="display: flex; flex-grow: 2; flex-direction: column;"> - <div style="height: 72vh;"> - <div id="bufferBox" class="box"> - <div class="box3"> - <h1 style="font-size: 4vh; text-align: center; width: 36vw;">Buffer</h1> - - <svg style="cursor: pointer; padding-top: 15px;" onclick="closeBox('bufferBox')" - xmlns="http://www.w3.org/2000/svg" width="3vw" height="3vw" fill="currentColor" class="bi bi-x-circle-fill" viewBox="0 0 16 16"> - <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/> - </svg> + <div id="drop_zone"> + <div style="display: flex; flex-grow: 2; flex-direction: column;"> + <div style="height: 72vh;"> + <div id="bufferBox" class="box"> + <div class="box3"> + <h1 style="font-size: 4vh; text-align: center; width: 36vw;">Buffer</h1> + + <svg style="cursor: pointer; padding-top: 15px;" onclick="closeBox('bufferBox')" + xmlns="http://www.w3.org/2000/svg" width="3vw" height="3vw" fill="currentColor" class="bi bi-x-circle-fill" viewBox="0 0 16 16"> + <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/> + </svg> + </div> </div> - </div> - <div id="intersectionBox" class="box"> - <div class="box3"> - <h1 style="font-size: 4vh; text-align: center; width: 36vw;">Intersection</h1> - - <svg style="cursor: pointer; padding-top: 15px;" onclick="closeBox('intersectionBox')" - xmlns="http://www.w3.org/2000/svg" width="3vw" height="3vw" fill="currentColor" class="bi bi-x-circle-fill" viewBox="0 0 16 16"> - <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/> - </svg> + <div id="intersectionBox" class="box"> + <div class="box3"> + <h1 style="font-size: 4vh; text-align: center; width: 36vw;">Intersection</h1> + + <svg style="cursor: pointer; padding-top: 15px;" onclick="closeBox('intersectionBox')" + xmlns="http://www.w3.org/2000/svg" width="3vw" height="3vw" fill="currentColor" class="bi bi-x-circle-fill" viewBox="0 0 16 16"> + <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/> + </svg> + </div> </div> - </div> - <div id="unionBox" class="box"> - <div class="box3"> - <h1 style="font-size: 4vh; text-align: center; width: 36vw;">Union</h1> - - <svg style="cursor: pointer; padding-top: 15px;" onclick="closeBox('unionBox')" - xmlns="http://www.w3.org/2000/svg" width="3vw" height="3vw" fill="currentColor" class="bi bi-x-circle-fill" viewBox="0 0 16 16"> - <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/> - </svg> + <div id="unionBox" class="box"> + <div class="box3"> + <h1 style="font-size: 4vh; text-align: center; width: 36vw;">Union</h1> + + <svg style="cursor: pointer; padding-top: 15px;" onclick="closeBox('unionBox')" + xmlns="http://www.w3.org/2000/svg" width="3vw" height="3vw" fill="currentColor" class="bi bi-x-circle-fill" viewBox="0 0 16 16"> + <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/> + </svg> + </div> </div> - </div> - <div id="differenceBox" class="box"> - <div class="box3"> - <h1 style="font-size: 4vh; text-align: center; width: 36vw;">Difference</h1> - - <svg style="cursor: pointer; padding-top: 15px;" onclick="closeBox('differenceBox')" - xmlns="http://www.w3.org/2000/svg" width="3vw" height="3vw" fill="currentColor" class="bi bi-x-circle-fill" viewBox="0 0 16 16"> - <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/> - </svg> + <div id="differenceBox" class="box"> + <div class="box3"> + <h1 style="font-size: 4vh; text-align: center; width: 36vw;">Difference</h1> + + <svg style="cursor: pointer; padding-top: 15px;" onclick="closeBox('differenceBox')" + xmlns="http://www.w3.org/2000/svg" width="3vw" height="3vw" fill="currentColor" class="bi bi-x-circle-fill" viewBox="0 0 16 16"> + <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/> + </svg> + </div> </div> - </div> - <div id="tutorialBox" class="box"> - <div class="box3"> - <h1 style="font-size: 4vh; text-align: center; width: 36vw;">Tutorial</h1> + <div id="tutorialBox" class="box"> + <div class="box3"> + <h1 style="font-size: 4vh; text-align: center; width: 36vw;">Tutorial</h1> + + <svg style="cursor: pointer; padding-top: 15px;" onclick="closeBox('tutorialBox')" + xmlns="http://www.w3.org/2000/svg" width="3vw" height="3vw" fill="currentColor" class="bi bi-x-circle-fill" viewBox="0 0 16 16"> + <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/> + </svg> + </div> - <svg style="cursor: pointer; padding-top: 15px;" onclick="closeBox('tutorialBox')" - xmlns="http://www.w3.org/2000/svg" width="3vw" height="3vw" fill="currentColor" class="bi bi-x-circle-fill" viewBox="0 0 16 16"> - <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/> - </svg> + <p style="margin: 2vw; padding: 5px; background-color: white; border-color: black; + border-width: 2px; color: black; height: 18vh; width: 35vw; text-align: left;"> + Legg til piler pÃ¥ hver side av 'Tutorial' for Ã¥ navigere rundt blant de ulike tutorialene. + </p> </div> - - <textarea style="margin: 2vw; padding: 5px; background-color: white; border-color: black; - border-width: 2px; color: black; height: 18vh; width: 35vw; text-align: left;"> -Legg til piler pÃ¥ hver side av 'Tutorial' for Ã¥ navigere rundt blant de ulike tutorialene. - </textarea> </div> - </div> - <div class="box2"> - <div style="padding-left: 2vw;"> - <svg style="cursor: pointer; border: none; position: absolute; color: orangered; z-index: 999;" onclick="openNav()" - xmlns="http://www.w3.org/2000/svg" width="6vh" height="6vh" fill="currentColor" class="bi bi-plus-circle-fill" viewBox="0 0 16 16"> - <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.5 4.5a.5.5 0 0 0-1 0v3h-3a.5.5 0 0 0 0 1h3v3a.5.5 0 0 0 1 0v-3h3a.5.5 0 0 0 0-1h-3v-3z"/> - </svg> - </div> + <div class="box2"> + <div style="padding-left: 2vw;"> + <svg style="cursor: pointer; border: none; position: absolute; color: orangered; z-index: 999;" onclick="openNav()" + xmlns="http://www.w3.org/2000/svg" width="6vh" height="6vh" fill="currentColor" class="bi bi-plus-circle-fill" viewBox="0 0 16 16"> + <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.5 4.5a.5.5 0 0 0-1 0v3h-3a.5.5 0 0 0 0 1h3v3a.5.5 0 0 0 1 0v-3h3a.5.5 0 0 0 0-1h-3v-3z"/> + </svg> + </div> - <div style="width: 95vw;"></div> - - <div style="padding-right: 2vw;"> - <svg style="cursor: pointer; border: none; position: relative; color: orangered; z-index: 999;" onclick="openBox('tutorialBox')" - xmlns="http://www.w3.org/2000/svg" width="6vh" height="6v" fill="currentColor" class="bi bi-question-circle-fill" viewBox="0 0 16 16"> - <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.496 6.033h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286a.237.237 0 0 0 .241.247zm2.325 6.443c.61 0 1.029-.394 1.029-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94 0 .533.425.927 1.01.927z"/> - </svg> + <div style="width: 95vw;"></div> + + <div style="padding-right: 2vw;"> + <svg style="cursor: pointer; border: none; position: relative; color: orangered; z-index: 999;" onclick="openBox('tutorialBox')" + xmlns="http://www.w3.org/2000/svg" width="6vh" height="6v" fill="currentColor" class="bi bi-question-circle-fill" viewBox="0 0 16 16"> + <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.496 6.033h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286a.237.237 0 0 0 .241.247zm2.325 6.443c.61 0 1.029-.394 1.029-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94 0 .533.425.927 1.01.927z"/> + </svg> + </div> </div> </div> </div> </div> + + <script src="javascript/map.js"></script> + <script src="javascript/sidebar&boxes.js"></script> + <script src="javascript/openFileFromExplorer.js"></script> + </body> </html> - -<script src="javascript/map.js"></script> -<script src="javascript/sidebar&boxes.js"></script> \ No newline at end of file diff --git a/javascript/catiline.js b/javascript/catiline.js new file mode 100644 index 0000000000000000000000000000000000000000..e9602379094aaf73457a791f1833b2d3387296f2 --- /dev/null +++ b/javascript/catiline.js @@ -0,0 +1,769 @@ +/*! catiline 2.4.2 2013-08-08*/ +/*!©2013 Calvin Metcalf @license MIT https://github.com/calvinmetcalf/catiline */ +if (typeof document === 'undefined') { + self._noTransferable=true; + self.onmessage=function(e){ + /*jslint evil: true */ + eval(e.data); + }; +} else { +(function(global){ + 'use strict'; +/*!From setImmediate Copyright (c) 2012 Barnesandnoble.com,llc, Donavon West, and Domenic Denicola @license MIT https://github.com/NobleJS/setImmediate */ +(function(attachTo,global) { + var tasks = (function () { + function Task(handler, args) { + this.handler = handler; + this.args = args; + } + Task.prototype.run = function () { + // See steps in section 5 of the spec. + if (typeof this.handler === 'function') { + // Choice of `thisArg` is not in the setImmediate spec; `undefined` is in the setTimeout spec though: + // http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html + this.handler.apply(undefined, this.args); + } else { + var scriptSource = '' + this.handler; + /*jshint evil: true */ + eval(scriptSource); + } + }; + + var nextHandle = 1; // Spec says greater than zero + var tasksByHandle = {}; + var currentlyRunningATask = false; + + return { + addFromSetImmediateArguments: function (args) { + var handler = args[0]; + var argsToHandle = Array.prototype.slice.call(args, 1); + var task = new Task(handler, argsToHandle); + + var thisHandle = nextHandle++; + tasksByHandle[thisHandle] = task; + return thisHandle; + }, + runIfPresent: function (handle) { + // From the spec: 'Wait until any invocations of this algorithm started before this one have completed.' + // So if we're currently running a task, we'll need to delay this invocation. + if (!currentlyRunningATask) { + var task = tasksByHandle[handle]; + if (task) { + currentlyRunningATask = true; + try { + task.run(); + } finally { + delete tasksByHandle[handle]; + currentlyRunningATask = false; + } + } + } else { + // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a + // 'too much recursion' error. + global.setTimeout(function () { + tasks.runIfPresent(handle); + }, 0); + } + }, + remove: function (handle) { + delete tasksByHandle[handle]; + } + }; + }()); + // Installs an event handler on `global` for the `message` event: see + // * https://developer.mozilla.org/en/DOM/window.postMessage + // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages + + var MESSAGE_PREFIX = 'com.catilinejs.setImmediate' + Math.random(); + + function isStringAndStartsWith(string, putativeStart) { + return typeof string === 'string' && string.substring(0, putativeStart.length) === putativeStart; + } + + function onGlobalMessage(event) { + // This will catch all incoming messages (even from other windows!), so we need to try reasonably hard to + // avoid letting anyone else trick us into firing off. We test the origin is still this window, and that a + // (randomly generated) unpredictable identifying prefix is present. + if (event.source === global && isStringAndStartsWith(event.data, MESSAGE_PREFIX)) { + var handle = event.data.substring(MESSAGE_PREFIX.length); + tasks.runIfPresent(handle); + } + } + if (global.addEventListener) { + global.addEventListener('message', onGlobalMessage, false); + } else { + global.attachEvent('onmessage', onGlobalMessage); + } + + attachTo.setImmediate = function () { + var handle = tasks.addFromSetImmediateArguments(arguments); + + // Make `global` post a message to itself with the handle and identifying prefix, thus asynchronously + // invoking our onGlobalMessage listener above. + global.postMessage(MESSAGE_PREFIX + handle, '*'); + + return handle; + }; + })(catiline,global); + +/*! Promiscuous ©2013 Ruben Verborgh @license MIT https://github.com/RubenVerborgh/promiscuous*/ +(function (exports,tick) { + var func = 'function'; + // Creates a deferred: an object with a promise and corresponding resolve/reject methods + function Deferred() { + // The `handler` variable points to the function that will + // 1) handle a .then(onFulfilled, onRejected) call + // 2) handle a .resolve or .reject call (if not fulfilled) + // Before 2), `handler` holds a queue of callbacks. + // After 2), `handler` is a simple .then handler. + // We use only one function to save memory and complexity. + var handler = function (onFulfilled, onRejected, value) { + // Case 1) handle a .then(onFulfilled, onRejected) call + var createdDeffered; + if (onFulfilled !== handler) { + createdDeffered = createDeferred(); + handler.queue.push({ deferred: createdDeffered, resolve: onFulfilled, reject: onRejected }); + return createdDeffered.promise; + } + + // Case 2) handle a .resolve or .reject call + // (`onFulfilled` acts as a sentinel) + // The actual function signature is + // .re[ject|solve](sentinel, success, value) + var action = onRejected ? 'resolve' : 'reject',queue,deferred,callback; + for (var i = 0, l = handler.queue.length; i < l; i++) { + queue = handler.queue[i]; + deferred = queue.deferred; + callback = queue[action]; + if (typeof callback !== func) { + deferred[action](value); + } else { + execute(callback, value, deferred); + } + } + // Replace this handler with a simple resolved or rejected handler + handler = createHandler(promise, value, onRejected); + }; + function Promise(){ + this.then=function (onFulfilled, onRejected) { + return handler(onFulfilled, onRejected); + }; + } + var promise = new Promise(); + this.promise = promise; + // The queue of deferreds + handler.queue = []; + + this.resolve = function (value) { + handler.queue && handler(handler, true, value); + }; + + this.reject = function (reason) { + handler.queue && handler(handler, false, reason); + }; + } + + function createDeferred(){ + return new Deferred(); + } + + // Creates a fulfilled or rejected .then function + function createHandler(promise, value, success) { + return function (onFulfilled, onRejected) { + var callback = success ? onFulfilled : onRejected, result; + if (typeof callback !== func) { + return promise; + } + execute(callback, value, result = createDeferred()); + return result.promise; + }; + } + + // Executes the callback with the specified value, + // resolving or rejecting the deferred + function execute(callback, value, deferred) { + tick(function () { + var result; + try { + result = callback(value); + if (result && typeof result.then === func) { + result.then(deferred.resolve, deferred.reject); + } else { + deferred.resolve(result); + } + } + catch (error) { + deferred.reject(error); + } + }); + } + + // Returns a resolved promise + exports.resolve= function (value) { + var promise = {}; + promise.then = createHandler(promise, value, true); + return promise; + }; + // Returns a rejected promise + exports.reject= function (reason) { + var promise = {}; + promise.then = createHandler(promise, reason, false); + return promise; + }; + // Returns a deferred + exports.deferred= createDeferred; + exports.all=function(array){ + var promise = exports.deferred(); + var len = array.length; + var resolved=0; + var out = []; + var onSuccess=function(n){ + return function(v){ + out[n]=v; + resolved++; + if(resolved===len){ + promise.resolve(out); + } + }; + }; + array.forEach(function(v,i){ + v.then(onSuccess(i),function(a){ + promise.reject(a); + }); + }); + return promise.promise; + }; +})(catiline,catiline.setImmediate); + +catiline._hasWorker = typeof Worker !== 'undefined'&&typeof fakeLegacy === 'undefined'; +catiline.URL = window.URL || window.webkitURL; +catiline._noTransferable=!catiline.URL; +//regex out the importScript call and move it up to the top out of the function. +function regexImports(string){ + var rest=string, + match = true, + matches = {}, + loopFunc = function(a,b){ + if(b){ + 'importScripts('+b.split(',').forEach(function(cc){ + matches[catiline.makeUrl(cc.match(/\s*[\'\"](\S*)[\'\"]\s*/)[1])]=true; // trim whitespace, add to matches + })+');\n'; + } + }; + while(match){ + match = rest.match(/(importScripts\(.*?\);?)/); + rest = rest.replace(/(importScripts\(\s*(?:[\'\"].*?[\'\"])?\s*\);?)/,'\n'); + if(match){ + match[0].replace(/importScripts\(\s*([\'\"].*?[\'\"])?\s*\);?/g,loopFunc); + } + } + matches = Object.keys(matches); + return [matches,rest]; +} + +function moveImports(string){ + var str = regexImports(string); + var matches = str[0]; + var rest = str[1]; + if(matches.length>0){ + return 'importScripts(\''+matches.join('\',\'')+'\');\n'+rest; + }else{ + return rest; + } +} +function moveIimports(string){ + var str = regexImports(string); + var matches = str[0]; + var rest = str[1]; + if(matches.length>0){ + return 'importScripts(\''+matches.join('\',\'')+'\');eval(__scripts__);\n'+rest; + }else{ + return rest; + } +} +function getPath(){ + if(typeof SHIM_WORKER_PATH !== 'undefined'){ + return SHIM_WORKER_PATH; + }else if('SHIM_WORKER_PATH' in catiline){ + return catiline.SHIM_WORKER_PATH; + } + var scripts = document.getElementsByTagName('script'); + var len = scripts.length; + var i = 0; + while(i<len){ + if(/catiline(\.min)?\.js/.test(scripts[i].src)){ + return scripts[i].src; + } + i++; + } +} +function appendScript(iDoc,text){ + var iScript = iDoc.createElement('script'); + if (typeof iScript.text !== 'undefined') { + iScript.text = text; + } else { + iScript.innerHTML = text; + } + if(iDoc.readyState==='complete'){ + iDoc.documentElement.appendChild(iScript); + }else{ + iDoc.onreadystatechange=function(){ + if(iDoc.readyState==='complete'){ + iDoc.documentElement.appendChild(iScript); + } + }; + } +} +//much of the iframe stuff inspired by https://github.com/padolsey/operative +//mos tthings besides the names have since been changed +function actualMakeI(script,codeword){ + var iFrame = document.createElement('iframe'); + iFrame.style.display = 'none'; + document.body.appendChild(iFrame); + var iWin = iFrame.contentWindow; + var iDoc = iWin.document; + var text=['try{ ', + 'var __scripts__=\'\';function importScripts(scripts){', + ' if(Array.isArray(scripts)&&scripts.length>0){', + ' scripts.forEach(function(url){', + ' var ajax = new XMLHttpRequest();', + ' ajax.open(\'GET\',url,false);', + ' ajax.send();__scripts__+=ajax.responseText;', + ' __scripts__+=\'\\n;\';', + ' });', + ' }', + '};', + script, + '}catch(e){', + ' window.parent.postMessage([\''+codeword+'\',\'error\'],\'*\')', + '}'].join('\n'); + appendScript(iDoc,text); + + return iFrame; +} +function makeIframe(script,codeword){ + var promise = catiline.deferred(); + if(document.readyState==='complete'){ + promise.resolve(actualMakeI(script,codeword)); + }else{ + window.addEventListener('load',function(){ + promise.resolve(actualMakeI(script,codeword)); + },false); + } + return promise.promise; +} +catiline.makeIWorker = function (strings,codeword){ + var script =moveIimports(strings.join('')); + var worker = {onmessage:function(){}}; + var ipromise = makeIframe(script,codeword); + window.addEventListener('message',function(e){ + if(typeof e.data ==='string'&&e.data.length>codeword.length&&e.data.slice(0,codeword.length)===codeword){ + worker.onmessage({data:JSON.parse(e.data.slice(codeword.length))}); + } + }); + worker.postMessage=function(data){ + ipromise.then(function(iFrame){ + iFrame.contentWindow.postMessage(JSON.stringify(data),'*'); + }); + }; + worker.terminate=function(){ + ipromise.then(function(iFrame){ + document.body.removeChild(iFrame); + }); + }; + return worker; + +}; +//accepts an array of strings, joins them, and turns them into a worker. +function makeFallbackWorker(script){ + catiline._noTransferable=true; + var worker = new Worker(getPath()); + worker.postMessage(script); + return worker; +} +catiline.makeWorker = function (strings, codeword){ + if(!catiline._hasWorker){ + return catiline.makeIWorker(strings,codeword); + } + var worker; + var script =moveImports(strings.join('')); + if(catiline._noTransferable){ + return makeFallbackWorker(script); + } + try{ + worker= new Worker(catiline.URL.createObjectURL(new Blob([script],{type: 'text/javascript'}))); + }catch(e){ + try{ + worker=makeFallbackWorker(script); + }catch(ee){ + worker = catiline.makeIWorker(strings,codeword); + } + }finally{ + return worker; + } +}; + +catiline.makeUrl = function (fileName) { + var link = document.createElement('link'); + link.href = fileName; + return link.href; +}; + +catiline.Worker = function Catiline(obj) { + if(typeof obj === 'function'){ + obj = { + data:obj + }; + } + var __codeWord__='com.catilinejs.'+(catiline._hasWorker?'iframe':'worker')+Math.random(); + var listeners = {}; + var self = this; + self.on = function (eventName, func, scope) { + scope = scope || self; + if (eventName.indexOf(' ') > 0) { + eventName.split(' ').map(function (v) { + return self.on(v, func, scope); + }, this); + return self; + } + if (!(eventName in listeners)) { + listeners[eventName] = []; + } + listeners[eventName].push(function (a) { + func.call(scope, a); + }); + return self; + }; + + function _fire(eventName, data) { + if (eventName.indexOf(' ') > 0) { + eventName.split(' ').forEach(function (v) { + _fire(v, data); + }); + return self; + } + if (!(eventName in listeners)) { + return self; + } + listeners[eventName].forEach(function (v) { + v(data); + }); + return self; + } + self.fire = function (eventName, data, transfer) { + if(catiline._noTransferable){ + worker.postMessage([[eventName], data]); + }else{ + worker.postMessage([[eventName], data], transfer); + } + + return self; + }; + self.off = function (eventName, func) { + if (eventName.indexOf(' ') > 0) { + eventName.split(' ').map(function (v) { + return self.off(v, func); + }); + return self; + } + if (!(eventName in listeners)) { + return self; + } + else if (!func) { + delete listeners[eventName]; + } + else { + if (listeners[eventName].indexOf(func) > -1) { + if (listeners[eventName].length > 1) { + delete listeners[eventName]; + } + else { + listeners[eventName].splice(listeners[eventName].indexOf(func), 1); + } + } + } + return self; + }; + var i = 0; + var promises = []; + var rejectPromises = function (msg) { + if (typeof msg !== 'string' && 'preventDefault' in msg) { + msg.preventDefault(); + msg = msg.message; + } + promises.forEach(function (p) { + if (p) { + p.reject(msg); + } + }); + }; + obj.__codeWord__='"'+__codeWord__+'"'; + if (!('initialize' in obj)) { + if ('init' in obj) { + obj.initialize = obj.init; + } + else { + obj.initialize = function () {}; + } + } + var fObj = '{\n\t'; + var keyFunc = function (key) { + var out = function (data, transfer) { + var i = promises.length; + promises[i] = catiline.deferred(); + if(catiline._noTransferable){ + worker.postMessage([[__codeWord__, i], key, data]); + }else{ + worker.postMessage([[__codeWord__, i], key, data], transfer); + } + return promises[i].promise; + }; + return out; + }; + for (var key in obj) { + if (i !== 0) { + fObj = fObj + ',\n\t'; + } + else { + i++; + } + fObj = fObj + key + ':' + obj[key].toString(); + self[key] = keyFunc(key); + } + fObj = fObj + '}'; + var worker = catiline.makeWorker(['\'use strict\';\n\nvar _db = ',fObj,';\nvar listeners = {};\nvar __iFrame__ = typeof document!=="undefined";\nvar __self__={onmessage:function(e){\n _fire("messege",e.data[1]);\n if(e.data[0][0]===_db.__codeWord__){\n return regMsg(e);\n }else{\n _fire(e.data[0][0],e.data[1]);\n }\n}};\nif(__iFrame__){\n window.onmessage=function(e){\n if(typeof e.data === "string"){\n e ={data: JSON.parse(e.data)};\n }\n __self__.onmessage(e);\n };\n}else{\n self.onmessage=__self__.onmessage;\n}\n__self__.postMessage=function(rawData, transfer){\n var data;\n if(!self._noTransferable&&!__iFrame__){\n self.postMessage(rawData, transfer);\n }else if(__iFrame__){\n data = _db.__codeWord__+JSON.stringify(rawData);\n window.parent.postMessage(data,"*");\n }else if(self._noTransferable){\n self.postMessage(rawData);\n }\n};\n_db.on = function (eventName, func, scope) {\n if(eventName.indexOf(" ")>0){\n return eventName.split(" ").map(function(v){\n return _db.on(v,func,scope);\n },_db);\n }\n scope = scope || _db;\n if (!(eventName in listeners)) {\n listeners[eventName] = [];\n }\n listeners[eventName].push(function (a) {\n func.call(scope, a, _db);\n });\n};\nfunction _fire(eventName,data){\n if(eventName.indexOf(" ")>0){\n eventName.split(" ").forEach(function(v){\n _fire(v,data);\n });\n return;\n }\n if (!(eventName in listeners)) {\n return;\n }\n listeners[eventName].forEach(function (v) {\n v(data);\n });\n}\n\n_db.fire = function (eventName, data, transfer) {\n __self__.postMessage([[eventName], data], transfer);\n};\n_db.off=function(eventName,func){\n if(eventName.indexOf(" ")>0){\n return eventName.split(" ").map(function(v){\n return _db.off(v,func);\n });\n }\n if(!(eventName in listeners)){\n return;\n }else if(!func){\n delete listeners[eventName];\n }else{\n if(listeners[eventName].indexOf(func)>-1){\n if(listeners[eventName].length>1){\n delete listeners[eventName];\n }else{\n listeners[eventName].splice(listeners[eventName].indexOf(func),1);\n }\n }\n }\n};\nvar console={};\nfunction makeConsole(method){\n return function(){\n var len = arguments.length;\n var out =[];\n var i = 0;\n while (i<len){\n out.push(arguments[i]);\n i++;\n }\n _db.fire("console",[method,out]);\n };\n}\n["log", "debug", "error", "info", "warn", "time", "timeEnd"].forEach(function(v){\n console[v]=makeConsole(v);\n});\nvar regMsg = function(e){\n var cb=function(data,transfer){\n __self__.postMessage([e.data[0],data],transfer);\n };\n var result;\n if(__iFrame__){\n try{\n result = _db[e.data[1]](e.data[2],cb,_db);\n }catch(e){\n _db.fire("error",JSON.stringify(e));\n }\n }else{\n result = _db[e.data[1]](e.data[2],cb,_db);\n }\n if(typeof result !== "undefined"){\n cb(result);\n }\n};\n_db.initialize(_db);\n'],__codeWord__); + worker.onmessage = function (e) { + _fire('message', e.data[1]); + if (e.data[0][0] === __codeWord__) { + promises[e.data[0][1]].resolve(e.data[1]); + promises[e.data[0][1]] = 0; + } + else { + _fire(e.data[0][0], e.data[1]); + } + }; + self.on('error',rejectPromises); + worker.onerror = function (e) { + _fire('error', e); + }; + self.on('console', function (msg) { + console[msg[0]].apply(console, msg[1]); + }); + self._close = function () { + worker.terminate(); + rejectPromises('closed'); + return catiline.resolve(); + }; + if (!('close' in self)) { + self.close = self._close; + } + }; +catiline.worker = function (obj){ + return new catiline.Worker(obj); +}; + +catiline.Queue = function CatilineQueue(obj, n, dumb) { + var self = this; + self.__batchcb__ = {}; + self.__batchtcb__ = {}; + self.batch = function (cb) { + if (typeof cb === 'function') { + self.__batchcb__.__cb__ = cb; + return self.__batchcb__; + } + else { + return clearQueue(cb); + } + }; + self.batchTransfer = function (cb) { + if (typeof cb === 'function') { + self.__batchtcb__.__cb__ = cb; + return self.__batchtcb__; + } + else { + return clearQueue(cb); + } + }; + var workers = new Array(n); + var numIdle = 0; + var idle = []; + var que = []; + var queueLen = 0; + while (numIdle < n) { + workers[numIdle] = new catiline.Worker(obj); + idle.push(numIdle); + numIdle++; + } + self.on = function (eventName, func, context) { + workers.forEach(function (worker) { + worker.on(eventName, func, context); + }); + return self; + }; + self.off = function (eventName, func, context) { + workers.forEach(function (worker) { + worker.off(eventName, func, context); + }); + return self; + }; + var batchFire = function (eventName, data) { + workers.forEach(function (worker) { + worker.fire(eventName, data); + }); + return self; + }; + self.fire = function (eventName, data) { + workers[~~ (Math.random() * n)].fire(eventName, data); + return self; + }; + self.batch.fire = batchFire; + self.batchTransfer.fire = batchFire; + + function clearQueue(mgs) { + mgs = mgs || 'canceled'; + queueLen = 0; + var oQ = que; + que = []; + oQ.forEach(function (p) { + p[3].reject(mgs); + }); + return self; + } + + function keyFunc(k) { + return function (data, transfer) { + return doStuff(k, data, transfer); + }; + } + + function keyFuncBatch(k) { + return function (array) { + return catiline.all(array.map(function (data) { + return doStuff(k, data); + })); + }; + } + + function keyFuncBatchCB(k) { + return function (array) { + var self = this; + return catiline.all(array.map(function (data) { + return doStuff(k, data).then(self.__cb__); + })); + }; + } + + function keyFuncBatchTransfer(k) { + return function (array) { + return catiline.all(array.map(function (data) { + return doStuff(k, data[0], data[1]); + })); + }; + } + + function keyFuncBatchTransferCB(k) { + return function (array) { + var self = this; + return catiline.all(array.map(function (data) { + return doStuff(k, data[0], data[1]).then(self.__cb__); + })); + }; + } + for (var key in obj) { + self[key] = keyFunc(key); + self.batch[key] = keyFuncBatch(key); + self.__batchcb__[key] = keyFuncBatchCB(key); + self.batchTransfer[key] = keyFuncBatchTransfer(key); + self.__batchtcb__[key] = keyFuncBatchTransferCB(key); + } + + function done(num) { + var data; + if (queueLen) { + data = que.shift(); + queueLen--; + workers[num][data[0]](data[1], data[2]).then(function (d) { + done(num); + data[3].resolve(d); + }, function (d) { + done(num); + data[3].reject(d); + }); + } + else { + numIdle++; + idle.push(num); + } + } + + function doStuff(key, data, transfer) { //srsly better name! + if (dumb) { + return workers[~~ (Math.random() * n)][key](data, transfer); + } + var promise = catiline.deferred(), + num; + if (!queueLen && numIdle) { + num = idle.pop(); + numIdle--; + workers[num][key](data, transfer).then(function (d) { + done(num); + promise.resolve(d); + }, function (d) { + done(num); + promise.reject(d); + }); + } + else if (queueLen || !numIdle) { + queueLen = que.push([key, data, transfer, promise]); + } + return promise.promise; + } + self._close = function () { + return catiline.all(workers.map(function (w) { + return w._close(); + })); + }; + if (!('close' in self)) { + self.close = self._close; + } +}; +catiline.queue = function (obj, n, dumb) { + return new catiline.Queue(obj, n, dumb); +}; + +function catiline(object,queueLength,unmanaged){ + if(arguments.length === 1 || !queueLength || queueLength <= 1){ + return new catiline.Worker(object); + }else{ + return new catiline.Queue(object,queueLength,unmanaged); + } +} + +function initBrowser(catiline){ + var origCW = global.cw; + catiline.noConflict=function(newName){ + global.cw = origCW; + if(newName){ + global[newName]=catiline; + } + }; + global.catiline = catiline; + global.cw = catiline; + if(!('communist' in global)){ + global.communist=catiline; + } + +} + +if(typeof define === 'function'){ + define(function(require){ + catiline.SHIM_WORKER_PATH=require.toUrl('./catiline.js'); + return catiline; + }); +}else if(typeof module === 'undefined' || !('exports' in module)){ + initBrowser(catiline); +} else { + module.exports=catiline; +} +catiline.version = '2.4.2'; +})(this);} \ No newline at end of file diff --git a/javascript/leaflet.shpfile.js b/javascript/leaflet.shpfile.js new file mode 100644 index 0000000000000000000000000000000000000000..b09ed6cea03bef57675ca1c601ab16cff973cbb3 --- /dev/null +++ b/javascript/leaflet.shpfile.js @@ -0,0 +1,63 @@ +'use strict'; + +/* global cw, shp */ +L.Shapefile = L.GeoJSON.extend({ + options: { + importUrl: 'javascript/shp.js' + }, + + initialize: function(file, options) { + L.Util.setOptions(this, options); + if (typeof cw !== 'undefined') { + /*eslint-disable no-new-func*/ + if (!options.isArrayBuffer) { + this.worker = cw(new Function('data', 'cb', 'importScripts("' + this.options.importUrl + '");shp(data).then(cb);')); + } else { + this.worker = cw(new Function('data', 'importScripts("' + this.options.importUrl + '"); return shp.parseZip(data);')); + } + /*eslint-enable no-new-func*/ + } + L.GeoJSON.prototype.initialize.call(this, { + features: [] + }, options); + this.addFileData(file); + }, + + addFileData: function(file) { + var self = this; + this.fire('data:loading'); + if (typeof file !== 'string' && !('byteLength' in file)) { + var data = this.addData(file); + this.fire('data:loaded'); + return data; + } + if (!this.worker) { + shp(file).then(function(data) { + self.addData(data); + self.fire('data:loaded'); + }).catch(function(err) { + self.fire('data:error', err); + }) + return this; + } + var promise; + if (this.options.isArrayBufer) { + promise = this.worker.data(file, [file]); + } else { + promise = this.worker.data(cw.makeUrl(file)); + } + + promise.then(function(data) { + self.addData(data); + self.fire('data:loaded'); + self.worker.close(); + }).then(function() {}, function(err) { + self.fire('data:error', err); + }) + return this; + } +}); + +L.shapefile = function(a, b, c) { + return new L.Shapefile(a, b, c); +}; diff --git a/javascript/map.js b/javascript/map.js index b3e3b4816956abf99641db3b589449b90e75f7b5..f476ddab568827090b34d8eb233e772c67a1810c 100644 --- a/javascript/map.js +++ b/javascript/map.js @@ -1,21 +1,38 @@ -// Bestemme URL til basiskartet: -var osm_map = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { - attribution: '© <a href="https://www.openstreetmap.org/copyright"<OpenStreetMap</a> contributors' -}); - // Initialiserer kartet: var map = L.map('map', { - layers: [osm_map], // Default basiskart maxZoom: 18, // Justerer zoom-nivÃ¥et minZoom: 6, zoomControl: false, // Fjerner default zoom-knapper }).setView([63.418529, 10.40284], 13) +// Bestemme URL til basiskartet: +var osm_map = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + attribution: '© <a href="https://www.openstreetmap.org/copyright"<OpenStreetMap</a> contributors' +}); + +// Google Map layer: + +var googleSat = L.tileLayer('http://{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',{ + subdomains:['mt0','mt1','mt2','mt3'] +}); + +osm_map.addTo(map); +googleSat.addTo(map); + // Legger til zoom-knapper pÃ¥ egnet sted L.control.zoom({ position:'topright' }).addTo(map); +// Layer control: + +var baselayers = { + "OpenStreetMap": osm_map, + "Satellite": googleSat +} + +L.control.layers(baselayers).addTo(map) + /* Activate and deactivate interactions in the leaflet map*/ function deactivateMap() { diff --git a/javascript/openFileFromExplorer.js b/javascript/openFileFromExplorer.js new file mode 100644 index 0000000000000000000000000000000000000000..99400118d7567443e33468b5fb3c6430693a23e6 --- /dev/null +++ b/javascript/openFileFromExplorer.js @@ -0,0 +1,32 @@ +const clickOpen = document.getElementById("clickOpen"); // Knappen vi gir funksjonalitet +const dialog = document.getElementById("dialog"); // Input-feltet vi har skjult, men som lagrer dataen som velges + +function clickMe() { + dialog.click(); +} + +dialog.addEventListener("input", () => { + if (dialog.files.length) { + for (i = 0; i < dialog.files.length; i++) { + document.getElementById("layers").innerHTML = dialog.files[i].name; + } + } +}); + +var geo = L.geoJson({features:[]}, { + onEachFeature: function popUp(f, l) { + var out = []; + if (f.properties){ + for(var key in f.properties){ + out.push(key + ": " + f.properties[key]); + } + l.bindPopup(out.join("<br />")); + } +} +}).addTo(map); + +var base = 'vann.zip'; + +shp(base).then(function(data){ + geo.addData(data); +}); diff --git a/javascript/shp.js b/javascript/shp.js new file mode 100644 index 0000000000000000000000000000000000000000..d3c90272d7d3b42a0198b20094f7a28a3ab326e9 --- /dev/null +++ b/javascript/shp.js @@ -0,0 +1,17726 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.shp = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ +'use strict'; +var Promise = require('lie'); +module.exports = binaryAjax; +function binaryAjax(url){ + return new Promise(function(resolve,reject){ + var type = url.slice(-3); + var ajax = new XMLHttpRequest(); + ajax.open('GET',url,true); + if(type !== 'prj'){ + ajax.responseType='arraybuffer'; + } + ajax.addEventListener('load', function (){ + if(ajax.status>399){ + if(type==='prj'){ + return resolve(false); + }else{ + return reject(new Error(ajax.status)); + } + } + resolve(ajax.response); + }, false); + ajax.send(); + }); +} +},{"lie":51}],2:[function(require,module,exports){ +'use strict'; +function isClockWise(array){ + var sum = 0; + var i = 1; + var len = array.length; + var prev,cur; + while(i<len){ + prev = cur||array[0]; + cur = array[i]; + sum += ((cur[0]-prev[0])*(cur[1]+prev[1])); + i++; + } + return sum > 0; +} +function polyReduce(a,b){ + if(isClockWise(b)||!a.length){ + a.push([b]); + }else{ + a[a.length-1].push(b); + } + return a; +} +ParseShp.prototype.parsePoint = function (data){ + return { + 'type': 'Point', + 'coordinates': this.parseCoord(data,0) + }; +}; +ParseShp.prototype.parseZPoint = function (data){ + var pointXY = this.parsePoint(data); + pointXY.coordinates.push(this.parseCoord(data,16)); + return pointXY; +}; +ParseShp.prototype.parsePointArray = function (data,offset,num){ + var out = []; + var done = 0; + while(done<num){ + out.push(this.parseCoord(data,offset)); + offset += 16; + done++; + } + return out; +}; +ParseShp.prototype.parseZPointArray = function (data,zOffset,num,coordinates){ + var i = 0; + while(i<num){ + coordinates[i].push(data.getFloat64(zOffset,true)); + i++; + zOffset += 8; + } + return coordinates; +}; +ParseShp.prototype.parseArrayGroup = function (data,offset,partOffset,num,tot){ + var out = []; + var done = 0; + var curNum,nextNum=0,pointNumber; + while(done<num){ + done++; + partOffset += 4; + curNum = nextNum; + if(done===num){ + nextNum = tot; + }else{ + nextNum = data.getInt32(partOffset,true); + } + pointNumber = nextNum - curNum; + if(!pointNumber){ + continue; + } + out.push(this.parsePointArray(data,offset,pointNumber)); + offset += (pointNumber<<4); + } + return out; +}; +ParseShp.prototype.parseZArrayGroup = function(data,zOffset,num,coordinates){ + var i = 0; + while(i<num){ + coordinates[i] = this.parseZPointArray(data,zOffset,coordinates[i].length,coordinates[i]); + zOffset += (coordinates[i].length<<3); + i++; + } + return coordinates; +}; +ParseShp.prototype.parseMultiPoint = function (data){ + var out = {}; + var mins = this.parseCoord(data,0); + var maxs = this.parseCoord(data,16); + out.bbox = [ + mins[0], + mins[1], + maxs[0], + maxs[1] + ]; + var num = data.getInt32(32,true); + var offset = 36; + if(num===1){ + out.type = 'Point'; + out.coordinates = this.parseCoord(data,offset); + }else{ + out.type = 'MultiPoint'; + out.coordinates = this.parsePointArray(data,offset,num); + } + return out; +}; +ParseShp.prototype.parseZMultiPoint = function(data){ + var geoJson = this.parseMultiPoint(data); + var num; + if(geoJson.type === 'Point'){ + geoJson.coordinates.push(data.getFloat64(72,true)); + return geoJson; + }else{ + num = geoJson.coordinates.length; + } + var zOffset = 56 + (num<<4); + geoJson.coordinates = this.parseZPointArray(data,zOffset,num,geoJson.coordinates); + return geoJson; +}; +ParseShp.prototype.parsePolyline = function (data){ + var out = {}; + var mins = this.parseCoord(data,0); + var maxs = this.parseCoord(data,16); + out.bbox = [ + mins[0], + mins[1], + maxs[0], + maxs[1] + ]; + var numParts = data.getInt32(32,true); + var num = data.getInt32(36,true); + var offset,partOffset; + if(numParts === 1){ + out.type = 'LineString'; + offset = 44; + out.coordinates = this.parsePointArray(data,offset,num); + }else{ + out.type = 'MultiLineString'; + offset = 40 + (numParts<<2); + partOffset = 40; + out.coordinates = this.parseArrayGroup(data,offset,partOffset,numParts,num); + } + return out; +}; +ParseShp.prototype.parseZPolyline = function(data){ + var geoJson = this.parsePolyline(data); + var num = geoJson.coordinates.length; + var zOffset = 60 + (num<<4); + if(geoJson.type === 'LineString'){ + geoJson.coordinates = this.parseZPointArray(data,zOffset,num,geoJson.coordinates); + return geoJson; + }else{ + geoJson.coordinates = this.parseZArrayGroup(data,zOffset,num,geoJson.coordinates); + return geoJson; + } +}; +ParseShp.prototype.polyFuncs = function (out){ + if(out.type === 'LineString'){ + out.type = 'Polygon'; + out.coordinates = [out.coordinates]; + return out; + }else{ + out.coordinates = out.coordinates.reduce(polyReduce,[]); + if(out.coordinates.length === 1){ + out.type = 'Polygon'; + out.coordinates = out.coordinates[0]; + return out; + }else{ + out.type = 'MultiPolygon'; + return out; + } + } +}; +ParseShp.prototype.parsePolygon = function (data){ + return this.polyFuncs(this.parsePolyline(data)); +}; +ParseShp.prototype.parseZPolygon = function(data){ + return this.polyFuncs(this.parseZPolyline(data)); +}; +var shpFuncObj = { + 1:'parsePoint', + 3:'parsePolyline', + 5:'parsePolygon', + 8:'parseMultiPoint', + 11:'parseZPoint', + 13:'parseZPolyline', + 15:'parseZPolygon', + 18:'parseZMultiPoint' +}; + + + +function makeParseCoord(trans){ + if(trans){ + return function(data,offset){ + return trans.inverse([data.getFloat64(offset,true),data.getFloat64(offset+8,true)]); + }; + }else{ + return function(data,offset){ + return [data.getFloat64(offset,true),data.getFloat64(offset+8,true)]; + }; + } +} +function ParseShp(buffer,trans){ + if(!(this instanceof ParseShp)){ + return new ParseShp(buffer,trans); + } + this.buffer = buffer; + this.shpFuncs(trans); + this.rows = this.getRows(); +} +ParseShp.prototype.shpFuncs = function (tran){ + var num = this.getShpCode(); + if(num>20){ + num -= 20; + } + if(!(num in shpFuncObj)){ + throw new Error('I don\'t know that shp type'); + } + this.parseFunc = this[shpFuncObj[num]]; + this.parseCoord = makeParseCoord(tran); +}; +ParseShp.prototype.getShpCode = function(){ + return this.parseHeader().shpCode; +}; +ParseShp.prototype.parseHeader = function (){ + var view = new DataView(this.buffer,0,100) ; + return { + length : view.getInt32(6<<2,false), + version : view.getInt32(7<<2,true), + shpCode : view.getInt32(8<<2,true), + bbox : [ + view.getFloat64(9<<2,true), + view.getFloat64(11<<2,true), + view.getFloat64(13<<2,true), + view.getFloat64(13<<2,true) + ] + }; +}; +ParseShp.prototype.getRows = function(){ + var offset=100; + var len = this.buffer.byteLength; + var out = []; + var current; + while(offset<len){ + current = this.getRow(offset); + offset += 8; + offset += current.len; + if(current.type){ + out.push(this.parseFunc(current.data)); + } + } + return out; +}; +ParseShp.prototype.getRow = function(offset){ + var view = new DataView(this.buffer,offset,12); + var len = view.getInt32(4,false) << 1; + var data = new DataView(this.buffer,offset+12,len - 4); + + return { + id:view.getInt32(0,false), + len:len, + data:data, + type:view.getInt32(8,true) + }; +}; +module.exports = function(buffer, trans){ + return new ParseShp(buffer, trans).rows; +}; +},{}],3:[function(require,module,exports){ +'use strict'; +module.exports = toArrayBuffer; +function toArrayBuffer(buffer) { + var arrayBuffer = new ArrayBuffer(buffer.length); + var view = new Uint8Array(arrayBuffer); + var i = -1; + var len = buffer.length; + while (++i < len) { + view[i] = buffer[i]; + } + return arrayBuffer; +} +},{}],4:[function(require,module,exports){ +'use strict'; + +var JSZip = require('jszip'); +module.exports = function(buffer) { + var zip = new JSZip(buffer); + var files = zip.file(/.+/); + var out = {}; + files.forEach(function(a) { + if (a.name.slice(-3).toLowerCase() === 'shp' || a.name.slice(-3).toLowerCase() === 'dbf') { + out[a.name] = a.asArrayBuffer(); + } + else { + out[a.name] = a.asText(); + } + }); + return out; +}; + +},{"jszip":17}],5:[function(require,module,exports){ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org> + * @license MIT + */ + +var base64 = require('base64-js') +var ieee754 = require('ieee754') +var isArray = require('is-array') + +exports.Buffer = Buffer +exports.SlowBuffer = SlowBuffer +exports.INSPECT_MAX_BYTES = 50 +Buffer.poolSize = 8192 // not used by this implementation + +var rootParent = {} + +/** + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Due to various browser bugs, sometimes the Object implementation will be used even + * when the browser supports typed arrays. + * + * Note: + * + * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. + * + * - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property + * on objects. + * + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + + * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they + * get the Object implementation, which is slower but behaves correctly. + */ +Buffer.TYPED_ARRAY_SUPPORT = (function () { + function Bar () {} + try { + var arr = new Uint8Array(1) + arr.foo = function () { return 42 } + arr.constructor = Bar + return arr.foo() === 42 && // typed array instances can be augmented + arr.constructor === Bar && // constructor can be set + typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` + arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` + } catch (e) { + return false + } +})() + +function kMaxLength () { + return Buffer.TYPED_ARRAY_SUPPORT + ? 0x7fffffff + : 0x3fffffff +} + +/** + * Class: Buffer + * ============= + * + * The Buffer constructor returns instances of `Uint8Array` that are augmented + * with function properties for all the node `Buffer` API functions. We use + * `Uint8Array` so that square bracket notation works as expected -- it returns + * a single octet. + * + * By augmenting the instances, we can avoid modifying the `Uint8Array` + * prototype. + */ +function Buffer (arg) { + if (!(this instanceof Buffer)) { + // Avoid going through an ArgumentsAdaptorTrampoline in the common case. + if (arguments.length > 1) return new Buffer(arg, arguments[1]) + return new Buffer(arg) + } + + this.length = 0 + this.parent = undefined + + // Common case. + if (typeof arg === 'number') { + return fromNumber(this, arg) + } + + // Slightly less common case. + if (typeof arg === 'string') { + return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8') + } + + // Unusual. + return fromObject(this, arg) +} + +function fromNumber (that, length) { + that = allocate(that, length < 0 ? 0 : checked(length) | 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < length; i++) { + that[i] = 0 + } + } + return that +} + +function fromString (that, string, encoding) { + if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8' + + // Assumption: byteLength() return value is always < kMaxLength. + var length = byteLength(string, encoding) | 0 + that = allocate(that, length) + + that.write(string, encoding) + return that +} + +function fromObject (that, object) { + if (Buffer.isBuffer(object)) return fromBuffer(that, object) + + if (isArray(object)) return fromArray(that, object) + + if (object == null) { + throw new TypeError('must start with number, buffer, array or string') + } + + if (typeof ArrayBuffer !== 'undefined') { + if (object.buffer instanceof ArrayBuffer) { + return fromTypedArray(that, object) + } + if (object instanceof ArrayBuffer) { + return fromArrayBuffer(that, object) + } + } + + if (object.length) return fromArrayLike(that, object) + + return fromJsonObject(that, object) +} + +function fromBuffer (that, buffer) { + var length = checked(buffer.length) | 0 + that = allocate(that, length) + buffer.copy(that, 0, 0, length) + return that +} + +function fromArray (that, array) { + var length = checked(array.length) | 0 + that = allocate(that, length) + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +// Duplicate of fromArray() to keep fromArray() monomorphic. +function fromTypedArray (that, array) { + var length = checked(array.length) | 0 + that = allocate(that, length) + // Truncating the elements is probably not what people expect from typed + // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior + // of the old Buffer constructor. + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +function fromArrayBuffer (that, array) { + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + array.byteLength + that = Buffer._augment(new Uint8Array(array)) + } else { + // Fallback: Return an object instance of the Buffer class + that = fromTypedArray(that, new Uint8Array(array)) + } + return that +} + +function fromArrayLike (that, array) { + var length = checked(array.length) | 0 + that = allocate(that, length) + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object. +// Returns a zero-length buffer for inputs that don't conform to the spec. +function fromJsonObject (that, object) { + var array + var length = 0 + + if (object.type === 'Buffer' && isArray(object.data)) { + array = object.data + length = checked(array.length) | 0 + } + that = allocate(that, length) + + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +function allocate (that, length) { + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = Buffer._augment(new Uint8Array(length)) + } else { + // Fallback: Return an object instance of the Buffer class + that.length = length + that._isBuffer = true + } + + var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1 + if (fromPool) that.parent = rootParent + + return that +} + +function checked (length) { + // Note: cannot use `length < kMaxLength` here because that fails when + // length is NaN (which is otherwise coerced to zero.) + if (length >= kMaxLength()) { + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + kMaxLength().toString(16) + ' bytes') + } + return length | 0 +} + +function SlowBuffer (subject, encoding) { + if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding) + + var buf = new Buffer(subject, encoding) + delete buf.parent + return buf +} + +Buffer.isBuffer = function isBuffer (b) { + return !!(b != null && b._isBuffer) +} + +Buffer.compare = function compare (a, b) { + if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { + throw new TypeError('Arguments must be Buffers') + } + + if (a === b) return 0 + + var x = a.length + var y = b.length + + var i = 0 + var len = Math.min(x, y) + while (i < len) { + if (a[i] !== b[i]) break + + ++i + } + + if (i !== len) { + x = a[i] + y = b[i] + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 +} + +Buffer.isEncoding = function isEncoding (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'binary': + case 'base64': + case 'raw': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } +} + +Buffer.concat = function concat (list, length) { + if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.') + + if (list.length === 0) { + return new Buffer(0) + } + + var i + if (length === undefined) { + length = 0 + for (i = 0; i < list.length; i++) { + length += list[i].length + } + } + + var buf = new Buffer(length) + var pos = 0 + for (i = 0; i < list.length; i++) { + var item = list[i] + item.copy(buf, pos) + pos += item.length + } + return buf +} + +function byteLength (string, encoding) { + if (typeof string !== 'string') string = '' + string + + var len = string.length + if (len === 0) return 0 + + // Use a for loop to avoid recursion + var loweredCase = false + for (;;) { + switch (encoding) { + case 'ascii': + case 'binary': + // Deprecated + case 'raw': + case 'raws': + return len + case 'utf8': + case 'utf-8': + return utf8ToBytes(string).length + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return len * 2 + case 'hex': + return len >>> 1 + case 'base64': + return base64ToBytes(string).length + default: + if (loweredCase) return utf8ToBytes(string).length // assume utf8 + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} +Buffer.byteLength = byteLength + +// pre-set for values that may exist in the future +Buffer.prototype.length = undefined +Buffer.prototype.parent = undefined + +function slowToString (encoding, start, end) { + var loweredCase = false + + start = start | 0 + end = end === undefined || end === Infinity ? this.length : end | 0 + + if (!encoding) encoding = 'utf8' + if (start < 0) start = 0 + if (end > this.length) end = this.length + if (end <= start) return '' + + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) + + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) + + case 'ascii': + return asciiSlice(this, start, end) + + case 'binary': + return binarySlice(this, start, end) + + case 'base64': + return base64Slice(this, start, end) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = (encoding + '').toLowerCase() + loweredCase = true + } + } +} + +Buffer.prototype.toString = function toString () { + var length = this.length | 0 + if (length === 0) return '' + if (arguments.length === 0) return utf8Slice(this, 0, length) + return slowToString.apply(this, arguments) +} + +Buffer.prototype.equals = function equals (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return true + return Buffer.compare(this, b) === 0 +} + +Buffer.prototype.inspect = function inspect () { + var str = '' + var max = exports.INSPECT_MAX_BYTES + if (this.length > 0) { + str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') + if (this.length > max) str += ' ... ' + } + return '<Buffer ' + str + '>' +} + +Buffer.prototype.compare = function compare (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return 0 + return Buffer.compare(this, b) +} + +Buffer.prototype.indexOf = function indexOf (val, byteOffset) { + if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff + else if (byteOffset < -0x80000000) byteOffset = -0x80000000 + byteOffset >>= 0 + + if (this.length === 0) return -1 + if (byteOffset >= this.length) return -1 + + // Negative offsets start from the end of the buffer + if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) + + if (typeof val === 'string') { + if (val.length === 0) return -1 // special case: looking for empty string always fails + return String.prototype.indexOf.call(this, val, byteOffset) + } + if (Buffer.isBuffer(val)) { + return arrayIndexOf(this, val, byteOffset) + } + if (typeof val === 'number') { + if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { + return Uint8Array.prototype.indexOf.call(this, val, byteOffset) + } + return arrayIndexOf(this, [ val ], byteOffset) + } + + function arrayIndexOf (arr, val, byteOffset) { + var foundIndex = -1 + for (var i = 0; byteOffset + i < arr.length; i++) { + if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) { + if (foundIndex === -1) foundIndex = i + if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex + } else { + foundIndex = -1 + } + } + return -1 + } + + throw new TypeError('val must be string, number or Buffer') +} + +// `get` is deprecated +Buffer.prototype.get = function get (offset) { + console.log('.get() is deprecated. Access using array indexes instead.') + return this.readUInt8(offset) +} + +// `set` is deprecated +Buffer.prototype.set = function set (v, offset) { + console.log('.set() is deprecated. Access using array indexes instead.') + return this.writeUInt8(v, offset) +} + +function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0 + var remaining = buf.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + + // must be an even number of digits + var strLen = string.length + if (strLen % 2 !== 0) throw new Error('Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; i++) { + var parsed = parseInt(string.substr(i * 2, 2), 16) + if (isNaN(parsed)) throw new Error('Invalid hex string') + buf[offset + i] = parsed + } + return i +} + +function utf8Write (buf, string, offset, length) { + return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) +} + +function asciiWrite (buf, string, offset, length) { + return blitBuffer(asciiToBytes(string), buf, offset, length) +} + +function binaryWrite (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) +} + +function base64Write (buf, string, offset, length) { + return blitBuffer(base64ToBytes(string), buf, offset, length) +} + +function ucs2Write (buf, string, offset, length) { + return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) +} + +Buffer.prototype.write = function write (string, offset, length, encoding) { + // Buffer#write(string) + if (offset === undefined) { + encoding = 'utf8' + length = this.length + offset = 0 + // Buffer#write(string, encoding) + } else if (length === undefined && typeof offset === 'string') { + encoding = offset + length = this.length + offset = 0 + // Buffer#write(string, offset[, length][, encoding]) + } else if (isFinite(offset)) { + offset = offset | 0 + if (isFinite(length)) { + length = length | 0 + if (encoding === undefined) encoding = 'utf8' + } else { + encoding = length + length = undefined + } + // legacy write(string, encoding, offset, length) - remove in v0.13 + } else { + var swap = encoding + encoding = offset + offset = length | 0 + length = swap + } + + var remaining = this.length - offset + if (length === undefined || length > remaining) length = remaining + + if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { + throw new RangeError('attempt to write outside buffer bounds') + } + + if (!encoding) encoding = 'utf8' + + var loweredCase = false + for (;;) { + switch (encoding) { + case 'hex': + return hexWrite(this, string, offset, length) + + case 'utf8': + case 'utf-8': + return utf8Write(this, string, offset, length) + + case 'ascii': + return asciiWrite(this, string, offset, length) + + case 'binary': + return binaryWrite(this, string, offset, length) + + case 'base64': + // Warning: maxLength not taken into account in base64Write + return base64Write(this, string, offset, length) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return ucs2Write(this, string, offset, length) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} + +Buffer.prototype.toJSON = function toJSON () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +} + +function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return base64.fromByteArray(buf) + } else { + return base64.fromByteArray(buf.slice(start, end)) + } +} + +function utf8Slice (buf, start, end) { + end = Math.min(buf.length, end) + var firstByte + var secondByte + var thirdByte + var fourthByte + var bytesPerSequence + var tempCodePoint + var codePoint + var res = [] + var i = start + + for (; i < end; i += bytesPerSequence) { + firstByte = buf[i] + codePoint = 0xFFFD + + if (firstByte > 0xEF) { + bytesPerSequence = 4 + } else if (firstByte > 0xDF) { + bytesPerSequence = 3 + } else if (firstByte > 0xBF) { + bytesPerSequence = 2 + } else { + bytesPerSequence = 1 + } + + if (i + bytesPerSequence <= end) { + switch (bytesPerSequence) { + case 1: + if (firstByte < 0x80) { + codePoint = firstByte + } + break + case 2: + secondByte = buf[i + 1] + if ((secondByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) + if (tempCodePoint > 0x7F) { + codePoint = tempCodePoint + } + } + break + case 3: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) + if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { + codePoint = tempCodePoint + } + } + break + case 4: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + fourthByte = buf[i + 3] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) + if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { + codePoint = tempCodePoint + } + } + } + } + + if (codePoint === 0xFFFD) { + // we generated an invalid codePoint so make sure to only advance by 1 byte + bytesPerSequence = 1 + } else if (codePoint > 0xFFFF) { + // encode to utf16 (surrogate pair dance) + codePoint -= 0x10000 + res.push(codePoint >>> 10 & 0x3FF | 0xD800) + codePoint = 0xDC00 | codePoint & 0x3FF + } + + res.push(codePoint) + } + + return String.fromCharCode.apply(String, res) +} + +function asciiSlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + ret += String.fromCharCode(buf[i] & 0x7F) + } + return ret +} + +function binarySlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + ret += String.fromCharCode(buf[i]) + } + return ret +} + +function hexSlice (buf, start, end) { + var len = buf.length + + if (!start || start < 0) start = 0 + if (!end || end < 0 || end > len) end = len + + var out = '' + for (var i = start; i < end; i++) { + out += toHex(buf[i]) + } + return out +} + +function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end) + var res = '' + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) + } + return res +} + +Buffer.prototype.slice = function slice (start, end) { + var len = this.length + start = ~~start + end = end === undefined ? len : ~~end + + if (start < 0) { + start += len + if (start < 0) start = 0 + } else if (start > len) { + start = len + } + + if (end < 0) { + end += len + if (end < 0) end = 0 + } else if (end > len) { + end = len + } + + if (end < start) end = start + + var newBuf + if (Buffer.TYPED_ARRAY_SUPPORT) { + newBuf = Buffer._augment(this.subarray(start, end)) + } else { + var sliceLen = end - start + newBuf = new Buffer(sliceLen, undefined) + for (var i = 0; i < sliceLen; i++) { + newBuf[i] = this[i + start] + } + } + + if (newBuf.length) newBuf.parent = this.parent || this + + return newBuf +} + +/* + * Need to make sure that buffer isn't trying to write out of bounds. + */ +function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') + if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') +} + +Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + + return val +} + +Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + checkOffset(offset, byteLength, this.length) + } + + var val = this[offset + --byteLength] + var mul = 1 + while (byteLength > 0 && (mul *= 0x100)) { + val += this[offset + --byteLength] * mul + } + + return val +} + +Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + return this[offset] +} + +Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return this[offset] | (this[offset + 1] << 8) +} + +Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return (this[offset] << 8) | this[offset + 1] +} + +Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) +} + +Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) +} + +Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var i = byteLength + var mul = 1 + var val = this[offset + --i] + while (i > 0 && (mul *= 0x100)) { + val += this[offset + --i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + if (!(this[offset] & 0x80)) return (this[offset]) + return ((0xff - this[offset] + 1) * -1) +} + +Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset] | (this[offset + 1] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset + 1] | (this[offset] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) +} + +Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) +} + +Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, true, 23, 4) +} + +Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, false, 23, 4) +} + +Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, true, 52, 8) +} + +Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, false, 52, 8) +} + +function checkInt (buf, value, offset, ext, max, min) { + if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') + if (value > max || value < min) throw new RangeError('value is out of bounds') + if (offset + ext > buf.length) throw new RangeError('index out of range') +} + +Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) + + var mul = 1 + var i = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) + + var i = byteLength - 1 + var mul = 1 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + this[offset] = value + return offset + 1 +} + +function objectWriteUInt16 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { + buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } +} + +Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = value + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = value + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +function objectWriteUInt32 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffffffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { + buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } +} + +Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset + 3] = (value >>> 24) + this[offset + 2] = (value >>> 16) + this[offset + 1] = (value >>> 8) + this[offset] = value + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = value + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = 0 + var mul = 1 + var sub = value < 0 ? 1 : 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = byteLength - 1 + var mul = 1 + var sub = value < 0 ? 1 : 0 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + if (value < 0) value = 0xff + value + 1 + this[offset] = value + return offset + 1 +} + +Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = value + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = value + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = value + this[offset + 1] = (value >>> 8) + this[offset + 2] = (value >>> 16) + this[offset + 3] = (value >>> 24) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (value < 0) value = 0xffffffff + value + 1 + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = value + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +function checkIEEE754 (buf, value, offset, ext, max, min) { + if (value > max || value < min) throw new RangeError('value is out of bounds') + if (offset + ext > buf.length) throw new RangeError('index out of range') + if (offset < 0) throw new RangeError('index out of range') +} + +function writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) + } + ieee754.write(buf, value, offset, littleEndian, 23, 4) + return offset + 4 +} + +Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) +} + +function writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) + } + ieee754.write(buf, value, offset, littleEndian, 52, 8) + return offset + 8 +} + +Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) +} + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function copy (target, targetStart, start, end) { + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (targetStart >= target.length) targetStart = target.length + if (!targetStart) targetStart = 0 + if (end > 0 && end < start) end = start + + // Copy 0 bytes; we're done + if (end === start) return 0 + if (target.length === 0 || this.length === 0) return 0 + + // Fatal error conditions + if (targetStart < 0) { + throw new RangeError('targetStart out of bounds') + } + if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') + if (end < 0) throw new RangeError('sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) end = this.length + if (target.length - targetStart < end - start) { + end = target.length - targetStart + start + } + + var len = end - start + var i + + if (this === target && start < targetStart && targetStart < end) { + // descending copy from end + for (i = len - 1; i >= 0; i--) { + target[i + targetStart] = this[i + start] + } + } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { + // ascending copy from start + for (i = 0; i < len; i++) { + target[i + targetStart] = this[i + start] + } + } else { + target._set(this.subarray(start, start + len), targetStart) + } + + return len +} + +// fill(value, start=0, end=buffer.length) +Buffer.prototype.fill = function fill (value, start, end) { + if (!value) value = 0 + if (!start) start = 0 + if (!end) end = this.length + + if (end < start) throw new RangeError('end < start') + + // Fill 0 bytes; we're done + if (end === start) return + if (this.length === 0) return + + if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') + if (end < 0 || end > this.length) throw new RangeError('end out of bounds') + + var i + if (typeof value === 'number') { + for (i = start; i < end; i++) { + this[i] = value + } + } else { + var bytes = utf8ToBytes(value.toString()) + var len = bytes.length + for (i = start; i < end; i++) { + this[i] = bytes[i % len] + } + } + + return this +} + +/** + * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. + * Added in Node 0.12. Only available in browsers that support ArrayBuffer. + */ +Buffer.prototype.toArrayBuffer = function toArrayBuffer () { + if (typeof Uint8Array !== 'undefined') { + if (Buffer.TYPED_ARRAY_SUPPORT) { + return (new Buffer(this)).buffer + } else { + var buf = new Uint8Array(this.length) + for (var i = 0, len = buf.length; i < len; i += 1) { + buf[i] = this[i] + } + return buf.buffer + } + } else { + throw new TypeError('Buffer.toArrayBuffer not supported in this browser') + } +} + +// HELPER FUNCTIONS +// ================ + +var BP = Buffer.prototype + +/** + * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods + */ +Buffer._augment = function _augment (arr) { + arr.constructor = Buffer + arr._isBuffer = true + + // save reference to original Uint8Array set method before overwriting + arr._set = arr.set + + // deprecated + arr.get = BP.get + arr.set = BP.set + + arr.write = BP.write + arr.toString = BP.toString + arr.toLocaleString = BP.toString + arr.toJSON = BP.toJSON + arr.equals = BP.equals + arr.compare = BP.compare + arr.indexOf = BP.indexOf + arr.copy = BP.copy + arr.slice = BP.slice + arr.readUIntLE = BP.readUIntLE + arr.readUIntBE = BP.readUIntBE + arr.readUInt8 = BP.readUInt8 + arr.readUInt16LE = BP.readUInt16LE + arr.readUInt16BE = BP.readUInt16BE + arr.readUInt32LE = BP.readUInt32LE + arr.readUInt32BE = BP.readUInt32BE + arr.readIntLE = BP.readIntLE + arr.readIntBE = BP.readIntBE + arr.readInt8 = BP.readInt8 + arr.readInt16LE = BP.readInt16LE + arr.readInt16BE = BP.readInt16BE + arr.readInt32LE = BP.readInt32LE + arr.readInt32BE = BP.readInt32BE + arr.readFloatLE = BP.readFloatLE + arr.readFloatBE = BP.readFloatBE + arr.readDoubleLE = BP.readDoubleLE + arr.readDoubleBE = BP.readDoubleBE + arr.writeUInt8 = BP.writeUInt8 + arr.writeUIntLE = BP.writeUIntLE + arr.writeUIntBE = BP.writeUIntBE + arr.writeUInt16LE = BP.writeUInt16LE + arr.writeUInt16BE = BP.writeUInt16BE + arr.writeUInt32LE = BP.writeUInt32LE + arr.writeUInt32BE = BP.writeUInt32BE + arr.writeIntLE = BP.writeIntLE + arr.writeIntBE = BP.writeIntBE + arr.writeInt8 = BP.writeInt8 + arr.writeInt16LE = BP.writeInt16LE + arr.writeInt16BE = BP.writeInt16BE + arr.writeInt32LE = BP.writeInt32LE + arr.writeInt32BE = BP.writeInt32BE + arr.writeFloatLE = BP.writeFloatLE + arr.writeFloatBE = BP.writeFloatBE + arr.writeDoubleLE = BP.writeDoubleLE + arr.writeDoubleBE = BP.writeDoubleBE + arr.fill = BP.fill + arr.inspect = BP.inspect + arr.toArrayBuffer = BP.toArrayBuffer + + return arr +} + +var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g + +function base64clean (str) { + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = stringtrim(str).replace(INVALID_BASE64_RE, '') + // Node converts strings with length < 2 to '' + if (str.length < 2) return '' + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '=' + } + return str +} + +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} + +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} + +function utf8ToBytes (string, units) { + units = units || Infinity + var codePoint + var length = string.length + var leadSurrogate = null + var bytes = [] + + for (var i = 0; i < length; i++) { + codePoint = string.charCodeAt(i) + + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (!leadSurrogate) { + // no lead yet + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } + + // valid lead + leadSurrogate = codePoint + + continue + } + + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + leadSurrogate = codePoint + continue + } + + // valid surrogate pair + codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000 + + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + } + + leadSurrogate = null + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) break + bytes.push(codePoint) + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) break + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) break + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x110000) { + if ((units -= 4) < 0) break + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else { + throw new Error('Invalid code point') + } + } + + return bytes +} + +function asciiToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; i++) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF) + } + return byteArray +} + +function utf16leToBytes (str, units) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; i++) { + if ((units -= 2) < 0) break + + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray +} + +function base64ToBytes (str) { + return base64.toByteArray(base64clean(str)) +} + +function blitBuffer (src, dst, offset, length) { + for (var i = 0; i < length; i++) { + if ((i + offset >= dst.length) || (i >= src.length)) break + dst[i + offset] = src[i] + } + return i +} + +},{"base64-js":6,"ieee754":7,"is-array":8}],6:[function(require,module,exports){ +var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +;(function (exports) { + 'use strict'; + + var Arr = (typeof Uint8Array !== 'undefined') + ? Uint8Array + : Array + + var PLUS = '+'.charCodeAt(0) + var SLASH = '/'.charCodeAt(0) + var NUMBER = '0'.charCodeAt(0) + var LOWER = 'a'.charCodeAt(0) + var UPPER = 'A'.charCodeAt(0) + var PLUS_URL_SAFE = '-'.charCodeAt(0) + var SLASH_URL_SAFE = '_'.charCodeAt(0) + + function decode (elt) { + var code = elt.charCodeAt(0) + if (code === PLUS || + code === PLUS_URL_SAFE) + return 62 // '+' + if (code === SLASH || + code === SLASH_URL_SAFE) + return 63 // '/' + if (code < NUMBER) + return -1 //no match + if (code < NUMBER + 10) + return code - NUMBER + 26 + 26 + if (code < UPPER + 26) + return code - UPPER + if (code < LOWER + 26) + return code - LOWER + 26 + } + + function b64ToByteArray (b64) { + var i, j, l, tmp, placeHolders, arr + + if (b64.length % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + var len = b64.length + placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 + + // base64 is 4/3 + up to two characters of the original data + arr = new Arr(b64.length * 3 / 4 - placeHolders) + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? b64.length - 4 : b64.length + + var L = 0 + + function push (v) { + arr[L++] = v + } + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) + push((tmp & 0xFF0000) >> 16) + push((tmp & 0xFF00) >> 8) + push(tmp & 0xFF) + } + + if (placeHolders === 2) { + tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) + push(tmp & 0xFF) + } else if (placeHolders === 1) { + tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) + push((tmp >> 8) & 0xFF) + push(tmp & 0xFF) + } + + return arr + } + + function uint8ToBase64 (uint8) { + var i, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + temp, length + + function encode (num) { + return lookup.charAt(num) + } + + function tripletToBase64 (num) { + return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) + } + + // go through the array every three bytes, we'll deal with trailing stuff later + for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { + temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) + output += tripletToBase64(temp) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + switch (extraBytes) { + case 1: + temp = uint8[uint8.length - 1] + output += encode(temp >> 2) + output += encode((temp << 4) & 0x3F) + output += '==' + break + case 2: + temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) + output += encode(temp >> 10) + output += encode((temp >> 4) & 0x3F) + output += encode((temp << 2) & 0x3F) + output += '=' + break + } + + return output + } + + exports.toByteArray = b64ToByteArray + exports.fromByteArray = uint8ToBase64 +}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) + +},{}],7:[function(require,module,exports){ +exports.read = function (buffer, offset, isLE, mLen, nBytes) { + var e, m + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var nBits = -7 + var i = isLE ? (nBytes - 1) : 0 + var d = isLE ? -1 : 1 + var s = buffer[offset + i] + + i += d + + e = s & ((1 << (-nBits)) - 1) + s >>= (-nBits) + nBits += eLen + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1) + e >>= (-nBits) + nBits += mLen + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen) + e = e - eBias + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) +} + +exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) + var i = isLE ? 0 : (nBytes - 1) + var d = isLE ? 1 : -1 + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 + + value = Math.abs(value) + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0 + e = eMax + } else { + e = Math.floor(Math.log(value) / Math.LN2) + if (value * (c = Math.pow(2, -e)) < 1) { + e-- + c *= 2 + } + if (e + eBias >= 1) { + value += rt / c + } else { + value += rt * Math.pow(2, 1 - eBias) + } + if (value * c >= 2) { + e++ + c /= 2 + } + + if (e + eBias >= eMax) { + m = 0 + e = eMax + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen) + e = e + eBias + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) + e = 0 + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m + eLen += mLen + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128 +} + +},{}],8:[function(require,module,exports){ + +/** + * isArray + */ + +var isArray = Array.isArray; + +/** + * toString + */ + +var str = Object.prototype.toString; + +/** + * Whether or not the given `val` + * is an array. + * + * example: + * + * isArray([]); + * // > true + * isArray(arguments); + * // > false + * isArray(''); + * // > false + * + * @param {mixed} val + * @return {bool} + */ + +module.exports = isArray || function (val) { + return !! val && '[object Array]' == str.call(val); +}; + +},{}],9:[function(require,module,exports){ +'use strict'; +// private property +var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + + +// public method for encoding +exports.encode = function(input, utf8) { + var output = ""; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 0; + + while (i < input.length) { + + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } + else if (isNaN(chr3)) { + enc4 = 64; + } + + output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4); + + } + + return output; +}; + +// public method for decoding +exports.decode = function(input, utf8) { + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + while (i < input.length) { + + enc1 = _keyStr.indexOf(input.charAt(i++)); + enc2 = _keyStr.indexOf(input.charAt(i++)); + enc3 = _keyStr.indexOf(input.charAt(i++)); + enc4 = _keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output = output + String.fromCharCode(chr1); + + if (enc3 != 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 != 64) { + output = output + String.fromCharCode(chr3); + } + + } + + return output; + +}; + +},{}],10:[function(require,module,exports){ +'use strict'; +function CompressedObject() { + this.compressedSize = 0; + this.uncompressedSize = 0; + this.crc32 = 0; + this.compressionMethod = null; + this.compressedContent = null; +} + +CompressedObject.prototype = { + /** + * Return the decompressed content in an unspecified format. + * The format will depend on the decompressor. + * @return {Object} the decompressed content. + */ + getContent: function() { + return null; // see implementation + }, + /** + * Return the compressed content in an unspecified format. + * The format will depend on the compressed conten source. + * @return {Object} the compressed content. + */ + getCompressedContent: function() { + return null; // see implementation + } +}; +module.exports = CompressedObject; + +},{}],11:[function(require,module,exports){ +'use strict'; +exports.STORE = { + magic: "\x00\x00", + compress: function(content, compressionOptions) { + return content; // no compression + }, + uncompress: function(content) { + return content; // no compression + }, + compressInputType: null, + uncompressInputType: null +}; +exports.DEFLATE = require('./flate'); + +},{"./flate":16}],12:[function(require,module,exports){ +'use strict'; + +var utils = require('./utils'); + +var table = [ + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +]; + +/** + * + * Javascript crc32 + * http://www.webtoolkit.info/ + * + */ +module.exports = function crc32(input, crc) { + if (typeof input === "undefined" || !input.length) { + return 0; + } + + var isArray = utils.getTypeOf(input) !== "string"; + + if (typeof(crc) == "undefined") { + crc = 0; + } + var x = 0; + var y = 0; + var b = 0; + + crc = crc ^ (-1); + for (var i = 0, iTop = input.length; i < iTop; i++) { + b = isArray ? input[i] : input.charCodeAt(i); + y = (crc ^ b) & 0xFF; + x = table[y]; + crc = (crc >>> 8) ^ x; + } + + return crc ^ (-1); +}; +// vim: set shiftwidth=4 softtabstop=4: + +},{"./utils":29}],13:[function(require,module,exports){ +'use strict'; +var utils = require('./utils'); + +function DataReader(data) { + this.data = null; // type : see implementation + this.length = 0; + this.index = 0; +} +DataReader.prototype = { + /** + * Check that the offset will not go too far. + * @param {string} offset the additional offset to check. + * @throws {Error} an Error if the offset is out of bounds. + */ + checkOffset: function(offset) { + this.checkIndex(this.index + offset); + }, + /** + * Check that the specifed index will not be too far. + * @param {string} newIndex the index to check. + * @throws {Error} an Error if the index is out of bounds. + */ + checkIndex: function(newIndex) { + if (this.length < newIndex || newIndex < 0) { + throw new Error("End of data reached (data length = " + this.length + ", asked index = " + (newIndex) + "). Corrupted zip ?"); + } + }, + /** + * Change the index. + * @param {number} newIndex The new index. + * @throws {Error} if the new index is out of the data. + */ + setIndex: function(newIndex) { + this.checkIndex(newIndex); + this.index = newIndex; + }, + /** + * Skip the next n bytes. + * @param {number} n the number of bytes to skip. + * @throws {Error} if the new index is out of the data. + */ + skip: function(n) { + this.setIndex(this.index + n); + }, + /** + * Get the byte at the specified index. + * @param {number} i the index to use. + * @return {number} a byte. + */ + byteAt: function(i) { + // see implementations + }, + /** + * Get the next number with a given byte size. + * @param {number} size the number of bytes to read. + * @return {number} the corresponding number. + */ + readInt: function(size) { + var result = 0, + i; + this.checkOffset(size); + for (i = this.index + size - 1; i >= this.index; i--) { + result = (result << 8) + this.byteAt(i); + } + this.index += size; + return result; + }, + /** + * Get the next string with a given byte size. + * @param {number} size the number of bytes to read. + * @return {string} the corresponding string. + */ + readString: function(size) { + return utils.transformTo("string", this.readData(size)); + }, + /** + * Get raw data without conversion, <size> bytes. + * @param {number} size the number of bytes to read. + * @return {Object} the raw data, implementation specific. + */ + readData: function(size) { + // see implementations + }, + /** + * Find the last occurence of a zip signature (4 bytes). + * @param {string} sig the signature to find. + * @return {number} the index of the last occurence, -1 if not found. + */ + lastIndexOfSignature: function(sig) { + // see implementations + }, + /** + * Get the next date. + * @return {Date} the date. + */ + readDate: function() { + var dostime = this.readInt(4); + return new Date( + ((dostime >> 25) & 0x7f) + 1980, // year + ((dostime >> 21) & 0x0f) - 1, // month + (dostime >> 16) & 0x1f, // day + (dostime >> 11) & 0x1f, // hour + (dostime >> 5) & 0x3f, // minute + (dostime & 0x1f) << 1); // second + } +}; +module.exports = DataReader; + +},{"./utils":29}],14:[function(require,module,exports){ +'use strict'; +exports.base64 = false; +exports.binary = false; +exports.dir = false; +exports.createFolders = false; +exports.date = null; +exports.compression = null; +exports.compressionOptions = null; +exports.comment = null; +exports.unixPermissions = null; +exports.dosPermissions = null; + +},{}],15:[function(require,module,exports){ +'use strict'; +var utils = require('./utils'); + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.string2binary = function(str) { + return utils.string2binary(str); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.string2Uint8Array = function(str) { + return utils.transformTo("uint8array", str); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.uint8Array2String = function(array) { + return utils.transformTo("string", array); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.string2Blob = function(str) { + var buffer = utils.transformTo("arraybuffer", str); + return utils.arrayBuffer2Blob(buffer); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.arrayBuffer2Blob = function(buffer) { + return utils.arrayBuffer2Blob(buffer); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.transformTo = function(outputType, input) { + return utils.transformTo(outputType, input); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.getTypeOf = function(input) { + return utils.getTypeOf(input); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.checkSupport = function(type) { + return utils.checkSupport(type); +}; + +/** + * @deprecated + * This value will be removed in a future version without replacement. + */ +exports.MAX_VALUE_16BITS = utils.MAX_VALUE_16BITS; + +/** + * @deprecated + * This value will be removed in a future version without replacement. + */ +exports.MAX_VALUE_32BITS = utils.MAX_VALUE_32BITS; + + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.pretty = function(str) { + return utils.pretty(str); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.findCompression = function(compressionMethod) { + return utils.findCompression(compressionMethod); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.isRegExp = function (object) { + return utils.isRegExp(object); +}; + + +},{"./utils":29}],16:[function(require,module,exports){ +'use strict'; +var USE_TYPEDARRAY = (typeof Uint8Array !== 'undefined') && (typeof Uint16Array !== 'undefined') && (typeof Uint32Array !== 'undefined'); + +var pako = require("pako"); +exports.uncompressInputType = USE_TYPEDARRAY ? "uint8array" : "array"; +exports.compressInputType = USE_TYPEDARRAY ? "uint8array" : "array"; + +exports.magic = "\x08\x00"; +exports.compress = function(input, compressionOptions) { + return pako.deflateRaw(input, { + level : compressionOptions.level || -1 // default compression + }); +}; +exports.uncompress = function(input) { + return pako.inflateRaw(input); +}; + +},{"pako":32}],17:[function(require,module,exports){ +'use strict'; + +var base64 = require('./base64'); + +/** +Usage: + zip = new JSZip(); + zip.file("hello.txt", "Hello, World!").file("tempfile", "nothing"); + zip.folder("images").file("smile.gif", base64Data, {base64: true}); + zip.file("Xmas.txt", "Ho ho ho !", {date : new Date("December 25, 2007 00:00:01")}); + zip.remove("tempfile"); + + base64zip = zip.generate(); + +**/ + +/** + * Representation a of zip file in js + * @constructor + * @param {String=|ArrayBuffer=|Uint8Array=} data the data to load, if any (optional). + * @param {Object=} options the options for creating this objects (optional). + */ +function JSZip(data, options) { + // if this constructor is used without `new`, it adds `new` before itself: + if(!(this instanceof JSZip)) return new JSZip(data, options); + + // object containing the files : + // { + // "folder/" : {...}, + // "folder/data.txt" : {...} + // } + this.files = {}; + + this.comment = null; + + // Where we are in the hierarchy + this.root = ""; + if (data) { + this.load(data, options); + } + this.clone = function() { + var newObj = new JSZip(); + for (var i in this) { + if (typeof this[i] !== "function") { + newObj[i] = this[i]; + } + } + return newObj; + }; +} +JSZip.prototype = require('./object'); +JSZip.prototype.load = require('./load'); +JSZip.support = require('./support'); +JSZip.defaults = require('./defaults'); + +/** + * @deprecated + * This namespace will be removed in a future version without replacement. + */ +JSZip.utils = require('./deprecatedPublicUtils'); + +JSZip.base64 = { + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + encode : function(input) { + return base64.encode(input); + }, + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + decode : function(input) { + return base64.decode(input); + } +}; +JSZip.compressions = require('./compressions'); +module.exports = JSZip; + +},{"./base64":9,"./compressions":11,"./defaults":14,"./deprecatedPublicUtils":15,"./load":18,"./object":21,"./support":25}],18:[function(require,module,exports){ +'use strict'; +var base64 = require('./base64'); +var ZipEntries = require('./zipEntries'); +module.exports = function(data, options) { + var files, zipEntries, i, input; + options = options || {}; + if (options.base64) { + data = base64.decode(data); + } + + zipEntries = new ZipEntries(data, options); + files = zipEntries.files; + for (i = 0; i < files.length; i++) { + input = files[i]; + this.file(input.fileName, input.decompressed, { + binary: true, + optimizedBinaryString: true, + date: input.date, + dir: input.dir, + comment : input.fileComment.length ? input.fileComment : null, + unixPermissions : input.unixPermissions, + dosPermissions : input.dosPermissions, + createFolders: options.createFolders + }); + } + if (zipEntries.zipComment.length) { + this.comment = zipEntries.zipComment; + } + + return this; +}; + +},{"./base64":9,"./zipEntries":30}],19:[function(require,module,exports){ +(function (Buffer){ +'use strict'; +module.exports = function(data, encoding){ + return new Buffer(data, encoding); +}; +module.exports.test = function(b){ + return Buffer.isBuffer(b); +}; + +}).call(this,require("buffer").Buffer) +},{"buffer":5}],20:[function(require,module,exports){ +'use strict'; +var Uint8ArrayReader = require('./uint8ArrayReader'); + +function NodeBufferReader(data) { + this.data = data; + this.length = this.data.length; + this.index = 0; +} +NodeBufferReader.prototype = new Uint8ArrayReader(); + +/** + * @see DataReader.readData + */ +NodeBufferReader.prototype.readData = function(size) { + this.checkOffset(size); + var result = this.data.slice(this.index, this.index + size); + this.index += size; + return result; +}; +module.exports = NodeBufferReader; + +},{"./uint8ArrayReader":26}],21:[function(require,module,exports){ +'use strict'; +var support = require('./support'); +var utils = require('./utils'); +var crc32 = require('./crc32'); +var signature = require('./signature'); +var defaults = require('./defaults'); +var base64 = require('./base64'); +var compressions = require('./compressions'); +var CompressedObject = require('./compressedObject'); +var nodeBuffer = require('./nodeBuffer'); +var utf8 = require('./utf8'); +var StringWriter = require('./stringWriter'); +var Uint8ArrayWriter = require('./uint8ArrayWriter'); + +/** + * Returns the raw data of a ZipObject, decompress the content if necessary. + * @param {ZipObject} file the file to use. + * @return {String|ArrayBuffer|Uint8Array|Buffer} the data. + */ +var getRawData = function(file) { + if (file._data instanceof CompressedObject) { + file._data = file._data.getContent(); + file.options.binary = true; + file.options.base64 = false; + + if (utils.getTypeOf(file._data) === "uint8array") { + var copy = file._data; + // when reading an arraybuffer, the CompressedObject mechanism will keep it and subarray() a Uint8Array. + // if we request a file in the same format, we might get the same Uint8Array or its ArrayBuffer (the original zip file). + file._data = new Uint8Array(copy.length); + // with an empty Uint8Array, Opera fails with a "Offset larger than array size" + if (copy.length !== 0) { + file._data.set(copy, 0); + } + } + } + return file._data; +}; + +/** + * Returns the data of a ZipObject in a binary form. If the content is an unicode string, encode it. + * @param {ZipObject} file the file to use. + * @return {String|ArrayBuffer|Uint8Array|Buffer} the data. + */ +var getBinaryData = function(file) { + var result = getRawData(file), + type = utils.getTypeOf(result); + if (type === "string") { + if (!file.options.binary) { + // unicode text ! + // unicode string => binary string is a painful process, check if we can avoid it. + if (support.nodebuffer) { + return nodeBuffer(result, "utf-8"); + } + } + return file.asBinary(); + } + return result; +}; + +/** + * Transform this._data into a string. + * @param {function} filter a function String -> String, applied if not null on the result. + * @return {String} the string representing this._data. + */ +var dataToString = function(asUTF8) { + var result = getRawData(this); + if (result === null || typeof result === "undefined") { + return ""; + } + // if the data is a base64 string, we decode it before checking the encoding ! + if (this.options.base64) { + result = base64.decode(result); + } + if (asUTF8 && this.options.binary) { + // JSZip.prototype.utf8decode supports arrays as input + // skip to array => string step, utf8decode will do it. + result = out.utf8decode(result); + } + else { + // no utf8 transformation, do the array => string step. + result = utils.transformTo("string", result); + } + + if (!asUTF8 && !this.options.binary) { + result = utils.transformTo("string", out.utf8encode(result)); + } + return result; +}; +/** + * A simple object representing a file in the zip file. + * @constructor + * @param {string} name the name of the file + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data + * @param {Object} options the options of the file + */ +var ZipObject = function(name, data, options) { + this.name = name; + this.dir = options.dir; + this.date = options.date; + this.comment = options.comment; + this.unixPermissions = options.unixPermissions; + this.dosPermissions = options.dosPermissions; + + this._data = data; + this.options = options; + + /* + * This object contains initial values for dir and date. + * With them, we can check if the user changed the deprecated metadata in + * `ZipObject#options` or not. + */ + this._initialMetadata = { + dir : options.dir, + date : options.date + }; +}; + +ZipObject.prototype = { + /** + * Return the content as UTF8 string. + * @return {string} the UTF8 string. + */ + asText: function() { + return dataToString.call(this, true); + }, + /** + * Returns the binary content. + * @return {string} the content as binary. + */ + asBinary: function() { + return dataToString.call(this, false); + }, + /** + * Returns the content as a nodejs Buffer. + * @return {Buffer} the content as a Buffer. + */ + asNodeBuffer: function() { + var result = getBinaryData(this); + return utils.transformTo("nodebuffer", result); + }, + /** + * Returns the content as an Uint8Array. + * @return {Uint8Array} the content as an Uint8Array. + */ + asUint8Array: function() { + var result = getBinaryData(this); + return utils.transformTo("uint8array", result); + }, + /** + * Returns the content as an ArrayBuffer. + * @return {ArrayBuffer} the content as an ArrayBufer. + */ + asArrayBuffer: function() { + return this.asUint8Array().buffer; + } +}; + +/** + * Transform an integer into a string in hexadecimal. + * @private + * @param {number} dec the number to convert. + * @param {number} bytes the number of bytes to generate. + * @returns {string} the result. + */ +var decToHex = function(dec, bytes) { + var hex = "", + i; + for (i = 0; i < bytes; i++) { + hex += String.fromCharCode(dec & 0xff); + dec = dec >>> 8; + } + return hex; +}; + +/** + * Merge the objects passed as parameters into a new one. + * @private + * @param {...Object} var_args All objects to merge. + * @return {Object} a new object with the data of the others. + */ +var extend = function() { + var result = {}, i, attr; + for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers + for (attr in arguments[i]) { + if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") { + result[attr] = arguments[i][attr]; + } + } + } + return result; +}; + +/** + * Transforms the (incomplete) options from the user into the complete + * set of options to create a file. + * @private + * @param {Object} o the options from the user. + * @return {Object} the complete set of options. + */ +var prepareFileAttrs = function(o) { + o = o || {}; + if (o.base64 === true && (o.binary === null || o.binary === undefined)) { + o.binary = true; + } + o = extend(o, defaults); + o.date = o.date || new Date(); + if (o.compression !== null) o.compression = o.compression.toUpperCase(); + + return o; +}; + +/** + * Add a file in the current folder. + * @private + * @param {string} name the name of the file + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file + * @param {Object} o the options of the file + * @return {Object} the new file. + */ +var fileAdd = function(name, data, o) { + // be sure sub folders exist + var dataType = utils.getTypeOf(data), + parent; + + o = prepareFileAttrs(o); + + if (typeof o.unixPermissions === "string") { + o.unixPermissions = parseInt(o.unixPermissions, 8); + } + + // UNX_IFDIR 0040000 see zipinfo.c + if (o.unixPermissions && (o.unixPermissions & 0x4000)) { + o.dir = true; + } + // Bit 4 Directory + if (o.dosPermissions && (o.dosPermissions & 0x0010)) { + o.dir = true; + } + + if (o.dir) { + name = forceTrailingSlash(name); + } + + if (o.createFolders && (parent = parentFolder(name))) { + folderAdd.call(this, parent, true); + } + + if (o.dir || data === null || typeof data === "undefined") { + o.base64 = false; + o.binary = false; + data = null; + dataType = null; + } + else if (dataType === "string") { + if (o.binary && !o.base64) { + // optimizedBinaryString == true means that the file has already been filtered with a 0xFF mask + if (o.optimizedBinaryString !== true) { + // this is a string, not in a base64 format. + // Be sure that this is a correct "binary string" + data = utils.string2binary(data); + } + } + } + else { // arraybuffer, uint8array, ... + o.base64 = false; + o.binary = true; + + if (!dataType && !(data instanceof CompressedObject)) { + throw new Error("The data of '" + name + "' is in an unsupported format !"); + } + + // special case : it's way easier to work with Uint8Array than with ArrayBuffer + if (dataType === "arraybuffer") { + data = utils.transformTo("uint8array", data); + } + } + + var object = new ZipObject(name, data, o); + this.files[name] = object; + return object; +}; + +/** + * Find the parent folder of the path. + * @private + * @param {string} path the path to use + * @return {string} the parent folder, or "" + */ +var parentFolder = function (path) { + if (path.slice(-1) == '/') { + path = path.substring(0, path.length - 1); + } + var lastSlash = path.lastIndexOf('/'); + return (lastSlash > 0) ? path.substring(0, lastSlash) : ""; +}; + + +/** + * Returns the path with a slash at the end. + * @private + * @param {String} path the path to check. + * @return {String} the path with a trailing slash. + */ +var forceTrailingSlash = function(path) { + // Check the name ends with a / + if (path.slice(-1) != "/") { + path += "/"; // IE doesn't like substr(-1) + } + return path; +}; +/** + * Add a (sub) folder in the current folder. + * @private + * @param {string} name the folder's name + * @param {boolean=} [createFolders] If true, automatically create sub + * folders. Defaults to false. + * @return {Object} the new folder. + */ +var folderAdd = function(name, createFolders) { + createFolders = (typeof createFolders !== 'undefined') ? createFolders : false; + + name = forceTrailingSlash(name); + + // Does this folder already exist? + if (!this.files[name]) { + fileAdd.call(this, name, null, { + dir: true, + createFolders: createFolders + }); + } + return this.files[name]; +}; + +/** + * Generate a JSZip.CompressedObject for a given zipOject. + * @param {ZipObject} file the object to read. + * @param {JSZip.compression} compression the compression to use. + * @param {Object} compressionOptions the options to use when compressing. + * @return {JSZip.CompressedObject} the compressed result. + */ +var generateCompressedObjectFrom = function(file, compression, compressionOptions) { + var result = new CompressedObject(), + content; + + // the data has not been decompressed, we might reuse things ! + if (file._data instanceof CompressedObject) { + result.uncompressedSize = file._data.uncompressedSize; + result.crc32 = file._data.crc32; + + if (result.uncompressedSize === 0 || file.dir) { + compression = compressions['STORE']; + result.compressedContent = ""; + result.crc32 = 0; + } + else if (file._data.compressionMethod === compression.magic) { + result.compressedContent = file._data.getCompressedContent(); + } + else { + content = file._data.getContent(); + // need to decompress / recompress + result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content), compressionOptions); + } + } + else { + // have uncompressed data + content = getBinaryData(file); + if (!content || content.length === 0 || file.dir) { + compression = compressions['STORE']; + content = ""; + } + result.uncompressedSize = content.length; + result.crc32 = crc32(content); + result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content), compressionOptions); + } + + result.compressedSize = result.compressedContent.length; + result.compressionMethod = compression.magic; + + return result; +}; + + + + +/** + * Generate the UNIX part of the external file attributes. + * @param {Object} unixPermissions the unix permissions or null. + * @param {Boolean} isDir true if the entry is a directory, false otherwise. + * @return {Number} a 32 bit integer. + * + * adapted from http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute : + * + * TTTTsstrwxrwxrwx0000000000ADVSHR + * ^^^^____________________________ file type, see zipinfo.c (UNX_*) + * ^^^_________________________ setuid, setgid, sticky + * ^^^^^^^^^________________ permissions + * ^^^^^^^^^^______ not used ? + * ^^^^^^ DOS attribute bits : Archive, Directory, Volume label, System file, Hidden, Read only + */ +var generateUnixExternalFileAttr = function (unixPermissions, isDir) { + + var result = unixPermissions; + if (!unixPermissions) { + // I can't use octal values in strict mode, hence the hexa. + // 040775 => 0x41fd + // 0100664 => 0x81b4 + result = isDir ? 0x41fd : 0x81b4; + } + + return (result & 0xFFFF) << 16; +}; + +/** + * Generate the DOS part of the external file attributes. + * @param {Object} dosPermissions the dos permissions or null. + * @param {Boolean} isDir true if the entry is a directory, false otherwise. + * @return {Number} a 32 bit integer. + * + * Bit 0 Read-Only + * Bit 1 Hidden + * Bit 2 System + * Bit 3 Volume Label + * Bit 4 Directory + * Bit 5 Archive + */ +var generateDosExternalFileAttr = function (dosPermissions, isDir) { + + // the dir flag is already set for compatibility + + return (dosPermissions || 0) & 0x3F; +}; + +/** + * Generate the various parts used in the construction of the final zip file. + * @param {string} name the file name. + * @param {ZipObject} file the file content. + * @param {JSZip.CompressedObject} compressedObject the compressed object. + * @param {number} offset the current offset from the start of the zip file. + * @param {String} platform let's pretend we are this platform (change platform dependents fields) + * @return {object} the zip parts. + */ +var generateZipParts = function(name, file, compressedObject, offset, platform) { + var data = compressedObject.compressedContent, + utfEncodedFileName = utils.transformTo("string", utf8.utf8encode(file.name)), + comment = file.comment || "", + utfEncodedComment = utils.transformTo("string", utf8.utf8encode(comment)), + useUTF8ForFileName = utfEncodedFileName.length !== file.name.length, + useUTF8ForComment = utfEncodedComment.length !== comment.length, + o = file.options, + dosTime, + dosDate, + extraFields = "", + unicodePathExtraField = "", + unicodeCommentExtraField = "", + dir, date; + + + // handle the deprecated options.dir + if (file._initialMetadata.dir !== file.dir) { + dir = file.dir; + } else { + dir = o.dir; + } + + // handle the deprecated options.date + if(file._initialMetadata.date !== file.date) { + date = file.date; + } else { + date = o.date; + } + + var extFileAttr = 0; + var versionMadeBy = 0; + if (dir) { + // dos or unix, we set the dos dir flag + extFileAttr |= 0x00010; + } + if(platform === "UNIX") { + versionMadeBy = 0x031E; // UNIX, version 3.0 + extFileAttr |= generateUnixExternalFileAttr(file.unixPermissions, dir); + } else { // DOS or other, fallback to DOS + versionMadeBy = 0x0014; // DOS, version 2.0 + extFileAttr |= generateDosExternalFileAttr(file.dosPermissions, dir); + } + + // date + // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html + // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html + // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html + + dosTime = date.getHours(); + dosTime = dosTime << 6; + dosTime = dosTime | date.getMinutes(); + dosTime = dosTime << 5; + dosTime = dosTime | date.getSeconds() / 2; + + dosDate = date.getFullYear() - 1980; + dosDate = dosDate << 4; + dosDate = dosDate | (date.getMonth() + 1); + dosDate = dosDate << 5; + dosDate = dosDate | date.getDate(); + + if (useUTF8ForFileName) { + // set the unicode path extra field. unzip needs at least one extra + // field to correctly handle unicode path, so using the path is as good + // as any other information. This could improve the situation with + // other archive managers too. + // This field is usually used without the utf8 flag, with a non + // unicode path in the header (winrar, winzip). This helps (a bit) + // with the messy Windows' default compressed folders feature but + // breaks on p7zip which doesn't seek the unicode path extra field. + // So for now, UTF-8 everywhere ! + unicodePathExtraField = + // Version + decToHex(1, 1) + + // NameCRC32 + decToHex(crc32(utfEncodedFileName), 4) + + // UnicodeName + utfEncodedFileName; + + extraFields += + // Info-ZIP Unicode Path Extra Field + "\x75\x70" + + // size + decToHex(unicodePathExtraField.length, 2) + + // content + unicodePathExtraField; + } + + if(useUTF8ForComment) { + + unicodeCommentExtraField = + // Version + decToHex(1, 1) + + // CommentCRC32 + decToHex(this.crc32(utfEncodedComment), 4) + + // UnicodeName + utfEncodedComment; + + extraFields += + // Info-ZIP Unicode Path Extra Field + "\x75\x63" + + // size + decToHex(unicodeCommentExtraField.length, 2) + + // content + unicodeCommentExtraField; + } + + var header = ""; + + // version needed to extract + header += "\x0A\x00"; + // general purpose bit flag + // set bit 11 if utf8 + header += (useUTF8ForFileName || useUTF8ForComment) ? "\x00\x08" : "\x00\x00"; + // compression method + header += compressedObject.compressionMethod; + // last mod file time + header += decToHex(dosTime, 2); + // last mod file date + header += decToHex(dosDate, 2); + // crc-32 + header += decToHex(compressedObject.crc32, 4); + // compressed size + header += decToHex(compressedObject.compressedSize, 4); + // uncompressed size + header += decToHex(compressedObject.uncompressedSize, 4); + // file name length + header += decToHex(utfEncodedFileName.length, 2); + // extra field length + header += decToHex(extraFields.length, 2); + + + var fileRecord = signature.LOCAL_FILE_HEADER + header + utfEncodedFileName + extraFields; + + var dirRecord = signature.CENTRAL_FILE_HEADER + + // version made by (00: DOS) + decToHex(versionMadeBy, 2) + + // file header (common to file and central directory) + header + + // file comment length + decToHex(utfEncodedComment.length, 2) + + // disk number start + "\x00\x00" + + // internal file attributes TODO + "\x00\x00" + + // external file attributes + decToHex(extFileAttr, 4) + + // relative offset of local header + decToHex(offset, 4) + + // file name + utfEncodedFileName + + // extra field + extraFields + + // file comment + utfEncodedComment; + + return { + fileRecord: fileRecord, + dirRecord: dirRecord, + compressedObject: compressedObject + }; +}; + + +// return the actual prototype of JSZip +var out = { + /** + * Read an existing zip and merge the data in the current JSZip object. + * The implementation is in jszip-load.js, don't forget to include it. + * @param {String|ArrayBuffer|Uint8Array|Buffer} stream The stream to load + * @param {Object} options Options for loading the stream. + * options.base64 : is the stream in base64 ? default : false + * @return {JSZip} the current JSZip object + */ + load: function(stream, options) { + throw new Error("Load method is not defined. Is the file jszip-load.js included ?"); + }, + + /** + * Filter nested files/folders with the specified function. + * @param {Function} search the predicate to use : + * function (relativePath, file) {...} + * It takes 2 arguments : the relative path and the file. + * @return {Array} An array of matching elements. + */ + filter: function(search) { + var result = [], + filename, relativePath, file, fileClone; + for (filename in this.files) { + if (!this.files.hasOwnProperty(filename)) { + continue; + } + file = this.files[filename]; + // return a new object, don't let the user mess with our internal objects :) + fileClone = new ZipObject(file.name, file._data, extend(file.options)); + relativePath = filename.slice(this.root.length, filename.length); + if (filename.slice(0, this.root.length) === this.root && // the file is in the current root + search(relativePath, fileClone)) { // and the file matches the function + result.push(fileClone); + } + } + return result; + }, + + /** + * Add a file to the zip file, or search a file. + * @param {string|RegExp} name The name of the file to add (if data is defined), + * the name of the file to find (if no data) or a regex to match files. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data The file data, either raw or base64 encoded + * @param {Object} o File options + * @return {JSZip|Object|Array} this JSZip object (when adding a file), + * a file (when searching by string) or an array of files (when searching by regex). + */ + file: function(name, data, o) { + if (arguments.length === 1) { + if (utils.isRegExp(name)) { + var regexp = name; + return this.filter(function(relativePath, file) { + return !file.dir && regexp.test(relativePath); + }); + } + else { // text + return this.filter(function(relativePath, file) { + return !file.dir && relativePath === name; + })[0] || null; + } + } + else { // more than one argument : we have data ! + name = this.root + name; + fileAdd.call(this, name, data, o); + } + return this; + }, + + /** + * Add a directory to the zip file, or search. + * @param {String|RegExp} arg The name of the directory to add, or a regex to search folders. + * @return {JSZip} an object with the new directory as the root, or an array containing matching folders. + */ + folder: function(arg) { + if (!arg) { + return this; + } + + if (utils.isRegExp(arg)) { + return this.filter(function(relativePath, file) { + return file.dir && arg.test(relativePath); + }); + } + + // else, name is a new folder + var name = this.root + arg; + var newFolder = folderAdd.call(this, name); + + // Allow chaining by returning a new object with this folder as the root + var ret = this.clone(); + ret.root = newFolder.name; + return ret; + }, + + /** + * Delete a file, or a directory and all sub-files, from the zip + * @param {string} name the name of the file to delete + * @return {JSZip} this JSZip object + */ + remove: function(name) { + name = this.root + name; + var file = this.files[name]; + if (!file) { + // Look for any folders + if (name.slice(-1) != "/") { + name += "/"; + } + file = this.files[name]; + } + + if (file && !file.dir) { + // file + delete this.files[name]; + } else { + // maybe a folder, delete recursively + var kids = this.filter(function(relativePath, file) { + return file.name.slice(0, name.length) === name; + }); + for (var i = 0; i < kids.length; i++) { + delete this.files[kids[i].name]; + } + } + + return this; + }, + + /** + * Generate the complete zip file + * @param {Object} options the options to generate the zip file : + * - base64, (deprecated, use type instead) true to generate base64. + * - compression, "STORE" by default. + * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. + * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file + */ + generate: function(options) { + options = extend(options || {}, { + base64: true, + compression: "STORE", + compressionOptions : null, + type: "base64", + platform: "DOS", + comment: null, + mimeType: 'application/zip' + }); + + utils.checkSupport(options.type); + + // accept nodejs `process.platform` + if( + options.platform === 'darwin' || + options.platform === 'freebsd' || + options.platform === 'linux' || + options.platform === 'sunos' + ) { + options.platform = "UNIX"; + } + if (options.platform === 'win32') { + options.platform = "DOS"; + } + + var zipData = [], + localDirLength = 0, + centralDirLength = 0, + writer, i, + utfEncodedComment = utils.transformTo("string", this.utf8encode(options.comment || this.comment || "")); + + // first, generate all the zip parts. + for (var name in this.files) { + if (!this.files.hasOwnProperty(name)) { + continue; + } + var file = this.files[name]; + + var compressionName = file.options.compression || options.compression.toUpperCase(); + var compression = compressions[compressionName]; + if (!compression) { + throw new Error(compressionName + " is not a valid compression method !"); + } + var compressionOptions = file.options.compressionOptions || options.compressionOptions || {}; + + var compressedObject = generateCompressedObjectFrom.call(this, file, compression, compressionOptions); + + var zipPart = generateZipParts.call(this, name, file, compressedObject, localDirLength, options.platform); + localDirLength += zipPart.fileRecord.length + compressedObject.compressedSize; + centralDirLength += zipPart.dirRecord.length; + zipData.push(zipPart); + } + + var dirEnd = ""; + + // end of central dir signature + dirEnd = signature.CENTRAL_DIRECTORY_END + + // number of this disk + "\x00\x00" + + // number of the disk with the start of the central directory + "\x00\x00" + + // total number of entries in the central directory on this disk + decToHex(zipData.length, 2) + + // total number of entries in the central directory + decToHex(zipData.length, 2) + + // size of the central directory 4 bytes + decToHex(centralDirLength, 4) + + // offset of start of central directory with respect to the starting disk number + decToHex(localDirLength, 4) + + // .ZIP file comment length + decToHex(utfEncodedComment.length, 2) + + // .ZIP file comment + utfEncodedComment; + + + // we have all the parts (and the total length) + // time to create a writer ! + var typeName = options.type.toLowerCase(); + if(typeName==="uint8array"||typeName==="arraybuffer"||typeName==="blob"||typeName==="nodebuffer") { + writer = new Uint8ArrayWriter(localDirLength + centralDirLength + dirEnd.length); + }else{ + writer = new StringWriter(localDirLength + centralDirLength + dirEnd.length); + } + + for (i = 0; i < zipData.length; i++) { + writer.append(zipData[i].fileRecord); + writer.append(zipData[i].compressedObject.compressedContent); + } + for (i = 0; i < zipData.length; i++) { + writer.append(zipData[i].dirRecord); + } + + writer.append(dirEnd); + + var zip = writer.finalize(); + + + + switch(options.type.toLowerCase()) { + // case "zip is an Uint8Array" + case "uint8array" : + case "arraybuffer" : + case "nodebuffer" : + return utils.transformTo(options.type.toLowerCase(), zip); + case "blob" : + return utils.arrayBuffer2Blob(utils.transformTo("arraybuffer", zip), options.mimeType); + // case "zip is a string" + case "base64" : + return (options.base64) ? base64.encode(zip) : zip; + default : // case "string" : + return zip; + } + + }, + + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + crc32: function (input, crc) { + return crc32(input, crc); + }, + + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + utf8encode: function (string) { + return utils.transformTo("string", utf8.utf8encode(string)); + }, + + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + utf8decode: function (input) { + return utf8.utf8decode(input); + } +}; +module.exports = out; + +},{"./base64":9,"./compressedObject":10,"./compressions":11,"./crc32":12,"./defaults":14,"./nodeBuffer":19,"./signature":22,"./stringWriter":24,"./support":25,"./uint8ArrayWriter":27,"./utf8":28,"./utils":29}],22:[function(require,module,exports){ +'use strict'; +exports.LOCAL_FILE_HEADER = "PK\x03\x04"; +exports.CENTRAL_FILE_HEADER = "PK\x01\x02"; +exports.CENTRAL_DIRECTORY_END = "PK\x05\x06"; +exports.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK\x06\x07"; +exports.ZIP64_CENTRAL_DIRECTORY_END = "PK\x06\x06"; +exports.DATA_DESCRIPTOR = "PK\x07\x08"; + +},{}],23:[function(require,module,exports){ +'use strict'; +var DataReader = require('./dataReader'); +var utils = require('./utils'); + +function StringReader(data, optimizedBinaryString) { + this.data = data; + if (!optimizedBinaryString) { + this.data = utils.string2binary(this.data); + } + this.length = this.data.length; + this.index = 0; +} +StringReader.prototype = new DataReader(); +/** + * @see DataReader.byteAt + */ +StringReader.prototype.byteAt = function(i) { + return this.data.charCodeAt(i); +}; +/** + * @see DataReader.lastIndexOfSignature + */ +StringReader.prototype.lastIndexOfSignature = function(sig) { + return this.data.lastIndexOf(sig); +}; +/** + * @see DataReader.readData + */ +StringReader.prototype.readData = function(size) { + this.checkOffset(size); + // this will work because the constructor applied the "& 0xff" mask. + var result = this.data.slice(this.index, this.index + size); + this.index += size; + return result; +}; +module.exports = StringReader; + +},{"./dataReader":13,"./utils":29}],24:[function(require,module,exports){ +'use strict'; + +var utils = require('./utils'); + +/** + * An object to write any content to a string. + * @constructor + */ +var StringWriter = function() { + this.data = []; +}; +StringWriter.prototype = { + /** + * Append any content to the current string. + * @param {Object} input the content to add. + */ + append: function(input) { + input = utils.transformTo("string", input); + this.data.push(input); + }, + /** + * Finalize the construction an return the result. + * @return {string} the generated string. + */ + finalize: function() { + return this.data.join(""); + } +}; + +module.exports = StringWriter; + +},{"./utils":29}],25:[function(require,module,exports){ +(function (Buffer){ +'use strict'; +exports.base64 = true; +exports.array = true; +exports.string = true; +exports.arraybuffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined"; +// contains true if JSZip can read/generate nodejs Buffer, false otherwise. +// Browserify will provide a Buffer implementation for browsers, which is +// an augmented Uint8Array (i.e., can be used as either Buffer or U8). +exports.nodebuffer = typeof Buffer !== "undefined"; +// contains true if JSZip can read/generate Uint8Array, false otherwise. +exports.uint8array = typeof Uint8Array !== "undefined"; + +if (typeof ArrayBuffer === "undefined") { + exports.blob = false; +} +else { + var buffer = new ArrayBuffer(0); + try { + exports.blob = new Blob([buffer], { + type: "application/zip" + }).size === 0; + } + catch (e) { + try { + var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; + var builder = new Builder(); + builder.append(buffer); + exports.blob = builder.getBlob('application/zip').size === 0; + } + catch (e) { + exports.blob = false; + } + } +} + +}).call(this,require("buffer").Buffer) +},{"buffer":5}],26:[function(require,module,exports){ +'use strict'; +var DataReader = require('./dataReader'); + +function Uint8ArrayReader(data) { + if (data) { + this.data = data; + this.length = this.data.length; + this.index = 0; + } +} +Uint8ArrayReader.prototype = new DataReader(); +/** + * @see DataReader.byteAt + */ +Uint8ArrayReader.prototype.byteAt = function(i) { + return this.data[i]; +}; +/** + * @see DataReader.lastIndexOfSignature + */ +Uint8ArrayReader.prototype.lastIndexOfSignature = function(sig) { + var sig0 = sig.charCodeAt(0), + sig1 = sig.charCodeAt(1), + sig2 = sig.charCodeAt(2), + sig3 = sig.charCodeAt(3); + for (var i = this.length - 4; i >= 0; --i) { + if (this.data[i] === sig0 && this.data[i + 1] === sig1 && this.data[i + 2] === sig2 && this.data[i + 3] === sig3) { + return i; + } + } + + return -1; +}; +/** + * @see DataReader.readData + */ +Uint8ArrayReader.prototype.readData = function(size) { + this.checkOffset(size); + if(size === 0) { + // in IE10, when using subarray(idx, idx), we get the array [0x00] instead of []. + return new Uint8Array(0); + } + var result = this.data.subarray(this.index, this.index + size); + this.index += size; + return result; +}; +module.exports = Uint8ArrayReader; + +},{"./dataReader":13}],27:[function(require,module,exports){ +'use strict'; + +var utils = require('./utils'); + +/** + * An object to write any content to an Uint8Array. + * @constructor + * @param {number} length The length of the array. + */ +var Uint8ArrayWriter = function(length) { + this.data = new Uint8Array(length); + this.index = 0; +}; +Uint8ArrayWriter.prototype = { + /** + * Append any content to the current array. + * @param {Object} input the content to add. + */ + append: function(input) { + if (input.length !== 0) { + // with an empty Uint8Array, Opera fails with a "Offset larger than array size" + input = utils.transformTo("uint8array", input); + this.data.set(input, this.index); + this.index += input.length; + } + }, + /** + * Finalize the construction an return the result. + * @return {Uint8Array} the generated array. + */ + finalize: function() { + return this.data; + } +}; + +module.exports = Uint8ArrayWriter; + +},{"./utils":29}],28:[function(require,module,exports){ +'use strict'; + +var utils = require('./utils'); +var support = require('./support'); +var nodeBuffer = require('./nodeBuffer'); + +/** + * The following functions come from pako, from pako/lib/utils/strings + * released under the MIT license, see pako https://github.com/nodeca/pako/ + */ + +// Table with utf8 lengths (calculated by first byte of sequence) +// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, +// because max possible codepoint is 0x10ffff +var _utf8len = new Array(256); +for (var i=0; i<256; i++) { + _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1); +} +_utf8len[254]=_utf8len[254]=1; // Invalid sequence start + +// convert string to array (typed, when possible) +var string2buf = function (str) { + var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; + + // count binary size + for (m_pos = 0; m_pos < str_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; + } + + // allocate buffer + if (support.uint8array) { + buf = new Uint8Array(buf_len); + } else { + buf = new Array(buf_len); + } + + // convert + for (i=0, m_pos = 0; i < buf_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + if (c < 0x80) { + /* one byte */ + buf[i++] = c; + } else if (c < 0x800) { + /* two bytes */ + buf[i++] = 0xC0 | (c >>> 6); + buf[i++] = 0x80 | (c & 0x3f); + } else if (c < 0x10000) { + /* three bytes */ + buf[i++] = 0xE0 | (c >>> 12); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } else { + /* four bytes */ + buf[i++] = 0xf0 | (c >>> 18); + buf[i++] = 0x80 | (c >>> 12 & 0x3f); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } + } + + return buf; +}; + +// Calculate max possible position in utf8 buffer, +// that will not break sequence. If that's not possible +// - (very small limits) return max size as is. +// +// buf[] - utf8 bytes array +// max - length limit (mandatory); +var utf8border = function(buf, max) { + var pos; + + max = max || buf.length; + if (max > buf.length) { max = buf.length; } + + // go back from last position, until start of sequence found + pos = max-1; + while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } + + // Fuckup - very small and broken sequence, + // return max, because we should return something anyway. + if (pos < 0) { return max; } + + // If we came to start of buffer - that means vuffer is too small, + // return max too. + if (pos === 0) { return max; } + + return (pos + _utf8len[buf[pos]] > max) ? pos : max; +}; + +// convert array to string +var buf2string = function (buf) { + var str, i, out, c, c_len; + var len = buf.length; + + // Reserve max possible length (2 words per char) + // NB: by unknown reasons, Array is significantly faster for + // String.fromCharCode.apply than Uint16Array. + var utf16buf = new Array(len*2); + + for (out=0, i=0; i<len;) { + c = buf[i++]; + // quick process ascii + if (c < 0x80) { utf16buf[out++] = c; continue; } + + c_len = _utf8len[c]; + // skip 5 & 6 byte codes + if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len-1; continue; } + + // apply mask on first byte + c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; + // join the rest + while (c_len > 1 && i < len) { + c = (c << 6) | (buf[i++] & 0x3f); + c_len--; + } + + // terminated by end of string? + if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } + + if (c < 0x10000) { + utf16buf[out++] = c; + } else { + c -= 0x10000; + utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); + utf16buf[out++] = 0xdc00 | (c & 0x3ff); + } + } + + // shrinkBuf(utf16buf, out) + if (utf16buf.length !== out) { + if(utf16buf.subarray) { + utf16buf = utf16buf.subarray(0, out); + } else { + utf16buf.length = out; + } + } + + // return String.fromCharCode.apply(null, utf16buf); + return utils.applyFromCharCode(utf16buf); +}; + + +// That's all for the pako functions. + + +/** + * Transform a javascript string into an array (typed if possible) of bytes, + * UTF-8 encoded. + * @param {String} str the string to encode + * @return {Array|Uint8Array|Buffer} the UTF-8 encoded string. + */ +exports.utf8encode = function utf8encode(str) { + if (support.nodebuffer) { + return nodeBuffer(str, "utf-8"); + } + + return string2buf(str); +}; + + +/** + * Transform a bytes array (or a representation) representing an UTF-8 encoded + * string into a javascript string. + * @param {Array|Uint8Array|Buffer} buf the data de decode + * @return {String} the decoded string. + */ +exports.utf8decode = function utf8decode(buf) { + if (support.nodebuffer) { + return utils.transformTo("nodebuffer", buf).toString("utf-8"); + } + + buf = utils.transformTo(support.uint8array ? "uint8array" : "array", buf); + + // return buf2string(buf); + // Chrome prefers to work with "small" chunks of data + // for the method buf2string. + // Firefox and Chrome has their own shortcut, IE doesn't seem to really care. + var result = [], k = 0, len = buf.length, chunk = 65536; + while (k < len) { + var nextBoundary = utf8border(buf, Math.min(k + chunk, len)); + if (support.uint8array) { + result.push(buf2string(buf.subarray(k, nextBoundary))); + } else { + result.push(buf2string(buf.slice(k, nextBoundary))); + } + k = nextBoundary; + } + return result.join(""); + +}; +// vim: set shiftwidth=4 softtabstop=4: + +},{"./nodeBuffer":19,"./support":25,"./utils":29}],29:[function(require,module,exports){ +'use strict'; +var support = require('./support'); +var compressions = require('./compressions'); +var nodeBuffer = require('./nodeBuffer'); +/** + * Convert a string to a "binary string" : a string containing only char codes between 0 and 255. + * @param {string} str the string to transform. + * @return {String} the binary string. + */ +exports.string2binary = function(str) { + var result = ""; + for (var i = 0; i < str.length; i++) { + result += String.fromCharCode(str.charCodeAt(i) & 0xff); + } + return result; +}; +exports.arrayBuffer2Blob = function(buffer, mimeType) { + exports.checkSupport("blob"); + mimeType = mimeType || 'application/zip'; + + try { + // Blob constructor + return new Blob([buffer], { + type: mimeType + }); + } + catch (e) { + + try { + // deprecated, browser only, old way + var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; + var builder = new Builder(); + builder.append(buffer); + return builder.getBlob(mimeType); + } + catch (e) { + + // well, fuck ?! + throw new Error("Bug : can't construct the Blob."); + } + } + + +}; +/** + * The identity function. + * @param {Object} input the input. + * @return {Object} the same input. + */ +function identity(input) { + return input; +} + +/** + * Fill in an array with a string. + * @param {String} str the string to use. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to fill in (will be mutated). + * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated array. + */ +function stringToArrayLike(str, array) { + for (var i = 0; i < str.length; ++i) { + array[i] = str.charCodeAt(i) & 0xFF; + } + return array; +} + +/** + * Transform an array-like object to a string. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. + * @return {String} the result. + */ +function arrayLikeToString(array) { + // Performances notes : + // -------------------- + // String.fromCharCode.apply(null, array) is the fastest, see + // see http://jsperf.com/converting-a-uint8array-to-a-string/2 + // but the stack is limited (and we can get huge arrays !). + // + // result += String.fromCharCode(array[i]); generate too many strings ! + // + // This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2 + var chunk = 65536; + var result = [], + len = array.length, + type = exports.getTypeOf(array), + k = 0, + canUseApply = true; + try { + switch(type) { + case "uint8array": + String.fromCharCode.apply(null, new Uint8Array(0)); + break; + case "nodebuffer": + String.fromCharCode.apply(null, nodeBuffer(0)); + break; + } + } catch(e) { + canUseApply = false; + } + + // no apply : slow and painful algorithm + // default browser on android 4.* + if (!canUseApply) { + var resultStr = ""; + for(var i = 0; i < array.length;i++) { + resultStr += String.fromCharCode(array[i]); + } + return resultStr; + } + while (k < len && chunk > 1) { + try { + if (type === "array" || type === "nodebuffer") { + result.push(String.fromCharCode.apply(null, array.slice(k, Math.min(k + chunk, len)))); + } + else { + result.push(String.fromCharCode.apply(null, array.subarray(k, Math.min(k + chunk, len)))); + } + k += chunk; + } + catch (e) { + chunk = Math.floor(chunk / 2); + } + } + return result.join(""); +} + +exports.applyFromCharCode = arrayLikeToString; + + +/** + * Copy the data from an array-like to an other array-like. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayFrom the origin array. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayTo the destination array which will be mutated. + * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated destination array. + */ +function arrayLikeToArrayLike(arrayFrom, arrayTo) { + for (var i = 0; i < arrayFrom.length; i++) { + arrayTo[i] = arrayFrom[i]; + } + return arrayTo; +} + +// a matrix containing functions to transform everything into everything. +var transform = {}; + +// string to ? +transform["string"] = { + "string": identity, + "array": function(input) { + return stringToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return transform["string"]["uint8array"](input).buffer; + }, + "uint8array": function(input) { + return stringToArrayLike(input, new Uint8Array(input.length)); + }, + "nodebuffer": function(input) { + return stringToArrayLike(input, nodeBuffer(input.length)); + } +}; + +// array to ? +transform["array"] = { + "string": arrayLikeToString, + "array": identity, + "arraybuffer": function(input) { + return (new Uint8Array(input)).buffer; + }, + "uint8array": function(input) { + return new Uint8Array(input); + }, + "nodebuffer": function(input) { + return nodeBuffer(input); + } +}; + +// arraybuffer to ? +transform["arraybuffer"] = { + "string": function(input) { + return arrayLikeToString(new Uint8Array(input)); + }, + "array": function(input) { + return arrayLikeToArrayLike(new Uint8Array(input), new Array(input.byteLength)); + }, + "arraybuffer": identity, + "uint8array": function(input) { + return new Uint8Array(input); + }, + "nodebuffer": function(input) { + return nodeBuffer(new Uint8Array(input)); + } +}; + +// uint8array to ? +transform["uint8array"] = { + "string": arrayLikeToString, + "array": function(input) { + return arrayLikeToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return input.buffer; + }, + "uint8array": identity, + "nodebuffer": function(input) { + return nodeBuffer(input); + } +}; + +// nodebuffer to ? +transform["nodebuffer"] = { + "string": arrayLikeToString, + "array": function(input) { + return arrayLikeToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return transform["nodebuffer"]["uint8array"](input).buffer; + }, + "uint8array": function(input) { + return arrayLikeToArrayLike(input, new Uint8Array(input.length)); + }, + "nodebuffer": identity +}; + +/** + * Transform an input into any type. + * The supported output type are : string, array, uint8array, arraybuffer, nodebuffer. + * If no output type is specified, the unmodified input will be returned. + * @param {String} outputType the output type. + * @param {String|Array|ArrayBuffer|Uint8Array|Buffer} input the input to convert. + * @throws {Error} an Error if the browser doesn't support the requested output type. + */ +exports.transformTo = function(outputType, input) { + if (!input) { + // undefined, null, etc + // an empty string won't harm. + input = ""; + } + if (!outputType) { + return input; + } + exports.checkSupport(outputType); + var inputType = exports.getTypeOf(input); + var result = transform[inputType][outputType](input); + return result; +}; + +/** + * Return the type of the input. + * The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer. + * @param {Object} input the input to identify. + * @return {String} the (lowercase) type of the input. + */ +exports.getTypeOf = function(input) { + if (typeof input === "string") { + return "string"; + } + if (Object.prototype.toString.call(input) === "[object Array]") { + return "array"; + } + if (support.nodebuffer && nodeBuffer.test(input)) { + return "nodebuffer"; + } + if (support.uint8array && input instanceof Uint8Array) { + return "uint8array"; + } + if (support.arraybuffer && input instanceof ArrayBuffer) { + return "arraybuffer"; + } +}; + +/** + * Throw an exception if the type is not supported. + * @param {String} type the type to check. + * @throws {Error} an Error if the browser doesn't support the requested type. + */ +exports.checkSupport = function(type) { + var supported = support[type.toLowerCase()]; + if (!supported) { + throw new Error(type + " is not supported by this browser"); + } +}; +exports.MAX_VALUE_16BITS = 65535; +exports.MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1 + +/** + * Prettify a string read as binary. + * @param {string} str the string to prettify. + * @return {string} a pretty string. + */ +exports.pretty = function(str) { + var res = '', + code, i; + for (i = 0; i < (str || "").length; i++) { + code = str.charCodeAt(i); + res += '\\x' + (code < 16 ? "0" : "") + code.toString(16).toUpperCase(); + } + return res; +}; + +/** + * Find a compression registered in JSZip. + * @param {string} compressionMethod the method magic to find. + * @return {Object|null} the JSZip compression object, null if none found. + */ +exports.findCompression = function(compressionMethod) { + for (var method in compressions) { + if (!compressions.hasOwnProperty(method)) { + continue; + } + if (compressions[method].magic === compressionMethod) { + return compressions[method]; + } + } + return null; +}; +/** +* Cross-window, cross-Node-context regular expression detection +* @param {Object} object Anything +* @return {Boolean} true if the object is a regular expression, +* false otherwise +*/ +exports.isRegExp = function (object) { + return Object.prototype.toString.call(object) === "[object RegExp]"; +}; + + +},{"./compressions":11,"./nodeBuffer":19,"./support":25}],30:[function(require,module,exports){ +'use strict'; +var StringReader = require('./stringReader'); +var NodeBufferReader = require('./nodeBufferReader'); +var Uint8ArrayReader = require('./uint8ArrayReader'); +var utils = require('./utils'); +var sig = require('./signature'); +var ZipEntry = require('./zipEntry'); +var support = require('./support'); +var jszipProto = require('./object'); +// class ZipEntries {{{ +/** + * All the entries in the zip file. + * @constructor + * @param {String|ArrayBuffer|Uint8Array} data the binary stream to load. + * @param {Object} loadOptions Options for loading the stream. + */ +function ZipEntries(data, loadOptions) { + this.files = []; + this.loadOptions = loadOptions; + if (data) { + this.load(data); + } +} +ZipEntries.prototype = { + /** + * Check that the reader is on the speficied signature. + * @param {string} expectedSignature the expected signature. + * @throws {Error} if it is an other signature. + */ + checkSignature: function(expectedSignature) { + var signature = this.reader.readString(4); + if (signature !== expectedSignature) { + throw new Error("Corrupted zip or bug : unexpected signature " + "(" + utils.pretty(signature) + ", expected " + utils.pretty(expectedSignature) + ")"); + } + }, + /** + * Read the end of the central directory. + */ + readBlockEndOfCentral: function() { + this.diskNumber = this.reader.readInt(2); + this.diskWithCentralDirStart = this.reader.readInt(2); + this.centralDirRecordsOnThisDisk = this.reader.readInt(2); + this.centralDirRecords = this.reader.readInt(2); + this.centralDirSize = this.reader.readInt(4); + this.centralDirOffset = this.reader.readInt(4); + + this.zipCommentLength = this.reader.readInt(2); + // warning : the encoding depends of the system locale + // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded. + // On a windows machine, this field is encoded with the localized windows code page. + this.zipComment = this.reader.readString(this.zipCommentLength); + // To get consistent behavior with the generation part, we will assume that + // this is utf8 encoded. + this.zipComment = jszipProto.utf8decode(this.zipComment); + }, + /** + * Read the end of the Zip 64 central directory. + * Not merged with the method readEndOfCentral : + * The end of central can coexist with its Zip64 brother, + * I don't want to read the wrong number of bytes ! + */ + readBlockZip64EndOfCentral: function() { + this.zip64EndOfCentralSize = this.reader.readInt(8); + this.versionMadeBy = this.reader.readString(2); + this.versionNeeded = this.reader.readInt(2); + this.diskNumber = this.reader.readInt(4); + this.diskWithCentralDirStart = this.reader.readInt(4); + this.centralDirRecordsOnThisDisk = this.reader.readInt(8); + this.centralDirRecords = this.reader.readInt(8); + this.centralDirSize = this.reader.readInt(8); + this.centralDirOffset = this.reader.readInt(8); + + this.zip64ExtensibleData = {}; + var extraDataSize = this.zip64EndOfCentralSize - 44, + index = 0, + extraFieldId, + extraFieldLength, + extraFieldValue; + while (index < extraDataSize) { + extraFieldId = this.reader.readInt(2); + extraFieldLength = this.reader.readInt(4); + extraFieldValue = this.reader.readString(extraFieldLength); + this.zip64ExtensibleData[extraFieldId] = { + id: extraFieldId, + length: extraFieldLength, + value: extraFieldValue + }; + } + }, + /** + * Read the end of the Zip 64 central directory locator. + */ + readBlockZip64EndOfCentralLocator: function() { + this.diskWithZip64CentralDirStart = this.reader.readInt(4); + this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8); + this.disksCount = this.reader.readInt(4); + if (this.disksCount > 1) { + throw new Error("Multi-volumes zip are not supported"); + } + }, + /** + * Read the local files, based on the offset read in the central part. + */ + readLocalFiles: function() { + var i, file; + for (i = 0; i < this.files.length; i++) { + file = this.files[i]; + this.reader.setIndex(file.localHeaderOffset); + this.checkSignature(sig.LOCAL_FILE_HEADER); + file.readLocalPart(this.reader); + file.handleUTF8(); + file.processAttributes(); + } + }, + /** + * Read the central directory. + */ + readCentralDir: function() { + var file; + + this.reader.setIndex(this.centralDirOffset); + while (this.reader.readString(4) === sig.CENTRAL_FILE_HEADER) { + file = new ZipEntry({ + zip64: this.zip64 + }, this.loadOptions); + file.readCentralPart(this.reader); + this.files.push(file); + } + }, + /** + * Read the end of central directory. + */ + readEndOfCentral: function() { + var offset = this.reader.lastIndexOfSignature(sig.CENTRAL_DIRECTORY_END); + if (offset === -1) { + // Check if the content is a truncated zip or complete garbage. + // A "LOCAL_FILE_HEADER" is not required at the beginning (auto + // extractible zip for example) but it can give a good hint. + // If an ajax request was used without responseType, we will also + // get unreadable data. + var isGarbage = true; + try { + this.reader.setIndex(0); + this.checkSignature(sig.LOCAL_FILE_HEADER); + isGarbage = false; + } catch (e) {} + + if (isGarbage) { + throw new Error("Can't find end of central directory : is this a zip file ? " + + "If it is, see http://stuk.github.io/jszip/documentation/howto/read_zip.html"); + } else { + throw new Error("Corrupted zip : can't find end of central directory"); + } + } + this.reader.setIndex(offset); + this.checkSignature(sig.CENTRAL_DIRECTORY_END); + this.readBlockEndOfCentral(); + + + /* extract from the zip spec : + 4) If one of the fields in the end of central directory + record is too small to hold required data, the field + should be set to -1 (0xFFFF or 0xFFFFFFFF) and the + ZIP64 format record should be created. + 5) The end of central directory record and the + Zip64 end of central directory locator record must + reside on the same disk when splitting or spanning + an archive. + */ + if (this.diskNumber === utils.MAX_VALUE_16BITS || this.diskWithCentralDirStart === utils.MAX_VALUE_16BITS || this.centralDirRecordsOnThisDisk === utils.MAX_VALUE_16BITS || this.centralDirRecords === utils.MAX_VALUE_16BITS || this.centralDirSize === utils.MAX_VALUE_32BITS || this.centralDirOffset === utils.MAX_VALUE_32BITS) { + this.zip64 = true; + + /* + Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from + the zip file can fit into a 32bits integer. This cannot be solved : Javascript represents + all numbers as 64-bit double precision IEEE 754 floating point numbers. + So, we have 53bits for integers and bitwise operations treat everything as 32bits. + see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators + and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5 + */ + + // should look for a zip64 EOCD locator + offset = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); + if (offset === -1) { + throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator"); + } + this.reader.setIndex(offset); + this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); + this.readBlockZip64EndOfCentralLocator(); + + // now the zip64 EOCD record + this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir); + this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_END); + this.readBlockZip64EndOfCentral(); + } + }, + prepareReader: function(data) { + var type = utils.getTypeOf(data); + if (type === "string" && !support.uint8array) { + this.reader = new StringReader(data, this.loadOptions.optimizedBinaryString); + } + else if (type === "nodebuffer") { + this.reader = new NodeBufferReader(data); + } + else { + this.reader = new Uint8ArrayReader(utils.transformTo("uint8array", data)); + } + }, + /** + * Read a zip file and create ZipEntries. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file. + */ + load: function(data) { + this.prepareReader(data); + this.readEndOfCentral(); + this.readCentralDir(); + this.readLocalFiles(); + } +}; +// }}} end of ZipEntries +module.exports = ZipEntries; + +},{"./nodeBufferReader":20,"./object":21,"./signature":22,"./stringReader":23,"./support":25,"./uint8ArrayReader":26,"./utils":29,"./zipEntry":31}],31:[function(require,module,exports){ +'use strict'; +var StringReader = require('./stringReader'); +var utils = require('./utils'); +var CompressedObject = require('./compressedObject'); +var jszipProto = require('./object'); + +var MADE_BY_DOS = 0x00; +var MADE_BY_UNIX = 0x03; + +// class ZipEntry {{{ +/** + * An entry in the zip file. + * @constructor + * @param {Object} options Options of the current file. + * @param {Object} loadOptions Options for loading the stream. + */ +function ZipEntry(options, loadOptions) { + this.options = options; + this.loadOptions = loadOptions; +} +ZipEntry.prototype = { + /** + * say if the file is encrypted. + * @return {boolean} true if the file is encrypted, false otherwise. + */ + isEncrypted: function() { + // bit 1 is set + return (this.bitFlag & 0x0001) === 0x0001; + }, + /** + * say if the file has utf-8 filename/comment. + * @return {boolean} true if the filename/comment is in utf-8, false otherwise. + */ + useUTF8: function() { + // bit 11 is set + return (this.bitFlag & 0x0800) === 0x0800; + }, + /** + * Prepare the function used to generate the compressed content from this ZipFile. + * @param {DataReader} reader the reader to use. + * @param {number} from the offset from where we should read the data. + * @param {number} length the length of the data to read. + * @return {Function} the callback to get the compressed content (the type depends of the DataReader class). + */ + prepareCompressedContent: function(reader, from, length) { + return function() { + var previousIndex = reader.index; + reader.setIndex(from); + var compressedFileData = reader.readData(length); + reader.setIndex(previousIndex); + + return compressedFileData; + }; + }, + /** + * Prepare the function used to generate the uncompressed content from this ZipFile. + * @param {DataReader} reader the reader to use. + * @param {number} from the offset from where we should read the data. + * @param {number} length the length of the data to read. + * @param {JSZip.compression} compression the compression used on this file. + * @param {number} uncompressedSize the uncompressed size to expect. + * @return {Function} the callback to get the uncompressed content (the type depends of the DataReader class). + */ + prepareContent: function(reader, from, length, compression, uncompressedSize) { + return function() { + + var compressedFileData = utils.transformTo(compression.uncompressInputType, this.getCompressedContent()); + var uncompressedFileData = compression.uncompress(compressedFileData); + + if (uncompressedFileData.length !== uncompressedSize) { + throw new Error("Bug : uncompressed data size mismatch"); + } + + return uncompressedFileData; + }; + }, + /** + * Read the local part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readLocalPart: function(reader) { + var compression, localExtraFieldsLength; + + // we already know everything from the central dir ! + // If the central dir data are false, we are doomed. + // On the bright side, the local part is scary : zip64, data descriptors, both, etc. + // The less data we get here, the more reliable this should be. + // Let's skip the whole header and dash to the data ! + reader.skip(22); + // in some zip created on windows, the filename stored in the central dir contains \ instead of /. + // Strangely, the filename here is OK. + // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes + // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators... + // Search "unzip mismatching "local" filename continuing with "central" filename version" on + // the internet. + // + // I think I see the logic here : the central directory is used to display + // content and the local directory is used to extract the files. Mixing / and \ + // may be used to display \ to windows users and use / when extracting the files. + // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394 + this.fileNameLength = reader.readInt(2); + localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir + this.fileName = reader.readString(this.fileNameLength); + reader.skip(localExtraFieldsLength); + + if (this.compressedSize == -1 || this.uncompressedSize == -1) { + throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + "(compressedSize == -1 || uncompressedSize == -1)"); + } + + compression = utils.findCompression(this.compressionMethod); + if (compression === null) { // no compression found + throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + this.fileName + ")"); + } + this.decompressed = new CompressedObject(); + this.decompressed.compressedSize = this.compressedSize; + this.decompressed.uncompressedSize = this.uncompressedSize; + this.decompressed.crc32 = this.crc32; + this.decompressed.compressionMethod = this.compressionMethod; + this.decompressed.getCompressedContent = this.prepareCompressedContent(reader, reader.index, this.compressedSize, compression); + this.decompressed.getContent = this.prepareContent(reader, reader.index, this.compressedSize, compression, this.uncompressedSize); + + // we need to compute the crc32... + if (this.loadOptions.checkCRC32) { + this.decompressed = utils.transformTo("string", this.decompressed.getContent()); + if (jszipProto.crc32(this.decompressed) !== this.crc32) { + throw new Error("Corrupted zip : CRC32 mismatch"); + } + } + }, + + /** + * Read the central part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readCentralPart: function(reader) { + this.versionMadeBy = reader.readInt(2); + this.versionNeeded = reader.readInt(2); + this.bitFlag = reader.readInt(2); + this.compressionMethod = reader.readString(2); + this.date = reader.readDate(); + this.crc32 = reader.readInt(4); + this.compressedSize = reader.readInt(4); + this.uncompressedSize = reader.readInt(4); + this.fileNameLength = reader.readInt(2); + this.extraFieldsLength = reader.readInt(2); + this.fileCommentLength = reader.readInt(2); + this.diskNumberStart = reader.readInt(2); + this.internalFileAttributes = reader.readInt(2); + this.externalFileAttributes = reader.readInt(4); + this.localHeaderOffset = reader.readInt(4); + + if (this.isEncrypted()) { + throw new Error("Encrypted zip are not supported"); + } + + this.fileName = reader.readString(this.fileNameLength); + this.readExtraFields(reader); + this.parseZIP64ExtraField(reader); + this.fileComment = reader.readString(this.fileCommentLength); + }, + + /** + * Parse the external file attributes and get the unix/dos permissions. + */ + processAttributes: function () { + this.unixPermissions = null; + this.dosPermissions = null; + var madeBy = this.versionMadeBy >> 8; + + // Check if we have the DOS directory flag set. + // We look for it in the DOS and UNIX permissions + // but some unknown platform could set it as a compatibility flag. + this.dir = this.externalFileAttributes & 0x0010 ? true : false; + + if(madeBy === MADE_BY_DOS) { + // first 6 bits (0 to 5) + this.dosPermissions = this.externalFileAttributes & 0x3F; + } + + if(madeBy === MADE_BY_UNIX) { + this.unixPermissions = (this.externalFileAttributes >> 16) & 0xFFFF; + // the octal permissions are in (this.unixPermissions & 0x01FF).toString(8); + } + + // fail safe : if the name ends with a / it probably means a folder + if (!this.dir && this.fileName.slice(-1) === '/') { + this.dir = true; + } + }, + + /** + * Parse the ZIP64 extra field and merge the info in the current ZipEntry. + * @param {DataReader} reader the reader to use. + */ + parseZIP64ExtraField: function(reader) { + + if (!this.extraFields[0x0001]) { + return; + } + + // should be something, preparing the extra reader + var extraReader = new StringReader(this.extraFields[0x0001].value); + + // I really hope that these 64bits integer can fit in 32 bits integer, because js + // won't let us have more. + if (this.uncompressedSize === utils.MAX_VALUE_32BITS) { + this.uncompressedSize = extraReader.readInt(8); + } + if (this.compressedSize === utils.MAX_VALUE_32BITS) { + this.compressedSize = extraReader.readInt(8); + } + if (this.localHeaderOffset === utils.MAX_VALUE_32BITS) { + this.localHeaderOffset = extraReader.readInt(8); + } + if (this.diskNumberStart === utils.MAX_VALUE_32BITS) { + this.diskNumberStart = extraReader.readInt(4); + } + }, + /** + * Read the central part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readExtraFields: function(reader) { + var start = reader.index, + extraFieldId, + extraFieldLength, + extraFieldValue; + + this.extraFields = this.extraFields || {}; + + while (reader.index < start + this.extraFieldsLength) { + extraFieldId = reader.readInt(2); + extraFieldLength = reader.readInt(2); + extraFieldValue = reader.readString(extraFieldLength); + + this.extraFields[extraFieldId] = { + id: extraFieldId, + length: extraFieldLength, + value: extraFieldValue + }; + } + }, + /** + * Apply an UTF8 transformation if needed. + */ + handleUTF8: function() { + if (this.useUTF8()) { + this.fileName = jszipProto.utf8decode(this.fileName); + this.fileComment = jszipProto.utf8decode(this.fileComment); + } else { + var upath = this.findExtraFieldUnicodePath(); + if (upath !== null) { + this.fileName = upath; + } + var ucomment = this.findExtraFieldUnicodeComment(); + if (ucomment !== null) { + this.fileComment = ucomment; + } + } + }, + + /** + * Find the unicode path declared in the extra field, if any. + * @return {String} the unicode path, null otherwise. + */ + findExtraFieldUnicodePath: function() { + var upathField = this.extraFields[0x7075]; + if (upathField) { + var extraReader = new StringReader(upathField.value); + + // wrong version + if (extraReader.readInt(1) !== 1) { + return null; + } + + // the crc of the filename changed, this field is out of date. + if (jszipProto.crc32(this.fileName) !== extraReader.readInt(4)) { + return null; + } + + return jszipProto.utf8decode(extraReader.readString(upathField.length - 5)); + } + return null; + }, + + /** + * Find the unicode comment declared in the extra field, if any. + * @return {String} the unicode comment, null otherwise. + */ + findExtraFieldUnicodeComment: function() { + var ucommentField = this.extraFields[0x6375]; + if (ucommentField) { + var extraReader = new StringReader(ucommentField.value); + + // wrong version + if (extraReader.readInt(1) !== 1) { + return null; + } + + // the crc of the comment changed, this field is out of date. + if (jszipProto.crc32(this.fileComment) !== extraReader.readInt(4)) { + return null; + } + + return jszipProto.utf8decode(extraReader.readString(ucommentField.length - 5)); + } + return null; + } +}; +module.exports = ZipEntry; + +},{"./compressedObject":10,"./object":21,"./stringReader":23,"./utils":29}],32:[function(require,module,exports){ +// Top level file is just a mixin of submodules & constants +'use strict'; + +var assign = require('./lib/utils/common').assign; + +var deflate = require('./lib/deflate'); +var inflate = require('./lib/inflate'); +var constants = require('./lib/zlib/constants'); + +var pako = {}; + +assign(pako, deflate, inflate, constants); + +module.exports = pako; + +},{"./lib/deflate":33,"./lib/inflate":34,"./lib/utils/common":35,"./lib/zlib/constants":38}],33:[function(require,module,exports){ +'use strict'; + + +var zlib_deflate = require('./zlib/deflate.js'); +var utils = require('./utils/common'); +var strings = require('./utils/strings'); +var msg = require('./zlib/messages'); +var zstream = require('./zlib/zstream'); + +var toString = Object.prototype.toString; + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + +var Z_NO_FLUSH = 0; +var Z_FINISH = 4; + +var Z_OK = 0; +var Z_STREAM_END = 1; +var Z_SYNC_FLUSH = 2; + +var Z_DEFAULT_COMPRESSION = -1; + +var Z_DEFAULT_STRATEGY = 0; + +var Z_DEFLATED = 8; + +/* ===========================================================================*/ + + +/** + * class Deflate + * + * Generic JS-style wrapper for zlib calls. If you don't need + * streaming behaviour - use more simple functions: [[deflate]], + * [[deflateRaw]] and [[gzip]]. + **/ + +/* internal + * Deflate.chunks -> Array + * + * Chunks of output data, if [[Deflate#onData]] not overriden. + **/ + +/** + * Deflate.result -> Uint8Array|Array + * + * Compressed result, generated by default [[Deflate#onData]] + * and [[Deflate#onEnd]] handlers. Filled after you push last chunk + * (call [[Deflate#push]] with `Z_FINISH` / `true` param) or if you + * push a chunk with explicit flush (call [[Deflate#push]] with + * `Z_SYNC_FLUSH` param). + **/ + +/** + * Deflate.err -> Number + * + * Error code after deflate finished. 0 (Z_OK) on success. + * You will not need it in real life, because deflate errors + * are possible only on wrong options or bad `onData` / `onEnd` + * custom handlers. + **/ + +/** + * Deflate.msg -> String + * + * Error message, if [[Deflate.err]] != 0 + **/ + + +/** + * new Deflate(options) + * - options (Object): zlib deflate options. + * + * Creates new deflator instance with specified params. Throws exception + * on bad params. Supported options: + * + * - `level` + * - `windowBits` + * - `memLevel` + * - `strategy` + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Additional options, for internal needs: + * + * - `chunkSize` - size of generated data chunks (16K by default) + * - `raw` (Boolean) - do raw deflate + * - `gzip` (Boolean) - create gzip wrapper + * - `to` (String) - if equal to 'string', then result will be "binary string" + * (each char code [0..255]) + * - `header` (Object) - custom header for gzip + * - `text` (Boolean) - true if compressed data believed to be text + * - `time` (Number) - modification time, unix timestamp + * - `os` (Number) - operation system code + * - `extra` (Array) - array of bytes with extra data (max 65536) + * - `name` (String) - file name (binary string) + * - `comment` (String) - comment (binary string) + * - `hcrc` (Boolean) - true if header crc should be added + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) + * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); + * + * var deflate = new pako.Deflate({ level: 3}); + * + * deflate.push(chunk1, false); + * deflate.push(chunk2, true); // true -> last chunk + * + * if (deflate.err) { throw new Error(deflate.err); } + * + * console.log(deflate.result); + * ``` + **/ +var Deflate = function(options) { + + this.options = utils.assign({ + level: Z_DEFAULT_COMPRESSION, + method: Z_DEFLATED, + chunkSize: 16384, + windowBits: 15, + memLevel: 8, + strategy: Z_DEFAULT_STRATEGY, + to: '' + }, options || {}); + + var opt = this.options; + + if (opt.raw && (opt.windowBits > 0)) { + opt.windowBits = -opt.windowBits; + } + + else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) { + opt.windowBits += 16; + } + + this.err = 0; // error code, if happens (0 = Z_OK) + this.msg = ''; // error message + this.ended = false; // used to avoid multiple onEnd() calls + this.chunks = []; // chunks of compressed data + + this.strm = new zstream(); + this.strm.avail_out = 0; + + var status = zlib_deflate.deflateInit2( + this.strm, + opt.level, + opt.method, + opt.windowBits, + opt.memLevel, + opt.strategy + ); + + if (status !== Z_OK) { + throw new Error(msg[status]); + } + + if (opt.header) { + zlib_deflate.deflateSetHeader(this.strm, opt.header); + } +}; + +/** + * Deflate#push(data[, mode]) -> Boolean + * - data (Uint8Array|Array|ArrayBuffer|String): input data. Strings will be + * converted to utf8 byte sequence. + * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. + * See constants. Skipped or `false` means Z_NO_FLUSH, `true` meansh Z_FINISH. + * + * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with + * new compressed chunks. Returns `true` on success. The last data block must have + * mode Z_FINISH (or `true`). That will flush internal pending buffers and call + * [[Deflate#onEnd]]. For interim explicit flushes (without ending the stream) you + * can use mode Z_SYNC_FLUSH, keeping the compression context. + * + * On fail call [[Deflate#onEnd]] with error code and return false. + * + * We strongly recommend to use `Uint8Array` on input for best speed (output + * array format is detected automatically). Also, don't skip last param and always + * use the same type in your code (boolean or number). That will improve JS speed. + * + * For regular `Array`-s make sure all elements are [0..255]. + * + * ##### Example + * + * ```javascript + * push(chunk, false); // push one of data chunks + * ... + * push(chunk, true); // push last chunk + * ``` + **/ +Deflate.prototype.push = function(data, mode) { + var strm = this.strm; + var chunkSize = this.options.chunkSize; + var status, _mode; + + if (this.ended) { return false; } + + _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH); + + // Convert data if needed + if (typeof data === 'string') { + // If we need to compress text, change encoding to utf8. + strm.input = strings.string2buf(data); + } else if (toString.call(data) === '[object ArrayBuffer]') { + strm.input = new Uint8Array(data); + } else { + strm.input = data; + } + + strm.next_in = 0; + strm.avail_in = strm.input.length; + + do { + if (strm.avail_out === 0) { + strm.output = new utils.Buf8(chunkSize); + strm.next_out = 0; + strm.avail_out = chunkSize; + } + status = zlib_deflate.deflate(strm, _mode); /* no bad return value */ + + if (status !== Z_STREAM_END && status !== Z_OK) { + this.onEnd(status); + this.ended = true; + return false; + } + if (strm.avail_out === 0 || (strm.avail_in === 0 && (_mode === Z_FINISH || _mode === Z_SYNC_FLUSH))) { + if (this.options.to === 'string') { + this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out))); + } else { + this.onData(utils.shrinkBuf(strm.output, strm.next_out)); + } + } + } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END); + + // Finalize on the last chunk. + if (_mode === Z_FINISH) { + status = zlib_deflate.deflateEnd(this.strm); + this.onEnd(status); + this.ended = true; + return status === Z_OK; + } + + // callback interim results if Z_SYNC_FLUSH. + if (_mode === Z_SYNC_FLUSH) { + this.onEnd(Z_OK); + strm.avail_out = 0; + return true; + } + + return true; +}; + + +/** + * Deflate#onData(chunk) -> Void + * - chunk (Uint8Array|Array|String): ouput data. Type of array depends + * on js engine support. When string output requested, each chunk + * will be string. + * + * By default, stores data blocks in `chunks[]` property and glue + * those in `onEnd`. Override this handler, if you need another behaviour. + **/ +Deflate.prototype.onData = function(chunk) { + this.chunks.push(chunk); +}; + + +/** + * Deflate#onEnd(status) -> Void + * - status (Number): deflate status. 0 (Z_OK) on success, + * other if not. + * + * Called once after you tell deflate that the input stream is + * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH) + * or if an error happened. By default - join collected chunks, + * free memory and fill `results` / `err` properties. + **/ +Deflate.prototype.onEnd = function(status) { + // On success - join + if (status === Z_OK) { + if (this.options.to === 'string') { + this.result = this.chunks.join(''); + } else { + this.result = utils.flattenChunks(this.chunks); + } + } + this.chunks = []; + this.err = status; + this.msg = this.strm.msg; +}; + + +/** + * deflate(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to compress. + * - options (Object): zlib deflate options. + * + * Compress `data` with deflate alrorythm and `options`. + * + * Supported options are: + * + * - level + * - windowBits + * - memLevel + * - strategy + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Sugar (options): + * + * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify + * negative windowBits implicitly. + * - `to` (String) - if equal to 'string', then result will be "binary string" + * (each char code [0..255]) + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , data = Uint8Array([1,2,3,4,5,6,7,8,9]); + * + * console.log(pako.deflate(data)); + * ``` + **/ +function deflate(input, options) { + var deflator = new Deflate(options); + + deflator.push(input, true); + + // That will never happens, if you don't cheat with options :) + if (deflator.err) { throw deflator.msg; } + + return deflator.result; +} + + +/** + * deflateRaw(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to compress. + * - options (Object): zlib deflate options. + * + * The same as [[deflate]], but creates raw data, without wrapper + * (header and adler32 crc). + **/ +function deflateRaw(input, options) { + options = options || {}; + options.raw = true; + return deflate(input, options); +} + + +/** + * gzip(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to compress. + * - options (Object): zlib deflate options. + * + * The same as [[deflate]], but create gzip wrapper instead of + * deflate one. + **/ +function gzip(input, options) { + options = options || {}; + options.gzip = true; + return deflate(input, options); +} + + +exports.Deflate = Deflate; +exports.deflate = deflate; +exports.deflateRaw = deflateRaw; +exports.gzip = gzip; + +},{"./utils/common":35,"./utils/strings":36,"./zlib/deflate.js":40,"./zlib/messages":45,"./zlib/zstream":47}],34:[function(require,module,exports){ +'use strict'; + + +var zlib_inflate = require('./zlib/inflate.js'); +var utils = require('./utils/common'); +var strings = require('./utils/strings'); +var c = require('./zlib/constants'); +var msg = require('./zlib/messages'); +var zstream = require('./zlib/zstream'); +var gzheader = require('./zlib/gzheader'); + +var toString = Object.prototype.toString; + +/** + * class Inflate + * + * Generic JS-style wrapper for zlib calls. If you don't need + * streaming behaviour - use more simple functions: [[inflate]] + * and [[inflateRaw]]. + **/ + +/* internal + * inflate.chunks -> Array + * + * Chunks of output data, if [[Inflate#onData]] not overriden. + **/ + +/** + * Inflate.result -> Uint8Array|Array|String + * + * Uncompressed result, generated by default [[Inflate#onData]] + * and [[Inflate#onEnd]] handlers. Filled after you push last chunk + * (call [[Inflate#push]] with `Z_FINISH` / `true` param) or if you + * push a chunk with explicit flush (call [[Inflate#push]] with + * `Z_SYNC_FLUSH` param). + **/ + +/** + * Inflate.err -> Number + * + * Error code after inflate finished. 0 (Z_OK) on success. + * Should be checked if broken data possible. + **/ + +/** + * Inflate.msg -> String + * + * Error message, if [[Inflate.err]] != 0 + **/ + + +/** + * new Inflate(options) + * - options (Object): zlib inflate options. + * + * Creates new inflator instance with specified params. Throws exception + * on bad params. Supported options: + * + * - `windowBits` + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Additional options, for internal needs: + * + * - `chunkSize` - size of generated data chunks (16K by default) + * - `raw` (Boolean) - do raw inflate + * - `to` (String) - if equal to 'string', then result will be converted + * from utf8 to utf16 (javascript) string. When string output requested, + * chunk length can differ from `chunkSize`, depending on content. + * + * By default, when no options set, autodetect deflate/gzip data format via + * wrapper header. + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) + * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); + * + * var inflate = new pako.Inflate({ level: 3}); + * + * inflate.push(chunk1, false); + * inflate.push(chunk2, true); // true -> last chunk + * + * if (inflate.err) { throw new Error(inflate.err); } + * + * console.log(inflate.result); + * ``` + **/ +var Inflate = function(options) { + + this.options = utils.assign({ + chunkSize: 16384, + windowBits: 0, + to: '' + }, options || {}); + + var opt = this.options; + + // Force window size for `raw` data, if not set directly, + // because we have no header for autodetect. + if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) { + opt.windowBits = -opt.windowBits; + if (opt.windowBits === 0) { opt.windowBits = -15; } + } + + // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate + if ((opt.windowBits >= 0) && (opt.windowBits < 16) && + !(options && options.windowBits)) { + opt.windowBits += 32; + } + + // Gzip header has no info about windows size, we can do autodetect only + // for deflate. So, if window size not set, force it to max when gzip possible + if ((opt.windowBits > 15) && (opt.windowBits < 48)) { + // bit 3 (16) -> gzipped data + // bit 4 (32) -> autodetect gzip/deflate + if ((opt.windowBits & 15) === 0) { + opt.windowBits |= 15; + } + } + + this.err = 0; // error code, if happens (0 = Z_OK) + this.msg = ''; // error message + this.ended = false; // used to avoid multiple onEnd() calls + this.chunks = []; // chunks of compressed data + + this.strm = new zstream(); + this.strm.avail_out = 0; + + var status = zlib_inflate.inflateInit2( + this.strm, + opt.windowBits + ); + + if (status !== c.Z_OK) { + throw new Error(msg[status]); + } + + this.header = new gzheader(); + + zlib_inflate.inflateGetHeader(this.strm, this.header); +}; + +/** + * Inflate#push(data[, mode]) -> Boolean + * - data (Uint8Array|Array|ArrayBuffer|String): input data + * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. + * See constants. Skipped or `false` means Z_NO_FLUSH, `true` meansh Z_FINISH. + * + * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with + * new output chunks. Returns `true` on success. The last data block must have + * mode Z_FINISH (or `true`). That will flush internal pending buffers and call + * [[Inflate#onEnd]]. For interim explicit flushes (without ending the stream) you + * can use mode Z_SYNC_FLUSH, keeping the decompression context. + * + * On fail call [[Inflate#onEnd]] with error code and return false. + * + * We strongly recommend to use `Uint8Array` on input for best speed (output + * format is detected automatically). Also, don't skip last param and always + * use the same type in your code (boolean or number). That will improve JS speed. + * + * For regular `Array`-s make sure all elements are [0..255]. + * + * ##### Example + * + * ```javascript + * push(chunk, false); // push one of data chunks + * ... + * push(chunk, true); // push last chunk + * ``` + **/ +Inflate.prototype.push = function(data, mode) { + var strm = this.strm; + var chunkSize = this.options.chunkSize; + var status, _mode; + var next_out_utf8, tail, utf8str; + + if (this.ended) { return false; } + _mode = (mode === ~~mode) ? mode : ((mode === true) ? c.Z_FINISH : c.Z_NO_FLUSH); + + // Convert data if needed + if (typeof data === 'string') { + // Only binary strings can be decompressed on practice + strm.input = strings.binstring2buf(data); + } else if (toString.call(data) === '[object ArrayBuffer]') { + strm.input = new Uint8Array(data); + } else { + strm.input = data; + } + + strm.next_in = 0; + strm.avail_in = strm.input.length; + + do { + if (strm.avail_out === 0) { + strm.output = new utils.Buf8(chunkSize); + strm.next_out = 0; + strm.avail_out = chunkSize; + } + + status = zlib_inflate.inflate(strm, c.Z_NO_FLUSH); /* no bad return value */ + + if (status !== c.Z_STREAM_END && status !== c.Z_OK) { + this.onEnd(status); + this.ended = true; + return false; + } + + if (strm.next_out) { + if (strm.avail_out === 0 || status === c.Z_STREAM_END || (strm.avail_in === 0 && (_mode === c.Z_FINISH || _mode === c.Z_SYNC_FLUSH))) { + + if (this.options.to === 'string') { + + next_out_utf8 = strings.utf8border(strm.output, strm.next_out); + + tail = strm.next_out - next_out_utf8; + utf8str = strings.buf2string(strm.output, next_out_utf8); + + // move tail + strm.next_out = tail; + strm.avail_out = chunkSize - tail; + if (tail) { utils.arraySet(strm.output, strm.output, next_out_utf8, tail, 0); } + + this.onData(utf8str); + + } else { + this.onData(utils.shrinkBuf(strm.output, strm.next_out)); + } + } + } + } while ((strm.avail_in > 0) && status !== c.Z_STREAM_END); + + if (status === c.Z_STREAM_END) { + _mode = c.Z_FINISH; + } + + // Finalize on the last chunk. + if (_mode === c.Z_FINISH) { + status = zlib_inflate.inflateEnd(this.strm); + this.onEnd(status); + this.ended = true; + return status === c.Z_OK; + } + + // callback interim results if Z_SYNC_FLUSH. + if (_mode === c.Z_SYNC_FLUSH) { + this.onEnd(c.Z_OK); + strm.avail_out = 0; + return true; + } + + return true; +}; + + +/** + * Inflate#onData(chunk) -> Void + * - chunk (Uint8Array|Array|String): ouput data. Type of array depends + * on js engine support. When string output requested, each chunk + * will be string. + * + * By default, stores data blocks in `chunks[]` property and glue + * those in `onEnd`. Override this handler, if you need another behaviour. + **/ +Inflate.prototype.onData = function(chunk) { + this.chunks.push(chunk); +}; + + +/** + * Inflate#onEnd(status) -> Void + * - status (Number): inflate status. 0 (Z_OK) on success, + * other if not. + * + * Called either after you tell inflate that the input stream is + * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH) + * or if an error happened. By default - join collected chunks, + * free memory and fill `results` / `err` properties. + **/ +Inflate.prototype.onEnd = function(status) { + // On success - join + if (status === c.Z_OK) { + if (this.options.to === 'string') { + // Glue & convert here, until we teach pako to send + // utf8 alligned strings to onData + this.result = this.chunks.join(''); + } else { + this.result = utils.flattenChunks(this.chunks); + } + } + this.chunks = []; + this.err = status; + this.msg = this.strm.msg; +}; + + +/** + * inflate(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to decompress. + * - options (Object): zlib inflate options. + * + * Decompress `data` with inflate/ungzip and `options`. Autodetect + * format via wrapper header by default. That's why we don't provide + * separate `ungzip` method. + * + * Supported options are: + * + * - windowBits + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information. + * + * Sugar (options): + * + * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify + * negative windowBits implicitly. + * - `to` (String) - if equal to 'string', then result will be converted + * from utf8 to utf16 (javascript) string. When string output requested, + * chunk length can differ from `chunkSize`, depending on content. + * + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , input = pako.deflate([1,2,3,4,5,6,7,8,9]) + * , output; + * + * try { + * output = pako.inflate(input); + * } catch (err) + * console.log(err); + * } + * ``` + **/ +function inflate(input, options) { + var inflator = new Inflate(options); + + inflator.push(input, true); + + // That will never happens, if you don't cheat with options :) + if (inflator.err) { throw inflator.msg; } + + return inflator.result; +} + + +/** + * inflateRaw(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to decompress. + * - options (Object): zlib inflate options. + * + * The same as [[inflate]], but creates raw data, without wrapper + * (header and adler32 crc). + **/ +function inflateRaw(input, options) { + options = options || {}; + options.raw = true; + return inflate(input, options); +} + + +/** + * ungzip(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to decompress. + * - options (Object): zlib inflate options. + * + * Just shortcut to [[inflate]], because it autodetects format + * by header.content. Done for convenience. + **/ + + +exports.Inflate = Inflate; +exports.inflate = inflate; +exports.inflateRaw = inflateRaw; +exports.ungzip = inflate; + +},{"./utils/common":35,"./utils/strings":36,"./zlib/constants":38,"./zlib/gzheader":41,"./zlib/inflate.js":43,"./zlib/messages":45,"./zlib/zstream":47}],35:[function(require,module,exports){ +'use strict'; + + +var TYPED_OK = (typeof Uint8Array !== 'undefined') && + (typeof Uint16Array !== 'undefined') && + (typeof Int32Array !== 'undefined'); + + +exports.assign = function (obj /*from1, from2, from3, ...*/) { + var sources = Array.prototype.slice.call(arguments, 1); + while (sources.length) { + var source = sources.shift(); + if (!source) { continue; } + + if (typeof source !== 'object') { + throw new TypeError(source + 'must be non-object'); + } + + for (var p in source) { + if (source.hasOwnProperty(p)) { + obj[p] = source[p]; + } + } + } + + return obj; +}; + + +// reduce buffer size, avoiding mem copy +exports.shrinkBuf = function (buf, size) { + if (buf.length === size) { return buf; } + if (buf.subarray) { return buf.subarray(0, size); } + buf.length = size; + return buf; +}; + + +var fnTyped = { + arraySet: function (dest, src, src_offs, len, dest_offs) { + if (src.subarray && dest.subarray) { + dest.set(src.subarray(src_offs, src_offs+len), dest_offs); + return; + } + // Fallback to ordinary array + for (var i=0; i<len; i++) { + dest[dest_offs + i] = src[src_offs + i]; + } + }, + // Join array of chunks to single array. + flattenChunks: function(chunks) { + var i, l, len, pos, chunk, result; + + // calculate data length + len = 0; + for (i=0, l=chunks.length; i<l; i++) { + len += chunks[i].length; + } + + // join chunks + result = new Uint8Array(len); + pos = 0; + for (i=0, l=chunks.length; i<l; i++) { + chunk = chunks[i]; + result.set(chunk, pos); + pos += chunk.length; + } + + return result; + } +}; + +var fnUntyped = { + arraySet: function (dest, src, src_offs, len, dest_offs) { + for (var i=0; i<len; i++) { + dest[dest_offs + i] = src[src_offs + i]; + } + }, + // Join array of chunks to single array. + flattenChunks: function(chunks) { + return [].concat.apply([], chunks); + } +}; + + +// Enable/Disable typed arrays use, for testing +// +exports.setTyped = function (on) { + if (on) { + exports.Buf8 = Uint8Array; + exports.Buf16 = Uint16Array; + exports.Buf32 = Int32Array; + exports.assign(exports, fnTyped); + } else { + exports.Buf8 = Array; + exports.Buf16 = Array; + exports.Buf32 = Array; + exports.assign(exports, fnUntyped); + } +}; + +exports.setTyped(TYPED_OK); + +},{}],36:[function(require,module,exports){ +// String encode/decode helpers +'use strict'; + + +var utils = require('./common'); + + +// Quick check if we can use fast array to bin string conversion +// +// - apply(Array) can fail on Android 2.2 +// - apply(Uint8Array) can fail on iOS 5.1 Safary +// +var STR_APPLY_OK = true; +var STR_APPLY_UIA_OK = true; + +try { String.fromCharCode.apply(null, [0]); } catch(__) { STR_APPLY_OK = false; } +try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch(__) { STR_APPLY_UIA_OK = false; } + + +// Table with utf8 lengths (calculated by first byte of sequence) +// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, +// because max possible codepoint is 0x10ffff +var _utf8len = new utils.Buf8(256); +for (var q=0; q<256; q++) { + _utf8len[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1); +} +_utf8len[254]=_utf8len[254]=1; // Invalid sequence start + + +// convert string to array (typed, when possible) +exports.string2buf = function (str) { + var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; + + // count binary size + for (m_pos = 0; m_pos < str_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; + } + + // allocate buffer + buf = new utils.Buf8(buf_len); + + // convert + for (i=0, m_pos = 0; i < buf_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + if (c < 0x80) { + /* one byte */ + buf[i++] = c; + } else if (c < 0x800) { + /* two bytes */ + buf[i++] = 0xC0 | (c >>> 6); + buf[i++] = 0x80 | (c & 0x3f); + } else if (c < 0x10000) { + /* three bytes */ + buf[i++] = 0xE0 | (c >>> 12); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } else { + /* four bytes */ + buf[i++] = 0xf0 | (c >>> 18); + buf[i++] = 0x80 | (c >>> 12 & 0x3f); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } + } + + return buf; +}; + +// Helper (used in 2 places) +function buf2binstring(buf, len) { + // use fallback for big arrays to avoid stack overflow + if (len < 65537) { + if ((buf.subarray && STR_APPLY_UIA_OK) || (!buf.subarray && STR_APPLY_OK)) { + return String.fromCharCode.apply(null, utils.shrinkBuf(buf, len)); + } + } + + var result = ''; + for (var i=0; i < len; i++) { + result += String.fromCharCode(buf[i]); + } + return result; +} + + +// Convert byte array to binary string +exports.buf2binstring = function(buf) { + return buf2binstring(buf, buf.length); +}; + + +// Convert binary string (typed, when possible) +exports.binstring2buf = function(str) { + var buf = new utils.Buf8(str.length); + for (var i=0, len=buf.length; i < len; i++) { + buf[i] = str.charCodeAt(i); + } + return buf; +}; + + +// convert array to string +exports.buf2string = function (buf, max) { + var i, out, c, c_len; + var len = max || buf.length; + + // Reserve max possible length (2 words per char) + // NB: by unknown reasons, Array is significantly faster for + // String.fromCharCode.apply than Uint16Array. + var utf16buf = new Array(len*2); + + for (out=0, i=0; i<len;) { + c = buf[i++]; + // quick process ascii + if (c < 0x80) { utf16buf[out++] = c; continue; } + + c_len = _utf8len[c]; + // skip 5 & 6 byte codes + if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len-1; continue; } + + // apply mask on first byte + c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; + // join the rest + while (c_len > 1 && i < len) { + c = (c << 6) | (buf[i++] & 0x3f); + c_len--; + } + + // terminated by end of string? + if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } + + if (c < 0x10000) { + utf16buf[out++] = c; + } else { + c -= 0x10000; + utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); + utf16buf[out++] = 0xdc00 | (c & 0x3ff); + } + } + + return buf2binstring(utf16buf, out); +}; + + +// Calculate max possible position in utf8 buffer, +// that will not break sequence. If that's not possible +// - (very small limits) return max size as is. +// +// buf[] - utf8 bytes array +// max - length limit (mandatory); +exports.utf8border = function(buf, max) { + var pos; + + max = max || buf.length; + if (max > buf.length) { max = buf.length; } + + // go back from last position, until start of sequence found + pos = max-1; + while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } + + // Fuckup - very small and broken sequence, + // return max, because we should return something anyway. + if (pos < 0) { return max; } + + // If we came to start of buffer - that means vuffer is too small, + // return max too. + if (pos === 0) { return max; } + + return (pos + _utf8len[buf[pos]] > max) ? pos : max; +}; + +},{"./common":35}],37:[function(require,module,exports){ +'use strict'; + +// Note: adler32 takes 12% for level 0 and 2% for level 6. +// It doesn't worth to make additional optimizationa as in original. +// Small size is preferable. + +function adler32(adler, buf, len, pos) { + var s1 = (adler & 0xffff) |0, + s2 = ((adler >>> 16) & 0xffff) |0, + n = 0; + + while (len !== 0) { + // Set limit ~ twice less than 5552, to keep + // s2 in 31-bits, because we force signed ints. + // in other case %= will fail. + n = len > 2000 ? 2000 : len; + len -= n; + + do { + s1 = (s1 + buf[pos++]) |0; + s2 = (s2 + s1) |0; + } while (--n); + + s1 %= 65521; + s2 %= 65521; + } + + return (s1 | (s2 << 16)) |0; +} + + +module.exports = adler32; + +},{}],38:[function(require,module,exports){ +module.exports = { + + /* Allowed flush values; see deflate() and inflate() below for details */ + Z_NO_FLUSH: 0, + Z_PARTIAL_FLUSH: 1, + Z_SYNC_FLUSH: 2, + Z_FULL_FLUSH: 3, + Z_FINISH: 4, + Z_BLOCK: 5, + Z_TREES: 6, + + /* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + Z_OK: 0, + Z_STREAM_END: 1, + Z_NEED_DICT: 2, + Z_ERRNO: -1, + Z_STREAM_ERROR: -2, + Z_DATA_ERROR: -3, + //Z_MEM_ERROR: -4, + Z_BUF_ERROR: -5, + //Z_VERSION_ERROR: -6, + + /* compression levels */ + Z_NO_COMPRESSION: 0, + Z_BEST_SPEED: 1, + Z_BEST_COMPRESSION: 9, + Z_DEFAULT_COMPRESSION: -1, + + + Z_FILTERED: 1, + Z_HUFFMAN_ONLY: 2, + Z_RLE: 3, + Z_FIXED: 4, + Z_DEFAULT_STRATEGY: 0, + + /* Possible values of the data_type field (though see inflate()) */ + Z_BINARY: 0, + Z_TEXT: 1, + //Z_ASCII: 1, // = Z_TEXT (deprecated) + Z_UNKNOWN: 2, + + /* The deflate compression method */ + Z_DEFLATED: 8 + //Z_NULL: null // Use -1 or null inline, depending on var type +}; + +},{}],39:[function(require,module,exports){ +'use strict'; + +// Note: we can't get significant speed boost here. +// So write code to minimize size - no pregenerated tables +// and array tools dependencies. + + +// Use ordinary array, since untyped makes no boost here +function makeTable() { + var c, table = []; + + for (var n =0; n < 256; n++) { + c = n; + for (var k =0; k < 8; k++) { + c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); + } + table[n] = c; + } + + return table; +} + +// Create table on load. Just 255 signed longs. Not a problem. +var crcTable = makeTable(); + + +function crc32(crc, buf, len, pos) { + var t = crcTable, + end = pos + len; + + crc = crc ^ (-1); + + for (var i = pos; i < end; i++) { + crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; + } + + return (crc ^ (-1)); // >>> 0; +} + + +module.exports = crc32; + +},{}],40:[function(require,module,exports){ +'use strict'; + +var utils = require('../utils/common'); +var trees = require('./trees'); +var adler32 = require('./adler32'); +var crc32 = require('./crc32'); +var msg = require('./messages'); + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +/* Allowed flush values; see deflate() and inflate() below for details */ +var Z_NO_FLUSH = 0; +var Z_PARTIAL_FLUSH = 1; +//var Z_SYNC_FLUSH = 2; +var Z_FULL_FLUSH = 3; +var Z_FINISH = 4; +var Z_BLOCK = 5; +//var Z_TREES = 6; + + +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ +var Z_OK = 0; +var Z_STREAM_END = 1; +//var Z_NEED_DICT = 2; +//var Z_ERRNO = -1; +var Z_STREAM_ERROR = -2; +var Z_DATA_ERROR = -3; +//var Z_MEM_ERROR = -4; +var Z_BUF_ERROR = -5; +//var Z_VERSION_ERROR = -6; + + +/* compression levels */ +//var Z_NO_COMPRESSION = 0; +//var Z_BEST_SPEED = 1; +//var Z_BEST_COMPRESSION = 9; +var Z_DEFAULT_COMPRESSION = -1; + + +var Z_FILTERED = 1; +var Z_HUFFMAN_ONLY = 2; +var Z_RLE = 3; +var Z_FIXED = 4; +var Z_DEFAULT_STRATEGY = 0; + +/* Possible values of the data_type field (though see inflate()) */ +//var Z_BINARY = 0; +//var Z_TEXT = 1; +//var Z_ASCII = 1; // = Z_TEXT +var Z_UNKNOWN = 2; + + +/* The deflate compression method */ +var Z_DEFLATED = 8; + +/*============================================================================*/ + + +var MAX_MEM_LEVEL = 9; +/* Maximum value for memLevel in deflateInit2 */ +var MAX_WBITS = 15; +/* 32K LZ77 window */ +var DEF_MEM_LEVEL = 8; + + +var LENGTH_CODES = 29; +/* number of length codes, not counting the special END_BLOCK code */ +var LITERALS = 256; +/* number of literal bytes 0..255 */ +var L_CODES = LITERALS + 1 + LENGTH_CODES; +/* number of Literal or Length codes, including the END_BLOCK code */ +var D_CODES = 30; +/* number of distance codes */ +var BL_CODES = 19; +/* number of codes used to transfer the bit lengths */ +var HEAP_SIZE = 2*L_CODES + 1; +/* maximum heap size */ +var MAX_BITS = 15; +/* All codes must not exceed MAX_BITS bits */ + +var MIN_MATCH = 3; +var MAX_MATCH = 258; +var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); + +var PRESET_DICT = 0x20; + +var INIT_STATE = 42; +var EXTRA_STATE = 69; +var NAME_STATE = 73; +var COMMENT_STATE = 91; +var HCRC_STATE = 103; +var BUSY_STATE = 113; +var FINISH_STATE = 666; + +var BS_NEED_MORE = 1; /* block not completed, need more input or more output */ +var BS_BLOCK_DONE = 2; /* block flush performed */ +var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */ +var BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ + +var OS_CODE = 0x03; // Unix :) . Don't detect, use this default. + +function err(strm, errorCode) { + strm.msg = msg[errorCode]; + return errorCode; +} + +function rank(f) { + return ((f) << 1) - ((f) > 4 ? 9 : 0); +} + +function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } + + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->output buffer and copying into it. + * (See also read_buf()). + */ +function flush_pending(strm) { + var s = strm.state; + + //_tr_flush_bits(s); + var len = s.pending; + if (len > strm.avail_out) { + len = strm.avail_out; + } + if (len === 0) { return; } + + utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out); + strm.next_out += len; + s.pending_out += len; + strm.total_out += len; + strm.avail_out -= len; + s.pending -= len; + if (s.pending === 0) { + s.pending_out = 0; + } +} + + +function flush_block_only (s, last) { + trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); + s.block_start = s.strstart; + flush_pending(s.strm); +} + + +function put_byte(s, b) { + s.pending_buf[s.pending++] = b; +} + + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +function putShortMSB(s, b) { +// put_byte(s, (Byte)(b >> 8)); +// put_byte(s, (Byte)(b & 0xff)); + s.pending_buf[s.pending++] = (b >>> 8) & 0xff; + s.pending_buf[s.pending++] = b & 0xff; +} + + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->input buffer and copying from it. + * (See also flush_pending()). + */ +function read_buf(strm, buf, start, size) { + var len = strm.avail_in; + + if (len > size) { len = size; } + if (len === 0) { return 0; } + + strm.avail_in -= len; + + utils.arraySet(buf, strm.input, strm.next_in, len, start); + if (strm.state.wrap === 1) { + strm.adler = adler32(strm.adler, buf, len, start); + } + + else if (strm.state.wrap === 2) { + strm.adler = crc32(strm.adler, buf, len, start); + } + + strm.next_in += len; + strm.total_in += len; + + return len; +} + + +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +function longest_match(s, cur_match) { + var chain_length = s.max_chain_length; /* max hash chain length */ + var scan = s.strstart; /* current string */ + var match; /* matched string */ + var len; /* length of current match */ + var best_len = s.prev_length; /* best match length so far */ + var nice_match = s.nice_match; /* stop if match long enough */ + var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ? + s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/; + + var _win = s.window; // shortcut + + var wmask = s.w_mask; + var prev = s.prev; + + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + + var strend = s.strstart + MAX_MATCH; + var scan_end1 = _win[scan + best_len - 1]; + var scan_end = _win[scan + best_len]; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s.prev_length >= s.good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if (nice_match > s.lookahead) { nice_match = s.lookahead; } + + // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + // Assert(cur_match < s->strstart, "no future"); + match = cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ + + if (_win[match + best_len] !== scan_end || + _win[match + best_len - 1] !== scan_end1 || + _win[match] !== _win[scan] || + _win[++match] !== _win[scan + 1]) { + continue; + } + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2; + match++; + // Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + /*jshint noempty:false*/ + } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + scan < strend); + + // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (strend - scan); + scan = strend - MAX_MATCH; + + if (len > best_len) { + s.match_start = cur_match; + best_len = len; + if (len >= nice_match) { + break; + } + scan_end1 = _win[scan + best_len - 1]; + scan_end = _win[scan + best_len]; + } + } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); + + if (best_len <= s.lookahead) { + return best_len; + } + return s.lookahead; +} + + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +function fill_window(s) { + var _w_size = s.w_size; + var p, n, m, more, str; + + //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = s.window_size - s.lookahead - s.strstart; + + // JS ints have 32 bit, block below not needed + /* Deal with !@#$% 64K limit: */ + //if (sizeof(int) <= 2) { + // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + // more = wsize; + // + // } else if (more == (unsigned)(-1)) { + // /* Very unlikely, but possible on 16 bit machine if + // * strstart == 0 && lookahead == 1 (input done a byte at time) + // */ + // more--; + // } + //} + + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) { + + utils.arraySet(s.window, s.window, _w_size, _w_size, 0); + s.match_start -= _w_size; + s.strstart -= _w_size; + /* we now have strstart >= MAX_DIST */ + s.block_start -= _w_size; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + + n = s.hash_size; + p = n; + do { + m = s.head[--p]; + s.head[p] = (m >= _w_size ? m - _w_size : 0); + } while (--n); + + n = _w_size; + p = n; + do { + m = s.prev[--p]; + s.prev[p] = (m >= _w_size ? m - _w_size : 0); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); + + more += _w_size; + } + if (s.strm.avail_in === 0) { + break; + } + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + //Assert(more >= 2, "more < 2"); + n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more); + s.lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s.lookahead + s.insert >= MIN_MATCH) { + str = s.strstart - s.insert; + s.ins_h = s.window[str]; + + /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask; +//#if MIN_MATCH != 3 +// Call update_hash() MIN_MATCH-3 more times +//#endif + while (s.insert) { + /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH-1]) & s.hash_mask; + + s.prev[str & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = str; + str++; + s.insert--; + if (s.lookahead + s.insert < MIN_MATCH) { + break; + } + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ +// if (s.high_water < s.window_size) { +// var curr = s.strstart + s.lookahead; +// var init = 0; +// +// if (s.high_water < curr) { +// /* Previous high water mark below current data -- zero WIN_INIT +// * bytes or up to end of window, whichever is less. +// */ +// init = s.window_size - curr; +// if (init > WIN_INIT) +// init = WIN_INIT; +// zmemzero(s->window + curr, (unsigned)init); +// s->high_water = curr + init; +// } +// else if (s->high_water < (ulg)curr + WIN_INIT) { +// /* High water mark at or above current data, but below current data +// * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up +// * to end of window, whichever is less. +// */ +// init = (ulg)curr + WIN_INIT - s->high_water; +// if (init > s->window_size - s->high_water) +// init = s->window_size - s->high_water; +// zmemzero(s->window + s->high_water, (unsigned)init); +// s->high_water += init; +// } +// } +// +// Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, +// "not enough room for search"); +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +function deflate_stored(s, flush) { + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + var max_block_size = 0xffff; + + if (max_block_size > s.pending_buf_size - 5) { + max_block_size = s.pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s.lookahead <= 1) { + + //Assert(s->strstart < s->w_size+MAX_DIST(s) || + // s->block_start >= (long)s->w_size, "slide too late"); +// if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) || +// s.block_start >= s.w_size)) { +// throw new Error("slide too late"); +// } + + fill_window(s); + if (s.lookahead === 0 && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + + if (s.lookahead === 0) { + break; + } + /* flush the current block */ + } + //Assert(s->block_start >= 0L, "block gone"); +// if (s.block_start < 0) throw new Error("block gone"); + + s.strstart += s.lookahead; + s.lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + var max_start = s.block_start + max_block_size; + + if (s.strstart === 0 || s.strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s.lookahead = s.strstart - max_start; + s.strstart = max_start; + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + + + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + + s.insert = 0; + + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + + if (s.strstart > s.block_start) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + return BS_NEED_MORE; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +function deflate_fast(s, flush) { + var hash_head; /* head of the hash chain */ + var bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { + break; /* flush the current block */ + } + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0/*NIL*/; + if (s.lookahead >= MIN_MATCH) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s.match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ + } + if (s.match_length >= MIN_MATCH) { + // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only + + /*** _tr_tally_dist(s, s.strstart - s.match_start, + s.match_length - MIN_MATCH, bflush); ***/ + bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH); + + s.lookahead -= s.match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) { + s.match_length--; /* string at strstart already in table */ + do { + s.strstart++; + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s.match_length !== 0); + s.strstart++; + } else + { + s.strstart += s.match_length; + s.match_length = 0; + s.ins_h = s.window[s.strstart]; + /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask; + +//#if MIN_MATCH != 3 +// Call UPDATE_HASH() MIN_MATCH-3 more times +//#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + //Tracevv((stderr,"%c", s.window[s.strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + + s.lookahead--; + s.strstart++; + } + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = ((s.strstart < (MIN_MATCH-1)) ? s.strstart : MIN_MATCH-1); + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +} + +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +function deflate_slow(s, flush) { + var hash_head; /* head of hash chain */ + var bflush; /* set if current block must be flushed */ + + var max_insert; + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { break; } /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0/*NIL*/; + if (s.lookahead >= MIN_MATCH) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + + /* Find the longest match, discarding those <= prev_length. + */ + s.prev_length = s.match_length; + s.prev_match = s.match_start; + s.match_length = MIN_MATCH-1; + + if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && + s.strstart - hash_head <= (s.w_size-MIN_LOOKAHEAD)/*MAX_DIST(s)*/) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s.match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ + + if (s.match_length <= 5 && + (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s.match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) { + max_insert = s.strstart + s.lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + //check_match(s, s.strstart-1, s.prev_match, s.prev_length); + + /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, + s.prev_length - MIN_MATCH, bflush);***/ + bflush = trees._tr_tally(s, s.strstart - 1- s.prev_match, s.prev_length - MIN_MATCH); + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s.lookahead -= s.prev_length-1; + s.prev_length -= 2; + do { + if (++s.strstart <= max_insert) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + } while (--s.prev_length !== 0); + s.match_available = 0; + s.match_length = MIN_MATCH-1; + s.strstart++; + + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + } else if (s.match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + //Tracevv((stderr,"%c", s->window[s->strstart-1])); + /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart-1]); + + if (bflush) { + /*** FLUSH_BLOCK_ONLY(s, 0) ***/ + flush_block_only(s, false); + /***/ + } + s.strstart++; + s.lookahead--; + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s.match_available = 1; + s.strstart++; + s.lookahead--; + } + } + //Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s.match_available) { + //Tracevv((stderr,"%c", s->window[s->strstart-1])); + /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart-1]); + + s.match_available = 0; + } + s.insert = s.strstart < MIN_MATCH-1 ? s.strstart : MIN_MATCH-1; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + return BS_BLOCK_DONE; +} + + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +function deflate_rle(s, flush) { + var bflush; /* set if current block must be flushed */ + var prev; /* byte at distance one to match */ + var scan, strend; /* scan goes up to strend for length of run */ + + var _win = s.window; + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s.lookahead <= MAX_MATCH) { + fill_window(s); + if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { break; } /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s.match_length = 0; + if (s.lookahead >= MIN_MATCH && s.strstart > 0) { + scan = s.strstart - 1; + prev = _win[scan]; + if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { + strend = s.strstart + MAX_MATCH; + do { + /*jshint noempty:false*/ + } while (prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + scan < strend); + s.match_length = MAX_MATCH - (strend - scan); + if (s.match_length > s.lookahead) { + s.match_length = s.lookahead; + } + } + //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s.match_length >= MIN_MATCH) { + //check_match(s, s.strstart, s.strstart - 1, s.match_length); + + /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ + bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH); + + s.lookahead -= s.match_length; + s.strstart += s.match_length; + s.match_length = 0; + } else { + /* No match, output a literal byte */ + //Tracevv((stderr,"%c", s->window[s->strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + + s.lookahead--; + s.strstart++; + } + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = 0; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +function deflate_huff(s, flush) { + var bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s.lookahead === 0) { + fill_window(s); + if (s.lookahead === 0) { + if (flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s.match_length = 0; + //Tracevv((stderr,"%c", s->window[s->strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + s.lookahead--; + s.strstart++; + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = 0; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +} + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +var Config = function (good_length, max_lazy, nice_length, max_chain, func) { + this.good_length = good_length; + this.max_lazy = max_lazy; + this.nice_length = nice_length; + this.max_chain = max_chain; + this.func = func; +}; + +var configuration_table; + +configuration_table = [ + /* good lazy nice chain */ + new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */ + new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */ + new Config(4, 5, 16, 8, deflate_fast), /* 2 */ + new Config(4, 6, 32, 32, deflate_fast), /* 3 */ + + new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */ + new Config(8, 16, 32, 32, deflate_slow), /* 5 */ + new Config(8, 16, 128, 128, deflate_slow), /* 6 */ + new Config(8, 32, 128, 256, deflate_slow), /* 7 */ + new Config(32, 128, 258, 1024, deflate_slow), /* 8 */ + new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */ +]; + + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +function lm_init(s) { + s.window_size = 2 * s.w_size; + + /*** CLEAR_HASH(s); ***/ + zero(s.head); // Fill with NIL (= 0); + + /* Set the default configuration parameters: + */ + s.max_lazy_match = configuration_table[s.level].max_lazy; + s.good_match = configuration_table[s.level].good_length; + s.nice_match = configuration_table[s.level].nice_length; + s.max_chain_length = configuration_table[s.level].max_chain; + + s.strstart = 0; + s.block_start = 0; + s.lookahead = 0; + s.insert = 0; + s.match_length = s.prev_length = MIN_MATCH - 1; + s.match_available = 0; + s.ins_h = 0; +} + + +function DeflateState() { + this.strm = null; /* pointer back to this zlib stream */ + this.status = 0; /* as the name implies */ + this.pending_buf = null; /* output still pending */ + this.pending_buf_size = 0; /* size of pending_buf */ + this.pending_out = 0; /* next pending byte to output to the stream */ + this.pending = 0; /* nb of bytes in the pending buffer */ + this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ + this.gzhead = null; /* gzip header information to write */ + this.gzindex = 0; /* where in extra, name, or comment */ + this.method = Z_DEFLATED; /* can only be DEFLATED */ + this.last_flush = -1; /* value of flush param for previous deflate call */ + + this.w_size = 0; /* LZ77 window size (32K by default) */ + this.w_bits = 0; /* log2(w_size) (8..16) */ + this.w_mask = 0; /* w_size - 1 */ + + this.window = null; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. + */ + + this.window_size = 0; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + this.prev = null; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + this.head = null; /* Heads of the hash chains or NIL. */ + + this.ins_h = 0; /* hash index of string to be inserted */ + this.hash_size = 0; /* number of elements in hash table */ + this.hash_bits = 0; /* log2(hash_size) */ + this.hash_mask = 0; /* hash_size-1 */ + + this.hash_shift = 0; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + this.block_start = 0; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + this.match_length = 0; /* length of best match */ + this.prev_match = 0; /* previous match */ + this.match_available = 0; /* set if previous match exists */ + this.strstart = 0; /* start of string to insert */ + this.match_start = 0; /* start of matching string */ + this.lookahead = 0; /* number of valid bytes ahead in window */ + + this.prev_length = 0; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + this.max_chain_length = 0; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + this.max_lazy_match = 0; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ + // That's alias to max_lazy_match, don't use directly + //this.max_insert_length = 0; + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + this.level = 0; /* compression level (1..9) */ + this.strategy = 0; /* favor or force Huffman coding*/ + + this.good_match = 0; + /* Use a faster search when the previous match is longer than this */ + + this.nice_match = 0; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + + /* Didn't use ct_data typedef below to suppress compiler warning */ + + // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + // Use flat array of DOUBLE size, with interleaved fata, + // because JS does not support effective + this.dyn_ltree = new utils.Buf16(HEAP_SIZE * 2); + this.dyn_dtree = new utils.Buf16((2*D_CODES+1) * 2); + this.bl_tree = new utils.Buf16((2*BL_CODES+1) * 2); + zero(this.dyn_ltree); + zero(this.dyn_dtree); + zero(this.bl_tree); + + this.l_desc = null; /* desc. for literal tree */ + this.d_desc = null; /* desc. for distance tree */ + this.bl_desc = null; /* desc. for bit length tree */ + + //ush bl_count[MAX_BITS+1]; + this.bl_count = new utils.Buf16(MAX_BITS+1); + /* number of codes at each bit length for an optimal tree */ + + //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + this.heap = new utils.Buf16(2*L_CODES+1); /* heap used to build the Huffman trees */ + zero(this.heap); + + this.heap_len = 0; /* number of elements in the heap */ + this.heap_max = 0; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + this.depth = new utils.Buf16(2*L_CODES+1); //uch depth[2*L_CODES+1]; + zero(this.depth); + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + this.l_buf = 0; /* buffer index for literals or lengths */ + + this.lit_bufsize = 0; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + this.last_lit = 0; /* running index in l_buf */ + + this.d_buf = 0; + /* Buffer index for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + this.opt_len = 0; /* bit length of current block with optimal trees */ + this.static_len = 0; /* bit length of current block with static trees */ + this.matches = 0; /* number of string matches in current block */ + this.insert = 0; /* bytes at end of window left to insert */ + + + this.bi_buf = 0; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + this.bi_valid = 0; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + // Used for window memory init. We safely ignore it for JS. That makes + // sense only for pointers and memory check tools. + //this.high_water = 0; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ +} + + +function deflateResetKeep(strm) { + var s; + + if (!strm || !strm.state) { + return err(strm, Z_STREAM_ERROR); + } + + strm.total_in = strm.total_out = 0; + strm.data_type = Z_UNKNOWN; + + s = strm.state; + s.pending = 0; + s.pending_out = 0; + + if (s.wrap < 0) { + s.wrap = -s.wrap; + /* was made negative by deflate(..., Z_FINISH); */ + } + s.status = (s.wrap ? INIT_STATE : BUSY_STATE); + strm.adler = (s.wrap === 2) ? + 0 // crc32(0, Z_NULL, 0) + : + 1; // adler32(0, Z_NULL, 0) + s.last_flush = Z_NO_FLUSH; + trees._tr_init(s); + return Z_OK; +} + + +function deflateReset(strm) { + var ret = deflateResetKeep(strm); + if (ret === Z_OK) { + lm_init(strm.state); + } + return ret; +} + + +function deflateSetHeader(strm, head) { + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; } + strm.state.gzhead = head; + return Z_OK; +} + + +function deflateInit2(strm, level, method, windowBits, memLevel, strategy) { + if (!strm) { // === Z_NULL + return Z_STREAM_ERROR; + } + var wrap = 1; + + if (level === Z_DEFAULT_COMPRESSION) { + level = 6; + } + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } + + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } + + + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return err(strm, Z_STREAM_ERROR); + } + + + if (windowBits === 8) { + windowBits = 9; + } + /* until 256-byte window bug fixed */ + + var s = new DeflateState(); + + strm.state = s; + s.strm = strm; + + s.wrap = wrap; + s.gzhead = null; + s.w_bits = windowBits; + s.w_size = 1 << s.w_bits; + s.w_mask = s.w_size - 1; + + s.hash_bits = memLevel + 7; + s.hash_size = 1 << s.hash_bits; + s.hash_mask = s.hash_size - 1; + s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); + + s.window = new utils.Buf8(s.w_size * 2); + s.head = new utils.Buf16(s.hash_size); + s.prev = new utils.Buf16(s.w_size); + + // Don't need mem init magic for JS. + //s.high_water = 0; /* nothing written to s->window yet */ + + s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + s.pending_buf_size = s.lit_bufsize * 4; + s.pending_buf = new utils.Buf8(s.pending_buf_size); + + s.d_buf = s.lit_bufsize >> 1; + s.l_buf = (1 + 2) * s.lit_bufsize; + + s.level = level; + s.strategy = strategy; + s.method = method; + + return deflateReset(strm); +} + +function deflateInit(strm, level) { + return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); +} + + +function deflate(strm, flush) { + var old_flush, s; + var beg, val; // for gzip header write only + + if (!strm || !strm.state || + flush > Z_BLOCK || flush < 0) { + return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR; + } + + s = strm.state; + + if (!strm.output || + (!strm.input && strm.avail_in !== 0) || + (s.status === FINISH_STATE && flush !== Z_FINISH)) { + return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR); + } + + s.strm = strm; /* just in case */ + old_flush = s.last_flush; + s.last_flush = flush; + + /* Write the header */ + if (s.status === INIT_STATE) { + + if (s.wrap === 2) { // GZIP header + strm.adler = 0; //crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (!s.gzhead) { // s->gzhead == Z_NULL + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s.level === 9 ? 2 : + (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s.status = BUSY_STATE; + } + else { + put_byte(s, (s.gzhead.text ? 1 : 0) + + (s.gzhead.hcrc ? 2 : 0) + + (!s.gzhead.extra ? 0 : 4) + + (!s.gzhead.name ? 0 : 8) + + (!s.gzhead.comment ? 0 : 16) + ); + put_byte(s, s.gzhead.time & 0xff); + put_byte(s, (s.gzhead.time >> 8) & 0xff); + put_byte(s, (s.gzhead.time >> 16) & 0xff); + put_byte(s, (s.gzhead.time >> 24) & 0xff); + put_byte(s, s.level === 9 ? 2 : + (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? + 4 : 0)); + put_byte(s, s.gzhead.os & 0xff); + if (s.gzhead.extra && s.gzhead.extra.length) { + put_byte(s, s.gzhead.extra.length & 0xff); + put_byte(s, (s.gzhead.extra.length >> 8) & 0xff); + } + if (s.gzhead.hcrc) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0); + } + s.gzindex = 0; + s.status = EXTRA_STATE; + } + } + else // DEFLATE header + { + var header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8; + var level_flags = -1; + + if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) { + level_flags = 0; + } else if (s.level < 6) { + level_flags = 1; + } else if (s.level === 6) { + level_flags = 2; + } else { + level_flags = 3; + } + header |= (level_flags << 6); + if (s.strstart !== 0) { header |= PRESET_DICT; } + header += 31 - (header % 31); + + s.status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s.strstart !== 0) { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 0xffff); + } + strm.adler = 1; // adler32(0L, Z_NULL, 0); + } + } + +//#ifdef GZIP + if (s.status === EXTRA_STATE) { + if (s.gzhead.extra/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ + + while (s.gzindex < (s.gzhead.extra.length & 0xffff)) { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + break; + } + } + put_byte(s, s.gzhead.extra[s.gzindex] & 0xff); + s.gzindex++; + } + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (s.gzindex === s.gzhead.extra.length) { + s.gzindex = 0; + s.status = NAME_STATE; + } + } + else { + s.status = NAME_STATE; + } + } + if (s.status === NAME_STATE) { + if (s.gzhead.name/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ + //int val; + + do { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + val = 1; + break; + } + } + // JS specific: little magic to add zero terminator to end of string + if (s.gzindex < s.gzhead.name.length) { + val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff; + } else { + val = 0; + } + put_byte(s, val); + } while (val !== 0); + + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (val === 0) { + s.gzindex = 0; + s.status = COMMENT_STATE; + } + } + else { + s.status = COMMENT_STATE; + } + } + if (s.status === COMMENT_STATE) { + if (s.gzhead.comment/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ + //int val; + + do { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + val = 1; + break; + } + } + // JS specific: little magic to add zero terminator to end of string + if (s.gzindex < s.gzhead.comment.length) { + val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff; + } else { + val = 0; + } + put_byte(s, val); + } while (val !== 0); + + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (val === 0) { + s.status = HCRC_STATE; + } + } + else { + s.status = HCRC_STATE; + } + } + if (s.status === HCRC_STATE) { + if (s.gzhead.hcrc) { + if (s.pending + 2 > s.pending_buf_size) { + flush_pending(strm); + } + if (s.pending + 2 <= s.pending_buf_size) { + put_byte(s, strm.adler & 0xff); + put_byte(s, (strm.adler >> 8) & 0xff); + strm.adler = 0; //crc32(0L, Z_NULL, 0); + s.status = BUSY_STATE; + } + } + else { + s.status = BUSY_STATE; + } + } +//#endif + + /* Flush as much pending output as possible */ + if (s.pending !== 0) { + flush_pending(strm); + if (strm.avail_out === 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s.last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) && + flush !== Z_FINISH) { + return err(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s.status === FINISH_STATE && strm.avail_in !== 0) { + return err(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm.avail_in !== 0 || s.lookahead !== 0 || + (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) { + var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) : + (s.strategy === Z_RLE ? deflate_rle(s, flush) : + configuration_table[s.level].func(s, flush)); + + if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) { + s.status = FINISH_STATE; + } + if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) { + if (strm.avail_out === 0) { + s.last_flush = -1; + /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate === BS_BLOCK_DONE) { + if (flush === Z_PARTIAL_FLUSH) { + trees._tr_align(s); + } + else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + + trees._tr_stored_block(s, 0, 0, false); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush === Z_FULL_FLUSH) { + /*** CLEAR_HASH(s); ***/ /* forget history */ + zero(s.head); // Fill with NIL (= 0); + + if (s.lookahead === 0) { + s.strstart = 0; + s.block_start = 0; + s.insert = 0; + } + } + } + flush_pending(strm); + if (strm.avail_out === 0) { + s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + //Assert(strm->avail_out > 0, "bug2"); + //if (strm.avail_out <= 0) { throw new Error("bug2");} + + if (flush !== Z_FINISH) { return Z_OK; } + if (s.wrap <= 0) { return Z_STREAM_END; } + + /* Write the trailer */ + if (s.wrap === 2) { + put_byte(s, strm.adler & 0xff); + put_byte(s, (strm.adler >> 8) & 0xff); + put_byte(s, (strm.adler >> 16) & 0xff); + put_byte(s, (strm.adler >> 24) & 0xff); + put_byte(s, strm.total_in & 0xff); + put_byte(s, (strm.total_in >> 8) & 0xff); + put_byte(s, (strm.total_in >> 16) & 0xff); + put_byte(s, (strm.total_in >> 24) & 0xff); + } + else + { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 0xffff); + } + + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s.wrap > 0) { s.wrap = -s.wrap; } + /* write the trailer only once! */ + return s.pending !== 0 ? Z_OK : Z_STREAM_END; +} + +function deflateEnd(strm) { + var status; + + if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) { + return Z_STREAM_ERROR; + } + + status = strm.state.status; + if (status !== INIT_STATE && + status !== EXTRA_STATE && + status !== NAME_STATE && + status !== COMMENT_STATE && + status !== HCRC_STATE && + status !== BUSY_STATE && + status !== FINISH_STATE + ) { + return err(strm, Z_STREAM_ERROR); + } + + strm.state = null; + + return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state + */ +//function deflateCopy(dest, source) { +// +//} + +exports.deflateInit = deflateInit; +exports.deflateInit2 = deflateInit2; +exports.deflateReset = deflateReset; +exports.deflateResetKeep = deflateResetKeep; +exports.deflateSetHeader = deflateSetHeader; +exports.deflate = deflate; +exports.deflateEnd = deflateEnd; +exports.deflateInfo = 'pako deflate (from Nodeca project)'; + +/* Not implemented +exports.deflateBound = deflateBound; +exports.deflateCopy = deflateCopy; +exports.deflateSetDictionary = deflateSetDictionary; +exports.deflateParams = deflateParams; +exports.deflatePending = deflatePending; +exports.deflatePrime = deflatePrime; +exports.deflateTune = deflateTune; +*/ + +},{"../utils/common":35,"./adler32":37,"./crc32":39,"./messages":45,"./trees":46}],41:[function(require,module,exports){ +'use strict'; + + +function GZheader() { + /* true if compressed data believed to be text */ + this.text = 0; + /* modification time */ + this.time = 0; + /* extra flags (not used when writing a gzip file) */ + this.xflags = 0; + /* operating system */ + this.os = 0; + /* pointer to extra field or Z_NULL if none */ + this.extra = null; + /* extra field length (valid if extra != Z_NULL) */ + this.extra_len = 0; // Actually, we don't need it in JS, + // but leave for few code modifications + + // + // Setup limits is not necessary because in js we should not preallocate memory + // for inflate use constant limit in 65536 bytes + // + + /* space at extra (only when reading header) */ + // this.extra_max = 0; + /* pointer to zero-terminated file name or Z_NULL */ + this.name = ''; + /* space at name (only when reading header) */ + // this.name_max = 0; + /* pointer to zero-terminated comment or Z_NULL */ + this.comment = ''; + /* space at comment (only when reading header) */ + // this.comm_max = 0; + /* true if there was or will be a header crc */ + this.hcrc = 0; + /* true when done reading gzip header (not used when writing a gzip file) */ + this.done = false; +} + +module.exports = GZheader; + +},{}],42:[function(require,module,exports){ +'use strict'; + +// See state defs from inflate.js +var BAD = 30; /* got a data error -- remain here until reset */ +var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state.mode === LEN + strm.avail_in >= 6 + strm.avail_out >= 258 + start >= strm.avail_out + state.bits < 8 + + On return, state.mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm.avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm.avail_out >= 258 for each loop to avoid checking for + output space. + */ +module.exports = function inflate_fast(strm, start) { + var state; + var _in; /* local strm.input */ + var last; /* have enough input while in < last */ + var _out; /* local strm.output */ + var beg; /* inflate()'s initial strm.output */ + var end; /* while out < end, enough space available */ +//#ifdef INFLATE_STRICT + var dmax; /* maximum distance from zlib header */ +//#endif + var wsize; /* window size or zero if not using window */ + var whave; /* valid bytes in the window */ + var wnext; /* window write index */ + var window; /* allocated sliding window, if wsize != 0 */ + var hold; /* local strm.hold */ + var bits; /* local strm.bits */ + var lcode; /* local strm.lencode */ + var dcode; /* local strm.distcode */ + var lmask; /* mask for first level of length codes */ + var dmask; /* mask for first level of distance codes */ + var here; /* retrieved table entry */ + var op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + var len; /* match length, unused bytes */ + var dist; /* match distance */ + var from; /* where to copy match from */ + var from_source; + + + var input, output; // JS specific, because we have no pointers + + /* copy state to local variables */ + state = strm.state; + //here = state.here; + _in = strm.next_in; + input = strm.input; + last = _in + (strm.avail_in - 5); + _out = strm.next_out; + output = strm.output; + beg = _out - (start - strm.avail_out); + end = _out + (strm.avail_out - 257); +//#ifdef INFLATE_STRICT + dmax = state.dmax; +//#endif + wsize = state.wsize; + whave = state.whave; + wnext = state.wnext; + window = state.window; + hold = state.hold; + bits = state.bits; + lcode = state.lencode; + dcode = state.distcode; + lmask = (1 << state.lenbits) - 1; + dmask = (1 << state.distbits) - 1; + + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + + top: + do { + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + + here = lcode[hold & lmask]; + + dolen: + for (;;) { // Goto emulation + op = here >>> 24/*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff/*here.op*/; + if (op === 0) { /* literal */ + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + output[_out++] = here & 0xffff/*here.val*/; + } + else if (op & 16) { /* length base */ + len = here & 0xffff/*here.val*/; + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + len += hold & ((1 << op) - 1); + hold >>>= op; + bits -= op; + } + //Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + here = dcode[hold & dmask]; + + dodist: + for (;;) { // goto emulation + op = here >>> 24/*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff/*here.op*/; + + if (op & 16) { /* distance base */ + dist = here & 0xffff/*here.val*/; + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + } + dist += hold & ((1 << op) - 1); +//#ifdef INFLATE_STRICT + if (dist > dmax) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break top; + } +//#endif + hold >>>= op; + bits -= op; + //Tracevv((stderr, "inflate: distance %u\n", dist)); + op = _out - beg; /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state.sane) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break top; + } + +// (!) This block is disabled in zlib defailts, +// don't enable it for binary compatibility +//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR +// if (len <= op - whave) { +// do { +// output[_out++] = 0; +// } while (--len); +// continue top; +// } +// len -= op - whave; +// do { +// output[_out++] = 0; +// } while (--op > whave); +// if (op === 0) { +// from = _out - dist; +// do { +// output[_out++] = output[from++]; +// } while (--len); +// continue top; +// } +//#endif + } + from = 0; // window index + from_source = window; + if (wnext === 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + output[_out++] = window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + output[_out++] = window[from++]; + } while (--op); + from = 0; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + output[_out++] = window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + output[_out++] = window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + while (len > 2) { + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + len -= 3; + } + if (len) { + output[_out++] = from_source[from++]; + if (len > 1) { + output[_out++] = from_source[from++]; + } + } + } + else { + from = _out - dist; /* copy direct from output */ + do { /* minimum length is three */ + output[_out++] = output[from++]; + output[_out++] = output[from++]; + output[_out++] = output[from++]; + len -= 3; + } while (len > 2); + if (len) { + output[_out++] = output[from++]; + if (len > 1) { + output[_out++] = output[from++]; + } + } + } + } + else if ((op & 64) === 0) { /* 2nd level distance code */ + here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; + continue dodist; + } + else { + strm.msg = 'invalid distance code'; + state.mode = BAD; + break top; + } + + break; // need to emulate goto via "continue" + } + } + else if ((op & 64) === 0) { /* 2nd level length code */ + here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; + continue dolen; + } + else if (op & 32) { /* end-of-block */ + //Tracevv((stderr, "inflate: end of block\n")); + state.mode = TYPE; + break top; + } + else { + strm.msg = 'invalid literal/length code'; + state.mode = BAD; + break top; + } + + break; // need to emulate goto via "continue" + } + } while (_in < last && _out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + _in -= len; + bits -= len << 3; + hold &= (1 << bits) - 1; + + /* update state and return */ + strm.next_in = _in; + strm.next_out = _out; + strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); + strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); + state.hold = hold; + state.bits = bits; + return; +}; + +},{}],43:[function(require,module,exports){ +'use strict'; + + +var utils = require('../utils/common'); +var adler32 = require('./adler32'); +var crc32 = require('./crc32'); +var inflate_fast = require('./inffast'); +var inflate_table = require('./inftrees'); + +var CODES = 0; +var LENS = 1; +var DISTS = 2; + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +/* Allowed flush values; see deflate() and inflate() below for details */ +//var Z_NO_FLUSH = 0; +//var Z_PARTIAL_FLUSH = 1; +//var Z_SYNC_FLUSH = 2; +//var Z_FULL_FLUSH = 3; +var Z_FINISH = 4; +var Z_BLOCK = 5; +var Z_TREES = 6; + + +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ +var Z_OK = 0; +var Z_STREAM_END = 1; +var Z_NEED_DICT = 2; +//var Z_ERRNO = -1; +var Z_STREAM_ERROR = -2; +var Z_DATA_ERROR = -3; +var Z_MEM_ERROR = -4; +var Z_BUF_ERROR = -5; +//var Z_VERSION_ERROR = -6; + +/* The deflate compression method */ +var Z_DEFLATED = 8; + + +/* STATES ====================================================================*/ +/* ===========================================================================*/ + + +var HEAD = 1; /* i: waiting for magic header */ +var FLAGS = 2; /* i: waiting for method and flags (gzip) */ +var TIME = 3; /* i: waiting for modification time (gzip) */ +var OS = 4; /* i: waiting for extra flags and operating system (gzip) */ +var EXLEN = 5; /* i: waiting for extra length (gzip) */ +var EXTRA = 6; /* i: waiting for extra bytes (gzip) */ +var NAME = 7; /* i: waiting for end of file name (gzip) */ +var COMMENT = 8; /* i: waiting for end of comment (gzip) */ +var HCRC = 9; /* i: waiting for header crc (gzip) */ +var DICTID = 10; /* i: waiting for dictionary check value */ +var DICT = 11; /* waiting for inflateSetDictionary() call */ +var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ +var TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */ +var STORED = 14; /* i: waiting for stored size (length and complement) */ +var COPY_ = 15; /* i/o: same as COPY below, but only first time in */ +var COPY = 16; /* i/o: waiting for input or output to copy stored block */ +var TABLE = 17; /* i: waiting for dynamic block table lengths */ +var LENLENS = 18; /* i: waiting for code length code lengths */ +var CODELENS = 19; /* i: waiting for length/lit and distance code lengths */ +var LEN_ = 20; /* i: same as LEN below, but only first time in */ +var LEN = 21; /* i: waiting for length/lit/eob code */ +var LENEXT = 22; /* i: waiting for length extra bits */ +var DIST = 23; /* i: waiting for distance code */ +var DISTEXT = 24; /* i: waiting for distance extra bits */ +var MATCH = 25; /* o: waiting for output space to copy string */ +var LIT = 26; /* o: waiting for output space to write literal */ +var CHECK = 27; /* i: waiting for 32-bit check value */ +var LENGTH = 28; /* i: waiting for 32-bit length (gzip) */ +var DONE = 29; /* finished check, done -- remain here until reset */ +var BAD = 30; /* got a data error -- remain here until reset */ +var MEM = 31; /* got an inflate() memory error -- remain here until reset */ +var SYNC = 32; /* looking for synchronization bytes to restart inflate() */ + +/* ===========================================================================*/ + + + +var ENOUGH_LENS = 852; +var ENOUGH_DISTS = 592; +//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + +var MAX_WBITS = 15; +/* 32K LZ77 window */ +var DEF_WBITS = MAX_WBITS; + + +function ZSWAP32(q) { + return (((q >>> 24) & 0xff) + + ((q >>> 8) & 0xff00) + + ((q & 0xff00) << 8) + + ((q & 0xff) << 24)); +} + + +function InflateState() { + this.mode = 0; /* current inflate mode */ + this.last = false; /* true if processing last block */ + this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ + this.havedict = false; /* true if dictionary provided */ + this.flags = 0; /* gzip header method and flags (0 if zlib) */ + this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ + this.check = 0; /* protected copy of check value */ + this.total = 0; /* protected copy of output count */ + // TODO: may be {} + this.head = null; /* where to save gzip header information */ + + /* sliding window */ + this.wbits = 0; /* log base 2 of requested window size */ + this.wsize = 0; /* window size or zero if not using window */ + this.whave = 0; /* valid bytes in the window */ + this.wnext = 0; /* window write index */ + this.window = null; /* allocated sliding window, if needed */ + + /* bit accumulator */ + this.hold = 0; /* input bit accumulator */ + this.bits = 0; /* number of bits in "in" */ + + /* for string and stored block copying */ + this.length = 0; /* literal or length of data to copy */ + this.offset = 0; /* distance back to copy string from */ + + /* for table and code decoding */ + this.extra = 0; /* extra bits needed */ + + /* fixed and dynamic code tables */ + this.lencode = null; /* starting table for length/literal codes */ + this.distcode = null; /* starting table for distance codes */ + this.lenbits = 0; /* index bits for lencode */ + this.distbits = 0; /* index bits for distcode */ + + /* dynamic table building */ + this.ncode = 0; /* number of code length code lengths */ + this.nlen = 0; /* number of length code lengths */ + this.ndist = 0; /* number of distance code lengths */ + this.have = 0; /* number of code lengths in lens[] */ + this.next = null; /* next available space in codes[] */ + + this.lens = new utils.Buf16(320); /* temporary storage for code lengths */ + this.work = new utils.Buf16(288); /* work area for code table building */ + + /* + because we don't have pointers in js, we use lencode and distcode directly + as buffers so we don't need codes + */ + //this.codes = new utils.Buf32(ENOUGH); /* space for code tables */ + this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ + this.distdyn = null; /* dynamic table for distance codes (JS specific) */ + this.sane = 0; /* if false, allow invalid distance too far */ + this.back = 0; /* bits back of last unprocessed length/lit */ + this.was = 0; /* initial length of match */ +} + +function inflateResetKeep(strm) { + var state; + + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + strm.total_in = strm.total_out = state.total = 0; + strm.msg = ''; /*Z_NULL*/ + if (state.wrap) { /* to support ill-conceived Java test suite */ + strm.adler = state.wrap & 1; + } + state.mode = HEAD; + state.last = 0; + state.havedict = 0; + state.dmax = 32768; + state.head = null/*Z_NULL*/; + state.hold = 0; + state.bits = 0; + //state.lencode = state.distcode = state.next = state.codes; + state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS); + state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS); + + state.sane = 1; + state.back = -1; + //Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +function inflateReset(strm) { + var state; + + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + state.wsize = 0; + state.whave = 0; + state.wnext = 0; + return inflateResetKeep(strm); + +} + +function inflateReset2(strm, windowBits) { + var wrap; + var state; + + /* get the state */ + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; + if (windowBits < 48) { + windowBits &= 15; + } + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) { + return Z_STREAM_ERROR; + } + if (state.window !== null && state.wbits !== windowBits) { + state.window = null; + } + + /* update state and reset the rest of it */ + state.wrap = wrap; + state.wbits = windowBits; + return inflateReset(strm); +} + +function inflateInit2(strm, windowBits) { + var ret; + var state; + + if (!strm) { return Z_STREAM_ERROR; } + //strm.msg = Z_NULL; /* in case we return an error */ + + state = new InflateState(); + + //if (state === Z_NULL) return Z_MEM_ERROR; + //Tracev((stderr, "inflate: allocated\n")); + strm.state = state; + state.window = null/*Z_NULL*/; + ret = inflateReset2(strm, windowBits); + if (ret !== Z_OK) { + strm.state = null/*Z_NULL*/; + } + return ret; +} + +function inflateInit(strm) { + return inflateInit2(strm, DEF_WBITS); +} + + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +var virgin = true; + +var lenfix, distfix; // We have no pointers in JS, so keep tables separate + +function fixedtables(state) { + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + var sym; + + lenfix = new utils.Buf32(512); + distfix = new utils.Buf32(32); + + /* literal/length table */ + sym = 0; + while (sym < 144) { state.lens[sym++] = 8; } + while (sym < 256) { state.lens[sym++] = 9; } + while (sym < 280) { state.lens[sym++] = 7; } + while (sym < 288) { state.lens[sym++] = 8; } + + inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, {bits: 9}); + + /* distance table */ + sym = 0; + while (sym < 32) { state.lens[sym++] = 5; } + + inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, {bits: 5}); + + /* do this just once */ + virgin = false; + } + + state.lencode = lenfix; + state.lenbits = 9; + state.distcode = distfix; + state.distbits = 5; +} + + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +function updatewindow(strm, src, end, copy) { + var dist; + var state = strm.state; + + /* if it hasn't been done already, allocate space for the window */ + if (state.window === null) { + state.wsize = 1 << state.wbits; + state.wnext = 0; + state.whave = 0; + + state.window = new utils.Buf8(state.wsize); + } + + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state.wsize) { + utils.arraySet(state.window,src, end - state.wsize, state.wsize, 0); + state.wnext = 0; + state.whave = state.wsize; + } + else { + dist = state.wsize - state.wnext; + if (dist > copy) { + dist = copy; + } + //zmemcpy(state->window + state->wnext, end - copy, dist); + utils.arraySet(state.window,src, end - copy, dist, state.wnext); + copy -= dist; + if (copy) { + //zmemcpy(state->window, end - copy, copy); + utils.arraySet(state.window,src, end - copy, copy, 0); + state.wnext = copy; + state.whave = state.wsize; + } + else { + state.wnext += dist; + if (state.wnext === state.wsize) { state.wnext = 0; } + if (state.whave < state.wsize) { state.whave += dist; } + } + } + return 0; +} + +function inflate(strm, flush) { + var state; + var input, output; // input/output buffers + var next; /* next input INDEX */ + var put; /* next output INDEX */ + var have, left; /* available input and output */ + var hold; /* bit buffer */ + var bits; /* bits in bit buffer */ + var _in, _out; /* save starting available input and output */ + var copy; /* number of stored or match bytes to copy */ + var from; /* where to copy match bytes from */ + var from_source; + var here = 0; /* current decoding table entry */ + var here_bits, here_op, here_val; // paked "here" denormalized (JS specific) + //var last; /* parent table entry */ + var last_bits, last_op, last_val; // paked "last" denormalized (JS specific) + var len; /* length to copy for repeats, bits to drop */ + var ret; /* return code */ + var hbuf = new utils.Buf8(4); /* buffer for gzip header crc calculation */ + var opts; + + var n; // temporary var for NEED_BITS + + var order = /* permutation of code lengths */ + [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; + + + if (!strm || !strm.state || !strm.output || + (!strm.input && strm.avail_in !== 0)) { + return Z_STREAM_ERROR; + } + + state = strm.state; + if (state.mode === TYPE) { state.mode = TYPEDO; } /* skip check */ + + + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + _in = have; + _out = left; + ret = Z_OK; + + inf_leave: // goto emulation + for (;;) { + switch (state.mode) { + case HEAD: + if (state.wrap === 0) { + state.mode = TYPEDO; + break; + } + //=== NEEDBITS(16); + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ + state.check = 0/*crc32(0L, Z_NULL, 0)*/; + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = FLAGS; + break; + } + state.flags = 0; /* expect zlib header */ + if (state.head) { + state.head.done = false; + } + if (!(state.wrap & 1) || /* check if zlib header allowed */ + (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { + strm.msg = 'incorrect header check'; + state.mode = BAD; + break; + } + if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) { + strm.msg = 'unknown compression method'; + state.mode = BAD; + break; + } + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// + len = (hold & 0x0f)/*BITS(4)*/ + 8; + if (state.wbits === 0) { + state.wbits = len; + } + else if (len > state.wbits) { + strm.msg = 'invalid window size'; + state.mode = BAD; + break; + } + state.dmax = 1 << len; + //Tracev((stderr, "inflate: zlib header ok\n")); + strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; + state.mode = hold & 0x200 ? DICTID : TYPE; + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + break; + case FLAGS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.flags = hold; + if ((state.flags & 0xff) !== Z_DEFLATED) { + strm.msg = 'unknown compression method'; + state.mode = BAD; + break; + } + if (state.flags & 0xe000) { + strm.msg = 'unknown header flags set'; + state.mode = BAD; + break; + } + if (state.head) { + state.head.text = ((hold >> 8) & 1); + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = TIME; + /* falls through */ + case TIME: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.time = hold; + } + if (state.flags & 0x0200) { + //=== CRC4(state.check, hold) + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + hbuf[2] = (hold >>> 16) & 0xff; + hbuf[3] = (hold >>> 24) & 0xff; + state.check = crc32(state.check, hbuf, 4, 0); + //=== + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = OS; + /* falls through */ + case OS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.xflags = (hold & 0xff); + state.head.os = (hold >> 8); + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = EXLEN; + /* falls through */ + case EXLEN: + if (state.flags & 0x0400) { + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.length = hold; + if (state.head) { + state.head.extra_len = hold; + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + } + else if (state.head) { + state.head.extra = null/*Z_NULL*/; + } + state.mode = EXTRA; + /* falls through */ + case EXTRA: + if (state.flags & 0x0400) { + copy = state.length; + if (copy > have) { copy = have; } + if (copy) { + if (state.head) { + len = state.head.extra_len - state.length; + if (!state.head.extra) { + // Use untyped array for more conveniend processing later + state.head.extra = new Array(state.head.extra_len); + } + utils.arraySet( + state.head.extra, + input, + next, + // extra field is limited to 65536 bytes + // - no need for additional size check + copy, + /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ + len + ); + //zmemcpy(state.head.extra + len, next, + // len + copy > state.head.extra_max ? + // state.head.extra_max - len : copy); + } + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + state.length -= copy; + } + if (state.length) { break inf_leave; } + } + state.length = 0; + state.mode = NAME; + /* falls through */ + case NAME: + if (state.flags & 0x0800) { + if (have === 0) { break inf_leave; } + copy = 0; + do { + // TODO: 2 or 1 bytes? + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if (state.head && len && + (state.length < 65536 /*state.head.name_max*/)) { + state.head.name += String.fromCharCode(len); + } + } while (len && copy < have); + + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + if (len) { break inf_leave; } + } + else if (state.head) { + state.head.name = null; + } + state.length = 0; + state.mode = COMMENT; + /* falls through */ + case COMMENT: + if (state.flags & 0x1000) { + if (have === 0) { break inf_leave; } + copy = 0; + do { + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if (state.head && len && + (state.length < 65536 /*state.head.comm_max*/)) { + state.head.comment += String.fromCharCode(len); + } + } while (len && copy < have); + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + if (len) { break inf_leave; } + } + else if (state.head) { + state.head.comment = null; + } + state.mode = HCRC; + /* falls through */ + case HCRC: + if (state.flags & 0x0200) { + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (hold !== (state.check & 0xffff)) { + strm.msg = 'header crc mismatch'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + } + if (state.head) { + state.head.hcrc = ((state.flags >> 9) & 1); + state.head.done = true; + } + strm.adler = state.check = 0 /*crc32(0L, Z_NULL, 0)*/; + state.mode = TYPE; + break; + case DICTID: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + strm.adler = state.check = ZSWAP32(hold); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = DICT; + /* falls through */ + case DICT: + if (state.havedict === 0) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + return Z_NEED_DICT; + } + strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; + state.mode = TYPE; + /* falls through */ + case TYPE: + if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; } + /* falls through */ + case TYPEDO: + if (state.last) { + //--- BYTEBITS() ---// + hold >>>= bits & 7; + bits -= bits & 7; + //---// + state.mode = CHECK; + break; + } + //=== NEEDBITS(3); */ + while (bits < 3) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.last = (hold & 0x01)/*BITS(1)*/; + //--- DROPBITS(1) ---// + hold >>>= 1; + bits -= 1; + //---// + + switch ((hold & 0x03)/*BITS(2)*/) { + case 0: /* stored block */ + //Tracev((stderr, "inflate: stored block%s\n", + // state.last ? " (last)" : "")); + state.mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + //Tracev((stderr, "inflate: fixed codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = LEN_; /* decode codes */ + if (flush === Z_TREES) { + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break inf_leave; + } + break; + case 2: /* dynamic block */ + //Tracev((stderr, "inflate: dynamic codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = TABLE; + break; + case 3: + strm.msg = 'invalid block type'; + state.mode = BAD; + } + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break; + case STORED: + //--- BYTEBITS() ---// /* go to byte boundary */ + hold >>>= bits & 7; + bits -= bits & 7; + //---// + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { + strm.msg = 'invalid stored block lengths'; + state.mode = BAD; + break; + } + state.length = hold & 0xffff; + //Tracev((stderr, "inflate: stored length %u\n", + // state.length)); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = COPY_; + if (flush === Z_TREES) { break inf_leave; } + /* falls through */ + case COPY_: + state.mode = COPY; + /* falls through */ + case COPY: + copy = state.length; + if (copy) { + if (copy > have) { copy = have; } + if (copy > left) { copy = left; } + if (copy === 0) { break inf_leave; } + //--- zmemcpy(put, next, copy); --- + utils.arraySet(output, input, next, copy, put); + //---// + have -= copy; + next += copy; + left -= copy; + put += copy; + state.length -= copy; + break; + } + //Tracev((stderr, "inflate: stored end\n")); + state.mode = TYPE; + break; + case TABLE: + //=== NEEDBITS(14); */ + while (bits < 14) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// +//#ifndef PKZIP_BUG_WORKAROUND + if (state.nlen > 286 || state.ndist > 30) { + strm.msg = 'too many length or distance symbols'; + state.mode = BAD; + break; + } +//#endif + //Tracev((stderr, "inflate: table sizes ok\n")); + state.have = 0; + state.mode = LENLENS; + /* falls through */ + case LENLENS: + while (state.have < state.ncode) { + //=== NEEDBITS(3); + while (bits < 3) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; + //---// + } + while (state.have < 19) { + state.lens[order[state.have++]] = 0; + } + // We have separate tables & no pointers. 2 commented lines below not needed. + //state.next = state.codes; + //state.lencode = state.next; + // Switch to use dynamic table + state.lencode = state.lendyn; + state.lenbits = 7; + + opts = {bits: state.lenbits}; + ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); + state.lenbits = opts.bits; + + if (ret) { + strm.msg = 'invalid code lengths set'; + state.mode = BAD; + break; + } + //Tracev((stderr, "inflate: code lengths ok\n")); + state.have = 0; + state.mode = CODELENS; + /* falls through */ + case CODELENS: + while (state.have < state.nlen + state.ndist) { + for (;;) { + here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if (here_val < 16) { + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.lens[state.have++] = here_val; + } + else { + if (here_val === 16) { + //=== NEEDBITS(here.bits + 2); + n = here_bits + 2; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + if (state.have === 0) { + strm.msg = 'invalid bit length repeat'; + state.mode = BAD; + break; + } + len = state.lens[state.have - 1]; + copy = 3 + (hold & 0x03);//BITS(2); + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + } + else if (here_val === 17) { + //=== NEEDBITS(here.bits + 3); + n = here_bits + 3; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 3 + (hold & 0x07);//BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; + //---// + } + else { + //=== NEEDBITS(here.bits + 7); + n = here_bits + 7; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 11 + (hold & 0x7f);//BITS(7); + //--- DROPBITS(7) ---// + hold >>>= 7; + bits -= 7; + //---// + } + if (state.have + copy > state.nlen + state.ndist) { + strm.msg = 'invalid bit length repeat'; + state.mode = BAD; + break; + } + while (copy--) { + state.lens[state.have++] = len; + } + } + } + + /* handle error breaks in while */ + if (state.mode === BAD) { break; } + + /* check for end-of-block code (better have one) */ + if (state.lens[256] === 0) { + strm.msg = 'invalid code -- missing end-of-block'; + state.mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state.lenbits = 9; + + opts = {bits: state.lenbits}; + ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.lenbits = opts.bits; + // state.lencode = state.next; + + if (ret) { + strm.msg = 'invalid literal/lengths set'; + state.mode = BAD; + break; + } + + state.distbits = 6; + //state.distcode.copy(state.codes); + // Switch to use dynamic table + state.distcode = state.distdyn; + opts = {bits: state.distbits}; + ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.distbits = opts.bits; + // state.distcode = state.next; + + if (ret) { + strm.msg = 'invalid distances set'; + state.mode = BAD; + break; + } + //Tracev((stderr, 'inflate: codes ok\n')); + state.mode = LEN_; + if (flush === Z_TREES) { break inf_leave; } + /* falls through */ + case LEN_: + state.mode = LEN; + /* falls through */ + case LEN: + if (have >= 6 && left >= 258) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + inflate_fast(strm, _out); + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + if (state.mode === TYPE) { + state.back = -1; + } + break; + } + state.back = 0; + for (;;) { + here = state.lencode[hold & ((1 << state.lenbits) -1)]; /*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if (here_bits <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if (here_op && (here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (;;) { + here = state.lencode[last_val + + ((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits)]; + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((last_bits + here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; + //---// + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + state.length = here_val; + if (here_op === 0) { + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + state.mode = LIT; + break; + } + if (here_op & 32) { + //Tracevv((stderr, "inflate: end of block\n")); + state.back = -1; + state.mode = TYPE; + break; + } + if (here_op & 64) { + strm.msg = 'invalid literal/length code'; + state.mode = BAD; + break; + } + state.extra = here_op & 15; + state.mode = LENEXT; + /* falls through */ + case LENEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.length += hold & ((1 << state.extra) -1)/*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } + //Tracevv((stderr, "inflate: length %u\n", state.length)); + state.was = state.length; + state.mode = DIST; + /* falls through */ + case DIST: + for (;;) { + here = state.distcode[hold & ((1 << state.distbits) -1)];/*BITS(state.distbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if ((here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (;;) { + here = state.distcode[last_val + + ((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits)]; + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((last_bits + here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; + //---// + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + if (here_op & 64) { + strm.msg = 'invalid distance code'; + state.mode = BAD; + break; + } + state.offset = here_val; + state.extra = (here_op) & 15; + state.mode = DISTEXT; + /* falls through */ + case DISTEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.offset += hold & ((1 << state.extra) -1)/*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } +//#ifdef INFLATE_STRICT + if (state.offset > state.dmax) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break; + } +//#endif + //Tracevv((stderr, "inflate: distance %u\n", state.offset)); + state.mode = MATCH; + /* falls through */ + case MATCH: + if (left === 0) { break inf_leave; } + copy = _out - left; + if (state.offset > copy) { /* copy from window */ + copy = state.offset - copy; + if (copy > state.whave) { + if (state.sane) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break; + } +// (!) This block is disabled in zlib defailts, +// don't enable it for binary compatibility +//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR +// Trace((stderr, "inflate.c too far\n")); +// copy -= state.whave; +// if (copy > state.length) { copy = state.length; } +// if (copy > left) { copy = left; } +// left -= copy; +// state.length -= copy; +// do { +// output[put++] = 0; +// } while (--copy); +// if (state.length === 0) { state.mode = LEN; } +// break; +//#endif + } + if (copy > state.wnext) { + copy -= state.wnext; + from = state.wsize - copy; + } + else { + from = state.wnext - copy; + } + if (copy > state.length) { copy = state.length; } + from_source = state.window; + } + else { /* copy from output */ + from_source = output; + from = put - state.offset; + copy = state.length; + } + if (copy > left) { copy = left; } + left -= copy; + state.length -= copy; + do { + output[put++] = from_source[from++]; + } while (--copy); + if (state.length === 0) { state.mode = LEN; } + break; + case LIT: + if (left === 0) { break inf_leave; } + output[put++] = state.length; + left--; + state.mode = LEN; + break; + case CHECK: + if (state.wrap) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + // Use '|' insdead of '+' to make sure that result is signed + hold |= input[next++] << bits; + bits += 8; + } + //===// + _out -= left; + strm.total_out += _out; + state.total += _out; + if (_out) { + strm.adler = state.check = + /*UPDATE(state.check, put - _out, _out);*/ + (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out)); + + } + _out = left; + // NB: crc32 stored as signed 32-bit int, ZSWAP32 returns signed too + if ((state.flags ? hold : ZSWAP32(hold)) !== state.check) { + strm.msg = 'incorrect data check'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: check matches trailer\n")); + } + state.mode = LENGTH; + /* falls through */ + case LENGTH: + if (state.wrap && state.flags) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (hold !== (state.total & 0xffffffff)) { + strm.msg = 'incorrect length check'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: length matches trailer\n")); + } + state.mode = DONE; + /* falls through */ + case DONE: + ret = Z_STREAM_END; + break inf_leave; + case BAD: + ret = Z_DATA_ERROR; + break inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + /* falls through */ + default: + return Z_STREAM_ERROR; + } + } + + // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + + if (state.wsize || (_out !== strm.avail_out && state.mode < BAD && + (state.mode < CHECK || flush !== Z_FINISH))) { + if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) { + state.mode = MEM; + return Z_MEM_ERROR; + } + } + _in -= strm.avail_in; + _out -= strm.avail_out; + strm.total_in += _in; + strm.total_out += _out; + state.total += _out; + if (state.wrap && _out) { + strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/ + (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out)); + } + strm.data_type = state.bits + (state.last ? 64 : 0) + + (state.mode === TYPE ? 128 : 0) + + (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0); + if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) { + ret = Z_BUF_ERROR; + } + return ret; +} + +function inflateEnd(strm) { + + if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) { + return Z_STREAM_ERROR; + } + + var state = strm.state; + if (state.window) { + state.window = null; + } + strm.state = null; + return Z_OK; +} + +function inflateGetHeader(strm, head) { + var state; + + /* check state */ + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; } + + /* save header structure */ + state.head = head; + head.done = false; + return Z_OK; +} + + +exports.inflateReset = inflateReset; +exports.inflateReset2 = inflateReset2; +exports.inflateResetKeep = inflateResetKeep; +exports.inflateInit = inflateInit; +exports.inflateInit2 = inflateInit2; +exports.inflate = inflate; +exports.inflateEnd = inflateEnd; +exports.inflateGetHeader = inflateGetHeader; +exports.inflateInfo = 'pako inflate (from Nodeca project)'; + +/* Not implemented +exports.inflateCopy = inflateCopy; +exports.inflateGetDictionary = inflateGetDictionary; +exports.inflateMark = inflateMark; +exports.inflatePrime = inflatePrime; +exports.inflateSetDictionary = inflateSetDictionary; +exports.inflateSync = inflateSync; +exports.inflateSyncPoint = inflateSyncPoint; +exports.inflateUndermine = inflateUndermine; +*/ + +},{"../utils/common":35,"./adler32":37,"./crc32":39,"./inffast":42,"./inftrees":44}],44:[function(require,module,exports){ +'use strict'; + + +var utils = require('../utils/common'); + +var MAXBITS = 15; +var ENOUGH_LENS = 852; +var ENOUGH_DISTS = 592; +//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + +var CODES = 0; +var LENS = 1; +var DISTS = 2; + +var lbase = [ /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 +]; + +var lext = [ /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 +]; + +var dbase = [ /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0 +]; + +var dext = [ /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64 +]; + +module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) +{ + var bits = opts.bits; + //here = opts.here; /* table entry for duplication */ + + var len = 0; /* a code's length in bits */ + var sym = 0; /* index of code symbols */ + var min = 0, max = 0; /* minimum and maximum code lengths */ + var root = 0; /* number of index bits for root table */ + var curr = 0; /* number of index bits for current table */ + var drop = 0; /* code bits to drop for sub-table */ + var left = 0; /* number of prefix codes available */ + var used = 0; /* code entries in table used */ + var huff = 0; /* Huffman code */ + var incr; /* for incrementing code, index */ + var fill; /* index for replicating entries */ + var low; /* low bits for current root entry */ + var mask; /* mask for low root bits */ + var next; /* next available space in table */ + var base = null; /* base value table to use */ + var base_index = 0; +// var shoextra; /* extra bits table to use */ + var end; /* use base and extra for symbol > end */ + var count = new utils.Buf16(MAXBITS+1); //[MAXBITS+1]; /* number of codes of each length */ + var offs = new utils.Buf16(MAXBITS+1); //[MAXBITS+1]; /* offsets in table for each length */ + var extra = null; + var extra_index = 0; + + var here_bits, here_op, here_val; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) { + count[len] = 0; + } + for (sym = 0; sym < codes; sym++) { + count[lens[lens_index + sym]]++; + } + + /* bound code lengths, force root to be within code lengths */ + root = bits; + for (max = MAXBITS; max >= 1; max--) { + if (count[max] !== 0) { break; } + } + if (root > max) { + root = max; + } + if (max === 0) { /* no symbols to code at all */ + //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ + //table.bits[opts.table_index] = 1; //here.bits = (var char)1; + //table.val[opts.table_index++] = 0; //here.val = (var short)0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; + + + //table.op[opts.table_index] = 64; + //table.bits[opts.table_index] = 1; + //table.val[opts.table_index++] = 0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; + + opts.bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) { + if (count[min] !== 0) { break; } + } + if (root < min) { + root = min; + } + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) { + return -1; + } /* over-subscribed */ + } + if (left > 0 && (type === CODES || max !== 1)) { + return -1; /* incomplete set */ + } + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) { + offs[len + 1] = offs[len] + count[len]; + } + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) { + if (lens[lens_index + sym] !== 0) { + work[offs[lens[lens_index + sym]]++] = sym; + } + } + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + // poor man optimization - use if-else instead of switch, + // to avoid deopts in old v8 + if (type === CODES) { + base = extra = work; /* dummy value--not used */ + end = 19; + + } else if (type === LENS) { + base = lbase; + base_index -= 257; + extra = lext; + extra_index -= 257; + end = 256; + + } else { /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize opts for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = table_index; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = -1; /* trigger new sub-table when len > root */ + used = 1 << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type === LENS && used > ENOUGH_LENS) || + (type === DISTS && used > ENOUGH_DISTS)) { + return 1; + } + + var i=0; + /* process all codes and make table entries */ + for (;;) { + i++; + /* create table entry */ + here_bits = len - drop; + if (work[sym] < end) { + here_op = 0; + here_val = work[sym]; + } + else if (work[sym] > end) { + here_op = extra[extra_index + work[sym]]; + here_val = base[base_index + work[sym]]; + } + else { + here_op = 32 + 64; /* end of block */ + here_val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1 << (len - drop); + fill = 1 << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; + } while (fill !== 0); + + /* backwards increment the len-bit code huff */ + incr = 1 << (len - 1); + while (huff & incr) { + incr >>= 1; + } + if (incr !== 0) { + huff &= incr - 1; + huff += incr; + } else { + huff = 0; + } + + /* go to next symbol, update count, len */ + sym++; + if (--count[len] === 0) { + if (len === max) { break; } + len = lens[lens_index + work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) !== low) { + /* if first time, transition to sub-tables */ + if (drop === 0) { + drop = root; + } + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = 1 << curr; + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) { break; } + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1 << curr; + if ((type === LENS && used > ENOUGH_LENS) || + (type === DISTS && used > ENOUGH_DISTS)) { + return 1; + } + + /* point entry in root table to sub-table */ + low = huff & mask; + /*table.op[low] = curr; + table.bits[low] = root; + table.val[low] = next - opts.table_index;*/ + table[low] = (root << 24) | (curr << 16) | (next - table_index) |0; + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff !== 0) { + //table.op[next + huff] = 64; /* invalid code marker */ + //table.bits[next + huff] = len - drop; + //table.val[next + huff] = 0; + table[next + huff] = ((len - drop) << 24) | (64 << 16) |0; + } + + /* set return parameters */ + //opts.table_index += used; + opts.bits = root; + return 0; +}; + +},{"../utils/common":35}],45:[function(require,module,exports){ +'use strict'; + +module.exports = { + '2': 'need dictionary', /* Z_NEED_DICT 2 */ + '1': 'stream end', /* Z_STREAM_END 1 */ + '0': '', /* Z_OK 0 */ + '-1': 'file error', /* Z_ERRNO (-1) */ + '-2': 'stream error', /* Z_STREAM_ERROR (-2) */ + '-3': 'data error', /* Z_DATA_ERROR (-3) */ + '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */ + '-5': 'buffer error', /* Z_BUF_ERROR (-5) */ + '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ +}; + +},{}],46:[function(require,module,exports){ +'use strict'; + + +var utils = require('../utils/common'); + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +//var Z_FILTERED = 1; +//var Z_HUFFMAN_ONLY = 2; +//var Z_RLE = 3; +var Z_FIXED = 4; +//var Z_DEFAULT_STRATEGY = 0; + +/* Possible values of the data_type field (though see inflate()) */ +var Z_BINARY = 0; +var Z_TEXT = 1; +//var Z_ASCII = 1; // = Z_TEXT +var Z_UNKNOWN = 2; + +/*============================================================================*/ + + +function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } + +// From zutil.h + +var STORED_BLOCK = 0; +var STATIC_TREES = 1; +var DYN_TREES = 2; +/* The three kinds of block type */ + +var MIN_MATCH = 3; +var MAX_MATCH = 258; +/* The minimum and maximum match lengths */ + +// From deflate.h +/* =========================================================================== + * Internal compression state. + */ + +var LENGTH_CODES = 29; +/* number of length codes, not counting the special END_BLOCK code */ + +var LITERALS = 256; +/* number of literal bytes 0..255 */ + +var L_CODES = LITERALS + 1 + LENGTH_CODES; +/* number of Literal or Length codes, including the END_BLOCK code */ + +var D_CODES = 30; +/* number of distance codes */ + +var BL_CODES = 19; +/* number of codes used to transfer the bit lengths */ + +var HEAP_SIZE = 2*L_CODES + 1; +/* maximum heap size */ + +var MAX_BITS = 15; +/* All codes must not exceed MAX_BITS bits */ + +var Buf_size = 16; +/* size of bit buffer in bi_buf */ + + +/* =========================================================================== + * Constants + */ + +var MAX_BL_BITS = 7; +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +var END_BLOCK = 256; +/* end of block literal code */ + +var REP_3_6 = 16; +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +var REPZ_3_10 = 17; +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +var REPZ_11_138 = 18; +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +var extra_lbits = /* extra bits for each length code */ + [0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]; + +var extra_dbits = /* extra bits for each distance code */ + [0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]; + +var extra_blbits = /* extra bits for each bit length code */ + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]; + +var bl_order = + [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +// We pre-fill arrays with 0 to avoid uninitialized gaps + +var DIST_CODE_LEN = 512; /* see definition of array dist_code below */ + +// !!!! Use flat array insdead of structure, Freq = i*2, Len = i*2+1 +var static_ltree = new Array((L_CODES+2) * 2); +zero(static_ltree); +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +var static_dtree = new Array(D_CODES * 2); +zero(static_dtree); +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +var _dist_code = new Array(DIST_CODE_LEN); +zero(_dist_code); +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +var _length_code = new Array(MAX_MATCH-MIN_MATCH+1); +zero(_length_code); +/* length code for each normalized match length (0 == MIN_MATCH) */ + +var base_length = new Array(LENGTH_CODES); +zero(base_length); +/* First normalized length for each code (0 = MIN_MATCH) */ + +var base_dist = new Array(D_CODES); +zero(base_dist); +/* First normalized distance for each code (0 = distance of 1) */ + + +var StaticTreeDesc = function (static_tree, extra_bits, extra_base, elems, max_length) { + + this.static_tree = static_tree; /* static tree or NULL */ + this.extra_bits = extra_bits; /* extra bits for each code or NULL */ + this.extra_base = extra_base; /* base index for extra_bits */ + this.elems = elems; /* max number of elements in the tree */ + this.max_length = max_length; /* max bit length for the codes */ + + // show if `static_tree` has data or dummy - needed for monomorphic objects + this.has_stree = static_tree && static_tree.length; +}; + + +var static_l_desc; +var static_d_desc; +var static_bl_desc; + + +var TreeDesc = function(dyn_tree, stat_desc) { + this.dyn_tree = dyn_tree; /* the dynamic tree */ + this.max_code = 0; /* largest code with non zero frequency */ + this.stat_desc = stat_desc; /* the corresponding static tree */ +}; + + + +function d_code(dist) { + return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)]; +} + + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +function put_short (s, w) { +// put_byte(s, (uch)((w) & 0xff)); +// put_byte(s, (uch)((ush)(w) >> 8)); + s.pending_buf[s.pending++] = (w) & 0xff; + s.pending_buf[s.pending++] = (w >>> 8) & 0xff; +} + + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +function send_bits(s, value, length) { + if (s.bi_valid > (Buf_size - length)) { + s.bi_buf |= (value << s.bi_valid) & 0xffff; + put_short(s, s.bi_buf); + s.bi_buf = value >> (Buf_size - s.bi_valid); + s.bi_valid += length - Buf_size; + } else { + s.bi_buf |= (value << s.bi_valid) & 0xffff; + s.bi_valid += length; + } +} + + +function send_code(s, c, tree) { + send_bits(s, tree[c*2]/*.Code*/, tree[c*2 + 1]/*.Len*/); +} + + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +function bi_reverse(code, len) { + var res = 0; + do { + res |= code & 1; + code >>>= 1; + res <<= 1; + } while (--len > 0); + return res >>> 1; +} + + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +function bi_flush(s) { + if (s.bi_valid === 16) { + put_short(s, s.bi_buf); + s.bi_buf = 0; + s.bi_valid = 0; + + } else if (s.bi_valid >= 8) { + s.pending_buf[s.pending++] = s.bi_buf & 0xff; + s.bi_buf >>= 8; + s.bi_valid -= 8; + } +} + + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +function gen_bitlen(s, desc) +// deflate_state *s; +// tree_desc *desc; /* the tree descriptor */ +{ + var tree = desc.dyn_tree; + var max_code = desc.max_code; + var stree = desc.stat_desc.static_tree; + var has_stree = desc.stat_desc.has_stree; + var extra = desc.stat_desc.extra_bits; + var base = desc.stat_desc.extra_base; + var max_length = desc.stat_desc.max_length; + var h; /* heap index */ + var n, m; /* iterate over the tree elements */ + var bits; /* bit length */ + var xbits; /* extra bits */ + var f; /* frequency */ + var overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) { + s.bl_count[bits] = 0; + } + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s.heap[s.heap_max]*2 + 1]/*.Len*/ = 0; /* root of the heap */ + + for (h = s.heap_max+1; h < HEAP_SIZE; h++) { + n = s.heap[h]; + bits = tree[tree[n*2 +1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1; + if (bits > max_length) { + bits = max_length; + overflow++; + } + tree[n*2 + 1]/*.Len*/ = bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) { continue; } /* not a leaf node */ + + s.bl_count[bits]++; + xbits = 0; + if (n >= base) { + xbits = extra[n-base]; + } + f = tree[n * 2]/*.Freq*/; + s.opt_len += f * (bits + xbits); + if (has_stree) { + s.static_len += f * (stree[n*2 + 1]/*.Len*/ + xbits); + } + } + if (overflow === 0) { return; } + + // Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s.bl_count[bits] === 0) { bits--; } + s.bl_count[bits]--; /* move one leaf down the tree */ + s.bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s.bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits !== 0; bits--) { + n = s.bl_count[bits]; + while (n !== 0) { + m = s.heap[--h]; + if (m > max_code) { continue; } + if (tree[m*2 + 1]/*.Len*/ !== bits) { + // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s.opt_len += (bits - tree[m*2 + 1]/*.Len*/)*tree[m*2]/*.Freq*/; + tree[m*2 + 1]/*.Len*/ = bits; + } + n--; + } + } +} + + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +function gen_codes(tree, max_code, bl_count) +// ct_data *tree; /* the tree to decorate */ +// int max_code; /* largest code with non zero frequency */ +// ushf *bl_count; /* number of codes at each bit length */ +{ + var next_code = new Array(MAX_BITS+1); /* next code value for each bit length */ + var code = 0; /* running code value */ + var bits; /* bit index */ + var n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + //Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, + // "inconsistent bit counts"); + //Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); + + for (n = 0; n <= max_code; n++) { + var len = tree[n*2 + 1]/*.Len*/; + if (len === 0) { continue; } + /* Now reverse the bits */ + tree[n*2]/*.Code*/ = bi_reverse(next_code[len]++, len); + + //Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", + // n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); + } +} + + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +function tr_static_init() { + var n; /* iterates over tree elements */ + var bits; /* bit counter */ + var length; /* length value */ + var code; /* code value */ + var dist; /* distance index */ + var bl_count = new Array(MAX_BITS+1); + /* number of codes at each bit length for an optimal tree */ + + // do check in _tr_init() + //if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +/*#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif*/ + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1<<extra_lbits[code]); n++) { + _length_code[length++] = code; + } + } + //Assert (length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + _length_code[length-1] = code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<<extra_dbits[code]); n++) { + _dist_code[dist++] = code; + } + } + //Assert (dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for (; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = code; + } + } + //Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) { + bl_count[bits] = 0; + } + + n = 0; + while (n <= 143) { + static_ltree[n*2 + 1]/*.Len*/ = 8; + n++; + bl_count[8]++; + } + while (n <= 255) { + static_ltree[n*2 + 1]/*.Len*/ = 9; + n++; + bl_count[9]++; + } + while (n <= 279) { + static_ltree[n*2 + 1]/*.Len*/ = 7; + n++; + bl_count[7]++; + } + while (n <= 287) { + static_ltree[n*2 + 1]/*.Len*/ = 8; + n++; + bl_count[8]++; + } + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes(static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n*2 + 1]/*.Len*/ = 5; + static_dtree[n*2]/*.Code*/ = bi_reverse(n, 5); + } + + // Now data ready and we can init static trees + static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS); + static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES, MAX_BITS); + static_bl_desc =new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES, MAX_BL_BITS); + + //static_init_done = true; +} + + +/* =========================================================================== + * Initialize a new block. + */ +function init_block(s) { + var n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) { s.dyn_ltree[n*2]/*.Freq*/ = 0; } + for (n = 0; n < D_CODES; n++) { s.dyn_dtree[n*2]/*.Freq*/ = 0; } + for (n = 0; n < BL_CODES; n++) { s.bl_tree[n*2]/*.Freq*/ = 0; } + + s.dyn_ltree[END_BLOCK*2]/*.Freq*/ = 1; + s.opt_len = s.static_len = 0; + s.last_lit = s.matches = 0; +} + + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +function bi_windup(s) +{ + if (s.bi_valid > 8) { + put_short(s, s.bi_buf); + } else if (s.bi_valid > 0) { + //put_byte(s, (Byte)s->bi_buf); + s.pending_buf[s.pending++] = s.bi_buf; + } + s.bi_buf = 0; + s.bi_valid = 0; +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +function copy_block(s, buf, len, header) +//DeflateState *s; +//charf *buf; /* the input data */ +//unsigned len; /* its length */ +//int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + + if (header) { + put_short(s, len); + put_short(s, ~len); + } +// while (len--) { +// put_byte(s, *buf++); +// } + utils.arraySet(s.pending_buf, s.window, buf, len, s.pending); + s.pending += len; +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +function smaller(tree, n, m, depth) { + var _n2 = n*2; + var _m2 = m*2; + return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ || + (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m])); +} + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +function pqdownheap(s, tree, k) +// deflate_state *s; +// ct_data *tree; /* the tree to restore */ +// int k; /* node to move down */ +{ + var v = s.heap[k]; + var j = k << 1; /* left son of k */ + while (j <= s.heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s.heap_len && + smaller(tree, s.heap[j+1], s.heap[j], s.depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s.heap[j], s.depth)) { break; } + + /* Exchange v with the smallest son */ + s.heap[k] = s.heap[j]; + k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s.heap[k] = v; +} + + +// inlined manually +// var SMALLEST = 1; + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +function compress_block(s, ltree, dtree) +// deflate_state *s; +// const ct_data *ltree; /* literal tree */ +// const ct_data *dtree; /* distance tree */ +{ + var dist; /* distance of matched string */ + var lc; /* match length or unmatched char (if dist == 0) */ + var lx = 0; /* running index in l_buf */ + var code; /* the code to send */ + var extra; /* number of extra bits to send */ + + if (s.last_lit !== 0) { + do { + dist = (s.pending_buf[s.d_buf + lx*2] << 8) | (s.pending_buf[s.d_buf + lx*2 + 1]); + lc = s.pending_buf[s.l_buf + lx]; + lx++; + + if (dist === 0) { + send_code(s, lc, ltree); /* send a literal byte */ + //Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra !== 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + //Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra !== 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + // "pendingBuf overflow"); + + } while (lx < s.last_lit); + } + + send_code(s, END_BLOCK, ltree); +} + + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +function build_tree(s, desc) +// deflate_state *s; +// tree_desc *desc; /* the tree descriptor */ +{ + var tree = desc.dyn_tree; + var stree = desc.stat_desc.static_tree; + var has_stree = desc.stat_desc.has_stree; + var elems = desc.stat_desc.elems; + var n, m; /* iterate over heap elements */ + var max_code = -1; /* largest code with non zero frequency */ + var node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s.heap_len = 0; + s.heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n * 2]/*.Freq*/ !== 0) { + s.heap[++s.heap_len] = max_code = n; + s.depth[n] = 0; + + } else { + tree[n*2 + 1]/*.Len*/ = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s.heap_len < 2) { + node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); + tree[node * 2]/*.Freq*/ = 1; + s.depth[node] = 0; + s.opt_len--; + + if (has_stree) { + s.static_len -= stree[node*2 + 1]/*.Len*/; + } + /* node is 0 or 1 so it does not have extra bits */ + } + desc.max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); } + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + //pqremove(s, tree, n); /* n = node of least frequency */ + /*** pqremove ***/ + n = s.heap[1/*SMALLEST*/]; + s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--]; + pqdownheap(s, tree, 1/*SMALLEST*/); + /***/ + + m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ + + s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ + s.heap[--s.heap_max] = m; + + /* Create a new node father of n and m */ + tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; + s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; + tree[n*2 + 1]/*.Dad*/ = tree[m*2 + 1]/*.Dad*/ = node; + + /* and insert the new node in the heap */ + s.heap[1/*SMALLEST*/] = node++; + pqdownheap(s, tree, 1/*SMALLEST*/); + + } while (s.heap_len >= 2); + + s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes(tree, max_code, s.bl_count); +} + + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +function scan_tree(s, tree, max_code) +// deflate_state *s; +// ct_data *tree; /* the tree to be scanned */ +// int max_code; /* and its largest code of non zero frequency */ +{ + var n; /* iterates over all tree elements */ + var prevlen = -1; /* last emitted length */ + var curlen; /* length of current code */ + + var nextlen = tree[0*2 + 1]/*.Len*/; /* length of next code */ + + var count = 0; /* repeat count of the current code */ + var max_count = 7; /* max repeat count */ + var min_count = 4; /* min repeat count */ + + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } + tree[(max_code+1)*2 + 1]/*.Len*/ = 0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n+1)*2 + 1]/*.Len*/; + + if (++count < max_count && curlen === nextlen) { + continue; + + } else if (count < min_count) { + s.bl_tree[curlen * 2]/*.Freq*/ += count; + + } else if (curlen !== 0) { + + if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; } + s.bl_tree[REP_3_6*2]/*.Freq*/++; + + } else if (count <= 10) { + s.bl_tree[REPZ_3_10*2]/*.Freq*/++; + + } else { + s.bl_tree[REPZ_11_138*2]/*.Freq*/++; + } + + count = 0; + prevlen = curlen; + + if (nextlen === 0) { + max_count = 138; + min_count = 3; + + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; + + } else { + max_count = 7; + min_count = 4; + } + } +} + + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +function send_tree(s, tree, max_code) +// deflate_state *s; +// ct_data *tree; /* the tree to be scanned */ +// int max_code; /* and its largest code of non zero frequency */ +{ + var n; /* iterates over all tree elements */ + var prevlen = -1; /* last emitted length */ + var curlen; /* length of current code */ + + var nextlen = tree[0*2 + 1]/*.Len*/; /* length of next code */ + + var count = 0; /* repeat count of the current code */ + var max_count = 7; /* max repeat count */ + var min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n+1)*2 + 1]/*.Len*/; + + if (++count < max_count && curlen === nextlen) { + continue; + + } else if (count < min_count) { + do { send_code(s, curlen, s.bl_tree); } while (--count !== 0); + + } else if (curlen !== 0) { + if (curlen !== prevlen) { + send_code(s, curlen, s.bl_tree); + count--; + } + //Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s.bl_tree); + send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s.bl_tree); + send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s.bl_tree); + send_bits(s, count-11, 7); + } + + count = 0; + prevlen = curlen; + if (nextlen === 0) { + max_count = 138; + min_count = 3; + + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; + + } else { + max_count = 7; + min_count = 4; + } + } +} + + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +function build_bl_tree(s) { + var max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, s.dyn_ltree, s.l_desc.max_code); + scan_tree(s, s.dyn_dtree, s.d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, s.bl_desc); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s.bl_tree[bl_order[max_blindex]*2 + 1]/*.Len*/ !== 0) { + break; + } + } + /* Update opt_len to include the bit length tree and counts */ + s.opt_len += 3*(max_blindex+1) + 5+5+4; + //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + // s->opt_len, s->static_len)); + + return max_blindex; +} + + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +function send_all_trees(s, lcodes, dcodes, blcodes) +// deflate_state *s; +// int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + var rank; /* index in bl_order */ + + //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + // "too many codes"); + //Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + //Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s.bl_tree[bl_order[rank]*2 + 1]/*.Len*/, 3); + } + //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, s.dyn_ltree, lcodes-1); /* literal tree */ + //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, s.dyn_dtree, dcodes-1); /* distance tree */ + //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +function detect_data_type(s) { + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + var black_mask = 0xf3ffc07f; + var n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>>= 1) { + if ((black_mask & 1) && (s.dyn_ltree[n*2]/*.Freq*/ !== 0)) { + return Z_BINARY; + } + } + + /* Check for textual ("white-listed") bytes. */ + if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 || + s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) { + return Z_TEXT; + } + for (n = 32; n < LITERALS; n++) { + if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) { + return Z_TEXT; + } + } + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + + +var static_init_done = false; + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +function _tr_init(s) +{ + + if (!static_init_done) { + tr_static_init(); + static_init_done = true; + } + + s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); + s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); + s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); + + s.bi_buf = 0; + s.bi_valid = 0; + + /* Initialize the first block of the first file: */ + init_block(s); +} + + +/* =========================================================================== + * Send a stored block + */ +function _tr_stored_block(s, buf, stored_len, last) +//DeflateState *s; +//charf *buf; /* input block */ +//ulg stored_len; /* length of input block */ +//int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+(last ? 1 : 0), 3); /* send block type */ + copy_block(s, buf, stored_len, true); /* with header */ +} + + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +function _tr_align(s) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); + bi_flush(s); +} + + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +function _tr_flush_block(s, buf, stored_len, last) +//DeflateState *s; +//charf *buf; /* input block, or NULL if too old */ +//ulg stored_len; /* length of input block */ +//int last; /* one if this is the last block for a file */ +{ + var opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + var max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s.level > 0) { + + /* Check if the file is binary or text */ + if (s.strm.data_type === Z_UNKNOWN) { + s.strm.data_type = detect_data_type(s); + } + + /* Construct the literal and distance trees */ + build_tree(s, s.l_desc); + // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + // s->static_len)); + + build_tree(s, s.d_desc); + // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + // s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s.opt_len+3+7) >>> 3; + static_lenb = (s.static_len+3+7) >>> 3; + + // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + // s->last_lit)); + + if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } + + } else { + // Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + + if ((stored_len+4 <= opt_lenb) && (buf !== -1)) { + /* 4: two words for the lengths */ + + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + + } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) { + + send_bits(s, (STATIC_TREES<<1) + (last ? 1 : 0), 3); + compress_block(s, static_ltree, static_dtree); + + } else { + send_bits(s, (DYN_TREES<<1) + (last ? 1 : 0), 3); + send_all_trees(s, s.l_desc.max_code+1, s.d_desc.max_code+1, max_blindex+1); + compress_block(s, s.dyn_ltree, s.dyn_dtree); + } + // Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); + } + // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + // s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +function _tr_tally(s, dist, lc) +// deflate_state *s; +// unsigned dist; /* distance of matched string */ +// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + //var out_length, in_length, dcode; + + s.pending_buf[s.d_buf + s.last_lit * 2] = (dist >>> 8) & 0xff; + s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff; + + s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff; + s.last_lit++; + + if (dist === 0) { + /* lc is the unmatched char */ + s.dyn_ltree[lc*2]/*.Freq*/++; + } else { + s.matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + //Assert((ush)dist < (ush)MAX_DIST(s) && + // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s.dyn_ltree[(_length_code[lc]+LITERALS+1) * 2]/*.Freq*/++; + s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++; + } + +// (!) This block is disabled in zlib defailts, +// don't enable it for binary compatibility + +//#ifdef TRUNCATE_BLOCK +// /* Try to guess if it is profitable to stop the current block here */ +// if ((s.last_lit & 0x1fff) === 0 && s.level > 2) { +// /* Compute an upper bound for the compressed length */ +// out_length = s.last_lit*8; +// in_length = s.strstart - s.block_start; +// +// for (dcode = 0; dcode < D_CODES; dcode++) { +// out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]); +// } +// out_length >>>= 3; +// //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", +// // s->last_lit, in_length, out_length, +// // 100L - out_length*100L/in_length)); +// if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) { +// return true; +// } +// } +//#endif + + return (s.last_lit === s.lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +exports._tr_init = _tr_init; +exports._tr_stored_block = _tr_stored_block; +exports._tr_flush_block = _tr_flush_block; +exports._tr_tally = _tr_tally; +exports._tr_align = _tr_align; + +},{"../utils/common":35}],47:[function(require,module,exports){ +'use strict'; + + +function ZStream() { + /* next input byte */ + this.input = null; // JS specific, because we have no pointers + this.next_in = 0; + /* number of bytes available at input */ + this.avail_in = 0; + /* total number of input bytes read so far */ + this.total_in = 0; + /* next output byte should be put there */ + this.output = null; // JS specific, because we have no pointers + this.next_out = 0; + /* remaining free space at output */ + this.avail_out = 0; + /* total number of bytes output so far */ + this.total_out = 0; + /* last error message, NULL if no error */ + this.msg = ''/*Z_NULL*/; + /* not visible by applications */ + this.state = null; + /* best guess about the data type: binary or text */ + this.data_type = 2/*Z_UNKNOWN*/; + /* adler32 value of the uncompressed data */ + this.adler = 0; +} + +module.exports = ZStream; + +},{}],48:[function(require,module,exports){ +'use strict'; + +module.exports = INTERNAL; + +function INTERNAL() {} +},{}],49:[function(require,module,exports){ +'use strict'; +var Promise = require('./promise'); +var reject = require('./reject'); +var resolve = require('./resolve'); +var INTERNAL = require('./INTERNAL'); +var handlers = require('./handlers'); +module.exports = all; +function all(iterable) { + if (Object.prototype.toString.call(iterable) !== '[object Array]') { + return reject(new TypeError('must be an array')); + } + + var len = iterable.length; + var called = false; + if (!len) { + return resolve([]); + } + + var values = new Array(len); + var resolved = 0; + var i = -1; + var promise = new Promise(INTERNAL); + + while (++i < len) { + allResolver(iterable[i], i); + } + return promise; + function allResolver(value, i) { + resolve(value).then(resolveFromAll, function (error) { + if (!called) { + called = true; + handlers.reject(promise, error); + } + }); + function resolveFromAll(outValue) { + values[i] = outValue; + if (++resolved === len & !called) { + called = true; + handlers.resolve(promise, values); + } + } + } +} +},{"./INTERNAL":48,"./handlers":50,"./promise":52,"./reject":55,"./resolve":56}],50:[function(require,module,exports){ +'use strict'; +var tryCatch = require('./tryCatch'); +var resolveThenable = require('./resolveThenable'); +var states = require('./states'); + +exports.resolve = function (self, value) { + var result = tryCatch(getThen, value); + if (result.status === 'error') { + return exports.reject(self, result.value); + } + var thenable = result.value; + + if (thenable) { + resolveThenable.safely(self, thenable); + } else { + self.state = states.FULFILLED; + self.outcome = value; + var i = -1; + var len = self.queue.length; + while (++i < len) { + self.queue[i].callFulfilled(value); + } + } + return self; +}; +exports.reject = function (self, error) { + self.state = states.REJECTED; + self.outcome = error; + var i = -1; + var len = self.queue.length; + while (++i < len) { + self.queue[i].callRejected(error); + } + return self; +}; + +function getThen(obj) { + // Make sure we only access the accessor once as required by the spec + var then = obj && obj.then; + if (obj && typeof obj === 'object' && typeof then === 'function') { + return function appyThen() { + then.apply(obj, arguments); + }; + } +} + +},{"./resolveThenable":57,"./states":58,"./tryCatch":59}],51:[function(require,module,exports){ +module.exports = exports = require('./promise'); + +exports.resolve = require('./resolve'); +exports.reject = require('./reject'); +exports.all = require('./all'); +exports.race = require('./race'); + +},{"./all":49,"./promise":52,"./race":54,"./reject":55,"./resolve":56}],52:[function(require,module,exports){ +'use strict'; + +var unwrap = require('./unwrap'); +var INTERNAL = require('./INTERNAL'); +var resolveThenable = require('./resolveThenable'); +var states = require('./states'); +var QueueItem = require('./queueItem'); + +module.exports = Promise; +function Promise(resolver) { + if (!(this instanceof Promise)) { + return new Promise(resolver); + } + if (typeof resolver !== 'function') { + throw new TypeError('resolver must be a function'); + } + this.state = states.PENDING; + this.queue = []; + this.outcome = void 0; + if (resolver !== INTERNAL) { + resolveThenable.safely(this, resolver); + } +} + +Promise.prototype['catch'] = function (onRejected) { + return this.then(null, onRejected); +}; +Promise.prototype.then = function (onFulfilled, onRejected) { + if (typeof onFulfilled !== 'function' && this.state === states.FULFILLED || + typeof onRejected !== 'function' && this.state === states.REJECTED) { + return this; + } + var promise = new Promise(INTERNAL); + if (this.state !== states.PENDING) { + var resolver = this.state === states.FULFILLED ? onFulfilled : onRejected; + unwrap(promise, resolver, this.outcome); + } else { + this.queue.push(new QueueItem(promise, onFulfilled, onRejected)); + } + + return promise; +}; + +},{"./INTERNAL":48,"./queueItem":53,"./resolveThenable":57,"./states":58,"./unwrap":60}],53:[function(require,module,exports){ +'use strict'; +var handlers = require('./handlers'); +var unwrap = require('./unwrap'); + +module.exports = QueueItem; +function QueueItem(promise, onFulfilled, onRejected) { + this.promise = promise; + if (typeof onFulfilled === 'function') { + this.onFulfilled = onFulfilled; + this.callFulfilled = this.otherCallFulfilled; + } + if (typeof onRejected === 'function') { + this.onRejected = onRejected; + this.callRejected = this.otherCallRejected; + } +} +QueueItem.prototype.callFulfilled = function (value) { + handlers.resolve(this.promise, value); +}; +QueueItem.prototype.otherCallFulfilled = function (value) { + unwrap(this.promise, this.onFulfilled, value); +}; +QueueItem.prototype.callRejected = function (value) { + handlers.reject(this.promise, value); +}; +QueueItem.prototype.otherCallRejected = function (value) { + unwrap(this.promise, this.onRejected, value); +}; + +},{"./handlers":50,"./unwrap":60}],54:[function(require,module,exports){ +'use strict'; +var Promise = require('./promise'); +var reject = require('./reject'); +var resolve = require('./resolve'); +var INTERNAL = require('./INTERNAL'); +var handlers = require('./handlers'); +module.exports = race; +function race(iterable) { + if (Object.prototype.toString.call(iterable) !== '[object Array]') { + return reject(new TypeError('must be an array')); + } + + var len = iterable.length; + var called = false; + if (!len) { + return resolve([]); + } + + var i = -1; + var promise = new Promise(INTERNAL); + + while (++i < len) { + resolver(iterable[i]); + } + return promise; + function resolver(value) { + resolve(value).then(function (response) { + if (!called) { + called = true; + handlers.resolve(promise, response); + } + }, function (error) { + if (!called) { + called = true; + handlers.reject(promise, error); + } + }); + } +} + +},{"./INTERNAL":48,"./handlers":50,"./promise":52,"./reject":55,"./resolve":56}],55:[function(require,module,exports){ +'use strict'; + +var Promise = require('./promise'); +var INTERNAL = require('./INTERNAL'); +var handlers = require('./handlers'); +module.exports = reject; + +function reject(reason) { + var promise = new Promise(INTERNAL); + return handlers.reject(promise, reason); +} +},{"./INTERNAL":48,"./handlers":50,"./promise":52}],56:[function(require,module,exports){ +'use strict'; + +var Promise = require('./promise'); +var INTERNAL = require('./INTERNAL'); +var handlers = require('./handlers'); +module.exports = resolve; + +var FALSE = handlers.resolve(new Promise(INTERNAL), false); +var NULL = handlers.resolve(new Promise(INTERNAL), null); +var UNDEFINED = handlers.resolve(new Promise(INTERNAL), void 0); +var ZERO = handlers.resolve(new Promise(INTERNAL), 0); +var EMPTYSTRING = handlers.resolve(new Promise(INTERNAL), ''); + +function resolve(value) { + if (value) { + if (value instanceof Promise) { + return value; + } + return handlers.resolve(new Promise(INTERNAL), value); + } + var valueType = typeof value; + switch (valueType) { + case 'boolean': + return FALSE; + case 'undefined': + return UNDEFINED; + case 'object': + return NULL; + case 'number': + return ZERO; + case 'string': + return EMPTYSTRING; + } +} +},{"./INTERNAL":48,"./handlers":50,"./promise":52}],57:[function(require,module,exports){ +'use strict'; +var handlers = require('./handlers'); +var tryCatch = require('./tryCatch'); +function safelyResolveThenable(self, thenable) { + // Either fulfill, reject or reject with error + var called = false; + function onError(value) { + if (called) { + return; + } + called = true; + handlers.reject(self, value); + } + + function onSuccess(value) { + if (called) { + return; + } + called = true; + handlers.resolve(self, value); + } + + function tryToUnwrap() { + thenable(onSuccess, onError); + } + + var result = tryCatch(tryToUnwrap); + if (result.status === 'error') { + onError(result.value); + } +} +exports.safely = safelyResolveThenable; +},{"./handlers":50,"./tryCatch":59}],58:[function(require,module,exports){ +// Lazy man's symbols for states + +exports.REJECTED = ['REJECTED']; +exports.FULFILLED = ['FULFILLED']; +exports.PENDING = ['PENDING']; + +},{}],59:[function(require,module,exports){ +'use strict'; + +module.exports = tryCatch; + +function tryCatch(func, value) { + var out = {}; + try { + out.value = func(value); + out.status = 'success'; + } catch (e) { + out.status = 'error'; + out.value = e; + } + return out; +} +},{}],60:[function(require,module,exports){ +'use strict'; + +var immediate = require('immediate'); +var handlers = require('./handlers'); +module.exports = unwrap; + +function unwrap(promise, func, value) { + immediate(function () { + var returnValue; + try { + returnValue = func(value); + } catch (e) { + return handlers.reject(promise, e); + } + if (returnValue === promise) { + handlers.reject(promise, new TypeError('Cannot resolve promise with itself')); + } else { + handlers.resolve(promise, returnValue); + } + }); +} +},{"./handlers":50,"immediate":61}],61:[function(require,module,exports){ +(function (global){ +'use strict'; +var Mutation = global.MutationObserver || global.WebKitMutationObserver; + +var scheduleDrain; + +{ + if (Mutation) { + var called = 0; + var observer = new Mutation(nextTick); + var element = global.document.createTextNode(''); + observer.observe(element, { + characterData: true + }); + scheduleDrain = function () { + element.data = (called = ++called % 2); + }; + } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') { + var channel = new global.MessageChannel(); + channel.port1.onmessage = nextTick; + scheduleDrain = function () { + channel.port2.postMessage(0); + }; + } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) { + scheduleDrain = function () { + + // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted + // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called. + var scriptEl = global.document.createElement('script'); + scriptEl.onreadystatechange = function () { + nextTick(); + + scriptEl.onreadystatechange = null; + scriptEl.parentNode.removeChild(scriptEl); + scriptEl = null; + }; + global.document.documentElement.appendChild(scriptEl); + }; + } else { + scheduleDrain = function () { + setTimeout(nextTick, 0); + }; + } +} + +var draining; +var queue = []; +//named nextTick for less confusing stack traces +function nextTick() { + draining = true; + var i, oldQueue; + var len = queue.length; + while (len) { + oldQueue = queue; + queue = []; + i = -1; + while (++i < len) { + oldQueue[i](); + } + len = queue.length; + } + draining = false; +} + +module.exports = immediate; +function immediate(task) { + if (queue.push(task) === 1 && !draining) { + scheduleDrain(); + } +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],62:[function(require,module,exports){ +;(function () { // closure for web browsers + +if (typeof module === 'object' && module.exports) { + module.exports = LRUCache +} else { + // just set the global for non-node platforms. + this.LRUCache = LRUCache +} + +function hOP (obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key) +} + +function naiveLength () { return 1 } + +function LRUCache (options) { + if (!(this instanceof LRUCache)) + return new LRUCache(options) + + if (typeof options === 'number') + options = { max: options } + + if (!options) + options = {} + + this._max = options.max + // Kind of weird to have a default max of Infinity, but oh well. + if (!this._max || !(typeof this._max === "number") || this._max <= 0 ) + this._max = Infinity + + this._lengthCalculator = options.length || naiveLength + if (typeof this._lengthCalculator !== "function") + this._lengthCalculator = naiveLength + + this._allowStale = options.stale || false + this._maxAge = options.maxAge || null + this._dispose = options.dispose + this.reset() +} + +// resize the cache when the max changes. +Object.defineProperty(LRUCache.prototype, "max", + { set : function (mL) { + if (!mL || !(typeof mL === "number") || mL <= 0 ) mL = Infinity + this._max = mL + if (this._length > this._max) trim(this) + } + , get : function () { return this._max } + , enumerable : true + }) + +// resize the cache when the lengthCalculator changes. +Object.defineProperty(LRUCache.prototype, "lengthCalculator", + { set : function (lC) { + if (typeof lC !== "function") { + this._lengthCalculator = naiveLength + this._length = this._itemCount + for (var key in this._cache) { + this._cache[key].length = 1 + } + } else { + this._lengthCalculator = lC + this._length = 0 + for (var key in this._cache) { + this._cache[key].length = this._lengthCalculator(this._cache[key].value) + this._length += this._cache[key].length + } + } + + if (this._length > this._max) trim(this) + } + , get : function () { return this._lengthCalculator } + , enumerable : true + }) + +Object.defineProperty(LRUCache.prototype, "length", + { get : function () { return this._length } + , enumerable : true + }) + + +Object.defineProperty(LRUCache.prototype, "itemCount", + { get : function () { return this._itemCount } + , enumerable : true + }) + +LRUCache.prototype.forEach = function (fn, thisp) { + thisp = thisp || this + var i = 0 + var itemCount = this._itemCount + + for (var k = this._mru - 1; k >= 0 && i < itemCount; k--) if (this._lruList[k]) { + i++ + var hit = this._lruList[k] + if (isStale(this, hit)) { + del(this, hit) + if (!this._allowStale) hit = undefined + } + if (hit) { + fn.call(thisp, hit.value, hit.key, this) + } + } +} + +LRUCache.prototype.keys = function () { + var keys = new Array(this._itemCount) + var i = 0 + for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) { + var hit = this._lruList[k] + keys[i++] = hit.key + } + return keys +} + +LRUCache.prototype.values = function () { + var values = new Array(this._itemCount) + var i = 0 + for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) { + var hit = this._lruList[k] + values[i++] = hit.value + } + return values +} + +LRUCache.prototype.reset = function () { + if (this._dispose && this._cache) { + for (var k in this._cache) { + this._dispose(k, this._cache[k].value) + } + } + + this._cache = Object.create(null) // hash of items by key + this._lruList = Object.create(null) // list of items in order of use recency + this._mru = 0 // most recently used + this._lru = 0 // least recently used + this._length = 0 // number of items in the list + this._itemCount = 0 +} + +// Provided for debugging/dev purposes only. No promises whatsoever that +// this API stays stable. +LRUCache.prototype.dump = function () { + return this._cache +} + +LRUCache.prototype.dumpLru = function () { + return this._lruList +} + +LRUCache.prototype.set = function (key, value, maxAge) { + maxAge = maxAge || this._maxAge + var now = maxAge ? Date.now() : 0 + + if (hOP(this._cache, key)) { + // dispose of the old one before overwriting + if (this._dispose) + this._dispose(key, this._cache[key].value) + + this._cache[key].now = now + this._cache[key].maxAge = maxAge + this._cache[key].value = value + this.get(key) + return true + } + + var len = this._lengthCalculator(value) + var hit = new Entry(key, value, this._mru++, len, now, maxAge) + + // oversized objects fall out of cache automatically. + if (hit.length > this._max) { + if (this._dispose) this._dispose(key, value) + return false + } + + this._length += hit.length + this._lruList[hit.lu] = this._cache[key] = hit + this._itemCount ++ + + if (this._length > this._max) + trim(this) + + return true +} + +LRUCache.prototype.has = function (key) { + if (!hOP(this._cache, key)) return false + var hit = this._cache[key] + if (isStale(this, hit)) { + return false + } + return true +} + +LRUCache.prototype.get = function (key) { + return get(this, key, true) +} + +LRUCache.prototype.peek = function (key) { + return get(this, key, false) +} + +LRUCache.prototype.pop = function () { + var hit = this._lruList[this._lru] + del(this, hit) + return hit || null +} + +LRUCache.prototype.del = function (key) { + del(this, this._cache[key]) +} + +function get (self, key, doUse) { + var hit = self._cache[key] + if (hit) { + if (isStale(self, hit)) { + del(self, hit) + if (!self._allowStale) hit = undefined + } else { + if (doUse) use(self, hit) + } + if (hit) hit = hit.value + } + return hit +} + +function isStale(self, hit) { + if (!hit || (!hit.maxAge && !self._maxAge)) return false + var stale = false; + var diff = Date.now() - hit.now + if (hit.maxAge) { + stale = diff > hit.maxAge + } else { + stale = self._maxAge && (diff > self._maxAge) + } + return stale; +} + +function use (self, hit) { + shiftLU(self, hit) + hit.lu = self._mru ++ + self._lruList[hit.lu] = hit +} + +function trim (self) { + while (self._lru < self._mru && self._length > self._max) + del(self, self._lruList[self._lru]) +} + +function shiftLU (self, hit) { + delete self._lruList[ hit.lu ] + while (self._lru < self._mru && !self._lruList[self._lru]) self._lru ++ +} + +function del (self, hit) { + if (hit) { + if (self._dispose) self._dispose(hit.key, hit.value) + self._length -= hit.length + self._itemCount -- + delete self._cache[ hit.key ] + shiftLU(self, hit) + } +} + +// classy, since V8 prefers predictable objects. +function Entry (key, value, lu, length, now, maxAge) { + this.key = key + this.value = value + this.lu = lu + this.length = length + this.now = now + if (maxAge) this.maxAge = maxAge +} + +})() + +},{}],63:[function(require,module,exports){ +function dbfHeader(buffer){ + var data = new DataView(buffer); + var out = {}; + out.lastUpdated = new Date(data.getUint8(1,true)+1900,data.getUint8(2,true),data.getUint8(3,true)); + out.records = data.getUint32(4,true); + out.headerLen = data.getUint16(8,true); + out.recLen = data.getUint16(10,true); + return out; +} + +function dbfRowHeader(buffer){ + var data = new DataView(buffer); + var out = []; + var offset = 32; + while(true){ + out.push({ + name : String.fromCharCode.apply(this,(new Uint8Array(buffer,offset,10))).replace(/\0|\s+$/g,''), + dataType : String.fromCharCode(data.getUint8(offset+11)), + len : data.getUint8(offset+16), + decimal : data.getUint8(offset+17) + }); + if(data.getUint8(offset+32)===13){ + break; + }else{ + offset+=32; + } + } + return out; +} +function rowFuncs(buffer,offset,len,type){ + var data = (new Uint8Array(buffer,offset,len)); + var textData = String.fromCharCode.apply(this,data).replace(/\0|\s+$/g,''); + switch(type){ + case 'N': + case 'F': + case 'O': + return parseFloat(textData,10); + case 'D': + return new Date(textData.slice(0,4), parseInt(textData.slice(4,6),10)-1, textData.slice(6,8)); + case 'L': + return textData.toLowerCase() === 'y' || textData.toLowerCase() === 't'; + default: + return textData; + } +} +function parseRow(buffer,offset,rowHeaders){ + var out={}; + var i = 0; + var len = rowHeaders.length; + var field; + var header; + while(i<len){ + header = rowHeaders[i]; + field = rowFuncs(buffer,offset,header.len,header.dataType); + offset += header.len; + if(typeof field !== 'undefined'){ + out[header.name]=field; + } + i++; + } + return out; +} +module.exports = function(buffer){ + var rowHeaders = dbfRowHeader(buffer); + var header = dbfHeader(buffer); + var offset = ((rowHeaders.length+1)<<5)+2; + var recLen = header.recLen; + var records = header.records; + var out = []; + while(records){ + out.push(parseRow(buffer,offset,rowHeaders)); + offset += recLen; + records--; + } + return out; +}; + +},{}],64:[function(require,module,exports){ +var mgrs = require('mgrs'); + +function Point(x, y, z) { + if (!(this instanceof Point)) { + return new Point(x, y, z); + } + if (Array.isArray(x)) { + this.x = x[0]; + this.y = x[1]; + this.z = x[2] || 0.0; + }else if(typeof x === 'object'){ + this.x = x.x; + this.y = x.y; + this.z = x.z || 0.0; + } else if (typeof x === 'string' && typeof y === 'undefined') { + var coords = x.split(','); + this.x = parseFloat(coords[0], 10); + this.y = parseFloat(coords[1], 10); + this.z = parseFloat(coords[2], 10) || 0.0; + } + else { + this.x = x; + this.y = y; + this.z = z || 0.0; + } + console.warn('proj4.Point will be removed in version 3, use proj4.toPoint'); +} + +Point.fromMGRS = function(mgrsStr) { + return new Point(mgrs.toPoint(mgrsStr)); +}; +Point.prototype.toMGRS = function(accuracy) { + return mgrs.forward([this.x, this.y], accuracy); +}; +module.exports = Point; +},{"mgrs":131}],65:[function(require,module,exports){ +var parseCode = require("./parseCode"); +var extend = require('./extend'); +var projections = require('./projections'); +var deriveConstants = require('./deriveConstants'); + +function Projection(srsCode,callback) { + if (!(this instanceof Projection)) { + return new Projection(srsCode); + } + callback = callback || function(error){ + if(error){ + throw error; + } + }; + var json = parseCode(srsCode); + if(typeof json !== 'object'){ + callback(srsCode); + return; + } + var modifiedJSON = deriveConstants(json); + var ourProj = Projection.projections.get(modifiedJSON.projName); + if(ourProj){ + extend(this, modifiedJSON); + extend(this, ourProj); + this.init(); + callback(null, this); + }else{ + callback(srsCode); + } +} +Projection.projections = projections; +Projection.projections.start(); +module.exports = Projection; + +},{"./deriveConstants":96,"./extend":97,"./parseCode":101,"./projections":103}],66:[function(require,module,exports){ +module.exports = function(crs, denorm, point) { + var xin = point.x, + yin = point.y, + zin = point.z || 0.0; + var v, t, i; + for (i = 0; i < 3; i++) { + if (denorm && i === 2 && point.z === undefined) { + continue; + } + if (i === 0) { + v = xin; + t = 'x'; + } + else if (i === 1) { + v = yin; + t = 'y'; + } + else { + v = zin; + t = 'z'; + } + switch (crs.axis[i]) { + case 'e': + point[t] = v; + break; + case 'w': + point[t] = -v; + break; + case 'n': + point[t] = v; + break; + case 's': + point[t] = -v; + break; + case 'u': + if (point[t] !== undefined) { + point.z = v; + } + break; + case 'd': + if (point[t] !== undefined) { + point.z = -v; + } + break; + default: + //console.log("ERROR: unknow axis ("+crs.axis[i]+") - check definition of "+crs.projName); + return null; + } + } + return point; +}; + +},{}],67:[function(require,module,exports){ +var HALF_PI = Math.PI/2; +var sign = require('./sign'); + +module.exports = function(x) { + return (Math.abs(x) < HALF_PI) ? x : (x - (sign(x) * Math.PI)); +}; +},{"./sign":84}],68:[function(require,module,exports){ +var TWO_PI = Math.PI * 2; +// SPI is slightly greater than Math.PI, so values that exceed the -180..180 +// degree range by a tiny amount don't get wrapped. This prevents points that +// have drifted from their original location along the 180th meridian (due to +// floating point error) from changing their sign. +var SPI = 3.14159265359; +var sign = require('./sign'); + +module.exports = function(x) { + return (Math.abs(x) <= SPI) ? x : (x - (sign(x) * TWO_PI)); +}; +},{"./sign":84}],69:[function(require,module,exports){ +module.exports = function(x) { + if (Math.abs(x) > 1) { + x = (x > 1) ? 1 : -1; + } + return Math.asin(x); +}; +},{}],70:[function(require,module,exports){ +module.exports = function(x) { + return (1 - 0.25 * x * (1 + x / 16 * (3 + 1.25 * x))); +}; +},{}],71:[function(require,module,exports){ +module.exports = function(x) { + return (0.375 * x * (1 + 0.25 * x * (1 + 0.46875 * x))); +}; +},{}],72:[function(require,module,exports){ +module.exports = function(x) { + return (0.05859375 * x * x * (1 + 0.75 * x)); +}; +},{}],73:[function(require,module,exports){ +module.exports = function(x) { + return (x * x * x * (35 / 3072)); +}; +},{}],74:[function(require,module,exports){ +module.exports = function(a, e, sinphi) { + var temp = e * sinphi; + return a / Math.sqrt(1 - temp * temp); +}; +},{}],75:[function(require,module,exports){ +module.exports = function(ml, e0, e1, e2, e3) { + var phi; + var dphi; + + phi = ml / e0; + for (var i = 0; i < 15; i++) { + dphi = (ml - (e0 * phi - e1 * Math.sin(2 * phi) + e2 * Math.sin(4 * phi) - e3 * Math.sin(6 * phi))) / (e0 - 2 * e1 * Math.cos(2 * phi) + 4 * e2 * Math.cos(4 * phi) - 6 * e3 * Math.cos(6 * phi)); + phi += dphi; + if (Math.abs(dphi) <= 0.0000000001) { + return phi; + } + } + + //..reportError("IMLFN-CONV:Latitude failed to converge after 15 iterations"); + return NaN; +}; +},{}],76:[function(require,module,exports){ +var HALF_PI = Math.PI/2; + +module.exports = function(eccent, q) { + var temp = 1 - (1 - eccent * eccent) / (2 * eccent) * Math.log((1 - eccent) / (1 + eccent)); + if (Math.abs(Math.abs(q) - temp) < 1.0E-6) { + if (q < 0) { + return (-1 * HALF_PI); + } + else { + return HALF_PI; + } + } + //var phi = 0.5* q/(1-eccent*eccent); + var phi = Math.asin(0.5 * q); + var dphi; + var sin_phi; + var cos_phi; + var con; + for (var i = 0; i < 30; i++) { + sin_phi = Math.sin(phi); + cos_phi = Math.cos(phi); + con = eccent * sin_phi; + dphi = Math.pow(1 - con * con, 2) / (2 * cos_phi) * (q / (1 - eccent * eccent) - sin_phi / (1 - con * con) + 0.5 / eccent * Math.log((1 - con) / (1 + con))); + phi += dphi; + if (Math.abs(dphi) <= 0.0000000001) { + return phi; + } + } + + //console.log("IQSFN-CONV:Latitude failed to converge after 30 iterations"); + return NaN; +}; +},{}],77:[function(require,module,exports){ +module.exports = function(e0, e1, e2, e3, phi) { + return (e0 * phi - e1 * Math.sin(2 * phi) + e2 * Math.sin(4 * phi) - e3 * Math.sin(6 * phi)); +}; +},{}],78:[function(require,module,exports){ +module.exports = function(eccent, sinphi, cosphi) { + var con = eccent * sinphi; + return cosphi / (Math.sqrt(1 - con * con)); +}; +},{}],79:[function(require,module,exports){ +var HALF_PI = Math.PI/2; +module.exports = function(eccent, ts) { + var eccnth = 0.5 * eccent; + var con, dphi; + var phi = HALF_PI - 2 * Math.atan(ts); + for (var i = 0; i <= 15; i++) { + con = eccent * Math.sin(phi); + dphi = HALF_PI - 2 * Math.atan(ts * (Math.pow(((1 - con) / (1 + con)), eccnth))) - phi; + phi += dphi; + if (Math.abs(dphi) <= 0.0000000001) { + return phi; + } + } + //console.log("phi2z has NoConvergence"); + return -9999; +}; +},{}],80:[function(require,module,exports){ +var C00 = 1; +var C02 = 0.25; +var C04 = 0.046875; +var C06 = 0.01953125; +var C08 = 0.01068115234375; +var C22 = 0.75; +var C44 = 0.46875; +var C46 = 0.01302083333333333333; +var C48 = 0.00712076822916666666; +var C66 = 0.36458333333333333333; +var C68 = 0.00569661458333333333; +var C88 = 0.3076171875; + +module.exports = function(es) { + var en = []; + en[0] = C00 - es * (C02 + es * (C04 + es * (C06 + es * C08))); + en[1] = es * (C22 - es * (C04 + es * (C06 + es * C08))); + var t = es * es; + en[2] = t * (C44 - es * (C46 + es * C48)); + t *= es; + en[3] = t * (C66 - es * C68); + en[4] = t * es * C88; + return en; +}; +},{}],81:[function(require,module,exports){ +var pj_mlfn = require("./pj_mlfn"); +var EPSLN = 1.0e-10; +var MAX_ITER = 20; +module.exports = function(arg, es, en) { + var k = 1 / (1 - es); + var phi = arg; + for (var i = MAX_ITER; i; --i) { /* rarely goes over 2 iterations */ + var s = Math.sin(phi); + var t = 1 - es * s * s; + //t = this.pj_mlfn(phi, s, Math.cos(phi), en) - arg; + //phi -= t * (t * Math.sqrt(t)) * k; + t = (pj_mlfn(phi, s, Math.cos(phi), en) - arg) * (t * Math.sqrt(t)) * k; + phi -= t; + if (Math.abs(t) < EPSLN) { + return phi; + } + } + //..reportError("cass:pj_inv_mlfn: Convergence error"); + return phi; +}; +},{"./pj_mlfn":82}],82:[function(require,module,exports){ +module.exports = function(phi, sphi, cphi, en) { + cphi *= sphi; + sphi *= sphi; + return (en[0] * phi - cphi * (en[1] + sphi * (en[2] + sphi * (en[3] + sphi * en[4])))); +}; +},{}],83:[function(require,module,exports){ +module.exports = function(eccent, sinphi) { + var con; + if (eccent > 1.0e-7) { + con = eccent * sinphi; + return ((1 - eccent * eccent) * (sinphi / (1 - con * con) - (0.5 / eccent) * Math.log((1 - con) / (1 + con)))); + } + else { + return (2 * sinphi); + } +}; +},{}],84:[function(require,module,exports){ +module.exports = function(x) { + return x<0 ? -1 : 1; +}; +},{}],85:[function(require,module,exports){ +module.exports = function(esinp, exp) { + return (Math.pow((1 - esinp) / (1 + esinp), exp)); +}; +},{}],86:[function(require,module,exports){ +module.exports = function (array){ + var out = { + x: array[0], + y: array[1] + }; + if (array.length>2) { + out.z = array[2]; + } + if (array.length>3) { + out.m = array[3]; + } + return out; +}; +},{}],87:[function(require,module,exports){ +var HALF_PI = Math.PI/2; + +module.exports = function(eccent, phi, sinphi) { + var con = eccent * sinphi; + var com = 0.5 * eccent; + con = Math.pow(((1 - con) / (1 + con)), com); + return (Math.tan(0.5 * (HALF_PI - phi)) / con); +}; +},{}],88:[function(require,module,exports){ +exports.wgs84 = { + towgs84: "0,0,0", + ellipse: "WGS84", + datumName: "WGS84" +}; +exports.ch1903 = { + towgs84: "674.374,15.056,405.346", + ellipse: "bessel", + datumName: "swiss" +}; +exports.ggrs87 = { + towgs84: "-199.87,74.79,246.62", + ellipse: "GRS80", + datumName: "Greek_Geodetic_Reference_System_1987" +}; +exports.nad83 = { + towgs84: "0,0,0", + ellipse: "GRS80", + datumName: "North_American_Datum_1983" +}; +exports.nad27 = { + nadgrids: "@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat", + ellipse: "clrk66", + datumName: "North_American_Datum_1927" +}; +exports.potsdam = { + towgs84: "606.0,23.0,413.0", + ellipse: "bessel", + datumName: "Potsdam Rauenberg 1950 DHDN" +}; +exports.carthage = { + towgs84: "-263.0,6.0,431.0", + ellipse: "clark80", + datumName: "Carthage 1934 Tunisia" +}; +exports.hermannskogel = { + towgs84: "653.0,-212.0,449.0", + ellipse: "bessel", + datumName: "Hermannskogel" +}; +exports.ire65 = { + towgs84: "482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15", + ellipse: "mod_airy", + datumName: "Ireland 1965" +}; +exports.rassadiran = { + towgs84: "-133.63,-157.5,-158.62", + ellipse: "intl", + datumName: "Rassadiran" +}; +exports.nzgd49 = { + towgs84: "59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993", + ellipse: "intl", + datumName: "New Zealand Geodetic Datum 1949" +}; +exports.osgb36 = { + towgs84: "446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894", + ellipse: "airy", + datumName: "Airy 1830" +}; +exports.s_jtsk = { + towgs84: "589,76,480", + ellipse: 'bessel', + datumName: 'S-JTSK (Ferro)' +}; +exports.beduaram = { + towgs84: '-106,-87,188', + ellipse: 'clrk80', + datumName: 'Beduaram' +}; +exports.gunung_segara = { + towgs84: '-403,684,41', + ellipse: 'bessel', + datumName: 'Gunung Segara Jakarta' +}; +exports.rnb72 = { + towgs84: "106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1", + ellipse: "intl", + datumName: "Reseau National Belge 1972" +}; +},{}],89:[function(require,module,exports){ +exports.MERIT = { + a: 6378137.0, + rf: 298.257, + ellipseName: "MERIT 1983" +}; +exports.SGS85 = { + a: 6378136.0, + rf: 298.257, + ellipseName: "Soviet Geodetic System 85" +}; +exports.GRS80 = { + a: 6378137.0, + rf: 298.257222101, + ellipseName: "GRS 1980(IUGG, 1980)" +}; +exports.IAU76 = { + a: 6378140.0, + rf: 298.257, + ellipseName: "IAU 1976" +}; +exports.airy = { + a: 6377563.396, + b: 6356256.910, + ellipseName: "Airy 1830" +}; +exports.APL4 = { + a: 6378137, + rf: 298.25, + ellipseName: "Appl. Physics. 1965" +}; +exports.NWL9D = { + a: 6378145.0, + rf: 298.25, + ellipseName: "Naval Weapons Lab., 1965" +}; +exports.mod_airy = { + a: 6377340.189, + b: 6356034.446, + ellipseName: "Modified Airy" +}; +exports.andrae = { + a: 6377104.43, + rf: 300.0, + ellipseName: "Andrae 1876 (Den., Iclnd.)" +}; +exports.aust_SA = { + a: 6378160.0, + rf: 298.25, + ellipseName: "Australian Natl & S. Amer. 1969" +}; +exports.GRS67 = { + a: 6378160.0, + rf: 298.2471674270, + ellipseName: "GRS 67(IUGG 1967)" +}; +exports.bessel = { + a: 6377397.155, + rf: 299.1528128, + ellipseName: "Bessel 1841" +}; +exports.bess_nam = { + a: 6377483.865, + rf: 299.1528128, + ellipseName: "Bessel 1841 (Namibia)" +}; +exports.clrk66 = { + a: 6378206.4, + b: 6356583.8, + ellipseName: "Clarke 1866" +}; +exports.clrk80 = { + a: 6378249.145, + rf: 293.4663, + ellipseName: "Clarke 1880 mod." +}; +exports.clrk58 = { + a: 6378293.645208759, + rf: 294.2606763692654, + ellipseName: "Clarke 1858" +}; +exports.CPM = { + a: 6375738.7, + rf: 334.29, + ellipseName: "Comm. des Poids et Mesures 1799" +}; +exports.delmbr = { + a: 6376428.0, + rf: 311.5, + ellipseName: "Delambre 1810 (Belgium)" +}; +exports.engelis = { + a: 6378136.05, + rf: 298.2566, + ellipseName: "Engelis 1985" +}; +exports.evrst30 = { + a: 6377276.345, + rf: 300.8017, + ellipseName: "Everest 1830" +}; +exports.evrst48 = { + a: 6377304.063, + rf: 300.8017, + ellipseName: "Everest 1948" +}; +exports.evrst56 = { + a: 6377301.243, + rf: 300.8017, + ellipseName: "Everest 1956" +}; +exports.evrst69 = { + a: 6377295.664, + rf: 300.8017, + ellipseName: "Everest 1969" +}; +exports.evrstSS = { + a: 6377298.556, + rf: 300.8017, + ellipseName: "Everest (Sabah & Sarawak)" +}; +exports.fschr60 = { + a: 6378166.0, + rf: 298.3, + ellipseName: "Fischer (Mercury Datum) 1960" +}; +exports.fschr60m = { + a: 6378155.0, + rf: 298.3, + ellipseName: "Fischer 1960" +}; +exports.fschr68 = { + a: 6378150.0, + rf: 298.3, + ellipseName: "Fischer 1968" +}; +exports.helmert = { + a: 6378200.0, + rf: 298.3, + ellipseName: "Helmert 1906" +}; +exports.hough = { + a: 6378270.0, + rf: 297.0, + ellipseName: "Hough" +}; +exports.intl = { + a: 6378388.0, + rf: 297.0, + ellipseName: "International 1909 (Hayford)" +}; +exports.kaula = { + a: 6378163.0, + rf: 298.24, + ellipseName: "Kaula 1961" +}; +exports.lerch = { + a: 6378139.0, + rf: 298.257, + ellipseName: "Lerch 1979" +}; +exports.mprts = { + a: 6397300.0, + rf: 191.0, + ellipseName: "Maupertius 1738" +}; +exports.new_intl = { + a: 6378157.5, + b: 6356772.2, + ellipseName: "New International 1967" +}; +exports.plessis = { + a: 6376523.0, + rf: 6355863.0, + ellipseName: "Plessis 1817 (France)" +}; +exports.krass = { + a: 6378245.0, + rf: 298.3, + ellipseName: "Krassovsky, 1942" +}; +exports.SEasia = { + a: 6378155.0, + b: 6356773.3205, + ellipseName: "Southeast Asia" +}; +exports.walbeck = { + a: 6376896.0, + b: 6355834.8467, + ellipseName: "Walbeck" +}; +exports.WGS60 = { + a: 6378165.0, + rf: 298.3, + ellipseName: "WGS 60" +}; +exports.WGS66 = { + a: 6378145.0, + rf: 298.25, + ellipseName: "WGS 66" +}; +exports.WGS7 = { + a: 6378135.0, + rf: 298.26, + ellipseName: "WGS 72" +}; +exports.WGS84 = { + a: 6378137.0, + rf: 298.257223563, + ellipseName: "WGS 84" +}; +exports.sphere = { + a: 6370997.0, + b: 6370997.0, + ellipseName: "Normal Sphere (r=6370997)" +}; +},{}],90:[function(require,module,exports){ +exports.greenwich = 0.0; //"0dE", +exports.lisbon = -9.131906111111; //"9d07'54.862\"W", +exports.paris = 2.337229166667; //"2d20'14.025\"E", +exports.bogota = -74.080916666667; //"74d04'51.3\"W", +exports.madrid = -3.687938888889; //"3d41'16.58\"W", +exports.rome = 12.452333333333; //"12d27'8.4\"E", +exports.bern = 7.439583333333; //"7d26'22.5\"E", +exports.jakarta = 106.807719444444; //"106d48'27.79\"E", +exports.ferro = -17.666666666667; //"17d40'W", +exports.brussels = 4.367975; //"4d22'4.71\"E", +exports.stockholm = 18.058277777778; //"18d3'29.8\"E", +exports.athens = 23.7163375; //"23d42'58.815\"E", +exports.oslo = 10.722916666667; //"10d43'22.5\"E" +},{}],91:[function(require,module,exports){ +exports.ft = {to_meter: 0.3048}; +exports['us-ft'] = {to_meter: 1200 / 3937}; + +},{}],92:[function(require,module,exports){ +var proj = require('./Proj'); +var transform = require('./transform'); +var wgs84 = proj('WGS84'); + +function transformer(from, to, coords) { + var transformedArray; + if (Array.isArray(coords)) { + transformedArray = transform(from, to, coords); + if (coords.length === 3) { + return [transformedArray.x, transformedArray.y, transformedArray.z]; + } + else { + return [transformedArray.x, transformedArray.y]; + } + } + else { + return transform(from, to, coords); + } +} + +function checkProj(item) { + if (item instanceof proj) { + return item; + } + if (item.oProj) { + return item.oProj; + } + return proj(item); +} +function proj4(fromProj, toProj, coord) { + fromProj = checkProj(fromProj); + var single = false; + var obj; + if (typeof toProj === 'undefined') { + toProj = fromProj; + fromProj = wgs84; + single = true; + } + else if (typeof toProj.x !== 'undefined' || Array.isArray(toProj)) { + coord = toProj; + toProj = fromProj; + fromProj = wgs84; + single = true; + } + toProj = checkProj(toProj); + if (coord) { + return transformer(fromProj, toProj, coord); + } + else { + obj = { + forward: function(coords) { + return transformer(fromProj, toProj, coords); + }, + inverse: function(coords) { + return transformer(toProj, fromProj, coords); + } + }; + if (single) { + obj.oProj = toProj; + } + return obj; + } +} +module.exports = proj4; +},{"./Proj":65,"./transform":129}],93:[function(require,module,exports){ +var HALF_PI = Math.PI/2; +var PJD_3PARAM = 1; +var PJD_7PARAM = 2; +var PJD_GRIDSHIFT = 3; +var PJD_WGS84 = 4; // WGS84 or equivalent +var PJD_NODATUM = 5; // WGS84 or equivalent +var SEC_TO_RAD = 4.84813681109535993589914102357e-6; +var AD_C = 1.0026000; +var COS_67P5 = 0.38268343236508977; +var datum = function(proj) { + if (!(this instanceof datum)) { + return new datum(proj); + } + this.datum_type = PJD_WGS84; //default setting + if (!proj) { + return; + } + if (proj.datumCode && proj.datumCode === 'none') { + this.datum_type = PJD_NODATUM; + } + if (proj.datum_params) { + for (var i = 0; i < proj.datum_params.length; i++) { + proj.datum_params[i] = parseFloat(proj.datum_params[i]); + } + if (proj.datum_params[0] !== 0 || proj.datum_params[1] !== 0 || proj.datum_params[2] !== 0) { + this.datum_type = PJD_3PARAM; + } + if (proj.datum_params.length > 3) { + if (proj.datum_params[3] !== 0 || proj.datum_params[4] !== 0 || proj.datum_params[5] !== 0 || proj.datum_params[6] !== 0) { + this.datum_type = PJD_7PARAM; + proj.datum_params[3] *= SEC_TO_RAD; + proj.datum_params[4] *= SEC_TO_RAD; + proj.datum_params[5] *= SEC_TO_RAD; + proj.datum_params[6] = (proj.datum_params[6] / 1000000.0) + 1.0; + } + } + } + // DGR 2011-03-21 : nadgrids support + this.datum_type = proj.grids ? PJD_GRIDSHIFT : this.datum_type; + + this.a = proj.a; //datum object also uses these values + this.b = proj.b; + this.es = proj.es; + this.ep2 = proj.ep2; + this.datum_params = proj.datum_params; + if (this.datum_type === PJD_GRIDSHIFT) { + this.grids = proj.grids; + } +}; +datum.prototype = { + + + /****************************************************************/ + // cs_compare_datums() + // Returns TRUE if the two datums match, otherwise FALSE. + compare_datums: function(dest) { + if (this.datum_type !== dest.datum_type) { + return false; // false, datums are not equal + } + else if (this.a !== dest.a || Math.abs(this.es - dest.es) > 0.000000000050) { + // the tolerence for es is to ensure that GRS80 and WGS84 + // are considered identical + return false; + } + else if (this.datum_type === PJD_3PARAM) { + return (this.datum_params[0] === dest.datum_params[0] && this.datum_params[1] === dest.datum_params[1] && this.datum_params[2] === dest.datum_params[2]); + } + else if (this.datum_type === PJD_7PARAM) { + return (this.datum_params[0] === dest.datum_params[0] && this.datum_params[1] === dest.datum_params[1] && this.datum_params[2] === dest.datum_params[2] && this.datum_params[3] === dest.datum_params[3] && this.datum_params[4] === dest.datum_params[4] && this.datum_params[5] === dest.datum_params[5] && this.datum_params[6] === dest.datum_params[6]); + } + else if (this.datum_type === PJD_GRIDSHIFT || dest.datum_type === PJD_GRIDSHIFT) { + //alert("ERROR: Grid shift transformations are not implemented."); + //return false + //DGR 2012-07-29 lazy ... + return this.nadgrids === dest.nadgrids; + } + else { + return true; // datums are equal + } + }, // cs_compare_datums() + + /* + * The function Convert_Geodetic_To_Geocentric converts geodetic coordinates + * (latitude, longitude, and height) to geocentric coordinates (X, Y, Z), + * according to the current ellipsoid parameters. + * + * Latitude : Geodetic latitude in radians (input) + * Longitude : Geodetic longitude in radians (input) + * Height : Geodetic height, in meters (input) + * X : Calculated Geocentric X coordinate, in meters (output) + * Y : Calculated Geocentric Y coordinate, in meters (output) + * Z : Calculated Geocentric Z coordinate, in meters (output) + * + */ + geodetic_to_geocentric: function(p) { + var Longitude = p.x; + var Latitude = p.y; + var Height = p.z ? p.z : 0; //Z value not always supplied + var X; // output + var Y; + var Z; + + var Error_Code = 0; // GEOCENT_NO_ERROR; + var Rn; /* Earth radius at location */ + var Sin_Lat; /* Math.sin(Latitude) */ + var Sin2_Lat; /* Square of Math.sin(Latitude) */ + var Cos_Lat; /* Math.cos(Latitude) */ + + /* + ** Don't blow up if Latitude is just a little out of the value + ** range as it may just be a rounding issue. Also removed longitude + ** test, it should be wrapped by Math.cos() and Math.sin(). NFW for PROJ.4, Sep/2001. + */ + if (Latitude < -HALF_PI && Latitude > -1.001 * HALF_PI) { + Latitude = -HALF_PI; + } + else if (Latitude > HALF_PI && Latitude < 1.001 * HALF_PI) { + Latitude = HALF_PI; + } + else if ((Latitude < -HALF_PI) || (Latitude > HALF_PI)) { + /* Latitude out of range */ + //..reportError('geocent:lat out of range:' + Latitude); + return null; + } + + if (Longitude > Math.PI) { + Longitude -= (2 * Math.PI); + } + Sin_Lat = Math.sin(Latitude); + Cos_Lat = Math.cos(Latitude); + Sin2_Lat = Sin_Lat * Sin_Lat; + Rn = this.a / (Math.sqrt(1.0e0 - this.es * Sin2_Lat)); + X = (Rn + Height) * Cos_Lat * Math.cos(Longitude); + Y = (Rn + Height) * Cos_Lat * Math.sin(Longitude); + Z = ((Rn * (1 - this.es)) + Height) * Sin_Lat; + + p.x = X; + p.y = Y; + p.z = Z; + return Error_Code; + }, // cs_geodetic_to_geocentric() + + + geocentric_to_geodetic: function(p) { + /* local defintions and variables */ + /* end-criterium of loop, accuracy of sin(Latitude) */ + var genau = 1e-12; + var genau2 = (genau * genau); + var maxiter = 30; + + var P; /* distance between semi-minor axis and location */ + var RR; /* distance between center and location */ + var CT; /* sin of geocentric latitude */ + var ST; /* cos of geocentric latitude */ + var RX; + var RK; + var RN; /* Earth radius at location */ + var CPHI0; /* cos of start or old geodetic latitude in iterations */ + var SPHI0; /* sin of start or old geodetic latitude in iterations */ + var CPHI; /* cos of searched geodetic latitude */ + var SPHI; /* sin of searched geodetic latitude */ + var SDPHI; /* end-criterium: addition-theorem of sin(Latitude(iter)-Latitude(iter-1)) */ + var At_Pole; /* indicates location is in polar region */ + var iter; /* # of continous iteration, max. 30 is always enough (s.a.) */ + + var X = p.x; + var Y = p.y; + var Z = p.z ? p.z : 0.0; //Z value not always supplied + var Longitude; + var Latitude; + var Height; + + At_Pole = false; + P = Math.sqrt(X * X + Y * Y); + RR = Math.sqrt(X * X + Y * Y + Z * Z); + + /* special cases for latitude and longitude */ + if (P / this.a < genau) { + + /* special case, if P=0. (X=0., Y=0.) */ + At_Pole = true; + Longitude = 0.0; + + /* if (X,Y,Z)=(0.,0.,0.) then Height becomes semi-minor axis + * of ellipsoid (=center of mass), Latitude becomes PI/2 */ + if (RR / this.a < genau) { + Latitude = HALF_PI; + Height = -this.b; + return; + } + } + else { + /* ellipsoidal (geodetic) longitude + * interval: -PI < Longitude <= +PI */ + Longitude = Math.atan2(Y, X); + } + + /* -------------------------------------------------------------- + * Following iterative algorithm was developped by + * "Institut for Erdmessung", University of Hannover, July 1988. + * Internet: www.ife.uni-hannover.de + * Iterative computation of CPHI,SPHI and Height. + * Iteration of CPHI and SPHI to 10**-12 radian resp. + * 2*10**-7 arcsec. + * -------------------------------------------------------------- + */ + CT = Z / RR; + ST = P / RR; + RX = 1.0 / Math.sqrt(1.0 - this.es * (2.0 - this.es) * ST * ST); + CPHI0 = ST * (1.0 - this.es) * RX; + SPHI0 = CT * RX; + iter = 0; + + /* loop to find sin(Latitude) resp. Latitude + * until |sin(Latitude(iter)-Latitude(iter-1))| < genau */ + do { + iter++; + RN = this.a / Math.sqrt(1.0 - this.es * SPHI0 * SPHI0); + + /* ellipsoidal (geodetic) height */ + Height = P * CPHI0 + Z * SPHI0 - RN * (1.0 - this.es * SPHI0 * SPHI0); + + RK = this.es * RN / (RN + Height); + RX = 1.0 / Math.sqrt(1.0 - RK * (2.0 - RK) * ST * ST); + CPHI = ST * (1.0 - RK) * RX; + SPHI = CT * RX; + SDPHI = SPHI * CPHI0 - CPHI * SPHI0; + CPHI0 = CPHI; + SPHI0 = SPHI; + } + while (SDPHI * SDPHI > genau2 && iter < maxiter); + + /* ellipsoidal (geodetic) latitude */ + Latitude = Math.atan(SPHI / Math.abs(CPHI)); + + p.x = Longitude; + p.y = Latitude; + p.z = Height; + return p; + }, // cs_geocentric_to_geodetic() + + /** Convert_Geocentric_To_Geodetic + * The method used here is derived from 'An Improved Algorithm for + * Geocentric to Geodetic Coordinate Conversion', by Ralph Toms, Feb 1996 + */ + geocentric_to_geodetic_noniter: function(p) { + var X = p.x; + var Y = p.y; + var Z = p.z ? p.z : 0; //Z value not always supplied + var Longitude; + var Latitude; + var Height; + + var W; /* distance from Z axis */ + var W2; /* square of distance from Z axis */ + var T0; /* initial estimate of vertical component */ + var T1; /* corrected estimate of vertical component */ + var S0; /* initial estimate of horizontal component */ + var S1; /* corrected estimate of horizontal component */ + var Sin_B0; /* Math.sin(B0), B0 is estimate of Bowring aux variable */ + var Sin3_B0; /* cube of Math.sin(B0) */ + var Cos_B0; /* Math.cos(B0) */ + var Sin_p1; /* Math.sin(phi1), phi1 is estimated latitude */ + var Cos_p1; /* Math.cos(phi1) */ + var Rn; /* Earth radius at location */ + var Sum; /* numerator of Math.cos(phi1) */ + var At_Pole; /* indicates location is in polar region */ + + X = parseFloat(X); // cast from string to float + Y = parseFloat(Y); + Z = parseFloat(Z); + + At_Pole = false; + if (X !== 0.0) { + Longitude = Math.atan2(Y, X); + } + else { + if (Y > 0) { + Longitude = HALF_PI; + } + else if (Y < 0) { + Longitude = -HALF_PI; + } + else { + At_Pole = true; + Longitude = 0.0; + if (Z > 0.0) { /* north pole */ + Latitude = HALF_PI; + } + else if (Z < 0.0) { /* south pole */ + Latitude = -HALF_PI; + } + else { /* center of earth */ + Latitude = HALF_PI; + Height = -this.b; + return; + } + } + } + W2 = X * X + Y * Y; + W = Math.sqrt(W2); + T0 = Z * AD_C; + S0 = Math.sqrt(T0 * T0 + W2); + Sin_B0 = T0 / S0; + Cos_B0 = W / S0; + Sin3_B0 = Sin_B0 * Sin_B0 * Sin_B0; + T1 = Z + this.b * this.ep2 * Sin3_B0; + Sum = W - this.a * this.es * Cos_B0 * Cos_B0 * Cos_B0; + S1 = Math.sqrt(T1 * T1 + Sum * Sum); + Sin_p1 = T1 / S1; + Cos_p1 = Sum / S1; + Rn = this.a / Math.sqrt(1.0 - this.es * Sin_p1 * Sin_p1); + if (Cos_p1 >= COS_67P5) { + Height = W / Cos_p1 - Rn; + } + else if (Cos_p1 <= -COS_67P5) { + Height = W / -Cos_p1 - Rn; + } + else { + Height = Z / Sin_p1 + Rn * (this.es - 1.0); + } + if (At_Pole === false) { + Latitude = Math.atan(Sin_p1 / Cos_p1); + } + + p.x = Longitude; + p.y = Latitude; + p.z = Height; + return p; + }, // geocentric_to_geodetic_noniter() + + /****************************************************************/ + // pj_geocentic_to_wgs84( p ) + // p = point to transform in geocentric coordinates (x,y,z) + geocentric_to_wgs84: function(p) { + + if (this.datum_type === PJD_3PARAM) { + // if( x[io] === HUGE_VAL ) + // continue; + p.x += this.datum_params[0]; + p.y += this.datum_params[1]; + p.z += this.datum_params[2]; + + } + else if (this.datum_type === PJD_7PARAM) { + var Dx_BF = this.datum_params[0]; + var Dy_BF = this.datum_params[1]; + var Dz_BF = this.datum_params[2]; + var Rx_BF = this.datum_params[3]; + var Ry_BF = this.datum_params[4]; + var Rz_BF = this.datum_params[5]; + var M_BF = this.datum_params[6]; + // if( x[io] === HUGE_VAL ) + // continue; + var x_out = M_BF * (p.x - Rz_BF * p.y + Ry_BF * p.z) + Dx_BF; + var y_out = M_BF * (Rz_BF * p.x + p.y - Rx_BF * p.z) + Dy_BF; + var z_out = M_BF * (-Ry_BF * p.x + Rx_BF * p.y + p.z) + Dz_BF; + p.x = x_out; + p.y = y_out; + p.z = z_out; + } + }, // cs_geocentric_to_wgs84 + + /****************************************************************/ + // pj_geocentic_from_wgs84() + // coordinate system definition, + // point to transform in geocentric coordinates (x,y,z) + geocentric_from_wgs84: function(p) { + + if (this.datum_type === PJD_3PARAM) { + //if( x[io] === HUGE_VAL ) + // continue; + p.x -= this.datum_params[0]; + p.y -= this.datum_params[1]; + p.z -= this.datum_params[2]; + + } + else if (this.datum_type === PJD_7PARAM) { + var Dx_BF = this.datum_params[0]; + var Dy_BF = this.datum_params[1]; + var Dz_BF = this.datum_params[2]; + var Rx_BF = this.datum_params[3]; + var Ry_BF = this.datum_params[4]; + var Rz_BF = this.datum_params[5]; + var M_BF = this.datum_params[6]; + var x_tmp = (p.x - Dx_BF) / M_BF; + var y_tmp = (p.y - Dy_BF) / M_BF; + var z_tmp = (p.z - Dz_BF) / M_BF; + //if( x[io] === HUGE_VAL ) + // continue; + + p.x = x_tmp + Rz_BF * y_tmp - Ry_BF * z_tmp; + p.y = -Rz_BF * x_tmp + y_tmp + Rx_BF * z_tmp; + p.z = Ry_BF * x_tmp - Rx_BF * y_tmp + z_tmp; + } //cs_geocentric_from_wgs84() + } +}; + +/** point object, nothing fancy, just allows values to be + passed back and forth by reference rather than by value. + Other point classes may be used as long as they have + x and y properties, which will get modified in the transform method. +*/ +module.exports = datum; + +},{}],94:[function(require,module,exports){ +var PJD_3PARAM = 1; +var PJD_7PARAM = 2; +var PJD_GRIDSHIFT = 3; +var PJD_NODATUM = 5; // WGS84 or equivalent +var SRS_WGS84_SEMIMAJOR = 6378137; // only used in grid shift transforms +var SRS_WGS84_ESQUARED = 0.006694379990141316; //DGR: 2012-07-29 +module.exports = function(source, dest, point) { + var wp, i, l; + + function checkParams(fallback) { + return (fallback === PJD_3PARAM || fallback === PJD_7PARAM); + } + // Short cut if the datums are identical. + if (source.compare_datums(dest)) { + return point; // in this case, zero is sucess, + // whereas cs_compare_datums returns 1 to indicate TRUE + // confusing, should fix this + } + + // Explicitly skip datum transform by setting 'datum=none' as parameter for either source or dest + if (source.datum_type === PJD_NODATUM || dest.datum_type === PJD_NODATUM) { + return point; + } + + //DGR: 2012-07-29 : add nadgrids support (begin) + var src_a = source.a; + var src_es = source.es; + + var dst_a = dest.a; + var dst_es = dest.es; + + var fallback = source.datum_type; + // If this datum requires grid shifts, then apply it to geodetic coordinates. + if (fallback === PJD_GRIDSHIFT) { + if (this.apply_gridshift(source, 0, point) === 0) { + source.a = SRS_WGS84_SEMIMAJOR; + source.es = SRS_WGS84_ESQUARED; + } + else { + // try 3 or 7 params transformation or nothing ? + if (!source.datum_params) { + source.a = src_a; + source.es = source.es; + return point; + } + wp = 1; + for (i = 0, l = source.datum_params.length; i < l; i++) { + wp *= source.datum_params[i]; + } + if (wp === 0) { + source.a = src_a; + source.es = source.es; + return point; + } + if (source.datum_params.length > 3) { + fallback = PJD_7PARAM; + } + else { + fallback = PJD_3PARAM; + } + } + } + if (dest.datum_type === PJD_GRIDSHIFT) { + dest.a = SRS_WGS84_SEMIMAJOR; + dest.es = SRS_WGS84_ESQUARED; + } + // Do we need to go through geocentric coordinates? + if (source.es !== dest.es || source.a !== dest.a || checkParams(fallback) || checkParams(dest.datum_type)) { + //DGR: 2012-07-29 : add nadgrids support (end) + // Convert to geocentric coordinates. + source.geodetic_to_geocentric(point); + // CHECK_RETURN; + // Convert between datums + if (checkParams(source.datum_type)) { + source.geocentric_to_wgs84(point); + // CHECK_RETURN; + } + if (checkParams(dest.datum_type)) { + dest.geocentric_from_wgs84(point); + // CHECK_RETURN; + } + // Convert back to geodetic coordinates + dest.geocentric_to_geodetic(point); + // CHECK_RETURN; + } + // Apply grid shift to destination if required + if (dest.datum_type === PJD_GRIDSHIFT) { + this.apply_gridshift(dest, 1, point); + // CHECK_RETURN; + } + + source.a = src_a; + source.es = src_es; + dest.a = dst_a; + dest.es = dst_es; + + return point; +}; + + +},{}],95:[function(require,module,exports){ +var globals = require('./global'); +var parseProj = require('./projString'); +var wkt = require('./wkt'); + +function defs(name) { + /*global console*/ + var that = this; + if (arguments.length === 2) { + var def = arguments[1]; + if (typeof def === 'string') { + if (def.charAt(0) === '+') { + defs[name] = parseProj(arguments[1]); + } + else { + defs[name] = wkt(arguments[1]); + } + } else { + defs[name] = def; + } + } + else if (arguments.length === 1) { + if (Array.isArray(name)) { + return name.map(function(v) { + if (Array.isArray(v)) { + defs.apply(that, v); + } + else { + defs(v); + } + }); + } + else if (typeof name === 'string') { + if (name in defs) { + return defs[name]; + } + } + else if ('EPSG' in name) { + defs['EPSG:' + name.EPSG] = name; + } + else if ('ESRI' in name) { + defs['ESRI:' + name.ESRI] = name; + } + else if ('IAU2000' in name) { + defs['IAU2000:' + name.IAU2000] = name; + } + else { + console.log(name); + } + return; + } + + +} +globals(defs); +module.exports = defs; + +},{"./global":98,"./projString":102,"./wkt":130}],96:[function(require,module,exports){ +var Datum = require('./constants/Datum'); +var Ellipsoid = require('./constants/Ellipsoid'); +var extend = require('./extend'); +var datum = require('./datum'); +var EPSLN = 1.0e-10; +// ellipoid pj_set_ell.c +var SIXTH = 0.1666666666666666667; +/* 1/6 */ +var RA4 = 0.04722222222222222222; +/* 17/360 */ +var RA6 = 0.02215608465608465608; +module.exports = function(json) { + // DGR 2011-03-20 : nagrids -> nadgrids + if (json.datumCode && json.datumCode !== 'none') { + var datumDef = Datum[json.datumCode]; + if (datumDef) { + json.datum_params = datumDef.towgs84 ? datumDef.towgs84.split(',') : null; + json.ellps = datumDef.ellipse; + json.datumName = datumDef.datumName ? datumDef.datumName : json.datumCode; + } + } + if (!json.a) { // do we have an ellipsoid? + var ellipse = Ellipsoid[json.ellps] ? Ellipsoid[json.ellps] : Ellipsoid.WGS84; + extend(json, ellipse); + } + if (json.rf && !json.b) { + json.b = (1.0 - 1.0 / json.rf) * json.a; + } + if (json.rf === 0 || Math.abs(json.a - json.b) < EPSLN) { + json.sphere = true; + json.b = json.a; + } + json.a2 = json.a * json.a; // used in geocentric + json.b2 = json.b * json.b; // used in geocentric + json.es = (json.a2 - json.b2) / json.a2; // e ^ 2 + json.e = Math.sqrt(json.es); // eccentricity + if (json.R_A) { + json.a *= 1 - json.es * (SIXTH + json.es * (RA4 + json.es * RA6)); + json.a2 = json.a * json.a; + json.b2 = json.b * json.b; + json.es = 0; + } + json.ep2 = (json.a2 - json.b2) / json.b2; // used in geocentric + if (!json.k0) { + json.k0 = 1.0; //default value + } + //DGR 2010-11-12: axis + if (!json.axis) { + json.axis = "enu"; + } + + if (!json.datum) { + json.datum = datum(json); + } + return json; +}; + +},{"./constants/Datum":88,"./constants/Ellipsoid":89,"./datum":93,"./extend":97}],97:[function(require,module,exports){ +module.exports = function(destination, source) { + destination = destination || {}; + var value, property; + if (!source) { + return destination; + } + for (property in source) { + value = source[property]; + if (value !== undefined) { + destination[property] = value; + } + } + return destination; +}; + +},{}],98:[function(require,module,exports){ +module.exports = function(defs) { + defs('EPSG:4326', "+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees"); + defs('EPSG:4269', "+title=NAD83 (long/lat) +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees"); + defs('EPSG:3857', "+title=WGS 84 / Pseudo-Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs"); + + defs.WGS84 = defs['EPSG:4326']; + defs['EPSG:3785'] = defs['EPSG:3857']; // maintain backward compat, official code is 3857 + defs.GOOGLE = defs['EPSG:3857']; + defs['EPSG:900913'] = defs['EPSG:3857']; + defs['EPSG:102113'] = defs['EPSG:3857']; +}; + +},{}],99:[function(require,module,exports){ +var projs = [ + require('./projections/tmerc'), + require('./projections/utm'), + require('./projections/sterea'), + require('./projections/stere'), + require('./projections/somerc'), + require('./projections/omerc'), + require('./projections/lcc'), + require('./projections/krovak'), + require('./projections/cass'), + require('./projections/laea'), + require('./projections/aea'), + require('./projections/gnom'), + require('./projections/cea'), + require('./projections/eqc'), + require('./projections/poly'), + require('./projections/nzmg'), + require('./projections/mill'), + require('./projections/sinu'), + require('./projections/moll'), + require('./projections/eqdc'), + require('./projections/vandg'), + require('./projections/aeqd') +]; +module.exports = function(proj4){ + projs.forEach(function(proj){ + proj4.Proj.projections.add(proj); + }); +}; +},{"./projections/aea":104,"./projections/aeqd":105,"./projections/cass":106,"./projections/cea":107,"./projections/eqc":108,"./projections/eqdc":109,"./projections/gnom":111,"./projections/krovak":112,"./projections/laea":113,"./projections/lcc":114,"./projections/mill":117,"./projections/moll":118,"./projections/nzmg":119,"./projections/omerc":120,"./projections/poly":121,"./projections/sinu":122,"./projections/somerc":123,"./projections/stere":124,"./projections/sterea":125,"./projections/tmerc":126,"./projections/utm":127,"./projections/vandg":128}],100:[function(require,module,exports){ +var proj4 = require('./core'); +proj4.defaultDatum = 'WGS84'; //default datum +proj4.Proj = require('./Proj'); +proj4.WGS84 = new proj4.Proj('WGS84'); +proj4.Point = require('./Point'); +proj4.toPoint = require("./common/toPoint"); +proj4.defs = require('./defs'); +proj4.transform = require('./transform'); +proj4.mgrs = require('mgrs'); +proj4.version = require('../package.json').version; +require('./includedProjections')(proj4); +module.exports = proj4; +},{"../package.json":132,"./Point":64,"./Proj":65,"./common/toPoint":86,"./core":92,"./defs":95,"./includedProjections":99,"./transform":129,"mgrs":131}],101:[function(require,module,exports){ +var defs = require('./defs'); +var wkt = require('./wkt'); +var projStr = require('./projString'); +function testObj(code){ + return typeof code === 'string'; +} +function testDef(code){ + return code in defs; +} +function testWKT(code){ + var codeWords = ['GEOGCS','GEOCCS','PROJCS','LOCAL_CS']; + return codeWords.reduce(function(a,b){ + return a+1+code.indexOf(b); + },0); +} +function testProj(code){ + return code[0] === '+'; +} +function parse(code){ + if (testObj(code)) { + //check to see if this is a WKT string + if (testDef(code)) { + return defs[code]; + } + else if (testWKT(code)) { + return wkt(code); + } + else if (testProj(code)) { + return projStr(code); + } + }else{ + return code; + } +} + +module.exports = parse; +},{"./defs":95,"./projString":102,"./wkt":130}],102:[function(require,module,exports){ +var D2R = 0.01745329251994329577; +var PrimeMeridian = require('./constants/PrimeMeridian'); +var units = require('./constants/units'); + +module.exports = function(defData) { + var self = {}; + var paramObj = {}; + defData.split("+").map(function(v) { + return v.trim(); + }).filter(function(a) { + return a; + }).forEach(function(a) { + var split = a.split("="); + split.push(true); + paramObj[split[0].toLowerCase()] = split[1]; + }); + var paramName, paramVal, paramOutname; + var params = { + proj: 'projName', + datum: 'datumCode', + rf: function(v) { + self.rf = parseFloat(v); + }, + lat_0: function(v) { + self.lat0 = v * D2R; + }, + lat_1: function(v) { + self.lat1 = v * D2R; + }, + lat_2: function(v) { + self.lat2 = v * D2R; + }, + lat_ts: function(v) { + self.lat_ts = v * D2R; + }, + lon_0: function(v) { + self.long0 = v * D2R; + }, + lon_1: function(v) { + self.long1 = v * D2R; + }, + lon_2: function(v) { + self.long2 = v * D2R; + }, + alpha: function(v) { + self.alpha = parseFloat(v) * D2R; + }, + lonc: function(v) { + self.longc = v * D2R; + }, + x_0: function(v) { + self.x0 = parseFloat(v); + }, + y_0: function(v) { + self.y0 = parseFloat(v); + }, + k_0: function(v) { + self.k0 = parseFloat(v); + }, + k: function(v) { + self.k0 = parseFloat(v); + }, + a: function(v) { + self.a = parseFloat(v); + }, + b: function(v) { + self.b = parseFloat(v); + }, + r_a: function() { + self.R_A = true; + }, + zone: function(v) { + self.zone = parseInt(v, 10); + }, + south: function() { + self.utmSouth = true; + }, + towgs84: function(v) { + self.datum_params = v.split(",").map(function(a) { + return parseFloat(a); + }); + }, + to_meter: function(v) { + self.to_meter = parseFloat(v); + }, + units: function(v) { + self.units = v; + if (units[v]) { + self.to_meter = units[v].to_meter; + } + }, + from_greenwich: function(v) { + self.from_greenwich = v * D2R; + }, + pm: function(v) { + self.from_greenwich = (PrimeMeridian[v] ? PrimeMeridian[v] : parseFloat(v)) * D2R; + }, + nadgrids: function(v) { + if (v === '@null') { + self.datumCode = 'none'; + } + else { + self.nadgrids = v; + } + }, + axis: function(v) { + var legalAxis = "ewnsud"; + if (v.length === 3 && legalAxis.indexOf(v.substr(0, 1)) !== -1 && legalAxis.indexOf(v.substr(1, 1)) !== -1 && legalAxis.indexOf(v.substr(2, 1)) !== -1) { + self.axis = v; + } + } + }; + for (paramName in paramObj) { + paramVal = paramObj[paramName]; + if (paramName in params) { + paramOutname = params[paramName]; + if (typeof paramOutname === 'function') { + paramOutname(paramVal); + } + else { + self[paramOutname] = paramVal; + } + } + else { + self[paramName] = paramVal; + } + } + if(typeof self.datumCode === 'string' && self.datumCode !== "WGS84"){ + self.datumCode = self.datumCode.toLowerCase(); + } + return self; +}; + +},{"./constants/PrimeMeridian":90,"./constants/units":91}],103:[function(require,module,exports){ +var projs = [ + require('./projections/merc'), + require('./projections/longlat') +]; +var names = {}; +var projStore = []; + +function add(proj, i) { + var len = projStore.length; + if (!proj.names) { + console.log(i); + return true; + } + projStore[len] = proj; + proj.names.forEach(function(n) { + names[n.toLowerCase()] = len; + }); + return this; +} + +exports.add = add; + +exports.get = function(name) { + if (!name) { + return false; + } + var n = name.toLowerCase(); + if (typeof names[n] !== 'undefined' && projStore[names[n]]) { + return projStore[names[n]]; + } +}; +exports.start = function() { + projs.forEach(add); +}; + +},{"./projections/longlat":115,"./projections/merc":116}],104:[function(require,module,exports){ +var EPSLN = 1.0e-10; +var msfnz = require('../common/msfnz'); +var qsfnz = require('../common/qsfnz'); +var adjust_lon = require('../common/adjust_lon'); +var asinz = require('../common/asinz'); +exports.init = function() { + + if (Math.abs(this.lat1 + this.lat2) < EPSLN) { + return; + } + this.temp = this.b / this.a; + this.es = 1 - Math.pow(this.temp, 2); + this.e3 = Math.sqrt(this.es); + + this.sin_po = Math.sin(this.lat1); + this.cos_po = Math.cos(this.lat1); + this.t1 = this.sin_po; + this.con = this.sin_po; + this.ms1 = msfnz(this.e3, this.sin_po, this.cos_po); + this.qs1 = qsfnz(this.e3, this.sin_po, this.cos_po); + + this.sin_po = Math.sin(this.lat2); + this.cos_po = Math.cos(this.lat2); + this.t2 = this.sin_po; + this.ms2 = msfnz(this.e3, this.sin_po, this.cos_po); + this.qs2 = qsfnz(this.e3, this.sin_po, this.cos_po); + + this.sin_po = Math.sin(this.lat0); + this.cos_po = Math.cos(this.lat0); + this.t3 = this.sin_po; + this.qs0 = qsfnz(this.e3, this.sin_po, this.cos_po); + + if (Math.abs(this.lat1 - this.lat2) > EPSLN) { + this.ns0 = (this.ms1 * this.ms1 - this.ms2 * this.ms2) / (this.qs2 - this.qs1); + } + else { + this.ns0 = this.con; + } + this.c = this.ms1 * this.ms1 + this.ns0 * this.qs1; + this.rh = this.a * Math.sqrt(this.c - this.ns0 * this.qs0) / this.ns0; +}; + +/* Albers Conical Equal Area forward equations--mapping lat,long to x,y + -------------------------------------------------------------------*/ +exports.forward = function(p) { + + var lon = p.x; + var lat = p.y; + + this.sin_phi = Math.sin(lat); + this.cos_phi = Math.cos(lat); + + var qs = qsfnz(this.e3, this.sin_phi, this.cos_phi); + var rh1 = this.a * Math.sqrt(this.c - this.ns0 * qs) / this.ns0; + var theta = this.ns0 * adjust_lon(lon - this.long0); + var x = rh1 * Math.sin(theta) + this.x0; + var y = this.rh - rh1 * Math.cos(theta) + this.y0; + + p.x = x; + p.y = y; + return p; +}; + + +exports.inverse = function(p) { + var rh1, qs, con, theta, lon, lat; + + p.x -= this.x0; + p.y = this.rh - p.y + this.y0; + if (this.ns0 >= 0) { + rh1 = Math.sqrt(p.x * p.x + p.y * p.y); + con = 1; + } + else { + rh1 = -Math.sqrt(p.x * p.x + p.y * p.y); + con = -1; + } + theta = 0; + if (rh1 !== 0) { + theta = Math.atan2(con * p.x, con * p.y); + } + con = rh1 * this.ns0 / this.a; + if (this.sphere) { + lat = Math.asin((this.c - con * con) / (2 * this.ns0)); + } + else { + qs = (this.c - con * con) / this.ns0; + lat = this.phi1z(this.e3, qs); + } + + lon = adjust_lon(theta / this.ns0 + this.long0); + p.x = lon; + p.y = lat; + return p; +}; + +/* Function to compute phi1, the latitude for the inverse of the + Albers Conical Equal-Area projection. +-------------------------------------------*/ +exports.phi1z = function(eccent, qs) { + var sinphi, cosphi, con, com, dphi; + var phi = asinz(0.5 * qs); + if (eccent < EPSLN) { + return phi; + } + + var eccnts = eccent * eccent; + for (var i = 1; i <= 25; i++) { + sinphi = Math.sin(phi); + cosphi = Math.cos(phi); + con = eccent * sinphi; + com = 1 - con * con; + dphi = 0.5 * com * com / cosphi * (qs / (1 - eccnts) - sinphi / com + 0.5 / eccent * Math.log((1 - con) / (1 + con))); + phi = phi + dphi; + if (Math.abs(dphi) <= 1e-7) { + return phi; + } + } + return null; +}; +exports.names = ["Albers_Conic_Equal_Area", "Albers", "aea"]; + +},{"../common/adjust_lon":68,"../common/asinz":69,"../common/msfnz":78,"../common/qsfnz":83}],105:[function(require,module,exports){ +var adjust_lon = require('../common/adjust_lon'); +var HALF_PI = Math.PI/2; +var EPSLN = 1.0e-10; +var mlfn = require('../common/mlfn'); +var e0fn = require('../common/e0fn'); +var e1fn = require('../common/e1fn'); +var e2fn = require('../common/e2fn'); +var e3fn = require('../common/e3fn'); +var gN = require('../common/gN'); +var asinz = require('../common/asinz'); +var imlfn = require('../common/imlfn'); +exports.init = function() { + this.sin_p12 = Math.sin(this.lat0); + this.cos_p12 = Math.cos(this.lat0); +}; + +exports.forward = function(p) { + var lon = p.x; + var lat = p.y; + var sinphi = Math.sin(p.y); + var cosphi = Math.cos(p.y); + var dlon = adjust_lon(lon - this.long0); + var e0, e1, e2, e3, Mlp, Ml, tanphi, Nl1, Nl, psi, Az, G, H, GH, Hs, c, kp, cos_c, s, s2, s3, s4, s5; + if (this.sphere) { + if (Math.abs(this.sin_p12 - 1) <= EPSLN) { + //North Pole case + p.x = this.x0 + this.a * (HALF_PI - lat) * Math.sin(dlon); + p.y = this.y0 - this.a * (HALF_PI - lat) * Math.cos(dlon); + return p; + } + else if (Math.abs(this.sin_p12 + 1) <= EPSLN) { + //South Pole case + p.x = this.x0 + this.a * (HALF_PI + lat) * Math.sin(dlon); + p.y = this.y0 + this.a * (HALF_PI + lat) * Math.cos(dlon); + return p; + } + else { + //default case + cos_c = this.sin_p12 * sinphi + this.cos_p12 * cosphi * Math.cos(dlon); + c = Math.acos(cos_c); + kp = c / Math.sin(c); + p.x = this.x0 + this.a * kp * cosphi * Math.sin(dlon); + p.y = this.y0 + this.a * kp * (this.cos_p12 * sinphi - this.sin_p12 * cosphi * Math.cos(dlon)); + return p; + } + } + else { + e0 = e0fn(this.es); + e1 = e1fn(this.es); + e2 = e2fn(this.es); + e3 = e3fn(this.es); + if (Math.abs(this.sin_p12 - 1) <= EPSLN) { + //North Pole case + Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI); + Ml = this.a * mlfn(e0, e1, e2, e3, lat); + p.x = this.x0 + (Mlp - Ml) * Math.sin(dlon); + p.y = this.y0 - (Mlp - Ml) * Math.cos(dlon); + return p; + } + else if (Math.abs(this.sin_p12 + 1) <= EPSLN) { + //South Pole case + Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI); + Ml = this.a * mlfn(e0, e1, e2, e3, lat); + p.x = this.x0 + (Mlp + Ml) * Math.sin(dlon); + p.y = this.y0 + (Mlp + Ml) * Math.cos(dlon); + return p; + } + else { + //Default case + tanphi = sinphi / cosphi; + Nl1 = gN(this.a, this.e, this.sin_p12); + Nl = gN(this.a, this.e, sinphi); + psi = Math.atan((1 - this.es) * tanphi + this.es * Nl1 * this.sin_p12 / (Nl * cosphi)); + Az = Math.atan2(Math.sin(dlon), this.cos_p12 * Math.tan(psi) - this.sin_p12 * Math.cos(dlon)); + if (Az === 0) { + s = Math.asin(this.cos_p12 * Math.sin(psi) - this.sin_p12 * Math.cos(psi)); + } + else if (Math.abs(Math.abs(Az) - Math.PI) <= EPSLN) { + s = -Math.asin(this.cos_p12 * Math.sin(psi) - this.sin_p12 * Math.cos(psi)); + } + else { + s = Math.asin(Math.sin(dlon) * Math.cos(psi) / Math.sin(Az)); + } + G = this.e * this.sin_p12 / Math.sqrt(1 - this.es); + H = this.e * this.cos_p12 * Math.cos(Az) / Math.sqrt(1 - this.es); + GH = G * H; + Hs = H * H; + s2 = s * s; + s3 = s2 * s; + s4 = s3 * s; + s5 = s4 * s; + c = Nl1 * s * (1 - s2 * Hs * (1 - Hs) / 6 + s3 / 8 * GH * (1 - 2 * Hs) + s4 / 120 * (Hs * (4 - 7 * Hs) - 3 * G * G * (1 - 7 * Hs)) - s5 / 48 * GH); + p.x = this.x0 + c * Math.sin(Az); + p.y = this.y0 + c * Math.cos(Az); + return p; + } + } + + +}; + +exports.inverse = function(p) { + p.x -= this.x0; + p.y -= this.y0; + var rh, z, sinz, cosz, lon, lat, con, e0, e1, e2, e3, Mlp, M, N1, psi, Az, cosAz, tmp, A, B, D, Ee, F; + if (this.sphere) { + rh = Math.sqrt(p.x * p.x + p.y * p.y); + if (rh > (2 * HALF_PI * this.a)) { + return; + } + z = rh / this.a; + + sinz = Math.sin(z); + cosz = Math.cos(z); + + lon = this.long0; + if (Math.abs(rh) <= EPSLN) { + lat = this.lat0; + } + else { + lat = asinz(cosz * this.sin_p12 + (p.y * sinz * this.cos_p12) / rh); + con = Math.abs(this.lat0) - HALF_PI; + if (Math.abs(con) <= EPSLN) { + if (this.lat0 >= 0) { + lon = adjust_lon(this.long0 + Math.atan2(p.x, - p.y)); + } + else { + lon = adjust_lon(this.long0 - Math.atan2(-p.x, p.y)); + } + } + else { + /*con = cosz - this.sin_p12 * Math.sin(lat); + if ((Math.abs(con) < EPSLN) && (Math.abs(p.x) < EPSLN)) { + //no-op, just keep the lon value as is + } else { + var temp = Math.atan2((p.x * sinz * this.cos_p12), (con * rh)); + lon = adjust_lon(this.long0 + Math.atan2((p.x * sinz * this.cos_p12), (con * rh))); + }*/ + lon = adjust_lon(this.long0 + Math.atan2(p.x * sinz, rh * this.cos_p12 * cosz - p.y * this.sin_p12 * sinz)); + } + } + + p.x = lon; + p.y = lat; + return p; + } + else { + e0 = e0fn(this.es); + e1 = e1fn(this.es); + e2 = e2fn(this.es); + e3 = e3fn(this.es); + if (Math.abs(this.sin_p12 - 1) <= EPSLN) { + //North pole case + Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI); + rh = Math.sqrt(p.x * p.x + p.y * p.y); + M = Mlp - rh; + lat = imlfn(M / this.a, e0, e1, e2, e3); + lon = adjust_lon(this.long0 + Math.atan2(p.x, - 1 * p.y)); + p.x = lon; + p.y = lat; + return p; + } + else if (Math.abs(this.sin_p12 + 1) <= EPSLN) { + //South pole case + Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI); + rh = Math.sqrt(p.x * p.x + p.y * p.y); + M = rh - Mlp; + + lat = imlfn(M / this.a, e0, e1, e2, e3); + lon = adjust_lon(this.long0 + Math.atan2(p.x, p.y)); + p.x = lon; + p.y = lat; + return p; + } + else { + //default case + rh = Math.sqrt(p.x * p.x + p.y * p.y); + Az = Math.atan2(p.x, p.y); + N1 = gN(this.a, this.e, this.sin_p12); + cosAz = Math.cos(Az); + tmp = this.e * this.cos_p12 * cosAz; + A = -tmp * tmp / (1 - this.es); + B = 3 * this.es * (1 - A) * this.sin_p12 * this.cos_p12 * cosAz / (1 - this.es); + D = rh / N1; + Ee = D - A * (1 + A) * Math.pow(D, 3) / 6 - B * (1 + 3 * A) * Math.pow(D, 4) / 24; + F = 1 - A * Ee * Ee / 2 - D * Ee * Ee * Ee / 6; + psi = Math.asin(this.sin_p12 * Math.cos(Ee) + this.cos_p12 * Math.sin(Ee) * cosAz); + lon = adjust_lon(this.long0 + Math.asin(Math.sin(Az) * Math.sin(Ee) / Math.cos(psi))); + lat = Math.atan((1 - this.es * F * this.sin_p12 / Math.sin(psi)) * Math.tan(psi) / (1 - this.es)); + p.x = lon; + p.y = lat; + return p; + } + } + +}; +exports.names = ["Azimuthal_Equidistant", "aeqd"]; + +},{"../common/adjust_lon":68,"../common/asinz":69,"../common/e0fn":70,"../common/e1fn":71,"../common/e2fn":72,"../common/e3fn":73,"../common/gN":74,"../common/imlfn":75,"../common/mlfn":77}],106:[function(require,module,exports){ +var mlfn = require('../common/mlfn'); +var e0fn = require('../common/e0fn'); +var e1fn = require('../common/e1fn'); +var e2fn = require('../common/e2fn'); +var e3fn = require('../common/e3fn'); +var gN = require('../common/gN'); +var adjust_lon = require('../common/adjust_lon'); +var adjust_lat = require('../common/adjust_lat'); +var imlfn = require('../common/imlfn'); +var HALF_PI = Math.PI/2; +var EPSLN = 1.0e-10; +exports.init = function() { + if (!this.sphere) { + this.e0 = e0fn(this.es); + this.e1 = e1fn(this.es); + this.e2 = e2fn(this.es); + this.e3 = e3fn(this.es); + this.ml0 = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0); + } +}; + + + +/* Cassini forward equations--mapping lat,long to x,y + -----------------------------------------------------------------------*/ +exports.forward = function(p) { + + /* Forward equations + -----------------*/ + var x, y; + var lam = p.x; + var phi = p.y; + lam = adjust_lon(lam - this.long0); + + if (this.sphere) { + x = this.a * Math.asin(Math.cos(phi) * Math.sin(lam)); + y = this.a * (Math.atan2(Math.tan(phi), Math.cos(lam)) - this.lat0); + } + else { + //ellipsoid + var sinphi = Math.sin(phi); + var cosphi = Math.cos(phi); + var nl = gN(this.a, this.e, sinphi); + var tl = Math.tan(phi) * Math.tan(phi); + var al = lam * Math.cos(phi); + var asq = al * al; + var cl = this.es * cosphi * cosphi / (1 - this.es); + var ml = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, phi); + + x = nl * al * (1 - asq * tl * (1 / 6 - (8 - tl + 8 * cl) * asq / 120)); + y = ml - this.ml0 + nl * sinphi / cosphi * asq * (0.5 + (5 - tl + 6 * cl) * asq / 24); + + + } + + p.x = x + this.x0; + p.y = y + this.y0; + return p; +}; + +/* Inverse equations + -----------------*/ +exports.inverse = function(p) { + p.x -= this.x0; + p.y -= this.y0; + var x = p.x / this.a; + var y = p.y / this.a; + var phi, lam; + + if (this.sphere) { + var dd = y + this.lat0; + phi = Math.asin(Math.sin(dd) * Math.cos(x)); + lam = Math.atan2(Math.tan(x), Math.cos(dd)); + } + else { + /* ellipsoid */ + var ml1 = this.ml0 / this.a + y; + var phi1 = imlfn(ml1, this.e0, this.e1, this.e2, this.e3); + if (Math.abs(Math.abs(phi1) - HALF_PI) <= EPSLN) { + p.x = this.long0; + p.y = HALF_PI; + if (y < 0) { + p.y *= -1; + } + return p; + } + var nl1 = gN(this.a, this.e, Math.sin(phi1)); + + var rl1 = nl1 * nl1 * nl1 / this.a / this.a * (1 - this.es); + var tl1 = Math.pow(Math.tan(phi1), 2); + var dl = x * this.a / nl1; + var dsq = dl * dl; + phi = phi1 - nl1 * Math.tan(phi1) / rl1 * dl * dl * (0.5 - (1 + 3 * tl1) * dl * dl / 24); + lam = dl * (1 - dsq * (tl1 / 3 + (1 + 3 * tl1) * tl1 * dsq / 15)) / Math.cos(phi1); + + } + + p.x = adjust_lon(lam + this.long0); + p.y = adjust_lat(phi); + return p; + +}; +exports.names = ["Cassini", "Cassini_Soldner", "cass"]; +},{"../common/adjust_lat":67,"../common/adjust_lon":68,"../common/e0fn":70,"../common/e1fn":71,"../common/e2fn":72,"../common/e3fn":73,"../common/gN":74,"../common/imlfn":75,"../common/mlfn":77}],107:[function(require,module,exports){ +var adjust_lon = require('../common/adjust_lon'); +var qsfnz = require('../common/qsfnz'); +var msfnz = require('../common/msfnz'); +var iqsfnz = require('../common/iqsfnz'); +/* + reference: + "Cartographic Projection Procedures for the UNIX Environment- + A User's Manual" by Gerald I. Evenden, + USGS Open File Report 90-284and Release 4 Interim Reports (2003) +*/ +exports.init = function() { + //no-op + if (!this.sphere) { + this.k0 = msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts)); + } +}; + + +/* Cylindrical Equal Area forward equations--mapping lat,long to x,y + ------------------------------------------------------------*/ +exports.forward = function(p) { + var lon = p.x; + var lat = p.y; + var x, y; + /* Forward equations + -----------------*/ + var dlon = adjust_lon(lon - this.long0); + if (this.sphere) { + x = this.x0 + this.a * dlon * Math.cos(this.lat_ts); + y = this.y0 + this.a * Math.sin(lat) / Math.cos(this.lat_ts); + } + else { + var qs = qsfnz(this.e, Math.sin(lat)); + x = this.x0 + this.a * this.k0 * dlon; + y = this.y0 + this.a * qs * 0.5 / this.k0; + } + + p.x = x; + p.y = y; + return p; +}; + +/* Cylindrical Equal Area inverse equations--mapping x,y to lat/long + ------------------------------------------------------------*/ +exports.inverse = function(p) { + p.x -= this.x0; + p.y -= this.y0; + var lon, lat; + + if (this.sphere) { + lon = adjust_lon(this.long0 + (p.x / this.a) / Math.cos(this.lat_ts)); + lat = Math.asin((p.y / this.a) * Math.cos(this.lat_ts)); + } + else { + lat = iqsfnz(this.e, 2 * p.y * this.k0 / this.a); + lon = adjust_lon(this.long0 + p.x / (this.a * this.k0)); + } + + p.x = lon; + p.y = lat; + return p; +}; +exports.names = ["cea"]; + +},{"../common/adjust_lon":68,"../common/iqsfnz":76,"../common/msfnz":78,"../common/qsfnz":83}],108:[function(require,module,exports){ +var adjust_lon = require('../common/adjust_lon'); +var adjust_lat = require('../common/adjust_lat'); +exports.init = function() { + + this.x0 = this.x0 || 0; + this.y0 = this.y0 || 0; + this.lat0 = this.lat0 || 0; + this.long0 = this.long0 || 0; + this.lat_ts = this.lat_ts || 0; + this.title = this.title || "Equidistant Cylindrical (Plate Carre)"; + + this.rc = Math.cos(this.lat_ts); +}; + + +// forward equations--mapping lat,long to x,y +// ----------------------------------------------------------------- +exports.forward = function(p) { + + var lon = p.x; + var lat = p.y; + + var dlon = adjust_lon(lon - this.long0); + var dlat = adjust_lat(lat - this.lat0); + p.x = this.x0 + (this.a * dlon * this.rc); + p.y = this.y0 + (this.a * dlat); + return p; +}; + +// inverse equations--mapping x,y to lat/long +// ----------------------------------------------------------------- +exports.inverse = function(p) { + + var x = p.x; + var y = p.y; + + p.x = adjust_lon(this.long0 + ((x - this.x0) / (this.a * this.rc))); + p.y = adjust_lat(this.lat0 + ((y - this.y0) / (this.a))); + return p; +}; +exports.names = ["Equirectangular", "Equidistant_Cylindrical", "eqc"]; + +},{"../common/adjust_lat":67,"../common/adjust_lon":68}],109:[function(require,module,exports){ +var e0fn = require('../common/e0fn'); +var e1fn = require('../common/e1fn'); +var e2fn = require('../common/e2fn'); +var e3fn = require('../common/e3fn'); +var msfnz = require('../common/msfnz'); +var mlfn = require('../common/mlfn'); +var adjust_lon = require('../common/adjust_lon'); +var adjust_lat = require('../common/adjust_lat'); +var imlfn = require('../common/imlfn'); +var EPSLN = 1.0e-10; +exports.init = function() { + + /* Place parameters in static storage for common use + -------------------------------------------------*/ + // Standard Parallels cannot be equal and on opposite sides of the equator + if (Math.abs(this.lat1 + this.lat2) < EPSLN) { + return; + } + this.lat2 = this.lat2 || this.lat1; + this.temp = this.b / this.a; + this.es = 1 - Math.pow(this.temp, 2); + this.e = Math.sqrt(this.es); + this.e0 = e0fn(this.es); + this.e1 = e1fn(this.es); + this.e2 = e2fn(this.es); + this.e3 = e3fn(this.es); + + this.sinphi = Math.sin(this.lat1); + this.cosphi = Math.cos(this.lat1); + + this.ms1 = msfnz(this.e, this.sinphi, this.cosphi); + this.ml1 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat1); + + if (Math.abs(this.lat1 - this.lat2) < EPSLN) { + this.ns = this.sinphi; + } + else { + this.sinphi = Math.sin(this.lat2); + this.cosphi = Math.cos(this.lat2); + this.ms2 = msfnz(this.e, this.sinphi, this.cosphi); + this.ml2 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat2); + this.ns = (this.ms1 - this.ms2) / (this.ml2 - this.ml1); + } + this.g = this.ml1 + this.ms1 / this.ns; + this.ml0 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0); + this.rh = this.a * (this.g - this.ml0); +}; + + +/* Equidistant Conic forward equations--mapping lat,long to x,y + -----------------------------------------------------------*/ +exports.forward = function(p) { + var lon = p.x; + var lat = p.y; + var rh1; + + /* Forward equations + -----------------*/ + if (this.sphere) { + rh1 = this.a * (this.g - lat); + } + else { + var ml = mlfn(this.e0, this.e1, this.e2, this.e3, lat); + rh1 = this.a * (this.g - ml); + } + var theta = this.ns * adjust_lon(lon - this.long0); + var x = this.x0 + rh1 * Math.sin(theta); + var y = this.y0 + this.rh - rh1 * Math.cos(theta); + p.x = x; + p.y = y; + return p; +}; + +/* Inverse equations + -----------------*/ +exports.inverse = function(p) { + p.x -= this.x0; + p.y = this.rh - p.y + this.y0; + var con, rh1, lat, lon; + if (this.ns >= 0) { + rh1 = Math.sqrt(p.x * p.x + p.y * p.y); + con = 1; + } + else { + rh1 = -Math.sqrt(p.x * p.x + p.y * p.y); + con = -1; + } + var theta = 0; + if (rh1 !== 0) { + theta = Math.atan2(con * p.x, con * p.y); + } + + if (this.sphere) { + lon = adjust_lon(this.long0 + theta / this.ns); + lat = adjust_lat(this.g - rh1 / this.a); + p.x = lon; + p.y = lat; + return p; + } + else { + var ml = this.g - rh1 / this.a; + lat = imlfn(ml, this.e0, this.e1, this.e2, this.e3); + lon = adjust_lon(this.long0 + theta / this.ns); + p.x = lon; + p.y = lat; + return p; + } + +}; +exports.names = ["Equidistant_Conic", "eqdc"]; + +},{"../common/adjust_lat":67,"../common/adjust_lon":68,"../common/e0fn":70,"../common/e1fn":71,"../common/e2fn":72,"../common/e3fn":73,"../common/imlfn":75,"../common/mlfn":77,"../common/msfnz":78}],110:[function(require,module,exports){ +var FORTPI = Math.PI/4; +var srat = require('../common/srat'); +var HALF_PI = Math.PI/2; +var MAX_ITER = 20; +exports.init = function() { + var sphi = Math.sin(this.lat0); + var cphi = Math.cos(this.lat0); + cphi *= cphi; + this.rc = Math.sqrt(1 - this.es) / (1 - this.es * sphi * sphi); + this.C = Math.sqrt(1 + this.es * cphi * cphi / (1 - this.es)); + this.phic0 = Math.asin(sphi / this.C); + this.ratexp = 0.5 * this.C * this.e; + this.K = Math.tan(0.5 * this.phic0 + FORTPI) / (Math.pow(Math.tan(0.5 * this.lat0 + FORTPI), this.C) * srat(this.e * sphi, this.ratexp)); +}; + +exports.forward = function(p) { + var lon = p.x; + var lat = p.y; + + p.y = 2 * Math.atan(this.K * Math.pow(Math.tan(0.5 * lat + FORTPI), this.C) * srat(this.e * Math.sin(lat), this.ratexp)) - HALF_PI; + p.x = this.C * lon; + return p; +}; + +exports.inverse = function(p) { + var DEL_TOL = 1e-14; + var lon = p.x / this.C; + var lat = p.y; + var num = Math.pow(Math.tan(0.5 * lat + FORTPI) / this.K, 1 / this.C); + for (var i = MAX_ITER; i > 0; --i) { + lat = 2 * Math.atan(num * srat(this.e * Math.sin(p.y), - 0.5 * this.e)) - HALF_PI; + if (Math.abs(lat - p.y) < DEL_TOL) { + break; + } + p.y = lat; + } + /* convergence failed */ + if (!i) { + return null; + } + p.x = lon; + p.y = lat; + return p; +}; +exports.names = ["gauss"]; + +},{"../common/srat":85}],111:[function(require,module,exports){ +var adjust_lon = require('../common/adjust_lon'); +var EPSLN = 1.0e-10; +var asinz = require('../common/asinz'); + +/* + reference: + Wolfram Mathworld "Gnomonic Projection" + http://mathworld.wolfram.com/GnomonicProjection.html + Accessed: 12th November 2009 + */ +exports.init = function() { + + /* Place parameters in static storage for common use + -------------------------------------------------*/ + this.sin_p14 = Math.sin(this.lat0); + this.cos_p14 = Math.cos(this.lat0); + // Approximation for projecting points to the horizon (infinity) + this.infinity_dist = 1000 * this.a; + this.rc = 1; +}; + + +/* Gnomonic forward equations--mapping lat,long to x,y + ---------------------------------------------------*/ +exports.forward = function(p) { + var sinphi, cosphi; /* sin and cos value */ + var dlon; /* delta longitude value */ + var coslon; /* cos of longitude */ + var ksp; /* scale factor */ + var g; + var x, y; + var lon = p.x; + var lat = p.y; + /* Forward equations + -----------------*/ + dlon = adjust_lon(lon - this.long0); + + sinphi = Math.sin(lat); + cosphi = Math.cos(lat); + + coslon = Math.cos(dlon); + g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon; + ksp = 1; + if ((g > 0) || (Math.abs(g) <= EPSLN)) { + x = this.x0 + this.a * ksp * cosphi * Math.sin(dlon) / g; + y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon) / g; + } + else { + + // Point is in the opposing hemisphere and is unprojectable + // We still need to return a reasonable point, so we project + // to infinity, on a bearing + // equivalent to the northern hemisphere equivalent + // This is a reasonable approximation for short shapes and lines that + // straddle the horizon. + + x = this.x0 + this.infinity_dist * cosphi * Math.sin(dlon); + y = this.y0 + this.infinity_dist * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon); + + } + p.x = x; + p.y = y; + return p; +}; + + +exports.inverse = function(p) { + var rh; /* Rho */ + var sinc, cosc; + var c; + var lon, lat; + + /* Inverse equations + -----------------*/ + p.x = (p.x - this.x0) / this.a; + p.y = (p.y - this.y0) / this.a; + + p.x /= this.k0; + p.y /= this.k0; + + if ((rh = Math.sqrt(p.x * p.x + p.y * p.y))) { + c = Math.atan2(rh, this.rc); + sinc = Math.sin(c); + cosc = Math.cos(c); + + lat = asinz(cosc * this.sin_p14 + (p.y * sinc * this.cos_p14) / rh); + lon = Math.atan2(p.x * sinc, rh * this.cos_p14 * cosc - p.y * this.sin_p14 * sinc); + lon = adjust_lon(this.long0 + lon); + } + else { + lat = this.phic0; + lon = 0; + } + + p.x = lon; + p.y = lat; + return p; +}; +exports.names = ["gnom"]; + +},{"../common/adjust_lon":68,"../common/asinz":69}],112:[function(require,module,exports){ +var adjust_lon = require('../common/adjust_lon'); +exports.init = function() { + this.a = 6377397.155; + this.es = 0.006674372230614; + this.e = Math.sqrt(this.es); + if (!this.lat0) { + this.lat0 = 0.863937979737193; + } + if (!this.long0) { + this.long0 = 0.7417649320975901 - 0.308341501185665; + } + /* if scale not set default to 0.9999 */ + if (!this.k0) { + this.k0 = 0.9999; + } + this.s45 = 0.785398163397448; /* 45 */ + this.s90 = 2 * this.s45; + this.fi0 = this.lat0; + this.e2 = this.es; + this.e = Math.sqrt(this.e2); + this.alfa = Math.sqrt(1 + (this.e2 * Math.pow(Math.cos(this.fi0), 4)) / (1 - this.e2)); + this.uq = 1.04216856380474; + this.u0 = Math.asin(Math.sin(this.fi0) / this.alfa); + this.g = Math.pow((1 + this.e * Math.sin(this.fi0)) / (1 - this.e * Math.sin(this.fi0)), this.alfa * this.e / 2); + this.k = Math.tan(this.u0 / 2 + this.s45) / Math.pow(Math.tan(this.fi0 / 2 + this.s45), this.alfa) * this.g; + this.k1 = this.k0; + this.n0 = this.a * Math.sqrt(1 - this.e2) / (1 - this.e2 * Math.pow(Math.sin(this.fi0), 2)); + this.s0 = 1.37008346281555; + this.n = Math.sin(this.s0); + this.ro0 = this.k1 * this.n0 / Math.tan(this.s0); + this.ad = this.s90 - this.uq; +}; + +/* ellipsoid */ +/* calculate xy from lat/lon */ +/* Constants, identical to inverse transform function */ +exports.forward = function(p) { + var gfi, u, deltav, s, d, eps, ro; + var lon = p.x; + var lat = p.y; + var delta_lon = adjust_lon(lon - this.long0); + /* Transformation */ + gfi = Math.pow(((1 + this.e * Math.sin(lat)) / (1 - this.e * Math.sin(lat))), (this.alfa * this.e / 2)); + u = 2 * (Math.atan(this.k * Math.pow(Math.tan(lat / 2 + this.s45), this.alfa) / gfi) - this.s45); + deltav = -delta_lon * this.alfa; + s = Math.asin(Math.cos(this.ad) * Math.sin(u) + Math.sin(this.ad) * Math.cos(u) * Math.cos(deltav)); + d = Math.asin(Math.cos(u) * Math.sin(deltav) / Math.cos(s)); + eps = this.n * d; + ro = this.ro0 * Math.pow(Math.tan(this.s0 / 2 + this.s45), this.n) / Math.pow(Math.tan(s / 2 + this.s45), this.n); + p.y = ro * Math.cos(eps) / 1; + p.x = ro * Math.sin(eps) / 1; + + if (!this.czech) { + p.y *= -1; + p.x *= -1; + } + return (p); +}; + +/* calculate lat/lon from xy */ +exports.inverse = function(p) { + var u, deltav, s, d, eps, ro, fi1; + var ok; + + /* Transformation */ + /* revert y, x*/ + var tmp = p.x; + p.x = p.y; + p.y = tmp; + if (!this.czech) { + p.y *= -1; + p.x *= -1; + } + ro = Math.sqrt(p.x * p.x + p.y * p.y); + eps = Math.atan2(p.y, p.x); + d = eps / Math.sin(this.s0); + s = 2 * (Math.atan(Math.pow(this.ro0 / ro, 1 / this.n) * Math.tan(this.s0 / 2 + this.s45)) - this.s45); + u = Math.asin(Math.cos(this.ad) * Math.sin(s) - Math.sin(this.ad) * Math.cos(s) * Math.cos(d)); + deltav = Math.asin(Math.cos(s) * Math.sin(d) / Math.cos(u)); + p.x = this.long0 - deltav / this.alfa; + fi1 = u; + ok = 0; + var iter = 0; + do { + p.y = 2 * (Math.atan(Math.pow(this.k, - 1 / this.alfa) * Math.pow(Math.tan(u / 2 + this.s45), 1 / this.alfa) * Math.pow((1 + this.e * Math.sin(fi1)) / (1 - this.e * Math.sin(fi1)), this.e / 2)) - this.s45); + if (Math.abs(fi1 - p.y) < 0.0000000001) { + ok = 1; + } + fi1 = p.y; + iter += 1; + } while (ok === 0 && iter < 15); + if (iter >= 15) { + return null; + } + + return (p); +}; +exports.names = ["Krovak", "krovak"]; + +},{"../common/adjust_lon":68}],113:[function(require,module,exports){ +var HALF_PI = Math.PI/2; +var FORTPI = Math.PI/4; +var EPSLN = 1.0e-10; +var qsfnz = require('../common/qsfnz'); +var adjust_lon = require('../common/adjust_lon'); +/* + reference + "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder, + The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355. + */ + +exports.S_POLE = 1; +exports.N_POLE = 2; +exports.EQUIT = 3; +exports.OBLIQ = 4; + + +/* Initialize the Lambert Azimuthal Equal Area projection + ------------------------------------------------------*/ +exports.init = function() { + var t = Math.abs(this.lat0); + if (Math.abs(t - HALF_PI) < EPSLN) { + this.mode = this.lat0 < 0 ? this.S_POLE : this.N_POLE; + } + else if (Math.abs(t) < EPSLN) { + this.mode = this.EQUIT; + } + else { + this.mode = this.OBLIQ; + } + if (this.es > 0) { + var sinphi; + + this.qp = qsfnz(this.e, 1); + this.mmf = 0.5 / (1 - this.es); + this.apa = this.authset(this.es); + switch (this.mode) { + case this.N_POLE: + this.dd = 1; + break; + case this.S_POLE: + this.dd = 1; + break; + case this.EQUIT: + this.rq = Math.sqrt(0.5 * this.qp); + this.dd = 1 / this.rq; + this.xmf = 1; + this.ymf = 0.5 * this.qp; + break; + case this.OBLIQ: + this.rq = Math.sqrt(0.5 * this.qp); + sinphi = Math.sin(this.lat0); + this.sinb1 = qsfnz(this.e, sinphi) / this.qp; + this.cosb1 = Math.sqrt(1 - this.sinb1 * this.sinb1); + this.dd = Math.cos(this.lat0) / (Math.sqrt(1 - this.es * sinphi * sinphi) * this.rq * this.cosb1); + this.ymf = (this.xmf = this.rq) / this.dd; + this.xmf *= this.dd; + break; + } + } + else { + if (this.mode === this.OBLIQ) { + this.sinph0 = Math.sin(this.lat0); + this.cosph0 = Math.cos(this.lat0); + } + } +}; + +/* Lambert Azimuthal Equal Area forward equations--mapping lat,long to x,y + -----------------------------------------------------------------------*/ +exports.forward = function(p) { + + /* Forward equations + -----------------*/ + var x, y, coslam, sinlam, sinphi, q, sinb, cosb, b, cosphi; + var lam = p.x; + var phi = p.y; + + lam = adjust_lon(lam - this.long0); + + if (this.sphere) { + sinphi = Math.sin(phi); + cosphi = Math.cos(phi); + coslam = Math.cos(lam); + if (this.mode === this.OBLIQ || this.mode === this.EQUIT) { + y = (this.mode === this.EQUIT) ? 1 + cosphi * coslam : 1 + this.sinph0 * sinphi + this.cosph0 * cosphi * coslam; + if (y <= EPSLN) { + return null; + } + y = Math.sqrt(2 / y); + x = y * cosphi * Math.sin(lam); + y *= (this.mode === this.EQUIT) ? sinphi : this.cosph0 * sinphi - this.sinph0 * cosphi * coslam; + } + else if (this.mode === this.N_POLE || this.mode === this.S_POLE) { + if (this.mode === this.N_POLE) { + coslam = -coslam; + } + if (Math.abs(phi + this.phi0) < EPSLN) { + return null; + } + y = FORTPI - phi * 0.5; + y = 2 * ((this.mode === this.S_POLE) ? Math.cos(y) : Math.sin(y)); + x = y * Math.sin(lam); + y *= coslam; + } + } + else { + sinb = 0; + cosb = 0; + b = 0; + coslam = Math.cos(lam); + sinlam = Math.sin(lam); + sinphi = Math.sin(phi); + q = qsfnz(this.e, sinphi); + if (this.mode === this.OBLIQ || this.mode === this.EQUIT) { + sinb = q / this.qp; + cosb = Math.sqrt(1 - sinb * sinb); + } + switch (this.mode) { + case this.OBLIQ: + b = 1 + this.sinb1 * sinb + this.cosb1 * cosb * coslam; + break; + case this.EQUIT: + b = 1 + cosb * coslam; + break; + case this.N_POLE: + b = HALF_PI + phi; + q = this.qp - q; + break; + case this.S_POLE: + b = phi - HALF_PI; + q = this.qp + q; + break; + } + if (Math.abs(b) < EPSLN) { + return null; + } + switch (this.mode) { + case this.OBLIQ: + case this.EQUIT: + b = Math.sqrt(2 / b); + if (this.mode === this.OBLIQ) { + y = this.ymf * b * (this.cosb1 * sinb - this.sinb1 * cosb * coslam); + } + else { + y = (b = Math.sqrt(2 / (1 + cosb * coslam))) * sinb * this.ymf; + } + x = this.xmf * b * cosb * sinlam; + break; + case this.N_POLE: + case this.S_POLE: + if (q >= 0) { + x = (b = Math.sqrt(q)) * sinlam; + y = coslam * ((this.mode === this.S_POLE) ? b : -b); + } + else { + x = y = 0; + } + break; + } + } + + p.x = this.a * x + this.x0; + p.y = this.a * y + this.y0; + return p; +}; + +/* Inverse equations + -----------------*/ +exports.inverse = function(p) { + p.x -= this.x0; + p.y -= this.y0; + var x = p.x / this.a; + var y = p.y / this.a; + var lam, phi, cCe, sCe, q, rho, ab; + + if (this.sphere) { + var cosz = 0, + rh, sinz = 0; + + rh = Math.sqrt(x * x + y * y); + phi = rh * 0.5; + if (phi > 1) { + return null; + } + phi = 2 * Math.asin(phi); + if (this.mode === this.OBLIQ || this.mode === this.EQUIT) { + sinz = Math.sin(phi); + cosz = Math.cos(phi); + } + switch (this.mode) { + case this.EQUIT: + phi = (Math.abs(rh) <= EPSLN) ? 0 : Math.asin(y * sinz / rh); + x *= sinz; + y = cosz * rh; + break; + case this.OBLIQ: + phi = (Math.abs(rh) <= EPSLN) ? this.phi0 : Math.asin(cosz * this.sinph0 + y * sinz * this.cosph0 / rh); + x *= sinz * this.cosph0; + y = (cosz - Math.sin(phi) * this.sinph0) * rh; + break; + case this.N_POLE: + y = -y; + phi = HALF_PI - phi; + break; + case this.S_POLE: + phi -= HALF_PI; + break; + } + lam = (y === 0 && (this.mode === this.EQUIT || this.mode === this.OBLIQ)) ? 0 : Math.atan2(x, y); + } + else { + ab = 0; + if (this.mode === this.OBLIQ || this.mode === this.EQUIT) { + x /= this.dd; + y *= this.dd; + rho = Math.sqrt(x * x + y * y); + if (rho < EPSLN) { + p.x = 0; + p.y = this.phi0; + return p; + } + sCe = 2 * Math.asin(0.5 * rho / this.rq); + cCe = Math.cos(sCe); + x *= (sCe = Math.sin(sCe)); + if (this.mode === this.OBLIQ) { + ab = cCe * this.sinb1 + y * sCe * this.cosb1 / rho; + q = this.qp * ab; + y = rho * this.cosb1 * cCe - y * this.sinb1 * sCe; + } + else { + ab = y * sCe / rho; + q = this.qp * ab; + y = rho * cCe; + } + } + else if (this.mode === this.N_POLE || this.mode === this.S_POLE) { + if (this.mode === this.N_POLE) { + y = -y; + } + q = (x * x + y * y); + if (!q) { + p.x = 0; + p.y = this.phi0; + return p; + } + ab = 1 - q / this.qp; + if (this.mode === this.S_POLE) { + ab = -ab; + } + } + lam = Math.atan2(x, y); + phi = this.authlat(Math.asin(ab), this.apa); + } + + + p.x = adjust_lon(this.long0 + lam); + p.y = phi; + return p; +}; + +/* determine latitude from authalic latitude */ +exports.P00 = 0.33333333333333333333; +exports.P01 = 0.17222222222222222222; +exports.P02 = 0.10257936507936507936; +exports.P10 = 0.06388888888888888888; +exports.P11 = 0.06640211640211640211; +exports.P20 = 0.01641501294219154443; + +exports.authset = function(es) { + var t; + var APA = []; + APA[0] = es * this.P00; + t = es * es; + APA[0] += t * this.P01; + APA[1] = t * this.P10; + t *= es; + APA[0] += t * this.P02; + APA[1] += t * this.P11; + APA[2] = t * this.P20; + return APA; +}; + +exports.authlat = function(beta, APA) { + var t = beta + beta; + return (beta + APA[0] * Math.sin(t) + APA[1] * Math.sin(t + t) + APA[2] * Math.sin(t + t + t)); +}; +exports.names = ["Lambert Azimuthal Equal Area", "Lambert_Azimuthal_Equal_Area", "laea"]; + +},{"../common/adjust_lon":68,"../common/qsfnz":83}],114:[function(require,module,exports){ +var EPSLN = 1.0e-10; +var msfnz = require('../common/msfnz'); +var tsfnz = require('../common/tsfnz'); +var HALF_PI = Math.PI/2; +var sign = require('../common/sign'); +var adjust_lon = require('../common/adjust_lon'); +var phi2z = require('../common/phi2z'); +exports.init = function() { + + // array of: r_maj,r_min,lat1,lat2,c_lon,c_lat,false_east,false_north + //double c_lat; /* center latitude */ + //double c_lon; /* center longitude */ + //double lat1; /* first standard parallel */ + //double lat2; /* second standard parallel */ + //double r_maj; /* major axis */ + //double r_min; /* minor axis */ + //double false_east; /* x offset in meters */ + //double false_north; /* y offset in meters */ + + if (!this.lat2) { + this.lat2 = this.lat1; + } //if lat2 is not defined + if (!this.k0) { + this.k0 = 1; + } + this.x0 = this.x0 || 0; + this.y0 = this.y0 || 0; + // Standard Parallels cannot be equal and on opposite sides of the equator + if (Math.abs(this.lat1 + this.lat2) < EPSLN) { + return; + } + + var temp = this.b / this.a; + this.e = Math.sqrt(1 - temp * temp); + + var sin1 = Math.sin(this.lat1); + var cos1 = Math.cos(this.lat1); + var ms1 = msfnz(this.e, sin1, cos1); + var ts1 = tsfnz(this.e, this.lat1, sin1); + + var sin2 = Math.sin(this.lat2); + var cos2 = Math.cos(this.lat2); + var ms2 = msfnz(this.e, sin2, cos2); + var ts2 = tsfnz(this.e, this.lat2, sin2); + + var ts0 = tsfnz(this.e, this.lat0, Math.sin(this.lat0)); + + if (Math.abs(this.lat1 - this.lat2) > EPSLN) { + this.ns = Math.log(ms1 / ms2) / Math.log(ts1 / ts2); + } + else { + this.ns = sin1; + } + if (isNaN(this.ns)) { + this.ns = sin1; + } + this.f0 = ms1 / (this.ns * Math.pow(ts1, this.ns)); + this.rh = this.a * this.f0 * Math.pow(ts0, this.ns); + if (!this.title) { + this.title = "Lambert Conformal Conic"; + } +}; + + +// Lambert Conformal conic forward equations--mapping lat,long to x,y +// ----------------------------------------------------------------- +exports.forward = function(p) { + + var lon = p.x; + var lat = p.y; + + // singular cases : + if (Math.abs(2 * Math.abs(lat) - Math.PI) <= EPSLN) { + lat = sign(lat) * (HALF_PI - 2 * EPSLN); + } + + var con = Math.abs(Math.abs(lat) - HALF_PI); + var ts, rh1; + if (con > EPSLN) { + ts = tsfnz(this.e, lat, Math.sin(lat)); + rh1 = this.a * this.f0 * Math.pow(ts, this.ns); + } + else { + con = lat * this.ns; + if (con <= 0) { + return null; + } + rh1 = 0; + } + var theta = this.ns * adjust_lon(lon - this.long0); + p.x = this.k0 * (rh1 * Math.sin(theta)) + this.x0; + p.y = this.k0 * (this.rh - rh1 * Math.cos(theta)) + this.y0; + + return p; +}; + +// Lambert Conformal Conic inverse equations--mapping x,y to lat/long +// ----------------------------------------------------------------- +exports.inverse = function(p) { + + var rh1, con, ts; + var lat, lon; + var x = (p.x - this.x0) / this.k0; + var y = (this.rh - (p.y - this.y0) / this.k0); + if (this.ns > 0) { + rh1 = Math.sqrt(x * x + y * y); + con = 1; + } + else { + rh1 = -Math.sqrt(x * x + y * y); + con = -1; + } + var theta = 0; + if (rh1 !== 0) { + theta = Math.atan2((con * x), (con * y)); + } + if ((rh1 !== 0) || (this.ns > 0)) { + con = 1 / this.ns; + ts = Math.pow((rh1 / (this.a * this.f0)), con); + lat = phi2z(this.e, ts); + if (lat === -9999) { + return null; + } + } + else { + lat = -HALF_PI; + } + lon = adjust_lon(theta / this.ns + this.long0); + + p.x = lon; + p.y = lat; + return p; +}; + +exports.names = ["Lambert Tangential Conformal Conic Projection", "Lambert_Conformal_Conic", "Lambert_Conformal_Conic_2SP", "lcc"]; + +},{"../common/adjust_lon":68,"../common/msfnz":78,"../common/phi2z":79,"../common/sign":84,"../common/tsfnz":87}],115:[function(require,module,exports){ +exports.init = function() { + //no-op for longlat +}; + +function identity(pt) { + return pt; +} +exports.forward = identity; +exports.inverse = identity; +exports.names = ["longlat", "identity"]; + +},{}],116:[function(require,module,exports){ +var msfnz = require('../common/msfnz'); +var HALF_PI = Math.PI/2; +var EPSLN = 1.0e-10; +var R2D = 57.29577951308232088; +var adjust_lon = require('../common/adjust_lon'); +var FORTPI = Math.PI/4; +var tsfnz = require('../common/tsfnz'); +var phi2z = require('../common/phi2z'); +exports.init = function() { + var con = this.b / this.a; + this.es = 1 - con * con; + if(!('x0' in this)){ + this.x0 = 0; + } + if(!('y0' in this)){ + this.y0 = 0; + } + this.e = Math.sqrt(this.es); + if (this.lat_ts) { + if (this.sphere) { + this.k0 = Math.cos(this.lat_ts); + } + else { + this.k0 = msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts)); + } + } + else { + if (!this.k0) { + if (this.k) { + this.k0 = this.k; + } + else { + this.k0 = 1; + } + } + } +}; + +/* Mercator forward equations--mapping lat,long to x,y + --------------------------------------------------*/ + +exports.forward = function(p) { + var lon = p.x; + var lat = p.y; + // convert to radians + if (lat * R2D > 90 && lat * R2D < -90 && lon * R2D > 180 && lon * R2D < -180) { + return null; + } + + var x, y; + if (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN) { + return null; + } + else { + if (this.sphere) { + x = this.x0 + this.a * this.k0 * adjust_lon(lon - this.long0); + y = this.y0 + this.a * this.k0 * Math.log(Math.tan(FORTPI + 0.5 * lat)); + } + else { + var sinphi = Math.sin(lat); + var ts = tsfnz(this.e, lat, sinphi); + x = this.x0 + this.a * this.k0 * adjust_lon(lon - this.long0); + y = this.y0 - this.a * this.k0 * Math.log(ts); + } + p.x = x; + p.y = y; + return p; + } +}; + + +/* Mercator inverse equations--mapping x,y to lat/long + --------------------------------------------------*/ +exports.inverse = function(p) { + + var x = p.x - this.x0; + var y = p.y - this.y0; + var lon, lat; + + if (this.sphere) { + lat = HALF_PI - 2 * Math.atan(Math.exp(-y / (this.a * this.k0))); + } + else { + var ts = Math.exp(-y / (this.a * this.k0)); + lat = phi2z(this.e, ts); + if (lat === -9999) { + return null; + } + } + lon = adjust_lon(this.long0 + x / (this.a * this.k0)); + + p.x = lon; + p.y = lat; + return p; +}; + +exports.names = ["Mercator", "Popular Visualisation Pseudo Mercator", "Mercator_1SP", "Mercator_Auxiliary_Sphere", "merc"]; + +},{"../common/adjust_lon":68,"../common/msfnz":78,"../common/phi2z":79,"../common/tsfnz":87}],117:[function(require,module,exports){ +var adjust_lon = require('../common/adjust_lon'); +/* + reference + "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder, + The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355. + */ + + +/* Initialize the Miller Cylindrical projection + -------------------------------------------*/ +exports.init = function() { + //no-op +}; + + +/* Miller Cylindrical forward equations--mapping lat,long to x,y + ------------------------------------------------------------*/ +exports.forward = function(p) { + var lon = p.x; + var lat = p.y; + /* Forward equations + -----------------*/ + var dlon = adjust_lon(lon - this.long0); + var x = this.x0 + this.a * dlon; + var y = this.y0 + this.a * Math.log(Math.tan((Math.PI / 4) + (lat / 2.5))) * 1.25; + + p.x = x; + p.y = y; + return p; +}; + +/* Miller Cylindrical inverse equations--mapping x,y to lat/long + ------------------------------------------------------------*/ +exports.inverse = function(p) { + p.x -= this.x0; + p.y -= this.y0; + + var lon = adjust_lon(this.long0 + p.x / this.a); + var lat = 2.5 * (Math.atan(Math.exp(0.8 * p.y / this.a)) - Math.PI / 4); + + p.x = lon; + p.y = lat; + return p; +}; +exports.names = ["Miller_Cylindrical", "mill"]; + +},{"../common/adjust_lon":68}],118:[function(require,module,exports){ +var adjust_lon = require('../common/adjust_lon'); +var EPSLN = 1.0e-10; +exports.init = function() {}; + +/* Mollweide forward equations--mapping lat,long to x,y + ----------------------------------------------------*/ +exports.forward = function(p) { + + /* Forward equations + -----------------*/ + var lon = p.x; + var lat = p.y; + + var delta_lon = adjust_lon(lon - this.long0); + var theta = lat; + var con = Math.PI * Math.sin(lat); + + /* Iterate using the Newton-Raphson method to find theta + -----------------------------------------------------*/ + for (var i = 0; true; i++) { + var delta_theta = -(theta + Math.sin(theta) - con) / (1 + Math.cos(theta)); + theta += delta_theta; + if (Math.abs(delta_theta) < EPSLN) { + break; + } + } + theta /= 2; + + /* If the latitude is 90 deg, force the x coordinate to be "0 + false easting" + this is done here because of precision problems with "cos(theta)" + --------------------------------------------------------------------------*/ + if (Math.PI / 2 - Math.abs(lat) < EPSLN) { + delta_lon = 0; + } + var x = 0.900316316158 * this.a * delta_lon * Math.cos(theta) + this.x0; + var y = 1.4142135623731 * this.a * Math.sin(theta) + this.y0; + + p.x = x; + p.y = y; + return p; +}; + +exports.inverse = function(p) { + var theta; + var arg; + + /* Inverse equations + -----------------*/ + p.x -= this.x0; + p.y -= this.y0; + arg = p.y / (1.4142135623731 * this.a); + + /* Because of division by zero problems, 'arg' can not be 1. Therefore + a number very close to one is used instead. + -------------------------------------------------------------------*/ + if (Math.abs(arg) > 0.999999999999) { + arg = 0.999999999999; + } + theta = Math.asin(arg); + var lon = adjust_lon(this.long0 + (p.x / (0.900316316158 * this.a * Math.cos(theta)))); + if (lon < (-Math.PI)) { + lon = -Math.PI; + } + if (lon > Math.PI) { + lon = Math.PI; + } + arg = (2 * theta + Math.sin(2 * theta)) / Math.PI; + if (Math.abs(arg) > 1) { + arg = 1; + } + var lat = Math.asin(arg); + + p.x = lon; + p.y = lat; + return p; +}; +exports.names = ["Mollweide", "moll"]; + +},{"../common/adjust_lon":68}],119:[function(require,module,exports){ +var SEC_TO_RAD = 4.84813681109535993589914102357e-6; +/* + reference + Department of Land and Survey Technical Circular 1973/32 + http://www.linz.govt.nz/docs/miscellaneous/nz-map-definition.pdf + OSG Technical Report 4.1 + http://www.linz.govt.nz/docs/miscellaneous/nzmg.pdf + */ + +/** + * iterations: Number of iterations to refine inverse transform. + * 0 -> km accuracy + * 1 -> m accuracy -- suitable for most mapping applications + * 2 -> mm accuracy + */ +exports.iterations = 1; + +exports.init = function() { + this.A = []; + this.A[1] = 0.6399175073; + this.A[2] = -0.1358797613; + this.A[3] = 0.063294409; + this.A[4] = -0.02526853; + this.A[5] = 0.0117879; + this.A[6] = -0.0055161; + this.A[7] = 0.0026906; + this.A[8] = -0.001333; + this.A[9] = 0.00067; + this.A[10] = -0.00034; + + this.B_re = []; + this.B_im = []; + this.B_re[1] = 0.7557853228; + this.B_im[1] = 0; + this.B_re[2] = 0.249204646; + this.B_im[2] = 0.003371507; + this.B_re[3] = -0.001541739; + this.B_im[3] = 0.041058560; + this.B_re[4] = -0.10162907; + this.B_im[4] = 0.01727609; + this.B_re[5] = -0.26623489; + this.B_im[5] = -0.36249218; + this.B_re[6] = -0.6870983; + this.B_im[6] = -1.1651967; + + this.C_re = []; + this.C_im = []; + this.C_re[1] = 1.3231270439; + this.C_im[1] = 0; + this.C_re[2] = -0.577245789; + this.C_im[2] = -0.007809598; + this.C_re[3] = 0.508307513; + this.C_im[3] = -0.112208952; + this.C_re[4] = -0.15094762; + this.C_im[4] = 0.18200602; + this.C_re[5] = 1.01418179; + this.C_im[5] = 1.64497696; + this.C_re[6] = 1.9660549; + this.C_im[6] = 2.5127645; + + this.D = []; + this.D[1] = 1.5627014243; + this.D[2] = 0.5185406398; + this.D[3] = -0.03333098; + this.D[4] = -0.1052906; + this.D[5] = -0.0368594; + this.D[6] = 0.007317; + this.D[7] = 0.01220; + this.D[8] = 0.00394; + this.D[9] = -0.0013; +}; + +/** + New Zealand Map Grid Forward - long/lat to x/y + long/lat in radians + */ +exports.forward = function(p) { + var n; + var lon = p.x; + var lat = p.y; + + var delta_lat = lat - this.lat0; + var delta_lon = lon - this.long0; + + // 1. Calculate d_phi and d_psi ... // and d_lambda + // For this algorithm, delta_latitude is in seconds of arc x 10-5, so we need to scale to those units. Longitude is radians. + var d_phi = delta_lat / SEC_TO_RAD * 1E-5; + var d_lambda = delta_lon; + var d_phi_n = 1; // d_phi^0 + + var d_psi = 0; + for (n = 1; n <= 10; n++) { + d_phi_n = d_phi_n * d_phi; + d_psi = d_psi + this.A[n] * d_phi_n; + } + + // 2. Calculate theta + var th_re = d_psi; + var th_im = d_lambda; + + // 3. Calculate z + var th_n_re = 1; + var th_n_im = 0; // theta^0 + var th_n_re1; + var th_n_im1; + + var z_re = 0; + var z_im = 0; + for (n = 1; n <= 6; n++) { + th_n_re1 = th_n_re * th_re - th_n_im * th_im; + th_n_im1 = th_n_im * th_re + th_n_re * th_im; + th_n_re = th_n_re1; + th_n_im = th_n_im1; + z_re = z_re + this.B_re[n] * th_n_re - this.B_im[n] * th_n_im; + z_im = z_im + this.B_im[n] * th_n_re + this.B_re[n] * th_n_im; + } + + // 4. Calculate easting and northing + p.x = (z_im * this.a) + this.x0; + p.y = (z_re * this.a) + this.y0; + + return p; +}; + + +/** + New Zealand Map Grid Inverse - x/y to long/lat + */ +exports.inverse = function(p) { + var n; + var x = p.x; + var y = p.y; + + var delta_x = x - this.x0; + var delta_y = y - this.y0; + + // 1. Calculate z + var z_re = delta_y / this.a; + var z_im = delta_x / this.a; + + // 2a. Calculate theta - first approximation gives km accuracy + var z_n_re = 1; + var z_n_im = 0; // z^0 + var z_n_re1; + var z_n_im1; + + var th_re = 0; + var th_im = 0; + for (n = 1; n <= 6; n++) { + z_n_re1 = z_n_re * z_re - z_n_im * z_im; + z_n_im1 = z_n_im * z_re + z_n_re * z_im; + z_n_re = z_n_re1; + z_n_im = z_n_im1; + th_re = th_re + this.C_re[n] * z_n_re - this.C_im[n] * z_n_im; + th_im = th_im + this.C_im[n] * z_n_re + this.C_re[n] * z_n_im; + } + + // 2b. Iterate to refine the accuracy of the calculation + // 0 iterations gives km accuracy + // 1 iteration gives m accuracy -- good enough for most mapping applications + // 2 iterations bives mm accuracy + for (var i = 0; i < this.iterations; i++) { + var th_n_re = th_re; + var th_n_im = th_im; + var th_n_re1; + var th_n_im1; + + var num_re = z_re; + var num_im = z_im; + for (n = 2; n <= 6; n++) { + th_n_re1 = th_n_re * th_re - th_n_im * th_im; + th_n_im1 = th_n_im * th_re + th_n_re * th_im; + th_n_re = th_n_re1; + th_n_im = th_n_im1; + num_re = num_re + (n - 1) * (this.B_re[n] * th_n_re - this.B_im[n] * th_n_im); + num_im = num_im + (n - 1) * (this.B_im[n] * th_n_re + this.B_re[n] * th_n_im); + } + + th_n_re = 1; + th_n_im = 0; + var den_re = this.B_re[1]; + var den_im = this.B_im[1]; + for (n = 2; n <= 6; n++) { + th_n_re1 = th_n_re * th_re - th_n_im * th_im; + th_n_im1 = th_n_im * th_re + th_n_re * th_im; + th_n_re = th_n_re1; + th_n_im = th_n_im1; + den_re = den_re + n * (this.B_re[n] * th_n_re - this.B_im[n] * th_n_im); + den_im = den_im + n * (this.B_im[n] * th_n_re + this.B_re[n] * th_n_im); + } + + // Complex division + var den2 = den_re * den_re + den_im * den_im; + th_re = (num_re * den_re + num_im * den_im) / den2; + th_im = (num_im * den_re - num_re * den_im) / den2; + } + + // 3. Calculate d_phi ... // and d_lambda + var d_psi = th_re; + var d_lambda = th_im; + var d_psi_n = 1; // d_psi^0 + + var d_phi = 0; + for (n = 1; n <= 9; n++) { + d_psi_n = d_psi_n * d_psi; + d_phi = d_phi + this.D[n] * d_psi_n; + } + + // 4. Calculate latitude and longitude + // d_phi is calcuated in second of arc * 10^-5, so we need to scale back to radians. d_lambda is in radians. + var lat = this.lat0 + (d_phi * SEC_TO_RAD * 1E5); + var lon = this.long0 + d_lambda; + + p.x = lon; + p.y = lat; + + return p; +}; +exports.names = ["New_Zealand_Map_Grid", "nzmg"]; +},{}],120:[function(require,module,exports){ +var tsfnz = require('../common/tsfnz'); +var adjust_lon = require('../common/adjust_lon'); +var phi2z = require('../common/phi2z'); +var HALF_PI = Math.PI/2; +var FORTPI = Math.PI/4; +var EPSLN = 1.0e-10; + +/* Initialize the Oblique Mercator projection + ------------------------------------------*/ +exports.init = function() { + this.no_off = this.no_off || false; + this.no_rot = this.no_rot || false; + + if (isNaN(this.k0)) { + this.k0 = 1; + } + var sinlat = Math.sin(this.lat0); + var coslat = Math.cos(this.lat0); + var con = this.e * sinlat; + + this.bl = Math.sqrt(1 + this.es / (1 - this.es) * Math.pow(coslat, 4)); + this.al = this.a * this.bl * this.k0 * Math.sqrt(1 - this.es) / (1 - con * con); + var t0 = tsfnz(this.e, this.lat0, sinlat); + var dl = this.bl / coslat * Math.sqrt((1 - this.es) / (1 - con * con)); + if (dl * dl < 1) { + dl = 1; + } + var fl; + var gl; + if (!isNaN(this.longc)) { + //Central point and azimuth method + + if (this.lat0 >= 0) { + fl = dl + Math.sqrt(dl * dl - 1); + } + else { + fl = dl - Math.sqrt(dl * dl - 1); + } + this.el = fl * Math.pow(t0, this.bl); + gl = 0.5 * (fl - 1 / fl); + this.gamma0 = Math.asin(Math.sin(this.alpha) / dl); + this.long0 = this.longc - Math.asin(gl * Math.tan(this.gamma0)) / this.bl; + + } + else { + //2 points method + var t1 = tsfnz(this.e, this.lat1, Math.sin(this.lat1)); + var t2 = tsfnz(this.e, this.lat2, Math.sin(this.lat2)); + if (this.lat0 >= 0) { + this.el = (dl + Math.sqrt(dl * dl - 1)) * Math.pow(t0, this.bl); + } + else { + this.el = (dl - Math.sqrt(dl * dl - 1)) * Math.pow(t0, this.bl); + } + var hl = Math.pow(t1, this.bl); + var ll = Math.pow(t2, this.bl); + fl = this.el / hl; + gl = 0.5 * (fl - 1 / fl); + var jl = (this.el * this.el - ll * hl) / (this.el * this.el + ll * hl); + var pl = (ll - hl) / (ll + hl); + var dlon12 = adjust_lon(this.long1 - this.long2); + this.long0 = 0.5 * (this.long1 + this.long2) - Math.atan(jl * Math.tan(0.5 * this.bl * (dlon12)) / pl) / this.bl; + this.long0 = adjust_lon(this.long0); + var dlon10 = adjust_lon(this.long1 - this.long0); + this.gamma0 = Math.atan(Math.sin(this.bl * (dlon10)) / gl); + this.alpha = Math.asin(dl * Math.sin(this.gamma0)); + } + + if (this.no_off) { + this.uc = 0; + } + else { + if (this.lat0 >= 0) { + this.uc = this.al / this.bl * Math.atan2(Math.sqrt(dl * dl - 1), Math.cos(this.alpha)); + } + else { + this.uc = -1 * this.al / this.bl * Math.atan2(Math.sqrt(dl * dl - 1), Math.cos(this.alpha)); + } + } + +}; + + +/* Oblique Mercator forward equations--mapping lat,long to x,y + ----------------------------------------------------------*/ +exports.forward = function(p) { + var lon = p.x; + var lat = p.y; + var dlon = adjust_lon(lon - this.long0); + var us, vs; + var con; + if (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN) { + if (lat > 0) { + con = -1; + } + else { + con = 1; + } + vs = this.al / this.bl * Math.log(Math.tan(FORTPI + con * this.gamma0 * 0.5)); + us = -1 * con * HALF_PI * this.al / this.bl; + } + else { + var t = tsfnz(this.e, lat, Math.sin(lat)); + var ql = this.el / Math.pow(t, this.bl); + var sl = 0.5 * (ql - 1 / ql); + var tl = 0.5 * (ql + 1 / ql); + var vl = Math.sin(this.bl * (dlon)); + var ul = (sl * Math.sin(this.gamma0) - vl * Math.cos(this.gamma0)) / tl; + if (Math.abs(Math.abs(ul) - 1) <= EPSLN) { + vs = Number.POSITIVE_INFINITY; + } + else { + vs = 0.5 * this.al * Math.log((1 - ul) / (1 + ul)) / this.bl; + } + if (Math.abs(Math.cos(this.bl * (dlon))) <= EPSLN) { + us = this.al * this.bl * (dlon); + } + else { + us = this.al * Math.atan2(sl * Math.cos(this.gamma0) + vl * Math.sin(this.gamma0), Math.cos(this.bl * dlon)) / this.bl; + } + } + + if (this.no_rot) { + p.x = this.x0 + us; + p.y = this.y0 + vs; + } + else { + + us -= this.uc; + p.x = this.x0 + vs * Math.cos(this.alpha) + us * Math.sin(this.alpha); + p.y = this.y0 + us * Math.cos(this.alpha) - vs * Math.sin(this.alpha); + } + return p; +}; + +exports.inverse = function(p) { + var us, vs; + if (this.no_rot) { + vs = p.y - this.y0; + us = p.x - this.x0; + } + else { + vs = (p.x - this.x0) * Math.cos(this.alpha) - (p.y - this.y0) * Math.sin(this.alpha); + us = (p.y - this.y0) * Math.cos(this.alpha) + (p.x - this.x0) * Math.sin(this.alpha); + us += this.uc; + } + var qp = Math.exp(-1 * this.bl * vs / this.al); + var sp = 0.5 * (qp - 1 / qp); + var tp = 0.5 * (qp + 1 / qp); + var vp = Math.sin(this.bl * us / this.al); + var up = (vp * Math.cos(this.gamma0) + sp * Math.sin(this.gamma0)) / tp; + var ts = Math.pow(this.el / Math.sqrt((1 + up) / (1 - up)), 1 / this.bl); + if (Math.abs(up - 1) < EPSLN) { + p.x = this.long0; + p.y = HALF_PI; + } + else if (Math.abs(up + 1) < EPSLN) { + p.x = this.long0; + p.y = -1 * HALF_PI; + } + else { + p.y = phi2z(this.e, ts); + p.x = adjust_lon(this.long0 - Math.atan2(sp * Math.cos(this.gamma0) - vp * Math.sin(this.gamma0), Math.cos(this.bl * us / this.al)) / this.bl); + } + return p; +}; + +exports.names = ["Hotine_Oblique_Mercator", "Hotine Oblique Mercator", "Hotine_Oblique_Mercator_Azimuth_Natural_Origin", "Hotine_Oblique_Mercator_Azimuth_Center", "omerc"]; +},{"../common/adjust_lon":68,"../common/phi2z":79,"../common/tsfnz":87}],121:[function(require,module,exports){ +var e0fn = require('../common/e0fn'); +var e1fn = require('../common/e1fn'); +var e2fn = require('../common/e2fn'); +var e3fn = require('../common/e3fn'); +var adjust_lon = require('../common/adjust_lon'); +var adjust_lat = require('../common/adjust_lat'); +var mlfn = require('../common/mlfn'); +var EPSLN = 1.0e-10; +var gN = require('../common/gN'); +var MAX_ITER = 20; +exports.init = function() { + /* Place parameters in static storage for common use + -------------------------------------------------*/ + this.temp = this.b / this.a; + this.es = 1 - Math.pow(this.temp, 2); // devait etre dans tmerc.js mais n y est pas donc je commente sinon retour de valeurs nulles + this.e = Math.sqrt(this.es); + this.e0 = e0fn(this.es); + this.e1 = e1fn(this.es); + this.e2 = e2fn(this.es); + this.e3 = e3fn(this.es); + this.ml0 = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0); //si que des zeros le calcul ne se fait pas +}; + + +/* Polyconic forward equations--mapping lat,long to x,y + ---------------------------------------------------*/ +exports.forward = function(p) { + var lon = p.x; + var lat = p.y; + var x, y, el; + var dlon = adjust_lon(lon - this.long0); + el = dlon * Math.sin(lat); + if (this.sphere) { + if (Math.abs(lat) <= EPSLN) { + x = this.a * dlon; + y = -1 * this.a * this.lat0; + } + else { + x = this.a * Math.sin(el) / Math.tan(lat); + y = this.a * (adjust_lat(lat - this.lat0) + (1 - Math.cos(el)) / Math.tan(lat)); + } + } + else { + if (Math.abs(lat) <= EPSLN) { + x = this.a * dlon; + y = -1 * this.ml0; + } + else { + var nl = gN(this.a, this.e, Math.sin(lat)) / Math.tan(lat); + x = nl * Math.sin(el); + y = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, lat) - this.ml0 + nl * (1 - Math.cos(el)); + } + + } + p.x = x + this.x0; + p.y = y + this.y0; + return p; +}; + + +/* Inverse equations + -----------------*/ +exports.inverse = function(p) { + var lon, lat, x, y, i; + var al, bl; + var phi, dphi; + x = p.x - this.x0; + y = p.y - this.y0; + + if (this.sphere) { + if (Math.abs(y + this.a * this.lat0) <= EPSLN) { + lon = adjust_lon(x / this.a + this.long0); + lat = 0; + } + else { + al = this.lat0 + y / this.a; + bl = x * x / this.a / this.a + al * al; + phi = al; + var tanphi; + for (i = MAX_ITER; i; --i) { + tanphi = Math.tan(phi); + dphi = -1 * (al * (phi * tanphi + 1) - phi - 0.5 * (phi * phi + bl) * tanphi) / ((phi - al) / tanphi - 1); + phi += dphi; + if (Math.abs(dphi) <= EPSLN) { + lat = phi; + break; + } + } + lon = adjust_lon(this.long0 + (Math.asin(x * Math.tan(phi) / this.a)) / Math.sin(lat)); + } + } + else { + if (Math.abs(y + this.ml0) <= EPSLN) { + lat = 0; + lon = adjust_lon(this.long0 + x / this.a); + } + else { + + al = (this.ml0 + y) / this.a; + bl = x * x / this.a / this.a + al * al; + phi = al; + var cl, mln, mlnp, ma; + var con; + for (i = MAX_ITER; i; --i) { + con = this.e * Math.sin(phi); + cl = Math.sqrt(1 - con * con) * Math.tan(phi); + mln = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, phi); + mlnp = this.e0 - 2 * this.e1 * Math.cos(2 * phi) + 4 * this.e2 * Math.cos(4 * phi) - 6 * this.e3 * Math.cos(6 * phi); + ma = mln / this.a; + dphi = (al * (cl * ma + 1) - ma - 0.5 * cl * (ma * ma + bl)) / (this.es * Math.sin(2 * phi) * (ma * ma + bl - 2 * al * ma) / (4 * cl) + (al - ma) * (cl * mlnp - 2 / Math.sin(2 * phi)) - mlnp); + phi -= dphi; + if (Math.abs(dphi) <= EPSLN) { + lat = phi; + break; + } + } + + //lat=phi4z(this.e,this.e0,this.e1,this.e2,this.e3,al,bl,0,0); + cl = Math.sqrt(1 - this.es * Math.pow(Math.sin(lat), 2)) * Math.tan(lat); + lon = adjust_lon(this.long0 + Math.asin(x * cl / this.a) / Math.sin(lat)); + } + } + + p.x = lon; + p.y = lat; + return p; +}; +exports.names = ["Polyconic", "poly"]; +},{"../common/adjust_lat":67,"../common/adjust_lon":68,"../common/e0fn":70,"../common/e1fn":71,"../common/e2fn":72,"../common/e3fn":73,"../common/gN":74,"../common/mlfn":77}],122:[function(require,module,exports){ +var adjust_lon = require('../common/adjust_lon'); +var adjust_lat = require('../common/adjust_lat'); +var pj_enfn = require('../common/pj_enfn'); +var MAX_ITER = 20; +var pj_mlfn = require('../common/pj_mlfn'); +var pj_inv_mlfn = require('../common/pj_inv_mlfn'); +var HALF_PI = Math.PI/2; +var EPSLN = 1.0e-10; +var asinz = require('../common/asinz'); +exports.init = function() { + /* Place parameters in static storage for common use + -------------------------------------------------*/ + + + if (!this.sphere) { + this.en = pj_enfn(this.es); + } + else { + this.n = 1; + this.m = 0; + this.es = 0; + this.C_y = Math.sqrt((this.m + 1) / this.n); + this.C_x = this.C_y / (this.m + 1); + } + +}; + +/* Sinusoidal forward equations--mapping lat,long to x,y + -----------------------------------------------------*/ +exports.forward = function(p) { + var x, y; + var lon = p.x; + var lat = p.y; + /* Forward equations + -----------------*/ + lon = adjust_lon(lon - this.long0); + + if (this.sphere) { + if (!this.m) { + lat = this.n !== 1 ? Math.asin(this.n * Math.sin(lat)) : lat; + } + else { + var k = this.n * Math.sin(lat); + for (var i = MAX_ITER; i; --i) { + var V = (this.m * lat + Math.sin(lat) - k) / (this.m + Math.cos(lat)); + lat -= V; + if (Math.abs(V) < EPSLN) { + break; + } + } + } + x = this.a * this.C_x * lon * (this.m + Math.cos(lat)); + y = this.a * this.C_y * lat; + + } + else { + + var s = Math.sin(lat); + var c = Math.cos(lat); + y = this.a * pj_mlfn(lat, s, c, this.en); + x = this.a * lon * c / Math.sqrt(1 - this.es * s * s); + } + + p.x = x; + p.y = y; + return p; +}; + +exports.inverse = function(p) { + var lat, temp, lon, s; + + p.x -= this.x0; + lon = p.x / this.a; + p.y -= this.y0; + lat = p.y / this.a; + + if (this.sphere) { + lat /= this.C_y; + lon = lon / (this.C_x * (this.m + Math.cos(lat))); + if (this.m) { + lat = asinz((this.m * lat + Math.sin(lat)) / this.n); + } + else if (this.n !== 1) { + lat = asinz(Math.sin(lat) / this.n); + } + lon = adjust_lon(lon + this.long0); + lat = adjust_lat(lat); + } + else { + lat = pj_inv_mlfn(p.y / this.a, this.es, this.en); + s = Math.abs(lat); + if (s < HALF_PI) { + s = Math.sin(lat); + temp = this.long0 + p.x * Math.sqrt(1 - this.es * s * s) / (this.a * Math.cos(lat)); + //temp = this.long0 + p.x / (this.a * Math.cos(lat)); + lon = adjust_lon(temp); + } + else if ((s - EPSLN) < HALF_PI) { + lon = this.long0; + } + } + p.x = lon; + p.y = lat; + return p; +}; +exports.names = ["Sinusoidal", "sinu"]; +},{"../common/adjust_lat":67,"../common/adjust_lon":68,"../common/asinz":69,"../common/pj_enfn":80,"../common/pj_inv_mlfn":81,"../common/pj_mlfn":82}],123:[function(require,module,exports){ +/* + references: + Formules et constantes pour le Calcul pour la + projection cylindrique conforme à axe oblique et pour la transformation entre + des systèmes de référence. + http://www.swisstopo.admin.ch/internet/swisstopo/fr/home/topics/survey/sys/refsys/switzerland.parsysrelated1.31216.downloadList.77004.DownloadFile.tmp/swissprojectionfr.pdf + */ +exports.init = function() { + var phy0 = this.lat0; + this.lambda0 = this.long0; + var sinPhy0 = Math.sin(phy0); + var semiMajorAxis = this.a; + var invF = this.rf; + var flattening = 1 / invF; + var e2 = 2 * flattening - Math.pow(flattening, 2); + var e = this.e = Math.sqrt(e2); + this.R = this.k0 * semiMajorAxis * Math.sqrt(1 - e2) / (1 - e2 * Math.pow(sinPhy0, 2)); + this.alpha = Math.sqrt(1 + e2 / (1 - e2) * Math.pow(Math.cos(phy0), 4)); + this.b0 = Math.asin(sinPhy0 / this.alpha); + var k1 = Math.log(Math.tan(Math.PI / 4 + this.b0 / 2)); + var k2 = Math.log(Math.tan(Math.PI / 4 + phy0 / 2)); + var k3 = Math.log((1 + e * sinPhy0) / (1 - e * sinPhy0)); + this.K = k1 - this.alpha * k2 + this.alpha * e / 2 * k3; +}; + + +exports.forward = function(p) { + var Sa1 = Math.log(Math.tan(Math.PI / 4 - p.y / 2)); + var Sa2 = this.e / 2 * Math.log((1 + this.e * Math.sin(p.y)) / (1 - this.e * Math.sin(p.y))); + var S = -this.alpha * (Sa1 + Sa2) + this.K; + + // spheric latitude + var b = 2 * (Math.atan(Math.exp(S)) - Math.PI / 4); + + // spheric longitude + var I = this.alpha * (p.x - this.lambda0); + + // psoeudo equatorial rotation + var rotI = Math.atan(Math.sin(I) / (Math.sin(this.b0) * Math.tan(b) + Math.cos(this.b0) * Math.cos(I))); + + var rotB = Math.asin(Math.cos(this.b0) * Math.sin(b) - Math.sin(this.b0) * Math.cos(b) * Math.cos(I)); + + p.y = this.R / 2 * Math.log((1 + Math.sin(rotB)) / (1 - Math.sin(rotB))) + this.y0; + p.x = this.R * rotI + this.x0; + return p; +}; + +exports.inverse = function(p) { + var Y = p.x - this.x0; + var X = p.y - this.y0; + + var rotI = Y / this.R; + var rotB = 2 * (Math.atan(Math.exp(X / this.R)) - Math.PI / 4); + + var b = Math.asin(Math.cos(this.b0) * Math.sin(rotB) + Math.sin(this.b0) * Math.cos(rotB) * Math.cos(rotI)); + var I = Math.atan(Math.sin(rotI) / (Math.cos(this.b0) * Math.cos(rotI) - Math.sin(this.b0) * Math.tan(rotB))); + + var lambda = this.lambda0 + I / this.alpha; + + var S = 0; + var phy = b; + var prevPhy = -1000; + var iteration = 0; + while (Math.abs(phy - prevPhy) > 0.0000001) { + if (++iteration > 20) { + //...reportError("omercFwdInfinity"); + return; + } + //S = Math.log(Math.tan(Math.PI / 4 + phy / 2)); + S = 1 / this.alpha * (Math.log(Math.tan(Math.PI / 4 + b / 2)) - this.K) + this.e * Math.log(Math.tan(Math.PI / 4 + Math.asin(this.e * Math.sin(phy)) / 2)); + prevPhy = phy; + phy = 2 * Math.atan(Math.exp(S)) - Math.PI / 2; + } + + p.x = lambda; + p.y = phy; + return p; +}; + +exports.names = ["somerc"]; + +},{}],124:[function(require,module,exports){ +var HALF_PI = Math.PI/2; +var EPSLN = 1.0e-10; +var sign = require('../common/sign'); +var msfnz = require('../common/msfnz'); +var tsfnz = require('../common/tsfnz'); +var phi2z = require('../common/phi2z'); +var adjust_lon = require('../common/adjust_lon'); +exports.ssfn_ = function(phit, sinphi, eccen) { + sinphi *= eccen; + return (Math.tan(0.5 * (HALF_PI + phit)) * Math.pow((1 - sinphi) / (1 + sinphi), 0.5 * eccen)); +}; + +exports.init = function() { + this.coslat0 = Math.cos(this.lat0); + this.sinlat0 = Math.sin(this.lat0); + if (this.sphere) { + if (this.k0 === 1 && !isNaN(this.lat_ts) && Math.abs(this.coslat0) <= EPSLN) { + this.k0 = 0.5 * (1 + sign(this.lat0) * Math.sin(this.lat_ts)); + } + } + else { + if (Math.abs(this.coslat0) <= EPSLN) { + if (this.lat0 > 0) { + //North pole + //trace('stere:north pole'); + this.con = 1; + } + else { + //South pole + //trace('stere:south pole'); + this.con = -1; + } + } + this.cons = Math.sqrt(Math.pow(1 + this.e, 1 + this.e) * Math.pow(1 - this.e, 1 - this.e)); + if (this.k0 === 1 && !isNaN(this.lat_ts) && Math.abs(this.coslat0) <= EPSLN) { + this.k0 = 0.5 * this.cons * msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts)) / tsfnz(this.e, this.con * this.lat_ts, this.con * Math.sin(this.lat_ts)); + } + this.ms1 = msfnz(this.e, this.sinlat0, this.coslat0); + this.X0 = 2 * Math.atan(this.ssfn_(this.lat0, this.sinlat0, this.e)) - HALF_PI; + this.cosX0 = Math.cos(this.X0); + this.sinX0 = Math.sin(this.X0); + } +}; + +// Stereographic forward equations--mapping lat,long to x,y +exports.forward = function(p) { + var lon = p.x; + var lat = p.y; + var sinlat = Math.sin(lat); + var coslat = Math.cos(lat); + var A, X, sinX, cosX, ts, rh; + var dlon = adjust_lon(lon - this.long0); + + if (Math.abs(Math.abs(lon - this.long0) - Math.PI) <= EPSLN && Math.abs(lat + this.lat0) <= EPSLN) { + //case of the origine point + //trace('stere:this is the origin point'); + p.x = NaN; + p.y = NaN; + return p; + } + if (this.sphere) { + //trace('stere:sphere case'); + A = 2 * this.k0 / (1 + this.sinlat0 * sinlat + this.coslat0 * coslat * Math.cos(dlon)); + p.x = this.a * A * coslat * Math.sin(dlon) + this.x0; + p.y = this.a * A * (this.coslat0 * sinlat - this.sinlat0 * coslat * Math.cos(dlon)) + this.y0; + return p; + } + else { + X = 2 * Math.atan(this.ssfn_(lat, sinlat, this.e)) - HALF_PI; + cosX = Math.cos(X); + sinX = Math.sin(X); + if (Math.abs(this.coslat0) <= EPSLN) { + ts = tsfnz(this.e, lat * this.con, this.con * sinlat); + rh = 2 * this.a * this.k0 * ts / this.cons; + p.x = this.x0 + rh * Math.sin(lon - this.long0); + p.y = this.y0 - this.con * rh * Math.cos(lon - this.long0); + //trace(p.toString()); + return p; + } + else if (Math.abs(this.sinlat0) < EPSLN) { + //Eq + //trace('stere:equateur'); + A = 2 * this.a * this.k0 / (1 + cosX * Math.cos(dlon)); + p.y = A * sinX; + } + else { + //other case + //trace('stere:normal case'); + A = 2 * this.a * this.k0 * this.ms1 / (this.cosX0 * (1 + this.sinX0 * sinX + this.cosX0 * cosX * Math.cos(dlon))); + p.y = A * (this.cosX0 * sinX - this.sinX0 * cosX * Math.cos(dlon)) + this.y0; + } + p.x = A * cosX * Math.sin(dlon) + this.x0; + } + //trace(p.toString()); + return p; +}; + + +//* Stereographic inverse equations--mapping x,y to lat/long +exports.inverse = function(p) { + p.x -= this.x0; + p.y -= this.y0; + var lon, lat, ts, ce, Chi; + var rh = Math.sqrt(p.x * p.x + p.y * p.y); + if (this.sphere) { + var c = 2 * Math.atan(rh / (0.5 * this.a * this.k0)); + lon = this.long0; + lat = this.lat0; + if (rh <= EPSLN) { + p.x = lon; + p.y = lat; + return p; + } + lat = Math.asin(Math.cos(c) * this.sinlat0 + p.y * Math.sin(c) * this.coslat0 / rh); + if (Math.abs(this.coslat0) < EPSLN) { + if (this.lat0 > 0) { + lon = adjust_lon(this.long0 + Math.atan2(p.x, - 1 * p.y)); + } + else { + lon = adjust_lon(this.long0 + Math.atan2(p.x, p.y)); + } + } + else { + lon = adjust_lon(this.long0 + Math.atan2(p.x * Math.sin(c), rh * this.coslat0 * Math.cos(c) - p.y * this.sinlat0 * Math.sin(c))); + } + p.x = lon; + p.y = lat; + return p; + } + else { + if (Math.abs(this.coslat0) <= EPSLN) { + if (rh <= EPSLN) { + lat = this.lat0; + lon = this.long0; + p.x = lon; + p.y = lat; + //trace(p.toString()); + return p; + } + p.x *= this.con; + p.y *= this.con; + ts = rh * this.cons / (2 * this.a * this.k0); + lat = this.con * phi2z(this.e, ts); + lon = this.con * adjust_lon(this.con * this.long0 + Math.atan2(p.x, - 1 * p.y)); + } + else { + ce = 2 * Math.atan(rh * this.cosX0 / (2 * this.a * this.k0 * this.ms1)); + lon = this.long0; + if (rh <= EPSLN) { + Chi = this.X0; + } + else { + Chi = Math.asin(Math.cos(ce) * this.sinX0 + p.y * Math.sin(ce) * this.cosX0 / rh); + lon = adjust_lon(this.long0 + Math.atan2(p.x * Math.sin(ce), rh * this.cosX0 * Math.cos(ce) - p.y * this.sinX0 * Math.sin(ce))); + } + lat = -1 * phi2z(this.e, Math.tan(0.5 * (HALF_PI + Chi))); + } + } + p.x = lon; + p.y = lat; + + //trace(p.toString()); + return p; + +}; +exports.names = ["stere", "Stereographic_South_Pole", "Polar Stereographic (variant B)"]; + +},{"../common/adjust_lon":68,"../common/msfnz":78,"../common/phi2z":79,"../common/sign":84,"../common/tsfnz":87}],125:[function(require,module,exports){ +var gauss = require('./gauss'); +var adjust_lon = require('../common/adjust_lon'); +exports.init = function() { + gauss.init.apply(this); + if (!this.rc) { + return; + } + this.sinc0 = Math.sin(this.phic0); + this.cosc0 = Math.cos(this.phic0); + this.R2 = 2 * this.rc; + if (!this.title) { + this.title = "Oblique Stereographic Alternative"; + } +}; + +exports.forward = function(p) { + var sinc, cosc, cosl, k; + p.x = adjust_lon(p.x - this.long0); + gauss.forward.apply(this, [p]); + sinc = Math.sin(p.y); + cosc = Math.cos(p.y); + cosl = Math.cos(p.x); + k = this.k0 * this.R2 / (1 + this.sinc0 * sinc + this.cosc0 * cosc * cosl); + p.x = k * cosc * Math.sin(p.x); + p.y = k * (this.cosc0 * sinc - this.sinc0 * cosc * cosl); + p.x = this.a * p.x + this.x0; + p.y = this.a * p.y + this.y0; + return p; +}; + +exports.inverse = function(p) { + var sinc, cosc, lon, lat, rho; + p.x = (p.x - this.x0) / this.a; + p.y = (p.y - this.y0) / this.a; + + p.x /= this.k0; + p.y /= this.k0; + if ((rho = Math.sqrt(p.x * p.x + p.y * p.y))) { + var c = 2 * Math.atan2(rho, this.R2); + sinc = Math.sin(c); + cosc = Math.cos(c); + lat = Math.asin(cosc * this.sinc0 + p.y * sinc * this.cosc0 / rho); + lon = Math.atan2(p.x * sinc, rho * this.cosc0 * cosc - p.y * this.sinc0 * sinc); + } + else { + lat = this.phic0; + lon = 0; + } + + p.x = lon; + p.y = lat; + gauss.inverse.apply(this, [p]); + p.x = adjust_lon(p.x + this.long0); + return p; +}; + +exports.names = ["Stereographic_North_Pole", "Oblique_Stereographic", "Polar_Stereographic", "sterea","Oblique Stereographic Alternative"]; + +},{"../common/adjust_lon":68,"./gauss":110}],126:[function(require,module,exports){ +var e0fn = require('../common/e0fn'); +var e1fn = require('../common/e1fn'); +var e2fn = require('../common/e2fn'); +var e3fn = require('../common/e3fn'); +var mlfn = require('../common/mlfn'); +var adjust_lon = require('../common/adjust_lon'); +var HALF_PI = Math.PI/2; +var EPSLN = 1.0e-10; +var sign = require('../common/sign'); +var asinz = require('../common/asinz'); + +exports.init = function() { + this.e0 = e0fn(this.es); + this.e1 = e1fn(this.es); + this.e2 = e2fn(this.es); + this.e3 = e3fn(this.es); + this.ml0 = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0); +}; + +/** + Transverse Mercator Forward - long/lat to x/y + long/lat in radians + */ +exports.forward = function(p) { + var lon = p.x; + var lat = p.y; + + var delta_lon = adjust_lon(lon - this.long0); + var con; + var x, y; + var sin_phi = Math.sin(lat); + var cos_phi = Math.cos(lat); + + if (this.sphere) { + var b = cos_phi * Math.sin(delta_lon); + if ((Math.abs(Math.abs(b) - 1)) < 0.0000000001) { + return (93); + } + else { + x = 0.5 * this.a * this.k0 * Math.log((1 + b) / (1 - b)); + con = Math.acos(cos_phi * Math.cos(delta_lon) / Math.sqrt(1 - b * b)); + if (lat < 0) { + con = -con; + } + y = this.a * this.k0 * (con - this.lat0); + } + } + else { + var al = cos_phi * delta_lon; + var als = Math.pow(al, 2); + var c = this.ep2 * Math.pow(cos_phi, 2); + var tq = Math.tan(lat); + var t = Math.pow(tq, 2); + con = 1 - this.es * Math.pow(sin_phi, 2); + var n = this.a / Math.sqrt(con); + var ml = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, lat); + + x = this.k0 * n * al * (1 + als / 6 * (1 - t + c + als / 20 * (5 - 18 * t + Math.pow(t, 2) + 72 * c - 58 * this.ep2))) + this.x0; + y = this.k0 * (ml - this.ml0 + n * tq * (als * (0.5 + als / 24 * (5 - t + 9 * c + 4 * Math.pow(c, 2) + als / 30 * (61 - 58 * t + Math.pow(t, 2) + 600 * c - 330 * this.ep2))))) + this.y0; + + } + p.x = x; + p.y = y; + return p; +}; + +/** + Transverse Mercator Inverse - x/y to long/lat + */ +exports.inverse = function(p) { + var con, phi; + var delta_phi; + var i; + var max_iter = 6; + var lat, lon; + + if (this.sphere) { + var f = Math.exp(p.x / (this.a * this.k0)); + var g = 0.5 * (f - 1 / f); + var temp = this.lat0 + p.y / (this.a * this.k0); + var h = Math.cos(temp); + con = Math.sqrt((1 - h * h) / (1 + g * g)); + lat = asinz(con); + if (temp < 0) { + lat = -lat; + } + if ((g === 0) && (h === 0)) { + lon = this.long0; + } + else { + lon = adjust_lon(Math.atan2(g, h) + this.long0); + } + } + else { // ellipsoidal form + var x = p.x - this.x0; + var y = p.y - this.y0; + + con = (this.ml0 + y / this.k0) / this.a; + phi = con; + for (i = 0; true; i++) { + delta_phi = ((con + this.e1 * Math.sin(2 * phi) - this.e2 * Math.sin(4 * phi) + this.e3 * Math.sin(6 * phi)) / this.e0) - phi; + phi += delta_phi; + if (Math.abs(delta_phi) <= EPSLN) { + break; + } + if (i >= max_iter) { + return (95); + } + } // for() + if (Math.abs(phi) < HALF_PI) { + var sin_phi = Math.sin(phi); + var cos_phi = Math.cos(phi); + var tan_phi = Math.tan(phi); + var c = this.ep2 * Math.pow(cos_phi, 2); + var cs = Math.pow(c, 2); + var t = Math.pow(tan_phi, 2); + var ts = Math.pow(t, 2); + con = 1 - this.es * Math.pow(sin_phi, 2); + var n = this.a / Math.sqrt(con); + var r = n * (1 - this.es) / con; + var d = x / (n * this.k0); + var ds = Math.pow(d, 2); + lat = phi - (n * tan_phi * ds / r) * (0.5 - ds / 24 * (5 + 3 * t + 10 * c - 4 * cs - 9 * this.ep2 - ds / 30 * (61 + 90 * t + 298 * c + 45 * ts - 252 * this.ep2 - 3 * cs))); + lon = adjust_lon(this.long0 + (d * (1 - ds / 6 * (1 + 2 * t + c - ds / 20 * (5 - 2 * c + 28 * t - 3 * cs + 8 * this.ep2 + 24 * ts))) / cos_phi)); + } + else { + lat = HALF_PI * sign(y); + lon = this.long0; + } + } + p.x = lon; + p.y = lat; + return p; +}; +exports.names = ["Transverse_Mercator", "Transverse Mercator", "tmerc"]; + +},{"../common/adjust_lon":68,"../common/asinz":69,"../common/e0fn":70,"../common/e1fn":71,"../common/e2fn":72,"../common/e3fn":73,"../common/mlfn":77,"../common/sign":84}],127:[function(require,module,exports){ +var D2R = 0.01745329251994329577; +var tmerc = require('./tmerc'); +exports.dependsOn = 'tmerc'; +exports.init = function() { + if (!this.zone) { + return; + } + this.lat0 = 0; + this.long0 = ((6 * Math.abs(this.zone)) - 183) * D2R; + this.x0 = 500000; + this.y0 = this.utmSouth ? 10000000 : 0; + this.k0 = 0.9996; + + tmerc.init.apply(this); + this.forward = tmerc.forward; + this.inverse = tmerc.inverse; +}; +exports.names = ["Universal Transverse Mercator System", "utm"]; + +},{"./tmerc":126}],128:[function(require,module,exports){ +var adjust_lon = require('../common/adjust_lon'); +var HALF_PI = Math.PI/2; +var EPSLN = 1.0e-10; +var asinz = require('../common/asinz'); +/* Initialize the Van Der Grinten projection + ----------------------------------------*/ +exports.init = function() { + //this.R = 6370997; //Radius of earth + this.R = this.a; +}; + +exports.forward = function(p) { + + var lon = p.x; + var lat = p.y; + + /* Forward equations + -----------------*/ + var dlon = adjust_lon(lon - this.long0); + var x, y; + + if (Math.abs(lat) <= EPSLN) { + x = this.x0 + this.R * dlon; + y = this.y0; + } + var theta = asinz(2 * Math.abs(lat / Math.PI)); + if ((Math.abs(dlon) <= EPSLN) || (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN)) { + x = this.x0; + if (lat >= 0) { + y = this.y0 + Math.PI * this.R * Math.tan(0.5 * theta); + } + else { + y = this.y0 + Math.PI * this.R * -Math.tan(0.5 * theta); + } + // return(OK); + } + var al = 0.5 * Math.abs((Math.PI / dlon) - (dlon / Math.PI)); + var asq = al * al; + var sinth = Math.sin(theta); + var costh = Math.cos(theta); + + var g = costh / (sinth + costh - 1); + var gsq = g * g; + var m = g * (2 / sinth - 1); + var msq = m * m; + var con = Math.PI * this.R * (al * (g - msq) + Math.sqrt(asq * (g - msq) * (g - msq) - (msq + asq) * (gsq - msq))) / (msq + asq); + if (dlon < 0) { + con = -con; + } + x = this.x0 + con; + //con = Math.abs(con / (Math.PI * this.R)); + var q = asq + g; + con = Math.PI * this.R * (m * q - al * Math.sqrt((msq + asq) * (asq + 1) - q * q)) / (msq + asq); + if (lat >= 0) { + //y = this.y0 + Math.PI * this.R * Math.sqrt(1 - con * con - 2 * al * con); + y = this.y0 + con; + } + else { + //y = this.y0 - Math.PI * this.R * Math.sqrt(1 - con * con - 2 * al * con); + y = this.y0 - con; + } + p.x = x; + p.y = y; + return p; +}; + +/* Van Der Grinten inverse equations--mapping x,y to lat/long + ---------------------------------------------------------*/ +exports.inverse = function(p) { + var lon, lat; + var xx, yy, xys, c1, c2, c3; + var a1; + var m1; + var con; + var th1; + var d; + + /* inverse equations + -----------------*/ + p.x -= this.x0; + p.y -= this.y0; + con = Math.PI * this.R; + xx = p.x / con; + yy = p.y / con; + xys = xx * xx + yy * yy; + c1 = -Math.abs(yy) * (1 + xys); + c2 = c1 - 2 * yy * yy + xx * xx; + c3 = -2 * c1 + 1 + 2 * yy * yy + xys * xys; + d = yy * yy / c3 + (2 * c2 * c2 * c2 / c3 / c3 / c3 - 9 * c1 * c2 / c3 / c3) / 27; + a1 = (c1 - c2 * c2 / 3 / c3) / c3; + m1 = 2 * Math.sqrt(-a1 / 3); + con = ((3 * d) / a1) / m1; + if (Math.abs(con) > 1) { + if (con >= 0) { + con = 1; + } + else { + con = -1; + } + } + th1 = Math.acos(con) / 3; + if (p.y >= 0) { + lat = (-m1 * Math.cos(th1 + Math.PI / 3) - c2 / 3 / c3) * Math.PI; + } + else { + lat = -(-m1 * Math.cos(th1 + Math.PI / 3) - c2 / 3 / c3) * Math.PI; + } + + if (Math.abs(xx) < EPSLN) { + lon = this.long0; + } + else { + lon = adjust_lon(this.long0 + Math.PI * (xys - 1 + Math.sqrt(1 + 2 * (xx * xx - yy * yy) + xys * xys)) / 2 / xx); + } + + p.x = lon; + p.y = lat; + return p; +}; +exports.names = ["Van_der_Grinten_I", "VanDerGrinten", "vandg"]; +},{"../common/adjust_lon":68,"../common/asinz":69}],129:[function(require,module,exports){ +var D2R = 0.01745329251994329577; +var R2D = 57.29577951308232088; +var PJD_3PARAM = 1; +var PJD_7PARAM = 2; +var datum_transform = require('./datum_transform'); +var adjust_axis = require('./adjust_axis'); +var proj = require('./Proj'); +var toPoint = require('./common/toPoint'); +module.exports = function transform(source, dest, point) { + var wgs84; + if (Array.isArray(point)) { + point = toPoint(point); + } + function checkNotWGS(source, dest) { + return ((source.datum.datum_type === PJD_3PARAM || source.datum.datum_type === PJD_7PARAM) && dest.datumCode !== "WGS84"); + } + + // Workaround for datum shifts towgs84, if either source or destination projection is not wgs84 + if (source.datum && dest.datum && (checkNotWGS(source, dest) || checkNotWGS(dest, source))) { + wgs84 = new proj('WGS84'); + transform(source, wgs84, point); + source = wgs84; + } + // DGR, 2010/11/12 + if (source.axis !== "enu") { + adjust_axis(source, false, point); + } + // Transform source points to long/lat, if they aren't already. + if (source.projName === "longlat") { + point.x *= D2R; // convert degrees to radians + point.y *= D2R; + } + else { + if (source.to_meter) { + point.x *= source.to_meter; + point.y *= source.to_meter; + } + source.inverse(point); // Convert Cartesian to longlat + } + // Adjust for the prime meridian if necessary + if (source.from_greenwich) { + point.x += source.from_greenwich; + } + + // Convert datums if needed, and if possible. + point = datum_transform(source.datum, dest.datum, point); + + // Adjust for the prime meridian if necessary + if (dest.from_greenwich) { + point.x -= dest.from_greenwich; + } + + if (dest.projName === "longlat") { + // convert radians to decimal degrees + point.x *= R2D; + point.y *= R2D; + } + else { // else project + dest.forward(point); + if (dest.to_meter) { + point.x /= dest.to_meter; + point.y /= dest.to_meter; + } + } + + // DGR, 2010/11/12 + if (dest.axis !== "enu") { + adjust_axis(dest, true, point); + } + + return point; +}; +},{"./Proj":65,"./adjust_axis":66,"./common/toPoint":86,"./datum_transform":94}],130:[function(require,module,exports){ +var D2R = 0.01745329251994329577; +var extend = require('./extend'); + +function mapit(obj, key, v) { + obj[key] = v.map(function(aa) { + var o = {}; + sExpr(aa, o); + return o; + }).reduce(function(a, b) { + return extend(a, b); + }, {}); +} + +function sExpr(v, obj) { + var key; + if (!Array.isArray(v)) { + obj[v] = true; + return; + } + else { + key = v.shift(); + if (key === 'PARAMETER') { + key = v.shift(); + } + if (v.length === 1) { + if (Array.isArray(v[0])) { + obj[key] = {}; + sExpr(v[0], obj[key]); + } + else { + obj[key] = v[0]; + } + } + else if (!v.length) { + obj[key] = true; + } + else if (key === 'TOWGS84') { + obj[key] = v; + } + else { + obj[key] = {}; + if (['UNIT', 'PRIMEM', 'VERT_DATUM'].indexOf(key) > -1) { + obj[key] = { + name: v[0].toLowerCase(), + convert: v[1] + }; + if (v.length === 3) { + obj[key].auth = v[2]; + } + } + else if (key === 'SPHEROID') { + obj[key] = { + name: v[0], + a: v[1], + rf: v[2] + }; + if (v.length === 4) { + obj[key].auth = v[3]; + } + } + else if (['GEOGCS', 'GEOCCS', 'DATUM', 'VERT_CS', 'COMPD_CS', 'LOCAL_CS', 'FITTED_CS', 'LOCAL_DATUM'].indexOf(key) > -1) { + v[0] = ['name', v[0]]; + mapit(obj, key, v); + } + else if (v.every(function(aa) { + return Array.isArray(aa); + })) { + mapit(obj, key, v); + } + else { + sExpr(v, obj[key]); + } + } + } +} + +function rename(obj, params) { + var outName = params[0]; + var inName = params[1]; + if (!(outName in obj) && (inName in obj)) { + obj[outName] = obj[inName]; + if (params.length === 3) { + obj[outName] = params[2](obj[outName]); + } + } +} + +function d2r(input) { + return input * D2R; +} + +function cleanWKT(wkt) { + if (wkt.type === 'GEOGCS') { + wkt.projName = 'longlat'; + } + else if (wkt.type === 'LOCAL_CS') { + wkt.projName = 'identity'; + wkt.local = true; + } + else { + if (typeof wkt.PROJECTION === "object") { + wkt.projName = Object.keys(wkt.PROJECTION)[0]; + } + else { + wkt.projName = wkt.PROJECTION; + } + } + if (wkt.UNIT) { + wkt.units = wkt.UNIT.name.toLowerCase(); + if (wkt.units === 'metre') { + wkt.units = 'meter'; + } + if (wkt.UNIT.convert) { + wkt.to_meter = parseFloat(wkt.UNIT.convert, 10); + } + } + + if (wkt.GEOGCS) { + //if(wkt.GEOGCS.PRIMEM&&wkt.GEOGCS.PRIMEM.convert){ + // wkt.from_greenwich=wkt.GEOGCS.PRIMEM.convert*D2R; + //} + if (wkt.GEOGCS.DATUM) { + wkt.datumCode = wkt.GEOGCS.DATUM.name.toLowerCase(); + } + else { + wkt.datumCode = wkt.GEOGCS.name.toLowerCase(); + } + if (wkt.datumCode.slice(0, 2) === 'd_') { + wkt.datumCode = wkt.datumCode.slice(2); + } + if (wkt.datumCode === 'new_zealand_geodetic_datum_1949' || wkt.datumCode === 'new_zealand_1949') { + wkt.datumCode = 'nzgd49'; + } + if (wkt.datumCode === "wgs_1984") { + if (wkt.PROJECTION === 'Mercator_Auxiliary_Sphere') { + wkt.sphere = true; + } + wkt.datumCode = 'wgs84'; + } + if (wkt.datumCode.slice(-6) === '_ferro') { + wkt.datumCode = wkt.datumCode.slice(0, - 6); + } + if (wkt.datumCode.slice(-8) === '_jakarta') { + wkt.datumCode = wkt.datumCode.slice(0, - 8); + } + if (~wkt.datumCode.indexOf('belge')) { + wkt.datumCode = "rnb72"; + } + if (wkt.GEOGCS.DATUM && wkt.GEOGCS.DATUM.SPHEROID) { + wkt.ellps = wkt.GEOGCS.DATUM.SPHEROID.name.replace('_19', '').replace(/[Cc]larke\_18/, 'clrk'); + if (wkt.ellps.toLowerCase().slice(0, 13) === "international") { + wkt.ellps = 'intl'; + } + + wkt.a = wkt.GEOGCS.DATUM.SPHEROID.a; + wkt.rf = parseFloat(wkt.GEOGCS.DATUM.SPHEROID.rf, 10); + } + if (~wkt.datumCode.indexOf('osgb_1936')) { + wkt.datumCode = "osgb36"; + } + } + if (wkt.b && !isFinite(wkt.b)) { + wkt.b = wkt.a; + } + + function toMeter(input) { + var ratio = wkt.to_meter || 1; + return parseFloat(input, 10) * ratio; + } + var renamer = function(a) { + return rename(wkt, a); + }; + var list = [ + ['standard_parallel_1', 'Standard_Parallel_1'], + ['standard_parallel_2', 'Standard_Parallel_2'], + ['false_easting', 'False_Easting'], + ['false_northing', 'False_Northing'], + ['central_meridian', 'Central_Meridian'], + ['latitude_of_origin', 'Latitude_Of_Origin'], + ['latitude_of_origin', 'Central_Parallel'], + ['scale_factor', 'Scale_Factor'], + ['k0', 'scale_factor'], + ['latitude_of_center', 'Latitude_of_center'], + ['lat0', 'latitude_of_center', d2r], + ['longitude_of_center', 'Longitude_Of_Center'], + ['longc', 'longitude_of_center', d2r], + ['x0', 'false_easting', toMeter], + ['y0', 'false_northing', toMeter], + ['long0', 'central_meridian', d2r], + ['lat0', 'latitude_of_origin', d2r], + ['lat0', 'standard_parallel_1', d2r], + ['lat1', 'standard_parallel_1', d2r], + ['lat2', 'standard_parallel_2', d2r], + ['alpha', 'azimuth', d2r], + ['srsCode', 'name'] + ]; + list.forEach(renamer); + if (!wkt.long0 && wkt.longc && (wkt.projName === 'Albers_Conic_Equal_Area' || wkt.projName === "Lambert_Azimuthal_Equal_Area")) { + wkt.long0 = wkt.longc; + } + if (!wkt.lat_ts && wkt.lat1 && (wkt.projName === 'Stereographic_South_Pole' || wkt.projName === 'Polar Stereographic (variant B)')) { + wkt.lat0 = d2r(wkt.lat1 > 0 ? 90 : -90); + wkt.lat_ts = wkt.lat1; + } +} +module.exports = function(wkt, self) { + var lisp = JSON.parse(("," + wkt).replace(/\s*\,\s*([A-Z_0-9]+?)(\[)/g, ',["$1",').slice(1).replace(/\s*\,\s*([A-Z_0-9]+?)\]/g, ',"$1"]').replace(/,\["VERTCS".+/,'')); + var type = lisp.shift(); + var name = lisp.shift(); + lisp.unshift(['name', name]); + lisp.unshift(['type', type]); + lisp.unshift('output'); + var obj = {}; + sExpr(lisp, obj); + cleanWKT(obj.output); + return extend(self, obj.output); +}; + +},{"./extend":97}],131:[function(require,module,exports){ + + + +/** + * UTM zones are grouped, and assigned to one of a group of 6 + * sets. + * + * {int} @private + */ +var NUM_100K_SETS = 6; + +/** + * The column letters (for easting) of the lower left value, per + * set. + * + * {string} @private + */ +var SET_ORIGIN_COLUMN_LETTERS = 'AJSAJS'; + +/** + * The row letters (for northing) of the lower left value, per + * set. + * + * {string} @private + */ +var SET_ORIGIN_ROW_LETTERS = 'AFAFAF'; + +var A = 65; // A +var I = 73; // I +var O = 79; // O +var V = 86; // V +var Z = 90; // Z + +/** + * Conversion of lat/lon to MGRS. + * + * @param {object} ll Object literal with lat and lon properties on a + * WGS84 ellipsoid. + * @param {int} accuracy Accuracy in digits (5 for 1 m, 4 for 10 m, 3 for + * 100 m, 2 for 1000 m or 1 for 10000 m). Optional, default is 5. + * @return {string} the MGRS string for the given location and accuracy. + */ +exports.forward = function(ll, accuracy) { + accuracy = accuracy || 5; // default accuracy 1m + return encode(LLtoUTM({ + lat: ll[1], + lon: ll[0] + }), accuracy); +}; + +/** + * Conversion of MGRS to lat/lon. + * + * @param {string} mgrs MGRS string. + * @return {array} An array with left (longitude), bottom (latitude), right + * (longitude) and top (latitude) values in WGS84, representing the + * bounding box for the provided MGRS reference. + */ +exports.inverse = function(mgrs) { + var bbox = UTMtoLL(decode(mgrs.toUpperCase())); + if (bbox.lat && bbox.lon) { + return [bbox.lon, bbox.lat, bbox.lon, bbox.lat]; + } + return [bbox.left, bbox.bottom, bbox.right, bbox.top]; +}; + +exports.toPoint = function(mgrs) { + var bbox = UTMtoLL(decode(mgrs.toUpperCase())); + if (bbox.lat && bbox.lon) { + return [bbox.lon, bbox.lat]; + } + return [(bbox.left + bbox.right) / 2, (bbox.top + bbox.bottom) / 2]; +}; +/** + * Conversion from degrees to radians. + * + * @private + * @param {number} deg the angle in degrees. + * @return {number} the angle in radians. + */ +function degToRad(deg) { + return (deg * (Math.PI / 180.0)); +} + +/** + * Conversion from radians to degrees. + * + * @private + * @param {number} rad the angle in radians. + * @return {number} the angle in degrees. + */ +function radToDeg(rad) { + return (180.0 * (rad / Math.PI)); +} + +/** + * Converts a set of Longitude and Latitude co-ordinates to UTM + * using the WGS84 ellipsoid. + * + * @private + * @param {object} ll Object literal with lat and lon properties + * representing the WGS84 coordinate to be converted. + * @return {object} Object literal containing the UTM value with easting, + * northing, zoneNumber and zoneLetter properties, and an optional + * accuracy property in digits. Returns null if the conversion failed. + */ +function LLtoUTM(ll) { + var Lat = ll.lat; + var Long = ll.lon; + var a = 6378137.0; //ellip.radius; + var eccSquared = 0.00669438; //ellip.eccsq; + var k0 = 0.9996; + var LongOrigin; + var eccPrimeSquared; + var N, T, C, A, M; + var LatRad = degToRad(Lat); + var LongRad = degToRad(Long); + var LongOriginRad; + var ZoneNumber; + // (int) + ZoneNumber = Math.floor((Long + 180) / 6) + 1; + + //Make sure the longitude 180.00 is in Zone 60 + if (Long === 180) { + ZoneNumber = 60; + } + + // Special zone for Norway + if (Lat >= 56.0 && Lat < 64.0 && Long >= 3.0 && Long < 12.0) { + ZoneNumber = 32; + } + + // Special zones for Svalbard + if (Lat >= 72.0 && Lat < 84.0) { + if (Long >= 0.0 && Long < 9.0) { + ZoneNumber = 31; + } + else if (Long >= 9.0 && Long < 21.0) { + ZoneNumber = 33; + } + else if (Long >= 21.0 && Long < 33.0) { + ZoneNumber = 35; + } + else if (Long >= 33.0 && Long < 42.0) { + ZoneNumber = 37; + } + } + + LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3; //+3 puts origin + // in middle of + // zone + LongOriginRad = degToRad(LongOrigin); + + eccPrimeSquared = (eccSquared) / (1 - eccSquared); + + N = a / Math.sqrt(1 - eccSquared * Math.sin(LatRad) * Math.sin(LatRad)); + T = Math.tan(LatRad) * Math.tan(LatRad); + C = eccPrimeSquared * Math.cos(LatRad) * Math.cos(LatRad); + A = Math.cos(LatRad) * (LongRad - LongOriginRad); + + M = a * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256) * LatRad - (3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.sin(2 * LatRad) + (15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.sin(4 * LatRad) - (35 * eccSquared * eccSquared * eccSquared / 3072) * Math.sin(6 * LatRad)); + + var UTMEasting = (k0 * N * (A + (1 - T + C) * A * A * A / 6.0 + (5 - 18 * T + T * T + 72 * C - 58 * eccPrimeSquared) * A * A * A * A * A / 120.0) + 500000.0); + + var UTMNorthing = (k0 * (M + N * Math.tan(LatRad) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24.0 + (61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared) * A * A * A * A * A * A / 720.0))); + if (Lat < 0.0) { + UTMNorthing += 10000000.0; //10000000 meter offset for + // southern hemisphere + } + + return { + northing: Math.round(UTMNorthing), + easting: Math.round(UTMEasting), + zoneNumber: ZoneNumber, + zoneLetter: getLetterDesignator(Lat) + }; +} + +/** + * Converts UTM coords to lat/long, using the WGS84 ellipsoid. This is a convenience + * class where the Zone can be specified as a single string eg."60N" which + * is then broken down into the ZoneNumber and ZoneLetter. + * + * @private + * @param {object} utm An object literal with northing, easting, zoneNumber + * and zoneLetter properties. If an optional accuracy property is + * provided (in meters), a bounding box will be returned instead of + * latitude and longitude. + * @return {object} An object literal containing either lat and lon values + * (if no accuracy was provided), or top, right, bottom and left values + * for the bounding box calculated according to the provided accuracy. + * Returns null if the conversion failed. + */ +function UTMtoLL(utm) { + + var UTMNorthing = utm.northing; + var UTMEasting = utm.easting; + var zoneLetter = utm.zoneLetter; + var zoneNumber = utm.zoneNumber; + // check the ZoneNummber is valid + if (zoneNumber < 0 || zoneNumber > 60) { + return null; + } + + var k0 = 0.9996; + var a = 6378137.0; //ellip.radius; + var eccSquared = 0.00669438; //ellip.eccsq; + var eccPrimeSquared; + var e1 = (1 - Math.sqrt(1 - eccSquared)) / (1 + Math.sqrt(1 - eccSquared)); + var N1, T1, C1, R1, D, M; + var LongOrigin; + var mu, phi1Rad; + + // remove 500,000 meter offset for longitude + var x = UTMEasting - 500000.0; + var y = UTMNorthing; + + // We must know somehow if we are in the Northern or Southern + // hemisphere, this is the only time we use the letter So even + // if the Zone letter isn't exactly correct it should indicate + // the hemisphere correctly + if (zoneLetter < 'N') { + y -= 10000000.0; // remove 10,000,000 meter offset used + // for southern hemisphere + } + + // There are 60 zones with zone 1 being at West -180 to -174 + LongOrigin = (zoneNumber - 1) * 6 - 180 + 3; // +3 puts origin + // in middle of + // zone + + eccPrimeSquared = (eccSquared) / (1 - eccSquared); + + M = y / k0; + mu = M / (a * (1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256)); + + phi1Rad = mu + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.sin(2 * mu) + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * Math.sin(4 * mu) + (151 * e1 * e1 * e1 / 96) * Math.sin(6 * mu); + // double phi1 = ProjMath.radToDeg(phi1Rad); + + N1 = a / Math.sqrt(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad)); + T1 = Math.tan(phi1Rad) * Math.tan(phi1Rad); + C1 = eccPrimeSquared * Math.cos(phi1Rad) * Math.cos(phi1Rad); + R1 = a * (1 - eccSquared) / Math.pow(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad), 1.5); + D = x / (N1 * k0); + + var lat = phi1Rad - (N1 * Math.tan(phi1Rad) / R1) * (D * D / 2 - (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * eccPrimeSquared) * D * D * D * D / 24 + (61 + 90 * T1 + 298 * C1 + 45 * T1 * T1 - 252 * eccPrimeSquared - 3 * C1 * C1) * D * D * D * D * D * D / 720); + lat = radToDeg(lat); + + var lon = (D - (1 + 2 * T1 + C1) * D * D * D / 6 + (5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * eccPrimeSquared + 24 * T1 * T1) * D * D * D * D * D / 120) / Math.cos(phi1Rad); + lon = LongOrigin + radToDeg(lon); + + var result; + if (utm.accuracy) { + var topRight = UTMtoLL({ + northing: utm.northing + utm.accuracy, + easting: utm.easting + utm.accuracy, + zoneLetter: utm.zoneLetter, + zoneNumber: utm.zoneNumber + }); + result = { + top: topRight.lat, + right: topRight.lon, + bottom: lat, + left: lon + }; + } + else { + result = { + lat: lat, + lon: lon + }; + } + return result; +} + +/** + * Calculates the MGRS letter designator for the given latitude. + * + * @private + * @param {number} lat The latitude in WGS84 to get the letter designator + * for. + * @return {char} The letter designator. + */ +function getLetterDesignator(lat) { + //This is here as an error flag to show that the Latitude is + //outside MGRS limits + var LetterDesignator = 'Z'; + + if ((84 >= lat) && (lat >= 72)) { + LetterDesignator = 'X'; + } + else if ((72 > lat) && (lat >= 64)) { + LetterDesignator = 'W'; + } + else if ((64 > lat) && (lat >= 56)) { + LetterDesignator = 'V'; + } + else if ((56 > lat) && (lat >= 48)) { + LetterDesignator = 'U'; + } + else if ((48 > lat) && (lat >= 40)) { + LetterDesignator = 'T'; + } + else if ((40 > lat) && (lat >= 32)) { + LetterDesignator = 'S'; + } + else if ((32 > lat) && (lat >= 24)) { + LetterDesignator = 'R'; + } + else if ((24 > lat) && (lat >= 16)) { + LetterDesignator = 'Q'; + } + else if ((16 > lat) && (lat >= 8)) { + LetterDesignator = 'P'; + } + else if ((8 > lat) && (lat >= 0)) { + LetterDesignator = 'N'; + } + else if ((0 > lat) && (lat >= -8)) { + LetterDesignator = 'M'; + } + else if ((-8 > lat) && (lat >= -16)) { + LetterDesignator = 'L'; + } + else if ((-16 > lat) && (lat >= -24)) { + LetterDesignator = 'K'; + } + else if ((-24 > lat) && (lat >= -32)) { + LetterDesignator = 'J'; + } + else if ((-32 > lat) && (lat >= -40)) { + LetterDesignator = 'H'; + } + else if ((-40 > lat) && (lat >= -48)) { + LetterDesignator = 'G'; + } + else if ((-48 > lat) && (lat >= -56)) { + LetterDesignator = 'F'; + } + else if ((-56 > lat) && (lat >= -64)) { + LetterDesignator = 'E'; + } + else if ((-64 > lat) && (lat >= -72)) { + LetterDesignator = 'D'; + } + else if ((-72 > lat) && (lat >= -80)) { + LetterDesignator = 'C'; + } + return LetterDesignator; +} + +/** + * Encodes a UTM location as MGRS string. + * + * @private + * @param {object} utm An object literal with easting, northing, + * zoneLetter, zoneNumber + * @param {number} accuracy Accuracy in digits (1-5). + * @return {string} MGRS string for the given UTM location. + */ +function encode(utm, accuracy) { + // prepend with leading zeroes + var seasting = "00000" + utm.easting, + snorthing = "00000" + utm.northing; + + return utm.zoneNumber + utm.zoneLetter + get100kID(utm.easting, utm.northing, utm.zoneNumber) + seasting.substr(seasting.length - 5, accuracy) + snorthing.substr(snorthing.length - 5, accuracy); +} + +/** + * Get the two letter 100k designator for a given UTM easting, + * northing and zone number value. + * + * @private + * @param {number} easting + * @param {number} northing + * @param {number} zoneNumber + * @return the two letter 100k designator for the given UTM location. + */ +function get100kID(easting, northing, zoneNumber) { + var setParm = get100kSetForZone(zoneNumber); + var setColumn = Math.floor(easting / 100000); + var setRow = Math.floor(northing / 100000) % 20; + return getLetter100kID(setColumn, setRow, setParm); +} + +/** + * Given a UTM zone number, figure out the MGRS 100K set it is in. + * + * @private + * @param {number} i An UTM zone number. + * @return {number} the 100k set the UTM zone is in. + */ +function get100kSetForZone(i) { + var setParm = i % NUM_100K_SETS; + if (setParm === 0) { + setParm = NUM_100K_SETS; + } + + return setParm; +} + +/** + * Get the two-letter MGRS 100k designator given information + * translated from the UTM northing, easting and zone number. + * + * @private + * @param {number} column the column index as it relates to the MGRS + * 100k set spreadsheet, created from the UTM easting. + * Values are 1-8. + * @param {number} row the row index as it relates to the MGRS 100k set + * spreadsheet, created from the UTM northing value. Values + * are from 0-19. + * @param {number} parm the set block, as it relates to the MGRS 100k set + * spreadsheet, created from the UTM zone. Values are from + * 1-60. + * @return two letter MGRS 100k code. + */ +function getLetter100kID(column, row, parm) { + // colOrigin and rowOrigin are the letters at the origin of the set + var index = parm - 1; + var colOrigin = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(index); + var rowOrigin = SET_ORIGIN_ROW_LETTERS.charCodeAt(index); + + // colInt and rowInt are the letters to build to return + var colInt = colOrigin + column - 1; + var rowInt = rowOrigin + row; + var rollover = false; + + if (colInt > Z) { + colInt = colInt - Z + A - 1; + rollover = true; + } + + if (colInt === I || (colOrigin < I && colInt > I) || ((colInt > I || colOrigin < I) && rollover)) { + colInt++; + } + + if (colInt === O || (colOrigin < O && colInt > O) || ((colInt > O || colOrigin < O) && rollover)) { + colInt++; + + if (colInt === I) { + colInt++; + } + } + + if (colInt > Z) { + colInt = colInt - Z + A - 1; + } + + if (rowInt > V) { + rowInt = rowInt - V + A - 1; + rollover = true; + } + else { + rollover = false; + } + + if (((rowInt === I) || ((rowOrigin < I) && (rowInt > I))) || (((rowInt > I) || (rowOrigin < I)) && rollover)) { + rowInt++; + } + + if (((rowInt === O) || ((rowOrigin < O) && (rowInt > O))) || (((rowInt > O) || (rowOrigin < O)) && rollover)) { + rowInt++; + + if (rowInt === I) { + rowInt++; + } + } + + if (rowInt > V) { + rowInt = rowInt - V + A - 1; + } + + var twoLetter = String.fromCharCode(colInt) + String.fromCharCode(rowInt); + return twoLetter; +} + +/** + * Decode the UTM parameters from a MGRS string. + * + * @private + * @param {string} mgrsString an UPPERCASE coordinate string is expected. + * @return {object} An object literal with easting, northing, zoneLetter, + * zoneNumber and accuracy (in meters) properties. + */ +function decode(mgrsString) { + + if (mgrsString && mgrsString.length === 0) { + throw ("MGRSPoint coverting from nothing"); + } + + var length = mgrsString.length; + + var hunK = null; + var sb = ""; + var testChar; + var i = 0; + + // get Zone number + while (!(/[A-Z]/).test(testChar = mgrsString.charAt(i))) { + if (i >= 2) { + throw ("MGRSPoint bad conversion from: " + mgrsString); + } + sb += testChar; + i++; + } + + var zoneNumber = parseInt(sb, 10); + + if (i === 0 || i + 3 > length) { + // A good MGRS string has to be 4-5 digits long, + // ##AAA/#AAA at least. + throw ("MGRSPoint bad conversion from: " + mgrsString); + } + + var zoneLetter = mgrsString.charAt(i++); + + // Should we check the zone letter here? Why not. + if (zoneLetter <= 'A' || zoneLetter === 'B' || zoneLetter === 'Y' || zoneLetter >= 'Z' || zoneLetter === 'I' || zoneLetter === 'O') { + throw ("MGRSPoint zone letter " + zoneLetter + " not handled: " + mgrsString); + } + + hunK = mgrsString.substring(i, i += 2); + + var set = get100kSetForZone(zoneNumber); + + var east100k = getEastingFromChar(hunK.charAt(0), set); + var north100k = getNorthingFromChar(hunK.charAt(1), set); + + // We have a bug where the northing may be 2000000 too low. + // How + // do we know when to roll over? + + while (north100k < getMinNorthing(zoneLetter)) { + north100k += 2000000; + } + + // calculate the char index for easting/northing separator + var remainder = length - i; + + if (remainder % 2 !== 0) { + throw ("MGRSPoint has to have an even number \nof digits after the zone letter and two 100km letters - front \nhalf for easting meters, second half for \nnorthing meters" + mgrsString); + } + + var sep = remainder / 2; + + var sepEasting = 0.0; + var sepNorthing = 0.0; + var accuracyBonus, sepEastingString, sepNorthingString, easting, northing; + if (sep > 0) { + accuracyBonus = 100000.0 / Math.pow(10, sep); + sepEastingString = mgrsString.substring(i, i + sep); + sepEasting = parseFloat(sepEastingString) * accuracyBonus; + sepNorthingString = mgrsString.substring(i + sep); + sepNorthing = parseFloat(sepNorthingString) * accuracyBonus; + } + + easting = sepEasting + east100k; + northing = sepNorthing + north100k; + + return { + easting: easting, + northing: northing, + zoneLetter: zoneLetter, + zoneNumber: zoneNumber, + accuracy: accuracyBonus + }; +} + +/** + * Given the first letter from a two-letter MGRS 100k zone, and given the + * MGRS table set for the zone number, figure out the easting value that + * should be added to the other, secondary easting value. + * + * @private + * @param {char} e The first letter from a two-letter MGRS 100´k zone. + * @param {number} set The MGRS table set for the zone number. + * @return {number} The easting value for the given letter and set. + */ +function getEastingFromChar(e, set) { + // colOrigin is the letter at the origin of the set for the + // column + var curCol = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(set - 1); + var eastingValue = 100000.0; + var rewindMarker = false; + + while (curCol !== e.charCodeAt(0)) { + curCol++; + if (curCol === I) { + curCol++; + } + if (curCol === O) { + curCol++; + } + if (curCol > Z) { + if (rewindMarker) { + throw ("Bad character: " + e); + } + curCol = A; + rewindMarker = true; + } + eastingValue += 100000.0; + } + + return eastingValue; +} + +/** + * Given the second letter from a two-letter MGRS 100k zone, and given the + * MGRS table set for the zone number, figure out the northing value that + * should be added to the other, secondary northing value. You have to + * remember that Northings are determined from the equator, and the vertical + * cycle of letters mean a 2000000 additional northing meters. This happens + * approx. every 18 degrees of latitude. This method does *NOT* count any + * additional northings. You have to figure out how many 2000000 meters need + * to be added for the zone letter of the MGRS coordinate. + * + * @private + * @param {char} n Second letter of the MGRS 100k zone + * @param {number} set The MGRS table set number, which is dependent on the + * UTM zone number. + * @return {number} The northing value for the given letter and set. + */ +function getNorthingFromChar(n, set) { + + if (n > 'V') { + throw ("MGRSPoint given invalid Northing " + n); + } + + // rowOrigin is the letter at the origin of the set for the + // column + var curRow = SET_ORIGIN_ROW_LETTERS.charCodeAt(set - 1); + var northingValue = 0.0; + var rewindMarker = false; + + while (curRow !== n.charCodeAt(0)) { + curRow++; + if (curRow === I) { + curRow++; + } + if (curRow === O) { + curRow++; + } + // fixing a bug making whole application hang in this loop + // when 'n' is a wrong character + if (curRow > V) { + if (rewindMarker) { // making sure that this loop ends + throw ("Bad character: " + n); + } + curRow = A; + rewindMarker = true; + } + northingValue += 100000.0; + } + + return northingValue; +} + +/** + * The function getMinNorthing returns the minimum northing value of a MGRS + * zone. + * + * Ported from Geotrans' c Lattitude_Band_Value structure table. + * + * @private + * @param {char} zoneLetter The MGRS zone to get the min northing for. + * @return {number} + */ +function getMinNorthing(zoneLetter) { + var northing; + switch (zoneLetter) { + case 'C': + northing = 1100000.0; + break; + case 'D': + northing = 2000000.0; + break; + case 'E': + northing = 2800000.0; + break; + case 'F': + northing = 3700000.0; + break; + case 'G': + northing = 4600000.0; + break; + case 'H': + northing = 5500000.0; + break; + case 'J': + northing = 6400000.0; + break; + case 'K': + northing = 7300000.0; + break; + case 'L': + northing = 8200000.0; + break; + case 'M': + northing = 9100000.0; + break; + case 'N': + northing = 0.0; + break; + case 'P': + northing = 800000.0; + break; + case 'Q': + northing = 1700000.0; + break; + case 'R': + northing = 2600000.0; + break; + case 'S': + northing = 3500000.0; + break; + case 'T': + northing = 4400000.0; + break; + case 'U': + northing = 5300000.0; + break; + case 'V': + northing = 6200000.0; + break; + case 'W': + northing = 7000000.0; + break; + case 'X': + northing = 7900000.0; + break; + default: + northing = -1.0; + } + if (northing >= 0.0) { + return northing; + } + else { + throw ("Invalid zone letter: " + zoneLetter); + } + +} + +},{}],132:[function(require,module,exports){ +module.exports={ + "name": "proj4", + "version": "2.3.7", + "description": "Proj4js is a JavaScript library to transform point coordinates from one coordinate system to another, including datum transformations.", + "main": "lib/index.js", + "directories": { + "test": "test", + "doc": "docs" + }, + "scripts": { + "test": "./node_modules/istanbul/lib/cli.js test ./node_modules/mocha/bin/_mocha test/test.js" + }, + "repository": { + "type": "git", + "url": "git://github.com/proj4js/proj4js.git" + }, + "author": "", + "license": "MIT", + "jam": { + "main": "dist/proj4.js", + "include": [ + "dist/proj4.js", + "README.md", + "AUTHORS", + "LICENSE.md" + ] + }, + "devDependencies": { + "grunt-cli": "~0.1.13", + "grunt": "~0.4.2", + "grunt-contrib-connect": "~0.6.0", + "grunt-contrib-jshint": "~0.8.0", + "chai": "~1.8.1", + "mocha": "~1.17.1", + "grunt-mocha-phantomjs": "~0.4.0", + "browserify": "~3.24.5", + "grunt-browserify": "~1.3.0", + "grunt-contrib-uglify": "~0.3.2", + "curl": "git://github.com/cujojs/curl.git", + "istanbul": "~0.2.4", + "tin": "~0.4.0" + }, + "dependencies": { + "mgrs": "~0.0.2" + }, + "contributors": [ + { + "name": "Mike Adair", + "email": "madair@dmsolutions.ca" + }, + { + "name": "Richard Greenwood", + "email": "rich@greenwoodmap.com" + }, + { + "name": "Calvin Metcalf", + "email": "calvin.metcalf@gmail.com" + }, + { + "name": "Richard Marsden", + "url": "http://www.winwaed.com" + }, + { + "name": "T. Mittan" + }, + { + "name": "D. Steinwand" + }, + { + "name": "S. Nelson" + } + ], + "gitHead": "52b3a4f6bf8b609251d06f1f7ddd29d7074f3ce4", + "bugs": { + "url": "https://github.com/proj4js/proj4js/issues" + }, + "homepage": "https://github.com/proj4js/proj4js#readme", + "_id": "proj4@2.3.7", + "_shasum": "248a30b2dc346dd1896dc5526c1a5e6b546f334a", + "_from": "proj4@>=2.1.0 <3.0.0", + "_npmVersion": "2.11.2", + "_nodeVersion": "0.12.5", + "_npmUser": { + "name": "ahocevar", + "email": "andreas.hocevar@gmail.com" + }, + "maintainers": [ + { + "name": "cwmma", + "email": "calvin.metcalf@gmail.com" + }, + { + "name": "ahocevar", + "email": "andreas.hocevar@gmail.com" + } + ], + "dist": { + "shasum": "248a30b2dc346dd1896dc5526c1a5e6b546f334a", + "tarball": "http://registry.npmjs.org/proj4/-/proj4-2.3.7.tgz" + }, + "_resolved": "https://registry.npmjs.org/proj4/-/proj4-2.3.7.tgz" +} + +},{}],133:[function(require,module,exports){ +(function (Buffer){ +'use strict'; +var proj4 = require('proj4'); +var unzip = require('./unzip'); +var binaryAjax = require('./binaryajax'); +var parseShp = require('./parseShp'); +var toArrayBuffer = require('./toArrayBuffer'); +var parseDbf = require('parsedbf'); +var Promise = require('lie'); +var Cache = require('lru-cache'); +var cache = new Cache({ + max: 20 +}); +function shp(base, whiteList) { + if (typeof base === 'string' && cache.has(base)) { + return Promise.resolve(cache.get(base)); + } + return shp.getShapefile(base, whiteList).then(function (resp) { + if (typeof base === 'string') { + cache.set(base, resp); + } + return resp; + }); +} +shp.combine = function(arr) { + var out = {}; + out.type = 'FeatureCollection'; + out.features = []; + var i = 0; + var len = arr[0].length; + while (i < len) { + out.features.push({ + 'type': 'Feature', + 'geometry': arr[0][i], + 'properties': arr[1][i] + }); + i++; + } + return out; +}; +shp.parseZip = function(buffer, whiteList) { + var key; + var zip = unzip(buffer); + var names = []; + whiteList = whiteList || []; + for (key in zip) { + if (key.indexOf('__MACOSX') !== -1) { + continue; + } + if (key.slice(-3).toLowerCase() === 'shp') { + names.push(key.slice(0, - 4)); + } + else if (key.slice(-3).toLowerCase() === 'dbf') { + zip[key.slice(0, -3) + key.slice(-3).toLowerCase()] = parseDbf(zip[key]); + } + else if (key.slice(-3).toLowerCase() === 'prj') { + zip[key.slice(0, -3) + key.slice(-3).toLowerCase()] = proj4(zip[key]); + } + else if (key.slice(-4).toLowerCase() === 'json' || whiteList.indexOf(key.split('.').pop()) > -1) { + names.push(key.slice(0, -3) + key.slice(-3).toLowerCase()); + } + } + if (!names.length) { + throw new Error('no layers founds'); + } + var geojson = names.map(function(name) { + var parsed; + if (name.slice(-4).toLowerCase() === 'json') { + parsed = JSON.parse(zip[name]); + parsed.fileName = name.slice(0, name.lastIndexOf('.')); + } + else if (whiteList.indexOf(name.slice(name.lastIndexOf('.') + 1)) > -1) { + parsed = zip[name]; + parsed.fileName = name; + } + else { + parsed = shp.combine([parseShp(zip[name + '.shp'], zip[name + '.prj']), zip[name + '.dbf']]); + parsed.fileName = name; + } + return parsed; + }); + if (geojson.length === 1) { + return geojson[0]; + } + else { + return geojson; + } +}; + +function getZip(base, whiteList) { + return binaryAjax(base).then(function(a) { + return shp.parseZip(a, whiteList); + }); +} +shp.getShapefile = function(base, whiteList) { + if (typeof base === 'string') { + if (base.slice(-4) === '.zip') { + return getZip(base, whiteList); + } + else { + return Promise.all([ + Promise.all([ + binaryAjax(base + '.shp'), + binaryAjax(base + '.prj') + ]).then(function(args) { + return parseShp(args[0], args[1] ? proj4(args[1]) : false); + }), + binaryAjax(base + '.dbf').then(parseDbf) + ]).then(shp.combine); + } + } + else { + return new Promise(function(resolve) { + resolve(shp.parseZip(base)); + }); + } +}; +shp.parseShp = function (shp, prj) { + if (Buffer.isBuffer(shp)) { + shp = toArrayBuffer(shp); + } + if (Buffer.isBuffer(prj)) { + prj = prj.toString(); + } + if (typeof prj === 'string') { + prj = proj4(prj); + return parseShp(shp, prj); + } else { + return parseShp(shp); + } +}; +shp.parseDbf = function (dbf) { + if (Buffer.isBuffer(dbf)) { + dbf = toArrayBuffer(dbf); + } + return parseDbf(dbf); +}; +module.exports = shp; + +}).call(this,require("buffer").Buffer) +},{"./binaryajax":1,"./parseShp":2,"./toArrayBuffer":3,"./unzip":4,"buffer":5,"lie":51,"lru-cache":62,"parsedbf":63,"proj4":100}]},{},[133])(133) +}); \ No newline at end of file diff --git a/javascript/vann.zip b/javascript/vann.zip new file mode 100644 index 0000000000000000000000000000000000000000..4e2947fba060b51886c17723a37bb42950812c54 Binary files /dev/null and b/javascript/vann.zip differ