diff --git a/AstuteClient2/src/app/invoice/invoice.component.html b/AstuteClient2/src/app/invoice/invoice.component.html
index 73d3615..3066df5 100644
--- a/AstuteClient2/src/app/invoice/invoice.component.html
+++ b/AstuteClient2/src/app/invoice/invoice.component.html
@@ -197,10 +197,10 @@
 
 <!--MODAL: new invoice-->
 <app-modal-form [title]="'New Invoice'" #new>
+    <!--General-->
     <div class="modal-body">
         <p class="h4 text-right">General</p>
         <hr>
-
         <table class="table table-borderless table-sm">
             <tbody>
                 <tr>
@@ -300,25 +300,26 @@
                 <td class="p-0 m-0"><input type="text" class="form-control cell" [value]="feeTypes[inDet.feeTypeId - 1]"
                                            disabled></td>
                 <td class="p-0 m-0"><input type="number" class="form-control cell" [value]="inDet.fee"
-                                           (change)="onNewCellChange(i, 'fee', fee.value); updateNewBillAmt();" #fee>
+                                           (change)="onNewCellChange(i, 'fee', fee.value); updateNewBillAmt();" #fee disabled>
                 </td>
                 <td class="p-0 m-0"><input type="number" class="form-control cell" [value]="inDet.qty"
+                                           [step]="inDet.remainingQty / 100"
                                            (change)="onNewCellChange(i, 'qty', qty.value); updateNewBillAmt();" #qty>
                 </td>
             </tr>
             <tr class="p-0 m-0">
                 <th class="align-content-center">
-                    <p>{{getPerc(fee.value * qty.value, inDet.remainingQty)}}%</p>
+                    <p>{{getPerc(qty.value, inDet.remainingQty)}}%</p>
                 </th>
                 <td colspan="4">
                     <div class="progress" style="height: 25px;">
                         <div class="progress-bar bg-success" role="progressbar"
-                             [ngStyle]="{'width': getPerc(fee.value * qty.value, inDet.remainingQty) + '%'}">
-                            ${{fee.value * qty.value}}
+                             [ngStyle]="{'width': getPerc(qty.value, inDet.remainingQty) + '%'}">
+                            {{qty.value}}
                         </div>
                         <div class="progress-bar bg-danger" role="progressbar"
-                             [ngStyle]="{'width': (100 - getPerc(fee.value * qty.value, inDet.remainingQty)) + '%'}">
-                            ${{inDet.remainingQty - (fee.value * qty.value)}}
+                             [ngStyle]="{'width': (100 - getPerc(qty.value, inDet.remainingQty)) + '%'}">
+                            {{inDet.remainingQty - (qty.value)}}
                         </div>
                     </div>
                 </td>
@@ -330,7 +331,7 @@
                     <select class="custom-select"
                             (change)="pushOntoNewDetail(inNumIn.value, newInDetails.length + 1, poDetails[poDetSelec.value].lineItemNo,
                   poDetails[poDetSelec.value].feeTypeId, poDetails[poDetSelec.value].serviceTypeId,
-                  poDetails[poDetSelec.value].serviceDesc, 1, 0, poDetails[poDetSelec.value].remainingQty)"
+                  poDetails[poDetSelec.value].serviceDesc, 0, poDetails[poDetSelec.value].fee, poDetails[poDetSelec.value].remainingQty)"
                             [disabled]="!poDetails.length"
                             #poDetSelec>
                         <option>Choose PO Detail...</option>
diff --git a/AstuteClient2/src/app/invoice/invoice.component.ts b/AstuteClient2/src/app/invoice/invoice.component.ts
index f025208..70b6f2f 100644
--- a/AstuteClient2/src/app/invoice/invoice.component.ts
+++ b/AstuteClient2/src/app/invoice/invoice.component.ts
@@ -255,6 +255,20 @@ export class InvoiceComponent implements OnInit {
     return [year, month, day].join('-');
   }
 
+    formatDate(d: Date) {
+        let month = '' + (d.getMonth() + 1),
+            day = '' + d.getDate(),
+            year = d.getFullYear();
+
+        if (month.length < 2) {
+            month = '0' + month;
+        }
+        if (day.length < 2) {
+            day = '0' + day;
+        }
+        return [year, month, day].join('-');
+    }
+
   addInvoice(invoiceNumber, poNum, changeOrderNum, pmtStatus, billAmt, specialNotes, certification, status, ref) {
     // String  invoiceNumber;
     // Date invoiceDate;
@@ -267,14 +281,14 @@ export class InvoiceComponent implements OnInit {
     // Date pmtReceivedDate;
     const invData = {
       "invoiceNumber": invoiceNumber,
-      "invoiceDate": new Date(),
+      "invoiceDate": this.formatDate(new Date()),
       "poNum": poNum,
       "changeOrderNum": changeOrderNum,
       "pmtStatus": +pmtStatus,
       "billAmt": +billAmt,
       "specialNotes": specialNotes,
       "certification": certification,
-      "pmtReceivedDate": new Date(),
+      "pmtReceivedDate": this.formatDate(new Date()),
       'invoiceStatus': status
     };
 
@@ -362,7 +376,7 @@ export class InvoiceComponent implements OnInit {
       if (data) {
         this.refreshData();
       } else {
-        alert('submit invoice failed.')
+        alert('submit invoice failed.');
       }
     });
   }
diff --git a/AstuteClient2/src/assets/html2canvas/.flowconfig b/AstuteClient2/src/assets/html2canvas/.flowconfig
new file mode 100644
index 0000000..c4c5750
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/.flowconfig
@@ -0,0 +1,7 @@
+[ignore]
+.*/www/.*
+[include]
+[libs]
+./flow-typed
+[options]
+[lints]
diff --git a/AstuteClient2/src/assets/html2canvas/CHANGELOG.md b/AstuteClient2/src/assets/html2canvas/CHANGELOG.md
new file mode 100644
index 0000000..b503fbe
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/CHANGELOG.md
@@ -0,0 +1,144 @@
+### Changelog ###
+
+#### v1.0.0-alpha.12 - 5.4.2018 ####
+ * Fix white space appearing on element rendering (Fix #1438)
+ * Reset canvas transform on finish (Fix #1494)
+
+#### v1.0.0-alpha.11 - 1.4.2018 ####
+ * Fix IE11 member not found error 
+ * Support blob image resources in non-foreignObjectRendering mode
+
+#### v1.0.0-alpha.10 - 15.2.2018 ####
+ * Re-introduce `onclone` option (Fix #1434)
+ * Add `ignoreElements` predicate function option
+ * Fix version console logging
+
+#### v1.0.0-alpha.9 - 7.1.2018 ####
+ * Fix dynamic style sheets
+ * Fix > 50% border-radius values
+
+#### v1.0.0-alpha.8 - 2.1.2018 ####
+ * Use correct doctype in cloned Document (Fix #1298)
+ * Fix individual border rendering (Fix #1349)
+
+#### v1.0.0-alpha.7 - 31.12.2017 ####
+ * Fix form input rendering (#1338)
+ * Improve word line breaking algorithm
+
+#### v1.0.0-alpha.6 - 28.12.2017 ####
+ * Fix list-style: none (#1340)
+ * Extend supported values for pseudo element content
+
+#### v1.0.0-alpha.5 - 21.12.2017 ####
+ * Fix underline positioning
+ * Fix canvas rendering on Chrome
+ * Fix overflow: auto
+ * Added support for rendering list-style
+
+#### v1.0.0-alpha.4 - 12.12.2017 ####
+ * Fix rendering with multiple fonts defined (Fix #796)
+ * Add support for radial-gradients
+ * Fix logging option (#1302)
+ * Add support for rendering webgl canvas content (#646)
+ * Fix external SVG loading with proxies (#802)
+
+#### v1.0.0-alpha.3 - 9.12.2017 ####
+ * Disable `foreignObjectRendering` by default (#1295)
+ * Fix background-size when using background-origin and background-size: cover/contain (#1299)
+ * Added support for background-origin: content-box (#1299)
+
+#### v1.0.0-alpha.2 - 7.12.2017 ####
+ * Fix scroll positions for CanvasRenderer (#1259)
+ * Fix `data-html2canvas-ignore` attribute (#1253)
+ * Fix decimal `letter-spacing` values (#1293)
+
+#### v1.0.0-alpha.1 - 5.12.2017 ####
+ * Complete rewrite of library
+ ##### Breaking Changes #####
+ * Remove deprecated onrendered callback, calling `html2canvas` returns a `Promise<HTMLCanvasElement>`
+ * Removed option `type`, same results can be achieved by assigning `x`, `y`, `scrollX`, `scrollY`, `width` and `height` properties.
+ 
+ ##### New featues / fixes #####
+ * Add support for scaling canvas (defaults to device pixel ratio)
+ * Add support for multiple text-shadows
+ * Add support for multiple text-decorations
+ * Add support for text-decoration-color
+ * Add support for percentage values for border-radius
+ * Correctly handle px and percentage values in linear-gradients
+ * Correctly support all angle types for linear-gradients
+ * Add support for multiple values for background-repeat, background-position and background-size
+ 
+#### v0.5.0-beta4 - 23.1.2016 ####
+ * Fix logger requiring access to window object
+ * Derequire browserify build
+ * Fix rendering of specific elements when window is scrolled and `type` isn't set to `view`
+
+#### v0.5.0-beta3 - 6.12.2015 ####
+ * Handle color names in linear gradients
+
+#### v0.5.0-beta2 - 20.10.2015 ####
+ * Remove Promise polyfill (use native or provide it yourself)
+
+#### v0.5.0-beta1 - 19.10.2015 ####
+ * Fix bug with unmatched color stops in gradients
+ * Fix scrolling issues with iOS
+ * Correctly handle named colors in gradients
+ * Accept matrix3d transforms
+ * Fix transparent colors breaking gradients
+ * Preserve scrolling positions on render
+
+#### v0.5.0-alpha2 - 3.2.2015 ####
+ * Switch to using browserify for building
+ * Fix (#517) Chrome stretches background images with 'auto' or single attributes
+
+#### v0.5.0-alpha - 19.1.2015#### 
+ * Complete rewrite of library
+ * Switched interface to return Promise
+ * Uses hidden iframe window to perform rendering, allowing async rendering and doesn't force the viewport to be scrolled to the top anymore.
+ * Better support for unicode
+ * Checkbox/radio button rendering
+ * SVG rendering
+ * iframe rendering
+ * Changed format for proxy requests, permitting binary responses with CORS headers as well
+ * Fixed many layering issues (see z-index tests)
+
+#### v0.4.1 - 7.9.2013 ####
+ * Added support for bower
+ * Improved z-index ordering
+ * Basic implementation for CSS transformations
+ * Fixed inline text in top element
+ * Basic implementation for text-shadow
+
+#### v0.4.0 - 30.1.2013 ####
+ * Added rendering tests with <a href="https://github.com/niklasvh/webdriver.js">webdriver</a>
+ * Switched to using grunt for building
+ * Removed support for IE<9, including any FlashCanvas bits
+ * Support for border-radius
+ * Support for multiple background images, size, and clipping
+ * Support for :before and :after pseudo elements
+ * Support for placeholder rendering
+ * Reformatted all tests to small units to test specific features
+
+#### v0.3.4 - 26.6.2012 ####
+
+* Removed (last?) jQuery dependencies (<a href="https://github.com/niklasvh/html2canvas/commit/343b86705fe163766fcf735eb0217130e4bd5b17">niklasvh</a>)
+* SVG-powered rendering (<a href="https://github.com/niklasvh/html2canvas/commit/67d3e0d0f59a5a654caf71a2e3be6494ff146c75">niklasvh</a>)
+* Radial gradients (<a href="https://github.com/niklasvh/html2canvas/commit/4f22c18043a73c0c3bbf3b5e4d62714c56acd3c7">SunboX</a>)
+* Split renderers to their own objects (<a href="https://github.com/niklasvh/html2canvas/commit/94f2f799a457cd29a21cc56ef8c06f1697866739">niklasvh</a>)
+* Simplified API, cleaned up code (<a href="https://github.com/niklasvh/html2canvas/commit/c7d526c9eaa6a4abf4754d205fe1dee360c7660e">niklasvh</a>)
+
+#### v0.3.3 - 2.3.2012 ####
+
+* SVG taint fix, and additional taint testing options for rendering (<a href="https://github.com/niklasvh/html2canvas/commit/2dc8b9385e656696cb019d615bdfa1d98b17d5d4">niklasvh</a>)
+* Added support for CORS images and option to create canvas as tainted (<a href="https://github.com/niklasvh/html2canvas/commit/3ad49efa0032cde25c6ed32a39e35d1505d3b2ef">niklasvh</a>)
+* Improved minification saved ~1K! (<a href="https://github.com/cobexer/html2canvas/commit/b82be022b2b9240bd503e078ac980bde2b953e43">cobexer</a>)
+* Added integrated support for Flashcanvas (<a href="https://github.com/niklasvh/html2canvas/commit/e9257191519f67d74fd5e364d8dee3c0963ba5fc">niklasvh</a>)
+* Fixed a variety of legacy IE bugs (<a href="https://github.com/niklasvh/html2canvas/commit/b65357c55d0701017bafcd357bc654b54d458f8f">niklasvh</a>)
+
+#### v0.3.2 - 20.2.2012 ####
+
+* Added changelog!
+* Added bookmarklet (<a href="https://github.com/niklasvh/html2canvas/commit/b320dd306e1a2d32a3bc5a71b6ebf6d8c060cde5">cobexer</a>)
+* Option to select single element to render (<a href="https://github.com/niklasvh/html2canvas/commit/0cb252ada91c84ef411288b317c03e97da1f12ad">niklasvh</a>)
+* Fixed closure compiler warnings (<a href="https://github.com/niklasvh/html2canvas/commit/36ff1ec7aadcbdf66851a0b77f0b9e87e4a8e4a1">cobexer</a>)
+* Enable profiling in FF (<a href="https://github.com/niklasvh/html2canvas/commit/bbd75286a8406cf9e5aea01fdb7950d547edefb9">cobexer</a>)
diff --git a/AstuteClient2/src/assets/html2canvas/LICENSE b/AstuteClient2/src/assets/html2canvas/LICENSE
new file mode 100644
index 0000000..a73ffc9
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2012 Niklas von Hertzen
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/README.md b/AstuteClient2/src/assets/html2canvas/README.md
new file mode 100644
index 0000000..01f01c7
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/README.md
@@ -0,0 +1,89 @@
+html2canvas
+===========
+
+[Homepage](https://html2canvas.hertzen.com) | [Downloads](https://github.com/niklasvh/html2canvas/releases) | [Questions](http://stackoverflow.com/questions/tagged/html2canvas?sort=newest) | [Donate](https://www.gittip.com/niklasvh/)
+
+[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/niklasvh/html2canvas?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) 
+[![Build Status](https://travis-ci.org/niklasvh/html2canvas.svg)](https://travis-ci.org/niklasvh/html2canvas)
+[![NPM Downloads](https://img.shields.io/npm/dm/html2canvas.svg)](https://www.npmjs.org/package/html2canvas)
+[![NPM Version](https://img.shields.io/npm/v/html2canvas.svg)](https://www.npmjs.org/package/html2canvas)
+
+#### JavaScript HTML renderer ####
+
+ The script allows you to take "screenshots" of webpages or parts of it, directly on the users browser. The screenshot is based on the DOM and as such may not be 100% accurate to the real representation as it does not make an actual screenshot, but builds the screenshot based on the information available on the page.
+
+
+### How does it work? ###
+The script renders the current page as a canvas image, by reading the DOM and the different styles applied to the elements.
+
+It does **not require any rendering from the server**, as the whole image is created on the **client's browser**. However, as it is heavily dependent on the browser, this library is *not suitable* to be used in nodejs.
+It doesn't magically circumvent any browser content policy restrictions either, so rendering cross-origin content will require a [proxy](https://github.com/niklasvh/html2canvas/wiki/Proxies) to get the content to the [same origin](http://en.wikipedia.org/wiki/Same_origin_policy).
+
+The script is still in a **very experimental state**, so I don't recommend using it in a production environment nor start building applications with it yet, as there will be still major changes made.
+
+### Browser compatibility ###
+
+The library should work fine on the following browsers (with `Promise` polyfill):
+
+* Firefox 3.5+
+* Google Chrome
+* Opera 12+
+* IE9+
+* Safari 6+
+
+As each CSS property needs to be manually built to be supported, there are a number of properties that are not yet supported.
+
+### Usage ###
+
+The html2canvas library utilizes `Promise`s and expects them to be available in the global context. If you wish to
+support [older browsers](http://caniuse.com/#search=promise) that do not natively support `Promise`s, please include a polyfill such as
+[es6-promise](https://github.com/jakearchibald/es6-promise) before including `html2canvas`.
+
+**Note!** These instructions are for using the current dev version of 0.5, for the latest release version (0.4.1), checkout the [old readme](https://github.com/niklasvh/html2canvas/blob/v0.4/readme.md).
+
+To render an `element` with html2canvas, simply call:
+` html2canvas(element[, options]);`
+
+The function returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) containing the `<canvas>` element. Simply add a promise fullfillment handler to the promise using `then`:
+
+    html2canvas(document.body).then(function(canvas) {
+        document.body.appendChild(canvas);
+    });
+
+### Building ###
+
+You can download ready builds [here](https://github.com/niklasvh/html2canvas/releases).
+
+Clone git repository:
+
+    $ git clone git://github.com/niklasvh/html2canvas.git
+
+Install dependencies:
+
+    $ npm install
+
+Build browser bundle
+
+    $ npm run build
+
+### Running tests ###
+
+The library has two sets of tests. The first set is a number of qunit tests that check that different values parsed by browsers are correctly converted in html2canvas. To run these tests with grunt you'll need [phantomjs](http://phantomjs.org/).
+
+The other set of tests run Firefox, Chrome and Internet Explorer with [webdriver](https://github.com/niklasvh/webdriver.js). The selenium standalone server (runs on Java) is required for these tests and can be downloaded from [here](http://code.google.com/p/selenium/downloads/list). They capture an actual screenshot from the test pages and compare the image to the screenshot created by html2canvas and calculate the percentage differences. These tests generally aren't expected to provide 100% matches, but while committing changes, these should generally not go decrease from the baseline values.
+
+Start by downloading the dependencies:
+
+    $ npm install
+
+Run tests:
+
+    $ npm test
+
+### Examples ###
+
+For more information and examples, please visit the [homepage](https://html2canvas.hertzen.com) or try the [test console](http://html2canvas.hertzen.com/screenshots.html).
+
+### Contributing ###
+
+If you wish to contribute to the project, please send the pull requests to the develop branch. Before submitting any changes, try and test that the changes work with all the support browsers. If some CSS property isn't supported or is incomplete, please create appropriate tests for it as well before submitting any code changes.
diff --git a/AstuteClient2/src/assets/html2canvas/dist/RefTestRenderer.js b/AstuteClient2/src/assets/html2canvas/dist/RefTestRenderer.js
new file mode 100644
index 0000000..5480700
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/RefTestRenderer.js
@@ -0,0 +1,2199 @@
+/*!
+ * html2canvas 1.0.0-alpha.12 <https://html2canvas.hertzen.com>
+ * Copyright (c) 2018 Niklas von Hertzen <https://hertzen.com>
+ * Released under MIT License
+ */
+(function webpackUniversalModuleDefinition(root, factory) {
+	if(typeof exports === 'object' && typeof module === 'object')
+		module.exports = factory();
+	else if(typeof define === 'function' && define.amd)
+		define([], factory);
+	else if(typeof exports === 'object')
+		exports["RefTestRenderer"] = factory();
+	else
+		root["RefTestRenderer"] = factory();
+})(this, function() {
+return /******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+/******/
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+/******/
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId]) {
+/******/ 			return installedModules[moduleId].exports;
+/******/ 		}
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			i: moduleId,
+/******/ 			l: false,
+/******/ 			exports: {}
+/******/ 		};
+/******/
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ 		// Flag the module as loaded
+/******/ 		module.l = true;
+/******/
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/
+/******/
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+/******/
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+/******/
+/******/ 	// define getter function for harmony exports
+/******/ 	__webpack_require__.d = function(exports, name, getter) {
+/******/ 		if(!__webpack_require__.o(exports, name)) {
+/******/ 			Object.defineProperty(exports, name, {
+/******/ 				configurable: false,
+/******/ 				enumerable: true,
+/******/ 				get: getter
+/******/ 			});
+/******/ 		}
+/******/ 	};
+/******/
+/******/ 	// getDefaultExport function for compatibility with non-harmony modules
+/******/ 	__webpack_require__.n = function(module) {
+/******/ 		var getter = module && module.__esModule ?
+/******/ 			function getDefault() { return module['default']; } :
+/******/ 			function getModuleExports() { return module; };
+/******/ 		__webpack_require__.d(getter, 'a', getter);
+/******/ 		return getter;
+/******/ 	};
+/******/
+/******/ 	// Object.prototype.hasOwnProperty.call
+/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "";
+/******/
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(__webpack_require__.s = 0);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _url = __webpack_require__(1);
+
+var _textDecoration2 = __webpack_require__(9);
+
+var _Path = __webpack_require__(11);
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var RefTestRenderer = function () {
+    function RefTestRenderer() {
+        _classCallCheck(this, RefTestRenderer);
+    }
+
+    _createClass(RefTestRenderer, [{
+        key: 'render',
+        value: function render(options) {
+            this.options = options;
+            this.indent = 0;
+            this.lines = [];
+            options.logger.log('RefTest renderer initialized');
+            this.writeLine('Window: [' + options.width + ', ' + options.height + ']');
+        }
+    }, {
+        key: 'clip',
+        value: function clip(clipPaths, callback) {
+            this.writeLine('Clip: ' + clipPaths.map(this.formatPath, this).join(' | '));
+            this.indent += 2;
+            callback();
+            this.indent -= 2;
+        }
+    }, {
+        key: 'drawImage',
+        value: function drawImage(image, source, destination) {
+            this.writeLine('Draw image: ' + this.formatImage(image) + ' (source: ' + this.formatBounds(source) + ') (destination: ' + this.formatBounds(source) + ')');
+        }
+    }, {
+        key: 'drawShape',
+        value: function drawShape(path, color) {
+            this.writeLine('Shape: ' + color.toString() + ' ' + this.formatPath(path));
+        }
+    }, {
+        key: 'fill',
+        value: function fill(color) {
+            this.writeLine('Fill: ' + color.toString());
+        }
+    }, {
+        key: 'getTarget',
+        value: function getTarget() {
+            return Promise.resolve(this.lines.join('\n'));
+        }
+    }, {
+        key: 'rectangle',
+        value: function rectangle(x, y, width, height, color) {
+            var list = [x, y, width, height].map(function (v) {
+                return Math.round(v);
+            }).join(', ');
+            this.writeLine('Rectangle: [' + list + '] ' + color.toString());
+        }
+    }, {
+        key: 'formatBounds',
+        value: function formatBounds(bounds) {
+            var list = [bounds.left, bounds.top, bounds.width, bounds.height];
+            return '[' + list.map(function (v) {
+                return Math.round(v);
+            }).join(', ') + ']';
+        }
+    }, {
+        key: 'formatImage',
+        value: function formatImage(image) {
+            return image.tagName === 'CANVAS' ? 'Canvas' : // $FlowFixMe
+            'Image ("' + (0, _url.parse)(image.src).pathname.substring(0, 100) + '")';
+        }
+    }, {
+        key: 'formatPath',
+        value: function formatPath(path) {
+            if (!Array.isArray(path)) {
+                return 'Circle(x: ' + Math.round(path.x) + ', y: ' + Math.round(path.y) + ', r: ' + Math.round(path.radius) + ')';
+            }
+            var string = path.map(function (v) {
+                if (v.type === _Path.PATH.VECTOR) {
+                    return 'Vector(x: ' + Math.round(v.x) + ', y: ' + Math.round(v.y) + ')';
+                }
+                if (v.type === _Path.PATH.BEZIER_CURVE) {
+                    var values = ['x0: ' + Math.round(v.start.x), 'y0: ' + Math.round(v.start.y), 'x1: ' + Math.round(v.end.x), 'y1: ' + Math.round(v.end.y), 'cx0: ' + Math.round(v.startControl.x), 'cy0: ' + Math.round(v.startControl.y), 'cx1: ' + Math.round(v.endControl.x), 'cy1: ' + Math.round(v.endControl.y)];
+                    return 'BezierCurve(' + values.join(', ') + ')';
+                }
+            }).join(' > ');
+            return 'Path (' + string + ')';
+        }
+    }, {
+        key: 'renderLinearGradient',
+        value: function renderLinearGradient(bounds, gradient) {
+            var direction = ['x0: ' + Math.round(gradient.direction.x0), 'x1: ' + Math.round(gradient.direction.x1), 'y0: ' + Math.round(gradient.direction.y0), 'y1: ' + Math.round(gradient.direction.y1)];
+
+            var stops = gradient.colorStops.map(function (stop) {
+                return stop.color.toString() + ' ' + Math.ceil(stop.stop * 100) / 100;
+            });
+
+            this.writeLine('Gradient: ' + this.formatBounds(bounds) + ' linear-gradient(' + direction.join(', ') + ' ' + stops.join(', ') + ')');
+        }
+    }, {
+        key: 'renderRadialGradient',
+        value: function renderRadialGradient(bounds, gradient) {
+            var stops = gradient.colorStops.map(function (stop) {
+                return stop.color.toString() + ' ' + Math.ceil(stop.stop * 100) / 100;
+            });
+
+            this.writeLine('RadialGradient: ' + this.formatBounds(bounds) + ' radial-gradient(' + gradient.radius.x + ' ' + gradient.radius.y + ' at ' + gradient.center.x + ' ' + gradient.center.y + ', ' + stops.join(', ') + ')');
+        }
+    }, {
+        key: 'renderRepeat',
+        value: function renderRepeat(path, image, imageSize, offsetX, offsetY) {
+            this.writeLine('Repeat: ' + this.formatImage(image) + ' [' + Math.round(offsetX) + ', ' + Math.round(offsetY) + '] Size (' + Math.round(imageSize.width) + ', ' + Math.round(imageSize.height) + ') ' + this.formatPath(path));
+        }
+    }, {
+        key: 'renderTextNode',
+        value: function renderTextNode(textBounds, color, font, textDecoration, textShadows) {
+            var _this = this;
+
+            var fontString = [font.fontStyle, font.fontVariant, font.fontWeight, parseInt(font.fontSize, 10), font.fontFamily.replace(/"/g, '')].join(' ').split(',')[0];
+
+            var textDecorationString = this.textDecoration(textDecoration, color);
+            var shadowString = textShadows ? ' Shadows: (' + textShadows.map(function (shadow) {
+                return shadow.color.toString() + ' ' + shadow.offsetX + 'px ' + shadow.offsetY + 'px ' + shadow.blur + 'px';
+            }).join(', ') + ')' : '';
+
+            this.writeLine('Text: ' + color.toString() + ' ' + fontString + shadowString + textDecorationString);
+
+            this.indent += 2;
+            textBounds.forEach(function (textBound) {
+                _this.writeLine('[' + Math.round(textBound.bounds.left) + ', ' + Math.round(textBound.bounds.top) + ']: ' + textBound.text);
+            });
+            this.indent -= 2;
+        }
+    }, {
+        key: 'textDecoration',
+        value: function textDecoration(_textDecoration, color) {
+            if (_textDecoration) {
+                var textDecorationColor = (_textDecoration.textDecorationColor ? _textDecoration.textDecorationColor : color).toString();
+                var textDecorationLines = _textDecoration.textDecorationLine.map(this.textDecorationLine, this);
+                return _textDecoration ? ' ' + this.textDecorationStyle(_textDecoration.textDecorationStyle) + ' ' + textDecorationColor + ' ' + textDecorationLines.join(', ') : '';
+            }
+
+            return '';
+        }
+    }, {
+        key: 'textDecorationLine',
+        value: function textDecorationLine(_textDecorationLine) {
+            switch (_textDecorationLine) {
+                case _textDecoration2.TEXT_DECORATION_LINE.LINE_THROUGH:
+                    return 'line-through';
+                case _textDecoration2.TEXT_DECORATION_LINE.OVERLINE:
+                    return 'overline';
+                case _textDecoration2.TEXT_DECORATION_LINE.UNDERLINE:
+                    return 'underline';
+                case _textDecoration2.TEXT_DECORATION_LINE.BLINK:
+                    return 'blink';
+            }
+            return 'UNKNOWN';
+        }
+    }, {
+        key: 'textDecorationStyle',
+        value: function textDecorationStyle(_textDecorationStyle) {
+            switch (_textDecorationStyle) {
+                case _textDecoration2.TEXT_DECORATION_STYLE.SOLID:
+                    return 'solid';
+                case _textDecoration2.TEXT_DECORATION_STYLE.DOTTED:
+                    return 'dotted';
+                case _textDecoration2.TEXT_DECORATION_STYLE.DOUBLE:
+                    return 'double';
+                case _textDecoration2.TEXT_DECORATION_STYLE.DASHED:
+                    return 'dashed';
+                case _textDecoration2.TEXT_DECORATION_STYLE.WAVY:
+                    return 'WAVY';
+            }
+            return 'UNKNOWN';
+        }
+    }, {
+        key: 'setOpacity',
+        value: function setOpacity(opacity) {
+            this.writeLine('Opacity: ' + opacity);
+        }
+    }, {
+        key: 'transform',
+        value: function transform(offsetX, offsetY, matrix, callback) {
+            this.writeLine('Transform: (' + Math.round(offsetX) + ', ' + Math.round(offsetY) + ') [' + matrix.map(function (v) {
+                return Math.round(v * 100) / 100;
+            }).join(', ') + ']');
+            this.indent += 2;
+            callback();
+            this.indent -= 2;
+        }
+    }, {
+        key: 'writeLine',
+        value: function writeLine(text) {
+            this.lines.push('' + new Array(this.indent + 1).join(' ') + text);
+        }
+    }]);
+
+    return RefTestRenderer;
+}();
+
+module.exports = RefTestRenderer;
+
+/***/ }),
+/* 1 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+
+var punycode = __webpack_require__(2);
+var util = __webpack_require__(5);
+
+exports.parse = urlParse;
+exports.resolve = urlResolve;
+exports.resolveObject = urlResolveObject;
+exports.format = urlFormat;
+
+exports.Url = Url;
+
+function Url() {
+  this.protocol = null;
+  this.slashes = null;
+  this.auth = null;
+  this.host = null;
+  this.port = null;
+  this.hostname = null;
+  this.hash = null;
+  this.search = null;
+  this.query = null;
+  this.pathname = null;
+  this.path = null;
+  this.href = null;
+}
+
+// Reference: RFC 3986, RFC 1808, RFC 2396
+
+// define these here so at least they only have to be
+// compiled once on the first module load.
+var protocolPattern = /^([a-z0-9.+-]+:)/i,
+    portPattern = /:[0-9]*$/,
+
+    // Special case for a simple path URL
+    simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,
+
+    // RFC 2396: characters reserved for delimiting URLs.
+    // We actually just auto-escape these.
+    delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],
+
+    // RFC 2396: characters not allowed for various reasons.
+    unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),
+
+    // Allowed by RFCs, but cause of XSS attacks.  Always escape these.
+    autoEscape = ['\''].concat(unwise),
+    // Characters that are never ever allowed in a hostname.
+    // Note that any invalid chars are also handled, but these
+    // are the ones that are *expected* to be seen, so we fast-path
+    // them.
+    nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
+    hostEndingChars = ['/', '?', '#'],
+    hostnameMaxLen = 255,
+    hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,
+    hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,
+    // protocols that can allow "unsafe" and "unwise" chars.
+    unsafeProtocol = {
+      'javascript': true,
+      'javascript:': true
+    },
+    // protocols that never have a hostname.
+    hostlessProtocol = {
+      'javascript': true,
+      'javascript:': true
+    },
+    // protocols that always contain a // bit.
+    slashedProtocol = {
+      'http': true,
+      'https': true,
+      'ftp': true,
+      'gopher': true,
+      'file': true,
+      'http:': true,
+      'https:': true,
+      'ftp:': true,
+      'gopher:': true,
+      'file:': true
+    },
+    querystring = __webpack_require__(6);
+
+function urlParse(url, parseQueryString, slashesDenoteHost) {
+  if (url && util.isObject(url) && url instanceof Url) return url;
+
+  var u = new Url;
+  u.parse(url, parseQueryString, slashesDenoteHost);
+  return u;
+}
+
+Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
+  if (!util.isString(url)) {
+    throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
+  }
+
+  // Copy chrome, IE, opera backslash-handling behavior.
+  // Back slashes before the query string get converted to forward slashes
+  // See: https://code.google.com/p/chromium/issues/detail?id=25916
+  var queryIndex = url.indexOf('?'),
+      splitter =
+          (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#',
+      uSplit = url.split(splitter),
+      slashRegex = /\\/g;
+  uSplit[0] = uSplit[0].replace(slashRegex, '/');
+  url = uSplit.join(splitter);
+
+  var rest = url;
+
+  // trim before proceeding.
+  // This is to support parse stuff like "  http://foo.com  \n"
+  rest = rest.trim();
+
+  if (!slashesDenoteHost && url.split('#').length === 1) {
+    // Try fast path regexp
+    var simplePath = simplePathPattern.exec(rest);
+    if (simplePath) {
+      this.path = rest;
+      this.href = rest;
+      this.pathname = simplePath[1];
+      if (simplePath[2]) {
+        this.search = simplePath[2];
+        if (parseQueryString) {
+          this.query = querystring.parse(this.search.substr(1));
+        } else {
+          this.query = this.search.substr(1);
+        }
+      } else if (parseQueryString) {
+        this.search = '';
+        this.query = {};
+      }
+      return this;
+    }
+  }
+
+  var proto = protocolPattern.exec(rest);
+  if (proto) {
+    proto = proto[0];
+    var lowerProto = proto.toLowerCase();
+    this.protocol = lowerProto;
+    rest = rest.substr(proto.length);
+  }
+
+  // figure out if it's got a host
+  // user@server is *always* interpreted as a hostname, and url
+  // resolution will treat //foo/bar as host=foo,path=bar because that's
+  // how the browser resolves relative URLs.
+  if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
+    var slashes = rest.substr(0, 2) === '//';
+    if (slashes && !(proto && hostlessProtocol[proto])) {
+      rest = rest.substr(2);
+      this.slashes = true;
+    }
+  }
+
+  if (!hostlessProtocol[proto] &&
+      (slashes || (proto && !slashedProtocol[proto]))) {
+
+    // there's a hostname.
+    // the first instance of /, ?, ;, or # ends the host.
+    //
+    // If there is an @ in the hostname, then non-host chars *are* allowed
+    // to the left of the last @ sign, unless some host-ending character
+    // comes *before* the @-sign.
+    // URLs are obnoxious.
+    //
+    // ex:
+    // http://a@b@c/ => user:a@b host:c
+    // http://a@b?@c => user:a host:c path:/?@c
+
+    // v0.12 TODO(isaacs): This is not quite how Chrome does things.
+    // Review our test case against browsers more comprehensively.
+
+    // find the first instance of any hostEndingChars
+    var hostEnd = -1;
+    for (var i = 0; i < hostEndingChars.length; i++) {
+      var hec = rest.indexOf(hostEndingChars[i]);
+      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
+        hostEnd = hec;
+    }
+
+    // at this point, either we have an explicit point where the
+    // auth portion cannot go past, or the last @ char is the decider.
+    var auth, atSign;
+    if (hostEnd === -1) {
+      // atSign can be anywhere.
+      atSign = rest.lastIndexOf('@');
+    } else {
+      // atSign must be in auth portion.
+      // http://a@b/c@d => host:b auth:a path:/c@d
+      atSign = rest.lastIndexOf('@', hostEnd);
+    }
+
+    // Now we have a portion which is definitely the auth.
+    // Pull that off.
+    if (atSign !== -1) {
+      auth = rest.slice(0, atSign);
+      rest = rest.slice(atSign + 1);
+      this.auth = decodeURIComponent(auth);
+    }
+
+    // the host is the remaining to the left of the first non-host char
+    hostEnd = -1;
+    for (var i = 0; i < nonHostChars.length; i++) {
+      var hec = rest.indexOf(nonHostChars[i]);
+      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
+        hostEnd = hec;
+    }
+    // if we still have not hit it, then the entire thing is a host.
+    if (hostEnd === -1)
+      hostEnd = rest.length;
+
+    this.host = rest.slice(0, hostEnd);
+    rest = rest.slice(hostEnd);
+
+    // pull out port.
+    this.parseHost();
+
+    // we've indicated that there is a hostname,
+    // so even if it's empty, it has to be present.
+    this.hostname = this.hostname || '';
+
+    // if hostname begins with [ and ends with ]
+    // assume that it's an IPv6 address.
+    var ipv6Hostname = this.hostname[0] === '[' &&
+        this.hostname[this.hostname.length - 1] === ']';
+
+    // validate a little.
+    if (!ipv6Hostname) {
+      var hostparts = this.hostname.split(/\./);
+      for (var i = 0, l = hostparts.length; i < l; i++) {
+        var part = hostparts[i];
+        if (!part) continue;
+        if (!part.match(hostnamePartPattern)) {
+          var newpart = '';
+          for (var j = 0, k = part.length; j < k; j++) {
+            if (part.charCodeAt(j) > 127) {
+              // we replace non-ASCII char with a temporary placeholder
+              // we need this to make sure size of hostname is not
+              // broken by replacing non-ASCII by nothing
+              newpart += 'x';
+            } else {
+              newpart += part[j];
+            }
+          }
+          // we test again with ASCII char only
+          if (!newpart.match(hostnamePartPattern)) {
+            var validParts = hostparts.slice(0, i);
+            var notHost = hostparts.slice(i + 1);
+            var bit = part.match(hostnamePartStart);
+            if (bit) {
+              validParts.push(bit[1]);
+              notHost.unshift(bit[2]);
+            }
+            if (notHost.length) {
+              rest = '/' + notHost.join('.') + rest;
+            }
+            this.hostname = validParts.join('.');
+            break;
+          }
+        }
+      }
+    }
+
+    if (this.hostname.length > hostnameMaxLen) {
+      this.hostname = '';
+    } else {
+      // hostnames are always lower case.
+      this.hostname = this.hostname.toLowerCase();
+    }
+
+    if (!ipv6Hostname) {
+      // IDNA Support: Returns a punycoded representation of "domain".
+      // It only converts parts of the domain name that
+      // have non-ASCII characters, i.e. it doesn't matter if
+      // you call it with a domain that already is ASCII-only.
+      this.hostname = punycode.toASCII(this.hostname);
+    }
+
+    var p = this.port ? ':' + this.port : '';
+    var h = this.hostname || '';
+    this.host = h + p;
+    this.href += this.host;
+
+    // strip [ and ] from the hostname
+    // the host field still retains them, though
+    if (ipv6Hostname) {
+      this.hostname = this.hostname.substr(1, this.hostname.length - 2);
+      if (rest[0] !== '/') {
+        rest = '/' + rest;
+      }
+    }
+  }
+
+  // now rest is set to the post-host stuff.
+  // chop off any delim chars.
+  if (!unsafeProtocol[lowerProto]) {
+
+    // First, make 100% sure that any "autoEscape" chars get
+    // escaped, even if encodeURIComponent doesn't think they
+    // need to be.
+    for (var i = 0, l = autoEscape.length; i < l; i++) {
+      var ae = autoEscape[i];
+      if (rest.indexOf(ae) === -1)
+        continue;
+      var esc = encodeURIComponent(ae);
+      if (esc === ae) {
+        esc = escape(ae);
+      }
+      rest = rest.split(ae).join(esc);
+    }
+  }
+
+
+  // chop off from the tail first.
+  var hash = rest.indexOf('#');
+  if (hash !== -1) {
+    // got a fragment string.
+    this.hash = rest.substr(hash);
+    rest = rest.slice(0, hash);
+  }
+  var qm = rest.indexOf('?');
+  if (qm !== -1) {
+    this.search = rest.substr(qm);
+    this.query = rest.substr(qm + 1);
+    if (parseQueryString) {
+      this.query = querystring.parse(this.query);
+    }
+    rest = rest.slice(0, qm);
+  } else if (parseQueryString) {
+    // no query string, but parseQueryString still requested
+    this.search = '';
+    this.query = {};
+  }
+  if (rest) this.pathname = rest;
+  if (slashedProtocol[lowerProto] &&
+      this.hostname && !this.pathname) {
+    this.pathname = '/';
+  }
+
+  //to support http.request
+  if (this.pathname || this.search) {
+    var p = this.pathname || '';
+    var s = this.search || '';
+    this.path = p + s;
+  }
+
+  // finally, reconstruct the href based on what has been validated.
+  this.href = this.format();
+  return this;
+};
+
+// format a parsed object into a url string
+function urlFormat(obj) {
+  // ensure it's an object, and not a string url.
+  // If it's an obj, this is a no-op.
+  // this way, you can call url_format() on strings
+  // to clean up potentially wonky urls.
+  if (util.isString(obj)) obj = urlParse(obj);
+  if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
+  return obj.format();
+}
+
+Url.prototype.format = function() {
+  var auth = this.auth || '';
+  if (auth) {
+    auth = encodeURIComponent(auth);
+    auth = auth.replace(/%3A/i, ':');
+    auth += '@';
+  }
+
+  var protocol = this.protocol || '',
+      pathname = this.pathname || '',
+      hash = this.hash || '',
+      host = false,
+      query = '';
+
+  if (this.host) {
+    host = auth + this.host;
+  } else if (this.hostname) {
+    host = auth + (this.hostname.indexOf(':') === -1 ?
+        this.hostname :
+        '[' + this.hostname + ']');
+    if (this.port) {
+      host += ':' + this.port;
+    }
+  }
+
+  if (this.query &&
+      util.isObject(this.query) &&
+      Object.keys(this.query).length) {
+    query = querystring.stringify(this.query);
+  }
+
+  var search = this.search || (query && ('?' + query)) || '';
+
+  if (protocol && protocol.substr(-1) !== ':') protocol += ':';
+
+  // only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.
+  // unless they had them to begin with.
+  if (this.slashes ||
+      (!protocol || slashedProtocol[protocol]) && host !== false) {
+    host = '//' + (host || '');
+    if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
+  } else if (!host) {
+    host = '';
+  }
+
+  if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
+  if (search && search.charAt(0) !== '?') search = '?' + search;
+
+  pathname = pathname.replace(/[?#]/g, function(match) {
+    return encodeURIComponent(match);
+  });
+  search = search.replace('#', '%23');
+
+  return protocol + host + pathname + search + hash;
+};
+
+function urlResolve(source, relative) {
+  return urlParse(source, false, true).resolve(relative);
+}
+
+Url.prototype.resolve = function(relative) {
+  return this.resolveObject(urlParse(relative, false, true)).format();
+};
+
+function urlResolveObject(source, relative) {
+  if (!source) return relative;
+  return urlParse(source, false, true).resolveObject(relative);
+}
+
+Url.prototype.resolveObject = function(relative) {
+  if (util.isString(relative)) {
+    var rel = new Url();
+    rel.parse(relative, false, true);
+    relative = rel;
+  }
+
+  var result = new Url();
+  var tkeys = Object.keys(this);
+  for (var tk = 0; tk < tkeys.length; tk++) {
+    var tkey = tkeys[tk];
+    result[tkey] = this[tkey];
+  }
+
+  // hash is always overridden, no matter what.
+  // even href="" will remove it.
+  result.hash = relative.hash;
+
+  // if the relative url is empty, then there's nothing left to do here.
+  if (relative.href === '') {
+    result.href = result.format();
+    return result;
+  }
+
+  // hrefs like //foo/bar always cut to the protocol.
+  if (relative.slashes && !relative.protocol) {
+    // take everything except the protocol from relative
+    var rkeys = Object.keys(relative);
+    for (var rk = 0; rk < rkeys.length; rk++) {
+      var rkey = rkeys[rk];
+      if (rkey !== 'protocol')
+        result[rkey] = relative[rkey];
+    }
+
+    //urlParse appends trailing / to urls like http://www.example.com
+    if (slashedProtocol[result.protocol] &&
+        result.hostname && !result.pathname) {
+      result.path = result.pathname = '/';
+    }
+
+    result.href = result.format();
+    return result;
+  }
+
+  if (relative.protocol && relative.protocol !== result.protocol) {
+    // if it's a known url protocol, then changing
+    // the protocol does weird things
+    // first, if it's not file:, then we MUST have a host,
+    // and if there was a path
+    // to begin with, then we MUST have a path.
+    // if it is file:, then the host is dropped,
+    // because that's known to be hostless.
+    // anything else is assumed to be absolute.
+    if (!slashedProtocol[relative.protocol]) {
+      var keys = Object.keys(relative);
+      for (var v = 0; v < keys.length; v++) {
+        var k = keys[v];
+        result[k] = relative[k];
+      }
+      result.href = result.format();
+      return result;
+    }
+
+    result.protocol = relative.protocol;
+    if (!relative.host && !hostlessProtocol[relative.protocol]) {
+      var relPath = (relative.pathname || '').split('/');
+      while (relPath.length && !(relative.host = relPath.shift()));
+      if (!relative.host) relative.host = '';
+      if (!relative.hostname) relative.hostname = '';
+      if (relPath[0] !== '') relPath.unshift('');
+      if (relPath.length < 2) relPath.unshift('');
+      result.pathname = relPath.join('/');
+    } else {
+      result.pathname = relative.pathname;
+    }
+    result.search = relative.search;
+    result.query = relative.query;
+    result.host = relative.host || '';
+    result.auth = relative.auth;
+    result.hostname = relative.hostname || relative.host;
+    result.port = relative.port;
+    // to support http.request
+    if (result.pathname || result.search) {
+      var p = result.pathname || '';
+      var s = result.search || '';
+      result.path = p + s;
+    }
+    result.slashes = result.slashes || relative.slashes;
+    result.href = result.format();
+    return result;
+  }
+
+  var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
+      isRelAbs = (
+          relative.host ||
+          relative.pathname && relative.pathname.charAt(0) === '/'
+      ),
+      mustEndAbs = (isRelAbs || isSourceAbs ||
+                    (result.host && relative.pathname)),
+      removeAllDots = mustEndAbs,
+      srcPath = result.pathname && result.pathname.split('/') || [],
+      relPath = relative.pathname && relative.pathname.split('/') || [],
+      psychotic = result.protocol && !slashedProtocol[result.protocol];
+
+  // if the url is a non-slashed url, then relative
+  // links like ../.. should be able
+  // to crawl up to the hostname, as well.  This is strange.
+  // result.protocol has already been set by now.
+  // Later on, put the first path part into the host field.
+  if (psychotic) {
+    result.hostname = '';
+    result.port = null;
+    if (result.host) {
+      if (srcPath[0] === '') srcPath[0] = result.host;
+      else srcPath.unshift(result.host);
+    }
+    result.host = '';
+    if (relative.protocol) {
+      relative.hostname = null;
+      relative.port = null;
+      if (relative.host) {
+        if (relPath[0] === '') relPath[0] = relative.host;
+        else relPath.unshift(relative.host);
+      }
+      relative.host = null;
+    }
+    mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
+  }
+
+  if (isRelAbs) {
+    // it's absolute.
+    result.host = (relative.host || relative.host === '') ?
+                  relative.host : result.host;
+    result.hostname = (relative.hostname || relative.hostname === '') ?
+                      relative.hostname : result.hostname;
+    result.search = relative.search;
+    result.query = relative.query;
+    srcPath = relPath;
+    // fall through to the dot-handling below.
+  } else if (relPath.length) {
+    // it's relative
+    // throw away the existing file, and take the new path instead.
+    if (!srcPath) srcPath = [];
+    srcPath.pop();
+    srcPath = srcPath.concat(relPath);
+    result.search = relative.search;
+    result.query = relative.query;
+  } else if (!util.isNullOrUndefined(relative.search)) {
+    // just pull out the search.
+    // like href='?foo'.
+    // Put this after the other two cases because it simplifies the booleans
+    if (psychotic) {
+      result.hostname = result.host = srcPath.shift();
+      //occationaly the auth can get stuck only in host
+      //this especially happens in cases like
+      //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
+      var authInHost = result.host && result.host.indexOf('@') > 0 ?
+                       result.host.split('@') : false;
+      if (authInHost) {
+        result.auth = authInHost.shift();
+        result.host = result.hostname = authInHost.shift();
+      }
+    }
+    result.search = relative.search;
+    result.query = relative.query;
+    //to support http.request
+    if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
+      result.path = (result.pathname ? result.pathname : '') +
+                    (result.search ? result.search : '');
+    }
+    result.href = result.format();
+    return result;
+  }
+
+  if (!srcPath.length) {
+    // no path at all.  easy.
+    // we've already handled the other stuff above.
+    result.pathname = null;
+    //to support http.request
+    if (result.search) {
+      result.path = '/' + result.search;
+    } else {
+      result.path = null;
+    }
+    result.href = result.format();
+    return result;
+  }
+
+  // if a url ENDs in . or .., then it must get a trailing slash.
+  // however, if it ends in anything else non-slashy,
+  // then it must NOT get a trailing slash.
+  var last = srcPath.slice(-1)[0];
+  var hasTrailingSlash = (
+      (result.host || relative.host || srcPath.length > 1) &&
+      (last === '.' || last === '..') || last === '');
+
+  // strip single dots, resolve double dots to parent dir
+  // if the path tries to go above the root, `up` ends up > 0
+  var up = 0;
+  for (var i = srcPath.length; i >= 0; i--) {
+    last = srcPath[i];
+    if (last === '.') {
+      srcPath.splice(i, 1);
+    } else if (last === '..') {
+      srcPath.splice(i, 1);
+      up++;
+    } else if (up) {
+      srcPath.splice(i, 1);
+      up--;
+    }
+  }
+
+  // if the path is allowed to go above the root, restore leading ..s
+  if (!mustEndAbs && !removeAllDots) {
+    for (; up--; up) {
+      srcPath.unshift('..');
+    }
+  }
+
+  if (mustEndAbs && srcPath[0] !== '' &&
+      (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
+    srcPath.unshift('');
+  }
+
+  if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
+    srcPath.push('');
+  }
+
+  var isAbsolute = srcPath[0] === '' ||
+      (srcPath[0] && srcPath[0].charAt(0) === '/');
+
+  // put the host back
+  if (psychotic) {
+    result.hostname = result.host = isAbsolute ? '' :
+                                    srcPath.length ? srcPath.shift() : '';
+    //occationaly the auth can get stuck only in host
+    //this especially happens in cases like
+    //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
+    var authInHost = result.host && result.host.indexOf('@') > 0 ?
+                     result.host.split('@') : false;
+    if (authInHost) {
+      result.auth = authInHost.shift();
+      result.host = result.hostname = authInHost.shift();
+    }
+  }
+
+  mustEndAbs = mustEndAbs || (result.host && srcPath.length);
+
+  if (mustEndAbs && !isAbsolute) {
+    srcPath.unshift('');
+  }
+
+  if (!srcPath.length) {
+    result.pathname = null;
+    result.path = null;
+  } else {
+    result.pathname = srcPath.join('/');
+  }
+
+  //to support request.http
+  if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
+    result.path = (result.pathname ? result.pathname : '') +
+                  (result.search ? result.search : '');
+  }
+  result.auth = relative.auth || result.auth;
+  result.slashes = result.slashes || relative.slashes;
+  result.href = result.format();
+  return result;
+};
+
+Url.prototype.parseHost = function() {
+  var host = this.host;
+  var port = portPattern.exec(host);
+  if (port) {
+    port = port[0];
+    if (port !== ':') {
+      this.port = port.substr(1);
+    }
+    host = host.substr(0, host.length - port.length);
+  }
+  if (host) this.hostname = host;
+};
+
+
+/***/ }),
+/* 2 */
+/***/ (function(module, exports, __webpack_require__) {
+
+/* WEBPACK VAR INJECTION */(function(module, global) {var __WEBPACK_AMD_DEFINE_RESULT__;/*! https://mths.be/punycode v1.3.2 by @mathias */
+;(function(root) {
+
+	/** Detect free variables */
+	var freeExports = typeof exports == 'object' && exports &&
+		!exports.nodeType && exports;
+	var freeModule = typeof module == 'object' && module &&
+		!module.nodeType && module;
+	var freeGlobal = typeof global == 'object' && global;
+	if (
+		freeGlobal.global === freeGlobal ||
+		freeGlobal.window === freeGlobal ||
+		freeGlobal.self === freeGlobal
+	) {
+		root = freeGlobal;
+	}
+
+	/**
+	 * The `punycode` object.
+	 * @name punycode
+	 * @type Object
+	 */
+	var punycode,
+
+	/** Highest positive signed 32-bit float value */
+	maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
+
+	/** Bootstring parameters */
+	base = 36,
+	tMin = 1,
+	tMax = 26,
+	skew = 38,
+	damp = 700,
+	initialBias = 72,
+	initialN = 128, // 0x80
+	delimiter = '-', // '\x2D'
+
+	/** Regular expressions */
+	regexPunycode = /^xn--/,
+	regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
+	regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
+
+	/** Error messages */
+	errors = {
+		'overflow': 'Overflow: input needs wider integers to process',
+		'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
+		'invalid-input': 'Invalid input'
+	},
+
+	/** Convenience shortcuts */
+	baseMinusTMin = base - tMin,
+	floor = Math.floor,
+	stringFromCharCode = String.fromCharCode,
+
+	/** Temporary variable */
+	key;
+
+	/*--------------------------------------------------------------------------*/
+
+	/**
+	 * A generic error utility function.
+	 * @private
+	 * @param {String} type The error type.
+	 * @returns {Error} Throws a `RangeError` with the applicable error message.
+	 */
+	function error(type) {
+		throw RangeError(errors[type]);
+	}
+
+	/**
+	 * A generic `Array#map` utility function.
+	 * @private
+	 * @param {Array} array The array to iterate over.
+	 * @param {Function} callback The function that gets called for every array
+	 * item.
+	 * @returns {Array} A new array of values returned by the callback function.
+	 */
+	function map(array, fn) {
+		var length = array.length;
+		var result = [];
+		while (length--) {
+			result[length] = fn(array[length]);
+		}
+		return result;
+	}
+
+	/**
+	 * A simple `Array#map`-like wrapper to work with domain name strings or email
+	 * addresses.
+	 * @private
+	 * @param {String} domain The domain name or email address.
+	 * @param {Function} callback The function that gets called for every
+	 * character.
+	 * @returns {Array} A new string of characters returned by the callback
+	 * function.
+	 */
+	function mapDomain(string, fn) {
+		var parts = string.split('@');
+		var result = '';
+		if (parts.length > 1) {
+			// In email addresses, only the domain name should be punycoded. Leave
+			// the local part (i.e. everything up to `@`) intact.
+			result = parts[0] + '@';
+			string = parts[1];
+		}
+		// Avoid `split(regex)` for IE8 compatibility. See #17.
+		string = string.replace(regexSeparators, '\x2E');
+		var labels = string.split('.');
+		var encoded = map(labels, fn).join('.');
+		return result + encoded;
+	}
+
+	/**
+	 * Creates an array containing the numeric code points of each Unicode
+	 * character in the string. While JavaScript uses UCS-2 internally,
+	 * this function will convert a pair of surrogate halves (each of which
+	 * UCS-2 exposes as separate characters) into a single code point,
+	 * matching UTF-16.
+	 * @see `punycode.ucs2.encode`
+	 * @see <https://mathiasbynens.be/notes/javascript-encoding>
+	 * @memberOf punycode.ucs2
+	 * @name decode
+	 * @param {String} string The Unicode input string (UCS-2).
+	 * @returns {Array} The new array of code points.
+	 */
+	function ucs2decode(string) {
+		var output = [],
+		    counter = 0,
+		    length = string.length,
+		    value,
+		    extra;
+		while (counter < length) {
+			value = string.charCodeAt(counter++);
+			if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
+				// high surrogate, and there is a next character
+				extra = string.charCodeAt(counter++);
+				if ((extra & 0xFC00) == 0xDC00) { // low surrogate
+					output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
+				} else {
+					// unmatched surrogate; only append this code unit, in case the next
+					// code unit is the high surrogate of a surrogate pair
+					output.push(value);
+					counter--;
+				}
+			} else {
+				output.push(value);
+			}
+		}
+		return output;
+	}
+
+	/**
+	 * Creates a string based on an array of numeric code points.
+	 * @see `punycode.ucs2.decode`
+	 * @memberOf punycode.ucs2
+	 * @name encode
+	 * @param {Array} codePoints The array of numeric code points.
+	 * @returns {String} The new Unicode string (UCS-2).
+	 */
+	function ucs2encode(array) {
+		return map(array, function(value) {
+			var output = '';
+			if (value > 0xFFFF) {
+				value -= 0x10000;
+				output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
+				value = 0xDC00 | value & 0x3FF;
+			}
+			output += stringFromCharCode(value);
+			return output;
+		}).join('');
+	}
+
+	/**
+	 * Converts a basic code point into a digit/integer.
+	 * @see `digitToBasic()`
+	 * @private
+	 * @param {Number} codePoint The basic numeric code point value.
+	 * @returns {Number} The numeric value of a basic code point (for use in
+	 * representing integers) in the range `0` to `base - 1`, or `base` if
+	 * the code point does not represent a value.
+	 */
+	function basicToDigit(codePoint) {
+		if (codePoint - 48 < 10) {
+			return codePoint - 22;
+		}
+		if (codePoint - 65 < 26) {
+			return codePoint - 65;
+		}
+		if (codePoint - 97 < 26) {
+			return codePoint - 97;
+		}
+		return base;
+	}
+
+	/**
+	 * Converts a digit/integer into a basic code point.
+	 * @see `basicToDigit()`
+	 * @private
+	 * @param {Number} digit The numeric value of a basic code point.
+	 * @returns {Number} The basic code point whose value (when used for
+	 * representing integers) is `digit`, which needs to be in the range
+	 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
+	 * used; else, the lowercase form is used. The behavior is undefined
+	 * if `flag` is non-zero and `digit` has no uppercase form.
+	 */
+	function digitToBasic(digit, flag) {
+		//  0..25 map to ASCII a..z or A..Z
+		// 26..35 map to ASCII 0..9
+		return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
+	}
+
+	/**
+	 * Bias adaptation function as per section 3.4 of RFC 3492.
+	 * http://tools.ietf.org/html/rfc3492#section-3.4
+	 * @private
+	 */
+	function adapt(delta, numPoints, firstTime) {
+		var k = 0;
+		delta = firstTime ? floor(delta / damp) : delta >> 1;
+		delta += floor(delta / numPoints);
+		for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
+			delta = floor(delta / baseMinusTMin);
+		}
+		return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
+	}
+
+	/**
+	 * Converts a Punycode string of ASCII-only symbols to a string of Unicode
+	 * symbols.
+	 * @memberOf punycode
+	 * @param {String} input The Punycode string of ASCII-only symbols.
+	 * @returns {String} The resulting string of Unicode symbols.
+	 */
+	function decode(input) {
+		// Don't use UCS-2
+		var output = [],
+		    inputLength = input.length,
+		    out,
+		    i = 0,
+		    n = initialN,
+		    bias = initialBias,
+		    basic,
+		    j,
+		    index,
+		    oldi,
+		    w,
+		    k,
+		    digit,
+		    t,
+		    /** Cached calculation results */
+		    baseMinusT;
+
+		// Handle the basic code points: let `basic` be the number of input code
+		// points before the last delimiter, or `0` if there is none, then copy
+		// the first basic code points to the output.
+
+		basic = input.lastIndexOf(delimiter);
+		if (basic < 0) {
+			basic = 0;
+		}
+
+		for (j = 0; j < basic; ++j) {
+			// if it's not a basic code point
+			if (input.charCodeAt(j) >= 0x80) {
+				error('not-basic');
+			}
+			output.push(input.charCodeAt(j));
+		}
+
+		// Main decoding loop: start just after the last delimiter if any basic code
+		// points were copied; start at the beginning otherwise.
+
+		for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
+
+			// `index` is the index of the next character to be consumed.
+			// Decode a generalized variable-length integer into `delta`,
+			// which gets added to `i`. The overflow checking is easier
+			// if we increase `i` as we go, then subtract off its starting
+			// value at the end to obtain `delta`.
+			for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
+
+				if (index >= inputLength) {
+					error('invalid-input');
+				}
+
+				digit = basicToDigit(input.charCodeAt(index++));
+
+				if (digit >= base || digit > floor((maxInt - i) / w)) {
+					error('overflow');
+				}
+
+				i += digit * w;
+				t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
+
+				if (digit < t) {
+					break;
+				}
+
+				baseMinusT = base - t;
+				if (w > floor(maxInt / baseMinusT)) {
+					error('overflow');
+				}
+
+				w *= baseMinusT;
+
+			}
+
+			out = output.length + 1;
+			bias = adapt(i - oldi, out, oldi == 0);
+
+			// `i` was supposed to wrap around from `out` to `0`,
+			// incrementing `n` each time, so we'll fix that now:
+			if (floor(i / out) > maxInt - n) {
+				error('overflow');
+			}
+
+			n += floor(i / out);
+			i %= out;
+
+			// Insert `n` at position `i` of the output
+			output.splice(i++, 0, n);
+
+		}
+
+		return ucs2encode(output);
+	}
+
+	/**
+	 * Converts a string of Unicode symbols (e.g. a domain name label) to a
+	 * Punycode string of ASCII-only symbols.
+	 * @memberOf punycode
+	 * @param {String} input The string of Unicode symbols.
+	 * @returns {String} The resulting Punycode string of ASCII-only symbols.
+	 */
+	function encode(input) {
+		var n,
+		    delta,
+		    handledCPCount,
+		    basicLength,
+		    bias,
+		    j,
+		    m,
+		    q,
+		    k,
+		    t,
+		    currentValue,
+		    output = [],
+		    /** `inputLength` will hold the number of code points in `input`. */
+		    inputLength,
+		    /** Cached calculation results */
+		    handledCPCountPlusOne,
+		    baseMinusT,
+		    qMinusT;
+
+		// Convert the input in UCS-2 to Unicode
+		input = ucs2decode(input);
+
+		// Cache the length
+		inputLength = input.length;
+
+		// Initialize the state
+		n = initialN;
+		delta = 0;
+		bias = initialBias;
+
+		// Handle the basic code points
+		for (j = 0; j < inputLength; ++j) {
+			currentValue = input[j];
+			if (currentValue < 0x80) {
+				output.push(stringFromCharCode(currentValue));
+			}
+		}
+
+		handledCPCount = basicLength = output.length;
+
+		// `handledCPCount` is the number of code points that have been handled;
+		// `basicLength` is the number of basic code points.
+
+		// Finish the basic string - if it is not empty - with a delimiter
+		if (basicLength) {
+			output.push(delimiter);
+		}
+
+		// Main encoding loop:
+		while (handledCPCount < inputLength) {
+
+			// All non-basic code points < n have been handled already. Find the next
+			// larger one:
+			for (m = maxInt, j = 0; j < inputLength; ++j) {
+				currentValue = input[j];
+				if (currentValue >= n && currentValue < m) {
+					m = currentValue;
+				}
+			}
+
+			// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
+			// but guard against overflow
+			handledCPCountPlusOne = handledCPCount + 1;
+			if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
+				error('overflow');
+			}
+
+			delta += (m - n) * handledCPCountPlusOne;
+			n = m;
+
+			for (j = 0; j < inputLength; ++j) {
+				currentValue = input[j];
+
+				if (currentValue < n && ++delta > maxInt) {
+					error('overflow');
+				}
+
+				if (currentValue == n) {
+					// Represent delta as a generalized variable-length integer
+					for (q = delta, k = base; /* no condition */; k += base) {
+						t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
+						if (q < t) {
+							break;
+						}
+						qMinusT = q - t;
+						baseMinusT = base - t;
+						output.push(
+							stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
+						);
+						q = floor(qMinusT / baseMinusT);
+					}
+
+					output.push(stringFromCharCode(digitToBasic(q, 0)));
+					bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
+					delta = 0;
+					++handledCPCount;
+				}
+			}
+
+			++delta;
+			++n;
+
+		}
+		return output.join('');
+	}
+
+	/**
+	 * Converts a Punycode string representing a domain name or an email address
+	 * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
+	 * it doesn't matter if you call it on a string that has already been
+	 * converted to Unicode.
+	 * @memberOf punycode
+	 * @param {String} input The Punycoded domain name or email address to
+	 * convert to Unicode.
+	 * @returns {String} The Unicode representation of the given Punycode
+	 * string.
+	 */
+	function toUnicode(input) {
+		return mapDomain(input, function(string) {
+			return regexPunycode.test(string)
+				? decode(string.slice(4).toLowerCase())
+				: string;
+		});
+	}
+
+	/**
+	 * Converts a Unicode string representing a domain name or an email address to
+	 * Punycode. Only the non-ASCII parts of the domain name will be converted,
+	 * i.e. it doesn't matter if you call it with a domain that's already in
+	 * ASCII.
+	 * @memberOf punycode
+	 * @param {String} input The domain name or email address to convert, as a
+	 * Unicode string.
+	 * @returns {String} The Punycode representation of the given domain name or
+	 * email address.
+	 */
+	function toASCII(input) {
+		return mapDomain(input, function(string) {
+			return regexNonASCII.test(string)
+				? 'xn--' + encode(string)
+				: string;
+		});
+	}
+
+	/*--------------------------------------------------------------------------*/
+
+	/** Define the public API */
+	punycode = {
+		/**
+		 * A string representing the current Punycode.js version number.
+		 * @memberOf punycode
+		 * @type String
+		 */
+		'version': '1.3.2',
+		/**
+		 * An object of methods to convert from JavaScript's internal character
+		 * representation (UCS-2) to Unicode code points, and back.
+		 * @see <https://mathiasbynens.be/notes/javascript-encoding>
+		 * @memberOf punycode
+		 * @type Object
+		 */
+		'ucs2': {
+			'decode': ucs2decode,
+			'encode': ucs2encode
+		},
+		'decode': decode,
+		'encode': encode,
+		'toASCII': toASCII,
+		'toUnicode': toUnicode
+	};
+
+	/** Expose `punycode` */
+	// Some AMD build optimizers, like r.js, check for specific condition patterns
+	// like the following:
+	if (
+		true
+	) {
+		!(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
+			return punycode;
+		}.call(exports, __webpack_require__, exports, module),
+				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
+	} else if (freeExports && freeModule) {
+		if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+
+			freeModule.exports = punycode;
+		} else { // in Narwhal or RingoJS v0.7.0-
+			for (key in punycode) {
+				punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
+			}
+		}
+	} else { // in Rhino or a web browser
+		root.punycode = punycode;
+	}
+
+}(this));
+
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3)(module), __webpack_require__(4)))
+
+/***/ }),
+/* 3 */
+/***/ (function(module, exports) {
+
+module.exports = function(module) {
+	if(!module.webpackPolyfill) {
+		module.deprecate = function() {};
+		module.paths = [];
+		// module.parent = undefined by default
+		if(!module.children) module.children = [];
+		Object.defineProperty(module, "loaded", {
+			enumerable: true,
+			get: function() {
+				return module.l;
+			}
+		});
+		Object.defineProperty(module, "id", {
+			enumerable: true,
+			get: function() {
+				return module.i;
+			}
+		});
+		module.webpackPolyfill = 1;
+	}
+	return module;
+};
+
+
+/***/ }),
+/* 4 */
+/***/ (function(module, exports) {
+
+var g;
+
+// This works in non-strict mode
+g = (function() {
+	return this;
+})();
+
+try {
+	// This works if eval is allowed (see CSP)
+	g = g || Function("return this")() || (1,eval)("this");
+} catch(e) {
+	// This works if the window reference is available
+	if(typeof window === "object")
+		g = window;
+}
+
+// g can still be undefined, but nothing to do about it...
+// We return undefined, instead of nothing here, so it's
+// easier to handle this case. if(!global) { ...}
+
+module.exports = g;
+
+
+/***/ }),
+/* 5 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+module.exports = {
+  isString: function(arg) {
+    return typeof(arg) === 'string';
+  },
+  isObject: function(arg) {
+    return typeof(arg) === 'object' && arg !== null;
+  },
+  isNull: function(arg) {
+    return arg === null;
+  },
+  isNullOrUndefined: function(arg) {
+    return arg == null;
+  }
+};
+
+
+/***/ }),
+/* 6 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+exports.decode = exports.parse = __webpack_require__(7);
+exports.encode = exports.stringify = __webpack_require__(8);
+
+
+/***/ }),
+/* 7 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+
+// If obj.hasOwnProperty has been overridden, then calling
+// obj.hasOwnProperty(prop) will break.
+// See: https://github.com/joyent/node/issues/1707
+function hasOwnProperty(obj, prop) {
+  return Object.prototype.hasOwnProperty.call(obj, prop);
+}
+
+module.exports = function(qs, sep, eq, options) {
+  sep = sep || '&';
+  eq = eq || '=';
+  var obj = {};
+
+  if (typeof qs !== 'string' || qs.length === 0) {
+    return obj;
+  }
+
+  var regexp = /\+/g;
+  qs = qs.split(sep);
+
+  var maxKeys = 1000;
+  if (options && typeof options.maxKeys === 'number') {
+    maxKeys = options.maxKeys;
+  }
+
+  var len = qs.length;
+  // maxKeys <= 0 means that we should not limit keys count
+  if (maxKeys > 0 && len > maxKeys) {
+    len = maxKeys;
+  }
+
+  for (var i = 0; i < len; ++i) {
+    var x = qs[i].replace(regexp, '%20'),
+        idx = x.indexOf(eq),
+        kstr, vstr, k, v;
+
+    if (idx >= 0) {
+      kstr = x.substr(0, idx);
+      vstr = x.substr(idx + 1);
+    } else {
+      kstr = x;
+      vstr = '';
+    }
+
+    k = decodeURIComponent(kstr);
+    v = decodeURIComponent(vstr);
+
+    if (!hasOwnProperty(obj, k)) {
+      obj[k] = v;
+    } else if (isArray(obj[k])) {
+      obj[k].push(v);
+    } else {
+      obj[k] = [obj[k], v];
+    }
+  }
+
+  return obj;
+};
+
+var isArray = Array.isArray || function (xs) {
+  return Object.prototype.toString.call(xs) === '[object Array]';
+};
+
+
+/***/ }),
+/* 8 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+
+var stringifyPrimitive = function(v) {
+  switch (typeof v) {
+    case 'string':
+      return v;
+
+    case 'boolean':
+      return v ? 'true' : 'false';
+
+    case 'number':
+      return isFinite(v) ? v : '';
+
+    default:
+      return '';
+  }
+};
+
+module.exports = function(obj, sep, eq, name) {
+  sep = sep || '&';
+  eq = eq || '=';
+  if (obj === null) {
+    obj = undefined;
+  }
+
+  if (typeof obj === 'object') {
+    return map(objectKeys(obj), function(k) {
+      var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
+      if (isArray(obj[k])) {
+        return map(obj[k], function(v) {
+          return ks + encodeURIComponent(stringifyPrimitive(v));
+        }).join(sep);
+      } else {
+        return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
+      }
+    }).join(sep);
+
+  }
+
+  if (!name) return '';
+  return encodeURIComponent(stringifyPrimitive(name)) + eq +
+         encodeURIComponent(stringifyPrimitive(obj));
+};
+
+var isArray = Array.isArray || function (xs) {
+  return Object.prototype.toString.call(xs) === '[object Array]';
+};
+
+function map (xs, f) {
+  if (xs.map) return xs.map(f);
+  var res = [];
+  for (var i = 0; i < xs.length; i++) {
+    res.push(f(xs[i], i));
+  }
+  return res;
+}
+
+var objectKeys = Object.keys || function (obj) {
+  var res = [];
+  for (var key in obj) {
+    if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
+  }
+  return res;
+};
+
+
+/***/ }),
+/* 9 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseTextDecoration = exports.TEXT_DECORATION_LINE = exports.TEXT_DECORATION = exports.TEXT_DECORATION_STYLE = undefined;
+
+var _Color = __webpack_require__(10);
+
+var _Color2 = _interopRequireDefault(_Color);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var TEXT_DECORATION_STYLE = exports.TEXT_DECORATION_STYLE = {
+    SOLID: 0,
+    DOUBLE: 1,
+    DOTTED: 2,
+    DASHED: 3,
+    WAVY: 4
+};
+
+var TEXT_DECORATION = exports.TEXT_DECORATION = {
+    NONE: null
+};
+
+var TEXT_DECORATION_LINE = exports.TEXT_DECORATION_LINE = {
+    UNDERLINE: 1,
+    OVERLINE: 2,
+    LINE_THROUGH: 3,
+    BLINK: 4
+};
+
+var parseLine = function parseLine(line) {
+    switch (line) {
+        case 'underline':
+            return TEXT_DECORATION_LINE.UNDERLINE;
+        case 'overline':
+            return TEXT_DECORATION_LINE.OVERLINE;
+        case 'line-through':
+            return TEXT_DECORATION_LINE.LINE_THROUGH;
+    }
+    return TEXT_DECORATION_LINE.BLINK;
+};
+
+var parseTextDecorationLine = function parseTextDecorationLine(line) {
+    if (line === 'none') {
+        return null;
+    }
+
+    return line.split(' ').map(parseLine);
+};
+
+var parseTextDecorationStyle = function parseTextDecorationStyle(style) {
+    switch (style) {
+        case 'double':
+            return TEXT_DECORATION_STYLE.DOUBLE;
+        case 'dotted':
+            return TEXT_DECORATION_STYLE.DOTTED;
+        case 'dashed':
+            return TEXT_DECORATION_STYLE.DASHED;
+        case 'wavy':
+            return TEXT_DECORATION_STYLE.WAVY;
+    }
+    return TEXT_DECORATION_STYLE.SOLID;
+};
+
+var parseTextDecoration = exports.parseTextDecoration = function parseTextDecoration(style) {
+    var textDecorationLine = parseTextDecorationLine(style.textDecorationLine ? style.textDecorationLine : style.textDecoration);
+    if (textDecorationLine === null) {
+        return TEXT_DECORATION.NONE;
+    }
+
+    var textDecorationColor = style.textDecorationColor ? new _Color2.default(style.textDecorationColor) : null;
+    var textDecorationStyle = parseTextDecorationStyle(style.textDecorationStyle);
+
+    return {
+        textDecorationLine: textDecorationLine,
+        textDecorationColor: textDecorationColor,
+        textDecorationStyle: textDecorationStyle
+    };
+};
+
+/***/ }),
+/* 10 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+// http://dev.w3.org/csswg/css-color/
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var HEX3 = /^#([a-f0-9]{3})$/i;
+var hex3 = function hex3(value) {
+    var match = value.match(HEX3);
+    if (match) {
+        return [parseInt(match[1][0] + match[1][0], 16), parseInt(match[1][1] + match[1][1], 16), parseInt(match[1][2] + match[1][2], 16), null];
+    }
+    return false;
+};
+
+var HEX6 = /^#([a-f0-9]{6})$/i;
+var hex6 = function hex6(value) {
+    var match = value.match(HEX6);
+    if (match) {
+        return [parseInt(match[1].substring(0, 2), 16), parseInt(match[1].substring(2, 4), 16), parseInt(match[1].substring(4, 6), 16), null];
+    }
+    return false;
+};
+
+var RGB = /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/;
+var rgb = function rgb(value) {
+    var match = value.match(RGB);
+    if (match) {
+        return [Number(match[1]), Number(match[2]), Number(match[3]), null];
+    }
+    return false;
+};
+
+var RGBA = /^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d?\.?\d+)\s*\)$/;
+var rgba = function rgba(value) {
+    var match = value.match(RGBA);
+    if (match && match.length > 4) {
+        return [Number(match[1]), Number(match[2]), Number(match[3]), Number(match[4])];
+    }
+    return false;
+};
+
+var fromArray = function fromArray(array) {
+    return [Math.min(array[0], 255), Math.min(array[1], 255), Math.min(array[2], 255), array.length > 3 ? array[3] : null];
+};
+
+var namedColor = function namedColor(name) {
+    var color = NAMED_COLORS[name.toLowerCase()];
+    return color ? color : false;
+};
+
+var Color = function () {
+    function Color(value) {
+        _classCallCheck(this, Color);
+
+        var _ref = Array.isArray(value) ? fromArray(value) : hex3(value) || rgb(value) || rgba(value) || namedColor(value) || hex6(value) || [0, 0, 0, null],
+            _ref2 = _slicedToArray(_ref, 4),
+            r = _ref2[0],
+            g = _ref2[1],
+            b = _ref2[2],
+            a = _ref2[3];
+
+        this.r = r;
+        this.g = g;
+        this.b = b;
+        this.a = a;
+    }
+
+    _createClass(Color, [{
+        key: 'isTransparent',
+        value: function isTransparent() {
+            return this.a === 0;
+        }
+    }, {
+        key: 'toString',
+        value: function toString() {
+            return this.a !== null && this.a !== 1 ? 'rgba(' + this.r + ',' + this.g + ',' + this.b + ',' + this.a + ')' : 'rgb(' + this.r + ',' + this.g + ',' + this.b + ')';
+        }
+    }]);
+
+    return Color;
+}();
+
+exports.default = Color;
+
+
+var NAMED_COLORS = {
+    transparent: [0, 0, 0, 0],
+    aliceblue: [240, 248, 255, null],
+    antiquewhite: [250, 235, 215, null],
+    aqua: [0, 255, 255, null],
+    aquamarine: [127, 255, 212, null],
+    azure: [240, 255, 255, null],
+    beige: [245, 245, 220, null],
+    bisque: [255, 228, 196, null],
+    black: [0, 0, 0, null],
+    blanchedalmond: [255, 235, 205, null],
+    blue: [0, 0, 255, null],
+    blueviolet: [138, 43, 226, null],
+    brown: [165, 42, 42, null],
+    burlywood: [222, 184, 135, null],
+    cadetblue: [95, 158, 160, null],
+    chartreuse: [127, 255, 0, null],
+    chocolate: [210, 105, 30, null],
+    coral: [255, 127, 80, null],
+    cornflowerblue: [100, 149, 237, null],
+    cornsilk: [255, 248, 220, null],
+    crimson: [220, 20, 60, null],
+    cyan: [0, 255, 255, null],
+    darkblue: [0, 0, 139, null],
+    darkcyan: [0, 139, 139, null],
+    darkgoldenrod: [184, 134, 11, null],
+    darkgray: [169, 169, 169, null],
+    darkgreen: [0, 100, 0, null],
+    darkgrey: [169, 169, 169, null],
+    darkkhaki: [189, 183, 107, null],
+    darkmagenta: [139, 0, 139, null],
+    darkolivegreen: [85, 107, 47, null],
+    darkorange: [255, 140, 0, null],
+    darkorchid: [153, 50, 204, null],
+    darkred: [139, 0, 0, null],
+    darksalmon: [233, 150, 122, null],
+    darkseagreen: [143, 188, 143, null],
+    darkslateblue: [72, 61, 139, null],
+    darkslategray: [47, 79, 79, null],
+    darkslategrey: [47, 79, 79, null],
+    darkturquoise: [0, 206, 209, null],
+    darkviolet: [148, 0, 211, null],
+    deeppink: [255, 20, 147, null],
+    deepskyblue: [0, 191, 255, null],
+    dimgray: [105, 105, 105, null],
+    dimgrey: [105, 105, 105, null],
+    dodgerblue: [30, 144, 255, null],
+    firebrick: [178, 34, 34, null],
+    floralwhite: [255, 250, 240, null],
+    forestgreen: [34, 139, 34, null],
+    fuchsia: [255, 0, 255, null],
+    gainsboro: [220, 220, 220, null],
+    ghostwhite: [248, 248, 255, null],
+    gold: [255, 215, 0, null],
+    goldenrod: [218, 165, 32, null],
+    gray: [128, 128, 128, null],
+    green: [0, 128, 0, null],
+    greenyellow: [173, 255, 47, null],
+    grey: [128, 128, 128, null],
+    honeydew: [240, 255, 240, null],
+    hotpink: [255, 105, 180, null],
+    indianred: [205, 92, 92, null],
+    indigo: [75, 0, 130, null],
+    ivory: [255, 255, 240, null],
+    khaki: [240, 230, 140, null],
+    lavender: [230, 230, 250, null],
+    lavenderblush: [255, 240, 245, null],
+    lawngreen: [124, 252, 0, null],
+    lemonchiffon: [255, 250, 205, null],
+    lightblue: [173, 216, 230, null],
+    lightcoral: [240, 128, 128, null],
+    lightcyan: [224, 255, 255, null],
+    lightgoldenrodyellow: [250, 250, 210, null],
+    lightgray: [211, 211, 211, null],
+    lightgreen: [144, 238, 144, null],
+    lightgrey: [211, 211, 211, null],
+    lightpink: [255, 182, 193, null],
+    lightsalmon: [255, 160, 122, null],
+    lightseagreen: [32, 178, 170, null],
+    lightskyblue: [135, 206, 250, null],
+    lightslategray: [119, 136, 153, null],
+    lightslategrey: [119, 136, 153, null],
+    lightsteelblue: [176, 196, 222, null],
+    lightyellow: [255, 255, 224, null],
+    lime: [0, 255, 0, null],
+    limegreen: [50, 205, 50, null],
+    linen: [250, 240, 230, null],
+    magenta: [255, 0, 255, null],
+    maroon: [128, 0, 0, null],
+    mediumaquamarine: [102, 205, 170, null],
+    mediumblue: [0, 0, 205, null],
+    mediumorchid: [186, 85, 211, null],
+    mediumpurple: [147, 112, 219, null],
+    mediumseagreen: [60, 179, 113, null],
+    mediumslateblue: [123, 104, 238, null],
+    mediumspringgreen: [0, 250, 154, null],
+    mediumturquoise: [72, 209, 204, null],
+    mediumvioletred: [199, 21, 133, null],
+    midnightblue: [25, 25, 112, null],
+    mintcream: [245, 255, 250, null],
+    mistyrose: [255, 228, 225, null],
+    moccasin: [255, 228, 181, null],
+    navajowhite: [255, 222, 173, null],
+    navy: [0, 0, 128, null],
+    oldlace: [253, 245, 230, null],
+    olive: [128, 128, 0, null],
+    olivedrab: [107, 142, 35, null],
+    orange: [255, 165, 0, null],
+    orangered: [255, 69, 0, null],
+    orchid: [218, 112, 214, null],
+    palegoldenrod: [238, 232, 170, null],
+    palegreen: [152, 251, 152, null],
+    paleturquoise: [175, 238, 238, null],
+    palevioletred: [219, 112, 147, null],
+    papayawhip: [255, 239, 213, null],
+    peachpuff: [255, 218, 185, null],
+    peru: [205, 133, 63, null],
+    pink: [255, 192, 203, null],
+    plum: [221, 160, 221, null],
+    powderblue: [176, 224, 230, null],
+    purple: [128, 0, 128, null],
+    rebeccapurple: [102, 51, 153, null],
+    red: [255, 0, 0, null],
+    rosybrown: [188, 143, 143, null],
+    royalblue: [65, 105, 225, null],
+    saddlebrown: [139, 69, 19, null],
+    salmon: [250, 128, 114, null],
+    sandybrown: [244, 164, 96, null],
+    seagreen: [46, 139, 87, null],
+    seashell: [255, 245, 238, null],
+    sienna: [160, 82, 45, null],
+    silver: [192, 192, 192, null],
+    skyblue: [135, 206, 235, null],
+    slateblue: [106, 90, 205, null],
+    slategray: [112, 128, 144, null],
+    slategrey: [112, 128, 144, null],
+    snow: [255, 250, 250, null],
+    springgreen: [0, 255, 127, null],
+    steelblue: [70, 130, 180, null],
+    tan: [210, 180, 140, null],
+    teal: [0, 128, 128, null],
+    thistle: [216, 191, 216, null],
+    tomato: [255, 99, 71, null],
+    turquoise: [64, 224, 208, null],
+    violet: [238, 130, 238, null],
+    wheat: [245, 222, 179, null],
+    white: [255, 255, 255, null],
+    whitesmoke: [245, 245, 245, null],
+    yellow: [255, 255, 0, null],
+    yellowgreen: [154, 205, 50, null]
+};
+
+var TRANSPARENT = exports.TRANSPARENT = new Color([0, 0, 0, 0]);
+
+/***/ }),
+/* 11 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var PATH = exports.PATH = {
+    VECTOR: 0,
+    BEZIER_CURVE: 1,
+    CIRCLE: 2
+};
+
+/***/ })
+/******/ ]);
+});
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/html2canvas.js b/AstuteClient2/src/assets/html2canvas/dist/html2canvas.js
new file mode 100644
index 0000000..69ecf87
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/html2canvas.js
@@ -0,0 +1,7274 @@
+/*!
+ * html2canvas 1.0.0-alpha.12 <https://html2canvas.hertzen.com>
+ * Copyright (c) 2018 Niklas von Hertzen <https://hertzen.com>
+ * Released under MIT License
+ */
+(function webpackUniversalModuleDefinition(root, factory) {
+	if(typeof exports === 'object' && typeof module === 'object')
+		module.exports = factory();
+	else if(typeof define === 'function' && define.amd)
+		define([], factory);
+	else if(typeof exports === 'object')
+		exports["html2canvas"] = factory();
+	else
+		root["html2canvas"] = factory();
+})(this, function() {
+return /******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+/******/
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+/******/
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId]) {
+/******/ 			return installedModules[moduleId].exports;
+/******/ 		}
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			i: moduleId,
+/******/ 			l: false,
+/******/ 			exports: {}
+/******/ 		};
+/******/
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ 		// Flag the module as loaded
+/******/ 		module.l = true;
+/******/
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/
+/******/
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+/******/
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+/******/
+/******/ 	// define getter function for harmony exports
+/******/ 	__webpack_require__.d = function(exports, name, getter) {
+/******/ 		if(!__webpack_require__.o(exports, name)) {
+/******/ 			Object.defineProperty(exports, name, {
+/******/ 				configurable: false,
+/******/ 				enumerable: true,
+/******/ 				get: getter
+/******/ 			});
+/******/ 		}
+/******/ 	};
+/******/
+/******/ 	// getDefaultExport function for compatibility with non-harmony modules
+/******/ 	__webpack_require__.n = function(module) {
+/******/ 		var getter = module && module.__esModule ?
+/******/ 			function getDefault() { return module['default']; } :
+/******/ 			function getModuleExports() { return module; };
+/******/ 		__webpack_require__.d(getter, 'a', getter);
+/******/ 		return getter;
+/******/ 	};
+/******/
+/******/ 	// Object.prototype.hasOwnProperty.call
+/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "";
+/******/
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(__webpack_require__.s = 27);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+// http://dev.w3.org/csswg/css-color/
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var HEX3 = /^#([a-f0-9]{3})$/i;
+var hex3 = function hex3(value) {
+    var match = value.match(HEX3);
+    if (match) {
+        return [parseInt(match[1][0] + match[1][0], 16), parseInt(match[1][1] + match[1][1], 16), parseInt(match[1][2] + match[1][2], 16), null];
+    }
+    return false;
+};
+
+var HEX6 = /^#([a-f0-9]{6})$/i;
+var hex6 = function hex6(value) {
+    var match = value.match(HEX6);
+    if (match) {
+        return [parseInt(match[1].substring(0, 2), 16), parseInt(match[1].substring(2, 4), 16), parseInt(match[1].substring(4, 6), 16), null];
+    }
+    return false;
+};
+
+var RGB = /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/;
+var rgb = function rgb(value) {
+    var match = value.match(RGB);
+    if (match) {
+        return [Number(match[1]), Number(match[2]), Number(match[3]), null];
+    }
+    return false;
+};
+
+var RGBA = /^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d?\.?\d+)\s*\)$/;
+var rgba = function rgba(value) {
+    var match = value.match(RGBA);
+    if (match && match.length > 4) {
+        return [Number(match[1]), Number(match[2]), Number(match[3]), Number(match[4])];
+    }
+    return false;
+};
+
+var fromArray = function fromArray(array) {
+    return [Math.min(array[0], 255), Math.min(array[1], 255), Math.min(array[2], 255), array.length > 3 ? array[3] : null];
+};
+
+var namedColor = function namedColor(name) {
+    var color = NAMED_COLORS[name.toLowerCase()];
+    return color ? color : false;
+};
+
+var Color = function () {
+    function Color(value) {
+        _classCallCheck(this, Color);
+
+        var _ref = Array.isArray(value) ? fromArray(value) : hex3(value) || rgb(value) || rgba(value) || namedColor(value) || hex6(value) || [0, 0, 0, null],
+            _ref2 = _slicedToArray(_ref, 4),
+            r = _ref2[0],
+            g = _ref2[1],
+            b = _ref2[2],
+            a = _ref2[3];
+
+        this.r = r;
+        this.g = g;
+        this.b = b;
+        this.a = a;
+    }
+
+    _createClass(Color, [{
+        key: 'isTransparent',
+        value: function isTransparent() {
+            return this.a === 0;
+        }
+    }, {
+        key: 'toString',
+        value: function toString() {
+            return this.a !== null && this.a !== 1 ? 'rgba(' + this.r + ',' + this.g + ',' + this.b + ',' + this.a + ')' : 'rgb(' + this.r + ',' + this.g + ',' + this.b + ')';
+        }
+    }]);
+
+    return Color;
+}();
+
+exports.default = Color;
+
+
+var NAMED_COLORS = {
+    transparent: [0, 0, 0, 0],
+    aliceblue: [240, 248, 255, null],
+    antiquewhite: [250, 235, 215, null],
+    aqua: [0, 255, 255, null],
+    aquamarine: [127, 255, 212, null],
+    azure: [240, 255, 255, null],
+    beige: [245, 245, 220, null],
+    bisque: [255, 228, 196, null],
+    black: [0, 0, 0, null],
+    blanchedalmond: [255, 235, 205, null],
+    blue: [0, 0, 255, null],
+    blueviolet: [138, 43, 226, null],
+    brown: [165, 42, 42, null],
+    burlywood: [222, 184, 135, null],
+    cadetblue: [95, 158, 160, null],
+    chartreuse: [127, 255, 0, null],
+    chocolate: [210, 105, 30, null],
+    coral: [255, 127, 80, null],
+    cornflowerblue: [100, 149, 237, null],
+    cornsilk: [255, 248, 220, null],
+    crimson: [220, 20, 60, null],
+    cyan: [0, 255, 255, null],
+    darkblue: [0, 0, 139, null],
+    darkcyan: [0, 139, 139, null],
+    darkgoldenrod: [184, 134, 11, null],
+    darkgray: [169, 169, 169, null],
+    darkgreen: [0, 100, 0, null],
+    darkgrey: [169, 169, 169, null],
+    darkkhaki: [189, 183, 107, null],
+    darkmagenta: [139, 0, 139, null],
+    darkolivegreen: [85, 107, 47, null],
+    darkorange: [255, 140, 0, null],
+    darkorchid: [153, 50, 204, null],
+    darkred: [139, 0, 0, null],
+    darksalmon: [233, 150, 122, null],
+    darkseagreen: [143, 188, 143, null],
+    darkslateblue: [72, 61, 139, null],
+    darkslategray: [47, 79, 79, null],
+    darkslategrey: [47, 79, 79, null],
+    darkturquoise: [0, 206, 209, null],
+    darkviolet: [148, 0, 211, null],
+    deeppink: [255, 20, 147, null],
+    deepskyblue: [0, 191, 255, null],
+    dimgray: [105, 105, 105, null],
+    dimgrey: [105, 105, 105, null],
+    dodgerblue: [30, 144, 255, null],
+    firebrick: [178, 34, 34, null],
+    floralwhite: [255, 250, 240, null],
+    forestgreen: [34, 139, 34, null],
+    fuchsia: [255, 0, 255, null],
+    gainsboro: [220, 220, 220, null],
+    ghostwhite: [248, 248, 255, null],
+    gold: [255, 215, 0, null],
+    goldenrod: [218, 165, 32, null],
+    gray: [128, 128, 128, null],
+    green: [0, 128, 0, null],
+    greenyellow: [173, 255, 47, null],
+    grey: [128, 128, 128, null],
+    honeydew: [240, 255, 240, null],
+    hotpink: [255, 105, 180, null],
+    indianred: [205, 92, 92, null],
+    indigo: [75, 0, 130, null],
+    ivory: [255, 255, 240, null],
+    khaki: [240, 230, 140, null],
+    lavender: [230, 230, 250, null],
+    lavenderblush: [255, 240, 245, null],
+    lawngreen: [124, 252, 0, null],
+    lemonchiffon: [255, 250, 205, null],
+    lightblue: [173, 216, 230, null],
+    lightcoral: [240, 128, 128, null],
+    lightcyan: [224, 255, 255, null],
+    lightgoldenrodyellow: [250, 250, 210, null],
+    lightgray: [211, 211, 211, null],
+    lightgreen: [144, 238, 144, null],
+    lightgrey: [211, 211, 211, null],
+    lightpink: [255, 182, 193, null],
+    lightsalmon: [255, 160, 122, null],
+    lightseagreen: [32, 178, 170, null],
+    lightskyblue: [135, 206, 250, null],
+    lightslategray: [119, 136, 153, null],
+    lightslategrey: [119, 136, 153, null],
+    lightsteelblue: [176, 196, 222, null],
+    lightyellow: [255, 255, 224, null],
+    lime: [0, 255, 0, null],
+    limegreen: [50, 205, 50, null],
+    linen: [250, 240, 230, null],
+    magenta: [255, 0, 255, null],
+    maroon: [128, 0, 0, null],
+    mediumaquamarine: [102, 205, 170, null],
+    mediumblue: [0, 0, 205, null],
+    mediumorchid: [186, 85, 211, null],
+    mediumpurple: [147, 112, 219, null],
+    mediumseagreen: [60, 179, 113, null],
+    mediumslateblue: [123, 104, 238, null],
+    mediumspringgreen: [0, 250, 154, null],
+    mediumturquoise: [72, 209, 204, null],
+    mediumvioletred: [199, 21, 133, null],
+    midnightblue: [25, 25, 112, null],
+    mintcream: [245, 255, 250, null],
+    mistyrose: [255, 228, 225, null],
+    moccasin: [255, 228, 181, null],
+    navajowhite: [255, 222, 173, null],
+    navy: [0, 0, 128, null],
+    oldlace: [253, 245, 230, null],
+    olive: [128, 128, 0, null],
+    olivedrab: [107, 142, 35, null],
+    orange: [255, 165, 0, null],
+    orangered: [255, 69, 0, null],
+    orchid: [218, 112, 214, null],
+    palegoldenrod: [238, 232, 170, null],
+    palegreen: [152, 251, 152, null],
+    paleturquoise: [175, 238, 238, null],
+    palevioletred: [219, 112, 147, null],
+    papayawhip: [255, 239, 213, null],
+    peachpuff: [255, 218, 185, null],
+    peru: [205, 133, 63, null],
+    pink: [255, 192, 203, null],
+    plum: [221, 160, 221, null],
+    powderblue: [176, 224, 230, null],
+    purple: [128, 0, 128, null],
+    rebeccapurple: [102, 51, 153, null],
+    red: [255, 0, 0, null],
+    rosybrown: [188, 143, 143, null],
+    royalblue: [65, 105, 225, null],
+    saddlebrown: [139, 69, 19, null],
+    salmon: [250, 128, 114, null],
+    sandybrown: [244, 164, 96, null],
+    seagreen: [46, 139, 87, null],
+    seashell: [255, 245, 238, null],
+    sienna: [160, 82, 45, null],
+    silver: [192, 192, 192, null],
+    skyblue: [135, 206, 235, null],
+    slateblue: [106, 90, 205, null],
+    slategray: [112, 128, 144, null],
+    slategrey: [112, 128, 144, null],
+    snow: [255, 250, 250, null],
+    springgreen: [0, 255, 127, null],
+    steelblue: [70, 130, 180, null],
+    tan: [210, 180, 140, null],
+    teal: [0, 128, 128, null],
+    thistle: [216, 191, 216, null],
+    tomato: [255, 99, 71, null],
+    turquoise: [64, 224, 208, null],
+    violet: [238, 130, 238, null],
+    wheat: [245, 222, 179, null],
+    white: [255, 255, 255, null],
+    whitesmoke: [245, 245, 245, null],
+    yellow: [255, 255, 0, null],
+    yellowgreen: [154, 205, 50, null]
+};
+
+var TRANSPARENT = exports.TRANSPARENT = new Color([0, 0, 0, 0]);
+
+/***/ }),
+/* 1 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.calculateLengthFromValueWithUnit = exports.LENGTH_TYPE = undefined;
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _NodeContainer = __webpack_require__(3);
+
+var _NodeContainer2 = _interopRequireDefault(_NodeContainer);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var LENGTH_WITH_UNIT = /([\d.]+)(px|r?em|%)/i;
+
+var LENGTH_TYPE = exports.LENGTH_TYPE = {
+    PX: 0,
+    PERCENTAGE: 1
+};
+
+var Length = function () {
+    function Length(value) {
+        _classCallCheck(this, Length);
+
+        this.type = value.substr(value.length - 1) === '%' ? LENGTH_TYPE.PERCENTAGE : LENGTH_TYPE.PX;
+        var parsedValue = parseFloat(value);
+        if (true && isNaN(parsedValue)) {
+            console.error('Invalid value given for Length: "' + value + '"');
+        }
+        this.value = isNaN(parsedValue) ? 0 : parsedValue;
+    }
+
+    _createClass(Length, [{
+        key: 'isPercentage',
+        value: function isPercentage() {
+            return this.type === LENGTH_TYPE.PERCENTAGE;
+        }
+    }, {
+        key: 'getAbsoluteValue',
+        value: function getAbsoluteValue(parentLength) {
+            return this.isPercentage() ? parentLength * (this.value / 100) : this.value;
+        }
+    }], [{
+        key: 'create',
+        value: function create(v) {
+            return new Length(v);
+        }
+    }]);
+
+    return Length;
+}();
+
+exports.default = Length;
+
+
+var getRootFontSize = function getRootFontSize(container) {
+    var parent = container.parent;
+    return parent ? getRootFontSize(parent) : parseFloat(container.style.font.fontSize);
+};
+
+var calculateLengthFromValueWithUnit = exports.calculateLengthFromValueWithUnit = function calculateLengthFromValueWithUnit(container, value, unit) {
+    switch (unit) {
+        case 'px':
+        case '%':
+            return new Length(value + unit);
+        case 'em':
+        case 'rem':
+            var length = new Length(value);
+            length.value *= unit === 'em' ? parseFloat(container.style.font.fontSize) : getRootFontSize(container);
+            return length;
+        default:
+            // TODO: handle correctly if unknown unit is used
+            return new Length('0');
+    }
+};
+
+/***/ }),
+/* 2 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseBoundCurves = exports.calculatePaddingBoxPath = exports.calculateBorderBoxPath = exports.parsePathForBorder = exports.parseDocumentSize = exports.calculateContentBox = exports.calculatePaddingBox = exports.parseBounds = exports.Bounds = undefined;
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Vector = __webpack_require__(7);
+
+var _Vector2 = _interopRequireDefault(_Vector);
+
+var _BezierCurve = __webpack_require__(32);
+
+var _BezierCurve2 = _interopRequireDefault(_BezierCurve);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var TOP = 0;
+var RIGHT = 1;
+var BOTTOM = 2;
+var LEFT = 3;
+
+var H = 0;
+var V = 1;
+
+var Bounds = exports.Bounds = function () {
+    function Bounds(x, y, w, h) {
+        _classCallCheck(this, Bounds);
+
+        this.left = x;
+        this.top = y;
+        this.width = w;
+        this.height = h;
+    }
+
+    _createClass(Bounds, null, [{
+        key: 'fromClientRect',
+        value: function fromClientRect(clientRect, scrollX, scrollY) {
+            return new Bounds(clientRect.left + scrollX, clientRect.top + scrollY, clientRect.width, clientRect.height);
+        }
+    }]);
+
+    return Bounds;
+}();
+
+var parseBounds = exports.parseBounds = function parseBounds(node, scrollX, scrollY) {
+    return Bounds.fromClientRect(node.getBoundingClientRect(), scrollX, scrollY);
+};
+
+var calculatePaddingBox = exports.calculatePaddingBox = function calculatePaddingBox(bounds, borders) {
+    return new Bounds(bounds.left + borders[LEFT].borderWidth, bounds.top + borders[TOP].borderWidth, bounds.width - (borders[RIGHT].borderWidth + borders[LEFT].borderWidth), bounds.height - (borders[TOP].borderWidth + borders[BOTTOM].borderWidth));
+};
+
+var calculateContentBox = exports.calculateContentBox = function calculateContentBox(bounds, padding, borders) {
+    // TODO support percentage paddings
+    var paddingTop = padding[TOP].value;
+    var paddingRight = padding[RIGHT].value;
+    var paddingBottom = padding[BOTTOM].value;
+    var paddingLeft = padding[LEFT].value;
+
+    return new Bounds(bounds.left + paddingLeft + borders[LEFT].borderWidth, bounds.top + paddingTop + borders[TOP].borderWidth, bounds.width - (borders[RIGHT].borderWidth + borders[LEFT].borderWidth + paddingLeft + paddingRight), bounds.height - (borders[TOP].borderWidth + borders[BOTTOM].borderWidth + paddingTop + paddingBottom));
+};
+
+var parseDocumentSize = exports.parseDocumentSize = function parseDocumentSize(document) {
+    var body = document.body;
+    var documentElement = document.documentElement;
+
+    if (!body || !documentElement) {
+        throw new Error( true ? 'Unable to get document size' : '');
+    }
+    var width = Math.max(Math.max(body.scrollWidth, documentElement.scrollWidth), Math.max(body.offsetWidth, documentElement.offsetWidth), Math.max(body.clientWidth, documentElement.clientWidth));
+
+    var height = Math.max(Math.max(body.scrollHeight, documentElement.scrollHeight), Math.max(body.offsetHeight, documentElement.offsetHeight), Math.max(body.clientHeight, documentElement.clientHeight));
+
+    return new Bounds(0, 0, width, height);
+};
+
+var parsePathForBorder = exports.parsePathForBorder = function parsePathForBorder(curves, borderSide) {
+    switch (borderSide) {
+        case TOP:
+            return createPathFromCurves(curves.topLeftOuter, curves.topLeftInner, curves.topRightOuter, curves.topRightInner);
+        case RIGHT:
+            return createPathFromCurves(curves.topRightOuter, curves.topRightInner, curves.bottomRightOuter, curves.bottomRightInner);
+        case BOTTOM:
+            return createPathFromCurves(curves.bottomRightOuter, curves.bottomRightInner, curves.bottomLeftOuter, curves.bottomLeftInner);
+        case LEFT:
+        default:
+            return createPathFromCurves(curves.bottomLeftOuter, curves.bottomLeftInner, curves.topLeftOuter, curves.topLeftInner);
+    }
+};
+
+var createPathFromCurves = function createPathFromCurves(outer1, inner1, outer2, inner2) {
+    var path = [];
+    if (outer1 instanceof _BezierCurve2.default) {
+        path.push(outer1.subdivide(0.5, false));
+    } else {
+        path.push(outer1);
+    }
+
+    if (outer2 instanceof _BezierCurve2.default) {
+        path.push(outer2.subdivide(0.5, true));
+    } else {
+        path.push(outer2);
+    }
+
+    if (inner2 instanceof _BezierCurve2.default) {
+        path.push(inner2.subdivide(0.5, true).reverse());
+    } else {
+        path.push(inner2);
+    }
+
+    if (inner1 instanceof _BezierCurve2.default) {
+        path.push(inner1.subdivide(0.5, false).reverse());
+    } else {
+        path.push(inner1);
+    }
+
+    return path;
+};
+
+var calculateBorderBoxPath = exports.calculateBorderBoxPath = function calculateBorderBoxPath(curves) {
+    return [curves.topLeftOuter, curves.topRightOuter, curves.bottomRightOuter, curves.bottomLeftOuter];
+};
+
+var calculatePaddingBoxPath = exports.calculatePaddingBoxPath = function calculatePaddingBoxPath(curves) {
+    return [curves.topLeftInner, curves.topRightInner, curves.bottomRightInner, curves.bottomLeftInner];
+};
+
+var parseBoundCurves = exports.parseBoundCurves = function parseBoundCurves(bounds, borders, borderRadius) {
+    var tlh = borderRadius[CORNER.TOP_LEFT][H].getAbsoluteValue(bounds.width);
+    var tlv = borderRadius[CORNER.TOP_LEFT][V].getAbsoluteValue(bounds.height);
+    var trh = borderRadius[CORNER.TOP_RIGHT][H].getAbsoluteValue(bounds.width);
+    var trv = borderRadius[CORNER.TOP_RIGHT][V].getAbsoluteValue(bounds.height);
+    var brh = borderRadius[CORNER.BOTTOM_RIGHT][H].getAbsoluteValue(bounds.width);
+    var brv = borderRadius[CORNER.BOTTOM_RIGHT][V].getAbsoluteValue(bounds.height);
+    var blh = borderRadius[CORNER.BOTTOM_LEFT][H].getAbsoluteValue(bounds.width);
+    var blv = borderRadius[CORNER.BOTTOM_LEFT][V].getAbsoluteValue(bounds.height);
+
+    var factors = [];
+    factors.push((tlh + trh) / bounds.width);
+    factors.push((blh + brh) / bounds.width);
+    factors.push((tlv + blv) / bounds.height);
+    factors.push((trv + brv) / bounds.height);
+    var maxFactor = Math.max.apply(Math, factors);
+
+    if (maxFactor > 1) {
+        tlh /= maxFactor;
+        tlv /= maxFactor;
+        trh /= maxFactor;
+        trv /= maxFactor;
+        brh /= maxFactor;
+        brv /= maxFactor;
+        blh /= maxFactor;
+        blv /= maxFactor;
+    }
+
+    var topWidth = bounds.width - trh;
+    var rightHeight = bounds.height - brv;
+    var bottomWidth = bounds.width - brh;
+    var leftHeight = bounds.height - blv;
+
+    return {
+        topLeftOuter: tlh > 0 || tlv > 0 ? getCurvePoints(bounds.left, bounds.top, tlh, tlv, CORNER.TOP_LEFT) : new _Vector2.default(bounds.left, bounds.top),
+        topLeftInner: tlh > 0 || tlv > 0 ? getCurvePoints(bounds.left + borders[LEFT].borderWidth, bounds.top + borders[TOP].borderWidth, Math.max(0, tlh - borders[LEFT].borderWidth), Math.max(0, tlv - borders[TOP].borderWidth), CORNER.TOP_LEFT) : new _Vector2.default(bounds.left + borders[LEFT].borderWidth, bounds.top + borders[TOP].borderWidth),
+        topRightOuter: trh > 0 || trv > 0 ? getCurvePoints(bounds.left + topWidth, bounds.top, trh, trv, CORNER.TOP_RIGHT) : new _Vector2.default(bounds.left + bounds.width, bounds.top),
+        topRightInner: trh > 0 || trv > 0 ? getCurvePoints(bounds.left + Math.min(topWidth, bounds.width + borders[LEFT].borderWidth), bounds.top + borders[TOP].borderWidth, topWidth > bounds.width + borders[LEFT].borderWidth ? 0 : trh - borders[LEFT].borderWidth, trv - borders[TOP].borderWidth, CORNER.TOP_RIGHT) : new _Vector2.default(bounds.left + bounds.width - borders[RIGHT].borderWidth, bounds.top + borders[TOP].borderWidth),
+        bottomRightOuter: brh > 0 || brv > 0 ? getCurvePoints(bounds.left + bottomWidth, bounds.top + rightHeight, brh, brv, CORNER.BOTTOM_RIGHT) : new _Vector2.default(bounds.left + bounds.width, bounds.top + bounds.height),
+        bottomRightInner: brh > 0 || brv > 0 ? getCurvePoints(bounds.left + Math.min(bottomWidth, bounds.width - borders[LEFT].borderWidth), bounds.top + Math.min(rightHeight, bounds.height + borders[TOP].borderWidth), Math.max(0, brh - borders[RIGHT].borderWidth), brv - borders[BOTTOM].borderWidth, CORNER.BOTTOM_RIGHT) : new _Vector2.default(bounds.left + bounds.width - borders[RIGHT].borderWidth, bounds.top + bounds.height - borders[BOTTOM].borderWidth),
+        bottomLeftOuter: blh > 0 || blv > 0 ? getCurvePoints(bounds.left, bounds.top + leftHeight, blh, blv, CORNER.BOTTOM_LEFT) : new _Vector2.default(bounds.left, bounds.top + bounds.height),
+        bottomLeftInner: blh > 0 || blv > 0 ? getCurvePoints(bounds.left + borders[LEFT].borderWidth, bounds.top + leftHeight, Math.max(0, blh - borders[LEFT].borderWidth), blv - borders[BOTTOM].borderWidth, CORNER.BOTTOM_LEFT) : new _Vector2.default(bounds.left + borders[LEFT].borderWidth, bounds.top + bounds.height - borders[BOTTOM].borderWidth)
+    };
+};
+
+var CORNER = {
+    TOP_LEFT: 0,
+    TOP_RIGHT: 1,
+    BOTTOM_RIGHT: 2,
+    BOTTOM_LEFT: 3
+};
+
+var getCurvePoints = function getCurvePoints(x, y, r1, r2, position) {
+    var kappa = 4 * ((Math.sqrt(2) - 1) / 3);
+    var ox = r1 * kappa; // control point offset horizontal
+    var oy = r2 * kappa; // control point offset vertical
+    var xm = x + r1; // x-middle
+    var ym = y + r2; // y-middle
+
+    switch (position) {
+        case CORNER.TOP_LEFT:
+            return new _BezierCurve2.default(new _Vector2.default(x, ym), new _Vector2.default(x, ym - oy), new _Vector2.default(xm - ox, y), new _Vector2.default(xm, y));
+        case CORNER.TOP_RIGHT:
+            return new _BezierCurve2.default(new _Vector2.default(x, y), new _Vector2.default(x + ox, y), new _Vector2.default(xm, ym - oy), new _Vector2.default(xm, ym));
+        case CORNER.BOTTOM_RIGHT:
+            return new _BezierCurve2.default(new _Vector2.default(xm, y), new _Vector2.default(xm, y + oy), new _Vector2.default(x + ox, ym), new _Vector2.default(x, ym));
+        case CORNER.BOTTOM_LEFT:
+        default:
+            return new _BezierCurve2.default(new _Vector2.default(xm, ym), new _Vector2.default(xm - ox, ym), new _Vector2.default(x, y + oy), new _Vector2.default(x, y));
+    }
+};
+
+/***/ }),
+/* 3 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Color = __webpack_require__(0);
+
+var _Color2 = _interopRequireDefault(_Color);
+
+var _Util = __webpack_require__(4);
+
+var _background = __webpack_require__(5);
+
+var _border = __webpack_require__(12);
+
+var _borderRadius = __webpack_require__(33);
+
+var _display = __webpack_require__(34);
+
+var _float = __webpack_require__(35);
+
+var _font = __webpack_require__(36);
+
+var _letterSpacing = __webpack_require__(37);
+
+var _lineBreak = __webpack_require__(38);
+
+var _listStyle = __webpack_require__(8);
+
+var _margin = __webpack_require__(39);
+
+var _overflow = __webpack_require__(40);
+
+var _overflowWrap = __webpack_require__(18);
+
+var _padding = __webpack_require__(17);
+
+var _position = __webpack_require__(19);
+
+var _textDecoration = __webpack_require__(11);
+
+var _textShadow = __webpack_require__(41);
+
+var _textTransform = __webpack_require__(20);
+
+var _transform = __webpack_require__(42);
+
+var _visibility = __webpack_require__(43);
+
+var _wordBreak = __webpack_require__(44);
+
+var _zIndex = __webpack_require__(45);
+
+var _Bounds = __webpack_require__(2);
+
+var _Input = __webpack_require__(21);
+
+var _ListItem = __webpack_require__(14);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];
+
+var NodeContainer = function () {
+    function NodeContainer(node, parent, resourceLoader, index) {
+        var _this = this;
+
+        _classCallCheck(this, NodeContainer);
+
+        this.parent = parent;
+        this.tagName = node.tagName;
+        this.index = index;
+        this.childNodes = [];
+        this.listItems = [];
+        if (typeof node.start === 'number') {
+            this.listStart = node.start;
+        }
+        var defaultView = node.ownerDocument.defaultView;
+        var scrollX = defaultView.pageXOffset;
+        var scrollY = defaultView.pageYOffset;
+        var style = defaultView.getComputedStyle(node, null);
+        var display = (0, _display.parseDisplay)(style.display);
+
+        var IS_INPUT = node.type === 'radio' || node.type === 'checkbox';
+
+        var position = (0, _position.parsePosition)(style.position);
+
+        this.style = {
+            background: IS_INPUT ? _Input.INPUT_BACKGROUND : (0, _background.parseBackground)(style, resourceLoader),
+            border: IS_INPUT ? _Input.INPUT_BORDERS : (0, _border.parseBorder)(style),
+            borderRadius: (node instanceof defaultView.HTMLInputElement || node instanceof HTMLInputElement) && IS_INPUT ? (0, _Input.getInputBorderRadius)(node) : (0, _borderRadius.parseBorderRadius)(style),
+            color: IS_INPUT ? _Input.INPUT_COLOR : new _Color2.default(style.color),
+            display: display,
+            float: (0, _float.parseCSSFloat)(style.float),
+            font: (0, _font.parseFont)(style),
+            letterSpacing: (0, _letterSpacing.parseLetterSpacing)(style.letterSpacing),
+            listStyle: display === _display.DISPLAY.LIST_ITEM ? (0, _listStyle.parseListStyle)(style) : null,
+            lineBreak: (0, _lineBreak.parseLineBreak)(style.lineBreak),
+            margin: (0, _margin.parseMargin)(style),
+            opacity: parseFloat(style.opacity),
+            overflow: INPUT_TAGS.indexOf(node.tagName) === -1 ? (0, _overflow.parseOverflow)(style.overflow) : _overflow.OVERFLOW.HIDDEN,
+            overflowWrap: (0, _overflowWrap.parseOverflowWrap)(style.overflowWrap ? style.overflowWrap : style.wordWrap),
+            padding: (0, _padding.parsePadding)(style),
+            position: position,
+            textDecoration: (0, _textDecoration.parseTextDecoration)(style),
+            textShadow: (0, _textShadow.parseTextShadow)(style.textShadow),
+            textTransform: (0, _textTransform.parseTextTransform)(style.textTransform),
+            transform: (0, _transform.parseTransform)(style),
+            visibility: (0, _visibility.parseVisibility)(style.visibility),
+            wordBreak: (0, _wordBreak.parseWordBreak)(style.wordBreak),
+            zIndex: (0, _zIndex.parseZIndex)(position !== _position.POSITION.STATIC ? style.zIndex : 'auto')
+        };
+
+        if (this.isTransformed()) {
+            // getBoundingClientRect provides values post-transform, we want them without the transformation
+            node.style.transform = 'matrix(1,0,0,1,0,0)';
+        }
+
+        if (display === _display.DISPLAY.LIST_ITEM) {
+            var listOwner = (0, _ListItem.getListOwner)(this);
+            if (listOwner) {
+                var listIndex = listOwner.listItems.length;
+                listOwner.listItems.push(this);
+                this.listIndex = node.hasAttribute('value') && typeof node.value === 'number' ? node.value : listIndex === 0 ? typeof listOwner.listStart === 'number' ? listOwner.listStart : 1 : listOwner.listItems[listIndex - 1].listIndex + 1;
+            }
+        }
+
+        // TODO move bound retrieval for all nodes to a later stage?
+        if (node.tagName === 'IMG') {
+            node.addEventListener('load', function () {
+                _this.bounds = (0, _Bounds.parseBounds)(node, scrollX, scrollY);
+                _this.curvedBounds = (0, _Bounds.parseBoundCurves)(_this.bounds, _this.style.border, _this.style.borderRadius);
+            });
+        }
+        this.image = getImage(node, resourceLoader);
+        this.bounds = IS_INPUT ? (0, _Input.reformatInputBounds)((0, _Bounds.parseBounds)(node, scrollX, scrollY)) : (0, _Bounds.parseBounds)(node, scrollX, scrollY);
+        this.curvedBounds = (0, _Bounds.parseBoundCurves)(this.bounds, this.style.border, this.style.borderRadius);
+
+        if (true) {
+            this.name = '' + node.tagName.toLowerCase() + (node.id ? '#' + node.id : '') + node.className.toString().split(' ').map(function (s) {
+                return s.length ? '.' + s : '';
+            }).join('');
+        }
+    }
+
+    _createClass(NodeContainer, [{
+        key: 'getClipPaths',
+        value: function getClipPaths() {
+            var parentClips = this.parent ? this.parent.getClipPaths() : [];
+            var isClipped = this.style.overflow !== _overflow.OVERFLOW.VISIBLE;
+
+            return isClipped ? parentClips.concat([(0, _Bounds.calculatePaddingBoxPath)(this.curvedBounds)]) : parentClips;
+        }
+    }, {
+        key: 'isInFlow',
+        value: function isInFlow() {
+            return this.isRootElement() && !this.isFloating() && !this.isAbsolutelyPositioned();
+        }
+    }, {
+        key: 'isVisible',
+        value: function isVisible() {
+            return !(0, _Util.contains)(this.style.display, _display.DISPLAY.NONE) && this.style.opacity > 0 && this.style.visibility === _visibility.VISIBILITY.VISIBLE;
+        }
+    }, {
+        key: 'isAbsolutelyPositioned',
+        value: function isAbsolutelyPositioned() {
+            return this.style.position !== _position.POSITION.STATIC && this.style.position !== _position.POSITION.RELATIVE;
+        }
+    }, {
+        key: 'isPositioned',
+        value: function isPositioned() {
+            return this.style.position !== _position.POSITION.STATIC;
+        }
+    }, {
+        key: 'isFloating',
+        value: function isFloating() {
+            return this.style.float !== _float.FLOAT.NONE;
+        }
+    }, {
+        key: 'isRootElement',
+        value: function isRootElement() {
+            return this.parent === null;
+        }
+    }, {
+        key: 'isTransformed',
+        value: function isTransformed() {
+            return this.style.transform !== null;
+        }
+    }, {
+        key: 'isPositionedWithZIndex',
+        value: function isPositionedWithZIndex() {
+            return this.isPositioned() && !this.style.zIndex.auto;
+        }
+    }, {
+        key: 'isInlineLevel',
+        value: function isInlineLevel() {
+            return (0, _Util.contains)(this.style.display, _display.DISPLAY.INLINE) || (0, _Util.contains)(this.style.display, _display.DISPLAY.INLINE_BLOCK) || (0, _Util.contains)(this.style.display, _display.DISPLAY.INLINE_FLEX) || (0, _Util.contains)(this.style.display, _display.DISPLAY.INLINE_GRID) || (0, _Util.contains)(this.style.display, _display.DISPLAY.INLINE_LIST_ITEM) || (0, _Util.contains)(this.style.display, _display.DISPLAY.INLINE_TABLE);
+        }
+    }, {
+        key: 'isInlineBlockOrInlineTable',
+        value: function isInlineBlockOrInlineTable() {
+            return (0, _Util.contains)(this.style.display, _display.DISPLAY.INLINE_BLOCK) || (0, _Util.contains)(this.style.display, _display.DISPLAY.INLINE_TABLE);
+        }
+    }]);
+
+    return NodeContainer;
+}();
+
+exports.default = NodeContainer;
+
+
+var getImage = function getImage(node, resourceLoader) {
+    if (node instanceof node.ownerDocument.defaultView.SVGSVGElement || node instanceof SVGSVGElement) {
+        var s = new XMLSerializer();
+        return resourceLoader.loadImage('data:image/svg+xml,' + encodeURIComponent(s.serializeToString(node)));
+    }
+    switch (node.tagName) {
+        case 'IMG':
+            // $FlowFixMe
+            var img = node;
+            return resourceLoader.loadImage(img.currentSrc || img.src);
+        case 'CANVAS':
+            // $FlowFixMe
+            var canvas = node;
+            return resourceLoader.loadCanvas(canvas);
+        case 'IFRAME':
+            var iframeKey = node.getAttribute('data-html2canvas-internal-iframe-key');
+            if (iframeKey) {
+                return iframeKey;
+            }
+            break;
+    }
+
+    return null;
+};
+
+/***/ }),
+/* 4 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var contains = exports.contains = function contains(bit, value) {
+    return (bit & value) !== 0;
+};
+
+var distance = exports.distance = function distance(a, b) {
+    return Math.sqrt(a * a + b * b);
+};
+
+var copyCSSStyles = exports.copyCSSStyles = function copyCSSStyles(style, target) {
+    // Edge does not provide value for cssText
+    for (var i = style.length - 1; i >= 0; i--) {
+        var property = style.item(i);
+        // Safari shows pseudoelements if content is set
+        if (property !== 'content') {
+            target.style.setProperty(property, style.getPropertyValue(property));
+        }
+    }
+    return target;
+};
+
+var SMALL_IMAGE = exports.SMALL_IMAGE = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
+
+/***/ }),
+/* 5 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseBackgroundImage = exports.parseBackground = exports.calculateBackgroundRepeatPath = exports.calculateBackgroundPosition = exports.calculateBackgroungPositioningArea = exports.calculateBackgroungPaintingArea = exports.calculateGradientBackgroundSize = exports.calculateBackgroundSize = exports.BACKGROUND_ORIGIN = exports.BACKGROUND_CLIP = exports.BACKGROUND_SIZE = exports.BACKGROUND_REPEAT = undefined;
+
+var _Color = __webpack_require__(0);
+
+var _Color2 = _interopRequireDefault(_Color);
+
+var _Length = __webpack_require__(1);
+
+var _Length2 = _interopRequireDefault(_Length);
+
+var _Size = __webpack_require__(31);
+
+var _Size2 = _interopRequireDefault(_Size);
+
+var _Vector = __webpack_require__(7);
+
+var _Vector2 = _interopRequireDefault(_Vector);
+
+var _Bounds = __webpack_require__(2);
+
+var _padding = __webpack_require__(17);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var BACKGROUND_REPEAT = exports.BACKGROUND_REPEAT = {
+    REPEAT: 0,
+    NO_REPEAT: 1,
+    REPEAT_X: 2,
+    REPEAT_Y: 3
+};
+
+var BACKGROUND_SIZE = exports.BACKGROUND_SIZE = {
+    AUTO: 0,
+    CONTAIN: 1,
+    COVER: 2,
+    LENGTH: 3
+};
+
+var BACKGROUND_CLIP = exports.BACKGROUND_CLIP = {
+    BORDER_BOX: 0,
+    PADDING_BOX: 1,
+    CONTENT_BOX: 2
+};
+
+var BACKGROUND_ORIGIN = exports.BACKGROUND_ORIGIN = BACKGROUND_CLIP;
+
+var AUTO = 'auto';
+
+var BackgroundSize = function BackgroundSize(size) {
+    _classCallCheck(this, BackgroundSize);
+
+    switch (size) {
+        case 'contain':
+            this.size = BACKGROUND_SIZE.CONTAIN;
+            break;
+        case 'cover':
+            this.size = BACKGROUND_SIZE.COVER;
+            break;
+        case 'auto':
+            this.size = BACKGROUND_SIZE.AUTO;
+            break;
+        default:
+            this.value = new _Length2.default(size);
+    }
+};
+
+var calculateBackgroundSize = exports.calculateBackgroundSize = function calculateBackgroundSize(backgroundImage, image, bounds) {
+    var width = 0;
+    var height = 0;
+    var size = backgroundImage.size;
+    if (size[0].size === BACKGROUND_SIZE.CONTAIN || size[0].size === BACKGROUND_SIZE.COVER) {
+        var targetRatio = bounds.width / bounds.height;
+        var currentRatio = image.width / image.height;
+        return targetRatio < currentRatio !== (size[0].size === BACKGROUND_SIZE.COVER) ? new _Size2.default(bounds.width, bounds.width / currentRatio) : new _Size2.default(bounds.height * currentRatio, bounds.height);
+    }
+
+    if (size[0].value) {
+        width = size[0].value.getAbsoluteValue(bounds.width);
+    }
+
+    if (size[0].size === BACKGROUND_SIZE.AUTO && size[1].size === BACKGROUND_SIZE.AUTO) {
+        height = image.height;
+    } else if (size[1].size === BACKGROUND_SIZE.AUTO) {
+        height = width / image.width * image.height;
+    } else if (size[1].value) {
+        height = size[1].value.getAbsoluteValue(bounds.height);
+    }
+
+    if (size[0].size === BACKGROUND_SIZE.AUTO) {
+        width = height / image.height * image.width;
+    }
+
+    return new _Size2.default(width, height);
+};
+
+var calculateGradientBackgroundSize = exports.calculateGradientBackgroundSize = function calculateGradientBackgroundSize(backgroundImage, bounds) {
+    var size = backgroundImage.size;
+    var width = size[0].value ? size[0].value.getAbsoluteValue(bounds.width) : bounds.width;
+    var height = size[1].value ? size[1].value.getAbsoluteValue(bounds.height) : size[0].value ? width : bounds.height;
+
+    return new _Size2.default(width, height);
+};
+
+var AUTO_SIZE = new BackgroundSize(AUTO);
+
+var calculateBackgroungPaintingArea = exports.calculateBackgroungPaintingArea = function calculateBackgroungPaintingArea(curves, clip) {
+    switch (clip) {
+        case BACKGROUND_CLIP.BORDER_BOX:
+            return (0, _Bounds.calculateBorderBoxPath)(curves);
+        case BACKGROUND_CLIP.PADDING_BOX:
+        default:
+            return (0, _Bounds.calculatePaddingBoxPath)(curves);
+    }
+};
+
+var calculateBackgroungPositioningArea = exports.calculateBackgroungPositioningArea = function calculateBackgroungPositioningArea(backgroundOrigin, bounds, padding, border) {
+    var paddingBox = (0, _Bounds.calculatePaddingBox)(bounds, border);
+
+    switch (backgroundOrigin) {
+        case BACKGROUND_ORIGIN.BORDER_BOX:
+            return bounds;
+        case BACKGROUND_ORIGIN.CONTENT_BOX:
+            var paddingLeft = padding[_padding.PADDING_SIDES.LEFT].getAbsoluteValue(bounds.width);
+            var paddingRight = padding[_padding.PADDING_SIDES.RIGHT].getAbsoluteValue(bounds.width);
+            var paddingTop = padding[_padding.PADDING_SIDES.TOP].getAbsoluteValue(bounds.width);
+            var paddingBottom = padding[_padding.PADDING_SIDES.BOTTOM].getAbsoluteValue(bounds.width);
+            return new _Bounds.Bounds(paddingBox.left + paddingLeft, paddingBox.top + paddingTop, paddingBox.width - paddingLeft - paddingRight, paddingBox.height - paddingTop - paddingBottom);
+        case BACKGROUND_ORIGIN.PADDING_BOX:
+        default:
+            return paddingBox;
+    }
+};
+
+var calculateBackgroundPosition = exports.calculateBackgroundPosition = function calculateBackgroundPosition(position, size, bounds) {
+    return new _Vector2.default(position[0].getAbsoluteValue(bounds.width - size.width), position[1].getAbsoluteValue(bounds.height - size.height));
+};
+
+var calculateBackgroundRepeatPath = exports.calculateBackgroundRepeatPath = function calculateBackgroundRepeatPath(background, position, size, backgroundPositioningArea, bounds) {
+    var repeat = background.repeat;
+    switch (repeat) {
+        case BACKGROUND_REPEAT.REPEAT_X:
+            return [new _Vector2.default(Math.round(bounds.left), Math.round(backgroundPositioningArea.top + position.y)), new _Vector2.default(Math.round(bounds.left + bounds.width), Math.round(backgroundPositioningArea.top + position.y)), new _Vector2.default(Math.round(bounds.left + bounds.width), Math.round(size.height + backgroundPositioningArea.top + position.y)), new _Vector2.default(Math.round(bounds.left), Math.round(size.height + backgroundPositioningArea.top + position.y))];
+        case BACKGROUND_REPEAT.REPEAT_Y:
+            return [new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x), Math.round(bounds.top)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x + size.width), Math.round(bounds.top)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x + size.width), Math.round(bounds.height + bounds.top)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x), Math.round(bounds.height + bounds.top))];
+        case BACKGROUND_REPEAT.NO_REPEAT:
+            return [new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x), Math.round(backgroundPositioningArea.top + position.y)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x + size.width), Math.round(backgroundPositioningArea.top + position.y)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x + size.width), Math.round(backgroundPositioningArea.top + position.y + size.height)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x), Math.round(backgroundPositioningArea.top + position.y + size.height))];
+        default:
+            return [new _Vector2.default(Math.round(bounds.left), Math.round(bounds.top)), new _Vector2.default(Math.round(bounds.left + bounds.width), Math.round(bounds.top)), new _Vector2.default(Math.round(bounds.left + bounds.width), Math.round(bounds.height + bounds.top)), new _Vector2.default(Math.round(bounds.left), Math.round(bounds.height + bounds.top))];
+    }
+};
+
+var parseBackground = exports.parseBackground = function parseBackground(style, resourceLoader) {
+    return {
+        backgroundColor: new _Color2.default(style.backgroundColor),
+        backgroundImage: parseBackgroundImages(style, resourceLoader),
+        backgroundClip: parseBackgroundClip(style.backgroundClip),
+        backgroundOrigin: parseBackgroundOrigin(style.backgroundOrigin)
+    };
+};
+
+var parseBackgroundClip = function parseBackgroundClip(backgroundClip) {
+    switch (backgroundClip) {
+        case 'padding-box':
+            return BACKGROUND_CLIP.PADDING_BOX;
+        case 'content-box':
+            return BACKGROUND_CLIP.CONTENT_BOX;
+    }
+    return BACKGROUND_CLIP.BORDER_BOX;
+};
+
+var parseBackgroundOrigin = function parseBackgroundOrigin(backgroundOrigin) {
+    switch (backgroundOrigin) {
+        case 'padding-box':
+            return BACKGROUND_ORIGIN.PADDING_BOX;
+        case 'content-box':
+            return BACKGROUND_ORIGIN.CONTENT_BOX;
+    }
+    return BACKGROUND_ORIGIN.BORDER_BOX;
+};
+
+var parseBackgroundRepeat = function parseBackgroundRepeat(backgroundRepeat) {
+    switch (backgroundRepeat.trim()) {
+        case 'no-repeat':
+            return BACKGROUND_REPEAT.NO_REPEAT;
+        case 'repeat-x':
+        case 'repeat no-repeat':
+            return BACKGROUND_REPEAT.REPEAT_X;
+        case 'repeat-y':
+        case 'no-repeat repeat':
+            return BACKGROUND_REPEAT.REPEAT_Y;
+        case 'repeat':
+            return BACKGROUND_REPEAT.REPEAT;
+    }
+
+    if (true) {
+        console.error('Invalid background-repeat value "' + backgroundRepeat + '"');
+    }
+
+    return BACKGROUND_REPEAT.REPEAT;
+};
+
+var parseBackgroundImages = function parseBackgroundImages(style, resourceLoader) {
+    var sources = parseBackgroundImage(style.backgroundImage).map(function (backgroundImage) {
+        if (backgroundImage.method === 'url') {
+            var key = resourceLoader.loadImage(backgroundImage.args[0]);
+            backgroundImage.args = key ? [key] : [];
+        }
+        return backgroundImage;
+    });
+    var positions = style.backgroundPosition.split(',');
+    var repeats = style.backgroundRepeat.split(',');
+    var sizes = style.backgroundSize.split(',');
+
+    return sources.map(function (source, index) {
+        var size = (sizes[index] || AUTO).trim().split(' ').map(parseBackgroundSize);
+        var position = (positions[index] || AUTO).trim().split(' ').map(parseBackgoundPosition);
+
+        return {
+            source: source,
+            repeat: parseBackgroundRepeat(typeof repeats[index] === 'string' ? repeats[index] : repeats[0]),
+            size: size.length < 2 ? [size[0], AUTO_SIZE] : [size[0], size[1]],
+            position: position.length < 2 ? [position[0], position[0]] : [position[0], position[1]]
+        };
+    });
+};
+
+var parseBackgroundSize = function parseBackgroundSize(size) {
+    return size === 'auto' ? AUTO_SIZE : new BackgroundSize(size);
+};
+
+var parseBackgoundPosition = function parseBackgoundPosition(position) {
+    switch (position) {
+        case 'bottom':
+        case 'right':
+            return new _Length2.default('100%');
+        case 'left':
+        case 'top':
+            return new _Length2.default('0%');
+        case 'auto':
+            return new _Length2.default('0');
+    }
+    return new _Length2.default(position);
+};
+
+var parseBackgroundImage = exports.parseBackgroundImage = function parseBackgroundImage(image) {
+    var whitespace = /^\s$/;
+    var results = [];
+
+    var args = [];
+    var method = '';
+    var quote = null;
+    var definition = '';
+    var mode = 0;
+    var numParen = 0;
+
+    var appendResult = function appendResult() {
+        var prefix = '';
+        if (method) {
+            if (definition.substr(0, 1) === '"') {
+                definition = definition.substr(1, definition.length - 2);
+            }
+
+            if (definition) {
+                args.push(definition.trim());
+            }
+
+            var prefix_i = method.indexOf('-', 1) + 1;
+            if (method.substr(0, 1) === '-' && prefix_i > 0) {
+                prefix = method.substr(0, prefix_i).toLowerCase();
+                method = method.substr(prefix_i);
+            }
+            method = method.toLowerCase();
+            if (method !== 'none') {
+                results.push({
+                    prefix: prefix,
+                    method: method,
+                    args: args
+                });
+            }
+        }
+        args = [];
+        method = definition = '';
+    };
+
+    image.split('').forEach(function (c) {
+        if (mode === 0 && whitespace.test(c)) {
+            return;
+        }
+        switch (c) {
+            case '"':
+                if (!quote) {
+                    quote = c;
+                } else if (quote === c) {
+                    quote = null;
+                }
+                break;
+            case '(':
+                if (quote) {
+                    break;
+                } else if (mode === 0) {
+                    mode = 1;
+                    return;
+                } else {
+                    numParen++;
+                }
+                break;
+            case ')':
+                if (quote) {
+                    break;
+                } else if (mode === 1) {
+                    if (numParen === 0) {
+                        mode = 0;
+                        appendResult();
+                        return;
+                    } else {
+                        numParen--;
+                    }
+                }
+                break;
+
+            case ',':
+                if (quote) {
+                    break;
+                } else if (mode === 0) {
+                    appendResult();
+                    return;
+                } else if (mode === 1) {
+                    if (numParen === 0 && !method.match(/^url$/i)) {
+                        args.push(definition.trim());
+                        definition = '';
+                        return;
+                    }
+                }
+                break;
+        }
+
+        if (mode === 0) {
+            method += c;
+        } else {
+            definition += c;
+        }
+    });
+
+    appendResult();
+    return results;
+};
+
+/***/ }),
+/* 6 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var PATH = exports.PATH = {
+    VECTOR: 0,
+    BEZIER_CURVE: 1,
+    CIRCLE: 2
+};
+
+/***/ }),
+/* 7 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _Path = __webpack_require__(6);
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Vector = function Vector(x, y) {
+    _classCallCheck(this, Vector);
+
+    this.type = _Path.PATH.VECTOR;
+    this.x = x;
+    this.y = y;
+    if (true) {
+        if (isNaN(x)) {
+            console.error('Invalid x value given for Vector');
+        }
+        if (isNaN(y)) {
+            console.error('Invalid y value given for Vector');
+        }
+    }
+};
+
+exports.default = Vector;
+
+/***/ }),
+/* 8 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseListStyle = exports.parseListStyleType = exports.LIST_STYLE_TYPE = exports.LIST_STYLE_POSITION = undefined;
+
+var _background = __webpack_require__(5);
+
+var LIST_STYLE_POSITION = exports.LIST_STYLE_POSITION = {
+    INSIDE: 0,
+    OUTSIDE: 1
+};
+
+var LIST_STYLE_TYPE = exports.LIST_STYLE_TYPE = {
+    NONE: -1,
+    DISC: 0,
+    CIRCLE: 1,
+    SQUARE: 2,
+    DECIMAL: 3,
+    CJK_DECIMAL: 4,
+    DECIMAL_LEADING_ZERO: 5,
+    LOWER_ROMAN: 6,
+    UPPER_ROMAN: 7,
+    LOWER_GREEK: 8,
+    LOWER_ALPHA: 9,
+    UPPER_ALPHA: 10,
+    ARABIC_INDIC: 11,
+    ARMENIAN: 12,
+    BENGALI: 13,
+    CAMBODIAN: 14,
+    CJK_EARTHLY_BRANCH: 15,
+    CJK_HEAVENLY_STEM: 16,
+    CJK_IDEOGRAPHIC: 17,
+    DEVANAGARI: 18,
+    ETHIOPIC_NUMERIC: 19,
+    GEORGIAN: 20,
+    GUJARATI: 21,
+    GURMUKHI: 22,
+    HEBREW: 22,
+    HIRAGANA: 23,
+    HIRAGANA_IROHA: 24,
+    JAPANESE_FORMAL: 25,
+    JAPANESE_INFORMAL: 26,
+    KANNADA: 27,
+    KATAKANA: 28,
+    KATAKANA_IROHA: 29,
+    KHMER: 30,
+    KOREAN_HANGUL_FORMAL: 31,
+    KOREAN_HANJA_FORMAL: 32,
+    KOREAN_HANJA_INFORMAL: 33,
+    LAO: 34,
+    LOWER_ARMENIAN: 35,
+    MALAYALAM: 36,
+    MONGOLIAN: 37,
+    MYANMAR: 38,
+    ORIYA: 39,
+    PERSIAN: 40,
+    SIMP_CHINESE_FORMAL: 41,
+    SIMP_CHINESE_INFORMAL: 42,
+    TAMIL: 43,
+    TELUGU: 44,
+    THAI: 45,
+    TIBETAN: 46,
+    TRAD_CHINESE_FORMAL: 47,
+    TRAD_CHINESE_INFORMAL: 48,
+    UPPER_ARMENIAN: 49,
+    DISCLOSURE_OPEN: 50,
+    DISCLOSURE_CLOSED: 51
+};
+
+var parseListStyleType = exports.parseListStyleType = function parseListStyleType(type) {
+    switch (type) {
+        case 'disc':
+            return LIST_STYLE_TYPE.DISC;
+        case 'circle':
+            return LIST_STYLE_TYPE.CIRCLE;
+        case 'square':
+            return LIST_STYLE_TYPE.SQUARE;
+        case 'decimal':
+            return LIST_STYLE_TYPE.DECIMAL;
+        case 'cjk-decimal':
+            return LIST_STYLE_TYPE.CJK_DECIMAL;
+        case 'decimal-leading-zero':
+            return LIST_STYLE_TYPE.DECIMAL_LEADING_ZERO;
+        case 'lower-roman':
+            return LIST_STYLE_TYPE.LOWER_ROMAN;
+        case 'upper-roman':
+            return LIST_STYLE_TYPE.UPPER_ROMAN;
+        case 'lower-greek':
+            return LIST_STYLE_TYPE.LOWER_GREEK;
+        case 'lower-alpha':
+            return LIST_STYLE_TYPE.LOWER_ALPHA;
+        case 'upper-alpha':
+            return LIST_STYLE_TYPE.UPPER_ALPHA;
+        case 'arabic-indic':
+            return LIST_STYLE_TYPE.ARABIC_INDIC;
+        case 'armenian':
+            return LIST_STYLE_TYPE.ARMENIAN;
+        case 'bengali':
+            return LIST_STYLE_TYPE.BENGALI;
+        case 'cambodian':
+            return LIST_STYLE_TYPE.CAMBODIAN;
+        case 'cjk-earthly-branch':
+            return LIST_STYLE_TYPE.CJK_EARTHLY_BRANCH;
+        case 'cjk-heavenly-stem':
+            return LIST_STYLE_TYPE.CJK_HEAVENLY_STEM;
+        case 'cjk-ideographic':
+            return LIST_STYLE_TYPE.CJK_IDEOGRAPHIC;
+        case 'devanagari':
+            return LIST_STYLE_TYPE.DEVANAGARI;
+        case 'ethiopic-numeric':
+            return LIST_STYLE_TYPE.ETHIOPIC_NUMERIC;
+        case 'georgian':
+            return LIST_STYLE_TYPE.GEORGIAN;
+        case 'gujarati':
+            return LIST_STYLE_TYPE.GUJARATI;
+        case 'gurmukhi':
+            return LIST_STYLE_TYPE.GURMUKHI;
+        case 'hebrew':
+            return LIST_STYLE_TYPE.HEBREW;
+        case 'hiragana':
+            return LIST_STYLE_TYPE.HIRAGANA;
+        case 'hiragana-iroha':
+            return LIST_STYLE_TYPE.HIRAGANA_IROHA;
+        case 'japanese-formal':
+            return LIST_STYLE_TYPE.JAPANESE_FORMAL;
+        case 'japanese-informal':
+            return LIST_STYLE_TYPE.JAPANESE_INFORMAL;
+        case 'kannada':
+            return LIST_STYLE_TYPE.KANNADA;
+        case 'katakana':
+            return LIST_STYLE_TYPE.KATAKANA;
+        case 'katakana-iroha':
+            return LIST_STYLE_TYPE.KATAKANA_IROHA;
+        case 'khmer':
+            return LIST_STYLE_TYPE.KHMER;
+        case 'korean-hangul-formal':
+            return LIST_STYLE_TYPE.KOREAN_HANGUL_FORMAL;
+        case 'korean-hanja-formal':
+            return LIST_STYLE_TYPE.KOREAN_HANJA_FORMAL;
+        case 'korean-hanja-informal':
+            return LIST_STYLE_TYPE.KOREAN_HANJA_INFORMAL;
+        case 'lao':
+            return LIST_STYLE_TYPE.LAO;
+        case 'lower-armenian':
+            return LIST_STYLE_TYPE.LOWER_ARMENIAN;
+        case 'malayalam':
+            return LIST_STYLE_TYPE.MALAYALAM;
+        case 'mongolian':
+            return LIST_STYLE_TYPE.MONGOLIAN;
+        case 'myanmar':
+            return LIST_STYLE_TYPE.MYANMAR;
+        case 'oriya':
+            return LIST_STYLE_TYPE.ORIYA;
+        case 'persian':
+            return LIST_STYLE_TYPE.PERSIAN;
+        case 'simp-chinese-formal':
+            return LIST_STYLE_TYPE.SIMP_CHINESE_FORMAL;
+        case 'simp-chinese-informal':
+            return LIST_STYLE_TYPE.SIMP_CHINESE_INFORMAL;
+        case 'tamil':
+            return LIST_STYLE_TYPE.TAMIL;
+        case 'telugu':
+            return LIST_STYLE_TYPE.TELUGU;
+        case 'thai':
+            return LIST_STYLE_TYPE.THAI;
+        case 'tibetan':
+            return LIST_STYLE_TYPE.TIBETAN;
+        case 'trad-chinese-formal':
+            return LIST_STYLE_TYPE.TRAD_CHINESE_FORMAL;
+        case 'trad-chinese-informal':
+            return LIST_STYLE_TYPE.TRAD_CHINESE_INFORMAL;
+        case 'upper-armenian':
+            return LIST_STYLE_TYPE.UPPER_ARMENIAN;
+        case 'disclosure-open':
+            return LIST_STYLE_TYPE.DISCLOSURE_OPEN;
+        case 'disclosure-closed':
+            return LIST_STYLE_TYPE.DISCLOSURE_CLOSED;
+        case 'none':
+        default:
+            return LIST_STYLE_TYPE.NONE;
+    }
+};
+
+var parseListStyle = exports.parseListStyle = function parseListStyle(style) {
+    var listStyleImage = (0, _background.parseBackgroundImage)(style.getPropertyValue('list-style-image'));
+    return {
+        listStyleType: parseListStyleType(style.getPropertyValue('list-style-type')),
+        listStyleImage: listStyleImage.length ? listStyleImage[0] : null,
+        listStylePosition: parseListStylePosition(style.getPropertyValue('list-style-position'))
+    };
+};
+
+var parseListStylePosition = function parseListStylePosition(position) {
+    switch (position) {
+        case 'inside':
+            return LIST_STYLE_POSITION.INSIDE;
+        case 'outside':
+        default:
+            return LIST_STYLE_POSITION.OUTSIDE;
+    }
+};
+
+/***/ }),
+/* 9 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _textTransform = __webpack_require__(20);
+
+var _TextBounds = __webpack_require__(22);
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var TextContainer = function () {
+    function TextContainer(text, parent, bounds) {
+        _classCallCheck(this, TextContainer);
+
+        this.text = text;
+        this.parent = parent;
+        this.bounds = bounds;
+    }
+
+    _createClass(TextContainer, null, [{
+        key: 'fromTextNode',
+        value: function fromTextNode(node, parent) {
+            var text = transform(node.data, parent.style.textTransform);
+            return new TextContainer(text, parent, (0, _TextBounds.parseTextBounds)(text, parent, node));
+        }
+    }]);
+
+    return TextContainer;
+}();
+
+exports.default = TextContainer;
+
+
+var CAPITALIZE = /(^|\s|:|-|\(|\))([a-z])/g;
+
+var transform = function transform(text, _transform) {
+    switch (_transform) {
+        case _textTransform.TEXT_TRANSFORM.LOWERCASE:
+            return text.toLowerCase();
+        case _textTransform.TEXT_TRANSFORM.CAPITALIZE:
+            return text.replace(CAPITALIZE, capitalize);
+        case _textTransform.TEXT_TRANSFORM.UPPERCASE:
+            return text.toUpperCase();
+        default:
+            return text;
+    }
+};
+
+function capitalize(m, p1, p2) {
+    if (m.length > 0) {
+        return p1 + p2.toUpperCase();
+    }
+
+    return m;
+}
+
+/***/ }),
+/* 10 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _ForeignObjectRenderer = __webpack_require__(23);
+
+var testRangeBounds = function testRangeBounds(document) {
+    var TEST_HEIGHT = 123;
+
+    if (document.createRange) {
+        var range = document.createRange();
+        if (range.getBoundingClientRect) {
+            var testElement = document.createElement('boundtest');
+            testElement.style.height = TEST_HEIGHT + 'px';
+            testElement.style.display = 'block';
+            document.body.appendChild(testElement);
+
+            range.selectNode(testElement);
+            var rangeBounds = range.getBoundingClientRect();
+            var rangeHeight = Math.round(rangeBounds.height);
+            document.body.removeChild(testElement);
+            if (rangeHeight === TEST_HEIGHT) {
+                return true;
+            }
+        }
+    }
+
+    return false;
+};
+
+// iOS 10.3 taints canvas with base64 images unless crossOrigin = 'anonymous'
+var testBase64 = function testBase64(document, src) {
+    var img = new Image();
+    var canvas = document.createElement('canvas');
+    var ctx = canvas.getContext('2d');
+
+    return new Promise(function (resolve) {
+        // Single pixel base64 image renders fine on iOS 10.3???
+        img.src = src;
+
+        var onload = function onload() {
+            try {
+                ctx.drawImage(img, 0, 0);
+                canvas.toDataURL();
+            } catch (e) {
+                return resolve(false);
+            }
+
+            return resolve(true);
+        };
+
+        img.onload = onload;
+        img.onerror = function () {
+            return resolve(false);
+        };
+
+        if (img.complete === true) {
+            setTimeout(function () {
+                onload();
+            }, 500);
+        }
+    });
+};
+
+var testCORS = function testCORS() {
+    return typeof new Image().crossOrigin !== 'undefined';
+};
+
+var testResponseType = function testResponseType() {
+    return typeof new XMLHttpRequest().responseType === 'string';
+};
+
+var testSVG = function testSVG(document) {
+    var img = new Image();
+    var canvas = document.createElement('canvas');
+    var ctx = canvas.getContext('2d');
+    img.src = 'data:image/svg+xml,<svg xmlns=\'http://www.w3.org/2000/svg\'></svg>';
+
+    try {
+        ctx.drawImage(img, 0, 0);
+        canvas.toDataURL();
+    } catch (e) {
+        return false;
+    }
+    return true;
+};
+
+var isGreenPixel = function isGreenPixel(data) {
+    return data[0] === 0 && data[1] === 255 && data[2] === 0 && data[3] === 255;
+};
+
+var testForeignObject = function testForeignObject(document) {
+    var canvas = document.createElement('canvas');
+    var size = 100;
+    canvas.width = size;
+    canvas.height = size;
+    var ctx = canvas.getContext('2d');
+    ctx.fillStyle = 'rgb(0, 255, 0)';
+    ctx.fillRect(0, 0, size, size);
+
+    var img = new Image();
+    var greenImageSrc = canvas.toDataURL();
+    img.src = greenImageSrc;
+    var svg = (0, _ForeignObjectRenderer.createForeignObjectSVG)(size, size, 0, 0, img);
+    ctx.fillStyle = 'red';
+    ctx.fillRect(0, 0, size, size);
+
+    return (0, _ForeignObjectRenderer.loadSerializedSVG)(svg).then(function (img) {
+        ctx.drawImage(img, 0, 0);
+        var data = ctx.getImageData(0, 0, size, size).data;
+        ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, size, size);
+
+        var node = document.createElement('div');
+        node.style.backgroundImage = 'url(' + greenImageSrc + ')';
+        node.style.height = size + 'px';
+        // Firefox 55 does not render inline <img /> tags
+        return isGreenPixel(data) ? (0, _ForeignObjectRenderer.loadSerializedSVG)((0, _ForeignObjectRenderer.createForeignObjectSVG)(size, size, 0, 0, node)) : Promise.reject(false);
+    }).then(function (img) {
+        ctx.drawImage(img, 0, 0);
+        // Edge does not render background-images
+        return isGreenPixel(ctx.getImageData(0, 0, size, size).data);
+    }).catch(function (e) {
+        return false;
+    });
+};
+
+var FEATURES = {
+    // $FlowFixMe - get/set properties not yet supported
+    get SUPPORT_RANGE_BOUNDS() {
+        'use strict';
+
+        var value = testRangeBounds(document);
+        Object.defineProperty(FEATURES, 'SUPPORT_RANGE_BOUNDS', { value: value });
+        return value;
+    },
+    // $FlowFixMe - get/set properties not yet supported
+    get SUPPORT_SVG_DRAWING() {
+        'use strict';
+
+        var value = testSVG(document);
+        Object.defineProperty(FEATURES, 'SUPPORT_SVG_DRAWING', { value: value });
+        return value;
+    },
+    // $FlowFixMe - get/set properties not yet supported
+    get SUPPORT_BASE64_DRAWING() {
+        'use strict';
+
+        return function (src) {
+            var _value = testBase64(document, src);
+            Object.defineProperty(FEATURES, 'SUPPORT_BASE64_DRAWING', { value: function value() {
+                    return _value;
+                } });
+            return _value;
+        };
+    },
+    // $FlowFixMe - get/set properties not yet supported
+    get SUPPORT_FOREIGNOBJECT_DRAWING() {
+        'use strict';
+
+        var value = typeof Array.from === 'function' && typeof window.fetch === 'function' ? testForeignObject(document) : Promise.resolve(false);
+        Object.defineProperty(FEATURES, 'SUPPORT_FOREIGNOBJECT_DRAWING', { value: value });
+        return value;
+    },
+    // $FlowFixMe - get/set properties not yet supported
+    get SUPPORT_CORS_IMAGES() {
+        'use strict';
+
+        var value = testCORS();
+        Object.defineProperty(FEATURES, 'SUPPORT_CORS_IMAGES', { value: value });
+        return value;
+    },
+    // $FlowFixMe - get/set properties not yet supported
+    get SUPPORT_RESPONSE_TYPE() {
+        'use strict';
+
+        var value = testResponseType();
+        Object.defineProperty(FEATURES, 'SUPPORT_RESPONSE_TYPE', { value: value });
+        return value;
+    },
+    // $FlowFixMe - get/set properties not yet supported
+    get SUPPORT_CORS_XHR() {
+        'use strict';
+
+        var value = 'withCredentials' in new XMLHttpRequest();
+        Object.defineProperty(FEATURES, 'SUPPORT_CORS_XHR', { value: value });
+        return value;
+    }
+};
+
+exports.default = FEATURES;
+
+/***/ }),
+/* 11 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseTextDecoration = exports.TEXT_DECORATION_LINE = exports.TEXT_DECORATION = exports.TEXT_DECORATION_STYLE = undefined;
+
+var _Color = __webpack_require__(0);
+
+var _Color2 = _interopRequireDefault(_Color);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var TEXT_DECORATION_STYLE = exports.TEXT_DECORATION_STYLE = {
+    SOLID: 0,
+    DOUBLE: 1,
+    DOTTED: 2,
+    DASHED: 3,
+    WAVY: 4
+};
+
+var TEXT_DECORATION = exports.TEXT_DECORATION = {
+    NONE: null
+};
+
+var TEXT_DECORATION_LINE = exports.TEXT_DECORATION_LINE = {
+    UNDERLINE: 1,
+    OVERLINE: 2,
+    LINE_THROUGH: 3,
+    BLINK: 4
+};
+
+var parseLine = function parseLine(line) {
+    switch (line) {
+        case 'underline':
+            return TEXT_DECORATION_LINE.UNDERLINE;
+        case 'overline':
+            return TEXT_DECORATION_LINE.OVERLINE;
+        case 'line-through':
+            return TEXT_DECORATION_LINE.LINE_THROUGH;
+    }
+    return TEXT_DECORATION_LINE.BLINK;
+};
+
+var parseTextDecorationLine = function parseTextDecorationLine(line) {
+    if (line === 'none') {
+        return null;
+    }
+
+    return line.split(' ').map(parseLine);
+};
+
+var parseTextDecorationStyle = function parseTextDecorationStyle(style) {
+    switch (style) {
+        case 'double':
+            return TEXT_DECORATION_STYLE.DOUBLE;
+        case 'dotted':
+            return TEXT_DECORATION_STYLE.DOTTED;
+        case 'dashed':
+            return TEXT_DECORATION_STYLE.DASHED;
+        case 'wavy':
+            return TEXT_DECORATION_STYLE.WAVY;
+    }
+    return TEXT_DECORATION_STYLE.SOLID;
+};
+
+var parseTextDecoration = exports.parseTextDecoration = function parseTextDecoration(style) {
+    var textDecorationLine = parseTextDecorationLine(style.textDecorationLine ? style.textDecorationLine : style.textDecoration);
+    if (textDecorationLine === null) {
+        return TEXT_DECORATION.NONE;
+    }
+
+    var textDecorationColor = style.textDecorationColor ? new _Color2.default(style.textDecorationColor) : null;
+    var textDecorationStyle = parseTextDecorationStyle(style.textDecorationStyle);
+
+    return {
+        textDecorationLine: textDecorationLine,
+        textDecorationColor: textDecorationColor,
+        textDecorationStyle: textDecorationStyle
+    };
+};
+
+/***/ }),
+/* 12 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseBorder = exports.BORDER_SIDES = exports.BORDER_STYLE = undefined;
+
+var _Color = __webpack_require__(0);
+
+var _Color2 = _interopRequireDefault(_Color);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var BORDER_STYLE = exports.BORDER_STYLE = {
+    NONE: 0,
+    SOLID: 1
+};
+
+var BORDER_SIDES = exports.BORDER_SIDES = {
+    TOP: 0,
+    RIGHT: 1,
+    BOTTOM: 2,
+    LEFT: 3
+};
+
+var SIDES = Object.keys(BORDER_SIDES).map(function (s) {
+    return s.toLowerCase();
+});
+
+var parseBorderStyle = function parseBorderStyle(style) {
+    switch (style) {
+        case 'none':
+            return BORDER_STYLE.NONE;
+    }
+    return BORDER_STYLE.SOLID;
+};
+
+var parseBorder = exports.parseBorder = function parseBorder(style) {
+    return SIDES.map(function (side) {
+        var borderColor = new _Color2.default(style.getPropertyValue('border-' + side + '-color'));
+        var borderStyle = parseBorderStyle(style.getPropertyValue('border-' + side + '-style'));
+        var borderWidth = parseFloat(style.getPropertyValue('border-' + side + '-width'));
+        return {
+            borderColor: borderColor,
+            borderStyle: borderStyle,
+            borderWidth: isNaN(borderWidth) ? 0 : borderWidth
+        };
+    });
+};
+
+/***/ }),
+/* 13 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var toCodePoints = exports.toCodePoints = function toCodePoints(str) {
+    var codePoints = [];
+    var i = 0;
+    var length = str.length;
+    while (i < length) {
+        var value = str.charCodeAt(i++);
+        if (value >= 0xd800 && value <= 0xdbff && i < length) {
+            var extra = str.charCodeAt(i++);
+            if ((extra & 0xfc00) === 0xdc00) {
+                codePoints.push(((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000);
+            } else {
+                codePoints.push(value);
+                i--;
+            }
+        } else {
+            codePoints.push(value);
+        }
+    }
+    return codePoints;
+};
+
+var fromCodePoint = exports.fromCodePoint = function fromCodePoint() {
+    if (String.fromCodePoint) {
+        return String.fromCodePoint.apply(String, arguments);
+    }
+
+    var length = arguments.length;
+    if (!length) {
+        return '';
+    }
+
+    var codeUnits = [];
+
+    var index = -1;
+    var result = '';
+    while (++index < length) {
+        var codePoint = arguments.length <= index ? undefined : arguments[index];
+        if (codePoint <= 0xffff) {
+            codeUnits.push(codePoint);
+        } else {
+            codePoint -= 0x10000;
+            codeUnits.push((codePoint >> 10) + 0xd800, codePoint % 0x400 + 0xdc00);
+        }
+        if (index + 1 === length || codeUnits.length > 0x4000) {
+            result += String.fromCharCode.apply(String, codeUnits);
+            codeUnits.length = 0;
+        }
+    }
+    return result;
+};
+
+var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+
+// Use a lookup table to find the index.
+var lookup = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);
+for (var i = 0; i < chars.length; i++) {
+    lookup[chars.charCodeAt(i)] = i;
+}
+
+var decode = exports.decode = function decode(base64) {
+    var bufferLength = base64.length * 0.75,
+        len = base64.length,
+        i = void 0,
+        p = 0,
+        encoded1 = void 0,
+        encoded2 = void 0,
+        encoded3 = void 0,
+        encoded4 = void 0;
+
+    if (base64[base64.length - 1] === '=') {
+        bufferLength--;
+        if (base64[base64.length - 2] === '=') {
+            bufferLength--;
+        }
+    }
+
+    var buffer = typeof ArrayBuffer !== 'undefined' && typeof Uint8Array !== 'undefined' && typeof Uint8Array.prototype.slice !== 'undefined' ? new ArrayBuffer(bufferLength) : new Array(bufferLength);
+    var bytes = Array.isArray(buffer) ? buffer : new Uint8Array(buffer);
+
+    for (i = 0; i < len; i += 4) {
+        encoded1 = lookup[base64.charCodeAt(i)];
+        encoded2 = lookup[base64.charCodeAt(i + 1)];
+        encoded3 = lookup[base64.charCodeAt(i + 2)];
+        encoded4 = lookup[base64.charCodeAt(i + 3)];
+
+        bytes[p++] = encoded1 << 2 | encoded2 >> 4;
+        bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;
+        bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;
+    }
+
+    return buffer;
+};
+
+var polyUint16Array = exports.polyUint16Array = function polyUint16Array(buffer) {
+    var length = buffer.length;
+    var bytes = [];
+    for (var _i = 0; _i < length; _i += 2) {
+        bytes.push(buffer[_i + 1] << 8 | buffer[_i]);
+    }
+    return bytes;
+};
+
+var polyUint32Array = exports.polyUint32Array = function polyUint32Array(buffer) {
+    var length = buffer.length;
+    var bytes = [];
+    for (var _i2 = 0; _i2 < length; _i2 += 4) {
+        bytes.push(buffer[_i2 + 3] << 24 | buffer[_i2 + 2] << 16 | buffer[_i2 + 1] << 8 | buffer[_i2]);
+    }
+    return bytes;
+};
+
+/***/ }),
+/* 14 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.createCounterText = exports.inlineListItemElement = exports.getListOwner = undefined;
+
+var _Util = __webpack_require__(4);
+
+var _NodeContainer = __webpack_require__(3);
+
+var _NodeContainer2 = _interopRequireDefault(_NodeContainer);
+
+var _TextContainer = __webpack_require__(9);
+
+var _TextContainer2 = _interopRequireDefault(_TextContainer);
+
+var _listStyle = __webpack_require__(8);
+
+var _Unicode = __webpack_require__(24);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+// Margin between the enumeration and the list item content
+var MARGIN_RIGHT = 7;
+
+var ancestorTypes = ['OL', 'UL', 'MENU'];
+
+var getListOwner = exports.getListOwner = function getListOwner(container) {
+    var parent = container.parent;
+    if (!parent) {
+        return null;
+    }
+
+    do {
+        var isAncestor = ancestorTypes.indexOf(parent.tagName) !== -1;
+        if (isAncestor) {
+            return parent;
+        }
+        parent = parent.parent;
+    } while (parent);
+
+    return container.parent;
+};
+
+var inlineListItemElement = exports.inlineListItemElement = function inlineListItemElement(node, container, resourceLoader) {
+    var listStyle = container.style.listStyle;
+
+    if (!listStyle) {
+        return;
+    }
+
+    var style = node.ownerDocument.defaultView.getComputedStyle(node, null);
+    var wrapper = node.ownerDocument.createElement('html2canvaswrapper');
+    (0, _Util.copyCSSStyles)(style, wrapper);
+
+    wrapper.style.position = 'absolute';
+    wrapper.style.bottom = 'auto';
+    wrapper.style.display = 'block';
+    wrapper.style.letterSpacing = 'normal';
+
+    switch (listStyle.listStylePosition) {
+        case _listStyle.LIST_STYLE_POSITION.OUTSIDE:
+            wrapper.style.left = 'auto';
+            wrapper.style.right = node.ownerDocument.defaultView.innerWidth - container.bounds.left - container.style.margin[1].getAbsoluteValue(container.bounds.width) + MARGIN_RIGHT + 'px';
+            wrapper.style.textAlign = 'right';
+            break;
+        case _listStyle.LIST_STYLE_POSITION.INSIDE:
+            wrapper.style.left = container.bounds.left - container.style.margin[3].getAbsoluteValue(container.bounds.width) + 'px';
+            wrapper.style.right = 'auto';
+            wrapper.style.textAlign = 'left';
+            break;
+    }
+
+    var text = void 0;
+    var MARGIN_TOP = container.style.margin[0].getAbsoluteValue(container.bounds.width);
+    var styleImage = listStyle.listStyleImage;
+    if (styleImage) {
+        if (styleImage.method === 'url') {
+            var image = node.ownerDocument.createElement('img');
+            image.src = styleImage.args[0];
+            wrapper.style.top = container.bounds.top - MARGIN_TOP + 'px';
+            wrapper.style.width = 'auto';
+            wrapper.style.height = 'auto';
+            wrapper.appendChild(image);
+        } else {
+            var size = parseFloat(container.style.font.fontSize) * 0.5;
+            wrapper.style.top = container.bounds.top - MARGIN_TOP + container.bounds.height - 1.5 * size + 'px';
+            wrapper.style.width = size + 'px';
+            wrapper.style.height = size + 'px';
+            wrapper.style.backgroundImage = style.listStyleImage;
+        }
+    } else if (typeof container.listIndex === 'number') {
+        text = node.ownerDocument.createTextNode(createCounterText(container.listIndex, listStyle.listStyleType, true));
+        wrapper.appendChild(text);
+        wrapper.style.top = container.bounds.top - MARGIN_TOP + 'px';
+    }
+
+    // $FlowFixMe
+    var body = node.ownerDocument.body;
+    body.appendChild(wrapper);
+
+    if (text) {
+        container.childNodes.push(_TextContainer2.default.fromTextNode(text, container));
+        body.removeChild(wrapper);
+    } else {
+        // $FlowFixMe
+        container.childNodes.push(new _NodeContainer2.default(wrapper, container, resourceLoader, 0));
+    }
+};
+
+var ROMAN_UPPER = {
+    integers: [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1],
+    values: ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']
+};
+
+var ARMENIAN = {
+    integers: [9000, 8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
+    values: ['Ք', 'Փ', 'Ւ', 'Ց', 'Ր', 'Տ', 'Վ', 'Ս', 'Ռ', 'Ջ', 'Պ', 'Չ', 'Ո', 'Շ', 'Ն', 'Յ', 'Մ', 'Ճ', 'Ղ', 'Ձ', 'Հ', 'Կ', 'Ծ', 'Խ', 'Լ', 'Ի', 'Ժ', 'Թ', 'Ը', 'Է', 'Զ', 'Ե', 'Դ', 'Գ', 'Բ', 'Ա']
+};
+
+var HEBREW = {
+    integers: [10000, 9000, 8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000, 400, 300, 200, 100, 90, 80, 70, 60, 50, 40, 30, 20, 19, 18, 17, 16, 15, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
+    values: ['י׳', 'ט׳', 'ח׳', 'ז׳', 'ו׳', 'ה׳', 'ד׳', 'ג׳', 'ב׳', 'א׳', 'ת', 'ש', 'ר', 'ק', 'צ', 'פ', 'ע', 'ס', 'נ', 'מ', 'ל', 'כ', 'יט', 'יח', 'יז', 'טז', 'טו', 'י', 'ט', 'ח', 'ז', 'ו', 'ה', 'ד', 'ג', 'ב', 'א']
+};
+
+var GEORGIAN = {
+    integers: [10000, 9000, 8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
+    values: ['ჵ', 'ჰ', 'ჯ', 'ჴ', 'ხ', 'ჭ', 'წ', 'ძ', 'ც', 'ჩ', 'შ', 'ყ', 'ღ', 'ქ', 'ფ', 'ჳ', 'ტ', 'ს', 'რ', 'ჟ', 'პ', 'ო', 'ჲ', 'ნ', 'მ', 'ლ', 'კ', 'ი', 'თ', 'ჱ', 'ზ', 'ვ', 'ე', 'დ', 'გ', 'ბ', 'ა']
+};
+
+var createAdditiveCounter = function createAdditiveCounter(value, min, max, symbols, fallback, suffix) {
+    if (value < min || value > max) {
+        return createCounterText(value, fallback, suffix.length > 0);
+    }
+
+    return symbols.integers.reduce(function (string, integer, index) {
+        while (value >= integer) {
+            value -= integer;
+            string += symbols.values[index];
+        }
+        return string;
+    }, '') + suffix;
+};
+
+var createCounterStyleWithSymbolResolver = function createCounterStyleWithSymbolResolver(value, codePointRangeLength, isNumeric, resolver) {
+    var string = '';
+
+    do {
+        if (!isNumeric) {
+            value--;
+        }
+        string = resolver(value) + string;
+        value /= codePointRangeLength;
+    } while (value * codePointRangeLength >= codePointRangeLength);
+
+    return string;
+};
+
+var createCounterStyleFromRange = function createCounterStyleFromRange(value, codePointRangeStart, codePointRangeEnd, isNumeric, suffix) {
+    var codePointRangeLength = codePointRangeEnd - codePointRangeStart + 1;
+
+    return (value < 0 ? '-' : '') + (createCounterStyleWithSymbolResolver(Math.abs(value), codePointRangeLength, isNumeric, function (codePoint) {
+        return (0, _Unicode.fromCodePoint)(Math.floor(codePoint % codePointRangeLength) + codePointRangeStart);
+    }) + suffix);
+};
+
+var createCounterStyleFromSymbols = function createCounterStyleFromSymbols(value, symbols) {
+    var suffix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '. ';
+
+    var codePointRangeLength = symbols.length;
+    return createCounterStyleWithSymbolResolver(Math.abs(value), codePointRangeLength, false, function (codePoint) {
+        return symbols[Math.floor(codePoint % codePointRangeLength)];
+    }) + suffix;
+};
+
+var CJK_ZEROS = 1 << 0;
+var CJK_TEN_COEFFICIENTS = 1 << 1;
+var CJK_TEN_HIGH_COEFFICIENTS = 1 << 2;
+var CJK_HUNDRED_COEFFICIENTS = 1 << 3;
+
+var createCJKCounter = function createCJKCounter(value, numbers, multipliers, negativeSign, suffix, flags) {
+    if (value < -9999 || value > 9999) {
+        return createCounterText(value, _listStyle.LIST_STYLE_TYPE.CJK_DECIMAL, suffix.length > 0);
+    }
+    var tmp = Math.abs(value);
+    var string = suffix;
+
+    if (tmp === 0) {
+        return numbers[0] + string;
+    }
+
+    for (var digit = 0; tmp > 0 && digit <= 4; digit++) {
+        var coefficient = tmp % 10;
+
+        if (coefficient === 0 && (0, _Util.contains)(flags, CJK_ZEROS) && string !== '') {
+            string = numbers[coefficient] + string;
+        } else if (coefficient > 1 || coefficient === 1 && digit === 0 || coefficient === 1 && digit === 1 && (0, _Util.contains)(flags, CJK_TEN_COEFFICIENTS) || coefficient === 1 && digit === 1 && (0, _Util.contains)(flags, CJK_TEN_HIGH_COEFFICIENTS) && value > 100 || coefficient === 1 && digit > 1 && (0, _Util.contains)(flags, CJK_HUNDRED_COEFFICIENTS)) {
+            string = numbers[coefficient] + (digit > 0 ? multipliers[digit - 1] : '') + string;
+        } else if (coefficient === 1 && digit > 0) {
+            string = multipliers[digit - 1] + string;
+        }
+        tmp = Math.floor(tmp / 10);
+    }
+
+    return (value < 0 ? negativeSign : '') + string;
+};
+
+var CHINESE_INFORMAL_MULTIPLIERS = '十百千萬';
+var CHINESE_FORMAL_MULTIPLIERS = '拾佰仟萬';
+var JAPANESE_NEGATIVE = 'マイナス';
+var KOREAN_NEGATIVE = '마이너스 ';
+
+var createCounterText = exports.createCounterText = function createCounterText(value, type, appendSuffix) {
+    var defaultSuffix = appendSuffix ? '. ' : '';
+    var cjkSuffix = appendSuffix ? '、' : '';
+    var koreanSuffix = appendSuffix ? ', ' : '';
+    switch (type) {
+        case _listStyle.LIST_STYLE_TYPE.DISC:
+            return '•';
+        case _listStyle.LIST_STYLE_TYPE.CIRCLE:
+            return '◦';
+        case _listStyle.LIST_STYLE_TYPE.SQUARE:
+            return '◾';
+        case _listStyle.LIST_STYLE_TYPE.DECIMAL_LEADING_ZERO:
+            var string = createCounterStyleFromRange(value, 48, 57, true, defaultSuffix);
+            return string.length < 4 ? '0' + string : string;
+        case _listStyle.LIST_STYLE_TYPE.CJK_DECIMAL:
+            return createCounterStyleFromSymbols(value, '〇一二三四五六七八九', cjkSuffix);
+        case _listStyle.LIST_STYLE_TYPE.LOWER_ROMAN:
+            return createAdditiveCounter(value, 1, 3999, ROMAN_UPPER, _listStyle.LIST_STYLE_TYPE.DECIMAL, defaultSuffix).toLowerCase();
+        case _listStyle.LIST_STYLE_TYPE.UPPER_ROMAN:
+            return createAdditiveCounter(value, 1, 3999, ROMAN_UPPER, _listStyle.LIST_STYLE_TYPE.DECIMAL, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.LOWER_GREEK:
+            return createCounterStyleFromRange(value, 945, 969, false, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.LOWER_ALPHA:
+            return createCounterStyleFromRange(value, 97, 122, false, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.UPPER_ALPHA:
+            return createCounterStyleFromRange(value, 65, 90, false, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.ARABIC_INDIC:
+            return createCounterStyleFromRange(value, 1632, 1641, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.ARMENIAN:
+        case _listStyle.LIST_STYLE_TYPE.UPPER_ARMENIAN:
+            return createAdditiveCounter(value, 1, 9999, ARMENIAN, _listStyle.LIST_STYLE_TYPE.DECIMAL, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.LOWER_ARMENIAN:
+            return createAdditiveCounter(value, 1, 9999, ARMENIAN, _listStyle.LIST_STYLE_TYPE.DECIMAL, defaultSuffix).toLowerCase();
+        case _listStyle.LIST_STYLE_TYPE.BENGALI:
+            return createCounterStyleFromRange(value, 2534, 2543, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.CAMBODIAN:
+        case _listStyle.LIST_STYLE_TYPE.KHMER:
+            return createCounterStyleFromRange(value, 6112, 6121, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.CJK_EARTHLY_BRANCH:
+            return createCounterStyleFromSymbols(value, '子丑寅卯辰巳午未申酉戌亥', cjkSuffix);
+        case _listStyle.LIST_STYLE_TYPE.CJK_HEAVENLY_STEM:
+            return createCounterStyleFromSymbols(value, '甲乙丙丁戊己庚辛壬癸', cjkSuffix);
+        case _listStyle.LIST_STYLE_TYPE.CJK_IDEOGRAPHIC:
+        case _listStyle.LIST_STYLE_TYPE.TRAD_CHINESE_INFORMAL:
+            return createCJKCounter(value, '零一二三四五六七八九', CHINESE_INFORMAL_MULTIPLIERS, '負', cjkSuffix, CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS | CJK_HUNDRED_COEFFICIENTS);
+        case _listStyle.LIST_STYLE_TYPE.TRAD_CHINESE_FORMAL:
+            return createCJKCounter(value, '零壹貳參肆伍陸柒捌玖', CHINESE_FORMAL_MULTIPLIERS, '負', cjkSuffix, CJK_ZEROS | CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS | CJK_HUNDRED_COEFFICIENTS);
+        case _listStyle.LIST_STYLE_TYPE.SIMP_CHINESE_INFORMAL:
+            return createCJKCounter(value, '零一二三四五六七八九', CHINESE_INFORMAL_MULTIPLIERS, '负', cjkSuffix, CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS | CJK_HUNDRED_COEFFICIENTS);
+        case _listStyle.LIST_STYLE_TYPE.SIMP_CHINESE_FORMAL:
+            return createCJKCounter(value, '零壹贰叁肆伍陆柒捌玖', CHINESE_FORMAL_MULTIPLIERS, '负', cjkSuffix, CJK_ZEROS | CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS | CJK_HUNDRED_COEFFICIENTS);
+        case _listStyle.LIST_STYLE_TYPE.JAPANESE_INFORMAL:
+            return createCJKCounter(value, '〇一二三四五六七八九', '十百千万', JAPANESE_NEGATIVE, cjkSuffix, 0);
+        case _listStyle.LIST_STYLE_TYPE.JAPANESE_FORMAL:
+            return createCJKCounter(value, '零壱弐参四伍六七八九', '拾百千万', JAPANESE_NEGATIVE, cjkSuffix, CJK_ZEROS | CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS);
+        case _listStyle.LIST_STYLE_TYPE.KOREAN_HANGUL_FORMAL:
+            return createCJKCounter(value, '영일이삼사오육칠팔구', '십백천만', KOREAN_NEGATIVE, koreanSuffix, CJK_ZEROS | CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS);
+        case _listStyle.LIST_STYLE_TYPE.KOREAN_HANJA_INFORMAL:
+            return createCJKCounter(value, '零一二三四五六七八九', '十百千萬', KOREAN_NEGATIVE, koreanSuffix, 0);
+        case _listStyle.LIST_STYLE_TYPE.KOREAN_HANJA_FORMAL:
+            return createCJKCounter(value, '零壹貳參四五六七八九', '拾百千', KOREAN_NEGATIVE, koreanSuffix, CJK_ZEROS | CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS);
+        case _listStyle.LIST_STYLE_TYPE.DEVANAGARI:
+            return createCounterStyleFromRange(value, 0x966, 0x96f, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.GEORGIAN:
+            return createAdditiveCounter(value, 1, 19999, GEORGIAN, _listStyle.LIST_STYLE_TYPE.DECIMAL, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.GUJARATI:
+            return createCounterStyleFromRange(value, 0xae6, 0xaef, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.GURMUKHI:
+            return createCounterStyleFromRange(value, 0xa66, 0xa6f, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.HEBREW:
+            return createAdditiveCounter(value, 1, 10999, HEBREW, _listStyle.LIST_STYLE_TYPE.DECIMAL, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.HIRAGANA:
+            return createCounterStyleFromSymbols(value, 'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわゐゑをん');
+        case _listStyle.LIST_STYLE_TYPE.HIRAGANA_IROHA:
+            return createCounterStyleFromSymbols(value, 'いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす');
+        case _listStyle.LIST_STYLE_TYPE.KANNADA:
+            return createCounterStyleFromRange(value, 0xce6, 0xcef, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.KATAKANA:
+            return createCounterStyleFromSymbols(value, 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヰヱヲン', cjkSuffix);
+        case _listStyle.LIST_STYLE_TYPE.KATAKANA_IROHA:
+            return createCounterStyleFromSymbols(value, 'イロハニホヘトチリヌルヲワカヨタレソツネナラムウヰノオクヤマケフコエテアサキユメミシヱヒモセス', cjkSuffix);
+        case _listStyle.LIST_STYLE_TYPE.LAO:
+            return createCounterStyleFromRange(value, 0xed0, 0xed9, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.MONGOLIAN:
+            return createCounterStyleFromRange(value, 0x1810, 0x1819, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.MYANMAR:
+            return createCounterStyleFromRange(value, 0x1040, 0x1049, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.ORIYA:
+            return createCounterStyleFromRange(value, 0xb66, 0xb6f, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.PERSIAN:
+            return createCounterStyleFromRange(value, 0x6f0, 0x6f9, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.TAMIL:
+            return createCounterStyleFromRange(value, 0xbe6, 0xbef, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.TELUGU:
+            return createCounterStyleFromRange(value, 0xc66, 0xc6f, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.THAI:
+            return createCounterStyleFromRange(value, 0xe50, 0xe59, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.TIBETAN:
+            return createCounterStyleFromRange(value, 0xf20, 0xf29, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.DECIMAL:
+        default:
+            return createCounterStyleFromRange(value, 48, 57, true, defaultSuffix);
+    }
+};
+
+/***/ }),
+/* 15 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Path = __webpack_require__(6);
+
+var _textDecoration = __webpack_require__(11);
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var addColorStops = function addColorStops(gradient, canvasGradient) {
+    var maxStop = Math.max.apply(null, gradient.colorStops.map(function (colorStop) {
+        return colorStop.stop;
+    }));
+    var f = 1 / Math.max(1, maxStop);
+    gradient.colorStops.forEach(function (colorStop) {
+        canvasGradient.addColorStop(f * colorStop.stop, colorStop.color.toString());
+    });
+};
+
+var CanvasRenderer = function () {
+    function CanvasRenderer(canvas) {
+        _classCallCheck(this, CanvasRenderer);
+
+        this.canvas = canvas ? canvas : document.createElement('canvas');
+    }
+
+    _createClass(CanvasRenderer, [{
+        key: 'render',
+        value: function render(options) {
+            this.ctx = this.canvas.getContext('2d');
+            this.options = options;
+            this.canvas.width = Math.floor(options.width * options.scale);
+            this.canvas.height = Math.floor(options.height * options.scale);
+            this.canvas.style.width = options.width + 'px';
+            this.canvas.style.height = options.height + 'px';
+
+            this.ctx.scale(this.options.scale, this.options.scale);
+            this.ctx.translate(-options.x, -options.y);
+            this.ctx.textBaseline = 'bottom';
+            options.logger.log('Canvas renderer initialized (' + options.width + 'x' + options.height + ' at ' + options.x + ',' + options.y + ') with scale ' + this.options.scale);
+        }
+    }, {
+        key: 'clip',
+        value: function clip(clipPaths, callback) {
+            var _this = this;
+
+            if (clipPaths.length) {
+                this.ctx.save();
+                clipPaths.forEach(function (path) {
+                    _this.path(path);
+                    _this.ctx.clip();
+                });
+            }
+
+            callback();
+
+            if (clipPaths.length) {
+                this.ctx.restore();
+            }
+        }
+    }, {
+        key: 'drawImage',
+        value: function drawImage(image, source, destination) {
+            this.ctx.drawImage(image, source.left, source.top, source.width, source.height, destination.left, destination.top, destination.width, destination.height);
+        }
+    }, {
+        key: 'drawShape',
+        value: function drawShape(path, color) {
+            this.path(path);
+            this.ctx.fillStyle = color.toString();
+            this.ctx.fill();
+        }
+    }, {
+        key: 'fill',
+        value: function fill(color) {
+            this.ctx.fillStyle = color.toString();
+            this.ctx.fill();
+        }
+    }, {
+        key: 'getTarget',
+        value: function getTarget() {
+            this.canvas.getContext('2d').setTransform(1, 0, 0, 1, 0, 0);
+            return Promise.resolve(this.canvas);
+        }
+    }, {
+        key: 'path',
+        value: function path(_path) {
+            var _this2 = this;
+
+            this.ctx.beginPath();
+            if (Array.isArray(_path)) {
+                _path.forEach(function (point, index) {
+                    var start = point.type === _Path.PATH.VECTOR ? point : point.start;
+                    if (index === 0) {
+                        _this2.ctx.moveTo(start.x, start.y);
+                    } else {
+                        _this2.ctx.lineTo(start.x, start.y);
+                    }
+
+                    if (point.type === _Path.PATH.BEZIER_CURVE) {
+                        _this2.ctx.bezierCurveTo(point.startControl.x, point.startControl.y, point.endControl.x, point.endControl.y, point.end.x, point.end.y);
+                    }
+                });
+            } else {
+                this.ctx.arc(_path.x + _path.radius, _path.y + _path.radius, _path.radius, 0, Math.PI * 2, true);
+            }
+
+            this.ctx.closePath();
+        }
+    }, {
+        key: 'rectangle',
+        value: function rectangle(x, y, width, height, color) {
+            this.ctx.fillStyle = color.toString();
+            this.ctx.fillRect(x, y, width, height);
+        }
+    }, {
+        key: 'renderLinearGradient',
+        value: function renderLinearGradient(bounds, gradient) {
+            var linearGradient = this.ctx.createLinearGradient(bounds.left + gradient.direction.x1, bounds.top + gradient.direction.y1, bounds.left + gradient.direction.x0, bounds.top + gradient.direction.y0);
+
+            addColorStops(gradient, linearGradient);
+            this.ctx.fillStyle = linearGradient;
+            this.ctx.fillRect(bounds.left, bounds.top, bounds.width, bounds.height);
+        }
+    }, {
+        key: 'renderRadialGradient',
+        value: function renderRadialGradient(bounds, gradient) {
+            var _this3 = this;
+
+            var x = bounds.left + gradient.center.x;
+            var y = bounds.top + gradient.center.y;
+
+            var radialGradient = this.ctx.createRadialGradient(x, y, 0, x, y, gradient.radius.x);
+            if (!radialGradient) {
+                return;
+            }
+
+            addColorStops(gradient, radialGradient);
+            this.ctx.fillStyle = radialGradient;
+
+            if (gradient.radius.x !== gradient.radius.y) {
+                // transforms for elliptical radial gradient
+                var midX = bounds.left + 0.5 * bounds.width;
+                var midY = bounds.top + 0.5 * bounds.height;
+                var f = gradient.radius.y / gradient.radius.x;
+                var invF = 1 / f;
+
+                this.transform(midX, midY, [1, 0, 0, f, 0, 0], function () {
+                    return _this3.ctx.fillRect(bounds.left, invF * (bounds.top - midY) + midY, bounds.width, bounds.height * invF);
+                });
+            } else {
+                this.ctx.fillRect(bounds.left, bounds.top, bounds.width, bounds.height);
+            }
+        }
+    }, {
+        key: 'renderRepeat',
+        value: function renderRepeat(path, image, imageSize, offsetX, offsetY) {
+            this.path(path);
+            this.ctx.fillStyle = this.ctx.createPattern(this.resizeImage(image, imageSize), 'repeat');
+            this.ctx.translate(offsetX, offsetY);
+            this.ctx.fill();
+            this.ctx.translate(-offsetX, -offsetY);
+        }
+    }, {
+        key: 'renderTextNode',
+        value: function renderTextNode(textBounds, color, font, textDecoration, textShadows) {
+            var _this4 = this;
+
+            this.ctx.font = [font.fontStyle, font.fontVariant, font.fontWeight, font.fontSize, font.fontFamily].join(' ');
+
+            textBounds.forEach(function (text) {
+                _this4.ctx.fillStyle = color.toString();
+                if (textShadows && text.text.trim().length) {
+                    textShadows.slice(0).reverse().forEach(function (textShadow) {
+                        _this4.ctx.shadowColor = textShadow.color.toString();
+                        _this4.ctx.shadowOffsetX = textShadow.offsetX * _this4.options.scale;
+                        _this4.ctx.shadowOffsetY = textShadow.offsetY * _this4.options.scale;
+                        _this4.ctx.shadowBlur = textShadow.blur;
+
+                        _this4.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
+                    });
+                } else {
+                    _this4.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
+                }
+
+                if (textDecoration !== null) {
+                    var textDecorationColor = textDecoration.textDecorationColor || color;
+                    textDecoration.textDecorationLine.forEach(function (textDecorationLine) {
+                        switch (textDecorationLine) {
+                            case _textDecoration.TEXT_DECORATION_LINE.UNDERLINE:
+                                // Draws a line at the baseline of the font
+                                // TODO As some browsers display the line as more than 1px if the font-size is big,
+                                // need to take that into account both in position and size
+                                var _options$fontMetrics$ = _this4.options.fontMetrics.getMetrics(font),
+                                    baseline = _options$fontMetrics$.baseline;
+
+                                _this4.rectangle(text.bounds.left, Math.round(text.bounds.top + baseline), text.bounds.width, 1, textDecorationColor);
+                                break;
+                            case _textDecoration.TEXT_DECORATION_LINE.OVERLINE:
+                                _this4.rectangle(text.bounds.left, Math.round(text.bounds.top), text.bounds.width, 1, textDecorationColor);
+                                break;
+                            case _textDecoration.TEXT_DECORATION_LINE.LINE_THROUGH:
+                                // TODO try and find exact position for line-through
+                                var _options$fontMetrics$2 = _this4.options.fontMetrics.getMetrics(font),
+                                    middle = _options$fontMetrics$2.middle;
+
+                                _this4.rectangle(text.bounds.left, Math.ceil(text.bounds.top + middle), text.bounds.width, 1, textDecorationColor);
+                                break;
+                        }
+                    });
+                }
+            });
+        }
+    }, {
+        key: 'resizeImage',
+        value: function resizeImage(image, size) {
+            if (image.width === size.width && image.height === size.height) {
+                return image;
+            }
+
+            var canvas = this.canvas.ownerDocument.createElement('canvas');
+            canvas.width = size.width;
+            canvas.height = size.height;
+            var ctx = canvas.getContext('2d');
+            ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, size.width, size.height);
+            return canvas;
+        }
+    }, {
+        key: 'setOpacity',
+        value: function setOpacity(opacity) {
+            this.ctx.globalAlpha = opacity;
+        }
+    }, {
+        key: 'transform',
+        value: function transform(offsetX, offsetY, matrix, callback) {
+            this.ctx.save();
+            this.ctx.translate(offsetX, offsetY);
+            this.ctx.transform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
+            this.ctx.translate(-offsetX, -offsetY);
+
+            callback();
+
+            this.ctx.restore();
+        }
+    }]);
+
+    return CanvasRenderer;
+}();
+
+exports.default = CanvasRenderer;
+
+/***/ }),
+/* 16 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Logger = function () {
+    function Logger(enabled, id, start) {
+        _classCallCheck(this, Logger);
+
+        this.enabled = typeof window !== 'undefined' && enabled;
+        this.start = start ? start : Date.now();
+        this.id = id;
+    }
+
+    _createClass(Logger, [{
+        key: 'child',
+        value: function child(id) {
+            return new Logger(this.enabled, id, this.start);
+        }
+
+        // eslint-disable-next-line flowtype/no-weak-types
+
+    }, {
+        key: 'log',
+        value: function log() {
+            if (this.enabled && window.console && window.console.log) {
+                for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+                    args[_key] = arguments[_key];
+                }
+
+                Function.prototype.bind.call(window.console.log, window.console).apply(window.console, [Date.now() - this.start + 'ms', this.id ? 'html2canvas (' + this.id + '):' : 'html2canvas:'].concat([].slice.call(args, 0)));
+            }
+        }
+
+        // eslint-disable-next-line flowtype/no-weak-types
+
+    }, {
+        key: 'error',
+        value: function error() {
+            if (this.enabled && window.console && window.console.error) {
+                for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
+                    args[_key2] = arguments[_key2];
+                }
+
+                Function.prototype.bind.call(window.console.error, window.console).apply(window.console, [Date.now() - this.start + 'ms', this.id ? 'html2canvas (' + this.id + '):' : 'html2canvas:'].concat([].slice.call(args, 0)));
+            }
+        }
+    }]);
+
+    return Logger;
+}();
+
+exports.default = Logger;
+
+/***/ }),
+/* 17 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parsePadding = exports.PADDING_SIDES = undefined;
+
+var _Length = __webpack_require__(1);
+
+var _Length2 = _interopRequireDefault(_Length);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var PADDING_SIDES = exports.PADDING_SIDES = {
+    TOP: 0,
+    RIGHT: 1,
+    BOTTOM: 2,
+    LEFT: 3
+};
+
+var SIDES = ['top', 'right', 'bottom', 'left'];
+
+var parsePadding = exports.parsePadding = function parsePadding(style) {
+    return SIDES.map(function (side) {
+        return new _Length2.default(style.getPropertyValue('padding-' + side));
+    });
+};
+
+/***/ }),
+/* 18 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var OVERFLOW_WRAP = exports.OVERFLOW_WRAP = {
+    NORMAL: 0,
+    BREAK_WORD: 1
+};
+
+var parseOverflowWrap = exports.parseOverflowWrap = function parseOverflowWrap(overflow) {
+    switch (overflow) {
+        case 'break-word':
+            return OVERFLOW_WRAP.BREAK_WORD;
+        case 'normal':
+        default:
+            return OVERFLOW_WRAP.NORMAL;
+    }
+};
+
+/***/ }),
+/* 19 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var POSITION = exports.POSITION = {
+    STATIC: 0,
+    RELATIVE: 1,
+    ABSOLUTE: 2,
+    FIXED: 3,
+    STICKY: 4
+};
+
+var parsePosition = exports.parsePosition = function parsePosition(position) {
+    switch (position) {
+        case 'relative':
+            return POSITION.RELATIVE;
+        case 'absolute':
+            return POSITION.ABSOLUTE;
+        case 'fixed':
+            return POSITION.FIXED;
+        case 'sticky':
+            return POSITION.STICKY;
+    }
+
+    return POSITION.STATIC;
+};
+
+/***/ }),
+/* 20 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var TEXT_TRANSFORM = exports.TEXT_TRANSFORM = {
+    NONE: 0,
+    LOWERCASE: 1,
+    UPPERCASE: 2,
+    CAPITALIZE: 3
+};
+
+var parseTextTransform = exports.parseTextTransform = function parseTextTransform(textTransform) {
+    switch (textTransform) {
+        case 'uppercase':
+            return TEXT_TRANSFORM.UPPERCASE;
+        case 'lowercase':
+            return TEXT_TRANSFORM.LOWERCASE;
+        case 'capitalize':
+            return TEXT_TRANSFORM.CAPITALIZE;
+    }
+
+    return TEXT_TRANSFORM.NONE;
+};
+
+/***/ }),
+/* 21 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.reformatInputBounds = exports.inlineSelectElement = exports.inlineTextAreaElement = exports.inlineInputElement = exports.getInputBorderRadius = exports.INPUT_BACKGROUND = exports.INPUT_BORDERS = exports.INPUT_COLOR = undefined;
+
+var _TextContainer = __webpack_require__(9);
+
+var _TextContainer2 = _interopRequireDefault(_TextContainer);
+
+var _background = __webpack_require__(5);
+
+var _border = __webpack_require__(12);
+
+var _Circle = __webpack_require__(50);
+
+var _Circle2 = _interopRequireDefault(_Circle);
+
+var _Vector = __webpack_require__(7);
+
+var _Vector2 = _interopRequireDefault(_Vector);
+
+var _Color = __webpack_require__(0);
+
+var _Color2 = _interopRequireDefault(_Color);
+
+var _Length = __webpack_require__(1);
+
+var _Length2 = _interopRequireDefault(_Length);
+
+var _Bounds = __webpack_require__(2);
+
+var _TextBounds = __webpack_require__(22);
+
+var _Util = __webpack_require__(4);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var INPUT_COLOR = exports.INPUT_COLOR = new _Color2.default([42, 42, 42]);
+var INPUT_BORDER_COLOR = new _Color2.default([165, 165, 165]);
+var INPUT_BACKGROUND_COLOR = new _Color2.default([222, 222, 222]);
+var INPUT_BORDER = {
+    borderWidth: 1,
+    borderColor: INPUT_BORDER_COLOR,
+    borderStyle: _border.BORDER_STYLE.SOLID
+};
+var INPUT_BORDERS = exports.INPUT_BORDERS = [INPUT_BORDER, INPUT_BORDER, INPUT_BORDER, INPUT_BORDER];
+var INPUT_BACKGROUND = exports.INPUT_BACKGROUND = {
+    backgroundColor: INPUT_BACKGROUND_COLOR,
+    backgroundImage: [],
+    backgroundClip: _background.BACKGROUND_CLIP.PADDING_BOX,
+    backgroundOrigin: _background.BACKGROUND_ORIGIN.PADDING_BOX
+};
+
+var RADIO_BORDER_RADIUS = new _Length2.default('50%');
+var RADIO_BORDER_RADIUS_TUPLE = [RADIO_BORDER_RADIUS, RADIO_BORDER_RADIUS];
+var INPUT_RADIO_BORDER_RADIUS = [RADIO_BORDER_RADIUS_TUPLE, RADIO_BORDER_RADIUS_TUPLE, RADIO_BORDER_RADIUS_TUPLE, RADIO_BORDER_RADIUS_TUPLE];
+
+var CHECKBOX_BORDER_RADIUS = new _Length2.default('3px');
+var CHECKBOX_BORDER_RADIUS_TUPLE = [CHECKBOX_BORDER_RADIUS, CHECKBOX_BORDER_RADIUS];
+var INPUT_CHECKBOX_BORDER_RADIUS = [CHECKBOX_BORDER_RADIUS_TUPLE, CHECKBOX_BORDER_RADIUS_TUPLE, CHECKBOX_BORDER_RADIUS_TUPLE, CHECKBOX_BORDER_RADIUS_TUPLE];
+
+var getInputBorderRadius = exports.getInputBorderRadius = function getInputBorderRadius(node) {
+    return node.type === 'radio' ? INPUT_RADIO_BORDER_RADIUS : INPUT_CHECKBOX_BORDER_RADIUS;
+};
+
+var inlineInputElement = exports.inlineInputElement = function inlineInputElement(node, container) {
+    if (node.type === 'radio' || node.type === 'checkbox') {
+        if (node.checked) {
+            var size = Math.min(container.bounds.width, container.bounds.height);
+            container.childNodes.push(node.type === 'checkbox' ? [new _Vector2.default(container.bounds.left + size * 0.39363, container.bounds.top + size * 0.79), new _Vector2.default(container.bounds.left + size * 0.16, container.bounds.top + size * 0.5549), new _Vector2.default(container.bounds.left + size * 0.27347, container.bounds.top + size * 0.44071), new _Vector2.default(container.bounds.left + size * 0.39694, container.bounds.top + size * 0.5649), new _Vector2.default(container.bounds.left + size * 0.72983, container.bounds.top + size * 0.23), new _Vector2.default(container.bounds.left + size * 0.84, container.bounds.top + size * 0.34085), new _Vector2.default(container.bounds.left + size * 0.39363, container.bounds.top + size * 0.79)] : new _Circle2.default(container.bounds.left + size / 4, container.bounds.top + size / 4, size / 4));
+        }
+    } else {
+        inlineFormElement(getInputValue(node), node, container, false);
+    }
+};
+
+var inlineTextAreaElement = exports.inlineTextAreaElement = function inlineTextAreaElement(node, container) {
+    inlineFormElement(node.value, node, container, true);
+};
+
+var inlineSelectElement = exports.inlineSelectElement = function inlineSelectElement(node, container) {
+    var option = node.options[node.selectedIndex || 0];
+    inlineFormElement(option ? option.text || '' : '', node, container, false);
+};
+
+var reformatInputBounds = exports.reformatInputBounds = function reformatInputBounds(bounds) {
+    if (bounds.width > bounds.height) {
+        bounds.left += (bounds.width - bounds.height) / 2;
+        bounds.width = bounds.height;
+    } else if (bounds.width < bounds.height) {
+        bounds.top += (bounds.height - bounds.width) / 2;
+        bounds.height = bounds.width;
+    }
+    return bounds;
+};
+
+var inlineFormElement = function inlineFormElement(value, node, container, allowLinebreak) {
+    var body = node.ownerDocument.body;
+    if (value.length > 0 && body) {
+        var wrapper = node.ownerDocument.createElement('html2canvaswrapper');
+        (0, _Util.copyCSSStyles)(node.ownerDocument.defaultView.getComputedStyle(node, null), wrapper);
+        wrapper.style.position = 'absolute';
+        wrapper.style.left = container.bounds.left + 'px';
+        wrapper.style.top = container.bounds.top + 'px';
+        if (!allowLinebreak) {
+            wrapper.style.whiteSpace = 'nowrap';
+        }
+        var text = node.ownerDocument.createTextNode(value);
+        wrapper.appendChild(text);
+        body.appendChild(wrapper);
+        container.childNodes.push(_TextContainer2.default.fromTextNode(text, container));
+        body.removeChild(wrapper);
+    }
+};
+
+var getInputValue = function getInputValue(node) {
+    var value = node.type === 'password' ? new Array(node.value.length + 1).join('\u2022') : node.value;
+
+    return value.length === 0 ? node.placeholder || '' : value;
+};
+
+/***/ }),
+/* 22 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseTextBounds = exports.TextBounds = undefined;
+
+var _Bounds = __webpack_require__(2);
+
+var _textDecoration = __webpack_require__(11);
+
+var _Feature = __webpack_require__(10);
+
+var _Feature2 = _interopRequireDefault(_Feature);
+
+var _Unicode = __webpack_require__(24);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var TextBounds = exports.TextBounds = function TextBounds(text, bounds) {
+    _classCallCheck(this, TextBounds);
+
+    this.text = text;
+    this.bounds = bounds;
+};
+
+var parseTextBounds = exports.parseTextBounds = function parseTextBounds(value, parent, node) {
+    var letterRendering = parent.style.letterSpacing !== 0;
+    var textList = letterRendering ? (0, _Unicode.toCodePoints)(value).map(function (i) {
+        return (0, _Unicode.fromCodePoint)(i);
+    }) : (0, _Unicode.breakWords)(value, parent);
+    var length = textList.length;
+    var defaultView = node.parentNode ? node.parentNode.ownerDocument.defaultView : null;
+    var scrollX = defaultView ? defaultView.pageXOffset : 0;
+    var scrollY = defaultView ? defaultView.pageYOffset : 0;
+    var textBounds = [];
+    var offset = 0;
+    for (var i = 0; i < length; i++) {
+        var text = textList[i];
+        if (parent.style.textDecoration !== _textDecoration.TEXT_DECORATION.NONE || text.trim().length > 0) {
+            if (_Feature2.default.SUPPORT_RANGE_BOUNDS) {
+                textBounds.push(new TextBounds(text, getRangeBounds(node, offset, text.length, scrollX, scrollY)));
+            } else {
+                var replacementNode = node.splitText(text.length);
+                textBounds.push(new TextBounds(text, getWrapperBounds(node, scrollX, scrollY)));
+                node = replacementNode;
+            }
+        } else if (!_Feature2.default.SUPPORT_RANGE_BOUNDS) {
+            node = node.splitText(text.length);
+        }
+        offset += text.length;
+    }
+    return textBounds;
+};
+
+var getWrapperBounds = function getWrapperBounds(node, scrollX, scrollY) {
+    var wrapper = node.ownerDocument.createElement('html2canvaswrapper');
+    wrapper.appendChild(node.cloneNode(true));
+    var parentNode = node.parentNode;
+    if (parentNode) {
+        parentNode.replaceChild(wrapper, node);
+        var bounds = (0, _Bounds.parseBounds)(wrapper, scrollX, scrollY);
+        if (wrapper.firstChild) {
+            parentNode.replaceChild(wrapper.firstChild, wrapper);
+        }
+        return bounds;
+    }
+    return new _Bounds.Bounds(0, 0, 0, 0);
+};
+
+var getRangeBounds = function getRangeBounds(node, offset, length, scrollX, scrollY) {
+    var range = node.ownerDocument.createRange();
+    range.setStart(node, offset);
+    range.setEnd(node, offset + length);
+    return _Bounds.Bounds.fromClientRect(range.getBoundingClientRect(), scrollX, scrollY);
+};
+
+/***/ }),
+/* 23 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var ForeignObjectRenderer = function () {
+    function ForeignObjectRenderer(element) {
+        _classCallCheck(this, ForeignObjectRenderer);
+
+        this.element = element;
+    }
+
+    _createClass(ForeignObjectRenderer, [{
+        key: 'render',
+        value: function render(options) {
+            var _this = this;
+
+            this.options = options;
+            this.canvas = document.createElement('canvas');
+            this.ctx = this.canvas.getContext('2d');
+            this.canvas.width = Math.floor(options.width) * options.scale;
+            this.canvas.height = Math.floor(options.height) * options.scale;
+            this.canvas.style.width = options.width + 'px';
+            this.canvas.style.height = options.height + 'px';
+
+            options.logger.log('ForeignObject renderer initialized (' + options.width + 'x' + options.height + ' at ' + options.x + ',' + options.y + ') with scale ' + options.scale);
+            var svg = createForeignObjectSVG(Math.max(options.windowWidth, options.width) * options.scale, Math.max(options.windowHeight, options.height) * options.scale, options.scrollX * options.scale, options.scrollY * options.scale, this.element);
+
+            return loadSerializedSVG(svg).then(function (img) {
+                if (options.backgroundColor) {
+                    _this.ctx.fillStyle = options.backgroundColor.toString();
+                    _this.ctx.fillRect(0, 0, options.width * options.scale, options.height * options.scale);
+                }
+
+                _this.ctx.drawImage(img, -options.x * options.scale, -options.y * options.scale);
+                return _this.canvas;
+            });
+        }
+    }]);
+
+    return ForeignObjectRenderer;
+}();
+
+exports.default = ForeignObjectRenderer;
+var createForeignObjectSVG = exports.createForeignObjectSVG = function createForeignObjectSVG(width, height, x, y, node) {
+    var xmlns = 'http://www.w3.org/2000/svg';
+    var svg = document.createElementNS(xmlns, 'svg');
+    var foreignObject = document.createElementNS(xmlns, 'foreignObject');
+    svg.setAttributeNS(null, 'width', width);
+    svg.setAttributeNS(null, 'height', height);
+
+    foreignObject.setAttributeNS(null, 'width', '100%');
+    foreignObject.setAttributeNS(null, 'height', '100%');
+    foreignObject.setAttributeNS(null, 'x', x);
+    foreignObject.setAttributeNS(null, 'y', y);
+    foreignObject.setAttributeNS(null, 'externalResourcesRequired', 'true');
+    svg.appendChild(foreignObject);
+
+    foreignObject.appendChild(node);
+
+    return svg;
+};
+
+var loadSerializedSVG = exports.loadSerializedSVG = function loadSerializedSVG(svg) {
+    return new Promise(function (resolve, reject) {
+        var img = new Image();
+        img.onload = function () {
+            return resolve(img);
+        };
+        img.onerror = reject;
+
+        img.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(new XMLSerializer().serializeToString(svg));
+    });
+};
+
+/***/ }),
+/* 24 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.breakWords = exports.fromCodePoint = exports.toCodePoints = undefined;
+
+var _cssLineBreak = __webpack_require__(46);
+
+Object.defineProperty(exports, 'toCodePoints', {
+    enumerable: true,
+    get: function get() {
+        return _cssLineBreak.toCodePoints;
+    }
+});
+Object.defineProperty(exports, 'fromCodePoint', {
+    enumerable: true,
+    get: function get() {
+        return _cssLineBreak.fromCodePoint;
+    }
+});
+
+var _NodeContainer = __webpack_require__(3);
+
+var _NodeContainer2 = _interopRequireDefault(_NodeContainer);
+
+var _overflowWrap = __webpack_require__(18);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var breakWords = exports.breakWords = function breakWords(str, parent) {
+    var breaker = (0, _cssLineBreak.LineBreaker)(str, {
+        lineBreak: parent.style.lineBreak,
+        wordBreak: parent.style.overflowWrap === _overflowWrap.OVERFLOW_WRAP.BREAK_WORD ? 'break-word' : parent.style.wordBreak
+    });
+
+    var words = [];
+    var bk = void 0;
+
+    while (!(bk = breaker.next()).done) {
+        words.push(bk.value.slice());
+    }
+
+    return words;
+};
+
+/***/ }),
+/* 25 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.FontMetrics = undefined;
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Util = __webpack_require__(4);
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var SAMPLE_TEXT = 'Hidden Text';
+
+var FontMetrics = exports.FontMetrics = function () {
+    function FontMetrics(document) {
+        _classCallCheck(this, FontMetrics);
+
+        this._data = {};
+        this._document = document;
+    }
+
+    _createClass(FontMetrics, [{
+        key: '_parseMetrics',
+        value: function _parseMetrics(font) {
+            var container = this._document.createElement('div');
+            var img = this._document.createElement('img');
+            var span = this._document.createElement('span');
+
+            var body = this._document.body;
+            if (!body) {
+                throw new Error( true ? 'No document found for font metrics' : '');
+            }
+
+            container.style.visibility = 'hidden';
+            container.style.fontFamily = font.fontFamily;
+            container.style.fontSize = font.fontSize;
+            container.style.margin = '0';
+            container.style.padding = '0';
+
+            body.appendChild(container);
+
+            img.src = _Util.SMALL_IMAGE;
+            img.width = 1;
+            img.height = 1;
+
+            img.style.margin = '0';
+            img.style.padding = '0';
+            img.style.verticalAlign = 'baseline';
+
+            span.style.fontFamily = font.fontFamily;
+            span.style.fontSize = font.fontSize;
+            span.style.margin = '0';
+            span.style.padding = '0';
+
+            span.appendChild(this._document.createTextNode(SAMPLE_TEXT));
+            container.appendChild(span);
+            container.appendChild(img);
+            var baseline = img.offsetTop - span.offsetTop + 2;
+
+            container.removeChild(span);
+            container.appendChild(this._document.createTextNode(SAMPLE_TEXT));
+
+            container.style.lineHeight = 'normal';
+            img.style.verticalAlign = 'super';
+
+            var middle = img.offsetTop - container.offsetTop + 2;
+
+            body.removeChild(container);
+
+            return { baseline: baseline, middle: middle };
+        }
+    }, {
+        key: 'getMetrics',
+        value: function getMetrics(font) {
+            var key = font.fontFamily + ' ' + font.fontSize;
+            if (this._data[key] === undefined) {
+                this._data[key] = this._parseMetrics(font);
+            }
+
+            return this._data[key];
+        }
+    }]);
+
+    return FontMetrics;
+}();
+
+/***/ }),
+/* 26 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.Proxy = undefined;
+
+var _Feature = __webpack_require__(10);
+
+var _Feature2 = _interopRequireDefault(_Feature);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var Proxy = exports.Proxy = function Proxy(src, options) {
+    if (!options.proxy) {
+        return Promise.reject( true ? 'No proxy defined' : null);
+    }
+    var proxy = options.proxy;
+
+    return new Promise(function (resolve, reject) {
+        var responseType = _Feature2.default.SUPPORT_CORS_XHR && _Feature2.default.SUPPORT_RESPONSE_TYPE ? 'blob' : 'text';
+        var xhr = _Feature2.default.SUPPORT_CORS_XHR ? new XMLHttpRequest() : new XDomainRequest();
+        xhr.onload = function () {
+            if (xhr instanceof XMLHttpRequest) {
+                if (xhr.status === 200) {
+                    if (responseType === 'text') {
+                        resolve(xhr.response);
+                    } else {
+                        var reader = new FileReader();
+                        // $FlowFixMe
+                        reader.addEventListener('load', function () {
+                            return resolve(reader.result);
+                        }, false);
+                        // $FlowFixMe
+                        reader.addEventListener('error', function (e) {
+                            return reject(e);
+                        }, false);
+                        reader.readAsDataURL(xhr.response);
+                    }
+                } else {
+                    reject( true ? 'Failed to proxy resource ' + src.substring(0, 256) + ' with status code ' + xhr.status : '');
+                }
+            } else {
+                resolve(xhr.responseText);
+            }
+        };
+
+        xhr.onerror = reject;
+        xhr.open('GET', proxy + '?url=' + encodeURIComponent(src) + '&responseType=' + responseType);
+
+        if (responseType !== 'text' && xhr instanceof XMLHttpRequest) {
+            xhr.responseType = responseType;
+        }
+
+        if (options.imageTimeout) {
+            var timeout = options.imageTimeout;
+            xhr.timeout = timeout;
+            xhr.ontimeout = function () {
+                return reject( true ? 'Timed out (' + timeout + 'ms) proxying ' + src.substring(0, 256) : '');
+            };
+        }
+
+        xhr.send();
+    });
+};
+
+/***/ }),
+/* 27 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+var _CanvasRenderer = __webpack_require__(15);
+
+var _CanvasRenderer2 = _interopRequireDefault(_CanvasRenderer);
+
+var _Logger = __webpack_require__(16);
+
+var _Logger2 = _interopRequireDefault(_Logger);
+
+var _Window = __webpack_require__(28);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var html2canvas = function html2canvas(element, conf) {
+    var config = conf || {};
+    var logger = new _Logger2.default(typeof config.logging === 'boolean' ? config.logging : true);
+    logger.log('html2canvas ' + "1.0.0-alpha.12");
+
+    if (true && typeof config.onrendered === 'function') {
+        logger.error('onrendered option is deprecated, html2canvas returns a Promise with the canvas as the value');
+    }
+
+    var ownerDocument = element.ownerDocument;
+    if (!ownerDocument) {
+        return Promise.reject('Provided element is not within a Document');
+    }
+    var defaultView = ownerDocument.defaultView;
+
+    var defaultOptions = {
+        async: true,
+        allowTaint: false,
+        backgroundColor: '#ffffff',
+        imageTimeout: 15000,
+        logging: true,
+        proxy: null,
+        removeContainer: true,
+        foreignObjectRendering: false,
+        scale: defaultView.devicePixelRatio || 1,
+        target: new _CanvasRenderer2.default(config.canvas),
+        useCORS: false,
+        windowWidth: defaultView.innerWidth,
+        windowHeight: defaultView.innerHeight,
+        scrollX: defaultView.pageXOffset,
+        scrollY: defaultView.pageYOffset
+    };
+
+    var result = (0, _Window.renderElement)(element, _extends({}, defaultOptions, config), logger);
+
+    if (true) {
+        return result.catch(function (e) {
+            logger.error(e);
+            throw e;
+        });
+    }
+    return result;
+};
+
+html2canvas.CanvasRenderer = _CanvasRenderer2.default;
+
+module.exports = html2canvas;
+
+/***/ }),
+/* 28 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.renderElement = undefined;
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var _Logger = __webpack_require__(16);
+
+var _Logger2 = _interopRequireDefault(_Logger);
+
+var _NodeParser = __webpack_require__(29);
+
+var _Renderer = __webpack_require__(51);
+
+var _Renderer2 = _interopRequireDefault(_Renderer);
+
+var _ForeignObjectRenderer = __webpack_require__(23);
+
+var _ForeignObjectRenderer2 = _interopRequireDefault(_ForeignObjectRenderer);
+
+var _Feature = __webpack_require__(10);
+
+var _Feature2 = _interopRequireDefault(_Feature);
+
+var _Bounds = __webpack_require__(2);
+
+var _Clone = __webpack_require__(54);
+
+var _Font = __webpack_require__(25);
+
+var _Color = __webpack_require__(0);
+
+var _Color2 = _interopRequireDefault(_Color);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var renderElement = exports.renderElement = function renderElement(element, options, logger) {
+    var ownerDocument = element.ownerDocument;
+
+    var windowBounds = new _Bounds.Bounds(options.scrollX, options.scrollY, options.windowWidth, options.windowHeight);
+
+    // http://www.w3.org/TR/css3-background/#special-backgrounds
+    var documentBackgroundColor = ownerDocument.documentElement ? new _Color2.default(getComputedStyle(ownerDocument.documentElement).backgroundColor) : _Color.TRANSPARENT;
+    var bodyBackgroundColor = ownerDocument.body ? new _Color2.default(getComputedStyle(ownerDocument.body).backgroundColor) : _Color.TRANSPARENT;
+
+    var backgroundColor = element === ownerDocument.documentElement ? documentBackgroundColor.isTransparent() ? bodyBackgroundColor.isTransparent() ? options.backgroundColor ? new _Color2.default(options.backgroundColor) : null : bodyBackgroundColor : documentBackgroundColor : options.backgroundColor ? new _Color2.default(options.backgroundColor) : null;
+
+    return (options.foreignObjectRendering ? // $FlowFixMe
+    _Feature2.default.SUPPORT_FOREIGNOBJECT_DRAWING : Promise.resolve(false)).then(function (supportForeignObject) {
+        return supportForeignObject ? function (cloner) {
+            if (true) {
+                logger.log('Document cloned, using foreignObject rendering');
+            }
+
+            return cloner.inlineFonts(ownerDocument).then(function () {
+                return cloner.resourceLoader.ready();
+            }).then(function () {
+                var renderer = new _ForeignObjectRenderer2.default(cloner.documentElement);
+
+                var defaultView = ownerDocument.defaultView;
+                var scrollX = defaultView.pageXOffset;
+                var scrollY = defaultView.pageYOffset;
+
+                var isDocument = element.tagName === 'HTML' || element.tagName === 'BODY';
+
+                var _ref = isDocument ? (0, _Bounds.parseDocumentSize)(ownerDocument) : (0, _Bounds.parseBounds)(element, scrollX, scrollY),
+                    width = _ref.width,
+                    height = _ref.height,
+                    left = _ref.left,
+                    top = _ref.top;
+
+                return renderer.render({
+                    backgroundColor: backgroundColor,
+                    logger: logger,
+                    scale: options.scale,
+                    x: typeof options.x === 'number' ? options.x : left,
+                    y: typeof options.y === 'number' ? options.y : top,
+                    width: typeof options.width === 'number' ? options.width : Math.ceil(width),
+                    height: typeof options.height === 'number' ? options.height : Math.ceil(height),
+                    windowWidth: options.windowWidth,
+                    windowHeight: options.windowHeight,
+                    scrollX: options.scrollX,
+                    scrollY: options.scrollY
+                });
+            });
+        }(new _Clone.DocumentCloner(element, options, logger, true, renderElement)) : (0, _Clone.cloneWindow)(ownerDocument, windowBounds, element, options, logger, renderElement).then(function (_ref2) {
+            var _ref3 = _slicedToArray(_ref2, 3),
+                container = _ref3[0],
+                clonedElement = _ref3[1],
+                resourceLoader = _ref3[2];
+
+            if (true) {
+                logger.log('Document cloned, using computed rendering');
+            }
+
+            var stack = (0, _NodeParser.NodeParser)(clonedElement, resourceLoader, logger);
+            var clonedDocument = clonedElement.ownerDocument;
+
+            if (backgroundColor === stack.container.style.background.backgroundColor) {
+                stack.container.style.background.backgroundColor = _Color.TRANSPARENT;
+            }
+
+            return resourceLoader.ready().then(function (imageStore) {
+                var fontMetrics = new _Font.FontMetrics(clonedDocument);
+                if (true) {
+                    logger.log('Starting renderer');
+                }
+
+                var defaultView = clonedDocument.defaultView;
+                var scrollX = defaultView.pageXOffset;
+                var scrollY = defaultView.pageYOffset;
+
+                var isDocument = clonedElement.tagName === 'HTML' || clonedElement.tagName === 'BODY';
+
+                var _ref4 = isDocument ? (0, _Bounds.parseDocumentSize)(ownerDocument) : (0, _Bounds.parseBounds)(clonedElement, scrollX, scrollY),
+                    width = _ref4.width,
+                    height = _ref4.height,
+                    left = _ref4.left,
+                    top = _ref4.top;
+
+                var renderOptions = {
+                    backgroundColor: backgroundColor,
+                    fontMetrics: fontMetrics,
+                    imageStore: imageStore,
+                    logger: logger,
+                    scale: options.scale,
+                    x: typeof options.x === 'number' ? options.x : left,
+                    y: typeof options.y === 'number' ? options.y : top,
+                    width: typeof options.width === 'number' ? options.width : Math.ceil(width),
+                    height: typeof options.height === 'number' ? options.height : Math.ceil(height)
+                };
+
+                if (Array.isArray(options.target)) {
+                    return Promise.all(options.target.map(function (target) {
+                        var renderer = new _Renderer2.default(target, renderOptions);
+                        return renderer.render(stack);
+                    }));
+                } else {
+                    var renderer = new _Renderer2.default(options.target, renderOptions);
+                    var canvas = renderer.render(stack);
+                    if (options.removeContainer === true) {
+                        if (container.parentNode) {
+                            container.parentNode.removeChild(container);
+                        } else if (true) {
+                            logger.log('Cannot detach cloned iframe as it is not in the DOM anymore');
+                        }
+                    }
+
+                    return canvas;
+                }
+            });
+        });
+    });
+};
+
+/***/ }),
+/* 29 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.NodeParser = undefined;
+
+var _StackingContext = __webpack_require__(30);
+
+var _StackingContext2 = _interopRequireDefault(_StackingContext);
+
+var _NodeContainer = __webpack_require__(3);
+
+var _NodeContainer2 = _interopRequireDefault(_NodeContainer);
+
+var _TextContainer = __webpack_require__(9);
+
+var _TextContainer2 = _interopRequireDefault(_TextContainer);
+
+var _Input = __webpack_require__(21);
+
+var _ListItem = __webpack_require__(14);
+
+var _listStyle = __webpack_require__(8);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var NodeParser = exports.NodeParser = function NodeParser(node, resourceLoader, logger) {
+    if (true) {
+        logger.log('Starting node parsing');
+    }
+
+    var index = 0;
+
+    var container = new _NodeContainer2.default(node, null, resourceLoader, index++);
+    var stack = new _StackingContext2.default(container, null, true);
+
+    parseNodeTree(node, container, stack, resourceLoader, index);
+
+    if (true) {
+        logger.log('Finished parsing node tree');
+    }
+
+    return stack;
+};
+
+var IGNORED_NODE_NAMES = ['SCRIPT', 'HEAD', 'TITLE', 'OBJECT', 'BR', 'OPTION'];
+
+var parseNodeTree = function parseNodeTree(node, parent, stack, resourceLoader, index) {
+    if (true && index > 50000) {
+        throw new Error('Recursion error while parsing node tree');
+    }
+
+    for (var childNode = node.firstChild, nextNode; childNode; childNode = nextNode) {
+        nextNode = childNode.nextSibling;
+        var defaultView = childNode.ownerDocument.defaultView;
+        if (childNode instanceof defaultView.Text || childNode instanceof Text || defaultView.parent && childNode instanceof defaultView.parent.Text) {
+            if (childNode.data.trim().length > 0) {
+                parent.childNodes.push(_TextContainer2.default.fromTextNode(childNode, parent));
+            }
+        } else if (childNode instanceof defaultView.HTMLElement || childNode instanceof HTMLElement || defaultView.parent && childNode instanceof defaultView.parent.HTMLElement) {
+            if (IGNORED_NODE_NAMES.indexOf(childNode.nodeName) === -1) {
+                var container = new _NodeContainer2.default(childNode, parent, resourceLoader, index++);
+                if (container.isVisible()) {
+                    if (childNode.tagName === 'INPUT') {
+                        // $FlowFixMe
+                        (0, _Input.inlineInputElement)(childNode, container);
+                    } else if (childNode.tagName === 'TEXTAREA') {
+                        // $FlowFixMe
+                        (0, _Input.inlineTextAreaElement)(childNode, container);
+                    } else if (childNode.tagName === 'SELECT') {
+                        // $FlowFixMe
+                        (0, _Input.inlineSelectElement)(childNode, container);
+                    } else if (container.style.listStyle && container.style.listStyle.listStyleType !== _listStyle.LIST_STYLE_TYPE.NONE) {
+                        (0, _ListItem.inlineListItemElement)(childNode, container, resourceLoader);
+                    }
+
+                    var SHOULD_TRAVERSE_CHILDREN = childNode.tagName !== 'TEXTAREA';
+                    var treatAsRealStackingContext = createsRealStackingContext(container, childNode);
+                    if (treatAsRealStackingContext || createsStackingContext(container)) {
+                        // for treatAsRealStackingContext:false, any positioned descendants and descendants
+                        // which actually create a new stacking context should be considered part of the parent stacking context
+                        var parentStack = treatAsRealStackingContext || container.isPositioned() ? stack.getRealParentStackingContext() : stack;
+                        var childStack = new _StackingContext2.default(container, parentStack, treatAsRealStackingContext);
+                        parentStack.contexts.push(childStack);
+                        if (SHOULD_TRAVERSE_CHILDREN) {
+                            parseNodeTree(childNode, container, childStack, resourceLoader, index);
+                        }
+                    } else {
+                        stack.children.push(container);
+                        if (SHOULD_TRAVERSE_CHILDREN) {
+                            parseNodeTree(childNode, container, stack, resourceLoader, index);
+                        }
+                    }
+                }
+            }
+        } else if (childNode instanceof defaultView.SVGSVGElement || childNode instanceof SVGSVGElement || defaultView.parent && childNode instanceof defaultView.parent.SVGSVGElement) {
+            var _container = new _NodeContainer2.default(childNode, parent, resourceLoader, index++);
+            var _treatAsRealStackingContext = createsRealStackingContext(_container, childNode);
+            if (_treatAsRealStackingContext || createsStackingContext(_container)) {
+                // for treatAsRealStackingContext:false, any positioned descendants and descendants
+                // which actually create a new stacking context should be considered part of the parent stacking context
+                var _parentStack = _treatAsRealStackingContext || _container.isPositioned() ? stack.getRealParentStackingContext() : stack;
+                var _childStack = new _StackingContext2.default(_container, _parentStack, _treatAsRealStackingContext);
+                _parentStack.contexts.push(_childStack);
+            } else {
+                stack.children.push(_container);
+            }
+        }
+    }
+};
+
+var createsRealStackingContext = function createsRealStackingContext(container, node) {
+    return container.isRootElement() || container.isPositionedWithZIndex() || container.style.opacity < 1 || container.isTransformed() || isBodyWithTransparentRoot(container, node);
+};
+
+var createsStackingContext = function createsStackingContext(container) {
+    return container.isPositioned() || container.isFloating();
+};
+
+var isBodyWithTransparentRoot = function isBodyWithTransparentRoot(container, node) {
+    return node.nodeName === 'BODY' && container.parent instanceof _NodeContainer2.default && container.parent.style.background.backgroundColor.isTransparent();
+};
+
+/***/ }),
+/* 30 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _NodeContainer = __webpack_require__(3);
+
+var _NodeContainer2 = _interopRequireDefault(_NodeContainer);
+
+var _position = __webpack_require__(19);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var StackingContext = function () {
+    function StackingContext(container, parent, treatAsRealStackingContext) {
+        _classCallCheck(this, StackingContext);
+
+        this.container = container;
+        this.parent = parent;
+        this.contexts = [];
+        this.children = [];
+        this.treatAsRealStackingContext = treatAsRealStackingContext;
+    }
+
+    _createClass(StackingContext, [{
+        key: 'getOpacity',
+        value: function getOpacity() {
+            return this.parent ? this.container.style.opacity * this.parent.getOpacity() : this.container.style.opacity;
+        }
+    }, {
+        key: 'getRealParentStackingContext',
+        value: function getRealParentStackingContext() {
+            return !this.parent || this.treatAsRealStackingContext ? this : this.parent.getRealParentStackingContext();
+        }
+    }]);
+
+    return StackingContext;
+}();
+
+exports.default = StackingContext;
+
+/***/ }),
+/* 31 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Size = function Size(width, height) {
+    _classCallCheck(this, Size);
+
+    this.width = width;
+    this.height = height;
+};
+
+exports.default = Size;
+
+/***/ }),
+/* 32 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Path = __webpack_require__(6);
+
+var _Vector = __webpack_require__(7);
+
+var _Vector2 = _interopRequireDefault(_Vector);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var lerp = function lerp(a, b, t) {
+    return new _Vector2.default(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t);
+};
+
+var BezierCurve = function () {
+    function BezierCurve(start, startControl, endControl, end) {
+        _classCallCheck(this, BezierCurve);
+
+        this.type = _Path.PATH.BEZIER_CURVE;
+        this.start = start;
+        this.startControl = startControl;
+        this.endControl = endControl;
+        this.end = end;
+    }
+
+    _createClass(BezierCurve, [{
+        key: 'subdivide',
+        value: function subdivide(t, firstHalf) {
+            var ab = lerp(this.start, this.startControl, t);
+            var bc = lerp(this.startControl, this.endControl, t);
+            var cd = lerp(this.endControl, this.end, t);
+            var abbc = lerp(ab, bc, t);
+            var bccd = lerp(bc, cd, t);
+            var dest = lerp(abbc, bccd, t);
+            return firstHalf ? new BezierCurve(this.start, ab, abbc, dest) : new BezierCurve(dest, bccd, cd, this.end);
+        }
+    }, {
+        key: 'reverse',
+        value: function reverse() {
+            return new BezierCurve(this.end, this.endControl, this.startControl, this.start);
+        }
+    }]);
+
+    return BezierCurve;
+}();
+
+exports.default = BezierCurve;
+
+/***/ }),
+/* 33 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseBorderRadius = undefined;
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var _Length = __webpack_require__(1);
+
+var _Length2 = _interopRequireDefault(_Length);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var SIDES = ['top-left', 'top-right', 'bottom-right', 'bottom-left'];
+
+var parseBorderRadius = exports.parseBorderRadius = function parseBorderRadius(style) {
+    return SIDES.map(function (side) {
+        var value = style.getPropertyValue('border-' + side + '-radius');
+
+        var _value$split$map = value.split(' ').map(_Length2.default.create),
+            _value$split$map2 = _slicedToArray(_value$split$map, 2),
+            horizontal = _value$split$map2[0],
+            vertical = _value$split$map2[1];
+
+        return typeof vertical === 'undefined' ? [horizontal, horizontal] : [horizontal, vertical];
+    });
+};
+
+/***/ }),
+/* 34 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var DISPLAY = exports.DISPLAY = {
+    NONE: 1 << 0,
+    BLOCK: 1 << 1,
+    INLINE: 1 << 2,
+    RUN_IN: 1 << 3,
+    FLOW: 1 << 4,
+    FLOW_ROOT: 1 << 5,
+    TABLE: 1 << 6,
+    FLEX: 1 << 7,
+    GRID: 1 << 8,
+    RUBY: 1 << 9,
+    SUBGRID: 1 << 10,
+    LIST_ITEM: 1 << 11,
+    TABLE_ROW_GROUP: 1 << 12,
+    TABLE_HEADER_GROUP: 1 << 13,
+    TABLE_FOOTER_GROUP: 1 << 14,
+    TABLE_ROW: 1 << 15,
+    TABLE_CELL: 1 << 16,
+    TABLE_COLUMN_GROUP: 1 << 17,
+    TABLE_COLUMN: 1 << 18,
+    TABLE_CAPTION: 1 << 19,
+    RUBY_BASE: 1 << 20,
+    RUBY_TEXT: 1 << 21,
+    RUBY_BASE_CONTAINER: 1 << 22,
+    RUBY_TEXT_CONTAINER: 1 << 23,
+    CONTENTS: 1 << 24,
+    INLINE_BLOCK: 1 << 25,
+    INLINE_LIST_ITEM: 1 << 26,
+    INLINE_TABLE: 1 << 27,
+    INLINE_FLEX: 1 << 28,
+    INLINE_GRID: 1 << 29
+};
+
+var parseDisplayValue = function parseDisplayValue(display) {
+    switch (display) {
+        case 'block':
+            return DISPLAY.BLOCK;
+        case 'inline':
+            return DISPLAY.INLINE;
+        case 'run-in':
+            return DISPLAY.RUN_IN;
+        case 'flow':
+            return DISPLAY.FLOW;
+        case 'flow-root':
+            return DISPLAY.FLOW_ROOT;
+        case 'table':
+            return DISPLAY.TABLE;
+        case 'flex':
+            return DISPLAY.FLEX;
+        case 'grid':
+            return DISPLAY.GRID;
+        case 'ruby':
+            return DISPLAY.RUBY;
+        case 'subgrid':
+            return DISPLAY.SUBGRID;
+        case 'list-item':
+            return DISPLAY.LIST_ITEM;
+        case 'table-row-group':
+            return DISPLAY.TABLE_ROW_GROUP;
+        case 'table-header-group':
+            return DISPLAY.TABLE_HEADER_GROUP;
+        case 'table-footer-group':
+            return DISPLAY.TABLE_FOOTER_GROUP;
+        case 'table-row':
+            return DISPLAY.TABLE_ROW;
+        case 'table-cell':
+            return DISPLAY.TABLE_CELL;
+        case 'table-column-group':
+            return DISPLAY.TABLE_COLUMN_GROUP;
+        case 'table-column':
+            return DISPLAY.TABLE_COLUMN;
+        case 'table-caption':
+            return DISPLAY.TABLE_CAPTION;
+        case 'ruby-base':
+            return DISPLAY.RUBY_BASE;
+        case 'ruby-text':
+            return DISPLAY.RUBY_TEXT;
+        case 'ruby-base-container':
+            return DISPLAY.RUBY_BASE_CONTAINER;
+        case 'ruby-text-container':
+            return DISPLAY.RUBY_TEXT_CONTAINER;
+        case 'contents':
+            return DISPLAY.CONTENTS;
+        case 'inline-block':
+            return DISPLAY.INLINE_BLOCK;
+        case 'inline-list-item':
+            return DISPLAY.INLINE_LIST_ITEM;
+        case 'inline-table':
+            return DISPLAY.INLINE_TABLE;
+        case 'inline-flex':
+            return DISPLAY.INLINE_FLEX;
+        case 'inline-grid':
+            return DISPLAY.INLINE_GRID;
+    }
+
+    return DISPLAY.NONE;
+};
+
+var setDisplayBit = function setDisplayBit(bit, display) {
+    return bit | parseDisplayValue(display);
+};
+
+var parseDisplay = exports.parseDisplay = function parseDisplay(display) {
+    return display.split(' ').reduce(setDisplayBit, 0);
+};
+
+/***/ }),
+/* 35 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var FLOAT = exports.FLOAT = {
+    NONE: 0,
+    LEFT: 1,
+    RIGHT: 2,
+    INLINE_START: 3,
+    INLINE_END: 4
+};
+
+var parseCSSFloat = exports.parseCSSFloat = function parseCSSFloat(float) {
+    switch (float) {
+        case 'left':
+            return FLOAT.LEFT;
+        case 'right':
+            return FLOAT.RIGHT;
+        case 'inline-start':
+            return FLOAT.INLINE_START;
+        case 'inline-end':
+            return FLOAT.INLINE_END;
+    }
+    return FLOAT.NONE;
+};
+
+/***/ }),
+/* 36 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+
+var parseFontWeight = function parseFontWeight(weight) {
+    switch (weight) {
+        case 'normal':
+            return 400;
+        case 'bold':
+            return 700;
+    }
+
+    var value = parseInt(weight, 10);
+    return isNaN(value) ? 400 : value;
+};
+
+var parseFont = exports.parseFont = function parseFont(style) {
+    var fontFamily = style.fontFamily;
+    var fontSize = style.fontSize;
+    var fontStyle = style.fontStyle;
+    var fontVariant = style.fontVariant;
+    var fontWeight = parseFontWeight(style.fontWeight);
+
+    return {
+        fontFamily: fontFamily,
+        fontSize: fontSize,
+        fontStyle: fontStyle,
+        fontVariant: fontVariant,
+        fontWeight: fontWeight
+    };
+};
+
+/***/ }),
+/* 37 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var parseLetterSpacing = exports.parseLetterSpacing = function parseLetterSpacing(letterSpacing) {
+    if (letterSpacing === 'normal') {
+        return 0;
+    }
+    var value = parseFloat(letterSpacing);
+    return isNaN(value) ? 0 : value;
+};
+
+/***/ }),
+/* 38 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var LINE_BREAK = exports.LINE_BREAK = {
+    NORMAL: 'normal',
+    STRICT: 'strict'
+};
+
+var parseLineBreak = exports.parseLineBreak = function parseLineBreak(wordBreak) {
+    switch (wordBreak) {
+        case 'strict':
+            return LINE_BREAK.STRICT;
+        case 'normal':
+        default:
+            return LINE_BREAK.NORMAL;
+    }
+};
+
+/***/ }),
+/* 39 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseMargin = undefined;
+
+var _Length = __webpack_require__(1);
+
+var _Length2 = _interopRequireDefault(_Length);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var SIDES = ['top', 'right', 'bottom', 'left'];
+
+var parseMargin = exports.parseMargin = function parseMargin(style) {
+    return SIDES.map(function (side) {
+        return new _Length2.default(style.getPropertyValue('margin-' + side));
+    });
+};
+
+/***/ }),
+/* 40 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var OVERFLOW = exports.OVERFLOW = {
+    VISIBLE: 0,
+    HIDDEN: 1,
+    SCROLL: 2,
+    AUTO: 3
+};
+
+var parseOverflow = exports.parseOverflow = function parseOverflow(overflow) {
+    switch (overflow) {
+        case 'hidden':
+            return OVERFLOW.HIDDEN;
+        case 'scroll':
+            return OVERFLOW.SCROLL;
+        case 'auto':
+            return OVERFLOW.AUTO;
+        case 'visible':
+        default:
+            return OVERFLOW.VISIBLE;
+    }
+};
+
+/***/ }),
+/* 41 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseTextShadow = undefined;
+
+var _Color = __webpack_require__(0);
+
+var _Color2 = _interopRequireDefault(_Color);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var NUMBER = /^([+-]|\d|\.)$/i;
+
+var parseTextShadow = exports.parseTextShadow = function parseTextShadow(textShadow) {
+    if (textShadow === 'none' || typeof textShadow !== 'string') {
+        return null;
+    }
+
+    var currentValue = '';
+    var isLength = false;
+    var values = [];
+    var shadows = [];
+    var numParens = 0;
+    var color = null;
+
+    var appendValue = function appendValue() {
+        if (currentValue.length) {
+            if (isLength) {
+                values.push(parseFloat(currentValue));
+            } else {
+                color = new _Color2.default(currentValue);
+            }
+        }
+        isLength = false;
+        currentValue = '';
+    };
+
+    var appendShadow = function appendShadow() {
+        if (values.length && color !== null) {
+            shadows.push({
+                color: color,
+                offsetX: values[0] || 0,
+                offsetY: values[1] || 0,
+                blur: values[2] || 0
+            });
+        }
+        values.splice(0, values.length);
+        color = null;
+    };
+
+    for (var i = 0; i < textShadow.length; i++) {
+        var c = textShadow[i];
+        switch (c) {
+            case '(':
+                currentValue += c;
+                numParens++;
+                break;
+            case ')':
+                currentValue += c;
+                numParens--;
+                break;
+            case ',':
+                if (numParens === 0) {
+                    appendValue();
+                    appendShadow();
+                } else {
+                    currentValue += c;
+                }
+                break;
+            case ' ':
+                if (numParens === 0) {
+                    appendValue();
+                } else {
+                    currentValue += c;
+                }
+                break;
+            default:
+                if (currentValue.length === 0 && NUMBER.test(c)) {
+                    isLength = true;
+                }
+                currentValue += c;
+        }
+    }
+
+    appendValue();
+    appendShadow();
+
+    if (shadows.length === 0) {
+        return null;
+    }
+
+    return shadows;
+};
+
+/***/ }),
+/* 42 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseTransform = undefined;
+
+var _Length = __webpack_require__(1);
+
+var _Length2 = _interopRequireDefault(_Length);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var toFloat = function toFloat(s) {
+    return parseFloat(s.trim());
+};
+
+var MATRIX = /(matrix|matrix3d)\((.+)\)/;
+
+var parseTransform = exports.parseTransform = function parseTransform(style) {
+    var transform = parseTransformMatrix(style.transform || style.webkitTransform || style.mozTransform ||
+    // $FlowFixMe
+    style.msTransform ||
+    // $FlowFixMe
+    style.oTransform);
+    if (transform === null) {
+        return null;
+    }
+
+    return {
+        transform: transform,
+        transformOrigin: parseTransformOrigin(style.transformOrigin || style.webkitTransformOrigin || style.mozTransformOrigin ||
+        // $FlowFixMe
+        style.msTransformOrigin ||
+        // $FlowFixMe
+        style.oTransformOrigin)
+    };
+};
+
+// $FlowFixMe
+var parseTransformOrigin = function parseTransformOrigin(origin) {
+    if (typeof origin !== 'string') {
+        var v = new _Length2.default('0');
+        return [v, v];
+    }
+    var values = origin.split(' ').map(_Length2.default.create);
+    return [values[0], values[1]];
+};
+
+// $FlowFixMe
+var parseTransformMatrix = function parseTransformMatrix(transform) {
+    if (transform === 'none' || typeof transform !== 'string') {
+        return null;
+    }
+
+    var match = transform.match(MATRIX);
+    if (match) {
+        if (match[1] === 'matrix') {
+            var matrix = match[2].split(',').map(toFloat);
+            return [matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]];
+        } else {
+            var matrix3d = match[2].split(',').map(toFloat);
+            return [matrix3d[0], matrix3d[1], matrix3d[4], matrix3d[5], matrix3d[12], matrix3d[13]];
+        }
+    }
+    return null;
+};
+
+/***/ }),
+/* 43 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var VISIBILITY = exports.VISIBILITY = {
+    VISIBLE: 0,
+    HIDDEN: 1,
+    COLLAPSE: 2
+};
+
+var parseVisibility = exports.parseVisibility = function parseVisibility(visibility) {
+    switch (visibility) {
+        case 'hidden':
+            return VISIBILITY.HIDDEN;
+        case 'collapse':
+            return VISIBILITY.COLLAPSE;
+        case 'visible':
+        default:
+            return VISIBILITY.VISIBLE;
+    }
+};
+
+/***/ }),
+/* 44 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var WORD_BREAK = exports.WORD_BREAK = {
+    NORMAL: 'normal',
+    BREAK_ALL: 'break-all',
+    KEEP_ALL: 'keep-all'
+};
+
+var parseWordBreak = exports.parseWordBreak = function parseWordBreak(wordBreak) {
+    switch (wordBreak) {
+        case 'break-all':
+            return WORD_BREAK.BREAK_ALL;
+        case 'keep-all':
+            return WORD_BREAK.KEEP_ALL;
+        case 'normal':
+        default:
+            return WORD_BREAK.NORMAL;
+    }
+};
+
+/***/ }),
+/* 45 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var parseZIndex = exports.parseZIndex = function parseZIndex(zIndex) {
+    var auto = zIndex === 'auto';
+    return {
+        auto: auto,
+        order: auto ? 0 : parseInt(zIndex, 10)
+    };
+};
+
+/***/ }),
+/* 46 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _Util = __webpack_require__(13);
+
+Object.defineProperty(exports, 'toCodePoints', {
+  enumerable: true,
+  get: function get() {
+    return _Util.toCodePoints;
+  }
+});
+Object.defineProperty(exports, 'fromCodePoint', {
+  enumerable: true,
+  get: function get() {
+    return _Util.fromCodePoint;
+  }
+});
+
+var _LineBreak = __webpack_require__(47);
+
+Object.defineProperty(exports, 'LineBreaker', {
+  enumerable: true,
+  get: function get() {
+    return _LineBreak.LineBreaker;
+  }
+});
+
+/***/ }),
+/* 47 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.LineBreaker = exports.inlineBreakOpportunities = exports.lineBreakAtIndex = exports.codePointsToCharacterClasses = exports.UnicodeTrie = exports.BREAK_ALLOWED = exports.BREAK_NOT_ALLOWED = exports.BREAK_MANDATORY = exports.classes = exports.LETTER_NUMBER_MODIFIER = undefined;
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var _Trie = __webpack_require__(48);
+
+var _linebreakTrie = __webpack_require__(49);
+
+var _linebreakTrie2 = _interopRequireDefault(_linebreakTrie);
+
+var _Util = __webpack_require__(13);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var LETTER_NUMBER_MODIFIER = exports.LETTER_NUMBER_MODIFIER = 50;
+
+// Non-tailorable Line Breaking Classes
+var BK = 1; //  Cause a line break (after)
+var CR = 2; //  Cause a line break (after), except between CR and LF
+var LF = 3; //  Cause a line break (after)
+var CM = 4; //  Prohibit a line break between the character and the preceding character
+var NL = 5; //  Cause a line break (after)
+var SG = 6; //  Do not occur in well-formed text
+var WJ = 7; //  Prohibit line breaks before and after
+var ZW = 8; //  Provide a break opportunity
+var GL = 9; //  Prohibit line breaks before and after
+var SP = 10; // Enable indirect line breaks
+var ZWJ = 11; // Prohibit line breaks within joiner sequences
+// Break Opportunities
+var B2 = 12; //  Provide a line break opportunity before and after the character
+var BA = 13; //  Generally provide a line break opportunity after the character
+var BB = 14; //  Generally provide a line break opportunity before the character
+var HY = 15; //  Provide a line break opportunity after the character, except in numeric context
+var CB = 16; //   Provide a line break opportunity contingent on additional information
+// Characters Prohibiting Certain Breaks
+var CL = 17; //  Prohibit line breaks before
+var CP = 18; //  Prohibit line breaks before
+var EX = 19; //  Prohibit line breaks before
+var IN = 20; //  Allow only indirect line breaks between pairs
+var NS = 21; //  Allow only indirect line breaks before
+var OP = 22; //  Prohibit line breaks after
+var QU = 23; //  Act like they are both opening and closing
+// Numeric Context
+var IS = 24; //  Prevent breaks after any and before numeric
+var NU = 25; //  Form numeric expressions for line breaking purposes
+var PO = 26; //  Do not break following a numeric expression
+var PR = 27; //  Do not break in front of a numeric expression
+var SY = 28; //  Prevent a break before; and allow a break after
+// Other Characters
+var AI = 29; //  Act like AL when the resolvedEAW is N; otherwise; act as ID
+var AL = 30; //  Are alphabetic characters or symbols that are used with alphabetic characters
+var CJ = 31; //  Treat as NS or ID for strict or normal breaking.
+var EB = 32; //  Do not break from following Emoji Modifier
+var EM = 33; //  Do not break from preceding Emoji Base
+var H2 = 34; //  Form Korean syllable blocks
+var H3 = 35; //  Form Korean syllable blocks
+var HL = 36; //  Do not break around a following hyphen; otherwise act as Alphabetic
+var ID = 37; //  Break before or after; except in some numeric context
+var JL = 38; //  Form Korean syllable blocks
+var JV = 39; //  Form Korean syllable blocks
+var JT = 40; //  Form Korean syllable blocks
+var RI = 41; //  Keep pairs together. For pairs; break before and after other classes
+var SA = 42; //  Provide a line break opportunity contingent on additional, language-specific context analysis
+var XX = 43; //  Have as yet unknown line breaking behavior or unassigned code positions
+
+var classes = exports.classes = {
+    BK: BK,
+    CR: CR,
+    LF: LF,
+    CM: CM,
+    NL: NL,
+    SG: SG,
+    WJ: WJ,
+    ZW: ZW,
+    GL: GL,
+    SP: SP,
+    ZWJ: ZWJ,
+    B2: B2,
+    BA: BA,
+    BB: BB,
+    HY: HY,
+    CB: CB,
+    CL: CL,
+    CP: CP,
+    EX: EX,
+    IN: IN,
+    NS: NS,
+    OP: OP,
+    QU: QU,
+    IS: IS,
+    NU: NU,
+    PO: PO,
+    PR: PR,
+    SY: SY,
+    AI: AI,
+    AL: AL,
+    CJ: CJ,
+    EB: EB,
+    EM: EM,
+    H2: H2,
+    H3: H3,
+    HL: HL,
+    ID: ID,
+    JL: JL,
+    JV: JV,
+    JT: JT,
+    RI: RI,
+    SA: SA,
+    XX: XX
+};
+
+var BREAK_MANDATORY = exports.BREAK_MANDATORY = '!';
+var BREAK_NOT_ALLOWED = exports.BREAK_NOT_ALLOWED = '×';
+var BREAK_ALLOWED = exports.BREAK_ALLOWED = '÷';
+var UnicodeTrie = exports.UnicodeTrie = (0, _Trie.createTrieFromBase64)(_linebreakTrie2.default);
+
+var ALPHABETICS = [AL, HL];
+var HARD_LINE_BREAKS = [BK, CR, LF, NL];
+var SPACE = [SP, ZW];
+var PREFIX_POSTFIX = [PR, PO];
+var LINE_BREAKS = HARD_LINE_BREAKS.concat(SPACE);
+var KOREAN_SYLLABLE_BLOCK = [JL, JV, JT, H2, H3];
+var HYPHEN = [HY, BA];
+
+var codePointsToCharacterClasses = exports.codePointsToCharacterClasses = function codePointsToCharacterClasses(codePoints) {
+    var lineBreak = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'strict';
+
+    var types = [];
+    var indicies = [];
+    var categories = [];
+    codePoints.forEach(function (codePoint, index) {
+        var classType = UnicodeTrie.get(codePoint);
+        if (classType > LETTER_NUMBER_MODIFIER) {
+            categories.push(true);
+            classType -= LETTER_NUMBER_MODIFIER;
+        } else {
+            categories.push(false);
+        }
+
+        if (['normal', 'auto', 'loose'].indexOf(lineBreak) !== -1) {
+            // U+2010, – U+2013, 〜 U+301C, ゠ U+30A0
+            if ([0x2010, 0x2013, 0x301c, 0x30a0].indexOf(codePoint) !== -1) {
+                indicies.push(index);
+                return types.push(CB);
+            }
+        }
+
+        if (classType === CM || classType === ZWJ) {
+            // LB10 Treat any remaining combining mark or ZWJ as AL.
+            if (index === 0) {
+                indicies.push(index);
+                return types.push(AL);
+            }
+
+            // LB9 Do not break a combining character sequence; treat it as if it has the line breaking class of
+            // the base character in all of the following rules. Treat ZWJ as if it were CM.
+            var prev = types[index - 1];
+            if (LINE_BREAKS.indexOf(prev) === -1) {
+                indicies.push(indicies[index - 1]);
+                return types.push(prev);
+            }
+            indicies.push(index);
+            return types.push(AL);
+        }
+
+        indicies.push(index);
+
+        if (classType === CJ) {
+            return types.push(lineBreak === 'strict' ? NS : ID);
+        }
+
+        if (classType === SA) {
+            return types.push(AL);
+        }
+
+        if (classType === AI) {
+            return types.push(AL);
+        }
+
+        // For supplementary characters, a useful default is to treat characters in the range 10000..1FFFD as AL
+        // and characters in the ranges 20000..2FFFD and 30000..3FFFD as ID, until the implementation can be revised
+        // to take into account the actual line breaking properties for these characters.
+        if (classType === XX) {
+            if (codePoint >= 0x20000 && codePoint <= 0x2fffd || codePoint >= 0x30000 && codePoint <= 0x3fffd) {
+                return types.push(ID);
+            } else {
+                return types.push(AL);
+            }
+        }
+
+        types.push(classType);
+    });
+
+    return [indicies, types, categories];
+};
+
+var isAdjacentWithSpaceIgnored = function isAdjacentWithSpaceIgnored(a, b, currentIndex, classTypes) {
+    var current = classTypes[currentIndex];
+    if (Array.isArray(a) ? a.indexOf(current) !== -1 : a === current) {
+        var i = currentIndex;
+        while (i <= classTypes.length) {
+            i++;
+            var next = classTypes[i];
+
+            if (next === b) {
+                return true;
+            }
+
+            if (next !== SP) {
+                break;
+            }
+        }
+    }
+
+    if (current === SP) {
+        var _i = currentIndex;
+
+        while (_i > 0) {
+            _i--;
+            var prev = classTypes[_i];
+
+            if (Array.isArray(a) ? a.indexOf(prev) !== -1 : a === prev) {
+                var n = currentIndex;
+                while (n <= classTypes.length) {
+                    n++;
+                    var _next = classTypes[n];
+
+                    if (_next === b) {
+                        return true;
+                    }
+
+                    if (_next !== SP) {
+                        break;
+                    }
+                }
+            }
+
+            if (prev !== SP) {
+                break;
+            }
+        }
+    }
+    return false;
+};
+
+var previousNonSpaceClassType = function previousNonSpaceClassType(currentIndex, classTypes) {
+    var i = currentIndex;
+    while (i >= 0) {
+        var type = classTypes[i];
+        if (type === SP) {
+            i--;
+        } else {
+            return type;
+        }
+    }
+    return 0;
+};
+
+var _lineBreakAtIndex = function _lineBreakAtIndex(codePoints, classTypes, indicies, index, forbiddenBreaks) {
+    if (indicies[index] === 0) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    var currentIndex = index - 1;
+    if (Array.isArray(forbiddenBreaks) && forbiddenBreaks[currentIndex] === true) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    var beforeIndex = currentIndex - 1;
+    var afterIndex = currentIndex + 1;
+    var current = classTypes[currentIndex];
+
+    // LB4 Always break after hard line breaks.
+    // LB5 Treat CR followed by LF, as well as CR, LF, and NL as hard line breaks.
+    var before = beforeIndex >= 0 ? classTypes[beforeIndex] : 0;
+    var next = classTypes[afterIndex];
+
+    if (current === CR && next === LF) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    if (HARD_LINE_BREAKS.indexOf(current) !== -1) {
+        return BREAK_MANDATORY;
+    }
+
+    // LB6 Do not break before hard line breaks.
+    if (HARD_LINE_BREAKS.indexOf(next) !== -1) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB7 Do not break before spaces or zero width space.
+    if (SPACE.indexOf(next) !== -1) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB8 Break before any character following a zero-width space, even if one or more spaces intervene.
+    if (previousNonSpaceClassType(currentIndex, classTypes) === ZW) {
+        return BREAK_ALLOWED;
+    }
+
+    // LB8a Do not break between a zero width joiner and an ideograph, emoji base or emoji modifier.
+    if (UnicodeTrie.get(codePoints[currentIndex]) === ZWJ && (next === ID || next === EB || next === EM)) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB11 Do not break before or after Word joiner and related characters.
+    if (current === WJ || next === WJ) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB12 Do not break after NBSP and related characters.
+    if (current === GL) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB12a Do not break before NBSP and related characters, except after spaces and hyphens.
+    if ([SP, BA, HY].indexOf(current) === -1 && next === GL) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB13 Do not break before ‘]’ or ‘!’ or ‘;’ or ‘/’, even after spaces.
+    if ([CL, CP, EX, IS, SY].indexOf(next) !== -1) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB14 Do not break after ‘[’, even after spaces.
+    if (previousNonSpaceClassType(currentIndex, classTypes) === OP) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB15 Do not break within ‘”[’, even with intervening spaces.
+    if (isAdjacentWithSpaceIgnored(QU, OP, currentIndex, classTypes)) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB16 Do not break between closing punctuation and a nonstarter (lb=NS), even with intervening spaces.
+    if (isAdjacentWithSpaceIgnored([CL, CP], NS, currentIndex, classTypes)) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB17 Do not break within ‘——’, even with intervening spaces.
+    if (isAdjacentWithSpaceIgnored(B2, B2, currentIndex, classTypes)) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB18 Break after spaces.
+    if (current === SP) {
+        return BREAK_ALLOWED;
+    }
+
+    // LB19 Do not break before or after quotation marks, such as ‘ ” ’.
+    if (current === QU || next === QU) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB20 Break before and after unresolved CB.
+    if (next === CB || current === CB) {
+        return BREAK_ALLOWED;
+    }
+
+    // LB21 Do not break before hyphen-minus, other hyphens, fixed-width spaces, small kana, and other non-starters, or after acute accents.
+    if ([BA, HY, NS].indexOf(next) !== -1 || current === BB) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB21a Don't break after Hebrew + Hyphen.
+    if (before === HL && HYPHEN.indexOf(current) !== -1) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB21b Don’t break between Solidus and Hebrew letters.
+    if (current === SY && next === HL) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB22 Do not break between two ellipses, or between letters, numbers or exclamations and ellipsis.
+    if (next === IN && ALPHABETICS.concat(IN, EX, NU, ID, EB, EM).indexOf(current) !== -1) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB23 Do not break between digits and letters.
+    if (ALPHABETICS.indexOf(next) !== -1 && current === NU || ALPHABETICS.indexOf(current) !== -1 && next === NU) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB23a Do not break between numeric prefixes and ideographs, or between ideographs and numeric postfixes.
+    if (current === PR && [ID, EB, EM].indexOf(next) !== -1 || [ID, EB, EM].indexOf(current) !== -1 && next === PO) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB24 Do not break between numeric prefix/postfix and letters, or between letters and prefix/postfix.
+    if (ALPHABETICS.indexOf(current) !== -1 && PREFIX_POSTFIX.indexOf(next) !== -1 || PREFIX_POSTFIX.indexOf(current) !== -1 && ALPHABETICS.indexOf(next) !== -1) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB25 Do not break between the following pairs of classes relevant to numbers:
+    if (
+    // (PR | PO) × ( OP | HY )? NU
+    [PR, PO].indexOf(current) !== -1 && (next === NU || [OP, HY].indexOf(next) !== -1 && classTypes[afterIndex + 1] === NU) ||
+    // ( OP | HY ) × NU
+    [OP, HY].indexOf(current) !== -1 && next === NU ||
+    // NU ×	(NU | SY | IS)
+    current === NU && [NU, SY, IS].indexOf(next) !== -1) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // NU (NU | SY | IS)* × (NU | SY | IS | CL | CP)
+    if ([NU, SY, IS, CL, CP].indexOf(next) !== -1) {
+        var prevIndex = currentIndex;
+        while (prevIndex >= 0) {
+            var type = classTypes[prevIndex];
+            if (type === NU) {
+                return BREAK_NOT_ALLOWED;
+            } else if ([SY, IS].indexOf(type) !== -1) {
+                prevIndex--;
+            } else {
+                break;
+            }
+        }
+    }
+
+    // NU (NU | SY | IS)* (CL | CP)? × (PO | PR))
+    if ([PR, PO].indexOf(next) !== -1) {
+        var _prevIndex = [CL, CP].indexOf(current) !== -1 ? beforeIndex : currentIndex;
+        while (_prevIndex >= 0) {
+            var _type = classTypes[_prevIndex];
+            if (_type === NU) {
+                return BREAK_NOT_ALLOWED;
+            } else if ([SY, IS].indexOf(_type) !== -1) {
+                _prevIndex--;
+            } else {
+                break;
+            }
+        }
+    }
+
+    // LB26 Do not break a Korean syllable.
+    if (JL === current && [JL, JV, H2, H3].indexOf(next) !== -1 || [JV, H2].indexOf(current) !== -1 && [JV, JT].indexOf(next) !== -1 || [JT, H3].indexOf(current) !== -1 && next === JT) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB27 Treat a Korean Syllable Block the same as ID.
+    if (KOREAN_SYLLABLE_BLOCK.indexOf(current) !== -1 && [IN, PO].indexOf(next) !== -1 || KOREAN_SYLLABLE_BLOCK.indexOf(next) !== -1 && current === PR) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB28 Do not break between alphabetics (“at”).
+    if (ALPHABETICS.indexOf(current) !== -1 && ALPHABETICS.indexOf(next) !== -1) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB29 Do not break between numeric punctuation and alphabetics (“e.g.”).
+    if (current === IS && ALPHABETICS.indexOf(next) !== -1) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB30 Do not break between letters, numbers, or ordinary symbols and opening or closing parentheses.
+    if (ALPHABETICS.concat(NU).indexOf(current) !== -1 && next === OP || ALPHABETICS.concat(NU).indexOf(next) !== -1 && current === CP) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB30a Break between two regional indicator symbols if and only if there are an even number of regional
+    // indicators preceding the position of the break.
+    if (current === RI && next === RI) {
+        var i = indicies[currentIndex];
+        var count = 1;
+        while (i > 0) {
+            i--;
+            if (classTypes[i] === RI) {
+                count++;
+            } else {
+                break;
+            }
+        }
+        if (count % 2 !== 0) {
+            return BREAK_NOT_ALLOWED;
+        }
+    }
+
+    // LB30b Do not break between an emoji base and an emoji modifier.
+    if (current === EB && next === EM) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    return BREAK_ALLOWED;
+};
+
+var lineBreakAtIndex = exports.lineBreakAtIndex = function lineBreakAtIndex(codePoints, index) {
+    // LB2 Never break at the start of text.
+    if (index === 0) {
+        return BREAK_NOT_ALLOWED;
+    }
+
+    // LB3 Always break at the end of text.
+    if (index >= codePoints.length) {
+        return BREAK_MANDATORY;
+    }
+
+    var _codePointsToCharacte = codePointsToCharacterClasses(codePoints),
+        _codePointsToCharacte2 = _slicedToArray(_codePointsToCharacte, 2),
+        indicies = _codePointsToCharacte2[0],
+        classTypes = _codePointsToCharacte2[1];
+
+    return _lineBreakAtIndex(codePoints, classTypes, indicies, index);
+};
+
+var cssFormattedClasses = function cssFormattedClasses(codePoints, options) {
+    if (!options) {
+        options = { lineBreak: 'normal', wordBreak: 'normal' };
+    }
+
+    var _codePointsToCharacte3 = codePointsToCharacterClasses(codePoints, options.lineBreak),
+        _codePointsToCharacte4 = _slicedToArray(_codePointsToCharacte3, 3),
+        indicies = _codePointsToCharacte4[0],
+        classTypes = _codePointsToCharacte4[1],
+        isLetterNumber = _codePointsToCharacte4[2];
+
+    if (options.wordBreak === 'break-all' || options.wordBreak === 'break-word') {
+        classTypes = classTypes.map(function (type) {
+            return [NU, AL, SA].indexOf(type) !== -1 ? ID : type;
+        });
+    }
+
+    var forbiddenBreakpoints = options.wordBreak === 'keep-all' ? isLetterNumber.map(function (isLetterNumber, i) {
+        return isLetterNumber && codePoints[i] >= 0x4e00 && codePoints[i] <= 0x9fff;
+    }) : null;
+
+    return [indicies, classTypes, forbiddenBreakpoints];
+};
+
+var inlineBreakOpportunities = exports.inlineBreakOpportunities = function inlineBreakOpportunities(str, options) {
+    var codePoints = (0, _Util.toCodePoints)(str);
+    var output = BREAK_NOT_ALLOWED;
+
+    var _cssFormattedClasses = cssFormattedClasses(codePoints, options),
+        _cssFormattedClasses2 = _slicedToArray(_cssFormattedClasses, 3),
+        indicies = _cssFormattedClasses2[0],
+        classTypes = _cssFormattedClasses2[1],
+        forbiddenBreakpoints = _cssFormattedClasses2[2];
+
+    codePoints.forEach(function (codePoint, i) {
+        output += (0, _Util.fromCodePoint)(codePoint) + (i >= codePoints.length - 1 ? BREAK_MANDATORY : _lineBreakAtIndex(codePoints, classTypes, indicies, i + 1, forbiddenBreakpoints));
+    });
+
+    return output;
+};
+
+var Break = function () {
+    function Break(codePoints, lineBreak, start, end) {
+        _classCallCheck(this, Break);
+
+        this._codePoints = codePoints;
+        this.required = lineBreak === BREAK_MANDATORY;
+        this.start = start;
+        this.end = end;
+    }
+
+    _createClass(Break, [{
+        key: 'slice',
+        value: function slice() {
+            return _Util.fromCodePoint.apply(undefined, _toConsumableArray(this._codePoints.slice(this.start, this.end)));
+        }
+    }]);
+
+    return Break;
+}();
+
+var LineBreaker = exports.LineBreaker = function LineBreaker(str, options) {
+    var codePoints = (0, _Util.toCodePoints)(str);
+
+    var _cssFormattedClasses3 = cssFormattedClasses(codePoints, options),
+        _cssFormattedClasses4 = _slicedToArray(_cssFormattedClasses3, 3),
+        indicies = _cssFormattedClasses4[0],
+        classTypes = _cssFormattedClasses4[1],
+        forbiddenBreakpoints = _cssFormattedClasses4[2];
+
+    var length = codePoints.length;
+    var lastEnd = 0;
+    var nextIndex = 0;
+
+    return {
+        next: function next() {
+            if (nextIndex >= length) {
+                return { done: true };
+            }
+            var lineBreak = BREAK_NOT_ALLOWED;
+            while (nextIndex < length && (lineBreak = _lineBreakAtIndex(codePoints, classTypes, indicies, ++nextIndex, forbiddenBreakpoints)) === BREAK_NOT_ALLOWED) {}
+
+            if (lineBreak !== BREAK_NOT_ALLOWED || nextIndex === length) {
+                var value = new Break(codePoints, lineBreak, lastEnd, nextIndex);
+                lastEnd = nextIndex;
+                return { value: value, done: false };
+            }
+
+            return { done: true };
+        }
+    };
+};
+
+/***/ }),
+/* 48 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.Trie = exports.createTrieFromBase64 = exports.UTRIE2_INDEX_2_MASK = exports.UTRIE2_INDEX_2_BLOCK_LENGTH = exports.UTRIE2_OMITTED_BMP_INDEX_1_LENGTH = exports.UTRIE2_INDEX_1_OFFSET = exports.UTRIE2_UTF8_2B_INDEX_2_LENGTH = exports.UTRIE2_UTF8_2B_INDEX_2_OFFSET = exports.UTRIE2_INDEX_2_BMP_LENGTH = exports.UTRIE2_LSCP_INDEX_2_LENGTH = exports.UTRIE2_DATA_MASK = exports.UTRIE2_DATA_BLOCK_LENGTH = exports.UTRIE2_LSCP_INDEX_2_OFFSET = exports.UTRIE2_SHIFT_1_2 = exports.UTRIE2_INDEX_SHIFT = exports.UTRIE2_SHIFT_1 = exports.UTRIE2_SHIFT_2 = undefined;
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Util = __webpack_require__(13);
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+/** Shift size for getting the index-2 table offset. */
+var UTRIE2_SHIFT_2 = exports.UTRIE2_SHIFT_2 = 5;
+
+/** Shift size for getting the index-1 table offset. */
+var UTRIE2_SHIFT_1 = exports.UTRIE2_SHIFT_1 = 6 + 5;
+
+/**
+ * Shift size for shifting left the index array values.
+ * Increases possible data size with 16-bit index values at the cost
+ * of compactability.
+ * This requires data blocks to be aligned by UTRIE2_DATA_GRANULARITY.
+ */
+var UTRIE2_INDEX_SHIFT = exports.UTRIE2_INDEX_SHIFT = 2;
+
+/**
+ * Difference between the two shift sizes,
+ * for getting an index-1 offset from an index-2 offset. 6=11-5
+ */
+var UTRIE2_SHIFT_1_2 = exports.UTRIE2_SHIFT_1_2 = UTRIE2_SHIFT_1 - UTRIE2_SHIFT_2;
+
+/**
+ * The part of the index-2 table for U+D800..U+DBFF stores values for
+ * lead surrogate code _units_ not code _points_.
+ * Values for lead surrogate code _points_ are indexed with this portion of the table.
+ * Length=32=0x20=0x400>>UTRIE2_SHIFT_2. (There are 1024=0x400 lead surrogates.)
+ */
+var UTRIE2_LSCP_INDEX_2_OFFSET = exports.UTRIE2_LSCP_INDEX_2_OFFSET = 0x10000 >> UTRIE2_SHIFT_2;
+
+/** Number of entries in a data block. 32=0x20 */
+var UTRIE2_DATA_BLOCK_LENGTH = exports.UTRIE2_DATA_BLOCK_LENGTH = 1 << UTRIE2_SHIFT_2;
+/** Mask for getting the lower bits for the in-data-block offset. */
+var UTRIE2_DATA_MASK = exports.UTRIE2_DATA_MASK = UTRIE2_DATA_BLOCK_LENGTH - 1;
+
+var UTRIE2_LSCP_INDEX_2_LENGTH = exports.UTRIE2_LSCP_INDEX_2_LENGTH = 0x400 >> UTRIE2_SHIFT_2;
+/** Count the lengths of both BMP pieces. 2080=0x820 */
+var UTRIE2_INDEX_2_BMP_LENGTH = exports.UTRIE2_INDEX_2_BMP_LENGTH = UTRIE2_LSCP_INDEX_2_OFFSET + UTRIE2_LSCP_INDEX_2_LENGTH;
+/**
+ * The 2-byte UTF-8 version of the index-2 table follows at offset 2080=0x820.
+ * Length 32=0x20 for lead bytes C0..DF, regardless of UTRIE2_SHIFT_2.
+ */
+var UTRIE2_UTF8_2B_INDEX_2_OFFSET = exports.UTRIE2_UTF8_2B_INDEX_2_OFFSET = UTRIE2_INDEX_2_BMP_LENGTH;
+var UTRIE2_UTF8_2B_INDEX_2_LENGTH = exports.UTRIE2_UTF8_2B_INDEX_2_LENGTH = 0x800 >> 6; /* U+0800 is the first code point after 2-byte UTF-8 */
+/**
+ * The index-1 table, only used for supplementary code points, at offset 2112=0x840.
+ * Variable length, for code points up to highStart, where the last single-value range starts.
+ * Maximum length 512=0x200=0x100000>>UTRIE2_SHIFT_1.
+ * (For 0x100000 supplementary code points U+10000..U+10ffff.)
+ *
+ * The part of the index-2 table for supplementary code points starts
+ * after this index-1 table.
+ *
+ * Both the index-1 table and the following part of the index-2 table
+ * are omitted completely if there is only BMP data.
+ */
+var UTRIE2_INDEX_1_OFFSET = exports.UTRIE2_INDEX_1_OFFSET = UTRIE2_UTF8_2B_INDEX_2_OFFSET + UTRIE2_UTF8_2B_INDEX_2_LENGTH;
+
+/**
+ * Number of index-1 entries for the BMP. 32=0x20
+ * This part of the index-1 table is omitted from the serialized form.
+ */
+var UTRIE2_OMITTED_BMP_INDEX_1_LENGTH = exports.UTRIE2_OMITTED_BMP_INDEX_1_LENGTH = 0x10000 >> UTRIE2_SHIFT_1;
+
+/** Number of entries in an index-2 block. 64=0x40 */
+var UTRIE2_INDEX_2_BLOCK_LENGTH = exports.UTRIE2_INDEX_2_BLOCK_LENGTH = 1 << UTRIE2_SHIFT_1_2;
+/** Mask for getting the lower bits for the in-index-2-block offset. */
+var UTRIE2_INDEX_2_MASK = exports.UTRIE2_INDEX_2_MASK = UTRIE2_INDEX_2_BLOCK_LENGTH - 1;
+
+var createTrieFromBase64 = exports.createTrieFromBase64 = function createTrieFromBase64(base64) {
+    var buffer = (0, _Util.decode)(base64);
+    var view32 = Array.isArray(buffer) ? (0, _Util.polyUint32Array)(buffer) : new Uint32Array(buffer);
+    var view16 = Array.isArray(buffer) ? (0, _Util.polyUint16Array)(buffer) : new Uint16Array(buffer);
+    var headerLength = 24;
+
+    var index = view16.slice(headerLength / 2, view32[4] / 2);
+    var data = view32[5] === 2 ? view16.slice((headerLength + view32[4]) / 2) : view32.slice(Math.ceil((headerLength + view32[4]) / 4));
+
+    return new Trie(view32[0], view32[1], view32[2], view32[3], index, data);
+};
+
+var Trie = exports.Trie = function () {
+    function Trie(initialValue, errorValue, highStart, highValueIndex, index, data) {
+        _classCallCheck(this, Trie);
+
+        this.initialValue = initialValue;
+        this.errorValue = errorValue;
+        this.highStart = highStart;
+        this.highValueIndex = highValueIndex;
+        this.index = index;
+        this.data = data;
+    }
+
+    /**
+     * Get the value for a code point as stored in the Trie.
+     *
+     * @param codePoint the code point
+     * @return the value
+     */
+
+
+    _createClass(Trie, [{
+        key: 'get',
+        value: function get(codePoint) {
+            var ix = void 0;
+            if (codePoint >= 0) {
+                if (codePoint < 0x0d800 || codePoint > 0x0dbff && codePoint <= 0x0ffff) {
+                    // Ordinary BMP code point, excluding leading surrogates.
+                    // BMP uses a single level lookup.  BMP index starts at offset 0 in the Trie2 index.
+                    // 16 bit data is stored in the index array itself.
+                    ix = this.index[codePoint >> UTRIE2_SHIFT_2];
+                    ix = (ix << UTRIE2_INDEX_SHIFT) + (codePoint & UTRIE2_DATA_MASK);
+                    return this.data[ix];
+                }
+
+                if (codePoint <= 0xffff) {
+                    // Lead Surrogate Code Point.  A Separate index section is stored for
+                    // lead surrogate code units and code points.
+                    //   The main index has the code unit data.
+                    //   For this function, we need the code point data.
+                    // Note: this expression could be refactored for slightly improved efficiency, but
+                    //       surrogate code points will be so rare in practice that it's not worth it.
+                    ix = this.index[UTRIE2_LSCP_INDEX_2_OFFSET + (codePoint - 0xd800 >> UTRIE2_SHIFT_2)];
+                    ix = (ix << UTRIE2_INDEX_SHIFT) + (codePoint & UTRIE2_DATA_MASK);
+                    return this.data[ix];
+                }
+
+                if (codePoint < this.highStart) {
+                    // Supplemental code point, use two-level lookup.
+                    ix = UTRIE2_INDEX_1_OFFSET - UTRIE2_OMITTED_BMP_INDEX_1_LENGTH + (codePoint >> UTRIE2_SHIFT_1);
+                    ix = this.index[ix];
+                    ix += codePoint >> UTRIE2_SHIFT_2 & UTRIE2_INDEX_2_MASK;
+                    ix = this.index[ix];
+                    ix = (ix << UTRIE2_INDEX_SHIFT) + (codePoint & UTRIE2_DATA_MASK);
+                    return this.data[ix];
+                }
+                if (codePoint <= 0x10ffff) {
+                    return this.data[this.highValueIndex];
+                }
+            }
+
+            // Fall through.  The code point is outside of the legal range of 0..0x10ffff.
+            return this.errorValue;
+        }
+    }]);
+
+    return Trie;
+}();
+
+/***/ }),
+/* 49 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+module.exports = 'KwAAAAAAAAAACA4AIDoAAPAfAAACAAAAAAAIABAAGABAAEgAUABYAF4AZgBeAGYAYABoAHAAeABeAGYAfACEAIAAiACQAJgAoACoAK0AtQC9AMUAXgBmAF4AZgBeAGYAzQDVAF4AZgDRANkA3gDmAOwA9AD8AAQBDAEUARoBIgGAAIgAJwEvATcBPwFFAU0BTAFUAVwBZAFsAXMBewGDATAAiwGTAZsBogGkAawBtAG8AcIBygHSAdoB4AHoAfAB+AH+AQYCDgIWAv4BHgImAi4CNgI+AkUCTQJTAlsCYwJrAnECeQKBAk0CiQKRApkCoQKoArACuALAAsQCzAIwANQC3ALkAjAA7AL0AvwCAQMJAxADGAMwACADJgMuAzYDPgOAAEYDSgNSA1IDUgNaA1oDYANiA2IDgACAAGoDgAByA3YDfgOAAIQDgACKA5IDmgOAAIAAogOqA4AAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAK8DtwOAAIAAvwPHA88D1wPfAyAD5wPsA/QD/AOAAIAABAQMBBIEgAAWBB4EJgQuBDMEIAM7BEEEXgBJBCADUQRZBGEEaQQwADAAcQQ+AXkEgQSJBJEEgACYBIAAoASoBK8EtwQwAL8ExQSAAIAAgACAAIAAgACgAM0EXgBeAF4AXgBeAF4AXgBeANUEXgDZBOEEXgDpBPEE+QQBBQkFEQUZBSEFKQUxBTUFPQVFBUwFVAVcBV4AYwVeAGsFcwV7BYMFiwWSBV4AmgWgBacFXgBeAF4AXgBeAKsFXgCyBbEFugW7BcIFwgXIBcIFwgXQBdQF3AXkBesF8wX7BQMGCwYTBhsGIwYrBjMGOwZeAD8GRwZNBl4AVAZbBl4AXgBeAF4AXgBeAF4AXgBeAF4AXgBeAGMGXgBqBnEGXgBeAF4AXgBeAF4AXgBeAF4AXgB5BoAG4wSGBo4GkwaAAIADHgR5AF4AXgBeAJsGgABGA4AAowarBrMGswagALsGwwbLBjAA0wbaBtoG3QbaBtoG2gbaBtoG2gblBusG8wb7BgMHCwcTBxsHCwcjBysHMAc1BzUHOgdCB9oGSgdSB1oHYAfaBloHaAfaBlIH2gbaBtoG2gbaBtoG2gbaBjUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHbQdeAF4ANQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQd1B30HNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1B4MH2gaKB68EgACAAIAAgACAAIAAgACAAI8HlwdeAJ8HpweAAIAArwe3B14AXgC/B8UHygcwANAH2AfgB4AA6AfwBz4B+AcACFwBCAgPCBcIogEYAR8IJwiAAC8INwg/CCADRwhPCFcIXwhnCEoDGgSAAIAAgABvCHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIhAiLCI4IMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlggwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAANQc1BzUHNQc1BzUHNQc1BzUHNQc1B54INQc1B6II2gaqCLIIugiAAIAAvgjGCIAAgACAAIAAgACAAIAAgACAAIAAywiHAYAA0wiAANkI3QjlCO0I9Aj8CIAAgACAAAIJCgkSCRoJIgknCTYHLwk3CZYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiAAIAAAAFAAXgBeAGAAcABeAHwAQACQAKAArQC9AJ4AXgBeAE0A3gBRAN4A7AD8AMwBGgEAAKcBNwEFAUwBXAF4QkhCmEKnArcCgAHHAsABz4LAAcABwAHAAd+C6ABoAG+C/4LAAcABwAHAAc+DF4MAAcAB54M3gweDV4Nng3eDaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAEeDqABVg6WDqABoQ6gAaABoAHXDvcONw/3DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DncPAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcAB7cPPwlGCU4JMACAAIAAgABWCV4JYQmAAGkJcAl4CXwJgAkwADAAMAAwAIgJgACLCZMJgACZCZ8JowmrCYAAswkwAF4AXgB8AIAAuwkABMMJyQmAAM4JgADVCTAAMAAwADAAgACAAIAAgACAAIAAgACAAIAAqwYWBNkIMAAwADAAMADdCeAJ6AnuCR4E9gkwAP4JBQoNCjAAMACAABUK0wiAAB0KJAosCjQKgAAwADwKQwqAAEsKvQmdCVMKWwowADAAgACAALcEMACAAGMKgABrCjAAMAAwADAAMAAwADAAMAAwADAAMAAeBDAAMAAwADAAMAAwADAAMAAwADAAMAAwAIkEPQFzCnoKiQSCCooKkAqJBJgKoAqkCokEGAGsCrQKvArBCjAAMADJCtEKFQHZCuEK/gHpCvEKMAAwADAAMACAAIwE+QowAIAAPwEBCzAAMAAwADAAMACAAAkLEQswAIAAPwEZCyELgAAOCCkLMAAxCzkLMAAwADAAMAAwADAAXgBeAEELMAAwADAAMAAwADAAMAAwAEkLTQtVC4AAXAtkC4AAiQkwADAAMAAwADAAMAAwADAAbAtxC3kLgAuFC4sLMAAwAJMLlwufCzAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAApwswADAAMACAAIAAgACvC4AAgACAAIAAgACAALcLMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAvwuAAMcLgACAAIAAgACAAIAAyguAAIAAgACAAIAA0QswADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAANkLgACAAIAA4AswADAAMAAwADAAMAAwADAAMAAwADAAMAAwAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACJCR4E6AswADAAhwHwC4AA+AsADAgMEAwwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMACAAIAAGAwdDCUMMAAwAC0MNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQw1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHPQwwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADUHNQc1BzUHNQc1BzUHNQc2BzAAMAA5DDUHNQc1BzUHNQc1BzUHNQc1BzUHNQdFDDAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAgACAAIAATQxSDFoMMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAF4AXgBeAF4AXgBeAF4AYgxeAGoMXgBxDHkMfwxeAIUMXgBeAI0MMAAwADAAMAAwAF4AXgCVDJ0MMAAwADAAMABeAF4ApQxeAKsMswy7DF4Awgy9DMoMXgBeAF4AXgBeAF4AXgBeAF4AXgDRDNkMeQBqCeAM3Ax8AOYM7Az0DPgMXgBeAF4AXgBeAF4AXgBeAF4AXgBeAF4AXgBeAF4AXgCgAAANoAAHDQ4NFg0wADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAeDSYNMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAIAAgACAAIAAgACAAC4NMABeAF4ANg0wADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAD4NRg1ODVYNXg1mDTAAbQ0wADAAMAAwADAAMAAwADAA2gbaBtoG2gbaBtoG2gbaBnUNeg3CBYANwgWFDdoGjA3aBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gaUDZwNpA2oDdoG2gawDbcNvw3HDdoG2gbPDdYN3A3fDeYN2gbsDfMN2gbaBvoN/g3aBgYODg7aBl4AXgBeABYOXgBeACUG2gYeDl4AJA5eACwO2w3aBtoGMQ45DtoG2gbaBtoGQQ7aBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gZJDjUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1B1EO2gY1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQdZDjUHNQc1BzUHNQc1B2EONQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHaA41BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1B3AO2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gY1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1B2EO2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gZJDtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBkkOeA6gAKAAoAAwADAAMAAwAKAAoACgAKAAoACgAKAAgA4wADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAD//wQABAAEAAQABAAEAAQABAAEAA0AAwABAAEAAgAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAKABMAFwAeABsAGgAeABcAFgASAB4AGwAYAA8AGAAcAEsASwBLAEsASwBLAEsASwBLAEsAGAAYAB4AHgAeABMAHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAFgAbABIAHgAeAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQABYADQARAB4ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAAUABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAkAFgAaABsAGwAbAB4AHQAdAB4ATwAXAB4ADQAeAB4AGgAbAE8ATwAOAFAAHQAdAB0ATwBPABcATwBPAE8AFgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAB4AHgAeAB4AUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AHgAeAFAATwBAAE8ATwBPAEAATwBQAFAATwBQAB4AHgAeAB4AHgAeAB0AHQAdAB0AHgAdAB4ADgBQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgBQAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAJAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAkACQAJAAkACQAJAAkABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgAeAFAAHgAeAB4AKwArAFAAUABQAFAAGABQACsAKwArACsAHgAeAFAAHgBQAFAAUAArAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAUAAeAB4AHgAeAB4AHgArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwAYAA0AKwArAB4AHgAbACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQADQAEAB4ABAAEAB4ABAAEABMABAArACsAKwArACsAKwArACsAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAKwArACsAKwArAFYAVgBWAB4AHgArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AGgAaABoAGAAYAB4AHgAEAAQABAAEAAQABAAEAAQABAAEAAQAEwAEACsAEwATAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABLAEsASwBLAEsASwBLAEsASwBLABoAGQAZAB4AUABQAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQABMAUAAEAAQABAAEAAQABAAEAB4AHgAEAAQABAAEAAQABABQAFAABAAEAB4ABAAEAAQABABQAFAASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUAAeAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAFAABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQAUABQAB4AHgAYABMAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAFAABAAEAAQABAAEAFAABAAEAAQAUAAEAAQABAAEAAQAKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAArACsAHgArAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAFAABAAEAAQABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAAQABAANAA0ASwBLAEsASwBLAEsASwBLAEsASwAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQAKwBQAFAAUABQAFAAUABQAFAAKwArAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUAArAFAAKwArACsAUABQAFAAUAArACsABABQAAQABAAEAAQABAAEAAQAKwArAAQABAArACsABAAEAAQAUAArACsAKwArACsAKwArACsABAArACsAKwArAFAAUAArAFAAUABQAAQABAArACsASwBLAEsASwBLAEsASwBLAEsASwBQAFAAGgAaAFAAUABQAFAAUABMAB4AGwBQAB4AKwArACsABAAEAAQAKwBQAFAAUABQAFAAUAArACsAKwArAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUAArAFAAUAArAFAAUAArAFAAUAArACsABAArAAQABAAEAAQABAArACsAKwArAAQABAArACsABAAEAAQAKwArACsABAArACsAKwArACsAKwArAFAAUABQAFAAKwBQACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwAEAAQAUABQAFAABAArACsAKwArACsAKwArACsAKwArACsABAAEAAQAKwBQAFAAUABQAFAAUABQAFAAUAArAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUAArAFAAUAArAFAAUABQAFAAUAArACsABABQAAQABAAEAAQABAAEAAQABAArAAQABAAEACsABAAEAAQAKwArAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAAQABAArACsASwBLAEsASwBLAEsASwBLAEsASwAeABsAKwArACsAKwArACsAKwBQAAQABAAEAAQABAAEACsABAAEAAQAKwBQAFAAUABQAFAAUABQAFAAKwArAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQAKwArAAQABAArACsABAAEAAQAKwArACsAKwArACsAKwArAAQABAArACsAKwArAFAAUAArAFAAUABQAAQABAArACsASwBLAEsASwBLAEsASwBLAEsASwAeAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwAEAFAAKwBQAFAAUABQAFAAUAArACsAKwBQAFAAUAArAFAAUABQAFAAKwArACsAUABQACsAUAArAFAAUAArACsAKwBQAFAAKwArACsAUABQAFAAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwAEAAQABAAEAAQAKwArACsABAAEAAQAKwAEAAQABAAEACsAKwBQACsAKwArACsAKwArAAQAKwArACsAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLAFAAUABQAB4AHgAeAB4AHgAeABsAHgArACsAKwArACsABAAEAAQABAArAFAAUABQAFAAUABQAFAAUAArAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAFAABAAEAAQABAAEAAQABAArAAQABAAEACsABAAEAAQABAArACsAKwArACsAKwArAAQABAArAFAAUABQACsAKwArACsAKwBQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAB4AUAAEAAQABAArAFAAUABQAFAAUABQAFAAUAArAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQACsAKwAEAFAABAAEAAQABAAEAAQABAArAAQABAAEACsABAAEAAQABAArACsAKwArACsAKwArAAQABAArACsAKwArACsAKwArAFAAKwBQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAFAABAAEAAQABAAEAAQABAArAAQABAAEACsABAAEAAQABABQAB4AKwArACsAKwBQAFAAUAAEAFAAUABQAFAAUABQAFAAUABQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAFAAUABQAFAAUABQAFAAUABQABoAUABQAFAAUABQAFAAKwArAAQABAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQACsAUAArACsAUABQAFAAUABQAFAAUAArACsAKwAEACsAKwArACsABAAEAAQABAAEAAQAKwAEACsABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArAAQABAAeACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAAqAFwAXAAqACoAKgAqACoAKgAqACsAKwArACsAGwBcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAeAEsASwBLAEsASwBLAEsASwBLAEsADQANACsAKwArACsAKwBcAFwAKwBcACsAKwBcAFwAKwBcACsAKwBcACsAKwArACsAKwArAFwAXABcAFwAKwBcAFwAXABcAFwAXABcACsAXABcAFwAKwBcACsAXAArACsAXABcACsAXABcAFwAXAAqAFwAXAAqACoAKgAqACoAKgArACoAKgBcACsAKwBcAFwAXABcAFwAKwBcACsAKgAqACoAKgAqACoAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArAFwAXABcAFwAUAAOAA4ADgAOAB4ADgAOAAkADgAOAA0ACQATABMAEwATABMACQAeABMAHgAeAB4ABAAEAB4AHgAeAB4AHgAeAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAUABQAFAAUABQAFAAUAANAAQAHgAEAB4ABAAWABEAFgARAAQABABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAANAAQABAAEAAQABAANAAQABABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsADQANAB4AHgAeAB4AHgAeAAQAHgAeAB4AHgAeAB4AKwAeAB4ADgAOAA0ADgAeAB4AHgAeAB4ACQAJACsAKwArACsAKwBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqAFwASwBLAEsASwBLAEsASwBLAEsASwANAA0AHgAeAB4AHgBcAFwAXABcAFwAXAAqACoAKgAqAFwAXABcAFwAKgAqACoAXAAqACoAKgBcAFwAKgAqACoAKgAqACoAKgBcAFwAXAAqACoAKgAqAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAKgAqACoAKgAqACoAKgAqACoAXAAqAEsASwBLAEsASwBLAEsASwBLAEsAKgAqACoAKgAqACoAUABQAFAAUABQAFAAKwBQACsAKwArACsAKwBQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQACsAUAArAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUAArACsAUABQAFAAUABQAFAAUAArAFAAKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwAEAAQABAAeAA0AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQACsAKwANAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQABYAEQArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAADQANAA0AUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAABAAEAAQAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAA0ADQArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQACsABAAEACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoADQANABUAXAANAB4ADQAbAFwAKgArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArAB4AHgATABMADQANAA4AHgATABMAHgAEAAQABAAJACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAUABQAFAAUABQAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABABQACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwAeACsAKwArABMAEwBLAEsASwBLAEsASwBLAEsASwBLAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACsAKwBcAFwAXABcAFwAKwArACsAKwArACsAKwArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcACsAKwArACsAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBcACsAKwArACoAKgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEACsAKwAeAB4AXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAKgAqACoAKgAqACoAKgArACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgArACsABABLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAKgAqACoAKgAqACoAKgBcACoAKgAqACoAKgAqACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArAAQABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQAUABQAFAAUABQAFAAUAArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsADQANAB4ADQANAA0ADQAeAB4AHgAeAB4AHgAeAB4AHgAeAAQABAAEAAQABAAEAAQABAAEAB4AHgAeAB4AHgAeAB4AHgAeACsAKwArAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAUABQAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArACsAKwArACsAHgAeAB4AHgBQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwANAA0ADQANAA0ASwBLAEsASwBLAEsASwBLAEsASwArACsAKwBQAFAAUABLAEsASwBLAEsASwBLAEsASwBLAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAANAA0AUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsABAAEAAQAHgAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAFAAUABQAFAABABQAFAAUABQAAQABAAEAFAAUAAEAAQABAArACsAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwAEAAQABAAEAAQAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUAArAFAAKwBQACsAUAArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAHgAeAB4AHgAeAB4AHgAeAFAAHgAeAB4AUABQAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAKwArAB4AHgAeAB4AHgAeACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAUABQAFAAKwAeAB4AHgAeAB4AHgAeAA4AHgArAA0ADQANAA0ADQANAA0ACQANAA0ADQAIAAQACwAEAAQADQAJAA0ADQAMAB0AHQAeABcAFwAWABcAFwAXABYAFwAdAB0AHgAeABQAFAAUAA0AAQABAAQABAAEAAQABAAJABoAGgAaABoAGgAaABoAGgAeABcAFwAdABUAFQAeAB4AHgAeAB4AHgAYABYAEQAVABUAFQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgANAB4ADQANAA0ADQAeAA0ADQANAAcAHgAeAB4AHgArAAQABAAEAAQABAAEAAQABAAEAAQAUABQACsAKwBPAFAAUABQAFAAUAAeAB4AHgAWABEATwBQAE8ATwBPAE8AUABQAFAAUABQAB4AHgAeABYAEQArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAGwAbABsAGwAbABsAGwAaABsAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGwAaABsAGwAbABsAGgAbABsAGgAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbABsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgBQABoAHgAdAB4AUAAeABoAHgAeAB4AHgAeAB4AHgAeAB4ATwAeAFAAGwAeAB4AUABQAFAAUABQAB4AHgAeAB0AHQAeAFAAHgBQAB4AUAAeAFAATwBQAFAAHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAB4AUABQAFAAUABPAE8AUABQAFAAUABQAE8AUABQAE8AUABPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBQAFAAUABQAE8ATwBPAE8ATwBPAE8ATwBPAE8AUABQAFAAUABQAFAAUABQAFAAHgAeAFAAUABQAFAATwAeAB4AKwArACsAKwAdAB0AHQAdAB0AHQAdAB0AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAeAB0AHQAeAB4AHgAdAB0AHgAeAB0AHgAeAB4AHQAeAB0AGwAbAB4AHQAeAB4AHgAeAB0AHgAeAB0AHQAdAB0AHgAeAB0AHgAdAB4AHQAdAB0AHQAdAB0AHgAdAB4AHgAeAB4AHgAdAB0AHQAdAB4AHgAeAB4AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAeAB4AHgAdAB4AHgAeAB4AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB4AHgAdAB0AHQAdAB4AHgAdAB0AHgAeAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHgAeAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AHQAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABQAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAWABEAFgARAB4AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAlACUAHgAeAB4AHgAeAB4AHgAeAB4AFgARAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBQAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB4AHgAeAB4AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHgAdAB0AHQAdAB0AHQAdAB4AHgAeAB4AHgAeAB4AHgAdAB0AHgAeAB0AHQAeAB4AHgAeAB0AHQAeAB4AHgAeAB0AHQAdAB4AHgAdAB4AHgAdAB0AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAeAB0AHQAeAB4AHQAeAB4AHgAeAB0AHQAeAB4AHgAeACUAJQAdAB0AJQAeACUAJQAlACAAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAHgAeAB4AHgAdAB4AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB4AHQAdAB0AHgAdACUAHQAdAB4AHQAdAB4AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAHQAdAB0AHQAlAB4AJQAlACUAHQAlACUAHQAdAB0AJQAlAB0AHQAlAB0AHQAlACUAJQAeAB0AHgAeAB4AHgAdAB0AJQAdAB0AHQAdAB0AHQAlACUAJQAlACUAHQAlACUAIAAlAB0AHQAlACUAJQAlACUAJQAlACUAHgAeAB4AJQAlACAAIAAgACAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHgAeABcAFwAXABcAFwAXAB4AEwATACUAHgAeAB4AFgARABYAEQAWABEAFgARABYAEQAWABEAFgARAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAWABEAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFgARABYAEQAWABEAFgARABYAEQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABYAEQAWABEAFgARABYAEQAWABEAFgARABYAEQAWABEAFgARABYAEQAWABEAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFgARABYAEQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABYAEQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB0AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAEAAQABAAeAB4AKwArACsAKwArABMADQANAA0AUAATAA0AUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAUAANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAA0ADQANAA0ADQANAA0ADQAeAA0AFgANAB4AHgAXABcAHgAeABcAFwAWABEAFgARABYAEQAWABEADQANAA0ADQATAFAADQANAB4ADQANAB4AHgAeAB4AHgAMAAwADQANAA0AHgANAA0AFgANAA0ADQANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAKwArACsAKwArACsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArAA0AEQARACUAJQBHAFcAVwAWABEAFgARABYAEQAWABEAFgARACUAJQAWABEAFgARABYAEQAWABEAFQAWABEAEQAlAFcAVwBXAFcAVwBXAFcAVwBXAAQABAAEAAQABAAEACUAVwBXAFcAVwA2ACUAJQBXAFcAVwBHAEcAJQAlACUAKwBRAFcAUQBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFEAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBRAFcAUQBXAFEAVwBXAFcAVwBXAFcAUQBXAFcAVwBXAFcAVwBRAFEAKwArAAQABAAVABUARwBHAFcAFQBRAFcAUQBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBRAFcAVwBXAFcAVwBXAFEAUQBXAFcAVwBXABUAUQBHAEcAVwArACsAKwArACsAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwArAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwArACUAJQBXAFcAVwBXACUAJQAlACUAJQAlACUAJQAlACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwArACsAKwArACUAJQAlACUAKwArACsAKwArACsAKwArACsAKwArACsAUQBRAFEAUQBRAFEAUQBRAFEAUQBRAFEAUQBRAFEAUQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACsAVwBXAFcAVwBXAFcAVwBXAFcAVwAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAE8ATwBPAE8ATwBPAE8ATwAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQAlACUAJQAlACUAJQAlACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAEcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAADQATAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABLAEsASwBLAEsASwBLAEsASwBLAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAABAAEAAQABAAeAAQABAAEAAQABAAEAAQABAAEAAQAHgBQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUABQAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAeAA0ADQANAA0ADQArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAB4AHgAeAB4AHgAeAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAAQAUABQAFAABABQAFAAUABQAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAeAB4AHgAeACsAKwArACsAUABQAFAAUABQAFAAHgAeABoAHgArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAADgAOABMAEwArACsAKwArACsAKwArACsABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwANAA0ASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAFAAUAAeAB4AHgBQAA4AUAArACsAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAA0ADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArAB4AWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYACsAKwArAAQAHgAeAB4AHgAeAB4ADQANAA0AHgAeAB4AHgArAFAASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArAB4AHgBcAFwAXABcAFwAKgBcAFwAXABcAFwAXABcAFwAXABcAEsASwBLAEsASwBLAEsASwBLAEsAXABcAFwAXABcACsAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArAFAAUABQAAQAUABQAFAAUABQAFAAUABQAAQABAArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAHgANAA0ADQBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAXAAqACoAKgBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAAqAFwAKgAqACoAXABcACoAKgBcAFwAXABcAFwAKgAqAFwAKgBcACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcACoAKgBQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAA0ADQBQAFAAUAAEAAQAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUAArACsAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQADQAEAAQAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAVABVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBUAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVACsAKwArACsAKwArACsAKwArACsAKwArAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAKwArACsAKwBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAKwArACsAKwAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAKwArACsAKwArAFYABABWAFYAVgBWAFYAVgBWAFYAVgBWAB4AVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgArAFYAVgBWAFYAVgArAFYAKwBWAFYAKwBWAFYAKwBWAFYAVgBWAFYAVgBWAFYAVgBWAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAEQAWAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUAAaAB4AKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAGAARABEAGAAYABMAEwAWABEAFAArACsAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACUAJQAlACUAJQAWABEAFgARABYAEQAWABEAFgARABYAEQAlACUAFgARACUAJQAlACUAJQAlACUAEQAlABEAKwAVABUAEwATACUAFgARABYAEQAWABEAJQAlACUAJQAlACUAJQAlACsAJQAbABoAJQArACsAKwArAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAcAKwATACUAJQAbABoAJQAlABYAEQAlACUAEQAlABEAJQBXAFcAVwBXAFcAVwBXAFcAVwBXABUAFQAlACUAJQATACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXABYAJQARACUAJQAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwAWACUAEQAlABYAEQARABYAEQARABUAVwBRAFEAUQBRAFEAUQBRAFEAUQBRAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAEcARwArACsAVwBXAFcAVwBXAFcAKwArAFcAVwBXAFcAVwBXACsAKwBXAFcAVwBXAFcAVwArACsAVwBXAFcAKwArACsAGgAbACUAJQAlABsAGwArAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwAEAAQABAAQAB0AKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsADQANAA0AKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsADQBQAFAAUABQACsAKwArACsAUABQAFAAUABQAFAAUABQAA0AUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUAArACsAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQACsAKwArAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgBQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwBQAFAAUABQAFAABAAEAAQAKwAEAAQAKwArACsAKwArAAQABAAEAAQAUABQAFAAUAArAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsABAAEAAQAKwArACsAKwAEAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsADQANAA0ADQANAA0ADQANAB4AKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AUABQAFAAUABQAFAAUABQAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEACsAKwArACsAUABQAFAAUABQAA0ADQANAA0ADQANABQAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwANAA0ADQANAA0ADQANAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwBQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAA0ADQAeAB4AHgAeAB4AKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsASwBLAEsASwBLAEsASwBLAEsASwANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAeAA4AUAArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAADQANAB4ADQAeAAQABAAEAB4AKwArAEsASwBLAEsASwBLAEsASwBLAEsAUAAOAFAADQANAA0AKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAANAA0AHgANAA0AHgAEACsAUABQAFAAUABQAFAAUAArAFAAKwBQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAA0AKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsABAAEAAQABAArAFAAUABQAFAAUABQAFAAUAArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAArACsABAAEACsAKwAEAAQABAArACsAUAArACsAKwArACsAKwAEACsAKwArACsAKwBQAFAAUABQAFAABAAEACsAKwAEAAQABAAEAAQABAAEACsAKwArAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAAQABABQAFAAUABQAA0ADQANAA0AHgBLAEsASwBLAEsASwBLAEsASwBLACsADQArAB4AKwArAAQABAAEAAQAUABQAB4AUAArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEACsAKwAEAAQABAAEAAQABAAEAAQABAAOAA0ADQATABMAHgAeAB4ADQANAA0ADQANAA0ADQANAA0ADQANAA0ADQANAA0AUABQAFAAUAAEAAQAKwArAAQADQANAB4AUAArACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAArACsAKwAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAXABcAA0ADQANACoASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwBQAFAABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAFAABAAEAAQABAAOAB4ADQANAA0ADQAOAB4ABAArACsAKwArACsAKwArACsAUAAEAAQABAAEAAQABAAEAAQABAAEAAQAUABQAFAAUAArACsAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAA0ADQANACsADgAOAA4ADQANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEACsABAAEAAQABAAEAAQABAAEAFAADQANAA0ADQANACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwAOABMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAArACsAKwAEACsABAAEACsABAAEAAQABAAEAAQABABQAAQAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsADQANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAASABIAEgAQwBDAEMAUABQAFAAUABDAFAAUABQAEgAQwBIAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAASABDAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABIAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwANAA0AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEAAQABAANACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAA0ADQANAB4AHgAeAB4AHgAeAFAAUABQAFAADQAeACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAEcARwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwArACsAKwArACsAKwArACsAKwArACsAKwArAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQACsAKwAeAAQABAANAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAB4AHgAeAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAHgAeAAQABAAEAAQABAAEAAQAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAEAAQABAAEAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgAEAAQABAAeACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAFAAUAArACsAUAArACsAUABQACsAKwBQAFAAUABQACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwBQACsAUABQAFAAUABQAFAAUAArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAKwAeAB4AUABQAFAAUABQACsAUAArACsAKwBQAFAAUABQAFAAUABQACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AKwArAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAB4AHgAeAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAB4AHgAeAB4AHgAeAB4AHgAEAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAeAB4ADQANAA0ADQAeACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAAQABAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsABAAEAAQABAAEAAQABAArAAQABAArAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAEAAQABAAEAAQABAAEACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAFgAWAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUAArAFAAKwArAFAAKwBQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUAArAFAAKwBQACsAKwArACsAKwArAFAAKwArACsAKwBQACsAUAArAFAAKwBQAFAAUAArAFAAUAArAFAAKwArAFAAKwBQACsAUAArAFAAKwBQACsAUABQACsAUAArACsAUABQAFAAUAArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQACsAUABQAFAAUAArAFAAKwBQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwBQAFAAUAArAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwAlACUAJQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAeACUAHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeACUAJQAlACUAHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQAlACUAJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeACUAJQAlACUAJQAeACUAJQAlACUAJQAgACAAIAAlACUAIAAlACUAIAAgACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAIQAhACEAIQAhACUAJQAgACAAJQAlACAAIAAgACAAIAAgACAAIAAgACAAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAIAAgACAAIAAlACUAJQAlACAAJQAgACAAIAAgACAAIAAgACAAIAAlACUAJQAgACUAJQAlACUAIAAgACAAJQAgACAAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeACUAHgAlAB4AJQAlACUAJQAlACAAJQAlACUAJQAeACUAHgAeACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAIAAgACUAJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAIAAlACUAJQAlACAAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAIAAgACAAJQAlACUAIAAgACAAIAAgAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFwAXABcAFQAVABUAHgAeAB4AHgAlACUAJQAgACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAIAAgACAAJQAlACUAJQAlACUAJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAgACAAIAAlACAAIAAlACUAJQAlACUAJQAgACUAJQAlACUAJQAlACUAJQAlACAAIAAgACAAIAAgACAAIAAgACAAJQAlACUAIAAgACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACsAKwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsA';
+
+/***/ }),
+/* 50 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _Path = __webpack_require__(6);
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Circle = function Circle(x, y, radius) {
+    _classCallCheck(this, Circle);
+
+    this.type = _Path.PATH.CIRCLE;
+    this.x = x;
+    this.y = y;
+    this.radius = radius;
+    if (true) {
+        if (isNaN(x)) {
+            console.error('Invalid x value given for Circle');
+        }
+        if (isNaN(y)) {
+            console.error('Invalid y value given for Circle');
+        }
+        if (isNaN(radius)) {
+            console.error('Invalid radius value given for Circle');
+        }
+    }
+};
+
+exports.default = Circle;
+
+/***/ }),
+/* 51 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Bounds = __webpack_require__(2);
+
+var _Font = __webpack_require__(25);
+
+var _Gradient = __webpack_require__(52);
+
+var _TextContainer = __webpack_require__(9);
+
+var _TextContainer2 = _interopRequireDefault(_TextContainer);
+
+var _background = __webpack_require__(5);
+
+var _border = __webpack_require__(12);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Renderer = function () {
+    function Renderer(target, options) {
+        _classCallCheck(this, Renderer);
+
+        this.target = target;
+        this.options = options;
+        target.render(options);
+    }
+
+    _createClass(Renderer, [{
+        key: 'renderNode',
+        value: function renderNode(container) {
+            if (container.isVisible()) {
+                this.renderNodeBackgroundAndBorders(container);
+                this.renderNodeContent(container);
+            }
+        }
+    }, {
+        key: 'renderNodeContent',
+        value: function renderNodeContent(container) {
+            var _this = this;
+
+            var callback = function callback() {
+                if (container.childNodes.length) {
+                    container.childNodes.forEach(function (child) {
+                        if (child instanceof _TextContainer2.default) {
+                            var style = child.parent.style;
+                            _this.target.renderTextNode(child.bounds, style.color, style.font, style.textDecoration, style.textShadow);
+                        } else {
+                            _this.target.drawShape(child, container.style.color);
+                        }
+                    });
+                }
+
+                if (container.image) {
+                    var _image = _this.options.imageStore.get(container.image);
+                    if (_image) {
+                        var contentBox = (0, _Bounds.calculateContentBox)(container.bounds, container.style.padding, container.style.border);
+                        var _width = typeof _image.width === 'number' && _image.width > 0 ? _image.width : contentBox.width;
+                        var _height = typeof _image.height === 'number' && _image.height > 0 ? _image.height : contentBox.height;
+                        if (_width > 0 && _height > 0) {
+                            _this.target.clip([(0, _Bounds.calculatePaddingBoxPath)(container.curvedBounds)], function () {
+                                _this.target.drawImage(_image, new _Bounds.Bounds(0, 0, _width, _height), contentBox);
+                            });
+                        }
+                    }
+                }
+            };
+            var paths = container.getClipPaths();
+            if (paths.length) {
+                this.target.clip(paths, callback);
+            } else {
+                callback();
+            }
+        }
+    }, {
+        key: 'renderNodeBackgroundAndBorders',
+        value: function renderNodeBackgroundAndBorders(container) {
+            var _this2 = this;
+
+            var HAS_BACKGROUND = !container.style.background.backgroundColor.isTransparent() || container.style.background.backgroundImage.length;
+
+            var hasRenderableBorders = container.style.border.some(function (border) {
+                return border.borderStyle !== _border.BORDER_STYLE.NONE && !border.borderColor.isTransparent();
+            });
+
+            var callback = function callback() {
+                var backgroundPaintingArea = (0, _background.calculateBackgroungPaintingArea)(container.curvedBounds, container.style.background.backgroundClip);
+
+                if (HAS_BACKGROUND) {
+                    _this2.target.clip([backgroundPaintingArea], function () {
+                        if (!container.style.background.backgroundColor.isTransparent()) {
+                            _this2.target.fill(container.style.background.backgroundColor);
+                        }
+
+                        _this2.renderBackgroundImage(container);
+                    });
+                }
+
+                container.style.border.forEach(function (border, side) {
+                    if (border.borderStyle !== _border.BORDER_STYLE.NONE && !border.borderColor.isTransparent()) {
+                        _this2.renderBorder(border, side, container.curvedBounds);
+                    }
+                });
+            };
+
+            if (HAS_BACKGROUND || hasRenderableBorders) {
+                var paths = container.parent ? container.parent.getClipPaths() : [];
+                if (paths.length) {
+                    this.target.clip(paths, callback);
+                } else {
+                    callback();
+                }
+            }
+        }
+    }, {
+        key: 'renderBackgroundImage',
+        value: function renderBackgroundImage(container) {
+            var _this3 = this;
+
+            container.style.background.backgroundImage.slice(0).reverse().forEach(function (backgroundImage) {
+                if (backgroundImage.source.method === 'url' && backgroundImage.source.args.length) {
+                    _this3.renderBackgroundRepeat(container, backgroundImage);
+                } else if (/gradient/i.test(backgroundImage.source.method)) {
+                    _this3.renderBackgroundGradient(container, backgroundImage);
+                }
+            });
+        }
+    }, {
+        key: 'renderBackgroundRepeat',
+        value: function renderBackgroundRepeat(container, background) {
+            var image = this.options.imageStore.get(background.source.args[0]);
+            if (image) {
+                var backgroundPositioningArea = (0, _background.calculateBackgroungPositioningArea)(container.style.background.backgroundOrigin, container.bounds, container.style.padding, container.style.border);
+                var backgroundImageSize = (0, _background.calculateBackgroundSize)(background, image, backgroundPositioningArea);
+                var position = (0, _background.calculateBackgroundPosition)(background.position, backgroundImageSize, backgroundPositioningArea);
+                var _path = (0, _background.calculateBackgroundRepeatPath)(background, position, backgroundImageSize, backgroundPositioningArea, container.bounds);
+
+                var _offsetX = Math.round(backgroundPositioningArea.left + position.x);
+                var _offsetY = Math.round(backgroundPositioningArea.top + position.y);
+                this.target.renderRepeat(_path, image, backgroundImageSize, _offsetX, _offsetY);
+            }
+        }
+    }, {
+        key: 'renderBackgroundGradient',
+        value: function renderBackgroundGradient(container, background) {
+            var backgroundPositioningArea = (0, _background.calculateBackgroungPositioningArea)(container.style.background.backgroundOrigin, container.bounds, container.style.padding, container.style.border);
+            var backgroundImageSize = (0, _background.calculateGradientBackgroundSize)(background, backgroundPositioningArea);
+            var position = (0, _background.calculateBackgroundPosition)(background.position, backgroundImageSize, backgroundPositioningArea);
+            var gradientBounds = new _Bounds.Bounds(Math.round(backgroundPositioningArea.left + position.x), Math.round(backgroundPositioningArea.top + position.y), backgroundImageSize.width, backgroundImageSize.height);
+
+            var gradient = (0, _Gradient.parseGradient)(container, background.source, gradientBounds);
+            if (gradient) {
+                switch (gradient.type) {
+                    case _Gradient.GRADIENT_TYPE.LINEAR_GRADIENT:
+                        // $FlowFixMe
+                        this.target.renderLinearGradient(gradientBounds, gradient);
+                        break;
+                    case _Gradient.GRADIENT_TYPE.RADIAL_GRADIENT:
+                        // $FlowFixMe
+                        this.target.renderRadialGradient(gradientBounds, gradient);
+                        break;
+                }
+            }
+        }
+    }, {
+        key: 'renderBorder',
+        value: function renderBorder(border, side, curvePoints) {
+            this.target.drawShape((0, _Bounds.parsePathForBorder)(curvePoints, side), border.borderColor);
+        }
+    }, {
+        key: 'renderStack',
+        value: function renderStack(stack) {
+            var _this4 = this;
+
+            if (stack.container.isVisible()) {
+                var _opacity = stack.getOpacity();
+                if (_opacity !== this._opacity) {
+                    this.target.setOpacity(stack.getOpacity());
+                    this._opacity = _opacity;
+                }
+
+                var _transform = stack.container.style.transform;
+                if (_transform !== null) {
+                    this.target.transform(stack.container.bounds.left + _transform.transformOrigin[0].value, stack.container.bounds.top + _transform.transformOrigin[1].value, _transform.transform, function () {
+                        return _this4.renderStackContent(stack);
+                    });
+                } else {
+                    this.renderStackContent(stack);
+                }
+            }
+        }
+    }, {
+        key: 'renderStackContent',
+        value: function renderStackContent(stack) {
+            var _splitStackingContext = splitStackingContexts(stack),
+                _splitStackingContext2 = _slicedToArray(_splitStackingContext, 5),
+                negativeZIndex = _splitStackingContext2[0],
+                zeroOrAutoZIndexOrTransformedOrOpacity = _splitStackingContext2[1],
+                positiveZIndex = _splitStackingContext2[2],
+                nonPositionedFloats = _splitStackingContext2[3],
+                nonPositionedInlineLevel = _splitStackingContext2[4];
+
+            var _splitDescendants = splitDescendants(stack),
+                _splitDescendants2 = _slicedToArray(_splitDescendants, 2),
+                inlineLevel = _splitDescendants2[0],
+                nonInlineLevel = _splitDescendants2[1];
+
+            // https://www.w3.org/TR/css-position-3/#painting-order
+            // 1. the background and borders of the element forming the stacking context.
+
+
+            this.renderNodeBackgroundAndBorders(stack.container);
+            // 2. the child stacking contexts with negative stack levels (most negative first).
+            negativeZIndex.sort(sortByZIndex).forEach(this.renderStack, this);
+            // 3. For all its in-flow, non-positioned, block-level descendants in tree order:
+            this.renderNodeContent(stack.container);
+            nonInlineLevel.forEach(this.renderNode, this);
+            // 4. All non-positioned floating descendants, in tree order. For each one of these,
+            // treat the element as if it created a new stacking context, but any positioned descendants and descendants
+            // which actually create a new stacking context should be considered part of the parent stacking context,
+            // not this new one.
+            nonPositionedFloats.forEach(this.renderStack, this);
+            // 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
+            nonPositionedInlineLevel.forEach(this.renderStack, this);
+            inlineLevel.forEach(this.renderNode, this);
+            // 6. All positioned, opacity or transform descendants, in tree order that fall into the following categories:
+            //  All positioned descendants with 'z-index: auto' or 'z-index: 0', in tree order.
+            //  For those with 'z-index: auto', treat the element as if it created a new stacking context,
+            //  but any positioned descendants and descendants which actually create a new stacking context should be
+            //  considered part of the parent stacking context, not this new one. For those with 'z-index: 0',
+            //  treat the stacking context generated atomically.
+            //
+            //  All opacity descendants with opacity less than 1
+            //
+            //  All transform descendants with transform other than none
+            zeroOrAutoZIndexOrTransformedOrOpacity.forEach(this.renderStack, this);
+            // 7. Stacking contexts formed by positioned descendants with z-indices greater than or equal to 1 in z-index
+            // order (smallest first) then tree order.
+            positiveZIndex.sort(sortByZIndex).forEach(this.renderStack, this);
+        }
+    }, {
+        key: 'render',
+        value: function render(stack) {
+            var _this5 = this;
+
+            if (this.options.backgroundColor) {
+                this.target.rectangle(this.options.x, this.options.y, this.options.width, this.options.height, this.options.backgroundColor);
+            }
+            this.renderStack(stack);
+            var target = this.target.getTarget();
+            if (true) {
+                return target.then(function (output) {
+                    _this5.options.logger.log('Render completed');
+                    return output;
+                });
+            }
+            return target;
+        }
+    }]);
+
+    return Renderer;
+}();
+
+exports.default = Renderer;
+
+
+var splitDescendants = function splitDescendants(stack) {
+    var inlineLevel = [];
+    var nonInlineLevel = [];
+
+    var length = stack.children.length;
+    for (var i = 0; i < length; i++) {
+        var child = stack.children[i];
+        if (child.isInlineLevel()) {
+            inlineLevel.push(child);
+        } else {
+            nonInlineLevel.push(child);
+        }
+    }
+    return [inlineLevel, nonInlineLevel];
+};
+
+var splitStackingContexts = function splitStackingContexts(stack) {
+    var negativeZIndex = [];
+    var zeroOrAutoZIndexOrTransformedOrOpacity = [];
+    var positiveZIndex = [];
+    var nonPositionedFloats = [];
+    var nonPositionedInlineLevel = [];
+    var length = stack.contexts.length;
+    for (var i = 0; i < length; i++) {
+        var child = stack.contexts[i];
+        if (child.container.isPositioned() || child.container.style.opacity < 1 || child.container.isTransformed()) {
+            if (child.container.style.zIndex.order < 0) {
+                negativeZIndex.push(child);
+            } else if (child.container.style.zIndex.order > 0) {
+                positiveZIndex.push(child);
+            } else {
+                zeroOrAutoZIndexOrTransformedOrOpacity.push(child);
+            }
+        } else {
+            if (child.container.isFloating()) {
+                nonPositionedFloats.push(child);
+            } else {
+                nonPositionedInlineLevel.push(child);
+            }
+        }
+    }
+    return [negativeZIndex, zeroOrAutoZIndexOrTransformedOrOpacity, positiveZIndex, nonPositionedFloats, nonPositionedInlineLevel];
+};
+
+var sortByZIndex = function sortByZIndex(a, b) {
+    if (a.container.style.zIndex.order > b.container.style.zIndex.order) {
+        return 1;
+    } else if (a.container.style.zIndex.order < b.container.style.zIndex.order) {
+        return -1;
+    }
+
+    return a.container.index > b.container.index ? 1 : -1;
+};
+
+/***/ }),
+/* 52 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.transformWebkitRadialGradientArgs = exports.parseGradient = exports.RadialGradient = exports.LinearGradient = exports.RADIAL_GRADIENT_SHAPE = exports.GRADIENT_TYPE = undefined;
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var _NodeContainer = __webpack_require__(3);
+
+var _NodeContainer2 = _interopRequireDefault(_NodeContainer);
+
+var _Angle = __webpack_require__(53);
+
+var _Color = __webpack_require__(0);
+
+var _Color2 = _interopRequireDefault(_Color);
+
+var _Length = __webpack_require__(1);
+
+var _Length2 = _interopRequireDefault(_Length);
+
+var _Util = __webpack_require__(4);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var SIDE_OR_CORNER = /^(to )?(left|top|right|bottom)( (left|top|right|bottom))?$/i;
+var PERCENTAGE_ANGLES = /^([+-]?\d*\.?\d+)% ([+-]?\d*\.?\d+)%$/i;
+var ENDS_WITH_LENGTH = /(px)|%|( 0)$/i;
+var FROM_TO_COLORSTOP = /^(from|to|color-stop)\((?:([\d.]+)(%)?,\s*)?(.+?)\)$/i;
+var RADIAL_SHAPE_DEFINITION = /^\s*(circle|ellipse)?\s*((?:([\d.]+)(px|r?em|%)\s*(?:([\d.]+)(px|r?em|%))?)|closest-side|closest-corner|farthest-side|farthest-corner)?\s*(?:at\s*(?:(left|center|right)|([\d.]+)(px|r?em|%))\s+(?:(top|center|bottom)|([\d.]+)(px|r?em|%)))?(?:\s|$)/i;
+
+var GRADIENT_TYPE = exports.GRADIENT_TYPE = {
+    LINEAR_GRADIENT: 0,
+    RADIAL_GRADIENT: 1
+};
+
+var RADIAL_GRADIENT_SHAPE = exports.RADIAL_GRADIENT_SHAPE = {
+    CIRCLE: 0,
+    ELLIPSE: 1
+};
+
+var LENGTH_FOR_POSITION = {
+    left: new _Length2.default('0%'),
+    top: new _Length2.default('0%'),
+    center: new _Length2.default('50%'),
+    right: new _Length2.default('100%'),
+    bottom: new _Length2.default('100%')
+};
+
+var LinearGradient = exports.LinearGradient = function LinearGradient(colorStops, direction) {
+    _classCallCheck(this, LinearGradient);
+
+    this.type = GRADIENT_TYPE.LINEAR_GRADIENT;
+    this.colorStops = colorStops;
+    this.direction = direction;
+};
+
+var RadialGradient = exports.RadialGradient = function RadialGradient(colorStops, shape, center, radius) {
+    _classCallCheck(this, RadialGradient);
+
+    this.type = GRADIENT_TYPE.RADIAL_GRADIENT;
+    this.colorStops = colorStops;
+    this.shape = shape;
+    this.center = center;
+    this.radius = radius;
+};
+
+var parseGradient = exports.parseGradient = function parseGradient(container, _ref, bounds) {
+    var args = _ref.args,
+        method = _ref.method,
+        prefix = _ref.prefix;
+
+    if (method === 'linear-gradient') {
+        return parseLinearGradient(args, bounds, !!prefix);
+    } else if (method === 'gradient' && args[0] === 'linear') {
+        // TODO handle correct angle
+        return parseLinearGradient(['to bottom'].concat(transformObsoleteColorStops(args.slice(3))), bounds, !!prefix);
+    } else if (method === 'radial-gradient') {
+        return parseRadialGradient(container, prefix === '-webkit-' ? transformWebkitRadialGradientArgs(args) : args, bounds);
+    } else if (method === 'gradient' && args[0] === 'radial') {
+        return parseRadialGradient(container, transformObsoleteColorStops(transformWebkitRadialGradientArgs(args.slice(1))), bounds);
+    }
+};
+
+var parseColorStops = function parseColorStops(args, firstColorStopIndex, lineLength) {
+    var colorStops = [];
+
+    for (var i = firstColorStopIndex; i < args.length; i++) {
+        var value = args[i];
+        var HAS_LENGTH = ENDS_WITH_LENGTH.test(value);
+        var lastSpaceIndex = value.lastIndexOf(' ');
+        var _color = new _Color2.default(HAS_LENGTH ? value.substring(0, lastSpaceIndex) : value);
+        var _stop = HAS_LENGTH ? new _Length2.default(value.substring(lastSpaceIndex + 1)) : i === firstColorStopIndex ? new _Length2.default('0%') : i === args.length - 1 ? new _Length2.default('100%') : null;
+        colorStops.push({ color: _color, stop: _stop });
+    }
+
+    var absoluteValuedColorStops = colorStops.map(function (_ref2) {
+        var color = _ref2.color,
+            stop = _ref2.stop;
+
+        var absoluteStop = lineLength === 0 ? 0 : stop ? stop.getAbsoluteValue(lineLength) / lineLength : null;
+
+        return {
+            color: color,
+            // $FlowFixMe
+            stop: absoluteStop
+        };
+    });
+
+    var previousColorStop = absoluteValuedColorStops[0].stop;
+    for (var _i = 0; _i < absoluteValuedColorStops.length; _i++) {
+        if (previousColorStop !== null) {
+            var _stop2 = absoluteValuedColorStops[_i].stop;
+            if (_stop2 === null) {
+                var n = _i;
+                while (absoluteValuedColorStops[n].stop === null) {
+                    n++;
+                }
+                var steps = n - _i + 1;
+                var nextColorStep = absoluteValuedColorStops[n].stop;
+                var stepSize = (nextColorStep - previousColorStop) / steps;
+                for (; _i < n; _i++) {
+                    previousColorStop = absoluteValuedColorStops[_i].stop = previousColorStop + stepSize;
+                }
+            } else {
+                previousColorStop = _stop2;
+            }
+        }
+    }
+
+    return absoluteValuedColorStops;
+};
+
+var parseLinearGradient = function parseLinearGradient(args, bounds, hasPrefix) {
+    var angle = (0, _Angle.parseAngle)(args[0]);
+    var HAS_SIDE_OR_CORNER = SIDE_OR_CORNER.test(args[0]);
+    var HAS_DIRECTION = HAS_SIDE_OR_CORNER || angle !== null || PERCENTAGE_ANGLES.test(args[0]);
+    var direction = HAS_DIRECTION ? angle !== null ? calculateGradientDirection(
+    // if there is a prefix, the 0° angle points due East (instead of North per W3C)
+    hasPrefix ? angle - Math.PI * 0.5 : angle, bounds) : HAS_SIDE_OR_CORNER ? parseSideOrCorner(args[0], bounds) : parsePercentageAngle(args[0], bounds) : calculateGradientDirection(Math.PI, bounds);
+    var firstColorStopIndex = HAS_DIRECTION ? 1 : 0;
+
+    // TODO: Fix some inaccuracy with color stops with px values
+    var lineLength = Math.min((0, _Util.distance)(Math.abs(direction.x0) + Math.abs(direction.x1), Math.abs(direction.y0) + Math.abs(direction.y1)), bounds.width * 2, bounds.height * 2);
+
+    return new LinearGradient(parseColorStops(args, firstColorStopIndex, lineLength), direction);
+};
+
+var parseRadialGradient = function parseRadialGradient(container, args, bounds) {
+    var m = args[0].match(RADIAL_SHAPE_DEFINITION);
+    var shape = m && (m[1] === 'circle' || // explicit shape specification
+    m[3] !== undefined && m[5] === undefined) // only one radius coordinate
+    ? RADIAL_GRADIENT_SHAPE.CIRCLE : RADIAL_GRADIENT_SHAPE.ELLIPSE;
+    var radius = {};
+    var center = {};
+
+    if (m) {
+        // Radius
+        if (m[3] !== undefined) {
+            radius.x = (0, _Length.calculateLengthFromValueWithUnit)(container, m[3], m[4]).getAbsoluteValue(bounds.width);
+        }
+
+        if (m[5] !== undefined) {
+            radius.y = (0, _Length.calculateLengthFromValueWithUnit)(container, m[5], m[6]).getAbsoluteValue(bounds.height);
+        }
+
+        // Position
+        if (m[7]) {
+            center.x = LENGTH_FOR_POSITION[m[7].toLowerCase()];
+        } else if (m[8] !== undefined) {
+            center.x = (0, _Length.calculateLengthFromValueWithUnit)(container, m[8], m[9]);
+        }
+
+        if (m[10]) {
+            center.y = LENGTH_FOR_POSITION[m[10].toLowerCase()];
+        } else if (m[11] !== undefined) {
+            center.y = (0, _Length.calculateLengthFromValueWithUnit)(container, m[11], m[12]);
+        }
+    }
+
+    var gradientCenter = {
+        x: center.x === undefined ? bounds.width / 2 : center.x.getAbsoluteValue(bounds.width),
+        y: center.y === undefined ? bounds.height / 2 : center.y.getAbsoluteValue(bounds.height)
+    };
+    var gradientRadius = calculateRadius(m && m[2] || 'farthest-corner', shape, gradientCenter, radius, bounds);
+
+    return new RadialGradient(parseColorStops(args, m ? 1 : 0, Math.min(gradientRadius.x, gradientRadius.y)), shape, gradientCenter, gradientRadius);
+};
+
+var calculateGradientDirection = function calculateGradientDirection(radian, bounds) {
+    var width = bounds.width;
+    var height = bounds.height;
+    var HALF_WIDTH = width * 0.5;
+    var HALF_HEIGHT = height * 0.5;
+    var lineLength = Math.abs(width * Math.sin(radian)) + Math.abs(height * Math.cos(radian));
+    var HALF_LINE_LENGTH = lineLength / 2;
+
+    var x0 = HALF_WIDTH + Math.sin(radian) * HALF_LINE_LENGTH;
+    var y0 = HALF_HEIGHT - Math.cos(radian) * HALF_LINE_LENGTH;
+    var x1 = width - x0;
+    var y1 = height - y0;
+
+    return { x0: x0, x1: x1, y0: y0, y1: y1 };
+};
+
+var parseTopRight = function parseTopRight(bounds) {
+    return Math.acos(bounds.width / 2 / ((0, _Util.distance)(bounds.width, bounds.height) / 2));
+};
+
+var parseSideOrCorner = function parseSideOrCorner(side, bounds) {
+    switch (side) {
+        case 'bottom':
+        case 'to top':
+            return calculateGradientDirection(0, bounds);
+        case 'left':
+        case 'to right':
+            return calculateGradientDirection(Math.PI / 2, bounds);
+        case 'right':
+        case 'to left':
+            return calculateGradientDirection(3 * Math.PI / 2, bounds);
+        case 'top right':
+        case 'right top':
+        case 'to bottom left':
+        case 'to left bottom':
+            return calculateGradientDirection(Math.PI + parseTopRight(bounds), bounds);
+        case 'top left':
+        case 'left top':
+        case 'to bottom right':
+        case 'to right bottom':
+            return calculateGradientDirection(Math.PI - parseTopRight(bounds), bounds);
+        case 'bottom left':
+        case 'left bottom':
+        case 'to top right':
+        case 'to right top':
+            return calculateGradientDirection(parseTopRight(bounds), bounds);
+        case 'bottom right':
+        case 'right bottom':
+        case 'to top left':
+        case 'to left top':
+            return calculateGradientDirection(2 * Math.PI - parseTopRight(bounds), bounds);
+        case 'top':
+        case 'to bottom':
+        default:
+            return calculateGradientDirection(Math.PI, bounds);
+    }
+};
+
+var parsePercentageAngle = function parsePercentageAngle(angle, bounds) {
+    var _angle$split$map = angle.split(' ').map(parseFloat),
+        _angle$split$map2 = _slicedToArray(_angle$split$map, 2),
+        left = _angle$split$map2[0],
+        top = _angle$split$map2[1];
+
+    var ratio = left / 100 * bounds.width / (top / 100 * bounds.height);
+
+    return calculateGradientDirection(Math.atan(isNaN(ratio) ? 1 : ratio) + Math.PI / 2, bounds);
+};
+
+var findCorner = function findCorner(bounds, x, y, closest) {
+    var corners = [{ x: 0, y: 0 }, { x: 0, y: bounds.height }, { x: bounds.width, y: 0 }, { x: bounds.width, y: bounds.height }];
+
+    // $FlowFixMe
+    return corners.reduce(function (stat, corner) {
+        var d = (0, _Util.distance)(x - corner.x, y - corner.y);
+        if (closest ? d < stat.optimumDistance : d > stat.optimumDistance) {
+            return {
+                optimumCorner: corner,
+                optimumDistance: d
+            };
+        }
+
+        return stat;
+    }, {
+        optimumDistance: closest ? Infinity : -Infinity,
+        optimumCorner: null
+    }).optimumCorner;
+};
+
+var calculateRadius = function calculateRadius(extent, shape, center, radius, bounds) {
+    var x = center.x;
+    var y = center.y;
+    var rx = 0;
+    var ry = 0;
+
+    switch (extent) {
+        case 'closest-side':
+            // The ending shape is sized so that that it exactly meets the side of the gradient box closest to the gradient’s center.
+            // If the shape is an ellipse, it exactly meets the closest side in each dimension.
+            if (shape === RADIAL_GRADIENT_SHAPE.CIRCLE) {
+                rx = ry = Math.min(Math.abs(x), Math.abs(x - bounds.width), Math.abs(y), Math.abs(y - bounds.height));
+            } else if (shape === RADIAL_GRADIENT_SHAPE.ELLIPSE) {
+                rx = Math.min(Math.abs(x), Math.abs(x - bounds.width));
+                ry = Math.min(Math.abs(y), Math.abs(y - bounds.height));
+            }
+            break;
+
+        case 'closest-corner':
+            // The ending shape is sized so that that it passes through the corner of the gradient box closest to the gradient’s center.
+            // If the shape is an ellipse, the ending shape is given the same aspect-ratio it would have if closest-side were specified.
+            if (shape === RADIAL_GRADIENT_SHAPE.CIRCLE) {
+                rx = ry = Math.min((0, _Util.distance)(x, y), (0, _Util.distance)(x, y - bounds.height), (0, _Util.distance)(x - bounds.width, y), (0, _Util.distance)(x - bounds.width, y - bounds.height));
+            } else if (shape === RADIAL_GRADIENT_SHAPE.ELLIPSE) {
+                // Compute the ratio ry/rx (which is to be the same as for "closest-side")
+                var c = Math.min(Math.abs(y), Math.abs(y - bounds.height)) / Math.min(Math.abs(x), Math.abs(x - bounds.width));
+                var corner = findCorner(bounds, x, y, true);
+                rx = (0, _Util.distance)(corner.x - x, (corner.y - y) / c);
+                ry = c * rx;
+            }
+            break;
+
+        case 'farthest-side':
+            // Same as closest-side, except the ending shape is sized based on the farthest side(s)
+            if (shape === RADIAL_GRADIENT_SHAPE.CIRCLE) {
+                rx = ry = Math.max(Math.abs(x), Math.abs(x - bounds.width), Math.abs(y), Math.abs(y - bounds.height));
+            } else if (shape === RADIAL_GRADIENT_SHAPE.ELLIPSE) {
+                rx = Math.max(Math.abs(x), Math.abs(x - bounds.width));
+                ry = Math.max(Math.abs(y), Math.abs(y - bounds.height));
+            }
+            break;
+
+        case 'farthest-corner':
+            // Same as closest-corner, except the ending shape is sized based on the farthest corner.
+            // If the shape is an ellipse, the ending shape is given the same aspect ratio it would have if farthest-side were specified.
+            if (shape === RADIAL_GRADIENT_SHAPE.CIRCLE) {
+                rx = ry = Math.max((0, _Util.distance)(x, y), (0, _Util.distance)(x, y - bounds.height), (0, _Util.distance)(x - bounds.width, y), (0, _Util.distance)(x - bounds.width, y - bounds.height));
+            } else if (shape === RADIAL_GRADIENT_SHAPE.ELLIPSE) {
+                // Compute the ratio ry/rx (which is to be the same as for "farthest-side")
+                var _c = Math.max(Math.abs(y), Math.abs(y - bounds.height)) / Math.max(Math.abs(x), Math.abs(x - bounds.width));
+                var _corner = findCorner(bounds, x, y, false);
+                rx = (0, _Util.distance)(_corner.x - x, (_corner.y - y) / _c);
+                ry = _c * rx;
+            }
+            break;
+
+        default:
+            // pixel or percentage values
+            rx = radius.x || 0;
+            ry = radius.y !== undefined ? radius.y : rx;
+            break;
+    }
+
+    return {
+        x: rx,
+        y: ry
+    };
+};
+
+var transformWebkitRadialGradientArgs = exports.transformWebkitRadialGradientArgs = function transformWebkitRadialGradientArgs(args) {
+    var shape = '';
+    var radius = '';
+    var extent = '';
+    var position = '';
+    var idx = 0;
+
+    var POSITION = /^(left|center|right|\d+(?:px|r?em|%)?)(?:\s+(top|center|bottom|\d+(?:px|r?em|%)?))?$/i;
+    var SHAPE_AND_EXTENT = /^(circle|ellipse)?\s*(closest-side|closest-corner|farthest-side|farthest-corner|contain|cover)?$/i;
+    var RADIUS = /^\d+(px|r?em|%)?(?:\s+\d+(px|r?em|%)?)?$/i;
+
+    var matchStartPosition = args[idx].match(POSITION);
+    if (matchStartPosition) {
+        idx++;
+    }
+
+    var matchShapeExtent = args[idx].match(SHAPE_AND_EXTENT);
+    if (matchShapeExtent) {
+        shape = matchShapeExtent[1] || '';
+        extent = matchShapeExtent[2] || '';
+        if (extent === 'contain') {
+            extent = 'closest-side';
+        } else if (extent === 'cover') {
+            extent = 'farthest-corner';
+        }
+        idx++;
+    }
+
+    var matchStartRadius = args[idx].match(RADIUS);
+    if (matchStartRadius) {
+        idx++;
+    }
+
+    var matchEndPosition = args[idx].match(POSITION);
+    if (matchEndPosition) {
+        idx++;
+    }
+
+    var matchEndRadius = args[idx].match(RADIUS);
+    if (matchEndRadius) {
+        idx++;
+    }
+
+    var matchPosition = matchEndPosition || matchStartPosition;
+    if (matchPosition && matchPosition[1]) {
+        position = matchPosition[1] + (/^\d+$/.test(matchPosition[1]) ? 'px' : '');
+        if (matchPosition[2]) {
+            position += ' ' + matchPosition[2] + (/^\d+$/.test(matchPosition[2]) ? 'px' : '');
+        }
+    }
+
+    var matchRadius = matchEndRadius || matchStartRadius;
+    if (matchRadius) {
+        radius = matchRadius[0];
+        if (!matchRadius[1]) {
+            radius += 'px';
+        }
+    }
+
+    if (position && !shape && !radius && !extent) {
+        radius = position;
+        position = '';
+    }
+
+    if (position) {
+        position = 'at ' + position;
+    }
+
+    return [[shape, extent, radius, position].filter(function (s) {
+        return !!s;
+    }).join(' ')].concat(args.slice(idx));
+};
+
+var transformObsoleteColorStops = function transformObsoleteColorStops(args) {
+    return args.map(function (color) {
+        return color.match(FROM_TO_COLORSTOP);
+    })
+    // $FlowFixMe
+    .map(function (v, index) {
+        if (!v) {
+            return args[index];
+        }
+
+        switch (v[1]) {
+            case 'from':
+                return v[4] + ' 0%';
+            case 'to':
+                return v[4] + ' 100%';
+            case 'color-stop':
+                if (v[3] === '%') {
+                    return v[4] + ' ' + v[2];
+                }
+                return v[4] + ' ' + parseFloat(v[2]) * 100 + '%';
+        }
+    });
+};
+
+/***/ }),
+/* 53 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var ANGLE = /([+-]?\d*\.?\d+)(deg|grad|rad|turn)/i;
+
+var parseAngle = exports.parseAngle = function parseAngle(angle) {
+    var match = angle.match(ANGLE);
+
+    if (match) {
+        var value = parseFloat(match[1]);
+        switch (match[2].toLowerCase()) {
+            case 'deg':
+                return Math.PI * value / 180;
+            case 'grad':
+                return Math.PI / 200 * value;
+            case 'rad':
+                return value;
+            case 'turn':
+                return Math.PI * 2 * value;
+        }
+    }
+
+    return null;
+};
+
+/***/ }),
+/* 54 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.cloneWindow = exports.DocumentCloner = undefined;
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Bounds = __webpack_require__(2);
+
+var _Proxy = __webpack_require__(26);
+
+var _ResourceLoader = __webpack_require__(55);
+
+var _ResourceLoader2 = _interopRequireDefault(_ResourceLoader);
+
+var _Util = __webpack_require__(4);
+
+var _background = __webpack_require__(5);
+
+var _CanvasRenderer = __webpack_require__(15);
+
+var _CanvasRenderer2 = _interopRequireDefault(_CanvasRenderer);
+
+var _PseudoNodeContent = __webpack_require__(56);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var IGNORE_ATTRIBUTE = 'data-html2canvas-ignore';
+
+var DocumentCloner = exports.DocumentCloner = function () {
+    function DocumentCloner(element, options, logger, copyInline, renderer) {
+        _classCallCheck(this, DocumentCloner);
+
+        this.referenceElement = element;
+        this.scrolledElements = [];
+        this.copyStyles = copyInline;
+        this.inlineImages = copyInline;
+        this.logger = logger;
+        this.options = options;
+        this.renderer = renderer;
+        this.resourceLoader = new _ResourceLoader2.default(options, logger, window);
+        this.pseudoContentData = {
+            counters: {},
+            quoteDepth: 0
+        };
+        // $FlowFixMe
+        this.documentElement = this.cloneNode(element.ownerDocument.documentElement);
+    }
+
+    _createClass(DocumentCloner, [{
+        key: 'inlineAllImages',
+        value: function inlineAllImages(node) {
+            var _this = this;
+
+            if (this.inlineImages && node) {
+                var style = node.style;
+                Promise.all((0, _background.parseBackgroundImage)(style.backgroundImage).map(function (backgroundImage) {
+                    if (backgroundImage.method === 'url') {
+                        return _this.resourceLoader.inlineImage(backgroundImage.args[0]).then(function (img) {
+                            return img && typeof img.src === 'string' ? 'url("' + img.src + '")' : 'none';
+                        }).catch(function (e) {
+                            if (true) {
+                                _this.logger.log('Unable to load image', e);
+                            }
+                        });
+                    }
+                    return Promise.resolve('' + backgroundImage.prefix + backgroundImage.method + '(' + backgroundImage.args.join(',') + ')');
+                })).then(function (backgroundImages) {
+                    if (backgroundImages.length > 1) {
+                        // TODO Multiple backgrounds somehow broken in Chrome
+                        style.backgroundColor = '';
+                    }
+                    style.backgroundImage = backgroundImages.join(',');
+                });
+
+                if (node instanceof HTMLImageElement) {
+                    this.resourceLoader.inlineImage(node.src).then(function (img) {
+                        if (img && node instanceof HTMLImageElement && node.parentNode) {
+                            var parentNode = node.parentNode;
+                            var clonedChild = (0, _Util.copyCSSStyles)(node.style, img.cloneNode(false));
+                            parentNode.replaceChild(clonedChild, node);
+                        }
+                    }).catch(function (e) {
+                        if (true) {
+                            _this.logger.log('Unable to load image', e);
+                        }
+                    });
+                }
+            }
+        }
+    }, {
+        key: 'inlineFonts',
+        value: function inlineFonts(document) {
+            var _this2 = this;
+
+            return Promise.all(Array.from(document.styleSheets).map(function (sheet) {
+                if (sheet.href) {
+                    return fetch(sheet.href).then(function (res) {
+                        return res.text();
+                    }).then(function (text) {
+                        return createStyleSheetFontsFromText(text, sheet.href);
+                    }).catch(function (e) {
+                        if (true) {
+                            _this2.logger.log('Unable to load stylesheet', e);
+                        }
+                        return [];
+                    });
+                }
+                return getSheetFonts(sheet, document);
+            })).then(function (fonts) {
+                return fonts.reduce(function (acc, font) {
+                    return acc.concat(font);
+                }, []);
+            }).then(function (fonts) {
+                return Promise.all(fonts.map(function (font) {
+                    return fetch(font.formats[0].src).then(function (response) {
+                        return response.blob();
+                    }).then(function (blob) {
+                        return new Promise(function (resolve, reject) {
+                            var reader = new FileReader();
+                            reader.onerror = reject;
+                            reader.onload = function () {
+                                // $FlowFixMe
+                                var result = reader.result;
+                                resolve(result);
+                            };
+                            reader.readAsDataURL(blob);
+                        });
+                    }).then(function (dataUri) {
+                        font.fontFace.setProperty('src', 'url("' + dataUri + '")');
+                        return '@font-face {' + font.fontFace.cssText + ' ';
+                    });
+                }));
+            }).then(function (fontCss) {
+                var style = document.createElement('style');
+                style.textContent = fontCss.join('\n');
+                _this2.documentElement.appendChild(style);
+            });
+        }
+    }, {
+        key: 'createElementClone',
+        value: function createElementClone(node) {
+            var _this3 = this;
+
+            if (this.copyStyles && node instanceof HTMLCanvasElement) {
+                var img = node.ownerDocument.createElement('img');
+                try {
+                    img.src = node.toDataURL();
+                    return img;
+                } catch (e) {
+                    if (true) {
+                        this.logger.log('Unable to clone canvas contents, canvas is tainted');
+                    }
+                }
+            }
+
+            if (node instanceof HTMLIFrameElement) {
+                var tempIframe = node.cloneNode(false);
+                var iframeKey = generateIframeKey();
+                tempIframe.setAttribute('data-html2canvas-internal-iframe-key', iframeKey);
+
+                var _parseBounds = (0, _Bounds.parseBounds)(node, 0, 0),
+                    width = _parseBounds.width,
+                    height = _parseBounds.height;
+
+                this.resourceLoader.cache[iframeKey] = getIframeDocumentElement(node, this.options).then(function (documentElement) {
+                    return _this3.renderer(documentElement, {
+                        async: _this3.options.async,
+                        allowTaint: _this3.options.allowTaint,
+                        backgroundColor: '#ffffff',
+                        canvas: null,
+                        imageTimeout: _this3.options.imageTimeout,
+                        logging: _this3.options.logging,
+                        proxy: _this3.options.proxy,
+                        removeContainer: _this3.options.removeContainer,
+                        scale: _this3.options.scale,
+                        foreignObjectRendering: _this3.options.foreignObjectRendering,
+                        useCORS: _this3.options.useCORS,
+                        target: new _CanvasRenderer2.default(),
+                        width: width,
+                        height: height,
+                        x: 0,
+                        y: 0,
+                        windowWidth: documentElement.ownerDocument.defaultView.innerWidth,
+                        windowHeight: documentElement.ownerDocument.defaultView.innerHeight,
+                        scrollX: documentElement.ownerDocument.defaultView.pageXOffset,
+                        scrollY: documentElement.ownerDocument.defaultView.pageYOffset
+                    }, _this3.logger.child(iframeKey));
+                }).then(function (canvas) {
+                    return new Promise(function (resolve, reject) {
+                        var iframeCanvas = document.createElement('img');
+                        iframeCanvas.onload = function () {
+                            return resolve(canvas);
+                        };
+                        iframeCanvas.onerror = reject;
+                        iframeCanvas.src = canvas.toDataURL();
+                        if (tempIframe.parentNode) {
+                            tempIframe.parentNode.replaceChild((0, _Util.copyCSSStyles)(node.ownerDocument.defaultView.getComputedStyle(node), iframeCanvas), tempIframe);
+                        }
+                    });
+                });
+                return tempIframe;
+            }
+
+            if (node instanceof HTMLStyleElement && node.sheet && node.sheet.cssRules) {
+                var css = [].slice.call(node.sheet.cssRules, 0).reduce(function (css, rule) {
+                    try {
+                        if (rule && rule.cssText) {
+                            return css + rule.cssText;
+                        }
+                        return css;
+                    } catch (err) {
+                        _this3.logger.log('Unable to access cssText property', rule.name);
+                        return css;
+                    }
+                }, '');
+                var style = node.cloneNode(false);
+                style.textContent = css;
+                return style;
+            }
+
+            return node.cloneNode(false);
+        }
+    }, {
+        key: 'cloneNode',
+        value: function cloneNode(node) {
+            var clone = node.nodeType === Node.TEXT_NODE ? document.createTextNode(node.nodeValue) : this.createElementClone(node);
+
+            var window = node.ownerDocument.defaultView;
+            var style = node instanceof window.HTMLElement ? window.getComputedStyle(node) : null;
+            var styleBefore = node instanceof window.HTMLElement ? window.getComputedStyle(node, ':before') : null;
+            var styleAfter = node instanceof window.HTMLElement ? window.getComputedStyle(node, ':after') : null;
+
+            if (this.referenceElement === node && clone instanceof window.HTMLElement) {
+                this.clonedReferenceElement = clone;
+            }
+
+            if (clone instanceof window.HTMLBodyElement) {
+                createPseudoHideStyles(clone);
+            }
+
+            var counters = (0, _PseudoNodeContent.parseCounterReset)(style, this.pseudoContentData);
+            var contentBefore = (0, _PseudoNodeContent.resolvePseudoContent)(node, styleBefore, this.pseudoContentData);
+
+            for (var child = node.firstChild; child; child = child.nextSibling) {
+                if (child.nodeType !== Node.ELEMENT_NODE || child.nodeName !== 'SCRIPT' &&
+                // $FlowFixMe
+                !child.hasAttribute(IGNORE_ATTRIBUTE) && (typeof this.options.ignoreElements !== 'function' ||
+                // $FlowFixMe
+                !this.options.ignoreElements(child))) {
+                    if (!this.copyStyles || child.nodeName !== 'STYLE') {
+                        clone.appendChild(this.cloneNode(child));
+                    }
+                }
+            }
+
+            var contentAfter = (0, _PseudoNodeContent.resolvePseudoContent)(node, styleAfter, this.pseudoContentData);
+            (0, _PseudoNodeContent.popCounters)(counters, this.pseudoContentData);
+
+            if (node instanceof window.HTMLElement && clone instanceof window.HTMLElement) {
+                if (styleBefore) {
+                    this.inlineAllImages(inlinePseudoElement(node, clone, styleBefore, contentBefore, PSEUDO_BEFORE));
+                }
+                if (styleAfter) {
+                    this.inlineAllImages(inlinePseudoElement(node, clone, styleAfter, contentAfter, PSEUDO_AFTER));
+                }
+                if (style && this.copyStyles && !(node instanceof HTMLIFrameElement)) {
+                    (0, _Util.copyCSSStyles)(style, clone);
+                }
+                this.inlineAllImages(clone);
+                if (node.scrollTop !== 0 || node.scrollLeft !== 0) {
+                    this.scrolledElements.push([clone, node.scrollLeft, node.scrollTop]);
+                }
+                switch (node.nodeName) {
+                    case 'CANVAS':
+                        if (!this.copyStyles) {
+                            cloneCanvasContents(node, clone);
+                        }
+                        break;
+                    case 'TEXTAREA':
+                    case 'SELECT':
+                        clone.value = node.value;
+                        break;
+                }
+            }
+            return clone;
+        }
+    }]);
+
+    return DocumentCloner;
+}();
+
+var getSheetFonts = function getSheetFonts(sheet, document) {
+    // $FlowFixMe
+    return (sheet.cssRules ? Array.from(sheet.cssRules) : []).filter(function (rule) {
+        return rule.type === CSSRule.FONT_FACE_RULE;
+    }).map(function (rule) {
+        var src = (0, _background.parseBackgroundImage)(rule.style.getPropertyValue('src'));
+        var formats = [];
+        for (var i = 0; i < src.length; i++) {
+            if (src[i].method === 'url' && src[i + 1] && src[i + 1].method === 'format') {
+                var a = document.createElement('a');
+                a.href = src[i].args[0];
+                if (document.body) {
+                    document.body.appendChild(a);
+                }
+
+                var font = {
+                    src: a.href,
+                    format: src[i + 1].args[0]
+                };
+                formats.push(font);
+            }
+        }
+
+        return {
+            // TODO select correct format for browser),
+
+            formats: formats.filter(function (font) {
+                return (/^woff/i.test(font.format)
+                );
+            }),
+            fontFace: rule.style
+        };
+    }).filter(function (font) {
+        return font.formats.length;
+    });
+};
+
+var createStyleSheetFontsFromText = function createStyleSheetFontsFromText(text, baseHref) {
+    var doc = document.implementation.createHTMLDocument('');
+    var base = document.createElement('base');
+    // $FlowFixMe
+    base.href = baseHref;
+    var style = document.createElement('style');
+
+    style.textContent = text;
+    if (doc.head) {
+        doc.head.appendChild(base);
+    }
+    if (doc.body) {
+        doc.body.appendChild(style);
+    }
+
+    return style.sheet ? getSheetFonts(style.sheet, doc) : [];
+};
+
+var restoreOwnerScroll = function restoreOwnerScroll(ownerDocument, x, y) {
+    if (ownerDocument.defaultView && (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset)) {
+        ownerDocument.defaultView.scrollTo(x, y);
+    }
+};
+
+var cloneCanvasContents = function cloneCanvasContents(canvas, clonedCanvas) {
+    try {
+        if (clonedCanvas) {
+            clonedCanvas.width = canvas.width;
+            clonedCanvas.height = canvas.height;
+            var ctx = canvas.getContext('2d');
+            var clonedCtx = clonedCanvas.getContext('2d');
+            if (ctx) {
+                clonedCtx.putImageData(ctx.getImageData(0, 0, canvas.width, canvas.height), 0, 0);
+            } else {
+                clonedCtx.drawImage(canvas, 0, 0);
+            }
+        }
+    } catch (e) {}
+};
+
+var inlinePseudoElement = function inlinePseudoElement(node, clone, style, contentItems, pseudoElt) {
+    if (!style || !style.content || style.content === 'none' || style.content === '-moz-alt-content' || style.display === 'none') {
+        return;
+    }
+
+    var anonymousReplacedElement = clone.ownerDocument.createElement('html2canvaspseudoelement');
+    (0, _Util.copyCSSStyles)(style, anonymousReplacedElement);
+
+    if (contentItems) {
+        var len = contentItems.length;
+        for (var i = 0; i < len; i++) {
+            var item = contentItems[i];
+            switch (item.type) {
+                case _PseudoNodeContent.PSEUDO_CONTENT_ITEM_TYPE.IMAGE:
+                    var img = clone.ownerDocument.createElement('img');
+                    img.src = (0, _background.parseBackgroundImage)('url(' + item.value + ')')[0].args[0];
+                    img.style.opacity = '1';
+                    anonymousReplacedElement.appendChild(img);
+                    break;
+                case _PseudoNodeContent.PSEUDO_CONTENT_ITEM_TYPE.TEXT:
+                    anonymousReplacedElement.appendChild(clone.ownerDocument.createTextNode(item.value));
+                    break;
+            }
+        }
+    }
+
+    anonymousReplacedElement.className = PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + ' ' + PSEUDO_HIDE_ELEMENT_CLASS_AFTER;
+    clone.className += pseudoElt === PSEUDO_BEFORE ? ' ' + PSEUDO_HIDE_ELEMENT_CLASS_BEFORE : ' ' + PSEUDO_HIDE_ELEMENT_CLASS_AFTER;
+    if (pseudoElt === PSEUDO_BEFORE) {
+        clone.insertBefore(anonymousReplacedElement, clone.firstChild);
+    } else {
+        clone.appendChild(anonymousReplacedElement);
+    }
+
+    return anonymousReplacedElement;
+};
+
+var URL_REGEXP = /^url\((.+)\)$/i;
+var PSEUDO_BEFORE = ':before';
+var PSEUDO_AFTER = ':after';
+var PSEUDO_HIDE_ELEMENT_CLASS_BEFORE = '___html2canvas___pseudoelement_before';
+var PSEUDO_HIDE_ELEMENT_CLASS_AFTER = '___html2canvas___pseudoelement_after';
+
+var PSEUDO_HIDE_ELEMENT_STYLE = '{\n    content: "" !important;\n    display: none !important;\n}';
+
+var createPseudoHideStyles = function createPseudoHideStyles(body) {
+    createStyles(body, '.' + PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + PSEUDO_BEFORE + PSEUDO_HIDE_ELEMENT_STYLE + '\n         .' + PSEUDO_HIDE_ELEMENT_CLASS_AFTER + PSEUDO_AFTER + PSEUDO_HIDE_ELEMENT_STYLE);
+};
+
+var createStyles = function createStyles(body, styles) {
+    var style = body.ownerDocument.createElement('style');
+    style.innerHTML = styles;
+    body.appendChild(style);
+};
+
+var initNode = function initNode(_ref) {
+    var _ref2 = _slicedToArray(_ref, 3),
+        element = _ref2[0],
+        x = _ref2[1],
+        y = _ref2[2];
+
+    element.scrollLeft = x;
+    element.scrollTop = y;
+};
+
+var generateIframeKey = function generateIframeKey() {
+    return Math.ceil(Date.now() + Math.random() * 10000000).toString(16);
+};
+
+var DATA_URI_REGEXP = /^data:text\/(.+);(base64)?,(.*)$/i;
+
+var getIframeDocumentElement = function getIframeDocumentElement(node, options) {
+    try {
+        return Promise.resolve(node.contentWindow.document.documentElement);
+    } catch (e) {
+        return options.proxy ? (0, _Proxy.Proxy)(node.src, options).then(function (html) {
+            var match = html.match(DATA_URI_REGEXP);
+            if (!match) {
+                return Promise.reject();
+            }
+
+            return match[2] === 'base64' ? window.atob(decodeURIComponent(match[3])) : decodeURIComponent(match[3]);
+        }).then(function (html) {
+            return createIframeContainer(node.ownerDocument, (0, _Bounds.parseBounds)(node, 0, 0)).then(function (cloneIframeContainer) {
+                var cloneWindow = cloneIframeContainer.contentWindow;
+                var documentClone = cloneWindow.document;
+
+                documentClone.open();
+                documentClone.write(html);
+                var iframeLoad = iframeLoader(cloneIframeContainer).then(function () {
+                    return documentClone.documentElement;
+                });
+
+                documentClone.close();
+                return iframeLoad;
+            });
+        }) : Promise.reject();
+    }
+};
+
+var createIframeContainer = function createIframeContainer(ownerDocument, bounds) {
+    var cloneIframeContainer = ownerDocument.createElement('iframe');
+
+    cloneIframeContainer.className = 'html2canvas-container';
+    cloneIframeContainer.style.visibility = 'hidden';
+    cloneIframeContainer.style.position = 'fixed';
+    cloneIframeContainer.style.left = '-10000px';
+    cloneIframeContainer.style.top = '0px';
+    cloneIframeContainer.style.border = '0';
+    cloneIframeContainer.width = bounds.width.toString();
+    cloneIframeContainer.height = bounds.height.toString();
+    cloneIframeContainer.scrolling = 'no'; // ios won't scroll without it
+    cloneIframeContainer.setAttribute(IGNORE_ATTRIBUTE, 'true');
+    if (!ownerDocument.body) {
+        return Promise.reject( true ? 'Body element not found in Document that is getting rendered' : '');
+    }
+
+    ownerDocument.body.appendChild(cloneIframeContainer);
+
+    return Promise.resolve(cloneIframeContainer);
+};
+
+var iframeLoader = function iframeLoader(cloneIframeContainer) {
+    var cloneWindow = cloneIframeContainer.contentWindow;
+    var documentClone = cloneWindow.document;
+
+    return new Promise(function (resolve, reject) {
+        cloneWindow.onload = cloneIframeContainer.onload = documentClone.onreadystatechange = function () {
+            var interval = setInterval(function () {
+                if (documentClone.body.childNodes.length > 0 && documentClone.readyState === 'complete') {
+                    clearInterval(interval);
+                    resolve(cloneIframeContainer);
+                }
+            }, 50);
+        };
+    });
+};
+
+var cloneWindow = exports.cloneWindow = function cloneWindow(ownerDocument, bounds, referenceElement, options, logger, renderer) {
+    var cloner = new DocumentCloner(referenceElement, options, logger, false, renderer);
+    var scrollX = ownerDocument.defaultView.pageXOffset;
+    var scrollY = ownerDocument.defaultView.pageYOffset;
+
+    return createIframeContainer(ownerDocument, bounds).then(function (cloneIframeContainer) {
+        var cloneWindow = cloneIframeContainer.contentWindow;
+        var documentClone = cloneWindow.document;
+
+        /* Chrome doesn't detect relative background-images assigned in inline <style> sheets when fetched through getComputedStyle
+             if window url is about:blank, we can assign the url to current by writing onto the document
+             */
+
+        var iframeLoad = iframeLoader(cloneIframeContainer).then(function () {
+            cloner.scrolledElements.forEach(initNode);
+            cloneWindow.scrollTo(bounds.left, bounds.top);
+            if (/(iPad|iPhone|iPod)/g.test(navigator.userAgent) && (cloneWindow.scrollY !== bounds.top || cloneWindow.scrollX !== bounds.left)) {
+                documentClone.documentElement.style.top = -bounds.top + 'px';
+                documentClone.documentElement.style.left = -bounds.left + 'px';
+                documentClone.documentElement.style.position = 'absolute';
+            }
+
+            var result = Promise.resolve([cloneIframeContainer, cloner.clonedReferenceElement, cloner.resourceLoader]);
+
+            var onclone = options.onclone;
+
+            return cloner.clonedReferenceElement instanceof cloneWindow.HTMLElement || cloner.clonedReferenceElement instanceof ownerDocument.defaultView.HTMLElement || cloner.clonedReferenceElement instanceof HTMLElement ? typeof onclone === 'function' ? Promise.resolve().then(function () {
+                return onclone(documentClone);
+            }).then(function () {
+                return result;
+            }) : result : Promise.reject( true ? 'Error finding the ' + referenceElement.nodeName + ' in the cloned document' : '');
+        });
+
+        documentClone.open();
+        documentClone.write(serializeDoctype(document.doctype) + '<html></html>');
+        // Chrome scrolls the parent document for some reason after the write to the cloned window???
+        restoreOwnerScroll(referenceElement.ownerDocument, scrollX, scrollY);
+        documentClone.replaceChild(documentClone.adoptNode(cloner.documentElement), documentClone.documentElement);
+        documentClone.close();
+
+        return iframeLoad;
+    });
+};
+
+var serializeDoctype = function serializeDoctype(doctype) {
+    var str = '';
+    if (doctype) {
+        str += '<!DOCTYPE ';
+        if (doctype.name) {
+            str += doctype.name;
+        }
+
+        if (doctype.internalSubset) {
+            str += doctype.internalSubset;
+        }
+
+        if (doctype.publicId) {
+            str += '"' + doctype.publicId + '"';
+        }
+
+        if (doctype.systemId) {
+            str += '"' + doctype.systemId + '"';
+        }
+
+        str += '>';
+    }
+
+    return str;
+};
+
+/***/ }),
+/* 55 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.ResourceStore = undefined;
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Feature = __webpack_require__(10);
+
+var _Feature2 = _interopRequireDefault(_Feature);
+
+var _Proxy = __webpack_require__(26);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var ResourceLoader = function () {
+    function ResourceLoader(options, logger, window) {
+        _classCallCheck(this, ResourceLoader);
+
+        this.options = options;
+        this._window = window;
+        this.origin = this.getOrigin(window.location.href);
+        this.cache = {};
+        this.logger = logger;
+        this._index = 0;
+    }
+
+    _createClass(ResourceLoader, [{
+        key: 'loadImage',
+        value: function loadImage(src) {
+            var _this = this;
+
+            if (this.hasResourceInCache(src)) {
+                return src;
+            }
+            if (isBlobImage(src)) {
+                this.cache[src] = _loadImage(src, this.options.imageTimeout || 0);
+                return src;
+            }
+
+            if (!isSVG(src) || _Feature2.default.SUPPORT_SVG_DRAWING) {
+                if (this.options.allowTaint === true || isInlineImage(src) || this.isSameOrigin(src)) {
+                    return this.addImage(src, src, false);
+                } else if (!this.isSameOrigin(src)) {
+                    if (typeof this.options.proxy === 'string') {
+                        this.cache[src] = (0, _Proxy.Proxy)(src, this.options).then(function (src) {
+                            return _loadImage(src, _this.options.imageTimeout || 0);
+                        });
+                        return src;
+                    } else if (this.options.useCORS === true && _Feature2.default.SUPPORT_CORS_IMAGES) {
+                        return this.addImage(src, src, true);
+                    }
+                }
+            }
+        }
+    }, {
+        key: 'inlineImage',
+        value: function inlineImage(src) {
+            var _this2 = this;
+
+            if (isInlineImage(src)) {
+                return _loadImage(src, this.options.imageTimeout || 0);
+            }
+            if (this.hasResourceInCache(src)) {
+                return this.cache[src];
+            }
+            if (!this.isSameOrigin(src) && typeof this.options.proxy === 'string') {
+                return this.cache[src] = (0, _Proxy.Proxy)(src, this.options).then(function (src) {
+                    return _loadImage(src, _this2.options.imageTimeout || 0);
+                });
+            }
+
+            return this.xhrImage(src);
+        }
+    }, {
+        key: 'xhrImage',
+        value: function xhrImage(src) {
+            var _this3 = this;
+
+            this.cache[src] = new Promise(function (resolve, reject) {
+                var xhr = new XMLHttpRequest();
+                xhr.onreadystatechange = function () {
+                    if (xhr.readyState === 4) {
+                        if (xhr.status !== 200) {
+                            reject('Failed to fetch image ' + src.substring(0, 256) + ' with status code ' + xhr.status);
+                        } else {
+                            var reader = new FileReader();
+                            reader.addEventListener('load', function () {
+                                // $FlowFixMe
+                                var result = reader.result;
+                                resolve(result);
+                            }, false);
+                            reader.addEventListener('error', function (e) {
+                                return reject(e);
+                            }, false);
+                            reader.readAsDataURL(xhr.response);
+                        }
+                    }
+                };
+                xhr.responseType = 'blob';
+                if (_this3.options.imageTimeout) {
+                    var timeout = _this3.options.imageTimeout;
+                    xhr.timeout = timeout;
+                    xhr.ontimeout = function () {
+                        return reject( true ? 'Timed out (' + timeout + 'ms) fetching ' + src.substring(0, 256) : '');
+                    };
+                }
+                xhr.open('GET', src, true);
+                xhr.send();
+            }).then(function (src) {
+                return _loadImage(src, _this3.options.imageTimeout || 0);
+            });
+
+            return this.cache[src];
+        }
+    }, {
+        key: 'loadCanvas',
+        value: function loadCanvas(node) {
+            var key = String(this._index++);
+            this.cache[key] = Promise.resolve(node);
+            return key;
+        }
+    }, {
+        key: 'hasResourceInCache',
+        value: function hasResourceInCache(key) {
+            return typeof this.cache[key] !== 'undefined';
+        }
+    }, {
+        key: 'addImage',
+        value: function addImage(key, src, useCORS) {
+            var _this4 = this;
+
+            if (true) {
+                this.logger.log('Added image ' + key.substring(0, 256));
+            }
+
+            var imageLoadHandler = function imageLoadHandler(supportsDataImages) {
+                return new Promise(function (resolve, reject) {
+                    var img = new Image();
+                    img.onload = function () {
+                        return resolve(img);
+                    };
+                    //ios safari 10.3 taints canvas with data urls unless crossOrigin is set to anonymous
+                    if (!supportsDataImages || useCORS) {
+                        img.crossOrigin = 'anonymous';
+                    }
+
+                    img.onerror = reject;
+                    img.src = src;
+                    if (img.complete === true) {
+                        // Inline XML images may fail to parse, throwing an Error later on
+                        setTimeout(function () {
+                            resolve(img);
+                        }, 500);
+                    }
+                    if (_this4.options.imageTimeout) {
+                        var timeout = _this4.options.imageTimeout;
+                        setTimeout(function () {
+                            return reject( true ? 'Timed out (' + timeout + 'ms) fetching ' + src.substring(0, 256) : '');
+                        }, timeout);
+                    }
+                });
+            };
+
+            this.cache[key] = isInlineBase64Image(src) && !isSVG(src) ? // $FlowFixMe
+            _Feature2.default.SUPPORT_BASE64_DRAWING(src).then(imageLoadHandler) : imageLoadHandler(true);
+            return key;
+        }
+    }, {
+        key: 'isSameOrigin',
+        value: function isSameOrigin(url) {
+            return this.getOrigin(url) === this.origin;
+        }
+    }, {
+        key: 'getOrigin',
+        value: function getOrigin(url) {
+            var link = this._link || (this._link = this._window.document.createElement('a'));
+            link.href = url;
+            link.href = link.href; // IE9, LOL! - http://jsfiddle.net/niklasvh/2e48b/
+            return link.protocol + link.hostname + link.port;
+        }
+    }, {
+        key: 'ready',
+        value: function ready() {
+            var _this5 = this;
+
+            var keys = Object.keys(this.cache);
+            var values = keys.map(function (str) {
+                return _this5.cache[str].catch(function (e) {
+                    if (true) {
+                        _this5.logger.log('Unable to load image', e);
+                    }
+                    return null;
+                });
+            });
+            return Promise.all(values).then(function (images) {
+                if (true) {
+                    _this5.logger.log('Finished loading ' + images.length + ' images', images);
+                }
+                return new ResourceStore(keys, images);
+            });
+        }
+    }]);
+
+    return ResourceLoader;
+}();
+
+exports.default = ResourceLoader;
+
+var ResourceStore = exports.ResourceStore = function () {
+    function ResourceStore(keys, resources) {
+        _classCallCheck(this, ResourceStore);
+
+        this._keys = keys;
+        this._resources = resources;
+    }
+
+    _createClass(ResourceStore, [{
+        key: 'get',
+        value: function get(key) {
+            var index = this._keys.indexOf(key);
+            return index === -1 ? null : this._resources[index];
+        }
+    }]);
+
+    return ResourceStore;
+}();
+
+var INLINE_SVG = /^data:image\/svg\+xml/i;
+var INLINE_BASE64 = /^data:image\/.*;base64,/i;
+var INLINE_IMG = /^data:image\/.*/i;
+
+var isInlineImage = function isInlineImage(src) {
+    return INLINE_IMG.test(src);
+};
+var isInlineBase64Image = function isInlineBase64Image(src) {
+    return INLINE_BASE64.test(src);
+};
+var isBlobImage = function isBlobImage(src) {
+    return src.substr(0, 4) === 'blob';
+};
+
+var isSVG = function isSVG(src) {
+    return src.substr(-3).toLowerCase() === 'svg' || INLINE_SVG.test(src);
+};
+
+var _loadImage = function _loadImage(src, timeout) {
+    return new Promise(function (resolve, reject) {
+        var img = new Image();
+        img.onload = function () {
+            return resolve(img);
+        };
+        img.onerror = reject;
+        img.src = src;
+        if (img.complete === true) {
+            // Inline XML images may fail to parse, throwing an Error later on
+            setTimeout(function () {
+                resolve(img);
+            }, 500);
+        }
+        if (timeout) {
+            setTimeout(function () {
+                return reject( true ? 'Timed out (' + timeout + 'ms) loading image' : '');
+            }, timeout);
+        }
+    });
+};
+
+/***/ }),
+/* 56 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseContent = exports.resolvePseudoContent = exports.popCounters = exports.parseCounterReset = exports.TOKEN_TYPE = exports.PSEUDO_CONTENT_ITEM_TYPE = undefined;
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var _ListItem = __webpack_require__(14);
+
+var _listStyle = __webpack_require__(8);
+
+var PSEUDO_CONTENT_ITEM_TYPE = exports.PSEUDO_CONTENT_ITEM_TYPE = {
+    TEXT: 0,
+    IMAGE: 1
+};
+
+var TOKEN_TYPE = exports.TOKEN_TYPE = {
+    STRING: 0,
+    ATTRIBUTE: 1,
+    URL: 2,
+    COUNTER: 3,
+    COUNTERS: 4,
+    OPENQUOTE: 5,
+    CLOSEQUOTE: 6
+};
+
+var parseCounterReset = exports.parseCounterReset = function parseCounterReset(style, data) {
+    if (!style || !style.counterReset || style.counterReset === 'none') {
+        return [];
+    }
+
+    var counterNames = [];
+    var counterResets = style.counterReset.split(/\s*,\s*/);
+    var lenCounterResets = counterResets.length;
+
+    for (var i = 0; i < lenCounterResets; i++) {
+        var _counterResets$i$spli = counterResets[i].split(/\s+/),
+            _counterResets$i$spli2 = _slicedToArray(_counterResets$i$spli, 2),
+            counterName = _counterResets$i$spli2[0],
+            initialValue = _counterResets$i$spli2[1];
+
+        counterNames.push(counterName);
+        var counter = data.counters[counterName];
+        if (!counter) {
+            counter = data.counters[counterName] = [];
+        }
+        counter.push(parseInt(initialValue || 0, 10));
+    }
+
+    return counterNames;
+};
+
+var popCounters = exports.popCounters = function popCounters(counterNames, data) {
+    var lenCounters = counterNames.length;
+    for (var i = 0; i < lenCounters; i++) {
+        data.counters[counterNames[i]].pop();
+    }
+};
+
+var resolvePseudoContent = exports.resolvePseudoContent = function resolvePseudoContent(node, style, data) {
+    if (!style || !style.content || style.content === 'none' || style.content === '-moz-alt-content' || style.display === 'none') {
+        return null;
+    }
+
+    var tokens = parseContent(style.content);
+
+    var len = tokens.length;
+    var contentItems = [];
+    var s = '';
+
+    // increment the counter (if there is a "counter-increment" declaration)
+    var counterIncrement = style.counterIncrement;
+    if (counterIncrement && counterIncrement !== 'none') {
+        var _counterIncrement$spl = counterIncrement.split(/\s+/),
+            _counterIncrement$spl2 = _slicedToArray(_counterIncrement$spl, 2),
+            counterName = _counterIncrement$spl2[0],
+            incrementValue = _counterIncrement$spl2[1];
+
+        var counter = data.counters[counterName];
+        if (counter) {
+            counter[counter.length - 1] += incrementValue === undefined ? 1 : parseInt(incrementValue, 10);
+        }
+    }
+
+    // build the content string
+    for (var i = 0; i < len; i++) {
+        var token = tokens[i];
+        switch (token.type) {
+            case TOKEN_TYPE.STRING:
+                s += token.value || '';
+                break;
+
+            case TOKEN_TYPE.ATTRIBUTE:
+                if (node instanceof HTMLElement && token.value) {
+                    s += node.getAttribute(token.value) || '';
+                }
+                break;
+
+            case TOKEN_TYPE.COUNTER:
+                var _counter = data.counters[token.name || ''];
+                if (_counter) {
+                    s += formatCounterValue([_counter[_counter.length - 1]], '', token.format);
+                }
+                break;
+
+            case TOKEN_TYPE.COUNTERS:
+                var _counters = data.counters[token.name || ''];
+                if (_counters) {
+                    s += formatCounterValue(_counters, token.glue, token.format);
+                }
+                break;
+
+            case TOKEN_TYPE.OPENQUOTE:
+                s += getQuote(style, true, data.quoteDepth);
+                data.quoteDepth++;
+                break;
+
+            case TOKEN_TYPE.CLOSEQUOTE:
+                data.quoteDepth--;
+                s += getQuote(style, false, data.quoteDepth);
+                break;
+
+            case TOKEN_TYPE.URL:
+                if (s) {
+                    contentItems.push({ type: PSEUDO_CONTENT_ITEM_TYPE.TEXT, value: s });
+                    s = '';
+                }
+                contentItems.push({ type: PSEUDO_CONTENT_ITEM_TYPE.IMAGE, value: token.value || '' });
+                break;
+        }
+    }
+
+    if (s) {
+        contentItems.push({ type: PSEUDO_CONTENT_ITEM_TYPE.TEXT, value: s });
+    }
+
+    return contentItems;
+};
+
+var parseContent = exports.parseContent = function parseContent(content, cache) {
+    if (cache && cache[content]) {
+        return cache[content];
+    }
+
+    var tokens = [];
+    var len = content.length;
+
+    var isString = false;
+    var isEscaped = false;
+    var isFunction = false;
+    var str = '';
+    var functionName = '';
+    var args = [];
+
+    for (var i = 0; i < len; i++) {
+        var c = content.charAt(i);
+
+        switch (c) {
+            case "'":
+            case '"':
+                if (isEscaped) {
+                    str += c;
+                } else {
+                    isString = !isString;
+                    if (!isFunction && !isString) {
+                        tokens.push({ type: TOKEN_TYPE.STRING, value: str });
+                        str = '';
+                    }
+                }
+                break;
+
+            case '\\':
+                if (isEscaped) {
+                    str += c;
+                    isEscaped = false;
+                } else {
+                    isEscaped = true;
+                }
+                break;
+
+            case '(':
+                if (isString) {
+                    str += c;
+                } else {
+                    isFunction = true;
+                    functionName = str;
+                    str = '';
+                    args = [];
+                }
+                break;
+
+            case ')':
+                if (isString) {
+                    str += c;
+                } else if (isFunction) {
+                    if (str) {
+                        args.push(str);
+                    }
+
+                    switch (functionName) {
+                        case 'attr':
+                            if (args.length > 0) {
+                                tokens.push({ type: TOKEN_TYPE.ATTRIBUTE, value: args[0] });
+                            }
+                            break;
+
+                        case 'counter':
+                            if (args.length > 0) {
+                                var counter = {
+                                    type: TOKEN_TYPE.COUNTER,
+                                    name: args[0]
+                                };
+                                if (args.length > 1) {
+                                    counter.format = args[1];
+                                }
+                                tokens.push(counter);
+                            }
+                            break;
+
+                        case 'counters':
+                            if (args.length > 0) {
+                                var _counters2 = {
+                                    type: TOKEN_TYPE.COUNTERS,
+                                    name: args[0]
+                                };
+                                if (args.length > 1) {
+                                    _counters2.glue = args[1];
+                                }
+                                if (args.length > 2) {
+                                    _counters2.format = args[2];
+                                }
+                                tokens.push(_counters2);
+                            }
+                            break;
+
+                        case 'url':
+                            if (args.length > 0) {
+                                tokens.push({ type: TOKEN_TYPE.URL, value: args[0] });
+                            }
+                            break;
+                    }
+
+                    isFunction = false;
+                    str = '';
+                }
+                break;
+
+            case ',':
+                if (isString) {
+                    str += c;
+                } else if (isFunction) {
+                    args.push(str);
+                    str = '';
+                }
+                break;
+
+            case ' ':
+            case '\t':
+                if (isString) {
+                    str += c;
+                } else if (str) {
+                    addOtherToken(tokens, str);
+                    str = '';
+                }
+                break;
+
+            default:
+                str += c;
+        }
+
+        if (c !== '\\') {
+            isEscaped = false;
+        }
+    }
+
+    if (str) {
+        addOtherToken(tokens, str);
+    }
+
+    if (cache) {
+        cache[content] = tokens;
+    }
+
+    return tokens;
+};
+
+var addOtherToken = function addOtherToken(tokens, identifier) {
+    switch (identifier) {
+        case 'open-quote':
+            tokens.push({ type: TOKEN_TYPE.OPENQUOTE });
+            break;
+        case 'close-quote':
+            tokens.push({ type: TOKEN_TYPE.CLOSEQUOTE });
+            break;
+    }
+};
+
+var getQuote = function getQuote(style, isOpening, quoteDepth) {
+    var quotes = style.quotes ? style.quotes.split(/\s+/) : ["'\"'", "'\"'"];
+    var idx = quoteDepth * 2;
+    if (idx >= quotes.length) {
+        idx = quotes.length - 2;
+    }
+    if (!isOpening) {
+        ++idx;
+    }
+    return quotes[idx].replace(/^["']|["']$/g, '');
+};
+
+var formatCounterValue = function formatCounterValue(counter, glue, format) {
+    var len = counter.length;
+    var result = '';
+
+    for (var i = 0; i < len; i++) {
+        if (i > 0) {
+            result += glue || '';
+        }
+        result += (0, _ListItem.createCounterText)(counter[i], (0, _listStyle.parseListStyleType)(format || 'decimal'), false);
+    }
+
+    return result;
+};
+
+/***/ })
+/******/ ]);
+});
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/html2canvas.min.js b/AstuteClient2/src/assets/html2canvas/dist/html2canvas.min.js
new file mode 100644
index 0000000..e95b911
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/html2canvas.min.js
@@ -0,0 +1,6 @@
+/*!
+ * html2canvas 1.0.0-alpha.12 <https://html2canvas.hertzen.com>
+ * Copyright (c) 2018 Niklas von Hertzen <https://hertzen.com>
+ * Released under MIT License
+ */
+!function(A,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.html2canvas=e():A.html2canvas=e()}(this,function(){return function(A){var e={};function t(r){if(e[r])return e[r].exports;var n=e[r]={i:r,l:!1,exports:{}};return A[r].call(n.exports,n,n.exports,t),n.l=!0,n.exports}return t.m=A,t.c=e,t.d=function(A,e,r){t.o(A,e)||Object.defineProperty(A,e,{configurable:!1,enumerable:!0,get:r})},t.n=function(A){var e=A&&A.__esModule?function(){return A.default}:function(){return A};return t.d(e,"a",e),e},t.o=function(A,e){return Object.prototype.hasOwnProperty.call(A,e)},t.p="",t(t.s=27)}([function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){return function(A,e){if(Array.isArray(A))return A;if(Symbol.iterator in Object(A))return function(A,e){var t=[],r=!0,n=!1,B=void 0;try{for(var a,s=A[Symbol.iterator]();!(r=(a=s.next()).done)&&(t.push(a.value),!e||t.length!==e);r=!0);}catch(A){n=!0,B=A}finally{try{!r&&s.return&&s.return()}finally{if(n)throw B}}return t}(A,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),n=function(){function A(A,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(A,r.key,r)}}return function(e,t,r){return t&&A(e.prototype,t),r&&A(e,r),e}}();var B=/^#([a-f0-9]{3})$/i,a=function(A){var e=A.match(B);return!!e&&[parseInt(e[1][0]+e[1][0],16),parseInt(e[1][1]+e[1][1],16),parseInt(e[1][2]+e[1][2],16),null]},s=/^#([a-f0-9]{6})$/i,o=function(A){var e=A.match(s);return!!e&&[parseInt(e[1].substring(0,2),16),parseInt(e[1].substring(2,4),16),parseInt(e[1].substring(4,6),16),null]},i=/^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/,c=function(A){var e=A.match(i);return!!e&&[Number(e[1]),Number(e[2]),Number(e[3]),null]},l=/^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d?\.?\d+)\s*\)$/,u=function(A){var e=A.match(l);return!!(e&&e.length>4)&&[Number(e[1]),Number(e[2]),Number(e[3]),Number(e[4])]},Q=function(A){return[Math.min(A[0],255),Math.min(A[1],255),Math.min(A[2],255),A.length>3?A[3]:null]},w=function(A){var e=g[A.toLowerCase()];return e||!1},U=function(){function A(e){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A);var t=Array.isArray(e)?Q(e):a(e)||c(e)||u(e)||w(e)||o(e)||[0,0,0,null],n=r(t,4),B=n[0],s=n[1],i=n[2],l=n[3];this.r=B,this.g=s,this.b=i,this.a=l}return n(A,[{key:"isTransparent",value:function(){return 0===this.a}},{key:"toString",value:function(){return null!==this.a&&1!==this.a?"rgba("+this.r+","+this.g+","+this.b+","+this.a+")":"rgb("+this.r+","+this.g+","+this.b+")"}}]),A}();e.default=U;var g={transparent:[0,0,0,0],aliceblue:[240,248,255,null],antiquewhite:[250,235,215,null],aqua:[0,255,255,null],aquamarine:[127,255,212,null],azure:[240,255,255,null],beige:[245,245,220,null],bisque:[255,228,196,null],black:[0,0,0,null],blanchedalmond:[255,235,205,null],blue:[0,0,255,null],blueviolet:[138,43,226,null],brown:[165,42,42,null],burlywood:[222,184,135,null],cadetblue:[95,158,160,null],chartreuse:[127,255,0,null],chocolate:[210,105,30,null],coral:[255,127,80,null],cornflowerblue:[100,149,237,null],cornsilk:[255,248,220,null],crimson:[220,20,60,null],cyan:[0,255,255,null],darkblue:[0,0,139,null],darkcyan:[0,139,139,null],darkgoldenrod:[184,134,11,null],darkgray:[169,169,169,null],darkgreen:[0,100,0,null],darkgrey:[169,169,169,null],darkkhaki:[189,183,107,null],darkmagenta:[139,0,139,null],darkolivegreen:[85,107,47,null],darkorange:[255,140,0,null],darkorchid:[153,50,204,null],darkred:[139,0,0,null],darksalmon:[233,150,122,null],darkseagreen:[143,188,143,null],darkslateblue:[72,61,139,null],darkslategray:[47,79,79,null],darkslategrey:[47,79,79,null],darkturquoise:[0,206,209,null],darkviolet:[148,0,211,null],deeppink:[255,20,147,null],deepskyblue:[0,191,255,null],dimgray:[105,105,105,null],dimgrey:[105,105,105,null],dodgerblue:[30,144,255,null],firebrick:[178,34,34,null],floralwhite:[255,250,240,null],forestgreen:[34,139,34,null],fuchsia:[255,0,255,null],gainsboro:[220,220,220,null],ghostwhite:[248,248,255,null],gold:[255,215,0,null],goldenrod:[218,165,32,null],gray:[128,128,128,null],green:[0,128,0,null],greenyellow:[173,255,47,null],grey:[128,128,128,null],honeydew:[240,255,240,null],hotpink:[255,105,180,null],indianred:[205,92,92,null],indigo:[75,0,130,null],ivory:[255,255,240,null],khaki:[240,230,140,null],lavender:[230,230,250,null],lavenderblush:[255,240,245,null],lawngreen:[124,252,0,null],lemonchiffon:[255,250,205,null],lightblue:[173,216,230,null],lightcoral:[240,128,128,null],lightcyan:[224,255,255,null],lightgoldenrodyellow:[250,250,210,null],lightgray:[211,211,211,null],lightgreen:[144,238,144,null],lightgrey:[211,211,211,null],lightpink:[255,182,193,null],lightsalmon:[255,160,122,null],lightseagreen:[32,178,170,null],lightskyblue:[135,206,250,null],lightslategray:[119,136,153,null],lightslategrey:[119,136,153,null],lightsteelblue:[176,196,222,null],lightyellow:[255,255,224,null],lime:[0,255,0,null],limegreen:[50,205,50,null],linen:[250,240,230,null],magenta:[255,0,255,null],maroon:[128,0,0,null],mediumaquamarine:[102,205,170,null],mediumblue:[0,0,205,null],mediumorchid:[186,85,211,null],mediumpurple:[147,112,219,null],mediumseagreen:[60,179,113,null],mediumslateblue:[123,104,238,null],mediumspringgreen:[0,250,154,null],mediumturquoise:[72,209,204,null],mediumvioletred:[199,21,133,null],midnightblue:[25,25,112,null],mintcream:[245,255,250,null],mistyrose:[255,228,225,null],moccasin:[255,228,181,null],navajowhite:[255,222,173,null],navy:[0,0,128,null],oldlace:[253,245,230,null],olive:[128,128,0,null],olivedrab:[107,142,35,null],orange:[255,165,0,null],orangered:[255,69,0,null],orchid:[218,112,214,null],palegoldenrod:[238,232,170,null],palegreen:[152,251,152,null],paleturquoise:[175,238,238,null],palevioletred:[219,112,147,null],papayawhip:[255,239,213,null],peachpuff:[255,218,185,null],peru:[205,133,63,null],pink:[255,192,203,null],plum:[221,160,221,null],powderblue:[176,224,230,null],purple:[128,0,128,null],rebeccapurple:[102,51,153,null],red:[255,0,0,null],rosybrown:[188,143,143,null],royalblue:[65,105,225,null],saddlebrown:[139,69,19,null],salmon:[250,128,114,null],sandybrown:[244,164,96,null],seagreen:[46,139,87,null],seashell:[255,245,238,null],sienna:[160,82,45,null],silver:[192,192,192,null],skyblue:[135,206,235,null],slateblue:[106,90,205,null],slategray:[112,128,144,null],slategrey:[112,128,144,null],snow:[255,250,250,null],springgreen:[0,255,127,null],steelblue:[70,130,180,null],tan:[210,180,140,null],teal:[0,128,128,null],thistle:[216,191,216,null],tomato:[255,99,71,null],turquoise:[64,224,208,null],violet:[238,130,238,null],wheat:[245,222,179,null],white:[255,255,255,null],whitesmoke:[245,245,245,null],yellow:[255,255,0,null],yellowgreen:[154,205,50,null]};e.TRANSPARENT=new U([0,0,0,0])},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.calculateLengthFromValueWithUnit=e.LENGTH_TYPE=void 0;var r,n=function(){function A(A,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(A,r.key,r)}}return function(e,t,r){return t&&A(e.prototype,t),r&&A(e,r),e}}(),B=t(3);(r=B)&&r.__esModule;var a=e.LENGTH_TYPE={PX:0,PERCENTAGE:1},s=function(){function A(e){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.type="%"===e.substr(e.length-1)?a.PERCENTAGE:a.PX;var t=parseFloat(e);this.value=isNaN(t)?0:t}return n(A,[{key:"isPercentage",value:function(){return this.type===a.PERCENTAGE}},{key:"getAbsoluteValue",value:function(A){return this.isPercentage()?A*(this.value/100):this.value}}],[{key:"create",value:function(e){return new A(e)}}]),A}();e.default=s;e.calculateLengthFromValueWithUnit=function(A,e,t){switch(t){case"px":case"%":return new s(e+t);case"em":case"rem":var r=new s(e);return r.value*="em"===t?parseFloat(A.style.font.fontSize):function A(e){var t=e.parent;return t?A(t):parseFloat(e.style.font.fontSize)}(A),r;default:return new s("0")}}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.parseBoundCurves=e.calculatePaddingBoxPath=e.calculateBorderBoxPath=e.parsePathForBorder=e.parseDocumentSize=e.calculateContentBox=e.calculatePaddingBox=e.parseBounds=e.Bounds=void 0;var r=function(){function A(A,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(A,r.key,r)}}return function(e,t,r){return t&&A(e.prototype,t),r&&A(e,r),e}}(),n=a(t(7)),B=a(t(32));function a(A){return A&&A.__esModule?A:{default:A}}var s=e.Bounds=function(){function A(e,t,r,n){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.left=e,this.top=t,this.width=r,this.height=n}return r(A,null,[{key:"fromClientRect",value:function(e,t,r){return new A(e.left+t,e.top+r,e.width,e.height)}}]),A}(),o=(e.parseBounds=function(A,e,t){return s.fromClientRect(A.getBoundingClientRect(),e,t)},e.calculatePaddingBox=function(A,e){return new s(A.left+e[3].borderWidth,A.top+e[0].borderWidth,A.width-(e[1].borderWidth+e[3].borderWidth),A.height-(e[0].borderWidth+e[2].borderWidth))},e.calculateContentBox=function(A,e,t){var r=e[0].value,n=e[1].value,B=e[2].value,a=e[3].value;return new s(A.left+a+t[3].borderWidth,A.top+r+t[0].borderWidth,A.width-(t[1].borderWidth+t[3].borderWidth+a+n),A.height-(t[0].borderWidth+t[2].borderWidth+r+B))},e.parseDocumentSize=function(A){var e=A.body,t=A.documentElement;if(!e||!t)throw new Error("");var r=Math.max(Math.max(e.scrollWidth,t.scrollWidth),Math.max(e.offsetWidth,t.offsetWidth),Math.max(e.clientWidth,t.clientWidth)),n=Math.max(Math.max(e.scrollHeight,t.scrollHeight),Math.max(e.offsetHeight,t.offsetHeight),Math.max(e.clientHeight,t.clientHeight));return new s(0,0,r,n)},e.parsePathForBorder=function(A,e){switch(e){case 0:return o(A.topLeftOuter,A.topLeftInner,A.topRightOuter,A.topRightInner);case 1:return o(A.topRightOuter,A.topRightInner,A.bottomRightOuter,A.bottomRightInner);case 2:return o(A.bottomRightOuter,A.bottomRightInner,A.bottomLeftOuter,A.bottomLeftInner);case 3:default:return o(A.bottomLeftOuter,A.bottomLeftInner,A.topLeftOuter,A.topLeftInner)}},function(A,e,t,r){var n=[];return A instanceof B.default?n.push(A.subdivide(.5,!1)):n.push(A),t instanceof B.default?n.push(t.subdivide(.5,!0)):n.push(t),r instanceof B.default?n.push(r.subdivide(.5,!0).reverse()):n.push(r),e instanceof B.default?n.push(e.subdivide(.5,!1).reverse()):n.push(e),n}),i=(e.calculateBorderBoxPath=function(A){return[A.topLeftOuter,A.topRightOuter,A.bottomRightOuter,A.bottomLeftOuter]},e.calculatePaddingBoxPath=function(A){return[A.topLeftInner,A.topRightInner,A.bottomRightInner,A.bottomLeftInner]},e.parseBoundCurves=function(A,e,t){var r=t[i.TOP_LEFT][0].getAbsoluteValue(A.width),B=t[i.TOP_LEFT][1].getAbsoluteValue(A.height),a=t[i.TOP_RIGHT][0].getAbsoluteValue(A.width),s=t[i.TOP_RIGHT][1].getAbsoluteValue(A.height),o=t[i.BOTTOM_RIGHT][0].getAbsoluteValue(A.width),l=t[i.BOTTOM_RIGHT][1].getAbsoluteValue(A.height),u=t[i.BOTTOM_LEFT][0].getAbsoluteValue(A.width),Q=t[i.BOTTOM_LEFT][1].getAbsoluteValue(A.height),w=[];w.push((r+a)/A.width),w.push((u+o)/A.width),w.push((B+Q)/A.height),w.push((s+l)/A.height);var U=Math.max.apply(Math,w);U>1&&(r/=U,B/=U,a/=U,s/=U,o/=U,l/=U,u/=U,Q/=U);var g=A.width-a,C=A.height-l,d=A.width-o,F=A.height-Q;return{topLeftOuter:r>0||B>0?c(A.left,A.top,r,B,i.TOP_LEFT):new n.default(A.left,A.top),topLeftInner:r>0||B>0?c(A.left+e[3].borderWidth,A.top+e[0].borderWidth,Math.max(0,r-e[3].borderWidth),Math.max(0,B-e[0].borderWidth),i.TOP_LEFT):new n.default(A.left+e[3].borderWidth,A.top+e[0].borderWidth),topRightOuter:a>0||s>0?c(A.left+g,A.top,a,s,i.TOP_RIGHT):new n.default(A.left+A.width,A.top),topRightInner:a>0||s>0?c(A.left+Math.min(g,A.width+e[3].borderWidth),A.top+e[0].borderWidth,g>A.width+e[3].borderWidth?0:a-e[3].borderWidth,s-e[0].borderWidth,i.TOP_RIGHT):new n.default(A.left+A.width-e[1].borderWidth,A.top+e[0].borderWidth),bottomRightOuter:o>0||l>0?c(A.left+d,A.top+C,o,l,i.BOTTOM_RIGHT):new n.default(A.left+A.width,A.top+A.height),bottomRightInner:o>0||l>0?c(A.left+Math.min(d,A.width-e[3].borderWidth),A.top+Math.min(C,A.height+e[0].borderWidth),Math.max(0,o-e[1].borderWidth),l-e[2].borderWidth,i.BOTTOM_RIGHT):new n.default(A.left+A.width-e[1].borderWidth,A.top+A.height-e[2].borderWidth),bottomLeftOuter:u>0||Q>0?c(A.left,A.top+F,u,Q,i.BOTTOM_LEFT):new n.default(A.left,A.top+A.height),bottomLeftInner:u>0||Q>0?c(A.left+e[3].borderWidth,A.top+F,Math.max(0,u-e[3].borderWidth),Q-e[2].borderWidth,i.BOTTOM_LEFT):new n.default(A.left+e[3].borderWidth,A.top+A.height-e[2].borderWidth)}},{TOP_LEFT:0,TOP_RIGHT:1,BOTTOM_RIGHT:2,BOTTOM_LEFT:3}),c=function(A,e,t,r,a){var s=(Math.sqrt(2)-1)/3*4,o=t*s,c=r*s,l=A+t,u=e+r;switch(a){case i.TOP_LEFT:return new B.default(new n.default(A,u),new n.default(A,u-c),new n.default(l-o,e),new n.default(l,e));case i.TOP_RIGHT:return new B.default(new n.default(A,e),new n.default(A+o,e),new n.default(l,u-c),new n.default(l,u));case i.BOTTOM_RIGHT:return new B.default(new n.default(l,e),new n.default(l,e+c),new n.default(A+o,u),new n.default(A,u));case i.BOTTOM_LEFT:default:return new B.default(new n.default(l,u),new n.default(l-o,u),new n.default(A,e+c),new n.default(A,e))}}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r,n=function(){function A(A,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(A,r.key,r)}}return function(e,t,r){return t&&A(e.prototype,t),r&&A(e,r),e}}(),B=t(0),a=(r=B)&&r.__esModule?r:{default:r},s=t(4),o=t(5),i=t(12),c=t(33),l=t(34),u=t(35),Q=t(36),w=t(37),U=t(38),g=t(8),C=t(39),d=t(40),F=t(18),E=t(17),f=t(19),h=t(11),H=t(41),p=t(20),N=t(42),I=t(43),K=t(44),T=t(45),m=t(2),v=t(21),y=t(14);var b=["INPUT","TEXTAREA","SELECT"],S=function(){function A(e,t,r,n){var B=this;!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.parent=t,this.tagName=e.tagName,this.index=n,this.childNodes=[],this.listItems=[],"number"==typeof e.start&&(this.listStart=e.start);var s=e.ownerDocument.defaultView,S=s.pageXOffset,_=s.pageYOffset,D=s.getComputedStyle(e,null),M=(0,l.parseDisplay)(D.display),O="radio"===e.type||"checkbox"===e.type,R=(0,f.parsePosition)(D.position);if(this.style={background:O?v.INPUT_BACKGROUND:(0,o.parseBackground)(D,r),border:O?v.INPUT_BORDERS:(0,i.parseBorder)(D),borderRadius:(e instanceof s.HTMLInputElement||e instanceof HTMLInputElement)&&O?(0,v.getInputBorderRadius)(e):(0,c.parseBorderRadius)(D),color:O?v.INPUT_COLOR:new a.default(D.color),display:M,float:(0,u.parseCSSFloat)(D.float),font:(0,Q.parseFont)(D),letterSpacing:(0,w.parseLetterSpacing)(D.letterSpacing),listStyle:M===l.DISPLAY.LIST_ITEM?(0,g.parseListStyle)(D):null,lineBreak:(0,U.parseLineBreak)(D.lineBreak),margin:(0,C.parseMargin)(D),opacity:parseFloat(D.opacity),overflow:-1===b.indexOf(e.tagName)?(0,d.parseOverflow)(D.overflow):d.OVERFLOW.HIDDEN,overflowWrap:(0,F.parseOverflowWrap)(D.overflowWrap?D.overflowWrap:D.wordWrap),padding:(0,E.parsePadding)(D),position:R,textDecoration:(0,h.parseTextDecoration)(D),textShadow:(0,H.parseTextShadow)(D.textShadow),textTransform:(0,p.parseTextTransform)(D.textTransform),transform:(0,N.parseTransform)(D),visibility:(0,I.parseVisibility)(D.visibility),wordBreak:(0,K.parseWordBreak)(D.wordBreak),zIndex:(0,T.parseZIndex)(R!==f.POSITION.STATIC?D.zIndex:"auto")},this.isTransformed()&&(e.style.transform="matrix(1,0,0,1,0,0)"),M===l.DISPLAY.LIST_ITEM){var P=(0,y.getListOwner)(this);if(P){var X=P.listItems.length;P.listItems.push(this),this.listIndex=e.hasAttribute("value")&&"number"==typeof e.value?e.value:0===X?"number"==typeof P.listStart?P.listStart:1:P.listItems[X-1].listIndex+1}}"IMG"===e.tagName&&e.addEventListener("load",function(){B.bounds=(0,m.parseBounds)(e,S,_),B.curvedBounds=(0,m.parseBoundCurves)(B.bounds,B.style.border,B.style.borderRadius)}),this.image=L(e,r),this.bounds=O?(0,v.reformatInputBounds)((0,m.parseBounds)(e,S,_)):(0,m.parseBounds)(e,S,_),this.curvedBounds=(0,m.parseBoundCurves)(this.bounds,this.style.border,this.style.borderRadius)}return n(A,[{key:"getClipPaths",value:function(){var A=this.parent?this.parent.getClipPaths():[];return this.style.overflow!==d.OVERFLOW.VISIBLE?A.concat([(0,m.calculatePaddingBoxPath)(this.curvedBounds)]):A}},{key:"isInFlow",value:function(){return this.isRootElement()&&!this.isFloating()&&!this.isAbsolutelyPositioned()}},{key:"isVisible",value:function(){return!(0,s.contains)(this.style.display,l.DISPLAY.NONE)&&this.style.opacity>0&&this.style.visibility===I.VISIBILITY.VISIBLE}},{key:"isAbsolutelyPositioned",value:function(){return this.style.position!==f.POSITION.STATIC&&this.style.position!==f.POSITION.RELATIVE}},{key:"isPositioned",value:function(){return this.style.position!==f.POSITION.STATIC}},{key:"isFloating",value:function(){return this.style.float!==u.FLOAT.NONE}},{key:"isRootElement",value:function(){return null===this.parent}},{key:"isTransformed",value:function(){return null!==this.style.transform}},{key:"isPositionedWithZIndex",value:function(){return this.isPositioned()&&!this.style.zIndex.auto}},{key:"isInlineLevel",value:function(){return(0,s.contains)(this.style.display,l.DISPLAY.INLINE)||(0,s.contains)(this.style.display,l.DISPLAY.INLINE_BLOCK)||(0,s.contains)(this.style.display,l.DISPLAY.INLINE_FLEX)||(0,s.contains)(this.style.display,l.DISPLAY.INLINE_GRID)||(0,s.contains)(this.style.display,l.DISPLAY.INLINE_LIST_ITEM)||(0,s.contains)(this.style.display,l.DISPLAY.INLINE_TABLE)}},{key:"isInlineBlockOrInlineTable",value:function(){return(0,s.contains)(this.style.display,l.DISPLAY.INLINE_BLOCK)||(0,s.contains)(this.style.display,l.DISPLAY.INLINE_TABLE)}}]),A}();e.default=S;var L=function(A,e){if(A instanceof A.ownerDocument.defaultView.SVGSVGElement||A instanceof SVGSVGElement){var t=new XMLSerializer;return e.loadImage("data:image/svg+xml,"+encodeURIComponent(t.serializeToString(A)))}switch(A.tagName){case"IMG":var r=A;return e.loadImage(r.currentSrc||r.src);case"CANVAS":var n=A;return e.loadCanvas(n);case"IFRAME":var B=A.getAttribute("data-html2canvas-internal-iframe-key");if(B)return B}return null}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});e.contains=function(A,e){return 0!=(A&e)},e.distance=function(A,e){return Math.sqrt(A*A+e*e)},e.copyCSSStyles=function(A,e){for(var t=A.length-1;t>=0;t--){var r=A.item(t);"content"!==r&&e.style.setProperty(r,A.getPropertyValue(r))}return e},e.SMALL_IMAGE="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.parseBackgroundImage=e.parseBackground=e.calculateBackgroundRepeatPath=e.calculateBackgroundPosition=e.calculateBackgroungPositioningArea=e.calculateBackgroungPaintingArea=e.calculateGradientBackgroundSize=e.calculateBackgroundSize=e.BACKGROUND_ORIGIN=e.BACKGROUND_CLIP=e.BACKGROUND_SIZE=e.BACKGROUND_REPEAT=void 0;var r=i(t(0)),n=i(t(1)),B=i(t(31)),a=i(t(7)),s=t(2),o=t(17);function i(A){return A&&A.__esModule?A:{default:A}}var c=e.BACKGROUND_REPEAT={REPEAT:0,NO_REPEAT:1,REPEAT_X:2,REPEAT_Y:3},l=e.BACKGROUND_SIZE={AUTO:0,CONTAIN:1,COVER:2,LENGTH:3},u=e.BACKGROUND_CLIP={BORDER_BOX:0,PADDING_BOX:1,CONTENT_BOX:2},Q=e.BACKGROUND_ORIGIN=u,w=function A(e){switch(function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),e){case"contain":this.size=l.CONTAIN;break;case"cover":this.size=l.COVER;break;case"auto":this.size=l.AUTO;break;default:this.value=new n.default(e)}},U=(e.calculateBackgroundSize=function(A,e,t){var r=0,n=0,a=A.size;if(a[0].size===l.CONTAIN||a[0].size===l.COVER){var s=t.width/t.height,o=e.width/e.height;return s<o!=(a[0].size===l.COVER)?new B.default(t.width,t.width/o):new B.default(t.height*o,t.height)}return a[0].value&&(r=a[0].value.getAbsoluteValue(t.width)),a[0].size===l.AUTO&&a[1].size===l.AUTO?n=e.height:a[1].size===l.AUTO?n=r/e.width*e.height:a[1].value&&(n=a[1].value.getAbsoluteValue(t.height)),a[0].size===l.AUTO&&(r=n/e.height*e.width),new B.default(r,n)},e.calculateGradientBackgroundSize=function(A,e){var t=A.size,r=t[0].value?t[0].value.getAbsoluteValue(e.width):e.width,n=t[1].value?t[1].value.getAbsoluteValue(e.height):t[0].value?r:e.height;return new B.default(r,n)},new w("auto")),g=(e.calculateBackgroungPaintingArea=function(A,e){switch(e){case u.BORDER_BOX:return(0,s.calculateBorderBoxPath)(A);case u.PADDING_BOX:default:return(0,s.calculatePaddingBoxPath)(A)}},e.calculateBackgroungPositioningArea=function(A,e,t,r){var n=(0,s.calculatePaddingBox)(e,r);switch(A){case Q.BORDER_BOX:return e;case Q.CONTENT_BOX:var B=t[o.PADDING_SIDES.LEFT].getAbsoluteValue(e.width),a=t[o.PADDING_SIDES.RIGHT].getAbsoluteValue(e.width),i=t[o.PADDING_SIDES.TOP].getAbsoluteValue(e.width),c=t[o.PADDING_SIDES.BOTTOM].getAbsoluteValue(e.width);return new s.Bounds(n.left+B,n.top+i,n.width-B-a,n.height-i-c);case Q.PADDING_BOX:default:return n}},e.calculateBackgroundPosition=function(A,e,t){return new a.default(A[0].getAbsoluteValue(t.width-e.width),A[1].getAbsoluteValue(t.height-e.height))},e.calculateBackgroundRepeatPath=function(A,e,t,r,n){switch(A.repeat){case c.REPEAT_X:return[new a.default(Math.round(n.left),Math.round(r.top+e.y)),new a.default(Math.round(n.left+n.width),Math.round(r.top+e.y)),new a.default(Math.round(n.left+n.width),Math.round(t.height+r.top+e.y)),new a.default(Math.round(n.left),Math.round(t.height+r.top+e.y))];case c.REPEAT_Y:return[new a.default(Math.round(r.left+e.x),Math.round(n.top)),new a.default(Math.round(r.left+e.x+t.width),Math.round(n.top)),new a.default(Math.round(r.left+e.x+t.width),Math.round(n.height+n.top)),new a.default(Math.round(r.left+e.x),Math.round(n.height+n.top))];case c.NO_REPEAT:return[new a.default(Math.round(r.left+e.x),Math.round(r.top+e.y)),new a.default(Math.round(r.left+e.x+t.width),Math.round(r.top+e.y)),new a.default(Math.round(r.left+e.x+t.width),Math.round(r.top+e.y+t.height)),new a.default(Math.round(r.left+e.x),Math.round(r.top+e.y+t.height))];default:return[new a.default(Math.round(n.left),Math.round(n.top)),new a.default(Math.round(n.left+n.width),Math.round(n.top)),new a.default(Math.round(n.left+n.width),Math.round(n.height+n.top)),new a.default(Math.round(n.left),Math.round(n.height+n.top))]}},e.parseBackground=function(A,e){return{backgroundColor:new r.default(A.backgroundColor),backgroundImage:d(A,e),backgroundClip:g(A.backgroundClip),backgroundOrigin:C(A.backgroundOrigin)}},function(A){switch(A){case"padding-box":return u.PADDING_BOX;case"content-box":return u.CONTENT_BOX}return u.BORDER_BOX}),C=function(A){switch(A){case"padding-box":return Q.PADDING_BOX;case"content-box":return Q.CONTENT_BOX}return Q.BORDER_BOX},d=function(A,e){var t=f(A.backgroundImage).map(function(A){if("url"===A.method){var t=e.loadImage(A.args[0]);A.args=t?[t]:[]}return A}),r=A.backgroundPosition.split(","),n=A.backgroundRepeat.split(","),B=A.backgroundSize.split(",");return t.map(function(A,e){var t=(B[e]||"auto").trim().split(" ").map(F),a=(r[e]||"auto").trim().split(" ").map(E);return{source:A,repeat:function(A){switch(A.trim()){case"no-repeat":return c.NO_REPEAT;case"repeat-x":case"repeat no-repeat":return c.REPEAT_X;case"repeat-y":case"no-repeat repeat":return c.REPEAT_Y;case"repeat":return c.REPEAT}return c.REPEAT}("string"==typeof n[e]?n[e]:n[0]),size:t.length<2?[t[0],U]:[t[0],t[1]],position:a.length<2?[a[0],a[0]]:[a[0],a[1]]}})},F=function(A){return"auto"===A?U:new w(A)},E=function(A){switch(A){case"bottom":case"right":return new n.default("100%");case"left":case"top":return new n.default("0%");case"auto":return new n.default("0")}return new n.default(A)},f=e.parseBackgroundImage=function(A){var e=/^\s$/,t=[],r=[],n="",B=null,a="",s=0,o=0,i=function(){var A="";if(n){'"'===a.substr(0,1)&&(a=a.substr(1,a.length-2)),a&&r.push(a.trim());var e=n.indexOf("-",1)+1;"-"===n.substr(0,1)&&e>0&&(A=n.substr(0,e).toLowerCase(),n=n.substr(e)),"none"!==(n=n.toLowerCase())&&t.push({prefix:A,method:n,args:r})}r=[],n=a=""};return A.split("").forEach(function(A){if(0!==s||!e.test(A)){switch(A){case'"':B?B===A&&(B=null):B=A;break;case"(":if(B)break;if(0===s)return void(s=1);o++;break;case")":if(B)break;if(1===s){if(0===o)return s=0,void i();o--}break;case",":if(B)break;if(0===s)return void i();if(1===s&&0===o&&!n.match(/^url$/i))return r.push(a.trim()),void(a="")}0===s?n+=A:a+=A}}),i(),t}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});e.PATH={VECTOR:0,BEZIER_CURVE:1,CIRCLE:2}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=t(6);e.default=function A(e,t){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.type=r.PATH.VECTOR,this.x=e,this.y=t}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.parseListStyle=e.parseListStyleType=e.LIST_STYLE_TYPE=e.LIST_STYLE_POSITION=void 0;var r=t(5),n=e.LIST_STYLE_POSITION={INSIDE:0,OUTSIDE:1},B=e.LIST_STYLE_TYPE={NONE:-1,DISC:0,CIRCLE:1,SQUARE:2,DECIMAL:3,CJK_DECIMAL:4,DECIMAL_LEADING_ZERO:5,LOWER_ROMAN:6,UPPER_ROMAN:7,LOWER_GREEK:8,LOWER_ALPHA:9,UPPER_ALPHA:10,ARABIC_INDIC:11,ARMENIAN:12,BENGALI:13,CAMBODIAN:14,CJK_EARTHLY_BRANCH:15,CJK_HEAVENLY_STEM:16,CJK_IDEOGRAPHIC:17,DEVANAGARI:18,ETHIOPIC_NUMERIC:19,GEORGIAN:20,GUJARATI:21,GURMUKHI:22,HEBREW:22,HIRAGANA:23,HIRAGANA_IROHA:24,JAPANESE_FORMAL:25,JAPANESE_INFORMAL:26,KANNADA:27,KATAKANA:28,KATAKANA_IROHA:29,KHMER:30,KOREAN_HANGUL_FORMAL:31,KOREAN_HANJA_FORMAL:32,KOREAN_HANJA_INFORMAL:33,LAO:34,LOWER_ARMENIAN:35,MALAYALAM:36,MONGOLIAN:37,MYANMAR:38,ORIYA:39,PERSIAN:40,SIMP_CHINESE_FORMAL:41,SIMP_CHINESE_INFORMAL:42,TAMIL:43,TELUGU:44,THAI:45,TIBETAN:46,TRAD_CHINESE_FORMAL:47,TRAD_CHINESE_INFORMAL:48,UPPER_ARMENIAN:49,DISCLOSURE_OPEN:50,DISCLOSURE_CLOSED:51},a=e.parseListStyleType=function(A){switch(A){case"disc":return B.DISC;case"circle":return B.CIRCLE;case"square":return B.SQUARE;case"decimal":return B.DECIMAL;case"cjk-decimal":return B.CJK_DECIMAL;case"decimal-leading-zero":return B.DECIMAL_LEADING_ZERO;case"lower-roman":return B.LOWER_ROMAN;case"upper-roman":return B.UPPER_ROMAN;case"lower-greek":return B.LOWER_GREEK;case"lower-alpha":return B.LOWER_ALPHA;case"upper-alpha":return B.UPPER_ALPHA;case"arabic-indic":return B.ARABIC_INDIC;case"armenian":return B.ARMENIAN;case"bengali":return B.BENGALI;case"cambodian":return B.CAMBODIAN;case"cjk-earthly-branch":return B.CJK_EARTHLY_BRANCH;case"cjk-heavenly-stem":return B.CJK_HEAVENLY_STEM;case"cjk-ideographic":return B.CJK_IDEOGRAPHIC;case"devanagari":return B.DEVANAGARI;case"ethiopic-numeric":return B.ETHIOPIC_NUMERIC;case"georgian":return B.GEORGIAN;case"gujarati":return B.GUJARATI;case"gurmukhi":return B.GURMUKHI;case"hebrew":return B.HEBREW;case"hiragana":return B.HIRAGANA;case"hiragana-iroha":return B.HIRAGANA_IROHA;case"japanese-formal":return B.JAPANESE_FORMAL;case"japanese-informal":return B.JAPANESE_INFORMAL;case"kannada":return B.KANNADA;case"katakana":return B.KATAKANA;case"katakana-iroha":return B.KATAKANA_IROHA;case"khmer":return B.KHMER;case"korean-hangul-formal":return B.KOREAN_HANGUL_FORMAL;case"korean-hanja-formal":return B.KOREAN_HANJA_FORMAL;case"korean-hanja-informal":return B.KOREAN_HANJA_INFORMAL;case"lao":return B.LAO;case"lower-armenian":return B.LOWER_ARMENIAN;case"malayalam":return B.MALAYALAM;case"mongolian":return B.MONGOLIAN;case"myanmar":return B.MYANMAR;case"oriya":return B.ORIYA;case"persian":return B.PERSIAN;case"simp-chinese-formal":return B.SIMP_CHINESE_FORMAL;case"simp-chinese-informal":return B.SIMP_CHINESE_INFORMAL;case"tamil":return B.TAMIL;case"telugu":return B.TELUGU;case"thai":return B.THAI;case"tibetan":return B.TIBETAN;case"trad-chinese-formal":return B.TRAD_CHINESE_FORMAL;case"trad-chinese-informal":return B.TRAD_CHINESE_INFORMAL;case"upper-armenian":return B.UPPER_ARMENIAN;case"disclosure-open":return B.DISCLOSURE_OPEN;case"disclosure-closed":return B.DISCLOSURE_CLOSED;case"none":default:return B.NONE}},s=(e.parseListStyle=function(A){var e=(0,r.parseBackgroundImage)(A.getPropertyValue("list-style-image"));return{listStyleType:a(A.getPropertyValue("list-style-type")),listStyleImage:e.length?e[0]:null,listStylePosition:s(A.getPropertyValue("list-style-position"))}},function(A){switch(A){case"inside":return n.INSIDE;case"outside":default:return n.OUTSIDE}})},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function A(A,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(A,r.key,r)}}return function(e,t,r){return t&&A(e.prototype,t),r&&A(e,r),e}}(),n=t(20),B=t(22);var a=function(){function A(e,t,r){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.text=e,this.parent=t,this.bounds=r}return r(A,null,[{key:"fromTextNode",value:function(e,t){var r=o(e.data,t.style.textTransform);return new A(r,t,(0,B.parseTextBounds)(r,t,e))}}]),A}();e.default=a;var s=/(^|\s|:|-|\(|\))([a-z])/g,o=function(A,e){switch(e){case n.TEXT_TRANSFORM.LOWERCASE:return A.toLowerCase();case n.TEXT_TRANSFORM.CAPITALIZE:return A.replace(s,i);case n.TEXT_TRANSFORM.UPPERCASE:return A.toUpperCase();default:return A}};function i(A,e,t){return A.length>0?e+t.toUpperCase():A}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=t(23),n=function(A){return 0===A[0]&&255===A[1]&&0===A[2]&&255===A[3]},B={get SUPPORT_RANGE_BOUNDS(){var A=function(A){if(A.createRange){var e=A.createRange();if(e.getBoundingClientRect){var t=A.createElement("boundtest");t.style.height="123px",t.style.display="block",A.body.appendChild(t),e.selectNode(t);var r=e.getBoundingClientRect(),n=Math.round(r.height);if(A.body.removeChild(t),123===n)return!0}}return!1}(document);return Object.defineProperty(B,"SUPPORT_RANGE_BOUNDS",{value:A}),A},get SUPPORT_SVG_DRAWING(){var A=function(A){var e=new Image,t=A.createElement("canvas"),r=t.getContext("2d");e.src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>";try{r.drawImage(e,0,0),t.toDataURL()}catch(A){return!1}return!0}(document);return Object.defineProperty(B,"SUPPORT_SVG_DRAWING",{value:A}),A},get SUPPORT_BASE64_DRAWING(){return function(A){var e=function(A,e){var t=new Image,r=A.createElement("canvas"),n=r.getContext("2d");return new Promise(function(A){t.src=e;var B=function(){try{n.drawImage(t,0,0),r.toDataURL()}catch(e){return A(!1)}return A(!0)};t.onload=B,t.onerror=function(){return A(!1)},!0===t.complete&&setTimeout(function(){B()},500)})}(document,A);return Object.defineProperty(B,"SUPPORT_BASE64_DRAWING",{value:function(){return e}}),e}},get SUPPORT_FOREIGNOBJECT_DRAWING(){var A="function"==typeof Array.from&&"function"==typeof window.fetch?function(A){var e=A.createElement("canvas");e.width=100,e.height=100;var t=e.getContext("2d");t.fillStyle="rgb(0, 255, 0)",t.fillRect(0,0,100,100);var B=new Image,a=e.toDataURL();B.src=a;var s=(0,r.createForeignObjectSVG)(100,100,0,0,B);return t.fillStyle="red",t.fillRect(0,0,100,100),(0,r.loadSerializedSVG)(s).then(function(e){t.drawImage(e,0,0);var B=t.getImageData(0,0,100,100).data;t.fillStyle="red",t.fillRect(0,0,100,100);var s=A.createElement("div");return s.style.backgroundImage="url("+a+")",s.style.height="100px",n(B)?(0,r.loadSerializedSVG)((0,r.createForeignObjectSVG)(100,100,0,0,s)):Promise.reject(!1)}).then(function(A){return t.drawImage(A,0,0),n(t.getImageData(0,0,100,100).data)}).catch(function(A){return!1})}(document):Promise.resolve(!1);return Object.defineProperty(B,"SUPPORT_FOREIGNOBJECT_DRAWING",{value:A}),A},get SUPPORT_CORS_IMAGES(){var A=void 0!==(new Image).crossOrigin;return Object.defineProperty(B,"SUPPORT_CORS_IMAGES",{value:A}),A},get SUPPORT_RESPONSE_TYPE(){var A="string"==typeof(new XMLHttpRequest).responseType;return Object.defineProperty(B,"SUPPORT_RESPONSE_TYPE",{value:A}),A},get SUPPORT_CORS_XHR(){var A="withCredentials"in new XMLHttpRequest;return Object.defineProperty(B,"SUPPORT_CORS_XHR",{value:A}),A}};e.default=B},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.parseTextDecoration=e.TEXT_DECORATION_LINE=e.TEXT_DECORATION=e.TEXT_DECORATION_STYLE=void 0;var r,n=t(0),B=(r=n)&&r.__esModule?r:{default:r};var a=e.TEXT_DECORATION_STYLE={SOLID:0,DOUBLE:1,DOTTED:2,DASHED:3,WAVY:4},s=e.TEXT_DECORATION={NONE:null},o=e.TEXT_DECORATION_LINE={UNDERLINE:1,OVERLINE:2,LINE_THROUGH:3,BLINK:4},i=function(A){switch(A){case"underline":return o.UNDERLINE;case"overline":return o.OVERLINE;case"line-through":return o.LINE_THROUGH}return o.BLINK};e.parseTextDecoration=function(A){var e,t="none"===(e=A.textDecorationLine?A.textDecorationLine:A.textDecoration)?null:e.split(" ").map(i);return null===t?s.NONE:{textDecorationLine:t,textDecorationColor:A.textDecorationColor?new B.default(A.textDecorationColor):null,textDecorationStyle:function(A){switch(A){case"double":return a.DOUBLE;case"dotted":return a.DOTTED;case"dashed":return a.DASHED;case"wavy":return a.WAVY}return a.SOLID}(A.textDecorationStyle)}}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.parseBorder=e.BORDER_SIDES=e.BORDER_STYLE=void 0;var r,n=t(0),B=(r=n)&&r.__esModule?r:{default:r};var a=e.BORDER_STYLE={NONE:0,SOLID:1},s=e.BORDER_SIDES={TOP:0,RIGHT:1,BOTTOM:2,LEFT:3},o=Object.keys(s).map(function(A){return A.toLowerCase()});e.parseBorder=function(A){return o.map(function(e){var t=new B.default(A.getPropertyValue("border-"+e+"-color")),r=function(A){switch(A){case"none":return a.NONE}return a.SOLID}(A.getPropertyValue("border-"+e+"-style")),n=parseFloat(A.getPropertyValue("border-"+e+"-width"));return{borderColor:t,borderStyle:r,borderWidth:isNaN(n)?0:n}})}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});e.toCodePoints=function(A){for(var e=[],t=0,r=A.length;t<r;){var n=A.charCodeAt(t++);if(n>=55296&&n<=56319&&t<r){var B=A.charCodeAt(t++);56320==(64512&B)?e.push(((1023&n)<<10)+(1023&B)+65536):(e.push(n),t--)}else e.push(n)}return e},e.fromCodePoint=function(){if(String.fromCodePoint)return String.fromCodePoint.apply(String,arguments);var A=arguments.length;if(!A)return"";for(var e=[],t=-1,r="";++t<A;){var n=arguments.length<=t?void 0:arguments[t];n<=65535?e.push(n):(n-=65536,e.push(55296+(n>>10),n%1024+56320)),(t+1===A||e.length>16384)&&(r+=String.fromCharCode.apply(String,e),e.length=0)}return r};for(var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n="undefined"==typeof Uint8Array?[]:new Uint8Array(256),B=0;B<r.length;B++)n[r.charCodeAt(B)]=B;e.decode=function(A){var e=.75*A.length,t=A.length,r=void 0,B=0,a=void 0,s=void 0,o=void 0,i=void 0;"="===A[A.length-1]&&(e--,"="===A[A.length-2]&&e--);var c="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array&&void 0!==Uint8Array.prototype.slice?new ArrayBuffer(e):new Array(e),l=Array.isArray(c)?c:new Uint8Array(c);for(r=0;r<t;r+=4)a=n[A.charCodeAt(r)],s=n[A.charCodeAt(r+1)],o=n[A.charCodeAt(r+2)],i=n[A.charCodeAt(r+3)],l[B++]=a<<2|s>>4,l[B++]=(15&s)<<4|o>>2,l[B++]=(3&o)<<6|63&i;return c},e.polyUint16Array=function(A){for(var e=A.length,t=[],r=0;r<e;r+=2)t.push(A[r+1]<<8|A[r]);return t},e.polyUint32Array=function(A){for(var e=A.length,t=[],r=0;r<e;r+=4)t.push(A[r+3]<<24|A[r+2]<<16|A[r+1]<<8|A[r]);return t}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.createCounterText=e.inlineListItemElement=e.getListOwner=void 0;var r=t(4),n=o(t(3)),B=o(t(9)),a=t(8),s=t(24);function o(A){return A&&A.__esModule?A:{default:A}}var i=["OL","UL","MENU"],c=(e.getListOwner=function(A){var e=A.parent;if(!e)return null;do{if(-1!==i.indexOf(e.tagName))return e;e=e.parent}while(e);return A.parent},e.inlineListItemElement=function(A,e,t){var s=e.style.listStyle;if(s){var o=A.ownerDocument.defaultView.getComputedStyle(A,null),i=A.ownerDocument.createElement("html2canvaswrapper");switch((0,r.copyCSSStyles)(o,i),i.style.position="absolute",i.style.bottom="auto",i.style.display="block",i.style.letterSpacing="normal",s.listStylePosition){case a.LIST_STYLE_POSITION.OUTSIDE:i.style.left="auto",i.style.right=A.ownerDocument.defaultView.innerWidth-e.bounds.left-e.style.margin[1].getAbsoluteValue(e.bounds.width)+7+"px",i.style.textAlign="right";break;case a.LIST_STYLE_POSITION.INSIDE:i.style.left=e.bounds.left-e.style.margin[3].getAbsoluteValue(e.bounds.width)+"px",i.style.right="auto",i.style.textAlign="left"}var c=void 0,l=e.style.margin[0].getAbsoluteValue(e.bounds.width),u=s.listStyleImage;if(u)if("url"===u.method){var Q=A.ownerDocument.createElement("img");Q.src=u.args[0],i.style.top=e.bounds.top-l+"px",i.style.width="auto",i.style.height="auto",i.appendChild(Q)}else{var w=.5*parseFloat(e.style.font.fontSize);i.style.top=e.bounds.top-l+e.bounds.height-1.5*w+"px",i.style.width=w+"px",i.style.height=w+"px",i.style.backgroundImage=o.listStyleImage}else"number"==typeof e.listIndex&&(c=A.ownerDocument.createTextNode(F(e.listIndex,s.listStyleType,!0)),i.appendChild(c),i.style.top=e.bounds.top-l+"px");var U=A.ownerDocument.body;U.appendChild(i),c?(e.childNodes.push(B.default.fromTextNode(c,e)),U.removeChild(i)):e.childNodes.push(new n.default(i,e,t,0))}},{integers:[1e3,900,500,400,100,90,50,40,10,9,5,4,1],values:["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"]}),l={integers:[9e3,8e3,7e3,6e3,5e3,4e3,3e3,2e3,1e3,900,800,700,600,500,400,300,200,100,90,80,70,60,50,40,30,20,10,9,8,7,6,5,4,3,2,1],values:["Ք","Փ","Ւ","Ց","Ր","Տ","Վ","Ս","Ռ","Ջ","Պ","Չ","Ո","Շ","Ն","Յ","Մ","Ճ","Ղ","Ձ","Հ","Կ","Ծ","Խ","Լ","Ի","Ժ","Թ","Ը","Է","Զ","Ե","Դ","Գ","Բ","Ա"]},u={integers:[1e4,9e3,8e3,7e3,6e3,5e3,4e3,3e3,2e3,1e3,400,300,200,100,90,80,70,60,50,40,30,20,19,18,17,16,15,10,9,8,7,6,5,4,3,2,1],values:["י׳","ט׳","ח׳","ז׳","ו׳","ה׳","ד׳","ג׳","ב׳","א׳","ת","ש","ר","ק","צ","פ","ע","ס","נ","מ","ל","כ","יט","יח","יז","טז","טו","י","ט","ח","ז","ו","ה","ד","ג","ב","א"]},Q={integers:[1e4,9e3,8e3,7e3,6e3,5e3,4e3,3e3,2e3,1e3,900,800,700,600,500,400,300,200,100,90,80,70,60,50,40,30,20,10,9,8,7,6,5,4,3,2,1],values:["ჵ","ჰ","ჯ","ჴ","ხ","ჭ","წ","ძ","ც","ჩ","შ","ყ","ღ","ქ","ფ","ჳ","ტ","ს","რ","ჟ","პ","ო","ჲ","ნ","მ","ლ","კ","ი","თ","ჱ","ზ","ვ","ე","დ","გ","ბ","ა"]},w=function(A,e,t,r,n,B){return A<e||A>t?F(A,n,B.length>0):r.integers.reduce(function(e,t,n){for(;A>=t;)A-=t,e+=r.values[n];return e},"")+B},U=function(A,e,t,r){var n="";do{t||A--,n=r(A)+n,A/=e}while(A*e>=e);return n},g=function(A,e,t,r,n){var B=t-e+1;return(A<0?"-":"")+(U(Math.abs(A),B,r,function(A){return(0,s.fromCodePoint)(Math.floor(A%B)+e)})+n)},C=function(A,e){var t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:". ",r=e.length;return U(Math.abs(A),r,!1,function(A){return e[Math.floor(A%r)]})+t},d=function(A,e,t,n,B,s){if(A<-9999||A>9999)return F(A,a.LIST_STYLE_TYPE.CJK_DECIMAL,B.length>0);var o=Math.abs(A),i=B;if(0===o)return e[0]+i;for(var c=0;o>0&&c<=4;c++){var l=o%10;0===l&&(0,r.contains)(s,1)&&""!==i?i=e[l]+i:l>1||1===l&&0===c||1===l&&1===c&&(0,r.contains)(s,2)||1===l&&1===c&&(0,r.contains)(s,4)&&A>100||1===l&&c>1&&(0,r.contains)(s,8)?i=e[l]+(c>0?t[c-1]:"")+i:1===l&&c>0&&(i=t[c-1]+i),o=Math.floor(o/10)}return(A<0?n:"")+i},F=e.createCounterText=function(A,e,t){var r=t?". ":"",n=t?"、":"",B=t?", ":"";switch(e){case a.LIST_STYLE_TYPE.DISC:return"•";case a.LIST_STYLE_TYPE.CIRCLE:return"◦";case a.LIST_STYLE_TYPE.SQUARE:return"◾";case a.LIST_STYLE_TYPE.DECIMAL_LEADING_ZERO:var s=g(A,48,57,!0,r);return s.length<4?"0"+s:s;case a.LIST_STYLE_TYPE.CJK_DECIMAL:return C(A,"〇一二三四五六七八九",n);case a.LIST_STYLE_TYPE.LOWER_ROMAN:return w(A,1,3999,c,a.LIST_STYLE_TYPE.DECIMAL,r).toLowerCase();case a.LIST_STYLE_TYPE.UPPER_ROMAN:return w(A,1,3999,c,a.LIST_STYLE_TYPE.DECIMAL,r);case a.LIST_STYLE_TYPE.LOWER_GREEK:return g(A,945,969,!1,r);case a.LIST_STYLE_TYPE.LOWER_ALPHA:return g(A,97,122,!1,r);case a.LIST_STYLE_TYPE.UPPER_ALPHA:return g(A,65,90,!1,r);case a.LIST_STYLE_TYPE.ARABIC_INDIC:return g(A,1632,1641,!0,r);case a.LIST_STYLE_TYPE.ARMENIAN:case a.LIST_STYLE_TYPE.UPPER_ARMENIAN:return w(A,1,9999,l,a.LIST_STYLE_TYPE.DECIMAL,r);case a.LIST_STYLE_TYPE.LOWER_ARMENIAN:return w(A,1,9999,l,a.LIST_STYLE_TYPE.DECIMAL,r).toLowerCase();case a.LIST_STYLE_TYPE.BENGALI:return g(A,2534,2543,!0,r);case a.LIST_STYLE_TYPE.CAMBODIAN:case a.LIST_STYLE_TYPE.KHMER:return g(A,6112,6121,!0,r);case a.LIST_STYLE_TYPE.CJK_EARTHLY_BRANCH:return C(A,"子丑寅卯辰巳午未申酉戌亥",n);case a.LIST_STYLE_TYPE.CJK_HEAVENLY_STEM:return C(A,"甲乙丙丁戊己庚辛壬癸",n);case a.LIST_STYLE_TYPE.CJK_IDEOGRAPHIC:case a.LIST_STYLE_TYPE.TRAD_CHINESE_INFORMAL:return d(A,"零一二三四五六七八九","十百千萬","負",n,14);case a.LIST_STYLE_TYPE.TRAD_CHINESE_FORMAL:return d(A,"零壹貳參肆伍陸柒捌玖","拾佰仟萬","負",n,15);case a.LIST_STYLE_TYPE.SIMP_CHINESE_INFORMAL:return d(A,"零一二三四五六七八九","十百千萬","负",n,14);case a.LIST_STYLE_TYPE.SIMP_CHINESE_FORMAL:return d(A,"零壹贰叁肆伍陆柒捌玖","拾佰仟萬","负",n,15);case a.LIST_STYLE_TYPE.JAPANESE_INFORMAL:return d(A,"〇一二三四五六七八九","十百千万","マイナス",n,0);case a.LIST_STYLE_TYPE.JAPANESE_FORMAL:return d(A,"零壱弐参四伍六七八九","拾百千万","マイナス",n,7);case a.LIST_STYLE_TYPE.KOREAN_HANGUL_FORMAL:return d(A,"영일이삼사오육칠팔구","십백천만","마이너스 ",B,7);case a.LIST_STYLE_TYPE.KOREAN_HANJA_INFORMAL:return d(A,"零一二三四五六七八九","十百千萬","마이너스 ",B,0);case a.LIST_STYLE_TYPE.KOREAN_HANJA_FORMAL:return d(A,"零壹貳參四五六七八九","拾百千","마이너스 ",B,7);case a.LIST_STYLE_TYPE.DEVANAGARI:return g(A,2406,2415,!0,r);case a.LIST_STYLE_TYPE.GEORGIAN:return w(A,1,19999,Q,a.LIST_STYLE_TYPE.DECIMAL,r);case a.LIST_STYLE_TYPE.GUJARATI:return g(A,2790,2799,!0,r);case a.LIST_STYLE_TYPE.GURMUKHI:return g(A,2662,2671,!0,r);case a.LIST_STYLE_TYPE.HEBREW:return w(A,1,10999,u,a.LIST_STYLE_TYPE.DECIMAL,r);case a.LIST_STYLE_TYPE.HIRAGANA:return C(A,"あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわゐゑをん");case a.LIST_STYLE_TYPE.HIRAGANA_IROHA:return C(A,"いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす");case a.LIST_STYLE_TYPE.KANNADA:return g(A,3302,3311,!0,r);case a.LIST_STYLE_TYPE.KATAKANA:return C(A,"アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヰヱヲン",n);case a.LIST_STYLE_TYPE.KATAKANA_IROHA:return C(A,"イロハニホヘトチリヌルヲワカヨタレソツネナラムウヰノオクヤマケフコエテアサキユメミシヱヒモセス",n);case a.LIST_STYLE_TYPE.LAO:return g(A,3792,3801,!0,r);case a.LIST_STYLE_TYPE.MONGOLIAN:return g(A,6160,6169,!0,r);case a.LIST_STYLE_TYPE.MYANMAR:return g(A,4160,4169,!0,r);case a.LIST_STYLE_TYPE.ORIYA:return g(A,2918,2927,!0,r);case a.LIST_STYLE_TYPE.PERSIAN:return g(A,1776,1785,!0,r);case a.LIST_STYLE_TYPE.TAMIL:return g(A,3046,3055,!0,r);case a.LIST_STYLE_TYPE.TELUGU:return g(A,3174,3183,!0,r);case a.LIST_STYLE_TYPE.THAI:return g(A,3664,3673,!0,r);case a.LIST_STYLE_TYPE.TIBETAN:return g(A,3872,3881,!0,r);case a.LIST_STYLE_TYPE.DECIMAL:default:return g(A,48,57,!0,r)}}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function A(A,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(A,r.key,r)}}return function(e,t,r){return t&&A(e.prototype,t),r&&A(e,r),e}}(),n=t(6),B=t(11);var a=function(A,e){var t=Math.max.apply(null,A.colorStops.map(function(A){return A.stop})),r=1/Math.max(1,t);A.colorStops.forEach(function(A){e.addColorStop(r*A.stop,A.color.toString())})},s=function(){function A(e){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.canvas=e||document.createElement("canvas")}return r(A,[{key:"render",value:function(A){this.ctx=this.canvas.getContext("2d"),this.options=A,this.canvas.width=Math.floor(A.width*A.scale),this.canvas.height=Math.floor(A.height*A.scale),this.canvas.style.width=A.width+"px",this.canvas.style.height=A.height+"px",this.ctx.scale(this.options.scale,this.options.scale),this.ctx.translate(-A.x,-A.y),this.ctx.textBaseline="bottom",A.logger.log("Canvas renderer initialized ("+A.width+"x"+A.height+" at "+A.x+","+A.y+") with scale "+this.options.scale)}},{key:"clip",value:function(A,e){var t=this;A.length&&(this.ctx.save(),A.forEach(function(A){t.path(A),t.ctx.clip()})),e(),A.length&&this.ctx.restore()}},{key:"drawImage",value:function(A,e,t){this.ctx.drawImage(A,e.left,e.top,e.width,e.height,t.left,t.top,t.width,t.height)}},{key:"drawShape",value:function(A,e){this.path(A),this.ctx.fillStyle=e.toString(),this.ctx.fill()}},{key:"fill",value:function(A){this.ctx.fillStyle=A.toString(),this.ctx.fill()}},{key:"getTarget",value:function(){return this.canvas.getContext("2d").setTransform(1,0,0,1,0,0),Promise.resolve(this.canvas)}},{key:"path",value:function(A){var e=this;this.ctx.beginPath(),Array.isArray(A)?A.forEach(function(A,t){var r=A.type===n.PATH.VECTOR?A:A.start;0===t?e.ctx.moveTo(r.x,r.y):e.ctx.lineTo(r.x,r.y),A.type===n.PATH.BEZIER_CURVE&&e.ctx.bezierCurveTo(A.startControl.x,A.startControl.y,A.endControl.x,A.endControl.y,A.end.x,A.end.y)}):this.ctx.arc(A.x+A.radius,A.y+A.radius,A.radius,0,2*Math.PI,!0),this.ctx.closePath()}},{key:"rectangle",value:function(A,e,t,r,n){this.ctx.fillStyle=n.toString(),this.ctx.fillRect(A,e,t,r)}},{key:"renderLinearGradient",value:function(A,e){var t=this.ctx.createLinearGradient(A.left+e.direction.x1,A.top+e.direction.y1,A.left+e.direction.x0,A.top+e.direction.y0);a(e,t),this.ctx.fillStyle=t,this.ctx.fillRect(A.left,A.top,A.width,A.height)}},{key:"renderRadialGradient",value:function(A,e){var t=this,r=A.left+e.center.x,n=A.top+e.center.y,B=this.ctx.createRadialGradient(r,n,0,r,n,e.radius.x);if(B)if(a(e,B),this.ctx.fillStyle=B,e.radius.x!==e.radius.y){var s=A.left+.5*A.width,o=A.top+.5*A.height,i=e.radius.y/e.radius.x,c=1/i;this.transform(s,o,[1,0,0,i,0,0],function(){return t.ctx.fillRect(A.left,c*(A.top-o)+o,A.width,A.height*c)})}else this.ctx.fillRect(A.left,A.top,A.width,A.height)}},{key:"renderRepeat",value:function(A,e,t,r,n){this.path(A),this.ctx.fillStyle=this.ctx.createPattern(this.resizeImage(e,t),"repeat"),this.ctx.translate(r,n),this.ctx.fill(),this.ctx.translate(-r,-n)}},{key:"renderTextNode",value:function(A,e,t,r,n){var a=this;this.ctx.font=[t.fontStyle,t.fontVariant,t.fontWeight,t.fontSize,t.fontFamily].join(" "),A.forEach(function(A){if(a.ctx.fillStyle=e.toString(),n&&A.text.trim().length?n.slice(0).reverse().forEach(function(e){a.ctx.shadowColor=e.color.toString(),a.ctx.shadowOffsetX=e.offsetX*a.options.scale,a.ctx.shadowOffsetY=e.offsetY*a.options.scale,a.ctx.shadowBlur=e.blur,a.ctx.fillText(A.text,A.bounds.left,A.bounds.top+A.bounds.height)}):a.ctx.fillText(A.text,A.bounds.left,A.bounds.top+A.bounds.height),null!==r){var s=r.textDecorationColor||e;r.textDecorationLine.forEach(function(e){switch(e){case B.TEXT_DECORATION_LINE.UNDERLINE:var r=a.options.fontMetrics.getMetrics(t).baseline;a.rectangle(A.bounds.left,Math.round(A.bounds.top+r),A.bounds.width,1,s);break;case B.TEXT_DECORATION_LINE.OVERLINE:a.rectangle(A.bounds.left,Math.round(A.bounds.top),A.bounds.width,1,s);break;case B.TEXT_DECORATION_LINE.LINE_THROUGH:var n=a.options.fontMetrics.getMetrics(t).middle;a.rectangle(A.bounds.left,Math.ceil(A.bounds.top+n),A.bounds.width,1,s)}})}})}},{key:"resizeImage",value:function(A,e){if(A.width===e.width&&A.height===e.height)return A;var t=this.canvas.ownerDocument.createElement("canvas");return t.width=e.width,t.height=e.height,t.getContext("2d").drawImage(A,0,0,A.width,A.height,0,0,e.width,e.height),t}},{key:"setOpacity",value:function(A){this.ctx.globalAlpha=A}},{key:"transform",value:function(A,e,t,r){this.ctx.save(),this.ctx.translate(A,e),this.ctx.transform(t[0],t[1],t[2],t[3],t[4],t[5]),this.ctx.translate(-A,-e),r(),this.ctx.restore()}}]),A}();e.default=s},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function A(A,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(A,r.key,r)}}return function(e,t,r){return t&&A(e.prototype,t),r&&A(e,r),e}}();var n=function(){function A(e,t,r){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.enabled="undefined"!=typeof window&&e,this.start=r||Date.now(),this.id=t}return r(A,[{key:"child",value:function(e){return new A(this.enabled,e,this.start)}},{key:"log",value:function(){if(this.enabled&&window.console&&window.console.log){for(var A=arguments.length,e=Array(A),t=0;t<A;t++)e[t]=arguments[t];Function.prototype.bind.call(window.console.log,window.console).apply(window.console,[Date.now()-this.start+"ms",this.id?"html2canvas ("+this.id+"):":"html2canvas:"].concat([].slice.call(e,0)))}}},{key:"error",value:function(){if(this.enabled&&window.console&&window.console.error){for(var A=arguments.length,e=Array(A),t=0;t<A;t++)e[t]=arguments[t];Function.prototype.bind.call(window.console.error,window.console).apply(window.console,[Date.now()-this.start+"ms",this.id?"html2canvas ("+this.id+"):":"html2canvas:"].concat([].slice.call(e,0)))}}}]),A}();e.default=n},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.parsePadding=e.PADDING_SIDES=void 0;var r,n=t(1),B=(r=n)&&r.__esModule?r:{default:r};e.PADDING_SIDES={TOP:0,RIGHT:1,BOTTOM:2,LEFT:3};var a=["top","right","bottom","left"];e.parsePadding=function(A){return a.map(function(e){return new B.default(A.getPropertyValue("padding-"+e))})}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=e.OVERFLOW_WRAP={NORMAL:0,BREAK_WORD:1};e.parseOverflowWrap=function(A){switch(A){case"break-word":return r.BREAK_WORD;case"normal":default:return r.NORMAL}}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=e.POSITION={STATIC:0,RELATIVE:1,ABSOLUTE:2,FIXED:3,STICKY:4};e.parsePosition=function(A){switch(A){case"relative":return r.RELATIVE;case"absolute":return r.ABSOLUTE;case"fixed":return r.FIXED;case"sticky":return r.STICKY}return r.STATIC}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=e.TEXT_TRANSFORM={NONE:0,LOWERCASE:1,UPPERCASE:2,CAPITALIZE:3};e.parseTextTransform=function(A){switch(A){case"uppercase":return r.UPPERCASE;case"lowercase":return r.LOWERCASE;case"capitalize":return r.CAPITALIZE}return r.NONE}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.reformatInputBounds=e.inlineSelectElement=e.inlineTextAreaElement=e.inlineInputElement=e.getInputBorderRadius=e.INPUT_BACKGROUND=e.INPUT_BORDERS=e.INPUT_COLOR=void 0;var r=l(t(9)),n=t(5),B=t(12),a=l(t(50)),s=l(t(7)),o=l(t(0)),i=l(t(1)),c=(t(2),t(22),t(4));function l(A){return A&&A.__esModule?A:{default:A}}e.INPUT_COLOR=new o.default([42,42,42]);var u=new o.default([165,165,165]),Q=new o.default([222,222,222]),w={borderWidth:1,borderColor:u,borderStyle:B.BORDER_STYLE.SOLID},U=(e.INPUT_BORDERS=[w,w,w,w],e.INPUT_BACKGROUND={backgroundColor:Q,backgroundImage:[],backgroundClip:n.BACKGROUND_CLIP.PADDING_BOX,backgroundOrigin:n.BACKGROUND_ORIGIN.PADDING_BOX},new i.default("50%")),g=[U,U],C=[g,g,g,g],d=new i.default("3px"),F=[d,d],E=[F,F,F,F],f=(e.getInputBorderRadius=function(A){return"radio"===A.type?C:E},e.inlineInputElement=function(A,e){if("radio"===A.type||"checkbox"===A.type){if(A.checked){var t=Math.min(e.bounds.width,e.bounds.height);e.childNodes.push("checkbox"===A.type?[new s.default(e.bounds.left+.39363*t,e.bounds.top+.79*t),new s.default(e.bounds.left+.16*t,e.bounds.top+.5549*t),new s.default(e.bounds.left+.27347*t,e.bounds.top+.44071*t),new s.default(e.bounds.left+.39694*t,e.bounds.top+.5649*t),new s.default(e.bounds.left+.72983*t,e.bounds.top+.23*t),new s.default(e.bounds.left+.84*t,e.bounds.top+.34085*t),new s.default(e.bounds.left+.39363*t,e.bounds.top+.79*t)]:new a.default(e.bounds.left+t/4,e.bounds.top+t/4,t/4))}}else f(h(A),A,e,!1)},e.inlineTextAreaElement=function(A,e){f(A.value,A,e,!0)},e.inlineSelectElement=function(A,e){var t=A.options[A.selectedIndex||0];f(t&&t.text||"",A,e,!1)},e.reformatInputBounds=function(A){return A.width>A.height?(A.left+=(A.width-A.height)/2,A.width=A.height):A.width<A.height&&(A.top+=(A.height-A.width)/2,A.height=A.width),A},function(A,e,t,n){var B=e.ownerDocument.body;if(A.length>0&&B){var a=e.ownerDocument.createElement("html2canvaswrapper");(0,c.copyCSSStyles)(e.ownerDocument.defaultView.getComputedStyle(e,null),a),a.style.position="absolute",a.style.left=t.bounds.left+"px",a.style.top=t.bounds.top+"px",n||(a.style.whiteSpace="nowrap");var s=e.ownerDocument.createTextNode(A);a.appendChild(s),B.appendChild(a),t.childNodes.push(r.default.fromTextNode(s,t)),B.removeChild(a)}}),h=function(A){var e="password"===A.type?new Array(A.value.length+1).join("•"):A.value;return 0===e.length?A.placeholder||"":e}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.parseTextBounds=e.TextBounds=void 0;var r,n=t(2),B=t(11),a=t(10),s=(r=a)&&r.__esModule?r:{default:r},o=t(24);var i=e.TextBounds=function A(e,t){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.text=e,this.bounds=t},c=(e.parseTextBounds=function(A,e,t){for(var r=0!==e.style.letterSpacing?(0,o.toCodePoints)(A).map(function(A){return(0,o.fromCodePoint)(A)}):(0,o.breakWords)(A,e),n=r.length,a=t.parentNode?t.parentNode.ownerDocument.defaultView:null,u=a?a.pageXOffset:0,Q=a?a.pageYOffset:0,w=[],U=0,g=0;g<n;g++){var C=r[g];if(e.style.textDecoration!==B.TEXT_DECORATION.NONE||C.trim().length>0)if(s.default.SUPPORT_RANGE_BOUNDS)w.push(new i(C,l(t,U,C.length,u,Q)));else{var d=t.splitText(C.length);w.push(new i(C,c(t,u,Q))),t=d}else s.default.SUPPORT_RANGE_BOUNDS||(t=t.splitText(C.length));U+=C.length}return w},function(A,e,t){var r=A.ownerDocument.createElement("html2canvaswrapper");r.appendChild(A.cloneNode(!0));var B=A.parentNode;if(B){B.replaceChild(r,A);var a=(0,n.parseBounds)(r,e,t);return r.firstChild&&B.replaceChild(r.firstChild,r),a}return new n.Bounds(0,0,0,0)}),l=function(A,e,t,r,B){var a=A.ownerDocument.createRange();return a.setStart(A,e),a.setEnd(A,e+t),n.Bounds.fromClientRect(a.getBoundingClientRect(),r,B)}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function A(A,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(A,r.key,r)}}return function(e,t,r){return t&&A(e.prototype,t),r&&A(e,r),e}}();var n=function(){function A(e){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.element=e}return r(A,[{key:"render",value:function(A){var e=this;this.options=A,this.canvas=document.createElement("canvas"),this.ctx=this.canvas.getContext("2d"),this.canvas.width=Math.floor(A.width)*A.scale,this.canvas.height=Math.floor(A.height)*A.scale,this.canvas.style.width=A.width+"px",this.canvas.style.height=A.height+"px",A.logger.log("ForeignObject renderer initialized ("+A.width+"x"+A.height+" at "+A.x+","+A.y+") with scale "+A.scale);var t=B(Math.max(A.windowWidth,A.width)*A.scale,Math.max(A.windowHeight,A.height)*A.scale,A.scrollX*A.scale,A.scrollY*A.scale,this.element);return a(t).then(function(t){return A.backgroundColor&&(e.ctx.fillStyle=A.backgroundColor.toString(),e.ctx.fillRect(0,0,A.width*A.scale,A.height*A.scale)),e.ctx.drawImage(t,-A.x*A.scale,-A.y*A.scale),e.canvas})}}]),A}();e.default=n;var B=e.createForeignObjectSVG=function(A,e,t,r,n){var B="http://www.w3.org/2000/svg",a=document.createElementNS(B,"svg"),s=document.createElementNS(B,"foreignObject");return a.setAttributeNS(null,"width",A),a.setAttributeNS(null,"height",e),s.setAttributeNS(null,"width","100%"),s.setAttributeNS(null,"height","100%"),s.setAttributeNS(null,"x",t),s.setAttributeNS(null,"y",r),s.setAttributeNS(null,"externalResourcesRequired","true"),a.appendChild(s),s.appendChild(n),a},a=e.loadSerializedSVG=function(A){return new Promise(function(e,t){var r=new Image;r.onload=function(){return e(r)},r.onerror=t,r.src="data:image/svg+xml;charset=utf-8,"+encodeURIComponent((new XMLSerializer).serializeToString(A))})}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.breakWords=e.fromCodePoint=e.toCodePoints=void 0;var r=t(46);Object.defineProperty(e,"toCodePoints",{enumerable:!0,get:function(){return r.toCodePoints}}),Object.defineProperty(e,"fromCodePoint",{enumerable:!0,get:function(){return r.fromCodePoint}});var n,B=t(3),a=((n=B)&&n.__esModule,t(18));e.breakWords=function(A,e){for(var t=(0,r.LineBreaker)(A,{lineBreak:e.style.lineBreak,wordBreak:e.style.overflowWrap===a.OVERFLOW_WRAP.BREAK_WORD?"break-word":e.style.wordBreak}),n=[],B=void 0;!(B=t.next()).done;)n.push(B.value.slice());return n}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.FontMetrics=void 0;var r=function(){function A(A,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(A,r.key,r)}}return function(e,t,r){return t&&A(e.prototype,t),r&&A(e,r),e}}(),n=t(4);e.FontMetrics=function(){function A(e){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this._data={},this._document=e}return r(A,[{key:"_parseMetrics",value:function(A){var e=this._document.createElement("div"),t=this._document.createElement("img"),r=this._document.createElement("span"),B=this._document.body;if(!B)throw new Error("");e.style.visibility="hidden",e.style.fontFamily=A.fontFamily,e.style.fontSize=A.fontSize,e.style.margin="0",e.style.padding="0",B.appendChild(e),t.src=n.SMALL_IMAGE,t.width=1,t.height=1,t.style.margin="0",t.style.padding="0",t.style.verticalAlign="baseline",r.style.fontFamily=A.fontFamily,r.style.fontSize=A.fontSize,r.style.margin="0",r.style.padding="0",r.appendChild(this._document.createTextNode("Hidden Text")),e.appendChild(r),e.appendChild(t);var a=t.offsetTop-r.offsetTop+2;e.removeChild(r),e.appendChild(this._document.createTextNode("Hidden Text")),e.style.lineHeight="normal",t.style.verticalAlign="super";var s=t.offsetTop-e.offsetTop+2;return B.removeChild(e),{baseline:a,middle:s}}},{key:"getMetrics",value:function(A){var e=A.fontFamily+" "+A.fontSize;return void 0===this._data[e]&&(this._data[e]=this._parseMetrics(A)),this._data[e]}}]),A}()},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Proxy=void 0;var r,n=t(10),B=(r=n)&&r.__esModule?r:{default:r};e.Proxy=function(A,e){if(!e.proxy)return Promise.reject(null);var t=e.proxy;return new Promise(function(r,n){var a=B.default.SUPPORT_CORS_XHR&&B.default.SUPPORT_RESPONSE_TYPE?"blob":"text",s=B.default.SUPPORT_CORS_XHR?new XMLHttpRequest:new XDomainRequest;if(s.onload=function(){if(s instanceof XMLHttpRequest)if(200===s.status)if("text"===a)r(s.response);else{var A=new FileReader;A.addEventListener("load",function(){return r(A.result)},!1),A.addEventListener("error",function(A){return n(A)},!1),A.readAsDataURL(s.response)}else n("");else r(s.responseText)},s.onerror=n,s.open("GET",t+"?url="+encodeURIComponent(A)+"&responseType="+a),"text"!==a&&s instanceof XMLHttpRequest&&(s.responseType=a),e.imageTimeout){var o=e.imageTimeout;s.timeout=o,s.ontimeout=function(){return n("")}}s.send()})}},function(A,e,t){"use strict";var r=Object.assign||function(A){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(A[r]=t[r])}return A},n=s(t(15)),B=s(t(16)),a=t(28);function s(A){return A&&A.__esModule?A:{default:A}}var o=function(A,e){var t=e||{},s=new B.default("boolean"!=typeof t.logging||t.logging);s.log("html2canvas 1.0.0-alpha.12");var o=A.ownerDocument;if(!o)return Promise.reject("Provided element is not within a Document");var i=o.defaultView,c={async:!0,allowTaint:!1,backgroundColor:"#ffffff",imageTimeout:15e3,logging:!0,proxy:null,removeContainer:!0,foreignObjectRendering:!1,scale:i.devicePixelRatio||1,target:new n.default(t.canvas),useCORS:!1,windowWidth:i.innerWidth,windowHeight:i.innerHeight,scrollX:i.pageXOffset,scrollY:i.pageYOffset},l=(0,a.renderElement)(A,r({},c,t),s);return l};o.CanvasRenderer=n.default,A.exports=o},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.renderElement=void 0;var r=function(){return function(A,e){if(Array.isArray(A))return A;if(Symbol.iterator in Object(A))return function(A,e){var t=[],r=!0,n=!1,B=void 0;try{for(var a,s=A[Symbol.iterator]();!(r=(a=s.next()).done)&&(t.push(a.value),!e||t.length!==e);r=!0);}catch(A){n=!0,B=A}finally{try{!r&&s.return&&s.return()}finally{if(n)throw B}}return t}(A,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),n=(Q(t(16)),t(29)),B=Q(t(51)),a=Q(t(23)),s=Q(t(10)),o=t(2),i=t(54),c=t(25),l=t(0),u=Q(l);function Q(A){return A&&A.__esModule?A:{default:A}}e.renderElement=function A(e,t,Q){var w=e.ownerDocument,U=new o.Bounds(t.scrollX,t.scrollY,t.windowWidth,t.windowHeight),g=w.documentElement?new u.default(getComputedStyle(w.documentElement).backgroundColor):l.TRANSPARENT,C=w.body?new u.default(getComputedStyle(w.body).backgroundColor):l.TRANSPARENT,d=e===w.documentElement?g.isTransparent()?C.isTransparent()?t.backgroundColor?new u.default(t.backgroundColor):null:C:g:t.backgroundColor?new u.default(t.backgroundColor):null;return(t.foreignObjectRendering?s.default.SUPPORT_FOREIGNOBJECT_DRAWING:Promise.resolve(!1)).then(function(s){return s?(u=new i.DocumentCloner(e,t,Q,!0,A)).inlineFonts(w).then(function(){return u.resourceLoader.ready()}).then(function(){var A=new a.default(u.documentElement),r=w.defaultView,n=r.pageXOffset,B=r.pageYOffset,s="HTML"===e.tagName||"BODY"===e.tagName?(0,o.parseDocumentSize)(w):(0,o.parseBounds)(e,n,B),i=s.width,c=s.height,l=s.left,U=s.top;return A.render({backgroundColor:d,logger:Q,scale:t.scale,x:"number"==typeof t.x?t.x:l,y:"number"==typeof t.y?t.y:U,width:"number"==typeof t.width?t.width:Math.ceil(i),height:"number"==typeof t.height?t.height:Math.ceil(c),windowWidth:t.windowWidth,windowHeight:t.windowHeight,scrollX:t.scrollX,scrollY:t.scrollY})}):(0,i.cloneWindow)(w,U,e,t,Q,A).then(function(A){var e=r(A,3),a=e[0],s=e[1],i=e[2];var u=(0,n.NodeParser)(s,i,Q),U=s.ownerDocument;return d===u.container.style.background.backgroundColor&&(u.container.style.background.backgroundColor=l.TRANSPARENT),i.ready().then(function(A){var e=new c.FontMetrics(U);var r=U.defaultView,n=r.pageXOffset,i=r.pageYOffset,l="HTML"===s.tagName||"BODY"===s.tagName?(0,o.parseDocumentSize)(w):(0,o.parseBounds)(s,n,i),g=l.width,C=l.height,F=l.left,E=l.top,f={backgroundColor:d,fontMetrics:e,imageStore:A,logger:Q,scale:t.scale,x:"number"==typeof t.x?t.x:F,y:"number"==typeof t.y?t.y:E,width:"number"==typeof t.width?t.width:Math.ceil(g),height:"number"==typeof t.height?t.height:Math.ceil(C)};if(Array.isArray(t.target))return Promise.all(t.target.map(function(A){return new B.default(A,f).render(u)}));var h=new B.default(t.target,f).render(u);return!0===t.removeContainer&&a.parentNode&&a.parentNode.removeChild(a),h})});var u})}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.NodeParser=void 0;var r=i(t(30)),n=i(t(3)),B=i(t(9)),a=t(21),s=t(14),o=t(8);function i(A){return A&&A.__esModule?A:{default:A}}e.NodeParser=function(A,e,t){var B=0,a=new n.default(A,null,e,B++),s=new r.default(a,null,!0);return l(A,a,s,e,B),s};var c=["SCRIPT","HEAD","TITLE","OBJECT","BR","OPTION"],l=function A(e,t,i,l,w){for(var U,g=e.firstChild;g;g=U){U=g.nextSibling;var C=g.ownerDocument.defaultView;if(g instanceof C.Text||g instanceof Text||C.parent&&g instanceof C.parent.Text)g.data.trim().length>0&&t.childNodes.push(B.default.fromTextNode(g,t));else if(g instanceof C.HTMLElement||g instanceof HTMLElement||C.parent&&g instanceof C.parent.HTMLElement){if(-1===c.indexOf(g.nodeName)){var d=new n.default(g,t,l,w++);if(d.isVisible()){"INPUT"===g.tagName?(0,a.inlineInputElement)(g,d):"TEXTAREA"===g.tagName?(0,a.inlineTextAreaElement)(g,d):"SELECT"===g.tagName?(0,a.inlineSelectElement)(g,d):d.style.listStyle&&d.style.listStyle.listStyleType!==o.LIST_STYLE_TYPE.NONE&&(0,s.inlineListItemElement)(g,d,l);var F="TEXTAREA"!==g.tagName,E=u(d,g);if(E||Q(d)){var f=E||d.isPositioned()?i.getRealParentStackingContext():i,h=new r.default(d,f,E);f.contexts.push(h),F&&A(g,d,h,l,w)}else i.children.push(d),F&&A(g,d,i,l,w)}}}else if(g instanceof C.SVGSVGElement||g instanceof SVGSVGElement||C.parent&&g instanceof C.parent.SVGSVGElement){var H=new n.default(g,t,l,w++),p=u(H,g);if(p||Q(H)){var N=p||H.isPositioned()?i.getRealParentStackingContext():i,I=new r.default(H,N,p);N.contexts.push(I)}else i.children.push(H)}}},u=function(A,e){return A.isRootElement()||A.isPositionedWithZIndex()||A.style.opacity<1||A.isTransformed()||w(A,e)},Q=function(A){return A.isPositioned()||A.isFloating()},w=function(A,e){return"BODY"===e.nodeName&&A.parent instanceof n.default&&A.parent.style.background.backgroundColor.isTransparent()}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r,n=function(){function A(A,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(A,r.key,r)}}return function(e,t,r){return t&&A(e.prototype,t),r&&A(e,r),e}}(),B=t(3);(r=B)&&r.__esModule,t(19);var a=function(){function A(e,t,r){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.container=e,this.parent=t,this.contexts=[],this.children=[],this.treatAsRealStackingContext=r}return n(A,[{key:"getOpacity",value:function(){return this.parent?this.container.style.opacity*this.parent.getOpacity():this.container.style.opacity}},{key:"getRealParentStackingContext",value:function(){return!this.parent||this.treatAsRealStackingContext?this:this.parent.getRealParentStackingContext()}}]),A}();e.default=a},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});e.default=function A(e,t){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.width=e,this.height=t}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r,n=function(){function A(A,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(A,r.key,r)}}return function(e,t,r){return t&&A(e.prototype,t),r&&A(e,r),e}}(),B=t(6),a=t(7),s=(r=a)&&r.__esModule?r:{default:r};var o=function(A,e,t){return new s.default(A.x+(e.x-A.x)*t,A.y+(e.y-A.y)*t)},i=function(){function A(e,t,r,n){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.type=B.PATH.BEZIER_CURVE,this.start=e,this.startControl=t,this.endControl=r,this.end=n}return n(A,[{key:"subdivide",value:function(e,t){var r=o(this.start,this.startControl,e),n=o(this.startControl,this.endControl,e),B=o(this.endControl,this.end,e),a=o(r,n,e),s=o(n,B,e),i=o(a,s,e);return t?new A(this.start,r,a,i):new A(i,s,B,this.end)}},{key:"reverse",value:function(){return new A(this.end,this.endControl,this.startControl,this.start)}}]),A}();e.default=i},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.parseBorderRadius=void 0;var r,n=function(){return function(A,e){if(Array.isArray(A))return A;if(Symbol.iterator in Object(A))return function(A,e){var t=[],r=!0,n=!1,B=void 0;try{for(var a,s=A[Symbol.iterator]();!(r=(a=s.next()).done)&&(t.push(a.value),!e||t.length!==e);r=!0);}catch(A){n=!0,B=A}finally{try{!r&&s.return&&s.return()}finally{if(n)throw B}}return t}(A,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),B=t(1),a=(r=B)&&r.__esModule?r:{default:r};var s=["top-left","top-right","bottom-right","bottom-left"];e.parseBorderRadius=function(A){return s.map(function(e){var t=A.getPropertyValue("border-"+e+"-radius").split(" ").map(a.default.create),r=n(t,2),B=r[0],s=r[1];return void 0===s?[B,B]:[B,s]})}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=e.DISPLAY={NONE:1,BLOCK:2,INLINE:4,RUN_IN:8,FLOW:16,FLOW_ROOT:32,TABLE:64,FLEX:128,GRID:256,RUBY:512,SUBGRID:1024,LIST_ITEM:2048,TABLE_ROW_GROUP:4096,TABLE_HEADER_GROUP:8192,TABLE_FOOTER_GROUP:16384,TABLE_ROW:32768,TABLE_CELL:65536,TABLE_COLUMN_GROUP:1<<17,TABLE_COLUMN:1<<18,TABLE_CAPTION:1<<19,RUBY_BASE:1<<20,RUBY_TEXT:1<<21,RUBY_BASE_CONTAINER:1<<22,RUBY_TEXT_CONTAINER:1<<23,CONTENTS:1<<24,INLINE_BLOCK:1<<25,INLINE_LIST_ITEM:1<<26,INLINE_TABLE:1<<27,INLINE_FLEX:1<<28,INLINE_GRID:1<<29},n=function(A,e){return A|function(A){switch(A){case"block":return r.BLOCK;case"inline":return r.INLINE;case"run-in":return r.RUN_IN;case"flow":return r.FLOW;case"flow-root":return r.FLOW_ROOT;case"table":return r.TABLE;case"flex":return r.FLEX;case"grid":return r.GRID;case"ruby":return r.RUBY;case"subgrid":return r.SUBGRID;case"list-item":return r.LIST_ITEM;case"table-row-group":return r.TABLE_ROW_GROUP;case"table-header-group":return r.TABLE_HEADER_GROUP;case"table-footer-group":return r.TABLE_FOOTER_GROUP;case"table-row":return r.TABLE_ROW;case"table-cell":return r.TABLE_CELL;case"table-column-group":return r.TABLE_COLUMN_GROUP;case"table-column":return r.TABLE_COLUMN;case"table-caption":return r.TABLE_CAPTION;case"ruby-base":return r.RUBY_BASE;case"ruby-text":return r.RUBY_TEXT;case"ruby-base-container":return r.RUBY_BASE_CONTAINER;case"ruby-text-container":return r.RUBY_TEXT_CONTAINER;case"contents":return r.CONTENTS;case"inline-block":return r.INLINE_BLOCK;case"inline-list-item":return r.INLINE_LIST_ITEM;case"inline-table":return r.INLINE_TABLE;case"inline-flex":return r.INLINE_FLEX;case"inline-grid":return r.INLINE_GRID}return r.NONE}(e)};e.parseDisplay=function(A){return A.split(" ").reduce(n,0)}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=e.FLOAT={NONE:0,LEFT:1,RIGHT:2,INLINE_START:3,INLINE_END:4};e.parseCSSFloat=function(A){switch(A){case"left":return r.LEFT;case"right":return r.RIGHT;case"inline-start":return r.INLINE_START;case"inline-end":return r.INLINE_END}return r.NONE}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});e.parseFont=function(A){return{fontFamily:A.fontFamily,fontSize:A.fontSize,fontStyle:A.fontStyle,fontVariant:A.fontVariant,fontWeight:function(A){switch(A){case"normal":return 400;case"bold":return 700}var e=parseInt(A,10);return isNaN(e)?400:e}(A.fontWeight)}}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});e.parseLetterSpacing=function(A){if("normal"===A)return 0;var e=parseFloat(A);return isNaN(e)?0:e}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=e.LINE_BREAK={NORMAL:"normal",STRICT:"strict"};e.parseLineBreak=function(A){switch(A){case"strict":return r.STRICT;case"normal":default:return r.NORMAL}}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.parseMargin=void 0;var r,n=t(1),B=(r=n)&&r.__esModule?r:{default:r};var a=["top","right","bottom","left"];e.parseMargin=function(A){return a.map(function(e){return new B.default(A.getPropertyValue("margin-"+e))})}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=e.OVERFLOW={VISIBLE:0,HIDDEN:1,SCROLL:2,AUTO:3};e.parseOverflow=function(A){switch(A){case"hidden":return r.HIDDEN;case"scroll":return r.SCROLL;case"auto":return r.AUTO;case"visible":default:return r.VISIBLE}}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.parseTextShadow=void 0;var r,n=t(0),B=(r=n)&&r.__esModule?r:{default:r};var a=/^([+-]|\d|\.)$/i;e.parseTextShadow=function(A){if("none"===A||"string"!=typeof A)return null;for(var e="",t=!1,r=[],n=[],s=0,o=null,i=function(){e.length&&(t?r.push(parseFloat(e)):o=new B.default(e)),t=!1,e=""},c=function(){r.length&&null!==o&&n.push({color:o,offsetX:r[0]||0,offsetY:r[1]||0,blur:r[2]||0}),r.splice(0,r.length),o=null},l=0;l<A.length;l++){var u=A[l];switch(u){case"(":e+=u,s++;break;case")":e+=u,s--;break;case",":0===s?(i(),c()):e+=u;break;case" ":0===s?i():e+=u;break;default:0===e.length&&a.test(u)&&(t=!0),e+=u}}return i(),c(),0===n.length?null:n}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.parseTransform=void 0;var r,n=t(1),B=(r=n)&&r.__esModule?r:{default:r};var a=function(A){return parseFloat(A.trim())},s=/(matrix|matrix3d)\((.+)\)/,o=(e.parseTransform=function(A){var e=i(A.transform||A.webkitTransform||A.mozTransform||A.msTransform||A.oTransform);return null===e?null:{transform:e,transformOrigin:o(A.transformOrigin||A.webkitTransformOrigin||A.mozTransformOrigin||A.msTransformOrigin||A.oTransformOrigin)}},function(A){if("string"!=typeof A){var e=new B.default("0");return[e,e]}var t=A.split(" ").map(B.default.create);return[t[0],t[1]]}),i=function(A){if("none"===A||"string"!=typeof A)return null;var e=A.match(s);if(e){if("matrix"===e[1]){var t=e[2].split(",").map(a);return[t[0],t[1],t[2],t[3],t[4],t[5]]}var r=e[2].split(",").map(a);return[r[0],r[1],r[4],r[5],r[12],r[13]]}return null}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=e.VISIBILITY={VISIBLE:0,HIDDEN:1,COLLAPSE:2};e.parseVisibility=function(A){switch(A){case"hidden":return r.HIDDEN;case"collapse":return r.COLLAPSE;case"visible":default:return r.VISIBLE}}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=e.WORD_BREAK={NORMAL:"normal",BREAK_ALL:"break-all",KEEP_ALL:"keep-all"};e.parseWordBreak=function(A){switch(A){case"break-all":return r.BREAK_ALL;case"keep-all":return r.KEEP_ALL;case"normal":default:return r.NORMAL}}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});e.parseZIndex=function(A){var e="auto"===A;return{auto:e,order:e?0:parseInt(A,10)}}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=t(13);Object.defineProperty(e,"toCodePoints",{enumerable:!0,get:function(){return r.toCodePoints}}),Object.defineProperty(e,"fromCodePoint",{enumerable:!0,get:function(){return r.fromCodePoint}});var n=t(47);Object.defineProperty(e,"LineBreaker",{enumerable:!0,get:function(){return n.LineBreaker}})},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.LineBreaker=e.inlineBreakOpportunities=e.lineBreakAtIndex=e.codePointsToCharacterClasses=e.UnicodeTrie=e.BREAK_ALLOWED=e.BREAK_NOT_ALLOWED=e.BREAK_MANDATORY=e.classes=e.LETTER_NUMBER_MODIFIER=void 0;var r,n=function(){function A(A,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(A,r.key,r)}}return function(e,t,r){return t&&A(e.prototype,t),r&&A(e,r),e}}(),B=function(){return function(A,e){if(Array.isArray(A))return A;if(Symbol.iterator in Object(A))return function(A,e){var t=[],r=!0,n=!1,B=void 0;try{for(var a,s=A[Symbol.iterator]();!(r=(a=s.next()).done)&&(t.push(a.value),!e||t.length!==e);r=!0);}catch(A){n=!0,B=A}finally{try{!r&&s.return&&s.return()}finally{if(n)throw B}}return t}(A,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),a=t(48),s=t(49),o=(r=s)&&r.__esModule?r:{default:r},i=t(13);var c=e.LETTER_NUMBER_MODIFIER=50,l=10,u=13,Q=15,w=17,U=18,g=19,C=20,d=21,F=22,E=24,f=25,h=26,H=27,p=28,N=30,I=32,K=33,T=34,m=35,v=37,y=38,b=39,S=40,L=42,_=(e.classes={BK:1,CR:2,LF:3,CM:4,NL:5,SG:6,WJ:7,ZW:8,GL:9,SP:l,ZWJ:11,B2:12,BA:u,BB:14,HY:Q,CB:16,CL:w,CP:U,EX:g,IN:C,NS:d,OP:F,QU:23,IS:E,NU:f,PO:h,PR:H,SY:p,AI:29,AL:N,CJ:31,EB:I,EM:K,H2:T,H3:m,HL:36,ID:v,JL:y,JV:b,JT:S,RI:41,SA:L,XX:43},e.BREAK_MANDATORY="!"),D=e.BREAK_NOT_ALLOWED="×",M=e.BREAK_ALLOWED="÷",O=e.UnicodeTrie=(0,a.createTrieFromBase64)(o.default),R=[N,36],P=[1,2,3,5],X=[l,8],z=[H,h],x=P.concat(X),V=[y,b,S,T,m],k=[Q,u],J=e.codePointsToCharacterClasses=function(A){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"strict",t=[],r=[],n=[];return A.forEach(function(A,B){var a=O.get(A);if(a>c?(n.push(!0),a-=c):n.push(!1),-1!==["normal","auto","loose"].indexOf(e)&&-1!==[8208,8211,12316,12448].indexOf(A))return r.push(B),t.push(16);if(4===a||11===a){if(0===B)return r.push(B),t.push(N);var s=t[B-1];return-1===x.indexOf(s)?(r.push(r[B-1]),t.push(s)):(r.push(B),t.push(N))}return r.push(B),31===a?t.push("strict"===e?d:v):a===L?t.push(N):29===a?t.push(N):43===a?A>=131072&&A<=196605||A>=196608&&A<=262141?t.push(v):t.push(N):void t.push(a)}),[r,t,n]},G=function(A,e,t,r){var n=r[t];if(Array.isArray(A)?-1!==A.indexOf(n):A===n)for(var B=t;B<=r.length;){var a=r[++B];if(a===e)return!0;if(a!==l)break}if(n===l)for(var s=t;s>0;){var o=r[--s];if(Array.isArray(A)?-1!==A.indexOf(o):A===o)for(var i=t;i<=r.length;){var c=r[++i];if(c===e)return!0;if(c!==l)break}if(o!==l)break}return!1},Y=function(A,e){for(var t=A;t>=0;){var r=e[t];if(r!==l)return r;t--}return 0},W=function(A,e,t,r,n){if(0===t[r])return D;var B=r-1;if(Array.isArray(n)&&!0===n[B])return D;var a=B-1,s=B+1,o=e[B],i=a>=0?e[a]:0,c=e[s];if(2===o&&3===c)return D;if(-1!==P.indexOf(o))return _;if(-1!==P.indexOf(c))return D;if(-1!==X.indexOf(c))return D;if(8===Y(B,e))return M;if(11===O.get(A[B])&&(c===v||c===I||c===K))return D;if(7===o||7===c)return D;if(9===o)return D;if(-1===[l,u,Q].indexOf(o)&&9===c)return D;if(-1!==[w,U,g,E,p].indexOf(c))return D;if(Y(B,e)===F)return D;if(G(23,F,B,e))return D;if(G([w,U],d,B,e))return D;if(G(12,12,B,e))return D;if(o===l)return M;if(23===o||23===c)return D;if(16===c||16===o)return M;if(-1!==[u,Q,d].indexOf(c)||14===o)return D;if(36===i&&-1!==k.indexOf(o))return D;if(o===p&&36===c)return D;if(c===C&&-1!==R.concat(C,g,f,v,I,K).indexOf(o))return D;if(-1!==R.indexOf(c)&&o===f||-1!==R.indexOf(o)&&c===f)return D;if(o===H&&-1!==[v,I,K].indexOf(c)||-1!==[v,I,K].indexOf(o)&&c===h)return D;if(-1!==R.indexOf(o)&&-1!==z.indexOf(c)||-1!==z.indexOf(o)&&-1!==R.indexOf(c))return D;if(-1!==[H,h].indexOf(o)&&(c===f||-1!==[F,Q].indexOf(c)&&e[s+1]===f)||-1!==[F,Q].indexOf(o)&&c===f||o===f&&-1!==[f,p,E].indexOf(c))return D;if(-1!==[f,p,E,w,U].indexOf(c))for(var N=B;N>=0;){var L=e[N];if(L===f)return D;if(-1===[p,E].indexOf(L))break;N--}if(-1!==[H,h].indexOf(c))for(var x=-1!==[w,U].indexOf(o)?a:B;x>=0;){var J=e[x];if(J===f)return D;if(-1===[p,E].indexOf(J))break;x--}if(y===o&&-1!==[y,b,T,m].indexOf(c)||-1!==[b,T].indexOf(o)&&-1!==[b,S].indexOf(c)||-1!==[S,m].indexOf(o)&&c===S)return D;if(-1!==V.indexOf(o)&&-1!==[C,h].indexOf(c)||-1!==V.indexOf(c)&&o===H)return D;if(-1!==R.indexOf(o)&&-1!==R.indexOf(c))return D;if(o===E&&-1!==R.indexOf(c))return D;if(-1!==R.concat(f).indexOf(o)&&c===F||-1!==R.concat(f).indexOf(c)&&o===U)return D;if(41===o&&41===c){for(var W=t[B],j=1;W>0&&41===e[--W];)j++;if(j%2!=0)return D}return o===I&&c===K?D:M},j=(e.lineBreakAtIndex=function(A,e){if(0===e)return D;if(e>=A.length)return _;var t=J(A),r=B(t,2),n=r[0],a=r[1];return W(A,a,n,e)},function(A,e){e||(e={lineBreak:"normal",wordBreak:"normal"});var t=J(A,e.lineBreak),r=B(t,3),n=r[0],a=r[1],s=r[2];return"break-all"!==e.wordBreak&&"break-word"!==e.wordBreak||(a=a.map(function(A){return-1!==[f,N,L].indexOf(A)?v:A})),[n,a,"keep-all"===e.wordBreak?s.map(function(e,t){return e&&A[t]>=19968&&A[t]<=40959}):null]}),q=(e.inlineBreakOpportunities=function(A,e){var t=(0,i.toCodePoints)(A),r=D,n=j(t,e),a=B(n,3),s=a[0],o=a[1],c=a[2];return t.forEach(function(A,e){r+=(0,i.fromCodePoint)(A)+(e>=t.length-1?_:W(t,o,s,e+1,c))}),r},function(){function A(e,t,r,n){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this._codePoints=e,this.required=t===_,this.start=r,this.end=n}return n(A,[{key:"slice",value:function(){return i.fromCodePoint.apply(void 0,function(A){if(Array.isArray(A)){for(var e=0,t=Array(A.length);e<A.length;e++)t[e]=A[e];return t}return Array.from(A)}(this._codePoints.slice(this.start,this.end)))}}]),A}());e.LineBreaker=function(A,e){var t=(0,i.toCodePoints)(A),r=j(t,e),n=B(r,3),a=n[0],s=n[1],o=n[2],c=t.length,l=0,u=0;return{next:function(){if(u>=c)return{done:!0};for(var A=D;u<c&&(A=W(t,s,a,++u,o))===D;);if(A!==D||u===c){var e=new q(t,A,l,u);return l=u,{value:e,done:!1}}return{done:!0}}}}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Trie=e.createTrieFromBase64=e.UTRIE2_INDEX_2_MASK=e.UTRIE2_INDEX_2_BLOCK_LENGTH=e.UTRIE2_OMITTED_BMP_INDEX_1_LENGTH=e.UTRIE2_INDEX_1_OFFSET=e.UTRIE2_UTF8_2B_INDEX_2_LENGTH=e.UTRIE2_UTF8_2B_INDEX_2_OFFSET=e.UTRIE2_INDEX_2_BMP_LENGTH=e.UTRIE2_LSCP_INDEX_2_LENGTH=e.UTRIE2_DATA_MASK=e.UTRIE2_DATA_BLOCK_LENGTH=e.UTRIE2_LSCP_INDEX_2_OFFSET=e.UTRIE2_SHIFT_1_2=e.UTRIE2_INDEX_SHIFT=e.UTRIE2_SHIFT_1=e.UTRIE2_SHIFT_2=void 0;var r=function(){function A(A,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(A,r.key,r)}}return function(e,t,r){return t&&A(e.prototype,t),r&&A(e,r),e}}(),n=t(13);var B=e.UTRIE2_SHIFT_2=5,a=e.UTRIE2_SHIFT_1=11,s=e.UTRIE2_INDEX_SHIFT=2,o=e.UTRIE2_SHIFT_1_2=a-B,i=e.UTRIE2_LSCP_INDEX_2_OFFSET=65536>>B,c=e.UTRIE2_DATA_BLOCK_LENGTH=1<<B,l=e.UTRIE2_DATA_MASK=c-1,u=e.UTRIE2_LSCP_INDEX_2_LENGTH=1024>>B,Q=e.UTRIE2_INDEX_2_BMP_LENGTH=i+u,w=e.UTRIE2_UTF8_2B_INDEX_2_OFFSET=Q,U=e.UTRIE2_UTF8_2B_INDEX_2_LENGTH=32,g=e.UTRIE2_INDEX_1_OFFSET=w+U,C=e.UTRIE2_OMITTED_BMP_INDEX_1_LENGTH=65536>>a,d=e.UTRIE2_INDEX_2_BLOCK_LENGTH=1<<o,F=e.UTRIE2_INDEX_2_MASK=d-1,E=(e.createTrieFromBase64=function(A){var e=(0,n.decode)(A),t=Array.isArray(e)?(0,n.polyUint32Array)(e):new Uint32Array(e),r=Array.isArray(e)?(0,n.polyUint16Array)(e):new Uint16Array(e),B=r.slice(12,t[4]/2),a=2===t[5]?r.slice((24+t[4])/2):t.slice(Math.ceil((24+t[4])/4));return new E(t[0],t[1],t[2],t[3],B,a)},e.Trie=function(){function A(e,t,r,n,B,a){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.initialValue=e,this.errorValue=t,this.highStart=r,this.highValueIndex=n,this.index=B,this.data=a}return r(A,[{key:"get",value:function(A){var e=void 0;if(A>=0){if(A<55296||A>56319&&A<=65535)return e=((e=this.index[A>>B])<<s)+(A&l),this.data[e];if(A<=65535)return e=((e=this.index[i+(A-55296>>B)])<<s)+(A&l),this.data[e];if(A<this.highStart)return e=g-C+(A>>a),e=this.index[e],e+=A>>B&F,e=((e=this.index[e])<<s)+(A&l),this.data[e];if(A<=1114111)return this.data[this.highValueIndex]}return this.errorValue}}]),A}())},function(A,e,t){"use strict";A.exports="KwAAAAAAAAAACA4AIDoAAPAfAAACAAAAAAAIABAAGABAAEgAUABYAF4AZgBeAGYAYABoAHAAeABeAGYAfACEAIAAiACQAJgAoACoAK0AtQC9AMUAXgBmAF4AZgBeAGYAzQDVAF4AZgDRANkA3gDmAOwA9AD8AAQBDAEUARoBIgGAAIgAJwEvATcBPwFFAU0BTAFUAVwBZAFsAXMBewGDATAAiwGTAZsBogGkAawBtAG8AcIBygHSAdoB4AHoAfAB+AH+AQYCDgIWAv4BHgImAi4CNgI+AkUCTQJTAlsCYwJrAnECeQKBAk0CiQKRApkCoQKoArACuALAAsQCzAIwANQC3ALkAjAA7AL0AvwCAQMJAxADGAMwACADJgMuAzYDPgOAAEYDSgNSA1IDUgNaA1oDYANiA2IDgACAAGoDgAByA3YDfgOAAIQDgACKA5IDmgOAAIAAogOqA4AAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAK8DtwOAAIAAvwPHA88D1wPfAyAD5wPsA/QD/AOAAIAABAQMBBIEgAAWBB4EJgQuBDMEIAM7BEEEXgBJBCADUQRZBGEEaQQwADAAcQQ+AXkEgQSJBJEEgACYBIAAoASoBK8EtwQwAL8ExQSAAIAAgACAAIAAgACgAM0EXgBeAF4AXgBeAF4AXgBeANUEXgDZBOEEXgDpBPEE+QQBBQkFEQUZBSEFKQUxBTUFPQVFBUwFVAVcBV4AYwVeAGsFcwV7BYMFiwWSBV4AmgWgBacFXgBeAF4AXgBeAKsFXgCyBbEFugW7BcIFwgXIBcIFwgXQBdQF3AXkBesF8wX7BQMGCwYTBhsGIwYrBjMGOwZeAD8GRwZNBl4AVAZbBl4AXgBeAF4AXgBeAF4AXgBeAF4AXgBeAGMGXgBqBnEGXgBeAF4AXgBeAF4AXgBeAF4AXgB5BoAG4wSGBo4GkwaAAIADHgR5AF4AXgBeAJsGgABGA4AAowarBrMGswagALsGwwbLBjAA0wbaBtoG3QbaBtoG2gbaBtoG2gblBusG8wb7BgMHCwcTBxsHCwcjBysHMAc1BzUHOgdCB9oGSgdSB1oHYAfaBloHaAfaBlIH2gbaBtoG2gbaBtoG2gbaBjUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHbQdeAF4ANQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQd1B30HNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1B4MH2gaKB68EgACAAIAAgACAAIAAgACAAI8HlwdeAJ8HpweAAIAArwe3B14AXgC/B8UHygcwANAH2AfgB4AA6AfwBz4B+AcACFwBCAgPCBcIogEYAR8IJwiAAC8INwg/CCADRwhPCFcIXwhnCEoDGgSAAIAAgABvCHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIhAiLCI4IMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlggwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAANQc1BzUHNQc1BzUHNQc1BzUHNQc1B54INQc1B6II2gaqCLIIugiAAIAAvgjGCIAAgACAAIAAgACAAIAAgACAAIAAywiHAYAA0wiAANkI3QjlCO0I9Aj8CIAAgACAAAIJCgkSCRoJIgknCTYHLwk3CZYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiAAIAAAAFAAXgBeAGAAcABeAHwAQACQAKAArQC9AJ4AXgBeAE0A3gBRAN4A7AD8AMwBGgEAAKcBNwEFAUwBXAF4QkhCmEKnArcCgAHHAsABz4LAAcABwAHAAd+C6ABoAG+C/4LAAcABwAHAAc+DF4MAAcAB54M3gweDV4Nng3eDaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAEeDqABVg6WDqABoQ6gAaABoAHXDvcONw/3DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DncPAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcAB7cPPwlGCU4JMACAAIAAgABWCV4JYQmAAGkJcAl4CXwJgAkwADAAMAAwAIgJgACLCZMJgACZCZ8JowmrCYAAswkwAF4AXgB8AIAAuwkABMMJyQmAAM4JgADVCTAAMAAwADAAgACAAIAAgACAAIAAgACAAIAAqwYWBNkIMAAwADAAMADdCeAJ6AnuCR4E9gkwAP4JBQoNCjAAMACAABUK0wiAAB0KJAosCjQKgAAwADwKQwqAAEsKvQmdCVMKWwowADAAgACAALcEMACAAGMKgABrCjAAMAAwADAAMAAwADAAMAAwADAAMAAeBDAAMAAwADAAMAAwADAAMAAwADAAMAAwAIkEPQFzCnoKiQSCCooKkAqJBJgKoAqkCokEGAGsCrQKvArBCjAAMADJCtEKFQHZCuEK/gHpCvEKMAAwADAAMACAAIwE+QowAIAAPwEBCzAAMAAwADAAMACAAAkLEQswAIAAPwEZCyELgAAOCCkLMAAxCzkLMAAwADAAMAAwADAAXgBeAEELMAAwADAAMAAwADAAMAAwAEkLTQtVC4AAXAtkC4AAiQkwADAAMAAwADAAMAAwADAAbAtxC3kLgAuFC4sLMAAwAJMLlwufCzAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAApwswADAAMACAAIAAgACvC4AAgACAAIAAgACAALcLMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAvwuAAMcLgACAAIAAgACAAIAAyguAAIAAgACAAIAA0QswADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAANkLgACAAIAA4AswADAAMAAwADAAMAAwADAAMAAwADAAMAAwAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACJCR4E6AswADAAhwHwC4AA+AsADAgMEAwwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMACAAIAAGAwdDCUMMAAwAC0MNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQw1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHPQwwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADUHNQc1BzUHNQc1BzUHNQc2BzAAMAA5DDUHNQc1BzUHNQc1BzUHNQc1BzUHNQdFDDAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAgACAAIAATQxSDFoMMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAF4AXgBeAF4AXgBeAF4AYgxeAGoMXgBxDHkMfwxeAIUMXgBeAI0MMAAwADAAMAAwAF4AXgCVDJ0MMAAwADAAMABeAF4ApQxeAKsMswy7DF4Awgy9DMoMXgBeAF4AXgBeAF4AXgBeAF4AXgDRDNkMeQBqCeAM3Ax8AOYM7Az0DPgMXgBeAF4AXgBeAF4AXgBeAF4AXgBeAF4AXgBeAF4AXgCgAAANoAAHDQ4NFg0wADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAeDSYNMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAIAAgACAAIAAgACAAC4NMABeAF4ANg0wADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAD4NRg1ODVYNXg1mDTAAbQ0wADAAMAAwADAAMAAwADAA2gbaBtoG2gbaBtoG2gbaBnUNeg3CBYANwgWFDdoGjA3aBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gaUDZwNpA2oDdoG2gawDbcNvw3HDdoG2gbPDdYN3A3fDeYN2gbsDfMN2gbaBvoN/g3aBgYODg7aBl4AXgBeABYOXgBeACUG2gYeDl4AJA5eACwO2w3aBtoGMQ45DtoG2gbaBtoGQQ7aBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gZJDjUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1B1EO2gY1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQdZDjUHNQc1BzUHNQc1B2EONQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHaA41BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1B3AO2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gY1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1B2EO2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gZJDtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBkkOeA6gAKAAoAAwADAAMAAwAKAAoACgAKAAoACgAKAAgA4wADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAD//wQABAAEAAQABAAEAAQABAAEAA0AAwABAAEAAgAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAKABMAFwAeABsAGgAeABcAFgASAB4AGwAYAA8AGAAcAEsASwBLAEsASwBLAEsASwBLAEsAGAAYAB4AHgAeABMAHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAFgAbABIAHgAeAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQABYADQARAB4ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAAUABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAkAFgAaABsAGwAbAB4AHQAdAB4ATwAXAB4ADQAeAB4AGgAbAE8ATwAOAFAAHQAdAB0ATwBPABcATwBPAE8AFgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAB4AHgAeAB4AUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AHgAeAFAATwBAAE8ATwBPAEAATwBQAFAATwBQAB4AHgAeAB4AHgAeAB0AHQAdAB0AHgAdAB4ADgBQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgBQAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAJAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAkACQAJAAkACQAJAAkABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgAeAFAAHgAeAB4AKwArAFAAUABQAFAAGABQACsAKwArACsAHgAeAFAAHgBQAFAAUAArAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAUAAeAB4AHgAeAB4AHgArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwAYAA0AKwArAB4AHgAbACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQADQAEAB4ABAAEAB4ABAAEABMABAArACsAKwArACsAKwArACsAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAKwArACsAKwArAFYAVgBWAB4AHgArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AGgAaABoAGAAYAB4AHgAEAAQABAAEAAQABAAEAAQABAAEAAQAEwAEACsAEwATAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABLAEsASwBLAEsASwBLAEsASwBLABoAGQAZAB4AUABQAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQABMAUAAEAAQABAAEAAQABAAEAB4AHgAEAAQABAAEAAQABABQAFAABAAEAB4ABAAEAAQABABQAFAASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUAAeAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAFAABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQAUABQAB4AHgAYABMAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAFAABAAEAAQABAAEAFAABAAEAAQAUAAEAAQABAAEAAQAKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAArACsAHgArAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAFAABAAEAAQABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAAQABAANAA0ASwBLAEsASwBLAEsASwBLAEsASwAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQAKwBQAFAAUABQAFAAUABQAFAAKwArAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUAArAFAAKwArACsAUABQAFAAUAArACsABABQAAQABAAEAAQABAAEAAQAKwArAAQABAArACsABAAEAAQAUAArACsAKwArACsAKwArACsABAArACsAKwArAFAAUAArAFAAUABQAAQABAArACsASwBLAEsASwBLAEsASwBLAEsASwBQAFAAGgAaAFAAUABQAFAAUABMAB4AGwBQAB4AKwArACsABAAEAAQAKwBQAFAAUABQAFAAUAArACsAKwArAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUAArAFAAUAArAFAAUAArAFAAUAArACsABAArAAQABAAEAAQABAArACsAKwArAAQABAArACsABAAEAAQAKwArACsABAArACsAKwArACsAKwArAFAAUABQAFAAKwBQACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwAEAAQAUABQAFAABAArACsAKwArACsAKwArACsAKwArACsABAAEAAQAKwBQAFAAUABQAFAAUABQAFAAUAArAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUAArAFAAUAArAFAAUABQAFAAUAArACsABABQAAQABAAEAAQABAAEAAQABAArAAQABAAEACsABAAEAAQAKwArAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAAQABAArACsASwBLAEsASwBLAEsASwBLAEsASwAeABsAKwArACsAKwArACsAKwBQAAQABAAEAAQABAAEACsABAAEAAQAKwBQAFAAUABQAFAAUABQAFAAKwArAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQAKwArAAQABAArACsABAAEAAQAKwArACsAKwArACsAKwArAAQABAArACsAKwArAFAAUAArAFAAUABQAAQABAArACsASwBLAEsASwBLAEsASwBLAEsASwAeAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwAEAFAAKwBQAFAAUABQAFAAUAArACsAKwBQAFAAUAArAFAAUABQAFAAKwArACsAUABQACsAUAArAFAAUAArACsAKwBQAFAAKwArACsAUABQAFAAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwAEAAQABAAEAAQAKwArACsABAAEAAQAKwAEAAQABAAEACsAKwBQACsAKwArACsAKwArAAQAKwArACsAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLAFAAUABQAB4AHgAeAB4AHgAeABsAHgArACsAKwArACsABAAEAAQABAArAFAAUABQAFAAUABQAFAAUAArAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAFAABAAEAAQABAAEAAQABAArAAQABAAEACsABAAEAAQABAArACsAKwArACsAKwArAAQABAArAFAAUABQACsAKwArACsAKwBQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAB4AUAAEAAQABAArAFAAUABQAFAAUABQAFAAUAArAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQACsAKwAEAFAABAAEAAQABAAEAAQABAArAAQABAAEACsABAAEAAQABAArACsAKwArACsAKwArAAQABAArACsAKwArACsAKwArAFAAKwBQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAFAABAAEAAQABAAEAAQABAArAAQABAAEACsABAAEAAQABABQAB4AKwArACsAKwBQAFAAUAAEAFAAUABQAFAAUABQAFAAUABQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAFAAUABQAFAAUABQAFAAUABQABoAUABQAFAAUABQAFAAKwArAAQABAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQACsAUAArACsAUABQAFAAUABQAFAAUAArACsAKwAEACsAKwArACsABAAEAAQABAAEAAQAKwAEACsABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArAAQABAAeACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAAqAFwAXAAqACoAKgAqACoAKgAqACsAKwArACsAGwBcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAeAEsASwBLAEsASwBLAEsASwBLAEsADQANACsAKwArACsAKwBcAFwAKwBcACsAKwBcAFwAKwBcACsAKwBcACsAKwArACsAKwArAFwAXABcAFwAKwBcAFwAXABcAFwAXABcACsAXABcAFwAKwBcACsAXAArACsAXABcACsAXABcAFwAXAAqAFwAXAAqACoAKgAqACoAKgArACoAKgBcACsAKwBcAFwAXABcAFwAKwBcACsAKgAqACoAKgAqACoAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArAFwAXABcAFwAUAAOAA4ADgAOAB4ADgAOAAkADgAOAA0ACQATABMAEwATABMACQAeABMAHgAeAB4ABAAEAB4AHgAeAB4AHgAeAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAUABQAFAAUABQAFAAUAANAAQAHgAEAB4ABAAWABEAFgARAAQABABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAANAAQABAAEAAQABAANAAQABABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsADQANAB4AHgAeAB4AHgAeAAQAHgAeAB4AHgAeAB4AKwAeAB4ADgAOAA0ADgAeAB4AHgAeAB4ACQAJACsAKwArACsAKwBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqAFwASwBLAEsASwBLAEsASwBLAEsASwANAA0AHgAeAB4AHgBcAFwAXABcAFwAXAAqACoAKgAqAFwAXABcAFwAKgAqACoAXAAqACoAKgBcAFwAKgAqACoAKgAqACoAKgBcAFwAXAAqACoAKgAqAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAKgAqACoAKgAqACoAKgAqACoAXAAqAEsASwBLAEsASwBLAEsASwBLAEsAKgAqACoAKgAqACoAUABQAFAAUABQAFAAKwBQACsAKwArACsAKwBQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQACsAUAArAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUAArACsAUABQAFAAUABQAFAAUAArAFAAKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwAEAAQABAAeAA0AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQACsAKwANAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQABYAEQArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAADQANAA0AUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAABAAEAAQAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAA0ADQArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQACsABAAEACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoADQANABUAXAANAB4ADQAbAFwAKgArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArAB4AHgATABMADQANAA4AHgATABMAHgAEAAQABAAJACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAUABQAFAAUABQAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABABQACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwAeACsAKwArABMAEwBLAEsASwBLAEsASwBLAEsASwBLAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACsAKwBcAFwAXABcAFwAKwArACsAKwArACsAKwArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcACsAKwArACsAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBcACsAKwArACoAKgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEACsAKwAeAB4AXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAKgAqACoAKgAqACoAKgArACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgArACsABABLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAKgAqACoAKgAqACoAKgBcACoAKgAqACoAKgAqACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArAAQABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQAUABQAFAAUABQAFAAUAArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsADQANAB4ADQANAA0ADQAeAB4AHgAeAB4AHgAeAB4AHgAeAAQABAAEAAQABAAEAAQABAAEAB4AHgAeAB4AHgAeAB4AHgAeACsAKwArAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAUABQAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArACsAKwArACsAHgAeAB4AHgBQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwANAA0ADQANAA0ASwBLAEsASwBLAEsASwBLAEsASwArACsAKwBQAFAAUABLAEsASwBLAEsASwBLAEsASwBLAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAANAA0AUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsABAAEAAQAHgAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAFAAUABQAFAABABQAFAAUABQAAQABAAEAFAAUAAEAAQABAArACsAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwAEAAQABAAEAAQAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUAArAFAAKwBQACsAUAArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAHgAeAB4AHgAeAB4AHgAeAFAAHgAeAB4AUABQAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAKwArAB4AHgAeAB4AHgAeACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAUABQAFAAKwAeAB4AHgAeAB4AHgAeAA4AHgArAA0ADQANAA0ADQANAA0ACQANAA0ADQAIAAQACwAEAAQADQAJAA0ADQAMAB0AHQAeABcAFwAWABcAFwAXABYAFwAdAB0AHgAeABQAFAAUAA0AAQABAAQABAAEAAQABAAJABoAGgAaABoAGgAaABoAGgAeABcAFwAdABUAFQAeAB4AHgAeAB4AHgAYABYAEQAVABUAFQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgANAB4ADQANAA0ADQAeAA0ADQANAAcAHgAeAB4AHgArAAQABAAEAAQABAAEAAQABAAEAAQAUABQACsAKwBPAFAAUABQAFAAUAAeAB4AHgAWABEATwBQAE8ATwBPAE8AUABQAFAAUABQAB4AHgAeABYAEQArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAGwAbABsAGwAbABsAGwAaABsAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGwAaABsAGwAbABsAGgAbABsAGgAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbABsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgBQABoAHgAdAB4AUAAeABoAHgAeAB4AHgAeAB4AHgAeAB4ATwAeAFAAGwAeAB4AUABQAFAAUABQAB4AHgAeAB0AHQAeAFAAHgBQAB4AUAAeAFAATwBQAFAAHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAB4AUABQAFAAUABPAE8AUABQAFAAUABQAE8AUABQAE8AUABPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBQAFAAUABQAE8ATwBPAE8ATwBPAE8ATwBPAE8AUABQAFAAUABQAFAAUABQAFAAHgAeAFAAUABQAFAATwAeAB4AKwArACsAKwAdAB0AHQAdAB0AHQAdAB0AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAeAB0AHQAeAB4AHgAdAB0AHgAeAB0AHgAeAB4AHQAeAB0AGwAbAB4AHQAeAB4AHgAeAB0AHgAeAB0AHQAdAB0AHgAeAB0AHgAdAB4AHQAdAB0AHQAdAB0AHgAdAB4AHgAeAB4AHgAdAB0AHQAdAB4AHgAeAB4AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAeAB4AHgAdAB4AHgAeAB4AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB4AHgAdAB0AHQAdAB4AHgAdAB0AHgAeAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHgAeAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AHQAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABQAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAWABEAFgARAB4AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAlACUAHgAeAB4AHgAeAB4AHgAeAB4AFgARAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBQAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB4AHgAeAB4AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHgAdAB0AHQAdAB0AHQAdAB4AHgAeAB4AHgAeAB4AHgAdAB0AHgAeAB0AHQAeAB4AHgAeAB0AHQAeAB4AHgAeAB0AHQAdAB4AHgAdAB4AHgAdAB0AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAeAB0AHQAeAB4AHQAeAB4AHgAeAB0AHQAeAB4AHgAeACUAJQAdAB0AJQAeACUAJQAlACAAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAHgAeAB4AHgAdAB4AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB4AHQAdAB0AHgAdACUAHQAdAB4AHQAdAB4AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAHQAdAB0AHQAlAB4AJQAlACUAHQAlACUAHQAdAB0AJQAlAB0AHQAlAB0AHQAlACUAJQAeAB0AHgAeAB4AHgAdAB0AJQAdAB0AHQAdAB0AHQAlACUAJQAlACUAHQAlACUAIAAlAB0AHQAlACUAJQAlACUAJQAlACUAHgAeAB4AJQAlACAAIAAgACAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHgAeABcAFwAXABcAFwAXAB4AEwATACUAHgAeAB4AFgARABYAEQAWABEAFgARABYAEQAWABEAFgARAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAWABEAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFgARABYAEQAWABEAFgARABYAEQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABYAEQAWABEAFgARABYAEQAWABEAFgARABYAEQAWABEAFgARABYAEQAWABEAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFgARABYAEQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABYAEQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB0AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAEAAQABAAeAB4AKwArACsAKwArABMADQANAA0AUAATAA0AUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAUAANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAA0ADQANAA0ADQANAA0ADQAeAA0AFgANAB4AHgAXABcAHgAeABcAFwAWABEAFgARABYAEQAWABEADQANAA0ADQATAFAADQANAB4ADQANAB4AHgAeAB4AHgAMAAwADQANAA0AHgANAA0AFgANAA0ADQANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAKwArACsAKwArACsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArAA0AEQARACUAJQBHAFcAVwAWABEAFgARABYAEQAWABEAFgARACUAJQAWABEAFgARABYAEQAWABEAFQAWABEAEQAlAFcAVwBXAFcAVwBXAFcAVwBXAAQABAAEAAQABAAEACUAVwBXAFcAVwA2ACUAJQBXAFcAVwBHAEcAJQAlACUAKwBRAFcAUQBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFEAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBRAFcAUQBXAFEAVwBXAFcAVwBXAFcAUQBXAFcAVwBXAFcAVwBRAFEAKwArAAQABAAVABUARwBHAFcAFQBRAFcAUQBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBRAFcAVwBXAFcAVwBXAFEAUQBXAFcAVwBXABUAUQBHAEcAVwArACsAKwArACsAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwArAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwArACUAJQBXAFcAVwBXACUAJQAlACUAJQAlACUAJQAlACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwArACsAKwArACUAJQAlACUAKwArACsAKwArACsAKwArACsAKwArACsAUQBRAFEAUQBRAFEAUQBRAFEAUQBRAFEAUQBRAFEAUQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACsAVwBXAFcAVwBXAFcAVwBXAFcAVwAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAE8ATwBPAE8ATwBPAE8ATwAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQAlACUAJQAlACUAJQAlACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAEcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAADQATAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABLAEsASwBLAEsASwBLAEsASwBLAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAABAAEAAQABAAeAAQABAAEAAQABAAEAAQABAAEAAQAHgBQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUABQAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAeAA0ADQANAA0ADQArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAB4AHgAeAB4AHgAeAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAAQAUABQAFAABABQAFAAUABQAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAeAB4AHgAeACsAKwArACsAUABQAFAAUABQAFAAHgAeABoAHgArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAADgAOABMAEwArACsAKwArACsAKwArACsABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwANAA0ASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAFAAUAAeAB4AHgBQAA4AUAArACsAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAA0ADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArAB4AWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYACsAKwArAAQAHgAeAB4AHgAeAB4ADQANAA0AHgAeAB4AHgArAFAASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArAB4AHgBcAFwAXABcAFwAKgBcAFwAXABcAFwAXABcAFwAXABcAEsASwBLAEsASwBLAEsASwBLAEsAXABcAFwAXABcACsAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArAFAAUABQAAQAUABQAFAAUABQAFAAUABQAAQABAArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAHgANAA0ADQBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAXAAqACoAKgBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAAqAFwAKgAqACoAXABcACoAKgBcAFwAXABcAFwAKgAqAFwAKgBcACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcACoAKgBQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAA0ADQBQAFAAUAAEAAQAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUAArACsAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQADQAEAAQAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAVABVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBUAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVACsAKwArACsAKwArACsAKwArACsAKwArAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAKwArACsAKwBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAKwArACsAKwAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAKwArACsAKwArAFYABABWAFYAVgBWAFYAVgBWAFYAVgBWAB4AVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgArAFYAVgBWAFYAVgArAFYAKwBWAFYAKwBWAFYAKwBWAFYAVgBWAFYAVgBWAFYAVgBWAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAEQAWAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUAAaAB4AKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAGAARABEAGAAYABMAEwAWABEAFAArACsAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACUAJQAlACUAJQAWABEAFgARABYAEQAWABEAFgARABYAEQAlACUAFgARACUAJQAlACUAJQAlACUAEQAlABEAKwAVABUAEwATACUAFgARABYAEQAWABEAJQAlACUAJQAlACUAJQAlACsAJQAbABoAJQArACsAKwArAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAcAKwATACUAJQAbABoAJQAlABYAEQAlACUAEQAlABEAJQBXAFcAVwBXAFcAVwBXAFcAVwBXABUAFQAlACUAJQATACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXABYAJQARACUAJQAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwAWACUAEQAlABYAEQARABYAEQARABUAVwBRAFEAUQBRAFEAUQBRAFEAUQBRAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAEcARwArACsAVwBXAFcAVwBXAFcAKwArAFcAVwBXAFcAVwBXACsAKwBXAFcAVwBXAFcAVwArACsAVwBXAFcAKwArACsAGgAbACUAJQAlABsAGwArAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwAEAAQABAAQAB0AKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsADQANAA0AKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsADQBQAFAAUABQACsAKwArACsAUABQAFAAUABQAFAAUABQAA0AUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUAArACsAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQACsAKwArAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgBQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwBQAFAAUABQAFAABAAEAAQAKwAEAAQAKwArACsAKwArAAQABAAEAAQAUABQAFAAUAArAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsABAAEAAQAKwArACsAKwAEAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsADQANAA0ADQANAA0ADQANAB4AKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AUABQAFAAUABQAFAAUABQAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEACsAKwArACsAUABQAFAAUABQAA0ADQANAA0ADQANABQAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwANAA0ADQANAA0ADQANAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwBQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAA0ADQAeAB4AHgAeAB4AKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsASwBLAEsASwBLAEsASwBLAEsASwANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAeAA4AUAArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAADQANAB4ADQAeAAQABAAEAB4AKwArAEsASwBLAEsASwBLAEsASwBLAEsAUAAOAFAADQANAA0AKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAANAA0AHgANAA0AHgAEACsAUABQAFAAUABQAFAAUAArAFAAKwBQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAA0AKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsABAAEAAQABAArAFAAUABQAFAAUABQAFAAUAArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAArACsABAAEACsAKwAEAAQABAArACsAUAArACsAKwArACsAKwAEACsAKwArACsAKwBQAFAAUABQAFAABAAEACsAKwAEAAQABAAEAAQABAAEACsAKwArAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAAQABABQAFAAUABQAA0ADQANAA0AHgBLAEsASwBLAEsASwBLAEsASwBLACsADQArAB4AKwArAAQABAAEAAQAUABQAB4AUAArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEACsAKwAEAAQABAAEAAQABAAEAAQABAAOAA0ADQATABMAHgAeAB4ADQANAA0ADQANAA0ADQANAA0ADQANAA0ADQANAA0AUABQAFAAUAAEAAQAKwArAAQADQANAB4AUAArACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAArACsAKwAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAXABcAA0ADQANACoASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwBQAFAABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAFAABAAEAAQABAAOAB4ADQANAA0ADQAOAB4ABAArACsAKwArACsAKwArACsAUAAEAAQABAAEAAQABAAEAAQABAAEAAQAUABQAFAAUAArACsAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAA0ADQANACsADgAOAA4ADQANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEACsABAAEAAQABAAEAAQABAAEAFAADQANAA0ADQANACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwAOABMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAArACsAKwAEACsABAAEACsABAAEAAQABAAEAAQABABQAAQAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsADQANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAASABIAEgAQwBDAEMAUABQAFAAUABDAFAAUABQAEgAQwBIAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAASABDAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABIAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwANAA0AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEAAQABAANACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAA0ADQANAB4AHgAeAB4AHgAeAFAAUABQAFAADQAeACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAEcARwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwArACsAKwArACsAKwArACsAKwArACsAKwArAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQACsAKwAeAAQABAANAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAB4AHgAeAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAHgAeAAQABAAEAAQABAAEAAQAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAEAAQABAAEAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgAEAAQABAAeACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAFAAUAArACsAUAArACsAUABQACsAKwBQAFAAUABQACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwBQACsAUABQAFAAUABQAFAAUAArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAKwAeAB4AUABQAFAAUABQACsAUAArACsAKwBQAFAAUABQAFAAUABQACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AKwArAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAB4AHgAeAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAB4AHgAeAB4AHgAeAB4AHgAEAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAeAB4ADQANAA0ADQAeACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAAQABAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsABAAEAAQABAAEAAQABAArAAQABAArAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAEAAQABAAEAAQABAAEACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAFgAWAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUAArAFAAKwArAFAAKwBQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUAArAFAAKwBQACsAKwArACsAKwArAFAAKwArACsAKwBQACsAUAArAFAAKwBQAFAAUAArAFAAUAArAFAAKwArAFAAKwBQACsAUAArAFAAKwBQACsAUABQACsAUAArACsAUABQAFAAUAArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQACsAUABQAFAAUAArAFAAKwBQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwBQAFAAUAArAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwAlACUAJQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAeACUAHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeACUAJQAlACUAHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQAlACUAJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeACUAJQAlACUAJQAeACUAJQAlACUAJQAgACAAIAAlACUAIAAlACUAIAAgACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAIQAhACEAIQAhACUAJQAgACAAJQAlACAAIAAgACAAIAAgACAAIAAgACAAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAIAAgACAAIAAlACUAJQAlACAAJQAgACAAIAAgACAAIAAgACAAIAAlACUAJQAgACUAJQAlACUAIAAgACAAJQAgACAAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeACUAHgAlAB4AJQAlACUAJQAlACAAJQAlACUAJQAeACUAHgAeACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAIAAgACUAJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAIAAlACUAJQAlACAAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAIAAgACAAJQAlACUAIAAgACAAIAAgAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFwAXABcAFQAVABUAHgAeAB4AHgAlACUAJQAgACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAIAAgACAAJQAlACUAJQAlACUAJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAgACAAIAAlACAAIAAlACUAJQAlACUAJQAgACUAJQAlACUAJQAlACUAJQAlACAAIAAgACAAIAAgACAAIAAgACAAJQAlACUAIAAgACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACsAKwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsA"},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=t(6);e.default=function A(e,t,n){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.type=r.PATH.CIRCLE,this.x=e,this.y=t,this.radius=n}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r,n=function(){return function(A,e){if(Array.isArray(A))return A;if(Symbol.iterator in Object(A))return function(A,e){var t=[],r=!0,n=!1,B=void 0;try{for(var a,s=A[Symbol.iterator]();!(r=(a=s.next()).done)&&(t.push(a.value),!e||t.length!==e);r=!0);}catch(A){n=!0,B=A}finally{try{!r&&s.return&&s.return()}finally{if(n)throw B}}return t}(A,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),B=function(){function A(A,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(A,r.key,r)}}return function(e,t,r){return t&&A(e.prototype,t),r&&A(e,r),e}}(),a=t(2),s=(t(25),t(52)),o=t(9),i=(r=o)&&r.__esModule?r:{default:r},c=t(5),l=t(12);var u=function(){function A(e,t){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.target=e,this.options=t,e.render(t)}return B(A,[{key:"renderNode",value:function(A){A.isVisible()&&(this.renderNodeBackgroundAndBorders(A),this.renderNodeContent(A))}},{key:"renderNodeContent",value:function(A){var e=this,t=function(){if(A.childNodes.length&&A.childNodes.forEach(function(t){if(t instanceof i.default){var r=t.parent.style;e.target.renderTextNode(t.bounds,r.color,r.font,r.textDecoration,r.textShadow)}else e.target.drawShape(t,A.style.color)}),A.image){var t=e.options.imageStore.get(A.image);if(t){var r=(0,a.calculateContentBox)(A.bounds,A.style.padding,A.style.border),n="number"==typeof t.width&&t.width>0?t.width:r.width,B="number"==typeof t.height&&t.height>0?t.height:r.height;n>0&&B>0&&e.target.clip([(0,a.calculatePaddingBoxPath)(A.curvedBounds)],function(){e.target.drawImage(t,new a.Bounds(0,0,n,B),r)})}}},r=A.getClipPaths();r.length?this.target.clip(r,t):t()}},{key:"renderNodeBackgroundAndBorders",value:function(A){var e=this,t=!A.style.background.backgroundColor.isTransparent()||A.style.background.backgroundImage.length,r=A.style.border.some(function(A){return A.borderStyle!==l.BORDER_STYLE.NONE&&!A.borderColor.isTransparent()}),n=function(){var r=(0,c.calculateBackgroungPaintingArea)(A.curvedBounds,A.style.background.backgroundClip);t&&e.target.clip([r],function(){A.style.background.backgroundColor.isTransparent()||e.target.fill(A.style.background.backgroundColor),e.renderBackgroundImage(A)}),A.style.border.forEach(function(t,r){t.borderStyle===l.BORDER_STYLE.NONE||t.borderColor.isTransparent()||e.renderBorder(t,r,A.curvedBounds)})};if(t||r){var B=A.parent?A.parent.getClipPaths():[];B.length?this.target.clip(B,n):n()}}},{key:"renderBackgroundImage",value:function(A){var e=this;A.style.background.backgroundImage.slice(0).reverse().forEach(function(t){"url"===t.source.method&&t.source.args.length?e.renderBackgroundRepeat(A,t):/gradient/i.test(t.source.method)&&e.renderBackgroundGradient(A,t)})}},{key:"renderBackgroundRepeat",value:function(A,e){var t=this.options.imageStore.get(e.source.args[0]);if(t){var r=(0,c.calculateBackgroungPositioningArea)(A.style.background.backgroundOrigin,A.bounds,A.style.padding,A.style.border),n=(0,c.calculateBackgroundSize)(e,t,r),B=(0,c.calculateBackgroundPosition)(e.position,n,r),a=(0,c.calculateBackgroundRepeatPath)(e,B,n,r,A.bounds),s=Math.round(r.left+B.x),o=Math.round(r.top+B.y);this.target.renderRepeat(a,t,n,s,o)}}},{key:"renderBackgroundGradient",value:function(A,e){var t=(0,c.calculateBackgroungPositioningArea)(A.style.background.backgroundOrigin,A.bounds,A.style.padding,A.style.border),r=(0,c.calculateGradientBackgroundSize)(e,t),n=(0,c.calculateBackgroundPosition)(e.position,r,t),B=new a.Bounds(Math.round(t.left+n.x),Math.round(t.top+n.y),r.width,r.height),o=(0,s.parseGradient)(A,e.source,B);if(o)switch(o.type){case s.GRADIENT_TYPE.LINEAR_GRADIENT:this.target.renderLinearGradient(B,o);break;case s.GRADIENT_TYPE.RADIAL_GRADIENT:this.target.renderRadialGradient(B,o)}}},{key:"renderBorder",value:function(A,e,t){this.target.drawShape((0,a.parsePathForBorder)(t,e),A.borderColor)}},{key:"renderStack",value:function(A){var e=this;if(A.container.isVisible()){var t=A.getOpacity();t!==this._opacity&&(this.target.setOpacity(A.getOpacity()),this._opacity=t);var r=A.container.style.transform;null!==r?this.target.transform(A.container.bounds.left+r.transformOrigin[0].value,A.container.bounds.top+r.transformOrigin[1].value,r.transform,function(){return e.renderStackContent(A)}):this.renderStackContent(A)}}},{key:"renderStackContent",value:function(A){var e=w(A),t=n(e,5),r=t[0],B=t[1],a=t[2],s=t[3],o=t[4],i=Q(A),c=n(i,2),l=c[0],u=c[1];this.renderNodeBackgroundAndBorders(A.container),r.sort(U).forEach(this.renderStack,this),this.renderNodeContent(A.container),u.forEach(this.renderNode,this),s.forEach(this.renderStack,this),o.forEach(this.renderStack,this),l.forEach(this.renderNode,this),B.forEach(this.renderStack,this),a.sort(U).forEach(this.renderStack,this)}},{key:"render",value:function(A){this.options.backgroundColor&&this.target.rectangle(this.options.x,this.options.y,this.options.width,this.options.height,this.options.backgroundColor),this.renderStack(A);var e=this.target.getTarget();return e}}]),A}();e.default=u;var Q=function(A){for(var e=[],t=[],r=A.children.length,n=0;n<r;n++){var B=A.children[n];B.isInlineLevel()?e.push(B):t.push(B)}return[e,t]},w=function(A){for(var e=[],t=[],r=[],n=[],B=[],a=A.contexts.length,s=0;s<a;s++){var o=A.contexts[s];o.container.isPositioned()||o.container.style.opacity<1||o.container.isTransformed()?o.container.style.zIndex.order<0?e.push(o):o.container.style.zIndex.order>0?r.push(o):t.push(o):o.container.isFloating()?n.push(o):B.push(o)}return[e,t,r,n,B]},U=function(A,e){return A.container.style.zIndex.order>e.container.style.zIndex.order?1:A.container.style.zIndex.order<e.container.style.zIndex.order?-1:A.container.index>e.container.index?1:-1}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.transformWebkitRadialGradientArgs=e.parseGradient=e.RadialGradient=e.LinearGradient=e.RADIAL_GRADIENT_SHAPE=e.GRADIENT_TYPE=void 0;var r=function(){return function(A,e){if(Array.isArray(A))return A;if(Symbol.iterator in Object(A))return function(A,e){var t=[],r=!0,n=!1,B=void 0;try{for(var a,s=A[Symbol.iterator]();!(r=(a=s.next()).done)&&(t.push(a.value),!e||t.length!==e);r=!0);}catch(A){n=!0,B=A}finally{try{!r&&s.return&&s.return()}finally{if(n)throw B}}return t}(A,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),n=(i(t(3)),t(53)),B=i(t(0)),a=t(1),s=i(a),o=t(4);function i(A){return A&&A.__esModule?A:{default:A}}function c(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}var l=/^(to )?(left|top|right|bottom)( (left|top|right|bottom))?$/i,u=/^([+-]?\d*\.?\d+)% ([+-]?\d*\.?\d+)%$/i,Q=/(px)|%|( 0)$/i,w=/^(from|to|color-stop)\((?:([\d.]+)(%)?,\s*)?(.+?)\)$/i,U=/^\s*(circle|ellipse)?\s*((?:([\d.]+)(px|r?em|%)\s*(?:([\d.]+)(px|r?em|%))?)|closest-side|closest-corner|farthest-side|farthest-corner)?\s*(?:at\s*(?:(left|center|right)|([\d.]+)(px|r?em|%))\s+(?:(top|center|bottom)|([\d.]+)(px|r?em|%)))?(?:\s|$)/i,g=e.GRADIENT_TYPE={LINEAR_GRADIENT:0,RADIAL_GRADIENT:1},C=e.RADIAL_GRADIENT_SHAPE={CIRCLE:0,ELLIPSE:1},d={left:new s.default("0%"),top:new s.default("0%"),center:new s.default("50%"),right:new s.default("100%"),bottom:new s.default("100%")},F=e.LinearGradient=function A(e,t){c(this,A),this.type=g.LINEAR_GRADIENT,this.colorStops=e,this.direction=t},E=e.RadialGradient=function A(e,t,r,n){c(this,A),this.type=g.RADIAL_GRADIENT,this.colorStops=e,this.shape=t,this.center=r,this.radius=n},f=(e.parseGradient=function(A,e,t){var r=e.args,n=e.method,B=e.prefix;return"linear-gradient"===n?h(r,t,!!B):"gradient"===n&&"linear"===r[0]?h(["to bottom"].concat(y(r.slice(3))),t,!!B):"radial-gradient"===n?H(A,"-webkit-"===B?v(r):r,t):"gradient"===n&&"radial"===r[0]?H(A,y(v(r.slice(1))),t):void 0},function(A,e,t){for(var r=[],n=e;n<A.length;n++){var a=A[n],o=Q.test(a),i=a.lastIndexOf(" "),c=new B.default(o?a.substring(0,i):a),l=o?new s.default(a.substring(i+1)):n===e?new s.default("0%"):n===A.length-1?new s.default("100%"):null;r.push({color:c,stop:l})}for(var u=r.map(function(A){var e=A.color,r=A.stop;return{color:e,stop:0===t?0:r?r.getAbsoluteValue(t)/t:null}}),w=u[0].stop,U=0;U<u.length;U++)if(null!==w){var g=u[U].stop;if(null===g){for(var C=U;null===u[C].stop;)C++;for(var d=C-U+1,F=(u[C].stop-w)/d;U<C;U++)w=u[U].stop=w+F}else w=g}return u}),h=function(A,e,t){var r=(0,n.parseAngle)(A[0]),B=l.test(A[0]),a=B||null!==r||u.test(A[0]),s=a?null!==r?p(t?r-.5*Math.PI:r,e):B?I(A[0],e):K(A[0],e):p(Math.PI,e),i=a?1:0,c=Math.min((0,o.distance)(Math.abs(s.x0)+Math.abs(s.x1),Math.abs(s.y0)+Math.abs(s.y1)),2*e.width,2*e.height);return new F(f(A,i,c),s)},H=function(A,e,t){var r=e[0].match(U),n=r&&("circle"===r[1]||void 0!==r[3]&&void 0===r[5])?C.CIRCLE:C.ELLIPSE,B={},s={};r&&(void 0!==r[3]&&(B.x=(0,a.calculateLengthFromValueWithUnit)(A,r[3],r[4]).getAbsoluteValue(t.width)),void 0!==r[5]&&(B.y=(0,a.calculateLengthFromValueWithUnit)(A,r[5],r[6]).getAbsoluteValue(t.height)),r[7]?s.x=d[r[7].toLowerCase()]:void 0!==r[8]&&(s.x=(0,a.calculateLengthFromValueWithUnit)(A,r[8],r[9])),r[10]?s.y=d[r[10].toLowerCase()]:void 0!==r[11]&&(s.y=(0,a.calculateLengthFromValueWithUnit)(A,r[11],r[12])));var o={x:void 0===s.x?t.width/2:s.x.getAbsoluteValue(t.width),y:void 0===s.y?t.height/2:s.y.getAbsoluteValue(t.height)},i=m(r&&r[2]||"farthest-corner",n,o,B,t);return new E(f(e,r?1:0,Math.min(i.x,i.y)),n,o,i)},p=function(A,e){var t=e.width,r=e.height,n=.5*t,B=.5*r,a=(Math.abs(t*Math.sin(A))+Math.abs(r*Math.cos(A)))/2,s=n+Math.sin(A)*a,o=B-Math.cos(A)*a;return{x0:s,x1:t-s,y0:o,y1:r-o}},N=function(A){return Math.acos(A.width/2/((0,o.distance)(A.width,A.height)/2))},I=function(A,e){switch(A){case"bottom":case"to top":return p(0,e);case"left":case"to right":return p(Math.PI/2,e);case"right":case"to left":return p(3*Math.PI/2,e);case"top right":case"right top":case"to bottom left":case"to left bottom":return p(Math.PI+N(e),e);case"top left":case"left top":case"to bottom right":case"to right bottom":return p(Math.PI-N(e),e);case"bottom left":case"left bottom":case"to top right":case"to right top":return p(N(e),e);case"bottom right":case"right bottom":case"to top left":case"to left top":return p(2*Math.PI-N(e),e);case"top":case"to bottom":default:return p(Math.PI,e)}},K=function(A,e){var t=A.split(" ").map(parseFloat),n=r(t,2),B=n[0],a=n[1],s=B/100*e.width/(a/100*e.height);return p(Math.atan(isNaN(s)?1:s)+Math.PI/2,e)},T=function(A,e,t,r){return[{x:0,y:0},{x:0,y:A.height},{x:A.width,y:0},{x:A.width,y:A.height}].reduce(function(A,n){var B=(0,o.distance)(e-n.x,t-n.y);return(r?B<A.optimumDistance:B>A.optimumDistance)?{optimumCorner:n,optimumDistance:B}:A},{optimumDistance:r?1/0:-1/0,optimumCorner:null}).optimumCorner},m=function(A,e,t,r,n){var B=t.x,a=t.y,s=0,i=0;switch(A){case"closest-side":e===C.CIRCLE?s=i=Math.min(Math.abs(B),Math.abs(B-n.width),Math.abs(a),Math.abs(a-n.height)):e===C.ELLIPSE&&(s=Math.min(Math.abs(B),Math.abs(B-n.width)),i=Math.min(Math.abs(a),Math.abs(a-n.height)));break;case"closest-corner":if(e===C.CIRCLE)s=i=Math.min((0,o.distance)(B,a),(0,o.distance)(B,a-n.height),(0,o.distance)(B-n.width,a),(0,o.distance)(B-n.width,a-n.height));else if(e===C.ELLIPSE){var c=Math.min(Math.abs(a),Math.abs(a-n.height))/Math.min(Math.abs(B),Math.abs(B-n.width)),l=T(n,B,a,!0);i=c*(s=(0,o.distance)(l.x-B,(l.y-a)/c))}break;case"farthest-side":e===C.CIRCLE?s=i=Math.max(Math.abs(B),Math.abs(B-n.width),Math.abs(a),Math.abs(a-n.height)):e===C.ELLIPSE&&(s=Math.max(Math.abs(B),Math.abs(B-n.width)),i=Math.max(Math.abs(a),Math.abs(a-n.height)));break;case"farthest-corner":if(e===C.CIRCLE)s=i=Math.max((0,o.distance)(B,a),(0,o.distance)(B,a-n.height),(0,o.distance)(B-n.width,a),(0,o.distance)(B-n.width,a-n.height));else if(e===C.ELLIPSE){var u=Math.max(Math.abs(a),Math.abs(a-n.height))/Math.max(Math.abs(B),Math.abs(B-n.width)),Q=T(n,B,a,!1);i=u*(s=(0,o.distance)(Q.x-B,(Q.y-a)/u))}break;default:s=r.x||0,i=void 0!==r.y?r.y:s}return{x:s,y:i}},v=e.transformWebkitRadialGradientArgs=function(A){var e="",t="",r="",n="",B=0,a=/^(left|center|right|\d+(?:px|r?em|%)?)(?:\s+(top|center|bottom|\d+(?:px|r?em|%)?))?$/i,s=/^\d+(px|r?em|%)?(?:\s+\d+(px|r?em|%)?)?$/i,o=A[B].match(a);o&&B++;var i=A[B].match(/^(circle|ellipse)?\s*(closest-side|closest-corner|farthest-side|farthest-corner|contain|cover)?$/i);i&&(e=i[1]||"","contain"===(r=i[2]||"")?r="closest-side":"cover"===r&&(r="farthest-corner"),B++);var c=A[B].match(s);c&&B++;var l=A[B].match(a);l&&B++;var u=A[B].match(s);u&&B++;var Q=l||o;Q&&Q[1]&&(n=Q[1]+(/^\d+$/.test(Q[1])?"px":""),Q[2]&&(n+=" "+Q[2]+(/^\d+$/.test(Q[2])?"px":"")));var w=u||c;return w&&(t=w[0],w[1]||(t+="px")),!n||e||t||r||(t=n,n=""),n&&(n="at "+n),[[e,r,t,n].filter(function(A){return!!A}).join(" ")].concat(A.slice(B))},y=function(A){return A.map(function(A){return A.match(w)}).map(function(e,t){if(!e)return A[t];switch(e[1]){case"from":return e[4]+" 0%";case"to":return e[4]+" 100%";case"color-stop":return"%"===e[3]?e[4]+" "+e[2]:e[4]+" "+100*parseFloat(e[2])+"%"}})}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=/([+-]?\d*\.?\d+)(deg|grad|rad|turn)/i;e.parseAngle=function(A){var e=A.match(r);if(e){var t=parseFloat(e[1]);switch(e[2].toLowerCase()){case"deg":return Math.PI*t/180;case"grad":return Math.PI/200*t;case"rad":return t;case"turn":return 2*Math.PI*t}}return null}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.cloneWindow=e.DocumentCloner=void 0;var r=function(){return function(A,e){if(Array.isArray(A))return A;if(Symbol.iterator in Object(A))return function(A,e){var t=[],r=!0,n=!1,B=void 0;try{for(var a,s=A[Symbol.iterator]();!(r=(a=s.next()).done)&&(t.push(a.value),!e||t.length!==e);r=!0);}catch(A){n=!0,B=A}finally{try{!r&&s.return&&s.return()}finally{if(n)throw B}}return t}(A,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),n=function(){function A(A,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(A,r.key,r)}}return function(e,t,r){return t&&A(e.prototype,t),r&&A(e,r),e}}(),B=t(2),a=t(26),s=u(t(55)),o=t(4),i=t(5),c=u(t(15)),l=t(56);function u(A){return A&&A.__esModule?A:{default:A}}var Q=e.DocumentCloner=function(){function A(e,t,r,n,B){!function(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}(this,A),this.referenceElement=e,this.scrolledElements=[],this.copyStyles=n,this.inlineImages=n,this.logger=r,this.options=t,this.renderer=B,this.resourceLoader=new s.default(t,r,window),this.pseudoContentData={counters:{},quoteDepth:0},this.documentElement=this.cloneNode(e.ownerDocument.documentElement)}return n(A,[{key:"inlineAllImages",value:function(A){var e=this;if(this.inlineImages&&A){var t=A.style;Promise.all((0,i.parseBackgroundImage)(t.backgroundImage).map(function(A){return"url"===A.method?e.resourceLoader.inlineImage(A.args[0]).then(function(A){return A&&"string"==typeof A.src?'url("'+A.src+'")':"none"}).catch(function(A){0}):Promise.resolve(""+A.prefix+A.method+"("+A.args.join(",")+")")})).then(function(A){A.length>1&&(t.backgroundColor=""),t.backgroundImage=A.join(",")}),A instanceof HTMLImageElement&&this.resourceLoader.inlineImage(A.src).then(function(e){if(e&&A instanceof HTMLImageElement&&A.parentNode){var t=A.parentNode,r=(0,o.copyCSSStyles)(A.style,e.cloneNode(!1));t.replaceChild(r,A)}}).catch(function(A){0})}}},{key:"inlineFonts",value:function(A){var e=this;return Promise.all(Array.from(A.styleSheets).map(function(e){return e.href?fetch(e.href).then(function(A){return A.text()}).then(function(A){return U(A,e.href)}).catch(function(A){return[]}):w(e,A)})).then(function(A){return A.reduce(function(A,e){return A.concat(e)},[])}).then(function(A){return Promise.all(A.map(function(A){return fetch(A.formats[0].src).then(function(A){return A.blob()}).then(function(A){return new Promise(function(e,t){var r=new FileReader;r.onerror=t,r.onload=function(){var A=r.result;e(A)},r.readAsDataURL(A)})}).then(function(e){return A.fontFace.setProperty("src",'url("'+e+'")'),"@font-face {"+A.fontFace.cssText+" "})}))}).then(function(t){var r=A.createElement("style");r.textContent=t.join("\n"),e.documentElement.appendChild(r)})}},{key:"createElementClone",value:function(A){var e=this;if(this.copyStyles&&A instanceof HTMLCanvasElement){var t=A.ownerDocument.createElement("img");try{return t.src=A.toDataURL(),t}catch(A){0}}if(A instanceof HTMLIFrameElement){var r=A.cloneNode(!1),n=N();r.setAttribute("data-html2canvas-internal-iframe-key",n);var a=(0,B.parseBounds)(A,0,0),s=a.width,i=a.height;return this.resourceLoader.cache[n]=K(A,this.options).then(function(A){return e.renderer(A,{async:e.options.async,allowTaint:e.options.allowTaint,backgroundColor:"#ffffff",canvas:null,imageTimeout:e.options.imageTimeout,logging:e.options.logging,proxy:e.options.proxy,removeContainer:e.options.removeContainer,scale:e.options.scale,foreignObjectRendering:e.options.foreignObjectRendering,useCORS:e.options.useCORS,target:new c.default,width:s,height:i,x:0,y:0,windowWidth:A.ownerDocument.defaultView.innerWidth,windowHeight:A.ownerDocument.defaultView.innerHeight,scrollX:A.ownerDocument.defaultView.pageXOffset,scrollY:A.ownerDocument.defaultView.pageYOffset},e.logger.child(n))}).then(function(e){return new Promise(function(t,n){var B=document.createElement("img");B.onload=function(){return t(e)},B.onerror=n,B.src=e.toDataURL(),r.parentNode&&r.parentNode.replaceChild((0,o.copyCSSStyles)(A.ownerDocument.defaultView.getComputedStyle(A),B),r)})}),r}if(A instanceof HTMLStyleElement&&A.sheet&&A.sheet.cssRules){var l=[].slice.call(A.sheet.cssRules,0).reduce(function(A,t){try{return t&&t.cssText?A+t.cssText:A}catch(r){return e.logger.log("Unable to access cssText property",t.name),A}},""),u=A.cloneNode(!1);return u.textContent=l,u}return A.cloneNode(!1)}},{key:"cloneNode",value:function(A){var e=A.nodeType===Node.TEXT_NODE?document.createTextNode(A.nodeValue):this.createElementClone(A),t=A.ownerDocument.defaultView,r=A instanceof t.HTMLElement?t.getComputedStyle(A):null,n=A instanceof t.HTMLElement?t.getComputedStyle(A,":before"):null,B=A instanceof t.HTMLElement?t.getComputedStyle(A,":after"):null;this.referenceElement===A&&e instanceof t.HTMLElement&&(this.clonedReferenceElement=e),e instanceof t.HTMLBodyElement&&h(e);for(var a=(0,l.parseCounterReset)(r,this.pseudoContentData),s=(0,l.resolvePseudoContent)(A,n,this.pseudoContentData),i=A.firstChild;i;i=i.nextSibling)i.nodeType===Node.ELEMENT_NODE&&("SCRIPT"===i.nodeName||i.hasAttribute("data-html2canvas-ignore")||"function"==typeof this.options.ignoreElements&&this.options.ignoreElements(i))||this.copyStyles&&"STYLE"===i.nodeName||e.appendChild(this.cloneNode(i));var c=(0,l.resolvePseudoContent)(A,B,this.pseudoContentData);if((0,l.popCounters)(a,this.pseudoContentData),A instanceof t.HTMLElement&&e instanceof t.HTMLElement)switch(n&&this.inlineAllImages(C(A,e,n,s,d)),B&&this.inlineAllImages(C(A,e,B,c,F)),!r||!this.copyStyles||A instanceof HTMLIFrameElement||(0,o.copyCSSStyles)(r,e),this.inlineAllImages(e),0===A.scrollTop&&0===A.scrollLeft||this.scrolledElements.push([e,A.scrollLeft,A.scrollTop]),A.nodeName){case"CANVAS":this.copyStyles||g(A,e);break;case"TEXTAREA":case"SELECT":e.value=A.value}return e}}]),A}(),w=function(A,e){return(A.cssRules?Array.from(A.cssRules):[]).filter(function(A){return A.type===CSSRule.FONT_FACE_RULE}).map(function(A){for(var t=(0,i.parseBackgroundImage)(A.style.getPropertyValue("src")),r=[],n=0;n<t.length;n++)if("url"===t[n].method&&t[n+1]&&"format"===t[n+1].method){var B=e.createElement("a");B.href=t[n].args[0],e.body&&e.body.appendChild(B);var a={src:B.href,format:t[n+1].args[0]};r.push(a)}return{formats:r.filter(function(A){return/^woff/i.test(A.format)}),fontFace:A.style}}).filter(function(A){return A.formats.length})},U=function(A,e){var t=document.implementation.createHTMLDocument(""),r=document.createElement("base");r.href=e;var n=document.createElement("style");return n.textContent=A,t.head&&t.head.appendChild(r),t.body&&t.body.appendChild(n),n.sheet?w(n.sheet,t):[]},g=function(A,e){try{if(e){e.width=A.width,e.height=A.height;var t=A.getContext("2d"),r=e.getContext("2d");t?r.putImageData(t.getImageData(0,0,A.width,A.height),0,0):r.drawImage(A,0,0)}}catch(A){}},C=function(A,e,t,r,n){if(t&&t.content&&"none"!==t.content&&"-moz-alt-content"!==t.content&&"none"!==t.display){var B=e.ownerDocument.createElement("html2canvaspseudoelement");if((0,o.copyCSSStyles)(t,B),r)for(var a=r.length,s=0;s<a;s++){var c=r[s];switch(c.type){case l.PSEUDO_CONTENT_ITEM_TYPE.IMAGE:var u=e.ownerDocument.createElement("img");u.src=(0,i.parseBackgroundImage)("url("+c.value+")")[0].args[0],u.style.opacity="1",B.appendChild(u);break;case l.PSEUDO_CONTENT_ITEM_TYPE.TEXT:B.appendChild(e.ownerDocument.createTextNode(c.value))}}return B.className=E+" "+f,e.className+=n===d?" "+E:" "+f,n===d?e.insertBefore(B,e.firstChild):e.appendChild(B),B}},d=":before",F=":after",E="___html2canvas___pseudoelement_before",f="___html2canvas___pseudoelement_after",h=function(A){H(A,"."+E+d+'{\n    content: "" !important;\n    display: none !important;\n}\n         .'+f+F+'{\n    content: "" !important;\n    display: none !important;\n}')},H=function(A,e){var t=A.ownerDocument.createElement("style");t.innerHTML=e,A.appendChild(t)},p=function(A){var e=r(A,3),t=e[0],n=e[1],B=e[2];t.scrollLeft=n,t.scrollTop=B},N=function(){return Math.ceil(Date.now()+1e7*Math.random()).toString(16)},I=/^data:text\/(.+);(base64)?,(.*)$/i,K=function(A,e){try{return Promise.resolve(A.contentWindow.document.documentElement)}catch(t){return e.proxy?(0,a.Proxy)(A.src,e).then(function(A){var e=A.match(I);return e?"base64"===e[2]?window.atob(decodeURIComponent(e[3])):decodeURIComponent(e[3]):Promise.reject()}).then(function(e){return T(A.ownerDocument,(0,B.parseBounds)(A,0,0)).then(function(A){var t=A.contentWindow.document;t.open(),t.write(e);var r=m(A).then(function(){return t.documentElement});return t.close(),r})}):Promise.reject()}},T=function(A,e){var t=A.createElement("iframe");return t.className="html2canvas-container",t.style.visibility="hidden",t.style.position="fixed",t.style.left="-10000px",t.style.top="0px",t.style.border="0",t.width=e.width.toString(),t.height=e.height.toString(),t.scrolling="no",t.setAttribute("data-html2canvas-ignore","true"),A.body?(A.body.appendChild(t),Promise.resolve(t)):Promise.reject("")},m=function(A){var e=A.contentWindow,t=e.document;return new Promise(function(r,n){e.onload=A.onload=t.onreadystatechange=function(){var e=setInterval(function(){t.body.childNodes.length>0&&"complete"===t.readyState&&(clearInterval(e),r(A))},50)}})},v=(e.cloneWindow=function(A,e,t,r,n,B){var a=new Q(t,r,n,!1,B),s=A.defaultView.pageXOffset,o=A.defaultView.pageYOffset;return T(A,e).then(function(n){var B=n.contentWindow,i=B.document,c=m(n).then(function(){a.scrolledElements.forEach(p),B.scrollTo(e.left,e.top),!/(iPad|iPhone|iPod)/g.test(navigator.userAgent)||B.scrollY===e.top&&B.scrollX===e.left||(i.documentElement.style.top=-e.top+"px",i.documentElement.style.left=-e.left+"px",i.documentElement.style.position="absolute");var t=Promise.resolve([n,a.clonedReferenceElement,a.resourceLoader]),s=r.onclone;return a.clonedReferenceElement instanceof B.HTMLElement||a.clonedReferenceElement instanceof A.defaultView.HTMLElement||a.clonedReferenceElement instanceof HTMLElement?"function"==typeof s?Promise.resolve().then(function(){return s(i)}).then(function(){return t}):t:Promise.reject("")});return i.open(),i.write(v(document.doctype)+"<html></html>"),function(A,e,t){!A.defaultView||e===A.defaultView.pageXOffset&&t===A.defaultView.pageYOffset||A.defaultView.scrollTo(e,t)}(t.ownerDocument,s,o),i.replaceChild(i.adoptNode(a.documentElement),i.documentElement),i.close(),c})},function(A){var e="";return A&&(e+="<!DOCTYPE ",A.name&&(e+=A.name),A.internalSubset&&(e+=A.internalSubset),A.publicId&&(e+='"'+A.publicId+'"'),A.systemId&&(e+='"'+A.systemId+'"'),e+=">"),e})},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ResourceStore=void 0;var r,n=function(){function A(A,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(A,r.key,r)}}return function(e,t,r){return t&&A(e.prototype,t),r&&A(e,r),e}}(),B=t(10),a=(r=B)&&r.__esModule?r:{default:r},s=t(26);function o(A,e){if(!(A instanceof e))throw new TypeError("Cannot call a class as a function")}var i=function(){function A(e,t,r){o(this,A),this.options=e,this._window=r,this.origin=this.getOrigin(r.location.href),this.cache={},this.logger=t,this._index=0}return n(A,[{key:"loadImage",value:function(A){var e=this;if(this.hasResourceInCache(A))return A;if(g(A))return this.cache[A]=d(A,this.options.imageTimeout||0),A;if(!C(A)||a.default.SUPPORT_SVG_DRAWING){if(!0===this.options.allowTaint||w(A)||this.isSameOrigin(A))return this.addImage(A,A,!1);if(!this.isSameOrigin(A)){if("string"==typeof this.options.proxy)return this.cache[A]=(0,s.Proxy)(A,this.options).then(function(A){return d(A,e.options.imageTimeout||0)}),A;if(!0===this.options.useCORS&&a.default.SUPPORT_CORS_IMAGES)return this.addImage(A,A,!0)}}}},{key:"inlineImage",value:function(A){var e=this;return w(A)?d(A,this.options.imageTimeout||0):this.hasResourceInCache(A)?this.cache[A]:this.isSameOrigin(A)||"string"!=typeof this.options.proxy?this.xhrImage(A):this.cache[A]=(0,s.Proxy)(A,this.options).then(function(A){return d(A,e.options.imageTimeout||0)})}},{key:"xhrImage",value:function(A){var e=this;return this.cache[A]=new Promise(function(t,r){var n=new XMLHttpRequest;if(n.onreadystatechange=function(){if(4===n.readyState)if(200!==n.status)r("Failed to fetch image "+A.substring(0,256)+" with status code "+n.status);else{var e=new FileReader;e.addEventListener("load",function(){var A=e.result;t(A)},!1),e.addEventListener("error",function(A){return r(A)},!1),e.readAsDataURL(n.response)}},n.responseType="blob",e.options.imageTimeout){var B=e.options.imageTimeout;n.timeout=B,n.ontimeout=function(){return r("")}}n.open("GET",A,!0),n.send()}).then(function(A){return d(A,e.options.imageTimeout||0)}),this.cache[A]}},{key:"loadCanvas",value:function(A){var e=String(this._index++);return this.cache[e]=Promise.resolve(A),e}},{key:"hasResourceInCache",value:function(A){return void 0!==this.cache[A]}},{key:"addImage",value:function(A,e,t){var r=this;var n=function(A){return new Promise(function(n,B){var a=new Image;if(a.onload=function(){return n(a)},A&&!t||(a.crossOrigin="anonymous"),a.onerror=B,a.src=e,!0===a.complete&&setTimeout(function(){n(a)},500),r.options.imageTimeout){var s=r.options.imageTimeout;setTimeout(function(){return B("")},s)}})};return this.cache[A]=U(e)&&!C(e)?a.default.SUPPORT_BASE64_DRAWING(e).then(n):n(!0),A}},{key:"isSameOrigin",value:function(A){return this.getOrigin(A)===this.origin}},{key:"getOrigin",value:function(A){var e=this._link||(this._link=this._window.document.createElement("a"));return e.href=A,e.href=e.href,e.protocol+e.hostname+e.port}},{key:"ready",value:function(){var A=this,e=Object.keys(this.cache),t=e.map(function(e){return A.cache[e].catch(function(A){return null})});return Promise.all(t).then(function(A){return new c(e,A)})}}]),A}();e.default=i;var c=e.ResourceStore=function(){function A(e,t){o(this,A),this._keys=e,this._resources=t}return n(A,[{key:"get",value:function(A){var e=this._keys.indexOf(A);return-1===e?null:this._resources[e]}}]),A}(),l=/^data:image\/svg\+xml/i,u=/^data:image\/.*;base64,/i,Q=/^data:image\/.*/i,w=function(A){return Q.test(A)},U=function(A){return u.test(A)},g=function(A){return"blob"===A.substr(0,4)},C=function(A){return"svg"===A.substr(-3).toLowerCase()||l.test(A)},d=function(A,e){return new Promise(function(t,r){var n=new Image;n.onload=function(){return t(n)},n.onerror=r,n.src=A,!0===n.complete&&setTimeout(function(){t(n)},500),e&&setTimeout(function(){return r("")},e)})}},function(A,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.parseContent=e.resolvePseudoContent=e.popCounters=e.parseCounterReset=e.TOKEN_TYPE=e.PSEUDO_CONTENT_ITEM_TYPE=void 0;var r=function(){return function(A,e){if(Array.isArray(A))return A;if(Symbol.iterator in Object(A))return function(A,e){var t=[],r=!0,n=!1,B=void 0;try{for(var a,s=A[Symbol.iterator]();!(r=(a=s.next()).done)&&(t.push(a.value),!e||t.length!==e);r=!0);}catch(A){n=!0,B=A}finally{try{!r&&s.return&&s.return()}finally{if(n)throw B}}return t}(A,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),n=t(14),B=t(8),a=e.PSEUDO_CONTENT_ITEM_TYPE={TEXT:0,IMAGE:1},s=e.TOKEN_TYPE={STRING:0,ATTRIBUTE:1,URL:2,COUNTER:3,COUNTERS:4,OPENQUOTE:5,CLOSEQUOTE:6},o=(e.parseCounterReset=function(A,e){if(!A||!A.counterReset||"none"===A.counterReset)return[];for(var t=[],n=A.counterReset.split(/\s*,\s*/),B=n.length,a=0;a<B;a++){var s=n[a].split(/\s+/),o=r(s,2),i=o[0],c=o[1];t.push(i);var l=e.counters[i];l||(l=e.counters[i]=[]),l.push(parseInt(c||0,10))}return t},e.popCounters=function(A,e){for(var t=A.length,r=0;r<t;r++)e.counters[A[r]].pop()},e.resolvePseudoContent=function(A,e,t){if(!e||!e.content||"none"===e.content||"-moz-alt-content"===e.content||"none"===e.display)return null;var n=o(e.content),B=n.length,i=[],u="",Q=e.counterIncrement;if(Q&&"none"!==Q){var w=Q.split(/\s+/),U=r(w,2),g=U[0],C=U[1],d=t.counters[g];d&&(d[d.length-1]+=void 0===C?1:parseInt(C,10))}for(var F=0;F<B;F++){var E=n[F];switch(E.type){case s.STRING:u+=E.value||"";break;case s.ATTRIBUTE:A instanceof HTMLElement&&E.value&&(u+=A.getAttribute(E.value)||"");break;case s.COUNTER:var f=t.counters[E.name||""];f&&(u+=l([f[f.length-1]],"",E.format));break;case s.COUNTERS:var h=t.counters[E.name||""];h&&(u+=l(h,E.glue,E.format));break;case s.OPENQUOTE:u+=c(e,!0,t.quoteDepth),t.quoteDepth++;break;case s.CLOSEQUOTE:t.quoteDepth--,u+=c(e,!1,t.quoteDepth);break;case s.URL:u&&(i.push({type:a.TEXT,value:u}),u=""),i.push({type:a.IMAGE,value:E.value||""})}}return u&&i.push({type:a.TEXT,value:u}),i},e.parseContent=function(A,e){if(e&&e[A])return e[A];for(var t=[],r=A.length,n=!1,B=!1,a=!1,o="",c="",l=[],u=0;u<r;u++){var Q=A.charAt(u);switch(Q){case"'":case'"':B?o+=Q:(n=!n,a||n||(t.push({type:s.STRING,value:o}),o=""));break;case"\\":B?(o+=Q,B=!1):B=!0;break;case"(":n?o+=Q:(a=!0,c=o,o="",l=[]);break;case")":if(n)o+=Q;else if(a){switch(o&&l.push(o),c){case"attr":l.length>0&&t.push({type:s.ATTRIBUTE,value:l[0]});break;case"counter":if(l.length>0){var w={type:s.COUNTER,name:l[0]};l.length>1&&(w.format=l[1]),t.push(w)}break;case"counters":if(l.length>0){var U={type:s.COUNTERS,name:l[0]};l.length>1&&(U.glue=l[1]),l.length>2&&(U.format=l[2]),t.push(U)}break;case"url":l.length>0&&t.push({type:s.URL,value:l[0]})}a=!1,o=""}break;case",":n?o+=Q:a&&(l.push(o),o="");break;case" ":case"\t":n?o+=Q:o&&(i(t,o),o="");break;default:o+=Q}"\\"!==Q&&(B=!1)}return o&&i(t,o),e&&(e[A]=t),t}),i=function(A,e){switch(e){case"open-quote":A.push({type:s.OPENQUOTE});break;case"close-quote":A.push({type:s.CLOSEQUOTE})}},c=function(A,e,t){var r=A.quotes?A.quotes.split(/\s+/):["'\"'","'\"'"],n=2*t;return n>=r.length&&(n=r.length-2),e||++n,r[n].replace(/^["']|["']$/g,"")},l=function(A,e,t){for(var r=A.length,a="",s=0;s<r;s++)s>0&&(a+=e||""),a+=(0,n.createCounterText)(A[s],(0,B.parseListStyleType)(t||"decimal"),!1);return a}}])});
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/Angle.js b/AstuteClient2/src/assets/html2canvas/dist/npm/Angle.js
new file mode 100644
index 0000000..ce19cb1
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/Angle.js
@@ -0,0 +1,26 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var ANGLE = /([+-]?\d*\.?\d+)(deg|grad|rad|turn)/i;
+
+var parseAngle = exports.parseAngle = function parseAngle(angle) {
+    var match = angle.match(ANGLE);
+
+    if (match) {
+        var value = parseFloat(match[1]);
+        switch (match[2].toLowerCase()) {
+            case 'deg':
+                return Math.PI * value / 180;
+            case 'grad':
+                return Math.PI / 200 * value;
+            case 'rad':
+                return value;
+            case 'turn':
+                return Math.PI * 2 * value;
+        }
+    }
+
+    return null;
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/Bounds.js b/AstuteClient2/src/assets/html2canvas/dist/npm/Bounds.js
new file mode 100644
index 0000000..074bbc5
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/Bounds.js
@@ -0,0 +1,203 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseBoundCurves = exports.calculatePaddingBoxPath = exports.calculateBorderBoxPath = exports.parsePathForBorder = exports.parseDocumentSize = exports.calculateContentBox = exports.calculatePaddingBox = exports.parseBounds = exports.Bounds = undefined;
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Vector = require('./drawing/Vector');
+
+var _Vector2 = _interopRequireDefault(_Vector);
+
+var _BezierCurve = require('./drawing/BezierCurve');
+
+var _BezierCurve2 = _interopRequireDefault(_BezierCurve);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var TOP = 0;
+var RIGHT = 1;
+var BOTTOM = 2;
+var LEFT = 3;
+
+var H = 0;
+var V = 1;
+
+var Bounds = exports.Bounds = function () {
+    function Bounds(x, y, w, h) {
+        _classCallCheck(this, Bounds);
+
+        this.left = x;
+        this.top = y;
+        this.width = w;
+        this.height = h;
+    }
+
+    _createClass(Bounds, null, [{
+        key: 'fromClientRect',
+        value: function fromClientRect(clientRect, scrollX, scrollY) {
+            return new Bounds(clientRect.left + scrollX, clientRect.top + scrollY, clientRect.width, clientRect.height);
+        }
+    }]);
+
+    return Bounds;
+}();
+
+var parseBounds = exports.parseBounds = function parseBounds(node, scrollX, scrollY) {
+    return Bounds.fromClientRect(node.getBoundingClientRect(), scrollX, scrollY);
+};
+
+var calculatePaddingBox = exports.calculatePaddingBox = function calculatePaddingBox(bounds, borders) {
+    return new Bounds(bounds.left + borders[LEFT].borderWidth, bounds.top + borders[TOP].borderWidth, bounds.width - (borders[RIGHT].borderWidth + borders[LEFT].borderWidth), bounds.height - (borders[TOP].borderWidth + borders[BOTTOM].borderWidth));
+};
+
+var calculateContentBox = exports.calculateContentBox = function calculateContentBox(bounds, padding, borders) {
+    // TODO support percentage paddings
+    var paddingTop = padding[TOP].value;
+    var paddingRight = padding[RIGHT].value;
+    var paddingBottom = padding[BOTTOM].value;
+    var paddingLeft = padding[LEFT].value;
+
+    return new Bounds(bounds.left + paddingLeft + borders[LEFT].borderWidth, bounds.top + paddingTop + borders[TOP].borderWidth, bounds.width - (borders[RIGHT].borderWidth + borders[LEFT].borderWidth + paddingLeft + paddingRight), bounds.height - (borders[TOP].borderWidth + borders[BOTTOM].borderWidth + paddingTop + paddingBottom));
+};
+
+var parseDocumentSize = exports.parseDocumentSize = function parseDocumentSize(document) {
+    var body = document.body;
+    var documentElement = document.documentElement;
+
+    if (!body || !documentElement) {
+        throw new Error(process.env.NODE_ENV !== 'production' ? 'Unable to get document size' : '');
+    }
+    var width = Math.max(Math.max(body.scrollWidth, documentElement.scrollWidth), Math.max(body.offsetWidth, documentElement.offsetWidth), Math.max(body.clientWidth, documentElement.clientWidth));
+
+    var height = Math.max(Math.max(body.scrollHeight, documentElement.scrollHeight), Math.max(body.offsetHeight, documentElement.offsetHeight), Math.max(body.clientHeight, documentElement.clientHeight));
+
+    return new Bounds(0, 0, width, height);
+};
+
+var parsePathForBorder = exports.parsePathForBorder = function parsePathForBorder(curves, borderSide) {
+    switch (borderSide) {
+        case TOP:
+            return createPathFromCurves(curves.topLeftOuter, curves.topLeftInner, curves.topRightOuter, curves.topRightInner);
+        case RIGHT:
+            return createPathFromCurves(curves.topRightOuter, curves.topRightInner, curves.bottomRightOuter, curves.bottomRightInner);
+        case BOTTOM:
+            return createPathFromCurves(curves.bottomRightOuter, curves.bottomRightInner, curves.bottomLeftOuter, curves.bottomLeftInner);
+        case LEFT:
+        default:
+            return createPathFromCurves(curves.bottomLeftOuter, curves.bottomLeftInner, curves.topLeftOuter, curves.topLeftInner);
+    }
+};
+
+var createPathFromCurves = function createPathFromCurves(outer1, inner1, outer2, inner2) {
+    var path = [];
+    if (outer1 instanceof _BezierCurve2.default) {
+        path.push(outer1.subdivide(0.5, false));
+    } else {
+        path.push(outer1);
+    }
+
+    if (outer2 instanceof _BezierCurve2.default) {
+        path.push(outer2.subdivide(0.5, true));
+    } else {
+        path.push(outer2);
+    }
+
+    if (inner2 instanceof _BezierCurve2.default) {
+        path.push(inner2.subdivide(0.5, true).reverse());
+    } else {
+        path.push(inner2);
+    }
+
+    if (inner1 instanceof _BezierCurve2.default) {
+        path.push(inner1.subdivide(0.5, false).reverse());
+    } else {
+        path.push(inner1);
+    }
+
+    return path;
+};
+
+var calculateBorderBoxPath = exports.calculateBorderBoxPath = function calculateBorderBoxPath(curves) {
+    return [curves.topLeftOuter, curves.topRightOuter, curves.bottomRightOuter, curves.bottomLeftOuter];
+};
+
+var calculatePaddingBoxPath = exports.calculatePaddingBoxPath = function calculatePaddingBoxPath(curves) {
+    return [curves.topLeftInner, curves.topRightInner, curves.bottomRightInner, curves.bottomLeftInner];
+};
+
+var parseBoundCurves = exports.parseBoundCurves = function parseBoundCurves(bounds, borders, borderRadius) {
+    var tlh = borderRadius[CORNER.TOP_LEFT][H].getAbsoluteValue(bounds.width);
+    var tlv = borderRadius[CORNER.TOP_LEFT][V].getAbsoluteValue(bounds.height);
+    var trh = borderRadius[CORNER.TOP_RIGHT][H].getAbsoluteValue(bounds.width);
+    var trv = borderRadius[CORNER.TOP_RIGHT][V].getAbsoluteValue(bounds.height);
+    var brh = borderRadius[CORNER.BOTTOM_RIGHT][H].getAbsoluteValue(bounds.width);
+    var brv = borderRadius[CORNER.BOTTOM_RIGHT][V].getAbsoluteValue(bounds.height);
+    var blh = borderRadius[CORNER.BOTTOM_LEFT][H].getAbsoluteValue(bounds.width);
+    var blv = borderRadius[CORNER.BOTTOM_LEFT][V].getAbsoluteValue(bounds.height);
+
+    var factors = [];
+    factors.push((tlh + trh) / bounds.width);
+    factors.push((blh + brh) / bounds.width);
+    factors.push((tlv + blv) / bounds.height);
+    factors.push((trv + brv) / bounds.height);
+    var maxFactor = Math.max.apply(Math, factors);
+
+    if (maxFactor > 1) {
+        tlh /= maxFactor;
+        tlv /= maxFactor;
+        trh /= maxFactor;
+        trv /= maxFactor;
+        brh /= maxFactor;
+        brv /= maxFactor;
+        blh /= maxFactor;
+        blv /= maxFactor;
+    }
+
+    var topWidth = bounds.width - trh;
+    var rightHeight = bounds.height - brv;
+    var bottomWidth = bounds.width - brh;
+    var leftHeight = bounds.height - blv;
+
+    return {
+        topLeftOuter: tlh > 0 || tlv > 0 ? getCurvePoints(bounds.left, bounds.top, tlh, tlv, CORNER.TOP_LEFT) : new _Vector2.default(bounds.left, bounds.top),
+        topLeftInner: tlh > 0 || tlv > 0 ? getCurvePoints(bounds.left + borders[LEFT].borderWidth, bounds.top + borders[TOP].borderWidth, Math.max(0, tlh - borders[LEFT].borderWidth), Math.max(0, tlv - borders[TOP].borderWidth), CORNER.TOP_LEFT) : new _Vector2.default(bounds.left + borders[LEFT].borderWidth, bounds.top + borders[TOP].borderWidth),
+        topRightOuter: trh > 0 || trv > 0 ? getCurvePoints(bounds.left + topWidth, bounds.top, trh, trv, CORNER.TOP_RIGHT) : new _Vector2.default(bounds.left + bounds.width, bounds.top),
+        topRightInner: trh > 0 || trv > 0 ? getCurvePoints(bounds.left + Math.min(topWidth, bounds.width + borders[LEFT].borderWidth), bounds.top + borders[TOP].borderWidth, topWidth > bounds.width + borders[LEFT].borderWidth ? 0 : trh - borders[LEFT].borderWidth, trv - borders[TOP].borderWidth, CORNER.TOP_RIGHT) : new _Vector2.default(bounds.left + bounds.width - borders[RIGHT].borderWidth, bounds.top + borders[TOP].borderWidth),
+        bottomRightOuter: brh > 0 || brv > 0 ? getCurvePoints(bounds.left + bottomWidth, bounds.top + rightHeight, brh, brv, CORNER.BOTTOM_RIGHT) : new _Vector2.default(bounds.left + bounds.width, bounds.top + bounds.height),
+        bottomRightInner: brh > 0 || brv > 0 ? getCurvePoints(bounds.left + Math.min(bottomWidth, bounds.width - borders[LEFT].borderWidth), bounds.top + Math.min(rightHeight, bounds.height + borders[TOP].borderWidth), Math.max(0, brh - borders[RIGHT].borderWidth), brv - borders[BOTTOM].borderWidth, CORNER.BOTTOM_RIGHT) : new _Vector2.default(bounds.left + bounds.width - borders[RIGHT].borderWidth, bounds.top + bounds.height - borders[BOTTOM].borderWidth),
+        bottomLeftOuter: blh > 0 || blv > 0 ? getCurvePoints(bounds.left, bounds.top + leftHeight, blh, blv, CORNER.BOTTOM_LEFT) : new _Vector2.default(bounds.left, bounds.top + bounds.height),
+        bottomLeftInner: blh > 0 || blv > 0 ? getCurvePoints(bounds.left + borders[LEFT].borderWidth, bounds.top + leftHeight, Math.max(0, blh - borders[LEFT].borderWidth), blv - borders[BOTTOM].borderWidth, CORNER.BOTTOM_LEFT) : new _Vector2.default(bounds.left + borders[LEFT].borderWidth, bounds.top + bounds.height - borders[BOTTOM].borderWidth)
+    };
+};
+
+var CORNER = {
+    TOP_LEFT: 0,
+    TOP_RIGHT: 1,
+    BOTTOM_RIGHT: 2,
+    BOTTOM_LEFT: 3
+};
+
+var getCurvePoints = function getCurvePoints(x, y, r1, r2, position) {
+    var kappa = 4 * ((Math.sqrt(2) - 1) / 3);
+    var ox = r1 * kappa; // control point offset horizontal
+    var oy = r2 * kappa; // control point offset vertical
+    var xm = x + r1; // x-middle
+    var ym = y + r2; // y-middle
+
+    switch (position) {
+        case CORNER.TOP_LEFT:
+            return new _BezierCurve2.default(new _Vector2.default(x, ym), new _Vector2.default(x, ym - oy), new _Vector2.default(xm - ox, y), new _Vector2.default(xm, y));
+        case CORNER.TOP_RIGHT:
+            return new _BezierCurve2.default(new _Vector2.default(x, y), new _Vector2.default(x + ox, y), new _Vector2.default(xm, ym - oy), new _Vector2.default(xm, ym));
+        case CORNER.BOTTOM_RIGHT:
+            return new _BezierCurve2.default(new _Vector2.default(xm, y), new _Vector2.default(xm, y + oy), new _Vector2.default(x + ox, ym), new _Vector2.default(x, ym));
+        case CORNER.BOTTOM_LEFT:
+        default:
+            return new _BezierCurve2.default(new _Vector2.default(xm, ym), new _Vector2.default(xm - ox, ym), new _Vector2.default(x, y + oy), new _Vector2.default(x, y));
+    }
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/Clone.js b/AstuteClient2/src/assets/html2canvas/dist/npm/Clone.js
new file mode 100644
index 0000000..316c990
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/Clone.js
@@ -0,0 +1,582 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.cloneWindow = exports.DocumentCloner = undefined;
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Bounds = require('./Bounds');
+
+var _Proxy = require('./Proxy');
+
+var _ResourceLoader = require('./ResourceLoader');
+
+var _ResourceLoader2 = _interopRequireDefault(_ResourceLoader);
+
+var _Util = require('./Util');
+
+var _background = require('./parsing/background');
+
+var _CanvasRenderer = require('./renderer/CanvasRenderer');
+
+var _CanvasRenderer2 = _interopRequireDefault(_CanvasRenderer);
+
+var _PseudoNodeContent = require('./PseudoNodeContent');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var IGNORE_ATTRIBUTE = 'data-html2canvas-ignore';
+
+var DocumentCloner = exports.DocumentCloner = function () {
+    function DocumentCloner(element, options, logger, copyInline, renderer) {
+        _classCallCheck(this, DocumentCloner);
+
+        this.referenceElement = element;
+        this.scrolledElements = [];
+        this.copyStyles = copyInline;
+        this.inlineImages = copyInline;
+        this.logger = logger;
+        this.options = options;
+        this.renderer = renderer;
+        this.resourceLoader = new _ResourceLoader2.default(options, logger, window);
+        this.pseudoContentData = {
+            counters: {},
+            quoteDepth: 0
+        };
+        // $FlowFixMe
+        this.documentElement = this.cloneNode(element.ownerDocument.documentElement);
+    }
+
+    _createClass(DocumentCloner, [{
+        key: 'inlineAllImages',
+        value: function inlineAllImages(node) {
+            var _this = this;
+
+            if (this.inlineImages && node) {
+                var style = node.style;
+                Promise.all((0, _background.parseBackgroundImage)(style.backgroundImage).map(function (backgroundImage) {
+                    if (backgroundImage.method === 'url') {
+                        return _this.resourceLoader.inlineImage(backgroundImage.args[0]).then(function (img) {
+                            return img && typeof img.src === 'string' ? 'url("' + img.src + '")' : 'none';
+                        }).catch(function (e) {
+                            if (process.env.NODE_ENV !== 'production') {
+                                _this.logger.log('Unable to load image', e);
+                            }
+                        });
+                    }
+                    return Promise.resolve('' + backgroundImage.prefix + backgroundImage.method + '(' + backgroundImage.args.join(',') + ')');
+                })).then(function (backgroundImages) {
+                    if (backgroundImages.length > 1) {
+                        // TODO Multiple backgrounds somehow broken in Chrome
+                        style.backgroundColor = '';
+                    }
+                    style.backgroundImage = backgroundImages.join(',');
+                });
+
+                if (node instanceof HTMLImageElement) {
+                    this.resourceLoader.inlineImage(node.src).then(function (img) {
+                        if (img && node instanceof HTMLImageElement && node.parentNode) {
+                            var parentNode = node.parentNode;
+                            var clonedChild = (0, _Util.copyCSSStyles)(node.style, img.cloneNode(false));
+                            parentNode.replaceChild(clonedChild, node);
+                        }
+                    }).catch(function (e) {
+                        if (process.env.NODE_ENV !== 'production') {
+                            _this.logger.log('Unable to load image', e);
+                        }
+                    });
+                }
+            }
+        }
+    }, {
+        key: 'inlineFonts',
+        value: function inlineFonts(document) {
+            var _this2 = this;
+
+            return Promise.all(Array.from(document.styleSheets).map(function (sheet) {
+                if (sheet.href) {
+                    return fetch(sheet.href).then(function (res) {
+                        return res.text();
+                    }).then(function (text) {
+                        return createStyleSheetFontsFromText(text, sheet.href);
+                    }).catch(function (e) {
+                        if (process.env.NODE_ENV !== 'production') {
+                            _this2.logger.log('Unable to load stylesheet', e);
+                        }
+                        return [];
+                    });
+                }
+                return getSheetFonts(sheet, document);
+            })).then(function (fonts) {
+                return fonts.reduce(function (acc, font) {
+                    return acc.concat(font);
+                }, []);
+            }).then(function (fonts) {
+                return Promise.all(fonts.map(function (font) {
+                    return fetch(font.formats[0].src).then(function (response) {
+                        return response.blob();
+                    }).then(function (blob) {
+                        return new Promise(function (resolve, reject) {
+                            var reader = new FileReader();
+                            reader.onerror = reject;
+                            reader.onload = function () {
+                                // $FlowFixMe
+                                var result = reader.result;
+                                resolve(result);
+                            };
+                            reader.readAsDataURL(blob);
+                        });
+                    }).then(function (dataUri) {
+                        font.fontFace.setProperty('src', 'url("' + dataUri + '")');
+                        return '@font-face {' + font.fontFace.cssText + ' ';
+                    });
+                }));
+            }).then(function (fontCss) {
+                var style = document.createElement('style');
+                style.textContent = fontCss.join('\n');
+                _this2.documentElement.appendChild(style);
+            });
+        }
+    }, {
+        key: 'createElementClone',
+        value: function createElementClone(node) {
+            var _this3 = this;
+
+            if (this.copyStyles && node instanceof HTMLCanvasElement) {
+                var img = node.ownerDocument.createElement('img');
+                try {
+                    img.src = node.toDataURL();
+                    return img;
+                } catch (e) {
+                    if (process.env.NODE_ENV !== 'production') {
+                        this.logger.log('Unable to clone canvas contents, canvas is tainted');
+                    }
+                }
+            }
+
+            if (node instanceof HTMLIFrameElement) {
+                var tempIframe = node.cloneNode(false);
+                var iframeKey = generateIframeKey();
+                tempIframe.setAttribute('data-html2canvas-internal-iframe-key', iframeKey);
+
+                var _parseBounds = (0, _Bounds.parseBounds)(node, 0, 0),
+                    width = _parseBounds.width,
+                    height = _parseBounds.height;
+
+                this.resourceLoader.cache[iframeKey] = getIframeDocumentElement(node, this.options).then(function (documentElement) {
+                    return _this3.renderer(documentElement, {
+                        async: _this3.options.async,
+                        allowTaint: _this3.options.allowTaint,
+                        backgroundColor: '#ffffff',
+                        canvas: null,
+                        imageTimeout: _this3.options.imageTimeout,
+                        logging: _this3.options.logging,
+                        proxy: _this3.options.proxy,
+                        removeContainer: _this3.options.removeContainer,
+                        scale: _this3.options.scale,
+                        foreignObjectRendering: _this3.options.foreignObjectRendering,
+                        useCORS: _this3.options.useCORS,
+                        target: new _CanvasRenderer2.default(),
+                        width: width,
+                        height: height,
+                        x: 0,
+                        y: 0,
+                        windowWidth: documentElement.ownerDocument.defaultView.innerWidth,
+                        windowHeight: documentElement.ownerDocument.defaultView.innerHeight,
+                        scrollX: documentElement.ownerDocument.defaultView.pageXOffset,
+                        scrollY: documentElement.ownerDocument.defaultView.pageYOffset
+                    }, _this3.logger.child(iframeKey));
+                }).then(function (canvas) {
+                    return new Promise(function (resolve, reject) {
+                        var iframeCanvas = document.createElement('img');
+                        iframeCanvas.onload = function () {
+                            return resolve(canvas);
+                        };
+                        iframeCanvas.onerror = reject;
+                        iframeCanvas.src = canvas.toDataURL();
+                        if (tempIframe.parentNode) {
+                            tempIframe.parentNode.replaceChild((0, _Util.copyCSSStyles)(node.ownerDocument.defaultView.getComputedStyle(node), iframeCanvas), tempIframe);
+                        }
+                    });
+                });
+                return tempIframe;
+            }
+
+            if (node instanceof HTMLStyleElement && node.sheet && node.sheet.cssRules) {
+                var css = [].slice.call(node.sheet.cssRules, 0).reduce(function (css, rule) {
+                    try {
+                        if (rule && rule.cssText) {
+                            return css + rule.cssText;
+                        }
+                        return css;
+                    } catch (err) {
+                        _this3.logger.log('Unable to access cssText property', rule.name);
+                        return css;
+                    }
+                }, '');
+                var style = node.cloneNode(false);
+                style.textContent = css;
+                return style;
+            }
+
+            return node.cloneNode(false);
+        }
+    }, {
+        key: 'cloneNode',
+        value: function cloneNode(node) {
+            var clone = node.nodeType === Node.TEXT_NODE ? document.createTextNode(node.nodeValue) : this.createElementClone(node);
+
+            var window = node.ownerDocument.defaultView;
+            var style = node instanceof window.HTMLElement ? window.getComputedStyle(node) : null;
+            var styleBefore = node instanceof window.HTMLElement ? window.getComputedStyle(node, ':before') : null;
+            var styleAfter = node instanceof window.HTMLElement ? window.getComputedStyle(node, ':after') : null;
+
+            if (this.referenceElement === node && clone instanceof window.HTMLElement) {
+                this.clonedReferenceElement = clone;
+            }
+
+            if (clone instanceof window.HTMLBodyElement) {
+                createPseudoHideStyles(clone);
+            }
+
+            var counters = (0, _PseudoNodeContent.parseCounterReset)(style, this.pseudoContentData);
+            var contentBefore = (0, _PseudoNodeContent.resolvePseudoContent)(node, styleBefore, this.pseudoContentData);
+
+            for (var child = node.firstChild; child; child = child.nextSibling) {
+                if (child.nodeType !== Node.ELEMENT_NODE || child.nodeName !== 'SCRIPT' &&
+                // $FlowFixMe
+                !child.hasAttribute(IGNORE_ATTRIBUTE) && (typeof this.options.ignoreElements !== 'function' ||
+                // $FlowFixMe
+                !this.options.ignoreElements(child))) {
+                    if (!this.copyStyles || child.nodeName !== 'STYLE') {
+                        clone.appendChild(this.cloneNode(child));
+                    }
+                }
+            }
+
+            var contentAfter = (0, _PseudoNodeContent.resolvePseudoContent)(node, styleAfter, this.pseudoContentData);
+            (0, _PseudoNodeContent.popCounters)(counters, this.pseudoContentData);
+
+            if (node instanceof window.HTMLElement && clone instanceof window.HTMLElement) {
+                if (styleBefore) {
+                    this.inlineAllImages(inlinePseudoElement(node, clone, styleBefore, contentBefore, PSEUDO_BEFORE));
+                }
+                if (styleAfter) {
+                    this.inlineAllImages(inlinePseudoElement(node, clone, styleAfter, contentAfter, PSEUDO_AFTER));
+                }
+                if (style && this.copyStyles && !(node instanceof HTMLIFrameElement)) {
+                    (0, _Util.copyCSSStyles)(style, clone);
+                }
+                this.inlineAllImages(clone);
+                if (node.scrollTop !== 0 || node.scrollLeft !== 0) {
+                    this.scrolledElements.push([clone, node.scrollLeft, node.scrollTop]);
+                }
+                switch (node.nodeName) {
+                    case 'CANVAS':
+                        if (!this.copyStyles) {
+                            cloneCanvasContents(node, clone);
+                        }
+                        break;
+                    case 'TEXTAREA':
+                    case 'SELECT':
+                        clone.value = node.value;
+                        break;
+                }
+            }
+            return clone;
+        }
+    }]);
+
+    return DocumentCloner;
+}();
+
+var getSheetFonts = function getSheetFonts(sheet, document) {
+    // $FlowFixMe
+    return (sheet.cssRules ? Array.from(sheet.cssRules) : []).filter(function (rule) {
+        return rule.type === CSSRule.FONT_FACE_RULE;
+    }).map(function (rule) {
+        var src = (0, _background.parseBackgroundImage)(rule.style.getPropertyValue('src'));
+        var formats = [];
+        for (var i = 0; i < src.length; i++) {
+            if (src[i].method === 'url' && src[i + 1] && src[i + 1].method === 'format') {
+                var a = document.createElement('a');
+                a.href = src[i].args[0];
+                if (document.body) {
+                    document.body.appendChild(a);
+                }
+
+                var font = {
+                    src: a.href,
+                    format: src[i + 1].args[0]
+                };
+                formats.push(font);
+            }
+        }
+
+        return {
+            // TODO select correct format for browser),
+
+            formats: formats.filter(function (font) {
+                return (/^woff/i.test(font.format)
+                );
+            }),
+            fontFace: rule.style
+        };
+    }).filter(function (font) {
+        return font.formats.length;
+    });
+};
+
+var createStyleSheetFontsFromText = function createStyleSheetFontsFromText(text, baseHref) {
+    var doc = document.implementation.createHTMLDocument('');
+    var base = document.createElement('base');
+    // $FlowFixMe
+    base.href = baseHref;
+    var style = document.createElement('style');
+
+    style.textContent = text;
+    if (doc.head) {
+        doc.head.appendChild(base);
+    }
+    if (doc.body) {
+        doc.body.appendChild(style);
+    }
+
+    return style.sheet ? getSheetFonts(style.sheet, doc) : [];
+};
+
+var restoreOwnerScroll = function restoreOwnerScroll(ownerDocument, x, y) {
+    if (ownerDocument.defaultView && (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset)) {
+        ownerDocument.defaultView.scrollTo(x, y);
+    }
+};
+
+var cloneCanvasContents = function cloneCanvasContents(canvas, clonedCanvas) {
+    try {
+        if (clonedCanvas) {
+            clonedCanvas.width = canvas.width;
+            clonedCanvas.height = canvas.height;
+            var ctx = canvas.getContext('2d');
+            var clonedCtx = clonedCanvas.getContext('2d');
+            if (ctx) {
+                clonedCtx.putImageData(ctx.getImageData(0, 0, canvas.width, canvas.height), 0, 0);
+            } else {
+                clonedCtx.drawImage(canvas, 0, 0);
+            }
+        }
+    } catch (e) {}
+};
+
+var inlinePseudoElement = function inlinePseudoElement(node, clone, style, contentItems, pseudoElt) {
+    if (!style || !style.content || style.content === 'none' || style.content === '-moz-alt-content' || style.display === 'none') {
+        return;
+    }
+
+    var anonymousReplacedElement = clone.ownerDocument.createElement('html2canvaspseudoelement');
+    (0, _Util.copyCSSStyles)(style, anonymousReplacedElement);
+
+    if (contentItems) {
+        var len = contentItems.length;
+        for (var i = 0; i < len; i++) {
+            var item = contentItems[i];
+            switch (item.type) {
+                case _PseudoNodeContent.PSEUDO_CONTENT_ITEM_TYPE.IMAGE:
+                    var img = clone.ownerDocument.createElement('img');
+                    img.src = (0, _background.parseBackgroundImage)('url(' + item.value + ')')[0].args[0];
+                    img.style.opacity = '1';
+                    anonymousReplacedElement.appendChild(img);
+                    break;
+                case _PseudoNodeContent.PSEUDO_CONTENT_ITEM_TYPE.TEXT:
+                    anonymousReplacedElement.appendChild(clone.ownerDocument.createTextNode(item.value));
+                    break;
+            }
+        }
+    }
+
+    anonymousReplacedElement.className = PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + ' ' + PSEUDO_HIDE_ELEMENT_CLASS_AFTER;
+    clone.className += pseudoElt === PSEUDO_BEFORE ? ' ' + PSEUDO_HIDE_ELEMENT_CLASS_BEFORE : ' ' + PSEUDO_HIDE_ELEMENT_CLASS_AFTER;
+    if (pseudoElt === PSEUDO_BEFORE) {
+        clone.insertBefore(anonymousReplacedElement, clone.firstChild);
+    } else {
+        clone.appendChild(anonymousReplacedElement);
+    }
+
+    return anonymousReplacedElement;
+};
+
+var URL_REGEXP = /^url\((.+)\)$/i;
+var PSEUDO_BEFORE = ':before';
+var PSEUDO_AFTER = ':after';
+var PSEUDO_HIDE_ELEMENT_CLASS_BEFORE = '___html2canvas___pseudoelement_before';
+var PSEUDO_HIDE_ELEMENT_CLASS_AFTER = '___html2canvas___pseudoelement_after';
+
+var PSEUDO_HIDE_ELEMENT_STYLE = '{\n    content: "" !important;\n    display: none !important;\n}';
+
+var createPseudoHideStyles = function createPseudoHideStyles(body) {
+    createStyles(body, '.' + PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + PSEUDO_BEFORE + PSEUDO_HIDE_ELEMENT_STYLE + '\n         .' + PSEUDO_HIDE_ELEMENT_CLASS_AFTER + PSEUDO_AFTER + PSEUDO_HIDE_ELEMENT_STYLE);
+};
+
+var createStyles = function createStyles(body, styles) {
+    var style = body.ownerDocument.createElement('style');
+    style.innerHTML = styles;
+    body.appendChild(style);
+};
+
+var initNode = function initNode(_ref) {
+    var _ref2 = _slicedToArray(_ref, 3),
+        element = _ref2[0],
+        x = _ref2[1],
+        y = _ref2[2];
+
+    element.scrollLeft = x;
+    element.scrollTop = y;
+};
+
+var generateIframeKey = function generateIframeKey() {
+    return Math.ceil(Date.now() + Math.random() * 10000000).toString(16);
+};
+
+var DATA_URI_REGEXP = /^data:text\/(.+);(base64)?,(.*)$/i;
+
+var getIframeDocumentElement = function getIframeDocumentElement(node, options) {
+    try {
+        return Promise.resolve(node.contentWindow.document.documentElement);
+    } catch (e) {
+        return options.proxy ? (0, _Proxy.Proxy)(node.src, options).then(function (html) {
+            var match = html.match(DATA_URI_REGEXP);
+            if (!match) {
+                return Promise.reject();
+            }
+
+            return match[2] === 'base64' ? window.atob(decodeURIComponent(match[3])) : decodeURIComponent(match[3]);
+        }).then(function (html) {
+            return createIframeContainer(node.ownerDocument, (0, _Bounds.parseBounds)(node, 0, 0)).then(function (cloneIframeContainer) {
+                var cloneWindow = cloneIframeContainer.contentWindow;
+                var documentClone = cloneWindow.document;
+
+                documentClone.open();
+                documentClone.write(html);
+                var iframeLoad = iframeLoader(cloneIframeContainer).then(function () {
+                    return documentClone.documentElement;
+                });
+
+                documentClone.close();
+                return iframeLoad;
+            });
+        }) : Promise.reject();
+    }
+};
+
+var createIframeContainer = function createIframeContainer(ownerDocument, bounds) {
+    var cloneIframeContainer = ownerDocument.createElement('iframe');
+
+    cloneIframeContainer.className = 'html2canvas-container';
+    cloneIframeContainer.style.visibility = 'hidden';
+    cloneIframeContainer.style.position = 'fixed';
+    cloneIframeContainer.style.left = '-10000px';
+    cloneIframeContainer.style.top = '0px';
+    cloneIframeContainer.style.border = '0';
+    cloneIframeContainer.width = bounds.width.toString();
+    cloneIframeContainer.height = bounds.height.toString();
+    cloneIframeContainer.scrolling = 'no'; // ios won't scroll without it
+    cloneIframeContainer.setAttribute(IGNORE_ATTRIBUTE, 'true');
+    if (!ownerDocument.body) {
+        return Promise.reject(process.env.NODE_ENV !== 'production' ? 'Body element not found in Document that is getting rendered' : '');
+    }
+
+    ownerDocument.body.appendChild(cloneIframeContainer);
+
+    return Promise.resolve(cloneIframeContainer);
+};
+
+var iframeLoader = function iframeLoader(cloneIframeContainer) {
+    var cloneWindow = cloneIframeContainer.contentWindow;
+    var documentClone = cloneWindow.document;
+
+    return new Promise(function (resolve, reject) {
+        cloneWindow.onload = cloneIframeContainer.onload = documentClone.onreadystatechange = function () {
+            var interval = setInterval(function () {
+                if (documentClone.body.childNodes.length > 0 && documentClone.readyState === 'complete') {
+                    clearInterval(interval);
+                    resolve(cloneIframeContainer);
+                }
+            }, 50);
+        };
+    });
+};
+
+var cloneWindow = exports.cloneWindow = function cloneWindow(ownerDocument, bounds, referenceElement, options, logger, renderer) {
+    var cloner = new DocumentCloner(referenceElement, options, logger, false, renderer);
+    var scrollX = ownerDocument.defaultView.pageXOffset;
+    var scrollY = ownerDocument.defaultView.pageYOffset;
+
+    return createIframeContainer(ownerDocument, bounds).then(function (cloneIframeContainer) {
+        var cloneWindow = cloneIframeContainer.contentWindow;
+        var documentClone = cloneWindow.document;
+
+        /* Chrome doesn't detect relative background-images assigned in inline <style> sheets when fetched through getComputedStyle
+             if window url is about:blank, we can assign the url to current by writing onto the document
+             */
+
+        var iframeLoad = iframeLoader(cloneIframeContainer).then(function () {
+            cloner.scrolledElements.forEach(initNode);
+            cloneWindow.scrollTo(bounds.left, bounds.top);
+            if (/(iPad|iPhone|iPod)/g.test(navigator.userAgent) && (cloneWindow.scrollY !== bounds.top || cloneWindow.scrollX !== bounds.left)) {
+                documentClone.documentElement.style.top = -bounds.top + 'px';
+                documentClone.documentElement.style.left = -bounds.left + 'px';
+                documentClone.documentElement.style.position = 'absolute';
+            }
+
+            var result = Promise.resolve([cloneIframeContainer, cloner.clonedReferenceElement, cloner.resourceLoader]);
+
+            var onclone = options.onclone;
+
+            return cloner.clonedReferenceElement instanceof cloneWindow.HTMLElement || cloner.clonedReferenceElement instanceof ownerDocument.defaultView.HTMLElement || cloner.clonedReferenceElement instanceof HTMLElement ? typeof onclone === 'function' ? Promise.resolve().then(function () {
+                return onclone(documentClone);
+            }).then(function () {
+                return result;
+            }) : result : Promise.reject(process.env.NODE_ENV !== 'production' ? 'Error finding the ' + referenceElement.nodeName + ' in the cloned document' : '');
+        });
+
+        documentClone.open();
+        documentClone.write(serializeDoctype(document.doctype) + '<html></html>');
+        // Chrome scrolls the parent document for some reason after the write to the cloned window???
+        restoreOwnerScroll(referenceElement.ownerDocument, scrollX, scrollY);
+        documentClone.replaceChild(documentClone.adoptNode(cloner.documentElement), documentClone.documentElement);
+        documentClone.close();
+
+        return iframeLoad;
+    });
+};
+
+var serializeDoctype = function serializeDoctype(doctype) {
+    var str = '';
+    if (doctype) {
+        str += '<!DOCTYPE ';
+        if (doctype.name) {
+            str += doctype.name;
+        }
+
+        if (doctype.internalSubset) {
+            str += doctype.internalSubset;
+        }
+
+        if (doctype.publicId) {
+            str += '"' + doctype.publicId + '"';
+        }
+
+        if (doctype.systemId) {
+            str += '"' + doctype.systemId + '"';
+        }
+
+        str += '>';
+    }
+
+    return str;
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/Color.js b/AstuteClient2/src/assets/html2canvas/dist/npm/Color.js
new file mode 100644
index 0000000..2a48733
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/Color.js
@@ -0,0 +1,247 @@
+'use strict';
+
+// http://dev.w3.org/csswg/css-color/
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var HEX3 = /^#([a-f0-9]{3})$/i;
+var hex3 = function hex3(value) {
+    var match = value.match(HEX3);
+    if (match) {
+        return [parseInt(match[1][0] + match[1][0], 16), parseInt(match[1][1] + match[1][1], 16), parseInt(match[1][2] + match[1][2], 16), null];
+    }
+    return false;
+};
+
+var HEX6 = /^#([a-f0-9]{6})$/i;
+var hex6 = function hex6(value) {
+    var match = value.match(HEX6);
+    if (match) {
+        return [parseInt(match[1].substring(0, 2), 16), parseInt(match[1].substring(2, 4), 16), parseInt(match[1].substring(4, 6), 16), null];
+    }
+    return false;
+};
+
+var RGB = /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/;
+var rgb = function rgb(value) {
+    var match = value.match(RGB);
+    if (match) {
+        return [Number(match[1]), Number(match[2]), Number(match[3]), null];
+    }
+    return false;
+};
+
+var RGBA = /^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d?\.?\d+)\s*\)$/;
+var rgba = function rgba(value) {
+    var match = value.match(RGBA);
+    if (match && match.length > 4) {
+        return [Number(match[1]), Number(match[2]), Number(match[3]), Number(match[4])];
+    }
+    return false;
+};
+
+var fromArray = function fromArray(array) {
+    return [Math.min(array[0], 255), Math.min(array[1], 255), Math.min(array[2], 255), array.length > 3 ? array[3] : null];
+};
+
+var namedColor = function namedColor(name) {
+    var color = NAMED_COLORS[name.toLowerCase()];
+    return color ? color : false;
+};
+
+var Color = function () {
+    function Color(value) {
+        _classCallCheck(this, Color);
+
+        var _ref = Array.isArray(value) ? fromArray(value) : hex3(value) || rgb(value) || rgba(value) || namedColor(value) || hex6(value) || [0, 0, 0, null],
+            _ref2 = _slicedToArray(_ref, 4),
+            r = _ref2[0],
+            g = _ref2[1],
+            b = _ref2[2],
+            a = _ref2[3];
+
+        this.r = r;
+        this.g = g;
+        this.b = b;
+        this.a = a;
+    }
+
+    _createClass(Color, [{
+        key: 'isTransparent',
+        value: function isTransparent() {
+            return this.a === 0;
+        }
+    }, {
+        key: 'toString',
+        value: function toString() {
+            return this.a !== null && this.a !== 1 ? 'rgba(' + this.r + ',' + this.g + ',' + this.b + ',' + this.a + ')' : 'rgb(' + this.r + ',' + this.g + ',' + this.b + ')';
+        }
+    }]);
+
+    return Color;
+}();
+
+exports.default = Color;
+
+
+var NAMED_COLORS = {
+    transparent: [0, 0, 0, 0],
+    aliceblue: [240, 248, 255, null],
+    antiquewhite: [250, 235, 215, null],
+    aqua: [0, 255, 255, null],
+    aquamarine: [127, 255, 212, null],
+    azure: [240, 255, 255, null],
+    beige: [245, 245, 220, null],
+    bisque: [255, 228, 196, null],
+    black: [0, 0, 0, null],
+    blanchedalmond: [255, 235, 205, null],
+    blue: [0, 0, 255, null],
+    blueviolet: [138, 43, 226, null],
+    brown: [165, 42, 42, null],
+    burlywood: [222, 184, 135, null],
+    cadetblue: [95, 158, 160, null],
+    chartreuse: [127, 255, 0, null],
+    chocolate: [210, 105, 30, null],
+    coral: [255, 127, 80, null],
+    cornflowerblue: [100, 149, 237, null],
+    cornsilk: [255, 248, 220, null],
+    crimson: [220, 20, 60, null],
+    cyan: [0, 255, 255, null],
+    darkblue: [0, 0, 139, null],
+    darkcyan: [0, 139, 139, null],
+    darkgoldenrod: [184, 134, 11, null],
+    darkgray: [169, 169, 169, null],
+    darkgreen: [0, 100, 0, null],
+    darkgrey: [169, 169, 169, null],
+    darkkhaki: [189, 183, 107, null],
+    darkmagenta: [139, 0, 139, null],
+    darkolivegreen: [85, 107, 47, null],
+    darkorange: [255, 140, 0, null],
+    darkorchid: [153, 50, 204, null],
+    darkred: [139, 0, 0, null],
+    darksalmon: [233, 150, 122, null],
+    darkseagreen: [143, 188, 143, null],
+    darkslateblue: [72, 61, 139, null],
+    darkslategray: [47, 79, 79, null],
+    darkslategrey: [47, 79, 79, null],
+    darkturquoise: [0, 206, 209, null],
+    darkviolet: [148, 0, 211, null],
+    deeppink: [255, 20, 147, null],
+    deepskyblue: [0, 191, 255, null],
+    dimgray: [105, 105, 105, null],
+    dimgrey: [105, 105, 105, null],
+    dodgerblue: [30, 144, 255, null],
+    firebrick: [178, 34, 34, null],
+    floralwhite: [255, 250, 240, null],
+    forestgreen: [34, 139, 34, null],
+    fuchsia: [255, 0, 255, null],
+    gainsboro: [220, 220, 220, null],
+    ghostwhite: [248, 248, 255, null],
+    gold: [255, 215, 0, null],
+    goldenrod: [218, 165, 32, null],
+    gray: [128, 128, 128, null],
+    green: [0, 128, 0, null],
+    greenyellow: [173, 255, 47, null],
+    grey: [128, 128, 128, null],
+    honeydew: [240, 255, 240, null],
+    hotpink: [255, 105, 180, null],
+    indianred: [205, 92, 92, null],
+    indigo: [75, 0, 130, null],
+    ivory: [255, 255, 240, null],
+    khaki: [240, 230, 140, null],
+    lavender: [230, 230, 250, null],
+    lavenderblush: [255, 240, 245, null],
+    lawngreen: [124, 252, 0, null],
+    lemonchiffon: [255, 250, 205, null],
+    lightblue: [173, 216, 230, null],
+    lightcoral: [240, 128, 128, null],
+    lightcyan: [224, 255, 255, null],
+    lightgoldenrodyellow: [250, 250, 210, null],
+    lightgray: [211, 211, 211, null],
+    lightgreen: [144, 238, 144, null],
+    lightgrey: [211, 211, 211, null],
+    lightpink: [255, 182, 193, null],
+    lightsalmon: [255, 160, 122, null],
+    lightseagreen: [32, 178, 170, null],
+    lightskyblue: [135, 206, 250, null],
+    lightslategray: [119, 136, 153, null],
+    lightslategrey: [119, 136, 153, null],
+    lightsteelblue: [176, 196, 222, null],
+    lightyellow: [255, 255, 224, null],
+    lime: [0, 255, 0, null],
+    limegreen: [50, 205, 50, null],
+    linen: [250, 240, 230, null],
+    magenta: [255, 0, 255, null],
+    maroon: [128, 0, 0, null],
+    mediumaquamarine: [102, 205, 170, null],
+    mediumblue: [0, 0, 205, null],
+    mediumorchid: [186, 85, 211, null],
+    mediumpurple: [147, 112, 219, null],
+    mediumseagreen: [60, 179, 113, null],
+    mediumslateblue: [123, 104, 238, null],
+    mediumspringgreen: [0, 250, 154, null],
+    mediumturquoise: [72, 209, 204, null],
+    mediumvioletred: [199, 21, 133, null],
+    midnightblue: [25, 25, 112, null],
+    mintcream: [245, 255, 250, null],
+    mistyrose: [255, 228, 225, null],
+    moccasin: [255, 228, 181, null],
+    navajowhite: [255, 222, 173, null],
+    navy: [0, 0, 128, null],
+    oldlace: [253, 245, 230, null],
+    olive: [128, 128, 0, null],
+    olivedrab: [107, 142, 35, null],
+    orange: [255, 165, 0, null],
+    orangered: [255, 69, 0, null],
+    orchid: [218, 112, 214, null],
+    palegoldenrod: [238, 232, 170, null],
+    palegreen: [152, 251, 152, null],
+    paleturquoise: [175, 238, 238, null],
+    palevioletred: [219, 112, 147, null],
+    papayawhip: [255, 239, 213, null],
+    peachpuff: [255, 218, 185, null],
+    peru: [205, 133, 63, null],
+    pink: [255, 192, 203, null],
+    plum: [221, 160, 221, null],
+    powderblue: [176, 224, 230, null],
+    purple: [128, 0, 128, null],
+    rebeccapurple: [102, 51, 153, null],
+    red: [255, 0, 0, null],
+    rosybrown: [188, 143, 143, null],
+    royalblue: [65, 105, 225, null],
+    saddlebrown: [139, 69, 19, null],
+    salmon: [250, 128, 114, null],
+    sandybrown: [244, 164, 96, null],
+    seagreen: [46, 139, 87, null],
+    seashell: [255, 245, 238, null],
+    sienna: [160, 82, 45, null],
+    silver: [192, 192, 192, null],
+    skyblue: [135, 206, 235, null],
+    slateblue: [106, 90, 205, null],
+    slategray: [112, 128, 144, null],
+    slategrey: [112, 128, 144, null],
+    snow: [255, 250, 250, null],
+    springgreen: [0, 255, 127, null],
+    steelblue: [70, 130, 180, null],
+    tan: [210, 180, 140, null],
+    teal: [0, 128, 128, null],
+    thistle: [216, 191, 216, null],
+    tomato: [255, 99, 71, null],
+    turquoise: [64, 224, 208, null],
+    violet: [238, 130, 238, null],
+    wheat: [245, 222, 179, null],
+    white: [255, 255, 255, null],
+    whitesmoke: [245, 245, 245, null],
+    yellow: [255, 255, 0, null],
+    yellowgreen: [154, 205, 50, null]
+};
+
+var TRANSPARENT = exports.TRANSPARENT = new Color([0, 0, 0, 0]);
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/Feature.js b/AstuteClient2/src/assets/html2canvas/dist/npm/Feature.js
new file mode 100644
index 0000000..87c085c
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/Feature.js
@@ -0,0 +1,193 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _ForeignObjectRenderer = require('./renderer/ForeignObjectRenderer');
+
+var testRangeBounds = function testRangeBounds(document) {
+    var TEST_HEIGHT = 123;
+
+    if (document.createRange) {
+        var range = document.createRange();
+        if (range.getBoundingClientRect) {
+            var testElement = document.createElement('boundtest');
+            testElement.style.height = TEST_HEIGHT + 'px';
+            testElement.style.display = 'block';
+            document.body.appendChild(testElement);
+
+            range.selectNode(testElement);
+            var rangeBounds = range.getBoundingClientRect();
+            var rangeHeight = Math.round(rangeBounds.height);
+            document.body.removeChild(testElement);
+            if (rangeHeight === TEST_HEIGHT) {
+                return true;
+            }
+        }
+    }
+
+    return false;
+};
+
+// iOS 10.3 taints canvas with base64 images unless crossOrigin = 'anonymous'
+var testBase64 = function testBase64(document, src) {
+    var img = new Image();
+    var canvas = document.createElement('canvas');
+    var ctx = canvas.getContext('2d');
+
+    return new Promise(function (resolve) {
+        // Single pixel base64 image renders fine on iOS 10.3???
+        img.src = src;
+
+        var onload = function onload() {
+            try {
+                ctx.drawImage(img, 0, 0);
+                canvas.toDataURL();
+            } catch (e) {
+                return resolve(false);
+            }
+
+            return resolve(true);
+        };
+
+        img.onload = onload;
+        img.onerror = function () {
+            return resolve(false);
+        };
+
+        if (img.complete === true) {
+            setTimeout(function () {
+                onload();
+            }, 500);
+        }
+    });
+};
+
+var testCORS = function testCORS() {
+    return typeof new Image().crossOrigin !== 'undefined';
+};
+
+var testResponseType = function testResponseType() {
+    return typeof new XMLHttpRequest().responseType === 'string';
+};
+
+var testSVG = function testSVG(document) {
+    var img = new Image();
+    var canvas = document.createElement('canvas');
+    var ctx = canvas.getContext('2d');
+    img.src = 'data:image/svg+xml,<svg xmlns=\'http://www.w3.org/2000/svg\'></svg>';
+
+    try {
+        ctx.drawImage(img, 0, 0);
+        canvas.toDataURL();
+    } catch (e) {
+        return false;
+    }
+    return true;
+};
+
+var isGreenPixel = function isGreenPixel(data) {
+    return data[0] === 0 && data[1] === 255 && data[2] === 0 && data[3] === 255;
+};
+
+var testForeignObject = function testForeignObject(document) {
+    var canvas = document.createElement('canvas');
+    var size = 100;
+    canvas.width = size;
+    canvas.height = size;
+    var ctx = canvas.getContext('2d');
+    ctx.fillStyle = 'rgb(0, 255, 0)';
+    ctx.fillRect(0, 0, size, size);
+
+    var img = new Image();
+    var greenImageSrc = canvas.toDataURL();
+    img.src = greenImageSrc;
+    var svg = (0, _ForeignObjectRenderer.createForeignObjectSVG)(size, size, 0, 0, img);
+    ctx.fillStyle = 'red';
+    ctx.fillRect(0, 0, size, size);
+
+    return (0, _ForeignObjectRenderer.loadSerializedSVG)(svg).then(function (img) {
+        ctx.drawImage(img, 0, 0);
+        var data = ctx.getImageData(0, 0, size, size).data;
+        ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, size, size);
+
+        var node = document.createElement('div');
+        node.style.backgroundImage = 'url(' + greenImageSrc + ')';
+        node.style.height = size + 'px';
+        // Firefox 55 does not render inline <img /> tags
+        return isGreenPixel(data) ? (0, _ForeignObjectRenderer.loadSerializedSVG)((0, _ForeignObjectRenderer.createForeignObjectSVG)(size, size, 0, 0, node)) : Promise.reject(false);
+    }).then(function (img) {
+        ctx.drawImage(img, 0, 0);
+        // Edge does not render background-images
+        return isGreenPixel(ctx.getImageData(0, 0, size, size).data);
+    }).catch(function (e) {
+        return false;
+    });
+};
+
+var FEATURES = {
+    // $FlowFixMe - get/set properties not yet supported
+    get SUPPORT_RANGE_BOUNDS() {
+        'use strict';
+
+        var value = testRangeBounds(document);
+        Object.defineProperty(FEATURES, 'SUPPORT_RANGE_BOUNDS', { value: value });
+        return value;
+    },
+    // $FlowFixMe - get/set properties not yet supported
+    get SUPPORT_SVG_DRAWING() {
+        'use strict';
+
+        var value = testSVG(document);
+        Object.defineProperty(FEATURES, 'SUPPORT_SVG_DRAWING', { value: value });
+        return value;
+    },
+    // $FlowFixMe - get/set properties not yet supported
+    get SUPPORT_BASE64_DRAWING() {
+        'use strict';
+
+        return function (src) {
+            var _value = testBase64(document, src);
+            Object.defineProperty(FEATURES, 'SUPPORT_BASE64_DRAWING', { value: function value() {
+                    return _value;
+                } });
+            return _value;
+        };
+    },
+    // $FlowFixMe - get/set properties not yet supported
+    get SUPPORT_FOREIGNOBJECT_DRAWING() {
+        'use strict';
+
+        var value = typeof Array.from === 'function' && typeof window.fetch === 'function' ? testForeignObject(document) : Promise.resolve(false);
+        Object.defineProperty(FEATURES, 'SUPPORT_FOREIGNOBJECT_DRAWING', { value: value });
+        return value;
+    },
+    // $FlowFixMe - get/set properties not yet supported
+    get SUPPORT_CORS_IMAGES() {
+        'use strict';
+
+        var value = testCORS();
+        Object.defineProperty(FEATURES, 'SUPPORT_CORS_IMAGES', { value: value });
+        return value;
+    },
+    // $FlowFixMe - get/set properties not yet supported
+    get SUPPORT_RESPONSE_TYPE() {
+        'use strict';
+
+        var value = testResponseType();
+        Object.defineProperty(FEATURES, 'SUPPORT_RESPONSE_TYPE', { value: value });
+        return value;
+    },
+    // $FlowFixMe - get/set properties not yet supported
+    get SUPPORT_CORS_XHR() {
+        'use strict';
+
+        var value = 'withCredentials' in new XMLHttpRequest();
+        Object.defineProperty(FEATURES, 'SUPPORT_CORS_XHR', { value: value });
+        return value;
+    }
+};
+
+exports.default = FEATURES;
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/Font.js b/AstuteClient2/src/assets/html2canvas/dist/npm/Font.js
new file mode 100644
index 0000000..71dd8a5
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/Font.js
@@ -0,0 +1,87 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.FontMetrics = undefined;
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Util = require('./Util');
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var SAMPLE_TEXT = 'Hidden Text';
+
+var FontMetrics = exports.FontMetrics = function () {
+    function FontMetrics(document) {
+        _classCallCheck(this, FontMetrics);
+
+        this._data = {};
+        this._document = document;
+    }
+
+    _createClass(FontMetrics, [{
+        key: '_parseMetrics',
+        value: function _parseMetrics(font) {
+            var container = this._document.createElement('div');
+            var img = this._document.createElement('img');
+            var span = this._document.createElement('span');
+
+            var body = this._document.body;
+            if (!body) {
+                throw new Error(process.env.NODE_ENV !== 'production' ? 'No document found for font metrics' : '');
+            }
+
+            container.style.visibility = 'hidden';
+            container.style.fontFamily = font.fontFamily;
+            container.style.fontSize = font.fontSize;
+            container.style.margin = '0';
+            container.style.padding = '0';
+
+            body.appendChild(container);
+
+            img.src = _Util.SMALL_IMAGE;
+            img.width = 1;
+            img.height = 1;
+
+            img.style.margin = '0';
+            img.style.padding = '0';
+            img.style.verticalAlign = 'baseline';
+
+            span.style.fontFamily = font.fontFamily;
+            span.style.fontSize = font.fontSize;
+            span.style.margin = '0';
+            span.style.padding = '0';
+
+            span.appendChild(this._document.createTextNode(SAMPLE_TEXT));
+            container.appendChild(span);
+            container.appendChild(img);
+            var baseline = img.offsetTop - span.offsetTop + 2;
+
+            container.removeChild(span);
+            container.appendChild(this._document.createTextNode(SAMPLE_TEXT));
+
+            container.style.lineHeight = 'normal';
+            img.style.verticalAlign = 'super';
+
+            var middle = img.offsetTop - container.offsetTop + 2;
+
+            body.removeChild(container);
+
+            return { baseline: baseline, middle: middle };
+        }
+    }, {
+        key: 'getMetrics',
+        value: function getMetrics(font) {
+            var key = font.fontFamily + ' ' + font.fontSize;
+            if (this._data[key] === undefined) {
+                this._data[key] = this._parseMetrics(font);
+            }
+
+            return this._data[key];
+        }
+    }]);
+
+    return FontMetrics;
+}();
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/Gradient.js b/AstuteClient2/src/assets/html2canvas/dist/npm/Gradient.js
new file mode 100644
index 0000000..7774da4
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/Gradient.js
@@ -0,0 +1,447 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.transformWebkitRadialGradientArgs = exports.parseGradient = exports.RadialGradient = exports.LinearGradient = exports.RADIAL_GRADIENT_SHAPE = exports.GRADIENT_TYPE = undefined;
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var _NodeContainer = require('./NodeContainer');
+
+var _NodeContainer2 = _interopRequireDefault(_NodeContainer);
+
+var _Angle = require('./Angle');
+
+var _Color = require('./Color');
+
+var _Color2 = _interopRequireDefault(_Color);
+
+var _Length = require('./Length');
+
+var _Length2 = _interopRequireDefault(_Length);
+
+var _Util = require('./Util');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var SIDE_OR_CORNER = /^(to )?(left|top|right|bottom)( (left|top|right|bottom))?$/i;
+var PERCENTAGE_ANGLES = /^([+-]?\d*\.?\d+)% ([+-]?\d*\.?\d+)%$/i;
+var ENDS_WITH_LENGTH = /(px)|%|( 0)$/i;
+var FROM_TO_COLORSTOP = /^(from|to|color-stop)\((?:([\d.]+)(%)?,\s*)?(.+?)\)$/i;
+var RADIAL_SHAPE_DEFINITION = /^\s*(circle|ellipse)?\s*((?:([\d.]+)(px|r?em|%)\s*(?:([\d.]+)(px|r?em|%))?)|closest-side|closest-corner|farthest-side|farthest-corner)?\s*(?:at\s*(?:(left|center|right)|([\d.]+)(px|r?em|%))\s+(?:(top|center|bottom)|([\d.]+)(px|r?em|%)))?(?:\s|$)/i;
+
+var GRADIENT_TYPE = exports.GRADIENT_TYPE = {
+    LINEAR_GRADIENT: 0,
+    RADIAL_GRADIENT: 1
+};
+
+var RADIAL_GRADIENT_SHAPE = exports.RADIAL_GRADIENT_SHAPE = {
+    CIRCLE: 0,
+    ELLIPSE: 1
+};
+
+var LENGTH_FOR_POSITION = {
+    left: new _Length2.default('0%'),
+    top: new _Length2.default('0%'),
+    center: new _Length2.default('50%'),
+    right: new _Length2.default('100%'),
+    bottom: new _Length2.default('100%')
+};
+
+var LinearGradient = exports.LinearGradient = function LinearGradient(colorStops, direction) {
+    _classCallCheck(this, LinearGradient);
+
+    this.type = GRADIENT_TYPE.LINEAR_GRADIENT;
+    this.colorStops = colorStops;
+    this.direction = direction;
+};
+
+var RadialGradient = exports.RadialGradient = function RadialGradient(colorStops, shape, center, radius) {
+    _classCallCheck(this, RadialGradient);
+
+    this.type = GRADIENT_TYPE.RADIAL_GRADIENT;
+    this.colorStops = colorStops;
+    this.shape = shape;
+    this.center = center;
+    this.radius = radius;
+};
+
+var parseGradient = exports.parseGradient = function parseGradient(container, _ref, bounds) {
+    var args = _ref.args,
+        method = _ref.method,
+        prefix = _ref.prefix;
+
+    if (method === 'linear-gradient') {
+        return parseLinearGradient(args, bounds, !!prefix);
+    } else if (method === 'gradient' && args[0] === 'linear') {
+        // TODO handle correct angle
+        return parseLinearGradient(['to bottom'].concat(transformObsoleteColorStops(args.slice(3))), bounds, !!prefix);
+    } else if (method === 'radial-gradient') {
+        return parseRadialGradient(container, prefix === '-webkit-' ? transformWebkitRadialGradientArgs(args) : args, bounds);
+    } else if (method === 'gradient' && args[0] === 'radial') {
+        return parseRadialGradient(container, transformObsoleteColorStops(transformWebkitRadialGradientArgs(args.slice(1))), bounds);
+    }
+};
+
+var parseColorStops = function parseColorStops(args, firstColorStopIndex, lineLength) {
+    var colorStops = [];
+
+    for (var i = firstColorStopIndex; i < args.length; i++) {
+        var value = args[i];
+        var HAS_LENGTH = ENDS_WITH_LENGTH.test(value);
+        var lastSpaceIndex = value.lastIndexOf(' ');
+        var _color = new _Color2.default(HAS_LENGTH ? value.substring(0, lastSpaceIndex) : value);
+        var _stop = HAS_LENGTH ? new _Length2.default(value.substring(lastSpaceIndex + 1)) : i === firstColorStopIndex ? new _Length2.default('0%') : i === args.length - 1 ? new _Length2.default('100%') : null;
+        colorStops.push({ color: _color, stop: _stop });
+    }
+
+    var absoluteValuedColorStops = colorStops.map(function (_ref2) {
+        var color = _ref2.color,
+            stop = _ref2.stop;
+
+        var absoluteStop = lineLength === 0 ? 0 : stop ? stop.getAbsoluteValue(lineLength) / lineLength : null;
+
+        return {
+            color: color,
+            // $FlowFixMe
+            stop: absoluteStop
+        };
+    });
+
+    var previousColorStop = absoluteValuedColorStops[0].stop;
+    for (var _i = 0; _i < absoluteValuedColorStops.length; _i++) {
+        if (previousColorStop !== null) {
+            var _stop2 = absoluteValuedColorStops[_i].stop;
+            if (_stop2 === null) {
+                var n = _i;
+                while (absoluteValuedColorStops[n].stop === null) {
+                    n++;
+                }
+                var steps = n - _i + 1;
+                var nextColorStep = absoluteValuedColorStops[n].stop;
+                var stepSize = (nextColorStep - previousColorStop) / steps;
+                for (; _i < n; _i++) {
+                    previousColorStop = absoluteValuedColorStops[_i].stop = previousColorStop + stepSize;
+                }
+            } else {
+                previousColorStop = _stop2;
+            }
+        }
+    }
+
+    return absoluteValuedColorStops;
+};
+
+var parseLinearGradient = function parseLinearGradient(args, bounds, hasPrefix) {
+    var angle = (0, _Angle.parseAngle)(args[0]);
+    var HAS_SIDE_OR_CORNER = SIDE_OR_CORNER.test(args[0]);
+    var HAS_DIRECTION = HAS_SIDE_OR_CORNER || angle !== null || PERCENTAGE_ANGLES.test(args[0]);
+    var direction = HAS_DIRECTION ? angle !== null ? calculateGradientDirection(
+    // if there is a prefix, the 0° angle points due East (instead of North per W3C)
+    hasPrefix ? angle - Math.PI * 0.5 : angle, bounds) : HAS_SIDE_OR_CORNER ? parseSideOrCorner(args[0], bounds) : parsePercentageAngle(args[0], bounds) : calculateGradientDirection(Math.PI, bounds);
+    var firstColorStopIndex = HAS_DIRECTION ? 1 : 0;
+
+    // TODO: Fix some inaccuracy with color stops with px values
+    var lineLength = Math.min((0, _Util.distance)(Math.abs(direction.x0) + Math.abs(direction.x1), Math.abs(direction.y0) + Math.abs(direction.y1)), bounds.width * 2, bounds.height * 2);
+
+    return new LinearGradient(parseColorStops(args, firstColorStopIndex, lineLength), direction);
+};
+
+var parseRadialGradient = function parseRadialGradient(container, args, bounds) {
+    var m = args[0].match(RADIAL_SHAPE_DEFINITION);
+    var shape = m && (m[1] === 'circle' || // explicit shape specification
+    m[3] !== undefined && m[5] === undefined) // only one radius coordinate
+    ? RADIAL_GRADIENT_SHAPE.CIRCLE : RADIAL_GRADIENT_SHAPE.ELLIPSE;
+    var radius = {};
+    var center = {};
+
+    if (m) {
+        // Radius
+        if (m[3] !== undefined) {
+            radius.x = (0, _Length.calculateLengthFromValueWithUnit)(container, m[3], m[4]).getAbsoluteValue(bounds.width);
+        }
+
+        if (m[5] !== undefined) {
+            radius.y = (0, _Length.calculateLengthFromValueWithUnit)(container, m[5], m[6]).getAbsoluteValue(bounds.height);
+        }
+
+        // Position
+        if (m[7]) {
+            center.x = LENGTH_FOR_POSITION[m[7].toLowerCase()];
+        } else if (m[8] !== undefined) {
+            center.x = (0, _Length.calculateLengthFromValueWithUnit)(container, m[8], m[9]);
+        }
+
+        if (m[10]) {
+            center.y = LENGTH_FOR_POSITION[m[10].toLowerCase()];
+        } else if (m[11] !== undefined) {
+            center.y = (0, _Length.calculateLengthFromValueWithUnit)(container, m[11], m[12]);
+        }
+    }
+
+    var gradientCenter = {
+        x: center.x === undefined ? bounds.width / 2 : center.x.getAbsoluteValue(bounds.width),
+        y: center.y === undefined ? bounds.height / 2 : center.y.getAbsoluteValue(bounds.height)
+    };
+    var gradientRadius = calculateRadius(m && m[2] || 'farthest-corner', shape, gradientCenter, radius, bounds);
+
+    return new RadialGradient(parseColorStops(args, m ? 1 : 0, Math.min(gradientRadius.x, gradientRadius.y)), shape, gradientCenter, gradientRadius);
+};
+
+var calculateGradientDirection = function calculateGradientDirection(radian, bounds) {
+    var width = bounds.width;
+    var height = bounds.height;
+    var HALF_WIDTH = width * 0.5;
+    var HALF_HEIGHT = height * 0.5;
+    var lineLength = Math.abs(width * Math.sin(radian)) + Math.abs(height * Math.cos(radian));
+    var HALF_LINE_LENGTH = lineLength / 2;
+
+    var x0 = HALF_WIDTH + Math.sin(radian) * HALF_LINE_LENGTH;
+    var y0 = HALF_HEIGHT - Math.cos(radian) * HALF_LINE_LENGTH;
+    var x1 = width - x0;
+    var y1 = height - y0;
+
+    return { x0: x0, x1: x1, y0: y0, y1: y1 };
+};
+
+var parseTopRight = function parseTopRight(bounds) {
+    return Math.acos(bounds.width / 2 / ((0, _Util.distance)(bounds.width, bounds.height) / 2));
+};
+
+var parseSideOrCorner = function parseSideOrCorner(side, bounds) {
+    switch (side) {
+        case 'bottom':
+        case 'to top':
+            return calculateGradientDirection(0, bounds);
+        case 'left':
+        case 'to right':
+            return calculateGradientDirection(Math.PI / 2, bounds);
+        case 'right':
+        case 'to left':
+            return calculateGradientDirection(3 * Math.PI / 2, bounds);
+        case 'top right':
+        case 'right top':
+        case 'to bottom left':
+        case 'to left bottom':
+            return calculateGradientDirection(Math.PI + parseTopRight(bounds), bounds);
+        case 'top left':
+        case 'left top':
+        case 'to bottom right':
+        case 'to right bottom':
+            return calculateGradientDirection(Math.PI - parseTopRight(bounds), bounds);
+        case 'bottom left':
+        case 'left bottom':
+        case 'to top right':
+        case 'to right top':
+            return calculateGradientDirection(parseTopRight(bounds), bounds);
+        case 'bottom right':
+        case 'right bottom':
+        case 'to top left':
+        case 'to left top':
+            return calculateGradientDirection(2 * Math.PI - parseTopRight(bounds), bounds);
+        case 'top':
+        case 'to bottom':
+        default:
+            return calculateGradientDirection(Math.PI, bounds);
+    }
+};
+
+var parsePercentageAngle = function parsePercentageAngle(angle, bounds) {
+    var _angle$split$map = angle.split(' ').map(parseFloat),
+        _angle$split$map2 = _slicedToArray(_angle$split$map, 2),
+        left = _angle$split$map2[0],
+        top = _angle$split$map2[1];
+
+    var ratio = left / 100 * bounds.width / (top / 100 * bounds.height);
+
+    return calculateGradientDirection(Math.atan(isNaN(ratio) ? 1 : ratio) + Math.PI / 2, bounds);
+};
+
+var findCorner = function findCorner(bounds, x, y, closest) {
+    var corners = [{ x: 0, y: 0 }, { x: 0, y: bounds.height }, { x: bounds.width, y: 0 }, { x: bounds.width, y: bounds.height }];
+
+    // $FlowFixMe
+    return corners.reduce(function (stat, corner) {
+        var d = (0, _Util.distance)(x - corner.x, y - corner.y);
+        if (closest ? d < stat.optimumDistance : d > stat.optimumDistance) {
+            return {
+                optimumCorner: corner,
+                optimumDistance: d
+            };
+        }
+
+        return stat;
+    }, {
+        optimumDistance: closest ? Infinity : -Infinity,
+        optimumCorner: null
+    }).optimumCorner;
+};
+
+var calculateRadius = function calculateRadius(extent, shape, center, radius, bounds) {
+    var x = center.x;
+    var y = center.y;
+    var rx = 0;
+    var ry = 0;
+
+    switch (extent) {
+        case 'closest-side':
+            // The ending shape is sized so that that it exactly meets the side of the gradient box closest to the gradient’s center.
+            // If the shape is an ellipse, it exactly meets the closest side in each dimension.
+            if (shape === RADIAL_GRADIENT_SHAPE.CIRCLE) {
+                rx = ry = Math.min(Math.abs(x), Math.abs(x - bounds.width), Math.abs(y), Math.abs(y - bounds.height));
+            } else if (shape === RADIAL_GRADIENT_SHAPE.ELLIPSE) {
+                rx = Math.min(Math.abs(x), Math.abs(x - bounds.width));
+                ry = Math.min(Math.abs(y), Math.abs(y - bounds.height));
+            }
+            break;
+
+        case 'closest-corner':
+            // The ending shape is sized so that that it passes through the corner of the gradient box closest to the gradient’s center.
+            // If the shape is an ellipse, the ending shape is given the same aspect-ratio it would have if closest-side were specified.
+            if (shape === RADIAL_GRADIENT_SHAPE.CIRCLE) {
+                rx = ry = Math.min((0, _Util.distance)(x, y), (0, _Util.distance)(x, y - bounds.height), (0, _Util.distance)(x - bounds.width, y), (0, _Util.distance)(x - bounds.width, y - bounds.height));
+            } else if (shape === RADIAL_GRADIENT_SHAPE.ELLIPSE) {
+                // Compute the ratio ry/rx (which is to be the same as for "closest-side")
+                var c = Math.min(Math.abs(y), Math.abs(y - bounds.height)) / Math.min(Math.abs(x), Math.abs(x - bounds.width));
+                var corner = findCorner(bounds, x, y, true);
+                rx = (0, _Util.distance)(corner.x - x, (corner.y - y) / c);
+                ry = c * rx;
+            }
+            break;
+
+        case 'farthest-side':
+            // Same as closest-side, except the ending shape is sized based on the farthest side(s)
+            if (shape === RADIAL_GRADIENT_SHAPE.CIRCLE) {
+                rx = ry = Math.max(Math.abs(x), Math.abs(x - bounds.width), Math.abs(y), Math.abs(y - bounds.height));
+            } else if (shape === RADIAL_GRADIENT_SHAPE.ELLIPSE) {
+                rx = Math.max(Math.abs(x), Math.abs(x - bounds.width));
+                ry = Math.max(Math.abs(y), Math.abs(y - bounds.height));
+            }
+            break;
+
+        case 'farthest-corner':
+            // Same as closest-corner, except the ending shape is sized based on the farthest corner.
+            // If the shape is an ellipse, the ending shape is given the same aspect ratio it would have if farthest-side were specified.
+            if (shape === RADIAL_GRADIENT_SHAPE.CIRCLE) {
+                rx = ry = Math.max((0, _Util.distance)(x, y), (0, _Util.distance)(x, y - bounds.height), (0, _Util.distance)(x - bounds.width, y), (0, _Util.distance)(x - bounds.width, y - bounds.height));
+            } else if (shape === RADIAL_GRADIENT_SHAPE.ELLIPSE) {
+                // Compute the ratio ry/rx (which is to be the same as for "farthest-side")
+                var _c = Math.max(Math.abs(y), Math.abs(y - bounds.height)) / Math.max(Math.abs(x), Math.abs(x - bounds.width));
+                var _corner = findCorner(bounds, x, y, false);
+                rx = (0, _Util.distance)(_corner.x - x, (_corner.y - y) / _c);
+                ry = _c * rx;
+            }
+            break;
+
+        default:
+            // pixel or percentage values
+            rx = radius.x || 0;
+            ry = radius.y !== undefined ? radius.y : rx;
+            break;
+    }
+
+    return {
+        x: rx,
+        y: ry
+    };
+};
+
+var transformWebkitRadialGradientArgs = exports.transformWebkitRadialGradientArgs = function transformWebkitRadialGradientArgs(args) {
+    var shape = '';
+    var radius = '';
+    var extent = '';
+    var position = '';
+    var idx = 0;
+
+    var POSITION = /^(left|center|right|\d+(?:px|r?em|%)?)(?:\s+(top|center|bottom|\d+(?:px|r?em|%)?))?$/i;
+    var SHAPE_AND_EXTENT = /^(circle|ellipse)?\s*(closest-side|closest-corner|farthest-side|farthest-corner|contain|cover)?$/i;
+    var RADIUS = /^\d+(px|r?em|%)?(?:\s+\d+(px|r?em|%)?)?$/i;
+
+    var matchStartPosition = args[idx].match(POSITION);
+    if (matchStartPosition) {
+        idx++;
+    }
+
+    var matchShapeExtent = args[idx].match(SHAPE_AND_EXTENT);
+    if (matchShapeExtent) {
+        shape = matchShapeExtent[1] || '';
+        extent = matchShapeExtent[2] || '';
+        if (extent === 'contain') {
+            extent = 'closest-side';
+        } else if (extent === 'cover') {
+            extent = 'farthest-corner';
+        }
+        idx++;
+    }
+
+    var matchStartRadius = args[idx].match(RADIUS);
+    if (matchStartRadius) {
+        idx++;
+    }
+
+    var matchEndPosition = args[idx].match(POSITION);
+    if (matchEndPosition) {
+        idx++;
+    }
+
+    var matchEndRadius = args[idx].match(RADIUS);
+    if (matchEndRadius) {
+        idx++;
+    }
+
+    var matchPosition = matchEndPosition || matchStartPosition;
+    if (matchPosition && matchPosition[1]) {
+        position = matchPosition[1] + (/^\d+$/.test(matchPosition[1]) ? 'px' : '');
+        if (matchPosition[2]) {
+            position += ' ' + matchPosition[2] + (/^\d+$/.test(matchPosition[2]) ? 'px' : '');
+        }
+    }
+
+    var matchRadius = matchEndRadius || matchStartRadius;
+    if (matchRadius) {
+        radius = matchRadius[0];
+        if (!matchRadius[1]) {
+            radius += 'px';
+        }
+    }
+
+    if (position && !shape && !radius && !extent) {
+        radius = position;
+        position = '';
+    }
+
+    if (position) {
+        position = 'at ' + position;
+    }
+
+    return [[shape, extent, radius, position].filter(function (s) {
+        return !!s;
+    }).join(' ')].concat(args.slice(idx));
+};
+
+var transformObsoleteColorStops = function transformObsoleteColorStops(args) {
+    return args.map(function (color) {
+        return color.match(FROM_TO_COLORSTOP);
+    })
+    // $FlowFixMe
+    .map(function (v, index) {
+        if (!v) {
+            return args[index];
+        }
+
+        switch (v[1]) {
+            case 'from':
+                return v[4] + ' 0%';
+            case 'to':
+                return v[4] + ' 100%';
+            case 'color-stop':
+                if (v[3] === '%') {
+                    return v[4] + ' ' + v[2];
+                }
+                return v[4] + ' ' + parseFloat(v[2]) * 100 + '%';
+        }
+    });
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/Input.js b/AstuteClient2/src/assets/html2canvas/dist/npm/Input.js
new file mode 100644
index 0000000..1250aa5
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/Input.js
@@ -0,0 +1,122 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.reformatInputBounds = exports.inlineSelectElement = exports.inlineTextAreaElement = exports.inlineInputElement = exports.getInputBorderRadius = exports.INPUT_BACKGROUND = exports.INPUT_BORDERS = exports.INPUT_COLOR = undefined;
+
+var _TextContainer = require('./TextContainer');
+
+var _TextContainer2 = _interopRequireDefault(_TextContainer);
+
+var _background = require('./parsing/background');
+
+var _border = require('./parsing/border');
+
+var _Circle = require('./drawing/Circle');
+
+var _Circle2 = _interopRequireDefault(_Circle);
+
+var _Vector = require('./drawing/Vector');
+
+var _Vector2 = _interopRequireDefault(_Vector);
+
+var _Color = require('./Color');
+
+var _Color2 = _interopRequireDefault(_Color);
+
+var _Length = require('./Length');
+
+var _Length2 = _interopRequireDefault(_Length);
+
+var _Bounds = require('./Bounds');
+
+var _TextBounds = require('./TextBounds');
+
+var _Util = require('./Util');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var INPUT_COLOR = exports.INPUT_COLOR = new _Color2.default([42, 42, 42]);
+var INPUT_BORDER_COLOR = new _Color2.default([165, 165, 165]);
+var INPUT_BACKGROUND_COLOR = new _Color2.default([222, 222, 222]);
+var INPUT_BORDER = {
+    borderWidth: 1,
+    borderColor: INPUT_BORDER_COLOR,
+    borderStyle: _border.BORDER_STYLE.SOLID
+};
+var INPUT_BORDERS = exports.INPUT_BORDERS = [INPUT_BORDER, INPUT_BORDER, INPUT_BORDER, INPUT_BORDER];
+var INPUT_BACKGROUND = exports.INPUT_BACKGROUND = {
+    backgroundColor: INPUT_BACKGROUND_COLOR,
+    backgroundImage: [],
+    backgroundClip: _background.BACKGROUND_CLIP.PADDING_BOX,
+    backgroundOrigin: _background.BACKGROUND_ORIGIN.PADDING_BOX
+};
+
+var RADIO_BORDER_RADIUS = new _Length2.default('50%');
+var RADIO_BORDER_RADIUS_TUPLE = [RADIO_BORDER_RADIUS, RADIO_BORDER_RADIUS];
+var INPUT_RADIO_BORDER_RADIUS = [RADIO_BORDER_RADIUS_TUPLE, RADIO_BORDER_RADIUS_TUPLE, RADIO_BORDER_RADIUS_TUPLE, RADIO_BORDER_RADIUS_TUPLE];
+
+var CHECKBOX_BORDER_RADIUS = new _Length2.default('3px');
+var CHECKBOX_BORDER_RADIUS_TUPLE = [CHECKBOX_BORDER_RADIUS, CHECKBOX_BORDER_RADIUS];
+var INPUT_CHECKBOX_BORDER_RADIUS = [CHECKBOX_BORDER_RADIUS_TUPLE, CHECKBOX_BORDER_RADIUS_TUPLE, CHECKBOX_BORDER_RADIUS_TUPLE, CHECKBOX_BORDER_RADIUS_TUPLE];
+
+var getInputBorderRadius = exports.getInputBorderRadius = function getInputBorderRadius(node) {
+    return node.type === 'radio' ? INPUT_RADIO_BORDER_RADIUS : INPUT_CHECKBOX_BORDER_RADIUS;
+};
+
+var inlineInputElement = exports.inlineInputElement = function inlineInputElement(node, container) {
+    if (node.type === 'radio' || node.type === 'checkbox') {
+        if (node.checked) {
+            var size = Math.min(container.bounds.width, container.bounds.height);
+            container.childNodes.push(node.type === 'checkbox' ? [new _Vector2.default(container.bounds.left + size * 0.39363, container.bounds.top + size * 0.79), new _Vector2.default(container.bounds.left + size * 0.16, container.bounds.top + size * 0.5549), new _Vector2.default(container.bounds.left + size * 0.27347, container.bounds.top + size * 0.44071), new _Vector2.default(container.bounds.left + size * 0.39694, container.bounds.top + size * 0.5649), new _Vector2.default(container.bounds.left + size * 0.72983, container.bounds.top + size * 0.23), new _Vector2.default(container.bounds.left + size * 0.84, container.bounds.top + size * 0.34085), new _Vector2.default(container.bounds.left + size * 0.39363, container.bounds.top + size * 0.79)] : new _Circle2.default(container.bounds.left + size / 4, container.bounds.top + size / 4, size / 4));
+        }
+    } else {
+        inlineFormElement(getInputValue(node), node, container, false);
+    }
+};
+
+var inlineTextAreaElement = exports.inlineTextAreaElement = function inlineTextAreaElement(node, container) {
+    inlineFormElement(node.value, node, container, true);
+};
+
+var inlineSelectElement = exports.inlineSelectElement = function inlineSelectElement(node, container) {
+    var option = node.options[node.selectedIndex || 0];
+    inlineFormElement(option ? option.text || '' : '', node, container, false);
+};
+
+var reformatInputBounds = exports.reformatInputBounds = function reformatInputBounds(bounds) {
+    if (bounds.width > bounds.height) {
+        bounds.left += (bounds.width - bounds.height) / 2;
+        bounds.width = bounds.height;
+    } else if (bounds.width < bounds.height) {
+        bounds.top += (bounds.height - bounds.width) / 2;
+        bounds.height = bounds.width;
+    }
+    return bounds;
+};
+
+var inlineFormElement = function inlineFormElement(value, node, container, allowLinebreak) {
+    var body = node.ownerDocument.body;
+    if (value.length > 0 && body) {
+        var wrapper = node.ownerDocument.createElement('html2canvaswrapper');
+        (0, _Util.copyCSSStyles)(node.ownerDocument.defaultView.getComputedStyle(node, null), wrapper);
+        wrapper.style.position = 'absolute';
+        wrapper.style.left = container.bounds.left + 'px';
+        wrapper.style.top = container.bounds.top + 'px';
+        if (!allowLinebreak) {
+            wrapper.style.whiteSpace = 'nowrap';
+        }
+        var text = node.ownerDocument.createTextNode(value);
+        wrapper.appendChild(text);
+        body.appendChild(wrapper);
+        container.childNodes.push(_TextContainer2.default.fromTextNode(text, container));
+        body.removeChild(wrapper);
+    }
+};
+
+var getInputValue = function getInputValue(node) {
+    var value = node.type === 'password' ? new Array(node.value.length + 1).join('\u2022') : node.value;
+
+    return value.length === 0 ? node.placeholder || '' : value;
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/Length.js b/AstuteClient2/src/assets/html2canvas/dist/npm/Length.js
new file mode 100644
index 0000000..08542d4
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/Length.js
@@ -0,0 +1,79 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.calculateLengthFromValueWithUnit = exports.LENGTH_TYPE = undefined;
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _NodeContainer = require('./NodeContainer');
+
+var _NodeContainer2 = _interopRequireDefault(_NodeContainer);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var LENGTH_WITH_UNIT = /([\d.]+)(px|r?em|%)/i;
+
+var LENGTH_TYPE = exports.LENGTH_TYPE = {
+    PX: 0,
+    PERCENTAGE: 1
+};
+
+var Length = function () {
+    function Length(value) {
+        _classCallCheck(this, Length);
+
+        this.type = value.substr(value.length - 1) === '%' ? LENGTH_TYPE.PERCENTAGE : LENGTH_TYPE.PX;
+        var parsedValue = parseFloat(value);
+        if (process.env.NODE_ENV !== 'production' && isNaN(parsedValue)) {
+            console.error('Invalid value given for Length: "' + value + '"');
+        }
+        this.value = isNaN(parsedValue) ? 0 : parsedValue;
+    }
+
+    _createClass(Length, [{
+        key: 'isPercentage',
+        value: function isPercentage() {
+            return this.type === LENGTH_TYPE.PERCENTAGE;
+        }
+    }, {
+        key: 'getAbsoluteValue',
+        value: function getAbsoluteValue(parentLength) {
+            return this.isPercentage() ? parentLength * (this.value / 100) : this.value;
+        }
+    }], [{
+        key: 'create',
+        value: function create(v) {
+            return new Length(v);
+        }
+    }]);
+
+    return Length;
+}();
+
+exports.default = Length;
+
+
+var getRootFontSize = function getRootFontSize(container) {
+    var parent = container.parent;
+    return parent ? getRootFontSize(parent) : parseFloat(container.style.font.fontSize);
+};
+
+var calculateLengthFromValueWithUnit = exports.calculateLengthFromValueWithUnit = function calculateLengthFromValueWithUnit(container, value, unit) {
+    switch (unit) {
+        case 'px':
+        case '%':
+            return new Length(value + unit);
+        case 'em':
+        case 'rem':
+            var length = new Length(value);
+            length.value *= unit === 'em' ? parseFloat(container.style.font.fontSize) : getRootFontSize(container);
+            return length;
+        default:
+            // TODO: handle correctly if unknown unit is used
+            return new Length('0');
+    }
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/ListItem.js b/AstuteClient2/src/assets/html2canvas/dist/npm/ListItem.js
new file mode 100644
index 0000000..edcd8f7
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/ListItem.js
@@ -0,0 +1,317 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.createCounterText = exports.inlineListItemElement = exports.getListOwner = undefined;
+
+var _Util = require('./Util');
+
+var _NodeContainer = require('./NodeContainer');
+
+var _NodeContainer2 = _interopRequireDefault(_NodeContainer);
+
+var _TextContainer = require('./TextContainer');
+
+var _TextContainer2 = _interopRequireDefault(_TextContainer);
+
+var _listStyle = require('./parsing/listStyle');
+
+var _Unicode = require('./Unicode');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+// Margin between the enumeration and the list item content
+var MARGIN_RIGHT = 7;
+
+var ancestorTypes = ['OL', 'UL', 'MENU'];
+
+var getListOwner = exports.getListOwner = function getListOwner(container) {
+    var parent = container.parent;
+    if (!parent) {
+        return null;
+    }
+
+    do {
+        var isAncestor = ancestorTypes.indexOf(parent.tagName) !== -1;
+        if (isAncestor) {
+            return parent;
+        }
+        parent = parent.parent;
+    } while (parent);
+
+    return container.parent;
+};
+
+var inlineListItemElement = exports.inlineListItemElement = function inlineListItemElement(node, container, resourceLoader) {
+    var listStyle = container.style.listStyle;
+
+    if (!listStyle) {
+        return;
+    }
+
+    var style = node.ownerDocument.defaultView.getComputedStyle(node, null);
+    var wrapper = node.ownerDocument.createElement('html2canvaswrapper');
+    (0, _Util.copyCSSStyles)(style, wrapper);
+
+    wrapper.style.position = 'absolute';
+    wrapper.style.bottom = 'auto';
+    wrapper.style.display = 'block';
+    wrapper.style.letterSpacing = 'normal';
+
+    switch (listStyle.listStylePosition) {
+        case _listStyle.LIST_STYLE_POSITION.OUTSIDE:
+            wrapper.style.left = 'auto';
+            wrapper.style.right = node.ownerDocument.defaultView.innerWidth - container.bounds.left - container.style.margin[1].getAbsoluteValue(container.bounds.width) + MARGIN_RIGHT + 'px';
+            wrapper.style.textAlign = 'right';
+            break;
+        case _listStyle.LIST_STYLE_POSITION.INSIDE:
+            wrapper.style.left = container.bounds.left - container.style.margin[3].getAbsoluteValue(container.bounds.width) + 'px';
+            wrapper.style.right = 'auto';
+            wrapper.style.textAlign = 'left';
+            break;
+    }
+
+    var text = void 0;
+    var MARGIN_TOP = container.style.margin[0].getAbsoluteValue(container.bounds.width);
+    var styleImage = listStyle.listStyleImage;
+    if (styleImage) {
+        if (styleImage.method === 'url') {
+            var image = node.ownerDocument.createElement('img');
+            image.src = styleImage.args[0];
+            wrapper.style.top = container.bounds.top - MARGIN_TOP + 'px';
+            wrapper.style.width = 'auto';
+            wrapper.style.height = 'auto';
+            wrapper.appendChild(image);
+        } else {
+            var size = parseFloat(container.style.font.fontSize) * 0.5;
+            wrapper.style.top = container.bounds.top - MARGIN_TOP + container.bounds.height - 1.5 * size + 'px';
+            wrapper.style.width = size + 'px';
+            wrapper.style.height = size + 'px';
+            wrapper.style.backgroundImage = style.listStyleImage;
+        }
+    } else if (typeof container.listIndex === 'number') {
+        text = node.ownerDocument.createTextNode(createCounterText(container.listIndex, listStyle.listStyleType, true));
+        wrapper.appendChild(text);
+        wrapper.style.top = container.bounds.top - MARGIN_TOP + 'px';
+    }
+
+    // $FlowFixMe
+    var body = node.ownerDocument.body;
+    body.appendChild(wrapper);
+
+    if (text) {
+        container.childNodes.push(_TextContainer2.default.fromTextNode(text, container));
+        body.removeChild(wrapper);
+    } else {
+        // $FlowFixMe
+        container.childNodes.push(new _NodeContainer2.default(wrapper, container, resourceLoader, 0));
+    }
+};
+
+var ROMAN_UPPER = {
+    integers: [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1],
+    values: ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']
+};
+
+var ARMENIAN = {
+    integers: [9000, 8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
+    values: ['Ք', 'Փ', 'Ւ', 'Ց', 'Ր', 'Տ', 'Վ', 'Ս', 'Ռ', 'Ջ', 'Պ', 'Չ', 'Ո', 'Շ', 'Ն', 'Յ', 'Մ', 'Ճ', 'Ղ', 'Ձ', 'Հ', 'Կ', 'Ծ', 'Խ', 'Լ', 'Ի', 'Ժ', 'Թ', 'Ը', 'Է', 'Զ', 'Ե', 'Դ', 'Գ', 'Բ', 'Ա']
+};
+
+var HEBREW = {
+    integers: [10000, 9000, 8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000, 400, 300, 200, 100, 90, 80, 70, 60, 50, 40, 30, 20, 19, 18, 17, 16, 15, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
+    values: ['י׳', 'ט׳', 'ח׳', 'ז׳', 'ו׳', 'ה׳', 'ד׳', 'ג׳', 'ב׳', 'א׳', 'ת', 'ש', 'ר', 'ק', 'צ', 'פ', 'ע', 'ס', 'נ', 'מ', 'ל', 'כ', 'יט', 'יח', 'יז', 'טז', 'טו', 'י', 'ט', 'ח', 'ז', 'ו', 'ה', 'ד', 'ג', 'ב', 'א']
+};
+
+var GEORGIAN = {
+    integers: [10000, 9000, 8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
+    values: ['ჵ', 'ჰ', 'ჯ', 'ჴ', 'ხ', 'ჭ', 'წ', 'ძ', 'ც', 'ჩ', 'შ', 'ყ', 'ღ', 'ქ', 'ფ', 'ჳ', 'ტ', 'ს', 'რ', 'ჟ', 'პ', 'ო', 'ჲ', 'ნ', 'მ', 'ლ', 'კ', 'ი', 'თ', 'ჱ', 'ზ', 'ვ', 'ე', 'დ', 'გ', 'ბ', 'ა']
+};
+
+var createAdditiveCounter = function createAdditiveCounter(value, min, max, symbols, fallback, suffix) {
+    if (value < min || value > max) {
+        return createCounterText(value, fallback, suffix.length > 0);
+    }
+
+    return symbols.integers.reduce(function (string, integer, index) {
+        while (value >= integer) {
+            value -= integer;
+            string += symbols.values[index];
+        }
+        return string;
+    }, '') + suffix;
+};
+
+var createCounterStyleWithSymbolResolver = function createCounterStyleWithSymbolResolver(value, codePointRangeLength, isNumeric, resolver) {
+    var string = '';
+
+    do {
+        if (!isNumeric) {
+            value--;
+        }
+        string = resolver(value) + string;
+        value /= codePointRangeLength;
+    } while (value * codePointRangeLength >= codePointRangeLength);
+
+    return string;
+};
+
+var createCounterStyleFromRange = function createCounterStyleFromRange(value, codePointRangeStart, codePointRangeEnd, isNumeric, suffix) {
+    var codePointRangeLength = codePointRangeEnd - codePointRangeStart + 1;
+
+    return (value < 0 ? '-' : '') + (createCounterStyleWithSymbolResolver(Math.abs(value), codePointRangeLength, isNumeric, function (codePoint) {
+        return (0, _Unicode.fromCodePoint)(Math.floor(codePoint % codePointRangeLength) + codePointRangeStart);
+    }) + suffix);
+};
+
+var createCounterStyleFromSymbols = function createCounterStyleFromSymbols(value, symbols) {
+    var suffix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '. ';
+
+    var codePointRangeLength = symbols.length;
+    return createCounterStyleWithSymbolResolver(Math.abs(value), codePointRangeLength, false, function (codePoint) {
+        return symbols[Math.floor(codePoint % codePointRangeLength)];
+    }) + suffix;
+};
+
+var CJK_ZEROS = 1 << 0;
+var CJK_TEN_COEFFICIENTS = 1 << 1;
+var CJK_TEN_HIGH_COEFFICIENTS = 1 << 2;
+var CJK_HUNDRED_COEFFICIENTS = 1 << 3;
+
+var createCJKCounter = function createCJKCounter(value, numbers, multipliers, negativeSign, suffix, flags) {
+    if (value < -9999 || value > 9999) {
+        return createCounterText(value, _listStyle.LIST_STYLE_TYPE.CJK_DECIMAL, suffix.length > 0);
+    }
+    var tmp = Math.abs(value);
+    var string = suffix;
+
+    if (tmp === 0) {
+        return numbers[0] + string;
+    }
+
+    for (var digit = 0; tmp > 0 && digit <= 4; digit++) {
+        var coefficient = tmp % 10;
+
+        if (coefficient === 0 && (0, _Util.contains)(flags, CJK_ZEROS) && string !== '') {
+            string = numbers[coefficient] + string;
+        } else if (coefficient > 1 || coefficient === 1 && digit === 0 || coefficient === 1 && digit === 1 && (0, _Util.contains)(flags, CJK_TEN_COEFFICIENTS) || coefficient === 1 && digit === 1 && (0, _Util.contains)(flags, CJK_TEN_HIGH_COEFFICIENTS) && value > 100 || coefficient === 1 && digit > 1 && (0, _Util.contains)(flags, CJK_HUNDRED_COEFFICIENTS)) {
+            string = numbers[coefficient] + (digit > 0 ? multipliers[digit - 1] : '') + string;
+        } else if (coefficient === 1 && digit > 0) {
+            string = multipliers[digit - 1] + string;
+        }
+        tmp = Math.floor(tmp / 10);
+    }
+
+    return (value < 0 ? negativeSign : '') + string;
+};
+
+var CHINESE_INFORMAL_MULTIPLIERS = '十百千萬';
+var CHINESE_FORMAL_MULTIPLIERS = '拾佰仟萬';
+var JAPANESE_NEGATIVE = 'マイナス';
+var KOREAN_NEGATIVE = '마이너스 ';
+
+var createCounterText = exports.createCounterText = function createCounterText(value, type, appendSuffix) {
+    var defaultSuffix = appendSuffix ? '. ' : '';
+    var cjkSuffix = appendSuffix ? '、' : '';
+    var koreanSuffix = appendSuffix ? ', ' : '';
+    switch (type) {
+        case _listStyle.LIST_STYLE_TYPE.DISC:
+            return '•';
+        case _listStyle.LIST_STYLE_TYPE.CIRCLE:
+            return '◦';
+        case _listStyle.LIST_STYLE_TYPE.SQUARE:
+            return '◾';
+        case _listStyle.LIST_STYLE_TYPE.DECIMAL_LEADING_ZERO:
+            var string = createCounterStyleFromRange(value, 48, 57, true, defaultSuffix);
+            return string.length < 4 ? '0' + string : string;
+        case _listStyle.LIST_STYLE_TYPE.CJK_DECIMAL:
+            return createCounterStyleFromSymbols(value, '〇一二三四五六七八九', cjkSuffix);
+        case _listStyle.LIST_STYLE_TYPE.LOWER_ROMAN:
+            return createAdditiveCounter(value, 1, 3999, ROMAN_UPPER, _listStyle.LIST_STYLE_TYPE.DECIMAL, defaultSuffix).toLowerCase();
+        case _listStyle.LIST_STYLE_TYPE.UPPER_ROMAN:
+            return createAdditiveCounter(value, 1, 3999, ROMAN_UPPER, _listStyle.LIST_STYLE_TYPE.DECIMAL, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.LOWER_GREEK:
+            return createCounterStyleFromRange(value, 945, 969, false, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.LOWER_ALPHA:
+            return createCounterStyleFromRange(value, 97, 122, false, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.UPPER_ALPHA:
+            return createCounterStyleFromRange(value, 65, 90, false, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.ARABIC_INDIC:
+            return createCounterStyleFromRange(value, 1632, 1641, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.ARMENIAN:
+        case _listStyle.LIST_STYLE_TYPE.UPPER_ARMENIAN:
+            return createAdditiveCounter(value, 1, 9999, ARMENIAN, _listStyle.LIST_STYLE_TYPE.DECIMAL, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.LOWER_ARMENIAN:
+            return createAdditiveCounter(value, 1, 9999, ARMENIAN, _listStyle.LIST_STYLE_TYPE.DECIMAL, defaultSuffix).toLowerCase();
+        case _listStyle.LIST_STYLE_TYPE.BENGALI:
+            return createCounterStyleFromRange(value, 2534, 2543, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.CAMBODIAN:
+        case _listStyle.LIST_STYLE_TYPE.KHMER:
+            return createCounterStyleFromRange(value, 6112, 6121, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.CJK_EARTHLY_BRANCH:
+            return createCounterStyleFromSymbols(value, '子丑寅卯辰巳午未申酉戌亥', cjkSuffix);
+        case _listStyle.LIST_STYLE_TYPE.CJK_HEAVENLY_STEM:
+            return createCounterStyleFromSymbols(value, '甲乙丙丁戊己庚辛壬癸', cjkSuffix);
+        case _listStyle.LIST_STYLE_TYPE.CJK_IDEOGRAPHIC:
+        case _listStyle.LIST_STYLE_TYPE.TRAD_CHINESE_INFORMAL:
+            return createCJKCounter(value, '零一二三四五六七八九', CHINESE_INFORMAL_MULTIPLIERS, '負', cjkSuffix, CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS | CJK_HUNDRED_COEFFICIENTS);
+        case _listStyle.LIST_STYLE_TYPE.TRAD_CHINESE_FORMAL:
+            return createCJKCounter(value, '零壹貳參肆伍陸柒捌玖', CHINESE_FORMAL_MULTIPLIERS, '負', cjkSuffix, CJK_ZEROS | CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS | CJK_HUNDRED_COEFFICIENTS);
+        case _listStyle.LIST_STYLE_TYPE.SIMP_CHINESE_INFORMAL:
+            return createCJKCounter(value, '零一二三四五六七八九', CHINESE_INFORMAL_MULTIPLIERS, '负', cjkSuffix, CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS | CJK_HUNDRED_COEFFICIENTS);
+        case _listStyle.LIST_STYLE_TYPE.SIMP_CHINESE_FORMAL:
+            return createCJKCounter(value, '零壹贰叁肆伍陆柒捌玖', CHINESE_FORMAL_MULTIPLIERS, '负', cjkSuffix, CJK_ZEROS | CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS | CJK_HUNDRED_COEFFICIENTS);
+        case _listStyle.LIST_STYLE_TYPE.JAPANESE_INFORMAL:
+            return createCJKCounter(value, '〇一二三四五六七八九', '十百千万', JAPANESE_NEGATIVE, cjkSuffix, 0);
+        case _listStyle.LIST_STYLE_TYPE.JAPANESE_FORMAL:
+            return createCJKCounter(value, '零壱弐参四伍六七八九', '拾百千万', JAPANESE_NEGATIVE, cjkSuffix, CJK_ZEROS | CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS);
+        case _listStyle.LIST_STYLE_TYPE.KOREAN_HANGUL_FORMAL:
+            return createCJKCounter(value, '영일이삼사오육칠팔구', '십백천만', KOREAN_NEGATIVE, koreanSuffix, CJK_ZEROS | CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS);
+        case _listStyle.LIST_STYLE_TYPE.KOREAN_HANJA_INFORMAL:
+            return createCJKCounter(value, '零一二三四五六七八九', '十百千萬', KOREAN_NEGATIVE, koreanSuffix, 0);
+        case _listStyle.LIST_STYLE_TYPE.KOREAN_HANJA_FORMAL:
+            return createCJKCounter(value, '零壹貳參四五六七八九', '拾百千', KOREAN_NEGATIVE, koreanSuffix, CJK_ZEROS | CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS);
+        case _listStyle.LIST_STYLE_TYPE.DEVANAGARI:
+            return createCounterStyleFromRange(value, 0x966, 0x96f, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.GEORGIAN:
+            return createAdditiveCounter(value, 1, 19999, GEORGIAN, _listStyle.LIST_STYLE_TYPE.DECIMAL, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.GUJARATI:
+            return createCounterStyleFromRange(value, 0xae6, 0xaef, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.GURMUKHI:
+            return createCounterStyleFromRange(value, 0xa66, 0xa6f, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.HEBREW:
+            return createAdditiveCounter(value, 1, 10999, HEBREW, _listStyle.LIST_STYLE_TYPE.DECIMAL, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.HIRAGANA:
+            return createCounterStyleFromSymbols(value, 'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわゐゑをん');
+        case _listStyle.LIST_STYLE_TYPE.HIRAGANA_IROHA:
+            return createCounterStyleFromSymbols(value, 'いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす');
+        case _listStyle.LIST_STYLE_TYPE.KANNADA:
+            return createCounterStyleFromRange(value, 0xce6, 0xcef, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.KATAKANA:
+            return createCounterStyleFromSymbols(value, 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヰヱヲン', cjkSuffix);
+        case _listStyle.LIST_STYLE_TYPE.KATAKANA_IROHA:
+            return createCounterStyleFromSymbols(value, 'イロハニホヘトチリヌルヲワカヨタレソツネナラムウヰノオクヤマケフコエテアサキユメミシヱヒモセス', cjkSuffix);
+        case _listStyle.LIST_STYLE_TYPE.LAO:
+            return createCounterStyleFromRange(value, 0xed0, 0xed9, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.MONGOLIAN:
+            return createCounterStyleFromRange(value, 0x1810, 0x1819, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.MYANMAR:
+            return createCounterStyleFromRange(value, 0x1040, 0x1049, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.ORIYA:
+            return createCounterStyleFromRange(value, 0xb66, 0xb6f, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.PERSIAN:
+            return createCounterStyleFromRange(value, 0x6f0, 0x6f9, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.TAMIL:
+            return createCounterStyleFromRange(value, 0xbe6, 0xbef, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.TELUGU:
+            return createCounterStyleFromRange(value, 0xc66, 0xc6f, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.THAI:
+            return createCounterStyleFromRange(value, 0xe50, 0xe59, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.TIBETAN:
+            return createCounterStyleFromRange(value, 0xf20, 0xf29, true, defaultSuffix);
+        case _listStyle.LIST_STYLE_TYPE.DECIMAL:
+        default:
+            return createCounterStyleFromRange(value, 48, 57, true, defaultSuffix);
+    }
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/Logger.js b/AstuteClient2/src/assets/html2canvas/dist/npm/Logger.js
new file mode 100644
index 0000000..8f7984c
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/Logger.js
@@ -0,0 +1,58 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Logger = function () {
+    function Logger(enabled, id, start) {
+        _classCallCheck(this, Logger);
+
+        this.enabled = typeof window !== 'undefined' && enabled;
+        this.start = start ? start : Date.now();
+        this.id = id;
+    }
+
+    _createClass(Logger, [{
+        key: 'child',
+        value: function child(id) {
+            return new Logger(this.enabled, id, this.start);
+        }
+
+        // eslint-disable-next-line flowtype/no-weak-types
+
+    }, {
+        key: 'log',
+        value: function log() {
+            if (this.enabled && window.console && window.console.log) {
+                for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+                    args[_key] = arguments[_key];
+                }
+
+                Function.prototype.bind.call(window.console.log, window.console).apply(window.console, [Date.now() - this.start + 'ms', this.id ? 'html2canvas (' + this.id + '):' : 'html2canvas:'].concat([].slice.call(args, 0)));
+            }
+        }
+
+        // eslint-disable-next-line flowtype/no-weak-types
+
+    }, {
+        key: 'error',
+        value: function error() {
+            if (this.enabled && window.console && window.console.error) {
+                for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
+                    args[_key2] = arguments[_key2];
+                }
+
+                Function.prototype.bind.call(window.console.error, window.console).apply(window.console, [Date.now() - this.start + 'ms', this.id ? 'html2canvas (' + this.id + '):' : 'html2canvas:'].concat([].slice.call(args, 0)));
+            }
+        }
+    }]);
+
+    return Logger;
+}();
+
+exports.default = Logger;
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/NodeContainer.js b/AstuteClient2/src/assets/html2canvas/dist/npm/NodeContainer.js
new file mode 100644
index 0000000..798720e
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/NodeContainer.js
@@ -0,0 +1,240 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Color = require('./Color');
+
+var _Color2 = _interopRequireDefault(_Color);
+
+var _Util = require('./Util');
+
+var _background = require('./parsing/background');
+
+var _border = require('./parsing/border');
+
+var _borderRadius = require('./parsing/borderRadius');
+
+var _display = require('./parsing/display');
+
+var _float = require('./parsing/float');
+
+var _font = require('./parsing/font');
+
+var _letterSpacing = require('./parsing/letterSpacing');
+
+var _lineBreak = require('./parsing/lineBreak');
+
+var _listStyle = require('./parsing/listStyle');
+
+var _margin = require('./parsing/margin');
+
+var _overflow = require('./parsing/overflow');
+
+var _overflowWrap = require('./parsing/overflowWrap');
+
+var _padding = require('./parsing/padding');
+
+var _position = require('./parsing/position');
+
+var _textDecoration = require('./parsing/textDecoration');
+
+var _textShadow = require('./parsing/textShadow');
+
+var _textTransform = require('./parsing/textTransform');
+
+var _transform = require('./parsing/transform');
+
+var _visibility = require('./parsing/visibility');
+
+var _wordBreak = require('./parsing/word-break');
+
+var _zIndex = require('./parsing/zIndex');
+
+var _Bounds = require('./Bounds');
+
+var _Input = require('./Input');
+
+var _ListItem = require('./ListItem');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];
+
+var NodeContainer = function () {
+    function NodeContainer(node, parent, resourceLoader, index) {
+        var _this = this;
+
+        _classCallCheck(this, NodeContainer);
+
+        this.parent = parent;
+        this.tagName = node.tagName;
+        this.index = index;
+        this.childNodes = [];
+        this.listItems = [];
+        if (typeof node.start === 'number') {
+            this.listStart = node.start;
+        }
+        var defaultView = node.ownerDocument.defaultView;
+        var scrollX = defaultView.pageXOffset;
+        var scrollY = defaultView.pageYOffset;
+        var style = defaultView.getComputedStyle(node, null);
+        var display = (0, _display.parseDisplay)(style.display);
+
+        var IS_INPUT = node.type === 'radio' || node.type === 'checkbox';
+
+        var position = (0, _position.parsePosition)(style.position);
+
+        this.style = {
+            background: IS_INPUT ? _Input.INPUT_BACKGROUND : (0, _background.parseBackground)(style, resourceLoader),
+            border: IS_INPUT ? _Input.INPUT_BORDERS : (0, _border.parseBorder)(style),
+            borderRadius: (node instanceof defaultView.HTMLInputElement || node instanceof HTMLInputElement) && IS_INPUT ? (0, _Input.getInputBorderRadius)(node) : (0, _borderRadius.parseBorderRadius)(style),
+            color: IS_INPUT ? _Input.INPUT_COLOR : new _Color2.default(style.color),
+            display: display,
+            float: (0, _float.parseCSSFloat)(style.float),
+            font: (0, _font.parseFont)(style),
+            letterSpacing: (0, _letterSpacing.parseLetterSpacing)(style.letterSpacing),
+            listStyle: display === _display.DISPLAY.LIST_ITEM ? (0, _listStyle.parseListStyle)(style) : null,
+            lineBreak: (0, _lineBreak.parseLineBreak)(style.lineBreak),
+            margin: (0, _margin.parseMargin)(style),
+            opacity: parseFloat(style.opacity),
+            overflow: INPUT_TAGS.indexOf(node.tagName) === -1 ? (0, _overflow.parseOverflow)(style.overflow) : _overflow.OVERFLOW.HIDDEN,
+            overflowWrap: (0, _overflowWrap.parseOverflowWrap)(style.overflowWrap ? style.overflowWrap : style.wordWrap),
+            padding: (0, _padding.parsePadding)(style),
+            position: position,
+            textDecoration: (0, _textDecoration.parseTextDecoration)(style),
+            textShadow: (0, _textShadow.parseTextShadow)(style.textShadow),
+            textTransform: (0, _textTransform.parseTextTransform)(style.textTransform),
+            transform: (0, _transform.parseTransform)(style),
+            visibility: (0, _visibility.parseVisibility)(style.visibility),
+            wordBreak: (0, _wordBreak.parseWordBreak)(style.wordBreak),
+            zIndex: (0, _zIndex.parseZIndex)(position !== _position.POSITION.STATIC ? style.zIndex : 'auto')
+        };
+
+        if (this.isTransformed()) {
+            // getBoundingClientRect provides values post-transform, we want them without the transformation
+            node.style.transform = 'matrix(1,0,0,1,0,0)';
+        }
+
+        if (display === _display.DISPLAY.LIST_ITEM) {
+            var listOwner = (0, _ListItem.getListOwner)(this);
+            if (listOwner) {
+                var listIndex = listOwner.listItems.length;
+                listOwner.listItems.push(this);
+                this.listIndex = node.hasAttribute('value') && typeof node.value === 'number' ? node.value : listIndex === 0 ? typeof listOwner.listStart === 'number' ? listOwner.listStart : 1 : listOwner.listItems[listIndex - 1].listIndex + 1;
+            }
+        }
+
+        // TODO move bound retrieval for all nodes to a later stage?
+        if (node.tagName === 'IMG') {
+            node.addEventListener('load', function () {
+                _this.bounds = (0, _Bounds.parseBounds)(node, scrollX, scrollY);
+                _this.curvedBounds = (0, _Bounds.parseBoundCurves)(_this.bounds, _this.style.border, _this.style.borderRadius);
+            });
+        }
+        this.image = getImage(node, resourceLoader);
+        this.bounds = IS_INPUT ? (0, _Input.reformatInputBounds)((0, _Bounds.parseBounds)(node, scrollX, scrollY)) : (0, _Bounds.parseBounds)(node, scrollX, scrollY);
+        this.curvedBounds = (0, _Bounds.parseBoundCurves)(this.bounds, this.style.border, this.style.borderRadius);
+
+        if (process.env.NODE_ENV !== 'production') {
+            this.name = '' + node.tagName.toLowerCase() + (node.id ? '#' + node.id : '') + node.className.toString().split(' ').map(function (s) {
+                return s.length ? '.' + s : '';
+            }).join('');
+        }
+    }
+
+    _createClass(NodeContainer, [{
+        key: 'getClipPaths',
+        value: function getClipPaths() {
+            var parentClips = this.parent ? this.parent.getClipPaths() : [];
+            var isClipped = this.style.overflow !== _overflow.OVERFLOW.VISIBLE;
+
+            return isClipped ? parentClips.concat([(0, _Bounds.calculatePaddingBoxPath)(this.curvedBounds)]) : parentClips;
+        }
+    }, {
+        key: 'isInFlow',
+        value: function isInFlow() {
+            return this.isRootElement() && !this.isFloating() && !this.isAbsolutelyPositioned();
+        }
+    }, {
+        key: 'isVisible',
+        value: function isVisible() {
+            return !(0, _Util.contains)(this.style.display, _display.DISPLAY.NONE) && this.style.opacity > 0 && this.style.visibility === _visibility.VISIBILITY.VISIBLE;
+        }
+    }, {
+        key: 'isAbsolutelyPositioned',
+        value: function isAbsolutelyPositioned() {
+            return this.style.position !== _position.POSITION.STATIC && this.style.position !== _position.POSITION.RELATIVE;
+        }
+    }, {
+        key: 'isPositioned',
+        value: function isPositioned() {
+            return this.style.position !== _position.POSITION.STATIC;
+        }
+    }, {
+        key: 'isFloating',
+        value: function isFloating() {
+            return this.style.float !== _float.FLOAT.NONE;
+        }
+    }, {
+        key: 'isRootElement',
+        value: function isRootElement() {
+            return this.parent === null;
+        }
+    }, {
+        key: 'isTransformed',
+        value: function isTransformed() {
+            return this.style.transform !== null;
+        }
+    }, {
+        key: 'isPositionedWithZIndex',
+        value: function isPositionedWithZIndex() {
+            return this.isPositioned() && !this.style.zIndex.auto;
+        }
+    }, {
+        key: 'isInlineLevel',
+        value: function isInlineLevel() {
+            return (0, _Util.contains)(this.style.display, _display.DISPLAY.INLINE) || (0, _Util.contains)(this.style.display, _display.DISPLAY.INLINE_BLOCK) || (0, _Util.contains)(this.style.display, _display.DISPLAY.INLINE_FLEX) || (0, _Util.contains)(this.style.display, _display.DISPLAY.INLINE_GRID) || (0, _Util.contains)(this.style.display, _display.DISPLAY.INLINE_LIST_ITEM) || (0, _Util.contains)(this.style.display, _display.DISPLAY.INLINE_TABLE);
+        }
+    }, {
+        key: 'isInlineBlockOrInlineTable',
+        value: function isInlineBlockOrInlineTable() {
+            return (0, _Util.contains)(this.style.display, _display.DISPLAY.INLINE_BLOCK) || (0, _Util.contains)(this.style.display, _display.DISPLAY.INLINE_TABLE);
+        }
+    }]);
+
+    return NodeContainer;
+}();
+
+exports.default = NodeContainer;
+
+
+var getImage = function getImage(node, resourceLoader) {
+    if (node instanceof node.ownerDocument.defaultView.SVGSVGElement || node instanceof SVGSVGElement) {
+        var s = new XMLSerializer();
+        return resourceLoader.loadImage('data:image/svg+xml,' + encodeURIComponent(s.serializeToString(node)));
+    }
+    switch (node.tagName) {
+        case 'IMG':
+            // $FlowFixMe
+            var img = node;
+            return resourceLoader.loadImage(img.currentSrc || img.src);
+        case 'CANVAS':
+            // $FlowFixMe
+            var canvas = node;
+            return resourceLoader.loadCanvas(canvas);
+        case 'IFRAME':
+            var iframeKey = node.getAttribute('data-html2canvas-internal-iframe-key');
+            if (iframeKey) {
+                return iframeKey;
+            }
+            break;
+    }
+
+    return null;
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/NodeParser.js b/AstuteClient2/src/assets/html2canvas/dist/npm/NodeParser.js
new file mode 100644
index 0000000..b8e66f7
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/NodeParser.js
@@ -0,0 +1,123 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.NodeParser = undefined;
+
+var _StackingContext = require('./StackingContext');
+
+var _StackingContext2 = _interopRequireDefault(_StackingContext);
+
+var _NodeContainer = require('./NodeContainer');
+
+var _NodeContainer2 = _interopRequireDefault(_NodeContainer);
+
+var _TextContainer = require('./TextContainer');
+
+var _TextContainer2 = _interopRequireDefault(_TextContainer);
+
+var _Input = require('./Input');
+
+var _ListItem = require('./ListItem');
+
+var _listStyle = require('./parsing/listStyle');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var NodeParser = exports.NodeParser = function NodeParser(node, resourceLoader, logger) {
+    if (process.env.NODE_ENV !== 'production') {
+        logger.log('Starting node parsing');
+    }
+
+    var index = 0;
+
+    var container = new _NodeContainer2.default(node, null, resourceLoader, index++);
+    var stack = new _StackingContext2.default(container, null, true);
+
+    parseNodeTree(node, container, stack, resourceLoader, index);
+
+    if (process.env.NODE_ENV !== 'production') {
+        logger.log('Finished parsing node tree');
+    }
+
+    return stack;
+};
+
+var IGNORED_NODE_NAMES = ['SCRIPT', 'HEAD', 'TITLE', 'OBJECT', 'BR', 'OPTION'];
+
+var parseNodeTree = function parseNodeTree(node, parent, stack, resourceLoader, index) {
+    if (process.env.NODE_ENV !== 'production' && index > 50000) {
+        throw new Error('Recursion error while parsing node tree');
+    }
+
+    for (var childNode = node.firstChild, nextNode; childNode; childNode = nextNode) {
+        nextNode = childNode.nextSibling;
+        var defaultView = childNode.ownerDocument.defaultView;
+        if (childNode instanceof defaultView.Text || childNode instanceof Text || defaultView.parent && childNode instanceof defaultView.parent.Text) {
+            if (childNode.data.trim().length > 0) {
+                parent.childNodes.push(_TextContainer2.default.fromTextNode(childNode, parent));
+            }
+        } else if (childNode instanceof defaultView.HTMLElement || childNode instanceof HTMLElement || defaultView.parent && childNode instanceof defaultView.parent.HTMLElement) {
+            if (IGNORED_NODE_NAMES.indexOf(childNode.nodeName) === -1) {
+                var container = new _NodeContainer2.default(childNode, parent, resourceLoader, index++);
+                if (container.isVisible()) {
+                    if (childNode.tagName === 'INPUT') {
+                        // $FlowFixMe
+                        (0, _Input.inlineInputElement)(childNode, container);
+                    } else if (childNode.tagName === 'TEXTAREA') {
+                        // $FlowFixMe
+                        (0, _Input.inlineTextAreaElement)(childNode, container);
+                    } else if (childNode.tagName === 'SELECT') {
+                        // $FlowFixMe
+                        (0, _Input.inlineSelectElement)(childNode, container);
+                    } else if (container.style.listStyle && container.style.listStyle.listStyleType !== _listStyle.LIST_STYLE_TYPE.NONE) {
+                        (0, _ListItem.inlineListItemElement)(childNode, container, resourceLoader);
+                    }
+
+                    var SHOULD_TRAVERSE_CHILDREN = childNode.tagName !== 'TEXTAREA';
+                    var treatAsRealStackingContext = createsRealStackingContext(container, childNode);
+                    if (treatAsRealStackingContext || createsStackingContext(container)) {
+                        // for treatAsRealStackingContext:false, any positioned descendants and descendants
+                        // which actually create a new stacking context should be considered part of the parent stacking context
+                        var parentStack = treatAsRealStackingContext || container.isPositioned() ? stack.getRealParentStackingContext() : stack;
+                        var childStack = new _StackingContext2.default(container, parentStack, treatAsRealStackingContext);
+                        parentStack.contexts.push(childStack);
+                        if (SHOULD_TRAVERSE_CHILDREN) {
+                            parseNodeTree(childNode, container, childStack, resourceLoader, index);
+                        }
+                    } else {
+                        stack.children.push(container);
+                        if (SHOULD_TRAVERSE_CHILDREN) {
+                            parseNodeTree(childNode, container, stack, resourceLoader, index);
+                        }
+                    }
+                }
+            }
+        } else if (childNode instanceof defaultView.SVGSVGElement || childNode instanceof SVGSVGElement || defaultView.parent && childNode instanceof defaultView.parent.SVGSVGElement) {
+            var _container = new _NodeContainer2.default(childNode, parent, resourceLoader, index++);
+            var _treatAsRealStackingContext = createsRealStackingContext(_container, childNode);
+            if (_treatAsRealStackingContext || createsStackingContext(_container)) {
+                // for treatAsRealStackingContext:false, any positioned descendants and descendants
+                // which actually create a new stacking context should be considered part of the parent stacking context
+                var _parentStack = _treatAsRealStackingContext || _container.isPositioned() ? stack.getRealParentStackingContext() : stack;
+                var _childStack = new _StackingContext2.default(_container, _parentStack, _treatAsRealStackingContext);
+                _parentStack.contexts.push(_childStack);
+            } else {
+                stack.children.push(_container);
+            }
+        }
+    }
+};
+
+var createsRealStackingContext = function createsRealStackingContext(container, node) {
+    return container.isRootElement() || container.isPositionedWithZIndex() || container.style.opacity < 1 || container.isTransformed() || isBodyWithTransparentRoot(container, node);
+};
+
+var createsStackingContext = function createsStackingContext(container) {
+    return container.isPositioned() || container.isFloating();
+};
+
+var isBodyWithTransparentRoot = function isBodyWithTransparentRoot(container, node) {
+    return node.nodeName === 'BODY' && container.parent instanceof _NodeContainer2.default && container.parent.style.background.backgroundColor.isTransparent();
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/Proxy.js b/AstuteClient2/src/assets/html2canvas/dist/npm/Proxy.js
new file mode 100644
index 0000000..339d058
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/Proxy.js
@@ -0,0 +1,65 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.Proxy = undefined;
+
+var _Feature = require('./Feature');
+
+var _Feature2 = _interopRequireDefault(_Feature);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var Proxy = exports.Proxy = function Proxy(src, options) {
+    if (!options.proxy) {
+        return Promise.reject(process.env.NODE_ENV !== 'production' ? 'No proxy defined' : null);
+    }
+    var proxy = options.proxy;
+
+    return new Promise(function (resolve, reject) {
+        var responseType = _Feature2.default.SUPPORT_CORS_XHR && _Feature2.default.SUPPORT_RESPONSE_TYPE ? 'blob' : 'text';
+        var xhr = _Feature2.default.SUPPORT_CORS_XHR ? new XMLHttpRequest() : new XDomainRequest();
+        xhr.onload = function () {
+            if (xhr instanceof XMLHttpRequest) {
+                if (xhr.status === 200) {
+                    if (responseType === 'text') {
+                        resolve(xhr.response);
+                    } else {
+                        var reader = new FileReader();
+                        // $FlowFixMe
+                        reader.addEventListener('load', function () {
+                            return resolve(reader.result);
+                        }, false);
+                        // $FlowFixMe
+                        reader.addEventListener('error', function (e) {
+                            return reject(e);
+                        }, false);
+                        reader.readAsDataURL(xhr.response);
+                    }
+                } else {
+                    reject(process.env.NODE_ENV !== 'production' ? 'Failed to proxy resource ' + src.substring(0, 256) + ' with status code ' + xhr.status : '');
+                }
+            } else {
+                resolve(xhr.responseText);
+            }
+        };
+
+        xhr.onerror = reject;
+        xhr.open('GET', proxy + '?url=' + encodeURIComponent(src) + '&responseType=' + responseType);
+
+        if (responseType !== 'text' && xhr instanceof XMLHttpRequest) {
+            xhr.responseType = responseType;
+        }
+
+        if (options.imageTimeout) {
+            var timeout = options.imageTimeout;
+            xhr.timeout = timeout;
+            xhr.ontimeout = function () {
+                return reject(process.env.NODE_ENV !== 'production' ? 'Timed out (' + timeout + 'ms) proxying ' + src.substring(0, 256) : '');
+            };
+        }
+
+        xhr.send();
+    });
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/PseudoNodeContent.js b/AstuteClient2/src/assets/html2canvas/dist/npm/PseudoNodeContent.js
new file mode 100644
index 0000000..58fbc66
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/PseudoNodeContent.js
@@ -0,0 +1,324 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseContent = exports.resolvePseudoContent = exports.popCounters = exports.parseCounterReset = exports.TOKEN_TYPE = exports.PSEUDO_CONTENT_ITEM_TYPE = undefined;
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var _ListItem = require('./ListItem');
+
+var _listStyle = require('./parsing/listStyle');
+
+var PSEUDO_CONTENT_ITEM_TYPE = exports.PSEUDO_CONTENT_ITEM_TYPE = {
+    TEXT: 0,
+    IMAGE: 1
+};
+
+var TOKEN_TYPE = exports.TOKEN_TYPE = {
+    STRING: 0,
+    ATTRIBUTE: 1,
+    URL: 2,
+    COUNTER: 3,
+    COUNTERS: 4,
+    OPENQUOTE: 5,
+    CLOSEQUOTE: 6
+};
+
+var parseCounterReset = exports.parseCounterReset = function parseCounterReset(style, data) {
+    if (!style || !style.counterReset || style.counterReset === 'none') {
+        return [];
+    }
+
+    var counterNames = [];
+    var counterResets = style.counterReset.split(/\s*,\s*/);
+    var lenCounterResets = counterResets.length;
+
+    for (var i = 0; i < lenCounterResets; i++) {
+        var _counterResets$i$spli = counterResets[i].split(/\s+/),
+            _counterResets$i$spli2 = _slicedToArray(_counterResets$i$spli, 2),
+            counterName = _counterResets$i$spli2[0],
+            initialValue = _counterResets$i$spli2[1];
+
+        counterNames.push(counterName);
+        var counter = data.counters[counterName];
+        if (!counter) {
+            counter = data.counters[counterName] = [];
+        }
+        counter.push(parseInt(initialValue || 0, 10));
+    }
+
+    return counterNames;
+};
+
+var popCounters = exports.popCounters = function popCounters(counterNames, data) {
+    var lenCounters = counterNames.length;
+    for (var i = 0; i < lenCounters; i++) {
+        data.counters[counterNames[i]].pop();
+    }
+};
+
+var resolvePseudoContent = exports.resolvePseudoContent = function resolvePseudoContent(node, style, data) {
+    if (!style || !style.content || style.content === 'none' || style.content === '-moz-alt-content' || style.display === 'none') {
+        return null;
+    }
+
+    var tokens = parseContent(style.content);
+
+    var len = tokens.length;
+    var contentItems = [];
+    var s = '';
+
+    // increment the counter (if there is a "counter-increment" declaration)
+    var counterIncrement = style.counterIncrement;
+    if (counterIncrement && counterIncrement !== 'none') {
+        var _counterIncrement$spl = counterIncrement.split(/\s+/),
+            _counterIncrement$spl2 = _slicedToArray(_counterIncrement$spl, 2),
+            counterName = _counterIncrement$spl2[0],
+            incrementValue = _counterIncrement$spl2[1];
+
+        var counter = data.counters[counterName];
+        if (counter) {
+            counter[counter.length - 1] += incrementValue === undefined ? 1 : parseInt(incrementValue, 10);
+        }
+    }
+
+    // build the content string
+    for (var i = 0; i < len; i++) {
+        var token = tokens[i];
+        switch (token.type) {
+            case TOKEN_TYPE.STRING:
+                s += token.value || '';
+                break;
+
+            case TOKEN_TYPE.ATTRIBUTE:
+                if (node instanceof HTMLElement && token.value) {
+                    s += node.getAttribute(token.value) || '';
+                }
+                break;
+
+            case TOKEN_TYPE.COUNTER:
+                var _counter = data.counters[token.name || ''];
+                if (_counter) {
+                    s += formatCounterValue([_counter[_counter.length - 1]], '', token.format);
+                }
+                break;
+
+            case TOKEN_TYPE.COUNTERS:
+                var _counters = data.counters[token.name || ''];
+                if (_counters) {
+                    s += formatCounterValue(_counters, token.glue, token.format);
+                }
+                break;
+
+            case TOKEN_TYPE.OPENQUOTE:
+                s += getQuote(style, true, data.quoteDepth);
+                data.quoteDepth++;
+                break;
+
+            case TOKEN_TYPE.CLOSEQUOTE:
+                data.quoteDepth--;
+                s += getQuote(style, false, data.quoteDepth);
+                break;
+
+            case TOKEN_TYPE.URL:
+                if (s) {
+                    contentItems.push({ type: PSEUDO_CONTENT_ITEM_TYPE.TEXT, value: s });
+                    s = '';
+                }
+                contentItems.push({ type: PSEUDO_CONTENT_ITEM_TYPE.IMAGE, value: token.value || '' });
+                break;
+        }
+    }
+
+    if (s) {
+        contentItems.push({ type: PSEUDO_CONTENT_ITEM_TYPE.TEXT, value: s });
+    }
+
+    return contentItems;
+};
+
+var parseContent = exports.parseContent = function parseContent(content, cache) {
+    if (cache && cache[content]) {
+        return cache[content];
+    }
+
+    var tokens = [];
+    var len = content.length;
+
+    var isString = false;
+    var isEscaped = false;
+    var isFunction = false;
+    var str = '';
+    var functionName = '';
+    var args = [];
+
+    for (var i = 0; i < len; i++) {
+        var c = content.charAt(i);
+
+        switch (c) {
+            case "'":
+            case '"':
+                if (isEscaped) {
+                    str += c;
+                } else {
+                    isString = !isString;
+                    if (!isFunction && !isString) {
+                        tokens.push({ type: TOKEN_TYPE.STRING, value: str });
+                        str = '';
+                    }
+                }
+                break;
+
+            case '\\':
+                if (isEscaped) {
+                    str += c;
+                    isEscaped = false;
+                } else {
+                    isEscaped = true;
+                }
+                break;
+
+            case '(':
+                if (isString) {
+                    str += c;
+                } else {
+                    isFunction = true;
+                    functionName = str;
+                    str = '';
+                    args = [];
+                }
+                break;
+
+            case ')':
+                if (isString) {
+                    str += c;
+                } else if (isFunction) {
+                    if (str) {
+                        args.push(str);
+                    }
+
+                    switch (functionName) {
+                        case 'attr':
+                            if (args.length > 0) {
+                                tokens.push({ type: TOKEN_TYPE.ATTRIBUTE, value: args[0] });
+                            }
+                            break;
+
+                        case 'counter':
+                            if (args.length > 0) {
+                                var counter = {
+                                    type: TOKEN_TYPE.COUNTER,
+                                    name: args[0]
+                                };
+                                if (args.length > 1) {
+                                    counter.format = args[1];
+                                }
+                                tokens.push(counter);
+                            }
+                            break;
+
+                        case 'counters':
+                            if (args.length > 0) {
+                                var _counters2 = {
+                                    type: TOKEN_TYPE.COUNTERS,
+                                    name: args[0]
+                                };
+                                if (args.length > 1) {
+                                    _counters2.glue = args[1];
+                                }
+                                if (args.length > 2) {
+                                    _counters2.format = args[2];
+                                }
+                                tokens.push(_counters2);
+                            }
+                            break;
+
+                        case 'url':
+                            if (args.length > 0) {
+                                tokens.push({ type: TOKEN_TYPE.URL, value: args[0] });
+                            }
+                            break;
+                    }
+
+                    isFunction = false;
+                    str = '';
+                }
+                break;
+
+            case ',':
+                if (isString) {
+                    str += c;
+                } else if (isFunction) {
+                    args.push(str);
+                    str = '';
+                }
+                break;
+
+            case ' ':
+            case '\t':
+                if (isString) {
+                    str += c;
+                } else if (str) {
+                    addOtherToken(tokens, str);
+                    str = '';
+                }
+                break;
+
+            default:
+                str += c;
+        }
+
+        if (c !== '\\') {
+            isEscaped = false;
+        }
+    }
+
+    if (str) {
+        addOtherToken(tokens, str);
+    }
+
+    if (cache) {
+        cache[content] = tokens;
+    }
+
+    return tokens;
+};
+
+var addOtherToken = function addOtherToken(tokens, identifier) {
+    switch (identifier) {
+        case 'open-quote':
+            tokens.push({ type: TOKEN_TYPE.OPENQUOTE });
+            break;
+        case 'close-quote':
+            tokens.push({ type: TOKEN_TYPE.CLOSEQUOTE });
+            break;
+    }
+};
+
+var getQuote = function getQuote(style, isOpening, quoteDepth) {
+    var quotes = style.quotes ? style.quotes.split(/\s+/) : ["'\"'", "'\"'"];
+    var idx = quoteDepth * 2;
+    if (idx >= quotes.length) {
+        idx = quotes.length - 2;
+    }
+    if (!isOpening) {
+        ++idx;
+    }
+    return quotes[idx].replace(/^["']|["']$/g, '');
+};
+
+var formatCounterValue = function formatCounterValue(counter, glue, format) {
+    var len = counter.length;
+    var result = '';
+
+    for (var i = 0; i < len; i++) {
+        if (i > 0) {
+            result += glue || '';
+        }
+        result += (0, _ListItem.createCounterText)(counter[i], (0, _listStyle.parseListStyleType)(format || 'decimal'), false);
+    }
+
+    return result;
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/Renderer.js b/AstuteClient2/src/assets/html2canvas/dist/npm/Renderer.js
new file mode 100644
index 0000000..c5651c8
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/Renderer.js
@@ -0,0 +1,328 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Bounds = require('./Bounds');
+
+var _Font = require('./Font');
+
+var _Gradient = require('./Gradient');
+
+var _TextContainer = require('./TextContainer');
+
+var _TextContainer2 = _interopRequireDefault(_TextContainer);
+
+var _background = require('./parsing/background');
+
+var _border = require('./parsing/border');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Renderer = function () {
+    function Renderer(target, options) {
+        _classCallCheck(this, Renderer);
+
+        this.target = target;
+        this.options = options;
+        target.render(options);
+    }
+
+    _createClass(Renderer, [{
+        key: 'renderNode',
+        value: function renderNode(container) {
+            if (container.isVisible()) {
+                this.renderNodeBackgroundAndBorders(container);
+                this.renderNodeContent(container);
+            }
+        }
+    }, {
+        key: 'renderNodeContent',
+        value: function renderNodeContent(container) {
+            var _this = this;
+
+            var callback = function callback() {
+                if (container.childNodes.length) {
+                    container.childNodes.forEach(function (child) {
+                        if (child instanceof _TextContainer2.default) {
+                            var style = child.parent.style;
+                            _this.target.renderTextNode(child.bounds, style.color, style.font, style.textDecoration, style.textShadow);
+                        } else {
+                            _this.target.drawShape(child, container.style.color);
+                        }
+                    });
+                }
+
+                if (container.image) {
+                    var _image = _this.options.imageStore.get(container.image);
+                    if (_image) {
+                        var contentBox = (0, _Bounds.calculateContentBox)(container.bounds, container.style.padding, container.style.border);
+                        var _width = typeof _image.width === 'number' && _image.width > 0 ? _image.width : contentBox.width;
+                        var _height = typeof _image.height === 'number' && _image.height > 0 ? _image.height : contentBox.height;
+                        if (_width > 0 && _height > 0) {
+                            _this.target.clip([(0, _Bounds.calculatePaddingBoxPath)(container.curvedBounds)], function () {
+                                _this.target.drawImage(_image, new _Bounds.Bounds(0, 0, _width, _height), contentBox);
+                            });
+                        }
+                    }
+                }
+            };
+            var paths = container.getClipPaths();
+            if (paths.length) {
+                this.target.clip(paths, callback);
+            } else {
+                callback();
+            }
+        }
+    }, {
+        key: 'renderNodeBackgroundAndBorders',
+        value: function renderNodeBackgroundAndBorders(container) {
+            var _this2 = this;
+
+            var HAS_BACKGROUND = !container.style.background.backgroundColor.isTransparent() || container.style.background.backgroundImage.length;
+
+            var hasRenderableBorders = container.style.border.some(function (border) {
+                return border.borderStyle !== _border.BORDER_STYLE.NONE && !border.borderColor.isTransparent();
+            });
+
+            var callback = function callback() {
+                var backgroundPaintingArea = (0, _background.calculateBackgroungPaintingArea)(container.curvedBounds, container.style.background.backgroundClip);
+
+                if (HAS_BACKGROUND) {
+                    _this2.target.clip([backgroundPaintingArea], function () {
+                        if (!container.style.background.backgroundColor.isTransparent()) {
+                            _this2.target.fill(container.style.background.backgroundColor);
+                        }
+
+                        _this2.renderBackgroundImage(container);
+                    });
+                }
+
+                container.style.border.forEach(function (border, side) {
+                    if (border.borderStyle !== _border.BORDER_STYLE.NONE && !border.borderColor.isTransparent()) {
+                        _this2.renderBorder(border, side, container.curvedBounds);
+                    }
+                });
+            };
+
+            if (HAS_BACKGROUND || hasRenderableBorders) {
+                var paths = container.parent ? container.parent.getClipPaths() : [];
+                if (paths.length) {
+                    this.target.clip(paths, callback);
+                } else {
+                    callback();
+                }
+            }
+        }
+    }, {
+        key: 'renderBackgroundImage',
+        value: function renderBackgroundImage(container) {
+            var _this3 = this;
+
+            container.style.background.backgroundImage.slice(0).reverse().forEach(function (backgroundImage) {
+                if (backgroundImage.source.method === 'url' && backgroundImage.source.args.length) {
+                    _this3.renderBackgroundRepeat(container, backgroundImage);
+                } else if (/gradient/i.test(backgroundImage.source.method)) {
+                    _this3.renderBackgroundGradient(container, backgroundImage);
+                }
+            });
+        }
+    }, {
+        key: 'renderBackgroundRepeat',
+        value: function renderBackgroundRepeat(container, background) {
+            var image = this.options.imageStore.get(background.source.args[0]);
+            if (image) {
+                var backgroundPositioningArea = (0, _background.calculateBackgroungPositioningArea)(container.style.background.backgroundOrigin, container.bounds, container.style.padding, container.style.border);
+                var backgroundImageSize = (0, _background.calculateBackgroundSize)(background, image, backgroundPositioningArea);
+                var position = (0, _background.calculateBackgroundPosition)(background.position, backgroundImageSize, backgroundPositioningArea);
+                var _path = (0, _background.calculateBackgroundRepeatPath)(background, position, backgroundImageSize, backgroundPositioningArea, container.bounds);
+
+                var _offsetX = Math.round(backgroundPositioningArea.left + position.x);
+                var _offsetY = Math.round(backgroundPositioningArea.top + position.y);
+                this.target.renderRepeat(_path, image, backgroundImageSize, _offsetX, _offsetY);
+            }
+        }
+    }, {
+        key: 'renderBackgroundGradient',
+        value: function renderBackgroundGradient(container, background) {
+            var backgroundPositioningArea = (0, _background.calculateBackgroungPositioningArea)(container.style.background.backgroundOrigin, container.bounds, container.style.padding, container.style.border);
+            var backgroundImageSize = (0, _background.calculateGradientBackgroundSize)(background, backgroundPositioningArea);
+            var position = (0, _background.calculateBackgroundPosition)(background.position, backgroundImageSize, backgroundPositioningArea);
+            var gradientBounds = new _Bounds.Bounds(Math.round(backgroundPositioningArea.left + position.x), Math.round(backgroundPositioningArea.top + position.y), backgroundImageSize.width, backgroundImageSize.height);
+
+            var gradient = (0, _Gradient.parseGradient)(container, background.source, gradientBounds);
+            if (gradient) {
+                switch (gradient.type) {
+                    case _Gradient.GRADIENT_TYPE.LINEAR_GRADIENT:
+                        // $FlowFixMe
+                        this.target.renderLinearGradient(gradientBounds, gradient);
+                        break;
+                    case _Gradient.GRADIENT_TYPE.RADIAL_GRADIENT:
+                        // $FlowFixMe
+                        this.target.renderRadialGradient(gradientBounds, gradient);
+                        break;
+                }
+            }
+        }
+    }, {
+        key: 'renderBorder',
+        value: function renderBorder(border, side, curvePoints) {
+            this.target.drawShape((0, _Bounds.parsePathForBorder)(curvePoints, side), border.borderColor);
+        }
+    }, {
+        key: 'renderStack',
+        value: function renderStack(stack) {
+            var _this4 = this;
+
+            if (stack.container.isVisible()) {
+                var _opacity = stack.getOpacity();
+                if (_opacity !== this._opacity) {
+                    this.target.setOpacity(stack.getOpacity());
+                    this._opacity = _opacity;
+                }
+
+                var _transform = stack.container.style.transform;
+                if (_transform !== null) {
+                    this.target.transform(stack.container.bounds.left + _transform.transformOrigin[0].value, stack.container.bounds.top + _transform.transformOrigin[1].value, _transform.transform, function () {
+                        return _this4.renderStackContent(stack);
+                    });
+                } else {
+                    this.renderStackContent(stack);
+                }
+            }
+        }
+    }, {
+        key: 'renderStackContent',
+        value: function renderStackContent(stack) {
+            var _splitStackingContext = splitStackingContexts(stack),
+                _splitStackingContext2 = _slicedToArray(_splitStackingContext, 5),
+                negativeZIndex = _splitStackingContext2[0],
+                zeroOrAutoZIndexOrTransformedOrOpacity = _splitStackingContext2[1],
+                positiveZIndex = _splitStackingContext2[2],
+                nonPositionedFloats = _splitStackingContext2[3],
+                nonPositionedInlineLevel = _splitStackingContext2[4];
+
+            var _splitDescendants = splitDescendants(stack),
+                _splitDescendants2 = _slicedToArray(_splitDescendants, 2),
+                inlineLevel = _splitDescendants2[0],
+                nonInlineLevel = _splitDescendants2[1];
+
+            // https://www.w3.org/TR/css-position-3/#painting-order
+            // 1. the background and borders of the element forming the stacking context.
+
+
+            this.renderNodeBackgroundAndBorders(stack.container);
+            // 2. the child stacking contexts with negative stack levels (most negative first).
+            negativeZIndex.sort(sortByZIndex).forEach(this.renderStack, this);
+            // 3. For all its in-flow, non-positioned, block-level descendants in tree order:
+            this.renderNodeContent(stack.container);
+            nonInlineLevel.forEach(this.renderNode, this);
+            // 4. All non-positioned floating descendants, in tree order. For each one of these,
+            // treat the element as if it created a new stacking context, but any positioned descendants and descendants
+            // which actually create a new stacking context should be considered part of the parent stacking context,
+            // not this new one.
+            nonPositionedFloats.forEach(this.renderStack, this);
+            // 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
+            nonPositionedInlineLevel.forEach(this.renderStack, this);
+            inlineLevel.forEach(this.renderNode, this);
+            // 6. All positioned, opacity or transform descendants, in tree order that fall into the following categories:
+            //  All positioned descendants with 'z-index: auto' or 'z-index: 0', in tree order.
+            //  For those with 'z-index: auto', treat the element as if it created a new stacking context,
+            //  but any positioned descendants and descendants which actually create a new stacking context should be
+            //  considered part of the parent stacking context, not this new one. For those with 'z-index: 0',
+            //  treat the stacking context generated atomically.
+            //
+            //  All opacity descendants with opacity less than 1
+            //
+            //  All transform descendants with transform other than none
+            zeroOrAutoZIndexOrTransformedOrOpacity.forEach(this.renderStack, this);
+            // 7. Stacking contexts formed by positioned descendants with z-indices greater than or equal to 1 in z-index
+            // order (smallest first) then tree order.
+            positiveZIndex.sort(sortByZIndex).forEach(this.renderStack, this);
+        }
+    }, {
+        key: 'render',
+        value: function render(stack) {
+            var _this5 = this;
+
+            if (this.options.backgroundColor) {
+                this.target.rectangle(this.options.x, this.options.y, this.options.width, this.options.height, this.options.backgroundColor);
+            }
+            this.renderStack(stack);
+            var target = this.target.getTarget();
+            if (process.env.NODE_ENV !== 'production') {
+                return target.then(function (output) {
+                    _this5.options.logger.log('Render completed');
+                    return output;
+                });
+            }
+            return target;
+        }
+    }]);
+
+    return Renderer;
+}();
+
+exports.default = Renderer;
+
+
+var splitDescendants = function splitDescendants(stack) {
+    var inlineLevel = [];
+    var nonInlineLevel = [];
+
+    var length = stack.children.length;
+    for (var i = 0; i < length; i++) {
+        var child = stack.children[i];
+        if (child.isInlineLevel()) {
+            inlineLevel.push(child);
+        } else {
+            nonInlineLevel.push(child);
+        }
+    }
+    return [inlineLevel, nonInlineLevel];
+};
+
+var splitStackingContexts = function splitStackingContexts(stack) {
+    var negativeZIndex = [];
+    var zeroOrAutoZIndexOrTransformedOrOpacity = [];
+    var positiveZIndex = [];
+    var nonPositionedFloats = [];
+    var nonPositionedInlineLevel = [];
+    var length = stack.contexts.length;
+    for (var i = 0; i < length; i++) {
+        var child = stack.contexts[i];
+        if (child.container.isPositioned() || child.container.style.opacity < 1 || child.container.isTransformed()) {
+            if (child.container.style.zIndex.order < 0) {
+                negativeZIndex.push(child);
+            } else if (child.container.style.zIndex.order > 0) {
+                positiveZIndex.push(child);
+            } else {
+                zeroOrAutoZIndexOrTransformedOrOpacity.push(child);
+            }
+        } else {
+            if (child.container.isFloating()) {
+                nonPositionedFloats.push(child);
+            } else {
+                nonPositionedInlineLevel.push(child);
+            }
+        }
+    }
+    return [negativeZIndex, zeroOrAutoZIndexOrTransformedOrOpacity, positiveZIndex, nonPositionedFloats, nonPositionedInlineLevel];
+};
+
+var sortByZIndex = function sortByZIndex(a, b) {
+    if (a.container.style.zIndex.order > b.container.style.zIndex.order) {
+        return 1;
+    } else if (a.container.style.zIndex.order < b.container.style.zIndex.order) {
+        return -1;
+    }
+
+    return a.container.index > b.container.index ? 1 : -1;
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/ResourceLoader.js b/AstuteClient2/src/assets/html2canvas/dist/npm/ResourceLoader.js
new file mode 100644
index 0000000..3e4ec39
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/ResourceLoader.js
@@ -0,0 +1,271 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.ResourceStore = undefined;
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Feature = require('./Feature');
+
+var _Feature2 = _interopRequireDefault(_Feature);
+
+var _Proxy = require('./Proxy');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var ResourceLoader = function () {
+    function ResourceLoader(options, logger, window) {
+        _classCallCheck(this, ResourceLoader);
+
+        this.options = options;
+        this._window = window;
+        this.origin = this.getOrigin(window.location.href);
+        this.cache = {};
+        this.logger = logger;
+        this._index = 0;
+    }
+
+    _createClass(ResourceLoader, [{
+        key: 'loadImage',
+        value: function loadImage(src) {
+            var _this = this;
+
+            if (this.hasResourceInCache(src)) {
+                return src;
+            }
+            if (isBlobImage(src)) {
+                this.cache[src] = _loadImage(src, this.options.imageTimeout || 0);
+                return src;
+            }
+
+            if (!isSVG(src) || _Feature2.default.SUPPORT_SVG_DRAWING) {
+                if (this.options.allowTaint === true || isInlineImage(src) || this.isSameOrigin(src)) {
+                    return this.addImage(src, src, false);
+                } else if (!this.isSameOrigin(src)) {
+                    if (typeof this.options.proxy === 'string') {
+                        this.cache[src] = (0, _Proxy.Proxy)(src, this.options).then(function (src) {
+                            return _loadImage(src, _this.options.imageTimeout || 0);
+                        });
+                        return src;
+                    } else if (this.options.useCORS === true && _Feature2.default.SUPPORT_CORS_IMAGES) {
+                        return this.addImage(src, src, true);
+                    }
+                }
+            }
+        }
+    }, {
+        key: 'inlineImage',
+        value: function inlineImage(src) {
+            var _this2 = this;
+
+            if (isInlineImage(src)) {
+                return _loadImage(src, this.options.imageTimeout || 0);
+            }
+            if (this.hasResourceInCache(src)) {
+                return this.cache[src];
+            }
+            if (!this.isSameOrigin(src) && typeof this.options.proxy === 'string') {
+                return this.cache[src] = (0, _Proxy.Proxy)(src, this.options).then(function (src) {
+                    return _loadImage(src, _this2.options.imageTimeout || 0);
+                });
+            }
+
+            return this.xhrImage(src);
+        }
+    }, {
+        key: 'xhrImage',
+        value: function xhrImage(src) {
+            var _this3 = this;
+
+            this.cache[src] = new Promise(function (resolve, reject) {
+                var xhr = new XMLHttpRequest();
+                xhr.onreadystatechange = function () {
+                    if (xhr.readyState === 4) {
+                        if (xhr.status !== 200) {
+                            reject('Failed to fetch image ' + src.substring(0, 256) + ' with status code ' + xhr.status);
+                        } else {
+                            var reader = new FileReader();
+                            reader.addEventListener('load', function () {
+                                // $FlowFixMe
+                                var result = reader.result;
+                                resolve(result);
+                            }, false);
+                            reader.addEventListener('error', function (e) {
+                                return reject(e);
+                            }, false);
+                            reader.readAsDataURL(xhr.response);
+                        }
+                    }
+                };
+                xhr.responseType = 'blob';
+                if (_this3.options.imageTimeout) {
+                    var timeout = _this3.options.imageTimeout;
+                    xhr.timeout = timeout;
+                    xhr.ontimeout = function () {
+                        return reject(process.env.NODE_ENV !== 'production' ? 'Timed out (' + timeout + 'ms) fetching ' + src.substring(0, 256) : '');
+                    };
+                }
+                xhr.open('GET', src, true);
+                xhr.send();
+            }).then(function (src) {
+                return _loadImage(src, _this3.options.imageTimeout || 0);
+            });
+
+            return this.cache[src];
+        }
+    }, {
+        key: 'loadCanvas',
+        value: function loadCanvas(node) {
+            var key = String(this._index++);
+            this.cache[key] = Promise.resolve(node);
+            return key;
+        }
+    }, {
+        key: 'hasResourceInCache',
+        value: function hasResourceInCache(key) {
+            return typeof this.cache[key] !== 'undefined';
+        }
+    }, {
+        key: 'addImage',
+        value: function addImage(key, src, useCORS) {
+            var _this4 = this;
+
+            if (process.env.NODE_ENV !== 'production') {
+                this.logger.log('Added image ' + key.substring(0, 256));
+            }
+
+            var imageLoadHandler = function imageLoadHandler(supportsDataImages) {
+                return new Promise(function (resolve, reject) {
+                    var img = new Image();
+                    img.onload = function () {
+                        return resolve(img);
+                    };
+                    //ios safari 10.3 taints canvas with data urls unless crossOrigin is set to anonymous
+                    if (!supportsDataImages || useCORS) {
+                        img.crossOrigin = 'anonymous';
+                    }
+
+                    img.onerror = reject;
+                    img.src = src;
+                    if (img.complete === true) {
+                        // Inline XML images may fail to parse, throwing an Error later on
+                        setTimeout(function () {
+                            resolve(img);
+                        }, 500);
+                    }
+                    if (_this4.options.imageTimeout) {
+                        var timeout = _this4.options.imageTimeout;
+                        setTimeout(function () {
+                            return reject(process.env.NODE_ENV !== 'production' ? 'Timed out (' + timeout + 'ms) fetching ' + src.substring(0, 256) : '');
+                        }, timeout);
+                    }
+                });
+            };
+
+            this.cache[key] = isInlineBase64Image(src) && !isSVG(src) ? // $FlowFixMe
+            _Feature2.default.SUPPORT_BASE64_DRAWING(src).then(imageLoadHandler) : imageLoadHandler(true);
+            return key;
+        }
+    }, {
+        key: 'isSameOrigin',
+        value: function isSameOrigin(url) {
+            return this.getOrigin(url) === this.origin;
+        }
+    }, {
+        key: 'getOrigin',
+        value: function getOrigin(url) {
+            var link = this._link || (this._link = this._window.document.createElement('a'));
+            link.href = url;
+            link.href = link.href; // IE9, LOL! - http://jsfiddle.net/niklasvh/2e48b/
+            return link.protocol + link.hostname + link.port;
+        }
+    }, {
+        key: 'ready',
+        value: function ready() {
+            var _this5 = this;
+
+            var keys = Object.keys(this.cache);
+            var values = keys.map(function (str) {
+                return _this5.cache[str].catch(function (e) {
+                    if (process.env.NODE_ENV !== 'production') {
+                        _this5.logger.log('Unable to load image', e);
+                    }
+                    return null;
+                });
+            });
+            return Promise.all(values).then(function (images) {
+                if (process.env.NODE_ENV !== 'production') {
+                    _this5.logger.log('Finished loading ' + images.length + ' images', images);
+                }
+                return new ResourceStore(keys, images);
+            });
+        }
+    }]);
+
+    return ResourceLoader;
+}();
+
+exports.default = ResourceLoader;
+
+var ResourceStore = exports.ResourceStore = function () {
+    function ResourceStore(keys, resources) {
+        _classCallCheck(this, ResourceStore);
+
+        this._keys = keys;
+        this._resources = resources;
+    }
+
+    _createClass(ResourceStore, [{
+        key: 'get',
+        value: function get(key) {
+            var index = this._keys.indexOf(key);
+            return index === -1 ? null : this._resources[index];
+        }
+    }]);
+
+    return ResourceStore;
+}();
+
+var INLINE_SVG = /^data:image\/svg\+xml/i;
+var INLINE_BASE64 = /^data:image\/.*;base64,/i;
+var INLINE_IMG = /^data:image\/.*/i;
+
+var isInlineImage = function isInlineImage(src) {
+    return INLINE_IMG.test(src);
+};
+var isInlineBase64Image = function isInlineBase64Image(src) {
+    return INLINE_BASE64.test(src);
+};
+var isBlobImage = function isBlobImage(src) {
+    return src.substr(0, 4) === 'blob';
+};
+
+var isSVG = function isSVG(src) {
+    return src.substr(-3).toLowerCase() === 'svg' || INLINE_SVG.test(src);
+};
+
+var _loadImage = function _loadImage(src, timeout) {
+    return new Promise(function (resolve, reject) {
+        var img = new Image();
+        img.onload = function () {
+            return resolve(img);
+        };
+        img.onerror = reject;
+        img.src = src;
+        if (img.complete === true) {
+            // Inline XML images may fail to parse, throwing an Error later on
+            setTimeout(function () {
+                resolve(img);
+            }, 500);
+        }
+        if (timeout) {
+            setTimeout(function () {
+                return reject(process.env.NODE_ENV !== 'production' ? 'Timed out (' + timeout + 'ms) loading image' : '');
+            }, timeout);
+        }
+    });
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/StackingContext.js b/AstuteClient2/src/assets/html2canvas/dist/npm/StackingContext.js
new file mode 100644
index 0000000..4af8702
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/StackingContext.js
@@ -0,0 +1,45 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _NodeContainer = require('./NodeContainer');
+
+var _NodeContainer2 = _interopRequireDefault(_NodeContainer);
+
+var _position = require('./parsing/position');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var StackingContext = function () {
+    function StackingContext(container, parent, treatAsRealStackingContext) {
+        _classCallCheck(this, StackingContext);
+
+        this.container = container;
+        this.parent = parent;
+        this.contexts = [];
+        this.children = [];
+        this.treatAsRealStackingContext = treatAsRealStackingContext;
+    }
+
+    _createClass(StackingContext, [{
+        key: 'getOpacity',
+        value: function getOpacity() {
+            return this.parent ? this.container.style.opacity * this.parent.getOpacity() : this.container.style.opacity;
+        }
+    }, {
+        key: 'getRealParentStackingContext',
+        value: function getRealParentStackingContext() {
+            return !this.parent || this.treatAsRealStackingContext ? this : this.parent.getRealParentStackingContext();
+        }
+    }]);
+
+    return StackingContext;
+}();
+
+exports.default = StackingContext;
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/TextBounds.js b/AstuteClient2/src/assets/html2canvas/dist/npm/TextBounds.js
new file mode 100644
index 0000000..b1cc41f
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/TextBounds.js
@@ -0,0 +1,78 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseTextBounds = exports.TextBounds = undefined;
+
+var _Bounds = require('./Bounds');
+
+var _textDecoration = require('./parsing/textDecoration');
+
+var _Feature = require('./Feature');
+
+var _Feature2 = _interopRequireDefault(_Feature);
+
+var _Unicode = require('./Unicode');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var TextBounds = exports.TextBounds = function TextBounds(text, bounds) {
+    _classCallCheck(this, TextBounds);
+
+    this.text = text;
+    this.bounds = bounds;
+};
+
+var parseTextBounds = exports.parseTextBounds = function parseTextBounds(value, parent, node) {
+    var letterRendering = parent.style.letterSpacing !== 0;
+    var textList = letterRendering ? (0, _Unicode.toCodePoints)(value).map(function (i) {
+        return (0, _Unicode.fromCodePoint)(i);
+    }) : (0, _Unicode.breakWords)(value, parent);
+    var length = textList.length;
+    var defaultView = node.parentNode ? node.parentNode.ownerDocument.defaultView : null;
+    var scrollX = defaultView ? defaultView.pageXOffset : 0;
+    var scrollY = defaultView ? defaultView.pageYOffset : 0;
+    var textBounds = [];
+    var offset = 0;
+    for (var i = 0; i < length; i++) {
+        var text = textList[i];
+        if (parent.style.textDecoration !== _textDecoration.TEXT_DECORATION.NONE || text.trim().length > 0) {
+            if (_Feature2.default.SUPPORT_RANGE_BOUNDS) {
+                textBounds.push(new TextBounds(text, getRangeBounds(node, offset, text.length, scrollX, scrollY)));
+            } else {
+                var replacementNode = node.splitText(text.length);
+                textBounds.push(new TextBounds(text, getWrapperBounds(node, scrollX, scrollY)));
+                node = replacementNode;
+            }
+        } else if (!_Feature2.default.SUPPORT_RANGE_BOUNDS) {
+            node = node.splitText(text.length);
+        }
+        offset += text.length;
+    }
+    return textBounds;
+};
+
+var getWrapperBounds = function getWrapperBounds(node, scrollX, scrollY) {
+    var wrapper = node.ownerDocument.createElement('html2canvaswrapper');
+    wrapper.appendChild(node.cloneNode(true));
+    var parentNode = node.parentNode;
+    if (parentNode) {
+        parentNode.replaceChild(wrapper, node);
+        var bounds = (0, _Bounds.parseBounds)(wrapper, scrollX, scrollY);
+        if (wrapper.firstChild) {
+            parentNode.replaceChild(wrapper.firstChild, wrapper);
+        }
+        return bounds;
+    }
+    return new _Bounds.Bounds(0, 0, 0, 0);
+};
+
+var getRangeBounds = function getRangeBounds(node, offset, length, scrollX, scrollY) {
+    var range = node.ownerDocument.createRange();
+    range.setStart(node, offset);
+    range.setEnd(node, offset + length);
+    return _Bounds.Bounds.fromClientRect(range.getBoundingClientRect(), scrollX, scrollY);
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/TextContainer.js b/AstuteClient2/src/assets/html2canvas/dist/npm/TextContainer.js
new file mode 100644
index 0000000..036155f
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/TextContainer.js
@@ -0,0 +1,59 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _textTransform = require('./parsing/textTransform');
+
+var _TextBounds = require('./TextBounds');
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var TextContainer = function () {
+    function TextContainer(text, parent, bounds) {
+        _classCallCheck(this, TextContainer);
+
+        this.text = text;
+        this.parent = parent;
+        this.bounds = bounds;
+    }
+
+    _createClass(TextContainer, null, [{
+        key: 'fromTextNode',
+        value: function fromTextNode(node, parent) {
+            var text = transform(node.data, parent.style.textTransform);
+            return new TextContainer(text, parent, (0, _TextBounds.parseTextBounds)(text, parent, node));
+        }
+    }]);
+
+    return TextContainer;
+}();
+
+exports.default = TextContainer;
+
+
+var CAPITALIZE = /(^|\s|:|-|\(|\))([a-z])/g;
+
+var transform = function transform(text, _transform) {
+    switch (_transform) {
+        case _textTransform.TEXT_TRANSFORM.LOWERCASE:
+            return text.toLowerCase();
+        case _textTransform.TEXT_TRANSFORM.CAPITALIZE:
+            return text.replace(CAPITALIZE, capitalize);
+        case _textTransform.TEXT_TRANSFORM.UPPERCASE:
+            return text.toUpperCase();
+        default:
+            return text;
+    }
+};
+
+function capitalize(m, p1, p2) {
+    if (m.length > 0) {
+        return p1 + p2.toUpperCase();
+    }
+
+    return m;
+}
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/Unicode.js b/AstuteClient2/src/assets/html2canvas/dist/npm/Unicode.js
new file mode 100644
index 0000000..a93c798
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/Unicode.js
@@ -0,0 +1,45 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.breakWords = exports.fromCodePoint = exports.toCodePoints = undefined;
+
+var _cssLineBreak = require('css-line-break');
+
+Object.defineProperty(exports, 'toCodePoints', {
+    enumerable: true,
+    get: function get() {
+        return _cssLineBreak.toCodePoints;
+    }
+});
+Object.defineProperty(exports, 'fromCodePoint', {
+    enumerable: true,
+    get: function get() {
+        return _cssLineBreak.fromCodePoint;
+    }
+});
+
+var _NodeContainer = require('./NodeContainer');
+
+var _NodeContainer2 = _interopRequireDefault(_NodeContainer);
+
+var _overflowWrap = require('./parsing/overflowWrap');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var breakWords = exports.breakWords = function breakWords(str, parent) {
+    var breaker = (0, _cssLineBreak.LineBreaker)(str, {
+        lineBreak: parent.style.lineBreak,
+        wordBreak: parent.style.overflowWrap === _overflowWrap.OVERFLOW_WRAP.BREAK_WORD ? 'break-word' : parent.style.wordBreak
+    });
+
+    var words = [];
+    var bk = void 0;
+
+    while (!(bk = breaker.next()).done) {
+        words.push(bk.value.slice());
+    }
+
+    return words;
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/Util.js b/AstuteClient2/src/assets/html2canvas/dist/npm/Util.js
new file mode 100644
index 0000000..6b2f8c1
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/Util.js
@@ -0,0 +1,26 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var contains = exports.contains = function contains(bit, value) {
+    return (bit & value) !== 0;
+};
+
+var distance = exports.distance = function distance(a, b) {
+    return Math.sqrt(a * a + b * b);
+};
+
+var copyCSSStyles = exports.copyCSSStyles = function copyCSSStyles(style, target) {
+    // Edge does not provide value for cssText
+    for (var i = style.length - 1; i >= 0; i--) {
+        var property = style.item(i);
+        // Safari shows pseudoelements if content is set
+        if (property !== 'content') {
+            target.style.setProperty(property, style.getPropertyValue(property));
+        }
+    }
+    return target;
+};
+
+var SMALL_IMAGE = exports.SMALL_IMAGE = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/Window.js b/AstuteClient2/src/assets/html2canvas/dist/npm/Window.js
new file mode 100644
index 0000000..352a369
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/Window.js
@@ -0,0 +1,157 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.renderElement = undefined;
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var _Logger = require('./Logger');
+
+var _Logger2 = _interopRequireDefault(_Logger);
+
+var _NodeParser = require('./NodeParser');
+
+var _Renderer = require('./Renderer');
+
+var _Renderer2 = _interopRequireDefault(_Renderer);
+
+var _ForeignObjectRenderer = require('./renderer/ForeignObjectRenderer');
+
+var _ForeignObjectRenderer2 = _interopRequireDefault(_ForeignObjectRenderer);
+
+var _Feature = require('./Feature');
+
+var _Feature2 = _interopRequireDefault(_Feature);
+
+var _Bounds = require('./Bounds');
+
+var _Clone = require('./Clone');
+
+var _Font = require('./Font');
+
+var _Color = require('./Color');
+
+var _Color2 = _interopRequireDefault(_Color);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var renderElement = exports.renderElement = function renderElement(element, options, logger) {
+    var ownerDocument = element.ownerDocument;
+
+    var windowBounds = new _Bounds.Bounds(options.scrollX, options.scrollY, options.windowWidth, options.windowHeight);
+
+    // http://www.w3.org/TR/css3-background/#special-backgrounds
+    var documentBackgroundColor = ownerDocument.documentElement ? new _Color2.default(getComputedStyle(ownerDocument.documentElement).backgroundColor) : _Color.TRANSPARENT;
+    var bodyBackgroundColor = ownerDocument.body ? new _Color2.default(getComputedStyle(ownerDocument.body).backgroundColor) : _Color.TRANSPARENT;
+
+    var backgroundColor = element === ownerDocument.documentElement ? documentBackgroundColor.isTransparent() ? bodyBackgroundColor.isTransparent() ? options.backgroundColor ? new _Color2.default(options.backgroundColor) : null : bodyBackgroundColor : documentBackgroundColor : options.backgroundColor ? new _Color2.default(options.backgroundColor) : null;
+
+    return (options.foreignObjectRendering ? // $FlowFixMe
+    _Feature2.default.SUPPORT_FOREIGNOBJECT_DRAWING : Promise.resolve(false)).then(function (supportForeignObject) {
+        return supportForeignObject ? function (cloner) {
+            if (process.env.NODE_ENV !== 'production') {
+                logger.log('Document cloned, using foreignObject rendering');
+            }
+
+            return cloner.inlineFonts(ownerDocument).then(function () {
+                return cloner.resourceLoader.ready();
+            }).then(function () {
+                var renderer = new _ForeignObjectRenderer2.default(cloner.documentElement);
+
+                var defaultView = ownerDocument.defaultView;
+                var scrollX = defaultView.pageXOffset;
+                var scrollY = defaultView.pageYOffset;
+
+                var isDocument = element.tagName === 'HTML' || element.tagName === 'BODY';
+
+                var _ref = isDocument ? (0, _Bounds.parseDocumentSize)(ownerDocument) : (0, _Bounds.parseBounds)(element, scrollX, scrollY),
+                    width = _ref.width,
+                    height = _ref.height,
+                    left = _ref.left,
+                    top = _ref.top;
+
+                return renderer.render({
+                    backgroundColor: backgroundColor,
+                    logger: logger,
+                    scale: options.scale,
+                    x: typeof options.x === 'number' ? options.x : left,
+                    y: typeof options.y === 'number' ? options.y : top,
+                    width: typeof options.width === 'number' ? options.width : Math.ceil(width),
+                    height: typeof options.height === 'number' ? options.height : Math.ceil(height),
+                    windowWidth: options.windowWidth,
+                    windowHeight: options.windowHeight,
+                    scrollX: options.scrollX,
+                    scrollY: options.scrollY
+                });
+            });
+        }(new _Clone.DocumentCloner(element, options, logger, true, renderElement)) : (0, _Clone.cloneWindow)(ownerDocument, windowBounds, element, options, logger, renderElement).then(function (_ref2) {
+            var _ref3 = _slicedToArray(_ref2, 3),
+                container = _ref3[0],
+                clonedElement = _ref3[1],
+                resourceLoader = _ref3[2];
+
+            if (process.env.NODE_ENV !== 'production') {
+                logger.log('Document cloned, using computed rendering');
+            }
+
+            var stack = (0, _NodeParser.NodeParser)(clonedElement, resourceLoader, logger);
+            var clonedDocument = clonedElement.ownerDocument;
+
+            if (backgroundColor === stack.container.style.background.backgroundColor) {
+                stack.container.style.background.backgroundColor = _Color.TRANSPARENT;
+            }
+
+            return resourceLoader.ready().then(function (imageStore) {
+                var fontMetrics = new _Font.FontMetrics(clonedDocument);
+                if (process.env.NODE_ENV !== 'production') {
+                    logger.log('Starting renderer');
+                }
+
+                var defaultView = clonedDocument.defaultView;
+                var scrollX = defaultView.pageXOffset;
+                var scrollY = defaultView.pageYOffset;
+
+                var isDocument = clonedElement.tagName === 'HTML' || clonedElement.tagName === 'BODY';
+
+                var _ref4 = isDocument ? (0, _Bounds.parseDocumentSize)(ownerDocument) : (0, _Bounds.parseBounds)(clonedElement, scrollX, scrollY),
+                    width = _ref4.width,
+                    height = _ref4.height,
+                    left = _ref4.left,
+                    top = _ref4.top;
+
+                var renderOptions = {
+                    backgroundColor: backgroundColor,
+                    fontMetrics: fontMetrics,
+                    imageStore: imageStore,
+                    logger: logger,
+                    scale: options.scale,
+                    x: typeof options.x === 'number' ? options.x : left,
+                    y: typeof options.y === 'number' ? options.y : top,
+                    width: typeof options.width === 'number' ? options.width : Math.ceil(width),
+                    height: typeof options.height === 'number' ? options.height : Math.ceil(height)
+                };
+
+                if (Array.isArray(options.target)) {
+                    return Promise.all(options.target.map(function (target) {
+                        var renderer = new _Renderer2.default(target, renderOptions);
+                        return renderer.render(stack);
+                    }));
+                } else {
+                    var renderer = new _Renderer2.default(options.target, renderOptions);
+                    var canvas = renderer.render(stack);
+                    if (options.removeContainer === true) {
+                        if (container.parentNode) {
+                            container.parentNode.removeChild(container);
+                        } else if (process.env.NODE_ENV !== 'production') {
+                            logger.log('Cannot detach cloned iframe as it is not in the DOM anymore');
+                        }
+                    }
+
+                    return canvas;
+                }
+            });
+        });
+    });
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/drawing/BezierCurve.js b/AstuteClient2/src/assets/html2canvas/dist/npm/drawing/BezierCurve.js
new file mode 100644
index 0000000..18cf9ff
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/drawing/BezierCurve.js
@@ -0,0 +1,55 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Path = require('./Path');
+
+var _Vector = require('./Vector');
+
+var _Vector2 = _interopRequireDefault(_Vector);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var lerp = function lerp(a, b, t) {
+    return new _Vector2.default(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t);
+};
+
+var BezierCurve = function () {
+    function BezierCurve(start, startControl, endControl, end) {
+        _classCallCheck(this, BezierCurve);
+
+        this.type = _Path.PATH.BEZIER_CURVE;
+        this.start = start;
+        this.startControl = startControl;
+        this.endControl = endControl;
+        this.end = end;
+    }
+
+    _createClass(BezierCurve, [{
+        key: 'subdivide',
+        value: function subdivide(t, firstHalf) {
+            var ab = lerp(this.start, this.startControl, t);
+            var bc = lerp(this.startControl, this.endControl, t);
+            var cd = lerp(this.endControl, this.end, t);
+            var abbc = lerp(ab, bc, t);
+            var bccd = lerp(bc, cd, t);
+            var dest = lerp(abbc, bccd, t);
+            return firstHalf ? new BezierCurve(this.start, ab, abbc, dest) : new BezierCurve(dest, bccd, cd, this.end);
+        }
+    }, {
+        key: 'reverse',
+        value: function reverse() {
+            return new BezierCurve(this.end, this.endControl, this.startControl, this.start);
+        }
+    }]);
+
+    return BezierCurve;
+}();
+
+exports.default = BezierCurve;
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/drawing/Circle.js b/AstuteClient2/src/assets/html2canvas/dist/npm/drawing/Circle.js
new file mode 100644
index 0000000..c79b92e
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/drawing/Circle.js
@@ -0,0 +1,31 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _Path = require('./Path');
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Circle = function Circle(x, y, radius) {
+    _classCallCheck(this, Circle);
+
+    this.type = _Path.PATH.CIRCLE;
+    this.x = x;
+    this.y = y;
+    this.radius = radius;
+    if (process.env.NODE_ENV !== 'production') {
+        if (isNaN(x)) {
+            console.error('Invalid x value given for Circle');
+        }
+        if (isNaN(y)) {
+            console.error('Invalid y value given for Circle');
+        }
+        if (isNaN(radius)) {
+            console.error('Invalid radius value given for Circle');
+        }
+    }
+};
+
+exports.default = Circle;
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/drawing/Path.js b/AstuteClient2/src/assets/html2canvas/dist/npm/drawing/Path.js
new file mode 100644
index 0000000..06abd74
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/drawing/Path.js
@@ -0,0 +1,10 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var PATH = exports.PATH = {
+    VECTOR: 0,
+    BEZIER_CURVE: 1,
+    CIRCLE: 2
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/drawing/Size.js b/AstuteClient2/src/assets/html2canvas/dist/npm/drawing/Size.js
new file mode 100644
index 0000000..6c2abba
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/drawing/Size.js
@@ -0,0 +1,16 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Size = function Size(width, height) {
+    _classCallCheck(this, Size);
+
+    this.width = width;
+    this.height = height;
+};
+
+exports.default = Size;
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/drawing/Vector.js b/AstuteClient2/src/assets/html2canvas/dist/npm/drawing/Vector.js
new file mode 100644
index 0000000..01e2d55
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/drawing/Vector.js
@@ -0,0 +1,27 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _Path = require('./Path');
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Vector = function Vector(x, y) {
+    _classCallCheck(this, Vector);
+
+    this.type = _Path.PATH.VECTOR;
+    this.x = x;
+    this.y = y;
+    if (process.env.NODE_ENV !== 'production') {
+        if (isNaN(x)) {
+            console.error('Invalid x value given for Vector');
+        }
+        if (isNaN(y)) {
+            console.error('Invalid y value given for Vector');
+        }
+    }
+};
+
+exports.default = Vector;
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/index.js b/AstuteClient2/src/assets/html2canvas/dist/npm/index.js
new file mode 100644
index 0000000..5c34fb4
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/index.js
@@ -0,0 +1,63 @@
+'use strict';
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+var _CanvasRenderer = require('./renderer/CanvasRenderer');
+
+var _CanvasRenderer2 = _interopRequireDefault(_CanvasRenderer);
+
+var _Logger = require('./Logger');
+
+var _Logger2 = _interopRequireDefault(_Logger);
+
+var _Window = require('./Window');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var html2canvas = function html2canvas(element, conf) {
+    var config = conf || {};
+    var logger = new _Logger2.default(typeof config.logging === 'boolean' ? config.logging : true);
+    logger.log('html2canvas ' + "$npm_package_version");
+
+    if (process.env.NODE_ENV !== 'production' && typeof config.onrendered === 'function') {
+        logger.error('onrendered option is deprecated, html2canvas returns a Promise with the canvas as the value');
+    }
+
+    var ownerDocument = element.ownerDocument;
+    if (!ownerDocument) {
+        return Promise.reject('Provided element is not within a Document');
+    }
+    var defaultView = ownerDocument.defaultView;
+
+    var defaultOptions = {
+        async: true,
+        allowTaint: false,
+        backgroundColor: '#ffffff',
+        imageTimeout: 15000,
+        logging: true,
+        proxy: null,
+        removeContainer: true,
+        foreignObjectRendering: false,
+        scale: defaultView.devicePixelRatio || 1,
+        target: new _CanvasRenderer2.default(config.canvas),
+        useCORS: false,
+        windowWidth: defaultView.innerWidth,
+        windowHeight: defaultView.innerHeight,
+        scrollX: defaultView.pageXOffset,
+        scrollY: defaultView.pageYOffset
+    };
+
+    var result = (0, _Window.renderElement)(element, _extends({}, defaultOptions, config), logger);
+
+    if (process.env.NODE_ENV !== 'production') {
+        return result.catch(function (e) {
+            logger.error(e);
+            throw e;
+        });
+    }
+    return result;
+};
+
+html2canvas.CanvasRenderer = _CanvasRenderer2.default;
+
+module.exports = html2canvas;
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/background.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/background.js
new file mode 100644
index 0000000..2a5a302
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/background.js
@@ -0,0 +1,353 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseBackgroundImage = exports.parseBackground = exports.calculateBackgroundRepeatPath = exports.calculateBackgroundPosition = exports.calculateBackgroungPositioningArea = exports.calculateBackgroungPaintingArea = exports.calculateGradientBackgroundSize = exports.calculateBackgroundSize = exports.BACKGROUND_ORIGIN = exports.BACKGROUND_CLIP = exports.BACKGROUND_SIZE = exports.BACKGROUND_REPEAT = undefined;
+
+var _Color = require('../Color');
+
+var _Color2 = _interopRequireDefault(_Color);
+
+var _Length = require('../Length');
+
+var _Length2 = _interopRequireDefault(_Length);
+
+var _Size = require('../drawing/Size');
+
+var _Size2 = _interopRequireDefault(_Size);
+
+var _Vector = require('../drawing/Vector');
+
+var _Vector2 = _interopRequireDefault(_Vector);
+
+var _Bounds = require('../Bounds');
+
+var _padding = require('./padding');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var BACKGROUND_REPEAT = exports.BACKGROUND_REPEAT = {
+    REPEAT: 0,
+    NO_REPEAT: 1,
+    REPEAT_X: 2,
+    REPEAT_Y: 3
+};
+
+var BACKGROUND_SIZE = exports.BACKGROUND_SIZE = {
+    AUTO: 0,
+    CONTAIN: 1,
+    COVER: 2,
+    LENGTH: 3
+};
+
+var BACKGROUND_CLIP = exports.BACKGROUND_CLIP = {
+    BORDER_BOX: 0,
+    PADDING_BOX: 1,
+    CONTENT_BOX: 2
+};
+
+var BACKGROUND_ORIGIN = exports.BACKGROUND_ORIGIN = BACKGROUND_CLIP;
+
+var AUTO = 'auto';
+
+var BackgroundSize = function BackgroundSize(size) {
+    _classCallCheck(this, BackgroundSize);
+
+    switch (size) {
+        case 'contain':
+            this.size = BACKGROUND_SIZE.CONTAIN;
+            break;
+        case 'cover':
+            this.size = BACKGROUND_SIZE.COVER;
+            break;
+        case 'auto':
+            this.size = BACKGROUND_SIZE.AUTO;
+            break;
+        default:
+            this.value = new _Length2.default(size);
+    }
+};
+
+var calculateBackgroundSize = exports.calculateBackgroundSize = function calculateBackgroundSize(backgroundImage, image, bounds) {
+    var width = 0;
+    var height = 0;
+    var size = backgroundImage.size;
+    if (size[0].size === BACKGROUND_SIZE.CONTAIN || size[0].size === BACKGROUND_SIZE.COVER) {
+        var targetRatio = bounds.width / bounds.height;
+        var currentRatio = image.width / image.height;
+        return targetRatio < currentRatio !== (size[0].size === BACKGROUND_SIZE.COVER) ? new _Size2.default(bounds.width, bounds.width / currentRatio) : new _Size2.default(bounds.height * currentRatio, bounds.height);
+    }
+
+    if (size[0].value) {
+        width = size[0].value.getAbsoluteValue(bounds.width);
+    }
+
+    if (size[0].size === BACKGROUND_SIZE.AUTO && size[1].size === BACKGROUND_SIZE.AUTO) {
+        height = image.height;
+    } else if (size[1].size === BACKGROUND_SIZE.AUTO) {
+        height = width / image.width * image.height;
+    } else if (size[1].value) {
+        height = size[1].value.getAbsoluteValue(bounds.height);
+    }
+
+    if (size[0].size === BACKGROUND_SIZE.AUTO) {
+        width = height / image.height * image.width;
+    }
+
+    return new _Size2.default(width, height);
+};
+
+var calculateGradientBackgroundSize = exports.calculateGradientBackgroundSize = function calculateGradientBackgroundSize(backgroundImage, bounds) {
+    var size = backgroundImage.size;
+    var width = size[0].value ? size[0].value.getAbsoluteValue(bounds.width) : bounds.width;
+    var height = size[1].value ? size[1].value.getAbsoluteValue(bounds.height) : size[0].value ? width : bounds.height;
+
+    return new _Size2.default(width, height);
+};
+
+var AUTO_SIZE = new BackgroundSize(AUTO);
+
+var calculateBackgroungPaintingArea = exports.calculateBackgroungPaintingArea = function calculateBackgroungPaintingArea(curves, clip) {
+    switch (clip) {
+        case BACKGROUND_CLIP.BORDER_BOX:
+            return (0, _Bounds.calculateBorderBoxPath)(curves);
+        case BACKGROUND_CLIP.PADDING_BOX:
+        default:
+            return (0, _Bounds.calculatePaddingBoxPath)(curves);
+    }
+};
+
+var calculateBackgroungPositioningArea = exports.calculateBackgroungPositioningArea = function calculateBackgroungPositioningArea(backgroundOrigin, bounds, padding, border) {
+    var paddingBox = (0, _Bounds.calculatePaddingBox)(bounds, border);
+
+    switch (backgroundOrigin) {
+        case BACKGROUND_ORIGIN.BORDER_BOX:
+            return bounds;
+        case BACKGROUND_ORIGIN.CONTENT_BOX:
+            var paddingLeft = padding[_padding.PADDING_SIDES.LEFT].getAbsoluteValue(bounds.width);
+            var paddingRight = padding[_padding.PADDING_SIDES.RIGHT].getAbsoluteValue(bounds.width);
+            var paddingTop = padding[_padding.PADDING_SIDES.TOP].getAbsoluteValue(bounds.width);
+            var paddingBottom = padding[_padding.PADDING_SIDES.BOTTOM].getAbsoluteValue(bounds.width);
+            return new _Bounds.Bounds(paddingBox.left + paddingLeft, paddingBox.top + paddingTop, paddingBox.width - paddingLeft - paddingRight, paddingBox.height - paddingTop - paddingBottom);
+        case BACKGROUND_ORIGIN.PADDING_BOX:
+        default:
+            return paddingBox;
+    }
+};
+
+var calculateBackgroundPosition = exports.calculateBackgroundPosition = function calculateBackgroundPosition(position, size, bounds) {
+    return new _Vector2.default(position[0].getAbsoluteValue(bounds.width - size.width), position[1].getAbsoluteValue(bounds.height - size.height));
+};
+
+var calculateBackgroundRepeatPath = exports.calculateBackgroundRepeatPath = function calculateBackgroundRepeatPath(background, position, size, backgroundPositioningArea, bounds) {
+    var repeat = background.repeat;
+    switch (repeat) {
+        case BACKGROUND_REPEAT.REPEAT_X:
+            return [new _Vector2.default(Math.round(bounds.left), Math.round(backgroundPositioningArea.top + position.y)), new _Vector2.default(Math.round(bounds.left + bounds.width), Math.round(backgroundPositioningArea.top + position.y)), new _Vector2.default(Math.round(bounds.left + bounds.width), Math.round(size.height + backgroundPositioningArea.top + position.y)), new _Vector2.default(Math.round(bounds.left), Math.round(size.height + backgroundPositioningArea.top + position.y))];
+        case BACKGROUND_REPEAT.REPEAT_Y:
+            return [new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x), Math.round(bounds.top)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x + size.width), Math.round(bounds.top)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x + size.width), Math.round(bounds.height + bounds.top)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x), Math.round(bounds.height + bounds.top))];
+        case BACKGROUND_REPEAT.NO_REPEAT:
+            return [new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x), Math.round(backgroundPositioningArea.top + position.y)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x + size.width), Math.round(backgroundPositioningArea.top + position.y)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x + size.width), Math.round(backgroundPositioningArea.top + position.y + size.height)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x), Math.round(backgroundPositioningArea.top + position.y + size.height))];
+        default:
+            return [new _Vector2.default(Math.round(bounds.left), Math.round(bounds.top)), new _Vector2.default(Math.round(bounds.left + bounds.width), Math.round(bounds.top)), new _Vector2.default(Math.round(bounds.left + bounds.width), Math.round(bounds.height + bounds.top)), new _Vector2.default(Math.round(bounds.left), Math.round(bounds.height + bounds.top))];
+    }
+};
+
+var parseBackground = exports.parseBackground = function parseBackground(style, resourceLoader) {
+    return {
+        backgroundColor: new _Color2.default(style.backgroundColor),
+        backgroundImage: parseBackgroundImages(style, resourceLoader),
+        backgroundClip: parseBackgroundClip(style.backgroundClip),
+        backgroundOrigin: parseBackgroundOrigin(style.backgroundOrigin)
+    };
+};
+
+var parseBackgroundClip = function parseBackgroundClip(backgroundClip) {
+    switch (backgroundClip) {
+        case 'padding-box':
+            return BACKGROUND_CLIP.PADDING_BOX;
+        case 'content-box':
+            return BACKGROUND_CLIP.CONTENT_BOX;
+    }
+    return BACKGROUND_CLIP.BORDER_BOX;
+};
+
+var parseBackgroundOrigin = function parseBackgroundOrigin(backgroundOrigin) {
+    switch (backgroundOrigin) {
+        case 'padding-box':
+            return BACKGROUND_ORIGIN.PADDING_BOX;
+        case 'content-box':
+            return BACKGROUND_ORIGIN.CONTENT_BOX;
+    }
+    return BACKGROUND_ORIGIN.BORDER_BOX;
+};
+
+var parseBackgroundRepeat = function parseBackgroundRepeat(backgroundRepeat) {
+    switch (backgroundRepeat.trim()) {
+        case 'no-repeat':
+            return BACKGROUND_REPEAT.NO_REPEAT;
+        case 'repeat-x':
+        case 'repeat no-repeat':
+            return BACKGROUND_REPEAT.REPEAT_X;
+        case 'repeat-y':
+        case 'no-repeat repeat':
+            return BACKGROUND_REPEAT.REPEAT_Y;
+        case 'repeat':
+            return BACKGROUND_REPEAT.REPEAT;
+    }
+
+    if (process.env.NODE_ENV !== 'production') {
+        console.error('Invalid background-repeat value "' + backgroundRepeat + '"');
+    }
+
+    return BACKGROUND_REPEAT.REPEAT;
+};
+
+var parseBackgroundImages = function parseBackgroundImages(style, resourceLoader) {
+    var sources = parseBackgroundImage(style.backgroundImage).map(function (backgroundImage) {
+        if (backgroundImage.method === 'url') {
+            var key = resourceLoader.loadImage(backgroundImage.args[0]);
+            backgroundImage.args = key ? [key] : [];
+        }
+        return backgroundImage;
+    });
+    var positions = style.backgroundPosition.split(',');
+    var repeats = style.backgroundRepeat.split(',');
+    var sizes = style.backgroundSize.split(',');
+
+    return sources.map(function (source, index) {
+        var size = (sizes[index] || AUTO).trim().split(' ').map(parseBackgroundSize);
+        var position = (positions[index] || AUTO).trim().split(' ').map(parseBackgoundPosition);
+
+        return {
+            source: source,
+            repeat: parseBackgroundRepeat(typeof repeats[index] === 'string' ? repeats[index] : repeats[0]),
+            size: size.length < 2 ? [size[0], AUTO_SIZE] : [size[0], size[1]],
+            position: position.length < 2 ? [position[0], position[0]] : [position[0], position[1]]
+        };
+    });
+};
+
+var parseBackgroundSize = function parseBackgroundSize(size) {
+    return size === 'auto' ? AUTO_SIZE : new BackgroundSize(size);
+};
+
+var parseBackgoundPosition = function parseBackgoundPosition(position) {
+    switch (position) {
+        case 'bottom':
+        case 'right':
+            return new _Length2.default('100%');
+        case 'left':
+        case 'top':
+            return new _Length2.default('0%');
+        case 'auto':
+            return new _Length2.default('0');
+    }
+    return new _Length2.default(position);
+};
+
+var parseBackgroundImage = exports.parseBackgroundImage = function parseBackgroundImage(image) {
+    var whitespace = /^\s$/;
+    var results = [];
+
+    var args = [];
+    var method = '';
+    var quote = null;
+    var definition = '';
+    var mode = 0;
+    var numParen = 0;
+
+    var appendResult = function appendResult() {
+        var prefix = '';
+        if (method) {
+            if (definition.substr(0, 1) === '"') {
+                definition = definition.substr(1, definition.length - 2);
+            }
+
+            if (definition) {
+                args.push(definition.trim());
+            }
+
+            var prefix_i = method.indexOf('-', 1) + 1;
+            if (method.substr(0, 1) === '-' && prefix_i > 0) {
+                prefix = method.substr(0, prefix_i).toLowerCase();
+                method = method.substr(prefix_i);
+            }
+            method = method.toLowerCase();
+            if (method !== 'none') {
+                results.push({
+                    prefix: prefix,
+                    method: method,
+                    args: args
+                });
+            }
+        }
+        args = [];
+        method = definition = '';
+    };
+
+    image.split('').forEach(function (c) {
+        if (mode === 0 && whitespace.test(c)) {
+            return;
+        }
+        switch (c) {
+            case '"':
+                if (!quote) {
+                    quote = c;
+                } else if (quote === c) {
+                    quote = null;
+                }
+                break;
+            case '(':
+                if (quote) {
+                    break;
+                } else if (mode === 0) {
+                    mode = 1;
+                    return;
+                } else {
+                    numParen++;
+                }
+                break;
+            case ')':
+                if (quote) {
+                    break;
+                } else if (mode === 1) {
+                    if (numParen === 0) {
+                        mode = 0;
+                        appendResult();
+                        return;
+                    } else {
+                        numParen--;
+                    }
+                }
+                break;
+
+            case ',':
+                if (quote) {
+                    break;
+                } else if (mode === 0) {
+                    appendResult();
+                    return;
+                } else if (mode === 1) {
+                    if (numParen === 0 && !method.match(/^url$/i)) {
+                        args.push(definition.trim());
+                        definition = '';
+                        return;
+                    }
+                }
+                break;
+        }
+
+        if (mode === 0) {
+            method += c;
+        } else {
+            definition += c;
+        }
+    });
+
+    appendResult();
+    return results;
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/border.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/border.js
new file mode 100644
index 0000000..6d84e83
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/border.js
@@ -0,0 +1,49 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseBorder = exports.BORDER_SIDES = exports.BORDER_STYLE = undefined;
+
+var _Color = require('../Color');
+
+var _Color2 = _interopRequireDefault(_Color);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var BORDER_STYLE = exports.BORDER_STYLE = {
+    NONE: 0,
+    SOLID: 1
+};
+
+var BORDER_SIDES = exports.BORDER_SIDES = {
+    TOP: 0,
+    RIGHT: 1,
+    BOTTOM: 2,
+    LEFT: 3
+};
+
+var SIDES = Object.keys(BORDER_SIDES).map(function (s) {
+    return s.toLowerCase();
+});
+
+var parseBorderStyle = function parseBorderStyle(style) {
+    switch (style) {
+        case 'none':
+            return BORDER_STYLE.NONE;
+    }
+    return BORDER_STYLE.SOLID;
+};
+
+var parseBorder = exports.parseBorder = function parseBorder(style) {
+    return SIDES.map(function (side) {
+        var borderColor = new _Color2.default(style.getPropertyValue('border-' + side + '-color'));
+        var borderStyle = parseBorderStyle(style.getPropertyValue('border-' + side + '-style'));
+        var borderWidth = parseFloat(style.getPropertyValue('border-' + side + '-width'));
+        return {
+            borderColor: borderColor,
+            borderStyle: borderStyle,
+            borderWidth: isNaN(borderWidth) ? 0 : borderWidth
+        };
+    });
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/borderRadius.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/borderRadius.js
new file mode 100644
index 0000000..b53b598
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/borderRadius.js
@@ -0,0 +1,29 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseBorderRadius = undefined;
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var _Length = require('../Length');
+
+var _Length2 = _interopRequireDefault(_Length);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var SIDES = ['top-left', 'top-right', 'bottom-right', 'bottom-left'];
+
+var parseBorderRadius = exports.parseBorderRadius = function parseBorderRadius(style) {
+    return SIDES.map(function (side) {
+        var value = style.getPropertyValue('border-' + side + '-radius');
+
+        var _value$split$map = value.split(' ').map(_Length2.default.create),
+            _value$split$map2 = _slicedToArray(_value$split$map, 2),
+            horizontal = _value$split$map2[0],
+            vertical = _value$split$map2[1];
+
+        return typeof vertical === 'undefined' ? [horizontal, horizontal] : [horizontal, vertical];
+    });
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/display.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/display.js
new file mode 100644
index 0000000..0b1d418
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/display.js
@@ -0,0 +1,110 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var DISPLAY = exports.DISPLAY = {
+    NONE: 1 << 0,
+    BLOCK: 1 << 1,
+    INLINE: 1 << 2,
+    RUN_IN: 1 << 3,
+    FLOW: 1 << 4,
+    FLOW_ROOT: 1 << 5,
+    TABLE: 1 << 6,
+    FLEX: 1 << 7,
+    GRID: 1 << 8,
+    RUBY: 1 << 9,
+    SUBGRID: 1 << 10,
+    LIST_ITEM: 1 << 11,
+    TABLE_ROW_GROUP: 1 << 12,
+    TABLE_HEADER_GROUP: 1 << 13,
+    TABLE_FOOTER_GROUP: 1 << 14,
+    TABLE_ROW: 1 << 15,
+    TABLE_CELL: 1 << 16,
+    TABLE_COLUMN_GROUP: 1 << 17,
+    TABLE_COLUMN: 1 << 18,
+    TABLE_CAPTION: 1 << 19,
+    RUBY_BASE: 1 << 20,
+    RUBY_TEXT: 1 << 21,
+    RUBY_BASE_CONTAINER: 1 << 22,
+    RUBY_TEXT_CONTAINER: 1 << 23,
+    CONTENTS: 1 << 24,
+    INLINE_BLOCK: 1 << 25,
+    INLINE_LIST_ITEM: 1 << 26,
+    INLINE_TABLE: 1 << 27,
+    INLINE_FLEX: 1 << 28,
+    INLINE_GRID: 1 << 29
+};
+
+var parseDisplayValue = function parseDisplayValue(display) {
+    switch (display) {
+        case 'block':
+            return DISPLAY.BLOCK;
+        case 'inline':
+            return DISPLAY.INLINE;
+        case 'run-in':
+            return DISPLAY.RUN_IN;
+        case 'flow':
+            return DISPLAY.FLOW;
+        case 'flow-root':
+            return DISPLAY.FLOW_ROOT;
+        case 'table':
+            return DISPLAY.TABLE;
+        case 'flex':
+            return DISPLAY.FLEX;
+        case 'grid':
+            return DISPLAY.GRID;
+        case 'ruby':
+            return DISPLAY.RUBY;
+        case 'subgrid':
+            return DISPLAY.SUBGRID;
+        case 'list-item':
+            return DISPLAY.LIST_ITEM;
+        case 'table-row-group':
+            return DISPLAY.TABLE_ROW_GROUP;
+        case 'table-header-group':
+            return DISPLAY.TABLE_HEADER_GROUP;
+        case 'table-footer-group':
+            return DISPLAY.TABLE_FOOTER_GROUP;
+        case 'table-row':
+            return DISPLAY.TABLE_ROW;
+        case 'table-cell':
+            return DISPLAY.TABLE_CELL;
+        case 'table-column-group':
+            return DISPLAY.TABLE_COLUMN_GROUP;
+        case 'table-column':
+            return DISPLAY.TABLE_COLUMN;
+        case 'table-caption':
+            return DISPLAY.TABLE_CAPTION;
+        case 'ruby-base':
+            return DISPLAY.RUBY_BASE;
+        case 'ruby-text':
+            return DISPLAY.RUBY_TEXT;
+        case 'ruby-base-container':
+            return DISPLAY.RUBY_BASE_CONTAINER;
+        case 'ruby-text-container':
+            return DISPLAY.RUBY_TEXT_CONTAINER;
+        case 'contents':
+            return DISPLAY.CONTENTS;
+        case 'inline-block':
+            return DISPLAY.INLINE_BLOCK;
+        case 'inline-list-item':
+            return DISPLAY.INLINE_LIST_ITEM;
+        case 'inline-table':
+            return DISPLAY.INLINE_TABLE;
+        case 'inline-flex':
+            return DISPLAY.INLINE_FLEX;
+        case 'inline-grid':
+            return DISPLAY.INLINE_GRID;
+    }
+
+    return DISPLAY.NONE;
+};
+
+var setDisplayBit = function setDisplayBit(bit, display) {
+    return bit | parseDisplayValue(display);
+};
+
+var parseDisplay = exports.parseDisplay = function parseDisplay(display) {
+    return display.split(' ').reduce(setDisplayBit, 0);
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/float.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/float.js
new file mode 100644
index 0000000..cb74e34
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/float.js
@@ -0,0 +1,26 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var FLOAT = exports.FLOAT = {
+    NONE: 0,
+    LEFT: 1,
+    RIGHT: 2,
+    INLINE_START: 3,
+    INLINE_END: 4
+};
+
+var parseCSSFloat = exports.parseCSSFloat = function parseCSSFloat(float) {
+    switch (float) {
+        case 'left':
+            return FLOAT.LEFT;
+        case 'right':
+            return FLOAT.RIGHT;
+        case 'inline-start':
+            return FLOAT.INLINE_START;
+        case 'inline-end':
+            return FLOAT.INLINE_END;
+    }
+    return FLOAT.NONE;
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/font.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/font.js
new file mode 100644
index 0000000..69908ee
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/font.js
@@ -0,0 +1,34 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+
+var parseFontWeight = function parseFontWeight(weight) {
+    switch (weight) {
+        case 'normal':
+            return 400;
+        case 'bold':
+            return 700;
+    }
+
+    var value = parseInt(weight, 10);
+    return isNaN(value) ? 400 : value;
+};
+
+var parseFont = exports.parseFont = function parseFont(style) {
+    var fontFamily = style.fontFamily;
+    var fontSize = style.fontSize;
+    var fontStyle = style.fontStyle;
+    var fontVariant = style.fontVariant;
+    var fontWeight = parseFontWeight(style.fontWeight);
+
+    return {
+        fontFamily: fontFamily,
+        fontSize: fontSize,
+        fontStyle: fontStyle,
+        fontVariant: fontVariant,
+        fontWeight: fontWeight
+    };
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/letterSpacing.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/letterSpacing.js
new file mode 100644
index 0000000..040675d
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/letterSpacing.js
@@ -0,0 +1,12 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var parseLetterSpacing = exports.parseLetterSpacing = function parseLetterSpacing(letterSpacing) {
+    if (letterSpacing === 'normal') {
+        return 0;
+    }
+    var value = parseFloat(letterSpacing);
+    return isNaN(value) ? 0 : value;
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/lineBreak.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/lineBreak.js
new file mode 100644
index 0000000..51305cd
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/lineBreak.js
@@ -0,0 +1,19 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var LINE_BREAK = exports.LINE_BREAK = {
+    NORMAL: 'normal',
+    STRICT: 'strict'
+};
+
+var parseLineBreak = exports.parseLineBreak = function parseLineBreak(wordBreak) {
+    switch (wordBreak) {
+        case 'strict':
+            return LINE_BREAK.STRICT;
+        case 'normal':
+        default:
+            return LINE_BREAK.NORMAL;
+    }
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/listStyle.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/listStyle.js
new file mode 100644
index 0000000..85774a2
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/listStyle.js
@@ -0,0 +1,203 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseListStyle = exports.parseListStyleType = exports.LIST_STYLE_TYPE = exports.LIST_STYLE_POSITION = undefined;
+
+var _background = require('./background');
+
+var LIST_STYLE_POSITION = exports.LIST_STYLE_POSITION = {
+    INSIDE: 0,
+    OUTSIDE: 1
+};
+
+var LIST_STYLE_TYPE = exports.LIST_STYLE_TYPE = {
+    NONE: -1,
+    DISC: 0,
+    CIRCLE: 1,
+    SQUARE: 2,
+    DECIMAL: 3,
+    CJK_DECIMAL: 4,
+    DECIMAL_LEADING_ZERO: 5,
+    LOWER_ROMAN: 6,
+    UPPER_ROMAN: 7,
+    LOWER_GREEK: 8,
+    LOWER_ALPHA: 9,
+    UPPER_ALPHA: 10,
+    ARABIC_INDIC: 11,
+    ARMENIAN: 12,
+    BENGALI: 13,
+    CAMBODIAN: 14,
+    CJK_EARTHLY_BRANCH: 15,
+    CJK_HEAVENLY_STEM: 16,
+    CJK_IDEOGRAPHIC: 17,
+    DEVANAGARI: 18,
+    ETHIOPIC_NUMERIC: 19,
+    GEORGIAN: 20,
+    GUJARATI: 21,
+    GURMUKHI: 22,
+    HEBREW: 22,
+    HIRAGANA: 23,
+    HIRAGANA_IROHA: 24,
+    JAPANESE_FORMAL: 25,
+    JAPANESE_INFORMAL: 26,
+    KANNADA: 27,
+    KATAKANA: 28,
+    KATAKANA_IROHA: 29,
+    KHMER: 30,
+    KOREAN_HANGUL_FORMAL: 31,
+    KOREAN_HANJA_FORMAL: 32,
+    KOREAN_HANJA_INFORMAL: 33,
+    LAO: 34,
+    LOWER_ARMENIAN: 35,
+    MALAYALAM: 36,
+    MONGOLIAN: 37,
+    MYANMAR: 38,
+    ORIYA: 39,
+    PERSIAN: 40,
+    SIMP_CHINESE_FORMAL: 41,
+    SIMP_CHINESE_INFORMAL: 42,
+    TAMIL: 43,
+    TELUGU: 44,
+    THAI: 45,
+    TIBETAN: 46,
+    TRAD_CHINESE_FORMAL: 47,
+    TRAD_CHINESE_INFORMAL: 48,
+    UPPER_ARMENIAN: 49,
+    DISCLOSURE_OPEN: 50,
+    DISCLOSURE_CLOSED: 51
+};
+
+var parseListStyleType = exports.parseListStyleType = function parseListStyleType(type) {
+    switch (type) {
+        case 'disc':
+            return LIST_STYLE_TYPE.DISC;
+        case 'circle':
+            return LIST_STYLE_TYPE.CIRCLE;
+        case 'square':
+            return LIST_STYLE_TYPE.SQUARE;
+        case 'decimal':
+            return LIST_STYLE_TYPE.DECIMAL;
+        case 'cjk-decimal':
+            return LIST_STYLE_TYPE.CJK_DECIMAL;
+        case 'decimal-leading-zero':
+            return LIST_STYLE_TYPE.DECIMAL_LEADING_ZERO;
+        case 'lower-roman':
+            return LIST_STYLE_TYPE.LOWER_ROMAN;
+        case 'upper-roman':
+            return LIST_STYLE_TYPE.UPPER_ROMAN;
+        case 'lower-greek':
+            return LIST_STYLE_TYPE.LOWER_GREEK;
+        case 'lower-alpha':
+            return LIST_STYLE_TYPE.LOWER_ALPHA;
+        case 'upper-alpha':
+            return LIST_STYLE_TYPE.UPPER_ALPHA;
+        case 'arabic-indic':
+            return LIST_STYLE_TYPE.ARABIC_INDIC;
+        case 'armenian':
+            return LIST_STYLE_TYPE.ARMENIAN;
+        case 'bengali':
+            return LIST_STYLE_TYPE.BENGALI;
+        case 'cambodian':
+            return LIST_STYLE_TYPE.CAMBODIAN;
+        case 'cjk-earthly-branch':
+            return LIST_STYLE_TYPE.CJK_EARTHLY_BRANCH;
+        case 'cjk-heavenly-stem':
+            return LIST_STYLE_TYPE.CJK_HEAVENLY_STEM;
+        case 'cjk-ideographic':
+            return LIST_STYLE_TYPE.CJK_IDEOGRAPHIC;
+        case 'devanagari':
+            return LIST_STYLE_TYPE.DEVANAGARI;
+        case 'ethiopic-numeric':
+            return LIST_STYLE_TYPE.ETHIOPIC_NUMERIC;
+        case 'georgian':
+            return LIST_STYLE_TYPE.GEORGIAN;
+        case 'gujarati':
+            return LIST_STYLE_TYPE.GUJARATI;
+        case 'gurmukhi':
+            return LIST_STYLE_TYPE.GURMUKHI;
+        case 'hebrew':
+            return LIST_STYLE_TYPE.HEBREW;
+        case 'hiragana':
+            return LIST_STYLE_TYPE.HIRAGANA;
+        case 'hiragana-iroha':
+            return LIST_STYLE_TYPE.HIRAGANA_IROHA;
+        case 'japanese-formal':
+            return LIST_STYLE_TYPE.JAPANESE_FORMAL;
+        case 'japanese-informal':
+            return LIST_STYLE_TYPE.JAPANESE_INFORMAL;
+        case 'kannada':
+            return LIST_STYLE_TYPE.KANNADA;
+        case 'katakana':
+            return LIST_STYLE_TYPE.KATAKANA;
+        case 'katakana-iroha':
+            return LIST_STYLE_TYPE.KATAKANA_IROHA;
+        case 'khmer':
+            return LIST_STYLE_TYPE.KHMER;
+        case 'korean-hangul-formal':
+            return LIST_STYLE_TYPE.KOREAN_HANGUL_FORMAL;
+        case 'korean-hanja-formal':
+            return LIST_STYLE_TYPE.KOREAN_HANJA_FORMAL;
+        case 'korean-hanja-informal':
+            return LIST_STYLE_TYPE.KOREAN_HANJA_INFORMAL;
+        case 'lao':
+            return LIST_STYLE_TYPE.LAO;
+        case 'lower-armenian':
+            return LIST_STYLE_TYPE.LOWER_ARMENIAN;
+        case 'malayalam':
+            return LIST_STYLE_TYPE.MALAYALAM;
+        case 'mongolian':
+            return LIST_STYLE_TYPE.MONGOLIAN;
+        case 'myanmar':
+            return LIST_STYLE_TYPE.MYANMAR;
+        case 'oriya':
+            return LIST_STYLE_TYPE.ORIYA;
+        case 'persian':
+            return LIST_STYLE_TYPE.PERSIAN;
+        case 'simp-chinese-formal':
+            return LIST_STYLE_TYPE.SIMP_CHINESE_FORMAL;
+        case 'simp-chinese-informal':
+            return LIST_STYLE_TYPE.SIMP_CHINESE_INFORMAL;
+        case 'tamil':
+            return LIST_STYLE_TYPE.TAMIL;
+        case 'telugu':
+            return LIST_STYLE_TYPE.TELUGU;
+        case 'thai':
+            return LIST_STYLE_TYPE.THAI;
+        case 'tibetan':
+            return LIST_STYLE_TYPE.TIBETAN;
+        case 'trad-chinese-formal':
+            return LIST_STYLE_TYPE.TRAD_CHINESE_FORMAL;
+        case 'trad-chinese-informal':
+            return LIST_STYLE_TYPE.TRAD_CHINESE_INFORMAL;
+        case 'upper-armenian':
+            return LIST_STYLE_TYPE.UPPER_ARMENIAN;
+        case 'disclosure-open':
+            return LIST_STYLE_TYPE.DISCLOSURE_OPEN;
+        case 'disclosure-closed':
+            return LIST_STYLE_TYPE.DISCLOSURE_CLOSED;
+        case 'none':
+        default:
+            return LIST_STYLE_TYPE.NONE;
+    }
+};
+
+var parseListStyle = exports.parseListStyle = function parseListStyle(style) {
+    var listStyleImage = (0, _background.parseBackgroundImage)(style.getPropertyValue('list-style-image'));
+    return {
+        listStyleType: parseListStyleType(style.getPropertyValue('list-style-type')),
+        listStyleImage: listStyleImage.length ? listStyleImage[0] : null,
+        listStylePosition: parseListStylePosition(style.getPropertyValue('list-style-position'))
+    };
+};
+
+var parseListStylePosition = function parseListStylePosition(position) {
+    switch (position) {
+        case 'inside':
+            return LIST_STYLE_POSITION.INSIDE;
+        case 'outside':
+        default:
+            return LIST_STYLE_POSITION.OUTSIDE;
+    }
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/margin.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/margin.js
new file mode 100644
index 0000000..76320a1
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/margin.js
@@ -0,0 +1,20 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseMargin = undefined;
+
+var _Length = require('../Length');
+
+var _Length2 = _interopRequireDefault(_Length);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var SIDES = ['top', 'right', 'bottom', 'left'];
+
+var parseMargin = exports.parseMargin = function parseMargin(style) {
+    return SIDES.map(function (side) {
+        return new _Length2.default(style.getPropertyValue('margin-' + side));
+    });
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/overflow.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/overflow.js
new file mode 100644
index 0000000..85692ff
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/overflow.js
@@ -0,0 +1,25 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var OVERFLOW = exports.OVERFLOW = {
+    VISIBLE: 0,
+    HIDDEN: 1,
+    SCROLL: 2,
+    AUTO: 3
+};
+
+var parseOverflow = exports.parseOverflow = function parseOverflow(overflow) {
+    switch (overflow) {
+        case 'hidden':
+            return OVERFLOW.HIDDEN;
+        case 'scroll':
+            return OVERFLOW.SCROLL;
+        case 'auto':
+            return OVERFLOW.AUTO;
+        case 'visible':
+        default:
+            return OVERFLOW.VISIBLE;
+    }
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/overflowWrap.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/overflowWrap.js
new file mode 100644
index 0000000..10d7954
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/overflowWrap.js
@@ -0,0 +1,19 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var OVERFLOW_WRAP = exports.OVERFLOW_WRAP = {
+    NORMAL: 0,
+    BREAK_WORD: 1
+};
+
+var parseOverflowWrap = exports.parseOverflowWrap = function parseOverflowWrap(overflow) {
+    switch (overflow) {
+        case 'break-word':
+            return OVERFLOW_WRAP.BREAK_WORD;
+        case 'normal':
+        default:
+            return OVERFLOW_WRAP.NORMAL;
+    }
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/padding.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/padding.js
new file mode 100644
index 0000000..f0e640f
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/padding.js
@@ -0,0 +1,27 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parsePadding = exports.PADDING_SIDES = undefined;
+
+var _Length = require('../Length');
+
+var _Length2 = _interopRequireDefault(_Length);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var PADDING_SIDES = exports.PADDING_SIDES = {
+    TOP: 0,
+    RIGHT: 1,
+    BOTTOM: 2,
+    LEFT: 3
+};
+
+var SIDES = ['top', 'right', 'bottom', 'left'];
+
+var parsePadding = exports.parsePadding = function parsePadding(style) {
+    return SIDES.map(function (side) {
+        return new _Length2.default(style.getPropertyValue('padding-' + side));
+    });
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/position.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/position.js
new file mode 100644
index 0000000..a86f36c
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/position.js
@@ -0,0 +1,27 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var POSITION = exports.POSITION = {
+    STATIC: 0,
+    RELATIVE: 1,
+    ABSOLUTE: 2,
+    FIXED: 3,
+    STICKY: 4
+};
+
+var parsePosition = exports.parsePosition = function parsePosition(position) {
+    switch (position) {
+        case 'relative':
+            return POSITION.RELATIVE;
+        case 'absolute':
+            return POSITION.ABSOLUTE;
+        case 'fixed':
+            return POSITION.FIXED;
+        case 'sticky':
+            return POSITION.STICKY;
+    }
+
+    return POSITION.STATIC;
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/textDecoration.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/textDecoration.js
new file mode 100644
index 0000000..18276f1
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/textDecoration.js
@@ -0,0 +1,81 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseTextDecoration = exports.TEXT_DECORATION_LINE = exports.TEXT_DECORATION = exports.TEXT_DECORATION_STYLE = undefined;
+
+var _Color = require('../Color');
+
+var _Color2 = _interopRequireDefault(_Color);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var TEXT_DECORATION_STYLE = exports.TEXT_DECORATION_STYLE = {
+    SOLID: 0,
+    DOUBLE: 1,
+    DOTTED: 2,
+    DASHED: 3,
+    WAVY: 4
+};
+
+var TEXT_DECORATION = exports.TEXT_DECORATION = {
+    NONE: null
+};
+
+var TEXT_DECORATION_LINE = exports.TEXT_DECORATION_LINE = {
+    UNDERLINE: 1,
+    OVERLINE: 2,
+    LINE_THROUGH: 3,
+    BLINK: 4
+};
+
+var parseLine = function parseLine(line) {
+    switch (line) {
+        case 'underline':
+            return TEXT_DECORATION_LINE.UNDERLINE;
+        case 'overline':
+            return TEXT_DECORATION_LINE.OVERLINE;
+        case 'line-through':
+            return TEXT_DECORATION_LINE.LINE_THROUGH;
+    }
+    return TEXT_DECORATION_LINE.BLINK;
+};
+
+var parseTextDecorationLine = function parseTextDecorationLine(line) {
+    if (line === 'none') {
+        return null;
+    }
+
+    return line.split(' ').map(parseLine);
+};
+
+var parseTextDecorationStyle = function parseTextDecorationStyle(style) {
+    switch (style) {
+        case 'double':
+            return TEXT_DECORATION_STYLE.DOUBLE;
+        case 'dotted':
+            return TEXT_DECORATION_STYLE.DOTTED;
+        case 'dashed':
+            return TEXT_DECORATION_STYLE.DASHED;
+        case 'wavy':
+            return TEXT_DECORATION_STYLE.WAVY;
+    }
+    return TEXT_DECORATION_STYLE.SOLID;
+};
+
+var parseTextDecoration = exports.parseTextDecoration = function parseTextDecoration(style) {
+    var textDecorationLine = parseTextDecorationLine(style.textDecorationLine ? style.textDecorationLine : style.textDecoration);
+    if (textDecorationLine === null) {
+        return TEXT_DECORATION.NONE;
+    }
+
+    var textDecorationColor = style.textDecorationColor ? new _Color2.default(style.textDecorationColor) : null;
+    var textDecorationStyle = parseTextDecorationStyle(style.textDecorationStyle);
+
+    return {
+        textDecorationLine: textDecorationLine,
+        textDecorationColor: textDecorationColor,
+        textDecorationStyle: textDecorationStyle
+    };
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/textShadow.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/textShadow.js
new file mode 100644
index 0000000..5a9cd3e
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/textShadow.js
@@ -0,0 +1,95 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseTextShadow = undefined;
+
+var _Color = require('../Color');
+
+var _Color2 = _interopRequireDefault(_Color);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var NUMBER = /^([+-]|\d|\.)$/i;
+
+var parseTextShadow = exports.parseTextShadow = function parseTextShadow(textShadow) {
+    if (textShadow === 'none' || typeof textShadow !== 'string') {
+        return null;
+    }
+
+    var currentValue = '';
+    var isLength = false;
+    var values = [];
+    var shadows = [];
+    var numParens = 0;
+    var color = null;
+
+    var appendValue = function appendValue() {
+        if (currentValue.length) {
+            if (isLength) {
+                values.push(parseFloat(currentValue));
+            } else {
+                color = new _Color2.default(currentValue);
+            }
+        }
+        isLength = false;
+        currentValue = '';
+    };
+
+    var appendShadow = function appendShadow() {
+        if (values.length && color !== null) {
+            shadows.push({
+                color: color,
+                offsetX: values[0] || 0,
+                offsetY: values[1] || 0,
+                blur: values[2] || 0
+            });
+        }
+        values.splice(0, values.length);
+        color = null;
+    };
+
+    for (var i = 0; i < textShadow.length; i++) {
+        var c = textShadow[i];
+        switch (c) {
+            case '(':
+                currentValue += c;
+                numParens++;
+                break;
+            case ')':
+                currentValue += c;
+                numParens--;
+                break;
+            case ',':
+                if (numParens === 0) {
+                    appendValue();
+                    appendShadow();
+                } else {
+                    currentValue += c;
+                }
+                break;
+            case ' ':
+                if (numParens === 0) {
+                    appendValue();
+                } else {
+                    currentValue += c;
+                }
+                break;
+            default:
+                if (currentValue.length === 0 && NUMBER.test(c)) {
+                    isLength = true;
+                }
+                currentValue += c;
+        }
+    }
+
+    appendValue();
+    appendShadow();
+
+    if (shadows.length === 0) {
+        return null;
+    }
+
+    return shadows;
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/textTransform.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/textTransform.js
new file mode 100644
index 0000000..f6010e3
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/textTransform.js
@@ -0,0 +1,24 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var TEXT_TRANSFORM = exports.TEXT_TRANSFORM = {
+    NONE: 0,
+    LOWERCASE: 1,
+    UPPERCASE: 2,
+    CAPITALIZE: 3
+};
+
+var parseTextTransform = exports.parseTextTransform = function parseTextTransform(textTransform) {
+    switch (textTransform) {
+        case 'uppercase':
+            return TEXT_TRANSFORM.UPPERCASE;
+        case 'lowercase':
+            return TEXT_TRANSFORM.LOWERCASE;
+        case 'capitalize':
+            return TEXT_TRANSFORM.CAPITALIZE;
+    }
+
+    return TEXT_TRANSFORM.NONE;
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/transform.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/transform.js
new file mode 100644
index 0000000..fd992a6
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/transform.js
@@ -0,0 +1,67 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.parseTransform = undefined;
+
+var _Length = require('../Length');
+
+var _Length2 = _interopRequireDefault(_Length);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var toFloat = function toFloat(s) {
+    return parseFloat(s.trim());
+};
+
+var MATRIX = /(matrix|matrix3d)\((.+)\)/;
+
+var parseTransform = exports.parseTransform = function parseTransform(style) {
+    var transform = parseTransformMatrix(style.transform || style.webkitTransform || style.mozTransform ||
+    // $FlowFixMe
+    style.msTransform ||
+    // $FlowFixMe
+    style.oTransform);
+    if (transform === null) {
+        return null;
+    }
+
+    return {
+        transform: transform,
+        transformOrigin: parseTransformOrigin(style.transformOrigin || style.webkitTransformOrigin || style.mozTransformOrigin ||
+        // $FlowFixMe
+        style.msTransformOrigin ||
+        // $FlowFixMe
+        style.oTransformOrigin)
+    };
+};
+
+// $FlowFixMe
+var parseTransformOrigin = function parseTransformOrigin(origin) {
+    if (typeof origin !== 'string') {
+        var v = new _Length2.default('0');
+        return [v, v];
+    }
+    var values = origin.split(' ').map(_Length2.default.create);
+    return [values[0], values[1]];
+};
+
+// $FlowFixMe
+var parseTransformMatrix = function parseTransformMatrix(transform) {
+    if (transform === 'none' || typeof transform !== 'string') {
+        return null;
+    }
+
+    var match = transform.match(MATRIX);
+    if (match) {
+        if (match[1] === 'matrix') {
+            var matrix = match[2].split(',').map(toFloat);
+            return [matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]];
+        } else {
+            var matrix3d = match[2].split(',').map(toFloat);
+            return [matrix3d[0], matrix3d[1], matrix3d[4], matrix3d[5], matrix3d[12], matrix3d[13]];
+        }
+    }
+    return null;
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/visibility.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/visibility.js
new file mode 100644
index 0000000..eab52c5
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/visibility.js
@@ -0,0 +1,22 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var VISIBILITY = exports.VISIBILITY = {
+    VISIBLE: 0,
+    HIDDEN: 1,
+    COLLAPSE: 2
+};
+
+var parseVisibility = exports.parseVisibility = function parseVisibility(visibility) {
+    switch (visibility) {
+        case 'hidden':
+            return VISIBILITY.HIDDEN;
+        case 'collapse':
+            return VISIBILITY.COLLAPSE;
+        case 'visible':
+        default:
+            return VISIBILITY.VISIBLE;
+    }
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/word-break.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/word-break.js
new file mode 100644
index 0000000..0c75088
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/word-break.js
@@ -0,0 +1,22 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var WORD_BREAK = exports.WORD_BREAK = {
+    NORMAL: 'normal',
+    BREAK_ALL: 'break-all',
+    KEEP_ALL: 'keep-all'
+};
+
+var parseWordBreak = exports.parseWordBreak = function parseWordBreak(wordBreak) {
+    switch (wordBreak) {
+        case 'break-all':
+            return WORD_BREAK.BREAK_ALL;
+        case 'keep-all':
+            return WORD_BREAK.KEEP_ALL;
+        case 'normal':
+        default:
+            return WORD_BREAK.NORMAL;
+    }
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/zIndex.js b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/zIndex.js
new file mode 100644
index 0000000..3492f16
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/parsing/zIndex.js
@@ -0,0 +1,12 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var parseZIndex = exports.parseZIndex = function parseZIndex(zIndex) {
+    var auto = zIndex === 'auto';
+    return {
+        auto: auto,
+        order: auto ? 0 : parseInt(zIndex, 10)
+    };
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/renderer/CanvasRenderer.js b/AstuteClient2/src/assets/html2canvas/dist/npm/renderer/CanvasRenderer.js
new file mode 100644
index 0000000..b57c9d6
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/renderer/CanvasRenderer.js
@@ -0,0 +1,255 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _Path = require('../drawing/Path');
+
+var _textDecoration = require('../parsing/textDecoration');
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var addColorStops = function addColorStops(gradient, canvasGradient) {
+    var maxStop = Math.max.apply(null, gradient.colorStops.map(function (colorStop) {
+        return colorStop.stop;
+    }));
+    var f = 1 / Math.max(1, maxStop);
+    gradient.colorStops.forEach(function (colorStop) {
+        canvasGradient.addColorStop(f * colorStop.stop, colorStop.color.toString());
+    });
+};
+
+var CanvasRenderer = function () {
+    function CanvasRenderer(canvas) {
+        _classCallCheck(this, CanvasRenderer);
+
+        this.canvas = canvas ? canvas : document.createElement('canvas');
+    }
+
+    _createClass(CanvasRenderer, [{
+        key: 'render',
+        value: function render(options) {
+            this.ctx = this.canvas.getContext('2d');
+            this.options = options;
+            this.canvas.width = Math.floor(options.width * options.scale);
+            this.canvas.height = Math.floor(options.height * options.scale);
+            this.canvas.style.width = options.width + 'px';
+            this.canvas.style.height = options.height + 'px';
+
+            this.ctx.scale(this.options.scale, this.options.scale);
+            this.ctx.translate(-options.x, -options.y);
+            this.ctx.textBaseline = 'bottom';
+            options.logger.log('Canvas renderer initialized (' + options.width + 'x' + options.height + ' at ' + options.x + ',' + options.y + ') with scale ' + this.options.scale);
+        }
+    }, {
+        key: 'clip',
+        value: function clip(clipPaths, callback) {
+            var _this = this;
+
+            if (clipPaths.length) {
+                this.ctx.save();
+                clipPaths.forEach(function (path) {
+                    _this.path(path);
+                    _this.ctx.clip();
+                });
+            }
+
+            callback();
+
+            if (clipPaths.length) {
+                this.ctx.restore();
+            }
+        }
+    }, {
+        key: 'drawImage',
+        value: function drawImage(image, source, destination) {
+            this.ctx.drawImage(image, source.left, source.top, source.width, source.height, destination.left, destination.top, destination.width, destination.height);
+        }
+    }, {
+        key: 'drawShape',
+        value: function drawShape(path, color) {
+            this.path(path);
+            this.ctx.fillStyle = color.toString();
+            this.ctx.fill();
+        }
+    }, {
+        key: 'fill',
+        value: function fill(color) {
+            this.ctx.fillStyle = color.toString();
+            this.ctx.fill();
+        }
+    }, {
+        key: 'getTarget',
+        value: function getTarget() {
+            this.canvas.getContext('2d').setTransform(1, 0, 0, 1, 0, 0);
+            return Promise.resolve(this.canvas);
+        }
+    }, {
+        key: 'path',
+        value: function path(_path) {
+            var _this2 = this;
+
+            this.ctx.beginPath();
+            if (Array.isArray(_path)) {
+                _path.forEach(function (point, index) {
+                    var start = point.type === _Path.PATH.VECTOR ? point : point.start;
+                    if (index === 0) {
+                        _this2.ctx.moveTo(start.x, start.y);
+                    } else {
+                        _this2.ctx.lineTo(start.x, start.y);
+                    }
+
+                    if (point.type === _Path.PATH.BEZIER_CURVE) {
+                        _this2.ctx.bezierCurveTo(point.startControl.x, point.startControl.y, point.endControl.x, point.endControl.y, point.end.x, point.end.y);
+                    }
+                });
+            } else {
+                this.ctx.arc(_path.x + _path.radius, _path.y + _path.radius, _path.radius, 0, Math.PI * 2, true);
+            }
+
+            this.ctx.closePath();
+        }
+    }, {
+        key: 'rectangle',
+        value: function rectangle(x, y, width, height, color) {
+            this.ctx.fillStyle = color.toString();
+            this.ctx.fillRect(x, y, width, height);
+        }
+    }, {
+        key: 'renderLinearGradient',
+        value: function renderLinearGradient(bounds, gradient) {
+            var linearGradient = this.ctx.createLinearGradient(bounds.left + gradient.direction.x1, bounds.top + gradient.direction.y1, bounds.left + gradient.direction.x0, bounds.top + gradient.direction.y0);
+
+            addColorStops(gradient, linearGradient);
+            this.ctx.fillStyle = linearGradient;
+            this.ctx.fillRect(bounds.left, bounds.top, bounds.width, bounds.height);
+        }
+    }, {
+        key: 'renderRadialGradient',
+        value: function renderRadialGradient(bounds, gradient) {
+            var _this3 = this;
+
+            var x = bounds.left + gradient.center.x;
+            var y = bounds.top + gradient.center.y;
+
+            var radialGradient = this.ctx.createRadialGradient(x, y, 0, x, y, gradient.radius.x);
+            if (!radialGradient) {
+                return;
+            }
+
+            addColorStops(gradient, radialGradient);
+            this.ctx.fillStyle = radialGradient;
+
+            if (gradient.radius.x !== gradient.radius.y) {
+                // transforms for elliptical radial gradient
+                var midX = bounds.left + 0.5 * bounds.width;
+                var midY = bounds.top + 0.5 * bounds.height;
+                var f = gradient.radius.y / gradient.radius.x;
+                var invF = 1 / f;
+
+                this.transform(midX, midY, [1, 0, 0, f, 0, 0], function () {
+                    return _this3.ctx.fillRect(bounds.left, invF * (bounds.top - midY) + midY, bounds.width, bounds.height * invF);
+                });
+            } else {
+                this.ctx.fillRect(bounds.left, bounds.top, bounds.width, bounds.height);
+            }
+        }
+    }, {
+        key: 'renderRepeat',
+        value: function renderRepeat(path, image, imageSize, offsetX, offsetY) {
+            this.path(path);
+            this.ctx.fillStyle = this.ctx.createPattern(this.resizeImage(image, imageSize), 'repeat');
+            this.ctx.translate(offsetX, offsetY);
+            this.ctx.fill();
+            this.ctx.translate(-offsetX, -offsetY);
+        }
+    }, {
+        key: 'renderTextNode',
+        value: function renderTextNode(textBounds, color, font, textDecoration, textShadows) {
+            var _this4 = this;
+
+            this.ctx.font = [font.fontStyle, font.fontVariant, font.fontWeight, font.fontSize, font.fontFamily].join(' ');
+
+            textBounds.forEach(function (text) {
+                _this4.ctx.fillStyle = color.toString();
+                if (textShadows && text.text.trim().length) {
+                    textShadows.slice(0).reverse().forEach(function (textShadow) {
+                        _this4.ctx.shadowColor = textShadow.color.toString();
+                        _this4.ctx.shadowOffsetX = textShadow.offsetX * _this4.options.scale;
+                        _this4.ctx.shadowOffsetY = textShadow.offsetY * _this4.options.scale;
+                        _this4.ctx.shadowBlur = textShadow.blur;
+
+                        _this4.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
+                    });
+                } else {
+                    _this4.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
+                }
+
+                if (textDecoration !== null) {
+                    var textDecorationColor = textDecoration.textDecorationColor || color;
+                    textDecoration.textDecorationLine.forEach(function (textDecorationLine) {
+                        switch (textDecorationLine) {
+                            case _textDecoration.TEXT_DECORATION_LINE.UNDERLINE:
+                                // Draws a line at the baseline of the font
+                                // TODO As some browsers display the line as more than 1px if the font-size is big,
+                                // need to take that into account both in position and size
+                                var _options$fontMetrics$ = _this4.options.fontMetrics.getMetrics(font),
+                                    baseline = _options$fontMetrics$.baseline;
+
+                                _this4.rectangle(text.bounds.left, Math.round(text.bounds.top + baseline), text.bounds.width, 1, textDecorationColor);
+                                break;
+                            case _textDecoration.TEXT_DECORATION_LINE.OVERLINE:
+                                _this4.rectangle(text.bounds.left, Math.round(text.bounds.top), text.bounds.width, 1, textDecorationColor);
+                                break;
+                            case _textDecoration.TEXT_DECORATION_LINE.LINE_THROUGH:
+                                // TODO try and find exact position for line-through
+                                var _options$fontMetrics$2 = _this4.options.fontMetrics.getMetrics(font),
+                                    middle = _options$fontMetrics$2.middle;
+
+                                _this4.rectangle(text.bounds.left, Math.ceil(text.bounds.top + middle), text.bounds.width, 1, textDecorationColor);
+                                break;
+                        }
+                    });
+                }
+            });
+        }
+    }, {
+        key: 'resizeImage',
+        value: function resizeImage(image, size) {
+            if (image.width === size.width && image.height === size.height) {
+                return image;
+            }
+
+            var canvas = this.canvas.ownerDocument.createElement('canvas');
+            canvas.width = size.width;
+            canvas.height = size.height;
+            var ctx = canvas.getContext('2d');
+            ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, size.width, size.height);
+            return canvas;
+        }
+    }, {
+        key: 'setOpacity',
+        value: function setOpacity(opacity) {
+            this.ctx.globalAlpha = opacity;
+        }
+    }, {
+        key: 'transform',
+        value: function transform(offsetX, offsetY, matrix, callback) {
+            this.ctx.save();
+            this.ctx.translate(offsetX, offsetY);
+            this.ctx.transform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
+            this.ctx.translate(-offsetX, -offsetY);
+
+            callback();
+
+            this.ctx.restore();
+        }
+    }]);
+
+    return CanvasRenderer;
+}();
+
+exports.default = CanvasRenderer;
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/renderer/ForeignObjectRenderer.js b/AstuteClient2/src/assets/html2canvas/dist/npm/renderer/ForeignObjectRenderer.js
new file mode 100644
index 0000000..abf8553
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/renderer/ForeignObjectRenderer.js
@@ -0,0 +1,79 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var ForeignObjectRenderer = function () {
+    function ForeignObjectRenderer(element) {
+        _classCallCheck(this, ForeignObjectRenderer);
+
+        this.element = element;
+    }
+
+    _createClass(ForeignObjectRenderer, [{
+        key: 'render',
+        value: function render(options) {
+            var _this = this;
+
+            this.options = options;
+            this.canvas = document.createElement('canvas');
+            this.ctx = this.canvas.getContext('2d');
+            this.canvas.width = Math.floor(options.width) * options.scale;
+            this.canvas.height = Math.floor(options.height) * options.scale;
+            this.canvas.style.width = options.width + 'px';
+            this.canvas.style.height = options.height + 'px';
+
+            options.logger.log('ForeignObject renderer initialized (' + options.width + 'x' + options.height + ' at ' + options.x + ',' + options.y + ') with scale ' + options.scale);
+            var svg = createForeignObjectSVG(Math.max(options.windowWidth, options.width) * options.scale, Math.max(options.windowHeight, options.height) * options.scale, options.scrollX * options.scale, options.scrollY * options.scale, this.element);
+
+            return loadSerializedSVG(svg).then(function (img) {
+                if (options.backgroundColor) {
+                    _this.ctx.fillStyle = options.backgroundColor.toString();
+                    _this.ctx.fillRect(0, 0, options.width * options.scale, options.height * options.scale);
+                }
+
+                _this.ctx.drawImage(img, -options.x * options.scale, -options.y * options.scale);
+                return _this.canvas;
+            });
+        }
+    }]);
+
+    return ForeignObjectRenderer;
+}();
+
+exports.default = ForeignObjectRenderer;
+var createForeignObjectSVG = exports.createForeignObjectSVG = function createForeignObjectSVG(width, height, x, y, node) {
+    var xmlns = 'http://www.w3.org/2000/svg';
+    var svg = document.createElementNS(xmlns, 'svg');
+    var foreignObject = document.createElementNS(xmlns, 'foreignObject');
+    svg.setAttributeNS(null, 'width', width);
+    svg.setAttributeNS(null, 'height', height);
+
+    foreignObject.setAttributeNS(null, 'width', '100%');
+    foreignObject.setAttributeNS(null, 'height', '100%');
+    foreignObject.setAttributeNS(null, 'x', x);
+    foreignObject.setAttributeNS(null, 'y', y);
+    foreignObject.setAttributeNS(null, 'externalResourcesRequired', 'true');
+    svg.appendChild(foreignObject);
+
+    foreignObject.appendChild(node);
+
+    return svg;
+};
+
+var loadSerializedSVG = exports.loadSerializedSVG = function loadSerializedSVG(svg) {
+    return new Promise(function (resolve, reject) {
+        var img = new Image();
+        img.onload = function () {
+            return resolve(img);
+        };
+        img.onerror = reject;
+
+        img.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(new XMLSerializer().serializeToString(svg));
+    });
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/dist/npm/renderer/RefTestRenderer.js b/AstuteClient2/src/assets/html2canvas/dist/npm/renderer/RefTestRenderer.js
new file mode 100644
index 0000000..17378d7
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/dist/npm/renderer/RefTestRenderer.js
@@ -0,0 +1,207 @@
+'use strict';
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _url = require('url');
+
+var _textDecoration2 = require('../parsing/textDecoration');
+
+var _Path = require('../drawing/Path');
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var RefTestRenderer = function () {
+    function RefTestRenderer() {
+        _classCallCheck(this, RefTestRenderer);
+    }
+
+    _createClass(RefTestRenderer, [{
+        key: 'render',
+        value: function render(options) {
+            this.options = options;
+            this.indent = 0;
+            this.lines = [];
+            options.logger.log('RefTest renderer initialized');
+            this.writeLine('Window: [' + options.width + ', ' + options.height + ']');
+        }
+    }, {
+        key: 'clip',
+        value: function clip(clipPaths, callback) {
+            this.writeLine('Clip: ' + clipPaths.map(this.formatPath, this).join(' | '));
+            this.indent += 2;
+            callback();
+            this.indent -= 2;
+        }
+    }, {
+        key: 'drawImage',
+        value: function drawImage(image, source, destination) {
+            this.writeLine('Draw image: ' + this.formatImage(image) + ' (source: ' + this.formatBounds(source) + ') (destination: ' + this.formatBounds(source) + ')');
+        }
+    }, {
+        key: 'drawShape',
+        value: function drawShape(path, color) {
+            this.writeLine('Shape: ' + color.toString() + ' ' + this.formatPath(path));
+        }
+    }, {
+        key: 'fill',
+        value: function fill(color) {
+            this.writeLine('Fill: ' + color.toString());
+        }
+    }, {
+        key: 'getTarget',
+        value: function getTarget() {
+            return Promise.resolve(this.lines.join('\n'));
+        }
+    }, {
+        key: 'rectangle',
+        value: function rectangle(x, y, width, height, color) {
+            var list = [x, y, width, height].map(function (v) {
+                return Math.round(v);
+            }).join(', ');
+            this.writeLine('Rectangle: [' + list + '] ' + color.toString());
+        }
+    }, {
+        key: 'formatBounds',
+        value: function formatBounds(bounds) {
+            var list = [bounds.left, bounds.top, bounds.width, bounds.height];
+            return '[' + list.map(function (v) {
+                return Math.round(v);
+            }).join(', ') + ']';
+        }
+    }, {
+        key: 'formatImage',
+        value: function formatImage(image) {
+            return image.tagName === 'CANVAS' ? 'Canvas' : // $FlowFixMe
+            'Image ("' + (0, _url.parse)(image.src).pathname.substring(0, 100) + '")';
+        }
+    }, {
+        key: 'formatPath',
+        value: function formatPath(path) {
+            if (!Array.isArray(path)) {
+                return 'Circle(x: ' + Math.round(path.x) + ', y: ' + Math.round(path.y) + ', r: ' + Math.round(path.radius) + ')';
+            }
+            var string = path.map(function (v) {
+                if (v.type === _Path.PATH.VECTOR) {
+                    return 'Vector(x: ' + Math.round(v.x) + ', y: ' + Math.round(v.y) + ')';
+                }
+                if (v.type === _Path.PATH.BEZIER_CURVE) {
+                    var values = ['x0: ' + Math.round(v.start.x), 'y0: ' + Math.round(v.start.y), 'x1: ' + Math.round(v.end.x), 'y1: ' + Math.round(v.end.y), 'cx0: ' + Math.round(v.startControl.x), 'cy0: ' + Math.round(v.startControl.y), 'cx1: ' + Math.round(v.endControl.x), 'cy1: ' + Math.round(v.endControl.y)];
+                    return 'BezierCurve(' + values.join(', ') + ')';
+                }
+            }).join(' > ');
+            return 'Path (' + string + ')';
+        }
+    }, {
+        key: 'renderLinearGradient',
+        value: function renderLinearGradient(bounds, gradient) {
+            var direction = ['x0: ' + Math.round(gradient.direction.x0), 'x1: ' + Math.round(gradient.direction.x1), 'y0: ' + Math.round(gradient.direction.y0), 'y1: ' + Math.round(gradient.direction.y1)];
+
+            var stops = gradient.colorStops.map(function (stop) {
+                return stop.color.toString() + ' ' + Math.ceil(stop.stop * 100) / 100;
+            });
+
+            this.writeLine('Gradient: ' + this.formatBounds(bounds) + ' linear-gradient(' + direction.join(', ') + ' ' + stops.join(', ') + ')');
+        }
+    }, {
+        key: 'renderRadialGradient',
+        value: function renderRadialGradient(bounds, gradient) {
+            var stops = gradient.colorStops.map(function (stop) {
+                return stop.color.toString() + ' ' + Math.ceil(stop.stop * 100) / 100;
+            });
+
+            this.writeLine('RadialGradient: ' + this.formatBounds(bounds) + ' radial-gradient(' + gradient.radius.x + ' ' + gradient.radius.y + ' at ' + gradient.center.x + ' ' + gradient.center.y + ', ' + stops.join(', ') + ')');
+        }
+    }, {
+        key: 'renderRepeat',
+        value: function renderRepeat(path, image, imageSize, offsetX, offsetY) {
+            this.writeLine('Repeat: ' + this.formatImage(image) + ' [' + Math.round(offsetX) + ', ' + Math.round(offsetY) + '] Size (' + Math.round(imageSize.width) + ', ' + Math.round(imageSize.height) + ') ' + this.formatPath(path));
+        }
+    }, {
+        key: 'renderTextNode',
+        value: function renderTextNode(textBounds, color, font, textDecoration, textShadows) {
+            var _this = this;
+
+            var fontString = [font.fontStyle, font.fontVariant, font.fontWeight, parseInt(font.fontSize, 10), font.fontFamily.replace(/"/g, '')].join(' ').split(',')[0];
+
+            var textDecorationString = this.textDecoration(textDecoration, color);
+            var shadowString = textShadows ? ' Shadows: (' + textShadows.map(function (shadow) {
+                return shadow.color.toString() + ' ' + shadow.offsetX + 'px ' + shadow.offsetY + 'px ' + shadow.blur + 'px';
+            }).join(', ') + ')' : '';
+
+            this.writeLine('Text: ' + color.toString() + ' ' + fontString + shadowString + textDecorationString);
+
+            this.indent += 2;
+            textBounds.forEach(function (textBound) {
+                _this.writeLine('[' + Math.round(textBound.bounds.left) + ', ' + Math.round(textBound.bounds.top) + ']: ' + textBound.text);
+            });
+            this.indent -= 2;
+        }
+    }, {
+        key: 'textDecoration',
+        value: function textDecoration(_textDecoration, color) {
+            if (_textDecoration) {
+                var textDecorationColor = (_textDecoration.textDecorationColor ? _textDecoration.textDecorationColor : color).toString();
+                var textDecorationLines = _textDecoration.textDecorationLine.map(this.textDecorationLine, this);
+                return _textDecoration ? ' ' + this.textDecorationStyle(_textDecoration.textDecorationStyle) + ' ' + textDecorationColor + ' ' + textDecorationLines.join(', ') : '';
+            }
+
+            return '';
+        }
+    }, {
+        key: 'textDecorationLine',
+        value: function textDecorationLine(_textDecorationLine) {
+            switch (_textDecorationLine) {
+                case _textDecoration2.TEXT_DECORATION_LINE.LINE_THROUGH:
+                    return 'line-through';
+                case _textDecoration2.TEXT_DECORATION_LINE.OVERLINE:
+                    return 'overline';
+                case _textDecoration2.TEXT_DECORATION_LINE.UNDERLINE:
+                    return 'underline';
+                case _textDecoration2.TEXT_DECORATION_LINE.BLINK:
+                    return 'blink';
+            }
+            return 'UNKNOWN';
+        }
+    }, {
+        key: 'textDecorationStyle',
+        value: function textDecorationStyle(_textDecorationStyle) {
+            switch (_textDecorationStyle) {
+                case _textDecoration2.TEXT_DECORATION_STYLE.SOLID:
+                    return 'solid';
+                case _textDecoration2.TEXT_DECORATION_STYLE.DOTTED:
+                    return 'dotted';
+                case _textDecoration2.TEXT_DECORATION_STYLE.DOUBLE:
+                    return 'double';
+                case _textDecoration2.TEXT_DECORATION_STYLE.DASHED:
+                    return 'dashed';
+                case _textDecoration2.TEXT_DECORATION_STYLE.WAVY:
+                    return 'WAVY';
+            }
+            return 'UNKNOWN';
+        }
+    }, {
+        key: 'setOpacity',
+        value: function setOpacity(opacity) {
+            this.writeLine('Opacity: ' + opacity);
+        }
+    }, {
+        key: 'transform',
+        value: function transform(offsetX, offsetY, matrix, callback) {
+            this.writeLine('Transform: (' + Math.round(offsetX) + ', ' + Math.round(offsetY) + ') [' + matrix.map(function (v) {
+                return Math.round(v * 100) / 100;
+            }).join(', ') + ']');
+            this.indent += 2;
+            callback();
+            this.indent -= 2;
+        }
+    }, {
+        key: 'writeLine',
+        value: function writeLine(text) {
+            this.lines.push('' + new Array(this.indent + 1).join(' ') + text);
+        }
+    }]);
+
+    return RefTestRenderer;
+}();
+
+module.exports = RefTestRenderer;
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/html2canvas/flow-typed/myLibDef.js b/AstuteClient2/src/assets/html2canvas/flow-typed/myLibDef.js
new file mode 100644
index 0000000..e9ac982
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/flow-typed/myLibDef.js
@@ -0,0 +1,11 @@
+declare var __DEV__: boolean;
+declare var __VERSION__: string;
+
+declare class SVGSVGElement extends Element {
+    className: string;
+    style: CSSStyleDeclaration;
+
+    getPresentationAttribute(name: string): any;
+}
+
+declare class HTMLBodyElement extends HTMLElement {}
diff --git a/AstuteClient2/src/assets/html2canvas/package-lock.json b/AstuteClient2/src/assets/html2canvas/package-lock.json
new file mode 100644
index 0000000..576aafe
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/package-lock.json
@@ -0,0 +1,8919 @@
+{
+  "name": "html2canvas",
+  "version": "1.0.0-alpha.12",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "@types/core-js": {
+      "version": "0.9.46",
+      "resolved": "https://registry.npmjs.org/@types/core-js/-/core-js-0.9.46.tgz",
+      "integrity": "sha512-LooLR6XHes9V+kNYRz1Qm8w3atw9QMn7XeZUmIpUelllF9BdryeUKd/u0Wh5ErcjpWfG39NrToU9MF7ngsTFVw==",
+      "dev": true
+    },
+    "@types/mkdirp": {
+      "version": "0.3.29",
+      "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.3.29.tgz",
+      "integrity": "sha1-fyrX7FX5FEgvybHsS7GuYCjUYGY=",
+      "dev": true
+    },
+    "@types/node": {
+      "version": "6.0.66",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.66.tgz",
+      "integrity": "sha1-VoC3SmE10z1MAER+fD3GkaRgFiU=",
+      "dev": true
+    },
+    "accepts": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
+      "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
+      "dev": true,
+      "requires": {
+        "mime-types": "2.1.18",
+        "negotiator": "0.6.1"
+      }
+    },
+    "acorn": {
+      "version": "5.5.3",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz",
+      "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==",
+      "dev": true
+    },
+    "acorn-dynamic-import": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz",
+      "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=",
+      "dev": true,
+      "requires": {
+        "acorn": "4.0.13"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "4.0.13",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
+          "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=",
+          "dev": true
+        }
+      }
+    },
+    "acorn-jsx": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
+      "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
+      "dev": true,
+      "requires": {
+        "acorn": "3.3.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+          "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
+          "dev": true
+        }
+      }
+    },
+    "adm-zip": {
+      "version": "0.4.7",
+      "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.7.tgz",
+      "integrity": "sha1-hgbCy/HEJs6MjsABdER/1Jtur8E=",
+      "dev": true
+    },
+    "after": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
+      "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=",
+      "dev": true
+    },
+    "agent-base": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz",
+      "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=",
+      "dev": true,
+      "requires": {
+        "extend": "3.0.1",
+        "semver": "5.0.3"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.0.3",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz",
+          "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=",
+          "dev": true
+        }
+      }
+    },
+    "ajv": {
+      "version": "5.5.2",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+      "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+      "dev": true,
+      "requires": {
+        "co": "4.6.0",
+        "fast-deep-equal": "1.1.0",
+        "fast-json-stable-stringify": "2.0.0",
+        "json-schema-traverse": "0.3.1"
+      }
+    },
+    "ajv-keywords": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.1.0.tgz",
+      "integrity": "sha1-rCsnk5xUPpXSwG5/f1wnvkqlQ74=",
+      "dev": true
+    },
+    "align-text": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
+      "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2",
+        "longest": "1.0.1",
+        "repeat-string": "1.6.1"
+      }
+    },
+    "ansi-escapes": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
+      "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==",
+      "dev": true
+    },
+    "ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+      "dev": true
+    },
+    "ansi-styles": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+      "dev": true
+    },
+    "anymatch": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
+      "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
+      "dev": true,
+      "requires": {
+        "micromatch": "2.3.11",
+        "normalize-path": "2.1.1"
+      }
+    },
+    "aproba": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+      "dev": true
+    },
+    "archiver": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.3.0.tgz",
+      "integrity": "sha1-TyGU1tj5nfP1MeaIHxTxXVX6ryI=",
+      "dev": true,
+      "requires": {
+        "archiver-utils": "1.3.0",
+        "async": "2.6.0",
+        "buffer-crc32": "0.2.13",
+        "glob": "7.1.2",
+        "lodash": "4.17.5",
+        "readable-stream": "2.3.5",
+        "tar-stream": "1.5.5",
+        "walkdir": "0.0.11",
+        "zip-stream": "1.2.0"
+      },
+      "dependencies": {
+        "async": {
+          "version": "2.6.0",
+          "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz",
+          "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==",
+          "dev": true,
+          "requires": {
+            "lodash": "4.17.5"
+          }
+        }
+      }
+    },
+    "archiver-utils": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz",
+      "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=",
+      "dev": true,
+      "requires": {
+        "glob": "7.1.2",
+        "graceful-fs": "4.1.11",
+        "lazystream": "1.0.0",
+        "lodash": "4.17.5",
+        "normalize-path": "2.1.1",
+        "readable-stream": "2.3.5"
+      }
+    },
+    "argparse": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+      "dev": true,
+      "requires": {
+        "sprintf-js": "1.0.3"
+      }
+    },
+    "arr-diff": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+      "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+      "dev": true,
+      "requires": {
+        "arr-flatten": "1.1.0"
+      }
+    },
+    "arr-flatten": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+      "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+      "dev": true
+    },
+    "arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true
+    },
+    "array-flatten": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+      "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
+      "dev": true
+    },
+    "array-slice": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz",
+      "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=",
+      "dev": true
+    },
+    "array-union": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+      "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+      "dev": true,
+      "requires": {
+        "array-uniq": "1.0.3"
+      }
+    },
+    "array-uniq": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+      "dev": true
+    },
+    "array-unique": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+      "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+      "dev": true
+    },
+    "arraybuffer.slice": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz",
+      "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=",
+      "dev": true
+    },
+    "arrify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+      "dev": true
+    },
+    "asn1": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+      "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
+      "dev": true
+    },
+    "asn1.js": {
+      "version": "4.10.1",
+      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+      "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "inherits": "2.0.3",
+        "minimalistic-assert": "1.0.0"
+      }
+    },
+    "assert": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
+      "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
+      "dev": true,
+      "requires": {
+        "util": "0.10.3"
+      }
+    },
+    "assert-plus": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+      "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+      "dev": true
+    },
+    "assertion-error": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+      "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+      "dev": true
+    },
+    "assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true
+    },
+    "async": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.4.0.tgz",
+      "integrity": "sha1-Nfhvg8WeBCHQmc2akdgnj7V4wA0=",
+      "dev": true
+    },
+    "async-each": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
+      "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
+      "dev": true
+    },
+    "async-limiter": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
+      "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==",
+      "dev": true
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "dev": true
+    },
+    "atob": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.0.tgz",
+      "integrity": "sha512-SuiKH8vbsOyCALjA/+EINmt/Kdl+TQPrtFgW7XZZcwtryFu9e5kQoX3bjCW6mIvGH1fbeAZZuvwGR5IlBRznGw==",
+      "dev": true
+    },
+    "aws-sdk": {
+      "version": "2.218.1",
+      "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.218.1.tgz",
+      "integrity": "sha1-tM90LMCFO9fIaLOIy/C0oe8avBI=",
+      "dev": true,
+      "requires": {
+        "buffer": "4.9.1",
+        "events": "1.1.1",
+        "ieee754": "1.1.8",
+        "jmespath": "0.15.0",
+        "querystring": "0.2.0",
+        "sax": "1.2.1",
+        "url": "0.10.3",
+        "uuid": "3.1.0",
+        "xml2js": "0.4.17",
+        "xmlbuilder": "4.2.1"
+      }
+    },
+    "aws-sign2": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+      "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
+      "dev": true
+    },
+    "aws4": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+      "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
+      "dev": true
+    },
+    "babel-cli": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.24.1.tgz",
+      "integrity": "sha1-IHzXBbumFImy6kG1MSNBz2rKIoM=",
+      "dev": true,
+      "requires": {
+        "babel-core": "6.25.0",
+        "babel-polyfill": "6.26.0",
+        "babel-register": "6.26.0",
+        "babel-runtime": "6.26.0",
+        "chokidar": "1.7.0",
+        "commander": "2.15.1",
+        "convert-source-map": "1.5.1",
+        "fs-readdir-recursive": "1.1.0",
+        "glob": "7.1.2",
+        "lodash": "4.17.5",
+        "output-file-sync": "1.1.2",
+        "path-is-absolute": "1.0.1",
+        "slash": "1.0.0",
+        "source-map": "0.5.7",
+        "v8flags": "2.1.1"
+      }
+    },
+    "babel-code-frame": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "esutils": "2.0.2",
+        "js-tokens": "3.0.2"
+      }
+    },
+    "babel-core": {
+      "version": "6.25.0",
+      "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.25.0.tgz",
+      "integrity": "sha1-fdQrBGPHQunVKW3rPsZ6kyLa1yk=",
+      "dev": true,
+      "requires": {
+        "babel-code-frame": "6.26.0",
+        "babel-generator": "6.26.1",
+        "babel-helpers": "6.24.1",
+        "babel-messages": "6.23.0",
+        "babel-register": "6.26.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0",
+        "babylon": "6.18.0",
+        "convert-source-map": "1.5.1",
+        "debug": "2.6.9",
+        "json5": "0.5.1",
+        "lodash": "4.17.5",
+        "minimatch": "3.0.4",
+        "path-is-absolute": "1.0.1",
+        "private": "0.1.8",
+        "slash": "1.0.0",
+        "source-map": "0.5.7"
+      }
+    },
+    "babel-eslint": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz",
+      "integrity": "sha1-sv4tgBJkcPXBlELcdXJTqJdxCCc=",
+      "dev": true,
+      "requires": {
+        "babel-code-frame": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0",
+        "babylon": "6.18.0"
+      }
+    },
+    "babel-generator": {
+      "version": "6.26.1",
+      "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz",
+      "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==",
+      "dev": true,
+      "requires": {
+        "babel-messages": "6.23.0",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0",
+        "detect-indent": "4.0.0",
+        "jsesc": "1.3.0",
+        "lodash": "4.17.5",
+        "source-map": "0.5.7",
+        "trim-right": "1.0.1"
+      }
+    },
+    "babel-helper-call-delegate": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz",
+      "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=",
+      "dev": true,
+      "requires": {
+        "babel-helper-hoist-variables": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-define-map": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz",
+      "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=",
+      "dev": true,
+      "requires": {
+        "babel-helper-function-name": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0",
+        "lodash": "4.17.5"
+      }
+    },
+    "babel-helper-function-name": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
+      "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
+      "dev": true,
+      "requires": {
+        "babel-helper-get-function-arity": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-get-function-arity": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
+      "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-hoist-variables": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz",
+      "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-optimise-call-expression": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz",
+      "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-regex": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz",
+      "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0",
+        "lodash": "4.17.5"
+      }
+    },
+    "babel-helper-replace-supers": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
+      "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=",
+      "dev": true,
+      "requires": {
+        "babel-helper-optimise-call-expression": "6.24.1",
+        "babel-messages": "6.23.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helpers": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
+      "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-loader": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.1.tgz",
+      "integrity": "sha1-uHE0yLEuPkwqlOBUYIW8aAorhIg=",
+      "dev": true,
+      "requires": {
+        "find-cache-dir": "1.0.0",
+        "loader-utils": "1.1.0",
+        "mkdirp": "0.5.1"
+      }
+    },
+    "babel-messages": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+      "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-check-es2015-constants": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
+      "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-dev-expression": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-dev-expression/-/babel-plugin-dev-expression-0.2.1.tgz",
+      "integrity": "sha1-1Ke+7++7UOPyc0mQqCokhs+eue4=",
+      "dev": true
+    },
+    "babel-plugin-syntax-flow": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz",
+      "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=",
+      "dev": true
+    },
+    "babel-plugin-syntax-object-rest-spread": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
+      "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
+      "dev": true
+    },
+    "babel-plugin-transform-es2015-arrow-functions": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
+      "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-block-scoped-functions": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
+      "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-block-scoping": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz",
+      "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0",
+        "lodash": "4.17.5"
+      }
+    },
+    "babel-plugin-transform-es2015-classes": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz",
+      "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=",
+      "dev": true,
+      "requires": {
+        "babel-helper-define-map": "6.26.0",
+        "babel-helper-function-name": "6.24.1",
+        "babel-helper-optimise-call-expression": "6.24.1",
+        "babel-helper-replace-supers": "6.24.1",
+        "babel-messages": "6.23.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-computed-properties": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz",
+      "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-destructuring": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
+      "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-duplicate-keys": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
+      "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-for-of": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
+      "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-function-name": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz",
+      "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=",
+      "dev": true,
+      "requires": {
+        "babel-helper-function-name": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-literals": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
+      "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-modules-amd": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz",
+      "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-modules-commonjs": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz",
+      "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-strict-mode": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-modules-systemjs": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz",
+      "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=",
+      "dev": true,
+      "requires": {
+        "babel-helper-hoist-variables": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-modules-umd": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz",
+      "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-es2015-modules-amd": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-object-super": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz",
+      "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=",
+      "dev": true,
+      "requires": {
+        "babel-helper-replace-supers": "6.24.1",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-parameters": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz",
+      "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=",
+      "dev": true,
+      "requires": {
+        "babel-helper-call-delegate": "6.24.1",
+        "babel-helper-get-function-arity": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-shorthand-properties": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz",
+      "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-spread": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
+      "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-sticky-regex": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz",
+      "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=",
+      "dev": true,
+      "requires": {
+        "babel-helper-regex": "6.26.0",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-template-literals": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
+      "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-typeof-symbol": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
+      "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-unicode-regex": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
+      "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=",
+      "dev": true,
+      "requires": {
+        "babel-helper-regex": "6.26.0",
+        "babel-runtime": "6.26.0",
+        "regexpu-core": "2.0.0"
+      }
+    },
+    "babel-plugin-transform-flow-strip-types": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz",
+      "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-flow": "6.18.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-object-rest-spread": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.23.0.tgz",
+      "integrity": "sha1-h11ryb52HFiirj/u5dxIldjH+SE=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-object-rest-spread": "6.13.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-regenerator": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
+      "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=",
+      "dev": true,
+      "requires": {
+        "regenerator-transform": "0.10.1"
+      }
+    },
+    "babel-plugin-transform-strict-mode": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
+      "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-polyfill": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz",
+      "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "core-js": "2.5.4",
+        "regenerator-runtime": "0.10.5"
+      },
+      "dependencies": {
+        "regenerator-runtime": {
+          "version": "0.10.5",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
+          "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=",
+          "dev": true
+        }
+      }
+    },
+    "babel-preset-es2015": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz",
+      "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-check-es2015-constants": "6.22.0",
+        "babel-plugin-transform-es2015-arrow-functions": "6.22.0",
+        "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0",
+        "babel-plugin-transform-es2015-block-scoping": "6.26.0",
+        "babel-plugin-transform-es2015-classes": "6.24.1",
+        "babel-plugin-transform-es2015-computed-properties": "6.24.1",
+        "babel-plugin-transform-es2015-destructuring": "6.23.0",
+        "babel-plugin-transform-es2015-duplicate-keys": "6.24.1",
+        "babel-plugin-transform-es2015-for-of": "6.23.0",
+        "babel-plugin-transform-es2015-function-name": "6.24.1",
+        "babel-plugin-transform-es2015-literals": "6.22.0",
+        "babel-plugin-transform-es2015-modules-amd": "6.24.1",
+        "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
+        "babel-plugin-transform-es2015-modules-systemjs": "6.24.1",
+        "babel-plugin-transform-es2015-modules-umd": "6.24.1",
+        "babel-plugin-transform-es2015-object-super": "6.24.1",
+        "babel-plugin-transform-es2015-parameters": "6.24.1",
+        "babel-plugin-transform-es2015-shorthand-properties": "6.24.1",
+        "babel-plugin-transform-es2015-spread": "6.22.0",
+        "babel-plugin-transform-es2015-sticky-regex": "6.24.1",
+        "babel-plugin-transform-es2015-template-literals": "6.22.0",
+        "babel-plugin-transform-es2015-typeof-symbol": "6.23.0",
+        "babel-plugin-transform-es2015-unicode-regex": "6.24.1",
+        "babel-plugin-transform-regenerator": "6.26.0"
+      }
+    },
+    "babel-preset-flow": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz",
+      "integrity": "sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-flow-strip-types": "6.22.0"
+      }
+    },
+    "babel-register": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
+      "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
+      "dev": true,
+      "requires": {
+        "babel-core": "6.26.0",
+        "babel-runtime": "6.26.0",
+        "core-js": "2.5.4",
+        "home-or-tmp": "2.0.0",
+        "lodash": "4.17.5",
+        "mkdirp": "0.5.1",
+        "source-map-support": "0.4.18"
+      },
+      "dependencies": {
+        "babel-core": {
+          "version": "6.26.0",
+          "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz",
+          "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=",
+          "dev": true,
+          "requires": {
+            "babel-code-frame": "6.26.0",
+            "babel-generator": "6.26.1",
+            "babel-helpers": "6.24.1",
+            "babel-messages": "6.23.0",
+            "babel-register": "6.26.0",
+            "babel-runtime": "6.26.0",
+            "babel-template": "6.26.0",
+            "babel-traverse": "6.26.0",
+            "babel-types": "6.26.0",
+            "babylon": "6.18.0",
+            "convert-source-map": "1.5.1",
+            "debug": "2.6.9",
+            "json5": "0.5.1",
+            "lodash": "4.17.5",
+            "minimatch": "3.0.4",
+            "path-is-absolute": "1.0.1",
+            "private": "0.1.8",
+            "slash": "1.0.0",
+            "source-map": "0.5.7"
+          }
+        }
+      }
+    },
+    "babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+      "dev": true,
+      "requires": {
+        "core-js": "2.5.4",
+        "regenerator-runtime": "0.11.1"
+      }
+    },
+    "babel-template": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+      "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0",
+        "babylon": "6.18.0",
+        "lodash": "4.17.5"
+      }
+    },
+    "babel-traverse": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+      "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
+      "dev": true,
+      "requires": {
+        "babel-code-frame": "6.26.0",
+        "babel-messages": "6.23.0",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0",
+        "babylon": "6.18.0",
+        "debug": "2.6.9",
+        "globals": "9.18.0",
+        "invariant": "2.2.4",
+        "lodash": "4.17.5"
+      }
+    },
+    "babel-types": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+      "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "esutils": "2.0.2",
+        "lodash": "4.17.5",
+        "to-fast-properties": "1.0.3"
+      }
+    },
+    "babylon": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+      "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+      "dev": true
+    },
+    "backo2": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
+      "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=",
+      "dev": true
+    },
+    "balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+      "dev": true
+    },
+    "base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "dev": true,
+      "requires": {
+        "cache-base": "1.0.1",
+        "class-utils": "0.3.6",
+        "component-emitter": "1.2.1",
+        "define-property": "1.0.0",
+        "isobject": "3.0.1",
+        "mixin-deep": "1.3.1",
+        "pascalcase": "0.1.1"
+      },
+      "dependencies": {
+        "component-emitter": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+          "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+          "dev": true
+        },
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "1.0.2"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "base64-arraybuffer": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
+      "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg="
+    },
+    "base64-js": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz",
+      "integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w==",
+      "dev": true
+    },
+    "base64id": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
+      "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=",
+      "dev": true
+    },
+    "batch": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+      "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
+      "dev": true
+    },
+    "bcrypt-pbkdf": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+      "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "tweetnacl": "0.14.5"
+      }
+    },
+    "better-assert": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
+      "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
+      "dev": true,
+      "requires": {
+        "callsite": "1.0.0"
+      }
+    },
+    "big.js": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
+      "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
+      "dev": true
+    },
+    "binary-extensions": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
+      "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
+      "dev": true
+    },
+    "bl": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
+      "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
+      "dev": true,
+      "requires": {
+        "readable-stream": "2.3.5",
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "blob": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz",
+      "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=",
+      "dev": true
+    },
+    "bluebird": {
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
+      "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
+      "dev": true
+    },
+    "bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "body-parser": {
+      "version": "1.17.2",
+      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz",
+      "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=",
+      "dev": true,
+      "requires": {
+        "bytes": "2.4.0",
+        "content-type": "1.0.4",
+        "debug": "2.6.7",
+        "depd": "1.1.2",
+        "http-errors": "1.6.3",
+        "iconv-lite": "0.4.15",
+        "on-finished": "2.3.0",
+        "qs": "6.4.0",
+        "raw-body": "2.2.0",
+        "type-is": "1.6.16"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.7",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz",
+          "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "boom": {
+      "version": "2.10.1",
+      "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+      "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+      "dev": true,
+      "requires": {
+        "hoek": "2.16.3"
+      }
+    },
+    "brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "requires": {
+        "balanced-match": "1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "braces": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+      "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+      "dev": true,
+      "requires": {
+        "expand-range": "1.8.2",
+        "preserve": "0.2.0",
+        "repeat-element": "1.1.2"
+      }
+    },
+    "brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
+    "browser-fingerprint": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/browser-fingerprint/-/browser-fingerprint-0.0.1.tgz",
+      "integrity": "sha1-jfPNyiW/fVs1QtYVRdcwBT/OYEo=",
+      "dev": true
+    },
+    "browser-stdout": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz",
+      "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=",
+      "dev": true
+    },
+    "browserify-aes": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz",
+      "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==",
+      "dev": true,
+      "requires": {
+        "buffer-xor": "1.0.3",
+        "cipher-base": "1.0.4",
+        "create-hash": "1.1.3",
+        "evp_bytestokey": "1.0.3",
+        "inherits": "2.0.3",
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "browserify-cipher": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz",
+      "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=",
+      "dev": true,
+      "requires": {
+        "browserify-aes": "1.1.1",
+        "browserify-des": "1.0.0",
+        "evp_bytestokey": "1.0.3"
+      }
+    },
+    "browserify-des": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz",
+      "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=",
+      "dev": true,
+      "requires": {
+        "cipher-base": "1.0.4",
+        "des.js": "1.0.0",
+        "inherits": "2.0.3"
+      }
+    },
+    "browserify-rsa": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+      "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "randombytes": "2.0.6"
+      }
+    },
+    "browserify-sign": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
+      "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "browserify-rsa": "4.0.1",
+        "create-hash": "1.1.3",
+        "create-hmac": "1.1.6",
+        "elliptic": "6.4.0",
+        "inherits": "2.0.3",
+        "parse-asn1": "5.1.0"
+      }
+    },
+    "browserify-zlib": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+      "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+      "dev": true,
+      "requires": {
+        "pako": "1.0.6"
+      }
+    },
+    "buffer": {
+      "version": "4.9.1",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
+      "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
+      "dev": true,
+      "requires": {
+        "base64-js": "1.2.3",
+        "ieee754": "1.1.8",
+        "isarray": "1.0.0"
+      }
+    },
+    "buffer-crc32": {
+      "version": "0.2.13",
+      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+      "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
+      "dev": true
+    },
+    "buffer-from": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz",
+      "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==",
+      "dev": true
+    },
+    "buffer-xor": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+      "dev": true
+    },
+    "builtin-modules": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+      "dev": true
+    },
+    "builtin-status-codes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+      "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
+      "dev": true
+    },
+    "bytes": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
+      "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=",
+      "dev": true
+    },
+    "cacache": {
+      "version": "10.0.4",
+      "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz",
+      "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==",
+      "dev": true,
+      "requires": {
+        "bluebird": "3.5.1",
+        "chownr": "1.0.1",
+        "glob": "7.1.2",
+        "graceful-fs": "4.1.11",
+        "lru-cache": "4.1.2",
+        "mississippi": "2.0.0",
+        "mkdirp": "0.5.1",
+        "move-concurrently": "1.0.1",
+        "promise-inflight": "1.0.1",
+        "rimraf": "2.6.2",
+        "ssri": "5.3.0",
+        "unique-filename": "1.1.0",
+        "y18n": "4.0.0"
+      },
+      "dependencies": {
+        "rimraf": {
+          "version": "2.6.2",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+          "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+          "dev": true,
+          "requires": {
+            "glob": "7.1.2"
+          }
+        },
+        "y18n": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+          "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+          "dev": true
+        }
+      }
+    },
+    "cache-base": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+      "dev": true,
+      "requires": {
+        "collection-visit": "1.0.0",
+        "component-emitter": "1.2.1",
+        "get-value": "2.0.6",
+        "has-value": "1.0.0",
+        "isobject": "3.0.1",
+        "set-value": "2.0.0",
+        "to-object-path": "0.3.0",
+        "union-value": "1.0.0",
+        "unset-value": "1.0.0"
+      },
+      "dependencies": {
+        "component-emitter": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+          "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+          "dev": true
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "callback-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/callback-stream/-/callback-stream-1.1.0.tgz",
+      "integrity": "sha1-RwGlEmbwbgbqpx/BcjOCLYdfSQg=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.5"
+      }
+    },
+    "caller-path": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
+      "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
+      "dev": true,
+      "requires": {
+        "callsites": "0.2.0"
+      }
+    },
+    "callsite": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
+      "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=",
+      "dev": true
+    },
+    "callsites": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
+      "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
+      "dev": true
+    },
+    "camelcase": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+      "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+      "dev": true
+    },
+    "caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+      "dev": true
+    },
+    "center-align": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
+      "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
+      "dev": true,
+      "requires": {
+        "align-text": "0.1.4",
+        "lazy-cache": "1.0.4"
+      }
+    },
+    "chai": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.1.tgz",
+      "integrity": "sha1-ZuISeebzxkFf+CMYeCJ5AOIXGzk=",
+      "dev": true,
+      "requires": {
+        "assertion-error": "1.1.0",
+        "check-error": "1.0.2",
+        "deep-eql": "2.0.2",
+        "get-func-name": "2.0.0",
+        "pathval": "1.1.0",
+        "type-detect": "4.0.8"
+      }
+    },
+    "chalk": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+      "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "2.2.1",
+        "escape-string-regexp": "1.0.5",
+        "has-ansi": "2.0.0",
+        "strip-ansi": "3.0.1",
+        "supports-color": "2.0.0"
+      }
+    },
+    "chardet": {
+      "version": "0.4.2",
+      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
+      "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
+      "dev": true
+    },
+    "check-error": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+      "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
+      "dev": true
+    },
+    "chokidar": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
+      "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
+      "dev": true,
+      "requires": {
+        "anymatch": "1.3.2",
+        "async-each": "1.0.1",
+        "glob-parent": "2.0.0",
+        "inherits": "2.0.3",
+        "is-binary-path": "1.0.1",
+        "is-glob": "2.0.1",
+        "path-is-absolute": "1.0.1",
+        "readdirp": "2.1.0"
+      }
+    },
+    "chownr": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz",
+      "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=",
+      "dev": true
+    },
+    "chrome-launcher": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.4.0.tgz",
+      "integrity": "sha512-Uq34nQ2peVRwyjsyoLs01mL9aEQDbc5RCZWNyYjGPt5ZFPL2B4OazSc98hO6HZOvMUILLL4MyAEVMzA5OvwWug==",
+      "dev": true,
+      "requires": {
+        "@types/core-js": "0.9.46",
+        "@types/mkdirp": "0.3.29",
+        "@types/node": "6.0.66",
+        "lighthouse-logger": "1.0.1",
+        "mkdirp": "0.5.1",
+        "rimraf": "2.6.1"
+      }
+    },
+    "chrome-remote-interface": {
+      "version": "0.24.5",
+      "resolved": "https://registry.npmjs.org/chrome-remote-interface/-/chrome-remote-interface-0.24.5.tgz",
+      "integrity": "sha512-+RixJXes45Y4XnpAegjaWtDixdS6580aUpK8pzojRHHL89qXXvv0VBEPCoDaB9j0yBS+gMbpZKj2ZSH/45HABw==",
+      "dev": true,
+      "requires": {
+        "commander": "2.1.0",
+        "ws": "2.0.3"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz",
+          "integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=",
+          "dev": true
+        }
+      }
+    },
+    "chromeless": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/chromeless/-/chromeless-1.2.0.tgz",
+      "integrity": "sha1-0ncOIE8+k/1Abda/n7fv2B+z3Bs=",
+      "dev": true,
+      "requires": {
+        "aws-sdk": "2.218.1",
+        "bluebird": "3.5.1",
+        "chrome-launcher": "0.4.0",
+        "chrome-remote-interface": "0.24.5",
+        "cuid": "1.3.8",
+        "form-data": "2.3.2",
+        "got": "7.1.0",
+        "mqtt": "2.17.0"
+      }
+    },
+    "cipher-base": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+      "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "circular-json": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
+      "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
+      "dev": true
+    },
+    "class-utils": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+      "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+      "dev": true,
+      "requires": {
+        "arr-union": "3.1.0",
+        "define-property": "0.2.5",
+        "isobject": "3.0.1",
+        "static-extend": "0.1.2"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+          "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.6"
+              }
+            }
+          }
+        },
+        "is-data-descriptor": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+          "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.6"
+              }
+            }
+          }
+        },
+        "is-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+          "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "0.1.6",
+            "is-data-descriptor": "0.1.4",
+            "kind-of": "5.1.0"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "cli-cursor": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+      "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+      "dev": true,
+      "requires": {
+        "restore-cursor": "2.0.0"
+      }
+    },
+    "cli-width": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+      "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+      "dev": true
+    },
+    "cliui": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz",
+      "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==",
+      "dev": true,
+      "requires": {
+        "string-width": "2.1.1",
+        "strip-ansi": "4.0.0",
+        "wrap-ansi": "2.1.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "3.0.0"
+          }
+        }
+      }
+    },
+    "co": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+      "dev": true
+    },
+    "code-point-at": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+      "dev": true
+    },
+    "collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "requires": {
+        "map-visit": "1.0.0",
+        "object-visit": "1.0.1"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
+      "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
+      "dev": true,
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
+    "colors": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.1.tgz",
+      "integrity": "sha512-s8+wktIuDSLffCywiwSxQOMqtPxML11a/dtHE17tMn4B1MSWw/C22EKf7M2KGUBcDaVFEGT+S8N02geDXeuNKg==",
+      "dev": true
+    },
+    "combine-lists": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz",
+      "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=",
+      "dev": true,
+      "requires": {
+        "lodash": "4.17.5"
+      }
+    },
+    "combined-stream": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
+      "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
+      "dev": true,
+      "requires": {
+        "delayed-stream": "1.0.0"
+      }
+    },
+    "commander": {
+      "version": "2.15.1",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
+      "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
+      "dev": true
+    },
+    "commist": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/commist/-/commist-1.0.0.tgz",
+      "integrity": "sha1-wMNSUBz29S6RJOPvicmAbiAi6+8=",
+      "dev": true,
+      "requires": {
+        "leven": "1.0.2",
+        "minimist": "1.2.0"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "commondir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+      "dev": true
+    },
+    "component-bind": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
+      "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=",
+      "dev": true
+    },
+    "component-emitter": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz",
+      "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=",
+      "dev": true
+    },
+    "component-inherit": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
+      "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=",
+      "dev": true
+    },
+    "compress-commons": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz",
+      "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=",
+      "dev": true,
+      "requires": {
+        "buffer-crc32": "0.2.13",
+        "crc32-stream": "2.0.0",
+        "normalize-path": "2.1.1",
+        "readable-stream": "2.3.5"
+      }
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "dev": true
+    },
+    "concat-stream": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+      "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "1.0.0",
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.5",
+        "typedarray": "0.0.6"
+      }
+    },
+    "connect": {
+      "version": "3.6.6",
+      "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
+      "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "finalhandler": "1.1.0",
+        "parseurl": "1.3.2",
+        "utils-merge": "1.0.1"
+      },
+      "dependencies": {
+        "finalhandler": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
+          "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
+          "dev": true,
+          "requires": {
+            "debug": "2.6.9",
+            "encodeurl": "1.0.2",
+            "escape-html": "1.0.3",
+            "on-finished": "2.3.0",
+            "parseurl": "1.3.2",
+            "statuses": "1.3.1",
+            "unpipe": "1.0.0"
+          }
+        },
+        "statuses": {
+          "version": "1.3.1",
+          "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+          "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
+          "dev": true
+        },
+        "utils-merge": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+          "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+          "dev": true
+        }
+      }
+    },
+    "console-browserify": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
+      "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
+      "dev": true,
+      "requires": {
+        "date-now": "0.1.4"
+      }
+    },
+    "constants-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+      "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
+      "dev": true
+    },
+    "content-disposition": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
+      "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=",
+      "dev": true
+    },
+    "content-type": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+      "dev": true
+    },
+    "convert-source-map": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz",
+      "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=",
+      "dev": true
+    },
+    "cookie": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+      "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
+      "dev": true
+    },
+    "cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
+      "dev": true
+    },
+    "copy-concurrently": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
+      "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
+      "dev": true,
+      "requires": {
+        "aproba": "1.2.0",
+        "fs-write-stream-atomic": "1.0.10",
+        "iferr": "0.1.5",
+        "mkdirp": "0.5.1",
+        "rimraf": "2.6.1",
+        "run-queue": "1.0.3"
+      }
+    },
+    "copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true
+    },
+    "core-js": {
+      "version": "2.5.4",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.4.tgz",
+      "integrity": "sha1-8si/GB8qgLkvNgEhQpzmOi8K6uA=",
+      "dev": true
+    },
+    "core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+      "dev": true
+    },
+    "cors": {
+      "version": "2.8.4",
+      "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz",
+      "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=",
+      "dev": true,
+      "requires": {
+        "object-assign": "4.1.1",
+        "vary": "1.1.2"
+      }
+    },
+    "crc": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/crc/-/crc-3.5.0.tgz",
+      "integrity": "sha1-mLi6fUiWZbo5efWbITgTdBAaGWQ=",
+      "dev": true
+    },
+    "crc32-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz",
+      "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=",
+      "dev": true,
+      "requires": {
+        "crc": "3.5.0",
+        "readable-stream": "2.3.5"
+      }
+    },
+    "create-ecdh": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz",
+      "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "elliptic": "6.4.0"
+      }
+    },
+    "create-hash": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz",
+      "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=",
+      "dev": true,
+      "requires": {
+        "cipher-base": "1.0.4",
+        "inherits": "2.0.3",
+        "ripemd160": "2.0.1",
+        "sha.js": "2.4.11"
+      }
+    },
+    "create-hmac": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz",
+      "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=",
+      "dev": true,
+      "requires": {
+        "cipher-base": "1.0.4",
+        "create-hash": "1.1.3",
+        "inherits": "2.0.3",
+        "ripemd160": "2.0.1",
+        "safe-buffer": "5.1.1",
+        "sha.js": "2.4.11"
+      }
+    },
+    "cross-spawn": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+      "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+      "dev": true,
+      "requires": {
+        "lru-cache": "4.1.2",
+        "shebang-command": "1.2.0",
+        "which": "1.3.0"
+      }
+    },
+    "cryptiles": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+      "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+      "dev": true,
+      "requires": {
+        "boom": "2.10.1"
+      }
+    },
+    "crypto-browserify": {
+      "version": "3.12.0",
+      "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+      "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+      "dev": true,
+      "requires": {
+        "browserify-cipher": "1.0.0",
+        "browserify-sign": "4.0.4",
+        "create-ecdh": "4.0.0",
+        "create-hash": "1.1.3",
+        "create-hmac": "1.1.6",
+        "diffie-hellman": "5.0.2",
+        "inherits": "2.0.3",
+        "pbkdf2": "3.0.14",
+        "public-encrypt": "4.0.0",
+        "randombytes": "2.0.6",
+        "randomfill": "1.0.4"
+      }
+    },
+    "css-line-break": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-1.0.1.tgz",
+      "integrity": "sha1-GfIGOjPpX7KDG4ZEbAuAwYivRQo=",
+      "requires": {
+        "base64-arraybuffer": "0.1.5"
+      }
+    },
+    "cuid": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmjs.org/cuid/-/cuid-1.3.8.tgz",
+      "integrity": "sha1-S4deCWm612T37AcGz0T1+wgx9rc=",
+      "dev": true,
+      "requires": {
+        "browser-fingerprint": "0.0.1",
+        "core-js": "1.2.7",
+        "node-fingerprint": "0.0.2"
+      },
+      "dependencies": {
+        "core-js": {
+          "version": "1.2.7",
+          "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
+          "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=",
+          "dev": true
+        }
+      }
+    },
+    "custom-event": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
+      "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=",
+      "dev": true
+    },
+    "cyclist": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
+      "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=",
+      "dev": true
+    },
+    "d": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
+      "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
+      "dev": true,
+      "requires": {
+        "es5-ext": "0.10.42"
+      }
+    },
+    "dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0"
+      },
+      "dependencies": {
+        "assert-plus": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+          "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+          "dev": true
+        }
+      }
+    },
+    "date-now": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
+      "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
+      "dev": true
+    },
+    "debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "requires": {
+        "ms": "2.0.0"
+      }
+    },
+    "decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "dev": true
+    },
+    "decode-uri-component": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+      "dev": true
+    },
+    "decompress-response": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+      "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+      "dev": true,
+      "requires": {
+        "mimic-response": "1.0.0"
+      }
+    },
+    "deep-eql": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-2.0.2.tgz",
+      "integrity": "sha1-sbrAblbwp2d3aG1Qyf63XC7XZ5o=",
+      "dev": true,
+      "requires": {
+        "type-detect": "3.0.0"
+      },
+      "dependencies": {
+        "type-detect": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-3.0.0.tgz",
+          "integrity": "sha1-RtDMhVOrt7E6NSsNbeov1Y8tm1U=",
+          "dev": true
+        }
+      }
+    },
+    "deep-is": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+      "dev": true
+    },
+    "define-property": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+      "dev": true,
+      "requires": {
+        "is-descriptor": "1.0.2",
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "del": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
+      "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
+      "dev": true,
+      "requires": {
+        "globby": "5.0.0",
+        "is-path-cwd": "1.0.0",
+        "is-path-in-cwd": "1.0.1",
+        "object-assign": "4.1.1",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1",
+        "rimraf": "2.6.1"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+          "dev": true
+        }
+      }
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+      "dev": true
+    },
+    "depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+      "dev": true
+    },
+    "des.js": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
+      "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "minimalistic-assert": "1.0.0"
+      }
+    },
+    "destroy": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+      "dev": true
+    },
+    "detect-indent": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
+      "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
+      "dev": true,
+      "requires": {
+        "repeating": "2.0.1"
+      }
+    },
+    "di": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz",
+      "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=",
+      "dev": true
+    },
+    "diff": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz",
+      "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=",
+      "dev": true
+    },
+    "diffie-hellman": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz",
+      "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "miller-rabin": "4.0.1",
+        "randombytes": "2.0.6"
+      }
+    },
+    "doctrine": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+      "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+      "dev": true,
+      "requires": {
+        "esutils": "2.0.2"
+      }
+    },
+    "dom-serialize": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz",
+      "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=",
+      "dev": true,
+      "requires": {
+        "custom-event": "1.0.1",
+        "ent": "2.2.0",
+        "extend": "3.0.1",
+        "void-elements": "2.0.1"
+      }
+    },
+    "domain-browser": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+      "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
+      "dev": true
+    },
+    "duplexer3": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+      "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+      "dev": true
+    },
+    "duplexify": {
+      "version": "3.5.4",
+      "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.4.tgz",
+      "integrity": "sha512-JzYSLYMhoVVBe8+mbHQ4KgpvHpm0DZpJuL8PY93Vyv1fW7jYJ90LoXa1di/CVbJM+TgMs91rbDapE/RNIfnJsA==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "1.4.1",
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.5",
+        "stream-shift": "1.0.0"
+      }
+    },
+    "ecc-jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+      "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "jsbn": "0.1.1"
+      }
+    },
+    "edge-launcher": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/edge-launcher/-/edge-launcher-1.2.2.tgz",
+      "integrity": "sha1-60Cq+9Bnpup27/+rBke81VCbN7I=",
+      "dev": true
+    },
+    "ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+      "dev": true
+    },
+    "elliptic": {
+      "version": "6.4.0",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz",
+      "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "brorand": "1.1.0",
+        "hash.js": "1.1.3",
+        "hmac-drbg": "1.0.1",
+        "inherits": "2.0.3",
+        "minimalistic-assert": "1.0.0",
+        "minimalistic-crypto-utils": "1.0.1"
+      }
+    },
+    "emojis-list": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
+      "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
+      "dev": true
+    },
+    "encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+      "dev": true
+    },
+    "end-of-stream": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
+      "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+      "dev": true,
+      "requires": {
+        "once": "1.4.0"
+      }
+    },
+    "engine.io": {
+      "version": "1.8.3",
+      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.3.tgz",
+      "integrity": "sha1-jef5eJXSDTm4X4ju7nd7K9QrE9Q=",
+      "dev": true,
+      "requires": {
+        "accepts": "1.3.3",
+        "base64id": "1.0.0",
+        "cookie": "0.3.1",
+        "debug": "2.3.3",
+        "engine.io-parser": "1.3.2",
+        "ws": "1.1.2"
+      },
+      "dependencies": {
+        "accepts": {
+          "version": "1.3.3",
+          "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
+          "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=",
+          "dev": true,
+          "requires": {
+            "mime-types": "2.1.18",
+            "negotiator": "0.6.1"
+          }
+        },
+        "debug": {
+          "version": "2.3.3",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+          "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
+          "dev": true,
+          "requires": {
+            "ms": "0.7.2"
+          }
+        },
+        "ms": {
+          "version": "0.7.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+          "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
+          "dev": true
+        },
+        "ultron": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
+          "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=",
+          "dev": true
+        },
+        "ws": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz",
+          "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=",
+          "dev": true,
+          "requires": {
+            "options": "0.0.6",
+            "ultron": "1.0.2"
+          }
+        }
+      }
+    },
+    "engine.io-client": {
+      "version": "1.8.3",
+      "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.3.tgz",
+      "integrity": "sha1-F5jtk0USRkU9TG9jXXogH+lA1as=",
+      "dev": true,
+      "requires": {
+        "component-emitter": "1.2.1",
+        "component-inherit": "0.0.3",
+        "debug": "2.3.3",
+        "engine.io-parser": "1.3.2",
+        "has-cors": "1.1.0",
+        "indexof": "0.0.1",
+        "parsejson": "0.0.3",
+        "parseqs": "0.0.5",
+        "parseuri": "0.0.5",
+        "ws": "1.1.2",
+        "xmlhttprequest-ssl": "1.5.3",
+        "yeast": "0.1.2"
+      },
+      "dependencies": {
+        "component-emitter": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+          "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+          "dev": true
+        },
+        "debug": {
+          "version": "2.3.3",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+          "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
+          "dev": true,
+          "requires": {
+            "ms": "0.7.2"
+          }
+        },
+        "ms": {
+          "version": "0.7.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+          "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
+          "dev": true
+        },
+        "ultron": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
+          "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=",
+          "dev": true
+        },
+        "ws": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz",
+          "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=",
+          "dev": true,
+          "requires": {
+            "options": "0.0.6",
+            "ultron": "1.0.2"
+          }
+        }
+      }
+    },
+    "engine.io-parser": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz",
+      "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=",
+      "dev": true,
+      "requires": {
+        "after": "0.8.2",
+        "arraybuffer.slice": "0.0.6",
+        "base64-arraybuffer": "0.1.5",
+        "blob": "0.0.4",
+        "has-binary": "0.1.7",
+        "wtf-8": "1.0.0"
+      }
+    },
+    "enhanced-resolve": {
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz",
+      "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "memory-fs": "0.4.1",
+        "object-assign": "4.1.1",
+        "tapable": "0.2.8"
+      }
+    },
+    "ent": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz",
+      "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=",
+      "dev": true
+    },
+    "errno": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+      "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
+      "dev": true,
+      "requires": {
+        "prr": "1.0.1"
+      }
+    },
+    "error-ex": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
+      "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
+      "dev": true,
+      "requires": {
+        "is-arrayish": "0.2.1"
+      }
+    },
+    "es5-ext": {
+      "version": "0.10.42",
+      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.42.tgz",
+      "integrity": "sha512-AJxO1rmPe1bDEfSR6TJ/FgMFYuTBhR5R57KW58iCkYACMyFbrkqVyzXSurYoScDGvgyMpk7uRF/lPUPPTmsRSA==",
+      "dev": true,
+      "requires": {
+        "es6-iterator": "2.0.3",
+        "es6-symbol": "3.1.1",
+        "next-tick": "1.0.0"
+      }
+    },
+    "es6-iterator": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+      "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.42",
+        "es6-symbol": "3.1.1"
+      }
+    },
+    "es6-map": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
+      "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.42",
+        "es6-iterator": "2.0.3",
+        "es6-set": "0.1.5",
+        "es6-symbol": "3.1.1",
+        "event-emitter": "0.3.5"
+      }
+    },
+    "es6-set": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
+      "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.42",
+        "es6-iterator": "2.0.3",
+        "es6-symbol": "3.1.1",
+        "event-emitter": "0.3.5"
+      }
+    },
+    "es6-symbol": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
+      "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.42"
+      }
+    },
+    "es6-weak-map": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
+      "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.42",
+        "es6-iterator": "2.0.3",
+        "es6-symbol": "3.1.1"
+      }
+    },
+    "escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+      "dev": true
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+      "dev": true
+    },
+    "escope": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz",
+      "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=",
+      "dev": true,
+      "requires": {
+        "es6-map": "0.1.5",
+        "es6-weak-map": "2.0.2",
+        "esrecurse": "4.2.1",
+        "estraverse": "4.2.0"
+      }
+    },
+    "eslint": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.2.0.tgz",
+      "integrity": "sha1-orMYQRGxmOAunH88ymJaXgHFaz0=",
+      "dev": true,
+      "requires": {
+        "ajv": "5.5.2",
+        "babel-code-frame": "6.26.0",
+        "chalk": "1.1.3",
+        "concat-stream": "1.6.2",
+        "debug": "2.6.9",
+        "doctrine": "2.1.0",
+        "eslint-scope": "3.7.1",
+        "espree": "3.5.4",
+        "esquery": "1.0.0",
+        "estraverse": "4.2.0",
+        "esutils": "2.0.2",
+        "file-entry-cache": "2.0.0",
+        "glob": "7.1.2",
+        "globals": "9.18.0",
+        "ignore": "3.3.7",
+        "imurmurhash": "0.1.4",
+        "inquirer": "3.3.0",
+        "is-resolvable": "1.1.0",
+        "js-yaml": "3.11.0",
+        "json-stable-stringify": "1.0.1",
+        "levn": "0.3.0",
+        "lodash": "4.17.5",
+        "minimatch": "3.0.4",
+        "mkdirp": "0.5.1",
+        "natural-compare": "1.4.0",
+        "optionator": "0.8.2",
+        "path-is-inside": "1.0.2",
+        "pluralize": "4.0.0",
+        "progress": "2.0.0",
+        "require-uncached": "1.0.3",
+        "strip-json-comments": "2.0.1",
+        "table": "4.0.3",
+        "text-table": "0.2.0"
+      }
+    },
+    "eslint-plugin-flowtype": {
+      "version": "2.35.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.35.0.tgz",
+      "integrity": "sha512-zjXGjOsHds8b84C0Ad3VViKh+sUA9PeXKHwPRlSLwwSX0v1iUJf/6IX7wxc+w2T2tnDH8PT6B/YgtcEuNI3ssA==",
+      "dev": true,
+      "requires": {
+        "lodash": "4.17.5"
+      }
+    },
+    "eslint-plugin-prettier": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.1.2.tgz",
+      "integrity": "sha1-S5D07n+Sv74ukmAX4cpA62KJZeo=",
+      "dev": true,
+      "requires": {
+        "fast-diff": "1.1.2",
+        "jest-docblock": "20.0.3"
+      }
+    },
+    "eslint-scope": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
+      "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
+      "dev": true,
+      "requires": {
+        "esrecurse": "4.2.1",
+        "estraverse": "4.2.0"
+      }
+    },
+    "espree": {
+      "version": "3.5.4",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
+      "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
+      "dev": true,
+      "requires": {
+        "acorn": "5.5.3",
+        "acorn-jsx": "3.0.1"
+      }
+    },
+    "esprima": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
+      "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
+      "dev": true
+    },
+    "esquery": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz",
+      "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=",
+      "dev": true,
+      "requires": {
+        "estraverse": "4.2.0"
+      }
+    },
+    "esrecurse": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+      "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+      "dev": true,
+      "requires": {
+        "estraverse": "4.2.0"
+      }
+    },
+    "estraverse": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+      "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+      "dev": true
+    },
+    "esutils": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+      "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+      "dev": true
+    },
+    "etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+      "dev": true
+    },
+    "event-emitter": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+      "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.42"
+      }
+    },
+    "eventemitter3": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz",
+      "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=",
+      "dev": true
+    },
+    "events": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
+      "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=",
+      "dev": true
+    },
+    "evp_bytestokey": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+      "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+      "dev": true,
+      "requires": {
+        "md5.js": "1.3.4",
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "execa": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+      "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "5.1.0",
+        "get-stream": "3.0.0",
+        "is-stream": "1.1.0",
+        "npm-run-path": "2.0.2",
+        "p-finally": "1.0.0",
+        "signal-exit": "3.0.2",
+        "strip-eof": "1.0.0"
+      }
+    },
+    "expand-braces": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz",
+      "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=",
+      "dev": true,
+      "requires": {
+        "array-slice": "0.2.3",
+        "array-unique": "0.2.1",
+        "braces": "0.1.5"
+      },
+      "dependencies": {
+        "braces": {
+          "version": "0.1.5",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz",
+          "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=",
+          "dev": true,
+          "requires": {
+            "expand-range": "0.1.1"
+          }
+        },
+        "expand-range": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz",
+          "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=",
+          "dev": true,
+          "requires": {
+            "is-number": "0.1.1",
+            "repeat-string": "0.2.2"
+          }
+        },
+        "is-number": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz",
+          "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=",
+          "dev": true
+        },
+        "repeat-string": {
+          "version": "0.2.2",
+          "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz",
+          "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=",
+          "dev": true
+        }
+      }
+    },
+    "expand-brackets": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+      "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+      "dev": true,
+      "requires": {
+        "is-posix-bracket": "0.1.1"
+      }
+    },
+    "expand-range": {
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
+      "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
+      "dev": true,
+      "requires": {
+        "fill-range": "2.2.3"
+      }
+    },
+    "express": {
+      "version": "4.15.4",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.15.4.tgz",
+      "integrity": "sha1-Ay4iU0ic+PzgJma+yj0R7XotrtE=",
+      "dev": true,
+      "requires": {
+        "accepts": "1.3.5",
+        "array-flatten": "1.1.1",
+        "content-disposition": "0.5.2",
+        "content-type": "1.0.4",
+        "cookie": "0.3.1",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.8",
+        "depd": "1.1.2",
+        "encodeurl": "1.0.2",
+        "escape-html": "1.0.3",
+        "etag": "1.8.1",
+        "finalhandler": "1.0.6",
+        "fresh": "0.5.0",
+        "merge-descriptors": "1.0.1",
+        "methods": "1.1.2",
+        "on-finished": "2.3.0",
+        "parseurl": "1.3.2",
+        "path-to-regexp": "0.1.7",
+        "proxy-addr": "1.1.5",
+        "qs": "6.5.0",
+        "range-parser": "1.2.0",
+        "send": "0.15.4",
+        "serve-static": "1.12.4",
+        "setprototypeof": "1.0.3",
+        "statuses": "1.3.1",
+        "type-is": "1.6.16",
+        "utils-merge": "1.0.0",
+        "vary": "1.1.2"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.8",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+          "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "qs": {
+          "version": "6.5.0",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.0.tgz",
+          "integrity": "sha512-fjVFjW9yhqMhVGwRExCXLhJKrLlkYSaxNWdyc9rmHlrVZbk35YHH312dFd7191uQeXkI3mKLZTIbSvIeFwFemg==",
+          "dev": true
+        },
+        "setprototypeof": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
+          "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=",
+          "dev": true
+        },
+        "statuses": {
+          "version": "1.3.1",
+          "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+          "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
+          "dev": true
+        }
+      }
+    },
+    "extend": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+      "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+      "dev": true
+    },
+    "extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "requires": {
+        "assign-symbols": "1.0.0",
+        "is-extendable": "1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "2.0.4"
+          }
+        }
+      }
+    },
+    "external-editor": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz",
+      "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==",
+      "dev": true,
+      "requires": {
+        "chardet": "0.4.2",
+        "iconv-lite": "0.4.19",
+        "tmp": "0.0.33"
+      },
+      "dependencies": {
+        "iconv-lite": {
+          "version": "0.4.19",
+          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+          "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==",
+          "dev": true
+        }
+      }
+    },
+    "extglob": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+      "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+      "dev": true,
+      "requires": {
+        "is-extglob": "1.0.0"
+      }
+    },
+    "extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+      "dev": true
+    },
+    "fast-deep-equal": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
+      "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
+      "dev": true
+    },
+    "fast-diff": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz",
+      "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==",
+      "dev": true
+    },
+    "fast-json-stable-stringify": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+      "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
+      "dev": true
+    },
+    "fast-levenshtein": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+      "dev": true
+    },
+    "figures": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+      "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "1.0.5"
+      }
+    },
+    "file-entry-cache": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
+      "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
+      "dev": true,
+      "requires": {
+        "flat-cache": "1.3.0",
+        "object-assign": "4.1.1"
+      }
+    },
+    "filename-regex": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
+      "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
+      "dev": true
+    },
+    "filename-reserved-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz",
+      "integrity": "sha1-5hz4BfDeHJhFZ9A4bcXfUO5a9+Q=",
+      "dev": true
+    },
+    "filenamify": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-1.2.1.tgz",
+      "integrity": "sha1-qfL/0RxQO+0wABUCknI3jx8TZaU=",
+      "dev": true,
+      "requires": {
+        "filename-reserved-regex": "1.0.0",
+        "strip-outer": "1.0.1",
+        "trim-repeated": "1.0.0"
+      }
+    },
+    "filenamify-url": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/filenamify-url/-/filenamify-url-1.0.0.tgz",
+      "integrity": "sha1-syvYExnvWGO3MHi+1Q9GpPeXX1A=",
+      "dev": true,
+      "requires": {
+        "filenamify": "1.2.1",
+        "humanize-url": "1.0.1"
+      }
+    },
+    "fill-range": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz",
+      "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=",
+      "dev": true,
+      "requires": {
+        "is-number": "2.1.0",
+        "isobject": "2.1.0",
+        "randomatic": "1.1.7",
+        "repeat-element": "1.1.2",
+        "repeat-string": "1.6.1"
+      }
+    },
+    "finalhandler": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.6.tgz",
+      "integrity": "sha1-AHrqM9Gk0+QgF/YkhIrVjSEvgU8=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "encodeurl": "1.0.2",
+        "escape-html": "1.0.3",
+        "on-finished": "2.3.0",
+        "parseurl": "1.3.2",
+        "statuses": "1.3.1",
+        "unpipe": "1.0.0"
+      },
+      "dependencies": {
+        "statuses": {
+          "version": "1.3.1",
+          "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+          "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
+          "dev": true
+        }
+      }
+    },
+    "find-cache-dir": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz",
+      "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=",
+      "dev": true,
+      "requires": {
+        "commondir": "1.0.1",
+        "make-dir": "1.2.0",
+        "pkg-dir": "2.0.0"
+      }
+    },
+    "find-up": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+      "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+      "dev": true,
+      "requires": {
+        "locate-path": "2.0.0"
+      }
+    },
+    "flat-cache": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
+      "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
+      "dev": true,
+      "requires": {
+        "circular-json": "0.3.3",
+        "del": "2.2.2",
+        "graceful-fs": "4.1.11",
+        "write": "0.2.1"
+      }
+    },
+    "flow-bin": {
+      "version": "0.56.0",
+      "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.56.0.tgz",
+      "integrity": "sha1-zkMJIgOjRLqb9jwMq+ldlRRfbK0=",
+      "dev": true
+    },
+    "flush-write-stream": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz",
+      "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.5"
+      }
+    },
+    "for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true
+    },
+    "for-own": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
+      "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
+      "dev": true,
+      "requires": {
+        "for-in": "1.0.2"
+      }
+    },
+    "forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+      "dev": true
+    },
+    "form-data": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
+      "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
+      "dev": true,
+      "requires": {
+        "asynckit": "0.4.0",
+        "combined-stream": "1.0.6",
+        "mime-types": "2.1.18"
+      }
+    },
+    "forwarded": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+      "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+      "dev": true
+    },
+    "fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "dev": true,
+      "requires": {
+        "map-cache": "0.2.2"
+      }
+    },
+    "fresh": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz",
+      "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44=",
+      "dev": true
+    },
+    "from2": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+      "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.5"
+      }
+    },
+    "fs-access": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz",
+      "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=",
+      "dev": true,
+      "requires": {
+        "null-check": "1.0.0"
+      }
+    },
+    "fs-readdir-recursive": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
+      "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==",
+      "dev": true
+    },
+    "fs-write-stream-atomic": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
+      "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "iferr": "0.1.5",
+        "imurmurhash": "0.1.4",
+        "readable-stream": "2.3.5"
+      }
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "dev": true
+    },
+    "generate-function": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
+      "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=",
+      "dev": true
+    },
+    "generate-object-property": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
+      "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
+      "dev": true,
+      "requires": {
+        "is-property": "1.0.2"
+      }
+    },
+    "get-caller-file": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
+      "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=",
+      "dev": true
+    },
+    "get-func-name": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
+      "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
+      "dev": true
+    },
+    "get-stream": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+      "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+      "dev": true
+    },
+    "get-value": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "dev": true
+    },
+    "getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0"
+      },
+      "dependencies": {
+        "assert-plus": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+          "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+          "dev": true
+        }
+      }
+    },
+    "glob": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+      "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+      "dev": true,
+      "requires": {
+        "fs.realpath": "1.0.0",
+        "inflight": "1.0.6",
+        "inherits": "2.0.3",
+        "minimatch": "3.0.4",
+        "once": "1.4.0",
+        "path-is-absolute": "1.0.1"
+      }
+    },
+    "glob-base": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
+      "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
+      "dev": true,
+      "requires": {
+        "glob-parent": "2.0.0",
+        "is-glob": "2.0.1"
+      }
+    },
+    "glob-parent": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
+      "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+      "dev": true,
+      "requires": {
+        "is-glob": "2.0.1"
+      }
+    },
+    "glob-stream": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz",
+      "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=",
+      "dev": true,
+      "requires": {
+        "extend": "3.0.1",
+        "glob": "7.1.2",
+        "glob-parent": "3.1.0",
+        "is-negated-glob": "1.0.0",
+        "ordered-read-streams": "1.0.1",
+        "pumpify": "1.4.0",
+        "readable-stream": "2.3.5",
+        "remove-trailing-separator": "1.1.0",
+        "to-absolute-glob": "2.0.2",
+        "unique-stream": "2.2.1"
+      },
+      "dependencies": {
+        "glob-parent": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+          "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+          "dev": true,
+          "requires": {
+            "is-glob": "3.1.0",
+            "path-dirname": "1.0.2"
+          }
+        },
+        "is-extglob": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+          "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+          "dev": true
+        },
+        "is-glob": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+          "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+          "dev": true,
+          "requires": {
+            "is-extglob": "2.1.1"
+          }
+        }
+      }
+    },
+    "globals": {
+      "version": "9.18.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+      "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+      "dev": true
+    },
+    "globby": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
+      "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
+      "dev": true,
+      "requires": {
+        "array-union": "1.0.2",
+        "arrify": "1.0.1",
+        "glob": "7.1.2",
+        "object-assign": "4.1.1",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+          "dev": true
+        }
+      }
+    },
+    "got": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
+      "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
+      "dev": true,
+      "requires": {
+        "decompress-response": "3.3.0",
+        "duplexer3": "0.1.4",
+        "get-stream": "3.0.0",
+        "is-plain-obj": "1.1.0",
+        "is-retry-allowed": "1.1.0",
+        "is-stream": "1.1.0",
+        "isurl": "1.0.0",
+        "lowercase-keys": "1.0.1",
+        "p-cancelable": "0.3.0",
+        "p-timeout": "1.2.1",
+        "safe-buffer": "5.1.1",
+        "timed-out": "4.0.1",
+        "url-parse-lax": "1.0.0",
+        "url-to-options": "1.0.1"
+      }
+    },
+    "graceful-fs": {
+      "version": "4.1.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+      "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+      "dev": true
+    },
+    "graceful-readlink": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
+      "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
+      "dev": true
+    },
+    "growl": {
+      "version": "1.9.2",
+      "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz",
+      "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=",
+      "dev": true
+    },
+    "har-schema": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
+      "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=",
+      "dev": true
+    },
+    "har-validator": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz",
+      "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=",
+      "dev": true,
+      "requires": {
+        "ajv": "4.11.8",
+        "har-schema": "1.0.5"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "4.11.8",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+          "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
+          "dev": true,
+          "requires": {
+            "co": "4.6.0",
+            "json-stable-stringify": "1.0.1"
+          }
+        }
+      }
+    },
+    "has-ansi": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "2.1.1"
+      }
+    },
+    "has-binary": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz",
+      "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=",
+      "dev": true,
+      "requires": {
+        "isarray": "0.0.1"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+          "dev": true
+        }
+      }
+    },
+    "has-cors": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
+      "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=",
+      "dev": true
+    },
+    "has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "dev": true
+    },
+    "has-symbol-support-x": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz",
+      "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==",
+      "dev": true
+    },
+    "has-to-string-tag-x": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
+      "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
+      "dev": true,
+      "requires": {
+        "has-symbol-support-x": "1.4.2"
+      }
+    },
+    "has-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "dev": true,
+      "requires": {
+        "get-value": "2.0.6",
+        "has-values": "1.0.0",
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "has-values": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+      "dev": true,
+      "requires": {
+        "is-number": "3.0.0",
+        "kind-of": "4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.6"
+              }
+            }
+          }
+        },
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "1.1.6"
+          }
+        }
+      }
+    },
+    "hash-base": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
+      "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3"
+      }
+    },
+    "hash.js": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
+      "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "minimalistic-assert": "1.0.0"
+      }
+    },
+    "hawk": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+      "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+      "dev": true,
+      "requires": {
+        "boom": "2.10.1",
+        "cryptiles": "2.0.5",
+        "hoek": "2.16.3",
+        "sntp": "1.0.9"
+      }
+    },
+    "help-me": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/help-me/-/help-me-1.1.0.tgz",
+      "integrity": "sha1-jy1QjQYAtKRW2i8IZVbn5cBWo8Y=",
+      "dev": true,
+      "requires": {
+        "callback-stream": "1.1.0",
+        "glob-stream": "6.1.0",
+        "through2": "2.0.3",
+        "xtend": "4.0.1"
+      }
+    },
+    "hmac-drbg": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+      "dev": true,
+      "requires": {
+        "hash.js": "1.1.3",
+        "minimalistic-assert": "1.0.0",
+        "minimalistic-crypto-utils": "1.0.1"
+      }
+    },
+    "hoek": {
+      "version": "2.16.3",
+      "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+      "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+      "dev": true
+    },
+    "home-or-tmp": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
+      "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
+      "dev": true,
+      "requires": {
+        "os-homedir": "1.0.2",
+        "os-tmpdir": "1.0.2"
+      }
+    },
+    "hosted-git-info": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz",
+      "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==",
+      "dev": true
+    },
+    "html2canvas-proxy": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/html2canvas-proxy/-/html2canvas-proxy-1.0.0.tgz",
+      "integrity": "sha1-DF+vxjz1plQ5xklvhQs3Bios7UQ=",
+      "dev": true,
+      "requires": {
+        "cors": "2.8.4",
+        "request": "2.81.0"
+      }
+    },
+    "http-errors": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+      "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
+      "dev": true,
+      "requires": {
+        "depd": "1.1.2",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.1.0",
+        "statuses": "1.5.0"
+      }
+    },
+    "http-proxy": {
+      "version": "1.16.2",
+      "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz",
+      "integrity": "sha1-Bt/ykpUr9k2+hHH6nfcwZtTzd0I=",
+      "dev": true,
+      "requires": {
+        "eventemitter3": "1.2.0",
+        "requires-port": "1.0.0"
+      }
+    },
+    "http-signature": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+      "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "0.2.0",
+        "jsprim": "1.4.1",
+        "sshpk": "1.14.1"
+      }
+    },
+    "https-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+      "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
+      "dev": true
+    },
+    "https-proxy-agent": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz",
+      "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=",
+      "dev": true,
+      "requires": {
+        "agent-base": "2.1.1",
+        "debug": "2.6.9",
+        "extend": "3.0.1"
+      }
+    },
+    "humanize-url": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/humanize-url/-/humanize-url-1.0.1.tgz",
+      "integrity": "sha1-9KuZ4NKIF0yk4eUEB8VfuuRk7/8=",
+      "dev": true,
+      "requires": {
+        "normalize-url": "1.9.1",
+        "strip-url-auth": "1.0.1"
+      }
+    },
+    "iconv-lite": {
+      "version": "0.4.15",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz",
+      "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=",
+      "dev": true
+    },
+    "ieee754": {
+      "version": "1.1.8",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
+      "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=",
+      "dev": true
+    },
+    "iferr": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
+      "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
+      "dev": true
+    },
+    "ignore": {
+      "version": "3.3.7",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz",
+      "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==",
+      "dev": true
+    },
+    "imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "dev": true
+    },
+    "indexof": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
+      "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=",
+      "dev": true
+    },
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "dev": true,
+      "requires": {
+        "once": "1.4.0",
+        "wrappy": "1.0.2"
+      }
+    },
+    "inherits": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+      "dev": true
+    },
+    "inquirer": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
+      "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
+      "dev": true,
+      "requires": {
+        "ansi-escapes": "3.1.0",
+        "chalk": "2.3.2",
+        "cli-cursor": "2.1.0",
+        "cli-width": "2.2.0",
+        "external-editor": "2.1.0",
+        "figures": "2.0.0",
+        "lodash": "4.17.5",
+        "mute-stream": "0.0.7",
+        "run-async": "2.3.0",
+        "rx-lite": "4.0.8",
+        "rx-lite-aggregates": "4.0.8",
+        "string-width": "2.1.1",
+        "strip-ansi": "4.0.0",
+        "through": "2.3.8"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.1"
+          }
+        },
+        "chalk": {
+          "version": "2.3.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz",
+          "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.1",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.3.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "3.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.3.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz",
+          "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        }
+      }
+    },
+    "interpret": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
+      "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=",
+      "dev": true
+    },
+    "invariant": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+      "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+      "dev": true,
+      "requires": {
+        "loose-envify": "1.3.1"
+      }
+    },
+    "invert-kv": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+      "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
+      "dev": true
+    },
+    "ipaddr.js": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.4.0.tgz",
+      "integrity": "sha1-KWrKh4qCGBbluF0KKFqZvP9FgvA=",
+      "dev": true
+    },
+    "is-absolute": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
+      "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
+      "dev": true,
+      "requires": {
+        "is-relative": "1.0.0",
+        "is-windows": "1.0.2"
+      }
+    },
+    "is-accessor-descriptor": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+      "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+      "dev": true,
+      "requires": {
+        "kind-of": "6.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "dev": true
+    },
+    "is-binary-path": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+      "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+      "dev": true,
+      "requires": {
+        "binary-extensions": "1.11.0"
+      }
+    },
+    "is-buffer": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+      "dev": true
+    },
+    "is-builtin-module": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+      "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+      "dev": true,
+      "requires": {
+        "builtin-modules": "1.1.1"
+      }
+    },
+    "is-data-descriptor": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+      "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+      "dev": true,
+      "requires": {
+        "kind-of": "6.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "is-descriptor": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+      "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+      "dev": true,
+      "requires": {
+        "is-accessor-descriptor": "1.0.0",
+        "is-data-descriptor": "1.0.0",
+        "kind-of": "6.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "is-dotfile": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
+      "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=",
+      "dev": true
+    },
+    "is-equal-shallow": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
+      "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
+      "dev": true,
+      "requires": {
+        "is-primitive": "2.0.0"
+      }
+    },
+    "is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+      "dev": true
+    },
+    "is-extglob": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+      "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+      "dev": true
+    },
+    "is-finite": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+      "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+      "dev": true,
+      "requires": {
+        "number-is-nan": "1.0.1"
+      }
+    },
+    "is-fullwidth-code-point": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+      "dev": true
+    },
+    "is-glob": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+      "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+      "dev": true,
+      "requires": {
+        "is-extglob": "1.0.0"
+      }
+    },
+    "is-my-ip-valid": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz",
+      "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==",
+      "dev": true
+    },
+    "is-my-json-valid": {
+      "version": "2.17.2",
+      "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz",
+      "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==",
+      "dev": true,
+      "requires": {
+        "generate-function": "2.0.0",
+        "generate-object-property": "1.2.0",
+        "is-my-ip-valid": "1.0.0",
+        "jsonpointer": "4.0.1",
+        "xtend": "4.0.1"
+      }
+    },
+    "is-negated-glob": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
+      "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=",
+      "dev": true
+    },
+    "is-number": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
+      "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "is-object": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
+      "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=",
+      "dev": true
+    },
+    "is-odd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz",
+      "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==",
+      "dev": true,
+      "requires": {
+        "is-number": "4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+          "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+          "dev": true
+        }
+      }
+    },
+    "is-path-cwd": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
+      "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
+      "dev": true
+    },
+    "is-path-in-cwd": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz",
+      "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==",
+      "dev": true,
+      "requires": {
+        "is-path-inside": "1.0.1"
+      }
+    },
+    "is-path-inside": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
+      "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
+      "dev": true,
+      "requires": {
+        "path-is-inside": "1.0.2"
+      }
+    },
+    "is-plain-obj": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+      "dev": true
+    },
+    "is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "dev": true,
+      "requires": {
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "is-posix-bracket": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
+      "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=",
+      "dev": true
+    },
+    "is-primitive": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
+      "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=",
+      "dev": true
+    },
+    "is-promise": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+      "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
+      "dev": true
+    },
+    "is-property": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
+      "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
+      "dev": true
+    },
+    "is-relative": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
+      "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
+      "dev": true,
+      "requires": {
+        "is-unc-path": "1.0.0"
+      }
+    },
+    "is-resolvable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+      "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
+      "dev": true
+    },
+    "is-retry-allowed": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
+      "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=",
+      "dev": true
+    },
+    "is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+      "dev": true
+    },
+    "is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "dev": true
+    },
+    "is-unc-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
+      "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
+      "dev": true,
+      "requires": {
+        "unc-path-regex": "0.1.2"
+      }
+    },
+    "is-windows": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+      "dev": true
+    },
+    "isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "isbinaryfile": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.2.tgz",
+      "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=",
+      "dev": true
+    },
+    "isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "dev": true
+    },
+    "isobject": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+      "dev": true,
+      "requires": {
+        "isarray": "1.0.0"
+      }
+    },
+    "isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+      "dev": true
+    },
+    "isurl": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
+      "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
+      "dev": true,
+      "requires": {
+        "has-to-string-tag-x": "1.4.1",
+        "is-object": "1.0.1"
+      }
+    },
+    "jest-docblock": {
+      "version": "20.0.3",
+      "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-20.0.3.tgz",
+      "integrity": "sha1-F76phDQswz2DxQ++FUXqDvqkRxI=",
+      "dev": true
+    },
+    "jmespath": {
+      "version": "0.15.0",
+      "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz",
+      "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=",
+      "dev": true
+    },
+    "jquery": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz",
+      "integrity": "sha1-XE2d5lKvbNCncBVKYxu6ErAVx4c=",
+      "dev": true
+    },
+    "js-tokens": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+      "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+      "dev": true
+    },
+    "js-yaml": {
+      "version": "3.11.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz",
+      "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==",
+      "dev": true,
+      "requires": {
+        "argparse": "1.0.10",
+        "esprima": "4.0.0"
+      }
+    },
+    "jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+      "dev": true,
+      "optional": true
+    },
+    "jsesc": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
+      "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
+      "dev": true
+    },
+    "json-loader": {
+      "version": "0.5.7",
+      "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz",
+      "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==",
+      "dev": true
+    },
+    "json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+      "dev": true
+    },
+    "json-schema-traverse": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+      "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
+      "dev": true
+    },
+    "json-stable-stringify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+      "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+      "dev": true,
+      "requires": {
+        "jsonify": "0.0.0"
+      }
+    },
+    "json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+      "dev": true
+    },
+    "json3": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz",
+      "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=",
+      "dev": true
+    },
+    "json5": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+      "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+      "dev": true
+    },
+    "jsonify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+      "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+      "dev": true
+    },
+    "jsonpointer": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
+      "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
+      "dev": true
+    },
+    "jsprim": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.2.3",
+        "verror": "1.10.0"
+      },
+      "dependencies": {
+        "assert-plus": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+          "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+          "dev": true
+        }
+      }
+    },
+    "karma": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/karma/-/karma-1.7.0.tgz",
+      "integrity": "sha1-b3oaQGRG+i4YfslTmGmPTO5HYmk=",
+      "dev": true,
+      "requires": {
+        "bluebird": "3.5.1",
+        "body-parser": "1.17.2",
+        "chokidar": "1.7.0",
+        "colors": "1.2.1",
+        "combine-lists": "1.0.1",
+        "connect": "3.6.6",
+        "core-js": "2.5.4",
+        "di": "0.0.1",
+        "dom-serialize": "2.2.1",
+        "expand-braces": "0.1.2",
+        "glob": "7.1.2",
+        "graceful-fs": "4.1.11",
+        "http-proxy": "1.16.2",
+        "isbinaryfile": "3.0.2",
+        "lodash": "3.10.1",
+        "log4js": "0.6.38",
+        "mime": "1.3.4",
+        "minimatch": "3.0.4",
+        "optimist": "0.6.1",
+        "qjobs": "1.2.0",
+        "range-parser": "1.2.0",
+        "rimraf": "2.6.1",
+        "safe-buffer": "5.1.1",
+        "socket.io": "1.7.3",
+        "source-map": "0.5.7",
+        "tmp": "0.0.31",
+        "useragent": "2.3.0"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "3.10.1",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+          "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
+          "dev": true
+        },
+        "tmp": {
+          "version": "0.0.31",
+          "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz",
+          "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=",
+          "dev": true,
+          "requires": {
+            "os-tmpdir": "1.0.2"
+          }
+        }
+      }
+    },
+    "karma-chrome-launcher": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz",
+      "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==",
+      "dev": true,
+      "requires": {
+        "fs-access": "1.0.1",
+        "which": "1.3.0"
+      }
+    },
+    "karma-edge-launcher": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/karma-edge-launcher/-/karma-edge-launcher-0.4.1.tgz",
+      "integrity": "sha1-sE65a4z2AE66Cw/tKUtR2pNg4kQ=",
+      "dev": true,
+      "requires": {
+        "edge-launcher": "1.2.2"
+      }
+    },
+    "karma-firefox-launcher": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-1.0.1.tgz",
+      "integrity": "sha1-zlj0fCATqIFW1VpdYTN8CZz1u1E=",
+      "dev": true
+    },
+    "karma-ie-launcher": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/karma-ie-launcher/-/karma-ie-launcher-1.0.0.tgz",
+      "integrity": "sha1-SXmGhCxJAZA0bNifVJTKmDDG1Zw=",
+      "dev": true,
+      "requires": {
+        "lodash": "4.17.5"
+      }
+    },
+    "karma-mocha": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-1.3.0.tgz",
+      "integrity": "sha1-7qrH/8DiAetjxGdEDStpx883eL8=",
+      "dev": true,
+      "requires": {
+        "minimist": "1.2.0"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "karma-sauce-launcher": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/karma-sauce-launcher/-/karma-sauce-launcher-1.1.0.tgz",
+      "integrity": "sha1-PQg89WWdZzarl7zuXYrNhq1SIhI=",
+      "dev": true,
+      "requires": {
+        "q": "1.5.1",
+        "sauce-connect-launcher": "0.17.0",
+        "saucelabs": "1.4.0",
+        "wd": "1.6.1"
+      }
+    },
+    "kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "requires": {
+        "is-buffer": "1.1.6"
+      }
+    },
+    "lazy-cache": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
+      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
+      "dev": true
+    },
+    "lazystream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
+      "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "2.3.5"
+      }
+    },
+    "lcid": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+      "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+      "dev": true,
+      "requires": {
+        "invert-kv": "1.0.0"
+      }
+    },
+    "leven": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/leven/-/leven-1.0.2.tgz",
+      "integrity": "sha1-kUS27ryl8dBoAWnxpncNzqYLdcM=",
+      "dev": true
+    },
+    "levn": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+      "dev": true,
+      "requires": {
+        "prelude-ls": "1.1.2",
+        "type-check": "0.3.2"
+      }
+    },
+    "lighthouse-logger": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.0.1.tgz",
+      "integrity": "sha1-8HPYP3rLyWcpvxAKEhyPAGmRrmE=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9"
+      }
+    },
+    "load-json-file": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+      "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "parse-json": "2.2.0",
+        "pify": "2.3.0",
+        "strip-bom": "3.0.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+          "dev": true
+        }
+      }
+    },
+    "loader-runner": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz",
+      "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=",
+      "dev": true
+    },
+    "loader-utils": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
+      "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+      "dev": true,
+      "requires": {
+        "big.js": "3.2.0",
+        "emojis-list": "2.1.0",
+        "json5": "0.5.1"
+      }
+    },
+    "locate-path": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+      "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+      "dev": true,
+      "requires": {
+        "p-locate": "2.0.0",
+        "path-exists": "3.0.0"
+      }
+    },
+    "lodash": {
+      "version": "4.17.5",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz",
+      "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==",
+      "dev": true
+    },
+    "lodash._baseassign": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz",
+      "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=",
+      "dev": true,
+      "requires": {
+        "lodash._basecopy": "3.0.1",
+        "lodash.keys": "3.1.2"
+      }
+    },
+    "lodash._basecopy": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz",
+      "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=",
+      "dev": true
+    },
+    "lodash._basecreate": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz",
+      "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=",
+      "dev": true
+    },
+    "lodash._getnative": {
+      "version": "3.9.1",
+      "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
+      "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=",
+      "dev": true
+    },
+    "lodash._isiterateecall": {
+      "version": "3.0.9",
+      "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz",
+      "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=",
+      "dev": true
+    },
+    "lodash.create": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz",
+      "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=",
+      "dev": true,
+      "requires": {
+        "lodash._baseassign": "3.2.0",
+        "lodash._basecreate": "3.0.3",
+        "lodash._isiterateecall": "3.0.9"
+      }
+    },
+    "lodash.isarguments": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
+      "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=",
+      "dev": true
+    },
+    "lodash.isarray": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
+      "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=",
+      "dev": true
+    },
+    "lodash.keys": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
+      "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
+      "dev": true,
+      "requires": {
+        "lodash._getnative": "3.9.1",
+        "lodash.isarguments": "3.1.0",
+        "lodash.isarray": "3.0.4"
+      }
+    },
+    "log4js": {
+      "version": "0.6.38",
+      "resolved": "https://registry.npmjs.org/log4js/-/log4js-0.6.38.tgz",
+      "integrity": "sha1-LElBFmldb7JUgJQ9P8hy5mKlIv0=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "1.0.34",
+        "semver": "4.3.6"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "1.0.34",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+          "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+          "dev": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "0.0.1",
+            "string_decoder": "0.10.31"
+          }
+        },
+        "string_decoder": {
+          "version": "0.10.31",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+          "dev": true
+        }
+      }
+    },
+    "longest": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+      "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
+      "dev": true
+    },
+    "loose-envify": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
+      "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
+      "dev": true,
+      "requires": {
+        "js-tokens": "3.0.2"
+      }
+    },
+    "lowercase-keys": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+      "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+      "dev": true
+    },
+    "lru-cache": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz",
+      "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==",
+      "dev": true,
+      "requires": {
+        "pseudomap": "1.0.2",
+        "yallist": "2.1.2"
+      }
+    },
+    "make-dir": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz",
+      "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==",
+      "dev": true,
+      "requires": {
+        "pify": "3.0.0"
+      }
+    },
+    "map-cache": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "dev": true
+    },
+    "map-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+      "dev": true,
+      "requires": {
+        "object-visit": "1.0.1"
+      }
+    },
+    "md5.js": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
+      "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=",
+      "dev": true,
+      "requires": {
+        "hash-base": "3.0.4",
+        "inherits": "2.0.3"
+      },
+      "dependencies": {
+        "hash-base": {
+          "version": "3.0.4",
+          "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
+          "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+          "dev": true,
+          "requires": {
+            "inherits": "2.0.3",
+            "safe-buffer": "5.1.1"
+          }
+        }
+      }
+    },
+    "media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+      "dev": true
+    },
+    "mem": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz",
+      "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=",
+      "dev": true,
+      "requires": {
+        "mimic-fn": "1.2.0"
+      }
+    },
+    "memory-fs": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
+      "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
+      "dev": true,
+      "requires": {
+        "errno": "0.1.7",
+        "readable-stream": "2.3.5"
+      }
+    },
+    "merge-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+      "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
+      "dev": true
+    },
+    "methods": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+      "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+      "dev": true
+    },
+    "micromatch": {
+      "version": "2.3.11",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+      "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+      "dev": true,
+      "requires": {
+        "arr-diff": "2.0.0",
+        "array-unique": "0.2.1",
+        "braces": "1.8.5",
+        "expand-brackets": "0.1.5",
+        "extglob": "0.3.2",
+        "filename-regex": "2.0.1",
+        "is-extglob": "1.0.0",
+        "is-glob": "2.0.1",
+        "kind-of": "3.2.2",
+        "normalize-path": "2.1.1",
+        "object.omit": "2.0.1",
+        "parse-glob": "3.0.4",
+        "regex-cache": "0.4.4"
+      }
+    },
+    "miller-rabin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+      "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "brorand": "1.1.0"
+      }
+    },
+    "mime": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
+      "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=",
+      "dev": true
+    },
+    "mime-db": {
+      "version": "1.33.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
+      "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
+      "dev": true
+    },
+    "mime-types": {
+      "version": "2.1.18",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
+      "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
+      "dev": true,
+      "requires": {
+        "mime-db": "1.33.0"
+      }
+    },
+    "mimic-fn": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+      "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+      "dev": true
+    },
+    "mimic-response": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz",
+      "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=",
+      "dev": true
+    },
+    "minimalistic-assert": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz",
+      "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=",
+      "dev": true
+    },
+    "minimalistic-crypto-utils": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+      "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+      "dev": true
+    },
+    "minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "dev": true,
+      "requires": {
+        "brace-expansion": "1.1.11"
+      }
+    },
+    "minimist": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+      "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+      "dev": true
+    },
+    "mississippi": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz",
+      "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==",
+      "dev": true,
+      "requires": {
+        "concat-stream": "1.6.2",
+        "duplexify": "3.5.4",
+        "end-of-stream": "1.4.1",
+        "flush-write-stream": "1.0.3",
+        "from2": "2.3.0",
+        "parallel-transform": "1.1.0",
+        "pump": "2.0.1",
+        "pumpify": "1.4.0",
+        "stream-each": "1.2.2",
+        "through2": "2.0.3"
+      },
+      "dependencies": {
+        "pump": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+          "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+          "dev": true,
+          "requires": {
+            "end-of-stream": "1.4.1",
+            "once": "1.4.0"
+          }
+        }
+      }
+    },
+    "mixin-deep": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
+      "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+      "dev": true,
+      "requires": {
+        "for-in": "1.0.2",
+        "is-extendable": "1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "2.0.4"
+          }
+        }
+      }
+    },
+    "mkdirp": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+      "dev": true,
+      "requires": {
+        "minimist": "0.0.8"
+      }
+    },
+    "mocha": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.0.tgz",
+      "integrity": "sha512-pIU2PJjrPYvYRqVpjXzj76qltO9uBYI7woYAMoxbSefsa+vqAfptjoeevd6bUgwD0mPIO+hv9f7ltvsNreL2PA==",
+      "dev": true,
+      "requires": {
+        "browser-stdout": "1.3.0",
+        "commander": "2.9.0",
+        "debug": "2.6.8",
+        "diff": "3.2.0",
+        "escape-string-regexp": "1.0.5",
+        "glob": "7.1.1",
+        "growl": "1.9.2",
+        "json3": "3.3.2",
+        "lodash.create": "3.1.1",
+        "mkdirp": "0.5.1",
+        "supports-color": "3.1.2"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "2.9.0",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
+          "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
+          "dev": true,
+          "requires": {
+            "graceful-readlink": "1.0.1"
+          }
+        },
+        "debug": {
+          "version": "2.6.8",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+          "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "glob": {
+          "version": "7.1.1",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz",
+          "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "1.0.0",
+            "inflight": "1.0.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.1"
+          }
+        },
+        "has-flag": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "3.1.2",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz",
+          "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=",
+          "dev": true,
+          "requires": {
+            "has-flag": "1.0.0"
+          }
+        }
+      }
+    },
+    "move-concurrently": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
+      "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
+      "dev": true,
+      "requires": {
+        "aproba": "1.2.0",
+        "copy-concurrently": "1.0.5",
+        "fs-write-stream-atomic": "1.0.10",
+        "mkdirp": "0.5.1",
+        "rimraf": "2.6.1",
+        "run-queue": "1.0.3"
+      }
+    },
+    "mqtt": {
+      "version": "2.17.0",
+      "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-2.17.0.tgz",
+      "integrity": "sha512-eYeK5G/GQcdP/AOrGQMUULX7QvBXt3I9bfmgNkzMTsdSR1ywJQhK1iCYPrhh+rtRl3eUSJwEbO+oZx/Q51uHaw==",
+      "dev": true,
+      "requires": {
+        "commist": "1.0.0",
+        "concat-stream": "1.6.2",
+        "end-of-stream": "1.4.1",
+        "help-me": "1.1.0",
+        "inherits": "2.0.3",
+        "minimist": "1.2.0",
+        "mqtt-packet": "5.5.0",
+        "pump": "3.0.0",
+        "readable-stream": "2.3.5",
+        "reinterval": "1.1.0",
+        "split2": "2.2.0",
+        "websocket-stream": "5.1.2",
+        "xtend": "4.0.1"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "mqtt-packet": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-5.5.0.tgz",
+      "integrity": "sha512-kR+Uw+r9rjUFSLZutmaAhjL4Y1asKLMTwE++PP0iuApJuc+zItE5v2LluQN2K3Pri5e2+K4V++QDjqGTgle/+A==",
+      "dev": true,
+      "requires": {
+        "bl": "1.2.2",
+        "inherits": "2.0.3",
+        "process-nextick-args": "2.0.0",
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "mute-stream": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+      "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
+      "dev": true
+    },
+    "nanomatch": {
+      "version": "1.2.9",
+      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz",
+      "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==",
+      "dev": true,
+      "requires": {
+        "arr-diff": "4.0.0",
+        "array-unique": "0.3.2",
+        "define-property": "2.0.2",
+        "extend-shallow": "3.0.2",
+        "fragment-cache": "0.2.1",
+        "is-odd": "2.0.0",
+        "is-windows": "1.0.2",
+        "kind-of": "6.0.2",
+        "object.pick": "1.3.0",
+        "regex-not": "1.0.2",
+        "snapdragon": "0.8.2",
+        "to-regex": "3.0.2"
+      },
+      "dependencies": {
+        "arr-diff": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+          "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+          "dev": true
+        },
+        "array-unique": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+          "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "natural-compare": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+      "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+      "dev": true
+    },
+    "negotiator": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+      "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
+      "dev": true
+    },
+    "neo-async": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.0.tgz",
+      "integrity": "sha512-nJmSswG4As/MkRq7QZFuH/sf/yuv8ODdMZrY4Bedjp77a5MK4A6s7YbBB64c9u79EBUOfXUXBvArmvzTD0X+6g==",
+      "dev": true
+    },
+    "next-tick": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+      "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
+      "dev": true
+    },
+    "node-fingerprint": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/node-fingerprint/-/node-fingerprint-0.0.2.tgz",
+      "integrity": "sha1-Mcur63GmeufdWn3AQuUcPHWGhQE=",
+      "dev": true
+    },
+    "node-libs-browser": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz",
+      "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==",
+      "dev": true,
+      "requires": {
+        "assert": "1.4.1",
+        "browserify-zlib": "0.2.0",
+        "buffer": "4.9.1",
+        "console-browserify": "1.1.0",
+        "constants-browserify": "1.0.0",
+        "crypto-browserify": "3.12.0",
+        "domain-browser": "1.2.0",
+        "events": "1.1.1",
+        "https-browserify": "1.0.0",
+        "os-browserify": "0.3.0",
+        "path-browserify": "0.0.0",
+        "process": "0.11.10",
+        "punycode": "1.3.2",
+        "querystring-es3": "0.2.1",
+        "readable-stream": "2.3.5",
+        "stream-browserify": "2.0.1",
+        "stream-http": "2.8.1",
+        "string_decoder": "1.0.3",
+        "timers-browserify": "2.0.6",
+        "tty-browserify": "0.0.0",
+        "url": "0.11.0",
+        "util": "0.10.3",
+        "vm-browserify": "0.0.4"
+      },
+      "dependencies": {
+        "url": {
+          "version": "0.11.0",
+          "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+          "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+          "dev": true,
+          "requires": {
+            "punycode": "1.3.2",
+            "querystring": "0.2.0"
+          }
+        }
+      }
+    },
+    "normalize-package-data": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+      "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
+      "dev": true,
+      "requires": {
+        "hosted-git-info": "2.6.0",
+        "is-builtin-module": "1.0.0",
+        "semver": "4.3.6",
+        "validate-npm-package-license": "3.0.3"
+      }
+    },
+    "normalize-path": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+      "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+      "dev": true,
+      "requires": {
+        "remove-trailing-separator": "1.1.0"
+      }
+    },
+    "normalize-url": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz",
+      "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=",
+      "dev": true,
+      "requires": {
+        "object-assign": "4.1.1",
+        "prepend-http": "1.0.4",
+        "query-string": "4.3.4",
+        "sort-keys": "1.1.2"
+      }
+    },
+    "npm-run-path": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+      "dev": true,
+      "requires": {
+        "path-key": "2.0.1"
+      }
+    },
+    "null-check": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz",
+      "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=",
+      "dev": true
+    },
+    "number-is-nan": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+      "dev": true
+    },
+    "oauth-sign": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+      "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+      "dev": true
+    },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+      "dev": true
+    },
+    "object-component": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
+      "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=",
+      "dev": true
+    },
+    "object-copy": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "dev": true,
+      "requires": {
+        "copy-descriptor": "0.1.1",
+        "define-property": "0.2.5",
+        "kind-of": "3.2.2"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+          "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+          "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          }
+        },
+        "is-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+          "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "0.1.6",
+            "is-data-descriptor": "0.1.4",
+            "kind-of": "5.1.0"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "5.1.0",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+              "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+              "dev": true
+            }
+          }
+        }
+      }
+    },
+    "object-visit": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "dev": true,
+      "requires": {
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "object.omit": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
+      "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
+      "dev": true,
+      "requires": {
+        "for-own": "0.1.5",
+        "is-extendable": "0.1.1"
+      }
+    },
+    "object.pick": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+      "dev": true,
+      "requires": {
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "on-finished": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+      "dev": true,
+      "requires": {
+        "ee-first": "1.1.1"
+      }
+    },
+    "once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "dev": true,
+      "requires": {
+        "wrappy": "1.0.2"
+      }
+    },
+    "onetime": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+      "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+      "dev": true,
+      "requires": {
+        "mimic-fn": "1.2.0"
+      }
+    },
+    "optimist": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+      "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
+      "dev": true,
+      "requires": {
+        "minimist": "0.0.8",
+        "wordwrap": "0.0.3"
+      },
+      "dependencies": {
+        "wordwrap": {
+          "version": "0.0.3",
+          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+          "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
+          "dev": true
+        }
+      }
+    },
+    "optionator": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+      "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+      "dev": true,
+      "requires": {
+        "deep-is": "0.1.3",
+        "fast-levenshtein": "2.0.6",
+        "levn": "0.3.0",
+        "prelude-ls": "1.1.2",
+        "type-check": "0.3.2",
+        "wordwrap": "1.0.0"
+      }
+    },
+    "options": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
+      "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=",
+      "dev": true
+    },
+    "ordered-read-streams": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz",
+      "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "2.3.5"
+      }
+    },
+    "os-browserify": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+      "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
+      "dev": true
+    },
+    "os-homedir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+      "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+      "dev": true
+    },
+    "os-locale": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
+      "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
+      "dev": true,
+      "requires": {
+        "execa": "0.7.0",
+        "lcid": "1.0.0",
+        "mem": "1.1.0"
+      }
+    },
+    "os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+      "dev": true
+    },
+    "output-file-sync": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz",
+      "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "mkdirp": "0.5.1",
+        "object-assign": "4.1.1"
+      }
+    },
+    "p-cancelable": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
+      "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==",
+      "dev": true
+    },
+    "p-finally": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+      "dev": true
+    },
+    "p-limit": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz",
+      "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==",
+      "dev": true,
+      "requires": {
+        "p-try": "1.0.0"
+      }
+    },
+    "p-locate": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+      "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+      "dev": true,
+      "requires": {
+        "p-limit": "1.2.0"
+      }
+    },
+    "p-timeout": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
+      "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
+      "dev": true,
+      "requires": {
+        "p-finally": "1.0.0"
+      }
+    },
+    "p-try": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+      "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+      "dev": true
+    },
+    "pako": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
+      "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==",
+      "dev": true
+    },
+    "parallel-transform": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz",
+      "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=",
+      "dev": true,
+      "requires": {
+        "cyclist": "0.2.2",
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.5"
+      }
+    },
+    "parse-asn1": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz",
+      "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=",
+      "dev": true,
+      "requires": {
+        "asn1.js": "4.10.1",
+        "browserify-aes": "1.1.1",
+        "create-hash": "1.1.3",
+        "evp_bytestokey": "1.0.3",
+        "pbkdf2": "3.0.14"
+      }
+    },
+    "parse-glob": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
+      "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
+      "dev": true,
+      "requires": {
+        "glob-base": "0.3.0",
+        "is-dotfile": "1.0.3",
+        "is-extglob": "1.0.0",
+        "is-glob": "2.0.1"
+      }
+    },
+    "parse-json": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+      "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+      "dev": true,
+      "requires": {
+        "error-ex": "1.3.1"
+      }
+    },
+    "parsejson": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz",
+      "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=",
+      "dev": true,
+      "requires": {
+        "better-assert": "1.0.2"
+      }
+    },
+    "parseqs": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
+      "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
+      "dev": true,
+      "requires": {
+        "better-assert": "1.0.2"
+      }
+    },
+    "parseuri": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
+      "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
+      "dev": true,
+      "requires": {
+        "better-assert": "1.0.2"
+      }
+    },
+    "parseurl": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+      "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
+      "dev": true
+    },
+    "pascalcase": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "dev": true
+    },
+    "path-browserify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
+      "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=",
+      "dev": true
+    },
+    "path-dirname": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+      "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+      "dev": true
+    },
+    "path-exists": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+      "dev": true
+    },
+    "path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "dev": true
+    },
+    "path-is-inside": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+      "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+      "dev": true
+    },
+    "path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "dev": true
+    },
+    "path-to-regexp": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+      "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
+      "dev": true
+    },
+    "path-type": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+      "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+      "dev": true,
+      "requires": {
+        "pify": "2.3.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+          "dev": true
+        }
+      }
+    },
+    "pathval": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
+      "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
+      "dev": true
+    },
+    "pbkdf2": {
+      "version": "3.0.14",
+      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz",
+      "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==",
+      "dev": true,
+      "requires": {
+        "create-hash": "1.1.3",
+        "create-hmac": "1.1.6",
+        "ripemd160": "2.0.1",
+        "safe-buffer": "5.1.1",
+        "sha.js": "2.4.11"
+      }
+    },
+    "performance-now": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
+      "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=",
+      "dev": true
+    },
+    "pify": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+      "dev": true
+    },
+    "pinkie": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+      "dev": true
+    },
+    "pinkie-promise": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+      "dev": true,
+      "requires": {
+        "pinkie": "2.0.4"
+      }
+    },
+    "pkg-dir": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
+      "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
+      "dev": true,
+      "requires": {
+        "find-up": "2.1.0"
+      }
+    },
+    "platform": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.4.tgz",
+      "integrity": "sha1-bw+xftqqSPIUQrOpdcBjEw8cPr0=",
+      "dev": true
+    },
+    "pluralize": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-4.0.0.tgz",
+      "integrity": "sha1-WbcIwcAZCi9pLxx2GMRGsFL9F2I=",
+      "dev": true
+    },
+    "posix-character-classes": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+      "dev": true
+    },
+    "prelude-ls": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+      "dev": true
+    },
+    "prepend-http": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
+      "dev": true
+    },
+    "preserve": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
+      "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
+      "dev": true
+    },
+    "prettier": {
+      "version": "1.5.3",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.5.3.tgz",
+      "integrity": "sha1-WdrcaDNF7GuI+IuU7Urn4do5S/4=",
+      "dev": true
+    },
+    "private": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
+      "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
+      "dev": true
+    },
+    "process": {
+      "version": "0.11.10",
+      "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+      "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+      "dev": true
+    },
+    "process-nextick-args": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+      "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
+      "dev": true
+    },
+    "progress": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
+      "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
+      "dev": true
+    },
+    "promise-inflight": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+      "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
+      "dev": true
+    },
+    "promise-polyfill": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.0.2.tgz",
+      "integrity": "sha1-2chtPcTcLfkBboiUbe/Wm0m0EWI=",
+      "dev": true
+    },
+    "proxy-addr": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz",
+      "integrity": "sha1-ccDuOxAt4/IC87ZPYI0XP8uhqRg=",
+      "dev": true,
+      "requires": {
+        "forwarded": "0.1.2",
+        "ipaddr.js": "1.4.0"
+      }
+    },
+    "prr": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+      "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
+      "dev": true
+    },
+    "pseudomap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+      "dev": true
+    },
+    "public-encrypt": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz",
+      "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "browserify-rsa": "4.0.1",
+        "create-hash": "1.1.3",
+        "parse-asn1": "5.1.0",
+        "randombytes": "2.0.6"
+      }
+    },
+    "pump": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "1.4.1",
+        "once": "1.4.0"
+      }
+    },
+    "pumpify": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.4.0.tgz",
+      "integrity": "sha512-2kmNR9ry+Pf45opRVirpNuIFotsxUGLaYqxIwuR77AYrYRMuFCz9eryHBS52L360O+NcR383CL4QYlMKPq4zYA==",
+      "dev": true,
+      "requires": {
+        "duplexify": "3.5.4",
+        "inherits": "2.0.3",
+        "pump": "2.0.1"
+      },
+      "dependencies": {
+        "pump": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+          "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+          "dev": true,
+          "requires": {
+            "end-of-stream": "1.4.1",
+            "once": "1.4.0"
+          }
+        }
+      }
+    },
+    "punycode": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+      "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+      "dev": true
+    },
+    "q": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
+      "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
+      "dev": true
+    },
+    "qjobs": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz",
+      "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==",
+      "dev": true
+    },
+    "qs": {
+      "version": "6.4.0",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
+      "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=",
+      "dev": true
+    },
+    "query-string": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
+      "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
+      "dev": true,
+      "requires": {
+        "object-assign": "4.1.1",
+        "strict-uri-encode": "1.1.0"
+      }
+    },
+    "querystring": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+      "dev": true
+    },
+    "querystring-es3": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+      "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
+      "dev": true
+    },
+    "randomatic": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz",
+      "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==",
+      "dev": true,
+      "requires": {
+        "is-number": "3.0.0",
+        "kind-of": "4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.6"
+              }
+            }
+          }
+        },
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "1.1.6"
+          }
+        }
+      }
+    },
+    "randombytes": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz",
+      "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "randomfill": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+      "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+      "dev": true,
+      "requires": {
+        "randombytes": "2.0.6",
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "range-parser": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+      "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=",
+      "dev": true
+    },
+    "raw-body": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz",
+      "integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y=",
+      "dev": true,
+      "requires": {
+        "bytes": "2.4.0",
+        "iconv-lite": "0.4.15",
+        "unpipe": "1.0.0"
+      }
+    },
+    "read-pkg": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+      "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+      "dev": true,
+      "requires": {
+        "load-json-file": "2.0.0",
+        "normalize-package-data": "2.4.0",
+        "path-type": "2.0.0"
+      }
+    },
+    "read-pkg-up": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+      "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+      "dev": true,
+      "requires": {
+        "find-up": "2.1.0",
+        "read-pkg": "2.0.0"
+      }
+    },
+    "readable-stream": {
+      "version": "2.3.5",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz",
+      "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==",
+      "dev": true,
+      "requires": {
+        "core-util-is": "1.0.2",
+        "inherits": "2.0.3",
+        "isarray": "1.0.0",
+        "process-nextick-args": "2.0.0",
+        "safe-buffer": "5.1.1",
+        "string_decoder": "1.0.3",
+        "util-deprecate": "1.0.2"
+      }
+    },
+    "readdirp": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
+      "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "minimatch": "3.0.4",
+        "readable-stream": "2.3.5",
+        "set-immediate-shim": "1.0.1"
+      }
+    },
+    "regenerate": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz",
+      "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==",
+      "dev": true
+    },
+    "regenerator-runtime": {
+      "version": "0.11.1",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+      "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+      "dev": true
+    },
+    "regenerator-transform": {
+      "version": "0.10.1",
+      "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz",
+      "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0",
+        "private": "0.1.8"
+      }
+    },
+    "regex-cache": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
+      "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
+      "dev": true,
+      "requires": {
+        "is-equal-shallow": "0.1.3"
+      }
+    },
+    "regex-not": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "3.0.2",
+        "safe-regex": "1.1.0"
+      }
+    },
+    "regexpu-core": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
+      "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=",
+      "dev": true,
+      "requires": {
+        "regenerate": "1.3.3",
+        "regjsgen": "0.2.0",
+        "regjsparser": "0.1.5"
+      }
+    },
+    "regjsgen": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
+      "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
+      "dev": true
+    },
+    "regjsparser": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
+      "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
+      "dev": true,
+      "requires": {
+        "jsesc": "0.5.0"
+      },
+      "dependencies": {
+        "jsesc": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+          "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+          "dev": true
+        }
+      }
+    },
+    "reinterval": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz",
+      "integrity": "sha1-M2Hs+jymwYKDOA3Qu5VG85D17Oc=",
+      "dev": true
+    },
+    "remove-trailing-separator": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+      "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+      "dev": true
+    },
+    "repeat-element": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
+      "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
+      "dev": true
+    },
+    "repeat-string": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+      "dev": true
+    },
+    "repeating": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+      "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+      "dev": true,
+      "requires": {
+        "is-finite": "1.0.2"
+      }
+    },
+    "replace-in-file": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/replace-in-file/-/replace-in-file-3.4.0.tgz",
+      "integrity": "sha512-fto9Ooab00CniGkSjRCZCamER7P5S4mZHQ4w4dLd09nwP3FtFfjUJh8/OVC/In4ki5MEy+dYO5v9r7rtq2DrYQ==",
+      "dev": true,
+      "requires": {
+        "chalk": "2.3.2",
+        "glob": "7.1.2",
+        "yargs": "11.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.1"
+          }
+        },
+        "chalk": {
+          "version": "2.3.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz",
+          "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.1",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.3.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.3.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz",
+          "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        }
+      }
+    },
+    "request": {
+      "version": "2.81.0",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
+      "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=",
+      "dev": true,
+      "requires": {
+        "aws-sign2": "0.6.0",
+        "aws4": "1.6.0",
+        "caseless": "0.12.0",
+        "combined-stream": "1.0.6",
+        "extend": "3.0.1",
+        "forever-agent": "0.6.1",
+        "form-data": "2.1.4",
+        "har-validator": "4.2.1",
+        "hawk": "3.1.3",
+        "http-signature": "1.1.1",
+        "is-typedarray": "1.0.0",
+        "isstream": "0.1.2",
+        "json-stringify-safe": "5.0.1",
+        "mime-types": "2.1.18",
+        "oauth-sign": "0.8.2",
+        "performance-now": "0.2.0",
+        "qs": "6.4.0",
+        "safe-buffer": "5.1.1",
+        "stringstream": "0.0.5",
+        "tough-cookie": "2.3.4",
+        "tunnel-agent": "0.6.0",
+        "uuid": "3.1.0"
+      },
+      "dependencies": {
+        "form-data": {
+          "version": "2.1.4",
+          "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
+          "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+          "dev": true,
+          "requires": {
+            "asynckit": "0.4.0",
+            "combined-stream": "1.0.6",
+            "mime-types": "2.1.18"
+          }
+        }
+      }
+    },
+    "require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "dev": true
+    },
+    "require-main-filename": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+      "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
+      "dev": true
+    },
+    "require-uncached": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
+      "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
+      "dev": true,
+      "requires": {
+        "caller-path": "0.1.0",
+        "resolve-from": "1.0.1"
+      }
+    },
+    "requires-port": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+      "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
+      "dev": true
+    },
+    "resolve-from": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
+      "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
+      "dev": true
+    },
+    "resolve-url": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "dev": true
+    },
+    "restore-cursor": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+      "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+      "dev": true,
+      "requires": {
+        "onetime": "2.0.1",
+        "signal-exit": "3.0.2"
+      }
+    },
+    "ret": {
+      "version": "0.1.15",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+      "dev": true
+    },
+    "right-align": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
+      "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
+      "dev": true,
+      "requires": {
+        "align-text": "0.1.4"
+      }
+    },
+    "rimraf": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz",
+      "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=",
+      "dev": true,
+      "requires": {
+        "glob": "7.1.2"
+      }
+    },
+    "ripemd160": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
+      "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=",
+      "dev": true,
+      "requires": {
+        "hash-base": "2.0.2",
+        "inherits": "2.0.3"
+      }
+    },
+    "run-async": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
+      "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
+      "dev": true,
+      "requires": {
+        "is-promise": "2.1.0"
+      }
+    },
+    "run-queue": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
+      "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
+      "dev": true,
+      "requires": {
+        "aproba": "1.2.0"
+      }
+    },
+    "rx-lite": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
+      "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
+      "dev": true
+    },
+    "rx-lite-aggregates": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
+      "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
+      "dev": true,
+      "requires": {
+        "rx-lite": "4.0.8"
+      }
+    },
+    "safe-buffer": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+      "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
+      "dev": true
+    },
+    "safe-regex": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "dev": true,
+      "requires": {
+        "ret": "0.1.15"
+      }
+    },
+    "sauce-connect-launcher": {
+      "version": "0.17.0",
+      "resolved": "https://registry.npmjs.org/sauce-connect-launcher/-/sauce-connect-launcher-0.17.0.tgz",
+      "integrity": "sha1-kI2TEeyvF92bRkehQ1/UogcugM4=",
+      "dev": true,
+      "requires": {
+        "adm-zip": "0.4.7",
+        "async": "1.4.0",
+        "https-proxy-agent": "1.0.0",
+        "lodash": "3.10.1",
+        "rimraf": "2.4.3"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "5.0.15",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+          "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+          "dev": true,
+          "requires": {
+            "inflight": "1.0.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.1"
+          }
+        },
+        "lodash": {
+          "version": "3.10.1",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+          "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
+          "dev": true
+        },
+        "rimraf": {
+          "version": "2.4.3",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.3.tgz",
+          "integrity": "sha1-5bUclDekxYKtuVXp8oz42UXicq8=",
+          "dev": true,
+          "requires": {
+            "glob": "5.0.15"
+          }
+        }
+      }
+    },
+    "saucelabs": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.4.0.tgz",
+      "integrity": "sha1-uTSpr52ih0s/QKrh/N5QpEZvXzg=",
+      "dev": true,
+      "requires": {
+        "https-proxy-agent": "1.0.0"
+      }
+    },
+    "sax": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
+      "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=",
+      "dev": true
+    },
+    "schema-utils": {
+      "version": "0.4.5",
+      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz",
+      "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==",
+      "dev": true,
+      "requires": {
+        "ajv": "6.4.0",
+        "ajv-keywords": "3.1.0"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "6.4.0",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.4.0.tgz",
+          "integrity": "sha1-06/3jpJ3VJdx2vAWTP9ISCt1T8Y=",
+          "dev": true,
+          "requires": {
+            "fast-deep-equal": "1.1.0",
+            "fast-json-stable-stringify": "2.0.0",
+            "json-schema-traverse": "0.3.1",
+            "uri-js": "3.0.2"
+          }
+        }
+      }
+    },
+    "semver": {
+      "version": "4.3.6",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz",
+      "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=",
+      "dev": true
+    },
+    "send": {
+      "version": "0.15.4",
+      "resolved": "https://registry.npmjs.org/send/-/send-0.15.4.tgz",
+      "integrity": "sha1-mF+qPihLAnPHkzZKNcZze9k5Bbk=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.8",
+        "depd": "1.1.2",
+        "destroy": "1.0.4",
+        "encodeurl": "1.0.2",
+        "escape-html": "1.0.3",
+        "etag": "1.8.1",
+        "fresh": "0.5.0",
+        "http-errors": "1.6.3",
+        "mime": "1.3.4",
+        "ms": "2.0.0",
+        "on-finished": "2.3.0",
+        "range-parser": "1.2.0",
+        "statuses": "1.3.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.8",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+          "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "statuses": {
+          "version": "1.3.1",
+          "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+          "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
+          "dev": true
+        }
+      }
+    },
+    "serialize-javascript": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.4.0.tgz",
+      "integrity": "sha1-fJWFFNtqwkQ6irwGLcn3iGp/YAU=",
+      "dev": true
+    },
+    "serve-index": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.0.tgz",
+      "integrity": "sha1-0rKA/FYNYW7oG0i/D6gqvtJIXOc=",
+      "dev": true,
+      "requires": {
+        "accepts": "1.3.5",
+        "batch": "0.6.1",
+        "debug": "2.6.8",
+        "escape-html": "1.0.3",
+        "http-errors": "1.6.3",
+        "mime-types": "2.1.18",
+        "parseurl": "1.3.2"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.8",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+          "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "serve-static": {
+      "version": "1.12.4",
+      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.4.tgz",
+      "integrity": "sha1-m2qpjutyU8Tu3Ewfb9vKYJkBqWE=",
+      "dev": true,
+      "requires": {
+        "encodeurl": "1.0.2",
+        "escape-html": "1.0.3",
+        "parseurl": "1.3.2",
+        "send": "0.15.4"
+      }
+    },
+    "set-blocking": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+      "dev": true
+    },
+    "set-immediate-shim": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
+      "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
+      "dev": true
+    },
+    "set-value": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
+      "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "2.0.1",
+        "is-extendable": "0.1.1",
+        "is-plain-object": "2.0.4",
+        "split-string": "3.1.0"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "0.1.1"
+          }
+        }
+      }
+    },
+    "setimmediate": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
+      "dev": true
+    },
+    "setprototypeof": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+      "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+      "dev": true
+    },
+    "sha.js": {
+      "version": "2.4.11",
+      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "dev": true,
+      "requires": {
+        "shebang-regex": "1.0.0"
+      }
+    },
+    "shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "dev": true
+    },
+    "signal-exit": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+      "dev": true
+    },
+    "slash": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+      "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+      "dev": true
+    },
+    "slice-ansi": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
+      "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
+      "dev": true,
+      "requires": {
+        "is-fullwidth-code-point": "2.0.0"
+      }
+    },
+    "snapdragon": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+      "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+      "dev": true,
+      "requires": {
+        "base": "0.11.2",
+        "debug": "2.6.9",
+        "define-property": "0.2.5",
+        "extend-shallow": "2.0.1",
+        "map-cache": "0.2.2",
+        "source-map": "0.5.7",
+        "source-map-resolve": "0.5.1",
+        "use": "3.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "0.1.1"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+          "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.6"
+              }
+            }
+          }
+        },
+        "is-data-descriptor": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+          "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.6"
+              }
+            }
+          }
+        },
+        "is-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+          "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "0.1.6",
+            "is-data-descriptor": "0.1.4",
+            "kind-of": "5.1.0"
+          }
+        },
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "snapdragon-node": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+      "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+      "dev": true,
+      "requires": {
+        "define-property": "1.0.0",
+        "isobject": "3.0.1",
+        "snapdragon-util": "3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "1.0.2"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "snapdragon-util": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "sntp": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+      "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+      "dev": true,
+      "requires": {
+        "hoek": "2.16.3"
+      }
+    },
+    "socket.io": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.3.tgz",
+      "integrity": "sha1-uK+cq6AJSeVo42nxMn6pvp6iRhs=",
+      "dev": true,
+      "requires": {
+        "debug": "2.3.3",
+        "engine.io": "1.8.3",
+        "has-binary": "0.1.7",
+        "object-assign": "4.1.0",
+        "socket.io-adapter": "0.5.0",
+        "socket.io-client": "1.7.3",
+        "socket.io-parser": "2.3.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.3.3",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+          "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
+          "dev": true,
+          "requires": {
+            "ms": "0.7.2"
+          }
+        },
+        "ms": {
+          "version": "0.7.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+          "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
+          "dev": true
+        },
+        "object-assign": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz",
+          "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=",
+          "dev": true
+        }
+      }
+    },
+    "socket.io-adapter": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz",
+      "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=",
+      "dev": true,
+      "requires": {
+        "debug": "2.3.3",
+        "socket.io-parser": "2.3.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.3.3",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+          "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
+          "dev": true,
+          "requires": {
+            "ms": "0.7.2"
+          }
+        },
+        "ms": {
+          "version": "0.7.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+          "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
+          "dev": true
+        }
+      }
+    },
+    "socket.io-client": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.3.tgz",
+      "integrity": "sha1-sw6GqhDV7zVGYBwJzeR2Xjgdo3c=",
+      "dev": true,
+      "requires": {
+        "backo2": "1.0.2",
+        "component-bind": "1.0.0",
+        "component-emitter": "1.2.1",
+        "debug": "2.3.3",
+        "engine.io-client": "1.8.3",
+        "has-binary": "0.1.7",
+        "indexof": "0.0.1",
+        "object-component": "0.0.3",
+        "parseuri": "0.0.5",
+        "socket.io-parser": "2.3.1",
+        "to-array": "0.1.4"
+      },
+      "dependencies": {
+        "component-emitter": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+          "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+          "dev": true
+        },
+        "debug": {
+          "version": "2.3.3",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+          "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
+          "dev": true,
+          "requires": {
+            "ms": "0.7.2"
+          }
+        },
+        "ms": {
+          "version": "0.7.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+          "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
+          "dev": true
+        }
+      }
+    },
+    "socket.io-parser": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz",
+      "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=",
+      "dev": true,
+      "requires": {
+        "component-emitter": "1.1.2",
+        "debug": "2.2.0",
+        "isarray": "0.0.1",
+        "json3": "3.3.2"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+          "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+          "dev": true,
+          "requires": {
+            "ms": "0.7.1"
+          }
+        },
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+          "dev": true
+        },
+        "ms": {
+          "version": "0.7.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
+          "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=",
+          "dev": true
+        }
+      }
+    },
+    "sort-keys": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
+      "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
+      "dev": true,
+      "requires": {
+        "is-plain-obj": "1.1.0"
+      }
+    },
+    "source-list-map": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz",
+      "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==",
+      "dev": true
+    },
+    "source-map": {
+      "version": "0.5.7",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+      "dev": true
+    },
+    "source-map-resolve": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz",
+      "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==",
+      "dev": true,
+      "requires": {
+        "atob": "2.1.0",
+        "decode-uri-component": "0.2.0",
+        "resolve-url": "0.2.1",
+        "source-map-url": "0.4.0",
+        "urix": "0.1.0"
+      }
+    },
+    "source-map-support": {
+      "version": "0.4.18",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
+      "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
+      "dev": true,
+      "requires": {
+        "source-map": "0.5.7"
+      }
+    },
+    "source-map-url": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+      "dev": true
+    },
+    "spdx-correct": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz",
+      "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==",
+      "dev": true,
+      "requires": {
+        "spdx-expression-parse": "3.0.0",
+        "spdx-license-ids": "3.0.0"
+      }
+    },
+    "spdx-exceptions": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz",
+      "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==",
+      "dev": true
+    },
+    "spdx-expression-parse": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+      "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
+      "dev": true,
+      "requires": {
+        "spdx-exceptions": "2.1.0",
+        "spdx-license-ids": "3.0.0"
+      }
+    },
+    "spdx-license-ids": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz",
+      "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==",
+      "dev": true
+    },
+    "split-string": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+      "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "3.0.2"
+      }
+    },
+    "split2": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz",
+      "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==",
+      "dev": true,
+      "requires": {
+        "through2": "2.0.3"
+      }
+    },
+    "sprintf-js": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+      "dev": true
+    },
+    "sshpk": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz",
+      "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=",
+      "dev": true,
+      "requires": {
+        "asn1": "0.2.3",
+        "assert-plus": "1.0.0",
+        "bcrypt-pbkdf": "1.0.1",
+        "dashdash": "1.14.1",
+        "ecc-jsbn": "0.1.1",
+        "getpass": "0.1.7",
+        "jsbn": "0.1.1",
+        "tweetnacl": "0.14.5"
+      },
+      "dependencies": {
+        "assert-plus": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+          "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+          "dev": true
+        }
+      }
+    },
+    "ssri": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz",
+      "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "static-extend": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+      "dev": true,
+      "requires": {
+        "define-property": "0.2.5",
+        "object-copy": "0.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+          "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.6"
+              }
+            }
+          }
+        },
+        "is-data-descriptor": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+          "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.6"
+              }
+            }
+          }
+        },
+        "is-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+          "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "0.1.6",
+            "is-data-descriptor": "0.1.4",
+            "kind-of": "5.1.0"
+          }
+        },
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "statuses": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+      "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+      "dev": true
+    },
+    "stream-browserify": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
+      "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.5"
+      }
+    },
+    "stream-each": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz",
+      "integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "1.4.1",
+        "stream-shift": "1.0.0"
+      }
+    },
+    "stream-http": {
+      "version": "2.8.1",
+      "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.1.tgz",
+      "integrity": "sha512-cQ0jo17BLca2r0GfRdZKYAGLU6JRoIWxqSOakUMuKOT6MOK7AAlE856L33QuDmAy/eeOrhLee3dZKX0Uadu93A==",
+      "dev": true,
+      "requires": {
+        "builtin-status-codes": "3.0.0",
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.5",
+        "to-arraybuffer": "1.0.1",
+        "xtend": "4.0.1"
+      }
+    },
+    "stream-shift": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
+      "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
+      "dev": true
+    },
+    "strict-uri-encode": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+      "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
+      "dev": true
+    },
+    "string_decoder": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+      "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "string-width": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+      "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+      "dev": true,
+      "requires": {
+        "is-fullwidth-code-point": "2.0.0",
+        "strip-ansi": "4.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "3.0.0"
+          }
+        }
+      }
+    },
+    "stringstream": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+      "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
+      "dev": true
+    },
+    "strip-ansi": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "2.1.1"
+      }
+    },
+    "strip-bom": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+      "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+      "dev": true
+    },
+    "strip-eof": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+      "dev": true
+    },
+    "strip-json-comments": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+      "dev": true
+    },
+    "strip-outer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
+      "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "1.0.5"
+      }
+    },
+    "strip-url-auth": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/strip-url-auth/-/strip-url-auth-1.0.1.tgz",
+      "integrity": "sha1-IrD6OkE4WzO+PzMVUbu4N/oM164=",
+      "dev": true
+    },
+    "supports-color": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+      "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+      "dev": true
+    },
+    "table": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz",
+      "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==",
+      "dev": true,
+      "requires": {
+        "ajv": "6.4.0",
+        "ajv-keywords": "3.1.0",
+        "chalk": "2.3.2",
+        "lodash": "4.17.5",
+        "slice-ansi": "1.0.0",
+        "string-width": "2.1.1"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "6.4.0",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.4.0.tgz",
+          "integrity": "sha1-06/3jpJ3VJdx2vAWTP9ISCt1T8Y=",
+          "dev": true,
+          "requires": {
+            "fast-deep-equal": "1.1.0",
+            "fast-json-stable-stringify": "2.0.0",
+            "json-schema-traverse": "0.3.1",
+            "uri-js": "3.0.2"
+          }
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.1"
+          }
+        },
+        "chalk": {
+          "version": "2.3.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz",
+          "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.1",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.3.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.3.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz",
+          "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        }
+      }
+    },
+    "tapable": {
+      "version": "0.2.8",
+      "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz",
+      "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=",
+      "dev": true
+    },
+    "tar-stream": {
+      "version": "1.5.5",
+      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz",
+      "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==",
+      "dev": true,
+      "requires": {
+        "bl": "1.2.2",
+        "end-of-stream": "1.4.1",
+        "readable-stream": "2.3.5",
+        "xtend": "4.0.1"
+      }
+    },
+    "text-table": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+      "dev": true
+    },
+    "through": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "dev": true
+    },
+    "through2": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
+      "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "2.3.5",
+        "xtend": "4.0.1"
+      }
+    },
+    "through2-filter": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz",
+      "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=",
+      "dev": true,
+      "requires": {
+        "through2": "2.0.3",
+        "xtend": "4.0.1"
+      }
+    },
+    "timed-out": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+      "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
+      "dev": true
+    },
+    "timers-browserify": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.6.tgz",
+      "integrity": "sha512-HQ3nbYRAowdVd0ckGFvmJPPCOH/CHleFN/Y0YQCX1DVaB7t+KFvisuyN09fuP8Jtp1CpfSh8O8bMkHbdbPe6Pw==",
+      "dev": true,
+      "requires": {
+        "setimmediate": "1.0.5"
+      }
+    },
+    "tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "dev": true,
+      "requires": {
+        "os-tmpdir": "1.0.2"
+      }
+    },
+    "to-absolute-glob": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",
+      "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=",
+      "dev": true,
+      "requires": {
+        "is-absolute": "1.0.0",
+        "is-negated-glob": "1.0.0"
+      }
+    },
+    "to-array": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
+      "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=",
+      "dev": true
+    },
+    "to-arraybuffer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
+      "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
+      "dev": true
+    },
+    "to-fast-properties": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
+      "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
+      "dev": true
+    },
+    "to-object-path": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+      "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "to-regex": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+      "dev": true,
+      "requires": {
+        "define-property": "2.0.2",
+        "extend-shallow": "3.0.2",
+        "regex-not": "1.0.2",
+        "safe-regex": "1.1.0"
+      }
+    },
+    "to-regex-range": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+      "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+      "dev": true,
+      "requires": {
+        "is-number": "3.0.0",
+        "repeat-string": "1.6.1"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          }
+        }
+      }
+    },
+    "tough-cookie": {
+      "version": "2.3.4",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
+      "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
+      "dev": true,
+      "requires": {
+        "punycode": "1.4.1"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+          "dev": true
+        }
+      }
+    },
+    "trim-repeated": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",
+      "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "1.0.5"
+      }
+    },
+    "trim-right": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
+      "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
+      "dev": true
+    },
+    "tty-browserify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+      "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
+      "dev": true
+    },
+    "tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "dev": true,
+      "optional": true
+    },
+    "type-check": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+      "dev": true,
+      "requires": {
+        "prelude-ls": "1.1.2"
+      }
+    },
+    "type-detect": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+      "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+      "dev": true
+    },
+    "type-is": {
+      "version": "1.6.16",
+      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
+      "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
+      "dev": true,
+      "requires": {
+        "media-typer": "0.3.0",
+        "mime-types": "2.1.18"
+      }
+    },
+    "typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "dev": true
+    },
+    "uglify-es": {
+      "version": "3.3.9",
+      "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz",
+      "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==",
+      "dev": true,
+      "requires": {
+        "commander": "2.13.0",
+        "source-map": "0.6.1"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "2.13.0",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz",
+          "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "uglify-to-browserify": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+      "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
+      "dev": true,
+      "optional": true
+    },
+    "uglifyjs-webpack-plugin": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.4.tgz",
+      "integrity": "sha512-z0IbjpW8b3O/OVn+TTZN4pI29RN1zktFBXLIzzfZ+++cUtZ1ERSlLWgpE/5OERuEUs1ijVQnpYAkSlpoVmQmSQ==",
+      "dev": true,
+      "requires": {
+        "cacache": "10.0.4",
+        "find-cache-dir": "1.0.0",
+        "schema-utils": "0.4.5",
+        "serialize-javascript": "1.4.0",
+        "source-map": "0.6.1",
+        "uglify-es": "3.3.9",
+        "webpack-sources": "1.1.0",
+        "worker-farm": "1.6.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "ultron": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
+      "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
+      "dev": true
+    },
+    "unc-path-regex": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+      "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=",
+      "dev": true
+    },
+    "underscore.string": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.4.tgz",
+      "integrity": "sha1-LCo/n4PmR2L9xF5s6sZRQoZCE9s=",
+      "dev": true,
+      "requires": {
+        "sprintf-js": "1.0.3",
+        "util-deprecate": "1.0.2"
+      }
+    },
+    "union-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
+      "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+      "dev": true,
+      "requires": {
+        "arr-union": "3.1.0",
+        "get-value": "2.0.6",
+        "is-extendable": "0.1.1",
+        "set-value": "0.4.3"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "0.1.1"
+          }
+        },
+        "set-value": {
+          "version": "0.4.3",
+          "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
+          "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
+          "dev": true,
+          "requires": {
+            "extend-shallow": "2.0.1",
+            "is-extendable": "0.1.1",
+            "is-plain-object": "2.0.4",
+            "to-object-path": "0.3.0"
+          }
+        }
+      }
+    },
+    "unique-filename": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.0.tgz",
+      "integrity": "sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM=",
+      "dev": true,
+      "requires": {
+        "unique-slug": "2.0.0"
+      }
+    },
+    "unique-slug": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz",
+      "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=",
+      "dev": true,
+      "requires": {
+        "imurmurhash": "0.1.4"
+      }
+    },
+    "unique-stream": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz",
+      "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=",
+      "dev": true,
+      "requires": {
+        "json-stable-stringify": "1.0.1",
+        "through2-filter": "2.0.0"
+      }
+    },
+    "unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+      "dev": true
+    },
+    "unset-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "dev": true,
+      "requires": {
+        "has-value": "0.3.1",
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "has-value": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+          "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+          "dev": true,
+          "requires": {
+            "get-value": "2.0.6",
+            "has-values": "0.1.4",
+            "isobject": "2.1.0"
+          },
+          "dependencies": {
+            "isobject": {
+              "version": "2.1.0",
+              "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+              "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+              "dev": true,
+              "requires": {
+                "isarray": "1.0.0"
+              }
+            }
+          }
+        },
+        "has-values": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+          "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+          "dev": true
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "upath": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.4.tgz",
+      "integrity": "sha512-d4SJySNBXDaQp+DPrziv3xGS6w3d2Xt69FijJr86zMPBy23JEloMCEOUBBzuN7xCtjLCnmB9tI/z7SBCahHBOw==",
+      "dev": true
+    },
+    "uri-js": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-3.0.2.tgz",
+      "integrity": "sha1-+QuFhQf4HepNz7s8TD2/orVX+qo=",
+      "dev": true,
+      "requires": {
+        "punycode": "2.1.0"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz",
+          "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=",
+          "dev": true
+        }
+      }
+    },
+    "urix": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "dev": true
+    },
+    "url": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz",
+      "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=",
+      "dev": true,
+      "requires": {
+        "punycode": "1.3.2",
+        "querystring": "0.2.0"
+      }
+    },
+    "url-parse-lax": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+      "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+      "dev": true,
+      "requires": {
+        "prepend-http": "1.0.4"
+      }
+    },
+    "url-to-options": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
+      "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=",
+      "dev": true
+    },
+    "use": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz",
+      "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==",
+      "dev": true,
+      "requires": {
+        "kind-of": "6.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "user-home": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz",
+      "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=",
+      "dev": true
+    },
+    "useragent": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz",
+      "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==",
+      "dev": true,
+      "requires": {
+        "lru-cache": "4.1.2",
+        "tmp": "0.0.33"
+      }
+    },
+    "util": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+      "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.1"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+          "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+          "dev": true
+        }
+      }
+    },
+    "util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "dev": true
+    },
+    "utils-merge": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz",
+      "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=",
+      "dev": true
+    },
+    "uuid": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
+      "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==",
+      "dev": true
+    },
+    "v8flags": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz",
+      "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=",
+      "dev": true,
+      "requires": {
+        "user-home": "1.1.1"
+      }
+    },
+    "validate-npm-package-license": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz",
+      "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==",
+      "dev": true,
+      "requires": {
+        "spdx-correct": "3.0.0",
+        "spdx-expression-parse": "3.0.0"
+      }
+    },
+    "vargs": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/vargs/-/vargs-0.1.0.tgz",
+      "integrity": "sha1-a2GE2mUgzDIEzhtAfKwm2SYJ6/8=",
+      "dev": true
+    },
+    "vary": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+      "dev": true
+    },
+    "verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "1.3.0"
+      },
+      "dependencies": {
+        "assert-plus": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+          "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+          "dev": true
+        }
+      }
+    },
+    "vm-browserify": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
+      "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=",
+      "dev": true,
+      "requires": {
+        "indexof": "0.0.1"
+      }
+    },
+    "void-elements": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
+      "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
+      "dev": true
+    },
+    "walkdir": {
+      "version": "0.0.11",
+      "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.0.11.tgz",
+      "integrity": "sha1-oW0CXrkxvQO1LzCMrtD0D86+lTI=",
+      "dev": true
+    },
+    "watchpack": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.5.0.tgz",
+      "integrity": "sha512-RSlipNQB1u48cq0wH/BNfCu1tD/cJ8ydFIkNYhp9o+3d+8unClkIovpW5qpFPgmL9OE48wfAnlZydXByWP82AA==",
+      "dev": true,
+      "requires": {
+        "chokidar": "2.0.3",
+        "graceful-fs": "4.1.11",
+        "neo-async": "2.5.0"
+      },
+      "dependencies": {
+        "anymatch": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+          "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+          "dev": true,
+          "requires": {
+            "micromatch": "3.1.10",
+            "normalize-path": "2.1.1"
+          }
+        },
+        "arr-diff": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+          "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+          "dev": true
+        },
+        "array-unique": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+          "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+          "dev": true
+        },
+        "braces": {
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.1.tgz",
+          "integrity": "sha512-SO5lYHA3vO6gz66erVvedSCkp7AKWdv6VcQ2N4ysXfPxdAlxAMMAdwegGGcv1Bqwm7naF1hNdk5d6AAIEHV2nQ==",
+          "dev": true,
+          "requires": {
+            "arr-flatten": "1.1.0",
+            "array-unique": "0.3.2",
+            "define-property": "1.0.0",
+            "extend-shallow": "2.0.1",
+            "fill-range": "4.0.0",
+            "isobject": "3.0.1",
+            "kind-of": "6.0.2",
+            "repeat-element": "1.1.2",
+            "snapdragon": "0.8.2",
+            "snapdragon-node": "2.1.1",
+            "split-string": "3.1.0",
+            "to-regex": "3.0.2"
+          },
+          "dependencies": {
+            "define-property": {
+              "version": "1.0.0",
+              "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+              "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+              "dev": true,
+              "requires": {
+                "is-descriptor": "1.0.2"
+              }
+            },
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            }
+          }
+        },
+        "chokidar": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz",
+          "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==",
+          "dev": true,
+          "requires": {
+            "anymatch": "2.0.0",
+            "async-each": "1.0.1",
+            "braces": "2.3.1",
+            "glob-parent": "3.1.0",
+            "inherits": "2.0.3",
+            "is-binary-path": "1.0.1",
+            "is-glob": "4.0.0",
+            "normalize-path": "2.1.1",
+            "path-is-absolute": "1.0.1",
+            "readdirp": "2.1.0",
+            "upath": "1.0.4"
+          }
+        },
+        "expand-brackets": {
+          "version": "2.1.4",
+          "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+          "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+          "dev": true,
+          "requires": {
+            "debug": "2.6.9",
+            "define-property": "0.2.5",
+            "extend-shallow": "2.0.1",
+            "posix-character-classes": "0.1.1",
+            "regex-not": "1.0.2",
+            "snapdragon": "0.8.2",
+            "to-regex": "3.0.2"
+          },
+          "dependencies": {
+            "define-property": {
+              "version": "0.2.5",
+              "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+              "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+              "dev": true,
+              "requires": {
+                "is-descriptor": "0.1.6"
+              }
+            },
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            },
+            "is-descriptor": {
+              "version": "0.1.6",
+              "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+              "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+              "dev": true,
+              "requires": {
+                "is-accessor-descriptor": "0.1.6",
+                "is-data-descriptor": "0.1.4",
+                "kind-of": "5.1.0"
+              }
+            },
+            "kind-of": {
+              "version": "5.1.0",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+              "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+              "dev": true
+            }
+          }
+        },
+        "extglob": {
+          "version": "2.0.4",
+          "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+          "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+          "dev": true,
+          "requires": {
+            "array-unique": "0.3.2",
+            "define-property": "1.0.0",
+            "expand-brackets": "2.1.4",
+            "extend-shallow": "2.0.1",
+            "fragment-cache": "0.2.1",
+            "regex-not": "1.0.2",
+            "snapdragon": "0.8.2",
+            "to-regex": "3.0.2"
+          },
+          "dependencies": {
+            "define-property": {
+              "version": "1.0.0",
+              "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+              "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+              "dev": true,
+              "requires": {
+                "is-descriptor": "1.0.2"
+              }
+            },
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            }
+          }
+        },
+        "fill-range": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+          "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+          "dev": true,
+          "requires": {
+            "extend-shallow": "2.0.1",
+            "is-number": "3.0.0",
+            "repeat-string": "1.6.1",
+            "to-regex-range": "2.1.1"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            }
+          }
+        },
+        "glob-parent": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+          "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+          "dev": true,
+          "requires": {
+            "is-glob": "3.1.0",
+            "path-dirname": "1.0.2"
+          },
+          "dependencies": {
+            "is-glob": {
+              "version": "3.1.0",
+              "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+              "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+              "dev": true,
+              "requires": {
+                "is-extglob": "2.1.1"
+              }
+            }
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+          "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.6"
+              }
+            }
+          }
+        },
+        "is-data-descriptor": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+          "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.6"
+              }
+            }
+          }
+        },
+        "is-extglob": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+          "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+          "dev": true
+        },
+        "is-glob": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
+          "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
+          "dev": true,
+          "requires": {
+            "is-extglob": "2.1.1"
+          }
+        },
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.6"
+              }
+            }
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        },
+        "micromatch": {
+          "version": "3.1.10",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+          "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+          "dev": true,
+          "requires": {
+            "arr-diff": "4.0.0",
+            "array-unique": "0.3.2",
+            "braces": "2.3.1",
+            "define-property": "2.0.2",
+            "extend-shallow": "3.0.2",
+            "extglob": "2.0.4",
+            "fragment-cache": "0.2.1",
+            "kind-of": "6.0.2",
+            "nanomatch": "1.2.9",
+            "object.pick": "1.3.0",
+            "regex-not": "1.0.2",
+            "snapdragon": "0.8.2",
+            "to-regex": "3.0.2"
+          }
+        }
+      }
+    },
+    "wd": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/wd/-/wd-1.6.1.tgz",
+      "integrity": "sha512-X3KnoYBqZ4Xj7phL3hWnraapl2w0N4z9lHKDFVNOpO2j3okoO2lhd9+oAFdd/qTbCNeNuGM59Pte360jx1hMVQ==",
+      "dev": true,
+      "requires": {
+        "archiver": "1.3.0",
+        "async": "2.0.1",
+        "lodash": "4.16.2",
+        "mkdirp": "0.5.1",
+        "q": "1.4.1",
+        "request": "2.79.0",
+        "underscore.string": "3.3.4",
+        "vargs": "0.1.0"
+      },
+      "dependencies": {
+        "async": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/async/-/async-2.0.1.tgz",
+          "integrity": "sha1-twnMAoCpw28J9FNr6CPIOKkEniU=",
+          "dev": true,
+          "requires": {
+            "lodash": "4.16.2"
+          }
+        },
+        "caseless": {
+          "version": "0.11.0",
+          "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
+          "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=",
+          "dev": true
+        },
+        "form-data": {
+          "version": "2.1.4",
+          "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
+          "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+          "dev": true,
+          "requires": {
+            "asynckit": "0.4.0",
+            "combined-stream": "1.0.6",
+            "mime-types": "2.1.18"
+          }
+        },
+        "har-validator": {
+          "version": "2.0.6",
+          "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
+          "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
+          "dev": true,
+          "requires": {
+            "chalk": "1.1.3",
+            "commander": "2.15.1",
+            "is-my-json-valid": "2.17.2",
+            "pinkie-promise": "2.0.1"
+          }
+        },
+        "lodash": {
+          "version": "4.16.2",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.16.2.tgz",
+          "integrity": "sha1-PmJtuCcEimmSgaihJSJjJs/A5lI=",
+          "dev": true
+        },
+        "q": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz",
+          "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=",
+          "dev": true
+        },
+        "qs": {
+          "version": "6.3.2",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
+          "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=",
+          "dev": true
+        },
+        "request": {
+          "version": "2.79.0",
+          "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz",
+          "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=",
+          "dev": true,
+          "requires": {
+            "aws-sign2": "0.6.0",
+            "aws4": "1.6.0",
+            "caseless": "0.11.0",
+            "combined-stream": "1.0.6",
+            "extend": "3.0.1",
+            "forever-agent": "0.6.1",
+            "form-data": "2.1.4",
+            "har-validator": "2.0.6",
+            "hawk": "3.1.3",
+            "http-signature": "1.1.1",
+            "is-typedarray": "1.0.0",
+            "isstream": "0.1.2",
+            "json-stringify-safe": "5.0.1",
+            "mime-types": "2.1.18",
+            "oauth-sign": "0.8.2",
+            "qs": "6.3.2",
+            "stringstream": "0.0.5",
+            "tough-cookie": "2.3.4",
+            "tunnel-agent": "0.4.3",
+            "uuid": "3.1.0"
+          }
+        },
+        "tunnel-agent": {
+          "version": "0.4.3",
+          "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
+          "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
+          "dev": true
+        }
+      }
+    },
+    "webpack": {
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.4.1.tgz",
+      "integrity": "sha1-TD9PP7MYFVpNsMtqNv8FxWl0GPQ=",
+      "dev": true,
+      "requires": {
+        "acorn": "5.5.3",
+        "acorn-dynamic-import": "2.0.2",
+        "ajv": "5.5.2",
+        "ajv-keywords": "2.1.1",
+        "async": "2.6.0",
+        "enhanced-resolve": "3.4.1",
+        "escope": "3.6.0",
+        "interpret": "1.1.0",
+        "json-loader": "0.5.7",
+        "json5": "0.5.1",
+        "loader-runner": "2.3.0",
+        "loader-utils": "1.1.0",
+        "memory-fs": "0.4.1",
+        "mkdirp": "0.5.1",
+        "node-libs-browser": "2.1.0",
+        "source-map": "0.5.7",
+        "supports-color": "4.5.0",
+        "tapable": "0.2.8",
+        "uglifyjs-webpack-plugin": "0.4.6",
+        "watchpack": "1.5.0",
+        "webpack-sources": "1.1.0",
+        "yargs": "8.0.2"
+      },
+      "dependencies": {
+        "ajv-keywords": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
+          "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
+          "dev": true
+        },
+        "async": {
+          "version": "2.6.0",
+          "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz",
+          "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==",
+          "dev": true,
+          "requires": {
+            "lodash": "4.17.5"
+          }
+        },
+        "camelcase": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+          "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
+          "dev": true
+        },
+        "cliui": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
+          "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
+          "dev": true,
+          "requires": {
+            "center-align": "0.1.3",
+            "right-align": "0.1.3",
+            "wordwrap": "0.0.2"
+          }
+        },
+        "has-flag": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "1.0.1"
+          }
+        },
+        "supports-color": {
+          "version": "4.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+          "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        },
+        "uglify-js": {
+          "version": "2.8.29",
+          "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
+          "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
+          "dev": true,
+          "requires": {
+            "source-map": "0.5.7",
+            "uglify-to-browserify": "1.0.2",
+            "yargs": "3.10.0"
+          },
+          "dependencies": {
+            "yargs": {
+              "version": "3.10.0",
+              "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
+              "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
+              "dev": true,
+              "requires": {
+                "camelcase": "1.2.1",
+                "cliui": "2.1.0",
+                "decamelize": "1.2.0",
+                "window-size": "0.1.0"
+              }
+            }
+          }
+        },
+        "uglifyjs-webpack-plugin": {
+          "version": "0.4.6",
+          "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz",
+          "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=",
+          "dev": true,
+          "requires": {
+            "source-map": "0.5.7",
+            "uglify-js": "2.8.29",
+            "webpack-sources": "1.1.0"
+          }
+        },
+        "wordwrap": {
+          "version": "0.0.2",
+          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
+          "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
+          "dev": true
+        },
+        "yargs": {
+          "version": "8.0.2",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz",
+          "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=",
+          "dev": true,
+          "requires": {
+            "camelcase": "4.1.0",
+            "cliui": "3.2.0",
+            "decamelize": "1.2.0",
+            "get-caller-file": "1.0.2",
+            "os-locale": "2.1.0",
+            "read-pkg-up": "2.0.0",
+            "require-directory": "2.1.1",
+            "require-main-filename": "1.0.1",
+            "set-blocking": "2.0.0",
+            "string-width": "2.1.1",
+            "which-module": "2.0.0",
+            "y18n": "3.2.1",
+            "yargs-parser": "7.0.0"
+          },
+          "dependencies": {
+            "camelcase": {
+              "version": "4.1.0",
+              "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+              "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+              "dev": true
+            },
+            "cliui": {
+              "version": "3.2.0",
+              "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+              "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+              "dev": true,
+              "requires": {
+                "string-width": "1.0.2",
+                "strip-ansi": "3.0.1",
+                "wrap-ansi": "2.1.0"
+              },
+              "dependencies": {
+                "string-width": {
+                  "version": "1.0.2",
+                  "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+                  "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+                  "dev": true,
+                  "requires": {
+                    "code-point-at": "1.1.0",
+                    "is-fullwidth-code-point": "1.0.0",
+                    "strip-ansi": "3.0.1"
+                  }
+                }
+              }
+            }
+          }
+        },
+        "yargs-parser": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz",
+          "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=",
+          "dev": true,
+          "requires": {
+            "camelcase": "4.1.0"
+          },
+          "dependencies": {
+            "camelcase": {
+              "version": "4.1.0",
+              "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+              "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+              "dev": true
+            }
+          }
+        }
+      }
+    },
+    "webpack-sources": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz",
+      "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==",
+      "dev": true,
+      "requires": {
+        "source-list-map": "2.0.0",
+        "source-map": "0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "websocket-stream": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/websocket-stream/-/websocket-stream-5.1.2.tgz",
+      "integrity": "sha512-lchLOk435iDWs0jNuL+hiU14i3ERSrMA0IKSiJh7z6X/i4XNsutBZrtqu2CPOZuA4G/zabiqVAos0vW+S7GEVw==",
+      "dev": true,
+      "requires": {
+        "duplexify": "3.5.4",
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.5",
+        "safe-buffer": "5.1.1",
+        "ws": "3.3.3",
+        "xtend": "4.0.1"
+      },
+      "dependencies": {
+        "ws": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
+          "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
+          "dev": true,
+          "requires": {
+            "async-limiter": "1.0.0",
+            "safe-buffer": "5.1.1",
+            "ultron": "1.1.1"
+          }
+        }
+      }
+    },
+    "which": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
+      "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
+      "dev": true,
+      "requires": {
+        "isexe": "2.0.0"
+      }
+    },
+    "which-module": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+      "dev": true
+    },
+    "window-size": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
+      "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
+      "dev": true
+    },
+    "wordwrap": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+      "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+      "dev": true
+    },
+    "worker-farm": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz",
+      "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==",
+      "dev": true,
+      "requires": {
+        "errno": "0.1.7"
+      }
+    },
+    "wrap-ansi": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+      "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+      "dev": true,
+      "requires": {
+        "string-width": "1.0.2",
+        "strip-ansi": "3.0.1"
+      },
+      "dependencies": {
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "1.0.1"
+          }
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+          "dev": true,
+          "requires": {
+            "code-point-at": "1.1.0",
+            "is-fullwidth-code-point": "1.0.0",
+            "strip-ansi": "3.0.1"
+          }
+        }
+      }
+    },
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "dev": true
+    },
+    "write": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
+      "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
+      "dev": true,
+      "requires": {
+        "mkdirp": "0.5.1"
+      }
+    },
+    "ws": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-2.0.3.tgz",
+      "integrity": "sha1-Uy/UmcP319cg5UPx+AcQbPxX2cs=",
+      "dev": true,
+      "requires": {
+        "ultron": "1.1.1"
+      }
+    },
+    "wtf-8": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz",
+      "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=",
+      "dev": true
+    },
+    "xml2js": {
+      "version": "0.4.17",
+      "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz",
+      "integrity": "sha1-F76T6q4/O3eTWceVtBlwWogX6Gg=",
+      "dev": true,
+      "requires": {
+        "sax": "1.2.1",
+        "xmlbuilder": "4.2.1"
+      }
+    },
+    "xmlbuilder": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz",
+      "integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=",
+      "dev": true,
+      "requires": {
+        "lodash": "4.17.5"
+      }
+    },
+    "xmlhttprequest-ssl": {
+      "version": "1.5.3",
+      "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz",
+      "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=",
+      "dev": true
+    },
+    "xtend": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+      "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+      "dev": true
+    },
+    "y18n": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+      "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
+      "dev": true
+    },
+    "yallist": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+      "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+      "dev": true
+    },
+    "yargs": {
+      "version": "11.0.0",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz",
+      "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==",
+      "dev": true,
+      "requires": {
+        "cliui": "4.0.0",
+        "decamelize": "1.2.0",
+        "find-up": "2.1.0",
+        "get-caller-file": "1.0.2",
+        "os-locale": "2.1.0",
+        "require-directory": "2.1.1",
+        "require-main-filename": "1.0.1",
+        "set-blocking": "2.0.0",
+        "string-width": "2.1.1",
+        "which-module": "2.0.0",
+        "y18n": "3.2.1",
+        "yargs-parser": "9.0.2"
+      }
+    },
+    "yargs-parser": {
+      "version": "9.0.2",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz",
+      "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=",
+      "dev": true,
+      "requires": {
+        "camelcase": "4.1.0"
+      }
+    },
+    "yeast": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
+      "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=",
+      "dev": true
+    },
+    "zip-stream": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz",
+      "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=",
+      "dev": true,
+      "requires": {
+        "archiver-utils": "1.3.0",
+        "compress-commons": "1.2.2",
+        "lodash": "4.17.5",
+        "readable-stream": "2.3.5"
+      }
+    }
+  }
+}
diff --git a/AstuteClient2/src/assets/html2canvas/package.json b/AstuteClient2/src/assets/html2canvas/package.json
new file mode 100644
index 0000000..9a62c92
--- /dev/null
+++ b/AstuteClient2/src/assets/html2canvas/package.json
@@ -0,0 +1,109 @@
+{
+  "_from": "html2canvas",
+  "_id": "html2canvas@1.0.0-alpha.12",
+  "_inBundle": false,
+  "_integrity": "sha1-OxmS48mz9WBjw1/WIElPN+uohRM=",
+  "_location": "/html2canvas",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "tag",
+    "registry": true,
+    "raw": "html2canvas",
+    "name": "html2canvas",
+    "escapedName": "html2canvas",
+    "rawSpec": "",
+    "saveSpec": null,
+    "fetchSpec": "latest"
+  },
+  "_requiredBy": [
+    "#USER",
+    "/",
+    "/html2pdf.js"
+  ],
+  "_resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.0.0-alpha.12.tgz",
+  "_shasum": "3b1992e3c9b3f56063c35fd620494f37eba88513",
+  "_spec": "html2canvas",
+  "_where": "D:\\Documents\\Astute\\AstuteClient",
+  "author": {
+    "name": "Niklas von Hertzen",
+    "email": "niklasvh@gmail.com",
+    "url": "https://hertzen.com"
+  },
+  "bugs": {
+    "url": "https://github.com/niklasvh/html2canvas/issues"
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "css-line-break": "1.0.1"
+  },
+  "deprecated": false,
+  "description": "Screenshots with JavaScript",
+  "devDependencies": {
+    "babel-cli": "6.24.1",
+    "babel-core": "6.25.0",
+    "babel-eslint": "7.2.3",
+    "babel-loader": "7.1.1",
+    "babel-plugin-dev-expression": "0.2.1",
+    "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
+    "babel-plugin-transform-object-rest-spread": "6.23.0",
+    "babel-preset-es2015": "6.24.1",
+    "babel-preset-flow": "6.23.0",
+    "base64-arraybuffer": "0.1.5",
+    "body-parser": "1.17.2",
+    "chai": "4.1.1",
+    "chromeless": "1.2.0",
+    "cors": "2.8.4",
+    "eslint": "4.2.0",
+    "eslint-plugin-flowtype": "2.35.0",
+    "eslint-plugin-prettier": "2.1.2",
+    "express": "4.15.4",
+    "filenamify-url": "1.0.0",
+    "flow-bin": "0.56.0",
+    "glob": "7.1.2",
+    "html2canvas-proxy": "1.0.0",
+    "jquery": "3.2.1",
+    "karma": "1.7.0",
+    "karma-chrome-launcher": "2.2.0",
+    "karma-edge-launcher": "0.4.1",
+    "karma-firefox-launcher": "1.0.1",
+    "karma-ie-launcher": "1.0.0",
+    "karma-mocha": "1.3.0",
+    "karma-sauce-launcher": "1.1.0",
+    "mocha": "3.5.0",
+    "platform": "1.3.4",
+    "prettier": "1.5.3",
+    "promise-polyfill": "6.0.2",
+    "replace-in-file": "^3.0.0",
+    "rimraf": "2.6.1",
+    "serve-index": "1.9.0",
+    "slash": "1.0.0",
+    "uglifyjs-webpack-plugin": "^1.1.2",
+    "webpack": "3.4.1"
+  },
+  "engines": {
+    "node": ">=4.0.0"
+  },
+  "homepage": "https://html2canvas.hertzen.com",
+  "license": "MIT",
+  "main": "dist/npm/index.js",
+  "name": "html2canvas",
+  "repository": {
+    "type": "git",
+    "url": "git+ssh://git@github.com/niklasvh/html2canvas.git"
+  },
+  "scripts": {
+    "build": "rimraf dist/ && node scripts/create-reftest-list && npm run build:npm && npm run build:browser",
+    "build:browser": "webpack",
+    "build:npm": "babel src/ -d dist/npm/ --plugins=dev-expression,transform-es2015-modules-commonjs && replace-in-file __VERSION__ '\"$npm_package_version\"' dist/npm/index.js",
+    "flow": "flow",
+    "format": "prettier --single-quote --no-bracket-spacing --tab-width 4 --print-width 100 --write \"{src,www/src,tests,scripts}/**/*.js\"",
+    "karma": "node karma",
+    "lint": "eslint src/**",
+    "start": "node tests/server",
+    "test": "npm run flow && npm run lint && npm run test:node && npm run karma",
+    "test:node": "mocha tests/node/*.js",
+    "watch": "webpack --progress --colors --watch"
+  },
+  "title": "html2canvas",
+  "version": "1.0.0-alpha.12"
+}
diff --git a/AstuteClient2/src/assets/html2pdf.js/.babelrc b/AstuteClient2/src/assets/html2pdf.js/.babelrc
new file mode 100644
index 0000000..4e994ca
--- /dev/null
+++ b/AstuteClient2/src/assets/html2pdf.js/.babelrc
@@ -0,0 +1,14 @@
+{
+  "presets": [
+    [
+      "env",
+      {
+        "modules": false
+      }
+    ]
+  ],
+  "plugins": [
+    "external-helpers",
+    "transform-object-assign"
+  ]
+}
diff --git a/AstuteClient2/src/assets/html2pdf.js/LICENSE b/AstuteClient2/src/assets/html2pdf.js/LICENSE
new file mode 100644
index 0000000..5b9b97e
--- /dev/null
+++ b/AstuteClient2/src/assets/html2pdf.js/LICENSE
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2017 Erik Koopmans
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/AstuteClient2/src/assets/html2pdf.js/README.md b/AstuteClient2/src/assets/html2pdf.js/README.md
new file mode 100644
index 0000000..e826899
--- /dev/null
+++ b/AstuteClient2/src/assets/html2pdf.js/README.md
@@ -0,0 +1,176 @@
+# html2pdf
+
+html2pdf converts any webpage or element into a printable PDF entirely client-side using [html2canvas](https://github.com/niklasvh/html2canvas) and [jsPDF](https://github.com/MrRio/jsPDF).
+
+## Getting started
+
+#### HTML
+
+The simplest way to use html2pdf is to download `dist/html2pdf.bundle.min.js` to your project folder and include it in your HTML with:
+
+```html
+<script src="html2pdf.bundle.min.js"></script>
+```
+
+*Note: [Click here](#dependencies) for more information about using the unbundled version `dist/html2canvas.min.js`.*
+
+#### NPM
+
+Install html2pdf and its dependencies using NPM with `npm install --save html2pdf.js` (make sure to include `.js` in the package name).
+
+*Note: You can use NPM to create your project, but html2pdf **will not run in Node.js**, it must be run in a browser.*
+
+#### Bower
+
+Install html2pdf and its dependencies using Bower with `bower install --save html2pdf.js` (make sure to include `.js` in the package name).
+
+## Usage
+
+Once installed, html2pdf is ready to use. The following command will generate a PDF of `#element-to-print` and prompt the user to save the result:
+
+```js
+var element = document.getElementById('element-to-print');
+html2pdf(element);
+```
+
+### Advanced usage
+
+Every step of html2pdf is configurable, using its new Promise-based API. If html2pdf is called without arguments, it will return a `Worker` object:
+
+```js
+var worker = html2pdf();  // Or:  var worker = new html2pdf.Worker;
+```
+
+This worker has methods that can be chained sequentially, as each Promise resolves, and allows insertion of your own intermediate functions between steps. A prerequisite system allows you to skip over mandatory steps (like canvas creation) without any trouble:
+
+```js
+// This will implicitly create the canvas and PDF objects before saving.
+var worker = html2pdf().from(element).save();
+```
+
+#### Workflow
+
+The basic workflow of html2pdf tasks (enforced by the prereq system) is:
+
+```
+.from() -> .toContainer() -> .toCanvas() -> .toImg() -> .toPdf() -> .save()
+```
+
+#### Worker API
+
+| Method       | Arguments          | Description |
+|--------------|--------------------|-------------|
+| from         | src, type          | Sets the source (HTML string or element) for the PDF. Optional `type` specifies other sources: `'string'`, `'element'`, `'canvas'`, or `'img'`. |
+| to           | target             | Converts the source to the specified target (`'container'`, `'canvas'`, `'img'`, or `'pdf'`). Each target also has its own `toX` method that can be called directly: `toContainer()`, `toCanvas()`, `toImg()`, and `toPdf()`. |
+| output       | type, options, src | Routes to the appropriate `outputPdf` or `outputImg` method based on specified `src` (`'pdf'` (default) or `'img'`). |
+| outputPdf    | type, options      | Sends `type` and `options` to the jsPDF object's `output` method, and returns the result as a Promise (use `.then` to access). See the [jsPDF source code](https://rawgit.com/MrRio/jsPDF/master/docs/jspdf.js.html#line992) for more info. |
+| outputImg    | type, options      | Returns the specified data type for the image as a Promise (use `.then` to access). Supported types: `'img'`, `'datauristring'`/`'dataurlstring'`, and `'datauri'`/`'dataurl'`. |
+| save         | filename           | Saves the PDF object with the optional filename (creates user download prompt). |
+| set          | opt                | Sets the specified properties. See [Options](#options) below for more details. |
+| get          | key, cbk           | Returns the property specified in `key`, either as a Promise (use `.then` to access), or by calling `cbk` if provided. |
+| then         | onFulfilled, onRejected | Standard Promise method, with `this` re-bound to the Worker, and with added progress-tracking (see [Progress](#progress) below). Note that `.then` returns a `Worker`, which is a subclass of Promise. |
+| thenCore     | onFulFilled, onRejected | Standard Promise method, with `this` re-bound to the Worker (no progress-tracking). Note that `.thenCore` returns a `Worker`, which is a subclass of Promise. |
+| thenExternal | onFulfilled, onRejected | True Promise method. Using this 'exits' the Worker chain - you will not be able to continue chaining Worker methods after `.thenExternal`. |
+| catch, catchExternal | onRejected | Standard Promise method. `catchExternal` exits the Worker chain - you will not be able to continue chaining Worker methods after `.catchExternal`. |
+| error        | msg                | Throws an error in the Worker's Promise chain. |
+
+A few aliases are also provided for convenience:
+
+| Method    | Alias     |
+|-----------|-----------|
+| save      | saveAs    |
+| set       | using     |
+| output    | export    |
+| then      | run       |
+
+## Options
+
+html2pdf can be configured using an optional `opt` parameter:
+
+```js
+var element = document.getElementById('element-to-print');
+var opt = {
+  margin:       1,
+  filename:     'myfile.pdf',
+  image:        { type: 'jpeg', quality: 0.98 },
+  html2canvas:  { scale: 2 },
+  jsPDF:        { unit: 'in', format: 'letter', orientation: 'portrait' }
+};
+
+// New Promise-based usage:
+html2pdf().from(element).set(opt).save();
+
+// Old monolithic-style usage:
+html2pdf(element, opt);
+```
+
+The `opt` parameter has the following optional fields:
+
+|Name        |Type            |Default                       |Description                                                                                                 |
+|------------|----------------|------------------------------|------------------------------------------------------------------------------------------------------------|
+|margin      |number or array |0                             |PDF margin (in jsPDF units). Can be a single number, `[vMargin, hMargin]`, or `[top, left, bottom, right]`. |
+|filename    |string          |'file.pdf'                    |The default filename of the exported PDF.                                                                   |
+|image       |object          |{type: 'jpeg', quality: 0.95} |The image type and quality used to generate the PDF. See the Extra Features section below.                  |
+|enableLinks |boolean         |true                          |If enabled, PDF hyperlinks are automatically added ontop of all anchor tags.                                |
+|html2canvas |object          |{ }                           |Configuration options sent directly to `html2canvas` ([see here](https://html2canvas.hertzen.com/configuration) for usage).|
+|jsPDF       |object          |{ }                           |Configuration options sent directly to `jsPDF` ([see here](http://rawgit.com/MrRio/jsPDF/master/docs/jsPDF.html) for usage).|
+
+### Page-breaks
+
+You may add `html2pdf`-specific page-breaks to your document by adding the CSS class `html2pdf__page-break` to any element (normally an empty `div`). For React elements, use `className=html2pdf__page-break`. During PDF creation, these elements will be given a height calculated to fill the remainder of the PDF page that they are on. Example usage:
+
+```html
+<div id="element-to-print">
+  <span>I'm on page 1!</span>
+  <div class="html2pdf__page-break"></div>
+  <span>I'm on page 2!</span>
+</div>
+```
+
+### Image type and quality
+
+You may customize the image type and quality exported from the canvas by setting the `image` option. This must be an object with the following fields:
+
+|Name        |Type            |Default                       |Description                                                                                  |
+|------------|----------------|------------------------------|---------------------------------------------------------------------------------------------|
+|type        |string          |'jpeg'                        |The image type. HTMLCanvasElement only supports 'png', 'jpeg', and 'webp' (on Chrome).       |
+|quality     |number          |0.95                          |The image quality, from 0 to 1. This setting is only used for jpeg/webp (not png).           |
+
+These options are limited to the available settings for [HTMLCanvasElement.toDataURL()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL), which ignores quality settings for 'png' images. To enable png image compression, try using the [canvas-png-compression shim](https://github.com/ShyykoSerhiy/canvas-png-compression), which should be an in-place solution to enable png compression via the `quality` option.
+
+## Progress
+
+The Worker object returned by `html2pdf()` has a built-in progress-tracking mechanism. It will be updated to allow a progress callback that will be called with each update, however it is currently a work-in-progress.
+
+## Dependencies
+
+html2pdf depends on the external packages [html2canvas](https://github.com/niklasvh/html2canvas), [jsPDF](https://github.com/MrRio/jsPDF), and [es6-promise](https://github.com/stefanpenner/es6-promise). These dependencies are automatically loaded when using NPM or the bundled package.
+
+If using the unbundled `dist/html2pdf.min.js` (or its un-minified version), you must also include each dependency. Order is important, otherwise html2canvas will be overridden by jsPDF's own internal implementation:
+
+```html
+<script src="es6-promise.auto.min.js"></script>
+<script src="jspdf.min.js"></script>
+<script src="html2canvas.min.js"></script>
+<script src="html2pdf.min.js"></script>
+```
+
+## Contributing
+
+### Issues
+
+When submitting an issue, please provide reproducible code that highlights the issue, preferably by creating a fork of [this template jsFiddle](https://jsfiddle.net/u6o6ne41/) (which has html2pdf already loaded). Remember that html2pdf uses [html2canvas](https://github.com/niklasvh/html2canvas) and [jsPDF](https://github.com/MrRio/jsPDF) as dependencies, so it's a good idea to check each of those repositories' issue trackers to see if your problem has already been addressed.
+
+### Pull requests
+
+If you want to create a new feature or bugfix, please feel free to fork and submit a pull request! Use the [`develop`](/eKoopmans/html2pdf/tree/develop) branch, which features the latest development, and make changes to `/src/` rather than directly to `/dist/`. You can test your changes by rebuilding with `npm run build`.
+
+## Credits
+
+[Erik Koopmans](https://github.com/eKoopmans)
+
+## License
+
+[The MIT License](http://opensource.org/licenses/MIT)
+
+Copyright (c) 2017 Erik Koopmans <[http://www.erik-koopmans.com/](http://www.erik-koopmans.com/)>
diff --git a/AstuteClient2/src/assets/html2pdf.js/bower.json b/AstuteClient2/src/assets/html2pdf.js/bower.json
new file mode 100644
index 0000000..3ea77a7
--- /dev/null
+++ b/AstuteClient2/src/assets/html2pdf.js/bower.json
@@ -0,0 +1,28 @@
+{
+  "name": "html2pdf.js",
+  "description": "Client-side HTML-to-PDF rendering using pure JS",
+  "main": "dist/html2pdf.bundle.js",
+  "moduleType": [
+    "amd",
+    "globals",
+    "node"
+  ],
+  "authors": [
+    "Erik Koopmans <erik@erik-koopmans.com>"
+  ],
+  "license": "MIT",
+  "keywords": [
+    "javascript",
+    "pdf-generation",
+    "html",
+    "client-side",
+    "canvas"
+  ],
+  "homepage": "https://github.com/eKoopmans/html2pdf",
+  "ignore": [
+    "node_modules/",
+    "bower_components/",
+    ".archive/",
+    ".devel/"
+  ]
+}
diff --git a/AstuteClient2/src/assets/html2pdf.js/dist/html2pdf.js b/AstuteClient2/src/assets/html2pdf.js/dist/html2pdf.js
new file mode 100644
index 0000000..d3570be
--- /dev/null
+++ b/AstuteClient2/src/assets/html2pdf.js/dist/html2pdf.js
@@ -0,0 +1,803 @@
+/**
+ * html2pdf.js v0.9.0
+ * Copyright (c) 2018 Erik Koopmans
+ * Released under the MIT License.
+ */
+(function (global, factory) {
+	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('es6-promise/auto'), require('jspdf'), require('html2canvas')) :
+	typeof define === 'function' && define.amd ? define(['es6-promise/auto', 'jspdf', 'html2canvas'], factory) :
+	(global.html2pdf = factory(null,global.jsPDF,global.html2canvas));
+}(this, (function (auto,jsPDF,html2canvas) { 'use strict';
+
+jsPDF = jsPDF && jsPDF.hasOwnProperty('default') ? jsPDF['default'] : jsPDF;
+html2canvas = html2canvas && html2canvas.hasOwnProperty('default') ? html2canvas['default'] : html2canvas;
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
+  return typeof obj;
+} : function (obj) {
+  return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+var _extends = Object.assign || function (target) {
+  for (var i = 1; i < arguments.length; i++) {
+    var source = arguments[i];
+
+    for (var key in source) {
+      if (Object.prototype.hasOwnProperty.call(source, key)) {
+        target[key] = source[key];
+      }
+    }
+  }
+
+  return target;
+};
+
+// Determine the type of a variable/object.
+var objType = function objType(obj) {
+  var type = typeof obj === 'undefined' ? 'undefined' : _typeof(obj);
+  if (type === 'undefined') return 'undefined';else if (type === 'string' || obj instanceof String) return 'string';else if (type === 'number' || obj instanceof Number) return 'number';else if (type === 'function' || obj instanceof Function) return 'function';else if (!!obj && obj.constructor === Array) return 'array';else if (obj && obj.nodeType === 1) return 'element';else if (type === 'object') return 'object';else return 'unknown';
+};
+
+// Create an HTML element with optional className, innerHTML, and style.
+var createElement = function createElement(tagName, opt) {
+  var el = document.createElement(tagName);
+  if (opt.className) el.className = opt.className;
+  if (opt.innerHTML) {
+    el.innerHTML = opt.innerHTML;
+    var scripts = el.getElementsByTagName('script');
+    for (var i = scripts.length; i-- > 0; null) {
+      scripts[i].parentNode.removeChild(scripts[i]);
+    }
+  }
+  for (var key in opt.style) {
+    el.style[key] = opt.style[key];
+  }
+  return el;
+};
+
+// Deep-clone a node and preserve contents/properties.
+var cloneNode = function cloneNode(node, javascriptEnabled) {
+  // Recursively clone the node.
+  var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);
+  for (var child = node.firstChild; child; child = child.nextSibling) {
+    if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') {
+      clone.appendChild(cloneNode(child, javascriptEnabled));
+    }
+  }
+
+  if (node.nodeType === 1) {
+    // Preserve contents/properties of special nodes.
+    if (node.nodeName === 'CANVAS') {
+      clone.width = node.width;
+      clone.height = node.height;
+      clone.getContext('2d').drawImage(node, 0, 0);
+    } else if (node.nodeName === 'TEXTAREA' || node.nodeName === 'SELECT') {
+      clone.value = node.value;
+    }
+
+    // Preserve the node's scroll position when it loads.
+    clone.addEventListener('load', function () {
+      clone.scrollTop = node.scrollTop;
+      clone.scrollLeft = node.scrollLeft;
+    }, true);
+  }
+
+  // Return the cloned node.
+  return clone;
+};
+
+// Convert units using the conversion value 'k' from jsPDF.
+var unitConvert = function unitConvert(obj, k) {
+  var newObj = {};
+  for (var key in obj) {
+    newObj[key] = obj[key] * 72 / 96 / k;
+  }
+  return newObj;
+};
+
+/* ----- CONSTRUCTOR ----- */
+
+var Worker = function Worker(opt) {
+  // Create the root parent for the proto chain, and the starting Worker.
+  var root = _extends(Worker.convert(Promise.resolve()), JSON.parse(JSON.stringify(Worker.template)));
+  var self = Worker.convert(Promise.resolve(), root);
+
+  // Set progress, optional settings, and return.
+  self = self.setProgress(1, Worker, 1, [Worker]);
+  self = self.set(opt);
+  return self;
+};
+
+// Boilerplate for subclassing Promise.
+Worker.prototype = Object.create(Promise.prototype);
+Worker.prototype.constructor = Worker;
+
+// Converts/casts promises into Workers.
+Worker.convert = function convert(promise, inherit) {
+  // Uses prototypal inheritance to receive changes made to ancestors' properties.
+  promise.__proto__ = inherit || Worker.prototype;
+  return promise;
+};
+
+Worker.template = {
+  prop: {
+    src: null,
+    container: null,
+    overlay: null,
+    canvas: null,
+    img: null,
+    pdf: null,
+    pageSize: null
+  },
+  progress: {
+    val: 0,
+    state: null,
+    n: 0,
+    stack: []
+  },
+  opt: {
+    filename: 'file.pdf',
+    margin: [0, 0, 0, 0],
+    image: { type: 'jpeg', quality: 0.95 },
+    enableLinks: true,
+    html2canvas: {},
+    jsPDF: {}
+  }
+};
+
+/* ----- FROM / TO ----- */
+
+Worker.prototype.from = function from(src, type) {
+  function getType(src) {
+    switch (objType(src)) {
+      case 'string':
+        return 'string';
+      case 'element':
+        return src.nodeName.toLowerCase === 'canvas' ? 'canvas' : 'element';
+      default:
+        return 'unknown';
+    }
+  }
+
+  return this.then(function from_main() {
+    type = type || getType(src);
+    switch (type) {
+      case 'string':
+        return this.set({ src: createElement('div', { innerHTML: src }) });
+      case 'element':
+        return this.set({ src: src });
+      case 'canvas':
+        return this.set({ canvas: src });
+      case 'img':
+        return this.set({ img: src });
+      default:
+        return this.error('Unknown source type.');
+    }
+  });
+};
+
+Worker.prototype.to = function to(target) {
+  // Route the 'to' request to the appropriate method.
+  switch (target) {
+    case 'container':
+      return this.toContainer();
+    case 'canvas':
+      return this.toCanvas();
+    case 'img':
+      return this.toImg();
+    case 'pdf':
+      return this.toPdf();
+    default:
+      return this.error('Invalid target.');
+  }
+};
+
+Worker.prototype.toContainer = function toContainer() {
+  // Set up function prerequisites.
+  var prereqs = [function checkSrc() {
+    return this.prop.src || this.error('Cannot duplicate - no source HTML.');
+  }, function checkPageSize() {
+    return this.prop.pageSize || this.setPageSize();
+  }];
+
+  return this.thenList(prereqs).then(function toContainer_main() {
+    // Define the CSS styles for the container and its overlay parent.
+    var overlayCSS = {
+      position: 'fixed', overflow: 'hidden', zIndex: 1000,
+      left: 0, right: 0, bottom: 0, top: 0,
+      backgroundColor: 'rgba(0,0,0,0.8)'
+    };
+    var containerCSS = {
+      position: 'absolute', width: this.prop.pageSize.inner.width + this.prop.pageSize.unit,
+      left: 0, right: 0, top: 0, height: 'auto', margin: 'auto',
+      backgroundColor: 'white'
+    };
+
+    // Set the overlay to hidden (could be changed in the future to provide a print preview).
+    overlayCSS.opacity = 0;
+
+    // Create and attach the elements.
+    var source = cloneNode(this.prop.src, this.opt.html2canvas.javascriptEnabled);
+    this.prop.overlay = createElement('div', { className: 'html2pdf__overlay', style: overlayCSS });
+    this.prop.container = createElement('div', { className: 'html2pdf__container', style: containerCSS });
+    this.prop.container.appendChild(source);
+    this.prop.overlay.appendChild(this.prop.container);
+    document.body.appendChild(this.prop.overlay);
+  });
+};
+
+Worker.prototype.toCanvas = function toCanvas() {
+  // Set up function prerequisites.
+  var prereqs = [function checkContainer() {
+    return document.body.contains(this.prop.container) || this.toContainer();
+  }];
+
+  // Fulfill prereqs then create the canvas.
+  return this.thenList(prereqs).then(function toCanvas_main() {
+    // Handle old-fashioned 'onrendered' argument.
+    var options = _extends({}, this.opt.html2canvas);
+    delete options.onrendered;
+
+    return html2canvas(this.prop.container, options);
+  }).then(function toCanvas_post(canvas) {
+    // Handle old-fashioned 'onrendered' argument.
+    var onRendered = this.opt.html2canvas.onrendered || function () {};
+    onRendered(canvas);
+
+    this.prop.canvas = canvas;
+    document.body.removeChild(this.prop.overlay);
+  });
+};
+
+Worker.prototype.toImg = function toImg() {
+  // Set up function prerequisites.
+  var prereqs = [function checkCanvas() {
+    return this.prop.canvas || this.toCanvas();
+  }];
+
+  // Fulfill prereqs then create the image.
+  return this.thenList(prereqs).then(function toImg_main() {
+    var imgData = this.prop.canvas.toDataURL('image/' + this.opt.image.type, this.opt.image.quality);
+    this.prop.img = document.createElement('img');
+    this.prop.img.src = imgData;
+  });
+};
+
+Worker.prototype.toPdf = function toPdf() {
+  // Set up function prerequisites.
+  var prereqs = [function checkCanvas() {
+    return this.prop.canvas || this.toCanvas();
+  }];
+
+  // Fulfill prereqs then create the image.
+  return this.thenList(prereqs).then(function toPdf_main() {
+    // Create local copies of frequently used properties.
+    var canvas = this.prop.canvas;
+    var opt = this.opt;
+
+    // Calculate the number of pages.
+    var ctx = canvas.getContext('2d');
+    var pxFullHeight = canvas.height;
+    var pxPageHeight = Math.floor(canvas.width * this.prop.pageSize.inner.ratio);
+    var nPages = Math.ceil(pxFullHeight / pxPageHeight);
+
+    // Define pageHeight separately so it can be trimmed on the final page.
+    var pageHeight = this.prop.pageSize.inner.height;
+
+    // Create a one-page canvas to split up the full image.
+    var pageCanvas = document.createElement('canvas');
+    var pageCtx = pageCanvas.getContext('2d');
+    pageCanvas.width = canvas.width;
+    pageCanvas.height = pxPageHeight;
+
+    // Initialize the PDF.
+    this.prop.pdf = this.prop.pdf || new jsPDF(opt.jsPDF);
+
+    for (var page = 0; page < nPages; page++) {
+      // Trim the final page to reduce file size.
+      if (page === nPages - 1) {
+        pageCanvas.height = pxFullHeight % pxPageHeight;
+        pageHeight = pageCanvas.height * this.prop.pageSize.inner.width / pageCanvas.width;
+      }
+
+      // Display the page.
+      var w = pageCanvas.width;
+      var h = pageCanvas.height;
+      pageCtx.fillStyle = 'white';
+      pageCtx.fillRect(0, 0, w, h);
+      pageCtx.drawImage(canvas, 0, page * pxPageHeight, w, h, 0, 0, w, h);
+
+      // Add the page to the PDF.
+      if (page) this.prop.pdf.addPage();
+      var imgData = pageCanvas.toDataURL('image/' + opt.image.type, opt.image.quality);
+      this.prop.pdf.addImage(imgData, opt.image.type, opt.margin[1], opt.margin[0], this.prop.pageSize.inner.width, pageHeight);
+    }
+  });
+};
+
+/* ----- OUTPUT / SAVE ----- */
+
+Worker.prototype.output = function output(type, options, src) {
+  // Redirect requests to the correct function (outputPdf / outputImg).
+  src = src || 'pdf';
+  if (src.toLowerCase() === 'img' || src.toLowerCase() === 'image') {
+    return this.outputImg(type, options);
+  } else {
+    return this.outputPdf(type, options);
+  }
+};
+
+Worker.prototype.outputPdf = function outputPdf(type, options) {
+  // Set up function prerequisites.
+  var prereqs = [function checkPdf() {
+    return this.prop.pdf || this.toPdf();
+  }];
+
+  // Fulfill prereqs then perform the appropriate output.
+  return this.thenList(prereqs).then(function outputPdf_main() {
+    /* Currently implemented output types:
+     *    https://rawgit.com/MrRio/jsPDF/master/docs/jspdf.js.html#line992
+     *  save(options), arraybuffer, blob, bloburi/bloburl,
+     *  datauristring/dataurlstring, dataurlnewwindow, datauri/dataurl
+     */
+    return this.prop.pdf.output(type, options);
+  });
+};
+
+Worker.prototype.outputImg = function outputImg(type, options) {
+  // Set up function prerequisites.
+  var prereqs = [function checkImg() {
+    return this.prop.img || this.toImg();
+  }];
+
+  // Fulfill prereqs then perform the appropriate output.
+  return this.thenList(prereqs).then(function outputImg_main() {
+    switch (type) {
+      case undefined:
+      case 'img':
+        return this.prop.img;
+      case 'datauristring':
+      case 'dataurlstring':
+        return this.prop.img.src;
+      case 'datauri':
+      case 'dataurl':
+        return document.location.href = this.prop.img.src;
+      default:
+        throw 'Image output type "' + type + '" is not supported.';
+    }
+  });
+};
+
+Worker.prototype.save = function save(filename) {
+  // Set up function prerequisites.
+  var prereqs = [function checkPdf() {
+    return this.prop.pdf || this.toPdf();
+  }];
+
+  // Fulfill prereqs, update the filename (if provided), and save the PDF.
+  return this.thenList(prereqs).set(filename ? { filename: filename } : null).then(function save_main() {
+    this.prop.pdf.save(this.opt.filename);
+  });
+};
+
+/* ----- SET / GET ----- */
+
+Worker.prototype.set = function set$$1(opt) {
+  // TODO: Implement ordered pairs?
+
+  // Silently ignore invalid or empty input.
+  if (objType(opt) !== 'object') {
+    return this;
+  }
+
+  // Build an array of setter functions to queue.
+  var fns = Object.keys(opt || {}).map(function (key) {
+    if (key in Worker.template.prop) {
+      // Set pre-defined properties.
+      return function set_prop() {
+        this.prop[key] = opt[key];
+      };
+    } else {
+      switch (key) {
+        case 'margin':
+          return this.setMargin.bind(this, opt.margin);
+        case 'jsPDF':
+          return function set_jsPDF() {
+            this.opt.jsPDF = opt.jsPDF;return this.setPageSize();
+          };
+        case 'pageSize':
+          return this.setPageSize.bind(this, opt.pageSize);
+        default:
+          // Set any other properties in opt.
+          return function set_opt() {
+            this.opt[key] = opt[key];
+          };
+      }
+    }
+  }, this);
+
+  // Set properties within the promise chain.
+  return this.then(function set_main() {
+    return this.thenList(fns);
+  });
+};
+
+Worker.prototype.get = function get$$1(key, cbk) {
+  return this.then(function get_main() {
+    // Fetch the requested property, either as a predefined prop or in opt.
+    var val = key in Worker.template.prop ? this.prop[key] : this.opt[key];
+    return cbk ? cbk(val) : val;
+  });
+};
+
+Worker.prototype.setMargin = function setMargin(margin) {
+  return this.then(function setMargin_main() {
+    // Parse the margin property.
+    switch (objType(margin)) {
+      case 'number':
+        margin = [margin, margin, margin, margin];
+      case 'array':
+        if (margin.length === 2) {
+          margin = [margin[0], margin[1], margin[0], margin[1]];
+        }
+        if (margin.length === 4) {
+          break;
+        }
+      default:
+        return this.error('Invalid margin array.');
+    }
+
+    // Set the margin property, then update pageSize.
+    this.opt.margin = margin;
+  }).then(this.setPageSize);
+};
+
+Worker.prototype.setPageSize = function setPageSize(pageSize) {
+  function toPx(val, k) {
+    return Math.floor(val * k / 72 * 96);
+  }
+
+  return this.then(function setPageSize_main() {
+    // Retrieve page-size based on jsPDF settings, if not explicitly provided.
+    pageSize = pageSize || jsPDF.getPageSize(this.opt.jsPDF);
+
+    // Add 'inner' field if not present.
+    if (!pageSize.hasOwnProperty('inner')) {
+      pageSize.inner = {
+        width: pageSize.width - this.opt.margin[1] - this.opt.margin[3],
+        height: pageSize.height - this.opt.margin[0] - this.opt.margin[2]
+      };
+      pageSize.inner.px = {
+        width: toPx(pageSize.inner.width, pageSize.k),
+        height: toPx(pageSize.inner.height, pageSize.k)
+      };
+      pageSize.inner.ratio = pageSize.inner.height / pageSize.inner.width;
+    }
+
+    // Attach pageSize to this.
+    this.prop.pageSize = pageSize;
+  });
+};
+
+Worker.prototype.setProgress = function setProgress(val, state, n, stack) {
+  // Immediately update all progress values.
+  if (val != null) this.progress.val = val;
+  if (state != null) this.progress.state = state;
+  if (n != null) this.progress.n = n;
+  if (stack != null) this.progress.stack = stack;
+  this.progress.ratio = this.progress.val / this.progress.state;
+
+  // Return this for command chaining.
+  return this;
+};
+
+Worker.prototype.updateProgress = function updateProgress(val, state, n, stack) {
+  // Immediately update all progress values, using setProgress.
+  return this.setProgress(val ? this.progress.val + val : null, state ? state : null, n ? this.progress.n + n : null, stack ? this.progress.stack.concat(stack) : null);
+};
+
+/* ----- PROMISE MAPPING ----- */
+
+Worker.prototype.then = function then(onFulfilled, onRejected) {
+  // Wrap `this` for encapsulation.
+  var self = this;
+
+  return this.thenCore(onFulfilled, onRejected, function then_main(onFulfilled, onRejected) {
+    // Update progress while queuing, calling, and resolving `then`.
+    self.updateProgress(null, null, 1, [onFulfilled]);
+    return Promise.prototype.then.call(this, function then_pre(val) {
+      self.updateProgress(null, onFulfilled);
+      return val;
+    }).then(onFulfilled, onRejected).then(function then_post(val) {
+      self.updateProgress(1);
+      return val;
+    });
+  });
+};
+
+Worker.prototype.thenCore = function thenCore(onFulfilled, onRejected, thenBase) {
+  // Handle optional thenBase parameter.
+  thenBase = thenBase || Promise.prototype.then;
+
+  // Wrap `this` for encapsulation and bind it to the promise handlers.
+  var self = this;
+  if (onFulfilled) {
+    onFulfilled = onFulfilled.bind(self);
+  }
+  if (onRejected) {
+    onRejected = onRejected.bind(self);
+  }
+
+  // Cast self into a Promise to avoid polyfills recursively defining `then`.
+  var isNative = Promise.toString().indexOf('[native code]') !== -1 && Promise.name === 'Promise';
+  var selfPromise = isNative ? self : Worker.convert(_extends({}, self), Promise.prototype);
+
+  // Return the promise, after casting it into a Worker and preserving props.
+  var returnVal = thenBase.call(selfPromise, onFulfilled, onRejected);
+  return Worker.convert(returnVal, self.__proto__);
+};
+
+Worker.prototype.thenExternal = function thenExternal(onFulfilled, onRejected) {
+  // Call `then` and return a standard promise (exits the Worker chain).
+  return Promise.prototype.then.call(this, onFulfilled, onRejected);
+};
+
+Worker.prototype.thenList = function thenList(fns) {
+  // Queue a series of promise 'factories' into the promise chain.
+  var self = this;
+  fns.forEach(function thenList_forEach(fn) {
+    self = self.thenCore(fn);
+  });
+  return self;
+};
+
+Worker.prototype['catch'] = function (onRejected) {
+  // Bind `this` to the promise handler, call `catch`, and return a Worker.
+  if (onRejected) {
+    onRejected = onRejected.bind(this);
+  }
+  var returnVal = Promise.prototype['catch'].call(this, onRejected);
+  return Worker.convert(returnVal, this);
+};
+
+Worker.prototype.catchExternal = function catchExternal(onRejected) {
+  // Call `catch` and return a standard promise (exits the Worker chain).
+  return Promise.prototype['catch'].call(this, onRejected);
+};
+
+Worker.prototype.error = function error(msg) {
+  // Throw the error in the Promise chain.
+  return this.then(function error_main() {
+    throw new Error(msg);
+  });
+};
+
+/* ----- ALIASES ----- */
+
+Worker.prototype.using = Worker.prototype.set;
+Worker.prototype.saveAs = Worker.prototype.save;
+Worker.prototype.export = Worker.prototype.output;
+Worker.prototype.run = Worker.prototype.then;
+
+// Import dependencies.
+// Get dimensions of a PDF page, as determined by jsPDF.
+jsPDF.getPageSize = function (orientation, unit, format) {
+  // Decode options object
+  if ((typeof orientation === 'undefined' ? 'undefined' : _typeof(orientation)) === 'object') {
+    var options = orientation;
+    orientation = options.orientation;
+    unit = options.unit || unit;
+    format = options.format || format;
+  }
+
+  // Default options
+  unit = unit || 'mm';
+  format = format || 'a4';
+  orientation = ('' + (orientation || 'P')).toLowerCase();
+  var format_as_string = ('' + format).toLowerCase();
+
+  // Size in pt of various paper formats
+  var pageFormats = {
+    'a0': [2383.94, 3370.39], 'a1': [1683.78, 2383.94],
+    'a2': [1190.55, 1683.78], 'a3': [841.89, 1190.55],
+    'a4': [595.28, 841.89], 'a5': [419.53, 595.28],
+    'a6': [297.64, 419.53], 'a7': [209.76, 297.64],
+    'a8': [147.40, 209.76], 'a9': [104.88, 147.40],
+    'a10': [73.70, 104.88], 'b0': [2834.65, 4008.19],
+    'b1': [2004.09, 2834.65], 'b2': [1417.32, 2004.09],
+    'b3': [1000.63, 1417.32], 'b4': [708.66, 1000.63],
+    'b5': [498.90, 708.66], 'b6': [354.33, 498.90],
+    'b7': [249.45, 354.33], 'b8': [175.75, 249.45],
+    'b9': [124.72, 175.75], 'b10': [87.87, 124.72],
+    'c0': [2599.37, 3676.54], 'c1': [1836.85, 2599.37],
+    'c2': [1298.27, 1836.85], 'c3': [918.43, 1298.27],
+    'c4': [649.13, 918.43], 'c5': [459.21, 649.13],
+    'c6': [323.15, 459.21], 'c7': [229.61, 323.15],
+    'c8': [161.57, 229.61], 'c9': [113.39, 161.57],
+    'c10': [79.37, 113.39], 'dl': [311.81, 623.62],
+    'letter': [612, 792],
+    'government-letter': [576, 756],
+    'legal': [612, 1008],
+    'junior-legal': [576, 360],
+    'ledger': [1224, 792],
+    'tabloid': [792, 1224],
+    'credit-card': [153, 243]
+  };
+
+  // Unit conversion
+  switch (unit) {
+    case 'pt':
+      var k = 1;break;
+    case 'mm':
+      var k = 72 / 25.4;break;
+    case 'cm':
+      var k = 72 / 2.54;break;
+    case 'in':
+      var k = 72;break;
+    case 'px':
+      var k = 72 / 96;break;
+    case 'pc':
+      var k = 12;break;
+    case 'em':
+      var k = 12;break;
+    case 'ex':
+      var k = 6;break;
+    default:
+      throw 'Invalid unit: ' + unit;
+  }
+
+  // Dimensions are stored as user units and converted to points on output
+  if (pageFormats.hasOwnProperty(format_as_string)) {
+    var pageHeight = pageFormats[format_as_string][1] / k;
+    var pageWidth = pageFormats[format_as_string][0] / k;
+  } else {
+    try {
+      var pageHeight = format[1];
+      var pageWidth = format[0];
+    } catch (err) {
+      throw new Error('Invalid format: ' + format);
+    }
+  }
+
+  // Handle page orientation
+  if (orientation === 'p' || orientation === 'portrait') {
+    orientation = 'p';
+    if (pageWidth > pageHeight) {
+      var tmp = pageWidth;
+      pageWidth = pageHeight;
+      pageHeight = tmp;
+    }
+  } else if (orientation === 'l' || orientation === 'landscape') {
+    orientation = 'l';
+    if (pageHeight > pageWidth) {
+      var tmp = pageWidth;
+      pageWidth = pageHeight;
+      pageHeight = tmp;
+    }
+  } else {
+    throw 'Invalid orientation: ' + orientation;
+  }
+
+  // Return information (k is the unit conversion ratio from pts)
+  var info = { 'width': pageWidth, 'height': pageHeight, 'unit': unit, 'k': k };
+  return info;
+};
+
+var orig = {
+  toContainer: Worker.prototype.toContainer
+};
+
+Worker.prototype.toContainer = function toContainer() {
+  return orig.toContainer.call(this).then(function toContainer_pagebreak() {
+    // Enable page-breaks.
+    var pageBreaks = this.prop.container.querySelectorAll('.html2pdf__page-break');
+    var pxPageHeight = this.prop.pageSize.inner.px.height;
+    Array.prototype.forEach.call(pageBreaks, function pageBreak_loop(el) {
+      el.style.display = 'block';
+      var clientRect = el.getBoundingClientRect();
+      el.style.height = pxPageHeight - clientRect.top % pxPageHeight + 'px';
+    }, this);
+  });
+};
+
+// Add hyperlink functionality to the PDF creation.
+
+// Main link array, and refs to original functions.
+var linkInfo = [];
+var orig$1 = {
+  toContainer: Worker.prototype.toContainer,
+  toPdf: Worker.prototype.toPdf
+};
+
+Worker.prototype.toContainer = function toContainer() {
+  return orig$1.toContainer.call(this).then(function toContainer_hyperlink() {
+    // Retrieve hyperlink info if the option is enabled.
+    if (this.opt.enableLinks) {
+      // Find all anchor tags and get the container's bounds for reference.
+      var container = this.prop.container;
+      var links = container.querySelectorAll('a');
+      var containerRect = unitConvert(container.getBoundingClientRect(), this.prop.pageSize.k);
+      linkInfo = [];
+
+      // Loop through each anchor tag.
+      Array.prototype.forEach.call(links, function (link) {
+        // Treat each client rect as a separate link (for text-wrapping).
+        var clientRects = link.getClientRects();
+        for (var i = 0; i < clientRects.length; i++) {
+          var clientRect = unitConvert(clientRects[i], this.prop.pageSize.k);
+          clientRect.left -= containerRect.left;
+          clientRect.top -= containerRect.top;
+
+          var page = Math.floor(clientRect.top / this.prop.pageSize.inner.height) + 1;
+          var top = this.opt.margin[0] + clientRect.top % this.prop.pageSize.inner.height;
+          var left = this.opt.margin[1] + clientRect.left;
+
+          linkInfo.push({ page: page, top: top, left: left, clientRect: clientRect, link: link });
+        }
+      }, this);
+    }
+  });
+};
+
+Worker.prototype.toPdf = function toPdf() {
+  return orig$1.toPdf.call(this).then(function toPdf_hyperlink() {
+    // Add hyperlinks if the option is enabled.
+    if (this.opt.enableLinks) {
+      // Attach each anchor tag based on info from toContainer().
+      linkInfo.forEach(function (l) {
+        this.prop.pdf.setPage(l.page);
+        this.prop.pdf.link(l.left, l.top, l.clientRect.width, l.clientRect.height, { url: l.link.href });
+      }, this);
+
+      // Reset the active page of the PDF to the final page.
+      var nPages = this.prop.pdf.internal.getNumberOfPages();
+      this.prop.pdf.setPage(nPages);
+    }
+  });
+};
+
+/**
+ * Generate a PDF from an HTML element or string using html2canvas and jsPDF.
+ *
+ * @param {Element|string} source The source element or HTML string.
+ * @param {Object=} opt An object of optional settings: 'margin', 'filename',
+ *    'image' ('type' and 'quality'), and 'html2canvas' / 'jspdf', which are
+ *    sent as settings to their corresponding functions.
+ */
+var html2pdf = function html2pdf(src, opt) {
+  // Create a new worker with the given options.
+  var worker = new html2pdf.Worker(opt);
+
+  if (src) {
+    // If src is specified, perform the traditional 'simple' operation.
+    return worker.from(src).save();
+  } else {
+    // Otherwise, return the worker for new Promise-based operation.
+    return worker;
+  }
+};
+html2pdf.Worker = Worker;
+
+return html2pdf;
+
+})));
diff --git a/AstuteClient2/src/assets/html2pdf.js/dist/include/html2pdf.es.js b/AstuteClient2/src/assets/html2pdf.js/dist/include/html2pdf.es.js
new file mode 100644
index 0000000..9446b60
--- /dev/null
+++ b/AstuteClient2/src/assets/html2pdf.js/dist/include/html2pdf.es.js
@@ -0,0 +1,796 @@
+/**
+ * html2pdf.js v0.9.0
+ * Copyright (c) 2018 Erik Koopmans
+ * Released under the MIT License.
+ */
+import 'es6-promise/auto';
+import jsPDF from 'jspdf';
+import html2canvas from 'html2canvas';
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
+  return typeof obj;
+} : function (obj) {
+  return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+var _extends = Object.assign || function (target) {
+  for (var i = 1; i < arguments.length; i++) {
+    var source = arguments[i];
+
+    for (var key in source) {
+      if (Object.prototype.hasOwnProperty.call(source, key)) {
+        target[key] = source[key];
+      }
+    }
+  }
+
+  return target;
+};
+
+// Determine the type of a variable/object.
+var objType = function objType(obj) {
+  var type = typeof obj === 'undefined' ? 'undefined' : _typeof(obj);
+  if (type === 'undefined') return 'undefined';else if (type === 'string' || obj instanceof String) return 'string';else if (type === 'number' || obj instanceof Number) return 'number';else if (type === 'function' || obj instanceof Function) return 'function';else if (!!obj && obj.constructor === Array) return 'array';else if (obj && obj.nodeType === 1) return 'element';else if (type === 'object') return 'object';else return 'unknown';
+};
+
+// Create an HTML element with optional className, innerHTML, and style.
+var createElement = function createElement(tagName, opt) {
+  var el = document.createElement(tagName);
+  if (opt.className) el.className = opt.className;
+  if (opt.innerHTML) {
+    el.innerHTML = opt.innerHTML;
+    var scripts = el.getElementsByTagName('script');
+    for (var i = scripts.length; i-- > 0; null) {
+      scripts[i].parentNode.removeChild(scripts[i]);
+    }
+  }
+  for (var key in opt.style) {
+    el.style[key] = opt.style[key];
+  }
+  return el;
+};
+
+// Deep-clone a node and preserve contents/properties.
+var cloneNode = function cloneNode(node, javascriptEnabled) {
+  // Recursively clone the node.
+  var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);
+  for (var child = node.firstChild; child; child = child.nextSibling) {
+    if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') {
+      clone.appendChild(cloneNode(child, javascriptEnabled));
+    }
+  }
+
+  if (node.nodeType === 1) {
+    // Preserve contents/properties of special nodes.
+    if (node.nodeName === 'CANVAS') {
+      clone.width = node.width;
+      clone.height = node.height;
+      clone.getContext('2d').drawImage(node, 0, 0);
+    } else if (node.nodeName === 'TEXTAREA' || node.nodeName === 'SELECT') {
+      clone.value = node.value;
+    }
+
+    // Preserve the node's scroll position when it loads.
+    clone.addEventListener('load', function () {
+      clone.scrollTop = node.scrollTop;
+      clone.scrollLeft = node.scrollLeft;
+    }, true);
+  }
+
+  // Return the cloned node.
+  return clone;
+};
+
+// Convert units using the conversion value 'k' from jsPDF.
+var unitConvert = function unitConvert(obj, k) {
+  var newObj = {};
+  for (var key in obj) {
+    newObj[key] = obj[key] * 72 / 96 / k;
+  }
+  return newObj;
+};
+
+/* ----- CONSTRUCTOR ----- */
+
+var Worker = function Worker(opt) {
+  // Create the root parent for the proto chain, and the starting Worker.
+  var root = _extends(Worker.convert(Promise.resolve()), JSON.parse(JSON.stringify(Worker.template)));
+  var self = Worker.convert(Promise.resolve(), root);
+
+  // Set progress, optional settings, and return.
+  self = self.setProgress(1, Worker, 1, [Worker]);
+  self = self.set(opt);
+  return self;
+};
+
+// Boilerplate for subclassing Promise.
+Worker.prototype = Object.create(Promise.prototype);
+Worker.prototype.constructor = Worker;
+
+// Converts/casts promises into Workers.
+Worker.convert = function convert(promise, inherit) {
+  // Uses prototypal inheritance to receive changes made to ancestors' properties.
+  promise.__proto__ = inherit || Worker.prototype;
+  return promise;
+};
+
+Worker.template = {
+  prop: {
+    src: null,
+    container: null,
+    overlay: null,
+    canvas: null,
+    img: null,
+    pdf: null,
+    pageSize: null
+  },
+  progress: {
+    val: 0,
+    state: null,
+    n: 0,
+    stack: []
+  },
+  opt: {
+    filename: 'file.pdf',
+    margin: [0, 0, 0, 0],
+    image: { type: 'jpeg', quality: 0.95 },
+    enableLinks: true,
+    html2canvas: {},
+    jsPDF: {}
+  }
+};
+
+/* ----- FROM / TO ----- */
+
+Worker.prototype.from = function from(src, type) {
+  function getType(src) {
+    switch (objType(src)) {
+      case 'string':
+        return 'string';
+      case 'element':
+        return src.nodeName.toLowerCase === 'canvas' ? 'canvas' : 'element';
+      default:
+        return 'unknown';
+    }
+  }
+
+  return this.then(function from_main() {
+    type = type || getType(src);
+    switch (type) {
+      case 'string':
+        return this.set({ src: createElement('div', { innerHTML: src }) });
+      case 'element':
+        return this.set({ src: src });
+      case 'canvas':
+        return this.set({ canvas: src });
+      case 'img':
+        return this.set({ img: src });
+      default:
+        return this.error('Unknown source type.');
+    }
+  });
+};
+
+Worker.prototype.to = function to(target) {
+  // Route the 'to' request to the appropriate method.
+  switch (target) {
+    case 'container':
+      return this.toContainer();
+    case 'canvas':
+      return this.toCanvas();
+    case 'img':
+      return this.toImg();
+    case 'pdf':
+      return this.toPdf();
+    default:
+      return this.error('Invalid target.');
+  }
+};
+
+Worker.prototype.toContainer = function toContainer() {
+  // Set up function prerequisites.
+  var prereqs = [function checkSrc() {
+    return this.prop.src || this.error('Cannot duplicate - no source HTML.');
+  }, function checkPageSize() {
+    return this.prop.pageSize || this.setPageSize();
+  }];
+
+  return this.thenList(prereqs).then(function toContainer_main() {
+    // Define the CSS styles for the container and its overlay parent.
+    var overlayCSS = {
+      position: 'fixed', overflow: 'hidden', zIndex: 1000,
+      left: 0, right: 0, bottom: 0, top: 0,
+      backgroundColor: 'rgba(0,0,0,0.8)'
+    };
+    var containerCSS = {
+      position: 'absolute', width: this.prop.pageSize.inner.width + this.prop.pageSize.unit,
+      left: 0, right: 0, top: 0, height: 'auto', margin: 'auto',
+      backgroundColor: 'white'
+    };
+
+    // Set the overlay to hidden (could be changed in the future to provide a print preview).
+    overlayCSS.opacity = 0;
+
+    // Create and attach the elements.
+    var source = cloneNode(this.prop.src, this.opt.html2canvas.javascriptEnabled);
+    this.prop.overlay = createElement('div', { className: 'html2pdf__overlay', style: overlayCSS });
+    this.prop.container = createElement('div', { className: 'html2pdf__container', style: containerCSS });
+    this.prop.container.appendChild(source);
+    this.prop.overlay.appendChild(this.prop.container);
+    document.body.appendChild(this.prop.overlay);
+  });
+};
+
+Worker.prototype.toCanvas = function toCanvas() {
+  // Set up function prerequisites.
+  var prereqs = [function checkContainer() {
+    return document.body.contains(this.prop.container) || this.toContainer();
+  }];
+
+  // Fulfill prereqs then create the canvas.
+  return this.thenList(prereqs).then(function toCanvas_main() {
+    // Handle old-fashioned 'onrendered' argument.
+    var options = _extends({}, this.opt.html2canvas);
+    delete options.onrendered;
+
+    return html2canvas(this.prop.container, options);
+  }).then(function toCanvas_post(canvas) {
+    // Handle old-fashioned 'onrendered' argument.
+    var onRendered = this.opt.html2canvas.onrendered || function () {};
+    onRendered(canvas);
+
+    this.prop.canvas = canvas;
+    document.body.removeChild(this.prop.overlay);
+  });
+};
+
+Worker.prototype.toImg = function toImg() {
+  // Set up function prerequisites.
+  var prereqs = [function checkCanvas() {
+    return this.prop.canvas || this.toCanvas();
+  }];
+
+  // Fulfill prereqs then create the image.
+  return this.thenList(prereqs).then(function toImg_main() {
+    var imgData = this.prop.canvas.toDataURL('image/' + this.opt.image.type, this.opt.image.quality);
+    this.prop.img = document.createElement('img');
+    this.prop.img.src = imgData;
+  });
+};
+
+Worker.prototype.toPdf = function toPdf() {
+  // Set up function prerequisites.
+  var prereqs = [function checkCanvas() {
+    return this.prop.canvas || this.toCanvas();
+  }];
+
+  // Fulfill prereqs then create the image.
+  return this.thenList(prereqs).then(function toPdf_main() {
+    // Create local copies of frequently used properties.
+    var canvas = this.prop.canvas;
+    var opt = this.opt;
+
+    // Calculate the number of pages.
+    var ctx = canvas.getContext('2d');
+    var pxFullHeight = canvas.height;
+    var pxPageHeight = Math.floor(canvas.width * this.prop.pageSize.inner.ratio);
+    var nPages = Math.ceil(pxFullHeight / pxPageHeight);
+
+    // Define pageHeight separately so it can be trimmed on the final page.
+    var pageHeight = this.prop.pageSize.inner.height;
+
+    // Create a one-page canvas to split up the full image.
+    var pageCanvas = document.createElement('canvas');
+    var pageCtx = pageCanvas.getContext('2d');
+    pageCanvas.width = canvas.width;
+    pageCanvas.height = pxPageHeight;
+
+    // Initialize the PDF.
+    this.prop.pdf = this.prop.pdf || new jsPDF(opt.jsPDF);
+
+    for (var page = 0; page < nPages; page++) {
+      // Trim the final page to reduce file size.
+      if (page === nPages - 1) {
+        pageCanvas.height = pxFullHeight % pxPageHeight;
+        pageHeight = pageCanvas.height * this.prop.pageSize.inner.width / pageCanvas.width;
+      }
+
+      // Display the page.
+      var w = pageCanvas.width;
+      var h = pageCanvas.height;
+      pageCtx.fillStyle = 'white';
+      pageCtx.fillRect(0, 0, w, h);
+      pageCtx.drawImage(canvas, 0, page * pxPageHeight, w, h, 0, 0, w, h);
+
+      // Add the page to the PDF.
+      if (page) this.prop.pdf.addPage();
+      var imgData = pageCanvas.toDataURL('image/' + opt.image.type, opt.image.quality);
+      this.prop.pdf.addImage(imgData, opt.image.type, opt.margin[1], opt.margin[0], this.prop.pageSize.inner.width, pageHeight);
+    }
+  });
+};
+
+/* ----- OUTPUT / SAVE ----- */
+
+Worker.prototype.output = function output(type, options, src) {
+  // Redirect requests to the correct function (outputPdf / outputImg).
+  src = src || 'pdf';
+  if (src.toLowerCase() === 'img' || src.toLowerCase() === 'image') {
+    return this.outputImg(type, options);
+  } else {
+    return this.outputPdf(type, options);
+  }
+};
+
+Worker.prototype.outputPdf = function outputPdf(type, options) {
+  // Set up function prerequisites.
+  var prereqs = [function checkPdf() {
+    return this.prop.pdf || this.toPdf();
+  }];
+
+  // Fulfill prereqs then perform the appropriate output.
+  return this.thenList(prereqs).then(function outputPdf_main() {
+    /* Currently implemented output types:
+     *    https://rawgit.com/MrRio/jsPDF/master/docs/jspdf.js.html#line992
+     *  save(options), arraybuffer, blob, bloburi/bloburl,
+     *  datauristring/dataurlstring, dataurlnewwindow, datauri/dataurl
+     */
+    return this.prop.pdf.output(type, options);
+  });
+};
+
+Worker.prototype.outputImg = function outputImg(type, options) {
+  // Set up function prerequisites.
+  var prereqs = [function checkImg() {
+    return this.prop.img || this.toImg();
+  }];
+
+  // Fulfill prereqs then perform the appropriate output.
+  return this.thenList(prereqs).then(function outputImg_main() {
+    switch (type) {
+      case undefined:
+      case 'img':
+        return this.prop.img;
+      case 'datauristring':
+      case 'dataurlstring':
+        return this.prop.img.src;
+      case 'datauri':
+      case 'dataurl':
+        return document.location.href = this.prop.img.src;
+      default:
+        throw 'Image output type "' + type + '" is not supported.';
+    }
+  });
+};
+
+Worker.prototype.save = function save(filename) {
+  // Set up function prerequisites.
+  var prereqs = [function checkPdf() {
+    return this.prop.pdf || this.toPdf();
+  }];
+
+  // Fulfill prereqs, update the filename (if provided), and save the PDF.
+  return this.thenList(prereqs).set(filename ? { filename: filename } : null).then(function save_main() {
+    this.prop.pdf.save(this.opt.filename);
+  });
+};
+
+/* ----- SET / GET ----- */
+
+Worker.prototype.set = function set$$1(opt) {
+  // TODO: Implement ordered pairs?
+
+  // Silently ignore invalid or empty input.
+  if (objType(opt) !== 'object') {
+    return this;
+  }
+
+  // Build an array of setter functions to queue.
+  var fns = Object.keys(opt || {}).map(function (key) {
+    if (key in Worker.template.prop) {
+      // Set pre-defined properties.
+      return function set_prop() {
+        this.prop[key] = opt[key];
+      };
+    } else {
+      switch (key) {
+        case 'margin':
+          return this.setMargin.bind(this, opt.margin);
+        case 'jsPDF':
+          return function set_jsPDF() {
+            this.opt.jsPDF = opt.jsPDF;return this.setPageSize();
+          };
+        case 'pageSize':
+          return this.setPageSize.bind(this, opt.pageSize);
+        default:
+          // Set any other properties in opt.
+          return function set_opt() {
+            this.opt[key] = opt[key];
+          };
+      }
+    }
+  }, this);
+
+  // Set properties within the promise chain.
+  return this.then(function set_main() {
+    return this.thenList(fns);
+  });
+};
+
+Worker.prototype.get = function get$$1(key, cbk) {
+  return this.then(function get_main() {
+    // Fetch the requested property, either as a predefined prop or in opt.
+    var val = key in Worker.template.prop ? this.prop[key] : this.opt[key];
+    return cbk ? cbk(val) : val;
+  });
+};
+
+Worker.prototype.setMargin = function setMargin(margin) {
+  return this.then(function setMargin_main() {
+    // Parse the margin property.
+    switch (objType(margin)) {
+      case 'number':
+        margin = [margin, margin, margin, margin];
+      case 'array':
+        if (margin.length === 2) {
+          margin = [margin[0], margin[1], margin[0], margin[1]];
+        }
+        if (margin.length === 4) {
+          break;
+        }
+      default:
+        return this.error('Invalid margin array.');
+    }
+
+    // Set the margin property, then update pageSize.
+    this.opt.margin = margin;
+  }).then(this.setPageSize);
+};
+
+Worker.prototype.setPageSize = function setPageSize(pageSize) {
+  function toPx(val, k) {
+    return Math.floor(val * k / 72 * 96);
+  }
+
+  return this.then(function setPageSize_main() {
+    // Retrieve page-size based on jsPDF settings, if not explicitly provided.
+    pageSize = pageSize || jsPDF.getPageSize(this.opt.jsPDF);
+
+    // Add 'inner' field if not present.
+    if (!pageSize.hasOwnProperty('inner')) {
+      pageSize.inner = {
+        width: pageSize.width - this.opt.margin[1] - this.opt.margin[3],
+        height: pageSize.height - this.opt.margin[0] - this.opt.margin[2]
+      };
+      pageSize.inner.px = {
+        width: toPx(pageSize.inner.width, pageSize.k),
+        height: toPx(pageSize.inner.height, pageSize.k)
+      };
+      pageSize.inner.ratio = pageSize.inner.height / pageSize.inner.width;
+    }
+
+    // Attach pageSize to this.
+    this.prop.pageSize = pageSize;
+  });
+};
+
+Worker.prototype.setProgress = function setProgress(val, state, n, stack) {
+  // Immediately update all progress values.
+  if (val != null) this.progress.val = val;
+  if (state != null) this.progress.state = state;
+  if (n != null) this.progress.n = n;
+  if (stack != null) this.progress.stack = stack;
+  this.progress.ratio = this.progress.val / this.progress.state;
+
+  // Return this for command chaining.
+  return this;
+};
+
+Worker.prototype.updateProgress = function updateProgress(val, state, n, stack) {
+  // Immediately update all progress values, using setProgress.
+  return this.setProgress(val ? this.progress.val + val : null, state ? state : null, n ? this.progress.n + n : null, stack ? this.progress.stack.concat(stack) : null);
+};
+
+/* ----- PROMISE MAPPING ----- */
+
+Worker.prototype.then = function then(onFulfilled, onRejected) {
+  // Wrap `this` for encapsulation.
+  var self = this;
+
+  return this.thenCore(onFulfilled, onRejected, function then_main(onFulfilled, onRejected) {
+    // Update progress while queuing, calling, and resolving `then`.
+    self.updateProgress(null, null, 1, [onFulfilled]);
+    return Promise.prototype.then.call(this, function then_pre(val) {
+      self.updateProgress(null, onFulfilled);
+      return val;
+    }).then(onFulfilled, onRejected).then(function then_post(val) {
+      self.updateProgress(1);
+      return val;
+    });
+  });
+};
+
+Worker.prototype.thenCore = function thenCore(onFulfilled, onRejected, thenBase) {
+  // Handle optional thenBase parameter.
+  thenBase = thenBase || Promise.prototype.then;
+
+  // Wrap `this` for encapsulation and bind it to the promise handlers.
+  var self = this;
+  if (onFulfilled) {
+    onFulfilled = onFulfilled.bind(self);
+  }
+  if (onRejected) {
+    onRejected = onRejected.bind(self);
+  }
+
+  // Cast self into a Promise to avoid polyfills recursively defining `then`.
+  var isNative = Promise.toString().indexOf('[native code]') !== -1 && Promise.name === 'Promise';
+  var selfPromise = isNative ? self : Worker.convert(_extends({}, self), Promise.prototype);
+
+  // Return the promise, after casting it into a Worker and preserving props.
+  var returnVal = thenBase.call(selfPromise, onFulfilled, onRejected);
+  return Worker.convert(returnVal, self.__proto__);
+};
+
+Worker.prototype.thenExternal = function thenExternal(onFulfilled, onRejected) {
+  // Call `then` and return a standard promise (exits the Worker chain).
+  return Promise.prototype.then.call(this, onFulfilled, onRejected);
+};
+
+Worker.prototype.thenList = function thenList(fns) {
+  // Queue a series of promise 'factories' into the promise chain.
+  var self = this;
+  fns.forEach(function thenList_forEach(fn) {
+    self = self.thenCore(fn);
+  });
+  return self;
+};
+
+Worker.prototype['catch'] = function (onRejected) {
+  // Bind `this` to the promise handler, call `catch`, and return a Worker.
+  if (onRejected) {
+    onRejected = onRejected.bind(this);
+  }
+  var returnVal = Promise.prototype['catch'].call(this, onRejected);
+  return Worker.convert(returnVal, this);
+};
+
+Worker.prototype.catchExternal = function catchExternal(onRejected) {
+  // Call `catch` and return a standard promise (exits the Worker chain).
+  return Promise.prototype['catch'].call(this, onRejected);
+};
+
+Worker.prototype.error = function error(msg) {
+  // Throw the error in the Promise chain.
+  return this.then(function error_main() {
+    throw new Error(msg);
+  });
+};
+
+/* ----- ALIASES ----- */
+
+Worker.prototype.using = Worker.prototype.set;
+Worker.prototype.saveAs = Worker.prototype.save;
+Worker.prototype.export = Worker.prototype.output;
+Worker.prototype.run = Worker.prototype.then;
+
+// Import dependencies.
+// Get dimensions of a PDF page, as determined by jsPDF.
+jsPDF.getPageSize = function (orientation, unit, format) {
+  // Decode options object
+  if ((typeof orientation === 'undefined' ? 'undefined' : _typeof(orientation)) === 'object') {
+    var options = orientation;
+    orientation = options.orientation;
+    unit = options.unit || unit;
+    format = options.format || format;
+  }
+
+  // Default options
+  unit = unit || 'mm';
+  format = format || 'a4';
+  orientation = ('' + (orientation || 'P')).toLowerCase();
+  var format_as_string = ('' + format).toLowerCase();
+
+  // Size in pt of various paper formats
+  var pageFormats = {
+    'a0': [2383.94, 3370.39], 'a1': [1683.78, 2383.94],
+    'a2': [1190.55, 1683.78], 'a3': [841.89, 1190.55],
+    'a4': [595.28, 841.89], 'a5': [419.53, 595.28],
+    'a6': [297.64, 419.53], 'a7': [209.76, 297.64],
+    'a8': [147.40, 209.76], 'a9': [104.88, 147.40],
+    'a10': [73.70, 104.88], 'b0': [2834.65, 4008.19],
+    'b1': [2004.09, 2834.65], 'b2': [1417.32, 2004.09],
+    'b3': [1000.63, 1417.32], 'b4': [708.66, 1000.63],
+    'b5': [498.90, 708.66], 'b6': [354.33, 498.90],
+    'b7': [249.45, 354.33], 'b8': [175.75, 249.45],
+    'b9': [124.72, 175.75], 'b10': [87.87, 124.72],
+    'c0': [2599.37, 3676.54], 'c1': [1836.85, 2599.37],
+    'c2': [1298.27, 1836.85], 'c3': [918.43, 1298.27],
+    'c4': [649.13, 918.43], 'c5': [459.21, 649.13],
+    'c6': [323.15, 459.21], 'c7': [229.61, 323.15],
+    'c8': [161.57, 229.61], 'c9': [113.39, 161.57],
+    'c10': [79.37, 113.39], 'dl': [311.81, 623.62],
+    'letter': [612, 792],
+    'government-letter': [576, 756],
+    'legal': [612, 1008],
+    'junior-legal': [576, 360],
+    'ledger': [1224, 792],
+    'tabloid': [792, 1224],
+    'credit-card': [153, 243]
+  };
+
+  // Unit conversion
+  switch (unit) {
+    case 'pt':
+      var k = 1;break;
+    case 'mm':
+      var k = 72 / 25.4;break;
+    case 'cm':
+      var k = 72 / 2.54;break;
+    case 'in':
+      var k = 72;break;
+    case 'px':
+      var k = 72 / 96;break;
+    case 'pc':
+      var k = 12;break;
+    case 'em':
+      var k = 12;break;
+    case 'ex':
+      var k = 6;break;
+    default:
+      throw 'Invalid unit: ' + unit;
+  }
+
+  // Dimensions are stored as user units and converted to points on output
+  if (pageFormats.hasOwnProperty(format_as_string)) {
+    var pageHeight = pageFormats[format_as_string][1] / k;
+    var pageWidth = pageFormats[format_as_string][0] / k;
+  } else {
+    try {
+      var pageHeight = format[1];
+      var pageWidth = format[0];
+    } catch (err) {
+      throw new Error('Invalid format: ' + format);
+    }
+  }
+
+  // Handle page orientation
+  if (orientation === 'p' || orientation === 'portrait') {
+    orientation = 'p';
+    if (pageWidth > pageHeight) {
+      var tmp = pageWidth;
+      pageWidth = pageHeight;
+      pageHeight = tmp;
+    }
+  } else if (orientation === 'l' || orientation === 'landscape') {
+    orientation = 'l';
+    if (pageHeight > pageWidth) {
+      var tmp = pageWidth;
+      pageWidth = pageHeight;
+      pageHeight = tmp;
+    }
+  } else {
+    throw 'Invalid orientation: ' + orientation;
+  }
+
+  // Return information (k is the unit conversion ratio from pts)
+  var info = { 'width': pageWidth, 'height': pageHeight, 'unit': unit, 'k': k };
+  return info;
+};
+
+var orig = {
+  toContainer: Worker.prototype.toContainer
+};
+
+Worker.prototype.toContainer = function toContainer() {
+  return orig.toContainer.call(this).then(function toContainer_pagebreak() {
+    // Enable page-breaks.
+    var pageBreaks = this.prop.container.querySelectorAll('.html2pdf__page-break');
+    var pxPageHeight = this.prop.pageSize.inner.px.height;
+    Array.prototype.forEach.call(pageBreaks, function pageBreak_loop(el) {
+      el.style.display = 'block';
+      var clientRect = el.getBoundingClientRect();
+      el.style.height = pxPageHeight - clientRect.top % pxPageHeight + 'px';
+    }, this);
+  });
+};
+
+// Add hyperlink functionality to the PDF creation.
+
+// Main link array, and refs to original functions.
+var linkInfo = [];
+var orig$1 = {
+  toContainer: Worker.prototype.toContainer,
+  toPdf: Worker.prototype.toPdf
+};
+
+Worker.prototype.toContainer = function toContainer() {
+  return orig$1.toContainer.call(this).then(function toContainer_hyperlink() {
+    // Retrieve hyperlink info if the option is enabled.
+    if (this.opt.enableLinks) {
+      // Find all anchor tags and get the container's bounds for reference.
+      var container = this.prop.container;
+      var links = container.querySelectorAll('a');
+      var containerRect = unitConvert(container.getBoundingClientRect(), this.prop.pageSize.k);
+      linkInfo = [];
+
+      // Loop through each anchor tag.
+      Array.prototype.forEach.call(links, function (link) {
+        // Treat each client rect as a separate link (for text-wrapping).
+        var clientRects = link.getClientRects();
+        for (var i = 0; i < clientRects.length; i++) {
+          var clientRect = unitConvert(clientRects[i], this.prop.pageSize.k);
+          clientRect.left -= containerRect.left;
+          clientRect.top -= containerRect.top;
+
+          var page = Math.floor(clientRect.top / this.prop.pageSize.inner.height) + 1;
+          var top = this.opt.margin[0] + clientRect.top % this.prop.pageSize.inner.height;
+          var left = this.opt.margin[1] + clientRect.left;
+
+          linkInfo.push({ page: page, top: top, left: left, clientRect: clientRect, link: link });
+        }
+      }, this);
+    }
+  });
+};
+
+Worker.prototype.toPdf = function toPdf() {
+  return orig$1.toPdf.call(this).then(function toPdf_hyperlink() {
+    // Add hyperlinks if the option is enabled.
+    if (this.opt.enableLinks) {
+      // Attach each anchor tag based on info from toContainer().
+      linkInfo.forEach(function (l) {
+        this.prop.pdf.setPage(l.page);
+        this.prop.pdf.link(l.left, l.top, l.clientRect.width, l.clientRect.height, { url: l.link.href });
+      }, this);
+
+      // Reset the active page of the PDF to the final page.
+      var nPages = this.prop.pdf.internal.getNumberOfPages();
+      this.prop.pdf.setPage(nPages);
+    }
+  });
+};
+
+/**
+ * Generate a PDF from an HTML element or string using html2canvas and jsPDF.
+ *
+ * @param {Element|string} source The source element or HTML string.
+ * @param {Object=} opt An object of optional settings: 'margin', 'filename',
+ *    'image' ('type' and 'quality'), and 'html2canvas' / 'jspdf', which are
+ *    sent as settings to their corresponding functions.
+ */
+var html2pdf = function html2pdf(src, opt) {
+  // Create a new worker with the given options.
+  var worker = new html2pdf.Worker(opt);
+
+  if (src) {
+    // If src is specified, perform the traditional 'simple' operation.
+    return worker.from(src).save();
+  } else {
+    // Otherwise, return the worker for new Promise-based operation.
+    return worker;
+  }
+};
+html2pdf.Worker = Worker;
+
+export default html2pdf;
diff --git a/AstuteClient2/src/assets/html2pdf.js/dist/require/html2pdf.cjs.js b/AstuteClient2/src/assets/html2pdf.js/dist/require/html2pdf.cjs.js
new file mode 100644
index 0000000..e802108
--- /dev/null
+++ b/AstuteClient2/src/assets/html2pdf.js/dist/require/html2pdf.cjs.js
@@ -0,0 +1,800 @@
+/**
+ * html2pdf.js v0.9.0
+ * Copyright (c) 2018 Erik Koopmans
+ * Released under the MIT License.
+ */
+'use strict';
+
+function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
+
+require('es6-promise/auto');
+var jsPDF = _interopDefault(require('jspdf'));
+var html2canvas = _interopDefault(require('html2canvas'));
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
+  return typeof obj;
+} : function (obj) {
+  return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+var _extends = Object.assign || function (target) {
+  for (var i = 1; i < arguments.length; i++) {
+    var source = arguments[i];
+
+    for (var key in source) {
+      if (Object.prototype.hasOwnProperty.call(source, key)) {
+        target[key] = source[key];
+      }
+    }
+  }
+
+  return target;
+};
+
+// Determine the type of a variable/object.
+var objType = function objType(obj) {
+  var type = typeof obj === 'undefined' ? 'undefined' : _typeof(obj);
+  if (type === 'undefined') return 'undefined';else if (type === 'string' || obj instanceof String) return 'string';else if (type === 'number' || obj instanceof Number) return 'number';else if (type === 'function' || obj instanceof Function) return 'function';else if (!!obj && obj.constructor === Array) return 'array';else if (obj && obj.nodeType === 1) return 'element';else if (type === 'object') return 'object';else return 'unknown';
+};
+
+// Create an HTML element with optional className, innerHTML, and style.
+var createElement = function createElement(tagName, opt) {
+  var el = document.createElement(tagName);
+  if (opt.className) el.className = opt.className;
+  if (opt.innerHTML) {
+    el.innerHTML = opt.innerHTML;
+    var scripts = el.getElementsByTagName('script');
+    for (var i = scripts.length; i-- > 0; null) {
+      scripts[i].parentNode.removeChild(scripts[i]);
+    }
+  }
+  for (var key in opt.style) {
+    el.style[key] = opt.style[key];
+  }
+  return el;
+};
+
+// Deep-clone a node and preserve contents/properties.
+var cloneNode = function cloneNode(node, javascriptEnabled) {
+  // Recursively clone the node.
+  var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);
+  for (var child = node.firstChild; child; child = child.nextSibling) {
+    if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') {
+      clone.appendChild(cloneNode(child, javascriptEnabled));
+    }
+  }
+
+  if (node.nodeType === 1) {
+    // Preserve contents/properties of special nodes.
+    if (node.nodeName === 'CANVAS') {
+      clone.width = node.width;
+      clone.height = node.height;
+      clone.getContext('2d').drawImage(node, 0, 0);
+    } else if (node.nodeName === 'TEXTAREA' || node.nodeName === 'SELECT') {
+      clone.value = node.value;
+    }
+
+    // Preserve the node's scroll position when it loads.
+    clone.addEventListener('load', function () {
+      clone.scrollTop = node.scrollTop;
+      clone.scrollLeft = node.scrollLeft;
+    }, true);
+  }
+
+  // Return the cloned node.
+  return clone;
+};
+
+// Convert units using the conversion value 'k' from jsPDF.
+var unitConvert = function unitConvert(obj, k) {
+  var newObj = {};
+  for (var key in obj) {
+    newObj[key] = obj[key] * 72 / 96 / k;
+  }
+  return newObj;
+};
+
+/* ----- CONSTRUCTOR ----- */
+
+var Worker = function Worker(opt) {
+  // Create the root parent for the proto chain, and the starting Worker.
+  var root = _extends(Worker.convert(Promise.resolve()), JSON.parse(JSON.stringify(Worker.template)));
+  var self = Worker.convert(Promise.resolve(), root);
+
+  // Set progress, optional settings, and return.
+  self = self.setProgress(1, Worker, 1, [Worker]);
+  self = self.set(opt);
+  return self;
+};
+
+// Boilerplate for subclassing Promise.
+Worker.prototype = Object.create(Promise.prototype);
+Worker.prototype.constructor = Worker;
+
+// Converts/casts promises into Workers.
+Worker.convert = function convert(promise, inherit) {
+  // Uses prototypal inheritance to receive changes made to ancestors' properties.
+  promise.__proto__ = inherit || Worker.prototype;
+  return promise;
+};
+
+Worker.template = {
+  prop: {
+    src: null,
+    container: null,
+    overlay: null,
+    canvas: null,
+    img: null,
+    pdf: null,
+    pageSize: null
+  },
+  progress: {
+    val: 0,
+    state: null,
+    n: 0,
+    stack: []
+  },
+  opt: {
+    filename: 'file.pdf',
+    margin: [0, 0, 0, 0],
+    image: { type: 'jpeg', quality: 0.95 },
+    enableLinks: true,
+    html2canvas: {},
+    jsPDF: {}
+  }
+};
+
+/* ----- FROM / TO ----- */
+
+Worker.prototype.from = function from(src, type) {
+  function getType(src) {
+    switch (objType(src)) {
+      case 'string':
+        return 'string';
+      case 'element':
+        return src.nodeName.toLowerCase === 'canvas' ? 'canvas' : 'element';
+      default:
+        return 'unknown';
+    }
+  }
+
+  return this.then(function from_main() {
+    type = type || getType(src);
+    switch (type) {
+      case 'string':
+        return this.set({ src: createElement('div', { innerHTML: src }) });
+      case 'element':
+        return this.set({ src: src });
+      case 'canvas':
+        return this.set({ canvas: src });
+      case 'img':
+        return this.set({ img: src });
+      default:
+        return this.error('Unknown source type.');
+    }
+  });
+};
+
+Worker.prototype.to = function to(target) {
+  // Route the 'to' request to the appropriate method.
+  switch (target) {
+    case 'container':
+      return this.toContainer();
+    case 'canvas':
+      return this.toCanvas();
+    case 'img':
+      return this.toImg();
+    case 'pdf':
+      return this.toPdf();
+    default:
+      return this.error('Invalid target.');
+  }
+};
+
+Worker.prototype.toContainer = function toContainer() {
+  // Set up function prerequisites.
+  var prereqs = [function checkSrc() {
+    return this.prop.src || this.error('Cannot duplicate - no source HTML.');
+  }, function checkPageSize() {
+    return this.prop.pageSize || this.setPageSize();
+  }];
+
+  return this.thenList(prereqs).then(function toContainer_main() {
+    // Define the CSS styles for the container and its overlay parent.
+    var overlayCSS = {
+      position: 'fixed', overflow: 'hidden', zIndex: 1000,
+      left: 0, right: 0, bottom: 0, top: 0,
+      backgroundColor: 'rgba(0,0,0,0.8)'
+    };
+    var containerCSS = {
+      position: 'absolute', width: this.prop.pageSize.inner.width + this.prop.pageSize.unit,
+      left: 0, right: 0, top: 0, height: 'auto', margin: 'auto',
+      backgroundColor: 'white'
+    };
+
+    // Set the overlay to hidden (could be changed in the future to provide a print preview).
+    overlayCSS.opacity = 0;
+
+    // Create and attach the elements.
+    var source = cloneNode(this.prop.src, this.opt.html2canvas.javascriptEnabled);
+    this.prop.overlay = createElement('div', { className: 'html2pdf__overlay', style: overlayCSS });
+    this.prop.container = createElement('div', { className: 'html2pdf__container', style: containerCSS });
+    this.prop.container.appendChild(source);
+    this.prop.overlay.appendChild(this.prop.container);
+    document.body.appendChild(this.prop.overlay);
+  });
+};
+
+Worker.prototype.toCanvas = function toCanvas() {
+  // Set up function prerequisites.
+  var prereqs = [function checkContainer() {
+    return document.body.contains(this.prop.container) || this.toContainer();
+  }];
+
+  // Fulfill prereqs then create the canvas.
+  return this.thenList(prereqs).then(function toCanvas_main() {
+    // Handle old-fashioned 'onrendered' argument.
+    var options = _extends({}, this.opt.html2canvas);
+    delete options.onrendered;
+
+    return html2canvas(this.prop.container, options);
+  }).then(function toCanvas_post(canvas) {
+    // Handle old-fashioned 'onrendered' argument.
+    var onRendered = this.opt.html2canvas.onrendered || function () {};
+    onRendered(canvas);
+
+    this.prop.canvas = canvas;
+    document.body.removeChild(this.prop.overlay);
+  });
+};
+
+Worker.prototype.toImg = function toImg() {
+  // Set up function prerequisites.
+  var prereqs = [function checkCanvas() {
+    return this.prop.canvas || this.toCanvas();
+  }];
+
+  // Fulfill prereqs then create the image.
+  return this.thenList(prereqs).then(function toImg_main() {
+    var imgData = this.prop.canvas.toDataURL('image/' + this.opt.image.type, this.opt.image.quality);
+    this.prop.img = document.createElement('img');
+    this.prop.img.src = imgData;
+  });
+};
+
+Worker.prototype.toPdf = function toPdf() {
+  // Set up function prerequisites.
+  var prereqs = [function checkCanvas() {
+    return this.prop.canvas || this.toCanvas();
+  }];
+
+  // Fulfill prereqs then create the image.
+  return this.thenList(prereqs).then(function toPdf_main() {
+    // Create local copies of frequently used properties.
+    var canvas = this.prop.canvas;
+    var opt = this.opt;
+
+    // Calculate the number of pages.
+    var ctx = canvas.getContext('2d');
+    var pxFullHeight = canvas.height;
+    var pxPageHeight = Math.floor(canvas.width * this.prop.pageSize.inner.ratio);
+    var nPages = Math.ceil(pxFullHeight / pxPageHeight);
+
+    // Define pageHeight separately so it can be trimmed on the final page.
+    var pageHeight = this.prop.pageSize.inner.height;
+
+    // Create a one-page canvas to split up the full image.
+    var pageCanvas = document.createElement('canvas');
+    var pageCtx = pageCanvas.getContext('2d');
+    pageCanvas.width = canvas.width;
+    pageCanvas.height = pxPageHeight;
+
+    // Initialize the PDF.
+    this.prop.pdf = this.prop.pdf || new jsPDF(opt.jsPDF);
+
+    for (var page = 0; page < nPages; page++) {
+      // Trim the final page to reduce file size.
+      if (page === nPages - 1) {
+        pageCanvas.height = pxFullHeight % pxPageHeight;
+        pageHeight = pageCanvas.height * this.prop.pageSize.inner.width / pageCanvas.width;
+      }
+
+      // Display the page.
+      var w = pageCanvas.width;
+      var h = pageCanvas.height;
+      pageCtx.fillStyle = 'white';
+      pageCtx.fillRect(0, 0, w, h);
+      pageCtx.drawImage(canvas, 0, page * pxPageHeight, w, h, 0, 0, w, h);
+
+      // Add the page to the PDF.
+      if (page) this.prop.pdf.addPage();
+      var imgData = pageCanvas.toDataURL('image/' + opt.image.type, opt.image.quality);
+      this.prop.pdf.addImage(imgData, opt.image.type, opt.margin[1], opt.margin[0], this.prop.pageSize.inner.width, pageHeight);
+    }
+  });
+};
+
+/* ----- OUTPUT / SAVE ----- */
+
+Worker.prototype.output = function output(type, options, src) {
+  // Redirect requests to the correct function (outputPdf / outputImg).
+  src = src || 'pdf';
+  if (src.toLowerCase() === 'img' || src.toLowerCase() === 'image') {
+    return this.outputImg(type, options);
+  } else {
+    return this.outputPdf(type, options);
+  }
+};
+
+Worker.prototype.outputPdf = function outputPdf(type, options) {
+  // Set up function prerequisites.
+  var prereqs = [function checkPdf() {
+    return this.prop.pdf || this.toPdf();
+  }];
+
+  // Fulfill prereqs then perform the appropriate output.
+  return this.thenList(prereqs).then(function outputPdf_main() {
+    /* Currently implemented output types:
+     *    https://rawgit.com/MrRio/jsPDF/master/docs/jspdf.js.html#line992
+     *  save(options), arraybuffer, blob, bloburi/bloburl,
+     *  datauristring/dataurlstring, dataurlnewwindow, datauri/dataurl
+     */
+    return this.prop.pdf.output(type, options);
+  });
+};
+
+Worker.prototype.outputImg = function outputImg(type, options) {
+  // Set up function prerequisites.
+  var prereqs = [function checkImg() {
+    return this.prop.img || this.toImg();
+  }];
+
+  // Fulfill prereqs then perform the appropriate output.
+  return this.thenList(prereqs).then(function outputImg_main() {
+    switch (type) {
+      case undefined:
+      case 'img':
+        return this.prop.img;
+      case 'datauristring':
+      case 'dataurlstring':
+        return this.prop.img.src;
+      case 'datauri':
+      case 'dataurl':
+        return document.location.href = this.prop.img.src;
+      default:
+        throw 'Image output type "' + type + '" is not supported.';
+    }
+  });
+};
+
+Worker.prototype.save = function save(filename) {
+  // Set up function prerequisites.
+  var prereqs = [function checkPdf() {
+    return this.prop.pdf || this.toPdf();
+  }];
+
+  // Fulfill prereqs, update the filename (if provided), and save the PDF.
+  return this.thenList(prereqs).set(filename ? { filename: filename } : null).then(function save_main() {
+    this.prop.pdf.save(this.opt.filename);
+  });
+};
+
+/* ----- SET / GET ----- */
+
+Worker.prototype.set = function set$$1(opt) {
+  // TODO: Implement ordered pairs?
+
+  // Silently ignore invalid or empty input.
+  if (objType(opt) !== 'object') {
+    return this;
+  }
+
+  // Build an array of setter functions to queue.
+  var fns = Object.keys(opt || {}).map(function (key) {
+    if (key in Worker.template.prop) {
+      // Set pre-defined properties.
+      return function set_prop() {
+        this.prop[key] = opt[key];
+      };
+    } else {
+      switch (key) {
+        case 'margin':
+          return this.setMargin.bind(this, opt.margin);
+        case 'jsPDF':
+          return function set_jsPDF() {
+            this.opt.jsPDF = opt.jsPDF;return this.setPageSize();
+          };
+        case 'pageSize':
+          return this.setPageSize.bind(this, opt.pageSize);
+        default:
+          // Set any other properties in opt.
+          return function set_opt() {
+            this.opt[key] = opt[key];
+          };
+      }
+    }
+  }, this);
+
+  // Set properties within the promise chain.
+  return this.then(function set_main() {
+    return this.thenList(fns);
+  });
+};
+
+Worker.prototype.get = function get$$1(key, cbk) {
+  return this.then(function get_main() {
+    // Fetch the requested property, either as a predefined prop or in opt.
+    var val = key in Worker.template.prop ? this.prop[key] : this.opt[key];
+    return cbk ? cbk(val) : val;
+  });
+};
+
+Worker.prototype.setMargin = function setMargin(margin) {
+  return this.then(function setMargin_main() {
+    // Parse the margin property.
+    switch (objType(margin)) {
+      case 'number':
+        margin = [margin, margin, margin, margin];
+      case 'array':
+        if (margin.length === 2) {
+          margin = [margin[0], margin[1], margin[0], margin[1]];
+        }
+        if (margin.length === 4) {
+          break;
+        }
+      default:
+        return this.error('Invalid margin array.');
+    }
+
+    // Set the margin property, then update pageSize.
+    this.opt.margin = margin;
+  }).then(this.setPageSize);
+};
+
+Worker.prototype.setPageSize = function setPageSize(pageSize) {
+  function toPx(val, k) {
+    return Math.floor(val * k / 72 * 96);
+  }
+
+  return this.then(function setPageSize_main() {
+    // Retrieve page-size based on jsPDF settings, if not explicitly provided.
+    pageSize = pageSize || jsPDF.getPageSize(this.opt.jsPDF);
+
+    // Add 'inner' field if not present.
+    if (!pageSize.hasOwnProperty('inner')) {
+      pageSize.inner = {
+        width: pageSize.width - this.opt.margin[1] - this.opt.margin[3],
+        height: pageSize.height - this.opt.margin[0] - this.opt.margin[2]
+      };
+      pageSize.inner.px = {
+        width: toPx(pageSize.inner.width, pageSize.k),
+        height: toPx(pageSize.inner.height, pageSize.k)
+      };
+      pageSize.inner.ratio = pageSize.inner.height / pageSize.inner.width;
+    }
+
+    // Attach pageSize to this.
+    this.prop.pageSize = pageSize;
+  });
+};
+
+Worker.prototype.setProgress = function setProgress(val, state, n, stack) {
+  // Immediately update all progress values.
+  if (val != null) this.progress.val = val;
+  if (state != null) this.progress.state = state;
+  if (n != null) this.progress.n = n;
+  if (stack != null) this.progress.stack = stack;
+  this.progress.ratio = this.progress.val / this.progress.state;
+
+  // Return this for command chaining.
+  return this;
+};
+
+Worker.prototype.updateProgress = function updateProgress(val, state, n, stack) {
+  // Immediately update all progress values, using setProgress.
+  return this.setProgress(val ? this.progress.val + val : null, state ? state : null, n ? this.progress.n + n : null, stack ? this.progress.stack.concat(stack) : null);
+};
+
+/* ----- PROMISE MAPPING ----- */
+
+Worker.prototype.then = function then(onFulfilled, onRejected) {
+  // Wrap `this` for encapsulation.
+  var self = this;
+
+  return this.thenCore(onFulfilled, onRejected, function then_main(onFulfilled, onRejected) {
+    // Update progress while queuing, calling, and resolving `then`.
+    self.updateProgress(null, null, 1, [onFulfilled]);
+    return Promise.prototype.then.call(this, function then_pre(val) {
+      self.updateProgress(null, onFulfilled);
+      return val;
+    }).then(onFulfilled, onRejected).then(function then_post(val) {
+      self.updateProgress(1);
+      return val;
+    });
+  });
+};
+
+Worker.prototype.thenCore = function thenCore(onFulfilled, onRejected, thenBase) {
+  // Handle optional thenBase parameter.
+  thenBase = thenBase || Promise.prototype.then;
+
+  // Wrap `this` for encapsulation and bind it to the promise handlers.
+  var self = this;
+  if (onFulfilled) {
+    onFulfilled = onFulfilled.bind(self);
+  }
+  if (onRejected) {
+    onRejected = onRejected.bind(self);
+  }
+
+  // Cast self into a Promise to avoid polyfills recursively defining `then`.
+  var isNative = Promise.toString().indexOf('[native code]') !== -1 && Promise.name === 'Promise';
+  var selfPromise = isNative ? self : Worker.convert(_extends({}, self), Promise.prototype);
+
+  // Return the promise, after casting it into a Worker and preserving props.
+  var returnVal = thenBase.call(selfPromise, onFulfilled, onRejected);
+  return Worker.convert(returnVal, self.__proto__);
+};
+
+Worker.prototype.thenExternal = function thenExternal(onFulfilled, onRejected) {
+  // Call `then` and return a standard promise (exits the Worker chain).
+  return Promise.prototype.then.call(this, onFulfilled, onRejected);
+};
+
+Worker.prototype.thenList = function thenList(fns) {
+  // Queue a series of promise 'factories' into the promise chain.
+  var self = this;
+  fns.forEach(function thenList_forEach(fn) {
+    self = self.thenCore(fn);
+  });
+  return self;
+};
+
+Worker.prototype['catch'] = function (onRejected) {
+  // Bind `this` to the promise handler, call `catch`, and return a Worker.
+  if (onRejected) {
+    onRejected = onRejected.bind(this);
+  }
+  var returnVal = Promise.prototype['catch'].call(this, onRejected);
+  return Worker.convert(returnVal, this);
+};
+
+Worker.prototype.catchExternal = function catchExternal(onRejected) {
+  // Call `catch` and return a standard promise (exits the Worker chain).
+  return Promise.prototype['catch'].call(this, onRejected);
+};
+
+Worker.prototype.error = function error(msg) {
+  // Throw the error in the Promise chain.
+  return this.then(function error_main() {
+    throw new Error(msg);
+  });
+};
+
+/* ----- ALIASES ----- */
+
+Worker.prototype.using = Worker.prototype.set;
+Worker.prototype.saveAs = Worker.prototype.save;
+Worker.prototype.export = Worker.prototype.output;
+Worker.prototype.run = Worker.prototype.then;
+
+// Import dependencies.
+// Get dimensions of a PDF page, as determined by jsPDF.
+jsPDF.getPageSize = function (orientation, unit, format) {
+  // Decode options object
+  if ((typeof orientation === 'undefined' ? 'undefined' : _typeof(orientation)) === 'object') {
+    var options = orientation;
+    orientation = options.orientation;
+    unit = options.unit || unit;
+    format = options.format || format;
+  }
+
+  // Default options
+  unit = unit || 'mm';
+  format = format || 'a4';
+  orientation = ('' + (orientation || 'P')).toLowerCase();
+  var format_as_string = ('' + format).toLowerCase();
+
+  // Size in pt of various paper formats
+  var pageFormats = {
+    'a0': [2383.94, 3370.39], 'a1': [1683.78, 2383.94],
+    'a2': [1190.55, 1683.78], 'a3': [841.89, 1190.55],
+    'a4': [595.28, 841.89], 'a5': [419.53, 595.28],
+    'a6': [297.64, 419.53], 'a7': [209.76, 297.64],
+    'a8': [147.40, 209.76], 'a9': [104.88, 147.40],
+    'a10': [73.70, 104.88], 'b0': [2834.65, 4008.19],
+    'b1': [2004.09, 2834.65], 'b2': [1417.32, 2004.09],
+    'b3': [1000.63, 1417.32], 'b4': [708.66, 1000.63],
+    'b5': [498.90, 708.66], 'b6': [354.33, 498.90],
+    'b7': [249.45, 354.33], 'b8': [175.75, 249.45],
+    'b9': [124.72, 175.75], 'b10': [87.87, 124.72],
+    'c0': [2599.37, 3676.54], 'c1': [1836.85, 2599.37],
+    'c2': [1298.27, 1836.85], 'c3': [918.43, 1298.27],
+    'c4': [649.13, 918.43], 'c5': [459.21, 649.13],
+    'c6': [323.15, 459.21], 'c7': [229.61, 323.15],
+    'c8': [161.57, 229.61], 'c9': [113.39, 161.57],
+    'c10': [79.37, 113.39], 'dl': [311.81, 623.62],
+    'letter': [612, 792],
+    'government-letter': [576, 756],
+    'legal': [612, 1008],
+    'junior-legal': [576, 360],
+    'ledger': [1224, 792],
+    'tabloid': [792, 1224],
+    'credit-card': [153, 243]
+  };
+
+  // Unit conversion
+  switch (unit) {
+    case 'pt':
+      var k = 1;break;
+    case 'mm':
+      var k = 72 / 25.4;break;
+    case 'cm':
+      var k = 72 / 2.54;break;
+    case 'in':
+      var k = 72;break;
+    case 'px':
+      var k = 72 / 96;break;
+    case 'pc':
+      var k = 12;break;
+    case 'em':
+      var k = 12;break;
+    case 'ex':
+      var k = 6;break;
+    default:
+      throw 'Invalid unit: ' + unit;
+  }
+
+  // Dimensions are stored as user units and converted to points on output
+  if (pageFormats.hasOwnProperty(format_as_string)) {
+    var pageHeight = pageFormats[format_as_string][1] / k;
+    var pageWidth = pageFormats[format_as_string][0] / k;
+  } else {
+    try {
+      var pageHeight = format[1];
+      var pageWidth = format[0];
+    } catch (err) {
+      throw new Error('Invalid format: ' + format);
+    }
+  }
+
+  // Handle page orientation
+  if (orientation === 'p' || orientation === 'portrait') {
+    orientation = 'p';
+    if (pageWidth > pageHeight) {
+      var tmp = pageWidth;
+      pageWidth = pageHeight;
+      pageHeight = tmp;
+    }
+  } else if (orientation === 'l' || orientation === 'landscape') {
+    orientation = 'l';
+    if (pageHeight > pageWidth) {
+      var tmp = pageWidth;
+      pageWidth = pageHeight;
+      pageHeight = tmp;
+    }
+  } else {
+    throw 'Invalid orientation: ' + orientation;
+  }
+
+  // Return information (k is the unit conversion ratio from pts)
+  var info = { 'width': pageWidth, 'height': pageHeight, 'unit': unit, 'k': k };
+  return info;
+};
+
+var orig = {
+  toContainer: Worker.prototype.toContainer
+};
+
+Worker.prototype.toContainer = function toContainer() {
+  return orig.toContainer.call(this).then(function toContainer_pagebreak() {
+    // Enable page-breaks.
+    var pageBreaks = this.prop.container.querySelectorAll('.html2pdf__page-break');
+    var pxPageHeight = this.prop.pageSize.inner.px.height;
+    Array.prototype.forEach.call(pageBreaks, function pageBreak_loop(el) {
+      el.style.display = 'block';
+      var clientRect = el.getBoundingClientRect();
+      el.style.height = pxPageHeight - clientRect.top % pxPageHeight + 'px';
+    }, this);
+  });
+};
+
+// Add hyperlink functionality to the PDF creation.
+
+// Main link array, and refs to original functions.
+var linkInfo = [];
+var orig$1 = {
+  toContainer: Worker.prototype.toContainer,
+  toPdf: Worker.prototype.toPdf
+};
+
+Worker.prototype.toContainer = function toContainer() {
+  return orig$1.toContainer.call(this).then(function toContainer_hyperlink() {
+    // Retrieve hyperlink info if the option is enabled.
+    if (this.opt.enableLinks) {
+      // Find all anchor tags and get the container's bounds for reference.
+      var container = this.prop.container;
+      var links = container.querySelectorAll('a');
+      var containerRect = unitConvert(container.getBoundingClientRect(), this.prop.pageSize.k);
+      linkInfo = [];
+
+      // Loop through each anchor tag.
+      Array.prototype.forEach.call(links, function (link) {
+        // Treat each client rect as a separate link (for text-wrapping).
+        var clientRects = link.getClientRects();
+        for (var i = 0; i < clientRects.length; i++) {
+          var clientRect = unitConvert(clientRects[i], this.prop.pageSize.k);
+          clientRect.left -= containerRect.left;
+          clientRect.top -= containerRect.top;
+
+          var page = Math.floor(clientRect.top / this.prop.pageSize.inner.height) + 1;
+          var top = this.opt.margin[0] + clientRect.top % this.prop.pageSize.inner.height;
+          var left = this.opt.margin[1] + clientRect.left;
+
+          linkInfo.push({ page: page, top: top, left: left, clientRect: clientRect, link: link });
+        }
+      }, this);
+    }
+  });
+};
+
+Worker.prototype.toPdf = function toPdf() {
+  return orig$1.toPdf.call(this).then(function toPdf_hyperlink() {
+    // Add hyperlinks if the option is enabled.
+    if (this.opt.enableLinks) {
+      // Attach each anchor tag based on info from toContainer().
+      linkInfo.forEach(function (l) {
+        this.prop.pdf.setPage(l.page);
+        this.prop.pdf.link(l.left, l.top, l.clientRect.width, l.clientRect.height, { url: l.link.href });
+      }, this);
+
+      // Reset the active page of the PDF to the final page.
+      var nPages = this.prop.pdf.internal.getNumberOfPages();
+      this.prop.pdf.setPage(nPages);
+    }
+  });
+};
+
+/**
+ * Generate a PDF from an HTML element or string using html2canvas and jsPDF.
+ *
+ * @param {Element|string} source The source element or HTML string.
+ * @param {Object=} opt An object of optional settings: 'margin', 'filename',
+ *    'image' ('type' and 'quality'), and 'html2canvas' / 'jspdf', which are
+ *    sent as settings to their corresponding functions.
+ */
+var html2pdf = function html2pdf(src, opt) {
+  // Create a new worker with the given options.
+  var worker = new html2pdf.Worker(opt);
+
+  if (src) {
+    // If src is specified, perform the traditional 'simple' operation.
+    return worker.from(src).save();
+  } else {
+    // Otherwise, return the worker for new Promise-based operation.
+    return worker;
+  }
+};
+html2pdf.Worker = Worker;
+
+module.exports = html2pdf;
diff --git a/AstuteClient2/src/assets/html2pdf.js/gulpfile.js b/AstuteClient2/src/assets/html2pdf.js/gulpfile.js
new file mode 100644
index 0000000..392be3b
--- /dev/null
+++ b/AstuteClient2/src/assets/html2pdf.js/gulpfile.js
@@ -0,0 +1,81 @@
+// Imports.
+var gulp = require('gulp');
+var util = require('util');
+var exec = util.promisify(require('child_process').exec);
+var minimist = require('minimist');
+var fs = require('fs');
+
+// Fetch command-line arguments.
+var args = minimist(process.argv.slice(2), {
+  string: ['env', 'newversion', 'tagmessage'],
+  default: {
+    env: process.env.NODE_ENV || 'production',
+    newversion: 'patch',
+    tagmessage: ''
+  }
+});
+args.newversion = args.newversion || 'patch';
+
+/* ----- REUSABLE TASKS ----- */
+
+// Get package version from package.json.
+function getVersion() {
+  var pkg = JSON.parse(fs.readFileSync('./package.json'));
+  return 'v' + pkg.version;
+}
+
+// Merge the specified branch back into master and develop.
+function mergeBranch(branch) {
+  var mergeCmd = 'git merge --no-ff --no-edit ' + branch;
+
+  console.log('Merging release into master.')
+  return exec('git checkout master && ' + mergeCmd).then(function() {
+    console.log('Merging release into develop.')
+    return exec('git checkout develop && ' + mergeCmd);
+  });
+}
+
+/* ----- TASKS ----- */
+
+// Bump version using NPM (only affects package*.json, doesn't commit).
+gulp.task('bump-version', function() {
+  console.log('Bumping version number.');
+  return exec('npm --no-git-tag-version version ' + args.newversion);
+});
+
+// Stage a release (bump version and create a 'release/[version]' branch).
+gulp.task('stage-release', ['bump-version'], function() {
+  var version = getVersion();
+  var branch = 'release/' + version;
+  var cmd = 'git checkout -b ' + branch + ' && git add -A';
+  cmd += ' && git commit -m "Prepare release ' + version + '"';
+
+  console.log('Creating release branch and committing changes.');
+  return exec(cmd);
+});
+
+gulp.task('finalize-release', function() {
+  var version = getVersion();
+  var branch = 'release/' + version;
+  var cmd = 'git checkout ' + branch + ' && npm run build';
+
+  console.log('Running build process in release branch.');
+  return exec(cmd).then(function() {
+    console.log('Adding all changes and performing final commit.');
+    return exec('git add -A && git commit --allow-empty -m "Build ' + version + '"');
+  }).then(function() {
+    console.log('Tagging with provided tag message.');
+    return exec('git tag -a ' + version + ' -m "' + version + ' ' + args.tagmessage + '"');
+  });
+});
+
+// Tag and merge the latest release into master/develop.
+gulp.task('release', ['finalize-release'], function() {
+  var version = getVersion();
+  var branch = 'release/' + version;
+
+  return mergeBranch(branch).then(function() {
+    console.log('Deleting release branch.');
+    return exec('git branch -d ' + branch);
+  });
+});
diff --git a/AstuteClient2/src/assets/html2pdf.js/package.json b/AstuteClient2/src/assets/html2pdf.js/package.json
new file mode 100644
index 0000000..8227d32
--- /dev/null
+++ b/AstuteClient2/src/assets/html2pdf.js/package.json
@@ -0,0 +1,83 @@
+{
+  "_from": "html2pdf.js",
+  "_id": "html2pdf.js@0.9.0",
+  "_inBundle": false,
+  "_integrity": "sha512-IIhGjx0DJ2JBLSfhLn1hphJ4PWCQNnT8OnybPxEybA9+Qz3bbsrCaGXDX0rq5zLdKPCL82g2plMjgaAKUz41mw==",
+  "_location": "/html2pdf.js",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "tag",
+    "registry": true,
+    "raw": "html2pdf.js",
+    "name": "html2pdf.js",
+    "escapedName": "html2pdf.js",
+    "rawSpec": "",
+    "saveSpec": null,
+    "fetchSpec": "latest"
+  },
+  "_requiredBy": [
+    "#USER",
+    "/"
+  ],
+  "_resolved": "https://registry.npmjs.org/html2pdf.js/-/html2pdf.js-0.9.0.tgz",
+  "_shasum": "30976b096da1776f70e17c31d137a1c825a70f2a",
+  "_spec": "html2pdf.js",
+  "_where": "D:\\Documents\\Astute\\AstuteClient",
+  "author": {
+    "name": "Erik Koopmans",
+    "email": "erik@erik-koopmans.com",
+    "url": "https://www.erik-koopmans.com"
+  },
+  "browser": "dist/html2pdf.js",
+  "bugs": {
+    "url": "https://github.com/eKoopmans/html2pdf/issues"
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "es6-promise": "^4.1.1",
+    "html2canvas": "^1.0.0-alpha.12",
+    "jspdf": "^1.3.5"
+  },
+  "deprecated": false,
+  "description": "Client-side HTML-to-PDF rendering using pure JS",
+  "devDependencies": {
+    "babel-core": "^6.26.0",
+    "babel-plugin-external-helpers": "^6.22.0",
+    "babel-plugin-transform-object-assign": "^6.22.0",
+    "babel-preset-env": "^1.6.1",
+    "gulp": "^3.9.1",
+    "rimraf": "^2.6.2",
+    "rollup": "^0.51.8",
+    "rollup-plugin-babel": "^3.0.2",
+    "rollup-plugin-commonjs": "^8.2.6",
+    "rollup-plugin-node-resolve": "^3.0.0",
+    "rollup-plugin-replace": "^2.0.0",
+    "rollup-plugin-uglify": "^2.0.1"
+  },
+  "homepage": "https://github.com/eKoopmans/html2pdf",
+  "keywords": [
+    "javascript",
+    "pdf-generation",
+    "html",
+    "client-side",
+    "canvas"
+  ],
+  "license": "MIT",
+  "main": "dist/require/html2pdf.cjs.js",
+  "module": "dist/include/html2pdf.es.js",
+  "name": "html2pdf.js",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/eKoopmans/html2pdf.git"
+  },
+  "scripts": {
+    "build": "rollup -c",
+    "clean": "rimraf dist",
+    "prebuild": "npm install && npm run clean",
+    "publish": "npm publish",
+    "release": "gulp release --tagmessage",
+    "stage-release": "gulp stage-release --newversion",
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "version": "0.9.0"
+}
diff --git a/AstuteClient2/src/assets/html2pdf.js/rollup.config.js b/AstuteClient2/src/assets/html2pdf.js/rollup.config.js
new file mode 100644
index 0000000..06d3cb6
--- /dev/null
+++ b/AstuteClient2/src/assets/html2pdf.js/rollup.config.js
@@ -0,0 +1,116 @@
+// Import dependencies.
+import resolve from 'rollup-plugin-node-resolve';
+import commonjs from 'rollup-plugin-commonjs';
+import replace from 'rollup-plugin-replace';
+import babel from 'rollup-plugin-babel';
+import uglify from 'rollup-plugin-uglify';
+import pkg from './package.json';
+
+function banner() {
+  var text = pkg.name + ' v' + pkg.version + '\n';
+  text += 'Copyright (c) ' + (new Date).getFullYear() + ' Erik Koopmans\n';
+  text += 'Released under the ' + pkg.license + ' License.';
+  text = '/**\n * ' + text.replace(/\n/g, '\n * ') + '\n */';
+  return { banner: text };
+}
+function license(filename) {
+  filename = filename || './LICENSE';
+  var data = fs.readFileSync(filename).toString();
+  data = '/**\n * @license\n * ' + data.trim().replace(/\n/g, '\n * ') + '\n */\n';
+  return { banner: data };
+}
+
+export default [
+  // Un-bundled builds.
+  {
+    name: 'html2pdf',
+    input: 'src/index.js',
+    output: [
+      { file: pkg.main, format: 'cjs' },
+      { file: pkg.module, format: 'es' },
+      { file: pkg.browser, format: 'umd' }
+    ],
+    external: [
+      'jspdf',
+      'html2canvas',
+      'es6-promise/auto'
+    ],
+    globals: {
+      jspdf: 'jsPDF',
+      html2canvas: 'html2canvas'
+    },
+    plugins: [
+      resolve(),
+      commonjs(),
+      replace({ 'process.env.NODE_ENV': JSON.stringify('production') }),
+      babel({ exclude: 'node_modules/**' }),
+      banner()
+    ]
+  },
+  // Un-bundled builds (minified).
+  {
+    name: 'html2pdf',
+    input: 'src/index.js',
+    output: [
+      { file: pkg.browser.replace(/js$/, 'min.js'), format: 'umd' }
+    ],
+    external: [
+      'jspdf',
+      'html2canvas',
+      'es6-promise/auto'
+    ],
+    globals: {
+      jspdf: 'jsPDF',
+      html2canvas: 'html2canvas'
+    },
+    plugins: [
+      resolve(),
+      commonjs(),
+      replace({ 'process.env.NODE_ENV': JSON.stringify('production') }),
+      babel({ exclude: 'node_modules/**' }),
+      uglify({
+        output: { preamble: banner().banner }
+      })
+    ]
+  },
+  // Bundled builds.
+  {
+    name: 'html2pdf',
+    input: 'src/index.js',
+    output: [
+      { file: pkg.browser.replace(/js$/, 'bundle.js'), format: 'umd' }
+    ],
+    globals: {
+      jspdf: 'jsPDF',
+      html2canvas: 'html2canvas'
+    },
+    plugins: [
+      resolve(),
+      commonjs(),
+      replace({ 'process.env.NODE_ENV': JSON.stringify('production') }),
+      babel({ exclude: 'node_modules/**' }),
+      banner()
+    ]
+  },
+  // Bundled builds (minified).
+  {
+    name: 'html2pdf',
+    input: 'src/index.js',
+    output: [
+      { file: pkg.browser.replace(/js$/, 'bundle.min.js'), format: 'umd' }
+    ],
+    globals: {
+      jspdf: 'jsPDF',
+      html2canvas: 'html2canvas'
+    },
+    plugins: [
+      resolve(),
+      commonjs(),
+      replace({ 'process.env.NODE_ENV': JSON.stringify('production') }),
+      babel({ exclude: 'node_modules/**' }),
+      uglify({
+        output: { preamble: banner().banner }
+      })
+    ]
+  }
+];
diff --git a/AstuteClient2/src/assets/html2pdf.js/src/index.js b/AstuteClient2/src/assets/html2pdf.js/src/index.js
new file mode 100644
index 0000000..12a4d1a
--- /dev/null
+++ b/AstuteClient2/src/assets/html2pdf.js/src/index.js
@@ -0,0 +1,31 @@
+import 'es6-promise/auto';
+
+import Worker from './worker.js';
+import './plugin/jspdf-plugin.js';
+import './plugin/pagebreaks.js';
+import './plugin/hyperlinks.js';
+
+/**
+ * Generate a PDF from an HTML element or string using html2canvas and jsPDF.
+ *
+ * @param {Element|string} source The source element or HTML string.
+ * @param {Object=} opt An object of optional settings: 'margin', 'filename',
+ *    'image' ('type' and 'quality'), and 'html2canvas' / 'jspdf', which are
+ *    sent as settings to their corresponding functions.
+ */
+var html2pdf = function html2pdf(src, opt) {
+  // Create a new worker with the given options.
+  var worker = new html2pdf.Worker(opt);
+
+  if (src) {
+    // If src is specified, perform the traditional 'simple' operation.
+    return worker.from(src).save();
+  } else {
+    // Otherwise, return the worker for new Promise-based operation.
+    return worker;
+  }
+}
+html2pdf.Worker = Worker;
+
+// Expose the html2pdf function.
+export default html2pdf;
diff --git a/AstuteClient2/src/assets/html2pdf.js/src/plugin/hyperlinks.js b/AstuteClient2/src/assets/html2pdf.js/src/plugin/hyperlinks.js
new file mode 100644
index 0000000..8646d23
--- /dev/null
+++ b/AstuteClient2/src/assets/html2pdf.js/src/plugin/hyperlinks.js
@@ -0,0 +1,59 @@
+import Worker from '../worker.js';
+import { unitConvert } from '../utils.js';
+
+// Add hyperlink functionality to the PDF creation.
+
+// Main link array, and refs to original functions.
+var linkInfo = [];
+var orig = {
+  toContainer: Worker.prototype.toContainer,
+  toPdf: Worker.prototype.toPdf,
+};
+
+Worker.prototype.toContainer = function toContainer() {
+  return orig.toContainer.call(this).then(function toContainer_hyperlink() {
+    // Retrieve hyperlink info if the option is enabled.
+    if (this.opt.enableLinks) {
+      // Find all anchor tags and get the container's bounds for reference.
+      var container = this.prop.container;
+      var links = container.querySelectorAll('a');
+      var containerRect = unitConvert(container.getBoundingClientRect(), this.prop.pageSize.k);
+      linkInfo = [];
+
+      // Loop through each anchor tag.
+      Array.prototype.forEach.call(links, function(link) {
+        // Treat each client rect as a separate link (for text-wrapping).
+        var clientRects = link.getClientRects();
+        for (var i=0; i<clientRects.length; i++) {
+          var clientRect = unitConvert(clientRects[i], this.prop.pageSize.k);
+          clientRect.left -= containerRect.left;
+          clientRect.top -= containerRect.top;
+
+          var page = Math.floor(clientRect.top / this.prop.pageSize.inner.height) + 1;
+          var top = this.opt.margin[0] + clientRect.top % this.prop.pageSize.inner.height;
+          var left = this.opt.margin[1] + clientRect.left;
+
+          linkInfo.push({ page, top, left, clientRect, link });
+        }
+      }, this);
+    }
+  });
+};
+
+Worker.prototype.toPdf = function toPdf() {
+  return orig.toPdf.call(this).then(function toPdf_hyperlink() {
+    // Add hyperlinks if the option is enabled.
+    if (this.opt.enableLinks) {
+      // Attach each anchor tag based on info from toContainer().
+      linkInfo.forEach(function(l) {
+        this.prop.pdf.setPage(l.page);
+        this.prop.pdf.link(l.left, l.top, l.clientRect.width, l.clientRect.height,
+                           { url: l.link.href });
+      }, this);
+
+      // Reset the active page of the PDF to the final page.
+      var nPages = this.prop.pdf.internal.getNumberOfPages();
+      this.prop.pdf.setPage(nPages);
+    }
+  });
+};
diff --git a/AstuteClient2/src/assets/html2pdf.js/src/plugin/jspdf-plugin.js b/AstuteClient2/src/assets/html2pdf.js/src/plugin/jspdf-plugin.js
new file mode 100644
index 0000000..b7c369a
--- /dev/null
+++ b/AstuteClient2/src/assets/html2pdf.js/src/plugin/jspdf-plugin.js
@@ -0,0 +1,99 @@
+// Import dependencies.
+import jsPDF from 'jspdf';
+
+// Get dimensions of a PDF page, as determined by jsPDF.
+jsPDF.getPageSize = function(orientation, unit, format) {
+  // Decode options object
+  if (typeof orientation === 'object') {
+    var options = orientation;
+    orientation = options.orientation;
+    unit = options.unit || unit;
+    format = options.format || format;
+  }
+
+  // Default options
+  unit        = unit || 'mm';
+  format      = format || 'a4';
+  orientation = ('' + (orientation || 'P')).toLowerCase();
+  var format_as_string = ('' + format).toLowerCase();
+
+  // Size in pt of various paper formats
+  var pageFormats = {
+    'a0'  : [2383.94, 3370.39], 'a1'  : [1683.78, 2383.94],
+    'a2'  : [1190.55, 1683.78], 'a3'  : [ 841.89, 1190.55],
+    'a4'  : [ 595.28,  841.89], 'a5'  : [ 419.53,  595.28],
+    'a6'  : [ 297.64,  419.53], 'a7'  : [ 209.76,  297.64],
+    'a8'  : [ 147.40,  209.76], 'a9'  : [ 104.88,  147.40],
+    'a10' : [  73.70,  104.88], 'b0'  : [2834.65, 4008.19],
+    'b1'  : [2004.09, 2834.65], 'b2'  : [1417.32, 2004.09],
+    'b3'  : [1000.63, 1417.32], 'b4'  : [ 708.66, 1000.63],
+    'b5'  : [ 498.90,  708.66], 'b6'  : [ 354.33,  498.90],
+    'b7'  : [ 249.45,  354.33], 'b8'  : [ 175.75,  249.45],
+    'b9'  : [ 124.72,  175.75], 'b10' : [  87.87,  124.72],
+    'c0'  : [2599.37, 3676.54], 'c1'  : [1836.85, 2599.37],
+    'c2'  : [1298.27, 1836.85], 'c3'  : [ 918.43, 1298.27],
+    'c4'  : [ 649.13,  918.43], 'c5'  : [ 459.21,  649.13],
+    'c6'  : [ 323.15,  459.21], 'c7'  : [ 229.61,  323.15],
+    'c8'  : [ 161.57,  229.61], 'c9'  : [ 113.39,  161.57],
+    'c10' : [  79.37,  113.39], 'dl'  : [ 311.81,  623.62],
+    'letter'            : [612,   792],
+    'government-letter' : [576,   756],
+    'legal'             : [612,  1008],
+    'junior-legal'      : [576,   360],
+    'ledger'            : [1224,  792],
+    'tabloid'           : [792,  1224],
+    'credit-card'       : [153,   243]
+  };
+
+  // Unit conversion
+  switch (unit) {
+    case 'pt':  var k = 1;          break;
+    case 'mm':  var k = 72 / 25.4;  break;
+    case 'cm':  var k = 72 / 2.54;  break;
+    case 'in':  var k = 72;         break;
+    case 'px':  var k = 72 / 96;    break;
+    case 'pc':  var k = 12;         break;
+    case 'em':  var k = 12;         break;
+    case 'ex':  var k = 6;          break;
+    default:
+      throw ('Invalid unit: ' + unit);
+  }
+
+  // Dimensions are stored as user units and converted to points on output
+  if (pageFormats.hasOwnProperty(format_as_string)) {
+    var pageHeight = pageFormats[format_as_string][1] / k;
+    var pageWidth = pageFormats[format_as_string][0] / k;
+  } else {
+    try {
+      var pageHeight = format[1];
+      var pageWidth = format[0];
+    } catch (err) {
+      throw new Error('Invalid format: ' + format);
+    }
+  }
+
+  // Handle page orientation
+  if (orientation === 'p' || orientation === 'portrait') {
+    orientation = 'p';
+    if (pageWidth > pageHeight) {
+      var tmp = pageWidth;
+      pageWidth = pageHeight;
+      pageHeight = tmp;
+    }
+  } else if (orientation === 'l' || orientation === 'landscape') {
+    orientation = 'l';
+    if (pageHeight > pageWidth) {
+      var tmp = pageWidth;
+      pageWidth = pageHeight;
+      pageHeight = tmp;
+    }
+  } else {
+    throw('Invalid orientation: ' + orientation);
+  }
+
+  // Return information (k is the unit conversion ratio from pts)
+  var info = { 'width': pageWidth, 'height': pageHeight, 'unit': unit, 'k': k };
+  return info;
+};
+
+export default jsPDF;
diff --git a/AstuteClient2/src/assets/html2pdf.js/src/plugin/pagebreaks.js b/AstuteClient2/src/assets/html2pdf.js/src/plugin/pagebreaks.js
new file mode 100644
index 0000000..b620688
--- /dev/null
+++ b/AstuteClient2/src/assets/html2pdf.js/src/plugin/pagebreaks.js
@@ -0,0 +1,18 @@
+import Worker from '../worker.js';
+
+var orig = {
+  toContainer: Worker.prototype.toContainer
+};
+
+Worker.prototype.toContainer = function toContainer() {
+  return orig.toContainer.call(this).then(function toContainer_pagebreak() {
+    // Enable page-breaks.
+    var pageBreaks = this.prop.container.querySelectorAll('.html2pdf__page-break');
+    var pxPageHeight = this.prop.pageSize.inner.px.height;
+    Array.prototype.forEach.call(pageBreaks, function pageBreak_loop(el) {
+      el.style.display = 'block';
+      var clientRect = el.getBoundingClientRect();
+      el.style.height = pxPageHeight - (clientRect.top % pxPageHeight) + 'px';
+    }, this);
+  });
+};
diff --git a/AstuteClient2/src/assets/html2pdf.js/src/utils.js b/AstuteClient2/src/assets/html2pdf.js/src/utils.js
new file mode 100644
index 0000000..a0e9486
--- /dev/null
+++ b/AstuteClient2/src/assets/html2pdf.js/src/utils.js
@@ -0,0 +1,69 @@
+// Determine the type of a variable/object.
+export const objType = function(obj) {
+  var type = typeof obj;
+  if (type === 'undefined')                                 return 'undefined';
+  else if (type === 'string' || obj instanceof String)      return 'string';
+  else if (type === 'number' || obj instanceof Number)      return 'number';
+  else if (type === 'function' || obj instanceof Function)  return 'function';
+  else if (!!obj && obj.constructor === Array)              return 'array';
+  else if (obj && obj.nodeType === 1)                       return 'element';
+  else if (type === 'object')                               return 'object';
+  else                                                      return 'unknown';
+};
+
+// Create an HTML element with optional className, innerHTML, and style.
+export const createElement = function(tagName, opt) {
+  var el = document.createElement(tagName);
+  if (opt.className)  el.className = opt.className;
+  if (opt.innerHTML) {
+    el.innerHTML = opt.innerHTML;
+    var scripts = el.getElementsByTagName('script');
+    for (var i = scripts.length; i-- > 0; null) {
+      scripts[i].parentNode.removeChild(scripts[i]);
+    }
+  }
+  for (var key in opt.style) {
+    el.style[key] = opt.style[key];
+  }
+  return el;
+};
+
+// Deep-clone a node and preserve contents/properties.
+export const cloneNode = function(node, javascriptEnabled) {
+  // Recursively clone the node.
+  var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);
+  for (var child = node.firstChild; child; child = child.nextSibling) {
+    if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') {
+      clone.appendChild(cloneNode(child, javascriptEnabled));
+    }
+  }
+
+  if (node.nodeType === 1) {
+    // Preserve contents/properties of special nodes.
+    if (node.nodeName === 'CANVAS') {
+      clone.width = node.width;
+      clone.height = node.height;
+      clone.getContext('2d').drawImage(node, 0, 0);
+    } else if (node.nodeName === 'TEXTAREA' || node.nodeName === 'SELECT') {
+      clone.value = node.value;
+    }
+
+    // Preserve the node's scroll position when it loads.
+    clone.addEventListener('load', function() {
+      clone.scrollTop = node.scrollTop;
+      clone.scrollLeft = node.scrollLeft;
+    }, true);
+  }
+
+  // Return the cloned node.
+  return clone;
+}
+
+// Convert units using the conversion value 'k' from jsPDF.
+export const unitConvert = function(obj, k) {
+  var newObj = {};
+  for (var key in obj) {
+    newObj[key] = obj[key] * 72 / 96 / k;
+  }
+  return newObj;
+};
diff --git a/AstuteClient2/src/assets/html2pdf.js/src/worker.js b/AstuteClient2/src/assets/html2pdf.js/src/worker.js
new file mode 100644
index 0000000..657fd77
--- /dev/null
+++ b/AstuteClient2/src/assets/html2pdf.js/src/worker.js
@@ -0,0 +1,484 @@
+import jsPDF from 'jspdf';
+import html2canvas from 'html2canvas';
+import { objType, createElement, cloneNode, unitConvert } from './utils.js';
+
+/* ----- CONSTRUCTOR ----- */
+
+var Worker = function Worker(opt) {
+  // Create the root parent for the proto chain, and the starting Worker.
+  var root = Object.assign(Worker.convert(Promise.resolve()),
+                           JSON.parse(JSON.stringify(Worker.template)));
+  var self = Worker.convert(Promise.resolve(), root);
+
+  // Set progress, optional settings, and return.
+  self = self.setProgress(1, Worker, 1, [Worker]);
+  self = self.set(opt);
+  return self;
+};
+
+// Boilerplate for subclassing Promise.
+Worker.prototype = Object.create(Promise.prototype);
+Worker.prototype.constructor = Worker;
+
+// Converts/casts promises into Workers.
+Worker.convert = function convert(promise, inherit) {
+  // Uses prototypal inheritance to receive changes made to ancestors' properties.
+  promise.__proto__ = inherit || Worker.prototype;
+  return promise;
+};
+
+Worker.template = {
+  prop: {
+    src: null,
+    container: null,
+    overlay: null,
+    canvas: null,
+    img: null,
+    pdf: null,
+    pageSize: null
+  },
+  progress: {
+    val: 0,
+    state: null,
+    n: 0,
+    stack: []
+  },
+  opt: {
+    filename: 'file.pdf',
+    margin: [0,0,0,0],
+    image: { type: 'jpeg', quality: 0.95 },
+    enableLinks: true,
+    html2canvas: {},
+    jsPDF: {}
+  }
+};
+
+/* ----- FROM / TO ----- */
+
+Worker.prototype.from = function from(src, type) {
+  function getType(src) {
+    switch (objType(src)) {
+      case 'string':  return 'string';
+      case 'element': return src.nodeName.toLowerCase === 'canvas' ? 'canvas' : 'element';
+      default:        return 'unknown';
+    }
+  }
+
+  return this.then(function from_main() {
+    type = type || getType(src);
+    switch (type) {
+      case 'string':  return this.set({ src: createElement('div', {innerHTML: src}) });
+      case 'element': return this.set({ src: src });
+      case 'canvas':  return this.set({ canvas: src });
+      case 'img':     return this.set({ img: src });
+      default:        return this.error('Unknown source type.');
+    }
+  });
+};
+
+Worker.prototype.to = function to(target) {
+  // Route the 'to' request to the appropriate method.
+  switch (target) {
+    case 'container':
+      return this.toContainer();
+    case 'canvas':
+      return this.toCanvas();
+    case 'img':
+      return this.toImg();
+    case 'pdf':
+      return this.toPdf();
+    default:
+      return this.error('Invalid target.');
+  }
+};
+
+Worker.prototype.toContainer = function toContainer() {
+  // Set up function prerequisites.
+  var prereqs = [
+    function checkSrc() { return this.prop.src || this.error('Cannot duplicate - no source HTML.'); },
+    function checkPageSize() { return this.prop.pageSize || this.setPageSize(); }
+  ];
+
+  return this.thenList(prereqs).then(function toContainer_main() {
+    // Define the CSS styles for the container and its overlay parent.
+    var overlayCSS = {
+      position: 'fixed', overflow: 'hidden', zIndex: 1000,
+      left: 0, right: 0, bottom: 0, top: 0,
+      backgroundColor: 'rgba(0,0,0,0.8)'
+    };
+    var containerCSS = {
+      position: 'absolute', width: this.prop.pageSize.inner.width + this.prop.pageSize.unit,
+      left: 0, right: 0, top: 0, height: 'auto', margin: 'auto',
+      backgroundColor: 'white'
+    };
+
+    // Set the overlay to hidden (could be changed in the future to provide a print preview).
+    overlayCSS.opacity = 0;
+
+    // Create and attach the elements.
+    var source = cloneNode(this.prop.src, this.opt.html2canvas.javascriptEnabled);
+    this.prop.overlay = createElement('div',   { className: 'html2pdf__overlay', style: overlayCSS });
+    this.prop.container = createElement('div', { className: 'html2pdf__container', style: containerCSS });
+    this.prop.container.appendChild(source);
+    this.prop.overlay.appendChild(this.prop.container);
+    document.body.appendChild(this.prop.overlay);
+  });
+};
+
+Worker.prototype.toCanvas = function toCanvas() {
+  // Set up function prerequisites.
+  var prereqs = [
+    function checkContainer() { return document.body.contains(this.prop.container)
+                               || this.toContainer(); }
+  ];
+
+  // Fulfill prereqs then create the canvas.
+  return this.thenList(prereqs).then(function toCanvas_main() {
+    // Handle old-fashioned 'onrendered' argument.
+    var options = Object.assign({}, this.opt.html2canvas);
+    delete options.onrendered;
+
+    return html2canvas(this.prop.container, options);
+  }).then(function toCanvas_post(canvas) {
+    // Handle old-fashioned 'onrendered' argument.
+    var onRendered = this.opt.html2canvas.onrendered || function () {};
+    onRendered(canvas);
+
+    this.prop.canvas = canvas;
+    document.body.removeChild(this.prop.overlay);
+  });
+};
+
+Worker.prototype.toImg = function toImg() {
+  // Set up function prerequisites.
+  var prereqs = [
+    function checkCanvas() { return this.prop.canvas || this.toCanvas(); }
+  ];
+
+  // Fulfill prereqs then create the image.
+  return this.thenList(prereqs).then(function toImg_main() {
+    var imgData = this.prop.canvas.toDataURL('image/' + this.opt.image.type, this.opt.image.quality);
+    this.prop.img = document.createElement('img');
+    this.prop.img.src = imgData;
+  });
+};
+
+Worker.prototype.toPdf = function toPdf() {
+  // Set up function prerequisites.
+  var prereqs = [
+    function checkCanvas() { return this.prop.canvas || this.toCanvas(); }
+  ];
+
+  // Fulfill prereqs then create the image.
+  return this.thenList(prereqs).then(function toPdf_main() {
+    // Create local copies of frequently used properties.
+    var canvas = this.prop.canvas;
+    var opt = this.opt;
+
+    // Calculate the number of pages.
+    var ctx = canvas.getContext('2d');
+    var pxFullHeight = canvas.height;
+    var pxPageHeight = Math.floor(canvas.width * this.prop.pageSize.inner.ratio);
+    var nPages = Math.ceil(pxFullHeight / pxPageHeight);
+
+    // Define pageHeight separately so it can be trimmed on the final page.
+    var pageHeight = this.prop.pageSize.inner.height;
+
+    // Create a one-page canvas to split up the full image.
+    var pageCanvas = document.createElement('canvas');
+    var pageCtx = pageCanvas.getContext('2d');
+    pageCanvas.width = canvas.width;
+    pageCanvas.height = pxPageHeight;
+
+    // Initialize the PDF.
+    this.prop.pdf = this.prop.pdf || new jsPDF(opt.jsPDF);
+
+    for (var page=0; page<nPages; page++) {
+      // Trim the final page to reduce file size.
+      if (page === nPages-1) {
+        pageCanvas.height = pxFullHeight % pxPageHeight;
+        pageHeight = pageCanvas.height * this.prop.pageSize.inner.width / pageCanvas.width;
+      }
+
+      // Display the page.
+      var w = pageCanvas.width;
+      var h = pageCanvas.height;
+      pageCtx.fillStyle = 'white';
+      pageCtx.fillRect(0, 0, w, h);
+      pageCtx.drawImage(canvas, 0, page*pxPageHeight, w, h, 0, 0, w, h);
+
+      // Add the page to the PDF.
+      if (page)  this.prop.pdf.addPage();
+      var imgData = pageCanvas.toDataURL('image/' + opt.image.type, opt.image.quality);
+      this.prop.pdf.addImage(imgData, opt.image.type, opt.margin[1], opt.margin[0],
+                        this.prop.pageSize.inner.width, pageHeight);
+    }
+  });
+};
+
+
+/* ----- OUTPUT / SAVE ----- */
+
+Worker.prototype.output = function output(type, options, src) {
+  // Redirect requests to the correct function (outputPdf / outputImg).
+  src = src || 'pdf';
+  if (src.toLowerCase() === 'img' || src.toLowerCase() === 'image') {
+    return this.outputImg(type, options);
+  } else {
+    return this.outputPdf(type, options);
+  }
+};
+
+Worker.prototype.outputPdf = function outputPdf(type, options) {
+  // Set up function prerequisites.
+  var prereqs = [
+    function checkPdf() { return this.prop.pdf || this.toPdf(); }
+  ];
+
+  // Fulfill prereqs then perform the appropriate output.
+  return this.thenList(prereqs).then(function outputPdf_main() {
+    /* Currently implemented output types:
+     *    https://rawgit.com/MrRio/jsPDF/master/docs/jspdf.js.html#line992
+     *  save(options), arraybuffer, blob, bloburi/bloburl,
+     *  datauristring/dataurlstring, dataurlnewwindow, datauri/dataurl
+     */
+    return this.prop.pdf.output(type, options);
+  });
+};
+
+Worker.prototype.outputImg = function outputImg(type, options) {
+  // Set up function prerequisites.
+  var prereqs = [
+    function checkImg() { return this.prop.img || this.toImg(); }
+  ];
+
+  // Fulfill prereqs then perform the appropriate output.
+  return this.thenList(prereqs).then(function outputImg_main() {
+    switch (type) {
+      case undefined:
+      case 'img':
+        return this.prop.img;
+      case 'datauristring':
+      case 'dataurlstring':
+        return this.prop.img.src;
+      case 'datauri':
+      case 'dataurl':
+        return document.location.href = this.prop.img.src;
+      default:
+        throw 'Image output type "' + type + '" is not supported.';
+    }
+  });
+};
+
+Worker.prototype.save = function save(filename) {
+  // Set up function prerequisites.
+  var prereqs = [
+    function checkPdf() { return this.prop.pdf || this.toPdf(); }
+  ];
+
+  // Fulfill prereqs, update the filename (if provided), and save the PDF.
+  return this.thenList(prereqs).set(
+    filename ? { filename: filename } : null
+  ).then(function save_main() {
+    this.prop.pdf.save(this.opt.filename);
+  });
+};
+
+/* ----- SET / GET ----- */
+
+Worker.prototype.set = function set(opt) {
+  // TODO: Implement ordered pairs?
+
+  // Silently ignore invalid or empty input.
+  if (objType(opt) !== 'object') {
+    return this;
+  }
+
+  // Build an array of setter functions to queue.
+  var fns = Object.keys(opt || {}).map(function (key) {
+      if (key in Worker.template.prop) {
+        // Set pre-defined properties.
+        return function set_prop() { this.prop[key] = opt[key]; }
+      } else {
+        switch (key) {
+          case 'margin':
+            return this.setMargin.bind(this, opt.margin);
+          case 'jsPDF':
+            return function set_jsPDF() { this.opt.jsPDF = opt.jsPDF; return this.setPageSize(); }
+          case 'pageSize':
+            return this.setPageSize.bind(this, opt.pageSize);
+          default:
+            // Set any other properties in opt.
+            return function set_opt() { this.opt[key] = opt[key] };
+        }
+      }
+  }, this);
+
+  // Set properties within the promise chain.
+  return this.then(function set_main() {
+    return this.thenList(fns);
+  });
+};
+
+Worker.prototype.get = function get(key, cbk) {
+  return this.then(function get_main() {
+    // Fetch the requested property, either as a predefined prop or in opt.
+    var val = (key in Worker.template.prop) ? this.prop[key] : this.opt[key];
+    return cbk ? cbk(val) : val;
+  });
+};
+
+Worker.prototype.setMargin = function setMargin(margin) {
+  return this.then(function setMargin_main() {
+    // Parse the margin property.
+    switch (objType(margin)) {
+      case 'number':
+        margin = [margin, margin, margin, margin];
+      case 'array':
+        if (margin.length === 2) {
+          margin = [margin[0], margin[1], margin[0], margin[1]];
+        }
+        if (margin.length === 4) {
+          break;
+        }
+      default:
+        return this.error('Invalid margin array.');
+    }
+
+    // Set the margin property, then update pageSize.
+    this.opt.margin = margin;
+  }).then(this.setPageSize);
+}
+
+Worker.prototype.setPageSize = function setPageSize(pageSize) {
+  function toPx(val, k) {
+    return Math.floor(val * k / 72 * 96);
+  }
+
+  return this.then(function setPageSize_main() {
+    // Retrieve page-size based on jsPDF settings, if not explicitly provided.
+    pageSize = pageSize || jsPDF.getPageSize(this.opt.jsPDF);
+
+    // Add 'inner' field if not present.
+    if (!pageSize.hasOwnProperty('inner')) {
+      pageSize.inner = {
+        width:  pageSize.width - this.opt.margin[1] - this.opt.margin[3],
+        height: pageSize.height - this.opt.margin[0] - this.opt.margin[2]
+      };
+      pageSize.inner.px = {
+        width:  toPx(pageSize.inner.width, pageSize.k),
+        height: toPx(pageSize.inner.height, pageSize.k)
+      };
+      pageSize.inner.ratio = pageSize.inner.height / pageSize.inner.width;
+    }
+
+    // Attach pageSize to this.
+    this.prop.pageSize = pageSize;
+  });
+}
+
+Worker.prototype.setProgress = function setProgress(val, state, n, stack) {
+  // Immediately update all progress values.
+  if (val != null)    this.progress.val = val;
+  if (state != null)  this.progress.state = state;
+  if (n != null)      this.progress.n = n;
+  if (stack != null)  this.progress.stack = stack;
+  this.progress.ratio = this.progress.val / this.progress.state;
+
+  // Return this for command chaining.
+  return this;
+};
+
+Worker.prototype.updateProgress = function updateProgress(val, state, n, stack) {
+  // Immediately update all progress values, using setProgress.
+  return this.setProgress(
+    val ? this.progress.val + val : null,
+    state ? state : null,
+    n ? this.progress.n + n : null,
+    stack ? this.progress.stack.concat(stack) : null
+  );
+};
+
+/* ----- PROMISE MAPPING ----- */
+
+Worker.prototype.then = function then(onFulfilled, onRejected) {
+  // Wrap `this` for encapsulation.
+  var self = this;
+
+  return this.thenCore(onFulfilled, onRejected, function then_main(onFulfilled, onRejected) {
+    // Update progress while queuing, calling, and resolving `then`.
+    self.updateProgress(null, null, 1, [onFulfilled]);
+    return Promise.prototype.then.call(this, function then_pre(val) {
+      self.updateProgress(null, onFulfilled);
+      return val;
+    }).then(onFulfilled, onRejected).then(function then_post(val) {
+      self.updateProgress(1);
+      return val;
+    });
+  });
+};
+
+Worker.prototype.thenCore = function thenCore(onFulfilled, onRejected, thenBase) {
+  // Handle optional thenBase parameter.
+  thenBase = thenBase || Promise.prototype.then;
+
+  // Wrap `this` for encapsulation and bind it to the promise handlers.
+  var self = this;
+  if (onFulfilled)  { onFulfilled = onFulfilled.bind(self); }
+  if (onRejected)   { onRejected = onRejected.bind(self); }
+
+  // Cast self into a Promise to avoid polyfills recursively defining `then`.
+  var isNative = Promise.toString().indexOf('[native code]') !== -1 && Promise.name === 'Promise';
+  var selfPromise = isNative ? self : Worker.convert(Object.assign({}, self), Promise.prototype);
+
+  // Return the promise, after casting it into a Worker and preserving props.
+  var returnVal = thenBase.call(selfPromise, onFulfilled, onRejected);
+  return Worker.convert(returnVal, self.__proto__);
+};
+
+Worker.prototype.thenExternal = function thenExternal(onFulfilled, onRejected) {
+  // Call `then` and return a standard promise (exits the Worker chain).
+  return Promise.prototype.then.call(this, onFulfilled, onRejected);
+};
+
+Worker.prototype.thenList = function thenList(fns) {
+  // Queue a series of promise 'factories' into the promise chain.
+  var self = this;
+  fns.forEach(function thenList_forEach(fn) {
+    self = self.thenCore(fn);
+  });
+  return self;
+};
+
+Worker.prototype['catch'] = function (onRejected) {
+  // Bind `this` to the promise handler, call `catch`, and return a Worker.
+  if (onRejected)   { onRejected = onRejected.bind(this); }
+  var returnVal = Promise.prototype['catch'].call(this, onRejected);
+  return Worker.convert(returnVal, this);
+};
+
+Worker.prototype.catchExternal = function catchExternal(onRejected) {
+  // Call `catch` and return a standard promise (exits the Worker chain).
+  return Promise.prototype['catch'].call(this, onRejected);
+};
+
+Worker.prototype.error = function error(msg) {
+  // Throw the error in the Promise chain.
+  return this.then(function error_main() {
+    throw new Error(msg);
+  });
+};
+
+
+/* ----- ALIASES ----- */
+
+Worker.prototype.using = Worker.prototype.set;
+Worker.prototype.saveAs = Worker.prototype.save;
+Worker.prototype.export = Worker.prototype.output;
+Worker.prototype.run = Worker.prototype.then;
+
+
+/* ----- FINISHING ----- */
+
+// Expose the Worker class.
+export default Worker;
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/.gitignore b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/.gitignore
new file mode 100644
index 0000000..061d2ba
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/.gitignore
@@ -0,0 +1,9 @@
+index.html
+css/*
+img/*
+js/*
+node_modules/
+bower_components/
+.sparkleshare
+libpeerconnection.log
+.versions
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/.jshintrc b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/.jshintrc
new file mode 100644
index 0000000..9ad374f
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/.jshintrc
@@ -0,0 +1,34 @@
+{
+  "bitwise": true,
+  "browser": true,
+  "camelcase": true,
+  "curly": true,
+  "eqeqeq": true,
+  "esnext": true,
+  "expr": true,
+  "globals": {
+    "console": false,
+    "define": false,
+    "document": false,
+    "expect": false,
+    "module": false,
+    "require": false,
+    "window": false
+  },
+  "immed": true,
+  "indent": 4,
+  "latedef": true,
+  "maxcomplexity": 15,
+  "newcap": true,
+  "noarg": true,
+  "node": true,
+  "noempty": true,
+  "nonstandard": true,
+  "quotmark": "single",
+  "regexp": true,
+  "smarttabs": true,
+  "strict": false,
+  "trailing": true,
+  "undef": true,
+  "unused": true
+}
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/.ruby-version b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/.ruby-version
new file mode 100644
index 0000000..68b3a4c
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/.ruby-version
@@ -0,0 +1 @@
+1.9.3-p551
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/.travis.yml b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/.travis.yml
new file mode 100644
index 0000000..c6ea430
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/.travis.yml
@@ -0,0 +1,7 @@
+language: node_js
+node_js:
+  - "8.9.3"
+before_script:
+  - npm install -g grunt-cli
+  - npm install
+script: grunt test
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/CHANGELOG.md b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/CHANGELOG.md
new file mode 100644
index 0000000..848ac30
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/CHANGELOG.md
@@ -0,0 +1,914 @@
+== v1.14.15 (Mar/08 2018 22:59 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* rolling back change to fix caret positioning. it didn’t worked on some devices
+
+== v1.14.14 (Mar/02 2018 16:55 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing mask positioning delays
+* unmask: also removing place holder if added on the first place.
+* unmask: unsetting maxlength if we set it in the first place
+
+== v1.14.13 (Dec/11 2017 18:59 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixes caret issue explained on #636
+* fixing use strict issue
+
+== v1.14.12 (Oct/04 2017 09:57 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* bug fixing on caret positioning on some devices
+
+== v1.14.11 (May/30 2017 21:53 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing a lot of caret positioning issues. Thanks to @onuradsay
+
+== v1.14.10 (Feb/13 2017 14:18 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing exception when oValue in undefined
+
+== v1.14.9 (Jan/25 2017 11:17 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* don’t use input event when using samsung browser or old chrome versions
+
+== v1.14.8 (Dec/26 2016 13:18 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing caret on android with chrome 28
+
+== v1.14.7 (Dec/25 2016 03:51 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* improving caret positioning when cursor is on the middle
+
+== v1.14.6 (Dec/24 2016 17:14 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* fix caret positioning with multiple mask chars
+
+== v1.14.5 (Dec/24 2016 14:42 +0000 by Igor Escobar) ==
+
+Changes:
+
+* fixing reserved word
+
+== v1.14.4 (Dec/24 2016 14:38 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing android cursor positioning (special thanks to @felipejunges and @fernandobandeira)
+
+== v1.14.3 (Nov/28 2016 11:53 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing caret positioning on safari
+
+== v1.14.2 (Nov/27 2016 20:04 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* apply auto maxlength in case the mask doesn't have recursive pattern
+
+== v1.14.1 (Nov/27 2016 19:20 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* Fix input value mangling when inserting before a static mask character
+* fixing caret position issue
+
+== v1.14.0 (Apr/03 2016 17:52 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* Fix cursor jumping while editing in non-IE browsers. Thanks to @archwyrm
+
+Features:
+
+* adding masked function for better angular use
+
+== v1.13.9 (Mar/20 2016 16:17 +0000 by Igor Escobar) ==
+
+Changes:
+
+* giving the opportunity to pass watchInputs locally
+
+== v1.13.8 (Mar/06 2016 23:25 +0000 by Igor Escobar) ==
+
+Changes:
+
+* adding support for meteor
+
+== v1.13.7 (Mar/06 2016 22:46 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing onChange behaviour
+
+== v1.13.6 (Mar/06 2016 22:14 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing deploy procedure
+
+== v1.13.5 (Mar/06 2016 22:01 +0000 by Igor Escobar) ==
+
+Changes:
+
+* adding clearIfNotMatch to globalOptions
+
+Bugfixes:
+
+* fixing some bugs when using non-input elements
+* fixing mobile issues at #348.
+* using input event when supported
+
+== v1.13.4 (Aug/07 2015 14:21 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* Add check to ensure that there are input elements before using them
+
+== v1.13.3 (Jul/16 2015 16:11 +0100 by Igor Escobar) ==
+
+Changes:
+
+* adding main property to package.json
+
+== v1.13.2 (Jul/16 2015 16:06 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* change event wasnt being triggered in some cases
+
+== v1.13.1 (Jul/07 2015 15:38 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* destroying input event too
+
+== v1.13.0 (Jul/07 2015 15:26 +0100 by Igor Escobar) ==
+
+Changes:
+
+* removing the autocomplete default.
+
+Bugfixes:
+
+* fixing bower file thanks to @lazyants
+
+Features:
+
+* prevent glitch when invalid chars.
+* turning off autocomplete when browsers doesn't support oninput event.
+
+== v1.12.0 (Jul/07 2015 11:37 +0100 by Igor Escobar) ==
+
+Features:
+
+* giving an alternative to the autocomplete/autofill problem.
+
+== v1.11.4 (Feb/26 2015 22:11 +0000 by Igor Escobar) ==
+
+Changes:
+
+* grunt, jshint and better applyDataMask. Thanks to @lagden
+* automated deploy to npm
+
+== v1.11.3 (Jan/28 2015 15:41 +0000 by Igor Escobar) ==
+
+Changes:
+
+* Added commonjs module definition
+
+== v1.11.2 (Dec/26 2014 15:36 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* unreachable code
+
+== v1.11.1 (Dec/26 2014 15:34 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* unreachable code
+
+== v1.11.0 (Dec/26 2014 15:33 +0000 by Igor Escobar) ==
+
+Features:
+
+* implementing selectOnFocus and data-mask-selectonfocus option
+* adding public method called: .applyDataMask in case you want to decide whether to apply masks in data-mask fields
+
+== v1.10.13 (Nov/19 2014 16:06 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing bug with watchInputs feature when mask is used as a function and not a string.
+
+== v1.10.12 (Nov/06 2014 13:08 +0000 by Igor Escobar) ==
+
+Changes:
+
+* making a few improvements to make selection, copy events easier
+
+== v1.10.11 (Nov/06 2014 11:26 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* we need to revaluate dataMask flags everytime
+
+== v1.10.10 (Nov/06 2014 10:41 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing dynamically data-mask added elements
+
+== v1.10.9 (Nov/05 2014 10:52 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* data-mask wasnt working
+
+== v1.10.8 (Nov/01 2014 13:49 +0000 by Igor Escobar) ==
+
+Changes:
+
+* we dont need to seek for data-mask every time
+
+== v1.10.7 (Nov/01 2014 13:18 +0000 by Igor Escobar) ==
+
+Changes:
+
+* little optimization
+
+== v1.10.6 (Oct/28 2014 13:59 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing weird cursor problems in weird cases.
+* dynamically added inputs wasnt working
+
+== v1.10.5 (Oct/23 2014 11:41 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing weird cursor problems in weird cases.
+
+== v1.10.4 (Oct/23 2014 11:02 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing on the fly mask change feature.
+
+== v1.10.3 (Oct/22 2014 09:50 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing unmask method.
+
+== v1.10.2 (Oct/20 2014 16:38 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* onChange event fired at the wrong time when the field already has a value.
+
+== v1.10.1 (Oct/20 2014 16:08 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing onChange event behaviour
+
+== v1.10.0 (Oct/20 2014 10:56 +0100 by Igor Escobar) ==
+
+Features:
+
+* adding a way to change global settings like translation object and the byPassKeys object.
+
+== v1.9.2 (Oct/20 2014 10:08 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing fallback digits implementation. Thanks @A1rPun
+
+== v1.9.1 (Oct/18 2014 12:27 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* cant convert circular json exception
+
+== v1.9.0 (Oct/18 2014 12:07 +0100 by Igor Escobar) ==
+
+Features:
+
+* adding onInvalid callback
+
+== v1.8.0 (Oct/17 2014 11:35 +0100 by Igor Escobar) ==
+
+Changes:
+
+* removing automatic maxlength support
+* making a few optimizations to make it faster and retro compatible with other libraries
+* creating globalOptions to make it more fast and flexible
+
+Bugfixes:
+
+* fixing issue #196
+
+Features:
+
+* adding the fallback translation option
+
+== v1.7.8 (Oct/15 2014 10:55 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* change event may experience issues
+* avoid maximum call stack trace error
+
+== v1.7.7 (Sep/10 2014 22:31 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing clojure compile issue
+
+== v1.7.6 (Sep/10 2014 22:14 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing clearifnotmatch in masks with literal digits
+
+== v1.7.5 (Sep/09 2014 15:43 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing paste inside of empty fields.
+
+== v1.7.4 (Aug/11 2014 14:53 +0100 by Igor Escobar) ==
+
+Changes:
+
+* smaller and reliable code
+
+== v1.7.3 (Aug/11 2014 11:28 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing issue #185
+
+== v1.7.2 (Aug/08 2014 11:11 +0100 by Igor Escobar) ==
+
+Changes:
+
+* smaller code
+
+Bugfixes:
+
+* fixing remove bug
+
+== v1.7.1 (Aug/08 2014 00:55 +0100 by Igor Escobar) ==
+
+Changes:
+
+* upgrading zepto, smaller syntax and fixing build
+
+== v1.7.0 (Aug/07 2014 23:56 +0100 by Igor Escobar) ==
+
+Features:
+
+* applying masks to dynamically added elements. (html/javascript notation)
+
+== v1.6.5 (Jun/30 2014 10:24 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing clearIfNotMatch feature in cases of optional and recursive digits
+
+== v1.6.4 (May/08 2014 23:54 +0100 by Igor Escobar) ==
+
+Changes:
+
+* testing some deployment stunts
+
+== v1.6.3 (May/08 2014 23:51 +0100 by Igor Escobar) ==
+
+Changes:
+
+* testing some deployment stunts
+
+== v1.6.2 (May/08 2014 23:45 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* fuckin typo
+
+== v1.6.1 (May/08 2014 23:39 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing autofocus bug
+
+== v1.6.0 (May/07 2014 21:13 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing autofocus bug
+
+Features:
+
+* adding support to the clearIfNotMatch option
+* HTML5 placeholder support
+
+== v1.5.7 (May/01 2014 18:37 +0100 by Igor Escobar) ==
+
+Changes:
+
+* some cleanup and stuff
+
+== v1.5.6 (May/01 2014 18:30 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* Bug in calculating difference between mask characters between old and new field values
+* Fix stack limit exceeded
+
+== v1.5.5 (Apr/27 2014 13:47 +0100 by Igor Escobar) ==
+
+Changes:
+
+* UMD (Universal Module Definition) patterns for JavaScript modules
+
+Bugfixes:
+
+* caret position correction
+* 114 - Fix onChange Event error
+
+== v1.5.4 (Feb/09 2014 12:02 +0000 by Igor Escobar) ==
+
+Changes:
+
+* optmizing code
+
+== v1.5.3 (Feb/08 2014 14:59 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing ctrl a bug
+
+== v1.5.2 (Dec/20 2013 16:35 +0000 by Igor Escobar) ==
+
+Changes:
+
+* smaller source code
+
+== v1.5.1 (Dec/18 2013 22:34 +0000 by Igor Escobar) ==
+
+Changes:
+
+* fixing some code climate problems
+
+== v1.5.0 (Dec/18 2013 22:10 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing getCleanVal()
+
+Features:
+
+* new public method called cleanVal
+
+== v1.4.2 (Dec/16 2013 15:48 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* Dirty fix for masks not completing with a literal
+
+== v1.4.1 (Dec/09 2013 21:23 +0000 by Igor Escobar) ==
+
+Changes:
+
+* revising ignored keys
+
+== v1.4.0 (Nov/28 2013 18:06 +0000 by Igor Escobar) ==
+
+Features:
+
+* caret positioning implementation
+
+== v1.3.1 (Oct/08 2013 20:38 +0100 by Igor Escobar) ==
+
+Changes:
+
+* adding more keys to ignore list to make the char navigation smoothly
+
+Bugfixes:
+
+* Sounds like 'options' has disappeared for some reason
+
+== v1.3.0 (Sep/13 2013 10:37 +0100 by Igor Escobar) ==
+
+Features:
+
+* creating the maxlength option
+
+== v1.2.0 (Sep/07 2013 12:07 +0100 by Igor Escobar) ==
+
+Features:
+
+* adding the possibility to put recursive digits inside masks
+
+== v1.1.3 (Sep/04 2013 21:21 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing late masking
+
+== v1.1.2 (Aug/26 2013 15:08 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing mask on div,span etc
+
+== v1.1.1 (Aug/26 2013 14:42 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* better callback handling
+
+== v1.1.0 (Aug/24 2013 15:59 +0100 by Igor Escobar) ==
+
+Features:
+
+* adding onchange support
+
+== v1.0.3 (Aug/23 2013 23:10 +0100 by Igor Escobar) ==
+
+Changes:
+
+* optimizations to mask on non html fields
+
+== v1.0.2 (Aug/23 2013 22:46 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* adding remask method do improve callback performance
+
+== v1.0.1 (Aug/23 2013 22:01 +0100 by Igor Escobar) ==
+
+Changes:
+
+* normal releases again
+
+== v1.0.0 (Aug/23 2013 21:59 +0100 by Igor Escobar) ==
+
+Features:
+
+* huge refactoring focusing no reduce source code weight and bugfixing
+
+== v0.11.5 (Aug/20 2013 17:11 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* bug fixing when mask range is bigger than 2 digits.
+
+== v0.11.4 (Aug/19 2013 10:24 +0100 by Igor Escobar) ==
+
+Changes:
+
+* adding de delete key to byPassKeys
+
+== v0.11.3 (Aug/18 2013 00:48 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing zepto compatibily
+
+== v0.11.2 (Aug/17 2013 18:39 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* jmask iterate all items
+
+== v0.11.1 (Aug/17 2013 18:32 +0100 by Igor Escobar) ==
+
+Changes:
+
+* a little bit smaller source code
+
+== v0.11.0 (Aug/16 2013 21:27 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* Altered "ignored keys" hook to run events (i.e. onKeyPress) afterwards. Otherwise, we miss key triggered events when the user deletes the entire text box, etc.
+
+Features:
+
+* adding support to method getCleanVal
+
+== v0.10.1 (Jul/26 2013 09:35 +0100 by ) ==
+
+
+
+== v0.10.0 (Jul/19 2013 23:07 +0100 by Igor Escobar) ==
+
+Features:
+
+* adding data-mask support
+
+== v0.9.1 (Jul/19 2013 22:35 +0100 by Igor Escobar) ==
+
+Changes:
+
+* jQuery-Mask-Plugin is now available at bower.io
+
+Bugfixes:
+
+* fixing addEventListener on IE7
+
+== v0.9.0 (Apr/24 2013 07:44 +0100 by Igor Escobar) ==
+
+Features:
+
+* Adding compatibility with Zepto.js
+
+== v0.8.0 (Apr/07 2013 18:39 +0100 by Igor Escobar) ==
+
+Features:
+
+* applying masks anything != than input :)
+* implementing the possibility of range chars ex: A{1,3}
+
+== v0.7.11 (Apr/05 2013 22:12 +0100 by Igor Escobar) ==
+
+Changes:
+
+* now when you type a wrong char, the plugin will make your text fit inside of the mask instead of lose your data.
+
+== v0.7.10 (Apr/04 2013 22:14 +0100 by Igor Escobar) ==
+
+Changes:
+
+* changing yui-compressor to clojure-compiler
+
+== v0.7.9 (Apr/04 2013 22:04 +0100 by Igor Escobar) ==
+
+Changes:
+
+* refactoring and implementation of optional mask digits
+
+Bugfixes:
+
+* fixing maxlength and adding a smarter mask removal. issue #18
+
+== v0.7.8 (Mar/30 2013 00:48 +0000 by Igor Escobar) ==
+
+Changes:
+
+* a few changes to get the code smallest possible.
+* removing unnecessary methods and making code smaller.
+
+== v0.7.7 (Mar/29 2013 12:38 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* fixing copy and paste problem related on issue #15
+
+== v0.7.6 (Mar/29 2013 00:28 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* correcting mask formatationg problem related on issue #16
+
+== v0.7.5 (Mar/03 2013 20:56 +0000 by Igor Escobar) ==
+
+Changes:
+
+* generating .gz file on deploy
+
+== v0.7.4 (Mar/03 2013 20:38 +0000 by Igor Escobar) ==
+
+Changes:
+
+* changing minifier jsmin to yui compressor.
+
+== v0.7.3 (Mar/02 2013 01:12 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* bug fixing when typed wrong data type on mixing masks.
+
+== v0.7.2 (Feb/24 2013 22:02 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* fuckin stupid comma.
+
+== v0.7.1 (Feb/24 2013 21:57 +0000 by Igor Escobar) ==
+
+Changes:
+
+* testing the private method maskToRegex
+* a little bit of changes to make the code more testable
+
+== v0.7.0 (Feb/12 2013 00:30 +0000 by Igor Escobar) ==
+
+Features:
+
+* Now you can decide for jquery mask plugin how to interpret 0 to 9, A and S and even teach him how to reconize patterns.
+
+== v0.6.3 (Feb/11 2013 12:20 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* When the user paste a text and the last char is valid sanitize may fail
+
+== v0.6.2 (Feb/11 2013 00:02 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* allowing the user type the same character as the mask without erasing it.
+
+== v0.6.1 (Jan/20 2013 23:57 +0000 by Igor Escobar) ==
+
+Changes:
+
+* changing the way ta deployment occurs to correct jquery plugins deployments.
+
+== v0.6.0 (Jan/18 2013 17:19 +0000 by Igor Escobar) ==
+
+Changes:
+
+* Now pushing jQuery Mask Plugin to jQuery Plugins Repository
+
+== v0.5.4 (Jan/17 2013 23:06 +0000 by Igor Escobar) ==
+
+Changes:
+
+* upgrading jquery plugins manifest file
+
+== v0.5.3 (Jan/17 2013 22:48 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* correctly generating jmask version inside of jquery mask source
+
+== v0.5.2 (Jan/17 2013 22:43 +0000 by Igor Escobar) ==
+
+Changes:
+
+* Now pushing to jQuery Plugin Repository
+
+== v0.5.1 (Jan/07 2013 23:33 +0000 by Igor Escobar) ==
+
+Changes:
+
+* improving the deploy process with the new stepup's upgrade.
+
+== v0.5.0 (Oct/27 2012 13:40 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* Bug fixes on OnSupport method with Firefox.
+
+Features:
+
+* the first parameter of the .mask() function, now accepts a string or a anonymous function
+
+== v0.4.7 (Aug/06 2012 22:56 +0100 by Igor Escobar) ==
+
+Changes:
+
+* Nothing big, just class refactoring
+
+== v0.4.6 (Aug/06 2012 01:25 +0100 by Igor Escobar) ==
+
+Changes:
+
+- better OOP design
+- implementing the jquery data object on each mask field
+- implementing the public method .remove to disable and remove the mask
+
+== v0.4.5 (Aug/04 2012 01:31 +0100 by Igor Escobar) ==
+
+Changes:
+
+- improving support to complex jquery selectors
+- performance improvement.
+- callback handling improvement
+
+== v0.4.4 (Jun/03 2012 21:01 +0100 by Igor Escobar) ==
+
+Bugfixes:
+
+* Bug fixes on Internet Explorer 8.
+
+== v0.4.3 (Mar/19 2012 21:52 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* Corrigindo bug para mascaras com +
+
+== v0.4.2 (Mar/18 2012 15:28 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* Mascara não pararecia no firefox
+
+== v0.4.1 (Mar/18 2012 15:01 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* Corrigindo tim das macaras.
+
+== v0.4.0 (Mar/18 2012 14:51 +0000 by Igor Escobar) ==
+
+Features:
+
+* Implementado mascara reversa para moeda/cpf/rg/etc.
+* Nova engine.
+
+== v0.3.0 (Mar/14 2012 10:14 +0000 by Igor Escobar) ==
+
+Changes:
+
+* License and comments up to date.
+
+Features:
+
+* On-the-fly mask change.
+* onComplete and onKeyPress new callbacks.
+
+== v0.2.5 (Mar/13 2012 22:55 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+- Corrigindo ctrl+v com mascara errada. - Cortando dados que exceder a mascara no ctrl+v ou se segurar alguma tecla. - Refatorando algumas partes do código.
+
+== v0.2.4 (Mar/13 2012 11:06 +0000 by Igor Escobar) ==
+
+Changes:
+
+* Codigo refatorado, otimizado, validação mais precisa e efetiva.
+
+== v0.2.3 (Mar/13 2012 01:01 +0000 by Igor Escobar) ==
+
+Changes:
+
+* Melhorando expressoes regulares.
+
+== v0.2.2 (Mar/13 2012 00:50 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* Corrindo regex de validação
+
+== v0.2.1 (Mar/13 2012 00:41 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* Corrigida validação alphanumerica.
+
+== v0.2.0 (Mar/13 2012 00:24 +0000 by Igor Escobar) ==
+
+Features:
+
+- Input Data Type Validation.
+- Automatic MaxLength (When are not defined).
+- Live Event Implemented for Ajax-based Apps.
+- Mixed mask with validation.
+* S for string digit
+* A for alphanumeric digit
+* 0 to 9 for numeric digit.
+
+== v0.1.1 (Mar/10 2012 14:05 +0000 by Igor Escobar) ==
+
+Bugfixes:
+
+* Implementando Crossbrowser event handling.
+
+== v0.1.0 (Mar/10 2012 13:10 +0000 by Igor Escobar) ==
+
+Features:
+
+* Implementando mascaras com espaço para data e hora
+
+== v0.0.1 (Mar/10 2012 04:42 +0000 by Igor Escobar) ==
+
+Changes:
+
+* Refatorando o codigo para suportar multiplas instancias
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/CONTRIBUTING.md b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/CONTRIBUTING.md
new file mode 100644
index 0000000..6536717
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/CONTRIBUTING.md
@@ -0,0 +1,9 @@
+### Have you take a look into our docs?
+https://igorescobar.github.io/jQuery-Mask-Plugin/
+
+### Want to contribute? Make sure you read this first
+https://github.com/igorescobar/jQuery-Mask-Plugin#contributing
+
+Is this plugin helping you out? Buy me a beer and cheers! :beer:
+
+:bowtie: https://www.paypal.me/igorcescobar
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/Dockerfile b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/Dockerfile
new file mode 100644
index 0000000..db59cb7
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/Dockerfile
@@ -0,0 +1,36 @@
+FROM phusion/baseimage:0.9.17
+
+# Use baseimage-docker's init system.
+CMD ["/sbin/my_init"]
+
+# Java 8 for Google's clojure compiler
+RUN \
+  echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | debconf-set-selections && \
+  echo "deb http://dl.bintray.com/sbt/debian /" | tee -a /etc/apt/sources.list.d/sbt.list && \
+  add-apt-repository -y ppa:webupd8team/java && \
+  apt-get update && \
+  apt-get install -y oracle-java8-installer git unzip ruby-full && \
+  rm -rf /var/lib/apt/lists/* && \
+  rm -rf /var/cache/oracle-jdk8-installer
+
+# Define commonly used JAVA_HOME variable
+ENV JAVA_HOME /usr/lib/jvm/java-8-oracle
+
+RUN mkdir /app
+RUN mkdir /app/clojure-compiler
+
+# Clojure compiler
+RUN \
+  curl -O http://dl.google.com/closure-compiler/compiler-latest.zip && \
+  unzip compiler-latest.zip -d /app/clojure-compiler && \
+  chmod a+x /app/clojure-compiler && \
+  rm compiler-latest.zip
+
+RUN gem install bundler pry step-up --no-rdoc --no-ri
+
+# Install Node.js
+RUN curl --silent --location https://deb.nodesource.com/setup_0.12 | sudo bash -
+RUN apt-get install --yes nodejs
+
+RUN npm install -g grunt-cli
+WORKDIR /app/jquery-mask-plugin
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/Gruntfile.js b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/Gruntfile.js
new file mode 100644
index 0000000..35917c4
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/Gruntfile.js
@@ -0,0 +1,43 @@
+module.exports = function(grunt) {
+  require('load-grunt-tasks')(grunt);
+  require('time-grunt')(grunt);
+
+  grunt.initConfig({
+
+    jshint: {
+      options: {
+        jshintrc: '.jshintrc',
+        reporter: require('jshint-stylish')
+      },
+      all: ['src/{,*/}*.js']
+    },
+    connect: {
+      server: {
+        options: {
+          port: 9001,
+          base: './'
+        }
+      }
+    },
+    qunit: {
+      all: {
+        options: {
+          urls: [
+            'http://localhost:9001/test/test-for-jquery-1.11.1.html',
+            'http://localhost:9001/test/test-for-jquery-1.7.2.html',
+            'http://localhost:9001/test/test-for-jquery-1.8.3.html',
+            'http://localhost:9001/test/test-for-jquery-1.9.1.html',
+            'http://localhost:9001/test/test-for-jquery-2.1.1.html',
+            'http://localhost:9001/test/test-for-jquery-3.0.0.html',
+            'http://localhost:9001/test/test-for-zepto.html'
+          ]
+        }
+      }
+    }
+  });
+
+  // A convenient task alias.
+  grunt.registerTask('test', ['jshint', 'connect', 'qunit']);
+  grunt.registerTask('default', ['test']);
+
+};
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/ISSUE_TEMPLATE.md b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/ISSUE_TEMPLATE.md
new file mode 100644
index 0000000..001550a
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/ISSUE_TEMPLATE.md
@@ -0,0 +1,22 @@
+### Have you take a look into our docs?
+https://igorescobar.github.io/jQuery-Mask-Plugin/
+
+### Make sure your read this before opening a new issue:
+https://github.com/igorescobar/jQuery-Mask-Plugin#problems-or-questions
+
+#### Device
+[...]
+
+#### Browser (and version)?
+[...]
+
+#### Functional `jsfiddle` exemplifying your problem: 
+You can use this one as exemple: http://jsfiddle.net/igorescobar/6pco4om7/
+
+#### Describe de problem depth:
+[...]
+
+
+Is this plugin helping you out? Buy me a beer and cheers! :beer:
+
+:bowtie: https://www.paypal.me/igorcescobar
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/LICENSE b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/LICENSE
new file mode 100644
index 0000000..49285f3
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/LICENSE
@@ -0,0 +1,26 @@
+ Created by Igor Escobar on 2012-03-10. Please report any bug at http://blog.igorescobar.com
+
+ Copyright (c) 2012 Igor Escobar http://blog.igorescobar.com
+
+ The MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/README.md b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/README.md
new file mode 100644
index 0000000..144513c
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/README.md
@@ -0,0 +1,137 @@
+# jQuery Mask Plugin
+A jQuery Plugin to make masks on form fields and HTML elements.
+
+[![Build Status](https://travis-ci.org/igorescobar/jQuery-Mask-Plugin.png)](https://travis-ci.org/igorescobar/jQuery-Mask-Plugin)
+[![Code Climate](https://codeclimate.com/github/igorescobar/jQuery-Mask-Plugin.png)](https://codeclimate.com/github/igorescobar/jQuery-Mask-Plugin)
+[![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/jquery-mask-plugin/badge?style=rounded)](https://www.jsdelivr.com/package/npm/jquery-mask-plugin)
+[![CDNJS](https://img.shields.io/cdnjs/v/jquery.mask.svg)](https://cdnjs.com/libraries/jquery.mask)
+
+# Documentation, Demos & Usage Examples
+https://igorescobar.github.io/jQuery-Mask-Plugin/
+
+## Features
+
+  * Lightweight (~2kb minified, ~1kb gziped).
+  * Built-in support for dynamically added elements.
+  * Masks on any HTML element (no need to server-side mask anymore!)!
+  * HTML notation support (data-mask, data-mask-recursive, data-mask-clearifnotmatch).
+  * String/Numeric/Alpha/Mixed masks.
+  * Reverse mask support for masks on numeric fields.
+  * Sanitization.
+  * Optional digits.
+  * Recursive Digits.
+  * Fallback Digits.
+  * Advanced mask initialization.
+  * Advanced Callbacks.
+  * On-the-fly mask change.
+  * Mask removal.
+  * Full customization.
+  * Compatibility with React/UMD/Zepto.js/Angular.JS.
+  * HTML5 placeholder support.
+  * Clear the field if it not matches support.
+
+## Want to buy me a beer? :heart_eyes:
+http://paypal.me/igorcescobar
+
+## Install it via Package Managers
+### Bower
+`bower install jquery-mask-plugin`
+### NPM
+`npm i jquery-mask-plugin`
+### Meteor
+`meteor add igorescobar:jquery-mask-plugin`
+### Packagist/Composer
+`composer require igorescobar/jquery-mask-plugin`
+
+## CDNs
+### CDNjs
+https://cdnjs.com/libraries/jquery.mask
+### JSDelivr
+http://www.jsdelivr.com/projects/jquery.mask
+
+## RubyGems
+```ruby
+gem 'jquery_mask_rails' # more details at http://bit.ly/jquery-mask-gem
+```
+
+## Tutorials
+### English
+  * [Masks with jQuery Mask Plugin](http://bit.ly/masks-with-jquery-mask-plugin)
+  * [Using jQuery Mask Plugin With Zepto.js](http://bit.ly/using-jquery-mask-plugin-with-zeptojs)
+
+### Portuguese
+  * [Mascaras com JQuery Mask Plugin](http://bit.ly/mascaras-com-jquery-mask-plugin)
+  * [Mascara Javascript para os novos telefones de São Paulo](http://bit.ly/mascara-javascript-para-os-novos-telefones-de-sao-paulo)
+
+### Fun (or not) facts
+  * [I’ve had the chance to troll Donald Trump. But I didn’t.](http://www.igorescobar.com/blog/2016/08/21/ive-the-chance-to-troll-donald-trump-but-i-didnt/)
+
+## Compatibility
+jQuery Mask Plugin has been tested with jQuery 1.7+ on all major browsers:
+
+ * Firefox 2+ (Win, Mac, Linux);
+ * IE7+ (Win);
+ * Chrome 6+ (Win, Mac, Linux, Android, iPhone);
+ * Safari 3.2+ (Win, Mac, iPhone);
+ * Opera 8+ (Win, Mac, Linux, Android, iPhone).
+ * Android Default Browser v4+
+
+## Typescript support
+Definition can be found [here](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/jquery-mask-plugin).
+
+To install, open terminal and navigate to your working directory.
+
+### Typescript 1.x users
+  * Install [typings](https://github.com/typings/typings) by running `npm install typings --global`.
+  * Then install the definition by running `typings install dt~jquery-mask-plugin --global --save`.
+### Typescript 2.x users
+  * Use npm `npm install --save-dev @types/jquery-mask-plugin`.
+
+For configuration options and troubleshooting refer to these repositories:
+* [Typings](https://github.com/typings/typings)
+* [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped)
+* [Typescript](https://github.com/Microsoft/TypeScript)
+
+
+## Problems or Questions?
+Before opening a new [issue](https://github.com/igorescobar/jQuery-Mask-Plugin/issues) take a look on those frequently asked questions:
+#### [How to integrate with React.js?](https://github.com/igorescobar/jQuery-Mask-Plugin/issues/498)
+#### [How to integrate with Angular.js?](https://github.com/igorescobar/jQuery-Mask-Plugin/issues/499)
+#### [How to integrate with Vue.js?](https://github.com/ankurk91/vue-jquery-mask)
+#### [Problems with old versions of Android keyboard](https://github.com/igorescobar/jQuery-Mask-Plugin/issues/135)
+#### [Negative numbers, or currency related problems](https://github.com/igorescobar/jQuery-Mask-Plugin/issues/436#issuecomment-253176511)
+#### [Prefix or sufix on the Mask](https://github.com/igorescobar/jQuery-Mask-Plugin/issues/166)
+#### [Add validation?](https://github.com/igorescobar/jQuery-Mask-Plugin/issues/387#issuecomment-192998092)
+#### [Field type number, email not working?](https://github.com/igorescobar/jQuery-Mask-Plugin/issues/450#issuecomment-253225719)
+#### [Want to keep the placeholder as the user types?](https://github.com/igorescobar/jQuery-Mask-Plugin/issues/633#issuecomment-350819224)
+#### [E-mail mask?](https://github.com/igorescobar/jQuery-Mask-Plugin/issues/582)
+
+## Bugs?
+Did you read our [docs](https://igorescobar.github.io/jQuery-Mask-Plugin/docs.html)? Yes? Cool! So now... make sure that you have a *functional* [jsfiddle](http://jsfiddle.net/) exemplifying your problem and open an [issue](https://github.com/igorescobar/jQuery-Mask-Plugin/issues) for us. Don't know how to do it? Use this [fiddle example](http://jsfiddle.net/igorescobar/6pco4om7/).
+
+## Contributing
+ * **Bug Reporting**: Yes! You can contribute opening [issues](https://github.com/igorescobar/jQuery-Mask-Plugin/issues)!
+ * **Documenting**: Do you think that something in our [docs](https://github.com/igorescobar/jQuery-Mask-Plugin/tree/gh-pages) should be better? Do you have a cool idea to increase the awesomeness? Summit your pull request with your idea!
+ * **Bug Fixing**: No time to lose? Fix it and help others! Write some [tests](https://github.com/igorescobar/jQuery-Mask-Plugin/tree/master/test) to make sure that everything are working propertly.
+ * **Improving**: Open an [issue](https://github.com/igorescobar/jQuery-Mask-Plugin/issues) and lets discuss it. Just to make sure that you're on the right track.
+ * **Sharing**: Yes! Have we saved some of your time? Are you enjoying our mask plugin? Sharing is caring! Tweet it! Facebook it! Linkedin It(?!) :D
+ * **Donating**: Hey, now that you don't need to worry about masks again... buy me a coffee, beer or a PlayStation 4 (Xbox One also accepted!) :o)
+
+### Unit Tests
+We use [QUnit](http://qunitjs.com/) and [GruntJS](http://gruntjs.com/). To run our test suit is just run: ```grunt test``` in your console or you can open those ```test-for*.html``` files inside of our ```test/``` folder.
+
+In case you're familiar with [Docker](https://www.docker.com/) here is how you can use it:
+```bash
+docker build -t jquery-mask .
+CONTAINER_ID=$(docker run -d -v $PWD:/app/jquery-mask-plugin jquery-mask)
+docker exec $CONTAINER_ID sh -c "npm install"
+docker exec -it $CONTAINER_ID /bin/bash
+grunt test
+```
+
+## Contributors
+ * [Igor Lima](https://github.com/igorlima)
+ * [Mark Simmons](https://github.com/Markipelago)
+ * [Gabriel Schammah](https://github.com/gschammah)
+ * [Marcelo Manzan](https://github.com/kawamanza)
+ * [See the full list](https://github.com/igorescobar/jQuery-Mask-Plugin/graphs/contributors)
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/bower.json b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/bower.json
new file mode 100644
index 0000000..6d90941
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/bower.json
@@ -0,0 +1,12 @@
+{
+  "name": "jquery-mask-plugin",
+  "version": "1.14.15",
+  "main": "dist/jquery.mask.js",
+  "ignore": [
+    "deploy.rb",
+    "jquery.mask.json",
+    "Gruntfile.js",
+    "test/*",
+    ".*"
+  ]
+}
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/component.json b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/component.json
new file mode 100644
index 0000000..970995a
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/component.json
@@ -0,0 +1,10 @@
+{
+  "name": "jQuery-Mask-Plugin",
+  "description": "A jQuery Plugin to make masks on form fields and HTML elements.",
+  "version": "1.14.15",
+  "keywords": ["javascript", "mask", "form"],
+  "scripts": [
+    "dist/jquery.mask.js"
+  ],
+  "main": "dist/jquery.mask.js"
+}
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/composer.json b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/composer.json
new file mode 100644
index 0000000..f9a7541
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/composer.json
@@ -0,0 +1,19 @@
+{
+  "name": "igorescobar/jquery-mask-plugin",
+  "type": "library",
+  "description": "A jQuery Plugin to make masks on form fields and html elements.",
+  "keywords": ["jquery", "mask", "plugin"],
+  "homepage": "https://github.com/igorescobar/jQuery-Mask-Plugin",
+  "license": "MIT",
+  "authors": [
+    {
+      "name": "Igor Escobar",
+      "email": "blog@igorescobar.com",
+      "homepage": "https://about.me/igorescobar",
+      "role": "Developer"
+    }
+  ],
+  "support": {
+    "issues": "https://github.com/igorescobar/jQuery-Mask-Plugin/issues"
+  }
+}
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/deploy.rb b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/deploy.rb
new file mode 100644
index 0000000..acfbc78
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/deploy.rb
@@ -0,0 +1,77 @@
+require 'rubygems'
+require 'zlib'
+
+JMASK_FILE = 'src/jquery.mask.js'
+JMASK_MIN_FILE = 'dist/jquery.mask.min.js'
+GHPAGES_JMASK_MIN_FILE = 'js/jquery.mask.min.js'
+JMASK_VERSION = `stepup version --next-release`.delete("\n")
+BOWER_MANIFEST_FILE = 'bower.json'
+NPM_MANIFEST_FILE = 'package.json'
+METEOR_MANIFEST_FILE = 'package.js'
+COMPONENT_MANIFEST_FILE = 'component.json'
+
+abort("No notes, do deal.") if JMASK_VERSION.empty?
+
+puts '# PUTTING NEW VERSION INSIDE OF JQUERY MASK FILE'
+unversioned_jmask_file = File.open(JMASK_FILE, 'rb') { |file| file.read }
+File.open(JMASK_FILE, 'w') do |file|
+  file.write(unversioned_jmask_file.gsub(/\* @version: (v[0-9.+]+)/, "\* @version: #{JMASK_VERSION}"))
+end
+
+puts '# COPYING NEW JMASK FILE TO DIST/'
+`yes | cp #{JMASK_FILE} dist/`
+
+[BOWER_MANIFEST_FILE, NPM_MANIFEST_FILE, COMPONENT_MANIFEST_FILE, METEOR_MANIFEST_FILE].each { |manifest_name|
+  puts "# UPGRADING #{manifest_name} "
+  manifest_file = File.open(manifest_name, 'rb') { |file| file.read }
+  File.open(manifest_name, 'w') do |file|
+    file.write(manifest_file.gsub(/"version": "([0-9.+]+)"/, "\"version\": \"#{JMASK_VERSION.gsub("v", "")}\""))
+  end
+}
+
+puts '# GENERATING MIN FILE'
+jquery_mask_min_file = nil
+File.open(JMASK_FILE, 'r') do |file|
+  minFile = File.open(JMASK_MIN_FILE, 'w')
+  minFile.puts("// jQuery Mask Plugin #{JMASK_VERSION}")
+  minFile.puts("// github.com/igorescobar/jQuery-Mask-Plugin")
+  jquery_mask_min_file = `java -jar ../clojure-compiler/compiler.jar --js src/jquery.mask.js --charset UTF-8`
+  minFile.puts(jquery_mask_min_file)
+  minFile.close
+end
+
+puts '# GENERATING A NEW COMMIT WITH VERSIONED FILEs'
+`git commit -am 'generating jquery mask files #{JMASK_VERSION}'`
+
+puts '# PUSHING CHANGES TO REMOTE'
+`git pull --rebase && git push`
+
+puts '# CREATING NEW VERSION'
+`stepup version create --no-editor`
+
+puts '# UPGRATING CHANGELOG'
+`stepup changelog --format=wiki > CHANGELOG.md`
+`git commit -am "upgrading changelog"`
+`git push`
+
+puts '# UPGRADING gh-pages'
+`git checkout gh-pages`
+`git pull origin gh-pages`
+
+minFile = File.open(GHPAGES_JMASK_MIN_FILE, 'w')
+minFile.puts("// jQuery Mask Plugin #{JMASK_VERSION}")
+minFile.puts("// github.com/igorescobar/jQuery-Mask-Plugin")
+minFile.puts(jquery_mask_min_file)
+minFile.close
+
+`git commit -am "upgrading plugin file"`
+`git push`
+`git checkout master`
+
+puts '# PUBLISHING NPM PACKAGE'
+`npm publish`
+
+puts '# PUBLISHING METEOR PACKAGE'
+`meteor publish`
+
+puts '# DONE!'
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/dist/jquery.mask.js b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/dist/jquery.mask.js
new file mode 100644
index 0000000..019f2ec
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/dist/jquery.mask.js
@@ -0,0 +1,604 @@
+/**
+ * jquery.mask.js
+ * @version: v1.14.15
+ * @author: Igor Escobar
+ *
+ * Created by Igor Escobar on 2012-03-10. Please report any bug at github.com/igorescobar/jQuery-Mask-Plugin
+ *
+ * Copyright (c) 2012 Igor Escobar http://igorescobar.com
+ *
+ * The MIT License (http://www.opensource.org/licenses/mit-license.php)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* jshint laxbreak: true */
+/* jshint maxcomplexity:17 */
+/* global define */
+
+// UMD (Universal Module Definition) patterns for JavaScript modules that work everywhere.
+// https://github.com/umdjs/umd/blob/master/templates/jqueryPlugin.js
+(function (factory, jQuery, Zepto) {
+
+    if (typeof define === 'function' && define.amd) {
+        define(['jquery'], factory);
+    } else if (typeof exports === 'object') {
+        module.exports = factory(require('jquery'));
+    } else {
+        factory(jQuery || Zepto);
+    }
+
+}(function ($) {
+    'use strict';
+
+    var Mask = function (el, mask, options) {
+
+        var p = {
+            invalid: [],
+            getCaret: function () {
+                try {
+                    var sel,
+                        pos = 0,
+                        ctrl = el.get(0),
+                        dSel = document.selection,
+                        cSelStart = ctrl.selectionStart;
+
+                    // IE Support
+                    if (dSel && navigator.appVersion.indexOf('MSIE 10') === -1) {
+                        sel = dSel.createRange();
+                        sel.moveStart('character', -p.val().length);
+                        pos = sel.text.length;
+                    }
+                    // Firefox support
+                    else if (cSelStart || cSelStart === '0') {
+                        pos = cSelStart;
+                    }
+
+                    return pos;
+                } catch (e) {}
+            },
+            setCaret: function(pos) {
+                try {
+                    if (el.is(':focus')) {
+                        var range, ctrl = el.get(0);
+
+                        // Firefox, WebKit, etc..
+                        if (ctrl.setSelectionRange) {
+                            ctrl.setSelectionRange(pos, pos);
+                        } else { // IE
+                            range = ctrl.createTextRange();
+                            range.collapse(true);
+                            range.moveEnd('character', pos);
+                            range.moveStart('character', pos);
+                            range.select();
+                        }
+                    }
+                } catch (e) {}
+            },
+            events: function() {
+                el
+                .on('keydown.mask', function(e) {
+                    el.data('mask-keycode', e.keyCode || e.which);
+                    el.data('mask-previus-value', el.val());
+                    el.data('mask-previus-caret-pos', p.getCaret());
+                    p.maskDigitPosMapOld = p.maskDigitPosMap;
+                })
+                .on($.jMaskGlobals.useInput ? 'input.mask' : 'keyup.mask', p.behaviour)
+                .on('paste.mask drop.mask', function() {
+                    setTimeout(function() {
+                        el.keydown().keyup();
+                    }, 100);
+                })
+                .on('change.mask', function(){
+                    el.data('changed', true);
+                })
+                .on('blur.mask', function(){
+                    if (oldValue !== p.val() && !el.data('changed')) {
+                        el.trigger('change');
+                    }
+                    el.data('changed', false);
+                })
+                // it's very important that this callback remains in this position
+                // otherwhise oldValue it's going to work buggy
+                .on('blur.mask', function() {
+                    oldValue = p.val();
+                })
+                // select all text on focus
+                .on('focus.mask', function (e) {
+                    if (options.selectOnFocus === true) {
+                        $(e.target).select();
+                    }
+                })
+                // clear the value if it not complete the mask
+                .on('focusout.mask', function() {
+                    if (options.clearIfNotMatch && !regexMask.test(p.val())) {
+                       p.val('');
+                   }
+                });
+            },
+            getRegexMask: function() {
+                var maskChunks = [], translation, pattern, optional, recursive, oRecursive, r;
+
+                for (var i = 0; i < mask.length; i++) {
+                    translation = jMask.translation[mask.charAt(i)];
+
+                    if (translation) {
+
+                        pattern = translation.pattern.toString().replace(/.{1}$|^.{1}/g, '');
+                        optional = translation.optional;
+                        recursive = translation.recursive;
+
+                        if (recursive) {
+                            maskChunks.push(mask.charAt(i));
+                            oRecursive = {digit: mask.charAt(i), pattern: pattern};
+                        } else {
+                            maskChunks.push(!optional && !recursive ? pattern : (pattern + '?'));
+                        }
+
+                    } else {
+                        maskChunks.push(mask.charAt(i).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'));
+                    }
+                }
+
+                r = maskChunks.join('');
+
+                if (oRecursive) {
+                    r = r.replace(new RegExp('(' + oRecursive.digit + '(.*' + oRecursive.digit + ')?)'), '($1)?')
+                         .replace(new RegExp(oRecursive.digit, 'g'), oRecursive.pattern);
+                }
+
+                return new RegExp(r);
+            },
+            destroyEvents: function() {
+                el.off(['input', 'keydown', 'keyup', 'paste', 'drop', 'blur', 'focusout', ''].join('.mask '));
+            },
+            val: function(v) {
+                var isInput = el.is('input'),
+                    method = isInput ? 'val' : 'text',
+                    r;
+
+                if (arguments.length > 0) {
+                    if (el[method]() !== v) {
+                        el[method](v);
+                    }
+                    r = el;
+                } else {
+                    r = el[method]();
+                }
+
+                return r;
+            },
+            calculateCaretPosition: function() {
+                var oldVal = el.data('mask-previus-value') || '',
+                    newVal = p.getMasked(),
+                    caretPosNew = p.getCaret();
+                if (oldVal !== newVal) {
+                    var caretPosOld = el.data('mask-previus-caret-pos') || 0,
+                        newValL = newVal.length,
+                        oldValL = oldVal.length,
+                        maskDigitsBeforeCaret = 0,
+                        maskDigitsAfterCaret = 0,
+                        maskDigitsBeforeCaretAll = 0,
+                        maskDigitsBeforeCaretAllOld = 0,
+                        i = 0;
+
+                    for (i = caretPosNew; i < newValL; i++) {
+                        if (!p.maskDigitPosMap[i]) {
+                            break;
+                        }
+                        maskDigitsAfterCaret++;
+                    }
+
+                    for (i = caretPosNew - 1; i >= 0; i--) {
+                        if (!p.maskDigitPosMap[i]) {
+                            break;
+                        }
+                        maskDigitsBeforeCaret++;
+                    }
+
+                    for (i = caretPosNew - 1; i >= 0; i--) {
+                        if (p.maskDigitPosMap[i]) {
+                            maskDigitsBeforeCaretAll++;
+                        }
+                    }
+
+                    for (i = caretPosOld - 1; i >= 0; i--) {
+                        if (p.maskDigitPosMapOld[i]) {
+                            maskDigitsBeforeCaretAllOld++;
+                        }
+                    }
+
+                    // if the cursor is at the end keep it there
+                    if (caretPosNew > oldValL) {
+                      caretPosNew = newValL * 10;
+                    } else if (caretPosOld >= caretPosNew && caretPosOld !== oldValL) {
+                        if (!p.maskDigitPosMapOld[caretPosNew])  {
+                          var caretPos = caretPosNew;
+                          caretPosNew -= maskDigitsBeforeCaretAllOld - maskDigitsBeforeCaretAll;
+                          caretPosNew -= maskDigitsBeforeCaret;
+                          if (p.maskDigitPosMap[caretPosNew])  {
+                            caretPosNew = caretPos;
+                          }
+                        }
+                    }
+                    else if (caretPosNew > caretPosOld) {
+                        caretPosNew += maskDigitsBeforeCaretAll - maskDigitsBeforeCaretAllOld;
+                        caretPosNew += maskDigitsAfterCaret;
+                    }
+                }
+                return caretPosNew;
+            },
+            behaviour: function(e) {
+                e = e || window.event;
+                p.invalid = [];
+
+                var keyCode = el.data('mask-keycode');
+
+                if ($.inArray(keyCode, jMask.byPassKeys) === -1) {
+                    var newVal = p.getMasked(),
+                        caretPos = p.getCaret();
+
+                    // this is a compensation to devices/browsers that don't compensate
+                    // caret positioning the right way
+                    setTimeout(function() {
+                      p.setCaret(p.calculateCaretPosition());
+                    }, $.jMaskGlobals.keyStrokeCompensation);
+
+                    p.val(newVal);
+                    p.setCaret(caretPos);
+                    return p.callbacks(e);
+                }
+            },
+            getMasked: function(skipMaskChars, val) {
+                var buf = [],
+                    value = val === undefined ? p.val() : val + '',
+                    m = 0, maskLen = mask.length,
+                    v = 0, valLen = value.length,
+                    offset = 1, addMethod = 'push',
+                    resetPos = -1,
+                    maskDigitCount = 0,
+                    maskDigitPosArr = [],
+                    lastMaskChar,
+                    check;
+
+                if (options.reverse) {
+                    addMethod = 'unshift';
+                    offset = -1;
+                    lastMaskChar = 0;
+                    m = maskLen - 1;
+                    v = valLen - 1;
+                    check = function () {
+                        return m > -1 && v > -1;
+                    };
+                } else {
+                    lastMaskChar = maskLen - 1;
+                    check = function () {
+                        return m < maskLen && v < valLen;
+                    };
+                }
+
+                var lastUntranslatedMaskChar;
+                while (check()) {
+                    var maskDigit = mask.charAt(m),
+                        valDigit = value.charAt(v),
+                        translation = jMask.translation[maskDigit];
+
+                    if (translation) {
+                        if (valDigit.match(translation.pattern)) {
+                            buf[addMethod](valDigit);
+                             if (translation.recursive) {
+                                if (resetPos === -1) {
+                                    resetPos = m;
+                                } else if (m === lastMaskChar && m !== resetPos) {
+                                    m = resetPos - offset;
+                                }
+
+                                if (lastMaskChar === resetPos) {
+                                    m -= offset;
+                                }
+                            }
+                            m += offset;
+                        } else if (valDigit === lastUntranslatedMaskChar) {
+                            // matched the last untranslated (raw) mask character that we encountered
+                            // likely an insert offset the mask character from the last entry; fall
+                            // through and only increment v
+                            maskDigitCount--;
+                            lastUntranslatedMaskChar = undefined;
+                        } else if (translation.optional) {
+                            m += offset;
+                            v -= offset;
+                        } else if (translation.fallback) {
+                            buf[addMethod](translation.fallback);
+                            m += offset;
+                            v -= offset;
+                        } else {
+                          p.invalid.push({p: v, v: valDigit, e: translation.pattern});
+                        }
+                        v += offset;
+                    } else {
+                        if (!skipMaskChars) {
+                            buf[addMethod](maskDigit);
+                        }
+
+                        if (valDigit === maskDigit) {
+                            maskDigitPosArr.push(v);
+                            v += offset;
+                        } else {
+                            lastUntranslatedMaskChar = maskDigit;
+                            maskDigitPosArr.push(v + maskDigitCount);
+                            maskDigitCount++;
+                        }
+
+                        m += offset;
+                    }
+                }
+
+                var lastMaskCharDigit = mask.charAt(lastMaskChar);
+                if (maskLen === valLen + 1 && !jMask.translation[lastMaskCharDigit]) {
+                    buf.push(lastMaskCharDigit);
+                }
+
+                var newVal = buf.join('');
+                p.mapMaskdigitPositions(newVal, maskDigitPosArr, valLen);
+                return newVal;
+            },
+            mapMaskdigitPositions: function(newVal, maskDigitPosArr, valLen) {
+              var maskDiff = options.reverse ? newVal.length - valLen : 0;
+              p.maskDigitPosMap = {};
+              for (var i = 0; i < maskDigitPosArr.length; i++) {
+                p.maskDigitPosMap[maskDigitPosArr[i] + maskDiff] = 1;
+              }
+            },
+            callbacks: function (e) {
+                var val = p.val(),
+                    changed = val !== oldValue,
+                    defaultArgs = [val, e, el, options],
+                    callback = function(name, criteria, args) {
+                        if (typeof options[name] === 'function' && criteria) {
+                            options[name].apply(this, args);
+                        }
+                    };
+
+                callback('onChange', changed === true, defaultArgs);
+                callback('onKeyPress', changed === true, defaultArgs);
+                callback('onComplete', val.length === mask.length, defaultArgs);
+                callback('onInvalid', p.invalid.length > 0, [val, e, el, p.invalid, options]);
+            }
+        };
+
+        el = $(el);
+        var jMask = this, oldValue = p.val(), regexMask;
+
+        mask = typeof mask === 'function' ? mask(p.val(), undefined, el,  options) : mask;
+
+        // public methods
+        jMask.mask = mask;
+        jMask.options = options;
+        jMask.remove = function() {
+            var caret = p.getCaret();
+            if (jMask.options.placeholder) {
+                el.removeAttr('placeholder');
+            }
+            if (el.data('mask-maxlength')) {
+                el.removeAttr('maxlength');
+            }
+            p.destroyEvents();
+            p.val(jMask.getCleanVal());
+            p.setCaret(caret);
+            return el;
+        };
+
+        // get value without mask
+        jMask.getCleanVal = function() {
+           return p.getMasked(true);
+        };
+
+        // get masked value without the value being in the input or element
+        jMask.getMaskedVal = function(val) {
+           return p.getMasked(false, val);
+        };
+
+       jMask.init = function(onlyMask) {
+            onlyMask = onlyMask || false;
+            options = options || {};
+
+            jMask.clearIfNotMatch  = $.jMaskGlobals.clearIfNotMatch;
+            jMask.byPassKeys       = $.jMaskGlobals.byPassKeys;
+            jMask.translation      = $.extend({}, $.jMaskGlobals.translation, options.translation);
+
+            jMask = $.extend(true, {}, jMask, options);
+
+            regexMask = p.getRegexMask();
+
+            if (onlyMask) {
+                p.events();
+                p.val(p.getMasked());
+            } else {
+                if (options.placeholder) {
+                    el.attr('placeholder' , options.placeholder);
+                }
+
+                // this is necessary, otherwise if the user submit the form
+                // and then press the "back" button, the autocomplete will erase
+                // the data. Works fine on IE9+, FF, Opera, Safari.
+                if (el.data('mask')) {
+                  el.attr('autocomplete', 'off');
+                }
+
+                // detect if is necessary let the user type freely.
+                // for is a lot faster than forEach.
+                for (var i = 0, maxlength = true; i < mask.length; i++) {
+                    var translation = jMask.translation[mask.charAt(i)];
+                    if (translation && translation.recursive) {
+                        maxlength = false;
+                        break;
+                    }
+                }
+
+                if (maxlength) {
+                    el.attr('maxlength', mask.length).data('mask-maxlength', true);
+                }
+
+                p.destroyEvents();
+                p.events();
+
+                var caret = p.getCaret();
+                p.val(p.getMasked());
+                p.setCaret(caret);
+            }
+        };
+
+        jMask.init(!el.is('input'));
+    };
+
+    $.maskWatchers = {};
+    var HTMLAttributes = function () {
+        var input = $(this),
+            options = {},
+            prefix = 'data-mask-',
+            mask = input.attr('data-mask');
+
+        if (input.attr(prefix + 'reverse')) {
+            options.reverse = true;
+        }
+
+        if (input.attr(prefix + 'clearifnotmatch')) {
+            options.clearIfNotMatch = true;
+        }
+
+        if (input.attr(prefix + 'selectonfocus') === 'true') {
+           options.selectOnFocus = true;
+        }
+
+        if (notSameMaskObject(input, mask, options)) {
+            return input.data('mask', new Mask(this, mask, options));
+        }
+    },
+    notSameMaskObject = function(field, mask, options) {
+        options = options || {};
+        var maskObject = $(field).data('mask'),
+            stringify = JSON.stringify,
+            value = $(field).val() || $(field).text();
+        try {
+            if (typeof mask === 'function') {
+                mask = mask(value);
+            }
+            return typeof maskObject !== 'object' || stringify(maskObject.options) !== stringify(options) || maskObject.mask !== mask;
+        } catch (e) {}
+    },
+    eventSupported = function(eventName) {
+        var el = document.createElement('div'), isSupported;
+
+        eventName = 'on' + eventName;
+        isSupported = (eventName in el);
+
+        if ( !isSupported ) {
+            el.setAttribute(eventName, 'return;');
+            isSupported = typeof el[eventName] === 'function';
+        }
+        el = null;
+
+        return isSupported;
+    };
+
+    $.fn.mask = function(mask, options) {
+        options = options || {};
+        var selector = this.selector,
+            globals = $.jMaskGlobals,
+            interval = globals.watchInterval,
+            watchInputs = options.watchInputs || globals.watchInputs,
+            maskFunction = function() {
+                if (notSameMaskObject(this, mask, options)) {
+                    return $(this).data('mask', new Mask(this, mask, options));
+                }
+            };
+
+        $(this).each(maskFunction);
+
+        if (selector && selector !== '' && watchInputs) {
+            clearInterval($.maskWatchers[selector]);
+            $.maskWatchers[selector] = setInterval(function(){
+                $(document).find(selector).each(maskFunction);
+            }, interval);
+        }
+        return this;
+    };
+
+    $.fn.masked = function(val) {
+        return this.data('mask').getMaskedVal(val);
+    };
+
+    $.fn.unmask = function() {
+        clearInterval($.maskWatchers[this.selector]);
+        delete $.maskWatchers[this.selector];
+        return this.each(function() {
+            var dataMask = $(this).data('mask');
+            if (dataMask) {
+                dataMask.remove().removeData('mask');
+            }
+        });
+    };
+
+    $.fn.cleanVal = function() {
+        return this.data('mask').getCleanVal();
+    };
+
+    $.applyDataMask = function(selector) {
+        selector = selector || $.jMaskGlobals.maskElements;
+        var $selector = (selector instanceof $) ? selector : $(selector);
+        $selector.filter($.jMaskGlobals.dataMaskAttr).each(HTMLAttributes);
+    };
+
+    var globals = {
+        maskElements: 'input,td,span,div',
+        dataMaskAttr: '*[data-mask]',
+        dataMask: true,
+        watchInterval: 300,
+        watchInputs: true,
+        keyStrokeCompensation: 10,
+        // old versions of chrome dont work great with input event
+        useInput: !/Chrome\/[2-4][0-9]|SamsungBrowser/.test(window.navigator.userAgent) && eventSupported('input'),
+        watchDataMask: false,
+        byPassKeys: [9, 16, 17, 18, 36, 37, 38, 39, 40, 91],
+        translation: {
+            '0': {pattern: /\d/},
+            '9': {pattern: /\d/, optional: true},
+            '#': {pattern: /\d/, recursive: true},
+            'A': {pattern: /[a-zA-Z0-9]/},
+            'S': {pattern: /[a-zA-Z]/}
+        }
+    };
+
+    $.jMaskGlobals = $.jMaskGlobals || {};
+    globals = $.jMaskGlobals = $.extend(true, {}, globals, $.jMaskGlobals);
+
+    // looking for inputs with data-mask attribute
+    if (globals.dataMask) {
+        $.applyDataMask();
+    }
+
+    setInterval(function() {
+        if ($.jMaskGlobals.watchDataMask) {
+            $.applyDataMask();
+        }
+    }, globals.watchInterval);
+}, window.jQuery, window.Zepto));
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/dist/jquery.mask.min.js b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/dist/jquery.mask.min.js
new file mode 100644
index 0000000..ce86d08
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/dist/jquery.mask.min.js
@@ -0,0 +1,19 @@
+// jQuery Mask Plugin v1.14.15
+// github.com/igorescobar/jQuery-Mask-Plugin
+var $jscomp={scope:{},findInternal:function(a,l,d){a instanceof String&&(a=String(a));for(var p=a.length,h=0;h<p;h++){var b=a[h];if(l.call(d,b,h,a))return{i:h,v:b}}return{i:-1,v:void 0}}};$jscomp.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(a,l,d){if(d.get||d.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[l]=d.value)};
+$jscomp.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global&&null!=global?global:a};$jscomp.global=$jscomp.getGlobal(this);$jscomp.polyfill=function(a,l,d,p){if(l){d=$jscomp.global;a=a.split(".");for(p=0;p<a.length-1;p++){var h=a[p];h in d||(d[h]={});d=d[h]}a=a[a.length-1];p=d[a];l=l(p);l!=p&&null!=l&&$jscomp.defineProperty(d,a,{configurable:!0,writable:!0,value:l})}};
+$jscomp.polyfill("Array.prototype.find",function(a){return a?a:function(a,d){return $jscomp.findInternal(this,a,d).v}},"es6-impl","es3");
+(function(a,l,d){"function"===typeof define&&define.amd?define(["jquery"],a):"object"===typeof exports?module.exports=a(require("jquery")):a(l||d)})(function(a){var l=function(b,e,f){var c={invalid:[],getCaret:function(){try{var a,r=0,g=b.get(0),e=document.selection,f=g.selectionStart;if(e&&-1===navigator.appVersion.indexOf("MSIE 10"))a=e.createRange(),a.moveStart("character",-c.val().length),r=a.text.length;else if(f||"0"===f)r=f;return r}catch(C){}},setCaret:function(a){try{if(b.is(":focus")){var c,
+g=b.get(0);g.setSelectionRange?g.setSelectionRange(a,a):(c=g.createTextRange(),c.collapse(!0),c.moveEnd("character",a),c.moveStart("character",a),c.select())}}catch(B){}},events:function(){b.on("keydown.mask",function(a){b.data("mask-keycode",a.keyCode||a.which);b.data("mask-previus-value",b.val());b.data("mask-previus-caret-pos",c.getCaret());c.maskDigitPosMapOld=c.maskDigitPosMap}).on(a.jMaskGlobals.useInput?"input.mask":"keyup.mask",c.behaviour).on("paste.mask drop.mask",function(){setTimeout(function(){b.keydown().keyup()},
+100)}).on("change.mask",function(){b.data("changed",!0)}).on("blur.mask",function(){d===c.val()||b.data("changed")||b.trigger("change");b.data("changed",!1)}).on("blur.mask",function(){d=c.val()}).on("focus.mask",function(b){!0===f.selectOnFocus&&a(b.target).select()}).on("focusout.mask",function(){f.clearIfNotMatch&&!h.test(c.val())&&c.val("")})},getRegexMask:function(){for(var a=[],b,c,f,n,d=0;d<e.length;d++)(b=m.translation[e.charAt(d)])?(c=b.pattern.toString().replace(/.{1}$|^.{1}/g,""),f=b.optional,
+(b=b.recursive)?(a.push(e.charAt(d)),n={digit:e.charAt(d),pattern:c}):a.push(f||b?c+"?":c)):a.push(e.charAt(d).replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&"));a=a.join("");n&&(a=a.replace(new RegExp("("+n.digit+"(.*"+n.digit+")?)"),"($1)?").replace(new RegExp(n.digit,"g"),n.pattern));return new RegExp(a)},destroyEvents:function(){b.off("input keydown keyup paste drop blur focusout ".split(" ").join(".mask "))},val:function(a){var c=b.is("input")?"val":"text";if(0<arguments.length){if(b[c]()!==a)b[c](a);
+c=b}else c=b[c]();return c},calculateCaretPosition:function(){var a=b.data("mask-previus-value")||"",e=c.getMasked(),g=c.getCaret();if(a!==e){var f=b.data("mask-previus-caret-pos")||0,e=e.length,d=a.length,m=a=0,h=0,l=0,k;for(k=g;k<e&&c.maskDigitPosMap[k];k++)m++;for(k=g-1;0<=k&&c.maskDigitPosMap[k];k--)a++;for(k=g-1;0<=k;k--)c.maskDigitPosMap[k]&&h++;for(k=f-1;0<=k;k--)c.maskDigitPosMapOld[k]&&l++;g>d?g=10*e:f>=g&&f!==d?c.maskDigitPosMapOld[g]||(f=g,g=g-(l-h)-a,c.maskDigitPosMap[g]&&(g=f)):g>f&&
+(g=g+(h-l)+m)}return g},behaviour:function(f){f=f||window.event;c.invalid=[];var e=b.data("mask-keycode");if(-1===a.inArray(e,m.byPassKeys)){var e=c.getMasked(),g=c.getCaret();setTimeout(function(){c.setCaret(c.calculateCaretPosition())},a.jMaskGlobals.keyStrokeCompensation);c.val(e);c.setCaret(g);return c.callbacks(f)}},getMasked:function(a,b){var g=[],d=void 0===b?c.val():b+"",n=0,h=e.length,q=0,l=d.length,k=1,r="push",p=-1,t=0,y=[],v,z;f.reverse?(r="unshift",k=-1,v=0,n=h-1,q=l-1,z=function(){return-1<
+n&&-1<q}):(v=h-1,z=function(){return n<h&&q<l});for(var A;z();){var x=e.charAt(n),w=d.charAt(q),u=m.translation[x];if(u)w.match(u.pattern)?(g[r](w),u.recursive&&(-1===p?p=n:n===v&&n!==p&&(n=p-k),v===p&&(n-=k)),n+=k):w===A?(t--,A=void 0):u.optional?(n+=k,q-=k):u.fallback?(g[r](u.fallback),n+=k,q-=k):c.invalid.push({p:q,v:w,e:u.pattern}),q+=k;else{if(!a)g[r](x);w===x?(y.push(q),q+=k):(A=x,y.push(q+t),t++);n+=k}}d=e.charAt(v);h!==l+1||m.translation[d]||g.push(d);g=g.join("");c.mapMaskdigitPositions(g,
+y,l);return g},mapMaskdigitPositions:function(a,b,e){a=f.reverse?a.length-e:0;c.maskDigitPosMap={};for(e=0;e<b.length;e++)c.maskDigitPosMap[b[e]+a]=1},callbacks:function(a){var h=c.val(),g=h!==d,m=[h,a,b,f],q=function(a,b,c){"function"===typeof f[a]&&b&&f[a].apply(this,c)};q("onChange",!0===g,m);q("onKeyPress",!0===g,m);q("onComplete",h.length===e.length,m);q("onInvalid",0<c.invalid.length,[h,a,b,c.invalid,f])}};b=a(b);var m=this,d=c.val(),h;e="function"===typeof e?e(c.val(),void 0,b,f):e;m.mask=
+e;m.options=f;m.remove=function(){var a=c.getCaret();m.options.placeholder&&b.removeAttr("placeholder");b.data("mask-maxlength")&&b.removeAttr("maxlength");c.destroyEvents();c.val(m.getCleanVal());c.setCaret(a);return b};m.getCleanVal=function(){return c.getMasked(!0)};m.getMaskedVal=function(a){return c.getMasked(!1,a)};m.init=function(d){d=d||!1;f=f||{};m.clearIfNotMatch=a.jMaskGlobals.clearIfNotMatch;m.byPassKeys=a.jMaskGlobals.byPassKeys;m.translation=a.extend({},a.jMaskGlobals.translation,f.translation);
+m=a.extend(!0,{},m,f);h=c.getRegexMask();if(d)c.events(),c.val(c.getMasked());else{f.placeholder&&b.attr("placeholder",f.placeholder);b.data("mask")&&b.attr("autocomplete","off");d=0;for(var l=!0;d<e.length;d++){var g=m.translation[e.charAt(d)];if(g&&g.recursive){l=!1;break}}l&&b.attr("maxlength",e.length).data("mask-maxlength",!0);c.destroyEvents();c.events();d=c.getCaret();c.val(c.getMasked());c.setCaret(d)}};m.init(!b.is("input"))};a.maskWatchers={};var d=function(){var b=a(this),e={},f=b.attr("data-mask");
+b.attr("data-mask-reverse")&&(e.reverse=!0);b.attr("data-mask-clearifnotmatch")&&(e.clearIfNotMatch=!0);"true"===b.attr("data-mask-selectonfocus")&&(e.selectOnFocus=!0);if(p(b,f,e))return b.data("mask",new l(this,f,e))},p=function(b,e,f){f=f||{};var c=a(b).data("mask"),d=JSON.stringify;b=a(b).val()||a(b).text();try{return"function"===typeof e&&(e=e(b)),"object"!==typeof c||d(c.options)!==d(f)||c.mask!==e}catch(t){}},h=function(a){var b=document.createElement("div"),d;a="on"+a;d=a in b;d||(b.setAttribute(a,
+"return;"),d="function"===typeof b[a]);return d};a.fn.mask=function(b,d){d=d||{};var e=this.selector,c=a.jMaskGlobals,h=c.watchInterval,c=d.watchInputs||c.watchInputs,t=function(){if(p(this,b,d))return a(this).data("mask",new l(this,b,d))};a(this).each(t);e&&""!==e&&c&&(clearInterval(a.maskWatchers[e]),a.maskWatchers[e]=setInterval(function(){a(document).find(e).each(t)},h));return this};a.fn.masked=function(a){return this.data("mask").getMaskedVal(a)};a.fn.unmask=function(){clearInterval(a.maskWatchers[this.selector]);
+delete a.maskWatchers[this.selector];return this.each(function(){var b=a(this).data("mask");b&&b.remove().removeData("mask")})};a.fn.cleanVal=function(){return this.data("mask").getCleanVal()};a.applyDataMask=function(b){b=b||a.jMaskGlobals.maskElements;(b instanceof a?b:a(b)).filter(a.jMaskGlobals.dataMaskAttr).each(d)};h={maskElements:"input,td,span,div",dataMaskAttr:"*[data-mask]",dataMask:!0,watchInterval:300,watchInputs:!0,keyStrokeCompensation:10,useInput:!/Chrome\/[2-4][0-9]|SamsungBrowser/.test(window.navigator.userAgent)&&
+h("input"),watchDataMask:!1,byPassKeys:[9,16,17,18,36,37,38,39,40,91],translation:{0:{pattern:/\d/},9:{pattern:/\d/,optional:!0},"#":{pattern:/\d/,recursive:!0},A:{pattern:/[a-zA-Z0-9]/},S:{pattern:/[a-zA-Z]/}}};a.jMaskGlobals=a.jMaskGlobals||{};h=a.jMaskGlobals=a.extend(!0,{},h,a.jMaskGlobals);h.dataMask&&a.applyDataMask();setInterval(function(){a.jMaskGlobals.watchDataMask&&a.applyDataMask()},h.watchInterval)},window.jQuery,window.Zepto);
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/docker-compose.yml b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/docker-compose.yml
new file mode 100644
index 0000000..e4e155c
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/docker-compose.yml
@@ -0,0 +1,4 @@
+web:
+  build: .
+  volumes:
+    - ./:/app/jquery-mask-plugin
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/package-lock.json b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/package-lock.json
new file mode 100644
index 0000000..d2c1381
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/package-lock.json
@@ -0,0 +1,2351 @@
+{
+  "name": "jquery-mask-plugin",
+  "version": "1.14.12",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "abbrev": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+      "dev": true
+    },
+    "accepts": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
+      "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=",
+      "dev": true,
+      "requires": {
+        "mime-types": "2.1.17",
+        "negotiator": "0.6.1"
+      }
+    },
+    "ajv": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+      "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
+      "dev": true,
+      "requires": {
+        "co": "4.6.0",
+        "json-stable-stringify": "1.0.1"
+      }
+    },
+    "ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+      "dev": true
+    },
+    "ansi-styles": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+      "dev": true
+    },
+    "argparse": {
+      "version": "0.1.16",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz",
+      "integrity": "sha1-z9AeD7uj1srtBJ+9dY1A9lGW9Xw=",
+      "dev": true,
+      "requires": {
+        "underscore": "1.7.0",
+        "underscore.string": "2.4.0"
+      },
+      "dependencies": {
+        "underscore.string": {
+          "version": "2.4.0",
+          "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz",
+          "integrity": "sha1-jN2PusTi0uoefi6Al8QvRCKA+Fs=",
+          "dev": true
+        }
+      }
+    },
+    "array-differ": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
+      "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=",
+      "dev": true
+    },
+    "array-find-index": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+      "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
+      "dev": true
+    },
+    "array-union": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+      "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+      "dev": true,
+      "requires": {
+        "array-uniq": "1.0.3"
+      }
+    },
+    "array-uniq": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+      "dev": true
+    },
+    "arrify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+      "dev": true
+    },
+    "asn1": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+      "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
+      "dev": true
+    },
+    "assert-plus": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+      "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+      "dev": true
+    },
+    "async": {
+      "version": "0.1.22",
+      "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz",
+      "integrity": "sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE=",
+      "dev": true
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "dev": true
+    },
+    "aws-sign2": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+      "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
+      "dev": true
+    },
+    "aws4": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+      "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
+      "dev": true
+    },
+    "balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+      "dev": true
+    },
+    "basic-auth": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz",
+      "integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "batch": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+      "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
+      "dev": true
+    },
+    "bcrypt-pbkdf": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+      "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "tweetnacl": "0.14.5"
+      }
+    },
+    "boom": {
+      "version": "2.10.1",
+      "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+      "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+      "dev": true,
+      "requires": {
+        "hoek": "2.16.3"
+      }
+    },
+    "brace-expansion": {
+      "version": "1.1.8",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+      "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+      "dev": true,
+      "requires": {
+        "balanced-match": "1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "browserify-zlib": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz",
+      "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=",
+      "dev": true,
+      "requires": {
+        "pako": "0.2.9"
+      }
+    },
+    "builtin-modules": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+      "dev": true
+    },
+    "camelcase": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+      "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
+      "dev": true
+    },
+    "camelcase-keys": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+      "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+      "dev": true,
+      "requires": {
+        "camelcase": "2.1.1",
+        "map-obj": "1.0.1"
+      }
+    },
+    "caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+      "dev": true
+    },
+    "chalk": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+      "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "2.2.1",
+        "escape-string-regexp": "1.0.5",
+        "has-ansi": "2.0.0",
+        "strip-ansi": "3.0.1",
+        "supports-color": "2.0.0"
+      }
+    },
+    "cli": {
+      "version": "0.6.6",
+      "resolved": "https://registry.npmjs.org/cli/-/cli-0.6.6.tgz",
+      "integrity": "sha1-Aq1Eo4Cr8nraxebwzdewQ9dMU+M=",
+      "dev": true,
+      "requires": {
+        "exit": "0.1.2",
+        "glob": "3.2.11"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "3.2.11",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz",
+          "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=",
+          "dev": true,
+          "requires": {
+            "inherits": "2.0.3",
+            "minimatch": "0.3.0"
+          }
+        },
+        "minimatch": {
+          "version": "0.3.0",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz",
+          "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=",
+          "dev": true,
+          "requires": {
+            "lru-cache": "2.7.3",
+            "sigmund": "1.0.1"
+          }
+        }
+      }
+    },
+    "co": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+      "dev": true
+    },
+    "coffee-script": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz",
+      "integrity": "sha1-FQ1rTLUiiUNp7+1qIQHCC8f0pPQ=",
+      "dev": true
+    },
+    "colors": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
+      "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=",
+      "dev": true
+    },
+    "combined-stream": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+      "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
+      "dev": true,
+      "requires": {
+        "delayed-stream": "1.0.0"
+      }
+    },
+    "commander": {
+      "version": "2.12.2",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz",
+      "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==",
+      "dev": true
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "dev": true
+    },
+    "concat-stream": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
+      "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.3",
+        "typedarray": "0.0.6"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.3",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
+          "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "1.0.0",
+            "process-nextick-args": "1.0.7",
+            "safe-buffer": "5.1.1",
+            "string_decoder": "1.0.3",
+            "util-deprecate": "1.0.2"
+          }
+        },
+        "string_decoder": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+          "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "5.1.1"
+          }
+        }
+      }
+    },
+    "connect": {
+      "version": "3.6.5",
+      "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.5.tgz",
+      "integrity": "sha1-+43ee6B2OHfQ7J352sC0tA5yx9o=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "finalhandler": "1.0.6",
+        "parseurl": "1.3.2",
+        "utils-merge": "1.0.1"
+      }
+    },
+    "connect-livereload": {
+      "version": "0.5.4",
+      "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.5.4.tgz",
+      "integrity": "sha1-gBV9E3HJ83zBQDmrGJWXDRGdw7w=",
+      "dev": true
+    },
+    "console-browserify": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
+      "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
+      "dev": true,
+      "requires": {
+        "date-now": "0.1.4"
+      }
+    },
+    "core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+      "dev": true
+    },
+    "cryptiles": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+      "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+      "dev": true,
+      "requires": {
+        "boom": "2.10.1"
+      }
+    },
+    "currently-unhandled": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+      "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+      "dev": true,
+      "requires": {
+        "array-find-index": "1.0.2"
+      }
+    },
+    "dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0"
+      },
+      "dependencies": {
+        "assert-plus": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+          "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+          "dev": true
+        }
+      }
+    },
+    "date-now": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
+      "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
+      "dev": true
+    },
+    "date-time": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/date-time/-/date-time-1.1.0.tgz",
+      "integrity": "sha1-GIdtC9pMGf5w3Tv0sDTygbEqQLY=",
+      "dev": true,
+      "requires": {
+        "time-zone": "0.1.0"
+      }
+    },
+    "dateformat": {
+      "version": "1.0.2-1.2.3",
+      "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz",
+      "integrity": "sha1-sCIMAt6YYXQztyhRz0fePfLNvuk=",
+      "dev": true
+    },
+    "debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "requires": {
+        "ms": "2.0.0"
+      }
+    },
+    "decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "dev": true
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+      "dev": true
+    },
+    "depd": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+      "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=",
+      "dev": true
+    },
+    "destroy": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+      "dev": true
+    },
+    "dom-serializer": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
+      "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "1.1.3",
+        "entities": "1.1.1"
+      },
+      "dependencies": {
+        "domelementtype": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
+          "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=",
+          "dev": true
+        },
+        "entities": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
+          "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=",
+          "dev": true
+        }
+      }
+    },
+    "domelementtype": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
+      "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=",
+      "dev": true
+    },
+    "domhandler": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz",
+      "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "1.3.0"
+      }
+    },
+    "domutils": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
+      "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
+      "dev": true,
+      "requires": {
+        "dom-serializer": "0.1.0",
+        "domelementtype": "1.3.0"
+      }
+    },
+    "ecc-jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+      "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "jsbn": "0.1.1"
+      }
+    },
+    "ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+      "dev": true
+    },
+    "encodeurl": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
+      "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=",
+      "dev": true
+    },
+    "entities": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
+      "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=",
+      "dev": true
+    },
+    "error-ex": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
+      "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
+      "dev": true,
+      "requires": {
+        "is-arrayish": "0.2.1"
+      }
+    },
+    "es6-promise": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.1.1.tgz",
+      "integrity": "sha512-OaU1hHjgJf+b0NzsxCg7NdIYERD6Hy/PEmFLTjw+b65scuisG3Kt4QoTvJ66BBkPZ581gr0kpoVzKnxniM8nng==",
+      "dev": true
+    },
+    "escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+      "dev": true
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+      "dev": true
+    },
+    "esprima": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
+      "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=",
+      "dev": true
+    },
+    "etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+      "dev": true
+    },
+    "eventemitter2": {
+      "version": "0.4.14",
+      "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
+      "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=",
+      "dev": true
+    },
+    "exit": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+      "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+      "dev": true
+    },
+    "extend": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+      "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+      "dev": true
+    },
+    "extract-zip": {
+      "version": "1.6.6",
+      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz",
+      "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=",
+      "dev": true,
+      "requires": {
+        "concat-stream": "1.6.0",
+        "debug": "2.6.9",
+        "mkdirp": "0.5.0",
+        "yauzl": "2.4.1"
+      }
+    },
+    "extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+      "dev": true
+    },
+    "fd-slicer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
+      "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
+      "dev": true,
+      "requires": {
+        "pend": "1.2.0"
+      }
+    },
+    "figures": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+      "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "1.0.5",
+        "object-assign": "4.1.1"
+      }
+    },
+    "finalhandler": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.6.tgz",
+      "integrity": "sha1-AHrqM9Gk0+QgF/YkhIrVjSEvgU8=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "encodeurl": "1.0.1",
+        "escape-html": "1.0.3",
+        "on-finished": "2.3.0",
+        "parseurl": "1.3.2",
+        "statuses": "1.3.1",
+        "unpipe": "1.0.0"
+      }
+    },
+    "find-up": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+      "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+      "dev": true,
+      "requires": {
+        "path-exists": "2.1.0",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "findup-sync": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz",
+      "integrity": "sha1-fz56l7gjksZTvwZYm9hRkOk8NoM=",
+      "dev": true,
+      "requires": {
+        "glob": "3.2.11",
+        "lodash": "2.4.2"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "3.2.11",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz",
+          "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=",
+          "dev": true,
+          "requires": {
+            "inherits": "2.0.3",
+            "minimatch": "0.3.0"
+          }
+        },
+        "lodash": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
+          "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
+          "dev": true
+        },
+        "minimatch": {
+          "version": "0.3.0",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz",
+          "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=",
+          "dev": true,
+          "requires": {
+            "lru-cache": "2.7.3",
+            "sigmund": "1.0.1"
+          }
+        }
+      }
+    },
+    "forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+      "dev": true
+    },
+    "form-data": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
+      "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+      "dev": true,
+      "requires": {
+        "asynckit": "0.4.0",
+        "combined-stream": "1.0.5",
+        "mime-types": "2.1.17"
+      }
+    },
+    "fresh": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+      "dev": true
+    },
+    "fs-extra": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
+      "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "jsonfile": "2.4.0",
+        "klaw": "1.3.1"
+      },
+      "dependencies": {
+        "graceful-fs": {
+          "version": "4.1.11",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+          "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+          "dev": true
+        }
+      }
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "dev": true
+    },
+    "get-stdin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+      "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+      "dev": true
+    },
+    "getobject": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz",
+      "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=",
+      "dev": true
+    },
+    "getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0"
+      },
+      "dependencies": {
+        "assert-plus": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+          "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+          "dev": true
+        }
+      }
+    },
+    "glob": {
+      "version": "3.1.21",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz",
+      "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "1.2.3",
+        "inherits": "1.0.2",
+        "minimatch": "0.2.14"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz",
+          "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=",
+          "dev": true
+        }
+      }
+    },
+    "graceful-fs": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz",
+      "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=",
+      "dev": true
+    },
+    "grunt": {
+      "version": "0.4.5",
+      "resolved": "https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz",
+      "integrity": "sha1-VpN81RlDJK3/bSB2MYMqnWuk5/A=",
+      "dev": true,
+      "requires": {
+        "async": "0.1.22",
+        "coffee-script": "1.3.3",
+        "colors": "0.6.2",
+        "dateformat": "1.0.2-1.2.3",
+        "eventemitter2": "0.4.14",
+        "exit": "0.1.2",
+        "findup-sync": "0.1.3",
+        "getobject": "0.1.0",
+        "glob": "3.1.21",
+        "grunt-legacy-log": "0.1.3",
+        "grunt-legacy-util": "0.2.0",
+        "hooker": "0.2.3",
+        "iconv-lite": "0.2.11",
+        "js-yaml": "2.0.5",
+        "lodash": "0.9.2",
+        "minimatch": "0.2.14",
+        "nopt": "1.0.10",
+        "rimraf": "2.2.8",
+        "underscore.string": "2.2.1",
+        "which": "1.0.9"
+      }
+    },
+    "grunt-contrib-connect": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/grunt-contrib-connect/-/grunt-contrib-connect-1.0.2.tgz",
+      "integrity": "sha1-XPkzuRpnOGBEJzwLJERgPNmIebo=",
+      "dev": true,
+      "requires": {
+        "async": "1.5.2",
+        "connect": "3.6.5",
+        "connect-livereload": "0.5.4",
+        "http2": "3.3.7",
+        "morgan": "1.9.0",
+        "opn": "4.0.2",
+        "portscanner": "1.2.0",
+        "serve-index": "1.9.1",
+        "serve-static": "1.13.1"
+      },
+      "dependencies": {
+        "async": {
+          "version": "1.5.2",
+          "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+          "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+          "dev": true
+        }
+      }
+    },
+    "grunt-contrib-jshint": {
+      "version": "0.11.3",
+      "resolved": "https://registry.npmjs.org/grunt-contrib-jshint/-/grunt-contrib-jshint-0.11.3.tgz",
+      "integrity": "sha1-gDaBgdzNVRGG5bg4XAEc7iTWQKA=",
+      "dev": true,
+      "requires": {
+        "hooker": "0.2.3",
+        "jshint": "2.8.0"
+      }
+    },
+    "grunt-contrib-qunit": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/grunt-contrib-qunit/-/grunt-contrib-qunit-2.0.0.tgz",
+      "integrity": "sha1-VKUbSyyE/uYsO34AFFySjR7Ct+w=",
+      "dev": true,
+      "requires": {
+        "grunt-lib-phantomjs": "1.1.0"
+      }
+    },
+    "grunt-contrib-uglify": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-3.2.1.tgz",
+      "integrity": "sha512-xBPwg8wuA/m+HiSh2uMADuadKEnFQt9N5OhEy35vIl945yG6095oY1H1Og3ucg0wBSOieIBn3raqStvIcwKqHg==",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "maxmin": "1.1.0",
+        "uglify-js": "3.2.2",
+        "uri-path": "1.0.0"
+      }
+    },
+    "grunt-legacy-log": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-0.1.3.tgz",
+      "integrity": "sha1-7ClCboAwIa9ZAp+H0vnNczWgVTE=",
+      "dev": true,
+      "requires": {
+        "colors": "0.6.2",
+        "grunt-legacy-log-utils": "0.1.1",
+        "hooker": "0.2.3",
+        "lodash": "2.4.2",
+        "underscore.string": "2.3.3"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
+          "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
+          "dev": true
+        },
+        "underscore.string": {
+          "version": "2.3.3",
+          "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz",
+          "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=",
+          "dev": true
+        }
+      }
+    },
+    "grunt-legacy-log-utils": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-0.1.1.tgz",
+      "integrity": "sha1-wHBrndkGThFvNvI/5OawSGcsD34=",
+      "dev": true,
+      "requires": {
+        "colors": "0.6.2",
+        "lodash": "2.4.2",
+        "underscore.string": "2.3.3"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
+          "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
+          "dev": true
+        },
+        "underscore.string": {
+          "version": "2.3.3",
+          "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz",
+          "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=",
+          "dev": true
+        }
+      }
+    },
+    "grunt-legacy-util": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-0.2.0.tgz",
+      "integrity": "sha1-kzJIhNv343qf98Am3/RR2UqeVUs=",
+      "dev": true,
+      "requires": {
+        "async": "0.1.22",
+        "exit": "0.1.2",
+        "getobject": "0.1.0",
+        "hooker": "0.2.3",
+        "lodash": "0.9.2",
+        "underscore.string": "2.2.1",
+        "which": "1.0.9"
+      }
+    },
+    "grunt-lib-phantomjs": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/grunt-lib-phantomjs/-/grunt-lib-phantomjs-1.1.0.tgz",
+      "integrity": "sha1-np7c3Z/S3UDgwYHJQ3HVcqpe6tI=",
+      "dev": true,
+      "requires": {
+        "eventemitter2": "0.4.14",
+        "phantomjs-prebuilt": "2.1.16",
+        "rimraf": "2.6.2",
+        "semver": "5.4.1",
+        "temporary": "0.0.8"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.1.2",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "1.0.0",
+            "inflight": "1.0.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.1"
+          }
+        },
+        "minimatch": {
+          "version": "3.0.4",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "1.1.8"
+          }
+        },
+        "rimraf": {
+          "version": "2.6.2",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+          "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+          "dev": true,
+          "requires": {
+            "glob": "7.1.2"
+          }
+        }
+      }
+    },
+    "gzip-size": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-1.0.0.tgz",
+      "integrity": "sha1-Zs+LEBBHInuVus5uodoMF37Vwi8=",
+      "dev": true,
+      "requires": {
+        "browserify-zlib": "0.1.4",
+        "concat-stream": "1.6.0"
+      }
+    },
+    "har-schema": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
+      "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=",
+      "dev": true
+    },
+    "har-validator": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz",
+      "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=",
+      "dev": true,
+      "requires": {
+        "ajv": "4.11.8",
+        "har-schema": "1.0.5"
+      }
+    },
+    "has-ansi": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "2.1.1"
+      }
+    },
+    "hasha": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz",
+      "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=",
+      "dev": true,
+      "requires": {
+        "is-stream": "1.1.0",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "hawk": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+      "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+      "dev": true,
+      "requires": {
+        "boom": "2.10.1",
+        "cryptiles": "2.0.5",
+        "hoek": "2.16.3",
+        "sntp": "1.0.9"
+      }
+    },
+    "hoek": {
+      "version": "2.16.3",
+      "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+      "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+      "dev": true
+    },
+    "hooker": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
+      "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=",
+      "dev": true
+    },
+    "hosted-git-info": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
+      "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==",
+      "dev": true
+    },
+    "htmlparser2": {
+      "version": "3.8.3",
+      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
+      "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "1.3.0",
+        "domhandler": "2.3.0",
+        "domutils": "1.5.1",
+        "entities": "1.0.0",
+        "readable-stream": "1.1.14"
+      }
+    },
+    "http-errors": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+      "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
+      "dev": true,
+      "requires": {
+        "depd": "1.1.1",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.0.3",
+        "statuses": "1.3.1"
+      }
+    },
+    "http-signature": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+      "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "0.2.0",
+        "jsprim": "1.4.1",
+        "sshpk": "1.13.1"
+      }
+    },
+    "http2": {
+      "version": "3.3.7",
+      "resolved": "https://registry.npmjs.org/http2/-/http2-3.3.7.tgz",
+      "integrity": "sha512-puSi8M8WNlFJm9Pk4c/Mbz9Gwparuj3gO9/RRO5zv6piQ0FY+9Qywp0PdWshYgsMJSalixFY7eC6oPu0zRxLAQ==",
+      "dev": true
+    },
+    "iconv-lite": {
+      "version": "0.2.11",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz",
+      "integrity": "sha1-HOYKOleGSiktEyH/RgnKS7llrcg=",
+      "dev": true
+    },
+    "indent-string": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+      "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
+      "dev": true,
+      "requires": {
+        "repeating": "2.0.1"
+      }
+    },
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "dev": true,
+      "requires": {
+        "once": "1.4.0",
+        "wrappy": "1.0.2"
+      }
+    },
+    "inherits": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+      "dev": true
+    },
+    "is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "dev": true
+    },
+    "is-builtin-module": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+      "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+      "dev": true,
+      "requires": {
+        "builtin-modules": "1.1.1"
+      }
+    },
+    "is-finite": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+      "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+      "dev": true,
+      "requires": {
+        "number-is-nan": "1.0.1"
+      }
+    },
+    "is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+      "dev": true
+    },
+    "is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "dev": true
+    },
+    "is-utf8": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+      "dev": true
+    },
+    "isarray": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+      "dev": true
+    },
+    "isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "dev": true
+    },
+    "isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+      "dev": true
+    },
+    "js-yaml": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz",
+      "integrity": "sha1-olrmUJmZ6X3yeMZxnaEb0Gh3Q6g=",
+      "dev": true,
+      "requires": {
+        "argparse": "0.1.16",
+        "esprima": "1.0.4"
+      }
+    },
+    "jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+      "dev": true,
+      "optional": true
+    },
+    "jshint": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.8.0.tgz",
+      "integrity": "sha1-HQmjvZE8TK36gb8Y1YK9hb/+DUQ=",
+      "dev": true,
+      "requires": {
+        "cli": "0.6.6",
+        "console-browserify": "1.1.0",
+        "exit": "0.1.2",
+        "htmlparser2": "3.8.3",
+        "lodash": "3.7.0",
+        "minimatch": "2.0.10",
+        "shelljs": "0.3.0",
+        "strip-json-comments": "1.0.4"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "3.7.0",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz",
+          "integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU=",
+          "dev": true
+        },
+        "minimatch": {
+          "version": "2.0.10",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
+          "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "1.1.8"
+          }
+        }
+      }
+    },
+    "jshint-stylish": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/jshint-stylish/-/jshint-stylish-1.0.2.tgz",
+      "integrity": "sha1-6Z88w0CvsY4qdwL4eY10AMoxRGo=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "log-symbols": "1.0.2",
+        "string-length": "1.0.1",
+        "text-table": "0.2.0"
+      }
+    },
+    "json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+      "dev": true
+    },
+    "json-stable-stringify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+      "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+      "dev": true,
+      "requires": {
+        "jsonify": "0.0.0"
+      }
+    },
+    "json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+      "dev": true
+    },
+    "jsonfile": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11"
+      },
+      "dependencies": {
+        "graceful-fs": {
+          "version": "4.1.11",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+          "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "jsonify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+      "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+      "dev": true
+    },
+    "jsprim": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.2.3",
+        "verror": "1.10.0"
+      },
+      "dependencies": {
+        "assert-plus": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+          "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+          "dev": true
+        }
+      }
+    },
+    "kew": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz",
+      "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=",
+      "dev": true
+    },
+    "klaw": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+      "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11"
+      },
+      "dependencies": {
+        "graceful-fs": {
+          "version": "4.1.11",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+          "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "load-grunt-tasks": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.5.2.tgz",
+      "integrity": "sha1-ByhWEYD9IP+KaSdQWFL8WKrqDIg=",
+      "dev": true,
+      "requires": {
+        "arrify": "1.0.1",
+        "multimatch": "2.1.0",
+        "pkg-up": "1.0.0",
+        "resolve-pkg": "0.1.0"
+      }
+    },
+    "load-json-file": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+      "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "parse-json": "2.2.0",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1",
+        "strip-bom": "2.0.0"
+      },
+      "dependencies": {
+        "graceful-fs": {
+          "version": "4.1.11",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+          "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+          "dev": true
+        }
+      }
+    },
+    "lodash": {
+      "version": "0.9.2",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz",
+      "integrity": "sha1-jzSZxSRdNG1oLlsNO0B2fgnxqSw=",
+      "dev": true
+    },
+    "log-symbols": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
+      "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3"
+      }
+    },
+    "loud-rejection": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+      "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+      "dev": true,
+      "requires": {
+        "currently-unhandled": "0.4.1",
+        "signal-exit": "3.0.2"
+      }
+    },
+    "lru-cache": {
+      "version": "2.7.3",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
+      "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=",
+      "dev": true
+    },
+    "map-obj": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+      "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+      "dev": true
+    },
+    "maxmin": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-1.1.0.tgz",
+      "integrity": "sha1-cTZehKmd2Piz99X94vANHn9zvmE=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "figures": "1.7.0",
+        "gzip-size": "1.0.0",
+        "pretty-bytes": "1.0.4"
+      }
+    },
+    "meow": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+      "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
+      "dev": true,
+      "requires": {
+        "camelcase-keys": "2.1.0",
+        "decamelize": "1.2.0",
+        "loud-rejection": "1.6.0",
+        "map-obj": "1.0.1",
+        "minimist": "1.2.0",
+        "normalize-package-data": "2.4.0",
+        "object-assign": "4.1.1",
+        "read-pkg-up": "1.0.1",
+        "redent": "1.0.0",
+        "trim-newlines": "1.0.0"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "mime": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+      "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
+      "dev": true
+    },
+    "mime-db": {
+      "version": "1.30.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
+      "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=",
+      "dev": true
+    },
+    "mime-types": {
+      "version": "2.1.17",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
+      "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
+      "dev": true,
+      "requires": {
+        "mime-db": "1.30.0"
+      }
+    },
+    "minimatch": {
+      "version": "0.2.14",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
+      "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=",
+      "dev": true,
+      "requires": {
+        "lru-cache": "2.7.3",
+        "sigmund": "1.0.1"
+      }
+    },
+    "minimist": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+      "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+      "dev": true
+    },
+    "mkdirp": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz",
+      "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=",
+      "dev": true,
+      "requires": {
+        "minimist": "0.0.8"
+      }
+    },
+    "morgan": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz",
+      "integrity": "sha1-0B+mxlhZt2/PMbPLU6OCGjEdgFE=",
+      "dev": true,
+      "requires": {
+        "basic-auth": "2.0.0",
+        "debug": "2.6.9",
+        "depd": "1.1.1",
+        "on-finished": "2.3.0",
+        "on-headers": "1.0.1"
+      }
+    },
+    "ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "multimatch": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz",
+      "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=",
+      "dev": true,
+      "requires": {
+        "array-differ": "1.0.0",
+        "array-union": "1.0.2",
+        "arrify": "1.0.1",
+        "minimatch": "3.0.4"
+      },
+      "dependencies": {
+        "minimatch": {
+          "version": "3.0.4",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "1.1.8"
+          }
+        }
+      }
+    },
+    "negotiator": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+      "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
+      "dev": true
+    },
+    "nopt": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
+      "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
+      "dev": true,
+      "requires": {
+        "abbrev": "1.1.1"
+      }
+    },
+    "normalize-package-data": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+      "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
+      "dev": true,
+      "requires": {
+        "hosted-git-info": "2.5.0",
+        "is-builtin-module": "1.0.0",
+        "semver": "5.4.1",
+        "validate-npm-package-license": "3.0.1"
+      }
+    },
+    "number-is-nan": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+      "dev": true
+    },
+    "oauth-sign": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+      "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+      "dev": true
+    },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+      "dev": true
+    },
+    "on-finished": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+      "dev": true,
+      "requires": {
+        "ee-first": "1.1.1"
+      }
+    },
+    "on-headers": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
+      "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=",
+      "dev": true
+    },
+    "once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "dev": true,
+      "requires": {
+        "wrappy": "1.0.2"
+      }
+    },
+    "opn": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz",
+      "integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=",
+      "dev": true,
+      "requires": {
+        "object-assign": "4.1.1",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "package": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/package/-/package-1.0.1.tgz",
+      "integrity": "sha1-0lofmeJQbcsn1nBLg9yooxLk7cw=",
+      "dev": true
+    },
+    "pako": {
+      "version": "0.2.9",
+      "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
+      "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=",
+      "dev": true
+    },
+    "parse-json": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+      "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+      "dev": true,
+      "requires": {
+        "error-ex": "1.3.1"
+      }
+    },
+    "parse-ms": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz",
+      "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=",
+      "dev": true
+    },
+    "parseurl": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+      "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
+      "dev": true
+    },
+    "path-exists": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+      "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+      "dev": true,
+      "requires": {
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "dev": true
+    },
+    "path-type": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+      "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1"
+      },
+      "dependencies": {
+        "graceful-fs": {
+          "version": "4.1.11",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+          "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+          "dev": true
+        }
+      }
+    },
+    "pend": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+      "dev": true
+    },
+    "performance-now": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
+      "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=",
+      "dev": true
+    },
+    "phantomjs-prebuilt": {
+      "version": "2.1.16",
+      "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz",
+      "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=",
+      "dev": true,
+      "requires": {
+        "es6-promise": "4.1.1",
+        "extract-zip": "1.6.6",
+        "fs-extra": "1.0.0",
+        "hasha": "2.2.0",
+        "kew": "0.7.0",
+        "progress": "1.1.8",
+        "request": "2.81.0",
+        "request-progress": "2.0.1",
+        "which": "1.3.0"
+      },
+      "dependencies": {
+        "which": {
+          "version": "1.3.0",
+          "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
+          "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
+          "dev": true,
+          "requires": {
+            "isexe": "2.0.0"
+          }
+        }
+      }
+    },
+    "pify": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+      "dev": true
+    },
+    "pinkie": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+      "dev": true
+    },
+    "pinkie-promise": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+      "dev": true,
+      "requires": {
+        "pinkie": "2.0.4"
+      }
+    },
+    "pkg-up": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz",
+      "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=",
+      "dev": true,
+      "requires": {
+        "find-up": "1.1.2"
+      }
+    },
+    "plur": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz",
+      "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=",
+      "dev": true
+    },
+    "portscanner": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-1.2.0.tgz",
+      "integrity": "sha1-sUu9olfRTDEPqcwJaCrwLUCWGAI=",
+      "dev": true,
+      "requires": {
+        "async": "1.5.2"
+      },
+      "dependencies": {
+        "async": {
+          "version": "1.5.2",
+          "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+          "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+          "dev": true
+        }
+      }
+    },
+    "pretty-bytes": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz",
+      "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=",
+      "dev": true,
+      "requires": {
+        "get-stdin": "4.0.1",
+        "meow": "3.7.0"
+      }
+    },
+    "pretty-ms": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz",
+      "integrity": "sha1-QlfCVt8/sLRR1q/6qwIYhBJpgdw=",
+      "dev": true,
+      "requires": {
+        "is-finite": "1.0.2",
+        "parse-ms": "1.0.1",
+        "plur": "1.0.0"
+      }
+    },
+    "process-nextick-args": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+      "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+      "dev": true
+    },
+    "progress": {
+      "version": "1.1.8",
+      "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+      "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
+      "dev": true
+    },
+    "punycode": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+      "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+      "dev": true
+    },
+    "qs": {
+      "version": "6.4.0",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
+      "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=",
+      "dev": true
+    },
+    "range-parser": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+      "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=",
+      "dev": true
+    },
+    "read-pkg": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+      "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+      "dev": true,
+      "requires": {
+        "load-json-file": "1.1.0",
+        "normalize-package-data": "2.4.0",
+        "path-type": "1.1.0"
+      }
+    },
+    "read-pkg-up": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+      "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+      "dev": true,
+      "requires": {
+        "find-up": "1.1.2",
+        "read-pkg": "1.1.0"
+      }
+    },
+    "readable-stream": {
+      "version": "1.1.14",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+      "dev": true,
+      "requires": {
+        "core-util-is": "1.0.2",
+        "inherits": "2.0.3",
+        "isarray": "0.0.1",
+        "string_decoder": "0.10.31"
+      }
+    },
+    "redent": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+      "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
+      "dev": true,
+      "requires": {
+        "indent-string": "2.1.0",
+        "strip-indent": "1.0.1"
+      }
+    },
+    "repeating": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+      "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+      "dev": true,
+      "requires": {
+        "is-finite": "1.0.2"
+      }
+    },
+    "request": {
+      "version": "2.81.0",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
+      "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=",
+      "dev": true,
+      "requires": {
+        "aws-sign2": "0.6.0",
+        "aws4": "1.6.0",
+        "caseless": "0.12.0",
+        "combined-stream": "1.0.5",
+        "extend": "3.0.1",
+        "forever-agent": "0.6.1",
+        "form-data": "2.1.4",
+        "har-validator": "4.2.1",
+        "hawk": "3.1.3",
+        "http-signature": "1.1.1",
+        "is-typedarray": "1.0.0",
+        "isstream": "0.1.2",
+        "json-stringify-safe": "5.0.1",
+        "mime-types": "2.1.17",
+        "oauth-sign": "0.8.2",
+        "performance-now": "0.2.0",
+        "qs": "6.4.0",
+        "safe-buffer": "5.1.1",
+        "stringstream": "0.0.5",
+        "tough-cookie": "2.3.3",
+        "tunnel-agent": "0.6.0",
+        "uuid": "3.1.0"
+      }
+    },
+    "request-progress": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz",
+      "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=",
+      "dev": true,
+      "requires": {
+        "throttleit": "1.0.0"
+      }
+    },
+    "resolve-from": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
+      "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=",
+      "dev": true
+    },
+    "resolve-pkg": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-0.1.0.tgz",
+      "integrity": "sha1-AsyZNBDik2livZcWahsHfalyVTE=",
+      "dev": true,
+      "requires": {
+        "resolve-from": "2.0.0"
+      }
+    },
+    "rimraf": {
+      "version": "2.2.8",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
+      "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
+      "dev": true
+    },
+    "safe-buffer": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+      "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
+      "dev": true
+    },
+    "semver": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
+      "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
+      "dev": true
+    },
+    "send": {
+      "version": "0.16.1",
+      "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz",
+      "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "depd": "1.1.1",
+        "destroy": "1.0.4",
+        "encodeurl": "1.0.1",
+        "escape-html": "1.0.3",
+        "etag": "1.8.1",
+        "fresh": "0.5.2",
+        "http-errors": "1.6.2",
+        "mime": "1.4.1",
+        "ms": "2.0.0",
+        "on-finished": "2.3.0",
+        "range-parser": "1.2.0",
+        "statuses": "1.3.1"
+      }
+    },
+    "serve-index": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
+      "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
+      "dev": true,
+      "requires": {
+        "accepts": "1.3.4",
+        "batch": "0.6.1",
+        "debug": "2.6.9",
+        "escape-html": "1.0.3",
+        "http-errors": "1.6.2",
+        "mime-types": "2.1.17",
+        "parseurl": "1.3.2"
+      }
+    },
+    "serve-static": {
+      "version": "1.13.1",
+      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz",
+      "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==",
+      "dev": true,
+      "requires": {
+        "encodeurl": "1.0.1",
+        "escape-html": "1.0.3",
+        "parseurl": "1.3.2",
+        "send": "0.16.1"
+      }
+    },
+    "setprototypeof": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
+      "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=",
+      "dev": true
+    },
+    "shelljs": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz",
+      "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=",
+      "dev": true
+    },
+    "sigmund": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
+      "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
+      "dev": true
+    },
+    "signal-exit": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+      "dev": true
+    },
+    "sntp": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+      "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+      "dev": true,
+      "requires": {
+        "hoek": "2.16.3"
+      }
+    },
+    "source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true
+    },
+    "spdx-correct": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
+      "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
+      "dev": true,
+      "requires": {
+        "spdx-license-ids": "1.2.2"
+      }
+    },
+    "spdx-expression-parse": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
+      "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=",
+      "dev": true
+    },
+    "spdx-license-ids": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
+      "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=",
+      "dev": true
+    },
+    "sshpk": {
+      "version": "1.13.1",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
+      "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
+      "dev": true,
+      "requires": {
+        "asn1": "0.2.3",
+        "assert-plus": "1.0.0",
+        "bcrypt-pbkdf": "1.0.1",
+        "dashdash": "1.14.1",
+        "ecc-jsbn": "0.1.1",
+        "getpass": "0.1.7",
+        "jsbn": "0.1.1",
+        "tweetnacl": "0.14.5"
+      },
+      "dependencies": {
+        "assert-plus": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+          "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+          "dev": true
+        }
+      }
+    },
+    "statuses": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+      "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
+      "dev": true
+    },
+    "string-length": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz",
+      "integrity": "sha1-VpcPscOFWOnnC3KL894mmsRa36w=",
+      "dev": true,
+      "requires": {
+        "strip-ansi": "3.0.1"
+      }
+    },
+    "string_decoder": {
+      "version": "0.10.31",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+      "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+      "dev": true
+    },
+    "stringstream": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+      "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
+      "dev": true
+    },
+    "strip-ansi": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "2.1.1"
+      }
+    },
+    "strip-bom": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+      "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+      "dev": true,
+      "requires": {
+        "is-utf8": "0.2.1"
+      }
+    },
+    "strip-indent": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+      "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
+      "dev": true,
+      "requires": {
+        "get-stdin": "4.0.1"
+      }
+    },
+    "strip-json-comments": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
+      "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=",
+      "dev": true
+    },
+    "supports-color": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+      "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+      "dev": true
+    },
+    "temporary": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/temporary/-/temporary-0.0.8.tgz",
+      "integrity": "sha1-oYqYHSi6jKNgJ/s8MFOMPst0CsA=",
+      "dev": true,
+      "requires": {
+        "package": "1.0.1"
+      }
+    },
+    "text-table": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+      "dev": true
+    },
+    "throttleit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
+      "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=",
+      "dev": true
+    },
+    "time-grunt": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/time-grunt/-/time-grunt-1.4.0.tgz",
+      "integrity": "sha1-BiIT5mDJB+hvRAVWwB6mWXtxJCA=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "date-time": "1.1.0",
+        "figures": "1.7.0",
+        "hooker": "0.2.3",
+        "number-is-nan": "1.0.1",
+        "pretty-ms": "2.1.0",
+        "text-table": "0.2.0"
+      }
+    },
+    "time-zone": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-0.1.0.tgz",
+      "integrity": "sha1-Sncotqwo2w4Aj1FAQ/1VW9VXO0Y=",
+      "dev": true
+    },
+    "tough-cookie": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
+      "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
+      "dev": true,
+      "requires": {
+        "punycode": "1.4.1"
+      }
+    },
+    "trim-newlines": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+      "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
+      "dev": true
+    },
+    "tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "dev": true,
+      "optional": true
+    },
+    "typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "dev": true
+    },
+    "uglify-js": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.2.2.tgz",
+      "integrity": "sha512-++1NO/zZIEdWf6cDIGceSJQPX31SqIpbVAHwFG5+240MtZqPG/NIPoinj8zlXQtAfMBqEt1Jyv2FiLP3n9gVhQ==",
+      "dev": true,
+      "requires": {
+        "commander": "2.12.2",
+        "source-map": "0.6.1"
+      }
+    },
+    "underscore": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz",
+      "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=",
+      "dev": true
+    },
+    "underscore.string": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz",
+      "integrity": "sha1-18D6KvXVoaZ/QlPa7pgTLnM/Dxk=",
+      "dev": true
+    },
+    "unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+      "dev": true
+    },
+    "uri-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz",
+      "integrity": "sha1-l0fwGDWJM8Md4PzP2C0TjmcmLjI=",
+      "dev": true
+    },
+    "util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "dev": true
+    },
+    "utils-merge": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+      "dev": true
+    },
+    "uuid": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
+      "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==",
+      "dev": true
+    },
+    "validate-npm-package-license": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
+      "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
+      "dev": true,
+      "requires": {
+        "spdx-correct": "1.0.2",
+        "spdx-expression-parse": "1.0.4"
+      }
+    },
+    "verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "1.3.0"
+      },
+      "dependencies": {
+        "assert-plus": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+          "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+          "dev": true
+        }
+      }
+    },
+    "which": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz",
+      "integrity": "sha1-RgwdoPgQED0DIam2M6+eV15kSG8=",
+      "dev": true
+    },
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "dev": true
+    },
+    "yauzl": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
+      "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
+      "dev": true,
+      "requires": {
+        "fd-slicer": "1.0.1"
+      }
+    }
+  }
+}
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/package.js b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/package.js
new file mode 100644
index 0000000..2962920
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/package.js
@@ -0,0 +1,14 @@
+Package.describe({
+  "name": "igorescobar:jquery-mask-plugin",
+  "version": "1.14.15",
+  "summary": "A jQuery Plugin to make masks on form fields and HTML elements.",
+  "git": "git@github.com:igorescobar/jQuery-Mask-Plugin.git",
+  "documentation": "README.md"
+});
+
+Package.onUse(function(api) {
+  api.versionsFrom('1.2.1');
+  api.use('ecmascript');
+  api.addFiles('dist/jquery.mask.js');
+  api.addFiles('dist/jquery.mask.min.js');
+});
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/package.json b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/package.json
new file mode 100644
index 0000000..fb5a419
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/package.json
@@ -0,0 +1,34 @@
+{
+  "name": "jquery-mask-plugin",
+  "version": "1.14.15",
+  "description": "A jQuery Plugin to make masks on form fields and html elements.",
+  "author": "Igor Escobar <blog@igorescobar.com>",
+  "homepage": "http://igorescobar.github.io/jQuery-Mask-Plugin/",
+  "main": "./dist/jquery.mask.js",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/igorescobar/jQuery-Mask-Plugin"
+  },
+  "bugs": {
+    "url": "https://github.com/igorescobar/jQuery-Mask-Plugin/issues"
+  },
+  "keywords": [
+    "mask",
+    "masks",
+    "form",
+    "input",
+    "jquery-plugin"
+  ],
+  "license": "MIT",
+  "devDependencies": {
+    "grunt": "~0.4.1",
+    "grunt-contrib-connect": "*",
+    "grunt-contrib-jshint": "^0.11.0",
+    "grunt-contrib-qunit": "*",
+    "grunt-contrib-uglify": "*",
+    "jshint-stylish": "^1.0.0",
+    "load-grunt-tasks": "^3.1.0",
+    "time-grunt": "^1.0.0",
+    "request": "2.81.0"
+  }
+}
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/src/jquery.mask.js b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/src/jquery.mask.js
new file mode 100644
index 0000000..019f2ec
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/src/jquery.mask.js
@@ -0,0 +1,604 @@
+/**
+ * jquery.mask.js
+ * @version: v1.14.15
+ * @author: Igor Escobar
+ *
+ * Created by Igor Escobar on 2012-03-10. Please report any bug at github.com/igorescobar/jQuery-Mask-Plugin
+ *
+ * Copyright (c) 2012 Igor Escobar http://igorescobar.com
+ *
+ * The MIT License (http://www.opensource.org/licenses/mit-license.php)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* jshint laxbreak: true */
+/* jshint maxcomplexity:17 */
+/* global define */
+
+// UMD (Universal Module Definition) patterns for JavaScript modules that work everywhere.
+// https://github.com/umdjs/umd/blob/master/templates/jqueryPlugin.js
+(function (factory, jQuery, Zepto) {
+
+    if (typeof define === 'function' && define.amd) {
+        define(['jquery'], factory);
+    } else if (typeof exports === 'object') {
+        module.exports = factory(require('jquery'));
+    } else {
+        factory(jQuery || Zepto);
+    }
+
+}(function ($) {
+    'use strict';
+
+    var Mask = function (el, mask, options) {
+
+        var p = {
+            invalid: [],
+            getCaret: function () {
+                try {
+                    var sel,
+                        pos = 0,
+                        ctrl = el.get(0),
+                        dSel = document.selection,
+                        cSelStart = ctrl.selectionStart;
+
+                    // IE Support
+                    if (dSel && navigator.appVersion.indexOf('MSIE 10') === -1) {
+                        sel = dSel.createRange();
+                        sel.moveStart('character', -p.val().length);
+                        pos = sel.text.length;
+                    }
+                    // Firefox support
+                    else if (cSelStart || cSelStart === '0') {
+                        pos = cSelStart;
+                    }
+
+                    return pos;
+                } catch (e) {}
+            },
+            setCaret: function(pos) {
+                try {
+                    if (el.is(':focus')) {
+                        var range, ctrl = el.get(0);
+
+                        // Firefox, WebKit, etc..
+                        if (ctrl.setSelectionRange) {
+                            ctrl.setSelectionRange(pos, pos);
+                        } else { // IE
+                            range = ctrl.createTextRange();
+                            range.collapse(true);
+                            range.moveEnd('character', pos);
+                            range.moveStart('character', pos);
+                            range.select();
+                        }
+                    }
+                } catch (e) {}
+            },
+            events: function() {
+                el
+                .on('keydown.mask', function(e) {
+                    el.data('mask-keycode', e.keyCode || e.which);
+                    el.data('mask-previus-value', el.val());
+                    el.data('mask-previus-caret-pos', p.getCaret());
+                    p.maskDigitPosMapOld = p.maskDigitPosMap;
+                })
+                .on($.jMaskGlobals.useInput ? 'input.mask' : 'keyup.mask', p.behaviour)
+                .on('paste.mask drop.mask', function() {
+                    setTimeout(function() {
+                        el.keydown().keyup();
+                    }, 100);
+                })
+                .on('change.mask', function(){
+                    el.data('changed', true);
+                })
+                .on('blur.mask', function(){
+                    if (oldValue !== p.val() && !el.data('changed')) {
+                        el.trigger('change');
+                    }
+                    el.data('changed', false);
+                })
+                // it's very important that this callback remains in this position
+                // otherwhise oldValue it's going to work buggy
+                .on('blur.mask', function() {
+                    oldValue = p.val();
+                })
+                // select all text on focus
+                .on('focus.mask', function (e) {
+                    if (options.selectOnFocus === true) {
+                        $(e.target).select();
+                    }
+                })
+                // clear the value if it not complete the mask
+                .on('focusout.mask', function() {
+                    if (options.clearIfNotMatch && !regexMask.test(p.val())) {
+                       p.val('');
+                   }
+                });
+            },
+            getRegexMask: function() {
+                var maskChunks = [], translation, pattern, optional, recursive, oRecursive, r;
+
+                for (var i = 0; i < mask.length; i++) {
+                    translation = jMask.translation[mask.charAt(i)];
+
+                    if (translation) {
+
+                        pattern = translation.pattern.toString().replace(/.{1}$|^.{1}/g, '');
+                        optional = translation.optional;
+                        recursive = translation.recursive;
+
+                        if (recursive) {
+                            maskChunks.push(mask.charAt(i));
+                            oRecursive = {digit: mask.charAt(i), pattern: pattern};
+                        } else {
+                            maskChunks.push(!optional && !recursive ? pattern : (pattern + '?'));
+                        }
+
+                    } else {
+                        maskChunks.push(mask.charAt(i).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'));
+                    }
+                }
+
+                r = maskChunks.join('');
+
+                if (oRecursive) {
+                    r = r.replace(new RegExp('(' + oRecursive.digit + '(.*' + oRecursive.digit + ')?)'), '($1)?')
+                         .replace(new RegExp(oRecursive.digit, 'g'), oRecursive.pattern);
+                }
+
+                return new RegExp(r);
+            },
+            destroyEvents: function() {
+                el.off(['input', 'keydown', 'keyup', 'paste', 'drop', 'blur', 'focusout', ''].join('.mask '));
+            },
+            val: function(v) {
+                var isInput = el.is('input'),
+                    method = isInput ? 'val' : 'text',
+                    r;
+
+                if (arguments.length > 0) {
+                    if (el[method]() !== v) {
+                        el[method](v);
+                    }
+                    r = el;
+                } else {
+                    r = el[method]();
+                }
+
+                return r;
+            },
+            calculateCaretPosition: function() {
+                var oldVal = el.data('mask-previus-value') || '',
+                    newVal = p.getMasked(),
+                    caretPosNew = p.getCaret();
+                if (oldVal !== newVal) {
+                    var caretPosOld = el.data('mask-previus-caret-pos') || 0,
+                        newValL = newVal.length,
+                        oldValL = oldVal.length,
+                        maskDigitsBeforeCaret = 0,
+                        maskDigitsAfterCaret = 0,
+                        maskDigitsBeforeCaretAll = 0,
+                        maskDigitsBeforeCaretAllOld = 0,
+                        i = 0;
+
+                    for (i = caretPosNew; i < newValL; i++) {
+                        if (!p.maskDigitPosMap[i]) {
+                            break;
+                        }
+                        maskDigitsAfterCaret++;
+                    }
+
+                    for (i = caretPosNew - 1; i >= 0; i--) {
+                        if (!p.maskDigitPosMap[i]) {
+                            break;
+                        }
+                        maskDigitsBeforeCaret++;
+                    }
+
+                    for (i = caretPosNew - 1; i >= 0; i--) {
+                        if (p.maskDigitPosMap[i]) {
+                            maskDigitsBeforeCaretAll++;
+                        }
+                    }
+
+                    for (i = caretPosOld - 1; i >= 0; i--) {
+                        if (p.maskDigitPosMapOld[i]) {
+                            maskDigitsBeforeCaretAllOld++;
+                        }
+                    }
+
+                    // if the cursor is at the end keep it there
+                    if (caretPosNew > oldValL) {
+                      caretPosNew = newValL * 10;
+                    } else if (caretPosOld >= caretPosNew && caretPosOld !== oldValL) {
+                        if (!p.maskDigitPosMapOld[caretPosNew])  {
+                          var caretPos = caretPosNew;
+                          caretPosNew -= maskDigitsBeforeCaretAllOld - maskDigitsBeforeCaretAll;
+                          caretPosNew -= maskDigitsBeforeCaret;
+                          if (p.maskDigitPosMap[caretPosNew])  {
+                            caretPosNew = caretPos;
+                          }
+                        }
+                    }
+                    else if (caretPosNew > caretPosOld) {
+                        caretPosNew += maskDigitsBeforeCaretAll - maskDigitsBeforeCaretAllOld;
+                        caretPosNew += maskDigitsAfterCaret;
+                    }
+                }
+                return caretPosNew;
+            },
+            behaviour: function(e) {
+                e = e || window.event;
+                p.invalid = [];
+
+                var keyCode = el.data('mask-keycode');
+
+                if ($.inArray(keyCode, jMask.byPassKeys) === -1) {
+                    var newVal = p.getMasked(),
+                        caretPos = p.getCaret();
+
+                    // this is a compensation to devices/browsers that don't compensate
+                    // caret positioning the right way
+                    setTimeout(function() {
+                      p.setCaret(p.calculateCaretPosition());
+                    }, $.jMaskGlobals.keyStrokeCompensation);
+
+                    p.val(newVal);
+                    p.setCaret(caretPos);
+                    return p.callbacks(e);
+                }
+            },
+            getMasked: function(skipMaskChars, val) {
+                var buf = [],
+                    value = val === undefined ? p.val() : val + '',
+                    m = 0, maskLen = mask.length,
+                    v = 0, valLen = value.length,
+                    offset = 1, addMethod = 'push',
+                    resetPos = -1,
+                    maskDigitCount = 0,
+                    maskDigitPosArr = [],
+                    lastMaskChar,
+                    check;
+
+                if (options.reverse) {
+                    addMethod = 'unshift';
+                    offset = -1;
+                    lastMaskChar = 0;
+                    m = maskLen - 1;
+                    v = valLen - 1;
+                    check = function () {
+                        return m > -1 && v > -1;
+                    };
+                } else {
+                    lastMaskChar = maskLen - 1;
+                    check = function () {
+                        return m < maskLen && v < valLen;
+                    };
+                }
+
+                var lastUntranslatedMaskChar;
+                while (check()) {
+                    var maskDigit = mask.charAt(m),
+                        valDigit = value.charAt(v),
+                        translation = jMask.translation[maskDigit];
+
+                    if (translation) {
+                        if (valDigit.match(translation.pattern)) {
+                            buf[addMethod](valDigit);
+                             if (translation.recursive) {
+                                if (resetPos === -1) {
+                                    resetPos = m;
+                                } else if (m === lastMaskChar && m !== resetPos) {
+                                    m = resetPos - offset;
+                                }
+
+                                if (lastMaskChar === resetPos) {
+                                    m -= offset;
+                                }
+                            }
+                            m += offset;
+                        } else if (valDigit === lastUntranslatedMaskChar) {
+                            // matched the last untranslated (raw) mask character that we encountered
+                            // likely an insert offset the mask character from the last entry; fall
+                            // through and only increment v
+                            maskDigitCount--;
+                            lastUntranslatedMaskChar = undefined;
+                        } else if (translation.optional) {
+                            m += offset;
+                            v -= offset;
+                        } else if (translation.fallback) {
+                            buf[addMethod](translation.fallback);
+                            m += offset;
+                            v -= offset;
+                        } else {
+                          p.invalid.push({p: v, v: valDigit, e: translation.pattern});
+                        }
+                        v += offset;
+                    } else {
+                        if (!skipMaskChars) {
+                            buf[addMethod](maskDigit);
+                        }
+
+                        if (valDigit === maskDigit) {
+                            maskDigitPosArr.push(v);
+                            v += offset;
+                        } else {
+                            lastUntranslatedMaskChar = maskDigit;
+                            maskDigitPosArr.push(v + maskDigitCount);
+                            maskDigitCount++;
+                        }
+
+                        m += offset;
+                    }
+                }
+
+                var lastMaskCharDigit = mask.charAt(lastMaskChar);
+                if (maskLen === valLen + 1 && !jMask.translation[lastMaskCharDigit]) {
+                    buf.push(lastMaskCharDigit);
+                }
+
+                var newVal = buf.join('');
+                p.mapMaskdigitPositions(newVal, maskDigitPosArr, valLen);
+                return newVal;
+            },
+            mapMaskdigitPositions: function(newVal, maskDigitPosArr, valLen) {
+              var maskDiff = options.reverse ? newVal.length - valLen : 0;
+              p.maskDigitPosMap = {};
+              for (var i = 0; i < maskDigitPosArr.length; i++) {
+                p.maskDigitPosMap[maskDigitPosArr[i] + maskDiff] = 1;
+              }
+            },
+            callbacks: function (e) {
+                var val = p.val(),
+                    changed = val !== oldValue,
+                    defaultArgs = [val, e, el, options],
+                    callback = function(name, criteria, args) {
+                        if (typeof options[name] === 'function' && criteria) {
+                            options[name].apply(this, args);
+                        }
+                    };
+
+                callback('onChange', changed === true, defaultArgs);
+                callback('onKeyPress', changed === true, defaultArgs);
+                callback('onComplete', val.length === mask.length, defaultArgs);
+                callback('onInvalid', p.invalid.length > 0, [val, e, el, p.invalid, options]);
+            }
+        };
+
+        el = $(el);
+        var jMask = this, oldValue = p.val(), regexMask;
+
+        mask = typeof mask === 'function' ? mask(p.val(), undefined, el,  options) : mask;
+
+        // public methods
+        jMask.mask = mask;
+        jMask.options = options;
+        jMask.remove = function() {
+            var caret = p.getCaret();
+            if (jMask.options.placeholder) {
+                el.removeAttr('placeholder');
+            }
+            if (el.data('mask-maxlength')) {
+                el.removeAttr('maxlength');
+            }
+            p.destroyEvents();
+            p.val(jMask.getCleanVal());
+            p.setCaret(caret);
+            return el;
+        };
+
+        // get value without mask
+        jMask.getCleanVal = function() {
+           return p.getMasked(true);
+        };
+
+        // get masked value without the value being in the input or element
+        jMask.getMaskedVal = function(val) {
+           return p.getMasked(false, val);
+        };
+
+       jMask.init = function(onlyMask) {
+            onlyMask = onlyMask || false;
+            options = options || {};
+
+            jMask.clearIfNotMatch  = $.jMaskGlobals.clearIfNotMatch;
+            jMask.byPassKeys       = $.jMaskGlobals.byPassKeys;
+            jMask.translation      = $.extend({}, $.jMaskGlobals.translation, options.translation);
+
+            jMask = $.extend(true, {}, jMask, options);
+
+            regexMask = p.getRegexMask();
+
+            if (onlyMask) {
+                p.events();
+                p.val(p.getMasked());
+            } else {
+                if (options.placeholder) {
+                    el.attr('placeholder' , options.placeholder);
+                }
+
+                // this is necessary, otherwise if the user submit the form
+                // and then press the "back" button, the autocomplete will erase
+                // the data. Works fine on IE9+, FF, Opera, Safari.
+                if (el.data('mask')) {
+                  el.attr('autocomplete', 'off');
+                }
+
+                // detect if is necessary let the user type freely.
+                // for is a lot faster than forEach.
+                for (var i = 0, maxlength = true; i < mask.length; i++) {
+                    var translation = jMask.translation[mask.charAt(i)];
+                    if (translation && translation.recursive) {
+                        maxlength = false;
+                        break;
+                    }
+                }
+
+                if (maxlength) {
+                    el.attr('maxlength', mask.length).data('mask-maxlength', true);
+                }
+
+                p.destroyEvents();
+                p.events();
+
+                var caret = p.getCaret();
+                p.val(p.getMasked());
+                p.setCaret(caret);
+            }
+        };
+
+        jMask.init(!el.is('input'));
+    };
+
+    $.maskWatchers = {};
+    var HTMLAttributes = function () {
+        var input = $(this),
+            options = {},
+            prefix = 'data-mask-',
+            mask = input.attr('data-mask');
+
+        if (input.attr(prefix + 'reverse')) {
+            options.reverse = true;
+        }
+
+        if (input.attr(prefix + 'clearifnotmatch')) {
+            options.clearIfNotMatch = true;
+        }
+
+        if (input.attr(prefix + 'selectonfocus') === 'true') {
+           options.selectOnFocus = true;
+        }
+
+        if (notSameMaskObject(input, mask, options)) {
+            return input.data('mask', new Mask(this, mask, options));
+        }
+    },
+    notSameMaskObject = function(field, mask, options) {
+        options = options || {};
+        var maskObject = $(field).data('mask'),
+            stringify = JSON.stringify,
+            value = $(field).val() || $(field).text();
+        try {
+            if (typeof mask === 'function') {
+                mask = mask(value);
+            }
+            return typeof maskObject !== 'object' || stringify(maskObject.options) !== stringify(options) || maskObject.mask !== mask;
+        } catch (e) {}
+    },
+    eventSupported = function(eventName) {
+        var el = document.createElement('div'), isSupported;
+
+        eventName = 'on' + eventName;
+        isSupported = (eventName in el);
+
+        if ( !isSupported ) {
+            el.setAttribute(eventName, 'return;');
+            isSupported = typeof el[eventName] === 'function';
+        }
+        el = null;
+
+        return isSupported;
+    };
+
+    $.fn.mask = function(mask, options) {
+        options = options || {};
+        var selector = this.selector,
+            globals = $.jMaskGlobals,
+            interval = globals.watchInterval,
+            watchInputs = options.watchInputs || globals.watchInputs,
+            maskFunction = function() {
+                if (notSameMaskObject(this, mask, options)) {
+                    return $(this).data('mask', new Mask(this, mask, options));
+                }
+            };
+
+        $(this).each(maskFunction);
+
+        if (selector && selector !== '' && watchInputs) {
+            clearInterval($.maskWatchers[selector]);
+            $.maskWatchers[selector] = setInterval(function(){
+                $(document).find(selector).each(maskFunction);
+            }, interval);
+        }
+        return this;
+    };
+
+    $.fn.masked = function(val) {
+        return this.data('mask').getMaskedVal(val);
+    };
+
+    $.fn.unmask = function() {
+        clearInterval($.maskWatchers[this.selector]);
+        delete $.maskWatchers[this.selector];
+        return this.each(function() {
+            var dataMask = $(this).data('mask');
+            if (dataMask) {
+                dataMask.remove().removeData('mask');
+            }
+        });
+    };
+
+    $.fn.cleanVal = function() {
+        return this.data('mask').getCleanVal();
+    };
+
+    $.applyDataMask = function(selector) {
+        selector = selector || $.jMaskGlobals.maskElements;
+        var $selector = (selector instanceof $) ? selector : $(selector);
+        $selector.filter($.jMaskGlobals.dataMaskAttr).each(HTMLAttributes);
+    };
+
+    var globals = {
+        maskElements: 'input,td,span,div',
+        dataMaskAttr: '*[data-mask]',
+        dataMask: true,
+        watchInterval: 300,
+        watchInputs: true,
+        keyStrokeCompensation: 10,
+        // old versions of chrome dont work great with input event
+        useInput: !/Chrome\/[2-4][0-9]|SamsungBrowser/.test(window.navigator.userAgent) && eventSupported('input'),
+        watchDataMask: false,
+        byPassKeys: [9, 16, 17, 18, 36, 37, 38, 39, 40, 91],
+        translation: {
+            '0': {pattern: /\d/},
+            '9': {pattern: /\d/, optional: true},
+            '#': {pattern: /\d/, recursive: true},
+            'A': {pattern: /[a-zA-Z0-9]/},
+            'S': {pattern: /[a-zA-Z]/}
+        }
+    };
+
+    $.jMaskGlobals = $.jMaskGlobals || {};
+    globals = $.jMaskGlobals = $.extend(true, {}, globals, $.jMaskGlobals);
+
+    // looking for inputs with data-mask attribute
+    if (globals.dataMask) {
+        $.applyDataMask();
+    }
+
+    setInterval(function() {
+        if ($.jMaskGlobals.watchDataMask) {
+            $.applyDataMask();
+        }
+    }, globals.watchInterval);
+}, window.jQuery, window.Zepto));
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/jquery.mask.test.js b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/jquery.mask.test.js
new file mode 100644
index 0000000..378aebb
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/jquery.mask.test.js
@@ -0,0 +1,718 @@
+var QUNIT = true;
+$(document).ready(function(){
+
+    var testfield = $('.simple-field'),
+        testfieldDataMask = $('.simple-field-data-mask'),
+        testfieldDataMaskWithReverse = $('.simple-field-data-mask-reverse'),
+        testfieldDataMaskWithClearIfNotMatch = $('.simple-field-data-mask-clearifnotmatch'),
+        testfieldDataMaskWithClearIfNotMatchAndOptionalMask = $('.simple-field-data-mask-clearifnotmatch-and-optional-mask'),
+        testdiv = $('.simple-div'),
+        typeTest = function (typedValue, obj) {
+          obj = typeof obj === "undefined" ? testfield : obj;
+
+          return obj.keydown().val(typedValue).trigger('input').val();
+        },
+        typeDivTest = function(typedValue){
+          return testdiv.keydown().text(typedValue).trigger('input').text();
+        };
+
+    module('Setting Up');
+    test("test if the mask method exists after plugin insertion", function() {
+      equal( typeof testfield.mask , "function" , "mask function should exists" );
+    });
+
+    module('Simple Masks');
+    test("Masks with only numbers.", function(){
+      testfield.mask('000000');
+
+      equal( typeTest("1."), "1");
+      equal( typeTest('1éáa2aaaaqwo'), "12");
+      equal( typeTest('1234567'), "123456");
+
+    });
+
+    test("When I change the mask on-the-fly things should work normally", function(){
+      testfield.mask('0000.0000');
+
+      equal( typeTest("1."), "1");
+      equal( typeTest('1éáa2aaaaqwo'), "12");
+      equal( typeTest('1234567'), "1234.567");
+
+      // changing on-the-fly
+      testfield.mask('0.000.000');
+
+      equal( typeTest("1."), "1.");
+      equal( typeTest('1éáa2aaaaqwo'), "1.2");
+      equal( typeTest('1234567'), "1.234.567");
+
+    });
+
+    test("When I change the mask on-the-fly with onChange callback things should work normally", function(){
+
+      var masks = ['0000.00009', '0.0000.0000'];
+      var SPphoneMask = function(phone){
+        return phone.length <= 9 ? masks[0] : masks[1];
+      };
+
+      testfield.mask(SPphoneMask, {onChange: function(phone, e, currentField, options){
+        $(currentField).mask(SPphoneMask(phone), options);
+      }});
+
+      equal( typeTest("1"), "1");
+      equal( typeTest("12"), "12");
+      equal( typeTest("123"), "123");
+      equal( typeTest("1234"), "1234");
+      equal( typeTest("12345"), "1234.5");
+      equal( typeTest("123456"), "1234.56");
+      equal( typeTest("1234567"), "1234.567");
+      equal( typeTest("12345678"), "1234.5678");
+      equal( typeTest("123456789"), "1.2345.6789");
+
+    });
+
+    test("When I change the mask on-the-fly with onKeyPress callback things should work normally", function(){
+
+      var masks = ['0000.00009', '0.0000.0000'];
+      var SPphoneMask = function(phone){
+        return phone.length <= 9 ? masks[0] : masks[1];
+      };
+
+      testfield.mask(SPphoneMask, {onKeyPress: function(phone, e, currentField, options){
+        $(currentField).mask(SPphoneMask(phone), options);
+      }});
+
+      equal( typeTest("1"), "1");
+      equal( typeTest("12"), "12");
+      equal( typeTest("123"), "123");
+      equal( typeTest("1234"), "1234");
+      equal( typeTest("12345"), "1234.5");
+      equal( typeTest("123456"), "1234.56");
+      equal( typeTest("1234567"), "1234.567");
+      equal( typeTest("12345678"), "1234.5678");
+      equal( typeTest("123456789"), "1.2345.6789");
+
+    });
+
+    test("#onInvalid callback. should call when invalid", function(){
+      testfield.mask('00/00/0000', {onInvalid: function(val, e, el, invalid, options){
+        equal(val, "1")
+        equal(typeof e, "object")
+        equal(typeof el, "object")
+        equal(invalid.length, 1);
+        equal(invalid[0]["e"], "/\\d/");
+        equal(invalid[0]["p"], 1);
+        equal(invalid[0]["v"], "a");
+        equal(typeof options.onInvalid, "function");
+      }});
+
+      equal( typeTest("1a") , "1");
+    });
+
+    test("#onInvalid callback. should not call when valid", function(){
+      var callback = sinon.spy();
+      testfield.mask('00/00/0000', {onInvalid: callback});
+
+      equal( typeTest("11") , "11");
+      equal(callback.called, false)
+    });
+
+    test('When I typed a char thats the same as the mask char', function(){
+      testfield.unmask();
+      testfield.mask('00/00/0000');
+
+      equal( typeTest("00/"), "00/");
+      equal( typeTest("00a"), "00/");
+      equal( typeTest("00a00/00"), "00/00/00");
+      equal( typeTest("0a/00/00"), "00/00/0");
+      equal( typeTest("0a/0a/00"), "00/00");
+
+    });
+
+    test('When I typed exactly the same as the mask', function(){
+      testfield.mask('00/00/0000');
+      equal( typeTest("00"), "00");
+      equal( typeTest("00/"), "00/");
+      equal( typeTest("aa/"), "");
+      equal( typeTest("00/0"), "00/0");
+      equal( typeTest("00/00"), "00/00");
+      equal( typeTest("00/00/0"), "00/00/0");
+      equal( typeTest("00/00/00"), "00/00/00");
+    });
+
+    test("Testing masks with a literal on the last char", function () {
+      testfield.mask("(99)");
+
+      equal( typeTest("(99"), "(99)");
+    });
+
+
+    module('Masks with numbers and especial characters');
+
+    test("Masks with numbers and special characters.", function(){
+      testfield.mask('(000) 000-0000');
+
+      equal( typeTest("1"), "(1");
+      equal( typeTest('12'), "(12");
+      equal( typeTest('123'), "(123");
+      equal( typeTest('1234'), "(123) 4");
+      equal( typeTest('12345'), "(123) 45");
+      equal( typeTest('(123) 456'), "(123) 456");
+      equal( typeTest('(123) 4567'), "(123) 456-7");
+
+    });
+
+    test("Testing masks with a annonymous function", function(){
+      testfield.mask(function(){
+        return "(123) 456-7899"
+      });
+
+      equal( typeTest("1"), "(1");
+      equal( typeTest('12'), "(12");
+      equal( typeTest('123'), "(123");
+      equal( typeTest('1234'), "(123) 4");
+      equal( typeTest('12345'), "(123) 45");
+      equal( typeTest('123456'), "(123) 456");
+      equal( typeTest('1234567'), "(123) 456-7");
+
+    });
+
+    test("Masks with numbers, strings e special characters", function(){
+      testfield.mask('(999) A99-SSSS');
+
+      equal( typeTest("(1"), "(1");
+      equal( typeTest('(12'), "(12");
+      equal( typeTest('(123'), "(123");
+      equal( typeTest('(123) 4'), "(123) 4");
+      equal( typeTest('(123) A'), "(123) A");
+      equal( typeTest('123.'), "(123) ");
+      equal( typeTest('(123) 45'), "(123) 45");
+      equal( typeTest('(123) 456'), "(123) 456");
+      equal( typeTest('(123) 456-A'), "(123) 456-A");
+      equal( typeTest('(123) 456-AB'), "(123) 456-AB");
+      equal( typeTest('(123) 456-ABC'), "(123) 456-ABC");
+      equal( typeTest('(123) 456-ABCD'), "(123) 456-ABCD");
+      equal( typeTest('(123) 456-ABCDE'), "(123) 456-ABCD");
+      equal( typeTest('(123) 456-ABCD1'), "(123) 456-ABCD");
+
+    });
+
+    test("Masks with numbers, strings e special characters #2 ", function(){
+      testfield.mask('AAA 000-S0S');
+
+      equal( typeTest("1"), "1");
+      equal( typeTest('12'), "12");
+      equal( typeTest('123'), "123");
+      equal( typeTest('123 4'), "123 4");
+      equal( typeTest('123 45'), "123 45");
+      equal( typeTest('123 456'), "123 456");
+      equal( typeTest('123 456-7'), "123 456-");
+
+    });
+
+    module("Testing Reversible Masks");
+
+    test("Testing a CPF Mask", function(){
+      testfield.mask('000.000.000-00', {reverse: true});
+
+      equal( typeTest("1"), "1");
+      equal( typeTest("12"), "12");
+      equal( typeTest("123"), "1-23");
+      equal( typeTest("12-34"), "12-34");
+      equal( typeTest("123-45"), "123-45");
+      equal( typeTest("1.234-56"), "1.234-56");
+      equal( typeTest("12.345-67"), "12.345-67");
+      equal( typeTest("123.456-78"), "123.456-78");
+      equal( typeTest("1.234.567-89"), "1.234.567-89");
+      equal( typeTest("12.345.678-90"), "12.345.678-90");
+      equal( typeTest("123.456.789-00"), "123.456.789-00");
+      equal( typeTest("123.456.789-00"), "123.456.789-00");
+
+      equal( typeTest("123.456.789a00"), "123.456.789-00");
+      equal( typeTest("123-a5"), "12-35");
+
+      equal( typeTest("1"), "1");
+      equal( typeTest("12"), "12");
+      equal( typeTest("1-23"), "1-23");
+      equal( typeTest("12-34"), "12-34");
+      equal( typeTest("12-345"), "123-45");
+      equal( typeTest("1.234-56"), "1.234-56");
+      equal( typeTest("12.345-67"), "12.345-67");
+      equal( typeTest("123.456-78"), "123.456-78");
+      equal( typeTest("1.234.567-89"), "1.234.567-89");
+      equal( typeTest("12.345.678-90"), "12.345.678-90");
+      equal( typeTest("123.456.789-00"), "123.456.789-00");
+      equal( typeTest("123.456.789-00"), "123.456.789-00");
+      equal( typeTest("123.456.789a00"), "123.456.789-00");
+    });
+
+  test("Testing Reverse numbers with recursive mask", function(){
+    testfield.mask("#.##0,00", {reverse: true});
+
+    equal(typeTest(""), "");
+    equal(typeTest("1"), "1");
+    equal(typeTest("12"), "12");
+    equal(typeTest("123"), "1,23");
+    equal(typeTest("1,234"), "12,34");
+    equal(typeTest("12,345"), "123,45");
+    equal(typeTest("123,456"), "1.234,56");
+    equal(typeTest("1.234,567"), "12.345,67");
+    equal(typeTest("12.345,678"), "123.456,78");
+    equal(typeTest("123.456,789"), "1.234.567,89");
+    equal(typeTest("1.234.567,890"), "12.345.678,90");
+    equal(typeTest("12.345.678,901"), "123.456.789,01");
+    equal(typeTest("123.456.789,012"), "1.234.567.890,12");
+    equal(typeTest("1.234.567.890,1"), "123.456.789,01");
+    equal(typeTest("123.456.789,0"), "12.345.678,90");
+    equal(typeTest("12.345.678,9"), "1.234.567,89");
+    equal(typeTest("1.234.567,8"), "123.456,78");
+  });
+
+  test("Testing numbers with recursive mask", function(){
+    testfield.mask("0#.#");
+
+    equal(typeTest(""), "");
+    equal(typeTest("1"), "1");
+    equal(typeTest("12"), "12");
+    equal(typeTest("12."), "12.");
+    equal(typeTest("12.3"), "12.3");
+    equal(typeTest("12.34"), "12.34");
+    equal(typeTest("12.345"), "12.34.5");
+    equal(typeTest("12.34.5."), "12.34.5");
+    equal(typeTest("12.34.56"), "12.34.56");
+    equal(typeTest("12.34.567"), "12.34.56.7");
+    equal(typeTest("12.34.56."), "12.34.56.");
+    equal(typeTest("12.34.56"), "12.34.56");
+    equal(typeTest("12.34.5"), "12.34.5");
+  });
+
+  test("Testing numbers with recursive mask with one #", function(){
+    testfield.mask("0#", {});
+
+    equal(typeTest(""), "");
+    equal(typeTest("1"), "1");
+    equal(typeTest("12"), "12");
+    equal(typeTest("123"), "123");
+    equal(typeTest("1234"), "1234");
+    equal(typeTest("12345"), "12345");
+    equal(typeTest("12345"), "12345");
+    equal(typeTest("123456"), "123456");
+    equal(typeTest("1234567"), "1234567");
+    equal(typeTest("123456."), "123456");
+    equal(typeTest("123456"), "123456");
+    equal(typeTest("12345"), "12345");
+  });
+  test("Testing numbers with recursive mask with one # and reverse", function(){
+    testfield.mask("#0", {reverse: true});
+
+    equal(typeTest(""), "");
+    equal(typeTest("1"), "1");
+    equal(typeTest("12"), "12");
+    equal(typeTest("123"), "123");
+    equal(typeTest("1234"), "1234");
+    equal(typeTest("12345"), "12345");
+    equal(typeTest("12345"), "12345");
+    equal(typeTest("123456"), "123456");
+    equal(typeTest("1234567"), "1234567");
+    equal(typeTest("123456."), "123456");
+    equal(typeTest("123456"), "123456");
+    equal(typeTest("12345"), "12345");
+  });
+  test("Testing reversible masks with a literal on the last char", function () {
+      testfield.mask("(99)");
+
+      equal( typeTest("(99"), "(99)");
+    });
+
+  module('Removing mask');
+
+  test("when I get the unmasked value", function(){
+    testfield.mask('(00) 0000-0000', { placeholder: '(__) ____-____' });
+
+    equal(typeTest("1299999999"), "(12) 9999-9999");
+    testfield.unmask()
+    equal(testfield.val(), "1299999999");
+
+    if (window.Zepto) {
+      equal(testfield.attr('placeholder'), '');
+      equal(testfield.attr('maxlength'), null);
+    } else {
+      equal(testfield.attr('placeholder'), undefined);
+      equal(testfield.attr('maxlength'), undefined);
+    }
+  });
+
+  module('Getting Unmasked Value');
+
+  test("when I get the unmasked value", function(){
+    testfield.mask('(00) 0000-0000');
+
+    equal( typeTest("1299999999"), "(12) 9999-9999");
+    equal( testfield.cleanVal(), "1299999999");
+  });
+
+  test("when I get the unmasked value with recursive mask", function(){
+    testfield.mask('#.##0,00', {reverse:true});
+
+    equal( typeTest("123123123123123123", testfield), "1.231.231.231.231.231,23");
+    equal( testfield.cleanVal(), "123123123123123123");
+  });
+
+  module('Masking a value programmatically');
+
+  test("when I get the masked value programmatically", function(){
+    testfield.mask('(00) 0000-0000');
+    typeTest("1299999999", testfield);
+    equal( testfield.masked("3488888888"), "(34) 8888-8888");
+  });
+
+  module('personalized settings')
+
+  test("when adding more itens to the table translation",function(){
+    testfield.mask('00/00/0000', {'translation': {0: {pattern: /[0-9*]/}}});
+
+    equal( typeTest('12/34/5678'), '12/34/5678');
+    equal( typeTest('**/34/5678'), '**/34/5678');
+  });
+
+  test("when adding more itens to the table translation #2",function(){
+    testfield.mask('00/YY/0000', {'translation': {'Y': {pattern: /[0-9*]/}}});
+
+    equal( typeTest('12/34/5678'), '12/34/5678');
+    equal( typeTest('12/**/5678'), '12/**/5678');
+  });
+
+  test("when adding more itens to the table translation #3",function(){
+    var old_translation = $.jMaskGlobals.translation
+    $.jMaskGlobals.translation = {
+      '1': {pattern: /\d/},
+      '9': {pattern: /\d/, optional: true},
+      '#': {pattern: /\d/, recursive: true},
+      'A': {pattern: /[a-zA-Z0-9]/},
+      'S': {pattern: /[a-zA-Z]/}
+    };
+
+    testfield.mask('00/11/1111');
+
+    equal( typeTest('12/12/5678'), '00/12/1256');
+
+    testfield.mask('11/00/1111');
+    equal( typeTest('12/12/5678'), '12/00/1256');
+
+    $.jMaskGlobals.translation = old_translation;
+  });
+
+  test("when adding more itens to the table translation #fallback",function(){
+    testfield.mask('zz/z0/0000', {'translation': {'z': {pattern: /[0-9*]/, fallback: '*'}}});
+
+    equal( typeTest('12/:4/5678'), '12/*4/5678');
+    equal( typeTest('::/:4/5678'), '**/*4/5678');
+  });
+
+  test("test the translation #fallback #1" , function(){
+    testfield.mask('00t00', {'translation': {'t': {pattern: /[:,.]/, fallback: ':'}}});
+
+    equal( typeTest('1'), '1');
+    equal( typeTest('13'), '13');
+    equal( typeTest('137'), '13:7');
+    equal( typeTest('1337'), '13:37');
+    equal( typeTest('13z00'), '13:00');
+  });
+
+  test("test the translation #fallback #2" , function(){
+    testfield.mask('00/t0/t0', {'translation': {'t': {pattern: /[:,.*]/, fallback: '*'}}});
+
+    equal( typeTest('1'), '1');
+    equal( typeTest('13'), '13');
+    equal( typeTest('13/'), '13/');
+    equal( typeTest('13/a'), '13/*');
+    equal( typeTest('13/a1z1'), '13/*1/*1');
+  });
+
+  test("test the translation #fallback #3" , function(){
+    testfield.mask('tt/00/00', {'translation': {'t': {pattern: /[:,.*]/, fallback: '*'}}});
+
+    equal( typeTest('*'), '*');
+    equal( typeTest('13'), '**/13');
+    equal( typeTest('13/'), '**/13/');
+    equal( typeTest('13/a'), '**/13/');
+    equal( typeTest('13/a1z1'), '**/13/11');
+  });
+
+  test("when adding opcional chars",function(){
+    testfield.mask('099.099.099.099');
+
+    equal( typeTest('0.0.0.0'), '0.0.0.0');
+    equal( typeTest('00.00.00.00'), '00.00.00.00');
+    equal( typeTest('00.000.00.000'), '00.000.00.000');
+    equal( typeTest('000.00.000.00'), '000.00.000.00');
+    equal( typeTest('000.000.000.000'), '000.000.000.000');
+    equal( typeTest('000000000000'), '000.000.000.000');
+    equal( typeTest('0'), '0');
+    equal( typeTest('00'), '00');
+    equal( typeTest('00.'), '00.');
+    equal( typeTest('00.0'), '00.0');
+    equal( typeTest('00.00'), '00.00');
+    equal( typeTest('00.00.'), '00.00.');
+    equal( typeTest('00.00.000'), '00.00.000');
+    equal( typeTest('00.00.000.'), '00.00.000.');
+    equal( typeTest('00.00.000.0'), '00.00.000.0');
+    equal( typeTest('00..'), '00.');
+  });
+
+  test("when aplying mask on a element different than a form field",function(){
+    testdiv.mask('000.000.000-00', {reverse: true});
+
+    equal( typeDivTest('12312312312'), '123.123.123-12');
+    equal( typeDivTest('123.123.123-12'), '123.123.123-12');
+    equal( typeDivTest('123.123a123-12'), '123.123.123-12');
+    equal( typeDivTest('191'), '1-91');
+
+    testdiv.mask('00/00/0000');
+    equal( typeDivTest('000000'), '00/00/00');
+    equal( typeDivTest('00000000'), '00/00/0000');
+    equal( typeDivTest('00/00/0000'), '00/00/0000');
+    equal( typeDivTest('0a/00/0000'), '00/00/000');
+
+  });
+
+  module('Testing data-mask attribute support');
+
+  test("Testing data-mask attribute", function(){
+    equal( typeTest("00/", testfieldDataMask), "00/");
+    equal( typeTest("00a", testfieldDataMask), "00/");
+    equal( typeTest("00a00/00", testfieldDataMask), "00/00/00");
+    equal( typeTest("0a/00/00", testfieldDataMask), "00/00/0");
+    equal( typeTest("0a/0a/00", testfieldDataMask), "00/00");
+    equal( typeTest("00000000", testfieldDataMask), "00/00/0000");
+  });
+
+  test("Testing data-mask-reverse attribute", function(){
+    equal( typeTest("0000", testfieldDataMaskWithReverse), "00,00");
+    equal( typeTest("000000", testfieldDataMaskWithReverse), "0.000,00");
+    equal( typeTest("0000000000", testfieldDataMaskWithReverse), "00.000.000,00");
+  });
+
+  module('Event fire test');
+
+  // TODO: need to understand why zepto.js isnt calling change event!
+  if(!window.Zepto) {
+    test('onChange Test', 2, function(){
+      testfield.unmask();
+
+      var callback = sinon.spy();
+      var mock = sinon.mock()
+      var typeAndBlur = function(typedValue){
+        testfield.trigger('keydown');
+        testfield.val(typedValue);
+        testfield.trigger('input');
+        testfield.trigger("blur");
+      };
+
+      testfield.mask('000.(000).000/0-0');
+
+      testfield.on("change", callback);
+
+      typeAndBlur("");
+      typeAndBlur("1");
+      typeAndBlur("12");
+      typeAndBlur("123");
+      typeAndBlur("1234");
+      typeAndBlur("12345");
+      typeAndBlur("123456");
+      typeAndBlur("1234567");
+      typeAndBlur("12345678");
+      typeAndBlur("123456789");
+      typeAndBlur("123456789");
+      typeAndBlur("1234567891");
+      typeAndBlur("12345678912");
+
+      equal(testfield.val(), "123.(456).789/1-2" );
+      equal(true, sinon.match(11).or(12).test(callback.callCount))
+
+      testfield.off("change");
+      testfield.unmask();
+
+    });
+  }
+
+
+  test('onDrop Test', function(){
+    ok(true, "todo");
+  });
+
+  module('testing Remove If Not Match Feature');
+
+  test('test when clearifnotmatch javascript notation', 4, function(){
+    var typeAndFocusOut = function(typedValue){
+      testfield.keydown().val(typedValue).trigger('input');
+      testfield.trigger("focusout");
+    };
+
+    testfield.mask('000');
+
+    typeAndFocusOut("1");
+    equal( testfield.val(), "1" );
+
+    testfield.mask('000', {clearIfNotMatch: true});
+
+    typeAndFocusOut("1");
+    equal( testfield.val(), "" );
+
+    typeAndFocusOut("12");
+    equal( testfield.val(), "" );
+
+    typeAndFocusOut("123");
+    equal( testfield.val(), "123" );
+  });
+
+  test('test when clearifnotmatch javascript notation #2', 4, function(){
+    var typeAndFocusOut = function(typedValue){
+      testfield.keydown().val(typedValue).trigger('input');
+      testfield.trigger("focusout");
+    };
+
+    testfield.mask('7 (000) 000-0000');
+
+    typeAndFocusOut("1");
+    equal( testfield.val(), "7 (1" );
+
+    testfield.mask('7 (000) 000-0000', {clearIfNotMatch: true});
+
+    typeAndFocusOut("1");
+    equal( testfield.val(), "" );
+
+    typeAndFocusOut("12");
+    equal( testfield.val(), "" );
+
+    typeAndFocusOut("7 (123) 123-1234");
+    equal( testfield.val(), "7 (123) 123-1234" );
+  });
+
+  test('test when clearifnotmatch is HTML notation', 3, function(){
+    var typeAndFocusOut = function(typedValue){
+      testfieldDataMaskWithClearIfNotMatch.keydown().val(typedValue).trigger('input');
+      testfieldDataMaskWithClearIfNotMatch.trigger("focusout");
+    };
+
+    typeAndFocusOut("1");
+    equal( testfieldDataMaskWithClearIfNotMatch.val(), "" );
+
+    typeAndFocusOut("12");
+    equal( testfieldDataMaskWithClearIfNotMatch.val(), "" );
+
+    typeAndFocusOut("123");
+    equal( testfieldDataMaskWithClearIfNotMatch.val(), "123" );
+  });
+
+  module('testing Remove If Not Match Feature');
+
+  test('test when clearifnotmatch javascript notation', 1, function(){
+
+    testfield.mask('000', {placeholder: '___'});
+    equal( testfield.attr('placeholder'), "___" );
+
+  });
+
+  test('test when clearifnotmatch with optional mask', 9, function(){
+    // html notation
+    var typeAndBlur = function(field, typedValue){
+      field.keydown().val(typedValue).trigger('input');
+      field.trigger("focusout");
+    };
+
+    typeAndBlur(testfieldDataMaskWithClearIfNotMatchAndOptionalMask, "1");
+    equal( testfieldDataMaskWithClearIfNotMatchAndOptionalMask.val(), "" );
+
+    typeAndBlur(testfieldDataMaskWithClearIfNotMatchAndOptionalMask, "12");
+    equal( testfieldDataMaskWithClearIfNotMatchAndOptionalMask.val(), "12" );
+
+    typeAndBlur(testfieldDataMaskWithClearIfNotMatchAndOptionalMask, "123");
+    equal( testfieldDataMaskWithClearIfNotMatchAndOptionalMask.val(), "123" );
+
+    // javascript notation
+    testfield.mask('099.099.099.099', {clearIfNotMatch: true});
+
+    typeAndBlur(testfield, "1");
+    equal( testfield.val(), "" );
+
+    typeAndBlur(testfield, "123.");
+    equal( testfield.val(), "" );
+
+    typeAndBlur(testfield, "123.0");
+    equal( testfield.val(), "" );
+
+    typeAndBlur(testfield, "123.01.000.");
+    equal( testfield.val(), "" );
+
+    typeAndBlur(testfield, "123.01.000.123");
+    equal( testfield.val(), "123.01.000.123" );
+
+    typeAndBlur(testfield, "0.0.0.0");
+    equal( testfield.val(), "0.0.0.0" );
+  });
+
+  test('test when clearifnotmatch with recursive mask', 4, function(){
+    // html notation
+    var typeAndBlur = function(field, typedValue){
+      field.keydown().val(typedValue).trigger('input');
+      field.trigger("focusout");
+    };
+
+    // javascript notation
+    testfield.mask('#.##0,00', {clearIfNotMatch: true, reverse: true});
+
+    typeAndBlur(testfield, "0");
+    equal( testfield.val(), "" );
+
+    typeAndBlur(testfield, "00");
+    equal( testfield.val(), "" );
+
+    typeAndBlur(testfield, "0,00");
+    equal( testfield.val(), "0,00" );
+
+    typeAndBlur(testfield, "1.000,00");
+    equal( testfield.val(), "1.000,00" );
+
+  });
+
+  module('dynamically loaded elements')
+  test('#non-inputs', function(){
+    expect(5);
+
+    var $container = $('#container-dy-non-inputs');
+    var clock = this.clock;
+    var ticker;
+    var tester;
+    var c = 0;
+
+    function write() {
+
+      if (c >= 5) {
+          clearInterval(ticker);
+          clearInterval(tester);
+          return;
+      }
+
+      c++;
+
+      $container.append('<div class="c">' + c + c + c + c + '</div>');
+      clock.tick(1000);
+    };
+
+    function testIt() {
+
+      var cs = $container.find('.c');
+      $.each(cs, function(k, field){
+        var t = k + 1;
+        equal($(field).text(), '' + t + t + ':' + t + t);
+        t++;
+      });
+    };
+
+    ticker = setInterval(write, 1000);
+
+    write();
+    $('.c', $container).mask('00:00');
+    testIt()
+  });
+});
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/qunit.css b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/qunit.css
new file mode 100644
index 0000000..cb4815b
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/qunit.css
@@ -0,0 +1,244 @@
+/**
+ * QUnit v1.11.0 - A JavaScript Unit Testing Framework
+ *
+ * http://qunitjs.com
+ *
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+/** Font Family and Sizes */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
+	font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
+}
+
+#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
+#qunit-tests { font-size: smaller; }
+
+
+/** Resets */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
+	margin: 0;
+	padding: 0;
+}
+
+
+/** Header */
+
+#qunit-header {
+	padding: 0.5em 0 0.5em 1em;
+
+	color: #8699a4;
+	background-color: #0d3349;
+
+	font-size: 1.5em;
+	line-height: 1em;
+	font-weight: normal;
+
+	border-radius: 5px 5px 0 0;
+	-moz-border-radius: 5px 5px 0 0;
+	-webkit-border-top-right-radius: 5px;
+	-webkit-border-top-left-radius: 5px;
+}
+
+#qunit-header a {
+	text-decoration: none;
+	color: #c2ccd1;
+}
+
+#qunit-header a:hover,
+#qunit-header a:focus {
+	color: #fff;
+}
+
+#qunit-testrunner-toolbar label {
+	display: inline-block;
+	padding: 0 .5em 0 .1em;
+}
+
+#qunit-banner {
+	height: 5px;
+}
+
+#qunit-testrunner-toolbar {
+	padding: 0.5em 0 0.5em 2em;
+	color: #5E740B;
+	background-color: #eee;
+	overflow: hidden;
+}
+
+#qunit-userAgent {
+	padding: 0.5em 0 0.5em 2.5em;
+	background-color: #2b81af;
+	color: #fff;
+	text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
+}
+
+#qunit-modulefilter-container {
+	float: right;
+}
+
+/** Tests: Pass/Fail */
+
+#qunit-tests {
+	list-style-position: inside;
+}
+
+#qunit-tests li {
+	padding: 0.4em 0.5em 0.4em 2.5em;
+	border-bottom: 1px solid #fff;
+	list-style-position: inside;
+}
+
+#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running  {
+	display: none;
+}
+
+#qunit-tests li strong {
+	cursor: pointer;
+}
+
+#qunit-tests li a {
+	padding: 0.5em;
+	color: #c2ccd1;
+	text-decoration: none;
+}
+#qunit-tests li a:hover,
+#qunit-tests li a:focus {
+	color: #000;
+}
+
+#qunit-tests li .runtime {
+	float: right;
+	font-size: smaller;
+}
+
+.qunit-assert-list {
+	margin-top: 0.5em;
+	padding: 0.5em;
+
+	background-color: #fff;
+
+	border-radius: 5px;
+	-moz-border-radius: 5px;
+	-webkit-border-radius: 5px;
+}
+
+.qunit-collapsed {
+	display: none;
+}
+
+#qunit-tests table {
+	border-collapse: collapse;
+	margin-top: .2em;
+}
+
+#qunit-tests th {
+	text-align: right;
+	vertical-align: top;
+	padding: 0 .5em 0 0;
+}
+
+#qunit-tests td {
+	vertical-align: top;
+}
+
+#qunit-tests pre {
+	margin: 0;
+	white-space: pre-wrap;
+	word-wrap: break-word;
+}
+
+#qunit-tests del {
+	background-color: #e0f2be;
+	color: #374e0c;
+	text-decoration: none;
+}
+
+#qunit-tests ins {
+	background-color: #ffcaca;
+	color: #500;
+	text-decoration: none;
+}
+
+/*** Test Counts */
+
+#qunit-tests b.counts                       { color: black; }
+#qunit-tests b.passed                       { color: #5E740B; }
+#qunit-tests b.failed                       { color: #710909; }
+
+#qunit-tests li li {
+	padding: 5px;
+	background-color: #fff;
+	border-bottom: none;
+	list-style-position: inside;
+}
+
+/*** Passing Styles */
+
+#qunit-tests li li.pass {
+	color: #3c510c;
+	background-color: #fff;
+	border-left: 10px solid #C6E746;
+}
+
+#qunit-tests .pass                          { color: #528CE0; background-color: #D2E0E6; }
+#qunit-tests .pass .test-name               { color: #366097; }
+
+#qunit-tests .pass .test-actual,
+#qunit-tests .pass .test-expected           { color: #999999; }
+
+#qunit-banner.qunit-pass                    { background-color: #C6E746; }
+
+/*** Failing Styles */
+
+#qunit-tests li li.fail {
+	color: #710909;
+	background-color: #fff;
+	border-left: 10px solid #EE5757;
+	white-space: pre;
+}
+
+#qunit-tests > li:last-child {
+	border-radius: 0 0 5px 5px;
+	-moz-border-radius: 0 0 5px 5px;
+	-webkit-border-bottom-right-radius: 5px;
+	-webkit-border-bottom-left-radius: 5px;
+}
+
+#qunit-tests .fail                          { color: #000000; background-color: #EE5757; }
+#qunit-tests .fail .test-name,
+#qunit-tests .fail .module-name             { color: #000000; }
+
+#qunit-tests .fail .test-actual             { color: #EE5757; }
+#qunit-tests .fail .test-expected           { color: green;   }
+
+#qunit-banner.qunit-fail                    { background-color: #EE5757; }
+
+
+/** Result */
+
+#qunit-testresult {
+	padding: 0.5em 0.5em 0.5em 2.5em;
+
+	color: #2b81af;
+	background-color: #D2E0E6;
+
+	border-bottom: 1px solid white;
+}
+#qunit-testresult .module-name {
+	font-weight: bold;
+}
+
+/** Fixture */
+
+#qunit-fixture {
+	position: absolute;
+	top: -10000px;
+	left: -10000px;
+	width: 1000px;
+	height: 1000px;
+}
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/qunit.js b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/qunit.js
new file mode 100644
index 0000000..9729418
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/qunit.js
@@ -0,0 +1,2152 @@
+/**
+ * QUnit v1.11.0 - A JavaScript Unit Testing Framework
+ *
+ * http://qunitjs.com
+ *
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+(function( window ) {
+
+var QUnit,
+	assert,
+	config,
+	onErrorFnPrev,
+	testId = 0,
+	fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""),
+	toString = Object.prototype.toString,
+	hasOwn = Object.prototype.hasOwnProperty,
+	// Keep a local reference to Date (GH-283)
+	Date = window.Date,
+	defined = {
+		setTimeout: typeof window.setTimeout !== "undefined",
+		sessionStorage: (function() {
+			var x = "qunit-test-string";
+			try {
+				sessionStorage.setItem( x, x );
+				sessionStorage.removeItem( x );
+				return true;
+			} catch( e ) {
+				return false;
+			}
+		}())
+	},
+	/**
+	 * Provides a normalized error string, correcting an issue
+	 * with IE 7 (and prior) where Error.prototype.toString is
+	 * not properly implemented
+	 *
+	 * Based on http://es5.github.com/#x15.11.4.4
+	 *
+	 * @param {String|Error} error
+	 * @return {String} error message
+	 */
+	errorString = function( error ) {
+		var name, message,
+			errorString = error.toString();
+		if ( errorString.substring( 0, 7 ) === "[object" ) {
+			name = error.name ? error.name.toString() : "Error";
+			message = error.message ? error.message.toString() : "";
+			if ( name && message ) {
+				return name + ": " + message;
+			} else if ( name ) {
+				return name;
+			} else if ( message ) {
+				return message;
+			} else {
+				return "Error";
+			}
+		} else {
+			return errorString;
+		}
+	},
+	/**
+	 * Makes a clone of an object using only Array or Object as base,
+	 * and copies over the own enumerable properties.
+	 *
+	 * @param {Object} obj
+	 * @return {Object} New object with only the own properties (recursively).
+	 */
+	objectValues = function( obj ) {
+		// Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392.
+		/*jshint newcap: false */
+		var key, val,
+			vals = QUnit.is( "array", obj ) ? [] : {};
+		for ( key in obj ) {
+			if ( hasOwn.call( obj, key ) ) {
+				val = obj[key];
+				vals[key] = val === Object(val) ? objectValues(val) : val;
+			}
+		}
+		return vals;
+	};
+
+function Test( settings ) {
+	extend( this, settings );
+	this.assertions = [];
+	this.testNumber = ++Test.count;
+}
+
+Test.count = 0;
+
+Test.prototype = {
+	init: function() {
+		var a, b, li,
+			tests = id( "qunit-tests" );
+
+		if ( tests ) {
+			b = document.createElement( "strong" );
+			b.innerHTML = this.nameHtml;
+
+			// `a` initialized at top of scope
+			a = document.createElement( "a" );
+			a.innerHTML = "Rerun";
+			a.href = QUnit.url({ testNumber: this.testNumber });
+
+			li = document.createElement( "li" );
+			li.appendChild( b );
+			li.appendChild( a );
+			li.className = "running";
+			li.id = this.id = "qunit-test-output" + testId++;
+
+			tests.appendChild( li );
+		}
+	},
+	setup: function() {
+		if ( this.module !== config.previousModule ) {
+			if ( config.previousModule ) {
+				runLoggingCallbacks( "moduleDone", QUnit, {
+					name: config.previousModule,
+					failed: config.moduleStats.bad,
+					passed: config.moduleStats.all - config.moduleStats.bad,
+					total: config.moduleStats.all
+				});
+			}
+			config.previousModule = this.module;
+			config.moduleStats = { all: 0, bad: 0 };
+			runLoggingCallbacks( "moduleStart", QUnit, {
+				name: this.module
+			});
+		} else if ( config.autorun ) {
+			runLoggingCallbacks( "moduleStart", QUnit, {
+				name: this.module
+			});
+		}
+
+		config.current = this;
+
+		this.testEnvironment = extend({
+			setup: function() {},
+			teardown: function() {}
+		}, this.moduleTestEnvironment );
+
+		this.started = +new Date();
+		runLoggingCallbacks( "testStart", QUnit, {
+			name: this.testName,
+			module: this.module
+		});
+
+		// allow utility functions to access the current test environment
+		// TODO why??
+		QUnit.current_testEnvironment = this.testEnvironment;
+
+		if ( !config.pollution ) {
+			saveGlobal();
+		}
+		if ( config.notrycatch ) {
+			this.testEnvironment.setup.call( this.testEnvironment );
+			return;
+		}
+		try {
+			this.testEnvironment.setup.call( this.testEnvironment );
+		} catch( e ) {
+			QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
+		}
+	},
+	run: function() {
+		config.current = this;
+
+		var running = id( "qunit-testresult" );
+
+		if ( running ) {
+			running.innerHTML = "Running: <br/>" + this.nameHtml;
+		}
+
+		if ( this.async ) {
+			QUnit.stop();
+		}
+
+		this.callbackStarted = +new Date();
+
+		if ( config.notrycatch ) {
+			this.callback.call( this.testEnvironment, QUnit.assert );
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+			return;
+		}
+
+		try {
+			this.callback.call( this.testEnvironment, QUnit.assert );
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+		} catch( e ) {
+			this.callbackRuntime = +new Date() - this.callbackStarted;
+
+			QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
+			// else next test will carry the responsibility
+			saveGlobal();
+
+			// Restart the tests if they're blocking
+			if ( config.blocking ) {
+				QUnit.start();
+			}
+		}
+	},
+	teardown: function() {
+		config.current = this;
+		if ( config.notrycatch ) {
+			if ( typeof this.callbackRuntime === "undefined" ) {
+				this.callbackRuntime = +new Date() - this.callbackStarted;
+			}
+			this.testEnvironment.teardown.call( this.testEnvironment );
+			return;
+		} else {
+			try {
+				this.testEnvironment.teardown.call( this.testEnvironment );
+			} catch( e ) {
+				QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
+			}
+		}
+		checkPollution();
+	},
+	finish: function() {
+		config.current = this;
+		if ( config.requireExpects && this.expected === null ) {
+			QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack );
+		} else if ( this.expected !== null && this.expected !== this.assertions.length ) {
+			QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack );
+		} else if ( this.expected === null && !this.assertions.length ) {
+			QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack );
+		}
+
+		var i, assertion, a, b, time, li, ol,
+			test = this,
+			good = 0,
+			bad = 0,
+			tests = id( "qunit-tests" );
+
+		this.runtime = +new Date() - this.started;
+		config.stats.all += this.assertions.length;
+		config.moduleStats.all += this.assertions.length;
+
+		if ( tests ) {
+			ol = document.createElement( "ol" );
+			ol.className = "qunit-assert-list";
+
+			for ( i = 0; i < this.assertions.length; i++ ) {
+				assertion = this.assertions[i];
+
+				li = document.createElement( "li" );
+				li.className = assertion.result ? "pass" : "fail";
+				li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" );
+				ol.appendChild( li );
+
+				if ( assertion.result ) {
+					good++;
+				} else {
+					bad++;
+					config.stats.bad++;
+					config.moduleStats.bad++;
+				}
+			}
+
+			// store result when possible
+			if ( QUnit.config.reorder && defined.sessionStorage ) {
+				if ( bad ) {
+					sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad );
+				} else {
+					sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName );
+				}
+			}
+
+			if ( bad === 0 ) {
+				addClass( ol, "qunit-collapsed" );
+			}
+
+			// `b` initialized at top of scope
+			b = document.createElement( "strong" );
+			b.innerHTML = this.nameHtml + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
+
+			addEvent(b, "click", function() {
+				var next = b.parentNode.lastChild,
+					collapsed = hasClass( next, "qunit-collapsed" );
+				( collapsed ? removeClass : addClass )( next, "qunit-collapsed" );
+			});
+
+			addEvent(b, "dblclick", function( e ) {
+				var target = e && e.target ? e.target : window.event.srcElement;
+				if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) {
+					target = target.parentNode;
+				}
+				if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
+					window.location = QUnit.url({ testNumber: test.testNumber });
+				}
+			});
+
+			// `time` initialized at top of scope
+			time = document.createElement( "span" );
+			time.className = "runtime";
+			time.innerHTML = this.runtime + " ms";
+
+			// `li` initialized at top of scope
+			li = id( this.id );
+			li.className = bad ? "fail" : "pass";
+			li.removeChild( li.firstChild );
+			a = li.firstChild;
+			li.appendChild( b );
+			li.appendChild( a );
+			li.appendChild( time );
+			li.appendChild( ol );
+
+		} else {
+			for ( i = 0; i < this.assertions.length; i++ ) {
+				if ( !this.assertions[i].result ) {
+					bad++;
+					config.stats.bad++;
+					config.moduleStats.bad++;
+				}
+			}
+		}
+
+		runLoggingCallbacks( "testDone", QUnit, {
+			name: this.testName,
+			module: this.module,
+			failed: bad,
+			passed: this.assertions.length - bad,
+			total: this.assertions.length,
+			duration: this.runtime
+		});
+
+		QUnit.reset();
+
+		config.current = undefined;
+	},
+
+	queue: function() {
+		var bad,
+			test = this;
+
+		synchronize(function() {
+			test.init();
+		});
+		function run() {
+			// each of these can by async
+			synchronize(function() {
+				test.setup();
+			});
+			synchronize(function() {
+				test.run();
+			});
+			synchronize(function() {
+				test.teardown();
+			});
+			synchronize(function() {
+				test.finish();
+			});
+		}
+
+		// `bad` initialized at top of scope
+		// defer when previous test run passed, if storage is available
+		bad = QUnit.config.reorder && defined.sessionStorage &&
+						+sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName );
+
+		if ( bad ) {
+			run();
+		} else {
+			synchronize( run, true );
+		}
+	}
+};
+
+// Root QUnit object.
+// `QUnit` initialized at top of scope
+QUnit = {
+
+	// call on start of module test to prepend name to all tests
+	module: function( name, testEnvironment ) {
+		config.currentModule = name;
+		config.currentModuleTestEnvironment = testEnvironment;
+		config.modules[name] = true;
+	},
+
+	asyncTest: function( testName, expected, callback ) {
+		if ( arguments.length === 2 ) {
+			callback = expected;
+			expected = null;
+		}
+
+		QUnit.test( testName, expected, callback, true );
+	},
+
+	test: function( testName, expected, callback, async ) {
+		var test,
+			nameHtml = "<span class='test-name'>" + escapeText( testName ) + "</span>";
+
+		if ( arguments.length === 2 ) {
+			callback = expected;
+			expected = null;
+		}
+
+		if ( config.currentModule ) {
+			nameHtml = "<span class='module-name'>" + escapeText( config.currentModule ) + "</span>: " + nameHtml;
+		}
+
+		test = new Test({
+			nameHtml: nameHtml,
+			testName: testName,
+			expected: expected,
+			async: async,
+			callback: callback,
+			module: config.currentModule,
+			moduleTestEnvironment: config.currentModuleTestEnvironment,
+			stack: sourceFromStacktrace( 2 )
+		});
+
+		if ( !validTest( test ) ) {
+			return;
+		}
+
+		test.queue();
+	},
+
+	// Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
+	expect: function( asserts ) {
+		if (arguments.length === 1) {
+			config.current.expected = asserts;
+		} else {
+			return config.current.expected;
+		}
+	},
+
+	start: function( count ) {
+		// QUnit hasn't been initialized yet.
+		// Note: RequireJS (et al) may delay onLoad
+		if ( config.semaphore === undefined ) {
+			QUnit.begin(function() {
+				// This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first
+				setTimeout(function() {
+					QUnit.start( count );
+				});
+			});
+			return;
+		}
+
+		config.semaphore -= count || 1;
+		// don't start until equal number of stop-calls
+		if ( config.semaphore > 0 ) {
+			return;
+		}
+		// ignore if start is called more often then stop
+		if ( config.semaphore < 0 ) {
+			config.semaphore = 0;
+			QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) );
+			return;
+		}
+		// A slight delay, to avoid any current callbacks
+		if ( defined.setTimeout ) {
+			window.setTimeout(function() {
+				if ( config.semaphore > 0 ) {
+					return;
+				}
+				if ( config.timeout ) {
+					clearTimeout( config.timeout );
+				}
+
+				config.blocking = false;
+				process( true );
+			}, 13);
+		} else {
+			config.blocking = false;
+			process( true );
+		}
+	},
+
+	stop: function( count ) {
+		config.semaphore += count || 1;
+		config.blocking = true;
+
+		if ( config.testTimeout && defined.setTimeout ) {
+			clearTimeout( config.timeout );
+			config.timeout = window.setTimeout(function() {
+				QUnit.ok( false, "Test timed out" );
+				config.semaphore = 1;
+				QUnit.start();
+			}, config.testTimeout );
+		}
+	}
+};
+
+// `assert` initialized at top of scope
+// Asssert helpers
+// All of these must either call QUnit.push() or manually do:
+// - runLoggingCallbacks( "log", .. );
+// - config.current.assertions.push({ .. });
+// We attach it to the QUnit object *after* we expose the public API,
+// otherwise `assert` will become a global variable in browsers (#341).
+assert = {
+	/**
+	 * Asserts rough true-ish result.
+	 * @name ok
+	 * @function
+	 * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
+	 */
+	ok: function( result, msg ) {
+		if ( !config.current ) {
+			throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) );
+		}
+		result = !!result;
+
+		var source,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: result,
+				message: msg
+			};
+
+		msg = escapeText( msg || (result ? "okay" : "failed" ) );
+		msg = "<span class='test-message'>" + msg + "</span>";
+
+		if ( !result ) {
+			source = sourceFromStacktrace( 2 );
+			if ( source ) {
+				details.source = source;
+				msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr></table>";
+			}
+		}
+		runLoggingCallbacks( "log", QUnit, details );
+		config.current.assertions.push({
+			result: result,
+			message: msg
+		});
+	},
+
+	/**
+	 * Assert that the first two arguments are equal, with an optional message.
+	 * Prints out both actual and expected values.
+	 * @name equal
+	 * @function
+	 * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" );
+	 */
+	equal: function( actual, expected, message ) {
+		/*jshint eqeqeq:false */
+		QUnit.push( expected == actual, actual, expected, message );
+	},
+
+	/**
+	 * @name notEqual
+	 * @function
+	 */
+	notEqual: function( actual, expected, message ) {
+		/*jshint eqeqeq:false */
+		QUnit.push( expected != actual, actual, expected, message );
+	},
+
+	/**
+	 * @name propEqual
+	 * @function
+	 */
+	propEqual: function( actual, expected, message ) {
+		actual = objectValues(actual);
+		expected = objectValues(expected);
+		QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name notPropEqual
+	 * @function
+	 */
+	notPropEqual: function( actual, expected, message ) {
+		actual = objectValues(actual);
+		expected = objectValues(expected);
+		QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name deepEqual
+	 * @function
+	 */
+	deepEqual: function( actual, expected, message ) {
+		QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name notDeepEqual
+	 * @function
+	 */
+	notDeepEqual: function( actual, expected, message ) {
+		QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
+	},
+
+	/**
+	 * @name strictEqual
+	 * @function
+	 */
+	strictEqual: function( actual, expected, message ) {
+		QUnit.push( expected === actual, actual, expected, message );
+	},
+
+	/**
+	 * @name notStrictEqual
+	 * @function
+	 */
+	notStrictEqual: function( actual, expected, message ) {
+		QUnit.push( expected !== actual, actual, expected, message );
+	},
+
+	"throws": function( block, expected, message ) {
+		var actual,
+			expectedOutput = expected,
+			ok = false;
+
+		// 'expected' is optional
+		if ( typeof expected === "string" ) {
+			message = expected;
+			expected = null;
+		}
+
+		config.current.ignoreGlobalErrors = true;
+		try {
+			block.call( config.current.testEnvironment );
+		} catch (e) {
+			actual = e;
+		}
+		config.current.ignoreGlobalErrors = false;
+
+		if ( actual ) {
+			// we don't want to validate thrown error
+			if ( !expected ) {
+				ok = true;
+				expectedOutput = null;
+			// expected is a regexp
+			} else if ( QUnit.objectType( expected ) === "regexp" ) {
+				ok = expected.test( errorString( actual ) );
+			// expected is a constructor
+			} else if ( actual instanceof expected ) {
+				ok = true;
+			// expected is a validation function which returns true is validation passed
+			} else if ( expected.call( {}, actual ) === true ) {
+				expectedOutput = null;
+				ok = true;
+			}
+
+			QUnit.push( ok, actual, expectedOutput, message );
+		} else {
+			QUnit.pushFailure( message, null, 'No exception was thrown.' );
+		}
+	}
+};
+
+/**
+ * @deprecate since 1.8.0
+ * Kept assertion helpers in root for backwards compatibility.
+ */
+extend( QUnit, assert );
+
+/**
+ * @deprecated since 1.9.0
+ * Kept root "raises()" for backwards compatibility.
+ * (Note that we don't introduce assert.raises).
+ */
+QUnit.raises = assert[ "throws" ];
+
+/**
+ * @deprecated since 1.0.0, replaced with error pushes since 1.3.0
+ * Kept to avoid TypeErrors for undefined methods.
+ */
+QUnit.equals = function() {
+	QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" );
+};
+QUnit.same = function() {
+	QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" );
+};
+
+// We want access to the constructor's prototype
+(function() {
+	function F() {}
+	F.prototype = QUnit;
+	QUnit = new F();
+	// Make F QUnit's constructor so that we can add to the prototype later
+	QUnit.constructor = F;
+}());
+
+/**
+ * Config object: Maintain internal state
+ * Later exposed as QUnit.config
+ * `config` initialized at top of scope
+ */
+config = {
+	// The queue of tests to run
+	queue: [],
+
+	// block until document ready
+	blocking: true,
+
+	// when enabled, show only failing tests
+	// gets persisted through sessionStorage and can be changed in UI via checkbox
+	hidepassed: false,
+
+	// by default, run previously failed tests first
+	// very useful in combination with "Hide passed tests" checked
+	reorder: true,
+
+	// by default, modify document.title when suite is done
+	altertitle: true,
+
+	// when enabled, all tests must call expect()
+	requireExpects: false,
+
+	// add checkboxes that are persisted in the query-string
+	// when enabled, the id is set to `true` as a `QUnit.config` property
+	urlConfig: [
+		{
+			id: "noglobals",
+			label: "Check for Globals",
+			tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings."
+		},
+		{
+			id: "notrycatch",
+			label: "No try-catch",
+			tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings."
+		}
+	],
+
+	// Set of all modules.
+	modules: {},
+
+	// logging callback queues
+	begin: [],
+	done: [],
+	log: [],
+	testStart: [],
+	testDone: [],
+	moduleStart: [],
+	moduleDone: []
+};
+
+// Export global variables, unless an 'exports' object exists,
+// in that case we assume we're in CommonJS (dealt with on the bottom of the script)
+if ( typeof exports === "undefined" ) {
+	extend( window, QUnit );
+
+	// Expose QUnit object
+	window.QUnit = QUnit;
+}
+
+// Initialize more QUnit.config and QUnit.urlParams
+(function() {
+	var i,
+		location = window.location || { search: "", protocol: "file:" },
+		params = location.search.slice( 1 ).split( "&" ),
+		length = params.length,
+		urlParams = {},
+		current;
+
+	if ( params[ 0 ] ) {
+		for ( i = 0; i < length; i++ ) {
+			current = params[ i ].split( "=" );
+			current[ 0 ] = decodeURIComponent( current[ 0 ] );
+			// allow just a key to turn on a flag, e.g., test.html?noglobals
+			current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
+			urlParams[ current[ 0 ] ] = current[ 1 ];
+		}
+	}
+
+	QUnit.urlParams = urlParams;
+
+	// String search anywhere in moduleName+testName
+	config.filter = urlParams.filter;
+
+	// Exact match of the module name
+	config.module = urlParams.module;
+
+	config.testNumber = parseInt( urlParams.testNumber, 10 ) || null;
+
+	// Figure out if we're running the tests from a server or not
+	QUnit.isLocal = location.protocol === "file:";
+}());
+
+// Extend QUnit object,
+// these after set here because they should not be exposed as global functions
+extend( QUnit, {
+	assert: assert,
+
+	config: config,
+
+	// Initialize the configuration options
+	init: function() {
+		extend( config, {
+			stats: { all: 0, bad: 0 },
+			moduleStats: { all: 0, bad: 0 },
+			started: +new Date(),
+			updateRate: 1000,
+			blocking: false,
+			autostart: true,
+			autorun: false,
+			filter: "",
+			queue: [],
+			semaphore: 1
+		});
+
+		var tests, banner, result,
+			qunit = id( "qunit" );
+
+		if ( qunit ) {
+			qunit.innerHTML =
+				"<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
+				"<h2 id='qunit-banner'></h2>" +
+				"<div id='qunit-testrunner-toolbar'></div>" +
+				"<h2 id='qunit-userAgent'></h2>" +
+				"<ol id='qunit-tests'></ol>";
+		}
+
+		tests = id( "qunit-tests" );
+		banner = id( "qunit-banner" );
+		result = id( "qunit-testresult" );
+
+		if ( tests ) {
+			tests.innerHTML = "";
+		}
+
+		if ( banner ) {
+			banner.className = "";
+		}
+
+		if ( result ) {
+			result.parentNode.removeChild( result );
+		}
+
+		if ( tests ) {
+			result = document.createElement( "p" );
+			result.id = "qunit-testresult";
+			result.className = "result";
+			tests.parentNode.insertBefore( result, tests );
+			result.innerHTML = "Running...<br/>&nbsp;";
+		}
+	},
+
+	// Resets the test setup. Useful for tests that modify the DOM.
+	reset: function() {
+		var fixture = id( "qunit-fixture" );
+		if ( fixture ) {
+			fixture.innerHTML = config.fixture;
+		}
+	},
+
+	// Trigger an event on an element.
+	// @example triggerEvent( document.body, "click" );
+	triggerEvent: function( elem, type, event ) {
+		if ( document.createEvent ) {
+			event = document.createEvent( "MouseEvents" );
+			event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
+				0, 0, 0, 0, 0, false, false, false, false, 0, null);
+
+			elem.dispatchEvent( event );
+		} else if ( elem.fireEvent ) {
+			elem.fireEvent( "on" + type );
+		}
+	},
+
+	// Safe object type checking
+	is: function( type, obj ) {
+		return QUnit.objectType( obj ) === type;
+	},
+
+	objectType: function( obj ) {
+		if ( typeof obj === "undefined" ) {
+				return "undefined";
+		// consider: typeof null === object
+		}
+		if ( obj === null ) {
+				return "null";
+		}
+
+		var match = toString.call( obj ).match(/^\[object\s(.*)\]$/),
+			type = match && match[1] || "";
+
+		switch ( type ) {
+			case "Number":
+				if ( isNaN(obj) ) {
+					return "nan";
+				}
+				return "number";
+			case "String":
+			case "Boolean":
+			case "Array":
+			case "Date":
+			case "RegExp":
+			case "Function":
+				return type.toLowerCase();
+		}
+		if ( typeof obj === "object" ) {
+			return "object";
+		}
+		return undefined;
+	},
+
+	push: function( result, actual, expected, message ) {
+		if ( !config.current ) {
+			throw new Error( "assertion outside test context, was " + sourceFromStacktrace() );
+		}
+
+		var output, source,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: result,
+				message: message,
+				actual: actual,
+				expected: expected
+			};
+
+		message = escapeText( message ) || ( result ? "okay" : "failed" );
+		message = "<span class='test-message'>" + message + "</span>";
+		output = message;
+
+		if ( !result ) {
+			expected = escapeText( QUnit.jsDump.parse(expected) );
+			actual = escapeText( QUnit.jsDump.parse(actual) );
+			output += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" + expected + "</pre></td></tr>";
+
+			if ( actual !== expected ) {
+				output += "<tr class='test-actual'><th>Result: </th><td><pre>" + actual + "</pre></td></tr>";
+				output += "<tr class='test-diff'><th>Diff: </th><td><pre>" + QUnit.diff( expected, actual ) + "</pre></td></tr>";
+			}
+
+			source = sourceFromStacktrace();
+
+			if ( source ) {
+				details.source = source;
+				output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
+			}
+
+			output += "</table>";
+		}
+
+		runLoggingCallbacks( "log", QUnit, details );
+
+		config.current.assertions.push({
+			result: !!result,
+			message: output
+		});
+	},
+
+	pushFailure: function( message, source, actual ) {
+		if ( !config.current ) {
+			throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) );
+		}
+
+		var output,
+			details = {
+				module: config.current.module,
+				name: config.current.testName,
+				result: false,
+				message: message
+			};
+
+		message = escapeText( message ) || "error";
+		message = "<span class='test-message'>" + message + "</span>";
+		output = message;
+
+		output += "<table>";
+
+		if ( actual ) {
+			output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText( actual ) + "</pre></td></tr>";
+		}
+
+		if ( source ) {
+			details.source = source;
+			output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
+		}
+
+		output += "</table>";
+
+		runLoggingCallbacks( "log", QUnit, details );
+
+		config.current.assertions.push({
+			result: false,
+			message: output
+		});
+	},
+
+	url: function( params ) {
+		params = extend( extend( {}, QUnit.urlParams ), params );
+		var key,
+			querystring = "?";
+
+		for ( key in params ) {
+			if ( !hasOwn.call( params, key ) ) {
+				continue;
+			}
+			querystring += encodeURIComponent( key ) + "=" +
+				encodeURIComponent( params[ key ] ) + "&";
+		}
+		return window.location.protocol + "//" + window.location.host +
+			window.location.pathname + querystring.slice( 0, -1 );
+	},
+
+	extend: extend,
+	id: id,
+	addEvent: addEvent
+	// load, equiv, jsDump, diff: Attached later
+});
+
+/**
+ * @deprecated: Created for backwards compatibility with test runner that set the hook function
+ * into QUnit.{hook}, instead of invoking it and passing the hook function.
+ * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here.
+ * Doing this allows us to tell if the following methods have been overwritten on the actual
+ * QUnit object.
+ */
+extend( QUnit.constructor.prototype, {
+
+	// Logging callbacks; all receive a single argument with the listed properties
+	// run test/logs.html for any related changes
+	begin: registerLoggingCallback( "begin" ),
+
+	// done: { failed, passed, total, runtime }
+	done: registerLoggingCallback( "done" ),
+
+	// log: { result, actual, expected, message }
+	log: registerLoggingCallback( "log" ),
+
+	// testStart: { name }
+	testStart: registerLoggingCallback( "testStart" ),
+
+	// testDone: { name, failed, passed, total, duration }
+	testDone: registerLoggingCallback( "testDone" ),
+
+	// moduleStart: { name }
+	moduleStart: registerLoggingCallback( "moduleStart" ),
+
+	// moduleDone: { name, failed, passed, total }
+	moduleDone: registerLoggingCallback( "moduleDone" )
+});
+
+if ( typeof document === "undefined" || document.readyState === "complete" ) {
+	config.autorun = true;
+}
+
+QUnit.load = function() {
+	runLoggingCallbacks( "begin", QUnit, {} );
+
+	// Initialize the config, saving the execution queue
+	var banner, filter, i, label, len, main, ol, toolbar, userAgent, val,
+		urlConfigCheckboxesContainer, urlConfigCheckboxes, moduleFilter,
+		numModules = 0,
+		moduleFilterHtml = "",
+		urlConfigHtml = "",
+		oldconfig = extend( {}, config );
+
+	QUnit.init();
+	extend(config, oldconfig);
+
+	config.blocking = false;
+
+	len = config.urlConfig.length;
+
+	for ( i = 0; i < len; i++ ) {
+		val = config.urlConfig[i];
+		if ( typeof val === "string" ) {
+			val = {
+				id: val,
+				label: val,
+				tooltip: "[no tooltip available]"
+			};
+		}
+		config[ val.id ] = QUnit.urlParams[ val.id ];
+		urlConfigHtml += "<input id='qunit-urlconfig-" + escapeText( val.id ) +
+			"' name='" + escapeText( val.id ) +
+			"' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) +
+			" title='" + escapeText( val.tooltip ) +
+			"'><label for='qunit-urlconfig-" + escapeText( val.id ) +
+			"' title='" + escapeText( val.tooltip ) + "'>" + val.label + "</label>";
+	}
+
+	moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " +
+		( config.module === undefined  ? "selected='selected'" : "" ) +
+		">< All Modules ></option>";
+
+	for ( i in config.modules ) {
+		if ( config.modules.hasOwnProperty( i ) ) {
+			numModules += 1;
+			moduleFilterHtml += "<option value='" + escapeText( encodeURIComponent(i) ) + "' " +
+				( config.module === i ? "selected='selected'" : "" ) +
+				">" + escapeText(i) + "</option>";
+		}
+	}
+	moduleFilterHtml += "</select>";
+
+	// `userAgent` initialized at top of scope
+	userAgent = id( "qunit-userAgent" );
+	if ( userAgent ) {
+		userAgent.innerHTML = navigator.userAgent;
+	}
+
+	// `banner` initialized at top of scope
+	banner = id( "qunit-header" );
+	if ( banner ) {
+		banner.innerHTML = "<a href='" + QUnit.url({ filter: undefined, module: undefined, testNumber: undefined }) + "'>" + banner.innerHTML + "</a> ";
+	}
+
+	// `toolbar` initialized at top of scope
+	toolbar = id( "qunit-testrunner-toolbar" );
+	if ( toolbar ) {
+		// `filter` initialized at top of scope
+		filter = document.createElement( "input" );
+		filter.type = "checkbox";
+		filter.id = "qunit-filter-pass";
+
+		addEvent( filter, "click", function() {
+			var tmp,
+				ol = document.getElementById( "qunit-tests" );
+
+			if ( filter.checked ) {
+				ol.className = ol.className + " hidepass";
+			} else {
+				tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " ";
+				ol.className = tmp.replace( / hidepass /, " " );
+			}
+			if ( defined.sessionStorage ) {
+				if (filter.checked) {
+					sessionStorage.setItem( "qunit-filter-passed-tests", "true" );
+				} else {
+					sessionStorage.removeItem( "qunit-filter-passed-tests" );
+				}
+			}
+		});
+
+		if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) {
+			filter.checked = true;
+			// `ol` initialized at top of scope
+			ol = document.getElementById( "qunit-tests" );
+			ol.className = ol.className + " hidepass";
+		}
+		toolbar.appendChild( filter );
+
+		// `label` initialized at top of scope
+		label = document.createElement( "label" );
+		label.setAttribute( "for", "qunit-filter-pass" );
+		label.setAttribute( "title", "Only show tests and assertons that fail. Stored in sessionStorage." );
+		label.innerHTML = "Hide passed tests";
+		toolbar.appendChild( label );
+
+		urlConfigCheckboxesContainer = document.createElement("span");
+		urlConfigCheckboxesContainer.innerHTML = urlConfigHtml;
+		urlConfigCheckboxes = urlConfigCheckboxesContainer.getElementsByTagName("input");
+		// For oldIE support:
+		// * Add handlers to the individual elements instead of the container
+		// * Use "click" instead of "change"
+		// * Fallback from event.target to event.srcElement
+		addEvents( urlConfigCheckboxes, "click", function( event ) {
+			var params = {},
+				target = event.target || event.srcElement;
+			params[ target.name ] = target.checked ? true : undefined;
+			window.location = QUnit.url( params );
+		});
+		toolbar.appendChild( urlConfigCheckboxesContainer );
+
+		if (numModules > 1) {
+			moduleFilter = document.createElement( 'span' );
+			moduleFilter.setAttribute( 'id', 'qunit-modulefilter-container' );
+			moduleFilter.innerHTML = moduleFilterHtml;
+			addEvent( moduleFilter.lastChild, "change", function() {
+				var selectBox = moduleFilter.getElementsByTagName("select")[0],
+					selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
+
+				window.location = QUnit.url( { module: ( selectedModule === "" ) ? undefined : selectedModule } );
+			});
+			toolbar.appendChild(moduleFilter);
+		}
+	}
+
+	// `main` initialized at top of scope
+	main = id( "qunit-fixture" );
+	if ( main ) {
+		config.fixture = main.innerHTML;
+	}
+
+	if ( config.autostart ) {
+		QUnit.start();
+	}
+};
+
+addEvent( window, "load", QUnit.load );
+
+// `onErrorFnPrev` initialized at top of scope
+// Preserve other handlers
+onErrorFnPrev = window.onerror;
+
+// Cover uncaught exceptions
+// Returning true will surpress the default browser handler,
+// returning false will let it run.
+window.onerror = function ( error, filePath, linerNr ) {
+	var ret = false;
+	if ( onErrorFnPrev ) {
+		ret = onErrorFnPrev( error, filePath, linerNr );
+	}
+
+	// Treat return value as window.onerror itself does,
+	// Only do our handling if not surpressed.
+	if ( ret !== true ) {
+		if ( QUnit.config.current ) {
+			if ( QUnit.config.current.ignoreGlobalErrors ) {
+				return true;
+			}
+			QUnit.pushFailure( error, filePath + ":" + linerNr );
+		} else {
+			QUnit.test( "global failure", extend( function() {
+				QUnit.pushFailure( error, filePath + ":" + linerNr );
+			}, { validTest: validTest } ) );
+		}
+		return false;
+	}
+
+	return ret;
+};
+
+function done() {
+	config.autorun = true;
+
+	// Log the last module results
+	if ( config.currentModule ) {
+		runLoggingCallbacks( "moduleDone", QUnit, {
+			name: config.currentModule,
+			failed: config.moduleStats.bad,
+			passed: config.moduleStats.all - config.moduleStats.bad,
+			total: config.moduleStats.all
+		});
+	}
+
+	var i, key,
+		banner = id( "qunit-banner" ),
+		tests = id( "qunit-tests" ),
+		runtime = +new Date() - config.started,
+		passed = config.stats.all - config.stats.bad,
+		html = [
+			"Tests completed in ",
+			runtime,
+			" milliseconds.<br/>",
+			"<span class='passed'>",
+			passed,
+			"</span> assertions of <span class='total'>",
+			config.stats.all,
+			"</span> passed, <span class='failed'>",
+			config.stats.bad,
+			"</span> failed."
+		].join( "" );
+
+	if ( banner ) {
+		banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" );
+	}
+
+	if ( tests ) {
+		id( "qunit-testresult" ).innerHTML = html;
+	}
+
+	if ( config.altertitle && typeof document !== "undefined" && document.title ) {
+		// show ✖ for good, ✔ for bad suite result in title
+		// use escape sequences in case file gets loaded with non-utf-8-charset
+		document.title = [
+			( config.stats.bad ? "\u2716" : "\u2714" ),
+			document.title.replace( /^[\u2714\u2716] /i, "" )
+		].join( " " );
+	}
+
+	// clear own sessionStorage items if all tests passed
+	if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {
+		// `key` & `i` initialized at top of scope
+		for ( i = 0; i < sessionStorage.length; i++ ) {
+			key = sessionStorage.key( i++ );
+			if ( key.indexOf( "qunit-test-" ) === 0 ) {
+				sessionStorage.removeItem( key );
+			}
+		}
+	}
+
+	// scroll back to top to show results
+	if ( window.scrollTo ) {
+		window.scrollTo(0, 0);
+	}
+
+	runLoggingCallbacks( "done", QUnit, {
+		failed: config.stats.bad,
+		passed: passed,
+		total: config.stats.all,
+		runtime: runtime
+	});
+}
+
+/** @return Boolean: true if this test should be ran */
+function validTest( test ) {
+	var include,
+		filter = config.filter && config.filter.toLowerCase(),
+		module = config.module && config.module.toLowerCase(),
+		fullName = (test.module + ": " + test.testName).toLowerCase();
+
+	// Internally-generated tests are always valid
+	if ( test.callback && test.callback.validTest === validTest ) {
+		delete test.callback.validTest;
+		return true;
+	}
+
+	if ( config.testNumber ) {
+		return test.testNumber === config.testNumber;
+	}
+
+	if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) {
+		return false;
+	}
+
+	if ( !filter ) {
+		return true;
+	}
+
+	include = filter.charAt( 0 ) !== "!";
+	if ( !include ) {
+		filter = filter.slice( 1 );
+	}
+
+	// If the filter matches, we need to honour include
+	if ( fullName.indexOf( filter ) !== -1 ) {
+		return include;
+	}
+
+	// Otherwise, do the opposite
+	return !include;
+}
+
+// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions)
+// Later Safari and IE10 are supposed to support error.stack as well
+// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
+function extractStacktrace( e, offset ) {
+	offset = offset === undefined ? 3 : offset;
+
+	var stack, include, i;
+
+	if ( e.stacktrace ) {
+		// Opera
+		return e.stacktrace.split( "\n" )[ offset + 3 ];
+	} else if ( e.stack ) {
+		// Firefox, Chrome
+		stack = e.stack.split( "\n" );
+		if (/^error$/i.test( stack[0] ) ) {
+			stack.shift();
+		}
+		if ( fileName ) {
+			include = [];
+			for ( i = offset; i < stack.length; i++ ) {
+				if ( stack[ i ].indexOf( fileName ) !== -1 ) {
+					break;
+				}
+				include.push( stack[ i ] );
+			}
+			if ( include.length ) {
+				return include.join( "\n" );
+			}
+		}
+		return stack[ offset ];
+	} else if ( e.sourceURL ) {
+		// Safari, PhantomJS
+		// hopefully one day Safari provides actual stacktraces
+		// exclude useless self-reference for generated Error objects
+		if ( /qunit.js$/.test( e.sourceURL ) ) {
+			return;
+		}
+		// for actual exceptions, this is useful
+		return e.sourceURL + ":" + e.line;
+	}
+}
+function sourceFromStacktrace( offset ) {
+	try {
+		throw new Error();
+	} catch ( e ) {
+		return extractStacktrace( e, offset );
+	}
+}
+
+/**
+ * Escape text for attribute or text content.
+ */
+function escapeText( s ) {
+	if ( !s ) {
+		return "";
+	}
+	s = s + "";
+	// Both single quotes and double quotes (for attributes)
+	return s.replace( /['"<>&]/g, function( s ) {
+		switch( s ) {
+			case '\'':
+				return '&#039;';
+			case '"':
+				return '&quot;';
+			case '<':
+				return '&lt;';
+			case '>':
+				return '&gt;';
+			case '&':
+				return '&amp;';
+		}
+	});
+}
+
+function synchronize( callback, last ) {
+	config.queue.push( callback );
+
+	if ( config.autorun && !config.blocking ) {
+		process( last );
+	}
+}
+
+function process( last ) {
+	function next() {
+		process( last );
+	}
+	var start = new Date().getTime();
+	config.depth = config.depth ? config.depth + 1 : 1;
+
+	while ( config.queue.length && !config.blocking ) {
+		if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
+			config.queue.shift()();
+		} else {
+			window.setTimeout( next, 13 );
+			break;
+		}
+	}
+	config.depth--;
+	if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
+		done();
+	}
+}
+
+function saveGlobal() {
+	config.pollution = [];
+
+	if ( config.noglobals ) {
+		for ( var key in window ) {
+			// in Opera sometimes DOM element ids show up here, ignore them
+			if ( !hasOwn.call( window, key ) || /^qunit-test-output/.test( key ) ) {
+				continue;
+			}
+			config.pollution.push( key );
+		}
+	}
+}
+
+function checkPollution() {
+	var newGlobals,
+		deletedGlobals,
+		old = config.pollution;
+
+	saveGlobal();
+
+	newGlobals = diff( config.pollution, old );
+	if ( newGlobals.length > 0 ) {
+		QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") );
+	}
+
+	deletedGlobals = diff( old, config.pollution );
+	if ( deletedGlobals.length > 0 ) {
+		QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") );
+	}
+}
+
+// returns a new Array with the elements that are in a but not in b
+function diff( a, b ) {
+	var i, j,
+		result = a.slice();
+
+	for ( i = 0; i < result.length; i++ ) {
+		for ( j = 0; j < b.length; j++ ) {
+			if ( result[i] === b[j] ) {
+				result.splice( i, 1 );
+				i--;
+				break;
+			}
+		}
+	}
+	return result;
+}
+
+function extend( a, b ) {
+	for ( var prop in b ) {
+		if ( b[ prop ] === undefined ) {
+			delete a[ prop ];
+
+		// Avoid "Member not found" error in IE8 caused by setting window.constructor
+		} else if ( prop !== "constructor" || a !== window ) {
+			a[ prop ] = b[ prop ];
+		}
+	}
+
+	return a;
+}
+
+/**
+ * @param {HTMLElement} elem
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvent( elem, type, fn ) {
+	// Standards-based browsers
+	if ( elem.addEventListener ) {
+		elem.addEventListener( type, fn, false );
+	// IE
+	} else {
+		elem.attachEvent( "on" + type, fn );
+	}
+}
+
+/**
+ * @param {Array|NodeList} elems
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvents( elems, type, fn ) {
+	var i = elems.length;
+	while ( i-- ) {
+		addEvent( elems[i], type, fn );
+	}
+}
+
+function hasClass( elem, name ) {
+	return (" " + elem.className + " ").indexOf(" " + name + " ") > -1;
+}
+
+function addClass( elem, name ) {
+	if ( !hasClass( elem, name ) ) {
+		elem.className += (elem.className ? " " : "") + name;
+	}
+}
+
+function removeClass( elem, name ) {
+	var set = " " + elem.className + " ";
+	// Class name may appear multiple times
+	while ( set.indexOf(" " + name + " ") > -1 ) {
+		set = set.replace(" " + name + " " , " ");
+	}
+	// If possible, trim it for prettiness, but not neccecarily
+	elem.className = window.jQuery ? jQuery.trim( set ) : ( set.trim ? set.trim() : set );
+}
+
+function id( name ) {
+	return !!( typeof document !== "undefined" && document && document.getElementById ) &&
+		document.getElementById( name );
+}
+
+function registerLoggingCallback( key ) {
+	return function( callback ) {
+		config[key].push( callback );
+	};
+}
+
+// Supports deprecated method of completely overwriting logging callbacks
+function runLoggingCallbacks( key, scope, args ) {
+	var i, callbacks;
+	if ( QUnit.hasOwnProperty( key ) ) {
+		QUnit[ key ].call(scope, args );
+	} else {
+		callbacks = config[ key ];
+		for ( i = 0; i < callbacks.length; i++ ) {
+			callbacks[ i ].call( scope, args );
+		}
+	}
+}
+
+// Test for equality any JavaScript type.
+// Author: Philippe Rathé <prathe@gmail.com>
+QUnit.equiv = (function() {
+
+	// Call the o related callback with the given arguments.
+	function bindCallbacks( o, callbacks, args ) {
+		var prop = QUnit.objectType( o );
+		if ( prop ) {
+			if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) {
+				return callbacks[ prop ].apply( callbacks, args );
+			} else {
+				return callbacks[ prop ]; // or undefined
+			}
+		}
+	}
+
+	// the real equiv function
+	var innerEquiv,
+		// stack to decide between skip/abort functions
+		callers = [],
+		// stack to avoiding loops from circular referencing
+		parents = [],
+
+		getProto = Object.getPrototypeOf || function ( obj ) {
+			return obj.__proto__;
+		},
+		callbacks = (function () {
+
+			// for string, boolean, number and null
+			function useStrictEquality( b, a ) {
+				/*jshint eqeqeq:false */
+				if ( b instanceof a.constructor || a instanceof b.constructor ) {
+					// to catch short annotaion VS 'new' annotation of a
+					// declaration
+					// e.g. var i = 1;
+					// var j = new Number(1);
+					return a == b;
+				} else {
+					return a === b;
+				}
+			}
+
+			return {
+				"string": useStrictEquality,
+				"boolean": useStrictEquality,
+				"number": useStrictEquality,
+				"null": useStrictEquality,
+				"undefined": useStrictEquality,
+
+				"nan": function( b ) {
+					return isNaN( b );
+				},
+
+				"date": function( b, a ) {
+					return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf();
+				},
+
+				"regexp": function( b, a ) {
+					return QUnit.objectType( b ) === "regexp" &&
+						// the regex itself
+						a.source === b.source &&
+						// and its modifers
+						a.global === b.global &&
+						// (gmi) ...
+						a.ignoreCase === b.ignoreCase &&
+						a.multiline === b.multiline &&
+						a.sticky === b.sticky;
+				},
+
+				// - skip when the property is a method of an instance (OOP)
+				// - abort otherwise,
+				// initial === would have catch identical references anyway
+				"function": function() {
+					var caller = callers[callers.length - 1];
+					return caller !== Object && typeof caller !== "undefined";
+				},
+
+				"array": function( b, a ) {
+					var i, j, len, loop;
+
+					// b could be an object literal here
+					if ( QUnit.objectType( b ) !== "array" ) {
+						return false;
+					}
+
+					len = a.length;
+					if ( len !== b.length ) {
+						// safe and faster
+						return false;
+					}
+
+					// track reference to avoid circular references
+					parents.push( a );
+					for ( i = 0; i < len; i++ ) {
+						loop = false;
+						for ( j = 0; j < parents.length; j++ ) {
+							if ( parents[j] === a[i] ) {
+								loop = true;// dont rewalk array
+							}
+						}
+						if ( !loop && !innerEquiv(a[i], b[i]) ) {
+							parents.pop();
+							return false;
+						}
+					}
+					parents.pop();
+					return true;
+				},
+
+				"object": function( b, a ) {
+					var i, j, loop,
+						// Default to true
+						eq = true,
+						aProperties = [],
+						bProperties = [];
+
+					// comparing constructors is more strict than using
+					// instanceof
+					if ( a.constructor !== b.constructor ) {
+						// Allow objects with no prototype to be equivalent to
+						// objects with Object as their constructor.
+						if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) ||
+							( getProto(b) === null && getProto(a) === Object.prototype ) ) ) {
+								return false;
+						}
+					}
+
+					// stack constructor before traversing properties
+					callers.push( a.constructor );
+					// track reference to avoid circular references
+					parents.push( a );
+
+					for ( i in a ) { // be strict: don't ensures hasOwnProperty
+									// and go deep
+						loop = false;
+						for ( j = 0; j < parents.length; j++ ) {
+							if ( parents[j] === a[i] ) {
+								// don't go down the same path twice
+								loop = true;
+							}
+						}
+						aProperties.push(i); // collect a's properties
+
+						if (!loop && !innerEquiv( a[i], b[i] ) ) {
+							eq = false;
+							break;
+						}
+					}
+
+					callers.pop(); // unstack, we are done
+					parents.pop();
+
+					for ( i in b ) {
+						bProperties.push( i ); // collect b's properties
+					}
+
+					// Ensures identical properties name
+					return eq && innerEquiv( aProperties.sort(), bProperties.sort() );
+				}
+			};
+		}());
+
+	innerEquiv = function() { // can take multiple arguments
+		var args = [].slice.apply( arguments );
+		if ( args.length < 2 ) {
+			return true; // end transition
+		}
+
+		return (function( a, b ) {
+			if ( a === b ) {
+				return true; // catch the most you can
+			} else if ( a === null || b === null || typeof a === "undefined" ||
+					typeof b === "undefined" ||
+					QUnit.objectType(a) !== QUnit.objectType(b) ) {
+				return false; // don't lose time with error prone cases
+			} else {
+				return bindCallbacks(a, callbacks, [ b, a ]);
+			}
+
+			// apply transition with (1..n) arguments
+		}( args[0], args[1] ) && arguments.callee.apply( this, args.splice(1, args.length - 1 )) );
+	};
+
+	return innerEquiv;
+}());
+
+/**
+ * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com |
+ * http://flesler.blogspot.com Licensed under BSD
+ * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008
+ *
+ * @projectDescription Advanced and extensible data dumping for Javascript.
+ * @version 1.0.0
+ * @author Ariel Flesler
+ * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}
+ */
+QUnit.jsDump = (function() {
+	function quote( str ) {
+		return '"' + str.toString().replace( /"/g, '\\"' ) + '"';
+	}
+	function literal( o ) {
+		return o + "";
+	}
+	function join( pre, arr, post ) {
+		var s = jsDump.separator(),
+			base = jsDump.indent(),
+			inner = jsDump.indent(1);
+		if ( arr.join ) {
+			arr = arr.join( "," + s + inner );
+		}
+		if ( !arr ) {
+			return pre + post;
+		}
+		return [ pre, inner + arr, base + post ].join(s);
+	}
+	function array( arr, stack ) {
+		var i = arr.length, ret = new Array(i);
+		this.up();
+		while ( i-- ) {
+			ret[i] = this.parse( arr[i] , undefined , stack);
+		}
+		this.down();
+		return join( "[", ret, "]" );
+	}
+
+	var reName = /^function (\w+)/,
+		jsDump = {
+			// type is used mostly internally, you can fix a (custom)type in advance
+			parse: function( obj, type, stack ) {
+				stack = stack || [ ];
+				var inStack, res,
+					parser = this.parsers[ type || this.typeOf(obj) ];
+
+				type = typeof parser;
+				inStack = inArray( obj, stack );
+
+				if ( inStack !== -1 ) {
+					return "recursion(" + (inStack - stack.length) + ")";
+				}
+				if ( type === "function" )  {
+					stack.push( obj );
+					res = parser.call( this, obj, stack );
+					stack.pop();
+					return res;
+				}
+				return ( type === "string" ) ? parser : this.parsers.error;
+			},
+			typeOf: function( obj ) {
+				var type;
+				if ( obj === null ) {
+					type = "null";
+				} else if ( typeof obj === "undefined" ) {
+					type = "undefined";
+				} else if ( QUnit.is( "regexp", obj) ) {
+					type = "regexp";
+				} else if ( QUnit.is( "date", obj) ) {
+					type = "date";
+				} else if ( QUnit.is( "function", obj) ) {
+					type = "function";
+				} else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) {
+					type = "window";
+				} else if ( obj.nodeType === 9 ) {
+					type = "document";
+				} else if ( obj.nodeType ) {
+					type = "node";
+				} else if (
+					// native arrays
+					toString.call( obj ) === "[object Array]" ||
+					// NodeList objects
+					( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) )
+				) {
+					type = "array";
+				} else if ( obj.constructor === Error.prototype.constructor ) {
+					type = "error";
+				} else {
+					type = typeof obj;
+				}
+				return type;
+			},
+			separator: function() {
+				return this.multiline ?	this.HTML ? "<br />" : "\n" : this.HTML ? "&nbsp;" : " ";
+			},
+			// extra can be a number, shortcut for increasing-calling-decreasing
+			indent: function( extra ) {
+				if ( !this.multiline ) {
+					return "";
+				}
+				var chr = this.indentChar;
+				if ( this.HTML ) {
+					chr = chr.replace( /\t/g, "   " ).replace( / /g, "&nbsp;" );
+				}
+				return new Array( this._depth_ + (extra||0) ).join(chr);
+			},
+			up: function( a ) {
+				this._depth_ += a || 1;
+			},
+			down: function( a ) {
+				this._depth_ -= a || 1;
+			},
+			setParser: function( name, parser ) {
+				this.parsers[name] = parser;
+			},
+			// The next 3 are exposed so you can use them
+			quote: quote,
+			literal: literal,
+			join: join,
+			//
+			_depth_: 1,
+			// This is the list of parsers, to modify them, use jsDump.setParser
+			parsers: {
+				window: "[Window]",
+				document: "[Document]",
+				error: function(error) {
+					return "Error(\"" + error.message + "\")";
+				},
+				unknown: "[Unknown]",
+				"null": "null",
+				"undefined": "undefined",
+				"function": function( fn ) {
+					var ret = "function",
+						// functions never have name in IE
+						name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];
+
+					if ( name ) {
+						ret += " " + name;
+					}
+					ret += "( ";
+
+					ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" );
+					return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" );
+				},
+				array: array,
+				nodelist: array,
+				"arguments": array,
+				object: function( map, stack ) {
+					var ret = [ ], keys, key, val, i;
+					QUnit.jsDump.up();
+					keys = [];
+					for ( key in map ) {
+						keys.push( key );
+					}
+					keys.sort();
+					for ( i = 0; i < keys.length; i++ ) {
+						key = keys[ i ];
+						val = map[ key ];
+						ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) );
+					}
+					QUnit.jsDump.down();
+					return join( "{", ret, "}" );
+				},
+				node: function( node ) {
+					var len, i, val,
+						open = QUnit.jsDump.HTML ? "&lt;" : "<",
+						close = QUnit.jsDump.HTML ? "&gt;" : ">",
+						tag = node.nodeName.toLowerCase(),
+						ret = open + tag,
+						attrs = node.attributes;
+
+					if ( attrs ) {
+						for ( i = 0, len = attrs.length; i < len; i++ ) {
+							val = attrs[i].nodeValue;
+							// IE6 includes all attributes in .attributes, even ones not explicitly set.
+							// Those have values like undefined, null, 0, false, "" or "inherit".
+							if ( val && val !== "inherit" ) {
+								ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" );
+							}
+						}
+					}
+					ret += close;
+
+					// Show content of TextNode or CDATASection
+					if ( node.nodeType === 3 || node.nodeType === 4 ) {
+						ret += node.nodeValue;
+					}
+
+					return ret + open + "/" + tag + close;
+				},
+				// function calls it internally, it's the arguments part of the function
+				functionArgs: function( fn ) {
+					var args,
+						l = fn.length;
+
+					if ( !l ) {
+						return "";
+					}
+
+					args = new Array(l);
+					while ( l-- ) {
+						// 97 is 'a'
+						args[l] = String.fromCharCode(97+l);
+					}
+					return " " + args.join( ", " ) + " ";
+				},
+				// object calls it internally, the key part of an item in a map
+				key: quote,
+				// function calls it internally, it's the content of the function
+				functionCode: "[code]",
+				// node calls it internally, it's an html attribute value
+				attribute: quote,
+				string: quote,
+				date: quote,
+				regexp: literal,
+				number: literal,
+				"boolean": literal
+			},
+			// if true, entities are escaped ( <, >, \t, space and \n )
+			HTML: false,
+			// indentation unit
+			indentChar: "  ",
+			// if true, items in a collection, are separated by a \n, else just a space.
+			multiline: true
+		};
+
+	return jsDump;
+}());
+
+// from jquery.js
+function inArray( elem, array ) {
+	if ( array.indexOf ) {
+		return array.indexOf( elem );
+	}
+
+	for ( var i = 0, length = array.length; i < length; i++ ) {
+		if ( array[ i ] === elem ) {
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+/*
+ * Javascript Diff Algorithm
+ *  By John Resig (http://ejohn.org/)
+ *  Modified by Chu Alan "sprite"
+ *
+ * Released under the MIT license.
+ *
+ * More Info:
+ *  http://ejohn.org/projects/javascript-diff-algorithm/
+ *
+ * Usage: QUnit.diff(expected, actual)
+ *
+ * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the  quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
+ */
+QUnit.diff = (function() {
+	/*jshint eqeqeq:false, eqnull:true */
+	function diff( o, n ) {
+		var i,
+			ns = {},
+			os = {};
+
+		for ( i = 0; i < n.length; i++ ) {
+			if ( !hasOwn.call( ns, n[i] ) ) {
+				ns[ n[i] ] = {
+					rows: [],
+					o: null
+				};
+			}
+			ns[ n[i] ].rows.push( i );
+		}
+
+		for ( i = 0; i < o.length; i++ ) {
+			if ( !hasOwn.call( os, o[i] ) ) {
+				os[ o[i] ] = {
+					rows: [],
+					n: null
+				};
+			}
+			os[ o[i] ].rows.push( i );
+		}
+
+		for ( i in ns ) {
+			if ( !hasOwn.call( ns, i ) ) {
+				continue;
+			}
+			if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) {
+				n[ ns[i].rows[0] ] = {
+					text: n[ ns[i].rows[0] ],
+					row: os[i].rows[0]
+				};
+				o[ os[i].rows[0] ] = {
+					text: o[ os[i].rows[0] ],
+					row: ns[i].rows[0]
+				};
+			}
+		}
+
+		for ( i = 0; i < n.length - 1; i++ ) {
+			if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null &&
+						n[ i + 1 ] == o[ n[i].row + 1 ] ) {
+
+				n[ i + 1 ] = {
+					text: n[ i + 1 ],
+					row: n[i].row + 1
+				};
+				o[ n[i].row + 1 ] = {
+					text: o[ n[i].row + 1 ],
+					row: i + 1
+				};
+			}
+		}
+
+		for ( i = n.length - 1; i > 0; i-- ) {
+			if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null &&
+						n[ i - 1 ] == o[ n[i].row - 1 ]) {
+
+				n[ i - 1 ] = {
+					text: n[ i - 1 ],
+					row: n[i].row - 1
+				};
+				o[ n[i].row - 1 ] = {
+					text: o[ n[i].row - 1 ],
+					row: i - 1
+				};
+			}
+		}
+
+		return {
+			o: o,
+			n: n
+		};
+	}
+
+	return function( o, n ) {
+		o = o.replace( /\s+$/, "" );
+		n = n.replace( /\s+$/, "" );
+
+		var i, pre,
+			str = "",
+			out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ),
+			oSpace = o.match(/\s+/g),
+			nSpace = n.match(/\s+/g);
+
+		if ( oSpace == null ) {
+			oSpace = [ " " ];
+		}
+		else {
+			oSpace.push( " " );
+		}
+
+		if ( nSpace == null ) {
+			nSpace = [ " " ];
+		}
+		else {
+			nSpace.push( " " );
+		}
+
+		if ( out.n.length === 0 ) {
+			for ( i = 0; i < out.o.length; i++ ) {
+				str += "<del>" + out.o[i] + oSpace[i] + "</del>";
+			}
+		}
+		else {
+			if ( out.n[0].text == null ) {
+				for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) {
+					str += "<del>" + out.o[n] + oSpace[n] + "</del>";
+				}
+			}
+
+			for ( i = 0; i < out.n.length; i++ ) {
+				if (out.n[i].text == null) {
+					str += "<ins>" + out.n[i] + nSpace[i] + "</ins>";
+				}
+				else {
+					// `pre` initialized at top of scope
+					pre = "";
+
+					for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) {
+						pre += "<del>" + out.o[n] + oSpace[n] + "</del>";
+					}
+					str += " " + out.n[i].text + nSpace[i] + pre;
+				}
+			}
+		}
+
+		return str;
+	};
+}());
+
+// for CommonJS enviroments, export everything
+if ( typeof exports !== "undefined" ) {
+	extend( exports, QUnit );
+}
+
+// get at whatever the global object is, like window in browsers
+}( (function() {return this;}.call()) ));
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/sinon-1.10.3.js b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/sinon-1.10.3.js
new file mode 100644
index 0000000..703414d
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/sinon-1.10.3.js
@@ -0,0 +1,5073 @@
+/**
+ * Sinon.JS 1.10.3, 2014/07/11
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
+ *
+ * (The BSD License)
+ * 
+ * Copyright (c) 2010-2014, Christian Johansen, christian@cjohansen.no
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright notice,
+ *       this list of conditions and the following disclaimer in the documentation
+ *       and/or other materials provided with the distribution.
+ *     * Neither the name of Christian Johansen nor the names of his contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+this.sinon = (function () {
+var samsam, formatio;
+function define(mod, deps, fn) { if (mod == "samsam") { samsam = deps(); } else if (typeof fn === "function") { formatio = fn(samsam); } }
+define.amd = {};
+((typeof define === "function" && define.amd && function (m) { define("samsam", m); }) ||
+ (typeof module === "object" &&
+      function (m) { module.exports = m(); }) || // Node
+ function (m) { this.samsam = m(); } // Browser globals
+)(function () {
+    var o = Object.prototype;
+    var div = typeof document !== "undefined" && document.createElement("div");
+
+    function isNaN(value) {
+        // Unlike global isNaN, this avoids type coercion
+        // typeof check avoids IE host object issues, hat tip to
+        // lodash
+        var val = value; // JsLint thinks value !== value is "weird"
+        return typeof value === "number" && value !== val;
+    }
+
+    function getClass(value) {
+        // Returns the internal [[Class]] by calling Object.prototype.toString
+        // with the provided value as this. Return value is a string, naming the
+        // internal class, e.g. "Array"
+        return o.toString.call(value).split(/[ \]]/)[1];
+    }
+
+    /**
+     * @name samsam.isArguments
+     * @param Object object
+     *
+     * Returns ``true`` if ``object`` is an ``arguments`` object,
+     * ``false`` otherwise.
+     */
+    function isArguments(object) {
+        if (typeof object !== "object" || typeof object.length !== "number" ||
+                getClass(object) === "Array") {
+            return false;
+        }
+        if (typeof object.callee == "function") { return true; }
+        try {
+            object[object.length] = 6;
+            delete object[object.length];
+        } catch (e) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * @name samsam.isElement
+     * @param Object object
+     *
+     * Returns ``true`` if ``object`` is a DOM element node. Unlike
+     * Underscore.js/lodash, this function will return ``false`` if ``object``
+     * is an *element-like* object, i.e. a regular object with a ``nodeType``
+     * property that holds the value ``1``.
+     */
+    function isElement(object) {
+        if (!object || object.nodeType !== 1 || !div) { return false; }
+        try {
+            object.appendChild(div);
+            object.removeChild(div);
+        } catch (e) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * @name samsam.keys
+     * @param Object object
+     *
+     * Return an array of own property names.
+     */
+    function keys(object) {
+        var ks = [], prop;
+        for (prop in object) {
+            if (o.hasOwnProperty.call(object, prop)) { ks.push(prop); }
+        }
+        return ks;
+    }
+
+    /**
+     * @name samsam.isDate
+     * @param Object value
+     *
+     * Returns true if the object is a ``Date``, or *date-like*. Duck typing
+     * of date objects work by checking that the object has a ``getTime``
+     * function whose return value equals the return value from the object's
+     * ``valueOf``.
+     */
+    function isDate(value) {
+        return typeof value.getTime == "function" &&
+            value.getTime() == value.valueOf();
+    }
+
+    /**
+     * @name samsam.isNegZero
+     * @param Object value
+     *
+     * Returns ``true`` if ``value`` is ``-0``.
+     */
+    function isNegZero(value) {
+        return value === 0 && 1 / value === -Infinity;
+    }
+
+    /**
+     * @name samsam.equal
+     * @param Object obj1
+     * @param Object obj2
+     *
+     * Returns ``true`` if two objects are strictly equal. Compared to
+     * ``===`` there are two exceptions:
+     *
+     *   - NaN is considered equal to NaN
+     *   - -0 and +0 are not considered equal
+     */
+    function identical(obj1, obj2) {
+        if (obj1 === obj2 || (isNaN(obj1) && isNaN(obj2))) {
+            return obj1 !== 0 || isNegZero(obj1) === isNegZero(obj2);
+        }
+    }
+
+
+    /**
+     * @name samsam.deepEqual
+     * @param Object obj1
+     * @param Object obj2
+     *
+     * Deep equal comparison. Two values are "deep equal" if:
+     *
+     *   - They are equal, according to samsam.identical
+     *   - They are both date objects representing the same time
+     *   - They are both arrays containing elements that are all deepEqual
+     *   - They are objects with the same set of properties, and each property
+     *     in ``obj1`` is deepEqual to the corresponding property in ``obj2``
+     *
+     * Supports cyclic objects.
+     */
+    function deepEqualCyclic(obj1, obj2) {
+
+        // used for cyclic comparison
+        // contain already visited objects
+        var objects1 = [],
+            objects2 = [],
+        // contain pathes (position in the object structure)
+        // of the already visited objects
+        // indexes same as in objects arrays
+            paths1 = [],
+            paths2 = [],
+        // contains combinations of already compared objects
+        // in the manner: { "$1['ref']$2['ref']": true }
+            compared = {};
+
+        /**
+         * used to check, if the value of a property is an object
+         * (cyclic logic is only needed for objects)
+         * only needed for cyclic logic
+         */
+        function isObject(value) {
+
+            if (typeof value === 'object' && value !== null &&
+                    !(value instanceof Boolean) &&
+                    !(value instanceof Date)    &&
+                    !(value instanceof Number)  &&
+                    !(value instanceof RegExp)  &&
+                    !(value instanceof String)) {
+
+                return true;
+            }
+
+            return false;
+        }
+
+        /**
+         * returns the index of the given object in the
+         * given objects array, -1 if not contained
+         * only needed for cyclic logic
+         */
+        function getIndex(objects, obj) {
+
+            var i;
+            for (i = 0; i < objects.length; i++) {
+                if (objects[i] === obj) {
+                    return i;
+                }
+            }
+
+            return -1;
+        }
+
+        // does the recursion for the deep equal check
+        return (function deepEqual(obj1, obj2, path1, path2) {
+            var type1 = typeof obj1;
+            var type2 = typeof obj2;
+
+            // == null also matches undefined
+            if (obj1 === obj2 ||
+                    isNaN(obj1) || isNaN(obj2) ||
+                    obj1 == null || obj2 == null ||
+                    type1 !== "object" || type2 !== "object") {
+
+                return identical(obj1, obj2);
+            }
+
+            // Elements are only equal if identical(expected, actual)
+            if (isElement(obj1) || isElement(obj2)) { return false; }
+
+            var isDate1 = isDate(obj1), isDate2 = isDate(obj2);
+            if (isDate1 || isDate2) {
+                if (!isDate1 || !isDate2 || obj1.getTime() !== obj2.getTime()) {
+                    return false;
+                }
+            }
+
+            if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
+                if (obj1.toString() !== obj2.toString()) { return false; }
+            }
+
+            var class1 = getClass(obj1);
+            var class2 = getClass(obj2);
+            var keys1 = keys(obj1);
+            var keys2 = keys(obj2);
+
+            if (isArguments(obj1) || isArguments(obj2)) {
+                if (obj1.length !== obj2.length) { return false; }
+            } else {
+                if (type1 !== type2 || class1 !== class2 ||
+                        keys1.length !== keys2.length) {
+                    return false;
+                }
+            }
+
+            var key, i, l,
+                // following vars are used for the cyclic logic
+                value1, value2,
+                isObject1, isObject2,
+                index1, index2,
+                newPath1, newPath2;
+
+            for (i = 0, l = keys1.length; i < l; i++) {
+                key = keys1[i];
+                if (!o.hasOwnProperty.call(obj2, key)) {
+                    return false;
+                }
+
+                // Start of the cyclic logic
+
+                value1 = obj1[key];
+                value2 = obj2[key];
+
+                isObject1 = isObject(value1);
+                isObject2 = isObject(value2);
+
+                // determine, if the objects were already visited
+                // (it's faster to check for isObject first, than to
+                // get -1 from getIndex for non objects)
+                index1 = isObject1 ? getIndex(objects1, value1) : -1;
+                index2 = isObject2 ? getIndex(objects2, value2) : -1;
+
+                // determine the new pathes of the objects
+                // - for non cyclic objects the current path will be extended
+                //   by current property name
+                // - for cyclic objects the stored path is taken
+                newPath1 = index1 !== -1
+                    ? paths1[index1]
+                    : path1 + '[' + JSON.stringify(key) + ']';
+                newPath2 = index2 !== -1
+                    ? paths2[index2]
+                    : path2 + '[' + JSON.stringify(key) + ']';
+
+                // stop recursion if current objects are already compared
+                if (compared[newPath1 + newPath2]) {
+                    return true;
+                }
+
+                // remember the current objects and their pathes
+                if (index1 === -1 && isObject1) {
+                    objects1.push(value1);
+                    paths1.push(newPath1);
+                }
+                if (index2 === -1 && isObject2) {
+                    objects2.push(value2);
+                    paths2.push(newPath2);
+                }
+
+                // remember that the current objects are already compared
+                if (isObject1 && isObject2) {
+                    compared[newPath1 + newPath2] = true;
+                }
+
+                // End of cyclic logic
+
+                // neither value1 nor value2 is a cycle
+                // continue with next level
+                if (!deepEqual(value1, value2, newPath1, newPath2)) {
+                    return false;
+                }
+            }
+
+            return true;
+
+        }(obj1, obj2, '$1', '$2'));
+    }
+
+    var match;
+
+    function arrayContains(array, subset) {
+        if (subset.length === 0) { return true; }
+        var i, l, j, k;
+        for (i = 0, l = array.length; i < l; ++i) {
+            if (match(array[i], subset[0])) {
+                for (j = 0, k = subset.length; j < k; ++j) {
+                    if (!match(array[i + j], subset[j])) { return false; }
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @name samsam.match
+     * @param Object object
+     * @param Object matcher
+     *
+     * Compare arbitrary value ``object`` with matcher.
+     */
+    match = function match(object, matcher) {
+        if (matcher && typeof matcher.test === "function") {
+            return matcher.test(object);
+        }
+
+        if (typeof matcher === "function") {
+            return matcher(object) === true;
+        }
+
+        if (typeof matcher === "string") {
+            matcher = matcher.toLowerCase();
+            var notNull = typeof object === "string" || !!object;
+            return notNull &&
+                (String(object)).toLowerCase().indexOf(matcher) >= 0;
+        }
+
+        if (typeof matcher === "number") {
+            return matcher === object;
+        }
+
+        if (typeof matcher === "boolean") {
+            return matcher === object;
+        }
+
+        if (getClass(object) === "Array" && getClass(matcher) === "Array") {
+            return arrayContains(object, matcher);
+        }
+
+        if (matcher && typeof matcher === "object") {
+            var prop;
+            for (prop in matcher) {
+                if (!match(object[prop], matcher[prop])) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        throw new Error("Matcher was not a string, a number, a " +
+                        "function, a boolean or an object");
+    };
+
+    return {
+        isArguments: isArguments,
+        isElement: isElement,
+        isDate: isDate,
+        isNegZero: isNegZero,
+        identical: identical,
+        deepEqual: deepEqualCyclic,
+        match: match,
+        keys: keys
+    };
+});
+((typeof define === "function" && define.amd && function (m) {
+    define("formatio", ["samsam"], m);
+}) || (typeof module === "object" && function (m) {
+    module.exports = m(require("samsam"));
+}) || function (m) { this.formatio = m(this.samsam); }
+)(function (samsam) {
+    
+    var formatio = {
+        excludeConstructors: ["Object", /^.$/],
+        quoteStrings: true
+    };
+
+    var hasOwn = Object.prototype.hasOwnProperty;
+
+    var specialObjects = [];
+    if (typeof global !== "undefined") {
+        specialObjects.push({ object: global, value: "[object global]" });
+    }
+    if (typeof document !== "undefined") {
+        specialObjects.push({
+            object: document,
+            value: "[object HTMLDocument]"
+        });
+    }
+    if (typeof window !== "undefined") {
+        specialObjects.push({ object: window, value: "[object Window]" });
+    }
+
+    function functionName(func) {
+        if (!func) { return ""; }
+        if (func.displayName) { return func.displayName; }
+        if (func.name) { return func.name; }
+        var matches = func.toString().match(/function\s+([^\(]+)/m);
+        return (matches && matches[1]) || "";
+    }
+
+    function constructorName(f, object) {
+        var name = functionName(object && object.constructor);
+        var excludes = f.excludeConstructors ||
+                formatio.excludeConstructors || [];
+
+        var i, l;
+        for (i = 0, l = excludes.length; i < l; ++i) {
+            if (typeof excludes[i] === "string" && excludes[i] === name) {
+                return "";
+            } else if (excludes[i].test && excludes[i].test(name)) {
+                return "";
+            }
+        }
+
+        return name;
+    }
+
+    function isCircular(object, objects) {
+        if (typeof object !== "object") { return false; }
+        var i, l;
+        for (i = 0, l = objects.length; i < l; ++i) {
+            if (objects[i] === object) { return true; }
+        }
+        return false;
+    }
+
+    function ascii(f, object, processed, indent) {
+        if (typeof object === "string") {
+            var qs = f.quoteStrings;
+            var quote = typeof qs !== "boolean" || qs;
+            return processed || quote ? '"' + object + '"' : object;
+        }
+
+        if (typeof object === "function" && !(object instanceof RegExp)) {
+            return ascii.func(object);
+        }
+
+        processed = processed || [];
+
+        if (isCircular(object, processed)) { return "[Circular]"; }
+
+        if (Object.prototype.toString.call(object) === "[object Array]") {
+            return ascii.array.call(f, object, processed);
+        }
+
+        if (!object) { return String((1/object) === -Infinity ? "-0" : object); }
+        if (samsam.isElement(object)) { return ascii.element(object); }
+
+        if (typeof object.toString === "function" &&
+                object.toString !== Object.prototype.toString) {
+            return object.toString();
+        }
+
+        var i, l;
+        for (i = 0, l = specialObjects.length; i < l; i++) {
+            if (object === specialObjects[i].object) {
+                return specialObjects[i].value;
+            }
+        }
+
+        return ascii.object.call(f, object, processed, indent);
+    }
+
+    ascii.func = function (func) {
+        return "function " + functionName(func) + "() {}";
+    };
+
+    ascii.array = function (array, processed) {
+        processed = processed || [];
+        processed.push(array);
+        var i, l, pieces = [];
+        for (i = 0, l = array.length; i < l; ++i) {
+            pieces.push(ascii(this, array[i], processed));
+        }
+        return "[" + pieces.join(", ") + "]";
+    };
+
+    ascii.object = function (object, processed, indent) {
+        processed = processed || [];
+        processed.push(object);
+        indent = indent || 0;
+        var pieces = [], properties = samsam.keys(object).sort();
+        var length = 3;
+        var prop, str, obj, i, l;
+
+        for (i = 0, l = properties.length; i < l; ++i) {
+            prop = properties[i];
+            obj = object[prop];
+
+            if (isCircular(obj, processed)) {
+                str = "[Circular]";
+            } else {
+                str = ascii(this, obj, processed, indent + 2);
+            }
+
+            str = (/\s/.test(prop) ? '"' + prop + '"' : prop) + ": " + str;
+            length += str.length;
+            pieces.push(str);
+        }
+
+        var cons = constructorName(this, object);
+        var prefix = cons ? "[" + cons + "] " : "";
+        var is = "";
+        for (i = 0, l = indent; i < l; ++i) { is += " "; }
+
+        if (length + indent > 80) {
+            return prefix + "{\n  " + is + pieces.join(",\n  " + is) + "\n" +
+                is + "}";
+        }
+        return prefix + "{ " + pieces.join(", ") + " }";
+    };
+
+    ascii.element = function (element) {
+        var tagName = element.tagName.toLowerCase();
+        var attrs = element.attributes, attr, pairs = [], attrName, i, l, val;
+
+        for (i = 0, l = attrs.length; i < l; ++i) {
+            attr = attrs.item(i);
+            attrName = attr.nodeName.toLowerCase().replace("html:", "");
+            val = attr.nodeValue;
+            if (attrName !== "contenteditable" || val !== "inherit") {
+                if (!!val) { pairs.push(attrName + "=\"" + val + "\""); }
+            }
+        }
+
+        var formatted = "<" + tagName + (pairs.length > 0 ? " " : "");
+        var content = element.innerHTML;
+
+        if (content.length > 20) {
+            content = content.substr(0, 20) + "[...]";
+        }
+
+        var res = formatted + pairs.join(" ") + ">" + content +
+                "</" + tagName + ">";
+
+        return res.replace(/ contentEditable="inherit"/, "");
+    };
+
+    function Formatio(options) {
+        for (var opt in options) {
+            this[opt] = options[opt];
+        }
+    }
+
+    Formatio.prototype = {
+        functionName: functionName,
+
+        configure: function (options) {
+            return new Formatio(options);
+        },
+
+        constructorName: function (object) {
+            return constructorName(this, object);
+        },
+
+        ascii: function (object, processed, indent) {
+            return ascii(this, object, processed, indent);
+        }
+    };
+
+    return Formatio.prototype;
+});
+/*jslint eqeqeq: false, onevar: false, forin: true, nomen: false, regexp: false, plusplus: false*/
+/*global module, require, __dirname, document*/
+/**
+ * Sinon core utilities. For internal use only.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+var sinon = (function (formatio) {
+    var div = typeof document != "undefined" && document.createElement("div");
+    var hasOwn = Object.prototype.hasOwnProperty;
+
+    function isDOMNode(obj) {
+        var success = false;
+
+        try {
+            obj.appendChild(div);
+            success = div.parentNode == obj;
+        } catch (e) {
+            return false;
+        } finally {
+            try {
+                obj.removeChild(div);
+            } catch (e) {
+                // Remove failed, not much we can do about that
+            }
+        }
+
+        return success;
+    }
+
+    function isElement(obj) {
+        return div && obj && obj.nodeType === 1 && isDOMNode(obj);
+    }
+
+    function isFunction(obj) {
+        return typeof obj === "function" || !!(obj && obj.constructor && obj.call && obj.apply);
+    }
+
+    function isReallyNaN(val) {
+        return typeof val === 'number' && isNaN(val);
+    }
+
+    function mirrorProperties(target, source) {
+        for (var prop in source) {
+            if (!hasOwn.call(target, prop)) {
+                target[prop] = source[prop];
+            }
+        }
+    }
+
+    function isRestorable (obj) {
+        return typeof obj === "function" && typeof obj.restore === "function" && obj.restore.sinon;
+    }
+
+    var sinon = {
+        wrapMethod: function wrapMethod(object, property, method) {
+            if (!object) {
+                throw new TypeError("Should wrap property of object");
+            }
+
+            if (typeof method != "function") {
+                throw new TypeError("Method wrapper should be function");
+            }
+
+            var wrappedMethod = object[property],
+                error;
+
+            if (!isFunction(wrappedMethod)) {
+                error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
+                                    property + " as function");
+            } else if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
+                error = new TypeError("Attempted to wrap " + property + " which is already wrapped");
+            } else if (wrappedMethod.calledBefore) {
+                var verb = !!wrappedMethod.returns ? "stubbed" : "spied on";
+                error = new TypeError("Attempted to wrap " + property + " which is already " + verb);
+            }
+
+            if (error) {
+                if (wrappedMethod && wrappedMethod._stack) {
+                    error.stack += '\n--------------\n' + wrappedMethod._stack;
+                }
+                throw error;
+            }
+
+            // IE 8 does not support hasOwnProperty on the window object and Firefox has a problem
+            // when using hasOwn.call on objects from other frames.
+            var owned = object.hasOwnProperty ? object.hasOwnProperty(property) : hasOwn.call(object, property);
+            object[property] = method;
+            method.displayName = property;
+            // Set up a stack trace which can be used later to find what line of
+            // code the original method was created on.
+            method._stack = (new Error('Stack Trace for original')).stack;
+
+            method.restore = function () {
+                // For prototype properties try to reset by delete first.
+                // If this fails (ex: localStorage on mobile safari) then force a reset
+                // via direct assignment.
+                if (!owned) {
+                    delete object[property];
+                }
+                if (object[property] === method) {
+                    object[property] = wrappedMethod;
+                }
+            };
+
+            method.restore.sinon = true;
+            mirrorProperties(method, wrappedMethod);
+
+            return method;
+        },
+
+        extend: function extend(target) {
+            for (var i = 1, l = arguments.length; i < l; i += 1) {
+                for (var prop in arguments[i]) {
+                    if (arguments[i].hasOwnProperty(prop)) {
+                        target[prop] = arguments[i][prop];
+                    }
+
+                    // DONT ENUM bug, only care about toString
+                    if (arguments[i].hasOwnProperty("toString") &&
+                        arguments[i].toString != target.toString) {
+                        target.toString = arguments[i].toString;
+                    }
+                }
+            }
+
+            return target;
+        },
+
+        create: function create(proto) {
+            var F = function () {};
+            F.prototype = proto;
+            return new F();
+        },
+
+        deepEqual: function deepEqual(a, b) {
+            if (sinon.match && sinon.match.isMatcher(a)) {
+                return a.test(b);
+            }
+
+            if (typeof a != 'object' || typeof b != 'object') {
+                if (isReallyNaN(a) && isReallyNaN(b)) {
+                    return true;
+                } else {
+                    return a === b;
+                }
+            }
+
+            if (isElement(a) || isElement(b)) {
+                return a === b;
+            }
+
+            if (a === b) {
+                return true;
+            }
+
+            if ((a === null && b !== null) || (a !== null && b === null)) {
+                return false;
+            }
+
+            if (a instanceof RegExp && b instanceof RegExp) {
+              return (a.source === b.source) && (a.global === b.global) &&
+                (a.ignoreCase === b.ignoreCase) && (a.multiline === b.multiline);
+            }
+
+            var aString = Object.prototype.toString.call(a);
+            if (aString != Object.prototype.toString.call(b)) {
+                return false;
+            }
+
+            if (aString == "[object Date]") {
+                return a.valueOf() === b.valueOf();
+            }
+
+            var prop, aLength = 0, bLength = 0;
+
+            if (aString == "[object Array]" && a.length !== b.length) {
+                return false;
+            }
+
+            for (prop in a) {
+                aLength += 1;
+
+                if (!(prop in b)) {
+                    return false;
+                }
+
+                if (!deepEqual(a[prop], b[prop])) {
+                    return false;
+                }
+            }
+
+            for (prop in b) {
+                bLength += 1;
+            }
+
+            return aLength == bLength;
+        },
+
+        functionName: function functionName(func) {
+            var name = func.displayName || func.name;
+
+            // Use function decomposition as a last resort to get function
+            // name. Does not rely on function decomposition to work - if it
+            // doesn't debugging will be slightly less informative
+            // (i.e. toString will say 'spy' rather than 'myFunc').
+            if (!name) {
+                var matches = func.toString().match(/function ([^\s\(]+)/);
+                name = matches && matches[1];
+            }
+
+            return name;
+        },
+
+        functionToString: function toString() {
+            if (this.getCall && this.callCount) {
+                var thisValue, prop, i = this.callCount;
+
+                while (i--) {
+                    thisValue = this.getCall(i).thisValue;
+
+                    for (prop in thisValue) {
+                        if (thisValue[prop] === this) {
+                            return prop;
+                        }
+                    }
+                }
+            }
+
+            return this.displayName || "sinon fake";
+        },
+
+        getConfig: function (custom) {
+            var config = {};
+            custom = custom || {};
+            var defaults = sinon.defaultConfig;
+
+            for (var prop in defaults) {
+                if (defaults.hasOwnProperty(prop)) {
+                    config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop];
+                }
+            }
+
+            return config;
+        },
+
+        format: function (val) {
+            return "" + val;
+        },
+
+        defaultConfig: {
+            injectIntoThis: true,
+            injectInto: null,
+            properties: ["spy", "stub", "mock", "clock", "server", "requests"],
+            useFakeTimers: true,
+            useFakeServer: true
+        },
+
+        timesInWords: function timesInWords(count) {
+            return count == 1 && "once" ||
+                count == 2 && "twice" ||
+                count == 3 && "thrice" ||
+                (count || 0) + " times";
+        },
+
+        calledInOrder: function (spies) {
+            for (var i = 1, l = spies.length; i < l; i++) {
+                if (!spies[i - 1].calledBefore(spies[i]) || !spies[i].called) {
+                    return false;
+                }
+            }
+
+            return true;
+        },
+
+        orderByFirstCall: function (spies) {
+            return spies.sort(function (a, b) {
+                // uuid, won't ever be equal
+                var aCall = a.getCall(0);
+                var bCall = b.getCall(0);
+                var aId = aCall && aCall.callId || -1;
+                var bId = bCall && bCall.callId || -1;
+
+                return aId < bId ? -1 : 1;
+            });
+        },
+
+        log: function () {},
+
+        logError: function (label, err) {
+            var msg = label + " threw exception: ";
+            sinon.log(msg + "[" + err.name + "] " + err.message);
+            if (err.stack) { sinon.log(err.stack); }
+
+            setTimeout(function () {
+                err.message = msg + err.message;
+                throw err;
+            }, 0);
+        },
+
+        typeOf: function (value) {
+            if (value === null) {
+                return "null";
+            }
+            else if (value === undefined) {
+                return "undefined";
+            }
+            var string = Object.prototype.toString.call(value);
+            return string.substring(8, string.length - 1).toLowerCase();
+        },
+
+        createStubInstance: function (constructor) {
+            if (typeof constructor !== "function") {
+                throw new TypeError("The constructor should be a function.");
+            }
+            return sinon.stub(sinon.create(constructor.prototype));
+        },
+
+        restore: function (object) {
+            if (object !== null && typeof object === "object") {
+                for (var prop in object) {
+                    if (isRestorable(object[prop])) {
+                        object[prop].restore();
+                    }
+                }
+            }
+            else if (isRestorable(object)) {
+                object.restore();
+            }
+        }
+    };
+
+    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var isAMD = typeof define === 'function' && typeof define.amd === 'object' && define.amd;
+
+    function makePublicAPI(require, exports, module) {
+        module.exports = sinon;
+        sinon.spy = require("./sinon/spy");
+        sinon.spyCall = require("./sinon/call");
+        sinon.behavior = require("./sinon/behavior");
+        sinon.stub = require("./sinon/stub");
+        sinon.mock = require("./sinon/mock");
+        sinon.collection = require("./sinon/collection");
+        sinon.assert = require("./sinon/assert");
+        sinon.sandbox = require("./sinon/sandbox");
+        sinon.test = require("./sinon/test");
+        sinon.testCase = require("./sinon/test_case");
+        sinon.match = require("./sinon/match");
+    }
+
+    if (isAMD) {
+        define(makePublicAPI);
+    } else if (isNode) {
+        try {
+            formatio = require("formatio");
+        } catch (e) {}
+        makePublicAPI(require, exports, module);
+    }
+
+    if (formatio) {
+        var formatter = formatio.configure({ quoteStrings: false });
+        sinon.format = function () {
+            return formatter.ascii.apply(formatter, arguments);
+        };
+    } else if (isNode) {
+        try {
+            var util = require("util");
+            sinon.format = function (value) {
+                return typeof value == "object" && value.toString === Object.prototype.toString ? util.inspect(value) : value;
+            };
+        } catch (e) {
+            /* Node, but no util module - would be very old, but better safe than
+             sorry */
+        }
+    }
+
+    return sinon;
+}(typeof formatio == "object" && formatio));
+
+/* @depend ../sinon.js */
+/*jslint eqeqeq: false, onevar: false, plusplus: false*/
+/*global module, require, sinon*/
+/**
+ * Match functions
+ *
+ * @author Maximilian Antoni (mail@maxantoni.de)
+ * @license BSD
+ *
+ * Copyright (c) 2012 Maximilian Antoni
+ */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    function assertType(value, type, name) {
+        var actual = sinon.typeOf(value);
+        if (actual !== type) {
+            throw new TypeError("Expected type of " + name + " to be " +
+                type + ", but was " + actual);
+        }
+    }
+
+    var matcher = {
+        toString: function () {
+            return this.message;
+        }
+    };
+
+    function isMatcher(object) {
+        return matcher.isPrototypeOf(object);
+    }
+
+    function matchObject(expectation, actual) {
+        if (actual === null || actual === undefined) {
+            return false;
+        }
+        for (var key in expectation) {
+            if (expectation.hasOwnProperty(key)) {
+                var exp = expectation[key];
+                var act = actual[key];
+                if (match.isMatcher(exp)) {
+                    if (!exp.test(act)) {
+                        return false;
+                    }
+                } else if (sinon.typeOf(exp) === "object") {
+                    if (!matchObject(exp, act)) {
+                        return false;
+                    }
+                } else if (!sinon.deepEqual(exp, act)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    matcher.or = function (m2) {
+        if (!arguments.length) {
+            throw new TypeError("Matcher expected");
+        } else if (!isMatcher(m2)) {
+            m2 = match(m2);
+        }
+        var m1 = this;
+        var or = sinon.create(matcher);
+        or.test = function (actual) {
+            return m1.test(actual) || m2.test(actual);
+        };
+        or.message = m1.message + ".or(" + m2.message + ")";
+        return or;
+    };
+
+    matcher.and = function (m2) {
+        if (!arguments.length) {
+            throw new TypeError("Matcher expected");
+        } else if (!isMatcher(m2)) {
+            m2 = match(m2);
+        }
+        var m1 = this;
+        var and = sinon.create(matcher);
+        and.test = function (actual) {
+            return m1.test(actual) && m2.test(actual);
+        };
+        and.message = m1.message + ".and(" + m2.message + ")";
+        return and;
+    };
+
+    var match = function (expectation, message) {
+        var m = sinon.create(matcher);
+        var type = sinon.typeOf(expectation);
+        switch (type) {
+        case "object":
+            if (typeof expectation.test === "function") {
+                m.test = function (actual) {
+                    return expectation.test(actual) === true;
+                };
+                m.message = "match(" + sinon.functionName(expectation.test) + ")";
+                return m;
+            }
+            var str = [];
+            for (var key in expectation) {
+                if (expectation.hasOwnProperty(key)) {
+                    str.push(key + ": " + expectation[key]);
+                }
+            }
+            m.test = function (actual) {
+                return matchObject(expectation, actual);
+            };
+            m.message = "match(" + str.join(", ") + ")";
+            break;
+        case "number":
+            m.test = function (actual) {
+                return expectation == actual;
+            };
+            break;
+        case "string":
+            m.test = function (actual) {
+                if (typeof actual !== "string") {
+                    return false;
+                }
+                return actual.indexOf(expectation) !== -1;
+            };
+            m.message = "match(\"" + expectation + "\")";
+            break;
+        case "regexp":
+            m.test = function (actual) {
+                if (typeof actual !== "string") {
+                    return false;
+                }
+                return expectation.test(actual);
+            };
+            break;
+        case "function":
+            m.test = expectation;
+            if (message) {
+                m.message = message;
+            } else {
+                m.message = "match(" + sinon.functionName(expectation) + ")";
+            }
+            break;
+        default:
+            m.test = function (actual) {
+              return sinon.deepEqual(expectation, actual);
+            };
+        }
+        if (!m.message) {
+            m.message = "match(" + expectation + ")";
+        }
+        return m;
+    };
+
+    match.isMatcher = isMatcher;
+
+    match.any = match(function () {
+        return true;
+    }, "any");
+
+    match.defined = match(function (actual) {
+        return actual !== null && actual !== undefined;
+    }, "defined");
+
+    match.truthy = match(function (actual) {
+        return !!actual;
+    }, "truthy");
+
+    match.falsy = match(function (actual) {
+        return !actual;
+    }, "falsy");
+
+    match.same = function (expectation) {
+        return match(function (actual) {
+            return expectation === actual;
+        }, "same(" + expectation + ")");
+    };
+
+    match.typeOf = function (type) {
+        assertType(type, "string", "type");
+        return match(function (actual) {
+            return sinon.typeOf(actual) === type;
+        }, "typeOf(\"" + type + "\")");
+    };
+
+    match.instanceOf = function (type) {
+        assertType(type, "function", "type");
+        return match(function (actual) {
+            return actual instanceof type;
+        }, "instanceOf(" + sinon.functionName(type) + ")");
+    };
+
+    function createPropertyMatcher(propertyTest, messagePrefix) {
+        return function (property, value) {
+            assertType(property, "string", "property");
+            var onlyProperty = arguments.length === 1;
+            var message = messagePrefix + "(\"" + property + "\"";
+            if (!onlyProperty) {
+                message += ", " + value;
+            }
+            message += ")";
+            return match(function (actual) {
+                if (actual === undefined || actual === null ||
+                        !propertyTest(actual, property)) {
+                    return false;
+                }
+                return onlyProperty || sinon.deepEqual(value, actual[property]);
+            }, message);
+        };
+    }
+
+    match.has = createPropertyMatcher(function (actual, property) {
+        if (typeof actual === "object") {
+            return property in actual;
+        }
+        return actual[property] !== undefined;
+    }, "has");
+
+    match.hasOwn = createPropertyMatcher(function (actual, property) {
+        return actual.hasOwnProperty(property);
+    }, "hasOwn");
+
+    match.bool = match.typeOf("boolean");
+    match.number = match.typeOf("number");
+    match.string = match.typeOf("string");
+    match.object = match.typeOf("object");
+    match.func = match.typeOf("function");
+    match.array = match.typeOf("array");
+    match.regexp = match.typeOf("regexp");
+    match.date = match.typeOf("date");
+
+    sinon.match = match;
+
+    if (typeof define === "function" && define.amd) {
+        define(["module"], function(module) { module.exports = match; });
+    } else if (commonJSModule) {
+        module.exports = match;
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+  * @depend ../sinon.js
+  * @depend match.js
+  */
+/*jslint eqeqeq: false, onevar: false, plusplus: false*/
+/*global module, require, sinon*/
+/**
+  * Spy calls
+  *
+  * @author Christian Johansen (christian@cjohansen.no)
+  * @author Maximilian Antoni (mail@maxantoni.de)
+  * @license BSD
+  *
+  * Copyright (c) 2010-2013 Christian Johansen
+  * Copyright (c) 2013 Maximilian Antoni
+  */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    function throwYieldError(proxy, text, args) {
+        var msg = sinon.functionName(proxy) + text;
+        if (args.length) {
+            msg += " Received [" + slice.call(args).join(", ") + "]";
+        }
+        throw new Error(msg);
+    }
+
+    var slice = Array.prototype.slice;
+
+    var callProto = {
+        calledOn: function calledOn(thisValue) {
+            if (sinon.match && sinon.match.isMatcher(thisValue)) {
+                return thisValue.test(this.thisValue);
+            }
+            return this.thisValue === thisValue;
+        },
+
+        calledWith: function calledWith() {
+            for (var i = 0, l = arguments.length; i < l; i += 1) {
+                if (!sinon.deepEqual(arguments[i], this.args[i])) {
+                    return false;
+                }
+            }
+
+            return true;
+        },
+
+        calledWithMatch: function calledWithMatch() {
+            for (var i = 0, l = arguments.length; i < l; i += 1) {
+                var actual = this.args[i];
+                var expectation = arguments[i];
+                if (!sinon.match || !sinon.match(expectation).test(actual)) {
+                    return false;
+                }
+            }
+            return true;
+        },
+
+        calledWithExactly: function calledWithExactly() {
+            return arguments.length == this.args.length &&
+                this.calledWith.apply(this, arguments);
+        },
+
+        notCalledWith: function notCalledWith() {
+            return !this.calledWith.apply(this, arguments);
+        },
+
+        notCalledWithMatch: function notCalledWithMatch() {
+            return !this.calledWithMatch.apply(this, arguments);
+        },
+
+        returned: function returned(value) {
+            return sinon.deepEqual(value, this.returnValue);
+        },
+
+        threw: function threw(error) {
+            if (typeof error === "undefined" || !this.exception) {
+                return !!this.exception;
+            }
+
+            return this.exception === error || this.exception.name === error;
+        },
+
+        calledWithNew: function calledWithNew() {
+            return this.proxy.prototype && this.thisValue instanceof this.proxy;
+        },
+
+        calledBefore: function (other) {
+            return this.callId < other.callId;
+        },
+
+        calledAfter: function (other) {
+            return this.callId > other.callId;
+        },
+
+        callArg: function (pos) {
+            this.args[pos]();
+        },
+
+        callArgOn: function (pos, thisValue) {
+            this.args[pos].apply(thisValue);
+        },
+
+        callArgWith: function (pos) {
+            this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1)));
+        },
+
+        callArgOnWith: function (pos, thisValue) {
+            var args = slice.call(arguments, 2);
+            this.args[pos].apply(thisValue, args);
+        },
+
+        "yield": function () {
+            this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)));
+        },
+
+        yieldOn: function (thisValue) {
+            var args = this.args;
+            for (var i = 0, l = args.length; i < l; ++i) {
+                if (typeof args[i] === "function") {
+                    args[i].apply(thisValue, slice.call(arguments, 1));
+                    return;
+                }
+            }
+            throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
+        },
+
+        yieldTo: function (prop) {
+            this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1)));
+        },
+
+        yieldToOn: function (prop, thisValue) {
+            var args = this.args;
+            for (var i = 0, l = args.length; i < l; ++i) {
+                if (args[i] && typeof args[i][prop] === "function") {
+                    args[i][prop].apply(thisValue, slice.call(arguments, 2));
+                    return;
+                }
+            }
+            throwYieldError(this.proxy, " cannot yield to '" + prop +
+                "' since no callback was passed.", args);
+        },
+
+        toString: function () {
+            var callStr = this.proxy.toString() + "(";
+            var args = [];
+
+            for (var i = 0, l = this.args.length; i < l; ++i) {
+                args.push(sinon.format(this.args[i]));
+            }
+
+            callStr = callStr + args.join(", ") + ")";
+
+            if (typeof this.returnValue != "undefined") {
+                callStr += " => " + sinon.format(this.returnValue);
+            }
+
+            if (this.exception) {
+                callStr += " !" + this.exception.name;
+
+                if (this.exception.message) {
+                    callStr += "(" + this.exception.message + ")";
+                }
+            }
+
+            return callStr;
+        }
+    };
+
+    callProto.invokeCallback = callProto.yield;
+
+    function createSpyCall(spy, thisValue, args, returnValue, exception, id) {
+        if (typeof id !== "number") {
+            throw new TypeError("Call id is not a number");
+        }
+        var proxyCall = sinon.create(callProto);
+        proxyCall.proxy = spy;
+        proxyCall.thisValue = thisValue;
+        proxyCall.args = args;
+        proxyCall.returnValue = returnValue;
+        proxyCall.exception = exception;
+        proxyCall.callId = id;
+
+        return proxyCall;
+    }
+    createSpyCall.toString = callProto.toString; // used by mocks
+
+    sinon.spyCall = createSpyCall;
+
+    if (typeof define === "function" && define.amd) {
+        define(["module"], function(module) { module.exports = createSpyCall; });
+    } else if (commonJSModule) {
+        module.exports = createSpyCall;
+    }
+}(typeof sinon == "object" && sinon || null));
+
+
+/**
+  * @depend ../sinon.js
+  * @depend call.js
+  */
+/*jslint eqeqeq: false, onevar: false, plusplus: false*/
+/*global module, require, sinon*/
+/**
+  * Spy functions
+  *
+  * @author Christian Johansen (christian@cjohansen.no)
+  * @license BSD
+  *
+  * Copyright (c) 2010-2013 Christian Johansen
+  */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var push = Array.prototype.push;
+    var slice = Array.prototype.slice;
+    var callId = 0;
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    function spy(object, property) {
+        if (!property && typeof object == "function") {
+            return spy.create(object);
+        }
+
+        if (!object && !property) {
+            return spy.create(function () { });
+        }
+
+        var method = object[property];
+        return sinon.wrapMethod(object, property, spy.create(method));
+    }
+
+    function matchingFake(fakes, args, strict) {
+        if (!fakes) {
+            return;
+        }
+
+        for (var i = 0, l = fakes.length; i < l; i++) {
+            if (fakes[i].matches(args, strict)) {
+                return fakes[i];
+            }
+        }
+    }
+
+    function incrementCallCount() {
+        this.called = true;
+        this.callCount += 1;
+        this.notCalled = false;
+        this.calledOnce = this.callCount == 1;
+        this.calledTwice = this.callCount == 2;
+        this.calledThrice = this.callCount == 3;
+    }
+
+    function createCallProperties() {
+        this.firstCall = this.getCall(0);
+        this.secondCall = this.getCall(1);
+        this.thirdCall = this.getCall(2);
+        this.lastCall = this.getCall(this.callCount - 1);
+    }
+
+    var vars = "a,b,c,d,e,f,g,h,i,j,k,l";
+    function createProxy(func) {
+        // Retain the function length:
+        var p;
+        if (func.length) {
+            eval("p = (function proxy(" + vars.substring(0, func.length * 2 - 1) +
+                ") { return p.invoke(func, this, slice.call(arguments)); });");
+        }
+        else {
+            p = function proxy() {
+                return p.invoke(func, this, slice.call(arguments));
+            };
+        }
+        return p;
+    }
+
+    var uuid = 0;
+
+    // Public API
+    var spyApi = {
+        reset: function () {
+            this.called = false;
+            this.notCalled = true;
+            this.calledOnce = false;
+            this.calledTwice = false;
+            this.calledThrice = false;
+            this.callCount = 0;
+            this.firstCall = null;
+            this.secondCall = null;
+            this.thirdCall = null;
+            this.lastCall = null;
+            this.args = [];
+            this.returnValues = [];
+            this.thisValues = [];
+            this.exceptions = [];
+            this.callIds = [];
+            if (this.fakes) {
+                for (var i = 0; i < this.fakes.length; i++) {
+                    this.fakes[i].reset();
+                }
+            }
+        },
+
+        create: function create(func) {
+            var name;
+
+            if (typeof func != "function") {
+                func = function () { };
+            } else {
+                name = sinon.functionName(func);
+            }
+
+            var proxy = createProxy(func);
+
+            sinon.extend(proxy, spy);
+            delete proxy.create;
+            sinon.extend(proxy, func);
+
+            proxy.reset();
+            proxy.prototype = func.prototype;
+            proxy.displayName = name || "spy";
+            proxy.toString = sinon.functionToString;
+            proxy._create = sinon.spy.create;
+            proxy.id = "spy#" + uuid++;
+
+            return proxy;
+        },
+
+        invoke: function invoke(func, thisValue, args) {
+            var matching = matchingFake(this.fakes, args);
+            var exception, returnValue;
+
+            incrementCallCount.call(this);
+            push.call(this.thisValues, thisValue);
+            push.call(this.args, args);
+            push.call(this.callIds, callId++);
+
+            // Make call properties available from within the spied function:
+            createCallProperties.call(this);
+
+            try {
+                if (matching) {
+                    returnValue = matching.invoke(func, thisValue, args);
+                } else {
+                    returnValue = (this.func || func).apply(thisValue, args);
+                }
+
+                var thisCall = this.getCall(this.callCount - 1);
+                if (thisCall.calledWithNew() && typeof returnValue !== 'object') {
+                    returnValue = thisValue;
+                }
+            } catch (e) {
+                exception = e;
+            }
+
+            push.call(this.exceptions, exception);
+            push.call(this.returnValues, returnValue);
+
+            // Make return value and exception available in the calls:
+            createCallProperties.call(this);
+
+            if (exception !== undefined) {
+                throw exception;
+            }
+
+            return returnValue;
+        },
+
+        named: function named(name) {
+            this.displayName = name;
+            return this;
+        },
+
+        getCall: function getCall(i) {
+            if (i < 0 || i >= this.callCount) {
+                return null;
+            }
+
+            return sinon.spyCall(this, this.thisValues[i], this.args[i],
+                                    this.returnValues[i], this.exceptions[i],
+                                    this.callIds[i]);
+        },
+
+        getCalls: function () {
+            var calls = [];
+            var i;
+
+            for (i = 0; i < this.callCount; i++) {
+                calls.push(this.getCall(i));
+            }
+
+            return calls;
+        },
+
+        calledBefore: function calledBefore(spyFn) {
+            if (!this.called) {
+                return false;
+            }
+
+            if (!spyFn.called) {
+                return true;
+            }
+
+            return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
+        },
+
+        calledAfter: function calledAfter(spyFn) {
+            if (!this.called || !spyFn.called) {
+                return false;
+            }
+
+            return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
+        },
+
+        withArgs: function () {
+            var args = slice.call(arguments);
+
+            if (this.fakes) {
+                var match = matchingFake(this.fakes, args, true);
+
+                if (match) {
+                    return match;
+                }
+            } else {
+                this.fakes = [];
+            }
+
+            var original = this;
+            var fake = this._create();
+            fake.matchingAguments = args;
+            fake.parent = this;
+            push.call(this.fakes, fake);
+
+            fake.withArgs = function () {
+                return original.withArgs.apply(original, arguments);
+            };
+
+            for (var i = 0; i < this.args.length; i++) {
+                if (fake.matches(this.args[i])) {
+                    incrementCallCount.call(fake);
+                    push.call(fake.thisValues, this.thisValues[i]);
+                    push.call(fake.args, this.args[i]);
+                    push.call(fake.returnValues, this.returnValues[i]);
+                    push.call(fake.exceptions, this.exceptions[i]);
+                    push.call(fake.callIds, this.callIds[i]);
+                }
+            }
+            createCallProperties.call(fake);
+
+            return fake;
+        },
+
+        matches: function (args, strict) {
+            var margs = this.matchingAguments;
+
+            if (margs.length <= args.length &&
+                sinon.deepEqual(margs, args.slice(0, margs.length))) {
+                return !strict || margs.length == args.length;
+            }
+        },
+
+        printf: function (format) {
+            var spy = this;
+            var args = slice.call(arguments, 1);
+            var formatter;
+
+            return (format || "").replace(/%(.)/g, function (match, specifyer) {
+                formatter = spyApi.formatters[specifyer];
+
+                if (typeof formatter == "function") {
+                    return formatter.call(null, spy, args);
+                } else if (!isNaN(parseInt(specifyer, 10))) {
+                    return sinon.format(args[specifyer - 1]);
+                }
+
+                return "%" + specifyer;
+            });
+        }
+    };
+
+    function delegateToCalls(method, matchAny, actual, notCalled) {
+        spyApi[method] = function () {
+            if (!this.called) {
+                if (notCalled) {
+                    return notCalled.apply(this, arguments);
+                }
+                return false;
+            }
+
+            var currentCall;
+            var matches = 0;
+
+            for (var i = 0, l = this.callCount; i < l; i += 1) {
+                currentCall = this.getCall(i);
+
+                if (currentCall[actual || method].apply(currentCall, arguments)) {
+                    matches += 1;
+
+                    if (matchAny) {
+                        return true;
+                    }
+                }
+            }
+
+            return matches === this.callCount;
+        };
+    }
+
+    delegateToCalls("calledOn", true);
+    delegateToCalls("alwaysCalledOn", false, "calledOn");
+    delegateToCalls("calledWith", true);
+    delegateToCalls("calledWithMatch", true);
+    delegateToCalls("alwaysCalledWith", false, "calledWith");
+    delegateToCalls("alwaysCalledWithMatch", false, "calledWithMatch");
+    delegateToCalls("calledWithExactly", true);
+    delegateToCalls("alwaysCalledWithExactly", false, "calledWithExactly");
+    delegateToCalls("neverCalledWith", false, "notCalledWith",
+        function () { return true; });
+    delegateToCalls("neverCalledWithMatch", false, "notCalledWithMatch",
+        function () { return true; });
+    delegateToCalls("threw", true);
+    delegateToCalls("alwaysThrew", false, "threw");
+    delegateToCalls("returned", true);
+    delegateToCalls("alwaysReturned", false, "returned");
+    delegateToCalls("calledWithNew", true);
+    delegateToCalls("alwaysCalledWithNew", false, "calledWithNew");
+    delegateToCalls("callArg", false, "callArgWith", function () {
+        throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
+    });
+    spyApi.callArgWith = spyApi.callArg;
+    delegateToCalls("callArgOn", false, "callArgOnWith", function () {
+        throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
+    });
+    spyApi.callArgOnWith = spyApi.callArgOn;
+    delegateToCalls("yield", false, "yield", function () {
+        throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
+    });
+    // "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
+    spyApi.invokeCallback = spyApi.yield;
+    delegateToCalls("yieldOn", false, "yieldOn", function () {
+        throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
+    });
+    delegateToCalls("yieldTo", false, "yieldTo", function (property) {
+        throw new Error(this.toString() + " cannot yield to '" + property +
+            "' since it was not yet invoked.");
+    });
+    delegateToCalls("yieldToOn", false, "yieldToOn", function (property) {
+        throw new Error(this.toString() + " cannot yield to '" + property +
+            "' since it was not yet invoked.");
+    });
+
+    spyApi.formatters = {
+        "c": function (spy) {
+            return sinon.timesInWords(spy.callCount);
+        },
+
+        "n": function (spy) {
+            return spy.toString();
+        },
+
+        "C": function (spy) {
+            var calls = [];
+
+            for (var i = 0, l = spy.callCount; i < l; ++i) {
+                var stringifiedCall = "    " + spy.getCall(i).toString();
+                if (/\n/.test(calls[i - 1])) {
+                    stringifiedCall = "\n" + stringifiedCall;
+                }
+                push.call(calls, stringifiedCall);
+            }
+
+            return calls.length > 0 ? "\n" + calls.join("\n") : "";
+        },
+
+        "t": function (spy) {
+            var objects = [];
+
+            for (var i = 0, l = spy.callCount; i < l; ++i) {
+                push.call(objects, sinon.format(spy.thisValues[i]));
+            }
+
+            return objects.join(", ");
+        },
+
+        "*": function (spy, args) {
+            var formatted = [];
+
+            for (var i = 0, l = args.length; i < l; ++i) {
+                push.call(formatted, sinon.format(args[i]));
+            }
+
+            return formatted.join(", ");
+        }
+    };
+
+    sinon.extend(spy, spyApi);
+
+    spy.spyCall = sinon.spyCall;
+    sinon.spy = spy;
+
+    if (typeof define === "function" && define.amd) {
+        define(["module"], function(module) { module.exports = spy; });
+    } else if (commonJSModule) {
+        module.exports = spy;
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend ../sinon.js
+ */
+/*jslint eqeqeq: false, onevar: false*/
+/*global module, require, sinon, process, setImmediate, setTimeout*/
+/**
+ * Stub behavior
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @author Tim Fischbach (mail@timfischbach.de)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    var slice = Array.prototype.slice;
+    var join = Array.prototype.join;
+    var proto;
+
+    var nextTick = (function () {
+        if (typeof process === "object" && typeof process.nextTick === "function") {
+            return process.nextTick;
+        } else if (typeof setImmediate === "function") {
+            return setImmediate;
+        } else {
+            return function (callback) {
+                setTimeout(callback, 0);
+            };
+        }
+    })();
+
+    function throwsException(error, message) {
+        if (typeof error == "string") {
+            this.exception = new Error(message || "");
+            this.exception.name = error;
+        } else if (!error) {
+            this.exception = new Error("Error");
+        } else {
+            this.exception = error;
+        }
+
+        return this;
+    }
+
+    function getCallback(behavior, args) {
+        var callArgAt = behavior.callArgAt;
+
+        if (callArgAt < 0) {
+            var callArgProp = behavior.callArgProp;
+
+            for (var i = 0, l = args.length; i < l; ++i) {
+                if (!callArgProp && typeof args[i] == "function") {
+                    return args[i];
+                }
+
+                if (callArgProp && args[i] &&
+                    typeof args[i][callArgProp] == "function") {
+                    return args[i][callArgProp];
+                }
+            }
+
+            return null;
+        }
+
+        return args[callArgAt];
+    }
+
+    function getCallbackError(behavior, func, args) {
+        if (behavior.callArgAt < 0) {
+            var msg;
+
+            if (behavior.callArgProp) {
+                msg = sinon.functionName(behavior.stub) +
+                    " expected to yield to '" + behavior.callArgProp +
+                    "', but no object with such a property was passed.";
+            } else {
+                msg = sinon.functionName(behavior.stub) +
+                    " expected to yield, but no callback was passed.";
+            }
+
+            if (args.length > 0) {
+                msg += " Received [" + join.call(args, ", ") + "]";
+            }
+
+            return msg;
+        }
+
+        return "argument at index " + behavior.callArgAt + " is not a function: " + func;
+    }
+
+    function callCallback(behavior, args) {
+        if (typeof behavior.callArgAt == "number") {
+            var func = getCallback(behavior, args);
+
+            if (typeof func != "function") {
+                throw new TypeError(getCallbackError(behavior, func, args));
+            }
+
+            if (behavior.callbackAsync) {
+                nextTick(function() {
+                    func.apply(behavior.callbackContext, behavior.callbackArguments);
+                });
+            } else {
+                func.apply(behavior.callbackContext, behavior.callbackArguments);
+            }
+        }
+    }
+
+    proto = {
+        create: function(stub) {
+            var behavior = sinon.extend({}, sinon.behavior);
+            delete behavior.create;
+            behavior.stub = stub;
+
+            return behavior;
+        },
+
+        isPresent: function() {
+            return (typeof this.callArgAt == 'number' ||
+                    this.exception ||
+                    typeof this.returnArgAt == 'number' ||
+                    this.returnThis ||
+                    this.returnValueDefined);
+        },
+
+        invoke: function(context, args) {
+            callCallback(this, args);
+
+            if (this.exception) {
+                throw this.exception;
+            } else if (typeof this.returnArgAt == 'number') {
+                return args[this.returnArgAt];
+            } else if (this.returnThis) {
+                return context;
+            }
+
+            return this.returnValue;
+        },
+
+        onCall: function(index) {
+            return this.stub.onCall(index);
+        },
+
+        onFirstCall: function() {
+            return this.stub.onFirstCall();
+        },
+
+        onSecondCall: function() {
+            return this.stub.onSecondCall();
+        },
+
+        onThirdCall: function() {
+            return this.stub.onThirdCall();
+        },
+
+        withArgs: function(/* arguments */) {
+            throw new Error('Defining a stub by invoking "stub.onCall(...).withArgs(...)" is not supported. ' +
+                            'Use "stub.withArgs(...).onCall(...)" to define sequential behavior for calls with certain arguments.');
+        },
+
+        callsArg: function callsArg(pos) {
+            if (typeof pos != "number") {
+                throw new TypeError("argument index is not number");
+            }
+
+            this.callArgAt = pos;
+            this.callbackArguments = [];
+            this.callbackContext = undefined;
+            this.callArgProp = undefined;
+            this.callbackAsync = false;
+
+            return this;
+        },
+
+        callsArgOn: function callsArgOn(pos, context) {
+            if (typeof pos != "number") {
+                throw new TypeError("argument index is not number");
+            }
+            if (typeof context != "object") {
+                throw new TypeError("argument context is not an object");
+            }
+
+            this.callArgAt = pos;
+            this.callbackArguments = [];
+            this.callbackContext = context;
+            this.callArgProp = undefined;
+            this.callbackAsync = false;
+
+            return this;
+        },
+
+        callsArgWith: function callsArgWith(pos) {
+            if (typeof pos != "number") {
+                throw new TypeError("argument index is not number");
+            }
+
+            this.callArgAt = pos;
+            this.callbackArguments = slice.call(arguments, 1);
+            this.callbackContext = undefined;
+            this.callArgProp = undefined;
+            this.callbackAsync = false;
+
+            return this;
+        },
+
+        callsArgOnWith: function callsArgWith(pos, context) {
+            if (typeof pos != "number") {
+                throw new TypeError("argument index is not number");
+            }
+            if (typeof context != "object") {
+                throw new TypeError("argument context is not an object");
+            }
+
+            this.callArgAt = pos;
+            this.callbackArguments = slice.call(arguments, 2);
+            this.callbackContext = context;
+            this.callArgProp = undefined;
+            this.callbackAsync = false;
+
+            return this;
+        },
+
+        yields: function () {
+            this.callArgAt = -1;
+            this.callbackArguments = slice.call(arguments, 0);
+            this.callbackContext = undefined;
+            this.callArgProp = undefined;
+            this.callbackAsync = false;
+
+            return this;
+        },
+
+        yieldsOn: function (context) {
+            if (typeof context != "object") {
+                throw new TypeError("argument context is not an object");
+            }
+
+            this.callArgAt = -1;
+            this.callbackArguments = slice.call(arguments, 1);
+            this.callbackContext = context;
+            this.callArgProp = undefined;
+            this.callbackAsync = false;
+
+            return this;
+        },
+
+        yieldsTo: function (prop) {
+            this.callArgAt = -1;
+            this.callbackArguments = slice.call(arguments, 1);
+            this.callbackContext = undefined;
+            this.callArgProp = prop;
+            this.callbackAsync = false;
+
+            return this;
+        },
+
+        yieldsToOn: function (prop, context) {
+            if (typeof context != "object") {
+                throw new TypeError("argument context is not an object");
+            }
+
+            this.callArgAt = -1;
+            this.callbackArguments = slice.call(arguments, 2);
+            this.callbackContext = context;
+            this.callArgProp = prop;
+            this.callbackAsync = false;
+
+            return this;
+        },
+
+
+        "throws": throwsException,
+        throwsException: throwsException,
+
+        returns: function returns(value) {
+            this.returnValue = value;
+            this.returnValueDefined = true;
+
+            return this;
+        },
+
+        returnsArg: function returnsArg(pos) {
+            if (typeof pos != "number") {
+                throw new TypeError("argument index is not number");
+            }
+
+            this.returnArgAt = pos;
+
+            return this;
+        },
+
+        returnsThis: function returnsThis() {
+            this.returnThis = true;
+
+            return this;
+        }
+    };
+
+    // create asynchronous versions of callsArg* and yields* methods
+    for (var method in proto) {
+        // need to avoid creating anotherasync versions of the newly added async methods
+        if (proto.hasOwnProperty(method) &&
+            method.match(/^(callsArg|yields)/) &&
+            !method.match(/Async/)) {
+            proto[method + 'Async'] = (function (syncFnName) {
+                return function () {
+                    var result = this[syncFnName].apply(this, arguments);
+                    this.callbackAsync = true;
+                    return result;
+                };
+            })(method);
+        }
+    }
+
+    sinon.behavior = proto;
+
+    if (typeof define === "function" && define.amd) {
+        define(["module"], function(module) { module.exports = proto; });
+    } else if (commonJSModule) {
+        module.exports = proto;
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend ../sinon.js
+ * @depend spy.js
+ * @depend behavior.js
+ */
+/*jslint eqeqeq: false, onevar: false*/
+/*global module, require, sinon*/
+/**
+ * Stub functions
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    function stub(object, property, func) {
+        if (!!func && typeof func != "function") {
+            throw new TypeError("Custom stub should be function");
+        }
+
+        var wrapper;
+
+        if (func) {
+            wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(func) : func;
+        } else {
+            wrapper = stub.create();
+        }
+
+        if (!object && typeof property === "undefined") {
+            return sinon.stub.create();
+        }
+
+        if (typeof property === "undefined" && typeof object == "object") {
+            for (var prop in object) {
+                if (typeof object[prop] === "function") {
+                    stub(object, prop);
+                }
+            }
+
+            return object;
+        }
+
+        return sinon.wrapMethod(object, property, wrapper);
+    }
+
+    function getDefaultBehavior(stub) {
+        return stub.defaultBehavior || getParentBehaviour(stub) || sinon.behavior.create(stub);
+    }
+
+    function getParentBehaviour(stub) {
+        return (stub.parent && getCurrentBehavior(stub.parent));
+    }
+
+    function getCurrentBehavior(stub) {
+        var behavior = stub.behaviors[stub.callCount - 1];
+        return behavior && behavior.isPresent() ? behavior : getDefaultBehavior(stub);
+    }
+
+    var uuid = 0;
+
+    sinon.extend(stub, (function () {
+        var proto = {
+            create: function create() {
+                var functionStub = function () {
+                    return getCurrentBehavior(functionStub).invoke(this, arguments);
+                };
+
+                functionStub.id = "stub#" + uuid++;
+                var orig = functionStub;
+                functionStub = sinon.spy.create(functionStub);
+                functionStub.func = orig;
+
+                sinon.extend(functionStub, stub);
+                functionStub._create = sinon.stub.create;
+                functionStub.displayName = "stub";
+                functionStub.toString = sinon.functionToString;
+
+                functionStub.defaultBehavior = null;
+                functionStub.behaviors = [];
+
+                return functionStub;
+            },
+
+            resetBehavior: function () {
+                var i;
+
+                this.defaultBehavior = null;
+                this.behaviors = [];
+
+                delete this.returnValue;
+                delete this.returnArgAt;
+                this.returnThis = false;
+
+                if (this.fakes) {
+                    for (i = 0; i < this.fakes.length; i++) {
+                        this.fakes[i].resetBehavior();
+                    }
+                }
+            },
+
+            onCall: function(index) {
+                if (!this.behaviors[index]) {
+                    this.behaviors[index] = sinon.behavior.create(this);
+                }
+
+                return this.behaviors[index];
+            },
+
+            onFirstCall: function() {
+                return this.onCall(0);
+            },
+
+            onSecondCall: function() {
+                return this.onCall(1);
+            },
+
+            onThirdCall: function() {
+                return this.onCall(2);
+            }
+        };
+
+        for (var method in sinon.behavior) {
+            if (sinon.behavior.hasOwnProperty(method) &&
+                !proto.hasOwnProperty(method) &&
+                method != 'create' &&
+                method != 'withArgs' &&
+                method != 'invoke') {
+                proto[method] = (function(behaviorMethod) {
+                    return function() {
+                        this.defaultBehavior = this.defaultBehavior || sinon.behavior.create(this);
+                        this.defaultBehavior[behaviorMethod].apply(this.defaultBehavior, arguments);
+                        return this;
+                    };
+                }(method));
+            }
+        }
+
+        return proto;
+    }()));
+
+    sinon.stub = stub;
+
+    if (typeof define === "function" && define.amd) {
+        define(["module"], function(module) { module.exports = stub; });
+    } else if (commonJSModule) {
+        module.exports = stub;
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend ../sinon.js
+ * @depend stub.js
+ */
+/*jslint eqeqeq: false, onevar: false, nomen: false*/
+/*global module, require, sinon*/
+/**
+ * Mock functions.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var push = [].push;
+    var match;
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    match = sinon.match;
+
+    if (!match && commonJSModule) {
+        match = require("./match");
+    }
+
+    function mock(object) {
+        if (!object) {
+            return sinon.expectation.create("Anonymous mock");
+        }
+
+        return mock.create(object);
+    }
+
+    sinon.mock = mock;
+
+    sinon.extend(mock, (function () {
+        function each(collection, callback) {
+            if (!collection) {
+                return;
+            }
+
+            for (var i = 0, l = collection.length; i < l; i += 1) {
+                callback(collection[i]);
+            }
+        }
+
+        return {
+            create: function create(object) {
+                if (!object) {
+                    throw new TypeError("object is null");
+                }
+
+                var mockObject = sinon.extend({}, mock);
+                mockObject.object = object;
+                delete mockObject.create;
+
+                return mockObject;
+            },
+
+            expects: function expects(method) {
+                if (!method) {
+                    throw new TypeError("method is falsy");
+                }
+
+                if (!this.expectations) {
+                    this.expectations = {};
+                    this.proxies = [];
+                }
+
+                if (!this.expectations[method]) {
+                    this.expectations[method] = [];
+                    var mockObject = this;
+
+                    sinon.wrapMethod(this.object, method, function () {
+                        return mockObject.invokeMethod(method, this, arguments);
+                    });
+
+                    push.call(this.proxies, method);
+                }
+
+                var expectation = sinon.expectation.create(method);
+                push.call(this.expectations[method], expectation);
+
+                return expectation;
+            },
+
+            restore: function restore() {
+                var object = this.object;
+
+                each(this.proxies, function (proxy) {
+                    if (typeof object[proxy].restore == "function") {
+                        object[proxy].restore();
+                    }
+                });
+            },
+
+            verify: function verify() {
+                var expectations = this.expectations || {};
+                var messages = [], met = [];
+
+                each(this.proxies, function (proxy) {
+                    each(expectations[proxy], function (expectation) {
+                        if (!expectation.met()) {
+                            push.call(messages, expectation.toString());
+                        } else {
+                            push.call(met, expectation.toString());
+                        }
+                    });
+                });
+
+                this.restore();
+
+                if (messages.length > 0) {
+                    sinon.expectation.fail(messages.concat(met).join("\n"));
+                } else {
+                    sinon.expectation.pass(messages.concat(met).join("\n"));
+                }
+
+                return true;
+            },
+
+            invokeMethod: function invokeMethod(method, thisValue, args) {
+                var expectations = this.expectations && this.expectations[method];
+                var length = expectations && expectations.length || 0, i;
+
+                for (i = 0; i < length; i += 1) {
+                    if (!expectations[i].met() &&
+                        expectations[i].allowsCall(thisValue, args)) {
+                        return expectations[i].apply(thisValue, args);
+                    }
+                }
+
+                var messages = [], available, exhausted = 0;
+
+                for (i = 0; i < length; i += 1) {
+                    if (expectations[i].allowsCall(thisValue, args)) {
+                        available = available || expectations[i];
+                    } else {
+                        exhausted += 1;
+                    }
+                    push.call(messages, "    " + expectations[i].toString());
+                }
+
+                if (exhausted === 0) {
+                    return available.apply(thisValue, args);
+                }
+
+                messages.unshift("Unexpected call: " + sinon.spyCall.toString.call({
+                    proxy: method,
+                    args: args
+                }));
+
+                sinon.expectation.fail(messages.join("\n"));
+            }
+        };
+    }()));
+
+    var times = sinon.timesInWords;
+
+    sinon.expectation = (function () {
+        var slice = Array.prototype.slice;
+        var _invoke = sinon.spy.invoke;
+
+        function callCountInWords(callCount) {
+            if (callCount == 0) {
+                return "never called";
+            } else {
+                return "called " + times(callCount);
+            }
+        }
+
+        function expectedCallCountInWords(expectation) {
+            var min = expectation.minCalls;
+            var max = expectation.maxCalls;
+
+            if (typeof min == "number" && typeof max == "number") {
+                var str = times(min);
+
+                if (min != max) {
+                    str = "at least " + str + " and at most " + times(max);
+                }
+
+                return str;
+            }
+
+            if (typeof min == "number") {
+                return "at least " + times(min);
+            }
+
+            return "at most " + times(max);
+        }
+
+        function receivedMinCalls(expectation) {
+            var hasMinLimit = typeof expectation.minCalls == "number";
+            return !hasMinLimit || expectation.callCount >= expectation.minCalls;
+        }
+
+        function receivedMaxCalls(expectation) {
+            if (typeof expectation.maxCalls != "number") {
+                return false;
+            }
+
+            return expectation.callCount == expectation.maxCalls;
+        }
+
+        function verifyMatcher(possibleMatcher, arg){
+            if (match && match.isMatcher(possibleMatcher)) {
+                return possibleMatcher.test(arg);
+            } else {
+                return true;
+            }
+        }
+
+        return {
+            minCalls: 1,
+            maxCalls: 1,
+
+            create: function create(methodName) {
+                var expectation = sinon.extend(sinon.stub.create(), sinon.expectation);
+                delete expectation.create;
+                expectation.method = methodName;
+
+                return expectation;
+            },
+
+            invoke: function invoke(func, thisValue, args) {
+                this.verifyCallAllowed(thisValue, args);
+
+                return _invoke.apply(this, arguments);
+            },
+
+            atLeast: function atLeast(num) {
+                if (typeof num != "number") {
+                    throw new TypeError("'" + num + "' is not number");
+                }
+
+                if (!this.limitsSet) {
+                    this.maxCalls = null;
+                    this.limitsSet = true;
+                }
+
+                this.minCalls = num;
+
+                return this;
+            },
+
+            atMost: function atMost(num) {
+                if (typeof num != "number") {
+                    throw new TypeError("'" + num + "' is not number");
+                }
+
+                if (!this.limitsSet) {
+                    this.minCalls = null;
+                    this.limitsSet = true;
+                }
+
+                this.maxCalls = num;
+
+                return this;
+            },
+
+            never: function never() {
+                return this.exactly(0);
+            },
+
+            once: function once() {
+                return this.exactly(1);
+            },
+
+            twice: function twice() {
+                return this.exactly(2);
+            },
+
+            thrice: function thrice() {
+                return this.exactly(3);
+            },
+
+            exactly: function exactly(num) {
+                if (typeof num != "number") {
+                    throw new TypeError("'" + num + "' is not a number");
+                }
+
+                this.atLeast(num);
+                return this.atMost(num);
+            },
+
+            met: function met() {
+                return !this.failed && receivedMinCalls(this);
+            },
+
+            verifyCallAllowed: function verifyCallAllowed(thisValue, args) {
+                if (receivedMaxCalls(this)) {
+                    this.failed = true;
+                    sinon.expectation.fail(this.method + " already called " + times(this.maxCalls));
+                }
+
+                if ("expectedThis" in this && this.expectedThis !== thisValue) {
+                    sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " +
+                        this.expectedThis);
+                }
+
+                if (!("expectedArguments" in this)) {
+                    return;
+                }
+
+                if (!args) {
+                    sinon.expectation.fail(this.method + " received no arguments, expected " +
+                        sinon.format(this.expectedArguments));
+                }
+
+                if (args.length < this.expectedArguments.length) {
+                    sinon.expectation.fail(this.method + " received too few arguments (" + sinon.format(args) +
+                        "), expected " + sinon.format(this.expectedArguments));
+                }
+
+                if (this.expectsExactArgCount &&
+                    args.length != this.expectedArguments.length) {
+                    sinon.expectation.fail(this.method + " received too many arguments (" + sinon.format(args) +
+                        "), expected " + sinon.format(this.expectedArguments));
+                }
+
+                for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
+
+                    if (!verifyMatcher(this.expectedArguments[i],args[i])) {
+                        sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
+                            ", didn't match " + this.expectedArguments.toString());
+                    }
+
+                    if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
+                        sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
+                            ", expected " + sinon.format(this.expectedArguments));
+                    }
+                }
+            },
+
+            allowsCall: function allowsCall(thisValue, args) {
+                if (this.met() && receivedMaxCalls(this)) {
+                    return false;
+                }
+
+                if ("expectedThis" in this && this.expectedThis !== thisValue) {
+                    return false;
+                }
+
+                if (!("expectedArguments" in this)) {
+                    return true;
+                }
+
+                args = args || [];
+
+                if (args.length < this.expectedArguments.length) {
+                    return false;
+                }
+
+                if (this.expectsExactArgCount &&
+                    args.length != this.expectedArguments.length) {
+                    return false;
+                }
+
+                for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
+                    if (!verifyMatcher(this.expectedArguments[i],args[i])) {
+                        return false;
+                    }
+
+                    if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
+                        return false;
+                    }
+                }
+
+                return true;
+            },
+
+            withArgs: function withArgs() {
+                this.expectedArguments = slice.call(arguments);
+                return this;
+            },
+
+            withExactArgs: function withExactArgs() {
+                this.withArgs.apply(this, arguments);
+                this.expectsExactArgCount = true;
+                return this;
+            },
+
+            on: function on(thisValue) {
+                this.expectedThis = thisValue;
+                return this;
+            },
+
+            toString: function () {
+                var args = (this.expectedArguments || []).slice();
+
+                if (!this.expectsExactArgCount) {
+                    push.call(args, "[...]");
+                }
+
+                var callStr = sinon.spyCall.toString.call({
+                    proxy: this.method || "anonymous mock expectation",
+                    args: args
+                });
+
+                var message = callStr.replace(", [...", "[, ...") + " " +
+                    expectedCallCountInWords(this);
+
+                if (this.met()) {
+                    return "Expectation met: " + message;
+                }
+
+                return "Expected " + message + " (" +
+                    callCountInWords(this.callCount) + ")";
+            },
+
+            verify: function verify() {
+                if (!this.met()) {
+                    sinon.expectation.fail(this.toString());
+                } else {
+                    sinon.expectation.pass(this.toString());
+                }
+
+                return true;
+            },
+
+            pass: function(message) {
+              sinon.assert.pass(message);
+            },
+            fail: function (message) {
+                var exception = new Error(message);
+                exception.name = "ExpectationError";
+
+                throw exception;
+            }
+        };
+    }());
+
+    sinon.mock = mock;
+
+    if (typeof define === "function" && define.amd) {
+        define(["module"], function(module) { module.exports = mock; });
+    } else if (commonJSModule) {
+        module.exports = mock;
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend ../sinon.js
+ * @depend stub.js
+ * @depend mock.js
+ */
+/*jslint eqeqeq: false, onevar: false, forin: true*/
+/*global module, require, sinon*/
+/**
+ * Collections of stubs, spies and mocks.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var push = [].push;
+    var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    function getFakes(fakeCollection) {
+        if (!fakeCollection.fakes) {
+            fakeCollection.fakes = [];
+        }
+
+        return fakeCollection.fakes;
+    }
+
+    function each(fakeCollection, method) {
+        var fakes = getFakes(fakeCollection);
+
+        for (var i = 0, l = fakes.length; i < l; i += 1) {
+            if (typeof fakes[i][method] == "function") {
+                fakes[i][method]();
+            }
+        }
+    }
+
+    function compact(fakeCollection) {
+        var fakes = getFakes(fakeCollection);
+        var i = 0;
+        while (i < fakes.length) {
+          fakes.splice(i, 1);
+        }
+    }
+
+    var collection = {
+        verify: function resolve() {
+            each(this, "verify");
+        },
+
+        restore: function restore() {
+            each(this, "restore");
+            compact(this);
+        },
+
+        verifyAndRestore: function verifyAndRestore() {
+            var exception;
+
+            try {
+                this.verify();
+            } catch (e) {
+                exception = e;
+            }
+
+            this.restore();
+
+            if (exception) {
+                throw exception;
+            }
+        },
+
+        add: function add(fake) {
+            push.call(getFakes(this), fake);
+            return fake;
+        },
+
+        spy: function spy() {
+            return this.add(sinon.spy.apply(sinon, arguments));
+        },
+
+        stub: function stub(object, property, value) {
+            if (property) {
+                var original = object[property];
+
+                if (typeof original != "function") {
+                    if (!hasOwnProperty.call(object, property)) {
+                        throw new TypeError("Cannot stub non-existent own property " + property);
+                    }
+
+                    object[property] = value;
+
+                    return this.add({
+                        restore: function () {
+                            object[property] = original;
+                        }
+                    });
+                }
+            }
+            if (!property && !!object && typeof object == "object") {
+                var stubbedObj = sinon.stub.apply(sinon, arguments);
+
+                for (var prop in stubbedObj) {
+                    if (typeof stubbedObj[prop] === "function") {
+                        this.add(stubbedObj[prop]);
+                    }
+                }
+
+                return stubbedObj;
+            }
+
+            return this.add(sinon.stub.apply(sinon, arguments));
+        },
+
+        mock: function mock() {
+            return this.add(sinon.mock.apply(sinon, arguments));
+        },
+
+        inject: function inject(obj) {
+            var col = this;
+
+            obj.spy = function () {
+                return col.spy.apply(col, arguments);
+            };
+
+            obj.stub = function () {
+                return col.stub.apply(col, arguments);
+            };
+
+            obj.mock = function () {
+                return col.mock.apply(col, arguments);
+            };
+
+            return obj;
+        }
+    };
+
+    sinon.collection = collection;
+
+    if (typeof define === "function" && define.amd) {
+        define(["module"], function(module) { module.exports = collection; });
+    } else if (commonJSModule) {
+        module.exports = collection;
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/
+/*global module, require, window*/
+/**
+ * Fake timer API
+ * setTimeout
+ * setInterval
+ * clearTimeout
+ * clearInterval
+ * tick
+ * reset
+ * Date
+ *
+ * Inspired by jsUnitMockTimeOut from JsUnit
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+if (typeof sinon == "undefined") {
+    var sinon = {};
+}
+
+(function (global) {
+    // node expects setTimeout/setInterval to return a fn object w/ .ref()/.unref()
+    // browsers, a number.
+    // see https://github.com/cjohansen/Sinon.JS/pull/436
+    var timeoutResult = setTimeout(function() {}, 0);
+    var addTimerReturnsObject = typeof timeoutResult === 'object';
+    clearTimeout(timeoutResult);
+
+    var id = 1;
+
+    function addTimer(args, recurring) {
+        if (args.length === 0) {
+            throw new Error("Function requires at least 1 parameter");
+        }
+
+        if (typeof args[0] === "undefined") {
+            throw new Error("Callback must be provided to timer calls");
+        }
+
+        var toId = id++;
+        var delay = args[1] || 0;
+
+        if (!this.timeouts) {
+            this.timeouts = {};
+        }
+
+        this.timeouts[toId] = {
+            id: toId,
+            func: args[0],
+            callAt: this.now + delay,
+            invokeArgs: Array.prototype.slice.call(args, 2)
+        };
+
+        if (recurring === true) {
+            this.timeouts[toId].interval = delay;
+        }
+
+        if (addTimerReturnsObject) {
+            return {
+                id: toId,
+                ref: function() {},
+                unref: function() {}
+            };
+        }
+        else {
+            return toId;
+        }
+    }
+
+    function parseTime(str) {
+        if (!str) {
+            return 0;
+        }
+
+        var strings = str.split(":");
+        var l = strings.length, i = l;
+        var ms = 0, parsed;
+
+        if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
+            throw new Error("tick only understands numbers and 'h:m:s'");
+        }
+
+        while (i--) {
+            parsed = parseInt(strings[i], 10);
+
+            if (parsed >= 60) {
+                throw new Error("Invalid time " + str);
+            }
+
+            ms += parsed * Math.pow(60, (l - i - 1));
+        }
+
+        return ms * 1000;
+    }
+
+    function createObject(object) {
+        var newObject;
+
+        if (Object.create) {
+            newObject = Object.create(object);
+        } else {
+            var F = function () {};
+            F.prototype = object;
+            newObject = new F();
+        }
+
+        newObject.Date.clock = newObject;
+        return newObject;
+    }
+
+    sinon.clock = {
+        now: 0,
+
+        create: function create(now) {
+            var clock = createObject(this);
+
+            if (typeof now == "number") {
+                clock.now = now;
+            }
+
+            if (!!now && typeof now == "object") {
+                throw new TypeError("now should be milliseconds since UNIX epoch");
+            }
+
+            return clock;
+        },
+
+        setTimeout: function setTimeout(callback, timeout) {
+            return addTimer.call(this, arguments, false);
+        },
+
+        clearTimeout: function clearTimeout(timerId) {
+            if (!timerId) {
+                // null appears to be allowed in most browsers, and appears to be relied upon by some libraries, like Bootstrap carousel
+                return;
+            }
+            if (!this.timeouts) {
+                this.timeouts = [];
+            }
+            // in Node, timerId is an object with .ref()/.unref(), and
+            // its .id field is the actual timer id.
+            if (typeof timerId === 'object') {
+              timerId = timerId.id
+            }
+            if (timerId in this.timeouts) {
+                delete this.timeouts[timerId];
+            }
+        },
+
+        setInterval: function setInterval(callback, timeout) {
+            return addTimer.call(this, arguments, true);
+        },
+
+        clearInterval: function clearInterval(timerId) {
+            this.clearTimeout(timerId);
+        },
+
+        setImmediate: function setImmediate(callback) {
+            var passThruArgs = Array.prototype.slice.call(arguments, 1);
+
+            return addTimer.call(this, [callback, 0].concat(passThruArgs), false);
+        },
+
+        clearImmediate: function clearImmediate(timerId) {
+            this.clearTimeout(timerId);
+        },
+
+        tick: function tick(ms) {
+            ms = typeof ms == "number" ? ms : parseTime(ms);
+            var tickFrom = this.now, tickTo = this.now + ms, previous = this.now;
+            var timer = this.firstTimerInRange(tickFrom, tickTo);
+
+            var firstException;
+            while (timer && tickFrom <= tickTo) {
+                if (this.timeouts[timer.id]) {
+                    tickFrom = this.now = timer.callAt;
+                    try {
+                      this.callTimer(timer);
+                    } catch (e) {
+                      firstException = firstException || e;
+                    }
+                }
+
+                timer = this.firstTimerInRange(previous, tickTo);
+                previous = tickFrom;
+            }
+
+            this.now = tickTo;
+
+            if (firstException) {
+              throw firstException;
+            }
+
+            return this.now;
+        },
+
+        firstTimerInRange: function (from, to) {
+            var timer, smallest = null, originalTimer;
+
+            for (var id in this.timeouts) {
+                if (this.timeouts.hasOwnProperty(id)) {
+                    if (this.timeouts[id].callAt < from || this.timeouts[id].callAt > to) {
+                        continue;
+                    }
+
+                    if (smallest === null || this.timeouts[id].callAt < smallest) {
+                        originalTimer = this.timeouts[id];
+                        smallest = this.timeouts[id].callAt;
+
+                        timer = {
+                            func: this.timeouts[id].func,
+                            callAt: this.timeouts[id].callAt,
+                            interval: this.timeouts[id].interval,
+                            id: this.timeouts[id].id,
+                            invokeArgs: this.timeouts[id].invokeArgs
+                        };
+                    }
+                }
+            }
+
+            return timer || null;
+        },
+
+        callTimer: function (timer) {
+            if (typeof timer.interval == "number") {
+                this.timeouts[timer.id].callAt += timer.interval;
+            } else {
+                delete this.timeouts[timer.id];
+            }
+
+            try {
+                if (typeof timer.func == "function") {
+                    timer.func.apply(null, timer.invokeArgs);
+                } else {
+                    eval(timer.func);
+                }
+            } catch (e) {
+              var exception = e;
+            }
+
+            if (!this.timeouts[timer.id]) {
+                if (exception) {
+                  throw exception;
+                }
+                return;
+            }
+
+            if (exception) {
+              throw exception;
+            }
+        },
+
+        reset: function reset() {
+            this.timeouts = {};
+        },
+
+        Date: (function () {
+            var NativeDate = Date;
+
+            function ClockDate(year, month, date, hour, minute, second, ms) {
+                // Defensive and verbose to avoid potential harm in passing
+                // explicit undefined when user does not pass argument
+                switch (arguments.length) {
+                case 0:
+                    return new NativeDate(ClockDate.clock.now);
+                case 1:
+                    return new NativeDate(year);
+                case 2:
+                    return new NativeDate(year, month);
+                case 3:
+                    return new NativeDate(year, month, date);
+                case 4:
+                    return new NativeDate(year, month, date, hour);
+                case 5:
+                    return new NativeDate(year, month, date, hour, minute);
+                case 6:
+                    return new NativeDate(year, month, date, hour, minute, second);
+                default:
+                    return new NativeDate(year, month, date, hour, minute, second, ms);
+                }
+            }
+
+            return mirrorDateProperties(ClockDate, NativeDate);
+        }())
+    };
+
+    function mirrorDateProperties(target, source) {
+        if (source.now) {
+            target.now = function now() {
+                return target.clock.now;
+            };
+        } else {
+            delete target.now;
+        }
+
+        if (source.toSource) {
+            target.toSource = function toSource() {
+                return source.toSource();
+            };
+        } else {
+            delete target.toSource;
+        }
+
+        target.toString = function toString() {
+            return source.toString();
+        };
+
+        target.prototype = source.prototype;
+        target.parse = source.parse;
+        target.UTC = source.UTC;
+        target.prototype.toUTCString = source.prototype.toUTCString;
+
+        for (var prop in source) {
+            if (source.hasOwnProperty(prop)) {
+                target[prop] = source[prop];
+            }
+        }
+
+        return target;
+    }
+
+    var methods = ["Date", "setTimeout", "setInterval",
+                   "clearTimeout", "clearInterval"];
+
+    if (typeof global.setImmediate !== "undefined") {
+        methods.push("setImmediate");
+    }
+
+    if (typeof global.clearImmediate !== "undefined") {
+        methods.push("clearImmediate");
+    }
+
+    function restore() {
+        var method;
+
+        for (var i = 0, l = this.methods.length; i < l; i++) {
+            method = this.methods[i];
+
+            if (global[method].hadOwnProperty) {
+                global[method] = this["_" + method];
+            } else {
+                try {
+                    delete global[method];
+                } catch (e) {}
+            }
+        }
+
+        // Prevent multiple executions which will completely remove these props
+        this.methods = [];
+    }
+
+    function stubGlobal(method, clock) {
+        clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(global, method);
+        clock["_" + method] = global[method];
+
+        if (method == "Date") {
+            var date = mirrorDateProperties(clock[method], global[method]);
+            global[method] = date;
+        } else {
+            global[method] = function () {
+                return clock[method].apply(clock, arguments);
+            };
+
+            for (var prop in clock[method]) {
+                if (clock[method].hasOwnProperty(prop)) {
+                    global[method][prop] = clock[method][prop];
+                }
+            }
+        }
+
+        global[method].clock = clock;
+    }
+
+    sinon.useFakeTimers = function useFakeTimers(now) {
+        var clock = sinon.clock.create(now);
+        clock.restore = restore;
+        clock.methods = Array.prototype.slice.call(arguments,
+                                                   typeof now == "number" ? 1 : 0);
+
+        if (clock.methods.length === 0) {
+            clock.methods = methods;
+        }
+
+        for (var i = 0, l = clock.methods.length; i < l; i++) {
+            stubGlobal(clock.methods[i], clock);
+        }
+
+        return clock;
+    };
+}(typeof global != "undefined" && typeof global !== "function" ? global : this));
+
+sinon.timers = {
+    setTimeout: setTimeout,
+    clearTimeout: clearTimeout,
+    setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined),
+    clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmediate: undefined),
+    setInterval: setInterval,
+    clearInterval: clearInterval,
+    Date: Date
+};
+
+if (typeof module !== 'undefined' && module.exports) {
+    module.exports = sinon;
+}
+
+/*jslint eqeqeq: false, onevar: false*/
+/*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
+/**
+ * Minimal Event interface implementation
+ *
+ * Original implementation by Sven Fuchs: https://gist.github.com/995028
+ * Modifications and tests by Christian Johansen.
+ *
+ * @author Sven Fuchs (svenfuchs@artweb-design.de)
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2011 Sven Fuchs, Christian Johansen
+ */
+
+if (typeof sinon == "undefined") {
+    this.sinon = {};
+}
+
+(function () {
+    var push = [].push;
+
+    sinon.Event = function Event(type, bubbles, cancelable, target) {
+        this.initEvent(type, bubbles, cancelable, target);
+    };
+
+    sinon.Event.prototype = {
+        initEvent: function(type, bubbles, cancelable, target) {
+            this.type = type;
+            this.bubbles = bubbles;
+            this.cancelable = cancelable;
+            this.target = target;
+        },
+
+        stopPropagation: function () {},
+
+        preventDefault: function () {
+            this.defaultPrevented = true;
+        }
+    };
+
+    sinon.ProgressEvent = function ProgressEvent(type, progressEventRaw, target) {
+        this.initEvent(type, false, false, target);
+        this.loaded = progressEventRaw.loaded || null;
+        this.total = progressEventRaw.total || null;
+    };
+
+    sinon.ProgressEvent.prototype = new sinon.Event();
+
+    sinon.ProgressEvent.prototype.constructor =  sinon.ProgressEvent;
+
+    sinon.CustomEvent = function CustomEvent(type, customData, target) {
+        this.initEvent(type, false, false, target);
+        this.detail = customData.detail || null;
+    };
+
+    sinon.CustomEvent.prototype = new sinon.Event();
+
+    sinon.CustomEvent.prototype.constructor =  sinon.CustomEvent;
+
+    sinon.EventTarget = {
+        addEventListener: function addEventListener(event, listener) {
+            this.eventListeners = this.eventListeners || {};
+            this.eventListeners[event] = this.eventListeners[event] || [];
+            push.call(this.eventListeners[event], listener);
+        },
+
+        removeEventListener: function removeEventListener(event, listener) {
+            var listeners = this.eventListeners && this.eventListeners[event] || [];
+
+            for (var i = 0, l = listeners.length; i < l; ++i) {
+                if (listeners[i] == listener) {
+                    return listeners.splice(i, 1);
+                }
+            }
+        },
+
+        dispatchEvent: function dispatchEvent(event) {
+            var type = event.type;
+            var listeners = this.eventListeners && this.eventListeners[type] || [];
+
+            for (var i = 0; i < listeners.length; i++) {
+                if (typeof listeners[i] == "function") {
+                    listeners[i].call(this, event);
+                } else {
+                    listeners[i].handleEvent(event);
+                }
+            }
+
+            return !!event.defaultPrevented;
+        }
+    };
+}());
+
+/**
+ * @depend ../../sinon.js
+ * @depend event.js
+ */
+/*jslint eqeqeq: false, onevar: false*/
+/*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
+/**
+ * Fake XMLHttpRequest object
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+// wrapper for global
+(function(global) {
+    if (typeof sinon === "undefined") {
+        global.sinon = {};
+    }
+
+    var supportsProgress = typeof ProgressEvent !== "undefined";
+    var supportsCustomEvent = typeof CustomEvent !== "undefined";
+    sinon.xhr = { XMLHttpRequest: global.XMLHttpRequest };
+    var xhr = sinon.xhr;
+    xhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
+    xhr.GlobalActiveXObject = global.ActiveXObject;
+    xhr.supportsActiveX = typeof xhr.GlobalActiveXObject != "undefined";
+    xhr.supportsXHR = typeof xhr.GlobalXMLHttpRequest != "undefined";
+    xhr.workingXHR = xhr.supportsXHR ? xhr.GlobalXMLHttpRequest : xhr.supportsActiveX
+                                     ? function() { return new xhr.GlobalActiveXObject("MSXML2.XMLHTTP.3.0") } : false;
+    xhr.supportsCORS = xhr.supportsXHR && 'withCredentials' in (new sinon.xhr.GlobalXMLHttpRequest());
+
+    /*jsl:ignore*/
+    var unsafeHeaders = {
+        "Accept-Charset": true,
+        "Accept-Encoding": true,
+        "Connection": true,
+        "Content-Length": true,
+        "Cookie": true,
+        "Cookie2": true,
+        "Content-Transfer-Encoding": true,
+        "Date": true,
+        "Expect": true,
+        "Host": true,
+        "Keep-Alive": true,
+        "Referer": true,
+        "TE": true,
+        "Trailer": true,
+        "Transfer-Encoding": true,
+        "Upgrade": true,
+        "User-Agent": true,
+        "Via": true
+    };
+    /*jsl:end*/
+
+    function FakeXMLHttpRequest() {
+        this.readyState = FakeXMLHttpRequest.UNSENT;
+        this.requestHeaders = {};
+        this.requestBody = null;
+        this.status = 0;
+        this.statusText = "";
+        this.upload = new UploadProgress();
+        if (sinon.xhr.supportsCORS) {
+            this.withCredentials = false;
+        }
+
+
+        var xhr = this;
+        var events = ["loadstart", "load", "abort", "loadend"];
+
+        function addEventListener(eventName) {
+            xhr.addEventListener(eventName, function (event) {
+                var listener = xhr["on" + eventName];
+
+                if (listener && typeof listener == "function") {
+                    listener.call(this, event);
+                }
+            });
+        }
+
+        for (var i = events.length - 1; i >= 0; i--) {
+            addEventListener(events[i]);
+        }
+
+        if (typeof FakeXMLHttpRequest.onCreate == "function") {
+            FakeXMLHttpRequest.onCreate(this);
+        }
+    }
+
+    // An upload object is created for each
+    // FakeXMLHttpRequest and allows upload
+    // events to be simulated using uploadProgress
+    // and uploadError.
+    function UploadProgress() {
+        this.eventListeners = {
+            "progress": [],
+            "load": [],
+            "abort": [],
+            "error": []
+        }
+    }
+
+    UploadProgress.prototype.addEventListener = function(event, listener) {
+        this.eventListeners[event].push(listener);
+    };
+
+    UploadProgress.prototype.removeEventListener = function(event, listener) {
+        var listeners = this.eventListeners[event] || [];
+
+        for (var i = 0, l = listeners.length; i < l; ++i) {
+            if (listeners[i] == listener) {
+                return listeners.splice(i, 1);
+            }
+        }
+    };
+
+    UploadProgress.prototype.dispatchEvent = function(event) {
+        var listeners = this.eventListeners[event.type] || [];
+
+        for (var i = 0, listener; (listener = listeners[i]) != null; i++) {
+            listener(event);
+        }
+    };
+
+    function verifyState(xhr) {
+        if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
+            throw new Error("INVALID_STATE_ERR");
+        }
+
+        if (xhr.sendFlag) {
+            throw new Error("INVALID_STATE_ERR");
+        }
+    }
+
+    // filtering to enable a white-list version of Sinon FakeXhr,
+    // where whitelisted requests are passed through to real XHR
+    function each(collection, callback) {
+        if (!collection) return;
+        for (var i = 0, l = collection.length; i < l; i += 1) {
+            callback(collection[i]);
+        }
+    }
+    function some(collection, callback) {
+        for (var index = 0; index < collection.length; index++) {
+            if(callback(collection[index]) === true) return true;
+        }
+        return false;
+    }
+    // largest arity in XHR is 5 - XHR#open
+    var apply = function(obj,method,args) {
+        switch(args.length) {
+        case 0: return obj[method]();
+        case 1: return obj[method](args[0]);
+        case 2: return obj[method](args[0],args[1]);
+        case 3: return obj[method](args[0],args[1],args[2]);
+        case 4: return obj[method](args[0],args[1],args[2],args[3]);
+        case 5: return obj[method](args[0],args[1],args[2],args[3],args[4]);
+        }
+    };
+
+    FakeXMLHttpRequest.filters = [];
+    FakeXMLHttpRequest.addFilter = function(fn) {
+        this.filters.push(fn)
+    };
+    var IE6Re = /MSIE 6/;
+    FakeXMLHttpRequest.defake = function(fakeXhr,xhrArgs) {
+        var xhr = new sinon.xhr.workingXHR();
+        each(["open","setRequestHeader","send","abort","getResponseHeader",
+              "getAllResponseHeaders","addEventListener","overrideMimeType","removeEventListener"],
+             function(method) {
+                 fakeXhr[method] = function() {
+                   return apply(xhr,method,arguments);
+                 };
+             });
+
+        var copyAttrs = function(args) {
+            each(args, function(attr) {
+              try {
+                fakeXhr[attr] = xhr[attr]
+              } catch(e) {
+                if(!IE6Re.test(navigator.userAgent)) throw e;
+              }
+            });
+        };
+
+        var stateChange = function() {
+            fakeXhr.readyState = xhr.readyState;
+            if(xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) {
+                copyAttrs(["status","statusText"]);
+            }
+            if(xhr.readyState >= FakeXMLHttpRequest.LOADING) {
+                copyAttrs(["responseText"]);
+            }
+            if(xhr.readyState === FakeXMLHttpRequest.DONE) {
+                copyAttrs(["responseXML"]);
+            }
+            if(fakeXhr.onreadystatechange) fakeXhr.onreadystatechange.call(fakeXhr, { target: fakeXhr });
+        };
+        if(xhr.addEventListener) {
+          for(var event in fakeXhr.eventListeners) {
+              if(fakeXhr.eventListeners.hasOwnProperty(event)) {
+                  each(fakeXhr.eventListeners[event],function(handler) {
+                      xhr.addEventListener(event, handler);
+                  });
+              }
+          }
+          xhr.addEventListener("readystatechange",stateChange);
+        } else {
+          xhr.onreadystatechange = stateChange;
+        }
+        apply(xhr,"open",xhrArgs);
+    };
+    FakeXMLHttpRequest.useFilters = false;
+
+    function verifyRequestOpened(xhr) {
+        if (xhr.readyState != FakeXMLHttpRequest.OPENED) {
+            throw new Error("INVALID_STATE_ERR - " + xhr.readyState);
+        }
+    }
+
+    function verifyRequestSent(xhr) {
+        if (xhr.readyState == FakeXMLHttpRequest.DONE) {
+            throw new Error("Request done");
+        }
+    }
+
+    function verifyHeadersReceived(xhr) {
+        if (xhr.async && xhr.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) {
+            throw new Error("No headers received");
+        }
+    }
+
+    function verifyResponseBodyType(body) {
+        if (typeof body != "string") {
+            var error = new Error("Attempted to respond to fake XMLHttpRequest with " +
+                                 body + ", which is not a string.");
+            error.name = "InvalidBodyException";
+            throw error;
+        }
+    }
+
+    sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, {
+        async: true,
+
+        open: function open(method, url, async, username, password) {
+            this.method = method;
+            this.url = url;
+            this.async = typeof async == "boolean" ? async : true;
+            this.username = username;
+            this.password = password;
+            this.responseText = null;
+            this.responseXML = null;
+            this.requestHeaders = {};
+            this.sendFlag = false;
+            if(sinon.FakeXMLHttpRequest.useFilters === true) {
+                var xhrArgs = arguments;
+                var defake = some(FakeXMLHttpRequest.filters,function(filter) {
+                    return filter.apply(this,xhrArgs)
+                });
+                if (defake) {
+                  return sinon.FakeXMLHttpRequest.defake(this,arguments);
+                }
+            }
+            this.readyStateChange(FakeXMLHttpRequest.OPENED);
+        },
+
+        readyStateChange: function readyStateChange(state) {
+            this.readyState = state;
+
+            if (typeof this.onreadystatechange == "function") {
+                try {
+                    this.onreadystatechange();
+                } catch (e) {
+                    sinon.logError("Fake XHR onreadystatechange handler", e);
+                }
+            }
+
+            this.dispatchEvent(new sinon.Event("readystatechange"));
+
+            switch (this.readyState) {
+                case FakeXMLHttpRequest.DONE:
+                    this.dispatchEvent(new sinon.Event("load", false, false, this));
+                    this.dispatchEvent(new sinon.Event("loadend", false, false, this));
+                    this.upload.dispatchEvent(new sinon.Event("load", false, false, this));
+                    if (supportsProgress) {
+                        this.upload.dispatchEvent(new sinon.ProgressEvent('progress', {loaded: 100, total: 100}));
+                    }
+                    break;
+            }
+        },
+
+        setRequestHeader: function setRequestHeader(header, value) {
+            verifyState(this);
+
+            if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
+                throw new Error("Refused to set unsafe header \"" + header + "\"");
+            }
+
+            if (this.requestHeaders[header]) {
+                this.requestHeaders[header] += "," + value;
+            } else {
+                this.requestHeaders[header] = value;
+            }
+        },
+
+        // Helps testing
+        setResponseHeaders: function setResponseHeaders(headers) {
+            verifyRequestOpened(this);
+            this.responseHeaders = {};
+
+            for (var header in headers) {
+                if (headers.hasOwnProperty(header)) {
+                    this.responseHeaders[header] = headers[header];
+                }
+            }
+
+            if (this.async) {
+                this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
+            } else {
+                this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED;
+            }
+        },
+
+        // Currently treats ALL data as a DOMString (i.e. no Document)
+        send: function send(data) {
+            verifyState(this);
+
+            if (!/^(get|head)$/i.test(this.method)) {
+                if (this.requestHeaders["Content-Type"]) {
+                    var value = this.requestHeaders["Content-Type"].split(";");
+                    this.requestHeaders["Content-Type"] = value[0] + ";charset=utf-8";
+                } else {
+                    this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
+                }
+
+                this.requestBody = data;
+            }
+
+            this.errorFlag = false;
+            this.sendFlag = this.async;
+            this.readyStateChange(FakeXMLHttpRequest.OPENED);
+
+            if (typeof this.onSend == "function") {
+                this.onSend(this);
+            }
+
+            this.dispatchEvent(new sinon.Event("loadstart", false, false, this));
+        },
+
+        abort: function abort() {
+            this.aborted = true;
+            this.responseText = null;
+            this.errorFlag = true;
+            this.requestHeaders = {};
+
+            if (this.readyState > sinon.FakeXMLHttpRequest.UNSENT && this.sendFlag) {
+                this.readyStateChange(sinon.FakeXMLHttpRequest.DONE);
+                this.sendFlag = false;
+            }
+
+            this.readyState = sinon.FakeXMLHttpRequest.UNSENT;
+
+            this.dispatchEvent(new sinon.Event("abort", false, false, this));
+
+            this.upload.dispatchEvent(new sinon.Event("abort", false, false, this));
+
+            if (typeof this.onerror === "function") {
+                this.onerror();
+            }
+        },
+
+        getResponseHeader: function getResponseHeader(header) {
+            if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
+                return null;
+            }
+
+            if (/^Set-Cookie2?$/i.test(header)) {
+                return null;
+            }
+
+            header = header.toLowerCase();
+
+            for (var h in this.responseHeaders) {
+                if (h.toLowerCase() == header) {
+                    return this.responseHeaders[h];
+                }
+            }
+
+            return null;
+        },
+
+        getAllResponseHeaders: function getAllResponseHeaders() {
+            if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
+                return "";
+            }
+
+            var headers = "";
+
+            for (var header in this.responseHeaders) {
+                if (this.responseHeaders.hasOwnProperty(header) &&
+                    !/^Set-Cookie2?$/i.test(header)) {
+                    headers += header + ": " + this.responseHeaders[header] + "\r\n";
+                }
+            }
+
+            return headers;
+        },
+
+        setResponseBody: function setResponseBody(body) {
+            verifyRequestSent(this);
+            verifyHeadersReceived(this);
+            verifyResponseBodyType(body);
+
+            var chunkSize = this.chunkSize || 10;
+            var index = 0;
+            this.responseText = "";
+
+            do {
+                if (this.async) {
+                    this.readyStateChange(FakeXMLHttpRequest.LOADING);
+                }
+
+                this.responseText += body.substring(index, index + chunkSize);
+                index += chunkSize;
+            } while (index < body.length);
+
+            var type = this.getResponseHeader("Content-Type");
+
+            if (this.responseText &&
+                (!type || /(text\/xml)|(application\/xml)|(\+xml)/.test(type))) {
+                try {
+                    this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText);
+                } catch (e) {
+                    // Unable to parse XML - no biggie
+                }
+            }
+
+            if (this.async) {
+                this.readyStateChange(FakeXMLHttpRequest.DONE);
+            } else {
+                this.readyState = FakeXMLHttpRequest.DONE;
+            }
+        },
+
+        respond: function respond(status, headers, body) {
+            this.status = typeof status == "number" ? status : 200;
+            this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
+            this.setResponseHeaders(headers || {});
+            this.setResponseBody(body || "");
+        },
+
+        uploadProgress: function uploadProgress(progressEventRaw) {
+            if (supportsProgress) {
+                this.upload.dispatchEvent(new sinon.ProgressEvent("progress", progressEventRaw));
+            }
+        },
+
+        uploadError: function uploadError(error) {
+            if (supportsCustomEvent) {
+                this.upload.dispatchEvent(new sinon.CustomEvent("error", {"detail": error}));
+            }
+        }
+    });
+
+    sinon.extend(FakeXMLHttpRequest, {
+        UNSENT: 0,
+        OPENED: 1,
+        HEADERS_RECEIVED: 2,
+        LOADING: 3,
+        DONE: 4
+    });
+
+    // Borrowed from JSpec
+    FakeXMLHttpRequest.parseXML = function parseXML(text) {
+        var xmlDoc;
+
+        if (typeof DOMParser != "undefined") {
+            var parser = new DOMParser();
+            xmlDoc = parser.parseFromString(text, "text/xml");
+        } else {
+            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
+            xmlDoc.async = "false";
+            xmlDoc.loadXML(text);
+        }
+
+        return xmlDoc;
+    };
+
+    FakeXMLHttpRequest.statusCodes = {
+        100: "Continue",
+        101: "Switching Protocols",
+        200: "OK",
+        201: "Created",
+        202: "Accepted",
+        203: "Non-Authoritative Information",
+        204: "No Content",
+        205: "Reset Content",
+        206: "Partial Content",
+        300: "Multiple Choice",
+        301: "Moved Permanently",
+        302: "Found",
+        303: "See Other",
+        304: "Not Modified",
+        305: "Use Proxy",
+        307: "Temporary Redirect",
+        400: "Bad Request",
+        401: "Unauthorized",
+        402: "Payment Required",
+        403: "Forbidden",
+        404: "Not Found",
+        405: "Method Not Allowed",
+        406: "Not Acceptable",
+        407: "Proxy Authentication Required",
+        408: "Request Timeout",
+        409: "Conflict",
+        410: "Gone",
+        411: "Length Required",
+        412: "Precondition Failed",
+        413: "Request Entity Too Large",
+        414: "Request-URI Too Long",
+        415: "Unsupported Media Type",
+        416: "Requested Range Not Satisfiable",
+        417: "Expectation Failed",
+        422: "Unprocessable Entity",
+        500: "Internal Server Error",
+        501: "Not Implemented",
+        502: "Bad Gateway",
+        503: "Service Unavailable",
+        504: "Gateway Timeout",
+        505: "HTTP Version Not Supported"
+    };
+
+    sinon.useFakeXMLHttpRequest = function () {
+        sinon.FakeXMLHttpRequest.restore = function restore(keepOnCreate) {
+            if (xhr.supportsXHR) {
+                global.XMLHttpRequest = xhr.GlobalXMLHttpRequest;
+            }
+
+            if (xhr.supportsActiveX) {
+                global.ActiveXObject = xhr.GlobalActiveXObject;
+            }
+
+            delete sinon.FakeXMLHttpRequest.restore;
+
+            if (keepOnCreate !== true) {
+                delete sinon.FakeXMLHttpRequest.onCreate;
+            }
+        };
+        if (xhr.supportsXHR) {
+            global.XMLHttpRequest = sinon.FakeXMLHttpRequest;
+        }
+
+        if (xhr.supportsActiveX) {
+            global.ActiveXObject = function ActiveXObject(objId) {
+                if (objId == "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) {
+
+                    return new sinon.FakeXMLHttpRequest();
+                }
+
+                return new xhr.GlobalActiveXObject(objId);
+            };
+        }
+
+        return sinon.FakeXMLHttpRequest;
+    };
+
+    sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
+
+})((function(){ return typeof global === "object" ? global : this; })());
+
+if (typeof module !== 'undefined' && module.exports) {
+    module.exports = sinon;
+}
+
+/**
+ * @depend fake_xml_http_request.js
+ */
+/*jslint eqeqeq: false, onevar: false, regexp: false, plusplus: false*/
+/*global module, require, window*/
+/**
+ * The Sinon "server" mimics a web server that receives requests from
+ * sinon.FakeXMLHttpRequest and provides an API to respond to those requests,
+ * both synchronously and asynchronously. To respond synchronuously, canned
+ * answers have to be provided upfront.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+if (typeof sinon == "undefined") {
+    var sinon = {};
+}
+
+sinon.fakeServer = (function () {
+    var push = [].push;
+    function F() {}
+
+    function create(proto) {
+        F.prototype = proto;
+        return new F();
+    }
+
+    function responseArray(handler) {
+        var response = handler;
+
+        if (Object.prototype.toString.call(handler) != "[object Array]") {
+            response = [200, {}, handler];
+        }
+
+        if (typeof response[2] != "string") {
+            throw new TypeError("Fake server response body should be string, but was " +
+                                typeof response[2]);
+        }
+
+        return response;
+    }
+
+    var wloc = typeof window !== "undefined" ? window.location : {};
+    var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host);
+
+    function matchOne(response, reqMethod, reqUrl) {
+        var rmeth = response.method;
+        var matchMethod = !rmeth || rmeth.toLowerCase() == reqMethod.toLowerCase();
+        var url = response.url;
+        var matchUrl = !url || url == reqUrl || (typeof url.test == "function" && url.test(reqUrl));
+
+        return matchMethod && matchUrl;
+    }
+
+    function match(response, request) {
+        var requestUrl = request.url;
+
+        if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
+            requestUrl = requestUrl.replace(rCurrLoc, "");
+        }
+
+        if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
+            if (typeof response.response == "function") {
+                var ru = response.url;
+                var args = [request].concat(ru && typeof ru.exec == "function" ? ru.exec(requestUrl).slice(1) : []);
+                return response.response.apply(response, args);
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    return {
+        create: function () {
+            var server = create(this);
+            this.xhr = sinon.useFakeXMLHttpRequest();
+            server.requests = [];
+
+            this.xhr.onCreate = function (xhrObj) {
+                server.addRequest(xhrObj);
+            };
+
+            return server;
+        },
+
+        addRequest: function addRequest(xhrObj) {
+            var server = this;
+            push.call(this.requests, xhrObj);
+
+            xhrObj.onSend = function () {
+                server.handleRequest(this);
+
+                if (server.autoRespond && !server.responding) {
+                    setTimeout(function () {
+                        server.responding = false;
+                        server.respond();
+                    }, server.autoRespondAfter || 10);
+
+                    server.responding = true;
+                }
+            };
+        },
+
+        getHTTPMethod: function getHTTPMethod(request) {
+            if (this.fakeHTTPMethods && /post/i.test(request.method)) {
+                var matches = (request.requestBody || "").match(/_method=([^\b;]+)/);
+                return !!matches ? matches[1] : request.method;
+            }
+
+            return request.method;
+        },
+
+        handleRequest: function handleRequest(xhr) {
+            if (xhr.async) {
+                if (!this.queue) {
+                    this.queue = [];
+                }
+
+                push.call(this.queue, xhr);
+            } else {
+                this.processRequest(xhr);
+            }
+        },
+
+        log: function(response, request) {
+            var str;
+
+            str =  "Request:\n"  + sinon.format(request)  + "\n\n";
+            str += "Response:\n" + sinon.format(response) + "\n\n";
+
+            sinon.log(str);
+        },
+
+        respondWith: function respondWith(method, url, body) {
+            if (arguments.length == 1 && typeof method != "function") {
+                this.response = responseArray(method);
+                return;
+            }
+
+            if (!this.responses) { this.responses = []; }
+
+            if (arguments.length == 1) {
+                body = method;
+                url = method = null;
+            }
+
+            if (arguments.length == 2) {
+                body = url;
+                url = method;
+                method = null;
+            }
+
+            push.call(this.responses, {
+                method: method,
+                url: url,
+                response: typeof body == "function" ? body : responseArray(body)
+            });
+        },
+
+        respond: function respond() {
+            if (arguments.length > 0) this.respondWith.apply(this, arguments);
+            var queue = this.queue || [];
+            var requests = queue.splice(0, queue.length);
+            var request;
+
+            while(request = requests.shift()) {
+                this.processRequest(request);
+            }
+        },
+
+        processRequest: function processRequest(request) {
+            try {
+                if (request.aborted) {
+                    return;
+                }
+
+                var response = this.response || [404, {}, ""];
+
+                if (this.responses) {
+                    for (var l = this.responses.length, i = l - 1; i >= 0; i--) {
+                        if (match.call(this, this.responses[i], request)) {
+                            response = this.responses[i].response;
+                            break;
+                        }
+                    }
+                }
+
+                if (request.readyState != 4) {
+                    sinon.fakeServer.log(response, request);
+
+                    request.respond(response[0], response[1], response[2]);
+                }
+            } catch (e) {
+                sinon.logError("Fake server request processing", e);
+            }
+        },
+
+        restore: function restore() {
+            return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments);
+        }
+    };
+}());
+
+if (typeof module !== 'undefined' && module.exports) {
+    module.exports = sinon;
+}
+
+/**
+ * @depend fake_server.js
+ * @depend fake_timers.js
+ */
+/*jslint browser: true, eqeqeq: false, onevar: false*/
+/*global sinon*/
+/**
+ * Add-on for sinon.fakeServer that automatically handles a fake timer along with
+ * the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery
+ * 1.3.x, which does not use xhr object's onreadystatehandler at all - instead,
+ * it polls the object for completion with setInterval. Dispite the direct
+ * motivation, there is nothing jQuery-specific in this file, so it can be used
+ * in any environment where the ajax implementation depends on setInterval or
+ * setTimeout.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function () {
+    function Server() {}
+    Server.prototype = sinon.fakeServer;
+
+    sinon.fakeServerWithClock = new Server();
+
+    sinon.fakeServerWithClock.addRequest = function addRequest(xhr) {
+        if (xhr.async) {
+            if (typeof setTimeout.clock == "object") {
+                this.clock = setTimeout.clock;
+            } else {
+                this.clock = sinon.useFakeTimers();
+                this.resetClock = true;
+            }
+
+            if (!this.longestTimeout) {
+                var clockSetTimeout = this.clock.setTimeout;
+                var clockSetInterval = this.clock.setInterval;
+                var server = this;
+
+                this.clock.setTimeout = function (fn, timeout) {
+                    server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
+
+                    return clockSetTimeout.apply(this, arguments);
+                };
+
+                this.clock.setInterval = function (fn, timeout) {
+                    server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
+
+                    return clockSetInterval.apply(this, arguments);
+                };
+            }
+        }
+
+        return sinon.fakeServer.addRequest.call(this, xhr);
+    };
+
+    sinon.fakeServerWithClock.respond = function respond() {
+        var returnVal = sinon.fakeServer.respond.apply(this, arguments);
+
+        if (this.clock) {
+            this.clock.tick(this.longestTimeout || 0);
+            this.longestTimeout = 0;
+
+            if (this.resetClock) {
+                this.clock.restore();
+                this.resetClock = false;
+            }
+        }
+
+        return returnVal;
+    };
+
+    sinon.fakeServerWithClock.restore = function restore() {
+        if (this.clock) {
+            this.clock.restore();
+        }
+
+        return sinon.fakeServer.restore.apply(this, arguments);
+    };
+}());
+
+/**
+ * @depend ../sinon.js
+ * @depend collection.js
+ * @depend util/fake_timers.js
+ * @depend util/fake_server_with_clock.js
+ */
+/*jslint eqeqeq: false, onevar: false, plusplus: false*/
+/*global require, module*/
+/**
+ * Manages fake collections as well as fake utilities such as Sinon's
+ * timers and fake XHR implementation in one convenient object.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+if (typeof module !== "undefined" && module.exports && typeof require == "function") {
+    var sinon = require("../sinon");
+    sinon.extend(sinon, require("./util/fake_timers"));
+}
+
+(function () {
+    var push = [].push;
+
+    function exposeValue(sandbox, config, key, value) {
+        if (!value) {
+            return;
+        }
+
+        if (config.injectInto && !(key in config.injectInto)) {
+            config.injectInto[key] = value;
+            sandbox.injectedKeys.push(key);
+        } else {
+            push.call(sandbox.args, value);
+        }
+    }
+
+    function prepareSandboxFromConfig(config) {
+        var sandbox = sinon.create(sinon.sandbox);
+
+        if (config.useFakeServer) {
+            if (typeof config.useFakeServer == "object") {
+                sandbox.serverPrototype = config.useFakeServer;
+            }
+
+            sandbox.useFakeServer();
+        }
+
+        if (config.useFakeTimers) {
+            if (typeof config.useFakeTimers == "object") {
+                sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers);
+            } else {
+                sandbox.useFakeTimers();
+            }
+        }
+
+        return sandbox;
+    }
+
+    sinon.sandbox = sinon.extend(sinon.create(sinon.collection), {
+        useFakeTimers: function useFakeTimers() {
+            this.clock = sinon.useFakeTimers.apply(sinon, arguments);
+
+            return this.add(this.clock);
+        },
+
+        serverPrototype: sinon.fakeServer,
+
+        useFakeServer: function useFakeServer() {
+            var proto = this.serverPrototype || sinon.fakeServer;
+
+            if (!proto || !proto.create) {
+                return null;
+            }
+
+            this.server = proto.create();
+            return this.add(this.server);
+        },
+
+        inject: function (obj) {
+            sinon.collection.inject.call(this, obj);
+
+            if (this.clock) {
+                obj.clock = this.clock;
+            }
+
+            if (this.server) {
+                obj.server = this.server;
+                obj.requests = this.server.requests;
+            }
+
+            return obj;
+        },
+
+        restore: function () {
+            sinon.collection.restore.apply(this, arguments);
+            this.restoreContext();
+        },
+
+        restoreContext: function () {
+            if (this.injectedKeys) {
+                for (var i = 0, j = this.injectedKeys.length; i < j; i++) {
+                    delete this.injectInto[this.injectedKeys[i]];
+                }
+                this.injectedKeys = [];
+            }
+        },
+
+        create: function (config) {
+            if (!config) {
+                return sinon.create(sinon.sandbox);
+            }
+
+            var sandbox = prepareSandboxFromConfig(config);
+            sandbox.args = sandbox.args || [];
+            sandbox.injectedKeys = [];
+            sandbox.injectInto = config.injectInto;
+            var prop, value, exposed = sandbox.inject({});
+
+            if (config.properties) {
+                for (var i = 0, l = config.properties.length; i < l; i++) {
+                    prop = config.properties[i];
+                    value = exposed[prop] || prop == "sandbox" && sandbox;
+                    exposeValue(sandbox, config, prop, value);
+                }
+            } else {
+                exposeValue(sandbox, config, "sandbox", value);
+            }
+
+            return sandbox;
+        }
+    });
+
+    sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;
+
+    if (typeof define === "function" && define.amd) {
+        define(["module"], function(module) { module.exports = sinon.sandbox; });
+    } else if (typeof module !== 'undefined' && module.exports) {
+        module.exports = sinon.sandbox;
+    }
+}());
+
+/**
+ * @depend ../sinon.js
+ * @depend stub.js
+ * @depend mock.js
+ * @depend sandbox.js
+ */
+/*jslint eqeqeq: false, onevar: false, forin: true, plusplus: false*/
+/*global module, require, sinon*/
+/**
+ * Test function, sandboxes fakes
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    function test(callback) {
+        var type = typeof callback;
+
+        if (type != "function") {
+            throw new TypeError("sinon.test needs to wrap a test function, got " + type);
+        }
+
+        function sinonSandboxedTest() {
+            var config = sinon.getConfig(sinon.config);
+            config.injectInto = config.injectIntoThis && this || config.injectInto;
+            var sandbox = sinon.sandbox.create(config);
+            var exception, result;
+            var args = Array.prototype.slice.call(arguments).concat(sandbox.args);
+
+            try {
+                result = callback.apply(this, args);
+            } catch (e) {
+                exception = e;
+            }
+
+            if (typeof exception !== "undefined") {
+                sandbox.restore();
+                throw exception;
+            }
+            else {
+                sandbox.verifyAndRestore();
+            }
+
+            return result;
+        };
+
+        if (callback.length) {
+            return function sinonAsyncSandboxedTest(callback) {
+                return sinonSandboxedTest.apply(this, arguments);
+            };
+        }
+
+        return sinonSandboxedTest;
+    }
+
+    test.config = {
+        injectIntoThis: true,
+        injectInto: null,
+        properties: ["spy", "stub", "mock", "clock", "server", "requests"],
+        useFakeTimers: true,
+        useFakeServer: true
+    };
+
+    sinon.test = test;
+
+    if (typeof define === "function" && define.amd) {
+        define(["module"], function(module) { module.exports = test; });
+    } else if (commonJSModule) {
+        module.exports = test;
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend ../sinon.js
+ * @depend test.js
+ */
+/*jslint eqeqeq: false, onevar: false, eqeqeq: false*/
+/*global module, require, sinon*/
+/**
+ * Test case, sandboxes all test functions
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon || !Object.prototype.hasOwnProperty) {
+        return;
+    }
+
+    function createTest(property, setUp, tearDown) {
+        return function () {
+            if (setUp) {
+                setUp.apply(this, arguments);
+            }
+
+            var exception, result;
+
+            try {
+                result = property.apply(this, arguments);
+            } catch (e) {
+                exception = e;
+            }
+
+            if (tearDown) {
+                tearDown.apply(this, arguments);
+            }
+
+            if (exception) {
+                throw exception;
+            }
+
+            return result;
+        };
+    }
+
+    function testCase(tests, prefix) {
+        /*jsl:ignore*/
+        if (!tests || typeof tests != "object") {
+            throw new TypeError("sinon.testCase needs an object with test functions");
+        }
+        /*jsl:end*/
+
+        prefix = prefix || "test";
+        var rPrefix = new RegExp("^" + prefix);
+        var methods = {}, testName, property, method;
+        var setUp = tests.setUp;
+        var tearDown = tests.tearDown;
+
+        for (testName in tests) {
+            if (tests.hasOwnProperty(testName)) {
+                property = tests[testName];
+
+                if (/^(setUp|tearDown)$/.test(testName)) {
+                    continue;
+                }
+
+                if (typeof property == "function" && rPrefix.test(testName)) {
+                    method = property;
+
+                    if (setUp || tearDown) {
+                        method = createTest(property, setUp, tearDown);
+                    }
+
+                    methods[testName] = sinon.test(method);
+                } else {
+                    methods[testName] = tests[testName];
+                }
+            }
+        }
+
+        return methods;
+    }
+
+    sinon.testCase = testCase;
+
+    if (typeof define === "function" && define.amd) {
+        define(["module"], function(module) { module.exports = testCase; });
+    } else if (commonJSModule) {
+        module.exports = testCase;
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend ../sinon.js
+ * @depend stub.js
+ */
+/*jslint eqeqeq: false, onevar: false, nomen: false, plusplus: false*/
+/*global module, require, sinon*/
+/**
+ * Assertions matching the test spy retrieval interface.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon, global) {
+    var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function";
+    var slice = Array.prototype.slice;
+    var assert;
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    function verifyIsStub() {
+        var method;
+
+        for (var i = 0, l = arguments.length; i < l; ++i) {
+            method = arguments[i];
+
+            if (!method) {
+                assert.fail("fake is not a spy");
+            }
+
+            if (typeof method != "function") {
+                assert.fail(method + " is not a function");
+            }
+
+            if (typeof method.getCall != "function") {
+                assert.fail(method + " is not stubbed");
+            }
+        }
+    }
+
+    function failAssertion(object, msg) {
+        object = object || global;
+        var failMethod = object.fail || assert.fail;
+        failMethod.call(object, msg);
+    }
+
+    function mirrorPropAsAssertion(name, method, message) {
+        if (arguments.length == 2) {
+            message = method;
+            method = name;
+        }
+
+        assert[name] = function (fake) {
+            verifyIsStub(fake);
+
+            var args = slice.call(arguments, 1);
+            var failed = false;
+
+            if (typeof method == "function") {
+                failed = !method(fake);
+            } else {
+                failed = typeof fake[method] == "function" ?
+                    !fake[method].apply(fake, args) : !fake[method];
+            }
+
+            if (failed) {
+                failAssertion(this, fake.printf.apply(fake, [message].concat(args)));
+            } else {
+                assert.pass(name);
+            }
+        };
+    }
+
+    function exposedName(prefix, prop) {
+        return !prefix || /^fail/.test(prop) ? prop :
+            prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
+    }
+
+    assert = {
+        failException: "AssertError",
+
+        fail: function fail(message) {
+            var error = new Error(message);
+            error.name = this.failException || assert.failException;
+
+            throw error;
+        },
+
+        pass: function pass(assertion) {},
+
+        callOrder: function assertCallOrder() {
+            verifyIsStub.apply(null, arguments);
+            var expected = "", actual = "";
+
+            if (!sinon.calledInOrder(arguments)) {
+                try {
+                    expected = [].join.call(arguments, ", ");
+                    var calls = slice.call(arguments);
+                    var i = calls.length;
+                    while (i) {
+                        if (!calls[--i].called) {
+                            calls.splice(i, 1);
+                        }
+                    }
+                    actual = sinon.orderByFirstCall(calls).join(", ");
+                } catch (e) {
+                    // If this fails, we'll just fall back to the blank string
+                }
+
+                failAssertion(this, "expected " + expected + " to be " +
+                              "called in order but were called as " + actual);
+            } else {
+                assert.pass("callOrder");
+            }
+        },
+
+        callCount: function assertCallCount(method, count) {
+            verifyIsStub(method);
+
+            if (method.callCount != count) {
+                var msg = "expected %n to be called " + sinon.timesInWords(count) +
+                    " but was called %c%C";
+                failAssertion(this, method.printf(msg));
+            } else {
+                assert.pass("callCount");
+            }
+        },
+
+        expose: function expose(target, options) {
+            if (!target) {
+                throw new TypeError("target is null or undefined");
+            }
+
+            var o = options || {};
+            var prefix = typeof o.prefix == "undefined" && "assert" || o.prefix;
+            var includeFail = typeof o.includeFail == "undefined" || !!o.includeFail;
+
+            for (var method in this) {
+                if (method != "export" && (includeFail || !/^(fail)/.test(method))) {
+                    target[exposedName(prefix, method)] = this[method];
+                }
+            }
+
+            return target;
+        },
+
+        match: function match(actual, expectation) {
+            var matcher = sinon.match(expectation);
+            if (matcher.test(actual)) {
+                assert.pass("match");
+            } else {
+                var formatted = [
+                    "expected value to match",
+                    "    expected = " + sinon.format(expectation),
+                    "    actual = " + sinon.format(actual)
+                ]
+                failAssertion(this, formatted.join("\n"));
+            }
+        }
+    };
+
+    mirrorPropAsAssertion("called", "expected %n to have been called at least once but was never called");
+    mirrorPropAsAssertion("notCalled", function (spy) { return !spy.called; },
+                          "expected %n to not have been called but was called %c%C");
+    mirrorPropAsAssertion("calledOnce", "expected %n to be called once but was called %c%C");
+    mirrorPropAsAssertion("calledTwice", "expected %n to be called twice but was called %c%C");
+    mirrorPropAsAssertion("calledThrice", "expected %n to be called thrice but was called %c%C");
+    mirrorPropAsAssertion("calledOn", "expected %n to be called with %1 as this but was called with %t");
+    mirrorPropAsAssertion("alwaysCalledOn", "expected %n to always be called with %1 as this but was called with %t");
+    mirrorPropAsAssertion("calledWithNew", "expected %n to be called with new");
+    mirrorPropAsAssertion("alwaysCalledWithNew", "expected %n to always be called with new");
+    mirrorPropAsAssertion("calledWith", "expected %n to be called with arguments %*%C");
+    mirrorPropAsAssertion("calledWithMatch", "expected %n to be called with match %*%C");
+    mirrorPropAsAssertion("alwaysCalledWith", "expected %n to always be called with arguments %*%C");
+    mirrorPropAsAssertion("alwaysCalledWithMatch", "expected %n to always be called with match %*%C");
+    mirrorPropAsAssertion("calledWithExactly", "expected %n to be called with exact arguments %*%C");
+    mirrorPropAsAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*%C");
+    mirrorPropAsAssertion("neverCalledWith", "expected %n to never be called with arguments %*%C");
+    mirrorPropAsAssertion("neverCalledWithMatch", "expected %n to never be called with match %*%C");
+    mirrorPropAsAssertion("threw", "%n did not throw exception%C");
+    mirrorPropAsAssertion("alwaysThrew", "%n did not always throw exception%C");
+
+    sinon.assert = assert;
+
+    if (typeof define === "function" && define.amd) {
+        define(["module"], function(module) { module.exports = assert; });
+    } else if (commonJSModule) {
+        module.exports = assert;
+    }
+}(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : (typeof self != "undefined") ? self : global));
+
+/**
+ * @depend ../../sinon.js
+ * @depend event.js
+ */
+/*jslint eqeqeq: false, onevar: false*/
+/*global sinon, module, require, XDomainRequest*/
+/**
+ * Fake XDomainRequest object
+ */
+
+if (typeof sinon == "undefined") {
+    this.sinon = {};
+}
+sinon.xdr = { XDomainRequest: this.XDomainRequest };
+
+// wrapper for global
+(function (global) {
+    var xdr = sinon.xdr;
+    xdr.GlobalXDomainRequest = global.XDomainRequest;
+    xdr.supportsXDR = typeof xdr.GlobalXDomainRequest != "undefined";
+    xdr.workingXDR = xdr.supportsXDR ? xdr.GlobalXDomainRequest :  false;
+
+    function FakeXDomainRequest() {
+        this.readyState = FakeXDomainRequest.UNSENT;
+        this.requestBody = null;
+        this.requestHeaders = {};
+        this.status = 0;
+        this.timeout = null;
+
+        if (typeof FakeXDomainRequest.onCreate == "function") {
+            FakeXDomainRequest.onCreate(this);
+        }
+    }
+
+    function verifyState(xdr) {
+        if (xdr.readyState !== FakeXDomainRequest.OPENED) {
+            throw new Error("INVALID_STATE_ERR");
+        }
+
+        if (xdr.sendFlag) {
+            throw new Error("INVALID_STATE_ERR");
+        }
+    }
+
+    function verifyRequestSent(xdr) {
+        if (xdr.readyState == FakeXDomainRequest.UNSENT) {
+            throw new Error("Request not sent");
+        }
+        if (xdr.readyState == FakeXDomainRequest.DONE) {
+            throw new Error("Request done");
+        }
+    }
+
+    function verifyResponseBodyType(body) {
+        if (typeof body != "string") {
+            var error = new Error("Attempted to respond to fake XDomainRequest with " +
+                                  body + ", which is not a string.");
+            error.name = "InvalidBodyException";
+            throw error;
+        }
+    }
+
+    sinon.extend(FakeXDomainRequest.prototype, sinon.EventTarget, {
+        open: function open(method, url) {
+            this.method = method;
+            this.url = url;
+
+            this.responseText = null;
+            this.sendFlag = false;
+
+            this.readyStateChange(FakeXDomainRequest.OPENED);
+        },
+
+        readyStateChange: function readyStateChange(state) {
+            this.readyState = state;
+            var eventName = '';
+            switch (this.readyState) {
+            case FakeXDomainRequest.UNSENT:
+                break;
+            case FakeXDomainRequest.OPENED:
+                break;
+            case FakeXDomainRequest.LOADING:
+                if (this.sendFlag){
+                    //raise the progress event
+                    eventName = 'onprogress';
+                }
+                break;
+            case FakeXDomainRequest.DONE:
+                if (this.isTimeout){
+                    eventName = 'ontimeout'
+                }
+                else if (this.errorFlag || (this.status < 200 || this.status > 299)) {
+                    eventName = 'onerror';
+                }
+                else {
+                    eventName = 'onload'
+                }
+                break;
+            }
+
+            // raising event (if defined)
+            if (eventName) {
+                if (typeof this[eventName] == "function") {
+                    try {
+                        this[eventName]();
+                    } catch (e) {
+                        sinon.logError("Fake XHR " + eventName + " handler", e);
+                    }
+                }
+            }
+        },
+
+        send: function send(data) {
+            verifyState(this);
+
+            if (!/^(get|head)$/i.test(this.method)) {
+                this.requestBody = data;
+            }
+            this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
+
+            this.errorFlag = false;
+            this.sendFlag = true;
+            this.readyStateChange(FakeXDomainRequest.OPENED);
+
+            if (typeof this.onSend == "function") {
+                this.onSend(this);
+            }
+        },
+
+        abort: function abort() {
+            this.aborted = true;
+            this.responseText = null;
+            this.errorFlag = true;
+
+            if (this.readyState > sinon.FakeXDomainRequest.UNSENT && this.sendFlag) {
+                this.readyStateChange(sinon.FakeXDomainRequest.DONE);
+                this.sendFlag = false;
+            }
+        },
+
+        setResponseBody: function setResponseBody(body) {
+            verifyRequestSent(this);
+            verifyResponseBodyType(body);
+
+            var chunkSize = this.chunkSize || 10;
+            var index = 0;
+            this.responseText = "";
+
+            do {
+                this.readyStateChange(FakeXDomainRequest.LOADING);
+                this.responseText += body.substring(index, index + chunkSize);
+                index += chunkSize;
+            } while (index < body.length);
+
+            this.readyStateChange(FakeXDomainRequest.DONE);
+        },
+
+        respond: function respond(status, contentType, body) {
+            // content-type ignored, since XDomainRequest does not carry this
+            // we keep the same syntax for respond(...) as for FakeXMLHttpRequest to ease
+            // test integration across browsers
+            this.status = typeof status == "number" ? status : 200;
+            this.setResponseBody(body || "");
+        },
+
+        simulatetimeout: function(){
+            this.status = 0;
+            this.isTimeout = true;
+            // Access to this should actually throw an error
+            this.responseText = undefined;
+            this.readyStateChange(FakeXDomainRequest.DONE);
+        }
+    });
+
+    sinon.extend(FakeXDomainRequest, {
+        UNSENT: 0,
+        OPENED: 1,
+        LOADING: 3,
+        DONE: 4
+    });
+
+    sinon.useFakeXDomainRequest = function () {
+        sinon.FakeXDomainRequest.restore = function restore(keepOnCreate) {
+            if (xdr.supportsXDR) {
+                global.XDomainRequest = xdr.GlobalXDomainRequest;
+            }
+
+            delete sinon.FakeXDomainRequest.restore;
+
+            if (keepOnCreate !== true) {
+                delete sinon.FakeXDomainRequest.onCreate;
+            }
+        };
+        if (xdr.supportsXDR) {
+            global.XDomainRequest = sinon.FakeXDomainRequest;
+        }
+        return sinon.FakeXDomainRequest;
+    };
+
+    sinon.FakeXDomainRequest = FakeXDomainRequest;
+})(this);
+
+if (typeof module == "object" && typeof require == "function") {
+    module.exports = sinon;
+}
+
+return sinon;}.call(typeof window != 'undefined' && window || {}));
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/sinon-qunit-1.0.0.js b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/sinon-qunit-1.0.0.js
new file mode 100644
index 0000000..c26232f
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/sinon-qunit-1.0.0.js
@@ -0,0 +1,62 @@
+/**
+ * sinon-qunit 1.0.0, 2010/12/09
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ *
+ * (The BSD License)
+ * 
+ * Copyright (c) 2010-2011, Christian Johansen, christian@cjohansen.no
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright notice,
+ *       this list of conditions and the following disclaimer in the documentation
+ *       and/or other materials provided with the distribution.
+ *     * Neither the name of Christian Johansen nor the names of his contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*global sinon, QUnit, test*/
+sinon.assert.fail = function (msg) {
+    QUnit.ok(false, msg);
+};
+
+sinon.assert.pass = function (assertion) {
+    QUnit.ok(true, assertion);
+};
+
+sinon.config = {
+    injectIntoThis: true,
+    injectInto: null,
+    properties: ["spy", "stub", "mock", "clock", "sandbox"],
+    useFakeTimers: true,
+    useFakeServer: false
+};
+
+(function (global) {
+    var qTest = QUnit.test;
+    
+    QUnit.test = global.test = function (testName, expected, callback, async) {
+        if (arguments.length === 2) {
+            callback = expected;
+            expected = null;
+        }
+
+        return qTest(testName, expected, sinon.test(callback), async);
+    };
+}(this));
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/sinon-qunit.js b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/sinon-qunit.js
new file mode 100644
index 0000000..c26232f
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/sinon-qunit.js
@@ -0,0 +1,62 @@
+/**
+ * sinon-qunit 1.0.0, 2010/12/09
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ *
+ * (The BSD License)
+ * 
+ * Copyright (c) 2010-2011, Christian Johansen, christian@cjohansen.no
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright notice,
+ *       this list of conditions and the following disclaimer in the documentation
+ *       and/or other materials provided with the distribution.
+ *     * Neither the name of Christian Johansen nor the names of his contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*global sinon, QUnit, test*/
+sinon.assert.fail = function (msg) {
+    QUnit.ok(false, msg);
+};
+
+sinon.assert.pass = function (assertion) {
+    QUnit.ok(true, assertion);
+};
+
+sinon.config = {
+    injectIntoThis: true,
+    injectInto: null,
+    properties: ["spy", "stub", "mock", "clock", "sandbox"],
+    useFakeTimers: true,
+    useFakeServer: false
+};
+
+(function (global) {
+    var qTest = QUnit.test;
+    
+    QUnit.test = global.test = function (testName, expected, callback, async) {
+        if (arguments.length === 2) {
+            callback = expected;
+            expected = null;
+        }
+
+        return qTest(testName, expected, sinon.test(callback), async);
+    };
+}(this));
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-1.11.1.html b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-1.11.1.html
new file mode 100644
index 0000000..23de894
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-1.11.1.html
@@ -0,0 +1,35 @@
+<html>
+<head>
+  <title>jQuery-Mask-Plugin UnitTesting</title>
+  <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.11.0.css" type="text/css" media="all">
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+</head>
+<body>
+  <h1 id="qunit-header">jQuery-Mask-Plugin QUnit Tests</h1>
+  <h2 id="qunit-banner"></h2>
+  <div id="qunit-testrunner-toolbar"></div>
+  <h2 id="qunit-userAgent"></h2>
+  <ol id="qunit-tests"></ol>
+  <div id="qunit-fixture">test markup, will be hidden</div>
+
+  <!-- testing area -->
+  <input class="simple-field" type="text" />
+  <input class="simple-field-data-mask" type="text" data-mask="00/00/0000"/>
+  <input class="simple-field-data-mask-selectonfocus" type="text" data-mask="00/00/0000" data-mask-selectonfocus="true" />
+  <input class="simple-field-data-mask-reverse" type="text" data-mask="#.##0,00" data-mask-reverse="true" data-mask-maxlength="false"/>
+  <input class="simple-field-data-mask-clearifnotmatch" data-mask="000" type="text" data-mask-clearifnotmatch="true" />
+  <input class="simple-field-data-mask-clearifnotmatch-and-optional-mask" data-mask="009" type="text" data-mask-clearifnotmatch="true" />
+  <div class="simple-div"></div>
+  <div id="container-dy-non-inputs"> </div>
+  <!--/ testing area-->
+
+  <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
+  <script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.11.0.js"></script>
+
+  <script type="text/javascript" src="./sinon-1.10.3.js"></script>
+  <script type="text/javascript" src="./sinon-qunit-1.0.0.js"></script>
+
+  <script type="text/javascript" src="../src/jquery.mask.js"></script>
+  <script type="text/javascript" src="jquery.mask.test.js"></script>
+</body>
+</html>
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-1.7.2.html b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-1.7.2.html
new file mode 100644
index 0000000..e50d43a
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-1.7.2.html
@@ -0,0 +1,35 @@
+<html>
+<head>
+  <title>jQuery-Mask-Plugin UnitTesting</title>
+  <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.11.0.css" type="text/css" media="all">
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+</head>
+<body>
+  <h1 id="qunit-header">jQuery-Mask-Plugin QUnit Tests</h1>
+  <h2 id="qunit-banner"></h2>
+  <div id="qunit-testrunner-toolbar"></div>
+  <h2 id="qunit-userAgent"></h2>
+  <ol id="qunit-tests"></ol>
+  <div id="qunit-fixture">test markup, will be hidden</div>
+
+  <!-- testing area -->
+  <input class="simple-field" type="text" />
+  <input class="simple-field-data-mask" type="text" data-mask="00/00/0000"/>
+  <input class="simple-field-data-mask-selectonfocus" type="text" data-mask="00/00/0000" data-mask-selectonfocus="true" />
+  <input class="simple-field-data-mask-reverse" type="text" data-mask="#.##0,00" data-mask-reverse="true" data-mask-maxlength="false"/>
+  <input class="simple-field-data-mask-clearifnotmatch" data-mask="000" type="text" data-mask-clearifnotmatch="true" />
+  <input class="simple-field-data-mask-clearifnotmatch-and-optional-mask" data-mask="009" type="text" data-mask-clearifnotmatch="true" />
+  <div class="simple-div"></div>
+  <div id="container-dy-non-inputs"> </div>
+  <!--/ testing area-->
+
+  <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
+  <script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.11.0.js"></script>
+
+  <script type="text/javascript" src="./sinon-1.10.3.js"></script>
+  <script type="text/javascript" src="./sinon-qunit-1.0.0.js"></script>
+
+  <script type="text/javascript" src="../src/jquery.mask.js"></script>
+  <script type="text/javascript" src="jquery.mask.test.js"></script>
+</body>
+</html>
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-1.8.3.html b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-1.8.3.html
new file mode 100644
index 0000000..c037820
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-1.8.3.html
@@ -0,0 +1,35 @@
+<html>
+<head>
+  <title>jQuery-Mask-Plugin UnitTesting</title>
+  <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.11.0.css" type="text/css" media="all">
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+</head>
+<body>
+  <h1 id="qunit-header">jQuery-Mask-Plugin QUnit Tests</h1>
+  <h2 id="qunit-banner"></h2>
+  <div id="qunit-testrunner-toolbar"></div>
+  <h2 id="qunit-userAgent"></h2>
+  <ol id="qunit-tests"></ol>
+  <div id="qunit-fixture">test markup, will be hidden</div>
+
+  <!-- testing area -->
+  <input class="simple-field" type="text" />
+  <input class="simple-field-data-mask" type="text" data-mask="00/00/0000"/>
+  <input class="simple-field-data-mask-selectonfocus" type="text" data-mask="00/00/0000" data-mask-selectonfocus="true" />
+  <input class="simple-field-data-mask-reverse" type="text" data-mask="#.##0,00" data-mask-reverse="true" data-mask-maxlength="false"/>
+  <input class="simple-field-data-mask-clearifnotmatch" data-mask="000" type="text" data-mask-clearifnotmatch="true" />
+  <input class="simple-field-data-mask-clearifnotmatch-and-optional-mask" data-mask="009" type="text" data-mask-clearifnotmatch="true" />
+  <div class="simple-div"></div>
+  <div id="container-dy-non-inputs"> </div>
+  <!--/ testing area-->
+
+  <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
+  <script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.11.0.js"></script>
+
+  <script type="text/javascript" src="./sinon-1.10.3.js"></script>
+  <script type="text/javascript" src="./sinon-qunit-1.0.0.js"></script>
+
+  <script type="text/javascript" src="../src/jquery.mask.js"></script>
+  <script type="text/javascript" src="jquery.mask.test.js"></script>
+</body>
+</html>
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-1.9.1.html b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-1.9.1.html
new file mode 100644
index 0000000..6576585
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-1.9.1.html
@@ -0,0 +1,35 @@
+<html>
+<head>
+  <title>jQuery-Mask-Plugin UnitTesting</title>
+  <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.11.0.css" type="text/css" media="all">
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+</head>
+<body>
+  <h1 id="qunit-header">jQuery-Mask-Plugin QUnit Tests</h1>
+  <h2 id="qunit-banner"></h2>
+  <div id="qunit-testrunner-toolbar"></div>
+  <h2 id="qunit-userAgent"></h2>
+  <ol id="qunit-tests"></ol>
+  <div id="qunit-fixture">test markup, will be hidden</div>
+
+  <!-- testing area -->
+  <input class="simple-field" type="text" />
+  <input class="simple-field-data-mask" type="text" data-mask="00/00/0000"/>
+  <input class="simple-field-data-mask-selectonfocus" type="text" data-mask="00/00/0000" data-mask-selectonfocus="true" />
+  <input class="simple-field-data-mask-reverse" type="text" data-mask="#.##0,00" data-mask-reverse="true" data-mask-maxlength="false"/>
+  <input class="simple-field-data-mask-clearifnotmatch" data-mask="000" type="text" data-mask-clearifnotmatch="true" />
+  <input class="simple-field-data-mask-clearifnotmatch-and-optional-mask" data-mask="009" type="text" data-mask-clearifnotmatch="true" />
+  <div class="simple-div"></div>
+  <div id="container-dy-non-inputs"> </div>
+  <!--/ testing area-->
+
+  <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
+  <script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.11.0.js"></script>
+
+  <script type="text/javascript" src="./sinon-1.10.3.js"></script>
+  <script type="text/javascript" src="./sinon-qunit-1.0.0.js"></script>
+
+  <script type="text/javascript" src="../src/jquery.mask.js"></script>
+  <script type="text/javascript" src="jquery.mask.test.js"></script>
+</body>
+</html>
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-2.1.1.html b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-2.1.1.html
new file mode 100644
index 0000000..052517a
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-2.1.1.html
@@ -0,0 +1,35 @@
+<html>
+<head>
+  <title>jQuery-Mask-Plugin UnitTesting</title>
+  <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.11.0.css" type="text/css" media="all">
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+</head>
+<body>
+  <h1 id="qunit-header">jQuery-Mask-Plugin QUnit Tests</h1>
+  <h2 id="qunit-banner"></h2>
+  <div id="qunit-testrunner-toolbar"></div>
+  <h2 id="qunit-userAgent"></h2>
+  <ol id="qunit-tests"></ol>
+  <div id="qunit-fixture">test markup, will be hidden</div>
+
+  <!-- testing area -->
+  <input class="simple-field" type="text" />
+  <input class="simple-field-data-mask" type="text" data-mask="00/00/0000"/>
+  <input class="simple-field-data-mask-selectonfocus" type="text" data-mask="00/00/0000" data-mask-selectonfocus="true" />
+  <input class="simple-field-data-mask-reverse" type="text" data-mask="#.##0,00" data-mask-reverse="true" data-mask-maxlength="false"/>
+  <input class="simple-field-data-mask-clearifnotmatch" data-mask="000" type="text" data-mask-clearifnotmatch="true" />
+  <input class="simple-field-data-mask-clearifnotmatch-and-optional-mask" data-mask="009" type="text" data-mask-clearifnotmatch="true" />
+  <div class="simple-div"></div>
+  <div id="container-dy-non-inputs"> </div>
+  <!--/ testing area-->
+
+  <script type="text/javascript" src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
+  <script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.11.0.js"></script>
+  
+  <script type="text/javascript" src="./sinon-1.10.3.js"></script>
+  <script type="text/javascript" src="./sinon-qunit-1.0.0.js"></script>
+
+  <script type="text/javascript" src="../src/jquery.mask.js"></script>
+  <script type="text/javascript" src="jquery.mask.test.js"></script>
+</body>
+</html>
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-3.0.0.html b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-3.0.0.html
new file mode 100644
index 0000000..283b5cd
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-jquery-3.0.0.html
@@ -0,0 +1,35 @@
+<html>
+<head>
+  <title>jQuery-Mask-Plugin UnitTesting</title>
+  <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.11.0.css" type="text/css" media="all">
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+</head>
+<body>
+  <h1 id="qunit-header">jQuery-Mask-Plugin QUnit Tests</h1>
+  <h2 id="qunit-banner"></h2>
+  <div id="qunit-testrunner-toolbar"></div>
+  <h2 id="qunit-userAgent"></h2>
+  <ol id="qunit-tests"></ol>
+  <div id="qunit-fixture">test markup, will be hidden</div>
+
+  <!-- testing area -->
+  <input class="simple-field" type="text" />
+  <input class="simple-field-data-mask" type="text" data-mask="00/00/0000"/>
+  <input class="simple-field-data-mask-selectonfocus" type="text" data-mask="00/00/0000" data-mask-selectonfocus="true" />
+  <input class="simple-field-data-mask-reverse" type="text" data-mask="#.##0,00" data-mask-reverse="true" data-mask-maxlength="false"/>
+  <input class="simple-field-data-mask-clearifnotmatch" data-mask="000" type="text" data-mask-clearifnotmatch="true" />
+  <input class="simple-field-data-mask-clearifnotmatch-and-optional-mask" data-mask="009" type="text" data-mask-clearifnotmatch="true" />
+  <div class="simple-div"></div>
+  <div id="container-dy-non-inputs"> </div>
+  <!--/ testing area-->
+
+  <script type="text/javascript" src="http://code.jquery.com/jquery-3.0.0.min.js"></script>
+  <script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.11.0.js"></script>
+  
+  <script type="text/javascript" src="./sinon-1.10.3.js"></script>
+  <script type="text/javascript" src="./sinon-qunit-1.0.0.js"></script>
+
+  <script type="text/javascript" src="../src/jquery.mask.js"></script>
+  <script type="text/javascript" src="jquery.mask.test.js"></script>
+</body>
+</html>
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-zepto.html b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-zepto.html
new file mode 100644
index 0000000..abb5932
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/test-for-zepto.html
@@ -0,0 +1,36 @@
+<html>
+<head>
+  <title>Zepto-Mask-Plugin UnitTesting</title>  
+  <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.11.0.css" type="text/css" media="all">
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
+</head>
+<body>
+  <h1 id="qunit-header">Zepto-Mask-Plugin QUnit Tests</h1>
+  <h2 id="qunit-banner"></h2>
+  <div id="qunit-testrunner-toolbar"></div>
+  <h2 id="qunit-userAgent"></h2>
+  <ol id="qunit-tests"></ol>
+  <div id="qunit-fixture">test markup, will be hidden</div>
+
+  <!-- testing area -->
+  <input class="simple-field" type="text" />
+  <input class="simple-field-data-mask" type="text" data-mask="00/00/0000"/>
+  <input class="simple-field-data-mask-selectonfocus" type="text" data-mask="00/00/0000" data-mask-selectonfocus="true" />
+  <input class="simple-field-data-mask-reverse" type="text" data-mask="#.##0,00" data-mask-reverse="true" data-mask-maxlength="false"/>
+  <input class="simple-field-data-mask-clearifnotmatch" data-mask="000" type="text" data-mask-clearifnotmatch="true" />
+  <input class="simple-field-data-mask-clearifnotmatch-and-optional-mask" data-mask="009" type="text" data-mask-clearifnotmatch="true" />
+  <div class="simple-div"></div>
+  <div id="container-dy-non-inputs"> </div>
+  <!--/ testing area-->
+
+  <script type="text/javascript" src="zepto/zepto.min.js"></script>
+  <script type="text/javascript" src="zepto/data.js"></script>
+  <script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.11.0.js"></script>
+
+  <script type="text/javascript" src="./sinon-1.10.3.js"></script>
+  <script type="text/javascript" src="./sinon-qunit-1.0.0.js"></script>
+
+  <script type="text/javascript" src="../src/jquery.mask.js"></script>
+  <script type="text/javascript" src="jquery.mask.test.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/zepto/data.js b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/zepto/data.js
new file mode 100644
index 0000000..8a9f9db
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/zepto/data.js
@@ -0,0 +1,80 @@
+//     Zepto.js
+//     (c) 2010-2014 Thomas Fuchs
+//     Zepto.js may be freely distributed under the MIT license.
+
+// The following code is heavily inspired by jQuery's $.fn.data()
+
+;(function($){
+  var data = {}, dataAttr = $.fn.data, camelize = $.camelCase,
+    exp = $.expando = 'Zepto' + (+new Date()), emptyArray = []
+
+  // Get value from node:
+  // 1. first try key as given,
+  // 2. then try camelized key,
+  // 3. fall back to reading "data-*" attribute.
+  function getData(node, name) {
+    var id = node[exp], store = id && data[id]
+    if (name === undefined) return store || setData(node)
+    else {
+      if (store) {
+        if (name in store) return store[name]
+        var camelName = camelize(name)
+        if (camelName in store) return store[camelName]
+      }
+      return dataAttr.call($(node), name)
+    }
+  }
+
+  // Store value under camelized key on node
+  function setData(node, name, value) {
+    var id = node[exp] || (node[exp] = ++$.uuid),
+      store = data[id] || (data[id] = attributeData(node))
+    if (name !== undefined) store[camelize(name)] = value
+    return store
+  }
+
+  // Read all "data-*" attributes from a node
+  function attributeData(node) {
+    var store = {}
+    $.each(node.attributes || emptyArray, function(i, attr){
+      if (attr.name.indexOf('data-') == 0)
+        store[camelize(attr.name.replace('data-', ''))] =
+          $.zepto.deserializeValue(attr.value)
+    })
+    return store
+  }
+
+  $.fn.data = function(name, value) {
+    return value === undefined ?
+      // set multiple values via object
+      $.isPlainObject(name) ?
+        this.each(function(i, node){
+          $.each(name, function(key, value){ setData(node, key, value) })
+        }) :
+        // get value from first element
+        (0 in this ? getData(this[0], name) : undefined) :
+      // set value on all elements
+      this.each(function(){ setData(this, name, value) })
+  }
+
+  $.fn.removeData = function(names) {
+    if (typeof names == 'string') names = names.split(/\s+/)
+    return this.each(function(){
+      var id = this[exp], store = id && data[id]
+      if (store) $.each(names || store, function(key){
+        delete store[names ? camelize(this) : key]
+      })
+    })
+  }
+
+  // Generate extended `remove` and `empty` functions
+  ;['remove', 'empty'].forEach(function(methodName){
+    var origFn = $.fn[methodName]
+    $.fn[methodName] = function() {
+      var elements = this.find('*')
+      if (methodName === 'remove') elements = elements.add(this)
+      elements.removeData()
+      return origFn.call(this)
+    }
+  })
+})(Zepto)
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/zepto/event.js b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/zepto/event.js
new file mode 100644
index 0000000..a7d2ec1
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/zepto/event.js
@@ -0,0 +1,282 @@
+//     Zepto.js
+//     (c) 2010-2014 Thomas Fuchs
+//     Zepto.js may be freely distributed under the MIT license.
+
+;(function($){
+  var _zid = 1, undefined,
+      slice = Array.prototype.slice,
+      isFunction = $.isFunction,
+      isString = function(obj){ return typeof obj == 'string' },
+      handlers = {},
+      specialEvents={},
+      focusinSupported = 'onfocusin' in window,
+      focus = { focus: 'focusin', blur: 'focusout' },
+      hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' }
+
+  specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents'
+
+  function zid(element) {
+    return element._zid || (element._zid = _zid++)
+  }
+  function findHandlers(element, event, fn, selector) {
+    event = parse(event)
+    if (event.ns) var matcher = matcherFor(event.ns)
+    return (handlers[zid(element)] || []).filter(function(handler) {
+      return handler
+        && (!event.e  || handler.e == event.e)
+        && (!event.ns || matcher.test(handler.ns))
+        && (!fn       || zid(handler.fn) === zid(fn))
+        && (!selector || handler.sel == selector)
+    })
+  }
+  function parse(event) {
+    var parts = ('' + event).split('.')
+    return {e: parts[0], ns: parts.slice(1).sort().join(' ')}
+  }
+  function matcherFor(ns) {
+    return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)')
+  }
+
+  function eventCapture(handler, captureSetting) {
+    return handler.del &&
+      (!focusinSupported && (handler.e in focus)) ||
+      !!captureSetting
+  }
+
+  function realEvent(type) {
+    return hover[type] || (focusinSupported && focus[type]) || type
+  }
+
+  function add(element, events, fn, data, selector, delegator, capture){
+    var id = zid(element), set = (handlers[id] || (handlers[id] = []))
+    events.split(/\s/).forEach(function(event){
+      if (event == 'ready') return $(document).ready(fn)
+      var handler   = parse(event)
+      handler.fn    = fn
+      handler.sel   = selector
+      // emulate mouseenter, mouseleave
+      if (handler.e in hover) fn = function(e){
+        var related = e.relatedTarget
+        if (!related || (related !== this && !$.contains(this, related)))
+          return handler.fn.apply(this, arguments)
+      }
+      handler.del   = delegator
+      var callback  = delegator || fn
+      handler.proxy = function(e){
+        e = compatible(e)
+        if (e.isImmediatePropagationStopped()) return
+        e.data = data
+        var result = callback.apply(element, e._args == undefined ? [e] : [e].concat(e._args))
+        if (result === false) e.preventDefault(), e.stopPropagation()
+        return result
+      }
+      handler.i = set.length
+      set.push(handler)
+      if ('addEventListener' in element)
+        element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
+    })
+  }
+  function remove(element, events, fn, selector, capture){
+    var id = zid(element)
+    ;(events || '').split(/\s/).forEach(function(event){
+      findHandlers(element, event, fn, selector).forEach(function(handler){
+        delete handlers[id][handler.i]
+      if ('removeEventListener' in element)
+        element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
+      })
+    })
+  }
+
+  $.event = { add: add, remove: remove }
+
+  $.proxy = function(fn, context) {
+    var args = (2 in arguments) && slice.call(arguments, 2)
+    if (isFunction(fn)) {
+      var proxyFn = function(){ return fn.apply(context, args ? args.concat(slice.call(arguments)) : arguments) }
+      proxyFn._zid = zid(fn)
+      return proxyFn
+    } else if (isString(context)) {
+      if (args) {
+        args.unshift(fn[context], fn)
+        return $.proxy.apply(null, args)
+      } else {
+        return $.proxy(fn[context], fn)
+      }
+    } else {
+      throw new TypeError("expected function")
+    }
+  }
+
+  $.fn.bind = function(event, data, callback){
+    return this.on(event, data, callback)
+  }
+  $.fn.unbind = function(event, callback){
+    return this.off(event, callback)
+  }
+  $.fn.one = function(event, selector, data, callback){
+    return this.on(event, selector, data, callback, 1)
+  }
+
+  var returnTrue = function(){return true},
+      returnFalse = function(){return false},
+      ignoreProperties = /^([A-Z]|returnValue$|layer[XY]$)/,
+      eventMethods = {
+        preventDefault: 'isDefaultPrevented',
+        stopImmediatePropagation: 'isImmediatePropagationStopped',
+        stopPropagation: 'isPropagationStopped'
+      }
+
+  function compatible(event, source) {
+    if (source || !event.isDefaultPrevented) {
+      source || (source = event)
+
+      $.each(eventMethods, function(name, predicate) {
+        var sourceMethod = source[name]
+        event[name] = function(){
+          this[predicate] = returnTrue
+          return sourceMethod && sourceMethod.apply(source, arguments)
+        }
+        event[predicate] = returnFalse
+      })
+
+      if (source.defaultPrevented !== undefined ? source.defaultPrevented :
+          'returnValue' in source ? source.returnValue === false :
+          source.getPreventDefault && source.getPreventDefault())
+        event.isDefaultPrevented = returnTrue
+    }
+    return event
+  }
+
+  function createProxy(event) {
+    var key, proxy = { originalEvent: event }
+    for (key in event)
+      if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key]
+
+    return compatible(proxy, event)
+  }
+
+  $.fn.delegate = function(selector, event, callback){
+    return this.on(event, selector, callback)
+  }
+  $.fn.undelegate = function(selector, event, callback){
+    return this.off(event, selector, callback)
+  }
+
+  $.fn.live = function(event, callback){
+    $(document.body).delegate(this.selector, event, callback)
+    return this
+  }
+  $.fn.die = function(event, callback){
+    $(document.body).undelegate(this.selector, event, callback)
+    return this
+  }
+
+  $.fn.on = function(event, selector, data, callback, one){
+    var autoRemove, delegator, $this = this
+    if (event && !isString(event)) {
+      $.each(event, function(type, fn){
+        $this.on(type, selector, data, fn, one)
+      })
+      return $this
+    }
+
+    if (!isString(selector) && !isFunction(callback) && callback !== false)
+      callback = data, data = selector, selector = undefined
+    if (isFunction(data) || data === false)
+      callback = data, data = undefined
+
+    if (callback === false) callback = returnFalse
+
+    return $this.each(function(_, element){
+      if (one) autoRemove = function(e){
+        remove(element, e.type, callback)
+        return callback.apply(this, arguments)
+      }
+
+      if (selector) delegator = function(e){
+        var evt, match = $(e.target).closest(selector, element).get(0)
+        if (match && match !== element) {
+          evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element})
+          return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1)))
+        }
+      }
+
+      add(element, event, callback, data, selector, delegator || autoRemove)
+    })
+  }
+  $.fn.off = function(event, selector, callback){
+    var $this = this
+    if (event && !isString(event)) {
+      $.each(event, function(type, fn){
+        $this.off(type, selector, fn)
+      })
+      return $this
+    }
+
+    if (!isString(selector) && !isFunction(callback) && callback !== false)
+      callback = selector, selector = undefined
+
+    if (callback === false) callback = returnFalse
+
+    return $this.each(function(){
+      remove(this, event, callback, selector)
+    })
+  }
+
+  $.fn.trigger = function(event, args){
+    event = (isString(event) || $.isPlainObject(event)) ? $.Event(event) : compatible(event)
+    event._args = args
+    return this.each(function(){
+      // items in the collection might not be DOM elements
+      if('dispatchEvent' in this) this.dispatchEvent(event)
+      else $(this).triggerHandler(event, args)
+    })
+  }
+
+  // triggers event handlers on current element just as if an event occurred,
+  // doesn't trigger an actual event, doesn't bubble
+  $.fn.triggerHandler = function(event, args){
+    var e, result
+    this.each(function(i, element){
+      e = createProxy(isString(event) ? $.Event(event) : event)
+      e._args = args
+      e.target = element
+      $.each(findHandlers(element, event.type || event), function(i, handler){
+        result = handler.proxy(e)
+        if (e.isImmediatePropagationStopped()) return false
+      })
+    })
+    return result
+  }
+
+  // shortcut methods for `.bind(event, fn)` for each event type
+  ;('focusin focusout load resize scroll unload click dblclick '+
+  'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+
+  'change select keydown keypress keyup error').split(' ').forEach(function(event) {
+    $.fn[event] = function(callback) {
+      return callback ?
+        this.bind(event, callback) :
+        this.trigger(event)
+    }
+  })
+
+  ;['focus', 'blur'].forEach(function(name) {
+    $.fn[name] = function(callback) {
+      if (callback) this.bind(name, callback)
+      else this.each(function(){
+        try { this[name]() }
+        catch(e) {}
+      })
+      return this
+    }
+  })
+
+  $.Event = function(type, props) {
+    if (!isString(type)) props = type, type = props.type
+    var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true
+    if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name])
+    event.initEvent(type, bubbles, true)
+    return compatible(event)
+  }
+
+})(Zepto)
diff --git a/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/zepto/zepto.min.js b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/zepto/zepto.min.js
new file mode 100644
index 0000000..99949a3
--- /dev/null
+++ b/AstuteClient2/src/assets/jQuery-Mask-Plugin-master/test/zepto/zepto.min.js
@@ -0,0 +1,1580 @@
+/* Zepto v1.1.4 - zepto event ajax form ie - zeptojs.com/license */
+
+var Zepto = (function() {
+  var undefined, key, $, classList, emptyArray = [], slice = emptyArray.slice, filter = emptyArray.filter,
+    document = window.document,
+    elementDisplay = {}, classCache = {},
+    cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 },
+    fragmentRE = /^\s*<(\w+|!)[^>]*>/,
+    singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
+    tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
+    rootNodeRE = /^(?:body|html)$/i,
+    capitalRE = /([A-Z])/g,
+
+    // special attributes that should be get/set via method calls
+    methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'],
+
+    adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ],
+    table = document.createElement('table'),
+    tableRow = document.createElement('tr'),
+    containers = {
+      'tr': document.createElement('tbody'),
+      'tbody': table, 'thead': table, 'tfoot': table,
+      'td': tableRow, 'th': tableRow,
+      '*': document.createElement('div')
+    },
+    readyRE = /complete|loaded|interactive/,
+    simpleSelectorRE = /^[\w-]*$/,
+    class2type = {},
+    toString = class2type.toString,
+    zepto = {},
+    camelize, uniq,
+    tempParent = document.createElement('div'),
+    propMap = {
+      'tabindex': 'tabIndex',
+      'readonly': 'readOnly',
+      'for': 'htmlFor',
+      'class': 'className',
+      'maxlength': 'maxLength',
+      'cellspacing': 'cellSpacing',
+      'cellpadding': 'cellPadding',
+      'rowspan': 'rowSpan',
+      'colspan': 'colSpan',
+      'usemap': 'useMap',
+      'frameborder': 'frameBorder',
+      'contenteditable': 'contentEditable'
+    },
+    isArray = Array.isArray ||
+      function(object){ return object instanceof Array }
+
+  zepto.matches = function(element, selector) {
+    if (!selector || !element || element.nodeType !== 1) return false
+    var matchesSelector = element.webkitMatchesSelector || element.mozMatchesSelector ||
+                          element.oMatchesSelector || element.matchesSelector
+    if (matchesSelector) return matchesSelector.call(element, selector)
+    // fall back to performing a selector:
+    var match, parent = element.parentNode, temp = !parent
+    if (temp) (parent = tempParent).appendChild(element)
+    match = ~zepto.qsa(parent, selector).indexOf(element)
+    temp && tempParent.removeChild(element)
+    return match
+  }
+
+  function type(obj) {
+    return obj == null ? String(obj) :
+      class2type[toString.call(obj)] || "object"
+  }
+
+  function isFunction(value) { return type(value) == "function" }
+  function isWindow(obj)     { return obj != null && obj == obj.window }
+  function isDocument(obj)   { return obj != null && obj.nodeType == obj.DOCUMENT_NODE }
+  function isObject(obj)     { return type(obj) == "object" }
+  function isPlainObject(obj) {
+    return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype
+  }
+  function likeArray(obj) { return typeof obj.length == 'number' }
+
+  function compact(array) { return filter.call(array, function(item){ return item != null }) }
+  function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array }
+  camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) }
+  function dasherize(str) {
+    return str.replace(/::/g, '/')
+           .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
+           .replace(/([a-z\d])([A-Z])/g, '$1_$2')
+           .replace(/_/g, '-')
+           .toLowerCase()
+  }
+  uniq = function(array){ return filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) }
+
+  function classRE(name) {
+    return name in classCache ?
+      classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)'))
+  }
+
+  function maybeAddPx(name, value) {
+    return (typeof value == "number" && !cssNumber[dasherize(name)]) ? value + "px" : value
+  }
+
+  function defaultDisplay(nodeName) {
+    var element, display
+    if (!elementDisplay[nodeName]) {
+      element = document.createElement(nodeName)
+      document.body.appendChild(element)
+      display = getComputedStyle(element, '').getPropertyValue("display")
+      element.parentNode.removeChild(element)
+      display == "none" && (display = "block")
+      elementDisplay[nodeName] = display
+    }
+    return elementDisplay[nodeName]
+  }
+
+  function children(element) {
+    return 'children' in element ?
+      slice.call(element.children) :
+      $.map(element.childNodes, function(node){ if (node.nodeType == 1) return node })
+  }
+
+  // `$.zepto.fragment` takes a html string and an optional tag name
+  // to generate DOM nodes nodes from the given html string.
+  // The generated DOM nodes are returned as an array.
+  // This function can be overriden in plugins for example to make
+  // it compatible with browsers that don't support the DOM fully.
+  zepto.fragment = function(html, name, properties) {
+    var dom, nodes, container
+
+    // A special case optimization for a single tag
+    if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1))
+
+    if (!dom) {
+      if (html.replace) html = html.replace(tagExpanderRE, "<$1></$2>")
+      if (name === undefined) name = fragmentRE.test(html) && RegExp.$1
+      if (!(name in containers)) name = '*'
+
+      container = containers[name]
+      container.innerHTML = '' + html
+      dom = $.each(slice.call(container.childNodes), function(){
+        container.removeChild(this)
+      })
+    }
+
+    if (isPlainObject(properties)) {
+      nodes = $(dom)
+      $.each(properties, function(key, value) {
+        if (methodAttributes.indexOf(key) > -1) nodes[key](value)
+        else nodes.attr(key, value)
+      })
+    }
+
+    return dom
+  }
+
+  // `$.zepto.Z` swaps out the prototype of the given `dom` array
+  // of nodes with `$.fn` and thus supplying all the Zepto functions
+  // to the array. Note that `__proto__` is not supported on Internet
+  // Explorer. This method can be overriden in plugins.
+  zepto.Z = function(dom, selector) {
+    dom = dom || []
+    dom.__proto__ = $.fn
+    dom.selector = selector || ''
+    return dom
+  }
+
+  // `$.zepto.isZ` should return `true` if the given object is a Zepto
+  // collection. This method can be overriden in plugins.
+  zepto.isZ = function(object) {
+    return object instanceof zepto.Z
+  }
+
+  // `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and
+  // takes a CSS selector and an optional context (and handles various
+  // special cases).
+  // This method can be overriden in plugins.
+  zepto.init = function(selector, context) {
+    var dom
+    // If nothing given, return an empty Zepto collection
+    if (!selector) return zepto.Z()
+    // Optimize for string selectors
+    else if (typeof selector == 'string') {
+      selector = selector.trim()
+      // If it's a html fragment, create nodes from it
+      // Note: In both Chrome 21 and Firefox 15, DOM error 12
+      // is thrown if the fragment doesn't begin with <
+      if (selector[0] == '<' && fragmentRE.test(selector))
+        dom = zepto.fragment(selector, RegExp.$1, context), selector = null
+      // If there's a context, create a collection on that context first, and select
+      // nodes from there
+      else if (context !== undefined) return $(context).find(selector)
+      // If it's a CSS selector, use it to select nodes.
+      else dom = zepto.qsa(document, selector)
+    }
+    // If a function is given, call it when the DOM is ready
+    else if (isFunction(selector)) return $(document).ready(selector)
+    // If a Zepto collection is given, just return it
+    else if (zepto.isZ(selector)) return selector
+    else {
+      // normalize array if an array of nodes is given
+      if (isArray(selector)) dom = compact(selector)
+      // Wrap DOM nodes.
+      else if (isObject(selector))
+        dom = [selector], selector = null
+      // If it's a html fragment, create nodes from it
+      else if (fragmentRE.test(selector))
+        dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null
+      // If there's a context, create a collection on that context first, and select
+      // nodes from there
+      else if (context !== undefined) return $(context).find(selector)
+      // And last but no least, if it's a CSS selector, use it to select nodes.
+      else dom = zepto.qsa(document, selector)
+    }
+    // create a new Zepto collection from the nodes found
+    return zepto.Z(dom, selector)
+  }
+
+  // `$` will be the base `Zepto` object. When calling this
+  // function just call `$.zepto.init, which makes the implementation
+  // details of selecting nodes and creating Zepto collections
+  // patchable in plugins.
+  $ = function(selector, context){
+    return zepto.init(selector, context)
+  }
+
+  function extend(target, source, deep) {
+    for (key in source)
+      if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
+        if (isPlainObject(source[key]) && !isPlainObject(target[key]))
+          target[key] = {}
+        if (isArray(source[key]) && !isArray(target[key]))
+          target[key] = []
+        extend(target[key], source[key], deep)
+      }
+      else if (source[key] !== undefined) target[key] = source[key]
+  }
+
+  // Copy all but undefined properties from one or more
+  // objects to the `target` object.
+  $.extend = function(target){
+    var deep, args = slice.call(arguments, 1)
+    if (typeof target == 'boolean') {
+      deep = target
+      target = args.shift()
+    }
+    args.forEach(function(arg){ extend(target, arg, deep) })
+    return target
+  }
+
+  // `$.zepto.qsa` is Zepto's CSS selector implementation which
+  // uses `document.querySelectorAll` and optimizes for some special cases, like `#id`.
+  // This method can be overriden in plugins.
+  zepto.qsa = function(element, selector){
+    var found,
+        maybeID = selector[0] == '#',
+        maybeClass = !maybeID && selector[0] == '.',
+        nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked
+        isSimple = simpleSelectorRE.test(nameOnly)
+    return (isDocument(element) && isSimple && maybeID) ?
+      ( (found = element.getElementById(nameOnly)) ? [found] : [] ) :
+      (element.nodeType !== 1 && element.nodeType !== 9) ? [] :
+      slice.call(
+        isSimple && !maybeID ?
+          maybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a class
+          element.getElementsByTagName(selector) : // Or a tag
+          element.querySelectorAll(selector) // Or it's not simple, and we need to query all
+      )
+  }
+
+  function filtered(nodes, selector) {
+    return selector == null ? $(nodes) : $(nodes).filter(selector)
+  }
+
+  $.contains = document.documentElement.contains ?
+    function(parent, node) {
+      return parent !== node && parent.contains(node)
+    } :
+    function(parent, node) {
+      while (node && (node = node.parentNode))
+        if (node === parent) return true
+      return false
+    }
+
+  function funcArg(context, arg, idx, payload) {
+    return isFunction(arg) ? arg.call(context, idx, payload) : arg
+  }
+
+  function setAttribute(node, name, value) {
+    value == null ? node.removeAttribute(name) : node.setAttribute(name, value)
+  }
+
+  // access className property while respecting SVGAnimatedString
+  function className(node, value){
+    var klass = node.className,
+        svg   = klass && klass.baseVal !== undefined
+
+    if (value === undefined) return svg ? klass.baseVal : klass
+    svg ? (klass.baseVal = value) : (node.className = value)
+  }
+
+  // "true"  => true
+  // "false" => false
+  // "null"  => null
+  // "42"    => 42
+  // "42.5"  => 42.5
+  // "08"    => "08"
+  // JSON    => parse if valid
+  // String  => self
+  function deserializeValue(value) {
+    var num
+    try {
+      return value ?
+        value == "true" ||
+        ( value == "false" ? false :
+          value == "null" ? null :
+          !/^0/.test(value) && !isNaN(num = Number(value)) ? num :
+          /^[\[\{]/.test(value) ? $.parseJSON(value) :
+          value )
+        : value
+    } catch(e) {
+      return value
+    }
+  }
+
+  $.type = type
+  $.isFunction = isFunction
+  $.isWindow = isWindow
+  $.isArray = isArray
+  $.isPlainObject = isPlainObject
+
+  $.isEmptyObject = function(obj) {
+    var name
+    for (name in obj) return false
+    return true
+  }
+
+  $.inArray = function(elem, array, i){
+    return emptyArray.indexOf.call(array, elem, i)
+  }
+
+  $.camelCase = camelize
+  $.trim = function(str) {
+    return str == null ? "" : String.prototype.trim.call(str)
+  }
+
+  // plugin compatibility
+  $.uuid = 0
+  $.support = { }
+  $.expr = { }
+
+  $.map = function(elements, callback){
+    var value, values = [], i, key
+    if (likeArray(elements))
+      for (i = 0; i < elements.length; i++) {
+        value = callback(elements[i], i)
+        if (value != null) values.push(value)
+      }
+    else
+      for (key in elements) {
+        value = callback(elements[key], key)
+        if (value != null) values.push(value)
+      }
+    return flatten(values)
+  }
+
+  $.each = function(elements, callback){
+    var i, key
+    if (likeArray(elements)) {
+      for (i = 0; i < elements.length; i++)
+        if (callback.call(elements[i], i, elements[i]) === false) return elements
+    } else {
+      for (key in elements)
+        if (callback.call(elements[key], key, elements[key]) === false) return elements
+    }
+
+    return elements
+  }
+
+  $.grep = function(elements, callback){
+    return filter.call(elements, callback)
+  }
+
+  if (window.JSON) $.parseJSON = JSON.parse
+
+  // Populate the class2type map
+  $.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
+    class2type[ "[object " + name + "]" ] = name.toLowerCase()
+  })
+
+  // Define methods that will be available on all
+  // Zepto collections
+  $.fn = {
+    // Because a collection acts like an array
+    // copy over these useful array functions.
+    forEach: emptyArray.forEach,
+    reduce: emptyArray.reduce,
+    push: emptyArray.push,
+    sort: emptyArray.sort,
+    indexOf: emptyArray.indexOf,
+    concat: emptyArray.concat,
+
+    // `map` and `slice` in the jQuery API work differently
+    // from their array counterparts
+    map: function(fn){
+      return $($.map(this, function(el, i){ return fn.call(el, i, el) }))
+    },
+    slice: function(){
+      return $(slice.apply(this, arguments))
+    },
+
+    ready: function(callback){
+      // need to check if document.body exists for IE as that browser reports
+      // document ready when it hasn't yet created the body element
+      if (readyRE.test(document.readyState) && document.body) callback($)
+      else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false)
+      return this
+    },
+    get: function(idx){
+      return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length]
+    },
+    toArray: function(){ return this.get() },
+    size: function(){
+      return this.length
+    },
+    remove: function(){
+      return this.each(function(){
+        if (this.parentNode != null)
+          this.parentNode.removeChild(this)
+      })
+    },
+    each: function(callback){
+      emptyArray.every.call(this, function(el, idx){
+        return callback.call(el, idx, el) !== false
+      })
+      return this
+    },
+    filter: function(selector){
+      if (isFunction(selector)) return this.not(this.not(selector))
+      return $(filter.call(this, function(element){
+        return zepto.matches(element, selector)
+      }))
+    },
+    add: function(selector,context){
+      return $(uniq(this.concat($(selector,context))))
+    },
+    is: function(selector){
+      return this.length > 0 && zepto.matches(this[0], selector)
+    },
+    not: function(selector){
+      var nodes=[]
+      if (isFunction(selector) && selector.call !== undefined)
+        this.each(function(idx){
+          if (!selector.call(this,idx)) nodes.push(this)
+        })
+      else {
+        var excludes = typeof selector == 'string' ? this.filter(selector) :
+          (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector)
+        this.forEach(function(el){
+          if (excludes.indexOf(el) < 0) nodes.push(el)
+        })
+      }
+      return $(nodes)
+    },
+    has: function(selector){
+      return this.filter(function(){
+        return isObject(selector) ?
+          $.contains(this, selector) :
+          $(this).find(selector).size()
+      })
+    },
+    eq: function(idx){
+      return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1)
+    },
+    first: function(){
+      var el = this[0]
+      return el && !isObject(el) ? el : $(el)
+    },
+    last: function(){
+      var el = this[this.length - 1]
+      return el && !isObject(el) ? el : $(el)
+    },
+    find: function(selector){
+      var result, $this = this
+      if (!selector) result = []
+      else if (typeof selector == 'object')
+        result = $(selector).filter(function(){
+          var node = this
+          return emptyArray.some.call($this, function(parent){
+            return $.contains(parent, node)
+          })
+        })
+      else if (this.length == 1) result = $(zepto.qsa(this[0], selector))
+      else result = this.map(function(){ return zepto.qsa(this, selector) })
+      return result
+    },
+    closest: function(selector, context){
+      var node = this[0], collection = false
+      if (typeof selector == 'object') collection = $(selector)
+      while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector)))
+        node = node !== context && !isDocument(node) && node.parentNode
+      return $(node)
+    },
+    parents: function(selector){
+      var ancestors = [], nodes = this
+      while (nodes.length > 0)
+        nodes = $.map(nodes, function(node){
+          if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) {
+            ancestors.push(node)
+            return node
+          }
+        })
+      return filtered(ancestors, selector)
+    },
+    parent: function(selector){
+      return filtered(uniq(this.pluck('parentNode')), selector)
+    },
+    children: function(selector){
+      return filtered(this.map(function(){ return children(this) }), selector)
+    },
+    contents: function() {
+      return this.map(function() { return slice.call(this.childNodes) })
+    },
+    siblings: function(selector){
+      return filtered(this.map(function(i, el){
+        return filter.call(children(el.parentNode), function(child){ return child!==el })
+      }), selector)
+    },
+    empty: function(){
+      return this.each(function(){ this.innerHTML = '' })
+    },
+    // `pluck` is borrowed from Prototype.js
+    pluck: function(property){
+      return $.map(this, function(el){ return el[property] })
+    },
+    show: function(){
+      return this.each(function(){
+        this.style.display == "none" && (this.style.display = '')
+        if (getComputedStyle(this, '').getPropertyValue("display") == "none")
+          this.style.display = defaultDisplay(this.nodeName)
+      })
+    },
+    replaceWith: function(newContent){
+      return this.before(newContent).remove()
+    },
+    wrap: function(structure){
+      var func = isFunction(structure)
+      if (this[0] && !func)
+        var dom   = $(structure).get(0),
+            clone = dom.parentNode || this.length > 1
+
+      return this.each(function(index){
+        $(this).wrapAll(
+          func ? structure.call(this, index) :
+            clone ? dom.cloneNode(true) : dom
+        )
+      })
+    },
+    wrapAll: function(structure){
+      if (this[0]) {
+        $(this[0]).before(structure = $(structure))
+        var children
+        // drill down to the inmost element
+        while ((children = structure.children()).length) structure = children.first()
+        $(structure).append(this)
+      }
+      return this
+    },
+    wrapInner: function(structure){
+      var func = isFunction(structure)
+      return this.each(function(index){
+        var self = $(this), contents = self.contents(),
+            dom  = func ? structure.call(this, index) : structure
+        contents.length ? contents.wrapAll(dom) : self.append(dom)
+      })
+    },
+    unwrap: function(){
+      this.parent().each(function(){
+        $(this).replaceWith($(this).children())
+      })
+      return this
+    },
+    clone: function(){
+      return this.map(function(){ return this.cloneNode(true) })
+    },
+    hide: function(){
+      return this.css("display", "none")
+    },
+    toggle: function(setting){
+      return this.each(function(){
+        var el = $(this)
+        ;(setting === undefined ? el.css("display") == "none" : setting) ? el.show() : el.hide()
+      })
+    },
+    prev: function(selector){ return $(this.pluck('previousElementSibling')).filter(selector || '*') },
+    next: function(selector){ return $(this.pluck('nextElementSibling')).filter(selector || '*') },
+    html: function(html){
+      return 0 in arguments ?
+        this.each(function(idx){
+          var originHtml = this.innerHTML
+          $(this).empty().append( funcArg(this, html, idx, originHtml) )
+        }) :
+        (0 in this ? this[0].innerHTML : null)
+    },
+    text: function(text){
+      return 0 in arguments ?
+        this.each(function(idx){
+          var newText = funcArg(this, text, idx, this.textContent)
+          this.textContent = newText == null ? '' : ''+newText
+        }) :
+        (0 in this ? this[0].textContent : null)
+    },
+    attr: function(name, value){
+      var result
+      return (typeof name == 'string' && !(1 in arguments)) ?
+        (!this.length || this[0].nodeType !== 1 ? undefined :
+          (!(result = this[0].getAttribute(name)) && name in this[0]) ? this[0][name] : result
+        ) :
+        this.each(function(idx){
+          if (this.nodeType !== 1) return
+          if (isObject(name)) for (key in name) setAttribute(this, key, name[key])
+          else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name)))
+        })
+    },
+    removeAttr: function(name){
+      return this.each(function(){ this.nodeType === 1 && setAttribute(this, name) })
+    },
+    prop: function(name, value){
+      name = propMap[name] || name
+      return (1 in arguments) ?
+        this.each(function(idx){
+          this[name] = funcArg(this, value, idx, this[name])
+        }) :
+        (this[0] && this[0][name])
+    },
+    data: function(name, value){
+      var attrName = 'data-' + name.replace(capitalRE, '-$1').toLowerCase()
+
+      var data = (1 in arguments) ?
+        this.attr(attrName, value) :
+        this.attr(attrName)
+
+      return data !== null ? deserializeValue(data) : undefined
+    },
+    val: function(value){
+      return 0 in arguments ?
+        this.each(function(idx){
+          this.value = funcArg(this, value, idx, this.value)
+        }) :
+        (this[0] && (this[0].multiple ?
+           $(this[0]).find('option').filter(function(){ return this.selected }).pluck('value') :
+           this[0].value)
+        )
+    },
+    offset: function(coordinates){
+      if (coordinates) return this.each(function(index){
+        var $this = $(this),
+            coords = funcArg(this, coordinates, index, $this.offset()),
+            parentOffset = $this.offsetParent().offset(),
+            props = {
+              top:  coords.top  - parentOffset.top,
+              left: coords.left - parentOffset.left
+            }
+
+        if ($this.css('position') == 'static') props['position'] = 'relative'
+        $this.css(props)
+      })
+      if (!this.length) return null
+      var obj = this[0].getBoundingClientRect()
+      return {
+        left: obj.left + window.pageXOffset,
+        top: obj.top + window.pageYOffset,
+        width: Math.round(obj.width),
+        height: Math.round(obj.height)
+      }
+    },
+    css: function(property, value){
+      if (arguments.length < 2) {
+        var element = this[0], computedStyle = getComputedStyle(element, '')
+        if(!element) return
+        if (typeof property == 'string')
+          return element.style[camelize(property)] || computedStyle.getPropertyValue(property)
+        else if (isArray(property)) {
+          var props = {}
+          $.each(isArray(property) ? property: [property], function(_, prop){
+            props[prop] = (element.style[camelize(prop)] || computedStyle.getPropertyValue(prop))
+          })
+          return props
+        }
+      }
+
+      var css = ''
+      if (type(property) == 'string') {
+        if (!value && value !== 0)
+          this.each(function(){ this.style.removeProperty(dasherize(property)) })
+        else
+          css = dasherize(property) + ":" + maybeAddPx(property, value)
+      } else {
+        for (key in property)
+          if (!property[key] && property[key] !== 0)
+            this.each(function(){ this.style.removeProperty(dasherize(key)) })
+          else
+            css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';'
+      }
+
+      return this.each(function(){ this.style.cssText += ';' + css })
+    },
+    index: function(element){
+      return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0])
+    },
+    hasClass: function(name){
+      if (!name) return false
+      return emptyArray.some.call(this, function(el){
+        return this.test(className(el))
+      }, classRE(name))
+    },
+    addClass: function(name){
+      if (!name) return this
+      return this.each(function(idx){
+        classList = []
+        var cls = className(this), newName = funcArg(this, name, idx, cls)
+        newName.split(/\s+/g).forEach(function(klass){
+          if (!$(this).hasClass(klass)) classList.push(klass)
+        }, this)
+        classList.length && className(this, cls + (cls ? " " : "") + classList.join(" "))
+      })
+    },
+    removeClass: function(name){
+      return this.each(function(idx){
+        if (name === undefined) return className(this, '')
+        classList = className(this)
+        funcArg(this, name, idx, classList).split(/\s+/g).forEach(function(klass){
+          classList = classList.replace(classRE(klass), " ")
+        })
+        className(this, classList.trim())
+      })
+    },
+    toggleClass: function(name, when){
+      if (!name) return this
+      return this.each(function(idx){
+        var $this = $(this), names = funcArg(this, name, idx, className(this))
+        names.split(/\s+/g).forEach(function(klass){
+          (when === undefined ? !$this.hasClass(klass) : when) ?
+            $this.addClass(klass) : $this.removeClass(klass)
+        })
+      })
+    },
+    scrollTop: function(value){
+      if (!this.length) return
+      var hasScrollTop = 'scrollTop' in this[0]
+      if (value === undefined) return hasScrollTop ? this[0].scrollTop : this[0].pageYOffset
+      return this.each(hasScrollTop ?
+        function(){ this.scrollTop = value } :
+        function(){ this.scrollTo(this.scrollX, value) })
+    },
+    scrollLeft: function(value){
+      if (!this.length) return
+      var hasScrollLeft = 'scrollLeft' in this[0]
+      if (value === undefined) return hasScrollLeft ? this[0].scrollLeft : this[0].pageXOffset
+      return this.each(hasScrollLeft ?
+        function(){ this.scrollLeft = value } :
+        function(){ this.scrollTo(value, this.scrollY) })
+    },
+    position: function() {
+      if (!this.length) return
+
+      var elem = this[0],
+        // Get *real* offsetParent
+        offsetParent = this.offsetParent(),
+        // Get correct offsets
+        offset       = this.offset(),
+        parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset()
+
+      // Subtract element margins
+      // note: when an element has margin: auto the offsetLeft and marginLeft
+      // are the same in Safari causing offset.left to incorrectly be 0
+      offset.top  -= parseFloat( $(elem).css('margin-top') ) || 0
+      offset.left -= parseFloat( $(elem).css('margin-left') ) || 0
+
+      // Add offsetParent borders
+      parentOffset.top  += parseFloat( $(offsetParent[0]).css('border-top-width') ) || 0
+      parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0
+
+      // Subtract the two offsets
+      return {
+        top:  offset.top  - parentOffset.top,
+        left: offset.left - parentOffset.left
+      }
+    },
+    offsetParent: function() {
+      return this.map(function(){
+        var parent = this.offsetParent || document.body
+        while (parent && !rootNodeRE.test(parent.nodeName) && $(parent).css("position") == "static")
+          parent = parent.offsetParent
+        return parent
+      })
+    }
+  }
+
+  // for now
+  $.fn.detach = $.fn.remove
+
+  // Generate the `width` and `height` functions
+  ;['width', 'height'].forEach(function(dimension){
+    var dimensionProperty =
+      dimension.replace(/./, function(m){ return m[0].toUpperCase() })
+
+    $.fn[dimension] = function(value){
+      var offset, el = this[0]
+      if (value === undefined) return isWindow(el) ? el['inner' + dimensionProperty] :
+        isDocument(el) ? el.documentElement['scroll' + dimensionProperty] :
+        (offset = this.offset()) && offset[dimension]
+      else return this.each(function(idx){
+        el = $(this)
+        el.css(dimension, funcArg(this, value, idx, el[dimension]()))
+      })
+    }
+  })
+
+  function traverseNode(node, fun) {
+    fun(node)
+    for (var i = 0, len = node.childNodes.length; i < len; i++)
+      traverseNode(node.childNodes[i], fun)
+  }
+
+  // Generate the `after`, `prepend`, `before`, `append`,
+  // `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods.
+  adjacencyOperators.forEach(function(operator, operatorIndex) {
+    var inside = operatorIndex % 2 //=> prepend, append
+
+    $.fn[operator] = function(){
+      // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings
+      var argType, nodes = $.map(arguments, function(arg) {
+            argType = type(arg)
+            return argType == "object" || argType == "array" || arg == null ?
+              arg : zepto.fragment(arg)
+          }),
+          parent, copyByClone = this.length > 1
+      if (nodes.length < 1) return this
+
+      return this.each(function(_, target){
+        parent = inside ? target : target.parentNode
+
+        // convert all methods to a "before" operation
+        target = operatorIndex == 0 ? target.nextSibling :
+                 operatorIndex == 1 ? target.firstChild :
+                 operatorIndex == 2 ? target :
+                 null
+
+        var parentInDocument = $.contains(document.documentElement, parent)
+
+        nodes.forEach(function(node){
+          if (copyByClone) node = node.cloneNode(true)
+          else if (!parent) return $(node).remove()
+
+          parent.insertBefore(node, target)
+          if (parentInDocument) traverseNode(node, function(el){
+            if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' &&
+               (!el.type || el.type === 'text/javascript') && !el.src)
+              window['eval'].call(window, el.innerHTML)
+          })
+        })
+      })
+    }
+
+    // after    => insertAfter
+    // prepend  => prependTo
+    // before   => insertBefore
+    // append   => appendTo
+    $.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){
+      $(html)[operator](this)
+      return this
+    }
+  })
+
+  zepto.Z.prototype = $.fn
+
+  // Export internal API functions in the `$.zepto` namespace
+  zepto.uniq = uniq
+  zepto.deserializeValue = deserializeValue
+  $.zepto = zepto
+
+  return $
+})()
+
+window.Zepto = Zepto
+window.$ === undefined && (window.$ = Zepto)
+
+;(function($){
+  var _zid = 1, undefined,
+      slice = Array.prototype.slice,
+      isFunction = $.isFunction,
+      isString = function(obj){ return typeof obj == 'string' },
+      handlers = {},
+      specialEvents={},
+      focusinSupported = 'onfocusin' in window,
+      focus = { focus: 'focusin', blur: 'focusout' },
+      hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' }
+
+  specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents'
+
+  function zid(element) {
+    return element._zid || (element._zid = _zid++)
+  }
+  function findHandlers(element, event, fn, selector) {
+    event = parse(event)
+    if (event.ns) var matcher = matcherFor(event.ns)
+    return (handlers[zid(element)] || []).filter(function(handler) {
+      return handler
+        && (!event.e  || handler.e == event.e)
+        && (!event.ns || matcher.test(handler.ns))
+        && (!fn       || zid(handler.fn) === zid(fn))
+        && (!selector || handler.sel == selector)
+    })
+  }
+  function parse(event) {
+    var parts = ('' + event).split('.')
+    return {e: parts[0], ns: parts.slice(1).sort().join(' ')}
+  }
+  function matcherFor(ns) {
+    return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)')
+  }
+
+  function eventCapture(handler, captureSetting) {
+    return handler.del &&
+      (!focusinSupported && (handler.e in focus)) ||
+      !!captureSetting
+  }
+
+  function realEvent(type) {
+    return hover[type] || (focusinSupported && focus[type]) || type
+  }
+
+  function add(element, events, fn, data, selector, delegator, capture){
+    var id = zid(element), set = (handlers[id] || (handlers[id] = []))
+    events.split(/\s/).forEach(function(event){
+      if (event == 'ready') return $(document).ready(fn)
+      var handler   = parse(event)
+      handler.fn    = fn
+      handler.sel   = selector
+      // emulate mouseenter, mouseleave
+      if (handler.e in hover) fn = function(e){
+        var related = e.relatedTarget
+        if (!related || (related !== this && !$.contains(this, related)))
+          return handler.fn.apply(this, arguments)
+      }
+      handler.del   = delegator
+      var callback  = delegator || fn
+      handler.proxy = function(e){
+        e = compatible(e)
+        if (e.isImmediatePropagationStopped()) return
+        e.data = data
+        var result = callback.apply(element, e._args == undefined ? [e] : [e].concat(e._args))
+        if (result === false) e.preventDefault(), e.stopPropagation()
+        return result
+      }
+      handler.i = set.length
+      set.push(handler)
+      if ('addEventListener' in element)
+        element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
+    })
+  }
+  function remove(element, events, fn, selector, capture){
+    var id = zid(element)
+    ;(events || '').split(/\s/).forEach(function(event){
+      findHandlers(element, event, fn, selector).forEach(function(handler){
+        delete handlers[id][handler.i]
+      if ('removeEventListener' in element)
+        element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
+      })
+    })
+  }
+
+  $.event = { add: add, remove: remove }
+
+  $.proxy = function(fn, context) {
+    var args = (2 in arguments) && slice.call(arguments, 2)
+    if (isFunction(fn)) {
+      var proxyFn = function(){ return fn.apply(context, args ? args.concat(slice.call(arguments)) : arguments) }
+      proxyFn._zid = zid(fn)
+      return proxyFn
+    } else if (isString(context)) {
+      if (args) {
+        args.unshift(fn[context], fn)
+        return $.proxy.apply(null, args)
+      } else {
+        return $.proxy(fn[context], fn)
+      }
+    } else {
+      throw new TypeError("expected function")
+    }
+  }
+
+  $.fn.bind = function(event, data, callback){
+    return this.on(event, data, callback)
+  }
+  $.fn.unbind = function(event, callback){
+    return this.off(event, callback)
+  }
+  $.fn.one = function(event, selector, data, callback){
+    return this.on(event, selector, data, callback, 1)
+  }
+
+  var returnTrue = function(){return true},
+      returnFalse = function(){return false},
+      ignoreProperties = /^([A-Z]|returnValue$|layer[XY]$)/,
+      eventMethods = {
+        preventDefault: 'isDefaultPrevented',
+        stopImmediatePropagation: 'isImmediatePropagationStopped',
+        stopPropagation: 'isPropagationStopped'
+      }
+
+  function compatible(event, source) {
+    if (source || !event.isDefaultPrevented) {
+      source || (source = event)
+
+      $.each(eventMethods, function(name, predicate) {
+        var sourceMethod = source[name]
+        event[name] = function(){
+          this[predicate] = returnTrue
+          return sourceMethod && sourceMethod.apply(source, arguments)
+        }
+        event[predicate] = returnFalse
+      })
+
+      if (source.defaultPrevented !== undefined ? source.defaultPrevented :
+          'returnValue' in source ? source.returnValue === false :
+          source.getPreventDefault && source.getPreventDefault())
+        event.isDefaultPrevented = returnTrue
+    }
+    return event
+  }
+
+  function createProxy(event) {
+    var key, proxy = { originalEvent: event }
+    for (key in event)
+      if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key]
+
+    return compatible(proxy, event)
+  }
+
+  $.fn.delegate = function(selector, event, callback){
+    return this.on(event, selector, callback)
+  }
+  $.fn.undelegate = function(selector, event, callback){
+    return this.off(event, selector, callback)
+  }
+
+  $.fn.live = function(event, callback){
+    $(document.body).delegate(this.selector, event, callback)
+    return this
+  }
+  $.fn.die = function(event, callback){
+    $(document.body).undelegate(this.selector, event, callback)
+    return this
+  }
+
+  $.fn.on = function(event, selector, data, callback, one){
+    var autoRemove, delegator, $this = this
+    if (event && !isString(event)) {
+      $.each(event, function(type, fn){
+        $this.on(type, selector, data, fn, one)
+      })
+      return $this
+    }
+
+    if (!isString(selector) && !isFunction(callback) && callback !== false)
+      callback = data, data = selector, selector = undefined
+    if (isFunction(data) || data === false)
+      callback = data, data = undefined
+
+    if (callback === false) callback = returnFalse
+
+    return $this.each(function(_, element){
+      if (one) autoRemove = function(e){
+        remove(element, e.type, callback)
+        return callback.apply(this, arguments)
+      }
+
+      if (selector) delegator = function(e){
+        var evt, match = $(e.target).closest(selector, element).get(0)
+        if (match && match !== element) {
+          evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element})
+          return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1)))
+        }
+      }
+
+      add(element, event, callback, data, selector, delegator || autoRemove)
+    })
+  }
+  $.fn.off = function(event, selector, callback){
+    var $this = this
+    if (event && !isString(event)) {
+      $.each(event, function(type, fn){
+        $this.off(type, selector, fn)
+      })
+      return $this
+    }
+
+    if (!isString(selector) && !isFunction(callback) && callback !== false)
+      callback = selector, selector = undefined
+
+    if (callback === false) callback = returnFalse
+
+    return $this.each(function(){
+      remove(this, event, callback, selector)
+    })
+  }
+
+  $.fn.trigger = function(event, args){
+    event = (isString(event) || $.isPlainObject(event)) ? $.Event(event) : compatible(event)
+    event._args = args
+    return this.each(function(){
+      // items in the collection might not be DOM elements
+      if('dispatchEvent' in this) this.dispatchEvent(event)
+      else $(this).triggerHandler(event, args)
+    })
+  }
+
+  // triggers event handlers on current element just as if an event occurred,
+  // doesn't trigger an actual event, doesn't bubble
+  $.fn.triggerHandler = function(event, args){
+    var e, result
+    this.each(function(i, element){
+      e = createProxy(isString(event) ? $.Event(event) : event)
+      e._args = args
+      e.target = element
+      $.each(findHandlers(element, event.type || event), function(i, handler){
+        result = handler.proxy(e)
+        if (e.isImmediatePropagationStopped()) return false
+      })
+    })
+    return result
+  }
+
+  // shortcut methods for `.bind(event, fn)` for each event type
+  ;('focusin focusout load resize scroll unload click dblclick '+
+  'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+
+  'change select keydown keypress keyup error').split(' ').forEach(function(event) {
+    $.fn[event] = function(callback) {
+      return callback ?
+        this.bind(event, callback) :
+        this.trigger(event)
+    }
+  })
+
+  ;['focus', 'blur'].forEach(function(name) {
+    $.fn[name] = function(callback) {
+      if (callback) this.bind(name, callback)
+      else this.each(function(){
+        try { this[name]() }
+        catch(e) {}
+      })
+      return this
+    }
+  })
+
+  $.Event = function(type, props) {
+    if (!isString(type)) props = type, type = props.type
+    var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true
+    if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name])
+    event.initEvent(type, bubbles, true)
+    return compatible(event)
+  }
+
+})(Zepto)
+
+;(function($){
+  var jsonpID = 0,
+      document = window.document,
+      key,
+      name,
+      rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
+      scriptTypeRE = /^(?:text|application)\/javascript/i,
+      xmlTypeRE = /^(?:text|application)\/xml/i,
+      jsonType = 'application/json',
+      htmlType = 'text/html',
+      blankRE = /^\s*$/
+
+  // trigger a custom event and return false if it was cancelled
+  function triggerAndReturn(context, eventName, data) {
+    var event = $.Event(eventName)
+    $(context).trigger(event, data)
+    return !event.isDefaultPrevented()
+  }
+
+  // trigger an Ajax "global" event
+  function triggerGlobal(settings, context, eventName, data) {
+    if (settings.global) return triggerAndReturn(context || document, eventName, data)
+  }
+
+  // Number of active Ajax requests
+  $.active = 0
+
+  function ajaxStart(settings) {
+    if (settings.global && $.active++ === 0) triggerGlobal(settings, null, 'ajaxStart')
+  }
+  function ajaxStop(settings) {
+    if (settings.global && !(--$.active)) triggerGlobal(settings, null, 'ajaxStop')
+  }
+
+  // triggers an extra global event "ajaxBeforeSend" that's like "ajaxSend" but cancelable
+  function ajaxBeforeSend(xhr, settings) {
+    var context = settings.context
+    if (settings.beforeSend.call(context, xhr, settings) === false ||
+        triggerGlobal(settings, context, 'ajaxBeforeSend', [xhr, settings]) === false)
+      return false
+
+    triggerGlobal(settings, context, 'ajaxSend', [xhr, settings])
+  }
+  function ajaxSuccess(data, xhr, settings, deferred) {
+    var context = settings.context, status = 'success'
+    settings.success.call(context, data, status, xhr)
+    if (deferred) deferred.resolveWith(context, [data, status, xhr])
+    triggerGlobal(settings, context, 'ajaxSuccess', [xhr, settings, data])
+    ajaxComplete(status, xhr, settings)
+  }
+  // type: "timeout", "error", "abort", "parsererror"
+  function ajaxError(error, type, xhr, settings, deferred) {
+    var context = settings.context
+    settings.error.call(context, xhr, type, error)
+    if (deferred) deferred.rejectWith(context, [xhr, type, error])
+    triggerGlobal(settings, context, 'ajaxError', [xhr, settings, error || type])
+    ajaxComplete(type, xhr, settings)
+  }
+  // status: "success", "notmodified", "error", "timeout", "abort", "parsererror"
+  function ajaxComplete(status, xhr, settings) {
+    var context = settings.context
+    settings.complete.call(context, xhr, status)
+    triggerGlobal(settings, context, 'ajaxComplete', [xhr, settings])
+    ajaxStop(settings)
+  }
+
+  // Empty function, used as default callback
+  function empty() {}
+
+  $.ajaxJSONP = function(options, deferred){
+    if (!('type' in options)) return $.ajax(options)
+
+    var _callbackName = options.jsonpCallback,
+      callbackName = ($.isFunction(_callbackName) ?
+        _callbackName() : _callbackName) || ('jsonp' + (++jsonpID)),
+      script = document.createElement('script'),
+      originalCallback = window[callbackName],
+      responseData,
+      abort = function(errorType) {
+        $(script).triggerHandler('error', errorType || 'abort')
+      },
+      xhr = { abort: abort }, abortTimeout
+
+    if (deferred) deferred.promise(xhr)
+
+    $(script).on('load error', function(e, errorType){
+      clearTimeout(abortTimeout)
+      $(script).off().remove()
+
+      if (e.type == 'error' || !responseData) {
+        ajaxError(null, errorType || 'error', xhr, options, deferred)
+      } else {
+        ajaxSuccess(responseData[0], xhr, options, deferred)
+      }
+
+      window[callbackName] = originalCallback
+      if (responseData && $.isFunction(originalCallback))
+        originalCallback(responseData[0])
+
+      originalCallback = responseData = undefined
+    })
+
+    if (ajaxBeforeSend(xhr, options) === false) {
+      abort('abort')
+      return xhr
+    }
+
+    window[callbackName] = function(){
+      responseData = arguments
+    }
+
+    script.src = options.url.replace(/\?(.+)=\?/, '?$1=' + callbackName)
+    document.head.appendChild(script)
+
+    if (options.timeout > 0) abortTimeout = setTimeout(function(){
+      abort('timeout')
+    }, options.timeout)
+
+    return xhr
+  }
+
+  $.ajaxSettings = {
+    // Default type of request
+    type: 'GET',
+    // Callback that is executed before request
+    beforeSend: empty,
+    // Callback that is executed if the request succeeds
+    success: empty,
+    // Callback that is executed the the server drops error
+    error: empty,
+    // Callback that is executed on request complete (both: error and success)
+    complete: empty,
+    // The context for the callbacks
+    context: null,
+    // Whether to trigger "global" Ajax events
+    global: true,
+    // Transport
+    xhr: function () {
+      return new window.XMLHttpRequest()
+    },
+    // MIME types mapping
+    // IIS returns Javascript as "application/x-javascript"
+    accepts: {
+      script: 'text/javascript, application/javascript, application/x-javascript',
+      json:   jsonType,
+      xml:    'application/xml, text/xml',
+      html:   htmlType,
+      text:   'text/plain'
+    },
+    // Whether the request is to another domain
+    crossDomain: false,
+    // Default timeout
+    timeout: 0,
+    // Whether data should be serialized to string
+    processData: true,
+    // Whether the browser should be allowed to cache GET responses
+    cache: true
+  }
+
+  function mimeToDataType(mime) {
+    if (mime) mime = mime.split(';', 2)[0]
+    return mime && ( mime == htmlType ? 'html' :
+      mime == jsonType ? 'json' :
+      scriptTypeRE.test(mime) ? 'script' :
+      xmlTypeRE.test(mime) && 'xml' ) || 'text'
+  }
+
+  function appendQuery(url, query) {
+    if (query == '') return url
+    return (url + '&' + query).replace(/[&?]{1,2}/, '?')
+  }
+
+  // serialize payload and append it to the URL for GET requests
+  function serializeData(options) {
+    if (options.processData && options.data && $.type(options.data) != "string")
+      options.data = $.param(options.data, options.traditional)
+    if (options.data && (!options.type || options.type.toUpperCase() == 'GET'))
+      options.url = appendQuery(options.url, options.data), options.data = undefined
+  }
+
+  $.ajax = function(options){
+    var settings = $.extend({}, options || {}),
+        deferred = $.Deferred && $.Deferred()
+    for (key in $.ajaxSettings) if (settings[key] === undefined) settings[key] = $.ajaxSettings[key]
+
+    ajaxStart(settings)
+
+    if (!settings.crossDomain) settings.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(settings.url) &&
+      RegExp.$2 != window.location.host
+
+    if (!settings.url) settings.url = window.location.toString()
+    serializeData(settings)
+
+    var dataType = settings.dataType, hasPlaceholder = /\?.+=\?/.test(settings.url)
+    if (hasPlaceholder) dataType = 'jsonp'
+
+    if (settings.cache === false || (
+         (!options || options.cache !== true) &&
+         ('script' == dataType || 'jsonp' == dataType)
+        ))
+      settings.url = appendQuery(settings.url, '_=' + Date.now())
+
+    if ('jsonp' == dataType) {
+      if (!hasPlaceholder)
+        settings.url = appendQuery(settings.url,
+          settings.jsonp ? (settings.jsonp + '=?') : settings.jsonp === false ? '' : 'callback=?')
+      return $.ajaxJSONP(settings, deferred)
+    }
+
+    var mime = settings.accepts[dataType],
+        headers = { },
+        setHeader = function(name, value) { headers[name.toLowerCase()] = [name, value] },
+        protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol,
+        xhr = settings.xhr(),
+        nativeSetHeader = xhr.setRequestHeader,
+        abortTimeout
+
+    if (deferred) deferred.promise(xhr)
+
+    if (!settings.crossDomain) setHeader('X-Requested-With', 'XMLHttpRequest')
+    setHeader('Accept', mime || '*/*')
+    if (mime = settings.mimeType || mime) {
+      if (mime.indexOf(',') > -1) mime = mime.split(',', 2)[0]
+      xhr.overrideMimeType && xhr.overrideMimeType(mime)
+    }
+    if (settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() != 'GET'))
+      setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded')
+
+    if (settings.headers) for (name in settings.headers) setHeader(name, settings.headers[name])
+    xhr.setRequestHeader = setHeader
+
+    xhr.onreadystatechange = function(){
+      if (xhr.readyState == 4) {
+        xhr.onreadystatechange = empty
+        clearTimeout(abortTimeout)
+        var result, error = false
+        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status == 0 && protocol == 'file:')) {
+          dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type'))
+          result = xhr.responseText
+
+          try {
+            // http://perfectionkills.com/global-eval-what-are-the-options/
+            if (dataType == 'script')    (1,eval)(result)
+            else if (dataType == 'xml')  result = xhr.responseXML
+            else if (dataType == 'json') result = blankRE.test(result) ? null : $.parseJSON(result)
+          } catch (e) { error = e }
+
+          if (error) ajaxError(error, 'parsererror', xhr, settings, deferred)
+          else ajaxSuccess(result, xhr, settings, deferred)
+        } else {
+          ajaxError(xhr.statusText || null, xhr.status ? 'error' : 'abort', xhr, settings, deferred)
+        }
+      }
+    }
+
+    if (ajaxBeforeSend(xhr, settings) === false) {
+      xhr.abort()
+      ajaxError(null, 'abort', xhr, settings, deferred)
+      return xhr
+    }
+
+    if (settings.xhrFields) for (name in settings.xhrFields) xhr[name] = settings.xhrFields[name]
+
+    var async = 'async' in settings ? settings.async : true
+    xhr.open(settings.type, settings.url, async, settings.username, settings.password)
+
+    for (name in headers) nativeSetHeader.apply(xhr, headers[name])
+
+    if (settings.timeout > 0) abortTimeout = setTimeout(function(){
+        xhr.onreadystatechange = empty
+        xhr.abort()
+        ajaxError(null, 'timeout', xhr, settings, deferred)
+      }, settings.timeout)
+
+    // avoid sending empty string (#319)
+    xhr.send(settings.data ? settings.data : null)
+    return xhr
+  }
+
+  // handle optional data/success arguments
+  function parseArguments(url, data, success, dataType) {
+    if ($.isFunction(data)) dataType = success, success = data, data = undefined
+    if (!$.isFunction(success)) dataType = success, success = undefined
+    return {
+      url: url
+    , data: data
+    , success: success
+    , dataType: dataType
+    }
+  }
+
+  $.get = function(/* url, data, success, dataType */){
+    return $.ajax(parseArguments.apply(null, arguments))
+  }
+
+  $.post = function(/* url, data, success, dataType */){
+    var options = parseArguments.apply(null, arguments)
+    options.type = 'POST'
+    return $.ajax(options)
+  }
+
+  $.getJSON = function(/* url, data, success */){
+    var options = parseArguments.apply(null, arguments)
+    options.dataType = 'json'
+    return $.ajax(options)
+  }
+
+  $.fn.load = function(url, data, success){
+    if (!this.length) return this
+    var self = this, parts = url.split(/\s/), selector,
+        options = parseArguments(url, data, success),
+        callback = options.success
+    if (parts.length > 1) options.url = parts[0], selector = parts[1]
+    options.success = function(response){
+      self.html(selector ?
+        $('<div>').html(response.replace(rscript, "")).find(selector)
+        : response)
+      callback && callback.apply(self, arguments)
+    }
+    $.ajax(options)
+    return this
+  }
+
+  var escape = encodeURIComponent
+
+  function serialize(params, obj, traditional, scope){
+    var type, array = $.isArray(obj), hash = $.isPlainObject(obj)
+    $.each(obj, function(key, value) {
+      type = $.type(value)
+      if (scope) key = traditional ? scope :
+        scope + '[' + (hash || type == 'object' || type == 'array' ? key : '') + ']'
+      // handle data in serializeArray() format
+      if (!scope && array) params.add(value.name, value.value)
+      // recurse into nested objects
+      else if (type == "array" || (!traditional && type == "object"))
+        serialize(params, value, traditional, key)
+      else params.add(key, value)
+    })
+  }
+
+  $.param = function(obj, traditional){
+    var params = []
+    params.add = function(k, v){ this.push(escape(k) + '=' + escape(v)) }
+    serialize(params, obj, traditional)
+    return params.join('&').replace(/%20/g, '+')
+  }
+})(Zepto)
+
+;(function($){
+  $.fn.serializeArray = function() {
+    var result = [], el
+    $([].slice.call(this.get(0).elements)).each(function(){
+      el = $(this)
+      var type = el.attr('type')
+      if (this.nodeName.toLowerCase() != 'fieldset' &&
+        !this.disabled && type != 'submit' && type != 'reset' && type != 'button' &&
+        ((type != 'radio' && type != 'checkbox') || this.checked))
+        result.push({
+          name: el.attr('name'),
+          value: el.val()
+        })
+    })
+    return result
+  }
+
+  $.fn.serialize = function(){
+    var result = []
+    this.serializeArray().forEach(function(elm){
+      result.push(encodeURIComponent(elm.name) + '=' + encodeURIComponent(elm.value))
+    })
+    return result.join('&')
+  }
+
+  $.fn.submit = function(callback) {
+    if (callback) this.bind('submit', callback)
+    else if (this.length) {
+      var event = $.Event('submit')
+      this.eq(0).trigger(event)
+      if (!event.isDefaultPrevented()) this.get(0).submit()
+    }
+    return this
+  }
+
+})(Zepto)
+
+;(function($){
+  // __proto__ doesn't exist on IE<11, so redefine
+  // the Z function to use object extension instead
+  if (!('__proto__' in {})) {
+    $.extend($.zepto, {
+      Z: function(dom, selector){
+        dom = dom || []
+        $.extend(dom, $.fn)
+        dom.selector = selector || ''
+        dom.__Z = true
+        return dom
+      },
+      // this is a kludge but works
+      isZ: function(object){
+        return $.type(object) === 'array' && '__Z' in object
+      }
+    })
+  }
+
+  // getComputedStyle shouldn't freak out when called
+  // without a valid element as argument
+  try {
+    getComputedStyle(undefined)
+  } catch(e) {
+    var nativeGetComputedStyle = getComputedStyle;
+    window.getComputedStyle = function(element){
+      try {
+        return nativeGetComputedStyle(element)
+      } catch(e) {
+        return null
+      }
+    }
+  }
+})(Zepto)
diff --git a/AstuteClient2/src/assets/jspdf/README.md b/AstuteClient2/src/assets/jspdf/README.md
new file mode 100644
index 0000000..7baf76f
--- /dev/null
+++ b/AstuteClient2/src/assets/jspdf/README.md
@@ -0,0 +1,108 @@
+# jsPDF
+
+[![Greenkeeper badge](https://badges.greenkeeper.io/MrRio/jsPDF.svg)](https://greenkeeper.io/)
+
+[![Build Status](https://saucelabs.com/buildstatus/jspdf)](https://saucelabs.com/beta/builds/526e7fda50bd4f97a854bf10f280305d)
+
+[![Code Climate](https://codeclimate.com/repos/57f943855cdc43705e00592f/badges/2665cddeba042dc5191f/gpa.svg)](https://codeclimate.com/repos/57f943855cdc43705e00592f/feed) [![Test Coverage](https://codeclimate.com/repos/57f943855cdc43705e00592f/badges/2665cddeba042dc5191f/coverage.svg)](https://codeclimate.com/repos/57f943855cdc43705e00592f/coverage)
+
+**A library to generate PDFs in client-side JavaScript.**
+
+You can [catch me on twitter](http://twitter.com/MrRio): [@MrRio](http://twitter.com/MrRio) or head over to [my company's website](http://parall.ax) for consultancy.
+
+## [Live Demo](http://rawgit.com/MrRio/jsPDF/master/) | [Documentation](http://rawgit.com/MrRio/jsPDF/master/docs/)
+
+## Creating your first document
+
+The easiest way to get started is to drop the CDN hosted library into your page:
+
+```html
+<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.debug.js" integrity="sha384-CchuzHs077vGtfhGYl9Qtc7Vx64rXBXdIAZIPbItbNyWIRTdG0oYAqki3Ry13Yzu" crossorigin="anonymous"></script>
+```
+
+Integrity-hash generated by https://www.srihash.org/
+
+or can always get latest version via [unpkg](https://unpkg.com/#/)
+
+```html
+<script src="https://unpkg.com/jspdf@latest/dist/jspdf.min.js"></script>
+```
+
+Using yarn:
+
+```bash
+yarn add jspdf
+```
+
+Using npm:
+
+```bash
+npm install jspdf --save
+```
+
+Then you're ready to start making your document:
+
+```javascript
+// Default export is a4 paper, portrait, using milimeters for units
+var doc = new jsPDF()
+
+doc.text('Hello world!', 10, 10)
+doc.save('a4.pdf')
+```
+
+If you want to change the paper size, orientation, or units, you can do:
+
+```javascript
+// Landscape export, 2×4 inches
+var doc = new jsPDF({
+  orientation: 'landscape',
+  unit: 'in',
+  format: [4, 2]
+})
+
+doc.text('Hello world!', 1, 1)
+doc.save('two-by-four.pdf')
+```
+## Angular Configuration:
+
+Add following in angular-cli.json:
+```
+"scripts": [ "../node_modules/jspdf/dist/jspdf.min.js" ]
+```
+and import it in your component:
+```
+import * as jsPDF from 'jspdf'
+```
+
+
+Great! Now give us a Star :)
+
+## Contributing
+Build the library with `npm run build`. This will fetch all dependencies and then compile the `dist` files. To see the examples locally you can start a web server with `npm start` and go to `localhost:8000`.
+
+## Credits
+- Big thanks to Daniel Dotsenko from [Willow Systems Corporation](https://github.com/willowsystems) for making huge contributions to the codebase.
+- Thanks to Ajaxian.com for [featuring us back in 2009](http://ajaxian.com/archives/dynamically-generic-pdfs-with-javascript).
+- Everyone else that's contributed patches or bug reports. You rock.
+
+## License (MIT)
+Copyright (c) 2010-2017 James Hall, https://github.com/MrRio/jsPDF
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/AstuteClient2/src/assets/jspdf/dist/jspdf.debug.js b/AstuteClient2/src/assets/jspdf/dist/jspdf.debug.js
new file mode 100644
index 0000000..912ee6b
--- /dev/null
+++ b/AstuteClient2/src/assets/jspdf/dist/jspdf.debug.js
@@ -0,0 +1,20712 @@
+(function (global, factory) {
+  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+  typeof define === 'function' && define.amd ? define(factory) :
+  (global.jsPDF = factory());
+}(this, (function () { 'use strict';
+
+  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
+    return typeof obj;
+  } : function (obj) {
+    return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
+  };
+
+  /** @preserve
+   * jsPDF - PDF Document creation from JavaScript
+   * Version 1.4.0 Built on 2018-05-21T16:49:17.000Z
+   *                           CommitID 48c1917315
+   *
+   * Copyright (c) 2010-2016 James Hall <james@parall.ax>, https://github.com/MrRio/jsPDF
+   *               2010 Aaron Spike, https://github.com/acspike
+   *               2012 Willow Systems Corporation, willow-systems.com
+   *               2012 Pablo Hess, https://github.com/pablohess
+   *               2012 Florian Jenett, https://github.com/fjenett
+   *               2013 Warren Weckesser, https://github.com/warrenweckesser
+   *               2013 Youssef Beddad, https://github.com/lifof
+   *               2013 Lee Driscoll, https://github.com/lsdriscoll
+   *               2013 Stefan Slonevskiy, https://github.com/stefslon
+   *               2013 Jeremy Morel, https://github.com/jmorel
+   *               2013 Christoph Hartmann, https://github.com/chris-rock
+   *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
+   *               2014 James Makes, https://github.com/dollaruw
+   *               2014 Diego Casorran, https://github.com/diegocr
+   *               2014 Steven Spungin, https://github.com/Flamenco
+   *               2014 Kenneth Glassey, https://github.com/Gavvers
+   *
+   * Licensed under the MIT License
+   *
+   * Contributor(s):
+   *    siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango,
+   *    kim3er, mfo, alnorth, Flamenco
+   */
+
+  /**
+   * Creates new jsPDF document object instance.
+   * @name jsPDF
+   * @class
+   * @param orientation {String/Object} Orientation of the first page. Possible values are "portrait" or "landscape" (or shortcuts "p" (Default), "l") <br />
+   * Can also be an options object.
+   * @param unit {String}  Measurement unit to be used when coordinates are specified.<br />
+   * Possible values are "pt" (points), "mm" (Default), "cm", "in" or "px".
+   * @param format {String/Array} The format of the first page. Can be <ul><li>a0 - a10</li><li>b0 - b10</li><li>c0 - c10</li><li>c0 - c10</li><li>dl</li><li>letter</li><li>government-letter</li><li>legal</li><li>junior-legal</li><li>ledger</li><li>tabloid</li><li>credit-card</li></ul><br />
+   * Default is "a4". If you want to use your own format just pass instead of one of the above predefined formats the size as an number-array , e.g. [595.28, 841.89]
+   * @returns {jsPDF}
+   * @description
+   * If the first parameter (orientation) is an object, it will be interpreted as an object of named parameters
+   * ```
+   * {
+   *  orientation: 'p',
+   *  unit: 'mm',
+   *  format: 'a4',
+   *  hotfixes: [] // an array of hotfix strings to enable
+   * }
+   * ```
+   */
+  var jsPDF = function (global) {
+
+    var pdfVersion = '1.3',
+        pageFormats = { // Size in pt of various paper formats
+      'a0': [2383.94, 3370.39],
+      'a1': [1683.78, 2383.94],
+      'a2': [1190.55, 1683.78],
+      'a3': [841.89, 1190.55],
+      'a4': [595.28, 841.89],
+      'a5': [419.53, 595.28],
+      'a6': [297.64, 419.53],
+      'a7': [209.76, 297.64],
+      'a8': [147.40, 209.76],
+      'a9': [104.88, 147.40],
+      'a10': [73.70, 104.88],
+      'b0': [2834.65, 4008.19],
+      'b1': [2004.09, 2834.65],
+      'b2': [1417.32, 2004.09],
+      'b3': [1000.63, 1417.32],
+      'b4': [708.66, 1000.63],
+      'b5': [498.90, 708.66],
+      'b6': [354.33, 498.90],
+      'b7': [249.45, 354.33],
+      'b8': [175.75, 249.45],
+      'b9': [124.72, 175.75],
+      'b10': [87.87, 124.72],
+      'c0': [2599.37, 3676.54],
+      'c1': [1836.85, 2599.37],
+      'c2': [1298.27, 1836.85],
+      'c3': [918.43, 1298.27],
+      'c4': [649.13, 918.43],
+      'c5': [459.21, 649.13],
+      'c6': [323.15, 459.21],
+      'c7': [229.61, 323.15],
+      'c8': [161.57, 229.61],
+      'c9': [113.39, 161.57],
+      'c10': [79.37, 113.39],
+      'dl': [311.81, 623.62],
+      'letter': [612, 792],
+      'government-letter': [576, 756],
+      'legal': [612, 1008],
+      'junior-legal': [576, 360],
+      'ledger': [1224, 792],
+      'tabloid': [792, 1224],
+      'credit-card': [153, 243]
+    };
+
+    /**
+     * jsPDF's Internal PubSub Implementation.
+     * See mrrio.github.io/jsPDF/doc/symbols/PubSub.html
+     * Backward compatible rewritten on 2014 by
+     * Diego Casorran, https://github.com/diegocr
+     *
+     * @class
+     * @name PubSub
+     * @ignore This should not be in the public docs.
+     */
+    function PubSub(context) {
+      var topics = {};
+
+      this.subscribe = function (topic, callback, once) {
+        if (typeof callback !== 'function') {
+          return false;
+        }
+
+        if (!topics.hasOwnProperty(topic)) {
+          topics[topic] = {};
+        }
+
+        var id = Math.random().toString(35);
+        topics[topic][id] = [callback, !!once];
+
+        return id;
+      };
+
+      this.unsubscribe = function (token) {
+        for (var topic in topics) {
+          if (topics[topic][token]) {
+            delete topics[topic][token];
+            return true;
+          }
+        }
+        return false;
+      };
+
+      this.publish = function (topic) {
+        if (topics.hasOwnProperty(topic)) {
+          var args = Array.prototype.slice.call(arguments, 1),
+              idr = [];
+
+          for (var id in topics[topic]) {
+            var sub = topics[topic][id];
+            try {
+              sub[0].apply(context, args);
+            } catch (ex) {
+              if (global.console) {
+                console.error('jsPDF PubSub Error', ex.message, ex);
+              }
+            }
+            if (sub[1]) idr.push(id);
+          }
+          if (idr.length) idr.forEach(this.unsubscribe);
+        }
+      };
+    }
+
+    /**
+     * @constructor
+     * @private
+     */
+    function jsPDF(orientation, unit, format, compressPdf) {
+      var options = {};
+
+      if ((typeof orientation === 'undefined' ? 'undefined' : _typeof(orientation)) === 'object') {
+        options = orientation;
+
+        orientation = options.orientation;
+        unit = options.unit || unit;
+        format = options.format || format;
+        compressPdf = options.compress || options.compressPdf || compressPdf;
+      }
+
+      // Default options
+      unit = unit || 'mm';
+      format = format || 'a4';
+      orientation = ('' + (orientation || 'P')).toLowerCase();
+
+      var format_as_string = ('' + format).toLowerCase(),
+          compress = !!compressPdf && typeof Uint8Array === 'function',
+          textColor = options.textColor || '0 g',
+          drawColor = options.drawColor || '0 G',
+          activeFontSize = options.fontSize || 16,
+          activeCharSpace = options.charSpace || 0,
+          R2L = options.R2L || false,
+          lineHeightProportion = options.lineHeight || 1.15,
+          lineWidth = options.lineWidth || 0.200025,
+          // 2mm
+      fileId = '00000000000000000000000000000000',
+          objectNumber = 2,
+          // 'n' Current object number
+      outToPages = !1,
+          // switches where out() prints. outToPages true = push to pages obj. outToPages false = doc builder content
+      offsets = [],
+          // List of offsets. Activated and reset by buildDocument(). Pupulated by various calls buildDocument makes.
+      fonts = {},
+          // collection of font objects, where key is fontKey - a dynamically created label for a given font.
+      fontmap = {},
+          // mapping structure fontName > fontStyle > font key - performance layer. See addFont()
+      activeFontKey,
+          // will be string representing the KEY of the font as combination of fontName + fontStyle
+      k,
+          // Scale factor
+      tmp,
+          page = 0,
+          currentPage,
+          pages = [],
+          pagesContext = [],
+          // same index as pages and pagedim
+      pagedim = [],
+          content = [],
+          additionalObjects = [],
+          lineCapID = 0,
+          lineJoinID = 0,
+          content_length = 0,
+          pageWidth,
+          pageHeight,
+          pageMode,
+          zoomMode,
+          layoutMode,
+          creationDate,
+          documentProperties = {
+        'title': '',
+        'subject': '',
+        'author': '',
+        'keywords': '',
+        'creator': ''
+      },
+          API = {},
+          events = new PubSub(API),
+          hotfixes = options.hotfixes || [],
+
+
+      /////////////////////
+      // Private functions
+      /////////////////////
+      generateColorString = function generateColorString(options) {
+        var color;
+
+        var ch1 = options.ch1;
+        var ch2 = options.ch2;
+        var ch3 = options.ch3;
+        var ch4 = options.ch4;
+        var precision = options.precision;
+        var letterArray = options.pdfColorType === "draw" ? ['G', 'RG', 'K'] : ['g', 'rg', 'k'];
+
+        var cssColorNames = { "aliceblue": "#f0f8ff", "antiquewhite": "#faebd7", "aqua": "#00ffff", "aquamarine": "#7fffd4", "azure": "#f0ffff",
+          "beige": "#f5f5dc", "bisque": "#ffe4c4", "black": "#000000", "blanchedalmond": "#ffebcd", "blue": "#0000ff", "blueviolet": "#8a2be2", "brown": "#a52a2a", "burlywood": "#deb887",
+          "cadetblue": "#5f9ea0", "chartreuse": "#7fff00", "chocolate": "#d2691e", "coral": "#ff7f50", "cornflowerblue": "#6495ed", "cornsilk": "#fff8dc", "crimson": "#dc143c", "cyan": "#00ffff",
+          "darkblue": "#00008b", "darkcyan": "#008b8b", "darkgoldenrod": "#b8860b", "darkgray": "#a9a9a9", "darkgreen": "#006400", "darkkhaki": "#bdb76b", "darkmagenta": "#8b008b", "darkolivegreen": "#556b2f",
+          "darkorange": "#ff8c00", "darkorchid": "#9932cc", "darkred": "#8b0000", "darksalmon": "#e9967a", "darkseagreen": "#8fbc8f", "darkslateblue": "#483d8b", "darkslategray": "#2f4f4f", "darkturquoise": "#00ced1",
+          "darkviolet": "#9400d3", "deeppink": "#ff1493", "deepskyblue": "#00bfff", "dimgray": "#696969", "dodgerblue": "#1e90ff",
+          "firebrick": "#b22222", "floralwhite": "#fffaf0", "forestgreen": "#228b22", "fuchsia": "#ff00ff",
+          "gainsboro": "#dcdcdc", "ghostwhite": "#f8f8ff", "gold": "#ffd700", "goldenrod": "#daa520", "gray": "#808080", "green": "#008000", "greenyellow": "#adff2f",
+          "honeydew": "#f0fff0", "hotpink": "#ff69b4",
+          "indianred ": "#cd5c5c", "indigo": "#4b0082", "ivory": "#fffff0", "khaki": "#f0e68c",
+          "lavender": "#e6e6fa", "lavenderblush": "#fff0f5", "lawngreen": "#7cfc00", "lemonchiffon": "#fffacd", "lightblue": "#add8e6", "lightcoral": "#f08080", "lightcyan": "#e0ffff", "lightgoldenrodyellow": "#fafad2",
+          "lightgrey": "#d3d3d3", "lightgreen": "#90ee90", "lightpink": "#ffb6c1", "lightsalmon": "#ffa07a", "lightseagreen": "#20b2aa", "lightskyblue": "#87cefa", "lightslategray": "#778899", "lightsteelblue": "#b0c4de", "lightyellow": "#ffffe0", "lime": "#00ff00", "limegreen": "#32cd32", "linen": "#faf0e6",
+          "magenta": "#ff00ff", "maroon": "#800000", "mediumaquamarine": "#66cdaa", "mediumblue": "#0000cd", "mediumorchid": "#ba55d3", "mediumpurple": "#9370d8", "mediumseagreen": "#3cb371", "mediumslateblue": "#7b68ee", "mediumspringgreen": "#00fa9a", "mediumturquoise": "#48d1cc", "mediumvioletred": "#c71585", "midnightblue": "#191970", "mintcream": "#f5fffa", "mistyrose": "#ffe4e1", "moccasin": "#ffe4b5",
+          "navajowhite": "#ffdead", "navy": "#000080",
+          "oldlace": "#fdf5e6", "olive": "#808000", "olivedrab": "#6b8e23", "orange": "#ffa500", "orangered": "#ff4500", "orchid": "#da70d6",
+          "palegoldenrod": "#eee8aa", "palegreen": "#98fb98", "paleturquoise": "#afeeee", "palevioletred": "#d87093", "papayawhip": "#ffefd5", "peachpuff": "#ffdab9", "peru": "#cd853f", "pink": "#ffc0cb", "plum": "#dda0dd", "powderblue": "#b0e0e6", "purple": "#800080",
+          "rebeccapurple": "#663399", "red": "#ff0000", "rosybrown": "#bc8f8f", "royalblue": "#4169e1",
+          "saddlebrown": "#8b4513", "salmon": "#fa8072", "sandybrown": "#f4a460", "seagreen": "#2e8b57", "seashell": "#fff5ee", "sienna": "#a0522d", "silver": "#c0c0c0", "skyblue": "#87ceeb", "slateblue": "#6a5acd", "slategray": "#708090", "snow": "#fffafa", "springgreen": "#00ff7f", "steelblue": "#4682b4",
+          "tan": "#d2b48c", "teal": "#008080", "thistle": "#d8bfd8", "tomato": "#ff6347", "turquoise": "#40e0d0",
+          "violet": "#ee82ee",
+          "wheat": "#f5deb3", "white": "#ffffff", "whitesmoke": "#f5f5f5",
+          "yellow": "#ffff00", "yellowgreen": "#9acd32" };
+
+        if (typeof ch1 === "string" && cssColorNames.hasOwnProperty(ch1)) {
+          ch1 = cssColorNames[ch1];
+        }
+
+        //convert short rgb to long form
+        if (typeof ch1 === "string" && /^#[0-9A-Fa-f]{3}$/.test(ch1)) {
+          ch1 = '#' + ch1[1] + ch1[1] + ch1[2] + ch1[2] + ch1[3] + ch1[3];
+        }
+
+        if (typeof ch1 === "string" && /^#[0-9A-Fa-f]{6}$/.test(ch1)) {
+          var hex = parseInt(ch1.substr(1), 16);
+          ch1 = hex >> 16 & 255;
+          ch2 = hex >> 8 & 255;
+          ch3 = hex & 255;
+        }
+
+        if (typeof ch2 === "undefined" || typeof ch4 === "undefined" && ch1 === ch2 && ch2 === ch3) {
+          // Gray color space.
+          if (typeof ch1 === "string") {
+            color = ch1 + " " + letterArray[0];
+          } else {
+            switch (options.precision) {
+              case 2:
+                color = f2(ch1 / 255) + " " + letterArray[0];
+                break;
+              case 3:
+              default:
+                color = f3(ch1 / 255) + " " + letterArray[0];
+            }
+          }
+        } else if (typeof ch4 === "undefined" || (typeof ch4 === 'undefined' ? 'undefined' : _typeof(ch4)) === "object") {
+          // assume RGB
+          if (typeof ch1 === "string") {
+            color = [ch1, ch2, ch3, letterArray[1]].join(" ");
+          } else {
+            switch (options.precision) {
+              case 2:
+                color = [f2(ch1 / 255), f2(ch2 / 255), f2(ch3 / 255), letterArray[1]].join(" ");
+                break;
+              default:
+              case 3:
+                color = [f3(ch1 / 255), f3(ch2 / 255), f3(ch3 / 255), letterArray[1]].join(" ");
+            }
+          }
+          // assume RGBA
+          if (ch4 && ch4.a === 0) {
+            //TODO Implement transparency.
+            //WORKAROUND use white for now
+            color = ['255', '255', '255', letterArray[1]].join(" ");
+          }
+        } else {
+          // assume CMYK
+          if (typeof ch1 === 'string') {
+            color = [ch1, ch2, ch3, ch4, letterArray[2]].join(" ");
+          } else {
+            switch (options.precision) {
+              case 2:
+                color = [f2(ch1), f2(ch2), f2(ch3), f2(ch4), letterArray[2]].join(" ");
+                break;
+              case 3:
+              default:
+                color = [f3(ch1), f3(ch2), f3(ch3), f3(ch4), letterArray[2]].join(" ");
+            }
+          }
+        }
+        return color;
+      },
+          convertDateToPDFDate = function convertDateToPDFDate(parmDate) {
+        var padd2 = function padd2(number) {
+          return ('0' + parseInt(number)).slice(-2);
+        };
+        var result = '';
+        var tzoffset = parmDate.getTimezoneOffset(),
+            tzsign = tzoffset < 0 ? '+' : '-',
+            tzhour = Math.floor(Math.abs(tzoffset / 60)),
+            tzmin = Math.abs(tzoffset % 60),
+            timeZoneString = [tzsign, padd2(tzhour), "'", padd2(tzmin), "'"].join('');
+
+        result = ['D:', parmDate.getFullYear(), padd2(parmDate.getMonth() + 1), padd2(parmDate.getDate()), padd2(parmDate.getHours()), padd2(parmDate.getMinutes()), padd2(parmDate.getSeconds()), timeZoneString].join('');
+        return result;
+      },
+          convertPDFDateToDate = function convertPDFDateToDate(parmPDFDate) {
+        var year = parseInt(parmPDFDate.substr(2, 4), 10);
+        var month = parseInt(parmPDFDate.substr(6, 2), 10) - 1;
+        var date = parseInt(parmPDFDate.substr(8, 2), 10);
+        var hour = parseInt(parmPDFDate.substr(10, 2), 10);
+        var minutes = parseInt(parmPDFDate.substr(12, 2), 10);
+        var seconds = parseInt(parmPDFDate.substr(14, 2), 10);
+        var timeZoneHour = parseInt(parmPDFDate.substr(16, 2), 10);
+        var timeZoneMinutes = parseInt(parmPDFDate.substr(20, 2), 10);
+
+        var resultingDate = new Date(year, month, date, hour, minutes, seconds, 0);
+        return resultingDate;
+      },
+          setCreationDate = function setCreationDate(date) {
+        var tmpCreationDateString;
+        var regexPDFCreationDate = /^D:(20[0-2][0-9]|203[0-7]|19[7-9][0-9])(0[0-9]|1[0-2])([0-2][0-9]|3[0-1])(0[0-9]|1[0-9]|2[0-3])(0[0-9]|[1-5][0-9])(0[0-9]|[1-5][0-9])(\+0[0-9]|\+1[0-4]|\-0[0-9]|\-1[0-1])\'(0[0-9]|[1-5][0-9])\'?$/;
+        if ((typeof date === 'undefined' ? 'undefined' : _typeof(date)) === undefined) {
+          date = new Date();
+        }
+
+        if ((typeof date === 'undefined' ? 'undefined' : _typeof(date)) === "object" && Object.prototype.toString.call(date) === "[object Date]") {
+          tmpCreationDateString = convertDateToPDFDate(date);
+        } else if (regexPDFCreationDate.test(date)) {
+          tmpCreationDateString = date;
+        } else {
+          tmpCreationDateString = convertDateToPDFDate(new Date());
+        }
+        creationDate = tmpCreationDateString;
+        return creationDate;
+      },
+          getCreationDate = function getCreationDate(type) {
+        var result = creationDate;
+        if (type === "jsDate") {
+          result = convertPDFDateToDate(creationDate);
+        }
+        return result;
+      },
+          setFileId = function setFileId(value) {
+        value = value || "12345678901234567890123456789012".split('').map(function () {
+          return "ABCDEF0123456789".charAt(Math.floor(Math.random() * 16));
+        }).join('');
+        fileId = value;
+        return fileId;
+      },
+          getFileId = function getFileId() {
+        return fileId;
+      },
+          f2 = function f2(number) {
+        return number.toFixed(2); // Ie, %.2f
+      },
+          f3 = function f3(number) {
+        return number.toFixed(3); // Ie, %.3f
+      },
+          out = function out(string) {
+        string = typeof string === "string" ? string : string.toString();
+        if (outToPages) {
+          /* set by beginPage */
+          pages[currentPage].push(string);
+        } else {
+          // +1 for '\n' that will be used to join 'content'
+          content_length += string.length + 1;
+          content.push(string);
+        }
+      },
+          newObject = function newObject() {
+        // Begin a new object
+        objectNumber++;
+        offsets[objectNumber] = content_length;
+        out(objectNumber + ' 0 obj');
+        return objectNumber;
+      },
+
+      // Does not output the object until after the pages have been output.
+      // Returns an object containing the objectId and content.
+      // All pages have been added so the object ID can be estimated to start right after.
+      // This does not modify the current objectNumber;  It must be updated after the newObjects are output.
+      newAdditionalObject = function newAdditionalObject() {
+        var objId = pages.length * 2 + 1;
+        objId += additionalObjects.length;
+        var obj = {
+          objId: objId,
+          content: ''
+        };
+        additionalObjects.push(obj);
+        return obj;
+      },
+
+      // Does not output the object.  The caller must call newObjectDeferredBegin(oid) before outputing any data
+      newObjectDeferred = function newObjectDeferred() {
+        objectNumber++;
+        offsets[objectNumber] = function () {
+          return content_length;
+        };
+        return objectNumber;
+      },
+          newObjectDeferredBegin = function newObjectDeferredBegin(oid) {
+        offsets[oid] = content_length;
+      },
+          putStream = function putStream(str) {
+        out('stream');
+        out(str);
+        out('endstream');
+      },
+          putPages = function putPages() {
+        var n,
+            p,
+            arr,
+            i,
+            deflater,
+            adler32,
+            adler32cs,
+            wPt,
+            hPt,
+            pageObjectNumbers = [];
+
+        adler32cs = global.adler32cs || jsPDF.API.adler32cs;
+        if (compress && typeof adler32cs === 'undefined') {
+          compress = false;
+        }
+
+        // outToPages = false as set in endDocument(). out() writes to content.
+
+        for (n = 1; n <= page; n++) {
+          pageObjectNumbers.push(newObject());
+          wPt = (pageWidth = pagedim[n].width) * k;
+          hPt = (pageHeight = pagedim[n].height) * k;
+          out('<</Type /Page');
+          out('/Parent 1 0 R');
+          out('/Resources 2 0 R');
+          out('/MediaBox [0 0 ' + f2(wPt) + ' ' + f2(hPt) + ']');
+          // Added for annotation plugin
+          events.publish('putPage', {
+            pageNumber: n,
+            page: pages[n]
+          });
+          out('/Contents ' + (objectNumber + 1) + ' 0 R');
+          out('>>');
+          out('endobj');
+
+          // Page content
+          p = pages[n].join('\n');
+          newObject();
+          if (compress) {
+            arr = [];
+            i = p.length;
+            while (i--) {
+              arr[i] = p.charCodeAt(i);
+            }
+            adler32 = adler32cs.from(p);
+            deflater = new Deflater(6);
+            deflater.append(new Uint8Array(arr));
+            p = deflater.flush();
+            arr = new Uint8Array(p.length + 6);
+            arr.set(new Uint8Array([120, 156])), arr.set(p, 2);
+            arr.set(new Uint8Array([adler32 & 0xFF, adler32 >> 8 & 0xFF, adler32 >> 16 & 0xFF, adler32 >> 24 & 0xFF]), p.length + 2);
+            p = String.fromCharCode.apply(null, arr);
+            out('<</Length ' + p.length + ' /Filter [/FlateDecode]>>');
+          } else {
+            out('<</Length ' + p.length + '>>');
+          }
+          putStream(p);
+          out('endobj');
+        }
+        offsets[1] = content_length;
+        out('1 0 obj');
+        out('<</Type /Pages');
+        var kids = '/Kids [';
+        for (i = 0; i < page; i++) {
+          kids += pageObjectNumbers[i] + ' 0 R ';
+        }
+        out(kids + ']');
+        out('/Count ' + page);
+        out('>>');
+        out('endobj');
+        events.publish('postPutPages');
+      },
+          putFont = function putFont(font) {
+
+        events.publish('putFont', {
+          font: font,
+          out: out,
+          newObject: newObject
+        });
+        if (font.isAlreadyPutted !== true) {
+          font.objectNumber = newObject();
+          out('<<');
+          out('/Type /Font');
+          out('/BaseFont /' + font.postScriptName);
+          out('/Subtype /Type1');
+          if (typeof font.encoding === 'string') {
+            out('/Encoding /' + font.encoding);
+          }
+          out('/FirstChar 32');
+          out('/LastChar 255');
+          out('>>');
+          out('endobj');
+        }
+      },
+          putFonts = function putFonts() {
+        for (var fontKey in fonts) {
+          if (fonts.hasOwnProperty(fontKey)) {
+            putFont(fonts[fontKey]);
+          }
+        }
+      },
+          putXobjectDict = function putXobjectDict() {
+        // Loop through images, or other data objects
+        events.publish('putXobjectDict');
+      },
+          putResourceDictionary = function putResourceDictionary() {
+        out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
+        out('/Font <<');
+
+        // Do this for each font, the '1' bit is the index of the font
+        for (var fontKey in fonts) {
+          if (fonts.hasOwnProperty(fontKey)) {
+            out('/' + fontKey + ' ' + fonts[fontKey].objectNumber + ' 0 R');
+          }
+        }
+        out('>>');
+        out('/XObject <<');
+        putXobjectDict();
+        out('>>');
+      },
+          putResources = function putResources() {
+        putFonts();
+        events.publish('putResources');
+        // Resource dictionary
+        offsets[2] = content_length;
+        out('2 0 obj');
+        out('<<');
+        putResourceDictionary();
+        out('>>');
+        out('endobj');
+        events.publish('postPutResources');
+      },
+          putAdditionalObjects = function putAdditionalObjects() {
+        events.publish('putAdditionalObjects');
+        for (var i = 0; i < additionalObjects.length; i++) {
+          var obj = additionalObjects[i];
+          offsets[obj.objId] = content_length;
+          out(obj.objId + ' 0 obj');
+          out(obj.content);        out('endobj');
+        }
+        objectNumber += additionalObjects.length;
+        events.publish('postPutAdditionalObjects');
+      },
+          addToFontDictionary = function addToFontDictionary(fontKey, fontName, fontStyle) {
+        // this is mapping structure for quick font key lookup.
+        // returns the KEY of the font (ex: "F1") for a given
+        // pair of font name and type (ex: "Arial". "Italic")
+        if (!fontmap.hasOwnProperty(fontName)) {
+          fontmap[fontName] = {};
+        }
+        fontmap[fontName][fontStyle] = fontKey;
+      },
+
+      /**
+       * FontObject describes a particular font as member of an instnace of jsPDF
+       *
+       * It's a collection of properties like 'id' (to be used in PDF stream),
+       * 'fontName' (font's family name), 'fontStyle' (font's style variant label)
+       *
+       * @class
+       * @public
+       * @property id {String} PDF-document-instance-specific label assinged to the font.
+       * @property postScriptName {String} PDF specification full name for the font
+       * @property encoding {Object} Encoding_name-to-Font_metrics_object mapping.
+       * @name FontObject
+       * @ignore This should not be in the public docs.
+       */
+      addFont = function addFont(postScriptName, fontName, fontStyle, encoding) {
+        var fontKey = 'F' + (Object.keys(fonts).length + 1).toString(10),
+
+        // This is FontObject
+        font = fonts[fontKey] = {
+          'id': fontKey,
+          'postScriptName': postScriptName,
+          'fontName': fontName,
+          'fontStyle': fontStyle,
+          'encoding': encoding,
+          'metadata': {}
+        };
+        addToFontDictionary(fontKey, fontName, fontStyle);
+        events.publish('addFont', font);
+
+        return fontKey;
+      },
+          addFonts = function addFonts() {
+
+        var HELVETICA = "helvetica",
+            TIMES = "times",
+            COURIER = "courier",
+            NORMAL = "normal",
+            BOLD = "bold",
+            ITALIC = "italic",
+            BOLD_ITALIC = "bolditalic",
+            ZAPF = "zapfdingbats",
+            SYMBOL = "symbol",
+            standardFonts = [['Helvetica', HELVETICA, NORMAL, 'WinAnsiEncoding'], ['Helvetica-Bold', HELVETICA, BOLD, 'WinAnsiEncoding'], ['Helvetica-Oblique', HELVETICA, ITALIC, 'WinAnsiEncoding'], ['Helvetica-BoldOblique', HELVETICA, BOLD_ITALIC, 'WinAnsiEncoding'], ['Courier', COURIER, NORMAL, 'WinAnsiEncoding'], ['Courier-Bold', COURIER, BOLD, 'WinAnsiEncoding'], ['Courier-Oblique', COURIER, ITALIC, 'WinAnsiEncoding'], ['Courier-BoldOblique', COURIER, BOLD_ITALIC, 'WinAnsiEncoding'], ['Times-Roman', TIMES, NORMAL, 'WinAnsiEncoding'], ['Times-Bold', TIMES, BOLD, 'WinAnsiEncoding'], ['Times-Italic', TIMES, ITALIC, 'WinAnsiEncoding'], ['Times-BoldItalic', TIMES, BOLD_ITALIC, 'WinAnsiEncoding'], ['ZapfDingbats', ZAPF, NORMAL, null], ['Symbol', SYMBOL, NORMAL, null]];
+
+        for (var i = 0, l = standardFonts.length; i < l; i++) {
+          var fontKey = addFont(standardFonts[i][0], standardFonts[i][1], standardFonts[i][2], standardFonts[i][3]);
+
+          // adding aliases for standard fonts, this time matching the capitalization
+          var parts = standardFonts[i][0].split('-');
+          addToFontDictionary(fontKey, parts[0], parts[1] || '');
+        }
+        events.publish('addFonts', {
+          fonts: fonts,
+          dictionary: fontmap
+        });
+      },
+          SAFE = function __safeCall(fn) {
+        fn.foo = function __safeCallWrapper() {
+          try {
+            return fn.apply(this, arguments);
+          } catch (e) {
+            var stack = e.stack || '';
+            if (~stack.indexOf(' at ')) stack = stack.split(" at ")[1];
+            var m = "Error in function " + stack.split("\n")[0].split('<')[0] + ": " + e.message;
+            if (global.console) {
+              global.console.error(m, e);
+              if (global.alert) alert(m);
+            } else {
+              throw new Error(m);
+            }
+          }
+        };
+        fn.foo.bar = fn;
+        return fn.foo;
+      },
+          to8bitStream = function to8bitStream(text, flags) {
+        /**
+         * PDF 1.3 spec:
+         * "For text strings encoded in Unicode, the first two bytes must be 254 followed by
+         * 255, representing the Unicode byte order marker, U+FEFF. (This sequence conflicts
+         * with the PDFDocEncoding character sequence thorn ydieresis, which is unlikely
+         * to be a meaningful beginning of a word or phrase.) The remainder of the
+         * string consists of Unicode character codes, according to the UTF-16 encoding
+         * specified in the Unicode standard, version 2.0. Commonly used Unicode values
+         * are represented as 2 bytes per character, with the high-order byte appearing first
+         * in the string."
+         *
+         * In other words, if there are chars in a string with char code above 255, we
+         * recode the string to UCS2 BE - string doubles in length and BOM is prepended.
+         *
+         * HOWEVER!
+         * Actual *content* (body) text (as opposed to strings used in document properties etc)
+         * does NOT expect BOM. There, it is treated as a literal GID (Glyph ID)
+         *
+         * Because of Adobe's focus on "you subset your fonts!" you are not supposed to have
+         * a font that maps directly Unicode (UCS2 / UTF16BE) code to font GID, but you could
+         * fudge it with "Identity-H" encoding and custom CIDtoGID map that mimics Unicode
+         * code page. There, however, all characters in the stream are treated as GIDs,
+         * including BOM, which is the reason we need to skip BOM in content text (i.e. that
+         * that is tied to a font).
+         *
+         * To signal this "special" PDFEscape / to8bitStream handling mode,
+         * API.text() function sets (unless you overwrite it with manual values
+         * given to API.text(.., flags) )
+         * flags.autoencode = true
+         * flags.noBOM = true
+         *
+         * ===================================================================================
+         * `flags` properties relied upon:
+         *   .sourceEncoding = string with encoding label.
+         *                     "Unicode" by default. = encoding of the incoming text.
+         *                     pass some non-existing encoding name
+         *                     (ex: 'Do not touch my strings! I know what I am doing.')
+         *                     to make encoding code skip the encoding step.
+         *   .outputEncoding = Either valid PDF encoding name
+         *                     (must be supported by jsPDF font metrics, otherwise no encoding)
+         *                     or a JS object, where key = sourceCharCode, value = outputCharCode
+         *                     missing keys will be treated as: sourceCharCode === outputCharCode
+         *   .noBOM
+         *       See comment higher above for explanation for why this is important
+         *   .autoencode
+         *       See comment higher above for explanation for why this is important
+         */
+
+        var i, l, sourceEncoding, encodingBlock, outputEncoding, newtext, isUnicode, ch, bch;
+
+        flags = flags || {};
+        sourceEncoding = flags.sourceEncoding || 'Unicode';
+        outputEncoding = flags.outputEncoding;
+
+        // This 'encoding' section relies on font metrics format
+        // attached to font objects by, among others,
+        // "Willow Systems' standard_font_metrics plugin"
+        // see jspdf.plugin.standard_font_metrics.js for format
+        // of the font.metadata.encoding Object.
+        // It should be something like
+        //   .encoding = {'codePages':['WinANSI....'], 'WinANSI...':{code:code, ...}}
+        //   .widths = {0:width, code:width, ..., 'fof':divisor}
+        //   .kerning = {code:{previous_char_code:shift, ..., 'fof':-divisor},...}
+        if ((flags.autoencode || outputEncoding) && fonts[activeFontKey].metadata && fonts[activeFontKey].metadata[sourceEncoding] && fonts[activeFontKey].metadata[sourceEncoding].encoding) {
+          encodingBlock = fonts[activeFontKey].metadata[sourceEncoding].encoding;
+
+          // each font has default encoding. Some have it clearly defined.
+          if (!outputEncoding && fonts[activeFontKey].encoding) {
+            outputEncoding = fonts[activeFontKey].encoding;
+          }
+
+          // Hmmm, the above did not work? Let's try again, in different place.
+          if (!outputEncoding && encodingBlock.codePages) {
+            outputEncoding = encodingBlock.codePages[0]; // let's say, first one is the default
+          }
+
+          if (typeof outputEncoding === 'string') {
+            outputEncoding = encodingBlock[outputEncoding];
+          }
+          // we want output encoding to be a JS Object, where
+          // key = sourceEncoding's character code and
+          // value = outputEncoding's character code.
+          if (outputEncoding) {
+            isUnicode = false;
+            newtext = [];
+            for (i = 0, l = text.length; i < l; i++) {
+              ch = outputEncoding[text.charCodeAt(i)];
+              if (ch) {
+                newtext.push(String.fromCharCode(ch));
+              } else {
+                newtext.push(text[i]);
+              }
+
+              // since we are looping over chars anyway, might as well
+              // check for residual unicodeness
+              if (newtext[i].charCodeAt(0) >> 8) {
+                /* more than 255 */
+                isUnicode = true;
+              }
+            }
+            text = newtext.join('');
+          }
+        }
+
+        i = text.length;
+        // isUnicode may be set to false above. Hence the triple-equal to undefined
+        while (isUnicode === undefined && i !== 0) {
+          if (text.charCodeAt(i - 1) >> 8) {
+            /* more than 255 */
+            isUnicode = true;
+          }
+          i--;
+        }
+        if (!isUnicode) {
+          return text;
+        }
+
+        newtext = flags.noBOM ? [] : [254, 255];
+        for (i = 0, l = text.length; i < l; i++) {
+          ch = text.charCodeAt(i);
+          bch = ch >> 8; // divide by 256
+          if (bch >> 8) {
+            /* something left after dividing by 256 second time */
+            throw new Error("Character at position " + i + " of string '" + text + "' exceeds 16bits. Cannot be encoded into UCS-2 BE");
+          }
+          newtext.push(bch);
+          newtext.push(ch - (bch << 8));
+        }
+        return String.fromCharCode.apply(undefined, newtext);
+      },
+          pdfEscape = function pdfEscape(text, flags) {
+        /**
+         * Replace '/', '(', and ')' with pdf-safe versions
+         *
+         * Doing to8bitStream does NOT make this PDF display unicode text. For that
+         * we also need to reference a unicode font and embed it - royal pain in the rear.
+         *
+         * There is still a benefit to to8bitStream - PDF simply cannot handle 16bit chars,
+         * which JavaScript Strings are happy to provide. So, while we still cannot display
+         * 2-byte characters property, at least CONDITIONALLY converting (entire string containing)
+         * 16bit chars to (USC-2-BE) 2-bytes per char + BOM streams we ensure that entire PDF
+         * is still parseable.
+         * This will allow immediate support for unicode in document properties strings.
+         */
+        return to8bitStream(text, flags).replace(/\\/g, '\\\\').replace(/\(/g, '\\(').replace(/\)/g, '\\)');
+      },
+          putInfo = function putInfo() {
+        out('/Producer (jsPDF ' + jsPDF.version + ')');
+        for (var key in documentProperties) {
+          if (documentProperties.hasOwnProperty(key) && documentProperties[key]) {
+            out('/' + key.substr(0, 1).toUpperCase() + key.substr(1) + ' (' + pdfEscape(documentProperties[key]) + ')');
+          }
+        }
+        out('/CreationDate (' + creationDate + ')');
+      },
+          putCatalog = function putCatalog() {
+        out('/Type /Catalog');
+        out('/Pages 1 0 R');
+        // PDF13ref Section 7.2.1
+        if (!zoomMode) zoomMode = 'fullwidth';
+        switch (zoomMode) {
+          case 'fullwidth':
+            out('/OpenAction [3 0 R /FitH null]');
+            break;
+          case 'fullheight':
+            out('/OpenAction [3 0 R /FitV null]');
+            break;
+          case 'fullpage':
+            out('/OpenAction [3 0 R /Fit]');
+            break;
+          case 'original':
+            out('/OpenAction [3 0 R /XYZ null null 1]');
+            break;
+          default:
+            var pcn = '' + zoomMode;
+            if (pcn.substr(pcn.length - 1) === '%') zoomMode = parseInt(zoomMode) / 100;
+            if (typeof zoomMode === 'number') {
+              out('/OpenAction [3 0 R /XYZ null null ' + f2(zoomMode) + ']');
+            }
+        }
+        if (!layoutMode) layoutMode = 'continuous';
+        switch (layoutMode) {
+          case 'continuous':
+            out('/PageLayout /OneColumn');
+            break;
+          case 'single':
+            out('/PageLayout /SinglePage');
+            break;
+          case 'two':
+          case 'twoleft':
+            out('/PageLayout /TwoColumnLeft');
+            break;
+          case 'tworight':
+            out('/PageLayout /TwoColumnRight');
+            break;
+        }
+        if (pageMode) {
+          /**
+           * A name object specifying how the document should be displayed when opened:
+           * UseNone      : Neither document outline nor thumbnail images visible -- DEFAULT
+           * UseOutlines  : Document outline visible
+           * UseThumbs    : Thumbnail images visible
+           * FullScreen   : Full-screen mode, with no menu bar, window controls, or any other window visible
+           */
+          out('/PageMode /' + pageMode);
+        }
+        events.publish('putCatalog');
+      },
+          putTrailer = function putTrailer() {
+        out('/Size ' + (objectNumber + 1));
+        out('/Root ' + objectNumber + ' 0 R');
+        out('/Info ' + (objectNumber - 1) + ' 0 R');
+        out("/ID [ <" + fileId + "> <" + fileId + "> ]");
+      },
+          beginPage = function beginPage(width, height) {
+        // Dimensions are stored as user units and converted to points on output
+        var orientation = typeof height === 'string' && height.toLowerCase();
+        if (typeof width === 'string') {
+          var format = width.toLowerCase();
+          if (pageFormats.hasOwnProperty(format)) {
+            width = pageFormats[format][0] / k;
+            height = pageFormats[format][1] / k;
+          }
+        }
+        if (Array.isArray(width)) {
+          height = width[1];
+          width = width[0];
+        }
+        if (orientation) {
+          switch (orientation.substr(0, 1)) {
+            case 'l':
+              if (height > width) orientation = 's';
+              break;
+            case 'p':
+              if (width > height) orientation = 's';
+              break;
+          }
+          if (orientation === 's') {
+            tmp = width;
+            width = height;
+            height = tmp;
+          }
+        }
+        outToPages = true;
+        pages[++page] = [];
+        pagedim[page] = {
+          width: Number(width) || pageWidth,
+          height: Number(height) || pageHeight
+        };
+        pagesContext[page] = {};
+        _setPage(page);
+      },
+          _addPage = function _addPage() {
+        beginPage.apply(this, arguments);
+        // Set line width
+        out(f2(lineWidth * k) + ' w');
+        // Set draw color
+        out(drawColor);
+        // resurrecting non-default line caps, joins
+        if (lineCapID !== 0) {
+          out(lineCapID + ' J');
+        }
+        if (lineJoinID !== 0) {
+          out(lineJoinID + ' j');
+        }
+        events.publish('addPage', {
+          pageNumber: page
+        });
+      },
+          _deletePage = function _deletePage(n) {
+        if (n > 0 && n <= page) {
+          pages.splice(n, 1);
+          pagedim.splice(n, 1);
+          page--;
+          if (currentPage > page) {
+            currentPage = page;
+          }
+          this.setPage(currentPage);
+        }
+      },
+          _setPage = function _setPage(n) {
+        if (n > 0 && n <= page) {
+          currentPage = n;
+          pageWidth = pagedim[n].width;
+          pageHeight = pagedim[n].height;
+        }
+      },
+
+      /**
+       * Returns a document-specific font key - a label assigned to a
+       * font name + font type combination at the time the font was added
+       * to the font inventory.
+       *
+       * Font key is used as label for the desired font for a block of text
+       * to be added to the PDF document stream.
+       * @private
+       * @function
+       * @param fontName {String} can be undefined on "falthy" to indicate "use current"
+       * @param fontStyle {String} can be undefined on "falthy" to indicate "use current"
+       * @returns {String} Font key.
+       */
+      _getFont = function _getFont(fontName, fontStyle) {
+        var key, fontNameLowerCase;
+
+        fontName = fontName !== undefined ? fontName : fonts[activeFontKey].fontName;
+        fontStyle = fontStyle !== undefined ? fontStyle : fonts[activeFontKey].fontStyle;
+        fontNameLowerCase = fontName.toLowerCase();
+
+        if (fontmap[fontNameLowerCase] !== undefined && fontmap[fontNameLowerCase][fontStyle] !== undefined) {
+          key = fontmap[fontNameLowerCase][fontStyle];
+        } else if (fontmap[fontName] !== undefined && fontmap[fontName][fontStyle] !== undefined) {
+          key = fontmap[fontName][fontStyle];
+        } else {
+          console.warn("Unable to look up font label for font '" + fontName + "', '" + fontStyle + "'. Refer to getFontList() for available fonts.");
+        }
+
+        if (!key) {
+          //throw new Error();
+          key = fontmap['times'][fontStyle];
+          if (key == null) {
+            key = fontmap['times']['normal'];
+          }
+        }
+        return key;
+      },
+          buildDocument = function buildDocument() {
+        outToPages = false; // switches out() to content
+
+        objectNumber = 2;
+        content_length = 0;
+        content = [];
+        offsets = [];
+        additionalObjects = [];
+        // Added for AcroForm
+        events.publish('buildDocument');
+
+        // putHeader()
+        out('%PDF-' + pdfVersion);
+        out("%\xBA\xDF\xAC\xE0");
+
+        putPages();
+
+        // Must happen after putPages
+        // Modifies current object Id
+        putAdditionalObjects();
+
+        putResources();
+
+        // Info
+        newObject();
+        out('<<');
+        putInfo();
+        out('>>');
+        out('endobj');
+
+        // Catalog
+        newObject();
+        out('<<');
+        putCatalog();
+        out('>>');
+        out('endobj');
+
+        // Cross-ref
+        var o = content_length,
+            i,
+            p = "0000000000";
+        out('xref');
+        out('0 ' + (objectNumber + 1));
+        out(p + ' 65535 f ');
+        for (i = 1; i <= objectNumber; i++) {
+          var offset = offsets[i];
+          if (typeof offset === 'function') {
+            out((p + offsets[i]()).slice(-10) + ' 00000 n ');
+          } else {
+            out((p + offsets[i]).slice(-10) + ' 00000 n ');
+          }
+        }
+        // Trailer
+        out('trailer');
+        out('<<');
+        putTrailer();
+        out('>>');
+        out('startxref');
+        out('' + o);
+        out('%%EOF');
+
+        outToPages = true;
+
+        return content.join('\n');
+      },
+          getStyle = function getStyle(style) {
+        // see path-painting operators in PDF spec
+        var op = 'S'; // stroke
+        if (style === 'F') {
+          op = 'f'; // fill
+        } else if (style === 'FD' || style === 'DF') {
+          op = 'B'; // both
+        } else if (style === 'f' || style === 'f*' || style === 'B' || style === 'B*') {
+          /*
+           Allow direct use of these PDF path-painting operators:
+           - f    fill using nonzero winding number rule
+           - f*    fill using even-odd rule
+           - B    fill then stroke with fill using non-zero winding number rule
+           - B*    fill then stroke with fill using even-odd rule
+           */
+          op = style;
+        }
+        return op;
+      },
+          getArrayBuffer = function getArrayBuffer() {
+        var data = buildDocument(),
+            len = data.length,
+            ab = new ArrayBuffer(len),
+            u8 = new Uint8Array(ab);
+
+        while (len--) {
+          u8[len] = data.charCodeAt(len);
+        }return ab;
+      },
+          getBlob = function getBlob() {
+        return new Blob([getArrayBuffer()], {
+          type: "application/pdf"
+        });
+      },
+
+      /**
+       * Generates the PDF document.
+       *
+       * If `type` argument is undefined, output is raw body of resulting PDF returned as a string.
+       *
+       * @param {String} type A string identifying one of the possible output types.
+       * @param {Object} options An object providing some additional signalling to PDF generator.
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name output
+       */
+      _output = SAFE(function (type, options) {
+        var datauri = ('' + type).substr(0, 6) === 'dataur' ? 'data:application/pdf;base64,' + btoa(buildDocument()) : 0;
+
+        switch (type) {
+          case undefined:
+            return buildDocument();
+          case 'save':
+            if ((typeof navigator === 'undefined' ? 'undefined' : _typeof(navigator)) === "object" && navigator.getUserMedia) {
+              if (global.URL === undefined || global.URL.createObjectURL === undefined) {
+                return API.output('dataurlnewwindow');
+              }
+            }
+            saveAs(getBlob(), options);
+            if (typeof saveAs.unload === 'function') {
+              if (global.setTimeout) {
+                setTimeout(saveAs.unload, 911);
+              }
+            }
+            break;
+          case 'arraybuffer':
+            return getArrayBuffer();
+          case 'blob':
+            return getBlob();
+          case 'bloburi':
+          case 'bloburl':
+            // User is responsible of calling revokeObjectURL
+            return global.URL && global.URL.createObjectURL(getBlob()) || void 0;
+          case 'datauristring':
+          case 'dataurlstring':
+            return datauri;
+          case 'dataurlnewwindow':
+            var nW = global.open(datauri);
+            if (nW || typeof safari === "undefined") return nW;
+          /* pass through */
+          case 'datauri':
+          case 'dataurl':
+            return global.document.location.href = datauri;
+          default:
+            throw new Error('Output type "' + type + '" is not supported.');
+        }
+        // @TODO: Add different output options
+      }),
+
+
+      /**
+       * Used to see if a supplied hotfix was requested when the pdf instance was created.
+       * @param {String} hotfixName - The name of the hotfix to check.
+       * @returns {boolean}
+       */
+      hasHotfix = function hasHotfix(hotfixName) {
+        return Array.isArray(hotfixes) === true && hotfixes.indexOf(hotfixName) > -1;
+      };
+
+      switch (unit) {
+        case 'pt':
+          k = 1;
+          break;
+        case 'mm':
+          k = 72 / 25.4;
+          break;
+        case 'cm':
+          k = 72 / 2.54;
+          break;
+        case 'in':
+          k = 72;
+          break;
+        case 'px':
+          if (hasHotfix('px_scaling') == true) {
+            k = 72 / 96;
+          } else {
+            k = 96 / 72;
+          }
+          break;
+        case 'pc':
+          k = 12;
+          break;
+        case 'em':
+          k = 12;
+          break;
+        case 'ex':
+          k = 6;
+          break;
+        default:
+          throw 'Invalid unit: ' + unit;
+      }
+
+      setCreationDate();
+      setFileId();
+
+      //---------------------------------------
+      // Public API
+
+      /**
+       * Object exposing internal API to plugins
+       * @public
+       */
+      API.internal = {
+        'pdfEscape': pdfEscape,
+        'getStyle': getStyle,
+        /**
+         * Returns {FontObject} describing a particular font.
+         * @public
+         * @function
+         * @param fontName {String} (Optional) Font's family name
+         * @param fontStyle {String} (Optional) Font's style variation name (Example:"Italic")
+         * @returns {FontObject}
+         */
+        'getFont': function getFont() {
+          return fonts[_getFont.apply(API, arguments)];
+        },
+        'getFontSize': function getFontSize() {
+          return activeFontSize;
+        },
+        'getCharSpace': function getCharSpace() {
+          return activeCharSpace;
+        },
+        'getTextColor': function getTextColor() {
+          var colorEncoded = textColor.split(' ');
+          if (colorEncoded.length === 2 && colorEncoded[1] === 'g') {
+            // convert grayscale value to rgb so that it can be converted to hex for consistency
+            var floatVal = parseFloat(colorEncoded[0]);
+            colorEncoded = [floatVal, floatVal, floatVal, 'r'];
+          }
+          var colorAsHex = '#';
+          for (var i = 0; i < 3; i++) {
+            colorAsHex += ('0' + Math.floor(parseFloat(colorEncoded[i]) * 255).toString(16)).slice(-2);
+          }
+          return colorAsHex;
+        },
+        'getLineHeight': function getLineHeight() {
+          return activeFontSize * lineHeightProportion;
+        },
+        'write': function write(string1 /*, string2, string3, etc */) {
+          out(arguments.length === 1 ? string1 : Array.prototype.join.call(arguments, ' '));
+        },
+        'getCoordinateString': function getCoordinateString(value) {
+          return f2(value * k);
+        },
+        'getVerticalCoordinateString': function getVerticalCoordinateString(value) {
+          return f2((pageHeight - value) * k);
+        },
+        'collections': {},
+        'newObject': newObject,
+        'newAdditionalObject': newAdditionalObject,
+        'newObjectDeferred': newObjectDeferred,
+        'newObjectDeferredBegin': newObjectDeferredBegin,
+        'putStream': putStream,
+        'events': events,
+        // ratio that you use in multiplication of a given "size" number to arrive to 'point'
+        // units of measurement.
+        // scaleFactor is set at initialization of the document and calculated against the stated
+        // default measurement units for the document.
+        // If default is "mm", k is the number that will turn number in 'mm' into 'points' number.
+        // through multiplication.
+        'scaleFactor': k,
+        'pageSize': {
+          getWidth: function getWidth() {
+            return pageWidth;
+          },
+          getHeight: function getHeight() {
+            return pageHeight;
+          }
+        },
+        'output': function output(type, options) {
+          return _output(type, options);
+        },
+        'getNumberOfPages': function getNumberOfPages() {
+          return pages.length - 1;
+        },
+        'pages': pages,
+        'out': out,
+        'f2': f2,
+        'getPageInfo': function getPageInfo(pageNumberOneBased) {
+          var objId = (pageNumberOneBased - 1) * 2 + 3;
+          return {
+            objId: objId,
+            pageNumber: pageNumberOneBased,
+            pageContext: pagesContext[pageNumberOneBased]
+          };
+        },
+        'getCurrentPageInfo': function getCurrentPageInfo() {
+          var objId = (currentPage - 1) * 2 + 3;
+          return {
+            objId: objId,
+            pageNumber: currentPage,
+            pageContext: pagesContext[currentPage]
+          };
+        },
+        'getPDFVersion': function getPDFVersion() {
+          return pdfVersion;
+        },
+        'hasHotfix': hasHotfix //Expose the hasHotfix check so plugins can also check them.
+      };
+
+      /**
+       * Adds (and transfers the focus to) new page to the PDF document.
+       * @param format {String/Array} The format of the new page. Can be <ul><li>a0 - a10</li><li>b0 - b10</li><li>c0 - c10</li><li>c0 - c10</li><li>dl</li><li>letter</li><li>government-letter</li><li>legal</li><li>junior-legal</li><li>ledger</li><li>tabloid</li><li>credit-card</li></ul><br />
+       * Default is "a4". If you want to use your own format just pass instead of one of the above predefined formats the size as an number-array , e.g. [595.28, 841.89]
+       * @param orientation {String} Orientation of the new page. Possible values are "portrait" or "landscape" (or shortcuts "p" (Default), "l") 
+       * @function
+       * @returns {jsPDF}
+       *
+       * @methodOf jsPDF#
+       * @name addPage
+       */
+      API.addPage = function () {
+        _addPage.apply(this, arguments);
+        return this;
+      };
+      /**
+       * Adds (and transfers the focus to) new page to the PDF document.
+       * @function
+       * @returns {jsPDF}
+       *
+       * @methodOf jsPDF#
+       * @name setPage
+       * @param {Number} page Switch the active page to the page number specified
+       * @example
+       * doc = jsPDF()
+       * doc.addPage()
+       * doc.addPage()
+       * doc.text('I am on page 3', 10, 10)
+       * doc.setPage(1)
+       * doc.text('I am on page 1', 10, 10)
+       */
+      API.setPage = function () {
+        _setPage.apply(this, arguments);
+        return this;
+      };
+      API.insertPage = function (beforePage) {
+        this.addPage();
+        this.movePage(currentPage, beforePage);
+        return this;
+      };
+      API.movePage = function (targetPage, beforePage) {
+        if (targetPage > beforePage) {
+          var tmpPages = pages[targetPage];
+          var tmpPagedim = pagedim[targetPage];
+          var tmpPagesContext = pagesContext[targetPage];
+          for (var i = targetPage; i > beforePage; i--) {
+            pages[i] = pages[i - 1];
+            pagedim[i] = pagedim[i - 1];
+            pagesContext[i] = pagesContext[i - 1];
+          }
+          pages[beforePage] = tmpPages;
+          pagedim[beforePage] = tmpPagedim;
+          pagesContext[beforePage] = tmpPagesContext;
+          this.setPage(beforePage);
+        } else if (targetPage < beforePage) {
+          var tmpPages = pages[targetPage];
+          var tmpPagedim = pagedim[targetPage];
+          var tmpPagesContext = pagesContext[targetPage];
+          for (var i = targetPage; i < beforePage; i++) {
+            pages[i] = pages[i + 1];
+            pagedim[i] = pagedim[i + 1];
+            pagesContext[i] = pagesContext[i + 1];
+          }
+          pages[beforePage] = tmpPages;
+          pagedim[beforePage] = tmpPagedim;
+          pagesContext[beforePage] = tmpPagesContext;
+          this.setPage(beforePage);
+        }
+        return this;
+      };
+
+      API.deletePage = function () {
+        _deletePage.apply(this, arguments);
+        return this;
+      };
+
+      API.setCreationDate = function (date) {
+        setCreationDate(date);
+        return this;
+      };
+
+      API.getCreationDate = function (type) {
+        return getCreationDate(type);
+      };
+
+      API.setFileId = function (value) {
+        setFileId(value);
+        return this;
+      };
+
+      API.getFileId = function () {
+        return getFileId();
+      };
+
+      /**
+       * Set the display mode options of the page like zoom and layout.
+       *
+       * @param {integer|String} zoom   You can pass an integer or percentage as
+       * a string. 2 will scale the document up 2x, '200%' will scale up by the
+       * same amount. You can also set it to 'fullwidth', 'fullheight',
+       * 'fullpage', or 'original'.
+       *
+       * Only certain PDF readers support this, such as Adobe Acrobat
+       *
+       * @param {String} layout Layout mode can be: 'continuous' - this is the
+       * default continuous scroll. 'single' - the single page mode only shows one
+       * page at a time. 'twoleft' - two column left mode, first page starts on
+       * the left, and 'tworight' - pages are laid out in two columns, with the
+       * first page on the right. This would be used for books.
+       * @param {String} pmode 'UseOutlines' - it shows the
+       * outline of the document on the left. 'UseThumbs' - shows thumbnails along
+       * the left. 'FullScreen' - prompts the user to enter fullscreen mode.
+       *
+       * @function
+       * @returns {jsPDF}
+       * @name setDisplayMode
+       */
+      API.setDisplayMode = function (zoom, layout, pmode) {
+        zoomMode = zoom;
+        layoutMode = layout;
+        pageMode = pmode;
+
+        var validPageModes = [undefined, null, 'UseNone', 'UseOutlines', 'UseThumbs', 'FullScreen'];
+        if (validPageModes.indexOf(pmode) == -1) {
+          throw new Error('Page mode must be one of UseNone, UseOutlines, UseThumbs, or FullScreen. "' + pmode + '" is not recognized.');
+        }
+        return this;
+      };
+
+      /**
+       * Adds text to page. Supports adding multiline text when 'text' argument is an Array of Strings.
+       *
+       * @function
+       * @param {String|Array} text String or array of strings to be added to the page. Each line is shifted one line down per font, spacing settings declared before this call.
+       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
+       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
+       * @param {Object} options Collection of settings signalling how the text must be encoded. Defaults are sane. If you think you want to pass some flags, you likely can read the source.
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name text
+       */
+      API.text = function (text, x, y, options) {
+        /**
+         * Inserts something like this into PDF
+         *   BT
+         *    /F1 16 Tf  % Font name + size
+         *    16 TL % How many units down for next line in multiline text
+         *    0 g % color
+         *    28.35 813.54 Td % position
+         *    (line one) Tj
+         *    T* (line two) Tj
+         *    T* (line three) Tj
+         *   ET
+         */
+
+        var xtra = '';
+        var isHex = false;
+        var lineHeight = lineHeightProportion;
+
+        function ESC(s) {
+          s = s.split("\t").join(Array(options.TabLen || 9).join(" "));
+          return pdfEscape(s, flags);
+        }
+
+        function transformTextToSpecialArray(text) {
+          //we don't want to destroy original text array, so cloning it
+          var sa = text.concat();
+          var da = [];
+          var len = sa.length;
+          var curDa;
+          //we do array.join('text that must not be PDFescaped")
+          //thus, pdfEscape each component separately
+          while (len--) {
+            curDa = sa.shift();
+            if (typeof curDa === "string") {
+              da.push(curDa);
+            } else {
+              if (Object.prototype.toString.call(text) === '[object Array]' && curDa.length === 1) {
+                da.push(curDa[0]);
+              } else {
+                da.push([curDa[0], curDa[1], curDa[2]]);
+              }
+            }
+          }
+          return da;
+        }
+
+        function processTextByFunction(text, processingFunction) {
+          var result;
+          if (typeof text === 'string') {
+            result = processingFunction(text)[0];
+          } else if (Object.prototype.toString.call(text) === '[object Array]') {
+            //we don't want to destroy original text array, so cloning it
+            var sa = text.concat();
+            var da = [];
+            var len = sa.length;
+            var curDa;
+            var tmpResult;
+            //we do array.join('text that must not be PDFescaped")
+            //thus, pdfEscape each component separately
+            while (len--) {
+              curDa = sa.shift();
+              if (typeof curDa === "string") {
+                da.push(processingFunction(curDa)[0]);
+              } else if (Object.prototype.toString.call(curDa) === '[object Array]' && curDa[0] === "string") {
+                tmpResult = processingFunction(curDa[0], curDa[1], curDa[2]);
+                da.push([tmpResult[0], tmpResult[1], tmpResult[2]]);
+              }
+            }
+            result = da;
+          }
+          return result;
+        }
+        /**
+        Returns a widths of string in a given font, if the font size is set as 1 point.
+         In other words, this is "proportional" value. For 1 unit of font size, the length
+        of the string will be that much.
+         Multiply by font size to get actual width in *points*
+        Then divide by 72 to get inches or divide by (72/25.6) to get 'mm' etc.
+         @public
+        @function
+        @param
+        @returns {Type}
+        */
+        var getStringUnitWidth = function getStringUnitWidth(text, options) {
+          var result = 0;
+          if (typeof options.font.metadata.widthOfString === "function") {
+            result = options.font.metadata.widthOfString(text, options.fontSize, options.charSpace);
+          } else {
+            result = getArraySum(getCharWidthsArray(text, options)) * options.fontSize;
+          }
+          return result;
+        };
+
+        /**
+        Returns an array of length matching length of the 'word' string, with each
+        cell ocupied by the width of the char in that position.
+         @function
+        @param word {String}
+        @param widths {Object}
+        @param kerning {Object}
+        @returns {Array}
+        */
+        function getCharWidthsArray(text, options) {
+          options = options || {};
+
+          var widths = options.widths ? options.widths : options.font.metadata.Unicode.widths;
+          var widthsFractionOf = widths.fof ? widths.fof : 1;
+          var kerning = options.kerning ? options.kerning : options.font.metadata.Unicode.kerning;
+          var kerningFractionOf = kerning.fof ? kerning.fof : 1;
+
+          var i;
+          var l;
+          var char_code;
+          var prior_char_code = 0; //for kerning
+          var default_char_width = widths[0] || widthsFractionOf;
+          var output = [];
+
+          for (i = 0, l = text.length; i < l; i++) {
+            char_code = text.charCodeAt(i);
+            output.push((widths[char_code] || default_char_width) / widthsFractionOf + (kerning[char_code] && kerning[char_code][prior_char_code] || 0) / kerningFractionOf);
+            prior_char_code = char_code;
+          }
+
+          return output;
+        }
+
+        var getArraySum = function getArraySum(array) {
+          var i = array.length;
+          var output = 0;
+
+          while (i) {
+  i--;
+            output += array[i];
+          }
+
+          return output;
+        };
+
+        //backwardsCompatibility
+        var tmp;
+
+        // Pre-August-2012 the order of arguments was function(x, y, text, flags)
+        // in effort to make all calls have similar signature like
+        //   function(data, coordinates... , miscellaneous)
+        // this method had its args flipped.
+        // code below allows backward compatibility with old arg order.
+        if (typeof text === 'number') {
+          tmp = y;
+          y = x;
+          x = text;
+          text = tmp;
+        }
+
+        var flags = arguments[3];
+        var angle = arguments[4];
+        var align = arguments[5];
+
+        if ((typeof flags === 'undefined' ? 'undefined' : _typeof(flags)) !== "object" || flags === null) {
+          if (typeof angle === 'string') {
+            align = angle;
+            angle = null;
+          }
+          if (typeof flags === 'string') {
+            align = flags;
+            flags = null;
+          }
+          if (typeof flags === 'number') {
+            angle = flags;
+            flags = null;
+          }
+          options = { flags: flags, angle: angle, align: align };
+        }
+
+        //Check if text is of type String
+        var textIsOfTypeString = false;
+        var tmpTextIsOfTypeString = true;
+
+        if (typeof text === 'string') {
+          textIsOfTypeString = true;
+        } else if (Object.prototype.toString.call(text) === '[object Array]') {
+          //we don't want to destroy original text array, so cloning it
+          var sa = text.concat();
+          var da = [];
+          var len = sa.length;
+          var curDa;
+          //we do array.join('text that must not be PDFescaped")
+          //thus, pdfEscape each component separately
+          while (len--) {
+            curDa = sa.shift();
+            if (typeof curDa !== "string" || Object.prototype.toString.call(curDa) === '[object Array]' && typeof curDa[0] !== "string") {
+              tmpTextIsOfTypeString = false;
+            }
+          }
+          textIsOfTypeString = tmpTextIsOfTypeString;
+        }
+        if (textIsOfTypeString === false) {
+          throw new Error('Type of text must be string or Array. "' + text + '" is not recognized.');
+        }
+
+        //Escaping 
+        var activeFontEncoding = fonts[activeFontKey].encoding;
+
+        if (activeFontEncoding === "WinAnsiEncoding" || activeFontEncoding === "StandardEncoding") {
+          text = processTextByFunction(text, function (text, posX, posY) {
+            return [ESC(text), posX, posY];
+          });
+        }
+        //If there are any newlines in text, we assume
+        //the user wanted to print multiple lines, so break the
+        //text up into an array. If the text is already an array,
+        //we assume the user knows what they are doing.
+        //Convert text into an array anyway to simplify
+        //later code.
+
+        if (typeof text === 'string') {
+          if (text.match(/[\r?\n]/)) {
+            text = text.split(/\r\n|\r|\n/g);
+          } else {
+            text = [text];
+          }
+        }
+
+        //multiline
+        var maxWidth = options.maxWidth || 0;
+        var algorythm = options.maxWidthAlgorythm || "first-fit";
+
+        lineHeight = options.lineHeight || lineHeightProportion;
+        var leading = activeFontSize * lineHeight;
+        var activeFont = fonts[activeFontKey];
+        var k = this.internal.scaleFactor;
+        var charSpace = options.charSpace || activeCharSpace;
+
+        var widthOfSpace = getStringUnitWidth(" ", { font: activeFont, charSpace: charSpace, fontSize: activeFontSize }) / k;
+        var splitByMaxWidth = function splitByMaxWidth(value, maxWidth) {
+          var i = 0;
+          var lastBreak = 0;
+          var currentWidth = 0;
+          var resultingChunks = [];
+          var widthOfEachWord = [];
+          var currentChunk = [];
+
+          var listOfWords = [];
+          var result = [];
+
+          listOfWords = value.split(/ /g);
+
+          for (i = 0; i < listOfWords.length; i += 1) {
+            widthOfEachWord.push(getStringUnitWidth(listOfWords[i], { font: activeFont, charSpace: charSpace, fontSize: activeFontSize }) / k);
+          }
+          for (i = 0; i < listOfWords.length; i += 1) {
+            currentChunk = widthOfEachWord.slice(lastBreak, i);
+            currentWidth = getArraySum(currentChunk) + widthOfSpace * (currentChunk.length - 1);
+            if (currentWidth >= maxWidth) {
+              resultingChunks.push(listOfWords.slice(lastBreak, i !== 0 ? i - 1 : 0).join(" "));
+              lastBreak = i !== 0 ? i - 1 : 0;
+              i -= 1;
+            } else if (i === widthOfEachWord.length - 1) {
+              resultingChunks.push(listOfWords.slice(lastBreak, widthOfEachWord.length).join(" "));
+            }
+          }
+          result = [];
+          for (i = 0; i < resultingChunks.length; i += 1) {
+            result = result.concat(resultingChunks[i]);
+          }
+          return result;
+        };
+        var firstFitMethod = function firstFitMethod(value, maxWidth) {
+          var j = 0;
+          var tmpText = [];
+          for (j = 0; j < value.length; j += 1) {
+            tmpText = tmpText.concat(splitByMaxWidth(value[j], maxWidth));
+          }
+          return tmpText;
+        };
+        if (maxWidth > 0) {
+          switch (algorythm) {
+            case "first-fit":
+            default:
+              text = firstFitMethod(text, maxWidth);
+              break;
+          }
+        }
+
+        //creating Payload-Object to make text byRef
+        var payload = {
+          text: text,
+          x: x,
+          y: y,
+          options: options,
+          mutex: {
+            pdfEscape: pdfEscape,
+            activeFontKey: activeFontKey,
+            fonts: fonts,
+            activeFontSize: activeFontSize
+          }
+        };
+        events.publish('preProcessText', payload);
+
+        text = payload.text;
+        options = payload.options;
+        //angle
+
+        var angle = options.angle;
+        var k = this.internal.scaleFactor;
+        var curY = (this.internal.pageSize.getHeight() - y) * k;
+        var transformationMatrix = [];
+
+        if (angle) {
+          angle *= Math.PI / 180;
+          var c = Math.cos(angle),
+              s = Math.sin(angle);
+          var f2 = function f2(number) {
+            return number.toFixed(2);
+          };
+          transformationMatrix = [f2(c), f2(s), f2(s * -1), f2(c)];
+        }
+
+        //charSpace
+
+        var charSpace = options.charSpace;
+
+        if (charSpace !== undefined) {
+          xtra += charSpace + " Tc\n";
+        }
+
+        //lang
+
+        var lang = options.lang;
+        var tmpRenderingMode = -1;
+        var parmRenderingMode = options.renderingMode || options.stroke;
+        var pageContext = this.internal.getCurrentPageInfo().pageContext;
+
+        switch (parmRenderingMode) {
+          case 0:
+          case false:
+          case 'fill':
+            tmpRenderingMode = 0;
+            break;
+          case 1:
+          case true:
+          case 'stroke':
+            tmpRenderingMode = 1;
+            break;
+          case 2:
+          case 'fillThenStroke':
+            tmpRenderingMode = 2;
+            break;
+          case 3:
+          case 'invisible':
+            tmpRenderingMode = 3;
+            break;
+          case 4:
+          case 'fillAndAddForClipping':
+            tmpRenderingMode = 4;
+            break;
+          case 5:
+          case 'strokeAndAddPathForClipping':
+            tmpRenderingMode = 5;
+            break;
+          case 6:
+          case 'fillThenStrokeAndAddToPathForClipping':
+            tmpRenderingMode = 6;
+            break;
+          case 7:
+          case 'addToPathForClipping':
+            tmpRenderingMode = 7;
+            break;
+        }
+
+        var usedRenderingMode = pageContext.usedRenderingMode || -1;
+
+        //if the coder wrote it explicitly to use a specific 
+        //renderingMode, then use it
+        if (tmpRenderingMode !== -1) {
+          xtra += tmpRenderingMode + " Tr\n";
+          //otherwise check if we used the rendering Mode already
+          //if so then set the rendering Mode...
+        } else if (usedRenderingMode !== -1) {
+          xtra += "0 Tr\n";
+        }
+
+        if (tmpRenderingMode !== -1) {
+          pageContext.usedRenderingMode = tmpRenderingMode;
+        }
+
+        //align
+
+        var align = options.align || 'left';
+        var leading = activeFontSize * lineHeight;
+        var pageHeight = this.internal.pageSize.getHeight();
+        var pageWidth = this.internal.pageSize.getWidth();
+        var k = this.internal.scaleFactor;
+        var activeFont = fonts[activeFontKey];
+        var charSpace = options.charSpace || activeCharSpace;
+        var maxWidth = options.maxWidth || 0;
+
+        var lineWidths;
+        var flags = {};
+        var wordSpacingPerLine = [];
+
+        if (Object.prototype.toString.call(text) === '[object Array]') {
+          var da = transformTextToSpecialArray(text);
+          var newY;
+          var maxLineLength;
+          var lineWidths;
+          if (align !== "left") {
+            lineWidths = da.map(function (v) {
+              return getStringUnitWidth(v, { font: activeFont, charSpace: charSpace, fontSize: activeFontSize }) / k;
+            });
+          }
+          var maxLineLength = Math.max.apply(Math, lineWidths);
+          //The first line uses the "main" Td setting,
+          //and the subsequent lines are offset by the
+          //previous line's x coordinate.
+          var prevWidth = 0;
+          var delta;
+          var newX;
+          if (align === "right") {
+            x -= lineWidths[0];
+            text = [];
+            for (var i = 0, len = da.length; i < len; i++) {
+              delta = maxLineLength - lineWidths[i];
+              if (i === 0) {
+                newX = x * k;
+                newY = (pageHeight - y) * k;
+              } else {
+                newX = (prevWidth - lineWidths[i]) * k;
+                newY = -leading;
+              }
+              text.push([da[i], newX, newY]);
+              prevWidth = lineWidths[i];
+            }
+          } else if (align === "center") {
+            x -= lineWidths[0] / 2;
+            text = [];
+            for (var i = 0, len = da.length; i < len; i++) {
+              delta = (maxLineLength - lineWidths[i]) / 2;
+              if (i === 0) {
+                newX = x * k;
+                newY = (pageHeight - y) * k;
+              } else {
+                newX = (prevWidth - lineWidths[i]) / 2 * k;
+                newY = -leading;
+              }
+              text.push([da[i], newX, newY]);
+              prevWidth = lineWidths[i];
+            }
+          } else if (align === "left") {
+            text = [];
+            for (var i = 0, len = da.length; i < len; i++) {
+              newY = i === 0 ? (pageHeight - y) * k : -leading;
+              newX = i === 0 ? x * k : 0;
+              //text.push([da[i], newX, newY]);
+              text.push(da[i]);
+            }
+          } else if (align === "justify") {
+            text = [];
+            var maxWidth = maxWidth !== 0 ? maxWidth : pageWidth;
+
+            for (var i = 0, len = da.length; i < len; i++) {
+              newY = i === 0 ? (pageHeight - y) * k : -leading;
+              newX = i === 0 ? x * k : 0;
+              if (i < len - 1) {
+                wordSpacingPerLine.push(((maxWidth - lineWidths[i]) / (da[i].split(" ").length - 1) * k).toFixed(2));
+              }
+              text.push([da[i], newX, newY]);
+            }
+          } else {
+            throw new Error('Unrecognized alignment option, use "left", "center", "right" or "justify".');
+          }
+        }
+
+        //R2L
+        var doReversing = typeof options.R2L === "boolean" ? options.R2L : R2L;
+        if (doReversing === true) {
+          text = processTextByFunction(text, function (text, posX, posY) {
+            return [text.split("").reverse().join(""), posX, posY];
+          });
+        }
+
+        //creating Payload-Object to make text byRef
+        var payload = {
+          text: text,
+          x: x,
+          y: y,
+          options: options,
+          mutex: {
+            pdfEscape: pdfEscape,
+            activeFontKey: activeFontKey,
+            fonts: fonts,
+            activeFontSize: activeFontSize
+          }
+        };
+        events.publish('postProcessText', payload);
+
+        text = payload.text;
+        isHex = payload.mutex.isHex;
+
+        var da = transformTextToSpecialArray(text);
+
+        text = [];
+        var variant = 0;
+        var len = da.length;
+        var posX;
+        var posY;
+        var content;
+        var wordSpacing = '';
+
+        for (var i = 0; i < len; i++) {
+
+          wordSpacing = '';
+          if (Object.prototype.toString.call(da[i]) !== '[object Array]') {
+            posX = parseFloat(x * k).toFixed(2);
+            posY = parseFloat((pageHeight - y) * k).toFixed(2);
+            content = (isHex ? "<" : "(") + da[i] + (isHex ? ">" : ")");
+          } else if (Object.prototype.toString.call(da[i]) === '[object Array]') {
+            posX = parseFloat(da[i][1]).toFixed(2);
+            posY = parseFloat(da[i][2]).toFixed(2);
+            content = (isHex ? "<" : "(") + da[i][0] + (isHex ? ">" : ")");
+            variant = 1;
+          }
+          if (wordSpacingPerLine !== undefined && wordSpacingPerLine[i] !== undefined) {
+            wordSpacing = wordSpacingPerLine[i] + " Tw\n";
+          }
+          //TODO: Kind of a hack?
+          if (transformationMatrix.length !== 0 && i === 0) {
+            text.push(wordSpacing + transformationMatrix.join(" ") + " " + posX + " " + posY + " Tm\n" + content);
+          } else if (variant === 1 || variant === 0 && i === 0) {
+            text.push(wordSpacing + posX + " " + posY + " Td\n" + content);
+          } else {
+            text.push(wordSpacing + content);
+          }
+        }
+        if (variant === 0) {
+          text = text.join(" Tj\nT* ");
+        } else {
+          text = text.join(" Tj\n");
+        }
+
+        text += " Tj\n";
+
+        var result = 'BT\n/' + activeFontKey + ' ' + activeFontSize + ' Tf\n' + // font face, style, size
+        (activeFontSize * lineHeight).toFixed(2) + ' TL\n' + // line spacing
+        textColor + '\n';
+        result += xtra;
+        result += text;
+        result += "ET";
+
+        out(result);
+        return this;
+      };
+
+      /**
+       * Letter spacing method to print text with gaps
+       *
+       * @function
+       * @param {String|Array} text String to be added to the page.
+       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
+       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
+       * @param {Number} spacing Spacing (in units declared at inception)
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name lstext
+       * @deprecated We'll be removing this function. It doesn't take character width into account.
+       */
+      API.lstext = function (text, x, y, spacing) {
+        console.warn('jsPDF.lstext is deprecated');
+        for (var i = 0, len = text.length; i < len; i++, x += spacing) {
+          this.text(text[i], x, y);
+        }return this;
+      };
+
+      API.line = function (x1, y1, x2, y2) {
+        return this.lines([[x2 - x1, y2 - y1]], x1, y1);
+      };
+
+      API.clip = function () {
+        // By patrick-roberts, github.com/MrRio/jsPDF/issues/328
+        // Call .clip() after calling .rect() with a style argument of null
+        out('W'); // clip
+        out('S'); // stroke path; necessary for clip to work
+      };
+
+      /**
+       * This fixes the previous function clip(). Perhaps the 'stroke path' hack was due to the missing 'n' instruction?
+       * We introduce the fixed version so as to not break API.
+       * @param fillRule
+       */
+      API.clip_fixed = function (fillRule) {
+        // Call .clip() after calling drawing ops with a style argument of null
+        // W is the PDF clipping op
+        if ('evenodd' === fillRule) {
+          out('W*');
+        } else {
+          out('W');
+        }
+        // End the path object without filling or stroking it.
+        // This operator is a path-painting no-op, used primarily for the side effect of changing the current clipping path
+        // (see Section 4.4.3, “Clipping Path Operators”)
+        out('n');
+      };
+
+      /**
+       * Adds series of curves (straight lines or cubic bezier curves) to canvas, starting at `x`, `y` coordinates.
+       * All data points in `lines` are relative to last line origin.
+       * `x`, `y` become x1,y1 for first line / curve in the set.
+       * For lines you only need to specify [x2, y2] - (ending point) vector against x1, y1 starting point.
+       * For bezier curves you need to specify [x2,y2,x3,y3,x4,y4] - vectors to control points 1, 2, ending point. All vectors are against the start of the curve - x1,y1.
+       *
+       * @example .lines([[2,2],[-2,2],[1,1,2,2,3,3],[2,1]], 212,110, 10) // line, line, bezier curve, line
+       * @param {Array} lines Array of *vector* shifts as pairs (lines) or sextets (cubic bezier curves).
+       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
+       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
+       * @param {Number} scale (Defaults to [1.0,1.0]) x,y Scaling factor for all vectors. Elements can be any floating number Sub-one makes drawing smaller. Over-one grows the drawing. Negative flips the direction.
+       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
+       * @param {Boolean} closed If true, the path is closed with a straight line from the end of the last curve to the starting point.
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name lines
+       */
+      API.lines = function (lines, x, y, scale, style, closed) {
+        var scalex, scaley, i, l, leg, x2, y2, x3, y3, x4, y4;
+
+        // Pre-August-2012 the order of arguments was function(x, y, lines, scale, style)
+        // in effort to make all calls have similar signature like
+        //   function(content, coordinateX, coordinateY , miscellaneous)
+        // this method had its args flipped.
+        // code below allows backward compatibility with old arg order.
+        if (typeof lines === 'number') {
+          tmp = y;
+          y = x;
+          x = lines;
+          lines = tmp;
+        }
+
+        scale = scale || [1, 1];
+
+        // starting point
+        out(f3(x * k) + ' ' + f3((pageHeight - y) * k) + ' m ');
+
+        scalex = scale[0];
+        scaley = scale[1];
+        l = lines.length;
+        //, x2, y2 // bezier only. In page default measurement "units", *after* scaling
+        //, x3, y3 // bezier only. In page default measurement "units", *after* scaling
+        // ending point for all, lines and bezier. . In page default measurement "units", *after* scaling
+        x4 = x; // last / ending point = starting point for first item.
+        y4 = y; // last / ending point = starting point for first item.
+
+        for (i = 0; i < l; i++) {
+          leg = lines[i];
+          if (leg.length === 2) {
+            // simple line
+            x4 = leg[0] * scalex + x4; // here last x4 was prior ending point
+            y4 = leg[1] * scaley + y4; // here last y4 was prior ending point
+            out(f3(x4 * k) + ' ' + f3((pageHeight - y4) * k) + ' l');
+          } else {
+            // bezier curve
+            x2 = leg[0] * scalex + x4; // here last x4 is prior ending point
+            y2 = leg[1] * scaley + y4; // here last y4 is prior ending point
+            x3 = leg[2] * scalex + x4; // here last x4 is prior ending point
+            y3 = leg[3] * scaley + y4; // here last y4 is prior ending point
+            x4 = leg[4] * scalex + x4; // here last x4 was prior ending point
+            y4 = leg[5] * scaley + y4; // here last y4 was prior ending point
+            out(f3(x2 * k) + ' ' + f3((pageHeight - y2) * k) + ' ' + f3(x3 * k) + ' ' + f3((pageHeight - y3) * k) + ' ' + f3(x4 * k) + ' ' + f3((pageHeight - y4) * k) + ' c');
+          }
+        }
+
+        if (closed) {
+          out(' h');
+        }
+
+        // stroking / filling / both the path
+        if (style !== null) {
+          out(getStyle(style));
+        }
+        return this;
+      };
+
+      /**
+       * Adds a rectangle to PDF
+       *
+       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
+       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
+       * @param {Number} w Width (in units declared at inception of PDF document)
+       * @param {Number} h Height (in units declared at inception of PDF document)
+       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name rect
+       */
+      API.rect = function (x, y, w, h, style) {
+        var op = getStyle(style);
+        out([f2(x * k), f2((pageHeight - y) * k), f2(w * k), f2(-h * k), 're'].join(' '));
+
+        if (style !== null) {
+          out(getStyle(style));
+        }
+
+        return this;
+      };
+
+      /**
+       * Adds a triangle to PDF
+       *
+       * @param {Number} x1 Coordinate (in units declared at inception of PDF document) against left edge of the page
+       * @param {Number} y1 Coordinate (in units declared at inception of PDF document) against upper edge of the page
+       * @param {Number} x2 Coordinate (in units declared at inception of PDF document) against left edge of the page
+       * @param {Number} y2 Coordinate (in units declared at inception of PDF document) against upper edge of the page
+       * @param {Number} x3 Coordinate (in units declared at inception of PDF document) against left edge of the page
+       * @param {Number} y3 Coordinate (in units declared at inception of PDF document) against upper edge of the page
+       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name triangle
+       */
+      API.triangle = function (x1, y1, x2, y2, x3, y3, style) {
+        this.lines([[x2 - x1, y2 - y1], // vector to point 2
+        [x3 - x2, y3 - y2], // vector to point 3
+        [x1 - x3, y1 - y3] // closing vector back to point 1
+        ], x1, y1, // start of path
+        [1, 1], style, true);
+        return this;
+      };
+
+      /**
+       * Adds a rectangle with rounded corners to PDF
+       *
+       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
+       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
+       * @param {Number} w Width (in units declared at inception of PDF document)
+       * @param {Number} h Height (in units declared at inception of PDF document)
+       * @param {Number} rx Radius along x axis (in units declared at inception of PDF document)
+       * @param {Number} rx Radius along y axis (in units declared at inception of PDF document)
+       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name roundedRect
+       */
+      API.roundedRect = function (x, y, w, h, rx, ry, style) {
+        var MyArc = 4 / 3 * (Math.SQRT2 - 1);
+        this.lines([[w - 2 * rx, 0], [rx * MyArc, 0, rx, ry - ry * MyArc, rx, ry], [0, h - 2 * ry], [0, ry * MyArc, -(rx * MyArc), ry, -rx, ry], [-w + 2 * rx, 0], [-(rx * MyArc), 0, -rx, -(ry * MyArc), -rx, -ry], [0, -h + 2 * ry], [0, -(ry * MyArc), rx * MyArc, -ry, rx, -ry]], x + rx, y, // start of path
+        [1, 1], style);
+        return this;
+      };
+
+      /**
+       * Adds an ellipse to PDF
+       *
+       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
+       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
+       * @param {Number} rx Radius along x axis (in units declared at inception of PDF document)
+       * @param {Number} rx Radius along y axis (in units declared at inception of PDF document)
+       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name ellipse
+       */
+      API.ellipse = function (x, y, rx, ry, style) {
+        var lx = 4 / 3 * (Math.SQRT2 - 1) * rx,
+            ly = 4 / 3 * (Math.SQRT2 - 1) * ry;
+
+        out([f2((x + rx) * k), f2((pageHeight - y) * k), 'm', f2((x + rx) * k), f2((pageHeight - (y - ly)) * k), f2((x + lx) * k), f2((pageHeight - (y - ry)) * k), f2(x * k), f2((pageHeight - (y - ry)) * k), 'c'].join(' '));
+        out([f2((x - lx) * k), f2((pageHeight - (y - ry)) * k), f2((x - rx) * k), f2((pageHeight - (y - ly)) * k), f2((x - rx) * k), f2((pageHeight - y) * k), 'c'].join(' '));
+        out([f2((x - rx) * k), f2((pageHeight - (y + ly)) * k), f2((x - lx) * k), f2((pageHeight - (y + ry)) * k), f2(x * k), f2((pageHeight - (y + ry)) * k), 'c'].join(' '));
+        out([f2((x + lx) * k), f2((pageHeight - (y + ry)) * k), f2((x + rx) * k), f2((pageHeight - (y + ly)) * k), f2((x + rx) * k), f2((pageHeight - y) * k), 'c'].join(' '));
+
+        if (style !== null) {
+          out(getStyle(style));
+        }
+
+        return this;
+      };
+
+      /**
+       * Adds an circle to PDF
+       *
+       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
+       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
+       * @param {Number} r Radius (in units declared at inception of PDF document)
+       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name circle
+       */
+      API.circle = function (x, y, r, style) {
+        return this.ellipse(x, y, r, r, style);
+      };
+
+      /**
+       * Adds a properties to the PDF document
+       *
+       * @param {Object} A property_name-to-property_value object structure.
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name setProperties
+       */
+      API.setProperties = function (properties) {
+        // copying only those properties we can render.
+        for (var property in documentProperties) {
+          if (documentProperties.hasOwnProperty(property) && properties[property]) {
+            documentProperties[property] = properties[property];
+          }
+        }
+        return this;
+      };
+
+      /**
+       * Sets font size for upcoming text elements.
+       *
+       * @param {Number} size Font size in points.
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name setFontSize
+       */
+      API.setFontSize = function (size) {
+        activeFontSize = size;
+        return this;
+      };
+
+      /**
+       * Sets text font face, variant for upcoming text elements.
+       * See output of jsPDF.getFontList() for possible font names, styles.
+       *
+       * @param {String} fontName Font name or family. Example: "times"
+       * @param {String} fontStyle Font style or variant. Example: "italic"
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name setFont
+       */
+      API.setFont = function (fontName, fontStyle) {
+        activeFontKey = _getFont(fontName, fontStyle);
+        // if font is not found, the above line blows up and we never go further
+        return this;
+      };
+
+      /**
+       * Switches font style or variant for upcoming text elements,
+       * while keeping the font face or family same.
+       * See output of jsPDF.getFontList() for possible font names, styles.
+       *
+       * @param {String} style Font style or variant. Example: "italic"
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name setFontStyle
+       */
+      API.setFontStyle = API.setFontType = function (style) {
+        activeFontKey = _getFont(undefined, style);
+        // if font is not found, the above line blows up and we never go further
+        return this;
+      };
+
+      /**
+       * Returns an object - a tree of fontName to fontStyle relationships available to
+       * active PDF document.
+       *
+       * @public
+       * @function
+       * @returns {Object} Like {'times':['normal', 'italic', ... ], 'arial':['normal', 'bold', ... ], ... }
+       * @methodOf jsPDF#
+       * @name getFontList
+       */
+      API.getFontList = function () {
+        // TODO: iterate over fonts array or return copy of fontmap instead in case more are ever added.
+        var list = {},
+            fontName,
+            fontStyle,
+            tmp;
+
+        for (fontName in fontmap) {
+          if (fontmap.hasOwnProperty(fontName)) {
+            list[fontName] = tmp = [];
+            for (fontStyle in fontmap[fontName]) {
+              if (fontmap[fontName].hasOwnProperty(fontStyle)) {
+                tmp.push(fontStyle);
+              }
+            }
+          }
+        }
+
+        return list;
+      };
+
+      /**
+       * Add a custom font.
+       *
+       * @param {String} Postscript name of the Font.  Example: "Menlo-Regular"
+       * @param {String} Name of font-family from @font-face definition.  Example: "Menlo Regular"
+       * @param {String} Font style.  Example: "normal"
+       * @function
+       * @returns the {fontKey} (same as the internal method)
+       * @methodOf jsPDF#
+       * @name addFont
+       */
+      API.addFont = function (postScriptName, fontName, fontStyle, encoding) {
+        encoding = encoding || 'Identity-H';
+        addFont(postScriptName, fontName, fontStyle, encoding);
+      };
+
+      /**
+       * Sets line width for upcoming lines.
+       *
+       * @param {Number} width Line width (in units declared at inception of PDF document)
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name setLineWidth
+       */
+      API.setLineWidth = function (width) {
+        out((width * k).toFixed(2) + ' w');
+        return this;
+      };
+
+      /**
+       * Sets the stroke color for upcoming elements.
+       *
+       * Depending on the number of arguments given, Gray, RGB, or CMYK
+       * color space is implied.
+       *
+       * When only ch1 is given, "Gray" color space is implied and it
+       * must be a value in the range from 0.00 (solid black) to to 1.00 (white)
+       * if values are communicated as String types, or in range from 0 (black)
+       * to 255 (white) if communicated as Number type.
+       * The RGB-like 0-255 range is provided for backward compatibility.
+       *
+       * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each
+       * value must be in the range from 0.00 (minimum intensity) to to 1.00
+       * (max intensity) if values are communicated as String types, or
+       * from 0 (min intensity) to to 255 (max intensity) if values are communicated
+       * as Number types.
+       * The RGB-like 0-255 range is provided for backward compatibility.
+       *
+       * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each
+       * value must be a in the range from 0.00 (0% concentration) to to
+       * 1.00 (100% concentration)
+       *
+       * Because JavaScript treats fixed point numbers badly (rounds to
+       * floating point nearest to binary representation) it is highly advised to
+       * communicate the fractional numbers as String types, not JavaScript Number type.
+       *
+       * @param {Number|String} ch1 Color channel value or {String} ch1 color value in hexadecimal, example: '#FFFFFF'
+       * @param {Number|String} ch2 Color channel value
+       * @param {Number|String} ch3 Color channel value
+       * @param {Number|String} ch4 Color channel value
+       *
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name setDrawColor
+       */
+      API.setDrawColor = function (ch1, ch2, ch3, ch4) {
+        var options = {
+          "ch1": ch1,
+          "ch2": ch2,
+          "ch3": ch3,
+          "ch4": ch4,
+          "pdfColorType": "draw",
+          "precision": 2
+        };
+
+        out(generateColorString(options));
+        return this;
+      };
+
+      /**
+       * Sets the fill color for upcoming elements.
+       *
+       * Depending on the number of arguments given, Gray, RGB, or CMYK
+       * color space is implied.
+       *
+       * When only ch1 is given, "Gray" color space is implied and it
+       * must be a value in the range from 0.00 (solid black) to to 1.00 (white)
+       * if values are communicated as String types, or in range from 0 (black)
+       * to 255 (white) if communicated as Number type.
+       * The RGB-like 0-255 range is provided for backward compatibility.
+       *
+       * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each
+       * value must be in the range from 0.00 (minimum intensity) to to 1.00
+       * (max intensity) if values are communicated as String types, or
+       * from 0 (min intensity) to to 255 (max intensity) if values are communicated
+       * as Number types.
+       * The RGB-like 0-255 range is provided for backward compatibility.
+       *
+       * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each
+       * value must be a in the range from 0.00 (0% concentration) to to
+       * 1.00 (100% concentration)
+       *
+       * Because JavaScript treats fixed point numbers badly (rounds to
+       * floating point nearest to binary representation) it is highly advised to
+       * communicate the fractional numbers as String types, not JavaScript Number type.
+       *
+       * @param {Number|String} ch1 Color channel value or {String} ch1 color value in hexadecimal, example: '#FFFFFF'
+       * @param {Number|String} ch2 Color channel value
+       * @param {Number|String} ch3 Color channel value
+       * @param {Number|String} ch4 Color channel value
+       *
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name setFillColor
+       */
+
+      API.setFillColor = function (ch1, ch2, ch3, ch4) {
+        var options = {
+          "ch1": ch1,
+          "ch2": ch2,
+          "ch3": ch3,
+          "ch4": ch4,
+          "pdfColorType": "fill",
+          "precision": 2
+        };
+
+        out(generateColorString(options));
+        return this;
+      };
+
+      /**
+       * Sets the text color for upcoming elements.
+       *
+       * Depending on the number of arguments given, Gray, RGB, or CMYK
+       * color space is implied.
+       *
+       * When only ch1 is given, "Gray" color space is implied and it
+       * must be a value in the range from 0.00 (solid black) to to 1.00 (white)
+       * if values are communicated as String types, or in range from 0 (black)
+       * to 255 (white) if communicated as Number type.
+       * The RGB-like 0-255 range is provided for backward compatibility.
+       *
+       * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each
+       * value must be in the range from 0.00 (minimum intensity) to to 1.00
+       * (max intensity) if values are communicated as String types, or
+       * from 0 (min intensity) to to 255 (max intensity) if values are communicated
+       * as Number types.
+       * The RGB-like 0-255 range is provided for backward compatibility.
+       *
+       * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each
+       * value must be a in the range from 0.00 (0% concentration) to to
+       * 1.00 (100% concentration)
+       *
+       * Because JavaScript treats fixed point numbers badly (rounds to
+       * floating point nearest to binary representation) it is highly advised to
+       * communicate the fractional numbers as String types, not JavaScript Number type.
+       *
+       * @param {Number|String} ch1 Color channel value or {String} ch1 color value in hexadecimal, example: '#FFFFFF'
+       * @param {Number|String} ch2 Color channel value
+       * @param {Number|String} ch3 Color channel value
+       * @param {Number|String} ch4 Color channel value
+       *
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name setTextColor
+       */
+      API.setTextColor = function (ch1, ch2, ch3, ch4) {
+        var options = {
+          "ch1": ch1,
+          "ch2": ch2,
+          "ch3": ch3,
+          "ch4": ch4,
+          "pdfColorType": "text",
+          "precision": 3
+        };
+        textColor = generateColorString(options);
+
+        return this;
+      };
+
+      /**
+       * Initializes the default character set that the user wants to be global..
+       *
+       * @param {Number} charSpace
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name setCharSpace
+       */
+
+      API.setCharSpace = function (charSpace) {
+        activeCharSpace = charSpace;
+        return this;
+      };
+
+      /**
+       * Initializes the default character set that the user wants to be global..
+       *
+       * @param {Boolean} boolean
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name setR2L
+       */
+
+      API.setR2L = function (boolean) {
+        R2L = boolean;
+        return this;
+      };
+
+      /**
+       * Is an Object providing a mapping from human-readable to
+       * integer flag values designating the varieties of line cap
+       * and join styles.
+       *
+       * @returns {Object}
+       * @fieldOf jsPDF#
+       * @name CapJoinStyles
+       */
+      API.CapJoinStyles = {
+        0: 0,
+        'butt': 0,
+        'but': 0,
+        'miter': 0,
+        1: 1,
+        'round': 1,
+        'rounded': 1,
+        'circle': 1,
+        2: 2,
+        'projecting': 2,
+        'project': 2,
+        'square': 2,
+        'bevel': 2
+      };
+
+      /**
+       * Sets the line cap styles
+       * See {jsPDF.CapJoinStyles} for variants
+       *
+       * @param {String|Number} style A string or number identifying the type of line cap
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name setLineCap
+       */
+      API.setLineCap = function (style) {
+        var id = this.CapJoinStyles[style];
+        if (id === undefined) {
+          throw new Error("Line cap style of '" + style + "' is not recognized. See or extend .CapJoinStyles property for valid styles");
+        }
+        lineCapID = id;
+        out(id + ' J');
+
+        return this;
+      };
+
+      /**
+       * Sets the line join styles
+       * See {jsPDF.CapJoinStyles} for variants
+       *
+       * @param {String|Number} style A string or number identifying the type of line join
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name setLineJoin
+       */
+      API.setLineJoin = function (style) {
+        var id = this.CapJoinStyles[style];
+        if (id === undefined) {
+          throw new Error("Line join style of '" + style + "' is not recognized. See or extend .CapJoinStyles property for valid styles");
+        }
+        lineJoinID = id;
+        out(id + ' j');
+
+        return this;
+      };
+
+      // Output is both an internal (for plugins) and external function
+      API.output = _output;
+
+      /**
+       * Saves as PDF document. An alias of jsPDF.output('save', 'filename.pdf')
+       * @param  {String} filename The filename including extension.
+       *
+       * @function
+       * @returns {jsPDF}
+       * @methodOf jsPDF#
+       * @name save
+       */
+      API.save = function (filename) {
+        API.output('save', filename);
+      };
+
+      // applying plugins (more methods) ON TOP of built-in API.
+      // this is intentional as we allow plugins to override
+      // built-ins
+      for (var plugin in jsPDF.API) {
+        if (jsPDF.API.hasOwnProperty(plugin)) {
+          if (plugin === 'events' && jsPDF.API.events.length) {
+            (function (events, newEvents) {
+
+              // jsPDF.API.events is a JS Array of Arrays
+              // where each Array is a pair of event name, handler
+              // Events were added by plugins to the jsPDF instantiator.
+              // These are always added to the new instance and some ran
+              // during instantiation.
+              var eventname, handler_and_args, i;
+
+              for (i = newEvents.length - 1; i !== -1; i--) {
+                // subscribe takes 3 args: 'topic', function, runonce_flag
+                // if undefined, runonce is false.
+                // users can attach callback directly,
+                // or they can attach an array with [callback, runonce_flag]
+                // that's what the "apply" magic is for below.
+                eventname = newEvents[i][0];
+                handler_and_args = newEvents[i][1];
+                events.subscribe.apply(events, [eventname].concat(typeof handler_and_args === 'function' ? [handler_and_args] : handler_and_args));
+              }
+            })(events, jsPDF.API.events);
+          } else {
+            API[plugin] = jsPDF.API[plugin];
+          }
+        }
+      }
+
+      //////////////////////////////////////////////////////
+      // continuing initialization of jsPDF Document object
+      //////////////////////////////////////////////////////
+      // Add the first page automatically
+      addFonts();
+      activeFontKey = 'F1';
+      _addPage(format, orientation);
+
+      events.publish('initialized');
+      return API;
+    }
+
+    /**
+     * jsPDF.API is a STATIC property of jsPDF class.
+     * jsPDF.API is an object you can add methods and properties to.
+     * The methods / properties you add will show up in new jsPDF objects.
+     *
+     * One property is prepopulated. It is the 'events' Object. Plugin authors can add topics,
+     * callbacks to this object. These will be reassigned to all new instances of jsPDF.
+     * Examples:
+     * jsPDF.API.events['initialized'] = function(){ 'this' is API object }
+     * jsPDF.API.events['addFont'] = function(added_font_object){ 'this' is API object }
+     *
+     * @static
+     * @public
+     * @memberOf jsPDF
+     * @name API
+     *
+     * @example
+     * jsPDF.API.mymethod = function(){
+     *   // 'this' will be ref to internal API object. see jsPDF source
+     *   // , so you can refer to built-in methods like so:
+     *   //     this.line(....)
+     *   //     this.text(....)
+     * }
+     * var pdfdoc = new jsPDF()
+     * pdfdoc.mymethod() // <- !!!!!!
+     */
+    jsPDF.API = {
+      events: []
+    };
+    jsPDF.version = "0.0.0";
+
+    if (typeof define === 'function' && define.amd) {
+      define('jsPDF', function () {
+        return jsPDF;
+      });
+    } else if (typeof module !== 'undefined' && module.exports) {
+      module.exports = jsPDF;
+      module.exports.jsPDF = jsPDF;
+    } else {
+      global.jsPDF = jsPDF;
+    }
+    return jsPDF;
+  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || typeof global !== "undefined" && global || Function('return typeof this === "object" && this.content')() || Function('return this')());
+  // `self` is undefined in Firefox for Android content script context
+  // while `this` is nsIContentFrameMessageManager
+  // with an attribute `content` that corresponds to the window
+  
+
+  /**
+   * jsPDF AcroForm Plugin
+   * Copyright (c) 2016 Alexander Weidt, https://github.com/BiggA94
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+
+  (function (jsPDFAPI, globalObj) {
+
+      var scope;
+      var pageHeight;
+      var scaleFactor = 1;
+      var inherit = function inherit(child, parent) {
+          child.prototype = Object.create(parent.prototype);
+          child.prototype.constructor = child;
+      };
+      var scale = function scale(x) {
+          return x * (scaleFactor / 1); // 1 = (96 / 72)
+      };
+
+      /**
+      Returns a widths of string in a given font, if the font size is set as 1 point.
+       In other words, this is "proportional" value. For 1 unit of font size, the length
+      of the string will be that much.
+       Multiply by font size to get actual width in *points*
+      Then divide by 72 to get inches or divide by (72/25.6) to get 'mm' etc.
+       @public
+      @function
+      @param
+      @returns {Type}
+      */
+      var getStringUnitWidth = function getStringUnitWidth(text, options) {
+          var result = 0;
+          if (typeof options.font.metadata.widthOfString === "function") {
+              result = options.font.metadata.widthOfString(text, options.fontSize, options.charSpace);
+          } else {
+              result = getArraySum(getCharWidthsArray(text, options)) * options.fontSize;
+          }
+          return result;
+      };
+
+      /**
+      Returns an array of length matching length of the 'word' string, with each
+      cell ocupied by the width of the char in that position.
+       @function
+      @param word {String}
+      @param widths {Object}
+      @param kerning {Object}
+      @returns {Array}
+      */
+      function getCharWidthsArray(text, options) {
+          options = options || {};
+
+          var widths = options.widths ? options.widths : options.font.metadata.Unicode.widths;
+          var widthsFractionOf = widths.fof ? widths.fof : 1;
+          var kerning = options.kerning ? options.kerning : options.font.metadata.Unicode.kerning;
+          var kerningFractionOf = kerning.fof ? kerning.fof : 1;
+
+          var i;
+          var l;
+          var char_code;
+          var prior_char_code = 0; //for kerning
+          var default_char_width = widths[0] || widthsFractionOf;
+          var output = [];
+
+          for (i = 0, l = text.length; i < l; i++) {
+              char_code = text.charCodeAt(i);
+              output.push((widths[char_code] || default_char_width) / widthsFractionOf + (kerning[char_code] && kerning[char_code][prior_char_code] || 0) / kerningFractionOf);
+              prior_char_code = char_code;
+          }
+
+          return output;
+      }
+
+      var getArraySum = function getArraySum(array) {
+          var i = array.length;
+          var output = 0;
+
+          while (i) {
+  i--;
+              output += array[i];
+          }
+
+          return output;
+      };
+
+      var createFormXObject = function createFormXObject(formObject) {
+          var xobj = new AcroFormXObject();
+          var height = AcroFormAppearance.internal.getHeight(formObject) || 0;
+          var width = AcroFormAppearance.internal.getWidth(formObject) || 0;
+          xobj.BBox = [0, 0, width.toFixed(2), height.toFixed(2)];
+          return xobj;
+      };
+
+      var setBitPosition = function setBitPosition(variable, position, value) {
+          variable = variable || 0;
+          value = value || 1;
+
+          var bitMask = 1;
+          bitMask = bitMask << position - 1;
+
+          if (value == 1) {
+              // Set the Bit to 1
+              var variable = variable | bitMask;
+          } else {
+              // Set the Bit to 0
+              var variable = variable & ~bitMask;
+          }
+
+          return variable;
+      };
+
+      /**
+       * Calculating the Ff entry:
+       *
+       * The Ff entry contains flags, that have to be set bitwise
+       * In the Following the number in the Comment is the BitPosition
+       */
+      var calculateFlagsOnOptions = function calculateFlagsOnOptions(flags, opts, PDFVersion) {
+          var PDFVersion = PDFVersion || 1.3;
+          var flags = flags || 0;
+
+          // 1, readOnly
+          if (opts.readOnly == true) {
+              flags = setBitPosition(flags, 1);
+          }
+
+          // 2, required
+          if (opts.required == true) {
+              flags = setBitPosition(flags, 2);
+          }
+
+          // 4, noExport
+          if (opts.noExport == true) {
+              flags = setBitPosition(flags, 3);
+          }
+
+          // 13, multiline
+          if (opts.multiline == true) {
+              flags = setBitPosition(flags, 13);
+          }
+
+          // 14, Password
+          if (opts.password) {
+              flags = setBitPosition(flags, 14);
+          }
+
+          // 15, NoToggleToOff (Radio buttons only
+          if (opts.noToggleToOff) {
+              flags = setBitPosition(flags, 15);
+          }
+
+          //16, Radio
+          if (opts.radio) {
+              flags = setBitPosition(flags, 16);
+          }
+
+          // 17, Pushbutton
+          if (opts.pushbutton) {
+              flags = setBitPosition(flags, 17);
+          }
+
+          // 18, Combo (If not set, the choiceField is a listBox!!)
+          if (opts.combo) {
+              flags = setBitPosition(flags, 18);
+          }
+
+          // 19, Edit
+          if (opts.edit) {
+              flags = setBitPosition(flags, 19);
+          }
+
+          // 20, Sort
+          if (opts.sort) {
+              flags = setBitPosition(flags, 20);
+          }
+
+          // 21, FileSelect, PDF 1.4...
+          if (opts.fileSelect && PDFVersion >= 1.4) {
+              flags = setBitPosition(flags, 21);
+          }
+
+          // 22, MultiSelect (PDF 1.4)
+          if (opts.multiSelect && PDFVersion >= 1.4) {
+              flags = setBitPosition(flags, 22);
+          }
+
+          // 23, DoNotSpellCheck (PDF 1.4)
+          if (opts.doNotSpellCheck && PDFVersion >= 1.4) {
+              flags = setBitPosition(flags, 23);
+          }
+
+          // 24, DoNotScroll (PDF 1.4)
+          if (opts.doNotScroll == true && PDFVersion >= 1.4) {
+              flags = setBitPosition(flags, 24);
+          }
+
+          // 25, RichText (PDF 1.4)
+          if (opts.richText && PDFVersion >= 1.4) {
+              flags = setBitPosition(flags, 25);
+          }
+
+          return flags;
+      };
+
+      var calculateCoordinates = function calculateCoordinates(args) {
+          var x = args[0];
+          var y = args[1];
+          var w = args[2];
+          var h = args[3];
+
+          var coordinates = {};
+
+          if (Array.isArray(x)) {
+              x[0] = scale(x[0]);
+              x[1] = scale(x[1]);
+              x[2] = scale(x[2]);
+              x[3] = scale(x[3]);
+          } else {
+              x = scale(x);
+              y = scale(y);
+              w = scale(w);
+              h = scale(h);
+          }
+          coordinates.lowerLeft_X = x || 0;
+          coordinates.lowerLeft_Y = scale(pageHeight) - y - h || 0;
+          coordinates.upperRight_X = x + w || 0;
+          coordinates.upperRight_Y = scale(pageHeight) - y || 0;
+
+          return [coordinates.lowerLeft_X.toFixed(2), coordinates.lowerLeft_Y.toFixed(2), coordinates.upperRight_X.toFixed(2), coordinates.upperRight_Y.toFixed(2)];
+      };
+
+      var calculateAppearanceStream = function calculateAppearanceStream(formObject) {
+          if (formObject.appearanceStreamContent) {
+              // If appearanceStream is already set, use it
+              return formObject.appearanceStreamContent;
+          }
+
+          if (!formObject.V && !formObject.DV) {
+              return;
+          }
+
+          // else calculate it
+
+          var stream = [];
+          var text = formObject.V || formObject.DV;
+          var calcRes = calculateX(formObject, text);
+
+          stream.push('/Tx BMC');
+          stream.push('q');
+          stream.push('/F1 ' + calcRes.fontSize.toFixed(2) + ' Tf');
+          stream.push('1 0 0 1 0 0 Tm'); // Text Matrix
+
+          stream.push('BT'); // Begin Text
+          stream.push(calcRes.text);
+
+          stream.push('ET'); // End Text
+          stream.push('Q');
+          stream.push('EMC');
+
+          var appearanceStreamContent = new createFormXObject(formObject);
+          appearanceStreamContent.stream = stream.join("\n");
+
+          return appearanceStreamContent;
+      };
+
+      var calculateX = function calculateX(formObject, text, font, maxFontSize) {
+          var maxFontSize = maxFontSize || 12;
+          var font = font || "helvetica";
+          var returnValue = {
+              text: "",
+              fontSize: ""
+          };
+          // Remove Brackets
+          text = text.substr(0, 1) == '(' ? text.substr(1) : text;
+          text = text.substr(text.length - 1) == ')' ? text.substr(0, text.length - 1) : text;
+          // split into array of words
+          var textSplit = text.split(' ');
+          var fontSize = maxFontSize; // The Starting fontSize (The Maximum)
+          var lineSpacing = 2;
+          var borderPadding = 2;
+
+          var height = AcroFormAppearance.internal.getHeight(formObject) || 0;
+          height = height < 0 ? -height : height;
+          var width = AcroFormAppearance.internal.getWidth(formObject) || 0;
+          width = width < 0 ? -width : width;
+
+          var isSmallerThanWidth = function isSmallerThanWidth(i, lastLine, fontSize) {
+              if (i + 1 < textSplit.length) {
+                  var tmp = lastLine + " " + textSplit[i + 1];
+                  var TextWidth = calculateFontSpace(tmp, fontSize + "px", font).width;
+                  var FieldWidth = width - 2 * borderPadding;
+                  return TextWidth <= FieldWidth;
+              } else {
+                  return false;
+              }
+          };
+
+          fontSize++;
+          FontSize: while (true) {
+              var text = "";
+              fontSize--;
+              var textHeight = calculateFontSpace("3", fontSize + "px", font).height;
+              var startY = formObject.multiline ? height - fontSize : (height - textHeight) / 2;
+              startY += lineSpacing;
+              var startX = -borderPadding;
+
+              var lastY = startY;
+              var firstWordInLine = 0,
+                  lastWordInLine = 0;
+              var lastLength = 0;
+              if (fontSize <= 0) {
+                  // In case, the Text doesn't fit at all
+                  fontSize = 12;
+                  text = "(...) Tj\n";
+                  text += "% Width of Text: " + calculateFontSpace(text, "1px").width + ", FieldWidth:" + width + "\n";
+                  break;
+              }
+
+              lastLength = calculateFontSpace(textSplit[0] + " ", fontSize + "px", font).width;
+
+              var lastLine = "";
+              var lineCount = 0;
+              Line: for (var i in textSplit) {
+                  lastLine += textSplit[i] + " ";
+                  // Remove last blank
+                  lastLine = lastLine.substr(lastLine.length - 1) == " " ? lastLine.substr(0, lastLine.length - 1) : lastLine;
+                  var key = parseInt(i);
+                  lastLength = calculateFontSpace(lastLine + " ", fontSize + "px", font).width;
+                  var nextLineIsSmaller = isSmallerThanWidth(key, lastLine, fontSize);
+                  var isLastWord = i >= textSplit.length - 1;
+                  if (nextLineIsSmaller && !isLastWord) {
+                      lastLine += " ";
+                      continue; // Line
+                  } else if (!nextLineIsSmaller && !isLastWord) {
+                      if (!formObject.multiline) {
+                          continue FontSize;
+                      } else {
+                          if ((textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) {
+                              // If the Text is higher than the FieldObject
+                              continue FontSize;
+                          }
+                          lastWordInLine = key;
+                          // go on
+                      }
+                  } else if (isLastWord) {
+                      lastWordInLine = key;
+                  } else {
+                      if (formObject.multiline && (textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) {
+                          // If the Text is higher than the FieldObject
+                          continue FontSize;
+                      }
+                  }
+
+                  var line = '';
+
+                  for (var x = firstWordInLine; x <= lastWordInLine; x++) {
+                      line += textSplit[x] + ' ';
+                  }
+
+                  // Remove last blank
+                  line = line.substr(line.length - 1) == " " ? line.substr(0, line.length - 1) : line;
+                  //lastLength -= blankSpace.width;
+                  lastLength = calculateFontSpace(line, fontSize + "px", font).width;
+
+                  // Calculate startX
+                  switch (formObject.Q) {
+                      case 2:
+                          // Right justified
+                          startX = width - lastLength - borderPadding;
+                          break;
+                      case 1:
+                          // Q = 1 := Text-Alignment: Center
+                          startX = (width - lastLength) / 2;
+                          break;
+                      case 0:
+                      default:
+                          startX = borderPadding;
+                          break;
+                  }
+                  text += startX.toFixed(2) + ' ' + lastY.toFixed(2) + ' Td\n';
+                  text += '(' + line + ') Tj\n';
+                  // reset X in PDF
+                  text += -startX.toFixed(2) + ' 0 Td\n';
+
+                  // After a Line, adjust y position
+                  lastY = -(fontSize + lineSpacing);
+
+                  // Reset for next iteration step
+                  lastLength = 0;
+                  firstWordInLine = lastWordInLine + 1;
+                  lineCount++;
+
+                  lastLine = "";
+                  continue Line;
+              }
+              break;
+          }
+
+          returnValue.text = text;
+          returnValue.fontSize = fontSize;
+
+          return returnValue;
+      };
+      /*
+       * small workaround for calculating the TextMetric approximately
+       * @param text
+       * @param fontsize
+       * @returns {TextMetrics} (Has Height and Width)
+       */
+      var calculateFontSpace = function calculateFontSpace(text, fontsize, fonttype) {
+          var fonttype = fonttype || "helvetica";
+          var font = scope.internal.getFont(fonttype);
+          var width = getStringUnitWidth(text, { font: font, fontSize: parseFloat(fontsize), charSpace: 0 });
+          var height = getStringUnitWidth("3", { font: font, fontSize: parseFloat(fontsize), charSpace: 0 }) * 1.5;
+          var result = { height: height, width: width };
+          return result;
+      };
+
+      var acroformPluginTemplate = {
+          fields: [],
+          xForms: [],
+          /**
+           * acroFormDictionaryRoot contains information about the AcroForm Dictionary
+           * 0: The Event-Token, the AcroFormDictionaryCallback has
+           * 1: The Object ID of the Root
+           */
+          acroFormDictionaryRoot: null,
+          /**
+           * After the PDF gets evaluated, the reference to the root has to be reset,
+           * this indicates, whether the root has already been printed out
+           */
+          printedOut: false,
+          internal: null,
+          isInitialized: false
+      };
+
+      var annotReferenceCallback = function annotReferenceCallback() {
+          for (var i in scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields) {
+              var formObject = scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields[i];
+              // add Annot Reference!
+              if (formObject.hasAnnotation) {
+                  // If theres an Annotation Widget in the Form Object, put the Reference in the /Annot array
+                  createAnnotationReference.call(scope, formObject);
+              }
+          }
+      };
+
+      var putForm = function putForm(formObject) {
+          if (scope.internal.acroformPlugin.printedOut) {
+              scope.internal.acroformPlugin.printedOut = false;
+              scope.internal.acroformPlugin.acroFormDictionaryRoot = null;
+          }
+          if (!scope.internal.acroformPlugin.acroFormDictionaryRoot) {
+              initializeAcroForm.call(scope);
+          }
+          scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields.push(formObject);
+      };
+      /**
+       * Create the Reference to the widgetAnnotation, so that it gets referenced in the Annot[] int the+
+       * (Requires the Annotation Plugin)
+       */
+      var createAnnotationReference = function createAnnotationReference(object) {
+          var options = {
+              type: 'reference',
+              object: object
+          };
+          scope.annotationPlugin.annotations[scope.internal.getPageInfo(object.page).pageNumber].push(options);
+      };
+
+      // Callbacks
+
+      var putCatalogCallback = function putCatalogCallback() {
+          //Put reference to AcroForm to DocumentCatalog
+          if (typeof scope.internal.acroformPlugin.acroFormDictionaryRoot != 'undefined') {
+              // for safety, shouldn't normally be the case
+              scope.internal.write('/AcroForm ' + scope.internal.acroformPlugin.acroFormDictionaryRoot.objId + ' ' + 0 + ' R');
+          } else {
+              console.log('Root missing...');
+          }
+      };
+
+      /**
+       * Adds /Acroform X 0 R to Document Catalog,
+       * and creates the AcroForm Dictionary
+       */
+      var AcroFormDictionaryCallback = function AcroFormDictionaryCallback() {
+          // Remove event
+          scope.internal.events.unsubscribe(scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID);
+
+          delete scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID;
+
+          scope.internal.acroformPlugin.printedOut = true;
+      };
+
+      /**
+       * Creates the single Fields and writes them into the Document
+       *
+       * If fieldArray is set, use the fields that are inside it instead of the fields from the AcroRoot
+       * (for the FormXObjects...)
+       */
+      var createFieldCallback = function createFieldCallback(fieldArray) {
+          var standardFields = !fieldArray;
+
+          if (!fieldArray) {
+              // in case there is no fieldArray specified, we want to print out the Fields of the AcroForm
+              // Print out Root
+              scope.internal.newObjectDeferredBegin(scope.internal.acroformPlugin.acroFormDictionaryRoot.objId);
+              scope.internal.out(scope.internal.acroformPlugin.acroFormDictionaryRoot.getString());
+          }
+
+          var fieldArray = fieldArray || scope.internal.acroformPlugin.acroFormDictionaryRoot.Kids;
+
+          for (var i in fieldArray) {
+              var form = fieldArray[i];
+
+              var oldRect = form.Rect;
+
+              if (form.Rect) {
+                  form.Rect = calculateCoordinates.call(this, form.Rect);
+              }
+
+              // Start Writing the Object
+              scope.internal.newObjectDeferredBegin(form.objId);
+
+              var content = form.objId + " 0 obj\n<<\n";
+
+              if ((typeof form === 'undefined' ? 'undefined' : _typeof(form)) === "object" && typeof form.getContent === "function") {
+                  content += form.getContent();
+              }
+
+              form.Rect = oldRect;
+
+              if (form.hasAppearanceStream && !form.appearanceStreamContent) {
+                  // Calculate Appearance
+                  var appearance = calculateAppearanceStream.call(this, form);
+                  content += "/AP << /N " + appearance + " >>\n";
+
+                  scope.internal.acroformPlugin.xForms.push(appearance);
+              }
+
+              // Assume AppearanceStreamContent is a Array with N,R,D (at least one of them!)
+              if (form.appearanceStreamContent) {
+                  content += "/AP << ";
+                  // Iterate over N,R and D
+                  for (var k in form.appearanceStreamContent) {
+                      var value = form.appearanceStreamContent[k];
+                      content += "/" + k + " ";
+                      content += "<< ";
+                      if (Object.keys(value).length >= 1 || Array.isArray(value)) {
+                          // appearanceStream is an Array or Object!
+                          for (var i in value) {
+                              var obj = value[i];
+                              if (typeof obj === 'function') {
+                                  // if Function is referenced, call it in order to get the FormXObject
+                                  obj = obj.call(this, form);
+                              }
+                              content += "/" + i + " " + obj + " ";
+
+                              // In case the XForm is already used, e.g. OffState of CheckBoxes, don't add it
+                              if (!(scope.internal.acroformPlugin.xForms.indexOf(obj) >= 0)) scope.internal.acroformPlugin.xForms.push(obj);
+                          }
+                      } else {
+                          var obj = value;
+                          if (typeof obj === 'function') {
+                              // if Function is referenced, call it in order to get the FormXObject
+                              obj = obj.call(this, form);
+                          }
+                          content += "/" + i + " " + obj + " \n";
+                          if (!(scope.internal.acroformPlugin.xForms.indexOf(obj) >= 0)) scope.internal.acroformPlugin.xForms.push(obj);
+                      }
+                      content += " >>\n";
+                  }
+
+                  // appearance stream is a normal Object..
+                  content += ">>\n";
+              }
+
+              content += ">>\nendobj\n";
+
+              scope.internal.out(content);
+          }
+          if (standardFields) {
+              createXFormObjectCallback.call(this, scope.internal.acroformPlugin.xForms);
+          }
+      };
+
+      var createXFormObjectCallback = function createXFormObjectCallback(fieldArray) {
+          for (var i in fieldArray) {
+              var key = i;
+              var form = fieldArray[i];
+              // Start Writing the Object
+              scope.internal.newObjectDeferredBegin(form && form.objId);
+
+              var content = "";
+              if ((typeof form === 'undefined' ? 'undefined' : _typeof(form)) === "object" && typeof form.getString === "function") {
+                  content = form.getString();
+              }
+              scope.internal.out(content);
+
+              delete fieldArray[key];
+          }
+      };
+      var initializeAcroForm = function initializeAcroForm() {
+          if (this.internal !== undefined && (this.internal.acroformPlugin === undefined || this.internal.acroformPlugin.isInitialized === false)) {
+
+              scope = this;
+
+              AcroFormField.FieldNum = 0;
+              this.internal.acroformPlugin = JSON.parse(JSON.stringify(acroformPluginTemplate));
+              if (this.internal.acroformPlugin.acroFormDictionaryRoot) {
+                  //return;
+                  throw new Error("Exception while creating AcroformDictionary");
+              }
+              scaleFactor = scope.internal.scaleFactor;
+              pageHeight = scope.internal.pageSize.getHeight();
+
+              // The Object Number of the AcroForm Dictionary
+              scope.internal.acroformPlugin.acroFormDictionaryRoot = new AcroFormDictionary();
+
+              // add Callback for creating the AcroForm Dictionary
+              scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID = scope.internal.events.subscribe('postPutResources', AcroFormDictionaryCallback);
+
+              scope.internal.events.subscribe('buildDocument', annotReferenceCallback); //buildDocument
+
+              // Register event, that is triggered when the DocumentCatalog is written, in order to add /AcroForm
+              scope.internal.events.subscribe('putCatalog', putCatalogCallback);
+
+              // Register event, that creates all Fields
+              scope.internal.events.subscribe('postPutPages', createFieldCallback);
+
+              scope.internal.acroformPlugin.isInitialized = true;
+          }
+      };
+
+      // ### Handy Functions:
+
+      var arrayToPdfArray = function arrayToPdfArray(array) {
+          if (Array.isArray(array)) {
+              var content = ' [';
+              for (var i in array) {
+                  var element = array[i].toString();
+                  content += element;
+                  content += i < array.length - 1 ? ' ' : '';
+              }
+              content += ']';
+
+              return content;
+          }
+      };
+
+      var toPdfString = function toPdfString(string) {
+          string = string || "";
+
+          // put Bracket at the Beginning of the String
+          if (string.indexOf('(') !== 0) {
+              string = '(' + string;
+          }
+
+          if (string.substring(string.length - 1) != ')') {
+              string += ')';
+          }
+          return string;
+      };
+
+      // ##########################
+      // Classes
+      // ##########################
+
+      var AcroFormPDFObject = function AcroFormPDFObject() {
+          // The Object ID in the PDF Object Model
+          // todo
+          var _objId;
+          Object.defineProperty(this, 'objId', {
+              get: function get$$1() {
+                  if (!_objId) {
+                      _objId = scope.internal.newObjectDeferred();
+                  }
+                  if (!_objId) {
+                      console.log("Couldn't create Object ID");
+                  }
+                  return _objId;
+              },
+              configurable: false
+          });
+      };
+
+      AcroFormPDFObject.prototype.toString = function () {
+          return this.objId + " 0 R";
+      };
+
+      AcroFormPDFObject.prototype.getString = function () {
+          var res = this.objId + " 0 obj\n<<";
+          var content = this.getContent();
+
+          res += content + ">>\n";
+          if (this.stream) {
+              res += "stream\n";
+              res += this.stream;
+              res += "\nendstream\n";
+          }
+          res += "endobj\n";
+          return res;
+      };
+
+      AcroFormPDFObject.prototype.getContent = function () {
+          /**
+           * Prints out all enumerable Variables from the Object
+           * @param fieldObject
+           * @returns {string}
+           */
+          var createContentFromFieldObject = function createContentFromFieldObject(fieldObject) {
+              var content = '';
+
+              var keys = Object.keys(fieldObject).filter(function (key) {
+                  return key != 'content' && key != 'appearanceStreamContent' && key.substring(0, 1) != "_";
+              });
+
+              for (var i in keys) {
+                  var key = keys[i];
+                  var value = fieldObject[key];
+
+                  /*if (key == 'Rect' && value) {
+                   value = AcroForm.internal.calculateCoordinates.call(jsPDF.API.acroformPlugin.internal, value);
+                   }*/
+
+                  if (value) {
+                      if (Array.isArray(value)) {
+                          content += '/' + key + ' ' + arrayToPdfArray(value) + "\n";
+                      } else if (value instanceof AcroFormPDFObject) {
+                          // In case it is a reference to another PDFObject, take the referennce number
+                          content += '/' + key + ' ' + value.objId + " 0 R" + "\n";
+                      } else {
+                          content += '/' + key + ' ' + value + '\n';
+                      }
+                  }
+              }
+              return content;
+          };
+
+          var object = "";
+
+          object += createContentFromFieldObject(this);
+          return object;
+      };
+
+      var AcroFormXObject = function AcroFormXObject() {
+          AcroFormPDFObject.call(this);
+          this.Type = "/XObject";
+          this.Subtype = "/Form";
+          this.FormType = 1;
+          this.BBox;
+          this.Matrix;
+          this.Resources = "2 0 R";
+          this.PieceInfo;
+          var _stream;
+          Object.defineProperty(this, 'Length', {
+              enumerable: true,
+              get: function get$$1() {
+                  return _stream !== undefined ? _stream.length : 0;
+              }
+          });
+          Object.defineProperty(this, 'stream', {
+              enumerable: false,
+              set: function set$$1(val) {
+                  _stream = val.trim();
+              },
+              get: function get$$1() {
+                  if (_stream) {
+                      return _stream;
+                  } else {
+                      return null;
+                  }
+              }
+          });
+      };
+
+      inherit(AcroFormXObject, AcroFormPDFObject);
+      // ##### The Objects, the User can Create:
+
+      var AcroFormDictionary = function AcroFormDictionary() {
+          AcroFormPDFObject.call(this);
+          var _Kids = [];
+          Object.defineProperty(this, 'Kids', {
+              enumerable: false,
+              configurable: true,
+              get: function get$$1() {
+                  if (_Kids.length > 0) {
+                      return _Kids;
+                  } else {
+                      return;
+                  }
+              }
+          });
+          Object.defineProperty(this, 'Fields', {
+              enumerable: true,
+              configurable: true,
+              get: function get$$1() {
+                  return _Kids;
+              }
+          });
+          // Default Appearance
+          this.DA;
+      };
+
+      inherit(AcroFormDictionary, AcroFormPDFObject);
+
+      // The Field Object contains the Variables, that every Field needs
+      // Rectangle for Appearance: lower_left_X, lower_left_Y, width, height
+      var AcroFormField = function AcroFormField() {
+
+          AcroFormPDFObject.call(this);
+
+          var _Rect;
+          Object.defineProperty(this, 'Rect', {
+              enumerable: true,
+              configurable: false,
+              get: function get$$1() {
+                  if (!_Rect) {
+                      return;
+                  }
+                  var tmp = _Rect;
+                  //var calculatedRes = AcroForm.internal.calculateCoordinates(_Rect); // do later!
+                  return tmp;
+              },
+              set: function set$$1(val) {
+                  _Rect = val;
+              }
+          });
+
+          var _FT = "";
+          Object.defineProperty(this, 'FT', {
+              enumerable: true,
+              set: function set$$1(val) {
+                  _FT = val;
+              },
+              get: function get$$1() {
+                  return _FT;
+              }
+          });
+          /**
+           * The Partial name of the Field Object.
+           * It has to be unique.
+           */
+          var _T;
+
+          Object.defineProperty(this, 'T', {
+              enumerable: true,
+              configurable: false,
+              set: function set$$1(val) {
+                  _T = val;
+              },
+              get: function get$$1() {
+                  if (!_T || _T.length < 1) {
+                      if (this instanceof AcroFormChildClass) {
+                          // In case of a Child from a Radio´Group, you don't need a FieldName!!!
+                          return;
+                      }
+                      return "(FieldObject" + AcroFormField.FieldNum++ + ")";
+                  }
+                  if (_T.substring(0, 1) == "(" && _T.substring(_T.length - 1)) {
+                      return _T;
+                  }
+                  return "(" + _T + ")";
+              }
+          });
+
+          var _DA;
+          // Defines the default appearance (Needed for variable Text)
+          Object.defineProperty(this, 'DA', {
+              enumerable: true,
+              get: function get$$1() {
+                  if (!_DA) {
+                      return;
+                  }
+                  return '(' + _DA + ')';
+              },
+              set: function set$$1(val) {
+                  _DA = val;
+              }
+          });
+
+          var _DV;
+          // Defines the default value
+          Object.defineProperty(this, 'DV', {
+              enumerable: true,
+              configurable: true,
+              get: function get$$1() {
+                  if (!_DV) {
+                      return;
+                  }
+                  return _DV;
+              },
+              set: function set$$1(val) {
+                  _DV = val;
+              }
+          });
+
+          var _V;
+          // Defines the default value
+          Object.defineProperty(this, 'V', {
+              enumerable: true,
+              configurable: true,
+              get: function get$$1() {
+                  if (!_V) {
+                      return;
+                  }
+                  return _V;
+              },
+              set: function set$$1(val) {
+                  _V = val;
+              }
+          });
+
+          //this.Type = "/Annot";
+          //this.Subtype = "/Widget";
+          Object.defineProperty(this, 'Type', {
+              enumerable: true,
+              get: function get$$1() {
+                  return this.hasAnnotation ? "/Annot" : null;
+              }
+          });
+
+          Object.defineProperty(this, 'Subtype', {
+              enumerable: true,
+              get: function get$$1() {
+                  return this.hasAnnotation ? "/Widget" : null;
+              }
+          });
+
+          /**
+           *
+           * @type {Array}
+           */
+          this.BG;
+
+          Object.defineProperty(this, 'hasAnnotation', {
+              enumerable: false,
+              get: function get$$1() {
+                  if (this.Rect || this.BC || this.BG) {
+                      return true;
+                  }
+                  return false;
+              }
+          });
+
+          Object.defineProperty(this, 'hasAppearanceStream', {
+              enumerable: false,
+              configurable: true,
+              writable: true
+          });
+
+          Object.defineProperty(this, 'page', {
+              enumerable: false,
+              configurable: true,
+              writable: true
+          });
+      };
+
+      inherit(AcroFormField, AcroFormPDFObject);
+
+      var AcroFormChoiceField = function AcroFormChoiceField() {
+          AcroFormField.call(this);
+          // Field Type = Choice Field
+          this.FT = "/Ch";
+          // options
+          this.Opt = [];
+          this.V = '()';
+          // Top Index
+          this.TI = 0;
+          /**
+           * Defines, whether the
+           * @type {boolean}
+           */
+
+          var _combo = false;
+
+          Object.defineProperty(this, 'combo', {
+              enumerable: false,
+              get: function get$$1() {
+                  return _combo;
+              },
+              set: function set$$1(val) {
+                  _combo = val;
+              }
+          });
+          /**
+           * Defines, whether the Choice Field is an Edit Field.
+           * An Edit Field is automatically an Combo Field.
+           */
+          Object.defineProperty(this, 'edit', {
+              enumerable: true,
+              set: function set$$1(val) {
+                  if (val == true) {
+                      this._edit = true;
+                      // ComboBox has to be true
+                      this.combo = true;
+                  } else {
+                      this._edit = false;
+                  }
+              },
+              get: function get$$1() {
+                  if (!this._edit) {
+                      return false;
+                  }
+                  return this._edit;
+              },
+              configurable: false
+          });
+          this.hasAppearanceStream = true;
+      };
+      inherit(AcroFormChoiceField, AcroFormField);
+
+      var AcroFormListBox = function AcroFormListBox() {
+          AcroFormChoiceField.call(this);
+          this.combo = false;
+      };
+      inherit(AcroFormListBox, AcroFormChoiceField);
+
+      var AcroFormComboBox = function AcroFormComboBox() {
+          AcroFormListBox.call(this);
+          this.combo = true;
+      };
+      inherit(AcroFormComboBox, AcroFormListBox);
+
+      var AcroFormEditBox = function AcroFormEditBox() {
+          AcroFormComboBox.call(this);
+          this.edit = true;
+      };
+      inherit(AcroFormEditBox, AcroFormComboBox);
+
+      var AcroFormButton = function AcroFormButton() {
+          AcroFormField.call(this);
+          this.FT = "/Btn";
+          //this.hasAnnotation = true;
+      };
+      inherit(AcroFormButton, AcroFormField);
+
+      var AcroFormPushButton = function AcroFormPushButton() {
+          AcroFormButton.call(this);
+
+          var _pushbutton = true;
+          Object.defineProperty(this, 'pushbutton', {
+              enumerable: false,
+              get: function get$$1() {
+                  return _pushbutton;
+              },
+              set: function set$$1(val) {
+                  _pushbutton = val;
+              }
+          });
+      };
+      inherit(AcroFormPushButton, AcroFormButton);
+
+      var AcroFormRadioButton = function AcroFormRadioButton() {
+          AcroFormButton.call(this);
+
+          var _radio = true;
+          Object.defineProperty(this, 'radio', {
+              enumerable: false,
+              get: function get$$1() {
+                  return _radio;
+              },
+              set: function set$$1(val) {
+                  _radio = val;
+              }
+          });
+
+          var _Kids = [];
+          Object.defineProperty(this, 'Kids', {
+              enumerable: true,
+              get: function get$$1() {
+                  if (_Kids.length > 0) {
+                      return _Kids;
+                  }
+              }
+          });
+
+          Object.defineProperty(this, '__Kids', {
+              get: function get$$1() {
+                  return _Kids;
+              }
+          });
+
+          var _noToggleToOff;
+
+          Object.defineProperty(this, 'noToggleToOff', {
+              enumerable: false,
+              get: function get$$1() {
+                  return _noToggleToOff;
+              },
+              set: function set$$1(val) {
+                  _noToggleToOff = val;
+              }
+          });
+
+          //this.hasAnnotation = false;
+      };
+      inherit(AcroFormRadioButton, AcroFormButton);
+
+      /*
+       * The Child classs of a RadioButton (the radioGroup)
+       * -> The single Buttons
+       */
+      var AcroFormChildClass = function AcroFormChildClass(parent, name) {
+          AcroFormField.call(this);
+          this.Parent = parent;
+
+          // todo: set AppearanceType as variable that can be set from the outside...
+          this._AppearanceType = AcroFormAppearance.RadioButton.Circle; // The Default appearanceType is the Circle
+          this.appearanceStreamContent = this._AppearanceType.createAppearanceStream(name);
+
+          // Set Print in the Annot Flag
+          this.F = setBitPosition(this.F, 3, 1);
+
+          // Set AppearanceCharacteristicsDictionary with default appearance if field is not interacting with user
+          this.MK = this._AppearanceType.createMK(); // (8) -> Cross, (1)-> Circle, ()-> nothing
+
+          // Default Appearance is Off
+          this.AS = "/Off"; // + name;
+
+          this._Name = name;
+      };
+      inherit(AcroFormChildClass, AcroFormField);
+
+      AcroFormRadioButton.prototype.setAppearance = function (appearance) {
+          if (!('createAppearanceStream' in appearance && 'createMK' in appearance)) {
+              console.log("Couldn't assign Appearance to RadioButton. Appearance was Invalid!");
+              return;
+          }
+          for (var i in this.__Kids) {
+              var child = this.__Kids[i];
+
+              child.appearanceStreamContent = appearance.createAppearanceStream(child._Name);
+              child.MK = appearance.createMK();
+          }
+      };
+
+      AcroFormRadioButton.prototype.createOption = function (name) {
+          var parent = this;
+          var kidCount = this.__Kids.length;
+
+          // Create new Child for RadioGroup
+          var child = new AcroFormChildClass(parent, name);
+          // Add to Parent
+          this.__Kids.push(child);
+
+          jsPDFAPI.addField(child);
+
+          return child;
+      };
+
+      var AcroFormCheckBox = function AcroFormCheckBox() {
+          AcroFormButton.call(this);
+          this.appearanceStreamContent = AcroFormAppearance.CheckBox.createAppearanceStream();
+          this.MK = AcroFormAppearance.CheckBox.createMK();
+          this.AS = "/On";
+          this.V = "/On";
+      };
+      inherit(AcroFormCheckBox, AcroFormButton);
+
+      var AcroFormTextField = function AcroFormTextField() {
+          AcroFormField.call(this);
+          this.DA = AcroFormAppearance.createDefaultAppearanceStream();
+          this.F = 4;
+          var _V;
+          Object.defineProperty(this, 'V', {
+              get: function get$$1() {
+                  if (_V) {
+                      return toPdfString(_V);
+                  } else {
+                      return _V;
+                  }
+              },
+              enumerable: true,
+              set: function set$$1(val) {
+                  _V = val;
+              }
+          });
+
+          var _DV;
+          Object.defineProperty(this, 'DV', {
+              get: function get$$1() {
+                  if (_DV) {
+                      return toPdfString(_DV);
+                  } else {
+                      return _DV;
+                  }
+              },
+              enumerable: true,
+              set: function set$$1(val) {
+                  _DV = val;
+              }
+          });
+
+          var _multiline = false;
+          Object.defineProperty(this, 'multiline', {
+              enumerable: false,
+              get: function get$$1() {
+                  return _multiline;
+              },
+              set: function set$$1(val) {
+                  _multiline = val;
+              }
+          });
+
+          /**
+           * For PDF 1.4
+           * @type {boolean}
+           */
+          var _fileSelect = false;
+          Object.defineProperty(this, 'fileSelect', {
+              enumerable: false,
+              get: function get$$1() {
+                  return _fileSelect;
+              },
+              set: function set$$1(val) {
+                  _fileSelect = val;
+              }
+          });
+          /**
+           * For PDF 1.4
+           * @type {boolean}
+           */
+          var _doNotSpellCheck = false;
+          Object.defineProperty(this, 'doNotSpellCheck', {
+              enumerable: false,
+              get: function get$$1() {
+                  return _doNotSpellCheck;
+              },
+              set: function set$$1(val) {
+                  _doNotSpellCheck = val;
+              }
+          });
+          /**
+           * For PDF 1.4
+           * @type {boolean}
+           */
+          var _doNotScroll = false;
+          Object.defineProperty(this, 'doNotScroll', {
+              enumerable: false,
+              get: function get$$1() {
+                  return _doNotScroll;
+              },
+              set: function set$$1(val) {
+                  _doNotScroll = val;
+              }
+          });
+
+          var _MaxLen = false;
+          Object.defineProperty(this, 'MaxLen', {
+              enumerable: true,
+              get: function get$$1() {
+                  return _MaxLen;
+              },
+              set: function set$$1(val) {
+                  _MaxLen = val;
+              }
+          });
+
+          Object.defineProperty(this, 'hasAppearanceStream', {
+              enumerable: false,
+              get: function get$$1() {
+                  return this.V || this.DV;
+              }
+          });
+      };
+      inherit(AcroFormTextField, AcroFormField);
+
+      var AcroFormPasswordField = function AcroFormPasswordField() {
+          AcroFormTextField.call(this);
+
+          var _password = true;
+          Object.defineProperty(this, 'password', {
+              enumerable: false,
+              get: function get$$1() {
+                  return _password;
+              },
+              set: function set$$1(val) {
+                  _password = val;
+              }
+          });
+      };
+      inherit(AcroFormPasswordField, AcroFormTextField);
+
+      // Contains Methods for creating standard appearances
+      var AcroFormAppearance = {
+          CheckBox: {
+              createAppearanceStream: function createAppearanceStream() {
+                  var appearance = {
+                      N: {
+                          On: AcroFormAppearance.CheckBox.YesNormal
+                      },
+                      D: {
+                          On: AcroFormAppearance.CheckBox.YesPushDown,
+                          Off: AcroFormAppearance.CheckBox.OffPushDown
+                      }
+                  };
+
+                  return appearance;
+              },
+              /**
+               * If any other icons are needed, the number between the brackets can be changed
+               * @returns {string}
+               */
+              createMK: function createMK() {
+                  return "<< /CA (3)>>";
+              },
+              /**
+               * Returns the standard On Appearance for a CheckBox
+               * @returns {AcroFormXObject}
+               */
+              YesPushDown: function YesPushDown(formObject) {
+                  var xobj = createFormXObject(formObject);
+                  var stream = [];
+                  var zapfDingbatsId = scope.internal.getFont("zapfdingbats", "normal").id;
+                  formObject.Q = 1; // set text-alignment as centered
+                  var calcRes = calculateX(formObject, "3", "ZapfDingbats", 50);
+                  stream.push("0.749023 g");
+                  stream.push("0 0 " + AcroFormAppearance.internal.getWidth(formObject).toFixed(2) + " " + AcroFormAppearance.internal.getHeight(formObject).toFixed(2) + " re");
+                  stream.push("f");
+                  stream.push("BMC");
+                  stream.push("q");
+                  stream.push("0 0 1 rg");
+                  stream.push("/" + zapfDingbatsId + " " + calcRes.fontSize.toFixed(2) + " Tf 0 g");
+                  stream.push("BT");
+                  stream.push(calcRes.text);
+                  stream.push("ET");
+                  stream.push("Q");
+                  stream.push("EMC");
+                  xobj.stream = stream.join("\n");
+                  return xobj;
+              },
+
+              YesNormal: function YesNormal(formObject) {
+                  var xobj = createFormXObject(formObject);
+                  var zapfDingbatsId = scope.internal.getFont("zapfdingbats", "normal").id;
+                  var stream = [];
+                  formObject.Q = 1; // set text-alignment as centered
+                  var height = AcroFormAppearance.internal.getHeight(formObject);
+                  var width = AcroFormAppearance.internal.getWidth(formObject);
+                  var calcRes = calculateX(formObject, "3", "ZapfDingbats", height * 0.9);
+                  stream.push("1 g");
+                  stream.push("0 0 " + width.toFixed(2) + " " + height.toFixed(2) + " re");
+                  stream.push("f");
+                  stream.push("q");
+                  stream.push("0 0 1 rg");
+                  stream.push("0 0 " + (width - 1).toFixed(2) + " " + (height - 1).toFixed(2) + " re");
+                  stream.push("W");
+                  stream.push("n");
+                  stream.push("0 g");
+                  stream.push("BT");
+                  stream.push("/" + zapfDingbatsId + " " + calcRes.fontSize.toFixed(2) + " Tf 0 g");
+                  stream.push(calcRes.text);
+                  stream.push("ET");
+                  stream.push("Q");
+                  xobj.stream = stream.join("\n");
+                  return xobj;
+              },
+
+              /**
+               * Returns the standard Off Appearance for a CheckBox
+               * @returns {AcroFormXObject}
+               */
+              OffPushDown: function OffPushDown(formObject) {
+                  var xobj = createFormXObject(formObject);
+                  var stream = [];
+                  stream.push("0.749023 g");
+                  stream.push("0 0 " + AcroFormAppearance.internal.getWidth(formObject).toFixed(2) + " " + AcroFormAppearance.internal.getHeight(formObject).toFixed(2) + " re");
+                  stream.push("f");
+                  xobj.stream = stream.join("\n");
+                  return xobj;
+              }
+          },
+
+          RadioButton: {
+              Circle: {
+                  createAppearanceStream: function createAppearanceStream(name) {
+                      var appearanceStreamContent = {
+                          D: {
+                              'Off': AcroFormAppearance.RadioButton.Circle.OffPushDown
+                          },
+                          N: {}
+                      };
+                      appearanceStreamContent.N[name] = AcroFormAppearance.RadioButton.Circle.YesNormal;
+                      appearanceStreamContent.D[name] = AcroFormAppearance.RadioButton.Circle.YesPushDown;
+                      return appearanceStreamContent;
+                  },
+                  createMK: function createMK() {
+                      return "<< /CA (l)>>";
+                  },
+
+                  YesNormal: function YesNormal(formObject) {
+                      var xobj = createFormXObject(formObject);
+                      var stream = [];
+                      // Make the Radius of the Circle relative to min(height, width) of formObject
+                      var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4;
+                      // The Borderpadding...
+                      DotRadius *= 0.9;
+                      var c = AcroFormAppearance.internal.Bezier_C;
+                      /*
+                       The Following is a Circle created with Bezier-Curves.
+                       */
+                      stream.push("q");
+                      stream.push("1 0 0 1 " + AcroFormAppearance.internal.getWidth(formObject) / 2 + " " + AcroFormAppearance.internal.getHeight(formObject) / 2 + " cm");
+                      stream.push(DotRadius + " 0 m");
+                      stream.push(DotRadius + " " + DotRadius * c + " " + DotRadius * c + " " + DotRadius + " 0 " + DotRadius + " c");
+                      stream.push("-" + DotRadius * c + " " + DotRadius + " -" + DotRadius + " " + DotRadius * c + " -" + DotRadius + " 0 c");
+                      stream.push("-" + DotRadius + " -" + DotRadius * c + " -" + DotRadius * c + " -" + DotRadius + " 0 -" + DotRadius + " c");
+                      stream.push(DotRadius * c + " -" + DotRadius + " " + DotRadius + " -" + DotRadius * c + " " + DotRadius + " 0 c");
+                      stream.push("f");
+                      stream.push("Q");
+                      xobj.stream = stream.join("\n");
+                      return xobj;
+                  },
+                  YesPushDown: function YesPushDown(formObject) {
+                      var xobj = createFormXObject(formObject);
+                      var stream = [];
+                      var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4;
+                      // The Borderpadding...
+                      DotRadius *= 0.9;
+                      // Save results for later use; no need to waste processor ticks on doing math
+                      var k = DotRadius * 2;
+                      // var c = AcroFormAppearance.internal.Bezier_C;
+                      var kc = k * AcroFormAppearance.internal.Bezier_C;
+                      var dc = DotRadius * AcroFormAppearance.internal.Bezier_C;
+
+                      stream.push("0.749023 g");
+                      stream.push("q");
+                      stream.push("1 0 0 1 " + (AcroFormAppearance.internal.getWidth(formObject) / 2).toFixed(2) + " " + (AcroFormAppearance.internal.getHeight(formObject) / 2).toFixed(2) + " cm");
+                      stream.push(k + " 0 m");
+                      stream.push(k + " " + kc + " " + kc + " " + k + " 0 " + k + " c");
+                      stream.push("-" + kc + " " + k + " -" + k + " " + kc + " -" + k + " 0 c");
+                      stream.push("-" + k + " -" + kc + " -" + kc + " -" + k + " 0 -" + k + " c");
+                      stream.push(kc + " -" + k + " " + k + " -" + kc + " " + k + " 0 c");
+                      stream.push("f");
+                      stream.push("Q");
+                      stream.push("0 g");
+                      stream.push("q");
+                      stream.push("1 0 0 1 " + (AcroFormAppearance.internal.getWidth(formObject) / 2).toFixed(2) + " " + (AcroFormAppearance.internal.getHeight(formObject) / 2).toFixed(2) + " cm");
+                      stream.push(DotRadius + " 0 m");
+                      stream.push("" + DotRadius + " " + dc + " " + dc + " " + DotRadius + " 0 " + DotRadius + " c");
+                      stream.push("-" + dc + " " + DotRadius + " -" + DotRadius + " " + dc + " -" + DotRadius + " 0 c");
+                      stream.push("-" + DotRadius + " -" + dc + " -" + dc + " -" + DotRadius + " 0 -" + DotRadius + " c");
+                      stream.push(dc + " -" + DotRadius + " " + DotRadius + " -" + dc + " " + DotRadius + " 0 c");
+                      stream.push("f");
+                      stream.push("Q");
+                      xobj.stream = stream.join("\n");
+                      return xobj;
+                  },
+                  OffPushDown: function OffPushDown(formObject) {
+                      var xobj = createFormXObject(formObject);
+                      var stream = [];
+                      var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4;
+                      // The Borderpadding...
+                      DotRadius *= 0.9;
+                      // Save results for later use; no need to waste processor ticks on doing math
+                      var k = DotRadius * 2;
+                      // var c = AcroFormAppearance.internal.Bezier_C;
+                      var kc = k * AcroFormAppearance.internal.Bezier_C;
+
+                      stream.push("0.749023 g");
+                      stream.push("q");
+                      stream.push("1 0 0 1 " + (AcroFormAppearance.internal.getWidth(formObject) / 2).toFixed(2) + " " + (AcroFormAppearance.internal.getHeight(formObject) / 2).toFixed(2) + " cm");
+                      stream.push(k + " 0 m");
+                      stream.push(k + " " + kc + " " + kc + " " + k + " 0 " + k + " c");
+                      stream.push("-" + kc + " " + k + " -" + k + " " + kc + " -" + k + " 0 c");
+                      stream.push("-" + k + " -" + kc + " -" + kc + " -" + k + " 0 -" + k + " c");
+                      stream.push(kc + " -" + k + " " + k + " -" + kc + " " + k + " 0 c");
+                      stream.push("f");
+                      stream.push("Q");
+                      xobj.stream = stream.join("\n");
+                      return xobj;
+                  }
+              },
+
+              Cross: {
+                  /**
+                   * Creates the Actual AppearanceDictionary-References
+                   * @param name
+                   * @returns
+                   */
+                  createAppearanceStream: function createAppearanceStream(name) {
+                      var appearanceStreamContent = {
+                          D: {
+                              'Off': AcroFormAppearance.RadioButton.Cross.OffPushDown
+                          },
+                          N: {}
+                      };
+                      appearanceStreamContent.N[name] = AcroFormAppearance.RadioButton.Cross.YesNormal;
+                      appearanceStreamContent.D[name] = AcroFormAppearance.RadioButton.Cross.YesPushDown;
+                      return appearanceStreamContent;
+                  },
+                  createMK: function createMK() {
+                      return "<< /CA (8)>>";
+                  },
+
+                  YesNormal: function YesNormal(formObject) {
+                      var xobj = createFormXObject(formObject);
+                      var stream = [];
+                      var cross = AcroFormAppearance.internal.calculateCross(formObject);
+                      stream.push("q");
+                      stream.push("1 1 " + (AcroFormAppearance.internal.getWidth(formObject) - 2).toFixed(2) + " " + (AcroFormAppearance.internal.getHeight(formObject) - 2).toFixed(2) + " re");
+                      stream.push("W");
+                      stream.push("n");
+                      stream.push(cross.x1.x.toFixed(2) + " " + cross.x1.y.toFixed(2) + " m");
+                      stream.push(cross.x2.x.toFixed(2) + " " + cross.x2.y.toFixed(2) + " l");
+                      stream.push(cross.x4.x.toFixed(2) + " " + cross.x4.y.toFixed(2) + " m");
+                      stream.push(cross.x3.x.toFixed(2) + " " + cross.x3.y.toFixed(2) + " l");
+                      stream.push("s");
+                      stream.push("Q");
+                      xobj.stream = stream.join("\n");
+                      return xobj;
+                  },
+                  YesPushDown: function YesPushDown(formObject) {
+                      var xobj = createFormXObject(formObject);
+                      var cross = AcroFormAppearance.internal.calculateCross(formObject);
+                      var stream = [];
+                      stream.push("0.749023 g");
+                      stream.push("0 0 " + AcroFormAppearance.internal.getWidth(formObject).toFixed(2) + " " + AcroFormAppearance.internal.getHeight(formObject).toFixed(2) + " re");
+                      stream.push("f");
+                      stream.push("q");
+                      stream.push("1 1 " + (AcroFormAppearance.internal.getWidth(formObject) - 2).toFixed(2) + " " + (AcroFormAppearance.internal.getHeight(formObject) - 2).toFixed(2) + " re");
+                      stream.push("W");
+                      stream.push("n");
+                      stream.push(cross.x1.x.toFixed(2) + " " + cross.x1.y.toFixed(2) + " m");
+                      stream.push(cross.x2.x.toFixed(2) + " " + cross.x2.y.toFixed(2) + " l");
+                      stream.push(cross.x4.x.toFixed(2) + " " + cross.x4.y.toFixed(2) + " m");
+                      stream.push(cross.x3.x.toFixed(2) + " " + cross.x3.y.toFixed(2) + " l");
+                      stream.push("s");
+                      stream.push("Q");
+                      xobj.stream = stream.join("\n");
+                      return xobj;
+                  },
+                  OffPushDown: function OffPushDown(formObject) {
+                      var xobj = createFormXObject(formObject);
+                      var stream = [];
+                      stream.push("0.749023 g");
+                      stream.push("0 0 " + AcroFormAppearance.internal.getWidth(formObject).toFixed(2) + " " + AcroFormAppearance.internal.getHeight(formObject).toFixed(2) + " re");
+                      stream.push("f");
+                      xobj.stream = stream.join("\n");
+                      return xobj;
+                  }
+              }
+          },
+
+          /**
+           * Returns the standard Appearance
+           * @returns {AcroFormXObject}
+           */
+          createDefaultAppearanceStream: function createDefaultAppearanceStream(formObject) {
+              // Set Helvetica to Standard Font (size: auto)
+              // Color: Black
+              return "/F1 0 Tf 0 g";
+          }
+      };
+
+      AcroFormAppearance.internal = {
+          Bezier_C: 0.551915024494,
+
+          calculateCross: function calculateCross(formObject) {
+              var min = function min(x, y) {
+                  return x > y ? y : x;
+              };
+
+              var width = AcroFormAppearance.internal.getWidth(formObject);
+              var height = AcroFormAppearance.internal.getHeight(formObject);
+              var a = min(width, height);
+
+
+              var cross = {
+                  x1: { // upperLeft
+                      x: (width - a) / 2,
+                      y: (height - a) / 2 + a //height - borderPadding
+                  },
+                  x2: { // lowerRight
+                      x: (width - a) / 2 + a,
+                      y: (height - a) / 2 //borderPadding
+                  },
+                  x3: { // lowerLeft
+                      x: (width - a) / 2,
+                      y: (height - a) / 2 //borderPadding
+                  },
+                  x4: { // upperRight
+                      x: (width - a) / 2 + a,
+                      y: (height - a) / 2 + a //height - borderPadding
+                  }
+              };
+
+              return cross;
+          }
+      };
+      AcroFormAppearance.internal.getWidth = function (formObject) {
+          var result = 0;
+          if ((typeof formObject === 'undefined' ? 'undefined' : _typeof(formObject)) === "object") {
+              result = scale(formObject.Rect[2]); //(formObject.Rect[2] - formObject.Rect[0]) || 0;
+          }
+          return result;
+      };
+      AcroFormAppearance.internal.getHeight = function (formObject) {
+          var result = 0;
+          if ((typeof formObject === 'undefined' ? 'undefined' : _typeof(formObject)) === "object") {
+              result = scale(formObject.Rect[3]); //(formObject.Rect[1] - formObject.Rect[3]) || 0;
+          }
+          return result;
+      };
+
+      // Public:
+
+      jsPDFAPI.addField = function (fieldObject) {
+          initializeAcroForm.call(this);
+          //var opt = parseOptions(fieldObject);
+          if (fieldObject instanceof AcroFormTextField) {
+              this.addTextField.call(this, fieldObject);
+          } else if (fieldObject instanceof AcroFormChoiceField) {
+              this.addChoiceField.call(this, fieldObject);
+          } else if (fieldObject instanceof AcroFormButton) {
+              this.addButton.call(this, fieldObject);
+          } else if (fieldObject instanceof AcroFormChildClass) {
+              putForm.call(this, fieldObject);
+          } else if (fieldObject) {
+              // try to put..
+              putForm.call(this, fieldObject);
+          }
+          fieldObject.page = scope.internal.getCurrentPageInfo().pageNumber;
+          return this;
+      };
+
+      /**
+       * Button
+       * FT = Btn
+       */
+      jsPDFAPI.addButton = function (opts) {
+          initializeAcroForm.call(this);
+          var options = opts || new AcroFormField();
+
+          options.FT = '/Btn';
+          options.Ff = calculateFlagsOnOptions(options.Ff, opts, scope.internal.getPDFVersion());
+
+          putForm.call(this, options);
+      };
+
+      jsPDFAPI.addTextField = function (opts) {
+          initializeAcroForm.call(this);
+          var options = opts || new AcroFormField();
+
+          options.FT = '/Tx';
+
+          options.Ff = calculateFlagsOnOptions(options.Ff, opts, scope.internal.getPDFVersion());
+
+          // Add field
+          putForm.call(this, options);
+      };
+
+      jsPDFAPI.addChoiceField = function (opts) {
+          initializeAcroForm.call(this);
+          var options = opts || new AcroFormField();
+
+          options.FT = '/Ch';
+
+          options.Ff = calculateFlagsOnOptions(options.Ff, opts, scope.internal.getPDFVersion());
+          //options.hasAnnotation = true;
+
+          // Add field
+          putForm.call(this, options);
+      };
+
+      if ((typeof globalObj === 'undefined' ? 'undefined' : _typeof(globalObj)) == "object") {
+          globalObj["ChoiceField"] = AcroFormChoiceField;
+          globalObj["ListBox"] = AcroFormListBox;
+          globalObj["ComboBox"] = AcroFormComboBox;
+          globalObj["EditBox"] = AcroFormEditBox;
+          globalObj["Button"] = AcroFormButton;
+          globalObj["PushButton"] = AcroFormPushButton;
+          globalObj["RadioButton"] = AcroFormRadioButton;
+          globalObj["CheckBox"] = AcroFormCheckBox;
+          globalObj["TextField"] = AcroFormTextField;
+          globalObj["PasswordField"] = AcroFormPasswordField;
+
+          //backwardsCompatibility
+          globalObj["AcroForm"] = { Appearance: AcroFormAppearance };
+      }
+  })(jsPDF.API, typeof window !== "undefined" && window || typeof global !== "undefined" && global);
+
+  /**
+   * jsPDF addHTML PlugIn
+   * Copyright (c) 2014 Diego Casorran
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+
+  (function (jsPDFAPI) {
+
+      /**
+       * Renders an HTML element to canvas object which added to the PDF
+       *
+       * This feature requires [html2canvas](https://github.com/niklasvh/html2canvas)
+       * or [rasterizeHTML](https://github.com/cburgmer/rasterizeHTML.js)
+       *
+       * @returns {jsPDF}
+       * @name addHTML
+       * @param element {Mixed} HTML Element, or anything supported by html2canvas.
+       * @param x {Number} starting X coordinate in jsPDF instance's declared units.
+       * @param y {Number} starting Y coordinate in jsPDF instance's declared units.
+       * @param options {Object} Additional options, check the code below.
+       * @param callback {Function} to call when the rendering has finished.
+       * NOTE: Every parameter is optional except 'element' and 'callback', in such
+       *       case the image is positioned at 0x0 covering the whole PDF document
+       *       size. Ie, to easily take screenshots of webpages saving them to PDF.
+       * @deprecated This is being replace with a vector-supporting API. See
+       * [this link](https://cdn.rawgit.com/MrRio/jsPDF/master/examples/html2pdf/showcase_supported_html.html)
+       */
+
+      jsPDFAPI.addHTML = function (element, x, y, options, callback) {
+
+          if (typeof html2canvas === 'undefined' && typeof rasterizeHTML === 'undefined') throw new Error('You need either ' + 'https://github.com/niklasvh/html2canvas' + ' or https://github.com/cburgmer/rasterizeHTML.js');
+
+          if (typeof x !== 'number') {
+              options = x;
+              callback = y;
+          }
+
+          if (typeof options === 'function') {
+              callback = options;
+              options = null;
+          }
+
+          if (typeof callback !== 'function') {
+              callback = function callback() {};
+          }
+
+          var I = this.internal,
+              K = I.scaleFactor,
+              W = I.pageSize.getWidth(),
+              H = I.pageSize.getHeight();
+
+          options = options || {};
+          options.onrendered = function (obj) {
+              x = parseInt(x) || 0;
+              y = parseInt(y) || 0;
+              var dim = options.dim || {};
+              var margin = Object.assign({ top: 0, right: 0, bottom: 0, left: 0, useFor: 'content' }, options.margin);
+              var h = dim.h || Math.min(H, obj.height / K);
+              var w = dim.w || Math.min(W, obj.width / K) - x;
+
+              var format = options.format || 'JPEG';
+              var imageCompression = options.imageCompression || 'SLOW';
+
+              var notFittingHeight = obj.height > H - margin.top - margin.bottom;
+
+              if (notFittingHeight && options.pagesplit) {
+                  var cropArea = function cropArea(parmObj, parmX, parmY, parmWidth, parmHeight) {
+                      var canvas = document.createElement('canvas');
+                      canvas.height = parmHeight;
+                      canvas.width = parmWidth;
+                      var ctx = canvas.getContext('2d');
+                      ctx.mozImageSmoothingEnabled = false;
+                      ctx.webkitImageSmoothingEnabled = false;
+                      ctx.msImageSmoothingEnabled = false;
+                      ctx.imageSmoothingEnabled = false;
+                      ctx.fillStyle = options.backgroundColor || '#ffffff';
+                      ctx.fillRect(0, 0, parmWidth, parmHeight);
+                      ctx.drawImage(parmObj, parmX, parmY, parmWidth, parmHeight, 0, 0, parmWidth, parmHeight);
+                      return canvas;
+                  };
+                  var crop = function () {
+                      var cy = 0;
+                      var cx = 0;
+                      var position = {};
+                      var isOverWide = false;
+                      var width;
+                      var height;
+                      while (1) {
+                          cx = 0;
+                          position.top = cy !== 0 ? margin.top : y;
+                          position.left = cy !== 0 ? margin.left : x;
+                          isOverWide = (W - margin.left - margin.right) * K < obj.width;
+                          if (margin.useFor === "content") {
+                              if (cy === 0) {
+                                  width = Math.min((W - margin.left) * K, obj.width);
+                                  height = Math.min((H - margin.top) * K, obj.height - cy);
+                              } else {
+                                  width = Math.min(W * K, obj.width);
+                                  height = Math.min(H * K, obj.height - cy);
+                                  position.top = 0;
+                              }
+                          } else {
+                              width = Math.min((W - margin.left - margin.right) * K, obj.width);
+                              height = Math.min((H - margin.bottom - margin.top) * K, obj.height - cy);
+                          }
+                          if (isOverWide) {
+                              while (1) {
+                                  if (margin.useFor === "content") {
+                                      if (cx === 0) {
+                                          width = Math.min((W - margin.left) * K, obj.width);
+                                      } else {
+                                          width = Math.min(W * K, obj.width - cx);
+                                          position.left = 0;
+                                      }
+                                  }
+                                  var canvas = cropArea(obj, cx, cy, width, height);
+                                  var args = [canvas, position.left, position.top, canvas.width / K, canvas.height / K, format, null, imageCompression];
+                                  this.addImage.apply(this, args);
+                                  cx += width;
+                                  if (cx >= obj.width) {
+                                      break;
+                                  }
+                                  this.addPage();
+                              }
+                          } else {
+                              var canvas = cropArea(obj, 0, cy, width, height);
+                              var args = [canvas, position.left, position.top, canvas.width / K, canvas.height / K, format, null, imageCompression];
+                              this.addImage.apply(this, args);
+                          }
+                          cy += height;
+                          if (cy >= obj.height) {
+                              break;
+                          }
+                          this.addPage();
+                      }
+                      callback(w, cy, null, args);
+                  }.bind(this);
+                  if (obj.nodeName === 'CANVAS') {
+                      var img = new Image();
+                      img.onload = crop;
+                      img.src = obj.toDataURL("image/png");
+                      obj = img;
+                  } else {
+                      crop();
+                  }
+              } else {
+                  var alias = Math.random().toString(35);
+                  var args = [obj, x, y, w, h, format, alias, imageCompression];
+
+                  this.addImage.apply(this, args);
+
+                  callback(w, h, alias, args);
+              }
+          }.bind(this);
+
+          if (typeof html2canvas !== 'undefined' && !options.rstz) {
+              return html2canvas(element, options);
+          }
+
+          if (typeof rasterizeHTML !== 'undefined') {
+              var meth = 'drawDocument';
+              if (typeof element === 'string') {
+                  meth = /^http/.test(element) ? 'drawURL' : 'drawHTML';
+              }
+              options.width = options.width || W * K;
+              return rasterizeHTML[meth](element, void 0, options).then(function (r) {
+                  options.onrendered(r.image);
+              }, function (e) {
+                  callback(null, e);
+              });
+          }
+
+          return null;
+      };
+  })(jsPDF.API);
+
+  /** @preserve
+   * jsPDF addImage plugin
+   * Copyright (c) 2012 Jason Siefken, https://github.com/siefkenj/
+   *               2013 Chris Dowling, https://github.com/gingerchris
+   *               2013 Trinh Ho, https://github.com/ineedfat
+   *               2013 Edwin Alejandro Perez, https://github.com/eaparango
+   *               2013 Norah Smith, https://github.com/burnburnrocket
+   *               2014 Diego Casorran, https://github.com/diegocr
+   *               2014 James Robb, https://github.com/jamesbrobb
+   *
+   * 
+   */
+  (function (jsPDFAPI) {
+
+  	var namespace = 'addImage_';
+
+  	var imageFileTypeHeaders = {
+  		PNG: [[0x89, 0x50, 0x4e, 0x47]],
+  		TIFF: [[0x4D, 0x4D, 0x00, 0x2A], //Motorola
+  		[0x49, 0x49, 0x2A, 0x00] //Intel
+  		],
+  		JPEG: [[0xFF, 0xD8, 0xFF, 0xE0, undefined, undefined, 0x4A, 0x46, 0x49, 0x46, 0x00], //JFIF
+  		[0xFF, 0xD8, 0xFF, 0xE1, undefined, undefined, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00] //Exif
+  		],
+  		JPEG2000: [[0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20]],
+  		GIF87a: [[0x47, 0x49, 0x46, 0x38, 0x37, 0x61]],
+  		GIF89a: [[0x47, 0x49, 0x46, 0x38, 0x39, 0x61]],
+  		BMP: [[0x42, 0x4D], //BM - Windows 3.1x, 95, NT, ... etc.
+  		[0x42, 0x41], //BA - OS/2 struct bitmap array
+  		[0x43, 0x49], //CI - OS/2 struct color icon
+  		[0x43, 0x50], //CP - OS/2 const color pointer
+  		[0x49, 0x43], //IC - OS/2 struct icon
+  		[0x50, 0x54] //PT - OS/2 pointer
+  		]
+  	};
+
+  	jsPDFAPI.getImageFileTypeByImageData = function (imageData) {
+  		var i;
+  		var j;
+  		var result = 'UNKNOWN';
+  		var headerSchemata;
+  		var compareResult;
+  		var fileType;
+
+  		for (fileType in imageFileTypeHeaders) {
+  			headerSchemata = imageFileTypeHeaders[fileType];
+  			for (i = 0; i < headerSchemata.length; i += 1) {
+  				compareResult = true;
+  				for (j = 0; j < headerSchemata[i].length; j += 1) {
+  					if (headerSchemata[i][j] === undefined) {
+  						continue;
+  					}
+  					if (headerSchemata[i][j] !== imageData.charCodeAt(j)) {
+  						compareResult = false;
+  						break;
+  					}
+  				}
+  				if (compareResult === true) {
+  					result = fileType;
+  					break;
+  				}
+  			}
+  		}
+  		return result;
+  	};
+
+  	// Image functionality ported from pdf.js
+  	var putImage = function putImage(img) {
+
+  		var objectNumber = this.internal.newObject(),
+  		    out = this.internal.write,
+  		    putStream = this.internal.putStream;
+
+  		img['n'] = objectNumber;
+
+  		out('<</Type /XObject');
+  		out('/Subtype /Image');
+  		out('/Width ' + img['w']);
+  		out('/Height ' + img['h']);
+  		if (img['cs'] === this.color_spaces.INDEXED) {
+  			out('/ColorSpace [/Indexed /DeviceRGB '
+  			// if an indexed png defines more than one colour with transparency, we've created a smask
+  			+ (img['pal'].length / 3 - 1) + ' ' + ('smask' in img ? objectNumber + 2 : objectNumber + 1) + ' 0 R]');
+  		} else {
+  			out('/ColorSpace /' + img['cs']);
+  			if (img['cs'] === this.color_spaces.DEVICE_CMYK) {
+  				out('/Decode [1 0 1 0 1 0 1 0]');
+  			}
+  		}
+  		out('/BitsPerComponent ' + img['bpc']);
+  		if ('f' in img) {
+  			out('/Filter /' + img['f']);
+  		}
+  		if ('dp' in img) {
+  			out('/DecodeParms <<' + img['dp'] + '>>');
+  		}
+  		if ('trns' in img && img['trns'].constructor == Array) {
+  			var trns = '',
+  			    i = 0,
+  			    len = img['trns'].length;
+  			for (; i < len; i++) {
+  				trns += img['trns'][i] + ' ' + img['trns'][i] + ' ';
+  			}out('/Mask [' + trns + ']');
+  		}
+  		if ('smask' in img) {
+  			out('/SMask ' + (objectNumber + 1) + ' 0 R');
+  		}
+  		out('/Length ' + img['data'].length + '>>');
+
+  		putStream(img['data']);
+
+  		out('endobj');
+
+  		// Soft mask
+  		if ('smask' in img) {
+  			var dp = '/Predictor ' + img['p'] + ' /Colors 1 /BitsPerComponent ' + img['bpc'] + ' /Columns ' + img['w'];
+  			var smask = { 'w': img['w'], 'h': img['h'], 'cs': 'DeviceGray', 'bpc': img['bpc'], 'dp': dp, 'data': img['smask'] };
+  			if ('f' in img) smask.f = img['f'];
+  			putImage.call(this, smask);
+  		}
+
+  		//Palette
+  		if (img['cs'] === this.color_spaces.INDEXED) {
+
+  			this.internal.newObject();
+  			//out('<< /Filter / ' + img['f'] +' /Length ' + img['pal'].length + '>>');
+  			//putStream(zlib.compress(img['pal']));
+  			out('<< /Length ' + img['pal'].length + '>>');
+  			putStream(this.arrayBufferToBinaryString(new Uint8Array(img['pal'])));
+  			out('endobj');
+  		}
+  	},
+  	    putResourcesCallback = function putResourcesCallback() {
+  		var images = this.internal.collections[namespace + 'images'];
+  		for (var i in images) {
+  			putImage.call(this, images[i]);
+  		}
+  	},
+  	    putXObjectsDictCallback = function putXObjectsDictCallback() {
+  		var images = this.internal.collections[namespace + 'images'],
+  		    out = this.internal.write,
+  		    image;
+  		for (var i in images) {
+  			image = images[i];
+  			out('/I' + image['i'], image['n'], '0', 'R');
+  		}
+  	},
+  	    checkCompressValue = function checkCompressValue(value) {
+  		if (value && typeof value === 'string') value = value.toUpperCase();
+  		return value in jsPDFAPI.image_compression ? value : jsPDFAPI.image_compression.NONE;
+  	},
+  	    getImages = function getImages() {
+  		var images = this.internal.collections[namespace + 'images'];
+  		//first run, so initialise stuff
+  		if (!images) {
+  			this.internal.collections[namespace + 'images'] = images = {};
+  			this.internal.events.subscribe('putResources', putResourcesCallback);
+  			this.internal.events.subscribe('putXobjectDict', putXObjectsDictCallback);
+  		}
+
+  		return images;
+  	},
+  	    getImageIndex = function getImageIndex(images) {
+  		var imageIndex = 0;
+
+  		if (images) {
+  			// this is NOT the first time this method is ran on this instance of jsPDF object.
+  			imageIndex = Object.keys ? Object.keys(images).length : function (o) {
+  				var i = 0;
+  				for (var e in o) {
+  					if (o.hasOwnProperty(e)) {
+  						i++;
+  					}
+  				}
+  				return i;
+  			}(images);
+  		}
+
+  		return imageIndex;
+  	},
+  	    notDefined = function notDefined(value) {
+  		return typeof value === 'undefined' || value === null || value.length === 0;
+  	},
+  	    generateAliasFromData = function generateAliasFromData(data) {
+  		return typeof data === 'string' && jsPDFAPI.sHashCode(data);
+  	},
+  	    isImageTypeSupported = function isImageTypeSupported(type) {
+  		return typeof jsPDFAPI["process" + type.toUpperCase()] === "function";
+  	},
+  	    isDOMElement = function isDOMElement(object) {
+  		return (typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object' && object.nodeType === 1;
+  	},
+  	    createDataURIFromElement = function createDataURIFromElement(element, format) {
+
+  		//if element is an image which uses data url definition, just return the dataurl
+  		if (element.nodeName === 'IMG' && element.hasAttribute('src')) {
+  			var src = '' + element.getAttribute('src');
+  			if (src.indexOf('data:image/') === 0) return src;
+
+  			// only if the user doesn't care about a format
+  			if (!format && /\.png(?:[?#].*)?$/i.test(src)) format = 'png';
+  		}
+
+  		if (element.nodeName === 'CANVAS') {
+  			var canvas = element;
+  		} else {
+  			var canvas = document.createElement('canvas');
+  			canvas.width = element.clientWidth || element.width;
+  			canvas.height = element.clientHeight || element.height;
+
+  			var ctx = canvas.getContext('2d');
+  			if (!ctx) {
+  				throw 'addImage requires canvas to be supported by browser.';
+  			}
+  			ctx.drawImage(element, 0, 0, canvas.width, canvas.height);
+  		}
+  		return canvas.toDataURL(('' + format).toLowerCase() == 'png' ? 'image/png' : 'image/jpeg');
+  	},
+  	    checkImagesForAlias = function checkImagesForAlias(alias, images) {
+  		var cached_info;
+  		if (images) {
+  			for (var e in images) {
+  				if (alias === images[e].alias) {
+  					cached_info = images[e];
+  					break;
+  				}
+  			}
+  		}
+  		return cached_info;
+  	},
+  	    determineWidthAndHeight = function determineWidthAndHeight(w, h, info) {
+  		if (!w && !h) {
+  			w = -96;
+  			h = -96;
+  		}
+  		if (w < 0) {
+  			w = -1 * info['w'] * 72 / w / this.internal.scaleFactor;
+  		}
+  		if (h < 0) {
+  			h = -1 * info['h'] * 72 / h / this.internal.scaleFactor;
+  		}
+  		if (w === 0) {
+  			w = h * info['w'] / info['h'];
+  		}
+  		if (h === 0) {
+  			h = w * info['h'] / info['w'];
+  		}
+
+  		return [w, h];
+  	},
+  	    writeImageToPDF = function writeImageToPDF(x, y, w, h, info, index, images, rotation) {
+  		var dims = determineWidthAndHeight.call(this, w, h, info),
+  		    coord = this.internal.getCoordinateString,
+  		    vcoord = this.internal.getVerticalCoordinateString;
+
+  		w = dims[0];
+  		h = dims[1];
+
+  		images[index] = info;
+
+  		if (rotation) {
+  			rotation *= Math.PI / 180;
+  			var c = Math.cos(rotation);
+  			var s = Math.sin(rotation);
+  			//like in pdf Reference do it 4 digits instead of 2
+  			var f4 = function f4(number) {
+  				return number.toFixed(4);
+  			};
+  			var rotationTransformationMatrix = [f4(c), f4(s), f4(s * -1), f4(c), 0, 0, 'cm'];
+  		}
+  		this.internal.write('q'); //Save graphics state
+  		if (rotation) {
+  			this.internal.write([1, '0', '0', 1, coord(x), vcoord(y + h), 'cm'].join(' ')); //Translate
+  			this.internal.write(rotationTransformationMatrix.join(' ')); //Rotate
+  			this.internal.write([coord(w), '0', '0', coord(h), '0', '0', 'cm'].join(' ')); //Scale
+  		} else {
+  			this.internal.write([coord(w), '0', '0', coord(h), coord(x), vcoord(y + h), 'cm'].join(' ')); //Translate and Scale
+  		}
+  		this.internal.write('/I' + info['i'] + ' Do'); //Paint Image
+  		this.internal.write('Q'); //Restore graphics state
+  	};
+
+  	/**
+    * COLOR SPACES
+    */
+  	jsPDFAPI.color_spaces = {
+  		DEVICE_RGB: 'DeviceRGB',
+  		DEVICE_GRAY: 'DeviceGray',
+  		DEVICE_CMYK: 'DeviceCMYK',
+  		CAL_GREY: 'CalGray',
+  		CAL_RGB: 'CalRGB',
+  		LAB: 'Lab',
+  		ICC_BASED: 'ICCBased',
+  		INDEXED: 'Indexed',
+  		PATTERN: 'Pattern',
+  		SEPARATION: 'Separation',
+  		DEVICE_N: 'DeviceN'
+  	};
+
+  	/**
+    * DECODE METHODS
+    */
+  	jsPDFAPI.decode = {
+  		DCT_DECODE: 'DCTDecode',
+  		FLATE_DECODE: 'FlateDecode',
+  		LZW_DECODE: 'LZWDecode',
+  		JPX_DECODE: 'JPXDecode',
+  		JBIG2_DECODE: 'JBIG2Decode',
+  		ASCII85_DECODE: 'ASCII85Decode',
+  		ASCII_HEX_DECODE: 'ASCIIHexDecode',
+  		RUN_LENGTH_DECODE: 'RunLengthDecode',
+  		CCITT_FAX_DECODE: 'CCITTFaxDecode'
+  	};
+
+  	/**
+    * IMAGE COMPRESSION TYPES
+    */
+  	jsPDFAPI.image_compression = {
+  		NONE: 'NONE',
+  		FAST: 'FAST',
+  		MEDIUM: 'MEDIUM',
+  		SLOW: 'SLOW'
+  	};
+
+  	jsPDFAPI.sHashCode = function (str) {
+  		str = str || "";
+  		return Array.prototype.reduce && str.split("").reduce(function (a, b) {
+  			a = (a << 5) - a + b.charCodeAt(0);return a & a;
+  		}, 0);
+  	};
+
+  	jsPDFAPI.isString = function (object) {
+  		return typeof object === 'string';
+  	};
+
+  	/**
+   * Regex taken from https://github.com/kevva/base64-regex
+   **/
+  	jsPDFAPI.validateStringAsBase64 = function (possibleBase64String) {
+  		possibleBase64String = possibleBase64String || '';
+  		var base64Regex = new RegExp('(?:^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$)');
+  		return base64Regex.test(possibleBase64String);
+  	};
+
+  	/**
+    * Strips out and returns info from a valid base64 data URI
+    * @param {String[dataURI]} a valid data URI of format 'data:[<MIME-type>][;base64],<data>'
+    * @returns an Array containing the following
+    * [0] the complete data URI
+    * [1] <MIME-type>
+    * [2] format - the second part of the mime-type i.e 'png' in 'image/png'
+    * [4] <data>
+    */
+  	jsPDFAPI.extractInfoFromBase64DataURI = function (dataURI) {
+  		return (/^data:([\w]+?\/([\w]+?));base64,(.+?)$/g.exec(dataURI)
+  		);
+  	};
+
+  	/**
+    * Check to see if ArrayBuffer is supported
+    */
+  	jsPDFAPI.supportsArrayBuffer = function () {
+  		return typeof ArrayBuffer !== 'undefined' && typeof Uint8Array !== 'undefined';
+  	};
+
+  	/**
+    * Tests supplied object to determine if ArrayBuffer
+    * @param {Object[object]}
+    */
+  	jsPDFAPI.isArrayBuffer = function (object) {
+  		if (!this.supportsArrayBuffer()) return false;
+  		return object instanceof ArrayBuffer;
+  	};
+
+  	/**
+    * Tests supplied object to determine if it implements the ArrayBufferView (TypedArray) interface
+    * @param {Object[object]}
+    */
+  	jsPDFAPI.isArrayBufferView = function (object) {
+  		if (!this.supportsArrayBuffer()) return false;
+  		if (typeof Uint32Array === 'undefined') return false;
+  		return object instanceof Int8Array || object instanceof Uint8Array || typeof Uint8ClampedArray !== 'undefined' && object instanceof Uint8ClampedArray || object instanceof Int16Array || object instanceof Uint16Array || object instanceof Int32Array || object instanceof Uint32Array || object instanceof Float32Array || object instanceof Float64Array;
+  	};
+
+  	/**
+    * Exactly what it says on the tin
+    */
+  	jsPDFAPI.binaryStringToUint8Array = function (binary_string) {
+  		/*
+     * not sure how efficient this will be will bigger files. Is there a native method?
+     */
+  		var len = binary_string.length;
+  		var bytes = new Uint8Array(len);
+  		for (var i = 0; i < len; i++) {
+  			bytes[i] = binary_string.charCodeAt(i);
+  		}
+  		return bytes;
+  	};
+
+  	/**
+    * Convert the Buffer to a Binary String
+    */
+  	jsPDFAPI.arrayBufferToBinaryString = function (buffer) {
+
+  		if (typeof atob === "function") {
+  			return atob(this.arrayBufferToBase64(buffer));
+  		}
+
+  		if (typeof TextDecoder === "function") {
+  			var decoder = new TextDecoder('ascii');
+  			// test if the encoding is supported
+  			if (decoder.encoding === 'ascii') {
+  				return decoder.decode(buffer);
+  			}
+  		}
+
+  		//Fallback-solution
+  		var data = this.isArrayBuffer(buffer) ? buffer : new Uint8Array(buffer);
+  		var chunkSizeForSlice = 0x5000;
+  		var binary_string = '';
+  		var slicesCount = Math.ceil(data.byteLength / chunkSizeForSlice);
+  		for (var i = 0; i < slicesCount; i++) {
+  			binary_string += String.fromCharCode.apply(null, data.slice(i * chunkSizeForSlice, i * chunkSizeForSlice + chunkSizeForSlice));
+  		}
+  		return binary_string;
+  	};
+
+  	/**
+    * Converts an ArrayBuffer directly to base64
+    *
+    * Taken from here
+    *
+    * http://jsperf.com/encoding-xhr-image-data/31
+    *
+    * Need to test if this is a better solution for larger files
+    *
+    */
+  	jsPDFAPI.arrayBufferToBase64 = function (arrayBuffer) {
+  		var base64 = '';
+  		var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+
+  		var bytes = new Uint8Array(arrayBuffer);
+  		var byteLength = bytes.byteLength;
+  		var byteRemainder = byteLength % 3;
+  		var mainLength = byteLength - byteRemainder;
+
+  		var a, b, c, d;
+  		var chunk;
+
+  		// Main loop deals with bytes in chunks of 3
+  		for (var i = 0; i < mainLength; i = i + 3) {
+  			// Combine the three bytes into a single integer
+  			chunk = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
+
+  			// Use bitmasks to extract 6-bit segments from the triplet
+  			a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18
+  			b = (chunk & 258048) >> 12; // 258048   = (2^6 - 1) << 12
+  			c = (chunk & 4032) >> 6; // 4032     = (2^6 - 1) << 6
+  			d = chunk & 63; // 63       = 2^6 - 1
+
+  			// Convert the raw binary segments to the appropriate ASCII encoding
+  			base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d];
+  		}
+
+  		// Deal with the remaining bytes and padding
+  		if (byteRemainder == 1) {
+  			chunk = bytes[mainLength];
+
+  			a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2
+
+  			// Set the 4 least significant bits to zero
+  			b = (chunk & 3) << 4; // 3   = 2^2 - 1
+
+  			base64 += encodings[a] + encodings[b] + '==';
+  		} else if (byteRemainder == 2) {
+  			chunk = bytes[mainLength] << 8 | bytes[mainLength + 1];
+
+  			a = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10
+  			b = (chunk & 1008) >> 4; // 1008  = (2^6 - 1) << 4
+
+  			// Set the 2 least significant bits to zero
+  			c = (chunk & 15) << 2; // 15    = 2^4 - 1
+
+  			base64 += encodings[a] + encodings[b] + encodings[c] + '=';
+  		}
+
+  		return base64;
+  	};
+
+  	jsPDFAPI.createImageInfo = function (data, wd, ht, cs, bpc, f, imageIndex, alias, dp, trns, pal, smask, p) {
+  		var info = {
+  			alias: alias,
+  			w: wd,
+  			h: ht,
+  			cs: cs,
+  			bpc: bpc,
+  			i: imageIndex,
+  			data: data
+  			// n: objectNumber will be added by putImage code
+  		};
+
+  		if (f) info.f = f;
+  		if (dp) info.dp = dp;
+  		if (trns) info.trns = trns;
+  		if (pal) info.pal = pal;
+  		if (smask) info.smask = smask;
+  		if (p) info.p = p; // predictor parameter for PNG compression
+
+  		return info;
+  	};
+
+  	jsPDFAPI.addImage = function (imageData, format, x, y, w, h, alias, compression, rotation) {
+
+  		var tmpImageData = '';
+
+  		if (typeof format !== 'string') {
+  			var tmp = h;
+  			h = w;
+  			w = y;
+  			y = x;
+  			x = format;
+  			format = tmp;
+  		}
+
+  		if ((typeof imageData === 'undefined' ? 'undefined' : _typeof(imageData)) === 'object' && !isDOMElement(imageData) && "imageData" in imageData) {
+  			var options = imageData;
+
+  			imageData = options.imageData;
+  			format = options.format || format;
+  			x = options.x || x || 0;
+  			y = options.y || y || 0;
+  			w = options.w || w;
+  			h = options.h || h;
+  			alias = options.alias || alias;
+  			compression = options.compression || compression;
+  			rotation = options.rotation || options.angle || rotation;
+  		}
+
+  		if (isNaN(x) || isNaN(y)) {
+  			console.error('jsPDF.addImage: Invalid coordinates', arguments);
+  			throw new Error('Invalid coordinates passed to jsPDF.addImage');
+  		}
+
+  		var images = getImages.call(this),
+  		    info;
+
+  		if (!(info = checkImagesForAlias(imageData, images))) {
+  			var dataAsBinaryString;
+
+  			if (isDOMElement(imageData)) imageData = createDataURIFromElement(imageData, format);
+
+  			if (notDefined(alias)) alias = generateAliasFromData(imageData);
+
+  			if (!(info = checkImagesForAlias(alias, images))) {
+  				if (this.isString(imageData)) {
+  					tmpImageData = this.convertStringToImageData(imageData);
+
+  					if (tmpImageData !== '') {
+  						imageData = tmpImageData;
+  					} else {
+  						tmpImageData = this.loadImageFile(imageData);
+  						if (tmpImageData !== undefined) {
+  							imageData = tmpImageData;
+  						}
+  					}
+  				}
+  				format = this.getImageFileTypeByImageData(imageData);
+
+  				if (!isImageTypeSupported(format)) throw new Error('addImage does not support files of type \'' + format + '\', please ensure that a plugin for \'' + format + '\' support is added.');
+
+  				/**
+       * need to test if it's more efficient to convert all binary strings
+       * to TypedArray - or should we just leave and process as string?
+       */
+  				if (this.supportsArrayBuffer()) {
+  					// no need to convert if imageData is already uint8array
+  					if (!(imageData instanceof Uint8Array)) {
+  						dataAsBinaryString = imageData;
+  						imageData = this.binaryStringToUint8Array(imageData);
+  					}
+  				}
+
+  				info = this['process' + format.toUpperCase()](imageData, getImageIndex(images), alias, checkCompressValue(compression), dataAsBinaryString);
+
+  				if (!info) throw new Error('An unkwown error occurred whilst processing the image');
+  			}
+  		}
+  		writeImageToPDF.call(this, x, y, w, h, info, info.i, images, rotation);
+
+  		return this;
+  	};
+
+  	jsPDFAPI.convertStringToImageData = function (stringData) {
+  		var base64Info;
+  		var imageData = '';
+  		if (this.isString(stringData)) {
+  			var base64Info = this.extractInfoFromBase64DataURI(stringData);
+
+  			if (base64Info !== null) {
+  				if (jsPDFAPI.validateStringAsBase64(base64Info[3])) {
+  					imageData = atob(base64Info[3]); //convert to binary string
+  				}
+  			} else if (jsPDFAPI.validateStringAsBase64(stringData)) {
+  				imageData = atob(stringData);
+  			}
+  		}
+  		return imageData;
+  	};
+  	/**
+    * JPEG SUPPORT
+    **/
+
+  	//takes a string imgData containing the raw bytes of
+  	//a jpeg image and returns [width, height]
+  	//Algorithm from: http://www.64lines.com/jpeg-width-height
+  	var getJpegSize = function getJpegSize(imgData) {
+
+  		var width, height, numcomponents;
+  		// Verify we have a valid jpeg header 0xff,0xd8,0xff,0xe0,?,?,'J','F','I','F',0x00
+  		if (!imgData.charCodeAt(0) === 0xff || !imgData.charCodeAt(1) === 0xd8 || !imgData.charCodeAt(2) === 0xff || !imgData.charCodeAt(3) === 0xe0 || !imgData.charCodeAt(6) === 'J'.charCodeAt(0) || !imgData.charCodeAt(7) === 'F'.charCodeAt(0) || !imgData.charCodeAt(8) === 'I'.charCodeAt(0) || !imgData.charCodeAt(9) === 'F'.charCodeAt(0) || !imgData.charCodeAt(10) === 0x00) {
+  			throw new Error('getJpegSize requires a binary string jpeg file');
+  		}
+  		var blockLength = imgData.charCodeAt(4) * 256 + imgData.charCodeAt(5);
+  		var i = 4,
+  		    len = imgData.length;
+  		while (i < len) {
+  			i += blockLength;
+  			if (imgData.charCodeAt(i) !== 0xff) {
+  				throw new Error('getJpegSize could not find the size of the image');
+  			}
+  			if (imgData.charCodeAt(i + 1) === 0xc0 || //(SOF) Huffman  - Baseline DCT
+  			imgData.charCodeAt(i + 1) === 0xc1 || //(SOF) Huffman  - Extended sequential DCT
+  			imgData.charCodeAt(i + 1) === 0xc2 || // Progressive DCT (SOF2)
+  			imgData.charCodeAt(i + 1) === 0xc3 || // Spatial (sequential) lossless (SOF3)
+  			imgData.charCodeAt(i + 1) === 0xc4 || // Differential sequential DCT (SOF5)
+  			imgData.charCodeAt(i + 1) === 0xc5 || // Differential progressive DCT (SOF6)
+  			imgData.charCodeAt(i + 1) === 0xc6 || // Differential spatial (SOF7)
+  			imgData.charCodeAt(i + 1) === 0xc7) {
+  				height = imgData.charCodeAt(i + 5) * 256 + imgData.charCodeAt(i + 6);
+  				width = imgData.charCodeAt(i + 7) * 256 + imgData.charCodeAt(i + 8);
+  				numcomponents = imgData.charCodeAt(i + 9);
+  				return [width, height, numcomponents];
+  			} else {
+  				i += 2;
+  				blockLength = imgData.charCodeAt(i) * 256 + imgData.charCodeAt(i + 1);
+  			}
+  		}
+  	},
+  	    getJpegSizeFromBytes = function getJpegSizeFromBytes(data) {
+
+  		var hdr = data[0] << 8 | data[1];
+
+  		if (hdr !== 0xFFD8) throw new Error('Supplied data is not a JPEG');
+
+  		var len = data.length,
+  		    block = (data[4] << 8) + data[5],
+  		    pos = 4,
+  		    bytes,
+  		    width,
+  		    height,
+  		    numcomponents;
+
+  		while (pos < len) {
+  			pos += block;
+  			bytes = readBytes(data, pos);
+  			block = (bytes[2] << 8) + bytes[3];
+  			if ((bytes[1] === 0xC0 || bytes[1] === 0xC2) && bytes[0] === 0xFF && block > 7) {
+  				bytes = readBytes(data, pos + 5);
+  				width = (bytes[2] << 8) + bytes[3];
+  				height = (bytes[0] << 8) + bytes[1];
+  				numcomponents = bytes[4];
+  				return { width: width, height: height, numcomponents: numcomponents };
+  			}
+
+  			pos += 2;
+  		}
+
+  		throw new Error('getJpegSizeFromBytes could not find the size of the image');
+  	},
+  	    readBytes = function readBytes(data, offset) {
+  		return data.subarray(offset, offset + 5);
+  	};
+
+  	jsPDFAPI.processJPEG = function (data, index, alias, compression, dataAsBinaryString, colorSpace) {
+
+  		var filter = this.decode.DCT_DECODE,
+  		    bpc = 8,
+  		    dims;
+
+  		if (!this.isString(data) && !this.isArrayBuffer(data) && !this.isArrayBufferView(data)) {
+  			return null;
+  		}
+
+  		if (this.isString(data)) {
+  			dims = getJpegSize(data);
+  		}
+
+  		if (this.isArrayBuffer(data)) {
+  			data = new Uint8Array(data);
+  		}
+  		if (this.isArrayBufferView(data)) {
+
+  			dims = getJpegSizeFromBytes(data);
+
+  			// if we already have a stored binary string rep use that
+  			data = dataAsBinaryString || this.arrayBufferToBinaryString(data);
+  		}
+
+  		if (colorSpace === undefined) {
+  			switch (dims.numcomponents) {
+  				case 1:
+  					colorSpace = this.color_spaces.DEVICE_GRAY;
+  					break;
+  				case 4:
+  					colorSpace = this.color_spaces.DEVICE_CMYK;
+  					break;
+  				default:
+  				case 3:
+  					colorSpace = this.color_spaces.DEVICE_RGB;
+  					break;
+  			}
+  		}
+
+  		return this.createImageInfo(data, dims.width, dims.height, colorSpace, bpc, filter, index, alias);
+  	};
+
+  	jsPDFAPI.processJPG = function () /*data, index, alias, compression, dataAsBinaryString*/{
+  		return this.processJPEG.apply(this, arguments);
+  	};
+
+  	jsPDFAPI.loadImageFile = function (path, sync, callback) {
+  		sync = sync || true;
+  		callback = callback || function () {};
+  		var isNode = Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]';
+
+  		var xhrMethod = function xhrMethod(url, sync, callback) {
+  			var req = new XMLHttpRequest();
+  			var byteArray = [];
+  			var i = 0;
+
+  			var sanitizeUnicode = function sanitizeUnicode(data) {
+  				var dataLength = data.length;
+  				var StringFromCharCode = String.fromCharCode;
+
+  				//Transform Unicode to ASCII
+  				for (i = 0; i < dataLength; i += 1) {
+  					byteArray.push(StringFromCharCode(data.charCodeAt(i) & 0xff));
+  				}
+  				return byteArray.join("");
+  			};
+
+  			req.open('GET', url, !sync);
+  			// XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
+  			req.overrideMimeType('text\/plain; charset=x-user-defined');
+
+  			if (sync === false) {
+  				req.onload = function () {
+  					return sanitizeUnicode(this.responseText);
+  				};
+  			}
+  			req.send(null);
+
+  			if (req.status !== 200) {
+  				console.warn('Unable to load file "' + url + '"');
+  				return;
+  			}
+
+  			if (sync) {
+  				return sanitizeUnicode(req.responseText);
+  			}
+  		};
+
+  		var nodeJSMethod = function nodeJSMethod(path, sync, callback) {
+  			sync = sync || true;
+  			var fs = require('fs');
+  			if (sync === true) {
+  				var data = fs.readFileSync(path).toString();
+  				return data;
+  			} else {
+  				fs.readFile('image.jpg', function (err, data) {
+  					callback(data);
+  				});
+  			}
+  		};
+
+  		//we have a browser and probably no CORS-Problem
+  		if ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) !== undefined && (typeof location === 'undefined' ? 'undefined' : _typeof(location)) === "object" && location.protocol.substr(0, 4) === "http") {
+  			return xhrMethod(path, sync, callback);
+  		} else if (isNode) {
+  			return nodeJSMethod(path, sync, callback);
+  		}
+  	};
+
+  	jsPDFAPI.getImageProperties = function (imageData) {
+  		var info;
+  		var tmpImageData = '';
+  		var format;
+
+  		if (isDOMElement(imageData)) {
+  			imageData = createDataURIFromElement(imageData);
+  		}
+
+  		if (this.isString(imageData)) {
+  			tmpImageData = this.convertStringToImageData(imageData);
+
+  			if (tmpImageData !== '') {
+  				imageData = tmpImageData;
+  			} else {
+  				tmpImageData = this.loadImageFile(imageData);
+  				if (tmpImageData !== undefined) {
+  					imageData = tmpImageData;
+  				}
+  			}
+  		}
+  		format = this.getImageFileTypeByImageData(imageData);
+
+  		if (!isImageTypeSupported(format)) throw new Error('addImage does not support files of type \'' + format + '\', please ensure that a plugin for \'' + format + '\' support is added.');
+
+  		/**
+     * need to test if it's more efficient to convert all binary strings
+     * to TypedArray - or should we just leave and process as string?
+     */
+  		if (this.supportsArrayBuffer()) {
+  			// no need to convert if imageData is already uint8array
+  			if (!(imageData instanceof Uint8Array)) {
+  				imageData = this.binaryStringToUint8Array(imageData);
+  			}
+  		}
+
+  		info = this['process' + format.toUpperCase()](imageData);
+
+  		if (!info) {
+  			throw new Error('An unkwown error occurred whilst processing the image');
+  		}
+
+  		return {
+  			fileType: format,
+  			width: info.w,
+  			height: info.h,
+  			colorSpace: info.cs,
+  			compressionMode: info.f,
+  			bitsPerComponent: info.bpc
+  		};
+  	};
+  })(jsPDF.API);
+
+  /**
+   * jsPDF Annotations PlugIn
+   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+
+  /**
+   * There are many types of annotations in a PDF document. Annotations are placed
+   * on a page at a particular location. They are not 'attached' to an object.
+   * <br />
+   * This plugin current supports <br />
+   * <li> Goto Page (set pageNumber and top in options)
+   * <li> Goto Name (set name and top in options)
+   * <li> Goto URL (set url in options)
+   * <p>
+   * 	The destination magnification factor can also be specified when goto is a page number or a named destination. (see documentation below)
+   *  (set magFactor in options).  XYZ is the default.
+   * </p>
+   * <p>
+   *  Links, Text, Popup, and FreeText are supported.
+   * </p>
+   * <p>
+   * Options In PDF spec Not Implemented Yet
+   * <li> link border
+   * <li> named target
+   * <li> page coordinates
+   * <li> destination page scaling and layout
+   * <li> actions other than URL and GotoPage
+   * <li> background / hover actions
+   * </p>
+   */
+
+  /*
+      Destination Magnification Factors
+      See PDF 1.3 Page 386 for meanings and options
+
+      [supported]
+  	XYZ (options; left top zoom)
+  	Fit (no options)
+  	FitH (options: top)
+  	FitV (options: left)
+
+  	[not supported]
+  	FitR
+  	FitB
+  	FitBH
+  	FitBV
+   */
+
+  (function (jsPDFAPI) {
+
+  	var annotationPlugin = {
+
+  		/**
+     * An array of arrays, indexed by <em>pageNumber</em>.
+     */
+  		annotations: [],
+
+  		f2: function f2(number) {
+  			return number.toFixed(2);
+  		},
+
+  		notEmpty: function notEmpty(obj) {
+  			if (typeof obj != 'undefined') {
+  				if (obj != '') {
+  					return true;
+  				}
+  			}
+  		}
+  	};
+
+  	jsPDF.API.annotationPlugin = annotationPlugin;
+
+  	jsPDF.API.events.push(['addPage', function (info) {
+  		this.annotationPlugin.annotations[info.pageNumber] = [];
+  	}]);
+
+  	jsPDFAPI.events.push(['putPage', function (info) {
+  		//TODO store annotations in pageContext so reorder/remove will not affect them.
+  		var pageAnnos = this.annotationPlugin.annotations[info.pageNumber];
+
+  		var found = false;
+  		for (var a = 0; a < pageAnnos.length && !found; a++) {
+  			var anno = pageAnnos[a];
+  			switch (anno.type) {
+  				case 'link':
+  					if (annotationPlugin.notEmpty(anno.options.url) || annotationPlugin.notEmpty(anno.options.pageNumber)) {
+  						found = true;
+  						break;
+  					}
+  				case 'reference':
+  				case 'text':
+  				case 'freetext':
+  					found = true;
+  					break;
+  			}
+  		}
+  		if (found == false) {
+  			return;
+  		}
+
+  		this.internal.write("/Annots [");
+  		var f2 = this.annotationPlugin.f2;
+  		var k = this.internal.scaleFactor;
+  		var pageHeight = this.internal.pageSize.getHeight();
+  		var pageInfo = this.internal.getPageInfo(info.pageNumber);
+  		for (var a = 0; a < pageAnnos.length; a++) {
+  			var anno = pageAnnos[a];
+
+  			switch (anno.type) {
+  				case 'reference':
+  					// References to Widget Anotations (for AcroForm Fields)
+  					this.internal.write(' ' + anno.object.objId + ' 0 R ');
+  					break;
+  				case 'text':
+  					// Create a an object for both the text and the popup
+  					var objText = this.internal.newAdditionalObject();
+  					var objPopup = this.internal.newAdditionalObject();
+
+  					var title = anno.title || 'Note';
+  					var rect = "/Rect [" + f2(anno.bounds.x * k) + " " + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + " " + f2((anno.bounds.x + anno.bounds.w) * k) + " " + f2((pageHeight - anno.bounds.y) * k) + "] ";
+  					line = '<</Type /Annot /Subtype /' + 'Text' + ' ' + rect + '/Contents (' + anno.contents + ')';
+  					line += ' /Popup ' + objPopup.objId + " 0 R";
+  					line += ' /P ' + pageInfo.objId + " 0 R";
+  					line += ' /T (' + title + ') >>';
+  					objText.content = line;
+
+  					var parent = objText.objId + ' 0 R';
+  					var popoff = 30;
+  					var rect = "/Rect [" + f2((anno.bounds.x + popoff) * k) + " " + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + " " + f2((anno.bounds.x + anno.bounds.w + popoff) * k) + " " + f2((pageHeight - anno.bounds.y) * k) + "] ";
+  					//var rect2 = "/Rect [" + f2(anno.bounds.x * k) + " " + f2((pageHeight - anno.bounds.y) * k) + " " + f2(anno.bounds.x + anno.bounds.w * k) + " " + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + "] ";
+  					line = '<</Type /Annot /Subtype /' + 'Popup' + ' ' + rect + ' /Parent ' + parent;
+  					if (anno.open) {
+  						line += ' /Open true';
+  					}
+  					line += ' >>';
+  					objPopup.content = line;
+
+  					this.internal.write(objText.objId, '0 R', objPopup.objId, '0 R');
+
+  					break;
+  				case 'freetext':
+  					var rect = "/Rect [" + f2(anno.bounds.x * k) + " " + f2((pageHeight - anno.bounds.y) * k) + " " + f2(anno.bounds.x + anno.bounds.w * k) + " " + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + "] ";
+  					var color = anno.color || '#000000';
+  					line = '<</Type /Annot /Subtype /' + 'FreeText' + ' ' + rect + '/Contents (' + anno.contents + ')';
+  					line += ' /DS(font: Helvetica,sans-serif 12.0pt; text-align:left; color:#' + color + ')';
+  					line += ' /Border [0 0 0]';
+  					line += ' >>';
+  					this.internal.write(line);
+  					break;
+  				case 'link':
+  					if (anno.options.name) {
+  						var loc = this.annotations._nameMap[anno.options.name];
+  						anno.options.pageNumber = loc.page;
+  						anno.options.top = loc.y;
+  					} else {
+  						if (!anno.options.top) {
+  							anno.options.top = 0;
+  						}
+  					}
+
+  					var rect = "/Rect [" + f2(anno.x * k) + " " + f2((pageHeight - anno.y) * k) + " " + f2((anno.x + anno.w) * k) + " " + f2((pageHeight - (anno.y + anno.h)) * k) + "] ";
+
+  					var line = '';
+  					if (anno.options.url) {
+  						line = '<</Type /Annot /Subtype /Link ' + rect + '/Border [0 0 0] /A <</S /URI /URI (' + anno.options.url + ') >>';
+  					} else if (anno.options.pageNumber) {
+  						// first page is 0
+  						var info = this.internal.getPageInfo(anno.options.pageNumber);
+  						line = '<</Type /Annot /Subtype /Link ' + rect + '/Border [0 0 0] /Dest [' + info.objId + " 0 R";
+  						anno.options.magFactor = anno.options.magFactor || "XYZ";
+  						switch (anno.options.magFactor) {
+  							case 'Fit':
+  								line += ' /Fit]';
+  								break;
+  							case 'FitH':
+  								//anno.options.top = anno.options.top || f2(pageHeight * k);
+  								line += ' /FitH ' + anno.options.top + ']';
+  								break;
+  							case 'FitV':
+  								anno.options.left = anno.options.left || 0;
+  								line += ' /FitV ' + anno.options.left + ']';
+  								break;
+  							case 'XYZ':
+  							default:
+  								var top = f2((pageHeight - anno.options.top) * k); // || f2(pageHeight * k);
+  								anno.options.left = anno.options.left || 0;
+  								// 0 or null zoom will not change zoom factor
+  								if (typeof anno.options.zoom === 'undefined') {
+  									anno.options.zoom = 0;
+  								}
+  								line += ' /XYZ ' + anno.options.left + ' ' + top + ' ' + anno.options.zoom + ']';
+  								break;
+  						}
+  					}
+  					if (line != '') {
+  						line += " >>";
+  						this.internal.write(line);
+  					}
+  					break;
+  			}
+  		}
+  		this.internal.write("]");
+  	}]);
+
+  	jsPDFAPI.createAnnotation = function (options) {
+  		switch (options.type) {
+  			case 'link':
+  				this.link(options.bounds.x, options.bounds.y, options.bounds.w, options.bounds.h, options);
+  				break;
+  			case 'text':
+  			case 'freetext':
+  				this.annotationPlugin.annotations[this.internal.getCurrentPageInfo().pageNumber].push(options);
+  				break;
+  		}
+  	};
+
+  	/**
+    * valid options
+    * <li> pageNumber or url [required]
+    * <p>If pageNumber is specified, top and zoom may also be specified</p>
+    */
+  	jsPDFAPI.link = function (x, y, w, h, options) {
+
+  		this.annotationPlugin.annotations[this.internal.getCurrentPageInfo().pageNumber].push({
+  			x: x,
+  			y: y,
+  			w: w,
+  			h: h,
+  			options: options,
+  			type: 'link'
+  		});
+  	};
+
+  	/**
+    * Currently only supports single line text.
+    * Returns the width of the text/link
+    */
+  	jsPDFAPI.textWithLink = function (text, x, y, options) {
+
+  		var width = this.getTextWidth(text);
+  		var height = this.internal.getLineHeight() / this.internal.scaleFactor;
+  		this.text(text, x, y);
+  		//TODO We really need the text baseline height to do this correctly.
+  		// Or ability to draw text on top, bottom, center, or baseline.
+  		y += height * .2;
+  		this.link(x, y - height, width, height, options);
+  		return width;
+  	};
+
+  	//TODO move into external library
+  	jsPDFAPI.getTextWidth = function (text) {
+
+  		var fontSize = this.internal.getFontSize();
+  		var txtWidth = this.getStringUnitWidth(text) * fontSize / this.internal.scaleFactor;
+  		return txtWidth;
+  	};
+
+  	//TODO move into external library
+  	jsPDFAPI.getLineHeight = function () {
+  		return this.internal.getLineHeight();
+  	};
+
+  	return this;
+  })(jsPDF.API);
+
+  (function (jsPDFAPI) {
+
+      var arLangCodes = {
+          "ar": "Arabic (Standard)",
+          "ar-DZ": "Arabic (Algeria)",
+          "ar-BH": "Arabic (Bahrain)",
+          "ar-EG": "Arabic (Egypt)",
+          "ar-IQ": "Arabic (Iraq)",
+          "ar-JO": "Arabic (Jordan)",
+          "ar-KW": "Arabic (Kuwait)",
+          "ar-LB": "Arabic (Lebanon)",
+          "ar-LY": "Arabic (Libya)",
+          "ar-MA": "Arabic (Morocco)",
+          "ar-OM": "Arabic (Oman)",
+          "ar-QA": "Arabic (Qatar)",
+          "ar-SA": "Arabic (Saudi Arabia)",
+          "ar-SY": "Arabic (Syria)",
+          "ar-TN": "Arabic (Tunisia)",
+          "ar-AE": "Arabic (U.A.E.)",
+          "ar-YE": "Arabic (Yemen)",
+          "fa": "Persian",
+          "fa-IR": "Persian/Iran",
+          "ur": "Urdu"
+      };
+
+      var arLangCodesKeys = Object.keys(arLangCodes);
+
+      /**
+       * Arabic shape substitutions: char code => (isolated, final, initial, medial).
+       */
+      var arabicSubst = {
+          1569: [65152],
+          1570: [65153, 65154, 65153, 65154],
+          1571: [65155, 65156, 65155, 65156],
+          1572: [65157, 65158],
+          1573: [65159, 65160, 65159, 65160],
+          1574: [65161, 65162, 65163, 65164],
+          1575: [65165, 65166, 65165, 65166],
+          1576: [65167, 65168, 65169, 65170],
+          1577: [65171, 65172],
+          1578: [65173, 65174, 65175, 65176],
+          1579: [65177, 65178, 65179, 65180],
+          1580: [65181, 65182, 65183, 65184],
+          1581: [65185, 65186, 65187, 65188],
+          1582: [65189, 65190, 65191, 65192],
+          1583: [65193, 65194, 65193, 65194],
+          1584: [65195, 65196, 65195, 65196],
+          1585: [65197, 65198, 65197, 65198],
+          1586: [65199, 65200, 65199, 65200],
+          1587: [65201, 65202, 65203, 65204],
+          1588: [65205, 65206, 65207, 65208],
+          1589: [65209, 65210, 65211, 65212],
+          1590: [65213, 65214, 65215, 65216],
+          1591: [65217, 65218, 65219, 65220],
+          1592: [65221, 65222, 65223, 65224],
+          1593: [65225, 65226, 65227, 65228],
+          1594: [65229, 65230, 65231, 65232],
+          1601: [65233, 65234, 65235, 65236],
+          1602: [65237, 65238, 65239, 65240],
+          1603: [65241, 65242, 65243, 65244],
+          1604: [65245, 65246, 65247, 65248],
+          1605: [65249, 65250, 65251, 65252],
+          1606: [65253, 65254, 65255, 65256],
+          1607: [65257, 65258, 65259, 65260],
+          1608: [65261, 65262, 65261, 65262],
+          1609: [65263, 65264, 64488, 64489],
+          1610: [65265, 65266, 65267, 65268],
+          1649: [64336, 64337],
+          1655: [64477],
+          1657: [64358, 64359, 64360, 64361],
+          1658: [64350, 64351, 64352, 64353],
+          1659: [64338, 64339, 64340, 64341],
+          1662: [64342, 64343, 64344, 64345],
+          1663: [64354, 64355, 64356, 64357],
+          1664: [64346, 64347, 64348, 64349],
+          1667: [64374, 64375, 64376, 64377],
+          1668: [64370, 64371, 64372, 64373],
+          1670: [64378, 64379, 64380, 64381],
+          1671: [64382, 64383, 64384, 64385],
+          1672: [64392, 64393],
+          1676: [64388, 64389],
+          1677: [64386, 64387],
+          1678: [64390, 64391],
+          1681: [64396, 64397],
+          1688: [64394, 64395, 64394, 64395],
+          1700: [64362, 64363, 64364, 64365],
+          1702: [64366, 64367, 64368, 64369],
+          1705: [64398, 64399, 64400, 64401],
+          1709: [64467, 64468, 64469, 64470],
+          1711: [64402, 64403, 64404, 64405],
+          1713: [64410, 64411, 64412, 64413],
+          1715: [64406, 64407, 64408, 64409],
+          1722: [64414, 64415],
+          1723: [64416, 64417, 64418, 64419],
+          1726: [64426, 64427, 64428, 64429],
+          1728: [64420, 64421],
+          1729: [64422, 64423, 64424, 64425],
+          1733: [64480, 64481],
+          1734: [64473, 64474],
+          1735: [64471, 64472],
+          1736: [64475, 64476],
+          1737: [64482, 64483],
+          1739: [64478, 64479],
+          1740: [64508, 64509, 64510, 64511],
+          1744: [64484, 64485, 64486, 64487],
+          1746: [64430, 64431],
+          1747: [64432, 64433]
+      };
+      var arabiclaasubst = {
+          1570: [65269, 65270, 65269, 65270],
+          1571: [65271, 65272, 65271, 65272],
+          1573: [65273, 65274, 65273, 65274],
+          1575: [65275, 65276, 65275, 65276]
+      };
+      var arabicorigsubst = {
+          1570: [65153, 65154, 65153, 65154],
+          1571: [65155, 65156, 65155, 65156],
+          1573: [65159, 65160, 65159, 65160],
+          1575: [65165, 65166, 65165, 65166]
+      };
+      var arabic_diacritics = {
+          1612: 64606, // Shadda + Dammatan
+          1613: 64607, // Shadda + Kasratan
+          1614: 64608, // Shadda + Fatha
+          1615: 64609, // Shadda + Damma
+          1616: 64610 // Shadda + Kasra
+      };
+
+      var alfletter = [1570, 1571, 1573, 1575];
+      var endedletter = [1569, 1570, 1571, 1572, 1573, 1575, 1577, 1583, 1584, 1585, 1586, 1608, 1688];
+
+      var isolatedForm = 0;
+      var finalForm = 1;
+      var initialForm = 2;
+      var medialForm = 3;
+
+      //private
+      function isArabicLetter(letter) {
+          return letter !== undefined && arabicSubst[letter.charCodeAt(0)] !== undefined;
+      }
+
+      function isArabicEndLetter(letter) {
+          return letter !== undefined && endedletter.indexOf(letter.charCodeAt(0)) >= 0;
+      }
+
+      function isArabicAlfLetter(letter) {
+          return letter !== undefined && alfletter.indexOf(letter.charCodeAt(0)) >= 0;
+      }
+
+      function arabicLetterHasFinalForm(letter) {
+          return isArabicLetter(letter) && arabicSubst[letter.charCodeAt(0)].length >= 2;
+      }
+
+      function arabicLetterHasMedialForm(letter) {
+          return isArabicLetter(letter) && arabicSubst[letter.charCodeAt(0)].length == 4;
+      }
+
+      function isArabicDiacritic(letter) {
+          return letter !== undefined && arabic_diacritics[letter.charCodeAt(0)] !== undefined;
+      }
+
+      function getCorrectForm(currentChar, beforeChar, nextChar, arabicSubstition) {
+          if (!isArabicLetter(currentChar)) {
+              return -1;
+          }
+
+          arabicSubstition = arabicSubstition || {};
+          arabicSubst = Object.assign(arabicSubst, arabicSubstition);
+
+          if (!arabicLetterHasFinalForm(currentChar) || !isArabicLetter(beforeChar) && !isArabicLetter(nextChar) || !isArabicLetter(nextChar) && isArabicEndLetter(beforeChar) || isArabicEndLetter(currentChar) && !isArabicLetter(beforeChar) || isArabicEndLetter(currentChar) && isArabicAlfLetter(beforeChar)) {
+              arabicSubst = Object.assign(arabicSubst, arabicorigsubst);
+              return isolatedForm;
+          }
+
+          if (arabicLetterHasMedialForm(currentChar) && isArabicLetter(beforeChar) && !isArabicEndLetter(beforeChar) && isArabicLetter(nextChar) && arabicLetterHasFinalForm(nextChar)) {
+              arabicSubst = Object.assign(arabicSubst, arabicorigsubst);
+              return medialForm;
+          }
+
+          if (isArabicEndLetter(currentChar) || !isArabicLetter(nextChar)) {
+              arabicSubst = Object.assign(arabicSubst, arabicorigsubst);
+              return finalForm;
+          }
+
+          arabicSubst = Object.assign(arabicSubst, arabicorigsubst);
+          return initialForm;
+      }
+
+      function processArabic(text) {
+          text = text || "";
+          var result = "";
+          var i = 0;
+          var position = 0;
+          var currentLetter = "";
+          var prevLetter = "";
+          var nextLetter = "";
+          var resultingLetter;
+
+          var localPrevLetter;
+          var localCurrentLetter;
+          var localNextLetter;
+
+          for (i = 0; i < text.length; i += 1) {
+              currentLetter = text[i];
+              prevLetter = text[i - 1];
+              nextLetter = text[i + 1];
+              if (!isArabicLetter(currentLetter)) {
+                  result += currentLetter;
+              } else {
+                  if (prevLetter !== undefined && prevLetter.charCodeAt(0) === 1604 && isArabicAlfLetter(currentLetter)) {
+                      localPrevLetter = text[i - 2];
+                      localCurrentLetter = currentLetter;
+                      localNextLetter = text[i + 1];
+                      position = getCorrectForm(localCurrentLetter, localPrevLetter, localNextLetter, arabiclaasubst);
+                      resultingLetter = String.fromCharCode(arabiclaasubst[currentLetter.charCodeAt(0)][position]);
+                      result = result.substr(0, result.length - 1) + resultingLetter;
+                  } else if (prevLetter !== undefined && prevLetter.charCodeAt(0) === 1617 && isArabicDiacritic(currentLetter)) {
+                      localPrevLetter = text[i - 2];
+                      localCurrentLetter = currentLetter;
+                      localNextLetter = text[i + 1];
+                      position = getCorrectForm(localCurrentLetter, localPrevLetter, localNextLetter, arabicorigsubst);
+                      resultingLetter = String.fromCharCode(arabic_diacritics[currentLetter.charCodeAt(0)][position]);
+                      result = result.substr(0, result.length - 1) + resultingLetter;
+                  } else {
+                      position = getCorrectForm(currentLetter, prevLetter, nextLetter, arabicorigsubst);
+                      result += String.fromCharCode(arabicSubst[currentLetter.charCodeAt(0)][position]);
+                  }
+              }
+          }
+          return result.split("").reverse().join("");
+      }
+
+      var arabicParserFunction = function arabicParserFunction(args) {
+          var text = args.text;
+          var x = args.x;
+          var y = args.y;
+          var options = args.options || {};
+          var mutex = args.mutex || {};
+          var lang = options.lang;
+          var tmpText = [];
+
+          if (arLangCodesKeys.indexOf(lang) >= 0) {
+              if (Object.prototype.toString.call(text) === '[object Array]') {
+                  var i = 0;
+                  tmpText = [];
+                  for (i = 0; i < text.length; i += 1) {
+                      if (Object.prototype.toString.call(text[i]) === '[object Array]') {
+                          tmpText.push([processArabic(text[i][0]), text[i][1], text[i][2]]);
+                      } else {
+                          tmpText.push([processArabic(text[i])]);
+                      }
+                  }
+                  args.text = tmpText;
+              } else {
+                  args.text = processArabic(text);
+              }
+              //force charSpace if not given.
+              if (options.charSpace === undefined) {
+                  args.options.charSpace = 0;
+              }
+              //if R2L is true, set it false.
+              if (options.R2L === true) {
+                  args.options.R2L = false;
+              }
+          }
+      };
+
+      jsPDFAPI.events.push(['preProcessText', arabicParserFunction]);
+  })(jsPDF.API);
+
+  /**
+   * jsPDF Autoprint Plugin
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+
+  /**
+  * Makes the PDF automatically print. This works in Chrome, Firefox, Acrobat
+  * Reader.
+  *
+  * @returns {jsPDF}
+  * @name autoPrint
+  * @example
+  * var doc = new jsPDF()
+  * doc.text(10, 10, 'This is a test')
+  * doc.autoPrint()
+  * doc.save('autoprint.pdf')
+  */
+
+  (function (jsPDFAPI) {
+
+    jsPDFAPI.autoPrint = function (options) {
+
+      var refAutoPrintTag;
+      options = options || {};
+      options.variant = options.variant || 'non-conform';
+
+      switch (options.variant) {
+        case 'javascript':
+          //https://github.com/Rob--W/pdf.js/commit/c676ecb5a0f54677b9f3340c3ef2cf42225453bb
+          this.addJS('print({});');
+          break;
+        case 'non-conform':
+        default:
+          this.internal.events.subscribe('postPutResources', function () {
+            refAutoPrintTag = this.internal.newObject();
+            this.internal.out("<<");
+            this.internal.out("/S /Named");
+            this.internal.out("/Type /Action");
+            this.internal.out("/N /Print");
+            this.internal.out(">>");
+            this.internal.out("endobj");
+          });
+
+          this.internal.events.subscribe("putCatalog", function () {
+            this.internal.out("/OpenAction " + refAutoPrintTag + " 0 R");
+          });
+          break;
+      }
+      return this;
+    };
+  })(jsPDF.API);
+
+  /**
+   * jsPDF Canvas PlugIn
+   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+
+  /**
+   * This plugin mimics the HTML5 Canvas
+   * 
+   * The goal is to provide a way for current canvas users to print directly to a PDF.
+   */
+
+  (function (jsPDFAPI) {
+
+  	jsPDFAPI.events.push(['initialized', function () {
+  		this.canvas.pdf = this;
+  	}]);
+
+  	jsPDFAPI.canvas = {
+  		getContext: function getContext(name) {
+  			this.pdf.context2d._canvas = this;
+  			return this.pdf.context2d;
+  		},
+  		style: {}
+  	};
+
+  	Object.defineProperty(jsPDFAPI.canvas, 'width', {
+  		get: function get() {
+  			return this._width;
+  		},
+  		set: function set(value) {
+  			this._width = value;
+  			this.getContext('2d').pageWrapX = value + 1;
+  		}
+  	});
+
+  	Object.defineProperty(jsPDFAPI.canvas, 'height', {
+  		get: function get() {
+  			return this._height;
+  		},
+  		set: function set(value) {
+  			this._height = value;
+  			this.getContext('2d').pageWrapY = value + 1;
+  		}
+  	});
+
+  	return this;
+  })(jsPDF.API);
+
+  /** ====================================================================
+   * jsPDF Cell plugin
+   * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
+   *               2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
+   *               2013 Lee Driscoll, https://github.com/lsdriscoll
+   *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
+   *               2014 James Hall, james@parall.ax
+   *               2014 Diego Casorran, https://github.com/diegocr
+   *
+   * 
+   * ====================================================================
+   */
+
+  (function (jsPDFAPI) {
+      /*jslint browser:true */
+      /*global document: false, jsPDF */
+
+      var fontName,
+          fontSize,
+          fontStyle,
+          padding = 3,
+          margin = 13,
+          headerFunction,
+          lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined },
+          pages = 1,
+          setLastCellPosition = function setLastCellPosition(x, y, w, h, ln) {
+          lastCellPos = { 'x': x, 'y': y, 'w': w, 'h': h, 'ln': ln };
+      },
+          getLastCellPosition = function getLastCellPosition() {
+          return lastCellPos;
+      },
+          NO_MARGINS = { left: 0, top: 0, bottom: 0 };
+
+      jsPDFAPI.setHeaderFunction = function (func) {
+          headerFunction = func;
+      };
+
+      jsPDFAPI.getTextDimensions = function (txt) {
+          fontName = this.internal.getFont().fontName;
+          fontSize = this.table_font_size || this.internal.getFontSize();
+          fontStyle = this.internal.getFont().fontStyle;
+          // 1 pixel = 0.264583 mm and 1 mm = 72/25.4 point
+          var px2pt = 0.264583 * 72 / 25.4,
+              dimensions,
+              text;
+
+          text = document.createElement('font');
+          text.id = "jsPDFCell";
+
+          try {
+              text.style.fontStyle = fontStyle;
+          } catch (e) {
+              text.style.fontWeight = fontStyle;
+          }
+
+          text.style.fontSize = fontSize + 'pt';
+          text.style.fontFamily = fontName;
+          try {
+              text.textContent = txt;
+          } catch (e) {
+              text.innerText = txt;
+          }
+
+          document.body.appendChild(text);
+
+          dimensions = { w: (text.offsetWidth + 1) * px2pt, h: (text.offsetHeight + 1) * px2pt };
+
+          document.body.removeChild(text);
+
+          return dimensions;
+      };
+
+      jsPDFAPI.cellAddPage = function () {
+          var margins = this.margins || NO_MARGINS;
+
+          this.addPage();
+
+          setLastCellPosition(margins.left, margins.top, undefined, undefined);
+          //setLastCellPosition(undefined, undefined, undefined, undefined, undefined);
+          pages += 1;
+      };
+
+      jsPDFAPI.cellInitialize = function () {
+          lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined };
+          pages = 1;
+      };
+
+      jsPDFAPI.cell = function (x, y, w, h, txt, ln, align) {
+          var curCell = getLastCellPosition();
+          var pgAdded = false;
+
+          // If this is not the first cell, we must change its position
+          if (curCell.ln !== undefined) {
+              if (curCell.ln === ln) {
+                  //Same line
+                  x = curCell.x + curCell.w;
+                  y = curCell.y;
+              } else {
+                  //New line
+                  var margins = this.margins || NO_MARGINS;
+                  if (curCell.y + curCell.h + h + margin >= this.internal.pageSize.getHeight() - margins.bottom) {
+                      this.cellAddPage();
+                      pgAdded = true;
+                      if (this.printHeaders && this.tableHeaderRow) {
+                          this.printHeaderRow(ln, true);
+                      }
+                  }
+                  //We ignore the passed y: the lines may have different heights
+                  y = getLastCellPosition().y + getLastCellPosition().h;
+                  if (pgAdded) y = margin + 10;
+              }
+          }
+
+          if (txt[0] !== undefined) {
+              if (this.printingHeaderRow) {
+                  this.rect(x, y, w, h, 'FD');
+              } else {
+                  this.rect(x, y, w, h);
+              }
+              if (align === 'right') {
+                  if (!(txt instanceof Array)) {
+                      txt = [txt];
+                  }
+                  for (var i = 0; i < txt.length; i++) {
+                      var currentLine = txt[i];
+                      var textSize = this.getStringUnitWidth(currentLine) * this.internal.getFontSize();
+                      this.text(currentLine, x + w - textSize - padding, y + this.internal.getLineHeight() * (i + 1));
+                  }
+              } else {
+                  this.text(txt, x + padding, y + this.internal.getLineHeight());
+              }
+          }
+          setLastCellPosition(x, y, w, h, ln);
+          return this;
+      };
+
+      /**
+       * Return the maximum value from an array
+       * @param array
+       * @param comparisonFn
+       * @returns {*}
+       */
+      jsPDFAPI.arrayMax = function (array, comparisonFn) {
+          var max = array[0],
+              i,
+              ln,
+              item;
+
+          for (i = 0, ln = array.length; i < ln; i += 1) {
+              item = array[i];
+
+              if (comparisonFn) {
+                  if (comparisonFn(max, item) === -1) {
+                      max = item;
+                  }
+              } else {
+                  if (item > max) {
+                      max = item;
+                  }
+              }
+          }
+
+          return max;
+      };
+
+      /**
+       * Create a table from a set of data.
+       * @param {Integer} [x] : left-position for top-left corner of table
+       * @param {Integer} [y] top-position for top-left corner of table
+       * @param {Object[]} [data] As array of objects containing key-value pairs corresponding to a row of data.
+       * @param {String[]} [headers] Omit or null to auto-generate headers at a performance cost
+        * @param {Object} [config.printHeaders] True to print column headers at the top of every page
+       * @param {Object} [config.autoSize] True to dynamically set the column widths to match the widest cell value
+       * @param {Object} [config.margins] margin values for left, top, bottom, and width
+       * @param {Object} [config.fontSize] Integer fontSize to use (optional)
+       */
+
+      jsPDFAPI.table = function (x, y, data, headers, config) {
+          if (!data) {
+              throw 'No data for PDF table';
+          }
+
+          var headerNames = [],
+              headerPrompts = [],
+              header,
+              i,
+              ln,
+              cln,
+              columnMatrix = {},
+              columnWidths = {},
+              columnData,
+              column,
+              columnMinWidths = [],
+              j,
+              tableHeaderConfigs = [],
+              model,
+              jln,
+              func,
+
+
+          //set up defaults. If a value is provided in config, defaults will be overwritten:
+          autoSize = false,
+              printHeaders = true,
+              fontSize = 12,
+              margins = NO_MARGINS;
+
+          margins.width = this.internal.pageSize.getWidth();
+
+          if (config) {
+              //override config defaults if the user has specified non-default behavior:
+              if (config.autoSize === true) {
+                  autoSize = true;
+              }
+              if (config.printHeaders === false) {
+                  printHeaders = false;
+              }
+              if (config.fontSize) {
+                  fontSize = config.fontSize;
+              }
+              if (config.css && typeof config.css['font-size'] !== "undefined") {
+                  fontSize = config.css['font-size'] * 16;
+              }
+              if (config.margins) {
+                  margins = config.margins;
+              }
+          }
+
+          /**
+           * @property {Number} lnMod
+           * Keep track of the current line number modifier used when creating cells
+           */
+          this.lnMod = 0;
+          lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined }, pages = 1;
+
+          this.printHeaders = printHeaders;
+          this.margins = margins;
+          this.setFontSize(fontSize);
+          this.table_font_size = fontSize;
+
+          // Set header values
+          if (headers === undefined || headers === null) {
+              // No headers defined so we derive from data
+              headerNames = Object.keys(data[0]);
+          } else if (headers[0] && typeof headers[0] !== 'string') {
+              var px2pt = 0.264583 * 72 / 25.4;
+
+              // Split header configs into names and prompts
+              for (i = 0, ln = headers.length; i < ln; i += 1) {
+                  header = headers[i];
+                  headerNames.push(header.name);
+                  headerPrompts.push(header.prompt);
+                  columnWidths[header.name] = header.width * px2pt;
+              }
+          } else {
+              headerNames = headers;
+          }
+
+          if (autoSize) {
+              // Create a matrix of columns e.g., {column_title: [row1_Record, row2_Record]}
+              func = function func(rec) {
+                  return rec[header];
+              };
+
+              for (i = 0, ln = headerNames.length; i < ln; i += 1) {
+                  header = headerNames[i];
+
+                  columnMatrix[header] = data.map(func);
+
+                  // get header width
+                  columnMinWidths.push(this.getTextDimensions(headerPrompts[i] || header).w);
+                  column = columnMatrix[header];
+
+                  // get cell widths
+                  for (j = 0, cln = column.length; j < cln; j += 1) {
+                      columnData = column[j];
+                      columnMinWidths.push(this.getTextDimensions(columnData).w);
+                  }
+
+                  // get final column width
+                  columnWidths[header] = jsPDFAPI.arrayMax(columnMinWidths);
+
+                  //have to reset
+                  columnMinWidths = [];
+              }
+          }
+
+          // -- Construct the table
+
+          if (printHeaders) {
+              var lineHeight = this.calculateLineHeight(headerNames, columnWidths, headerPrompts.length ? headerPrompts : headerNames);
+
+              // Construct the header row
+              for (i = 0, ln = headerNames.length; i < ln; i += 1) {
+                  header = headerNames[i];
+                  tableHeaderConfigs.push([x, y, columnWidths[header], lineHeight, String(headerPrompts.length ? headerPrompts[i] : header)]);
+              }
+
+              // Store the table header config
+              this.setTableHeaderRow(tableHeaderConfigs);
+
+              // Print the header for the start of the table
+              this.printHeaderRow(1, false);
+          }
+
+          // Construct the data rows
+          for (i = 0, ln = data.length; i < ln; i += 1) {
+              var lineHeight;
+              model = data[i];
+              lineHeight = this.calculateLineHeight(headerNames, columnWidths, model);
+
+              for (j = 0, jln = headerNames.length; j < jln; j += 1) {
+                  header = headerNames[j];
+                  this.cell(x, y, columnWidths[header], lineHeight, model[header], i + 2, header.align);
+              }
+          }
+          this.lastCellPos = lastCellPos;
+          this.table_x = x;
+          this.table_y = y;
+          return this;
+      };
+      /**
+       * Calculate the height for containing the highest column
+       * @param {String[]} headerNames is the header, used as keys to the data
+       * @param {Integer[]} columnWidths is size of each column
+       * @param {Object[]} model is the line of data we want to calculate the height of
+       */
+      jsPDFAPI.calculateLineHeight = function (headerNames, columnWidths, model) {
+          var header,
+              lineHeight = 0;
+          for (var j = 0; j < headerNames.length; j++) {
+              header = headerNames[j];
+              model[header] = this.splitTextToSize(String(model[header]), columnWidths[header] - padding);
+              var h = this.internal.getLineHeight() * model[header].length + padding;
+              if (h > lineHeight) lineHeight = h;
+          }
+          return lineHeight;
+      };
+
+      /**
+       * Store the config for outputting a table header
+       * @param {Object[]} config
+       * An array of cell configs that would define a header row: Each config matches the config used by jsPDFAPI.cell
+       * except the ln parameter is excluded
+       */
+      jsPDFAPI.setTableHeaderRow = function (config) {
+          this.tableHeaderRow = config;
+      };
+
+      /**
+       * Output the store header row
+       * @param lineNumber The line number to output the header at
+       */
+      jsPDFAPI.printHeaderRow = function (lineNumber, new_page) {
+          if (!this.tableHeaderRow) {
+              throw 'Property tableHeaderRow does not exist.';
+          }
+
+          var tableHeaderCell, tmpArray, i, ln;
+
+          this.printingHeaderRow = true;
+          if (headerFunction !== undefined) {
+              var position = headerFunction(this, pages);
+              setLastCellPosition(position[0], position[1], position[2], position[3], -1);
+          }
+          this.setFontStyle('bold');
+          var tempHeaderConf = [];
+          for (i = 0, ln = this.tableHeaderRow.length; i < ln; i += 1) {
+              this.setFillColor(200, 200, 200);
+
+              tableHeaderCell = this.tableHeaderRow[i];
+              if (new_page) {
+                  this.margins.top = margin;
+                  tableHeaderCell[1] = this.margins && this.margins.top || 0;
+                  tempHeaderConf.push(tableHeaderCell);
+              }
+              tmpArray = [].concat(tableHeaderCell);
+              this.cell.apply(this, tmpArray.concat(lineNumber));
+          }
+          if (tempHeaderConf.length > 0) {
+              this.setTableHeaderRow(tempHeaderConf);
+          }
+          this.setFontStyle('normal');
+          this.printingHeaderRow = false;
+      };
+  })(jsPDF.API);
+
+  /**
+   * jsPDF Context2D PlugIn Copyright (c) 2014 Steven Spungin (TwelveTone LLC) steven@twelvetone.tv
+   *
+   * Licensed under the MIT License. http://opensource.org/licenses/mit-license
+   */
+
+  /**
+   * This plugin mimics the HTML5 Canvas's context2d.
+   *
+   * The goal is to provide a way for current canvas implementations to print directly to a PDF.
+   */
+
+  /**
+   * TODO implement stroke opacity (refactor from fill() method )
+   * TODO transform angle and radii parameters
+   */
+
+  /**
+   * require('jspdf.js'); require('lib/css_colors.js');
+   */
+
+  (function (jsPDFAPI) {
+
+      jsPDFAPI.events.push(['initialized', function () {
+          this.context2d.pdf = this;
+          this.context2d.internal.pdf = this;
+          this.context2d.ctx = new context();
+          this.context2d.ctxStack = [];
+          this.context2d.path = [];
+      }]);
+
+      jsPDFAPI.context2d = {
+          pageWrapXEnabled: false,
+          pageWrapYEnabled: false,
+          pageWrapX: 9999999,
+          pageWrapY: 9999999,
+          ctx: new context(),
+          f2: function f2(number) {
+              return number.toFixed(2);
+          },
+
+          fillRect: function fillRect(x, y, w, h) {
+              if (this._isFillTransparent()) {
+                  return;
+              }
+              x = this._wrapX(x);
+              y = this._wrapY(y);
+
+              var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h });
+              this.pdf.rect(xRect.x, xRect.y, xRect.w, xRect.h, "f");
+          },
+
+          strokeRect: function strokeRect(x, y, w, h) {
+              if (this._isStrokeTransparent()) {
+                  return;
+              }
+              x = this._wrapX(x);
+              y = this._wrapY(y);
+
+              var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h });
+              this.pdf.rect(xRect.x, xRect.y, xRect.w, xRect.h, "s");
+          },
+
+          /**
+           * We cannot clear PDF commands that were already written to PDF, so we use white instead. <br />
+           * As a special case, read a special flag (ignoreClearRect) and do nothing if it is set.
+           * This results in all calls to clearRect() to do nothing, and keep the canvas transparent.
+           * This flag is stored in the save/restore context and is managed the same way as other drawing states.
+           * @param x
+           * @param y
+           * @param w
+           * @param h
+           */
+          clearRect: function clearRect(x, y, w, h) {
+              if (this.ctx.ignoreClearRect) {
+                  return;
+              }
+
+              x = this._wrapX(x);
+              y = this._wrapY(y);
+
+              var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h });
+              this.save();
+              this.setFillStyle('#ffffff');
+              //TODO This is hack to fill with white.
+              this.pdf.rect(xRect.x, xRect.y, xRect.w, xRect.h, "f");
+              this.restore();
+          },
+
+          save: function save() {
+              this.ctx._fontSize = this.pdf.internal.getFontSize();
+              var ctx = new context();
+              ctx.copy(this.ctx);
+              this.ctxStack.push(this.ctx);
+              this.ctx = ctx;
+          },
+
+          restore: function restore() {
+              this.ctx = this.ctxStack.pop();
+              this.setFillStyle(this.ctx.fillStyle);
+              this.setStrokeStyle(this.ctx.strokeStyle);
+              this.setFont(this.ctx.font);
+              this.pdf.setFontSize(this.ctx._fontSize);
+              this.setLineCap(this.ctx.lineCap);
+              this.setLineWidth(this.ctx.lineWidth);
+              this.setLineJoin(this.ctx.lineJoin);
+          },
+
+          rect: function rect(x, y, w, h) {
+              this.moveTo(x, y);
+              this.lineTo(x + w, y);
+              this.lineTo(x + w, y + h);
+              this.lineTo(x, y + h);
+              this.lineTo(x, y); //TODO not needed
+              this.closePath();
+          },
+
+          beginPath: function beginPath() {
+              this.path = [];
+          },
+
+          closePath: function closePath() {
+              this.path.push({
+                  type: 'close'
+              });
+          },
+
+          _getRGBA: function _getRGBA(style) {
+              // get the decimal values of r, g, and b;
+              var r, g, b, a;
+              if (!style) {
+                  return { r: 0, g: 0, b: 0, a: 0, style: style };
+              }
+
+              if (this.internal.rxTransparent.test(style)) {
+                  r = 0;
+                  g = 0;
+                  b = 0;
+                  a = 0;
+              } else {
+                  var m = this.internal.rxRgb.exec(style);
+                  if (m != null) {
+                      r = parseInt(m[1]);
+                      g = parseInt(m[2]);
+                      b = parseInt(m[3]);
+                      a = 1;
+                  } else {
+                      m = this.internal.rxRgba.exec(style);
+                      if (m != null) {
+                          r = parseInt(m[1]);
+                          g = parseInt(m[2]);
+                          b = parseInt(m[3]);
+                          a = parseFloat(m[4]);
+                      } else {
+                          a = 1;
+                          if (style.charAt(0) != '#') {
+                              style = CssColors.colorNameToHex(style);
+                              if (!style) {
+                                  style = '#000000';
+                              }
+                          }
+
+                          if (style.length === 4) {
+                              r = style.substring(1, 2);
+                              r += r;
+                              g = style.substring(2, 3);
+                              g += g;
+                              b = style.substring(3, 4);
+                              b += b;
+                          } else {
+                              r = style.substring(1, 3);
+                              g = style.substring(3, 5);
+                              b = style.substring(5, 7);
+                          }
+                          r = parseInt(r, 16);
+                          g = parseInt(g, 16);
+                          b = parseInt(b, 16);
+                      }
+                  }
+              }
+              return { r: r, g: g, b: b, a: a, style: style };
+          },
+
+          setFillStyle: function setFillStyle(style) {
+              var rgba = this._getRGBA(style);
+
+              this.ctx.fillStyle = style;
+              this.ctx._isFillTransparent = rgba.a === 0;
+              this.ctx._fillOpacity = rgba.a;
+
+              this.pdf.setFillColor(rgba.r, rgba.g, rgba.b, {
+                  a: rgba.a
+              });
+              this.pdf.setTextColor(rgba.r, rgba.g, rgba.b, {
+                  a: rgba.a
+              });
+          },
+
+          setStrokeStyle: function setStrokeStyle(style) {
+              var rgba = this._getRGBA(style);
+
+              this.ctx.strokeStyle = rgba.style;
+              this.ctx._isStrokeTransparent = rgba.a === 0;
+              this.ctx._strokeOpacity = rgba.a;
+
+              //TODO jsPDF to handle rgba
+              if (rgba.a === 0) {
+                  this.pdf.setDrawColor(255, 255, 255);
+              } else if (rgba.a === 1) {
+                  this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b);
+              } else {
+                  //this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b, {a: rgba.a});
+                  this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b);
+              }
+          },
+
+          fillText: function fillText(text, x, y, maxWidth) {
+              if (this._isFillTransparent()) {
+                  return;
+              }
+              x = this._wrapX(x);
+              y = this._wrapY(y);
+
+              var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
+              x = xpt[0];
+              y = xpt[1];
+              var rads = this._matrix_rotation(this.ctx._transform);
+              var degs = rads * 57.2958;
+
+              //TODO only push the clip if it has not been applied to the current PDF context
+              if (this.ctx._clip_path.length > 0) {
+                  var lines;
+                  if (window.outIntercept) {
+                      lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;
+                  } else {
+                      lines = this.internal.getCurrentPage();
+                  }
+                  lines.push("q");
+                  var origPath = this.path;
+                  this.path = this.ctx._clip_path;
+                  this.ctx._clip_path = [];
+                  this._fill(null, true);
+                  this.ctx._clip_path = this.path;
+                  this.path = origPath;
+              }
+
+              // We only use X axis as scale hint 
+              var scale = 1;
+              try {
+                  scale = this._matrix_decompose(this._getTransform()).scale[0];
+              } catch (e) {
+                  console.warn(e);
+              }
+
+              // In some cases the transform was very small (5.715760606202283e-17).  Most likely a canvg rounding error.
+              if (scale < 0.01) {
+                  this.pdf.text(text, x, this._getBaseline(y), null, degs);
+              } else {
+                  var oldSize = this.pdf.internal.getFontSize();
+                  this.pdf.setFontSize(oldSize * scale);
+                  this.pdf.text(text, x, this._getBaseline(y), null, degs);
+                  this.pdf.setFontSize(oldSize);
+              }
+
+              if (this.ctx._clip_path.length > 0) {
+                  lines.push('Q');
+              }
+          },
+
+          strokeText: function strokeText(text, x, y, maxWidth) {
+              if (this._isStrokeTransparent()) {
+                  return;
+              }
+              x = this._wrapX(x);
+              y = this._wrapY(y);
+
+              var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
+              x = xpt[0];
+              y = xpt[1];
+              var rads = this._matrix_rotation(this.ctx._transform);
+              var degs = rads * 57.2958;
+
+              //TODO only push the clip if it has not been applied to the current PDF context
+              if (this.ctx._clip_path.length > 0) {
+                  var lines;
+                  if (window.outIntercept) {
+                      lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;
+                  } else {
+                      lines = this.internal.getCurrentPage();
+                  }
+                  lines.push("q");
+                  var origPath = this.path;
+                  this.path = this.ctx._clip_path;
+                  this.ctx._clip_path = [];
+                  this._fill(null, true);
+                  this.ctx._clip_path = this.path;
+                  this.path = origPath;
+              }
+
+              var scale = 1;
+              // We only use the X axis as scale hint 
+              try {
+                  scale = this._matrix_decompose(this._getTransform()).scale[0];
+              } catch (e) {
+                  console.warn(e);
+              }
+
+              if (scale === 1) {
+                  this.pdf.text(text, x, this._getBaseline(y), {
+                      stroke: true
+                  }, degs);
+              } else {
+                  var oldSize = this.pdf.internal.getFontSize();
+                  this.pdf.setFontSize(oldSize * scale);
+                  this.pdf.text(text, x, this._getBaseline(y), {
+                      stroke: true
+                  }, degs);
+                  this.pdf.setFontSize(oldSize);
+              }
+
+              if (this.ctx._clip_path.length > 0) {
+                  lines.push('Q');
+              }
+          },
+
+          setFont: function setFont(font) {
+              this.ctx.font = font;
+
+              //var rx = /\s*(\w+)\s+(\w+)\s+(\w+)\s+([\d\.]+)(px|pt|em)\s+["']?(\w+)['"]?/;
+              var rx = /\s*(\w+)\s+(\w+)\s+(\w+)\s+([\d\.]+)(px|pt|em)\s+(.*)?/;
+              m = rx.exec(font);
+              if (m != null) {
+                  var fontStyle = m[1];
+                  var fontVariant = m[2];
+                  var fontWeight = m[3];
+                  var fontSize = m[4];
+                  var fontSizeUnit = m[5];
+                  var fontFamily = m[6];
+
+                  if ('px' === fontSizeUnit) {
+                      fontSize = Math.floor(parseFloat(fontSize));
+                      // fontSize = fontSize * 1.25;
+                  } else if ('em' === fontSizeUnit) {
+                      fontSize = Math.floor(parseFloat(fontSize) * this.pdf.getFontSize());
+                  } else {
+                      fontSize = Math.floor(parseFloat(fontSize));
+                  }
+
+                  this.pdf.setFontSize(fontSize);
+
+                  if (fontWeight === 'bold' || fontWeight === '700') {
+                      this.pdf.setFontStyle('bold');
+                  } else {
+                      if (fontStyle === 'italic') {
+                          this.pdf.setFontStyle('italic');
+                      } else {
+                          this.pdf.setFontStyle('normal');
+                      }
+                  }
+
+                  var name = fontFamily;
+                  var parts = name.toLowerCase().split(/\s*,\s*/);
+                  var jsPdfFontName;
+
+                  if (parts.indexOf('arial') != -1) {
+                      jsPdfFontName = 'Arial';
+                  } else if (parts.indexOf('verdana') != -1) {
+                      jsPdfFontName = 'Verdana';
+                  } else if (parts.indexOf('helvetica') != -1) {
+                      jsPdfFontName = 'Helvetica';
+                  } else if (parts.indexOf('sans-serif') != -1) {
+                      jsPdfFontName = 'sans-serif';
+                  } else if (parts.indexOf('fixed') != -1) {
+                      jsPdfFontName = 'Fixed';
+                  } else if (parts.indexOf('monospace') != -1) {
+                      jsPdfFontName = 'Monospace';
+                  } else if (parts.indexOf('terminal') != -1) {
+                      jsPdfFontName = 'Terminal';
+                  } else if (parts.indexOf('courier') != -1) {
+                      jsPdfFontName = 'Courier';
+                  } else if (parts.indexOf('times') != -1) {
+                      jsPdfFontName = 'Times';
+                  } else if (parts.indexOf('cursive') != -1) {
+                      jsPdfFontName = 'Cursive';
+                  } else if (parts.indexOf('fantasy') != -1) {
+                      jsPdfFontName = 'Fantasy';
+                  } else if (parts.indexOf('serif') != -1) {
+                      jsPdfFontName = 'Serif';
+                  } else {
+                      jsPdfFontName = 'Serif';
+                  }
+
+                  //TODO check more cases
+                  var style;
+                  if ('bold' === fontWeight) {
+                      style = 'bold';
+                  } else {
+                      style = 'normal';
+                  }
+
+                  this.pdf.setFont(jsPdfFontName, style);
+              } else {
+                  var rx = /\s*(\d+)(pt|px|em)\s+([\w "]+)\s*([\w "]+)?/;
+                  var m = rx.exec(font);
+                  if (m != null) {
+                      var size = m[1];
+                      var unit = m[2];
+                      var name = m[3];
+                      var style = m[4];
+                      if (!style) {
+                          style = 'normal';
+                      }
+                      if ('em' === fontSizeUnit) {
+                          size = Math.floor(parseFloat(fontSize) * this.pdf.getFontSize());
+                      } else {
+                          size = Math.floor(parseFloat(size));
+                      }
+                      this.pdf.setFontSize(size);
+                      this.pdf.setFont(name, style);
+                  }
+              }
+          },
+
+          setTextBaseline: function setTextBaseline(baseline) {
+              this.ctx.textBaseline = baseline;
+          },
+
+          getTextBaseline: function getTextBaseline() {
+              return this.ctx.textBaseline;
+          },
+
+          //TODO implement textAlign
+          setTextAlign: function setTextAlign(align) {
+              this.ctx.textAlign = align;
+          },
+
+          getTextAlign: function getTextAlign() {
+              return this.ctx.textAlign;
+          },
+
+          setLineWidth: function setLineWidth(width) {
+              this.ctx.lineWidth = width;
+              this.pdf.setLineWidth(width);
+          },
+
+          setLineCap: function setLineCap(style) {
+              this.ctx.lineCap = style;
+              this.pdf.setLineCap(style);
+          },
+
+          setLineJoin: function setLineJoin(style) {
+              this.ctx.lineJoin = style;
+              this.pdf.setLineJoin(style);
+          },
+
+          moveTo: function moveTo(x, y) {
+              x = this._wrapX(x);
+              y = this._wrapY(y);
+
+              var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
+              x = xpt[0];
+              y = xpt[1];
+
+              var obj = {
+                  type: 'mt',
+                  x: x,
+                  y: y
+              };
+              this.path.push(obj);
+          },
+
+          _wrapX: function _wrapX(x) {
+              if (this.pageWrapXEnabled) {
+                  return x % this.pageWrapX;
+              } else {
+                  return x;
+              }
+          },
+
+          _wrapY: function _wrapY(y) {
+              if (this.pageWrapYEnabled) {
+                  this._gotoPage(this._page(y));
+                  return (y - this.lastBreak) % this.pageWrapY;
+              } else {
+                  return y;
+              }
+          },
+
+          transform: function transform(a, b, c, d, e, f) {
+              //TODO apply to current transformation instead of replacing
+              this.ctx._transform = [a, b, c, d, e, f];
+          },
+
+          setTransform: function setTransform(a, b, c, d, e, f) {
+              this.ctx._transform = [a, b, c, d, e, f];
+          },
+
+          _getTransform: function _getTransform() {
+              return this.ctx._transform;
+          },
+
+          lastBreak: 0,
+          // Y Position of page breaks.
+          pageBreaks: [],
+          // returns: One-based Page Number
+          // Should only be used if pageWrapYEnabled is true
+          _page: function _page(y) {
+              if (this.pageWrapYEnabled) {
+                  this.lastBreak = 0;
+                  var manualBreaks = 0;
+                  var autoBreaks = 0;
+                  for (var i = 0; i < this.pageBreaks.length; i++) {
+                      if (y >= this.pageBreaks[i]) {
+                          manualBreaks++;
+                          if (this.lastBreak === 0) {
+                              autoBreaks++;
+                          }
+                          var spaceBetweenLastBreak = this.pageBreaks[i] - this.lastBreak;
+                          this.lastBreak = this.pageBreaks[i];
+                          var pagesSinceLastBreak = Math.floor(spaceBetweenLastBreak / this.pageWrapY);
+                          autoBreaks += pagesSinceLastBreak;
+                      }
+                  }
+                  if (this.lastBreak === 0) {
+                      var pagesSinceLastBreak = Math.floor(y / this.pageWrapY) + 1;
+                      autoBreaks += pagesSinceLastBreak;
+                  }
+                  return autoBreaks + manualBreaks;
+              } else {
+                  return this.pdf.internal.getCurrentPageInfo().pageNumber;
+              }
+          },
+
+          _gotoPage: function _gotoPage(pageOneBased) {
+              // This is a stub to be overriden if needed
+          },
+
+          lineTo: function lineTo(x, y) {
+              x = this._wrapX(x);
+              y = this._wrapY(y);
+
+              var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
+              x = xpt[0];
+              y = xpt[1];
+
+              var obj = {
+                  type: 'lt',
+                  x: x,
+                  y: y
+              };
+              this.path.push(obj);
+          },
+
+          bezierCurveTo: function bezierCurveTo(x1, y1, x2, y2, x, y) {
+              x1 = this._wrapX(x1);
+              y1 = this._wrapY(y1);
+              x2 = this._wrapX(x2);
+              y2 = this._wrapY(y2);
+              x = this._wrapX(x);
+              y = this._wrapY(y);
+
+              var xpt;
+              xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
+              x = xpt[0];
+              y = xpt[1];
+              xpt = this._matrix_map_point(this.ctx._transform, [x1, y1]);
+              x1 = xpt[0];
+              y1 = xpt[1];
+              xpt = this._matrix_map_point(this.ctx._transform, [x2, y2]);
+              x2 = xpt[0];
+              y2 = xpt[1];
+
+              var obj = {
+                  type: 'bct',
+                  x1: x1,
+                  y1: y1,
+                  x2: x2,
+                  y2: y2,
+                  x: x,
+                  y: y
+              };
+              this.path.push(obj);
+          },
+
+          quadraticCurveTo: function quadraticCurveTo(x1, y1, x, y) {
+              x1 = this._wrapX(x1);
+              y1 = this._wrapY(y1);
+              x = this._wrapX(x);
+              y = this._wrapY(y);
+
+              var xpt;
+              xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
+              x = xpt[0];
+              y = xpt[1];
+              xpt = this._matrix_map_point(this.ctx._transform, [x1, y1]);
+              x1 = xpt[0];
+              y1 = xpt[1];
+
+              var obj = {
+                  type: 'qct',
+                  x1: x1,
+                  y1: y1,
+                  x: x,
+                  y: y
+              };
+              this.path.push(obj);
+          },
+
+          arc: function arc(x, y, radius, startAngle, endAngle, anticlockwise) {
+              x = this._wrapX(x);
+              y = this._wrapY(y);
+
+              if (!this._matrix_is_identity(this.ctx._transform)) {
+                  var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
+                  x = xpt[0];
+                  y = xpt[1];
+
+                  var x_radPt0 = this._matrix_map_point(this.ctx._transform, [0, 0]);
+                  var x_radPt = this._matrix_map_point(this.ctx._transform, [0, radius]);
+                  radius = Math.sqrt(Math.pow(x_radPt[0] - x_radPt0[0], 2) + Math.pow(x_radPt[1] - x_radPt0[1], 2));
+
+                  //TODO angles need to be transformed
+              }
+
+              var obj = {
+                  type: 'arc',
+                  x: x,
+                  y: y,
+                  radius: radius,
+                  startAngle: startAngle,
+                  endAngle: endAngle,
+                  anticlockwise: anticlockwise
+              };
+              this.path.push(obj);
+          },
+
+          drawImage: function drawImage(img, x, y, w, h, x2, y2, w2, h2) {
+              if (x2 !== undefined) {
+                  x = x2;
+                  y = y2;
+                  w = w2;
+                  h = h2;
+              }
+              x = this._wrapX(x);
+              y = this._wrapY(y);
+
+              var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h });
+              var xRect2 = this._matrix_map_rect(this.ctx._transform, { x: x2, y: y2, w: w2, h: h2 });
+
+              // TODO implement source clipping and image scaling
+              var format;
+              var rx = /data:image\/(\w+).*/i;
+              var m = rx.exec(img);
+              if (m != null) {
+                  format = m[1];
+              } else {
+                  // format = "jpeg";
+                  format = "png";
+              }
+
+              this.pdf.addImage(img, format, xRect.x, xRect.y, xRect.w, xRect.h);
+          },
+
+          /**
+           * Multiply the first matrix by the second
+           * @param m1
+           * @param m2
+           * @returns {*[]}
+           * @private
+           */
+          _matrix_multiply: function _matrix_multiply(m2, m1) {
+              var sx = m1[0];
+              var shy = m1[1];
+              var shx = m1[2];
+              var sy = m1[3];
+              var tx = m1[4];
+              var ty = m1[5];
+
+              var t0 = sx * m2[0] + shy * m2[2];
+              var t2 = shx * m2[0] + sy * m2[2];
+              var t4 = tx * m2[0] + ty * m2[2] + m2[4];
+              shy = sx * m2[1] + shy * m2[3];
+              sy = shx * m2[1] + sy * m2[3];
+              ty = tx * m2[1] + ty * m2[3] + m2[5];
+              sx = t0;
+              shx = t2;
+              tx = t4;
+
+              return [sx, shy, shx, sy, tx, ty];
+          },
+
+          _matrix_rotation: function _matrix_rotation(m) {
+              return Math.atan2(m[2], m[0]);
+          },
+
+          _matrix_decompose: function _matrix_decompose(matrix) {
+
+              var a = matrix[0];
+              var b = matrix[1];
+              var c = matrix[2];
+              var d = matrix[3];
+
+              var scaleX = Math.sqrt(a * a + b * b);
+              a /= scaleX;
+              b /= scaleX;
+
+              var shear = a * c + b * d;
+              c -= a * shear;
+              d -= b * shear;
+
+              var scaleY = Math.sqrt(c * c + d * d);
+              c /= scaleY;
+              d /= scaleY;
+              shear /= scaleY;
+
+              if (a * d < b * c) {
+                  a = -a;
+                  b = -b;
+                  shear = -shear;
+                  scaleX = -scaleX;
+              }
+
+              return {
+                  scale: [scaleX, 0, 0, scaleY, 0, 0],
+                  translate: [1, 0, 0, 1, matrix[4], matrix[5]],
+                  rotate: [a, b, -b, a, 0, 0],
+                  skew: [1, 0, shear, 1, 0, 0]
+              };
+          },
+
+          _matrix_map_point: function _matrix_map_point(m1, pt) {
+              var sx = m1[0];
+              var shy = m1[1];
+              var shx = m1[2];
+              var sy = m1[3];
+              var tx = m1[4];
+              var ty = m1[5];
+
+              var px = pt[0];
+              var py = pt[1];
+
+              var x = px * sx + py * shx + tx;
+              var y = px * shy + py * sy + ty;
+              return [x, y];
+          },
+
+          _matrix_map_point_obj: function _matrix_map_point_obj(m1, pt) {
+              var xpt = this._matrix_map_point(m1, [pt.x, pt.y]);
+              return { x: xpt[0], y: xpt[1] };
+          },
+
+          _matrix_map_rect: function _matrix_map_rect(m1, rect) {
+              var p1 = this._matrix_map_point(m1, [rect.x, rect.y]);
+              var p2 = this._matrix_map_point(m1, [rect.x + rect.w, rect.y + rect.h]);
+              return { x: p1[0], y: p1[1], w: p2[0] - p1[0], h: p2[1] - p1[1] };
+          },
+
+          _matrix_is_identity: function _matrix_is_identity(m1) {
+              if (m1[0] != 1) {
+                  return false;
+              }
+              if (m1[1] != 0) {
+                  return false;
+              }
+              if (m1[2] != 0) {
+                  return false;
+              }
+              if (m1[3] != 1) {
+                  return false;
+              }
+              if (m1[4] != 0) {
+                  return false;
+              }
+              if (m1[5] != 0) {
+                  return false;
+              }
+              return true;
+          },
+
+          rotate: function rotate(angle) {
+              var matrix = [Math.cos(angle), Math.sin(angle), -Math.sin(angle), Math.cos(angle), 0.0, 0.0];
+              this.ctx._transform = this._matrix_multiply(this.ctx._transform, matrix);
+          },
+
+          scale: function scale(sx, sy) {
+              var matrix = [sx, 0.0, 0.0, sy, 0.0, 0.0];
+              this.ctx._transform = this._matrix_multiply(this.ctx._transform, matrix);
+          },
+
+          translate: function translate(x, y) {
+              var matrix = [1.0, 0.0, 0.0, 1.0, x, y];
+              this.ctx._transform = this._matrix_multiply(this.ctx._transform, matrix);
+          },
+
+          stroke: function stroke() {
+              if (this.ctx._clip_path.length > 0) {
+
+                  var lines;
+                  if (window.outIntercept) {
+                      lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;
+                  } else {
+                      lines = this.internal.getCurrentPage();
+                  }
+                  lines.push("q");
+
+                  var origPath = this.path;
+                  this.path = this.ctx._clip_path;
+                  this.ctx._clip_path = [];
+                  this._stroke(true);
+
+                  this.ctx._clip_path = this.path;
+                  this.path = origPath;
+                  this._stroke(false);
+
+                  lines.push("Q");
+              } else {
+                  this._stroke(false);
+              }
+          },
+
+          _stroke: function _stroke(isClip) {
+              if (!isClip && this._isStrokeTransparent()) {
+                  return;
+              }
+
+              //TODO opacity
+
+              var moves = [];
+
+              var xPath = this.path;
+
+              for (var i = 0; i < xPath.length; i++) {
+                  var pt = xPath[i];
+                  switch (pt.type) {
+                      case 'mt':
+                          moves.push({ start: pt, deltas: [], abs: [] });
+                          break;
+                      case 'lt':
+                          var delta = [pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];
+                          moves[moves.length - 1].deltas.push(delta);
+                          moves[moves.length - 1].abs.push(pt);
+                          break;
+                      case 'bct':
+                          var delta = [pt.x1 - xPath[i - 1].x, pt.y1 - xPath[i - 1].y, pt.x2 - xPath[i - 1].x, pt.y2 - xPath[i - 1].y, pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];
+                          moves[moves.length - 1].deltas.push(delta);
+                          break;
+                      case 'qct':
+                          // convert to bezier
+                          var x1 = xPath[i - 1].x + 2.0 / 3.0 * (pt.x1 - xPath[i - 1].x);
+                          var y1 = xPath[i - 1].y + 2.0 / 3.0 * (pt.y1 - xPath[i - 1].y);
+                          var x2 = pt.x + 2.0 / 3.0 * (pt.x1 - pt.x);
+                          var y2 = pt.y + 2.0 / 3.0 * (pt.y1 - pt.y);
+                          var x3 = pt.x;
+                          var y3 = pt.y;
+                          var delta = [x1 - xPath[i - 1].x, y1 - xPath[i - 1].y, x2 - xPath[i - 1].x, y2 - xPath[i - 1].y, x3 - xPath[i - 1].x, y3 - xPath[i - 1].y];
+                          moves[moves.length - 1].deltas.push(delta);
+                          break;
+                      case 'arc':
+                          //TODO this was hack to avoid out-of-bounds issue
+                          // No move-to before drawing the arc
+                          if (moves.length == 0) {
+                              moves.push({ start: { x: 0, y: 0 }, deltas: [], abs: [] });
+                          }
+                          moves[moves.length - 1].arc = true;
+                          moves[moves.length - 1].abs.push(pt);
+                          break;
+                      case 'close':
+                          break;
+                  }
+              }
+
+              for (var i = 0; i < moves.length; i++) {
+                  var style;
+                  if (i == moves.length - 1) {
+                      style = 's';
+                  } else {
+                      style = null;
+                  }
+                  if (moves[i].arc) {
+                      var arcs = moves[i].abs;
+                      for (var ii = 0; ii < arcs.length; ii++) {
+                          var arc = arcs[ii];
+                          var start = arc.startAngle * 360 / (2 * Math.PI);
+                          var end = arc.endAngle * 360 / (2 * Math.PI);
+                          var x = arc.x;
+                          var y = arc.y;
+                          this.internal.arc2(this, x, y, arc.radius, start, end, arc.anticlockwise, style, isClip);
+                      }
+                  } else {
+                      var x = moves[i].start.x;
+                      var y = moves[i].start.y;
+                      if (!isClip) {
+                          this.pdf.lines(moves[i].deltas, x, y, null, style);
+                      } else {
+                          this.pdf.lines(moves[i].deltas, x, y, null, null);
+                          this.pdf.clip_fixed();
+                      }
+                  }
+              }
+          },
+
+          _isFillTransparent: function _isFillTransparent() {
+              return this.ctx._isFillTransparent || this.globalAlpha == 0;
+          },
+
+          _isStrokeTransparent: function _isStrokeTransparent() {
+              return this.ctx._isStrokeTransparent || this.globalAlpha == 0;
+          },
+
+          fill: function fill(fillRule) {
+              //evenodd or nonzero (default)
+              if (this.ctx._clip_path.length > 0) {
+
+                  var lines;
+                  if (window.outIntercept) {
+                      lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;
+                  } else {
+                      lines = this.internal.getCurrentPage();
+                  }
+                  lines.push("q");
+
+                  var origPath = this.path;
+                  this.path = this.ctx._clip_path;
+                  this.ctx._clip_path = [];
+                  this._fill(fillRule, true);
+
+                  this.ctx._clip_path = this.path;
+                  this.path = origPath;
+                  this._fill(fillRule, false);
+
+                  lines.push('Q');
+              } else {
+                  this._fill(fillRule, false);
+              }
+          },
+
+          _fill: function _fill(fillRule, isClip) {
+              if (this._isFillTransparent()) {
+                  return;
+              }
+              var v2Support = typeof this.pdf.internal.newObject2 === 'function';
+
+              var lines;
+              if (window.outIntercept) {
+                  lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;
+              } else {
+                  lines = this.internal.getCurrentPage();
+              }
+
+              // if (this.ctx._clip_path.length > 0) {
+              //     lines.push('q');
+              //     var oldPath = this.path;
+              //     this.path = this.ctx._clip_path;
+              //     this.ctx._clip_path = [];
+              //     this._fill(fillRule, true);
+              //     this.ctx._clip_path = this.path;
+              //     this.path = oldPath;
+              // }
+
+              var moves = [];
+              var outInterceptOld = window.outIntercept;
+
+              if (v2Support) {
+                  // Blend and Mask
+                  switch (this.ctx.globalCompositeOperation) {
+                      case 'normal':
+                      case 'source-over':
+                          break;
+                      case 'destination-in':
+                      case 'destination-out':
+                          //TODO this need to be added to the current group or page
+                          // define a mask stream
+                          var obj = this.pdf.internal.newStreamObject();
+
+                          // define a mask state
+                          var obj2 = this.pdf.internal.newObject2();
+                          obj2.push('<</Type /ExtGState');
+                          obj2.push('/SMask <</S /Alpha /G ' + obj.objId + ' 0 R>>'); // /S /Luminosity will need to define color space
+                          obj2.push('>>');
+
+                          // add mask to page resources
+                          var gsName = 'MASK' + obj2.objId;
+                          this.pdf.internal.addGraphicsState(gsName, obj2.objId);
+
+                          var instruction = '/' + gsName + ' gs';
+                          // add mask to page, group, or stream
+                          lines.splice(0, 0, 'q');
+                          lines.splice(1, 0, instruction);
+                          lines.push('Q');
+
+                          window.outIntercept = obj;
+                          break;
+                      default:
+                          var dictionaryEntry = '/' + this.pdf.internal.blendModeMap[this.ctx.globalCompositeOperation.toUpperCase()];
+                          if (dictionaryEntry) {
+                              this.pdf.internal.out(dictionaryEntry + ' gs');
+                          }
+                          break;
+                  }
+              }
+
+              var alpha = this.ctx.globalAlpha;
+              if (this.ctx._fillOpacity < 1) {
+                  // TODO combine this with global opacity
+                  alpha = this.ctx._fillOpacity;
+              }
+
+              //TODO check for an opacity graphics state that was already created
+              //TODO do not set opacity if current value is already active
+              if (v2Support) {
+                  var objOpac = this.pdf.internal.newObject2();
+                  objOpac.push('<</Type /ExtGState');
+                  //objOpac.push(this.ctx.globalAlpha + " CA"); // Stroke
+                  //objOpac.push(this.ctx.globalAlpha + " ca"); // Not Stroke
+                  objOpac.push('/CA ' + alpha); // Stroke
+                  objOpac.push('/ca ' + alpha); // Not Stroke
+                  objOpac.push('>>');
+                  var gsName = 'GS_O_' + objOpac.objId;
+                  this.pdf.internal.addGraphicsState(gsName, objOpac.objId);
+                  this.pdf.internal.out('/' + gsName + ' gs');
+              }
+
+              var xPath = this.path;
+
+              for (var i = 0; i < xPath.length; i++) {
+                  var pt = xPath[i];
+                  switch (pt.type) {
+                      case 'mt':
+                          moves.push({ start: pt, deltas: [], abs: [] });
+                          break;
+                      case 'lt':
+                          var delta = [pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];
+                          moves[moves.length - 1].deltas.push(delta);
+                          moves[moves.length - 1].abs.push(pt);
+                          break;
+                      case 'bct':
+                          var delta = [pt.x1 - xPath[i - 1].x, pt.y1 - xPath[i - 1].y, pt.x2 - xPath[i - 1].x, pt.y2 - xPath[i - 1].y, pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];
+                          moves[moves.length - 1].deltas.push(delta);
+                          break;
+                      case 'qct':
+                          // convert to bezier
+                          var x1 = xPath[i - 1].x + 2.0 / 3.0 * (pt.x1 - xPath[i - 1].x);
+                          var y1 = xPath[i - 1].y + 2.0 / 3.0 * (pt.y1 - xPath[i - 1].y);
+                          var x2 = pt.x + 2.0 / 3.0 * (pt.x1 - pt.x);
+                          var y2 = pt.y + 2.0 / 3.0 * (pt.y1 - pt.y);
+                          var x3 = pt.x;
+                          var y3 = pt.y;
+                          var delta = [x1 - xPath[i - 1].x, y1 - xPath[i - 1].y, x2 - xPath[i - 1].x, y2 - xPath[i - 1].y, x3 - xPath[i - 1].x, y3 - xPath[i - 1].y];
+                          moves[moves.length - 1].deltas.push(delta);
+                          break;
+                      case 'arc':
+                          //TODO this was hack to avoid out-of-bounds issue when drawing circle
+                          // No move-to before drawing the arc
+                          if (moves.length === 0) {
+                              moves.push({ deltas: [], abs: [] });
+                          }
+                          moves[moves.length - 1].arc = true;
+                          moves[moves.length - 1].abs.push(pt);
+                          break;
+                      case 'close':
+                          moves.push({ close: true });
+                          break;
+                  }
+              }
+
+              for (var i = 0; i < moves.length; i++) {
+                  var style;
+                  if (i == moves.length - 1) {
+                      style = 'f';
+                      if (fillRule === 'evenodd') {
+                          style += '*';
+                      }
+                  } else {
+                      style = null;
+                  }
+
+                  if (moves[i].close) {
+                      this.pdf.internal.out('h');
+                      if (style) {
+                          // only fill at final path move
+                          this.pdf.internal.out(style);
+                      }
+                  } else if (moves[i].arc) {
+                      if (moves[i].start) {
+                          this.internal.move2(this, moves[i].start.x, moves[i].start.y);
+                      }
+                      var arcs = moves[i].abs;
+                      for (var ii = 0; ii < arcs.length; ii++) {
+                          var arc = arcs[ii];
+                          //TODO lines deltas were getting in here
+                          if (typeof arc.startAngle !== 'undefined') {
+                              var start = arc.startAngle * 360 / (2 * Math.PI);
+                              var end = arc.endAngle * 360 / (2 * Math.PI);
+                              var x = arc.x;
+                              var y = arc.y;
+                              if (ii === 0) {
+                                  this.internal.move2(this, x, y);
+                              }
+                              this.internal.arc2(this, x, y, arc.radius, start, end, arc.anticlockwise, null, isClip);
+                              if (ii === arcs.length - 1) {
+                                  // The original arc move did not occur because of the algorithm
+                                  if (moves[i].start) {
+                                      var x = moves[i].start.x;
+                                      var y = moves[i].start.y;
+                                      this.internal.line2(c2d, x, y);
+                                  }
+                              }
+                          } else {
+                              this.internal.line2(c2d, arc.x, arc.y);
+                          }
+                      }
+                  } else {
+                      var x = moves[i].start.x;
+                      var y = moves[i].start.y;
+                      if (!isClip) {
+                          this.pdf.lines(moves[i].deltas, x, y, null, style);
+                      } else {
+                          this.pdf.lines(moves[i].deltas, x, y, null, null);
+                          this.pdf.clip_fixed();
+                      }
+                  }
+              }
+
+              window.outIntercept = outInterceptOld;
+
+              // if (this.ctx._clip_path.length > 0) {
+              //     lines.push('Q');
+              // }
+          },
+
+          pushMask: function pushMask() {
+              var v2Support = typeof this.pdf.internal.newObject2 === 'function';
+
+              if (!v2Support) {
+                  console.log('jsPDF v2 not enabled');
+                  return;
+              }
+
+              // define a mask stream
+              var obj = this.pdf.internal.newStreamObject();
+
+              // define a mask state
+              var obj2 = this.pdf.internal.newObject2();
+              obj2.push('<</Type /ExtGState');
+              obj2.push('/SMask <</S /Alpha /G ' + obj.objId + ' 0 R>>'); // /S /Luminosity will need to define color space
+              obj2.push('>>');
+
+              // add mask to page resources
+              var gsName = 'MASK' + obj2.objId;
+              this.pdf.internal.addGraphicsState(gsName, obj2.objId);
+
+              var instruction = '/' + gsName + ' gs';
+              this.pdf.internal.out(instruction);
+          },
+
+          clip: function clip() {
+              //TODO do we reset the path, or just copy it?
+              if (this.ctx._clip_path.length > 0) {
+                  for (var i = 0; i < this.path.length; i++) {
+                      this.ctx._clip_path.push(this.path[i]);
+                  }
+              } else {
+                  this.ctx._clip_path = this.path;
+              }
+              this.path = [];
+          },
+
+          measureText: function measureText(text) {
+              var pdf = this.pdf;
+              return {
+                  getWidth: function getWidth() {
+                      var fontSize = pdf.internal.getFontSize();
+                      var txtWidth = pdf.getStringUnitWidth(text) * fontSize / pdf.internal.scaleFactor;
+                      // Convert points to pixels
+                      txtWidth *= 1.3333;
+                      return txtWidth;
+                  },
+
+                  get width() {
+                      return this.getWidth(text);
+                  }
+              };
+          },
+          _getBaseline: function _getBaseline(y) {
+              var height = parseInt(this.pdf.internal.getFontSize());
+              // TODO Get descent from font descriptor
+              var descent = height * 0.25;
+              switch (this.ctx.textBaseline) {
+                  case 'bottom':
+                      return y - descent;
+                  case 'top':
+                      return y + height;
+                  case 'hanging':
+                      return y + height - descent;
+                  case 'middle':
+                      return y + height / 2 - descent;
+                  case 'ideographic':
+                      // TODO not implemented
+                      return y;
+                  case 'alphabetic':
+                  default:
+                      return y;
+              }
+          }
+      };
+
+      var c2d = jsPDFAPI.context2d;
+
+      // accessor methods
+      Object.defineProperty(c2d, 'fillStyle', {
+          set: function set(value) {
+              this.setFillStyle(value);
+          },
+          get: function get() {
+              return this.ctx.fillStyle;
+          }
+      });
+      Object.defineProperty(c2d, 'strokeStyle', {
+          set: function set(value) {
+              this.setStrokeStyle(value);
+          },
+          get: function get() {
+              return this.ctx.strokeStyle;
+          }
+      });
+      Object.defineProperty(c2d, 'lineWidth', {
+          set: function set(value) {
+              this.setLineWidth(value);
+          },
+          get: function get() {
+              return this.ctx.lineWidth;
+          }
+      });
+      Object.defineProperty(c2d, 'lineCap', {
+          set: function set(val) {
+              this.setLineCap(val);
+          },
+          get: function get() {
+              return this.ctx.lineCap;
+          }
+      });
+      Object.defineProperty(c2d, 'lineJoin', {
+          set: function set(val) {
+              this.setLineJoin(val);
+          },
+          get: function get() {
+              return this.ctx.lineJoin;
+          }
+      });
+      Object.defineProperty(c2d, 'miterLimit', {
+          set: function set(val) {
+              this.ctx.miterLimit = val;
+          },
+          get: function get() {
+              return this.ctx.miterLimit;
+          }
+      });
+      Object.defineProperty(c2d, 'textBaseline', {
+          set: function set(value) {
+              this.setTextBaseline(value);
+          },
+          get: function get() {
+              return this.getTextBaseline();
+          }
+      });
+      Object.defineProperty(c2d, 'textAlign', {
+          set: function set(value) {
+              this.setTextAlign(value);
+          },
+          get: function get() {
+              return this.getTextAlign();
+          }
+      });
+      Object.defineProperty(c2d, 'font', {
+          set: function set(value) {
+              this.setFont(value);
+          },
+          get: function get() {
+              return this.ctx.font;
+          }
+      });
+      Object.defineProperty(c2d, 'globalCompositeOperation', {
+          set: function set(value) {
+              this.ctx.globalCompositeOperation = value;
+          },
+          get: function get() {
+              return this.ctx.globalCompositeOperation;
+          }
+      });
+      Object.defineProperty(c2d, 'globalAlpha', {
+          set: function set(value) {
+              this.ctx.globalAlpha = value;
+          },
+          get: function get() {
+              return this.ctx.globalAlpha;
+          }
+      });
+      // Not HTML API
+      Object.defineProperty(c2d, 'ignoreClearRect', {
+          set: function set(value) {
+              this.ctx.ignoreClearRect = value;
+          },
+          get: function get() {
+              return this.ctx.ignoreClearRect;
+          }
+      });
+      // End Not HTML API
+
+      c2d.internal = {};
+
+      c2d.internal.rxRgb = /rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/;
+      c2d.internal.rxRgba = /rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/;
+      c2d.internal.rxTransparent = /transparent|rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*0+\s*\)/;
+
+      // http://hansmuller-flex.blogspot.com/2011/10/more-about-approximating-circular-arcs.html
+      c2d.internal.arc = function (c2d, xc, yc, r, a1, a2, anticlockwise, style) {
+
+          var k = this.pdf.internal.scaleFactor;
+          var pageHeight = this.pdf.internal.pageSize.getHeight();
+          var f2 = this.pdf.internal.f2;
+
+          var a1r = a1 * (Math.PI / 180);
+          var a2r = a2 * (Math.PI / 180);
+          var curves = this.createArc(r, a1r, a2r, anticlockwise);
+
+          for (var i = 0; i < curves.length; i++) {
+              var curve = curves[i];
+              if (i === 0) {
+                  this.pdf.internal.out([f2((curve.x1 + xc) * k), f2((pageHeight - (curve.y1 + yc)) * k), 'm', f2((curve.x2 + xc) * k), f2((pageHeight - (curve.y2 + yc)) * k), f2((curve.x3 + xc) * k), f2((pageHeight - (curve.y3 + yc)) * k), f2((curve.x4 + xc) * k), f2((pageHeight - (curve.y4 + yc)) * k), 'c'].join(' '));
+              } else {
+                  this.pdf.internal.out([f2((curve.x2 + xc) * k), f2((pageHeight - (curve.y2 + yc)) * k), f2((curve.x3 + xc) * k), f2((pageHeight - (curve.y3 + yc)) * k), f2((curve.x4 + xc) * k), f2((pageHeight - (curve.y4 + yc)) * k), 'c'].join(' '));
+              }
+
+              //c2d._lastPoint = {x: curve.x1 + xc, y: curve.y1 + yc};
+              c2d._lastPoint = { x: xc, y: yc };
+              // f2((curve.x1 + xc) * k), f2((pageHeight - (curve.y1 + yc)) * k), 'm', f2((curve.x2 + xc) * k), f2((pageHeight - (curve.y2 + yc)) * k), f2((curve.x3 + xc) * k), f2((pageHeight - (curve.y3 + yc)) * k), f2((curve.x4 + xc) * k), f2((pageHeight - (curve.y4 + yc)) * k), 'c'
+          }
+
+          if (style !== null) {
+              this.pdf.internal.out(this.pdf.internal.getStyle(style));
+          }
+      };
+
+      /**
+       *
+       * @param x Edge point X
+       * @param y Edge point Y
+       * @param r Radius
+       * @param a1 start angle
+       * @param a2 end angle
+       * @param anticlockwise
+       * @param style
+       * @param isClip
+       */
+      c2d.internal.arc2 = function (c2d, x, y, r, a1, a2, anticlockwise, style, isClip) {
+          // we need to convert from cartesian to polar here methinks.
+          var centerX = x; // + r;
+          var centerY = y;
+
+          if (!isClip) {
+              this.arc(c2d, centerX, centerY, r, a1, a2, anticlockwise, style);
+          } else {
+              this.arc(c2d, centerX, centerY, r, a1, a2, anticlockwise, null);
+              this.pdf.clip_fixed();
+          }
+      };
+
+      c2d.internal.move2 = function (c2d, x, y) {
+          var k = this.pdf.internal.scaleFactor;
+          var pageHeight = this.pdf.internal.pageSize.getHeight();
+          var f2 = this.pdf.internal.f2;
+
+          this.pdf.internal.out([f2(x * k), f2((pageHeight - y) * k), 'm'].join(' '));
+          c2d._lastPoint = { x: x, y: y };
+      };
+
+      c2d.internal.line2 = function (c2d, dx, dy) {
+          var k = this.pdf.internal.scaleFactor;
+          var pageHeight = this.pdf.internal.pageSize.getHeight();
+          var f2 = this.pdf.internal.f2;
+
+          //var pt = {x: c2d._lastPoint.x + dx, y: c2d._lastPoint.y + dy};
+          var pt = { x: dx, y: dy };
+
+          this.pdf.internal.out([f2(pt.x * k), f2((pageHeight - pt.y) * k), 'l'].join(' '));
+          //this.pdf.internal.out('f');
+          c2d._lastPoint = pt;
+      };
+
+      /**
+       * Return a array of objects that represent bezier curves which approximate the circular arc centered at the origin, from startAngle to endAngle (radians) with the specified radius.
+       *
+       * Each bezier curve is an object with four points, where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points.
+       */
+
+      c2d.internal.createArc = function (radius, startAngle, endAngle, anticlockwise) {
+          var EPSILON = 0.00001; // Roughly 1/1000th of a degree, see below
+          var twoPI = Math.PI * 2;
+          var piOverTwo = Math.PI / 2.0;
+
+          // normalize startAngle, endAngle to [0, 2PI]
+          var startAngleN = startAngle;
+          if (startAngleN < twoPI || startAngleN > twoPI) {
+              startAngleN = startAngleN % twoPI;
+          }
+          if (startAngleN < 0) {
+              startAngleN = twoPI + startAngleN;
+          }
+
+          while (startAngle > endAngle) {
+              startAngle = startAngle - twoPI;
+          }
+          var totalAngle = Math.abs(endAngle - startAngle);
+          if (totalAngle < twoPI) {
+              if (anticlockwise) {
+                  totalAngle = twoPI - totalAngle;
+              }
+          }
+
+          // Compute the sequence of arc curves, up to PI/2 at a time.
+          var curves = [];
+          var sgn = anticlockwise ? -1 : +1;
+
+          var a1 = startAngleN;
+          for (; totalAngle > EPSILON;) {
+              var remain = sgn * Math.min(totalAngle, piOverTwo);
+              var a2 = a1 + remain;
+              curves.push(this.createSmallArc(radius, a1, a2));
+              totalAngle -= Math.abs(a2 - a1);
+              a1 = a2;
+          }
+
+          return curves;
+      };
+
+      c2d.internal.getCurrentPage = function () {
+          return this.pdf.internal.pages[this.pdf.internal.getCurrentPageInfo().pageNumber];
+      };
+
+      /**
+       * Cubic bezier approximation of a circular arc centered at the origin, from (radians) a1 to a2, where a2-a1 < pi/2. The arc's radius is r.
+       *
+       * Returns an object with four points, where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points.
+       *
+       * This algorithm is based on the approach described in: A. Riškus, "Approximation of a Cubic Bezier Curve by Circular Arcs and Vice Versa," Information Technology and Control, 35(4), 2006 pp. 371-378.
+       */
+
+      c2d.internal.createSmallArc = function (r, a1, a2) {
+          // Compute all four points for an arc that subtends the same total angle
+          // but is centered on the X-axis
+
+          var a = (a2 - a1) / 2.0;
+
+          var x4 = r * Math.cos(a);
+          var y4 = r * Math.sin(a);
+          var x1 = x4;
+          var y1 = -y4;
+
+          var q1 = x1 * x1 + y1 * y1;
+          var q2 = q1 + x1 * x4 + y1 * y4;
+          var k2 = 4 / 3 * (Math.sqrt(2 * q1 * q2) - q2) / (x1 * y4 - y1 * x4);
+
+          var x2 = x1 - k2 * y1;
+          var y2 = y1 + k2 * x1;
+          var x3 = x2;
+          var y3 = -y2;
+
+          // Find the arc points' actual locations by computing x1,y1 and x4,y4
+          // and rotating the control points by a + a1
+
+          var ar = a + a1;
+          var cos_ar = Math.cos(ar);
+          var sin_ar = Math.sin(ar);
+
+          return {
+              x1: r * Math.cos(a1),
+              y1: r * Math.sin(a1),
+              x2: x2 * cos_ar - y2 * sin_ar,
+              y2: x2 * sin_ar + y2 * cos_ar,
+              x3: x3 * cos_ar - y3 * sin_ar,
+              y3: x3 * sin_ar + y3 * cos_ar,
+              x4: r * Math.cos(a2),
+              y4: r * Math.sin(a2)
+          };
+      };
+
+      function context() {
+          this._isStrokeTransparent = false;
+          this._strokeOpacity = 1;
+          this.strokeStyle = '#000000';
+          this.fillStyle = '#000000';
+          this._isFillTransparent = false;
+          this._fillOpacity = 1;
+          this.font = "12pt times";
+          this.textBaseline = 'alphabetic'; // top,bottom,middle,ideographic,alphabetic,hanging
+          this.textAlign = 'start';
+          this.lineWidth = 1;
+          this.lineJoin = 'miter'; // round, bevel, miter
+          this.lineCap = 'butt'; // butt, round, square
+          this._transform = [1, 0, 0, 1, 0, 0]; // sx, shy, shx, sy, tx, ty
+          this.globalCompositeOperation = 'normal';
+          this.globalAlpha = 1.0;
+          this._clip_path = [];
+          // TODO miter limit //default 10
+
+          // Not HTML API
+          this.ignoreClearRect = false;
+
+          this.copy = function (ctx) {
+              this._isStrokeTransparent = ctx._isStrokeTransparent;
+              this._strokeOpacity = ctx._strokeOpacity;
+              this.strokeStyle = ctx.strokeStyle;
+              this._isFillTransparent = ctx._isFillTransparent;
+              this._fillOpacity = ctx._fillOpacity;
+              this.fillStyle = ctx.fillStyle;
+              this.font = ctx.font;
+              this.lineWidth = ctx.lineWidth;
+              this.lineJoin = ctx.lineJoin;
+              this.lineCap = ctx.lineCap;
+              this.textBaseline = ctx.textBaseline;
+              this.textAlign = ctx.textAlign;
+              this._fontSize = ctx._fontSize;
+              this._transform = ctx._transform.slice(0);
+              this.globalCompositeOperation = ctx.globalCompositeOperation;
+              this.globalAlpha = ctx.globalAlpha;
+              this._clip_path = ctx._clip_path.slice(0); //TODO deep copy?
+
+              // Not HTML API
+              this.ignoreClearRect = ctx.ignoreClearRect;
+          };
+      }
+
+      return this;
+  })(jsPDF.API);
+
+  /** @preserve
+   * jsPDF fromHTML plugin. BETA stage. API subject to change. Needs browser
+   * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
+   *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
+   *               2014 Diego Casorran, https://github.com/diegocr
+   *               2014 Daniel Husar, https://github.com/danielhusar
+   *               2014 Wolfgang Gassler, https://github.com/woolfg
+   *               2014 Steven Spungin, https://github.com/flamenco
+   *
+   * 
+   * ====================================================================
+   */
+
+  (function (jsPDFAPI) {
+  	var clone, _DrillForContent, FontNameDB, FontStyleMap, TextAlignMap, FontWeightMap, FloatMap, ClearMap, GetCSS, PurgeWhiteSpace, Renderer, ResolveFont, ResolveUnitedNumber, UnitedNumberMap, elementHandledElsewhere, images, loadImgs, checkForFooter, process, tableToJson;
+  	clone = function () {
+  		return function (obj) {
+  			Clone.prototype = obj;
+  			return new Clone();
+  		};
+  		function Clone() {}
+  	}();
+  	PurgeWhiteSpace = function PurgeWhiteSpace(array) {
+  		var fragment, i, l, lTrimmed, r, rTrimmed, trailingSpace;
+  		i = 0;
+  		l = array.length;
+  		fragment = void 0;
+  		lTrimmed = false;
+  		rTrimmed = false;
+  		while (!lTrimmed && i !== l) {
+  			fragment = array[i] = array[i].trimLeft();
+  			if (fragment) {
+  				lTrimmed = true;
+  			}
+  			i++;
+  		}
+  		i = l - 1;
+  		while (l && !rTrimmed && i !== -1) {
+  			fragment = array[i] = array[i].trimRight();
+  			if (fragment) {
+  				rTrimmed = true;
+  			}
+  			i--;
+  		}
+  		r = /\s+$/g;
+  		trailingSpace = true;
+  		i = 0;
+  		while (i !== l) {
+  			// Leave the line breaks intact
+  			if (array[i] != "\u2028") {
+  				fragment = array[i].replace(/\s+/g, " ");
+  				if (trailingSpace) {
+  					fragment = fragment.trimLeft();
+  				}
+  				if (fragment) {
+  					trailingSpace = r.test(fragment);
+  				}
+  				array[i] = fragment;
+  			}
+  			i++;
+  		}
+  		return array;
+  	};
+  	Renderer = function Renderer(pdf, x, y, settings) {
+  		this.pdf = pdf;
+  		this.x = x;
+  		this.y = y;
+  		this.settings = settings;
+  		//list of functions which are called after each element-rendering process
+  		this.watchFunctions = [];
+  		this.init();
+  		return this;
+  	};
+  	ResolveFont = function ResolveFont(css_font_family_string) {
+  		var name, part, parts;
+  		name = void 0;
+  		parts = css_font_family_string.split(",");
+  		part = parts.shift();
+  		while (!name && part) {
+  			name = FontNameDB[part.trim().toLowerCase()];
+  			part = parts.shift();
+  		}
+  		return name;
+  	};
+  	ResolveUnitedNumber = function ResolveUnitedNumber(css_line_height_string) {
+
+  		//IE8 issues
+  		css_line_height_string = css_line_height_string === "auto" ? "0px" : css_line_height_string;
+  		if (css_line_height_string.indexOf("em") > -1 && !isNaN(Number(css_line_height_string.replace("em", "")))) {
+  			css_line_height_string = Number(css_line_height_string.replace("em", "")) * 18.719 + "px";
+  		}
+  		if (css_line_height_string.indexOf("pt") > -1 && !isNaN(Number(css_line_height_string.replace("pt", "")))) {
+  			css_line_height_string = Number(css_line_height_string.replace("pt", "")) * 1.333 + "px";
+  		}
+
+  		var normal, undef, value;
+  		undef = void 0;
+  		normal = 16.00;
+  		value = UnitedNumberMap[css_line_height_string];
+  		if (value) {
+  			return value;
+  		}
+  		value = {
+  			"xx-small": 9,
+  			"x-small": 11,
+  			small: 13,
+  			medium: 16,
+  			large: 19,
+  			"x-large": 23,
+  			"xx-large": 28,
+  			auto: 0
+  		}[{ css_line_height_string: css_line_height_string }];
+
+  		if (value !== undef) {
+  			return UnitedNumberMap[css_line_height_string] = value / normal;
+  		}
+  		if (value = parseFloat(css_line_height_string)) {
+  			return UnitedNumberMap[css_line_height_string] = value / normal;
+  		}
+  		value = css_line_height_string.match(/([\d\.]+)(px)/);
+  		if (value.length === 3) {
+  			return UnitedNumberMap[css_line_height_string] = parseFloat(value[1]) / normal;
+  		}
+  		return UnitedNumberMap[css_line_height_string] = 1;
+  	};
+  	GetCSS = function GetCSS(element) {
+  		var css, tmp, computedCSSElement;
+  		computedCSSElement = function (el) {
+  			var compCSS;
+  			compCSS = function (el) {
+  				if (document.defaultView && document.defaultView.getComputedStyle) {
+  					return document.defaultView.getComputedStyle(el, null);
+  				} else if (el.currentStyle) {
+  					return el.currentStyle;
+  				} else {
+  					return el.style;
+  				}
+  			}(el);
+  			return function (prop) {
+  				prop = prop.replace(/-\D/g, function (match) {
+  					return match.charAt(1).toUpperCase();
+  				});
+  				return compCSS[prop];
+  			};
+  		}(element);
+  		css = {};
+  		tmp = void 0;
+  		css["font-family"] = ResolveFont(computedCSSElement("font-family")) || "times";
+  		css["font-style"] = FontStyleMap[computedCSSElement("font-style")] || "normal";
+  		css["text-align"] = TextAlignMap[computedCSSElement("text-align")] || "left";
+  		tmp = FontWeightMap[computedCSSElement("font-weight")] || "normal";
+  		if (tmp === "bold") {
+  			if (css["font-style"] === "normal") {
+  				css["font-style"] = tmp;
+  			} else {
+  				css["font-style"] = tmp + css["font-style"];
+  			}
+  		}
+  		css["font-size"] = ResolveUnitedNumber(computedCSSElement("font-size")) || 1;
+  		css["line-height"] = ResolveUnitedNumber(computedCSSElement("line-height")) || 1;
+  		css["display"] = computedCSSElement("display") === "inline" ? "inline" : "block";
+
+  		tmp = css["display"] === "block";
+  		css["margin-top"] = tmp && ResolveUnitedNumber(computedCSSElement("margin-top")) || 0;
+  		css["margin-bottom"] = tmp && ResolveUnitedNumber(computedCSSElement("margin-bottom")) || 0;
+  		css["padding-top"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-top")) || 0;
+  		css["padding-bottom"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-bottom")) || 0;
+  		css["margin-left"] = tmp && ResolveUnitedNumber(computedCSSElement("margin-left")) || 0;
+  		css["margin-right"] = tmp && ResolveUnitedNumber(computedCSSElement("margin-right")) || 0;
+  		css["padding-left"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-left")) || 0;
+  		css["padding-right"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-right")) || 0;
+
+  		css["page-break-before"] = computedCSSElement("page-break-before") || "auto";
+
+  		//float and clearing of floats
+  		css["float"] = FloatMap[computedCSSElement("cssFloat")] || "none";
+  		css["clear"] = ClearMap[computedCSSElement("clear")] || "none";
+
+  		css["color"] = computedCSSElement("color");
+
+  		return css;
+  	};
+  	elementHandledElsewhere = function elementHandledElsewhere(element, renderer, elementHandlers) {
+  		var handlers, i, isHandledElsewhere, l, classNames;
+  		isHandledElsewhere = false;
+  		i = void 0;
+  		l = void 0;
+  		handlers = elementHandlers["#" + element.id];
+  		if (handlers) {
+  			if (typeof handlers === "function") {
+  				isHandledElsewhere = handlers(element, renderer);
+  			} else {
+  				i = 0;
+  				l = handlers.length;
+  				while (!isHandledElsewhere && i !== l) {
+  					isHandledElsewhere = handlers[i](element, renderer);
+  					i++;
+  				}
+  			}
+  		}
+  		handlers = elementHandlers[element.nodeName];
+  		if (!isHandledElsewhere && handlers) {
+  			if (typeof handlers === "function") {
+  				isHandledElsewhere = handlers(element, renderer);
+  			} else {
+  				i = 0;
+  				l = handlers.length;
+  				while (!isHandledElsewhere && i !== l) {
+  					isHandledElsewhere = handlers[i](element, renderer);
+  					i++;
+  				}
+  			}
+  		}
+
+  		// Try class names
+  		classNames = typeof element.className === 'string' ? element.className.split(' ') : [];
+  		for (i = 0; i < classNames.length; i++) {
+  			handlers = elementHandlers['.' + classNames[i]];
+  			if (!isHandledElsewhere && handlers) {
+  				if (typeof handlers === "function") {
+  					isHandledElsewhere = handlers(element, renderer);
+  				} else {
+  					i = 0;
+  					l = handlers.length;
+  					while (!isHandledElsewhere && i !== l) {
+  						isHandledElsewhere = handlers[i](element, renderer);
+  						i++;
+  					}
+  				}
+  			}
+  		}
+
+  		return isHandledElsewhere;
+  	};
+  	tableToJson = function tableToJson(table, renderer) {
+  		var data, headers, i, j, rowData, tableRow, table_obj, table_with, cell, l;
+  		data = [];
+  		headers = [];
+  		i = 0;
+  		l = table.rows[0].cells.length;
+  		table_with = table.clientWidth;
+  		while (i < l) {
+  			cell = table.rows[0].cells[i];
+  			headers[i] = {
+  				name: cell.textContent.toLowerCase().replace(/\s+/g, ''),
+  				prompt: cell.textContent.replace(/\r?\n/g, ''),
+  				width: cell.clientWidth / table_with * renderer.pdf.internal.pageSize.getWidth()
+  			};
+  			i++;
+  		}
+  		i = 1;
+  		while (i < table.rows.length) {
+  			tableRow = table.rows[i];
+  			rowData = {};
+  			j = 0;
+  			while (j < tableRow.cells.length) {
+  				rowData[headers[j].name] = tableRow.cells[j].textContent.replace(/\r?\n/g, '');
+  				j++;
+  			}
+  			data.push(rowData);
+  			i++;
+  		}
+  		return table_obj = {
+  			rows: data,
+  			headers: headers
+  		};
+  	};
+  	var SkipNode = {
+  		SCRIPT: 1,
+  		STYLE: 1,
+  		NOSCRIPT: 1,
+  		OBJECT: 1,
+  		EMBED: 1,
+  		SELECT: 1
+  	};
+  	var listCount = 1;
+  	_DrillForContent = function DrillForContent(element, renderer, elementHandlers) {
+  		var cn, cns, fragmentCSS, i, isBlock, l, table2json, cb;
+  		cns = element.childNodes;
+  		cn = void 0;
+  		fragmentCSS = GetCSS(element);
+  		isBlock = fragmentCSS.display === "block";
+  		if (isBlock) {
+  			renderer.setBlockBoundary();
+  			renderer.setBlockStyle(fragmentCSS);
+  		}
+  		i = 0;
+  		l = cns.length;
+  		while (i < l) {
+  			cn = cns[i];
+  			if ((typeof cn === "undefined" ? "undefined" : _typeof(cn)) === "object") {
+
+  				//execute all watcher functions to e.g. reset floating
+  				renderer.executeWatchFunctions(cn);
+
+  				/*** HEADER rendering **/
+  				if (cn.nodeType === 1 && cn.nodeName === 'HEADER') {
+  					var header = cn;
+  					//store old top margin
+  					var oldMarginTop = renderer.pdf.margins_doc.top;
+  					//subscribe for new page event and render header first on every page
+  					renderer.pdf.internal.events.subscribe('addPage', function (pageInfo) {
+  						//set current y position to old margin
+  						renderer.y = oldMarginTop;
+  						//render all child nodes of the header element
+  						_DrillForContent(header, renderer, elementHandlers);
+  						//set margin to old margin + rendered header + 10 space to prevent overlapping
+  						//important for other plugins (e.g. table) to start rendering at correct position after header
+  						renderer.pdf.margins_doc.top = renderer.y + 10;
+  						renderer.y += 10;
+  					}, false);
+  				}
+
+  				if (cn.nodeType === 8 && cn.nodeName === "#comment") {
+  					if (~cn.textContent.indexOf("ADD_PAGE")) {
+  						renderer.pdf.addPage();
+  						renderer.y = renderer.pdf.margins_doc.top;
+  					}
+  				} else if (cn.nodeType === 1 && !SkipNode[cn.nodeName]) {
+  					/*** IMAGE RENDERING ***/
+  					var cached_image;
+  					if (cn.nodeName === "IMG") {
+  						var url = cn.getAttribute("src");
+  						cached_image = images[renderer.pdf.sHashCode(url) || url];
+  					}
+  					if (cached_image) {
+  						if (renderer.pdf.internal.pageSize.getHeight() - renderer.pdf.margins_doc.bottom < renderer.y + cn.height && renderer.y > renderer.pdf.margins_doc.top) {
+  							renderer.pdf.addPage();
+  							renderer.y = renderer.pdf.margins_doc.top;
+  							//check if we have to set back some values due to e.g. header rendering for new page
+  							renderer.executeWatchFunctions(cn);
+  						}
+
+  						var imagesCSS = GetCSS(cn);
+  						var imageX = renderer.x;
+  						var fontToUnitRatio = 12 / renderer.pdf.internal.scaleFactor;
+
+  						//define additional paddings, margins which have to be taken into account for margin calculations
+  						var additionalSpaceLeft = (imagesCSS["margin-left"] + imagesCSS["padding-left"]) * fontToUnitRatio;
+  						var additionalSpaceRight = (imagesCSS["margin-right"] + imagesCSS["padding-right"]) * fontToUnitRatio;
+  						var additionalSpaceTop = (imagesCSS["margin-top"] + imagesCSS["padding-top"]) * fontToUnitRatio;
+  						var additionalSpaceBottom = (imagesCSS["margin-bottom"] + imagesCSS["padding-bottom"]) * fontToUnitRatio;
+
+  						//if float is set to right, move the image to the right border
+  						//add space if margin is set
+  						if (imagesCSS['float'] !== undefined && imagesCSS['float'] === 'right') {
+  							imageX += renderer.settings.width - cn.width - additionalSpaceRight;
+  						} else {
+  							imageX += additionalSpaceLeft;
+  						}
+
+  						renderer.pdf.addImage(cached_image, imageX, renderer.y + additionalSpaceTop, cn.width, cn.height);
+  						cached_image = undefined;
+  						//if the float prop is specified we have to float the text around the image
+  						if (imagesCSS['float'] === 'right' || imagesCSS['float'] === 'left') {
+  							//add functiont to set back coordinates after image rendering
+  							renderer.watchFunctions.push(function (diffX, thresholdY, diffWidth, el) {
+  								//undo drawing box adaptions which were set by floating
+  								if (renderer.y >= thresholdY) {
+  									renderer.x += diffX;
+  									renderer.settings.width += diffWidth;
+  									return true;
+  								} else if (el && el.nodeType === 1 && !SkipNode[el.nodeName] && renderer.x + el.width > renderer.pdf.margins_doc.left + renderer.pdf.margins_doc.width) {
+  									renderer.x += diffX;
+  									renderer.y = thresholdY;
+  									renderer.settings.width += diffWidth;
+  									return true;
+  								} else {
+  									return false;
+  								}
+  							}.bind(this, imagesCSS['float'] === 'left' ? -cn.width - additionalSpaceLeft - additionalSpaceRight : 0, renderer.y + cn.height + additionalSpaceTop + additionalSpaceBottom, cn.width));
+  							//reset floating by clear:both divs
+  							//just set cursorY after the floating element
+  							renderer.watchFunctions.push(function (yPositionAfterFloating, pages, el) {
+  								if (renderer.y < yPositionAfterFloating && pages === renderer.pdf.internal.getNumberOfPages()) {
+  									if (el.nodeType === 1 && GetCSS(el).clear === 'both') {
+  										renderer.y = yPositionAfterFloating;
+  										return true;
+  									} else {
+  										return false;
+  									}
+  								} else {
+  									return true;
+  								}
+  							}.bind(this, renderer.y + cn.height, renderer.pdf.internal.getNumberOfPages()));
+
+  							//if floating is set we decrease the available width by the image width
+  							renderer.settings.width -= cn.width + additionalSpaceLeft + additionalSpaceRight;
+  							//if left just add the image width to the X coordinate
+  							if (imagesCSS['float'] === 'left') {
+  								renderer.x += cn.width + additionalSpaceLeft + additionalSpaceRight;
+  							}
+  						} else {
+  							//if no floating is set, move the rendering cursor after the image height
+  							renderer.y += cn.height + additionalSpaceTop + additionalSpaceBottom;
+  						}
+
+  						/*** TABLE RENDERING ***/
+  					} else if (cn.nodeName === "TABLE") {
+  						table2json = tableToJson(cn, renderer);
+  						renderer.y += 10;
+  						renderer.pdf.table(renderer.x, renderer.y, table2json.rows, table2json.headers, {
+  							autoSize: false,
+  							printHeaders: elementHandlers.printHeaders,
+  							margins: renderer.pdf.margins_doc,
+  							css: GetCSS(cn)
+  						});
+  						renderer.y = renderer.pdf.lastCellPos.y + renderer.pdf.lastCellPos.h + 20;
+  					} else if (cn.nodeName === "OL" || cn.nodeName === "UL") {
+  						listCount = 1;
+  						if (!elementHandledElsewhere(cn, renderer, elementHandlers)) {
+  							_DrillForContent(cn, renderer, elementHandlers);
+  						}
+  						renderer.y += 10;
+  					} else if (cn.nodeName === "LI") {
+  						var temp = renderer.x;
+  						renderer.x += 20 / renderer.pdf.internal.scaleFactor;
+  						renderer.y += 3;
+  						if (!elementHandledElsewhere(cn, renderer, elementHandlers)) {
+  							_DrillForContent(cn, renderer, elementHandlers);
+  						}
+  						renderer.x = temp;
+  					} else if (cn.nodeName === "BR") {
+  						renderer.y += fragmentCSS["font-size"] * renderer.pdf.internal.scaleFactor;
+  						renderer.addText("\u2028", clone(fragmentCSS));
+  					} else {
+  						if (!elementHandledElsewhere(cn, renderer, elementHandlers)) {
+  							_DrillForContent(cn, renderer, elementHandlers);
+  						}
+  					}
+  				} else if (cn.nodeType === 3) {
+  					var value = cn.nodeValue;
+  					if (cn.nodeValue && cn.parentNode.nodeName === "LI") {
+  						if (cn.parentNode.parentNode.nodeName === "OL") {
+  							value = listCount++ + '. ' + value;
+  						} else {
+  							var fontSize = fragmentCSS["font-size"];
+  							var offsetX = (3 - fontSize * 0.75) * renderer.pdf.internal.scaleFactor;
+  							var offsetY = fontSize * 0.75 * renderer.pdf.internal.scaleFactor;
+  							var radius = fontSize * 1.74 / renderer.pdf.internal.scaleFactor;
+  							cb = function cb(x, y) {
+  								this.pdf.circle(x + offsetX, y + offsetY, radius, 'FD');
+  							};
+  						}
+  					}
+  					// Only add the text if the text node is in the body element
+  					// Add compatibility with IE11
+  					if (!!(cn.ownerDocument.body.compareDocumentPosition(cn) & 16)) {
+  						renderer.addText(value, fragmentCSS);
+  					}
+  				} else if (typeof cn === "string") {
+  					renderer.addText(cn, fragmentCSS);
+  				}
+  			}
+  			i++;
+  		}
+  		elementHandlers.outY = renderer.y;
+
+  		if (isBlock) {
+  			return renderer.setBlockBoundary(cb);
+  		}
+  	};
+  	images = {};
+  	loadImgs = function loadImgs(element, renderer, elementHandlers, cb) {
+  		var imgs = element.getElementsByTagName('img'),
+  		    l = imgs.length,
+  		    found_images,
+  		    x = 0;
+  		function done() {
+  			renderer.pdf.internal.events.publish('imagesLoaded');
+  			cb(found_images);
+  		}
+  		function loadImage(url, width, height) {
+  			if (!url) return;
+  			var img = new Image();
+  			found_images = ++x;
+  			img.crossOrigin = '';
+  			img.onerror = img.onload = function () {
+  				if (img.complete) {
+  					//to support data urls in images, set width and height
+  					//as those values are not recognized automatically
+  					if (img.src.indexOf('data:image/') === 0) {
+  						img.width = width || img.width || 0;
+  						img.height = height || img.height || 0;
+  					}
+  					//if valid image add to known images array
+  					if (img.width + img.height) {
+  						var hash = renderer.pdf.sHashCode(url) || url;
+  						images[hash] = images[hash] || img;
+  					}
+  				}
+  				if (! --x) {
+  					done();
+  				}
+  			};
+  			img.src = url;
+  		}
+  		while (l--) {
+  			loadImage(imgs[l].getAttribute("src"), imgs[l].width, imgs[l].height);
+  		}return x || done();
+  	};
+  	checkForFooter = function checkForFooter(elem, renderer, elementHandlers) {
+  		//check if we can found a <footer> element
+  		var footer = elem.getElementsByTagName("footer");
+  		if (footer.length > 0) {
+
+  			footer = footer[0];
+
+  			//bad hack to get height of footer
+  			//creat dummy out and check new y after fake rendering
+  			var oldOut = renderer.pdf.internal.write;
+  			var oldY = renderer.y;
+  			renderer.pdf.internal.write = function () {};
+  			_DrillForContent(footer, renderer, elementHandlers);
+  			var footerHeight = Math.ceil(renderer.y - oldY) + 5;
+  			renderer.y = oldY;
+  			renderer.pdf.internal.write = oldOut;
+
+  			//add 20% to prevent overlapping
+  			renderer.pdf.margins_doc.bottom += footerHeight;
+
+  			//Create function render header on every page
+  			var renderFooter = function renderFooter(pageInfo) {
+  				var pageNumber = pageInfo !== undefined ? pageInfo.pageNumber : 1;
+  				//set current y position to old margin
+  				var oldPosition = renderer.y;
+  				//render all child nodes of the header element
+  				renderer.y = renderer.pdf.internal.pageSize.getHeight() - renderer.pdf.margins_doc.bottom;
+  				renderer.pdf.margins_doc.bottom -= footerHeight;
+
+  				//check if we have to add page numbers
+  				var spans = footer.getElementsByTagName('span');
+  				for (var i = 0; i < spans.length; ++i) {
+  					//if we find some span element with class pageCounter, set the page
+  					if ((" " + spans[i].className + " ").replace(/[\n\t]/g, " ").indexOf(" pageCounter ") > -1) {
+  						spans[i].innerHTML = pageNumber;
+  					}
+  					//if we find some span element with class totalPages, set a variable which is replaced after rendering of all pages
+  					if ((" " + spans[i].className + " ").replace(/[\n\t]/g, " ").indexOf(" totalPages ") > -1) {
+  						spans[i].innerHTML = '###jsPDFVarTotalPages###';
+  					}
+  				}
+
+  				//render footer content
+  				_DrillForContent(footer, renderer, elementHandlers);
+  				//set bottom margin to previous height including the footer height
+  				renderer.pdf.margins_doc.bottom += footerHeight;
+  				//important for other plugins (e.g. table) to start rendering at correct position after header
+  				renderer.y = oldPosition;
+  			};
+
+  			//check if footer contains totalPages which should be replace at the disoposal of the document
+  			var spans = footer.getElementsByTagName('span');
+  			for (var i = 0; i < spans.length; ++i) {
+  				if ((" " + spans[i].className + " ").replace(/[\n\t]/g, " ").indexOf(" totalPages ") > -1) {
+  					renderer.pdf.internal.events.subscribe('htmlRenderingFinished', renderer.pdf.putTotalPages.bind(renderer.pdf, '###jsPDFVarTotalPages###'), true);
+  				}
+  			}
+
+  			//register event to render footer on every new page
+  			renderer.pdf.internal.events.subscribe('addPage', renderFooter, false);
+  			//render footer on first page
+  			renderFooter();
+
+  			//prevent footer rendering
+  			SkipNode['FOOTER'] = 1;
+  		}
+  	};
+  	process = function process(pdf, element, x, y, settings, callback) {
+  		if (!element) return false;
+  		if (typeof element !== "string" && !element.parentNode) element = '' + element.innerHTML;
+  		if (typeof element === "string") {
+  			element = function (element) {
+  				var $frame, $hiddendiv, framename, visuallyhidden;
+  				framename = "jsPDFhtmlText" + Date.now().toString() + (Math.random() * 1000).toFixed(0);
+  				visuallyhidden = "position: absolute !important;" + "clip: rect(1px 1px 1px 1px); /* IE6, IE7 */" + "clip: rect(1px, 1px, 1px, 1px);" + "padding:0 !important;" + "border:0 !important;" + "height: 1px !important;" + "width: 1px !important; " + "top:auto;" + "left:-100px;" + "overflow: hidden;";
+  				$hiddendiv = document.createElement('div');
+  				$hiddendiv.style.cssText = visuallyhidden;
+  				$hiddendiv.innerHTML = "<iframe style=\"height:1px;width:1px\" name=\"" + framename + "\" />";
+  				document.body.appendChild($hiddendiv);
+  				$frame = window.frames[framename];
+  				$frame.document.open();
+  				$frame.document.writeln(element);
+  				$frame.document.close();
+  				return $frame.document.body;
+  			}(element.replace(/<\/?script[^>]*?>/gi, ''));
+  		}
+  		var r = new Renderer(pdf, x, y, settings),
+  		    out;
+
+  		// 1. load images
+  		// 2. prepare optional footer elements
+  		// 3. render content
+  		loadImgs.call(this, element, r, settings.elementHandlers, function (found_images) {
+  			checkForFooter(element, r, settings.elementHandlers);
+  			_DrillForContent(element, r, settings.elementHandlers);
+  			//send event dispose for final taks (e.g. footer totalpage replacement)
+  			r.pdf.internal.events.publish('htmlRenderingFinished');
+  			out = r.dispose();
+  			if (typeof callback === 'function') callback(out);else if (found_images) console.error('jsPDF Warning: rendering issues? provide a callback to fromHTML!');
+  		});
+  		return out || { x: r.x, y: r.y };
+  	};
+  	Renderer.prototype.init = function () {
+  		this.paragraph = {
+  			text: [],
+  			style: []
+  		};
+  		return this.pdf.internal.write("q");
+  	};
+  	Renderer.prototype.dispose = function () {
+  		this.pdf.internal.write("Q");
+  		return {
+  			x: this.x,
+  			y: this.y,
+  			ready: true
+  		};
+  	};
+
+  	//Checks if we have to execute some watcher functions
+  	//e.g. to end text floating around an image
+  	Renderer.prototype.executeWatchFunctions = function (el) {
+  		var ret = false;
+  		var narray = [];
+  		if (this.watchFunctions.length > 0) {
+  			for (var i = 0; i < this.watchFunctions.length; ++i) {
+  				if (this.watchFunctions[i](el) === true) {
+  					ret = true;
+  				} else {
+  					narray.push(this.watchFunctions[i]);
+  				}
+  			}
+  			this.watchFunctions = narray;
+  		}
+  		return ret;
+  	};
+
+  	Renderer.prototype.splitFragmentsIntoLines = function (fragments, styles) {
+  		var currentLineLength, defaultFontSize, ff, fontMetrics, fontMetricsCache, fragment, fragmentChopped, fragmentLength, fragmentSpecificMetrics, fs, k, line, lines, maxLineLength, style;
+  		defaultFontSize = 12;
+  		k = this.pdf.internal.scaleFactor;
+  		fontMetricsCache = {};
+  		ff = void 0;
+  		fs = void 0;
+  		fontMetrics = void 0;
+  		fragment = void 0;
+  		style = void 0;
+  		fragmentSpecificMetrics = void 0;
+  		fragmentLength = void 0;
+  		fragmentChopped = void 0;
+  		line = [];
+  		lines = [line];
+  		currentLineLength = 0;
+  		maxLineLength = this.settings.width;
+  		while (fragments.length) {
+  			fragment = fragments.shift();
+  			style = styles.shift();
+  			if (fragment) {
+  				ff = style["font-family"];
+  				fs = style["font-style"];
+  				fontMetrics = fontMetricsCache[ff + fs];
+  				if (!fontMetrics) {
+  					fontMetrics = this.pdf.internal.getFont(ff, fs).metadata.Unicode;
+  					fontMetricsCache[ff + fs] = fontMetrics;
+  				}
+  				fragmentSpecificMetrics = {
+  					widths: fontMetrics.widths,
+  					kerning: fontMetrics.kerning,
+  					fontSize: style["font-size"] * defaultFontSize,
+  					textIndent: currentLineLength
+  				};
+  				fragmentLength = this.pdf.getStringUnitWidth(fragment, fragmentSpecificMetrics) * fragmentSpecificMetrics.fontSize / k;
+  				if (fragment == "\u2028") {
+  					line = [];
+  					lines.push(line);
+  				} else if (currentLineLength + fragmentLength > maxLineLength) {
+  					fragmentChopped = this.pdf.splitTextToSize(fragment, maxLineLength, fragmentSpecificMetrics);
+  					line.push([fragmentChopped.shift(), style]);
+  					while (fragmentChopped.length) {
+  						line = [[fragmentChopped.shift(), style]];
+  						lines.push(line);
+  					}
+  					currentLineLength = this.pdf.getStringUnitWidth(line[0][0], fragmentSpecificMetrics) * fragmentSpecificMetrics.fontSize / k;
+  				} else {
+  					line.push([fragment, style]);
+  					currentLineLength += fragmentLength;
+  				}
+  			}
+  		}
+
+  		//if text alignment was set, set margin/indent of each line
+  		if (style['text-align'] !== undefined && (style['text-align'] === 'center' || style['text-align'] === 'right' || style['text-align'] === 'justify')) {
+  			for (var i = 0; i < lines.length; ++i) {
+  				var length = this.pdf.getStringUnitWidth(lines[i][0][0], fragmentSpecificMetrics) * fragmentSpecificMetrics.fontSize / k;
+  				//if there is more than on line we have to clone the style object as all lines hold a reference on this object
+  				if (i > 0) {
+  					lines[i][0][1] = clone(lines[i][0][1]);
+  				}
+  				var space = maxLineLength - length;
+
+  				if (style['text-align'] === 'right') {
+  					lines[i][0][1]['margin-left'] = space;
+  					//if alignment is not right, it has to be center so split the space to the left and the right
+  				} else if (style['text-align'] === 'center') {
+  					lines[i][0][1]['margin-left'] = space / 2;
+  					//if justify was set, calculate the word spacing and define in by using the css property
+  				} else if (style['text-align'] === 'justify') {
+  					var countSpaces = lines[i][0][0].split(' ').length - 1;
+  					lines[i][0][1]['word-spacing'] = space / countSpaces;
+  					//ignore the last line in justify mode
+  					if (i === lines.length - 1) {
+  						lines[i][0][1]['word-spacing'] = 0;
+  					}
+  				}
+  			}
+  		}
+
+  		return lines;
+  	};
+  	Renderer.prototype.RenderTextFragment = function (text, style) {
+  		var defaultFontSize, font, maxLineHeight;
+
+  		maxLineHeight = 0;
+  		defaultFontSize = 12;
+
+  		if (this.pdf.internal.pageSize.getHeight() - this.pdf.margins_doc.bottom < this.y + this.pdf.internal.getFontSize()) {
+  			this.pdf.internal.write("ET", "Q");
+  			this.pdf.addPage();
+  			this.y = this.pdf.margins_doc.top;
+  			this.pdf.internal.write("q", "BT", this.getPdfColor(style.color), this.pdf.internal.getCoordinateString(this.x), this.pdf.internal.getVerticalCoordinateString(this.y), "Td");
+  			//move cursor by one line on new page
+  			maxLineHeight = Math.max(maxLineHeight, style["line-height"], style["font-size"]);
+  			this.pdf.internal.write(0, (-1 * defaultFontSize * maxLineHeight).toFixed(2), "Td");
+  		}
+
+  		font = this.pdf.internal.getFont(style["font-family"], style["font-style"]);
+
+  		// text color
+  		var pdfTextColor = this.getPdfColor(style["color"]);
+  		if (pdfTextColor !== this.lastTextColor) {
+  			this.pdf.internal.write(pdfTextColor);
+  			this.lastTextColor = pdfTextColor;
+  		}
+
+  		//set the word spacing for e.g. justify style
+  		if (style['word-spacing'] !== undefined && style['word-spacing'] > 0) {
+  			this.pdf.internal.write(style['word-spacing'].toFixed(2), "Tw");
+  		}
+
+  		this.pdf.internal.write("/" + font.id, (defaultFontSize * style["font-size"]).toFixed(2), "Tf", "(" + this.pdf.internal.pdfEscape(text) + ") Tj");
+
+  		//set the word spacing back to neutral => 0
+  		if (style['word-spacing'] !== undefined) {
+  			this.pdf.internal.write(0, "Tw");
+  		}
+  	};
+
+  	// Accepts #FFFFFF, rgb(int,int,int), or CSS Color Name
+  	Renderer.prototype.getPdfColor = function (style) {
+  		var textColor;
+  		var r, g, b;
+
+  		var rx = /rgb\s*\(\s*(\d+),\s*(\d+),\s*(\d+\s*)\)/;
+  		var m = rx.exec(style);
+  		if (m != null) {
+  			r = parseInt(m[1]);
+  			g = parseInt(m[2]);
+  			b = parseInt(m[3]);
+  		} else {
+  			if (style.charAt(0) != '#') {
+  				style = CssColors.colorNameToHex(style);
+  				if (!style) {
+  					style = '#000000';
+  				}
+  			}
+  			r = style.substring(1, 3);
+  			r = parseInt(r, 16);
+  			g = style.substring(3, 5);
+  			g = parseInt(g, 16);
+  			b = style.substring(5, 7);
+  			b = parseInt(b, 16);
+  		}
+
+  		if (typeof r === 'string' && /^#[0-9A-Fa-f]{6}$/.test(r)) {
+  			var hex = parseInt(r.substr(1), 16);
+  			r = hex >> 16 & 255;
+  			g = hex >> 8 & 255;
+  			b = hex & 255;
+  		}
+
+  		var f3 = this.f3;
+  		if (r === 0 && g === 0 && b === 0 || typeof g === 'undefined') {
+  			textColor = f3(r / 255) + ' g';
+  		} else {
+  			textColor = [f3(r / 255), f3(g / 255), f3(b / 255), 'rg'].join(' ');
+  		}
+  		return textColor;
+  	};
+
+  	Renderer.prototype.f3 = function (number) {
+  		return number.toFixed(3); // Ie, %.3f
+  	}, Renderer.prototype.renderParagraph = function (cb) {
+  		var blockstyle, defaultFontSize, fontToUnitRatio, fragments, i, l, line, lines, maxLineHeight, out, paragraphspacing_after, paragraphspacing_before, priorblockstyle, styles, fontSize;
+  		fragments = PurgeWhiteSpace(this.paragraph.text);
+  		styles = this.paragraph.style;
+  		blockstyle = this.paragraph.blockstyle;
+  		priorblockstyle = this.paragraph.priorblockstyle || {};
+  		this.paragraph = {
+  			text: [],
+  			style: [],
+  			blockstyle: {},
+  			priorblockstyle: blockstyle
+  		};
+  		if (!fragments.join("").trim()) {
+  			return;
+  		}
+  		lines = this.splitFragmentsIntoLines(fragments, styles);
+  		line = void 0;
+  		maxLineHeight = void 0;
+  		defaultFontSize = 12;
+  		fontToUnitRatio = defaultFontSize / this.pdf.internal.scaleFactor;
+  		this.priorMarginBottom = this.priorMarginBottom || 0;
+  		paragraphspacing_before = (Math.max((blockstyle["margin-top"] || 0) - this.priorMarginBottom, 0) + (blockstyle["padding-top"] || 0)) * fontToUnitRatio;
+  		paragraphspacing_after = ((blockstyle["margin-bottom"] || 0) + (blockstyle["padding-bottom"] || 0)) * fontToUnitRatio;
+  		this.priorMarginBottom = blockstyle["margin-bottom"] || 0;
+
+  		if (blockstyle['page-break-before'] === 'always') {
+  			this.pdf.addPage();
+  			this.y = 0;
+  			paragraphspacing_before = ((blockstyle["margin-top"] || 0) + (blockstyle["padding-top"] || 0)) * fontToUnitRatio;
+  		}
+
+  		out = this.pdf.internal.write;
+  		i = void 0;
+  		l = void 0;
+  		this.y += paragraphspacing_before;
+  		out("q", "BT 0 g", this.pdf.internal.getCoordinateString(this.x), this.pdf.internal.getVerticalCoordinateString(this.y), "Td");
+
+  		//stores the current indent of cursor position
+  		var currentIndent = 0;
+
+  		while (lines.length) {
+  			line = lines.shift();
+  			maxLineHeight = 0;
+  			i = 0;
+  			l = line.length;
+  			while (i !== l) {
+  				if (line[i][0].trim()) {
+  					maxLineHeight = Math.max(maxLineHeight, line[i][1]["line-height"], line[i][1]["font-size"]);
+  					fontSize = line[i][1]["font-size"] * 7;
+  				}
+  				i++;
+  			}
+  			//if we have to move the cursor to adapt the indent
+  			var indentMove = 0;
+  			var wantedIndent = 0;
+  			//if a margin was added (by e.g. a text-alignment), move the cursor
+  			if (line[0][1]["margin-left"] !== undefined && line[0][1]["margin-left"] > 0) {
+  				wantedIndent = this.pdf.internal.getCoordinateString(line[0][1]["margin-left"]);
+  				indentMove = wantedIndent - currentIndent;
+  				currentIndent = wantedIndent;
+  			}
+  			var indentMore = Math.max(blockstyle["margin-left"] || 0, 0) * fontToUnitRatio;
+  			//move the cursor
+  			out(indentMove + indentMore, (-1 * defaultFontSize * maxLineHeight).toFixed(2), "Td");
+  			i = 0;
+  			l = line.length;
+  			while (i !== l) {
+  				if (line[i][0]) {
+  					this.RenderTextFragment(line[i][0], line[i][1]);
+  				}
+  				i++;
+  			}
+  			this.y += maxLineHeight * fontToUnitRatio;
+
+  			//if some watcher function was executed successful, so e.g. margin and widths were changed,
+  			//reset line drawing and calculate position and lines again
+  			//e.g. to stop text floating around an image
+  			if (this.executeWatchFunctions(line[0][1]) && lines.length > 0) {
+  				var localFragments = [];
+  				var localStyles = [];
+  				//create fragment array of
+  				lines.forEach(function (localLine) {
+  					var i = 0;
+  					var l = localLine.length;
+  					while (i !== l) {
+  						if (localLine[i][0]) {
+  							localFragments.push(localLine[i][0] + ' ');
+  							localStyles.push(localLine[i][1]);
+  						}
+  						++i;
+  					}
+  				});
+  				//split lines again due to possible coordinate changes
+  				lines = this.splitFragmentsIntoLines(PurgeWhiteSpace(localFragments), localStyles);
+  				//reposition the current cursor
+  				out("ET", "Q");
+  				out("q", "BT 0 g", this.pdf.internal.getCoordinateString(this.x), this.pdf.internal.getVerticalCoordinateString(this.y), "Td");
+  			}
+  		}
+  		if (cb && typeof cb === "function") {
+  			cb.call(this, this.x - 9, this.y - fontSize / 2);
+  		}
+  		out("ET", "Q");
+  		return this.y += paragraphspacing_after;
+  	};
+  	Renderer.prototype.setBlockBoundary = function (cb) {
+  		return this.renderParagraph(cb);
+  	};
+  	Renderer.prototype.setBlockStyle = function (css) {
+  		return this.paragraph.blockstyle = css;
+  	};
+  	Renderer.prototype.addText = function (text, css) {
+  		this.paragraph.text.push(text);
+  		return this.paragraph.style.push(css);
+  	};
+  	FontNameDB = {
+  		helvetica: "helvetica",
+  		"sans-serif": "helvetica",
+  		"times new roman": "times",
+  		serif: "times",
+  		times: "times",
+  		monospace: "courier",
+  		courier: "courier"
+  	};
+  	FontWeightMap = {
+  		100: "normal",
+  		200: "normal",
+  		300: "normal",
+  		400: "normal",
+  		500: "bold",
+  		600: "bold",
+  		700: "bold",
+  		800: "bold",
+  		900: "bold",
+  		normal: "normal",
+  		bold: "bold",
+  		bolder: "bold",
+  		lighter: "normal"
+  	};
+  	FontStyleMap = {
+  		normal: "normal",
+  		italic: "italic",
+  		oblique: "italic"
+  	};
+  	TextAlignMap = {
+  		left: "left",
+  		right: "right",
+  		center: "center",
+  		justify: "justify"
+  	};
+  	FloatMap = {
+  		none: 'none',
+  		right: 'right',
+  		left: 'left'
+  	};
+  	ClearMap = {
+  		none: 'none',
+  		both: 'both'
+  	};
+  	UnitedNumberMap = {
+  		normal: 1
+  	};
+  	/**
+    * Converts HTML-formatted text into formatted PDF text.
+    *
+    * Notes:
+    * 2012-07-18
+    * Plugin relies on having browser, DOM around. The HTML is pushed into dom and traversed.
+    * Plugin relies on jQuery for CSS extraction.
+    * Targeting HTML output from Markdown templating, which is a very simple
+    * markup - div, span, em, strong, p. No br-based paragraph separation supported explicitly (but still may work.)
+    * Images, tables are NOT supported.
+    *
+    * @public
+    * @function
+    * @param HTML {String or DOM Element} HTML-formatted text, or pointer to DOM element that is to be rendered into PDF.
+    * @param x {Number} starting X coordinate in jsPDF instance's declared units.
+    * @param y {Number} starting Y coordinate in jsPDF instance's declared units.
+    * @param settings {Object} Additional / optional variables controlling parsing, rendering.
+    * @returns {Object} jsPDF instance
+    */
+  	jsPDFAPI.fromHTML = function (HTML, x, y, settings, callback, margins) {
+
+  		this.margins_doc = margins || {
+  			top: 0,
+  			bottom: 0
+  		};
+  		if (!settings) settings = {};
+  		if (!settings.elementHandlers) settings.elementHandlers = {};
+
+  		return process(this, HTML, isNaN(x) ? 4 : x, isNaN(y) ? 4 : y, settings, callback);
+  	};
+  })(jsPDF.API);
+
+  /** ==================================================================== 
+   * jsPDF JavaScript plugin
+   * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
+   * 
+   * 
+   * ====================================================================
+   */
+
+  /*global jsPDF */
+
+  (function (jsPDFAPI) {
+
+      var jsNamesObj, jsJsObj, text;
+      jsPDFAPI.addJS = function (txt) {
+          text = txt;
+          this.internal.events.subscribe('postPutResources', function (txt) {
+              jsNamesObj = this.internal.newObject();
+              this.internal.out('<<');
+              this.internal.out('/Names [(EmbeddedJS) ' + (jsNamesObj + 1) + ' 0 R]');
+              this.internal.out('>>');
+              this.internal.out('endobj');
+
+              jsJsObj = this.internal.newObject();
+              this.internal.out('<<');
+              this.internal.out('/S /JavaScript');
+              this.internal.out('/JS (' + text + ')');
+              this.internal.out('>>');
+              this.internal.out('endobj');
+          });
+          this.internal.events.subscribe('putCatalog', function () {
+              if (jsNamesObj !== undefined && jsJsObj !== undefined) {
+                  this.internal.out('/Names <</JavaScript ' + jsNamesObj + ' 0 R>>');
+              }
+          });
+          return this;
+      };
+  })(jsPDF.API);
+
+  /**
+   * jsPDF Outline PlugIn
+   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+  (function (jsPDFAPI) {
+
+  	jsPDFAPI.events.push(['postPutResources', function () {
+  		var pdf = this;
+  		var rx = /^(\d+) 0 obj$/;
+
+  		// Write action goto objects for each page
+  		// this.outline.destsGoto = [];
+  		// for (var i = 0; i < totalPages; i++) {
+  		// var id = pdf.internal.newObject();
+  		// this.outline.destsGoto.push(id);
+  		// pdf.internal.write("<</D[" + (i * 2 + 3) + " 0 R /XYZ null
+  		// null null]/S/GoTo>> endobj");
+  		// }
+  		//
+  		// for (var i = 0; i < dests.length; i++) {
+  		// pdf.internal.write("(page_" + (i + 1) + ")" + dests[i] + " 0
+  		// R");
+  		// }
+  		//				
+  		if (this.outline.root.children.length > 0) {
+  			var lines = pdf.outline.render().split(/\r\n/);
+  			for (var i = 0; i < lines.length; i++) {
+  				var line = lines[i];
+  				var m = rx.exec(line);
+  				if (m != null) {
+  					var oid = m[1];
+  					pdf.internal.newObjectDeferredBegin(oid);
+  				}
+  				pdf.internal.write(line);
+  			}
+  		}
+
+  		// This code will write named destination for each page reference
+  		// (page_1, etc)
+  		if (this.outline.createNamedDestinations) {
+  			var totalPages = this.internal.pages.length;
+  			// WARNING: this assumes jsPDF starts on page 3 and pageIDs
+  			// follow 5, 7, 9, etc
+  			// Write destination objects for each page
+  			var dests = [];
+  			for (var i = 0; i < totalPages; i++) {
+  				var id = pdf.internal.newObject();
+  				dests.push(id);
+  				var info = pdf.internal.getPageInfo(i + 1);
+  				pdf.internal.write("<< /D[" + info.objId + " 0 R /XYZ null null null]>> endobj");
+  			}
+
+  			// assign a name for each destination
+  			var names2Oid = pdf.internal.newObject();
+  			pdf.internal.write('<< /Names [ ');
+  			for (var i = 0; i < dests.length; i++) {
+  				pdf.internal.write("(page_" + (i + 1) + ")" + dests[i] + " 0 R");
+  			}
+  			pdf.internal.write(' ] >>', 'endobj');
+
+  			// var kids = pdf.internal.newObject();
+  			// pdf.internal.write('<< /Kids [ ' + names2Oid + ' 0 R');
+  			// pdf.internal.write(' ] >>', 'endobj');
+
+  			var namesOid = pdf.internal.newObject();
+  			pdf.internal.write('<< /Dests ' + names2Oid + " 0 R");
+  			pdf.internal.write('>>', 'endobj');
+  		}
+  	}]);
+
+  	jsPDFAPI.events.push(['putCatalog', function () {
+  		var pdf = this;
+  		if (pdf.outline.root.children.length > 0) {
+  			pdf.internal.write("/Outlines", this.outline.makeRef(this.outline.root));
+  			if (this.outline.createNamedDestinations) {
+  				pdf.internal.write("/Names " + namesOid + " 0 R");
+  			}
+  			// Open with Bookmarks showing
+  			// pdf.internal.write("/PageMode /UseOutlines");
+  		}
+  	}]);
+
+  	jsPDFAPI.events.push(['initialized', function () {
+  		var pdf = this;
+
+  		pdf.outline = {
+  			createNamedDestinations: false,
+  			root: {
+  				children: []
+  			}
+  		};
+
+  		/**
+     * Options: pageNumber
+     */
+  		pdf.outline.add = function (parent, title, options) {
+  			var item = {
+  				title: title,
+  				options: options,
+  				children: []
+  			};
+  			if (parent == null) {
+  				parent = this.root;
+  			}
+  			parent.children.push(item);
+  			return item;
+  		};
+
+  		pdf.outline.render = function () {
+  			this.ctx = {};
+  			this.ctx.val = '';
+  			this.ctx.pdf = pdf;
+
+  			this.genIds_r(this.root);
+  			this.renderRoot(this.root);
+  			this.renderItems(this.root);
+
+  			return this.ctx.val;
+  		};
+
+  		pdf.outline.genIds_r = function (node) {
+  			node.id = pdf.internal.newObjectDeferred();
+  			for (var i = 0; i < node.children.length; i++) {
+  				this.genIds_r(node.children[i]);
+  			}
+  		};
+
+  		pdf.outline.renderRoot = function (node) {
+  			this.objStart(node);
+  			this.line('/Type /Outlines');
+  			if (node.children.length > 0) {
+  				this.line('/First ' + this.makeRef(node.children[0]));
+  				this.line('/Last ' + this.makeRef(node.children[node.children.length - 1]));
+  			}
+  			this.line('/Count ' + this.count_r({
+  				count: 0
+  			}, node));
+  			this.objEnd();
+  		};
+
+  		pdf.outline.renderItems = function (node) {
+  			for (var i = 0; i < node.children.length; i++) {
+  				var item = node.children[i];
+  				this.objStart(item);
+
+  				this.line('/Title ' + this.makeString(item.title));
+
+  				this.line('/Parent ' + this.makeRef(node));
+  				if (i > 0) {
+  					this.line('/Prev ' + this.makeRef(node.children[i - 1]));
+  				}
+  				if (i < node.children.length - 1) {
+  					this.line('/Next ' + this.makeRef(node.children[i + 1]));
+  				}
+  				if (item.children.length > 0) {
+  					this.line('/First ' + this.makeRef(item.children[0]));
+  					this.line('/Last ' + this.makeRef(item.children[item.children.length - 1]));
+  				}
+
+  				var count = this.count = this.count_r({
+  					count: 0
+  				}, item);
+  				if (count > 0) {
+  					this.line('/Count ' + count);
+  				}
+
+  				if (item.options) {
+  					if (item.options.pageNumber) {
+  						// Explicit Destination
+  						//WARNING this assumes page ids are 3,5,7, etc.
+  						var info = pdf.internal.getPageInfo(item.options.pageNumber);
+  						this.line('/Dest ' + '[' + info.objId + ' 0 R /XYZ 0 ' + this.ctx.pdf.internal.pageSize.getHeight() * this.ctx.pdf.internal.scaleFactor + ' 0]');
+  						// this line does not work on all clients (pageNumber instead of page ref)
+  						//this.line('/Dest ' + '[' + (item.options.pageNumber - 1) + ' /XYZ 0 ' + this.ctx.pdf.internal.pageSize.getHeight() + ' 0]');
+
+  						// Named Destination
+  						// this.line('/Dest (page_' + (item.options.pageNumber) + ')');
+
+  						// Action Destination
+  						// var id = pdf.internal.newObject();
+  						// pdf.internal.write('<</D[' + (item.options.pageNumber - 1) + ' /XYZ null null null]/S/GoTo>> endobj');
+  						// this.line('/A ' + id + ' 0 R' );
+  					}
+  				}
+  				this.objEnd();
+  			}
+  			for (var i = 0; i < node.children.length; i++) {
+  				var item = node.children[i];
+  				this.renderItems(item);
+  			}
+  		};
+
+  		pdf.outline.line = function (text) {
+  			this.ctx.val += text + '\r\n';
+  		};
+
+  		pdf.outline.makeRef = function (node) {
+  			return node.id + ' 0 R';
+  		};
+
+  		pdf.outline.makeString = function (val) {
+  			return '(' + pdf.internal.pdfEscape(val) + ')';
+  		};
+
+  		pdf.outline.objStart = function (node) {
+  			this.ctx.val += '\r\n' + node.id + ' 0 obj' + '\r\n<<\r\n';
+  		};
+
+  		pdf.outline.objEnd = function (node) {
+  			this.ctx.val += '>> \r\n' + 'endobj' + '\r\n';
+  		};
+
+  		pdf.outline.count_r = function (ctx, node) {
+  			for (var i = 0; i < node.children.length; i++) {
+  				ctx.count++;
+  				this.count_r(ctx, node.children[i]);
+  			}
+  			return ctx.count;
+  		};
+  	}]);
+
+  	return this;
+  })(jsPDF.API);
+
+  /**@preserve
+   *  ====================================================================
+   * jsPDF PNG PlugIn
+   * Copyright (c) 2014 James Robb, https://github.com/jamesbrobb
+   *
+   * 
+   * ====================================================================
+   */
+
+  (function (jsPDFAPI) {
+
+  	/*
+    * @see http://www.w3.org/TR/PNG-Chunks.html
+    *
+    Color    Allowed      Interpretation
+    Type     Bit Depths
+   	   0       1,2,4,8,16  Each pixel is a grayscale sample.
+   	   2       8,16        Each pixel is an R,G,B triple.
+   	   3       1,2,4,8     Each pixel is a palette index;
+                          a PLTE chunk must appear.
+   	   4       8,16        Each pixel is a grayscale sample,
+                          followed by an alpha sample.
+   	   6       8,16        Each pixel is an R,G,B triple,
+                          followed by an alpha sample.
+   */
+
+  	/*
+    * PNG filter method types
+    *
+    * @see http://www.w3.org/TR/PNG-Filters.html
+    * @see http://www.libpng.org/pub/png/book/chapter09.html
+    *
+    * This is what the value 'Predictor' in decode params relates to
+    *
+    * 15 is "optimal prediction", which means the prediction algorithm can change from line to line.
+    * In that case, you actually have to read the first byte off each line for the prediction algorthim (which should be 0-4, corresponding to PDF 10-14) and select the appropriate unprediction algorithm based on that byte.
+    *
+      0       None
+      1       Sub
+      2       Up
+      3       Average
+      4       Paeth
+    */
+
+  	var doesNotHavePngJS = function doesNotHavePngJS() {
+  		return typeof PNG !== 'function' || typeof FlateStream !== 'function';
+  	},
+  	    canCompress = function canCompress(value) {
+  		return value !== jsPDFAPI.image_compression.NONE && hasCompressionJS();
+  	},
+  	    hasCompressionJS = function hasCompressionJS() {
+  		var inst = typeof Deflater === 'function';
+  		if (!inst) throw new Error("requires deflate.js for compression");
+  		return inst;
+  	},
+  	    compressBytes = function compressBytes(bytes, lineLength, colorsPerPixel, compression) {
+
+  		var level = 5,
+  		    filter_method = filterUp;
+
+  		switch (compression) {
+
+  			case jsPDFAPI.image_compression.FAST:
+
+  				level = 3;
+  				filter_method = filterSub;
+  				break;
+
+  			case jsPDFAPI.image_compression.MEDIUM:
+
+  				level = 6;
+  				filter_method = filterAverage;
+  				break;
+
+  			case jsPDFAPI.image_compression.SLOW:
+
+  				level = 9;
+  				filter_method = filterPaeth; //uses to sum to choose best filter for each line
+  				break;
+  		}
+
+  		bytes = applyPngFilterMethod(bytes, lineLength, colorsPerPixel, filter_method);
+
+  		var header = new Uint8Array(createZlibHeader(level));
+  		var checksum = adler32(bytes);
+
+  		var deflate = new Deflater(level);
+  		var a = deflate.append(bytes);
+  		var cBytes = deflate.flush();
+
+  		var len = header.length + a.length + cBytes.length;
+
+  		var cmpd = new Uint8Array(len + 4);
+  		cmpd.set(header);
+  		cmpd.set(a, header.length);
+  		cmpd.set(cBytes, header.length + a.length);
+
+  		cmpd[len++] = checksum >>> 24 & 0xff;
+  		cmpd[len++] = checksum >>> 16 & 0xff;
+  		cmpd[len++] = checksum >>> 8 & 0xff;
+  		cmpd[len++] = checksum & 0xff;
+
+  		return jsPDFAPI.arrayBufferToBinaryString(cmpd);
+  	},
+  	    createZlibHeader = function createZlibHeader(bytes, level) {
+  		/*
+     * @see http://www.ietf.org/rfc/rfc1950.txt for zlib header
+     */
+  		var cm = 8;
+  		var cinfo = Math.LOG2E * Math.log(0x8000) - 8;
+  		var cmf = cinfo << 4 | cm;
+
+  		var hdr = cmf << 8;
+  		var flevel = Math.min(3, (level - 1 & 0xff) >> 1);
+
+  		hdr |= flevel << 6;
+  		hdr |= 0; //FDICT
+  		hdr += 31 - hdr % 31;
+
+  		return [cmf, hdr & 0xff & 0xff];
+  	},
+  	    adler32 = function adler32(array, param) {
+  		var adler = 1;
+  		var s1 = adler & 0xffff,
+  		    s2 = adler >>> 16 & 0xffff;
+  		var len = array.length;
+  		var tlen;
+  		var i = 0;
+
+  		while (len > 0) {
+  			tlen = len > param ? param : len;
+  			len -= tlen;
+  			do {
+  				s1 += array[i++];
+  				s2 += s1;
+  			} while (--tlen);
+
+  			s1 %= 65521;
+  			s2 %= 65521;
+  		}
+
+  		return (s2 << 16 | s1) >>> 0;
+  	},
+  	    applyPngFilterMethod = function applyPngFilterMethod(bytes, lineLength, colorsPerPixel, filter_method) {
+  		var lines = bytes.length / lineLength,
+  		    result = new Uint8Array(bytes.length + lines),
+  		    filter_methods = getFilterMethods(),
+  		    i = 0,
+  		    line,
+  		    prevLine,
+  		    offset;
+
+  		for (; i < lines; i++) {
+  			offset = i * lineLength;
+  			line = bytes.subarray(offset, offset + lineLength);
+
+  			if (filter_method) {
+  				result.set(filter_method(line, colorsPerPixel, prevLine), offset + i);
+  			} else {
+
+  				var j = 0,
+  				    len = filter_methods.length,
+  				    results = [];
+
+  				for (; j < len; j++) {
+  					results[j] = filter_methods[j](line, colorsPerPixel, prevLine);
+  				}var ind = getIndexOfSmallestSum(results.concat());
+
+  				result.set(results[ind], offset + i);
+  			}
+
+  			prevLine = line;
+  		}
+
+  		return result;
+  	},
+  	    filterNone = function filterNone(line, colorsPerPixel, prevLine) {
+  		/*var result = new Uint8Array(line.length + 1);
+    result[0] = 0;
+    result.set(line, 1);*/
+
+  		var result = Array.apply([], line);
+  		result.unshift(0);
+
+  		return result;
+  	},
+  	    filterSub = function filterSub(line, colorsPerPixel, prevLine) {
+  		var result = [],
+  		    i = 0,
+  		    len = line.length,
+  		    left;
+
+  		result[0] = 1;
+
+  		for (; i < len; i++) {
+  			left = line[i - colorsPerPixel] || 0;
+  			result[i + 1] = line[i] - left + 0x0100 & 0xff;
+  		}
+
+  		return result;
+  	},
+  	    filterUp = function filterUp(line, colorsPerPixel, prevLine) {
+  		var result = [],
+  		    i = 0,
+  		    len = line.length,
+  		    up;
+
+  		result[0] = 2;
+
+  		for (; i < len; i++) {
+  			up = prevLine && prevLine[i] || 0;
+  			result[i + 1] = line[i] - up + 0x0100 & 0xff;
+  		}
+
+  		return result;
+  	},
+  	    filterAverage = function filterAverage(line, colorsPerPixel, prevLine) {
+  		var result = [],
+  		    i = 0,
+  		    len = line.length,
+  		    left,
+  		    up;
+
+  		result[0] = 3;
+
+  		for (; i < len; i++) {
+  			left = line[i - colorsPerPixel] || 0;
+  			up = prevLine && prevLine[i] || 0;
+  			result[i + 1] = line[i] + 0x0100 - (left + up >>> 1) & 0xff;
+  		}
+
+  		return result;
+  	},
+  	    filterPaeth = function filterPaeth(line, colorsPerPixel, prevLine) {
+  		var result = [],
+  		    i = 0,
+  		    len = line.length,
+  		    left,
+  		    up,
+  		    upLeft,
+  		    paeth;
+
+  		result[0] = 4;
+
+  		for (; i < len; i++) {
+  			left = line[i - colorsPerPixel] || 0;
+  			up = prevLine && prevLine[i] || 0;
+  			upLeft = prevLine && prevLine[i - colorsPerPixel] || 0;
+  			paeth = paethPredictor(left, up, upLeft);
+  			result[i + 1] = line[i] - paeth + 0x0100 & 0xff;
+  		}
+
+  		return result;
+  	},
+  	    paethPredictor = function paethPredictor(left, up, upLeft) {
+
+  		var p = left + up - upLeft,
+  		    pLeft = Math.abs(p - left),
+  		    pUp = Math.abs(p - up),
+  		    pUpLeft = Math.abs(p - upLeft);
+
+  		return pLeft <= pUp && pLeft <= pUpLeft ? left : pUp <= pUpLeft ? up : upLeft;
+  	},
+  	    getFilterMethods = function getFilterMethods() {
+  		return [filterNone, filterSub, filterUp, filterAverage, filterPaeth];
+  	},
+  	    getIndexOfSmallestSum = function getIndexOfSmallestSum(arrays) {
+  		var i = 0,
+  		    len = arrays.length,
+  		    sum,
+  		    min,
+  		    ind;
+
+  		while (i < len) {
+  			sum = absSum(arrays[i].slice(1));
+
+  			if (sum < min || !min) {
+  				min = sum;
+  				ind = i;
+  			}
+
+  			i++;
+  		}
+
+  		return ind;
+  	},
+  	    absSum = function absSum(array) {
+  		var i = 0,
+  		    len = array.length,
+  		    sum = 0;
+
+  		while (i < len) {
+  			sum += Math.abs(array[i++]);
+  		}return sum;
+  	},
+  	    getPredictorFromCompression = function getPredictorFromCompression(compression) {
+  		var predictor;
+  		switch (compression) {
+  			case jsPDFAPI.image_compression.FAST:
+  				predictor = 11;
+  				break;
+
+  			case jsPDFAPI.image_compression.MEDIUM:
+  				predictor = 13;
+  				break;
+
+  			case jsPDFAPI.image_compression.SLOW:
+  				predictor = 14;
+  				break;
+
+  			default:
+  				predictor = 12;
+  				break;
+  		}
+  		return predictor;
+  	};
+
+  	jsPDFAPI.processPNG = function (imageData, imageIndex, alias, compression, dataAsBinaryString) {
+
+  		var colorSpace = this.color_spaces.DEVICE_RGB,
+  		    decode = this.decode.FLATE_DECODE,
+  		    bpc = 8,
+  		    img,
+  		    dp,
+  		    trns,
+  		    colors,
+  		    pal,
+  		    smask;
+
+  		/*	if(this.isString(imageData)) {
+    		}*/
+
+  		if (this.isArrayBuffer(imageData)) imageData = new Uint8Array(imageData);
+
+  		if (this.isArrayBufferView(imageData)) {
+
+  			if (doesNotHavePngJS()) throw new Error("PNG support requires png.js and zlib.js");
+
+  			img = new PNG(imageData);
+  			imageData = img.imgData;
+  			bpc = img.bits;
+  			colorSpace = img.colorSpace;
+  			colors = img.colors;
+
+  			//logImg(img);
+
+  			/*
+      * colorType 6 - Each pixel is an R,G,B triple, followed by an alpha sample.
+      *
+      * colorType 4 - Each pixel is a grayscale sample, followed by an alpha sample.
+      *
+      * Extract alpha to create two separate images, using the alpha as a sMask
+      */
+  			if ([4, 6].indexOf(img.colorType) !== -1) {
+
+  				/*
+       * processes 8 bit RGBA and grayscale + alpha images
+       */
+  				if (img.bits === 8) {
+
+  					var pixels = img.pixelBitlength == 32 ? new Uint32Array(img.decodePixels().buffer) : img.pixelBitlength == 16 ? new Uint16Array(img.decodePixels().buffer) : new Uint8Array(img.decodePixels().buffer),
+  					    len = pixels.length,
+  					    imgData = new Uint8Array(len * img.colors),
+  					    alphaData = new Uint8Array(len),
+  					    pDiff = img.pixelBitlength - img.bits,
+  					    i = 0,
+  					    n = 0,
+  					    pixel,
+  					    pbl;
+
+  					for (; i < len; i++) {
+  						pixel = pixels[i];
+  						pbl = 0;
+
+  						while (pbl < pDiff) {
+
+  							imgData[n++] = pixel >>> pbl & 0xff;
+  							pbl = pbl + img.bits;
+  						}
+
+  						alphaData[i] = pixel >>> pbl & 0xff;
+  					}
+  				}
+
+  				/*
+       * processes 16 bit RGBA and grayscale + alpha images
+       */
+  				if (img.bits === 16) {
+
+  					var pixels = new Uint32Array(img.decodePixels().buffer),
+  					    len = pixels.length,
+  					    imgData = new Uint8Array(len * (32 / img.pixelBitlength) * img.colors),
+  					    alphaData = new Uint8Array(len * (32 / img.pixelBitlength)),
+  					    hasColors = img.colors > 1,
+  					    i = 0,
+  					    n = 0,
+  					    a = 0,
+  					    pixel;
+
+  					while (i < len) {
+  						pixel = pixels[i++];
+
+  						imgData[n++] = pixel >>> 0 & 0xFF;
+
+  						if (hasColors) {
+  							imgData[n++] = pixel >>> 16 & 0xFF;
+
+  							pixel = pixels[i++];
+  							imgData[n++] = pixel >>> 0 & 0xFF;
+  						}
+
+  						alphaData[a++] = pixel >>> 16 & 0xFF;
+  					}
+
+  					bpc = 8;
+  				}
+
+  				if (canCompress(compression)) {
+
+  					imageData = compressBytes(imgData, img.width * img.colors, img.colors, compression);
+  					smask = compressBytes(alphaData, img.width, 1, compression);
+  				} else {
+
+  					imageData = imgData;
+  					smask = alphaData;
+  					decode = null;
+  				}
+  			}
+
+  			/*
+      * Indexed png. Each pixel is a palette index.
+      */
+  			if (img.colorType === 3) {
+
+  				colorSpace = this.color_spaces.INDEXED;
+  				pal = img.palette;
+
+  				if (img.transparency.indexed) {
+
+  					var trans = img.transparency.indexed;
+
+  					var total = 0,
+  					    i = 0,
+  					    len = trans.length;
+
+  					for (; i < len; ++i) {
+  						total += trans[i];
+  					}total = total / 255;
+
+  					/*
+        * a single color is specified as 100% transparent (0),
+        * so we set trns to use a /Mask with that index
+        */
+  					if (total === len - 1 && trans.indexOf(0) !== -1) {
+  						trns = [trans.indexOf(0)];
+
+  						/*
+         * there's more than one colour within the palette that specifies
+         * a transparency value less than 255, so we unroll the pixels to create an image sMask
+         */
+  					} else if (total !== len) {
+
+  						var pixels = img.decodePixels(),
+  						    alphaData = new Uint8Array(pixels.length),
+  						    i = 0,
+  						    len = pixels.length;
+
+  						for (; i < len; i++) {
+  							alphaData[i] = trans[pixels[i]];
+  						}smask = compressBytes(alphaData, img.width, 1);
+  					}
+  				}
+  			}
+
+  			var predictor = getPredictorFromCompression(compression);
+
+  			if (decode === this.decode.FLATE_DECODE) dp = '/Predictor ' + predictor + ' /Colors ' + colors + ' /BitsPerComponent ' + bpc + ' /Columns ' + img.width;else
+  				//remove 'Predictor' as it applies to the type of png filter applied to its IDAT - we only apply with compression
+  				dp = '/Colors ' + colors + ' /BitsPerComponent ' + bpc + ' /Columns ' + img.width;
+
+  			if (this.isArrayBuffer(imageData) || this.isArrayBufferView(imageData)) imageData = this.arrayBufferToBinaryString(imageData);
+
+  			if (smask && this.isArrayBuffer(smask) || this.isArrayBufferView(smask)) smask = this.arrayBufferToBinaryString(smask);
+
+  			return this.createImageInfo(imageData, img.width, img.height, colorSpace, bpc, decode, imageIndex, alias, dp, trns, pal, smask, predictor);
+  		}
+
+  		throw new Error("Unsupported PNG image data, try using JPEG instead.");
+  	};
+  })(jsPDF.API);
+
+  /**
+   * jsPDF setLanguage Plugin
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+
+  (function (jsPDFAPI) {
+
+      /**
+      * Add Language Tag to PDF
+      *
+      * @returns {jsPDF}
+      * @name setLanguage
+      * @example
+      * var doc = new jsPDF()
+      * doc.text(10, 10, 'This is a test')
+      * doc.setLanguage("en-US")
+      * doc.save('english.pdf')
+      */
+
+      jsPDFAPI.setLanguage = function (langCode) {
+
+          var langCodes = {
+              "af": "Afrikaans",
+              "sq": "Albanian",
+              "ar": "Arabic (Standard)",
+              "ar-DZ": "Arabic (Algeria)",
+              "ar-BH": "Arabic (Bahrain)",
+              "ar-EG": "Arabic (Egypt)",
+              "ar-IQ": "Arabic (Iraq)",
+              "ar-JO": "Arabic (Jordan)",
+              "ar-KW": "Arabic (Kuwait)",
+              "ar-LB": "Arabic (Lebanon)",
+              "ar-LY": "Arabic (Libya)",
+              "ar-MA": "Arabic (Morocco)",
+              "ar-OM": "Arabic (Oman)",
+              "ar-QA": "Arabic (Qatar)",
+              "ar-SA": "Arabic (Saudi Arabia)",
+              "ar-SY": "Arabic (Syria)",
+              "ar-TN": "Arabic (Tunisia)",
+              "ar-AE": "Arabic (U.A.E.)",
+              "ar-YE": "Arabic (Yemen)",
+              "an": "Aragonese",
+              "hy": "Armenian",
+              "as": "Assamese",
+              "ast": "Asturian",
+              "az": "Azerbaijani",
+              "eu": "Basque",
+              "be": "Belarusian",
+              "bn": "Bengali",
+              "bs": "Bosnian",
+              "br": "Breton",
+              "bg": "Bulgarian",
+              "my": "Burmese",
+              "ca": "Catalan",
+              "ch": "Chamorro",
+              "ce": "Chechen",
+              "zh": "Chinese",
+              "zh-HK": "Chinese (Hong Kong)",
+              "zh-CN": "Chinese (PRC)",
+              "zh-SG": "Chinese (Singapore)",
+              "zh-TW": "Chinese (Taiwan)",
+              "cv": "Chuvash",
+              "co": "Corsican",
+              "cr": "Cree",
+              "hr": "Croatian",
+              "cs": "Czech",
+              "da": "Danish",
+              "nl": "Dutch (Standard)",
+              "nl-BE": "Dutch (Belgian)",
+              "en": "English",
+              "en-AU": "English (Australia)",
+              "en-BZ": "English (Belize)",
+              "en-CA": "English (Canada)",
+              "en-IE": "English (Ireland)",
+              "en-JM": "English (Jamaica)",
+              "en-NZ": "English (New Zealand)",
+              "en-PH": "English (Philippines)",
+              "en-ZA": "English (South Africa)",
+              "en-TT": "English (Trinidad & Tobago)",
+              "en-GB": "English (United Kingdom)",
+              "en-US": "English (United States)",
+              "en-ZW": "English (Zimbabwe)",
+              "eo": "Esperanto",
+              "et": "Estonian",
+              "fo": "Faeroese",
+              "fj": "Fijian",
+              "fi": "Finnish",
+              "fr": "French (Standard)",
+              "fr-BE": "French (Belgium)",
+              "fr-CA": "French (Canada)",
+              "fr-FR": "French (France)",
+              "fr-LU": "French (Luxembourg)",
+              "fr-MC": "French (Monaco)",
+              "fr-CH": "French (Switzerland)",
+              "fy": "Frisian",
+              "fur": "Friulian",
+              "gd": "Gaelic (Scots)",
+              "gd-IE": "Gaelic (Irish)",
+              "gl": "Galacian",
+              "ka": "Georgian",
+              "de": "German (Standard)",
+              "de-AT": "German (Austria)",
+              "de-DE": "German (Germany)",
+              "de-LI": "German (Liechtenstein)",
+              "de-LU": "German (Luxembourg)",
+              "de-CH": "German (Switzerland)",
+              "el": "Greek",
+              "gu": "Gujurati",
+              "ht": "Haitian",
+              "he": "Hebrew",
+              "hi": "Hindi",
+              "hu": "Hungarian",
+              "is": "Icelandic",
+              "id": "Indonesian",
+              "iu": "Inuktitut",
+              "ga": "Irish",
+              "it": "Italian (Standard)",
+              "it-CH": "Italian (Switzerland)",
+              "ja": "Japanese",
+              "kn": "Kannada",
+              "ks": "Kashmiri",
+              "kk": "Kazakh",
+              "km": "Khmer",
+              "ky": "Kirghiz",
+              "tlh": "Klingon",
+              "ko": "Korean",
+              "ko-KP": "Korean (North Korea)",
+              "ko-KR": "Korean (South Korea)",
+              "la": "Latin",
+              "lv": "Latvian",
+              "lt": "Lithuanian",
+              "lb": "Luxembourgish",
+              "mk": "FYRO Macedonian",
+              "ms": "Malay",
+              "ml": "Malayalam",
+              "mt": "Maltese",
+              "mi": "Maori",
+              "mr": "Marathi",
+              "mo": "Moldavian",
+              "nv": "Navajo",
+              "ng": "Ndonga",
+              "ne": "Nepali",
+              "no": "Norwegian",
+              "nb": "Norwegian (Bokmal)",
+              "nn": "Norwegian (Nynorsk)",
+              "oc": "Occitan",
+              "or": "Oriya",
+              "om": "Oromo",
+              "fa": "Persian",
+              "fa-IR": "Persian/Iran",
+              "pl": "Polish",
+              "pt": "Portuguese",
+              "pt-BR": "Portuguese (Brazil)",
+              "pa": "Punjabi",
+              "pa-IN": "Punjabi (India)",
+              "pa-PK": "Punjabi (Pakistan)",
+              "qu": "Quechua",
+              "rm": "Rhaeto-Romanic",
+              "ro": "Romanian",
+              "ro-MO": "Romanian (Moldavia)",
+              "ru": "Russian",
+              "ru-MO": "Russian (Moldavia)",
+              "sz": "Sami (Lappish)",
+              "sg": "Sango",
+              "sa": "Sanskrit",
+              "sc": "Sardinian",
+              "sd": "Sindhi",
+              "si": "Singhalese",
+              "sr": "Serbian",
+              "sk": "Slovak",
+              "sl": "Slovenian",
+              "so": "Somani",
+              "sb": "Sorbian",
+              "es": "Spanish",
+              "es-AR": "Spanish (Argentina)",
+              "es-BO": "Spanish (Bolivia)",
+              "es-CL": "Spanish (Chile)",
+              "es-CO": "Spanish (Colombia)",
+              "es-CR": "Spanish (Costa Rica)",
+              "es-DO": "Spanish (Dominican Republic)",
+              "es-EC": "Spanish (Ecuador)",
+              "es-SV": "Spanish (El Salvador)",
+              "es-GT": "Spanish (Guatemala)",
+              "es-HN": "Spanish (Honduras)",
+              "es-MX": "Spanish (Mexico)",
+              "es-NI": "Spanish (Nicaragua)",
+              "es-PA": "Spanish (Panama)",
+              "es-PY": "Spanish (Paraguay)",
+              "es-PE": "Spanish (Peru)",
+              "es-PR": "Spanish (Puerto Rico)",
+              "es-ES": "Spanish (Spain)",
+              "es-UY": "Spanish (Uruguay)",
+              "es-VE": "Spanish (Venezuela)",
+              "sx": "Sutu",
+              "sw": "Swahili",
+              "sv": "Swedish",
+              "sv-FI": "Swedish (Finland)",
+              "sv-SV": "Swedish (Sweden)",
+              "ta": "Tamil",
+              "tt": "Tatar",
+              "te": "Teluga",
+              "th": "Thai",
+              "tig": "Tigre",
+              "ts": "Tsonga",
+              "tn": "Tswana",
+              "tr": "Turkish",
+              "tk": "Turkmen",
+              "uk": "Ukrainian",
+              "hsb": "Upper Sorbian",
+              "ur": "Urdu",
+              "ve": "Venda",
+              "vi": "Vietnamese",
+              "vo": "Volapuk",
+              "wa": "Walloon",
+              "cy": "Welsh",
+              "xh": "Xhosa",
+              "ji": "Yiddish",
+              "zu": "Zulu"
+          };
+
+          if (this.internal.languageSettings === undefined) {
+              this.internal.languageSettings = {};
+              this.internal.languageSettings.isSubscribed = false;
+          }
+
+          if (langCodes[langCode] !== undefined) {
+              this.internal.languageSettings.languageCode = langCode;
+              if (this.internal.languageSettings.isSubscribed === false) {
+                  this.internal.events.subscribe("putCatalog", function () {
+                      this.internal.write("/Lang (" + this.internal.languageSettings.languageCode + ")");
+                  });
+                  this.internal.languageSettings.isSubscribed = true;
+              }
+          }
+          return this;
+      };
+  })(jsPDF.API);
+
+  /** @preserve
+   * jsPDF split_text_to_size plugin - MIT license.
+   * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
+   *               2014 Diego Casorran, https://github.com/diegocr
+   */
+  (function (API) {
+  	/**
+    * Returns an array of length matching length of the 'word' string, with each
+    * cell occupied by the width of the char in that position.
+    * 
+    * @function
+    * @param word {String}
+    * @param widths {Object}
+    * @param kerning {Object}
+    * @returns {Array}
+    */
+
+  	var getCharWidthsArray = API.getCharWidthsArray = function (text, options) {
+
+  		if (!options) {
+  			options = {};
+  		}
+
+  		var l = text.length;
+  		var output = [];
+  		var i;
+
+  		if (!!options.font) {
+  			var fontSize = options.fontSize;
+  			var charSpace = options.charSpace;
+  			for (i = 0; i < l; i++) {
+  				output.push(options.font.widthOfString(text[i], fontSize, charSpace) / fontSize);
+  			}
+  			return output;
+  		}
+
+  		var widths = options.widths ? options.widths : this.internal.getFont().metadata.Unicode.widths,
+  		    widthsFractionOf = widths.fof ? widths.fof : 1,
+  		    kerning = options.kerning ? options.kerning : this.internal.getFont().metadata.Unicode.kerning,
+  		    kerningFractionOf = kerning.fof ? kerning.fof : 1;
+
+  		// console.log("widths, kergnings", widths, kerning)
+
+  		var char_code = 0;
+  		var prior_char_code = 0; // for kerning
+  		var default_char_width = widths[0] || widthsFractionOf;
+
+  		for (i = 0, l = text.length; i < l; i++) {
+  			char_code = text.charCodeAt(i);
+  			output.push((widths[char_code] || default_char_width) / widthsFractionOf + (kerning[char_code] && kerning[char_code][prior_char_code] || 0) / kerningFractionOf);
+  			prior_char_code = char_code;
+  		}
+
+  		return output;
+  	};
+  	var getArraySum = function getArraySum(array) {
+  		var i = array.length,
+  		    output = 0;
+  		while (i) {
+  			i--;
+  			output += array[i];
+  		}
+  		return output;
+  	};
+  	/**
+   Returns a widths of string in a given font, if the font size is set as 1 point.
+   	In other words, this is "proportional" value. For 1 unit of font size, the length
+   of the string will be that much.
+   	Multiply by font size to get actual width in *points*
+   Then divide by 72 to get inches or divide by (72/25.6) to get 'mm' etc.
+   	@public
+   @function
+   @param
+   @returns {Type}
+   */
+  	var getStringUnitWidth = API.getStringUnitWidth = function (text, options) {
+  		return getArraySum(getCharWidthsArray.call(this, text, options));
+  	};
+
+  	/**
+   returns array of lines
+   */
+  	var splitLongWord = function splitLongWord(word, widths_array, firstLineMaxLen, maxLen) {
+  		var answer = [];
+
+  		// 1st, chop off the piece that can fit on the hanging line.
+  		var i = 0,
+  		    l = word.length,
+  		    workingLen = 0;
+  		while (i !== l && workingLen + widths_array[i] < firstLineMaxLen) {
+  			workingLen += widths_array[i];
+  			i++;
+  		}
+  		// this is first line.
+  		answer.push(word.slice(0, i));
+
+  		// 2nd. Split the rest into maxLen pieces.
+  		var startOfLine = i;
+  		workingLen = 0;
+  		while (i !== l) {
+  			if (workingLen + widths_array[i] > maxLen) {
+  				answer.push(word.slice(startOfLine, i));
+  				workingLen = 0;
+  				startOfLine = i;
+  			}
+  			workingLen += widths_array[i];
+  			i++;
+  		}
+  		if (startOfLine !== i) {
+  			answer.push(word.slice(startOfLine, i));
+  		}
+
+  		return answer;
+  	};
+
+  	// Note, all sizing inputs for this function must be in "font measurement units"
+  	// By default, for PDF, it's "point".
+  	var splitParagraphIntoLines = function splitParagraphIntoLines(text, maxlen, options) {
+  		// at this time works only on Western scripts, ones with space char
+  		// separating the words. Feel free to expand.
+
+  		if (!options) {
+  			options = {};
+  		}
+
+  		var line = [],
+  		    lines = [line],
+  		    line_length = options.textIndent || 0,
+  		    separator_length = 0,
+  		    current_word_length = 0,
+  		    word,
+  		    widths_array,
+  		    words = text.split(' '),
+  		    spaceCharWidth = getCharWidthsArray(' ', options)[0],
+  		    i,
+  		    l,
+  		    tmp,
+  		    lineIndent;
+
+  		if (options.lineIndent === -1) {
+  			lineIndent = words[0].length + 2;
+  		} else {
+  			lineIndent = options.lineIndent || 0;
+  		}
+  		if (lineIndent) {
+  			var pad = Array(lineIndent).join(" "),
+  			    wrds = [];
+  			words.map(function (wrd) {
+  				wrd = wrd.split(/\s*\n/);
+  				if (wrd.length > 1) {
+  					wrds = wrds.concat(wrd.map(function (wrd, idx) {
+  						return (idx && wrd.length ? "\n" : "") + wrd;
+  					}));
+  				} else {
+  					wrds.push(wrd[0]);
+  				}
+  			});
+  			words = wrds;
+  			lineIndent = getStringUnitWidth(pad, options);
+  		}
+
+  		for (i = 0, l = words.length; i < l; i++) {
+  			var force = 0;
+
+  			word = words[i];
+  			if (lineIndent && word[0] == "\n") {
+  				word = word.substr(1);
+  				force = 1;
+  			}
+  			widths_array = getCharWidthsArray(word, options);
+  			current_word_length = getArraySum(widths_array);
+
+  			if (line_length + separator_length + current_word_length > maxlen || force) {
+  				if (current_word_length > maxlen) {
+  					// this happens when you have space-less long URLs for example.
+  					// we just chop these to size. We do NOT insert hiphens
+  					tmp = splitLongWord(word, widths_array, maxlen - (line_length + separator_length), maxlen);
+  					// first line we add to existing line object
+  					line.push(tmp.shift()); // it's ok to have extra space indicator there
+  					// last line we make into new line object
+  					line = [tmp.pop()];
+  					// lines in the middle we apped to lines object as whole lines
+  					while (tmp.length) {
+  						lines.push([tmp.shift()]); // single fragment occupies whole line
+  					}
+  					current_word_length = getArraySum(widths_array.slice(word.length - (line[0] ? line[0].length : 0)));
+  				} else {
+  					// just put it on a new line
+  					line = [word];
+  				}
+
+  				// now we attach new line to lines
+  				lines.push(line);
+  				line_length = current_word_length + lineIndent;
+  				separator_length = spaceCharWidth;
+  			} else {
+  				line.push(word);
+
+  				line_length += separator_length + current_word_length;
+  				separator_length = spaceCharWidth;
+  			}
+  		}
+
+  		if (lineIndent) {
+  			var postProcess = function postProcess(ln, idx) {
+  				return (idx ? pad : '') + ln.join(" ");
+  			};
+  		} else {
+  			var postProcess = function postProcess(ln) {
+  				return ln.join(" ");
+  			};
+  		}
+
+  		return lines.map(postProcess);
+  	};
+
+  	/**
+   Splits a given string into an array of strings. Uses 'size' value
+   (in measurement units declared as default for the jsPDF instance)
+   and the font's "widths" and "Kerning" tables, where available, to
+   determine display length of a given string for a given font.
+   	We use character's 100% of unit size (height) as width when Width
+   table or other default width is not available.
+   	@public
+   @function
+   @param text {String} Unencoded, regular JavaScript (Unicode, UTF-16 / UCS-2) string.
+   @param size {Number} Nominal number, measured in units default to this instance of jsPDF.
+   @param options {Object} Optional flags needed for chopper to do the right thing.
+   @returns {Array} with strings chopped to size.
+   */
+  	API.splitTextToSize = function (text, maxlen, options) {
+
+  		if (!options) {
+  			options = {};
+  		}
+
+  		var fsize = options.fontSize || this.internal.getFontSize(),
+  		    newOptions = function (options) {
+  			var widths = {
+  				0: 1
+  			},
+  			    kerning = {};
+
+  			if (!options.widths || !options.kerning) {
+  				var f = this.internal.getFont(options.fontName, options.fontStyle),
+  				    encoding = 'Unicode';
+  				// NOT UTF8, NOT UTF16BE/LE, NOT UCS2BE/LE
+  				// Actual JavaScript-native String's 16bit char codes used.
+  				// no multi-byte logic here
+
+  				if (f.metadata[encoding]) {
+  					return {
+  						widths: f.metadata[encoding].widths || widths,
+  						kerning: f.metadata[encoding].kerning || kerning
+  					};
+  				} else {
+  					return {
+  						font: f.metadata,
+  						fontSize: this.internal.getFontSize(),
+  						charSpace: this.internal.getCharSpace()
+  					};
+  				}
+  			} else {
+  				return {
+  					widths: options.widths,
+  					kerning: options.kerning
+  				};
+  			}
+
+  			// then use default values
+  			return {
+  				widths: widths,
+  				kerning: kerning
+  			};
+  		}.call(this, options);
+
+  		// first we split on end-of-line chars
+  		var paragraphs;
+  		if (Array.isArray(text)) {
+  			paragraphs = text;
+  		} else {
+  			paragraphs = text.split(/\r?\n/);
+  		}
+
+  		// now we convert size (max length of line) into "font size units"
+  		// at present time, the "font size unit" is always 'point'
+  		// 'proportional' means, "in proportion to font size"
+  		var fontUnit_maxLen = 1.0 * this.internal.scaleFactor * maxlen / fsize;
+  		// at this time, fsize is always in "points" regardless of the default measurement unit of the doc.
+  		// this may change in the future?
+  		// until then, proportional_maxlen is likely to be in 'points'
+
+  		// If first line is to be indented (shorter or longer) than maxLen
+  		// we indicate that by using CSS-style "text-indent" option.
+  		// here it's in font units too (which is likely 'points')
+  		// it can be negative (which makes the first line longer than maxLen)
+  		newOptions.textIndent = options.textIndent ? options.textIndent * 1.0 * this.internal.scaleFactor / fsize : 0;
+  		newOptions.lineIndent = options.lineIndent;
+
+  		var i,
+  		    l,
+  		    output = [];
+  		for (i = 0, l = paragraphs.length; i < l; i++) {
+  			output = output.concat(splitParagraphIntoLines(paragraphs[i], fontUnit_maxLen, newOptions));
+  		}
+
+  		return output;
+  	};
+  })(jsPDF.API);
+
+  /** @preserve 
+  jsPDF standard_fonts_metrics plugin
+  Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
+  MIT license.
+  */
+  (function (API) {
+
+  	/*
+   # reference (Python) versions of 'compress' and 'uncompress'
+   # only 'uncompress' function is featured lower as JavaScript
+   # if you want to unit test "roundtrip", just transcribe the reference
+   # 'compress' function from Python into JavaScript
+   
+   def compress(data):
+   
+   	keys =   '0123456789abcdef'
+   	values = 'klmnopqrstuvwxyz'
+   	mapping = dict(zip(keys, values))
+   	vals = []
+   	for key in data.keys():
+   		value = data[key]
+   		try:
+   			keystring = hex(key)[2:]
+   			keystring = keystring[:-1] + mapping[keystring[-1:]]
+   		except:
+   			keystring = key.join(["'","'"])
+   			#print('Keystring is %s' % keystring)
+   
+   		try:
+   			if value < 0:
+   				valuestring = hex(value)[3:]
+   				numberprefix = '-'
+   			else:
+   				valuestring = hex(value)[2:]
+   				numberprefix = ''
+   			valuestring = numberprefix + valuestring[:-1] + mapping[valuestring[-1:]]
+   		except:
+   			if type(value) == dict:
+   				valuestring = compress(value)
+   			else:
+   				raise Exception("Don't know what to do with value type %s" % type(value))
+   
+   		vals.append(keystring+valuestring)
+   	
+   	return '{' + ''.join(vals) + '}'
+   
+   def uncompress(data):
+   
+   	decoded = '0123456789abcdef'
+   	encoded = 'klmnopqrstuvwxyz'
+   	mapping = dict(zip(encoded, decoded))
+   
+   	sign = +1
+   	stringmode = False
+   	stringparts = []
+   
+   	output = {}
+   
+   	activeobject = output
+   	parentchain = []
+   
+   	keyparts = ''
+   	valueparts = ''
+   
+   	key = None
+   
+   	ending = set(encoded)
+   
+   	i = 1
+   	l = len(data) - 1 # stripping starting, ending {}
+   	while i != l: # stripping {}
+   		# -, {, }, ' are special.
+   
+   		ch = data[i]
+   		i += 1
+   
+   		if ch == "'":
+   			if stringmode:
+   				# end of string mode
+   				stringmode = False
+   				key = ''.join(stringparts)
+   			else:
+   				# start of string mode
+   				stringmode = True
+   				stringparts = []
+   		elif stringmode == True:
+   			#print("Adding %s to stringpart" % ch)
+   			stringparts.append(ch)
+   
+   		elif ch == '{':
+   			# start of object
+   			parentchain.append( [activeobject, key] )
+   			activeobject = {}
+   			key = None
+   			#DEBUG = True
+   		elif ch == '}':
+   			# end of object
+   			parent, key = parentchain.pop()
+   			parent[key] = activeobject
+   			key = None
+   			activeobject = parent
+   			#DEBUG = False
+   
+   		elif ch == '-':
+   			sign = -1
+   		else:
+   			# must be number
+   			if key == None:
+   				#debug("In Key. It is '%s', ch is '%s'" % (keyparts, ch))
+   				if ch in ending:
+   					#debug("End of key")
+   					keyparts += mapping[ch]
+   					key = int(keyparts, 16) * sign
+   					sign = +1
+   					keyparts = ''
+   				else:
+   					keyparts += ch
+   			else:
+   				#debug("In value. It is '%s', ch is '%s'" % (valueparts, ch))
+   				if ch in ending:
+   					#debug("End of value")
+   					valueparts += mapping[ch]
+   					activeobject[key] = int(valueparts, 16) * sign
+   					sign = +1
+   					key = None
+   					valueparts = ''
+   				else:
+   					valueparts += ch
+   
+   			#debug(activeobject)
+   
+   	return output
+   
+   */
+
+  	/**
+   Uncompresses data compressed into custom, base16-like format. 
+   @public
+   @function
+   @param
+   @returns {Type}
+   */
+
+  	var uncompress = function uncompress(data) {
+
+  		var decoded = '0123456789abcdef',
+  		    encoded = 'klmnopqrstuvwxyz',
+  		    mapping = {};
+
+  		for (var i = 0; i < encoded.length; i++) {
+  			mapping[encoded[i]] = decoded[i];
+  		}
+
+  		var undef,
+  		    output = {},
+  		    sign = 1,
+  		    stringparts // undef. will be [] in string mode
+
+  		,
+  		    activeobject = output,
+  		    parentchain = [],
+  		    parent_key_pair,
+  		    keyparts = '',
+  		    valueparts = '',
+  		    key // undef. will be Truthy when Key is resolved.
+  		,
+  		    datalen = data.length - 1 // stripping ending }
+  		,
+  		    ch;
+
+  		i = 1; // stripping starting {
+
+  		while (i != datalen) {
+  			// - { } ' are special.
+
+  			ch = data[i];
+  			i += 1;
+
+  			if (ch == "'") {
+  				if (stringparts) {
+  					// end of string mode
+  					key = stringparts.join('');
+  					stringparts = undef;
+  				} else {
+  					// start of string mode
+  					stringparts = [];
+  				}
+  			} else if (stringparts) {
+  				stringparts.push(ch);
+  			} else if (ch == '{') {
+  				// start of object
+  				parentchain.push([activeobject, key]);
+  				activeobject = {};
+  				key = undef;
+  			} else if (ch == '}') {
+  				// end of object
+  				parent_key_pair = parentchain.pop();
+  				parent_key_pair[0][parent_key_pair[1]] = activeobject;
+  				key = undef;
+  				activeobject = parent_key_pair[0];
+  			} else if (ch == '-') {
+  				sign = -1;
+  			} else {
+  				// must be number
+  				if (key === undef) {
+  					if (mapping.hasOwnProperty(ch)) {
+  						keyparts += mapping[ch];
+  						key = parseInt(keyparts, 16) * sign;
+  						sign = +1;
+  						keyparts = '';
+  					} else {
+  						keyparts += ch;
+  					}
+  				} else {
+  					if (mapping.hasOwnProperty(ch)) {
+  						valueparts += mapping[ch];
+  						activeobject[key] = parseInt(valueparts, 16) * sign;
+  						sign = +1;
+  						key = undef;
+  						valueparts = '';
+  					} else {
+  						valueparts += ch;
+  					}
+  				}
+  			}
+  		} // end while
+
+  		return output;
+  	};
+
+  	// encoding = 'Unicode' 
+  	// NOT UTF8, NOT UTF16BE/LE, NOT UCS2BE/LE. NO clever BOM behavior
+  	// Actual 16bit char codes used.
+  	// no multi-byte logic here
+
+  	// Unicode characters to WinAnsiEncoding:
+  	// {402: 131, 8211: 150, 8212: 151, 8216: 145, 8217: 146, 8218: 130, 8220: 147, 8221: 148, 8222: 132, 8224: 134, 8225: 135, 8226: 149, 8230: 133, 8364: 128, 8240:137, 8249: 139, 8250: 155, 710: 136, 8482: 153, 338: 140, 339: 156, 732: 152, 352: 138, 353: 154, 376: 159, 381: 142, 382: 158}
+  	// as you can see, all Unicode chars are outside of 0-255 range. No char code conflicts.
+  	// this means that you can give Win cp1252 encoded strings to jsPDF for rendering directly
+  	// as well as give strings with some (supported by these fonts) Unicode characters and 
+  	// these will be mapped to win cp1252 
+  	// for example, you can send char code (cp1252) 0x80 or (unicode) 0x20AC, getting "Euro" glyph displayed in both cases.
+
+  	var encodingBlock = {
+  		'codePages': ['WinAnsiEncoding'],
+  		'WinAnsiEncoding': uncompress("{19m8n201n9q201o9r201s9l201t9m201u8m201w9n201x9o201y8o202k8q202l8r202m9p202q8p20aw8k203k8t203t8v203u9v2cq8s212m9t15m8w15n9w2dw9s16k8u16l9u17s9z17x8y17y9y}")
+  	},
+  	    encodings = { 'Unicode': {
+  			'Courier': encodingBlock,
+  			'Courier-Bold': encodingBlock,
+  			'Courier-BoldOblique': encodingBlock,
+  			'Courier-Oblique': encodingBlock,
+  			'Helvetica': encodingBlock,
+  			'Helvetica-Bold': encodingBlock,
+  			'Helvetica-BoldOblique': encodingBlock,
+  			'Helvetica-Oblique': encodingBlock,
+  			'Times-Roman': encodingBlock,
+  			'Times-Bold': encodingBlock,
+  			'Times-BoldItalic': encodingBlock,
+  			'Times-Italic': encodingBlock
+  			//	, 'Symbol'
+  			//	, 'ZapfDingbats'
+  		}
+  		/** 
+    Resources:
+    Font metrics data is reprocessed derivative of contents of
+    "Font Metrics for PDF Core 14 Fonts" package, which exhibits the following copyright and license:
+    
+    Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
+    
+    This file and the 14 PostScript(R) AFM files it accompanies may be used,
+    copied, and distributed for any purpose and without charge, with or without
+    modification, provided that all copyright notices are retained; that the AFM
+    files are not distributed without this file; that all modifications to this
+    file or any of the AFM files are prominently noted in the modified file(s);
+    and that this paragraph is not modified. Adobe Systems has no responsibility
+    or obligation to support the use of the AFM files.
+    
+    */
+  	},
+  	    fontMetrics = { 'Unicode': {
+  			// all sizing numbers are n/fontMetricsFractionOf = one font size unit
+  			// this means that if fontMetricsFractionOf = 1000, and letter A's width is 476, it's
+  			// width is 476/1000 or 47.6% of its height (regardless of font size)
+  			// At this time this value applies to "widths" and "kerning" numbers.
+
+  			// char code 0 represents "default" (average) width - use it for chars missing in this table.
+  			// key 'fof' represents the "fontMetricsFractionOf" value
+
+  			'Courier-Oblique': uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
+  			'Times-BoldItalic': uncompress("{'widths'{k3o2q4ycx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2r202m2n2n3m2o3m2p5n202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5n4l4m4m4m4n4m4o4s4p4m4q4m4r4s4s4y4t2r4u3m4v4m4w3x4x5t4y4s4z4s5k3x5l4s5m4m5n3r5o3x5p4s5q4m5r5t5s4m5t3x5u3x5v2l5w1w5x2l5y3t5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q2l6r3m6s3r6t1w6u1w6v3m6w1w6x4y6y3r6z3m7k3m7l3m7m2r7n2r7o1w7p3r7q2w7r4m7s3m7t2w7u2r7v2n7w1q7x2n7y3t202l3mcl4mal2ram3man3mao3map3mar3mas2lat4uau1uav3maw3way4uaz2lbk2sbl3t'fof'6obo2lbp3tbq3mbr1tbs2lbu1ybv3mbz3mck4m202k3mcm4mcn4mco4mcp4mcq5ycr4mcs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz2w203k6o212m6o2dw2l2cq2l3t3m3u2l17s3x19m3m}'kerning'{cl{4qu5kt5qt5rs17ss5ts}201s{201ss}201t{cks4lscmscnscoscpscls2wu2yu201ts}201x{2wu2yu}2k{201ts}2w{4qx5kx5ou5qx5rs17su5tu}2x{17su5tu5ou}2y{4qx5kx5ou5qx5rs17ss5ts}'fof'-6ofn{17sw5tw5ou5qw5rs}7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qs}3v{17su5tu5os5qs}7p{17su5tu}ck{4qu5kt5qt5rs17ss5ts}4l{4qu5kt5qt5rs17ss5ts}cm{4qu5kt5qt5rs17ss5ts}cn{4qu5kt5qt5rs17ss5ts}co{4qu5kt5qt5rs17ss5ts}cp{4qu5kt5qt5rs17ss5ts}6l{4qu5ou5qw5rt17su5tu}5q{ckuclucmucnucoucpu4lu}5r{ckuclucmucnucoucpu4lu}7q{cksclscmscnscoscps4ls}6p{4qu5ou5qw5rt17sw5tw}ek{4qu5ou5qw5rt17su5tu}el{4qu5ou5qw5rt17su5tu}em{4qu5ou5qw5rt17su5tu}en{4qu5ou5qw5rt17su5tu}eo{4qu5ou5qw5rt17su5tu}ep{4qu5ou5qw5rt17su5tu}es{17ss5ts5qs4qu}et{4qu5ou5qw5rt17sw5tw}eu{4qu5ou5qw5rt17ss5ts}ev{17ss5ts5qs4qu}6z{17sw5tw5ou5qw5rs}fm{17sw5tw5ou5qw5rs}7n{201ts}fo{17sw5tw5ou5qw5rs}fp{17sw5tw5ou5qw5rs}fq{17sw5tw5ou5qw5rs}7r{cksclscmscnscoscps4ls}fs{17sw5tw5ou5qw5rs}ft{17su5tu}fu{17su5tu}fv{17su5tu}fw{17su5tu}fz{cksclscmscnscoscps4ls}}}"),
+  			'Helvetica-Bold': uncompress("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),
+  			'Courier': uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
+  			'Courier-BoldOblique': uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
+  			'Times-Bold': uncompress("{'widths'{k3q2q5ncx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2l202m2n2n3m2o3m2p6o202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5x4l4s4m4m4n4s4o4s4p4m4q3x4r4y4s4y4t2r4u3m4v4y4w4m4x5y4y4s4z4y5k3x5l4y5m4s5n3r5o4m5p4s5q4s5r6o5s4s5t4s5u4m5v2l5w1w5x2l5y3u5z3m6k2l6l3m6m3r6n2w6o3r6p2w6q2l6r3m6s3r6t1w6u2l6v3r6w1w6x5n6y3r6z3m7k3r7l3r7m2w7n2r7o2l7p3r7q3m7r4s7s3m7t3m7u2w7v2r7w1q7x2r7y3o202l3mcl4sal2lam3man3mao3map3mar3mas2lat4uau1yav3maw3tay4uaz2lbk2sbl3t'fof'6obo2lbp3rbr1tbs2lbu2lbv3mbz3mck4s202k3mcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3rek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3m3u2l17s4s19m3m}'kerning'{cl{4qt5ks5ot5qy5rw17sv5tv}201t{cks4lscmscnscoscpscls4wv}2k{201ts}2w{4qu5ku7mu5os5qx5ru17su5tu}2x{17su5tu5ou5qs}2y{4qv5kv7mu5ot5qz5ru17su5tu}'fof'-6o7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qu}3v{17su5tu5os5qu}fu{17su5tu5ou5qu}7p{17su5tu5ou5qu}ck{4qt5ks5ot5qy5rw17sv5tv}4l{4qt5ks5ot5qy5rw17sv5tv}cm{4qt5ks5ot5qy5rw17sv5tv}cn{4qt5ks5ot5qy5rw17sv5tv}co{4qt5ks5ot5qy5rw17sv5tv}cp{4qt5ks5ot5qy5rw17sv5tv}6l{17st5tt5ou5qu}17s{ckuclucmucnucoucpu4lu4wu}5o{ckuclucmucnucoucpu4lu4wu}5q{ckzclzcmzcnzcozcpz4lz4wu}5r{ckxclxcmxcnxcoxcpx4lx4wu}5t{ckuclucmucnucoucpu4lu4wu}7q{ckuclucmucnucoucpu4lu}6p{17sw5tw5ou5qu}ek{17st5tt5qu}el{17st5tt5ou5qu}em{17st5tt5qu}en{17st5tt5qu}eo{17st5tt5qu}ep{17st5tt5ou5qu}es{17ss5ts5qu}et{17sw5tw5ou5qu}eu{17sw5tw5ou5qu}ev{17ss5ts5qu}6z{17sw5tw5ou5qu5rs}fm{17sw5tw5ou5qu5rs}fn{17sw5tw5ou5qu5rs}fo{17sw5tw5ou5qu5rs}fp{17sw5tw5ou5qu5rs}fq{17sw5tw5ou5qu5rs}7r{cktcltcmtcntcotcpt4lt5os}fs{17sw5tw5ou5qu5rs}ft{17su5tu5ou5qu}7m{5os}fv{17su5tu5ou5qu}fw{17su5tu5ou5qu}fz{cksclscmscnscoscps4ls}}}"),
+  			'Symbol': uncompress("{'widths'{k3uaw4r19m3m2k1t2l2l202m2y2n3m2p5n202q6o3k3m2s2l2t2l2v3r2w1t3m3m2y1t2z1wbk2sbl3r'fof'6o3n3m3o3m3p3m3q3m3r3m3s3m3t3m3u1w3v1w3w3r3x3r3y3r3z2wbp3t3l3m5v2l5x2l5z3m2q4yfr3r7v3k7w1o7x3k}'kerning'{'fof'-6o}}"),
+  			'Helvetica': uncompress("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}"),
+  			'Helvetica-BoldOblique': uncompress("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),
+  			'ZapfDingbats': uncompress("{'widths'{k4u2k1w'fof'6o}'kerning'{'fof'-6o}}"),
+  			'Courier-Bold': uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
+  			'Times-Italic': uncompress("{'widths'{k3n2q4ycx2l201n3m201o5t201s2l201t2l201u2l201w3r201x3r201y3r2k1t2l2l202m2n2n3m2o3m2p5n202q5t2r1p2s2l2t2l2u3m2v4n2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w4n3x4n3y4n3z3m4k5w4l3x4m3x4n4m4o4s4p3x4q3x4r4s4s4s4t2l4u2w4v4m4w3r4x5n4y4m4z4s5k3x5l4s5m3x5n3m5o3r5p4s5q3x5r5n5s3x5t3r5u3r5v2r5w1w5x2r5y2u5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q1w6r3m6s3m6t1w6u1w6v2w6w1w6x4s6y3m6z3m7k3m7l3m7m2r7n2r7o1w7p3m7q2w7r4m7s2w7t2w7u2r7v2s7w1v7x2s7y3q202l3mcl3xal2ram3man3mao3map3mar3mas2lat4wau1vav3maw4nay4waz2lbk2sbl4n'fof'6obo2lbp3mbq3obr1tbs2lbu1zbv3mbz3mck3x202k3mcm3xcn3xco3xcp3xcq5tcr4mcs3xct3xcu3xcv3xcw2l2m2ucy2lcz2ldl4mdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr4nfs3mft3mfu3mfv3mfw3mfz2w203k6o212m6m2dw2l2cq2l3t3m3u2l17s3r19m3m}'kerning'{cl{5kt4qw}201s{201sw}201t{201tw2wy2yy6q-t}201x{2wy2yy}2k{201tw}2w{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}2x{17ss5ts5os}2y{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}'fof'-6o6t{17ss5ts5qs}7t{5os}3v{5qs}7p{17su5tu5qs}ck{5kt4qw}4l{5kt4qw}cm{5kt4qw}cn{5kt4qw}co{5kt4qw}cp{5kt4qw}6l{4qs5ks5ou5qw5ru17su5tu}17s{2ks}5q{ckvclvcmvcnvcovcpv4lv}5r{ckuclucmucnucoucpu4lu}5t{2ks}6p{4qs5ks5ou5qw5ru17su5tu}ek{4qs5ks5ou5qw5ru17su5tu}el{4qs5ks5ou5qw5ru17su5tu}em{4qs5ks5ou5qw5ru17su5tu}en{4qs5ks5ou5qw5ru17su5tu}eo{4qs5ks5ou5qw5ru17su5tu}ep{4qs5ks5ou5qw5ru17su5tu}es{5ks5qs4qs}et{4qs5ks5ou5qw5ru17su5tu}eu{4qs5ks5qw5ru17su5tu}ev{5ks5qs4qs}ex{17ss5ts5qs}6z{4qv5ks5ou5qw5ru17su5tu}fm{4qv5ks5ou5qw5ru17su5tu}fn{4qv5ks5ou5qw5ru17su5tu}fo{4qv5ks5ou5qw5ru17su5tu}fp{4qv5ks5ou5qw5ru17su5tu}fq{4qv5ks5ou5qw5ru17su5tu}7r{5os}fs{4qv5ks5ou5qw5ru17su5tu}ft{17su5tu5qs}fu{17su5tu5qs}fv{17su5tu5qs}fw{17su5tu5qs}}}"),
+  			'Times-Roman': uncompress("{'widths'{k3n2q4ycx2l201n3m201o6o201s2l201t2l201u2l201w2w201x2w201y2w2k1t2l2l202m2n2n3m2o3m2p5n202q6o2r1m2s2l2t2l2u3m2v3s2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v1w3w3s3x3s3y3s3z2w4k5w4l4s4m4m4n4m4o4s4p3x4q3r4r4s4s4s4t2l4u2r4v4s4w3x4x5t4y4s4z4s5k3r5l4s5m4m5n3r5o3x5p4s5q4s5r5y5s4s5t4s5u3x5v2l5w1w5x2l5y2z5z3m6k2l6l2w6m3m6n2w6o3m6p2w6q2l6r3m6s3m6t1w6u1w6v3m6w1w6x4y6y3m6z3m7k3m7l3m7m2l7n2r7o1w7p3m7q3m7r4s7s3m7t3m7u2w7v3k7w1o7x3k7y3q202l3mcl4sal2lam3man3mao3map3mar3mas2lat4wau1vav3maw3say4waz2lbk2sbl3s'fof'6obo2lbp3mbq2xbr1tbs2lbu1zbv3mbz2wck4s202k3mcm4scn4sco4scp4scq5tcr4mcs3xct3xcu3xcv3xcw2l2m2tcy2lcz2ldl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek2wel2wem2wen2weo2wep2weq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr3sfs3mft3mfu3mfv3mfw3mfz3m203k6o212m6m2dw2l2cq2l3t3m3u1w17s4s19m3m}'kerning'{cl{4qs5ku17sw5ou5qy5rw201ss5tw201ws}201s{201ss}201t{ckw4lwcmwcnwcowcpwclw4wu201ts}2k{201ts}2w{4qs5kw5os5qx5ru17sx5tx}2x{17sw5tw5ou5qu}2y{4qs5kw5os5qx5ru17sx5tx}'fof'-6o7t{ckuclucmucnucoucpu4lu5os5rs}3u{17su5tu5qs}3v{17su5tu5qs}7p{17sw5tw5qs}ck{4qs5ku17sw5ou5qy5rw201ss5tw201ws}4l{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cm{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cn{4qs5ku17sw5ou5qy5rw201ss5tw201ws}co{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cp{4qs5ku17sw5ou5qy5rw201ss5tw201ws}6l{17su5tu5os5qw5rs}17s{2ktclvcmvcnvcovcpv4lv4wuckv}5o{ckwclwcmwcnwcowcpw4lw4wu}5q{ckyclycmycnycoycpy4ly4wu5ms}5r{cktcltcmtcntcotcpt4lt4ws}5t{2ktclvcmvcnvcovcpv4lv4wuckv}7q{cksclscmscnscoscps4ls}6p{17su5tu5qw5rs}ek{5qs5rs}el{17su5tu5os5qw5rs}em{17su5tu5os5qs5rs}en{17su5qs5rs}eo{5qs5rs}ep{17su5tu5os5qw5rs}es{5qs}et{17su5tu5qw5rs}eu{17su5tu5qs5rs}ev{5qs}6z{17sv5tv5os5qx5rs}fm{5os5qt5rs}fn{17sv5tv5os5qx5rs}fo{17sv5tv5os5qx5rs}fp{5os5qt5rs}fq{5os5qt5rs}7r{ckuclucmucnucoucpu4lu5os}fs{17sv5tv5os5qx5rs}ft{17ss5ts5qs}fu{17sw5tw5qs}fv{17sw5tw5qs}fw{17ss5ts5qs}fz{ckuclucmucnucoucpu4lu5os5rs}}}"),
+  			'Helvetica-Oblique': uncompress("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}")
+  		} };
+
+  	/*
+   This event handler is fired when a new jsPDF object is initialized
+   This event handler appends metrics data to standard fonts within
+   that jsPDF instance. The metrics are mapped over Unicode character
+   codes, NOT CIDs or other codes matching the StandardEncoding table of the
+   standard PDF fonts.
+   Future:
+   Also included is the encoding maping table, converting Unicode (UCS-2, UTF-16)
+   char codes to StandardEncoding character codes. The encoding table is to be used
+   somewhere around "pdfEscape" call.
+   */
+
+  	API.events.push(['addFont', function (font) {
+  		var metrics,
+  		    unicode_section,
+  		    encoding = 'Unicode',
+  		    encodingBlock;
+
+  		metrics = fontMetrics[encoding][font.postScriptName];
+  		if (metrics) {
+  			if (font.metadata[encoding]) {
+  				unicode_section = font.metadata[encoding];
+  			} else {
+  				unicode_section = font.metadata[encoding] = {};
+  			}
+
+  			unicode_section.widths = metrics.widths;
+  			unicode_section.kerning = metrics.kerning;
+  		}
+
+  		encodingBlock = encodings[encoding][font.postScriptName];
+  		if (encodingBlock) {
+  			if (font.metadata[encoding]) {
+  				unicode_section = font.metadata[encoding];
+  			} else {
+  				unicode_section = font.metadata[encoding] = {};
+  			}
+
+  			unicode_section.encoding = encodingBlock;
+  			if (encodingBlock.codePages && encodingBlock.codePages.length) {
+  				font.encoding = encodingBlock.codePages[0];
+  			}
+  		}
+  	}]); // end of adding event handler
+  })(jsPDF.API);
+
+  /**
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+  (function (jsPDF, global) {
+
+      jsPDF.API.events.push(['addFont', function (font) {
+          if (jsPDF.API.existsFileInVFS(font.postScriptName)) {
+              font.metadata = jsPDF.API.TTFFont.open(font.postScriptName, font.fontName, jsPDF.API.getFileFromVFS(font.postScriptName), font.encoding);
+              font.metadata.Unicode = font.metadata.Unicode || { encoding: {}, kerning: {}, widths: [] };
+          } else if (font.id.slice(1) > 14) {
+              console.error("Font does not exist in FileInVFS, import fonts or remove declaration doc.addFont('" + font.postScriptName + "').");
+          }
+      }]); // end of adding event handler
+  })(jsPDF, typeof self !== "undefined" && self || typeof global !== "undefined" && global || typeof window !== "undefined" && window || Function("return this")());
+
+  /** @preserve
+  jsPDF SVG plugin
+  Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
+  */
+  (function (jsPDFAPI) {
+
+  	/**
+   Parses SVG XML and converts only some of the SVG elements into
+   PDF elements.
+   
+   Supports:
+    paths
+   
+   @public
+   @function
+   @param
+   @returns {Type}
+   */
+
+  	jsPDFAPI.addSVG = function (svgtext, x, y, w, h) {
+  		// 'this' is _jsPDF object returned when jsPDF is inited (new jsPDF())
+
+  		var undef;
+
+  		if (x === undef || y === undef) {
+  			throw new Error("addSVG needs values for 'x' and 'y'");
+  		}
+
+  		function InjectCSS(cssbody, document) {
+  			var styletag = document.createElement('style');
+  			styletag.type = 'text/css';
+  			if (styletag.styleSheet) {
+  				// ie
+  				styletag.styleSheet.cssText = cssbody;
+  			} else {
+  				// others
+  				styletag.appendChild(document.createTextNode(cssbody));
+  			}
+  			document.getElementsByTagName("head")[0].appendChild(styletag);
+  		}
+
+  		function createWorkerNode(document) {
+
+  			var frameID = 'childframe' // Date.now().toString() + '_' + (Math.random() * 100).toString()
+  			,
+  			    frame = document.createElement('iframe');
+
+  			InjectCSS('.jsPDF_sillysvg_iframe {display:none;position:absolute;}', document);
+
+  			frame.name = frameID;
+  			frame.setAttribute("width", 0);
+  			frame.setAttribute("height", 0);
+  			frame.setAttribute("frameborder", "0");
+  			frame.setAttribute("scrolling", "no");
+  			frame.setAttribute("seamless", "seamless");
+  			frame.setAttribute("class", "jsPDF_sillysvg_iframe");
+
+  			document.body.appendChild(frame);
+
+  			return frame;
+  		}
+
+  		function attachSVGToWorkerNode(svgtext, frame) {
+  			var framedoc = (frame.contentWindow || frame.contentDocument).document;
+  			framedoc.write(svgtext);
+  			framedoc.close();
+  			return framedoc.getElementsByTagName('svg')[0];
+  		}
+
+  		function convertPathToPDFLinesArgs(path) {
+  			// we will use 'lines' method call. it needs:
+  			// - starting coordinate pair
+  			// - array of arrays of vector shifts (2-len for line, 6 len for bezier)
+  			// - scale array [horizontal, vertical] ratios
+  			// - style (stroke, fill, both)
+
+  			var x = parseFloat(path[1]),
+  			    y = parseFloat(path[2]),
+  			    vectors = [],
+  			    position = 3,
+  			    len = path.length;
+
+  			while (position < len) {
+  				if (path[position] === 'c') {
+  					vectors.push([parseFloat(path[position + 1]), parseFloat(path[position + 2]), parseFloat(path[position + 3]), parseFloat(path[position + 4]), parseFloat(path[position + 5]), parseFloat(path[position + 6])]);
+  					position += 7;
+  				} else if (path[position] === 'l') {
+  					vectors.push([parseFloat(path[position + 1]), parseFloat(path[position + 2])]);
+  					position += 3;
+  				} else {
+  					position += 1;
+  				}
+  			}
+  			return [x, y, vectors];
+  		}
+
+  		var workernode = createWorkerNode(document),
+  		    svgnode = attachSVGToWorkerNode(svgtext, workernode),
+  		    scale = [1, 1],
+  		    svgw = parseFloat(svgnode.getAttribute('width')),
+  		    svgh = parseFloat(svgnode.getAttribute('height'));
+
+  		if (svgw && svgh) {
+  			// setting both w and h makes image stretch to size.
+  			// this may distort the image, but fits your demanded size
+  			if (w && h) {
+  				scale = [w / svgw, h / svgh];
+  			}
+  			// if only one is set, that value is set as max and SVG
+  			// is scaled proportionately.
+  			else if (w) {
+  					scale = [w / svgw, w / svgw];
+  				} else if (h) {
+  					scale = [h / svgh, h / svgh];
+  				}
+  		}
+
+  		var i,
+  		    l,
+  		    tmp,
+  		    linesargs,
+  		    items = svgnode.childNodes;
+  		for (i = 0, l = items.length; i < l; i++) {
+  			tmp = items[i];
+  			if (tmp.tagName && tmp.tagName.toUpperCase() === 'PATH') {
+  				linesargs = convertPathToPDFLinesArgs(tmp.getAttribute("d").split(' '));
+  				// path start x coordinate
+  				linesargs[0] = linesargs[0] * scale[0] + x; // where x is upper left X of image
+  				// path start y coordinate
+  				linesargs[1] = linesargs[1] * scale[1] + y; // where y is upper left Y of image
+  				// the rest of lines are vectors. these will adjust with scale value auto.
+  				this.lines.call(this, linesargs[2] // lines
+  				, linesargs[0] // starting x
+  				, linesargs[1] // starting y
+  				, scale);
+  			}
+  		}
+
+  		// clean up
+  		// workernode.parentNode.removeChild(workernode)
+
+  		return this;
+  	};
+  })(jsPDF.API);
+
+  /** ==================================================================== 
+   * jsPDF total_pages plugin
+   * Copyright (c) 2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
+   * 
+   * 
+   * ====================================================================
+   */
+
+  (function (jsPDFAPI) {
+
+    jsPDFAPI.putTotalPages = function (pageExpression) {
+
+      var replaceExpression = new RegExp(pageExpression, 'g');
+      for (var n = 1; n <= this.internal.getNumberOfPages(); n++) {
+        for (var i = 0; i < this.internal.pages[n].length; i++) {
+          this.internal.pages[n][i] = this.internal.pages[n][i].replace(replaceExpression, this.internal.getNumberOfPages());
+        }
+      }
+      return this;
+    };
+  })(jsPDF.API);
+
+  /**
+   * jsPDF viewerPreferences Plugin
+   * @author Aras Abbasi (github.com/arasabbasi)
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+
+  /**
+  * Adds the ability to set ViewerPreferences and by thus
+  * controlling the way the document is to be presented on the
+  * screen or in print.
+  */
+
+  (function (jsPDFAPI) {
+      /**
+       * Set the ViewerPreferences of the generated PDF
+       *
+       * @param {Object} options Array with the ViewerPreferences<br />
+       * Example: doc.viewerPreferences({"FitWindow":true});<br />
+       * <br />
+       * You can set following preferences:<br />
+       * <br/>
+       * <b>HideToolbar</b> <i>(boolean)</i><br />
+       * Default value: false<br />
+       * <br />
+       * <b>HideMenubar</b> <i>(boolean)</i><br />
+       * Default value: false.<br />
+       * <br />
+       * <b>HideWindowUI</b> <i>(boolean)</i><br />
+       * Default value: false.<br />
+       * <br />
+       * <b>FitWindow</b> <i>(boolean)</i><br />
+       * Default value: false.<br />
+       * <br />
+       * <b>CenterWindow</b> <i>(boolean)</i><br />
+       * Default value: false<br />
+       * <br />
+       * <b>DisplayDocTitle</b> <i>(boolean)</i><br />
+       * Default value: false.<br />
+       * <br />
+       * <b>NonFullScreenPageMode</b> <i>(String)</i><br />
+       * Possible values: UseNone, UseOutlines, UseThumbs, UseOC<br />
+       * Default value: UseNone<br/>
+       * <br />
+       * <b>Direction</b> <i>(String)</i><br />
+       * Possible values: L2R, R2L<br />
+       * Default value: L2R.<br />
+       * <br />
+       * <b>ViewArea</b> <i>(String)</i><br />
+       * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
+       * Default value: CropBox.<br />
+       * <br />
+       * <b>ViewClip</b> <i>(String)</i><br />
+       * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
+       * Default value: CropBox<br />
+       * <br />
+       * <b>PrintArea</b> <i>(String)</i><br />
+       * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
+       * Default value: CropBox<br />
+       * <br />
+       * <b>PrintClip</b> <i>(String)</i><br />
+       * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
+       * Default value: CropBox.<br />
+       * <br />
+       * <b>PrintScaling</b> <i>(String)</i><br />
+       * Possible values: AppDefault, None<br />
+       * Default value: AppDefault.<br />
+       * <br />
+       * <b>Duplex</b> <i>(String)</i><br />
+       * Possible values: Simplex, DuplexFlipLongEdge, DuplexFlipShortEdge
+       * Default value: none<br />
+       * <br />
+       * <b>PickTrayByPDFSize</b> <i>(boolean)</i><br />
+       * Default value: false<br />
+       * <br />
+       * <b>PrintPageRange</b> <i>(Array)</i><br />
+       * Example: [[1,5], [7,9]]<br />
+       * Default value: as defined by PDF viewer application<br />
+       * <br />
+       * <b>NumCopies</b> <i>(Number)</i><br />
+       * Possible values: 1, 2, 3, 4, 5<br />
+       * Default value: 1<br />
+       * <br />
+       * For more information see the PDF Reference, sixth edition on Page 577
+       * @param {boolean} doReset True to reset the settings
+       * @function
+       * @returns jsPDF
+       * @methodOf jsPDF#
+       * @example
+       * var doc = new jsPDF()
+       * doc.text('This is a test', 10, 10)
+       * doc.viewerPreferences({'FitWindow': true}, true)
+       * doc.save("viewerPreferences.pdf")
+       *
+       * // Example printing 10 copies, using cropbox, and hiding UI.
+       * doc.viewerPreferences({
+       *   'HideWindowUI': true,
+       *   'PrintArea': 'CropBox',
+       *   'NumCopies': 10
+       * })
+       * @name viewerPreferences
+       */
+
+      jsPDFAPI.viewerPreferences = function (options, doReset) {
+          options = options || {};
+          doReset = doReset || false;
+
+          var configuration;
+          var configurationTemplate = {
+              "HideToolbar": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },
+              "HideMenubar": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },
+              "HideWindowUI": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },
+              "FitWindow": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },
+              "CenterWindow": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },
+              "DisplayDocTitle": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.4 },
+              "NonFullScreenPageMode": { defaultValue: "UseNone", value: "UseNone", type: "name", explicitSet: false, valueSet: ["UseNone", "UseOutlines", "UseThumbs", "UseOC"], pdfVersion: 1.3 },
+              "Direction": { defaultValue: "L2R", value: "L2R", type: "name", explicitSet: false, valueSet: ["L2R", "R2L"], pdfVersion: 1.3 },
+              "ViewArea": { defaultValue: "CropBox", value: "CropBox", type: "name", explicitSet: false, valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"], pdfVersion: 1.4 },
+              "ViewClip": { defaultValue: "CropBox", value: "CropBox", type: "name", explicitSet: false, valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"], pdfVersion: 1.4 },
+              "PrintArea": { defaultValue: "CropBox", value: "CropBox", type: "name", explicitSet: false, valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"], pdfVersion: 1.4 },
+              "PrintClip": { defaultValue: "CropBox", value: "CropBox", type: "name", explicitSet: false, valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"], pdfVersion: 1.4 },
+              "PrintScaling": { defaultValue: "AppDefault", value: "AppDefault", type: "name", explicitSet: false, valueSet: ["AppDefault", "None"], pdfVersion: 1.6 },
+              "Duplex": { defaultValue: "", value: "none", type: "name", explicitSet: false, valueSet: ["Simplex", "DuplexFlipShortEdge", "DuplexFlipLongEdge", "none"], pdfVersion: 1.7 },
+              "PickTrayByPDFSize": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.7 },
+              "PrintPageRange": { defaultValue: "", value: "", type: "array", explicitSet: false, valueSet: null, pdfVersion: 1.7 },
+              "NumCopies": { defaultValue: 1, value: 1, type: "integer", explicitSet: false, valueSet: null, pdfVersion: 1.7 }
+          };
+
+          var configurationKeys = Object.keys(configurationTemplate);
+
+          var rangeArray = [];
+          var i = 0;
+          var j = 0;
+          var k = 0;
+          var isValid = true;
+
+          var method;
+          var value;
+
+          function arrayContainsElement(array, element) {
+              var iterator;
+              var result = false;
+
+              for (iterator = 0; iterator < array.length; iterator += 1) {
+                  if (array[iterator] === element) {
+                      result = true;
+                  }
+              }
+              return result;
+          }
+
+          if (this.internal.viewerpreferences === undefined) {
+              this.internal.viewerpreferences = {};
+              this.internal.viewerpreferences.configuration = JSON.parse(JSON.stringify(configurationTemplate));
+              this.internal.viewerpreferences.isSubscribed = false;
+          }
+          configuration = this.internal.viewerpreferences.configuration;
+
+          if (options === "reset" || doReset === true) {
+              var len = configurationKeys.length;
+
+              for (k = 0; k < len; k += 1) {
+                  configuration[configurationKeys[k]].value = configuration[configurationKeys[k]].defaultValue;
+                  configuration[configurationKeys[k]].explicitSet = false;
+              }
+          }
+
+          if ((typeof options === "undefined" ? "undefined" : _typeof(options)) === "object") {
+              for (method in options) {
+                  value = options[method];
+                  if (arrayContainsElement(configurationKeys, method) && value !== undefined) {
+
+                      if (configuration[method].type === "boolean" && typeof value === "boolean") {
+                          configuration[method].value = value;
+                      } else if (configuration[method].type === "name" && arrayContainsElement(configuration[method].valueSet, value)) {
+                          configuration[method].value = value;
+                      } else if (configuration[method].type === "integer" && Number.isInteger(value)) {
+                          configuration[method].value = value;
+                      } else if (configuration[method].type === "array") {
+
+                          for (i = 0; i < value.length; i += 1) {
+                              isValid = true;
+                              if (value[i].length === 1 && typeof value[i][0] === "number") {
+                                  rangeArray.push(String(value[i]));
+                              } else if (value[i].length > 1) {
+                                  for (j = 0; j < value[i].length; j += 1) {
+                                      if (typeof value[i][j] !== "number") {
+                                          isValid = false;
+                                      }
+                                  }
+                                  if (isValid === true) {
+                                      rangeArray.push(String(value[i].join("-")));
+                                  }
+                              }
+                          }
+                          configuration[method].value = String(rangeArray);
+                      } else {
+                          configuration[method].value = configuration[method].defaultValue;
+                      }
+
+                      configuration[method].explicitSet = true;
+                  }
+              }
+          }
+
+          if (this.internal.viewerpreferences.isSubscribed === false) {
+              this.internal.events.subscribe("putCatalog", function () {
+                  var pdfDict = [];
+                  var vPref;
+                  for (vPref in configuration) {
+                      if (configuration[vPref].explicitSet === true) {
+                          if (configuration[vPref].type === "name") {
+                              pdfDict.push("/" + vPref + " /" + configuration[vPref].value);
+                          } else {
+                              pdfDict.push("/" + vPref + " " + configuration[vPref].value);
+                          }
+                      }
+                  }
+                  if (pdfDict.length !== 0) {
+                      this.internal.write("/ViewerPreferences\n<<\n" + pdfDict.join("\n") + "\n>>");
+                  }
+              });
+              this.internal.viewerpreferences.isSubscribed = true;
+          }
+
+          this.internal.viewerpreferences.configuration = configuration;
+          return this;
+      };
+  })(jsPDF.API);
+
+  /** ==================================================================== 
+   * jsPDF XMP metadata plugin
+   * Copyright (c) 2016 Jussi Utunen, u-jussi@suomi24.fi
+   * 
+   * 
+   * ====================================================================
+   */
+
+  /*global jsPDF */
+
+  /**
+  * Adds XMP formatted metadata to PDF
+  *
+  * @param {String} metadata The actual metadata to be added. The metadata shall be stored as XMP simple value. Note that if the metadata string contains XML markup characters "<", ">" or "&", those characters should be written using XML entities.
+  * @param {String} namespaceuri Sets the namespace URI for the metadata. Last character should be slash or hash.
+  * @function
+  * @returns {jsPDF}
+  * @methodOf jsPDF#
+  * @name addMetadata
+  */
+
+  (function (jsPDFAPI) {
+
+      var xmpmetadata = "";
+      var xmpnamespaceuri = "";
+      var metadata_object_number = "";
+
+      jsPDFAPI.addMetadata = function (metadata, namespaceuri) {
+          xmpnamespaceuri = namespaceuri || "http://jspdf.default.namespaceuri/"; //The namespace URI for an XMP name shall not be empty
+          xmpmetadata = metadata;
+          this.internal.events.subscribe('postPutResources', function () {
+              if (!xmpmetadata) {
+                  metadata_object_number = "";
+              } else {
+                  var xmpmeta_beginning = '<x:xmpmeta xmlns:x="adobe:ns:meta/">';
+                  var rdf_beginning = '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:jspdf="' + xmpnamespaceuri + '"><jspdf:metadata>';
+                  var rdf_ending = '</jspdf:metadata></rdf:Description></rdf:RDF>';
+                  var xmpmeta_ending = '</x:xmpmeta>';
+                  var utf8_xmpmeta_beginning = unescape(encodeURIComponent(xmpmeta_beginning));
+                  var utf8_rdf_beginning = unescape(encodeURIComponent(rdf_beginning));
+                  var utf8_metadata = unescape(encodeURIComponent(xmpmetadata));
+                  var utf8_rdf_ending = unescape(encodeURIComponent(rdf_ending));
+                  var utf8_xmpmeta_ending = unescape(encodeURIComponent(xmpmeta_ending));
+
+                  var total_len = utf8_rdf_beginning.length + utf8_metadata.length + utf8_rdf_ending.length + utf8_xmpmeta_beginning.length + utf8_xmpmeta_ending.length;
+
+                  metadata_object_number = this.internal.newObject();
+                  this.internal.write('<< /Type /Metadata /Subtype /XML /Length ' + total_len + ' >>');
+                  this.internal.write('stream');
+                  this.internal.write(utf8_xmpmeta_beginning + utf8_rdf_beginning + utf8_metadata + utf8_rdf_ending + utf8_xmpmeta_ending);
+                  this.internal.write('endstream');
+                  this.internal.write('endobj');
+              }
+          });
+          this.internal.events.subscribe('putCatalog', function () {
+              if (metadata_object_number) {
+                  this.internal.write('/Metadata ' + metadata_object_number + ' 0 R');
+              }
+          });
+          return this;
+      };
+  })(jsPDF.API);
+
+  (function (jsPDF, global) {
+
+      var jsPDFAPI = jsPDF.API;
+
+      var glyID = [0];
+      /**************************************************/
+      /* function : toHex                               */
+      /* comment : Replace str with a hex string.       */
+      /**************************************************/
+      function toHex(str) {
+          var hex = '';
+          for (var i = 0; i < str.length; i++) {
+              hex += '' + str.charCodeAt(i).toString(16);
+          }
+          return hex;
+      }
+
+      /***************************************************************************************************/
+      /* function : pdfEscape16                                                                          */
+      /* comment : The character id of a 2-byte string is converted to a hexadecimal number by obtaining */
+      /*   the corresponding glyph id and width, and then adding padding to the string.                  */
+      /***************************************************************************************************/
+      var pdfEscape16 = function pdfEscape16(text, font) {
+          var widths = font.metadata.Unicode.widths;        var padz = ["", "0", "00", "000", "0000"];
+          var ar = [""];
+          for (var i = 0, l = text.length, t; i < l; ++i) {
+              t = font.metadata.characterToGlyph(text.charCodeAt(i));
+              glyID.push(t);
+              if (widths.indexOf(t) == -1) {
+                  widths.push(t);
+                  widths.push([parseInt(font.metadata.widthOfGlyph(t), 10)]);
+              }
+              if (t == '0') {
+                  //Spaces are not allowed in cmap.
+                  return ar.join("");
+              } else {
+                  t = t.toString(16);
+                  ar.push(padz[4 - t.length], t);
+              }
+          }
+          return ar.join("");
+      };
+
+      var identityHFunction = function identityHFunction(font, out, newObject) {
+
+          if (font.metadata instanceof jsPDF.API.TTFFont && font.encoding === 'Identity-H') {
+              //Tag with Identity-H
+              var widths = font.metadata.Unicode.widths;
+              var data = font.metadata.subset.encode(glyID);
+              var pdfOutput = data;
+              var pdfOutput2 = "";
+              for (var i = 0; i < pdfOutput.length; i++) {
+                  pdfOutput2 += String.fromCharCode(pdfOutput[i]);
+              }
+              var fontTable = newObject();
+              out('<<');
+              out('/Length ' + pdfOutput2.length);
+              out('/Length1 ' + pdfOutput2.length);
+              out('>>');
+
+              out('stream');
+              out(pdfOutput2);
+              out('endstream');
+              out('endobj');
+
+              var fontDescriptor = newObject();
+              out('<<');
+              out('/Type /FontDescriptor');
+              out('/FontName /' + font.fontName);
+              out('/FontFile2 ' + fontTable + ' 0 R');
+              out('/FontBBox ' + jsPDF.API.PDFObject.convert(font.metadata.bbox));
+              out('/Flags ' + font.metadata.flags);
+              out('/StemV ' + font.metadata.stemV);
+              out('/ItalicAngle ' + font.metadata.italicAngle);
+              out('/Ascent ' + font.metadata.ascender);
+              out('/Descent ' + font.metadata.decender);
+              out('/CapHeight ' + font.metadata.capHeight);
+              out('>>');
+              out('endobj');
+
+              var DescendantFont = newObject();
+              out('<<');
+              out('/Type /Font');
+              out('/BaseFont /' + font.fontName);
+              out('/FontDescriptor ' + fontDescriptor + ' 0 R');
+              out('/W ' + jsPDF.API.PDFObject.convert(widths));
+              out('/CIDToGIDMap /Identity');
+              out('/DW 1000');
+              out('/Subtype /CIDFontType2');
+              out('/CIDSystemInfo');
+              out('<<');
+              out('/Supplement 0');
+              out('/Registry (Adobe)');
+              out('/Ordering (' + font.encoding + ')');
+              out('>>');
+              out('>>');
+              out('endobj');
+
+              font.objectNumber = newObject();
+              out('<<');
+              out('/Type /Font');
+              out('/Subtype /Type0');
+              out('/BaseFont /' + font.fontName);
+              out('/Encoding /' + font.encoding);
+              out('/DescendantFonts [' + DescendantFont + ' 0 R]');
+              out('>>');
+              out('endobj');
+
+              font.isAlreadyPutted = true;
+          }
+      };
+
+      jsPDFAPI.events.push(['putFont', function (args) {
+          identityHFunction(args.font, args.out, args.newObject);
+      }]);
+
+      var winAnsiEncodingFunction = function winAnsiEncodingFunction(font, out, newObject) {
+
+          if (font.metadata instanceof jsPDF.API.TTFFont && font.encoding === 'WinAnsiEncoding') {
+              //Tag with WinAnsi encoding
+              var widths = font.metadata.Unicode.widths;
+              var data = font.metadata.rawData;
+              var pdfOutput = data;
+              var pdfOutput2 = "";
+              for (var i = 0; i < pdfOutput.length; i++) {
+                  pdfOutput2 += String.fromCharCode(pdfOutput[i]);
+              }
+              var fontTable = newObject();
+              out('<<');
+              out('/Length ' + pdfOutput2.length);
+              out('/Length1 ' + pdfOutput2.length);
+              out('>>');
+              out('stream');
+              out(pdfOutput2);
+              out('endstream');
+              out('endobj');
+              var fontDescriptor = newObject();
+              out('<<');
+              out('/Descent ' + font.metadata.decender);
+              out('/CapHeight ' + font.metadata.capHeight);
+              out('/StemV ' + font.metadata.stemV);
+              out('/Type /FontDescriptor');
+              out('/FontFile2 ' + fontTable + ' 0 R');
+              out('/Flags 96');
+              out('/FontBBox ' + jsPDF.API.PDFObject.convert(font.metadata.bbox));
+              out('/FontName /' + font.fontName);
+              out('/ItalicAngle ' + font.metadata.italicAngle);
+              out('/Ascent ' + font.metadata.ascender);
+              out('>>');
+              out('endobj');
+              font.objectNumber = newObject();
+              for (var i = 0; i < font.metadata.hmtx.widths.length; i++) {
+                  font.metadata.hmtx.widths[i] = parseInt(font.metadata.hmtx.widths[i] * (1000 / font.metadata.head.unitsPerEm)); //Change the width of Em units to Point units.
+              }
+              out('<</Subtype/TrueType/Type/Font/BaseFont/' + font.fontName + '/FontDescriptor ' + fontDescriptor + ' 0 R' + '/Encoding/' + font.encoding + ' /FirstChar 29 /LastChar 255 /Widths ' + jsPDF.API.PDFObject.convert(font.metadata.hmtx.widths) + '>>');
+              out('endobj');
+              font.isAlreadyPutted = true;
+          }
+      };
+
+      jsPDFAPI.events.push(['putFont', function (args) {
+          winAnsiEncodingFunction(args.font, args.out, args.newObject);
+      }]);
+
+      var utf8TextFunction = function utf8TextFunction(args) {
+          var text = args.text;
+          var x = args.x;
+          var y = args.y;
+          var options = args.options || {};
+          var mutex = args.mutex || {};
+
+          var pdfEscape = mutex.pdfEscape;
+          var activeFontKey = mutex.activeFontKey;
+          var fonts = mutex.fonts;
+          var key,
+              fontSize = mutex.activeFontSize;
+
+          var str = '',
+              s = 0,
+              cmapConfirm;
+          var strText = '';
+          var attr;
+          var key = activeFontKey;
+          var encoding = fonts[key].encoding;
+
+          if (fonts[key].encoding !== 'Identity-H') {
+              return {
+                  text: text,
+                  x: x,
+                  y: y,
+                  options: options,
+                  mutex: mutex
+              };
+          }
+          strText = text;
+
+          key = attr ? getFont(attr.font, attr.fontStyle) : activeFontKey;
+          if (Object.prototype.toString.call(text) === '[object Array]') {
+              strText = text[0];
+          }
+          for (s = 0; s < strText.length; s += 1) {
+              if (fonts[key].metadata.hasOwnProperty('cmap')) {
+                  cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)];
+                  /*
+                  if (Object.prototype.toString.call(text) === '[object Array]') {
+                             var i = 0;
+                            // for (i = 0; i < text.length; i += 1) {
+                                 if (Object.prototype.toString.call(text[s]) === '[object Array]') {
+                  	cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s][0].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id
+                                 } else {
+                                     
+                                 }
+                             //}
+                  
+                         } else {
+                  cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id
+                         }*/
+              }
+              if (!cmapConfirm) {
+                  if (strText[s].charCodeAt(0) < 256 && fonts[key].metadata.hasOwnProperty('Unicode')) {
+                      str += strText[s];
+                  } else {
+                      str += '';
+                  }
+              } else {
+                  str += strText[s];
+              }
+          }
+          var result = '';
+          if (parseInt(key.slice(1)) < 14 || encoding === 'WinAnsiEncoding') {
+              //For the default 13 font
+              result = toHex(pdfEscape(str, key));
+          } else if (encoding === 'Identity-H') {
+              result = pdfEscape16(str, fonts[key]);
+          }
+          mutex.isHex = true;
+
+          return {
+              text: result,
+              x: x,
+              y: y,
+              options: options,
+              mutex: mutex
+          };
+      };
+
+      var utf8EscapeFunction = function utf8EscapeFunction(parms) {
+          var text = parms.text,
+              x = parms.x,
+              y = parms.y,
+              options = parms.options,
+              mutex = parms.mutex;
+          var lang = options.lang;
+          var tmpText = [];
+          var args = {
+              text: text,
+              x: x,
+              y: y,
+              options: options,
+              mutex: mutex
+          };
+
+          if (Object.prototype.toString.call(text) === '[object Array]') {
+              var i = 0;
+              for (i = 0; i < text.length; i += 1) {
+                  if (Object.prototype.toString.call(text[i]) === '[object Array]') {
+                      if (text[i].length === 3) {
+                          tmpText.push([utf8TextFunction(Object.assign({}, args, { text: text[i][0] })).text, text[i][1], text[i][2]]);
+                      } else {
+                          tmpText.push(utf8TextFunction(Object.assign({}, args, { text: text[i] })).text);
+                      }
+                  } else {
+                      tmpText.push(utf8TextFunction(Object.assign({}, args, { text: text[i] })).text);
+                  }
+              }
+              parms.text = tmpText;
+          } else {
+              parms.text = utf8TextFunction(Object.assign({}, args, { text: text })).text;
+          }
+      };
+
+      jsPDFAPI.events.push(['postProcessText', utf8EscapeFunction]);
+  })(jsPDF, typeof self !== "undefined" && self || typeof global !== "undefined" && global || typeof window !== "undefined" && window || Function("return this")());
+
+  /**
+   * jsPDF virtual FileSystem functionality
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+
+  /**
+  * Use the vFS to handle files
+  */
+
+  (function (jsPDFAPI) {
+
+      var vFS = {};
+
+      /* Check if the file exists in the vFS
+      * @returns {boolean}
+      * @name existsFileInVFS
+      * @example
+      * doc.existsFileInVFS("someFile.txt");
+      */
+      jsPDFAPI.existsFileInVFS = function (filename) {
+          return vFS.hasOwnProperty(filename);
+      };
+
+      /* Add a file to the vFS
+      * @returns {jsPDF}
+      * @name addFileToVFS
+      * @example
+      * doc.addFileToVFS("someFile.txt", "BADFACE1");
+      */
+      jsPDFAPI.addFileToVFS = function (filename, filecontent) {
+          vFS[filename] = filecontent;
+          return this;
+      };
+
+      /* Get the file from the vFS
+      * @returns {string}
+      * @name addFileToVFS
+      * @example
+      * doc.getFileFromVFS("someFile.txt");
+      */
+      jsPDFAPI.getFileFromVFS = function (filename) {
+          if (vFS.hasOwnProperty(filename)) {
+              return vFS[filename];
+          }
+          return null;
+      };
+  })(jsPDF.API);
+
+  /* Blob.js
+   * A Blob implementation.
+   * 2014-07-24
+   *
+   * By Eli Grey, http://eligrey.com
+   * By Devin Samarin, https://github.com/dsamarin
+   * License: X11/MIT
+   *   See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md
+   */
+
+  /*global self, unescape */
+  /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
+    plusplus: true */
+
+  /*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
+
+  (function (view) {
+
+  	view.URL = view.URL || view.webkitURL;
+
+  	if (view.Blob && view.URL) {
+  		try {
+  			new Blob;
+  			return;
+  		} catch (e) {}
+  	}
+
+  	// Internally we use a BlobBuilder implementation to base Blob off of
+  	// in order to support older browsers that only have BlobBuilder
+  	var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) {
+  		var
+  			  get_class = function(object) {
+  				return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
+  			}
+  			, FakeBlobBuilder = function BlobBuilder() {
+  				this.data = [];
+  			}
+  			, FakeBlob = function Blob(data, type, encoding) {
+  				this.data = data;
+  				this.size = data.length;
+  				this.type = type;
+  				this.encoding = encoding;
+  			}
+  			, FBB_proto = FakeBlobBuilder.prototype
+  			, FB_proto = FakeBlob.prototype
+  			, FileReaderSync = view.FileReaderSync
+  			, FileException = function(type) {
+  				this.code = this[this.name = type];
+  			}
+  			, file_ex_codes = (
+  				  "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
+  				+ "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
+  			).split(" ")
+  			, file_ex_code = file_ex_codes.length
+  			, real_URL = view.URL || view.webkitURL || view
+  			, real_create_object_URL = real_URL.createObjectURL
+  			, real_revoke_object_URL = real_URL.revokeObjectURL
+  			, URL = real_URL
+  			, btoa = view.btoa
+  			, atob = view.atob
+
+  			, ArrayBuffer = view.ArrayBuffer
+  			, Uint8Array = view.Uint8Array
+
+  			, origin = /^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/
+  		;
+  		FakeBlob.fake = FB_proto.fake = true;
+  		while (file_ex_code--) {
+  			FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
+  		}
+  		// Polyfill URL
+  		if (!real_URL.createObjectURL) {
+  			URL = view.URL = function(uri) {
+  				var
+  					  uri_info = document.createElementNS("http://www.w3.org/1999/xhtml", "a")
+  					, uri_origin
+  				;
+  				uri_info.href = uri;
+  				if (!("origin" in uri_info)) {
+  					if (uri_info.protocol.toLowerCase() === "data:") {
+  						uri_info.origin = null;
+  					} else {
+  						uri_origin = uri.match(origin);
+  						uri_info.origin = uri_origin && uri_origin[1];
+  					}
+  				}
+  				return uri_info;
+  			};
+  		}
+  		URL.createObjectURL = function(blob) {
+  			var
+  				  type = blob.type
+  				, data_URI_header
+  			;
+  			if (type === null) {
+  				type = "application/octet-stream";
+  			}
+  			if (blob instanceof FakeBlob) {
+  				data_URI_header = "data:" + type;
+  				if (blob.encoding === "base64") {
+  					return data_URI_header + ";base64," + blob.data;
+  				} else if (blob.encoding === "URI") {
+  					return data_URI_header + "," + decodeURIComponent(blob.data);
+  				} if (btoa) {
+  					return data_URI_header + ";base64," + btoa(blob.data);
+  				} else {
+  					return data_URI_header + "," + encodeURIComponent(blob.data);
+  				}
+  			} else if (real_create_object_URL) {
+  				return real_create_object_URL.call(real_URL, blob);
+  			}
+  		};
+  		URL.revokeObjectURL = function(object_URL) {
+  			if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
+  				real_revoke_object_URL.call(real_URL, object_URL);
+  			}
+  		};
+  		FBB_proto.append = function(data/*, endings*/) {
+  			var bb = this.data;
+  			// decode data to a binary string
+  			if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
+  				var
+  					  str = ""
+  					, buf = new Uint8Array(data)
+  					, i = 0
+  					, buf_len = buf.length
+  				;
+  				for (; i < buf_len; i++) {
+  					str += String.fromCharCode(buf[i]);
+  				}
+  				bb.push(str);
+  			} else if (get_class(data) === "Blob" || get_class(data) === "File") {
+  				if (FileReaderSync) {
+  					var fr = new FileReaderSync;
+  					bb.push(fr.readAsBinaryString(data));
+  				} else {
+  					// async FileReader won't work as BlobBuilder is sync
+  					throw new FileException("NOT_READABLE_ERR");
+  				}
+  			} else if (data instanceof FakeBlob) {
+  				if (data.encoding === "base64" && atob) {
+  					bb.push(atob(data.data));
+  				} else if (data.encoding === "URI") {
+  					bb.push(decodeURIComponent(data.data));
+  				} else if (data.encoding === "raw") {
+  					bb.push(data.data);
+  				}
+  			} else {
+  				if (typeof data !== "string") {
+  					data += ""; // convert unsupported types to strings
+  				}
+  				// decode UTF-16 to binary string
+  				bb.push(unescape(encodeURIComponent(data)));
+  			}
+  		};
+  		FBB_proto.getBlob = function(type) {
+  			if (!arguments.length) {
+  				type = null;
+  			}
+  			return new FakeBlob(this.data.join(""), type, "raw");
+  		};
+  		FBB_proto.toString = function() {
+  			return "[object BlobBuilder]";
+  		};
+  		FB_proto.slice = function(start, end, type) {
+  			var args = arguments.length;
+  			if (args < 3) {
+  				type = null;
+  			}
+  			return new FakeBlob(
+  				  this.data.slice(start, args > 1 ? end : this.data.length)
+  				, type
+  				, this.encoding
+  			);
+  		};
+  		FB_proto.toString = function() {
+  			return "[object Blob]";
+  		};
+  		FB_proto.close = function() {
+  			this.size = 0;
+  			delete this.data;
+  		};
+  		return FakeBlobBuilder;
+  	}(view));
+
+  	view.Blob = function(blobParts, options) {
+  		var type = options ? (options.type || "") : "";
+  		var builder = new BlobBuilder();
+  		if (blobParts) {
+  			for (var i = 0, len = blobParts.length; i < len; i++) {
+  				if (Uint8Array && blobParts[i] instanceof Uint8Array) {
+  					builder.append(blobParts[i].buffer);
+  				}
+  				else {
+  					builder.append(blobParts[i]);
+  				}
+  			}
+  		}
+  		var blob = builder.getBlob(type);
+  		if (!blob.slice && blob.webkitSlice) {
+  			blob.slice = blob.webkitSlice;
+  		}
+  		return blob;
+  	};
+
+  	var getPrototypeOf = Object.getPrototypeOf || function(object) {
+  		return object.__proto__;
+  	};
+  	view.Blob.prototype = getPrototypeOf(new view.Blob());
+  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || window.content || window));
+
+  /* FileSaver.js
+   * A saveAs() FileSaver implementation.
+   * 1.3.2
+   * 2016-06-16 18:25:19
+   *
+   * By Eli Grey, http://eligrey.com
+   * License: MIT
+   *   See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
+   */
+
+  /*global self */
+  /*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
+
+  /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
+
+  var saveAs = saveAs || (function(view) {
+  	// IE <10 is explicitly unsupported
+  	if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
+  		return;
+  	}
+  	var
+  		  doc = view.document
+  		  // only get URL when necessary in case Blob.js hasn't overridden it yet
+  		, get_URL = function() {
+  			return view.URL || view.webkitURL || view;
+  		}
+  		, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
+  		, can_use_save_link = "download" in save_link
+  		, click = function(node) {
+  			var event = new MouseEvent("click");
+  			node.dispatchEvent(event);
+  		}
+  		, is_safari = /constructor/i.test(view.HTMLElement) || view.safari
+  		, is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent)
+  		, throw_outside = function(ex) {
+  			(view.setImmediate || view.setTimeout)(function() {
+  				throw ex;
+  			}, 0);
+  		}
+  		, force_saveable_type = "application/octet-stream"
+  		// the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
+  		, arbitrary_revoke_timeout = 1000 * 40 // in ms
+  		, revoke = function(file) {
+  			var revoker = function() {
+  				if (typeof file === "string") { // file is an object URL
+  					get_URL().revokeObjectURL(file);
+  				} else { // file is a File
+  					file.remove();
+  				}
+  			};
+  			setTimeout(revoker, arbitrary_revoke_timeout);
+  		}
+  		, dispatch = function(filesaver, event_types, event) {
+  			event_types = [].concat(event_types);
+  			var i = event_types.length;
+  			while (i--) {
+  				var listener = filesaver["on" + event_types[i]];
+  				if (typeof listener === "function") {
+  					try {
+  						listener.call(filesaver, event || filesaver);
+  					} catch (ex) {
+  						throw_outside(ex);
+  					}
+  				}
+  			}
+  		}
+  		, auto_bom = function(blob) {
+  			// prepend BOM for UTF-8 XML and text/* types (including HTML)
+  			// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
+  			if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
+  				return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type});
+  			}
+  			return blob;
+  		}
+  		, FileSaver = function(blob, name, no_auto_bom) {
+  			if (!no_auto_bom) {
+  				blob = auto_bom(blob);
+  			}
+  			// First try a.download, then web filesystem, then object URLs
+  			var
+  				  filesaver = this
+  				, type = blob.type
+  				, force = type === force_saveable_type
+  				, object_url
+  				, dispatch_all = function() {
+  					dispatch(filesaver, "writestart progress write writeend".split(" "));
+  				}
+  				// on any filesys errors revert to saving with object URLs
+  				, fs_error = function() {
+  					if ((is_chrome_ios || (force && is_safari)) && view.FileReader) {
+  						// Safari doesn't allow downloading of blob urls
+  						var reader = new FileReader();
+  						reader.onloadend = function() {
+  							var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');
+  							var popup = view.open(url, '_blank');
+  							if(!popup) view.location.href = url;
+  							url=undefined; // release reference before dispatching
+  							filesaver.readyState = filesaver.DONE;
+  							dispatch_all();
+  						};
+  						reader.readAsDataURL(blob);
+  						filesaver.readyState = filesaver.INIT;
+  						return;
+  					}
+  					// don't create more object URLs than needed
+  					if (!object_url) {
+  						object_url = get_URL().createObjectURL(blob);
+  					}
+  					if (force) {
+  						view.location.href = object_url;
+  					} else {
+  						var opened = view.open(object_url, "_blank");
+  						if (!opened) {
+  							// Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
+  							view.location.href = object_url;
+  						}
+  					}
+  					filesaver.readyState = filesaver.DONE;
+  					dispatch_all();
+  					revoke(object_url);
+  				}
+  			;
+  			filesaver.readyState = filesaver.INIT;
+
+  			if (can_use_save_link) {
+  				object_url = get_URL().createObjectURL(blob);
+  				setTimeout(function() {
+  					save_link.href = object_url;
+  					save_link.download = name;
+  					click(save_link);
+  					dispatch_all();
+  					revoke(object_url);
+  					filesaver.readyState = filesaver.DONE;
+  				});
+  				return;
+  			}
+
+  			fs_error();
+  		}
+  		, FS_proto = FileSaver.prototype
+  		, saveAs = function(blob, name, no_auto_bom) {
+  			return new FileSaver(blob, name || blob.name || "download", no_auto_bom);
+  		}
+  	;
+  	// IE 10+ (native saveAs)
+  	if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
+  		return function(blob, name, no_auto_bom) {
+  			name = name || blob.name || "download";
+
+  			if (!no_auto_bom) {
+  				blob = auto_bom(blob);
+  			}
+  			return navigator.msSaveOrOpenBlob(blob, name);
+  		};
+  	}
+
+  	FS_proto.abort = function(){};
+  	FS_proto.readyState = FS_proto.INIT = 0;
+  	FS_proto.WRITING = 1;
+  	FS_proto.DONE = 2;
+
+  	FS_proto.error =
+  	FS_proto.onwritestart =
+  	FS_proto.onprogress =
+  	FS_proto.onwrite =
+  	FS_proto.onabort =
+  	FS_proto.onerror =
+  	FS_proto.onwriteend =
+  		null;
+
+  	return saveAs;
+  }(
+  	   typeof self !== "undefined" && self
+  	|| typeof window !== "undefined" && window
+  	|| window.content
+  ));
+  // `self` is undefined in Firefox for Android content script context
+  // while `this` is nsIContentFrameMessageManager
+  // with an attribute `content` that corresponds to the window
+
+  if (typeof module !== "undefined" && module.exports) {
+    module.exports.saveAs = saveAs;
+  } else if ((typeof define !== "undefined" && define !== null) && (define.amd !== null)) {
+    define("FileSaver.js", function() {
+      return saveAs;
+    });
+  }
+
+  /*
+   * Copyright (c) 2012 chick307 <chick307@gmail.com>
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+
+  (function(jsPDF, callback) {
+    jsPDF.API.adler32cs = callback();
+  })(jsPDF, function() {
+    var _hasArrayBuffer = typeof ArrayBuffer === 'function' &&
+      typeof Uint8Array === 'function';
+
+    var _Buffer = null, _isBuffer = (function() {
+      if (!_hasArrayBuffer)
+        return function _isBuffer() { return false };
+
+      try {
+        var buffer = {};
+        if (typeof buffer.Buffer === 'function')
+          _Buffer = buffer.Buffer;
+      } catch (error) {}
+
+      return function _isBuffer(value) {
+        return value instanceof ArrayBuffer ||
+          _Buffer !== null && value instanceof _Buffer;
+      };
+    }());
+
+    var _utf8ToBinary = (function() {
+      if (_Buffer !== null) {
+        return function _utf8ToBinary(utf8String) {
+          return new _Buffer(utf8String, 'utf8').toString('binary');
+        };
+      } else {
+        return function _utf8ToBinary(utf8String) {
+          return unescape(encodeURIComponent(utf8String));
+        };
+      }
+    }());
+
+    var MOD = 65521;
+
+    var _update = function _update(checksum, binaryString) {
+      var a = checksum & 0xFFFF, b = checksum >>> 16;
+      for (var i = 0, length = binaryString.length; i < length; i++) {
+        a = (a + (binaryString.charCodeAt(i) & 0xFF)) % MOD;
+        b = (b + a) % MOD;
+      }
+      return (b << 16 | a) >>> 0;
+    };
+
+    var _updateUint8Array = function _updateUint8Array(checksum, uint8Array) {
+      var a = checksum & 0xFFFF, b = checksum >>> 16;
+      for (var i = 0, length = uint8Array.length; i < length; i++) {
+        a = (a + uint8Array[i]) % MOD;
+        b = (b + a) % MOD;
+      }
+      return (b << 16 | a) >>> 0
+    };
+
+    var exports = {};
+
+    var Adler32 = exports.Adler32 = (function() {
+      var ctor = function Adler32(checksum) {
+        if (!(this instanceof ctor)) {
+          throw new TypeError(
+            'Constructor cannot called be as a function.');
+        }
+        if (!isFinite(checksum = checksum == null ? 1 : +checksum)) {
+          throw new Error(
+            'First arguments needs to be a finite number.');
+        }
+        this.checksum = checksum >>> 0;
+      };
+
+      var proto = ctor.prototype = {};
+      proto.constructor = ctor;
+
+      ctor.from = function(from) {
+        from.prototype = proto;
+        return from;
+      }(function from(binaryString) {
+        if (!(this instanceof ctor)) {
+          throw new TypeError(
+            'Constructor cannot called be as a function.');
+        }
+        if (binaryString == null)
+          throw new Error('First argument needs to be a string.');
+        this.checksum = _update(1, binaryString.toString());
+      });
+
+      ctor.fromUtf8 = function(fromUtf8) {
+        fromUtf8.prototype = proto;
+        return fromUtf8;
+      }(function fromUtf8(utf8String) {
+        if (!(this instanceof ctor)) {
+          throw new TypeError(
+            'Constructor cannot called be as a function.');
+        }
+        if (utf8String == null)
+          throw new Error('First argument needs to be a string.');
+        var binaryString = _utf8ToBinary(utf8String.toString());
+        this.checksum = _update(1, binaryString);
+      });
+
+      if (_hasArrayBuffer) {
+        ctor.fromBuffer = function(fromBuffer) {
+          fromBuffer.prototype = proto;
+          return fromBuffer;
+        }(function fromBuffer(buffer) {
+          if (!(this instanceof ctor)) {
+            throw new TypeError(
+              'Constructor cannot called be as a function.');
+          }
+          if (!_isBuffer(buffer))
+            throw new Error('First argument needs to be ArrayBuffer.');
+          var array = new Uint8Array(buffer);
+          return this.checksum = _updateUint8Array(1, array);
+        });
+      }
+
+      proto.update = function update(binaryString) {
+        if (binaryString == null)
+          throw new Error('First argument needs to be a string.');
+        binaryString = binaryString.toString();
+        return this.checksum = _update(this.checksum, binaryString);
+      };
+
+      proto.updateUtf8 = function updateUtf8(utf8String) {
+        if (utf8String == null)
+          throw new Error('First argument needs to be a string.');
+        var binaryString = _utf8ToBinary(utf8String.toString());
+        return this.checksum = _update(this.checksum, binaryString);
+      };
+
+      if (_hasArrayBuffer) {
+        proto.updateBuffer = function updateBuffer(buffer) {
+          if (!_isBuffer(buffer))
+            throw new Error('First argument needs to be ArrayBuffer.');
+          var array = new Uint8Array(buffer);
+          return this.checksum = _updateUint8Array(this.checksum, array);
+        };
+      }
+
+      proto.clone = function clone() {
+        return new Adler32(this.checksum);
+      };
+
+      return ctor;
+    }());
+
+    exports.from = function from(binaryString) {
+      if (binaryString == null)
+        throw new Error('First argument needs to be a string.');
+      return _update(1, binaryString.toString());
+    };
+
+    exports.fromUtf8 = function fromUtf8(utf8String) {
+      if (utf8String == null)
+        throw new Error('First argument needs to be a string.');
+      var binaryString = _utf8ToBinary(utf8String.toString());
+      return _update(1, binaryString);
+    };
+
+    if (_hasArrayBuffer) {
+      exports.fromBuffer = function fromBuffer(buffer) {
+        if (!_isBuffer(buffer))
+          throw new Error('First argument need to be ArrayBuffer.');
+        var array = new Uint8Array(buffer);
+        return _updateUint8Array(1, array);
+      };
+    }
+
+    return exports;
+  });
+
+  /*
+   Copyright (c) 2013 Gildas Lormeau. All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the distribution.
+
+   3. The names of the authors may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+   INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+   OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+   EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+   */
+
+  /*
+   * This program is based on JZlib 1.0.2 ymnk, JCraft,Inc.
+   * JZlib is based on zlib-1.1.3, so all credit should go authors
+   * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+   * and contributors of zlib.
+   */
+
+  (function(global) {
+
+  	// Global
+
+  	var MAX_BITS = 15;
+  	var D_CODES = 30;
+  	var BL_CODES = 19;
+
+  	var LENGTH_CODES = 29;
+  	var LITERALS = 256;
+  	var L_CODES = (LITERALS + 1 + LENGTH_CODES);
+  	var HEAP_SIZE = (2 * L_CODES + 1);
+
+  	var END_BLOCK = 256;
+
+  	// Bit length codes must not exceed MAX_BL_BITS bits
+  	var MAX_BL_BITS = 7;
+
+  	// repeat previous bit length 3-6 times (2 bits of repeat count)
+  	var REP_3_6 = 16;
+
+  	// repeat a zero length 3-10 times (3 bits of repeat count)
+  	var REPZ_3_10 = 17;
+
+  	// repeat a zero length 11-138 times (7 bits of repeat count)
+  	var REPZ_11_138 = 18;
+
+  	// The lengths of the bit length codes are sent in order of decreasing
+  	// probability, to avoid transmitting the lengths for unused bit
+  	// length codes.
+
+  	var Buf_size = 8 * 2;
+
+  	// JZlib version : "1.0.2"
+  	var Z_DEFAULT_COMPRESSION = -1;
+
+  	// compression strategy
+  	var Z_FILTERED = 1;
+  	var Z_HUFFMAN_ONLY = 2;
+  	var Z_DEFAULT_STRATEGY = 0;
+
+  	var Z_NO_FLUSH = 0;
+  	var Z_PARTIAL_FLUSH = 1;
+  	var Z_FULL_FLUSH = 3;
+  	var Z_FINISH = 4;
+
+  	var Z_OK = 0;
+  	var Z_STREAM_END = 1;
+  	var Z_NEED_DICT = 2;
+  	var Z_STREAM_ERROR = -2;
+  	var Z_DATA_ERROR = -3;
+  	var Z_BUF_ERROR = -5;
+
+  	// Tree
+
+  	// see definition of array dist_code below
+  	var _dist_code = [ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  			10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  			12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  			13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  			14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  			14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  			15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 18, 18, 19, 19,
+  			20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+  			24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+  			26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+  			27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+  			28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29,
+  			29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+  			29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 ];
+
+  	function Tree() {
+  		var that = this;
+
+  		// dyn_tree; // the dynamic tree
+  		// max_code; // largest code with non zero frequency
+  		// stat_desc; // the corresponding static tree
+
+  		// 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) {
+  			var tree = that.dyn_tree;
+  			var stree = that.stat_desc.static_tree;
+  			var extra = that.stat_desc.extra_bits;
+  			var base = that.stat_desc.extra_base;
+  			var max_length = that.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] = 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] * 2 + 1] + 1;
+  				if (bits > max_length) {
+  					bits = max_length;
+  					overflow++;
+  				}
+  				tree[n * 2 + 1] = bits;
+  				// We overwrite tree[n*2+1] which is no longer needed
+
+  				if (n > that.max_code)
+  					continue; // not a leaf node
+
+  				s.bl_count[bits]++;
+  				xbits = 0;
+  				if (n >= base)
+  					xbits = extra[n - base];
+  				f = tree[n * 2];
+  				s.opt_len += f * (bits + xbits);
+  				if (stree)
+  					s.static_len += f * (stree[n * 2 + 1] + xbits);
+  			}
+  			if (overflow === 0)
+  				return;
+
+  			// 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);
+
+  			for (bits = max_length; bits !== 0; bits--) {
+  				n = s.bl_count[bits];
+  				while (n !== 0) {
+  					m = s.heap[--h];
+  					if (m > that.max_code)
+  						continue;
+  					if (tree[m * 2 + 1] != bits) {
+  						s.opt_len += (bits - tree[m * 2 + 1]) * tree[m * 2];
+  						tree[m * 2 + 1] = bits;
+  					}
+  					n--;
+  				}
+  			}
+  		}
+
+  		// 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, // the value to invert
+  		len // its bit length
+  		) {
+  			var res = 0;
+  			do {
+  				res |= code & 1;
+  				code >>>= 1;
+  				res <<= 1;
+  			} while (--len > 0);
+  			return res >>> 1;
+  		}
+
+  		// 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, // the tree to decorate
+  		max_code, // largest code with non zero frequency
+  		bl_count // number of codes at each bit length
+  		) {
+  			var next_code = []; // next code value for each
+  			// bit length
+  			var code = 0; // running code value
+  			var bits; // bit index
+  			var n; // code index
+  			var len;
+
+  			// 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++) {
+  				len = tree[n * 2 + 1];
+  				if (len === 0)
+  					continue;
+  				// Now reverse the bits
+  				tree[n * 2] = bi_reverse(next_code[len]++, len);
+  			}
+  		}
+
+  		// 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.
+  		that.build_tree = function(s) {
+  			var tree = that.dyn_tree;
+  			var stree = that.stat_desc.static_tree;
+  			var elems = that.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[1]. 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] !== 0) {
+  					s.heap[++s.heap_len] = max_code = n;
+  					s.depth[n] = 0;
+  				} else {
+  					tree[n * 2 + 1] = 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] = 1;
+  				s.depth[node] = 0;
+  				s.opt_len--;
+  				if (stree)
+  					s.static_len -= stree[node * 2 + 1];
+  				// node is 0 or 1 so it does not have extra bits
+  			}
+  			that.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 = Math.floor(s.heap_len / 2); n >= 1; n--)
+  				s.pqdownheap(tree, n);
+
+  			// Construct the Huffman tree by repeatedly combining the least two
+  			// frequent nodes.
+
+  			node = elems; // next internal node of the tree
+  			do {
+  				// n = node of least frequency
+  				n = s.heap[1];
+  				s.heap[1] = s.heap[s.heap_len--];
+  				s.pqdownheap(tree, 1);
+  				m = s.heap[1]; // 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] = (tree[n * 2] + tree[m * 2]);
+  				s.depth[node] = Math.max(s.depth[n], s.depth[m]) + 1;
+  				tree[n * 2 + 1] = tree[m * 2 + 1] = node;
+
+  				// and insert the new node in the heap
+  				s.heap[1] = node++;
+  				s.pqdownheap(tree, 1);
+  			} while (s.heap_len >= 2);
+
+  			s.heap[--s.heap_max] = s.heap[1];
+
+  			// At this point, the fields freq and dad are set. We can now
+  			// generate the bit lengths.
+
+  			gen_bitlen(s);
+
+  			// The field len is now set, we can generate the bit codes
+  			gen_codes(tree, that.max_code, s.bl_count);
+  		};
+
+  	}
+
+  	Tree._length_code = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16,
+  			16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+  			20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+  			22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+  			24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+  			25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+  			26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 ];
+
+  	Tree.base_length = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0 ];
+
+  	Tree.base_dist = [ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384,
+  			24576 ];
+
+  	// Mapping from a distance to a distance code. dist is the distance - 1 and
+  	// must not have side effects. _dist_code[256] and _dist_code[257] are never
+  	// used.
+  	Tree.d_code = function(dist) {
+  		return ((dist) < 256 ? _dist_code[dist] : _dist_code[256 + ((dist) >>> 7)]);
+  	};
+
+  	// extra bits for each length code
+  	Tree.extra_lbits = [ 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 ];
+
+  	// extra bits for each distance code
+  	Tree.extra_dbits = [ 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 ];
+
+  	// extra bits for each bit length code
+  	Tree.extra_blbits = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 ];
+
+  	Tree.bl_order = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
+
+  	// StaticTree
+
+  	function StaticTree(static_tree, extra_bits, extra_base, elems, max_length) {
+  		var that = this;
+  		that.static_tree = static_tree;
+  		that.extra_bits = extra_bits;
+  		that.extra_base = extra_base;
+  		that.elems = elems;
+  		that.max_length = max_length;
+  	}
+
+  	StaticTree.static_ltree = [ 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8, 2, 8,
+  			130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, 202, 8, 42,
+  			8, 170, 8, 106, 8, 234, 8, 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, 230, 8,
+  			22, 8, 150, 8, 86, 8, 214, 8, 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, 110, 8, 238, 8, 30, 8, 158, 8, 94, 8,
+  			222, 8, 62, 8, 190, 8, 126, 8, 254, 8, 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, 81, 8, 209, 8, 49, 8, 177, 8, 113,
+  			8, 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, 121, 8, 249, 8, 5, 8, 133, 8,
+  			69, 8, 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, 77, 8, 205, 8, 45, 8,
+  			173, 8, 109, 8, 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, 211, 9, 467, 9,
+  			51, 9, 307, 9, 179, 9, 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, 171, 9,
+  			427, 9, 107, 9, 363, 9, 235, 9, 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, 315, 9, 187, 9, 443, 9, 123, 9, 379,
+  			9, 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, 359, 9, 231, 9, 487, 9, 23,
+  			9, 279, 9, 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, 271, 9, 143, 9,
+  			399, 9, 79, 9, 335, 9, 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, 351, 9,
+  			223, 9, 479, 9, 63, 9, 319, 9, 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, 511, 9, 0, 7, 64, 7, 32, 7, 96, 7, 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, 72, 7,
+  			40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8,
+  			99, 8, 227, 8 ];
+
+  	StaticTree.static_dtree = [ 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5, 1, 5, 17, 5, 9, 5,
+  			25, 5, 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 ];
+
+  	StaticTree.static_l_desc = new StaticTree(StaticTree.static_ltree, Tree.extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);
+
+  	StaticTree.static_d_desc = new StaticTree(StaticTree.static_dtree, Tree.extra_dbits, 0, D_CODES, MAX_BITS);
+
+  	StaticTree.static_bl_desc = new StaticTree(null, Tree.extra_blbits, 0, BL_CODES, MAX_BL_BITS);
+
+  	// Deflate
+
+  	var MAX_MEM_LEVEL = 9;
+  	var DEF_MEM_LEVEL = 8;
+
+  	function Config(good_length, max_lazy, nice_length, max_chain, func) {
+  		var that = this;
+  		that.good_length = good_length;
+  		that.max_lazy = max_lazy;
+  		that.nice_length = nice_length;
+  		that.max_chain = max_chain;
+  		that.func = func;
+  	}
+
+  	var STORED = 0;
+  	var FAST = 1;
+  	var SLOW = 2;
+  	var config_table = [ new Config(0, 0, 0, 0, STORED), new Config(4, 4, 8, 4, FAST), new Config(4, 5, 16, 8, FAST), new Config(4, 6, 32, 32, FAST),
+  			new Config(4, 4, 16, 16, SLOW), new Config(8, 16, 32, 32, SLOW), new Config(8, 16, 128, 128, SLOW), new Config(8, 32, 128, 256, SLOW),
+  			new Config(32, 128, 258, 1024, SLOW), new Config(32, 258, 258, 4096, SLOW) ];
+
+  	var z_errmsg = [ "need dictionary", // Z_NEED_DICT
+  	// 2
+  	"stream end", // Z_STREAM_END 1
+  	"", // Z_OK 0
+  	"", // Z_ERRNO (-1)
+  	"stream error", // Z_STREAM_ERROR (-2)
+  	"data error", // Z_DATA_ERROR (-3)
+  	"", // Z_MEM_ERROR (-4)
+  	"buffer error", // Z_BUF_ERROR (-5)
+  	"",// Z_VERSION_ERROR (-6)
+  	"" ];
+
+  	// block not completed, need more input or more output
+  	var NeedMore = 0;
+
+  	// block flush performed
+  	var BlockDone = 1;
+
+  	// finish started, need only more output at next deflate
+  	var FinishStarted = 2;
+
+  	// finish done, accept no more input or output
+  	var FinishDone = 3;
+
+  	// preset dictionary flag in zlib header
+  	var PRESET_DICT = 0x20;
+
+  	var INIT_STATE = 42;
+  	var BUSY_STATE = 113;
+  	var FINISH_STATE = 666;
+
+  	// The deflate compression method
+  	var Z_DEFLATED = 8;
+
+  	var STORED_BLOCK = 0;
+  	var STATIC_TREES = 1;
+  	var DYN_TREES = 2;
+
+  	var MIN_MATCH = 3;
+  	var MAX_MATCH = 258;
+  	var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);
+
+  	function smaller(tree, n, m, depth) {
+  		var tn2 = tree[n * 2];
+  		var tm2 = tree[m * 2];
+  		return (tn2 < tm2 || (tn2 == tm2 && depth[n] <= depth[m]));
+  	}
+
+  	function Deflate() {
+
+  		var that = this;
+  		var strm; // pointer back to this zlib stream
+  		var status; // as the name implies
+  		// pending_buf; // output still pending
+  		var pending_buf_size; // size of pending_buf
+  		var last_flush; // value of flush param for previous deflate call
+
+  		var w_size; // LZ77 window size (32K by default)
+  		var w_bits; // log2(w_size) (8..16)
+  		var w_mask; // w_size - 1
+
+  		var window;
+  		// 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. Also, it limits
+  		// the window size to 64K, which is quite useful on MSDOS.
+  		// To do: use the user input buffer as sliding window.
+
+  		var window_size;
+  		// Actual size of window: 2*wSize, except when the user input buffer
+  		// is directly used as sliding window.
+
+  		var prev;
+  		// 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.
+
+  		var head; // Heads of the hash chains or NIL.
+
+  		var ins_h; // hash index of string to be inserted
+  		var hash_size; // number of elements in hash table
+  		var hash_bits; // log2(hash_size)
+  		var hash_mask; // hash_size-1
+
+  		// 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
+  		var hash_shift;
+
+  		// Window position at the beginning of the current output block. Gets
+  		// negative when the window is moved backwards.
+
+  		var block_start;
+
+  		var match_length; // length of best match
+  		var prev_match; // previous match
+  		var match_available; // set if previous match exists
+  		var strstart; // start of string to insert
+  		var match_start; // start of matching string
+  		var lookahead; // number of valid bytes ahead in window
+
+  		// Length of the best match at previous step. Matches not greater than this
+  		// are discarded. This is used in the lazy match evaluation.
+  		var prev_length;
+
+  		// To speed up deflation, hash chains are never searched beyond this
+  		// length. A higher limit improves compression ratio but degrades the speed.
+  		var max_chain_length;
+
+  		// 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.
+  		var max_lazy_match;
+
+  		// 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.
+
+  		var level; // compression level (1..9)
+  		var strategy; // favor or force Huffman coding
+
+  		// Use a faster search when the previous match is longer than this
+  		var good_match;
+
+  		// Stop searching when current match exceeds this
+  		var nice_match;
+
+  		var dyn_ltree; // literal and length tree
+  		var dyn_dtree; // distance tree
+  		var bl_tree; // Huffman tree for bit lengths
+
+  		var l_desc = new Tree(); // desc for literal tree
+  		var d_desc = new Tree(); // desc for distance tree
+  		var bl_desc = new Tree(); // desc for bit length tree
+
+  		// that.heap_len; // number of elements in the heap
+  		// that.heap_max; // 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.
+
+  		// Depth of each subtree used as tie breaker for trees of equal frequency
+  		that.depth = [];
+
+  		var l_buf; // index for literals or lengths */
+
+  		// 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
+  		var lit_bufsize;
+
+  		var last_lit; // running index in l_buf
+
+  		// Buffer 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.
+
+  		var d_buf; // index of pendig_buf
+
+  		// that.opt_len; // bit length of current block with optimal trees
+  		// that.static_len; // bit length of current block with static trees
+  		var matches; // number of string matches in current block
+  		var last_eob_len; // bit length of EOB code for last block
+
+  		// Output buffer. bits are inserted starting at the bottom (least
+  		// significant bits).
+  		var bi_buf;
+
+  		// Number of valid bits in bi_buf. All bits above the last valid bit
+  		// are always zero.
+  		var bi_valid;
+
+  		// number of codes at each bit length for an optimal tree
+  		that.bl_count = [];
+
+  		// heap used to build the Huffman trees
+  		that.heap = [];
+
+  		dyn_ltree = [];
+  		dyn_dtree = [];
+  		bl_tree = [];
+
+  		function lm_init() {
+  			var i;
+  			window_size = 2 * w_size;
+
+  			head[hash_size - 1] = 0;
+  			for (i = 0; i < hash_size - 1; i++) {
+  				head[i] = 0;
+  			}
+
+  			// Set the default configuration parameters:
+  			max_lazy_match = config_table[level].max_lazy;
+  			good_match = config_table[level].good_length;
+  			nice_match = config_table[level].nice_length;
+  			max_chain_length = config_table[level].max_chain;
+
+  			strstart = 0;
+  			block_start = 0;
+  			lookahead = 0;
+  			match_length = prev_length = MIN_MATCH - 1;
+  			match_available = 0;
+  			ins_h = 0;
+  		}
+
+  		function init_block() {
+  			var i;
+  			// Initialize the trees.
+  			for (i = 0; i < L_CODES; i++)
+  				dyn_ltree[i * 2] = 0;
+  			for (i = 0; i < D_CODES; i++)
+  				dyn_dtree[i * 2] = 0;
+  			for (i = 0; i < BL_CODES; i++)
+  				bl_tree[i * 2] = 0;
+
+  			dyn_ltree[END_BLOCK * 2] = 1;
+  			that.opt_len = that.static_len = 0;
+  			last_lit = matches = 0;
+  		}
+
+  		// Initialize the tree data structures for a new zlib stream.
+  		function tr_init() {
+
+  			l_desc.dyn_tree = dyn_ltree;
+  			l_desc.stat_desc = StaticTree.static_l_desc;
+
+  			d_desc.dyn_tree = dyn_dtree;
+  			d_desc.stat_desc = StaticTree.static_d_desc;
+
+  			bl_desc.dyn_tree = bl_tree;
+  			bl_desc.stat_desc = StaticTree.static_bl_desc;
+
+  			bi_buf = 0;
+  			bi_valid = 0;
+  			last_eob_len = 8; // enough lookahead for inflate
+
+  			// Initialize the first block of the first file:
+  			init_block();
+  		}
+
+  		// 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).
+  		that.pqdownheap = function(tree, // the tree to restore
+  		k // node to move down
+  		) {
+  			var heap = that.heap;
+  			var v = heap[k];
+  			var j = k << 1; // left son of k
+  			while (j <= that.heap_len) {
+  				// Set j to the smallest of the two sons:
+  				if (j < that.heap_len && smaller(tree, heap[j + 1], heap[j], that.depth)) {
+  					j++;
+  				}
+  				// Exit if v is smaller than both sons
+  				if (smaller(tree, v, heap[j], that.depth))
+  					break;
+
+  				// Exchange v with the smallest son
+  				heap[k] = heap[j];
+  				k = j;
+  				// And continue down the tree, setting j to the left son of k
+  				j <<= 1;
+  			}
+  			heap[k] = v;
+  		};
+
+  		// Scan a literal or distance tree to determine the frequencies of the codes
+  		// in the bit length tree.
+  		function scan_tree(tree,// the tree to be scanned
+  		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]; // 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] = 0xffff; // guard
+
+  			for (n = 0; n <= max_code; n++) {
+  				curlen = nextlen;
+  				nextlen = tree[(n + 1) * 2 + 1];
+  				if (++count < max_count && curlen == nextlen) {
+  					continue;
+  				} else if (count < min_count) {
+  					bl_tree[curlen * 2] += count;
+  				} else if (curlen !== 0) {
+  					if (curlen != prevlen)
+  						bl_tree[curlen * 2]++;
+  					bl_tree[REP_3_6 * 2]++;
+  				} else if (count <= 10) {
+  					bl_tree[REPZ_3_10 * 2]++;
+  				} else {
+  					bl_tree[REPZ_11_138 * 2]++;
+  				}
+  				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() {
+  			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(dyn_ltree, l_desc.max_code);
+  			scan_tree(dyn_dtree, d_desc.max_code);
+
+  			// Build the bit length tree:
+  			bl_desc.build_tree(that);
+  			// 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 (bl_tree[Tree.bl_order[max_blindex] * 2 + 1] !== 0)
+  					break;
+  			}
+  			// Update opt_len to include the bit length tree and counts
+  			that.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
+
+  			return max_blindex;
+  		}
+
+  		// Output a byte on the stream.
+  		// IN assertion: there is enough room in pending_buf.
+  		function put_byte(p) {
+  			that.pending_buf[that.pending++] = p;
+  		}
+
+  		function put_short(w) {
+  			put_byte(w & 0xff);
+  			put_byte((w >>> 8) & 0xff);
+  		}
+
+  		function putShortMSB(b) {
+  			put_byte((b >> 8) & 0xff);
+  			put_byte((b & 0xff) & 0xff);
+  		}
+
+  		function send_bits(value, length) {
+  			var val, len = length;
+  			if (bi_valid > Buf_size - len) {
+  				val = value;
+  				// bi_buf |= (val << bi_valid);
+  				bi_buf |= ((val << bi_valid) & 0xffff);
+  				put_short(bi_buf);
+  				bi_buf = val >>> (Buf_size - bi_valid);
+  				bi_valid += len - Buf_size;
+  			} else {
+  				// bi_buf |= (value) << bi_valid;
+  				bi_buf |= (((value) << bi_valid) & 0xffff);
+  				bi_valid += len;
+  			}
+  		}
+
+  		function send_code(c, tree) {
+  			var c2 = c * 2;
+  			send_bits(tree[c2] & 0xffff, tree[c2 + 1] & 0xffff);
+  		}
+
+  		// Send a literal or distance tree in compressed form, using the codes in
+  		// bl_tree.
+  		function send_tree(tree,// the tree to be sent
+  		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]; // 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;
+  			}
+
+  			for (n = 0; n <= max_code; n++) {
+  				curlen = nextlen;
+  				nextlen = tree[(n + 1) * 2 + 1];
+  				if (++count < max_count && curlen == nextlen) {
+  					continue;
+  				} else if (count < min_count) {
+  					do {
+  						send_code(curlen, bl_tree);
+  					} while (--count !== 0);
+  				} else if (curlen !== 0) {
+  					if (curlen != prevlen) {
+  						send_code(curlen, bl_tree);
+  						count--;
+  					}
+  					send_code(REP_3_6, bl_tree);
+  					send_bits(count - 3, 2);
+  				} else if (count <= 10) {
+  					send_code(REPZ_3_10, bl_tree);
+  					send_bits(count - 3, 3);
+  				} else {
+  					send_code(REPZ_11_138, bl_tree);
+  					send_bits(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;
+  				}
+  			}
+  		}
+
+  		// 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(lcodes, dcodes, blcodes) {
+  			var rank; // index in bl_order
+
+  			send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt
+  			send_bits(dcodes - 1, 5);
+  			send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt
+  			for (rank = 0; rank < blcodes; rank++) {
+  				send_bits(bl_tree[Tree.bl_order[rank] * 2 + 1], 3);
+  			}
+  			send_tree(dyn_ltree, lcodes - 1); // literal tree
+  			send_tree(dyn_dtree, dcodes - 1); // distance tree
+  		}
+
+  		// Flush the bit buffer, keeping at most 7 bits in it.
+  		function bi_flush() {
+  			if (bi_valid == 16) {
+  				put_short(bi_buf);
+  				bi_buf = 0;
+  				bi_valid = 0;
+  			} else if (bi_valid >= 8) {
+  				put_byte(bi_buf & 0xff);
+  				bi_buf >>>= 8;
+  				bi_valid -= 8;
+  			}
+  		}
+
+  		// Send one empty static block to give enough lookahead for inflate.
+  		// This takes 10 bits, of which 7 may remain in the bit buffer.
+  		// The current inflate code requires 9 bits of lookahead. If the
+  		// last two codes for the previous block (real code plus EOB) were coded
+  		// on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+  		// the last real code. In this case we send two empty static blocks instead
+  		// of one. (There are no problems if the previous block is stored or fixed.)
+  		// To simplify the code, we assume the worst case of last real code encoded
+  		// on one bit only.
+  		function _tr_align() {
+  			send_bits(STATIC_TREES << 1, 3);
+  			send_code(END_BLOCK, StaticTree.static_ltree);
+
+  			bi_flush();
+
+  			// Of the 10 bits for the empty block, we have already sent
+  			// (10 - bi_valid) bits. The lookahead for the last real code (before
+  			// the EOB of the previous block) was thus at least one plus the length
+  			// of the EOB plus what we have just sent of the empty static block.
+  			if (1 + last_eob_len + 10 - bi_valid < 9) {
+  				send_bits(STATIC_TREES << 1, 3);
+  				send_code(END_BLOCK, StaticTree.static_ltree);
+  				bi_flush();
+  			}
+  			last_eob_len = 7;
+  		}
+
+  		// Save the match info and tally the frequency counts. Return true if
+  		// the current block must be flushed.
+  		function _tr_tally(dist, // distance of matched string
+  		lc // match length-MIN_MATCH or unmatched char (if dist==0)
+  		) {
+  			var out_length, in_length, dcode;
+  			that.pending_buf[d_buf + last_lit * 2] = (dist >>> 8) & 0xff;
+  			that.pending_buf[d_buf + last_lit * 2 + 1] = dist & 0xff;
+
+  			that.pending_buf[l_buf + last_lit] = lc & 0xff;
+  			last_lit++;
+
+  			if (dist === 0) {
+  				// lc is the unmatched char
+  				dyn_ltree[lc * 2]++;
+  			} else {
+  				matches++;
+  				// Here, lc is the match length - MIN_MATCH
+  				dist--; // dist = match distance - 1
+  				dyn_ltree[(Tree._length_code[lc] + LITERALS + 1) * 2]++;
+  				dyn_dtree[Tree.d_code(dist) * 2]++;
+  			}
+
+  			if ((last_lit & 0x1fff) === 0 && level > 2) {
+  				// Compute an upper bound for the compressed length
+  				out_length = last_lit * 8;
+  				in_length = strstart - block_start;
+  				for (dcode = 0; dcode < D_CODES; dcode++) {
+  					out_length += dyn_dtree[dcode * 2] * (5 + Tree.extra_dbits[dcode]);
+  				}
+  				out_length >>>= 3;
+  				if ((matches < Math.floor(last_lit / 2)) && out_length < Math.floor(in_length / 2))
+  					return true;
+  			}
+
+  			return (last_lit == 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.
+  		}
+
+  		// Send the block data compressed using the given Huffman trees
+  		function compress_block(ltree, dtree) {
+  			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 (last_lit !== 0) {
+  				do {
+  					dist = ((that.pending_buf[d_buf + lx * 2] << 8) & 0xff00) | (that.pending_buf[d_buf + lx * 2 + 1] & 0xff);
+  					lc = (that.pending_buf[l_buf + lx]) & 0xff;
+  					lx++;
+
+  					if (dist === 0) {
+  						send_code(lc, ltree); // send a literal byte
+  					} else {
+  						// Here, lc is the match length - MIN_MATCH
+  						code = Tree._length_code[lc];
+
+  						send_code(code + LITERALS + 1, ltree); // send the length
+  						// code
+  						extra = Tree.extra_lbits[code];
+  						if (extra !== 0) {
+  							lc -= Tree.base_length[code];
+  							send_bits(lc, extra); // send the extra length bits
+  						}
+  						dist--; // dist is now the match distance - 1
+  						code = Tree.d_code(dist);
+
+  						send_code(code, dtree); // send the distance code
+  						extra = Tree.extra_dbits[code];
+  						if (extra !== 0) {
+  							dist -= Tree.base_dist[code];
+  							send_bits(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:
+  				} while (lx < last_lit);
+  			}
+
+  			send_code(END_BLOCK, ltree);
+  			last_eob_len = ltree[END_BLOCK * 2 + 1];
+  		}
+
+  		// Flush the bit buffer and align the output on a byte boundary
+  		function bi_windup() {
+  			if (bi_valid > 8) {
+  				put_short(bi_buf);
+  			} else if (bi_valid > 0) {
+  				put_byte(bi_buf & 0xff);
+  			}
+  			bi_buf = 0;
+  			bi_valid = 0;
+  		}
+
+  		// Copy a stored block, storing first the length and its
+  		// one's complement if requested.
+  		function copy_block(buf, // the input data
+  		len, // its length
+  		header // true if block header must be written
+  		) {
+  			bi_windup(); // align on byte boundary
+  			last_eob_len = 8; // enough lookahead for inflate
+
+  			if (header) {
+  				put_short(len);
+  				put_short(~len);
+  			}
+
+  			that.pending_buf.set(window.subarray(buf, buf + len), that.pending);
+  			that.pending += len;
+  		}
+
+  		// Send a stored block
+  		function _tr_stored_block(buf, // input block
+  		stored_len, // length of input block
+  		eof // true if this is the last block for a file
+  		) {
+  			send_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3); // send block type
+  			copy_block(buf, stored_len, true); // with header
+  		}
+
+  		// 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(buf, // input block, or NULL if too old
+  		stored_len, // length of input block
+  		eof // true 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 (level > 0) {
+  				// Construct the literal and distance trees
+  				l_desc.build_tree(that);
+
+  				d_desc.build_tree(that);
+
+  				// 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();
+
+  				// Determine the best encoding. Compute first the block length in
+  				// bytes
+  				opt_lenb = (that.opt_len + 3 + 7) >>> 3;
+  				static_lenb = (that.static_len + 3 + 7) >>> 3;
+
+  				if (static_lenb <= opt_lenb)
+  					opt_lenb = static_lenb;
+  			} else {
+  				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(buf, stored_len, eof);
+  			} else if (static_lenb == opt_lenb) {
+  				send_bits((STATIC_TREES << 1) + (eof ? 1 : 0), 3);
+  				compress_block(StaticTree.static_ltree, StaticTree.static_dtree);
+  			} else {
+  				send_bits((DYN_TREES << 1) + (eof ? 1 : 0), 3);
+  				send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1, max_blindex + 1);
+  				compress_block(dyn_ltree, dyn_dtree);
+  			}
+
+  			// The above check is made mod 2^32, for files larger than 512 MB
+  			// and uLong implemented on 32 bits.
+
+  			init_block();
+
+  			if (eof) {
+  				bi_windup();
+  			}
+  		}
+
+  		function flush_block_only(eof) {
+  			_tr_flush_block(block_start >= 0 ? block_start : -1, strstart - block_start, eof);
+  			block_start = strstart;
+  			strm.flush_pending();
+  		}
+
+  		// 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() {
+  			var n, m;
+  			var p;
+  			var more; // Amount of free space at the end of the window.
+
+  			do {
+  				more = (window_size - lookahead - strstart);
+
+  				// Deal with !@#$% 64K limit:
+  				if (more === 0 && strstart === 0 && lookahead === 0) {
+  					more = w_size;
+  				} else if (more == -1) {
+  					// Very unlikely, but possible on 16 bit machine if strstart ==
+  					// 0
+  					// and lookahead == 1 (input done one 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.
+  				} else if (strstart >= w_size + w_size - MIN_LOOKAHEAD) {
+  					window.set(window.subarray(w_size, w_size + w_size), 0);
+
+  					match_start -= w_size;
+  					strstart -= w_size; // we now have strstart >= MAX_DIST
+  					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 = hash_size;
+  					p = n;
+  					do {
+  						m = (head[--p] & 0xffff);
+  						head[p] = (m >= w_size ? m - w_size : 0);
+  					} while (--n !== 0);
+
+  					n = w_size;
+  					p = n;
+  					do {
+  						m = (prev[--p] & 0xffff);
+  						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 !== 0);
+  					more += w_size;
+  				}
+
+  				if (strm.avail_in === 0)
+  					return;
+
+  				// 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.
+
+  				n = strm.read_buf(window, strstart + lookahead, more);
+  				lookahead += n;
+
+  				// Initialize the hash value now that we have some input:
+  				if (lookahead >= MIN_MATCH) {
+  					ins_h = window[strstart] & 0xff;
+  					ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
+  				}
+  				// 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 (lookahead < MIN_LOOKAHEAD && strm.avail_in !== 0);
+  		}
+
+  		// 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(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;
+  			var max_start;
+
+  			if (max_block_size > pending_buf_size - 5) {
+  				max_block_size = pending_buf_size - 5;
+  			}
+
+  			// Copy as much as possible from input to output:
+  			while (true) {
+  				// Fill the window as much as possible:
+  				if (lookahead <= 1) {
+  					fill_window();
+  					if (lookahead === 0 && flush == Z_NO_FLUSH)
+  						return NeedMore;
+  					if (lookahead === 0)
+  						break; // flush the current block
+  				}
+
+  				strstart += lookahead;
+  				lookahead = 0;
+
+  				// Emit a stored block if pending_buf will be full:
+  				max_start = block_start + max_block_size;
+  				if (strstart === 0 || strstart >= max_start) {
+  					// strstart === 0 is possible when wraparound on 16-bit machine
+  					lookahead = (strstart - max_start);
+  					strstart = max_start;
+
+  					flush_block_only(false);
+  					if (strm.avail_out === 0)
+  						return NeedMore;
+
+  				}
+
+  				// Flush if we may have to slide, otherwise block_start may become
+  				// negative and the data will be gone:
+  				if (strstart - block_start >= w_size - MIN_LOOKAHEAD) {
+  					flush_block_only(false);
+  					if (strm.avail_out === 0)
+  						return NeedMore;
+  				}
+  			}
+
+  			flush_block_only(flush == Z_FINISH);
+  			if (strm.avail_out === 0)
+  				return (flush == Z_FINISH) ? FinishStarted : NeedMore;
+
+  			return flush == Z_FINISH ? FinishDone : BlockDone;
+  		}
+
+  		function longest_match(cur_match) {
+  			var chain_length = max_chain_length; // max hash chain length
+  			var scan = strstart; // current string
+  			var match; // matched string
+  			var len; // length of current match
+  			var best_len = prev_length; // best match length so far
+  			var limit = strstart > (w_size - MIN_LOOKAHEAD) ? strstart - (w_size - MIN_LOOKAHEAD) : 0;
+  			var _nice_match = nice_match;
+
+  			// Stop when cur_match becomes <= limit. To simplify the code,
+  			// we prevent matches with the string of window index 0.
+
+  			var wmask = w_mask;
+
+  			var strend = strstart + MAX_MATCH;
+  			var scan_end1 = window[scan + best_len - 1];
+  			var scan_end = window[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.
+
+  			// Do not waste too much time if we already have a good match:
+  			if (prev_length >= 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 > lookahead)
+  				_nice_match = lookahead;
+
+  			do {
+  				match = cur_match;
+
+  				// Skip to next match if the match length cannot increase
+  				// or if the match length is less than 2:
+  				if (window[match + best_len] != scan_end || window[match + best_len - 1] != scan_end1 || window[match] != window[scan]
+  						|| window[++match] != window[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++;
+
+  				// We check for insufficient lookahead only every 8th comparison;
+  				// the 256th check will be made at strstart+258.
+  				do {
+  				} while (window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match]
+  						&& window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match]
+  						&& window[++scan] == window[++match] && window[++scan] == window[++match] && scan < strend);
+
+  				len = MAX_MATCH - (strend - scan);
+  				scan = strend - MAX_MATCH;
+
+  				if (len > best_len) {
+  					match_start = cur_match;
+  					best_len = len;
+  					if (len >= _nice_match)
+  						break;
+  					scan_end1 = window[scan + best_len - 1];
+  					scan_end = window[scan + best_len];
+  				}
+
+  			} while ((cur_match = (prev[cur_match & wmask] & 0xffff)) > limit && --chain_length !== 0);
+
+  			if (best_len <= lookahead)
+  				return best_len;
+  			return lookahead;
+  		}
+
+  		// 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(flush) {
+  			// short hash_head = 0; // head of the hash chain
+  			var hash_head = 0; // head of the hash chain
+  			var bflush; // set if current block must be flushed
+
+  			while (true) {
+  				// 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 (lookahead < MIN_LOOKAHEAD) {
+  					fill_window();
+  					if (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+  						return NeedMore;
+  					}
+  					if (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:
+  				if (lookahead >= MIN_MATCH) {
+  					ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
+
+  					// prev[strstart&w_mask]=hash_head=head[ins_h];
+  					hash_head = (head[ins_h] & 0xffff);
+  					prev[strstart & w_mask] = head[ins_h];
+  					head[ins_h] = strstart;
+  				}
+
+  				// Find the longest match, discarding those <= prev_length.
+  				// At this point we have always match_length < MIN_MATCH
+
+  				if (hash_head !== 0 && ((strstart - hash_head) & 0xffff) <= 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).
+  					if (strategy != Z_HUFFMAN_ONLY) {
+  						match_length = longest_match(hash_head);
+  					}
+  					// longest_match() sets match_start
+  				}
+  				if (match_length >= MIN_MATCH) {
+  					// check_match(strstart, match_start, match_length);
+
+  					bflush = _tr_tally(strstart - match_start, match_length - MIN_MATCH);
+
+  					lookahead -= 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 (match_length <= max_lazy_match && lookahead >= MIN_MATCH) {
+  						match_length--; // string at strstart already in hash table
+  						do {
+  							strstart++;
+
+  							ins_h = ((ins_h << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
+  							// prev[strstart&w_mask]=hash_head=head[ins_h];
+  							hash_head = (head[ins_h] & 0xffff);
+  							prev[strstart & w_mask] = head[ins_h];
+  							head[ins_h] = strstart;
+
+  							// strstart never exceeds WSIZE-MAX_MATCH, so there are
+  							// always MIN_MATCH bytes ahead.
+  						} while (--match_length !== 0);
+  						strstart++;
+  					} else {
+  						strstart += match_length;
+  						match_length = 0;
+  						ins_h = window[strstart] & 0xff;
+
+  						ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
+  						// 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
+
+  					bflush = _tr_tally(0, window[strstart] & 0xff);
+  					lookahead--;
+  					strstart++;
+  				}
+  				if (bflush) {
+
+  					flush_block_only(false);
+  					if (strm.avail_out === 0)
+  						return NeedMore;
+  				}
+  			}
+
+  			flush_block_only(flush == Z_FINISH);
+  			if (strm.avail_out === 0) {
+  				if (flush == Z_FINISH)
+  					return FinishStarted;
+  				else
+  					return NeedMore;
+  			}
+  			return flush == Z_FINISH ? FinishDone : BlockDone;
+  		}
+
+  		// 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(flush) {
+  			// short hash_head = 0; // head of hash chain
+  			var hash_head = 0; // head of hash chain
+  			var bflush; // set if current block must be flushed
+  			var max_insert;
+
+  			// Process the input block.
+  			while (true) {
+  				// 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 (lookahead < MIN_LOOKAHEAD) {
+  					fill_window();
+  					if (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+  						return NeedMore;
+  					}
+  					if (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:
+
+  				if (lookahead >= MIN_MATCH) {
+  					ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
+  					// prev[strstart&w_mask]=hash_head=head[ins_h];
+  					hash_head = (head[ins_h] & 0xffff);
+  					prev[strstart & w_mask] = head[ins_h];
+  					head[ins_h] = strstart;
+  				}
+
+  				// Find the longest match, discarding those <= prev_length.
+  				prev_length = match_length;
+  				prev_match = match_start;
+  				match_length = MIN_MATCH - 1;
+
+  				if (hash_head !== 0 && prev_length < max_lazy_match && ((strstart - hash_head) & 0xffff) <= 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).
+
+  					if (strategy != Z_HUFFMAN_ONLY) {
+  						match_length = longest_match(hash_head);
+  					}
+  					// longest_match() sets match_start
+
+  					if (match_length <= 5 && (strategy == Z_FILTERED || (match_length == MIN_MATCH && strstart - match_start > 4096))) {
+
+  						// If prev_match is also MIN_MATCH, match_start is garbage
+  						// but we will ignore the current match anyway.
+  						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 (prev_length >= MIN_MATCH && match_length <= prev_length) {
+  					max_insert = strstart + lookahead - MIN_MATCH;
+  					// Do not insert strings in hash table beyond this.
+
+  					// check_match(strstart-1, prev_match, prev_length);
+
+  					bflush = _tr_tally(strstart - 1 - prev_match, 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.
+  					lookahead -= prev_length - 1;
+  					prev_length -= 2;
+  					do {
+  						if (++strstart <= max_insert) {
+  							ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
+  							// prev[strstart&w_mask]=hash_head=head[ins_h];
+  							hash_head = (head[ins_h] & 0xffff);
+  							prev[strstart & w_mask] = head[ins_h];
+  							head[ins_h] = strstart;
+  						}
+  					} while (--prev_length !== 0);
+  					match_available = 0;
+  					match_length = MIN_MATCH - 1;
+  					strstart++;
+
+  					if (bflush) {
+  						flush_block_only(false);
+  						if (strm.avail_out === 0)
+  							return NeedMore;
+  					}
+  				} else if (match_available !== 0) {
+
+  					// 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.
+
+  					bflush = _tr_tally(0, window[strstart - 1] & 0xff);
+
+  					if (bflush) {
+  						flush_block_only(false);
+  					}
+  					strstart++;
+  					lookahead--;
+  					if (strm.avail_out === 0)
+  						return NeedMore;
+  				} else {
+  					// There is no previous match to compare with, wait for
+  					// the next step to decide.
+
+  					match_available = 1;
+  					strstart++;
+  					lookahead--;
+  				}
+  			}
+
+  			if (match_available !== 0) {
+  				bflush = _tr_tally(0, window[strstart - 1] & 0xff);
+  				match_available = 0;
+  			}
+  			flush_block_only(flush == Z_FINISH);
+
+  			if (strm.avail_out === 0) {
+  				if (flush == Z_FINISH)
+  					return FinishStarted;
+  				else
+  					return NeedMore;
+  			}
+
+  			return flush == Z_FINISH ? FinishDone : BlockDone;
+  		}
+
+  		function deflateReset(strm) {
+  			strm.total_in = strm.total_out = 0;
+  			strm.msg = null; //
+  			
+  			that.pending = 0;
+  			that.pending_out = 0;
+
+  			status = BUSY_STATE;
+
+  			last_flush = Z_NO_FLUSH;
+
+  			tr_init();
+  			lm_init();
+  			return Z_OK;
+  		}
+
+  		that.deflateInit = function(strm, _level, bits, _method, memLevel, _strategy) {
+  			if (!_method)
+  				_method = Z_DEFLATED;
+  			if (!memLevel)
+  				memLevel = DEF_MEM_LEVEL;
+  			if (!_strategy)
+  				_strategy = Z_DEFAULT_STRATEGY;
+
+  			// byte[] my_version=ZLIB_VERSION;
+
+  			//
+  			// if (!version || version[0] != my_version[0]
+  			// || stream_size != sizeof(z_stream)) {
+  			// return Z_VERSION_ERROR;
+  			// }
+
+  			strm.msg = null;
+
+  			if (_level == Z_DEFAULT_COMPRESSION)
+  				_level = 6;
+
+  			if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || _method != Z_DEFLATED || bits < 9 || bits > 15 || _level < 0 || _level > 9 || _strategy < 0
+  					|| _strategy > Z_HUFFMAN_ONLY) {
+  				return Z_STREAM_ERROR;
+  			}
+
+  			strm.dstate = that;
+
+  			w_bits = bits;
+  			w_size = 1 << w_bits;
+  			w_mask = w_size - 1;
+
+  			hash_bits = memLevel + 7;
+  			hash_size = 1 << hash_bits;
+  			hash_mask = hash_size - 1;
+  			hash_shift = Math.floor((hash_bits + MIN_MATCH - 1) / MIN_MATCH);
+
+  			window = new Uint8Array(w_size * 2);
+  			prev = [];
+  			head = [];
+
+  			lit_bufsize = 1 << (memLevel + 6); // 16K elements by default
+
+  			// We overlay pending_buf and d_buf+l_buf. This works since the average
+  			// output size for (length,distance) codes is <= 24 bits.
+  			that.pending_buf = new Uint8Array(lit_bufsize * 4);
+  			pending_buf_size = lit_bufsize * 4;
+
+  			d_buf = Math.floor(lit_bufsize / 2);
+  			l_buf = (1 + 2) * lit_bufsize;
+
+  			level = _level;
+
+  			strategy = _strategy;
+
+  			return deflateReset(strm);
+  		};
+
+  		that.deflateEnd = function() {
+  			if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE) {
+  				return Z_STREAM_ERROR;
+  			}
+  			// Deallocate in reverse order of allocations:
+  			that.pending_buf = null;
+  			head = null;
+  			prev = null;
+  			window = null;
+  			// free
+  			that.dstate = null;
+  			return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+  		};
+
+  		that.deflateParams = function(strm, _level, _strategy) {
+  			var err = Z_OK;
+
+  			if (_level == Z_DEFAULT_COMPRESSION) {
+  				_level = 6;
+  			}
+  			if (_level < 0 || _level > 9 || _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) {
+  				return Z_STREAM_ERROR;
+  			}
+
+  			if (config_table[level].func != config_table[_level].func && strm.total_in !== 0) {
+  				// Flush the last buffer:
+  				err = strm.deflate(Z_PARTIAL_FLUSH);
+  			}
+
+  			if (level != _level) {
+  				level = _level;
+  				max_lazy_match = config_table[level].max_lazy;
+  				good_match = config_table[level].good_length;
+  				nice_match = config_table[level].nice_length;
+  				max_chain_length = config_table[level].max_chain;
+  			}
+  			strategy = _strategy;
+  			return err;
+  		};
+
+  		that.deflateSetDictionary = function(strm, dictionary, dictLength) {
+  			var length = dictLength;
+  			var n, index = 0;
+
+  			if (!dictionary || status != INIT_STATE)
+  				return Z_STREAM_ERROR;
+
+  			if (length < MIN_MATCH)
+  				return Z_OK;
+  			if (length > w_size - MIN_LOOKAHEAD) {
+  				length = w_size - MIN_LOOKAHEAD;
+  				index = dictLength - length; // use the tail of the dictionary
+  			}
+  			window.set(dictionary.subarray(index, index + length), 0);
+
+  			strstart = length;
+  			block_start = length;
+
+  			// Insert all strings in the hash table (except for the last two bytes).
+  			// s->lookahead stays null, so s->ins_h will be recomputed at the next
+  			// call of fill_window.
+
+  			ins_h = window[0] & 0xff;
+  			ins_h = (((ins_h) << hash_shift) ^ (window[1] & 0xff)) & hash_mask;
+
+  			for (n = 0; n <= length - MIN_MATCH; n++) {
+  				ins_h = (((ins_h) << hash_shift) ^ (window[(n) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
+  				prev[n & w_mask] = head[ins_h];
+  				head[ins_h] = n;
+  			}
+  			return Z_OK;
+  		};
+
+  		that.deflate = function(_strm, flush) {
+  			var i, header, level_flags, old_flush, bstate;
+
+  			if (flush > Z_FINISH || flush < 0) {
+  				return Z_STREAM_ERROR;
+  			}
+
+  			if (!_strm.next_out || (!_strm.next_in && _strm.avail_in !== 0) || (status == FINISH_STATE && flush != Z_FINISH)) {
+  				_strm.msg = z_errmsg[Z_NEED_DICT - (Z_STREAM_ERROR)];
+  				return Z_STREAM_ERROR;
+  			}
+  			if (_strm.avail_out === 0) {
+  				_strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
+  				return Z_BUF_ERROR;
+  			}
+
+  			strm = _strm; // just in case
+  			old_flush = last_flush;
+  			last_flush = flush;
+
+  			// Write the zlib header
+  			if (status == INIT_STATE) {
+  				header = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8;
+  				level_flags = ((level - 1) & 0xff) >> 1;
+
+  				if (level_flags > 3)
+  					level_flags = 3;
+  				header |= (level_flags << 6);
+  				if (strstart !== 0)
+  					header |= PRESET_DICT;
+  				header += 31 - (header % 31);
+
+  				status = BUSY_STATE;
+  				putShortMSB(header);
+  			}
+
+  			// Flush as much pending output as possible
+  			if (that.pending !== 0) {
+  				strm.flush_pending();
+  				if (strm.avail_out === 0) {
+  					// console.log(" 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:
+  					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_BUFF_ERROR.
+  			} else if (strm.avail_in === 0 && flush <= old_flush && flush != Z_FINISH) {
+  				strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
+  				return Z_BUF_ERROR;
+  			}
+
+  			// User must not provide more input after the first FINISH:
+  			if (status == FINISH_STATE && strm.avail_in !== 0) {
+  				_strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
+  				return Z_BUF_ERROR;
+  			}
+
+  			// Start a new block or continue the current one.
+  			if (strm.avail_in !== 0 || lookahead !== 0 || (flush != Z_NO_FLUSH && status != FINISH_STATE)) {
+  				bstate = -1;
+  				switch (config_table[level].func) {
+  				case STORED:
+  					bstate = deflate_stored(flush);
+  					break;
+  				case FAST:
+  					bstate = deflate_fast(flush);
+  					break;
+  				case SLOW:
+  					bstate = deflate_slow(flush);
+  					break;
+  				default:
+  				}
+
+  				if (bstate == FinishStarted || bstate == FinishDone) {
+  					status = FINISH_STATE;
+  				}
+  				if (bstate == NeedMore || bstate == FinishStarted) {
+  					if (strm.avail_out === 0) {
+  						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 == BlockDone) {
+  					if (flush == Z_PARTIAL_FLUSH) {
+  						_tr_align();
+  					} else { // FULL_FLUSH or SYNC_FLUSH
+  						_tr_stored_block(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) {
+  							// state.head[s.hash_size-1]=0;
+  							for (i = 0; i < hash_size/*-1*/; i++)
+  								// forget history
+  								head[i] = 0;
+  						}
+  					}
+  					strm.flush_pending();
+  					if (strm.avail_out === 0) {
+  						last_flush = -1; // avoid BUF_ERROR at next call, see above
+  						return Z_OK;
+  					}
+  				}
+  			}
+
+  			if (flush != Z_FINISH)
+  				return Z_OK;
+  			return Z_STREAM_END;
+  		};
+  	}
+
+  	// ZStream
+
+  	function ZStream() {
+  		var that = this;
+  		that.next_in_index = 0;
+  		that.next_out_index = 0;
+  		// that.next_in; // next input byte
+  		that.avail_in = 0; // number of bytes available at next_in
+  		that.total_in = 0; // total nb of input bytes read so far
+  		// that.next_out; // next output byte should be put there
+  		that.avail_out = 0; // remaining free space at next_out
+  		that.total_out = 0; // total nb of bytes output so far
+  		// that.msg;
+  		// that.dstate;
+  	}
+
+  	ZStream.prototype = {
+  		deflateInit : function(level, bits) {
+  			var that = this;
+  			that.dstate = new Deflate();
+  			if (!bits)
+  				bits = MAX_BITS;
+  			return that.dstate.deflateInit(that, level, bits);
+  		},
+
+  		deflate : function(flush) {
+  			var that = this;
+  			if (!that.dstate) {
+  				return Z_STREAM_ERROR;
+  			}
+  			return that.dstate.deflate(that, flush);
+  		},
+
+  		deflateEnd : function() {
+  			var that = this;
+  			if (!that.dstate)
+  				return Z_STREAM_ERROR;
+  			var ret = that.dstate.deflateEnd();
+  			that.dstate = null;
+  			return ret;
+  		},
+
+  		deflateParams : function(level, strategy) {
+  			var that = this;
+  			if (!that.dstate)
+  				return Z_STREAM_ERROR;
+  			return that.dstate.deflateParams(that, level, strategy);
+  		},
+
+  		deflateSetDictionary : function(dictionary, dictLength) {
+  			var that = this;
+  			if (!that.dstate)
+  				return Z_STREAM_ERROR;
+  			return that.dstate.deflateSetDictionary(that, dictionary, dictLength);
+  		},
+
+  		// Read a new buffer from the current input stream, update the
+  		// 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->next_in buffer and copying from it.
+  		// (See also flush_pending()).
+  		read_buf : function(buf, start, size) {
+  			var that = this;
+  			var len = that.avail_in;
+  			if (len > size)
+  				len = size;
+  			if (len === 0)
+  				return 0;
+  			that.avail_in -= len;
+  			buf.set(that.next_in.subarray(that.next_in_index, that.next_in_index + len), start);
+  			that.next_in_index += len;
+  			that.total_in += len;
+  			return len;
+  		},
+
+  		// 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->next_out buffer and copying into it.
+  		// (See also read_buf()).
+  		flush_pending : function() {
+  			var that = this;
+  			var len = that.dstate.pending;
+
+  			if (len > that.avail_out)
+  				len = that.avail_out;
+  			if (len === 0)
+  				return;
+
+  			// if (that.dstate.pending_buf.length <= that.dstate.pending_out || that.next_out.length <= that.next_out_index
+  			// || that.dstate.pending_buf.length < (that.dstate.pending_out + len) || that.next_out.length < (that.next_out_index +
+  			// len)) {
+  			// console.log(that.dstate.pending_buf.length + ", " + that.dstate.pending_out + ", " + that.next_out.length + ", " +
+  			// that.next_out_index + ", " + len);
+  			// console.log("avail_out=" + that.avail_out);
+  			// }
+
+  			that.next_out.set(that.dstate.pending_buf.subarray(that.dstate.pending_out, that.dstate.pending_out + len), that.next_out_index);
+
+  			that.next_out_index += len;
+  			that.dstate.pending_out += len;
+  			that.total_out += len;
+  			that.avail_out -= len;
+  			that.dstate.pending -= len;
+  			if (that.dstate.pending === 0) {
+  				that.dstate.pending_out = 0;
+  			}
+  		}
+  	};
+
+  	// Deflater
+
+  	function Deflater(options) {
+  		var that = this;
+  		var z = new ZStream();
+  		var bufsize = 512;
+  		var flush = Z_NO_FLUSH;
+  		var buf = new Uint8Array(bufsize);
+  		var level = options ? options.level : Z_DEFAULT_COMPRESSION;
+  		if (typeof level == "undefined")
+  			level = Z_DEFAULT_COMPRESSION;
+  		z.deflateInit(level);
+  		z.next_out = buf;
+
+  		that.append = function(data, onprogress) {
+  			var err, buffers = [], lastIndex = 0, bufferIndex = 0, bufferSize = 0, array;
+  			if (!data.length)
+  				return;
+  			z.next_in_index = 0;
+  			z.next_in = data;
+  			z.avail_in = data.length;
+  			do {
+  				z.next_out_index = 0;
+  				z.avail_out = bufsize;
+  				err = z.deflate(flush);
+  				if (err != Z_OK)
+  					throw new Error("deflating: " + z.msg);
+  				if (z.next_out_index)
+  					if (z.next_out_index == bufsize)
+  						buffers.push(new Uint8Array(buf));
+  					else
+  						buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
+  				bufferSize += z.next_out_index;
+  				if (onprogress && z.next_in_index > 0 && z.next_in_index != lastIndex) {
+  					onprogress(z.next_in_index);
+  					lastIndex = z.next_in_index;
+  				}
+  			} while (z.avail_in > 0 || z.avail_out === 0);
+  			array = new Uint8Array(bufferSize);
+  			buffers.forEach(function(chunk) {
+  				array.set(chunk, bufferIndex);
+  				bufferIndex += chunk.length;
+  			});
+  			return array;
+  		};
+  		that.flush = function() {
+  			var err, buffers = [], bufferIndex = 0, bufferSize = 0, array;
+  			do {
+  				z.next_out_index = 0;
+  				z.avail_out = bufsize;
+  				err = z.deflate(Z_FINISH);
+  				if (err != Z_STREAM_END && err != Z_OK)
+  					throw new Error("deflating: " + z.msg);
+  				if (bufsize - z.avail_out > 0)
+  					buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
+  				bufferSize += z.next_out_index;
+  			} while (z.avail_in > 0 || z.avail_out === 0);
+  			z.deflateEnd();
+  			array = new Uint8Array(bufferSize);
+  			buffers.forEach(function(chunk) {
+  				array.set(chunk, bufferIndex);
+  				bufferIndex += chunk.length;
+  			});
+  			return array;
+  		};
+  	}
+
+  	// 'zip' may not be defined in z-worker and some tests
+  	var env = global.zip || global;
+  	env.Deflater = env._jzlib_Deflater = Deflater;
+  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || typeof global !== "undefined" && global ||  Function('return typeof this === "object" && this.content')() || Function('return this')()));
+  // `self` is undefined in Firefox for Android content script context
+  // while `this` is nsIContentFrameMessageManager
+  // with an attribute `content` that corresponds to the window
+
+  /**
+   * CssColors
+   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+
+  /**
+   * Usage CssColors('red');
+   * Returns RGB hex color with '#' prefix
+   */
+
+  var CssColors = {};
+  CssColors._colorsTable = {
+  	"aliceblue" : "#f0f8ff",
+  	"antiquewhite" : "#faebd7",
+  	"aqua" : "#00ffff",
+  	"aquamarine" : "#7fffd4",
+  	"azure" : "#f0ffff",
+  	"beige" : "#f5f5dc",
+  	"bisque" : "#ffe4c4",
+  	"black" : "#000000",
+  	"blanchedalmond" : "#ffebcd",
+  	"blue" : "#0000ff",
+  	"blueviolet" : "#8a2be2",
+  	"brown" : "#a52a2a",
+  	"burlywood" : "#deb887",
+  	"cadetblue" : "#5f9ea0",
+  	"chartreuse" : "#7fff00",
+  	"chocolate" : "#d2691e",
+  	"coral" : "#ff7f50",
+  	"cornflowerblue" : "#6495ed",
+  	"cornsilk" : "#fff8dc",
+  	"crimson" : "#dc143c",
+  	"cyan" : "#00ffff",
+  	"darkblue" : "#00008b",
+  	"darkcyan" : "#008b8b",
+  	"darkgoldenrod" : "#b8860b",
+  	"darkgray" : "#a9a9a9",
+  	"darkgreen" : "#006400",
+  	"darkkhaki" : "#bdb76b",
+  	"darkmagenta" : "#8b008b",
+  	"darkolivegreen" : "#556b2f",
+  	"darkorange" : "#ff8c00",
+  	"darkorchid" : "#9932cc",
+  	"darkred" : "#8b0000",
+  	"darksalmon" : "#e9967a",
+  	"darkseagreen" : "#8fbc8f",
+  	"darkslateblue" : "#483d8b",
+  	"darkslategray" : "#2f4f4f",
+  	"darkturquoise" : "#00ced1",
+  	"darkviolet" : "#9400d3",
+  	"deeppink" : "#ff1493",
+  	"deepskyblue" : "#00bfff",
+  	"dimgray" : "#696969",
+  	"dodgerblue" : "#1e90ff",
+  	"firebrick" : "#b22222",
+  	"floralwhite" : "#fffaf0",
+  	"forestgreen" : "#228b22",
+  	"fuchsia" : "#ff00ff",
+  	"gainsboro" : "#dcdcdc",
+  	"ghostwhite" : "#f8f8ff",
+  	"gold" : "#ffd700",
+  	"goldenrod" : "#daa520",
+  	"gray" : "#808080",
+  	"green" : "#008000",
+  	"greenyellow" : "#adff2f",
+  	"honeydew" : "#f0fff0",
+  	"hotpink" : "#ff69b4",
+  	"indianred " : "#cd5c5c",
+  	"indigo" : "#4b0082",
+  	"ivory" : "#fffff0",
+  	"khaki" : "#f0e68c",
+  	"lavender" : "#e6e6fa",
+  	"lavenderblush" : "#fff0f5",
+  	"lawngreen" : "#7cfc00",
+  	"lemonchiffon" : "#fffacd",
+  	"lightblue" : "#add8e6",
+  	"lightcoral" : "#f08080",
+  	"lightcyan" : "#e0ffff",
+  	"lightgoldenrodyellow" : "#fafad2",
+  	"lightgrey" : "#d3d3d3",
+  	"lightgreen" : "#90ee90",
+  	"lightpink" : "#ffb6c1",
+  	"lightsalmon" : "#ffa07a",
+  	"lightseagreen" : "#20b2aa",
+  	"lightskyblue" : "#87cefa",
+  	"lightslategray" : "#778899",
+  	"lightsteelblue" : "#b0c4de",
+  	"lightyellow" : "#ffffe0",
+  	"lime" : "#00ff00",
+  	"limegreen" : "#32cd32",
+  	"linen" : "#faf0e6",
+  	"magenta" : "#ff00ff",
+  	"maroon" : "#800000",
+  	"mediumaquamarine" : "#66cdaa",
+  	"mediumblue" : "#0000cd",
+  	"mediumorchid" : "#ba55d3",
+  	"mediumpurple" : "#9370d8",
+  	"mediumseagreen" : "#3cb371",
+  	"mediumslateblue" : "#7b68ee",
+  	"mediumspringgreen" : "#00fa9a",
+  	"mediumturquoise" : "#48d1cc",
+  	"mediumvioletred" : "#c71585",
+  	"midnightblue" : "#191970",
+  	"mintcream" : "#f5fffa",
+  	"mistyrose" : "#ffe4e1",
+  	"moccasin" : "#ffe4b5",
+  	"navajowhite" : "#ffdead",
+  	"navy" : "#000080",
+  	"oldlace" : "#fdf5e6",
+  	"olive" : "#808000",
+  	"olivedrab" : "#6b8e23",
+  	"orange" : "#ffa500",
+  	"orangered" : "#ff4500",
+  	"orchid" : "#da70d6",
+  	"palegoldenrod" : "#eee8aa",
+  	"palegreen" : "#98fb98",
+  	"paleturquoise" : "#afeeee",
+  	"palevioletred" : "#d87093",
+  	"papayawhip" : "#ffefd5",
+  	"peachpuff" : "#ffdab9",
+  	"peru" : "#cd853f",
+  	"pink" : "#ffc0cb",
+  	"plum" : "#dda0dd",
+  	"powderblue" : "#b0e0e6",
+  	"purple" : "#800080",
+  	"red" : "#ff0000",
+  	"rosybrown" : "#bc8f8f",
+  	"royalblue" : "#4169e1",
+  	"saddlebrown" : "#8b4513",
+  	"salmon" : "#fa8072",
+  	"sandybrown" : "#f4a460",
+  	"seagreen" : "#2e8b57",
+  	"seashell" : "#fff5ee",
+  	"sienna" : "#a0522d",
+  	"silver" : "#c0c0c0",
+  	"skyblue" : "#87ceeb",
+  	"slateblue" : "#6a5acd",
+  	"slategray" : "#708090",
+  	"snow" : "#fffafa",
+  	"springgreen" : "#00ff7f",
+  	"steelblue" : "#4682b4",
+  	"tan" : "#d2b48c",
+  	"teal" : "#008080",
+  	"thistle" : "#d8bfd8",
+  	"tomato" : "#ff6347",
+  	"turquoise" : "#40e0d0",
+  	"violet" : "#ee82ee",
+  	"wheat" : "#f5deb3",
+  	"white" : "#ffffff",
+  	"whitesmoke" : "#f5f5f5",
+  	"yellow" : "#ffff00",
+  	"yellowgreen" : "#9acd32"
+  };
+
+  CssColors.colorNameToHex = function(color) {
+  	color = color.toLowerCase();
+  	if (typeof this._colorsTable[color] != 'undefined')
+  		return this._colorsTable[color];
+
+  	return false;
+  };
+
+  /*
+    html2canvas 0.5.0-beta3 <http://html2canvas.hertzen.com>
+    Copyright (c) 2016 Niklas von Hertzen
+
+    Released under  License
+  */
+
+  !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.html2canvas=e();}}(function(){var define;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(_dereq_,module,exports){
+  (function (global){
+  (function(root) {
+
+  	/** Detect free variables */
+  	var freeExports = typeof exports == 'object' && exports;
+  	var freeModule = typeof module == 'object' && module &&
+  		module.exports == freeExports && module;
+  	var freeGlobal = typeof global == 'object' && global;
+  	if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
+  		root = freeGlobal;
+  	}
+
+  	/**
+  	 * The `punycode` object.
+  	 * @name punycode
+  	 * @type Object
+  	 */
+  	var punycode,
+
+  	/** Highest positive signed 32-bit float value */
+  	maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
+
+  	/** Bootstring parameters */
+  	base = 36,
+  	tMin = 1,
+  	tMax = 26,
+  	skew = 38,
+  	damp = 700,
+  	initialBias = 72,
+  	initialN = 128, // 0x80
+  	delimiter = '-', // '\x2D'
+
+  	/** Regular expressions */
+  	regexPunycode = /^xn--/,
+  	regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars
+  	regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators
+
+  	/** Error messages */
+  	errors = {
+  		'overflow': 'Overflow: input needs wider integers to process',
+  		'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
+  		'invalid-input': 'Invalid input'
+  	},
+
+  	/** Convenience shortcuts */
+  	baseMinusTMin = base - tMin,
+  	floor = Math.floor,
+  	stringFromCharCode = String.fromCharCode,
+
+  	/** Temporary variable */
+  	key;
+
+  	/*--------------------------------------------------------------------------*/
+
+  	/**
+  	 * A generic error utility function.
+  	 * @private
+  	 * @param {String} type The error type.
+  	 * @returns {Error} Throws a `RangeError` with the applicable error message.
+  	 */
+  	function error(type) {
+  		throw RangeError(errors[type]);
+  	}
+
+  	/**
+  	 * A generic `Array#map` utility function.
+  	 * @private
+  	 * @param {Array} array The array to iterate over.
+  	 * @param {Function} callback The function that gets called for every array
+  	 * item.
+  	 * @returns {Array} A new array of values returned by the callback function.
+  	 */
+  	function map(array, fn) {
+  		var length = array.length;
+  		while (length--) {
+  			array[length] = fn(array[length]);
+  		}
+  		return array;
+  	}
+
+  	/**
+  	 * A simple `Array#map`-like wrapper to work with domain name strings.
+  	 * @private
+  	 * @param {String} domain The domain name.
+  	 * @param {Function} callback The function that gets called for every
+  	 * character.
+  	 * @returns {Array} A new string of characters returned by the callback
+  	 * function.
+  	 */
+  	function mapDomain(string, fn) {
+  		return map(string.split(regexSeparators), fn).join('.');
+  	}
+
+  	/**
+  	 * Creates an array containing the numeric code points of each Unicode
+  	 * character in the string. While JavaScript uses UCS-2 internally,
+  	 * this function will convert a pair of surrogate halves (each of which
+  	 * UCS-2 exposes as separate characters) into a single code point,
+  	 * matching UTF-16.
+  	 * @see `punycode.ucs2.encode`
+  	 * @see <http://mathiasbynens.be/notes/javascript-encoding>
+  	 * @memberOf punycode.ucs2
+  	 * @name decode
+  	 * @param {String} string The Unicode input string (UCS-2).
+  	 * @returns {Array} The new array of code points.
+  	 */
+  	function ucs2decode(string) {
+  		var output = [],
+  		    counter = 0,
+  		    length = string.length,
+  		    value,
+  		    extra;
+  		while (counter < length) {
+  			value = string.charCodeAt(counter++);
+  			if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
+  				// high surrogate, and there is a next character
+  				extra = string.charCodeAt(counter++);
+  				if ((extra & 0xFC00) == 0xDC00) { // low surrogate
+  					output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
+  				} else {
+  					// unmatched surrogate; only append this code unit, in case the next
+  					// code unit is the high surrogate of a surrogate pair
+  					output.push(value);
+  					counter--;
+  				}
+  			} else {
+  				output.push(value);
+  			}
+  		}
+  		return output;
+  	}
+
+  	/**
+  	 * Creates a string based on an array of numeric code points.
+  	 * @see `punycode.ucs2.decode`
+  	 * @memberOf punycode.ucs2
+  	 * @name encode
+  	 * @param {Array} codePoints The array of numeric code points.
+  	 * @returns {String} The new Unicode string (UCS-2).
+  	 */
+  	function ucs2encode(array) {
+  		return map(array, function(value) {
+  			var output = '';
+  			if (value > 0xFFFF) {
+  				value -= 0x10000;
+  				output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
+  				value = 0xDC00 | value & 0x3FF;
+  			}
+  			output += stringFromCharCode(value);
+  			return output;
+  		}).join('');
+  	}
+
+  	/**
+  	 * Converts a basic code point into a digit/integer.
+  	 * @see `digitToBasic()`
+  	 * @private
+  	 * @param {Number} codePoint The basic numeric code point value.
+  	 * @returns {Number} The numeric value of a basic code point (for use in
+  	 * representing integers) in the range `0` to `base - 1`, or `base` if
+  	 * the code point does not represent a value.
+  	 */
+  	function basicToDigit(codePoint) {
+  		if (codePoint - 48 < 10) {
+  			return codePoint - 22;
+  		}
+  		if (codePoint - 65 < 26) {
+  			return codePoint - 65;
+  		}
+  		if (codePoint - 97 < 26) {
+  			return codePoint - 97;
+  		}
+  		return base;
+  	}
+
+  	/**
+  	 * Converts a digit/integer into a basic code point.
+  	 * @see `basicToDigit()`
+  	 * @private
+  	 * @param {Number} digit The numeric value of a basic code point.
+  	 * @returns {Number} The basic code point whose value (when used for
+  	 * representing integers) is `digit`, which needs to be in the range
+  	 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
+  	 * used; else, the lowercase form is used. The behavior is undefined
+  	 * if `flag` is non-zero and `digit` has no uppercase form.
+  	 */
+  	function digitToBasic(digit, flag) {
+  		//  0..25 map to ASCII a..z or A..Z
+  		// 26..35 map to ASCII 0..9
+  		return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
+  	}
+
+  	/**
+  	 * Bias adaptation function as per section 3.4 of RFC 3492.
+  	 * http://tools.ietf.org/html/rfc3492#section-3.4
+  	 * @private
+  	 */
+  	function adapt(delta, numPoints, firstTime) {
+  		var k = 0;
+  		delta = firstTime ? floor(delta / damp) : delta >> 1;
+  		delta += floor(delta / numPoints);
+  		for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
+  			delta = floor(delta / baseMinusTMin);
+  		}
+  		return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
+  	}
+
+  	/**
+  	 * Converts a Punycode string of ASCII-only symbols to a string of Unicode
+  	 * symbols.
+  	 * @memberOf punycode
+  	 * @param {String} input The Punycode string of ASCII-only symbols.
+  	 * @returns {String} The resulting string of Unicode symbols.
+  	 */
+  	function decode(input) {
+  		// Don't use UCS-2
+  		var output = [],
+  		    inputLength = input.length,
+  		    out,
+  		    i = 0,
+  		    n = initialN,
+  		    bias = initialBias,
+  		    basic,
+  		    j,
+  		    index,
+  		    oldi,
+  		    w,
+  		    k,
+  		    digit,
+  		    t,
+  		    /** Cached calculation results */
+  		    baseMinusT;
+
+  		// Handle the basic code points: let `basic` be the number of input code
+  		// points before the last delimiter, or `0` if there is none, then copy
+  		// the first basic code points to the output.
+
+  		basic = input.lastIndexOf(delimiter);
+  		if (basic < 0) {
+  			basic = 0;
+  		}
+
+  		for (j = 0; j < basic; ++j) {
+  			// if it's not a basic code point
+  			if (input.charCodeAt(j) >= 0x80) {
+  				error('not-basic');
+  			}
+  			output.push(input.charCodeAt(j));
+  		}
+
+  		// Main decoding loop: start just after the last delimiter if any basic code
+  		// points were copied; start at the beginning otherwise.
+
+  		for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
+
+  			// `index` is the index of the next character to be consumed.
+  			// Decode a generalized variable-length integer into `delta`,
+  			// which gets added to `i`. The overflow checking is easier
+  			// if we increase `i` as we go, then subtract off its starting
+  			// value at the end to obtain `delta`.
+  			for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
+
+  				if (index >= inputLength) {
+  					error('invalid-input');
+  				}
+
+  				digit = basicToDigit(input.charCodeAt(index++));
+
+  				if (digit >= base || digit > floor((maxInt - i) / w)) {
+  					error('overflow');
+  				}
+
+  				i += digit * w;
+  				t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
+
+  				if (digit < t) {
+  					break;
+  				}
+
+  				baseMinusT = base - t;
+  				if (w > floor(maxInt / baseMinusT)) {
+  					error('overflow');
+  				}
+
+  				w *= baseMinusT;
+
+  			}
+
+  			out = output.length + 1;
+  			bias = adapt(i - oldi, out, oldi == 0);
+
+  			// `i` was supposed to wrap around from `out` to `0`,
+  			// incrementing `n` each time, so we'll fix that now:
+  			if (floor(i / out) > maxInt - n) {
+  				error('overflow');
+  			}
+
+  			n += floor(i / out);
+  			i %= out;
+
+  			// Insert `n` at position `i` of the output
+  			output.splice(i++, 0, n);
+
+  		}
+
+  		return ucs2encode(output);
+  	}
+
+  	/**
+  	 * Converts a string of Unicode symbols to a Punycode string of ASCII-only
+  	 * symbols.
+  	 * @memberOf punycode
+  	 * @param {String} input The string of Unicode symbols.
+  	 * @returns {String} The resulting Punycode string of ASCII-only symbols.
+  	 */
+  	function encode(input) {
+  		var n,
+  		    delta,
+  		    handledCPCount,
+  		    basicLength,
+  		    bias,
+  		    j,
+  		    m,
+  		    q,
+  		    k,
+  		    t,
+  		    currentValue,
+  		    output = [],
+  		    /** `inputLength` will hold the number of code points in `input`. */
+  		    inputLength,
+  		    /** Cached calculation results */
+  		    handledCPCountPlusOne,
+  		    baseMinusT,
+  		    qMinusT;
+
+  		// Convert the input in UCS-2 to Unicode
+  		input = ucs2decode(input);
+
+  		// Cache the length
+  		inputLength = input.length;
+
+  		// Initialize the state
+  		n = initialN;
+  		delta = 0;
+  		bias = initialBias;
+
+  		// Handle the basic code points
+  		for (j = 0; j < inputLength; ++j) {
+  			currentValue = input[j];
+  			if (currentValue < 0x80) {
+  				output.push(stringFromCharCode(currentValue));
+  			}
+  		}
+
+  		handledCPCount = basicLength = output.length;
+
+  		// `handledCPCount` is the number of code points that have been handled;
+  		// `basicLength` is the number of basic code points.
+
+  		// Finish the basic string - if it is not empty - with a delimiter
+  		if (basicLength) {
+  			output.push(delimiter);
+  		}
+
+  		// Main encoding loop:
+  		while (handledCPCount < inputLength) {
+
+  			// All non-basic code points < n have been handled already. Find the next
+  			// larger one:
+  			for (m = maxInt, j = 0; j < inputLength; ++j) {
+  				currentValue = input[j];
+  				if (currentValue >= n && currentValue < m) {
+  					m = currentValue;
+  				}
+  			}
+
+  			// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
+  			// but guard against overflow
+  			handledCPCountPlusOne = handledCPCount + 1;
+  			if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
+  				error('overflow');
+  			}
+
+  			delta += (m - n) * handledCPCountPlusOne;
+  			n = m;
+
+  			for (j = 0; j < inputLength; ++j) {
+  				currentValue = input[j];
+
+  				if (currentValue < n && ++delta > maxInt) {
+  					error('overflow');
+  				}
+
+  				if (currentValue == n) {
+  					// Represent delta as a generalized variable-length integer
+  					for (q = delta, k = base; /* no condition */; k += base) {
+  						t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
+  						if (q < t) {
+  							break;
+  						}
+  						qMinusT = q - t;
+  						baseMinusT = base - t;
+  						output.push(
+  							stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
+  						);
+  						q = floor(qMinusT / baseMinusT);
+  					}
+
+  					output.push(stringFromCharCode(digitToBasic(q, 0)));
+  					bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
+  					delta = 0;
+  					++handledCPCount;
+  				}
+  			}
+
+  			++delta;
+  			++n;
+
+  		}
+  		return output.join('');
+  	}
+
+  	/**
+  	 * Converts a Punycode string representing a domain name to Unicode. Only the
+  	 * Punycoded parts of the domain name will be converted, i.e. it doesn't
+  	 * matter if you call it on a string that has already been converted to
+  	 * Unicode.
+  	 * @memberOf punycode
+  	 * @param {String} domain The Punycode domain name to convert to Unicode.
+  	 * @returns {String} The Unicode representation of the given Punycode
+  	 * string.
+  	 */
+  	function toUnicode(domain) {
+  		return mapDomain(domain, function(string) {
+  			return regexPunycode.test(string)
+  				? decode(string.slice(4).toLowerCase())
+  				: string;
+  		});
+  	}
+
+  	/**
+  	 * Converts a Unicode string representing a domain name to Punycode. Only the
+  	 * non-ASCII parts of the domain name will be converted, i.e. it doesn't
+  	 * matter if you call it with a domain that's already in ASCII.
+  	 * @memberOf punycode
+  	 * @param {String} domain The domain name to convert, as a Unicode string.
+  	 * @returns {String} The Punycode representation of the given domain name.
+  	 */
+  	function toASCII(domain) {
+  		return mapDomain(domain, function(string) {
+  			return regexNonASCII.test(string)
+  				? 'xn--' + encode(string)
+  				: string;
+  		});
+  	}
+
+  	/*--------------------------------------------------------------------------*/
+
+  	/** Define the public API */
+  	punycode = {
+  		/**
+  		 * A string representing the current Punycode.js version number.
+  		 * @memberOf punycode
+  		 * @type String
+  		 */
+  		'version': '1.2.4',
+  		/**
+  		 * An object of methods to convert from JavaScript's internal character
+  		 * representation (UCS-2) to Unicode code points, and back.
+  		 * @see <http://mathiasbynens.be/notes/javascript-encoding>
+  		 * @memberOf punycode
+  		 * @type Object
+  		 */
+  		'ucs2': {
+  			'decode': ucs2decode,
+  			'encode': ucs2encode
+  		},
+  		'decode': decode,
+  		'encode': encode,
+  		'toASCII': toASCII,
+  		'toUnicode': toUnicode
+  	};
+
+  	/** Expose `punycode` */
+  	// Some AMD build optimizers, like r.js, check for specific condition patterns
+  	// like the following:
+  	if (
+  		typeof define == 'function' &&
+  		typeof define.amd == 'object' && define.amd && false
+  	) {
+  		define('punycode', function() {
+  			return punycode;
+  		});
+  	} else if (freeExports && !freeExports.nodeType) {
+  		if (freeModule) { // in Node.js or RingoJS v0.8.0+
+  			freeModule.exports = punycode;
+  		} else { // in Narwhal or RingoJS v0.7.0-
+  			for (key in punycode) {
+  				punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
+  			}
+  		}
+  	} else { // in Rhino or a web browser
+  		root.punycode = punycode;
+  	}
+
+  }(this));
+
+  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
+  },{}],2:[function(_dereq_,module,exports){
+  var log = _dereq_('./log');
+
+  function restoreOwnerScroll(ownerDocument, x, y) {
+      if (ownerDocument.defaultView && (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset)) {
+          ownerDocument.defaultView.scrollTo(x, y);
+      }
+  }
+
+  function cloneCanvasContents(canvas, clonedCanvas) {
+      try {
+          if (clonedCanvas) {
+              clonedCanvas.width = canvas.width;
+              clonedCanvas.height = canvas.height;
+              clonedCanvas.getContext("2d").putImageData(canvas.getContext("2d").getImageData(0, 0, canvas.width, canvas.height), 0, 0);
+          }
+      } catch(e) {
+          log("Unable to copy canvas content from", canvas, e);
+      }
+  }
+
+  function cloneNode(node, javascriptEnabled) {
+      var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);
+
+      var child = node.firstChild;
+      while(child) {
+          if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') {
+              clone.appendChild(cloneNode(child, javascriptEnabled));
+          }
+          child = child.nextSibling;
+      }
+
+      if (node.nodeType === 1) {
+          clone._scrollTop = node.scrollTop;
+          clone._scrollLeft = node.scrollLeft;
+          if (node.nodeName === "CANVAS") {
+              cloneCanvasContents(node, clone);
+          } else if (node.nodeName === "TEXTAREA" || node.nodeName === "SELECT") {
+              clone.value = node.value;
+          }
+      }
+
+      return clone;
+  }
+
+  function initNode(node) {
+      if (node.nodeType === 1) {
+          node.scrollTop = node._scrollTop;
+          node.scrollLeft = node._scrollLeft;
+
+          var child = node.firstChild;
+          while(child) {
+              initNode(child);
+              child = child.nextSibling;
+          }
+      }
+  }
+
+  module.exports = function(ownerDocument, containerDocument, width, height, options, x ,y) {
+      var documentElement = cloneNode(ownerDocument.documentElement, options.javascriptEnabled);
+      var container = containerDocument.createElement("iframe");
+
+      container.className = "html2canvas-container";
+      container.style.visibility = "hidden";
+      container.style.position = "fixed";
+      container.style.left = "-10000px";
+      container.style.top = "0px";
+      container.style.border = "0";
+      container.width = width;
+      container.height = height;
+      container.scrolling = "no"; // ios won't scroll without it
+      containerDocument.body.appendChild(container);
+
+      return new Promise(function(resolve) {
+          var documentClone = container.contentWindow.document;
+
+          /* Chrome doesn't detect relative background-images assigned in inline <style> sheets when fetched through getComputedStyle
+           if window url is about:blank, we can assign the url to current by writing onto the document
+           */
+          container.contentWindow.onload = container.onload = function() {
+              var interval = setInterval(function() {
+                  if (documentClone.body.childNodes.length > 0) {
+                      initNode(documentClone.documentElement);
+                      clearInterval(interval);
+                      if (options.type === "view") {
+                          container.contentWindow.scrollTo(x, y);
+                          if ((/(iPad|iPhone|iPod)/g).test(navigator.userAgent) && (container.contentWindow.scrollY !== y || container.contentWindow.scrollX !== x)) {
+                              documentClone.documentElement.style.top = (-y) + "px";
+                              documentClone.documentElement.style.left = (-x) + "px";
+                              documentClone.documentElement.style.position = 'absolute';
+                          }
+                      }
+                      resolve(container);
+                  }
+              }, 50);
+          };
+
+          documentClone.open();
+          documentClone.write("<!DOCTYPE html><html></html>");
+          // Chrome scrolls the parent document for some reason after the write to the cloned window???
+          restoreOwnerScroll(ownerDocument, x, y);
+          documentClone.replaceChild(documentClone.adoptNode(documentElement), documentClone.documentElement);
+          documentClone.close();
+      });
+  };
+
+  },{"./log":13}],3:[function(_dereq_,module,exports){
+  // http://dev.w3.org/csswg/css-color/
+
+  function Color(value) {
+      this.r = 0;
+      this.g = 0;
+      this.b = 0;
+      this.a = null;
+      var result = this.fromArray(value) ||
+          this.namedColor(value) ||
+          this.rgb(value) ||
+          this.rgba(value) ||
+          this.hex6(value) ||
+          this.hex3(value);
+  }
+
+  Color.prototype.darken = function(amount) {
+      var a = 1 - amount;
+      return  new Color([
+          Math.round(this.r * a),
+          Math.round(this.g * a),
+          Math.round(this.b * a),
+          this.a
+      ]);
+  };
+
+  Color.prototype.isTransparent = function() {
+      return this.a === 0;
+  };
+
+  Color.prototype.isBlack = function() {
+      return this.r === 0 && this.g === 0 && this.b === 0;
+  };
+
+  Color.prototype.fromArray = function(array) {
+      if (Array.isArray(array)) {
+          this.r = Math.min(array[0], 255);
+          this.g = Math.min(array[1], 255);
+          this.b = Math.min(array[2], 255);
+          if (array.length > 3) {
+              this.a = array[3];
+          }
+      }
+
+      return (Array.isArray(array));
+  };
+
+  var _hex3 = /^#([a-f0-9]{3})$/i;
+
+  Color.prototype.hex3 = function(value) {
+      var match = null;
+      if ((match = value.match(_hex3)) !== null) {
+          this.r = parseInt(match[1][0] + match[1][0], 16);
+          this.g = parseInt(match[1][1] + match[1][1], 16);
+          this.b = parseInt(match[1][2] + match[1][2], 16);
+      }
+      return match !== null;
+  };
+
+  var _hex6 = /^#([a-f0-9]{6})$/i;
+
+  Color.prototype.hex6 = function(value) {
+      var match = null;
+      if ((match = value.match(_hex6)) !== null) {
+          this.r = parseInt(match[1].substring(0, 2), 16);
+          this.g = parseInt(match[1].substring(2, 4), 16);
+          this.b = parseInt(match[1].substring(4, 6), 16);
+      }
+      return match !== null;
+  };
+
+
+  var _rgb = /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/;
+
+  Color.prototype.rgb = function(value) {
+      var match = null;
+      if ((match = value.match(_rgb)) !== null) {
+          this.r = Number(match[1]);
+          this.g = Number(match[2]);
+          this.b = Number(match[3]);
+      }
+      return match !== null;
+  };
+
+  var _rgba = /^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d?\.?\d+)\s*\)$/;
+
+  Color.prototype.rgba = function(value) {
+      var match = null;
+      if ((match = value.match(_rgba)) !== null) {
+          this.r = Number(match[1]);
+          this.g = Number(match[2]);
+          this.b = Number(match[3]);
+          this.a = Number(match[4]);
+      }
+      return match !== null;
+  };
+
+  Color.prototype.toString = function() {
+      return this.a !== null && this.a !== 1 ?
+      "rgba(" + [this.r, this.g, this.b, this.a].join(",") + ")" :
+      "rgb(" + [this.r, this.g, this.b].join(",") + ")";
+  };
+
+  Color.prototype.namedColor = function(value) {
+      value = value.toLowerCase();
+      var color = colors[value];
+      if (color) {
+          this.r = color[0];
+          this.g = color[1];
+          this.b = color[2];
+      } else if (value === "transparent") {
+          this.r = this.g = this.b = this.a = 0;
+          return true;
+      }
+
+      return !!color;
+  };
+
+  Color.prototype.isColor = true;
+
+  // JSON.stringify([].slice.call($$('.named-color-table tr'), 1).map(function(row) { return [row.childNodes[3].textContent, row.childNodes[5].textContent.trim().split(",").map(Number)] }).reduce(function(data, row) {data[row[0]] = row[1]; return data}, {}))
+  var colors = {
+      "aliceblue": [240, 248, 255],
+      "antiquewhite": [250, 235, 215],
+      "aqua": [0, 255, 255],
+      "aquamarine": [127, 255, 212],
+      "azure": [240, 255, 255],
+      "beige": [245, 245, 220],
+      "bisque": [255, 228, 196],
+      "black": [0, 0, 0],
+      "blanchedalmond": [255, 235, 205],
+      "blue": [0, 0, 255],
+      "blueviolet": [138, 43, 226],
+      "brown": [165, 42, 42],
+      "burlywood": [222, 184, 135],
+      "cadetblue": [95, 158, 160],
+      "chartreuse": [127, 255, 0],
+      "chocolate": [210, 105, 30],
+      "coral": [255, 127, 80],
+      "cornflowerblue": [100, 149, 237],
+      "cornsilk": [255, 248, 220],
+      "crimson": [220, 20, 60],
+      "cyan": [0, 255, 255],
+      "darkblue": [0, 0, 139],
+      "darkcyan": [0, 139, 139],
+      "darkgoldenrod": [184, 134, 11],
+      "darkgray": [169, 169, 169],
+      "darkgreen": [0, 100, 0],
+      "darkgrey": [169, 169, 169],
+      "darkkhaki": [189, 183, 107],
+      "darkmagenta": [139, 0, 139],
+      "darkolivegreen": [85, 107, 47],
+      "darkorange": [255, 140, 0],
+      "darkorchid": [153, 50, 204],
+      "darkred": [139, 0, 0],
+      "darksalmon": [233, 150, 122],
+      "darkseagreen": [143, 188, 143],
+      "darkslateblue": [72, 61, 139],
+      "darkslategray": [47, 79, 79],
+      "darkslategrey": [47, 79, 79],
+      "darkturquoise": [0, 206, 209],
+      "darkviolet": [148, 0, 211],
+      "deeppink": [255, 20, 147],
+      "deepskyblue": [0, 191, 255],
+      "dimgray": [105, 105, 105],
+      "dimgrey": [105, 105, 105],
+      "dodgerblue": [30, 144, 255],
+      "firebrick": [178, 34, 34],
+      "floralwhite": [255, 250, 240],
+      "forestgreen": [34, 139, 34],
+      "fuchsia": [255, 0, 255],
+      "gainsboro": [220, 220, 220],
+      "ghostwhite": [248, 248, 255],
+      "gold": [255, 215, 0],
+      "goldenrod": [218, 165, 32],
+      "gray": [128, 128, 128],
+      "green": [0, 128, 0],
+      "greenyellow": [173, 255, 47],
+      "grey": [128, 128, 128],
+      "honeydew": [240, 255, 240],
+      "hotpink": [255, 105, 180],
+      "indianred": [205, 92, 92],
+      "indigo": [75, 0, 130],
+      "ivory": [255, 255, 240],
+      "khaki": [240, 230, 140],
+      "lavender": [230, 230, 250],
+      "lavenderblush": [255, 240, 245],
+      "lawngreen": [124, 252, 0],
+      "lemonchiffon": [255, 250, 205],
+      "lightblue": [173, 216, 230],
+      "lightcoral": [240, 128, 128],
+      "lightcyan": [224, 255, 255],
+      "lightgoldenrodyellow": [250, 250, 210],
+      "lightgray": [211, 211, 211],
+      "lightgreen": [144, 238, 144],
+      "lightgrey": [211, 211, 211],
+      "lightpink": [255, 182, 193],
+      "lightsalmon": [255, 160, 122],
+      "lightseagreen": [32, 178, 170],
+      "lightskyblue": [135, 206, 250],
+      "lightslategray": [119, 136, 153],
+      "lightslategrey": [119, 136, 153],
+      "lightsteelblue": [176, 196, 222],
+      "lightyellow": [255, 255, 224],
+      "lime": [0, 255, 0],
+      "limegreen": [50, 205, 50],
+      "linen": [250, 240, 230],
+      "magenta": [255, 0, 255],
+      "maroon": [128, 0, 0],
+      "mediumaquamarine": [102, 205, 170],
+      "mediumblue": [0, 0, 205],
+      "mediumorchid": [186, 85, 211],
+      "mediumpurple": [147, 112, 219],
+      "mediumseagreen": [60, 179, 113],
+      "mediumslateblue": [123, 104, 238],
+      "mediumspringgreen": [0, 250, 154],
+      "mediumturquoise": [72, 209, 204],
+      "mediumvioletred": [199, 21, 133],
+      "midnightblue": [25, 25, 112],
+      "mintcream": [245, 255, 250],
+      "mistyrose": [255, 228, 225],
+      "moccasin": [255, 228, 181],
+      "navajowhite": [255, 222, 173],
+      "navy": [0, 0, 128],
+      "oldlace": [253, 245, 230],
+      "olive": [128, 128, 0],
+      "olivedrab": [107, 142, 35],
+      "orange": [255, 165, 0],
+      "orangered": [255, 69, 0],
+      "orchid": [218, 112, 214],
+      "palegoldenrod": [238, 232, 170],
+      "palegreen": [152, 251, 152],
+      "paleturquoise": [175, 238, 238],
+      "palevioletred": [219, 112, 147],
+      "papayawhip": [255, 239, 213],
+      "peachpuff": [255, 218, 185],
+      "peru": [205, 133, 63],
+      "pink": [255, 192, 203],
+      "plum": [221, 160, 221],
+      "powderblue": [176, 224, 230],
+      "purple": [128, 0, 128],
+      "rebeccapurple": [102, 51, 153],
+      "red": [255, 0, 0],
+      "rosybrown": [188, 143, 143],
+      "royalblue": [65, 105, 225],
+      "saddlebrown": [139, 69, 19],
+      "salmon": [250, 128, 114],
+      "sandybrown": [244, 164, 96],
+      "seagreen": [46, 139, 87],
+      "seashell": [255, 245, 238],
+      "sienna": [160, 82, 45],
+      "silver": [192, 192, 192],
+      "skyblue": [135, 206, 235],
+      "slateblue": [106, 90, 205],
+      "slategray": [112, 128, 144],
+      "slategrey": [112, 128, 144],
+      "snow": [255, 250, 250],
+      "springgreen": [0, 255, 127],
+      "steelblue": [70, 130, 180],
+      "tan": [210, 180, 140],
+      "teal": [0, 128, 128],
+      "thistle": [216, 191, 216],
+      "tomato": [255, 99, 71],
+      "turquoise": [64, 224, 208],
+      "violet": [238, 130, 238],
+      "wheat": [245, 222, 179],
+      "white": [255, 255, 255],
+      "whitesmoke": [245, 245, 245],
+      "yellow": [255, 255, 0],
+      "yellowgreen": [154, 205, 50]
+  };
+
+  module.exports = Color;
+
+  },{}],4:[function(_dereq_,module,exports){
+  var Support = _dereq_('./support');
+  var CanvasRenderer = _dereq_('./renderers/canvas');
+  var ImageLoader = _dereq_('./imageloader');
+  var NodeParser = _dereq_('./nodeparser');
+  var NodeContainer = _dereq_('./nodecontainer');
+  var log = _dereq_('./log');
+  var utils = _dereq_('./utils');
+  var createWindowClone = _dereq_('./clone');
+  var loadUrlDocument = _dereq_('./proxy').loadUrlDocument;
+  var getBounds = utils.getBounds;
+
+  var html2canvasNodeAttribute = "data-html2canvas-node";
+  var html2canvasCloneIndex = 0;
+
+  function html2canvas(nodeList, options) {
+      var index = html2canvasCloneIndex++;
+      options = options || {};
+      if (options.logging) {
+          log.options.logging = true;
+          log.options.start = Date.now();
+      }
+
+      options.async = typeof(options.async) === "undefined" ? true : options.async;
+      options.allowTaint = typeof(options.allowTaint) === "undefined" ? false : options.allowTaint;
+      options.removeContainer = typeof(options.removeContainer) === "undefined" ? true : options.removeContainer;
+      options.javascriptEnabled = typeof(options.javascriptEnabled) === "undefined" ? false : options.javascriptEnabled;
+      options.imageTimeout = typeof(options.imageTimeout) === "undefined" ? 10000 : options.imageTimeout;
+      options.renderer = typeof(options.renderer) === "function" ? options.renderer : CanvasRenderer;
+      options.strict = !!options.strict;
+
+      if (typeof(nodeList) === "string") {
+          if (typeof(options.proxy) !== "string") {
+              return Promise.reject("Proxy must be used when rendering url");
+          }
+          var width = options.width != null ? options.width : window.innerWidth;
+          var height = options.height != null ? options.height : window.innerHeight;
+          return loadUrlDocument(absoluteUrl(nodeList), options.proxy, document, width, height, options).then(function(container) {
+              return renderWindow(container.contentWindow.document.documentElement, container, options, width, height);
+          });
+      }
+
+      var node = ((nodeList === undefined) ? [document.documentElement] : ((nodeList.length) ? nodeList : [nodeList]))[0];
+      node.setAttribute(html2canvasNodeAttribute + index, index);
+      return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function(canvas) {
+          if (typeof(options.onrendered) === "function") {
+              log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");
+              options.onrendered(canvas);
+          }
+          return canvas;
+      });
+  }
+
+  html2canvas.CanvasRenderer = CanvasRenderer;
+  html2canvas.NodeContainer = NodeContainer;
+  html2canvas.log = log;
+  html2canvas.utils = utils;
+
+  var html2canvasExport = (typeof(document) === "undefined" || typeof(Object.create) !== "function" || typeof(document.createElement("canvas").getContext) !== "function") ? function() {
+      return Promise.reject("No canvas support");
+  } : html2canvas;
+
+  module.exports = html2canvasExport;
+
+  if (typeof(define) === 'function' && define.amd && false) {
+      define('html2canvas', [], function() {
+          return html2canvasExport;
+      });
+  }
+
+  function renderDocument(document, options, windowWidth, windowHeight, html2canvasIndex) {
+      return createWindowClone(document, document, windowWidth, windowHeight, options, document.defaultView.pageXOffset, document.defaultView.pageYOffset).then(function(container) {
+          log("Document cloned");
+          var attributeName = html2canvasNodeAttribute + html2canvasIndex;
+          var selector = "[" + attributeName + "='" + html2canvasIndex + "']";
+          document.querySelector(selector).removeAttribute(attributeName);
+          var clonedWindow = container.contentWindow;
+          var node = clonedWindow.document.querySelector(selector);
+          var oncloneHandler = (typeof(options.onclone) === "function") ? Promise.resolve(options.onclone(clonedWindow.document)) : Promise.resolve(true);
+          return oncloneHandler.then(function() {
+              return renderWindow(node, container, options, windowWidth, windowHeight);
+          });
+      });
+  }
+
+  function renderWindow(node, container, options, windowWidth, windowHeight) {
+      var clonedWindow = container.contentWindow;
+      var support = new Support(clonedWindow.document);
+      var imageLoader = new ImageLoader(options, support);
+      var bounds = getBounds(node);
+      var width = options.type === "view" ? windowWidth : documentWidth(clonedWindow.document);
+      var height = options.type === "view" ? windowHeight : documentHeight(clonedWindow.document);
+      var renderer = new options.renderer(width, height, imageLoader, options, document);
+      var parser = new NodeParser(node, renderer, support, imageLoader, options);
+      return parser.ready.then(function() {
+          log("Finished rendering");
+          var canvas;
+
+          if (options.type === "view") {
+              canvas = crop(renderer.canvas, {width: renderer.canvas.width, height: renderer.canvas.height, top: 0, left: 0, x: 0, y: 0});
+          } else if (node === clonedWindow.document.body || node === clonedWindow.document.documentElement || options.canvas != null) {
+              canvas = renderer.canvas;
+          } else {
+              canvas = crop(renderer.canvas, {width:  options.width != null ? options.width : bounds.width, height: options.height != null ? options.height : bounds.height, top: bounds.top, left: bounds.left, x: 0, y: 0});
+          }
+
+          cleanupContainer(container, options);
+          return canvas;
+      });
+  }
+
+  function cleanupContainer(container, options) {
+      if (options.removeContainer) {
+          container.parentNode.removeChild(container);
+          log("Cleaned up container");
+      }
+  }
+
+  function crop(canvas, bounds) {
+      var croppedCanvas = document.createElement("canvas");
+      var x1 = Math.min(canvas.width - 1, Math.max(0, bounds.left));
+      var x2 = Math.min(canvas.width, Math.max(1, bounds.left + bounds.width));
+      var y1 = Math.min(canvas.height - 1, Math.max(0, bounds.top));
+      var y2 = Math.min(canvas.height, Math.max(1, bounds.top + bounds.height));
+      croppedCanvas.width = bounds.width;
+      croppedCanvas.height =  bounds.height;
+      var width = x2-x1;
+      var height = y2-y1;
+      log("Cropping canvas at:", "left:", bounds.left, "top:", bounds.top, "width:", width, "height:", height);
+      log("Resulting crop with width", bounds.width, "and height", bounds.height, "with x", x1, "and y", y1);
+      croppedCanvas.getContext("2d").drawImage(canvas, x1, y1, width, height, bounds.x, bounds.y, width, height);
+      return croppedCanvas;
+  }
+
+  function documentWidth (doc) {
+      return Math.max(
+          Math.max(doc.body.scrollWidth, doc.documentElement.scrollWidth),
+          Math.max(doc.body.offsetWidth, doc.documentElement.offsetWidth),
+          Math.max(doc.body.clientWidth, doc.documentElement.clientWidth)
+      );
+  }
+
+  function documentHeight (doc) {
+      return Math.max(
+          Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight),
+          Math.max(doc.body.offsetHeight, doc.documentElement.offsetHeight),
+          Math.max(doc.body.clientHeight, doc.documentElement.clientHeight)
+      );
+  }
+
+  function absoluteUrl(url) {
+      var link = document.createElement("a");
+      link.href = url;
+      link.href = link.href;
+      return link;
+  }
+
+  },{"./clone":2,"./imageloader":11,"./log":13,"./nodecontainer":14,"./nodeparser":15,"./proxy":16,"./renderers/canvas":20,"./support":22,"./utils":26}],5:[function(_dereq_,module,exports){
+  var log = _dereq_('./log');
+  var smallImage = _dereq_('./utils').smallImage;
+
+  function DummyImageContainer(src) {
+      this.src = src;
+      log("DummyImageContainer for", src);
+      if (!this.promise || !this.image) {
+          log("Initiating DummyImageContainer");
+          DummyImageContainer.prototype.image = new Image();
+          var image = this.image;
+          DummyImageContainer.prototype.promise = new Promise(function(resolve, reject) {
+              image.onload = resolve;
+              image.onerror = reject;
+              image.src = smallImage();
+              if (image.complete === true) {
+                  resolve(image);
+              }
+          });
+      }
+  }
+
+  module.exports = DummyImageContainer;
+
+  },{"./log":13,"./utils":26}],6:[function(_dereq_,module,exports){
+  var smallImage = _dereq_('./utils').smallImage;
+
+  function Font(family, size) {
+      var container = document.createElement('div'),
+          img = document.createElement('img'),
+          span = document.createElement('span'),
+          sampleText = 'Hidden Text',
+          baseline,
+          middle;
+
+      container.style.visibility = "hidden";
+      container.style.fontFamily = family;
+      container.style.fontSize = size;
+      container.style.margin = 0;
+      container.style.padding = 0;
+
+      document.body.appendChild(container);
+
+      img.src = smallImage();
+      img.width = 1;
+      img.height = 1;
+
+      img.style.margin = 0;
+      img.style.padding = 0;
+      img.style.verticalAlign = "baseline";
+
+      span.style.fontFamily = family;
+      span.style.fontSize = size;
+      span.style.margin = 0;
+      span.style.padding = 0;
+
+      span.appendChild(document.createTextNode(sampleText));
+      container.appendChild(span);
+      container.appendChild(img);
+      baseline = (img.offsetTop - span.offsetTop) + 1;
+
+      container.removeChild(span);
+      container.appendChild(document.createTextNode(sampleText));
+
+      container.style.lineHeight = "normal";
+      img.style.verticalAlign = "super";
+
+      middle = (img.offsetTop-container.offsetTop) + 1;
+
+      document.body.removeChild(container);
+
+      this.baseline = baseline;
+      this.lineWidth = 1;
+      this.middle = middle;
+  }
+
+  module.exports = Font;
+
+  },{"./utils":26}],7:[function(_dereq_,module,exports){
+  var Font = _dereq_('./font');
+
+  function FontMetrics() {
+      this.data = {};
+  }
+
+  FontMetrics.prototype.getMetrics = function(family, size) {
+      if (this.data[family + "-" + size] === undefined) {
+          this.data[family + "-" + size] = new Font(family, size);
+      }
+      return this.data[family + "-" + size];
+  };
+
+  module.exports = FontMetrics;
+
+  },{"./font":6}],8:[function(_dereq_,module,exports){
+  var utils = _dereq_('./utils');
+  var getBounds = utils.getBounds;
+  var loadUrlDocument = _dereq_('./proxy').loadUrlDocument;
+
+  function FrameContainer(container, sameOrigin, options) {
+      this.image = null;
+      this.src = container;
+      var self = this;
+      var bounds = getBounds(container);
+      this.promise = (!sameOrigin ? this.proxyLoad(options.proxy, bounds, options) : new Promise(function(resolve) {
+          if (container.contentWindow.document.URL === "about:blank" || container.contentWindow.document.documentElement == null) {
+              container.contentWindow.onload = container.onload = function() {
+                  resolve(container);
+              };
+          } else {
+              resolve(container);
+          }
+      })).then(function(container) {
+          var html2canvas = _dereq_('./core');
+          return html2canvas(container.contentWindow.document.documentElement, {type: 'view', width: container.width, height: container.height, proxy: options.proxy, javascriptEnabled: options.javascriptEnabled, removeContainer: options.removeContainer, allowTaint: options.allowTaint, imageTimeout: options.imageTimeout / 2});
+      }).then(function(canvas) {
+          return self.image = canvas;
+      });
+  }
+
+  FrameContainer.prototype.proxyLoad = function(proxy, bounds, options) {
+      var container = this.src;
+      return loadUrlDocument(container.src, proxy, container.ownerDocument, bounds.width, bounds.height, options);
+  };
+
+  module.exports = FrameContainer;
+
+  },{"./core":4,"./proxy":16,"./utils":26}],9:[function(_dereq_,module,exports){
+  function GradientContainer(imageData) {
+      this.src = imageData.value;
+      this.colorStops = [];
+      this.type = null;
+      this.x0 = 0.5;
+      this.y0 = 0.5;
+      this.x1 = 0.5;
+      this.y1 = 0.5;
+      this.promise = Promise.resolve(true);
+  }
+
+  GradientContainer.TYPES = {
+      LINEAR: 1,
+      RADIAL: 2
+  };
+
+  // TODO: support hsl[a], negative %/length values
+  // TODO: support <angle> (e.g. -?\d{1,3}(?:\.\d+)deg, etc. : https://developer.mozilla.org/docs/Web/CSS/angle )
+  GradientContainer.REGEXP_COLORSTOP = /^\s*(rgba?\(\s*\d{1,3},\s*\d{1,3},\s*\d{1,3}(?:,\s*[0-9\.]+)?\s*\)|[a-z]{3,20}|#[a-f0-9]{3,6})(?:\s+(\d{1,3}(?:\.\d+)?)(%|px)?)?(?:\s|$)/i;
+
+  module.exports = GradientContainer;
+
+  },{}],10:[function(_dereq_,module,exports){
+  function ImageContainer(src, cors) {
+      this.src = src;
+      this.image = new Image();
+      var self = this;
+      this.tainted = null;
+      this.promise = new Promise(function(resolve, reject) {
+          self.image.onload = resolve;
+          self.image.onerror = reject;
+          if (cors) {
+              self.image.crossOrigin = "anonymous";
+          }
+          self.image.src = src;
+          if (self.image.complete === true) {
+              resolve(self.image);
+          }
+      });
+  }
+
+  module.exports = ImageContainer;
+
+  },{}],11:[function(_dereq_,module,exports){
+  var log = _dereq_('./log');
+  var ImageContainer = _dereq_('./imagecontainer');
+  var DummyImageContainer = _dereq_('./dummyimagecontainer');
+  var ProxyImageContainer = _dereq_('./proxyimagecontainer');
+  var FrameContainer = _dereq_('./framecontainer');
+  var SVGContainer = _dereq_('./svgcontainer');
+  var SVGNodeContainer = _dereq_('./svgnodecontainer');
+  var LinearGradientContainer = _dereq_('./lineargradientcontainer');
+  var WebkitGradientContainer = _dereq_('./webkitgradientcontainer');
+  var bind = _dereq_('./utils').bind;
+
+  function ImageLoader(options, support) {
+      this.link = null;
+      this.options = options;
+      this.support = support;
+      this.origin = this.getOrigin(window.location.href);
+  }
+
+  ImageLoader.prototype.findImages = function(nodes) {
+      var images = [];
+      nodes.reduce(function(imageNodes, container) {
+          switch(container.node.nodeName) {
+          case "IMG":
+              return imageNodes.concat([{
+                  args: [container.node.src],
+                  method: "url"
+              }]);
+          case "svg":
+          case "IFRAME":
+              return imageNodes.concat([{
+                  args: [container.node],
+                  method: container.node.nodeName
+              }]);
+          }
+          return imageNodes;
+      }, []).forEach(this.addImage(images, this.loadImage), this);
+      return images;
+  };
+
+  ImageLoader.prototype.findBackgroundImage = function(images, container) {
+      container.parseBackgroundImages().filter(this.hasImageBackground).forEach(this.addImage(images, this.loadImage), this);
+      return images;
+  };
+
+  ImageLoader.prototype.addImage = function(images, callback) {
+      return function(newImage) {
+          newImage.args.forEach(function(image) {
+              if (!this.imageExists(images, image)) {
+                  images.splice(0, 0, callback.call(this, newImage));
+                  log('Added image #' + (images.length), typeof(image) === "string" ? image.substring(0, 100) : image);
+              }
+          }, this);
+      };
+  };
+
+  ImageLoader.prototype.hasImageBackground = function(imageData) {
+      return imageData.method !== "none";
+  };
+
+  ImageLoader.prototype.loadImage = function(imageData) {
+      if (imageData.method === "url") {
+          var src = imageData.args[0];
+          if (this.isSVG(src) && !this.support.svg && !this.options.allowTaint) {
+              return new SVGContainer(src);
+          } else if (src.match(/data:image\/.*;base64,/i)) {
+              return new ImageContainer(src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, ''), false);
+          } else if (this.isSameOrigin(src) || this.options.allowTaint === true || this.isSVG(src)) {
+              return new ImageContainer(src, false);
+          } else if (this.support.cors && !this.options.allowTaint && this.options.useCORS) {
+              return new ImageContainer(src, true);
+          } else if (this.options.proxy) {
+              return new ProxyImageContainer(src, this.options.proxy);
+          } else {
+              return new DummyImageContainer(src);
+          }
+      } else if (imageData.method === "linear-gradient") {
+          return new LinearGradientContainer(imageData);
+      } else if (imageData.method === "gradient") {
+          return new WebkitGradientContainer(imageData);
+      } else if (imageData.method === "svg") {
+          return new SVGNodeContainer(imageData.args[0], this.support.svg);
+      } else if (imageData.method === "IFRAME") {
+          return new FrameContainer(imageData.args[0], this.isSameOrigin(imageData.args[0].src), this.options);
+      } else {
+          return new DummyImageContainer(imageData);
+      }
+  };
+
+  ImageLoader.prototype.isSVG = function(src) {
+      return src.substring(src.length - 3).toLowerCase() === "svg" || SVGContainer.prototype.isInline(src);
+  };
+
+  ImageLoader.prototype.imageExists = function(images, src) {
+      return images.some(function(image) {
+          return image.src === src;
+      });
+  };
+
+  ImageLoader.prototype.isSameOrigin = function(url) {
+      return (this.getOrigin(url) === this.origin);
+  };
+
+  ImageLoader.prototype.getOrigin = function(url) {
+      var link = this.link || (this.link = document.createElement("a"));
+      link.href = url;
+      link.href = link.href; // IE9, LOL! - http://jsfiddle.net/niklasvh/2e48b/
+      return link.protocol + link.hostname + link.port;
+  };
+
+  ImageLoader.prototype.getPromise = function(container) {
+      return this.timeout(container, this.options.imageTimeout)['catch'](function() {
+          var dummy = new DummyImageContainer(container.src);
+          return dummy.promise.then(function(image) {
+              container.image = image;
+          });
+      });
+  };
+
+  ImageLoader.prototype.get = function(src) {
+      var found = null;
+      return this.images.some(function(img) {
+          return (found = img).src === src;
+      }) ? found : null;
+  };
+
+  ImageLoader.prototype.fetch = function(nodes) {
+      this.images = nodes.reduce(bind(this.findBackgroundImage, this), this.findImages(nodes));
+      this.images.forEach(function(image, index) {
+          image.promise.then(function() {
+              log("Succesfully loaded image #"+ (index+1), image);
+          }, function(e) {
+              log("Failed loading image #"+ (index+1), image, e);
+          });
+      });
+      this.ready = Promise.all(this.images.map(this.getPromise, this));
+      log("Finished searching images");
+      return this;
+  };
+
+  ImageLoader.prototype.timeout = function(container, timeout) {
+      var timer;
+      var promise = Promise.race([container.promise, new Promise(function(res, reject) {
+          timer = setTimeout(function() {
+              log("Timed out loading image", container);
+              reject(container);
+          }, timeout);
+      })]).then(function(container) {
+          clearTimeout(timer);
+          return container;
+      });
+      promise['catch'](function() {
+          clearTimeout(timer);
+      });
+      return promise;
+  };
+
+  module.exports = ImageLoader;
+
+  },{"./dummyimagecontainer":5,"./framecontainer":8,"./imagecontainer":10,"./lineargradientcontainer":12,"./log":13,"./proxyimagecontainer":17,"./svgcontainer":23,"./svgnodecontainer":24,"./utils":26,"./webkitgradientcontainer":27}],12:[function(_dereq_,module,exports){
+  var GradientContainer = _dereq_('./gradientcontainer');
+  var Color = _dereq_('./color');
+
+  function LinearGradientContainer(imageData) {
+      GradientContainer.apply(this, arguments);
+      this.type = GradientContainer.TYPES.LINEAR;
+
+      var hasDirection = LinearGradientContainer.REGEXP_DIRECTION.test( imageData.args[0] ) ||
+          !GradientContainer.REGEXP_COLORSTOP.test( imageData.args[0] );
+
+      if (hasDirection) {
+          imageData.args[0].split(/\s+/).reverse().forEach(function(position, index) {
+              switch(position) {
+              case "left":
+                  this.x0 = 0;
+                  this.x1 = 1;
+                  break;
+              case "top":
+                  this.y0 = 0;
+                  this.y1 = 1;
+                  break;
+              case "right":
+                  this.x0 = 1;
+                  this.x1 = 0;
+                  break;
+              case "bottom":
+                  this.y0 = 1;
+                  this.y1 = 0;
+                  break;
+              case "to":
+                  var y0 = this.y0;
+                  var x0 = this.x0;
+                  this.y0 = this.y1;
+                  this.x0 = this.x1;
+                  this.x1 = x0;
+                  this.y1 = y0;
+                  break;
+              case "center":
+                  break; // centered by default
+              // Firefox internally converts position keywords to percentages:
+              // http://www.w3.org/TR/2010/WD-CSS2-20101207/colors.html#propdef-background-position
+              default: // percentage or absolute length
+                  // TODO: support absolute start point positions (e.g., use bounds to convert px to a ratio)
+                  var ratio = parseFloat(position, 10) * 1e-2;
+                  if (isNaN(ratio)) { // invalid or unhandled value
+                      break;
+                  }
+                  if (index === 0) {
+                      this.y0 = ratio;
+                      this.y1 = 1 - this.y0;
+                  } else {
+                      this.x0 = ratio;
+                      this.x1 = 1 - this.x0;
+                  }
+                  break;
+              }
+          }, this);
+      } else {
+          this.y0 = 0;
+          this.y1 = 1;
+      }
+
+      this.colorStops = imageData.args.slice(hasDirection ? 1 : 0).map(function(colorStop) {
+          var colorStopMatch = colorStop.match(GradientContainer.REGEXP_COLORSTOP);
+          var value = +colorStopMatch[2];
+          var unit = value === 0 ? "%" : colorStopMatch[3]; // treat "0" as "0%"
+          return {
+              color: new Color(colorStopMatch[1]),
+              // TODO: support absolute stop positions (e.g., compute gradient line length & convert px to ratio)
+              stop: unit === "%" ? value / 100 : null
+          };
+      });
+
+      if (this.colorStops[0].stop === null) {
+          this.colorStops[0].stop = 0;
+      }
+
+      if (this.colorStops[this.colorStops.length - 1].stop === null) {
+          this.colorStops[this.colorStops.length - 1].stop = 1;
+      }
+
+      // calculates and fills-in explicit stop positions when omitted from rule
+      this.colorStops.forEach(function(colorStop, index) {
+          if (colorStop.stop === null) {
+              this.colorStops.slice(index).some(function(find, count) {
+                  if (find.stop !== null) {
+                      colorStop.stop = ((find.stop - this.colorStops[index - 1].stop) / (count + 1)) + this.colorStops[index - 1].stop;
+                      return true;
+                  } else {
+                      return false;
+                  }
+              }, this);
+          }
+      }, this);
+  }
+
+  LinearGradientContainer.prototype = Object.create(GradientContainer.prototype);
+
+  // TODO: support <angle> (e.g. -?\d{1,3}(?:\.\d+)deg, etc. : https://developer.mozilla.org/docs/Web/CSS/angle )
+  LinearGradientContainer.REGEXP_DIRECTION = /^\s*(?:to|left|right|top|bottom|center|\d{1,3}(?:\.\d+)?%?)(?:\s|$)/i;
+
+  module.exports = LinearGradientContainer;
+
+  },{"./color":3,"./gradientcontainer":9}],13:[function(_dereq_,module,exports){
+  var logger = function() {
+      if (logger.options.logging && window.console && window.console.log) {
+          Function.prototype.bind.call(window.console.log, (window.console)).apply(window.console, [(Date.now() - logger.options.start) + "ms", "html2canvas:"].concat([].slice.call(arguments, 0)));
+      }
+  };
+
+  logger.options = {logging: false};
+  module.exports = logger;
+
+  },{}],14:[function(_dereq_,module,exports){
+  var Color = _dereq_('./color');
+  var utils = _dereq_('./utils');
+  var getBounds = utils.getBounds;
+  var parseBackgrounds = utils.parseBackgrounds;
+  var offsetBounds = utils.offsetBounds;
+
+  function NodeContainer(node, parent) {
+      this.node = node;
+      this.parent = parent;
+      this.stack = null;
+      this.bounds = null;
+      this.borders = null;
+      this.clip = [];
+      this.backgroundClip = [];
+      this.offsetBounds = null;
+      this.visible = null;
+      this.computedStyles = null;
+      this.colors = {};
+      this.styles = {};
+      this.backgroundImages = null;
+      this.transformData = null;
+      this.transformMatrix = null;
+      this.isPseudoElement = false;
+      this.opacity = null;
+  }
+
+  NodeContainer.prototype.cloneTo = function(stack) {
+      stack.visible = this.visible;
+      stack.borders = this.borders;
+      stack.bounds = this.bounds;
+      stack.clip = this.clip;
+      stack.backgroundClip = this.backgroundClip;
+      stack.computedStyles = this.computedStyles;
+      stack.styles = this.styles;
+      stack.backgroundImages = this.backgroundImages;
+      stack.opacity = this.opacity;
+  };
+
+  NodeContainer.prototype.getOpacity = function() {
+      return this.opacity === null ? (this.opacity = this.cssFloat('opacity')) : this.opacity;
+  };
+
+  NodeContainer.prototype.assignStack = function(stack) {
+      this.stack = stack;
+      stack.children.push(this);
+  };
+
+  NodeContainer.prototype.isElementVisible = function() {
+      return this.node.nodeType === Node.TEXT_NODE ? this.parent.visible : (
+          this.css('display') !== "none" &&
+          this.css('visibility') !== "hidden" &&
+          !this.node.hasAttribute("data-html2canvas-ignore") &&
+          (this.node.nodeName !== "INPUT" || this.node.getAttribute("type") !== "hidden")
+      );
+  };
+
+  NodeContainer.prototype.css = function(attribute) {
+      if (!this.computedStyles) {
+          this.computedStyles = this.isPseudoElement ? this.parent.computedStyle(this.before ? ":before" : ":after") : this.computedStyle(null);
+      }
+
+      return this.styles[attribute] || (this.styles[attribute] = this.computedStyles[attribute]);
+  };
+
+  NodeContainer.prototype.prefixedCss = function(attribute) {
+      var prefixes = ["webkit", "moz", "ms", "o"];
+      var value = this.css(attribute);
+      if (value === undefined) {
+          prefixes.some(function(prefix) {
+              value = this.css(prefix + attribute.substr(0, 1).toUpperCase() + attribute.substr(1));
+              return value !== undefined;
+          }, this);
+      }
+      return value === undefined ? null : value;
+  };
+
+  NodeContainer.prototype.computedStyle = function(type) {
+      return this.node.ownerDocument.defaultView.getComputedStyle(this.node, type);
+  };
+
+  NodeContainer.prototype.cssInt = function(attribute) {
+      var value = parseInt(this.css(attribute), 10);
+      return (isNaN(value)) ? 0 : value; // borders in old IE are throwing 'medium' for demo.html
+  };
+
+  NodeContainer.prototype.color = function(attribute) {
+      return this.colors[attribute] || (this.colors[attribute] = new Color(this.css(attribute)));
+  };
+
+  NodeContainer.prototype.cssFloat = function(attribute) {
+      var value = parseFloat(this.css(attribute));
+      return (isNaN(value)) ? 0 : value;
+  };
+
+  NodeContainer.prototype.fontWeight = function() {
+      var weight = this.css("fontWeight");
+      switch(parseInt(weight, 10)){
+      case 401:
+          weight = "bold";
+          break;
+      case 400:
+          weight = "normal";
+          break;
+      }
+      return weight;
+  };
+
+  NodeContainer.prototype.parseClip = function() {
+      var matches = this.css('clip').match(this.CLIP);
+      if (matches) {
+          return {
+              top: parseInt(matches[1], 10),
+              right: parseInt(matches[2], 10),
+              bottom: parseInt(matches[3], 10),
+              left: parseInt(matches[4], 10)
+          };
+      }
+      return null;
+  };
+
+  NodeContainer.prototype.parseBackgroundImages = function() {
+      return this.backgroundImages || (this.backgroundImages = parseBackgrounds(this.css("backgroundImage")));
+  };
+
+  NodeContainer.prototype.cssList = function(property, index) {
+      var value = (this.css(property) || '').split(',');
+      value = value[index || 0] || value[0] || 'auto';
+      value = value.trim().split(' ');
+      if (value.length === 1) {
+          value = [value[0], isPercentage(value[0]) ? 'auto' : value[0]];
+      }
+      return value;
+  };
+
+  NodeContainer.prototype.parseBackgroundSize = function(bounds, image, index) {
+      var size = this.cssList("backgroundSize", index);
+      var width, height;
+
+      if (isPercentage(size[0])) {
+          width = bounds.width * parseFloat(size[0]) / 100;
+      } else if (/contain|cover/.test(size[0])) {
+          var targetRatio = bounds.width / bounds.height, currentRatio = image.width / image.height;
+          return (targetRatio < currentRatio ^ size[0] === 'contain') ?  {width: bounds.height * currentRatio, height: bounds.height} : {width: bounds.width, height: bounds.width / currentRatio};
+      } else {
+          width = parseInt(size[0], 10);
+      }
+
+      if (size[0] === 'auto' && size[1] === 'auto') {
+          height = image.height;
+      } else if (size[1] === 'auto') {
+          height = width / image.width * image.height;
+      } else if (isPercentage(size[1])) {
+          height =  bounds.height * parseFloat(size[1]) / 100;
+      } else {
+          height = parseInt(size[1], 10);
+      }
+
+      if (size[0] === 'auto') {
+          width = height / image.height * image.width;
+      }
+
+      return {width: width, height: height};
+  };
+
+  NodeContainer.prototype.parseBackgroundPosition = function(bounds, image, index, backgroundSize) {
+      var position = this.cssList('backgroundPosition', index);
+      var left, top;
+
+      if (isPercentage(position[0])){
+          left = (bounds.width - (backgroundSize || image).width) * (parseFloat(position[0]) / 100);
+      } else {
+          left = parseInt(position[0], 10);
+      }
+
+      if (position[1] === 'auto') {
+          top = left / image.width * image.height;
+      } else if (isPercentage(position[1])){
+          top =  (bounds.height - (backgroundSize || image).height) * parseFloat(position[1]) / 100;
+      } else {
+          top = parseInt(position[1], 10);
+      }
+
+      if (position[0] === 'auto') {
+          left = top / image.height * image.width;
+      }
+
+      return {left: left, top: top};
+  };
+
+  NodeContainer.prototype.parseBackgroundRepeat = function(index) {
+      return this.cssList("backgroundRepeat", index)[0];
+  };
+
+  NodeContainer.prototype.parseTextShadows = function() {
+      var textShadow = this.css("textShadow");
+      var results = [];
+
+      if (textShadow && textShadow !== 'none') {
+          var shadows = textShadow.match(this.TEXT_SHADOW_PROPERTY);
+          for (var i = 0; shadows && (i < shadows.length); i++) {
+              var s = shadows[i].match(this.TEXT_SHADOW_VALUES);
+              results.push({
+                  color: new Color(s[0]),
+                  offsetX: s[1] ? parseFloat(s[1].replace('px', '')) : 0,
+                  offsetY: s[2] ? parseFloat(s[2].replace('px', '')) : 0,
+                  blur: s[3] ? s[3].replace('px', '') : 0
+              });
+          }
+      }
+      return results;
+  };
+
+  NodeContainer.prototype.parseTransform = function() {
+      if (!this.transformData) {
+          if (this.hasTransform()) {
+              var offset = this.parseBounds();
+              var origin = this.prefixedCss("transformOrigin").split(" ").map(removePx).map(asFloat);
+              origin[0] += offset.left;
+              origin[1] += offset.top;
+              this.transformData = {
+                  origin: origin,
+                  matrix: this.parseTransformMatrix()
+              };
+          } else {
+              this.transformData = {
+                  origin: [0, 0],
+                  matrix: [1, 0, 0, 1, 0, 0]
+              };
+          }
+      }
+      return this.transformData;
+  };
+
+  NodeContainer.prototype.parseTransformMatrix = function() {
+      if (!this.transformMatrix) {
+          var transform = this.prefixedCss("transform");
+          var matrix = transform ? parseMatrix(transform.match(this.MATRIX_PROPERTY)) : null;
+          this.transformMatrix = matrix ? matrix : [1, 0, 0, 1, 0, 0];
+      }
+      return this.transformMatrix;
+  };
+
+  NodeContainer.prototype.parseBounds = function() {
+      return this.bounds || (this.bounds = this.hasTransform() ? offsetBounds(this.node) : getBounds(this.node));
+  };
+
+  NodeContainer.prototype.hasTransform = function() {
+      return this.parseTransformMatrix().join(",") !== "1,0,0,1,0,0" || (this.parent && this.parent.hasTransform());
+  };
+
+  NodeContainer.prototype.getValue = function() {
+      var value = this.node.value || "";
+      if (this.node.tagName === "SELECT") {
+          value = selectionValue(this.node);
+      } else if (this.node.type === "password") {
+          value = Array(value.length + 1).join('\u2022'); // jshint ignore:line
+      }
+      return value.length === 0 ? (this.node.placeholder || "") : value;
+  };
+
+  NodeContainer.prototype.MATRIX_PROPERTY = /(matrix|matrix3d)\((.+)\)/;
+  NodeContainer.prototype.TEXT_SHADOW_PROPERTY = /((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g;
+  NodeContainer.prototype.TEXT_SHADOW_VALUES = /(-?\d+px)|(#.+)|(rgb\(.+\))|(rgba\(.+\))/g;
+  NodeContainer.prototype.CLIP = /^rect\((\d+)px,? (\d+)px,? (\d+)px,? (\d+)px\)$/;
+
+  function selectionValue(node) {
+      var option = node.options[node.selectedIndex || 0];
+      return option ? (option.text || "") : "";
+  }
+
+  function parseMatrix(match) {
+      if (match && match[1] === "matrix") {
+          return match[2].split(",").map(function(s) {
+              return parseFloat(s.trim());
+          });
+      } else if (match && match[1] === "matrix3d") {
+          var matrix3d = match[2].split(",").map(function(s) {
+            return parseFloat(s.trim());
+          });
+          return [matrix3d[0], matrix3d[1], matrix3d[4], matrix3d[5], matrix3d[12], matrix3d[13]];
+      }
+  }
+
+  function isPercentage(value) {
+      return value.toString().indexOf("%") !== -1;
+  }
+
+  function removePx(str) {
+      return str.replace("px", "");
+  }
+
+  function asFloat(str) {
+      return parseFloat(str);
+  }
+
+  module.exports = NodeContainer;
+
+  },{"./color":3,"./utils":26}],15:[function(_dereq_,module,exports){
+  var log = _dereq_('./log');
+  var punycode = _dereq_('punycode');
+  var NodeContainer = _dereq_('./nodecontainer');
+  var TextContainer = _dereq_('./textcontainer');
+  var PseudoElementContainer = _dereq_('./pseudoelementcontainer');
+  var FontMetrics = _dereq_('./fontmetrics');
+  var Color = _dereq_('./color');
+  var StackingContext = _dereq_('./stackingcontext');
+  var utils = _dereq_('./utils');
+  var bind = utils.bind;
+  var getBounds = utils.getBounds;
+  var parseBackgrounds = utils.parseBackgrounds;
+  var offsetBounds = utils.offsetBounds;
+
+  function NodeParser(element, renderer, support, imageLoader, options) {
+      log("Starting NodeParser");
+      this.renderer = renderer;
+      this.options = options;
+      this.range = null;
+      this.support = support;
+      this.renderQueue = [];
+      this.stack = new StackingContext(true, 1, element.ownerDocument, null);
+      var parent = new NodeContainer(element, null);
+      if (options.background) {
+          renderer.rectangle(0, 0, renderer.width, renderer.height, new Color(options.background));
+      }
+      if (element === element.ownerDocument.documentElement) {
+          // http://www.w3.org/TR/css3-background/#special-backgrounds
+          var canvasBackground = new NodeContainer(parent.color('backgroundColor').isTransparent() ? element.ownerDocument.body : element.ownerDocument.documentElement, null);
+          renderer.rectangle(0, 0, renderer.width, renderer.height, canvasBackground.color('backgroundColor'));
+      }
+      parent.visibile = parent.isElementVisible();
+      this.createPseudoHideStyles(element.ownerDocument);
+      this.disableAnimations(element.ownerDocument);
+      this.nodes = flatten([parent].concat(this.getChildren(parent)).filter(function(container) {
+          return container.visible = container.isElementVisible();
+      }).map(this.getPseudoElements, this));
+      this.fontMetrics = new FontMetrics();
+      log("Fetched nodes, total:", this.nodes.length);
+      log("Calculate overflow clips");
+      this.calculateOverflowClips();
+      log("Start fetching images");
+      this.images = imageLoader.fetch(this.nodes.filter(isElement));
+      this.ready = this.images.ready.then(bind(function() {
+          log("Images loaded, starting parsing");
+          log("Creating stacking contexts");
+          this.createStackingContexts();
+          log("Sorting stacking contexts");
+          this.sortStackingContexts(this.stack);
+          this.parse(this.stack);
+          log("Render queue created with " + this.renderQueue.length + " items");
+          return new Promise(bind(function(resolve) {
+              if (!options.async) {
+                  this.renderQueue.forEach(this.paint, this);
+                  resolve();
+              } else if (typeof(options.async) === "function") {
+                  options.async.call(this, this.renderQueue, resolve);
+              } else if (this.renderQueue.length > 0){
+                  this.renderIndex = 0;
+                  this.asyncRenderer(this.renderQueue, resolve);
+              } else {
+                  resolve();
+              }
+          }, this));
+      }, this));
+  }
+
+  NodeParser.prototype.calculateOverflowClips = function() {
+      this.nodes.forEach(function(container) {
+          if (isElement(container)) {
+              if (isPseudoElement(container)) {
+                  container.appendToDOM();
+              }
+              container.borders = this.parseBorders(container);
+              var clip = (container.css('overflow') === "hidden") ? [container.borders.clip] : [];
+              var cssClip = container.parseClip();
+              if (cssClip && ["absolute", "fixed"].indexOf(container.css('position')) !== -1) {
+                  clip.push([["rect",
+                          container.bounds.left + cssClip.left,
+                          container.bounds.top + cssClip.top,
+                          cssClip.right - cssClip.left,
+                          cssClip.bottom - cssClip.top
+                  ]]);
+              }
+              container.clip = hasParentClip(container) ? container.parent.clip.concat(clip) : clip;
+              container.backgroundClip = (container.css('overflow') !== "hidden") ? container.clip.concat([container.borders.clip]) : container.clip;
+              if (isPseudoElement(container)) {
+                  container.cleanDOM();
+              }
+          } else if (isTextNode(container)) {
+              container.clip = hasParentClip(container) ? container.parent.clip : [];
+          }
+          if (!isPseudoElement(container)) {
+              container.bounds = null;
+          }
+      }, this);
+  };
+
+  function hasParentClip(container) {
+      return container.parent && container.parent.clip.length;
+  }
+
+  NodeParser.prototype.asyncRenderer = function(queue, resolve, asyncTimer) {
+      asyncTimer = asyncTimer || Date.now();
+      this.paint(queue[this.renderIndex++]);
+      if (queue.length === this.renderIndex) {
+          resolve();
+      } else if (asyncTimer + 20 > Date.now()) {
+          this.asyncRenderer(queue, resolve, asyncTimer);
+      } else {
+          setTimeout(bind(function() {
+              this.asyncRenderer(queue, resolve);
+          }, this), 0);
+      }
+  };
+
+  NodeParser.prototype.createPseudoHideStyles = function(document) {
+      this.createStyles(document, '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + ':before { content: "" !important; display: none !important; }' +
+          '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER + ':after { content: "" !important; display: none !important; }');
+  };
+
+  NodeParser.prototype.disableAnimations = function(document) {
+      this.createStyles(document, '* { -webkit-animation: none !important; -moz-animation: none !important; -o-animation: none !important; animation: none !important; ' +
+          '-webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; transition: none !important;}');
+  };
+
+  NodeParser.prototype.createStyles = function(document, styles) {
+      var hidePseudoElements = document.createElement('style');
+      hidePseudoElements.innerHTML = styles;
+      document.body.appendChild(hidePseudoElements);
+  };
+
+  NodeParser.prototype.getPseudoElements = function(container) {
+      var nodes = [[container]];
+      if (container.node.nodeType === Node.ELEMENT_NODE) {
+          var before = this.getPseudoElement(container, ":before");
+          var after = this.getPseudoElement(container, ":after");
+
+          if (before) {
+              nodes.push(before);
+          }
+
+          if (after) {
+              nodes.push(after);
+          }
+      }
+      return flatten(nodes);
+  };
+
+  function toCamelCase(str) {
+      return str.replace(/(\-[a-z])/g, function(match){
+          return match.toUpperCase().replace('-','');
+      });
+  }
+
+  NodeParser.prototype.getPseudoElement = function(container, type) {
+      var style = container.computedStyle(type);
+      if(!style || !style.content || style.content === "none" || style.content === "-moz-alt-content" || style.display === "none") {
+          return null;
+      }
+
+      var content = stripQuotes(style.content);
+      var isImage = content.substr(0, 3) === 'url';
+      var pseudoNode = document.createElement(isImage ? 'img' : 'html2canvaspseudoelement');
+      var pseudoContainer = new PseudoElementContainer(pseudoNode, container, type);
+
+      for (var i = style.length-1; i >= 0; i--) {
+          var property = toCamelCase(style.item(i));
+          pseudoNode.style[property] = style[property];
+      }
+
+      pseudoNode.className = PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + " " + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER;
+
+      if (isImage) {
+          pseudoNode.src = parseBackgrounds(content)[0].args[0];
+          return [pseudoContainer];
+      } else {
+          var text = document.createTextNode(content);
+          pseudoNode.appendChild(text);
+          return [pseudoContainer, new TextContainer(text, pseudoContainer)];
+      }
+  };
+
+
+  NodeParser.prototype.getChildren = function(parentContainer) {
+      return flatten([].filter.call(parentContainer.node.childNodes, renderableNode).map(function(node) {
+          var container = [node.nodeType === Node.TEXT_NODE ? new TextContainer(node, parentContainer) : new NodeContainer(node, parentContainer)].filter(nonIgnoredElement);
+          return node.nodeType === Node.ELEMENT_NODE && container.length && node.tagName !== "TEXTAREA" ? (container[0].isElementVisible() ? container.concat(this.getChildren(container[0])) : []) : container;
+      }, this));
+  };
+
+  NodeParser.prototype.newStackingContext = function(container, hasOwnStacking) {
+      var stack = new StackingContext(hasOwnStacking, container.getOpacity(), container.node, container.parent);
+      container.cloneTo(stack);
+      var parentStack = hasOwnStacking ? stack.getParentStack(this) : stack.parent.stack;
+      parentStack.contexts.push(stack);
+      container.stack = stack;
+  };
+
+  NodeParser.prototype.createStackingContexts = function() {
+      this.nodes.forEach(function(container) {
+          if (isElement(container) && (this.isRootElement(container) || hasOpacity(container) || isPositionedForStacking(container) || this.isBodyWithTransparentRoot(container) || container.hasTransform())) {
+              this.newStackingContext(container, true);
+          } else if (isElement(container) && ((isPositioned(container) && zIndex0(container)) || isInlineBlock(container) || isFloating(container))) {
+              this.newStackingContext(container, false);
+          } else {
+              container.assignStack(container.parent.stack);
+          }
+      }, this);
+  };
+
+  NodeParser.prototype.isBodyWithTransparentRoot = function(container) {
+      return container.node.nodeName === "BODY" && container.parent.color('backgroundColor').isTransparent();
+  };
+
+  NodeParser.prototype.isRootElement = function(container) {
+      return container.parent === null;
+  };
+
+  NodeParser.prototype.sortStackingContexts = function(stack) {
+      stack.contexts.sort(zIndexSort(stack.contexts.slice(0)));
+      stack.contexts.forEach(this.sortStackingContexts, this);
+  };
+
+  NodeParser.prototype.parseTextBounds = function(container) {
+      return function(text, index, textList) {
+          if (container.parent.css("textDecoration").substr(0, 4) !== "none" || text.trim().length !== 0) {
+              if (this.support.rangeBounds && !container.parent.hasTransform()) {
+                  var offset = textList.slice(0, index).join("").length;
+                  return this.getRangeBounds(container.node, offset, text.length);
+              } else if (container.node && typeof(container.node.data) === "string") {
+                  var replacementNode = container.node.splitText(text.length);
+                  var bounds = this.getWrapperBounds(container.node, container.parent.hasTransform());
+                  container.node = replacementNode;
+                  return bounds;
+              }
+          } else if(!this.support.rangeBounds || container.parent.hasTransform()){
+              container.node = container.node.splitText(text.length);
+          }
+          return {};
+      };
+  };
+
+  NodeParser.prototype.getWrapperBounds = function(node, transform) {
+      var wrapper = node.ownerDocument.createElement('html2canvaswrapper');
+      var parent = node.parentNode,
+          backupText = node.cloneNode(true);
+
+      wrapper.appendChild(node.cloneNode(true));
+      parent.replaceChild(wrapper, node);
+      var bounds = transform ? offsetBounds(wrapper) : getBounds(wrapper);
+      parent.replaceChild(backupText, wrapper);
+      return bounds;
+  };
+
+  NodeParser.prototype.getRangeBounds = function(node, offset, length) {
+      var range = this.range || (this.range = node.ownerDocument.createRange());
+      range.setStart(node, offset);
+      range.setEnd(node, offset + length);
+      return range.getBoundingClientRect();
+  };
+
+  function ClearTransform() {}
+
+  NodeParser.prototype.parse = function(stack) {
+      // http://www.w3.org/TR/CSS21/visuren.html#z-index
+      var negativeZindex = stack.contexts.filter(negativeZIndex); // 2. the child stacking contexts with negative stack levels (most negative first).
+      var descendantElements = stack.children.filter(isElement);
+      var descendantNonFloats = descendantElements.filter(not(isFloating));
+      var nonInlineNonPositionedDescendants = descendantNonFloats.filter(not(isPositioned)).filter(not(inlineLevel)); // 3 the in-flow, non-inline-level, non-positioned descendants.
+      var nonPositionedFloats = descendantElements.filter(not(isPositioned)).filter(isFloating); // 4. the non-positioned floats.
+      var inFlow = descendantNonFloats.filter(not(isPositioned)).filter(inlineLevel); // 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
+      var stackLevel0 = stack.contexts.concat(descendantNonFloats.filter(isPositioned)).filter(zIndex0); // 6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
+      var text = stack.children.filter(isTextNode).filter(hasText);
+      var positiveZindex = stack.contexts.filter(positiveZIndex); // 7. the child stacking contexts with positive stack levels (least positive first).
+      negativeZindex.concat(nonInlineNonPositionedDescendants).concat(nonPositionedFloats)
+          .concat(inFlow).concat(stackLevel0).concat(text).concat(positiveZindex).forEach(function(container) {
+              this.renderQueue.push(container);
+              if (isStackingContext(container)) {
+                  this.parse(container);
+                  this.renderQueue.push(new ClearTransform());
+              }
+          }, this);
+  };
+
+  NodeParser.prototype.paint = function(container) {
+      try {
+          if (container instanceof ClearTransform) {
+              this.renderer.ctx.restore();
+          } else if (isTextNode(container)) {
+              if (isPseudoElement(container.parent)) {
+                  container.parent.appendToDOM();
+              }
+              this.paintText(container);
+              if (isPseudoElement(container.parent)) {
+                  container.parent.cleanDOM();
+              }
+          } else {
+              this.paintNode(container);
+          }
+      } catch(e) {
+          log(e);
+          if (this.options.strict) {
+              throw e;
+          }
+      }
+  };
+
+  NodeParser.prototype.paintNode = function(container) {
+      if (isStackingContext(container)) {
+          this.renderer.setOpacity(container.opacity);
+          this.renderer.ctx.save();
+          if (container.hasTransform()) {
+              this.renderer.setTransform(container.parseTransform());
+          }
+      }
+
+      if (container.node.nodeName === "INPUT" && container.node.type === "checkbox") {
+          this.paintCheckbox(container);
+      } else if (container.node.nodeName === "INPUT" && container.node.type === "radio") {
+          this.paintRadio(container);
+      } else {
+          this.paintElement(container);
+      }
+  };
+
+  NodeParser.prototype.paintElement = function(container) {
+      var bounds = container.parseBounds();
+      this.renderer.clip(container.backgroundClip, function() {
+          this.renderer.renderBackground(container, bounds, container.borders.borders.map(getWidth));
+      }, this);
+
+      this.renderer.clip(container.clip, function() {
+          this.renderer.renderBorders(container.borders.borders);
+      }, this);
+
+      this.renderer.clip(container.backgroundClip, function() {
+          switch (container.node.nodeName) {
+          case "svg":
+          case "IFRAME":
+              var imgContainer = this.images.get(container.node);
+              if (imgContainer) {
+                  this.renderer.renderImage(container, bounds, container.borders, imgContainer);
+              } else {
+                  log("Error loading <" + container.node.nodeName + ">", container.node);
+              }
+              break;
+          case "IMG":
+              var imageContainer = this.images.get(container.node.src);
+              if (imageContainer) {
+                  this.renderer.renderImage(container, bounds, container.borders, imageContainer);
+              } else {
+                  log("Error loading <img>", container.node.src);
+              }
+              break;
+          case "CANVAS":
+              this.renderer.renderImage(container, bounds, container.borders, {image: container.node});
+              break;
+          case "SELECT":
+          case "INPUT":
+          case "TEXTAREA":
+              this.paintFormValue(container);
+              break;
+          }
+      }, this);
+  };
+
+  NodeParser.prototype.paintCheckbox = function(container) {
+      var b = container.parseBounds();
+
+      var size = Math.min(b.width, b.height);
+      var bounds = {width: size - 1, height: size - 1, top: b.top, left: b.left};
+      var r = [3, 3];
+      var radius = [r, r, r, r];
+      var borders = [1,1,1,1].map(function(w) {
+          return {color: new Color('#A5A5A5'), width: w};
+      });
+
+      var borderPoints = calculateCurvePoints(bounds, radius, borders);
+
+      this.renderer.clip(container.backgroundClip, function() {
+          this.renderer.rectangle(bounds.left + 1, bounds.top + 1, bounds.width - 2, bounds.height - 2, new Color("#DEDEDE"));
+          this.renderer.renderBorders(calculateBorders(borders, bounds, borderPoints, radius));
+          if (container.node.checked) {
+              this.renderer.font(new Color('#424242'), 'normal', 'normal', 'bold', (size - 3) + "px", 'arial');
+              this.renderer.text("\u2714", bounds.left + size / 6, bounds.top + size - 1);
+          }
+      }, this);
+  };
+
+  NodeParser.prototype.paintRadio = function(container) {
+      var bounds = container.parseBounds();
+
+      var size = Math.min(bounds.width, bounds.height) - 2;
+
+      this.renderer.clip(container.backgroundClip, function() {
+          this.renderer.circleStroke(bounds.left + 1, bounds.top + 1, size, new Color('#DEDEDE'), 1, new Color('#A5A5A5'));
+          if (container.node.checked) {
+              this.renderer.circle(Math.ceil(bounds.left + size / 4) + 1, Math.ceil(bounds.top + size / 4) + 1, Math.floor(size / 2), new Color('#424242'));
+          }
+      }, this);
+  };
+
+  NodeParser.prototype.paintFormValue = function(container) {
+      var value = container.getValue();
+      if (value.length > 0) {
+          var document = container.node.ownerDocument;
+          var wrapper = document.createElement('html2canvaswrapper');
+          var properties = ['lineHeight', 'textAlign', 'fontFamily', 'fontWeight', 'fontSize', 'color',
+              'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom',
+              'width', 'height', 'borderLeftStyle', 'borderTopStyle', 'borderLeftWidth', 'borderTopWidth',
+              'boxSizing', 'whiteSpace', 'wordWrap'];
+
+          properties.forEach(function(property) {
+              try {
+                  wrapper.style[property] = container.css(property);
+              } catch(e) {
+                  // Older IE has issues with "border"
+                  log("html2canvas: Parse: Exception caught in renderFormValue: " + e.message);
+              }
+          });
+          var bounds = container.parseBounds();
+          wrapper.style.position = "fixed";
+          wrapper.style.left = bounds.left + "px";
+          wrapper.style.top = bounds.top + "px";
+          wrapper.textContent = value;
+          document.body.appendChild(wrapper);
+          this.paintText(new TextContainer(wrapper.firstChild, container));
+          document.body.removeChild(wrapper);
+      }
+  };
+
+  NodeParser.prototype.paintText = function(container) {
+      container.applyTextTransform();
+      var characters = punycode.ucs2.decode(container.node.data);
+      var textList = (!this.options.letterRendering || noLetterSpacing(container)) && !hasUnicode(container.node.data) ? getWords(characters) : characters.map(function(character) {
+          return punycode.ucs2.encode([character]);
+      });
+
+      var weight = container.parent.fontWeight();
+      var size = container.parent.css('fontSize');
+      var family = container.parent.css('fontFamily');
+      var shadows = container.parent.parseTextShadows();
+
+      this.renderer.font(container.parent.color('color'), container.parent.css('fontStyle'), container.parent.css('fontVariant'), weight, size, family);
+      if (shadows.length) {
+          // TODO: support multiple text shadows
+          this.renderer.fontShadow(shadows[0].color, shadows[0].offsetX, shadows[0].offsetY, shadows[0].blur);
+      } else {
+          this.renderer.clearShadow();
+      }
+
+      this.renderer.clip(container.parent.clip, function() {
+          textList.map(this.parseTextBounds(container), this).forEach(function(bounds, index) {
+              if (bounds) {
+                  this.renderer.text(textList[index], bounds.left, bounds.bottom);
+                  this.renderTextDecoration(container.parent, bounds, this.fontMetrics.getMetrics(family, size));
+              }
+          }, this);
+      }, this);
+  };
+
+  NodeParser.prototype.renderTextDecoration = function(container, bounds, metrics) {
+      switch(container.css("textDecoration").split(" ")[0]) {
+      case "underline":
+          // Draws a line at the baseline of the font
+          // TODO As some browsers display the line as more than 1px if the font-size is big, need to take that into account both in position and size
+          this.renderer.rectangle(bounds.left, Math.round(bounds.top + metrics.baseline + metrics.lineWidth), bounds.width, 1, container.color("color"));
+          break;
+      case "overline":
+          this.renderer.rectangle(bounds.left, Math.round(bounds.top), bounds.width, 1, container.color("color"));
+          break;
+      case "line-through":
+          // TODO try and find exact position for line-through
+          this.renderer.rectangle(bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, container.color("color"));
+          break;
+      }
+  };
+
+  var borderColorTransforms = {
+      inset: [
+          ["darken", 0.60],
+          ["darken", 0.10],
+          ["darken", 0.10],
+          ["darken", 0.60]
+      ]
+  };
+
+  NodeParser.prototype.parseBorders = function(container) {
+      var nodeBounds = container.parseBounds();
+      var radius = getBorderRadiusData(container);
+      var borders = ["Top", "Right", "Bottom", "Left"].map(function(side, index) {
+          var style = container.css('border' + side + 'Style');
+          var color = container.color('border' + side + 'Color');
+          if (style === "inset" && color.isBlack()) {
+              color = new Color([255, 255, 255, color.a]); // this is wrong, but
+          }
+          var colorTransform = borderColorTransforms[style] ? borderColorTransforms[style][index] : null;
+          return {
+              width: container.cssInt('border' + side + 'Width'),
+              color: colorTransform ? color[colorTransform[0]](colorTransform[1]) : color,
+              args: null
+          };
+      });
+      var borderPoints = calculateCurvePoints(nodeBounds, radius, borders);
+
+      return {
+          clip: this.parseBackgroundClip(container, borderPoints, borders, radius, nodeBounds),
+          borders: calculateBorders(borders, nodeBounds, borderPoints, radius)
+      };
+  };
+
+  function calculateBorders(borders, nodeBounds, borderPoints, radius) {
+      return borders.map(function(border, borderSide) {
+          if (border.width > 0) {
+              var bx = nodeBounds.left;
+              var by = nodeBounds.top;
+              var bw = nodeBounds.width;
+              var bh = nodeBounds.height - (borders[2].width);
+
+              switch(borderSide) {
+              case 0:
+                  // top border
+                  bh = borders[0].width;
+                  border.args = drawSide({
+                          c1: [bx, by],
+                          c2: [bx + bw, by],
+                          c3: [bx + bw - borders[1].width, by + bh],
+                          c4: [bx + borders[3].width, by + bh]
+                      }, radius[0], radius[1],
+                      borderPoints.topLeftOuter, borderPoints.topLeftInner, borderPoints.topRightOuter, borderPoints.topRightInner);
+                  break;
+              case 1:
+                  // right border
+                  bx = nodeBounds.left + nodeBounds.width - (borders[1].width);
+                  bw = borders[1].width;
+
+                  border.args = drawSide({
+                          c1: [bx + bw, by],
+                          c2: [bx + bw, by + bh + borders[2].width],
+                          c3: [bx, by + bh],
+                          c4: [bx, by + borders[0].width]
+                      }, radius[1], radius[2],
+                      borderPoints.topRightOuter, borderPoints.topRightInner, borderPoints.bottomRightOuter, borderPoints.bottomRightInner);
+                  break;
+              case 2:
+                  // bottom border
+                  by = (by + nodeBounds.height) - (borders[2].width);
+                  bh = borders[2].width;
+                  border.args = drawSide({
+                          c1: [bx + bw, by + bh],
+                          c2: [bx, by + bh],
+                          c3: [bx + borders[3].width, by],
+                          c4: [bx + bw - borders[3].width, by]
+                      }, radius[2], radius[3],
+                      borderPoints.bottomRightOuter, borderPoints.bottomRightInner, borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner);
+                  break;
+              case 3:
+                  // left border
+                  bw = borders[3].width;
+                  border.args = drawSide({
+                          c1: [bx, by + bh + borders[2].width],
+                          c2: [bx, by],
+                          c3: [bx + bw, by + borders[0].width],
+                          c4: [bx + bw, by + bh]
+                      }, radius[3], radius[0],
+                      borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner, borderPoints.topLeftOuter, borderPoints.topLeftInner);
+                  break;
+              }
+          }
+          return border;
+      });
+  }
+
+  NodeParser.prototype.parseBackgroundClip = function(container, borderPoints, borders, radius, bounds) {
+      var backgroundClip = container.css('backgroundClip'),
+          borderArgs = [];
+
+      switch(backgroundClip) {
+      case "content-box":
+      case "padding-box":
+          parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftInner, borderPoints.topRightInner, bounds.left + borders[3].width, bounds.top + borders[0].width);
+          parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightInner, borderPoints.bottomRightInner, bounds.left + bounds.width - borders[1].width, bounds.top + borders[0].width);
+          parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightInner, borderPoints.bottomLeftInner, bounds.left + bounds.width - borders[1].width, bounds.top + bounds.height - borders[2].width);
+          parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftInner, borderPoints.topLeftInner, bounds.left + borders[3].width, bounds.top + bounds.height - borders[2].width);
+          break;
+
+      default:
+          parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftOuter, borderPoints.topRightOuter, bounds.left, bounds.top);
+          parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightOuter, borderPoints.bottomRightOuter, bounds.left + bounds.width, bounds.top);
+          parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightOuter, borderPoints.bottomLeftOuter, bounds.left + bounds.width, bounds.top + bounds.height);
+          parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftOuter, borderPoints.topLeftOuter, bounds.left, bounds.top + bounds.height);
+          break;
+      }
+
+      return borderArgs;
+  };
+
+  function getCurvePoints(x, y, r1, r2) {
+      var kappa = 4 * ((Math.sqrt(2) - 1) / 3);
+      var ox = (r1) * kappa, // control point offset horizontal
+          oy = (r2) * kappa, // control point offset vertical
+          xm = x + r1, // x-middle
+          ym = y + r2; // y-middle
+      return {
+          topLeft: bezierCurve({x: x, y: ym}, {x: x, y: ym - oy}, {x: xm - ox, y: y}, {x: xm, y: y}),
+          topRight: bezierCurve({x: x, y: y}, {x: x + ox,y: y}, {x: xm, y: ym - oy}, {x: xm, y: ym}),
+          bottomRight: bezierCurve({x: xm, y: y}, {x: xm, y: y + oy}, {x: x + ox, y: ym}, {x: x, y: ym}),
+          bottomLeft: bezierCurve({x: xm, y: ym}, {x: xm - ox, y: ym}, {x: x, y: y + oy}, {x: x, y:y})
+      };
+  }
+
+  function calculateCurvePoints(bounds, borderRadius, borders) {
+      var x = bounds.left,
+          y = bounds.top,
+          width = bounds.width,
+          height = bounds.height,
+
+          tlh = borderRadius[0][0] < width / 2 ? borderRadius[0][0] : width / 2,
+          tlv = borderRadius[0][1] < height / 2 ? borderRadius[0][1] : height / 2,
+          trh = borderRadius[1][0] < width / 2 ? borderRadius[1][0] : width / 2,
+          trv = borderRadius[1][1] < height / 2 ? borderRadius[1][1] : height / 2,
+          brh = borderRadius[2][0] < width / 2 ? borderRadius[2][0] : width / 2,
+          brv = borderRadius[2][1] < height / 2 ? borderRadius[2][1] : height / 2,
+          blh = borderRadius[3][0] < width / 2 ? borderRadius[3][0] : width / 2,
+          blv = borderRadius[3][1] < height / 2 ? borderRadius[3][1] : height / 2;
+
+      var topWidth = width - trh,
+          rightHeight = height - brv,
+          bottomWidth = width - brh,
+          leftHeight = height - blv;
+
+      return {
+          topLeftOuter: getCurvePoints(x, y, tlh, tlv).topLeft.subdivide(0.5),
+          topLeftInner: getCurvePoints(x + borders[3].width, y + borders[0].width, Math.max(0, tlh - borders[3].width), Math.max(0, tlv - borders[0].width)).topLeft.subdivide(0.5),
+          topRightOuter: getCurvePoints(x + topWidth, y, trh, trv).topRight.subdivide(0.5),
+          topRightInner: getCurvePoints(x + Math.min(topWidth, width + borders[3].width), y + borders[0].width, (topWidth > width + borders[3].width) ? 0 :trh - borders[3].width, trv - borders[0].width).topRight.subdivide(0.5),
+          bottomRightOuter: getCurvePoints(x + bottomWidth, y + rightHeight, brh, brv).bottomRight.subdivide(0.5),
+          bottomRightInner: getCurvePoints(x + Math.min(bottomWidth, width - borders[3].width), y + Math.min(rightHeight, height + borders[0].width), Math.max(0, brh - borders[1].width),  brv - borders[2].width).bottomRight.subdivide(0.5),
+          bottomLeftOuter: getCurvePoints(x, y + leftHeight, blh, blv).bottomLeft.subdivide(0.5),
+          bottomLeftInner: getCurvePoints(x + borders[3].width, y + leftHeight, Math.max(0, blh - borders[3].width), blv - borders[2].width).bottomLeft.subdivide(0.5)
+      };
+  }
+
+  function bezierCurve(start, startControl, endControl, end) {
+      var lerp = function (a, b, t) {
+          return {
+              x: a.x + (b.x - a.x) * t,
+              y: a.y + (b.y - a.y) * t
+          };
+      };
+
+      return {
+          start: start,
+          startControl: startControl,
+          endControl: endControl,
+          end: end,
+          subdivide: function(t) {
+              var ab = lerp(start, startControl, t),
+                  bc = lerp(startControl, endControl, t),
+                  cd = lerp(endControl, end, t),
+                  abbc = lerp(ab, bc, t),
+                  bccd = lerp(bc, cd, t),
+                  dest = lerp(abbc, bccd, t);
+              return [bezierCurve(start, ab, abbc, dest), bezierCurve(dest, bccd, cd, end)];
+          },
+          curveTo: function(borderArgs) {
+              borderArgs.push(["bezierCurve", startControl.x, startControl.y, endControl.x, endControl.y, end.x, end.y]);
+          },
+          curveToReversed: function(borderArgs) {
+              borderArgs.push(["bezierCurve", endControl.x, endControl.y, startControl.x, startControl.y, start.x, start.y]);
+          }
+      };
+  }
+
+  function drawSide(borderData, radius1, radius2, outer1, inner1, outer2, inner2) {
+      var borderArgs = [];
+
+      if (radius1[0] > 0 || radius1[1] > 0) {
+          borderArgs.push(["line", outer1[1].start.x, outer1[1].start.y]);
+          outer1[1].curveTo(borderArgs);
+      } else {
+          borderArgs.push([ "line", borderData.c1[0], borderData.c1[1]]);
+      }
+
+      if (radius2[0] > 0 || radius2[1] > 0) {
+          borderArgs.push(["line", outer2[0].start.x, outer2[0].start.y]);
+          outer2[0].curveTo(borderArgs);
+          borderArgs.push(["line", inner2[0].end.x, inner2[0].end.y]);
+          inner2[0].curveToReversed(borderArgs);
+      } else {
+          borderArgs.push(["line", borderData.c2[0], borderData.c2[1]]);
+          borderArgs.push(["line", borderData.c3[0], borderData.c3[1]]);
+      }
+
+      if (radius1[0] > 0 || radius1[1] > 0) {
+          borderArgs.push(["line", inner1[1].end.x, inner1[1].end.y]);
+          inner1[1].curveToReversed(borderArgs);
+      } else {
+          borderArgs.push(["line", borderData.c4[0], borderData.c4[1]]);
+      }
+
+      return borderArgs;
+  }
+
+  function parseCorner(borderArgs, radius1, radius2, corner1, corner2, x, y) {
+      if (radius1[0] > 0 || radius1[1] > 0) {
+          borderArgs.push(["line", corner1[0].start.x, corner1[0].start.y]);
+          corner1[0].curveTo(borderArgs);
+          corner1[1].curveTo(borderArgs);
+      } else {
+          borderArgs.push(["line", x, y]);
+      }
+
+      if (radius2[0] > 0 || radius2[1] > 0) {
+          borderArgs.push(["line", corner2[0].start.x, corner2[0].start.y]);
+      }
+  }
+
+  function negativeZIndex(container) {
+      return container.cssInt("zIndex") < 0;
+  }
+
+  function positiveZIndex(container) {
+      return container.cssInt("zIndex") > 0;
+  }
+
+  function zIndex0(container) {
+      return container.cssInt("zIndex") === 0;
+  }
+
+  function inlineLevel(container) {
+      return ["inline", "inline-block", "inline-table"].indexOf(container.css("display")) !== -1;
+  }
+
+  function isStackingContext(container) {
+      return (container instanceof StackingContext);
+  }
+
+  function hasText(container) {
+      return container.node.data.trim().length > 0;
+  }
+
+  function noLetterSpacing(container) {
+      return (/^(normal|none|0px)$/.test(container.parent.css("letterSpacing")));
+  }
+
+  function getBorderRadiusData(container) {
+      return ["TopLeft", "TopRight", "BottomRight", "BottomLeft"].map(function(side) {
+          var value = container.css('border' + side + 'Radius');
+          var arr = value.split(" ");
+          if (arr.length <= 1) {
+              arr[1] = arr[0];
+          }
+          return arr.map(asInt);
+      });
+  }
+
+  function renderableNode(node) {
+      return (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.ELEMENT_NODE);
+  }
+
+  function isPositionedForStacking(container) {
+      var position = container.css("position");
+      var zIndex = (["absolute", "relative", "fixed"].indexOf(position) !== -1) ? container.css("zIndex") : "auto";
+      return zIndex !== "auto";
+  }
+
+  function isPositioned(container) {
+      return container.css("position") !== "static";
+  }
+
+  function isFloating(container) {
+      return container.css("float") !== "none";
+  }
+
+  function isInlineBlock(container) {
+      return ["inline-block", "inline-table"].indexOf(container.css("display")) !== -1;
+  }
+
+  function not(callback) {
+      var context = this;
+      return function() {
+          return !callback.apply(context, arguments);
+      };
+  }
+
+  function isElement(container) {
+      return container.node.nodeType === Node.ELEMENT_NODE;
+  }
+
+  function isPseudoElement(container) {
+      return container.isPseudoElement === true;
+  }
+
+  function isTextNode(container) {
+      return container.node.nodeType === Node.TEXT_NODE;
+  }
+
+  function zIndexSort(contexts) {
+      return function(a, b) {
+          return (a.cssInt("zIndex") + (contexts.indexOf(a) / contexts.length)) - (b.cssInt("zIndex") + (contexts.indexOf(b) / contexts.length));
+      };
+  }
+
+  function hasOpacity(container) {
+      return container.getOpacity() < 1;
+  }
+
+  function asInt(value) {
+      return parseInt(value, 10);
+  }
+
+  function getWidth(border) {
+      return border.width;
+  }
+
+  function nonIgnoredElement(nodeContainer) {
+      return (nodeContainer.node.nodeType !== Node.ELEMENT_NODE || ["SCRIPT", "HEAD", "TITLE", "OBJECT", "BR", "OPTION"].indexOf(nodeContainer.node.nodeName) === -1);
+  }
+
+  function flatten(arrays) {
+      return [].concat.apply([], arrays);
+  }
+
+  function stripQuotes(content) {
+      var first = content.substr(0, 1);
+      return (first === content.substr(content.length - 1) && first.match(/'|"/)) ? content.substr(1, content.length - 2) : content;
+  }
+
+  function getWords(characters) {
+      var words = [], i = 0, onWordBoundary = false, word;
+      while(characters.length) {
+          if (isWordBoundary(characters[i]) === onWordBoundary) {
+              word = characters.splice(0, i);
+              if (word.length) {
+                  words.push(punycode.ucs2.encode(word));
+              }
+              onWordBoundary =! onWordBoundary;
+              i = 0;
+          } else {
+              i++;
+          }
+
+          if (i >= characters.length) {
+              word = characters.splice(0, i);
+              if (word.length) {
+                  words.push(punycode.ucs2.encode(word));
+              }
+          }
+      }
+      return words;
+  }
+
+  function isWordBoundary(characterCode) {
+      return [
+          32, // <space>
+          13, // \r
+          10, // \n
+          9, // \t
+          45 // -
+      ].indexOf(characterCode) !== -1;
+  }
+
+  function hasUnicode(string) {
+      return (/[^\u0000-\u00ff]/).test(string);
+  }
+
+  module.exports = NodeParser;
+
+  },{"./color":3,"./fontmetrics":7,"./log":13,"./nodecontainer":14,"./pseudoelementcontainer":18,"./stackingcontext":21,"./textcontainer":25,"./utils":26,"punycode":1}],16:[function(_dereq_,module,exports){
+  var XHR = _dereq_('./xhr');
+  var utils = _dereq_('./utils');
+  var log = _dereq_('./log');
+  var createWindowClone = _dereq_('./clone');
+  var decode64 = utils.decode64;
+
+  function Proxy(src, proxyUrl, document) {
+      var supportsCORS = ('withCredentials' in new XMLHttpRequest());
+      if (!proxyUrl) {
+          return Promise.reject("No proxy configured");
+      }
+      var callback = createCallback(supportsCORS);
+      var url = createProxyUrl(proxyUrl, src, callback);
+
+      return supportsCORS ? XHR(url) : (jsonp(document, url, callback).then(function(response) {
+          return decode64(response.content);
+      }));
+  }
+  var proxyCount = 0;
+
+  function ProxyURL(src, proxyUrl, document) {
+      var supportsCORSImage = ('crossOrigin' in new Image());
+      var callback = createCallback(supportsCORSImage);
+      var url = createProxyUrl(proxyUrl, src, callback);
+      return (supportsCORSImage ? Promise.resolve(url) : jsonp(document, url, callback).then(function(response) {
+          return "data:" + response.type + ";base64," + response.content;
+      }));
+  }
+
+  function jsonp(document, url, callback) {
+      return new Promise(function(resolve, reject) {
+          var s = document.createElement("script");
+          var cleanup = function() {
+              delete window.html2canvas.proxy[callback];
+              document.body.removeChild(s);
+          };
+          window.html2canvas.proxy[callback] = function(response) {
+              cleanup();
+              resolve(response);
+          };
+          s.src = url;
+          s.onerror = function(e) {
+              cleanup();
+              reject(e);
+          };
+          document.body.appendChild(s);
+      });
+  }
+
+  function createCallback(useCORS) {
+      return !useCORS ? "html2canvas_" + Date.now() + "_" + (++proxyCount) + "_" + Math.round(Math.random() * 100000) : "";
+  }
+
+  function createProxyUrl(proxyUrl, src, callback) {
+      return proxyUrl + "?url=" + encodeURIComponent(src) + (callback.length ? "&callback=html2canvas.proxy." + callback : "");
+  }
+
+  function documentFromHTML(src) {
+      return function(html) {
+          var parser = new DOMParser(), doc;
+          try {
+              doc = parser.parseFromString(html, "text/html");
+          } catch(e) {
+              log("DOMParser not supported, falling back to createHTMLDocument");
+              doc = document.implementation.createHTMLDocument("");
+              try {
+                  doc.open();
+                  doc.write(html);
+                  doc.close();
+              } catch(ee) {
+                  log("createHTMLDocument write not supported, falling back to document.body.innerHTML");
+                  doc.body.innerHTML = html; // ie9 doesnt support writing to documentElement
+              }
+          }
+
+          var b = doc.querySelector("base");
+          if (!b || !b.href.host) {
+              var base = doc.createElement("base");
+              base.href = src;
+              doc.head.insertBefore(base, doc.head.firstChild);
+          }
+
+          return doc;
+      };
+  }
+
+  function loadUrlDocument(src, proxy, document, width, height, options) {
+      return new Proxy(src, proxy, window.document).then(documentFromHTML(src)).then(function(doc) {
+          return createWindowClone(doc, document, width, height, options, 0, 0);
+      });
+  }
+
+  exports.Proxy = Proxy;
+  exports.ProxyURL = ProxyURL;
+  exports.loadUrlDocument = loadUrlDocument;
+
+  },{"./clone":2,"./log":13,"./utils":26,"./xhr":28}],17:[function(_dereq_,module,exports){
+  var ProxyURL = _dereq_('./proxy').ProxyURL;
+
+  function ProxyImageContainer(src, proxy) {
+      var link = document.createElement("a");
+      link.href = src;
+      src = link.href;
+      this.src = src;
+      this.image = new Image();
+      var self = this;
+      this.promise = new Promise(function(resolve, reject) {
+          self.image.crossOrigin = "Anonymous";
+          self.image.onload = resolve;
+          self.image.onerror = reject;
+
+          new ProxyURL(src, proxy, document).then(function(url) {
+              self.image.src = url;
+          })['catch'](reject);
+      });
+  }
+
+  module.exports = ProxyImageContainer;
+
+  },{"./proxy":16}],18:[function(_dereq_,module,exports){
+  var NodeContainer = _dereq_('./nodecontainer');
+
+  function PseudoElementContainer(node, parent, type) {
+      NodeContainer.call(this, node, parent);
+      this.isPseudoElement = true;
+      this.before = type === ":before";
+  }
+
+  PseudoElementContainer.prototype.cloneTo = function(stack) {
+      PseudoElementContainer.prototype.cloneTo.call(this, stack);
+      stack.isPseudoElement = true;
+      stack.before = this.before;
+  };
+
+  PseudoElementContainer.prototype = Object.create(NodeContainer.prototype);
+
+  PseudoElementContainer.prototype.appendToDOM = function() {
+      if (this.before) {
+          this.parent.node.insertBefore(this.node, this.parent.node.firstChild);
+      } else {
+          this.parent.node.appendChild(this.node);
+      }
+      this.parent.node.className += " " + this.getHideClass();
+  };
+
+  PseudoElementContainer.prototype.cleanDOM = function() {
+      this.node.parentNode.removeChild(this.node);
+      this.parent.node.className = this.parent.node.className.replace(this.getHideClass(), "");
+  };
+
+  PseudoElementContainer.prototype.getHideClass = function() {
+      return this["PSEUDO_HIDE_ELEMENT_CLASS_" + (this.before ? "BEFORE" : "AFTER")];
+  };
+
+  PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE = "___html2canvas___pseudoelement_before";
+  PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER = "___html2canvas___pseudoelement_after";
+
+  module.exports = PseudoElementContainer;
+
+  },{"./nodecontainer":14}],19:[function(_dereq_,module,exports){
+  var log = _dereq_('./log');
+
+  function Renderer(width, height, images, options, document) {
+      this.width = width;
+      this.height = height;
+      this.images = images;
+      this.options = options;
+      this.document = document;
+  }
+
+  Renderer.prototype.renderImage = function(container, bounds, borderData, imageContainer) {
+      var paddingLeft = container.cssInt('paddingLeft'),
+          paddingTop = container.cssInt('paddingTop'),
+          paddingRight = container.cssInt('paddingRight'),
+          paddingBottom = container.cssInt('paddingBottom'),
+          borders = borderData.borders;
+
+      var width = bounds.width - (borders[1].width + borders[3].width + paddingLeft + paddingRight);
+      var height = bounds.height - (borders[0].width + borders[2].width + paddingTop + paddingBottom);
+      this.drawImage(
+          imageContainer,
+          0,
+          0,
+          imageContainer.image.width || width,
+          imageContainer.image.height || height,
+          bounds.left + paddingLeft + borders[3].width,
+          bounds.top + paddingTop + borders[0].width,
+          width,
+          height
+      );
+  };
+
+  Renderer.prototype.renderBackground = function(container, bounds, borderData) {
+      if (bounds.height > 0 && bounds.width > 0) {
+          this.renderBackgroundColor(container, bounds);
+          this.renderBackgroundImage(container, bounds, borderData);
+      }
+  };
+
+  Renderer.prototype.renderBackgroundColor = function(container, bounds) {
+      var color = container.color("backgroundColor");
+      if (!color.isTransparent()) {
+          this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, color);
+      }
+  };
+
+  Renderer.prototype.renderBorders = function(borders) {
+      borders.forEach(this.renderBorder, this);
+  };
+
+  Renderer.prototype.renderBorder = function(data) {
+      if (!data.color.isTransparent() && data.args !== null) {
+          this.drawShape(data.args, data.color);
+      }
+  };
+
+  Renderer.prototype.renderBackgroundImage = function(container, bounds, borderData) {
+      var backgroundImages = container.parseBackgroundImages();
+      backgroundImages.reverse().forEach(function(backgroundImage, index, arr) {
+          switch(backgroundImage.method) {
+          case "url":
+              var image = this.images.get(backgroundImage.args[0]);
+              if (image) {
+                  this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1), borderData);
+              } else {
+                  log("Error loading background-image", backgroundImage.args[0]);
+              }
+              break;
+          case "linear-gradient":
+          case "gradient":
+              var gradientImage = this.images.get(backgroundImage.value);
+              if (gradientImage) {
+                  this.renderBackgroundGradient(gradientImage, bounds, borderData);
+              } else {
+                  log("Error loading background-image", backgroundImage.args[0]);
+              }
+              break;
+          case "none":
+              break;
+          default:
+              log("Unknown background-image type", backgroundImage.args[0]);
+          }
+      }, this);
+  };
+
+  Renderer.prototype.renderBackgroundRepeating = function(container, bounds, imageContainer, index, borderData) {
+      var size = container.parseBackgroundSize(bounds, imageContainer.image, index);
+      var position = container.parseBackgroundPosition(bounds, imageContainer.image, index, size);
+      var repeat = container.parseBackgroundRepeat(index);
+      switch (repeat) {
+      case "repeat-x":
+      case "repeat no-repeat":
+          this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + borderData[3], bounds.top + position.top + borderData[0], 99999, size.height, borderData);
+          break;
+      case "repeat-y":
+      case "no-repeat repeat":
+          this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + borderData[0], size.width, 99999, borderData);
+          break;
+      case "no-repeat":
+          this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + position.top + borderData[0], size.width, size.height, borderData);
+          break;
+      default:
+          this.renderBackgroundRepeat(imageContainer, position, size, {top: bounds.top, left: bounds.left}, borderData[3], borderData[0]);
+          break;
+      }
+  };
+
+  module.exports = Renderer;
+
+  },{"./log":13}],20:[function(_dereq_,module,exports){
+  var Renderer = _dereq_('../renderer');
+  var LinearGradientContainer = _dereq_('../lineargradientcontainer');
+  var log = _dereq_('../log');
+
+  function CanvasRenderer(width, height) {
+      Renderer.apply(this, arguments);
+      this.canvas = this.options.canvas || this.document.createElement("canvas");
+      if (!this.options.canvas) {
+          this.canvas.width = width;
+          this.canvas.height = height;
+      }
+      this.ctx = this.canvas.getContext("2d");
+      this.taintCtx = this.document.createElement("canvas").getContext("2d");
+      this.ctx.textBaseline = "bottom";
+      this.variables = {};
+      log("Initialized CanvasRenderer with size", width, "x", height);
+  }
+
+  CanvasRenderer.prototype = Object.create(Renderer.prototype);
+
+  CanvasRenderer.prototype.setFillStyle = function(fillStyle) {
+      this.ctx.fillStyle = typeof(fillStyle) === "object" && !!fillStyle.isColor ? fillStyle.toString() : fillStyle;
+      return this.ctx;
+  };
+
+  CanvasRenderer.prototype.rectangle = function(left, top, width, height, color) {
+      this.setFillStyle(color).fillRect(left, top, width, height);
+  };
+
+  CanvasRenderer.prototype.circle = function(left, top, size, color) {
+      this.setFillStyle(color);
+      this.ctx.beginPath();
+      this.ctx.arc(left + size / 2, top + size / 2, size / 2, 0, Math.PI*2, true);
+      this.ctx.closePath();
+      this.ctx.fill();
+  };
+
+  CanvasRenderer.prototype.circleStroke = function(left, top, size, color, stroke, strokeColor) {
+      this.circle(left, top, size, color);
+      this.ctx.strokeStyle = strokeColor.toString();
+      this.ctx.stroke();
+  };
+
+  CanvasRenderer.prototype.drawShape = function(shape, color) {
+      this.shape(shape);
+      this.setFillStyle(color).fill();
+  };
+
+  CanvasRenderer.prototype.taints = function(imageContainer) {
+      if (imageContainer.tainted === null) {
+          this.taintCtx.drawImage(imageContainer.image, 0, 0);
+          try {
+              this.taintCtx.getImageData(0, 0, 1, 1);
+              imageContainer.tainted = false;
+          } catch(e) {
+              this.taintCtx = document.createElement("canvas").getContext("2d");
+              imageContainer.tainted = true;
+          }
+      }
+
+      return imageContainer.tainted;
+  };
+
+  CanvasRenderer.prototype.drawImage = function(imageContainer, sx, sy, sw, sh, dx, dy, dw, dh) {
+      if (!this.taints(imageContainer) || this.options.allowTaint) {
+          this.ctx.drawImage(imageContainer.image, sx, sy, sw, sh, dx, dy, dw, dh);
+      }
+  };
+
+  CanvasRenderer.prototype.clip = function(shapes, callback, context) {
+      this.ctx.save();
+      shapes.filter(hasEntries).forEach(function(shape) {
+          this.shape(shape).clip();
+      }, this);
+      callback.call(context);
+      this.ctx.restore();
+  };
+
+  CanvasRenderer.prototype.shape = function(shape) {
+      this.ctx.beginPath();
+      shape.forEach(function(point, index) {
+          if (point[0] === "rect") {
+              this.ctx.rect.apply(this.ctx, point.slice(1));
+          } else {
+              this.ctx[(index === 0) ? "moveTo" : point[0] + "To" ].apply(this.ctx, point.slice(1));
+          }
+      }, this);
+      this.ctx.closePath();
+      return this.ctx;
+  };
+
+  CanvasRenderer.prototype.font = function(color, style, variant, weight, size, family) {
+      this.setFillStyle(color).font = [style, variant, weight, size, family].join(" ").split(",")[0];
+  };
+
+  CanvasRenderer.prototype.fontShadow = function(color, offsetX, offsetY, blur) {
+      this.setVariable("shadowColor", color.toString())
+          .setVariable("shadowOffsetY", offsetX)
+          .setVariable("shadowOffsetX", offsetY)
+          .setVariable("shadowBlur", blur);
+  };
+
+  CanvasRenderer.prototype.clearShadow = function() {
+      this.setVariable("shadowColor", "rgba(0,0,0,0)");
+  };
+
+  CanvasRenderer.prototype.setOpacity = function(opacity) {
+      this.ctx.globalAlpha = opacity;
+  };
+
+  CanvasRenderer.prototype.setTransform = function(transform) {
+      this.ctx.translate(transform.origin[0], transform.origin[1]);
+      this.ctx.transform.apply(this.ctx, transform.matrix);
+      this.ctx.translate(-transform.origin[0], -transform.origin[1]);
+  };
+
+  CanvasRenderer.prototype.setVariable = function(property, value) {
+      if (this.variables[property] !== value) {
+          this.variables[property] = this.ctx[property] = value;
+      }
+
+      return this;
+  };
+
+  CanvasRenderer.prototype.text = function(text, left, bottom) {
+      this.ctx.fillText(text, left, bottom);
+  };
+
+  CanvasRenderer.prototype.backgroundRepeatShape = function(imageContainer, backgroundPosition, size, bounds, left, top, width, height, borderData) {
+      var shape = [
+          ["line", Math.round(left), Math.round(top)],
+          ["line", Math.round(left + width), Math.round(top)],
+          ["line", Math.round(left + width), Math.round(height + top)],
+          ["line", Math.round(left), Math.round(height + top)]
+      ];
+      this.clip([shape], function() {
+          this.renderBackgroundRepeat(imageContainer, backgroundPosition, size, bounds, borderData[3], borderData[0]);
+      }, this);
+  };
+
+  CanvasRenderer.prototype.renderBackgroundRepeat = function(imageContainer, backgroundPosition, size, bounds, borderLeft, borderTop) {
+      var offsetX = Math.round(bounds.left + backgroundPosition.left + borderLeft), offsetY = Math.round(bounds.top + backgroundPosition.top + borderTop);
+      this.setFillStyle(this.ctx.createPattern(this.resizeImage(imageContainer, size), "repeat"));
+      this.ctx.translate(offsetX, offsetY);
+      this.ctx.fill();
+      this.ctx.translate(-offsetX, -offsetY);
+  };
+
+  CanvasRenderer.prototype.renderBackgroundGradient = function(gradientImage, bounds) {
+      if (gradientImage instanceof LinearGradientContainer) {
+          var gradient = this.ctx.createLinearGradient(
+              bounds.left + bounds.width * gradientImage.x0,
+              bounds.top + bounds.height * gradientImage.y0,
+              bounds.left +  bounds.width * gradientImage.x1,
+              bounds.top +  bounds.height * gradientImage.y1);
+          gradientImage.colorStops.forEach(function(colorStop) {
+              gradient.addColorStop(colorStop.stop, colorStop.color.toString());
+          });
+          this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, gradient);
+      }
+  };
+
+  CanvasRenderer.prototype.resizeImage = function(imageContainer, size) {
+      var image = imageContainer.image;
+      if(image.width === size.width && image.height === size.height) {
+          return image;
+      }
+
+      var ctx, canvas = document.createElement('canvas');
+      canvas.width = size.width;
+      canvas.height = size.height;
+      ctx = canvas.getContext("2d");
+      ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, size.width, size.height );
+      return canvas;
+  };
+
+  function hasEntries(array) {
+      return array.length > 0;
+  }
+
+  module.exports = CanvasRenderer;
+
+  },{"../lineargradientcontainer":12,"../log":13,"../renderer":19}],21:[function(_dereq_,module,exports){
+  var NodeContainer = _dereq_('./nodecontainer');
+
+  function StackingContext(hasOwnStacking, opacity, element, parent) {
+      NodeContainer.call(this, element, parent);
+      this.ownStacking = hasOwnStacking;
+      this.contexts = [];
+      this.children = [];
+      this.opacity = (this.parent ? this.parent.stack.opacity : 1) * opacity;
+  }
+
+  StackingContext.prototype = Object.create(NodeContainer.prototype);
+
+  StackingContext.prototype.getParentStack = function(context) {
+      var parentStack = (this.parent) ? this.parent.stack : null;
+      return parentStack ? (parentStack.ownStacking ? parentStack : parentStack.getParentStack(context)) : context.stack;
+  };
+
+  module.exports = StackingContext;
+
+  },{"./nodecontainer":14}],22:[function(_dereq_,module,exports){
+  function Support(document) {
+      this.rangeBounds = this.testRangeBounds(document);
+      this.cors = this.testCORS();
+      this.svg = this.testSVG();
+  }
+
+  Support.prototype.testRangeBounds = function(document) {
+      var range, testElement, rangeBounds, rangeHeight, support = false;
+
+      if (document.createRange) {
+          range = document.createRange();
+          if (range.getBoundingClientRect) {
+              testElement = document.createElement('boundtest');
+              testElement.style.height = "123px";
+              testElement.style.display = "block";
+              document.body.appendChild(testElement);
+
+              range.selectNode(testElement);
+              rangeBounds = range.getBoundingClientRect();
+              rangeHeight = rangeBounds.height;
+
+              if (rangeHeight === 123) {
+                  support = true;
+              }
+              document.body.removeChild(testElement);
+          }
+      }
+
+      return support;
+  };
+
+  Support.prototype.testCORS = function() {
+      return typeof((new Image()).crossOrigin) !== "undefined";
+  };
+
+  Support.prototype.testSVG = function() {
+      var img = new Image();
+      var canvas = document.createElement("canvas");
+      var ctx =  canvas.getContext("2d");
+      img.src = "data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>";
+
+      try {
+          ctx.drawImage(img, 0, 0);
+          canvas.toDataURL();
+      } catch(e) {
+          return false;
+      }
+      return true;
+  };
+
+  module.exports = Support;
+
+  },{}],23:[function(_dereq_,module,exports){
+  var XHR = _dereq_('./xhr');
+  var decode64 = _dereq_('./utils').decode64;
+
+  function SVGContainer(src) {
+      this.src = src;
+      this.image = null;
+      var self = this;
+
+      this.promise = this.hasFabric().then(function() {
+          return (self.isInline(src) ? Promise.resolve(self.inlineFormatting(src)) : XHR(src));
+      }).then(function(svg) {
+          return new Promise(function(resolve) {
+              window.html2canvas.svg.fabric.loadSVGFromString(svg, self.createCanvas.call(self, resolve));
+          });
+      });
+  }
+
+  SVGContainer.prototype.hasFabric = function() {
+      return !window.html2canvas.svg || !window.html2canvas.svg.fabric ? Promise.reject(new Error("html2canvas.svg.js is not loaded, cannot render svg")) : Promise.resolve();
+  };
+
+  SVGContainer.prototype.inlineFormatting = function(src) {
+      return (/^data:image\/svg\+xml;base64,/.test(src)) ? this.decode64(this.removeContentType(src)) : this.removeContentType(src);
+  };
+
+  SVGContainer.prototype.removeContentType = function(src) {
+      return src.replace(/^data:image\/svg\+xml(;base64)?,/,'');
+  };
+
+  SVGContainer.prototype.isInline = function(src) {
+      return (/^data:image\/svg\+xml/i.test(src));
+  };
+
+  SVGContainer.prototype.createCanvas = function(resolve) {
+      var self = this;
+      return function (objects, options) {
+          var canvas = new window.html2canvas.svg.fabric.StaticCanvas('c');
+          self.image = canvas.lowerCanvasEl;
+          canvas
+              .setWidth(options.width)
+              .setHeight(options.height)
+              .add(window.html2canvas.svg.fabric.util.groupSVGElements(objects, options))
+              .renderAll();
+          resolve(canvas.lowerCanvasEl);
+      };
+  };
+
+  SVGContainer.prototype.decode64 = function(str) {
+      return (typeof(window.atob) === "function") ? window.atob(str) : decode64(str);
+  };
+
+  module.exports = SVGContainer;
+
+  },{"./utils":26,"./xhr":28}],24:[function(_dereq_,module,exports){
+  var SVGContainer = _dereq_('./svgcontainer');
+
+  function SVGNodeContainer(node, _native) {
+      this.src = node;
+      this.image = null;
+      var self = this;
+
+      this.promise = _native ? new Promise(function(resolve, reject) {
+          self.image = new Image();
+          self.image.onload = resolve;
+          self.image.onerror = reject;
+          self.image.src = "data:image/svg+xml," + (new XMLSerializer()).serializeToString(node);
+          if (self.image.complete === true) {
+              resolve(self.image);
+          }
+      }) : this.hasFabric().then(function() {
+          return new Promise(function(resolve) {
+              window.html2canvas.svg.fabric.parseSVGDocument(node, self.createCanvas.call(self, resolve));
+          });
+      });
+  }
+
+  SVGNodeContainer.prototype = Object.create(SVGContainer.prototype);
+
+  module.exports = SVGNodeContainer;
+
+  },{"./svgcontainer":23}],25:[function(_dereq_,module,exports){
+  var NodeContainer = _dereq_('./nodecontainer');
+
+  function TextContainer(node, parent) {
+      NodeContainer.call(this, node, parent);
+  }
+
+  TextContainer.prototype = Object.create(NodeContainer.prototype);
+
+  TextContainer.prototype.applyTextTransform = function() {
+      this.node.data = this.transform(this.parent.css("textTransform"));
+  };
+
+  TextContainer.prototype.transform = function(transform) {
+      var text = this.node.data;
+      switch(transform){
+          case "lowercase":
+              return text.toLowerCase();
+          case "capitalize":
+              return text.replace(/(^|\s|:|-|\(|\))([a-z])/g, capitalize);
+          case "uppercase":
+              return text.toUpperCase();
+          default:
+              return text;
+      }
+  };
+
+  function capitalize(m, p1, p2) {
+      if (m.length > 0) {
+          return p1 + p2.toUpperCase();
+      }
+  }
+
+  module.exports = TextContainer;
+
+  },{"./nodecontainer":14}],26:[function(_dereq_,module,exports){
+  exports.smallImage = function smallImage() {
+      return "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
+  };
+
+  exports.bind = function(callback, context) {
+      return function() {
+          return callback.apply(context, arguments);
+      };
+  };
+
+  /*
+   * base64-arraybuffer
+   * https://github.com/niklasvh/base64-arraybuffer
+   *
+   * Copyright (c) 2012 Niklas von Hertzen
+   * Licensed under the MIT license.
+   */
+
+  exports.decode64 = function(base64) {
+      var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+      var len = base64.length, i, encoded1, encoded2, encoded3, encoded4, byte1, byte2, byte3;
+
+      var output = "";
+
+      for (i = 0; i < len; i+=4) {
+          encoded1 = chars.indexOf(base64[i]);
+          encoded2 = chars.indexOf(base64[i+1]);
+          encoded3 = chars.indexOf(base64[i+2]);
+          encoded4 = chars.indexOf(base64[i+3]);
+
+          byte1 = (encoded1 << 2) | (encoded2 >> 4);
+          byte2 = ((encoded2 & 15) << 4) | (encoded3 >> 2);
+          byte3 = ((encoded3 & 3) << 6) | encoded4;
+          if (encoded3 === 64) {
+              output += String.fromCharCode(byte1);
+          } else if (encoded4 === 64 || encoded4 === -1) {
+              output += String.fromCharCode(byte1, byte2);
+          } else{
+              output += String.fromCharCode(byte1, byte2, byte3);
+          }
+      }
+
+      return output;
+  };
+
+  exports.getBounds = function(node) {
+      if (node.getBoundingClientRect) {
+          var clientRect = node.getBoundingClientRect();
+          var width = node.offsetWidth == null ? clientRect.width : node.offsetWidth;
+          return {
+              top: clientRect.top,
+              bottom: clientRect.bottom || (clientRect.top + clientRect.height),
+              right: clientRect.left + width,
+              left: clientRect.left,
+              width:  width,
+              height: node.offsetHeight == null ? clientRect.height : node.offsetHeight
+          };
+      }
+      return {};
+  };
+
+  exports.offsetBounds = function(node) {
+      var parent = node.offsetParent ? exports.offsetBounds(node.offsetParent) : {top: 0, left: 0};
+
+      return {
+          top: node.offsetTop + parent.top,
+          bottom: node.offsetTop + node.offsetHeight + parent.top,
+          right: node.offsetLeft + parent.left + node.offsetWidth,
+          left: node.offsetLeft + parent.left,
+          width: node.offsetWidth,
+          height: node.offsetHeight
+      };
+  };
+
+  exports.parseBackgrounds = function(backgroundImage) {
+      var whitespace = ' \r\n\t',
+          method, definition, prefix, prefix_i, block, results = [],
+          mode = 0, numParen = 0, quote, args;
+      var appendResult = function() {
+          if(method) {
+              if (definition.substr(0, 1) === '"') {
+                  definition = definition.substr(1, definition.length - 2);
+              }
+              if (definition) {
+                  args.push(definition);
+              }
+              if (method.substr(0, 1) === '-' && (prefix_i = method.indexOf('-', 1 ) + 1) > 0) {
+                  prefix = method.substr(0, prefix_i);
+                  method = method.substr(prefix_i);
+              }
+              results.push({
+                  prefix: prefix,
+                  method: method.toLowerCase(),
+                  value: block,
+                  args: args,
+                  image: null
+              });
+          }
+          args = [];
+          method = prefix = definition = block = '';
+      };
+      args = [];
+      method = prefix = definition = block = '';
+      backgroundImage.split("").forEach(function(c) {
+          if (mode === 0 && whitespace.indexOf(c) > -1) {
+              return;
+          }
+          switch(c) {
+          case '"':
+              if(!quote) {
+                  quote = c;
+              } else if(quote === c) {
+                  quote = null;
+              }
+              break;
+          case '(':
+              if(quote) {
+                  break;
+              } else if(mode === 0) {
+                  mode = 1;
+                  block += c;
+                  return;
+              } else {
+                  numParen++;
+              }
+              break;
+          case ')':
+              if (quote) {
+                  break;
+              } else if(mode === 1) {
+                  if(numParen === 0) {
+                      mode = 0;
+                      block += c;
+                      appendResult();
+                      return;
+                  } else {
+                      numParen--;
+                  }
+              }
+              break;
+
+          case ',':
+              if (quote) {
+                  break;
+              } else if(mode === 0) {
+                  appendResult();
+                  return;
+              } else if (mode === 1) {
+                  if (numParen === 0 && !method.match(/^url$/i)) {
+                      args.push(definition);
+                      definition = '';
+                      block += c;
+                      return;
+                  }
+              }
+              break;
+          }
+
+          block += c;
+          if (mode === 0) {
+              method += c;
+          } else {
+              definition += c;
+          }
+      });
+
+      appendResult();
+      return results;
+  };
+
+  },{}],27:[function(_dereq_,module,exports){
+  var GradientContainer = _dereq_('./gradientcontainer');
+
+  function WebkitGradientContainer(imageData) {
+      GradientContainer.apply(this, arguments);
+      this.type = imageData.args[0] === "linear" ? GradientContainer.TYPES.LINEAR : GradientContainer.TYPES.RADIAL;
+  }
+
+  WebkitGradientContainer.prototype = Object.create(GradientContainer.prototype);
+
+  module.exports = WebkitGradientContainer;
+
+  },{"./gradientcontainer":9}],28:[function(_dereq_,module,exports){
+  function XHR(url) {
+      return new Promise(function(resolve, reject) {
+          var xhr = new XMLHttpRequest();
+          xhr.open('GET', url);
+
+          xhr.onload = function() {
+              if (xhr.status === 200) {
+                  resolve(xhr.responseText);
+              } else {
+                  reject(new Error(xhr.statusText));
+              }
+          };
+
+          xhr.onerror = function() {
+              reject(new Error("Network Error"));
+          };
+
+          xhr.send();
+      });
+  }
+
+  module.exports = XHR;
+
+  },{}]},{},[4])(4)
+  });
+
+  /************************************************
+   * Title : custom font                          *
+   * Start Data : 2017. 01. 22.                   *
+   * Comment : TEXT API                           *
+   ************************************************/
+
+  /******************************
+   * jsPDF extension API Design *
+   * ****************************/
+  (function(jsPDF){
+      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 : b64ToByteArray                                     */
+      /* comment : Base64 encoded TTF file contents (b64) are decoded  */
+      /*     by Byte array and stored.                                 */
+      /*****************************************************************/
+      var b64ToByteArray = function(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 Uint8Array(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 : decode                                           */
+      /* comment : Change the base64 encoded font's content to match */
+      /*   the base64 index value.                                   */
+      /***************************************************************/
+      var decode = function(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
+      };
+
+      jsPDF.API.TTFFont = (function () {
+          /************************************************************************/
+          /* function : open                                                       */
+          /* comment : Decode the encoded ttf content and create a TTFFont object. */
+          /************************************************************************/
+          TTFFont.open = function (filename, name, vfs, encoding) {
+              var contents;
+              contents = b64ToByteArray(vfs);
+              return new TTFFont(contents, name, encoding);
+          };
+          /***************************************************************/
+          /* function : TTFFont gernerator                               */
+          /* comment : Decode TTF contents are parsed, Data,             */
+          /* Subset object is created, and registerTTF function is called.*/
+          /***************************************************************/
+          function TTFFont(rawData, name, encoding) {
+              var data;
+              this.rawData = rawData;
+              data = this.contents = new Data(rawData);
+              this.contents.pos = 4;
+              if (data.readString(4) === 'ttcf') {
+                  if (!name) {
+                      throw new Error("Must specify a font name for TTC files.");
+                  }
+                  throw new Error("Font " + name + " not found in TTC file.");
+              }
+              else {
+                  data.pos = 0;
+                  this.parse();
+                  this.subset = new Subset(this);
+                  this.registerTTF();
+              }
+          }
+          /********************************************************/
+          /* function : parse                                     */
+          /* comment : TTF Parses the file contents by each table.*/
+          /********************************************************/
+          TTFFont.prototype.parse = function () {
+              this.directory = new Directory(this.contents);
+              this.head = new HeadTable(this);
+              this.name = new NameTable(this);
+              this.cmap = new CmapTable(this);
+              this.hhea = new HheaTable(this);
+              this.maxp = new MaxpTable(this);
+              this.hmtx = new HmtxTable(this);
+              this.post = new PostTable(this);
+              this.os2 = new OS2Table(this);
+              this.loca = new LocaTable(this);
+              this.glyf = new GlyfTable(this);
+              this.ascender = (this.os2.exists && this.os2.ascender) || this.hhea.ascender;
+              this.decender = (this.os2.exists && this.os2.decender) || this.hhea.decender;
+              this.lineGap = (this.os2.exists && this.os2.lineGap) || this.hhea.lineGap;
+              return this.bbox = [this.head.xMin, this.head.yMin, this.head.xMax, this.head.yMax];
+          };
+          /***************************************************************/
+          /* function : registerTTF                                      */
+          /* comment : Get the value to assign pdf font descriptors.     */
+          /***************************************************************/
+          TTFFont.prototype.registerTTF = function () {
+              var e, hi, low, raw, _ref;
+              this.scaleFactor = 1000.0 / this.head.unitsPerEm;
+              this.bbox = (function () {
+                  var _i, _len, _ref, _results;
+                  _ref = this.bbox;
+                  _results = [];
+                  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+                      e = _ref[_i];
+                      _results.push(Math.round(e * this.scaleFactor));
+                  }
+                  return _results;
+              }).call(this);
+              this.stemV = 0;
+              if (this.post.exists) {
+                  raw = this.post.italic_angle;
+                  hi = raw >> 16;
+                  low = raw & 0xFF;
+                  if (hi & 0x8000 !== 0) {
+                      hi = -((hi ^ 0xFFFF) + 1);
+                  }
+                  this.italicAngle = +("" + hi + "." + low);
+              }
+              else {
+                  this.italicAngle = 0;
+              }
+              this.ascender = Math.round(this.ascender * this.scaleFactor);
+              this.decender = Math.round(this.decender * this.scaleFactor);
+              this.lineGap = Math.round(this.lineGap * this.scaleFactor);
+              this.capHeight = (this.os2.exists && this.os2.capHeight) || this.ascender;
+              this.xHeight = (this.os2.exists && this.os2.xHeight) || 0;
+              this.familyClass = (this.os2.exists && this.os2.familyClass || 0) >> 8;
+              this.isSerif = (_ref = this.familyClass) === 1 || _ref === 2 || _ref === 3 || _ref === 4 || _ref === 5 || _ref === 7;
+              this.isScript = this.familyClass === 10;
+              this.flags = 0;
+              if (this.post.isFixedPitch) {
+                  this.flags |= 1 << 0;
+              }
+              if (this.isSerif) {
+                  this.flags |= 1 << 1;
+              }
+              if (this.isScript) {
+                  this.flags |= 1 << 3;
+              }
+              if (this.italicAngle !== 0) {
+                  this.flags |= 1 << 6;
+              }
+              this.flags |= 1 << 5;
+              if (!this.cmap.unicode) {
+                  throw new Error('No unicode cmap for font');
+              }
+          };
+          TTFFont.prototype.characterToGlyph = function (character) {
+              var _ref;
+              return ((_ref = this.cmap.unicode) != null ? _ref.codeMap[character] : void 0) || 0;
+          };
+          TTFFont.prototype.widthOfGlyph = function (glyph) {
+              var scale;
+              scale = 1000.0 / this.head.unitsPerEm;
+              return this.hmtx.forGlyph(glyph).advance * scale;
+          };
+          TTFFont.prototype.widthOfString = function (string, size, charSpace) {
+              var charCode, i, scale, width, _i, _ref, charSpace;
+              string = '' + string;
+              width = 0;
+              for (i = _i = 0, _ref = string.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
+                  charCode = string.charCodeAt(i);
+                  width += (this.widthOfGlyph(this.characterToGlyph(charCode)) + charSpace * (1000/ size)) || 0;
+              }
+              scale = size / 1000;
+              return width * scale;
+          };
+          TTFFont.prototype.lineHeight = function (size, includeGap) {
+              var gap;
+              if (includeGap == null) {
+                  includeGap = false;
+              }
+              gap = includeGap ? this.lineGap : 0;
+              return (this.ascender + gap - this.decender) / 1000 * size;
+          };
+          return TTFFont;
+      })();
+
+      /************************************************************************************************/
+      /* function : Data                                                                              */
+      /* comment : The ttf data decoded and stored in an array is read and written to the Data object.*/
+      /************************************************************************************************/
+      var Data = (function () {
+          function Data(data) {
+              this.data = data != null ? data : [];
+              this.pos = 0;
+              this.length = this.data.length;
+          }
+          Data.prototype.readByte = function () {
+              return this.data[this.pos++];
+          };
+          Data.prototype.writeByte = function (byte) {
+              return this.data[this.pos++] = byte;
+          };
+          Data.prototype.readUInt32 = function () {
+              var b1, b2, b3, b4;
+              b1 = this.readByte() * 0x1000000;
+              b2 = this.readByte() << 16;
+              b3 = this.readByte() << 8;
+              b4 = this.readByte();
+              return b1 + b2 + b3 + b4;
+          };
+          Data.prototype.writeUInt32 = function (val) {
+              this.writeByte((val >>> 24) & 0xff);
+              this.writeByte((val >> 16) & 0xff);
+              this.writeByte((val >> 8) & 0xff);
+              return this.writeByte(val & 0xff);
+          };
+          Data.prototype.readInt32 = function () {
+              var int;
+              int = this.readUInt32();
+              if (int >= 0x80000000) {
+                  return int - 0x100000000;
+              }
+              else {
+                  return int;
+              }
+          };
+          Data.prototype.writeInt32 = function (val) {
+              if (val < 0) {
+                  val += 0x100000000;
+              }
+              return this.writeUInt32(val);
+          };
+          Data.prototype.readUInt16 = function () {
+              var b1, b2;
+              b1 = this.readByte() << 8;
+              b2 = this.readByte();
+              return b1 | b2;
+          };
+          Data.prototype.writeUInt16 = function (val) {
+              this.writeByte((val >> 8) & 0xff);
+              return this.writeByte(val & 0xff);
+          };
+          Data.prototype.readInt16 = function () {
+              var int;
+              int = this.readUInt16();
+              if (int >= 0x8000) {
+                  return int - 0x10000;
+              }
+              else {
+                  return int;
+              }
+          };
+          Data.prototype.writeInt16 = function (val) {
+              if (val < 0) {
+                  val += 0x10000;
+              }
+              return this.writeUInt16(val);
+          };
+          Data.prototype.readString = function (length) {
+              var i, ret, _i;
+              ret = [];
+              for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) {
+                  ret[i] = String.fromCharCode(this.readByte());
+              }
+              return ret.join('');
+          };
+          Data.prototype.writeString = function (val) {
+              var i, _i, _ref, _results;
+              _results = [];
+              for (i = _i = 0, _ref = val.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
+                  _results.push(this.writeByte(val.charCodeAt(i)));
+              }
+              return _results;
+          };
+          /*Data.prototype.stringAt = function (pos, length) {
+              this.pos = pos;
+              return this.readString(length);
+          };*/
+          Data.prototype.readShort = function () {
+              return this.readInt16();
+          };
+          Data.prototype.writeShort = function (val) {
+              return this.writeInt16(val);
+          };
+          Data.prototype.readLongLong = function () {
+              var b1, b2, b3, b4, b5, b6, b7, b8;
+              b1 = this.readByte();
+              b2 = this.readByte();
+              b3 = this.readByte();
+              b4 = this.readByte();
+              b5 = this.readByte();
+              b6 = this.readByte();
+              b7 = this.readByte();
+              b8 = this.readByte();
+              if (b1 & 0x80) {
+                  return ((b1 ^ 0xff) * 0x100000000000000 + (b2 ^ 0xff) * 0x1000000000000 + (b3 ^ 0xff) * 0x10000000000 + (b4 ^ 0xff) * 0x100000000 + (b5 ^ 0xff) * 0x1000000 + (b6 ^ 0xff) * 0x10000 + (b7 ^ 0xff) * 0x100 + (b8 ^ 0xff) + 1) * -1;
+              }
+              return b1 * 0x100000000000000 + b2 * 0x1000000000000 + b3 * 0x10000000000 + b4 * 0x100000000 + b5 * 0x1000000 + b6 * 0x10000 + b7 * 0x100 + b8;
+          };
+          /*Data.prototype.writeLongLong = function (val) {
+              var high, low;
+              high = Math.floor(val / 0x100000000);
+              low = val & 0xffffffff;
+              this.writeByte((high >> 24) & 0xff);
+              this.writeByte((high >> 16) & 0xff);
+              this.writeByte((high >> 8) & 0xff);
+              this.writeByte(high & 0xff);
+              this.writeByte((low >> 24) & 0xff);
+              this.writeByte((low >> 16) & 0xff);
+              this.writeByte((low >> 8) & 0xff);
+              return this.writeByte(low & 0xff);
+          };*/
+          Data.prototype.readInt = function () {
+              return this.readInt32();
+          };
+          Data.prototype.writeInt = function (val) {
+              return this.writeInt32(val);
+          };
+          /*Data.prototype.slice = function (start, end) {
+              return this.data.slice(start, end);
+          };*/
+          Data.prototype.read = function (bytes) {
+              var buf, i, _i;
+              buf = [];
+              for (i = _i = 0; 0 <= bytes ? _i < bytes : _i > bytes; i = 0 <= bytes ? ++_i : --_i) {
+                  buf.push(this.readByte());
+              }
+              return buf;
+          };
+          Data.prototype.write = function (bytes) {
+              var byte, _i, _len, _results;
+              _results = [];
+              for (_i = 0, _len = bytes.length; _i < _len; _i++) {
+                  byte = bytes[_i];
+                  _results.push(this.writeByte(byte));
+              }
+              return _results;
+          };
+          return Data;
+      })();
+
+      var Directory = (function () {
+          var checksum;
+
+          /*****************************************************************************************************/
+          /* function : Directory generator                                                                    */
+          /* comment : Initialize the offset, tag, length, and checksum for each table for the font to be used.*/
+          /*****************************************************************************************************/
+          function Directory(data) {
+              var entry, i, _i, _ref;
+              this.scalarType = data.readInt();
+              this.tableCount = data.readShort();
+              this.searchRange = data.readShort();
+              this.entrySelector = data.readShort();
+              this.rangeShift = data.readShort();
+              this.tables = {};
+              for (i = _i = 0, _ref = this.tableCount; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
+                  entry = {
+                      tag: data.readString(4)
+                      , checksum: data.readInt()
+                      , offset: data.readInt()
+                      , length: data.readInt()
+                  };
+                  this.tables[entry.tag] = entry;
+              }
+          }
+          /********************************************************************************************************/
+          /* function : encode                                                                                    */
+          /* comment : It encodes and stores the font table object and information used for the directory object. */
+          /********************************************************************************************************/
+          Directory.prototype.encode = function (tables) {
+              var adjustment, directory, directoryLength, entrySelector, headOffset, log2, offset, rangeShift, searchRange, sum, table, tableCount, tableData, tag;
+              tableCount = Object.keys(tables).length;
+              log2 = Math.log(2);
+              searchRange = Math.floor(Math.log(tableCount) / log2) * 16;
+              entrySelector = Math.floor(searchRange / log2);
+              rangeShift = tableCount * 16 - searchRange;
+              directory = new Data;
+              directory.writeInt(this.scalarType);
+              directory.writeShort(tableCount);
+              directory.writeShort(searchRange);
+              directory.writeShort(entrySelector);
+              directory.writeShort(rangeShift);
+              directoryLength = tableCount * 16;
+              offset = directory.pos + directoryLength;
+              headOffset = null;
+              tableData = [];
+              for (tag in tables) {
+                  table = tables[tag];
+                  directory.writeString(tag);
+                  directory.writeInt(checksum(table));
+                  directory.writeInt(offset);
+                  directory.writeInt(table.length);
+                  tableData = tableData.concat(table);
+                  if (tag === 'head') {
+                      headOffset = offset;
+                  }
+                  offset += table.length;
+                  while (offset % 4) {
+                      tableData.push(0);
+                      offset++;
+                  }
+              }
+              directory.write(tableData);
+              sum = checksum(directory.data);
+              adjustment = 0xB1B0AFBA - sum;
+              directory.pos = headOffset + 8;
+              directory.writeUInt32(adjustment);
+              return directory.data;
+          };
+          /***************************************************************/
+          /* function : checksum                                         */
+          /* comment : Duplicate the table for the tag.                  */
+          /***************************************************************/
+          checksum = function (data) {
+              var i, sum, tmp, _i, _ref;
+              data = __slice.call(data);
+              while (data.length % 4) {
+                  data.push(0);
+              }
+              tmp = new Data(data);
+              sum = 0;
+              for (i = _i = 0, _ref = data.length; _i < _ref; i = _i += 4) {
+                  sum += tmp.readUInt32();
+              }
+              return sum & 0xFFFFFFFF;
+          };
+          return Directory;
+      })();
+
+      var Table, __hasProp = {}.hasOwnProperty
+          , __extends = function (child, parent) {
+              for (var key in parent) {
+                  if (__hasProp.call(parent, key)) child[key] = parent[key];
+              }
+
+              function ctor() {
+                  this.constructor = child;
+              }
+              ctor.prototype = parent.prototype;
+              child.prototype = new ctor();
+              child.__super__ = parent.prototype;
+              return child;
+      };
+      /***************************************************************/
+      /* function : Table                                            */
+      /* comment : Save info for each table, and parse the table.    */
+      /***************************************************************/
+      Table = (function () {
+          function Table(file) {
+              var info;
+              this.file = file;
+              info = this.file.directory.tables[this.tag];
+              this.exists = !!info;
+              if (info) {
+                  this.offset = info.offset, this.length = info.length;
+                  this.parse(this.file.contents);
+              }
+          }
+          Table.prototype.parse = function () {};
+          Table.prototype.encode = function () {};
+          Table.prototype.raw = function () {
+              if (!this.exists) {
+                  return null;
+              }
+              this.file.contents.pos = this.offset;
+              return this.file.contents.read(this.length);
+          };
+          return Table;
+      })();
+
+      var HeadTable = (function (_super) {
+          __extends(HeadTable, _super);
+
+          function HeadTable() {
+              return HeadTable.__super__.constructor.apply(this, arguments);
+          }
+          HeadTable.prototype.tag = 'head';
+          HeadTable.prototype.parse = function (data) {
+              data.pos = this.offset;
+              this.version = data.readInt();
+              this.revision = data.readInt();
+              this.checkSumAdjustment = data.readInt();
+              this.magicNumber = data.readInt();
+              this.flags = data.readShort();
+              this.unitsPerEm = data.readShort();
+              this.created = data.readLongLong();
+              this.modified = data.readLongLong();
+              this.xMin = data.readShort();
+              this.yMin = data.readShort();
+              this.xMax = data.readShort();
+              this.yMax = data.readShort();
+              this.macStyle = data.readShort();
+              this.lowestRecPPEM = data.readShort();
+              this.fontDirectionHint = data.readShort();
+              this.indexToLocFormat = data.readShort();
+              return this.glyphDataFormat = data.readShort();
+          };
+          /*HeadTable.prototype.encode = function (loca) {
+              var table;
+              table = new Data;
+              table.writeInt(this.version);
+              table.writeInt(this.revision);
+              table.writeInt(this.checkSumAdjustment);
+              table.writeInt(this.magicNumber);
+              table.writeShort(this.flags);
+              table.writeShort(this.unitsPerEm);
+              table.writeLongLong(this.created);
+              table.writeLongLong(this.modified);
+              table.writeShort(this.xMin);
+              table.writeShort(this.yMin);
+              table.writeShort(this.xMax);
+              table.writeShort(this.yMax);
+              table.writeShort(this.macStyle);
+              table.writeShort(this.lowestRecPPEM);
+              table.writeShort(this.fontDirectionHint);
+              table.writeShort(loca.type);
+              table.writeShort(this.glyphDataFormat);
+              return table.data;
+          };*/
+          return HeadTable;
+      })(Table);
+
+      /************************************************************************************/
+      /* function : CmapEntry                                                             */
+      /* comment : Cmap Initializes and encodes object information (required by pdf spec).*/
+      /************************************************************************************/
+      var CmapEntry = (function () {
+          function CmapEntry(data, offset) {
+              var code, count, endCode, glyphId, glyphIds, i, idDelta, idRangeOffset, index, saveOffset, segCount, segCountX2, start, startCode, tail, _i, _j, _k, _len;
+              this.platformID = data.readUInt16();
+              this.encodingID = data.readShort();
+              this.offset = offset + data.readInt();
+              saveOffset = data.pos;
+              data.pos = this.offset;
+              this.format = data.readUInt16();
+              this.length = data.readUInt16();
+              this.language = data.readUInt16();
+              this.isUnicode = (this.platformID === 3 && this.encodingID === 1 && this.format === 4) || this.platformID === 0 && this.format === 4;
+              this.codeMap = {};
+              switch (this.format) {
+              case 0:
+                  for (i = _i = 0; _i < 256; i = ++_i) {
+                      this.codeMap[i] = data.readByte();
+                  }
+                  break;
+              case 4:
+                  segCountX2 = data.readUInt16();
+                  segCount = segCountX2 / 2;
+                  data.pos += 6;
+                  endCode = (function () {
+                      var _j, _results;
+                      _results = [];
+                      for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
+                          _results.push(data.readUInt16());
+                      }
+                      return _results;
+                  })();
+                  data.pos += 2;
+                  startCode = (function () {
+                      var _j, _results;
+                      _results = [];
+                      for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
+                          _results.push(data.readUInt16());
+                      }
+                      return _results;
+                  })();
+                  idDelta = (function () {
+                      var _j, _results;
+                      _results = [];
+                      for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
+                          _results.push(data.readUInt16());
+                      }
+                      return _results;
+                  })();
+                  idRangeOffset = (function () {
+                      var _j, _results;
+                      _results = [];
+                      for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
+                          _results.push(data.readUInt16());
+                      }
+                      return _results;
+                  })();
+                  count = (this.length - data.pos + this.offset) / 2;
+                  glyphIds = (function () {
+                      var _j, _results;
+                      _results = [];
+                      for (i = _j = 0; 0 <= count ? _j < count : _j > count; i = 0 <= count ? ++_j : --_j) {
+                          _results.push(data.readUInt16());
+                      }
+                      return _results;
+                  })();
+                  for (i = _j = 0, _len = endCode.length; _j < _len; i = ++_j) {
+                      tail = endCode[i];
+                      start = startCode[i];
+                      for (code = _k = start; start <= tail ? _k <= tail : _k >= tail; code = start <= tail ? ++_k : --_k) {
+                          if (idRangeOffset[i] === 0) {
+                              glyphId = code + idDelta[i];
+                          }
+                          else {
+                              index = idRangeOffset[i] / 2 + (code - start) - (segCount - i);
+                              glyphId = glyphIds[index] || 0;
+                              if (glyphId !== 0) {
+                                  glyphId += idDelta[i];
+                              }
+                          }
+                          this.codeMap[code] = glyphId & 0xFFFF;
+                      }
+                  }
+              }
+              data.pos = saveOffset;
+          }
+          CmapEntry.encode = function (charmap, encoding) {
+              var charMap, code, codeMap, codes, delta, deltas, diff, endCode, endCodes, entrySelector, glyphIDs, i, id, indexes, last, map, nextID, offset, old, rangeOffsets, rangeShift, result, searchRange, segCount, segCountX2, startCode, startCodes, startGlyph, subtable, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _len6, _len7, _m, _n, _name, _o, _p, _q;
+              subtable = new Data;
+              codes = Object.keys(charmap).sort(function (a, b) {
+                  return a - b;
+              });
+              switch (encoding) {
+              case 'macroman':
+                  id = 0;
+                  indexes = (function () {
+                      var _i, _results;
+                      _results = [];
+                      for (i = _i = 0; _i < 256; i = ++_i) {
+                          _results.push(0);
+                      }
+                      return _results;
+                  })();
+                  map = {
+                      0: 0
+                  };
+                  codeMap = {};
+                  for (_i = 0, _len = codes.length; _i < _len; _i++) {
+                      code = codes[_i];
+                      if (map[_name = charmap[code]] == null) {
+                          map[_name] = ++id;
+                      }
+                      codeMap[code] = {
+                          old: charmap[code]
+                          , "new": map[charmap[code]]
+                      };
+                      indexes[code] = map[charmap[code]];
+                  }
+                  subtable.writeUInt16(1);
+                  subtable.writeUInt16(0);
+                  subtable.writeUInt32(12);
+                  subtable.writeUInt16(0);
+                  subtable.writeUInt16(262);
+                  subtable.writeUInt16(0);
+                  subtable.write(indexes);
+                  return result = {
+                      charMap: codeMap
+                      , subtable: subtable.data
+                      , maxGlyphID: id + 1
+                  };
+              case 'unicode':
+                  startCodes = [];
+                  endCodes = [];
+                  nextID = 0;
+                  map = {};
+                  charMap = {};
+                  last = diff = null;
+                  for (_j = 0, _len1 = codes.length; _j < _len1; _j++) {
+                      code = codes[_j];
+                      old = charmap[code];
+                      if (map[old] == null) {
+                          map[old] = ++nextID;
+                      }
+                      charMap[code] = {
+                          old: old
+                          , "new": map[old]
+                      };
+                      delta = map[old] - code;
+                      if ((last == null) || delta !== diff) {
+                          if (last) {
+                              endCodes.push(last);
+                          }
+                          startCodes.push(code);
+                          diff = delta;
+                      }
+                      last = code;
+                  }
+                  if (last) {
+                      endCodes.push(last);
+                  }
+                  endCodes.push(0xFFFF);
+                  startCodes.push(0xFFFF);
+                  segCount = startCodes.length;
+                  segCountX2 = segCount * 2;
+                  searchRange = 2 * Math.pow(Math.log(segCount) / Math.LN2, 2);
+                  entrySelector = Math.log(searchRange / 2) / Math.LN2;
+                  rangeShift = 2 * segCount - searchRange;
+                  deltas = [];
+                  rangeOffsets = [];
+                  glyphIDs = [];
+                  for (i = _k = 0, _len2 = startCodes.length; _k < _len2; i = ++_k) {
+                      startCode = startCodes[i];
+                      endCode = endCodes[i];
+                      if (startCode === 0xFFFF) {
+                          deltas.push(0);
+                          rangeOffsets.push(0);
+                          break;
+                      }
+                      startGlyph = charMap[startCode]["new"];
+                      if (startCode - startGlyph >= 0x8000) {
+                          deltas.push(0);
+                          rangeOffsets.push(2 * (glyphIDs.length + segCount - i));
+                          for (code = _l = startCode; startCode <= endCode ? _l <= endCode : _l >= endCode; code = startCode <= endCode ? ++_l : --_l) {
+                              glyphIDs.push(charMap[code]["new"]);
+                          }
+                      }
+                      else {
+                          deltas.push(startGlyph - startCode);
+                          rangeOffsets.push(0);
+                      }
+                  }
+                  subtable.writeUInt16(3);
+                  subtable.writeUInt16(1);
+                  subtable.writeUInt32(12);
+                  subtable.writeUInt16(4);
+                  subtable.writeUInt16(16 + segCount * 8 + glyphIDs.length * 2);
+                  subtable.writeUInt16(0);
+                  subtable.writeUInt16(segCountX2);
+                  subtable.writeUInt16(searchRange);
+                  subtable.writeUInt16(entrySelector);
+                  subtable.writeUInt16(rangeShift);
+                  for (_m = 0, _len3 = endCodes.length; _m < _len3; _m++) {
+                      code = endCodes[_m];
+                      subtable.writeUInt16(code);
+                  }
+                  subtable.writeUInt16(0);
+                  for (_n = 0, _len4 = startCodes.length; _n < _len4; _n++) {
+                      code = startCodes[_n];
+                      subtable.writeUInt16(code);
+                  }
+                  for (_o = 0, _len5 = deltas.length; _o < _len5; _o++) {
+                      delta = deltas[_o];
+                      subtable.writeUInt16(delta);
+                  }
+                  for (_p = 0, _len6 = rangeOffsets.length; _p < _len6; _p++) {
+                      offset = rangeOffsets[_p];
+                      subtable.writeUInt16(offset);
+                  }
+                  for (_q = 0, _len7 = glyphIDs.length; _q < _len7; _q++) {
+                      id = glyphIDs[_q];
+                      subtable.writeUInt16(id);
+                  }
+                  return result = {
+                      charMap: charMap
+                      , subtable: subtable.data
+                      , maxGlyphID: nextID + 1
+                  };
+              }
+          };
+          return CmapEntry;
+      })();
+
+      var CmapTable = (function (_super) {
+          __extends(CmapTable, _super);
+
+          function CmapTable() {
+              return CmapTable.__super__.constructor.apply(this, arguments);
+          }
+          CmapTable.prototype.tag = 'cmap';
+          CmapTable.prototype.parse = function (data) {
+              var entry, i, tableCount, _i;
+              data.pos = this.offset;
+              this.version = data.readUInt16();
+              tableCount = data.readUInt16();
+              this.tables = [];
+              this.unicode = null;
+              for (i = _i = 0; 0 <= tableCount ? _i < tableCount : _i > tableCount; i = 0 <= tableCount ? ++_i : --_i) {
+                  entry = new CmapEntry(data, this.offset);
+                  this.tables.push(entry);
+                  if (entry.isUnicode) {
+                      if (this.unicode == null) {
+                          this.unicode = entry;
+                      }
+                  }
+              }
+              return true;
+          };
+          /*************************************************************************/
+          /* function : encode                                                     */
+          /* comment : Encode the cmap table corresponding to the input character. */
+          /*************************************************************************/
+          CmapTable.encode = function (charmap, encoding) {
+              var result, table;
+              if (encoding == null) {
+                  encoding = 'macroman';
+              }
+              result = CmapEntry.encode(charmap, encoding);
+              table = new Data;
+              table.writeUInt16(0);
+              table.writeUInt16(1);
+              result.table = table.data.concat(result.subtable);
+              return result;
+          };
+          return CmapTable;
+      })(Table);
+
+      var HheaTable = (function (_super) {
+          __extends(HheaTable, _super);
+
+          function HheaTable() {
+              return HheaTable.__super__.constructor.apply(this, arguments);
+          }
+          HheaTable.prototype.tag = 'hhea';
+          HheaTable.prototype.parse = function (data) {
+              data.pos = this.offset;
+              this.version = data.readInt();
+              this.ascender = data.readShort();
+              this.decender = data.readShort();
+              this.lineGap = data.readShort();
+              this.advanceWidthMax = data.readShort();
+              this.minLeftSideBearing = data.readShort();
+              this.minRightSideBearing = data.readShort();
+              this.xMaxExtent = data.readShort();
+              this.caretSlopeRise = data.readShort();
+              this.caretSlopeRun = data.readShort();
+              this.caretOffset = data.readShort();
+              data.pos += 4 * 2;
+              this.metricDataFormat = data.readShort();
+              return this.numberOfMetrics = data.readUInt16();
+          };
+          /*HheaTable.prototype.encode = function (ids) {
+              var i, table, _i, _ref;
+              table = new Data;
+              table.writeInt(this.version);
+              table.writeShort(this.ascender);
+              table.writeShort(this.decender);
+              table.writeShort(this.lineGap);
+              table.writeShort(this.advanceWidthMax);
+              table.writeShort(this.minLeftSideBearing);
+              table.writeShort(this.minRightSideBearing);
+              table.writeShort(this.xMaxExtent);
+              table.writeShort(this.caretSlopeRise);
+              table.writeShort(this.caretSlopeRun);
+              table.writeShort(this.caretOffset);
+              for (i = _i = 0, _ref = 4 * 2; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
+                  table.writeByte(0);
+              }
+              table.writeShort(this.metricDataFormat);
+              table.writeUInt16(ids.length);
+              return table.data;
+          };*/
+          return HheaTable;
+      })(Table);
+
+      var OS2Table = (function (_super) {
+          __extends(OS2Table, _super);
+
+          function OS2Table() {
+              return OS2Table.__super__.constructor.apply(this, arguments);
+          }
+          OS2Table.prototype.tag = 'OS/2';
+          OS2Table.prototype.parse = function (data) {
+              var i;
+              data.pos = this.offset;
+              this.version = data.readUInt16();
+              this.averageCharWidth = data.readShort();
+              this.weightClass = data.readUInt16();
+              this.widthClass = data.readUInt16();
+              this.type = data.readShort();
+              this.ySubscriptXSize = data.readShort();
+              this.ySubscriptYSize = data.readShort();
+              this.ySubscriptXOffset = data.readShort();
+              this.ySubscriptYOffset = data.readShort();
+              this.ySuperscriptXSize = data.readShort();
+              this.ySuperscriptYSize = data.readShort();
+              this.ySuperscriptXOffset = data.readShort();
+              this.ySuperscriptYOffset = data.readShort();
+              this.yStrikeoutSize = data.readShort();
+              this.yStrikeoutPosition = data.readShort();
+              this.familyClass = data.readShort();
+              this.panose = (function () {
+                  var _i, _results;
+                  _results = [];
+                  for (i = _i = 0; _i < 10; i = ++_i) {
+                      _results.push(data.readByte());
+                  }
+                  return _results;
+              })();
+              this.charRange = (function () {
+                  var _i, _results;
+                  _results = [];
+                  for (i = _i = 0; _i < 4; i = ++_i) {
+                      _results.push(data.readInt());
+                  }
+                  return _results;
+              })();
+              this.vendorID = data.readString(4);
+              this.selection = data.readShort();
+              this.firstCharIndex = data.readShort();
+              this.lastCharIndex = data.readShort();
+              if (this.version > 0) {
+                  this.ascent = data.readShort();
+                  this.descent = data.readShort();
+                  this.lineGap = data.readShort();
+                  this.winAscent = data.readShort();
+                  this.winDescent = data.readShort();
+                  this.codePageRange = (function () {
+                      var _i, _results;
+                      _results = [];
+                      for (i = _i = 0; _i < 2; i = ++_i) {
+                          _results.push(data.readInt());
+                      }
+                      return _results;
+                  })();
+                  if (this.version > 1) {
+                      this.xHeight = data.readShort();
+                      this.capHeight = data.readShort();
+                      this.defaultChar = data.readShort();
+                      this.breakChar = data.readShort();
+                      return this.maxContext = data.readShort();
+                  }
+              }
+          };
+          /*OS2Table.prototype.encode = function () {
+              return this.raw();
+          };*/
+          return OS2Table;
+      })(Table);
+
+      var PostTable = (function (_super) {
+          __extends(PostTable, _super);
+
+          function PostTable() {
+              return PostTable.__super__.constructor.apply(this, arguments);
+          }
+          PostTable.prototype.tag = 'post';
+          PostTable.prototype.parse = function (data) {
+              var i, length, numberOfGlyphs, _i, _results;
+              data.pos = this.offset;
+              this.format = data.readInt();
+              this.italicAngle = data.readInt();
+              this.underlinePosition = data.readShort();
+              this.underlineThickness = data.readShort();
+              this.isFixedPitch = data.readInt();
+              this.minMemType42 = data.readInt();
+              this.maxMemType42 = data.readInt();
+              this.minMemType1 = data.readInt();
+              this.maxMemType1 = data.readInt();
+              switch (this.format) {
+              case 0x00010000:
+                  break;
+              case 0x00020000:
+                  numberOfGlyphs = data.readUInt16();
+                  this.glyphNameIndex = [];
+                  for (i = _i = 0; 0 <= numberOfGlyphs ? _i < numberOfGlyphs : _i > numberOfGlyphs; i = 0 <= numberOfGlyphs ? ++_i : --_i) {
+                      this.glyphNameIndex.push(data.readUInt16());
+                  }
+                  this.names = [];
+                  _results = [];
+                  while (data.pos < this.offset + this.length) {
+                      length = data.readByte();
+                      _results.push(this.names.push(data.readString(length)));
+                  }
+                  return _results;
+                  break;
+              case 0x00025000:
+                  numberOfGlyphs = data.readUInt16();
+                  return this.offsets = data.read(numberOfGlyphs);
+              case 0x00030000:
+                  break;
+              case 0x00040000:
+                  return this.map = (function () {
+                      var _j, _ref, _results1;
+                      _results1 = [];
+                      for (i = _j = 0, _ref = this.file.maxp.numGlyphs; 0 <= _ref ? _j < _ref : _j > _ref; i = 0 <= _ref ? ++_j : --_j) {
+                          _results1.push(data.readUInt32());
+                      }
+                      return _results1;
+                  }).call(this);
+              }
+          };
+          return PostTable;
+      })(Table);
+
+      /*********************************************************************************************************/
+      /* function : NameEntry                                                                                  */
+      /* comment : Store copyright information, platformID, encodingID, and languageID in the NameEntry object.*/
+      /*********************************************************************************************************/
+      var NameEntry = (function () {
+          function NameEntry(raw, entry) {
+              this.raw = raw;
+              this.length = raw.length;
+              this.platformID = entry.platformID;
+              this.encodingID = entry.encodingID;
+              this.languageID = entry.languageID;
+          }
+          return NameEntry;
+      })();
+
+      var NameTable = (function (_super) {
+          __extends(NameTable, _super);
+
+          function NameTable() {
+              return NameTable.__super__.constructor.apply(this, arguments);
+          }
+          NameTable.prototype.tag = 'name';
+          NameTable.prototype.parse = function (data) {
+              var count, entries, entry, format, i, name, stringOffset, strings, text, _i, _j, _len, _name;
+              data.pos = this.offset;
+              format = data.readShort();
+              count = data.readShort();
+              stringOffset = data.readShort();
+              entries = [];
+              for (i = _i = 0; 0 <= count ? _i < count : _i > count; i = 0 <= count ? ++_i : --_i) {
+                  entries.push({
+                      platformID: data.readShort()
+                      , encodingID: data.readShort()
+                      , languageID: data.readShort()
+                      , nameID: data.readShort()
+                      , length: data.readShort()
+                      , offset: this.offset + stringOffset + data.readShort()
+                  });
+              }
+              strings = {};
+              for (i = _j = 0, _len = entries.length; _j < _len; i = ++_j) {
+                  entry = entries[i];
+                  data.pos = entry.offset;
+                  text = data.readString(entry.length);
+                  name = new NameEntry(text, entry);
+                  if (strings[_name = entry.nameID] == null) {
+                      strings[_name] = [];
+                  }
+                  strings[entry.nameID].push(name);
+              }
+              this.strings = strings;
+              this.copyright = strings[0];
+              this.fontFamily = strings[1];
+              this.fontSubfamily = strings[2];
+              this.uniqueSubfamily = strings[3];
+              this.fontName = strings[4];
+              this.version = strings[5];
+              this.postscriptName = strings[6][0].raw.replace(/[\x00-\x19\x80-\xff]/g, "");
+              this.trademark = strings[7];
+              this.manufacturer = strings[8];
+              this.designer = strings[9];
+              this.description = strings[10];
+              this.vendorUrl = strings[11];
+              this.designerUrl = strings[12];
+              this.license = strings[13];
+              this.licenseUrl = strings[14];
+              this.preferredFamily = strings[15];
+              this.preferredSubfamily = strings[17];
+              this.compatibleFull = strings[18];
+              return this.sampleText = strings[19];
+          };
+          /*NameTable.prototype.encode = function () {
+              var id, list, nameID, nameTable, postscriptName, strCount, strTable, string, strings, table, val, _i, _len, _ref;
+              strings = {};
+              _ref = this.strings;
+              for (id in _ref) {
+                  val = _ref[id];
+                  strings[id] = val;
+              }
+              postscriptName = new NameEntry("" + subsetTag + "+" + this.postscriptName, {
+                  platformID: 1
+                  , encodingID: 0
+                  , languageID: 0
+              });
+              strings[6] = [postscriptName];
+              subsetTag = successorOf(subsetTag);
+              strCount = 0;
+              for (id in strings) {
+                  list = strings[id];
+                  if (list != null) {
+                      strCount += list.length;
+                  }
+              }
+              table = new Data;
+              strTable = new Data;
+              table.writeShort(0);
+              table.writeShort(strCount);
+              table.writeShort(6 + 12 * strCount);
+              for (nameID in strings) {
+                  list = strings[nameID];
+                  if (list != null) {
+                      for (_i = 0, _len = list.length; _i < _len; _i++) {
+                          string = list[_i];
+                          table.writeShort(string.platformID);
+                          table.writeShort(string.encodingID);
+                          table.writeShort(string.languageID);
+                          table.writeShort(nameID);
+                          table.writeShort(string.length);
+                          table.writeShort(strTable.pos);
+                          strTable.writeString(string.raw);
+                      }
+                  }
+              }
+              return nameTable = {
+                  postscriptName: postscriptName.raw
+                  , table: table.data.concat(strTable.data)
+              };
+          };*/
+          return NameTable;
+      })(Table);
+
+      var MaxpTable = (function (_super) {
+          __extends(MaxpTable, _super);
+
+          function MaxpTable() {
+              return MaxpTable.__super__.constructor.apply(this, arguments);
+          }
+          MaxpTable.prototype.tag = 'maxp';
+          MaxpTable.prototype.parse = function (data) {
+              data.pos = this.offset;
+              this.version = data.readInt();
+              this.numGlyphs = data.readUInt16();
+              this.maxPoints = data.readUInt16();
+              this.maxContours = data.readUInt16();
+              this.maxCompositePoints = data.readUInt16();
+              this.maxComponentContours = data.readUInt16();
+              this.maxZones = data.readUInt16();
+              this.maxTwilightPoints = data.readUInt16();
+              this.maxStorage = data.readUInt16();
+              this.maxFunctionDefs = data.readUInt16();
+              this.maxInstructionDefs = data.readUInt16();
+              this.maxStackElements = data.readUInt16();
+              this.maxSizeOfInstructions = data.readUInt16();
+              this.maxComponentElements = data.readUInt16();
+              return this.maxComponentDepth = data.readUInt16();
+          };
+          /*MaxpTable.prototype.encode = function (ids) {
+              var table;
+              table = new Data;
+              table.writeInt(this.version);
+              table.writeUInt16(ids.length);
+              table.writeUInt16(this.maxPoints);
+              table.writeUInt16(this.maxContours);
+              table.writeUInt16(this.maxCompositePoints);
+              table.writeUInt16(this.maxComponentContours);
+              table.writeUInt16(this.maxZones);
+              table.writeUInt16(this.maxTwilightPoints);
+              table.writeUInt16(this.maxStorage);
+              table.writeUInt16(this.maxFunctionDefs);
+              table.writeUInt16(this.maxInstructionDefs);
+              table.writeUInt16(this.maxStackElements);
+              table.writeUInt16(this.maxSizeOfInstructions);
+              table.writeUInt16(this.maxComponentElements);
+              table.writeUInt16(this.maxComponentDepth);
+              return table.data;
+          };*/
+          return MaxpTable;
+      })(Table);
+
+      var HmtxTable = (function (_super) {
+          __extends(HmtxTable, _super);
+
+          function HmtxTable() {
+              return HmtxTable.__super__.constructor.apply(this, arguments);
+          }
+          HmtxTable.prototype.tag = 'hmtx';
+          HmtxTable.prototype.parse = function (data) {
+              var i, last, lsbCount, m, _i, _j, _ref, _results;
+              data.pos = this.offset;
+              this.metrics = [];
+              for (i = _i = 0, _ref = this.file.hhea.numberOfMetrics; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
+                  this.metrics.push({
+                      advance: data.readUInt16()
+                      , lsb: data.readInt16()
+                  });
+              }
+              lsbCount = this.file.maxp.numGlyphs - this.file.hhea.numberOfMetrics;
+              this.leftSideBearings = (function () {
+                  var _j, _results;
+                  _results = [];
+                  for (i = _j = 0; 0 <= lsbCount ? _j < lsbCount : _j > lsbCount; i = 0 <= lsbCount ? ++_j : --_j) {
+                      _results.push(data.readInt16());
+                  }
+                  return _results;
+              })();
+              this.widths = (function () {
+                  var _j, _len, _ref1, _results;
+                  _ref1 = this.metrics;
+                  _results = [];
+                  for (_j = 0, _len = _ref1.length; _j < _len; _j++) {
+                      m = _ref1[_j];
+                      _results.push(m.advance);
+                  }
+                  return _results;
+              }).call(this);
+              last = this.widths[this.widths.length - 1];
+              _results = [];
+              for (i = _j = 0; 0 <= lsbCount ? _j < lsbCount : _j > lsbCount; i = 0 <= lsbCount ? ++_j : --_j) {
+                  _results.push(this.widths.push(last));
+              }
+              return _results;
+          };
+          /***************************************************************/
+          /* function : forGlyph                                         */
+          /* comment : Returns the advance width and lsb for this glyph. */
+          /***************************************************************/
+          HmtxTable.prototype.forGlyph = function (id) {
+              var metrics;
+              if (id in this.metrics) {
+                  return this.metrics[id];
+              }
+              return metrics = {
+                  advance: this.metrics[this.metrics.length - 1].advance
+                  , lsb: this.leftSideBearings[id - this.metrics.length]
+              };
+          };
+          /*HmtxTable.prototype.encode = function (mapping) {
+              var id, metric, table, _i, _len;
+              table = new Data;
+              for (_i = 0, _len = mapping.length; _i < _len; _i++) {
+                  id = mapping[_i];
+                  metric = this.forGlyph(id);
+                  table.writeUInt16(metric.advance);
+                  table.writeUInt16(metric.lsb);
+              }
+              return table.data;
+          };*/
+          return HmtxTable;
+      })(Table);
+
+      var __slice = [].slice;
+
+      var GlyfTable = (function (_super) {
+          __extends(GlyfTable, _super);
+
+          function GlyfTable() {
+              return GlyfTable.__super__.constructor.apply(this, arguments);
+          }
+          GlyfTable.prototype.tag = 'glyf';
+          GlyfTable.prototype.parse = function (data) {
+              return this.cache = {};
+          };
+          GlyfTable.prototype.glyphFor = function (id) {
+              id = id;
+              var data, index, length, loca, numberOfContours, raw, xMax, xMin, yMax, yMin;
+              if (id in this.cache) {
+                  return this.cache[id];
+              }
+              loca = this.file.loca;
+              data = this.file.contents;
+              index = loca.indexOf(id);
+              length = loca.lengthOf(id);
+              if (length === 0) {
+                  return this.cache[id] = null;
+              }
+              data.pos = this.offset + index;
+              raw = new Data(data.read(length));
+              numberOfContours = raw.readShort();
+              xMin = raw.readShort();
+              yMin = raw.readShort();
+              xMax = raw.readShort();
+              yMax = raw.readShort();
+              if (numberOfContours === -1) {
+                  this.cache[id] = new CompoundGlyph(raw, xMin, yMin, xMax, yMax);
+              }
+              else {
+                  this.cache[id] = new SimpleGlyph(raw, numberOfContours, xMin, yMin, xMax, yMax);
+              }
+              return this.cache[id];
+          };
+          GlyfTable.prototype.encode = function (glyphs, mapping, old2new) {
+              var glyph, id, offsets, table, _i, _len;
+              table = [];
+              offsets = [];
+              for (_i = 0, _len = mapping.length; _i < _len; _i++) {
+                  id = mapping[_i];
+                  glyph = glyphs[id];
+                  offsets.push(table.length);
+                  if (glyph) {
+                      table = table.concat(glyph.encode(old2new));
+                  }
+              }
+              offsets.push(table.length);
+              return {
+                  table: table
+                  , offsets: offsets
+              };
+          };
+          return GlyfTable;
+      })(Table);
+
+      var SimpleGlyph = (function () {
+          /**************************************************************************/
+          /* function : SimpleGlyph                                                 */
+          /* comment : Stores raw, xMin, yMin, xMax, and yMax values for this glyph.*/
+          /**************************************************************************/
+          function SimpleGlyph(raw, numberOfContours, xMin, yMin, xMax, yMax) {
+              this.raw = raw;
+              this.numberOfContours = numberOfContours;
+              this.xMin = xMin;
+              this.yMin = yMin;
+              this.xMax = xMax;
+              this.yMax = yMax;
+              this.compound = false;
+          }
+          SimpleGlyph.prototype.encode = function () {
+              return this.raw.data;
+          };
+          return SimpleGlyph;
+      })();
+
+      var CompoundGlyph = (function () {
+          var ARG_1_AND_2_ARE_WORDS, MORE_COMPONENTS, WE_HAVE_AN_X_AND_Y_SCALE, WE_HAVE_A_SCALE, WE_HAVE_A_TWO_BY_TWO;
+          ARG_1_AND_2_ARE_WORDS = 0x0001;
+          WE_HAVE_A_SCALE = 0x0008;
+          MORE_COMPONENTS = 0x0020;
+          WE_HAVE_AN_X_AND_Y_SCALE = 0x0040;
+          WE_HAVE_A_TWO_BY_TWO = 0x0080;
+
+          /********************************************************************************************************************/
+          /* function : CompoundGlypg generator                                                                               */
+          /* comment : It stores raw, xMin, yMin, xMax, yMax, glyph id, and glyph offset for the corresponding compound glyph.*/
+          /********************************************************************************************************************/
+          function CompoundGlyph(raw, xMin, yMin, xMax, yMax) {
+              var data, flags;
+              this.raw = raw;
+              this.xMin = xMin;
+              this.yMin = yMin;
+              this.xMax = xMax;
+              this.yMax = yMax;
+              this.compound = true;
+              this.glyphIDs = [];
+              this.glyphOffsets = [];
+              data = this.raw;
+              while (true) {
+                  flags = data.readShort();
+                  this.glyphOffsets.push(data.pos);
+                  this.glyphIDs.push(data.readShort());
+                  if (!(flags & MORE_COMPONENTS)) {
+                      break;
+                  }
+                  if (flags & ARG_1_AND_2_ARE_WORDS) {
+                      data.pos += 4;
+                  }
+                  else {
+                      data.pos += 2;
+                  }
+                  if (flags & WE_HAVE_A_TWO_BY_TWO) {
+                      data.pos += 8;
+                  }
+                  else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {
+                      data.pos += 4;
+                  }
+                  else if (flags & WE_HAVE_A_SCALE) {
+                      data.pos += 2;
+                  }
+              }
+          }
+          /****************************************************************************************************************/
+          /* function : CompoundGlypg encode                                                                              */
+          /* comment : After creating a table for the characters you typed, you call directory.encode to encode the table.*/
+          /****************************************************************************************************************/
+          CompoundGlyph.prototype.encode = function (mapping) {
+              var i, id, result, _i, _len, _ref;
+              result = new Data(__slice.call(this.raw.data));
+              _ref = this.glyphIDs;
+              for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
+                  id = _ref[i];
+                  result.pos = this.glyphOffsets[i];
+              }
+              return result.data;
+          };
+          return CompoundGlyph;
+      })();
+
+      var LocaTable = (function (_super) {
+          __extends(LocaTable, _super);
+
+          function LocaTable() {
+              return LocaTable.__super__.constructor.apply(this, arguments);
+          }
+          LocaTable.prototype.tag = 'loca';
+          LocaTable.prototype.parse = function (data) {
+              var format, i;
+              data.pos = this.offset;
+              format = this.file.head.indexToLocFormat;
+              if (format === 0) {
+                  return this.offsets = (function () {
+                      var _i, _ref, _results;
+                      _results = [];
+                      for (i = _i = 0, _ref = this.length; _i < _ref; i = _i += 2) {
+                          _results.push(data.readUInt16() * 2);
+                      }
+                      return _results;
+                  }).call(this);
+              }
+              else {
+                  return this.offsets = (function () {
+                      var _i, _ref, _results;
+                      _results = [];
+                      for (i = _i = 0, _ref = this.length; _i < _ref; i = _i += 4) {
+                          _results.push(data.readUInt32());
+                      }
+                      return _results;
+                  }).call(this);
+              }
+          };
+          LocaTable.prototype.indexOf = function (id) {
+              return this.offsets[id];
+          };
+          LocaTable.prototype.lengthOf = function (id) {
+              return this.offsets[id + 1] - this.offsets[id];
+          };
+          LocaTable.prototype.encode = function (offsets, activeGlyphs) {
+              var LocaTable = new Uint32Array(this.offsets.length);
+              var glyfPtr = 0;
+              var listGlyf = 0;
+              for (var k = 0; k < LocaTable.length; ++k) {
+                  LocaTable[k] = glyfPtr;
+                  if (listGlyf < activeGlyphs.length && activeGlyphs[listGlyf] == k) {
+                      ++listGlyf;
+                      LocaTable[k] = glyfPtr;
+                      var start = this.offsets[k];
+                      var len = this.offsets[k + 1] - start;
+                      if (len > 0) {
+                          glyfPtr += len;
+                      }
+                  }
+              }
+              var newLocaTable = new Array(LocaTable.length * 4);
+              for (var j = 0; j < LocaTable.length; ++j) {
+                  newLocaTable[4 * j + 3] = (LocaTable[j] & 0x000000ff);
+                  newLocaTable[4 * j + 2] = (LocaTable[j] & 0x0000ff00) >> 8;
+                  newLocaTable[4 * j + 1] = (LocaTable[j] & 0x00ff0000) >> 16;
+                  newLocaTable[4 * j] = (LocaTable[j] & 0xff000000) >> 24;
+              }
+              return newLocaTable;
+          };
+          return LocaTable;
+      })(Table);
+
+      /************************************************************************************/
+      /* function : invert                                                                */
+      /* comment : Change the object's (key: value) to create an object with (value: key).*/
+      /************************************************************************************/
+      var invert = function (object) {
+          var key, ret, val;
+          ret = {};
+          for (key in object) {
+              val = object[key];
+              ret[val] = key;
+          }
+          return ret;
+      };
+
+      /*var successorOf = function (input) {
+          var added, alphabet, carry, i, index, isUpperCase, last, length, next, result;
+          alphabet = 'abcdefghijklmnopqrstuvwxyz';
+          length = alphabet.length;
+          result = input;
+          i = input.length;
+          while (i >= 0) {
+              last = input.charAt(--i);
+              if (isNaN(last)) {
+                  index = alphabet.indexOf(last.toLowerCase());
+                  if (index === -1) {
+                      next = last;
+                      carry = true;
+                  }
+                  else {
+                      next = alphabet.charAt((index + 1) % length);
+                      isUpperCase = last === last.toUpperCase();
+                      if (isUpperCase) {
+                          next = next.toUpperCase();
+                      }
+                      carry = index + 1 >= length;
+                      if (carry && i === 0) {
+                          added = isUpperCase ? 'A' : 'a';
+                          result = added + next + result.slice(1);
+                          break;
+                      }
+                  }
+              }
+              else {
+                  next = +last + 1;
+                  carry = next > 9;
+                  if (carry) {
+                      next = 0;
+                  }
+                  if (carry && i === 0) {
+                      result = '1' + next + result.slice(1);
+                      break;
+                  }
+              }
+              result = result.slice(0, i) + next + result.slice(i + 1);
+              if (!carry) {
+                  break;
+              }
+          }
+          return result;
+      };*/
+
+      var Subset = (function () {
+          function Subset(font) {
+              this.font = font;
+              this.subset = {};
+              this.unicodes = {};
+              this.next = 33;
+          }
+          /*Subset.prototype.use = function (character) {
+              var i, _i, _ref;
+              if (typeof character === 'string') {
+                  for (i = _i = 0, _ref = character.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
+                      this.use(character.charCodeAt(i));
+                  }
+                  return;
+              }
+              if (!this.unicodes[character]) {
+                  this.subset[this.next] = character;
+                  return this.unicodes[character] = this.next++;
+              }
+          };*/
+          /*Subset.prototype.encodeText = function (text) {
+              var char, i, string, _i, _ref;
+              string = '';
+              for (i = _i = 0, _ref = text.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
+                  char = this.unicodes[text.charCodeAt(i)];
+                  string += String.fromCharCode(char);
+              }
+              return string;
+          };*/
+          /***************************************************************/
+          /* function : generateCmap                                     */
+          /* comment : Returns the unicode cmap for this font.         */
+          /***************************************************************/
+          Subset.prototype.generateCmap = function () {
+              var mapping, roman, unicode, unicodeCmap, _ref;
+              unicodeCmap = this.font.cmap.tables[0].codeMap;
+              mapping = {};
+              _ref = this.subset;
+              for (roman in _ref) {
+                  unicode = _ref[roman];
+                  mapping[roman] = unicodeCmap[unicode];
+              }
+              return mapping;
+          };
+          /*Subset.prototype.glyphIDs = function () {
+              var ret, roman, unicode, unicodeCmap, val, _ref;
+              unicodeCmap = this.font.cmap.tables[0].codeMap;
+              ret = [0];
+              _ref = this.subset;
+              for (roman in _ref) {
+                  unicode = _ref[roman];
+                  val = unicodeCmap[unicode];
+                  if ((val != null) && __indexOf.call(ret, val) < 0) {
+                      ret.push(val);
+                  }
+              }
+              return ret.sort();
+          };*/
+          /******************************************************************/
+          /* function : glyphsFor                                           */
+          /* comment : Returns simple glyph objects for the input character.*/
+          /******************************************************************/
+          Subset.prototype.glyphsFor = function (glyphIDs) {
+              var additionalIDs, glyph, glyphs, id, _i, _len, _ref;
+              glyphs = {};
+              for (_i = 0, _len = glyphIDs.length; _i < _len; _i++) {
+                  id = glyphIDs[_i];
+                  glyphs[id] = this.font.glyf.glyphFor(id);
+              }
+              additionalIDs = [];
+              for (id in glyphs) {
+                  glyph = glyphs[id];
+                  if (glyph != null ? glyph.compound : void 0) {
+                      additionalIDs.push.apply(additionalIDs, glyph.glyphIDs);
+                  }
+              }
+              if (additionalIDs.length > 0) {
+                  _ref = this.glyphsFor(additionalIDs);
+                  for (id in _ref) {
+                      glyph = _ref[id];
+                      glyphs[id] = glyph;
+                  }
+              }
+              return glyphs;
+          };
+          /***************************************************************/
+          /* function : encode                                           */
+          /* comment : Encode various tables for the characters you use. */
+          /***************************************************************/
+          Subset.prototype.encode = function (glyID) {
+              var cmap, code, glyf, glyphs, id, ids, loca, new2old, newIDs, nextGlyphID, old2new, oldID, oldIDs, tables, _ref;
+              cmap = CmapTable.encode(this.generateCmap(), 'unicode');
+              glyphs = this.glyphsFor(glyID);
+              old2new = {
+                  0: 0
+              };
+              _ref = cmap.charMap;
+              for (code in _ref) {
+                  ids = _ref[code];
+                  old2new[ids.old] = ids["new"];
+              }
+              nextGlyphID = cmap.maxGlyphID;
+              for (oldID in glyphs) {
+                  if (!(oldID in old2new)) {
+                      old2new[oldID] = nextGlyphID++;
+                  }
+              }
+              new2old = invert(old2new);
+              newIDs = Object.keys(new2old).sort(function (a, b) {
+                  return a - b;
+              });
+              oldIDs = (function () {
+                  var _i, _len, _results;
+                  _results = [];
+                  for (_i = 0, _len = newIDs.length; _i < _len; _i++) {
+                      id = newIDs[_i];
+                      _results.push(new2old[id]);
+                  }
+                  return _results;
+              })();
+              glyf = this.font.glyf.encode(glyphs, oldIDs, old2new);
+              loca = this.font.loca.encode(glyf.offsets, oldIDs);
+              tables = {
+                  cmap: this.font.cmap.raw()
+                  , glyf: glyf.table
+                  , loca: loca
+                  , hmtx: this.font.hmtx.raw()
+                  , hhea: this.font.hhea.raw()
+                  , maxp: this.font.maxp.raw()
+                  , post: this.font.post.raw()
+                  , name: this.font.name.raw()
+                  , head: this.font.head.raw()
+              };
+              if (this.font.os2.exists) {
+                  tables['OS/2'] = this.font.os2.raw();
+              }
+              return this.font.directory.encode(tables);
+          };
+          return Subset;
+      })();
+
+      jsPDF.API.PDFObject = (function () {
+          var pad;
+
+          function PDFObject() {}
+          pad = function (str, length) {
+              return (Array(length + 1).join('0') + str).slice(-length);
+          };
+          /*****************************************************************************/
+          /* function : convert                                                        */
+          /* comment :Converts pdf tag's / FontBBox and array values in / W to strings */
+          /*****************************************************************************/
+          PDFObject.convert = function (object) {
+              var e, items, key, out, val;
+              if (Array.isArray(object)) {
+                  items = ((function () {
+                      var _i, _len, _results;
+                      _results = [];
+                      for (_i = 0, _len = object.length; _i < _len; _i++) {
+                          e = object[_i];
+                          _results.push(PDFObject.convert(e));
+                      }
+                      return _results;
+                  })()).join(' ');
+                  return '[' + items + ']';
+              }
+              else if (typeof object === 'string') {
+                  return '/' + object;
+              }
+              else if (object != null ? object.isString : void 0) {
+                  return '(' + object + ')';
+              }
+              else if (object instanceof Date) {
+                  return '(D:' + pad(object.getUTCFullYear(), 4) + pad(object.getUTCMonth(), 2) + pad(object.getUTCDate(), 2) + pad(object.getUTCHours(), 2) + pad(object.getUTCMinutes(), 2) + pad(object.getUTCSeconds(), 2) + 'Z)';
+              }
+              else if ({}.toString.call(object) === '[object Object]') {
+                  out = ['<<'];
+                  for (key in object) {
+                      val = object[key];
+                      out.push('/' + key + ' ' + PDFObject.convert(val));
+                  }
+                  out.push('>>');
+                  return out.join('\n');
+              }
+              else {
+                  return '' + object;
+              }
+          };
+          return PDFObject;
+      })();
+  })(jsPDF);
+
+  // Generated by CoffeeScript 1.4.0
+
+  /*
+  # PNG.js
+  # Copyright (c) 2011 Devon Govett
+  # MIT LICENSE
+  # 
+  # 
+  */
+
+
+  (function(global) {
+    var PNG;
+
+    PNG = (function() {
+      var APNG_BLEND_OP_SOURCE, APNG_DISPOSE_OP_BACKGROUND, APNG_DISPOSE_OP_PREVIOUS, makeImage, scratchCanvas, scratchCtx;
+
+      PNG.load = function(url, canvas, callback) {
+        var xhr;
+        if (typeof canvas === 'function') {
+          callback = canvas;
+        }
+        xhr = new XMLHttpRequest;
+        xhr.open("GET", url, true);
+        xhr.responseType = "arraybuffer";
+        xhr.onload = function() {
+          var data, png;
+          data = new Uint8Array(xhr.response || xhr.mozResponseArrayBuffer);
+          png = new PNG(data);
+          if (typeof (canvas != null ? canvas.getContext : void 0) === 'function') {
+            png.render(canvas);
+          }
+          return typeof callback === "function" ? callback(png) : void 0;
+        };
+        return xhr.send(null);
+      };
+
+      APNG_DISPOSE_OP_BACKGROUND = 1;
+
+      APNG_DISPOSE_OP_PREVIOUS = 2;
+
+      APNG_BLEND_OP_SOURCE = 0;
+
+      function PNG(data) {
+        var chunkSize, colors, palLen, delayDen, delayNum, frame, i, index, key, section, palShort, text, _i, _j, _ref;
+        this.data = data;
+        this.pos = 8;
+        this.palette = [];
+        this.imgData = [];
+        this.transparency = {};
+        this.animation = null;
+        this.text = {};
+        frame = null;
+        while (true) {
+          chunkSize = this.readUInt32();
+          section = ((function() {
+            var _i, _results;
+            _results = [];
+            for (i = _i = 0; _i < 4; i = ++_i) {
+              _results.push(String.fromCharCode(this.data[this.pos++]));
+            }
+            return _results;
+          }).call(this)).join('');
+          switch (section) {
+            case 'IHDR':
+              this.width = this.readUInt32();
+              this.height = this.readUInt32();
+              this.bits = this.data[this.pos++];
+              this.colorType = this.data[this.pos++];
+              this.compressionMethod = this.data[this.pos++];
+              this.filterMethod = this.data[this.pos++];
+              this.interlaceMethod = this.data[this.pos++];
+              break;
+            case 'acTL':
+              this.animation = {
+                numFrames: this.readUInt32(),
+                numPlays: this.readUInt32() || Infinity,
+                frames: []
+              };
+              break;
+            case 'PLTE':
+              this.palette = this.read(chunkSize);
+              break;
+            case 'fcTL':
+              if (frame) {
+                this.animation.frames.push(frame);
+              }
+              this.pos += 4;
+              frame = {
+                width: this.readUInt32(),
+                height: this.readUInt32(),
+                xOffset: this.readUInt32(),
+                yOffset: this.readUInt32()
+              };
+              delayNum = this.readUInt16();
+              delayDen = this.readUInt16() || 100;
+              frame.delay = 1000 * delayNum / delayDen;
+              frame.disposeOp = this.data[this.pos++];
+              frame.blendOp = this.data[this.pos++];
+              frame.data = [];
+              break;
+            case 'IDAT':
+            case 'fdAT':
+              if (section === 'fdAT') {
+                this.pos += 4;
+                chunkSize -= 4;
+              }
+              data = (frame != null ? frame.data : void 0) || this.imgData;
+              for (i = _i = 0; 0 <= chunkSize ? _i < chunkSize : _i > chunkSize; i = 0 <= chunkSize ? ++_i : --_i) {
+                data.push(this.data[this.pos++]);
+              }
+              break;
+            case 'tRNS':
+              this.transparency = {};
+              switch (this.colorType) {
+                case 3:
+              	palLen = this.palette.length/3;
+                  this.transparency.indexed = this.read(chunkSize);
+                  if(this.transparency.indexed.length > palLen)
+                  	throw new Error('More transparent colors than palette size');
+                  /*
+                   * According to the PNG spec trns should be increased to the same size as palette if shorter
+                   */
+                  //palShort = 255 - this.transparency.indexed.length;
+                  palShort = palLen - this.transparency.indexed.length;
+                  if (palShort > 0) {
+                    for (i = _j = 0; 0 <= palShort ? _j < palShort : _j > palShort; i = 0 <= palShort ? ++_j : --_j) {
+                      this.transparency.indexed.push(255);
+                    }
+                  }
+                  break;
+                case 0:
+                  this.transparency.grayscale = this.read(chunkSize)[0];
+                  break;
+                case 2:
+                  this.transparency.rgb = this.read(chunkSize);
+              }
+              break;
+            case 'tEXt':
+              text = this.read(chunkSize);
+              index = text.indexOf(0);
+              key = String.fromCharCode.apply(String, text.slice(0, index));
+              this.text[key] = String.fromCharCode.apply(String, text.slice(index + 1));
+              break;
+            case 'IEND':
+              if (frame) {
+                this.animation.frames.push(frame);
+              }
+              this.colors = (function() {
+                switch (this.colorType) {
+                  case 0:
+                  case 3:
+                  case 4:
+                    return 1;
+                  case 2:
+                  case 6:
+                    return 3;
+                }
+              }).call(this);
+              this.hasAlphaChannel = (_ref = this.colorType) === 4 || _ref === 6;
+              colors = this.colors + (this.hasAlphaChannel ? 1 : 0);
+              this.pixelBitlength = this.bits * colors;
+              this.colorSpace = (function() {
+                switch (this.colors) {
+                  case 1:
+                    return 'DeviceGray';
+                  case 3:
+                    return 'DeviceRGB';
+                }
+              }).call(this);
+              this.imgData = new Uint8Array(this.imgData);
+              return;
+            default:
+              this.pos += chunkSize;
+          }
+          this.pos += 4;
+          if (this.pos > this.data.length) {
+            throw new Error("Incomplete or corrupt PNG file");
+          }
+        }
+        return;
+      }
+
+      PNG.prototype.read = function(bytes) {
+        var i, _i, _results;
+        _results = [];
+        for (i = _i = 0; 0 <= bytes ? _i < bytes : _i > bytes; i = 0 <= bytes ? ++_i : --_i) {
+          _results.push(this.data[this.pos++]);
+        }
+        return _results;
+      };
+
+      PNG.prototype.readUInt32 = function() {
+        var b1, b2, b3, b4;
+        b1 = this.data[this.pos++] << 24;
+        b2 = this.data[this.pos++] << 16;
+        b3 = this.data[this.pos++] << 8;
+        b4 = this.data[this.pos++];
+        return b1 | b2 | b3 | b4;
+      };
+
+      PNG.prototype.readUInt16 = function() {
+        var b1, b2;
+        b1 = this.data[this.pos++] << 8;
+        b2 = this.data[this.pos++];
+        return b1 | b2;
+      };
+
+
+      PNG.prototype.decodePixels = function(data) {
+        var pixelBytes = this.pixelBitlength / 8;
+        var fullPixels = new Uint8Array(this.width * this.height * pixelBytes);
+        var pos = 0;
+        var _this = this;
+        
+        if (data == null) {
+            data = this.imgData;
+        }
+        if (data.length === 0) {
+            return new Uint8Array(0);
+        }
+        
+        data = new FlateStream(data);
+        data = data.getBytes();
+        function pass (x0, y0, dx, dy) {
+            var abyte, c, col, i, left, length, p, pa, paeth, pb, pc, pixels, row, scanlineLength, upper, upperLeft, _i, _j, _k, _l, _m;
+            var w = Math.ceil((_this.width - x0) / dx), h = Math.ceil((_this.height - y0) / dy);
+            var isFull = _this.width == w && _this.height == h;
+            scanlineLength = pixelBytes * w;
+            pixels = isFull ? fullPixels : new Uint8Array(scanlineLength * h);
+            length = data.length;
+            row = 0;
+            c = 0;
+            while (row < h && pos < length) {
+              switch (data[pos++]) {
+                case 0:
+                  for (i = _i = 0; _i < scanlineLength; i = _i += 1) {
+                    pixels[c++] = data[pos++];
+                  }
+                  break;
+                case 1:
+                  for (i = _j = 0; _j < scanlineLength; i = _j += 1) {
+                    abyte = data[pos++];
+                    left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
+                    pixels[c++] = (abyte + left) % 256;
+                  }
+                  break;
+                case 2:
+                  for (i = _k = 0; _k < scanlineLength; i = _k += 1) {
+                    abyte = data[pos++];
+                    col = (i - (i % pixelBytes)) / pixelBytes;
+                    upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
+                    pixels[c++] = (upper + abyte) % 256;
+                  }
+                  break;
+                case 3:
+                  for (i = _l = 0; _l < scanlineLength; i = _l += 1) {
+                    abyte = data[pos++];
+                    col = (i - (i % pixelBytes)) / pixelBytes;
+                    left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
+                    upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
+                    pixels[c++] = (abyte + Math.floor((left + upper) / 2)) % 256;
+                  }
+                  break;
+                case 4:
+                  for (i = _m = 0; _m < scanlineLength; i = _m += 1) {
+                    abyte = data[pos++];
+                    col = (i - (i % pixelBytes)) / pixelBytes;
+                    left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
+                    if (row === 0) {
+                      upper = upperLeft = 0;
+                    } else {
+                      upper = pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
+                      upperLeft = col && pixels[(row - 1) * scanlineLength + (col - 1) * pixelBytes + (i % pixelBytes)];
+                    }
+                    p = left + upper - upperLeft;
+                    pa = Math.abs(p - left);
+                    pb = Math.abs(p - upper);
+                    pc = Math.abs(p - upperLeft);
+                    if (pa <= pb && pa <= pc) {
+                      paeth = left;
+                    } else if (pb <= pc) {
+                      paeth = upper;
+                    } else {
+                      paeth = upperLeft;
+                    }
+                    pixels[c++] = (abyte + paeth) % 256;
+                  }
+                  break;
+                default:
+                  throw new Error("Invalid filter algorithm: " + data[pos - 1]);
+              }
+              if (!isFull) {
+                  var fullPos = ((y0 + row * dy) * _this.width + x0) * pixelBytes;
+                  var partPos = row * scanlineLength;
+                  for (i = 0; i < w; i += 1) {
+                    for (var j = 0; j < pixelBytes; j += 1)
+                      fullPixels[fullPos++] = pixels[partPos++];
+                    fullPos += (dx - 1) * pixelBytes;
+                  }
+                }
+              row++;
+            }
+        }
+        if (_this.interlaceMethod == 1) {
+            /*
+              1 6 4 6 2 6 4 6
+              7 7 7 7 7 7 7 7
+              5 6 5 6 5 6 5 6
+              7 7 7 7 7 7 7 7
+              3 6 4 6 3 6 4 6
+              7 7 7 7 7 7 7 7
+              5 6 5 6 5 6 5 6
+              7 7 7 7 7 7 7 7
+            */
+            pass(0, 0, 8, 8); // 1
+            /* NOTE these seem to follow the pattern:
+             * pass(x, 0, 2*x, 2*x);
+             * pass(0, x,   x, 2*x);
+             * with x being 4, 2, 1.
+             */
+            pass(4, 0, 8, 8); // 2
+            pass(0, 4, 4, 8); // 3
+
+            pass(2, 0, 4, 4); // 4
+            pass(0, 2, 2, 4); // 5
+
+            pass(1, 0, 2, 2); // 6
+            pass(0, 1, 1, 2); // 7
+          } else {
+            pass(0, 0, 1, 1);
+          }
+        return fullPixels;
+      };
+
+      PNG.prototype.decodePalette = function() {
+        var c, i, length, palette, pos, ret, transparency, _i, _ref, _ref1;
+        palette = this.palette;
+        transparency = this.transparency.indexed || [];
+        ret = new Uint8Array((transparency.length || 0) + palette.length);
+        pos = 0;
+        length = palette.length;
+        c = 0;
+        for (i = _i = 0, _ref = palette.length; _i < _ref; i = _i += 3) {
+          ret[pos++] = palette[i];
+          ret[pos++] = palette[i + 1];
+          ret[pos++] = palette[i + 2];
+          ret[pos++] = (_ref1 = transparency[c++]) != null ? _ref1 : 255;
+        }
+        return ret;
+      };
+
+      PNG.prototype.copyToImageData = function(imageData, pixels) {
+        var alpha, colors, data, i, input, j, k, length, palette, v, _ref;
+        colors = this.colors;
+        palette = null;
+        alpha = this.hasAlphaChannel;
+        if (this.palette.length) {
+          palette = (_ref = this._decodedPalette) != null ? _ref : this._decodedPalette = this.decodePalette();
+          colors = 4;
+          alpha = true;
+        }
+        data = imageData.data || imageData;
+        length = data.length;
+        input = palette || pixels;
+        i = j = 0;
+        if (colors === 1) {
+          while (i < length) {
+            k = palette ? pixels[i / 4] * 4 : j;
+            v = input[k++];
+            data[i++] = v;
+            data[i++] = v;
+            data[i++] = v;
+            data[i++] = alpha ? input[k++] : 255;
+            j = k;
+          }
+        } else {
+          while (i < length) {
+            k = palette ? pixels[i / 4] * 4 : j;
+            data[i++] = input[k++];
+            data[i++] = input[k++];
+            data[i++] = input[k++];
+            data[i++] = alpha ? input[k++] : 255;
+            j = k;
+          }
+        }
+      };
+
+      PNG.prototype.decode = function() {
+        var ret;
+        ret = new Uint8Array(this.width * this.height * 4);
+        this.copyToImageData(ret, this.decodePixels());
+        return ret;
+      };
+
+      try {
+          scratchCanvas = global.document.createElement('canvas');
+          scratchCtx = scratchCanvas.getContext('2d');
+      } catch(e) {
+          return -1;
+      }
+
+      makeImage = function(imageData) {
+        var img;
+        scratchCtx.width = imageData.width;
+        scratchCtx.height = imageData.height;
+        scratchCtx.clearRect(0, 0, imageData.width, imageData.height);
+        scratchCtx.putImageData(imageData, 0, 0);
+        img = new Image;
+        img.src = scratchCanvas.toDataURL();
+        return img;
+      };
+
+      PNG.prototype.decodeFrames = function(ctx) {
+        var frame, i, imageData, pixels, _i, _len, _ref, _results;
+        if (!this.animation) {
+          return;
+        }
+        _ref = this.animation.frames;
+        _results = [];
+        for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
+          frame = _ref[i];
+          imageData = ctx.createImageData(frame.width, frame.height);
+          pixels = this.decodePixels(new Uint8Array(frame.data));
+          this.copyToImageData(imageData, pixels);
+          frame.imageData = imageData;
+          _results.push(frame.image = makeImage(imageData));
+        }
+        return _results;
+      };
+
+      PNG.prototype.renderFrame = function(ctx, number) {
+        var frame, frames, prev;
+        frames = this.animation.frames;
+        frame = frames[number];
+        prev = frames[number - 1];
+        if (number === 0) {
+          ctx.clearRect(0, 0, this.width, this.height);
+        }
+        if ((prev != null ? prev.disposeOp : void 0) === APNG_DISPOSE_OP_BACKGROUND) {
+          ctx.clearRect(prev.xOffset, prev.yOffset, prev.width, prev.height);
+        } else if ((prev != null ? prev.disposeOp : void 0) === APNG_DISPOSE_OP_PREVIOUS) {
+          ctx.putImageData(prev.imageData, prev.xOffset, prev.yOffset);
+        }
+        if (frame.blendOp === APNG_BLEND_OP_SOURCE) {
+          ctx.clearRect(frame.xOffset, frame.yOffset, frame.width, frame.height);
+        }
+        return ctx.drawImage(frame.image, frame.xOffset, frame.yOffset);
+      };
+
+      PNG.prototype.animate = function(ctx) {
+        var doFrame, frameNumber, frames, numFrames, numPlays, _ref,
+          _this = this;
+        frameNumber = 0;
+        _ref = this.animation, numFrames = _ref.numFrames, frames = _ref.frames, numPlays = _ref.numPlays;
+        return (doFrame = function() {
+          var f, frame;
+          f = frameNumber++ % numFrames;
+          frame = frames[f];
+          _this.renderFrame(ctx, f);
+          if (numFrames > 1 && frameNumber / numFrames < numPlays) {
+            return _this.animation._timeout = setTimeout(doFrame, frame.delay);
+          }
+        })();
+      };
+
+      PNG.prototype.stopAnimation = function() {
+        var _ref;
+        return clearTimeout((_ref = this.animation) != null ? _ref._timeout : void 0);
+      };
+
+      PNG.prototype.render = function(canvas) {
+        var ctx, data;
+        if (canvas._png) {
+          canvas._png.stopAnimation();
+        }
+        canvas._png = this;
+        canvas.width = this.width;
+        canvas.height = this.height;
+        ctx = canvas.getContext("2d");
+        if (this.animation) {
+          this.decodeFrames(ctx);
+          return this.animate(ctx);
+        } else {
+          data = ctx.createImageData(this.width, this.height);
+          this.copyToImageData(data, this.decodePixels());
+          return ctx.putImageData(data, 0, 0);
+        }
+      };
+
+      return PNG;
+
+    })();
+
+    global.PNG = PNG;
+
+  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || typeof global !== "undefined" && global ||  Function('return typeof this === "object" && this.content')() || Function('return this')()));
+  // `self` is undefined in Firefox for Android content script context
+  // while `this` is nsIContentFrameMessageManager
+  // with an attribute `content` that corresponds to the window
+
+  /*
+   * Extracted from pdf.js
+   * https://github.com/andreasgal/pdf.js
+   *
+   * Copyright (c) 2011 Mozilla Foundation
+   *
+   * Contributors: Andreas Gal <gal@mozilla.com>
+   *               Chris G Jones <cjones@mozilla.com>
+   *               Shaon Barman <shaon.barman@gmail.com>
+   *               Vivien Nicolas <21@vingtetun.org>
+   *               Justin D'Arcangelo <justindarc@gmail.com>
+   *               Yury Delendik
+   *
+   * 
+   */
+
+  var DecodeStream = (function() {
+    function constructor() {
+      this.pos = 0;
+      this.bufferLength = 0;
+      this.eof = false;
+      this.buffer = null;
+    }
+
+    constructor.prototype = {
+      ensureBuffer: function decodestream_ensureBuffer(requested) {
+        var buffer = this.buffer;
+        var current = buffer ? buffer.byteLength : 0;
+        if (requested < current)
+          return buffer;
+        var size = 512;
+        while (size < requested)
+          size <<= 1;
+        var buffer2 = new Uint8Array(size);
+        for (var i = 0; i < current; ++i)
+          buffer2[i] = buffer[i];
+        return this.buffer = buffer2;
+      },
+      getByte: function decodestream_getByte() {
+        var pos = this.pos;
+        while (this.bufferLength <= pos) {
+          if (this.eof)
+            return null;
+          this.readBlock();
+        }
+        return this.buffer[this.pos++];
+      },
+      getBytes: function decodestream_getBytes(length) {
+        var pos = this.pos;
+
+        if (length) {
+          this.ensureBuffer(pos + length);
+          var end = pos + length;
+
+          while (!this.eof && this.bufferLength < end)
+            this.readBlock();
+
+          var bufEnd = this.bufferLength;
+          if (end > bufEnd)
+            end = bufEnd;
+        } else {
+          while (!this.eof)
+            this.readBlock();
+
+          var end = this.bufferLength;
+        }
+
+        this.pos = end;
+        return this.buffer.subarray(pos, end);
+      },
+      lookChar: function decodestream_lookChar() {
+        var pos = this.pos;
+        while (this.bufferLength <= pos) {
+          if (this.eof)
+            return null;
+          this.readBlock();
+        }
+        return String.fromCharCode(this.buffer[this.pos]);
+      },
+      getChar: function decodestream_getChar() {
+        var pos = this.pos;
+        while (this.bufferLength <= pos) {
+          if (this.eof)
+            return null;
+          this.readBlock();
+        }
+        return String.fromCharCode(this.buffer[this.pos++]);
+      },
+      makeSubStream: function decodestream_makeSubstream(start, length, dict) {
+        var end = start + length;
+        while (this.bufferLength <= end && !this.eof)
+          this.readBlock();
+        return new Stream(this.buffer, start, length, dict);
+      },
+      skip: function decodestream_skip(n) {
+        if (!n)
+          n = 1;
+        this.pos += n;
+      },
+      reset: function decodestream_reset() {
+        this.pos = 0;
+      }
+    };
+
+    return constructor;
+  })();
+
+  var FlateStream = (function() {
+    if (typeof Uint32Array === 'undefined') {
+      return undefined;
+    }
+    var codeLenCodeMap = new Uint32Array([
+      16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
+    ]);
+
+    var lengthDecode = new Uint32Array([
+      0x00003, 0x00004, 0x00005, 0x00006, 0x00007, 0x00008, 0x00009, 0x0000a,
+      0x1000b, 0x1000d, 0x1000f, 0x10011, 0x20013, 0x20017, 0x2001b, 0x2001f,
+      0x30023, 0x3002b, 0x30033, 0x3003b, 0x40043, 0x40053, 0x40063, 0x40073,
+      0x50083, 0x500a3, 0x500c3, 0x500e3, 0x00102, 0x00102, 0x00102
+    ]);
+
+    var distDecode = new Uint32Array([
+      0x00001, 0x00002, 0x00003, 0x00004, 0x10005, 0x10007, 0x20009, 0x2000d,
+      0x30011, 0x30019, 0x40021, 0x40031, 0x50041, 0x50061, 0x60081, 0x600c1,
+      0x70101, 0x70181, 0x80201, 0x80301, 0x90401, 0x90601, 0xa0801, 0xa0c01,
+      0xb1001, 0xb1801, 0xc2001, 0xc3001, 0xd4001, 0xd6001
+    ]);
+
+    var fixedLitCodeTab = [new Uint32Array([
+      0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c0,
+      0x70108, 0x80060, 0x80020, 0x900a0, 0x80000, 0x80080, 0x80040, 0x900e0,
+      0x70104, 0x80058, 0x80018, 0x90090, 0x70114, 0x80078, 0x80038, 0x900d0,
+      0x7010c, 0x80068, 0x80028, 0x900b0, 0x80008, 0x80088, 0x80048, 0x900f0,
+      0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c8,
+      0x7010a, 0x80064, 0x80024, 0x900a8, 0x80004, 0x80084, 0x80044, 0x900e8,
+      0x70106, 0x8005c, 0x8001c, 0x90098, 0x70116, 0x8007c, 0x8003c, 0x900d8,
+      0x7010e, 0x8006c, 0x8002c, 0x900b8, 0x8000c, 0x8008c, 0x8004c, 0x900f8,
+      0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c4,
+      0x70109, 0x80062, 0x80022, 0x900a4, 0x80002, 0x80082, 0x80042, 0x900e4,
+      0x70105, 0x8005a, 0x8001a, 0x90094, 0x70115, 0x8007a, 0x8003a, 0x900d4,
+      0x7010d, 0x8006a, 0x8002a, 0x900b4, 0x8000a, 0x8008a, 0x8004a, 0x900f4,
+      0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cc,
+      0x7010b, 0x80066, 0x80026, 0x900ac, 0x80006, 0x80086, 0x80046, 0x900ec,
+      0x70107, 0x8005e, 0x8001e, 0x9009c, 0x70117, 0x8007e, 0x8003e, 0x900dc,
+      0x7010f, 0x8006e, 0x8002e, 0x900bc, 0x8000e, 0x8008e, 0x8004e, 0x900fc,
+      0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c2,
+      0x70108, 0x80061, 0x80021, 0x900a2, 0x80001, 0x80081, 0x80041, 0x900e2,
+      0x70104, 0x80059, 0x80019, 0x90092, 0x70114, 0x80079, 0x80039, 0x900d2,
+      0x7010c, 0x80069, 0x80029, 0x900b2, 0x80009, 0x80089, 0x80049, 0x900f2,
+      0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900ca,
+      0x7010a, 0x80065, 0x80025, 0x900aa, 0x80005, 0x80085, 0x80045, 0x900ea,
+      0x70106, 0x8005d, 0x8001d, 0x9009a, 0x70116, 0x8007d, 0x8003d, 0x900da,
+      0x7010e, 0x8006d, 0x8002d, 0x900ba, 0x8000d, 0x8008d, 0x8004d, 0x900fa,
+      0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c6,
+      0x70109, 0x80063, 0x80023, 0x900a6, 0x80003, 0x80083, 0x80043, 0x900e6,
+      0x70105, 0x8005b, 0x8001b, 0x90096, 0x70115, 0x8007b, 0x8003b, 0x900d6,
+      0x7010d, 0x8006b, 0x8002b, 0x900b6, 0x8000b, 0x8008b, 0x8004b, 0x900f6,
+      0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900ce,
+      0x7010b, 0x80067, 0x80027, 0x900ae, 0x80007, 0x80087, 0x80047, 0x900ee,
+      0x70107, 0x8005f, 0x8001f, 0x9009e, 0x70117, 0x8007f, 0x8003f, 0x900de,
+      0x7010f, 0x8006f, 0x8002f, 0x900be, 0x8000f, 0x8008f, 0x8004f, 0x900fe,
+      0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c1,
+      0x70108, 0x80060, 0x80020, 0x900a1, 0x80000, 0x80080, 0x80040, 0x900e1,
+      0x70104, 0x80058, 0x80018, 0x90091, 0x70114, 0x80078, 0x80038, 0x900d1,
+      0x7010c, 0x80068, 0x80028, 0x900b1, 0x80008, 0x80088, 0x80048, 0x900f1,
+      0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c9,
+      0x7010a, 0x80064, 0x80024, 0x900a9, 0x80004, 0x80084, 0x80044, 0x900e9,
+      0x70106, 0x8005c, 0x8001c, 0x90099, 0x70116, 0x8007c, 0x8003c, 0x900d9,
+      0x7010e, 0x8006c, 0x8002c, 0x900b9, 0x8000c, 0x8008c, 0x8004c, 0x900f9,
+      0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c5,
+      0x70109, 0x80062, 0x80022, 0x900a5, 0x80002, 0x80082, 0x80042, 0x900e5,
+      0x70105, 0x8005a, 0x8001a, 0x90095, 0x70115, 0x8007a, 0x8003a, 0x900d5,
+      0x7010d, 0x8006a, 0x8002a, 0x900b5, 0x8000a, 0x8008a, 0x8004a, 0x900f5,
+      0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cd,
+      0x7010b, 0x80066, 0x80026, 0x900ad, 0x80006, 0x80086, 0x80046, 0x900ed,
+      0x70107, 0x8005e, 0x8001e, 0x9009d, 0x70117, 0x8007e, 0x8003e, 0x900dd,
+      0x7010f, 0x8006e, 0x8002e, 0x900bd, 0x8000e, 0x8008e, 0x8004e, 0x900fd,
+      0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c3,
+      0x70108, 0x80061, 0x80021, 0x900a3, 0x80001, 0x80081, 0x80041, 0x900e3,
+      0x70104, 0x80059, 0x80019, 0x90093, 0x70114, 0x80079, 0x80039, 0x900d3,
+      0x7010c, 0x80069, 0x80029, 0x900b3, 0x80009, 0x80089, 0x80049, 0x900f3,
+      0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900cb,
+      0x7010a, 0x80065, 0x80025, 0x900ab, 0x80005, 0x80085, 0x80045, 0x900eb,
+      0x70106, 0x8005d, 0x8001d, 0x9009b, 0x70116, 0x8007d, 0x8003d, 0x900db,
+      0x7010e, 0x8006d, 0x8002d, 0x900bb, 0x8000d, 0x8008d, 0x8004d, 0x900fb,
+      0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c7,
+      0x70109, 0x80063, 0x80023, 0x900a7, 0x80003, 0x80083, 0x80043, 0x900e7,
+      0x70105, 0x8005b, 0x8001b, 0x90097, 0x70115, 0x8007b, 0x8003b, 0x900d7,
+      0x7010d, 0x8006b, 0x8002b, 0x900b7, 0x8000b, 0x8008b, 0x8004b, 0x900f7,
+      0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900cf,
+      0x7010b, 0x80067, 0x80027, 0x900af, 0x80007, 0x80087, 0x80047, 0x900ef,
+      0x70107, 0x8005f, 0x8001f, 0x9009f, 0x70117, 0x8007f, 0x8003f, 0x900df,
+      0x7010f, 0x8006f, 0x8002f, 0x900bf, 0x8000f, 0x8008f, 0x8004f, 0x900ff
+    ]), 9];
+
+    var fixedDistCodeTab = [new Uint32Array([
+      0x50000, 0x50010, 0x50008, 0x50018, 0x50004, 0x50014, 0x5000c, 0x5001c,
+      0x50002, 0x50012, 0x5000a, 0x5001a, 0x50006, 0x50016, 0x5000e, 0x00000,
+      0x50001, 0x50011, 0x50009, 0x50019, 0x50005, 0x50015, 0x5000d, 0x5001d,
+      0x50003, 0x50013, 0x5000b, 0x5001b, 0x50007, 0x50017, 0x5000f, 0x00000
+    ]), 5];
+    
+    function error(e) {
+        throw new Error(e)
+    }
+
+    function constructor(bytes) {
+      //var bytes = stream.getBytes();
+      var bytesPos = 0;
+
+      var cmf = bytes[bytesPos++];
+      var flg = bytes[bytesPos++];
+      if (cmf == -1 || flg == -1)
+        error('Invalid header in flate stream');
+      if ((cmf & 0x0f) != 0x08)
+        error('Unknown compression method in flate stream');
+      if ((((cmf << 8) + flg) % 31) != 0)
+        error('Bad FCHECK in flate stream');
+      if (flg & 0x20)
+        error('FDICT bit set in flate stream');
+
+      this.bytes = bytes;
+      this.bytesPos = bytesPos;
+
+      this.codeSize = 0;
+      this.codeBuf = 0;
+
+      DecodeStream.call(this);
+    }
+
+    constructor.prototype = Object.create(DecodeStream.prototype);
+
+    constructor.prototype.getBits = function(bits) {
+      var codeSize = this.codeSize;
+      var codeBuf = this.codeBuf;
+      var bytes = this.bytes;
+      var bytesPos = this.bytesPos;
+
+      var b;
+      while (codeSize < bits) {
+        if (typeof (b = bytes[bytesPos++]) == 'undefined')
+          error('Bad encoding in flate stream');
+        codeBuf |= b << codeSize;
+        codeSize += 8;
+      }
+      b = codeBuf & ((1 << bits) - 1);
+      this.codeBuf = codeBuf >> bits;
+      this.codeSize = codeSize -= bits;
+      this.bytesPos = bytesPos;
+      return b;
+    };
+
+    constructor.prototype.getCode = function(table) {
+      var codes = table[0];
+      var maxLen = table[1];
+      var codeSize = this.codeSize;
+      var codeBuf = this.codeBuf;
+      var bytes = this.bytes;
+      var bytesPos = this.bytesPos;
+
+      while (codeSize < maxLen) {
+        var b;
+        if (typeof (b = bytes[bytesPos++]) == 'undefined')
+          error('Bad encoding in flate stream');
+        codeBuf |= (b << codeSize);
+        codeSize += 8;
+      }
+      var code = codes[codeBuf & ((1 << maxLen) - 1)];
+      var codeLen = code >> 16;
+      var codeVal = code & 0xffff;
+      if (codeSize == 0 || codeSize < codeLen || codeLen == 0)
+        error('Bad encoding in flate stream');
+      this.codeBuf = (codeBuf >> codeLen);
+      this.codeSize = (codeSize - codeLen);
+      this.bytesPos = bytesPos;
+      return codeVal;
+    };
+
+    constructor.prototype.generateHuffmanTable = function(lengths) {
+      var n = lengths.length;
+
+      // find max code length
+      var maxLen = 0;
+      for (var i = 0; i < n; ++i) {
+        if (lengths[i] > maxLen)
+          maxLen = lengths[i];
+      }
+
+      // build the table
+      var size = 1 << maxLen;
+      var codes = new Uint32Array(size);
+      for (var len = 1, code = 0, skip = 2;
+           len <= maxLen;
+           ++len, code <<= 1, skip <<= 1) {
+        for (var val = 0; val < n; ++val) {
+          if (lengths[val] == len) {
+            // bit-reverse the code
+            var code2 = 0;
+            var t = code;
+            for (var i = 0; i < len; ++i) {
+              code2 = (code2 << 1) | (t & 1);
+              t >>= 1;
+            }
+
+            // fill the table entries
+            for (var i = code2; i < size; i += skip)
+              codes[i] = (len << 16) | val;
+
+            ++code;
+          }
+        }
+      }
+
+      return [codes, maxLen];
+    };
+
+    constructor.prototype.readBlock = function() {
+      function repeat(stream, array, len, offset, what) {
+        var repeat = stream.getBits(len) + offset;
+        while (repeat-- > 0)
+          array[i++] = what;
+      }
+
+      // read block header
+      var hdr = this.getBits(3);
+      if (hdr & 1)
+        this.eof = true;
+      hdr >>= 1;
+
+      if (hdr == 0) { // uncompressed block
+        var bytes = this.bytes;
+        var bytesPos = this.bytesPos;
+        var b;
+
+        if (typeof (b = bytes[bytesPos++]) == 'undefined')
+          error('Bad block header in flate stream');
+        var blockLen = b;
+        if (typeof (b = bytes[bytesPos++]) == 'undefined')
+          error('Bad block header in flate stream');
+        blockLen |= (b << 8);
+        if (typeof (b = bytes[bytesPos++]) == 'undefined')
+          error('Bad block header in flate stream');
+        var check = b;
+        if (typeof (b = bytes[bytesPos++]) == 'undefined')
+          error('Bad block header in flate stream');
+        check |= (b << 8);
+        if (check != (~blockLen & 0xffff))
+          error('Bad uncompressed block length in flate stream');
+
+        this.codeBuf = 0;
+        this.codeSize = 0;
+
+        var bufferLength = this.bufferLength;
+        var buffer = this.ensureBuffer(bufferLength + blockLen);
+        var end = bufferLength + blockLen;
+        this.bufferLength = end;
+        for (var n = bufferLength; n < end; ++n) {
+          if (typeof (b = bytes[bytesPos++]) == 'undefined') {
+            this.eof = true;
+            break;
+          }
+          buffer[n] = b;
+        }
+        this.bytesPos = bytesPos;
+        return;
+      }
+
+      var litCodeTable;
+      var distCodeTable;
+      if (hdr == 1) { // compressed block, fixed codes
+        litCodeTable = fixedLitCodeTab;
+        distCodeTable = fixedDistCodeTab;
+      } else if (hdr == 2) { // compressed block, dynamic codes
+        var numLitCodes = this.getBits(5) + 257;
+        var numDistCodes = this.getBits(5) + 1;
+        var numCodeLenCodes = this.getBits(4) + 4;
+
+        // build the code lengths code table
+        var codeLenCodeLengths = Array(codeLenCodeMap.length);
+        var i = 0;
+        while (i < numCodeLenCodes)
+          codeLenCodeLengths[codeLenCodeMap[i++]] = this.getBits(3);
+        var codeLenCodeTab = this.generateHuffmanTable(codeLenCodeLengths);
+
+        // build the literal and distance code tables
+        var len = 0;
+        var i = 0;
+        var codes = numLitCodes + numDistCodes;
+        var codeLengths = new Array(codes);
+        while (i < codes) {
+          var code = this.getCode(codeLenCodeTab);
+          if (code == 16) {
+            repeat(this, codeLengths, 2, 3, len);
+          } else if (code == 17) {
+            repeat(this, codeLengths, 3, 3, len = 0);
+          } else if (code == 18) {
+            repeat(this, codeLengths, 7, 11, len = 0);
+          } else {
+            codeLengths[i++] = len = code;
+          }
+        }
+
+        litCodeTable =
+          this.generateHuffmanTable(codeLengths.slice(0, numLitCodes));
+        distCodeTable =
+          this.generateHuffmanTable(codeLengths.slice(numLitCodes, codes));
+      } else {
+        error('Unknown block type in flate stream');
+      }
+
+      var buffer = this.buffer;
+      var limit = buffer ? buffer.length : 0;
+      var pos = this.bufferLength;
+      while (true) {
+        var code1 = this.getCode(litCodeTable);
+        if (code1 < 256) {
+          if (pos + 1 >= limit) {
+            buffer = this.ensureBuffer(pos + 1);
+            limit = buffer.length;
+          }
+          buffer[pos++] = code1;
+          continue;
+        }
+        if (code1 == 256) {
+          this.bufferLength = pos;
+          return;
+        }
+        code1 -= 257;
+        code1 = lengthDecode[code1];
+        var code2 = code1 >> 16;
+        if (code2 > 0)
+          code2 = this.getBits(code2);
+        var len = (code1 & 0xffff) + code2;
+        code1 = this.getCode(distCodeTable);
+        code1 = distDecode[code1];
+        code2 = code1 >> 16;
+        if (code2 > 0)
+          code2 = this.getBits(code2);
+        var dist = (code1 & 0xffff) + code2;
+        if (pos + len >= limit) {
+          buffer = this.ensureBuffer(pos + len);
+          limit = buffer.length;
+        }
+        for (var k = 0; k < len; ++k, ++pos)
+          buffer[pos] = buffer[pos - dist];
+      }
+    };
+
+    return constructor;
+  })();
+
+  /**
+   * JavaScript Polyfill functions for jsPDF
+   * Collected from public resources by
+   * https://github.com/diegocr
+   */
+
+  (function (global) {
+      
+      if (typeof global.console !== "object") {
+          // Console-polyfill. MIT license.
+          // https://github.com/paulmillr/console-polyfill
+          // Make it safe to do console.log() always.
+          global.console = {};
+          
+          var con = global.console;
+          var prop, method;
+          var dummy = function() {};
+          var properties = ['memory'];
+          var methods = ('assert,clear,count,debug,dir,dirxml,error,exception,group,' +
+           'groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,' +
+           'show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn').split(',');
+          while (prop = properties.pop()) if (!con[prop]) con[prop] = {};
+          while (method = methods.pop()) if (!con[method]) con[method] = dummy;
+      }
+
+      var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
+
+      if (typeof global.btoa === 'undefined') {
+          global.btoa = function(data) {
+              //  discuss at: http://phpjs.org/functions/base64_encode/
+              // original by: Tyler Akins (http://rumkin.com)
+              // improved by: Bayron Guevara
+              // improved by: Thunder.m
+              // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
+              // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
+              // improved by: Rafal Kukawski (http://kukawski.pl)
+              // bugfixed by: Pellentesque Malesuada
+              //   example 1: base64_encode('Kevin van Zonneveld');
+              //   returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA=='
+
+              var o1,o2,o3,h1,h2,h3,h4,bits,i = 0,ac = 0,enc = '',tmp_arr = [];
+
+              if (!data) {
+                  return data;
+              }
+
+              do { // pack three octets into four hexets
+                  o1 = data.charCodeAt(i++);
+                  o2 = data.charCodeAt(i++);
+                  o3 = data.charCodeAt(i++);
+
+                  bits = o1 << 16 | o2 << 8 | o3;
+
+                  h1 = bits >> 18 & 0x3f;
+                  h2 = bits >> 12 & 0x3f;
+                  h3 = bits >> 6 & 0x3f;
+                  h4 = bits & 0x3f;
+
+                  // use hexets to index into b64, and append result to encoded string
+                  tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
+              } while (i < data.length);
+
+              enc = tmp_arr.join('');
+
+              var r = data.length % 3;
+
+              return (r ? enc.slice(0, r - 3) : enc) + '==='.slice(r || 3);
+          };
+      }
+
+      if (typeof global.atob === 'undefined') {
+          global.atob = function(data) {
+              //  discuss at: http://phpjs.org/functions/base64_decode/
+              // original by: Tyler Akins (http://rumkin.com)
+              // improved by: Thunder.m
+              // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
+              // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
+              //    input by: Aman Gupta
+              //    input by: Brett Zamir (http://brett-zamir.me)
+              // bugfixed by: Onno Marsman
+              // bugfixed by: Pellentesque Malesuada
+              // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
+              //   example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA==');
+              //   returns 1: 'Kevin van Zonneveld'
+
+              var o1,o2,o3,h1,h2,h3,h4,bits,i = 0,ac = 0,dec = '',tmp_arr = [];
+
+              if (!data) {
+                  return data;
+              }
+
+              data += '';
+
+              do { // unpack four hexets into three octets using index points in b64
+                  h1 = b64.indexOf(data.charAt(i++));
+                  h2 = b64.indexOf(data.charAt(i++));
+                  h3 = b64.indexOf(data.charAt(i++));
+                  h4 = b64.indexOf(data.charAt(i++));
+
+                  bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
+
+                  o1 = bits >> 16 & 0xff;
+                  o2 = bits >> 8 & 0xff;
+                  o3 = bits & 0xff;
+
+                  if (h3 == 64) {
+                      tmp_arr[ac++] = String.fromCharCode(o1);
+                  } else if (h4 == 64) {
+                      tmp_arr[ac++] = String.fromCharCode(o1, o2);
+                  } else {
+                      tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
+                  }
+              } while (i < data.length);
+
+              dec = tmp_arr.join('');
+
+              return dec;
+          };
+      }
+
+      if (!Array.prototype.map) {
+          Array.prototype.map = function(fun /*, thisArg */) {
+              if (this === void 0 || this === null || typeof fun !== "function")
+                  throw new TypeError();
+
+              var t = Object(this), len = t.length >>> 0, res = new Array(len);
+              var thisArg = arguments.length > 1 ? arguments[1] : void 0;
+              for (var i = 0; i < len; i++) {
+                  // NOTE: Absolute correctness would demand Object.defineProperty
+                  //       be used.  But this method is fairly new, and failure is
+                  //       possible only if Object.prototype or Array.prototype
+                  //       has a property |i| (very unlikely), so use a less-correct
+                  //       but more portable alternative.
+                  if (i in t)
+                      res[i] = fun.call(thisArg, t[i], i, t);
+              }
+
+              return res;
+          };
+      }
+
+
+      if(!Array.isArray) {
+          Array.isArray = function(arg) {
+              return Object.prototype.toString.call(arg) === '[object Array]';
+          };
+      }
+
+      if (!Array.prototype.forEach) {
+          Array.prototype.forEach = function(fun, thisArg) {
+
+              if (this === void 0 || this === null || typeof fun !== "function")
+                  throw new TypeError();
+
+              var t = Object(this), len = t.length >>> 0;
+              for (var i = 0; i < len; i++) {
+                  if (i in t)
+                      fun.call(thisArg, t[i], i, t);
+              }
+          };
+      }
+      
+      if (!Object.keys) {
+          Object.keys = (function () {
+
+              var hasOwnProperty = Object.prototype.hasOwnProperty,
+                  hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
+                  dontEnums = ['toString','toLocaleString','valueOf','hasOwnProperty',
+                      'isPrototypeOf','propertyIsEnumerable','constructor'],
+                  dontEnumsLength = dontEnums.length;
+
+              return function (obj) {
+                  if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
+                      throw new TypeError();
+                  }
+                  var result = [], prop, i;
+
+                  for (prop in obj) {
+                      if (hasOwnProperty.call(obj, prop)) {
+                          result.push(prop);
+                      }
+                  }
+
+                  if (hasDontEnumBug) {
+                      for (i = 0; i < dontEnumsLength; i++) {
+                          if (hasOwnProperty.call(obj, dontEnums[i])) {
+                              result.push(dontEnums[i]);
+                          }
+                      }
+                  }
+                  return result;
+              };
+          }());
+      }
+      
+      if (typeof Object.assign != 'function') {
+            Object.assign = function(target) {
+              if (target == null) {
+                throw new TypeError('Cannot convert undefined or null to object');
+              }
+
+              target = Object(target);
+              for (var index = 1; index < arguments.length; index++) {
+                var source = arguments[index];
+                if (source != null) {
+                  for (var key in source) {
+                    if (Object.prototype.hasOwnProperty.call(source, key)) {
+                      target[key] = source[key];
+                    }
+                  }
+                }
+              }
+              return target;
+            };
+          }
+
+      if (!String.prototype.trim) {
+          String.prototype.trim = function () {
+              return this.replace(/^\s+|\s+$/g, '');
+          };
+      }
+      if (!String.prototype.trimLeft) {
+          String.prototype.trimLeft = function() {
+              return this.replace(/^\s+/g, "");
+          };
+      }
+      if (!String.prototype.trimRight) {
+          String.prototype.trimRight = function() {
+              return this.replace(/\s+$/g, "");
+          };
+      }
+
+  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || typeof global !== "undefined" && global ||  Function('return typeof this === "object" && this.content')() || Function('return this')()));
+  // `self` is undefined in Firefox for Android content script context
+  // while `this` is nsIContentFrameMessageManager
+  // with an attribute `content` that corresponds to the window
+
+  return jsPDF;
+
+})));
diff --git a/AstuteClient2/src/assets/jspdf/dist/jspdf.min.js b/AstuteClient2/src/assets/jspdf/dist/jspdf.min.js
new file mode 100644
index 0000000..f0923f9
--- /dev/null
+++ b/AstuteClient2/src/assets/jspdf/dist/jspdf.min.js
@@ -0,0 +1,225 @@
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.jsPDF=e()}(this,function(){"use strict";var t,w,e,I,i,o,a,c,A,T,d,p,F,n,r,s,l,q,E,P,g,m,y,h,v,b,x,S,u,k,_,f,C,O,B,j,R,D,M,z,N,L,U,H,W,V,G,Y,X,J,vt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},K=function(pt){var gt="1.3",mt={a0:[2383.94,3370.39],a1:[1683.78,2383.94],a2:[1190.55,1683.78],a3:[841.89,1190.55],a4:[595.28,841.89],a5:[419.53,595.28],a6:[297.64,419.53],a7:[209.76,297.64],a8:[147.4,209.76],a9:[104.88,147.4],a10:[73.7,104.88],b0:[2834.65,4008.19],b1:[2004.09,2834.65],b2:[1417.32,2004.09],b3:[1000.63,1417.32],b4:[708.66,1000.63],b5:[498.9,708.66],b6:[354.33,498.9],b7:[249.45,354.33],b8:[175.75,249.45],b9:[124.72,175.75],b10:[87.87,124.72],c0:[2599.37,3676.54],c1:[1836.85,2599.37],c2:[1298.27,1836.85],c3:[918.43,1298.27],c4:[649.13,918.43],c5:[459.21,649.13],c6:[323.15,459.21],c7:[229.61,323.15],c8:[161.57,229.61],c9:[113.39,161.57],c10:[79.37,113.39],dl:[311.81,623.62],letter:[612,792],"government-letter":[576,756],legal:[612,1008],"junior-legal":[576,360],ledger:[1224,792],tabloid:[792,1224],"credit-card":[153,243]};function yt(o){var a={};this.subscribe=function(t,e,n){if("function"!=typeof e)return!1;a.hasOwnProperty(t)||(a[t]={});var r=Math.random().toString(35);return a[t][r]=[e,!!n],r},this.unsubscribe=function(t){for(var e in a)if(a[e][t])return delete a[e][t],!0;return!1},this.publish=function(t){if(a.hasOwnProperty(t)){var e=Array.prototype.slice.call(arguments,1),n=[];for(var r in a[t]){var i=a[t][r];try{i[0].apply(o,e)}catch(t){pt.console&&console.error("jsPDF PubSub Error",t.message,t)}i[1]&&n.push(r)}n.length&&n.forEach(this.unsubscribe)}}}function wt(t,e,n,r){var i={};"object"===(void 0===t?"undefined":vt(t))&&(t=(i=t).orientation,e=i.unit||e,n=i.format||n,r=i.compress||i.compressPdf||r),e=e||"mm",n=n||"a4",t=(""+(t||"P")).toLowerCase();(""+n).toLowerCase();var tt,y,w,o,u,v,a,s,c,l,h,f=!!r&&"function"==typeof Uint8Array,et=i.textColor||"0 g",d=i.drawColor||"0 G",nt=i.fontSize||16,rt=i.charSpace||0,it=i.R2L||!1,ot=i.lineHeight||1.15,p=i.lineWidth||.200025,g="00000000000000000000000000000000",m=2,b=!1,x=[],at={},S={},k=0,_=[],C=[],I=[],A=[],T=[],F=0,q=0,E=0,P={title:"",subject:"",author:"",keywords:"",creator:""},O={},st=new yt(O),B=i.hotfixes||[],j=function(t){var e,n=t.ch1,r=t.ch2,i=t.ch3,o=t.ch4,a=(t.precision,"draw"===t.pdfColorType?["G","RG","K"]:["g","rg","k"]),s={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4","indianred ":"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};if("string"==typeof n&&s.hasOwnProperty(n)&&(n=s[n]),"string"==typeof n&&/^#[0-9A-Fa-f]{3}$/.test(n)&&(n="#"+n[1]+n[1]+n[2]+n[2]+n[3]+n[3]),"string"==typeof n&&/^#[0-9A-Fa-f]{6}$/.test(n)){var c=parseInt(n.substr(1),16);n=c>>16&255,r=c>>8&255,i=255&c}if(void 0===r||void 0===o&&n===r&&r===i)if("string"==typeof n)e=n+" "+a[0];else switch(t.precision){case 2:e=N(n/255)+" "+a[0];break;case 3:default:e=L(n/255)+" "+a[0]}else if(void 0===o||"object"===(void 0===o?"undefined":vt(o))){if("string"==typeof n)e=[n,r,i,a[1]].join(" ");else switch(t.precision){case 2:e=[N(n/255),N(r/255),N(i/255),a[1]].join(" ");break;default:case 3:e=[L(n/255),L(r/255),L(i/255),a[1]].join(" ")}o&&0===o.a&&(e=["255","255","255",a[1]].join(" "))}else if("string"==typeof n)e=[n,r,i,o,a[2]].join(" ");else switch(t.precision){case 2:e=[N(n),N(r),N(i),N(o),a[2]].join(" ");break;case 3:default:e=[L(n),L(r),L(i),L(o),a[2]].join(" ")}return e},R=function(t){var e=function(t){return("0"+parseInt(t)).slice(-2)},n=t.getTimezoneOffset(),r=n<0?"+":"-",i=Math.floor(Math.abs(n/60)),o=Math.abs(n%60),a=[r,e(i),"'",e(o),"'"].join("");return["D:",t.getFullYear(),e(t.getMonth()+1),e(t.getDate()),e(t.getHours()),e(t.getMinutes()),e(t.getSeconds()),a].join("")},D=function(t){var e;return void 0===(void 0===t?"undefined":vt(t))&&(t=new Date),e="object"===(void 0===t?"undefined":vt(t))&&"[object Date]"===Object.prototype.toString.call(t)?R(t):/^D:(20[0-2][0-9]|203[0-7]|19[7-9][0-9])(0[0-9]|1[0-2])([0-2][0-9]|3[0-1])(0[0-9]|1[0-9]|2[0-3])(0[0-9]|[1-5][0-9])(0[0-9]|[1-5][0-9])(\+0[0-9]|\+1[0-4]|\-0[0-9]|\-1[0-1])\'(0[0-9]|[1-5][0-9])\'?$/.test(t)?t:R(new Date),l=e},M=function(t){var e=l;return"jsDate"===t&&(e=function(t){var e=parseInt(t.substr(2,4),10),n=parseInt(t.substr(6,2),10)-1,r=parseInt(t.substr(8,2),10),i=parseInt(t.substr(10,2),10),o=parseInt(t.substr(12,2),10),a=parseInt(t.substr(14,2),10);parseInt(t.substr(16,2),10),parseInt(t.substr(20,2),10);return new Date(e,n,r,i,o,a,0)}(l)),e},z=function(t){return t=t||"12345678901234567890123456789012".split("").map(function(){return"ABCDEF0123456789".charAt(Math.floor(16*Math.random()))}).join(""),g=t},N=function(t){return t.toFixed(2)},L=function(t){return t.toFixed(3)},ct=function(t){t="string"==typeof t?t:t.toString(),b?_[o].push(t):(E+=t.length+1,A.push(t))},U=function(){return x[++m]=E,ct(m+" 0 obj"),m},H=function(t){ct("stream"),ct(t),ct("endstream")},W=function(){for(var t in ct("/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]"),ct("/Font <<"),at)at.hasOwnProperty(t)&&ct("/"+t+" "+at[t].objectNumber+" 0 R");ct(">>"),ct("/XObject <<"),st.publish("putXobjectDict"),ct(">>")},V=function(){!function(){for(var t in at)at.hasOwnProperty(t)&&(e=at[t],st.publish("putFont",{font:e,out:ct,newObject:U}),!0!==e.isAlreadyPutted&&(e.objectNumber=U(),ct("<<"),ct("/Type /Font"),ct("/BaseFont /"+e.postScriptName),ct("/Subtype /Type1"),"string"==typeof e.encoding&&ct("/Encoding /"+e.encoding),ct("/FirstChar 32"),ct("/LastChar 255"),ct(">>"),ct("endobj")));var e}(),st.publish("putResources"),x[2]=E,ct("2 0 obj"),ct("<<"),W(),ct(">>"),ct("endobj"),st.publish("postPutResources")},G=function(t,e,n){S.hasOwnProperty(e)||(S[e]={}),S[e][n]=t},Y=function(t,e,n,r){var i="F"+(Object.keys(at).length+1).toString(10),o=at[i]={id:i,postScriptName:t,fontName:e,fontStyle:n,encoding:r,metadata:{}};return G(i,e,n),st.publish("addFont",o),i},lt=function(t,e){return function(t,e){var n,r,i,o,a,s,c,l,h;if(i=(e=e||{}).sourceEncoding||"Unicode",a=e.outputEncoding,(e.autoencode||a)&&at[tt].metadata&&at[tt].metadata[i]&&at[tt].metadata[i].encoding&&(o=at[tt].metadata[i].encoding,!a&&at[tt].encoding&&(a=at[tt].encoding),!a&&o.codePages&&(a=o.codePages[0]),"string"==typeof a&&(a=o[a]),a)){for(c=!1,s=[],n=0,r=t.length;n<r;n++)(l=a[t.charCodeAt(n)])?s.push(String.fromCharCode(l)):s.push(t[n]),s[n].charCodeAt(0)>>8&&(c=!0);t=s.join("")}for(n=t.length;void 0===c&&0!==n;)t.charCodeAt(n-1)>>8&&(c=!0),n--;if(!c)return t;for(s=e.noBOM?[]:[254,255],n=0,r=t.length;n<r;n++){if((h=(l=t.charCodeAt(n))>>8)>>8)throw new Error("Character at position "+n+" of string '"+t+"' exceeds 16bits. Cannot be encoded into UCS-2 BE");s.push(h),s.push(l-(h<<8))}return String.fromCharCode.apply(void 0,s)}(t,e).replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)")},X=function(){(function(t,e){var n="string"==typeof e&&e.toLowerCase();if("string"==typeof t){var r=t.toLowerCase();mt.hasOwnProperty(r)&&(t=mt[r][0]/y,e=mt[r][1]/y)}if(Array.isArray(t)&&(e=t[1],t=t[0]),n){switch(n.substr(0,1)){case"l":t<e&&(n="s");break;case"p":e<t&&(n="s")}"s"===n&&(w=t,t=e,e=w)}b=!0,_[++k]=[],I[k]={width:Number(t)||u,height:Number(e)||v},C[k]={},J(k)}).apply(this,arguments),ct(N(p*y)+" w"),ct(d),0!==F&&ct(F+" J"),0!==q&&ct(q+" j"),st.publish("addPage",{pageNumber:k})},J=function(t){0<t&&t<=k&&(u=I[o=t].width,v=I[t].height)},K=function(t,e){var n,r;return t=void 0!==t?t:at[tt].fontName,e=void 0!==e?e:at[tt].fontStyle,r=t.toLowerCase(),void 0!==S[r]&&void 0!==S[r][e]?n=S[r][e]:void 0!==S[t]&&void 0!==S[t][e]?n=S[t][e]:console.warn("Unable to look up font label for font '"+t+"', '"+e+"'. Refer to getFontList() for available fonts."),n||null==(n=S.times[e])&&(n=S.times.normal),n},Q=function(){b=!1,m=2,E=0,A=[],x=[],T=[],st.publish("buildDocument"),ct("%PDF-"+gt),ct("%ºß¬à"),function(){var t,e,n,r,i,o,a,s,c,l=[];for(a=pt.adler32cs||wt.API.adler32cs,f&&void 0===a&&(f=!1),t=1;t<=k;t++){if(l.push(U()),s=(u=I[t].width)*y,c=(v=I[t].height)*y,ct("<</Type /Page"),ct("/Parent 1 0 R"),ct("/Resources 2 0 R"),ct("/MediaBox [0 0 "+N(s)+" "+N(c)+"]"),st.publish("putPage",{pageNumber:t,page:_[t]}),ct("/Contents "+(m+1)+" 0 R"),ct(">>"),ct("endobj"),e=_[t].join("\n"),U(),f){for(n=[],r=e.length;r--;)n[r]=e.charCodeAt(r);o=a.from(e),(i=new Deflater(6)).append(new Uint8Array(n)),e=i.flush(),(n=new Uint8Array(e.length+6)).set(new Uint8Array([120,156])),n.set(e,2),n.set(new Uint8Array([255&o,o>>8&255,o>>16&255,o>>24&255]),e.length+2),e=String.fromCharCode.apply(null,n),ct("<</Length "+e.length+" /Filter [/FlateDecode]>>")}else ct("<</Length "+e.length+">>");H(e),ct("endobj")}x[1]=E,ct("1 0 obj"),ct("<</Type /Pages");var h="/Kids [";for(r=0;r<k;r++)h+=l[r]+" 0 R ";ct(h+"]"),ct("/Count "+k),ct(">>"),ct("endobj"),st.publish("postPutPages")}(),function(){st.publish("putAdditionalObjects");for(var t=0;t<T.length;t++){var e=T[t];x[e.objId]=E,ct(e.objId+" 0 obj"),ct(e.content),ct("endobj")}m+=T.length,st.publish("postPutAdditionalObjects")}(),V(),U(),ct("<<"),function(){for(var t in ct("/Producer (jsPDF "+wt.version+")"),P)P.hasOwnProperty(t)&&P[t]&&ct("/"+t.substr(0,1).toUpperCase()+t.substr(1)+" ("+lt(P[t])+")");ct("/CreationDate ("+l+")")}(),ct(">>"),ct("endobj"),U(),ct("<<"),function(){switch(ct("/Type /Catalog"),ct("/Pages 1 0 R"),s||(s="fullwidth"),s){case"fullwidth":ct("/OpenAction [3 0 R /FitH null]");break;case"fullheight":ct("/OpenAction [3 0 R /FitV null]");break;case"fullpage":ct("/OpenAction [3 0 R /Fit]");break;case"original":ct("/OpenAction [3 0 R /XYZ null null 1]");break;default:var t=""+s;"%"===t.substr(t.length-1)&&(s=parseInt(s)/100),"number"==typeof s&&ct("/OpenAction [3 0 R /XYZ null null "+N(s)+"]")}switch(c||(c="continuous"),c){case"continuous":ct("/PageLayout /OneColumn");break;case"single":ct("/PageLayout /SinglePage");break;case"two":case"twoleft":ct("/PageLayout /TwoColumnLeft");break;case"tworight":ct("/PageLayout /TwoColumnRight")}a&&ct("/PageMode /"+a),st.publish("putCatalog")}(),ct(">>"),ct("endobj");var t,e=E,n="0000000000";for(ct("xref"),ct("0 "+(m+1)),ct(n+" 65535 f "),t=1;t<=m;t++){var r=x[t];ct("function"==typeof r?(n+x[t]()).slice(-10)+" 00000 n ":(n+x[t]).slice(-10)+" 00000 n ")}return ct("trailer"),ct("<<"),ct("/Size "+(m+1)),ct("/Root "+m+" 0 R"),ct("/Info "+(m-1)+" 0 R"),ct("/ID [ <"+g+"> <"+g+"> ]"),ct(">>"),ct("startxref"),ct(""+e),ct("%%EOF"),b=!0,A.join("\n")},Z=function(t){var e="S";return"F"===t?e="f":"FD"===t||"DF"===t?e="B":"f"!==t&&"f*"!==t&&"B"!==t&&"B*"!==t||(e=t),e},$=function(){for(var t=Q(),e=t.length,n=new ArrayBuffer(e),r=new Uint8Array(n);e--;)r[e]=t.charCodeAt(e);return n},ht=function(){return new Blob([$()],{type:"application/pdf"})},ut=((h=function(t,e){var n="dataur"===(""+t).substr(0,6)?"data:application/pdf;base64,"+btoa(Q()):0;switch(t){case void 0:return Q();case"save":if("object"===("undefined"==typeof navigator?"undefined":vt(navigator))&&navigator.getUserMedia&&(void 0===pt.URL||void 0===pt.URL.createObjectURL))return O.output("dataurlnewwindow");bt(ht(),e),"function"==typeof bt.unload&&pt.setTimeout&&setTimeout(bt.unload,911);break;case"arraybuffer":return $();case"blob":return ht();case"bloburi":case"bloburl":return pt.URL&&pt.URL.createObjectURL(ht())||void 0;case"datauristring":case"dataurlstring":return n;case"dataurlnewwindow":var r=pt.open(n);if(r||"undefined"==typeof safari)return r;case"datauri":case"dataurl":return pt.document.location.href=n;default:throw new Error('Output type "'+t+'" is not supported.')}}).foo=function(){try{return h.apply(this,arguments)}catch(t){var e=t.stack||"";~e.indexOf(" at ")&&(e=e.split(" at ")[1]);var n="Error in function "+e.split("\n")[0].split("<")[0]+": "+t.message;if(!pt.console)throw new Error(n);pt.console.error(n,t),pt.alert&&alert(n)}},(h.foo.bar=h).foo),ft=function(t){return!0===Array.isArray(B)&&-1<B.indexOf(t)};switch(e){case"pt":y=1;break;case"mm":y=72/25.4;break;case"cm":y=72/2.54;break;case"in":y=72;break;case"px":y=1==ft("px_scaling")?.75:96/72;break;case"pc":case"em":y=12;break;case"ex":y=6;break;default:throw"Invalid unit: "+e}for(var dt in D(),z(),O.internal={pdfEscape:lt,getStyle:Z,getFont:function(){return at[K.apply(O,arguments)]},getFontSize:function(){return nt},getCharSpace:function(){return rt},getTextColor:function(){var t=et.split(" ");if(2===t.length&&"g"===t[1]){var e=parseFloat(t[0]);t=[e,e,e,"r"]}for(var n="#",r=0;r<3;r++)n+=("0"+Math.floor(255*parseFloat(t[r])).toString(16)).slice(-2);return n},getLineHeight:function(){return nt*ot},write:function(t){ct(1===arguments.length?t:Array.prototype.join.call(arguments," "))},getCoordinateString:function(t){return N(t*y)},getVerticalCoordinateString:function(t){return N((v-t)*y)},collections:{},newObject:U,newAdditionalObject:function(){var t=2*_.length+1,e={objId:t+=T.length,content:""};return T.push(e),e},newObjectDeferred:function(){return x[++m]=function(){return E},m},newObjectDeferredBegin:function(t){x[t]=E},putStream:H,events:st,scaleFactor:y,pageSize:{getWidth:function(){return u},getHeight:function(){return v}},output:function(t,e){return ut(t,e)},getNumberOfPages:function(){return _.length-1},pages:_,out:ct,f2:N,getPageInfo:function(t){return{objId:2*(t-1)+3,pageNumber:t,pageContext:C[t]}},getCurrentPageInfo:function(){return{objId:2*(o-1)+3,pageNumber:o,pageContext:C[o]}},getPDFVersion:function(){return gt},hasHotfix:ft},O.addPage=function(){return X.apply(this,arguments),this},O.setPage=function(){return J.apply(this,arguments),this},O.insertPage=function(t){return this.addPage(),this.movePage(o,t),this},O.movePage=function(t,e){if(e<t){for(var n=_[t],r=I[t],i=C[t],o=t;e<o;o--)_[o]=_[o-1],I[o]=I[o-1],C[o]=C[o-1];_[e]=n,I[e]=r,C[e]=i,this.setPage(e)}else if(t<e){for(n=_[t],r=I[t],i=C[t],o=t;o<e;o++)_[o]=_[o+1],I[o]=I[o+1],C[o]=C[o+1];_[e]=n,I[e]=r,C[e]=i,this.setPage(e)}return this},O.deletePage=function(){return function(t){0<t&&t<=k&&(_.splice(t,1),I.splice(t,1),--k<o&&(o=k),this.setPage(o))}.apply(this,arguments),this},O.setCreationDate=function(t){return D(t),this},O.getCreationDate=function(t){return M(t)},O.setFileId=function(t){return z(t),this},O.getFileId=function(){return g},O.setDisplayMode=function(t,e,n){if(s=t,c=e,-1==[void 0,null,"UseNone","UseOutlines","UseThumbs","FullScreen"].indexOf(a=n))throw new Error('Page mode must be one of UseNone, UseOutlines, UseThumbs, or FullScreen. "'+n+'" is not recognized.');return this},O.text=function(t,e,n,i){var r,o,a="";function s(t){for(var e,n=t.concat(),r=[],i=n.length;i--;)"string"==typeof(e=n.shift())?r.push(e):"[object Array]"===Object.prototype.toString.call(t)&&1===e.length?r.push(e[0]):r.push([e[0],e[1],e[2]]);return r}function c(t,e){var n;if("string"==typeof t)n=e(t)[0];else if("[object Array]"===Object.prototype.toString.call(t)){for(var r,i,o=t.concat(),a=[],s=o.length;s--;)"string"==typeof(r=o.shift())?a.push(e(r)[0]):"[object Array]"===Object.prototype.toString.call(r)&&"string"===r[0]&&(i=e(r[0],r[1],r[2]),a.push([i[0],i[1],i[2]]));n=a}return n}var l=function(t,e){return"function"==typeof e.font.metadata.widthOfString?e.font.metadata.widthOfString(t,e.fontSize,e.charSpace):u(function(t,e){var n,r,i,o=(e=e||{}).widths?e.widths:e.font.metadata.Unicode.widths,a=o.fof?o.fof:1,s=e.kerning?e.kerning:e.font.metadata.Unicode.kerning,c=s.fof?s.fof:1,l=0,h=o[0]||a,u=[];for(n=0,r=t.length;n<r;n++)i=t.charCodeAt(n),u.push((o[i]||h)/a+(s[i]&&s[i][l]||0)/c),l=i;return u}(t,e))*e.fontSize};var h,u=function(t){for(var e=t.length,n=0;e;)n+=t[--e];return n};"number"==typeof t&&(h=n,n=e,e=t,t=h);var f=i,d=arguments[4],p=arguments[5];"object"===(void 0===f?"undefined":vt(f))&&null!==f||("string"==typeof d&&(p=d,d=null),"string"==typeof f&&(p=f,f=null),"number"==typeof f&&(d=f,f=null),i={flags:f,angle:d,align:p});var g=!1,m=!0;if("string"==typeof t)g=!0;else if("[object Array]"===Object.prototype.toString.call(t)){for(var y,w=t.concat(),v=[],b=w.length;b--;)("string"!=typeof(y=w.shift())||"[object Array]"===Object.prototype.toString.call(y)&&"string"!=typeof y[0])&&(m=!1);g=m}if(!1===g)throw new Error('Type of text must be string or Array. "'+t+'" is not recognized.');var x=at[tt].encoding;"WinAnsiEncoding"!==x&&"StandardEncoding"!==x||(t=c(t,function(t,e,n){return[(r=t,r=r.split("\t").join(Array(i.TabLen||9).join(" ")),lt(r,f)),e,n];var r})),"string"==typeof t&&(t=t.match(/[\r?\n]/)?t.split(/\r\n|\r|\n/g):[t]);var S=i.maxWidth||0,k=i.maxWidthAlgorythm||"first-fit";o=i.lineHeight||ot;var _=at[tt],C=this.internal.scaleFactor,I=i.charSpace||rt,A=l(" ",{font:_,charSpace:I,fontSize:nt})/C,T=function(t,e){var n=0,r=0,i=[],o=[],a=[],s=[],c=[];for(s=t.split(/ /g),n=0;n<s.length;n+=1)o.push(l(s[n],{font:_,charSpace:I,fontSize:nt})/C);for(n=0;n<s.length;n+=1)a=o.slice(r,n),e<=u(a)+A*(a.length-1)?(i.push(s.slice(r,0!==n?n-1:0).join(" ")),r=0!==n?n-1:0,n-=1):n===o.length-1&&i.push(s.slice(r,o.length).join(" "));for(c=[],n=0;n<i.length;n+=1)c=c.concat(i[n]);return c};if(0<S)switch(k){case"first-fit":default:t=function(t,e){var n=0,r=[];for(n=0;n<t.length;n+=1)r=r.concat(T(t[n],e));return r}(t,S)}var F={text:t,x:e,y:n,options:i,mutex:{pdfEscape:lt,activeFontKey:tt,fonts:at,activeFontSize:nt}};st.publish("preProcessText",F),t=F.text;d=(i=F.options).angle,C=this.internal.scaleFactor,this.internal.pageSize.getHeight();var q=[];if(d){d*=Math.PI/180;var E=Math.cos(d),P=Math.sin(d),O=function(t){return t.toFixed(2)};q=[O(E),O(P),O(-1*P),O(E)]}void 0!==(I=i.charSpace)&&(a+=I+" Tc\n");i.lang;var B=-1,j=i.renderingMode||i.stroke,R=this.internal.getCurrentPageInfo().pageContext;switch(j){case 0:case!1:case"fill":B=0;break;case 1:case!0:case"stroke":B=1;break;case 2:case"fillThenStroke":B=2;break;case 3:case"invisible":B=3;break;case 4:case"fillAndAddForClipping":B=4;break;case 5:case"strokeAndAddPathForClipping":B=5;break;case 6:case"fillThenStrokeAndAddToPathForClipping":B=6;break;case 7:case"addToPathForClipping":B=7}var D=R.usedRenderingMode||-1;-1!==B?a+=B+" Tr\n":-1!==D&&(a+="0 Tr\n"),-1!==B&&(R.usedRenderingMode=B);p=i.align||"left";var M=nt*o,z=this.internal.pageSize.getHeight(),N=this.internal.pageSize.getWidth(),L=(C=this.internal.scaleFactor,_=at[tt],I=i.charSpace||rt,S=i.maxWidth||0,f={},[]);if("[object Array]"===Object.prototype.toString.call(t)){var U,H;v=s(t);"left"!==p&&(H=v.map(function(t){return l(t,{font:_,charSpace:I,fontSize:nt})/C}));var W,V=Math.max.apply(Math,H),G=0;if("right"===p){e-=H[0],t=[];var Y=0;for(b=v.length;Y<b;Y++)V-H[Y],0===Y?(W=e*C,U=(z-n)*C):(W=(G-H[Y])*C,U=-M),t.push([v[Y],W,U]),G=H[Y]}else if("center"===p){e-=H[0]/2,t=[];for(Y=0,b=v.length;Y<b;Y++)(V-H[Y])/2,0===Y?(W=e*C,U=(z-n)*C):(W=(G-H[Y])/2*C,U=-M),t.push([v[Y],W,U]),G=H[Y]}else if("left"===p){t=[];for(Y=0,b=v.length;Y<b;Y++)U=0===Y?(z-n)*C:-M,W=0===Y?e*C:0,t.push(v[Y])}else{if("justify"!==p)throw new Error('Unrecognized alignment option, use "left", "center", "right" or "justify".');t=[];for(S=0!==S?S:N,Y=0,b=v.length;Y<b;Y++)U=0===Y?(z-n)*C:-M,W=0===Y?e*C:0,Y<b-1&&L.push(((S-H[Y])/(v[Y].split(" ").length-1)*C).toFixed(2)),t.push([v[Y],W,U])}}!0===("boolean"==typeof i.R2L?i.R2L:it)&&(t=c(t,function(t,e,n){return[t.split("").reverse().join(""),e,n]}));F={text:t,x:e,y:n,options:i,mutex:{pdfEscape:lt,activeFontKey:tt,fonts:at,activeFontSize:nt}};st.publish("postProcessText",F),t=F.text,r=F.mutex.isHex;v=s(t);t=[];var X,J,K,Q=0,Z=(b=v.length,"");for(Y=0;Y<b;Y++)Z="","[object Array]"!==Object.prototype.toString.call(v[Y])?(X=parseFloat(e*C).toFixed(2),J=parseFloat((z-n)*C).toFixed(2),K=(r?"<":"(")+v[Y]+(r?">":")")):"[object Array]"===Object.prototype.toString.call(v[Y])&&(X=parseFloat(v[Y][1]).toFixed(2),J=parseFloat(v[Y][2]).toFixed(2),K=(r?"<":"(")+v[Y][0]+(r?">":")"),Q=1),void 0!==L&&void 0!==L[Y]&&(Z=L[Y]+" Tw\n"),0!==q.length&&0===Y?t.push(Z+q.join(" ")+" "+X+" "+J+" Tm\n"+K):1===Q||0===Q&&0===Y?t.push(Z+X+" "+J+" Td\n"+K):t.push(Z+K);t=0===Q?t.join(" Tj\nT* "):t.join(" Tj\n"),t+=" Tj\n";var $="BT\n/"+tt+" "+nt+" Tf\n"+(nt*o).toFixed(2)+" TL\n"+et+"\n";return $+=a,$+=t,ct($+="ET"),this},O.lstext=function(t,e,n,r){console.warn("jsPDF.lstext is deprecated");for(var i=0,o=t.length;i<o;i++,e+=r)this.text(t[i],e,n);return this},O.line=function(t,e,n,r){return this.lines([[n-t,r-e]],t,e)},O.clip=function(){ct("W"),ct("S")},O.clip_fixed=function(t){ct("evenodd"===t?"W*":"W"),ct("n")},O.lines=function(t,e,n,r,i,o){var a,s,c,l,h,u,f,d,p,g,m;for("number"==typeof t&&(w=n,n=e,e=t,t=w),r=r||[1,1],ct(L(e*y)+" "+L((v-n)*y)+" m "),a=r[0],s=r[1],l=t.length,g=e,m=n,c=0;c<l;c++)2===(h=t[c]).length?(g=h[0]*a+g,m=h[1]*s+m,ct(L(g*y)+" "+L((v-m)*y)+" l")):(u=h[0]*a+g,f=h[1]*s+m,d=h[2]*a+g,p=h[3]*s+m,g=h[4]*a+g,m=h[5]*s+m,ct(L(u*y)+" "+L((v-f)*y)+" "+L(d*y)+" "+L((v-p)*y)+" "+L(g*y)+" "+L((v-m)*y)+" c"));return o&&ct(" h"),null!==i&&ct(Z(i)),this},O.rect=function(t,e,n,r,i){Z(i);return ct([N(t*y),N((v-e)*y),N(n*y),N(-r*y),"re"].join(" ")),null!==i&&ct(Z(i)),this},O.triangle=function(t,e,n,r,i,o,a){return this.lines([[n-t,r-e],[i-n,o-r],[t-i,e-o]],t,e,[1,1],a,!0),this},O.roundedRect=function(t,e,n,r,i,o,a){var s=4/3*(Math.SQRT2-1);return this.lines([[n-2*i,0],[i*s,0,i,o-o*s,i,o],[0,r-2*o],[0,o*s,-i*s,o,-i,o],[2*i-n,0],[-i*s,0,-i,-o*s,-i,-o],[0,2*o-r],[0,-o*s,i*s,-o,i,-o]],t+i,e,[1,1],a),this},O.ellipse=function(t,e,n,r,i){var o=4/3*(Math.SQRT2-1)*n,a=4/3*(Math.SQRT2-1)*r;return ct([N((t+n)*y),N((v-e)*y),"m",N((t+n)*y),N((v-(e-a))*y),N((t+o)*y),N((v-(e-r))*y),N(t*y),N((v-(e-r))*y),"c"].join(" ")),ct([N((t-o)*y),N((v-(e-r))*y),N((t-n)*y),N((v-(e-a))*y),N((t-n)*y),N((v-e)*y),"c"].join(" ")),ct([N((t-n)*y),N((v-(e+a))*y),N((t-o)*y),N((v-(e+r))*y),N(t*y),N((v-(e+r))*y),"c"].join(" ")),ct([N((t+o)*y),N((v-(e+r))*y),N((t+n)*y),N((v-(e+a))*y),N((t+n)*y),N((v-e)*y),"c"].join(" ")),null!==i&&ct(Z(i)),this},O.circle=function(t,e,n,r){return this.ellipse(t,e,n,n,r)},O.setProperties=function(t){for(var e in P)P.hasOwnProperty(e)&&t[e]&&(P[e]=t[e]);return this},O.setFontSize=function(t){return nt=t,this},O.setFont=function(t,e){return tt=K(t,e),this},O.setFontStyle=O.setFontType=function(t){return tt=K(void 0,t),this},O.getFontList=function(){var t,e,n,r={};for(t in S)if(S.hasOwnProperty(t))for(e in r[t]=n=[],S[t])S[t].hasOwnProperty(e)&&n.push(e);return r},O.addFont=function(t,e,n,r){Y(t,e,n,r=r||"Identity-H")},O.setLineWidth=function(t){return ct((t*y).toFixed(2)+" w"),this},O.setDrawColor=function(t,e,n,r){return ct(j({ch1:t,ch2:e,ch3:n,ch4:r,pdfColorType:"draw",precision:2})),this},O.setFillColor=function(t,e,n,r){return ct(j({ch1:t,ch2:e,ch3:n,ch4:r,pdfColorType:"fill",precision:2})),this},O.setTextColor=function(t,e,n,r){return et=j({ch1:t,ch2:e,ch3:n,ch4:r,pdfColorType:"text",precision:3}),this},O.setCharSpace=function(t){return rt=t,this},O.setR2L=function(t){return it=t,this},O.CapJoinStyles={0:0,butt:0,but:0,miter:0,1:1,round:1,rounded:1,circle:1,2:2,projecting:2,project:2,square:2,bevel:2},O.setLineCap=function(t){var e=this.CapJoinStyles[t];if(void 0===e)throw new Error("Line cap style of '"+t+"' is not recognized. See or extend .CapJoinStyles property for valid styles");return ct((F=e)+" J"),this},O.setLineJoin=function(t){var e=this.CapJoinStyles[t];if(void 0===e)throw new Error("Line join style of '"+t+"' is not recognized. See or extend .CapJoinStyles property for valid styles");return ct((q=e)+" j"),this},O.output=ut,O.save=function(t){O.output("save",t)},wt.API)wt.API.hasOwnProperty(dt)&&("events"===dt&&wt.API.events.length?function(t,e){var n,r,i;for(i=e.length-1;-1!==i;i--)n=e[i][0],r=e[i][1],t.subscribe.apply(t,[n].concat("function"==typeof r?[r]:r))}(st,wt.API.events):O[dt]=wt.API[dt]);return function(){for(var t="helvetica",e="times",n="courier",r="normal",i="bold",o="italic",a="bolditalic",s=[["Helvetica",t,r,"WinAnsiEncoding"],["Helvetica-Bold",t,i,"WinAnsiEncoding"],["Helvetica-Oblique",t,o,"WinAnsiEncoding"],["Helvetica-BoldOblique",t,a,"WinAnsiEncoding"],["Courier",n,r,"WinAnsiEncoding"],["Courier-Bold",n,i,"WinAnsiEncoding"],["Courier-Oblique",n,o,"WinAnsiEncoding"],["Courier-BoldOblique",n,a,"WinAnsiEncoding"],["Times-Roman",e,r,"WinAnsiEncoding"],["Times-Bold",e,i,"WinAnsiEncoding"],["Times-Italic",e,o,"WinAnsiEncoding"],["Times-BoldItalic",e,a,"WinAnsiEncoding"],["ZapfDingbats","zapfdingbats",r,null],["Symbol","symbol",r,null]],c=0,l=s.length;c<l;c++){var h=Y(s[c][0],s[c][1],s[c][2],s[c][3]),u=s[c][0].split("-");G(h,u[0],u[1]||"")}st.publish("addFonts",{fonts:at,dictionary:S})}(),tt="F1",X(n,t),st.publish("initialized"),O}return wt.API={events:[]},wt.version="0.0.0","function"==typeof define&&define.amd?define("jsPDF",function(){return wt}):"undefined"!=typeof module&&module.exports?(module.exports=wt,module.exports.jsPDF=wt):pt.jsPDF=wt,wt}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||"undefined"!=typeof global&&global||Function('return typeof this === "object" && this.content')()||Function("return this")());
+/** @preserve
+   * jsPDF - PDF Document creation from JavaScript
+   * Version 1.4.0 Built on 2018-05-21T16:49:19.312Z
+   *                           CommitID 48c1917315
+   *
+   * Copyright (c) 2010-2016 James Hall <james@parall.ax>, https://github.com/MrRio/jsPDF
+   *               2010 Aaron Spike, https://github.com/acspike
+   *               2012 Willow Systems Corporation, willow-systems.com
+   *               2012 Pablo Hess, https://github.com/pablohess
+   *               2012 Florian Jenett, https://github.com/fjenett
+   *               2013 Warren Weckesser, https://github.com/warrenweckesser
+   *               2013 Youssef Beddad, https://github.com/lifof
+   *               2013 Lee Driscoll, https://github.com/lsdriscoll
+   *               2013 Stefan Slonevskiy, https://github.com/stefslon
+   *               2013 Jeremy Morel, https://github.com/jmorel
+   *               2013 Christoph Hartmann, https://github.com/chris-rock
+   *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
+   *               2014 James Makes, https://github.com/dollaruw
+   *               2014 Diego Casorran, https://github.com/diegocr
+   *               2014 Steven Spungin, https://github.com/Flamenco
+   *               2014 Kenneth Glassey, https://github.com/Gavvers
+   *
+   * Licensed under the MIT License
+   *
+   * Contributor(s):
+   *    siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango,
+   *    kim3er, mfo, alnorth, Flamenco
+   */
+/**
+   * jsPDF AcroForm Plugin
+   * Copyright (c) 2016 Alexander Weidt, https://github.com/BiggA94
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+!function(n,t){var h,a,e=1,r=function(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t},s=function(t){return t*(e/1)},o=function(t,e){return"function"==typeof e.font.metadata.widthOfString?e.font.metadata.widthOfString(t,e.fontSize,e.charSpace):i(function(t,e){var n,r,i,o=(e=e||{}).widths?e.widths:e.font.metadata.Unicode.widths,a=o.fof?o.fof:1,s=e.kerning?e.kerning:e.font.metadata.Unicode.kerning,c=s.fof?s.fof:1,l=0,h=o[0]||a,u=[];for(n=0,r=t.length;n<r;n++)i=t.charCodeAt(n),u.push((o[i]||h)/a+(s[i]&&s[i][l]||0)/c),l=i;return u}(t,e))*e.fontSize};var i=function(t){for(var e=t.length,n=0;e;)n+=t[--e];return n},c=function(t){var e=new T,n=U.internal.getHeight(t)||0,r=U.internal.getWidth(t)||0;return e.BBox=[0,0,r.toFixed(2),n.toFixed(2)],e},l=function(t,e,n){t=t||0;var r=1;if(r<<=e-1,1==(n=n||1))t=t|r;else t=t&~r;return t},u=function(t,e,n){n=n||1.3,t=t||0;return 1==e.readOnly&&(t=l(t,1)),1==e.required&&(t=l(t,2)),1==e.noExport&&(t=l(t,3)),1==e.multiline&&(t=l(t,13)),e.password&&(t=l(t,14)),e.noToggleToOff&&(t=l(t,15)),e.radio&&(t=l(t,16)),e.pushbutton&&(t=l(t,17)),e.combo&&(t=l(t,18)),e.edit&&(t=l(t,19)),e.sort&&(t=l(t,20)),e.fileSelect&&1.4<=n&&(t=l(t,21)),e.multiSelect&&1.4<=n&&(t=l(t,22)),e.doNotSpellCheck&&1.4<=n&&(t=l(t,23)),1==e.doNotScroll&&1.4<=n&&(t=l(t,24)),e.richText&&1.4<=n&&(t=l(t,25)),t},f=function(t){var e=t[0],n=t[1],r=t[2],i=t[3],o={};return Array.isArray(e)?(e[0]=s(e[0]),e[1]=s(e[1]),e[2]=s(e[2]),e[3]=s(e[3])):(e=s(e),n=s(n),r=s(r),i=s(i)),o.lowerLeft_X=e||0,o.lowerLeft_Y=s(a)-n-i||0,o.upperRight_X=e+r||0,o.upperRight_Y=s(a)-n||0,[o.lowerLeft_X.toFixed(2),o.lowerLeft_Y.toFixed(2),o.upperRight_X.toFixed(2),o.upperRight_Y.toFixed(2)]},d=function(t){if(t.appearanceStreamContent)return t.appearanceStreamContent;if(t.V||t.DV){var e=[],n=t.V||t.DV,r=p(t,n);e.push("/Tx BMC"),e.push("q"),e.push("/F1 "+r.fontSize.toFixed(2)+" Tf"),e.push("1 0 0 1 0 0 Tm"),e.push("BT"),e.push(r.text),e.push("ET"),e.push("Q"),e.push("EMC");var i=new c(t);return i.stream=e.join("\n"),i}},p=function(t,e,i,n){n=n||12,i=i||"helvetica";var r={text:"",fontSize:""},o=(e=")"==(e="("==e.substr(0,1)?e.substr(1):e).substr(e.length-1)?e.substr(0,e.length-1):e).split(" "),a=n,s=U.internal.getHeight(t)||0;s=s<0?-s:s;var c=U.internal.getWidth(t)||0;c=c<0?-c:c;var l=function(t,e,n){if(t+1<o.length){var r=e+" "+o[t+1];return C(r,n+"px",i).width<=c-4}return!1};a++;t:for(;;){e="";var h=C("3",--a+"px",i).height,u=t.multiline?s-a:(s-h)/2,f=-2,d=u+=2,p=0,g=0,m=0;if(a<=0){a=12,e="(...) Tj\n",e+="% Width of Text: "+C(e,"1px").width+", FieldWidth:"+c+"\n";break}m=C(o[0]+" ",a+"px",i).width;var y="",w=0;for(var v in o){y=" "==(y+=o[v]+" ").substr(y.length-1)?y.substr(0,y.length-1):y;var b=parseInt(v);m=C(y+" ",a+"px",i).width;var x=l(b,y,a),S=v>=o.length-1;if(!x||S){if(x||S){if(S)g=b;else if(t.multiline&&s<(h+2)*(w+2)+2)continue t}else{if(!t.multiline)continue t;if(s<(h+2)*(w+2)+2)continue t;g=b}for(var k="",_=p;_<=g;_++)k+=o[_]+" ";switch(k=" "==k.substr(k.length-1)?k.substr(0,k.length-1):k,m=C(k,a+"px",i).width,t.Q){case 2:f=c-m-2;break;case 1:f=(c-m)/2;break;case 0:default:f=2}e+=f.toFixed(2)+" "+d.toFixed(2)+" Td\n",e+="("+k+") Tj\n",e+=-f.toFixed(2)+" 0 Td\n",d=-(a+2),m=0,p=g+1,w++,y=""}else y+=" "}break}return r.text=e,r.fontSize=a,r},C=function(t,e,n){n=n||"helvetica";var r=h.internal.getFont(n),i=o(t,{font:r,fontSize:parseFloat(e),charSpace:0});return{height:1.5*o("3",{font:r,fontSize:parseFloat(e),charSpace:0}),width:i}},g={fields:[],xForms:[],acroFormDictionaryRoot:null,printedOut:!1,internal:null,isInitialized:!1},m=function(){for(var t in h.internal.acroformPlugin.acroFormDictionaryRoot.Fields){var e=h.internal.acroformPlugin.acroFormDictionaryRoot.Fields[t];e.hasAnnotation&&w.call(h,e)}},y=function(t){h.internal.acroformPlugin.printedOut&&(h.internal.acroformPlugin.printedOut=!1,h.internal.acroformPlugin.acroFormDictionaryRoot=null),h.internal.acroformPlugin.acroFormDictionaryRoot||k.call(h),h.internal.acroformPlugin.acroFormDictionaryRoot.Fields.push(t)},w=function(t){var e={type:"reference",object:t};h.annotationPlugin.annotations[h.internal.getPageInfo(t.page).pageNumber].push(e)},v=function(){void 0!==h.internal.acroformPlugin.acroFormDictionaryRoot?h.internal.write("/AcroForm "+h.internal.acroformPlugin.acroFormDictionaryRoot.objId+" 0 R"):console.log("Root missing...")},b=function(){h.internal.events.unsubscribe(h.internal.acroformPlugin.acroFormDictionaryRoot._eventID),delete h.internal.acroformPlugin.acroFormDictionaryRoot._eventID,h.internal.acroformPlugin.printedOut=!0},x=function(t){var e=!t;t||(h.internal.newObjectDeferredBegin(h.internal.acroformPlugin.acroFormDictionaryRoot.objId),h.internal.out(h.internal.acroformPlugin.acroFormDictionaryRoot.getString()));t=t||h.internal.acroformPlugin.acroFormDictionaryRoot.Kids;for(var n in t){var r=t[n],i=r.Rect;r.Rect&&(r.Rect=f.call(this,r.Rect)),h.internal.newObjectDeferredBegin(r.objId);var o=r.objId+" 0 obj\n<<\n";if("object"===(void 0===r?"undefined":vt(r))&&"function"==typeof r.getContent&&(o+=r.getContent()),r.Rect=i,r.hasAppearanceStream&&!r.appearanceStreamContent){var a=d.call(this,r);o+="/AP << /N "+a+" >>\n",h.internal.acroformPlugin.xForms.push(a)}if(r.appearanceStreamContent){for(var s in o+="/AP << ",r.appearanceStreamContent){var c=r.appearanceStreamContent[s];if(o+="/"+s+" ",o+="<< ",1<=Object.keys(c).length||Array.isArray(c))for(var n in c){var l;"function"==typeof(l=c[n])&&(l=l.call(this,r)),o+="/"+n+" "+l+" ",0<=h.internal.acroformPlugin.xForms.indexOf(l)||h.internal.acroformPlugin.xForms.push(l)}else"function"==typeof(l=c)&&(l=l.call(this,r)),o+="/"+n+" "+l+" \n",0<=h.internal.acroformPlugin.xForms.indexOf(l)||h.internal.acroformPlugin.xForms.push(l);o+=" >>\n"}o+=">>\n"}o+=">>\nendobj\n",h.internal.out(o)}e&&S.call(this,h.internal.acroformPlugin.xForms)},S=function(t){for(var e in t){var n=e,r=t[e];h.internal.newObjectDeferredBegin(r&&r.objId);var i="";"object"===(void 0===r?"undefined":vt(r))&&"function"==typeof r.getString&&(i=r.getString()),h.internal.out(i),delete t[n]}},k=function(){if(void 0!==this.internal&&(void 0===this.internal.acroformPlugin||!1===this.internal.acroformPlugin.isInitialized)){if(h=this,q.FieldNum=0,this.internal.acroformPlugin=JSON.parse(JSON.stringify(g)),this.internal.acroformPlugin.acroFormDictionaryRoot)throw new Error("Exception while creating AcroformDictionary");e=h.internal.scaleFactor,a=h.internal.pageSize.getHeight(),h.internal.acroformPlugin.acroFormDictionaryRoot=new F,h.internal.acroformPlugin.acroFormDictionaryRoot._eventID=h.internal.events.subscribe("postPutResources",b),h.internal.events.subscribe("buildDocument",m),h.internal.events.subscribe("putCatalog",v),h.internal.events.subscribe("postPutPages",x),h.internal.acroformPlugin.isInitialized=!0}},_=function(t){if(Array.isArray(t)){var e=" [";for(var n in t){e+=t[n].toString(),e+=n<t.length-1?" ":""}return e+="]"}},I=function(t){return 0!==(t=t||"").indexOf("(")&&(t="("+t),")"!=t.substring(t.length-1)&&(t+=")"),t},A=function(){var t;Object.defineProperty(this,"objId",{get:function(){return t||(t=h.internal.newObjectDeferred()),t||console.log("Couldn't create Object ID"),t},configurable:!1})};A.prototype.toString=function(){return this.objId+" 0 R"},A.prototype.getString=function(){var t=this.objId+" 0 obj\n<<";return t+=this.getContent()+">>\n",this.stream&&(t+="stream\n",t+=this.stream,t+="\nendstream\n"),t+="endobj\n"},A.prototype.getContent=function(){var t="";return t+=function(t){var e="",n=Object.keys(t).filter(function(t){return"content"!=t&&"appearanceStreamContent"!=t&&"_"!=t.substring(0,1)});for(var r in n){var i=n[r],o=t[i];o&&(Array.isArray(o)?e+="/"+i+" "+_(o)+"\n":e+=o instanceof A?"/"+i+" "+o.objId+" 0 R\n":"/"+i+" "+o+"\n")}return e}(this)};var T=function(){var e;A.call(this),this.Type="/XObject",this.Subtype="/Form",this.FormType=1,this.BBox,this.Matrix,this.Resources="2 0 R",this.PieceInfo,Object.defineProperty(this,"Length",{enumerable:!0,get:function(){return void 0!==e?e.length:0}}),Object.defineProperty(this,"stream",{enumerable:!1,set:function(t){e=t.trim()},get:function(){return e||null}})};r(T,A);var F=function(){A.call(this);var t=[];Object.defineProperty(this,"Kids",{enumerable:!1,configurable:!0,get:function(){return 0<t.length?t:void 0}}),Object.defineProperty(this,"Fields",{enumerable:!0,configurable:!0,get:function(){return t}}),this.DA};r(F,A);var q=function t(){var e;A.call(this),Object.defineProperty(this,"Rect",{enumerable:!0,configurable:!1,get:function(){if(e)return e},set:function(t){e=t}});var n,r,i,o,a="";Object.defineProperty(this,"FT",{enumerable:!0,set:function(t){a=t},get:function(){return a}}),Object.defineProperty(this,"T",{enumerable:!0,configurable:!1,set:function(t){n=t},get:function(){if(!n||n.length<1){if(this instanceof M)return;return"(FieldObject"+t.FieldNum+++")"}return"("==n.substring(0,1)&&n.substring(n.length-1)?n:"("+n+")"}}),Object.defineProperty(this,"DA",{enumerable:!0,get:function(){if(r)return"("+r+")"},set:function(t){r=t}}),Object.defineProperty(this,"DV",{enumerable:!0,configurable:!0,get:function(){if(i)return i},set:function(t){i=t}}),Object.defineProperty(this,"V",{enumerable:!0,configurable:!0,get:function(){if(o)return o},set:function(t){o=t}}),Object.defineProperty(this,"Type",{enumerable:!0,get:function(){return this.hasAnnotation?"/Annot":null}}),Object.defineProperty(this,"Subtype",{enumerable:!0,get:function(){return this.hasAnnotation?"/Widget":null}}),this.BG,Object.defineProperty(this,"hasAnnotation",{enumerable:!1,get:function(){return!!(this.Rect||this.BC||this.BG)}}),Object.defineProperty(this,"hasAppearanceStream",{enumerable:!1,configurable:!0,writable:!0}),Object.defineProperty(this,"page",{enumerable:!1,configurable:!0,writable:!0})};r(q,A);var E=function(){q.call(this),this.FT="/Ch",this.Opt=[],this.V="()",this.TI=0;var e=!1;Object.defineProperty(this,"combo",{enumerable:!1,get:function(){return e},set:function(t){e=t}}),Object.defineProperty(this,"edit",{enumerable:!0,set:function(t){1==t?(this._edit=!0,this.combo=!0):this._edit=!1},get:function(){return!!this._edit&&this._edit},configurable:!1}),this.hasAppearanceStream=!0};r(E,q);var P=function(){E.call(this),this.combo=!1};r(P,E);var O=function(){P.call(this),this.combo=!0};r(O,P);var B=function(){O.call(this),this.edit=!0};r(B,O);var j=function(){q.call(this),this.FT="/Btn"};r(j,q);var R=function(){j.call(this);var e=!0;Object.defineProperty(this,"pushbutton",{enumerable:!1,get:function(){return e},set:function(t){e=t}})};r(R,j);var D=function(){j.call(this);var e=!0;Object.defineProperty(this,"radio",{enumerable:!1,get:function(){return e},set:function(t){e=t}});var n,t=[];Object.defineProperty(this,"Kids",{enumerable:!0,get:function(){if(0<t.length)return t}}),Object.defineProperty(this,"__Kids",{get:function(){return t}}),Object.defineProperty(this,"noToggleToOff",{enumerable:!1,get:function(){return n},set:function(t){n=t}})};r(D,j);var M=function(t,e){q.call(this),this.Parent=t,this._AppearanceType=U.RadioButton.Circle,this.appearanceStreamContent=this._AppearanceType.createAppearanceStream(e),this.F=l(this.F,3,1),this.MK=this._AppearanceType.createMK(),this.AS="/Off",this._Name=e};r(M,q),D.prototype.setAppearance=function(t){if("createAppearanceStream"in t&&"createMK"in t)for(var e in this.__Kids){var n=this.__Kids[e];n.appearanceStreamContent=t.createAppearanceStream(n._Name),n.MK=t.createMK()}else console.log("Couldn't assign Appearance to RadioButton. Appearance was Invalid!")},D.prototype.createOption=function(t){this.__Kids.length;var e=new M(this,t);return this.__Kids.push(e),n.addField(e),e};var z=function(){j.call(this),this.appearanceStreamContent=U.CheckBox.createAppearanceStream(),this.MK=U.CheckBox.createMK(),this.AS="/On",this.V="/On"};r(z,j);var N=function(){var e,n;q.call(this),this.DA=U.createDefaultAppearanceStream(),this.F=4,Object.defineProperty(this,"V",{get:function(){return e?I(e):e},enumerable:!0,set:function(t){e=t}}),Object.defineProperty(this,"DV",{get:function(){return n?I(n):n},enumerable:!0,set:function(t){n=t}});var r=!1;Object.defineProperty(this,"multiline",{enumerable:!1,get:function(){return r},set:function(t){r=t}});var i=!1;Object.defineProperty(this,"fileSelect",{enumerable:!1,get:function(){return i},set:function(t){i=t}});var o=!1;Object.defineProperty(this,"doNotSpellCheck",{enumerable:!1,get:function(){return o},set:function(t){o=t}});var a=!1;Object.defineProperty(this,"doNotScroll",{enumerable:!1,get:function(){return a},set:function(t){a=t}});var s=!1;Object.defineProperty(this,"MaxLen",{enumerable:!0,get:function(){return s},set:function(t){s=t}}),Object.defineProperty(this,"hasAppearanceStream",{enumerable:!1,get:function(){return this.V||this.DV}})};r(N,q);var L=function(){N.call(this);var e=!0;Object.defineProperty(this,"password",{enumerable:!1,get:function(){return e},set:function(t){e=t}})};r(L,N);var U={CheckBox:{createAppearanceStream:function(){return{N:{On:U.CheckBox.YesNormal},D:{On:U.CheckBox.YesPushDown,Off:U.CheckBox.OffPushDown}}},createMK:function(){return"<< /CA (3)>>"},YesPushDown:function(t){var e=c(t),n=[],r=h.internal.getFont("zapfdingbats","normal").id;t.Q=1;var i=p(t,"3","ZapfDingbats",50);return n.push("0.749023 g"),n.push("0 0 "+U.internal.getWidth(t).toFixed(2)+" "+U.internal.getHeight(t).toFixed(2)+" re"),n.push("f"),n.push("BMC"),n.push("q"),n.push("0 0 1 rg"),n.push("/"+r+" "+i.fontSize.toFixed(2)+" Tf 0 g"),n.push("BT"),n.push(i.text),n.push("ET"),n.push("Q"),n.push("EMC"),e.stream=n.join("\n"),e},YesNormal:function(t){var e=c(t),n=h.internal.getFont("zapfdingbats","normal").id,r=[];t.Q=1;var i=U.internal.getHeight(t),o=U.internal.getWidth(t),a=p(t,"3","ZapfDingbats",.9*i);return r.push("1 g"),r.push("0 0 "+o.toFixed(2)+" "+i.toFixed(2)+" re"),r.push("f"),r.push("q"),r.push("0 0 1 rg"),r.push("0 0 "+(o-1).toFixed(2)+" "+(i-1).toFixed(2)+" re"),r.push("W"),r.push("n"),r.push("0 g"),r.push("BT"),r.push("/"+n+" "+a.fontSize.toFixed(2)+" Tf 0 g"),r.push(a.text),r.push("ET"),r.push("Q"),e.stream=r.join("\n"),e},OffPushDown:function(t){var e=c(t),n=[];return n.push("0.749023 g"),n.push("0 0 "+U.internal.getWidth(t).toFixed(2)+" "+U.internal.getHeight(t).toFixed(2)+" re"),n.push("f"),e.stream=n.join("\n"),e}},RadioButton:{Circle:{createAppearanceStream:function(t){var e={D:{Off:U.RadioButton.Circle.OffPushDown},N:{}};return e.N[t]=U.RadioButton.Circle.YesNormal,e.D[t]=U.RadioButton.Circle.YesPushDown,e},createMK:function(){return"<< /CA (l)>>"},YesNormal:function(t){var e=c(t),n=[],r=U.internal.getWidth(t)<=U.internal.getHeight(t)?U.internal.getWidth(t)/4:U.internal.getHeight(t)/4;r*=.9;var i=U.internal.Bezier_C;return n.push("q"),n.push("1 0 0 1 "+U.internal.getWidth(t)/2+" "+U.internal.getHeight(t)/2+" cm"),n.push(r+" 0 m"),n.push(r+" "+r*i+" "+r*i+" "+r+" 0 "+r+" c"),n.push("-"+r*i+" "+r+" -"+r+" "+r*i+" -"+r+" 0 c"),n.push("-"+r+" -"+r*i+" -"+r*i+" -"+r+" 0 -"+r+" c"),n.push(r*i+" -"+r+" "+r+" -"+r*i+" "+r+" 0 c"),n.push("f"),n.push("Q"),e.stream=n.join("\n"),e},YesPushDown:function(t){var e=c(t),n=[],r=U.internal.getWidth(t)<=U.internal.getHeight(t)?U.internal.getWidth(t)/4:U.internal.getHeight(t)/4,i=2*(r*=.9),o=i*U.internal.Bezier_C,a=r*U.internal.Bezier_C;return n.push("0.749023 g"),n.push("q"),n.push("1 0 0 1 "+(U.internal.getWidth(t)/2).toFixed(2)+" "+(U.internal.getHeight(t)/2).toFixed(2)+" cm"),n.push(i+" 0 m"),n.push(i+" "+o+" "+o+" "+i+" 0 "+i+" c"),n.push("-"+o+" "+i+" -"+i+" "+o+" -"+i+" 0 c"),n.push("-"+i+" -"+o+" -"+o+" -"+i+" 0 -"+i+" c"),n.push(o+" -"+i+" "+i+" -"+o+" "+i+" 0 c"),n.push("f"),n.push("Q"),n.push("0 g"),n.push("q"),n.push("1 0 0 1 "+(U.internal.getWidth(t)/2).toFixed(2)+" "+(U.internal.getHeight(t)/2).toFixed(2)+" cm"),n.push(r+" 0 m"),n.push(r+" "+a+" "+a+" "+r+" 0 "+r+" c"),n.push("-"+a+" "+r+" -"+r+" "+a+" -"+r+" 0 c"),n.push("-"+r+" -"+a+" -"+a+" -"+r+" 0 -"+r+" c"),n.push(a+" -"+r+" "+r+" -"+a+" "+r+" 0 c"),n.push("f"),n.push("Q"),e.stream=n.join("\n"),e},OffPushDown:function(t){var e=c(t),n=[],r=U.internal.getWidth(t)<=U.internal.getHeight(t)?U.internal.getWidth(t)/4:U.internal.getHeight(t)/4,i=2*(r*=.9),o=i*U.internal.Bezier_C;return n.push("0.749023 g"),n.push("q"),n.push("1 0 0 1 "+(U.internal.getWidth(t)/2).toFixed(2)+" "+(U.internal.getHeight(t)/2).toFixed(2)+" cm"),n.push(i+" 0 m"),n.push(i+" "+o+" "+o+" "+i+" 0 "+i+" c"),n.push("-"+o+" "+i+" -"+i+" "+o+" -"+i+" 0 c"),n.push("-"+i+" -"+o+" -"+o+" -"+i+" 0 -"+i+" c"),n.push(o+" -"+i+" "+i+" -"+o+" "+i+" 0 c"),n.push("f"),n.push("Q"),e.stream=n.join("\n"),e}},Cross:{createAppearanceStream:function(t){var e={D:{Off:U.RadioButton.Cross.OffPushDown},N:{}};return e.N[t]=U.RadioButton.Cross.YesNormal,e.D[t]=U.RadioButton.Cross.YesPushDown,e},createMK:function(){return"<< /CA (8)>>"},YesNormal:function(t){var e=c(t),n=[],r=U.internal.calculateCross(t);return n.push("q"),n.push("1 1 "+(U.internal.getWidth(t)-2).toFixed(2)+" "+(U.internal.getHeight(t)-2).toFixed(2)+" re"),n.push("W"),n.push("n"),n.push(r.x1.x.toFixed(2)+" "+r.x1.y.toFixed(2)+" m"),n.push(r.x2.x.toFixed(2)+" "+r.x2.y.toFixed(2)+" l"),n.push(r.x4.x.toFixed(2)+" "+r.x4.y.toFixed(2)+" m"),n.push(r.x3.x.toFixed(2)+" "+r.x3.y.toFixed(2)+" l"),n.push("s"),n.push("Q"),e.stream=n.join("\n"),e},YesPushDown:function(t){var e=c(t),n=U.internal.calculateCross(t),r=[];return r.push("0.749023 g"),r.push("0 0 "+U.internal.getWidth(t).toFixed(2)+" "+U.internal.getHeight(t).toFixed(2)+" re"),r.push("f"),r.push("q"),r.push("1 1 "+(U.internal.getWidth(t)-2).toFixed(2)+" "+(U.internal.getHeight(t)-2).toFixed(2)+" re"),r.push("W"),r.push("n"),r.push(n.x1.x.toFixed(2)+" "+n.x1.y.toFixed(2)+" m"),r.push(n.x2.x.toFixed(2)+" "+n.x2.y.toFixed(2)+" l"),r.push(n.x4.x.toFixed(2)+" "+n.x4.y.toFixed(2)+" m"),r.push(n.x3.x.toFixed(2)+" "+n.x3.y.toFixed(2)+" l"),r.push("s"),r.push("Q"),e.stream=r.join("\n"),e},OffPushDown:function(t){var e=c(t),n=[];return n.push("0.749023 g"),n.push("0 0 "+U.internal.getWidth(t).toFixed(2)+" "+U.internal.getHeight(t).toFixed(2)+" re"),n.push("f"),e.stream=n.join("\n"),e}}},createDefaultAppearanceStream:function(t){return"/F1 0 Tf 0 g"}};U.internal={Bezier_C:.551915024494,calculateCross:function(t){var e,n,r=U.internal.getWidth(t),i=U.internal.getHeight(t),o=(n=i)<(e=r)?n:e;return{x1:{x:(r-o)/2,y:(i-o)/2+o},x2:{x:(r-o)/2+o,y:(i-o)/2},x3:{x:(r-o)/2,y:(i-o)/2},x4:{x:(r-o)/2+o,y:(i-o)/2+o}}}},U.internal.getWidth=function(t){var e=0;return"object"===(void 0===t?"undefined":vt(t))&&(e=s(t.Rect[2])),e},U.internal.getHeight=function(t){var e=0;return"object"===(void 0===t?"undefined":vt(t))&&(e=s(t.Rect[3])),e},n.addField=function(t){return k.call(this),t instanceof N?this.addTextField.call(this,t):t instanceof E?this.addChoiceField.call(this,t):t instanceof j?this.addButton.call(this,t):t instanceof M?y.call(this,t):t&&y.call(this,t),t.page=h.internal.getCurrentPageInfo().pageNumber,this},n.addButton=function(t){k.call(this);var e=t||new q;e.FT="/Btn",e.Ff=u(e.Ff,t,h.internal.getPDFVersion()),y.call(this,e)},n.addTextField=function(t){k.call(this);var e=t||new q;e.FT="/Tx",e.Ff=u(e.Ff,t,h.internal.getPDFVersion()),y.call(this,e)},n.addChoiceField=function(t){k.call(this);var e=t||new q;e.FT="/Ch",e.Ff=u(e.Ff,t,h.internal.getPDFVersion()),y.call(this,e)},"object"==(void 0===t?"undefined":vt(t))&&(t.ChoiceField=E,t.ListBox=P,t.ComboBox=O,t.EditBox=B,t.Button=j,t.PushButton=R,t.RadioButton=D,t.CheckBox=z,t.TextField=N,t.PasswordField=L,t.AcroForm={Appearance:U})}(K.API,"undefined"!=typeof window&&window||"undefined"!=typeof global&&global),K.API.addHTML=function(t,p,g,s,m){if("undefined"==typeof html2canvas&&"undefined"==typeof rasterizeHTML)throw new Error("You need either https://github.com/niklasvh/html2canvas or https://github.com/cburgmer/rasterizeHTML.js");"number"!=typeof p&&(s=p,m=g),"function"==typeof s&&(m=s,s=null),"function"!=typeof m&&(m=function(){});var e=this.internal,y=e.scaleFactor,w=e.pageSize.getWidth(),v=e.pageSize.getHeight();if((s=s||{}).onrendered=function(c){p=parseInt(p)||0,g=parseInt(g)||0;var t=s.dim||{},l=Object.assign({top:0,right:0,bottom:0,left:0,useFor:"content"},s.margin),e=t.h||Math.min(v,c.height/y),h=t.w||Math.min(w,c.width/y)-p,u=s.format||"JPEG",f=s.imageCompression||"SLOW";if(c.height>v-l.top-l.bottom&&s.pagesplit){var d=function(t,e,n,r,i){var o=document.createElement("canvas");o.height=i,o.width=r;var a=o.getContext("2d");return a.mozImageSmoothingEnabled=!1,a.webkitImageSmoothingEnabled=!1,a.msImageSmoothingEnabled=!1,a.imageSmoothingEnabled=!1,a.fillStyle=s.backgroundColor||"#ffffff",a.fillRect(0,0,r,i),a.drawImage(t,e,n,r,i,0,0,r,i),o},n=function(){for(var t,e,n=0,r=0,i={},o=!1;;){var a;if(r=0,i.top=0!==n?l.top:g,i.left=0!==n?l.left:p,o=(w-l.left-l.right)*y<c.width,"content"===l.useFor?0===n?(t=Math.min((w-l.left)*y,c.width),e=Math.min((v-l.top)*y,c.height-n)):(t=Math.min(w*y,c.width),e=Math.min(v*y,c.height-n),i.top=0):(t=Math.min((w-l.left-l.right)*y,c.width),e=Math.min((v-l.bottom-l.top)*y,c.height-n)),o)for(;;){"content"===l.useFor&&(0===r?t=Math.min((w-l.left)*y,c.width):(t=Math.min(w*y,c.width-r),i.left=0));var s=[a=d(c,r,n,t,e),i.left,i.top,a.width/y,a.height/y,u,null,f];if(this.addImage.apply(this,s),(r+=t)>=c.width)break;this.addPage()}else s=[a=d(c,0,n,t,e),i.left,i.top,a.width/y,a.height/y,u,null,f],this.addImage.apply(this,s);if((n+=e)>=c.height)break;this.addPage()}m(h,n,null,s)}.bind(this);if("CANVAS"===c.nodeName){var r=new Image;r.onload=n,r.src=c.toDataURL("image/png"),c=r}else n()}else{var i=Math.random().toString(35),o=[c,p,g,h,e,u,i,f];this.addImage.apply(this,o),m(h,e,i,o)}}.bind(this),"undefined"!=typeof html2canvas&&!s.rstz)return html2canvas(t,s);if("undefined"!=typeof rasterizeHTML){var n="drawDocument";return"string"==typeof t&&(n=/^http/.test(t)?"drawURL":"drawHTML"),s.width=s.width||w*y,rasterizeHTML[n](t,void 0,s).then(function(t){s.onrendered(t.image)},function(t){m(null,t)})}return null},
+/** @preserve
+   * jsPDF addImage plugin
+   * Copyright (c) 2012 Jason Siefken, https://github.com/siefkenj/
+   *               2013 Chris Dowling, https://github.com/gingerchris
+   *               2013 Trinh Ho, https://github.com/ineedfat
+   *               2013 Edwin Alejandro Perez, https://github.com/eaparango
+   *               2013 Norah Smith, https://github.com/burnburnrocket
+   *               2014 Diego Casorran, https://github.com/diegocr
+   *               2014 James Robb, https://github.com/jamesbrobb
+   *
+   * 
+   */
+function(b){var x="addImage_",s={PNG:[[137,80,78,71]],TIFF:[[77,77,0,42],[73,73,42,0]],JPEG:[[255,216,255,224,void 0,void 0,74,70,73,70,0],[255,216,255,225,void 0,void 0,69,120,105,102,0,0]],JPEG2000:[[0,0,0,12,106,80,32,32]],GIF87a:[[71,73,70,56,55,97]],GIF89a:[[71,73,70,56,57,97]],BMP:[[66,77],[66,65],[67,73],[67,80],[73,67],[80,84]]};b.getImageFileTypeByImageData=function(t){var e,n,r,i,o,a="UNKNOWN";for(o in s)for(r=s[o],e=0;e<r.length;e+=1){for(i=!0,n=0;n<r[e].length;n+=1)if(void 0!==r[e][n]&&r[e][n]!==t.charCodeAt(n)){i=!1;break}if(!0===i){a=o;break}}return a};var n=function t(e){var n=this.internal.newObject(),r=this.internal.write,i=this.internal.putStream;if(e.n=n,r("<</Type /XObject"),r("/Subtype /Image"),r("/Width "+e.w),r("/Height "+e.h),e.cs===this.color_spaces.INDEXED?r("/ColorSpace [/Indexed /DeviceRGB "+(e.pal.length/3-1)+" "+("smask"in e?n+2:n+1)+" 0 R]"):(r("/ColorSpace /"+e.cs),e.cs===this.color_spaces.DEVICE_CMYK&&r("/Decode [1 0 1 0 1 0 1 0]")),r("/BitsPerComponent "+e.bpc),"f"in e&&r("/Filter /"+e.f),"dp"in e&&r("/DecodeParms <<"+e.dp+">>"),"trns"in e&&e.trns.constructor==Array){for(var o="",a=0,s=e.trns.length;a<s;a++)o+=e.trns[a]+" "+e.trns[a]+" ";r("/Mask ["+o+"]")}if("smask"in e&&r("/SMask "+(n+1)+" 0 R"),r("/Length "+e.data.length+">>"),i(e.data),r("endobj"),"smask"in e){var c="/Predictor "+e.p+" /Colors 1 /BitsPerComponent "+e.bpc+" /Columns "+e.w,l={w:e.w,h:e.h,cs:"DeviceGray",bpc:e.bpc,dp:c,data:e.smask};"f"in e&&(l.f=e.f),t.call(this,l)}e.cs===this.color_spaces.INDEXED&&(this.internal.newObject(),r("<< /Length "+e.pal.length+">>"),i(this.arrayBufferToBinaryString(new Uint8Array(e.pal))),r("endobj"))},S=function(){var t=this.internal.collections[x+"images"];for(var e in t)n.call(this,t[e])},k=function(){var t,e=this.internal.collections[x+"images"],n=this.internal.write;for(var r in e)n("/I"+(t=e[r]).i,t.n,"0","R")},_=function(t){return"function"==typeof b["process"+t.toUpperCase()]},C=function(t){return"object"===(void 0===t?"undefined":vt(t))&&1===t.nodeType},I=function(t,e){if("IMG"===t.nodeName&&t.hasAttribute("src")){var n=""+t.getAttribute("src");if(0===n.indexOf("data:image/"))return n;!e&&/\.png(?:[?#].*)?$/i.test(n)&&(e="png")}if("CANVAS"===t.nodeName)var r=t;else{(r=document.createElement("canvas")).width=t.clientWidth||t.width,r.height=t.clientHeight||t.height;var i=r.getContext("2d");if(!i)throw"addImage requires canvas to be supported by browser.";i.drawImage(t,0,0,r.width,r.height)}return r.toDataURL("png"==(""+e).toLowerCase()?"image/png":"image/jpeg")},A=function(t,e){var n;if(e)for(var r in e)if(t===e[r].alias){n=e[r];break}return n};b.color_spaces={DEVICE_RGB:"DeviceRGB",DEVICE_GRAY:"DeviceGray",DEVICE_CMYK:"DeviceCMYK",CAL_GREY:"CalGray",CAL_RGB:"CalRGB",LAB:"Lab",ICC_BASED:"ICCBased",INDEXED:"Indexed",PATTERN:"Pattern",SEPARATION:"Separation",DEVICE_N:"DeviceN"},b.decode={DCT_DECODE:"DCTDecode",FLATE_DECODE:"FlateDecode",LZW_DECODE:"LZWDecode",JPX_DECODE:"JPXDecode",JBIG2_DECODE:"JBIG2Decode",ASCII85_DECODE:"ASCII85Decode",ASCII_HEX_DECODE:"ASCIIHexDecode",RUN_LENGTH_DECODE:"RunLengthDecode",CCITT_FAX_DECODE:"CCITTFaxDecode"},b.image_compression={NONE:"NONE",FAST:"FAST",MEDIUM:"MEDIUM",SLOW:"SLOW"},b.sHashCode=function(t){return t=t||"",Array.prototype.reduce&&t.split("").reduce(function(t,e){return(t=(t<<5)-t+e.charCodeAt(0))&t},0)},b.isString=function(t){return"string"==typeof t},b.validateStringAsBase64=function(t){return t=t||"",new RegExp("(?:^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$)").test(t)},b.extractInfoFromBase64DataURI=function(t){return/^data:([\w]+?\/([\w]+?));base64,(.+?)$/g.exec(t)},b.supportsArrayBuffer=function(){return"undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array},b.isArrayBuffer=function(t){return!!this.supportsArrayBuffer()&&t instanceof ArrayBuffer},b.isArrayBufferView=function(t){return!!this.supportsArrayBuffer()&&("undefined"!=typeof Uint32Array&&(t instanceof Int8Array||t instanceof Uint8Array||"undefined"!=typeof Uint8ClampedArray&&t instanceof Uint8ClampedArray||t instanceof Int16Array||t instanceof Uint16Array||t instanceof Int32Array||t instanceof Uint32Array||t instanceof Float32Array||t instanceof Float64Array))},b.binaryStringToUint8Array=function(t){for(var e=t.length,n=new Uint8Array(e),r=0;r<e;r++)n[r]=t.charCodeAt(r);return n},b.arrayBufferToBinaryString=function(t){if("function"==typeof atob)return atob(this.arrayBufferToBase64(t));if("function"==typeof TextDecoder){var e=new TextDecoder("ascii");if("ascii"===e.encoding)return e.decode(t)}for(var n=this.isArrayBuffer(t)?t:new Uint8Array(t),r=20480,i="",o=Math.ceil(n.byteLength/r),a=0;a<o;a++)i+=String.fromCharCode.apply(null,n.slice(a*r,a*r+r));return i},b.arrayBufferToBase64=function(t){for(var e,n="",r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=new Uint8Array(t),o=i.byteLength,a=o%3,s=o-a,c=0;c<s;c+=3)n+=r[(16515072&(e=i[c]<<16|i[c+1]<<8|i[c+2]))>>18]+r[(258048&e)>>12]+r[(4032&e)>>6]+r[63&e];return 1==a?n+=r[(252&(e=i[s]))>>2]+r[(3&e)<<4]+"==":2==a&&(n+=r[(64512&(e=i[s]<<8|i[s+1]))>>10]+r[(1008&e)>>4]+r[(15&e)<<2]+"="),n},b.createImageInfo=function(t,e,n,r,i,o,a,s,c,l,h,u,f){var d={alias:s,w:e,h:n,cs:r,bpc:i,i:a,data:t};return o&&(d.f=o),c&&(d.dp=c),l&&(d.trns=l),h&&(d.pal=h),u&&(d.smask=u),f&&(d.p=f),d},b.addImage=function(t,e,n,r,i,o,a,s,c){var l="";if("string"!=typeof e){var h=o;o=i,i=r,r=n,n=e,e=h}if("object"===(void 0===t?"undefined":vt(t))&&!C(t)&&"imageData"in t){var u=t;t=u.imageData,e=u.format||e,n=u.x||n||0,r=u.y||r||0,i=u.w||i,o=u.h||o,a=u.alias||a,s=u.compression||s,c=u.rotation||u.angle||c}if(isNaN(n)||isNaN(r))throw console.error("jsPDF.addImage: Invalid coordinates",arguments),new Error("Invalid coordinates passed to jsPDF.addImage");var f,d,p,g,m,y,w,v=function(){var t=this.internal.collections[x+"images"];return t||(this.internal.collections[x+"images"]=t={},this.internal.events.subscribe("putResources",S),this.internal.events.subscribe("putXobjectDict",k)),t}.call(this);if(!(f=A(t,v))&&(C(t)&&(t=I(t,e)),(null==(w=a)||0===w.length)&&(a="string"==typeof(y=t)&&b.sHashCode(y)),!(f=A(a,v)))){if(this.isString(t)&&(""!==(l=this.convertStringToImageData(t))?t=l:void 0!==(l=this.loadImageFile(t))&&(t=l)),e=this.getImageFileTypeByImageData(t),!_(e))throw new Error("addImage does not support files of type '"+e+"', please ensure that a plugin for '"+e+"' support is added.");if(this.supportsArrayBuffer()&&(t instanceof Uint8Array||(d=t,t=this.binaryStringToUint8Array(t))),!(f=this["process"+e.toUpperCase()](t,(m=0,(g=v)&&(m=Object.keys?Object.keys(g).length:function(t){var e=0;for(var n in t)t.hasOwnProperty(n)&&e++;return e}(g)),m),a,((p=s)&&"string"==typeof p&&(p=p.toUpperCase()),p in b.image_compression?p:b.image_compression.NONE),d)))throw new Error("An unkwown error occurred whilst processing the image")}return function(t,e,n,r,i,o,a,s){var c=function(t,e,n){return t||e||(e=t=-96),t<0&&(t=-1*n.w*72/t/this.internal.scaleFactor),e<0&&(e=-1*n.h*72/e/this.internal.scaleFactor),0===t&&(t=e*n.w/n.h),0===e&&(e=t*n.h/n.w),[t,e]}.call(this,n,r,i),l=this.internal.getCoordinateString,h=this.internal.getVerticalCoordinateString;if(n=c[0],r=c[1],a[o]=i,s){s*=Math.PI/180;var u=Math.cos(s),f=Math.sin(s),d=function(t){return t.toFixed(4)},p=[d(u),d(f),d(-1*f),d(u),0,0,"cm"]}this.internal.write("q"),s?(this.internal.write([1,"0","0",1,l(t),h(e+r),"cm"].join(" ")),this.internal.write(p.join(" ")),this.internal.write([l(n),"0","0",l(r),"0","0","cm"].join(" "))):this.internal.write([l(n),"0","0",l(r),l(t),h(e+r),"cm"].join(" ")),this.internal.write("/I"+i.i+" Do"),this.internal.write("Q")}.call(this,n,r,i,o,f,f.i,v,c),this},b.convertStringToImageData=function(t){var e,n="";this.isString(t)&&(null!==(e=this.extractInfoFromBase64DataURI(t))?b.validateStringAsBase64(e[3])&&(n=atob(e[3])):b.validateStringAsBase64(t)&&(n=atob(t)));return n};var c=function(t,e){return t.subarray(e,e+5)};b.processJPEG=function(t,e,n,r,i,o){var a,s=this.decode.DCT_DECODE;if(!this.isString(t)&&!this.isArrayBuffer(t)&&!this.isArrayBufferView(t))return null;if(this.isString(t)&&(a=function(t){var e;if(255===!t.charCodeAt(0)||216===!t.charCodeAt(1)||255===!t.charCodeAt(2)||224===!t.charCodeAt(3)||!t.charCodeAt(6)==="J".charCodeAt(0)||!t.charCodeAt(7)==="F".charCodeAt(0)||!t.charCodeAt(8)==="I".charCodeAt(0)||!t.charCodeAt(9)==="F".charCodeAt(0)||0===!t.charCodeAt(10))throw new Error("getJpegSize requires a binary string jpeg file");for(var n=256*t.charCodeAt(4)+t.charCodeAt(5),r=4,i=t.length;r<i;){if(r+=n,255!==t.charCodeAt(r))throw new Error("getJpegSize could not find the size of the image");if(192===t.charCodeAt(r+1)||193===t.charCodeAt(r+1)||194===t.charCodeAt(r+1)||195===t.charCodeAt(r+1)||196===t.charCodeAt(r+1)||197===t.charCodeAt(r+1)||198===t.charCodeAt(r+1)||199===t.charCodeAt(r+1))return e=256*t.charCodeAt(r+5)+t.charCodeAt(r+6),[256*t.charCodeAt(r+7)+t.charCodeAt(r+8),e,t.charCodeAt(r+9)];r+=2,n=256*t.charCodeAt(r)+t.charCodeAt(r+1)}}(t)),this.isArrayBuffer(t)&&(t=new Uint8Array(t)),this.isArrayBufferView(t)&&(a=function(t){if(65496!=(t[0]<<8|t[1]))throw new Error("Supplied data is not a JPEG");for(var e,n=t.length,r=(t[4]<<8)+t[5],i=4;i<n;){if(r=((e=c(t,i+=r))[2]<<8)+e[3],(192===e[1]||194===e[1])&&255===e[0]&&7<r)return{width:((e=c(t,i+5))[2]<<8)+e[3],height:(e[0]<<8)+e[1],numcomponents:e[4]};i+=2}throw new Error("getJpegSizeFromBytes could not find the size of the image")}(t),t=i||this.arrayBufferToBinaryString(t)),void 0===o)switch(a.numcomponents){case 1:o=this.color_spaces.DEVICE_GRAY;break;case 4:o=this.color_spaces.DEVICE_CMYK;break;default:case 3:o=this.color_spaces.DEVICE_RGB}return this.createImageInfo(t,a.width,a.height,o,8,s,e,n)},b.processJPG=function(){return this.processJPEG.apply(this,arguments)},b.loadImageFile=function(t,e,n){e=e||!0,n=n||function(){};var r="[object process]"===Object.prototype.toString.call("undefined"!=typeof process?process:0);return void 0!==("undefined"==typeof window?"undefined":vt(window))&&"object"===("undefined"==typeof location?"undefined":vt(location))&&"http"===location.protocol.substr(0,4)?function(t,e,n){var r=new XMLHttpRequest,i=[],o=0,a=function(t){var e=t.length,n=String.fromCharCode;for(o=0;o<e;o+=1)i.push(n(255&t.charCodeAt(o)));return i.join("")};if(r.open("GET",t,!e),r.overrideMimeType("text/plain; charset=x-user-defined"),!1===e&&(r.onload=function(){return a(this.responseText)}),r.send(null),200===r.status)return e?a(r.responseText):void 0;console.warn('Unable to load file "'+t+'"')}(t,e):r?function(t,e,n){e=e||!0;var r=require("fs");if(!0===e)return r.readFileSync(t).toString();r.readFile("image.jpg",function(t,e){n(e)})}(t,e,n):void 0},b.getImageProperties=function(t){var e,n,r="";if(C(t)&&(t=I(t)),this.isString(t)&&(""!==(r=this.convertStringToImageData(t))?t=r:void 0!==(r=this.loadImageFile(t))&&(t=r)),n=this.getImageFileTypeByImageData(t),!_(n))throw new Error("addImage does not support files of type '"+n+"', please ensure that a plugin for '"+n+"' support is added.");if(this.supportsArrayBuffer()&&(t instanceof Uint8Array||(t=this.binaryStringToUint8Array(t))),!(e=this["process"+n.toUpperCase()](t)))throw new Error("An unkwown error occurred whilst processing the image");return{fileType:n,width:e.w,height:e.h,colorSpace:e.cs,compressionMode:e.f,bitsPerComponent:e.bpc}}}(K.API),
+/**
+   * jsPDF Annotations PlugIn
+   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+t=K.API,w={annotations:[],f2:function(t){return t.toFixed(2)},notEmpty:function(t){if(void 0!==t&&""!=t)return!0}},K.API.annotationPlugin=w,K.API.events.push(["addPage",function(t){this.annotationPlugin.annotations[t.pageNumber]=[]}]),t.events.push(["putPage",function(t){for(var e=this.annotationPlugin.annotations[t.pageNumber],n=!1,r=0;r<e.length&&!n;r++)switch((c=e[r]).type){case"link":if(w.notEmpty(c.options.url)||w.notEmpty(c.options.pageNumber)){n=!0;break}case"reference":case"text":case"freetext":n=!0}if(0!=n){this.internal.write("/Annots [");var i=this.annotationPlugin.f2,o=this.internal.scaleFactor,a=this.internal.pageSize.getHeight(),s=this.internal.getPageInfo(t.pageNumber);for(r=0;r<e.length;r++){var c;switch((c=e[r]).type){case"reference":this.internal.write(" "+c.object.objId+" 0 R ");break;case"text":var l=this.internal.newAdditionalObject(),h=this.internal.newAdditionalObject(),u=c.title||"Note";m="<</Type /Annot /Subtype /Text "+(d="/Rect ["+i(c.bounds.x*o)+" "+i(a-(c.bounds.y+c.bounds.h)*o)+" "+i((c.bounds.x+c.bounds.w)*o)+" "+i((a-c.bounds.y)*o)+"] ")+"/Contents ("+c.contents+")",m+=" /Popup "+h.objId+" 0 R",m+=" /P "+s.objId+" 0 R",m+=" /T ("+u+") >>",l.content=m;var f=l.objId+" 0 R";m="<</Type /Annot /Subtype /Popup "+(d="/Rect ["+i((c.bounds.x+30)*o)+" "+i(a-(c.bounds.y+c.bounds.h)*o)+" "+i((c.bounds.x+c.bounds.w+30)*o)+" "+i((a-c.bounds.y)*o)+"] ")+" /Parent "+f,c.open&&(m+=" /Open true"),m+=" >>",h.content=m,this.internal.write(l.objId,"0 R",h.objId,"0 R");break;case"freetext":var d="/Rect ["+i(c.bounds.x*o)+" "+i((a-c.bounds.y)*o)+" "+i(c.bounds.x+c.bounds.w*o)+" "+i(a-(c.bounds.y+c.bounds.h)*o)+"] ",p=c.color||"#000000";m="<</Type /Annot /Subtype /FreeText "+d+"/Contents ("+c.contents+")",m+=" /DS(font: Helvetica,sans-serif 12.0pt; text-align:left; color:#"+p+")",m+=" /Border [0 0 0]",m+=" >>",this.internal.write(m);break;case"link":if(c.options.name){var g=this.annotations._nameMap[c.options.name];c.options.pageNumber=g.page,c.options.top=g.y}else c.options.top||(c.options.top=0);d="/Rect ["+i(c.x*o)+" "+i((a-c.y)*o)+" "+i((c.x+c.w)*o)+" "+i((a-(c.y+c.h))*o)+"] ";var m="";if(c.options.url)m="<</Type /Annot /Subtype /Link "+d+"/Border [0 0 0] /A <</S /URI /URI ("+c.options.url+") >>";else if(c.options.pageNumber)switch(m="<</Type /Annot /Subtype /Link "+d+"/Border [0 0 0] /Dest ["+(t=this.internal.getPageInfo(c.options.pageNumber)).objId+" 0 R",c.options.magFactor=c.options.magFactor||"XYZ",c.options.magFactor){case"Fit":m+=" /Fit]";break;case"FitH":m+=" /FitH "+c.options.top+"]";break;case"FitV":c.options.left=c.options.left||0,m+=" /FitV "+c.options.left+"]";break;case"XYZ":default:var y=i((a-c.options.top)*o);c.options.left=c.options.left||0,void 0===c.options.zoom&&(c.options.zoom=0),m+=" /XYZ "+c.options.left+" "+y+" "+c.options.zoom+"]"}""!=m&&(m+=" >>",this.internal.write(m))}}this.internal.write("]")}}]),t.createAnnotation=function(t){switch(t.type){case"link":this.link(t.bounds.x,t.bounds.y,t.bounds.w,t.bounds.h,t);break;case"text":case"freetext":this.annotationPlugin.annotations[this.internal.getCurrentPageInfo().pageNumber].push(t)}},t.link=function(t,e,n,r,i){this.annotationPlugin.annotations[this.internal.getCurrentPageInfo().pageNumber].push({x:t,y:e,w:n,h:r,options:i,type:"link"})},t.textWithLink=function(t,e,n,r){var i=this.getTextWidth(t),o=this.internal.getLineHeight()/this.internal.scaleFactor;return this.text(t,e,n),n+=.2*o,this.link(e,n-o,i,o,r),i},t.getTextWidth=function(t){var e=this.internal.getFontSize();return this.getStringUnitWidth(t)*e/this.internal.scaleFactor},t.getLineHeight=function(){return this.internal.getLineHeight()},function(t){var a=Object.keys({ar:"Arabic (Standard)","ar-DZ":"Arabic (Algeria)","ar-BH":"Arabic (Bahrain)","ar-EG":"Arabic (Egypt)","ar-IQ":"Arabic (Iraq)","ar-JO":"Arabic (Jordan)","ar-KW":"Arabic (Kuwait)","ar-LB":"Arabic (Lebanon)","ar-LY":"Arabic (Libya)","ar-MA":"Arabic (Morocco)","ar-OM":"Arabic (Oman)","ar-QA":"Arabic (Qatar)","ar-SA":"Arabic (Saudi Arabia)","ar-SY":"Arabic (Syria)","ar-TN":"Arabic (Tunisia)","ar-AE":"Arabic (U.A.E.)","ar-YE":"Arabic (Yemen)",fa:"Persian","fa-IR":"Persian/Iran",ur:"Urdu"}),l={1569:[65152],1570:[65153,65154,65153,65154],1571:[65155,65156,65155,65156],1572:[65157,65158],1573:[65159,65160,65159,65160],1574:[65161,65162,65163,65164],1575:[65165,65166,65165,65166],1576:[65167,65168,65169,65170],1577:[65171,65172],1578:[65173,65174,65175,65176],1579:[65177,65178,65179,65180],1580:[65181,65182,65183,65184],1581:[65185,65186,65187,65188],1582:[65189,65190,65191,65192],1583:[65193,65194,65193,65194],1584:[65195,65196,65195,65196],1585:[65197,65198,65197,65198],1586:[65199,65200,65199,65200],1587:[65201,65202,65203,65204],1588:[65205,65206,65207,65208],1589:[65209,65210,65211,65212],1590:[65213,65214,65215,65216],1591:[65217,65218,65219,65220],1592:[65221,65222,65223,65224],1593:[65225,65226,65227,65228],1594:[65229,65230,65231,65232],1601:[65233,65234,65235,65236],1602:[65237,65238,65239,65240],1603:[65241,65242,65243,65244],1604:[65245,65246,65247,65248],1605:[65249,65250,65251,65252],1606:[65253,65254,65255,65256],1607:[65257,65258,65259,65260],1608:[65261,65262,65261,65262],1609:[65263,65264,64488,64489],1610:[65265,65266,65267,65268],1649:[64336,64337],1655:[64477],1657:[64358,64359,64360,64361],1658:[64350,64351,64352,64353],1659:[64338,64339,64340,64341],1662:[64342,64343,64344,64345],1663:[64354,64355,64356,64357],1664:[64346,64347,64348,64349],1667:[64374,64375,64376,64377],1668:[64370,64371,64372,64373],1670:[64378,64379,64380,64381],1671:[64382,64383,64384,64385],1672:[64392,64393],1676:[64388,64389],1677:[64386,64387],1678:[64390,64391],1681:[64396,64397],1688:[64394,64395,64394,64395],1700:[64362,64363,64364,64365],1702:[64366,64367,64368,64369],1705:[64398,64399,64400,64401],1709:[64467,64468,64469,64470],1711:[64402,64403,64404,64405],1713:[64410,64411,64412,64413],1715:[64406,64407,64408,64409],1722:[64414,64415],1723:[64416,64417,64418,64419],1726:[64426,64427,64428,64429],1728:[64420,64421],1729:[64422,64423,64424,64425],1733:[64480,64481],1734:[64473,64474],1735:[64471,64472],1736:[64475,64476],1737:[64482,64483],1739:[64478,64479],1740:[64508,64509,64510,64511],1744:[64484,64485,64486,64487],1746:[64430,64431],1747:[64432,64433]},h={1570:[65269,65270,65269,65270],1571:[65271,65272,65271,65272],1573:[65273,65274,65273,65274],1575:[65275,65276,65275,65276]},u={1570:[65153,65154,65153,65154],1571:[65155,65156,65155,65156],1573:[65159,65160,65159,65160],1575:[65165,65166,65165,65166]},f={1612:64606,1613:64607,1614:64608,1615:64609,1616:64610},e=[1570,1571,1573,1575],n=[1569,1570,1571,1572,1573,1575,1577,1583,1584,1585,1586,1608,1688],o=0,s=1,c=2,d=3;function p(t){return void 0!==t&&void 0!==l[t.charCodeAt(0)]}function g(t){return void 0!==t&&0<=n.indexOf(t.charCodeAt(0))}function m(t){return void 0!==t&&0<=e.indexOf(t.charCodeAt(0))}function y(t){return p(t)&&2<=l[t.charCodeAt(0)].length}function w(t,e,n,r){return p(t)?(r=r||{},l=Object.assign(l,r),!y(t)||!p(e)&&!p(n)||!p(n)&&g(e)||g(t)&&!p(e)||g(t)&&m(e)?(l=Object.assign(l,u),o):p(i=t)&&4==l[i.charCodeAt(0)].length&&p(e)&&!g(e)&&p(n)&&y(n)?(l=Object.assign(l,u),d):g(t)||!p(n)?(l=Object.assign(l,u),s):(l=Object.assign(l,u),c)):-1;var i}function v(t){t=t||"";var e,n,r="",i=0,o=0,a="",s="",c="";for(i=0;i<t.length;i+=1)a=t[i],s=t[i-1],c=t[i+1],p(a)?void 0!==s&&1604===s.charCodeAt(0)&&m(a)?(o=w(a,t[i-2],t[i+1],h),e=String.fromCharCode(h[a.charCodeAt(0)][o]),r=r.substr(0,r.length-1)+e):void 0!==s&&1617===s.charCodeAt(0)&&(void 0!==(n=a)&&void 0!==f[n.charCodeAt(0)])?(o=w(a,t[i-2],t[i+1],u),e=String.fromCharCode(f[a.charCodeAt(0)][o]),r=r.substr(0,r.length-1)+e):(o=w(a,s,c,u),r+=String.fromCharCode(l[a.charCodeAt(0)][o])):r+=a;return r.split("").reverse().join("")}t.events.push(["preProcessText",function(t){var e=t.text,n=(t.x,t.y,t.options||{}),r=(t.mutex,n.lang),i=[];if(0<=a.indexOf(r)){if("[object Array]"===Object.prototype.toString.call(e)){var o=0;for(i=[],o=0;o<e.length;o+=1)"[object Array]"===Object.prototype.toString.call(e[o])?i.push([v(e[o][0]),e[o][1],e[o][2]]):i.push([v(e[o])]);t.text=i}else t.text=v(e);void 0===n.charSpace&&(t.options.charSpace=0),!0===n.R2L&&(t.options.R2L=!1)}}])}(K.API),K.API.autoPrint=function(t){var e;switch((t=t||{}).variant=t.variant||"non-conform",t.variant){case"javascript":this.addJS("print({});");break;case"non-conform":default:this.internal.events.subscribe("postPutResources",function(){e=this.internal.newObject(),this.internal.out("<<"),this.internal.out("/S /Named"),this.internal.out("/Type /Action"),this.internal.out("/N /Print"),this.internal.out(">>"),this.internal.out("endobj")}),this.internal.events.subscribe("putCatalog",function(){this.internal.out("/OpenAction "+e+" 0 R")})}return this},(
+/**
+   * jsPDF Canvas PlugIn
+   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+e=K.API).events.push(["initialized",function(){this.canvas.pdf=this}]),e.canvas={getContext:function(t){return(this.pdf.context2d._canvas=this).pdf.context2d},style:{}},Object.defineProperty(e.canvas,"width",{get:function(){return this._width},set:function(t){this._width=t,this.getContext("2d").pageWrapX=t+1}}),Object.defineProperty(e.canvas,"height",{get:function(){return this._height},set:function(t){this._height=t,this.getContext("2d").pageWrapY=t+1}}),
+/** ====================================================================
+   * jsPDF Cell plugin
+   * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
+   *               2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
+   *               2013 Lee Driscoll, https://github.com/lsdriscoll
+   *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
+   *               2014 James Hall, james@parall.ax
+   *               2014 Diego Casorran, https://github.com/diegocr
+   *
+   * 
+   * ====================================================================
+   */
+I=K.API,A={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},T=1,d=function(t,e,n,r,i){A={x:t,y:e,w:n,h:r,ln:i}},p=function(){return A},F={left:0,top:0,bottom:0},I.setHeaderFunction=function(t){c=t},I.getTextDimensions=function(e){i=this.internal.getFont().fontName,o=this.table_font_size||this.internal.getFontSize(),a=this.internal.getFont().fontStyle;var t,n,r=19.049976/25.4;(n=document.createElement("font")).id="jsPDFCell";try{n.style.fontStyle=a}catch(t){n.style.fontWeight=a}n.style.fontSize=o+"pt",n.style.fontFamily=i;try{n.textContent=e}catch(t){n.innerText=e}return document.body.appendChild(n),t={w:(n.offsetWidth+1)*r,h:(n.offsetHeight+1)*r},document.body.removeChild(n),t},I.cellAddPage=function(){var t=this.margins||F;this.addPage(),d(t.left,t.top,void 0,void 0),T+=1},I.cellInitialize=function(){A={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},T=1},I.cell=function(t,e,n,r,i,o,a){var s=p(),c=!1;if(void 0!==s.ln)if(s.ln===o)t=s.x+s.w,e=s.y;else{var l=this.margins||F;s.y+s.h+r+13>=this.internal.pageSize.getHeight()-l.bottom&&(this.cellAddPage(),c=!0,this.printHeaders&&this.tableHeaderRow&&this.printHeaderRow(o,!0)),e=p().y+p().h,c&&(e=23)}if(void 0!==i[0])if(this.printingHeaderRow?this.rect(t,e,n,r,"FD"):this.rect(t,e,n,r),"right"===a){i instanceof Array||(i=[i]);for(var h=0;h<i.length;h++){var u=i[h],f=this.getStringUnitWidth(u)*this.internal.getFontSize();this.text(u,t+n-f-3,e+this.internal.getLineHeight()*(h+1))}}else this.text(i,t+3,e+this.internal.getLineHeight());return d(t,e,n,r,o),this},I.arrayMax=function(t,e){var n,r,i,o=t[0];for(n=0,r=t.length;n<r;n+=1)i=t[n],e?-1===e(o,i)&&(o=i):o<i&&(o=i);return o},I.table=function(t,e,n,r,i){if(!n)throw"No data for PDF table";var o,a,s,c,l,h,u,f,d,p,g=[],m=[],y={},w={},v=[],b=[],x=!1,S=!0,k=12,_=F;if(_.width=this.internal.pageSize.getWidth(),i&&(!0===i.autoSize&&(x=!0),!1===i.printHeaders&&(S=!1),i.fontSize&&(k=i.fontSize),i.css&&void 0!==i.css["font-size"]&&(k=16*i.css["font-size"]),i.margins&&(_=i.margins)),this.lnMod=0,A={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},T=1,this.printHeaders=S,this.margins=_,this.setFontSize(k),this.table_font_size=k,null==r)g=Object.keys(n[0]);else if(r[0]&&"string"!=typeof r[0])for(a=0,s=r.length;a<s;a+=1)o=r[a],g.push(o.name),m.push(o.prompt),w[o.name]=o.width*(19.049976/25.4);else g=r;if(x)for(p=function(t){return t[o]},a=0,s=g.length;a<s;a+=1){for(y[o=g[a]]=n.map(p),v.push(this.getTextDimensions(m[a]||o).w),u=0,c=(h=y[o]).length;u<c;u+=1)l=h[u],v.push(this.getTextDimensions(l).w);w[o]=I.arrayMax(v),v=[]}if(S){var C=this.calculateLineHeight(g,w,m.length?m:g);for(a=0,s=g.length;a<s;a+=1)o=g[a],b.push([t,e,w[o],C,String(m.length?m[a]:o)]);this.setTableHeaderRow(b),this.printHeaderRow(1,!1)}for(a=0,s=n.length;a<s;a+=1)for(f=n[a],C=this.calculateLineHeight(g,w,f),u=0,d=g.length;u<d;u+=1)o=g[u],this.cell(t,e,w[o],C,f[o],a+2,o.align);return this.lastCellPos=A,this.table_x=t,this.table_y=e,this},I.calculateLineHeight=function(t,e,n){for(var r,i=0,o=0;o<t.length;o++){n[r=t[o]]=this.splitTextToSize(String(n[r]),e[r]-3);var a=this.internal.getLineHeight()*n[r].length+3;i<a&&(i=a)}return i},I.setTableHeaderRow=function(t){this.tableHeaderRow=t},I.printHeaderRow=function(t,e){if(!this.tableHeaderRow)throw"Property tableHeaderRow does not exist.";var n,r,i,o;if(this.printingHeaderRow=!0,void 0!==c){var a=c(this,T);d(a[0],a[1],a[2],a[3],-1)}this.setFontStyle("bold");var s=[];for(i=0,o=this.tableHeaderRow.length;i<o;i+=1)this.setFillColor(200,200,200),n=this.tableHeaderRow[i],e&&(this.margins.top=13,n[1]=this.margins&&this.margins.top||0,s.push(n)),r=[].concat(n),this.cell.apply(this,r.concat(t));0<s.length&&this.setTableHeaderRow(s),this.setFontStyle("normal"),this.printingHeaderRow=!1},
+/**
+   * jsPDF Context2D PlugIn Copyright (c) 2014 Steven Spungin (TwelveTone LLC) steven@twelvetone.tv
+   *
+   * Licensed under the MIT License. http://opensource.org/licenses/mit-license
+   */
+function(t){t.events.push(["initialized",function(){((this.context2d.pdf=this).context2d.internal.pdf=this).context2d.ctx=new e,this.context2d.ctxStack=[],this.context2d.path=[]}]),t.context2d={pageWrapXEnabled:!1,pageWrapYEnabled:!1,pageWrapX:9999999,pageWrapY:9999999,ctx:new e,f2:function(t){return t.toFixed(2)},fillRect:function(t,e,n,r){if(!this._isFillTransparent()){t=this._wrapX(t),e=this._wrapY(e);var i=this._matrix_map_rect(this.ctx._transform,{x:t,y:e,w:n,h:r});this.pdf.rect(i.x,i.y,i.w,i.h,"f")}},strokeRect:function(t,e,n,r){if(!this._isStrokeTransparent()){t=this._wrapX(t),e=this._wrapY(e);var i=this._matrix_map_rect(this.ctx._transform,{x:t,y:e,w:n,h:r});this.pdf.rect(i.x,i.y,i.w,i.h,"s")}},clearRect:function(t,e,n,r){if(!this.ctx.ignoreClearRect){t=this._wrapX(t),e=this._wrapY(e);var i=this._matrix_map_rect(this.ctx._transform,{x:t,y:e,w:n,h:r});this.save(),this.setFillStyle("#ffffff"),this.pdf.rect(i.x,i.y,i.w,i.h,"f"),this.restore()}},save:function(){this.ctx._fontSize=this.pdf.internal.getFontSize();var t=new e;t.copy(this.ctx),this.ctxStack.push(this.ctx),this.ctx=t},restore:function(){this.ctx=this.ctxStack.pop(),this.setFillStyle(this.ctx.fillStyle),this.setStrokeStyle(this.ctx.strokeStyle),this.setFont(this.ctx.font),this.pdf.setFontSize(this.ctx._fontSize),this.setLineCap(this.ctx.lineCap),this.setLineWidth(this.ctx.lineWidth),this.setLineJoin(this.ctx.lineJoin)},rect:function(t,e,n,r){this.moveTo(t,e),this.lineTo(t+n,e),this.lineTo(t+n,e+r),this.lineTo(t,e+r),this.lineTo(t,e),this.closePath()},beginPath:function(){this.path=[]},closePath:function(){this.path.push({type:"close"})},_getRGBA:function(t){var e,n,r,i;if(!t)return{r:0,g:0,b:0,a:0,style:t};if(this.internal.rxTransparent.test(t))i=r=n=e=0;else{var o=this.internal.rxRgb.exec(t);null!=o?(e=parseInt(o[1]),n=parseInt(o[2]),r=parseInt(o[3]),i=1):null!=(o=this.internal.rxRgba.exec(t))?(e=parseInt(o[1]),n=parseInt(o[2]),r=parseInt(o[3]),i=parseFloat(o[4])):(i=1,"#"!=t.charAt(0)&&((t=dt.colorNameToHex(t))||(t="#000000")),4===t.length?(e=t.substring(1,2),e+=e,n=t.substring(2,3),n+=n,r=t.substring(3,4),r+=r):(e=t.substring(1,3),n=t.substring(3,5),r=t.substring(5,7)),e=parseInt(e,16),n=parseInt(n,16),r=parseInt(r,16))}return{r:e,g:n,b:r,a:i,style:t}},setFillStyle:function(t){var e=this._getRGBA(t);this.ctx.fillStyle=t,this.ctx._isFillTransparent=0===e.a,this.ctx._fillOpacity=e.a,this.pdf.setFillColor(e.r,e.g,e.b,{a:e.a}),this.pdf.setTextColor(e.r,e.g,e.b,{a:e.a})},setStrokeStyle:function(t){var e=this._getRGBA(t);this.ctx.strokeStyle=e.style,this.ctx._isStrokeTransparent=0===e.a,this.ctx._strokeOpacity=e.a,0===e.a?this.pdf.setDrawColor(255,255,255):(e.a,this.pdf.setDrawColor(e.r,e.g,e.b))},fillText:function(t,e,n,r){if(!this._isFillTransparent()){e=this._wrapX(e),n=this._wrapY(n);var i=this._matrix_map_point(this.ctx._transform,[e,n]);e=i[0],n=i[1];var o=57.2958*this._matrix_rotation(this.ctx._transform);if(0<this.ctx._clip_path.length){var a;(a=window.outIntercept?"group"===window.outIntercept.type?window.outIntercept.stream:window.outIntercept:this.internal.getCurrentPage()).push("q");var s=this.path;this.path=this.ctx._clip_path,this.ctx._clip_path=[],this._fill(null,!0),this.ctx._clip_path=this.path,this.path=s}var c=1;try{c=this._matrix_decompose(this._getTransform()).scale[0]}catch(t){console.warn(t)}if(c<.01)this.pdf.text(t,e,this._getBaseline(n),null,o);else{var l=this.pdf.internal.getFontSize();this.pdf.setFontSize(l*c),this.pdf.text(t,e,this._getBaseline(n),null,o),this.pdf.setFontSize(l)}0<this.ctx._clip_path.length&&a.push("Q")}},strokeText:function(t,e,n,r){if(!this._isStrokeTransparent()){e=this._wrapX(e),n=this._wrapY(n);var i=this._matrix_map_point(this.ctx._transform,[e,n]);e=i[0],n=i[1];var o=57.2958*this._matrix_rotation(this.ctx._transform);if(0<this.ctx._clip_path.length){var a;(a=window.outIntercept?"group"===window.outIntercept.type?window.outIntercept.stream:window.outIntercept:this.internal.getCurrentPage()).push("q");var s=this.path;this.path=this.ctx._clip_path,this.ctx._clip_path=[],this._fill(null,!0),this.ctx._clip_path=this.path,this.path=s}var c=1;try{c=this._matrix_decompose(this._getTransform()).scale[0]}catch(t){console.warn(t)}if(1===c)this.pdf.text(t,e,this._getBaseline(n),{stroke:!0},o);else{var l=this.pdf.internal.getFontSize();this.pdf.setFontSize(l*c),this.pdf.text(t,e,this._getBaseline(n),{stroke:!0},o),this.pdf.setFontSize(l)}0<this.ctx._clip_path.length&&a.push("Q")}},setFont:function(t){if(this.ctx.font=t,null!=(c=/\s*(\w+)\s+(\w+)\s+(\w+)\s+([\d\.]+)(px|pt|em)\s+(.*)?/.exec(t))){var e=c[1],n=(c[2],c[3]),r=c[4],i=c[5],o=c[6];r="px"===i?Math.floor(parseFloat(r)):"em"===i?Math.floor(parseFloat(r)*this.pdf.getFontSize()):Math.floor(parseFloat(r)),this.pdf.setFontSize(r),"bold"===n||"700"===n?this.pdf.setFontStyle("bold"):"italic"===e?this.pdf.setFontStyle("italic"):this.pdf.setFontStyle("normal");var a,s=(u=o).toLowerCase().split(/\s*,\s*/);a=-1!=s.indexOf("arial")?"Arial":-1!=s.indexOf("verdana")?"Verdana":-1!=s.indexOf("helvetica")?"Helvetica":-1!=s.indexOf("sans-serif")?"sans-serif":-1!=s.indexOf("fixed")?"Fixed":-1!=s.indexOf("monospace")?"Monospace":-1!=s.indexOf("terminal")?"Terminal":-1!=s.indexOf("courier")?"Courier":-1!=s.indexOf("times")?"Times":-1!=s.indexOf("cursive")?"Cursive":-1!=s.indexOf("fantasy")?"Fantasy":(s.indexOf("serif"),"Serif"),l="bold"===n?"bold":"normal",this.pdf.setFont(a,l)}else{var c=/\s*(\d+)(pt|px|em)\s+([\w "]+)\s*([\w "]+)?/.exec(t);if(null!=c){var l,h=c[1],u=(c[2],c[3]);(l=c[4])||(l="normal"),h="em"===i?Math.floor(parseFloat(r)*this.pdf.getFontSize()):Math.floor(parseFloat(h)),this.pdf.setFontSize(h),this.pdf.setFont(u,l)}}},setTextBaseline:function(t){this.ctx.textBaseline=t},getTextBaseline:function(){return this.ctx.textBaseline},setTextAlign:function(t){this.ctx.textAlign=t},getTextAlign:function(){return this.ctx.textAlign},setLineWidth:function(t){this.ctx.lineWidth=t,this.pdf.setLineWidth(t)},setLineCap:function(t){this.ctx.lineCap=t,this.pdf.setLineCap(t)},setLineJoin:function(t){this.ctx.lineJoin=t,this.pdf.setLineJoin(t)},moveTo:function(t,e){t=this._wrapX(t),e=this._wrapY(e);var n=this._matrix_map_point(this.ctx._transform,[t,e]),r={type:"mt",x:t=n[0],y:e=n[1]};this.path.push(r)},_wrapX:function(t){return this.pageWrapXEnabled?t%this.pageWrapX:t},_wrapY:function(t){return this.pageWrapYEnabled?(this._gotoPage(this._page(t)),(t-this.lastBreak)%this.pageWrapY):t},transform:function(t,e,n,r,i,o){this.ctx._transform=[t,e,n,r,i,o]},setTransform:function(t,e,n,r,i,o){this.ctx._transform=[t,e,n,r,i,o]},_getTransform:function(){return this.ctx._transform},lastBreak:0,pageBreaks:[],_page:function(t){if(this.pageWrapYEnabled){for(var e=this.lastBreak=0,n=0,r=0;r<this.pageBreaks.length;r++)if(t>=this.pageBreaks[r]){e++,0===this.lastBreak&&n++;var i=this.pageBreaks[r]-this.lastBreak;this.lastBreak=this.pageBreaks[r],n+=Math.floor(i/this.pageWrapY)}if(0===this.lastBreak)n+=Math.floor(t/this.pageWrapY)+1;return n+e}return this.pdf.internal.getCurrentPageInfo().pageNumber},_gotoPage:function(t){},lineTo:function(t,e){t=this._wrapX(t),e=this._wrapY(e);var n=this._matrix_map_point(this.ctx._transform,[t,e]),r={type:"lt",x:t=n[0],y:e=n[1]};this.path.push(r)},bezierCurveTo:function(t,e,n,r,i,o){var a;t=this._wrapX(t),e=this._wrapY(e),n=this._wrapX(n),r=this._wrapY(r),i=this._wrapX(i),o=this._wrapY(o),i=(a=this._matrix_map_point(this.ctx._transform,[i,o]))[0],o=a[1];var s={type:"bct",x1:t=(a=this._matrix_map_point(this.ctx._transform,[t,e]))[0],y1:e=a[1],x2:n=(a=this._matrix_map_point(this.ctx._transform,[n,r]))[0],y2:r=a[1],x:i,y:o};this.path.push(s)},quadraticCurveTo:function(t,e,n,r){var i;t=this._wrapX(t),e=this._wrapY(e),n=this._wrapX(n),r=this._wrapY(r),n=(i=this._matrix_map_point(this.ctx._transform,[n,r]))[0],r=i[1];var o={type:"qct",x1:t=(i=this._matrix_map_point(this.ctx._transform,[t,e]))[0],y1:e=i[1],x:n,y:r};this.path.push(o)},arc:function(t,e,n,r,i,o){if(t=this._wrapX(t),e=this._wrapY(e),!this._matrix_is_identity(this.ctx._transform)){var a=this._matrix_map_point(this.ctx._transform,[t,e]);t=a[0],e=a[1];var s=this._matrix_map_point(this.ctx._transform,[0,0]),c=this._matrix_map_point(this.ctx._transform,[0,n]);n=Math.sqrt(Math.pow(c[0]-s[0],2)+Math.pow(c[1]-s[1],2))}var l={type:"arc",x:t,y:e,radius:n,startAngle:r,endAngle:i,anticlockwise:o};this.path.push(l)},drawImage:function(t,e,n,r,i,o,a,s,c){void 0!==o&&(e=o,n=a,r=s,i=c),e=this._wrapX(e),n=this._wrapY(n);var l,h=this._matrix_map_rect(this.ctx._transform,{x:e,y:n,w:r,h:i}),u=(this._matrix_map_rect(this.ctx._transform,{x:o,y:a,w:s,h:c}),/data:image\/(\w+).*/i.exec(t));l=null!=u?u[1]:"png",this.pdf.addImage(t,l,h.x,h.y,h.w,h.h)},_matrix_multiply:function(t,e){var n=e[0],r=e[1],i=e[2],o=e[3],a=e[4],s=e[5],c=n*t[0]+r*t[2],l=i*t[0]+o*t[2],h=a*t[0]+s*t[2]+t[4];return r=n*t[1]+r*t[3],o=i*t[1]+o*t[3],s=a*t[1]+s*t[3]+t[5],[n=c,r,i=l,o,a=h,s]},_matrix_rotation:function(t){return Math.atan2(t[2],t[0])},_matrix_decompose:function(t){var e=t[0],n=t[1],r=t[2],i=t[3],o=Math.sqrt(e*e+n*n),a=(e/=o)*r+(n/=o)*i;r-=e*a,i-=n*a;var s=Math.sqrt(r*r+i*i);return a/=s,e*(i/=s)<n*(r/=s)&&(e=-e,n=-n,a=-a,o=-o),{scale:[o,0,0,s,0,0],translate:[1,0,0,1,t[4],t[5]],rotate:[e,n,-n,e,0,0],skew:[1,0,a,1,0,0]}},_matrix_map_point:function(t,e){var n=t[0],r=t[1],i=t[2],o=t[3],a=t[4],s=t[5],c=e[0],l=e[1];return[c*n+l*i+a,c*r+l*o+s]},_matrix_map_point_obj:function(t,e){var n=this._matrix_map_point(t,[e.x,e.y]);return{x:n[0],y:n[1]}},_matrix_map_rect:function(t,e){var n=this._matrix_map_point(t,[e.x,e.y]),r=this._matrix_map_point(t,[e.x+e.w,e.y+e.h]);return{x:n[0],y:n[1],w:r[0]-n[0],h:r[1]-n[1]}},_matrix_is_identity:function(t){return 1==t[0]&&(0==t[1]&&(0==t[2]&&(1==t[3]&&(0==t[4]&&0==t[5]))))},rotate:function(t){var e=[Math.cos(t),Math.sin(t),-Math.sin(t),Math.cos(t),0,0];this.ctx._transform=this._matrix_multiply(this.ctx._transform,e)},scale:function(t,e){var n=[t,0,0,e,0,0];this.ctx._transform=this._matrix_multiply(this.ctx._transform,n)},translate:function(t,e){var n=[1,0,0,1,t,e];this.ctx._transform=this._matrix_multiply(this.ctx._transform,n)},stroke:function(){if(0<this.ctx._clip_path.length){var t;(t=window.outIntercept?"group"===window.outIntercept.type?window.outIntercept.stream:window.outIntercept:this.internal.getCurrentPage()).push("q");var e=this.path;this.path=this.ctx._clip_path,this.ctx._clip_path=[],this._stroke(!0),this.ctx._clip_path=this.path,this.path=e,this._stroke(!1),t.push("Q")}else this._stroke(!1)},_stroke:function(t){if(t||!this._isStrokeTransparent()){for(var e=[],n=this.path,r=0;r<n.length;r++){var i=n[r];switch(i.type){case"mt":e.push({start:i,deltas:[],abs:[]});break;case"lt":var o=[i.x-n[r-1].x,i.y-n[r-1].y];e[e.length-1].deltas.push(o),e[e.length-1].abs.push(i);break;case"bct":o=[i.x1-n[r-1].x,i.y1-n[r-1].y,i.x2-n[r-1].x,i.y2-n[r-1].y,i.x-n[r-1].x,i.y-n[r-1].y];e[e.length-1].deltas.push(o);break;case"qct":var a=n[r-1].x+2/3*(i.x1-n[r-1].x),s=n[r-1].y+2/3*(i.y1-n[r-1].y),c=i.x+2/3*(i.x1-i.x),l=i.y+2/3*(i.y1-i.y),h=i.x,u=i.y;o=[a-n[r-1].x,s-n[r-1].y,c-n[r-1].x,l-n[r-1].y,h-n[r-1].x,u-n[r-1].y];e[e.length-1].deltas.push(o);break;case"arc":0==e.length&&e.push({start:{x:0,y:0},deltas:[],abs:[]}),e[e.length-1].arc=!0,e[e.length-1].abs.push(i)}}for(r=0;r<e.length;r++){var f;if(f=r==e.length-1?"s":null,e[r].arc)for(var d=e[r].abs,p=0;p<d.length;p++){var g=d[p],m=360*g.startAngle/(2*Math.PI),y=360*g.endAngle/(2*Math.PI),w=g.x,v=g.y;this.internal.arc2(this,w,v,g.radius,m,y,g.anticlockwise,f,t)}else{w=e[r].start.x,v=e[r].start.y;t?(this.pdf.lines(e[r].deltas,w,v,null,null),this.pdf.clip_fixed()):this.pdf.lines(e[r].deltas,w,v,null,f)}}}},_isFillTransparent:function(){return this.ctx._isFillTransparent||0==this.globalAlpha},_isStrokeTransparent:function(){return this.ctx._isStrokeTransparent||0==this.globalAlpha},fill:function(t){if(0<this.ctx._clip_path.length){var e;(e=window.outIntercept?"group"===window.outIntercept.type?window.outIntercept.stream:window.outIntercept:this.internal.getCurrentPage()).push("q");var n=this.path;this.path=this.ctx._clip_path,this.ctx._clip_path=[],this._fill(t,!0),this.ctx._clip_path=this.path,this.path=n,this._fill(t,!1),e.push("Q")}else this._fill(t,!1)},_fill:function(t,e){if(!this._isFillTransparent()){var n,r="function"==typeof this.pdf.internal.newObject2;n=window.outIntercept?"group"===window.outIntercept.type?window.outIntercept.stream:window.outIntercept:this.internal.getCurrentPage();var i=[],o=window.outIntercept;if(r)switch(this.ctx.globalCompositeOperation){case"normal":case"source-over":break;case"destination-in":case"destination-out":var a=this.pdf.internal.newStreamObject(),s=this.pdf.internal.newObject2();s.push("<</Type /ExtGState"),s.push("/SMask <</S /Alpha /G "+a.objId+" 0 R>>"),s.push(">>");var c="MASK"+s.objId;this.pdf.internal.addGraphicsState(c,s.objId);var l="/"+c+" gs";n.splice(0,0,"q"),n.splice(1,0,l),n.push("Q"),window.outIntercept=a;break;default:var h="/"+this.pdf.internal.blendModeMap[this.ctx.globalCompositeOperation.toUpperCase()];h&&this.pdf.internal.out(h+" gs")}var u=this.ctx.globalAlpha;if(this.ctx._fillOpacity<1&&(u=this.ctx._fillOpacity),r){var f=this.pdf.internal.newObject2();f.push("<</Type /ExtGState"),f.push("/CA "+u),f.push("/ca "+u),f.push(">>");c="GS_O_"+f.objId;this.pdf.internal.addGraphicsState(c,f.objId),this.pdf.internal.out("/"+c+" gs")}for(var d=this.path,p=0;p<d.length;p++){var g=d[p];switch(g.type){case"mt":i.push({start:g,deltas:[],abs:[]});break;case"lt":var m=[g.x-d[p-1].x,g.y-d[p-1].y];i[i.length-1].deltas.push(m),i[i.length-1].abs.push(g);break;case"bct":m=[g.x1-d[p-1].x,g.y1-d[p-1].y,g.x2-d[p-1].x,g.y2-d[p-1].y,g.x-d[p-1].x,g.y-d[p-1].y];i[i.length-1].deltas.push(m);break;case"qct":var y=d[p-1].x+2/3*(g.x1-d[p-1].x),w=d[p-1].y+2/3*(g.y1-d[p-1].y),v=g.x+2/3*(g.x1-g.x),b=g.y+2/3*(g.y1-g.y),x=g.x,S=g.y;m=[y-d[p-1].x,w-d[p-1].y,v-d[p-1].x,b-d[p-1].y,x-d[p-1].x,S-d[p-1].y];i[i.length-1].deltas.push(m);break;case"arc":0===i.length&&i.push({deltas:[],abs:[]}),i[i.length-1].arc=!0,i[i.length-1].abs.push(g);break;case"close":i.push({close:!0})}}for(p=0;p<i.length;p++){var k;if(p==i.length-1?(k="f","evenodd"===t&&(k+="*")):k=null,i[p].close)this.pdf.internal.out("h"),k&&this.pdf.internal.out(k);else if(i[p].arc){i[p].start&&this.internal.move2(this,i[p].start.x,i[p].start.y);for(var _=i[p].abs,C=0;C<_.length;C++){var I=_[C];if(void 0!==I.startAngle){var A=360*I.startAngle/(2*Math.PI),T=360*I.endAngle/(2*Math.PI),F=I.x,q=I.y;if(0===C&&this.internal.move2(this,F,q),this.internal.arc2(this,F,q,I.radius,A,T,I.anticlockwise,null,e),C===_.length-1&&i[p].start){F=i[p].start.x,q=i[p].start.y;this.internal.line2(E,F,q)}}else this.internal.line2(E,I.x,I.y)}}else{F=i[p].start.x,q=i[p].start.y;e?(this.pdf.lines(i[p].deltas,F,q,null,null),this.pdf.clip_fixed()):this.pdf.lines(i[p].deltas,F,q,null,k)}}window.outIntercept=o}},pushMask:function(){if("function"==typeof this.pdf.internal.newObject2){var t=this.pdf.internal.newStreamObject(),e=this.pdf.internal.newObject2();e.push("<</Type /ExtGState"),e.push("/SMask <</S /Alpha /G "+t.objId+" 0 R>>"),e.push(">>");var n="MASK"+e.objId;this.pdf.internal.addGraphicsState(n,e.objId);var r="/"+n+" gs";this.pdf.internal.out(r)}else console.log("jsPDF v2 not enabled")},clip:function(){if(0<this.ctx._clip_path.length)for(var t=0;t<this.path.length;t++)this.ctx._clip_path.push(this.path[t]);else this.ctx._clip_path=this.path;this.path=[]},measureText:function(n){var r=this.pdf;return{getWidth:function(){var t=r.internal.getFontSize(),e=r.getStringUnitWidth(n)*t/r.internal.scaleFactor;return e*=1.3333},get width(){return this.getWidth(n)}}},_getBaseline:function(t){var e=parseInt(this.pdf.internal.getFontSize()),n=.25*e;switch(this.ctx.textBaseline){case"bottom":return t-n;case"top":return t+e;case"hanging":return t+e-n;case"middle":return t+e/2-n;case"ideographic":return t;case"alphabetic":default:return t}}};var E=t.context2d;function e(){this._isStrokeTransparent=!1,this._strokeOpacity=1,this.strokeStyle="#000000",this.fillStyle="#000000",this._isFillTransparent=!1,this._fillOpacity=1,this.font="12pt times",this.textBaseline="alphabetic",this.textAlign="start",this.lineWidth=1,this.lineJoin="miter",this.lineCap="butt",this._transform=[1,0,0,1,0,0],this.globalCompositeOperation="normal",this.globalAlpha=1,this._clip_path=[],this.ignoreClearRect=!1,this.copy=function(t){this._isStrokeTransparent=t._isStrokeTransparent,this._strokeOpacity=t._strokeOpacity,this.strokeStyle=t.strokeStyle,this._isFillTransparent=t._isFillTransparent,this._fillOpacity=t._fillOpacity,this.fillStyle=t.fillStyle,this.font=t.font,this.lineWidth=t.lineWidth,this.lineJoin=t.lineJoin,this.lineCap=t.lineCap,this.textBaseline=t.textBaseline,this.textAlign=t.textAlign,this._fontSize=t._fontSize,this._transform=t._transform.slice(0),this.globalCompositeOperation=t.globalCompositeOperation,this.globalAlpha=t.globalAlpha,this._clip_path=t._clip_path.slice(0),this.ignoreClearRect=t.ignoreClearRect}}Object.defineProperty(E,"fillStyle",{set:function(t){this.setFillStyle(t)},get:function(){return this.ctx.fillStyle}}),Object.defineProperty(E,"strokeStyle",{set:function(t){this.setStrokeStyle(t)},get:function(){return this.ctx.strokeStyle}}),Object.defineProperty(E,"lineWidth",{set:function(t){this.setLineWidth(t)},get:function(){return this.ctx.lineWidth}}),Object.defineProperty(E,"lineCap",{set:function(t){this.setLineCap(t)},get:function(){return this.ctx.lineCap}}),Object.defineProperty(E,"lineJoin",{set:function(t){this.setLineJoin(t)},get:function(){return this.ctx.lineJoin}}),Object.defineProperty(E,"miterLimit",{set:function(t){this.ctx.miterLimit=t},get:function(){return this.ctx.miterLimit}}),Object.defineProperty(E,"textBaseline",{set:function(t){this.setTextBaseline(t)},get:function(){return this.getTextBaseline()}}),Object.defineProperty(E,"textAlign",{set:function(t){this.setTextAlign(t)},get:function(){return this.getTextAlign()}}),Object.defineProperty(E,"font",{set:function(t){this.setFont(t)},get:function(){return this.ctx.font}}),Object.defineProperty(E,"globalCompositeOperation",{set:function(t){this.ctx.globalCompositeOperation=t},get:function(){return this.ctx.globalCompositeOperation}}),Object.defineProperty(E,"globalAlpha",{set:function(t){this.ctx.globalAlpha=t},get:function(){return this.ctx.globalAlpha}}),Object.defineProperty(E,"ignoreClearRect",{set:function(t){this.ctx.ignoreClearRect=t},get:function(){return this.ctx.ignoreClearRect}}),E.internal={},E.internal.rxRgb=/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/,E.internal.rxRgba=/rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/,E.internal.rxTransparent=/transparent|rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*0+\s*\)/,E.internal.arc=function(t,e,n,r,i,o,a,s){for(var c=this.pdf.internal.scaleFactor,l=this.pdf.internal.pageSize.getHeight(),h=this.pdf.internal.f2,u=i*(Math.PI/180),f=o*(Math.PI/180),d=this.createArc(r,u,f,a),p=0;p<d.length;p++){var g=d[p];0===p?this.pdf.internal.out([h((g.x1+e)*c),h((l-(g.y1+n))*c),"m",h((g.x2+e)*c),h((l-(g.y2+n))*c),h((g.x3+e)*c),h((l-(g.y3+n))*c),h((g.x4+e)*c),h((l-(g.y4+n))*c),"c"].join(" ")):this.pdf.internal.out([h((g.x2+e)*c),h((l-(g.y2+n))*c),h((g.x3+e)*c),h((l-(g.y3+n))*c),h((g.x4+e)*c),h((l-(g.y4+n))*c),"c"].join(" ")),t._lastPoint={x:e,y:n}}null!==s&&this.pdf.internal.out(this.pdf.internal.getStyle(s))},E.internal.arc2=function(t,e,n,r,i,o,a,s,c){var l=e,h=n;c?(this.arc(t,l,h,r,i,o,a,null),this.pdf.clip_fixed()):this.arc(t,l,h,r,i,o,a,s)},E.internal.move2=function(t,e,n){var r=this.pdf.internal.scaleFactor,i=this.pdf.internal.pageSize.getHeight(),o=this.pdf.internal.f2;this.pdf.internal.out([o(e*r),o((i-n)*r),"m"].join(" ")),t._lastPoint={x:e,y:n}},E.internal.line2=function(t,e,n){var r=this.pdf.internal.scaleFactor,i=this.pdf.internal.pageSize.getHeight(),o=this.pdf.internal.f2,a={x:e,y:n};this.pdf.internal.out([o(a.x*r),o((i-a.y)*r),"l"].join(" ")),t._lastPoint=a},E.internal.createArc=function(t,e,n,r){var i=2*Math.PI,o=Math.PI/2,a=e;for((a<i||i<a)&&(a%=i),a<0&&(a=i+a);n<e;)e-=i;var s=Math.abs(n-e);s<i&&r&&(s=i-s);for(var c=[],l=r?-1:1,h=a;1e-5<s;){var u=h+l*Math.min(s,o);c.push(this.createSmallArc(t,h,u)),s-=Math.abs(u-h),h=u}return c},E.internal.getCurrentPage=function(){return this.pdf.internal.pages[this.pdf.internal.getCurrentPageInfo().pageNumber]},E.internal.createSmallArc=function(t,e,n){var r=(n-e)/2,i=t*Math.cos(r),o=t*Math.sin(r),a=i,s=-o,c=a*a+s*s,l=c+a*i+s*o,h=4/3*(Math.sqrt(2*c*l)-l)/(a*o-s*i),u=a-h*s,f=s+h*a,d=u,p=-f,g=r+e,m=Math.cos(g),y=Math.sin(g);return{x1:t*Math.cos(e),y1:t*Math.sin(e),x2:u*m-f*y,y2:u*y+f*m,x3:d*m-p*y,y3:d*y+p*m,x4:t*Math.cos(n),y4:t*Math.sin(n)}}}(K.API),
+/** @preserve
+   * jsPDF fromHTML plugin. BETA stage. API subject to change. Needs browser
+   * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
+   *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
+   *               2014 Diego Casorran, https://github.com/diegocr
+   *               2014 Daniel Husar, https://github.com/danielhusar
+   *               2014 Wolfgang Gassler, https://github.com/woolfg
+   *               2014 Steven Spungin, https://github.com/flamenco
+   *
+   * 
+   * ====================================================================
+   */
+function(t){var T,F,i,a,s,c,l,h,q,v,f,u,d,n,E,P,p,g,m,O;T=function(){return function(t){return e.prototype=t,new e};function e(){}}(),v=function(t){var e,n,r,i,o,a,s;for(n=0,r=t.length,e=void 0,a=i=!1;!i&&n!==r;)(e=t[n]=t[n].trimLeft())&&(i=!0),n++;for(n=r-1;r&&!a&&-1!==n;)(e=t[n]=t[n].trimRight())&&(a=!0),n--;for(o=/\s+$/g,s=!0,n=0;n!==r;)"\u2028"!=t[n]&&(e=t[n].replace(/\s+/g," "),s&&(e=e.trimLeft()),e&&(s=o.test(e)),t[n]=e),n++;return t},u=function(t){var e,n,r;for(e=void 0,n=(r=t.split(",")).shift();!e&&n;)e=i[n.trim().toLowerCase()],n=r.shift();return e},d=function(t){var e;return-1<(t="auto"===t?"0px":t).indexOf("em")&&!isNaN(Number(t.replace("em","")))&&(t=18.719*Number(t.replace("em",""))+"px"),-1<t.indexOf("pt")&&!isNaN(Number(t.replace("pt","")))&&(t=1.333*Number(t.replace("pt",""))+"px"),void 0,16,(e=n[t])?e:void 0!==(e={"xx-small":9,"x-small":11,small:13,medium:16,large:19,"x-large":23,"xx-large":28,auto:0}[{css_line_height_string:t}])?n[t]=e/16:(e=parseFloat(t))?n[t]=e/16:3===(e=t.match(/([\d\.]+)(px)/)).length?n[t]=parseFloat(e[1])/16:n[t]=1},q=function(t){var e,n,r,i,o;return o=t,i=document.defaultView&&document.defaultView.getComputedStyle?document.defaultView.getComputedStyle(o,null):o.currentStyle?o.currentStyle:o.style,n=void 0,(e={})["font-family"]=u((r=function(t){return t=t.replace(/-\D/g,function(t){return t.charAt(1).toUpperCase()}),i[t]})("font-family"))||"times",e["font-style"]=a[r("font-style")]||"normal",e["text-align"]=s[r("text-align")]||"left","bold"===(n=c[r("font-weight")]||"normal")&&("normal"===e["font-style"]?e["font-style"]=n:e["font-style"]=n+e["font-style"]),e["font-size"]=d(r("font-size"))||1,e["line-height"]=d(r("line-height"))||1,e.display="inline"===r("display")?"inline":"block",n="block"===e.display,e["margin-top"]=n&&d(r("margin-top"))||0,e["margin-bottom"]=n&&d(r("margin-bottom"))||0,e["padding-top"]=n&&d(r("padding-top"))||0,e["padding-bottom"]=n&&d(r("padding-bottom"))||0,e["margin-left"]=n&&d(r("margin-left"))||0,e["margin-right"]=n&&d(r("margin-right"))||0,e["padding-left"]=n&&d(r("padding-left"))||0,e["padding-right"]=n&&d(r("padding-right"))||0,e["page-break-before"]=r("page-break-before")||"auto",e.float=l[r("cssFloat")]||"none",e.clear=h[r("clear")]||"none",e.color=r("color"),e},E=function(t,e,n){var r,i,o,a,s;if(o=!1,a=i=void 0,r=n["#"+t.id])if("function"==typeof r)o=r(t,e);else for(i=0,a=r.length;!o&&i!==a;)o=r[i](t,e),i++;if(r=n[t.nodeName],!o&&r)if("function"==typeof r)o=r(t,e);else for(i=0,a=r.length;!o&&i!==a;)o=r[i](t,e),i++;for(s="string"==typeof t.className?t.className.split(" "):[],i=0;i<s.length;i++)if(r=n["."+s[i]],!o&&r)if("function"==typeof r)o=r(t,e);else for(i=0,a=r.length;!o&&i!==a;)o=r[i](t,e),i++;return o},O=function(t,e){var n,r,i,o,a,s,c,l,h;for(n=[],r=[],i=0,h=t.rows[0].cells.length,c=t.clientWidth;i<h;)l=t.rows[0].cells[i],r[i]={name:l.textContent.toLowerCase().replace(/\s+/g,""),prompt:l.textContent.replace(/\r?\n/g,""),width:l.clientWidth/c*e.pdf.internal.pageSize.getWidth()},i++;for(i=1;i<t.rows.length;){for(s=t.rows[i],a={},o=0;o<s.cells.length;)a[r[o].name]=s.cells[o].textContent.replace(/\r?\n/g,""),o++;n.push(a),i++}return{rows:n,headers:r}};var B={SCRIPT:1,STYLE:1,NOSCRIPT:1,OBJECT:1,EMBED:1,SELECT:1},j=1;F=function(t,i,e){var n,r,o,a,s,c,l,h;for(r=t.childNodes,n=void 0,(s="block"===(o=q(t)).display)&&(i.setBlockBoundary(),i.setBlockStyle(o)),a=0,c=r.length;a<c;){if("object"===(void 0===(n=r[a])?"undefined":vt(n))){if(i.executeWatchFunctions(n),1===n.nodeType&&"HEADER"===n.nodeName){var u=n,f=i.pdf.margins_doc.top;i.pdf.internal.events.subscribe("addPage",function(t){i.y=f,F(u,i,e),i.pdf.margins_doc.top=i.y+10,i.y+=10},!1)}if(8===n.nodeType&&"#comment"===n.nodeName)~n.textContent.indexOf("ADD_PAGE")&&(i.pdf.addPage(),i.y=i.pdf.margins_doc.top);else if(1!==n.nodeType||B[n.nodeName])if(3===n.nodeType){var d=n.nodeValue;if(n.nodeValue&&"LI"===n.parentNode.nodeName)if("OL"===n.parentNode.parentNode.nodeName)d=j+++". "+d;else{var p=o["font-size"],g=(3-.75*p)*i.pdf.internal.scaleFactor,m=.75*p*i.pdf.internal.scaleFactor,y=1.74*p/i.pdf.internal.scaleFactor;h=function(t,e){this.pdf.circle(t+g,e+m,y,"FD")}}16&n.ownerDocument.body.compareDocumentPosition(n)&&i.addText(d,o)}else"string"==typeof n&&i.addText(n,o);else{var w;if("IMG"===n.nodeName){var v=n.getAttribute("src");w=P[i.pdf.sHashCode(v)||v]}if(w){i.pdf.internal.pageSize.getHeight()-i.pdf.margins_doc.bottom<i.y+n.height&&i.y>i.pdf.margins_doc.top&&(i.pdf.addPage(),i.y=i.pdf.margins_doc.top,i.executeWatchFunctions(n));var b=q(n),x=i.x,S=12/i.pdf.internal.scaleFactor,k=(b["margin-left"]+b["padding-left"])*S,_=(b["margin-right"]+b["padding-right"])*S,C=(b["margin-top"]+b["padding-top"])*S,I=(b["margin-bottom"]+b["padding-bottom"])*S;void 0!==b.float&&"right"===b.float?x+=i.settings.width-n.width-_:x+=k,i.pdf.addImage(w,x,i.y+C,n.width,n.height),w=void 0,"right"===b.float||"left"===b.float?(i.watchFunctions.push(function(t,e,n,r){return i.y>=e?(i.x+=t,i.settings.width+=n,!0):!!(r&&1===r.nodeType&&!B[r.nodeName]&&i.x+r.width>i.pdf.margins_doc.left+i.pdf.margins_doc.width)&&(i.x+=t,i.y=e,i.settings.width+=n,!0)}.bind(this,"left"===b.float?-n.width-k-_:0,i.y+n.height+C+I,n.width)),i.watchFunctions.push(function(t,e,n){return!(i.y<t&&e===i.pdf.internal.getNumberOfPages())||1===n.nodeType&&"both"===q(n).clear&&(i.y=t,!0)}.bind(this,i.y+n.height,i.pdf.internal.getNumberOfPages())),i.settings.width-=n.width+k+_,"left"===b.float&&(i.x+=n.width+k+_)):i.y+=n.height+C+I}else if("TABLE"===n.nodeName)l=O(n,i),i.y+=10,i.pdf.table(i.x,i.y,l.rows,l.headers,{autoSize:!1,printHeaders:e.printHeaders,margins:i.pdf.margins_doc,css:q(n)}),i.y=i.pdf.lastCellPos.y+i.pdf.lastCellPos.h+20;else if("OL"===n.nodeName||"UL"===n.nodeName)j=1,E(n,i,e)||F(n,i,e),i.y+=10;else if("LI"===n.nodeName){var A=i.x;i.x+=20/i.pdf.internal.scaleFactor,i.y+=3,E(n,i,e)||F(n,i,e),i.x=A}else"BR"===n.nodeName?(i.y+=o["font-size"]*i.pdf.internal.scaleFactor,i.addText("\u2028",T(o))):E(n,i,e)||F(n,i,e)}}a++}if(e.outY=i.y,s)return i.setBlockBoundary(h)},P={},p=function(t,o,e,n){var a,r=t.getElementsByTagName("img"),i=r.length,s=0;function c(){o.pdf.internal.events.publish("imagesLoaded"),n(a)}function l(e,n,r){if(e){var i=new Image;a=++s,i.crossOrigin="",i.onerror=i.onload=function(){if(i.complete&&(0===i.src.indexOf("data:image/")&&(i.width=n||i.width||0,i.height=r||i.height||0),i.width+i.height)){var t=o.pdf.sHashCode(e)||e;P[t]=P[t]||i}--s||c()},i.src=e}}for(;i--;)l(r[i].getAttribute("src"),r[i].width,r[i].height);return s||c()},g=function(t,o,a){var s=t.getElementsByTagName("footer");if(0<s.length){s=s[0];var e=o.pdf.internal.write,n=o.y;o.pdf.internal.write=function(){},F(s,o,a);var c=Math.ceil(o.y-n)+5;o.y=n,o.pdf.internal.write=e,o.pdf.margins_doc.bottom+=c;for(var r=function(t){var e=void 0!==t?t.pageNumber:1,n=o.y;o.y=o.pdf.internal.pageSize.getHeight()-o.pdf.margins_doc.bottom,o.pdf.margins_doc.bottom-=c;for(var r=s.getElementsByTagName("span"),i=0;i<r.length;++i)-1<(" "+r[i].className+" ").replace(/[\n\t]/g," ").indexOf(" pageCounter ")&&(r[i].innerHTML=e),-1<(" "+r[i].className+" ").replace(/[\n\t]/g," ").indexOf(" totalPages ")&&(r[i].innerHTML="###jsPDFVarTotalPages###");F(s,o,a),o.pdf.margins_doc.bottom+=c,o.y=n},i=s.getElementsByTagName("span"),l=0;l<i.length;++l)-1<(" "+i[l].className+" ").replace(/[\n\t]/g," ").indexOf(" totalPages ")&&o.pdf.internal.events.subscribe("htmlRenderingFinished",o.pdf.putTotalPages.bind(o.pdf,"###jsPDFVarTotalPages###"),!0);o.pdf.internal.events.subscribe("addPage",r,!1),r(),B.FOOTER=1}},m=function(t,e,n,r,i,o){if(!e)return!1;var a,s,c,l;"string"==typeof e||e.parentNode||(e=""+e.innerHTML),"string"==typeof e&&(a=e.replace(/<\/?script[^>]*?>/gi,""),l="jsPDFhtmlText"+Date.now().toString()+(1e3*Math.random()).toFixed(0),(c=document.createElement("div")).style.cssText="position: absolute !important;clip: rect(1px 1px 1px 1px); /* IE6, IE7 */clip: rect(1px, 1px, 1px, 1px);padding:0 !important;border:0 !important;height: 1px !important;width: 1px !important; top:auto;left:-100px;overflow: hidden;",c.innerHTML='<iframe style="height:1px;width:1px" name="'+l+'" />',document.body.appendChild(c),(s=window.frames[l]).document.open(),s.document.writeln(a),s.document.close(),e=s.document.body);var h,u=new f(t,n,r,i);return p.call(this,e,u,i.elementHandlers,function(t){g(e,u,i.elementHandlers),F(e,u,i.elementHandlers),u.pdf.internal.events.publish("htmlRenderingFinished"),h=u.dispose(),"function"==typeof o?o(h):t&&console.error("jsPDF Warning: rendering issues? provide a callback to fromHTML!")}),h||{x:u.x,y:u.y}},(f=function(t,e,n,r){return this.pdf=t,this.x=e,this.y=n,this.settings=r,this.watchFunctions=[],this.init(),this}).prototype.init=function(){return this.paragraph={text:[],style:[]},this.pdf.internal.write("q")},f.prototype.dispose=function(){return this.pdf.internal.write("Q"),{x:this.x,y:this.y,ready:!0}},f.prototype.executeWatchFunctions=function(t){var e=!1,n=[];if(0<this.watchFunctions.length){for(var r=0;r<this.watchFunctions.length;++r)!0===this.watchFunctions[r](t)?e=!0:n.push(this.watchFunctions[r]);this.watchFunctions=n}return e},f.prototype.splitFragmentsIntoLines=function(t,e){var n,r,i,o,a,s,c,l,h,u,f,d,p,g;for(12,u=this.pdf.internal.scaleFactor,o={},s=c=l=g=a=i=h=r=void 0,d=[f=[]],n=0,p=this.settings.width;t.length;)if(a=t.shift(),g=e.shift(),a)if((i=o[(r=g["font-family"])+(h=g["font-style"])])||(i=this.pdf.internal.getFont(r,h).metadata.Unicode,o[r+h]=i),l={widths:i.widths,kerning:i.kerning,fontSize:12*g["font-size"],textIndent:n},c=this.pdf.getStringUnitWidth(a,l)*l.fontSize/u,"\u2028"==a)f=[],d.push(f);else if(p<n+c){for(s=this.pdf.splitTextToSize(a,p,l),f.push([s.shift(),g]);s.length;)f=[[s.shift(),g]],d.push(f);n=this.pdf.getStringUnitWidth(f[0][0],l)*l.fontSize/u}else f.push([a,g]),n+=c;if(void 0!==g["text-align"]&&("center"===g["text-align"]||"right"===g["text-align"]||"justify"===g["text-align"]))for(var m=0;m<d.length;++m){var y=this.pdf.getStringUnitWidth(d[m][0][0],l)*l.fontSize/u;0<m&&(d[m][0][1]=T(d[m][0][1]));var w=p-y;if("right"===g["text-align"])d[m][0][1]["margin-left"]=w;else if("center"===g["text-align"])d[m][0][1]["margin-left"]=w/2;else if("justify"===g["text-align"]){var v=d[m][0][0].split(" ").length-1;d[m][0][1]["word-spacing"]=w/v,m===d.length-1&&(d[m][0][1]["word-spacing"]=0)}}return d},f.prototype.RenderTextFragment=function(t,e){var n,r;r=0,this.pdf.internal.pageSize.getHeight()-this.pdf.margins_doc.bottom<this.y+this.pdf.internal.getFontSize()&&(this.pdf.internal.write("ET","Q"),this.pdf.addPage(),this.y=this.pdf.margins_doc.top,this.pdf.internal.write("q","BT",this.getPdfColor(e.color),this.pdf.internal.getCoordinateString(this.x),this.pdf.internal.getVerticalCoordinateString(this.y),"Td"),r=Math.max(r,e["line-height"],e["font-size"]),this.pdf.internal.write(0,(-12*r).toFixed(2),"Td")),n=this.pdf.internal.getFont(e["font-family"],e["font-style"]);var i=this.getPdfColor(e.color);i!==this.lastTextColor&&(this.pdf.internal.write(i),this.lastTextColor=i),void 0!==e["word-spacing"]&&0<e["word-spacing"]&&this.pdf.internal.write(e["word-spacing"].toFixed(2),"Tw"),this.pdf.internal.write("/"+n.id,(12*e["font-size"]).toFixed(2),"Tf","("+this.pdf.internal.pdfEscape(t)+") Tj"),void 0!==e["word-spacing"]&&this.pdf.internal.write(0,"Tw")},f.prototype.getPdfColor=function(t){var e,n,r,i=/rgb\s*\(\s*(\d+),\s*(\d+),\s*(\d+\s*)\)/.exec(t);if(null!=i?(e=parseInt(i[1]),n=parseInt(i[2]),r=parseInt(i[3])):("#"!=t.charAt(0)&&((t=dt.colorNameToHex(t))||(t="#000000")),e=t.substring(1,3),e=parseInt(e,16),n=t.substring(3,5),n=parseInt(n,16),r=t.substring(5,7),r=parseInt(r,16)),"string"==typeof e&&/^#[0-9A-Fa-f]{6}$/.test(e)){var o=parseInt(e.substr(1),16);e=o>>16&255,n=o>>8&255,r=255&o}var a=this.f3;return 0===e&&0===n&&0===r||void 0===n?a(e/255)+" g":[a(e/255),a(n/255),a(r/255),"rg"].join(" ")},f.prototype.f3=function(t){return t.toFixed(3)},f.prototype.renderParagraph=function(t){var e,n,r,i,o,a,s,c,l,h,u,f,d;if(r=v(this.paragraph.text),f=this.paragraph.style,e=this.paragraph.blockstyle,this.paragraph.priorblockstyle||{},this.paragraph={text:[],style:[],blockstyle:{},priorblockstyle:e},r.join("").trim()){s=this.splitFragmentsIntoLines(r,f),c=a=void 0,n=12/this.pdf.internal.scaleFactor,this.priorMarginBottom=this.priorMarginBottom||0,u=(Math.max((e["margin-top"]||0)-this.priorMarginBottom,0)+(e["padding-top"]||0))*n,h=((e["margin-bottom"]||0)+(e["padding-bottom"]||0))*n,this.priorMarginBottom=e["margin-bottom"]||0,"always"===e["page-break-before"]&&(this.pdf.addPage(),this.y=0,u=((e["margin-top"]||0)+(e["padding-top"]||0))*n),l=this.pdf.internal.write,o=i=void 0,this.y+=u,l("q","BT 0 g",this.pdf.internal.getCoordinateString(this.x),this.pdf.internal.getVerticalCoordinateString(this.y),"Td");for(var p=0;s.length;){for(i=c=0,o=(a=s.shift()).length;i!==o;)a[i][0].trim()&&(c=Math.max(c,a[i][1]["line-height"],a[i][1]["font-size"]),d=7*a[i][1]["font-size"]),i++;var g=0,m=0;for(void 0!==a[0][1]["margin-left"]&&0<a[0][1]["margin-left"]&&(g=(m=this.pdf.internal.getCoordinateString(a[0][1]["margin-left"]))-p,p=m),l(g+Math.max(e["margin-left"]||0,0)*n,(-12*c).toFixed(2),"Td"),i=0,o=a.length;i!==o;)a[i][0]&&this.RenderTextFragment(a[i][0],a[i][1]),i++;if(this.y+=c*n,this.executeWatchFunctions(a[0][1])&&0<s.length){var y=[],w=[];s.forEach(function(t){for(var e=0,n=t.length;e!==n;)t[e][0]&&(y.push(t[e][0]+" "),w.push(t[e][1])),++e}),s=this.splitFragmentsIntoLines(v(y),w),l("ET","Q"),l("q","BT 0 g",this.pdf.internal.getCoordinateString(this.x),this.pdf.internal.getVerticalCoordinateString(this.y),"Td")}}return t&&"function"==typeof t&&t.call(this,this.x-9,this.y-d/2),l("ET","Q"),this.y+=h}},f.prototype.setBlockBoundary=function(t){return this.renderParagraph(t)},f.prototype.setBlockStyle=function(t){return this.paragraph.blockstyle=t},f.prototype.addText=function(t,e){return this.paragraph.text.push(t),this.paragraph.style.push(e)},i={helvetica:"helvetica","sans-serif":"helvetica","times new roman":"times",serif:"times",times:"times",monospace:"courier",courier:"courier"},c={100:"normal",200:"normal",300:"normal",400:"normal",500:"bold",600:"bold",700:"bold",800:"bold",900:"bold",normal:"normal",bold:"bold",bolder:"bold",lighter:"normal"},a={normal:"normal",italic:"italic",oblique:"italic"},s={left:"left",right:"right",center:"center",justify:"justify"},l={none:"none",right:"right",left:"left"},h={none:"none",both:"both"},n={normal:1},t.fromHTML=function(t,e,n,r,i,o){return this.margins_doc=o||{top:0,bottom:0},r||(r={}),r.elementHandlers||(r.elementHandlers={}),m(this,t,isNaN(e)?4:e,isNaN(n)?4:n,r,i)}}(K.API),K.API.addJS=function(t){return s=t,this.internal.events.subscribe("postPutResources",function(t){n=this.internal.newObject(),this.internal.out("<<"),this.internal.out("/Names [(EmbeddedJS) "+(n+1)+" 0 R]"),this.internal.out(">>"),this.internal.out("endobj"),r=this.internal.newObject(),this.internal.out("<<"),this.internal.out("/S /JavaScript"),this.internal.out("/JS ("+s+")"),this.internal.out(">>"),this.internal.out("endobj")}),this.internal.events.subscribe("putCatalog",function(){void 0!==n&&void 0!==r&&this.internal.out("/Names <</JavaScript "+n+" 0 R>>")}),this},(
+/**
+   * jsPDF Outline PlugIn
+   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+l=K.API).events.push(["postPutResources",function(){var t=this,e=/^(\d+) 0 obj$/;if(0<this.outline.root.children.length)for(var n=t.outline.render().split(/\r\n/),r=0;r<n.length;r++){var i=n[r],o=e.exec(i);if(null!=o){var a=o[1];t.internal.newObjectDeferredBegin(a)}t.internal.write(i)}if(this.outline.createNamedDestinations){var s=this.internal.pages.length,c=[];for(r=0;r<s;r++){var l=t.internal.newObject();c.push(l);var h=t.internal.getPageInfo(r+1);t.internal.write("<< /D["+h.objId+" 0 R /XYZ null null null]>> endobj")}var u=t.internal.newObject();for(t.internal.write("<< /Names [ "),r=0;r<c.length;r++)t.internal.write("(page_"+(r+1)+")"+c[r]+" 0 R");t.internal.write(" ] >>","endobj"),t.internal.newObject(),t.internal.write("<< /Dests "+u+" 0 R"),t.internal.write(">>","endobj")}}]),l.events.push(["putCatalog",function(){0<this.outline.root.children.length&&(this.internal.write("/Outlines",this.outline.makeRef(this.outline.root)),this.outline.createNamedDestinations&&this.internal.write("/Names "+namesOid+" 0 R"))}]),l.events.push(["initialized",function(){var o=this;o.outline={createNamedDestinations:!1,root:{children:[]}},o.outline.add=function(t,e,n){var r={title:e,options:n,children:[]};return null==t&&(t=this.root),t.children.push(r),r},o.outline.render=function(){return this.ctx={},this.ctx.val="",this.ctx.pdf=o,this.genIds_r(this.root),this.renderRoot(this.root),this.renderItems(this.root),this.ctx.val},o.outline.genIds_r=function(t){t.id=o.internal.newObjectDeferred();for(var e=0;e<t.children.length;e++)this.genIds_r(t.children[e])},o.outline.renderRoot=function(t){this.objStart(t),this.line("/Type /Outlines"),0<t.children.length&&(this.line("/First "+this.makeRef(t.children[0])),this.line("/Last "+this.makeRef(t.children[t.children.length-1]))),this.line("/Count "+this.count_r({count:0},t)),this.objEnd()},o.outline.renderItems=function(t){for(var e=0;e<t.children.length;e++){var n=t.children[e];this.objStart(n),this.line("/Title "+this.makeString(n.title)),this.line("/Parent "+this.makeRef(t)),0<e&&this.line("/Prev "+this.makeRef(t.children[e-1])),e<t.children.length-1&&this.line("/Next "+this.makeRef(t.children[e+1])),0<n.children.length&&(this.line("/First "+this.makeRef(n.children[0])),this.line("/Last "+this.makeRef(n.children[n.children.length-1])));var r=this.count=this.count_r({count:0},n);if(0<r&&this.line("/Count "+r),n.options&&n.options.pageNumber){var i=o.internal.getPageInfo(n.options.pageNumber);this.line("/Dest ["+i.objId+" 0 R /XYZ 0 "+this.ctx.pdf.internal.pageSize.getHeight()*this.ctx.pdf.internal.scaleFactor+" 0]")}this.objEnd()}for(e=0;e<t.children.length;e++)n=t.children[e],this.renderItems(n)},o.outline.line=function(t){this.ctx.val+=t+"\r\n"},o.outline.makeRef=function(t){return t.id+" 0 R"},o.outline.makeString=function(t){return"("+o.internal.pdfEscape(t)+")"},o.outline.objStart=function(t){this.ctx.val+="\r\n"+t.id+" 0 obj\r\n<<\r\n"},o.outline.objEnd=function(t){this.ctx.val+=">> \r\nendobj\r\n"},o.outline.count_r=function(t,e){for(var n=0;n<e.children.length;n++)t.count++,this.count_r(t,e.children[n]);return t.count}}]),
+/**@preserve
+   *  ====================================================================
+   * jsPDF PNG PlugIn
+   * Copyright (c) 2014 James Robb, https://github.com/jamesbrobb
+   *
+   * 
+   * ====================================================================
+   */
+q=K.API,E=function(){var t="function"==typeof Deflater;if(!t)throw new Error("requires deflate.js for compression");return t},P=function(t,e,n,r){var i=5,o=b;switch(r){case q.image_compression.FAST:i=3,o=v;break;case q.image_compression.MEDIUM:i=6,o=x;break;case q.image_compression.SLOW:i=9,o=S}t=y(t,e,n,o);var a=new Uint8Array(g(i)),s=m(t),c=new Deflater(i),l=c.append(t),h=c.flush(),u=a.length+l.length+h.length,f=new Uint8Array(u+4);return f.set(a),f.set(l,a.length),f.set(h,a.length+l.length),f[u++]=s>>>24&255,f[u++]=s>>>16&255,f[u++]=s>>>8&255,f[u++]=255&s,q.arrayBufferToBinaryString(f)},g=function(t,e){var n=Math.LOG2E*Math.log(32768)-8<<4|8,r=n<<8;return r|=Math.min(3,(e-1&255)>>1)<<6,r|=0,[n,255&(r+=31-r%31)]},m=function(t,e){for(var n,r=1,i=0,o=t.length,a=0;0<o;){for(o-=n=e<o?e:o;i+=r+=t[a++],--n;);r%=65521,i%=65521}return(i<<16|r)>>>0},y=function(t,e,n,r){for(var i,o,a,s=t.length/e,c=new Uint8Array(t.length+s),l=k(),h=0;h<s;h++){if(a=h*e,i=t.subarray(a,a+e),r)c.set(r(i,n,o),a+h);else{for(var u=0,f=l.length,d=[];u<f;u++)d[u]=l[u](i,n,o);var p=_(d.concat());c.set(d[p],a+h)}o=i}return c},h=function(t,e,n){var r=Array.apply([],t);return r.unshift(0),r},v=function(t,e,n){var r,i=[],o=0,a=t.length;for(i[0]=1;o<a;o++)r=t[o-e]||0,i[o+1]=t[o]-r+256&255;return i},b=function(t,e,n){var r,i=[],o=0,a=t.length;for(i[0]=2;o<a;o++)r=n&&n[o]||0,i[o+1]=t[o]-r+256&255;return i},x=function(t,e,n){var r,i,o=[],a=0,s=t.length;for(o[0]=3;a<s;a++)r=t[a-e]||0,i=n&&n[a]||0,o[a+1]=t[a]+256-(r+i>>>1)&255;return o},S=function(t,e,n){var r,i,o,a,s=[],c=0,l=t.length;for(s[0]=4;c<l;c++)r=t[c-e]||0,i=n&&n[c]||0,o=n&&n[c-e]||0,a=u(r,i,o),s[c+1]=t[c]-a+256&255;return s},u=function(t,e,n){var r=t+e-n,i=Math.abs(r-t),o=Math.abs(r-e),a=Math.abs(r-n);return i<=o&&i<=a?t:o<=a?e:n},k=function(){return[h,v,b,x,S]},_=function(t){for(var e,n,r,i=0,o=t.length;i<o;)((e=f(t[i].slice(1)))<n||!n)&&(n=e,r=i),i++;return r},f=function(t){for(var e=0,n=t.length,r=0;e<n;)r+=Math.abs(t[e++]);return r},q.processPNG=function(t,e,n,r,i){var o,a,s,c,l,h,u=this.color_spaces.DEVICE_RGB,f=this.decode.FLATE_DECODE,d=8;if(this.isArrayBuffer(t)&&(t=new Uint8Array(t)),this.isArrayBufferView(t)){if("function"!=typeof PNG||"function"!=typeof gt)throw new Error("PNG support requires png.js and zlib.js");if(t=(o=new PNG(t)).imgData,d=o.bits,u=o.colorSpace,c=o.colors,-1!==[4,6].indexOf(o.colorType)){if(8===o.bits)for(var p,g=(I=32==o.pixelBitlength?new Uint32Array(o.decodePixels().buffer):16==o.pixelBitlength?new Uint16Array(o.decodePixels().buffer):new Uint8Array(o.decodePixels().buffer)).length,m=new Uint8Array(g*o.colors),y=new Uint8Array(g),w=o.pixelBitlength-o.bits,v=0,b=0;v<g;v++){for(x=I[v],p=0;p<w;)m[b++]=x>>>p&255,p+=o.bits;y[v]=x>>>p&255}if(16===o.bits){g=(I=new Uint32Array(o.decodePixels().buffer)).length,m=new Uint8Array(g*(32/o.pixelBitlength)*o.colors),y=new Uint8Array(g*(32/o.pixelBitlength));for(var x,S=1<o.colors,k=b=v=0;v<g;)x=I[v++],m[b++]=x>>>0&255,S&&(m[b++]=x>>>16&255,x=I[v++],m[b++]=x>>>0&255),y[k++]=x>>>16&255;d=8}r!==q.image_compression.NONE&&E()?(t=P(m,o.width*o.colors,o.colors,r),h=P(y,o.width,1,r)):(t=m,h=y,f=null)}if(3===o.colorType&&(u=this.color_spaces.INDEXED,l=o.palette,o.transparency.indexed)){var _=o.transparency.indexed,C=0;for(v=0,g=_.length;v<g;++v)C+=_[v];if((C/=255)==g-1&&-1!==_.indexOf(0))s=[_.indexOf(0)];else if(C!==g){var I=o.decodePixels();for(y=new Uint8Array(I.length),v=0,g=I.length;v<g;v++)y[v]=_[I[v]];h=P(y,o.width,1)}}var A=function(t){var e;switch(t){case q.image_compression.FAST:e=11;break;case q.image_compression.MEDIUM:e=13;break;case q.image_compression.SLOW:e=14;break;default:e=12}return e}(r);return a=f===this.decode.FLATE_DECODE?"/Predictor "+A+" /Colors "+c+" /BitsPerComponent "+d+" /Columns "+o.width:"/Colors "+c+" /BitsPerComponent "+d+" /Columns "+o.width,(this.isArrayBuffer(t)||this.isArrayBufferView(t))&&(t=this.arrayBufferToBinaryString(t)),(h&&this.isArrayBuffer(h)||this.isArrayBufferView(h))&&(h=this.arrayBufferToBinaryString(h)),this.createImageInfo(t,o.width,o.height,u,d,f,e,n,a,s,l,h,A)}throw new Error("Unsupported PNG image data, try using JPEG instead.")},K.API.setLanguage=function(t){return void 0===this.internal.languageSettings&&(this.internal.languageSettings={},this.internal.languageSettings.isSubscribed=!1),void 0!=={af:"Afrikaans",sq:"Albanian",ar:"Arabic (Standard)","ar-DZ":"Arabic (Algeria)","ar-BH":"Arabic (Bahrain)","ar-EG":"Arabic (Egypt)","ar-IQ":"Arabic (Iraq)","ar-JO":"Arabic (Jordan)","ar-KW":"Arabic (Kuwait)","ar-LB":"Arabic (Lebanon)","ar-LY":"Arabic (Libya)","ar-MA":"Arabic (Morocco)","ar-OM":"Arabic (Oman)","ar-QA":"Arabic (Qatar)","ar-SA":"Arabic (Saudi Arabia)","ar-SY":"Arabic (Syria)","ar-TN":"Arabic (Tunisia)","ar-AE":"Arabic (U.A.E.)","ar-YE":"Arabic (Yemen)",an:"Aragonese",hy:"Armenian",as:"Assamese",ast:"Asturian",az:"Azerbaijani",eu:"Basque",be:"Belarusian",bn:"Bengali",bs:"Bosnian",br:"Breton",bg:"Bulgarian",my:"Burmese",ca:"Catalan",ch:"Chamorro",ce:"Chechen",zh:"Chinese","zh-HK":"Chinese (Hong Kong)","zh-CN":"Chinese (PRC)","zh-SG":"Chinese (Singapore)","zh-TW":"Chinese (Taiwan)",cv:"Chuvash",co:"Corsican",cr:"Cree",hr:"Croatian",cs:"Czech",da:"Danish",nl:"Dutch (Standard)","nl-BE":"Dutch (Belgian)",en:"English","en-AU":"English (Australia)","en-BZ":"English (Belize)","en-CA":"English (Canada)","en-IE":"English (Ireland)","en-JM":"English (Jamaica)","en-NZ":"English (New Zealand)","en-PH":"English (Philippines)","en-ZA":"English (South Africa)","en-TT":"English (Trinidad & Tobago)","en-GB":"English (United Kingdom)","en-US":"English (United States)","en-ZW":"English (Zimbabwe)",eo:"Esperanto",et:"Estonian",fo:"Faeroese",fj:"Fijian",fi:"Finnish",fr:"French (Standard)","fr-BE":"French (Belgium)","fr-CA":"French (Canada)","fr-FR":"French (France)","fr-LU":"French (Luxembourg)","fr-MC":"French (Monaco)","fr-CH":"French (Switzerland)",fy:"Frisian",fur:"Friulian",gd:"Gaelic (Scots)","gd-IE":"Gaelic (Irish)",gl:"Galacian",ka:"Georgian",de:"German (Standard)","de-AT":"German (Austria)","de-DE":"German (Germany)","de-LI":"German (Liechtenstein)","de-LU":"German (Luxembourg)","de-CH":"German (Switzerland)",el:"Greek",gu:"Gujurati",ht:"Haitian",he:"Hebrew",hi:"Hindi",hu:"Hungarian",is:"Icelandic",id:"Indonesian",iu:"Inuktitut",ga:"Irish",it:"Italian (Standard)","it-CH":"Italian (Switzerland)",ja:"Japanese",kn:"Kannada",ks:"Kashmiri",kk:"Kazakh",km:"Khmer",ky:"Kirghiz",tlh:"Klingon",ko:"Korean","ko-KP":"Korean (North Korea)","ko-KR":"Korean (South Korea)",la:"Latin",lv:"Latvian",lt:"Lithuanian",lb:"Luxembourgish",mk:"FYRO Macedonian",ms:"Malay",ml:"Malayalam",mt:"Maltese",mi:"Maori",mr:"Marathi",mo:"Moldavian",nv:"Navajo",ng:"Ndonga",ne:"Nepali",no:"Norwegian",nb:"Norwegian (Bokmal)",nn:"Norwegian (Nynorsk)",oc:"Occitan",or:"Oriya",om:"Oromo",fa:"Persian","fa-IR":"Persian/Iran",pl:"Polish",pt:"Portuguese","pt-BR":"Portuguese (Brazil)",pa:"Punjabi","pa-IN":"Punjabi (India)","pa-PK":"Punjabi (Pakistan)",qu:"Quechua",rm:"Rhaeto-Romanic",ro:"Romanian","ro-MO":"Romanian (Moldavia)",ru:"Russian","ru-MO":"Russian (Moldavia)",sz:"Sami (Lappish)",sg:"Sango",sa:"Sanskrit",sc:"Sardinian",sd:"Sindhi",si:"Singhalese",sr:"Serbian",sk:"Slovak",sl:"Slovenian",so:"Somani",sb:"Sorbian",es:"Spanish","es-AR":"Spanish (Argentina)","es-BO":"Spanish (Bolivia)","es-CL":"Spanish (Chile)","es-CO":"Spanish (Colombia)","es-CR":"Spanish (Costa Rica)","es-DO":"Spanish (Dominican Republic)","es-EC":"Spanish (Ecuador)","es-SV":"Spanish (El Salvador)","es-GT":"Spanish (Guatemala)","es-HN":"Spanish (Honduras)","es-MX":"Spanish (Mexico)","es-NI":"Spanish (Nicaragua)","es-PA":"Spanish (Panama)","es-PY":"Spanish (Paraguay)","es-PE":"Spanish (Peru)","es-PR":"Spanish (Puerto Rico)","es-ES":"Spanish (Spain)","es-UY":"Spanish (Uruguay)","es-VE":"Spanish (Venezuela)",sx:"Sutu",sw:"Swahili",sv:"Swedish","sv-FI":"Swedish (Finland)","sv-SV":"Swedish (Sweden)",ta:"Tamil",tt:"Tatar",te:"Teluga",th:"Thai",tig:"Tigre",ts:"Tsonga",tn:"Tswana",tr:"Turkish",tk:"Turkmen",uk:"Ukrainian",hsb:"Upper Sorbian",ur:"Urdu",ve:"Venda",vi:"Vietnamese",vo:"Volapuk",wa:"Walloon",cy:"Welsh",xh:"Xhosa",ji:"Yiddish",zu:"Zulu"}[t]&&(this.internal.languageSettings.languageCode=t,!1===this.internal.languageSettings.isSubscribed&&(this.internal.events.subscribe("putCatalog",function(){this.internal.write("/Lang ("+this.internal.languageSettings.languageCode+")")}),this.internal.languageSettings.isSubscribed=!0)),this},
+/** @preserve
+   * jsPDF split_text_to_size plugin - MIT license.
+   * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
+   *               2014 Diego Casorran, https://github.com/diegocr
+   */
+C=K.API,O=C.getCharWidthsArray=function(t,e){e||(e={});var n,r=t.length,i=[];if(e.font){var o=e.fontSize,a=e.charSpace;for(n=0;n<r;n++)i.push(e.font.widthOfString(t[n],o,a)/o);return i}var s=e.widths?e.widths:this.internal.getFont().metadata.Unicode.widths,c=s.fof?s.fof:1,l=e.kerning?e.kerning:this.internal.getFont().metadata.Unicode.kerning,h=l.fof?l.fof:1,u=0,f=0,d=s[0]||c;for(n=0,r=t.length;n<r;n++)u=t.charCodeAt(n),i.push((s[u]||d)/c+(l[u]&&l[u][f]||0)/h),f=u;return i},B=function(t){for(var e=t.length,n=0;e;)n+=t[--e];return n},j=C.getStringUnitWidth=function(t,e){return B(O.call(this,t,e))},R=function(t,e,n,r){for(var i=[],o=0,a=t.length,s=0;o!==a&&s+e[o]<n;)s+=e[o],o++;i.push(t.slice(0,o));var c=o;for(s=0;o!==a;)s+e[o]>r&&(i.push(t.slice(c,o)),s=0,c=o),s+=e[o],o++;return c!==o&&i.push(t.slice(c,o)),i},D=function(t,e,n){n||(n={});var r,i,o,a,s,c,l=[],h=[l],u=n.textIndent||0,f=0,d=0,p=t.split(" "),g=O(" ",n)[0];if(c=-1===n.lineIndent?p[0].length+2:n.lineIndent||0){var m=Array(c).join(" "),y=[];p.map(function(t){1<(t=t.split(/\s*\n/)).length?y=y.concat(t.map(function(t,e){return(e&&t.length?"\n":"")+t})):y.push(t[0])}),p=y,c=j(m,n)}for(o=0,a=p.length;o<a;o++){var w=0;if(r=p[o],c&&"\n"==r[0]&&(r=r.substr(1),w=1),i=O(r,n),e<u+f+(d=B(i))||w){if(e<d){for(s=R(r,i,e-(u+f),e),l.push(s.shift()),l=[s.pop()];s.length;)h.push([s.shift()]);d=B(i.slice(r.length-(l[0]?l[0].length:0)))}else l=[r];h.push(l),u=d+c,f=g}else l.push(r),u+=f+d,f=g}if(c)var v=function(t,e){return(e?m:"")+t.join(" ")};else v=function(t){return t.join(" ")};return h.map(v)},C.splitTextToSize=function(t,e,n){n||(n={});var r,i=n.fontSize||this.internal.getFontSize(),o=function(t){var e={0:1},n={};if(t.widths&&t.kerning)return{widths:t.widths,kerning:t.kerning};var r=this.internal.getFont(t.fontName,t.fontStyle),i="Unicode";return r.metadata[i]?{widths:r.metadata[i].widths||e,kerning:r.metadata[i].kerning||n}:{font:r.metadata,fontSize:this.internal.getFontSize(),charSpace:this.internal.getCharSpace()}}.call(this,n);r=Array.isArray(t)?t:t.split(/\r?\n/);var a=1*this.internal.scaleFactor*e/i;o.textIndent=n.textIndent?1*n.textIndent*this.internal.scaleFactor/i:0,o.lineIndent=n.lineIndent;var s,c,l=[];for(s=0,c=r.length;s<c;s++)l=l.concat(D(r[s],a,o));return l},
+/** @preserve 
+  jsPDF standard_fonts_metrics plugin
+  Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
+  MIT license.
+  */
+M=K.API,N={codePages:["WinAnsiEncoding"],WinAnsiEncoding:(z=function(t){for(var e="klmnopqrstuvwxyz",n={},r=0;r<e.length;r++)n[e[r]]="0123456789abcdef"[r];var i,o,a,s,c,l={},h=1,u=l,f=[],d="",p="",g=t.length-1;for(r=1;r!=g;)c=t[r],r+=1,"'"==c?o?(s=o.join(""),o=i):o=[]:o?o.push(c):"{"==c?(f.push([u,s]),u={},s=i):"}"==c?((a=f.pop())[0][a[1]]=u,s=i,u=a[0]):"-"==c?h=-1:s===i?n.hasOwnProperty(c)?(d+=n[c],s=parseInt(d,16)*h,h=1,d=""):d+=c:n.hasOwnProperty(c)?(p+=n[c],u[s]=parseInt(p,16)*h,h=1,s=i,p=""):p+=c;return l})("{19m8n201n9q201o9r201s9l201t9m201u8m201w9n201x9o201y8o202k8q202l8r202m9p202q8p20aw8k203k8t203t8v203u9v2cq8s212m9t15m8w15n9w2dw9s16k8u16l9u17s9z17x8y17y9y}")},L={Unicode:{Courier:N,"Courier-Bold":N,"Courier-BoldOblique":N,"Courier-Oblique":N,Helvetica:N,"Helvetica-Bold":N,"Helvetica-BoldOblique":N,"Helvetica-Oblique":N,"Times-Roman":N,"Times-Bold":N,"Times-BoldItalic":N,"Times-Italic":N}
+/** 
+    Resources:
+    Font metrics data is reprocessed derivative of contents of
+    "Font Metrics for PDF Core 14 Fonts" package, which exhibits the following copyright and license:
+    
+    Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
+    
+    This file and the 14 PostScript(R) AFM files it accompanies may be used,
+    copied, and distributed for any purpose and without charge, with or without
+    modification, provided that all copyright notices are retained; that the AFM
+    files are not distributed without this file; that all modifications to this
+    file or any of the AFM files are prominently noted in the modified file(s);
+    and that this paragraph is not modified. Adobe Systems has no responsibility
+    or obligation to support the use of the AFM files.
+    
+    */},U={Unicode:{"Courier-Oblique":z("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-BoldItalic":z("{'widths'{k3o2q4ycx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2r202m2n2n3m2o3m2p5n202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5n4l4m4m4m4n4m4o4s4p4m4q4m4r4s4s4y4t2r4u3m4v4m4w3x4x5t4y4s4z4s5k3x5l4s5m4m5n3r5o3x5p4s5q4m5r5t5s4m5t3x5u3x5v2l5w1w5x2l5y3t5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q2l6r3m6s3r6t1w6u1w6v3m6w1w6x4y6y3r6z3m7k3m7l3m7m2r7n2r7o1w7p3r7q2w7r4m7s3m7t2w7u2r7v2n7w1q7x2n7y3t202l3mcl4mal2ram3man3mao3map3mar3mas2lat4uau1uav3maw3way4uaz2lbk2sbl3t'fof'6obo2lbp3tbq3mbr1tbs2lbu1ybv3mbz3mck4m202k3mcm4mcn4mco4mcp4mcq5ycr4mcs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz2w203k6o212m6o2dw2l2cq2l3t3m3u2l17s3x19m3m}'kerning'{cl{4qu5kt5qt5rs17ss5ts}201s{201ss}201t{cks4lscmscnscoscpscls2wu2yu201ts}201x{2wu2yu}2k{201ts}2w{4qx5kx5ou5qx5rs17su5tu}2x{17su5tu5ou}2y{4qx5kx5ou5qx5rs17ss5ts}'fof'-6ofn{17sw5tw5ou5qw5rs}7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qs}3v{17su5tu5os5qs}7p{17su5tu}ck{4qu5kt5qt5rs17ss5ts}4l{4qu5kt5qt5rs17ss5ts}cm{4qu5kt5qt5rs17ss5ts}cn{4qu5kt5qt5rs17ss5ts}co{4qu5kt5qt5rs17ss5ts}cp{4qu5kt5qt5rs17ss5ts}6l{4qu5ou5qw5rt17su5tu}5q{ckuclucmucnucoucpu4lu}5r{ckuclucmucnucoucpu4lu}7q{cksclscmscnscoscps4ls}6p{4qu5ou5qw5rt17sw5tw}ek{4qu5ou5qw5rt17su5tu}el{4qu5ou5qw5rt17su5tu}em{4qu5ou5qw5rt17su5tu}en{4qu5ou5qw5rt17su5tu}eo{4qu5ou5qw5rt17su5tu}ep{4qu5ou5qw5rt17su5tu}es{17ss5ts5qs4qu}et{4qu5ou5qw5rt17sw5tw}eu{4qu5ou5qw5rt17ss5ts}ev{17ss5ts5qs4qu}6z{17sw5tw5ou5qw5rs}fm{17sw5tw5ou5qw5rs}7n{201ts}fo{17sw5tw5ou5qw5rs}fp{17sw5tw5ou5qw5rs}fq{17sw5tw5ou5qw5rs}7r{cksclscmscnscoscps4ls}fs{17sw5tw5ou5qw5rs}ft{17su5tu}fu{17su5tu}fv{17su5tu}fw{17su5tu}fz{cksclscmscnscoscps4ls}}}"),"Helvetica-Bold":z("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),Courier:z("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Courier-BoldOblique":z("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-Bold":z("{'widths'{k3q2q5ncx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2l202m2n2n3m2o3m2p6o202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5x4l4s4m4m4n4s4o4s4p4m4q3x4r4y4s4y4t2r4u3m4v4y4w4m4x5y4y4s4z4y5k3x5l4y5m4s5n3r5o4m5p4s5q4s5r6o5s4s5t4s5u4m5v2l5w1w5x2l5y3u5z3m6k2l6l3m6m3r6n2w6o3r6p2w6q2l6r3m6s3r6t1w6u2l6v3r6w1w6x5n6y3r6z3m7k3r7l3r7m2w7n2r7o2l7p3r7q3m7r4s7s3m7t3m7u2w7v2r7w1q7x2r7y3o202l3mcl4sal2lam3man3mao3map3mar3mas2lat4uau1yav3maw3tay4uaz2lbk2sbl3t'fof'6obo2lbp3rbr1tbs2lbu2lbv3mbz3mck4s202k3mcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3rek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3m3u2l17s4s19m3m}'kerning'{cl{4qt5ks5ot5qy5rw17sv5tv}201t{cks4lscmscnscoscpscls4wv}2k{201ts}2w{4qu5ku7mu5os5qx5ru17su5tu}2x{17su5tu5ou5qs}2y{4qv5kv7mu5ot5qz5ru17su5tu}'fof'-6o7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qu}3v{17su5tu5os5qu}fu{17su5tu5ou5qu}7p{17su5tu5ou5qu}ck{4qt5ks5ot5qy5rw17sv5tv}4l{4qt5ks5ot5qy5rw17sv5tv}cm{4qt5ks5ot5qy5rw17sv5tv}cn{4qt5ks5ot5qy5rw17sv5tv}co{4qt5ks5ot5qy5rw17sv5tv}cp{4qt5ks5ot5qy5rw17sv5tv}6l{17st5tt5ou5qu}17s{ckuclucmucnucoucpu4lu4wu}5o{ckuclucmucnucoucpu4lu4wu}5q{ckzclzcmzcnzcozcpz4lz4wu}5r{ckxclxcmxcnxcoxcpx4lx4wu}5t{ckuclucmucnucoucpu4lu4wu}7q{ckuclucmucnucoucpu4lu}6p{17sw5tw5ou5qu}ek{17st5tt5qu}el{17st5tt5ou5qu}em{17st5tt5qu}en{17st5tt5qu}eo{17st5tt5qu}ep{17st5tt5ou5qu}es{17ss5ts5qu}et{17sw5tw5ou5qu}eu{17sw5tw5ou5qu}ev{17ss5ts5qu}6z{17sw5tw5ou5qu5rs}fm{17sw5tw5ou5qu5rs}fn{17sw5tw5ou5qu5rs}fo{17sw5tw5ou5qu5rs}fp{17sw5tw5ou5qu5rs}fq{17sw5tw5ou5qu5rs}7r{cktcltcmtcntcotcpt4lt5os}fs{17sw5tw5ou5qu5rs}ft{17su5tu5ou5qu}7m{5os}fv{17su5tu5ou5qu}fw{17su5tu5ou5qu}fz{cksclscmscnscoscps4ls}}}"),Symbol:z("{'widths'{k3uaw4r19m3m2k1t2l2l202m2y2n3m2p5n202q6o3k3m2s2l2t2l2v3r2w1t3m3m2y1t2z1wbk2sbl3r'fof'6o3n3m3o3m3p3m3q3m3r3m3s3m3t3m3u1w3v1w3w3r3x3r3y3r3z2wbp3t3l3m5v2l5x2l5z3m2q4yfr3r7v3k7w1o7x3k}'kerning'{'fof'-6o}}"),Helvetica:z("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}"),"Helvetica-BoldOblique":z("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),ZapfDingbats:z("{'widths'{k4u2k1w'fof'6o}'kerning'{'fof'-6o}}"),"Courier-Bold":z("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-Italic":z("{'widths'{k3n2q4ycx2l201n3m201o5t201s2l201t2l201u2l201w3r201x3r201y3r2k1t2l2l202m2n2n3m2o3m2p5n202q5t2r1p2s2l2t2l2u3m2v4n2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w4n3x4n3y4n3z3m4k5w4l3x4m3x4n4m4o4s4p3x4q3x4r4s4s4s4t2l4u2w4v4m4w3r4x5n4y4m4z4s5k3x5l4s5m3x5n3m5o3r5p4s5q3x5r5n5s3x5t3r5u3r5v2r5w1w5x2r5y2u5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q1w6r3m6s3m6t1w6u1w6v2w6w1w6x4s6y3m6z3m7k3m7l3m7m2r7n2r7o1w7p3m7q2w7r4m7s2w7t2w7u2r7v2s7w1v7x2s7y3q202l3mcl3xal2ram3man3mao3map3mar3mas2lat4wau1vav3maw4nay4waz2lbk2sbl4n'fof'6obo2lbp3mbq3obr1tbs2lbu1zbv3mbz3mck3x202k3mcm3xcn3xco3xcp3xcq5tcr4mcs3xct3xcu3xcv3xcw2l2m2ucy2lcz2ldl4mdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr4nfs3mft3mfu3mfv3mfw3mfz2w203k6o212m6m2dw2l2cq2l3t3m3u2l17s3r19m3m}'kerning'{cl{5kt4qw}201s{201sw}201t{201tw2wy2yy6q-t}201x{2wy2yy}2k{201tw}2w{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}2x{17ss5ts5os}2y{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}'fof'-6o6t{17ss5ts5qs}7t{5os}3v{5qs}7p{17su5tu5qs}ck{5kt4qw}4l{5kt4qw}cm{5kt4qw}cn{5kt4qw}co{5kt4qw}cp{5kt4qw}6l{4qs5ks5ou5qw5ru17su5tu}17s{2ks}5q{ckvclvcmvcnvcovcpv4lv}5r{ckuclucmucnucoucpu4lu}5t{2ks}6p{4qs5ks5ou5qw5ru17su5tu}ek{4qs5ks5ou5qw5ru17su5tu}el{4qs5ks5ou5qw5ru17su5tu}em{4qs5ks5ou5qw5ru17su5tu}en{4qs5ks5ou5qw5ru17su5tu}eo{4qs5ks5ou5qw5ru17su5tu}ep{4qs5ks5ou5qw5ru17su5tu}es{5ks5qs4qs}et{4qs5ks5ou5qw5ru17su5tu}eu{4qs5ks5qw5ru17su5tu}ev{5ks5qs4qs}ex{17ss5ts5qs}6z{4qv5ks5ou5qw5ru17su5tu}fm{4qv5ks5ou5qw5ru17su5tu}fn{4qv5ks5ou5qw5ru17su5tu}fo{4qv5ks5ou5qw5ru17su5tu}fp{4qv5ks5ou5qw5ru17su5tu}fq{4qv5ks5ou5qw5ru17su5tu}7r{5os}fs{4qv5ks5ou5qw5ru17su5tu}ft{17su5tu5qs}fu{17su5tu5qs}fv{17su5tu5qs}fw{17su5tu5qs}}}"),"Times-Roman":z("{'widths'{k3n2q4ycx2l201n3m201o6o201s2l201t2l201u2l201w2w201x2w201y2w2k1t2l2l202m2n2n3m2o3m2p5n202q6o2r1m2s2l2t2l2u3m2v3s2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v1w3w3s3x3s3y3s3z2w4k5w4l4s4m4m4n4m4o4s4p3x4q3r4r4s4s4s4t2l4u2r4v4s4w3x4x5t4y4s4z4s5k3r5l4s5m4m5n3r5o3x5p4s5q4s5r5y5s4s5t4s5u3x5v2l5w1w5x2l5y2z5z3m6k2l6l2w6m3m6n2w6o3m6p2w6q2l6r3m6s3m6t1w6u1w6v3m6w1w6x4y6y3m6z3m7k3m7l3m7m2l7n2r7o1w7p3m7q3m7r4s7s3m7t3m7u2w7v3k7w1o7x3k7y3q202l3mcl4sal2lam3man3mao3map3mar3mas2lat4wau1vav3maw3say4waz2lbk2sbl3s'fof'6obo2lbp3mbq2xbr1tbs2lbu1zbv3mbz2wck4s202k3mcm4scn4sco4scp4scq5tcr4mcs3xct3xcu3xcv3xcw2l2m2tcy2lcz2ldl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek2wel2wem2wen2weo2wep2weq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr3sfs3mft3mfu3mfv3mfw3mfz3m203k6o212m6m2dw2l2cq2l3t3m3u1w17s4s19m3m}'kerning'{cl{4qs5ku17sw5ou5qy5rw201ss5tw201ws}201s{201ss}201t{ckw4lwcmwcnwcowcpwclw4wu201ts}2k{201ts}2w{4qs5kw5os5qx5ru17sx5tx}2x{17sw5tw5ou5qu}2y{4qs5kw5os5qx5ru17sx5tx}'fof'-6o7t{ckuclucmucnucoucpu4lu5os5rs}3u{17su5tu5qs}3v{17su5tu5qs}7p{17sw5tw5qs}ck{4qs5ku17sw5ou5qy5rw201ss5tw201ws}4l{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cm{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cn{4qs5ku17sw5ou5qy5rw201ss5tw201ws}co{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cp{4qs5ku17sw5ou5qy5rw201ss5tw201ws}6l{17su5tu5os5qw5rs}17s{2ktclvcmvcnvcovcpv4lv4wuckv}5o{ckwclwcmwcnwcowcpw4lw4wu}5q{ckyclycmycnycoycpy4ly4wu5ms}5r{cktcltcmtcntcotcpt4lt4ws}5t{2ktclvcmvcnvcovcpv4lv4wuckv}7q{cksclscmscnscoscps4ls}6p{17su5tu5qw5rs}ek{5qs5rs}el{17su5tu5os5qw5rs}em{17su5tu5os5qs5rs}en{17su5qs5rs}eo{5qs5rs}ep{17su5tu5os5qw5rs}es{5qs}et{17su5tu5qw5rs}eu{17su5tu5qs5rs}ev{5qs}6z{17sv5tv5os5qx5rs}fm{5os5qt5rs}fn{17sv5tv5os5qx5rs}fo{17sv5tv5os5qx5rs}fp{5os5qt5rs}fq{5os5qt5rs}7r{ckuclucmucnucoucpu4lu5os}fs{17sv5tv5os5qx5rs}ft{17ss5ts5qs}fu{17sw5tw5qs}fv{17sw5tw5qs}fw{17ss5ts5qs}fz{ckuclucmucnucoucpu4lu5os5rs}}}"),"Helvetica-Oblique":z("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}")}},M.events.push(["addFont",function(t){var e,n,r,i="Unicode";(e=U[i][t.postScriptName])&&((n=t.metadata[i]?t.metadata[i]:t.metadata[i]={}).widths=e.widths,n.kerning=e.kerning),(r=L[i][t.postScriptName])&&((n=t.metadata[i]?t.metadata[i]:t.metadata[i]={}).encoding=r).codePages&&r.codePages.length&&(t.encoding=r.codePages[0])}]),H=K,"undefined"!=typeof self&&self||"undefined"!=typeof global&&global||"undefined"!=typeof window&&window||Function("return this")(),H.API.events.push(["addFont",function(t){H.API.existsFileInVFS(t.postScriptName)?(t.metadata=H.API.TTFFont.open(t.postScriptName,t.fontName,H.API.getFileFromVFS(t.postScriptName),t.encoding),t.metadata.Unicode=t.metadata.Unicode||{encoding:{},kerning:{},widths:[]}):14<t.id.slice(1)&&console.error("Font does not exist in FileInVFS, import fonts or remove declaration doc.addFont('"+t.postScriptName+"').")}]),K.API.addSVG=function(t,e,n,r,i){if(void 0===e||void 0===n)throw new Error("addSVG needs values for 'x' and 'y'");function o(t){for(var e=parseFloat(t[1]),n=parseFloat(t[2]),r=[],i=3,o=t.length;i<o;)"c"===t[i]?(r.push([parseFloat(t[i+1]),parseFloat(t[i+2]),parseFloat(t[i+3]),parseFloat(t[i+4]),parseFloat(t[i+5]),parseFloat(t[i+6])]),i+=7):"l"===t[i]?(r.push([parseFloat(t[i+1]),parseFloat(t[i+2])]),i+=3):i+=1;return[e,n,r]}var a,s,c,l,h,u,f,d,p=(l=document,d=l.createElement("iframe"),h=".jsPDF_sillysvg_iframe {display:none;position:absolute;}",(f=(u=l).createElement("style")).type="text/css",f.styleSheet?f.styleSheet.cssText=h:f.appendChild(u.createTextNode(h)),u.getElementsByTagName("head")[0].appendChild(f),d.name="childframe",d.setAttribute("width",0),d.setAttribute("height",0),d.setAttribute("frameborder","0"),d.setAttribute("scrolling","no"),d.setAttribute("seamless","seamless"),d.setAttribute("class","jsPDF_sillysvg_iframe"),l.body.appendChild(d),d),g=(a=t,(c=((s=p).contentWindow||s.contentDocument).document).write(a),c.close(),c.getElementsByTagName("svg")[0]),m=[1,1],y=parseFloat(g.getAttribute("width")),w=parseFloat(g.getAttribute("height"));y&&w&&(r&&i?m=[r/y,i/w]:r?m=[r/y,r/y]:i&&(m=[i/w,i/w]));var v,b,x,S,k=g.childNodes;for(v=0,b=k.length;v<b;v++)(x=k[v]).tagName&&"PATH"===x.tagName.toUpperCase()&&((S=o(x.getAttribute("d").split(" ")))[0]=S[0]*m[0]+e,S[1]=S[1]*m[1]+n,this.lines.call(this,S[2],S[0],S[1],m));return this},K.API.putTotalPages=function(t){for(var e=new RegExp(t,"g"),n=1;n<=this.internal.getNumberOfPages();n++)for(var r=0;r<this.internal.pages[n].length;r++)this.internal.pages[n][r]=this.internal.pages[n][r].replace(e,this.internal.getNumberOfPages());return this},K.API.viewerPreferences=function(t,e){var n;t=t||{},e=e||!1;var r,i,o={HideToolbar:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},HideMenubar:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},HideWindowUI:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},FitWindow:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},CenterWindow:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},DisplayDocTitle:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.4},NonFullScreenPageMode:{defaultValue:"UseNone",value:"UseNone",type:"name",explicitSet:!1,valueSet:["UseNone","UseOutlines","UseThumbs","UseOC"],pdfVersion:1.3},Direction:{defaultValue:"L2R",value:"L2R",type:"name",explicitSet:!1,valueSet:["L2R","R2L"],pdfVersion:1.3},ViewArea:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},ViewClip:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},PrintArea:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},PrintClip:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},PrintScaling:{defaultValue:"AppDefault",value:"AppDefault",type:"name",explicitSet:!1,valueSet:["AppDefault","None"],pdfVersion:1.6},Duplex:{defaultValue:"",value:"none",type:"name",explicitSet:!1,valueSet:["Simplex","DuplexFlipShortEdge","DuplexFlipLongEdge","none"],pdfVersion:1.7},PickTrayByPDFSize:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.7},PrintPageRange:{defaultValue:"",value:"",type:"array",explicitSet:!1,valueSet:null,pdfVersion:1.7},NumCopies:{defaultValue:1,value:1,type:"integer",explicitSet:!1,valueSet:null,pdfVersion:1.7}},a=Object.keys(o),s=[],c=0,l=0,h=0,u=!0;function f(t,e){var n,r=!1;for(n=0;n<t.length;n+=1)t[n]===e&&(r=!0);return r}if(void 0===this.internal.viewerpreferences&&(this.internal.viewerpreferences={},this.internal.viewerpreferences.configuration=JSON.parse(JSON.stringify(o)),this.internal.viewerpreferences.isSubscribed=!1),n=this.internal.viewerpreferences.configuration,"reset"===t||!0===e){var d=a.length;for(h=0;h<d;h+=1)n[a[h]].value=n[a[h]].defaultValue,n[a[h]].explicitSet=!1}if("object"===(void 0===t?"undefined":vt(t)))for(r in t)if(i=t[r],f(a,r)&&void 0!==i){if("boolean"===n[r].type&&"boolean"==typeof i)n[r].value=i;else if("name"===n[r].type&&f(n[r].valueSet,i))n[r].value=i;else if("integer"===n[r].type&&Number.isInteger(i))n[r].value=i;else if("array"===n[r].type){for(c=0;c<i.length;c+=1)if(u=!0,1===i[c].length&&"number"==typeof i[c][0])s.push(String(i[c]));else if(1<i[c].length){for(l=0;l<i[c].length;l+=1)"number"!=typeof i[c][l]&&(u=!1);!0===u&&s.push(String(i[c].join("-")))}n[r].value=String(s)}else n[r].value=n[r].defaultValue;n[r].explicitSet=!0}return!1===this.internal.viewerpreferences.isSubscribed&&(this.internal.events.subscribe("putCatalog",function(){var t,e=[];for(t in n)!0===n[t].explicitSet&&("name"===n[t].type?e.push("/"+t+" /"+n[t].value):e.push("/"+t+" "+n[t].value));0!==e.length&&this.internal.write("/ViewerPreferences\n<<\n"+e.join("\n")+"\n>>")}),this.internal.viewerpreferences.isSubscribed=!0),this.internal.viewerpreferences.configuration=n,this},
+/** ==================================================================== 
+   * jsPDF XMP metadata plugin
+   * Copyright (c) 2016 Jussi Utunen, u-jussi@suomi24.fi
+   * 
+   * 
+   * ====================================================================
+   */
+W=K.API,Y=G=V="",W.addMetadata=function(t,e){return G=e||"http://jspdf.default.namespaceuri/",V=t,this.internal.events.subscribe("postPutResources",function(){if(V){var t='<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:jspdf="'+G+'"><jspdf:metadata>',e=unescape(encodeURIComponent('<x:xmpmeta xmlns:x="adobe:ns:meta/">')),n=unescape(encodeURIComponent(t)),r=unescape(encodeURIComponent(V)),i=unescape(encodeURIComponent("</jspdf:metadata></rdf:Description></rdf:RDF>")),o=unescape(encodeURIComponent("</x:xmpmeta>")),a=n.length+r.length+i.length+e.length+o.length;Y=this.internal.newObject(),this.internal.write("<< /Type /Metadata /Subtype /XML /Length "+a+" >>"),this.internal.write("stream"),this.internal.write(e+n+r+i+o),this.internal.write("endstream"),this.internal.write("endobj")}else Y=""}),this.internal.events.subscribe("putCatalog",function(){Y&&this.internal.write("/Metadata "+Y+" 0 R")}),this},function(h,t){var e=h.API,m=[0];e.events.push(["putFont",function(t){!function(t,e,n){if(t.metadata instanceof h.API.TTFFont&&"Identity-H"===t.encoding){for(var r=t.metadata.Unicode.widths,i=t.metadata.subset.encode(m),o="",a=0;a<i.length;a++)o+=String.fromCharCode(i[a]);var s=n();e("<<"),e("/Length "+o.length),e("/Length1 "+o.length),e(">>"),e("stream"),e(o),e("endstream"),e("endobj");var c=n();e("<<"),e("/Type /FontDescriptor"),e("/FontName /"+t.fontName),e("/FontFile2 "+s+" 0 R"),e("/FontBBox "+h.API.PDFObject.convert(t.metadata.bbox)),e("/Flags "+t.metadata.flags),e("/StemV "+t.metadata.stemV),e("/ItalicAngle "+t.metadata.italicAngle),e("/Ascent "+t.metadata.ascender),e("/Descent "+t.metadata.decender),e("/CapHeight "+t.metadata.capHeight),e(">>"),e("endobj");var l=n();e("<<"),e("/Type /Font"),e("/BaseFont /"+t.fontName),e("/FontDescriptor "+c+" 0 R"),e("/W "+h.API.PDFObject.convert(r)),e("/CIDToGIDMap /Identity"),e("/DW 1000"),e("/Subtype /CIDFontType2"),e("/CIDSystemInfo"),e("<<"),e("/Supplement 0"),e("/Registry (Adobe)"),e("/Ordering ("+t.encoding+")"),e(">>"),e(">>"),e("endobj"),t.objectNumber=n(),e("<<"),e("/Type /Font"),e("/Subtype /Type0"),e("/BaseFont /"+t.fontName),e("/Encoding /"+t.encoding),e("/DescendantFonts ["+l+" 0 R]"),e(">>"),e("endobj"),t.isAlreadyPutted=!0}}(t.font,t.out,t.newObject)}]);e.events.push(["putFont",function(t){!function(t,e,n){if(t.metadata instanceof h.API.TTFFont&&"WinAnsiEncoding"===t.encoding){t.metadata.Unicode.widths;for(var r=t.metadata.rawData,i="",o=0;o<r.length;o++)i+=String.fromCharCode(r[o]);var a=n();e("<<"),e("/Length "+i.length),e("/Length1 "+i.length),e(">>"),e("stream"),e(i),e("endstream"),e("endobj");var s=n();for(e("<<"),e("/Descent "+t.metadata.decender),e("/CapHeight "+t.metadata.capHeight),e("/StemV "+t.metadata.stemV),e("/Type /FontDescriptor"),e("/FontFile2 "+a+" 0 R"),e("/Flags 96"),e("/FontBBox "+h.API.PDFObject.convert(t.metadata.bbox)),e("/FontName /"+t.fontName),e("/ItalicAngle "+t.metadata.italicAngle),e("/Ascent "+t.metadata.ascender),e(">>"),e("endobj"),t.objectNumber=n(),o=0;o<t.metadata.hmtx.widths.length;o++)t.metadata.hmtx.widths[o]=parseInt(t.metadata.hmtx.widths[o]*(1e3/t.metadata.head.unitsPerEm));e("<</Subtype/TrueType/Type/Font/BaseFont/"+t.fontName+"/FontDescriptor "+s+" 0 R/Encoding/"+t.encoding+" /FirstChar 29 /LastChar 255 /Widths "+h.API.PDFObject.convert(t.metadata.hmtx.widths)+">>"),e("endobj"),t.isAlreadyPutted=!0}}(t.font,t.out,t.newObject)}]);var l=function(t){var e,n,r=t.text,i=t.x,o=t.y,a=t.options||{},s=t.mutex||{},c=s.pdfEscape,l=s.activeFontKey,h=s.fonts,u=(s.activeFontSize,""),f=0,d="",p=h[n=l].encoding;if("Identity-H"!==h[n].encoding)return{text:r,x:i,y:o,options:a,mutex:s};for(d=r,n=l,"[object Array]"===Object.prototype.toString.call(r)&&(d=r[0]),f=0;f<d.length;f+=1)h[n].metadata.hasOwnProperty("cmap")&&(e=h[n].metadata.cmap.unicode.codeMap[d[f].charCodeAt(0)]),e?u+=d[f]:d[f].charCodeAt(0)<256&&h[n].metadata.hasOwnProperty("Unicode")?u+=d[f]:u+="";var g="";return parseInt(n.slice(1))<14||"WinAnsiEncoding"===p?g=function(t){for(var e="",n=0;n<t.length;n++)e+=""+t.charCodeAt(n).toString(16);return e}(c(u,n)):"Identity-H"===p&&(g=function(t,e){for(var n,r=e.metadata.Unicode.widths,i=["","0","00","000","0000"],o=[""],a=0,s=t.length;a<s;++a){if(n=e.metadata.characterToGlyph(t.charCodeAt(a)),m.push(n),-1==r.indexOf(n)&&(r.push(n),r.push([parseInt(e.metadata.widthOfGlyph(n),10)])),"0"==n)return o.join("");n=n.toString(16),o.push(i[4-n.length],n)}return o.join("")}(u,h[n])),s.isHex=!0,{text:g,x:i,y:o,options:a,mutex:s}};e.events.push(["postProcessText",function(t){var e=t.text,n=t.x,r=t.y,i=t.options,o=t.mutex,a=(i.lang,[]),s={text:e,x:n,y:r,options:i,mutex:o};if("[object Array]"===Object.prototype.toString.call(e)){var c=0;for(c=0;c<e.length;c+=1)"[object Array]"===Object.prototype.toString.call(e[c])&&3===e[c].length?a.push([l(Object.assign({},s,{text:e[c][0]})).text,e[c][1],e[c][2]]):a.push(l(Object.assign({},s,{text:e[c]})).text);t.text=a}else t.text=l(Object.assign({},s,{text:e})).text}])}(K,"undefined"!=typeof self&&self||"undefined"!=typeof global&&global||"undefined"!=typeof window&&window||Function("return this")()),X=K.API,J={},X.existsFileInVFS=function(t){return J.hasOwnProperty(t)},X.addFileToVFS=function(t,e){return J[t]=e,this},X.getFileFromVFS=function(t){return J.hasOwnProperty(t)?J[t]:null},function(t){if(t.URL=t.URL||t.webkitURL,t.Blob&&t.URL)try{return new Blob}catch(t){}var s=t.BlobBuilder||t.WebKitBlobBuilder||t.MozBlobBuilder||function(t){var s=function(t){return Object.prototype.toString.call(t).match(/^\[object\s(.*)\]$/)[1]},e=function(){this.data=[]},c=function(t,e,n){this.data=t,this.size=t.length,this.type=e,this.encoding=n},n=e.prototype,r=c.prototype,l=t.FileReaderSync,h=function(t){this.code=this[this.name=t]},i="NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR".split(" "),o=i.length,a=t.URL||t.webkitURL||t,u=a.createObjectURL,f=a.revokeObjectURL,d=a,p=t.btoa,g=t.atob,m=t.ArrayBuffer,y=t.Uint8Array,w=/^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/;for(c.fake=r.fake=!0;o--;)h.prototype[i[o]]=o+1;return a.createObjectURL||(d=t.URL=function(t){var e,n=document.createElementNS("http://www.w3.org/1999/xhtml","a");return n.href=t,"origin"in n||("data:"===n.protocol.toLowerCase()?n.origin=null:(e=t.match(w),n.origin=e&&e[1])),n}),d.createObjectURL=function(t){var e,n=t.type;return null===n&&(n="application/octet-stream"),t instanceof c?(e="data:"+n,"base64"===t.encoding?e+";base64,"+t.data:"URI"===t.encoding?e+","+decodeURIComponent(t.data):p?e+";base64,"+p(t.data):e+","+encodeURIComponent(t.data)):u?u.call(a,t):void 0},d.revokeObjectURL=function(t){"data:"!==t.substring(0,5)&&f&&f.call(a,t)},n.append=function(t){var e=this.data;if(y&&(t instanceof m||t instanceof y)){for(var n="",r=new y(t),i=0,o=r.length;i<o;i++)n+=String.fromCharCode(r[i]);e.push(n)}else if("Blob"===s(t)||"File"===s(t)){if(!l)throw new h("NOT_READABLE_ERR");var a=new l;e.push(a.readAsBinaryString(t))}else t instanceof c?"base64"===t.encoding&&g?e.push(g(t.data)):"URI"===t.encoding?e.push(decodeURIComponent(t.data)):"raw"===t.encoding&&e.push(t.data):("string"!=typeof t&&(t+=""),e.push(unescape(encodeURIComponent(t))))},n.getBlob=function(t){return arguments.length||(t=null),new c(this.data.join(""),t,"raw")},n.toString=function(){return"[object BlobBuilder]"},r.slice=function(t,e,n){var r=arguments.length;return r<3&&(n=null),new c(this.data.slice(t,1<r?e:this.data.length),n,this.encoding)},r.toString=function(){return"[object Blob]"},r.close=function(){this.size=0,delete this.data},e}(t);t.Blob=function(t,e){var n=e&&e.type||"",r=new s;if(t)for(var i=0,o=t.length;i<o;i++)Uint8Array&&t[i]instanceof Uint8Array?r.append(t[i].buffer):r.append(t[i]);var a=r.getBlob(n);return!a.slice&&a.webkitSlice&&(a.slice=a.webkitSlice),a};var e=Object.getPrototypeOf||function(t){return t.__proto__};t.Blob.prototype=e(new t.Blob)}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||window.content||window);var Q,Z,$,tt,et,nt,rt,it,ot,at,st,ct,lt,ht,bt=bt||function(s){if(!(void 0===s||"undefined"!=typeof navigator&&/MSIE [1-9]\./.test(navigator.userAgent))){var t=s.document,c=function(){return s.URL||s.webkitURL||s},l=t.createElementNS("http://www.w3.org/1999/xhtml","a"),h="download"in l,u=/constructor/i.test(s.HTMLElement)||s.safari,f=/CriOS\/[\d]+/.test(navigator.userAgent),d=function(t){(s.setImmediate||s.setTimeout)(function(){throw t},0)},p=function(t){setTimeout(function(){"string"==typeof t?c().revokeObjectURL(t):t.remove()},4e4)},g=function(t){return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(t.type)?new Blob([String.fromCharCode(65279),t],{type:t.type}):t},r=function(t,n,e){e||(t=g(t));var r,i=this,o="application/octet-stream"===t.type,a=function(){!function(t,e,n){for(var r=(e=[].concat(e)).length;r--;){var i=t["on"+e[r]];if("function"==typeof i)try{i.call(t,n||t)}catch(t){d(t)}}}(i,"writestart progress write writeend".split(" "))};if(i.readyState=i.INIT,h)return r=c().createObjectURL(t),void setTimeout(function(){var t,e;l.href=r,l.download=n,t=l,e=new MouseEvent("click"),t.dispatchEvent(e),a(),p(r),i.readyState=i.DONE});!function(){if((f||o&&u)&&s.FileReader){var e=new FileReader;return e.onloadend=function(){var t=f?e.result:e.result.replace(/^data:[^;]*;/,"data:attachment/file;");s.open(t,"_blank")||(s.location.href=t),t=void 0,i.readyState=i.DONE,a()},e.readAsDataURL(t),i.readyState=i.INIT}r||(r=c().createObjectURL(t)),o?s.location.href=r:s.open(r,"_blank")||(s.location.href=r);i.readyState=i.DONE,a(),p(r)}()},e=r.prototype;return"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob?function(t,e,n){return e=e||t.name||"download",n||(t=g(t)),navigator.msSaveOrOpenBlob(t,e)}:(e.abort=function(){},e.readyState=e.INIT=0,e.WRITING=1,e.DONE=2,e.error=e.onwritestart=e.onprogress=e.onwrite=e.onabort=e.onerror=e.onwriteend=null,function(t,e,n){return new r(t,e||t.name||"download",n)})}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||window.content);"undefined"!=typeof module&&module.exports?module.exports.saveAs=bt:"undefined"!=typeof define&&null!==define&&null!==define.amd&&define("FileSaver.js",function(){return bt})
+/*
+   * Copyright (c) 2012 chick307 <chick307@gmail.com>
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */,K.API.adler32cs=(nt="function"==typeof ArrayBuffer&&"function"==typeof Uint8Array,rt=null,it=function(){if(!nt)return function(){return!1};try{var t={};"function"==typeof t.Buffer&&(rt=t.Buffer)}catch(t){}return function(t){return t instanceof ArrayBuffer||null!==rt&&t instanceof rt}}(),ot=null!==rt?function(t){return new rt(t,"utf8").toString("binary")}:function(t){return unescape(encodeURIComponent(t))},at=65521,st=function(t,e){for(var n=65535&t,r=t>>>16,i=0,o=e.length;i<o;i++)n=(n+(255&e.charCodeAt(i)))%at,r=(r+n)%at;return(r<<16|n)>>>0},ct=function(t,e){for(var n=65535&t,r=t>>>16,i=0,o=e.length;i<o;i++)n=(n+e[i])%at,r=(r+n)%at;return(r<<16|n)>>>0},ht=(lt={}).Adler32=(((et=(tt=function(t){if(!(this instanceof tt))throw new TypeError("Constructor cannot called be as a function.");if(!isFinite(t=null==t?1:+t))throw new Error("First arguments needs to be a finite number.");this.checksum=t>>>0}).prototype={}).constructor=tt).from=((Q=function(t){if(!(this instanceof tt))throw new TypeError("Constructor cannot called be as a function.");if(null==t)throw new Error("First argument needs to be a string.");this.checksum=st(1,t.toString())}).prototype=et,Q),tt.fromUtf8=((Z=function(t){if(!(this instanceof tt))throw new TypeError("Constructor cannot called be as a function.");if(null==t)throw new Error("First argument needs to be a string.");var e=ot(t.toString());this.checksum=st(1,e)}).prototype=et,Z),nt&&(tt.fromBuffer=(($=function(t){if(!(this instanceof tt))throw new TypeError("Constructor cannot called be as a function.");if(!it(t))throw new Error("First argument needs to be ArrayBuffer.");var e=new Uint8Array(t);return this.checksum=ct(1,e)}).prototype=et,$)),et.update=function(t){if(null==t)throw new Error("First argument needs to be a string.");return t=t.toString(),this.checksum=st(this.checksum,t)},et.updateUtf8=function(t){if(null==t)throw new Error("First argument needs to be a string.");var e=ot(t.toString());return this.checksum=st(this.checksum,e)},nt&&(et.updateBuffer=function(t){if(!it(t))throw new Error("First argument needs to be ArrayBuffer.");var e=new Uint8Array(t);return this.checksum=ct(this.checksum,e)}),et.clone=function(){return new ht(this.checksum)},tt),lt.from=function(t){if(null==t)throw new Error("First argument needs to be a string.");return st(1,t.toString())},lt.fromUtf8=function(t){if(null==t)throw new Error("First argument needs to be a string.");var e=ot(t.toString());return st(1,e)},nt&&(lt.fromBuffer=function(t){if(!it(t))throw new Error("First argument need to be ArrayBuffer.");var e=new Uint8Array(t);return ct(1,e)}),lt),
+/*
+   Copyright (c) 2013 Gildas Lormeau. All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in 
+   the documentation and/or other materials provided with the distribution.
+
+   3. The names of the authors may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+   INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+   OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+   EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+   */
+function(t){var p=15,g=573,e=[0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,0,0,16,17,18,18,19,19,20,20,20,20,21,21,21,21,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29];function ut(){var d=this;function c(t,e){for(var n=0;n|=1&t,t>>>=1,n<<=1,0<--e;);return n>>>1}d.build_tree=function(t){var e,n,r,i=d.dyn_tree,o=d.stat_desc.static_tree,a=d.stat_desc.elems,s=-1;for(t.heap_len=0,t.heap_max=g,e=0;e<a;e++)0!==i[2*e]?(t.heap[++t.heap_len]=s=e,t.depth[e]=0):i[2*e+1]=0;for(;t.heap_len<2;)i[2*(r=t.heap[++t.heap_len]=s<2?++s:0)]=1,t.depth[r]=0,t.opt_len--,o&&(t.static_len-=o[2*r+1]);for(d.max_code=s,e=Math.floor(t.heap_len/2);1<=e;e--)t.pqdownheap(i,e);for(r=a;e=t.heap[1],t.heap[1]=t.heap[t.heap_len--],t.pqdownheap(i,1),n=t.heap[1],t.heap[--t.heap_max]=e,t.heap[--t.heap_max]=n,i[2*r]=i[2*e]+i[2*n],t.depth[r]=Math.max(t.depth[e],t.depth[n])+1,i[2*e+1]=i[2*n+1]=r,t.heap[1]=r++,t.pqdownheap(i,1),2<=t.heap_len;);t.heap[--t.heap_max]=t.heap[1],function(t){var e,n,r,i,o,a,s=d.dyn_tree,c=d.stat_desc.static_tree,l=d.stat_desc.extra_bits,h=d.stat_desc.extra_base,u=d.stat_desc.max_length,f=0;for(i=0;i<=p;i++)t.bl_count[i]=0;for(s[2*t.heap[t.heap_max]+1]=0,e=t.heap_max+1;e<g;e++)u<(i=s[2*s[2*(n=t.heap[e])+1]+1]+1)&&(i=u,f++),s[2*n+1]=i,n>d.max_code||(t.bl_count[i]++,o=0,h<=n&&(o=l[n-h]),a=s[2*n],t.opt_len+=a*(i+o),c&&(t.static_len+=a*(c[2*n+1]+o)));if(0!==f){do{for(i=u-1;0===t.bl_count[i];)i--;t.bl_count[i]--,t.bl_count[i+1]+=2,t.bl_count[u]--,f-=2}while(0<f);for(i=u;0!==i;i--)for(n=t.bl_count[i];0!==n;)(r=t.heap[--e])>d.max_code||(s[2*r+1]!=i&&(t.opt_len+=(i-s[2*r+1])*s[2*r],s[2*r+1]=i),n--)}}(t),function(t,e,n){var r,i,o,a=[],s=0;for(r=1;r<=p;r++)a[r]=s=s+n[r-1]<<1;for(i=0;i<=e;i++)0!==(o=t[2*i+1])&&(t[2*i]=c(a[o]++,o))}(i,d.max_code,t.bl_count)}}function ft(t,e,n,r,i){var o=this;o.static_tree=t,o.extra_bits=e,o.extra_base=n,o.elems=r,o.max_length=i}ut._length_code=[0,1,2,3,4,5,6,7,8,8,9,9,10,10,11,11,12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28],ut.base_length=[0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224,0],ut.base_dist=[0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576],ut.d_code=function(t){return t<256?e[t]:e[256+(t>>>7)]},ut.extra_lbits=[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],ut.extra_dbits=[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],ut.extra_blbits=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],ut.bl_order=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],ft.static_ltree=[12,8,140,8,76,8,204,8,44,8,172,8,108,8,236,8,28,8,156,8,92,8,220,8,60,8,188,8,124,8,252,8,2,8,130,8,66,8,194,8,34,8,162,8,98,8,226,8,18,8,146,8,82,8,210,8,50,8,178,8,114,8,242,8,10,8,138,8,74,8,202,8,42,8,170,8,106,8,234,8,26,8,154,8,90,8,218,8,58,8,186,8,122,8,250,8,6,8,134,8,70,8,198,8,38,8,166,8,102,8,230,8,22,8,150,8,86,8,214,8,54,8,182,8,118,8,246,8,14,8,142,8,78,8,206,8,46,8,174,8,110,8,238,8,30,8,158,8,94,8,222,8,62,8,190,8,126,8,254,8,1,8,129,8,65,8,193,8,33,8,161,8,97,8,225,8,17,8,145,8,81,8,209,8,49,8,177,8,113,8,241,8,9,8,137,8,73,8,201,8,41,8,169,8,105,8,233,8,25,8,153,8,89,8,217,8,57,8,185,8,121,8,249,8,5,8,133,8,69,8,197,8,37,8,165,8,101,8,229,8,21,8,149,8,85,8,213,8,53,8,181,8,117,8,245,8,13,8,141,8,77,8,205,8,45,8,173,8,109,8,237,8,29,8,157,8,93,8,221,8,61,8,189,8,125,8,253,8,19,9,275,9,147,9,403,9,83,9,339,9,211,9,467,9,51,9,307,9,179,9,435,9,115,9,371,9,243,9,499,9,11,9,267,9,139,9,395,9,75,9,331,9,203,9,459,9,43,9,299,9,171,9,427,9,107,9,363,9,235,9,491,9,27,9,283,9,155,9,411,9,91,9,347,9,219,9,475,9,59,9,315,9,187,9,443,9,123,9,379,9,251,9,507,9,7,9,263,9,135,9,391,9,71,9,327,9,199,9,455,9,39,9,295,9,167,9,423,9,103,9,359,9,231,9,487,9,23,9,279,9,151,9,407,9,87,9,343,9,215,9,471,9,55,9,311,9,183,9,439,9,119,9,375,9,247,9,503,9,15,9,271,9,143,9,399,9,79,9,335,9,207,9,463,9,47,9,303,9,175,9,431,9,111,9,367,9,239,9,495,9,31,9,287,9,159,9,415,9,95,9,351,9,223,9,479,9,63,9,319,9,191,9,447,9,127,9,383,9,255,9,511,9,0,7,64,7,32,7,96,7,16,7,80,7,48,7,112,7,8,7,72,7,40,7,104,7,24,7,88,7,56,7,120,7,4,7,68,7,36,7,100,7,20,7,84,7,52,7,116,7,3,8,131,8,67,8,195,8,35,8,163,8,99,8,227,8],ft.static_dtree=[0,5,16,5,8,5,24,5,4,5,20,5,12,5,28,5,2,5,18,5,10,5,26,5,6,5,22,5,14,5,30,5,1,5,17,5,9,5,25,5,5,5,21,5,13,5,29,5,3,5,19,5,11,5,27,5,7,5,23,5],ft.static_l_desc=new ft(ft.static_ltree,ut.extra_lbits,257,286,p),ft.static_d_desc=new ft(ft.static_dtree,ut.extra_dbits,0,30,p),ft.static_bl_desc=new ft(null,ut.extra_blbits,0,19,7);function n(t,e,n,r,i){var o=this;o.good_length=t,o.max_lazy=e,o.nice_length=n,o.max_chain=r,o.func=i}var dt=[new n(0,0,0,0,0),new n(4,4,8,4,1),new n(4,5,16,8,1),new n(4,6,32,32,1),new n(4,4,16,16,2),new n(8,16,32,32,2),new n(8,16,128,128,2),new n(8,32,128,256,2),new n(32,128,258,1024,2),new n(32,258,258,4096,2)],pt=["need dictionary","stream end","","","stream error","data error","","buffer error","",""],gt=262;function mt(t,e,n,r){var i=t[2*e],o=t[2*n];return i<o||i==o&&r[e]<=r[n]}function r(){var c,l,h,u,f,d,p,g,i,m,y,w,v,a,b,x,S,k,_,C,I,A,T,F,q,E,P,O,B,j,s,R,D,M,z,N,L,o,U,H,W,V=this,G=new ut,Y=new ut,X=new ut;function J(){var t;for(t=0;t<286;t++)s[2*t]=0;for(t=0;t<30;t++)R[2*t]=0;for(t=0;t<19;t++)D[2*t]=0;s[512]=1,V.opt_len=V.static_len=0,N=o=0}function K(t,e){var n,r,i=-1,o=t[1],a=0,s=7,c=4;for(0===o&&(s=138,c=3),t[2*(e+1)+1]=65535,n=0;n<=e;n++)r=o,o=t[2*(n+1)+1],++a<s&&r==o||(a<c?D[2*r]+=a:0!==r?(r!=i&&D[2*r]++,D[32]++):a<=10?D[34]++:D[36]++,i=r,(a=0)===o?(s=138,c=3):r==o?(s=6,c=3):(s=7,c=4))}function Q(t){V.pending_buf[V.pending++]=t}function Z(t){Q(255&t),Q(t>>>8&255)}function $(t,e){var n,r=e;16-r<W?(Z(H|=(n=t)<<W&65535),H=n>>>16-W,W+=r-16):(H|=t<<W&65535,W+=r)}function tt(t,e){var n=2*t;$(65535&e[n],65535&e[n+1])}function et(t,e){var n,r,i=-1,o=t[1],a=0,s=7,c=4;for(0===o&&(s=138,c=3),n=0;n<=e;n++)if(r=o,o=t[2*(n+1)+1],!(++a<s&&r==o)){if(a<c)for(;tt(r,D),0!=--a;);else 0!==r?(r!=i&&(tt(r,D),a--),tt(16,D),$(a-3,2)):a<=10?(tt(17,D),$(a-3,3)):(tt(18,D),$(a-11,7));i=r,(a=0)===o?(s=138,c=3):r==o?(s=6,c=3):(s=7,c=4)}}function nt(){16==W?(Z(H),W=H=0):8<=W&&(Q(255&H),H>>>=8,W-=8)}function rt(t,e){var n,r,i;if(V.pending_buf[L+2*N]=t>>>8&255,V.pending_buf[L+2*N+1]=255&t,V.pending_buf[M+N]=255&e,N++,0===t?s[2*e]++:(o++,t--,s[2*(ut._length_code[e]+256+1)]++,R[2*ut.d_code(t)]++),0==(8191&N)&&2<P){for(n=8*N,r=I-S,i=0;i<30;i++)n+=R[2*i]*(5+ut.extra_dbits[i]);if(n>>>=3,o<Math.floor(N/2)&&n<Math.floor(r/2))return!0}return N==z-1}function it(t,e){var n,r,i,o,a=0;if(0!==N)for(;n=V.pending_buf[L+2*a]<<8&65280|255&V.pending_buf[L+2*a+1],r=255&V.pending_buf[M+a],a++,0===n?tt(r,t):(tt((i=ut._length_code[r])+256+1,t),0!==(o=ut.extra_lbits[i])&&$(r-=ut.base_length[i],o),tt(i=ut.d_code(--n),e),0!==(o=ut.extra_dbits[i])&&$(n-=ut.base_dist[i],o)),a<N;);tt(256,t),U=t[513]}function ot(){8<W?Z(H):0<W&&Q(255&H),W=H=0}function at(t,e,n){var r,i,o;$(0+(n?1:0),3),r=t,i=e,o=!0,ot(),U=8,o&&(Z(i),Z(~i)),V.pending_buf.set(g.subarray(r,r+i),V.pending),V.pending+=i}function e(t,e,n){var r,i,o=0;0<P?(G.build_tree(V),Y.build_tree(V),o=function(){var t;for(K(s,G.max_code),K(R,Y.max_code),X.build_tree(V),t=18;3<=t&&0===D[2*ut.bl_order[t]+1];t--);return V.opt_len+=3*(t+1)+5+5+4,t}(),r=V.opt_len+3+7>>>3,(i=V.static_len+3+7>>>3)<=r&&(r=i)):r=i=e+5,e+4<=r&&-1!=t?at(t,e,n):i==r?($(2+(n?1:0),3),it(ft.static_ltree,ft.static_dtree)):($(4+(n?1:0),3),function(t,e,n){var r;for($(t-257,5),$(e-1,5),$(n-4,4),r=0;r<n;r++)$(D[2*ut.bl_order[r]+1],3);et(s,t-1),et(R,e-1)}(G.max_code+1,Y.max_code+1,o+1),it(s,R)),J(),n&&ot()}function st(t){e(0<=S?S:-1,I-S,t),S=I,c.flush_pending()}function ct(){var t,e,n,r;do{if(0===(r=i-T-I)&&0===I&&0===T)r=f;else if(-1==r)r--;else if(f+f-gt<=I){for(g.set(g.subarray(f,f+f),0),A-=f,I-=f,S-=f,n=t=v;e=65535&y[--n],y[n]=f<=e?e-f:0,0!=--t;);for(n=t=f;e=65535&m[--n],m[n]=f<=e?e-f:0,0!=--t;);r+=f}if(0===c.avail_in)return;t=c.read_buf(g,I+T,r),3<=(T+=t)&&(w=((w=255&g[I])<<x^255&g[I+1])&b)}while(T<gt&&0!==c.avail_in)}function lt(t){var e,n,r=q,i=I,o=F,a=f-gt<I?I-(f-gt):0,s=j,c=p,l=I+258,h=g[i+o-1],u=g[i+o];B<=F&&(r>>=2),T<s&&(s=T);do{if(g[(e=t)+o]==u&&g[e+o-1]==h&&g[e]==g[i]&&g[++e]==g[i+1]){i+=2,e++;do{}while(g[++i]==g[++e]&&g[++i]==g[++e]&&g[++i]==g[++e]&&g[++i]==g[++e]&&g[++i]==g[++e]&&g[++i]==g[++e]&&g[++i]==g[++e]&&g[++i]==g[++e]&&i<l);if(n=258-(l-i),i=l-258,o<n){if(A=t,s<=(o=n))break;h=g[i+o-1],u=g[i+o]}}}while((t=65535&m[t&c])>a&&0!=--r);return o<=T?o:T}function ht(t){return t.total_in=t.total_out=0,t.msg=null,V.pending=0,V.pending_out=0,l=113,u=0,G.dyn_tree=s,G.stat_desc=ft.static_l_desc,Y.dyn_tree=R,Y.stat_desc=ft.static_d_desc,X.dyn_tree=D,X.stat_desc=ft.static_bl_desc,W=H=0,U=8,J(),function(){var t;for(i=2*f,t=y[v-1]=0;t<v-1;t++)y[t]=0;E=dt[P].max_lazy,B=dt[P].good_length,j=dt[P].nice_length,q=dt[P].max_chain,k=F=2,w=C=T=S=I=0}(),0}V.depth=[],V.bl_count=[],V.heap=[],s=[],R=[],D=[],V.pqdownheap=function(t,e){for(var n=V.heap,r=n[e],i=e<<1;i<=V.heap_len&&(i<V.heap_len&&mt(t,n[i+1],n[i],V.depth)&&i++,!mt(t,r,n[i],V.depth));)n[e]=n[i],e=i,i<<=1;n[e]=r},V.deflateInit=function(t,e,n,r,i,o){return r||(r=8),i||(i=8),o||(o=0),t.msg=null,-1==e&&(e=6),i<1||9<i||8!=r||n<9||15<n||e<0||9<e||o<0||2<o?-2:(t.dstate=V,p=(f=1<<(d=n))-1,b=(v=1<<(a=i+7))-1,x=Math.floor((a+3-1)/3),g=new Uint8Array(2*f),m=[],y=[],z=1<<i+6,V.pending_buf=new Uint8Array(4*z),h=4*z,L=Math.floor(z/2),M=3*z,P=e,O=o,ht(t))},V.deflateEnd=function(){return 42!=l&&113!=l&&666!=l?-2:(V.pending_buf=null,g=m=y=null,V.dstate=null,113==l?-3:0)},V.deflateParams=function(t,e,n){var r=0;return-1==e&&(e=6),e<0||9<e||n<0||2<n?-2:(dt[P].func!=dt[e].func&&0!==t.total_in&&(r=t.deflate(1)),P!=e&&(E=dt[P=e].max_lazy,B=dt[P].good_length,j=dt[P].nice_length,q=dt[P].max_chain),O=n,r)},V.deflateSetDictionary=function(t,e,n){var r,i=n,o=0;if(!e||42!=l)return-2;if(i<3)return 0;for(f-gt<i&&(o=n-(i=f-gt)),g.set(e.subarray(o,o+i),0),S=I=i,w=((w=255&g[0])<<x^255&g[1])&b,r=0;r<=i-3;r++)w=(w<<x^255&g[r+2])&b,m[r&p]=y[w],y[w]=r;return 0},V.deflate=function(t,e){var n,r,i,o,a,s;if(4<e||e<0)return-2;if(!t.next_out||!t.next_in&&0!==t.avail_in||666==l&&4!=e)return t.msg=pt[4],-2;if(0===t.avail_out)return t.msg=pt[7],-5;if(c=t,o=u,u=e,42==l&&(r=8+(d-8<<4)<<8,3<(i=(P-1&255)>>1)&&(i=3),r|=i<<6,0!==I&&(r|=32),l=113,Q((s=r+=31-r%31)>>8&255),Q(255&s)),0!==V.pending){if(c.flush_pending(),0===c.avail_out)return u=-1,0}else if(0===c.avail_in&&e<=o&&4!=e)return c.msg=pt[7],-5;if(666==l&&0!==c.avail_in)return t.msg=pt[7],-5;if(0!==c.avail_in||0!==T||0!=e&&666!=l){switch(a=-1,dt[P].func){case 0:a=function(t){var e,n=65535;for(h-5<n&&(n=h-5);;){if(T<=1){if(ct(),0===T&&0==t)return 0;if(0===T)break}if(I+=T,e=S+n,((T=0)===I||e<=I)&&(T=I-e,I=e,st(!1),0===c.avail_out))return 0;if(f-gt<=I-S&&(st(!1),0===c.avail_out))return 0}return st(4==t),0===c.avail_out?4==t?2:0:4==t?3:1}(e);break;case 1:a=function(t){for(var e,n=0;;){if(T<gt){if(ct(),T<gt&&0==t)return 0;if(0===T)break}if(3<=T&&(w=(w<<x^255&g[I+2])&b,n=65535&y[w],m[I&p]=y[w],y[w]=I),0!==n&&(I-n&65535)<=f-gt&&2!=O&&(k=lt(n)),3<=k)if(e=rt(I-A,k-3),T-=k,k<=E&&3<=T){for(k--;w=(w<<x^255&g[++I+2])&b,n=65535&y[w],m[I&p]=y[w],y[w]=I,0!=--k;);I++}else I+=k,k=0,w=((w=255&g[I])<<x^255&g[I+1])&b;else e=rt(0,255&g[I]),T--,I++;if(e&&(st(!1),0===c.avail_out))return 0}return st(4==t),0===c.avail_out?4==t?2:0:4==t?3:1}(e);break;case 2:a=function(t){for(var e,n,r=0;;){if(T<gt){if(ct(),T<gt&&0==t)return 0;if(0===T)break}if(3<=T&&(w=(w<<x^255&g[I+2])&b,r=65535&y[w],m[I&p]=y[w],y[w]=I),F=k,_=A,k=2,0!==r&&F<E&&(I-r&65535)<=f-gt&&(2!=O&&(k=lt(r)),k<=5&&(1==O||3==k&&4096<I-A)&&(k=2)),3<=F&&k<=F){for(n=I+T-3,e=rt(I-1-_,F-3),T-=F-1,F-=2;++I<=n&&(w=(w<<x^255&g[I+2])&b,r=65535&y[w],m[I&p]=y[w],y[w]=I),0!=--F;);if(C=0,k=2,I++,e&&(st(!1),0===c.avail_out))return 0}else if(0!==C){if((e=rt(0,255&g[I-1]))&&st(!1),I++,T--,0===c.avail_out)return 0}else C=1,I++,T--}return 0!==C&&(e=rt(0,255&g[I-1]),C=0),st(4==t),0===c.avail_out?4==t?2:0:4==t?3:1}(e)}if(2!=a&&3!=a||(l=666),0==a||2==a)return 0===c.avail_out&&(u=-1),0;if(1==a){if(1==e)$(2,3),tt(256,ft.static_ltree),nt(),1+U+10-W<9&&($(2,3),tt(256,ft.static_ltree),nt()),U=7;else if(at(0,0,!1),3==e)for(n=0;n<v;n++)y[n]=0;if(c.flush_pending(),0===c.avail_out)return u=-1,0}}return 4!=e?0:1}}function i(){var t=this;t.next_in_index=0,t.next_out_index=0,t.avail_in=0,t.total_in=0,t.avail_out=0,t.total_out=0}i.prototype={deflateInit:function(t,e){return this.dstate=new r,e||(e=p),this.dstate.deflateInit(this,t,e)},deflate:function(t){return this.dstate?this.dstate.deflate(this,t):-2},deflateEnd:function(){if(!this.dstate)return-2;var t=this.dstate.deflateEnd();return this.dstate=null,t},deflateParams:function(t,e){return this.dstate?this.dstate.deflateParams(this,t,e):-2},deflateSetDictionary:function(t,e){return this.dstate?this.dstate.deflateSetDictionary(this,t,e):-2},read_buf:function(t,e,n){var r=this,i=r.avail_in;return n<i&&(i=n),0===i?0:(r.avail_in-=i,t.set(r.next_in.subarray(r.next_in_index,r.next_in_index+i),e),r.next_in_index+=i,r.total_in+=i,i)},flush_pending:function(){var t=this,e=t.dstate.pending;e>t.avail_out&&(e=t.avail_out),0!==e&&(t.next_out.set(t.dstate.pending_buf.subarray(t.dstate.pending_out,t.dstate.pending_out+e),t.next_out_index),t.next_out_index+=e,t.dstate.pending_out+=e,t.total_out+=e,t.avail_out-=e,t.dstate.pending-=e,0===t.dstate.pending&&(t.dstate.pending_out=0))}};var o=t.zip||t;o.Deflater=o._jzlib_Deflater=function(t){var s=new i,c=new Uint8Array(512),e=t?t.level:-1;void 0===e&&(e=-1),s.deflateInit(e),s.next_out=c,this.append=function(t,e){var n,r=[],i=0,o=0,a=0;if(t.length){s.next_in_index=0,s.next_in=t,s.avail_in=t.length;do{if(s.next_out_index=0,s.avail_out=512,0!=s.deflate(0))throw new Error("deflating: "+s.msg);s.next_out_index&&(512==s.next_out_index?r.push(new Uint8Array(c)):r.push(new Uint8Array(c.subarray(0,s.next_out_index)))),a+=s.next_out_index,e&&0<s.next_in_index&&s.next_in_index!=i&&(e(s.next_in_index),i=s.next_in_index)}while(0<s.avail_in||0===s.avail_out);return n=new Uint8Array(a),r.forEach(function(t){n.set(t,o),o+=t.length}),n}},this.flush=function(){var t,e,n=[],r=0,i=0;do{if(s.next_out_index=0,s.avail_out=512,1!=(t=s.deflate(4))&&0!=t)throw new Error("deflating: "+s.msg);0<512-s.avail_out&&n.push(new Uint8Array(c.subarray(0,s.next_out_index))),i+=s.next_out_index}while(0<s.avail_in||0===s.avail_out);return s.deflateEnd(),e=new Uint8Array(i),n.forEach(function(t){e.set(t,r),r+=t.length}),e}}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||"undefined"!=typeof global&&global||Function('return typeof this === "object" && this.content')()||Function("return this")());
+/**
+   * CssColors
+   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+var ut,ft,dt={};dt._colorsTable={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4","indianred ":"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},dt.colorNameToHex=function(t){return t=t.toLowerCase(),void 0!==this._colorsTable[t]&&this._colorsTable[t]},function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;"undefined"!=typeof window?e=window:"undefined"!=typeof global?e=global:"undefined"!=typeof self&&(e=self),e.html2canvas=t()}}(function(){return function o(a,s,c){function l(n,t){if(!s[n]){if(!a[n]){var e="function"==typeof require&&require;if(!t&&e)return e(n,!0);if(h)return h(n,!0);var r=new Error("Cannot find module '"+n+"'");throw r.code="MODULE_NOT_FOUND",r}var i=s[n]={exports:{}};a[n][0].call(i.exports,function(t){var e=a[n][1][t];return l(e||t)},i,i.exports,o,a,s,c)}return s[n].exports}for(var h="function"==typeof require&&require,t=0;t<c.length;t++)l(c[t]);return l}({1:[function(t,P,O){(function(E){!function(t){var e="object"==typeof O&&O,n="object"==typeof P&&P&&P.exports==e&&P,r="object"==typeof E&&E;r.global!==r&&r.window!==r||(t=r);var i,o,y=2147483647,w=36,v=1,b=26,a=38,s=700,x=72,S=128,k="-",c=/^xn--/,l=/[^ -~]/,h=/\x2E|\u3002|\uFF0E|\uFF61/g,u={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},f=w-v,_=Math.floor,C=String.fromCharCode;function I(t){throw RangeError(u[t])}function d(t,e){for(var n=t.length;n--;)t[n]=e(t[n]);return t}function p(t,e){return d(t.split(h),e).join(".")}function A(t){for(var e,n,r=[],i=0,o=t.length;i<o;)55296<=(e=t.charCodeAt(i++))&&e<=56319&&i<o?56320==(64512&(n=t.charCodeAt(i++)))?r.push(((1023&e)<<10)+(1023&n)+65536):(r.push(e),i--):r.push(e);return r}function T(t){return d(t,function(t){var e="";return 65535<t&&(e+=C((t-=65536)>>>10&1023|55296),t=56320|1023&t),e+=C(t)}).join("")}function F(t,e){return t+22+75*(t<26)-((0!=e)<<5)}function q(t,e,n){var r=0;for(t=n?_(t/s):t>>1,t+=_(t/e);f*b>>1<t;r+=w)t=_(t/f);return _(r+(f+1)*t/(t+a))}function g(t){var e,n,r,i,o,a,s,c,l,h,u,f=[],d=t.length,p=0,g=S,m=x;for((n=t.lastIndexOf(k))<0&&(n=0),r=0;r<n;++r)128<=t.charCodeAt(r)&&I("not-basic"),f.push(t.charCodeAt(r));for(i=0<n?n+1:0;i<d;){for(o=p,a=1,s=w;d<=i&&I("invalid-input"),u=t.charCodeAt(i++),(w<=(c=u-48<10?u-22:u-65<26?u-65:u-97<26?u-97:w)||c>_((y-p)/a))&&I("overflow"),p+=c*a,!(c<(l=s<=m?v:m+b<=s?b:s-m));s+=w)a>_(y/(h=w-l))&&I("overflow"),a*=h;m=q(p-o,e=f.length+1,0==o),_(p/e)>y-g&&I("overflow"),g+=_(p/e),p%=e,f.splice(p++,0,g)}return T(f)}function m(t){var e,n,r,i,o,a,s,c,l,h,u,f,d,p,g,m=[];for(f=(t=A(t)).length,e=S,o=x,a=n=0;a<f;++a)(u=t[a])<128&&m.push(C(u));for(r=i=m.length,i&&m.push(k);r<f;){for(s=y,a=0;a<f;++a)e<=(u=t[a])&&u<s&&(s=u);for(s-e>_((y-n)/(d=r+1))&&I("overflow"),n+=(s-e)*d,e=s,a=0;a<f;++a)if((u=t[a])<e&&++n>y&&I("overflow"),u==e){for(c=n,l=w;!(c<(h=l<=o?v:o+b<=l?b:l-o));l+=w)g=c-h,p=w-h,m.push(C(F(h+g%p,0))),c=_(g/p);m.push(C(F(c,0))),o=q(n,d,r==i),n=0,++r}++n,++e}return m.join("")}if(i={version:"1.2.4",ucs2:{decode:A,encode:T},decode:g,encode:m,toASCII:function(t){return p(t,function(t){return l.test(t)?"xn--"+m(t):t})},toUnicode:function(t){return p(t,function(t){return c.test(t)?g(t.slice(4).toLowerCase()):t})}},e&&!e.nodeType)if(n)n.exports=i;else for(o in i)i.hasOwnProperty(o)&&(e[o]=i[o]);else t.punycode=i}(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],2:[function(t,e,n){var i=t("./log");function u(t,e){for(var n=3===t.nodeType?document.createTextNode(t.nodeValue):t.cloneNode(!1),r=t.firstChild;r;)!0!==e&&1===r.nodeType&&"SCRIPT"===r.nodeName||n.appendChild(u(r,e)),r=r.nextSibling;return 1===t.nodeType&&(n._scrollTop=t.scrollTop,n._scrollLeft=t.scrollLeft,"CANVAS"===t.nodeName?function(e,t){try{t&&(t.width=e.width,t.height=e.height,t.getContext("2d").putImageData(e.getContext("2d").getImageData(0,0,e.width,e.height),0,0))}catch(t){i("Unable to copy canvas content from",e,t)}}(t,n):"TEXTAREA"!==t.nodeName&&"SELECT"!==t.nodeName||(n.value=t.value)),n}e.exports=function(o,t,e,n,a,s,c){var l=u(o.documentElement,a.javascriptEnabled),h=t.createElement("iframe");return h.className="html2canvas-container",h.style.visibility="hidden",h.style.position="fixed",h.style.left="-10000px",h.style.top="0px",h.style.border="0",h.width=e,h.height=n,h.scrolling="no",t.body.appendChild(h),new Promise(function(e){var t,n,r,i=h.contentWindow.document;h.contentWindow.onload=h.onload=function(){var t=setInterval(function(){0<i.body.childNodes.length&&(!function t(e){if(1===e.nodeType){e.scrollTop=e._scrollTop,e.scrollLeft=e._scrollLeft;for(var n=e.firstChild;n;)t(n),n=n.nextSibling}}(i.documentElement),clearInterval(t),"view"===a.type&&(h.contentWindow.scrollTo(s,c),!/(iPad|iPhone|iPod)/g.test(navigator.userAgent)||h.contentWindow.scrollY===c&&h.contentWindow.scrollX===s||(i.documentElement.style.top=-c+"px",i.documentElement.style.left=-s+"px",i.documentElement.style.position="absolute")),e(h))},50)},i.open(),i.write("<!DOCTYPE html><html></html>"),n=s,r=c,!(t=o).defaultView||n===t.defaultView.pageXOffset&&r===t.defaultView.pageYOffset||t.defaultView.scrollTo(n,r),i.replaceChild(i.adoptNode(l),i.documentElement),i.close()})}},{"./log":13}],3:[function(t,e,n){function r(t){this.r=0,this.g=0,this.b=0,this.a=null;this.fromArray(t)||this.namedColor(t)||this.rgb(t)||this.rgba(t)||this.hex6(t)||this.hex3(t)}r.prototype.darken=function(t){var e=1-t;return new r([Math.round(this.r*e),Math.round(this.g*e),Math.round(this.b*e),this.a])},r.prototype.isTransparent=function(){return 0===this.a},r.prototype.isBlack=function(){return 0===this.r&&0===this.g&&0===this.b},r.prototype.fromArray=function(t){return Array.isArray(t)&&(this.r=Math.min(t[0],255),this.g=Math.min(t[1],255),this.b=Math.min(t[2],255),3<t.length&&(this.a=t[3])),Array.isArray(t)};var i=/^#([a-f0-9]{3})$/i;r.prototype.hex3=function(t){var e;return null!==(e=t.match(i))&&(this.r=parseInt(e[1][0]+e[1][0],16),this.g=parseInt(e[1][1]+e[1][1],16),this.b=parseInt(e[1][2]+e[1][2],16)),null!==e};var o=/^#([a-f0-9]{6})$/i;r.prototype.hex6=function(t){var e=null;return null!==(e=t.match(o))&&(this.r=parseInt(e[1].substring(0,2),16),this.g=parseInt(e[1].substring(2,4),16),this.b=parseInt(e[1].substring(4,6),16)),null!==e};var a=/^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/;r.prototype.rgb=function(t){var e;return null!==(e=t.match(a))&&(this.r=Number(e[1]),this.g=Number(e[2]),this.b=Number(e[3])),null!==e};var s=/^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d?\.?\d+)\s*\)$/;r.prototype.rgba=function(t){var e;return null!==(e=t.match(s))&&(this.r=Number(e[1]),this.g=Number(e[2]),this.b=Number(e[3]),this.a=Number(e[4])),null!==e},r.prototype.toString=function(){return null!==this.a&&1!==this.a?"rgba("+[this.r,this.g,this.b,this.a].join(",")+")":"rgb("+[this.r,this.g,this.b].join(",")+")"},r.prototype.namedColor=function(t){t=t.toLowerCase();var e=c[t];if(e)this.r=e[0],this.g=e[1],this.b=e[2];else if("transparent"===t)return this.r=this.g=this.b=this.a=0,!0;return!!e},r.prototype.isColor=!0;var c={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]};e.exports=r},{}],4:[function(t,e,n){var p=t("./support"),d=t("./renderers/canvas"),g=t("./imageloader"),m=t("./nodeparser"),r=t("./nodecontainer"),y=t("./log"),i=t("./utils"),w=t("./clone"),v=t("./proxy").loadUrlDocument,b=i.getBounds,x="data-html2canvas-node",S=0;function o(t,e){var n,r,i=S++;if((e=e||{}).logging&&(y.options.logging=!0,y.options.start=Date.now()),e.async=void 0===e.async||e.async,e.allowTaint=void 0!==e.allowTaint&&e.allowTaint,e.removeContainer=void 0===e.removeContainer||e.removeContainer,e.javascriptEnabled=void 0!==e.javascriptEnabled&&e.javascriptEnabled,e.imageTimeout=void 0===e.imageTimeout?1e4:e.imageTimeout,e.renderer="function"==typeof e.renderer?e.renderer:d,e.strict=!!e.strict,"string"==typeof t){if("string"!=typeof e.proxy)return Promise.reject("Proxy must be used when rendering url");var o=null!=e.width?e.width:window.innerWidth,a=null!=e.height?e.height:window.innerHeight;return v((n=t,r=document.createElement("a"),r.href=n,r.href=r.href,r),e.proxy,document,o,a,e).then(function(t){return k(t.contentWindow.document.documentElement,t,e,o,a)})}var s,c,l,h,u,f=(void 0===t?[document.documentElement]:t.length?t:[t])[0];return f.setAttribute(x+i,i),(s=f.ownerDocument,c=e,l=f.ownerDocument.defaultView.innerWidth,h=f.ownerDocument.defaultView.innerHeight,u=i,w(s,s,l,h,c,s.defaultView.pageXOffset,s.defaultView.pageYOffset).then(function(t){y("Document cloned");var e=x+u,n="["+e+"='"+u+"']";s.querySelector(n).removeAttribute(e);var r=t.contentWindow,i=r.document.querySelector(n),o="function"==typeof c.onclone?Promise.resolve(c.onclone(r.document)):Promise.resolve(!0);return o.then(function(){return k(i,t,c,l,h)})})).then(function(t){return"function"==typeof e.onrendered&&(y("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas"),e.onrendered(t)),t})}o.CanvasRenderer=d,o.NodeContainer=r,o.log=y,o.utils=i;var a="undefined"==typeof document||"function"!=typeof Object.create||"function"!=typeof document.createElement("canvas").getContext?function(){return Promise.reject("No canvas support")}:o;function k(n,r,i,t,e){var o,a,s=r.contentWindow,c=new p(s.document),l=new g(i,c),h=b(n),u="view"===i.type?t:(o=s.document,Math.max(Math.max(o.body.scrollWidth,o.documentElement.scrollWidth),Math.max(o.body.offsetWidth,o.documentElement.offsetWidth),Math.max(o.body.clientWidth,o.documentElement.clientWidth))),f="view"===i.type?e:(a=s.document,Math.max(Math.max(a.body.scrollHeight,a.documentElement.scrollHeight),Math.max(a.body.offsetHeight,a.documentElement.offsetHeight),Math.max(a.body.clientHeight,a.documentElement.clientHeight))),d=new i.renderer(u,f,l,i,document);return new m(n,d,c,l,i).ready.then(function(){var t,e;return y("Finished rendering"),t="view"===i.type?_(d.canvas,{width:d.canvas.width,height:d.canvas.height,top:0,left:0,x:0,y:0}):n===s.document.body||n===s.document.documentElement||null!=i.canvas?d.canvas:_(d.canvas,{width:null!=i.width?i.width:h.width,height:null!=i.height?i.height:h.height,top:h.top,left:h.left,x:0,y:0}),e=r,i.removeContainer&&(e.parentNode.removeChild(e),y("Cleaned up container")),t})}function _(t,e){var n=document.createElement("canvas"),r=Math.min(t.width-1,Math.max(0,e.left)),i=Math.min(t.width,Math.max(1,e.left+e.width)),o=Math.min(t.height-1,Math.max(0,e.top)),a=Math.min(t.height,Math.max(1,e.top+e.height));n.width=e.width,n.height=e.height;var s=i-r,c=a-o;return y("Cropping canvas at:","left:",e.left,"top:",e.top,"width:",s,"height:",c),y("Resulting crop with width",e.width,"and height",e.height,"with x",r,"and y",o),n.getContext("2d").drawImage(t,r,o,s,c,e.x,e.y,s,c),n}e.exports=a},{"./clone":2,"./imageloader":11,"./log":13,"./nodecontainer":14,"./nodeparser":15,"./proxy":16,"./renderers/canvas":20,"./support":22,"./utils":26}],5:[function(t,e,n){var r=t("./log"),i=t("./utils").smallImage;e.exports=function t(e){if(this.src=e,r("DummyImageContainer for",e),!this.promise||!this.image){r("Initiating DummyImageContainer"),t.prototype.image=new Image;var n=this.image;t.prototype.promise=new Promise(function(t,e){n.onload=t,n.onerror=e,n.src=i(),!0===n.complete&&t(n)})}}},{"./log":13,"./utils":26}],6:[function(t,e,n){var c=t("./utils").smallImage;e.exports=function(t,e){var n,r,i=document.createElement("div"),o=document.createElement("img"),a=document.createElement("span"),s="Hidden Text";i.style.visibility="hidden",i.style.fontFamily=t,i.style.fontSize=e,i.style.margin=0,i.style.padding=0,document.body.appendChild(i),o.src=c(),o.width=1,o.height=1,o.style.margin=0,o.style.padding=0,o.style.verticalAlign="baseline",a.style.fontFamily=t,a.style.fontSize=e,a.style.margin=0,a.style.padding=0,a.appendChild(document.createTextNode(s)),i.appendChild(a),i.appendChild(o),n=o.offsetTop-a.offsetTop+1,i.removeChild(a),i.appendChild(document.createTextNode(s)),i.style.lineHeight="normal",o.style.verticalAlign="super",r=o.offsetTop-i.offsetTop+1,document.body.removeChild(i),this.baseline=n,this.lineWidth=1,this.middle=r}},{"./utils":26}],7:[function(t,e,n){var r=t("./font");function i(){this.data={}}i.prototype.getMetrics=function(t,e){return void 0===this.data[t+"-"+e]&&(this.data[t+"-"+e]=new r(t,e)),this.data[t+"-"+e]},e.exports=i},{"./font":6}],8:[function(o,t,e){var a=o("./utils").getBounds,i=o("./proxy").loadUrlDocument;function n(e,t,n){this.image=null,this.src=e;var r=this,i=a(e);this.promise=(t?new Promise(function(t){"about:blank"===e.contentWindow.document.URL||null==e.contentWindow.document.documentElement?e.contentWindow.onload=e.onload=function(){t(e)}:t(e)}):this.proxyLoad(n.proxy,i,n)).then(function(t){return o("./core")(t.contentWindow.document.documentElement,{type:"view",width:t.width,height:t.height,proxy:n.proxy,javascriptEnabled:n.javascriptEnabled,removeContainer:n.removeContainer,allowTaint:n.allowTaint,imageTimeout:n.imageTimeout/2})}).then(function(t){return r.image=t})}n.prototype.proxyLoad=function(t,e,n){var r=this.src;return i(r.src,t,r.ownerDocument,e.width,e.height,n)},t.exports=n},{"./core":4,"./proxy":16,"./utils":26}],9:[function(t,e,n){function r(t){this.src=t.value,this.colorStops=[],this.type=null,this.x0=.5,this.y0=.5,this.x1=.5,this.y1=.5,this.promise=Promise.resolve(!0)}r.TYPES={LINEAR:1,RADIAL:2},r.REGEXP_COLORSTOP=/^\s*(rgba?\(\s*\d{1,3},\s*\d{1,3},\s*\d{1,3}(?:,\s*[0-9\.]+)?\s*\)|[a-z]{3,20}|#[a-f0-9]{3,6})(?:\s+(\d{1,3}(?:\.\d+)?)(%|px)?)?(?:\s|$)/i,e.exports=r},{}],10:[function(t,e,n){e.exports=function(n,r){this.src=n,this.image=new Image;var i=this;this.tainted=null,this.promise=new Promise(function(t,e){i.image.onload=t,i.image.onerror=e,r&&(i.image.crossOrigin="anonymous"),i.image.src=n,!0===i.image.complete&&t(i.image)})}},{}],11:[function(t,e,n){var o=t("./log"),r=t("./imagecontainer"),i=t("./dummyimagecontainer"),a=t("./proxyimagecontainer"),s=t("./framecontainer"),c=t("./svgcontainer"),l=t("./svgnodecontainer"),h=t("./lineargradientcontainer"),u=t("./webkitgradientcontainer"),f=t("./utils").bind;function d(t,e){this.link=null,this.options=t,this.support=e,this.origin=this.getOrigin(window.location.href)}d.prototype.findImages=function(t){var e=[];return t.reduce(function(t,e){switch(e.node.nodeName){case"IMG":return t.concat([{args:[e.node.src],method:"url"}]);case"svg":case"IFRAME":return t.concat([{args:[e.node],method:e.node.nodeName}])}return t},[]).forEach(this.addImage(e,this.loadImage),this),e},d.prototype.findBackgroundImage=function(t,e){return e.parseBackgroundImages().filter(this.hasImageBackground).forEach(this.addImage(t,this.loadImage),this),t},d.prototype.addImage=function(n,r){return function(e){e.args.forEach(function(t){this.imageExists(n,t)||(n.splice(0,0,r.call(this,e)),o("Added image #"+n.length,"string"==typeof t?t.substring(0,100):t))},this)}},d.prototype.hasImageBackground=function(t){return"none"!==t.method},d.prototype.loadImage=function(t){if("url"===t.method){var e=t.args[0];return!this.isSVG(e)||this.support.svg||this.options.allowTaint?e.match(/data:image\/.*;base64,/i)?new r(e.replace(/url\(['"]{0,}|['"]{0,}\)$/gi,""),!1):this.isSameOrigin(e)||!0===this.options.allowTaint||this.isSVG(e)?new r(e,!1):this.support.cors&&!this.options.allowTaint&&this.options.useCORS?new r(e,!0):this.options.proxy?new a(e,this.options.proxy):new i(e):new c(e)}return"linear-gradient"===t.method?new h(t):"gradient"===t.method?new u(t):"svg"===t.method?new l(t.args[0],this.support.svg):"IFRAME"===t.method?new s(t.args[0],this.isSameOrigin(t.args[0].src),this.options):new i(t)},d.prototype.isSVG=function(t){return"svg"===t.substring(t.length-3).toLowerCase()||c.prototype.isInline(t)},d.prototype.imageExists=function(t,e){return t.some(function(t){return t.src===e})},d.prototype.isSameOrigin=function(t){return this.getOrigin(t)===this.origin},d.prototype.getOrigin=function(t){var e=this.link||(this.link=document.createElement("a"));return e.href=t,e.href=e.href,e.protocol+e.hostname+e.port},d.prototype.getPromise=function(e){return this.timeout(e,this.options.imageTimeout).catch(function(){return new i(e.src).promise.then(function(t){e.image=t})})},d.prototype.get=function(e){var n=null;return this.images.some(function(t){return(n=t).src===e})?n:null},d.prototype.fetch=function(t){return this.images=t.reduce(f(this.findBackgroundImage,this),this.findImages(t)),this.images.forEach(function(e,n){e.promise.then(function(){o("Succesfully loaded image #"+(n+1),e)},function(t){o("Failed loading image #"+(n+1),e,t)})}),this.ready=Promise.all(this.images.map(this.getPromise,this)),o("Finished searching images"),this},d.prototype.timeout=function(n,r){var i,t=Promise.race([n.promise,new Promise(function(t,e){i=setTimeout(function(){o("Timed out loading image",n),e(n)},r)})]).then(function(t){return clearTimeout(i),t});return t.catch(function(){clearTimeout(i)}),t},e.exports=d},{"./dummyimagecontainer":5,"./framecontainer":8,"./imagecontainer":10,"./lineargradientcontainer":12,"./log":13,"./proxyimagecontainer":17,"./svgcontainer":23,"./svgnodecontainer":24,"./utils":26,"./webkitgradientcontainer":27}],12:[function(t,e,n){var i=t("./gradientcontainer"),o=t("./color");function r(t){i.apply(this,arguments),this.type=i.TYPES.LINEAR;var e=r.REGEXP_DIRECTION.test(t.args[0])||!i.REGEXP_COLORSTOP.test(t.args[0]);e?t.args[0].split(/\s+/).reverse().forEach(function(t,e){switch(t){case"left":this.x0=0,this.x1=1;break;case"top":this.y0=0,this.y1=1;break;case"right":this.x0=1,this.x1=0;break;case"bottom":this.y0=1,this.y1=0;break;case"to":var n=this.y0,r=this.x0;this.y0=this.y1,this.x0=this.x1,this.x1=r,this.y1=n;break;case"center":break;default:var i=.01*parseFloat(t,10);if(isNaN(i))break;0===e?(this.y0=i,this.y1=1-this.y0):(this.x0=i,this.x1=1-this.x0)}},this):(this.y0=0,this.y1=1),this.colorStops=t.args.slice(e?1:0).map(function(t){var e=t.match(i.REGEXP_COLORSTOP),n=+e[2],r=0===n?"%":e[3];return{color:new o(e[1]),stop:"%"===r?n/100:null}}),null===this.colorStops[0].stop&&(this.colorStops[0].stop=0),null===this.colorStops[this.colorStops.length-1].stop&&(this.colorStops[this.colorStops.length-1].stop=1),this.colorStops.forEach(function(n,r){null===n.stop&&this.colorStops.slice(r).some(function(t,e){return null!==t.stop&&(n.stop=(t.stop-this.colorStops[r-1].stop)/(e+1)+this.colorStops[r-1].stop,!0)},this)},this)}r.prototype=Object.create(i.prototype),r.REGEXP_DIRECTION=/^\s*(?:to|left|right|top|bottom|center|\d{1,3}(?:\.\d+)?%?)(?:\s|$)/i,e.exports=r},{"./color":3,"./gradientcontainer":9}],13:[function(t,e,n){var r=function(){r.options.logging&&window.console&&window.console.log&&Function.prototype.bind.call(window.console.log,window.console).apply(window.console,[Date.now()-r.options.start+"ms","html2canvas:"].concat([].slice.call(arguments,0)))};r.options={logging:!1},e.exports=r},{}],14:[function(t,e,n){var o=t("./color"),r=t("./utils"),i=r.getBounds,a=r.parseBackgrounds,s=r.offsetBounds;function c(t,e){this.node=t,this.parent=e,this.stack=null,this.bounds=null,this.borders=null,this.clip=[],this.backgroundClip=[],this.offsetBounds=null,this.visible=null,this.computedStyles=null,this.colors={},this.styles={},this.backgroundImages=null,this.transformData=null,this.transformMatrix=null,this.isPseudoElement=!1,this.opacity=null}function l(t){return-1!==t.toString().indexOf("%")}function h(t){return t.replace("px","")}function u(t){return parseFloat(t)}c.prototype.cloneTo=function(t){t.visible=this.visible,t.borders=this.borders,t.bounds=this.bounds,t.clip=this.clip,t.backgroundClip=this.backgroundClip,t.computedStyles=this.computedStyles,t.styles=this.styles,t.backgroundImages=this.backgroundImages,t.opacity=this.opacity},c.prototype.getOpacity=function(){return null===this.opacity?this.opacity=this.cssFloat("opacity"):this.opacity},c.prototype.assignStack=function(t){(this.stack=t).children.push(this)},c.prototype.isElementVisible=function(){return this.node.nodeType===Node.TEXT_NODE?this.parent.visible:"none"!==this.css("display")&&"hidden"!==this.css("visibility")&&!this.node.hasAttribute("data-html2canvas-ignore")&&("INPUT"!==this.node.nodeName||"hidden"!==this.node.getAttribute("type"))},c.prototype.css=function(t){return this.computedStyles||(this.computedStyles=this.isPseudoElement?this.parent.computedStyle(this.before?":before":":after"):this.computedStyle(null)),this.styles[t]||(this.styles[t]=this.computedStyles[t])},c.prototype.prefixedCss=function(e){var n=this.css(e);return void 0===n&&["webkit","moz","ms","o"].some(function(t){return void 0!==(n=this.css(t+e.substr(0,1).toUpperCase()+e.substr(1)))},this),void 0===n?null:n},c.prototype.computedStyle=function(t){return this.node.ownerDocument.defaultView.getComputedStyle(this.node,t)},c.prototype.cssInt=function(t){var e=parseInt(this.css(t),10);return isNaN(e)?0:e},c.prototype.color=function(t){return this.colors[t]||(this.colors[t]=new o(this.css(t)))},c.prototype.cssFloat=function(t){var e=parseFloat(this.css(t));return isNaN(e)?0:e},c.prototype.fontWeight=function(){var t=this.css("fontWeight");switch(parseInt(t,10)){case 401:t="bold";break;case 400:t="normal"}return t},c.prototype.parseClip=function(){var t=this.css("clip").match(this.CLIP);return t?{top:parseInt(t[1],10),right:parseInt(t[2],10),bottom:parseInt(t[3],10),left:parseInt(t[4],10)}:null},c.prototype.parseBackgroundImages=function(){return this.backgroundImages||(this.backgroundImages=a(this.css("backgroundImage")))},c.prototype.cssList=function(t,e){var n=(this.css(t)||"").split(",");return 1===(n=(n=n[e||0]||n[0]||"auto").trim().split(" ")).length&&(n=[n[0],l(n[0])?"auto":n[0]]),n},c.prototype.parseBackgroundSize=function(t,e,n){var r,i,o=this.cssList("backgroundSize",n);if(l(o[0]))r=t.width*parseFloat(o[0])/100;else{if(/contain|cover/.test(o[0])){var a=t.width/t.height,s=e.width/e.height;return a<s^"contain"===o[0]?{width:t.height*s,height:t.height}:{width:t.width,height:t.width/s}}r=parseInt(o[0],10)}return i="auto"===o[0]&&"auto"===o[1]?e.height:"auto"===o[1]?r/e.width*e.height:l(o[1])?t.height*parseFloat(o[1])/100:parseInt(o[1],10),"auto"===o[0]&&(r=i/e.height*e.width),{width:r,height:i}},c.prototype.parseBackgroundPosition=function(t,e,n,r){var i,o,a=this.cssList("backgroundPosition",n);return i=l(a[0])?(t.width-(r||e).width)*(parseFloat(a[0])/100):parseInt(a[0],10),o="auto"===a[1]?i/e.width*e.height:l(a[1])?(t.height-(r||e).height)*parseFloat(a[1])/100:parseInt(a[1],10),"auto"===a[0]&&(i=o/e.height*e.width),{left:i,top:o}},c.prototype.parseBackgroundRepeat=function(t){return this.cssList("backgroundRepeat",t)[0]},c.prototype.parseTextShadows=function(){var t=this.css("textShadow"),e=[];if(t&&"none"!==t)for(var n=t.match(this.TEXT_SHADOW_PROPERTY),r=0;n&&r<n.length;r++){var i=n[r].match(this.TEXT_SHADOW_VALUES);e.push({color:new o(i[0]),offsetX:i[1]?parseFloat(i[1].replace("px","")):0,offsetY:i[2]?parseFloat(i[2].replace("px","")):0,blur:i[3]?i[3].replace("px",""):0})}return e},c.prototype.parseTransform=function(){if(!this.transformData)if(this.hasTransform()){var t=this.parseBounds(),e=this.prefixedCss("transformOrigin").split(" ").map(h).map(u);e[0]+=t.left,e[1]+=t.top,this.transformData={origin:e,matrix:this.parseTransformMatrix()}}else this.transformData={origin:[0,0],matrix:[1,0,0,1,0,0]};return this.transformData},c.prototype.parseTransformMatrix=function(){if(!this.transformMatrix){var t=this.prefixedCss("transform"),e=t?function(t){{if(t&&"matrix"===t[1])return t[2].split(",").map(function(t){return parseFloat(t.trim())});if(t&&"matrix3d"===t[1]){var e=t[2].split(",").map(function(t){return parseFloat(t.trim())});return[e[0],e[1],e[4],e[5],e[12],e[13]]}}}(t.match(this.MATRIX_PROPERTY)):null;this.transformMatrix=e||[1,0,0,1,0,0]}return this.transformMatrix},c.prototype.parseBounds=function(){return this.bounds||(this.bounds=this.hasTransform()?s(this.node):i(this.node))},c.prototype.hasTransform=function(){return"1,0,0,1,0,0"!==this.parseTransformMatrix().join(",")||this.parent&&this.parent.hasTransform()},c.prototype.getValue=function(){var t,e,n=this.node.value||"";return"SELECT"===this.node.tagName?(t=this.node,n=(e=t.options[t.selectedIndex||0])&&e.text||""):"password"===this.node.type&&(n=Array(n.length+1).join("•")),0===n.length?this.node.placeholder||"":n},c.prototype.MATRIX_PROPERTY=/(matrix|matrix3d)\((.+)\)/,c.prototype.TEXT_SHADOW_PROPERTY=/((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g,c.prototype.TEXT_SHADOW_VALUES=/(-?\d+px)|(#.+)|(rgb\(.+\))|(rgba\(.+\))/g,c.prototype.CLIP=/^rect\((\d+)px,? (\d+)px,? (\d+)px,? (\d+)px\)$/,e.exports=c},{"./color":3,"./utils":26}],15:[function(t,e,n){var s=t("./log"),c=t("punycode"),l=t("./nodecontainer"),f=t("./textcontainer"),d=t("./pseudoelementcontainer"),h=t("./fontmetrics"),u=t("./color"),p=t("./stackingcontext"),r=t("./utils"),g=r.bind,a=r.getBounds,m=r.parseBackgrounds,y=r.offsetBounds;function i(t,e,n,r,i){s("Starting NodeParser"),this.renderer=e,this.options=i,this.range=null,this.support=n,this.renderQueue=[],this.stack=new p(!0,1,t.ownerDocument,null);var o=new l(t,null);if(i.background&&e.rectangle(0,0,e.width,e.height,new u(i.background)),t===t.ownerDocument.documentElement){var a=new l(o.color("backgroundColor").isTransparent()?t.ownerDocument.body:t.ownerDocument.documentElement,null);e.rectangle(0,0,e.width,e.height,a.color("backgroundColor"))}o.visibile=o.isElementVisible(),this.createPseudoHideStyles(t.ownerDocument),this.disableAnimations(t.ownerDocument),this.nodes=U([o].concat(this.getChildren(o)).filter(function(t){return t.visible=t.isElementVisible()}).map(this.getPseudoElements,this)),this.fontMetrics=new h,s("Fetched nodes, total:",this.nodes.length),s("Calculate overflow clips"),this.calculateOverflowClips(),s("Start fetching images"),this.images=r.fetch(this.nodes.filter(R)),this.ready=this.images.ready.then(g(function(){return s("Images loaded, starting parsing"),s("Creating stacking contexts"),this.createStackingContexts(),s("Sorting stacking contexts"),this.sortStackingContexts(this.stack),this.parse(this.stack),s("Render queue created with "+this.renderQueue.length+" items"),new Promise(g(function(t){i.async?"function"==typeof i.async?i.async.call(this,this.renderQueue,t):0<this.renderQueue.length?(this.renderIndex=0,this.asyncRenderer(this.renderQueue,t)):t():(this.renderQueue.forEach(this.paint,this),t())},this))},this))}function o(t){return t.parent&&t.parent.clip.length}function w(){}i.prototype.calculateOverflowClips=function(){this.nodes.forEach(function(t){if(R(t)){D(t)&&t.appendToDOM(),t.borders=this.parseBorders(t);var e="hidden"===t.css("overflow")?[t.borders.clip]:[],n=t.parseClip();n&&-1!==["absolute","fixed"].indexOf(t.css("position"))&&e.push([["rect",t.bounds.left+n.left,t.bounds.top+n.top,n.right-n.left,n.bottom-n.top]]),t.clip=o(t)?t.parent.clip.concat(e):e,t.backgroundClip="hidden"!==t.css("overflow")?t.clip.concat([t.borders.clip]):t.clip,D(t)&&t.cleanDOM()}else M(t)&&(t.clip=o(t)?t.parent.clip:[]);D(t)||(t.bounds=null)},this)},i.prototype.asyncRenderer=function(t,e,n){n=n||Date.now(),this.paint(t[this.renderIndex++]),t.length===this.renderIndex?e():n+20>Date.now()?this.asyncRenderer(t,e,n):setTimeout(g(function(){this.asyncRenderer(t,e)},this),0)},i.prototype.createPseudoHideStyles=function(t){this.createStyles(t,"."+d.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE+':before { content: "" !important; display: none !important; }.'+d.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER+':after { content: "" !important; display: none !important; }')},i.prototype.disableAnimations=function(t){this.createStyles(t,"* { -webkit-animation: none !important; -moz-animation: none !important; -o-animation: none !important; animation: none !important; -webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; transition: none !important;}")},i.prototype.createStyles=function(t,e){var n=t.createElement("style");n.innerHTML=e,t.body.appendChild(n)},i.prototype.getPseudoElements=function(t){var e=[[t]];if(t.node.nodeType===Node.ELEMENT_NODE){var n=this.getPseudoElement(t,":before"),r=this.getPseudoElement(t,":after");n&&e.push(n),r&&e.push(r)}return U(e)},i.prototype.getPseudoElement=function(t,e){var n=t.computedStyle(e);if(!n||!n.content||"none"===n.content||"-moz-alt-content"===n.content||"none"===n.display)return null;for(var r,i,o=(r=n.content,(i=r.substr(0,1))===r.substr(r.length-1)&&i.match(/'|"/)?r.substr(1,r.length-2):r),a="url"===o.substr(0,3),s=document.createElement(a?"img":"html2canvaspseudoelement"),c=new d(s,t,e),l=n.length-1;0<=l;l--){var h=n.item(l).replace(/(\-[a-z])/g,function(t){return t.toUpperCase().replace("-","")});s.style[h]=n[h]}if(s.className=d.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE+" "+d.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER,a)return s.src=m(o)[0].args[0],[c];var u=document.createTextNode(o);return s.appendChild(u),[c,new f(u,c)]},i.prototype.getChildren=function(n){return U([].filter.call(n.node.childNodes,P).map(function(t){var e=[t.nodeType===Node.TEXT_NODE?new f(t,n):new l(t,n)].filter(L);return t.nodeType===Node.ELEMENT_NODE&&e.length&&"TEXTAREA"!==t.tagName?e[0].isElementVisible()?e.concat(this.getChildren(e[0])):[]:e},this))},i.prototype.newStackingContext=function(t,e){var n=new p(e,t.getOpacity(),t.node,t.parent);t.cloneTo(n),(e?n.getParentStack(this):n.parent.stack).contexts.push(n),t.stack=n},i.prototype.createStackingContexts=function(){this.nodes.forEach(function(t){var e,n;R(t)&&(this.isRootElement(t)||t.getOpacity()<1||(n=(e=t).css("position"),"auto"!==(-1!==["absolute","relative","fixed"].indexOf(n)?e.css("zIndex"):"auto"))||this.isBodyWithTransparentRoot(t)||t.hasTransform())?this.newStackingContext(t,!0):R(t)&&(O(t)&&T(t)||-1!==["inline-block","inline-table"].indexOf(t.css("display"))||B(t))?this.newStackingContext(t,!1):t.assignStack(t.parent.stack)},this)},i.prototype.isBodyWithTransparentRoot=function(t){return"BODY"===t.node.nodeName&&t.parent.color("backgroundColor").isTransparent()},i.prototype.isRootElement=function(t){return null===t.parent},i.prototype.sortStackingContexts=function(t){var n;t.contexts.sort((n=t.contexts.slice(0),function(t,e){return t.cssInt("zIndex")+n.indexOf(t)/n.length-(e.cssInt("zIndex")+n.indexOf(e)/n.length)})),t.contexts.forEach(this.sortStackingContexts,this)},i.prototype.parseTextBounds=function(a){return function(t,e,n){if("none"!==a.parent.css("textDecoration").substr(0,4)||0!==t.trim().length){if(this.support.rangeBounds&&!a.parent.hasTransform()){var r=n.slice(0,e).join("").length;return this.getRangeBounds(a.node,r,t.length)}if(a.node&&"string"==typeof a.node.data){var i=a.node.splitText(t.length),o=this.getWrapperBounds(a.node,a.parent.hasTransform());return a.node=i,o}}else this.support.rangeBounds&&!a.parent.hasTransform()||(a.node=a.node.splitText(t.length));return{}}},i.prototype.getWrapperBounds=function(t,e){var n=t.ownerDocument.createElement("html2canvaswrapper"),r=t.parentNode,i=t.cloneNode(!0);n.appendChild(t.cloneNode(!0)),r.replaceChild(n,t);var o=e?y(n):a(n);return r.replaceChild(i,n),o},i.prototype.getRangeBounds=function(t,e,n){var r=this.range||(this.range=t.ownerDocument.createRange());return r.setStart(t,e),r.setEnd(t,e+n),r.getBoundingClientRect()},i.prototype.parse=function(t){var e=t.contexts.filter(I),n=t.children.filter(R),r=n.filter(j(B)),i=r.filter(j(O)).filter(j(F)),o=n.filter(j(O)).filter(B),a=r.filter(j(O)).filter(F),s=t.contexts.concat(r.filter(O)).filter(T),c=t.children.filter(M).filter(E),l=t.contexts.filter(A);e.concat(i).concat(o).concat(a).concat(s).concat(c).concat(l).forEach(function(t){this.renderQueue.push(t),q(t)&&(this.parse(t),this.renderQueue.push(new w))},this)},i.prototype.paint=function(t){try{t instanceof w?this.renderer.ctx.restore():M(t)?(D(t.parent)&&t.parent.appendToDOM(),this.paintText(t),D(t.parent)&&t.parent.cleanDOM()):this.paintNode(t)}catch(t){if(s(t),this.options.strict)throw t}},i.prototype.paintNode=function(t){q(t)&&(this.renderer.setOpacity(t.opacity),this.renderer.ctx.save(),t.hasTransform()&&this.renderer.setTransform(t.parseTransform())),"INPUT"===t.node.nodeName&&"checkbox"===t.node.type?this.paintCheckbox(t):"INPUT"===t.node.nodeName&&"radio"===t.node.type?this.paintRadio(t):this.paintElement(t)},i.prototype.paintElement=function(n){var r=n.parseBounds();this.renderer.clip(n.backgroundClip,function(){this.renderer.renderBackground(n,r,n.borders.borders.map(N))},this),this.renderer.clip(n.clip,function(){this.renderer.renderBorders(n.borders.borders)},this),this.renderer.clip(n.backgroundClip,function(){switch(n.node.nodeName){case"svg":case"IFRAME":var t=this.images.get(n.node);t?this.renderer.renderImage(n,r,n.borders,t):s("Error loading <"+n.node.nodeName+">",n.node);break;case"IMG":var e=this.images.get(n.node.src);e?this.renderer.renderImage(n,r,n.borders,e):s("Error loading <img>",n.node.src);break;case"CANVAS":this.renderer.renderImage(n,r,n.borders,{image:n.node});break;case"SELECT":case"INPUT":case"TEXTAREA":this.paintFormValue(n)}},this)},i.prototype.paintCheckbox=function(t){var e=t.parseBounds(),n=Math.min(e.width,e.height),r={width:n-1,height:n-1,top:e.top,left:e.left},i=[3,3],o=[i,i,i,i],a=[1,1,1,1].map(function(t){return{color:new u("#A5A5A5"),width:t}}),s=S(r,o,a);this.renderer.clip(t.backgroundClip,function(){this.renderer.rectangle(r.left+1,r.top+1,r.width-2,r.height-2,new u("#DEDEDE")),this.renderer.renderBorders(b(a,r,s,o)),t.node.checked&&(this.renderer.font(new u("#424242"),"normal","normal","bold",n-3+"px","arial"),this.renderer.text("✔",r.left+n/6,r.top+n-1))},this)},i.prototype.paintRadio=function(t){var e=t.parseBounds(),n=Math.min(e.width,e.height)-2;this.renderer.clip(t.backgroundClip,function(){this.renderer.circleStroke(e.left+1,e.top+1,n,new u("#DEDEDE"),1,new u("#A5A5A5")),t.node.checked&&this.renderer.circle(Math.ceil(e.left+n/4)+1,Math.ceil(e.top+n/4)+1,Math.floor(n/2),new u("#424242"))},this)},i.prototype.paintFormValue=function(e){var t=e.getValue();if(0<t.length){var n=e.node.ownerDocument,r=n.createElement("html2canvaswrapper");["lineHeight","textAlign","fontFamily","fontWeight","fontSize","color","paddingLeft","paddingTop","paddingRight","paddingBottom","width","height","borderLeftStyle","borderTopStyle","borderLeftWidth","borderTopWidth","boxSizing","whiteSpace","wordWrap"].forEach(function(t){try{r.style[t]=e.css(t)}catch(t){s("html2canvas: Parse: Exception caught in renderFormValue: "+t.message)}});var i=e.parseBounds();r.style.position="fixed",r.style.left=i.left+"px",r.style.top=i.top+"px",r.textContent=t,n.body.appendChild(r),this.paintText(new f(r.firstChild,e)),n.body.removeChild(r)}},i.prototype.paintText=function(n){n.applyTextTransform();var t,e=c.ucs2.decode(n.node.data),r=this.options.letterRendering&&!/^(normal|none|0px)$/.test(n.parent.css("letterSpacing"))||(t=n.node.data,/[^\u0000-\u00ff]/.test(t))?e.map(function(t){return c.ucs2.encode([t])}):function(t){var e,n=[],r=0,i=!1;for(;t.length;)o=t[r],-1!==[32,13,10,9,45].indexOf(o)===i?((e=t.splice(0,r)).length&&n.push(c.ucs2.encode(e)),i=!i,r=0):r++,r>=t.length&&(e=t.splice(0,r)).length&&n.push(c.ucs2.encode(e));var o;return n}(e),i=n.parent.fontWeight(),o=n.parent.css("fontSize"),a=n.parent.css("fontFamily"),s=n.parent.parseTextShadows();this.renderer.font(n.parent.color("color"),n.parent.css("fontStyle"),n.parent.css("fontVariant"),i,o,a),s.length?this.renderer.fontShadow(s[0].color,s[0].offsetX,s[0].offsetY,s[0].blur):this.renderer.clearShadow(),this.renderer.clip(n.parent.clip,function(){r.map(this.parseTextBounds(n),this).forEach(function(t,e){t&&(this.renderer.text(r[e],t.left,t.bottom),this.renderTextDecoration(n.parent,t,this.fontMetrics.getMetrics(a,o)))},this)},this)},i.prototype.renderTextDecoration=function(t,e,n){switch(t.css("textDecoration").split(" ")[0]){case"underline":this.renderer.rectangle(e.left,Math.round(e.top+n.baseline+n.lineWidth),e.width,1,t.color("color"));break;case"overline":this.renderer.rectangle(e.left,Math.round(e.top),e.width,1,t.color("color"));break;case"line-through":this.renderer.rectangle(e.left,Math.ceil(e.top+n.middle+n.lineWidth),e.width,1,t.color("color"))}};var v={inset:[["darken",.6],["darken",.1],["darken",.1],["darken",.6]]};function b(a,s,c,l){return a.map(function(t,e){if(0<t.width){var n=s.left,r=s.top,i=s.width,o=s.height-a[2].width;switch(e){case 0:o=a[0].width,t.args=_({c1:[n,r],c2:[n+i,r],c3:[n+i-a[1].width,r+o],c4:[n+a[3].width,r+o]},l[0],l[1],c.topLeftOuter,c.topLeftInner,c.topRightOuter,c.topRightInner);break;case 1:n=s.left+s.width-a[1].width,i=a[1].width,t.args=_({c1:[n+i,r],c2:[n+i,r+o+a[2].width],c3:[n,r+o],c4:[n,r+a[0].width]},l[1],l[2],c.topRightOuter,c.topRightInner,c.bottomRightOuter,c.bottomRightInner);break;case 2:r=r+s.height-a[2].width,o=a[2].width,t.args=_({c1:[n+i,r+o],c2:[n,r+o],c3:[n+a[3].width,r],c4:[n+i-a[3].width,r]},l[2],l[3],c.bottomRightOuter,c.bottomRightInner,c.bottomLeftOuter,c.bottomLeftInner);break;case 3:i=a[3].width,t.args=_({c1:[n,r+o+a[2].width],c2:[n,r],c3:[n+i,r+a[0].width],c4:[n+i,r+o]},l[3],l[0],c.bottomLeftOuter,c.bottomLeftInner,c.topLeftOuter,c.topLeftInner)}}return t})}function x(t,e,n,r){var i=(Math.sqrt(2)-1)/3*4,o=n*i,a=r*i,s=t+n,c=e+r;return{topLeft:k({x:t,y:c},{x:t,y:c-a},{x:s-o,y:e},{x:s,y:e}),topRight:k({x:t,y:e},{x:t+o,y:e},{x:s,y:c-a},{x:s,y:c}),bottomRight:k({x:s,y:e},{x:s,y:e+a},{x:t+o,y:c},{x:t,y:c}),bottomLeft:k({x:s,y:c},{x:s-o,y:c},{x:t,y:e+a},{x:t,y:e})}}function S(t,e,n){var r=t.left,i=t.top,o=t.width,a=t.height,s=e[0][0]<o/2?e[0][0]:o/2,c=e[0][1]<a/2?e[0][1]:a/2,l=e[1][0]<o/2?e[1][0]:o/2,h=e[1][1]<a/2?e[1][1]:a/2,u=e[2][0]<o/2?e[2][0]:o/2,f=e[2][1]<a/2?e[2][1]:a/2,d=e[3][0]<o/2?e[3][0]:o/2,p=e[3][1]<a/2?e[3][1]:a/2,g=o-l,m=a-f,y=o-u,w=a-p;return{topLeftOuter:x(r,i,s,c).topLeft.subdivide(.5),topLeftInner:x(r+n[3].width,i+n[0].width,Math.max(0,s-n[3].width),Math.max(0,c-n[0].width)).topLeft.subdivide(.5),topRightOuter:x(r+g,i,l,h).topRight.subdivide(.5),topRightInner:x(r+Math.min(g,o+n[3].width),i+n[0].width,g>o+n[3].width?0:l-n[3].width,h-n[0].width).topRight.subdivide(.5),bottomRightOuter:x(r+y,i+m,u,f).bottomRight.subdivide(.5),bottomRightInner:x(r+Math.min(y,o-n[3].width),i+Math.min(m,a+n[0].width),Math.max(0,u-n[1].width),f-n[2].width).bottomRight.subdivide(.5),bottomLeftOuter:x(r,i+w,d,p).bottomLeft.subdivide(.5),bottomLeftInner:x(r+n[3].width,i+w,Math.max(0,d-n[3].width),p-n[2].width).bottomLeft.subdivide(.5)}}function k(s,c,l,h){var u=function(t,e,n){return{x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n}};return{start:s,startControl:c,endControl:l,end:h,subdivide:function(t){var e=u(s,c,t),n=u(c,l,t),r=u(l,h,t),i=u(e,n,t),o=u(n,r,t),a=u(i,o,t);return[k(s,e,i,a),k(a,o,r,h)]},curveTo:function(t){t.push(["bezierCurve",c.x,c.y,l.x,l.y,h.x,h.y])},curveToReversed:function(t){t.push(["bezierCurve",l.x,l.y,c.x,c.y,s.x,s.y])}}}function _(t,e,n,r,i,o,a){var s=[];return 0<e[0]||0<e[1]?(s.push(["line",r[1].start.x,r[1].start.y]),r[1].curveTo(s)):s.push(["line",t.c1[0],t.c1[1]]),0<n[0]||0<n[1]?(s.push(["line",o[0].start.x,o[0].start.y]),o[0].curveTo(s),s.push(["line",a[0].end.x,a[0].end.y]),a[0].curveToReversed(s)):(s.push(["line",t.c2[0],t.c2[1]]),s.push(["line",t.c3[0],t.c3[1]])),0<e[0]||0<e[1]?(s.push(["line",i[1].end.x,i[1].end.y]),i[1].curveToReversed(s)):s.push(["line",t.c4[0],t.c4[1]]),s}function C(t,e,n,r,i,o,a){0<e[0]||0<e[1]?(t.push(["line",r[0].start.x,r[0].start.y]),r[0].curveTo(t),r[1].curveTo(t)):t.push(["line",o,a]),(0<n[0]||0<n[1])&&t.push(["line",i[0].start.x,i[0].start.y])}function I(t){return t.cssInt("zIndex")<0}function A(t){return 0<t.cssInt("zIndex")}function T(t){return 0===t.cssInt("zIndex")}function F(t){return-1!==["inline","inline-block","inline-table"].indexOf(t.css("display"))}function q(t){return t instanceof p}function E(t){return 0<t.node.data.trim().length}function P(t){return t.nodeType===Node.TEXT_NODE||t.nodeType===Node.ELEMENT_NODE}function O(t){return"static"!==t.css("position")}function B(t){return"none"!==t.css("float")}function j(t){var e=this;return function(){return!t.apply(e,arguments)}}function R(t){return t.node.nodeType===Node.ELEMENT_NODE}function D(t){return!0===t.isPseudoElement}function M(t){return t.node.nodeType===Node.TEXT_NODE}function z(t){return parseInt(t,10)}function N(t){return t.width}function L(t){return t.node.nodeType!==Node.ELEMENT_NODE||-1===["SCRIPT","HEAD","TITLE","OBJECT","BR","OPTION"].indexOf(t.node.nodeName)}function U(t){return[].concat.apply([],t)}i.prototype.parseBorders=function(o){var r,t=o.parseBounds(),e=(r=o,["TopLeft","TopRight","BottomRight","BottomLeft"].map(function(t){var e=r.css("border"+t+"Radius"),n=e.split(" ");return n.length<=1&&(n[1]=n[0]),n.map(z)})),n=["Top","Right","Bottom","Left"].map(function(t,e){var n=o.css("border"+t+"Style"),r=o.color("border"+t+"Color");"inset"===n&&r.isBlack()&&(r=new u([255,255,255,r.a]));var i=v[n]?v[n][e]:null;return{width:o.cssInt("border"+t+"Width"),color:i?r[i[0]](i[1]):r,args:null}}),i=S(t,e,n);return{clip:this.parseBackgroundClip(o,i,n,e,t),borders:b(n,t,i,e)}},i.prototype.parseBackgroundClip=function(t,e,n,r,i){var o=[];switch(t.css("backgroundClip")){case"content-box":case"padding-box":C(o,r[0],r[1],e.topLeftInner,e.topRightInner,i.left+n[3].width,i.top+n[0].width),C(o,r[1],r[2],e.topRightInner,e.bottomRightInner,i.left+i.width-n[1].width,i.top+n[0].width),C(o,r[2],r[3],e.bottomRightInner,e.bottomLeftInner,i.left+i.width-n[1].width,i.top+i.height-n[2].width),C(o,r[3],r[0],e.bottomLeftInner,e.topLeftInner,i.left+n[3].width,i.top+i.height-n[2].width);break;default:C(o,r[0],r[1],e.topLeftOuter,e.topRightOuter,i.left,i.top),C(o,r[1],r[2],e.topRightOuter,e.bottomRightOuter,i.left+i.width,i.top),C(o,r[2],r[3],e.bottomRightOuter,e.bottomLeftOuter,i.left+i.width,i.top+i.height),C(o,r[3],r[0],e.bottomLeftOuter,e.topLeftOuter,i.left,i.top+i.height)}return o},e.exports=i},{"./color":3,"./fontmetrics":7,"./log":13,"./nodecontainer":14,"./pseudoelementcontainer":18,"./stackingcontext":21,"./textcontainer":25,"./utils":26,punycode:1}],16:[function(t,e,n){var a=t("./xhr"),r=t("./utils"),s=t("./log"),c=t("./clone"),l=r.decode64;function h(t,e,n){var r="withCredentials"in new XMLHttpRequest;if(!e)return Promise.reject("No proxy configured");var i=f(r),o=d(e,t,i);return r?a(o):u(n,o,i).then(function(t){return l(t.content)})}var i=0;function u(i,o,a){return new Promise(function(e,n){var t=i.createElement("script"),r=function(){delete window.html2canvas.proxy[a],i.body.removeChild(t)};window.html2canvas.proxy[a]=function(t){r(),e(t)},t.src=o,t.onerror=function(t){r(),n(t)},i.body.appendChild(t)})}function f(t){return t?"":"html2canvas_"+Date.now()+"_"+ ++i+"_"+Math.round(1e5*Math.random())}function d(t,e,n){return t+"?url="+encodeURIComponent(e)+(n.length?"&callback=html2canvas.proxy."+n:"")}n.Proxy=h,n.ProxyURL=function(t,e,n){var r="crossOrigin"in new Image,i=f(r),o=d(e,t,i);return r?Promise.resolve(o):u(n,o,i).then(function(t){return"data:"+t.type+";base64,"+t.content})},n.loadUrlDocument=function(t,e,n,r,i,o){return new h(t,e,window.document).then((a=t,function(e){var n,t=new DOMParser;try{n=t.parseFromString(e,"text/html")}catch(t){s("DOMParser not supported, falling back to createHTMLDocument"),n=document.implementation.createHTMLDocument("");try{n.open(),n.write(e),n.close()}catch(t){s("createHTMLDocument write not supported, falling back to document.body.innerHTML"),n.body.innerHTML=e}}var r=n.querySelector("base");if(!r||!r.href.host){var i=n.createElement("base");i.href=a,n.head.insertBefore(i,n.head.firstChild)}return n})).then(function(t){return c(t,n,r,i,o,0,0)});var a}},{"./clone":2,"./log":13,"./utils":26,"./xhr":28}],17:[function(t,e,n){var o=t("./proxy").ProxyURL;e.exports=function(n,r){var t=document.createElement("a");t.href=n,n=t.href,this.src=n,this.image=new Image;var i=this;this.promise=new Promise(function(t,e){i.image.crossOrigin="Anonymous",i.image.onload=t,i.image.onerror=e,new o(n,r,document).then(function(t){i.image.src=t}).catch(e)})}},{"./proxy":16}],18:[function(t,e,n){var r=t("./nodecontainer");function i(t,e,n){r.call(this,t,e),this.isPseudoElement=!0,this.before=":before"===n}i.prototype.cloneTo=function(t){i.prototype.cloneTo.call(this,t),t.isPseudoElement=!0,t.before=this.before},(i.prototype=Object.create(r.prototype)).appendToDOM=function(){this.before?this.parent.node.insertBefore(this.node,this.parent.node.firstChild):this.parent.node.appendChild(this.node),this.parent.node.className+=" "+this.getHideClass()},i.prototype.cleanDOM=function(){this.node.parentNode.removeChild(this.node),this.parent.node.className=this.parent.node.className.replace(this.getHideClass(),"")},i.prototype.getHideClass=function(){return this["PSEUDO_HIDE_ELEMENT_CLASS_"+(this.before?"BEFORE":"AFTER")]},i.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE="___html2canvas___pseudoelement_before",i.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER="___html2canvas___pseudoelement_after",e.exports=i},{"./nodecontainer":14}],19:[function(t,e,n){var c=t("./log");function r(t,e,n,r,i){this.width=t,this.height=e,this.images=n,this.options=r,this.document=i}r.prototype.renderImage=function(t,e,n,r){var i=t.cssInt("paddingLeft"),o=t.cssInt("paddingTop"),a=t.cssInt("paddingRight"),s=t.cssInt("paddingBottom"),c=n.borders,l=e.width-(c[1].width+c[3].width+i+a),h=e.height-(c[0].width+c[2].width+o+s);this.drawImage(r,0,0,r.image.width||l,r.image.height||h,e.left+i+c[3].width,e.top+o+c[0].width,l,h)},r.prototype.renderBackground=function(t,e,n){0<e.height&&0<e.width&&(this.renderBackgroundColor(t,e),this.renderBackgroundImage(t,e,n))},r.prototype.renderBackgroundColor=function(t,e){var n=t.color("backgroundColor");n.isTransparent()||this.rectangle(e.left,e.top,e.width,e.height,n)},r.prototype.renderBorders=function(t){t.forEach(this.renderBorder,this)},r.prototype.renderBorder=function(t){t.color.isTransparent()||null===t.args||this.drawShape(t.args,t.color)},r.prototype.renderBackgroundImage=function(o,a,s){o.parseBackgroundImages().reverse().forEach(function(t,e,n){switch(t.method){case"url":var r=this.images.get(t.args[0]);r?this.renderBackgroundRepeating(o,a,r,n.length-(e+1),s):c("Error loading background-image",t.args[0]);break;case"linear-gradient":case"gradient":var i=this.images.get(t.value);i?this.renderBackgroundGradient(i,a,s):c("Error loading background-image",t.args[0]);break;case"none":break;default:c("Unknown background-image type",t.args[0])}},this)},r.prototype.renderBackgroundRepeating=function(t,e,n,r,i){var o=t.parseBackgroundSize(e,n.image,r),a=t.parseBackgroundPosition(e,n.image,r,o);switch(t.parseBackgroundRepeat(r)){case"repeat-x":case"repeat no-repeat":this.backgroundRepeatShape(n,a,o,e,e.left+i[3],e.top+a.top+i[0],99999,o.height,i);break;case"repeat-y":case"no-repeat repeat":this.backgroundRepeatShape(n,a,o,e,e.left+a.left+i[3],e.top+i[0],o.width,99999,i);break;case"no-repeat":this.backgroundRepeatShape(n,a,o,e,e.left+a.left+i[3],e.top+a.top+i[0],o.width,o.height,i);break;default:this.renderBackgroundRepeat(n,a,o,{top:e.top,left:e.left},i[3],i[0])}},e.exports=r},{"./log":13}],20:[function(t,e,n){var r=t("../renderer"),i=t("../lineargradientcontainer"),o=t("../log");function a(t,e){r.apply(this,arguments),this.canvas=this.options.canvas||this.document.createElement("canvas"),this.options.canvas||(this.canvas.width=t,this.canvas.height=e),this.ctx=this.canvas.getContext("2d"),this.taintCtx=this.document.createElement("canvas").getContext("2d"),this.ctx.textBaseline="bottom",this.variables={},o("Initialized CanvasRenderer with size",t,"x",e)}function s(t){return 0<t.length}(a.prototype=Object.create(r.prototype)).setFillStyle=function(t){return this.ctx.fillStyle="object"==typeof t&&t.isColor?t.toString():t,this.ctx},a.prototype.rectangle=function(t,e,n,r,i){this.setFillStyle(i).fillRect(t,e,n,r)},a.prototype.circle=function(t,e,n,r){this.setFillStyle(r),this.ctx.beginPath(),this.ctx.arc(t+n/2,e+n/2,n/2,0,2*Math.PI,!0),this.ctx.closePath(),this.ctx.fill()},a.prototype.circleStroke=function(t,e,n,r,i,o){this.circle(t,e,n,r),this.ctx.strokeStyle=o.toString(),this.ctx.stroke()},a.prototype.drawShape=function(t,e){this.shape(t),this.setFillStyle(e).fill()},a.prototype.taints=function(e){if(null===e.tainted){this.taintCtx.drawImage(e.image,0,0);try{this.taintCtx.getImageData(0,0,1,1),e.tainted=!1}catch(t){this.taintCtx=document.createElement("canvas").getContext("2d"),e.tainted=!0}}return e.tainted},a.prototype.drawImage=function(t,e,n,r,i,o,a,s,c){this.taints(t)&&!this.options.allowTaint||this.ctx.drawImage(t.image,e,n,r,i,o,a,s,c)},a.prototype.clip=function(t,e,n){this.ctx.save(),t.filter(s).forEach(function(t){this.shape(t).clip()},this),e.call(n),this.ctx.restore()},a.prototype.shape=function(t){return this.ctx.beginPath(),t.forEach(function(t,e){"rect"===t[0]?this.ctx.rect.apply(this.ctx,t.slice(1)):this.ctx[0===e?"moveTo":t[0]+"To"].apply(this.ctx,t.slice(1))},this),this.ctx.closePath(),this.ctx},a.prototype.font=function(t,e,n,r,i,o){this.setFillStyle(t).font=[e,n,r,i,o].join(" ").split(",")[0]},a.prototype.fontShadow=function(t,e,n,r){this.setVariable("shadowColor",t.toString()).setVariable("shadowOffsetY",e).setVariable("shadowOffsetX",n).setVariable("shadowBlur",r)},a.prototype.clearShadow=function(){this.setVariable("shadowColor","rgba(0,0,0,0)")},a.prototype.setOpacity=function(t){this.ctx.globalAlpha=t},a.prototype.setTransform=function(t){this.ctx.translate(t.origin[0],t.origin[1]),this.ctx.transform.apply(this.ctx,t.matrix),this.ctx.translate(-t.origin[0],-t.origin[1])},a.prototype.setVariable=function(t,e){return this.variables[t]!==e&&(this.variables[t]=this.ctx[t]=e),this},a.prototype.text=function(t,e,n){this.ctx.fillText(t,e,n)},a.prototype.backgroundRepeatShape=function(t,e,n,r,i,o,a,s,c){var l=[["line",Math.round(i),Math.round(o)],["line",Math.round(i+a),Math.round(o)],["line",Math.round(i+a),Math.round(s+o)],["line",Math.round(i),Math.round(s+o)]];this.clip([l],function(){this.renderBackgroundRepeat(t,e,n,r,c[3],c[0])},this)},a.prototype.renderBackgroundRepeat=function(t,e,n,r,i,o){var a=Math.round(r.left+e.left+i),s=Math.round(r.top+e.top+o);this.setFillStyle(this.ctx.createPattern(this.resizeImage(t,n),"repeat")),this.ctx.translate(a,s),this.ctx.fill(),this.ctx.translate(-a,-s)},a.prototype.renderBackgroundGradient=function(t,e){if(t instanceof i){var n=this.ctx.createLinearGradient(e.left+e.width*t.x0,e.top+e.height*t.y0,e.left+e.width*t.x1,e.top+e.height*t.y1);t.colorStops.forEach(function(t){n.addColorStop(t.stop,t.color.toString())}),this.rectangle(e.left,e.top,e.width,e.height,n)}},a.prototype.resizeImage=function(t,e){var n=t.image;if(n.width===e.width&&n.height===e.height)return n;var r=document.createElement("canvas");return r.width=e.width,r.height=e.height,r.getContext("2d").drawImage(n,0,0,n.width,n.height,0,0,e.width,e.height),r},e.exports=a},{"../lineargradientcontainer":12,"../log":13,"../renderer":19}],21:[function(t,e,n){var i=t("./nodecontainer");function r(t,e,n,r){i.call(this,n,r),this.ownStacking=t,this.contexts=[],this.children=[],this.opacity=(this.parent?this.parent.stack.opacity:1)*e}(r.prototype=Object.create(i.prototype)).getParentStack=function(t){var e=this.parent?this.parent.stack:null;return e?e.ownStacking?e:e.getParentStack(t):t.stack},e.exports=r},{"./nodecontainer":14}],22:[function(t,e,n){function r(t){this.rangeBounds=this.testRangeBounds(t),this.cors=this.testCORS(),this.svg=this.testSVG()}r.prototype.testRangeBounds=function(t){var e,n,r=!1;return t.createRange&&(e=t.createRange()).getBoundingClientRect&&((n=t.createElement("boundtest")).style.height="123px",n.style.display="block",t.body.appendChild(n),e.selectNode(n),123===e.getBoundingClientRect().height&&(r=!0),t.body.removeChild(n)),r},r.prototype.testCORS=function(){return void 0!==(new Image).crossOrigin},r.prototype.testSVG=function(){var t=new Image,e=document.createElement("canvas"),n=e.getContext("2d");t.src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>";try{n.drawImage(t,0,0),e.toDataURL()}catch(t){return!1}return!0},e.exports=r},{}],23:[function(t,e,n){var r=t("./xhr"),i=t("./utils").decode64;function o(t){this.src=t,this.image=null;var n=this;this.promise=this.hasFabric().then(function(){return n.isInline(t)?Promise.resolve(n.inlineFormatting(t)):r(t)}).then(function(e){return new Promise(function(t){window.html2canvas.svg.fabric.loadSVGFromString(e,n.createCanvas.call(n,t))})})}o.prototype.hasFabric=function(){return window.html2canvas.svg&&window.html2canvas.svg.fabric?Promise.resolve():Promise.reject(new Error("html2canvas.svg.js is not loaded, cannot render svg"))},o.prototype.inlineFormatting=function(t){return/^data:image\/svg\+xml;base64,/.test(t)?this.decode64(this.removeContentType(t)):this.removeContentType(t)},o.prototype.removeContentType=function(t){return t.replace(/^data:image\/svg\+xml(;base64)?,/,"")},o.prototype.isInline=function(t){return/^data:image\/svg\+xml/i.test(t)},o.prototype.createCanvas=function(r){var i=this;return function(t,e){var n=new window.html2canvas.svg.fabric.StaticCanvas("c");i.image=n.lowerCanvasEl,n.setWidth(e.width).setHeight(e.height).add(window.html2canvas.svg.fabric.util.groupSVGElements(t,e)).renderAll(),r(n.lowerCanvasEl)}},o.prototype.decode64=function(t){return"function"==typeof window.atob?window.atob(t):i(t)},e.exports=o},{"./utils":26,"./xhr":28}],24:[function(t,e,n){var r=t("./svgcontainer");function i(n,t){this.src=n,this.image=null;var r=this;this.promise=t?new Promise(function(t,e){r.image=new Image,r.image.onload=t,r.image.onerror=e,r.image.src="data:image/svg+xml,"+(new XMLSerializer).serializeToString(n),!0===r.image.complete&&t(r.image)}):this.hasFabric().then(function(){return new Promise(function(t){window.html2canvas.svg.fabric.parseSVGDocument(n,r.createCanvas.call(r,t))})})}i.prototype=Object.create(r.prototype),e.exports=i},{"./svgcontainer":23}],25:[function(t,e,n){var r=t("./nodecontainer");function i(t,e){r.call(this,t,e)}function o(t,e,n){if(0<t.length)return e+n.toUpperCase()}(i.prototype=Object.create(r.prototype)).applyTextTransform=function(){this.node.data=this.transform(this.parent.css("textTransform"))},i.prototype.transform=function(t){var e=this.node.data;switch(t){case"lowercase":return e.toLowerCase();case"capitalize":return e.replace(/(^|\s|:|-|\(|\))([a-z])/g,o);case"uppercase":return e.toUpperCase();default:return e}},e.exports=i},{"./nodecontainer":14}],26:[function(t,e,n){n.smallImage=function(){return"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"},n.bind=function(t,e){return function(){return t.apply(e,arguments)}},
+/*
+   * base64-arraybuffer
+   * https://github.com/niklasvh/base64-arraybuffer
+   *
+   * Copyright (c) 2012 Niklas von Hertzen
+   * Licensed under the MIT license.
+   */
+n.decode64=function(t){var e,n,r,i,o,a,s,c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",l=t.length,h="";for(e=0;e<l;e+=4)o=c.indexOf(t[e])<<2|(n=c.indexOf(t[e+1]))>>4,a=(15&n)<<4|(r=c.indexOf(t[e+2]))>>2,s=(3&r)<<6|(i=c.indexOf(t[e+3])),h+=64===r?String.fromCharCode(o):64===i||-1===i?String.fromCharCode(o,a):String.fromCharCode(o,a,s);return h},n.getBounds=function(t){if(t.getBoundingClientRect){var e=t.getBoundingClientRect(),n=null==t.offsetWidth?e.width:t.offsetWidth;return{top:e.top,bottom:e.bottom||e.top+e.height,right:e.left+n,left:e.left,width:n,height:null==t.offsetHeight?e.height:t.offsetHeight}}return{}},n.offsetBounds=function(t){var e=t.offsetParent?n.offsetBounds(t.offsetParent):{top:0,left:0};return{top:t.offsetTop+e.top,bottom:t.offsetTop+t.offsetHeight+e.top,right:t.offsetLeft+e.left+t.offsetWidth,left:t.offsetLeft+e.left,width:t.offsetWidth,height:t.offsetHeight}},n.parseBackgrounds=function(t){var e,n,r,i,o,a,s,c=[],l=0,h=0,u=function(){e&&('"'===n.substr(0,1)&&(n=n.substr(1,n.length-2)),n&&s.push(n),"-"===e.substr(0,1)&&0<(i=e.indexOf("-",1)+1)&&(r=e.substr(0,i),e=e.substr(i)),c.push({prefix:r,method:e.toLowerCase(),value:o,args:s,image:null})),s=[],e=r=n=o=""};return s=[],e=r=n=o="",t.split("").forEach(function(t){if(!(0===l&&-1<" \r\n\t".indexOf(t))){switch(t){case'"':a?a===t&&(a=null):a=t;break;case"(":if(a)break;if(0===l)return l=1,void(o+=t);h++;break;case")":if(a)break;if(1===l){if(0===h)return l=0,o+=t,void u();h--}break;case",":if(a)break;if(0===l)return void u();if(1===l&&0===h&&!e.match(/^url$/i))return s.push(n),n="",void(o+=t)}o+=t,0===l?e+=t:n+=t}}),u(),c}},{}],27:[function(t,e,n){var r=t("./gradientcontainer");function i(t){r.apply(this,arguments),this.type="linear"===t.args[0]?r.TYPES.LINEAR:r.TYPES.RADIAL}i.prototype=Object.create(r.prototype),e.exports=i},{"./gradientcontainer":9}],28:[function(t,e,n){e.exports=function(r){return new Promise(function(t,e){var n=new XMLHttpRequest;n.open("GET",r),n.onload=function(){200===n.status?t(n.responseText):e(new Error(n.statusText))},n.onerror=function(){e(new Error("Network Error"))},n.send()})}},{}]},{},[4])(4)}),function(t){var n="+".charCodeAt(0),r="/".charCodeAt(0),i="0".charCodeAt(0),o="a".charCodeAt(0),a="A".charCodeAt(0),s="-".charCodeAt(0),c="_".charCodeAt(0),h=function(t){var e=t.charCodeAt(0);return e===n||e===s?62:e===r||e===c?63:e<i?-1:e<i+10?e-i+26+26:e<a+26?e-a:e<o+26?e-o+26:void 0};t.API.TTFFont=function(){function i(t,e,n){var r;if(this.rawData=t,r=this.contents=new X(t),this.contents.pos=4,"ttcf"===r.readString(4)){if(!e)throw new Error("Must specify a font name for TTC files.");throw new Error("Font "+e+" not found in TTC file.")}r.pos=0,this.parse(),this.subset=new T(this),this.registerTTF()}return i.open=function(t,e,n,r){return new i(function(t){var e,n,r,i,o,a;if(0<t.length%4)throw new Error("Invalid string. Length must be a multiple of 4");var s=t.length;o="="===t.charAt(s-2)?2:"="===t.charAt(s-1)?1:0,a=new Uint8Array(3*t.length/4-o),r=0<o?t.length-4:t.length;var c=0;function l(t){a[c++]=t}for(n=e=0;e<r;e+=4,n+=3)l((16711680&(i=h(t.charAt(e))<<18|h(t.charAt(e+1))<<12|h(t.charAt(e+2))<<6|h(t.charAt(e+3))))>>16),l((65280&i)>>8),l(255&i);return 2===o?l(255&(i=h(t.charAt(e))<<2|h(t.charAt(e+1))>>4)):1===o&&(l((i=h(t.charAt(e))<<10|h(t.charAt(e+1))<<4|h(t.charAt(e+2))>>2)>>8&255),l(255&i)),a}(n),e,r)},i.prototype.parse=function(){return this.directory=new e(this.contents),this.head=new d(this),this.name=new b(this),this.cmap=new m(this),this.hhea=new g(this),this.maxp=new x(this),this.hmtx=new S(this),this.post=new w(this),this.os2=new y(this),this.loca=new A(this),this.glyf=new _(this),this.ascender=this.os2.exists&&this.os2.ascender||this.hhea.ascender,this.decender=this.os2.exists&&this.os2.decender||this.hhea.decender,this.lineGap=this.os2.exists&&this.os2.lineGap||this.hhea.lineGap,this.bbox=[this.head.xMin,this.head.yMin,this.head.xMax,this.head.yMax]},i.prototype.registerTTF=function(){var i,t,e,n,r;if(this.scaleFactor=1e3/this.head.unitsPerEm,this.bbox=function(){var t,e,n,r;for(r=[],t=0,e=(n=this.bbox).length;t<e;t++)i=n[t],r.push(Math.round(i*this.scaleFactor));return r}.call(this),this.stemV=0,this.post.exists?(e=255&(n=this.post.italic_angle),!0&(t=n>>16)&&(t=-(1+(65535^t))),this.italicAngle=+(t+"."+e)):this.italicAngle=0,this.ascender=Math.round(this.ascender*this.scaleFactor),this.decender=Math.round(this.decender*this.scaleFactor),this.lineGap=Math.round(this.lineGap*this.scaleFactor),this.capHeight=this.os2.exists&&this.os2.capHeight||this.ascender,this.xHeight=this.os2.exists&&this.os2.xHeight||0,this.familyClass=(this.os2.exists&&this.os2.familyClass||0)>>8,this.isSerif=1===(r=this.familyClass)||2===r||3===r||4===r||5===r||7===r,this.isScript=10===this.familyClass,this.flags=0,this.post.isFixedPitch&&(this.flags|=1),this.isSerif&&(this.flags|=2),this.isScript&&(this.flags|=8),0!==this.italicAngle&&(this.flags|=64),this.flags|=32,!this.cmap.unicode)throw new Error("No unicode cmap for font")},i.prototype.characterToGlyph=function(t){var e;return(null!=(e=this.cmap.unicode)?e.codeMap[t]:void 0)||0},i.prototype.widthOfGlyph=function(t){var e;return e=1e3/this.head.unitsPerEm,this.hmtx.forGlyph(t).advance*e},i.prototype.widthOfString=function(t,e,n){var r,i,o,a,s;for(i=a=o=0,s=(t=""+t).length;0<=s?a<s:s<a;i=0<=s?++a:--a)r=t.charCodeAt(i),o+=this.widthOfGlyph(this.characterToGlyph(r))+n*(1e3/e)||0;return o*(e/1e3)},i.prototype.lineHeight=function(t,e){var n;return null==e&&(e=!1),n=e?this.lineGap:0,(this.ascender+n-this.decender)/1e3*t},i}();var l,X=function(){function t(t){this.data=null!=t?t:[],this.pos=0,this.length=this.data.length}return t.prototype.readByte=function(){return this.data[this.pos++]},t.prototype.writeByte=function(t){return this.data[this.pos++]=t},t.prototype.readUInt32=function(){return 16777216*this.readByte()+(this.readByte()<<16)+(this.readByte()<<8)+this.readByte()},t.prototype.writeUInt32=function(t){return this.writeByte(t>>>24&255),this.writeByte(t>>16&255),this.writeByte(t>>8&255),this.writeByte(255&t)},t.prototype.readInt32=function(){var t;return 2147483648<=(t=this.readUInt32())?t-4294967296:t},t.prototype.writeInt32=function(t){return t<0&&(t+=4294967296),this.writeUInt32(t)},t.prototype.readUInt16=function(){return this.readByte()<<8|this.readByte()},t.prototype.writeUInt16=function(t){return this.writeByte(t>>8&255),this.writeByte(255&t)},t.prototype.readInt16=function(){var t;return 32768<=(t=this.readUInt16())?t-65536:t},t.prototype.writeInt16=function(t){return t<0&&(t+=65536),this.writeUInt16(t)},t.prototype.readString=function(t){var e,n,r;for(n=[],e=r=0;0<=t?r<t:t<r;e=0<=t?++r:--r)n[e]=String.fromCharCode(this.readByte());return n.join("")},t.prototype.writeString=function(t){var e,n,r,i;for(i=[],e=n=0,r=t.length;0<=r?n<r:r<n;e=0<=r?++n:--n)i.push(this.writeByte(t.charCodeAt(e)));return i},t.prototype.readShort=function(){return this.readInt16()},t.prototype.writeShort=function(t){return this.writeInt16(t)},t.prototype.readLongLong=function(){var t,e,n,r,i,o,a,s;return t=this.readByte(),e=this.readByte(),n=this.readByte(),r=this.readByte(),i=this.readByte(),o=this.readByte(),a=this.readByte(),s=this.readByte(),128&t?-1*(72057594037927940*(255^t)+281474976710656*(255^e)+1099511627776*(255^n)+4294967296*(255^r)+16777216*(255^i)+65536*(255^o)+256*(255^a)+(255^s)+1):72057594037927940*t+281474976710656*e+1099511627776*n+4294967296*r+16777216*i+65536*o+256*a+s},t.prototype.readInt=function(){return this.readInt32()},t.prototype.writeInt=function(t){return this.writeInt32(t)},t.prototype.read=function(t){var e,n;for(e=[],n=0;0<=t?n<t:t<n;0<=t?++n:--n)e.push(this.readByte());return e},t.prototype.write=function(t){var e,n,r,i;for(i=[],n=0,r=t.length;n<r;n++)e=t[n],i.push(this.writeByte(e));return i},t}(),e=function(){var p;function t(t){var e,n,r;for(this.scalarType=t.readInt(),this.tableCount=t.readShort(),this.searchRange=t.readShort(),this.entrySelector=t.readShort(),this.rangeShift=t.readShort(),this.tables={},n=0,r=this.tableCount;0<=r?n<r:r<n;0<=r?++n:--n)e={tag:t.readString(4),checksum:t.readInt(),offset:t.readInt(),length:t.readInt()},this.tables[e.tag]=e}return t.prototype.encode=function(t){var e,n,r,i,o,a,s,c,l,h,u,f,d;for(d in u=Object.keys(t).length,a=Math.log(2),l=16*Math.floor(Math.log(u)/a),i=Math.floor(l/a),c=16*u-l,(n=new X).writeInt(this.scalarType),n.writeShort(u),n.writeShort(l),n.writeShort(i),n.writeShort(c),r=16*u,s=n.pos+r,o=null,f=[],t)for(h=t[d],n.writeString(d),n.writeInt(p(h)),n.writeInt(s),n.writeInt(h.length),f=f.concat(h),"head"===d&&(o=s),s+=h.length;s%4;)f.push(0),s++;return n.write(f),e=2981146554-p(n.data),n.pos=o+8,n.writeUInt32(e),n.data},p=function(t){var e,n,r,i;for(t=k.call(t);t.length%4;)t.push(0);for(n=new X(t),r=e=0,i=t.length;r<i;r+=4)e+=n.readUInt32();return 4294967295&e},t}(),u={}.hasOwnProperty,f=function(t,e){for(var n in e)u.call(e,n)&&(t[n]=e[n]);function r(){this.constructor=t}return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t};l=function(){function t(t){var e;this.file=t,e=this.file.directory.tables[this.tag],this.exists=!!e,e&&(this.offset=e.offset,this.length=e.length,this.parse(this.file.contents))}return t.prototype.parse=function(){},t.prototype.encode=function(){},t.prototype.raw=function(){return this.exists?(this.file.contents.pos=this.offset,this.file.contents.read(this.length)):null},t}();var d=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return f(e,l),e.prototype.tag="head",e.prototype.parse=function(t){return t.pos=this.offset,this.version=t.readInt(),this.revision=t.readInt(),this.checkSumAdjustment=t.readInt(),this.magicNumber=t.readInt(),this.flags=t.readShort(),this.unitsPerEm=t.readShort(),this.created=t.readLongLong(),this.modified=t.readLongLong(),this.xMin=t.readShort(),this.yMin=t.readShort(),this.xMax=t.readShort(),this.yMax=t.readShort(),this.macStyle=t.readShort(),this.lowestRecPPEM=t.readShort(),this.fontDirectionHint=t.readShort(),this.indexToLocFormat=t.readShort(),this.glyphDataFormat=t.readShort()},e}(),p=function(){function t(n,t){var e,r,i,o,a,s,c,l,h,u,f,d,p,g,m,y,w,v;switch(this.platformID=n.readUInt16(),this.encodingID=n.readShort(),this.offset=t+n.readInt(),h=n.pos,n.pos=this.offset,this.format=n.readUInt16(),this.length=n.readUInt16(),this.language=n.readUInt16(),this.isUnicode=3===this.platformID&&1===this.encodingID&&4===this.format||0===this.platformID&&4===this.format,this.codeMap={},this.format){case 0:for(s=m=0;m<256;s=++m)this.codeMap[s]=n.readByte();break;case 4:for(f=n.readUInt16(),u=f/2,n.pos+=6,i=function(){var t,e;for(e=[],s=t=0;0<=u?t<u:u<t;s=0<=u?++t:--t)e.push(n.readUInt16());return e}(),n.pos+=2,p=function(){var t,e;for(e=[],s=t=0;0<=u?t<u:u<t;s=0<=u?++t:--t)e.push(n.readUInt16());return e}(),c=function(){var t,e;for(e=[],s=t=0;0<=u?t<u:u<t;s=0<=u?++t:--t)e.push(n.readUInt16());return e}(),l=function(){var t,e;for(e=[],s=t=0;0<=u?t<u:u<t;s=0<=u?++t:--t)e.push(n.readUInt16());return e}(),r=(this.length-n.pos+this.offset)/2,a=function(){var t,e;for(e=[],s=t=0;0<=r?t<r:r<t;s=0<=r?++t:--t)e.push(n.readUInt16());return e}(),s=y=0,v=i.length;y<v;s=++y)for(g=i[s],e=w=d=p[s];d<=g?w<=g:g<=w;e=d<=g?++w:--w)0===l[s]?o=e+c[s]:0!==(o=a[l[s]/2+(e-d)-(u-s)]||0)&&(o+=c[s]),this.codeMap[e]=65535&o}n.pos=h}return t.encode=function(t,e){var n,r,i,o,a,s,c,l,h,u,f,d,p,g,m,y,w,v,b,x,S,k,_,C,I,A,T,F,q,E,P,O,B,j,R,D,M,z,N,L,U,H,W,V,G,Y;switch(F=new X,o=Object.keys(t).sort(function(t,e){return t-e}),e){case"macroman":for(p=0,g=function(){var t,e;for(e=[],d=t=0;t<256;d=++t)e.push(0);return e}(),y={0:0},i={},q=0,B=o.length;q<B;q++)null==y[W=t[r=o[q]]]&&(y[W]=++p),i[r]={old:t[r],new:y[t[r]]},g[r]=y[t[r]];return F.writeUInt16(1),F.writeUInt16(0),F.writeUInt32(12),F.writeUInt16(0),F.writeUInt16(262),F.writeUInt16(0),F.write(g),{charMap:i,subtable:F.data,maxGlyphID:p+1};case"unicode":for(A=[],h=[],y={},n={},m=c=null,E=w=0,j=o.length;E<j;E++)null==y[b=t[r=o[E]]]&&(y[b]=++w),n[r]={old:b,new:y[b]},a=y[b]-r,null!=m&&a===c||(m&&h.push(m),A.push(r),c=a),m=r;for(m&&h.push(m),h.push(65535),A.push(65535),C=2*(_=A.length),k=2*Math.pow(Math.log(_)/Math.LN2,2),u=Math.log(k/2)/Math.LN2,S=2*_-k,s=[],x=[],f=[],d=P=0,R=A.length;P<R;d=++P){if(I=A[d],l=h[d],65535===I){s.push(0),x.push(0);break}if(32768<=I-(T=n[I].new))for(s.push(0),x.push(2*(f.length+_-d)),r=O=I;I<=l?O<=l:l<=O;r=I<=l?++O:--O)f.push(n[r].new);else s.push(T-I),x.push(0)}for(F.writeUInt16(3),F.writeUInt16(1),F.writeUInt32(12),F.writeUInt16(4),F.writeUInt16(16+8*_+2*f.length),F.writeUInt16(0),F.writeUInt16(C),F.writeUInt16(k),F.writeUInt16(u),F.writeUInt16(S),U=0,D=h.length;U<D;U++)r=h[U],F.writeUInt16(r);for(F.writeUInt16(0),H=0,M=A.length;H<M;H++)r=A[H],F.writeUInt16(r);for(V=0,z=s.length;V<z;V++)a=s[V],F.writeUInt16(a);for(G=0,N=x.length;G<N;G++)v=x[G],F.writeUInt16(v);for(Y=0,L=f.length;Y<L;Y++)p=f[Y],F.writeUInt16(p);return{charMap:n,subtable:F.data,maxGlyphID:w+1}}},t}(),m=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return f(e,l),e.prototype.tag="cmap",e.prototype.parse=function(t){var e,n,r;for(t.pos=this.offset,this.version=t.readUInt16(),n=t.readUInt16(),this.tables=[],this.unicode=null,r=0;0<=n?r<n:n<r;0<=n?++r:--r)e=new p(t,this.offset),this.tables.push(e),e.isUnicode&&null==this.unicode&&(this.unicode=e);return!0},e.encode=function(t,e){var n,r;return null==e&&(e="macroman"),n=p.encode(t,e),(r=new X).writeUInt16(0),r.writeUInt16(1),n.table=r.data.concat(n.subtable),n},e}(),g=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return f(e,l),e.prototype.tag="hhea",e.prototype.parse=function(t){return t.pos=this.offset,this.version=t.readInt(),this.ascender=t.readShort(),this.decender=t.readShort(),this.lineGap=t.readShort(),this.advanceWidthMax=t.readShort(),this.minLeftSideBearing=t.readShort(),this.minRightSideBearing=t.readShort(),this.xMaxExtent=t.readShort(),this.caretSlopeRise=t.readShort(),this.caretSlopeRun=t.readShort(),this.caretOffset=t.readShort(),t.pos+=8,this.metricDataFormat=t.readShort(),this.numberOfMetrics=t.readUInt16()},e}(),y=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return f(e,l),e.prototype.tag="OS/2",e.prototype.parse=function(n){if(n.pos=this.offset,this.version=n.readUInt16(),this.averageCharWidth=n.readShort(),this.weightClass=n.readUInt16(),this.widthClass=n.readUInt16(),this.type=n.readShort(),this.ySubscriptXSize=n.readShort(),this.ySubscriptYSize=n.readShort(),this.ySubscriptXOffset=n.readShort(),this.ySubscriptYOffset=n.readShort(),this.ySuperscriptXSize=n.readShort(),this.ySuperscriptYSize=n.readShort(),this.ySuperscriptXOffset=n.readShort(),this.ySuperscriptYOffset=n.readShort(),this.yStrikeoutSize=n.readShort(),this.yStrikeoutPosition=n.readShort(),this.familyClass=n.readShort(),this.panose=function(){var t,e;for(e=[],t=0;t<10;++t)e.push(n.readByte());return e}(),this.charRange=function(){var t,e;for(e=[],t=0;t<4;++t)e.push(n.readInt());return e}(),this.vendorID=n.readString(4),this.selection=n.readShort(),this.firstCharIndex=n.readShort(),this.lastCharIndex=n.readShort(),0<this.version&&(this.ascent=n.readShort(),this.descent=n.readShort(),this.lineGap=n.readShort(),this.winAscent=n.readShort(),this.winDescent=n.readShort(),this.codePageRange=function(){var t,e;for(e=[],t=0;t<2;++t)e.push(n.readInt());return e}(),1<this.version))return this.xHeight=n.readShort(),this.capHeight=n.readShort(),this.defaultChar=n.readShort(),this.breakChar=n.readShort(),this.maxContext=n.readShort()},e}(),w=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return f(e,l),e.prototype.tag="post",e.prototype.parse=function(r){var t,e,n,i;switch(r.pos=this.offset,this.format=r.readInt(),this.italicAngle=r.readInt(),this.underlinePosition=r.readShort(),this.underlineThickness=r.readShort(),this.isFixedPitch=r.readInt(),this.minMemType42=r.readInt(),this.maxMemType42=r.readInt(),this.minMemType1=r.readInt(),this.maxMemType1=r.readInt(),this.format){case 65536:break;case 131072:for(e=r.readUInt16(),this.glyphNameIndex=[],n=0;0<=e?n<e:e<n;0<=e?++n:--n)this.glyphNameIndex.push(r.readUInt16());for(this.names=[],i=[];r.pos<this.offset+this.length;)t=r.readByte(),i.push(this.names.push(r.readString(t)));return i;case 151552:return e=r.readUInt16(),this.offsets=r.read(e);case 196608:break;case 262144:return this.map=function(){var t,e,n;for(n=[],t=0,e=this.file.maxp.numGlyphs;0<=e?t<e:e<t;0<=e?++t:--t)n.push(r.readUInt32());return n}.call(this)}},e}(),v=function(t,e){this.raw=t,this.length=t.length,this.platformID=e.platformID,this.encodingID=e.encodingID,this.languageID=e.languageID},b=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return f(e,l),e.prototype.tag="name",e.prototype.parse=function(t){var e,n,r,i,o,a,s,c,l,h,u,f;for(t.pos=this.offset,t.readShort(),e=t.readShort(),a=t.readShort(),n=[],i=l=0;0<=e?l<e:e<l;i=0<=e?++l:--l)n.push({platformID:t.readShort(),encodingID:t.readShort(),languageID:t.readShort(),nameID:t.readShort(),length:t.readShort(),offset:this.offset+a+t.readShort()});for(s={},i=h=0,u=n.length;h<u;i=++h)r=n[i],t.pos=r.offset,c=t.readString(r.length),o=new v(c,r),null==s[f=r.nameID]&&(s[f]=[]),s[r.nameID].push(o);return this.strings=s,this.copyright=s[0],this.fontFamily=s[1],this.fontSubfamily=s[2],this.uniqueSubfamily=s[3],this.fontName=s[4],this.version=s[5],this.postscriptName=s[6][0].raw.replace(/[\x00-\x19\x80-\xff]/g,""),this.trademark=s[7],this.manufacturer=s[8],this.designer=s[9],this.description=s[10],this.vendorUrl=s[11],this.designerUrl=s[12],this.license=s[13],this.licenseUrl=s[14],this.preferredFamily=s[15],this.preferredSubfamily=s[17],this.compatibleFull=s[18],this.sampleText=s[19]},e}(),x=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return f(e,l),e.prototype.tag="maxp",e.prototype.parse=function(t){return t.pos=this.offset,this.version=t.readInt(),this.numGlyphs=t.readUInt16(),this.maxPoints=t.readUInt16(),this.maxContours=t.readUInt16(),this.maxCompositePoints=t.readUInt16(),this.maxComponentContours=t.readUInt16(),this.maxZones=t.readUInt16(),this.maxTwilightPoints=t.readUInt16(),this.maxStorage=t.readUInt16(),this.maxFunctionDefs=t.readUInt16(),this.maxInstructionDefs=t.readUInt16(),this.maxStackElements=t.readUInt16(),this.maxSizeOfInstructions=t.readUInt16(),this.maxComponentElements=t.readUInt16(),this.maxComponentDepth=t.readUInt16()},e}(),S=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return f(e,l),e.prototype.tag="hmtx",e.prototype.parse=function(n){var t,r,i,e,o,a,s;for(n.pos=this.offset,this.metrics=[],e=0,a=this.file.hhea.numberOfMetrics;0<=a?e<a:a<e;0<=a?++e:--e)this.metrics.push({advance:n.readUInt16(),lsb:n.readInt16()});for(r=this.file.maxp.numGlyphs-this.file.hhea.numberOfMetrics,this.leftSideBearings=function(){var t,e;for(e=[],t=0;0<=r?t<r:r<t;0<=r?++t:--t)e.push(n.readInt16());return e}(),this.widths=function(){var t,e,n,r;for(r=[],t=0,e=(n=this.metrics).length;t<e;t++)i=n[t],r.push(i.advance);return r}.call(this),t=this.widths[this.widths.length-1],s=[],o=0;0<=r?o<r:r<o;0<=r?++o:--o)s.push(this.widths.push(t));return s},e.prototype.forGlyph=function(t){return t in this.metrics?this.metrics[t]:{advance:this.metrics[this.metrics.length-1].advance,lsb:this.leftSideBearings[t-this.metrics.length]}},e}(),k=[].slice,_=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return f(e,l),e.prototype.tag="glyf",e.prototype.parse=function(t){return this.cache={}},e.prototype.glyphFor=function(t){var e,n,r,i,o,a,s,c,l,h;return(t=t)in this.cache?this.cache[t]:(i=this.file.loca,e=this.file.contents,n=i.indexOf(t),0===(r=i.lengthOf(t))?this.cache[t]=null:(e.pos=this.offset+n,o=(a=new X(e.read(r))).readShort(),c=a.readShort(),h=a.readShort(),s=a.readShort(),l=a.readShort(),this.cache[t]=-1===o?new I(a,c,h,s,l):new C(a,o,c,h,s,l),this.cache[t]))},e.prototype.encode=function(t,e,n){var r,i,o,a,s;for(o=[],i=[],a=0,s=e.length;a<s;a++)r=t[e[a]],i.push(o.length),r&&(o=o.concat(r.encode(n)));return i.push(o.length),{table:o,offsets:i}},e}(),C=function(){function t(t,e,n,r,i,o){this.raw=t,this.numberOfContours=e,this.xMin=n,this.yMin=r,this.xMax=i,this.yMax=o,this.compound=!1}return t.prototype.encode=function(){return this.raw.data},t}(),I=function(){function t(t,e,n,r,i){var o,a;for(this.raw=t,this.xMin=e,this.yMin=n,this.xMax=r,this.yMax=i,this.compound=!0,this.glyphIDs=[],this.glyphOffsets=[],o=this.raw;a=o.readShort(),this.glyphOffsets.push(o.pos),this.glyphIDs.push(o.readShort()),32&a;)o.pos+=1&a?4:2,128&a?o.pos+=8:64&a?o.pos+=4:8&a&&(o.pos+=2)}return 1,8,32,64,128,t.prototype.encode=function(t){var e,n,r,i,o;for(n=new X(k.call(this.raw.data)),e=r=0,i=(o=this.glyphIDs).length;r<i;e=++r)o[e],n.pos=this.glyphOffsets[e];return n.data},t}(),A=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return f(e,l),e.prototype.tag="loca",e.prototype.parse=function(r){var t;return r.pos=this.offset,t=this.file.head.indexToLocFormat,this.offsets=0===t?function(){var t,e,n;for(n=[],t=0,e=this.length;t<e;t+=2)n.push(2*r.readUInt16());return n}.call(this):function(){var t,e,n;for(n=[],t=0,e=this.length;t<e;t+=4)n.push(r.readUInt32());return n}.call(this)},e.prototype.indexOf=function(t){return this.offsets[t]},e.prototype.lengthOf=function(t){return this.offsets[t+1]-this.offsets[t]},e.prototype.encode=function(t,e){for(var n=new Uint32Array(this.offsets.length),r=0,i=0,o=0;o<n.length;++o)if(n[o]=r,i<e.length&&e[i]==o){++i,n[o]=r;var a=this.offsets[o],s=this.offsets[o+1]-a;0<s&&(r+=s)}for(var c=new Array(4*n.length),l=0;l<n.length;++l)c[4*l+3]=255&n[l],c[4*l+2]=(65280&n[l])>>8,c[4*l+1]=(16711680&n[l])>>16,c[4*l]=(4278190080&n[l])>>24;return c},e}(),T=function(){function t(t){this.font=t,this.subset={},this.unicodes={},this.next=33}return t.prototype.generateCmap=function(){var t,e,n,r,i;for(e in r=this.font.cmap.tables[0].codeMap,t={},i=this.subset)n=i[e],t[e]=r[n];return t},t.prototype.glyphsFor=function(t){var e,n,r,i,o,a,s;for(r={},o=0,a=t.length;o<a;o++)r[i=t[o]]=this.font.glyf.glyphFor(i);for(i in e=[],r)(null!=(n=r[i])?n.compound:void 0)&&e.push.apply(e,n.glyphIDs);if(0<e.length)for(i in s=this.glyphsFor(e))n=s[i],r[i]=n;return r},t.prototype.encode=function(t){var e,n,r,i,o,a,s,c,l,h,u,f,d,p,g;for(n in e=m.encode(this.generateCmap(),"unicode"),i=this.glyphsFor(t),u={0:0},g=e.charMap)u[(a=g[n]).old]=a.new;for(f in h=e.maxGlyphID,i)f in u||(u[f]=h++);return c=function(t){var e,n;for(e in n={},t)n[t[e]]=e;return n}(u),l=Object.keys(c).sort(function(t,e){return t-e}),d=function(){var t,e,n;for(n=[],t=0,e=l.length;t<e;t++)o=l[t],n.push(c[o]);return n}(),r=this.font.glyf.encode(i,d,u),s=this.font.loca.encode(r.offsets,d),p={cmap:this.font.cmap.raw(),glyf:r.table,loca:s,hmtx:this.font.hmtx.raw(),hhea:this.font.hhea.raw(),maxp:this.font.maxp.raw(),post:this.font.post.raw(),name:this.font.name.raw(),head:this.font.head.raw()},this.font.os2.exists&&(p["OS/2"]=this.font.os2.raw()),this.font.directory.encode(p)},t}();t.API.PDFObject=function(){var o;function a(){}return o=function(t,e){return(Array(e+1).join("0")+t).slice(-e)},a.convert=function(r){var i,t,e,n;if(Array.isArray(r))return"["+function(){var t,e,n;for(n=[],t=0,e=r.length;t<e;t++)i=r[t],n.push(a.convert(i));return n}().join(" ")+"]";if("string"==typeof r)return"/"+r;if(null!=r?r.isString:void 0)return"("+r+")";if(r instanceof Date)return"(D:"+o(r.getUTCFullYear(),4)+o(r.getUTCMonth(),2)+o(r.getUTCDate(),2)+o(r.getUTCHours(),2)+o(r.getUTCMinutes(),2)+o(r.getUTCSeconds(),2)+"Z)";if("[object Object]"==={}.toString.call(r)){for(t in e=["<<"],r)n=r[t],e.push("/"+t+" "+a.convert(n));return e.push(">>"),e.join("\n")}return""+r},a}()}(K),
+/*
+  # PNG.js
+  # Copyright (c) 2011 Devon Govett
+  # MIT LICENSE
+  # 
+  # 
+  */
+ut="undefined"!=typeof self&&self||"undefined"!=typeof window&&window||"undefined"!=typeof global&&global||Function('return typeof this === "object" && this.content')()||Function("return this")(),ft=function(){var l,n,r;function i(t){var e,n,r,i,o,a,s,c,l,h,u,f,d,p;for(this.data=t,this.pos=8,this.palette=[],this.imgData=[],this.transparency={},this.animation=null,this.text={},a=null;;){switch(e=this.readUInt32(),l=function(){var t,e;for(e=[],t=0;t<4;++t)e.push(String.fromCharCode(this.data[this.pos++]));return e}.call(this).join("")){case"IHDR":this.width=this.readUInt32(),this.height=this.readUInt32(),this.bits=this.data[this.pos++],this.colorType=this.data[this.pos++],this.compressionMethod=this.data[this.pos++],this.filterMethod=this.data[this.pos++],this.interlaceMethod=this.data[this.pos++];break;case"acTL":this.animation={numFrames:this.readUInt32(),numPlays:this.readUInt32()||1/0,frames:[]};break;case"PLTE":this.palette=this.read(e);break;case"fcTL":a&&this.animation.frames.push(a),this.pos+=4,a={width:this.readUInt32(),height:this.readUInt32(),xOffset:this.readUInt32(),yOffset:this.readUInt32()},o=this.readUInt16(),i=this.readUInt16()||100,a.delay=1e3*o/i,a.disposeOp=this.data[this.pos++],a.blendOp=this.data[this.pos++],a.data=[];break;case"IDAT":case"fdAT":for("fdAT"===l&&(this.pos+=4,e-=4),t=(null!=a?a.data:void 0)||this.imgData,f=0;0<=e?f<e:e<f;0<=e?++f:--f)t.push(this.data[this.pos++]);break;case"tRNS":switch(this.transparency={},this.colorType){case 3:if(r=this.palette.length/3,this.transparency.indexed=this.read(e),this.transparency.indexed.length>r)throw new Error("More transparent colors than palette size");if(0<(h=r-this.transparency.indexed.length))for(d=0;0<=h?d<h:h<d;0<=h?++d:--d)this.transparency.indexed.push(255);break;case 0:this.transparency.grayscale=this.read(e)[0];break;case 2:this.transparency.rgb=this.read(e)}break;case"tEXt":s=(u=this.read(e)).indexOf(0),c=String.fromCharCode.apply(String,u.slice(0,s)),this.text[c]=String.fromCharCode.apply(String,u.slice(s+1));break;case"IEND":return a&&this.animation.frames.push(a),this.colors=function(){switch(this.colorType){case 0:case 3:case 4:return 1;case 2:case 6:return 3}}.call(this),this.hasAlphaChannel=4===(p=this.colorType)||6===p,n=this.colors+(this.hasAlphaChannel?1:0),this.pixelBitlength=this.bits*n,this.colorSpace=function(){switch(this.colors){case 1:return"DeviceGray";case 3:return"DeviceRGB"}}.call(this),void(this.imgData=new Uint8Array(this.imgData));default:this.pos+=e}if(this.pos+=4,this.pos>this.data.length)throw new Error("Incomplete or corrupt PNG file")}}i.load=function(t,e,n){var r;return"function"==typeof e&&(n=e),(r=new XMLHttpRequest).open("GET",t,!0),r.responseType="arraybuffer",r.onload=function(){var t;return t=new i(new Uint8Array(r.response||r.mozResponseArrayBuffer)),"function"==typeof(null!=e?e.getContext:void 0)&&t.render(e),"function"==typeof n?n(t):void 0},r.send(null)},i.prototype.read=function(t){var e,n;for(n=[],e=0;0<=t?e<t:t<e;0<=t?++e:--e)n.push(this.data[this.pos++]);return n},i.prototype.readUInt32=function(){return this.data[this.pos++]<<24|this.data[this.pos++]<<16|this.data[this.pos++]<<8|this.data[this.pos++]},i.prototype.readUInt16=function(){return this.data[this.pos++]<<8|this.data[this.pos++]},i.prototype.decodePixels=function(E){var P=this.pixelBitlength/8,O=new Uint8Array(this.width*this.height*P),B=0,j=this;if(null==E&&(E=this.imgData),0===E.length)return new Uint8Array(0);function t(t,e,n,r){var i,o,a,s,c,l,h,u,f,d,p,g,m,y,w,v,b,x,S,k,_,C=Math.ceil((j.width-t)/n),I=Math.ceil((j.height-e)/r),A=j.width==C&&j.height==I;for(y=P*C,g=A?O:new Uint8Array(y*I),l=E.length,o=m=0;m<I&&B<l;){switch(E[B++]){case 0:for(s=b=0;b<y;s=b+=1)g[o++]=E[B++];break;case 1:for(s=x=0;x<y;s=x+=1)i=E[B++],c=s<P?0:g[o-P],g[o++]=(i+c)%256;break;case 2:for(s=S=0;S<y;s=S+=1)i=E[B++],a=(s-s%P)/P,w=m&&g[(m-1)*y+a*P+s%P],g[o++]=(w+i)%256;break;case 3:for(s=k=0;k<y;s=k+=1)i=E[B++],a=(s-s%P)/P,c=s<P?0:g[o-P],w=m&&g[(m-1)*y+a*P+s%P],g[o++]=(i+Math.floor((c+w)/2))%256;break;case 4:for(s=_=0;_<y;s=_+=1)i=E[B++],a=(s-s%P)/P,c=s<P?0:g[o-P],0===m?w=v=0:(w=g[(m-1)*y+a*P+s%P],v=a&&g[(m-1)*y+(a-1)*P+s%P]),h=c+w-v,u=Math.abs(h-c),d=Math.abs(h-w),p=Math.abs(h-v),f=u<=d&&u<=p?c:d<=p?w:v,g[o++]=(i+f)%256;break;default:throw new Error("Invalid filter algorithm: "+E[B-1])}if(!A){var T=((e+m*r)*j.width+t)*P,F=m*y;for(s=0;s<C;s+=1){for(var q=0;q<P;q+=1)O[T++]=g[F++];T+=(n-1)*P}}m++}}return E=(E=new gt(E)).getBytes(),1==j.interlaceMethod?(t(0,0,8,8),t(4,0,8,8),t(0,4,4,8),t(2,0,4,4),t(0,2,2,4),t(1,0,2,2),t(0,1,1,2)):t(0,0,1,1),O},i.prototype.decodePalette=function(){var t,e,n,r,i,o,a,s,c;for(n=this.palette,o=this.transparency.indexed||[],i=new Uint8Array((o.length||0)+n.length),r=0,n.length,e=a=t=0,s=n.length;a<s;e=a+=3)i[r++]=n[e],i[r++]=n[e+1],i[r++]=n[e+2],i[r++]=null!=(c=o[t++])?c:255;return i},i.prototype.copyToImageData=function(t,e){var n,r,i,o,a,s,c,l,h,u,f;if(r=this.colors,h=null,n=this.hasAlphaChannel,this.palette.length&&(h=null!=(f=this._decodedPalette)?f:this._decodedPalette=this.decodePalette(),r=4,n=!0),l=(i=t.data||t).length,a=h||e,o=s=0,1===r)for(;o<l;)c=h?4*e[o/4]:s,u=a[c++],i[o++]=u,i[o++]=u,i[o++]=u,i[o++]=n?a[c++]:255,s=c;else for(;o<l;)c=h?4*e[o/4]:s,i[o++]=a[c++],i[o++]=a[c++],i[o++]=a[c++],i[o++]=n?a[c++]:255,s=c},i.prototype.decode=function(){var t;return t=new Uint8Array(this.width*this.height*4),this.copyToImageData(t,this.decodePixels()),t};try{n=ut.document.createElement("canvas"),r=n.getContext("2d")}catch(t){return-1}return l=function(t){var e;return r.width=t.width,r.height=t.height,r.clearRect(0,0,t.width,t.height),r.putImageData(t,0,0),(e=new Image).src=n.toDataURL(),e},i.prototype.decodeFrames=function(t){var e,n,r,i,o,a,s,c;if(this.animation){for(c=[],n=o=0,a=(s=this.animation.frames).length;o<a;n=++o)e=s[n],r=t.createImageData(e.width,e.height),i=this.decodePixels(new Uint8Array(e.data)),this.copyToImageData(r,i),e.imageData=r,c.push(e.image=l(r));return c}},i.prototype.renderFrame=function(t,e){var n,r,i;return n=(r=this.animation.frames)[e],i=r[e-1],0===e&&t.clearRect(0,0,this.width,this.height),1===(null!=i?i.disposeOp:void 0)?t.clearRect(i.xOffset,i.yOffset,i.width,i.height):2===(null!=i?i.disposeOp:void 0)&&t.putImageData(i.imageData,i.xOffset,i.yOffset),0===n.blendOp&&t.clearRect(n.xOffset,n.yOffset,n.width,n.height),t.drawImage(n.image,n.xOffset,n.yOffset)},i.prototype.animate=function(n){var r,i,o,a,s,t,c=this;return i=0,t=this.animation,a=t.numFrames,o=t.frames,s=t.numPlays,(r=function(){var t,e;if(t=i++%a,e=o[t],c.renderFrame(n,t),1<a&&i/a<s)return c.animation._timeout=setTimeout(r,e.delay)})()},i.prototype.stopAnimation=function(){var t;return clearTimeout(null!=(t=this.animation)?t._timeout:void 0)},i.prototype.render=function(t){var e,n;return t._png&&t._png.stopAnimation(),t._png=this,t.width=this.width,t.height=this.height,e=t.getContext("2d"),this.animation?(this.decodeFrames(e),this.animate(e)):(n=e.createImageData(this.width,this.height),this.copyToImageData(n,this.decodePixels()),e.putImageData(n,0,0))},i}(),ut.PNG=ft;
+/*
+   * Extracted from pdf.js
+   * https://github.com/andreasgal/pdf.js
+   *
+   * Copyright (c) 2011 Mozilla Foundation
+   *
+   * Contributors: Andreas Gal <gal@mozilla.com>
+   *               Chris G Jones <cjones@mozilla.com>
+   *               Shaon Barman <shaon.barman@gmail.com>
+   *               Vivien Nicolas <21@vingtetun.org>
+   *               Justin D'Arcangelo <justindarc@gmail.com>
+   *               Yury Delendik
+   *
+   * 
+   */
+var pt=function(){function t(){this.pos=0,this.bufferLength=0,this.eof=!1,this.buffer=null}return t.prototype={ensureBuffer:function(t){var e=this.buffer,n=e?e.byteLength:0;if(t<n)return e;for(var r=512;r<t;)r<<=1;for(var i=new Uint8Array(r),o=0;o<n;++o)i[o]=e[o];return this.buffer=i},getByte:function(){for(var t=this.pos;this.bufferLength<=t;){if(this.eof)return null;this.readBlock()}return this.buffer[this.pos++]},getBytes:function(t){var e=this.pos;if(t){this.ensureBuffer(e+t);for(var n=e+t;!this.eof&&this.bufferLength<n;)this.readBlock();var r=this.bufferLength;r<n&&(n=r)}else{for(;!this.eof;)this.readBlock();n=this.bufferLength}return this.pos=n,this.buffer.subarray(e,n)},lookChar:function(){for(var t=this.pos;this.bufferLength<=t;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos])},getChar:function(){for(var t=this.pos;this.bufferLength<=t;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos++])},makeSubStream:function(t,e,n){for(var r=t+e;this.bufferLength<=r&&!this.eof;)this.readBlock();return new Stream(this.buffer,t,e,n)},skip:function(t){t||(t=1),this.pos+=t},reset:function(){this.pos=0}},t}(),gt=function(){if("undefined"!=typeof Uint32Array){var F=new Uint32Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),q=new Uint32Array([3,4,5,6,7,8,9,10,65547,65549,65551,65553,131091,131095,131099,131103,196643,196651,196659,196667,262211,262227,262243,262259,327811,327843,327875,327907,258,258,258]),E=new Uint32Array([1,2,3,4,65541,65543,131081,131085,196625,196633,262177,262193,327745,327777,393345,393409,459009,459137,524801,525057,590849,591361,657409,658433,724993,727041,794625,798721,868353,876545]),P=[new Uint32Array([459008,524368,524304,524568,459024,524400,524336,590016,459016,524384,524320,589984,524288,524416,524352,590048,459012,524376,524312,589968,459028,524408,524344,590032,459020,524392,524328,59e4,524296,524424,524360,590064,459010,524372,524308,524572,459026,524404,524340,590024,459018,524388,524324,589992,524292,524420,524356,590056,459014,524380,524316,589976,459030,524412,524348,590040,459022,524396,524332,590008,524300,524428,524364,590072,459009,524370,524306,524570,459025,524402,524338,590020,459017,524386,524322,589988,524290,524418,524354,590052,459013,524378,524314,589972,459029,524410,524346,590036,459021,524394,524330,590004,524298,524426,524362,590068,459011,524374,524310,524574,459027,524406,524342,590028,459019,524390,524326,589996,524294,524422,524358,590060,459015,524382,524318,589980,459031,524414,524350,590044,459023,524398,524334,590012,524302,524430,524366,590076,459008,524369,524305,524569,459024,524401,524337,590018,459016,524385,524321,589986,524289,524417,524353,590050,459012,524377,524313,589970,459028,524409,524345,590034,459020,524393,524329,590002,524297,524425,524361,590066,459010,524373,524309,524573,459026,524405,524341,590026,459018,524389,524325,589994,524293,524421,524357,590058,459014,524381,524317,589978,459030,524413,524349,590042,459022,524397,524333,590010,524301,524429,524365,590074,459009,524371,524307,524571,459025,524403,524339,590022,459017,524387,524323,589990,524291,524419,524355,590054,459013,524379,524315,589974,459029,524411,524347,590038,459021,524395,524331,590006,524299,524427,524363,590070,459011,524375,524311,524575,459027,524407,524343,590030,459019,524391,524327,589998,524295,524423,524359,590062,459015,524383,524319,589982,459031,524415,524351,590046,459023,524399,524335,590014,524303,524431,524367,590078,459008,524368,524304,524568,459024,524400,524336,590017,459016,524384,524320,589985,524288,524416,524352,590049,459012,524376,524312,589969,459028,524408,524344,590033,459020,524392,524328,590001,524296,524424,524360,590065,459010,524372,524308,524572,459026,524404,524340,590025,459018,524388,524324,589993,524292,524420,524356,590057,459014,524380,524316,589977,459030,524412,524348,590041,459022,524396,524332,590009,524300,524428,524364,590073,459009,524370,524306,524570,459025,524402,524338,590021,459017,524386,524322,589989,524290,524418,524354,590053,459013,524378,524314,589973,459029,524410,524346,590037,459021,524394,524330,590005,524298,524426,524362,590069,459011,524374,524310,524574,459027,524406,524342,590029,459019,524390,524326,589997,524294,524422,524358,590061,459015,524382,524318,589981,459031,524414,524350,590045,459023,524398,524334,590013,524302,524430,524366,590077,459008,524369,524305,524569,459024,524401,524337,590019,459016,524385,524321,589987,524289,524417,524353,590051,459012,524377,524313,589971,459028,524409,524345,590035,459020,524393,524329,590003,524297,524425,524361,590067,459010,524373,524309,524573,459026,524405,524341,590027,459018,524389,524325,589995,524293,524421,524357,590059,459014,524381,524317,589979,459030,524413,524349,590043,459022,524397,524333,590011,524301,524429,524365,590075,459009,524371,524307,524571,459025,524403,524339,590023,459017,524387,524323,589991,524291,524419,524355,590055,459013,524379,524315,589975,459029,524411,524347,590039,459021,524395,524331,590007,524299,524427,524363,590071,459011,524375,524311,524575,459027,524407,524343,590031,459019,524391,524327,589999,524295,524423,524359,590063,459015,524383,524319,589983,459031,524415,524351,590047,459023,524399,524335,590015,524303,524431,524367,590079]),9],O=[new Uint32Array([327680,327696,327688,327704,327684,327700,327692,327708,327682,327698,327690,327706,327686,327702,327694,0,327681,327697,327689,327705,327685,327701,327693,327709,327683,327699,327691,327707,327687,327703,327695,0]),5];return(t.prototype=Object.create(pt.prototype)).getBits=function(t){for(var e,n=this.codeSize,r=this.codeBuf,i=this.bytes,o=this.bytesPos;n<t;)void 0===(e=i[o++])&&B("Bad encoding in flate stream"),r|=e<<n,n+=8;return e=r&(1<<t)-1,this.codeBuf=r>>t,this.codeSize=n-=t,this.bytesPos=o,e},t.prototype.getCode=function(t){for(var e=t[0],n=t[1],r=this.codeSize,i=this.codeBuf,o=this.bytes,a=this.bytesPos;r<n;){var s;void 0===(s=o[a++])&&B("Bad encoding in flate stream"),i|=s<<r,r+=8}var c=e[i&(1<<n)-1],l=c>>16,h=65535&c;return(0==r||r<l||0==l)&&B("Bad encoding in flate stream"),this.codeBuf=i>>l,this.codeSize=r-l,this.bytesPos=a,h},t.prototype.generateHuffmanTable=function(t){for(var e=t.length,n=0,r=0;r<e;++r)t[r]>n&&(n=t[r]);for(var i=1<<n,o=new Uint32Array(i),a=1,s=0,c=2;a<=n;++a,s<<=1,c<<=1)for(var l=0;l<e;++l)if(t[l]==a){var h=0,u=s;for(r=0;r<a;++r)h=h<<1|1&u,u>>=1;for(r=h;r<i;r+=c)o[r]=a<<16|l;++s}return[o,n]},t.prototype.readBlock=function(){function t(t,e,n,r,i){for(var o=t.getBits(n)+r;0<o--;)e[c++]=i}var e=this.getBits(3);if(1&e&&(this.eof=!0),0!=(e>>=1)){var n,r;if(1==e)n=P,r=O;else if(2==e){for(var i=this.getBits(5)+257,o=this.getBits(5)+1,a=this.getBits(4)+4,s=Array(F.length),c=0;c<a;)s[F[c++]]=this.getBits(3);for(var l=this.generateHuffmanTable(s),h=0,u=(c=0,i+o),f=new Array(u);c<u;){var d=this.getCode(l);16==d?t(this,f,2,3,h):17==d?t(this,f,3,3,h=0):18==d?t(this,f,7,11,h=0):f[c++]=h=d}n=this.generateHuffmanTable(f.slice(0,i)),r=this.generateHuffmanTable(f.slice(i,u))}else B("Unknown block type in flate stream");for(var p=(I=this.buffer)?I.length:0,g=this.bufferLength;;){var m=this.getCode(n);if(m<256)p<=g+1&&(p=(I=this.ensureBuffer(g+1)).length),I[g++]=m;else{if(256==m)return void(this.bufferLength=g);var y=(m=q[m-=257])>>16;0<y&&(y=this.getBits(y));h=(65535&m)+y;m=this.getCode(r),0<(y=(m=E[m])>>16)&&(y=this.getBits(y));var w=(65535&m)+y;p<=g+h&&(p=(I=this.ensureBuffer(g+h)).length);for(var v=0;v<h;++v,++g)I[g]=I[g-w]}}}else{var b,x=this.bytes,S=this.bytesPos;void 0===(b=x[S++])&&B("Bad block header in flate stream");var k=b;void 0===(b=x[S++])&&B("Bad block header in flate stream"),k|=b<<8,void 0===(b=x[S++])&&B("Bad block header in flate stream");var _=b;void 0===(b=x[S++])&&B("Bad block header in flate stream"),(_|=b<<8)!=(65535&~k)&&B("Bad uncompressed block length in flate stream"),this.codeBuf=0,this.codeSize=0;var C=this.bufferLength,I=this.ensureBuffer(C+k),A=C+k;this.bufferLength=A;for(var T=C;T<A;++T){if(void 0===(b=x[S++])){this.eof=!0;break}I[T]=b}this.bytesPos=S}},t}function B(t){throw new Error(t)}function t(t){var e=0,n=t[e++],r=t[e++];-1!=n&&-1!=r||B("Invalid header in flate stream"),8!=(15&n)&&B("Unknown compression method in flate stream"),((n<<8)+r)%31!=0&&B("Bad FCHECK in flate stream"),32&r&&B("FDICT bit set in flate stream"),this.bytes=t,this.bytesPos=2,this.codeSize=0,this.codeBuf=0,pt.call(this)}}();return function(t){if("object"!=typeof t.console){t.console={};for(var e,n,r=t.console,i=function(){},o=["memory"],a="assert,clear,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn".split(",");e=o.pop();)r[e]||(r[e]={});for(;n=a.pop();)r[n]||(r[n]=i)}var s,c,l,h,u="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";void 0===t.btoa&&(t.btoa=function(t){var e,n,r,i,o,a=0,s=0,c="",l=[];if(!t)return t;for(;e=(o=t.charCodeAt(a++)<<16|t.charCodeAt(a++)<<8|t.charCodeAt(a++))>>18&63,n=o>>12&63,r=o>>6&63,i=63&o,l[s++]=u.charAt(e)+u.charAt(n)+u.charAt(r)+u.charAt(i),a<t.length;);c=l.join("");var h=t.length%3;return(h?c.slice(0,h-3):c)+"===".slice(h||3)}),void 0===t.atob&&(t.atob=function(t){var e,n,r,i,o,a,s=0,c=0,l=[];if(!t)return t;for(t+="";e=(a=u.indexOf(t.charAt(s++))<<18|u.indexOf(t.charAt(s++))<<12|(i=u.indexOf(t.charAt(s++)))<<6|(o=u.indexOf(t.charAt(s++))))>>16&255,n=a>>8&255,r=255&a,l[c++]=64==i?String.fromCharCode(e):64==o?String.fromCharCode(e,n):String.fromCharCode(e,n,r),s<t.length;);return l.join("")}),Array.prototype.map||(Array.prototype.map=function(t){if(null==this||"function"!=typeof t)throw new TypeError;for(var e=Object(this),n=e.length>>>0,r=new Array(n),i=1<arguments.length?arguments[1]:void 0,o=0;o<n;o++)o in e&&(r[o]=t.call(i,e[o],o,e));return r}),Array.isArray||(Array.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)}),Array.prototype.forEach||(Array.prototype.forEach=function(t,e){if(null==this||"function"!=typeof t)throw new TypeError;for(var n=Object(this),r=n.length>>>0,i=0;i<r;i++)i in n&&t.call(e,n[i],i,n)}),Object.keys||(Object.keys=(s=Object.prototype.hasOwnProperty,c=!{toString:null}.propertyIsEnumerable("toString"),h=(l=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"]).length,function(t){if("object"!=typeof t&&("function"!=typeof t||null===t))throw new TypeError;var e,n,r=[];for(e in t)s.call(t,e)&&r.push(e);if(c)for(n=0;n<h;n++)s.call(t,l[n])&&r.push(l[n]);return r})),"function"!=typeof Object.assign&&(Object.assign=function(t){if(null==t)throw new TypeError("Cannot convert undefined or null to object");t=Object(t);for(var e=1;e<arguments.length;e++){var n=arguments[e];if(null!=n)for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t}),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),String.prototype.trimLeft||(String.prototype.trimLeft=function(){return this.replace(/^\s+/g,"")}),String.prototype.trimRight||(String.prototype.trimRight=function(){return this.replace(/\s+$/g,"")})}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||"undefined"!=typeof global&&global||Function('return typeof this === "object" && this.content')()||Function("return this")()),K});
\ No newline at end of file
diff --git a/AstuteClient2/src/assets/jspdf/package.json b/AstuteClient2/src/assets/jspdf/package.json
new file mode 100644
index 0000000..870d67c
--- /dev/null
+++ b/AstuteClient2/src/assets/jspdf/package.json
@@ -0,0 +1,86 @@
+{
+  "_from": "jspdf@^1.3.5",
+  "_id": "jspdf@1.4.0",
+  "_inBundle": false,
+  "_integrity": "sha512-VyKgRaRdifZnN9lAq9Sp0RiP6PZpmxDbWi6F0cUr0BEkzH5S1Kuss5XCmiSn+l/rcDUOJd9zfac/3vlIIv0igg==",
+  "_location": "/jspdf",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "jspdf@^1.3.5",
+    "name": "jspdf",
+    "escapedName": "jspdf",
+    "rawSpec": "^1.3.5",
+    "saveSpec": null,
+    "fetchSpec": "^1.3.5"
+  },
+  "_requiredBy": [
+    "/html2pdf.js"
+  ],
+  "_resolved": "https://registry.npmjs.org/jspdf/-/jspdf-1.4.0.tgz",
+  "_shasum": "14b5428c2ddb3f237780a2857d5d161f8a5a9cc7",
+  "_spec": "jspdf@^1.3.5",
+  "_where": "D:\\Documents\\Astute\\AstuteClient\\node_modules\\html2pdf.js",
+  "bugs": {
+    "url": "https://github.com/MrRio/jsPDF/issues"
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "cf-blob.js": "0.0.1",
+    "file-saver": "1.3.8"
+  },
+  "deprecated": false,
+  "description": "PDF Document creation from JavaScript",
+  "devDependencies": {
+    "babel-core": "6.26.0",
+    "babel-preset-es2015": "6.24.1",
+    "babel-preset-es2015-rollup": "3.0.0",
+    "codeclimate-test-reporter": "^0.5.0",
+    "diff": "3.5.0",
+    "docdash": "0.4.0",
+    "jasmine-core": "2.99.1",
+    "js-yaml": "3.11.0",
+    "jsdoc": "3.5.5",
+    "karma": "2.0.2",
+    "karma-babel-preprocessor": "7.0.0",
+    "karma-chrome-launcher": "2.2.0",
+    "karma-coverage": "1.1.2",
+    "karma-firefox-launcher": "1.1.0",
+    "karma-ie-launcher": "1.0.0",
+    "karma-jasmine": "1.1.1",
+    "karma-mocha-reporter": "2.2.5",
+    "karma-sauce-launcher": "1.2.0",
+    "karma-verbose-reporter": "0.0.6",
+    "local-web-server": "2.5.2",
+    "markdown": "0.5.0",
+    "rollup": "0.59.1",
+    "rollup-plugin-babel": "3.0.4",
+    "uglify-js": "3.3.25"
+  },
+  "files": [
+    "dist/jspdf.debug.js",
+    "dist/jspdf.min.js",
+    "README.md"
+  ],
+  "homepage": "https://github.com/mrrio/jspdf",
+  "keywords": [
+    "pdf"
+  ],
+  "license": "MIT",
+  "main": "dist/jspdf.min.js",
+  "name": "jspdf",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/MrRio/jsPDF.git"
+  },
+  "scripts": {
+    "build": "npm install && node build.js",
+    "generate-docs": "jsdoc -c jsdoc.json --readme README.md",
+    "start": "ws",
+    "test": "karma start saucelabs.karma.conf.js --single-run --verbose && for a in coverage/*; do codeclimate-test-reporter < \"$a/lcov.info\"; break; done",
+    "test-local": "node tests/utils/reference-server.js & karma start",
+    "version": "npm run build && git add -A dist"
+  },
+  "version": "1.4.0"
+}