PageSourceSearch

https://energieeffizienzprofi.de/wp-content/plugins/foerderungskal…/dist/jspdf.umd.js?ver=2.5.1.1791237937

js energieeffizienzprofi.de collected 2026-10-06 02:05:03 UTC 941,792 bytes, 28,833 lines download raw bytes

1/** @license
2 *
3 * jsPDF - PDF Document creation from JavaScript
4 * Version 2.5.1 Built on 2022-01-28T15:37:57.789Z
5 *                      CommitID 00000000
6 *
7 * Copyright (c) 2010-2021 James Hall <[email protected]>, https://github.com/MrRio/jsPDF
8 *               2015-2021 yWorks GmbH, http://www.yworks.com
9 *               2015-2021 Lukas Holländer <[email protected]>, https://github.com/HackbrettXXX
10 *               2016-2018 Aras Abbasi <[email protected]>
11 *               2010 Aaron Spike, https://github.com/acspike
12 *               2012 Willow Systems Corporation, https://github.com/willowsystems
13 *               2012 Pablo Hess, https://github.com/pablohess
14 *               2012 Florian Jenett, https://github.com/fjenett
15 *               2013 Warren Weckesser, https://github.com/warrenweckesser
16 *               2013 Youssef Beddad, https://github.com/lifof
17 *               2013 Lee Driscoll, https://github.com/lsdriscoll
18 *               2013 Stefan Slonevskiy, https://github.com/stefslon
19 *               2013 Jeremy Morel, https://github.com/jmorel
20 *               2013 Christoph Hartmann, https://github.com/chris-rock
21 *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
22 *               2014 James Makes, https://github.com/dollaruw
23 *               2014 Diego Casorran, https://github.com/diegocr
24 *               2014 Steven Spungin, https://github.com/Flamenco
25 *               2014 Kenneth Glassey, https://github.com/Gavvers
26 *
27 * Permission is hereby granted, free of charge, to any person obtaining
28 * a copy of this software and associated documentation files (the
29 * "Software"), to deal in the Software without restriction, including
30 * without limitation the rights to use, copy, modify, merge, publish,
31 * distribute, sublicense, and/or sell copies of the Software, and to
32 * permit persons to whom the Software is furnished to do so, subject to
33 * the following conditions:
34 *
35 * The above copyright notice and this permission notice shall be
36 * included in all copies or substantial portions of the Software.
37 *
38 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
39 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
40 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
41 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
42 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
43 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
44 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
45 *
46 * Contributor(s):
47 *    siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango,
48 *    kim3er, mfo, alnorth, Flamenco
49 */
50
51(function (global, factory) {
52  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
53  typeof define === 'function' && define.amd ? define(['exports'], factory) :
54  (global = global || self, factory(global.jspdf = {}));
55}(this, (function (exports) { 'use strict';
56
57  function _typeof(obj) {
58    "@babel/helpers - typeof";
59
60    if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
61      _typeof = function (obj) {
62        return typeof obj;
63      };
64    } else {
65      _typeof = function (obj) {
66        return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
67      };
68    }
69
70    return _typeof(obj);
71  }
72
73  var globalObject = function () {
74    return "undefined" !== typeof window ? window : "undefined" !== typeof global ? global : "undefined" !== typeof self ? self : this;
75  }();
76
77  function consoleLog() {
78    if (globalObject.console && typeof globalObject.console.log === "function") {
79      globalObject.console.log.apply(globalObject.console, arguments);
80    }
81  }
82
83  function consoleWarn(str) {
84    if (globalObject.console) {
85      if (typeof globalObject.console.warn === "function") {
86        globalObject.console.warn.apply(globalObject.console, arguments);
87      } else {
88        consoleLog.call(null, arguments);
89      }
90    }
91  }
92
93  function consoleError(str) {
94    if (globalObject.console) {
95      if (typeof globalObject.console.error === "function") {
96        globalObject.console.error.apply(globalObject.console, arguments);
97      } else {
98        consoleLog(str);
99      }
100    }
101  }
102
103  var console = {
104    log: consoleLog,
105    warn: consoleWarn,
106    error: consoleError
107  };
108
109  function bom(blob, opts) {
110    if (typeof opts === "undefined") opts = {
111      autoBom: false
112    };else if (_typeof(opts) !== "object") {
113      console.warn("Deprecated: Expected third argument to be a object");
114      opts = {
115        autoBom: !opts
116      };
117    } // prepend BOM for UTF-8 XML and text/* types (including HTML)
118    // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
119
120    if (opts.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
121      return new Blob([String.fromCharCode(0xfeff), blob], {
122        type: blob.type
123      });
124    }
125
126    return blob;
127  }
128
129  function download(url, name, opts) {
130    var xhr = new XMLHttpRequest();
131    xhr.open("GET", url);
132    xhr.responseType = "blob";
133
134    xhr.onload = function () {
135      saveAs(xhr.response, name, opts);
136    };
137
138    xhr.onerror = function () {
139      console.error("could not download file");
140    };
141
142    xhr.send();
143  }
144
145  function corsEnabled(url) {
146    var xhr = new XMLHttpRequest(); // use sync to avoid popup blocker
147
148    xhr.open("HEAD", url, false);
149
150    try {
151      xhr.send();
152    } catch (e) {}
153
154    return xhr.status >= 200 && xhr.status <= 299;
155  } // `a.click()` doesn't work for all browsers (#465)
156
157
158  function click(node) {
159    try {
160      node.dispatchEvent(new MouseEvent("click"));
161    } catch (e) {
162      var evt = document.createEvent("MouseEvents");
163      evt.initMouseEvent("click", true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
164      node.dispatchEvent(evt);
165    }
166  }
167
168  var saveAs = globalObject.saveAs || ( // probably in some web worker
169  (typeof window === "undefined" ? "undefined" : _typeof(window)) !== "object" || window !== globalObject ? function saveAs() {
170    /* noop */
171  } : // Use download attribute first if possible (#193 Lumia mobile) unless this is a native app
172  typeof HTMLAnchorElement !== "undefined" && "download" in HTMLAnchorElement.prototype ? function saveAs(blob, name, opts) {
173    var URL = globalObject.URL || globalObject.webkitURL;
174    var a = document.createElement("a");
175    name = name || blob.name || "download";
vendor: 113,971 bytes, lines 176-3826
176    a.download = name;
177    a.rel = "noopener"; // tabnabbing
178    // TODO: detect chrome extensions & packaged apps
179    // a.target = '_blank'
180
181    if (typeof blob === "string") {
182      // Support regular links
183      a.href = blob;
184
185      if (a.origin !== location.origin) {
186        corsEnabled(a.href) ? download(blob, name, opts) : click(a, a.target = "_blank");
187      } else {
188        click(a);
189      }
190    } else {
191      // Support blobs
192      a.href = URL.createObjectURL(blob);
193      setTimeout(function () {
194        URL.revokeObjectURL(a.href);
195      }, 4e4); // 40s
196
197      setTimeout(function () {
198        click(a);
199      }, 0);
200    }
201  } : // Use msSaveOrOpenBlob as a second approach
202  "msSaveOrOpenBlob" in navigator ? function saveAs(blob, name, opts) {
203    name = name || blob.name || "download";
204
205    if (typeof blob === "string") {
206      if (corsEnabled(blob)) {
207        download(blob, name, opts);
208      } else {
209        var a = document.createElement("a");
210        a.href = blob;
211        a.target = "_blank";
212        setTimeout(function () {
213          click(a);
214        });
215      }
216    } else {
217      navigator.msSaveOrOpenBlob(bom(blob, opts), name);
218    }
219  } : // Fallback to using FileReader and a popup
220  function saveAs(blob, name, opts, popup) {
221    // Open a popup immediately do go around popup blocker
222    // Mostly only available on user interaction and the fileReader is async so...
223    popup = popup || open("", "_blank");
224
225    if (popup) {
226      popup.document.title = popup.document.body.innerText = "downloading...";
227    }
228
229    if (typeof blob === "string") return download(blob, name, opts);
230    var force = blob.type === "application/octet-stream";
231
232    var isSafari = /constructor/i.test(globalObject.HTMLElement) || globalObject.safari;
233
234    var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);
235
236    if ((isChromeIOS || force && isSafari) && (typeof FileReader === "undefined" ? "undefined" : _typeof(FileReader)) === "object") {
237      // Safari doesn't allow downloading of blob URLs
238      var reader = new FileReader();
239
240      reader.onloadend = function () {
241        var url = reader.result;
242        url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, "data:attachment/file;");
243        if (popup) popup.location.href = url;else location = url;
244        popup = null; // reverse-tabnabbing #460
245      };
246
247      reader.readAsDataURL(blob);
248    } else {
249      var URL = globalObject.URL || globalObject.webkitURL;
250      var url = URL.createObjectURL(blob);
251      if (popup) popup.location = url;else location.href = url;
252      popup = null; // reverse-tabnabbing #460
253
254      setTimeout(function () {
255        URL.revokeObjectURL(url);
256      }, 4e4); // 40s
257    }
258  });
259
260  /**
261   * A class to parse color values
262   * @author Stoyan Stefanov <[email protected]>
263   * {@link   http://www.phpied.com/rgb-color-parser-in-javascript/}
264   * @license Use it if you like it
265   */
266  function RGBColor(color_string) {
267    color_string = color_string || "";
268    this.ok = false; // strip any leading #
269
270    if (color_string.charAt(0) == "#") {
271      // remove # if any
272      color_string = color_string.substr(1, 6);
273    }
274
275    color_string = color_string.replace(/ /g, "");
276    color_string = color_string.toLowerCase();
277    var channels; // before getting into regexps, try simple matches
278    // and overwrite the input
279
280    var simple_colors = {
281      aliceblue: "f0f8ff",
282      antiquewhite: "faebd7",
283      aqua: "00ffff",
284      aquamarine: "7fffd4",
285      azure: "f0ffff",
286      beige: "f5f5dc",
287      bisque: "ffe4c4",
288      black: "000000",
289      blanchedalmond: "ffebcd",
290      blue: "0000ff",
291      blueviolet: "8a2be2",
292      brown: "a52a2a",
293      burlywood: "deb887",
294      cadetblue: "5f9ea0",
295      chartreuse: "7fff00",
296      chocolate: "d2691e",
297      coral: "ff7f50",
298      cornflowerblue: "6495ed",
299      cornsilk: "fff8dc",
300      crimson: "dc143c",
301      cyan: "00ffff",
302      darkblue: "00008b",
303      darkcyan: "008b8b",
304      darkgoldenrod: "b8860b",
305      darkgray: "a9a9a9",
306      darkgreen: "006400",
307      darkkhaki: "bdb76b",
308      darkmagenta: "8b008b",
309      darkolivegreen: "556b2f",
310      darkorange: "ff8c00",
311      darkorchid: "9932cc",
312      darkred: "8b0000",
313      darksalmon: "e9967a",
314      darkseagreen: "8fbc8f",
315      darkslateblue: "483d8b",
316      darkslategray: "2f4f4f",
317      darkturquoise: "00ced1",
318      darkviolet: "9400d3",
319      deeppink: "ff1493",
320      deepskyblue: "00bfff",
321      dimgray: "696969",
322      dodgerblue: "1e90ff",
323      feldspar: "d19275",
324      firebrick: "b22222",
325      floralwhite: "fffaf0",
326      forestgreen: "228b22",
327      fuchsia: "ff00ff",
328      gainsboro: "dcdcdc",
329      ghostwhite: "f8f8ff",
330      gold: "ffd700",
331      goldenrod: "daa520",
332      gray: "808080",
333      green: "008000",
334      greenyellow: "adff2f",
335      honeydew: "f0fff0",
336      hotpink: "ff69b4",
337      indianred: "cd5c5c",
338      indigo: "4b0082",
339      ivory: "fffff0",
340      khaki: "f0e68c",
341      lavender: "e6e6fa",
342      lavenderblush: "fff0f5",
343      lawngreen: "7cfc00",
344      lemonchiffon: "fffacd",
345      lightblue: "add8e6",
346      lightcoral: "f08080",
347      lightcyan: "e0ffff",
348      lightgoldenrodyellow: "fafad2",
349      lightgrey: "d3d3d3",
350      lightgreen: "90ee90",
351      lightpink: "ffb6c1",
352      lightsalmon: "ffa07a",
353      lightseagreen: "20b2aa",
354      lightskyblue: "87cefa",
355      lightslateblue: "8470ff",
356      lightslategray: "778899",
357      lightsteelblue: "b0c4de",
358      lightyellow: "ffffe0",
359      lime: "00ff00",
360      limegreen: "32cd32",
361      linen: "faf0e6",
362      magenta: "ff00ff",
363      maroon: "800000",
364      mediumaquamarine: "66cdaa",
365      mediumblue: "0000cd",
366      mediumorchid: "ba55d3",
367      mediumpurple: "9370d8",
368      mediumseagreen: "3cb371",
369      mediumslateblue: "7b68ee",
370      mediumspringgreen: "00fa9a",
371      mediumturquoise: "48d1cc",
372      mediumvioletred: "c71585",
373      midnightblue: "191970",
374      mintcream: "f5fffa",
375      mistyrose: "ffe4e1",
376      moccasin: "ffe4b5",
377      navajowhite: "ffdead",
378      navy: "000080",
379      oldlace: "fdf5e6",
380      olive: "808000",
381      olivedrab: "6b8e23",
382      orange: "ffa500",
383      orangered: "ff4500",
384      orchid: "da70d6",
385      palegoldenrod: "eee8aa",
386      palegreen: "98fb98",
387      paleturquoise: "afeeee",
388      palevioletred: "d87093",
389      papayawhip: "ffefd5",
390      peachpuff: "ffdab9",
391      peru: "cd853f",
392      pink: "ffc0cb",
393      plum: "dda0dd",
394      powderblue: "b0e0e6",
395      purple: "800080",
396      red: "ff0000",
397      rosybrown: "bc8f8f",
398      royalblue: "4169e1",
399      saddlebrown: "8b4513",
400      salmon: "fa8072",
401      sandybrown: "f4a460",
402      seagreen: "2e8b57",
403      seashell: "fff5ee",
404      sienna: "a0522d",
405      silver: "c0c0c0",
406      skyblue: "87ceeb",
407      slateblue: "6a5acd",
408      slategray: "708090",
409      snow: "fffafa",
410      springgreen: "00ff7f",
411      steelblue: "4682b4",
412      tan: "d2b48c",
413      teal: "008080",
414      thistle: "d8bfd8",
415      tomato: "ff6347",
416      turquoise: "40e0d0",
417      violet: "ee82ee",
418      violetred: "d02090",
419      wheat: "f5deb3",
420      white: "ffffff",
421      whitesmoke: "f5f5f5",
422      yellow: "ffff00",
423      yellowgreen: "9acd32"
424    };
425    color_string = simple_colors[color_string] || color_string; // array of color definition objects
426
427    var color_defs = [{
428      re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
429      example: ["rgb(123, 234, 45)", "rgb(255,234,245)"],
430      process: function process(bits) {
431        return [parseInt(bits[1]), parseInt(bits[2]), parseInt(bits[3])];
432      }
433    }, {
434      re: /^(\w{2})(\w{2})(\w{2})$/,
435      example: ["#00ff00", "336699"],
436      process: function process(bits) {
437        return [parseInt(bits[1], 16), parseInt(bits[2], 16), parseInt(bits[3], 16)];
438      }
439    }, {
440      re: /^(\w{1})(\w{1})(\w{1})$/,
441      example: ["#fb0", "f0f"],
442      process: function process(bits) {
443        return [parseInt(bits[1] + bits[1], 16), parseInt(bits[2] + bits[2], 16), parseInt(bits[3] + bits[3], 16)];
444      }
445    }]; // search through the definitions to find a match
446
447    for (var i = 0; i < color_defs.length; i++) {
448      var re = color_defs[i].re;
449      var processor = color_defs[i].process;
450      var bits = re.exec(color_string);
451
452      if (bits) {
453        channels = processor(bits);
454        this.r = channels[0];
455        this.g = channels[1];
456        this.b = channels[2];
457        this.ok = true;
458      }
459    } // validate/cleanup values
460
461
462    this.r = this.r < 0 || isNaN(this.r) ? 0 : this.r > 255 ? 255 : this.r;
463    this.g = this.g < 0 || isNaN(this.g) ? 0 : this.g > 255 ? 255 : this.g;
464    this.b = this.b < 0 || isNaN(this.b) ? 0 : this.b > 255 ? 255 : this.b; // some getters
465
466    this.toRGB = function () {
467      return "rgb(" + this.r + ", " + this.g + ", " + this.b + ")";
468    };
469
470    this.toHex = function () {
471      var r = this.r.toString(16);
472      var g = this.g.toString(16);
473      var b = this.b.toString(16);
474      if (r.length == 1) r = "0" + r;
475      if (g.length == 1) g = "0" + g;
476      if (b.length == 1) b = "0" + b;
477      return "#" + r + g + b;
478    };
479  }
480
481  var atob, btoa;
482
483  (function () {
484    atob = globalObject.atob.bind(globalObject);
485    btoa = globalObject.btoa.bind(globalObject);
486    return;
487  })();
488
489  /**
490   * @license
491   * Joseph Myers does not specify a particular license for his work.
492   *
493   * Author: Joseph Myers
494   * Accessed from: http://www.myersdaily.org/joseph/javascript/md5.js
495   *
496   * Modified by: Owen Leong
497   */
498  function md5cycle(x, k) {
499    var a = x[0],
500        b = x[1],
501        c = x[2],
502        d = x[3];
503    a = ff(a, b, c, d, k[0], 7, -680876936);
504    d = ff(d, a, b, c, k[1], 12, -389564586);
505    c = ff(c, d, a, b, k[2], 17, 606105819);
506    b = ff(b, c, d, a, k[3], 22, -1044525330);
507    a = ff(a, b, c, d, k[4], 7, -176418897);
508    d = ff(d, a, b, c, k[5], 12, 1200080426);
509    c = ff(c, d, a, b, k[6], 17, -1473231341);
510    b = ff(b, c, d, a, k[7], 22, -45705983);
511    a = ff(a, b, c, d, k[8], 7, 1770035416);
512    d = ff(d, a, b, c, k[9], 12, -1958414417);
513    c = ff(c, d, a, b, k[10], 17, -42063);
514    b = ff(b, c, d, a, k[11], 22, -1990404162);
515    a = ff(a, b, c, d, k[12], 7, 1804603682);
516    d = ff(d, a, b, c, k[13], 12, -40341101);
517    c = ff(c, d, a, b, k[14], 17, -1502002290);
518    b = ff(b, c, d, a, k[15], 22, 1236535329);
519    a = gg(a, b, c, d, k[1], 5, -165796510);
520    d = gg(d, a, b, c, k[6], 9, -1069501632);
521    c = gg(c, d, a, b, k[11], 14, 643717713);
522    b = gg(b, c, d, a, k[0], 20, -373897302);
523    a = gg(a, b, c, d, k[5], 5, -701558691);
524    d = gg(d, a, b, c, k[10], 9, 38016083);
525    c = gg(c, d, a, b, k[15], 14, -660478335);
526    b = gg(b, c, d, a, k[4], 20, -405537848);
527    a = gg(a, b, c, d, k[9], 5, 568446438);
528    d = gg(d, a, b, c, k[14], 9, -1019803690);
529    c = gg(c, d, a, b, k[3], 14, -187363961);
530    b = gg(b, c, d, a, k[8], 20, 1163531501);
531    a = gg(a, b, c, d, k[13], 5, -1444681467);
532    d = gg(d, a, b, c, k[2], 9, -51403784);
533    c = gg(c, d, a, b, k[7], 14, 1735328473);
534    b = gg(b, c, d, a, k[12], 20, -1926607734);
535    a = hh(a, b, c, d, k[5], 4, -378558);
536    d = hh(d, a, b, c, k[8], 11, -2022574463);
537    c = hh(c, d, a, b, k[11], 16, 1839030562);
538    b = hh(b, c, d, a, k[14], 23, -35309556);
539    a = hh(a, b, c, d, k[1], 4, -1530992060);
540    d = hh(d, a, b, c, k[4], 11, 1272893353);
541    c = hh(c, d, a, b, k[7], 16, -155497632);
542    b = hh(b, c, d, a, k[10], 23, -1094730640);
543    a = hh(a, b, c, d, k[13], 4, 681279174);
544    d = hh(d, a, b, c, k[0], 11, -358537222);
545    c = hh(c, d, a, b, k[3], 16, -722521979);
546    b = hh(b, c, d, a, k[6], 23, 76029189);
547    a = hh(a, b, c, d, k[9], 4, -640364487);
548    d = hh(d, a, b, c, k[12], 11, -421815835);
549    c = hh(c, d, a, b, k[15], 16, 530742520);
550    b = hh(b, c, d, a, k[2], 23, -995338651);
551    a = ii(a, b, c, d, k[0], 6, -198630844);
552    d = ii(d, a, b, c, k[7], 10, 1126891415);
553    c = ii(c, d, a, b, k[14], 15, -1416354905);
554    b = ii(b, c, d, a, k[5], 21, -57434055);
555    a = ii(a, b, c, d, k[12], 6, 1700485571);
556    d = ii(d, a, b, c, k[3], 10, -1894986606);
557    c = ii(c, d, a, b, k[10], 15, -1051523);
558    b = ii(b, c, d, a, k[1], 21, -2054922799);
559    a = ii(a, b, c, d, k[8], 6, 1873313359);
560    d = ii(d, a, b, c, k[15], 10, -30611744);
561    c = ii(c, d, a, b, k[6], 15, -1560198380);
562    b = ii(b, c, d, a, k[13], 21, 1309151649);
563    a = ii(a, b, c, d, k[4], 6, -145523070);
564    d = ii(d, a, b, c, k[11], 10, -1120210379);
565    c = ii(c, d, a, b, k[2], 15, 718787259);
566    b = ii(b, c, d, a, k[9], 21, -343485551);
567    x[0] = add32(a, x[0]);
568    x[1] = add32(b, x[1]);
569    x[2] = add32(c, x[2]);
570    x[3] = add32(d, x[3]);
571  }
572
573  function cmn(q, a, b, x, s, t) {
574    a = add32(add32(a, q), add32(x, t));
575    return add32(a << s | a >>> 32 - s, b);
576  }
577
578  function ff(a, b, c, d, x, s, t) {
579    return cmn(b & c | ~b & d, a, b, x, s, t);
580  }
581
582  function gg(a, b, c, d, x, s, t) {
583    return cmn(b & d | c & ~d, a, b, x, s, t);
584  }
585
586  function hh(a, b, c, d, x, s, t) {
587    return cmn(b ^ c ^ d, a, b, x, s, t);
588  }
589
590  function ii(a, b, c, d, x, s, t) {
591    return cmn(c ^ (b | ~d), a, b, x, s, t);
592  }
593
594  function md51(s) {
595    // txt = '';
596    var n = s.length,
597        state = [1732584193, -271733879, -1732584194, 271733878],
598        i;
599
600    for (i = 64; i <= s.length; i += 64) {
601      md5cycle(state, md5blk(s.substring(i - 64, i)));
602    }
603
604    s = s.substring(i - 64);
605    var tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
606
607    for (i = 0; i < s.length; i++) {
608      tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3);
609    }
610
611    tail[i >> 2] |= 0x80 << (i % 4 << 3);
612
613    if (i > 55) {
614      md5cycle(state, tail);
615
616      for (i = 0; i < 16; i++) {
617        tail[i] = 0;
618      }
619    }
620
621    tail[14] = n * 8;
622    md5cycle(state, tail);
623    return state;
624  }
625  /* there needs to be support for Unicode here,
626   * unless we pretend that we can redefine the MD-5
627   * algorithm for multi-byte characters (perhaps
628   * by adding every four 16-bit characters and
629   * shortening the sum to 32 bits). Otherwise
630   * I suggest performing MD-5 as if every character
631   * was two bytes--e.g., 0040 0025 = @%--but then
632   * how will an ordinary MD-5 sum be matched?
633   * There is no way to standardize text to something
634   * like UTF-8 before transformation; speed cost is
635   * utterly prohibitive. The JavaScript standard
636   * itself needs to look at this: it should start
637   * providing access to strings as preformed UTF-8
638   * 8-bit unsigned value arrays.
639   */
640
641
642  function md5blk(s) {
643    /* I figured global was faster.   */
644    var md5blks = [],
645        i;
646    /* Andy King said do it this way. */
647
648    for (i = 0; i < 64; i += 4) {
649      md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
650    }
651
652    return md5blks;
653  }
654
655  var hex_chr = "0123456789abcdef".split("");
656
657  function rhex(n) {
658    var s = "",
659        j = 0;
660
661    for (; j < 4; j++) {
662      s += hex_chr[n >> j * 8 + 4 & 0x0f] + hex_chr[n >> j * 8 & 0x0f];
663    }
664
665    return s;
666  }
667
668  function hex(x) {
669    for (var i = 0; i < x.length; i++) {
670      x[i] = rhex(x[i]);
671    }
672
673    return x.join("");
674  } // Converts a 4-byte number to byte string
675
676
677  function singleToByteString(n) {
678    return String.fromCharCode((n & 0xff) >> 0, (n & 0xff00) >> 8, (n & 0xff0000) >> 16, (n & 0xff000000) >> 24);
679  } // Converts an array of numbers to a byte string
680
681
682  function toByteString(x) {
683    return x.map(singleToByteString).join("");
684  } // Returns the MD5 hash as a byte string
685
686
687  function md5Bin(s) {
688    return toByteString(md51(s));
689  } // Returns MD5 hash as a hex string
690
691
692  function md5(s) {
693    return hex(md51(s));
694  }
695
696  var md5Check = md5("hello") != "5d41402abc4b2a76b9719d911017c592";
697
698  function add32(a, b) {
699    if (md5Check) {
700      /* if the md5Check does not match
701       the expected value, we're dealing
702       with an old browser and need
703       this function. */
704      var lsw = (a & 0xffff) + (b & 0xffff),
705          msw = (a >> 16) + (b >> 16) + (lsw >> 16);
706      return msw << 16 | lsw & 0xffff;
707    } else {
708      /* this function is much faster,
709      so if possible we use it. Some IEs
710      are the only ones I know of that
711      need the idiotic second function,
712      generated by an if clause.  */
713      return a + b & 0xffffffff;
714    }
715  }
716
717  /**
718   * @license
719   * FPDF is released under a permissive license: there is no usage restriction.
720   * You may embed it freely in your application (commercial or not), with or
721   * without modifications.
722   *
723   * Reference: http://www.fpdf.org/en/script/script37.php
724   */
725  function repeat(str, num) {
726    return new Array(num + 1).join(str);
727  }
728  /**
729   * Converts a byte string to a hex string
730   *
731   * @name rc4
732   * @function
733   * @param {string} key Byte string of encryption key
734   * @param {string} data Byte string of data to be encrypted
735   * @returns {string} Encrypted string
736   */
737
738
739  function rc4(key, data) {
740    var lastKey, lastState;
741
742    if (key !== lastKey) {
743      var k = repeat(key, (256 / key.length >> 0) + 1);
744      var state = [];
745
746      for (var i = 0; i < 256; i++) {
747        state[i] = i;
748      }
749
750      var j = 0;
751
752      for (var i = 0; i < 256; i++) {
753        var t = state[i];
754        j = (j + t + k.charCodeAt(i)) % 256;
755        state[i] = state[j];
756        state[j] = t;
757      }
758
759      lastKey = key;
760      lastState = state;
761    } else {
762      state = lastState;
763    }
764
765    var length = data.length;
766    var a = 0;
767    var b = 0;
768    var out = "";
769
770    for (var i = 0; i < length; i++) {
771      a = (a + 1) % 256;
772      t = state[a];
773      b = (b + t) % 256;
774      state[a] = state[b];
775      state[b] = t;
776      k = state[(state[a] + state[b]) % 256];
777      out += String.fromCharCode(data.charCodeAt(i) ^ k);
778    }
779
780    return out;
781  }
782
783  /**
784   * @license
785   * Licensed under the MIT License.
786   * http://opensource.org/licenses/mit-license
787   * Author: Owen Leong (@owenl131)
788   * Date: 15 Oct 2020
789   * References:
790   * https://www.cs.cmu.edu/~dst/Adobe/Gallery/anon21jul01-pdf-encryption.txt
791   * https://github.com/foliojs/pdfkit/blob/master/lib/security.js
792   * http://www.fpdf.org/en/script/script37.php
793   */
794  var permissionOptions = {
795    print: 4,
796    modify: 8,
797    copy: 16,
798    "annot-forms": 32
799  };
800  /**
801   * Initializes encryption settings
802   *
803   * @name constructor
804   * @function
805   * @param {Array} permissions Permissions allowed for user, "print", "modify", "copy" and "annot-forms".
806   * @param {String} userPassword Permissions apply to this user. Leaving this empty means the document
807   *                              is not password protected but viewer has the above permissions.
808   * @param {String} ownerPassword Owner has full functionalities to the file.
809   * @param {String} fileId As hex string, should be same as the file ID in the trailer.
810   * @example
811   * var security = new PDFSecurity(["print"])
812   */
813
814  function PDFSecurity(permissions, userPassword, ownerPassword, fileId) {
815    this.v = 1; // algorithm 1, future work can add in more recent encryption schemes
816
817    this.r = 2; // revision 2
818    // set flags for what functionalities the user can access
819
820    var protection = 192;
821    permissions.forEach(function (perm) {
822      if (typeof permissionOptions.perm !== "undefined") {
823        throw new Error("Invalid permission: " + perm);
824      }
825
826      protection += permissionOptions[perm];
827    }); // padding is used to pad the passwords to 32 bytes, also is hashed and stored in the final PDF
828
829    this.padding = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08" + "\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
830    var paddedUserPassword = (userPassword + this.padding).substr(0, 32);
831    var paddedOwnerPassword = (ownerPassword + this.padding).substr(0, 32);
832    this.O = this.processOwnerPassword(paddedUserPassword, paddedOwnerPassword);
833    this.P = -((protection ^ 255) + 1);
834    this.encryptionKey = md5Bin(paddedUserPassword + this.O + this.lsbFirstWord(this.P) + this.hexToBytes(fileId)).substr(0, 5);
835    this.U = rc4(this.encryptionKey, this.padding);
836  }
837  /**
838   * Breaks down a 4-byte number into its individual bytes, with the least significant bit first
839   *
840   * @name lsbFirstWord
841   * @function
842   * @param {number} data 32-bit number
843   * @returns {Array}
844   */
845
846
847  PDFSecurity.prototype.lsbFirstWord = function (data) {
848    return String.fromCharCode(data >> 0 & 0xff, data >> 8 & 0xff, data >> 16 & 0xff, data >> 24 & 0xff);
849  };
850  /**
851   * Converts a byte string to a hex string
852   *
853   * @name toHexString
854   * @function
855   * @param {String} byteString Byte string
856   * @returns {String}
857   */
858
859
860  PDFSecurity.prototype.toHexString = function (byteString) {
861    return byteString.split("").map(function (byte) {
862      return ("0" + (byte.charCodeAt(0) & 0xff).toString(16)).slice(-2);
863    }).join("");
864  };
865  /**
866   * Converts a hex string to a byte string
867   *
868   * @name hexToBytes
869   * @function
870   * @param {String} hex Hex string
871   * @returns {String}
872   */
873
874
875  PDFSecurity.prototype.hexToBytes = function (hex) {
876    for (var bytes = [], c = 0; c < hex.length; c += 2) {
877      bytes.push(String.fromCharCode(parseInt(hex.substr(c, 2), 16)));
878    }
879
880    return bytes.join("");
881  };
882  /**
883   * Computes the 'O' field in the encryption dictionary
884   *
885   * @name processOwnerPassword
886   * @function
887   * @param {String} paddedUserPassword Byte string of padded user password
888   * @param {String} paddedOwnerPassword Byte string of padded owner password
889   * @returns {String}
890   */
891
892
893  PDFSecurity.prototype.processOwnerPassword = function (paddedUserPassword, paddedOwnerPassword) {
894    var key = md5Bin(paddedOwnerPassword).substr(0, 5);
895    return rc4(key, paddedUserPassword);
896  };
897  /**
898   * Returns an encryptor function which can take in a byte string and returns the encrypted version
899   *
900   * @name encryptor
901   * @function
902   * @param {number} objectId
903   * @param {number} generation Not sure what this is for, you can set it to 0
904   * @returns {Function}
905   * @example
906   * out("stream");
907   * encryptor = security.encryptor(object.id, 0);
908   * out(encryptor(data));
909   * out("endstream");
910   */
911
912
913  PDFSecurity.prototype.encryptor = function (objectId, generation) {
914    var key = md5Bin(this.encryptionKey + String.fromCharCode(objectId & 0xff, objectId >> 8 & 0xff, objectId >> 16 & 0xff, generation & 0xff, generation >> 8 & 0xff)).substr(0, 10);
915    return function (data) {
916      return rc4(key, data);
917    };
918  };
919
920  /**
921   * Convert string to `PDF Name Object`.
922   * Detail: PDF Reference 1.3 - Chapter 3.2.4 Name Object
923   * @param str
924   */
925  function toPDFName(str) {
926    // eslint-disable-next-line no-control-regex
927    if (/[^\u0000-\u00ff]/.test(str)) {
928      // non ascii string
929      throw new Error("Invalid PDF Name Object: " + str + ", Only accept ASCII characters.");
930    }
931
932    var result = "",
933        strLength = str.length;
934
935    for (var i = 0; i < strLength; i++) {
936      var charCode = str.charCodeAt(i);
937
938      if (charCode < 0x21 || charCode === 0x23
939      /* # */
940      || charCode === 0x25
941      /* % */
942      || charCode === 0x28
943      /* ( */
944      || charCode === 0x29
945      /* ) */
946      || charCode === 0x2f
947      /* / */
948      || charCode === 0x3c
949      /* < */
950      || charCode === 0x3e
951      /* > */
952      || charCode === 0x5b
953      /* [ */
954      || charCode === 0x5d
955      /* ] */
956      || charCode === 0x7b
957      /* { */
958      || charCode === 0x7d
959      /* } */
960      || charCode > 0x7e) {
961        // Char    CharCode    hexStr   paddingHexStr    Result
962        // "\t"    9           9        09               #09
963        // " "     32          20       20               #20
964        // "©"     169         a9       a9               #a9
965        var hexStr = charCode.toString(16),
966            paddingHexStr = ("0" + hexStr).slice(-2);
967        result += "#" + paddingHexStr;
968      } else {
969        // Other ASCII printable characters between 0x21 <= X <= 0x7e
970        result += str[i];
971      }
972    }
973
974    return result;
975  }
976
977  /**
978   * jsPDF's Internal PubSub Implementation.
979   * Backward compatible rewritten on 2014 by
980   * Diego Casorran, https://github.com/diegocr
981   *
982   * @class
983   * @name PubSub
984   * @ignore
985   */
986
987  function PubSub(context) {
988    if (_typeof(context) !== "object") {
989      throw new Error("Invalid Context passed to initialize PubSub (jsPDF-module)");
990    }
991
992    var topics = {};
993
994    this.subscribe = function (topic, callback, once) {
995      once = once || false;
996
997      if (typeof topic !== "string" || typeof callback !== "function" || typeof once !== "boolean") {
998        throw new Error("Invalid arguments passed to PubSub.subscribe (jsPDF-module)");
999      }
1000
1001      if (!topics.hasOwnProperty(topic)) {
1002        topics[topic] = {};
1003      }
1004
1005      var token = Math.random().toString(35);
1006      topics[topic][token] = [callback, !!once];
1007      return token;
1008    };
1009
1010    this.unsubscribe = function (token) {
1011      for (var topic in topics) {
1012        if (topics[topic][token]) {
1013          delete topics[topic][token];
1014
1015          if (Object.keys(topics[topic]).length === 0) {
1016            delete topics[topic];
1017          }
1018
1019          return true;
1020        }
1021      }
1022
1023      return false;
1024    };
1025
1026    this.publish = function (topic) {
1027      if (topics.hasOwnProperty(topic)) {
1028        var args = Array.prototype.slice.call(arguments, 1),
1029            tokens = [];
1030
1031        for (var token in topics[topic]) {
1032          var sub = topics[topic][token];
1033
1034          try {
1035            sub[0].apply(context, args);
1036          } catch (ex) {
1037            if (globalObject.console) {
1038              console.error("jsPDF PubSub Error", ex.message, ex);
1039            }
1040          }
1041
1042          if (sub[1]) tokens.push(token);
1043        }
1044
1045        if (tokens.length) tokens.forEach(this.unsubscribe);
1046      }
1047    };
1048
1049    this.getTopics = function () {
1050      return topics;
1051    };
1052  }
1053
1054  function GState(parameters) {
1055    if (!(this instanceof GState)) {
1056      return new GState(parameters);
1057    }
1058    /**
1059     * @name GState#opacity
1060     * @type {any}
1061     */
1062
1063    /**
1064     * @name GState#stroke-opacity
1065     * @type {any}
1066     */
1067
1068
1069    var supported = "opacity,stroke-opacity".split(",");
1070
1071    for (var p in parameters) {
1072      if (parameters.hasOwnProperty(p) && supported.indexOf(p) >= 0) {
1073        this[p] = parameters[p];
1074      }
1075    }
1076    /**
1077     * @name GState#id
1078     * @type {string}
1079     */
1080
1081
1082    this.id = ""; // set by addGState()
1083
1084    /**
1085     * @name GState#objectNumber
1086     * @type {number}
1087     */
1088
1089    this.objectNumber = -1; // will be set by putGState()
1090  }
1091
1092  GState.prototype.equals = function equals(other) {
1093    var ignore = "id,objectNumber,equals";
1094    var p;
1095    if (!other || _typeof(other) !== _typeof(this)) return false;
1096    var count = 0;
1097
1098    for (p in this) {
1099      if (ignore.indexOf(p) >= 0) continue;
1100      if (this.hasOwnProperty(p) && !other.hasOwnProperty(p)) return false;
1101      if (this[p] !== other[p]) return false;
1102      count++;
1103    }
1104
1105    for (p in other) {
1106      if (other.hasOwnProperty(p) && ignore.indexOf(p) < 0) count--;
1107    }
1108
1109    return count === 0;
1110  };
1111
1112  function Pattern(gState, matrix) {
1113    this.gState = gState;
1114    this.matrix = matrix;
1115    this.id = ""; // set by addPattern()
1116
1117    this.objectNumber = -1; // will be set by putPattern()
1118  }
1119
1120  function ShadingPattern(type, coords, colors, gState, matrix) {
1121    if (!(this instanceof ShadingPattern)) {
1122      return new ShadingPattern(type, coords, colors, gState, matrix);
1123    } // see putPattern() for information how they are realized
1124
1125
1126    this.type = type === "axial" ? 2 : 3;
1127    this.coords = coords;
1128    this.colors = colors;
1129    Pattern.call(this, gState, matrix);
1130  }
1131
1132  function TilingPattern(boundingBox, xStep, yStep, gState, matrix) {
1133    if (!(this instanceof TilingPattern)) {
1134      return new TilingPattern(boundingBox, xStep, yStep, gState, matrix);
1135    }
1136
1137    this.boundingBox = boundingBox;
1138    this.xStep = xStep;
1139    this.yStep = yStep;
1140    this.stream = ""; // set by endTilingPattern();
1141
1142    this.cloneIndex = 0;
1143    Pattern.call(this, gState, matrix);
1144  }
1145  /**
1146   * Creates new jsPDF document object instance.
1147   * @name jsPDF
1148   * @class
1149   * @param {Object} [options] - Collection of settings initializing the jsPDF-instance
1150   * @param {string} [options.orientation=portrait] - Orientation of the first page. Possible values are "portrait" or "landscape" (or shortcuts "p" or "l").<br />
1151   * @param {string} [options.unit=mm] Measurement unit (base unit) to be used when coordinates are specified.<br />
1152   * Possible values are "pt" (points), "mm", "cm", "in", "px", "pc", "em" or "ex". Note that in order to get the correct scaling for "px"
1153   * units, you need to enable the hotfix "px_scaling" by setting options.hotfixes = ["px_scaling"].
1154   * @param {string/Array} [options.format=a4] The format of the first page. Can be:<ul><li>a0 - a10</li><li>b0 - b10</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 />
1155   * 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]
1156   * @param {boolean} [options.putOnlyUsedFonts=false] Only put fonts into the PDF, which were used.
1157   * @param {boolean} [options.compress=false] Compress the generated PDF.
1158   * @param {number} [options.precision=16] Precision of the element-positions.
1159   * @param {number} [options.userUnit=1.0] Not to be confused with the base unit. Please inform yourself before you use it.
1160   * @param {string[]} [options.hotfixes] An array of strings to enable hotfixes such as correct pixel scaling.
1161   * @param {Object} [options.encryption]
1162   * @param {string} [options.encryption.userPassword] Password for the user bound by the given permissions list.
1163   * @param {string} [options.encryption.ownerPassword] Both userPassword and ownerPassword should be set for proper authentication.
1164   * @param {string[]} [options.encryption.userPermissions] Array of permissions "print", "modify", "copy", "annot-forms", accessible by the user.
1165   * @param {number|"smart"} [options.floatPrecision=16]
1166   * @returns {jsPDF} jsPDF-instance
1167   * @description
1168   * ```
1169   * {
1170   *  orientation: 'p',
1171   *  unit: 'mm',
1172   *  format: 'a4',
1173   *  putOnlyUsedFonts:true,
1174   *  floatPrecision: 16 // or "smart", default is 16
1175   * }
1176   * ```
1177   *
1178   * @constructor
1179   */
1180
1181
1182  function jsPDF(options) {
1183    var orientation = typeof arguments[0] === "string" ? arguments[0] : "p";
1184    var unit = arguments[1];
1185    var format = arguments[2];
1186    var compressPdf = arguments[3];
1187    var filters = [];
1188    var userUnit = 1.0;
1189    var precision;
1190    var floatPrecision = 16;
1191    var defaultPathOperation = "S";
1192    var encryptionOptions = null;
1193    options = options || {};
1194
1195    if (_typeof(options) === "object") {
1196      orientation = options.orientation;
1197      unit = options.unit || unit;
1198      format = options.format || format;
1199      compressPdf = options.compress || options.compressPdf || compressPdf;
1200      encryptionOptions = options.encryption || null;
1201
1202      if (encryptionOptions !== null) {
1203        encryptionOptions.userPassword = encryptionOptions.userPassword || "";
1204        encryptionOptions.ownerPassword = encryptionOptions.ownerPassword || "";
1205        encryptionOptions.userPermissions = encryptionOptions.userPermissions || [];
1206      }
1207
1208      userUnit = typeof options.userUnit === "number" ? Math.abs(options.userUnit) : 1.0;
1209
1210      if (typeof options.precision !== "undefined") {
1211        precision = options.precision;
1212      }
1213
1214      if (typeof options.floatPrecision !== "undefined") {
1215        floatPrecision = options.floatPrecision;
1216      }
1217
1218      defaultPathOperation = options.defaultPathOperation || "S";
1219    }
1220
1221    filters = options.filters || (compressPdf === true ? ["FlateEncode"] : filters);
1222    unit = unit || "mm";
1223    orientation = ("" + (orientation || "P")).toLowerCase();
1224    var putOnlyUsedFonts = options.putOnlyUsedFonts || false;
1225    var usedFonts = {};
1226    var API = {
1227      internal: {},
1228      __private__: {}
1229    };
1230    API.__private__.PubSub = PubSub;
1231    var pdfVersion = "1.3";
1232
1233    var getPdfVersion = API.__private__.getPdfVersion = function () {
1234      return pdfVersion;
1235    };
1236
1237    API.__private__.setPdfVersion = function (value) {
1238      pdfVersion = value;
1239    }; // Size in pt of various paper formats
1240
1241
1242    var pageFormats = {
1243      a0: [2383.94, 3370.39],
1244      a1: [1683.78, 2383.94],
1245      a2: [1190.55, 1683.78],
1246      a3: [841.89, 1190.55],
1247      a4: [595.28, 841.89],
1248      a5: [419.53, 595.28],
1249      a6: [297.64, 419.53],
1250      a7: [209.76, 297.64],
1251      a8: [147.4, 209.76],
1252      a9: [104.88, 147.4],
1253      a10: [73.7, 104.88],
1254      b0: [2834.65, 4008.19],
1255      b1: [2004.09, 2834.65],
1256      b2: [1417.32, 2004.09],
1257      b3: [1000.63, 1417.32],
1258      b4: [708.66, 1000.63],
1259      b5: [498.9, 708.66],
1260      b6: [354.33, 498.9],
1261      b7: [249.45, 354.33],
1262      b8: [175.75, 249.45],
1263      b9: [124.72, 175.75],
1264      b10: [87.87, 124.72],
1265      c0: [2599.37, 3676.54],
1266      c1: [1836.85, 2599.37],
1267      c2: [1298.27, 1836.85],
1268      c3: [918.43, 1298.27],
1269      c4: [649.13, 918.43],
1270      c5: [459.21, 649.13],
1271      c6: [323.15, 459.21],
1272      c7: [229.61, 323.15],
1273      c8: [161.57, 229.61],
1274      c9: [113.39, 161.57],
1275      c10: [79.37, 113.39],
1276      dl: [311.81, 623.62],
1277      letter: [612, 792],
1278      "government-letter": [576, 756],
1279      legal: [612, 1008],
1280      "junior-legal": [576, 360],
1281      ledger: [1224, 792],
1282      tabloid: [792, 1224],
1283      "credit-card": [153, 243]
1284    };
1285
1286    API.__private__.getPageFormats = function () {
1287      return pageFormats;
1288    };
1289
1290    var getPageFormat = API.__private__.getPageFormat = function (value) {
1291      return pageFormats[value];
1292    };
1293
1294    format = format || "a4";
1295    var ApiMode = {
1296      COMPAT: "compat",
1297      ADVANCED: "advanced"
1298    };
1299    var apiMode = ApiMode.COMPAT;
1300
1301    function advancedAPI() {
1302      // prepend global change of basis matrix
1303      // (Now, instead of converting every coordinate to the pdf coordinate system, we apply a matrix
1304      // that does this job for us (however, texts, images and similar objects must be drawn bottom up))
1305      this.saveGraphicsState();
1306      out(new Matrix(scaleFactor, 0, 0, -scaleFactor, 0, getPageHeight() * scaleFactor).toString() + " cm");
1307      this.setFontSize(this.getFontSize() / scaleFactor); // The default in MrRio's implementation is "S" (stroke), whereas the default in the yWorks implementation
1308      // was "n" (none). Although this has nothing to do with transforms, we should use the API switch here.
1309
1310      defaultPathOperation = "n";
1311      apiMode = ApiMode.ADVANCED;
1312    }
1313
1314    function compatAPI() {
1315      this.restoreGraphicsState();
1316      defaultPathOperation = "S";
1317      apiMode = ApiMode.COMPAT;
1318    }
1319    /**
1320     * @function combineFontStyleAndFontWeight
1321     * @param {string} fontStyle Fontstyle or variant. Example: "italic".
1322     * @param {number | string} fontWeight Weight of the Font. Example: "normal" | 400
1323     * @returns {string}
1324     * @private
1325     */
1326
1327
1328    var combineFontStyleAndFontWeight = API.__private__.combineFontStyleAndFontWeight = function (fontStyle, fontWeight) {
1329      if (fontStyle == "bold" && fontWeight == "normal" || fontStyle == "bold" && fontWeight == 400 || fontStyle == "normal" && fontWeight == "italic" || fontStyle == "bold" && fontWeight == "italic") {
1330        throw new Error("Invalid Combination of fontweight and fontstyle");
1331      }
1332
1333      if (fontWeight) {
1334        fontStyle = fontWeight == 400 || fontWeight === "normal" ? fontStyle === "italic" ? "italic" : "normal" : (fontWeight == 700 || fontWeight === "bold") && fontStyle === "normal" ? "bold" : (fontWeight == 700 ? "bold" : fontWeight) + "" + fontStyle;
1335      }
1336
1337      return fontStyle;
1338    };
1339    /**
1340     * @callback ApiSwitchBody
1341     * @param {jsPDF} pdf
1342     */
1343
1344    /**
1345     * For compatibility reasons jsPDF offers two API modes which differ in the way they convert between the the usual
1346     * screen coordinates and the PDF coordinate system.
1347     *   - "compat": Offers full compatibility across all plugins but does not allow arbitrary transforms
1348     *   - "advanced": Allows arbitrary transforms and more advanced features like pattern fills. Some plugins might
1349     *     not support this mode, though.
1350     * Initial mode is "compat".
1351     *
1352     * You can either provide a callback to the body argument, which means that jsPDF will automatically switch back to
1353     * the original API mode afterwards; or you can omit the callback and switch back manually using {@link compatAPI}.
1354     *
1355     * Note, that the calls to {@link saveGraphicsState} and {@link restoreGraphicsState} need to be balanced within the
1356     * callback or between calls of this method and its counterpart {@link compatAPI}. Calls to {@link beginFormObject}
1357     * or {@link beginTilingPattern} need to be closed by their counterparts before switching back to "compat" API mode.
1358     *
1359     * @param {ApiSwitchBody=} body When provided, this callback will be called after the API mode has been switched.
1360     * The API mode will be switched back automatically afterwards.
1361     * @returns {jsPDF}
1362     * @memberof jsPDF#
1363     * @name advancedAPI
1364     */
1365
1366
1367    API.advancedAPI = function (body) {
1368      var doSwitch = apiMode === ApiMode.COMPAT;
1369
1370      if (doSwitch) {
1371        advancedAPI.call(this);
1372      }
1373
1374      if (typeof body !== "function") {
1375        return this;
1376      }
1377
1378      body(this);
1379
1380      if (doSwitch) {
1381        compatAPI.call(this);
1382      }
1383
1384      return this;
1385    };
1386    /**
1387     * Switches to "compat" API mode. See {@link advancedAPI} for more details.
1388     *
1389     * @param {ApiSwitchBody=} body When provided, this callback will be called after the API mode has been switched.
1390     * The API mode will be switched back automatically afterwards.
1391     * @return {jsPDF}
1392     * @memberof jsPDF#
1393     * @name compatApi
1394     */
1395
1396
1397    API.compatAPI = function (body) {
1398      var doSwitch = apiMode === ApiMode.ADVANCED;
1399
1400      if (doSwitch) {
1401        compatAPI.call(this);
1402      }
1403
1404      if (typeof body !== "function") {
1405        return this;
1406      }
1407
1408      body(this);
1409
1410      if (doSwitch) {
1411        advancedAPI.call(this);
1412      }
1413
1414      return this;
1415    };
1416    /**
1417     * @return {boolean} True iff the current API mode is "advanced". See {@link advancedAPI}.
1418     * @memberof jsPDF#
1419     * @name isAdvancedAPI
1420     */
1421
1422
1423    API.isAdvancedAPI = function () {
1424      return apiMode === ApiMode.ADVANCED;
1425    };
1426
1427    var advancedApiModeTrap = function advancedApiModeTrap(methodName) {
1428      if (apiMode !== ApiMode.ADVANCED) {
1429        throw new Error(methodName + " is only available in 'advanced' API mode. " + "You need to call advancedAPI() first.");
1430      }
1431    };
1432
1433    var roundToPrecision = API.roundToPrecision = API.__private__.roundToPrecision = function (number, parmPrecision) {
1434      var tmpPrecision = precision || parmPrecision;
1435
1436      if (isNaN(number) || isNaN(tmpPrecision)) {
1437        throw new Error("Invalid argument passed to jsPDF.roundToPrecision");
1438      }
1439
1440      return number.toFixed(tmpPrecision).replace(/0+$/, "");
1441    }; // high precision float
1442
1443
1444    var hpf;
1445
1446    if (typeof floatPrecision === "number") {
1447      hpf = API.hpf = API.__private__.hpf = function (number) {
1448        if (isNaN(number)) {
1449          throw new Error("Invalid argument passed to jsPDF.hpf");
1450        }
1451
1452        return roundToPrecision(number, floatPrecision);
1453      };
1454    } else if (floatPrecision === "smart") {
1455      hpf = API.hpf = API.__private__.hpf = function (number) {
1456        if (isNaN(number)) {
1457          throw new Error("Invalid argument passed to jsPDF.hpf");
1458        }
1459
1460        if (number > -1 && number < 1) {
1461          return roundToPrecision(number, 16);
1462        } else {
1463          return roundToPrecision(number, 5);
1464        }
1465      };
1466    } else {
1467      hpf = API.hpf = API.__private__.hpf = function (number) {
1468        if (isNaN(number)) {
1469          throw new Error("Invalid argument passed to jsPDF.hpf");
1470        }
1471
1472        return roundToPrecision(number, 16);
1473      };
1474    }
1475
1476    var f2 = API.f2 = API.__private__.f2 = function (number) {
1477      if (isNaN(number)) {
1478        throw new Error("Invalid argument passed to jsPDF.f2");
1479      }
1480
1481      return roundToPrecision(number, 2);
1482    };
1483
1484    var f3 = API.__private__.f3 = function (number) {
1485      if (isNaN(number)) {
1486        throw new Error("Invalid argument passed to jsPDF.f3");
1487      }
1488
1489      return roundToPrecision(number, 3);
1490    };
1491
1492    var scale = API.scale = API.__private__.scale = function (number) {
1493      if (isNaN(number)) {
1494        throw new Error("Invalid argument passed to jsPDF.scale");
1495      }
1496
1497      if (apiMode === ApiMode.COMPAT) {
1498        return number * scaleFactor;
1499      } else if (apiMode === ApiMode.ADVANCED) {
1500        return number;
1501      }
1502    };
1503
1504    var transformY = function transformY(y) {
1505      if (apiMode === ApiMode.COMPAT) {
1506        return getPageHeight() - y;
1507      } else if (apiMode === ApiMode.ADVANCED) {
1508        return y;
1509      }
1510    };
1511
1512    var transformScaleY = function transformScaleY(y) {
1513      return scale(transformY(y));
1514    };
1515    /**
1516     * @name setPrecision
1517     * @memberof jsPDF#
1518     * @function
1519     * @instance
1520     * @param {string} precision
1521     * @returns {jsPDF}
1522     */
1523
1524
1525    API.__private__.setPrecision = API.setPrecision = function (value) {
1526      if (typeof parseInt(value, 10) === "number") {
1527        precision = parseInt(value, 10);
1528      }
1529    };
1530
1531    var fileId = "00000000000000000000000000000000";
1532
1533    var getFileId = API.__private__.getFileId = function () {
1534      return fileId;
1535    };
1536
1537    var setFileId = API.__private__.setFileId = function (value) {
1538      if (typeof value !== "undefined" && /^[a-fA-F0-9]{32}$/.test(value)) {
1539        fileId = value.toUpperCase();
1540      } else {
1541        fileId = fileId.split("").map(function () {
1542          return "ABCDEF0123456789".charAt(Math.floor(Math.random() * 16));
1543        }).join("");
1544      }
1545
1546      if (encryptionOptions !== null) {
1547        encryption = new PDFSecurity(encryptionOptions.userPermissions, encryptionOptions.userPassword, encryptionOptions.ownerPassword, fileId);
1548      }
1549
1550      return fileId;
1551    };
1552    /**
1553     * @name setFileId
1554     * @memberof jsPDF#
1555     * @function
1556     * @instance
1557     * @param {string} value GUID.
1558     * @returns {jsPDF}
1559     */
1560
1561
1562    API.setFileId = function (value) {
1563      setFileId(value);
1564      return this;
1565    };
1566    /**
1567     * @name getFileId
1568     * @memberof jsPDF#
1569     * @function
1570     * @instance
1571     *
1572     * @returns {string} GUID.
1573     */
1574
1575
1576    API.getFileId = function () {
1577      return getFileId();
1578    };
1579
1580    var creationDate;
1581
1582    var convertDateToPDFDate = API.__private__.convertDateToPDFDate = function (parmDate) {
1583      var result = "";
1584      var tzoffset = parmDate.getTimezoneOffset(),
1585          tzsign = tzoffset < 0 ? "+" : "-",
1586          tzhour = Math.floor(Math.abs(tzoffset / 60)),
1587          tzmin = Math.abs(tzoffset % 60),
1588          timeZoneString = [tzsign, padd2(tzhour), "'", padd2(tzmin), "'"].join("");
1589      result = ["D:", parmDate.getFullYear(), padd2(parmDate.getMonth() + 1), padd2(parmDate.getDate()), padd2(parmDate.getHours()), padd2(parmDate.getMinutes()), padd2(parmDate.getSeconds()), timeZoneString].join("");
1590      return result;
1591    };
1592
1593    var convertPDFDateToDate = API.__private__.convertPDFDateToDate = function (parmPDFDate) {
1594      var year = parseInt(parmPDFDate.substr(2, 4), 10);
1595      var month = parseInt(parmPDFDate.substr(6, 2), 10) - 1;
1596      var date = parseInt(parmPDFDate.substr(8, 2), 10);
1597      var hour = parseInt(parmPDFDate.substr(10, 2), 10);
1598      var minutes = parseInt(parmPDFDate.substr(12, 2), 10);
1599      var seconds = parseInt(parmPDFDate.substr(14, 2), 10); // var timeZoneHour = parseInt(parmPDFDate.substr(16, 2), 10);
1600      // var timeZoneMinutes = parseInt(parmPDFDate.substr(20, 2), 10);
1601
1602      var resultingDate = new Date(year, month, date, hour, minutes, seconds, 0);
1603      return resultingDate;
1604    };
1605
1606    var setCreationDate = API.__private__.setCreationDate = function (date) {
1607      var tmpCreationDateString;
1608      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])'?$/;
1609
1610      if (typeof date === "undefined") {
1611        date = new Date();
1612      }
1613
1614      if (date instanceof Date) {
1615        tmpCreationDateString = convertDateToPDFDate(date);
1616      } else if (regexPDFCreationDate.test(date)) {
1617        tmpCreationDateString = date;
1618      } else {
1619        throw new Error("Invalid argument passed to jsPDF.setCreationDate");
1620      }
1621
1622      creationDate = tmpCreationDateString;
1623      return creationDate;
1624    };
1625
1626    var getCreationDate = API.__private__.getCreationDate = function (type) {
1627      var result = creationDate;
1628
1629      if (type === "jsDate") {
1630        result = convertPDFDateToDate(creationDate);
1631      }
1632
1633      return result;
1634    };
1635    /**
1636     * @name setCreationDate
1637     * @memberof jsPDF#
1638     * @function
1639     * @instance
1640     * @param {Object} date
1641     * @returns {jsPDF}
1642     */
1643
1644
1645    API.setCreationDate = function (date) {
1646      setCreationDate(date);
1647      return this;
1648    };
1649    /**
1650     * @name getCreationDate
1651     * @memberof jsPDF#
1652     * @function
1653     * @instance
1654     * @param {Object} type
1655     * @returns {Object}
1656     */
1657
1658
1659    API.getCreationDate = function (type) {
1660      return getCreationDate(type);
1661    };
1662
1663    var padd2 = API.__private__.padd2 = function (number) {
1664      return ("0" + parseInt(number)).slice(-2);
1665    };
1666
1667    var padd2Hex = API.__private__.padd2Hex = function (hexString) {
1668      hexString = hexString.toString();
1669      return ("00" + hexString).substr(hexString.length);
1670    };
1671
1672    var objectNumber = 0; // 'n' Current object number
1673
1674    var offsets = []; // List of offsets. Activated and reset by buildDocument(). Pupulated by various calls buildDocument makes.
1675
1676    var content = [];
1677    var contentLength = 0;
1678    var additionalObjects = [];
1679    var pages = [];
1680    var currentPage;
1681    var hasCustomDestination = false;
1682    var outputDestination = content;
1683
1684    var resetDocument = function resetDocument() {
1685      //reset fields relevant for objectNumber generation and xref.
1686      objectNumber = 0;
1687      contentLength = 0;
1688      content = [];
1689      offsets = [];
1690      additionalObjects = [];
1691      rootDictionaryObjId = newObjectDeferred();
1692      resourceDictionaryObjId = newObjectDeferred();
1693    };
1694
1695    API.__private__.setCustomOutputDestination = function (destination) {
1696      hasCustomDestination = true;
1697      outputDestination = destination;
1698    };
1699
1700    var setOutputDestination = function setOutputDestination(destination) {
1701      if (!hasCustomDestination) {
1702        outputDestination = destination;
1703      }
1704    };
1705
1706    API.__private__.resetCustomOutputDestination = function () {
1707      hasCustomDestination = false;
1708      outputDestination = content;
1709    };
1710
1711    var out = API.__private__.out = function (string) {
1712      string = string.toString();
1713      contentLength += string.length + 1;
1714      outputDestination.push(string);
1715      return outputDestination;
1716    };
1717
1718    var write = API.__private__.write = function (value) {
1719      return out(arguments.length === 1 ? value.toString() : Array.prototype.join.call(arguments, " "));
1720    };
1721
1722    var getArrayBuffer = API.__private__.getArrayBuffer = function (data) {
1723      var len = data.length,
1724          ab = new ArrayBuffer(len),
1725          u8 = new Uint8Array(ab);
1726
1727      while (len--) {
1728        u8[len] = data.charCodeAt(len);
1729      }
1730
1731      return ab;
1732    };
1733
1734    var standardFonts = [["Helvetica", "helvetica", "normal", "WinAnsiEncoding"], ["Helvetica-Bold", "helvetica", "bold", "WinAnsiEncoding"], ["Helvetica-Oblique", "helvetica", "italic", "WinAnsiEncoding"], ["Helvetica-BoldOblique", "helvetica", "bolditalic", "WinAnsiEncoding"], ["Courier", "courier", "normal", "WinAnsiEncoding"], ["Courier-Bold", "courier", "bold", "WinAnsiEncoding"], ["Courier-Oblique", "courier", "italic", "WinAnsiEncoding"], ["Courier-BoldOblique", "courier", "bolditalic", "WinAnsiEncoding"], ["Times-Roman", "times", "normal", "WinAnsiEncoding"], ["Times-Bold", "times", "bold", "WinAnsiEncoding"], ["Times-Italic", "times", "italic", "WinAnsiEncoding"], ["Times-BoldItalic", "times", "bolditalic", "WinAnsiEncoding"], ["ZapfDingbats", "zapfdingbats", "normal", null], ["Symbol", "symbol", "normal", null]];
1735
1736    API.__private__.getStandardFonts = function () {
1737      return standardFonts;
1738    };
1739
1740    var activeFontSize = options.fontSize || 16;
1741    /**
1742     * Sets font size for upcoming text elements.
1743     *
1744     * @param {number} size Font size in points.
1745     * @function
1746     * @instance
1747     * @returns {jsPDF}
1748     * @memberof jsPDF#
1749     * @name setFontSize
1750     */
1751
1752    API.__private__.setFontSize = API.setFontSize = function (size) {
1753      if (apiMode === ApiMode.ADVANCED) {
1754        activeFontSize = size / scaleFactor;
1755      } else {
1756        activeFontSize = size;
1757      }
1758
1759      return this;
1760    };
1761    /**
1762     * Gets the fontsize for upcoming text elements.
1763     *
1764     * @function
1765     * @instance
1766     * @returns {number}
1767     * @memberof jsPDF#
1768     * @name getFontSize
1769     */
1770
1771
1772    var getFontSize = API.__private__.getFontSize = API.getFontSize = function () {
1773      if (apiMode === ApiMode.COMPAT) {
1774        return activeFontSize;
1775      } else {
1776        return activeFontSize * scaleFactor;
1777      }
1778    };
1779
1780    var R2L = options.R2L || false;
1781    /**
1782     * Set value of R2L functionality.
1783     *
1784     * @param {boolean} value
1785     * @function
1786     * @instance
1787     * @returns {jsPDF} jsPDF-instance
1788     * @memberof jsPDF#
1789     * @name setR2L
1790     */
1791
1792    API.__private__.setR2L = API.setR2L = function (value) {
1793      R2L = value;
1794      return this;
1795    };
1796    /**
1797     * Get value of R2L functionality.
1798     *
1799     * @function
1800     * @instance
1801     * @returns {boolean} jsPDF-instance
1802     * @memberof jsPDF#
1803     * @name getR2L
1804     */
1805
1806
1807    API.__private__.getR2L = API.getR2L = function () {
1808      return R2L;
1809    };
1810
1811    var zoomMode; // default: 1;
1812
1813    var setZoomMode = API.__private__.setZoomMode = function (zoom) {
1814      var validZoomModes = [undefined, null, "fullwidth", "fullheight", "fullpage", "original"];
1815
1816      if (/^(?:\d+\.\d*|\d*\.\d+|\d+)%$/.test(zoom)) {
1817        zoomMode = zoom;
1818      } else if (!isNaN(zoom)) {
1819        zoomMode = parseInt(zoom, 10);
1820      } else if (validZoomModes.indexOf(zoom) !== -1) {
1821        zoomMode = zoom;
1822      } else {
1823        throw new Error('zoom must be Integer (e.g. 2), a percentage Value (e.g. 300%) or fullwidth, fullheight, fullpage, original. "' + zoom + '" is not recognized.');
1824      }
1825    };
1826
1827    API.__private__.getZoomMode = function () {
1828      return zoomMode;
1829    };
1830
1831    var pageMode; // default: 'UseOutlines';
1832
1833    var setPageMode = API.__private__.setPageMode = function (pmode) {
1834      var validPageModes = [undefined, null, "UseNone", "UseOutlines", "UseThumbs", "FullScreen"];
1835
1836      if (validPageModes.indexOf(pmode) == -1) {
1837        throw new Error('Page mode must be one of UseNone, UseOutlines, UseThumbs, or FullScreen. "' + pmode + '" is not recognized.');
1838      }
1839
1840      pageMode = pmode;
1841    };
1842
1843    API.__private__.getPageMode = function () {
1844      return pageMode;
1845    };
1846
1847    var layoutMode; // default: 'continuous';
1848
1849    var setLayoutMode = API.__private__.setLayoutMode = function (layout) {
1850      var validLayoutModes = [undefined, null, "continuous", "single", "twoleft", "tworight", "two"];
1851
1852      if (validLayoutModes.indexOf(layout) == -1) {
1853        throw new Error('Layout mode must be one of continuous, single, twoleft, tworight. "' + layout + '" is not recognized.');
1854      }
1855
1856      layoutMode = layout;
1857    };
1858
1859    API.__private__.getLayoutMode = function () {
1860      return layoutMode;
1861    };
1862    /**
1863     * Set the display mode options of the page like zoom and layout.
1864     *
1865     * @name setDisplayMode
1866     * @memberof jsPDF#
1867     * @function
1868     * @instance
1869     * @param {integer|String} zoom   You can pass an integer or percentage as
1870     * a string. 2 will scale the document up 2x, '200%' will scale up by the
1871     * same amount. You can also set it to 'fullwidth', 'fullheight',
1872     * 'fullpage', or 'original'.
1873     *
1874     * Only certain PDF readers support this, such as Adobe Acrobat.
1875     *
1876     * @param {string} layout Layout mode can be: 'continuous' - this is the
1877     * default continuous scroll. 'single' - the single page mode only shows one
1878     * page at a time. 'twoleft' - two column left mode, first page starts on
1879     * the left, and 'tworight' - pages are laid out in two columns, with the
1880     * first page on the right. This would be used for books.
1881     * @param {string} pmode 'UseOutlines' - it shows the
1882     * outline of the document on the left. 'UseThumbs' - shows thumbnails along
1883     * the left. 'FullScreen' - prompts the user to enter fullscreen mode.
1884     *
1885     * @returns {jsPDF}
1886     */
1887
1888
1889    API.__private__.setDisplayMode = API.setDisplayMode = function (zoom, layout, pmode) {
1890      setZoomMode(zoom);
1891      setLayoutMode(layout);
1892      setPageMode(pmode);
1893      return this;
1894    };
1895
1896    var documentProperties = {
1897      title: "",
1898      subject: "",
1899      author: "",
1900      keywords: "",
1901      creator: ""
1902    };
1903
1904    API.__private__.getDocumentProperty = function (key) {
1905      if (Object.keys(documentProperties).indexOf(key) === -1) {
1906        throw new Error("Invalid argument passed to jsPDF.getDocumentProperty");
1907      }
1908
1909      return documentProperties[key];
1910    };
1911
1912    API.__private__.getDocumentProperties = function () {
1913      return documentProperties;
1914    };
1915    /**
1916     * Adds a properties to the PDF document.
1917     *
1918     * @param {Object} A property_name-to-property_value object structure.
1919     * @function
1920     * @instance
1921     * @returns {jsPDF}
1922     * @memberof jsPDF#
1923     * @name setDocumentProperties
1924     */
1925
1926
1927    API.__private__.setDocumentProperties = API.setProperties = API.setDocumentProperties = function (properties) {
1928      // copying only those properties we can render.
1929      for (var property in documentProperties) {
1930        if (documentProperties.hasOwnProperty(property) && properties[property]) {
1931          documentProperties[property] = properties[property];
1932        }
1933      }
1934
1935      return this;
1936    };
1937
1938    API.__private__.setDocumentProperty = function (key, value) {
1939      if (Object.keys(documentProperties).indexOf(key) === -1) {
1940        throw new Error("Invalid arguments passed to jsPDF.setDocumentProperty");
1941      }
1942
1943      return documentProperties[key] = value;
1944    };
1945
1946    var fonts = {}; // collection of font objects, where key is fontKey - a dynamically created label for a given font.
1947
1948    var fontmap = {}; // mapping structure fontName > fontStyle > font key - performance layer. See addFont()
1949
1950    var activeFontKey; // will be string representing the KEY of the font as combination of fontName + fontStyle
1951
1952    var fontStateStack = []; //
1953
1954    var patterns = {}; // collection of pattern objects
1955
1956    var patternMap = {}; // see fonts
1957
1958    var gStates = {}; // collection of graphic state objects
1959
1960    var gStatesMap = {}; // see fonts
1961
1962    var activeGState = null;
1963    var scaleFactor; // Scale factor
1964
1965    var page = 0;
1966    var pagesContext = [];
1967    var events = new PubSub(API);
1968    var hotfixes = options.hotfixes || [];
1969    var renderTargets = {};
1970    var renderTargetMap = {};
1971    var renderTargetStack = [];
1972    var pageX;
1973    var pageY;
1974    var pageMatrix; // only used for FormObjects
1975
1976    /**
1977     * A matrix object for 2D homogenous transformations: <br>
1978     * | a b 0 | <br>
1979     * | c d 0 | <br>
1980     * | e f 1 | <br>
1981     * pdf multiplies matrices righthand: v' = v x m1 x m2 x ...
1982     *
1983     * @class
1984     * @name Matrix
1985     * @param {number} sx
1986     * @param {number} shy
1987     * @param {number} shx
1988     * @param {number} sy
1989     * @param {number} tx
1990     * @param {number} ty
1991     * @constructor
1992     */
1993
1994    var Matrix = function Matrix(sx, shy, shx, sy, tx, ty) {
1995      if (!(this instanceof Matrix)) {
1996        return new Matrix(sx, shy, shx, sy, tx, ty);
1997      }
1998
1999      if (isNaN(sx)) sx = 1;
2000      if (isNaN(shy)) shy = 0;
2001      if (isNaN(shx)) shx = 0;
2002      if (isNaN(sy)) sy = 1;
2003      if (isNaN(tx)) tx = 0;
2004      if (isNaN(ty)) ty = 0;
2005      this._matrix = [sx, shy, shx, sy, tx, ty];
2006    };
2007    /**
2008     * @name sx
2009     * @memberof Matrix#
2010     */
2011
2012
2013    Object.defineProperty(Matrix.prototype, "sx", {
2014      get: function get() {
2015        return this._matrix[0];
2016      },
2017      set: function set(value) {
2018        this._matrix[0] = value;
2019      }
2020    });
2021    /**
2022     * @name shy
2023     * @memberof Matrix#
2024     */
2025
2026    Object.defineProperty(Matrix.prototype, "shy", {
2027      get: function get() {
2028        return this._matrix[1];
2029      },
2030      set: function set(value) {
2031        this._matrix[1] = value;
2032      }
2033    });
2034    /**
2035     * @name shx
2036     * @memberof Matrix#
2037     */
2038
2039    Object.defineProperty(Matrix.prototype, "shx", {
2040      get: function get() {
2041        return this._matrix[2];
2042      },
2043      set: function set(value) {
2044        this._matrix[2] = value;
2045      }
2046    });
2047    /**
2048     * @name sy
2049     * @memberof Matrix#
2050     */
2051
2052    Object.defineProperty(Matrix.prototype, "sy", {
2053      get: function get() {
2054        return this._matrix[3];
2055      },
2056      set: function set(value) {
2057        this._matrix[3] = value;
2058      }
2059    });
2060    /**
2061     * @name tx
2062     * @memberof Matrix#
2063     */
2064
2065    Object.defineProperty(Matrix.prototype, "tx", {
2066      get: function get() {
2067        return this._matrix[4];
2068      },
2069      set: function set(value) {
2070        this._matrix[4] = value;
2071      }
2072    });
2073    /**
2074     * @name ty
2075     * @memberof Matrix#
2076     */
2077
2078    Object.defineProperty(Matrix.prototype, "ty", {
2079      get: function get() {
2080        return this._matrix[5];
2081      },
2082      set: function set(value) {
2083        this._matrix[5] = value;
2084      }
2085    });
2086    Object.defineProperty(Matrix.prototype, "a", {
2087      get: function get() {
2088        return this._matrix[0];
2089      },
2090      set: function set(value) {
2091        this._matrix[0] = value;
2092      }
2093    });
2094    Object.defineProperty(Matrix.prototype, "b", {
2095      get: function get() {
2096        return this._matrix[1];
2097      },
2098      set: function set(value) {
2099        this._matrix[1] = value;
2100      }
2101    });
2102    Object.defineProperty(Matrix.prototype, "c", {
2103      get: function get() {
2104        return this._matrix[2];
2105      },
2106      set: function set(value) {
2107        this._matrix[2] = value;
2108      }
2109    });
2110    Object.defineProperty(Matrix.prototype, "d", {
2111      get: function get() {
2112        return this._matrix[3];
2113      },
2114      set: function set(value) {
2115        this._matrix[3] = value;
2116      }
2117    });
2118    Object.defineProperty(Matrix.prototype, "e", {
2119      get: function get() {
2120        return this._matrix[4];
2121      },
2122      set: function set(value) {
2123        this._matrix[4] = value;
2124      }
2125    });
2126    Object.defineProperty(Matrix.prototype, "f", {
2127      get: function get() {
2128        return this._matrix[5];
2129      },
2130      set: function set(value) {
2131        this._matrix[5] = value;
2132      }
2133    });
2134    /**
2135     * @name rotation
2136     * @memberof Matrix#
2137     */
2138
2139    Object.defineProperty(Matrix.prototype, "rotation", {
2140      get: function get() {
2141        return Math.atan2(this.shx, this.sx);
2142      }
2143    });
2144    /**
2145     * @name scaleX
2146     * @memberof Matrix#
2147     */
2148
2149    Object.defineProperty(Matrix.prototype, "scaleX", {
2150      get: function get() {
2151        return this.decompose().scale.sx;
2152      }
2153    });
2154    /**
2155     * @name scaleY
2156     * @memberof Matrix#
2157     */
2158
2159    Object.defineProperty(Matrix.prototype, "scaleY", {
2160      get: function get() {
2161        return this.decompose().scale.sy;
2162      }
2163    });
2164    /**
2165     * @name isIdentity
2166     * @memberof Matrix#
2167     */
2168
2169    Object.defineProperty(Matrix.prototype, "isIdentity", {
2170      get: function get() {
2171        if (this.sx !== 1) {
2172          return false;
2173        }
2174
2175        if (this.shy !== 0) {
2176          return false;
2177        }
2178
2179        if (this.shx !== 0) {
2180          return false;
2181        }
2182
2183        if (this.sy !== 1) {
2184          return false;
2185        }
2186
2187        if (this.tx !== 0) {
2188          return false;
2189        }
2190
2191        if (this.ty !== 0) {
2192          return false;
2193        }
2194
2195        return true;
2196      }
2197    });
2198    /**
2199     * Join the Matrix Values to a String
2200     *
2201     * @function join
2202     * @param {string} separator Specifies a string to separate each pair of adjacent elements of the array. The separator is converted to a string if necessary. If omitted, the array elements are separated with a comma (","). If separator is an empty string, all elements are joined without any characters in between them.
2203     * @returns {string} A string with all array elements joined.
2204     * @memberof Matrix#
2205     */
2206
2207    Matrix.prototype.join = function (separator) {
2208      return [this.sx, this.shy, this.shx, this.sy, this.tx, this.ty].map(hpf).join(separator);
2209    };
2210    /**
2211     * Multiply the matrix with given Matrix
2212     *
2213     * @function multiply
2214     * @param matrix
2215     * @returns {Matrix}
2216     * @memberof Matrix#
2217     */
2218
2219
2220    Matrix.prototype.multiply = function (matrix) {
2221      var sx = matrix.sx * this.sx + matrix.shy * this.shx;
2222      var shy = matrix.sx * this.shy + matrix.shy * this.sy;
2223      var shx = matrix.shx * this.sx + matrix.sy * this.shx;
2224      var sy = matrix.shx * this.shy + matrix.sy * this.sy;
2225      var tx = matrix.tx * this.sx + matrix.ty * this.shx + this.tx;
2226      var ty = matrix.tx * this.shy + matrix.ty * this.sy + this.ty;
2227      return new Matrix(sx, shy, shx, sy, tx, ty);
2228    };
2229    /**
2230     * @function decompose
2231     * @memberof Matrix#
2232     */
2233
2234
2235    Matrix.prototype.decompose = function () {
2236      var a = this.sx;
2237      var b = this.shy;
2238      var c = this.shx;
2239      var d = this.sy;
2240      var e = this.tx;
2241      var f = this.ty;
2242      var scaleX = Math.sqrt(a * a + b * b);
2243      a /= scaleX;
2244      b /= scaleX;
2245      var shear = a * c + b * d;
2246      c -= a * shear;
2247      d -= b * shear;
2248      var scaleY = Math.sqrt(c * c + d * d);
2249      c /= scaleY;
2250      d /= scaleY;
2251      shear /= scaleY;
2252
2253      if (a * d < b * c) {
2254        a = -a;
2255        b = -b;
2256        shear = -shear;
2257        scaleX = -scaleX;
2258      }
2259
2260      return {
2261        scale: new Matrix(scaleX, 0, 0, scaleY, 0, 0),
2262        translate: new Matrix(1, 0, 0, 1, e, f),
2263        rotate: new Matrix(a, b, -b, a, 0, 0),
2264        skew: new Matrix(1, 0, shear, 1, 0, 0)
2265      };
2266    };
2267    /**
2268     * @function toString
2269     * @memberof Matrix#
2270     */
2271
2272
2273    Matrix.prototype.toString = function (parmPrecision) {
2274      return this.join(" ");
2275    };
2276    /**
2277     * @function inversed
2278     * @memberof Matrix#
2279     */
2280
2281
2282    Matrix.prototype.inversed = function () {
2283      var a = this.sx,
2284          b = this.shy,
2285          c = this.shx,
2286          d = this.sy,
2287          e = this.tx,
2288          f = this.ty;
2289      var quot = 1 / (a * d - b * c);
2290      var aInv = d * quot;
2291      var bInv = -b * quot;
2292      var cInv = -c * quot;
2293      var dInv = a * quot;
2294      var eInv = -aInv * e - cInv * f;
2295      var fInv = -bInv * e - dInv * f;
2296      return new Matrix(aInv, bInv, cInv, dInv, eInv, fInv);
2297    };
2298    /**
2299     * @function applyToPoint
2300     * @memberof Matrix#
2301     */
2302
2303
2304    Matrix.prototype.applyToPoint = function (pt) {
2305      var x = pt.x * this.sx + pt.y * this.shx + this.tx;
2306      var y = pt.x * this.shy + pt.y * this.sy + this.ty;
2307      return new Point(x, y);
2308    };
2309    /**
2310     * @function applyToRectangle
2311     * @memberof Matrix#
2312     */
2313
2314
2315    Matrix.prototype.applyToRectangle = function (rect) {
2316      var pt1 = this.applyToPoint(rect);
2317      var pt2 = this.applyToPoint(new Point(rect.x + rect.w, rect.y + rect.h));
2318      return new Rectangle(pt1.x, pt1.y, pt2.x - pt1.x, pt2.y - pt1.y);
2319    };
2320    /**
2321     * Clone the Matrix
2322     *
2323     * @function clone
2324     * @memberof Matrix#
2325     * @name clone
2326     * @instance
2327     */
2328
2329
2330    Matrix.prototype.clone = function () {
2331      var sx = this.sx;
2332      var shy = this.shy;
2333      var shx = this.shx;
2334      var sy = this.sy;
2335      var tx = this.tx;
2336      var ty = this.ty;
2337      return new Matrix(sx, shy, shx, sy, tx, ty);
2338    };
2339
2340    API.Matrix = Matrix;
2341    /**
2342     * Multiplies two matrices. (see {@link Matrix})
2343     * @param {Matrix} m1
2344     * @param {Matrix} m2
2345     * @memberof jsPDF#
2346     * @name matrixMult
2347     */
2348
2349    var matrixMult = API.matrixMult = function (m1, m2) {
2350      return m2.multiply(m1);
2351    };
2352    /**
2353     * The identity matrix (equivalent to new Matrix(1, 0, 0, 1, 0, 0)).
2354     * @type {Matrix}
2355     * @memberof! jsPDF#
2356     * @name identityMatrix
2357     */
2358
2359
2360    var identityMatrix = new Matrix(1, 0, 0, 1, 0, 0);
2361    API.unitMatrix = API.identityMatrix = identityMatrix;
2362    /**
2363     * Adds a new pattern for later use.
2364     * @param {String} key The key by it can be referenced later. The keys must be unique!
2365     * @param {API.Pattern} pattern The pattern
2366     */
2367
2368    var addPattern = function addPattern(key, pattern) {
2369      // only add it if it is not already present (the keys provided by the user must be unique!)
2370      if (patternMap[key]) return;
2371      var prefix = pattern instanceof ShadingPattern ? "Sh" : "P";
2372      var patternKey = prefix + (Object.keys(patterns).length + 1).toString(10);
2373      pattern.id = patternKey;
2374      patternMap[key] = patternKey;
2375      patterns[patternKey] = pattern;
2376      events.publish("addPattern", pattern);
2377    };
2378    /**
2379     * A pattern describing a shading pattern.
2380     *
2381     * Only available in "advanced" API mode.
2382     *
2383     * @param {String} type One of "axial" or "radial"
2384     * @param {Array<Number>} coords Either [x1, y1, x2, y2] for "axial" type describing the two interpolation points
2385     * or [x1, y1, r, x2, y2, r2] for "radial" describing inner and the outer circle.
2386     * @param {Array<Object>} colors An array of objects with the fields "offset" and "color". "offset" describes
2387     * the offset in parameter space [0, 1]. "color" is an array of length 3 describing RGB values in [0, 255].
2388     * @param {GState=} gState An additional graphics state that gets applied to the pattern (optional).
2389     * @param {Matrix=} matrix A matrix that describes the transformation between the pattern coordinate system
2390     * and the use coordinate system (optional).
2391     * @constructor
2392     * @extends API.Pattern
2393     */
2394
2395
2396    API.ShadingPattern = ShadingPattern;
2397    /**
2398     * A PDF Tiling pattern.
2399     *
2400     * Only available in "advanced" API mode.
2401     *
2402     * @param {Array.<Number>} boundingBox The bounding box at which one pattern cell gets clipped.
2403     * @param {Number} xStep Horizontal spacing between pattern cells.
2404     * @param {Number} yStep Vertical spacing between pattern cells.
2405     * @param {API.GState=} gState An additional graphics state that gets applied to the pattern (optional).
2406     * @param {Matrix=} matrix A matrix that describes the transformation between the pattern coordinate system
2407     * and the use coordinate system (optional).
2408     * @constructor
2409     * @extends API.Pattern
2410     */
2411
2412    API.TilingPattern = TilingPattern;
2413    /**
2414     * Adds a new {@link API.ShadingPattern} for later use. Only available in "advanced" API mode.
2415     * @param {String} key
2416     * @param {Pattern} pattern
2417     * @function
2418     * @returns {jsPDF}
2419     * @memberof jsPDF#
2420     * @name addPattern
2421     */
2422
2423    API.addShadingPattern = function (key, pattern) {
2424      advancedApiModeTrap("addShadingPattern()");
2425      addPattern(key, pattern);
2426      return this;
2427    };
2428    /**
2429     * Begins a new tiling pattern. All subsequent render calls are drawn to this pattern until {@link API.endTilingPattern}
2430     * gets called. Only available in "advanced" API mode.
2431     * @param {API.Pattern} pattern
2432     * @memberof jsPDF#
2433     * @name beginTilingPattern
2434     */
2435
2436
2437    API.beginTilingPattern = function (pattern) {
2438      advancedApiModeTrap("beginTilingPattern()");
2439      beginNewRenderTarget(pattern.boundingBox[0], pattern.boundingBox[1], pattern.boundingBox[2] - pattern.boundingBox[0], pattern.boundingBox[3] - pattern.boundingBox[1], pattern.matrix);
2440    };
2441    /**
2442     * Ends a tiling pattern and sets the render target to the one active before {@link API.beginTilingPattern} has been called.
2443     *
2444     * Only available in "advanced" API mode.
2445     *
2446     * @param {string} key A unique key that is used to reference this pattern at later use.
2447     * @param {API.Pattern} pattern The pattern to end.
2448     * @memberof jsPDF#
2449     * @name endTilingPattern
2450     */
2451
2452
2453    API.endTilingPattern = function (key, pattern) {
2454      advancedApiModeTrap("endTilingPattern()"); // retrieve the stream
2455
2456      pattern.stream = pages[currentPage].join("\n");
2457      addPattern(key, pattern);
2458      events.publish("endTilingPattern", pattern); // restore state from stack
2459
2460      renderTargetStack.pop().restore();
2461    };
2462
2463    var newObject = API.__private__.newObject = function () {
2464      var oid = newObjectDeferred();
2465      newObjectDeferredBegin(oid, true);
2466      return oid;
2467    }; // Does not output the object.  The caller must call newObjectDeferredBegin(oid) before outputing any data
2468
2469
2470    var newObjectDeferred = API.__private__.newObjectDeferred = function () {
2471      objectNumber++;
2472
2473      offsets[objectNumber] = function () {
2474        return contentLength;
2475      };
2476
2477      return objectNumber;
2478    };
2479
2480    var newObjectDeferredBegin = function newObjectDeferredBegin(oid, doOutput) {
2481      doOutput = typeof doOutput === "boolean" ? doOutput : false;
2482      offsets[oid] = contentLength;
2483
2484      if (doOutput) {
2485        out(oid + " 0 obj");
2486      }
2487
2488      return oid;
2489    }; // Does not output the object until after the pages have been output.
2490    // Returns an object containing the objectId and content.
2491    // All pages have been added so the object ID can be estimated to start right after.
2492    // This does not modify the current objectNumber;  It must be updated after the newObjects are output.
2493
2494
2495    var newAdditionalObject = API.__private__.newAdditionalObject = function () {
2496      var objId = newObjectDeferred();
2497      var obj = {
2498        objId: objId,
2499        content: ""
2500      };
2501      additionalObjects.push(obj);
2502      return obj;
2503    };
2504
2505    var rootDictionaryObjId = newObjectDeferred();
2506    var resourceDictionaryObjId = newObjectDeferred(); /////////////////////
2507    // Private functions
2508    /////////////////////
2509
2510    var decodeColorString = API.__private__.decodeColorString = function (color) {
2511      var colorEncoded = color.split(" ");
2512
2513      if (colorEncoded.length === 2 && (colorEncoded[1] === "g" || colorEncoded[1] === "G")) {
2514        // convert grayscale value to rgb so that it can be converted to hex for consistency
2515        var floatVal = parseFloat(colorEncoded[0]);
2516        colorEncoded = [floatVal, floatVal, floatVal, "r"];
2517      } else if (colorEncoded.length === 5 && (colorEncoded[4] === "k" || colorEncoded[4] === "K")) {
2518        // convert CMYK values to rbg so that it can be converted to hex for consistency
2519        var red = (1.0 - colorEncoded[0]) * (1.0 - colorEncoded[3]);
2520        var green = (1.0 - colorEncoded[1]) * (1.0 - colorEncoded[3]);
2521        var blue = (1.0 - colorEncoded[2]) * (1.0 - colorEncoded[3]);
2522        colorEncoded = [red, green, blue, "r"];
2523      }
2524
2525      var colorAsRGB = "#";
2526
2527      for (var i = 0; i < 3; i++) {
2528        colorAsRGB += ("0" + Math.floor(parseFloat(colorEncoded[i]) * 255).toString(16)).slice(-2);
2529      }
2530
2531      return colorAsRGB;
2532    };
2533
2534    var encodeColorString = API.__private__.encodeColorString = function (options) {
2535      var color;
2536
2537      if (typeof options === "string") {
2538        options = {
2539          ch1: options
2540        };
2541      }
2542
2543      var ch1 = options.ch1;
2544      var ch2 = options.ch2;
2545      var ch3 = options.ch3;
2546      var ch4 = options.ch4;
2547      var letterArray = options.pdfColorType === "draw" ? ["G", "RG", "K"] : ["g", "rg", "k"];
2548
2549      if (typeof ch1 === "string" && ch1.charAt(0) !== "#") {
2550        var rgbColor = new RGBColor(ch1);
2551
2552        if (rgbColor.ok) {
2553          ch1 = rgbColor.toHex();
2554        } else if (!/^\d*\.?\d*$/.test(ch1)) {
2555          throw new Error('Invalid color "' + ch1 + '" passed to jsPDF.encodeColorString.');
2556        }
2557      } //convert short rgb to long form
2558
2559
2560      if (typeof ch1 === "string" && /^#[0-9A-Fa-f]{3}$/.test(ch1)) {
2561        ch1 = "#" + ch1[1] + ch1[1] + ch1[2] + ch1[2] + ch1[3] + ch1[3];
2562      }
2563
2564      if (typeof ch1 === "string" && /^#[0-9A-Fa-f]{6}$/.test(ch1)) {
2565        var hex = parseInt(ch1.substr(1), 16);
2566        ch1 = hex >> 16 & 255;
2567        ch2 = hex >> 8 & 255;
2568        ch3 = hex & 255;
2569      }
2570
2571      if (typeof ch2 === "undefined" || typeof ch4 === "undefined" && ch1 === ch2 && ch2 === ch3) {
2572        // Gray color space.
2573        if (typeof ch1 === "string") {
2574          color = ch1 + " " + letterArray[0];
2575        } else {
2576          switch (options.precision) {
2577            case 2:
2578              color = f2(ch1 / 255) + " " + letterArray[0];
2579              break;
2580
2581            case 3:
2582            default:
2583              color = f3(ch1 / 255) + " " + letterArray[0];
2584          }
2585        }
2586      } else if (typeof ch4 === "undefined" || _typeof(ch4) === "object") {
2587        // assume RGBA
2588        if (ch4 && !isNaN(ch4.a)) {
2589          //TODO Implement transparency.
2590          //WORKAROUND use white for now, if transparent, otherwise handle as rgb
2591          if (ch4.a === 0) {
2592            color = ["1.", "1.", "1.", letterArray[1]].join(" ");
2593            return color;
2594          }
2595        } // assume RGB
2596
2597
2598        if (typeof ch1 === "string") {
2599          color = [ch1, ch2, ch3, letterArray[1]].join(" ");
2600        } else {
2601          switch (options.precision) {
2602            case 2:
2603              color = [f2(ch1 / 255), f2(ch2 / 255), f2(ch3 / 255), letterArray[1]].join(" ");
2604              break;
2605
2606            default:
2607            case 3:
2608              color = [f3(ch1 / 255), f3(ch2 / 255), f3(ch3 / 255), letterArray[1]].join(" ");
2609          }
2610        }
2611      } else {
2612        // assume CMYK
2613        if (typeof ch1 === "string") {
2614          color = [ch1, ch2, ch3, ch4, letterArray[2]].join(" ");
2615        } else {
2616          switch (options.precision) {
2617            case 2:
2618              color = [f2(ch1), f2(ch2), f2(ch3), f2(ch4), letterArray[2]].join(" ");
2619              break;
2620
2621            case 3:
2622            default:
2623              color = [f3(ch1), f3(ch2), f3(ch3), f3(ch4), letterArray[2]].join(" ");
2624          }
2625        }
2626      }
2627
2628      return color;
2629    };
2630
2631    var getFilters = API.__private__.getFilters = function () {
2632      return filters;
2633    };
2634
2635    var putStream = API.__private__.putStream = function (options) {
2636      options = options || {};
2637      var data = options.data || "";
2638      var filters = options.filters || getFilters();
2639      var alreadyAppliedFilters = options.alreadyAppliedFilters || [];
2640      var addLength1 = options.addLength1 || false;
2641      var valueOfLength1 = data.length;
2642      var objectId = options.objectId;
2643
2644      var encryptor = function encryptor(data) {
2645        return data;
2646      };
2647
2648      if (encryptionOptions !== null && typeof objectId == "undefined") {
2649        throw new Error("ObjectId must be passed to putStream for file encryption");
2650      }
2651
2652      if (encryptionOptions !== null) {
2653        encryptor = encryption.encryptor(objectId, 0);
2654      }
2655
2656      var processedData = {};
2657
2658      if (filters === true) {
2659        filters = ["FlateEncode"];
2660      }
2661
2662      var keyValues = options.additionalKeyValues || [];
2663
2664      if (typeof jsPDF.API.processDataByFilters !== "undefined") {
2665        processedData = jsPDF.API.processDataByFilters(data, filters);
2666      } else {
2667        processedData = {
2668          data: data,
2669          reverseChain: []
2670        };
2671      }
2672
2673      var filterAsString = processedData.reverseChain + (Array.isArray(alreadyAppliedFilters) ? alreadyAppliedFilters.join(" ") : alreadyAppliedFilters.toString());
2674
2675      if (processedData.data.length !== 0) {
2676        keyValues.push({
2677          key: "Length",
2678          value: processedData.data.length
2679        });
2680
2681        if (addLength1 === true) {
2682          keyValues.push({
2683            key: "Length1",
2684            value: valueOfLength1
2685          });
2686        }
2687      }
2688
2689      if (filterAsString.length != 0) {
2690        if (filterAsString.split("/").length - 1 === 1) {
2691          keyValues.push({
2692            key: "Filter",
2693            value: filterAsString
2694          });
2695        } else {
2696          keyValues.push({
2697            key: "Filter",
2698            value: "[" + filterAsString + "]"
2699          });
2700
2701          for (var j = 0; j < keyValues.length; j += 1) {
2702            if (keyValues[j].key === "DecodeParms") {
2703              var decodeParmsArray = [];
2704
2705              for (var i = 0; i < processedData.reverseChain.split("/").length - 1; i += 1) {
2706                decodeParmsArray.push("null");
2707              }
2708
2709              decodeParmsArray.push(keyValues[j].value);
2710              keyValues[j].value = "[" + decodeParmsArray.join(" ") + "]";
2711            }
2712          }
2713        }
2714      }
2715
2716      out("<<");
2717
2718      for (var k = 0; k < keyValues.length; k++) {
2719        out("/" + keyValues[k].key + " " + keyValues[k].value);
2720      }
2721
2722      out(">>");
2723
2724      if (processedData.data.length !== 0) {
2725        out("stream");
2726        out(encryptor(processedData.data));
2727        out("endstream");
2728      }
2729    };
2730
2731    var putPage = API.__private__.putPage = function (page) {
2732      var pageNumber = page.number;
2733      var data = page.data;
2734      var pageObjectNumber = page.objId;
2735      var pageContentsObjId = page.contentsObjId;
2736      newObjectDeferredBegin(pageObjectNumber, true);
2737      out("<</Type /Page");
2738      out("/Parent " + page.rootDictionaryObjId + " 0 R");
2739      out("/Resources " + page.resourceDictionaryObjId + " 0 R");
2740      out("/MediaBox [" + parseFloat(hpf(page.mediaBox.bottomLeftX)) + " " + parseFloat(hpf(page.mediaBox.bottomLeftY)) + " " + hpf(page.mediaBox.topRightX) + " " + hpf(page.mediaBox.topRightY) + "]");
2741
2742      if (page.cropBox !== null) {
2743        out("/CropBox [" + hpf(page.cropBox.bottomLeftX) + " " + hpf(page.cropBox.bottomLeftY) + " " + hpf(page.cropBox.topRightX) + " " + hpf(page.cropBox.topRightY) + "]");
2744      }
2745
2746      if (page.bleedBox !== null) {
2747        out("/BleedBox [" + hpf(page.bleedBox.bottomLeftX) + " " + hpf(page.bleedBox.bottomLeftY) + " " + hpf(page.bleedBox.topRightX) + " " + hpf(page.bleedBox.topRightY) + "]");
2748      }
2749
2750      if (page.trimBox !== null) {
2751        out("/TrimBox [" + hpf(page.trimBox.bottomLeftX) + " " + hpf(page.trimBox.bottomLeftY) + " " + hpf(page.trimBox.topRightX) + " " + hpf(page.trimBox.topRightY) + "]");
2752      }
2753
2754      if (page.artBox !== null) {
2755        out("/ArtBox [" + hpf(page.artBox.bottomLeftX) + " " + hpf(page.artBox.bottomLeftY) + " " + hpf(page.artBox.topRightX) + " " + hpf(page.artBox.topRightY) + "]");
2756      }
2757
2758      if (typeof page.userUnit === "number" && page.userUnit !== 1.0) {
2759        out("/UserUnit " + page.userUnit);
2760      }
2761
2762      events.publish("putPage", {
2763        objId: pageObjectNumber,
2764        pageContext: pagesContext[pageNumber],
2765        pageNumber: pageNumber,
2766        page: data
2767      });
2768      out("/Contents " + pageContentsObjId + " 0 R");
2769      out(">>");
2770      out("endobj"); // Page content
2771
2772      var pageContent = data.join("\n");
2773
2774      if (apiMode === ApiMode.ADVANCED) {
2775        // if the user forgot to switch back to COMPAT mode, we must balance the graphics stack again
2776        pageContent += "\nQ";
2777      }
2778
2779      newObjectDeferredBegin(pageContentsObjId, true);
2780      putStream({
2781        data: pageContent,
2782        filters: getFilters(),
2783        objectId: pageContentsObjId
2784      });
2785      out("endobj");
2786      return pageObjectNumber;
2787    };
2788
2789    var putPages = API.__private__.putPages = function () {
2790      var n,
2791          i,
2792          pageObjectNumbers = [];
2793
2794      for (n = 1; n <= page; n++) {
2795        pagesContext[n].objId = newObjectDeferred();
2796        pagesContext[n].contentsObjId = newObjectDeferred();
2797      }
2798
2799      for (n = 1; n <= page; n++) {
2800        pageObjectNumbers.push(putPage({
2801          number: n,
2802          data: pages[n],
2803          objId: pagesContext[n].objId,
2804          contentsObjId: pagesContext[n].contentsObjId,
2805          mediaBox: pagesContext[n].mediaBox,
2806          cropBox: pagesContext[n].cropBox,
2807          bleedBox: pagesContext[n].bleedBox,
2808          trimBox: pagesContext[n].trimBox,
2809          artBox: pagesContext[n].artBox,
2810          userUnit: pagesContext[n].userUnit,
2811          rootDictionaryObjId: rootDictionaryObjId,
2812          resourceDictionaryObjId: resourceDictionaryObjId
2813        }));
2814      }
2815
2816      newObjectDeferredBegin(rootDictionaryObjId, true);
2817      out("<</Type /Pages");
2818      var kids = "/Kids [";
2819
2820      for (i = 0; i < page; i++) {
2821        kids += pageObjectNumbers[i] + " 0 R ";
2822      }
2823
2824      out(kids + "]");
2825      out("/Count " + page);
2826      out(">>");
2827      out("endobj");
2828      events.publish("postPutPages");
2829    };
2830
2831    var putFont = function putFont(font) {
2832      events.publish("putFont", {
2833        font: font,
2834        out: out,
2835        newObject: newObject,
2836        putStream: putStream
2837      });
2838
2839      if (font.isAlreadyPutted !== true) {
2840        font.objectNumber = newObject();
2841        out("<<");
2842        out("/Type /Font");
2843        out("/BaseFont /" + toPDFName(font.postScriptName));
2844        out("/Subtype /Type1");
2845
2846        if (typeof font.encoding === "string") {
2847          out("/Encoding /" + font.encoding);
2848        }
2849
2850        out("/FirstChar 32");
2851        out("/LastChar 255");
2852        out(">>");
2853        out("endobj");
2854      }
2855    };
2856
2857    var putFonts = function putFonts() {
2858      for (var fontKey in fonts) {
2859        if (fonts.hasOwnProperty(fontKey)) {
2860          if (putOnlyUsedFonts === false || putOnlyUsedFonts === true && usedFonts.hasOwnProperty(fontKey)) {
2861            putFont(fonts[fontKey]);
2862          }
2863        }
2864      }
2865    };
2866
2867    var putXObject = function putXObject(xObject) {
2868      xObject.objectNumber = newObject();
2869      var options = [];
2870      options.push({
2871        key: "Type",
2872        value: "/XObject"
2873      });
2874      options.push({
2875        key: "Subtype",
2876        value: "/Form"
2877      });
2878      options.push({
2879        key: "BBox",
2880        value: "[" + [hpf(xObject.x), hpf(xObject.y), hpf(xObject.x + xObject.width), hpf(xObject.y + xObject.height)].join(" ") + "]"
2881      });
2882      options.push({
2883        key: "Matrix",
2884        value: "[" + xObject.matrix.toString() + "]"
2885      }); // TODO: /Resources
2886
2887      var stream = xObject.pages[1].join("\n");
2888      putStream({
2889        data: stream,
2890        additionalKeyValues: options,
2891        objectId: xObject.objectNumber
2892      });
2893      out("endobj");
2894    };
2895
2896    var putXObjects = function putXObjects() {
2897      for (var xObjectKey in renderTargets) {
2898        if (renderTargets.hasOwnProperty(xObjectKey)) {
2899          putXObject(renderTargets[xObjectKey]);
2900        }
2901      }
2902    };
2903
2904    var interpolateAndEncodeRGBStream = function interpolateAndEncodeRGBStream(colors, numberSamples) {
2905      var tValues = [];
2906      var t;
2907      var dT = 1.0 / (numberSamples - 1);
2908
2909      for (t = 0.0; t < 1.0; t += dT) {
2910        tValues.push(t);
2911      }
2912
2913      tValues.push(1.0); // add first and last control point if not present
2914
2915      if (colors[0].offset != 0.0) {
2916        var c0 = {
2917          offset: 0.0,
2918          color: colors[0].color
2919        };
2920        colors.unshift(c0);
2921      }
2922
2923      if (colors[colors.length - 1].offset != 1.0) {
2924        var c1 = {
2925          offset: 1.0,
2926          color: colors[colors.length - 1].color
2927        };
2928        colors.push(c1);
2929      }
2930
2931      var out = "";
2932      var index = 0;
2933
2934      for (var i = 0; i < tValues.length; i++) {
2935        t = tValues[i];
2936
2937        while (t > colors[index + 1].offset) {
2938          index++;
2939        }
2940
2941        var a = colors[index].offset;
2942        var b = colors[index + 1].offset;
2943        var d = (t - a) / (b - a);
2944        var aColor = colors[index].color;
2945        var bColor = colors[index + 1].color;
2946        out += padd2Hex(Math.round((1 - d) * aColor[0] + d * bColor[0]).toString(16)) + padd2Hex(Math.round((1 - d) * aColor[1] + d * bColor[1]).toString(16)) + padd2Hex(Math.round((1 - d) * aColor[2] + d * bColor[2]).toString(16));
2947      }
2948
2949      return out.trim();
2950    };
2951
2952    var putShadingPattern = function putShadingPattern(pattern, numberSamples) {
2953      /*
2954         Axial patterns shade between the two points specified in coords, radial patterns between the inner
2955         and outer circle.
2956         The user can specify an array (colors) that maps t-Values in [0, 1] to RGB colors. These are now
2957         interpolated to equidistant samples and written to pdf as a sample (type 0) function.
2958         */
2959      // The number of color samples that should be used to describe the shading.
2960      // The higher, the more accurate the gradient will be.
2961      numberSamples || (numberSamples = 21);
2962      var funcObjectNumber = newObject();
2963      var stream = interpolateAndEncodeRGBStream(pattern.colors, numberSamples);
2964      var options = [];
2965      options.push({
2966        key: "FunctionType",
2967        value: "0"
2968      });
2969      options.push({
2970        key: "Domain",
2971        value: "[0.0 1.0]"
2972      });
2973      options.push({
2974        key: "Size",
2975        value: "[" + numberSamples + "]"
2976      });
2977      options.push({
2978        key: "BitsPerSample",
2979        value: "8"
2980      });
2981      options.push({
2982        key: "Range",
2983        value: "[0.0 1.0 0.0 1.0 0.0 1.0]"
2984      });
2985      options.push({
2986        key: "Decode",
2987        value: "[0.0 1.0 0.0 1.0 0.0 1.0]"
2988      });
2989      putStream({
2990        data: stream,
2991        additionalKeyValues: options,
2992        alreadyAppliedFilters: ["/ASCIIHexDecode"],
2993        objectId: funcObjectNumber
2994      });
2995      out("endobj");
2996      pattern.objectNumber = newObject();
2997      out("<< /ShadingType " + pattern.type);
2998      out("/ColorSpace /DeviceRGB");
2999      var coords = "/Coords [" + hpf(parseFloat(pattern.coords[0])) + " " + // x1
3000      hpf(parseFloat(pattern.coords[1])) + " "; // y1
3001
3002      if (pattern.type === 2) {
3003        // axial
3004        coords += hpf(parseFloat(pattern.coords[2])) + " " + // x2
3005        hpf(parseFloat(pattern.coords[3])); // y2
3006      } else {
3007        // radial
3008        coords += hpf(parseFloat(pattern.coords[2])) + " " + // r1
3009        hpf(parseFloat(pattern.coords[3])) + " " + // x2
3010        hpf(parseFloat(pattern.coords[4])) + " " + // y2
3011        hpf(parseFloat(pattern.coords[5])); // r2
3012      }
3013
3014      coords += "]";
3015      out(coords);
3016
3017      if (pattern.matrix) {
3018        out("/Matrix [" + pattern.matrix.toString() + "]");
3019      }
3020
3021      out("/Function " + funcObjectNumber + " 0 R");
3022      out("/Extend [true true]");
3023      out(">>");
3024      out("endobj");
3025    };
3026
3027    var putTilingPattern = function putTilingPattern(pattern, deferredResourceDictionaryIds) {
3028      var resourcesObjectId = newObjectDeferred();
3029      var patternObjectId = newObject();
3030      deferredResourceDictionaryIds.push({
3031        resourcesOid: resourcesObjectId,
3032        objectOid: patternObjectId
3033      });
3034      pattern.objectNumber = patternObjectId;
3035      var options = [];
3036      options.push({
3037        key: "Type",
3038        value: "/Pattern"
3039      });
3040      options.push({
3041        key: "PatternType",
3042        value: "1"
3043      }); // tiling pattern
3044
3045      options.push({
3046        key: "PaintType",
3047        value: "1"
3048      }); // colored tiling pattern
3049
3050      options.push({
3051        key: "TilingType",
3052        value: "1"
3053      }); // constant spacing
3054
3055      options.push({
3056        key: "BBox",
3057        value: "[" + pattern.boundingBox.map(hpf).join(" ") + "]"
3058      });
3059      options.push({
3060        key: "XStep",
3061        value: hpf(pattern.xStep)
3062      });
3063      options.push({
3064        key: "YStep",
3065        value: hpf(pattern.yStep)
3066      });
3067      options.push({
3068        key: "Resources",
3069        value: resourcesObjectId + " 0 R"
3070      });
3071
3072      if (pattern.matrix) {
3073        options.push({
3074          key: "Matrix",
3075          value: "[" + pattern.matrix.toString() + "]"
3076        });
3077      }
3078
3079      putStream({
3080        data: pattern.stream,
3081        additionalKeyValues: options,
3082        objectId: pattern.objectNumber
3083      });
3084      out("endobj");
3085    };
3086
3087    var putPatterns = function putPatterns(deferredResourceDictionaryIds) {
3088      var patternKey;
3089
3090      for (patternKey in patterns) {
3091        if (patterns.hasOwnProperty(patternKey)) {
3092          if (patterns[patternKey] instanceof ShadingPattern) {
3093            putShadingPattern(patterns[patternKey]);
3094          } else if (patterns[patternKey] instanceof TilingPattern) {
3095            putTilingPattern(patterns[patternKey], deferredResourceDictionaryIds);
3096          }
3097        }
3098      }
3099    };
3100
3101    var putGState = function putGState(gState) {
3102      gState.objectNumber = newObject();
3103      out("<<");
3104
3105      for (var p in gState) {
3106        switch (p) {
3107          case "opacity":
3108            out("/ca " + f2(gState[p]));
3109            break;
3110
3111          case "stroke-opacity":
3112            out("/CA " + f2(gState[p]));
3113            break;
3114        }
3115      }
3116
3117      out(">>");
3118      out("endobj");
3119    };
3120
3121    var putGStates = function putGStates() {
3122      var gStateKey;
3123
3124      for (gStateKey in gStates) {
3125        if (gStates.hasOwnProperty(gStateKey)) {
3126          putGState(gStates[gStateKey]);
3127        }
3128      }
3129    };
3130
3131    var putXobjectDict = function putXobjectDict() {
3132      out("/XObject <<");
3133
3134      for (var xObjectKey in renderTargets) {
3135        if (renderTargets.hasOwnProperty(xObjectKey) && renderTargets[xObjectKey].objectNumber >= 0) {
3136          out("/" + xObjectKey + " " + renderTargets[xObjectKey].objectNumber + " 0 R");
3137        }
3138      } // Loop through images, or other data objects
3139
3140
3141      events.publish("putXobjectDict");
3142      out(">>");
3143    };
3144
3145    var putEncryptionDict = function putEncryptionDict() {
3146      encryption.oid = newObject();
3147      out("<<");
3148      out("/Filter /Standard");
3149      out("/V " + encryption.v);
3150      out("/R " + encryption.r);
3151      out("/U <" + encryption.toHexString(encryption.U) + ">");
3152      out("/O <" + encryption.toHexString(encryption.O) + ">");
3153      out("/P " + encryption.P);
3154      out(">>");
3155      out("endobj");
3156    };
3157
3158    var putFontDict = function putFontDict() {
3159      out("/Font <<");
3160
3161      for (var fontKey in fonts) {
3162        if (fonts.hasOwnProperty(fontKey)) {
3163          if (putOnlyUsedFonts === false || putOnlyUsedFonts === true && usedFonts.hasOwnProperty(fontKey)) {
3164            out("/" + fontKey + " " + fonts[fontKey].objectNumber + " 0 R");
3165          }
3166        }
3167      }
3168
3169      out(">>");
3170    };
3171
3172    var putShadingPatternDict = function putShadingPatternDict() {
3173      if (Object.keys(patterns).length > 0) {
3174        out("/Shading <<");
3175
3176        for (var patternKey in patterns) {
3177          if (patterns.hasOwnProperty(patternKey) && patterns[patternKey] instanceof ShadingPattern && patterns[patternKey].objectNumber >= 0) {
3178            out("/" + patternKey + " " + patterns[patternKey].objectNumber + " 0 R");
3179          }
3180        }
3181
3182        events.publish("putShadingPatternDict");
3183        out(">>");
3184      }
3185    };
3186
3187    var putTilingPatternDict = function putTilingPatternDict(objectOid) {
3188      if (Object.keys(patterns).length > 0) {
3189        out("/Pattern <<");
3190
3191        for (var patternKey in patterns) {
3192          if (patterns.hasOwnProperty(patternKey) && patterns[patternKey] instanceof API.TilingPattern && patterns[patternKey].objectNumber >= 0 && patterns[patternKey].objectNumber < objectOid // prevent cyclic dependencies
3193          ) {
3194              out("/" + patternKey + " " + patterns[patternKey].objectNumber + " 0 R");
3195            }
3196        }
3197
3198        events.publish("putTilingPatternDict");
3199        out(">>");
3200      }
3201    };
3202
3203    var putGStatesDict = function putGStatesDict() {
3204      if (Object.keys(gStates).length > 0) {
3205        var gStateKey;
3206        out("/ExtGState <<");
3207
3208        for (gStateKey in gStates) {
3209          if (gStates.hasOwnProperty(gStateKey) && gStates[gStateKey].objectNumber >= 0) {
3210            out("/" + gStateKey + " " + gStates[gStateKey].objectNumber + " 0 R");
3211          }
3212        }
3213
3214        events.publish("putGStateDict");
3215        out(">>");
3216      }
3217    };
3218
3219    var putResourceDictionary = function putResourceDictionary(objectIds) {
3220      newObjectDeferredBegin(objectIds.resourcesOid, true);
3221      out("<<");
3222      out("/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]");
3223      putFontDict();
3224      putShadingPatternDict();
3225      putTilingPatternDict(objectIds.objectOid);
3226      putGStatesDict();
3227      putXobjectDict();
3228      out(">>");
3229      out("endobj");
3230    };
3231
3232    var putResources = function putResources() {
3233      // FormObjects, Patterns etc. might use other FormObjects/Patterns/Images
3234      // which means their resource dictionaries must contain the already resolved
3235      // object ids. For this reason we defer the serialization of the resource
3236      // dicts until all objects have been serialized and have object ids.
3237      //
3238      // In order to prevent cyclic dependencies (which Adobe Reader doesn't like),
3239      // we only put all oids that are smaller than the oid of the object the
3240      // resource dict belongs to. This is correct behavior, since the streams
3241      // may only use other objects that have already been defined and thus appear
3242      // earlier in their respective collection.
3243      // Currently, this only affects tiling patterns, but a (more) correct
3244      // implementation of FormObjects would also define their own resource dicts.
3245      var deferredResourceDictionaryIds = [];
3246      putFonts();
3247      putGStates();
3248      putXObjects();
3249      putPatterns(deferredResourceDictionaryIds);
3250      events.publish("putResources");
3251      deferredResourceDictionaryIds.forEach(putResourceDictionary);
3252      putResourceDictionary({
3253        resourcesOid: resourceDictionaryObjId,
3254        objectOid: Number.MAX_SAFE_INTEGER // output all objects
3255
3256      });
3257      events.publish("postPutResources");
3258    };
3259
3260    var putAdditionalObjects = function putAdditionalObjects() {
3261      events.publish("putAdditionalObjects");
3262
3263      for (var i = 0; i < additionalObjects.length; i++) {
3264        var obj = additionalObjects[i];
3265        newObjectDeferredBegin(obj.objId, true);
3266        out(obj.content);
3267        out("endobj");
3268      }
3269
3270      events.publish("postPutAdditionalObjects");
3271    };
3272
3273    var addFontToFontDictionary = function addFontToFontDictionary(font) {
3274      fontmap[font.fontName] = fontmap[font.fontName] || {};
3275      fontmap[font.fontName][font.fontStyle] = font.id;
3276    };
3277
3278    var addFont = function addFont(postScriptName, fontName, fontStyle, encoding, isStandardFont) {
3279      var font = {
3280        id: "F" + (Object.keys(fonts).length + 1).toString(10),
3281        postScriptName: postScriptName,
3282        fontName: fontName,
3283        fontStyle: fontStyle,
3284        encoding: encoding,
3285        isStandardFont: isStandardFont || false,
3286        metadata: {}
3287      };
3288      events.publish("addFont", {
3289        font: font,
3290        instance: this
3291      });
3292      fonts[font.id] = font;
3293      addFontToFontDictionary(font);
3294      return font.id;
3295    };
3296
3297    var addFonts = function addFonts(arrayOfFonts) {
3298      for (var i = 0, l = standardFonts.length; i < l; i++) {
3299        var fontKey = addFont.call(this, arrayOfFonts[i][0], arrayOfFonts[i][1], arrayOfFonts[i][2], standardFonts[i][3], true);
3300
3301        if (putOnlyUsedFonts === false) {
3302          usedFonts[fontKey] = true;
3303        } // adding aliases for standard fonts, this time matching the capitalization
3304
3305
3306        var parts = arrayOfFonts[i][0].split("-");
3307        addFontToFontDictionary({
3308          id: fontKey,
3309          fontName: parts[0],
3310          fontStyle: parts[1] || ""
3311        });
3312      }
3313
3314      events.publish("addFonts", {
3315        fonts: fonts,
3316        dictionary: fontmap
3317      });
3318    };
3319
3320    var SAFE = function __safeCall(fn) {
3321      fn.foo = function __safeCallWrapper() {
3322        try {
3323          return fn.apply(this, arguments);
3324        } catch (e) {
3325          var stack = e.stack || "";
3326          if (~stack.indexOf(" at ")) stack = stack.split(" at ")[1];
3327          var m = "Error in function " + stack.split("\n")[0].split("<")[0] + ": " + e.message;
3328
3329          if (globalObject.console) {
3330            globalObject.console.error(m, e);
3331            if (globalObject.alert) alert(m);
3332          } else {
3333            throw new Error(m);
3334          }
3335        }
3336      };
3337
3338      fn.foo.bar = fn;
3339      return fn.foo;
3340    };
3341
3342    var to8bitStream = function to8bitStream(text, flags) {
3343      /**
3344       * PDF 1.3 spec:
3345       * "For text strings encoded in Unicode, the first two bytes must be 254 followed by
3346       * 255, representing the Unicode byte order marker, U+FEFF. (This sequence conflicts
3347       * with the PDFDocEncoding character sequence thorn ydieresis, which is unlikely
3348       * to be a meaningful beginning of a word or phrase.) The remainder of the
3349       * string consists of Unicode character codes, according to the UTF-16 encoding
3350       * specified in the Unicode standard, version 2.0. Commonly used Unicode values
3351       * are represented as 2 bytes per character, with the high-order byte appearing first
3352       * in the string."
3353       *
3354       * In other words, if there are chars in a string with char code above 255, we
3355       * recode the string to UCS2 BE - string doubles in length and BOM is prepended.
3356       *
3357       * HOWEVER!
3358       * Actual *content* (body) text (as opposed to strings used in document properties etc)
3359       * does NOT expect BOM. There, it is treated as a literal GID (Glyph ID)
3360       *
3361       * Because of Adobe's focus on "you subset your fonts!" you are not supposed to have
3362       * a font that maps directly Unicode (UCS2 / UTF16BE) code to font GID, but you could
3363       * fudge it with "Identity-H" encoding and custom CIDtoGID map that mimics Unicode
3364       * code page. There, however, all characters in the stream are treated as GIDs,
3365       * including BOM, which is the reason we need to skip BOM in content text (i.e. that
3366       * that is tied to a font).
3367       *
3368       * To signal this "special" PDFEscape / to8bitStream handling mode,
3369       * API.text() function sets (unless you overwrite it with manual values
3370       * given to API.text(.., flags) )
3371       * flags.autoencode = true
3372       * flags.noBOM = true
3373       *
3374       * ===================================================================================
3375       * `flags` properties relied upon:
3376       *   .sourceEncoding = string with encoding label.
3377       *                     "Unicode" by default. = encoding of the incoming text.
3378       *                     pass some non-existing encoding name
3379       *                     (ex: 'Do not touch my strings! I know what I am doing.')
3380       *                     to make encoding code skip the encoding step.
3381       *   .outputEncoding = Either valid PDF encoding name
3382       *                     (must be supported by jsPDF font metrics, otherwise no encoding)
3383       *                     or a JS object, where key = sourceCharCode, value = outputCharCode
3384       *                     missing keys will be treated as: sourceCharCode === outputCharCode
3385       *   .noBOM
3386       *       See comment higher above for explanation for why this is important
3387       *   .autoencode
3388       *       See comment higher above for explanation for why this is important
3389       */
3390      var i, l, sourceEncoding, encodingBlock, outputEncoding, newtext, isUnicode, ch, bch;
3391      flags = flags || {};
3392      sourceEncoding = flags.sourceEncoding || "Unicode";
3393      outputEncoding = flags.outputEncoding; // This 'encoding' section relies on font metrics format
3394      // attached to font objects by, among others,
3395      // "Willow Systems' standard_font_metrics plugin"
3396      // see jspdf.plugin.standard_font_metrics.js for format
3397      // of the font.metadata.encoding Object.
3398      // It should be something like
3399      //   .encoding = {'codePages':['WinANSI....'], 'WinANSI...':{code:code, ...}}
3400      //   .widths = {0:width, code:width, ..., 'fof':divisor}
3401      //   .kerning = {code:{previous_char_code:shift, ..., 'fof':-divisor},...}
3402
3403      if ((flags.autoencode || outputEncoding) && fonts[activeFontKey].metadata && fonts[activeFontKey].metadata[sourceEncoding] && fonts[activeFontKey].metadata[sourceEncoding].encoding) {
3404        encodingBlock = fonts[activeFontKey].metadata[sourceEncoding].encoding; // each font has default encoding. Some have it clearly defined.
3405
3406        if (!outputEncoding && fonts[activeFontKey].encoding) {
3407          outputEncoding = fonts[activeFontKey].encoding;
3408        } // Hmmm, the above did not work? Let's try again, in different place.
3409
3410
3411        if (!outputEncoding && encodingBlock.codePages) {
3412          outputEncoding = encodingBlock.codePages[0]; // let's say, first one is the default
3413        }
3414
3415        if (typeof outputEncoding === "string") {
3416          outputEncoding = encodingBlock[outputEncoding];
3417        } // we want output encoding to be a JS Object, where
3418        // key = sourceEncoding's character code and
3419        // value = outputEncoding's character code.
3420
3421
3422        if (outputEncoding) {
3423          isUnicode = false;
3424          newtext = [];
3425
3426          for (i = 0, l = text.length; i < l; i++) {
3427            ch = outputEncoding[text.charCodeAt(i)];
3428
3429            if (ch) {
3430              newtext.push(String.fromCharCode(ch));
3431            } else {
3432              newtext.push(text[i]);
3433            } // since we are looping over chars anyway, might as well
3434            // check for residual unicodeness
3435
3436
3437            if (newtext[i].charCodeAt(0) >> 8) {
3438              /* more than 255 */
3439              isUnicode = true;
3440            }
3441          }
3442
3443          text = newtext.join("");
3444        }
3445      }
3446
3447      i = text.length; // isUnicode may be set to false above. Hence the triple-equal to undefined
3448
3449      while (isUnicode === undefined && i !== 0) {
3450        if (text.charCodeAt(i - 1) >> 8) {
3451          /* more than 255 */
3452          isUnicode = true;
3453        }
3454
3455        i--;
3456      }
3457
3458      if (!isUnicode) {
3459        return text;
3460      }
3461
3462      newtext = flags.noBOM ? [] : [254, 255];
3463
3464      for (i = 0, l = text.length; i < l; i++) {
3465        ch = text.charCodeAt(i);
3466        bch = ch >> 8; // divide by 256
3467
3468        if (bch >> 8) {
3469          /* something left after dividing by 256 second time */
3470          throw new Error("Character at position " + i + " of string '" + text + "' exceeds 16bits. Cannot be encoded into UCS-2 BE");
3471        }
3472
3473        newtext.push(bch);
3474        newtext.push(ch - (bch << 8));
3475      }
3476
3477      return String.fromCharCode.apply(undefined, newtext);
3478    };
3479
3480    var pdfEscape = API.__private__.pdfEscape = API.pdfEscape = function (text, flags) {
3481      /**
3482       * Replace '/', '(', and ')' with pdf-safe versions
3483       *
3484       * Doing to8bitStream does NOT make this PDF display unicode text. For that
3485       * we also need to reference a unicode font and embed it - royal pain in the rear.
3486       *
3487       * There is still a benefit to to8bitStream - PDF simply cannot handle 16bit chars,
3488       * which JavaScript Strings are happy to provide. So, while we still cannot display
3489       * 2-byte characters property, at least CONDITIONALLY converting (entire string containing)
3490       * 16bit chars to (USC-2-BE) 2-bytes per char + BOM streams we ensure that entire PDF
3491       * is still parseable.
3492       * This will allow immediate support for unicode in document properties strings.
3493       */
3494      return to8bitStream(text, flags).replace(/\\/g, "\\\\").replace(/\(/g, "\\(").replace(/\)/g, "\\)");
3495    };
3496
3497    var beginPage = API.__private__.beginPage = function (format) {
3498      pages[++page] = [];
3499      pagesContext[page] = {
3500        objId: 0,
3501        contentsObjId: 0,
3502        userUnit: Number(userUnit),
3503        artBox: null,
3504        bleedBox: null,
3505        cropBox: null,
3506        trimBox: null,
3507        mediaBox: {
3508          bottomLeftX: 0,
3509          bottomLeftY: 0,
3510          topRightX: Number(format[0]),
3511          topRightY: Number(format[1])
3512        }
3513      };
3514
3515      _setPage(page);
3516
3517      setOutputDestination(pages[currentPage]);
3518    };
3519
3520    var _addPage = function _addPage(parmFormat, parmOrientation) {
3521      var dimensions, width, height;
3522      orientation = parmOrientation || orientation;
3523
3524      if (typeof parmFormat === "string") {
3525        dimensions = getPageFormat(parmFormat.toLowerCase());
3526
3527        if (Array.isArray(dimensions)) {
3528          width = dimensions[0];
3529          height = dimensions[1];
3530        }
3531      }
3532
3533      if (Array.isArray(parmFormat)) {
3534        width = parmFormat[0] * scaleFactor;
3535        height = parmFormat[1] * scaleFactor;
3536      }
3537
3538      if (isNaN(width)) {
3539        width = format[0];
3540        height = format[1];
3541      }
3542
3543      if (width > 14400 || height > 14400) {
3544        console.warn("A page in a PDF can not be wider or taller than 14400 userUnit. jsPDF limits the width/height to 14400");
3545        width = Math.min(14400, width);
3546        height = Math.min(14400, height);
3547      }
3548
3549      format = [width, height];
3550
3551      switch (orientation.substr(0, 1)) {
3552        case "l":
3553          if (height > width) {
3554            format = [height, width];
3555          }
3556
3557          break;
3558
3559        case "p":
3560          if (width > height) {
3561            format = [height, width];
3562          }
3563
3564          break;
3565      }
3566
3567      beginPage(format); // Set line width
3568
3569      setLineWidth(lineWidth); // Set draw color
3570
3571      out(strokeColor); // resurrecting non-default line caps, joins
3572
3573      if (lineCapID !== 0) {
3574        out(lineCapID + " J");
3575      }
3576
3577      if (lineJoinID !== 0) {
3578        out(lineJoinID + " j");
3579      }
3580
3581      events.publish("addPage", {
3582        pageNumber: page
3583      });
3584    };
3585
3586    var _deletePage = function _deletePage(n) {
3587      if (n > 0 && n <= page) {
3588        pages.splice(n, 1);
3589        pagesContext.splice(n, 1);
3590        page--;
3591
3592        if (currentPage > page) {
3593          currentPage = page;
3594        }
3595
3596        this.setPage(currentPage);
3597      }
3598    };
3599
3600    var _setPage = function _setPage(n) {
3601      if (n > 0 && n <= page) {
3602        currentPage = n;
3603      }
3604    };
3605
3606    var getNumberOfPages = API.__private__.getNumberOfPages = API.getNumberOfPages = function () {
3607      return pages.length - 1;
3608    };
3609    /**
3610     * Returns a document-specific font key - a label assigned to a
3611     * font name + font type combination at the time the font was added
3612     * to the font inventory.
3613     *
3614     * Font key is used as label for the desired font for a block of text
3615     * to be added to the PDF document stream.
3616     * @private
3617     * @function
3618     * @param fontName {string} can be undefined on "falthy" to indicate "use current"
3619     * @param fontStyle {string} can be undefined on "falthy" to indicate "use current"
3620     * @returns {string} Font key.
3621     * @ignore
3622     */
3623
3624
3625    var getFont = function getFont(fontName, fontStyle, options) {
3626      var key = undefined,
3627          fontNameLowerCase;
3628      options = options || {};
3629      fontName = fontName !== undefined ? fontName : fonts[activeFontKey].fontName;
3630      fontStyle = fontStyle !== undefined ? fontStyle : fonts[activeFontKey].fontStyle;
3631      fontNameLowerCase = fontName.toLowerCase();
3632
3633      if (fontmap[fontNameLowerCase] !== undefined && fontmap[fontNameLowerCase][fontStyle] !== undefined) {
3634        key = fontmap[fontNameLowerCase][fontStyle];
3635      } else if (fontmap[fontName] !== undefined && fontmap[fontName][fontStyle] !== undefined) {
3636        key = fontmap[fontName][fontStyle];
3637      } else {
3638        if (options.disableWarning === false) {
3639          console.warn("Unable to look up font label for font '" + fontName + "', '" + fontStyle + "'. Refer to getFontList() for available fonts.");
3640        }
3641      }
3642
3643      if (!key && !options.noFallback) {
3644        key = fontmap["times"][fontStyle];
3645
3646        if (key == null) {
3647          key = fontmap["times"]["normal"];
3648        }
3649      }
3650
3651      return key;
3652    };
3653
3654    var putInfo = API.__private__.putInfo = function () {
3655      var objectId = newObject();
3656
3657      var encryptor = function encryptor(data) {
3658        return data;
3659      };
3660
3661      if (encryptionOptions !== null) {
3662        encryptor = encryption.encryptor(objectId, 0);
3663      }
3664
3665      out("<<");
3666      out("/Producer (" + pdfEscape(encryptor("jsPDF " + jsPDF.version)) + ")");
3667
3668      for (var key in documentProperties) {
3669        if (documentProperties.hasOwnProperty(key) && documentProperties[key]) {
3670          out("/" + key.substr(0, 1).toUpperCase() + key.substr(1) + " (" + pdfEscape(encryptor(documentProperties[key])) + ")");
3671        }
3672      }
3673
3674      out("/CreationDate (" + pdfEscape(encryptor(creationDate)) + ")");
3675      out(">>");
3676      out("endobj");
3677    };
3678
3679    var putCatalog = API.__private__.putCatalog = function (options) {
3680      options = options || {};
3681      var tmpRootDictionaryObjId = options.rootDictionaryObjId || rootDictionaryObjId;
3682      newObject();
3683      out("<<");
3684      out("/Type /Catalog");
3685      out("/Pages " + tmpRootDictionaryObjId + " 0 R"); // PDF13ref Section 7.2.1
3686
3687      if (!zoomMode) zoomMode = "fullwidth";
3688
3689      switch (zoomMode) {
3690        case "fullwidth":
3691          out("/OpenAction [3 0 R /FitH null]");
3692          break;
3693
3694        case "fullheight":
3695          out("/OpenAction [3 0 R /FitV null]");
3696          break;
3697
3698        case "fullpage":
3699          out("/OpenAction [3 0 R /Fit]");
3700          break;
3701
3702        case "original":
3703          out("/OpenAction [3 0 R /XYZ null null 1]");
3704          break;
3705
3706        default:
3707          var pcn = "" + zoomMode;
3708          if (pcn.substr(pcn.length - 1) === "%") zoomMode = parseInt(zoomMode) / 100;
3709
3710          if (typeof zoomMode === "number") {
3711            out("/OpenAction [3 0 R /XYZ null null " + f2(zoomMode) + "]");
3712          }
3713
3714      }
3715
3716      if (!layoutMode) layoutMode = "continuous";
3717
3718      switch (layoutMode) {
3719        case "continuous":
3720          out("/PageLayout /OneColumn");
3721          break;
3722
3723        case "single":
3724          out("/PageLayout /SinglePage");
3725          break;
3726
3727        case "two":
3728        case "twoleft":
3729          out("/PageLayout /TwoColumnLeft");
3730          break;
3731
3732        case "tworight":
3733          out("/PageLayout /TwoColumnRight");
3734          break;
3735      }
3736
3737      if (pageMode) {
3738        /**
3739         * A name object specifying how the document should be displayed when opened:
3740         * UseNone      : Neither document outline nor thumbnail images visible -- DEFAULT
3741         * UseOutlines  : Document outline visible
3742         * UseThumbs    : Thumbnail images visible
3743         * FullScreen   : Full-screen mode, with no menu bar, window controls, or any other window visible
3744         */
3745        out("/PageMode /" + pageMode);
3746      }
3747
3748      events.publish("putCatalog");
3749      out(">>");
3750      out("endobj");
3751    };
3752
3753    var putTrailer = API.__private__.putTrailer = function () {
3754      out("trailer");
3755      out("<<");
3756      out("/Size " + (objectNumber + 1)); // Root and Info must be the last and second last objects written respectively
3757
3758      out("/Root " + objectNumber + " 0 R");
3759      out("/Info " + (objectNumber - 1) + " 0 R");
3760
3761      if (encryptionOptions !== null) {
3762        out("/Encrypt " + encryption.oid + " 0 R");
3763      }
3764
3765      out("/ID [ <" + fileId + "> <" + fileId + "> ]");
3766      out(">>");
3767    };
3768
3769    var putHeader = API.__private__.putHeader = function () {
3770      out("%PDF-" + pdfVersion);
3771      out("%\xBA\xDF\xAC\xE0");
3772    };
3773
3774    var putXRef = API.__private__.putXRef = function () {
3775      var p = "0000000000";
3776      out("xref");
3777      out("0 " + (objectNumber + 1));
3778      out("0000000000 65535 f ");
3779
3780      for (var i = 1; i <= objectNumber; i++) {
3781        var offset = offsets[i];
3782
3783        if (typeof offset === "function") {
3784          out((p + offsets[i]()).slice(-10) + " 00000 n ");
3785        } else {
3786          if (typeof offsets[i] !== "undefined") {
3787            out((p + offsets[i]).slice(-10) + " 00000 n ");
3788          } else {
3789            out("0000000000 00000 n ");
3790          }
3791        }
3792      }
3793    };
3794
3795    var buildDocument = API.__private__.buildDocument = function () {
3796      resetDocument();
3797      setOutputDestination(content);
3798      events.publish("buildDocument");
3799      putHeader();
3800      putPages();
3801      putAdditionalObjects();
3802      putResources();
3803      if (encryptionOptions !== null) putEncryptionDict();
3804      putInfo();
3805      putCatalog();
3806      var offsetOfXRef = contentLength;
3807      putXRef();
3808      putTrailer();
3809      out("startxref");
3810      out("" + offsetOfXRef);
3811      out("%%EOF");
3812      setOutputDestination(pages[currentPage]);
3813      return content.join("\n");
3814    };
3815
3816    var getBlob = API.__private__.getBlob = function (data) {
3817      return new Blob([getArrayBuffer(data)], {
3818        type: "application/pdf"
3819      });
3820    };
3821    /**
3822     * Generates the PDF document.
3823     *
3824     * If `type` argument is undefined, output is raw body of resulting PDF returned as a string.
3825     *
3826     * @param {string}
3826 type A string identifying one of the possible output types.<br/>
3827     *                      Possible values are: <br/>
3828     *                          'arraybuffer' -> (ArrayBuffer)<br/>
3829     *                          'blob' -> (Blob)<br/>
3830     *                          'bloburi'/'bloburl' -> (string)<br/>
3831     *                          'datauristring'/'dataurlstring' -> (string)<br/>
3832     *                          'datauri'/'dataurl' -> (undefined) -> change location to generated datauristring/dataurlstring<br/>
3833     *                          'dataurlnewwindow' -> (window | null | undefined) throws error if global isn't a window object(node)<br/>
3834     *                          'pdfobjectnewwindow' -> (window | null) throws error if global isn't a window object(node)<br/>
3835     *                          'pdfjsnewwindow' -> (wind | null)
3836     * @param {Object|string} options An object providing some additional signalling to PDF generator.<br/>
3837     *                                Possible options are 'filename'.<br/>
3838     *                                A string can be passed instead of {filename:string} and defaults to 'generated.pdf'
3839     * @function
3840     * @instance
3841     * @returns {string|window|ArrayBuffer|Blob|jsPDF|null|undefined}
3842     * @memberof jsPDF#
3843     * @name output
3844     */
3845
3846
3847    var output = API.output = API.__private__.output = SAFE(function output(type, options) {
3848      options = options || {};
3849
3850      if (typeof options === "string") {
3851        options = {
3852          filename: options
3853        };
3854      } else {
3855        options.filename = options.filename || "generated.pdf";
3856      }
3857
3858      switch (type) {
3859        case undefined:
3860          return buildDocument();
3861
3862        case "save":
3863          API.save(options.filename);
3864          break;
3865
3866        case "arraybuffer":
3867          return getArrayBuffer(buildDocument());
3868
3869        case "blob":
3870          return getBlob(buildDocument());
3871
3872        case "bloburi":
3873        case "bloburl":
3874          // Developer is responsible of calling revokeObjectURL
3875          if (typeof globalObject.URL !== "undefined" && typeof globalObject.URL.createObjectURL === "function") {
3876            return globalObject.URL && globalObject.URL.createObjectURL(getBlob(buildDocument())) || void 0;
3877          } else {
3878            console.warn("bloburl is not supported by your system, because URL.createObjectURL is not supported by your browser.");
3879          }
3880
3881          break;
3882
3883        case "datauristring":
3884        case "dataurlstring":
3885          var dataURI = "";
3886          var pdfDocument = buildDocument();
3887
3888          try {
3889            dataURI = btoa(pdfDocument);
3890          } catch (e) {
3891            dataURI = btoa(unescape(encodeURIComponent(pdfDocument)));
3892          }
3893
3894          return "data:application/pdf;filename=" + options.filename + ";base64," + dataURI;
3895
3896        case "pdfobjectnewwindow":
3897          if (Object.prototype.toString.call(globalObject) === "[object Window]") {
3898            var pdfObjectUrl = "https://cdnjs.cloudflare.com/ajax/libs/pdfobject/2.1.1/pdfobject.min.js";
3899            var integrity = ' integrity="sha512-4ze/a9/4jqu+tX9dfOqJYSvyYd5M6qum/3HpCLr+/Jqf0whc37VUbkpNGHR7/8pSnCFw47T1fmIpwBV7UySh3g==" crossorigin="anonymous"';
3900
3901            if (options.pdfObjectUrl) {
3902              pdfObjectUrl = options.pdfObjectUrl;
3903              integrity = "";
3904            }
3905
3906            var htmlForNewWindow = "<html>" + '<style>html, body { padding: 0; margin: 0; } iframe { width: 100%; height: 100%; border: 0;}  </style><body><script src="' + pdfObjectUrl + '"' + integrity + '></script><script >PDFObject.embed("' + this.output("dataurlstring") + '", ' + JSON.stringify(options) + ");</script></body></html>";
3907            var nW = globalObject.open();
3908
3909            if (nW !== null) {
3910              nW.document.write(htmlForNewWindow);
3911            }
3912
3913            return nW;
3914          } else {
3915            throw new Error("The option pdfobjectnewwindow just works in a browser-environment.");
3916          }
3917
3918        case "pdfjsnewwindow":
3919          if (Object.prototype.toString.call(globalObject) === "[object Window]") {
3920            var pdfJsUrl = options.pdfJsUrl || "examples/PDF.js/web/viewer.html";
3921            var htmlForPDFjsNewWindow = "<html>" + "<style>html, body { padding: 0; margin: 0; } iframe { width: 100%; height: 100%; border: 0;}  </style>" + '<body><iframe id="pdfViewer" src="' + pdfJsUrl + "?file=&downloadName=" + options.filename + '" width="500px" height="400px" />' + "</body></html>";
3922            var PDFjsNewWindow = globalObject.open();
3923
3924            if (PDFjsNewWindow !== null) {
3925              PDFjsNewWindow.document.write(htmlForPDFjsNewWindow);
3926              var scope = this;
3927
3928              PDFjsNewWindow.document.documentElement.querySelector("#pdfViewer").onload = function () {
3929                PDFjsNewWindow.document.title = options.filename;
3930                PDFjsNewWindow.document.documentElement.querySelector("#pdfViewer").contentWindow.PDFViewerApplication.open(scope.output("bloburl"));
3931              };
3932            }
3933
3934            return PDFjsNewWindow;
3935          } else {
3936            throw new Error("The option pdfjsnewwindow just works in a browser-environment.");
3937          }
3938
3939        case "dataurlnewwindow":
3940          if (Object.prototype.toString.call(globalObject) === "[object Window]") {
3941            var htmlForDataURLNewWindow = "<html>" + "<style>html, body { padding: 0; margin: 0; } iframe { width: 100%; height: 100%; border: 0;}  </style>" + "<body>" + '<iframe src="' + this.output("datauristring", options) + '"></iframe>' + "</body></html>";
3942            var dataURLNewWindow = globalObject.open();
3943
3944            if (dataURLNewWindow !== null) {
3945              dataURLNewWindow.document.write(htmlForDataURLNewWindow);
3946              dataURLNewWindow.document.title = options.filename;
3947            }
3948
3949            if (dataURLNewWindow || typeof safari === "undefined") return dataURLNewWindow;
3950          } else {
3951            throw new Error("The option dataurlnewwindow just works in a browser-environment.");
3952          }
3953
3954          break;
3955
3956        case "datauri":
3957        case "dataurl":
3958          return globalObject.document.location.href = this.output("datauristring", options);
3959
3960        default:
3961          return null;
3962      }
3963    });
3964    /**
3965     * Used to see if a supplied hotfix was requested when the pdf instance was created.
3966     * @param {string} hotfixName - The name of the hotfix to check.
3967     * @returns {boolean}
3968     */
3969
3970    var hasHotfix = function hasHotfix(hotfixName) {
vendor: 5,864 bytes, lines 3971-4194
3971      return Array.isArray(hotfixes) === true && hotfixes.indexOf(hotfixName) > -1;
3972    };
3973
3974    switch (unit) {
3975      case "pt":
3976        scaleFactor = 1;
3977        break;
3978
3979      case "mm":
3980        scaleFactor = 72 / 25.4;
3981        break;
3982
3983      case "cm":
3984        scaleFactor = 72 / 2.54;
3985        break;
3986
3987      case "in":
3988        scaleFactor = 72;
3989        break;
3990
3991      case "px":
3992        if (hasHotfix("px_scaling") == true) {
3993          scaleFactor = 72 / 96;
3994        } else {
3995          scaleFactor = 96 / 72;
3996        }
3997
3998        break;
3999
4000      case "pc":
4001        scaleFactor = 12;
4002        break;
4003
4004      case "em":
4005        scaleFactor = 12;
4006        break;
4007
4008      case "ex":
4009        scaleFactor = 6;
4010        break;
4011
4012      default:
4013        if (typeof unit === "number") {
4014          scaleFactor = unit;
4015        } else {
4016          throw new Error("Invalid unit: " + unit);
4017        }
4018
4019    }
4020
4021    var encryption = null;
4022    setCreationDate();
4023    setFileId();
4024
4025    var getEncryptor = function getEncryptor(objectId) {
4026      if (encryptionOptions !== null) {
4027        return encryption.encryptor(objectId, 0);
4028      }
4029
4030      return function (data) {
4031        return data;
4032      };
4033    }; //---------------------------------------
4034    // Public API
4035
4036
4037    var getPageInfo = API.__private__.getPageInfo = API.getPageInfo = function (pageNumberOneBased) {
4038      if (isNaN(pageNumberOneBased) || pageNumberOneBased % 1 !== 0) {
4039        throw new Error("Invalid argument passed to jsPDF.getPageInfo");
4040      }
4041
4042      var objId = pagesContext[pageNumberOneBased].objId;
4043      return {
4044        objId: objId,
4045        pageNumber: pageNumberOneBased,
4046        pageContext: pagesContext[pageNumberOneBased]
4047      };
4048    };
4049
4050    var getPageInfoByObjId = API.__private__.getPageInfoByObjId = function (objId) {
4051      if (isNaN(objId) || objId % 1 !== 0) {
4052        throw new Error("Invalid argument passed to jsPDF.getPageInfoByObjId");
4053      }
4054
4055      for (var pageNumber in pagesContext) {
4056        if (pagesContext[pageNumber].objId === objId) {
4057          break;
4058        }
4059      }
4060
4061      return getPageInfo(pageNumber);
4062    };
4063
4064    var getCurrentPageInfo = API.__private__.getCurrentPageInfo = API.getCurrentPageInfo = function () {
4065      return {
4066        objId: pagesContext[currentPage].objId,
4067        pageNumber: currentPage,
4068        pageContext: pagesContext[currentPage]
4069      };
4070    };
4071    /**
4072     * Adds (and transfers the focus to) new page to the PDF document.
4073     * @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>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 />
4074     * 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]
4075     * @param orientation {string} Orientation of the new page. Possible values are "portrait" or "landscape" (or shortcuts "p" (Default), "l").
4076     * @function
4077     * @instance
4078     * @returns {jsPDF}
4079     *
4080     * @memberof jsPDF#
4081     * @name addPage
4082     */
4083
4084
4085    API.addPage = function () {
4086      _addPage.apply(this, arguments);
4087
4088      return this;
4089    };
4090    /**
4091     * Adds (and transfers the focus to) new page to the PDF document.
4092     * @function
4093     * @instance
4094     * @returns {jsPDF}
4095     *
4096     * @memberof jsPDF#
4097     * @name setPage
4098     * @param {number} page Switch the active page to the page number specified (indexed starting at 1).
4099     * @example
4100     * doc = jsPDF()
4101     * doc.addPage()
4102     * doc.addPage()
4103     * doc.text('I am on page 3', 10, 10)
4104     * doc.setPage(1)
4105     * doc.text('I am on page 1', 10, 10)
4106     */
4107
4108
4109    API.setPage = function () {
4110      _setPage.apply(this, arguments);
4111
4112      setOutputDestination.call(this, pages[currentPage]);
4113      return this;
4114    };
4115    /**
4116     * @name insertPage
4117     * @memberof jsPDF#
4118     *
4119     * @function
4120     * @instance
4121     * @param {Object} beforePage
4122     * @returns {jsPDF}
4123     */
4124
4125
4126    API.insertPage = function (beforePage) {
4127      this.addPage();
4128      this.movePage(currentPage, beforePage);
4129      return this;
4130    };
4131    /**
4132     * @name movePage
4133     * @memberof jsPDF#
4134     * @function
4135     * @instance
4136     * @param {number} targetPage
4137     * @param {number} beforePage
4138     * @returns {jsPDF}
4139     */
4140
4141
4142    API.movePage = function (targetPage, beforePage) {
4143      var tmpPages, tmpPagesContext;
4144
4145      if (targetPage > beforePage) {
4146        tmpPages = pages[targetPage];
4147        tmpPagesContext = pagesContext[targetPage];
4148
4149        for (var i = targetPage; i > beforePage; i--) {
4150          pages[i] = pages[i - 1];
4151          pagesContext[i] = pagesContext[i - 1];
4152        }
4153
4154        pages[beforePage] = tmpPages;
4155        pagesContext[beforePage] = tmpPagesContext;
4156        this.setPage(beforePage);
4157      } else if (targetPage < beforePage) {
4158        tmpPages = pages[targetPage];
4159        tmpPagesContext = pagesContext[targetPage];
4160
4161        for (var j = targetPage; j < beforePage; j++) {
4162          pages[j] = pages[j + 1];
4163          pagesContext[j] = pagesContext[j + 1];
4164        }
4165
4166        pages[beforePage] = tmpPages;
4167        pagesContext[beforePage] = tmpPagesContext;
4168        this.setPage(beforePage);
4169      }
4170
4171      return this;
4172    };
4173    /**
4174     * Deletes a page from the PDF.
4175     * @name deletePage
4176     * @memberof jsPDF#
4177     * @function
4178     * @param {number} targetPage
4179     * @instance
4180     * @returns {jsPDF}
4181     */
4182
4183
4184    API.deletePage = function () {
4185      _deletePage.apply(this, arguments);
4186
4187      return this;
4188    };
4189    /**
4190     * Adds text to page. Supports adding multiline text when 'text' argument is an Array of Strings.
4191     *
4192     * @function
4193     * @instance
4194     * @param {String|Array}
4194 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.
4195     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page.
4196     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page.
4197     * @param {Object} [options] - Collection of settings signaling how the text must be encoded.
4198     * @param {string} [options.align=left] - The alignment of the text, possible values: left, center, right, justify.
4199     * @param {string} [options.baseline=alphabetic] - Sets text baseline used when drawing the text, possible values: alphabetic, ideographic, bottom, top, middle, hanging
4200     * @param {number|Matrix} [options.angle=0] - Rotate the text clockwise or counterclockwise. Expects the angle in degree.
4201     * @param {number} [options.rotationDirection=1] - Direction of the rotation. 0 = clockwise, 1 = counterclockwise.
4202     * @param {number} [options.charSpace=0] - The space between each letter.
4203     * @param {number} [options.horizontalScale=1] - Horizontal scale of the text as a factor of the regular size.
4204     * @param {number} [options.lineHeightFactor=1.15] - The lineheight of each line.
4205     * @param {Object} [options.flags] - Flags for to8bitStream.
4206     * @param {boolean} [options.flags.noBOM=true] - Don't add BOM to Unicode-text.
4207     * @param {boolean} [options.flags.autoencode=true] - Autoencode the Text.
4208     * @param {number} [options.maxWidth=0] - Split the text by given width, 0 = no split.
4209     * @param {string} [options.renderingMode=fill] - Set how the text should be rendered, possible values: fill, stroke, fillThenStroke, invisible, fillAndAddForClipping, strokeAndAddPathForClipping, fillThenStrokeAndAddToPathForClipping, addToPathForClipping.
4210     * @param {boolean} [options.isInputVisual] - Option for the BidiEngine
4211     * @param {boolean} [options.isOutputVisual] - Option for the BidiEngine
4212     * @param {boolean} [options.isInputRtl] - Option for the BidiEngine
4213     * @param {boolean} [options.isOutputRtl] - Option for the BidiEngine
4214     * @param {boolean} [options.isSymmetricSwapping] - Option for the BidiEngine
4215     * @param {number|Matrix} transform If transform is a number the text will be rotated by this value around the anchor set by x and y.
4216     *
4217     * If it is a Matrix, this matrix gets directly applied to the text, which allows shearing
4218     * effects etc.; the x and y offsets are then applied AFTER the coordinate system has been established by this
4219     * matrix. This means passing a rotation matrix that is equivalent to some rotation angle will in general yield a
4220     * DIFFERENT result. A matrix is only allowed in "advanced" API mode.
4221     * @returns {jsPDF}
4222     * @memberof jsPDF#
4223     * @name text
4224     */
4225
4226
4227    API.__private__.text = API.text = function (text, x, y, options, transform) {
4228      /*
4229       * Inserts something like this into PDF
4230       *   BT
4231       *    /F1 16 Tf  % Font name + size
4232       *    16 TL % How many units down for next line in multiline text
4233       *    0 g % color
4234       *    28.35 813.54 Td % position
4235       *    (line one) Tj
4236       *    T* (line two) Tj
4237       *    T* (line three) Tj
4238       *   ET
4239       */
4240      options = options || {};
4241      var scope = options.scope || this;
4242      var payload, da, angle, align, charSpace, maxWidth, flags, horizontalScale; // Pre-August-2012 the order of arguments was function(x, y, text, flags)
4243      // in effort to make all calls have similar signature like
4244      //   function(data, coordinates... , miscellaneous)
4245      // this method had its args flipped.
4246      // code below allows backward compatibility with old arg order.
4247
4248      if (typeof text === "number" && typeof x === "number" && (typeof y === "string" || Array.isArray(y))) {
4249        var tmp = y;
4250        y = x;
4251        x = text;
4252        text = tmp;
4253      }
4254
4255      var transformationMatrix;
4256
4257      if (arguments[3] instanceof Matrix === false) {
4258        flags = arguments[3];
4259        angle = arguments[4];
4260        align = arguments[5];
4261
4262        if (_typeof(flags) !== "object" || flags === null) {
4263          if (typeof angle === "string") {
4264            align = angle;
4265            angle = null;
4266          }
4267
4268          if (typeof flags === "string") {
4269            align = flags;
4270            flags = null;
4271          }
4272
vendor: 50,021 bytes, lines 4273-5764
4273          if (typeof flags === "number") {
4274            angle = flags;
4275            flags = null;
4276          }
4277
4278          options = {
4279            flags: flags,
4280            angle: angle,
4281            align: align
4282          };
4283        }
4284      } else {
4285        advancedApiModeTrap("The transform parameter of text() with a Matrix value");
4286        transformationMatrix = transform;
4287      }
4288
4289      if (isNaN(x) || isNaN(y) || typeof text === "undefined" || text === null) {
4290        throw new Error("Invalid arguments passed to jsPDF.text");
4291      }
4292
4293      if (text.length === 0) {
4294        return scope;
4295      }
4296
4297      var xtra = "";
4298      var isHex = false;
4299      var lineHeight = typeof options.lineHeightFactor === "number" ? options.lineHeightFactor : lineHeightFactor;
4300      var scaleFactor = scope.internal.scaleFactor;
4301
4302      function ESC(s) {
4303        s = s.split("\t").join(Array(options.TabLen || 9).join(" "));
4304        return pdfEscape(s, flags);
4305      }
4306
4307      function transformTextToSpecialArray(text) {
4308        //we don't want to destroy original text array, so cloning it
4309        var sa = text.concat();
4310        var da = [];
4311        var len = sa.length;
4312        var curDa; //we do array.join('text that must not be PDFescaped")
4313        //thus, pdfEscape each component separately
4314
4315        while (len--) {
4316          curDa = sa.shift();
4317
4318          if (typeof curDa === "string") {
4319            da.push(curDa);
4320          } else {
4321            if (Array.isArray(text) && (curDa.length === 1 || curDa[1] === undefined && curDa[2] === undefined)) {
4322              da.push(curDa[0]);
4323            } else {
4324              da.push([curDa[0], curDa[1], curDa[2]]);
4325            }
4326          }
4327        }
4328
4329        return da;
4330      }
4331
4332      function processTextByFunction(text, processingFunction) {
4333        var result;
4334
4335        if (typeof text === "string") {
4336          result = processingFunction(text)[0];
4337        } else if (Array.isArray(text)) {
4338          //we don't want to destroy original text array, so cloning it
4339          var sa = text.concat();
4340          var da = [];
4341          var len = sa.length;
4342          var curDa;
4343          var tmpResult; //we do array.join('text that must not be PDFescaped")
4344          //thus, pdfEscape each component separately
4345
4346          while (len--) {
4347            curDa = sa.shift();
4348
4349            if (typeof curDa === "string") {
4350              da.push(processingFunction(curDa)[0]);
4351            } else if (Array.isArray(curDa) && typeof curDa[0] === "string") {
4352              tmpResult = processingFunction(curDa[0], curDa[1], curDa[2]);
4353              da.push([tmpResult[0], tmpResult[1], tmpResult[2]]);
4354            }
4355          }
4356
4357          result = da;
4358        }
4359
4360        return result;
4361      } //Check if text is of type String
4362
4363
4364      var textIsOfTypeString = false;
4365      var tmpTextIsOfTypeString = true;
4366
4367      if (typeof text === "string") {
4368        textIsOfTypeString = true;
4369      } else if (Array.isArray(text)) {
4370        //we don't want to destroy original text array, so cloning it
4371        var sa = text.concat();
4372        da = [];
4373        var len = sa.length;
4374        var curDa; //we do array.join('text that must not be PDFescaped")
4375        //thus, pdfEscape each component separately
4376
4377        while (len--) {
4378          curDa = sa.shift();
4379
4380          if (typeof curDa !== "string" || Array.isArray(curDa) && typeof curDa[0] !== "string") {
4381            tmpTextIsOfTypeString = false;
4382          }
4383        }
4384
4385        textIsOfTypeString = tmpTextIsOfTypeString;
4386      }
4387
4388      if (textIsOfTypeString === false) {
4389        throw new Error('Type of text must be string or Array. "' + text + '" is not recognized.');
4390      } //If there are any newlines in text, we assume
4391      //the user wanted to print multiple lines, so break the
4392      //text up into an array. If the text is already an array,
4393      //we assume the user knows what they are doing.
4394      //Convert text into an array anyway to simplify
4395      //later code.
4396
4397
4398      if (typeof text === "string") {
4399        if (text.match(/[\r?\n]/)) {
4400          text = text.split(/\r\n|\r|\n/g);
4401        } else {
4402          text = [text];
4403        }
4404      } //baseline
4405
4406
4407      var height = activeFontSize / scope.internal.scaleFactor;
4408      var descent = height * (lineHeight - 1);
4409
4410      switch (options.baseline) {
4411        case "bottom":
4412          y -= descent;
4413          break;
4414
4415        case "top":
4416          y += height - descent;
4417          break;
4418
4419        case "hanging":
4420          y += height - 2 * descent;
4421          break;
4422
4423        case "middle":
4424          y += height / 2 - descent;
4425          break;
4426      } //multiline
4427
4428
4429      maxWidth = options.maxWidth || 0;
4430
4431      if (maxWidth > 0) {
4432        if (typeof text === "string") {
4433          text = scope.splitTextToSize(text, maxWidth);
4434        } else if (Object.prototype.toString.call(text) === "[object Array]") {
4435          text = text.reduce(function (acc, textLine) {
4436            return acc.concat(scope.splitTextToSize(textLine, maxWidth));
4437          }, []);
4438        }
4439      } //creating Payload-Object to make text byRef
4440
4441
4442      payload = {
4443        text: text,
4444        x: x,
4445        y: y,
4446        options: options,
4447        mutex: {
4448          pdfEscape: pdfEscape,
4449          activeFontKey: activeFontKey,
4450          fonts: fonts,
4451          activeFontSize: activeFontSize
4452        }
4453      };
4454      events.publish("preProcessText", payload);
4455      text = payload.text;
4456      options = payload.options; //angle
4457
4458      angle = options.angle;
4459
4460      if (transformationMatrix instanceof Matrix === false && angle && typeof angle === "number") {
4461        angle *= Math.PI / 180;
4462
4463        if (options.rotationDirection === 0) {
4464          angle = -angle;
4465        }
4466
4467        if (apiMode === ApiMode.ADVANCED) {
4468          angle = -angle;
4469        }
4470
4471        var c = Math.cos(angle);
4472        var s = Math.sin(angle);
4473        transformationMatrix = new Matrix(c, s, -s, c, 0, 0);
4474      } else if (angle && angle instanceof Matrix) {
4475        transformationMatrix = angle;
4476      }
4477
4478      if (apiMode === ApiMode.ADVANCED && !transformationMatrix) {
4479        transformationMatrix = identityMatrix;
4480      } //charSpace
4481
4482
4483      charSpace = options.charSpace || activeCharSpace;
4484
4485      if (typeof charSpace !== "undefined") {
4486        xtra += hpf(scale(charSpace)) + " Tc\n";
4487        this.setCharSpace(this.getCharSpace() || 0);
4488      }
4489
4490      horizontalScale = options.horizontalScale;
4491
4492      if (typeof horizontalScale !== "undefined") {
4493        xtra += hpf(horizontalScale * 100) + " Tz\n";
4494      } //lang
4495
4496
4497      var lang = options.lang;
4498
4499
4500      var renderingMode = -1;
4501      var parmRenderingMode = typeof options.renderingMode !== "undefined" ? options.renderingMode : options.stroke;
4502      var pageContext = scope.internal.getCurrentPageInfo().pageContext;
4503
4504      switch (parmRenderingMode) {
4505        case 0:
4506        case false:
4507        case "fill":
4508          renderingMode = 0;
4509          break;
4510
4511        case 1:
4512        case true:
4513        case "stroke":
4514          renderingMode = 1;
4515          break;
4516
4517        case 2:
4518        case "fillThenStroke":
4519          renderingMode = 2;
4520          break;
4521
4522        case 3:
4523        case "invisible":
4524          renderingMode = 3;
4525          break;
4526
4527        case 4:
4528        case "fillAndAddForClipping":
4529          renderingMode = 4;
4530          break;
4531
4532        case 5:
4533        case "strokeAndAddPathForClipping":
4534          renderingMode = 5;
4535          break;
4536
4537        case 6:
4538        case "fillThenStrokeAndAddToPathForClipping":
4539          renderingMode = 6;
4540          break;
4541
4542        case 7:
4543        case "addToPathForClipping":
4544          renderingMode = 7;
4545          break;
4546      }
4547
4548      var usedRenderingMode = typeof pageContext.usedRenderingMode !== "undefined" ? pageContext.usedRenderingMode : -1; //if the coder wrote it explicitly to use a specific
4549      //renderingMode, then use it
4550
4551      if (renderingMode !== -1) {
4552        xtra += renderingMode + " Tr\n"; //otherwise check if we used the rendering Mode already
4553        //if so then set the rendering Mode...
4554      } else if (usedRenderingMode !== -1) {
4555        xtra += "0 Tr\n";
4556      }
4557
4558      if (renderingMode !== -1) {
4559        pageContext.usedRenderingMode = renderingMode;
4560      } //align
4561
4562
4563      align = options.align || "left";
4564      var leading = activeFontSize * lineHeight;
4565      var pageWidth = scope.internal.pageSize.getWidth();
4566      var activeFont = fonts[activeFontKey];
4567      charSpace = options.charSpace || activeCharSpace;
4568      maxWidth = options.maxWidth || 0;
4569      var lineWidths;
4570      flags = Object.assign({
4571        autoencode: true,
4572        noBOM: true
4573      }, options.flags);
4574      var wordSpacingPerLine = [];
4575
4576      if (Object.prototype.toString.call(text) === "[object Array]") {
4577        da = transformTextToSpecialArray(text);
4578        var newY;
4579
4580        if (align !== "left") {
4581          lineWidths = da.map(function (v) {
4582            return scope.getStringUnitWidth(v, {
4583              font: activeFont,
4584              charSpace: charSpace,
4585              fontSize: activeFontSize,
4586              doKerning: false
4587            }) * activeFontSize / scaleFactor;
4588          });
4589        } //The first line uses the "main" Td setting,
4590        //and the subsequent lines are offset by the
4591        //previous line's x coordinate.
4592
4593
4594        var prevWidth = 0;
4595        var newX;
4596
4597        if (align === "right") {
4598          //The passed in x coordinate defines the
4599          //rightmost point of the text.
4600          x -= lineWidths[0];
4601          text = [];
4602          len = da.length;
4603
4604          for (var i = 0; i < len; i++) {
4605            if (i === 0) {
4606              newX = getHorizontalCoordinate(x);
4607              newY = getVerticalCoordinate(y);
4608            } else {
4609              newX = scale(prevWidth - lineWidths[i]);
4610              newY = -leading;
4611            }
4612
4613            text.push([da[i], newX, newY]);
4614            prevWidth = lineWidths[i];
4615          }
4616        } else if (align === "center") {
4617          //The passed in x coordinate defines
4618          //the center point.
4619          x -= lineWidths[0] / 2;
4620          text = [];
4621          len = da.length;
4622
4623          for (var j = 0; j < len; j++) {
4624            if (j === 0) {
4625              newX = getHorizontalCoordinate(x);
4626              newY = getVerticalCoordinate(y);
4627            } else {
4628              newX = scale((prevWidth - lineWidths[j]) / 2);
4629              newY = -leading;
4630            }
4631
4632            text.push([da[j], newX, newY]);
4633            prevWidth = lineWidths[j];
4634          }
4635        } else if (align === "left") {
4636          text = [];
4637          len = da.length;
4638
4639          for (var h = 0; h < len; h++) {
4640            text.push(da[h]);
4641          }
4642        } else if (align === "justify") {
4643          text = [];
4644          len = da.length;
4645          maxWidth = maxWidth !== 0 ? maxWidth : pageWidth;
4646
4647          for (var l = 0; l < len; l++) {
4648            newY = l === 0 ? getVerticalCoordinate(y) : -leading;
4649            newX = l === 0 ? getHorizontalCoordinate(x) : 0;
4650
4651            if (l < len - 1) {
4652              wordSpacingPerLine.push(hpf(scale((maxWidth - lineWidths[l]) / (da[l].split(" ").length - 1))));
4653            } else {
4654              wordSpacingPerLine.push(0);
4655            }
4656
4657            text.push([da[l], newX, newY]);
4658          }
4659        } else {
4660          throw new Error('Unrecognized alignment option, use "left", "center", "right" or "justify".');
4661        }
4662      } //R2L
4663
4664
4665      var doReversing = typeof options.R2L === "boolean" ? options.R2L : R2L;
4666
4667      if (doReversing === true) {
4668        text = processTextByFunction(text, function (text, posX, posY) {
4669          return [text.split("").reverse().join(""), posX, posY];
4670        });
4671      } //creating Payload-Object to make text byRef
4672
4673
4674      payload = {
4675        text: text,
4676        x: x,
4677        y: y,
4678        options: options,
4679        mutex: {
4680          pdfEscape: pdfEscape,
4681          activeFontKey: activeFontKey,
4682          fonts: fonts,
4683          activeFontSize: activeFontSize
4684        }
4685      };
4686      events.publish("postProcessText", payload);
4687      text = payload.text;
4688      isHex = payload.mutex.isHex || false; //Escaping
4689
4690      var activeFontEncoding = fonts[activeFontKey].encoding;
4691
4692      if (activeFontEncoding === "WinAnsiEncoding" || activeFontEncoding === "StandardEncoding") {
4693        text = processTextByFunction(text, function (text, posX, posY) {
4694          return [ESC(text), posX, posY];
4695        });
4696      }
4697
4698      da = transformTextToSpecialArray(text);
4699      text = [];
4700      var STRING = 0;
4701      var ARRAY = 1;
4702      var variant = Array.isArray(da[0]) ? ARRAY : STRING;
4703      var posX;
4704      var posY;
4705      var content;
4706      var wordSpacing = "";
4707
4708      var generatePosition = function generatePosition(parmPosX, parmPosY, parmTransformationMatrix) {
4709        var position = "";
4710
4711        if (parmTransformationMatrix instanceof Matrix) {
4712          // It is kind of more intuitive to apply a plain rotation around the text anchor set by x and y
4713          // but when the user supplies an arbitrary transformation matrix, the x and y offsets should be applied
4714          // in the coordinate system established by this matrix
4715          if (typeof options.angle === "number") {
4716            parmTransformationMatrix = matrixMult(parmTransformationMatrix, new Matrix(1, 0, 0, 1, parmPosX, parmPosY));
4717          } else {
4718            parmTransformationMatrix = matrixMult(new Matrix(1, 0, 0, 1, parmPosX, parmPosY), parmTransformationMatrix);
4719          }
4720
4721          if (apiMode === ApiMode.ADVANCED) {
4722            parmTransformationMatrix = matrixMult(new Matrix(1, 0, 0, -1, 0, 0), parmTransformationMatrix);
4723          }
4724
4725          position = parmTransformationMatrix.join(" ") + " Tm\n";
4726        } else {
4727          position = hpf(parmPosX) + " " + hpf(parmPosY) + " Td\n";
4728        }
4729
4730        return position;
4731      };
4732
4733      for (var lineIndex = 0; lineIndex < da.length; lineIndex++) {
4734        wordSpacing = "";
4735
4736        switch (variant) {
4737          case ARRAY:
4738            content = (isHex ? "<" : "(") + da[lineIndex][0] + (isHex ? ">" : ")");
4739            posX = parseFloat(da[lineIndex][1]);
4740            posY = parseFloat(da[lineIndex][2]);
4741            break;
4742
4743          case STRING:
4744            content = (isHex ? "<" : "(") + da[lineIndex] + (isHex ? ">" : ")");
4745            posX = getHorizontalCoordinate(x);
4746            posY = getVerticalCoordinate(y);
4747            break;
4748        }
4749
4750        if (typeof wordSpacingPerLine !== "undefined" && typeof wordSpacingPerLine[lineIndex] !== "undefined") {
4751          wordSpacing = wordSpacingPerLine[lineIndex] + " Tw\n";
4752        }
4753
4754        if (lineIndex === 0) {
4755          text.push(wordSpacing + generatePosition(posX, posY, transformationMatrix) + content);
4756        } else if (variant === STRING) {
4757          text.push(wordSpacing + content);
4758        } else if (variant === ARRAY) {
4759          text.push(wordSpacing + generatePosition(posX, posY, transformationMatrix) + content);
4760        }
4761      }
4762
4763      text = variant === STRING ? text.join(" Tj\nT* ") : text.join(" Tj\n");
4764      text += " Tj\n";
4765      var result = "BT\n/";
4766      result += activeFontKey + " " + activeFontSize + " Tf\n"; // font face, style, size
4767
4768      result += hpf(activeFontSize * lineHeight) + " TL\n"; // line spacing
4769
4770      result += textColor + "\n";
4771      result += xtra;
4772      result += text;
4773      result += "ET";
4774      out(result);
4775      usedFonts[activeFontKey] = true;
4776      return scope;
4777    }; // PDF supports these path painting and clip path operators:
4778    //
4779    // S - stroke
4780    // s - close/stroke
4781    // f (F) - fill non-zero
4782    // f* - fill evenodd
4783    // B - fill stroke nonzero
4784    // B* - fill stroke evenodd
4785    // b - close fill stroke nonzero
4786    // b* - close fill stroke evenodd
4787    // n - nothing (consume path)
4788    // W - clip nonzero
4789    // W* - clip evenodd
4790    //
4791    // In order to keep the API small, we omit the close-and-fill/stroke operators and provide a separate close()
4792    // method.
4793
4794    /**
4795     *
4796     * @name clip
4797     * @function
4798     * @instance
4799     * @param {string} rule Only possible value is 'evenodd'
4800     * @returns {jsPDF}
4801     * @memberof jsPDF#
4802     * @description All .clip() after calling drawing ops with a style argument of null.
4803     */
4804
4805
4806    var clip = API.__private__.clip = API.clip = function (rule) {
4807      // Call .clip() after calling drawing ops with a style argument of null
4808      // W is the PDF clipping op
4809      if ("evenodd" === rule) {
4810        out("W*");
4811      } else {
4812        out("W");
4813      }
4814
4815      return this;
4816    };
4817    /**
4818     * @name clipEvenOdd
4819     * @function
4820     * @instance
4821     * @returns {jsPDF}
4822     * @memberof jsPDF#
4823     * @description Modify the current clip path by intersecting it with the current path using the even-odd rule. Note
4824     * that this will NOT consume the current path. In order to only use this path for clipping call
4825     * {@link API.discardPath} afterwards.
4826     */
4827
4828
4829    API.clipEvenOdd = function () {
4830      return clip("evenodd");
4831    };
4832    /**
4833     * Consumes the current path without any effect. Mainly used in combination with {@link clip} or
4834     * {@link clipEvenOdd}. The PDF "n" operator.
4835     * @name discardPath
4836     * @function
4837     * @instance
4838     * @returns {jsPDF}
4839     * @memberof jsPDF#
4840     */
4841
4842
4843    API.__private__.discardPath = API.discardPath = function () {
4844      out("n");
4845      return this;
4846    };
4847
4848    var isValidStyle = API.__private__.isValidStyle = function (style) {
4849      var validStyleVariants = [undefined, null, "S", "D", "F", "DF", "FD", "f", "f*", "B", "B*", "n"];
4850      var result = false;
4851
4852      if (validStyleVariants.indexOf(style) !== -1) {
4853        result = true;
4854      }
4855
4856      return result;
4857    };
4858
4859    API.__private__.setDefaultPathOperation = API.setDefaultPathOperation = function (operator) {
4860      if (isValidStyle(operator)) {
4861        defaultPathOperation = operator;
4862      }
4863
4864      return this;
4865    };
4866
4867    var getStyle = API.__private__.getStyle = API.getStyle = function (style) {
4868      // see path-painting operators in PDF spec
4869      var op = defaultPathOperation; // stroke
4870
4871      switch (style) {
4872        case "D":
4873        case "S":
4874          op = "S"; // stroke
4875
4876          break;
4877
4878        case "F":
4879          op = "f"; // fill
4880
4881          break;
4882
4883        case "FD":
4884        case "DF":
4885          op = "B";
4886          break;
4887
4888        case "f":
4889        case "f*":
4890        case "B":
4891        case "B*":
4892          /*
4893                 Allow direct use of these PDF path-painting operators:
4894                 - f    fill using nonzero winding number rule
4895                 - f*    fill using even-odd rule
4896                 - B    fill then stroke with fill using non-zero winding number rule
4897                 - B*    fill then stroke with fill using even-odd rule
4898                 */
4899          op = style;
4900          break;
4901      }
4902
4903      return op;
4904    };
4905    /**
4906     * Close the current path. The PDF "h" operator.
4907     * @name close
4908     * @function
4909     * @instance
4910     * @returns {jsPDF}
4911     * @memberof jsPDF#
4912     */
4913
4914
4915    var close = API.close = function () {
4916      out("h");
4917      return this;
4918    };
4919    /**
4920     * Stroke the path. The PDF "S" operator.
4921     * @name stroke
4922     * @function
4923     * @instance
4924     * @returns {jsPDF}
4925     * @memberof jsPDF#
4926     */
4927
4928
4929    API.stroke = function () {
4930      out("S");
4931      return this;
4932    };
4933    /**
4934     * Fill the current path using the nonzero winding number rule. If a pattern is provided, the path will be filled
4935     * with this pattern, otherwise with the current fill color. Equivalent to the PDF "f" operator.
4936     * @name fill
4937     * @function
4938     * @instance
4939     * @param {PatternData=} pattern If provided the path will be filled with this pattern
4940     * @returns {jsPDF}
4941     * @memberof jsPDF#
4942     */
4943
4944
4945    API.fill = function (pattern) {
4946      fillWithOptionalPattern("f", pattern);
4947      return this;
4948    };
4949    /**
4950     * Fill the current path using the even-odd rule. The PDF f* operator.
4951     * @see API.fill
4952     * @name fillEvenOdd
4953     * @function
4954     * @instance
4955     * @param {PatternData=} pattern If provided the path will be filled with this pattern
4956     * @returns {jsPDF}
4957     * @memberof jsPDF#
4958     */
4959
4960
4961    API.fillEvenOdd = function (pattern) {
4962      fillWithOptionalPattern("f*", pattern);
4963      return this;
4964    };
4965    /**
4966     * Fill using the nonzero winding number rule and then stroke the current Path. The PDF "B" operator.
4967     * @see API.fill
4968     * @name fillStroke
4969     * @function
4970     * @instance
4971     * @param {PatternData=} pattern If provided the path will be stroked with this pattern
4972     * @returns {jsPDF}
4973     * @memberof jsPDF#
4974     */
4975
4976
4977    API.fillStroke = function (pattern) {
4978      fillWithOptionalPattern("B", pattern);
4979      return this;
4980    };
4981    /**
4982     * Fill using the even-odd rule and then stroke the current Path. The PDF "B" operator.
4983     * @see API.fill
4984     * @name fillStrokeEvenOdd
4985     * @function
4986     * @instance
4987     * @param {PatternData=} pattern If provided the path will be fill-stroked with this pattern
4988     * @returns {jsPDF}
4989     * @memberof jsPDF#
4990     */
4991
4992
4993    API.fillStrokeEvenOdd = function (pattern) {
4994      fillWithOptionalPattern("B*", pattern);
4995      return this;
4996    };
4997
4998    var fillWithOptionalPattern = function fillWithOptionalPattern(style, pattern) {
4999      if (_typeof(pattern) === "object") {
5000        fillWithPattern(pattern, style);
5001      } else {
5002        out(style);
5003      }
5004    };
5005
5006    var putStyle = function putStyle(style) {
5007      if (style === null || apiMode === ApiMode.ADVANCED && style === undefined) {
5008        return;
5009      }
5010
5011      style = getStyle(style); // stroking / filling / both the path
5012
5013      out(style);
5014    };
5015
5016    function cloneTilingPattern(patternKey, boundingBox, xStep, yStep, matrix) {
5017      var clone = new TilingPattern(boundingBox || this.boundingBox, xStep || this.xStep, yStep || this.yStep, this.gState, matrix || this.matrix);
5018      clone.stream = this.stream;
5019      var key = patternKey + "$$" + this.cloneIndex++ + "$$";
5020      addPattern(key, clone);
5021      return clone;
5022    }
5023
5024    var fillWithPattern = function fillWithPattern(patternData, style) {
5025      var patternId = patternMap[patternData.key];
5026      var pattern = patterns[patternId];
5027
5028      if (pattern instanceof ShadingPattern) {
5029        out("q");
5030        out(clipRuleFromStyle(style));
5031
5032        if (pattern.gState) {
5033          API.setGState(pattern.gState);
5034        }
5035
5036        out(patternData.matrix.toString() + " cm");
5037        out("/" + patternId + " sh");
5038        out("Q");
5039      } else if (pattern instanceof TilingPattern) {
5040        // pdf draws patterns starting at the bottom left corner and they are not affected by the global transformation,
5041        // so we must flip them
5042        var matrix = new Matrix(1, 0, 0, -1, 0, getPageHeight());
5043
5044        if (patternData.matrix) {
5045          matrix = matrix.multiply(patternData.matrix || identityMatrix); // we cannot apply a matrix to the pattern on use so we must abuse the pattern matrix and create new instances
5046          // for each use
5047
5048          patternId = cloneTilingPattern.call(pattern, patternData.key, patternData.boundingBox, patternData.xStep, patternData.yStep, matrix).id;
5049        }
5050
5051        out("q");
5052        out("/Pattern cs");
5053        out("/" + patternId + " scn");
5054
5055        if (pattern.gState) {
5056          API.setGState(pattern.gState);
5057        }
5058
5059        out(style);
5060        out("Q");
5061      }
5062    };
5063
5064    var clipRuleFromStyle = function clipRuleFromStyle(style) {
5065      switch (style) {
5066        case "f":
5067        case "F":
5068          return "W n";
5069
5070        case "f*":
5071          return "W* n";
5072
5073        case "B":
5074          return "W S";
5075
5076        case "B*":
5077          return "W* S";
5078        // these two are for compatibility reasons (in the past, calling any primitive method with a shading pattern
5079        // and "n"/"S" as style would still fill/fill and stroke the path)
5080
5081        case "S":
5082          return "W S";
5083
5084        case "n":
5085          return "W n";
5086      }
5087    };
5088    /**
5089     * Begin a new subpath by moving the current point to coordinates (x, y). The PDF "m" operator.
5090     * @param {number} x
5091     * @param {number} y
5092     * @name moveTo
5093     * @function
5094     * @instance
5095     * @memberof jsPDF#
5096     * @returns {jsPDF}
5097     */
5098
5099
5100    var moveTo = API.moveTo = function (x, y) {
5101      out(hpf(scale(x)) + " " + hpf(transformScaleY(y)) + " m");
5102      return this;
5103    };
5104    /**
5105     * Append a straight line segment from the current point to the point (x, y). The PDF "l" operator.
5106     * @param {number} x
5107     * @param {number} y
5108     * @memberof jsPDF#
5109     * @name lineTo
5110     * @function
5111     * @instance
5112     * @memberof jsPDF#
5113     * @returns {jsPDF}
5114     */
5115
5116
5117    var lineTo = API.lineTo = function (x, y) {
5118      out(hpf(scale(x)) + " " + hpf(transformScaleY(y)) + " l");
5119      return this;
5120    };
5121    /**
5122     * Append a cubic Bézier curve to the current path. The curve shall extend from the current point to the point
5123     * (x3, y3), using (x1, y1) and (x2, y2) as Bézier control points. The new current point shall be (x3, x3).
5124     * @param {number} x1
5125     * @param {number} y1
5126     * @param {number} x2
5127     * @param {number} y2
5128     * @param {number} x3
5129     * @param {number} y3
5130     * @memberof jsPDF#
5131     * @name curveTo
5132     * @function
5133     * @instance
5134     * @memberof jsPDF#
5135     * @returns {jsPDF}
5136     */
5137
5138
5139    var curveTo = API.curveTo = function (x1, y1, x2, y2, x3, y3) {
5140      out([hpf(scale(x1)), hpf(transformScaleY(y1)), hpf(scale(x2)), hpf(transformScaleY(y2)), hpf(scale(x3)), hpf(transformScaleY(y3)), "c"].join(" "));
5141      return this;
5142    };
5143    /**
5144     * Draw a line on the current page.
5145     *
5146     * @name line
5147     * @function
5148     * @instance
5149     * @param {number} x1
5150     * @param {number} y1
5151     * @param {number} x2
5152     * @param {number} y2
5153     * @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. default: 'S'
5154     * @returns {jsPDF}
5155     * @memberof jsPDF#
5156     */
5157
5158
5159    API.__private__.line = API.line = function (x1, y1, x2, y2, style) {
5160      if (isNaN(x1) || isNaN(y1) || isNaN(x2) || isNaN(y2) || !isValidStyle(style)) {
5161        throw new Error("Invalid arguments passed to jsPDF.line");
5162      }
5163
5164      if (apiMode === ApiMode.COMPAT) {
5165        return this.lines([[x2 - x1, y2 - y1]], x1, y1, [1, 1], style || "S");
5166      } else {
5167        return this.lines([[x2 - x1, y2 - y1]], x1, y1, [1, 1]).stroke();
5168      }
5169    };
5170    /**
5171     * @typedef {Object} PatternData
5172     * {Matrix|undefined} matrix
5173     * {Number|undefined} xStep
5174     * {Number|undefined} yStep
5175     * {Array.<Number>|undefined} boundingBox
5176     */
5177
5178    /**
5179     * Adds series of curves (straight lines or cubic bezier curves) to canvas, starting at `x`, `y` coordinates.
5180     * All data points in `lines` are relative to last line origin.
5181     * `x`, `y` become x1,y1 for first line / curve in the set.
5182     * For lines you only need to specify [x2, y2] - (ending point) vector against x1, y1 starting point.
5183     * 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.
5184     *
5185     * @example .lines([[2,2],[-2,2],[1,1,2,2,3,3],[2,1]], 212,110, [1,1], 'F', false) // line, line, bezier curve, line
5186     * @param {Array} lines Array of *vector* shifts as pairs (lines) or sextets (cubic bezier curves).
5187     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
5188     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
5189     * @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.
5190     * @param {string=} style A string specifying the painting style or null. Valid styles include:
5191     * 'S' [default] - stroke,
5192     * 'F' - fill,
5193     * and 'DF' (or 'FD') -  fill then stroke.
5194     * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple
5195     * method calls. The last drawing method call used to define the shape should not have a null style argument.
5196     *
5197     * In "advanced" API mode this parameter is deprecated.
5198     * @param {Boolean=} closed If true, the path is closed with a straight line from the end of the last curve to the starting point.
5199     * @function
5200     * @instance
5201     * @returns {jsPDF}
5202     * @memberof jsPDF#
5203     * @name lines
5204     */
5205
5206
5207    API.__private__.lines = API.lines = function (lines, x, y, scale, style, closed) {
5208      var scalex, scaley, i, l, leg, x2, y2, x3, y3, x4, y4, tmp; // Pre-August-2012 the order of arguments was function(x, y, lines, scale, style)
5209      // in effort to make all calls have similar signature like
5210      //   function(content, coordinateX, coordinateY , miscellaneous)
5211      // this method had its args flipped.
5212      // code below allows backward compatibility with old arg order.
5213
5214      if (typeof lines === "number") {
5215        tmp = y;
5216        y = x;
5217        x = lines;
5218        lines = tmp;
5219      }
5220
5221      scale = scale || [1, 1];
5222      closed = closed || false;
5223
5224      if (isNaN(x) || isNaN(y) || !Array.isArray(lines) || !Array.isArray(scale) || !isValidStyle(style) || typeof closed !== "boolean") {
5225        throw new Error("Invalid arguments passed to jsPDF.lines");
5226      } // starting point
5227
5228
5229      moveTo(x, y);
5230      scalex = scale[0];
5231      scaley = scale[1];
5232      l = lines.length; //, x2, y2 // bezier only. In page default measurement "units", *after* scaling
5233      //, x3, y3 // bezier only. In page default measurement "units", *after* scaling
5234      // ending point for all, lines and bezier. . In page default measurement "units", *after* scaling
5235
5236      x4 = x; // last / ending point = starting point for first item.
5237
5238      y4 = y; // last / ending point = starting point for first item.
5239
5240      for (i = 0; i < l; i++) {
5241        leg = lines[i];
5242
5243        if (leg.length === 2) {
5244          // simple line
5245          x4 = leg[0] * scalex + x4; // here last x4 was prior ending point
5246
5247          y4 = leg[1] * scaley + y4; // here last y4 was prior ending point
5248
5249          lineTo(x4, y4);
5250        } else {
5251          // bezier curve
5252          x2 = leg[0] * scalex + x4; // here last x4 is prior ending point
5253
5254          y2 = leg[1] * scaley + y4; // here last y4 is prior ending point
5255
5256          x3 = leg[2] * scalex + x4; // here last x4 is prior ending point
5257
5258          y3 = leg[3] * scaley + y4; // here last y4 is prior ending point
5259
5260          x4 = leg[4] * scalex + x4; // here last x4 was prior ending point
5261
5262          y4 = leg[5] * scaley + y4; // here last y4 was prior ending point
5263
5264          curveTo(x2, y2, x3, y3, x4, y4);
5265        }
5266      }
5267
5268      if (closed) {
5269        close();
5270      }
5271
5272      putStyle(style);
5273      return this;
5274    };
5275    /**
5276     * Similar to {@link API.lines} but all coordinates are interpreted as absolute coordinates instead of relative.
5277     * @param {Array<Object>} lines An array of {op: operator, c: coordinates} object, where op is one of "m" (move to), "l" (line to)
5278     * "c" (cubic bezier curve) and "h" (close (sub)path)). c is an array of coordinates. "m" and "l" expect two, "c"
5279     * six and "h" an empty array (or undefined).
5280     * @function
5281     * @returns {jsPDF}
5282     * @memberof jsPDF#
5283     * @name path
5284     */
5285
5286
5287    API.path = function (lines) {
5288      for (var i = 0; i < lines.length; i++) {
5289        var leg = lines[i];
5290        var coords = leg.c;
5291
5292        switch (leg.op) {
5293          case "m":
5294            moveTo(coords[0], coords[1]);
5295            break;
5296
5297          case "l":
5298            lineTo(coords[0], coords[1]);
5299            break;
5300
5301          case "c":
5302            curveTo.apply(this, coords);
5303            break;
5304
5305          case "h":
5306            close();
5307            break;
5308        }
5309      }
5310
5311      return this;
5312    };
5313    /**
5314     * Adds a rectangle to PDF.
5315     *
5316     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
5317     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
5318     * @param {number} w Width (in units declared at inception of PDF document)
5319     * @param {number} h Height (in units declared at inception of PDF document)
5320     * @param {string=} style A string specifying the painting style or null. Valid styles include:
5321     * 'S' [default] - stroke,
5322     * 'F' - fill,
5323     * and 'DF' (or 'FD') -  fill then stroke.
5324     * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple
5325     * method calls. The last drawing method call used to define the shape should not have a null style argument.
5326     *
5327     * In "advanced" API mode this parameter is deprecated.
5328     * @function
5329     * @instance
5330     * @returns {jsPDF}
5331     * @memberof jsPDF#
5332     * @name rect
5333     */
5334
5335
5336    API.__private__.rect = API.rect = function (x, y, w, h, style) {
5337      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h) || !isValidStyle(style)) {
5338        throw new Error("Invalid arguments passed to jsPDF.rect");
5339      }
5340
5341      if (apiMode === ApiMode.COMPAT) {
5342        h = -h;
5343      }
5344
5345      out([hpf(scale(x)), hpf(transformScaleY(y)), hpf(scale(w)), hpf(scale(h)), "re"].join(" "));
5346      putStyle(style);
5347      return this;
5348    };
5349    /**
5350     * Adds a triangle to PDF.
5351     *
5352     * @param {number} x1 Coordinate (in units declared at inception of PDF document) against left edge of the page
5353     * @param {number} y1 Coordinate (in units declared at inception of PDF document) against upper edge of the page
5354     * @param {number} x2 Coordinate (in units declared at inception of PDF document) against left edge of the page
5355     * @param {number} y2 Coordinate (in units declared at inception of PDF document) against upper edge of the page
5356     * @param {number} x3 Coordinate (in units declared at inception of PDF document) against left edge of the page
5357     * @param {number} y3 Coordinate (in units declared at inception of PDF document) against upper edge of the page
5358     * @param {string=} style A string specifying the painting style or null. Valid styles include:
5359     * 'S' [default] - stroke,
5360     * 'F' - fill,
5361     * and 'DF' (or 'FD') -  fill then stroke.
5362     * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple
5363     * method calls. The last drawing method call used to define the shape should not have a null style argument.
5364     *
5365     * In "advanced" API mode this parameter is deprecated.
5366     * @function
5367     * @instance
5368     * @returns {jsPDF}
5369     * @memberof jsPDF#
5370     * @name triangle
5371     */
5372
5373
5374    API.__private__.triangle = API.triangle = function (x1, y1, x2, y2, x3, y3, style) {
5375      if (isNaN(x1) || isNaN(y1) || isNaN(x2) || isNaN(y2) || isNaN(x3) || isNaN(y3) || !isValidStyle(style)) {
5376        throw new Error("Invalid arguments passed to jsPDF.triangle");
5377      }
5378
5379      this.lines([[x2 - x1, y2 - y1], // vector to point 2
5380      [x3 - x2, y3 - y2], // vector to point 3
5381      [x1 - x3, y1 - y3] // closing vector back to point 1
5382      ], x1, y1, // start of path
5383      [1, 1], style, true);
5384      return this;
5385    };
5386    /**
5387     * Adds a rectangle with rounded corners to PDF.
5388     *
5389     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
5390     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
5391     * @param {number} w Width (in units declared at inception of PDF document)
5392     * @param {number} h Height (in units declared at inception of PDF document)
5393     * @param {number} rx Radius along x axis (in units declared at inception of PDF document)
5394     * @param {number} ry Radius along y axis (in units declared at inception of PDF document)
5395     * @param {string=} style A string specifying the painting style or null. Valid styles include:
5396     * 'S' [default] - stroke,
5397     * 'F' - fill,
5398     * and 'DF' (or 'FD') -  fill then stroke.
5399     * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple
5400     * method calls. The last drawing method call used to define the shape should not have a null style argument.
5401     *
5402     * In "advanced" API mode this parameter is deprecated.
5403     * @function
5404     * @instance
5405     * @returns {jsPDF}
5406     * @memberof jsPDF#
5407     * @name roundedRect
5408     */
5409
5410
5411    API.__private__.roundedRect = API.roundedRect = function (x, y, w, h, rx, ry, style) {
5412      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h) || isNaN(rx) || isNaN(ry) || !isValidStyle(style)) {
5413        throw new Error("Invalid arguments passed to jsPDF.roundedRect");
5414      }
5415
5416      var MyArc = 4 / 3 * (Math.SQRT2 - 1);
5417      rx = Math.min(rx, w * 0.5);
5418      ry = Math.min(ry, h * 0.5);
5419      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
5420      [1, 1], style, true);
5421      return this;
5422    };
5423    /**
5424     * Adds an ellipse to PDF.
5425     *
5426     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
5427     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
5428     * @param {number} rx Radius along x axis (in units declared at inception of PDF document)
5429     * @param {number} ry Radius along y axis (in units declared at inception of PDF document)
5430     * @param {string=} style A string specifying the painting style or null. Valid styles include:
5431     * 'S' [default] - stroke,
5432     * 'F' - fill,
5433     * and 'DF' (or 'FD') -  fill then stroke.
5434     * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple
5435     * method calls. The last drawing method call used to define the shape should not have a null style argument.
5436     *
5437     * In "advanced" API mode this parameter is deprecated.
5438     * @function
5439     * @instance
5440     * @returns {jsPDF}
5441     * @memberof jsPDF#
5442     * @name ellipse
5443     */
5444
5445
5446    API.__private__.ellipse = API.ellipse = function (x, y, rx, ry, style) {
5447      if (isNaN(x) || isNaN(y) || isNaN(rx) || isNaN(ry) || !isValidStyle(style)) {
5448        throw new Error("Invalid arguments passed to jsPDF.ellipse");
5449      }
5450
5451      var lx = 4 / 3 * (Math.SQRT2 - 1) * rx,
5452          ly = 4 / 3 * (Math.SQRT2 - 1) * ry;
5453      moveTo(x + rx, y);
5454      curveTo(x + rx, y - ly, x + lx, y - ry, x, y - ry);
5455      curveTo(x - lx, y - ry, x - rx, y - ly, x - rx, y);
5456      curveTo(x - rx, y + ly, x - lx, y + ry, x, y + ry);
5457      curveTo(x + lx, y + ry, x + rx, y + ly, x + rx, y);
5458      putStyle(style);
5459      return this;
5460    };
5461    /**
5462     * Adds an circle to PDF.
5463     *
5464     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
5465     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
5466     * @param {number} r Radius (in units declared at inception of PDF document)
5467     * @param {string=} style A string specifying the painting style or null. Valid styles include:
5468     * 'S' [default] - stroke,
5469     * 'F' - fill,
5470     * and 'DF' (or 'FD') -  fill then stroke.
5471     * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple
5472     * method calls. The last drawing method call used to define the shape should not have a null style argument.
5473     *
5474     * In "advanced" API mode this parameter is deprecated.
5475     * @function
5476     * @instance
5477     * @returns {jsPDF}
5478     * @memberof jsPDF#
5479     * @name circle
5480     */
5481
5482
5483    API.__private__.circle = API.circle = function (x, y, r, style) {
5484      if (isNaN(x) || isNaN(y) || isNaN(r) || !isValidStyle(style)) {
5485        throw new Error("Invalid arguments passed to jsPDF.circle");
5486      }
5487
5488      return this.ellipse(x, y, r, r, style);
5489    };
5490    /**
5491     * Sets text font face, variant for upcoming text elements.
5492     * See output of jsPDF.getFontList() for possible font names, styles.
5493     *
5494     * @param {string} fontName Font name or family. Example: "times".
5495     * @param {string} fontStyle Font style or variant. Example: "italic".
5496     * @param {number | string} fontWeight Weight of the Font. Example: "normal" | 400
5497     * @function
5498     * @instance
5499     * @returns {jsPDF}
5500     * @memberof jsPDF#
5501     * @name setFont
5502     */
5503
5504
5505    API.setFont = function (fontName, fontStyle, fontWeight) {
5506      if (fontWeight) {
5507        fontStyle = combineFontStyleAndFontWeight(fontStyle, fontWeight);
5508      }
5509
5510      activeFontKey = getFont(fontName, fontStyle, {
5511        disableWarning: false
5512      });
5513      return this;
5514    };
5515    /**
5516     * Gets text font face, variant for upcoming text elements.
5517     *
5518     * @function
5519     * @instance
5520     * @returns {Object}
5521     * @memberof jsPDF#
5522     * @name getFont
5523     */
5524
5525
5526    var getFontEntry = API.__private__.getFont = API.getFont = function () {
5527      return fonts[getFont.apply(API, arguments)];
5528    };
5529    /**
5530     * Returns an object - a tree of fontName to fontStyle relationships available to
5531     * active PDF document.
5532     *
5533     * @public
5534     * @function
5535     * @instance
5536     * @returns {Object} Like {'times':['normal', 'italic', ... ], 'arial':['normal', 'bold', ... ], ... }
5537     * @memberof jsPDF#
5538     * @name getFontList
5539     */
5540
5541
5542    API.__private__.getFontList = API.getFontList = function () {
5543      var list = {},
5544          fontName,
5545          fontStyle;
5546
5547      for (fontName in fontmap) {
5548        if (fontmap.hasOwnProperty(fontName)) {
5549          list[fontName] = [];
5550
5551          for (fontStyle in fontmap[fontName]) {
5552            if (fontmap[fontName].hasOwnProperty(fontStyle)) {
5553              list[fontName].push(fontStyle);
5554            }
5555          }
5556        }
5557      }
5558
5559      return list;
5560    };
5561    /**
5562     * Add a custom font to the current instance.
5563     *
5564     * @param {string} postScriptName PDF specification full name for the font.
5565     * @param {string} id PDF-document-instance-specific label assinged to the font.
5566     * @param {string} fontStyle Style of the Font.
5567     * @param {number | string} fontWeight Weight of the Font.
5568     * @param {Object} encoding Encoding_name-to-Font_metrics_object mapping.
5569     * @function
5570     * @instance
5571     * @memberof jsPDF#
5572     * @name addFont
5573     * @returns {string} fontId
5574     */
5575
5576
5577    API.addFont = function (postScriptName, fontName, fontStyle, fontWeight, encoding) {
5578      var encodingOptions = ["StandardEncoding", "MacRomanEncoding", "Identity-H", "WinAnsiEncoding"];
5579
5580      if (arguments[3] && encodingOptions.indexOf(arguments[3]) !== -1) {
5581        //IE 11 fix
5582        encoding = arguments[3];
5583      } else if (arguments[3] && encodingOptions.indexOf(arguments[3]) == -1) {
5584        fontStyle = combineFontStyleAndFontWeight(fontStyle, fontWeight);
5585      }
5586
5587      encoding = encoding || "Identity-H";
5588      return addFont.call(this, postScriptName, fontName, fontStyle, encoding);
5589    };
5590
5591    var lineWidth = options.lineWidth || 0.200025; // 2mm
5592
5593    /**
5594     * Gets the line width, default: 0.200025.
5595     *
5596     * @function
5597     * @instance
5598     * @returns {number} lineWidth
5599     * @memberof jsPDF#
5600     * @name getLineWidth
5601     */
5602
5603    var getLineWidth = API.__private__.getLineWidth = API.getLineWidth = function () {
5604      return lineWidth;
5605    };
5606    /**
5607     * Sets line width for upcoming lines.
5608     *
5609     * @param {number} width Line width (in units declared at inception of PDF document).
5610     * @function
5611     * @instance
5612     * @returns {jsPDF}
5613     * @memberof jsPDF#
5614     * @name setLineWidth
5615     */
5616
5617
5618    var setLineWidth = API.__private__.setLineWidth = API.setLineWidth = function (width) {
5619      lineWidth = width;
5620      out(hpf(scale(width)) + " w");
5621      return this;
5622    };
5623    /**
5624     * Sets the dash pattern for upcoming lines.
5625     *
5626     * To reset the settings simply call the method without any parameters.
5627     * @param {Array<number>} dashArray An array containing 0-2 numbers. The first number sets the length of the
5628     * dashes, the second number the length of the gaps. If the second number is missing, the gaps are considered
5629     * to be as long as the dashes. An empty array means solid, unbroken lines.
5630     * @param {number} dashPhase The phase lines start with.
5631     * @function
5632     * @instance
5633     * @returns {jsPDF}
5634     * @memberof jsPDF#
5635     * @name setLineDashPattern
5636     */
5637
5638
5639    API.__private__.setLineDash = jsPDF.API.setLineDash = jsPDF.API.setLineDashPattern = function (dashArray, dashPhase) {
5640      dashArray = dashArray || [];
5641      dashPhase = dashPhase || 0;
5642
5643      if (isNaN(dashPhase) || !Array.isArray(dashArray)) {
5644        throw new Error("Invalid arguments passed to jsPDF.setLineDash");
5645      }
5646
5647      dashArray = dashArray.map(function (x) {
5648        return hpf(scale(x));
5649      }).join(" ");
5650      dashPhase = hpf(scale(dashPhase));
5651      out("[" + dashArray + "] " + dashPhase + " d");
5652      return this;
5653    };
5654
5655    var lineHeightFactor;
5656
5657    var getLineHeight = API.__private__.getLineHeight = API.getLineHeight = function () {
5658      return activeFontSize * lineHeightFactor;
5659    };
5660
5661    API.__private__.getLineHeight = API.getLineHeight = function () {
5662      return activeFontSize * lineHeightFactor;
5663    };
5664    /**
5665     * Sets the LineHeightFactor of proportion.
5666     *
5667     * @param {number} value LineHeightFactor value. Default: 1.15.
5668     * @function
5669     * @instance
5670     * @returns {jsPDF}
5671     * @memberof jsPDF#
5672     * @name setLineHeightFactor
5673     */
5674
5675
5676    var setLineHeightFactor = API.__private__.setLineHeightFactor = API.setLineHeightFactor = function (value) {
5677      value = value || 1.15;
5678
5679      if (typeof value === "number") {
5680        lineHeightFactor = value;
5681      }
5682
5683      return this;
5684    };
5685    /**
5686     * Gets the LineHeightFactor, default: 1.15.
5687     *
5688     * @function
5689     * @instance
5690     * @returns {number} lineHeightFactor
5691     * @memberof jsPDF#
5692     * @name getLineHeightFactor
5693     */
5694
5695
5696    var getLineHeightFactor = API.__private__.getLineHeightFactor = API.getLineHeightFactor = function () {
5697      return lineHeightFactor;
5698    };
5699
5700    setLineHeightFactor(options.lineHeight);
5701
5702    var getHorizontalCoordinate = API.__private__.getHorizontalCoordinate = function (value) {
5703      return scale(value);
5704    };
5705
5706    var getVerticalCoordinate = API.__private__.getVerticalCoordinate = function (value) {
5707      if (apiMode === ApiMode.ADVANCED) {
5708        return value;
5709      } else {
5710        var pageHeight = pagesContext[currentPage].mediaBox.topRightY - pagesContext[currentPage].mediaBox.bottomLeftY;
5711        return pageHeight - scale(value);
5712      }
5713    };
5714
5715    var getHorizontalCoordinateString = API.__private__.getHorizontalCoordinateString = API.getHorizontalCoordinateString = function (value) {
5716      return hpf(getHorizontalCoordinate(value));
5717    };
5718
5719    var getVerticalCoordinateString = API.__private__.getVerticalCoordinateString = API.getVerticalCoordinateString = function (value) {
5720      return hpf(getVerticalCoordinate(value));
5721    };
5722
5723    var strokeColor = options.strokeColor || "0 G";
5724    /**
5725     *  Gets the stroke color for upcoming elements.
5726     *
5727     * @function
5728     * @instance
5729     * @returns {string} colorAsHex
5730     * @memberof jsPDF#
5731     * @name getDrawColor
5732     */
5733
5734    API.__private__.getStrokeColor = API.getDrawColor = function () {
5735      return decodeColorString(strokeColor);
5736    };
5737    /**
5738     * Sets the stroke color for upcoming elements.
5739     *
5740     * Depending on the number of arguments given, Gray, RGB, or CMYK
5741     * color space is implied.
5742     *
5743     * When only ch1 is given, "Gray" color space is implied and it
5744     * must be a value in the range from 0.00 (solid black) to to 1.00 (white)
5745     * if values are communicated as String types, or in range from 0 (black)
5746     * to 255 (white) if communicated as Number type.
5747     * The RGB-like 0-255 range is provided for backward compatibility.
5748     *
5749     * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each
5750     * value must be in the range from 0.00 (minimum intensity) to to 1.00
5751     * (max intensity) if values are communicated as String types, or
5752     * from 0 (min intensity) to to 255 (max intensity) if values are communicated
5753     * as Number types.
5754     * The RGB-like 0-255 range is provided for backward compatibility.
5755     *
5756     * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each
5757     * value must be a in the range from 0.00 (0% concentration) to to
5758     * 1.00 (100% concentration)
5759     *
5760     * Because JavaScript treats fixed point numbers badly (rounds to
5761     * floating point nearest to binary representation) it is highly advised to
5762     * communicate the fractional numbers as String types, not JavaScript Number type.
5763     *
5764     * @param {Number|String} ch1 Color channel value or {string}
5764 ch1 color value in hexadecimal, example: '#FFFFFF'.
5765     * @param {Number} ch2 Color channel value.
5766     * @param {Number} ch3 Color channel value.
5767     * @param {Number} ch4 Color channel value.
5768     *
5769     * @function
5770     * @instance
5771     * @returns {jsPDF}
5772     * @memberof jsPDF#
5773     * @name setDrawColor
5774     */
5775
5776
5777    API.__private__.setStrokeColor = API.setDrawColor = function (ch1, ch2, ch3, ch4) {
5778      var options = {
5779        ch1: ch1,
5780        ch2: ch2,
5781        ch3: ch3,
5782        ch4: ch4,
5783        pdfColorType: "draw",
5784        precision: 2
5785      };
5786      strokeColor = encodeColorString(options);
5787      out(strokeColor);
5788      return this;
5789    };
5790
5791    var fillColor = options.fillColor || "0 g";
5792    /**
5793     * Gets the fill color for upcoming elements.
5794     *
5795     * @function
5796     * @instance
5797     * @returns {string} colorAsHex
5798     * @memberof jsPDF#
5799     * @name getFillColor
5800     */
5801
5802    API.__private__.getFillColor = API.getFillColor = function () {
5803      return decodeColorString(fillColor);
5804    };
5805    /**
5806     * Sets the fill color for upcoming elements.
5807     *
5808     * Depending on the number of arguments given, Gray, RGB, or CMYK
5809     * color space is implied.
5810     *
5811     * When only ch1 is given, "Gray" color space is implied and it
5812     * must be a value in the range from 0.00 (solid black) to to 1.00 (white)
5813     * if values are communicated as String types, or in range from 0 (black)
5814     * to 255 (white) if communicated as Number type.
5815     * The RGB-like 0-255 range is provided for backward compatibility.
5816     *
5817     * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each
5818     * value must be in the range from 0.00 (minimum intensity) to to 1.00
5819     * (max intensity) if values are communicated as String types, or
5820     * from 0 (min intensity) to to 255 (max intensity) if values are communicated
5821     * as Number types.
5822     * The RGB-like 0-255 range is provided for backward compatibility.
5823     *
5824     * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each
5825     * value must be a in the range from 0.00 (0% concentration) to to
5826     * 1.00 (100% concentration)
5827     *
5828     * Because JavaScript treats fixed point numbers badly (rounds to
5829     * floating point nearest to binary representation) it is highly advised to
5830     * communicate the fractional numbers as String types, not JavaScript Number type.
5831     *
5832     * @param {Number|String} ch1 Color channel value or {string} ch1 color value in hexadecimal, example: '#FFFFFF'.
5833     * @param {Number} ch2 Color channel value.
5834     * @param {Number} ch3 Color channel value.
5835     * @param {Number} ch4 Color channel value.
5836     *
5837     * @function
5838     * @instance
5839     * @returns {jsPDF}
5840     * @memberof jsPDF#
5841     * @name setFillColor
5842     */
5843
5844
5845    API.__private__.setFillColor = API.setFillColor = function (ch1, ch2, ch3, ch4) {
5846      var options = {
5847        ch1: ch1,
5848        ch2: ch2,
5849        ch3: ch3,
5850        ch4: ch4,
5851        pdfColorType: "fill",
5852        precision: 2
5853      };
5854      fillColor = encodeColorString(options);
5855      out(fillColor);
5856      return this;
5857    };
5858
5859    var textColor = options.textColor || "0 g";
5860    /**
5861     * Gets the text color for upcoming elements.
5862     *
5863     * @function
5864     * @instance
5865     * @returns {string} colorAsHex
5866     * @memberof jsPDF#
5867     * @name getTextColor
5868     */
5869
5870    var getTextColor = API.__private__.getTextColor = API.getTextColor = function () {
5871      return decodeColorString(textColor);
5872    };
5873    /**
5874     * Sets the text color for upcoming elements.
5875     *
5876     * Depending on the number of arguments given, Gray, RGB, or CMYK
5877     * color space is implied.
5878     *
5879     * When only ch1 is given, "Gray" color space is implied and it
5880     * must be a value in the range from 0.00 (solid black) to to 1.00 (white)
5881     * if values are communicated as String types, or in range from 0 (black)
5882     * to 255 (white) if communicated as Number type.
5883     * The RGB-like 0-255 range is provided for backward compatibility.
5884     *
5885     * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each
5886     * value must be in the range from 0.00 (minimum intensity) to to 1.00
5887     * (max intensity) if values are communicated as String types, or
5888     * from 0 (min intensity) to to 255 (max intensity) if values are communicated
5889     * as Number types.
5890     * The RGB-like 0-255 range is provided for backward compatibility.
5891     *
5892     * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each
5893     * value must be a in the range from 0.00 (0% concentration) to to
5894     * 1.00 (100% concentration)
5895     *
5896     * Because JavaScript treats fixed point numbers badly (rounds to
5897     * floating point nearest to binary representation) it is highly advised to
5898     * communicate the fractional numbers as String types, not JavaScript Number type.
5899     *
5900     * @param {Number|String} ch1 Color channel value or {string}
vendor: 11,927 bytes, lines 5900-6358
5900 ch1 color value in hexadecimal, example: '#FFFFFF'.
5901     * @param {Number} ch2 Color channel value.
5902     * @param {Number} ch3 Color channel value.
5903     * @param {Number} ch4 Color channel value.
5904     *
5905     * @function
5906     * @instance
5907     * @returns {jsPDF}
5908     * @memberof jsPDF#
5909     * @name setTextColor
5910     */
5911
5912
5913    API.__private__.setTextColor = API.setTextColor = function (ch1, ch2, ch3, ch4) {
5914      var options = {
5915        ch1: ch1,
5916        ch2: ch2,
5917        ch3: ch3,
5918        ch4: ch4,
5919        pdfColorType: "text",
5920        precision: 3
5921      };
5922      textColor = encodeColorString(options);
5923      return this;
5924    };
5925
5926    var activeCharSpace = options.charSpace;
5927    /**
5928     * Get global value of CharSpace.
5929     *
5930     * @function
5931     * @instance
5932     * @returns {number} charSpace
5933     * @memberof jsPDF#
5934     * @name getCharSpace
5935     */
5936
5937    var getCharSpace = API.__private__.getCharSpace = API.getCharSpace = function () {
5938      return parseFloat(activeCharSpace || 0);
5939    };
5940    /**
5941     * Set global value of CharSpace.
5942     *
5943     * @param {number} charSpace
5944     * @function
5945     * @instance
5946     * @returns {jsPDF} jsPDF-instance
5947     * @memberof jsPDF#
5948     * @name setCharSpace
5949     */
5950
5951
5952    API.__private__.setCharSpace = API.setCharSpace = function (charSpace) {
5953      if (isNaN(charSpace)) {
5954        throw new Error("Invalid argument passed to jsPDF.setCharSpace");
5955      }
5956
5957      activeCharSpace = charSpace;
5958      return this;
5959    };
5960
5961    var lineCapID = 0;
5962    /**
5963     * Is an Object providing a mapping from human-readable to
5964     * integer flag values designating the varieties of line cap
5965     * and join styles.
5966     *
5967     * @memberof jsPDF#
5968     * @name CapJoinStyles
5969     */
5970
5971    API.CapJoinStyles = {
5972      0: 0,
5973      butt: 0,
5974      but: 0,
5975      miter: 0,
5976      1: 1,
5977      round: 1,
5978      rounded: 1,
5979      circle: 1,
5980      2: 2,
5981      projecting: 2,
5982      project: 2,
5983      square: 2,
5984      bevel: 2
5985    };
5986    /**
5987     * Sets the line cap styles.
5988     * See {jsPDF.CapJoinStyles} for variants.
5989     *
5990     * @param {String|Number} style A string or number identifying the type of line cap.
5991     * @function
5992     * @instance
5993     * @returns {jsPDF}
5994     * @memberof jsPDF#
5995     * @name setLineCap
5996     */
5997
5998    API.__private__.setLineCap = API.setLineCap = function (style) {
5999      var id = API.CapJoinStyles[style];
6000
6001      if (id === undefined) {
6002        throw new Error("Line cap style of '" + style + "' is not recognized. See or extend .CapJoinStyles property for valid styles");
6003      }
6004
6005      lineCapID = id;
6006      out(id + " J");
6007      return this;
6008    };
6009
6010    var lineJoinID = 0;
6011    /**
6012     * Sets the line join styles.
6013     * See {jsPDF.CapJoinStyles} for variants.
6014     *
6015     * @param {String|Number} style A string or number identifying the type of line join.
6016     * @function
6017     * @instance
6018     * @returns {jsPDF}
6019     * @memberof jsPDF#
6020     * @name setLineJoin
6021     */
6022
6023    API.__private__.setLineJoin = API.setLineJoin = function (style) {
6024      var id = API.CapJoinStyles[style];
6025
6026      if (id === undefined) {
6027        throw new Error("Line join style of '" + style + "' is not recognized. See or extend .CapJoinStyles property for valid styles");
6028      }
6029
6030      lineJoinID = id;
6031      out(id + " j");
6032      return this;
6033    };
6034    /**
6035     * Sets the miterLimit property, which effects the maximum miter length.
6036     *
6037     * @param {number} length The length of the miter
6038     * @function
6039     * @instance
6040     * @returns {jsPDF}
6041     * @memberof jsPDF#
6042     * @name setLineMiterLimit
6043     */
6044
6045    API.__private__.setLineMiterLimit = API.__private__.setMiterLimit = API.setLineMiterLimit = API.setMiterLimit = function (length) {
6046      length = length || 0;
6047
6048      if (isNaN(length)) {
6049        throw new Error("Invalid argument passed to jsPDF.setLineMiterLimit");
6050      }
6051
6052      out(hpf(scale(length)) + " M");
6053      return this;
6054    };
6055    /**
6056     * An object representing a pdf graphics state.
6057     * @class GState
6058     */
6059
6060    /**
6061     *
6062     * @param parameters A parameter object that contains all properties this graphics state wants to set.
6063     * Supported are: opacity, stroke-opacity
6064     * @constructor
6065     */
6066
6067
6068    API.GState = GState;
6069    /**
6070     * Sets a either previously added {@link GState} (via {@link addGState}) or a new {@link GState}.
6071     * @param {String|GState} gState If type is string, a previously added GState is used, if type is GState
6072     * it will be added before use.
6073     * @function
6074     * @returns {jsPDF}
6075     * @memberof jsPDF#
6076     * @name setGState
6077     */
6078
6079    API.setGState = function (gState) {
6080      if (typeof gState === "string") {
6081        gState = gStates[gStatesMap[gState]];
6082      } else {
6083        gState = addGState(null, gState);
6084      }
6085
6086      if (!gState.equals(activeGState)) {
6087        out("/" + gState.id + " gs");
6088        activeGState = gState;
6089      }
6090    };
6091    /**
6092     * Adds a new Graphics State. Duplicates are automatically eliminated.
6093     * @param {String} key Might also be null, if no later reference to this gState is needed
6094     * @param {Object} gState The gState object
6095     */
6096
6097
6098    var addGState = function addGState(key, gState) {
6099      // only add it if it is not already present (the keys provided by the user must be unique!)
6100      if (key && gStatesMap[key]) return;
6101      var duplicate = false;
6102
6103      for (var s in gStates) {
6104        if (gStates.hasOwnProperty(s)) {
6105          if (gStates[s].equals(gState)) {
6106            duplicate = true;
6107            break;
6108          }
6109        }
6110      }
6111
6112      if (duplicate) {
6113        gState = gStates[s];
6114      } else {
6115        var gStateKey = "GS" + (Object.keys(gStates).length + 1).toString(10);
6116        gStates[gStateKey] = gState;
6117        gState.id = gStateKey;
6118      } // several user keys may point to the same GState object
6119
6120
6121      key && (gStatesMap[key] = gState.id);
6122      events.publish("addGState", gState);
6123      return gState;
6124    };
6125    /**
6126     * Adds a new {@link GState} for later use. See {@link setGState}.
6127     * @param {String} key
6128     * @param {GState} gState
6129     * @function
6130     * @instance
6131     * @returns {jsPDF}
6132     *
6133     * @memberof jsPDF#
6134     * @name addGState
6135     */
6136
6137
6138    API.addGState = function (key, gState) {
6139      addGState(key, gState);
6140      return this;
6141    };
6142    /**
6143     * Saves the current graphics state ("pushes it on the stack"). It can be restored by {@link restoreGraphicsState}
6144     * later. Here, the general pdf graphics state is meant, also including the current transformation matrix,
6145     * fill and stroke colors etc.
6146     * @function
6147     * @returns {jsPDF}
6148     * @memberof jsPDF#
6149     * @name saveGraphicsState
6150     */
6151
6152
6153    API.saveGraphicsState = function () {
6154      out("q"); // as we cannot set font key and size independently we must keep track of both
6155
6156      fontStateStack.push({
6157        key: activeFontKey,
6158        size: activeFontSize,
6159        color: textColor
6160      });
6161      return this;
6162    };
6163    /**
6164     * Restores a previously saved graphics state saved by {@link saveGraphicsState} ("pops the stack").
6165     * @function
6166     * @returns {jsPDF}
6167     * @memberof jsPDF#
6168     * @name restoreGraphicsState
6169     */
6170
6171
6172    API.restoreGraphicsState = function () {
6173      out("Q"); // restore previous font state
6174
6175      var fontState = fontStateStack.pop();
6176      activeFontKey = fontState.key;
6177      activeFontSize = fontState.size;
6178      textColor = fontState.color;
6179      activeGState = null;
6180      return this;
6181    };
6182    /**
6183     * Appends this matrix to the left of all previously applied matrices.
6184     *
6185     * @param {Matrix} matrix
6186     * @function
6187     * @returns {jsPDF}
6188     * @memberof jsPDF#
6189     * @name setCurrentTransformationMatrix
6190     */
6191
6192
6193    API.setCurrentTransformationMatrix = function (matrix) {
6194      out(matrix.toString() + " cm");
6195      return this;
6196    };
6197    /**
6198     * Inserts a debug comment into the generated pdf.
6199     * @function
6200     * @instance
6201     * @param {String} text
6202     * @returns {jsPDF}
6203     * @memberof jsPDF#
6204     * @name comment
6205     */
6206
6207
6208    API.comment = function (text) {
6209      out("#" + text);
6210      return this;
6211    };
6212    /**
6213     * Point
6214     */
6215
6216
6217    var Point = function Point(x, y) {
6218      var _x = x || 0;
6219
6220      Object.defineProperty(this, "x", {
6221        enumerable: true,
6222        get: function get() {
6223          return _x;
6224        },
6225        set: function set(value) {
6226          if (!isNaN(value)) {
6227            _x = parseFloat(value);
6228          }
6229        }
6230      });
6231
6232      var _y = y || 0;
6233
6234      Object.defineProperty(this, "y", {
6235        enumerable: true,
6236        get: function get() {
6237          return _y;
6238        },
6239        set: function set(value) {
6240          if (!isNaN(value)) {
6241            _y = parseFloat(value);
6242          }
6243        }
6244      });
6245      var _type = "pt";
6246      Object.defineProperty(this, "type", {
6247        enumerable: true,
6248        get: function get() {
6249          return _type;
6250        },
6251        set: function set(value) {
6252          _type = value.toString();
6253        }
6254      });
6255      return this;
6256    };
6257    /**
6258     * Rectangle
6259     */
6260
6261
6262    var Rectangle = function Rectangle(x, y, w, h) {
6263      Point.call(this, x, y);
6264      this.type = "rect";
6265
6266      var _w = w || 0;
6267
6268      Object.defineProperty(this, "w", {
6269        enumerable: true,
6270        get: function get() {
6271          return _w;
6272        },
6273        set: function set(value) {
6274          if (!isNaN(value)) {
6275            _w = parseFloat(value);
6276          }
6277        }
6278      });
6279
6280      var _h = h || 0;
6281
6282      Object.defineProperty(this, "h", {
6283        enumerable: true,
6284        get: function get() {
6285          return _h;
6286        },
6287        set: function set(value) {
6288          if (!isNaN(value)) {
6289            _h = parseFloat(value);
6290          }
6291        }
6292      });
6293      return this;
6294    };
6295    /**
6296     * FormObject/RenderTarget
6297     */
6298
6299
6300    var RenderTarget = function RenderTarget() {
6301      this.page = page;
6302      this.currentPage = currentPage;
6303      this.pages = pages.slice(0);
6304      this.pagesContext = pagesContext.slice(0);
6305      this.x = pageX;
6306      this.y = pageY;
6307      this.matrix = pageMatrix;
6308      this.width = getPageWidth(currentPage);
6309      this.height = getPageHeight(currentPage);
6310      this.outputDestination = outputDestination;
6311      this.id = ""; // set by endFormObject()
6312
6313      this.objectNumber = -1; // will be set by putXObject()
6314    };
6315
6316    RenderTarget.prototype.restore = function () {
6317      page = this.page;
6318      currentPage = this.currentPage;
6319      pagesContext = this.pagesContext;
6320      pages = this.pages;
6321      pageX = this.x;
6322      pageY = this.y;
6323      pageMatrix = this.matrix;
6324      setPageWidth(currentPage, this.width);
6325      setPageHeight(currentPage, this.height);
6326      outputDestination = this.outputDestination;
6327    };
6328
6329    var beginNewRenderTarget = function beginNewRenderTarget(x, y, width, height, matrix) {
6330      // save current state
6331      renderTargetStack.push(new RenderTarget()); // clear pages
6332
6333      page = currentPage = 0;
6334      pages = [];
6335      pageX = x;
6336      pageY = y;
6337      pageMatrix = matrix;
6338      beginPage([width, height]);
6339    };
6340
6341    var endFormObject = function endFormObject(key) {
6342      // only add it if it is not already present (the keys provided by the user must be unique!)
6343      if (renderTargetMap[key]) {
6344        renderTargetStack.pop().restore();
6345        return;
6346      } // save the created xObject
6347
6348
6349      var newXObject = new RenderTarget();
6350      var xObjectId = "Xo" + (Object.keys(renderTargets).length + 1).toString(10);
6351      newXObject.id = xObjectId;
6352      renderTargetMap[key] = xObjectId;
6353      renderTargets[xObjectId] = newXObject;
6354      events.publish("addFormObject", newXObject); // restore state from stack
6355
6356      renderTargetStack.pop().restore();
6357    };
6358    /**
6359     * Starts a new pdf form object, which means that all consequent draw calls target a new independent object
6360     * until {@link endFormObject} is called. The created object can be referenced and drawn later using
6361     * {@link doFormObject}. Nested form objects are possible.
6362     * x, y, width, height set the bounding box that is used to clip the content.
6363     *
6364     * @param {number} x
6365     * @param {number} y
6366     * @param {number} width
6367     * @param {number} height
6368     * @param {Matrix} matrix The matrix that will be applied to convert the form objects coordinate system to
6369     * the parent's.
6370     * @function
6371     * @returns {jsPDF}
6372     * @memberof jsPDF#
6373     * @name beginFormObject
6374     */
6375
6376
6377    API.beginFormObject = function (x, y, width, height, matrix) {
6378      // The user can set the output target to a new form object. Nested form objects are possible.
6379      // Currently, they use the resource dictionary of the surrounding stream. This should be changed, as
6380      // the PDF-Spec states:
6381      // "In PDF 1.2 and later versions, form XObjects may be independent of the content streams in which
6382      // they appear, and this is strongly recommended although not requiredIn PDF 1.2 and later versions,
6383      // form XObjects may be independent of the content streams in which they appear, and this is strongly
6384      // recommended although not required"
6385      beginNewRenderTarget(x, y, width, height, matrix);
6386      return this;
6387    };
6388    /**
6389     * Completes and saves the form object.
6390     * @param {String} key The key by which this form object can be referenced.
6391     * @function
6392     * @returns {jsPDF}
6393     * @memberof jsPDF#
6394     * @name endFormObject
6395     */
6396
6397
6398    API.endFormObject = function (key) {
6399      endFormObject(key);
6400      return this;
6401    };
6402    /**
6403     * Draws the specified form object by referencing to the respective pdf XObject created with
6404     * {@link API.beginFormObject} and {@link endFormObject}.
6405     * The location is determined by matrix.
6406     *
6407     * @param {String} key The key to the form object.
6408     * @param {Matrix} matrix The matrix applied before drawing the form object.
6409     * @function
6410     * @returns {jsPDF}
6411     * @memberof jsPDF#
6412     * @name doFormObject
6413     */
6414
6415
6416    API.doFormObject = function (key, matrix) {
6417      var xObject = renderTargets[renderTargetMap[key]];
6418      out("q");
6419      out(matrix.toString() + " cm");
6420      out("/" + xObject.id + " Do");
6421      out("Q");
6422      return this;
6423    };
6424    /**
6425     * Returns the form object specified by key.
6426     * @param key {String}
6427     * @returns {{x: number, y: number, width: number, height: number, matrix: Matrix}}
6428     * @function
6429     * @returns {jsPDF}
6430     * @memberof jsPDF#
6431     * @name getFormObject
6432     */
6433
6434
6435    API.getFormObject = function (key) {
6436      var xObject = renderTargets[renderTargetMap[key]];
6437      return {
6438        x: xObject.x,
6439        y: xObject.y,
6440        width: xObject.width,
6441        height: xObject.height,
6442        matrix: xObject.matrix
6443      };
6444    };
6445    /**
6446     * Saves as PDF document. An alias of jsPDF.output('save', 'filename.pdf').
6447     * Uses FileSaver.js-method saveAs.
6448     *
6449     * @memberof jsPDF#
6450     * @name save
6451     * @function
6452     * @instance
6453     * @param  {string} filename The filename including extension.
6454     * @param  {Object} options An Object with additional options, possible options: 'returnPromise'.
6455     * @returns {jsPDF|Promise} jsPDF-instance     */
6456
6457
6458    API.save = function (filename, options) {
6459      filename = filename || "generated.pdf";
6460      options = options || {};
6461      options.returnPromise = options.returnPromise || false;
6462
6463      if (options.returnPromise === false) {
6464        saveAs(getBlob(buildDocument()), filename);
6465
6466        if (typeof saveAs.unload === "function") {
6467          if (globalObject.setTimeout) {
6468            setTimeout(saveAs.unload, 911);
6469          }
6470        }
6471
6472        return this;
6473      } else {
6474        return new Promise(function (resolve, reject) {
6475          try {
6476            var result = saveAs(getBlob(buildDocument()), filename);
6477
6478            if (typeof saveAs.unload === "function") {
6479              if (globalObject.setTimeout) {
6480                setTimeout(saveAs.unload, 911);
6481              }
6482            }
6483
6484            resolve(result);
6485          } catch (e) {
6486            reject(e.message);
6487          }
6488        });
6489      }
6490    }; // applying plugins (more methods) ON TOP of built-in API.
6491    // this is intentional as we allow plugins to override
6492    // built-ins
6493
6494
6495    for (var plugin in jsPDF.API) {
6496      if (jsPDF.API.hasOwnProperty(plugin)) {
6497        if (plugin === "events" && jsPDF.API.events.length) {
6498          (function (events, newEvents) {
6499            // jsPDF.API.events is a JS Array of Arrays
6500            // where each Array is a pair of event name, handler
6501            // Events were added by plugins to the jsPDF instantiator.
6502            // These are always added to the new instance and some ran
6503            // during instantiation.
6504            var eventname, handler_and_args, i;
6505
6506            for (i = newEvents.length - 1; i !== -1; i--) {
6507              // subscribe takes 3 args: 'topic', function, runonce_flag
6508              // if undefined, runonce is false.
6509              // users can attach callback directly,
6510              // or they can attach an array with [callback, runonce_flag]
6511              // that's what the "apply" magic is for below.
vendor: 66,795 bytes, lines 6512-8851
6512              eventname = newEvents[i][0];
6513              handler_and_args = newEvents[i][1];
6514              events.subscribe.apply(events, [eventname].concat(typeof handler_and_args === "function" ? [handler_and_args] : handler_and_args));
6515            }
6516          })(events, jsPDF.API.events);
6517        } else {
6518          API[plugin] = jsPDF.API[plugin];
6519        }
6520      }
6521    }
6522
6523    var getPageWidth = API.getPageWidth = function (pageNumber) {
6524      pageNumber = pageNumber || currentPage;
6525      return (pagesContext[pageNumber].mediaBox.topRightX - pagesContext[pageNumber].mediaBox.bottomLeftX) / scaleFactor;
6526    };
6527
6528    var setPageWidth = API.setPageWidth = function (pageNumber, value) {
6529      pagesContext[pageNumber].mediaBox.topRightX = value * scaleFactor + pagesContext[pageNumber].mediaBox.bottomLeftX;
6530    };
6531
6532    var getPageHeight = API.getPageHeight = function (pageNumber) {
6533      pageNumber = pageNumber || currentPage;
6534      return (pagesContext[pageNumber].mediaBox.topRightY - pagesContext[pageNumber].mediaBox.bottomLeftY) / scaleFactor;
6535    };
6536
6537    var setPageHeight = API.setPageHeight = function (pageNumber, value) {
6538      pagesContext[pageNumber].mediaBox.topRightY = value * scaleFactor + pagesContext[pageNumber].mediaBox.bottomLeftY;
6539    };
6540    /**
6541     * Object exposing internal API to plugins
6542     * @public
6543     * @ignore
6544     */
6545
6546
6547    API.internal = {
6548      pdfEscape: pdfEscape,
6549      getStyle: getStyle,
6550      getFont: getFontEntry,
6551      getFontSize: getFontSize,
6552      getCharSpace: getCharSpace,
6553      getTextColor: getTextColor,
6554      getLineHeight: getLineHeight,
6555      getLineHeightFactor: getLineHeightFactor,
6556      getLineWidth: getLineWidth,
6557      write: write,
6558      getHorizontalCoordinate: getHorizontalCoordinate,
6559      getVerticalCoordinate: getVerticalCoordinate,
6560      getCoordinateString: getHorizontalCoordinateString,
6561      getVerticalCoordinateString: getVerticalCoordinateString,
6562      collections: {},
6563      newObject: newObject,
6564      newAdditionalObject: newAdditionalObject,
6565      newObjectDeferred: newObjectDeferred,
6566      newObjectDeferredBegin: newObjectDeferredBegin,
6567      getFilters: getFilters,
6568      putStream: putStream,
6569      events: events,
6570      scaleFactor: scaleFactor,
6571      pageSize: {
6572        getWidth: function getWidth() {
6573          return getPageWidth(currentPage);
6574        },
6575        setWidth: function setWidth(value) {
6576          setPageWidth(currentPage, value);
6577        },
6578        getHeight: function getHeight() {
6579          return getPageHeight(currentPage);
6580        },
6581        setHeight: function setHeight(value) {
6582          setPageHeight(currentPage, value);
6583        }
6584      },
6585      encryptionOptions: encryptionOptions,
6586      encryption: encryption,
6587      getEncryptor: getEncryptor,
6588      output: output,
6589      getNumberOfPages: getNumberOfPages,
6590      pages: pages,
6591      out: out,
6592      f2: f2,
6593      f3: f3,
6594      getPageInfo: getPageInfo,
6595      getPageInfoByObjId: getPageInfoByObjId,
6596      getCurrentPageInfo: getCurrentPageInfo,
6597      getPDFVersion: getPdfVersion,
6598      Point: Point,
6599      Rectangle: Rectangle,
6600      Matrix: Matrix,
6601      hasHotfix: hasHotfix //Expose the hasHotfix check so plugins can also check them.
6602
6603    };
6604    Object.defineProperty(API.internal.pageSize, "width", {
6605      get: function get() {
6606        return getPageWidth(currentPage);
6607      },
6608      set: function set(value) {
6609        setPageWidth(currentPage, value);
6610      },
6611      enumerable: true,
6612      configurable: true
6613    });
6614    Object.defineProperty(API.internal.pageSize, "height", {
6615      get: function get() {
6616        return getPageHeight(currentPage);
6617      },
6618      set: function set(value) {
6619        setPageHeight(currentPage, value);
6620      },
6621      enumerable: true,
6622      configurable: true
6623    }); //////////////////////////////////////////////////////
6624    // continuing initialization of jsPDF Document object
6625    //////////////////////////////////////////////////////
6626    // Add the first page automatically
6627
6628    addFonts.call(API, standardFonts);
6629    activeFontKey = "F1";
6630
6631    _addPage(format, orientation);
6632
6633    events.publish("initialized");
6634    return API;
6635  }
6636  /**
6637   * jsPDF.API is a STATIC property of jsPDF class.
6638   * jsPDF.API is an object you can add methods and properties to.
6639   * The methods / properties you add will show up in new jsPDF objects.
6640   *
6641   * One property is prepopulated. It is the 'events' Object. Plugin authors can add topics,
6642   * callbacks to this object. These will be reassigned to all new instances of jsPDF.
6643   *
6644   * @static
6645   * @public
6646   * @memberof jsPDF#
6647   * @name API
6648   *
6649   * @example
6650   * jsPDF.API.mymethod = function(){
6651   *   // 'this' will be ref to internal API object. see jsPDF source
6652   *   // , so you can refer to built-in methods like so:
6653   *   //     this.line(....)
6654   *   //     this.text(....)
6655   * }
6656   * var pdfdoc = new jsPDF()
6657   * pdfdoc.mymethod() // <- !!!!!!
6658   */
6659
6660
6661  jsPDF.API = {
6662    events: []
6663  };
6664  /**
6665   * The version of jsPDF.
6666   * @name version
6667   * @type {string}
6668   * @memberof jsPDF#
6669   */
6670
6671  jsPDF.version = "2.5.1";
6672
6673  var jsPDFAPI = jsPDF.API;
6674  var scaleFactor = 1;
6675
6676  var pdfEscape = function pdfEscape(value) {
6677    return value.replace(/\\/g, "\\\\").replace(/\(/g, "\\(").replace(/\)/g, "\\)");
6678  };
6679
6680  var pdfUnescape = function pdfUnescape(value) {
6681    return value.replace(/\\\\/g, "\\").replace(/\\\(/g, "(").replace(/\\\)/g, ")");
6682  };
6683
6684  var f2 = function f2(number) {
6685    return number.toFixed(2); // Ie, %.2f
6686  };
6687
6688  var f5 = function f5(number) {
6689    return number.toFixed(5); // Ie, %.2f
6690  };
6691
6692  jsPDFAPI.__acroform__ = {};
6693
6694  var inherit = function inherit(child, parent) {
6695    child.prototype = Object.create(parent.prototype);
6696    child.prototype.constructor = child;
6697  };
6698
6699  var scale = function scale(x) {
6700    return x * scaleFactor;
6701  };
6702
6703  var createFormXObject = function createFormXObject(formObject) {
6704    var xobj = new AcroFormXObject();
6705    var height = AcroFormAppearance.internal.getHeight(formObject) || 0;
6706    var width = AcroFormAppearance.internal.getWidth(formObject) || 0;
6707    xobj.BBox = [0, 0, Number(f2(width)), Number(f2(height))];
6708    return xobj;
6709  };
6710  /**
6711   * Bit-Operations
6712   */
6713
6714
6715  var setBit = jsPDFAPI.__acroform__.setBit = function (number, bitPosition) {
6716    number = number || 0;
6717    bitPosition = bitPosition || 0;
6718
6719    if (isNaN(number) || isNaN(bitPosition)) {
6720      throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.setBit");
6721    }
6722
6723    var bitMask = 1 << bitPosition;
6724    number |= bitMask;
6725    return number;
6726  };
6727
6728  var clearBit = jsPDFAPI.__acroform__.clearBit = function (number, bitPosition) {
6729    number = number || 0;
6730    bitPosition = bitPosition || 0;
6731
6732    if (isNaN(number) || isNaN(bitPosition)) {
6733      throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.clearBit");
6734    }
6735
6736    var bitMask = 1 << bitPosition;
6737    number &= ~bitMask;
6738    return number;
6739  };
6740
6741  var getBit = jsPDFAPI.__acroform__.getBit = function (number, bitPosition) {
6742    if (isNaN(number) || isNaN(bitPosition)) {
6743      throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.getBit");
6744    }
6745
6746    return (number & 1 << bitPosition) === 0 ? 0 : 1;
6747  };
6748  /*
6749   * Ff starts counting the bit position at 1 and not like javascript at 0
6750   */
6751
6752
6753  var getBitForPdf = jsPDFAPI.__acroform__.getBitForPdf = function (number, bitPosition) {
6754    if (isNaN(number) || isNaN(bitPosition)) {
6755      throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.getBitForPdf");
6756    }
6757
6758    return getBit(number, bitPosition - 1);
6759  };
6760
6761  var setBitForPdf = jsPDFAPI.__acroform__.setBitForPdf = function (number, bitPosition) {
6762    if (isNaN(number) || isNaN(bitPosition)) {
6763      throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.setBitForPdf");
6764    }
6765
6766    return setBit(number, bitPosition - 1);
6767  };
6768
6769  var clearBitForPdf = jsPDFAPI.__acroform__.clearBitForPdf = function (number, bitPosition) {
6770    if (isNaN(number) || isNaN(bitPosition)) {
6771      throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.clearBitForPdf");
6772    }
6773
6774    return clearBit(number, bitPosition - 1);
6775  };
6776
6777  var calculateCoordinates = jsPDFAPI.__acroform__.calculateCoordinates = function (args, scope) {
6778    var getHorizontalCoordinate = scope.internal.getHorizontalCoordinate;
6779    var getVerticalCoordinate = scope.internal.getVerticalCoordinate;
6780    var x = args[0];
6781    var y = args[1];
6782    var w = args[2];
6783    var h = args[3];
6784    var coordinates = {};
6785    coordinates.lowerLeft_X = getHorizontalCoordinate(x) || 0;
6786    coordinates.lowerLeft_Y = getVerticalCoordinate(y + h) || 0;
6787    coordinates.upperRight_X = getHorizontalCoordinate(x + w) || 0;
6788    coordinates.upperRight_Y = getVerticalCoordinate(y) || 0;
6789    return [Number(f2(coordinates.lowerLeft_X)), Number(f2(coordinates.lowerLeft_Y)), Number(f2(coordinates.upperRight_X)), Number(f2(coordinates.upperRight_Y))];
6790  };
6791
6792  var calculateAppearanceStream = function calculateAppearanceStream(formObject) {
6793    if (formObject.appearanceStreamContent) {
6794      return formObject.appearanceStreamContent;
6795    }
6796
6797    if (!formObject.V && !formObject.DV) {
6798      return;
6799    } // else calculate it
6800
6801
6802    var stream = [];
6803    var text = formObject._V || formObject.DV;
6804    var calcRes = calculateX(formObject, text);
6805    var fontKey = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle).id; //PDF 32000-1:2008, page 444
6806
6807    stream.push("/Tx BMC");
6808    stream.push("q");
6809    stream.push("BT"); // Begin Text
6810
6811    stream.push(formObject.scope.__private__.encodeColorString(formObject.color));
6812    stream.push("/" + fontKey + " " + f2(calcRes.fontSize) + " Tf");
6813    stream.push("1 0 0 1 0 0 Tm"); // Transformation Matrix
6814
6815    stream.push(calcRes.text);
6816    stream.push("ET"); // End Text
6817
6818    stream.push("Q");
6819    stream.push("EMC");
6820    var appearanceStreamContent = createFormXObject(formObject);
6821    appearanceStreamContent.scope = formObject.scope;
6822    appearanceStreamContent.stream = stream.join("\n");
6823    return appearanceStreamContent;
6824  };
6825
6826  var calculateX = function calculateX(formObject, text) {
6827    var maxFontSize = formObject.fontSize === 0 ? formObject.maxFontSize : formObject.fontSize;
6828    var returnValue = {
6829      text: "",
6830      fontSize: ""
6831    }; // Remove Brackets
6832
6833    text = text.substr(0, 1) == "(" ? text.substr(1) : text;
6834    text = text.substr(text.length - 1) == ")" ? text.substr(0, text.length - 1) : text; // split into array of words
6835
6836    var textSplit = text.split(" ");
6837
6838    if (formObject.multiline) {
6839      textSplit = textSplit.map(function (word) {
6840        return word.split("\n");
6841      });
6842    } else {
6843      textSplit = textSplit.map(function (word) {
6844        return [word];
6845      });
6846    }
6847
6848    var fontSize = maxFontSize; // The Starting fontSize (The Maximum)
6849
6850    var lineSpacing = 2;
6851    var borderPadding = 2;
6852    var height = AcroFormAppearance.internal.getHeight(formObject) || 0;
6853    height = height < 0 ? -height : height;
6854    var width = AcroFormAppearance.internal.getWidth(formObject) || 0;
6855    width = width < 0 ? -width : width;
6856
6857    var isSmallerThanWidth = function isSmallerThanWidth(i, lastLine, fontSize) {
6858      if (i + 1 < textSplit.length) {
6859        var tmp = lastLine + " " + textSplit[i + 1][0];
6860        var TextWidth = calculateFontSpace(tmp, formObject, fontSize).width;
6861        var FieldWidth = width - 2 * borderPadding;
6862        return TextWidth <= FieldWidth;
6863      } else {
6864        return false;
6865      }
6866    };
6867
6868    fontSize++;
6869
6870    FontSize: while (fontSize > 0) {
6871      text = "";
6872      fontSize--;
6873      var textHeight = calculateFontSpace("3", formObject, fontSize).height;
6874      var startY = formObject.multiline ? height - fontSize : (height - textHeight) / 2;
6875      startY += lineSpacing;
6876      var startX;
6877      var lastY = startY;
6878      var firstWordInLine = 0,
6879          lastWordInLine = 0;
6880      var lastLength;
6881      var currWord = 0;
6882
6883      if (fontSize <= 0) {
6884        // In case, the Text doesn't fit at all
6885        fontSize = 12;
6886        text = "(...) Tj\n";
6887        text += "% Width of Text: " + calculateFontSpace(text, formObject, fontSize).width + ", FieldWidth:" + width + "\n";
6888        break;
6889      }
6890
6891      var lastLine = "";
6892      var lineCount = 0;
6893
6894      Line: for (var i = 0; i < textSplit.length; i++) {
6895        if (textSplit.hasOwnProperty(i)) {
6896          var isWithNewLine = false;
6897
6898          if (textSplit[i].length !== 1 && currWord !== textSplit[i].length - 1) {
6899            if ((textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) {
6900              continue FontSize;
6901            }
6902
6903            lastLine += textSplit[i][currWord];
6904            isWithNewLine = true;
6905            lastWordInLine = i;
6906            i--;
6907          } else {
6908            lastLine += textSplit[i][currWord] + " ";
6909            lastLine = lastLine.substr(lastLine.length - 1) == " " ? lastLine.substr(0, lastLine.length - 1) : lastLine;
6910            var key = parseInt(i);
6911            var nextLineIsSmaller = isSmallerThanWidth(key, lastLine, fontSize);
6912            var isLastWord = i >= textSplit.length - 1;
6913
6914            if (nextLineIsSmaller && !isLastWord) {
6915              lastLine += " ";
6916              currWord = 0;
6917              continue; // Line
6918            } else if (!nextLineIsSmaller && !isLastWord) {
6919              if (!formObject.multiline) {
6920                continue FontSize;
6921              } else {
6922                if ((textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) {
6923                  // If the Text is higher than the
6924                  // FieldObject
6925                  continue FontSize;
6926                }
6927
6928                lastWordInLine = key; // go on
6929              }
6930            } else if (isLastWord) {
6931              lastWordInLine = key;
6932            } else {
6933              if (formObject.multiline && (textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) {
6934                // If the Text is higher than the FieldObject
6935                continue FontSize;
6936              }
6937            }
6938          } // Remove last blank
6939
6940
6941          var line = "";
6942
6943          for (var x = firstWordInLine; x <= lastWordInLine; x++) {
6944            var currLine = textSplit[x];
6945
6946            if (formObject.multiline) {
6947              if (x === lastWordInLine) {
6948                line += currLine[currWord] + " ";
6949                currWord = (currWord + 1) % currLine.length;
6950                continue;
6951              }
6952
6953              if (x === firstWordInLine) {
6954                line += currLine[currLine.length - 1] + " ";
6955                continue;
6956              }
6957            }
6958
6959            line += currLine[0] + " ";
6960          } // Remove last blank
6961
6962
6963          line = line.substr(line.length - 1) == " " ? line.substr(0, line.length - 1) : line; // lastLength -= blankSpace.width;
6964
6965          lastLength = calculateFontSpace(line, formObject, fontSize).width; // Calculate startX
6966
6967          switch (formObject.textAlign) {
6968            case "right":
6969              startX = width - lastLength - borderPadding;
6970              break;
6971
6972            case "center":
6973              startX = (width - lastLength) / 2;
6974              break;
6975
6976            case "left":
6977            default:
6978              startX = borderPadding;
6979              break;
6980          }
6981
6982          text += f2(startX) + " " + f2(lastY) + " Td\n";
6983          text += "(" + pdfEscape(line) + ") Tj\n"; // reset X in PDF
6984
6985          text += -f2(startX) + " 0 Td\n"; // After a Line, adjust y position
6986
6987          lastY = -(fontSize + lineSpacing); // Reset for next iteration step
6988
6989          lastLength = 0;
6990          firstWordInLine = isWithNewLine ? lastWordInLine : lastWordInLine + 1;
6991          lineCount++;
6992          lastLine = "";
6993          continue Line;
6994        }
6995      }
6996
6997      break;
6998    }
6999
7000    returnValue.text = text;
7001    returnValue.fontSize = fontSize;
7002    return returnValue;
7003  };
7004  /**
7005   * Small workaround for calculating the TextMetric approximately.
7006   *
7007   * @param text
7008   * @param fontsize
7009   * @returns {TextMetrics} (Has Height and Width)
7010   */
7011
7012
7013  var calculateFontSpace = function calculateFontSpace(text, formObject, fontSize) {
7014    var font = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle);
7015    var width = formObject.scope.getStringUnitWidth(text, {
7016      font: font,
7017      fontSize: parseFloat(fontSize),
7018      charSpace: 0
7019    }) * parseFloat(fontSize);
7020    var height = formObject.scope.getStringUnitWidth("3", {
7021      font: font,
7022      fontSize: parseFloat(fontSize),
7023      charSpace: 0
7024    }) * parseFloat(fontSize) * 1.5;
7025    return {
7026      height: height,
7027      width: width
7028    };
7029  };
7030
7031  var acroformPluginTemplate = {
7032    fields: [],
7033    xForms: [],
7034
7035    /**
7036     * acroFormDictionaryRoot contains information about the AcroForm
7037     * Dictionary 0: The Event-Token, the AcroFormDictionaryCallback has
7038     * 1: The Object ID of the Root
7039     */
7040    acroFormDictionaryRoot: null,
7041
7042    /**
7043     * After the PDF gets evaluated, the reference to the root has to be
7044     * reset, this indicates, whether the root has already been printed
7045     * out
7046     */
7047    printedOut: false,
7048    internal: null,
7049    isInitialized: false
7050  };
7051
7052  var annotReferenceCallback = function annotReferenceCallback(scope) {
7053    //set objId to undefined and force it to get a new objId on buildDocument
7054    scope.internal.acroformPlugin.acroFormDictionaryRoot.objId = undefined;
7055    var fields = scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields;
7056
7057    for (var i in fields) {
7058      if (fields.hasOwnProperty(i)) {
7059        var formObject = fields[i]; //set objId to undefined and force it to get a new objId on buildDocument
7060
7061        formObject.objId = undefined; // add Annot Reference!
7062
7063        if (formObject.hasAnnotation) {
7064          // If theres an Annotation Widget in the Form Object, put the
7065          // Reference in the /Annot array
7066          createAnnotationReference(formObject, scope);
7067        }
7068      }
7069    }
7070  };
7071
7072  var putForm = function putForm(formObject) {
7073    if (formObject.scope.internal.acroformPlugin.printedOut) {
7074      formObject.scope.internal.acroformPlugin.printedOut = false;
7075      formObject.scope.internal.acroformPlugin.acroFormDictionaryRoot = null;
7076    }
7077
7078    formObject.scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields.push(formObject);
7079  };
7080  /**
7081   * Create the Reference to the widgetAnnotation, so that it gets referenced
7082   * in the Annot[] int the+ (Requires the Annotation Plugin)
7083   */
7084
7085
7086  var createAnnotationReference = function createAnnotationReference(object, scope) {
7087    var options = {
7088      type: "reference",
7089      object: object
7090    };
7091
7092    var findEntry = function findEntry(entry) {
7093      return entry.type === options.type && entry.object === options.object;
7094    };
7095
7096    if (scope.internal.getPageInfo(object.page).pageContext.annotations.find(findEntry) === undefined) {
7097      scope.internal.getPageInfo(object.page).pageContext.annotations.push(options);
7098    }
7099  }; // Callbacks
7100
7101
7102  var putCatalogCallback = function putCatalogCallback(scope) {
7103    // Put reference to AcroForm to DocumentCatalog
7104    if (typeof scope.internal.acroformPlugin.acroFormDictionaryRoot !== "undefined") {
7105      // for safety, shouldn't normally be the case
7106      scope.internal.write("/AcroForm " + scope.internal.acroformPlugin.acroFormDictionaryRoot.objId + " " + 0 + " R");
7107    } else {
7108      throw new Error("putCatalogCallback: Root missing.");
7109    }
7110  };
7111  /**
7112   * Adds /Acroform X 0 R to Document Catalog, and creates the AcroForm
7113   * Dictionary
7114   */
7115
7116
7117  var AcroFormDictionaryCallback = function AcroFormDictionaryCallback(scope) {
7118    // Remove event
7119    scope.internal.events.unsubscribe(scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID);
7120    delete scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID;
7121    scope.internal.acroformPlugin.printedOut = true;
7122  };
7123  /**
7124   * Creates the single Fields and writes them into the Document
7125   *
7126   * If fieldArray is set, use the fields that are inside it instead of the
7127   * fields from the AcroRoot (for the FormXObjects...)
7128   */
7129
7130
7131  var createFieldCallback = function createFieldCallback(fieldArray, scope) {
7132    var standardFields = !fieldArray;
7133
7134    if (!fieldArray) {
7135      // in case there is no fieldArray specified, we want to print out
7136      // the Fields of the AcroForm
7137      // Print out Root
7138      scope.internal.newObjectDeferredBegin(scope.internal.acroformPlugin.acroFormDictionaryRoot.objId, true);
7139      scope.internal.acroformPlugin.acroFormDictionaryRoot.putStream();
7140    }
7141
7142    fieldArray = fieldArray || scope.internal.acroformPlugin.acroFormDictionaryRoot.Kids;
7143
7144    for (var i in fieldArray) {
7145      if (fieldArray.hasOwnProperty(i)) {
7146        var fieldObject = fieldArray[i];
7147        var keyValueList = [];
7148        var oldRect = fieldObject.Rect;
7149
7150        if (fieldObject.Rect) {
7151          fieldObject.Rect = calculateCoordinates(fieldObject.Rect, scope);
7152        } // Start Writing the Object
7153
7154
7155        scope.internal.newObjectDeferredBegin(fieldObject.objId, true);
7156        fieldObject.DA = AcroFormAppearance.createDefaultAppearanceStream(fieldObject);
7157
7158        if (_typeof(fieldObject) === "object" && typeof fieldObject.getKeyValueListForStream === "function") {
7159          keyValueList = fieldObject.getKeyValueListForStream();
7160        }
7161
7162        fieldObject.Rect = oldRect;
7163
7164        if (fieldObject.hasAppearanceStream && !fieldObject.appearanceStreamContent) {
7165          // Calculate Appearance
7166          var appearance = calculateAppearanceStream(fieldObject);
7167          keyValueList.push({
7168            key: "AP",
7169            value: "<</N " + appearance + ">>"
7170          });
7171          scope.internal.acroformPlugin.xForms.push(appearance);
7172        } // Assume AppearanceStreamContent is a Array with N,R,D (at least
7173        // one of them!)
7174
7175
7176        if (fieldObject.appearanceStreamContent) {
7177          var appearanceStreamString = ""; // Iterate over N,R and D
7178
7179          for (var k in fieldObject.appearanceStreamContent) {
7180            if (fieldObject.appearanceStreamContent.hasOwnProperty(k)) {
7181              var value = fieldObject.appearanceStreamContent[k];
7182              appearanceStreamString += "/" + k + " ";
7183              appearanceStreamString += "<<";
7184
7185              if (Object.keys(value).length >= 1 || Array.isArray(value)) {
7186                // appearanceStream is an Array or Object!
7187                for (var i in value) {
7188                  if (value.hasOwnProperty(i)) {
7189                    var obj = value[i];
7190
7191                    if (typeof obj === "function") {
7192                      // if Function is referenced, call it in order
7193                      // to get the FormXObject
7194                      obj = obj.call(scope, fieldObject);
7195                    }
7196
7197                    appearanceStreamString += "/" + i + " " + obj + " "; // In case the XForm is already used, e.g. OffState
7198                    // of CheckBoxes, don't add it
7199
7200                    if (!(scope.internal.acroformPlugin.xForms.indexOf(obj) >= 0)) scope.internal.acroformPlugin.xForms.push(obj);
7201                  }
7202                }
7203              } else {
7204                obj = value;
7205
7206                if (typeof obj === "function") {
7207                  // if Function is referenced, call it in order to
7208                  // get the FormXObject
7209                  obj = obj.call(scope, fieldObject);
7210                }
7211
7212                appearanceStreamString += "/" + i + " " + obj;
7213                if (!(scope.internal.acroformPlugin.xForms.indexOf(obj) >= 0)) scope.internal.acroformPlugin.xForms.push(obj);
7214              }
7215
7216              appearanceStreamString += ">>";
7217            }
7218          } // appearance stream is a normal Object..
7219
7220
7221          keyValueList.push({
7222            key: "AP",
7223            value: "<<\n" + appearanceStreamString + ">>"
7224          });
7225        }
7226
7227        scope.internal.putStream({
7228          additionalKeyValues: keyValueList,
7229          objectId: fieldObject.objId
7230        });
7231        scope.internal.out("endobj");
7232      }
7233    }
7234
7235    if (standardFields) {
7236      createXFormObjectCallback(scope.internal.acroformPlugin.xForms, scope);
7237    }
7238  };
7239
7240  var createXFormObjectCallback = function createXFormObjectCallback(fieldArray, scope) {
7241    for (var i in fieldArray) {
7242      if (fieldArray.hasOwnProperty(i)) {
7243        var key = i;
7244        var fieldObject = fieldArray[i]; // Start Writing the Object
7245
7246        scope.internal.newObjectDeferredBegin(fieldObject.objId, true);
7247
7248        if (_typeof(fieldObject) === "object" && typeof fieldObject.putStream === "function") {
7249          fieldObject.putStream();
7250        }
7251
7252        delete fieldArray[key];
7253      }
7254    }
7255  };
7256
7257  var initializeAcroForm = function initializeAcroForm(scope, formObject) {
7258    formObject.scope = scope;
7259
7260    if (scope.internal !== undefined && (scope.internal.acroformPlugin === undefined || scope.internal.acroformPlugin.isInitialized === false)) {
7261      AcroFormField.FieldNum = 0;
7262      scope.internal.acroformPlugin = JSON.parse(JSON.stringify(acroformPluginTemplate));
7263
7264      if (scope.internal.acroformPlugin.acroFormDictionaryRoot) {
7265        throw new Error("Exception while creating AcroformDictionary");
7266      }
7267
7268      scaleFactor = scope.internal.scaleFactor; // The Object Number of the AcroForm Dictionary
7269
7270      scope.internal.acroformPlugin.acroFormDictionaryRoot = new AcroFormDictionary();
7271      scope.internal.acroformPlugin.acroFormDictionaryRoot.scope = scope; // add Callback for creating the AcroForm Dictionary
7272
7273      scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID = scope.internal.events.subscribe("postPutResources", function () {
7274        AcroFormDictionaryCallback(scope);
7275      });
7276      scope.internal.events.subscribe("buildDocument", function () {
7277        annotReferenceCallback(scope);
7278      }); // buildDocument
7279      // Register event, that is triggered when the DocumentCatalog is
7280      // written, in order to add /AcroForm
7281
7282      scope.internal.events.subscribe("putCatalog", function () {
7283        putCatalogCallback(scope);
7284      }); // Register event, that creates all Fields
7285
7286      scope.internal.events.subscribe("postPutPages", function (fieldArray) {
7287        createFieldCallback(fieldArray, scope);
7288      });
7289      scope.internal.acroformPlugin.isInitialized = true;
7290    }
7291  }; //PDF 32000-1:2008, page 26, 7.3.6
7292
7293
7294  var arrayToPdfArray = jsPDFAPI.__acroform__.arrayToPdfArray = function (array, objId, scope) {
7295    var encryptor = function encryptor(data) {
7296      return data;
7297    };
7298
7299    if (Array.isArray(array)) {
7300      var content = "[";
7301
7302      for (var i = 0; i < array.length; i++) {
7303        if (i !== 0) {
7304          content += " ";
7305        }
7306
7307        switch (_typeof(array[i])) {
7308          case "boolean":
7309          case "number":
7310          case "object":
7311            content += array[i].toString();
7312            break;
7313
7314          case "string":
7315            if (array[i].substr(0, 1) !== "/") {
7316              if (typeof objId !== "undefined" && scope) encryptor = scope.internal.getEncryptor(objId);
7317              content += "(" + pdfEscape(encryptor(array[i].toString())) + ")";
7318            } else {
7319              content += array[i].toString();
7320            }
7321
7322            break;
7323        }
7324      }
7325
7326      content += "]";
7327      return content;
7328    }
7329
7330    throw new Error("Invalid argument passed to jsPDF.__acroform__.arrayToPdfArray");
7331  };
7332
7333  function getMatches(string, regex, index) {
7334    index || (index = 1); // default to the first capturing group
7335
7336    var matches = [];
7337    var match;
7338
7339    while (match = regex.exec(string)) {
7340      matches.push(match[index]);
7341    }
7342
7343    return matches;
7344  }
7345
7346  var pdfArrayToStringArray = function pdfArrayToStringArray(array) {
7347    var result = [];
7348
7349    if (typeof array === "string") {
7350      result = getMatches(array, /\((.*?)\)/g);
7351    }
7352
7353    return result;
7354  };
7355
7356  var toPdfString = function toPdfString(string, objId, scope) {
7357    var encryptor = function encryptor(data) {
7358      return data;
7359    };
7360
7361    if (typeof objId !== "undefined" && scope) encryptor = scope.internal.getEncryptor(objId);
7362    string = string || "";
7363    string.toString();
7364    string = "(" + pdfEscape(encryptor(string)) + ")";
7365    return string;
7366  }; // ##########################
7367  // Classes
7368  // ##########################
7369
7370  /**
7371   * @class AcroFormPDFObject
7372   * @classdesc A AcroFormPDFObject
7373   */
7374
7375
7376  var AcroFormPDFObject = function AcroFormPDFObject() {
7377    this._objId = undefined;
7378    this._scope = undefined;
7379    /**
7380     * @name AcroFormPDFObject#objId
7381     * @type {any}
7382     */
7383
7384    Object.defineProperty(this, "objId", {
7385      get: function get() {
7386        if (typeof this._objId === "undefined") {
7387          if (typeof this.scope === "undefined") {
7388            return undefined;
7389          }
7390
7391          this._objId = this.scope.internal.newObjectDeferred();
7392        }
7393
7394        return this._objId;
7395      },
7396      set: function set(value) {
7397        this._objId = value;
7398      }
7399    });
7400    Object.defineProperty(this, "scope", {
7401      value: this._scope,
7402      writable: true
7403    });
7404  };
7405  /**
7406   * @function AcroFormPDFObject.toString
7407   */
7408
7409
7410  AcroFormPDFObject.prototype.toString = function () {
7411    return this.objId + " 0 R";
7412  };
7413
7414  AcroFormPDFObject.prototype.putStream = function () {
7415    var keyValueList = this.getKeyValueListForStream();
7416    this.scope.internal.putStream({
7417      data: this.stream,
7418      additionalKeyValues: keyValueList,
7419      objectId: this.objId
7420    });
7421    this.scope.internal.out("endobj");
7422  };
7423  /**
7424   * Returns an key-value-List of all non-configurable Variables from the Object
7425   *
7426   * @name getKeyValueListForStream
7427   * @returns {string}
7428   */
7429
7430
7431  AcroFormPDFObject.prototype.getKeyValueListForStream = function () {
7432    var keyValueList = [];
7433    var keys = Object.getOwnPropertyNames(this).filter(function (key) {
7434      return key != "content" && key != "appearanceStreamContent" && key != "scope" && key != "objId" && key.substring(0, 1) != "_";
7435    });
7436
7437    for (var i in keys) {
7438      if (Object.getOwnPropertyDescriptor(this, keys[i]).configurable === false) {
7439        var key = keys[i];
7440        var value = this[key];
7441
7442        if (value) {
7443          if (Array.isArray(value)) {
7444            keyValueList.push({
7445              key: key,
7446              value: arrayToPdfArray(value, this.objId, this.scope)
7447            });
7448          } else if (value instanceof AcroFormPDFObject) {
7449            // In case it is a reference to another PDFObject,
7450            // take the reference number
7451            value.scope = this.scope;
7452            keyValueList.push({
7453              key: key,
7454              value: value.objId + " 0 R"
7455            });
7456          } else if (typeof value !== "function") {
7457            keyValueList.push({
7458              key: key,
7459              value: value
7460            });
7461          }
7462        }
7463      }
7464    }
7465
7466    return keyValueList;
7467  };
7468
7469  var AcroFormXObject = function AcroFormXObject() {
7470    AcroFormPDFObject.call(this);
7471    Object.defineProperty(this, "Type", {
7472      value: "/XObject",
7473      configurable: false,
7474      writable: true
7475    });
7476    Object.defineProperty(this, "Subtype", {
7477      value: "/Form",
7478      configurable: false,
7479      writable: true
7480    });
7481    Object.defineProperty(this, "FormType", {
7482      value: 1,
7483      configurable: false,
7484      writable: true
7485    });
7486    var _BBox = [];
7487    Object.defineProperty(this, "BBox", {
7488      configurable: false,
7489      get: function get() {
7490        return _BBox;
7491      },
7492      set: function set(value) {
7493        _BBox = value;
7494      }
7495    });
7496    Object.defineProperty(this, "Resources", {
7497      value: "2 0 R",
7498      configurable: false,
7499      writable: true
7500    });
7501
7502    var _stream;
7503
7504    Object.defineProperty(this, "stream", {
7505      enumerable: false,
7506      configurable: true,
7507      set: function set(value) {
7508        _stream = value.trim();
7509      },
7510      get: function get() {
7511        if (_stream) {
7512          return _stream;
7513        } else {
7514          return null;
7515        }
7516      }
7517    });
7518  };
7519
7520  inherit(AcroFormXObject, AcroFormPDFObject);
7521
7522  var AcroFormDictionary = function AcroFormDictionary() {
7523    AcroFormPDFObject.call(this);
7524    var _Kids = [];
7525    Object.defineProperty(this, "Kids", {
7526      enumerable: false,
7527      configurable: true,
7528      get: function get() {
7529        if (_Kids.length > 0) {
7530          return _Kids;
7531        } else {
7532          return undefined;
7533        }
7534      }
7535    });
7536    Object.defineProperty(this, "Fields", {
7537      enumerable: false,
7538      configurable: false,
7539      get: function get() {
7540        return _Kids;
7541      }
7542    }); // Default Appearance
7543
7544    var _DA;
7545
7546    Object.defineProperty(this, "DA", {
7547      enumerable: false,
7548      configurable: false,
7549      get: function get() {
7550        if (!_DA) {
7551          return undefined;
7552        }
7553
7554        var encryptor = function encryptor(data) {
7555          return data;
7556        };
7557
7558        if (this.scope) encryptor = this.scope.internal.getEncryptor(this.objId);
7559        return "(" + pdfEscape(encryptor(_DA)) + ")";
7560      },
7561      set: function set(value) {
7562        _DA = value;
7563      }
7564    });
7565  };
7566
7567  inherit(AcroFormDictionary, AcroFormPDFObject);
7568  /**
7569   * The Field Object contains the Variables, that every Field needs
7570   *
7571   * @class AcroFormField
7572   * @classdesc An AcroForm FieldObject
7573   */
7574
7575  var AcroFormField = function AcroFormField() {
7576    AcroFormPDFObject.call(this); //Annotation-Flag See Table 165
7577
7578    var _F = 4;
7579    Object.defineProperty(this, "F", {
7580      enumerable: false,
7581      configurable: false,
7582      get: function get() {
7583        return _F;
7584      },
7585      set: function set(value) {
7586        if (!isNaN(value)) {
7587          _F = value;
7588        } else {
7589          throw new Error('Invalid value "' + value + '" for attribute F supplied.');
7590        }
7591      }
7592    });
7593    /**
7594     * (PDF 1.2) If set, print the annotation when the page is printed. If clear, never print the annotation, regardless of wether is is displayed on the screen.
7595     * NOTE 2 This can be useful for annotations representing interactive pushbuttons, which would serve no meaningful purpose on the printed page.
7596     *
7597     * @name AcroFormField#showWhenPrinted
7598     * @default true
7599     * @type {boolean}
7600     */
7601
7602    Object.defineProperty(this, "showWhenPrinted", {
7603      enumerable: true,
7604      configurable: true,
7605      get: function get() {
7606        return Boolean(getBitForPdf(_F, 3));
7607      },
7608      set: function set(value) {
7609        if (Boolean(value) === true) {
7610          this.F = setBitForPdf(_F, 3);
7611        } else {
7612          this.F = clearBitForPdf(_F, 3);
7613        }
7614      }
7615    });
7616    var _Ff = 0;
7617    Object.defineProperty(this, "Ff", {
7618      enumerable: false,
7619      configurable: false,
7620      get: function get() {
7621        return _Ff;
7622      },
7623      set: function set(value) {
7624        if (!isNaN(value)) {
7625          _Ff = value;
7626        } else {
7627          throw new Error('Invalid value "' + value + '" for attribute Ff supplied.');
7628        }
7629      }
7630    });
7631    var _Rect = [];
7632    Object.defineProperty(this, "Rect", {
7633      enumerable: false,
7634      configurable: false,
7635      get: function get() {
7636        if (_Rect.length === 0) {
7637          return undefined;
7638        }
7639
7640        return _Rect;
7641      },
7642      set: function set(value) {
7643        if (typeof value !== "undefined") {
7644          _Rect = value;
7645        } else {
7646          _Rect = [];
7647        }
7648      }
7649    });
7650    /**
7651     * The x-position of the field.
7652     *
7653     * @name AcroFormField#x
7654     * @default null
7655     * @type {number}
7656     */
7657
7658    Object.defineProperty(this, "x", {
7659      enumerable: true,
7660      configurable: true,
7661      get: function get() {
7662        if (!_Rect || isNaN(_Rect[0])) {
7663          return 0;
7664        }
7665
7666        return _Rect[0];
7667      },
7668      set: function set(value) {
7669        _Rect[0] = value;
7670      }
7671    });
7672    /**
7673     * The y-position of the field.
7674     *
7675     * @name AcroFormField#y
7676     * @default null
7677     * @type {number}
7678     */
7679
7680    Object.defineProperty(this, "y", {
7681      enumerable: true,
7682      configurable: true,
7683      get: function get() {
7684        if (!_Rect || isNaN(_Rect[1])) {
7685          return 0;
7686        }
7687
7688        return _Rect[1];
7689      },
7690      set: function set(value) {
7691        _Rect[1] = value;
7692      }
7693    });
7694    /**
7695     * The width of the field.
7696     *
7697     * @name AcroFormField#width
7698     * @default null
7699     * @type {number}
7700     */
7701
7702    Object.defineProperty(this, "width", {
7703      enumerable: true,
7704      configurable: true,
7705      get: function get() {
7706        if (!_Rect || isNaN(_Rect[2])) {
7707          return 0;
7708        }
7709
7710        return _Rect[2];
7711      },
7712      set: function set(value) {
7713        _Rect[2] = value;
7714      }
7715    });
7716    /**
7717     * The height of the field.
7718     *
7719     * @name AcroFormField#height
7720     * @default null
7721     * @type {number}
7722     */
7723
7724    Object.defineProperty(this, "height", {
7725      enumerable: true,
7726      configurable: true,
7727      get: function get() {
7728        if (!_Rect || isNaN(_Rect[3])) {
7729          return 0;
7730        }
7731
7732        return _Rect[3];
7733      },
7734      set: function set(value) {
7735        _Rect[3] = value;
7736      }
7737    });
7738    var _FT = "";
7739    Object.defineProperty(this, "FT", {
7740      enumerable: true,
7741      configurable: false,
7742      get: function get() {
7743        return _FT;
7744      },
7745      set: function set(value) {
7746        switch (value) {
7747          case "/Btn":
7748          case "/Tx":
7749          case "/Ch":
7750          case "/Sig":
7751            _FT = value;
7752            break;
7753
7754          default:
7755            throw new Error('Invalid value "' + value + '" for attribute FT supplied.');
7756        }
7757      }
7758    });
7759    var _T = null;
7760    Object.defineProperty(this, "T", {
7761      enumerable: true,
7762      configurable: false,
7763      get: function get() {
7764        if (!_T || _T.length < 1) {
7765          // In case of a Child from a Radio´Group, you don't need a FieldName
7766          if (this instanceof AcroFormChildClass) {
7767            return undefined;
7768          }
7769
7770          _T = "FieldObject" + AcroFormField.FieldNum++;
7771        }
7772
7773        var encryptor = function encryptor(data) {
7774          return data;
7775        };
7776
7777        if (this.scope) encryptor = this.scope.internal.getEncryptor(this.objId);
7778        return "(" + pdfEscape(encryptor(_T)) + ")";
7779      },
7780      set: function set(value) {
7781        _T = value.toString();
7782      }
7783    });
7784    /**
7785     * (Optional) The partial field name (see 12.7.3.2, “Field Names”).
7786     *
7787     * @name AcroFormField#fieldName
7788     * @default null
7789     * @type {string}
7790     */
7791
7792    Object.defineProperty(this, "fieldName", {
7793      configurable: true,
7794      enumerable: true,
7795      get: function get() {
7796        return _T;
7797      },
7798      set: function set(value) {
7799        _T = value;
7800      }
7801    });
7802    var _fontName = "helvetica";
7803    /**
7804     * The fontName of the font to be used.
7805     *
7806     * @name AcroFormField#fontName
7807     * @default 'helvetica'
7808     * @type {string}
7809     */
7810
7811    Object.defineProperty(this, "fontName", {
7812      enumerable: true,
7813      configurable: true,
7814      get: function get() {
7815        return _fontName;
7816      },
7817      set: function set(value) {
7818        _fontName = value;
7819      }
7820    });
7821    var _fontStyle = "normal";
7822    /**
7823     * The fontStyle of the font to be used.
7824     *
7825     * @name AcroFormField#fontStyle
7826     * @default 'normal'
7827     * @type {string}
7828     */
7829
7830    Object.defineProperty(this, "fontStyle", {
7831      enumerable: true,
7832      configurable: true,
7833      get: function get() {
7834        return _fontStyle;
7835      },
7836      set: function set(value) {
7837        _fontStyle = value;
7838      }
7839    });
7840    var _fontSize = 0;
7841    /**
7842     * The fontSize of the font to be used.
7843     *
7844     * @name AcroFormField#fontSize
7845     * @default 0 (for auto)
7846     * @type {number}
7847     */
7848
7849    Object.defineProperty(this, "fontSize", {
7850      enumerable: true,
7851      configurable: true,
7852      get: function get() {
7853        return _fontSize;
7854      },
7855      set: function set(value) {
7856        _fontSize = value;
7857      }
7858    });
7859    var _maxFontSize = undefined;
7860    /**
7861     * The maximum fontSize of the font to be used.
7862     *
7863     * @name AcroFormField#maxFontSize
7864     * @default 0 (for auto)
7865     * @type {number}
7866     */
7867
7868    Object.defineProperty(this, "maxFontSize", {
7869      enumerable: true,
7870      configurable: true,
7871      get: function get() {
7872        if (_maxFontSize === undefined) {
7873          // use the old default value here - the value is some kind of random as it depends on the scaleFactor (user unit)
7874          // ("50" is transformed to the "user space" but then used in "pdf space")
7875          return 50 / scaleFactor;
7876        } else {
7877          return _maxFontSize;
7878        }
7879      },
7880      set: function set(value) {
7881        _maxFontSize = value;
7882      }
7883    });
7884    var _color = "black";
7885    /**
7886     * The color of the text
7887     *
7888     * @name AcroFormField#color
7889     * @default 'black'
7890     * @type {string|rgba}
7891     */
7892
7893    Object.defineProperty(this, "color", {
7894      enumerable: true,
7895      configurable: true,
7896      get: function get() {
7897        return _color;
7898      },
7899      set: function set(value) {
7900        _color = value;
7901      }
7902    });
7903    var _DA = "/F1 0 Tf 0 g"; // Defines the default appearance (Needed for variable Text)
7904
7905    Object.defineProperty(this, "DA", {
7906      enumerable: true,
7907      configurable: false,
7908      get: function get() {
7909        if (!_DA || this instanceof AcroFormChildClass || this instanceof AcroFormTextField) {
7910          return undefined;
7911        }
7912
7913        return toPdfString(_DA, this.objId, this.scope);
7914      },
7915      set: function set(value) {
7916        value = value.toString();
7917        _DA = value;
7918      }
7919    });
7920    var _DV = null;
7921    Object.defineProperty(this, "DV", {
7922      enumerable: false,
7923      configurable: false,
7924      get: function get() {
7925        if (!_DV) {
7926          return undefined;
7927        }
7928
7929        if (this instanceof AcroFormButton === false) {
7930          return toPdfString(_DV, this.objId, this.scope);
7931        }
7932
7933        return _DV;
7934      },
7935      set: function set(value) {
7936        value = value.toString();
7937
7938        if (this instanceof AcroFormButton === false) {
7939          if (value.substr(0, 1) === "(") {
7940            _DV = pdfUnescape(value.substr(1, value.length - 2));
7941          } else {
7942            _DV = pdfUnescape(value);
7943          }
7944        } else {
7945          _DV = value;
7946        }
7947      }
7948    });
7949    /**
7950     * (Optional; inheritable) The default value to which the field reverts when a reset-form action is executed (see 12.7.5.3, “Reset-Form Action”). The format of this value is the same as that of value.
7951     *
7952     * @name AcroFormField#defaultValue
7953     * @default null
7954     * @type {any}
7955     */
7956
7957    Object.defineProperty(this, "defaultValue", {
7958      enumerable: true,
7959      configurable: true,
7960      get: function get() {
7961        if (this instanceof AcroFormButton === true) {
7962          return pdfUnescape(_DV.substr(1, _DV.length - 1));
7963        } else {
7964          return _DV;
7965        }
7966      },
7967      set: function set(value) {
7968        value = value.toString();
7969
7970        if (this instanceof AcroFormButton === true) {
7971          _DV = "/" + value;
7972        } else {
7973          _DV = value;
7974        }
7975      }
7976    });
7977    var _V = null;
7978    Object.defineProperty(this, "_V", {
7979      enumerable: false,
7980      configurable: false,
7981      get: function get() {
7982        if (!_V) {
7983          return undefined;
7984        }
7985
7986        return _V;
7987      },
7988      set: function set(value) {
7989        this.V = value;
7990      }
7991    });
7992    Object.defineProperty(this, "V", {
7993      enumerable: false,
7994      configurable: false,
7995      get: function get() {
7996        if (!_V) {
7997          return undefined;
7998        }
7999
8000        if (this instanceof AcroFormButton === false) {
8001          return toPdfString(_V, this.objId, this.scope);
8002        }
8003
8004        return _V;
8005      },
8006      set: function set(value) {
8007        value = value.toString();
8008
8009        if (this instanceof AcroFormButton === false) {
8010          if (value.substr(0, 1) === "(") {
8011            _V = pdfUnescape(value.substr(1, value.length - 2));
8012          } else {
8013            _V = pdfUnescape(value);
8014          }
8015        } else {
8016          _V = value;
8017        }
8018      }
8019    });
8020    /**
8021     * (Optional; inheritable) The field’s value, whose format varies depending on the field type. See the descriptions of individual field types for further information.
8022     *
8023     * @name AcroFormField#value
8024     * @default null
8025     * @type {any}
8026     */
8027
8028    Object.defineProperty(this, "value", {
8029      enumerable: true,
8030      configurable: true,
8031      get: function get() {
8032        if (this instanceof AcroFormButton === true) {
8033          return pdfUnescape(_V.substr(1, _V.length - 1));
8034        } else {
8035          return _V;
8036        }
8037      },
8038      set: function set(value) {
8039        value = value.toString();
8040
8041        if (this instanceof AcroFormButton === true) {
8042          _V = "/" + value;
8043        } else {
8044          _V = value;
8045        }
8046      }
8047    });
8048    /**
8049     * Check if field has annotations
8050     *
8051     * @name AcroFormField#hasAnnotation
8052     * @readonly
8053     * @type {boolean}
8054     */
8055
8056    Object.defineProperty(this, "hasAnnotation", {
8057      enumerable: true,
8058      configurable: true,
8059      get: function get() {
8060        return this.Rect;
8061      }
8062    });
8063    Object.defineProperty(this, "Type", {
8064      enumerable: true,
8065      configurable: false,
8066      get: function get() {
8067        return this.hasAnnotation ? "/Annot" : null;
8068      }
8069    });
8070    Object.defineProperty(this, "Subtype", {
8071      enumerable: true,
8072      configurable: false,
8073      get: function get() {
8074        return this.hasAnnotation ? "/Widget" : null;
8075      }
8076    });
8077    var _hasAppearanceStream = false;
8078    /**
8079     * true if field has an appearanceStream
8080     *
8081     * @name AcroFormField#hasAppearanceStream
8082     * @readonly
8083     * @type {boolean}
8084     */
8085
8086    Object.defineProperty(this, "hasAppearanceStream", {
8087      enumerable: true,
8088      configurable: true,
8089      get: function get() {
8090        return _hasAppearanceStream;
8091      },
8092      set: function set(value) {
8093        value = Boolean(value);
8094        _hasAppearanceStream = value;
8095      }
8096    });
8097    /**
8098     * The page on which the AcroFormField is placed
8099     *
8100     * @name AcroFormField#page
8101     * @type {number}
8102     */
8103
8104    var _page;
8105
8106    Object.defineProperty(this, "page", {
8107      enumerable: true,
8108      configurable: true,
8109      get: function get() {
8110        if (!_page) {
8111          return undefined;
8112        }
8113
8114        return _page;
8115      },
8116      set: function set(value) {
8117        _page = value;
8118      }
8119    });
8120    /**
8121     * If set, the user may not change the value of the field. Any associated widget annotations will not interact with the user; that is, they will not respond to mouse clicks or change their appearance in response to mouse motions. This flag is useful for fields whose values are computed or imported from a database.
8122     *
8123     * @name AcroFormField#readOnly
8124     * @default false
8125     * @type {boolean}
8126     */
8127
8128    Object.defineProperty(this, "readOnly", {
8129      enumerable: true,
8130      configurable: true,
8131      get: function get() {
8132        return Boolean(getBitForPdf(this.Ff, 1));
8133      },
8134      set: function set(value) {
8135        if (Boolean(value) === true) {
8136          this.Ff = setBitForPdf(this.Ff, 1);
8137        } else {
8138          this.Ff = clearBitForPdf(this.Ff, 1);
8139        }
8140      }
8141    });
8142    /**
8143     * If set, the field shall have a value at the time it is exported by a submitform action (see 12.7.5.2, “Submit-Form Action”).
8144     *
8145     * @name AcroFormField#required
8146     * @default false
8147     * @type {boolean}
8148     */
8149
8150    Object.defineProperty(this, "required", {
8151      enumerable: true,
8152      configurable: true,
8153      get: function get() {
8154        return Boolean(getBitForPdf(this.Ff, 2));
8155      },
8156      set: function set(value) {
8157        if (Boolean(value) === true) {
8158          this.Ff = setBitForPdf(this.Ff, 2);
8159        } else {
8160          this.Ff = clearBitForPdf(this.Ff, 2);
8161        }
8162      }
8163    });
8164    /**
8165     * If set, the field shall not be exported by a submit-form action (see 12.7.5.2, “Submit-Form Action”)
8166     *
8167     * @name AcroFormField#noExport
8168     * @default false
8169     * @type {boolean}
8170     */
8171
8172    Object.defineProperty(this, "noExport", {
8173      enumerable: true,
8174      configurable: true,
8175      get: function get() {
8176        return Boolean(getBitForPdf(this.Ff, 3));
8177      },
8178      set: function set(value) {
8179        if (Boolean(value) === true) {
8180          this.Ff = setBitForPdf(this.Ff, 3);
8181        } else {
8182          this.Ff = clearBitForPdf(this.Ff, 3);
8183        }
8184      }
8185    });
8186    var _Q = null;
8187    Object.defineProperty(this, "Q", {
8188      enumerable: true,
8189      configurable: false,
8190      get: function get() {
8191        if (_Q === null) {
8192          return undefined;
8193        }
8194
8195        return _Q;
8196      },
8197      set: function set(value) {
8198        if ([0, 1, 2].indexOf(value) !== -1) {
8199          _Q = value;
8200        } else {
8201          throw new Error('Invalid value "' + value + '" for attribute Q supplied.');
8202        }
8203      }
8204    });
8205    /**
8206     * (Optional; inheritable) A code specifying the form of quadding (justification) that shall be used in displaying the text:
8207     * 'left', 'center', 'right'
8208     *
8209     * @name AcroFormField#textAlign
8210     * @default 'left'
8211     * @type {string}
8212     */
8213
8214    Object.defineProperty(this, "textAlign", {
8215      get: function get() {
8216        var result;
8217
8218        switch (_Q) {
8219          case 0:
8220          default:
8221            result = "left";
8222            break;
8223
8224          case 1:
8225            result = "center";
8226            break;
8227
8228          case 2:
8229            result = "right";
8230            break;
8231        }
8232
8233        return result;
8234      },
8235      configurable: true,
8236      enumerable: true,
8237      set: function set(value) {
8238        switch (value) {
8239          case "right":
8240          case 2:
8241            _Q = 2;
8242            break;
8243
8244          case "center":
8245          case 1:
8246            _Q = 1;
8247            break;
8248
8249          case "left":
8250          case 0:
8251          default:
8252            _Q = 0;
8253        }
8254      }
8255    });
8256  };
8257
8258  inherit(AcroFormField, AcroFormPDFObject);
8259  /**
8260   * @class AcroFormChoiceField
8261   * @extends AcroFormField
8262   */
8263
8264  var AcroFormChoiceField = function AcroFormChoiceField() {
8265    AcroFormField.call(this); // Field Type = Choice Field
8266
8267    this.FT = "/Ch"; // options
8268
8269    this.V = "()";
8270    this.fontName = "zapfdingbats"; // Top Index
8271
8272    var _TI = 0;
8273    Object.defineProperty(this, "TI", {
8274      enumerable: true,
8275      configurable: false,
8276      get: function get() {
8277        return _TI;
8278      },
8279      set: function set(value) {
8280        _TI = value;
8281      }
8282    });
8283    /**
8284     * (Optional) For scrollable list boxes, the top index (the index in the Opt array of the first option visible in the list). Default value: 0.
8285     *
8286     * @name AcroFormChoiceField#topIndex
8287     * @default 0
8288     * @type {number}
8289     */
8290
8291    Object.defineProperty(this, "topIndex", {
8292      enumerable: true,
8293      configurable: true,
8294      get: function get() {
8295        return _TI;
8296      },
8297      set: function set(value) {
8298        _TI = value;
8299      }
8300    });
8301    var _Opt = [];
8302    Object.defineProperty(this, "Opt", {
8303      enumerable: true,
8304      configurable: false,
8305      get: function get() {
8306        return arrayToPdfArray(_Opt, this.objId, this.scope);
8307      },
8308      set: function set(value) {
8309        _Opt = pdfArrayToStringArray(value);
8310      }
8311    });
8312    /**
8313     * @memberof AcroFormChoiceField
8314     * @name getOptions
8315     * @function
8316     * @instance
8317     * @returns {array} array of Options
8318     */
8319
8320    this.getOptions = function () {
8321      return _Opt;
8322    };
8323    /**
8324     * @memberof AcroFormChoiceField
8325     * @name setOptions
8326     * @function
8327     * @instance
8328     * @param {array} value
8329     */
8330
8331
8332    this.setOptions = function (value) {
8333      _Opt = value;
8334
8335      if (this.sort) {
8336        _Opt.sort();
8337      }
8338    };
8339    /**
8340     * @memberof AcroFormChoiceField
8341     * @name addOption
8342     * @function
8343     * @instance
8344     * @param {string} value
8345     */
8346
8347
8348    this.addOption = function (value) {
8349      value = value || "";
8350      value = value.toString();
8351
8352      _Opt.push(value);
8353
8354      if (this.sort) {
8355        _Opt.sort();
8356      }
8357    };
8358    /**
8359     * @memberof AcroFormChoiceField
8360     * @name removeOption
8361     * @function
8362     * @instance
8363     * @param {string} value
8364     * @param {boolean} allEntries (default: false)
8365     */
8366
8367
8368    this.removeOption = function (value, allEntries) {
8369      allEntries = allEntries || false;
8370      value = value || "";
8371      value = value.toString();
8372
8373      while (_Opt.indexOf(value) !== -1) {
8374        _Opt.splice(_Opt.indexOf(value), 1);
8375
8376        if (allEntries === false) {
8377          break;
8378        }
8379      }
8380    };
8381    /**
8382     * If set, the field is a combo box; if clear, the field is a list box.
8383     *
8384     * @name AcroFormChoiceField#combo
8385     * @default false
8386     * @type {boolean}
8387     */
8388
8389
8390    Object.defineProperty(this, "combo", {
8391      enumerable: true,
8392      configurable: true,
8393      get: function get() {
8394        return Boolean(getBitForPdf(this.Ff, 18));
8395      },
8396      set: function set(value) {
8397        if (Boolean(value) === true) {
8398          this.Ff = setBitForPdf(this.Ff, 18);
8399        } else {
8400          this.Ff = clearBitForPdf(this.Ff, 18);
8401        }
8402      }
8403    });
8404    /**
8405     * If set, the combo box shall include an editable text box as well as a drop-down list; if clear, it shall include only a drop-down list. This flag shall be used only if the Combo flag is set.
8406     *
8407     * @name AcroFormChoiceField#edit
8408     * @default false
8409     * @type {boolean}
8410     */
8411
8412    Object.defineProperty(this, "edit", {
8413      enumerable: true,
8414      configurable: true,
8415      get: function get() {
8416        return Boolean(getBitForPdf(this.Ff, 19));
8417      },
8418      set: function set(value) {
8419        //PDF 32000-1:2008, page 444
8420        if (this.combo === true) {
8421          if (Boolean(value) === true) {
8422            this.Ff = setBitForPdf(this.Ff, 19);
8423          } else {
8424            this.Ff = clearBitForPdf(this.Ff, 19);
8425          }
8426        }
8427      }
8428    });
8429    /**
8430     * If set, the field’s option items shall be sorted alphabetically. This flag is intended for use by writers, not by readers. Conforming readers shall display the options in the order in which they occur in the Opt array (see Table 231).
8431     *
8432     * @name AcroFormChoiceField#sort
8433     * @default false
8434     * @type {boolean}
8435     */
8436
8437    Object.defineProperty(this, "sort", {
8438      enumerable: true,
8439      configurable: true,
8440      get: function get() {
8441        return Boolean(getBitForPdf(this.Ff, 20));
8442      },
8443      set: function set(value) {
8444        if (Boolean(value) === true) {
8445          this.Ff = setBitForPdf(this.Ff, 20);
8446
8447          _Opt.sort();
8448        } else {
8449          this.Ff = clearBitForPdf(this.Ff, 20);
8450        }
8451      }
8452    });
8453    /**
8454     * (PDF 1.4) If set, more than one of the field’s option items may be selected simultaneously; if clear, at most one item shall be selected
8455     *
8456     * @name AcroFormChoiceField#multiSelect
8457     * @default false
8458     * @type {boolean}
8459     */
8460
8461    Object.defineProperty(this, "multiSelect", {
8462      enumerable: true,
8463      configurable: true,
8464      get: function get() {
8465        return Boolean(getBitForPdf(this.Ff, 22));
8466      },
8467      set: function set(value) {
8468        if (Boolean(value) === true) {
8469          this.Ff = setBitForPdf(this.Ff, 22);
8470        } else {
8471          this.Ff = clearBitForPdf(this.Ff, 22);
8472        }
8473      }
8474    });
8475    /**
8476     * (PDF 1.4) If set, text entered in the field shall not be spellchecked. This flag shall not be used unless the Combo and Edit flags are both set.
8477     *
8478     * @name AcroFormChoiceField#doNotSpellCheck
8479     * @default false
8480     * @type {boolean}
8481     */
8482
8483    Object.defineProperty(this, "doNotSpellCheck", {
8484      enumerable: true,
8485      configurable: true,
8486      get: function get() {
8487        return Boolean(getBitForPdf(this.Ff, 23));
8488      },
8489      set: function set(value) {
8490        if (Boolean(value) === true) {
8491          this.Ff = setBitForPdf(this.Ff, 23);
8492        } else {
8493          this.Ff = clearBitForPdf(this.Ff, 23);
8494        }
8495      }
8496    });
8497    /**
8498     * (PDF 1.5) If set, the new value shall be committed as soon as a selection is made (commonly with the pointing device). In this case, supplying a value for a field involves three actions: selecting the field for fill-in, selecting a choice for the fill-in value, and leaving that field, which finalizes or “commits” the data choice and triggers any actions associated with the entry or changing of this data. If this flag is on, then processing does not wait for leaving the field action to occur, but immediately proceeds to the third step.
8499     * This option enables applications to perform an action once a selection is made, without requiring the user to exit the field. If clear, the new value is not committed until the user exits the field.
8500     *
8501     * @name AcroFormChoiceField#commitOnSelChange
8502     * @default false
8503     * @type {boolean}
8504     */
8505
8506    Object.defineProperty(this, "commitOnSelChange", {
8507      enumerable: true,
8508      configurable: true,
8509      get: function get() {
8510        return Boolean(getBitForPdf(this.Ff, 27));
8511      },
8512      set: function set(value) {
8513        if (Boolean(value) === true) {
8514          this.Ff = setBitForPdf(this.Ff, 27);
8515        } else {
8516          this.Ff = clearBitForPdf(this.Ff, 27);
8517        }
8518      }
8519    });
8520    this.hasAppearanceStream = false;
8521  };
8522
8523  inherit(AcroFormChoiceField, AcroFormField);
8524  /**
8525   * @class AcroFormListBox
8526   * @extends AcroFormChoiceField
8527   * @extends AcroFormField
8528   */
8529
8530  var AcroFormListBox = function AcroFormListBox() {
8531    AcroFormChoiceField.call(this);
8532    this.fontName = "helvetica"; //PDF 32000-1:2008, page 444
8533
8534    this.combo = false;
8535  };
8536
8537  inherit(AcroFormListBox, AcroFormChoiceField);
8538  /**
8539   * @class AcroFormComboBox
8540   * @extends AcroFormListBox
8541   * @extends AcroFormChoiceField
8542   * @extends AcroFormField
8543   */
8544
8545  var AcroFormComboBox = function AcroFormComboBox() {
8546    AcroFormListBox.call(this);
8547    this.combo = true;
8548  };
8549
8550  inherit(AcroFormComboBox, AcroFormListBox);
8551  /**
8552   * @class AcroFormEditBox
8553   * @extends AcroFormComboBox
8554   * @extends AcroFormListBox
8555   * @extends AcroFormChoiceField
8556   * @extends AcroFormField
8557   */
8558
8559  var AcroFormEditBox = function AcroFormEditBox() {
8560    AcroFormComboBox.call(this);
8561    this.edit = true;
8562  };
8563
8564  inherit(AcroFormEditBox, AcroFormComboBox);
8565  /**
8566   * @class AcroFormButton
8567   * @extends AcroFormField
8568   */
8569
8570  var AcroFormButton = function AcroFormButton() {
8571    AcroFormField.call(this);
8572    this.FT = "/Btn";
8573    /**
8574     * (Radio buttons only) If set, exactly one radio button shall be selected at all times; selecting the currently selected button has no effect. If clear, clicking the selected button deselects it, leaving no button selected.
8575     *
8576     * @name AcroFormButton#noToggleToOff
8577     * @type {boolean}
8578     */
8579
8580    Object.defineProperty(this, "noToggleToOff", {
8581      enumerable: true,
8582      configurable: true,
8583      get: function get() {
8584        return Boolean(getBitForPdf(this.Ff, 15));
8585      },
8586      set: function set(value) {
8587        if (Boolean(value) === true) {
8588          this.Ff = setBitForPdf(this.Ff, 15);
8589        } else {
8590          this.Ff = clearBitForPdf(this.Ff, 15);
8591        }
8592      }
8593    });
8594    /**
8595     * If set, the field is a set of radio buttons; if clear, the field is a checkbox. This flag may be set only if the Pushbutton flag is clear.
8596     *
8597     * @name AcroFormButton#radio
8598     * @type {boolean}
8599     */
8600
8601    Object.defineProperty(this, "radio", {
8602      enumerable: true,
8603      configurable: true,
8604      get: function get() {
8605        return Boolean(getBitForPdf(this.Ff, 16));
8606      },
8607      set: function set(value) {
8608        if (Boolean(value) === true) {
8609          this.Ff = setBitForPdf(this.Ff, 16);
8610        } else {
8611          this.Ff = clearBitForPdf(this.Ff, 16);
8612        }
8613      }
8614    });
8615    /**
8616     * If set, the field is a pushbutton that does not retain a permanent value.
8617     *
8618     * @name AcroFormButton#pushButton
8619     * @type {boolean}
8620     */
8621
8622    Object.defineProperty(this, "pushButton", {
8623      enumerable: true,
8624      configurable: true,
8625      get: function get() {
8626        return Boolean(getBitForPdf(this.Ff, 17));
8627      },
8628      set: function set(value) {
8629        if (Boolean(value) === true) {
8630          this.Ff = setBitForPdf(this.Ff, 17);
8631        } else {
8632          this.Ff = clearBitForPdf(this.Ff, 17);
8633        }
8634      }
8635    });
8636    /**
8637     * (PDF 1.5) If set, a group of radio buttons within a radio button field that use the same value for the on state will turn on and off in unison; that is if one is checked, they are all checked. If clear, the buttons are mutually exclusive (the same behavior as HTML radio buttons).
8638     *
8639     * @name AcroFormButton#radioIsUnison
8640     * @type {boolean}
8641     */
8642
8643    Object.defineProperty(this, "radioIsUnison", {
8644      enumerable: true,
8645      configurable: true,
8646      get: function get() {
8647        return Boolean(getBitForPdf(this.Ff, 26));
8648      },
8649      set: function set(value) {
8650        if (Boolean(value) === true) {
8651          this.Ff = setBitForPdf(this.Ff, 26);
8652        } else {
8653          this.Ff = clearBitForPdf(this.Ff, 26);
8654        }
8655      }
8656    });
8657    var _MK = {};
8658    Object.defineProperty(this, "MK", {
8659      enumerable: false,
8660      configurable: false,
8661      get: function get() {
8662        var encryptor = function encryptor(data) {
8663          return data;
8664        };
8665
8666        if (this.scope) encryptor = this.scope.internal.getEncryptor(this.objId);
8667
8668        if (Object.keys(_MK).length !== 0) {
8669          var result = [];
8670          result.push("<<");
8671          var key;
8672
8673          for (key in _MK) {
8674            result.push("/" + key + " (" + pdfEscape(encryptor(_MK[key])) + ")");
8675          }
8676
8677          result.push(">>");
8678          return result.join("\n");
8679        }
8680
8681        return undefined;
8682      },
8683      set: function set(value) {
8684        if (_typeof(value) === "object") {
8685          _MK = value;
8686        }
8687      }
8688    });
8689    /**
8690     * From the PDF reference:
8691     * (Optional, button fields only) The widget annotation's normal caption which shall be displayed when it is not interacting with the user.
8692     * Unlike the remaining entries listed in this Table which apply only to widget annotations associated with pushbutton fields (see Pushbuttons in 12.7.4.2, "Button Fields"), the CA entry may be used with any type of button field, including check boxes (see Check Boxes in 12.7.4.2, "Button Fields") and radio buttons (Radio Buttons in 12.7.4.2, "Button Fields").
8693     *
8694     * - '8' = Cross,
8695     * - 'l' =  Circle,
8696     * - '' = nothing
8697     * @name AcroFormButton#caption
8698     * @type {string}
8699     */
8700
8701    Object.defineProperty(this, "caption", {
8702      enumerable: true,
8703      configurable: true,
8704      get: function get() {
8705        return _MK.CA || "";
8706      },
8707      set: function set(value) {
8708        if (typeof value === "string") {
8709          _MK.CA = value;
8710        }
8711      }
8712    });
8713
8714    var _AS;
8715
8716    Object.defineProperty(this, "AS", {
8717      enumerable: false,
8718      configurable: false,
8719      get: function get() {
8720        return _AS;
8721      },
8722      set: function set(value) {
8723        _AS = value;
8724      }
8725    });
8726    /**
8727     * (Required if the appearance dictionary AP contains one or more subdictionaries; PDF 1.2) The annotation's appearance state, which selects the applicable appearance stream from an appearance subdictionary (see Section 12.5.5, "Appearance Streams")
8728     *
8729     * @name AcroFormButton#appearanceState
8730     * @type {any}
8731     */
8732
8733    Object.defineProperty(this, "appearanceState", {
8734      enumerable: true,
8735      configurable: true,
8736      get: function get() {
8737        return _AS.substr(1, _AS.length - 1);
8738      },
8739      set: function set(value) {
8740        _AS = "/" + value;
8741      }
8742    });
8743  };
8744
8745  inherit(AcroFormButton, AcroFormField);
8746  /**
8747   * @class AcroFormPushButton
8748   * @extends AcroFormButton
8749   * @extends AcroFormField
8750   */
8751
8752  var AcroFormPushButton = function AcroFormPushButton() {
8753    AcroFormButton.call(this);
8754    this.pushButton = true;
8755  };
8756
8757  inherit(AcroFormPushButton, AcroFormButton);
8758  /**
8759   * @class AcroFormRadioButton
8760   * @extends AcroFormButton
8761   * @extends AcroFormField
8762   */
8763
8764  var AcroFormRadioButton = function AcroFormRadioButton() {
8765    AcroFormButton.call(this);
8766    this.radio = true;
8767    this.pushButton = false;
8768    var _Kids = [];
8769    Object.defineProperty(this, "Kids", {
8770      enumerable: true,
8771      configurable: false,
8772      get: function get() {
8773        return _Kids;
8774      },
8775      set: function set(value) {
8776        if (typeof value !== "undefined") {
8777          _Kids = value;
8778        } else {
8779          _Kids = [];
8780        }
8781      }
8782    });
8783  };
8784
8785  inherit(AcroFormRadioButton, AcroFormButton);
8786  /**
8787   * The Child class of a RadioButton (the radioGroup) -> The single Buttons
8788   *
8789   * @class AcroFormChildClass
8790   * @extends AcroFormField
8791   * @ignore
8792   */
8793
8794  var AcroFormChildClass = function AcroFormChildClass() {
8795    AcroFormField.call(this);
8796
8797    var _parent;
8798
8799    Object.defineProperty(this, "Parent", {
8800      enumerable: false,
8801      configurable: false,
8802      get: function get() {
8803        return _parent;
8804      },
8805      set: function set(value) {
8806        _parent = value;
8807      }
8808    });
8809
8810    var _optionName;
8811
8812    Object.defineProperty(this, "optionName", {
8813      enumerable: false,
8814      configurable: true,
8815      get: function get() {
8816        return _optionName;
8817      },
8818      set: function set(value) {
8819        _optionName = value;
8820      }
8821    });
8822    var _MK = {};
8823    Object.defineProperty(this, "MK", {
8824      enumerable: false,
8825      configurable: false,
8826      get: function get() {
8827        var encryptor = function encryptor(data) {
8828          return data;
8829        };
8830
8831        if (this.scope) encryptor = this.scope.internal.getEncryptor(this.objId);
8832        var result = [];
8833        result.push("<<");
8834        var key;
8835
8836        for (key in _MK) {
8837          result.push("/" + key + " (" + pdfEscape(encryptor(_MK[key])) + ")");
8838        }
8839
8840        result.push(">>");
8841        return result.join("\n");
8842      },
8843      set: function set(value) {
8844        if (_typeof(value) === "object") {
8845          _MK = value;
8846        }
8847      }
8848    });
8849    /**
8850     * From the PDF reference:
8851     * (Optional, button fields only) The widget annotation's normal caption which shall be displayed when it is not interacting with the user.
8852     * Unlike the remaining entries listed in this Table which apply only to widget annotations associated with pushbutton fields (see Pushbuttons in 12.7.4.2, "Button Fields"), the CA entry may be used with any type of button field, including check boxes (see Check Boxes in 12.7.4.2, "Button Fields") and radio buttons (Radio Buttons in 12.7.4.2, "Button Fields").
8853     *
8854     * - '8' = Cross,
8855     * - 'l' =  Circle,
8856     * - '' = nothing
8857     * @name AcroFormButton#caption
8858     * @type {string}
8859     */
8860
8861    Object.defineProperty(this, "caption", {
8862      enumerable: true,
8863      configurable: true,
8864      get: function get() {
8865        return _MK.CA || "";
8866      },
8867      set: function set(value) {
8868        if (typeof value === "string") {
8869          _MK.CA = value;
8870        }
8871      }
8872    });
8873
8874    var _AS;
8875
8876    Object.defineProperty(this, "AS", {
8877      enumerable: false,
8878      configurable: false,
8879      get: function get() {
8880        return _AS;
8881      },
8882      set: function set(value) {
8883        _AS = value;
8884      }
8885    });
8886    /**
8887     * (Required if the appearance dictionary AP contains one or more subdictionaries; PDF 1.2) The annotation's appearance state, which selects the applicable appearance stream from an appearance subdictionary (see Section 12.5.5, "Appearance Streams")
8888     *
8889     * @name AcroFormButton#appearanceState
8890     * @type {any}
8891     */
8892
8893    Object.defineProperty(this, "appearanceState", {
8894      enumerable: true,
8895      configurable: true,
8896      get: function get() {
8897        return _AS.substr(1, _AS.length - 1);
8898      },
8899      set: function set(value) {
8900        _AS = "/" + value;
8901      }
8902    });
8903    this.caption = "l";
8904    this.appearanceState = "Off"; // todo: set AppearanceType as variable that can be set from the
8905    // outside...
8906
8907    this._AppearanceType = AcroFormAppearance.RadioButton.Circle; // The Default appearanceType is the Circle
8908
8909    this.appearanceStreamContent = this._AppearanceType.createAppearanceStream(this.optionName);
8910  };
8911
8912  inherit(AcroFormChildClass, AcroFormField);
8913
8914  AcroFormRadioButton.prototype.setAppearance = function (appearance) {
8915    if (!("createAppearanceStream" in appearance && "getCA" in appearance)) {
8916      throw new Error("Couldn't assign Appearance to RadioButton. Appearance was Invalid!");
8917    }
8918
8919    for (var objId in this.Kids) {
8920      if (this.Kids.hasOwnProperty(objId)) {
8921        var child = this.Kids[objId];
8922        child.appearanceStreamContent = appearance.createAppearanceStream(child.optionName);
8923        child.caption = appearance.getCA();
8924      }
8925    }
8926  };
8927
8928  AcroFormRadioButton.prototype.createOption = function (name) {
8929    // Create new Child for RadioGroup
8930    var child = new AcroFormChildClass();
8931    child.Parent = this;
8932    child.optionName = name; // Add to Parent
8933
8934    this.Kids.push(child);
8935    addField.call(this.scope, child);
8936    return child;
8937  };
8938  /**
8939   * @class AcroFormCheckBox
8940   * @extends AcroFormButton
8941   * @extends AcroFormField
8942   */
8943
8944
8945  var AcroFormCheckBox = function AcroFormCheckBox() {
8946    AcroFormButton.call(this);
8947    this.fontName = "zapfdingbats";
8948    this.caption = "3";
8949    this.appearanceState = "On";
8950    this.value = "On";
8951    this.textAlign = "center";
8952    this.appearanceStreamContent = AcroFormAppearance.CheckBox.createAppearanceStream();
8953  };
8954
8955  inherit(AcroFormCheckBox, AcroFormButton);
8956  /**
8957   * @class AcroFormTextField
8958   * @extends AcroFormField
8959   */
8960
8961  var AcroFormTextField = function AcroFormTextField() {
8962    AcroFormField.call(this);
8963    this.FT = "/Tx";
8964    /**
8965     * If set, the field may contain multiple lines of text; if clear, the field’s text shall be restricted to a single line.
8966     *
8967     * @name AcroFormTextField#multiline
8968     * @type {boolean}
8969     */
8970
8971    Object.defineProperty(this, "multiline", {
8972      enumerable: true,
8973      configurable: true,
8974      get: function get() {
8975        return Boolean(getBitForPdf(this.Ff, 13));
8976      },
8977      set: function set(value) {
8978        if (Boolean(value) === true) {
8979          this.Ff = setBitForPdf(this.Ff, 13);
8980        } else {
8981          this.Ff = clearBitForPdf(this.Ff, 13);
8982        }
8983      }
8984    });
8985    /**
8986     * (PDF 1.4) If set, the text entered in the field represents the pathname of a file whose contents shall be submitted as the value of the field.
8987     *
8988     * @name AcroFormTextField#fileSelect
8989     * @type {boolean}
8990     */
8991
8992    Object.defineProperty(this, "fileSelect", {
8993      enumerable: true,
8994      configurable: true,
8995      get: function get() {
8996        return Boolean(getBitForPdf(this.Ff, 21));
8997      },
8998      set: function set(value) {
8999        if (Boolean(value) === true) {
9000          this.Ff = setBitForPdf(this.Ff, 21);
9001        } else {
9002          this.Ff = clearBitForPdf(this.Ff, 21);
9003        }
9004      }
9005    });
9006    /**
9007     * (PDF 1.4) If set, text entered in the field shall not be spell-checked.
9008     *
9009     * @name AcroFormTextField#doNotSpellCheck
9010     * @type {boolean}
9011     */
9012
9013    Object.defineProperty(this, "doNotSpellCheck", {
9014      enumerable: true,
9015      configurable: true,
9016      get: function get() {
9017        return Boolean(getBitForPdf(this.Ff, 23));
9018      },
9019      set: function set(value) {
9020        if (Boolean(value) === true) {
9021          this.Ff = setBitForPdf(this.Ff, 23);
9022        } else {
9023          this.Ff = clearBitForPdf(this.Ff, 23);
9024        }
9025      }
9026    });
9027    /**
9028     * (PDF 1.4) If set, the field shall not scroll (horizontally for single-line fields, vertically for multiple-line fields) to accommodate more text than fits within its annotation rectangle. Once the field is full, no further text shall be accepted for interactive form filling; for noninteractive form filling, the filler should take care not to add more character than will visibly fit in the defined area.
9029     *
9030     * @name AcroFormTextField#doNotScroll
9031     * @type {boolean}
9032     */
9033
9034    Object.defineProperty(this, "doNotScroll", {
9035      enumerable: true,
9036      configurable: true,
9037      get: function get() {
9038        return Boolean(getBitForPdf(this.Ff, 24));
9039      },
9040      set: function set(value) {
9041        if (Boolean(value) === true) {
9042          this.Ff = setBitForPdf(this.Ff, 24);
9043        } else {
9044          this.Ff = clearBitForPdf(this.Ff, 24);
9045        }
9046      }
9047    });
9048    /**
9049     * (PDF 1.5) May be set only if the MaxLen entry is present in the text field dictionary (see Table 229) and if the Multiline, Password, and FileSelect flags are clear. If set, the field shall be automatically divi
vendor: 36,020 bytes, lines 9049-10083
9049ded into as many equally spaced positions, or combs, as the value of MaxLen, and the text is laid out into those combs.
9050     *
9051     * @name AcroFormTextField#comb
9052     * @type {boolean}
9053     */
9054
9055    Object.defineProperty(this, "comb", {
9056      enumerable: true,
9057      configurable: true,
9058      get: function get() {
9059        return Boolean(getBitForPdf(this.Ff, 25));
9060      },
9061      set: function set(value) {
9062        if (Boolean(value) === true) {
9063          this.Ff = setBitForPdf(this.Ff, 25);
9064        } else {
9065          this.Ff = clearBitForPdf(this.Ff, 25);
9066        }
9067      }
9068    });
9069    /**
9070     * (PDF 1.5) If set, the value of this field shall be a rich text string (see 12.7.3.4, “Rich Text Strings”). If the field has a value, the RV entry of the field dictionary (Table 222) shall specify the rich text string.
9071     *
9072     * @name AcroFormTextField#richText
9073     * @type {boolean}
9074     */
9075
9076    Object.defineProperty(this, "richText", {
9077      enumerable: true,
9078      configurable: true,
9079      get: function get() {
9080        return Boolean(getBitForPdf(this.Ff, 26));
9081      },
9082      set: function set(value) {
9083        if (Boolean(value) === true) {
9084          this.Ff = setBitForPdf(this.Ff, 26);
9085        } else {
9086          this.Ff = clearBitForPdf(this.Ff, 26);
9087        }
9088      }
9089    });
9090    var _MaxLen = null;
9091    Object.defineProperty(this, "MaxLen", {
9092      enumerable: true,
9093      configurable: false,
9094      get: function get() {
9095        return _MaxLen;
9096      },
9097      set: function set(value) {
9098        _MaxLen = value;
9099      }
9100    });
9101    /**
9102     * (Optional; inheritable) The maximum length of the field’s text, in characters.
9103     *
9104     * @name AcroFormTextField#maxLength
9105     * @type {number}
9106     */
9107
9108    Object.defineProperty(this, "maxLength", {
9109      enumerable: true,
9110      configurable: true,
9111      get: function get() {
9112        return _MaxLen;
9113      },
9114      set: function set(value) {
9115        if (Number.isInteger(value)) {
9116          _MaxLen = value;
9117        }
9118      }
9119    });
9120    Object.defineProperty(this, "hasAppearanceStream", {
9121      enumerable: true,
9122      configurable: true,
9123      get: function get() {
9124        return this.V || this.DV;
9125      }
9126    });
9127  };
9128
9129  inherit(AcroFormTextField, AcroFormField);
9130  /**
9131   * @class AcroFormPasswordField
9132   * @extends AcroFormTextField
9133   * @extends AcroFormField
9134   */
9135
9136  var AcroFormPasswordField = function AcroFormPasswordField() {
9137    AcroFormTextField.call(this);
9138    /**
9139     * If set, the field is intended for entering a secure password that should not be echoed visibly to the screen. Characters typed from the keyboard shall instead be echoed in some unreadable form, such as asterisks or bullet characters.
9140     * NOTE To protect password confidentiality, readers should never store the value of the text field in the PDF file if this flag is set.
9141     *
9142     * @name AcroFormTextField#password
9143     * @type {boolean}
9144     */
9145
9146    Object.defineProperty(this, "password", {
9147      enumerable: true,
9148      configurable: true,
9149      get: function get() {
9150        return Boolean(getBitForPdf(this.Ff, 14));
9151      },
9152      set: function set(value) {
9153        if (Boolean(value) === true) {
9154          this.Ff = setBitForPdf(this.Ff, 14);
9155        } else {
9156          this.Ff = clearBitForPdf(this.Ff, 14);
9157        }
9158      }
9159    });
9160    this.password = true;
9161  };
9162
9163  inherit(AcroFormPasswordField, AcroFormTextField); // Contains Methods for creating standard appearances
9164
9165  var AcroFormAppearance = {
9166    CheckBox: {
9167      createAppearanceStream: function createAppearanceStream() {
9168        var appearance = {
9169          N: {
9170            On: AcroFormAppearance.CheckBox.YesNormal
9171          },
9172          D: {
9173            On: AcroFormAppearance.CheckBox.YesPushDown,
9174            Off: AcroFormAppearance.CheckBox.OffPushDown
9175          }
9176        };
9177        return appearance;
9178      },
9179
9180      /**
9181       * Returns the standard On Appearance for a CheckBox
9182       *
9183       * @returns {AcroFormXObject}
9184       */
9185      YesPushDown: function YesPushDown(formObject) {
9186        var xobj = createFormXObject(formObject);
9187        xobj.scope = formObject.scope;
9188        var stream = [];
9189        var fontKey = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle).id;
9190
9191        var encodedColor = formObject.scope.__private__.encodeColorString(formObject.color);
9192
9193        var calcRes = calculateX(formObject, formObject.caption);
9194        stream.push("0.749023 g");
9195        stream.push("0 0 " + f2(AcroFormAppearance.internal.getWidth(formObject)) + " " + f2(AcroFormAppearance.internal.getHeight(formObject)) + " re");
9196        stream.push("f");
9197        stream.push("BMC");
9198        stream.push("q");
9199        stream.push("0 0 1 rg");
9200        stream.push("/" + fontKey + " " + f2(calcRes.fontSize) + " Tf " + encodedColor);
9201        stream.push("BT");
9202        stream.push(calcRes.text);
9203        stream.push("ET");
9204        stream.push("Q");
9205        stream.push("EMC");
9206        xobj.stream = stream.join("\n");
9207        return xobj;
9208      },
9209      YesNormal: function YesNormal(formObject) {
9210        var xobj = createFormXObject(formObject);
9211        xobj.scope = formObject.scope;
9212        var fontKey = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle).id;
9213
9214        var encodedColor = formObject.scope.__private__.encodeColorString(formObject.color);
9215
9216        var stream = [];
9217        var height = AcroFormAppearance.internal.getHeight(formObject);
9218        var width = AcroFormAppearance.internal.getWidth(formObject);
9219        var calcRes = calculateX(formObject, formObject.caption);
9220        stream.push("1 g");
9221        stream.push("0 0 " + f2(width) + " " + f2(height) + " re");
9222        stream.push("f");
9223        stream.push("q");
9224        stream.push("0 0 1 rg");
9225        stream.push("0 0 " + f2(width - 1) + " " + f2(height - 1) + " re");
9226        stream.push("W");
9227        stream.push("n");
9228        stream.push("0 g");
9229        stream.push("BT");
9230        stream.push("/" + fontKey + " " + f2(calcRes.fontSize) + " Tf " + encodedColor);
9231        stream.push(calcRes.text);
9232        stream.push("ET");
9233        stream.push("Q");
9234        xobj.stream = stream.join("\n");
9235        return xobj;
9236      },
9237
9238      /**
9239       * Returns the standard Off Appearance for a CheckBox
9240       *
9241       * @returns {AcroFormXObject}
9242       */
9243      OffPushDown: function OffPushDown(formObject) {
9244        var xobj = createFormXObject(formObject);
9245        xobj.scope = formObject.scope;
9246        var stream = [];
9247        stream.push("0.749023 g");
9248        stream.push("0 0 " + f2(AcroFormAppearance.internal.getWidth(formObject)) + " " + f2(AcroFormAppearance.internal.getHeight(formObject)) + " re");
9249        stream.push("f");
9250        xobj.stream = stream.join("\n");
9251        return xobj;
9252      }
9253    },
9254    RadioButton: {
9255      Circle: {
9256        createAppearanceStream: function createAppearanceStream(name) {
9257          var appearanceStreamContent = {
9258            D: {
9259              Off: AcroFormAppearance.RadioButton.Circle.OffPushDown
9260            },
9261            N: {}
9262          };
9263          appearanceStreamContent.N[name] = AcroFormAppearance.RadioButton.Circle.YesNormal;
9264          appearanceStreamContent.D[name] = AcroFormAppearance.RadioButton.Circle.YesPushDown;
9265          return appearanceStreamContent;
9266        },
9267        getCA: function getCA() {
9268          return "l";
9269        },
9270        YesNormal: function YesNormal(formObject) {
9271          var xobj = createFormXObject(formObject);
9272          xobj.scope = formObject.scope;
9273          var stream = []; // Make the Radius of the Circle relative to min(height, width) of formObject
9274
9275          var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4; // The Borderpadding...
9276
9277          DotRadius = Number((DotRadius * 0.9).toFixed(5));
9278          var c = AcroFormAppearance.internal.Bezier_C;
9279          var DotRadiusBezier = Number((DotRadius * c).toFixed(5));
9280          /*
9281           * The Following is a Circle created with Bezier-Curves.
9282           */
9283
9284          stream.push("q");
9285          stream.push("1 0 0 1 " + f5(AcroFormAppearance.internal.getWidth(formObject) / 2) + " " + f5(AcroFormAppearance.internal.getHeight(formObject) / 2) + " cm");
9286          stream.push(DotRadius + " 0 m");
9287          stream.push(DotRadius + " " + DotRadiusBezier + " " + DotRadiusBezier + " " + DotRadius + " 0 " + DotRadius + " c");
9288          stream.push("-" + DotRadiusBezier + " " + DotRadius + " -" + DotRadius + " " + DotRadiusBezier + " -" + DotRadius + " 0 c");
9289          stream.push("-" + DotRadius + " -" + DotRadiusBezier + " -" + DotRadiusBezier + " -" + DotRadius + " 0 -" + DotRadius + " c");
9290          stream.push(DotRadiusBezier + " -" + DotRadius + " " + DotRadius + " -" + DotRadiusBezier + " " + DotRadius + " 0 c");
9291          stream.push("f");
9292          stream.push("Q");
9293          xobj.stream = stream.join("\n");
9294          return xobj;
9295        },
9296        YesPushDown: function YesPushDown(formObject) {
9297          var xobj = createFormXObject(formObject);
9298          xobj.scope = formObject.scope;
9299          var stream = [];
9300          var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4; // The Borderpadding...
9301
9302          DotRadius = Number((DotRadius * 0.9).toFixed(5)); // Save results for later use; no need to waste
9303          // processor ticks on doing math
9304
9305          var k = Number((DotRadius * 2).toFixed(5));
9306          var kc = Number((k * AcroFormAppearance.internal.Bezier_C).toFixed(5));
9307          var dc = Number((DotRadius * AcroFormAppearance.internal.Bezier_C).toFixed(5));
9308          stream.push("0.749023 g");
9309          stream.push("q");
9310          stream.push("1 0 0 1 " + f5(AcroFormAppearance.internal.getWidth(formObject) / 2) + " " + f5(AcroFormAppearance.internal.getHeight(formObject) / 2) + " cm");
9311          stream.push(k + " 0 m");
9312          stream.push(k + " " + kc + " " + kc + " " + k + " 0 " + k + " c");
9313          stream.push("-" + kc + " " + k + " -" + k + " " + kc + " -" + k + " 0 c");
9314          stream.push("-" + k + " -" + kc + " -" + kc + " -" + k + " 0 -" + k + " c");
9315          stream.push(kc + " -" + k + " " + k + " -" + kc + " " + k + " 0 c");
9316          stream.push("f");
9317          stream.push("Q");
9318          stream.push("0 g");
9319          stream.push("q");
9320          stream.push("1 0 0 1 " + f5(AcroFormAppearance.internal.getWidth(formObject) / 2) + " " + f5(AcroFormAppearance.internal.getHeight(formObject) / 2) + " cm");
9321          stream.push(DotRadius + " 0 m");
9322          stream.push("" + DotRadius + " " + dc + " " + dc + " " + DotRadius + " 0 " + DotRadius + " c");
9323          stream.push("-" + dc + " " + DotRadius + " -" + DotRadius + " " + dc + " -" + DotRadius + " 0 c");
9324          stream.push("-" + DotRadius + " -" + dc + " -" + dc + " -" + DotRadius + " 0 -" + DotRadius + " c");
9325          stream.push(dc + " -" + DotRadius + " " + DotRadius + " -" + dc + " " + DotRadius + " 0 c");
9326          stream.push("f");
9327          stream.push("Q");
9328          xobj.stream = stream.join("\n");
9329          return xobj;
9330        },
9331        OffPushDown: function OffPushDown(formObject) {
9332          var xobj = createFormXObject(formObject);
9333          xobj.scope = formObject.scope;
9334          var stream = [];
9335          var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4; // The Borderpadding...
9336
9337          DotRadius = Number((DotRadius * 0.9).toFixed(5)); // Save results for later use; no need to waste
9338          // processor ticks on doing math
9339
9340          var k = Number((DotRadius * 2).toFixed(5));
9341          var kc = Number((k * AcroFormAppearance.internal.Bezier_C).toFixed(5));
9342          stream.push("0.749023 g");
9343          stream.push("q");
9344          stream.push("1 0 0 1 " + f5(AcroFormAppearance.internal.getWidth(formObject) / 2) + " " + f5(AcroFormAppearance.internal.getHeight(formObject) / 2) + " cm");
9345          stream.push(k + " 0 m");
9346          stream.push(k + " " + kc + " " + kc + " " + k + " 0 " + k + " c");
9347          stream.push("-" + kc + " " + k + " -" + k + " " + kc + " -" + k + " 0 c");
9348          stream.push("-" + k + " -" + kc + " -" + kc + " -" + k + " 0 -" + k + " c");
9349          stream.push(kc + " -" + k + " " + k + " -" + kc + " " + k + " 0 c");
9350          stream.push("f");
9351          stream.push("Q");
9352          xobj.stream = stream.join("\n");
9353          return xobj;
9354        }
9355      },
9356      Cross: {
9357        /**
9358         * Creates the Actual AppearanceDictionary-References
9359         *
9360         * @param {string} name
9361         * @returns {Object}
9362         * @ignore
9363         */
9364        createAppearanceStream: function createAppearanceStream(name) {
9365          var appearanceStreamContent = {
9366            D: {
9367              Off: AcroFormAppearance.RadioButton.Cross.OffPushDown
9368            },
9369            N: {}
9370          };
9371          appearanceStreamContent.N[name] = AcroFormAppearance.RadioButton.Cross.YesNormal;
9372          appearanceStreamContent.D[name] = AcroFormAppearance.RadioButton.Cross.YesPushDown;
9373          return appearanceStreamContent;
9374        },
9375        getCA: function getCA() {
9376          return "8";
9377        },
9378        YesNormal: function YesNormal(formObject) {
9379          var xobj = createFormXObject(formObject);
9380          xobj.scope = formObject.scope;
9381          var stream = [];
9382          var cross = AcroFormAppearance.internal.calculateCross(formObject);
9383          stream.push("q");
9384          stream.push("1 1 " + f2(AcroFormAppearance.internal.getWidth(formObject) - 2) + " " + f2(AcroFormAppearance.internal.getHeight(formObject) - 2) + " re");
9385          stream.push("W");
9386          stream.push("n");
9387          stream.push(f2(cross.x1.x) + " " + f2(cross.x1.y) + " m");
9388          stream.push(f2(cross.x2.x) + " " + f2(cross.x2.y) + " l");
9389          stream.push(f2(cross.x4.x) + " " + f2(cross.x4.y) + " m");
9390          stream.push(f2(cross.x3.x) + " " + f2(cross.x3.y) + " l");
9391          stream.push("s");
9392          stream.push("Q");
9393          xobj.stream = stream.join("\n");
9394          return xobj;
9395        },
9396        YesPushDown: function YesPushDown(formObject) {
9397          var xobj = createFormXObject(formObject);
9398          xobj.scope = formObject.scope;
9399          var cross = AcroFormAppearance.internal.calculateCross(formObject);
9400          var stream = [];
9401          stream.push("0.749023 g");
9402          stream.push("0 0 " + f2(AcroFormAppearance.internal.getWidth(formObject)) + " " + f2(AcroFormAppearance.internal.getHeight(formObject)) + " re");
9403          stream.push("f");
9404          stream.push("q");
9405          stream.push("1 1 " + f2(AcroFormAppearance.internal.getWidth(formObject) - 2) + " " + f2(AcroFormAppearance.internal.getHeight(formObject) - 2) + " re");
9406          stream.push("W");
9407          stream.push("n");
9408          stream.push(f2(cross.x1.x) + " " + f2(cross.x1.y) + " m");
9409          stream.push(f2(cross.x2.x) + " " + f2(cross.x2.y) + " l");
9410          stream.push(f2(cross.x4.x) + " " + f2(cross.x4.y) + " m");
9411          stream.push(f2(cross.x3.x) + " " + f2(cross.x3.y) + " l");
9412          stream.push("s");
9413          stream.push("Q");
9414          xobj.stream = stream.join("\n");
9415          return xobj;
9416        },
9417        OffPushDown: function OffPushDown(formObject) {
9418          var xobj = createFormXObject(formObject);
9419          xobj.scope = formObject.scope;
9420          var stream = [];
9421          stream.push("0.749023 g");
9422          stream.push("0 0 " + f2(AcroFormAppearance.internal.getWidth(formObject)) + " " + f2(AcroFormAppearance.internal.getHeight(formObject)) + " re");
9423          stream.push("f");
9424          xobj.stream = stream.join("\n");
9425          return xobj;
9426        }
9427      }
9428    },
9429
9430    /**
9431     * Returns the standard Appearance
9432     *
9433     * @returns {AcroFormXObject}
9434     */
9435    createDefaultAppearanceStream: function createDefaultAppearanceStream(formObject) {
9436      // Set Helvetica to Standard Font (size: auto)
9437      // Color: Black
9438      var fontKey = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle).id;
9439
9440      var encodedColor = formObject.scope.__private__.encodeColorString(formObject.color);
9441
9442      var fontSize = formObject.fontSize;
9443      var result = "/" + fontKey + " " + fontSize + " Tf " + encodedColor;
9444      return result;
9445    }
9446  };
9447  AcroFormAppearance.internal = {
9448    Bezier_C: 0.551915024494,
9449    calculateCross: function calculateCross(formObject) {
9450      var width = AcroFormAppearance.internal.getWidth(formObject);
9451      var height = AcroFormAppearance.internal.getHeight(formObject);
9452      var a = Math.min(width, height);
9453      var cross = {
9454        x1: {
9455          // upperLeft
9456          x: (width - a) / 2,
9457          y: (height - a) / 2 + a // height - borderPadding
9458
9459        },
9460        x2: {
9461          // lowerRight
9462          x: (width - a) / 2 + a,
9463          y: (height - a) / 2 // borderPadding
9464
9465        },
9466        x3: {
9467          // lowerLeft
9468          x: (width - a) / 2,
9469          y: (height - a) / 2 // borderPadding
9470
9471        },
9472        x4: {
9473          // upperRight
9474          x: (width - a) / 2 + a,
9475          y: (height - a) / 2 + a // height - borderPadding
9476
9477        }
9478      };
9479      return cross;
9480    }
9481  };
9482
9483  AcroFormAppearance.internal.getWidth = function (formObject) {
9484    var result = 0;
9485
9486    if (_typeof(formObject) === "object") {
9487      result = scale(formObject.Rect[2]);
9488    }
9489
9490    return result;
9491  };
9492
9493  AcroFormAppearance.internal.getHeight = function (formObject) {
9494    var result = 0;
9495
9496    if (_typeof(formObject) === "object") {
9497      result = scale(formObject.Rect[3]);
9498    }
9499
9500    return result;
9501  }; // Public:
9502
9503  /**
9504   * Add an AcroForm-Field to the jsPDF-instance
9505   *
9506   * @name addField
9507   * @function
9508   * @instance
9509   * @param {Object} fieldObject
9510   * @returns {jsPDF}
9511   */
9512
9513
9514  var addField = jsPDFAPI.addField = function (fieldObject) {
9515    initializeAcroForm(this, fieldObject);
9516
9517    if (fieldObject instanceof AcroFormField) {
9518      putForm(fieldObject);
9519    } else {
9520      throw new Error("Invalid argument passed to jsPDF.addField.");
9521    }
9522
9523    fieldObject.page = fieldObject.scope.internal.getCurrentPageInfo().pageNumber;
9524    return this;
9525  };
9526
9527  jsPDFAPI.AcroFormChoiceField = AcroFormChoiceField;
9528  jsPDFAPI.AcroFormListBox = AcroFormListBox;
9529  jsPDFAPI.AcroFormComboBox = AcroFormComboBox;
9530  jsPDFAPI.AcroFormEditBox = AcroFormEditBox;
9531  jsPDFAPI.AcroFormButton = AcroFormButton;
9532  jsPDFAPI.AcroFormPushButton = AcroFormPushButton;
9533  jsPDFAPI.AcroFormRadioButton = AcroFormRadioButton;
9534  jsPDFAPI.AcroFormCheckBox = AcroFormCheckBox;
9535  jsPDFAPI.AcroFormTextField = AcroFormTextField;
9536  jsPDFAPI.AcroFormPasswordField = AcroFormPasswordField;
9537  jsPDFAPI.AcroFormAppearance = AcroFormAppearance;
9538  jsPDFAPI.AcroForm = {
9539    ChoiceField: AcroFormChoiceField,
9540    ListBox: AcroFormListBox,
9541    ComboBox: AcroFormComboBox,
9542    EditBox: AcroFormEditBox,
9543    Button: AcroFormButton,
9544    PushButton: AcroFormPushButton,
9545    RadioButton: AcroFormRadioButton,
9546    CheckBox: AcroFormCheckBox,
9547    TextField: AcroFormTextField,
9548    PasswordField: AcroFormPasswordField,
9549    Appearance: AcroFormAppearance
9550  };
9551  jsPDF.AcroForm = {
9552    ChoiceField: AcroFormChoiceField,
9553    ListBox: AcroFormListBox,
9554    ComboBox: AcroFormComboBox,
9555    EditBox: AcroFormEditBox,
9556    Button: AcroFormButton,
9557    PushButton: AcroFormPushButton,
9558    RadioButton: AcroFormRadioButton,
9559    CheckBox: AcroFormCheckBox,
9560    TextField: AcroFormTextField,
9561    PasswordField: AcroFormPasswordField,
9562    Appearance: AcroFormAppearance
9563  };
9564  var AcroForm = jsPDF.AcroForm;
9565
9566  (function (jsPDFAPI) {
9567
9568    var namespace = "addImage_";
9569    jsPDFAPI.__addimage__ = {};
9570    var UNKNOWN = "UNKNOWN"; // Heuristic selection of a good batch for large array .apply. Not limiting make the call overflow.
9571    // With too small batch iteration will be slow as more calls are made,
9572    // higher values cause larger and slower garbage collection.
9573
9574    var ARRAY_APPLY_BATCH = 8192;
9575    var imageFileTypeHeaders = {
9576      PNG: [[0x89, 0x50, 0x4e, 0x47]],
9577      TIFF: [[0x4d, 0x4d, 0x00, 0x2a], //Motorola
9578      [0x49, 0x49, 0x2a, 0x00] //Intel
9579      ],
9580      JPEG: [[0xff, 0xd8, 0xff, 0xe0, undefined, undefined, 0x4a, 0x46, 0x49, 0x46, 0x00], //JFIF
9581      [0xff, 0xd8, 0xff, 0xe1, undefined, undefined, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00], //Exif
9582      [0xff, 0xd8, 0xff, 0xdb], //JPEG RAW
9583      [0xff, 0xd8, 0xff, 0xee] //EXIF RAW
9584      ],
9585      JPEG2000: [[0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20]],
9586      GIF87a: [[0x47, 0x49, 0x46, 0x38, 0x37, 0x61]],
9587      GIF89a: [[0x47, 0x49, 0x46, 0x38, 0x39, 0x61]],
9588      WEBP: [[0x52, 0x49, 0x46, 0x46, undefined, undefined, undefined, undefined, 0x57, 0x45, 0x42, 0x50]],
9589      BMP: [[0x42, 0x4d], //BM - Windows 3.1x, 95, NT, ... etc.
9590      [0x42, 0x41], //BA - OS/2 struct bitmap array
9591      [0x43, 0x49], //CI - OS/2 struct color icon
9592      [0x43, 0x50], //CP - OS/2 const color pointer
9593      [0x49, 0x43], //IC - OS/2 struct icon
9594      [0x50, 0x54] //PT - OS/2 pointer
9595      ]
9596    };
9597    /**
9598     * Recognize filetype of Image by magic-bytes
9599     *
9600     * https://en.wikipedia.org/wiki/List_of_file_signatures
9601     *
9602     * @name getImageFileTypeByImageData
9603     * @public
9604     * @function
9605     * @param {string|arraybuffer} imageData imageData as binary String or arraybuffer
9606     * @param {string} format format of file if filetype-recognition fails, e.g. 'JPEG'
9607     *
9608     * @returns {string} filetype of Image
9609     */
9610
9611    var getImageFileTypeByImageData = jsPDFAPI.__addimage__.getImageFileTypeByImageData = function (imageData, fallbackFormat) {
9612      fallbackFormat = fallbackFormat || UNKNOWN;
9613      var i;
9614      var j;
9615      var result = UNKNOWN;
9616      var headerSchemata;
9617      var compareResult;
9618      var fileType;
9619
9620      if (fallbackFormat === "RGBA" || imageData.data !== undefined && imageData.data instanceof Uint8ClampedArray && "height" in imageData && "width" in imageData) {
9621        return "RGBA";
9622      }
9623
9624      if (isArrayBufferView(imageData)) {
9625        for (fileType in imageFileTypeHeaders) {
9626          headerSchemata = imageFileTypeHeaders[fileType];
9627
9628          for (i = 0; i < headerSchemata.length; i += 1) {
9629            compareResult = true;
9630
9631            for (j = 0; j < headerSchemata[i].length; j += 1) {
9632              if (headerSchemata[i][j] === undefined) {
9633                continue;
9634              }
9635
9636              if (headerSchemata[i][j] !== imageData[j]) {
9637                compareResult = false;
9638                break;
9639              }
9640            }
9641
9642            if (compareResult === true) {
9643              result = fileType;
9644              break;
9645            }
9646          }
9647        }
9648      } else {
9649        for (fileType in imageFileTypeHeaders) {
9650          headerSchemata = imageFileTypeHeaders[fileType];
9651
9652          for (i = 0; i < headerSchemata.length; i += 1) {
9653            compareResult = true;
9654
9655            for (j = 0; j < headerSchemata[i].length; j += 1) {
9656              if (headerSchemata[i][j] === undefined) {
9657                continue;
9658              }
9659
9660              if (headerSchemata[i][j] !== imageData.charCodeAt(j)) {
9661                compareResult = false;
9662                break;
9663              }
9664            }
9665
9666            if (compareResult === true) {
9667              result = fileType;
9668              break;
9669            }
9670          }
9671        }
9672      }
9673
9674      if (result === UNKNOWN && fallbackFormat !== UNKNOWN) {
9675        result = fallbackFormat;
9676      }
9677
9678      return result;
9679    }; // Image functionality ported from pdf.js
9680
9681
9682    var putImage = function putImage(image) {
9683      var out = this.internal.write;
9684      var putStream = this.internal.putStream;
9685      var getFilters = this.internal.getFilters;
9686      var filter = getFilters();
9687
9688      while (filter.indexOf("FlateEncode") !== -1) {
9689        filter.splice(filter.indexOf("FlateEncode"), 1);
9690      }
9691
9692      image.objectId = this.internal.newObject();
9693      var additionalKeyValues = [];
9694      additionalKeyValues.push({
9695        key: "Type",
9696        value: "/XObject"
9697      });
9698      additionalKeyValues.push({
9699        key: "Subtype",
9700        value: "/Image"
9701      });
9702      additionalKeyValues.push({
9703        key: "Width",
9704        value: image.width
9705      });
9706      additionalKeyValues.push({
9707        key: "Height",
9708        value: image.height
9709      });
9710
9711      if (image.colorSpace === color_spaces.INDEXED) {
9712        additionalKeyValues.push({
9713          key: "ColorSpace",
9714          value: "[/Indexed /DeviceRGB " + ( // if an indexed png defines more than one colour with transparency, we've created a sMask
9715          image.palette.length / 3 - 1) + " " + ("sMask" in image && typeof image.sMask !== "undefined" ? image.objectId + 2 : image.objectId + 1) + " 0 R]"
9716        });
9717      } else {
9718        additionalKeyValues.push({
9719          key: "ColorSpace",
9720          value: "/" + image.colorSpace
9721        });
9722
9723        if (image.colorSpace === color_spaces.DEVICE_CMYK) {
9724          additionalKeyValues.push({
9725            key: "Decode",
9726            value: "[1 0 1 0 1 0 1 0]"
9727          });
9728        }
9729      }
9730
9731      additionalKeyValues.push({
9732        key: "BitsPerComponent",
9733        value: image.bitsPerComponent
9734      });
9735
9736      if ("decodeParameters" in image && typeof image.decodeParameters !== "undefined") {
9737        additionalKeyValues.push({
9738          key: "DecodeParms",
9739          value: "<<" + image.decodeParameters + ">>"
9740        });
9741      }
9742
9743      if ("transparency" in image && Array.isArray(image.transparency)) {
9744        var transparency = "",
9745            i = 0,
9746            len = image.transparency.length;
9747
9748        for (; i < len; i++) {
9749          transparency += image.transparency[i] + " " + image.transparency[i] + " ";
9750        }
9751
9752        additionalKeyValues.push({
9753          key: "Mask",
9754          value: "[" + transparency + "]"
9755        });
9756      }
9757
9758      if (typeof image.sMask !== "undefined") {
9759        additionalKeyValues.push({
9760          key: "SMask",
9761          value: image.objectId + 1 + " 0 R"
9762        });
9763      }
9764
9765      var alreadyAppliedFilters = typeof image.filter !== "undefined" ? ["/" + image.filter] : undefined;
9766      putStream({
9767        data: image.data,
9768        additionalKeyValues: additionalKeyValues,
9769        alreadyAppliedFilters: alreadyAppliedFilters,
9770        objectId: image.objectId
9771      });
9772      out("endobj"); // Soft mask
9773
9774      if ("sMask" in image && typeof image.sMask !== "undefined") {
9775        var decodeParameters = "/Predictor " + image.predictor + " /Colors 1 /BitsPerComponent " + image.bitsPerComponent + " /Columns " + image.width;
9776        var sMask = {
9777          width: image.width,
9778          height: image.height,
9779          colorSpace: "DeviceGray",
9780          bitsPerComponent: image.bitsPerComponent,
9781          decodeParameters: decodeParameters,
9782          data: image.sMask
9783        };
9784
9785        if ("filter" in image) {
9786          sMask.filter = image.filter;
9787        }
9788
9789        putImage.call(this, sMask);
9790      } //Palette
9791
9792
9793      if (image.colorSpace === color_spaces.INDEXED) {
9794        var objId = this.internal.newObject(); //out('<< /Filter / ' + img['f'] +' /Length ' + img['pal'].length + '>>');
9795        //putStream(zlib.compress(img['pal']));
9796
9797        putStream({
9798          data: arrayBufferToBinaryString(new Uint8Array(image.palette)),
9799          objectId: objId
9800        });
9801        out("endobj");
9802      }
9803    };
9804
9805    var putResourcesCallback = function putResourcesCallback() {
9806      var images = this.internal.collections[namespace + "images"];
9807
9808      for (var i in images) {
9809        putImage.call(this, images[i]);
9810      }
9811    };
9812
9813    var putXObjectsDictCallback = function putXObjectsDictCallback() {
9814      var images = this.internal.collections[namespace + "images"],
9815          out = this.internal.write,
9816          image;
9817
9818      for (var i in images) {
9819        image = images[i];
9820        out("/I" + image.index, image.objectId, "0", "R");
9821      }
9822    };
9823
9824    var checkCompressValue = function checkCompressValue(value) {
9825      if (value && typeof value === "string") value = value.toUpperCase();
9826      return value in jsPDFAPI.image_compression ? value : image_compression.NONE;
9827    };
9828
9829    var initialize = function initialize() {
9830      if (!this.internal.collections[namespace + "images"]) {
9831        this.internal.collections[namespace + "images"] = {};
9832        this.internal.events.subscribe("putResources", putResourcesCallback);
9833        this.internal.events.subscribe("putXobjectDict", putXObjectsDictCallback);
9834      }
9835    };
9836
9837    var getImages = function getImages() {
9838      var images = this.internal.collections[namespace + "images"];
9839      initialize.call(this);
9840      return images;
9841    };
9842
9843    var getImageIndex = function getImageIndex() {
9844      return Object.keys(this.internal.collections[namespace + "images"]).length;
9845    };
9846
9847    var notDefined = function notDefined(value) {
9848      return typeof value === "undefined" || value === null || value.length === 0;
9849    };
9850
9851    var generateAliasFromImageData = function generateAliasFromImageData(imageData) {
9852      if (typeof imageData === "string" || isArrayBufferView(imageData)) {
9853        return sHashCode(imageData);
9854      } else if (isArrayBufferView(imageData.data)) {
9855        return sHashCode(imageData.data);
9856      }
9857
9858      return null;
9859    };
9860
9861    var isImageTypeSupported = function isImageTypeSupported(type) {
9862      return typeof jsPDFAPI["process" + type.toUpperCase()] === "function";
9863    };
9864
9865    var isDOMElement = function isDOMElement(object) {
9866      return _typeof(object) === "object" && object.nodeType === 1;
9867    };
9868
9869    var getImageDataFromElement = function getImageDataFromElement(element, format) {
9870      //if element is an image which uses data url definition, just return the dataurl
9871      if (element.nodeName === "IMG" && element.hasAttribute("src")) {
9872        var src = "" + element.getAttribute("src"); //is base64 encoded dataUrl, directly process it
9873
9874        if (src.indexOf("data:image/") === 0) {
9875          return atob(unescape(src).split("base64,").pop());
9876        } //it is probably an url, try to load it
9877
9878
9879        var tmpImageData = jsPDFAPI.loadFile(src, true);
9880
9881        if (tmpImageData !== undefined) {
9882          return tmpImageData;
9883        }
9884      }
9885
9886      if (element.nodeName === "CANVAS") {
9887        if (element.width === 0 || element.height === 0) {
9888          throw new Error("Given canvas must have data. Canvas width: " + element.width + ", height: " + element.height);
9889        }
9890
9891        var mimeType;
9892
9893        switch (format) {
9894          case "PNG":
9895            mimeType = "image/png";
9896            break;
9897
9898          case "WEBP":
9899            mimeType = "image/webp";
9900            break;
9901
9902          case "JPEG":
9903          case "JPG":
9904          default:
9905            mimeType = "image/jpeg";
9906            break;
9907        }
9908
9909        return atob(element.toDataURL(mimeType, 1.0).split("base64,").pop());
9910      }
9911    };
9912
9913    var checkImagesForAlias = function checkImagesForAlias(alias) {
9914      var images = this.internal.collections[namespace + "images"];
9915
9916      if (images) {
9917        for (var e in images) {
9918          if (alias === images[e].alias) {
9919            return images[e];
9920          }
9921        }
9922      }
9923    };
9924
9925    var determineWidthAndHeight = function determineWidthAndHeight(width, height, image) {
9926      if (!width && !height) {
9927        width = -96;
9928        height = -96;
9929      }
9930
9931      if (width < 0) {
9932        width = -1 * image.width * 72 / width / this.internal.scaleFactor;
9933      }
9934
9935      if (height < 0) {
9936        height = -1 * image.height * 72 / height / this.internal.scaleFactor;
9937      }
9938
9939      if (width === 0) {
9940        width = height * image.width / image.height;
9941      }
9942
9943      if (height === 0) {
9944        height = width * image.height / image.width;
9945      }
9946
9947      return [width, height];
9948    };
9949
9950    var writeImageToPDF = function writeImageToPDF(x, y, width, height, image, rotation) {
9951      var dims = determineWidthAndHeight.call(this, width, height, image),
9952          coord = this.internal.getCoordinateString,
9953          vcoord = this.internal.getVerticalCoordinateString;
9954      var images = getImages.call(this);
9955      width = dims[0];
9956      height = dims[1];
9957      images[image.index] = image;
9958
9959      if (rotation) {
9960        rotation *= Math.PI / 180;
9961        var c = Math.cos(rotation);
9962        var s = Math.sin(rotation); //like in pdf Reference do it 4 digits instead of 2
9963
9964        var f4 = function f4(number) {
9965          return number.toFixed(4);
9966        };
9967
9968        var rotationTransformationMatrix = [f4(c), f4(s), f4(s * -1), f4(c), 0, 0, "cm"];
9969      }
9970
9971      this.internal.write("q"); //Save graphics state
9972
9973      if (rotation) {
9974        this.internal.write([1, "0", "0", 1, coord(x), vcoord(y + height), "cm"].join(" ")); //Translate
9975
9976        this.internal.write(rotationTransformationMatrix.join(" ")); //Rotate
9977
9978        this.internal.write([coord(width), "0", "0", coord(height), "0", "0", "cm"].join(" ")); //Scale
9979      } else {
9980        this.internal.write([coord(width), "0", "0", coord(height), coord(x), vcoord(y + height), "cm"].join(" ")); //Translate and Scale
9981      }
9982
9983      if (this.isAdvancedAPI()) {
9984        // draw image bottom up when in "advanced" API mode
9985        this.internal.write([1, 0, 0, -1, 0, 0, "cm"].join(" "));
9986      }
9987
9988      this.internal.write("/I" + image.index + " Do"); //Paint Image
9989
9990      this.internal.write("Q"); //Restore graphics state
9991    };
9992    /**
9993     * COLOR SPACES
9994     */
9995
9996
9997    var color_spaces = jsPDFAPI.color_spaces = {
9998      DEVICE_RGB: "DeviceRGB",
9999      DEVICE_GRAY: "DeviceGray",
10000      DEVICE_CMYK: "DeviceCMYK",
10001      CAL_GREY: "CalGray",
10002      CAL_RGB: "CalRGB",
10003      LAB: "Lab",
10004      ICC_BASED: "ICCBased",
10005      INDEXED: "Indexed",
10006      PATTERN: "Pattern",
10007      SEPARATION: "Separation",
10008      DEVICE_N: "DeviceN"
10009    };
10010    /**
10011     * DECODE METHODS
10012     */
10013
10014    jsPDFAPI.decode = {
10015      DCT_DECODE: "DCTDecode",
10016      FLATE_DECODE: "FlateDecode",
10017      LZW_DECODE: "LZWDecode",
10018      JPX_DECODE: "JPXDecode",
10019      JBIG2_DECODE: "JBIG2Decode",
10020      ASCII85_DECODE: "ASCII85Decode",
10021      ASCII_HEX_DECODE: "ASCIIHexDecode",
10022      RUN_LENGTH_DECODE: "RunLengthDecode",
10023      CCITT_FAX_DECODE: "CCITTFaxDecode"
10024    };
10025    /**
10026     * IMAGE COMPRESSION TYPES
10027     */
10028
10029    var image_compression = jsPDFAPI.image_compression = {
10030      NONE: "NONE",
10031      FAST: "FAST",
10032      MEDIUM: "MEDIUM",
10033      SLOW: "SLOW"
10034    };
10035    /**
10036     * @name sHashCode
10037     * @function
10038     * @param {string} data
10039     * @returns {string}
10040     */
10041
10042    var sHashCode = jsPDFAPI.__addimage__.sHashCode = function (data) {
10043      var hash = 0,
10044          i,
10045          len;
10046
10047      if (typeof data === "string") {
10048        len = data.length;
10049
10050        for (i = 0; i < len; i++) {
10051          hash = (hash << 5) - hash + data.charCodeAt(i);
10052          hash |= 0; // Convert to 32bit integer
10053        }
10054      } else if (isArrayBufferView(data)) {
10055        len = data.byteLength / 2;
10056
10057        for (i = 0; i < len; i++) {
10058          hash = (hash << 5) - hash + data[i];
10059          hash |= 0; // Convert to 32bit integer
10060        }
10061      }
10062
10063      return hash;
10064    };
10065    /**
10066     * Validates if given String is a valid Base64-String
10067     *
10068     * @name validateStringAsBase64
10069     * @public
10070     * @function
10071     * @param {String} possible Base64-String
10072     *
10073     * @returns {boolean}
10074     */
10075
10076
10077    var validateStringAsBase64 = jsPDFAPI.__addimage__.validateStringAsBase64 = function (possibleBase64String) {
10078      possibleBase64String = possibleBase64String || "";
10079      possibleBase64String.toString().trim();
10080      var result = true;
10081
10082      if (possibleBase64String.length === 0) {
10083        result = false;
10084      }
10085
10086      if (possibleBase64String.length % 4 !== 0) {
10087        result = false;
10088      }
10089
10090      if (/^[A-Za-z0-9+/]+$/.test(possibleBase64String.substr(0, possibleBase64String.length - 2)) === false) {
10091        result = false;
10092      }
10093
10094      if (/^[A-Za-z0-9/][A-Za-z0-9+/]|[A-Za-z0-9+/]=|==$/.test(possibleBase64String.substr(-2)) === false) {
10095        result = false;
10096      }
10097
10098      return result;
10099    };
10100    /**
10101     * Strips out and returns info from a valid base64 data URI
10102     *
10103     * @name extractImageFromDataUrl
10104     * @function
10105     * @param {string} dataUrl a valid data URI of format 'data:[<MIME-type>][;base64],<data>'
10106     * @returns {Array}an Array containing the following
10107     * [0] the complete data URI
10108     * [1] <MIME-type>
10109     * [2] format - the second part of the mime-type i.e 'png' in 'image/png'
10110     * [4] <data>
10111     */
10112
10113
10114    var extractImageFromDataUrl = jsPDFAPI.__addimage__.extractImageFromDataUrl = function (dataUrl) {
10115      dataUrl = dataUrl || "";
10116      var dataUrlParts = dataUrl.split("base64,");
10117      var result = null;
10118
10119      if (dataUrlParts.length === 2) {
10120        var extractedInfo = /^data:(\w*\/\w*);*(charset=(?!charset=)[\w=-]*)*;*$/.exec(dataUrlParts[0]);
10121
10122        if (Array.isArray(extractedInfo)) {
10123          result = {
10124            mimeType: extractedInfo[1],
10125            charset: extractedInfo[2],
10126            data: dataUrlParts[1]
10127          };
10128        }
10129      }
10130
10131      return result;
10132    };
10133    /**
10134     * Check to see if ArrayBuffer is supported
10135     *
10136     * @name supportsArrayBuffer
10137     * @function
10138     * @returns {boolean}
10139     */
10140
10141
10142    var supportsArrayBuffer = jsPDFAPI.__addimage__.supportsArrayBuffer = function () {
10143      return typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined";
10144    };
10145    /**
10146     * Tests supplied object to determine if ArrayBuffer
10147     *
10148     * @name isArrayBuffer
10149     * @function
10150     * @param {Object} object an Object
10151     *
10152     * @returns {boolean}
10153     */
10154
10155
10156    jsPDFAPI.__addimage__.isArrayBuffer = function (object) {
10157      return supportsArrayBuffer() && object instanceof ArrayBuffer;
10158    };
10159    /**
10160     * Tests supplied object to determine if it implements the ArrayBufferView (TypedArray) interface
10161     *
10162     * @name isArrayBufferView
10163     * @function
10164     * @param {Object} object an Object
10165     * @returns {boolean}
10166     */
10167
10168
10169    var isArrayBufferView = jsPDFAPI.__addimage__.isArrayBufferView = function (object) {
10170      return supportsArrayBuffer() && typeof Uint32Array !== "undefined" && (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);
10171    };
10172    /**
10173     * Convert Binary String to ArrayBuffer
10174     *
10175     * @name binaryStringToUint8Array
10176     * @public
10177     * @function
10178     * @param {string} BinaryString with ImageData
10179     * @returns {Uint8Array}
10180     */
10181
10182
10183    var binaryStringToUint8Array = jsPDFAPI.__addimage__.binaryStringToUint8Array = function (binary_string) {
10184      var len = binary_string.length;
10185      var bytes = new Uint8Array(len);
10186
10187      for (var i = 0; i < len; i++) {
10188        bytes[i] = binary_string.charCodeAt(i);
10189      }
10190
10191      return bytes;
10192    };
10193    /**
10194     * Convert the Buffer to a Binary String
10195     *
10196     * @name arrayBufferToBinaryString
10197     * @public
10198     * @function
10199     * @param {ArrayBuffer|ArrayBufferView} ArrayBuffer buffer or bufferView with ImageData
10200     *
10201     * @returns {String}
10202     */
10203
10204
10205    var arrayBufferToBinaryString = jsPDFAPI.__addimage__.arrayBufferToBinaryString = function (buffer) {
10206      var out = ""; // There are calls with both ArrayBuffer and already converted Uint8Array or other BufferView.
10207      // Do not copy the array if input is already an array.
10208
10209      var buf = isArrayBufferView(buffer) ? buffer : new Uint8Array(buffer);
10210
10211      for (var i = 0; i < buf.length; i += ARRAY_APPLY_BATCH) {
10212        // Limit the amount of characters being parsed to prevent overflow.
10213        // Note that while TextDecoder would be faster, it does not have the same
10214        // functionality as fromCharCode with any provided encodings as of 3/2021.
10215        out += String.fromCharCode.apply(null, buf.subarray(i, i + ARRAY_APPLY_BATCH));
10216      }
10217
10218      return out;
10219    };
10220    /**
10221     * Possible parameter for addImage, an RGBA buffer with size.
10222     *
10223     * @typedef {Object} RGBAData
10224     * @property {Uint8ClampedArray} data - Single dimensional array of RGBA values. For example from canvas getImageData.
10225     * @property {number} width - Image width as the data does not carry this information in itself.
10226     * @property {number} height - Image height as the data does not carry this information in itself.
10227     */
10228
10229    /**
10230     * Adds an Image to the PDF.
10231     *
10232     * @name addImage
10233     * @public
10234     * @function
10235     * @param {string|HTMLImageElement|HTMLCanvasElement|Uint8Array|RGBAData} imageData imageData as base64 encoded DataUrl or Image-HTMLElement or Canvas-HTMLElement or object c
10235ontaining RGBA array (like output from canvas.getImageData).
10236     * @param {string} format format of file if filetype-recognition fails or in case of a Canvas-Element needs to be specified (default for Canvas is JPEG), e.g. 'JPEG', 'PNG', 'WEBP'
10237     * @param {number} x x Coordinate (in units declared at inception of PDF document) against left edge of the page
10238     * @param {number} y y Coordinate (in units declared at inception of PDF document) against upper edge of the page
10239     * @param {number} width width of the image (in units declared at inception of PDF document)
10240     * @param {number} height height of the Image (in units declared at inception of PDF document)
10241     * @param {string} alias alias of the image (if used multiple times)
10242     * @param {string} compression compression of the generated JPEG, can have the values 'NONE', 'FAST', 'MEDIUM' and 'SLOW'
10243     * @param {number} rotation rotation of the image in degrees (0-359)
10244     *
10245     * @returns jsPDF
10246     */
10247
10248
10249    jsPDFAPI.addImage = function () {
10250      var imageData, format, x, y, w, h, alias, compression, rotation;
10251      imageData = arguments[0];
10252
10253      if (typeof arguments[1] === "number") {
10254        format = UNKNOWN;
10255        x = arguments[1];
10256        y = arguments[2];
10257        w = arguments[3];
10258        h = arguments[4];
10259        alias = arguments[5];
10260        compression = arguments[6];
10261        rotation = arguments[7];
10262      } else {
10263        format = arguments[1];
10264        x = arguments[2];
10265        y = arguments[3];
10266        w = arguments[4];
10267        h = arguments[5];
10268        alias = arguments[6];
10269        compression = arguments[7];
10270        rotation = arguments[8];
10271      }
10272
10273      if (_typeof(imageData) === "object" && !isDOMElement(imageData) && "imageData" in imageData) {
10274        var options = imageData;
10275        imageData = options.imageData;
10276        format = options.format || format || UNKNOWN;
10277        x = options.x || x || 0;
10278        y = options.y || y || 0;
10279        w = options.w || options.width || w;
10280        h = options.h || options.height || h;
10281        alias = options.alias || alias;
10282        compression = options.compression || compression;
10283        rotation = options.rotation || options.angle || rotation;
10284      } //If compression is not explicitly set, determine if we should use compression
10285
10286
10287      var filter = this.internal.getFilters();
10288
10289      if (compression === undefined && filter.indexOf("FlateEncode") !== -1) {
10290        compression = "SLOW";
10291      }
10292
10293      if (isNaN(x) || isNaN(y)) {
10294        throw new Error("Invalid coordinates passed to jsPDF.addImage");
10295      }
10296
10297      initialize.call(this);
10298      var image = processImageData.call(this, imageData, format, alias, compression);
10299      writeImageToPDF.call(this, x, y, w, h, image, rotation);
10300      return this;
10301    };
10302
10303    var processImageData = function processImageData(imageData, format, alias, compression) {
10304      var result, dataAsBinaryString;
10305
10306      if (typeof imageData === "string" && getImageFileTypeByImageData(imageData) === UNKNOWN) {
10307        imageData = unescape(imageData);
10308        var tmpImageData = convertBase64ToBinaryString(imageData, false);
10309
10310        if (tmpImageData !== "") {
10311          imageData = tmpImageData;
10312        } else {
10313          tmpImageData = jsPDFAPI.loadFile(imageData, true);
10314
10315          if (tmpImageData !== undefined) {
10316            imageData = tmpImageData;
10317          }
10318        }
10319      }
10320
10321      if (isDOMElement(imageData)) {
10322        imageData = getImageDataFromElement(imageData, format);
10323      }
10324
10325      format = getImageFileTypeByImageData(imageData, format);
10326
10327      if (!isImageTypeSupported(format)) {
10328        throw new Error("addImage does not support files of type '" + format + "', please ensure that a plugin for '" + format + "' support is added.");
10329      } // now do the heavy lifting
10330
10331
10332      if (notDefined(alias)) {
10333        alias = generateAliasFromImageData(imageData);
10334      }
10335
10336      result = checkImagesForAlias.call(this, alias);
10337
10338      if (!result) {
10339        if (supportsArrayBuffer()) {
10340          // no need to convert if imageData is already uint8array
10341          if (!(imageData instanceof Uint8Array) && format !== "RGBA") {
10342            dataAsBinaryString = imageData;
10343            imageData = binaryStringToUint8Array(imageData);
10344          }
10345        }
10346
10347        result = this["process" + format.toUpperCase()](imageData, getImageIndex.call(this), alias, checkCompressValue(compression), dataAsBinaryString);
10348      }
10349
10350      if (!result) {
10351        throw new Error("An unknown error occurred whilst processing the image.");
10352      }
10353
10354      return result;
10355    };
10356    /**
10357     * @name convertBase64ToBinaryString
10358     * @function
10359     * @param {string} stringData
10360     * @returns {string} binary string
10361     */
10362
10363
10364    var convertBase64ToBinaryString = jsPDFAPI.__addimage__.convertBase64ToBinaryString = function (stringData, throwError) {
10365      throwError = typeof throwError === "boolean" ? throwError : true;
10366      var base64Info;
10367      var imageData = "";
10368      var rawData;
10369
10370      if (typeof stringData === "string") {
10371        base64Info = extractImageFromDataUrl(stringData);
10372        rawData = base64Info !== null ? base64Info.data : stringData;
10373
10374        try {
10375          imageData = atob(rawData);
10376        } catch (e) {
10377          if (throwError) {
vendor: 70,551 bytes, lines 10378-12564
10378            if (!validateStringAsBase64(rawData)) {
10379              throw new Error("Supplied Data is not a valid base64-String jsPDF.convertBase64ToBinaryString ");
10380            } else {
10381              throw new Error("atob-Error in jsPDF.convertBase64ToBinaryString " + e.message);
10382            }
10383          }
10384        }
10385      }
10386
10387      return imageData;
10388    };
10389    /**
10390     * @name getImageProperties
10391     * @function
10392     * @param {Object} imageData
10393     * @returns {Object}
10394     */
10395
10396
10397    jsPDFAPI.getImageProperties = function (imageData) {
10398      var image;
10399      var tmpImageData = "";
10400      var format;
10401
10402      if (isDOMElement(imageData)) {
10403        imageData = getImageDataFromElement(imageData);
10404      }
10405
10406      if (typeof imageData === "string" && getImageFileTypeByImageData(imageData) === UNKNOWN) {
10407        tmpImageData = convertBase64ToBinaryString(imageData, false);
10408
10409        if (tmpImageData === "") {
10410          tmpImageData = jsPDFAPI.loadFile(imageData) || "";
10411        }
10412
10413        imageData = tmpImageData;
10414      }
10415
10416      format = getImageFileTypeByImageData(imageData);
10417
10418      if (!isImageTypeSupported(format)) {
10419        throw new Error("addImage does not support files of type '" + format + "', please ensure that a plugin for '" + format + "' support is added.");
10420      }
10421
10422      if (supportsArrayBuffer() && !(imageData instanceof Uint8Array)) {
10423        imageData = binaryStringToUint8Array(imageData);
10424      }
10425
10426      image = this["process" + format.toUpperCase()](imageData);
10427
10428      if (!image) {
10429        throw new Error("An unknown error occurred whilst processing the image");
10430      }
10431
10432      image.fileType = format;
10433      return image;
10434    };
10435  })(jsPDF.API);
10436
10437  /**
10438   * @license
10439   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  [email protected]
10440   *
10441   * Licensed under the MIT License.
10442   * http://opensource.org/licenses/mit-license
10443   */
10444
10445  (function (jsPDFAPI) {
10446
10447    var notEmpty = function notEmpty(obj) {
10448      if (typeof obj != "undefined") {
10449        if (obj != "") {
10450          return true;
10451        }
10452      }
10453    };
10454
10455    jsPDF.API.events.push(["addPage", function (addPageData) {
10456      var pageInfo = this.internal.getPageInfo(addPageData.pageNumber);
10457      pageInfo.pageContext.annotations = [];
10458    }]);
10459    jsPDFAPI.events.push(["putPage", function (putPageData) {
10460      var getHorizontalCoordinateString = this.internal.getCoordinateString;
10461      var getVerticalCoordinateString = this.internal.getVerticalCoordinateString;
10462      var pageInfo = this.internal.getPageInfoByObjId(putPageData.objId);
10463      var pageAnnos = putPageData.pageContext.annotations;
10464      var anno, rect, line;
10465      var found = false;
10466
10467      for (var a = 0; a < pageAnnos.length && !found; a++) {
10468        anno = pageAnnos[a];
10469
10470        switch (anno.type) {
10471          case "link":
10472            if (notEmpty(anno.options.url) || notEmpty(anno.options.pageNumber)) {
10473              found = true;
10474            }
10475
10476            break;
10477
10478          case "reference":
10479          case "text":
10480          case "freetext":
10481            found = true;
10482            break;
10483        }
10484      }
10485
10486      if (found == false) {
10487        return;
10488      }
10489
10490      this.internal.write("/Annots [");
10491
10492      for (var i = 0; i < pageAnnos.length; i++) {
10493        anno = pageAnnos[i];
10494        var escape = this.internal.pdfEscape;
10495        var encryptor = this.internal.getEncryptor(putPageData.objId);
10496
10497        switch (anno.type) {
10498          case "reference":
10499            // References to Widget Annotations (for AcroForm Fields)
10500            this.internal.write(" " + anno.object.objId + " 0 R ");
10501            break;
10502
10503          case "text":
10504            // Create a an object for both the text and the popup
10505            var objText = this.internal.newAdditionalObject();
10506            var objPopup = this.internal.newAdditionalObject();
10507            var encryptorText = this.internal.getEncryptor(objText.objId);
10508            var title = anno.title || "Note";
10509            rect = "/Rect [" + getHorizontalCoordinateString(anno.bounds.x) + " " + getVerticalCoordinateString(anno.bounds.y + anno.bounds.h) + " " + getHorizontalCoordinateString(anno.bounds.x + anno.bounds.w) + " " + getVerticalCoordinateString(anno.bounds.y) + "] ";
10510            line = "<</Type /Annot /Subtype /" + "Text" + " " + rect + "/Contents (" + escape(encryptorText(anno.contents)) + ")";
10511            line += " /Popup " + objPopup.objId + " 0 R";
10512            line += " /P " + pageInfo.objId + " 0 R";
10513            line += " /T (" + escape(encryptorText(title)) + ") >>";
10514            objText.content = line;
10515            var parent = objText.objId + " 0 R";
10516            var popoff = 30;
10517            rect = "/Rect [" + getHorizontalCoordinateString(anno.bounds.x + popoff) + " " + getVerticalCoordinateString(anno.bounds.y + anno.bounds.h) + " " + getHorizontalCoordinateString(anno.bounds.x + anno.bounds.w + popoff) + " " + getVerticalCoordinateString(anno.bounds.y) + "] ";
10518            line = "<</Type /Annot /Subtype /" + "Popup" + " " + rect + " /Parent " + parent;
10519
10520            if (anno.open) {
10521              line += " /Open true";
10522            }
10523
10524            line += " >>";
10525            objPopup.content = line;
10526            this.internal.write(objText.objId, "0 R", objPopup.objId, "0 R");
10527            break;
10528
10529          case "freetext":
10530            rect = "/Rect [" + getHorizontalCoordinateString(anno.bounds.x) + " " + getVerticalCoordinateString(anno.bounds.y) + " " + getHorizontalCoordinateString(anno.bounds.x + anno.bounds.w) + " " + getVerticalCoordinateString(anno.bounds.y + anno.bounds.h) + "] ";
10531            var color = anno.color || "#000000";
10532            line = "<</Type /Annot /Subtype /" + "FreeText" + " " + rect + "/Contents (" + escape(encryptor(anno.contents)) + ")";
10533            line += " /DS(font: Helvetica,sans-serif 12.0pt; text-align:left; color:#" + color + ")";
10534            line += " /Border [0 0 0]";
10535            line += " >>";
10536            this.internal.write(line);
10537            break;
10538
10539          case "link":
10540            if (anno.options.name) {
10541              var loc = this.annotations._nameMap[anno.options.name];
10542              anno.options.pageNumber = loc.page;
10543              anno.options.top = loc.y;
10544            } else {
10545              if (!anno.options.top) {
10546                anno.options.top = 0;
10547              }
10548            }
10549
10550            rect = "/Rect [" + anno.finalBounds.x + " " + anno.finalBounds.y + " " + anno.finalBounds.w + " " + anno.finalBounds.h + "] ";
10551            line = "";
10552
10553            if (anno.options.url) {
10554              line = "<</Type /Annot /Subtype /Link " + rect + "/Border [0 0 0] /A <</S /URI /URI (" + escape(encryptor(anno.options.url)) + ") >>";
10555            } else if (anno.options.pageNumber) {
10556              // first page is 0
10557              var info = this.internal.getPageInfo(anno.options.pageNumber);
10558              line = "<</Type /Annot /Subtype /Link " + rect + "/Border [0 0 0] /Dest [" + info.objId + " 0 R";
10559              anno.options.magFactor = anno.options.magFactor || "XYZ";
10560
10561              switch (anno.options.magFactor) {
10562                case "Fit":
10563                  line += " /Fit]";
10564                  break;
10565
10566                case "FitH":
10567                  line += " /FitH " + anno.options.top + "]";
10568                  break;
10569
10570                case "FitV":
10571                  anno.options.left = anno.options.left || 0;
10572                  line += " /FitV " + anno.options.left + "]";
10573                  break;
10574
10575                case "XYZ":
10576                default:
10577                  var top = getVerticalCoordinateString(anno.options.top);
10578                  anno.options.left = anno.options.left || 0; // 0 or null zoom will not change zoom factor
10579
10580                  if (typeof anno.options.zoom === "undefined") {
10581                    anno.options.zoom = 0;
10582                  }
10583
10584                  line += " /XYZ " + anno.options.left + " " + top + " " + anno.options.zoom + "]";
10585                  break;
10586              }
10587            }
10588
10589            if (line != "") {
10590              line += " >>";
10591              this.internal.write(line);
10592            }
10593
10594            break;
10595        }
10596      }
10597
10598      this.internal.write("]");
10599    }]);
10600    /**
10601     * @name createAnnotation
10602     * @function
10603     * @param {Object} options
10604     */
10605
10606    jsPDFAPI.createAnnotation = function (options) {
10607      var pageInfo = this.internal.getCurrentPageInfo();
10608
10609      switch (options.type) {
10610        case "link":
10611          this.link(options.bounds.x, options.bounds.y, options.bounds.w, options.bounds.h, options);
10612          break;
10613
10614        case "text":
10615        case "freetext":
10616          pageInfo.pageContext.annotations.push(options);
10617          break;
10618      }
10619    };
10620    /**
10621     * Create a link
10622     *
10623     * valid options
10624     * <li> pageNumber or url [required]
10625     * <p>If pageNumber is specified, top and zoom may also be specified</p>
10626     * @name link
10627     * @function
10628     * @param {number} x
10629     * @param {number} y
10630     * @param {number} w
10631     * @param {number} h
10632     * @param {Object} options
10633     */
10634
10635
10636    jsPDFAPI.link = function (x, y, w, h, options) {
10637      var pageInfo = this.internal.getCurrentPageInfo();
10638      var getHorizontalCoordinateString = this.internal.getCoordinateString;
10639      var getVerticalCoordinateString = this.internal.getVerticalCoordinateString;
10640      pageInfo.pageContext.annotations.push({
10641        finalBounds: {
10642          x: getHorizontalCoordinateString(x),
10643          y: getVerticalCoordinateString(y),
10644          w: getHorizontalCoordinateString(x + w),
10645          h: getVerticalCoordinateString(y + h)
10646        },
10647        options: options,
10648        type: "link"
10649      });
10650    };
10651    /**
10652     * Currently only supports single line text.
10653     * Returns the width of the text/link
10654     *
10655     * @name textWithLink
10656     * @function
10657     * @param {string} text
10658     * @param {number} x
10659     * @param {number} y
10660     * @param {Object} options
10661     * @returns {number} width the width of the text/link
10662     */
10663
10664
10665    jsPDFAPI.textWithLink = function (text, x, y, options) {
10666      var totalLineWidth = this.getTextWidth(text);
10667      var lineHeight = this.internal.getLineHeight() / this.internal.scaleFactor;
10668      var linkHeight, linkWidth; // Checking if maxWidth option is passed to determine lineWidth and number of lines for each line
10669
10670      if (options.maxWidth !== undefined) {
10671        var maxWidth = options.maxWidth;
10672        linkWidth = maxWidth;
10673        var numOfLines = this.splitTextToSize(text, linkWidth).length;
10674        linkHeight = Math.ceil(lineHeight * numOfLines);
10675      } else {
10676        linkWidth = totalLineWidth;
10677        linkHeight = lineHeight;
10678      }
10679
10680      this.text(text, x, y, options); //TODO We really need the text baseline height to do this correctly.
10681      // Or ability to draw text on top, bottom, center, or baseline.
10682
10683      y += lineHeight * 0.2; //handle x position based on the align option
10684
10685      if (options.align === "center") {
10686        x = x - totalLineWidth / 2; //since starting from center move the x position by half of text width
10687      }
10688
10689      if (options.align === "right") {
10690        x = x - totalLineWidth;
10691      }
10692
10693      this.link(x, y - lineHeight, linkWidth, linkHeight, options);
10694      return totalLineWidth;
10695    }; //TODO move into external library
10696
10697    /**
10698     * @name getTextWidth
10699     * @function
10700     * @param {string} text
10701     * @returns {number} txtWidth
10702     */
10703
10704
10705    jsPDFAPI.getTextWidth = function (text) {
10706      var fontSize = this.internal.getFontSize();
10707      var txtWidth = this.getStringUnitWidth(text) * fontSize / this.internal.scaleFactor;
10708      return txtWidth;
10709    };
10710
10711    return this;
10712  })(jsPDF.API);
10713
10714  /**
10715   * @license
10716   * Copyright (c) 2017 Aras Abbasi
10717   *
10718   * Licensed under the MIT License.
10719   * http://opensource.org/licenses/mit-license
10720   */
10721  /**
10722   * jsPDF arabic parser PlugIn
10723   *
10724   * @name arabic
10725   * @module
10726   */
10727
10728  (function (jsPDFAPI) {
10729    /**
10730     * Arabic shape substitutions: char code => (isolated, final, initial, medial).
10731     * Arabic Substition A
10732     */
10733
10734    var arabicSubstitionA = {
10735      0x0621: [0xfe80],
10736      // ARABIC LETTER HAMZA
10737      0x0622: [0xfe81, 0xfe82],
10738      // ARABIC LETTER ALEF WITH MADDA ABOVE
10739      0x0623: [0xfe83, 0xfe84],
10740      // ARABIC LETTER ALEF WITH HAMZA ABOVE
10741      0x0624: [0xfe85, 0xfe86],
10742      // ARABIC LETTER WAW WITH HAMZA ABOVE
10743      0x0625: [0xfe87, 0xfe88],
10744      // ARABIC LETTER ALEF WITH HAMZA BELOW
10745      0x0626: [0xfe89, 0xfe8a, 0xfe8b, 0xfe8c],
10746      // ARABIC LETTER YEH WITH HAMZA ABOVE
10747      0x0627: [0xfe8d, 0xfe8e],
10748      // ARABIC LETTER ALEF
10749      0x0628: [0xfe8f, 0xfe90, 0xfe91, 0xfe92],
10750      // ARABIC LETTER BEH
10751      0x0629: [0xfe93, 0xfe94],
10752      // ARABIC LETTER TEH MARBUTA
10753      0x062a: [0xfe95, 0xfe96, 0xfe97, 0xfe98],
10754      // ARABIC LETTER TEH
10755      0x062b: [0xfe99, 0xfe9a, 0xfe9b, 0xfe9c],
10756      // ARABIC LETTER THEH
10757      0x062c: [0xfe9d, 0xfe9e, 0xfe9f, 0xfea0],
10758      // ARABIC LETTER JEEM
10759      0x062d: [0xfea1, 0xfea2, 0xfea3, 0xfea4],
10760      // ARABIC LETTER HAH
10761      0x062e: [0xfea5, 0xfea6, 0xfea7, 0xfea8],
10762      // ARABIC LETTER KHAH
10763      0x062f: [0xfea9, 0xfeaa],
10764      // ARABIC LETTER DAL
10765      0x0630: [0xfeab, 0xfeac],
10766      // ARABIC LETTER THAL
10767      0x0631: [0xfead, 0xfeae],
10768      // ARABIC LETTER REH
10769      0x0632: [0xfeaf, 0xfeb0],
10770      // ARABIC LETTER ZAIN
10771      0x0633: [0xfeb1, 0xfeb2, 0xfeb3, 0xfeb4],
10772      // ARABIC LETTER SEEN
10773      0x0634: [0xfeb5, 0xfeb6, 0xfeb7, 0xfeb8],
10774      // ARABIC LETTER SHEEN
10775      0x0635: [0xfeb9, 0xfeba, 0xfebb, 0xfebc],
10776      // ARABIC LETTER SAD
10777      0x0636: [0xfebd, 0xfebe, 0xfebf, 0xfec0],
10778      // ARABIC LETTER DAD
10779      0x0637: [0xfec1, 0xfec2, 0xfec3, 0xfec4],
10780      // ARABIC LETTER TAH
10781      0x0638: [0xfec5, 0xfec6, 0xfec7, 0xfec8],
10782      // ARABIC LETTER ZAH
10783      0x0639: [0xfec9, 0xfeca, 0xfecb, 0xfecc],
10784      // ARABIC LETTER AIN
10785      0x063a: [0xfecd, 0xfece, 0xfecf, 0xfed0],
10786      // ARABIC LETTER GHAIN
10787      0x0641: [0xfed1, 0xfed2, 0xfed3, 0xfed4],
10788      // ARABIC LETTER FEH
10789      0x0642: [0xfed5, 0xfed6, 0xfed7, 0xfed8],
10790      // ARABIC LETTER QAF
10791      0x0643: [0xfed9, 0xfeda, 0xfedb, 0xfedc],
10792      // ARABIC LETTER KAF
10793      0x0644: [0xfedd, 0xfede, 0xfedf, 0xfee0],
10794      // ARABIC LETTER LAM
10795      0x0645: [0xfee1, 0xfee2, 0xfee3, 0xfee4],
10796      // ARABIC LETTER MEEM
10797      0x0646: [0xfee5, 0xfee6, 0xfee7, 0xfee8],
10798      // ARABIC LETTER NOON
10799      0x0647: [0xfee9, 0xfeea, 0xfeeb, 0xfeec],
10800      // ARABIC LETTER HEH
10801      0x0648: [0xfeed, 0xfeee],
10802      // ARABIC LETTER WAW
10803      0x0649: [0xfeef, 0xfef0, 64488, 64489],
10804      // ARABIC LETTER ALEF MAKSURA
10805      0x064a: [0xfef1, 0xfef2, 0xfef3, 0xfef4],
10806      // ARABIC LETTER YEH
10807      0x0671: [0xfb50, 0xfb51],
10808      // ARABIC LETTER ALEF WASLA
10809      0x0677: [0xfbdd],
10810      // ARABIC LETTER U WITH HAMZA ABOVE
10811      0x0679: [0xfb66, 0xfb67, 0xfb68, 0xfb69],
10812      // ARABIC LETTER TTEH
10813      0x067a: [0xfb5e, 0xfb5f, 0xfb60, 0xfb61],
10814      // ARABIC LETTER TTEHEH
10815      0x067b: [0xfb52, 0xfb53, 0xfb54, 0xfb55],
10816      // ARABIC LETTER BEEH
10817      0x067e: [0xfb56, 0xfb57, 0xfb58, 0xfb59],
10818      // ARABIC LETTER PEH
10819      0x067f: [0xfb62, 0xfb63, 0xfb64, 0xfb65],
10820      // ARABIC LETTER TEHEH
10821      0x0680: [0xfb5a, 0xfb5b, 0xfb5c, 0xfb5d],
10822      // ARABIC LETTER BEHEH
10823      0x0683: [0xfb76, 0xfb77, 0xfb78, 0xfb79],
10824      // ARABIC LETTER NYEH
10825      0x0684: [0xfb72, 0xfb73, 0xfb74, 0xfb75],
10826      // ARABIC LETTER DYEH
10827      0x0686: [0xfb7a, 0xfb7b, 0xfb7c, 0xfb7d],
10828      // ARABIC LETTER TCHEH
10829      0x0687: [0xfb7e, 0xfb7f, 0xfb80, 0xfb81],
10830      // ARABIC LETTER TCHEHEH
10831      0x0688: [0xfb88, 0xfb89],
10832      // ARABIC LETTER DDAL
10833      0x068c: [0xfb84, 0xfb85],
10834      // ARABIC LETTER DAHAL
10835      0x068d: [0xfb82, 0xfb83],
10836      // ARABIC LETTER DDAHAL
10837      0x068e: [0xfb86, 0xfb87],
10838      // ARABIC LETTER DUL
10839      0x0691: [0xfb8c, 0xfb8d],
10840      // ARABIC LETTER RREH
10841      0x0698: [0xfb8a, 0xfb8b],
10842      // ARABIC LETTER JEH
10843      0x06a4: [0xfb6a, 0xfb6b, 0xfb6c, 0xfb6d],
10844      // ARABIC LETTER VEH
10845      0x06a6: [0xfb6e, 0xfb6f, 0xfb70, 0xfb71],
10846      // ARABIC LETTER PEHEH
10847      0x06a9: [0xfb8e, 0xfb8f, 0xfb90, 0xfb91],
10848      // ARABIC LETTER KEHEH
10849      0x06ad: [0xfbd3, 0xfbd4, 0xfbd5, 0xfbd6],
10850      // ARABIC LETTER NG
10851      0x06af: [0xfb92, 0xfb93, 0xfb94, 0xfb95],
10852      // ARABIC LETTER GAF
10853      0x06b1: [0xfb9a, 0xfb9b, 0xfb9c, 0xfb9d],
10854      // ARABIC LETTER NGOEH
10855      0x06b3: [0xfb96, 0xfb97, 0xfb98, 0xfb99],
10856      // ARABIC LETTER GUEH
10857      0x06ba: [0xfb9e, 0xfb9f],
10858      // ARABIC LETTER NOON GHUNNA
10859      0x06bb: [0xfba0, 0xfba1, 0xfba2, 0xfba3],
10860      // ARABIC LETTER RNOON
10861      0x06be: [0xfbaa, 0xfbab, 0xfbac, 0xfbad],
10862      // ARABIC LETTER HEH DOACHASHMEE
10863      0x06c0: [0xfba4, 0xfba5],
10864      // ARABIC LETTER HEH WITH YEH ABOVE
10865      0x06c1: [0xfba6, 0xfba7, 0xfba8, 0xfba9],
10866      // ARABIC LETTER HEH GOAL
10867      0x06c5: [0xfbe0, 0xfbe1],
10868      // ARABIC LETTER KIRGHIZ OE
10869      0x06c6: [0xfbd9, 0xfbda],
10870      // ARABIC LETTER OE
10871      0x06c7: [0xfbd7, 0xfbd8],
10872      // ARABIC LETTER U
10873      0x06c8: [0xfbdb, 0xfbdc],
10874      // ARABIC LETTER YU
10875      0x06c9: [0xfbe2, 0xfbe3],
10876      // ARABIC LETTER KIRGHIZ YU
10877      0x06cb: [0xfbde, 0xfbdf],
10878      // ARABIC LETTER VE
10879      0x06cc: [0xfbfc, 0xfbfd, 0xfbfe, 0xfbff],
10880      // ARABIC LETTER FARSI YEH
10881      0x06d0: [0xfbe4, 0xfbe5, 0xfbe6, 0xfbe7],
10882      //ARABIC LETTER E
10883      0x06d2: [0xfbae, 0xfbaf],
10884      // ARABIC LETTER YEH BARREE
10885      0x06d3: [0xfbb0, 0xfbb1] // ARABIC LETTER YEH BARREE WITH HAMZA ABOVE
10886
10887    };
10888    /*
10889      var ligaturesSubstitutionA = {
10890          0xFBEA: []// ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM
10891      };
10892      */
10893
10894    var ligatures = {
10895      0xfedf: {
10896        0xfe82: 0xfef5,
10897        // ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM
10898        0xfe84: 0xfef7,
10899        // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
10900        0xfe88: 0xfef9,
10901        // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM
10902        0xfe8e: 0xfefb // ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
10903
10904      },
10905      0xfee0: {
10906        0xfe82: 0xfef6,
10907        // ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM
10908        0xfe84: 0xfef8,
10909        // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM
10910        0xfe88: 0xfefa,
10911        // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM
10912        0xfe8e: 0xfefc // ARABIC LIGATURE LAM WITH ALEF FINAL FORM
10913
10914      },
10915      0xfe8d: {
10916        0xfedf: {
10917          0xfee0: {
10918            0xfeea: 0xfdf2
10919          }
10920        }
10921      },
10922      // ALLAH
10923      0x0651: {
10924        0x064c: 0xfc5e,
10925        // Shadda + Dammatan
10926        0x064d: 0xfc5f,
10927        // Shadda + Kasratan
10928        0x064e: 0xfc60,
10929        // Shadda + Fatha
10930        0x064f: 0xfc61,
10931        // Shadda + Damma
10932        0x0650: 0xfc62 // Shadda + Kasra
10933
10934      }
10935    };
10936    var arabic_diacritics = {
10937      1612: 64606,
10938      // Shadda + Dammatan
10939      1613: 64607,
10940      // Shadda + Kasratan
10941      1614: 64608,
10942      // Shadda + Fatha
10943      1615: 64609,
10944      // Shadda + Damma
10945      1616: 64610 // Shadda + Kasra
10946
10947    };
10948    var alfletter = [1570, 1571, 1573, 1575];
10949    var noChangeInForm = -1;
10950    var isolatedForm = 0;
10951    var finalForm = 1;
10952    var initialForm = 2;
10953    var medialForm = 3;
10954    jsPDFAPI.__arabicParser__ = {}; //private
10955
10956    var isInArabicSubstitutionA = jsPDFAPI.__arabicParser__.isInArabicSubstitutionA = function (letter) {
10957      return typeof arabicSubstitionA[letter.charCodeAt(0)] !== "undefined";
10958    };
10959
10960    var isArabicLetter = jsPDFAPI.__arabicParser__.isArabicLetter = function (letter) {
10961      return typeof letter === "string" && /^[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]+$/.test(letter);
10962    };
10963
10964    var isArabicEndLetter = jsPDFAPI.__arabicParser__.isArabicEndLetter = function (letter) {
10965      return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length <= 2;
10966    };
10967
10968    var isArabicAlfLetter = jsPDFAPI.__arabicParser__.isArabicAlfLetter = function (letter) {
10969      return isArabicLetter(letter) && alfletter.indexOf(letter.charCodeAt(0)) >= 0;
10970    };
10971
10972    jsPDFAPI.__arabicParser__.arabicLetterHasIsolatedForm = function (letter) {
10973      return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length >= 1;
10974    };
10975
10976    var arabicLetterHasFinalForm = jsPDFAPI.__arabicParser__.arabicLetterHasFinalForm = function (letter) {
10977      return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length >= 2;
10978    };
10979
10980    jsPDFAPI.__arabicParser__.arabicLetterHasInitialForm = function (letter) {
10981      return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length >= 3;
10982    };
10983
10984    var arabicLetterHasMedialForm = jsPDFAPI.__arabicParser__.arabicLetterHasMedialForm = function (letter) {
10985      return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length == 4;
10986    };
10987
10988    var resolveLigatures = jsPDFAPI.__arabicParser__.resolveLigatures = function (letters) {
10989      var i = 0;
10990      var tmpLigatures = ligatures;
10991      var result = "";
10992      var effectedLetters = 0;
10993
10994      for (i = 0; i < letters.length; i += 1) {
10995        if (typeof tmpLigatures[letters.charCodeAt(i)] !== "undefined") {
10996          effectedLetters++;
10997          tmpLigatures = tmpLigatures[letters.charCodeAt(i)];
10998
10999          if (typeof tmpLigatures === "number") {
11000            result += String.fromCharCode(tmpLigatures);
11001            tmpLigatures = ligatures;
11002            effectedLetters = 0;
11003          }
11004
11005          if (i === letters.length - 1) {
11006            tmpLigatures = ligatures;
11007            result += letters.charAt(i - (effectedLetters - 1));
11008            i = i - (effectedLetters - 1);
11009            effectedLetters = 0;
11010          }
11011        } else {
11012          tmpLigatures = ligatures;
11013          result += letters.charAt(i - effectedLetters);
11014          i = i - effectedLetters;
11015          effectedLetters = 0;
11016        }
11017      }
11018
11019      return result;
11020    };
11021
11022    jsPDFAPI.__arabicParser__.isArabicDiacritic = function (letter) {
11023      return letter !== undefined && arabic_diacritics[letter.charCodeAt(0)] !== undefined;
11024    };
11025
11026    var getCorrectForm = jsPDFAPI.__arabicParser__.getCorrectForm = function (currentChar, beforeChar, nextChar) {
11027      if (!isArabicLetter(currentChar)) {
11028        return -1;
11029      }
11030
11031      if (isInArabicSubstitutionA(currentChar) === false) {
11032        return noChangeInForm;
11033      }
11034
11035      if (!arabicLetterHasFinalForm(currentChar) || !isArabicLetter(beforeChar) && !isArabicLetter(nextChar) || !isArabicLetter(nextChar) && isArabicEndLetter(beforeChar) || isArabicEndLetter(currentChar) && !isArabicLetter(beforeChar) || isArabicEndLetter(currentChar) && isArabicAlfLetter(beforeChar) || isArabicEndLetter(currentChar) && isArabicEndLetter(beforeChar)) {
11036        return isolatedForm;
11037      }
11038
11039      if (arabicLetterHasMedialForm(currentChar) && isArabicLetter(beforeChar) && !isArabicEndLetter(beforeChar) && isArabicLetter(nextChar) && arabicLetterHasFinalForm(nextChar)) {
11040        return medialForm;
11041      }
11042
11043      if (isArabicEndLetter(currentChar) || !isArabicLetter(nextChar)) {
11044        return finalForm;
11045      }
11046
11047      return initialForm;
11048    };
11049    /**
11050     * @name processArabic
11051     * @function
11052     * @param {string} text
11053     * @returns {string}
11054     */
11055
11056
11057    var parseArabic = function parseArabic(text) {
11058      text = text || "";
11059      var result = "";
11060      var i = 0;
11061      var j = 0;
11062      var position = 0;
11063      var currentLetter = "";
11064      var prevLetter = "";
11065      var nextLetter = "";
11066      var words = text.split("\\s+");
11067      var newWords = [];
11068
11069      for (i = 0; i < words.length; i += 1) {
11070        newWords.push("");
11071
11072        for (j = 0; j < words[i].length; j += 1) {
11073          currentLetter = words[i][j];
11074          prevLetter = words[i][j - 1];
11075          nextLetter = words[i][j + 1];
11076
11077          if (isArabicLetter(currentLetter)) {
11078            position = getCorrectForm(currentLetter, prevLetter, nextLetter);
11079
11080            if (position !== -1) {
11081              newWords[i] += String.fromCharCode(arabicSubstitionA[currentLetter.charCodeAt(0)][position]);
11082            } else {
11083              newWords[i] += currentLetter;
11084            }
11085          } else {
11086            newWords[i] += currentLetter;
11087          }
11088        }
11089
11090        newWords[i] = resolveLigatures(newWords[i]);
11091      }
11092
11093      result = newWords.join(" ");
11094      return result;
11095    };
11096
11097    var processArabic = jsPDFAPI.__arabicParser__.processArabic = jsPDFAPI.processArabic = function () {
11098      var text = typeof arguments[0] === "string" ? arguments[0] : arguments[0].text;
11099      var tmpText = [];
11100      var result;
11101
11102      if (Array.isArray(text)) {
11103        var i = 0;
11104        tmpText = [];
11105
11106        for (i = 0; i < text.length; i += 1) {
11107          if (Array.isArray(text[i])) {
11108            tmpText.push([parseArabic(text[i][0]), text[i][1], text[i][2]]);
11109          } else {
11110            tmpText.push([parseArabic(text[i])]);
11111          }
11112        }
11113
11114        result = tmpText;
11115      } else {
11116        result = parseArabic(text);
11117      }
11118
11119      if (typeof arguments[0] === "string") {
11120        return result;
11121      } else {
11122        arguments[0].text = result;
11123        return arguments[0];
11124      }
11125    };
11126
11127    jsPDFAPI.events.push(["preProcessText", processArabic]);
11128  })(jsPDF.API);
11129
11130  /** @license
11131   * jsPDF Autoprint Plugin
11132   *
11133   * Licensed under the MIT License.
11134   * http://opensource.org/licenses/mit-license
11135   */
11136  /**
11137   * @name autoprint
11138   * @module
11139   */
11140
11141  (function (jsPDFAPI) {
11142    /**
11143     * Makes the PDF automatically open the print-Dialog when opened in a PDF-viewer.
11144     *
11145     * @name autoPrint
11146     * @function
11147     * @param {Object} options (optional) Set the attribute variant to 'non-conform' (default) or 'javascript' to activate different methods of automatic printing when opening in a PDF-viewer .
11148     * @returns {jsPDF}
11149     * @example
11150     * var doc = new jsPDF();
11151     * doc.text(10, 10, 'This is a test');
11152     * doc.autoPrint({variant: 'non-conform'});
11153     * doc.save('autoprint.pdf');
11154     */
11155
11156    jsPDFAPI.autoPrint = function (options) {
11157
11158      var refAutoPrintTag;
11159      options = options || {};
11160      options.variant = options.variant || "non-conform";
11161
11162      switch (options.variant) {
11163        case "javascript":
11164          //https://github.com/Rob--W/pdf.js/commit/c676ecb5a0f54677b9f3340c3ef2cf42225453bb
11165          this.addJS("print({});");
11166          break;
11167
11168        case "non-conform":
11169        default:
11170          this.internal.events.subscribe("postPutResources", function () {
11171            refAutoPrintTag = this.internal.newObject();
11172            this.internal.out("<<");
11173            this.internal.out("/S /Named");
11174            this.internal.out("/Type /Action");
11175            this.internal.out("/N /Print");
11176            this.internal.out(">>");
11177            this.internal.out("endobj");
11178          });
11179          this.internal.events.subscribe("putCatalog", function () {
11180            this.internal.out("/OpenAction " + refAutoPrintTag + " 0 R");
11181          });
11182          break;
11183      }
11184
11185      return this;
11186    };
11187  })(jsPDF.API);
11188
11189  /**
11190   * @license
11191   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  [email protected]
11192   *
11193   * Licensed under the MIT License.
11194   * http://opensource.org/licenses/mit-license
11195   */
11196  /**
11197   * jsPDF Canvas PlugIn
11198   * This plugin mimics the HTML5 Canvas
11199   *
11200   * The goal is to provide a way for current canvas users to print directly to a PDF.
11201   * @name canvas
11202   * @module
11203   */
11204
11205  (function (jsPDFAPI) {
11206    /**
11207     * @class Canvas
11208     * @classdesc A Canvas Wrapper for jsPDF
11209     */
11210
11211    var Canvas = function Canvas() {
11212      var jsPdfInstance = undefined;
11213      Object.defineProperty(this, "pdf", {
11214        get: function get() {
11215          return jsPdfInstance;
11216        },
11217        set: function set(value) {
11218          jsPdfInstance = value;
11219        }
11220      });
11221      var _width = 150;
11222      /**
11223       * The height property is a positive integer reflecting the height HTML attribute of the <canvas> element interpreted in CSS pixels. When the attribute is not specified, or if it is set to an invalid value, like a negative, the default value of 150 is used.
11224       * This is one of the two properties, the other being width, that controls the size of the canvas.
11225       *
11226       * @name width
11227       */
11228
11229      Object.defineProperty(this, "width", {
11230        get: function get() {
11231          return _width;
11232        },
11233        set: function set(value) {
11234          if (isNaN(value) || Number.isInteger(value) === false || value < 0) {
11235            _width = 150;
11236          } else {
11237            _width = value;
11238          }
11239
11240          if (this.getContext("2d").pageWrapXEnabled) {
11241            this.getContext("2d").pageWrapX = _width + 1;
11242          }
11243        }
11244      });
11245      var _height = 300;
11246      /**
11247       * The width property is a positive integer reflecting the width HTML attribute of the <canvas> element interpreted in CSS pixels. When the attribute is not specified, or if it is set to an invalid value, like a negative, the default value of 300 is used.
11248       * This is one of the two properties, the other being height, that controls the size of the canvas.
11249       *
11250       * @name height
11251       */
11252
11253      Object.defineProperty(this, "height", {
11254        get: function get() {
11255          return _height;
11256        },
11257        set: function set(value) {
11258          if (isNaN(value) || Number.isInteger(value) === false || value < 0) {
11259            _height = 300;
11260          } else {
11261            _height = value;
11262          }
11263
11264          if (this.getContext("2d").pageWrapYEnabled) {
11265            this.getContext("2d").pageWrapY = _height + 1;
11266          }
11267        }
11268      });
11269      var _childNodes = [];
11270      Object.defineProperty(this, "childNodes", {
11271        get: function get() {
11272          return _childNodes;
11273        },
11274        set: function set(value) {
11275          _childNodes = value;
11276        }
11277      });
11278      var _style = {};
11279      Object.defineProperty(this, "style", {
11280        get: function get() {
11281          return _style;
11282        },
11283        set: function set(value) {
11284          _style = value;
11285        }
11286      });
11287      Object.defineProperty(this, "parentNode", {});
11288    };
11289    /**
11290     * The getContext() method returns a drawing context on the canvas, or null if the context identifier is not supported.
11291     *
11292     * @name getContext
11293     * @function
11294     * @param {string} contextType Is a String containing the context identifier defining the drawing context associated to the canvas. Possible value is "2d", leading to the creation of a Context2D object representing a two-dimensional rendering context.
11295     * @param {object} contextAttributes
11296     */
11297
11298
11299    Canvas.prototype.getContext = function (contextType, contextAttributes) {
11300      contextType = contextType || "2d";
11301      var key;
11302
11303      if (contextType !== "2d") {
11304        return null;
11305      }
11306
11307      for (key in contextAttributes) {
11308        if (this.pdf.context2d.hasOwnProperty(key)) {
11309          this.pdf.context2d[key] = contextAttributes[key];
11310        }
11311      }
11312
11313      this.pdf.context2d._canvas = this;
11314      return this.pdf.context2d;
11315    };
11316    /**
11317     * The toDataURL() method is just a stub to throw an error if accidently called.
11318     *
11319     * @name toDataURL
11320     * @function
11321     */
11322
11323
11324    Canvas.prototype.toDataURL = function () {
11325      throw new Error("toDataURL is not implemented.");
11326    };
11327
11328    jsPDFAPI.events.push(["initialized", function () {
11329      this.canvas = new Canvas();
11330      this.canvas.pdf = this;
11331    }]);
11332    return this;
11333  })(jsPDF.API);
11334
11335  /**
11336   * @name cell
11337   * @module
11338   */
11339
11340  (function (jsPDFAPI) {
11341
11342    var NO_MARGINS = {
11343      left: 0,
11344      top: 0,
11345      bottom: 0,
11346      right: 0
11347    };
11348    var px2pt = 0.264583 * 72 / 25.4;
11349    var printingHeaderRow = false;
11350
11351    var _initialize = function _initialize() {
11352      if (typeof this.internal.__cell__ === "undefined") {
11353        this.internal.__cell__ = {};
11354        this.internal.__cell__.padding = 3;
11355        this.internal.__cell__.headerFunction = undefined;
11356        this.internal.__cell__.margins = Object.assign({}, NO_MARGINS);
11357        this.internal.__cell__.margins.width = this.getPageWidth();
11358
11359        _reset.call(this);
11360      }
11361    };
11362
11363    var _reset = function _reset() {
11364      this.internal.__cell__.lastCell = new Cell();
11365      this.internal.__cell__.pages = 1;
11366    };
11367
11368    var Cell = function Cell() {
11369      var _x = arguments[0];
11370      Object.defineProperty(this, "x", {
11371        enumerable: true,
11372        get: function get() {
11373          return _x;
11374        },
11375        set: function set(value) {
11376          _x = value;
11377        }
11378      });
11379      var _y = arguments[1];
11380      Object.defineProperty(this, "y", {
11381        enumerable: true,
11382        get: function get() {
11383          return _y;
11384        },
11385        set: function set(value) {
11386          _y = value;
11387        }
11388      });
11389      var _width = arguments[2];
11390      Object.defineProperty(this, "width", {
11391        enumerable: true,
11392        get: function get() {
11393          return _width;
11394        },
11395        set: function set(value) {
11396          _width = value;
11397        }
11398      });
11399      var _height = arguments[3];
11400      Object.defineProperty(this, "height", {
11401        enumerable: true,
11402        get: function get() {
11403          return _height;
11404        },
11405        set: function set(value) {
11406          _height = value;
11407        }
11408      });
11409      var _text = arguments[4];
11410      Object.defineProperty(this, "text", {
11411        enumerable: true,
11412        get: function get() {
11413          return _text;
11414        },
11415        set: function set(value) {
11416          _text = value;
11417        }
11418      });
11419      var _lineNumber = arguments[5];
11420      Object.defineProperty(this, "lineNumber", {
11421        enumerable: true,
11422        get: function get() {
11423          return _lineNumber;
11424        },
11425        set: function set(value) {
11426          _lineNumber = value;
11427        }
11428      });
11429      var _align = arguments[6];
11430      Object.defineProperty(this, "align", {
11431        enumerable: true,
11432        get: function get() {
11433          return _align;
11434        },
11435        set: function set(value) {
11436          _align = value;
11437        }
11438      });
11439      return this;
11440    };
11441
11442    Cell.prototype.clone = function () {
11443      return new Cell(this.x, this.y, this.width, this.height, this.text, this.lineNumber, this.align);
11444    };
11445
11446    Cell.prototype.toArray = function () {
11447      return [this.x, this.y, this.width, this.height, this.text, this.lineNumber, this.align];
11448    };
11449    /**
11450     * @name setHeaderFunction
11451     * @function
11452     * @param {function} func
11453     */
11454
11455
11456    jsPDFAPI.setHeaderFunction = function (func) {
11457      _initialize.call(this);
11458
11459      this.internal.__cell__.headerFunction = typeof func === "function" ? func : undefined;
11460      return this;
11461    };
11462    /**
11463     * @name getTextDimensions
11464     * @function
11465     * @param {string} txt
11466     * @returns {Object} dimensions
11467     */
11468
11469
11470    jsPDFAPI.getTextDimensions = function (text, options) {
11471      _initialize.call(this);
11472
11473      options = options || {};
11474      var fontSize = options.fontSize || this.getFontSize();
11475      var font = options.font || this.getFont();
11476      var scaleFactor = options.scaleFactor || this.internal.scaleFactor;
11477      var width = 0;
11478      var amountOfLines = 0;
11479      var height = 0;
11480      var tempWidth = 0;
11481      var scope = this;
11482
11483      if (!Array.isArray(text) && typeof text !== "string") {
11484        if (typeof text === "number") {
11485          text = String(text);
11486        } else {
11487          throw new Error("getTextDimensions expects text-parameter to be of type String or type Number or an Array of Strings.");
11488        }
11489      }
11490
11491      var maxWidth = options.maxWidth;
11492
11493      if (maxWidth > 0) {
11494        if (typeof text === "string") {
11495          text = this.splitTextToSize(text, maxWidth);
11496        } else if (Object.prototype.toString.call(text) === "[object Array]") {
11497          text = text.reduce(function (acc, textLine) {
11498            return acc.concat(scope.splitTextToSize(textLine, maxWidth));
11499          }, []);
11500        }
11501      } else {
11502        // Without the else clause, it will not work if you do not pass along maxWidth
11503        text = Array.isArray(text) ? text : [text];
11504      }
11505
11506      for (var i = 0; i < text.length; i++) {
11507        tempWidth = this.getStringUnitWidth(text[i], {
11508          font: font
11509        }) * fontSize;
11510
11511        if (width < tempWidth) {
11512          width = tempWidth;
11513        }
11514      }
11515
11516      if (width !== 0) {
11517        amountOfLines = text.length;
11518      }
11519
11520      width = width / scaleFactor;
11521      height = Math.max((amountOfLines * fontSize * this.getLineHeightFactor() - fontSize * (this.getLineHeightFactor() - 1)) / scaleFactor, 0);
11522      return {
11523        w: width,
11524        h: height
11525      };
11526    };
11527    /**
11528     * @name cellAddPage
11529     * @function
11530     */
11531
11532
11533    jsPDFAPI.cellAddPage = function () {
11534      _initialize.call(this);
11535
11536      this.addPage();
11537      var margins = this.internal.__cell__.margins || NO_MARGINS;
11538      this.internal.__cell__.lastCell = new Cell(margins.left, margins.top, undefined, undefined);
11539      this.internal.__cell__.pages += 1;
11540      return this;
11541    };
11542    /**
11543     * @name cell
11544     * @function
11545     * @param {number} x
11546     * @param {number} y
11547     * @param {number} width
11548     * @param {number} height
11549     * @param {string} text
11550     * @param {number} lineNumber lineNumber
11551     * @param {string} align
11552     * @return {jsPDF} jsPDF-instance
11553     */
11554
11555
11556    var cell = jsPDFAPI.cell = function () {
11557      var currentCell;
11558
11559      if (arguments[0] instanceof Cell) {
11560        currentCell = arguments[0];
11561      } else {
11562        currentCell = new Cell(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
11563      }
11564
11565      _initialize.call(this);
11566
11567      var lastCell = this.internal.__cell__.lastCell;
11568      var padding = this.internal.__cell__.padding;
11569      var margins = this.internal.__cell__.margins || NO_MARGINS;
11570      var tableHeaderRow = this.internal.__cell__.tableHeaderRow;
11571      var printHeaders = this.internal.__cell__.printHeaders; // If this is not the first cell, we must change its position
11572
11573      if (typeof lastCell.lineNumber !== "undefined") {
11574        if (lastCell.lineNumber === currentCell.lineNumber) {
11575          //Same line
11576          currentCell.x = (lastCell.x || 0) + (lastCell.width || 0);
11577          currentCell.y = lastCell.y || 0;
11578        } else {
11579          //New line
11580          if (lastCell.y + lastCell.height + currentCell.height + margins.bottom > this.getPageHeight()) {
11581            this.cellAddPage();
11582            currentCell.y = margins.top;
11583
11584            if (printHeaders && tableHeaderRow) {
11585              this.printHeaderRow(currentCell.lineNumber, true);
11586              currentCell.y += tableHeaderRow[0].height;
11587            }
11588          } else {
11589            currentCell.y = lastCell.y + lastCell.height || currentCell.y;
11590          }
11591        }
11592      }
11593
11594      if (typeof currentCell.text[0] !== "undefined") {
11595        this.rect(currentCell.x, currentCell.y, currentCell.width, currentCell.height, printingHeaderRow === true ? "FD" : undefined);
11596
11597        if (currentCell.align === "right") {
11598          this.text(currentCell.text, currentCell.x + currentCell.width - padding, currentCell.y + padding, {
11599            align: "right",
11600            baseline: "top"
11601          });
11602        } else if (currentCell.align === "center") {
11603          this.text(currentCell.text, currentCell.x + currentCell.width / 2, currentCell.y + padding, {
11604            align: "center",
11605            baseline: "top",
11606            maxWidth: currentCell.width - padding - padding
11607          });
11608        } else {
11609          this.text(currentCell.text, currentCell.x + padding, currentCell.y + padding, {
11610            align: "left",
11611            baseline: "top",
11612            maxWidth: currentCell.width - padding - padding
11613          });
11614        }
11615      }
11616
11617      this.internal.__cell__.lastCell = currentCell;
11618      return this;
11619    };
11620    /**
11621       * Create a table from a set of data.
11622       * @name table
11623       * @function
11624       * @param {Integer} [x] : left-position for top-left corner of table
11625       * @param {Integer} [y] top-position for top-left corner of table
11626       * @param {Object[]} [data] An array of objects containing key-value pairs corresponding to a row of data.
11627       * @param {String[]} [headers] Omit or null to auto-generate headers at a performance cost
11628        * @param {Object} [config.printHeaders] True to print column headers at the top of every page
11629       * @param {Object} [config.autoSize] True to dynamically set the column widths to match the widest cell value
11630       * @param {Object} [config.margins] margin values for left, top, bottom, and width
11631       * @param {Object} [config.fontSize] Integer fontSize to use (optional)
11632       * @param {Object} [config.padding] cell-padding in pt to use (optional)
11633       * @param {Object} [config.headerBackgroundColor] default is #c8c8c8 (optional)
11634       * @param {Object} [config.headerTextColor] default is #000 (optional)
11635       * @param {Object} [config.rowStart] callback to handle before print each row (optional)
11636       * @param {Object} [config.cellStart] callback to handle before print each cell (optional)
11637       * @returns {jsPDF} jsPDF-instance
11638       */
11639
11640
11641    jsPDFAPI.table = function (x, y, data, headers, config) {
11642      _initialize.call(this);
11643
11644      if (!data) {
11645        throw new Error("No data for PDF table.");
11646      }
11647
11648      config = config || {};
11649      var headerNames = [],
11650          headerLabels = [],
11651          headerAligns = [],
11652          i,
11653          columnMatrix = {},
11654          columnWidths = {},
11655          column,
11656          columnMinWidths = [],
11657          j,
11658          tableHeaderConfigs = [],
11659          //set up defaults. If a value is provided in config, defaults will be overwritten:
11660      autoSize = config.autoSize || false,
11661          printHeaders = config.printHeaders === false ? false : true,
11662          fontSize = config.css && typeof config.css["font-size"] !== "undefined" ? config.css["font-size"] * 16 : config.fontSize || 12,
11663          margins = config.margins || Object.assign({
11664        width: this.getPageWidth()
11665      }, NO_MARGINS),
11666          padding = typeof config.padding === "number" ? config.padding : 3,
11667          headerBackgroundColor = config.headerBackgroundColor || "#c8c8c8",
11668          headerTextColor = config.headerTextColor || "#000";
11669
11670      _reset.call(this);
11671
11672      this.internal.__cell__.printHeaders = printHeaders;
11673      this.internal.__cell__.margins = margins;
11674      this.internal.__cell__.table_font_size = fontSize;
11675      this.internal.__cell__.padding = padding;
11676      this.internal.__cell__.headerBackgroundColor = headerBackgroundColor;
11677      this.internal.__cell__.headerTextColor = headerTextColor;
11678      this.setFontSize(fontSize); // Set header values
11679
11680      if (headers === undefined || headers === null) {
11681        // No headers defined so we derive from data
11682        headerNames = Object.keys(data[0]);
11683        headerLabels = headerNames;
11684        headerAligns = headerNames.map(function () {
11685          return "left";
11686        });
11687      } else if (Array.isArray(headers) && _typeof(headers[0]) === "object") {
11688        headerNames = headers.map(function (header) {
11689          return header.name;
11690        });
11691        headerLabels = headers.map(function (header) {
11692          return header.prompt || header.name || "";
11693        });
11694        headerAligns = headers.map(function (header) {
11695          return header.align || "left";
11696        }); // Split header configs into names and prompts
11697
11698        for (i = 0; i < headers.length; i += 1) {
11699          columnWidths[headers[i].name] = headers[i].width * px2pt;
11700        }
11701      } else if (Array.isArray(headers) && typeof headers[0] === "string") {
11702        headerNames = headers;
11703        headerLabels = headerNames;
11704        headerAligns = headerNames.map(function () {
11705          return "left";
11706        });
11707      }
11708
11709      if (autoSize || Array.isArray(headers) && typeof headers[0] === "string") {
11710        var headerName;
11711
11712        for (i = 0; i < headerNames.length; i += 1) {
11713          headerName = headerNames[i]; // Create a matrix of columns e.g., {column_title: [row1_Record, row2_Record]}
11714
11715          columnMatrix[headerName] = data.map(function (rec) {
11716            return rec[headerName];
11717          }); // get header width
11718
11719          this.setFont(undefined, "bold");
11720          columnMinWidths.push(this.getTextDimensions(headerLabels[i], {
11721            fontSize: this.internal.__cell__.table_font_size,
11722            scaleFactor: this.internal.scaleFactor
11723          }).w);
11724          column = columnMatrix[headerName]; // get cell widths
11725
11726          this.setFont(undefined, "normal");
11727
11728          for (j = 0; j < column.length; j += 1) {
11729            columnMinWidths.push(this.getTextDimensions(column[j], {
11730              fontSize: this.internal.__cell__.table_font_size,
11731              scaleFactor: this.internal.scaleFactor
11732            }).w);
11733          } // get final column width
11734
11735
11736          columnWidths[headerName] = Math.max.apply(null, columnMinWidths) + padding + padding; //have to reset
11737
11738          columnMinWidths = [];
11739        }
11740      } // -- Construct the table
11741
11742
11743      if (printHeaders) {
11744        var row = {};
11745
11746        for (i = 0; i < headerNames.length; i += 1) {
11747          row[headerNames[i]] = {};
11748          row[headerNames[i]].text = headerLabels[i];
11749          row[headerNames[i]].align = headerAligns[i];
11750        }
11751
11752        var rowHeight = calculateLineHeight.call(this, row, columnWidths); // Construct the header row
11753
11754        tableHeaderConfigs = headerNames.map(function (value) {
11755          return new Cell(x, y, columnWidths[value], rowHeight, row[value].text, undefined, row[value].align);
11756        }); // Store the table header config
11757
11758        this.setTableHeaderRow(tableHeaderConfigs); // Print the header for the start of the table
11759
11760        this.printHeaderRow(1, false);
11761      } // Construct the data rows
11762
11763
11764      var align = headers.reduce(function (pv, cv) {
11765        pv[cv.name] = cv.align;
11766        return pv;
11767      }, {});
11768
11769      for (i = 0; i < data.length; i += 1) {
11770        if ("rowStart" in config && config.rowStart instanceof Function) {
11771          config.rowStart({
11772            row: i,
11773            data: data[i]
11774          }, this);
11775        }
11776
11777        var lineHeight = calculateLineHeight.call(this, data[i], columnWidths);
11778
11779        for (j = 0; j < headerNames.length; j += 1) {
11780          var cellData = data[i][headerNames[j]];
11781
11782          if ("cellStart" in config && config.cellStart instanceof Function) {
11783            config.cellStart({
11784              row: i,
11785              col: j,
11786              data: cellData
11787            }, this);
11788          }
11789
11790          cell.call(this, new Cell(x, y, columnWidths[headerNames[j]], lineHeight, cellData, i + 2, align[headerNames[j]]));
11791        }
11792      }
11793
11794      this.internal.__cell__.table_x = x;
11795      this.internal.__cell__.table_y = y;
11796      return this;
11797    };
11798    /**
11799     * Calculate the height for containing the highest column
11800     *
11801     * @name calculateLineHeight
11802     * @function
11803     * @param {Object[]} model is the line of data we want to calculate the height of
11804     * @param {Integer[]} columnWidths is size of each column
11805     * @returns {number} lineHeight
11806     * @private
11807     */
11808
11809
11810    var calculateLineHeight = function calculateLineHeight(model, columnWidths) {
11811      var padding = this.internal.__cell__.padding;
11812      var fontSize = this.internal.__cell__.table_font_size;
11813      var scaleFactor = this.internal.scaleFactor;
11814      return Object.keys(model).map(function (key) {
11815        var value = model[key];
11816        return this.splitTextToSize(value.hasOwnProperty("text") ? value.text : value, columnWidths[key] - padding - padding);
11817      }, this).map(function (value) {
11818        return this.getLineHeightFactor() * value.length * fontSize / scaleFactor + padding + padding;
11819      }, this).reduce(function (pv, cv) {
11820        return Math.max(pv, cv);
11821      }, 0);
11822    };
11823    /**
11824     * Store the config for outputting a table header
11825     *
11826     * @name setTableHeaderRow
11827     * @function
11828     * @param {Object[]} config
11829     * An array of cell configs that would define a header row: Each config matches the config used by jsPDFAPI.cell
11830     * except the lineNumber parameter is excluded
11831     */
11832
11833
11834    jsPDFAPI.setTableHeaderRow = function (config) {
11835      _initialize.call(this);
11836
11837      this.internal.__cell__.tableHeaderRow = config;
11838    };
11839    /**
11840     * Output the store header row
11841     *
11842     * @name printHeaderRow
11843     * @function
11844     * @param {number} lineNumber The line number to output the header at
11845     * @param {boolean} new_page
11846     */
11847
11848
11849    jsPDFAPI.printHeaderRow = function (lineNumber, new_page) {
11850      _initialize.call(this);
11851
11852      if (!this.internal.__cell__.tableHeaderRow) {
11853        throw new Error("Property tableHeaderRow does not exist.");
11854      }
11855
11856      var tableHeaderCell;
11857      printingHeaderRow = true;
11858
11859      if (typeof this.internal.__cell__.headerFunction === "function") {
11860        var position = this.internal.__cell__.headerFunction(this, this.internal.__cell__.pages);
11861
11862        this.internal.__cell__.lastCell = new Cell(position[0], position[1], position[2], position[3], undefined, -1);
11863      }
11864
11865      this.setFont(undefined, "bold");
11866      var tempHeaderConf = [];
11867
11868      for (var i = 0; i < this.internal.__cell__.tableHeaderRow.length; i += 1) {
11869        tableHeaderCell = this.internal.__cell__.tableHeaderRow[i].clone();
11870
11871        if (new_page) {
11872          tableHeaderCell.y = this.internal.__cell__.margins.top || 0;
11873          tempHeaderConf.push(tableHeaderCell);
11874        }
11875
11876        tableHeaderCell.lineNumber = lineNumber;
11877        var currentTextColor = this.getTextColor();
11878        this.setTextColor(this.internal.__cell__.headerTextColor);
11879        this.setFillColor(this.internal.__cell__.headerBackgroundColor);
11880        cell.call(this, tableHeaderCell);
11881        this.setTextColor(currentTextColor);
11882      }
11883
11884      if (tempHeaderConf.length > 0) {
11885        this.setTableHeaderRow(tempHeaderConf);
11886      }
11887
11888      this.setFont(undefined, "normal");
11889      printingHeaderRow = false;
11890    };
11891  })(jsPDF.API);
11892
11893  function toLookup(arr) {
11894    return arr.reduce(function (lookup, name, index) {
11895      lookup[name] = index;
11896      return lookup;
11897    }, {});
11898  }
11899
11900  var fontStyleOrder = {
11901    italic: ["italic", "oblique", "normal"],
11902    oblique: ["oblique", "italic", "normal"],
11903    normal: ["normal", "oblique", "italic"]
11904  };
11905  var fontStretchOrder = ["ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "normal", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded"]; // For a given font-stretch value, we need to know where to start our search
11906  // from in the fontStretchOrder list.
11907
11908  var fontStretchLookup = toLookup(fontStretchOrder);
11909  var fontWeights = [100, 200, 300, 400, 500, 600, 700, 800, 900];
11910  var fontWeightsLookup = toLookup(fontWeights);
11911
11912  function normalizeFontStretch(stretch) {
11913    stretch = stretch || "normal";
11914    return typeof fontStretchLookup[stretch] === "number" ? stretch : "normal";
11915  }
11916
11917  function normalizeFontStyle(style) {
11918    style = style || "normal";
11919    return fontStyleOrder[style] ? style : "normal";
11920  }
11921
11922  function normalizeFontWeight(weight) {
11923    if (!weight) {
11924      return 400;
11925    }
11926
11927    if (typeof weight === "number") {
11928      // Ignore values which aren't valid font-weights.
11929      return weight >= 100 && weight <= 900 && weight % 100 === 0 ? weight : 400;
11930    }
11931
11932    if (/^\d00$/.test(weight)) {
11933      return parseInt(weight);
11934    }
11935
11936    switch (weight) {
11937      case "bold":
11938        return 700;
11939
11940      case "normal":
11941      default:
11942        return 400;
11943    }
11944  }
11945
11946  function normalizeFontFace(fontFace) {
11947    var family = fontFace.family.replace(/"|'/g, "").toLowerCase();
11948    var style = normalizeFontStyle(fontFace.style);
11949    var weight = normalizeFontWeight(fontFace.weight);
11950    var stretch = normalizeFontStretch(fontFace.stretch);
11951    return {
11952      family: family,
11953      style: style,
11954      weight: weight,
11955      stretch: stretch,
11956      src: fontFace.src || [],
11957      // The ref property maps this font-face to the font
11958      // added by the .addFont() method.
11959      ref: fontFace.ref || {
11960        name: family,
11961        style: [stretch, style, weight].join(" ")
11962      }
11963    };
11964  }
11965  /**
11966   * Turns a list of font-faces into a map, for easier lookup when resolving
11967   * fonts.
11968   * @private
11969   */
11970
11971  function buildFontFaceMap(fontFaces) {
11972    var map = {};
11973
11974    for (var i = 0; i < fontFaces.length; ++i) {
11975      var normalized = normalizeFontFace(fontFaces[i]);
11976      var name = normalized.family;
11977      var stretch = normalized.stretch;
11978      var style = normalized.style;
11979      var weight = normalized.weight;
11980      map[name] = map[name] || {};
11981      map[name][stretch] = map[name][stretch] || {};
11982      map[name][stretch][style] = map[name][stretch][style] || {};
11983      map[name][stretch][style][weight] = normalized;
11984    }
11985
11986    return map;
11987  }
11988  /**
11989   * Searches a map of stretches, weights, etc. in the given direction and
11990   * then, if no match has been found, in the opposite directions.
11991   *
11992   * @param {Object.<string, any>} matchingSet A map of the various font variations.
11993   * @param {any[]} order The order of the different variations
11994   * @param {number} pivot The starting point of the search in the order list.
11995   * @param {number} dir The initial direction of the search (desc = -1, asc = 1)
11996   * @private
11997   */
11998
11999  function searchFromPivot(matchingSet, order, pivot, dir) {
12000    var i;
12001
12002    for (i = pivot; i >= 0 && i < order.length; i += dir) {
12003      if (matchingSet[order[i]]) {
12004        return matchingSet[order[i]];
12005      }
12006    }
12007
12008    for (i = pivot; i >= 0 && i < order.length; i -= dir) {
12009      if (matchingSet[order[i]]) {
12010        return matchingSet[order[i]];
12011      }
12012    }
12013  }
12014
12015  function resolveFontStretch(stretch, matchingSet) {
12016    if (matchingSet[stretch]) {
12017      return matchingSet[stretch];
12018    }
12019
12020    var pivot = fontStretchLookup[stretch]; // If the font-stretch value is normal or more condensed, we want to
12021    // start with a descending search, otherwise we should do ascending.
12022
12023    var dir = pivot <= fontStretchLookup["normal"] ? -1 : 1;
12024    var match = searchFromPivot(matchingSet, fontStretchOrder, pivot, dir);
12025
12026    if (!match) {
12027      // Since a font-family cannot exist without having at least one stretch value
12028      // we should never reach this point.
12029      throw new Error("Could not find a matching font-stretch value for " + stretch);
12030    }
12031
12032    return match;
12033  }
12034
12035  function resolveFontStyle(fontStyle, matchingSet) {
12036    if (matchingSet[fontStyle]) {
12037      return matchingSet[fontStyle];
12038    }
12039
12040    var ordering = fontStyleOrder[fontStyle];
12041
12042    for (var i = 0; i < ordering.length; ++i) {
12043      if (matchingSet[ordering[i]]) {
12044        return matchingSet[ordering[i]];
12045      }
12046    } // Since a font-family cannot exist without having at least one style value
12047    // we should never reach this point.
12048
12049
12050    throw new Error("Could not find a matching font-style for " + fontStyle);
12051  }
12052
12053  function resolveFontWeight(weight, matchingSet) {
12054    if (matchingSet[weight]) {
12055      return matchingSet[weight];
12056    }
12057
12058    if (weight === 400 && matchingSet[500]) {
12059      return matchingSet[500];
12060    }
12061
12062    if (weight === 500 && matchingSet[400]) {
12063      return matchingSet[400];
12064    }
12065
12066    var pivot = fontWeightsLookup[weight]; // If the font-stretch value is normal or more condensed, we want to
12067    // start with a descending search, otherwise we should do ascending.
12068
12069    var dir = weight < 400 ? -1 : 1;
12070    var match = searchFromPivot(matchingSet, fontWeights, pivot, dir);
12071
12072    if (!match) {
12073      // Since a font-family cannot exist without having at least one stretch value
12074      // we should never reach this point.
12075      throw new Error("Could not find a matching font-weight for value " + weight);
12076    }
12077
12078    return match;
12079  }
12080
12081  var defaultGenericFontFamilies = {
12082    "sans-serif": "helvetica",
12083    fixed: "courier",
12084    monospace: "courier",
12085    terminal: "courier",
12086    cursive: "times",
12087    fantasy: "times",
12088    serif: "times"
12089  };
12090  var systemFonts = {
12091    caption: "times",
12092    icon: "times",
12093    menu: "times",
12094    "message-box": "times",
12095    "small-caption": "times",
12096    "status-bar": "times"
12097  };
12098
12099  function ruleToString(rule) {
12100    return [rule.stretch, rule.style, rule.weight, rule.family].join(" ");
12101  }
12102
12103  function resolveFontFace(fontFaceMap, rules, opts) {
12104    opts = opts || {};
12105    var defaultFontFamily = opts.defaultFontFamily || "times";
12106    var genericFontFamilies = Object.assign({}, defaultGenericFontFamilies, opts.genericFontFamilies || {});
12107    var rule = null;
12108    var matches = null;
12109
12110    for (var i = 0; i < rules.length; ++i) {
12111      rule = normalizeFontFace(rules[i]);
12112
12113      if (genericFontFamilies[rule.family]) {
12114        rule.family = genericFontFamilies[rule.family];
12115      }
12116
12117      if (fontFaceMap.hasOwnProperty(rule.family)) {
12118        matches = fontFaceMap[rule.family];
12119        break;
12120      }
12121    } // Always fallback to a known font family.
12122
12123
12124    matches = matches || fontFaceMap[defaultFontFamily];
12125
12126    if (!matches) {
12127      // At this point we should definitiely have a font family, but if we
12128      // don't there is something wrong with our configuration
12129      throw new Error("Could not find a font-family for the rule '" + ruleToString(rule) + "' and default family '" + defaultFontFamily + "'.");
12130    }
12131
12132    matches = resolveFontStretch(rule.stretch, matches);
12133    matches = resolveFontStyle(rule.style, matches);
12134    matches = resolveFontWeight(rule.weight, matches);
12135
12136    if (!matches) {
12137      // We should've fount
12138      throw new Error("Failed to resolve a font for the rule '" + ruleToString(rule) + "'.");
12139    }
12140
12141    return matches;
12142  }
12143
12144  function eatWhiteSpace(input) {
12145    return input.trimLeft();
12146  }
12147
12148  function parseQuotedFontFamily(input, quote) {
12149    var index = 0;
12150
12151    while (index < input.length) {
12152      var current = input.charAt(index);
12153
12154      if (current === quote) {
12155        return [input.substring(0, index), input.substring(index + 1)];
12156      }
12157
12158      index += 1;
12159    } // Unexpected end of input
12160
12161
12162    return null;
12163  }
12164
12165  function parseNonQuotedFontFamily(input) {
12166    // It implements part of the identifier parser here: https://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
12167    //
12168    // NOTE: This parser pretty much ignores escaped identifiers and that there is a thing called unicode.
12169    //
12170    // Breakdown of regexp:
12171    // -[a-z_]     - when identifier starts with a hyphen, you're not allowed to have another hyphen or a digit
12172    // [a-z_]      - allow a-z and underscore at beginning of input
12173    // [a-z0-9_-]* - after that, anything goes
12174    var match = input.match(/^(-[a-z_]|[a-z_])[a-z0-9_-]*/i); // non quoted value contains illegal characters
12175
12176    if (match === null) {
12177      return null;
12178    }
12179
12180    return [match[0], input.substring(match[0].length)];
12181  }
12182
12183  var defaultFont = ["times"];
12184  function parseFontFamily(input) {
12185    var result = [];
12186    var ch, parsed;
12187    var remaining = input.trim();
12188
12189    if (remaining === "") {
12190      return defaultFont;
12191    }
12192
12193    if (remaining in systemFonts) {
12194      return [systemFonts[remaining]];
12195    }
12196
12197    while (remaining !== "") {
12198      parsed = null;
12199      remaining = eatWhiteSpace(remaining);
12200      ch = remaining.charAt(0);
12201
12202      switch (ch) {
12203        case '"':
12204        case "'":
12205          parsed = parseQuotedFontFamily(remaining.substring(1), ch);
12206          break;
12207
12208        default:
12209          parsed = parseNonQuotedFontFamily(remaining);
12210          break;
12211      }
12212
12213      if (parsed === null) {
12214        return defaultFont;
12215      }
12216
12217      result.push(parsed[0]);
12218      remaining = eatWhiteSpace(parsed[1]); // We expect end of input or a comma separator here
12219
12220      if (remaining !== "" && remaining.charAt(0) !== ",") {
12221        return defaultFont;
12222      }
12223
12224      remaining = remaining.replace(/^,/, "");
12225    }
12226
12227    return result;
12228  }
12229
12230  /**
12231   * This plugin mimics the HTML5 CanvasRenderingContext2D.
12232   *
12233   * The goal is to provide a way for current canvas implementations to print directly to a PDF.
12234   *
12235   * @name context2d
12236   * @module
12237   */
12238
12239  (function (jsPDFAPI) {
12240
12241    var ContextLayer = function ContextLayer(ctx) {
12242      ctx = ctx || {};
12243      this.isStrokeTransparent = ctx.isStrokeTransparent || false;
12244      this.strokeOpacity = ctx.strokeOpacity || 1;
12245      this.strokeStyle = ctx.strokeStyle || "#000000";
12246      this.fillStyle = ctx.fillStyle || "#000000";
12247      this.isFillTransparent = ctx.isFillTransparent || false;
12248      this.fillOpacity = ctx.fillOpacity || 1;
12249      this.font = ctx.font || "10px sans-serif";
12250      this.textBaseline = ctx.textBaseline || "alphabetic";
12251      this.textAlign = ctx.textAlign || "left";
12252      this.lineWidth = ctx.lineWidth || 1;
12253      this.lineJoin = ctx.lineJoin || "miter";
12254      this.lineCap = ctx.lineCap || "butt";
12255      this.path = ctx.path || [];
12256      this.transform = typeof ctx.transform !== "undefined" ? ctx.transform.clone() : new Matrix();
12257      this.globalCompositeOperation = ctx.globalCompositeOperation || "normal";
12258      this.globalAlpha = ctx.globalAlpha || 1.0;
12259      this.clip_path = ctx.clip_path || [];
12260      this.currentPoint = ctx.currentPoint || new Point();
12261      this.miterLimit = ctx.miterLimit || 10.0;
12262      this.lastPoint = ctx.lastPoint || new Point();
12263      this.lineDashOffset = ctx.lineDashOffset || 0.0;
12264      this.lineDash = ctx.lineDash || [];
12265      this.margin = ctx.margin || [0, 0, 0, 0];
12266      this.prevPageLastElemOffset = ctx.prevPageLastElemOffset || 0;
12267      this.ignoreClearRect = typeof ctx.ignoreClearRect === "boolean" ? ctx.ignoreClearRect : true;
12268      return this;
12269    }; //stub
12270
12271
12272    var f2, getHorizontalCoordinateString, getVerticalCoordinateString, getHorizontalCoordinate, getVerticalCoordinate, Point, Rectangle, Matrix, _ctx;
12273
12274    jsPDFAPI.events.push(["initialized", function () {
12275      this.context2d = new Context2D(this);
12276      f2 = this.internal.f2;
12277      getHorizontalCoordinateString = this.internal.getCoordinateString;
12278      getVerticalCoordinateString = this.internal.getVerticalCoordinateString;
12279      getHorizontalCoordinate = this.internal.getHorizontalCoordinate;
12280      getVerticalCoordinate = this.internal.getVerticalCoordinate;
12281      Point = this.internal.Point;
12282      Rectangle = this.internal.Rectangle;
12283      Matrix = this.internal.Matrix;
12284      _ctx = new ContextLayer();
12285    }]);
12286
12287    var Context2D = function Context2D(pdf) {
12288      Object.defineProperty(this, "canvas", {
12289        get: function get() {
12290          return {
12291            parentNode: false,
12292            style: false
12293          };
12294        }
12295      });
12296      var _pdf = pdf;
12297      Object.defineProperty(this, "pdf", {
12298        get: function get() {
12299          return _pdf;
12300        }
12301      });
12302      var _pageWrapXEnabled = false;
12303      /**
12304       * @name pageWrapXEnabled
12305       * @type {boolean}
12306       * @default false
12307       */
12308
12309      Object.defineProperty(this, "pageWrapXEnabled", {
12310        get: function get() {
12311          return _pageWrapXEnabled;
12312        },
12313        set: function set(value) {
12314          _pageWrapXEnabled = Boolean(value);
12315        }
12316      });
12317      var _pageWrapYEnabled = false;
12318      /**
12319       * @name pageWrapYEnabled
12320       * @type {boolean}
12321       * @default true
12322       */
12323
12324      Object.defineProperty(this, "pageWrapYEnabled", {
12325        get: function get() {
12326          return _pageWrapYEnabled;
12327        },
12328        set: function set(value) {
12329          _pageWrapYEnabled = Boolean(value);
12330        }
12331      });
12332      var _posX = 0;
12333      /**
12334       * @name posX
12335       * @type {number}
12336       * @default 0
12337       */
12338
12339      Object.defineProperty(this, "posX", {
12340        get: function get() {
12341          return _posX;
12342        },
12343        set: function set(value) {
12344          if (!isNaN(value)) {
12345            _posX = value;
12346          }
12347        }
12348      });
12349      var _posY = 0;
12350      /**
12351       * @name posY
12352       * @type {number}
12353       * @default 0
12354       */
12355
12356      Object.defineProperty(this, "posY", {
12357        get: function get() {
12358          return _posY;
12359        },
12360        set: function set(value) {
12361          if (!isNaN(value)) {
12362            _posY = value;
12363          }
12364        }
12365      });
12366      /**
12367       * Gets or sets the page margin when using auto paging. Has no effect when {@link autoPaging} is off.
12368       * @name margin
12369       * @type {number|number[]}
12370       * @default [0, 0, 0, 0]
12371       */
12372
12373      Object.defineProperty(this, "margin", {
12374        get: function get() {
12375          return _ctx.margin;
12376        },
12377        set: function set(value) {
12378          var margin;
12379
12380          if (typeof value === "number") {
12381            margin = [value, value, value, value];
12382          } else {
12383            margin = new Array(4);
12384            margin[0] = value[0];
12385            margin[1] = value.length >= 2 ? value[1] : margin[0];
12386            margin[2] = value.length >= 3 ? value[2] : margin[0];
12387            margin[3] = value.length >= 4 ? value[3] : margin[1];
12388          }
12389
12390          _ctx.margin = margin;
12391        }
12392      });
12393      var _autoPaging = false;
12394      /**
12395       * Gets or sets the auto paging mode. When auto paging is enabled, the context2d will automatically draw on the
12396       * next page if a shape or text chunk doesn't fit entirely on the current page. The context2d will create new
12397       * pages if required.
12398       *
12399       * Context2d supports different modes:
12400       * <ul>
12401       * <li>
12402       *   <code>false</code>: Auto paging is disabled.
12403       * </li>
12404       * <li>
12405       *   <code>true</code> or <code>'slice'</code>: Will cut shapes or text chunks across page breaks. Will possibly
12406       *   slice text in half, making it difficult to read.
12407       * </li>
12408       * <li>
12409       *   <code>'text'</code>: Trys not to cut text in half across page breaks. Works best for documents consisting
12410       *   mostly of a single column of text.
12411       * </li>
12412       * </ul>
12413       * @name Context2D#autoPaging
12414       * @type {boolean|"slice"|"text"}
12415       * @default false
12416       */
12417
12418      Object.defineProperty(this, "autoPaging", {
12419        get: function get() {
12420          return _autoPaging;
12421        },
12422        set: function set(value) {
12423          _autoPaging = value;
12424        }
12425      });
12426      var lastBreak = 0;
12427      /**
12428       * @name lastBreak
12429       * @type {number}
12430       * @default 0
12431       */
12432
12433      Object.defineProperty(this, "lastBreak", {
12434        get: function get() {
12435          return lastBreak;
12436        },
12437        set: function set(value) {
12438          lastBreak = value;
12439        }
12440      });
12441      var pageBreaks = [];
12442      /**
12443       * Y Position of page breaks.
12444       * @name pageBreaks
12445       * @type {number}
12446       * @default 0
12447       */
12448
12449      Object.defineProperty(this, "pageBreaks", {
12450        get: function get() {
12451          return pageBreaks;
12452        },
12453        set: function set(value) {
12454          pageBreaks = value;
12455        }
12456      });
12457      /**
12458       * @name ctx
12459       * @type {object}
12460       * @default {}
12461       */
12462
12463      Object.defineProperty(this, "ctx", {
12464        get: function get() {
12465          return _ctx;
12466        },
12467        set: function set(value) {
12468          if (value instanceof ContextLayer) {
12469            _ctx = value;
12470          }
12471        }
12472      });
12473      /**
12474       * @name path
12475       * @type {array}
12476       * @default []
12477       */
12478
12479      Object.defineProperty(this, "path", {
12480        get: function get() {
12481          return _ctx.path;
12482        },
12483        set: function set(value) {
12484          _ctx.path = value;
12485        }
12486      });
12487      /**
12488       * @name ctxStack
12489       * @type {array}
12490       * @default []
12491       */
12492
12493      var _ctxStack = [];
12494      Object.defineProperty(this, "ctxStack", {
12495        get: function get() {
12496          return _ctxStack;
12497        },
12498        set: function set(value) {
12499          _ctxStack = value;
12500        }
12501      });
12502      /**
12503       * Sets or returns the color, gradient, or pattern used to fill the drawing
12504       *
12505       * @name fillStyle
12506       * @default #000000
12507       * @property {(color|gradient|pattern)} value The color of the drawing. Default value is #000000<br />
12508       * A gradient object (linear or radial) used to fill the drawing (not supported by context2d)<br />
12509       * A pattern object to use to fill the drawing (not supported by context2d)
12510       */
12511
12512      Object.defineProperty(this, "fillStyle", {
12513        get: function get() {
12514          return this.ctx.fillStyle;
12515        },
12516        set: function set(value) {
12517          var rgba;
12518          rgba = getRGBA(value);
12519          this.ctx.fillStyle = rgba.style;
12520          this.ctx.isFillTransparent = rgba.a === 0;
12521          this.ctx.fillOpacity = rgba.a;
12522          this.pdf.setFillColor(rgba.r, rgba.g, rgba.b, {
12523            a: rgba.a
12524          });
12525          this.pdf.setTextColor(rgba.r, rgba.g, rgba.b, {
12526            a: rgba.a
12527          });
12528        }
12529      });
12530      /**
12531       * Sets or returns the color, gradient, or pattern used for strokes
12532       *
12533       * @name strokeStyle
12534       * @default #000000
12535       * @property {color} color A CSS color value that indicates the stroke color of the drawing. Default value is #000000 (not supported by context2d)
12536       * @property {gradient} gradient A gradient object (linear or radial) used to create a gradient stroke (not supported by context2d)
12537       * @property {pattern} pattern A pattern object used to create a pattern stroke (not supported by context2d)
12538       */
12539
12540      Object.defineProperty(this, "strokeStyle", {
12541        get: function get() {
12542          return this.ctx.strokeStyle;
12543        },
12544        set: function set(value) {
12545          var rgba = getRGBA(value);
12546          this.ctx.strokeStyle = rgba.style;
12547          this.ctx.isStrokeTransparent = rgba.a === 0;
12548          this.ctx.strokeOpacity = rgba.a;
12549
12550          if (rgba.a === 0) {
12551            this.pdf.setDrawColor(255, 255, 255);
12552          } else if (rgba.a === 1) {
12553            this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b);
12554          } else {
12555            this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b);
12556          }
12557        }
12558      });
12559      /**
12560       * Sets or returns the style of the end caps for a line
12561       *
12562       * @name lineCap
12563       * @default butt
12564       * @property {(butt|round|square)} lineCap butt A flat edge is added to each end of the line <br/>
12565       * round A rounded end cap is added to each end of the line<br/>
12566       * square A square end cap is added to each end of the line<br/>
12567       */
12568
12569      Object.defineProperty(this, "lineCap", {
12570        get: function get() {
12571          return this.ctx.lineCap;
12572        },
12573        set: function set(value) {
12574          if (["butt", "round", "square"].indexOf(value) !== -1) {
12575            this.ctx.lineCap = value;
12576            this.pdf.setLineCap(value);
12577          }
12578        }
12579      });
12580      /**
12581       * Sets or returns the current line width
12582       *
12583       * @name lineWidth
12584       * @default 1
12585       * @property {number} lineWidth The current line width, in pixels
12586       */
12587
12588      Object.defineProperty(this, "lineWidth", {
12589        get: function get() {
12590          return this.ctx.lineWidth;
12591        },
12592        set: function set(value) {
12593          if (!isNaN(value)) {
12594            this.ctx.lineWidth = value;
12595            this.pdf.setLineWidth(value);
12596          }
12597        }
12598      });
12599      /**
12600       * Sets or returns the type of corner created, when two lines meet
12601       */
12602
12603      Object.defineProperty(this, "lineJoin", {
12604        get: function get() {
12605          return this.ctx.lineJoin;
12606        },
12607        set: function set(value) {
12608          if (["bevel", "round", "miter"].indexOf(value) !== -1) {
12609            this.ctx.lineJoin = value;
12610            this.pdf.setLineJoin(value);
12611          }
12612        }
12613      });
12614      /**
12615       * A number specifying the miter limit ratio in coordinate space units. Zero, negative, Infinity, and NaN values are ignored. The default value is 10.0.
12616       *
12617       * @name miterLimit
12618       * @default 10
12619       */
12620
12621      Object.defineProperty(this, "miterLimit", {
12622        get: function get() {
12623          return this.ctx.miterLimit;
12624        },
12625        set: function set(value) {
12626          if (!isNaN(value)) {
12627            this.ctx.miterLimit = value;
12628            this.pdf.setMiterLimit(value);
12629          }
12630        }
12631      });
12632      Object.defineProperty(this, "textBaseline", {
12633        get: function get() {
12634          return this.ctx.textBaseline;
12635        },
12636        set: function set(value) {
12637          this.ctx.textBaseline = value;
12638        }
12639      });
12640      Object.defineProperty(this, "textAlign", {
12641        get: function get() {
12642          return this.ctx.textAlign;
12643        },
12644        set: function set(value) {
12645          if (["right", "end", "center", "left", "start"].indexOf(value) !== -1) {
12646            this.ctx.textAlign = value;
12647          }
12648        }
12649      });
12650      var _fontFaceMap = null;
12651
12652      function getFontFaceMap(pdf, fontFaces) {
12653        if (_fontFaceMap === null) {
12654          var fontMap = pdf.getFontList();
12655          var convertedFontFaces = convertToFontFaces(fontMap);
12656          _fontFaceMap = buildFontFaceMap(convertedFontFaces.concat(fontFaces));
12657        }
12658
12659        return _fontFaceMap;
12660      }
12661
12662      function convertToFontFaces(fontMap) {
12663        var fontFaces = [];
12664        Object.keys(fontMap).forEach(function (family) {
12665          var styles = fontMap[family];
12666          styles.forEach(function (style) {
12667            var fontFace = null;
12668
12669            switch (style) {
12670              case "bold":
12671                fontFace = {
12672                  family: family,
12673                  weight: "bold"
12674                };
12675                break;
12676
12677              case "italic":
12678                fontFace = {
12679                  family: family,
12680                  style: "italic"
12681                };
12682                break;
12683
12684              case "bolditalic":
12685                fontFace = {
12686                  family: family,
12687                  weight: "bold",
12688                  style: "italic"
12689                };
12690                break;
12691
12692              case "":
12693              case "normal":
12694                fontFace = {
12695                  family: family
12696                };
12697                break;
12698            } // If font-face is still null here, it is a font with some styling we don't recognize and
12699            // cannot map or it is a font added via the fontFaces option of .html().
12700
12701
12702            if (fontFace !== null) {
12703              fontFace.ref = {
12704                name: family,
12705                style: style
12706              };
12707              fontFaces.push(fontFace);
12708            }
12709          });
12710        });
12711        return fontFaces;
12712      }
12713
12714      var _fontFaces = null;
12715      /**
12716       * A map of available font-faces, as passed in the options of
12717       * .html(). If set a limited implementation of the font style matching
12718       * algorithm defined by https://www.w3.org/TR/css-fonts-3/#font-matching-algorithm
12719       * will be used. If not set it will fallback to previous behavior.
12720       */
12721
12722      Object.defineProperty(this, "fontFaces", {
12723        get: function get() {
12724          return _fontFaces;
12725        },
12726        set: function set(value) {
12727          _fontFaceMap = null;
12728          _fontFaces = value;
12729        }
12730      });
12731      Object.defineProperty(this, "font", {
12732        get: function get() {
12733          return this.ctx.font;
12734        },
12735        set: function set(value) {
12736          this.ctx.font = value;
12737          var rx, matches; //source: https://stackoverflow.com/a/10136041
12738          // eslint-disable-next-line no-useless-escape
12739
vendor: 9,636 bytes, lines 12740-13025
12740          rx = /^\s*(?=(?:(?:[-a-z]+\s*){0,2}(italic|oblique))?)(?=(?:(?:[-a-z]+\s*){0,2}(small-caps))?)(?=(?:(?:[-a-z]+\s*){0,2}(bold(?:er)?|lighter|[1-9]00))?)(?:(?:normal|\1|\2|\3)\s*){0,3}((?:xx?-)?(?:small|large)|medium|smaller|larger|[.\d]+(?:\%|in|[cem]m|ex|p[ctx]))(?:\s*\/\s*(normal|[.\d]+(?:\%|in|[cem]m|ex|p[ctx])))?\s*([-_,\"\'\sa-z]+?)\s*$/i;
12741          matches = rx.exec(value);
12742
12743          if (matches !== null) {
12744            var fontStyle = matches[1];
12745            var fontVariant = matches[2];
12746            var fontWeight = matches[3];
12747            var fontSize = matches[4];
12748            var lineHeight = matches[5];
12749            var fontFamily = matches[6];
12750          } else {
12751            return;
12752          }
12753
12754          var rxFontSize = /^([.\d]+)((?:%|in|[cem]m|ex|p[ctx]))$/i;
12755          var fontSizeUnit = rxFontSize.exec(fontSize)[2];
12756
12757          if ("px" === fontSizeUnit) {
12758            fontSize = Math.floor(parseFloat(fontSize) * this.pdf.internal.scaleFactor);
12759          } else if ("em" === fontSizeUnit) {
12760            fontSize = Math.floor(parseFloat(fontSize) * this.pdf.getFontSize());
12761          } else {
12762            fontSize = Math.floor(parseFloat(fontSize) * this.pdf.internal.scaleFactor);
12763          }
12764
12765          this.pdf.setFontSize(fontSize);
12766          var parts = parseFontFamily(fontFamily);
12767
12768          if (this.fontFaces) {
12769            var fontFaceMap = getFontFaceMap(this.pdf, this.fontFaces);
12770            var rules = parts.map(function (ff) {
12771              return {
12772                family: ff,
12773                stretch: "normal",
12774                // TODO: Extract font-stretch from font rule (perhaps write proper parser for it?)
12775                weight: fontWeight,
12776                style: fontStyle
12777              };
12778            });
12779            var font = resolveFontFace(fontFaceMap, rules);
12780            this.pdf.setFont(font.ref.name, font.ref.style);
12781            return;
12782          }
12783
12784          var style = "";
12785
12786          if (fontWeight === "bold" || parseInt(fontWeight, 10) >= 700 || fontStyle === "bold") {
12787            style = "bold";
12788          }
12789
12790          if (fontStyle === "italic") {
12791            style += "italic";
12792          }
12793
12794          if (style.length === 0) {
12795            style = "normal";
12796          }
12797
12798          var jsPdfFontName = "";
12799          var fallbackFonts = {
12800            arial: "Helvetica",
12801            Arial: "Helvetica",
12802            verdana: "Helvetica",
12803            Verdana: "Helvetica",
12804            helvetica: "Helvetica",
12805            Helvetica: "Helvetica",
12806            "sans-serif": "Helvetica",
12807            fixed: "Courier",
12808            monospace: "Courier",
12809            terminal: "Courier",
12810            cursive: "Times",
12811            fantasy: "Times",
12812            serif: "Times"
12813          };
12814
12815          for (var i = 0; i < parts.length; i++) {
12816            if (this.pdf.internal.getFont(parts[i], style, {
12817              noFallback: true,
12818              disableWarning: true
12819            }) !== undefined) {
12820              jsPdfFontName = parts[i];
12821              break;
12822            } else if (style === "bolditalic" && this.pdf.internal.getFont(parts[i], "bold", {
12823              noFallback: true,
12824              disableWarning: true
12825            }) !== undefined) {
12826              jsPdfFontName = parts[i];
12827              style = "bold";
12828            } else if (this.pdf.internal.getFont(parts[i], "normal", {
12829              noFallback: true,
12830              disableWarning: true
12831            }) !== undefined) {
12832              jsPdfFontName = parts[i];
12833              style = "normal";
12834              break;
12835            }
12836          }
12837
12838          if (jsPdfFontName === "") {
12839            for (var j = 0; j < parts.length; j++) {
12840              if (fallbackFonts[parts[j]]) {
12841                jsPdfFontName = fallbackFonts[parts[j]];
12842                break;
12843              }
12844            }
12845          }
12846
12847          jsPdfFontName = jsPdfFontName === "" ? "Times" : jsPdfFontName;
12848          this.pdf.setFont(jsPdfFontName, style);
12849        }
12850      });
12851      Object.defineProperty(this, "globalCompositeOperation", {
12852        get: function get() {
12853          return this.ctx.globalCompositeOperation;
12854        },
12855        set: function set(value) {
12856          this.ctx.globalCompositeOperation = value;
12857        }
12858      });
12859      Object.defineProperty(this, "globalAlpha", {
12860        get: function get() {
12861          return this.ctx.globalAlpha;
12862        },
12863        set: function set(value) {
12864          this.ctx.globalAlpha = value;
12865        }
12866      });
12867      /**
12868       * A float specifying the amount of the line dash offset. The default value is 0.0.
12869       *
12870       * @name lineDashOffset
12871       * @default 0.0
12872       */
12873
12874      Object.defineProperty(this, "lineDashOffset", {
12875        get: function get() {
12876          return this.ctx.lineDashOffset;
12877        },
12878        set: function set(value) {
12879          this.ctx.lineDashOffset = value;
12880          setLineDash.call(this);
12881        }
12882      }); // Not HTML API
12883
12884      Object.defineProperty(this, "lineDash", {
12885        get: function get() {
12886          return this.ctx.lineDash;
12887        },
12888        set: function set(value) {
12889          this.ctx.lineDash = value;
12890          setLineDash.call(this);
12891        }
12892      }); // Not HTML API
12893
12894      Object.defineProperty(this, "ignoreClearRect", {
12895        get: function get() {
12896          return this.ctx.ignoreClearRect;
12897        },
12898        set: function set(value) {
12899          this.ctx.ignoreClearRect = Boolean(value);
12900        }
12901      });
12902    };
12903    /**
12904     * Sets the line dash pattern used when stroking lines.
12905     * @name setLineDash
12906     * @function
12907     * @description It uses an array of values that specify alternating lengths of lines and gaps which describe the pattern.
12908     */
12909
12910
12911    Context2D.prototype.setLineDash = function (dashArray) {
12912      this.lineDash = dashArray;
12913    };
12914    /**
12915     * gets the current line dash pattern.
12916     * @name getLineDash
12917     * @function
12918     * @returns {Array} An Array of numbers that specify distances to alternately draw a line and a gap (in coordinate space units). If the number, when setting the elements, is odd, the elements of the array get copied and concatenated. For example, setting the line dash to [5, 15, 25] will result in getting back [5, 15, 25, 5, 15, 25].
12919     */
12920
12921
12922    Context2D.prototype.getLineDash = function () {
12923      if (this.lineDash.length % 2) {
12924        // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getLineDash#return_value
12925        return this.lineDash.concat(this.lineDash);
12926      } else {
12927        // The copied value is returned to prevent contamination from outside.
12928        return this.lineDash.slice();
12929      }
12930    };
12931
12932    Context2D.prototype.fill = function () {
12933      pathPreProcess.call(this, "fill", false);
12934    };
12935    /**
12936     * Actually draws the path you have defined
12937     *
12938     * @name stroke
12939     * @function
12940     * @description The stroke() method actually draws the path you have defined with all those moveTo() and lineTo() methods. The default color is black.
12941     */
12942
12943
12944    Context2D.prototype.stroke = function () {
12945      pathPreProcess.call(this, "stroke", false);
12946    };
12947    /**
12948     * Begins a path, or resets the current
12949     *
12950     * @name beginPath
12951     * @function
12952     * @description The beginPath() method begins a path, or resets the current path.
12953     */
12954
12955
12956    Context2D.prototype.beginPath = function () {
12957      this.path = [{
12958        type: "begin"
12959      }];
12960    };
12961    /**
12962     * Moves the path to the specified point in the canvas, without creating a line
12963     *
12964     * @name moveTo
12965     * @function
12966     * @param x {Number} The x-coordinate of where to move the path to
12967     * @param y {Number} The y-coordinate of where to move the path to
12968     */
12969
12970
12971    Context2D.prototype.moveTo = function (x, y) {
12972      if (isNaN(x) || isNaN(y)) {
12973        console.error("jsPDF.context2d.moveTo: Invalid arguments", arguments);
12974        throw new Error("Invalid arguments passed to jsPDF.context2d.moveTo");
12975      }
12976
12977      var pt = this.ctx.transform.applyToPoint(new Point(x, y));
12978      this.path.push({
12979        type: "mt",
12980        x: pt.x,
12981        y: pt.y
12982      });
12983      this.ctx.lastPoint = new Point(x, y);
12984    };
12985    /**
12986     * Creates a path from the current point back to the starting point
12987     *
12988     * @name closePath
12989     * @function
12990     * @description The closePath() method creates a path from the current point back to the starting point.
12991     */
12992
12993
12994    Context2D.prototype.closePath = function () {
12995      var pathBegin = new Point(0, 0);
12996      var i = 0;
12997
12998      for (i = this.path.length - 1; i !== -1; i--) {
12999        if (this.path[i].type === "begin") {
13000          if (_typeof(this.path[i + 1]) === "object" && typeof this.path[i + 1].x === "number") {
13001            pathBegin = new Point(this.path[i + 1].x, this.path[i + 1].y);
13002            break;
13003          }
13004        }
13005      }
13006
13007      this.path.push({
13008        type: "close"
13009      });
13010      this.ctx.lastPoint = new Point(pathBegin.x, pathBegin.y);
13011    };
13012    /**
13013     * Adds a new point and creates a line to that point from the last specified point in the canvas
13014     *
13015     * @name lineTo
13016     * @function
13017     * @param x The x-coordinate of where to create the line to
13018     * @param y The y-coordinate of where to create the line to
13019     * @description The lineTo() method adds a new point and creates a line TO that point FROM the last specified point in the canvas (this method does not draw the line).
13020     */
13021
13022
13023    Context2D.prototype.lineTo = function (x, y) {
13024      if (isNaN(x) || isNaN(y)) {
13025        console.error("jsPDF.context2d.lineTo: Invalid arguments", arguments);
13026        throw new Error("Invalid arguments passed to jsPDF.context2d.lineTo");
13027      }
13028
13029      var pt = this.ctx.transform.applyToPoint(new Point(x, y));
13030      this.path.push({
13031        type: "lt",
13032        x: pt.x,
13033        y: pt.y
13034      });
13035      this.ctx.lastPoint = new Point(pt.x, pt.y);
13036    };
13037    /**
13038     * Clips a region of any shape and size from the original canvas
13039     *
13040     * @name clip
13041     * @function
13042     * @description The clip() method clips a region of any shape and size from the original canvas.
13043     */
13044
13045
13046    Context2D.prototype.clip = function () {
13047      this.ctx.clip_path = JSON.parse(JSON.stringify(this.path));
13048      pathPreProcess.call(this, null, true);
13049    };
13050    /**
13051     * Creates a cubic Bézier curve
13052     *
13053     * @name quadraticCurveTo
13054     * @function
13055     * @param cpx {Number} The x-coordinate of the Bézier control point
13056     * @param cpy {Number} The y-coordinate of the Bézier control point
13057     * @param x {Number} The x-coordinate of the ending point
13058     * @param y {Number} The y-coordinate of the ending point
13059     * @description The quadraticCurveTo() method adds a point to the current path by using the specified control points that represent a quadratic Bézier curve.<br /><br /> A quadratic Bézier curve requires two points. The first point is a control point that is used in the quadratic Bézier calculation and the second point is the ending point for the curve. The starting point for the curve is the last point in the current path. If a path does not exist, use the beginPath() and moveTo() methods to define a starting point.
13060     */
13061
13062
13063    Context2D.prototype.quadraticCurveTo = function (cpx, cpy, x, y) {
13064      if (isNaN(x) || isNaN(y) || isNaN(cpx) || isNaN(cpy)) {
13065        console.error("jsPDF.context2d.quadraticCurveTo: Invalid arguments", arguments);
13066        throw new Error("Invalid arguments passed to jsPDF.context2d.quadraticCurveTo");
13067      }
13068
13069      var pt0 = this.ctx.transform.applyToPoint(new Point(x, y));
13070      var pt1 = this.ctx.transform.applyToPoint(new Point(cpx, cpy));
13071      this.path.push({
13072        type: "qct",
13073        x1: pt1.x,
13074        y1: pt1.y,
13075        x: pt0.x,
13076        y: pt0.y
13077      });
13078      this.ctx.lastPoint = new Point(pt0.x, pt0.y);
13079    };
13080    /**
13081     * Creates a cubic Bézier curve
13082     *
13083     * @name bezierCurveTo
13084     * @function
13085     * @param cp1x {Number} The x-coordinate of the first Bézier control point
13086     * @param cp1y {Number} The y-coordinate of the first Bézier control point
13087     * @param cp2x {Number} The x-coordinate of the second Bézier control point
13088     * @param cp2y {Number} The y-coordinate of the second Bézier control point
13089     * @param x {Number} The x-coordinate of the ending point
13090     * @param y {Number} The y-coordinate of the ending point
13091     * @description The bezierCurveTo() method adds a point to the current path by using the specified control points that represent a cubic Bézier curve. <br /><br />A cubic bezier curve requires three points. The first two points are control points that are used in the cubic Bézier calculation and the last point is the ending point for the curve.  The starting point for the curve is the last point in the current path. If a path does not exist, use the beginPath() and moveTo() methods to define a starting point.
13092     */
13093
13094
13095    Context2D.prototype.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) {
13096      if (isNaN(x) || isNaN(y) || isNaN(cp1x) || isNaN(cp1y) || isNaN(cp2x) || isNaN(cp2y)) {
13097        console.error("jsPDF.context2d.bezierCurveTo: Invalid arguments", arguments);
13098        throw new Error("Invalid arguments passed to jsPDF.context2d.bezierCurveTo");
13099      }
13100
13101      var pt0 = this.ctx.transform.applyToPoint(new Point(x, y));
13102      var pt1 = this.ctx.transform.applyToPoint(new Point(cp1x, cp1y));
13103      var pt2 = this.ctx.transform.applyToPoint(new Point(cp2x, cp2y));
13104      this.path.push({
13105        type: "bct",
13106        x1: pt1.x,
13107        y1: pt1.y,
13108        x2: pt2.x,
13109        y2: pt2.y,
13110        x: pt0.x,
13111        y: pt0.y
13112      });
13113      this.ctx.lastPoint = new Point(pt0.x, pt0.y);
13114    };
13115    /**
13116     * Creates an arc/curve (used to create circles, or parts of circles)
13117     *
13118     * @name arc
13119     * @function
13120     * @param x {Number} The x-coordinate of the center of the circle
13121     * @param y {Number} The y-coordinate of the center of the circle
13122     * @param radius {Number} The radius of the circle
13123     * @param startAngle {Number} The starting angle, in radians (0 is at the 3 o'clock position of the arc's circle)
13124     * @param endAngle {Number} The ending angle, in radians
13125     * @param counterclockwise {Boolean} Optional. Specifies whether the drawing should be counterclockwise or clockwise. False is default, and indicates clockwise, while true indicates counter-clockwise.
vendor: 50,408 bytes, lines 13126-14588
13126     * @description The arc() method creates an arc/curve (used to create circles, or parts of circles).
13127     */
13128
13129
13130    Context2D.prototype.arc = function (x, y, radius, startAngle, endAngle, counterclockwise) {
13131      if (isNaN(x) || isNaN(y) || isNaN(radius) || isNaN(startAngle) || isNaN(endAngle)) {
13132        console.error("jsPDF.context2d.arc: Invalid arguments", arguments);
13133        throw new Error("Invalid arguments passed to jsPDF.context2d.arc");
13134      }
13135
13136      counterclockwise = Boolean(counterclockwise);
13137
13138      if (!this.ctx.transform.isIdentity) {
13139        var xpt = this.ctx.transform.applyToPoint(new Point(x, y));
13140        x = xpt.x;
13141        y = xpt.y;
13142        var x_radPt = this.ctx.transform.applyToPoint(new Point(0, radius));
13143        var x_radPt0 = this.ctx.transform.applyToPoint(new Point(0, 0));
13144        radius = Math.sqrt(Math.pow(x_radPt.x - x_radPt0.x, 2) + Math.pow(x_radPt.y - x_radPt0.y, 2));
13145      }
13146
13147      if (Math.abs(endAngle - startAngle) >= 2 * Math.PI) {
13148        startAngle = 0;
13149        endAngle = 2 * Math.PI;
13150      }
13151
13152      this.path.push({
13153        type: "arc",
13154        x: x,
13155        y: y,
13156        radius: radius,
13157        startAngle: startAngle,
13158        endAngle: endAngle,
13159        counterclockwise: counterclockwise
13160      }); // this.ctx.lastPoint(new Point(pt.x,pt.y));
13161    };
13162    /**
13163     * Creates an arc/curve between two tangents
13164     *
13165     * @name arcTo
13166     * @function
13167     * @param x1 {Number} The x-coordinate of the first tangent
13168     * @param y1 {Number} The y-coordinate of the first tangent
13169     * @param x2 {Number} The x-coordinate of the second tangent
13170     * @param y2 {Number} The y-coordinate of the second tangent
13171     * @param radius The radius of the arc
13172     * @description The arcTo() method creates an arc/curve between two tangents on the canvas.
13173     */
13174    // eslint-disable-next-line no-unused-vars
13175
13176
13177    Context2D.prototype.arcTo = function (x1, y1, x2, y2, radius) {
13178      throw new Error("arcTo not implemented.");
13179    };
13180    /**
13181     * Creates a rectangle
13182     *
13183     * @name rect
13184     * @function
13185     * @param x {Number} The x-coordinate of the upper-left corner of the rectangle
13186     * @param y {Number} The y-coordinate of the upper-left corner of the rectangle
13187     * @param w {Number} The width of the rectangle, in pixels
13188     * @param h {Number} The height of the rectangle, in pixels
13189     * @description The rect() method creates a rectangle.
13190     */
13191
13192
13193    Context2D.prototype.rect = function (x, y, w, h) {
13194      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) {
13195        console.error("jsPDF.context2d.rect: Invalid arguments", arguments);
13196        throw new Error("Invalid arguments passed to jsPDF.context2d.rect");
13197      }
13198
13199      this.moveTo(x, y);
13200      this.lineTo(x + w, y);
13201      this.lineTo(x + w, y + h);
13202      this.lineTo(x, y + h);
13203      this.lineTo(x, y);
13204      this.lineTo(x + w, y);
13205      this.lineTo(x, y);
13206    };
13207    /**
13208     * Draws a "filled" rectangle
13209     *
13210     * @name fillRect
13211     * @function
13212     * @param x {Number} The x-coordinate of the upper-left corner of the rectangle
13213     * @param y {Number} The y-coordinate of the upper-left corner of the rectangle
13214     * @param w {Number} The width of the rectangle, in pixels
13215     * @param h {Number} The height of the rectangle, in pixels
13216     * @description The fillRect() method draws a "filled" rectangle. The default color of the fill is black.
13217     */
13218
13219
13220    Context2D.prototype.fillRect = function (x, y, w, h) {
13221      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) {
13222        console.error("jsPDF.context2d.fillRect: Invalid arguments", arguments);
13223        throw new Error("Invalid arguments passed to jsPDF.context2d.fillRect");
13224      }
13225
13226      if (isFillTransparent.call(this)) {
13227        return;
13228      }
13229
13230      var tmp = {};
13231
13232      if (this.lineCap !== "butt") {
13233        tmp.lineCap = this.lineCap;
13234        this.lineCap = "butt";
13235      }
13236
13237      if (this.lineJoin !== "miter") {
13238        tmp.lineJoin = this.lineJoin;
13239        this.lineJoin = "miter";
13240      }
13241
13242      this.beginPath();
13243      this.rect(x, y, w, h);
13244      this.fill();
13245
13246      if (tmp.hasOwnProperty("lineCap")) {
13247        this.lineCap = tmp.lineCap;
13248      }
13249
13250      if (tmp.hasOwnProperty("lineJoin")) {
13251        this.lineJoin = tmp.lineJoin;
13252      }
13253    };
13254    /**
13255     *     Draws a rectangle (no fill)
13256     *
13257     * @name strokeRect
13258     * @function
13259     * @param x {Number} The x-coordinate of the upper-left corner of the rectangle
13260     * @param y {Number} The y-coordinate of the upper-left corner of the rectangle
13261     * @param w {Number} The width of the rectangle, in pixels
13262     * @param h {Number} The height of the rectangle, in pixels
13263     * @description The strokeRect() method draws a rectangle (no fill). The default color of the stroke is black.
13264     */
13265
13266
13267    Context2D.prototype.strokeRect = function strokeRect(x, y, w, h) {
13268      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) {
13269        console.error("jsPDF.context2d.strokeRect: Invalid arguments", arguments);
13270        throw new Error("Invalid arguments passed to jsPDF.context2d.strokeRect");
13271      }
13272
13273      if (isStrokeTransparent.call(this)) {
13274        return;
13275      }
13276
13277      this.beginPath();
13278      this.rect(x, y, w, h);
13279      this.stroke();
13280    };
13281    /**
13282     * Clears the specified pixels within a given rectangle
13283     *
13284     * @name clearRect
13285     * @function
13286     * @param x {Number} The x-coordinate of the upper-left corner of the rectangle
13287     * @param y {Number} The y-coordinate of the upper-left corner of the rectangle
13288     * @param w {Number} The width of the rectangle to clear, in pixels
13289     * @param h {Number} The height of the rectangle to clear, in pixels
13290     * @description We cannot clear PDF commands that were already written to PDF, so we use white instead. <br />
13291     * As a special case, read a special flag (ignoreClearRect) and do nothing if it is set.
13292     * This results in all calls to clearRect() to do nothing, and keep the canvas transparent.
13293     * This flag is stored in the save/restore context and is managed the same way as other drawing states.
13294     *
13295     */
13296
13297
13298    Context2D.prototype.clearRect = function (x, y, w, h) {
13299      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) {
13300        console.error("jsPDF.context2d.clearRect: Invalid arguments", arguments);
13301        throw new Error("Invalid arguments passed to jsPDF.context2d.clearRect");
13302      }
13303
13304      if (this.ignoreClearRect) {
13305        return;
13306      }
13307
13308      this.fillStyle = "#ffffff";
13309      this.fillRect(x, y, w, h);
13310    };
13311    /**
13312     * Saves the state of the current context
13313     *
13314     * @name save
13315     * @function
13316     */
13317
13318
13319    Context2D.prototype.save = function (doStackPush) {
13320      doStackPush = typeof doStackPush === "boolean" ? doStackPush : true;
13321      var tmpPageNumber = this.pdf.internal.getCurrentPageInfo().pageNumber;
13322
13323      for (var i = 0; i < this.pdf.internal.getNumberOfPages(); i++) {
13324        this.pdf.setPage(i + 1);
13325        this.pdf.internal.out("q");
13326      }
13327
13328      this.pdf.setPage(tmpPageNumber);
13329
13330      if (doStackPush) {
13331        this.ctx.fontSize = this.pdf.internal.getFontSize();
13332        var ctx = new ContextLayer(this.ctx);
13333        this.ctxStack.push(this.ctx);
13334        this.ctx = ctx;
13335      }
13336    };
13337    /**
13338     * Returns previously saved path state and attributes
13339     *
13340     * @name restore
13341     * @function
13342     */
13343
13344
13345    Context2D.prototype.restore = function (doStackPop) {
13346      doStackPop = typeof doStackPop === "boolean" ? doStackPop : true;
13347      var tmpPageNumber = this.pdf.internal.getCurrentPageInfo().pageNumber;
13348
13349      for (var i = 0; i < this.pdf.internal.getNumberOfPages(); i++) {
13350        this.pdf.setPage(i + 1);
13351        this.pdf.internal.out("Q");
13352      }
13353
13354      this.pdf.setPage(tmpPageNumber);
13355
13356      if (doStackPop && this.ctxStack.length !== 0) {
13357        this.ctx = this.ctxStack.pop();
13358        this.fillStyle = this.ctx.fillStyle;
13359        this.strokeStyle = this.ctx.strokeStyle;
13360        this.font = this.ctx.font;
13361        this.lineCap = this.ctx.lineCap;
13362        this.lineWidth = this.ctx.lineWidth;
13363        this.lineJoin = this.ctx.lineJoin;
13364        this.lineDash = this.ctx.lineDash;
13365        this.lineDashOffset = this.ctx.lineDashOffset;
13366      }
13367    };
13368    /**
13369     * @name toDataURL
13370     * @function
13371     */
13372
13373
13374    Context2D.prototype.toDataURL = function () {
13375      throw new Error("toDataUrl not implemented.");
13376    }; //helper functions
13377
13378    /**
13379     * Get the decimal values of r, g, b and a
13380     *
13381     * @name getRGBA
13382     * @function
13383     * @private
13384     * @ignore
13385     */
13386
13387
13388    var getRGBA = function getRGBA(style) {
13389      var rxRgb = /rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/;
13390      var rxRgba = /rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/;
13391      var rxTransparent = /transparent|rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*0+\s*\)/;
13392      var r, g, b, a;
13393
13394      if (style.isCanvasGradient === true) {
13395        style = style.getColor();
13396      }
13397
13398      if (!style) {
13399        return {
13400          r: 0,
13401          g: 0,
13402          b: 0,
13403          a: 0,
13404          style: style
13405        };
13406      }
13407
13408      if (rxTransparent.test(style)) {
13409        r = 0;
13410        g = 0;
13411        b = 0;
13412        a = 0;
13413      } else {
13414        var matches = rxRgb.exec(style);
13415
13416        if (matches !== null) {
13417          r = parseInt(matches[1]);
13418          g = parseInt(matches[2]);
13419          b = parseInt(matches[3]);
13420          a = 1;
13421        } else {
13422          matches = rxRgba.exec(style);
13423
13424          if (matches !== null) {
13425            r = parseInt(matches[1]);
13426            g = parseInt(matches[2]);
13427            b = parseInt(matches[3]);
13428            a = parseFloat(matches[4]);
13429          } else {
13430            a = 1;
13431
13432            if (typeof style === "string" && style.charAt(0) !== "#") {
13433              var rgbColor = new RGBColor(style);
13434
13435              if (rgbColor.ok) {
13436                style = rgbColor.toHex();
13437              } else {
13438                style = "#000000";
13439              }
13440            }
13441
13442            if (style.length === 4) {
13443              r = style.substring(1, 2);
13444              r += r;
13445              g = style.substring(2, 3);
13446              g += g;
13447              b = style.substring(3, 4);
13448              b += b;
13449            } else {
13450              r = style.substring(1, 3);
13451              g = style.substring(3, 5);
13452              b = style.substring(5, 7);
13453            }
13454
13455            r = parseInt(r, 16);
13456            g = parseInt(g, 16);
13457            b = parseInt(b, 16);
13458          }
13459        }
13460      }
13461
13462      return {
13463        r: r,
13464        g: g,
13465        b: b,
13466        a: a,
13467        style: style
13468      };
13469    };
13470    /**
13471     * @name isFillTransparent
13472     * @function
13473     * @private
13474     * @ignore
13475     * @returns {Boolean}
13476     */
13477
13478
13479    var isFillTransparent = function isFillTransparent() {
13480      return this.ctx.isFillTransparent || this.globalAlpha == 0;
13481    };
13482    /**
13483     * @name isStrokeTransparent
13484     * @function
13485     * @private
13486     * @ignore
13487     * @returns {Boolean}
13488     */
13489
13490
13491    var isStrokeTransparent = function isStrokeTransparent() {
13492      return Boolean(this.ctx.isStrokeTransparent || this.globalAlpha == 0);
13493    };
13494    /**
13495     * Draws "filled" text on the canvas
13496     *
13497     * @name fillText
13498     * @function
13499     * @param text {String} Specifies the text that will be written on the canvas
13500     * @param x {Number} The x coordinate where to start painting the text (relative to the canvas)
13501     * @param y {Number} The y coordinate where to start painting the text (relative to the canvas)
13502     * @param maxWidth {Number} Optional. The maximum allowed width of the text, in pixels
13503     * @description The fillText() method draws filled text on the canvas. The default color of the text is black.
13504     */
13505
13506
13507    Context2D.prototype.fillText = function (text, x, y, maxWidth) {
13508      if (isNaN(x) || isNaN(y) || typeof text !== "string") {
13509        console.error("jsPDF.context2d.fillText: Invalid arguments", arguments);
13510        throw new Error("Invalid arguments passed to jsPDF.context2d.fillText");
13511      }
13512
13513      maxWidth = isNaN(maxWidth) ? undefined : maxWidth;
13514
13515      if (isFillTransparent.call(this)) {
13516        return;
13517      }
13518
13519      var degs = rad2deg(this.ctx.transform.rotation); // We only use X axis as scale hint
13520
13521      var scale = this.ctx.transform.scaleX;
13522      putText.call(this, {
13523        text: text,
13524        x: x,
13525        y: y,
13526        scale: scale,
13527        angle: degs,
13528        align: this.textAlign,
13529        maxWidth: maxWidth
13530      });
13531    };
13532    /**
13533     * Draws text on the canvas (no fill)
13534     *
13535     * @name strokeText
13536     * @function
13537     * @param text {String} Specifies the text that will be written on the canvas
13538     * @param x {Number} The x coordinate where to start painting the text (relative to the canvas)
13539     * @param y {Number} The y coordinate where to start painting the text (relative to the canvas)
13540     * @param maxWidth {Number} Optional. The maximum allowed width of the text, in pixels
13541     * @description The strokeText() method draws text (with no fill) on the canvas. The default color of the text is black.
13542     */
13543
13544
13545    Context2D.prototype.strokeText = function (text, x, y, maxWidth) {
13546      if (isNaN(x) || isNaN(y) || typeof text !== "string") {
13547        console.error("jsPDF.context2d.strokeText: Invalid arguments", arguments);
13548        throw new Error("Invalid arguments passed to jsPDF.context2d.strokeText");
13549      }
13550
13551      if (isStrokeTransparent.call(this)) {
13552        return;
13553      }
13554
13555      maxWidth = isNaN(maxWidth) ? undefined : maxWidth;
13556      var degs = rad2deg(this.ctx.transform.rotation);
13557      var scale = this.ctx.transform.scaleX;
13558      putText.call(this, {
13559        text: text,
13560        x: x,
13561        y: y,
13562        scale: scale,
13563        renderingMode: "stroke",
13564        angle: degs,
13565        align: this.textAlign,
13566        maxWidth: maxWidth
13567      });
13568    };
13569    /**
13570     * Returns an object that contains the width of the specified text
13571     *
13572     * @name measureText
13573     * @function
13574     * @param text {String} The text to be measured
13575     * @description The measureText() method returns an object that contains the width of the specified text, in pixels.
13576     * @returns {Number}
13577     */
13578
13579
13580    Context2D.prototype.measureText = function (text) {
13581      if (typeof text !== "string") {
13582        console.error("jsPDF.context2d.measureText: Invalid arguments", arguments);
13583        throw new Error("Invalid arguments passed to jsPDF.context2d.measureText");
13584      }
13585
13586      var pdf = this.pdf;
13587      var k = this.pdf.internal.scaleFactor;
13588      var fontSize = pdf.internal.getFontSize();
13589      var txtWidth = pdf.getStringUnitWidth(text) * fontSize / pdf.internal.scaleFactor;
13590      txtWidth *= Math.round(k * 96 / 72 * 10000) / 10000;
13591
13592      var TextMetrics = function TextMetrics(options) {
13593        options = options || {};
13594
13595        var _width = options.width || 0;
13596
13597        Object.defineProperty(this, "width", {
13598          get: function get() {
13599            return _width;
13600          }
13601        });
13602        return this;
13603      };
13604
13605      return new TextMetrics({
13606        width: txtWidth
13607      });
13608    }; //Transformations
13609
13610    /**
13611     * Scales the current drawing bigger or smaller
13612     *
13613     * @name scale
13614     * @function
13615     * @param scalewidth {Number} Scales the width of the current drawing (1=100%, 0.5=50%, 2=200%, etc.)
13616     * @param scaleheight {Number} Scales the height of the current drawing (1=100%, 0.5=50%, 2=200%, etc.)
13617     * @description The scale() method scales the current drawing, bigger or smaller.
13618     */
13619
13620
13621    Context2D.prototype.scale = function (scalewidth, scaleheight) {
13622      if (isNaN(scalewidth) || isNaN(scaleheight)) {
13623        console.error("jsPDF.context2d.scale: Invalid arguments", arguments);
13624        throw new Error("Invalid arguments passed to jsPDF.context2d.scale");
13625      }
13626
13627      var matrix = new Matrix(scalewidth, 0.0, 0.0, scaleheight, 0.0, 0.0);
13628      this.ctx.transform = this.ctx.transform.multiply(matrix);
13629    };
13630    /**
13631     * Rotates the current drawing
13632     *
13633     * @name rotate
13634     * @function
13635     * @param angle {Number} The rotation angle, in radians.
13636     * @description To calculate from degrees to radians: degrees*Math.PI/180. <br />
13637     * Example: to rotate 5 degrees, specify the following: 5*Math.PI/180
13638     */
13639
13640
13641    Context2D.prototype.rotate = function (angle) {
13642      if (isNaN(angle)) {
13643        console.error("jsPDF.context2d.rotate: Invalid arguments", arguments);
13644        throw new Error("Invalid arguments passed to jsPDF.context2d.rotate");
13645      }
13646
13647      var matrix = new Matrix(Math.cos(angle), Math.sin(angle), -Math.sin(angle), Math.cos(angle), 0.0, 0.0);
13648      this.ctx.transform = this.ctx.transform.multiply(matrix);
13649    };
13650    /**
13651     * Remaps the (0,0) position on the canvas
13652     *
13653     * @name translate
13654     * @function
13655     * @param x {Number} The value to add to horizontal (x) coordinates
13656     * @param y {Number} The value to add to vertical (y) coordinates
13657     * @description The translate() method remaps the (0,0) position on the canvas.
13658     */
13659
13660
13661    Context2D.prototype.translate = function (x, y) {
13662      if (isNaN(x) || isNaN(y)) {
13663        console.error("jsPDF.context2d.translate: Invalid arguments", arguments);
13664        throw new Error("Invalid arguments passed to jsPDF.context2d.translate");
13665      }
13666
13667      var matrix = new Matrix(1.0, 0.0, 0.0, 1.0, x, y);
13668      this.ctx.transform = this.ctx.transform.multiply(matrix);
13669    };
13670    /**
13671     * Replaces the current transformation matrix for the drawing
13672     *
13673     * @name transform
13674     * @function
13675     * @param a {Number} Horizontal scaling
13676     * @param b {Number} Horizontal skewing
13677     * @param c {Number} Vertical skewing
13678     * @param d {Number} Vertical scaling
13679     * @param e {Number} Horizontal moving
13680     * @param f {Number} Vertical moving
13681     * @description Each object on the canvas has a current transformation matrix.<br /><br />The transform() method replaces the current transformation matrix. It multiplies the current transformation matrix with the matrix described by:<br /><br /><br /><br />a    c    e<br /><br />b    d    f<br /><br />0    0    1<br /><br />In other words, the transform() method lets you scale, rotate, move, and skew the current context.
13682     */
13683
13684
13685    Context2D.prototype.transform = function (a, b, c, d, e, f) {
13686      if (isNaN(a) || isNaN(b) || isNaN(c) || isNaN(d) || isNaN(e) || isNaN(f)) {
13687        console.error("jsPDF.context2d.transform: Invalid arguments", arguments);
13688        throw new Error("Invalid arguments passed to jsPDF.context2d.transform");
13689      }
13690
13691      var matrix = new Matrix(a, b, c, d, e, f);
13692      this.ctx.transform = this.ctx.transform.multiply(matrix);
13693    };
13694    /**
13695     * Resets the current transform to the identity matrix. Then runs transform()
13696     *
13697     * @name setTransform
13698     * @function
13699     * @param a {Number} Horizontal scaling
13700     * @param b {Number} Horizontal skewing
13701     * @param c {Number} Vertical skewing
13702     * @param d {Number} Vertical scaling
13703     * @param e {Number} Horizontal moving
13704     * @param f {Number} Vertical moving
13705     * @description Each object on the canvas has a current transformation matrix. <br /><br />The setTransform() method resets the current transform to the identity matrix, and then runs transform() with the same arguments.<br /><br />In other words, the setTransform() method lets you scale, rotate, move, and skew the current context.
13706     */
13707
13708
13709    Context2D.prototype.setTransform = function (a, b, c, d, e, f) {
13710      a = isNaN(a) ? 1 : a;
13711      b = isNaN(b) ? 0 : b;
13712      c = isNaN(c) ? 0 : c;
13713      d = isNaN(d) ? 1 : d;
13714      e = isNaN(e) ? 0 : e;
13715      f = isNaN(f) ? 0 : f;
13716      this.ctx.transform = new Matrix(a, b, c, d, e, f);
13717    };
13718
13719    var hasMargins = function hasMargins() {
13720      return this.margin[0] > 0 || this.margin[1] > 0 || this.margin[2] > 0 || this.margin[3] > 0;
13721    };
13722    /**
13723     * Draws an image, canvas, or video onto the canvas
13724     *
13725     * @function
13726     * @param img {} Specifies the image, canvas, or video element to use
13727     * @param sx {Number} Optional. The x coordinate where to start clipping
13728     * @param sy {Number} Optional. The y coordinate where to start clipping
13729     * @param swidth {Number} Optional. The width of the clipped image
13730     * @param sheight {Number} Optional. The height of the clipped image
13731     * @param x {Number} The x coordinate where to place the image on the canvas
13732     * @param y {Number} The y coordinate where to place the image on the canvas
13733     * @param width {Number} Optional. The width of the image to use (stretch or reduce the image)
13734     * @param height {Number} Optional. The height of the image to use (stretch or reduce the image)
13735     */
13736
13737
13738    Context2D.prototype.drawImage = function (img, sx, sy, swidth, sheight, x, y, width, height) {
13739      var imageProperties = this.pdf.getImageProperties(img);
13740      var factorX = 1;
13741      var factorY = 1;
13742      var clipFactorX = 1;
13743      var clipFactorY = 1;
13744
13745      if (typeof swidth !== "undefined" && typeof width !== "undefined") {
13746        clipFactorX = width / swidth;
13747        clipFactorY = height / sheight;
13748        factorX = imageProperties.width / swidth * width / swidth;
13749        factorY = imageProperties.height / sheight * height / sheight;
13750      } //is sx and sy are set and x and y not, set x and y with values of sx and sy
13751
13752
13753      if (typeof x === "undefined") {
13754        x = sx;
13755        y = sy;
13756        sx = 0;
13757        sy = 0;
13758      }
13759
13760      if (typeof swidth !== "undefined" && typeof width === "undefined") {
13761        width = swidth;
13762        height = sheight;
13763      }
13764
13765      if (typeof swidth === "undefined" && typeof width === "undefined") {
13766        width = imageProperties.width;
13767        height = imageProperties.height;
13768      }
13769
13770      var decomposedTransformationMatrix = this.ctx.transform.decompose();
13771      var angle = rad2deg(decomposedTransformationMatrix.rotate.shx);
13772      var matrix = new Matrix();
13773      matrix = matrix.multiply(decomposedTransformationMatrix.translate);
13774      matrix = matrix.multiply(decomposedTransformationMatrix.skew);
13775      matrix = matrix.multiply(decomposedTransformationMatrix.scale);
13776      var xRect = matrix.applyToRectangle(new Rectangle(x - sx * clipFactorX, y - sy * clipFactorY, swidth * factorX, sheight * factorY));
13777      var pageArray = getPagesByPath.call(this, xRect);
13778      var pages = [];
13779
13780      for (var ii = 0; ii < pageArray.length; ii += 1) {
13781        if (pages.indexOf(pageArray[ii]) === -1) {
13782          pages.push(pageArray[ii]);
13783        }
13784      }
13785
13786      sortPages(pages);
13787      var clipPath;
13788
13789      if (this.autoPaging) {
13790        var min = pages[0];
13791        var max = pages[pages.length - 1];
13792
13793        for (var i = min; i < max + 1; i++) {
13794          this.pdf.setPage(i);
13795          var pageWidthMinusMargins = this.pdf.internal.pageSize.width - this.margin[3] - this.margin[1];
13796          var topMargin = i === 1 ? this.posY + this.margin[0] : this.margin[0];
13797          var firstPageHeight = this.pdf.internal.pageSize.height - this.posY - this.margin[0] - this.margin[2];
13798          var pageHeightMinusMargins = this.pdf.internal.pageSize.height - this.margin[0] - this.margin[2];
13799          var previousPageHeightSum = i === 1 ? 0 : firstPageHeight + (i - 2) * pageHeightMinusMargins;
13800
13801          if (this.ctx.clip_path.length !== 0) {
13802            var tmpPaths = this.path;
13803            clipPath = JSON.parse(JSON.stringify(this.ctx.clip_path));
13804            this.path = pathPositionRedo(clipPath, this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset);
13805            drawPaths.call(this, "fill", true);
13806            this.path = tmpPaths;
13807          }
13808
13809          var tmpRect = JSON.parse(JSON.stringify(xRect));
13810          tmpRect = pathPositionRedo([tmpRect], this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset)[0];
13811          var needsClipping = (i > min || i < max) && hasMargins.call(this);
13812
13813          if (needsClipping) {
13814            this.pdf.saveGraphicsState();
13815            this.pdf.rect(this.margin[3], this.margin[0], pageWidthMinusMargins, pageHeightMinusMargins, null).clip().discardPath();
13816          }
13817
13818          this.pdf.addImage(img, "JPEG", tmpRect.x, tmpRect.y, tmpRect.w, tmpRect.h, null, null, angle);
13819
13820          if (needsClipping) {
13821            this.pdf.restoreGraphicsState();
13822          }
13823        }
13824      } else {
13825        this.pdf.addImage(img, "JPEG", xRect.x, xRect.y, xRect.w, xRect.h, null, null, angle);
13826      }
13827    };
13828
13829    var getPagesByPath = function getPagesByPath(path, pageWrapX, pageWrapY) {
13830      var result = [];
13831      pageWrapX = pageWrapX || this.pdf.internal.pageSize.width;
13832      pageWrapY = pageWrapY || this.pdf.internal.pageSize.height - this.margin[0] - this.margin[2];
13833      var yOffset = this.posY + this.ctx.prevPageLastElemOffset;
13834
13835      switch (path.type) {
13836        default:
13837        case "mt":
13838        case "lt":
13839          result.push(Math.floor((path.y + yOffset) / pageWrapY) + 1);
13840          break;
13841
13842        case "arc":
13843          result.push(Math.floor((path.y + yOffset - path.radius) / pageWrapY) + 1);
13844          result.push(Math.floor((path.y + yOffset + path.radius) / pageWrapY) + 1);
13845          break;
13846
13847        case "qct":
13848          var rectOfQuadraticCurve = getQuadraticCurveBoundary(this.ctx.lastPoint.x, this.ctx.lastPoint.y, path.x1, path.y1, path.x, path.y);
13849          result.push(Math.floor((rectOfQuadraticCurve.y + yOffset) / pageWrapY) + 1);
13850          result.push(Math.floor((rectOfQuadraticCurve.y + rectOfQuadraticCurve.h + yOffset) / pageWrapY) + 1);
13851          break;
13852
13853        case "bct":
13854          var rectOfBezierCurve = getBezierCurveBoundary(this.ctx.lastPoint.x, this.ctx.lastPoint.y, path.x1, path.y1, path.x2, path.y2, path.x, path.y);
13855          result.push(Math.floor((rectOfBezierCurve.y + yOffset) / pageWrapY) + 1);
13856          result.push(Math.floor((rectOfBezierCurve.y + rectOfBezierCurve.h + yOffset) / pageWrapY) + 1);
13857          break;
13858
13859        case "rect":
13860          result.push(Math.floor((path.y + yOffset) / pageWrapY) + 1);
13861          result.push(Math.floor((path.y + path.h + yOffset) / pageWrapY) + 1);
13862      }
13863
13864      for (var i = 0; i < result.length; i += 1) {
13865        while (this.pdf.internal.getNumberOfPages() < result[i]) {
13866          addPage.call(this);
13867        }
13868      }
13869
13870      return result;
13871    };
13872
13873    var addPage = function addPage() {
13874      var fillStyle = this.fillStyle;
13875      var strokeStyle = this.strokeStyle;
13876      var font = this.font;
13877      var lineCap = this.lineCap;
13878      var lineWidth = this.lineWidth;
13879      var lineJoin = this.lineJoin;
13880      this.pdf.addPage();
13881      this.fillStyle = fillStyle;
13882      this.strokeStyle = strokeStyle;
13883      this.font = font;
13884      this.lineCap = lineCap;
13885      this.lineWidth = lineWidth;
13886      this.lineJoin = lineJoin;
13887    };
13888
13889    var pathPositionRedo = function pathPositionRedo(paths, x, y) {
13890      for (var i = 0; i < paths.length; i++) {
13891        switch (paths[i].type) {
13892          case "bct":
13893            paths[i].x2 += x;
13894            paths[i].y2 += y;
13895
13896          case "qct":
13897            paths[i].x1 += x;
13898            paths[i].y1 += y;
13899
13900          case "mt":
13901          case "lt":
13902          case "arc":
13903          default:
13904            paths[i].x += x;
13905            paths[i].y += y;
13906        }
13907      }
13908
13909      return paths;
13910    };
13911
13912    var sortPages = function sortPages(pages) {
13913      return pages.sort(function (a, b) {
13914        return a - b;
13915      });
13916    };
13917
13918    var pathPreProcess = function pathPreProcess(rule, isClip) {
13919      var fillStyle = this.fillStyle;
13920      var strokeStyle = this.strokeStyle;
13921      var lineCap = this.lineCap;
13922      var oldLineWidth = this.lineWidth;
13923      var lineWidth = Math.abs(oldLineWidth * this.ctx.transform.scaleX);
13924      var lineJoin = this.lineJoin;
13925      var origPath = JSON.parse(JSON.stringify(this.path));
13926      var xPath = JSON.parse(JSON.stringify(this.path));
13927      var clipPath;
13928      var tmpPath;
13929      var pages = [];
13930
13931      for (var i = 0; i < xPath.length; i++) {
13932        if (typeof xPath[i].x !== "undefined") {
13933          var page = getPagesByPath.call(this, xPath[i]);
13934
13935          for (var ii = 0; ii < page.length; ii += 1) {
13936            if (pages.indexOf(page[ii]) === -1) {
13937              pages.push(page[ii]);
13938            }
13939          }
13940        }
13941      }
13942
13943      for (var j = 0; j < pages.length; j++) {
13944        while (this.pdf.internal.getNumberOfPages() < pages[j]) {
13945          addPage.call(this);
13946        }
13947      }
13948
13949      sortPages(pages);
13950
13951      if (this.autoPaging) {
13952        var min = pages[0];
13953        var max = pages[pages.length - 1];
13954
13955        for (var k = min; k < max + 1; k++) {
13956          this.pdf.setPage(k);
13957          this.fillStyle = fillStyle;
13958          this.strokeStyle = strokeStyle;
13959          this.lineCap = lineCap;
13960          this.lineWidth = lineWidth;
13961          this.lineJoin = lineJoin;
13962          var pageWidthMinusMargins = this.pdf.internal.pageSize.width - this.margin[3] - this.margin[1];
13963          var topMargin = k === 1 ? this.posY + this.margin[0] : this.margin[0];
13964          var firstPageHeight = this.pdf.internal.pageSize.height - this.posY - this.margin[0] - this.margin[2];
13965          var pageHeightMinusMargins = this.pdf.internal.pageSize.height - this.margin[0] - this.margin[2];
13966          var previousPageHeightSum = k === 1 ? 0 : firstPageHeight + (k - 2) * pageHeightMinusMargins;
13967
13968          if (this.ctx.clip_path.length !== 0) {
13969            var tmpPaths = this.path;
13970            clipPath = JSON.parse(JSON.stringify(this.ctx.clip_path));
13971            this.path = pathPositionRedo(clipPath, this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset);
13972            drawPaths.call(this, rule, true);
13973            this.path = tmpPaths;
13974          }
13975
13976          tmpPath = JSON.parse(JSON.stringify(origPath));
13977          this.path = pathPositionRedo(tmpPath, this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset);
13978
13979          if (isClip === false || k === 0) {
13980            var needsClipping = (k > min || k < max) && hasMargins.call(this);
13981
13982            if (needsClipping) {
13983              this.pdf.saveGraphicsState();
13984              this.pdf.rect(this.margin[3], this.margin[0], pageWidthMinusMargins, pageHeightMinusMargins, null).clip().discardPath();
13985            }
13986
13987            drawPaths.call(this, rule, isClip);
13988
13989            if (needsClipping) {
13990              this.pdf.restoreGraphicsState();
13991            }
13992          }
13993
13994          this.lineWidth = oldLineWidth;
13995        }
13996      } else {
13997        this.lineWidth = lineWidth;
13998        drawPaths.call(this, rule, isClip);
13999        this.lineWidth = oldLineWidth;
14000      }
14001
14002      this.path = origPath;
14003    };
14004    /**
14005     * Processes the paths
14006     *
14007     * @function
14008     * @param rule {String}
14009     * @param isClip {Boolean}
14010     * @private
14011     * @ignore
14012     */
14013
14014
14015    var drawPaths = function drawPaths(rule, isClip) {
14016      if (rule === "stroke" && !isClip && isStrokeTransparent.call(this)) {
14017        return;
14018      }
14019
14020      if (rule !== "stroke" && !isClip && isFillTransparent.call(this)) {
14021        return;
14022      }
14023
14024      var moves = []; //var alpha = (this.ctx.fillOpacity < 1) ? this.ctx.fillOpacity : this.ctx.globalAlpha;
14025
14026      var delta;
14027      var xPath = this.path;
14028
14029      for (var i = 0; i < xPath.length; i++) {
14030        var pt = xPath[i];
14031
14032        switch (pt.type) {
14033          case "begin":
14034            moves.push({
14035              begin: true
14036            });
14037            break;
14038
14039          case "close":
14040            moves.push({
14041              close: true
14042            });
14043            break;
14044
14045          case "mt":
14046            moves.push({
14047              start: pt,
14048              deltas: [],
14049              abs: []
14050            });
14051            break;
14052
14053          case "lt":
14054            var iii = moves.length;
14055
14056            if (xPath[i - 1] && !isNaN(xPath[i - 1].x)) {
14057              delta = [pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];
14058
14059              if (iii > 0) {
14060                for (iii; iii >= 0; iii--) {
14061                  if (moves[iii - 1].close !== true && moves[iii - 1].begin !== true) {
14062                    moves[iii - 1].deltas.push(delta);
14063                    moves[iii - 1].abs.push(pt);
14064                    break;
14065                  }
14066                }
14067              }
14068            }
14069
14070            break;
14071
14072          case "bct":
14073            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];
14074            moves[moves.length - 1].deltas.push(delta);
14075            break;
14076
14077          case "qct":
14078            var x1 = xPath[i - 1].x + 2.0 / 3.0 * (pt.x1 - xPath[i - 1].x);
14079            var y1 = xPath[i - 1].y + 2.0 / 3.0 * (pt.y1 - xPath[i - 1].y);
14080            var x2 = pt.x + 2.0 / 3.0 * (pt.x1 - pt.x);
14081            var y2 = pt.y + 2.0 / 3.0 * (pt.y1 - pt.y);
14082            var x3 = pt.x;
14083            var y3 = pt.y;
14084            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];
14085            moves[moves.length - 1].deltas.push(delta);
14086            break;
14087
14088          case "arc":
14089            moves.push({
14090              deltas: [],
14091              abs: [],
14092              arc: true
14093            });
14094
14095            if (Array.isArray(moves[moves.length - 1].abs)) {
14096              moves[moves.length - 1].abs.push(pt);
14097            }
14098
14099            break;
14100        }
14101      }
14102
14103      var style;
14104
14105      if (!isClip) {
14106        if (rule === "stroke") {
14107          style = "stroke";
14108        } else {
14109          style = "fill";
14110        }
14111      } else {
14112        style = null;
14113      }
14114
14115      var began = false;
14116
14117      for (var k = 0; k < moves.length; k++) {
14118        if (moves[k].arc) {
14119          var arcs = moves[k].abs;
14120
14121          for (var ii = 0; ii < arcs.length; ii++) {
14122            var arc = arcs[ii];
14123
14124            if (arc.type === "arc") {
14125              drawArc.call(this, arc.x, arc.y, arc.radius, arc.startAngle, arc.endAngle, arc.counterclockwise, undefined, isClip, !began);
14126            } else {
14127              drawLine.call(this, arc.x, arc.y);
14128            }
14129
14130            began = true;
14131          }
14132        } else if (moves[k].close === true) {
14133          this.pdf.internal.out("h");
14134          began = false;
14135        } else if (moves[k].begin !== true) {
14136          var x = moves[k].start.x;
14137          var y = moves[k].start.y;
14138          drawLines.call(this, moves[k].deltas, x, y);
14139          began = true;
14140        }
14141      }
14142
14143      if (style) {
14144        putStyle.call(this, style);
14145      }
14146
14147      if (isClip) {
14148        doClip.call(this);
14149      }
14150    };
14151
14152    var getBaseline = function getBaseline(y) {
14153      var height = this.pdf.internal.getFontSize() / this.pdf.internal.scaleFactor;
14154      var descent = height * (this.pdf.internal.getLineHeightFactor() - 1);
14155
14156      switch (this.ctx.textBaseline) {
14157        case "bottom":
14158          return y - descent;
14159
14160        case "top":
14161          return y + height - descent;
14162
14163        case "hanging":
14164          return y + height - 2 * descent;
14165
14166        case "middle":
14167          return y + height / 2 - descent;
14168
14169        case "ideographic":
14170          // TODO not implemented
14171          return y;
14172
14173        case "alphabetic":
14174        default:
14175          return y;
14176      }
14177    };
14178
14179    var getTextBottom = function getTextBottom(yBaseLine) {
14180      var height = this.pdf.internal.getFontSize() / this.pdf.internal.scaleFactor;
14181      var descent = height * (this.pdf.internal.getLineHeightFactor() - 1);
14182      return yBaseLine + descent;
14183    };
14184
14185    Context2D.prototype.createLinearGradient = function createLinearGradient() {
14186      var canvasGradient = function canvasGradient() {};
14187
14188      canvasGradient.colorStops = [];
14189
14190      canvasGradient.addColorStop = function (offset, color) {
14191        this.colorStops.push([offset, color]);
14192      };
14193
14194      canvasGradient.getColor = function () {
14195        if (this.colorStops.length === 0) {
14196          return "#000000";
14197        }
14198
14199        return this.colorStops[0][1];
14200      };
14201
14202      canvasGradient.isCanvasGradient = true;
14203      return canvasGradient;
14204    };
14205
14206    Context2D.prototype.createPattern = function createPattern() {
14207      return this.createLinearGradient();
14208    };
14209
14210    Context2D.prototype.createRadialGradient = function createRadialGradient() {
14211      return this.createLinearGradient();
14212    };
14213    /**
14214     *
14215     * @param x Edge point X
14216     * @param y Edge point Y
14217     * @param r Radius
14218     * @param a1 start angle
14219     * @param a2 end angle
14220     * @param counterclockwise
14221     * @param style
14222     * @param isClip
14223     */
14224
14225
14226    var drawArc = function drawArc(x, y, r, a1, a2, counterclockwise, style, isClip, includeMove) {
14227      // http://hansmuller-flex.blogspot.com/2011/10/more-about-approximating-circular-arcs.html
14228      var curves = createArc.call(this, r, a1, a2, counterclockwise);
14229
14230      for (var i = 0; i < curves.length; i++) {
14231        var curve = curves[i];
14232
14233        if (i === 0) {
14234          if (includeMove) {
14235            doMove.call(this, curve.x1 + x, curve.y1 + y);
14236          } else {
14237            drawLine.call(this, curve.x1 + x, curve.y1 + y);
14238          }
14239        }
14240
14241        drawCurve.call(this, x, y, curve.x2, curve.y2, curve.x3, curve.y3, curve.x4, curve.y4);
14242      }
14243
14244      if (!isClip) {
14245        putStyle.call(this, style);
14246      } else {
14247        doClip.call(this);
14248      }
14249    };
14250
14251    var putStyle = function putStyle(style) {
14252      switch (style) {
14253        case "stroke":
14254          this.pdf.internal.out("S");
14255          break;
14256
14257        case "fill":
14258          this.pdf.internal.out("f");
14259          break;
14260      }
14261    };
14262
14263    var doClip = function doClip() {
14264      this.pdf.clip();
14265      this.pdf.discardPath();
14266    };
14267
14268    var doMove = function doMove(x, y) {
14269      this.pdf.internal.out(getHorizontalCoordinateString(x) + " " + getVerticalCoordinateString(y) + " m");
14270    };
14271
14272    var putText = function putText(options) {
14273      var textAlign;
14274
14275      switch (options.align) {
14276        case "right":
14277        case "end":
14278          textAlign = "right";
14279          break;
14280
14281        case "center":
14282          textAlign = "center";
14283          break;
14284
14285        case "left":
14286        case "start":
14287        default:
14288          textAlign = "left";
14289          break;
14290      }
14291
14292      var textDimensions = this.pdf.getTextDimensions(options.text);
14293      var yBaseLine = getBaseline.call(this, options.y);
14294      var yBottom = getTextBottom.call(this, yBaseLine);
14295      var yTop = yBottom - textDimensions.h;
14296      var pt = this.ctx.transform.applyToPoint(new Point(options.x, yBaseLine));
14297      var decomposedTransformationMatrix = this.ctx.transform.decompose();
14298      var matrix = new Matrix();
14299      matrix = matrix.multiply(decomposedTransformationMatrix.translate);
14300      matrix = matrix.multiply(decomposedTransformationMatrix.skew);
14301      matrix = matrix.multiply(decomposedTransformationMatrix.scale);
14302      var baselineRect = this.ctx.transform.applyToRectangle(new Rectangle(options.x, yBaseLine, textDimensions.w, textDimensions.h));
14303      var textBounds = matrix.applyToRectangle(new Rectangle(options.x, yTop, textDimensions.w, textDimensions.h));
14304      var pageArray = getPagesByPath.call(this, textBounds);
14305      var pages = [];
14306
14307      for (var ii = 0; ii < pageArray.length; ii += 1) {
14308        if (pages.indexOf(pageArray[ii]) === -1) {
14309          pages.push(pageArray[ii]);
14310        }
14311      }
14312
14313      sortPages(pages);
14314      var clipPath, oldSize, oldLineWidth;
14315
14316      if (this.autoPaging) {
14317        var min = pages[0];
14318        var max = pages[pages.length - 1];
14319
14320        for (var i = min; i < max + 1; i++) {
14321          this.pdf.setPage(i);
14322          var topMargin = i === 1 ? this.posY + this.margin[0] : this.margin[0];
14323          var firstPageHeight = this.pdf.internal.pageSize.height - this.posY - this.margin[0] - this.margin[2];
14324          var pageHeightMinusBottomMargin = this.pdf.internal.pageSize.height - this.margin[2];
14325          var pageHeightMinusMargins = pageHeightMinusBottomMargin - this.margin[0];
14326          var pageWidthMinusRightMargin = this.pdf.internal.pageSize.width - this.margin[1];
14327          var pageWidthMinusMargins = pageWidthMinusRightMargin - this.margin[3];
14328          var previousPageHeightSum = i === 1 ? 0 : firstPageHeight + (i - 2) * pageHeightMinusMargins;
14329
14330          if (this.ctx.clip_path.length !== 0) {
14331            var tmpPaths = this.path;
14332            clipPath = JSON.parse(JSON.stringify(this.ctx.clip_path));
14333            this.path = pathPositionRedo(clipPath, this.posX + this.margin[3], -1 * previousPageHeightSum + topMargin);
14334            drawPaths.call(this, "fill", true);
14335            this.path = tmpPaths;
14336          }
14337
14338          var textBoundsOnPage = pathPositionRedo([JSON.parse(JSON.stringify(textBounds))], this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset)[0];
14339
14340          if (options.scale >= 0.01) {
14341            oldSize = this.pdf.internal.getFontSize();
14342            this.pdf.setFontSize(oldSize * options.scale);
14343            oldLineWidth = this.lineWidth;
14344            this.lineWidth = oldLineWidth * options.scale;
14345          }
14346
14347          var doSlice = this.autoPaging !== "text";
14348
14349          if (doSlice || textBoundsOnPage.y + textBoundsOnPage.h <= pageHeightMinusBottomMargin) {
14350            if (doSlice || textBoundsOnPage.y >= topMargin && textBoundsOnPage.x <= pageWidthMinusRightMargin) {
14351              var croppedText = doSlice ? options.text : this.pdf.splitTextToSize(options.text, options.maxWidth || pageWidthMinusRightMargin - textBoundsOnPage.x)[0];
14352              var baseLineRectOnPage = pathPositionRedo([JSON.parse(JSON.stringify(baselineRect))], this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset)[0];
14353              var needsClipping = doSlice && (i > min || i < max) && hasMargins.call(this);
14354
14355              if (needsClipping) {
14356                this.pdf.saveGraphicsState();
14357                this.pdf.rect(this.margin[3], this.margin[0], pageWidthMinusMargins, pageHeightMinusMargins, null).clip().discardPath();
14358              }
14359
14360              this.pdf.text(croppedText, baseLineRectOnPage.x, baseLineRectOnPage.y, {
14361                angle: options.angle,
14362                align: textAlign,
14363                renderingMode: options.renderingMode
14364              });
14365
14366              if (needsClipping) {
14367                this.pdf.restoreGraphicsState();
14368              }
14369            }
14370          } else {
14371            // This text is the last element of the page, but it got cut off due to the margin
14372            // so we render it in the next page
14373            if (textBoundsOnPage.y < pageHeightMinusBottomMargin) {
14374              // As a result, all other elements have their y offset increased
14375              this.ctx.prevPageLastElemOffset += pageHeightMinusBottomMargin - textBoundsOnPage.y;
14376            }
14377          }
14378
14379          if (options.scale >= 0.01) {
14380            this.pdf.setFontSize(oldSize);
14381            this.lineWidth = oldLineWidth;
14382          }
14383        }
14384      } else {
14385        if (options.scale >= 0.01) {
14386          oldSize = this.pdf.internal.getFontSize();
14387          this.pdf.setFontSize(oldSize * options.scale);
14388          oldLineWidth = this.lineWidth;
14389          this.lineWidth = oldLineWidth * options.scale;
14390        }
14391
14392        this.pdf.text(options.text, pt.x + this.posX, pt.y + this.posY, {
14393          angle: options.angle,
14394          align: textAlign,
14395          renderingMode: options.renderingMode,
14396          maxWidth: options.maxWidth
14397        });
14398
14399        if (options.scale >= 0.01) {
14400          this.pdf.setFontSize(oldSize);
14401          this.lineWidth = oldLineWidth;
14402        }
14403      }
14404    };
14405
14406    var drawLine = function drawLine(x, y, prevX, prevY) {
14407      prevX = prevX || 0;
14408      prevY = prevY || 0;
14409      this.pdf.internal.out(getHorizontalCoordinateString(x + prevX) + " " + getVerticalCoordinateString(y + prevY) + " l");
14410    };
14411
14412    var drawLines = function drawLines(lines, x, y) {
14413      return this.pdf.lines(lines, x, y, null, null);
14414    };
14415
14416    var drawCurve = function drawCurve(x, y, x1, y1, x2, y2, x3, y3) {
14417      this.pdf.internal.out([f2(getHorizontalCoordinate(x1 + x)), f2(getVerticalCoordinate(y1 + y)), f2(getHorizontalCoordinate(x2 + x)), f2(getVerticalCoordinate(y2 + y)), f2(getHorizontalCoordinate(x3 + x)), f2(getVerticalCoordinate(y3 + y)), "c"].join(" "));
14418    };
14419    /**
14420     * 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.
14421     *
14422     * 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.
14423     * @function createArc
14424     */
14425
14426
14427    var createArc = function createArc(radius, startAngle, endAngle, anticlockwise) {
14428      var EPSILON = 0.00001; // Roughly 1/1000th of a degree, see below
14429
14430      var twoPi = Math.PI * 2;
14431      var halfPi = Math.PI / 2.0;
14432
14433      while (startAngle > endAngle) {
14434        startAngle = startAngle - twoPi;
14435      }
14436
14437      var totalAngle = Math.abs(endAngle - startAngle);
14438
14439      if (totalAngle < twoPi) {
14440        if (anticlockwise) {
14441          totalAngle = twoPi - totalAngle;
14442        }
14443      } // Compute the sequence of arc curves, up to PI/2 at a time.
14444
14445
14446      var curves = []; // clockwise or counterclockwise
14447
14448      var sgn = anticlockwise ? -1 : +1;
14449      var a1 = startAngle;
14450
14451      for (; totalAngle > EPSILON;) {
14452        var remain = sgn * Math.min(totalAngle, halfPi);
14453        var a2 = a1 + remain;
14454        curves.push(createSmallArc.call(this, radius, a1, a2));
14455        totalAngle -= Math.abs(a2 - a1);
14456        a1 = a2;
14457      }
14458
14459      return curves;
14460    };
14461    /**
14462     * 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.
14463     *
14464     * 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.
14465     *
14466     * 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.
14467     */
14468
14469
14470    var createSmallArc = function createSmallArc(r, a1, a2) {
14471      var a = (a2 - a1) / 2.0;
14472      var x4 = r * Math.cos(a);
14473      var y4 = r * Math.sin(a);
14474      var x1 = x4;
14475      var y1 = -y4;
14476      var q1 = x1 * x1 + y1 * y1;
14477      var q2 = q1 + x1 * x4 + y1 * y4;
14478      var k2 = 4 / 3 * (Math.sqrt(2 * q1 * q2) - q2) / (x1 * y4 - y1 * x4);
14479      var x2 = x1 - k2 * y1;
14480      var y2 = y1 + k2 * x1;
14481      var x3 = x2;
14482      var y3 = -y2;
14483      var ar = a + a1;
14484      var cos_ar = Math.cos(ar);
14485      var sin_ar = Math.sin(ar);
14486      return {
14487        x1: r * Math.cos(a1),
14488        y1: r * Math.sin(a1),
14489        x2: x2 * cos_ar - y2 * sin_ar,
14490        y2: x2 * sin_ar + y2 * cos_ar,
14491        x3: x3 * cos_ar - y3 * sin_ar,
14492        y3: x3 * sin_ar + y3 * cos_ar,
14493        x4: r * Math.cos(a2),
14494        y4: r * Math.sin(a2)
14495      };
14496    };
14497
14498    var rad2deg = function rad2deg(value) {
14499      return value * 180 / Math.PI;
14500    };
14501
14502    var getQuadraticCurveBoundary = function getQuadraticCurveBoundary(sx, sy, cpx, cpy, ex, ey) {
14503      var midX1 = sx + (cpx - sx) * 0.5;
14504      var midY1 = sy + (cpy - sy) * 0.5;
14505      var midX2 = ex + (cpx - ex) * 0.5;
14506      var midY2 = ey + (cpy - ey) * 0.5;
14507      var resultX1 = Math.min(sx, ex, midX1, midX2);
14508      var resultX2 = Math.max(sx, ex, midX1, midX2);
14509      var resultY1 = Math.min(sy, ey, midY1, midY2);
14510      var resultY2 = Math.max(sy, ey, midY1, midY2);
14511      return new Rectangle(resultX1, resultY1, resultX2 - resultX1, resultY2 - resultY1);
14512    }; //De Casteljau algorithm
14513
14514
14515    var getBezierCurveBoundary = function getBezierCurveBoundary(ax, ay, bx, by, cx, cy, dx, dy) {
14516      var tobx = bx - ax;
14517      var toby = by - ay;
14518      var tocx = cx - bx;
14519      var tocy = cy - by;
14520      var todx = dx - cx;
14521      var tody = dy - cy;
14522      var precision = 40;
14523      var d, i, px, py, qx, qy, rx, ry, tx, ty, sx, sy, x, y, minx, miny, maxx, maxy, toqx, toqy, torx, tory, totx, toty;
14524
14525      for (i = 0; i < precision + 1; i++) {
14526        d = i / precision;
14527        px = ax + d * tobx;
14528        py = ay + d * toby;
14529        qx = bx + d * tocx;
14530        qy = by + d * tocy;
14531        rx = cx + d * todx;
14532        ry = cy + d * tody;
14533        toqx = qx - px;
14534        toqy = qy - py;
14535        torx = rx - qx;
14536        tory = ry - qy;
14537        sx = px + d * toqx;
14538        sy = py + d * toqy;
14539        tx = qx + d * torx;
14540        ty = qy + d * tory;
14541        totx = tx - sx;
14542        toty = ty - sy;
14543        x = sx + d * totx;
14544        y = sy + d * toty;
14545
14546        if (i == 0) {
14547          minx = x;
14548          miny = y;
14549          maxx = x;
14550          maxy = y;
14551        } else {
14552          minx = Math.min(minx, x);
14553          miny = Math.min(miny, y);
14554          maxx = Math.max(maxx, x);
14555          maxy = Math.max(maxy, y);
14556        }
14557      }
14558
14559      return new Rectangle(Math.round(minx), Math.round(miny), Math.round(maxx - minx), Math.round(maxy - miny));
14560    };
14561
14562    var getPrevLineDashValue = function getPrevLineDashValue(lineDash, lineDashOffset) {
14563      return JSON.stringify({
14564        lineDash: lineDash,
14565        lineDashOffset: lineDashOffset
14566      });
14567    };
14568
14569    var setLineDash = function setLineDash() {
14570      // Avoid unnecessary line dash declarations.
14571      if (!this.prevLineDash && !this.ctx.lineDash.length && !this.ctx.lineDashOffset) {
14572        return;
14573      } // Avoid unnecessary line dash declarations.
14574
14575
14576      var nextLineDash = getPrevLineDashValue(this.ctx.lineDash, this.ctx.lineDashOffset);
14577
14578      if (this.prevLineDash !== nextLineDash) {
14579        this.pdf.setLineDash(this.ctx.lineDash, this.ctx.lineDashOffset);
14580        this.prevLineDash = nextLineDash;
14581      }
14582    };
14583  })(jsPDF.API);
14584
14585  // DEFLATE is a complex format; to read this code, you should probably check the RFC first:
14586  // https://tools.ietf.org/html/rfc1951
14587  // You may also wish to take a look at the guide I made about this program:
14588  // https://gist.github.com/101arrowz/253f31eb5abc3d9275ab943003ffecad
vendor: 22,879 bytes, lines 14589-15422
14589  // Much of the following code is similar to that of UZIP.js:
14590  // https://github.com/photopea/UZIP.js
14591  // Many optimizations have been made, so the bundle size is ultimately smaller but performance is similar.
14592  // Sometimes 0 will appear where -1 would be more appropriate. This is because using a uint
14593  // is better for memory in most engines (I *think*).
14594  // Mediocre shim
14595  var Worker;
14596
14597  try {
14598    Worker = require('worker_threads').Worker;
14599  } catch (e) {}
14600
14601  var u8 = Uint8Array,
14602      u16 = Uint16Array,
14603      u32 = Uint32Array; // fixed length extra bits
14604
14605  var fleb = new u8([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,
14606  /* unused */
14607  0, 0,
14608  /* impossible */
14609  0]); // fixed distance extra bits
14610  // see fleb note
14611
14612  var fdeb = new u8([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,
14613  /* unused */
14614  0, 0]); // code length index map
14615
14616  var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]); // get base, reverse index map from extra bits
14617
14618  var freb = function (eb, start) {
14619    var b = new u16(31);
14620
14621    for (var i = 0; i < 31; ++i) {
14622      b[i] = start += 1 << eb[i - 1];
14623    } // numbers here are at max 18 bits
14624
14625
14626    var r = new u32(b[30]);
14627
14628    for (var i = 1; i < 30; ++i) {
14629      for (var j = b[i]; j < b[i + 1]; ++j) {
14630        r[j] = j - b[i] << 5 | i;
14631      }
14632    }
14633
14634    return [b, r];
14635  };
14636
14637  var _a = freb(fleb, 2),
14638      fl = _a[0],
14639      revfl = _a[1]; // we can ignore the fact that the other numbers are wrong; they never happen anyway
14640
14641
14642  fl[28] = 258, revfl[258] = 28;
14643
14644  var _b = freb(fdeb, 0),
14645      fd = _b[0],
14646      revfd = _b[1]; // map of value to reverse (assuming 16 bits)
14647
14648
14649  var rev = new u16(32768);
14650
14651  for (var i = 0; i < 32768; ++i) {
14652    // reverse table algorithm from SO
14653    var x = (i & 0xAAAA) >>> 1 | (i & 0x5555) << 1;
14654    x = (x & 0xCCCC) >>> 2 | (x & 0x3333) << 2;
14655    x = (x & 0xF0F0) >>> 4 | (x & 0x0F0F) << 4;
14656    rev[i] = ((x & 0xFF00) >>> 8 | (x & 0x00FF) << 8) >>> 1;
14657  } // create huffman tree from u8 "map": index -> code length for code index
14658  // mb (max bits) must be at most 15
14659  // TODO: optimize/split up?
14660
14661
14662  var hMap = function (cd, mb, r) {
14663    var s = cd.length; // index
14664
14665    var i = 0; // u16 "map": index -> # of codes with bit length = index
14666
14667    var l = new u16(mb); // length of cd must be 288 (total # of codes)
14668
14669    for (; i < s; ++i) ++l[cd[i] - 1]; // u16 "map": index -> minimum code for bit length = index
14670
14671
14672    var le = new u16(mb);
14673
14674    for (i = 0; i < mb; ++i) {
14675      le[i] = le[i - 1] + l[i - 1] << 1;
14676    }
14677
14678    var co;
14679
14680    if (r) {
14681      // u16 "map": index -> number of actual bits, symbol for code
14682      co = new u16(1 << mb); // bits to remove for reverser
14683
14684      var rvb = 15 - mb;
14685
14686      for (i = 0; i < s; ++i) {
14687        // ignore 0 lengths
14688        if (cd[i]) {
14689          // num encoding both symbol and bits read
14690          var sv = i << 4 | cd[i]; // free bits
14691
14692          var r_1 = mb - cd[i]; // start value
14693
14694          var v = le[cd[i] - 1]++ << r_1; // m is end value
14695
14696          for (var m = v | (1 << r_1) - 1; v <= m; ++v) {
14697            // every 16 bit value starting with the code yields the same result
14698            co[rev[v] >>> rvb] = sv;
14699          }
14700        }
14701      }
14702    } else {
14703      co = new u16(s);
14704
14705      for (i = 0; i < s; ++i) co[i] = rev[le[cd[i] - 1]++] >>> 15 - cd[i];
14706    }
14707
14708    return co;
14709  }; // fixed length tree
14710
14711
14712  var flt = new u8(288);
14713
14714  for (var i = 0; i < 144; ++i) flt[i] = 8;
14715
14716  for (var i = 144; i < 256; ++i) flt[i] = 9;
14717
14718  for (var i = 256; i < 280; ++i) flt[i] = 7;
14719
14720  for (var i = 280; i < 288; ++i) flt[i] = 8; // fixed distance tree
14721
14722
14723  var fdt = new u8(32);
14724
14725  for (var i = 0; i < 32; ++i) fdt[i] = 5; // fixed length map
14726
14727
14728  var flm = /*#__PURE__*/hMap(flt, 9, 0),
14729      flrm = /*#__PURE__*/hMap(flt, 9, 1); // fixed distance map
14730
14731  var fdm = /*#__PURE__*/hMap(fdt, 5, 0),
14732      fdrm = /*#__PURE__*/hMap(fdt, 5, 1); // find max of array
14733
14734  var max = function (a) {
14735    var m = a[0];
14736
14737    for (var i = 1; i < a.length; ++i) {
14738      if (a[i] > m) m = a[i];
14739    }
14740
14741    return m;
14742  }; // read d, starting at bit p and mask with m
14743
14744
14745  var bits = function (d, p, m) {
14746    var o = p / 8 >> 0;
14747    return (d[o] | d[o + 1] << 8) >>> (p & 7) & m;
14748  }; // read d, starting at bit p continuing for at least 16 bits
14749
14750
14751  var bits16 = function (d, p) {
14752    var o = p / 8 >> 0;
14753    return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >>> (p & 7);
14754  }; // get end of byte
14755
14756
14757  var shft = function (p) {
14758    return (p / 8 >> 0) + (p & 7 && 1);
14759  }; // typed array slice - allows garbage collector to free original reference,
14760  // while being more compatible than .slice
14761
14762
14763  var slc = function (v, s, e) {
14764    if (s == null || s < 0) s = 0;
14765    if (e == null || e > v.length) e = v.length; // can't use .constructor in case user-supplied
14766
14767    var n = new (v instanceof u16 ? u16 : v instanceof u32 ? u32 : u8)(e - s);
14768    n.set(v.subarray(s, e));
14769    return n;
14770  }; // expands raw DEFLATE data
14771
14772
14773  var inflt = function (dat, buf, st) {
14774    // source length
14775    var sl = dat.length; // have to estimate size
14776
14777    var noBuf = !buf || st; // no state
14778
14779    var noSt = !st || st.i;
14780    if (!st) st = {}; // Assumes roughly 33% compression ratio average
14781
14782    if (!buf) buf = new u8(sl * 3); // ensure buffer can fit at least l elements
14783
14784    var cbuf = function (l) {
14785      var bl = buf.length; // need to increase size to fit
14786
14787      if (l > bl) {
14788        // Double or set to necessary, whichever is greater
14789        var nbuf = new u8(Math.max(bl * 2, l));
14790        nbuf.set(buf);
14791        buf = nbuf;
14792      }
14793    }; //  last chunk         bitpos           bytes
14794
14795
14796    var final = st.f || 0,
14797        pos = st.p || 0,
14798        bt = st.b || 0,
14799        lm = st.l,
14800        dm = st.d,
14801        lbt = st.m,
14802        dbt = st.n; // total bits
14803
14804    var tbts = sl * 8;
14805
14806    do {
14807      if (!lm) {
14808        // BFINAL - this is only 1 when last chunk is next
14809        st.f = final = bits(dat, pos, 1); // type: 0 = no compression, 1 = fixed huffman, 2 = dynamic huffman
14810
14811        var type = bits(dat, pos + 1, 3);
14812        pos += 3;
14813
14814        if (!type) {
14815          // go to end of byte boundary
14816          var s = shft(pos) + 4,
14817              l = dat[s - 4] | dat[s - 3] << 8,
14818              t = s + l;
14819
14820          if (t > sl) {
14821            if (noSt) throw 'unexpected EOF';
14822            break;
14823          } // ensure size
14824
14825
14826          if (noBuf) cbuf(bt + l); // Copy over uncompressed data
14827
14828          buf.set(dat.subarray(s, t), bt); // Get new bitpos, update byte count
14829
14830          st.b = bt += l, st.p = pos = t * 8;
14831          continue;
14832        } else if (type == 1) lm = flrm, dm = fdrm, lbt = 9, dbt = 5;else if (type == 2) {
14833          //  literal                            lengths
14834          var hLit = bits(dat, pos, 31) + 257,
14835              hcLen = bits(dat, pos + 10, 15) + 4;
14836          var tl = hLit + bits(dat, pos + 5, 31) + 1;
14837          pos += 14; // length+distance tree
14838
14839          var ldt = new u8(tl); // code length tree
14840
14841          var clt = new u8(19);
14842
14843          for (var i = 0; i < hcLen; ++i) {
14844            // use index map to get real code
14845            clt[clim[i]] = bits(dat, pos + i * 3, 7);
14846          }
14847
14848          pos += hcLen * 3; // code lengths bits
14849
14850          var clb = max(clt),
14851              clbmsk = (1 << clb) - 1;
14852          if (!noSt && pos + tl * (clb + 7) > tbts) break; // code lengths map
14853
14854          var clm = hMap(clt, clb, 1);
14855
14856          for (var i = 0; i < tl;) {
14857            var r = clm[bits(dat, pos, clbmsk)]; // bits read
14858
14859            pos += r & 15; // symbol
14860
14861            var s = r >>> 4; // code length to copy
14862
14863            if (s < 16) {
14864              ldt[i++] = s;
14865            } else {
14866              //  copy   count
14867              var c = 0,
14868                  n = 0;
14869              if (s == 16) n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];else if (s == 17) n = 3 + bits(dat, pos, 7), pos += 3;else if (s == 18) n = 11 + bits(dat, pos, 127), pos += 7;
14870
14871              while (n--) ldt[i++] = c;
14872            }
14873          } //    length tree                 distance tree
14874
14875
14876          var lt = ldt.subarray(0, hLit),
14877              dt = ldt.subarray(hLit); // max length bits
14878
14879          lbt = max(lt); // max dist bits
14880
14881          dbt = max(dt);
14882          lm = hMap(lt, lbt, 1);
14883          dm = hMap(dt, dbt, 1);
14884        } else throw 'invalid block type';
14885
14886        if (pos > tbts) throw 'unexpected EOF';
14887      } // Make sure the buffer can hold this + the largest possible addition
14888      // Maximum chunk size (practically, theoretically infinite) is 2^17;
14889
14890
14891      if (noBuf) cbuf(bt + 131072);
14892      var lms = (1 << lbt) - 1,
14893          dms = (1 << dbt) - 1;
14894      var mxa = lbt + dbt + 18;
14895
14896      while (noSt || pos + mxa < tbts) {
14897        // bits read, code
14898        var c = lm[bits16(dat, pos) & lms],
14899            sym = c >>> 4;
14900        pos += c & 15;
14901        if (pos > tbts) throw 'unexpected EOF';
14902        if (!c) throw 'invalid length/literal';
14903        if (sym < 256) buf[bt++] = sym;else if (sym == 256) {
14904          lm = null;
14905          break;
14906        } else {
14907          var add = sym - 254; // no extra bits needed if less
14908
14909          if (sym > 264) {
14910            // index
14911            var i = sym - 257,
14912                b = fleb[i];
14913            add = bits(dat, pos, (1 << b) - 1) + fl[i];
14914            pos += b;
14915          } // dist
14916
14917
14918          var d = dm[bits16(dat, pos) & dms],
14919              dsym = d >>> 4;
14920          if (!d) throw 'invalid distance';
14921          pos += d & 15;
14922          var dt = fd[dsym];
14923
14924          if (dsym > 3) {
14925            var b = fdeb[dsym];
14926            dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
14927          }
14928
14929          if (pos > tbts) throw 'unexpected EOF';
14930          if (noBuf) cbuf(bt + 131072);
14931          var end = bt + add;
14932
14933          for (; bt < end; bt += 4) {
14934            buf[bt] = buf[bt - dt];
14935            buf[bt + 1] = buf[bt + 1 - dt];
14936            buf[bt + 2] = buf[bt + 2 - dt];
14937            buf[bt + 3] = buf[bt + 3 - dt];
14938          }
14939
14940          bt = end;
14941        }
14942      }
14943
14944      st.l = lm, st.p = pos, st.b = bt;
14945      if (lm) final = 1, st.m = lbt, st.d = dm, st.n = dbt;
14946    } while (!final);
14947
14948    return bt == buf.length ? buf : slc(buf, 0, bt);
14949  }; // starting at p, write the minimum number of bits that can hold v to d
14950
14951
14952  var wbits = function (d, p, v) {
14953    v <<= p & 7;
14954    var o = p / 8 >> 0;
14955    d[o] |= v;
14956    d[o + 1] |= v >>> 8;
14957  }; // starting at p, write the minimum number of bits (>8) that can hold v to d
14958
14959
14960  var wbits16 = function (d, p, v) {
14961    v <<= p & 7;
14962    var o = p / 8 >> 0;
14963    d[o] |= v;
14964    d[o + 1] |= v >>> 8;
14965    d[o + 2] |= v >>> 16;
14966  }; // creates code lengths from a frequency table
14967
14968
14969  var hTree = function (d, mb) {
14970    // Need extra info to make a tree
14971    var t = [];
14972
14973    for (var i = 0; i < d.length; ++i) {
14974      if (d[i]) t.push({
14975        s: i,
14976        f: d[i]
14977      });
14978    }
14979
14980    var s = t.length;
14981    var t2 = t.slice();
14982    if (!s) return [new u8(0), 0];
14983
14984    if (s == 1) {
14985      var v = new u8(t[0].s + 1);
14986      v[t[0].s] = 1;
14987      return [v, 1];
14988    }
14989
14990    t.sort(function (a, b) {
14991      return a.f - b.f;
14992    }); // after i2 reaches last ind, will be stopped
14993    // freq must be greater than largest possible number of symbols
14994
14995    t.push({
14996      s: -1,
14997      f: 25001
14998    });
14999    var l = t[0],
15000        r = t[1],
15001        i0 = 0,
15002        i1 = 1,
15003        i2 = 2;
15004    t[0] = {
15005      s: -1,
15006      f: l.f + r.f,
15007      l: l,
15008      r: r
15009    }; // efficient algorithm from UZIP.js
15010    // i0 is lookbehind, i2 is lookahead - after processing two low-freq
15011    // symbols that combined have high freq, will start processing i2 (high-freq,
15012    // non-composite) symbols instead
15013    // see https://reddit.com/r/photopea/comments/ikekht/uzipjs_questions/
15014
15015    while (i1 != s - 1) {
15016      l = t[t[i0].f < t[i2].f ? i0++ : i2++];
15017      r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++];
15018      t[i1++] = {
15019        s: -1,
15020        f: l.f + r.f,
15021        l: l,
15022        r: r
15023      };
15024    }
15025
15026    var maxSym = t2[0].s;
15027
15028    for (var i = 1; i < s; ++i) {
15029      if (t2[i].s > maxSym) maxSym = t2[i].s;
15030    } // code lengths
15031
15032
15033    var tr = new u16(maxSym + 1); // max bits in tree
15034
15035    var mbt = ln(t[i1 - 1], tr, 0);
15036
15037    if (mbt > mb) {
15038      // more algorithms from UZIP.js
15039      // TODO: find out how this code works (debt)
15040      //  ind    debt
15041      var i = 0,
15042          dt = 0; //    left            cost
15043
15044      var lft = mbt - mb,
15045          cst = 1 << lft;
15046      t2.sort(function (a, b) {
15047        return tr[b.s] - tr[a.s] || a.f - b.f;
15048      });
15049
15050      for (; i < s; ++i) {
15051        var i2_1 = t2[i].s;
15052
15053        if (tr[i2_1] > mb) {
15054          dt += cst - (1 << mbt - tr[i2_1]);
15055          tr[i2_1] = mb;
15056        } else break;
15057      }
15058
15059      dt >>>= lft;
15060
15061      while (dt > 0) {
15062        var i2_2 = t2[i].s;
15063        if (tr[i2_2] < mb) dt -= 1 << mb - tr[i2_2]++ - 1;else ++i;
15064      }
15065
15066      for (; i >= 0 && dt; --i) {
15067        var i2_3 = t2[i].s;
15068
15069        if (tr[i2_3] == mb) {
15070          --tr[i2_3];
15071          ++dt;
15072        }
15073      }
15074
15075      mbt = mb;
15076    }
15077
15078    return [new u8(tr), mbt];
15079  }; // get the max length and assign length codes
15080
15081
15082  var ln = function (n, l, d) {
15083    return n.s == -1 ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1)) : l[n.s] = d;
15084  }; // length codes generation
15085
15086
15087  var lc = function (c) {
15088    var s = c.length; // Note that the semicolon was intentional
15089
15090    while (s && !c[--s]);
15091
15092    var cl = new u16(++s); //  ind      num         streak
15093
15094    var cli = 0,
15095        cln = c[0],
15096        cls = 1;
15097
15098    var w = function (v) {
15099      cl[cli++] = v;
15100    };
15101
15102    for (var i = 1; i <= s; ++i) {
15103      if (c[i] == cln && i != s) ++cls;else {
15104        if (!cln && cls > 2) {
15105          for (; cls > 138; cls -= 138) w(32754);
15106
15107          if (cls > 2) {
15108            w(cls > 10 ? cls - 11 << 5 | 28690 : cls - 3 << 5 | 12305);
15109            cls = 0;
15110          }
15111        } else if (cls > 3) {
15112          w(cln), --cls;
15113
15114          for (; cls > 6; cls -= 6) w(8304);
15115
15116          if (cls > 2) w(cls - 3 << 5 | 8208), cls = 0;
15117        }
15118
15119        while (cls--) w(cln);
15120
15121        cls = 1;
15122        cln = c[i];
15123      }
15124    }
15125
15126    return [cl.subarray(0, cli), s];
15127  }; // calculate the length of output from tree, code lengths
15128
15129
15130  var clen = function (cf, cl) {
15131    var l = 0;
15132
15133    for (var i = 0; i < cl.length; ++i) l += cf[i] * cl[i];
15134
15135    return l;
15136  }; // writes a fixed block
15137  // returns the new bit pos
15138
15139
15140  var wfblk = function (out, pos, dat) {
15141    // no need to write 00 as type: TypedArray defaults to 0
15142    var s = dat.length;
15143    var o = shft(pos + 2);
15144    out[o] = s & 255;
15145    out[o + 1] = s >>> 8;
15146    out[o + 2] = out[o] ^ 255;
15147    out[o + 3] = out[o + 1] ^ 255;
15148
15149    for (var i = 0; i < s; ++i) out[o + i + 4] = dat[i];
15150
15151    return (o + 4 + s) * 8;
15152  }; // writes a block
15153
15154
15155  var wblk = function (dat, out, final, syms, lf, df, eb, li, bs, bl, p) {
15156    wbits(out, p++, final);
15157    ++lf[256];
15158
15159    var _a = hTree(lf, 15),
15160        dlt = _a[0],
15161        mlb = _a[1];
15162
15163    var _b = hTree(df, 15),
15164        ddt = _b[0],
15165        mdb = _b[1];
15166
15167    var _c = lc(dlt),
15168        lclt = _c[0],
15169        nlc = _c[1];
15170
15171    var _d = lc(ddt),
15172        lcdt = _d[0],
15173        ndc = _d[1];
15174
15175    var lcfreq = new u16(19);
15176
15177    for (var i = 0; i < lclt.length; ++i) lcfreq[lclt[i] & 31]++;
15178
15179    for (var i = 0; i < lcdt.length; ++i) lcfreq[lcdt[i] & 31]++;
15180
15181    var _e = hTree(lcfreq, 7),
15182        lct = _e[0],
15183        mlcb = _e[1];
15184
15185    var nlcc = 19;
15186
15187    for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc);
15188
15189    var flen = bl + 5 << 3;
15190    var ftlen = clen(lf, flt) + clen(df, fdt) + eb;
15191    var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + (2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18]);
15192    if (flen <= ftlen && flen <= dtlen) return wfblk(out, p, dat.subarray(bs, bs + bl));
15193    var lm, ll, dm, dl;
15194    wbits(out, p, 1 + (dtlen < ftlen)), p += 2;
15195
15196    if (dtlen < ftlen) {
15197      lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;
15198      var llm = hMap(lct, mlcb, 0);
15199      wbits(out, p, nlc - 257);
15200      wbits(out, p + 5, ndc - 1);
15201      wbits(out, p + 10, nlcc - 4);
15202      p += 14;
15203
15204      for (var i = 0; i < nlcc; ++i) wbits(out, p + 3 * i, lct[clim[i]]);
15205
15206      p += 3 * nlcc;
15207      var lcts = [lclt, lcdt];
15208
15209      for (var it = 0; it < 2; ++it) {
15210        var clct = lcts[it];
15211
15212        for (var i = 0; i < clct.length; ++i) {
15213          var len = clct[i] & 31;
15214          wbits(out, p, llm[len]), p += lct[len];
15215          if (len > 15) wbits(out, p, clct[i] >>> 5 & 127), p += clct[i] >>> 12;
15216        }
15217      }
15218    } else {
15219      lm = flm, ll = flt, dm = fdm, dl = fdt;
15220    }
15221
15222    for (var i = 0; i < li; ++i) {
15223      if (syms[i] > 255) {
15224        var len = syms[i] >>> 18 & 31;
15225        wbits16(out, p, lm[len + 257]), p += ll[len + 257];
15226        if (len > 7) wbits(out, p, syms[i] >>> 23 & 31), p += fleb[len];
15227        var dst = syms[i] & 31;
15228        wbits16(out, p, dm[dst]), p += dl[dst];
15229        if (dst > 3) wbits16(out, p, syms[i] >>> 5 & 8191), p += fdeb[dst];
15230      } else {
15231        wbits16(out, p, lm[syms[i]]), p += ll[syms[i]];
15232      }
15233    }
15234
15235    wbits16(out, p, lm[256]);
15236    return p + ll[256];
15237  }; // deflate options (nice << 13) | chain
15238
15239
15240  var deo = /*#__PURE__*/new u32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]); // empty
15241
15242  var et = /*#__PURE__*/new u8(0); // compresses data into a raw DEFLATE buffer
15243
15244  var dflt = function (dat, lvl, plvl, pre, post, lst) {
15245    var s = dat.length;
15246    var o = new u8(pre + s + 5 * (1 + Math.floor(s / 7000)) + post); // writing to this writes to the output buffer
15247
15248    var w = o.subarray(pre, o.length - post);
15249    var pos = 0;
15250
15251    if (!lvl || s < 8) {
15252      for (var i = 0; i <= s; i += 65535) {
15253        // end
15254        var e = i + 65535;
15255
15256        if (e < s) {
15257          // write full block
15258          pos = wfblk(w, pos, dat.subarray(i, e));
15259        } else {
15260          // write final block
15261          w[i] = lst;
15262          pos = wfblk(w, pos, dat.subarray(i, s));
15263        }
15264      }
15265    } else {
15266      var opt = deo[lvl - 1];
15267      var n = opt >>> 13,
15268          c = opt & 8191;
15269      var msk_1 = (1 << plvl) - 1; //    prev 2-byte val map    curr 2-byte val map
15270
15271      var prev = new u16(32768),
15272          head = new u16(msk_1 + 1);
15273      var bs1_1 = Math.ceil(plvl / 3),
15274          bs2_1 = 2 * bs1_1;
15275
15276      var hsh = function (i) {
15277        return (dat[i] ^ dat[i + 1] << bs1_1 ^ dat[i + 2] << bs2_1) & msk_1;
15278      }; // 24576 is an arbitrary number of maximum symbols per block
15279      // 424 buffer for last block
15280
15281
15282      var syms = new u32(25000); // length/literal freq   distance freq
15283
15284      var lf = new u16(288),
15285          df = new u16(32); //  l/lcnt  exbits  index  l/lind  waitdx  bitpos
15286
15287      var lc_1 = 0,
15288          eb = 0,
15289          i = 0,
15290          li = 0,
15291          wi = 0,
15292          bs = 0;
15293
15294      for (; i < s; ++i) {
15295        // hash value
15296        var hv = hsh(i); // index mod 32768
15297
15298        var imod = i & 32767; // previous index with this value
15299
15300        var pimod = head[hv];
15301        prev[imod] = pimod;
15302        head[hv] = imod; // We always should modify head and prev, but only add symbols if
15303        // this data is not yet processed ("wait" for wait index)
15304
15305        if (wi <= i) {
15306          // bytes remaining
15307          var rem = s - i;
15308
15309          if ((lc_1 > 7000 || li > 24576) && rem > 423) {
15310            pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);
15311            li = lc_1 = eb = 0, bs = i;
15312
15313            for (var j = 0; j < 286; ++j) lf[j] = 0;
15314
15315            for (var j = 0; j < 30; ++j) df[j] = 0;
15316          } //  len    dist   chain
15317
15318
15319          var l = 2,
15320              d = 0,
15321              ch_1 = c,
15322              dif = imod - pimod & 32767;
15323
15324          if (rem > 2 && hv == hsh(i - dif)) {
15325            var maxn = Math.min(n, rem) - 1;
15326            var maxd = Math.min(32767, i); // max possible length
15327            // not capped at dif because decompressors implement "rolling" index population
15328
15329            var ml = Math.min(258, rem);
15330
15331            while (dif <= maxd && --ch_1 && imod != pimod) {
15332              if (dat[i + l] == dat[i + l - dif]) {
15333                var nl = 0;
15334
15335                for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl);
15336
15337                if (nl > l) {
15338                  l = nl, d = dif; // break out early when we reach "nice" (we are satisfied enough)
15339
15340                  if (nl > maxn) break; // now, find the rarest 2-byte sequence within this
15341                  // length of literals and search for that instead.
15342                  // Much faster than just using the start
15343
15344                  var mmd = Math.min(dif, nl - 2);
15345                  var md = 0;
15346
15347                  for (var j = 0; j < mmd; ++j) {
15348                    var ti = i - dif + j + 32768 & 32767;
15349                    var pti = prev[ti];
15350                    var cd = ti - pti + 32768 & 32767;
15351                    if (cd > md) md = cd, pimod = ti;
15352                  }
15353                }
15354              } // check the previous match
15355
15356
15357              imod = pimod, pimod = prev[imod];
15358              dif += imod - pimod + 32768 & 32767;
15359            }
15360          } // d will be nonzero only when a match was found
15361
15362
15363          if (d) {
15364            // store both dist and len data in one Uint32
15365            // Make sure this is recognized as a len/dist with 28th bit (2^28)
15366            syms[li++] = 268435456 | revfl[l] << 18 | revfd[d];
15367            var lin = revfl[l] & 31,
15368                din = revfd[d] & 31;
15369            eb += fleb[lin] + fdeb[din];
15370            ++lf[257 + lin];
15371            ++df[din];
15372            wi = i + l;
15373            ++lc_1;
15374          } else {
15375            syms[li++] = dat[i];
15376            ++lf[dat[i]];
15377          }
15378        }
15379      }
15380
15381      pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos); // this is the easiest way to avoid needing to maintain state
15382
15383      if (!lst) pos = wfblk(w, pos, et);
15384    }
15385
15386    return slc(o, 0, pre + shft(pos) + post);
15387  }; // CRC32 table
15388
15389
15390  var adler = function () {
15391    var a = 1,
15392        b = 0;
15393    return {
15394      p: function (d) {
15395        // closures have awful performance
15396        var n = a,
15397            m = b;
15398        var l = d.length;
15399
15400        for (var i = 0; i != l;) {
15401          var e = Math.min(i + 5552, l);
15402
15403          for (; i < e; ++i) n += d[i], m += n;
15404
15405          n %= 65521, m %= 65521;
15406        }
15407
15408        a = n, b = m;
15409      },
15410      d: function () {
15411        return (a >>> 8 << 16 | (b & 255) << 8 | b >>> 8) + ((a & 255) << 23) * 2;
15412      }
15413    };
15414  };
15415
15416  var dopt = function (dat, opt, pre, post, st) {
15417    return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : 12 + opt.mem, pre, post, !st);
15418  }; // Walmart object spread
15419
15420
15421  var wbytes = function (d, b, v) {
15422    for (; v; ++b) d[b] = v, v >>
vendor: 12,805 bytes, lines 15422-15859
15422>= 8;
15423  }; // gzip header
15424
15425
15426  var zlh = function (c, o) {
15427    var lv = o.level,
15428        fl = lv == 0 ? 0 : lv < 6 ? 1 : lv == 9 ? 3 : 2;
15429    c[0] = 120, c[1] = fl << 6 | (fl ? 32 - 2 * fl : 1);
15430  }; // zlib valid
15431
15432
15433  var zlv = function (d) {
15434    if ((d[0] & 15) != 8 || d[0] >>> 4 > 7 || (d[0] << 8 | d[1]) % 31) throw 'invalid zlib data';
15435    if (d[1] & 32) throw 'invalid zlib data: preset dictionaries not supported';
15436  };
15437  /**
15438   * Compress data with Zlib
15439   * @param data The data to compress
15440   * @param opts The compression options
15441   * @returns The zlib-compressed version of the data
15442   */
15443
15444  function zlibSync(data, opts) {
15445    if (opts === void 0) {
15446      opts = {};
15447    }
15448
15449    var a = adler();
15450    a.p(data);
15451    var d = dopt(data, opts, 2, 4);
15452    return zlh(d, opts), wbytes(d, d.length - 4, a.d()), d;
15453  }
15454  /**
15455   * Expands Zlib data
15456   * @param data The data to decompress
15457   * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.
15458   * @returns The decompressed version of the data
15459   */
15460
15461  function unzlibSync(data, out) {
15462    return inflt((zlv(data), data.subarray(2, -4)), out);
15463  } // Default algorithm for compression (used because having a known output size allows faster decompression)
15464
15465  /**
15466   * @license
15467   * jsPDF filters PlugIn
15468   * Copyright (c) 2014 Aras Abbasi
15469   *
15470   * Licensed under the MIT License.
15471   * http://opensource.org/licenses/mit-license
15472   */
15473
15474  (function (jsPDFAPI) {
15475
15476    var ASCII85Encode = function ASCII85Encode(a) {
15477      var b, c, d, e, f, g, h, i, j, k; // eslint-disable-next-line no-control-regex
15478
15479      for (!/[^\x00-\xFF]/.test(a), b = "\x00\x00\x00\x00".slice(a.length % 4 || 4), a += b, c = [], d = 0, e = a.length; e > d; d += 4) {
15480        f = (a.charCodeAt(d) << 24) + (a.charCodeAt(d + 1) << 16) + (a.charCodeAt(d + 2) << 8) + a.charCodeAt(d + 3), 0 !== f ? (k = f % 85, f = (f - k) / 85, j = f % 85, f = (f - j) / 85, i = f % 85, f = (f - i) / 85, h = f % 85, f = (f - h) / 85, g = f % 85, c.push(g + 33, h + 33, i + 33, j + 33, k + 33)) : c.push(122);
15481      }
15482
15483      return function (a, b) {
15484        for (var c = b; c > 0; c--) {
15485          a.pop();
15486        }
15487      }(c, b.length), String.fromCharCode.apply(String, c) + "~>";
15488    };
15489
15490    var ASCII85Decode = function ASCII85Decode(a) {
15491      var c,
15492          d,
15493          e,
15494          f,
15495          g,
15496          h = String,
15497          l = "length",
15498          w = 255,
15499          x = "charCodeAt",
15500          y = "slice",
15501          z = "replace";
15502
15503      for ("~>" === a[y](-2), a = a[y](0, -2)[z](/\s/g, "")[z]("z", "!!!!!"), c = "uuuuu"[y](a[l] % 5 || 5), a += c, e = [], f = 0, g = a[l]; g > f; f += 5) {
15504        d = 52200625 * (a[x](f) - 33) + 614125 * (a[x](f + 1) - 33) + 7225 * (a[x](f + 2) - 33) + 85 * (a[x](f + 3) - 33) + (a[x](f + 4) - 33), e.push(w & d >> 24, w & d >> 16, w & d >> 8, w & d);
15505      }
15506
15507      return function (a, b) {
15508        for (var c = b; c > 0; c--) {
15509          a.pop();
15510        }
15511      }(e, c[l]), h.fromCharCode.apply(h, e);
15512    };
15513
15514    var ASCIIHexEncode = function ASCIIHexEncode(value) {
15515      return value.split("").map(function (value) {
15516        return ("0" + value.charCodeAt().toString(16)).slice(-2);
15517      }).join("") + ">";
15518    };
15519
15520    var ASCIIHexDecode = function ASCIIHexDecode(value) {
15521      var regexCheckIfHex = new RegExp(/^([0-9A-Fa-f]{2})+$/);
15522      value = value.replace(/\s/g, "");
15523
15524      if (value.indexOf(">") !== -1) {
15525        value = value.substr(0, value.indexOf(">"));
15526      }
15527
15528      if (value.length % 2) {
15529        value += "0";
15530      }
15531
15532      if (regexCheckIfHex.test(value) === false) {
15533        return "";
15534      }
15535
15536      var result = "";
15537
15538      for (var i = 0; i < value.length; i += 2) {
15539        result += String.fromCharCode("0x" + (value[i] + value[i + 1]));
15540      }
15541
15542      return result;
15543    };
15544    /*
15545    var FlatePredictors = {
15546        None: 1,
15547        TIFF: 2,
15548        PNG_None: 10,
15549        PNG_Sub: 11,
15550        PNG_Up: 12,
15551        PNG_Average: 13,
15552        PNG_Paeth: 14,
15553        PNG_Optimum: 15
15554    };
15555    */
15556
15557
15558    var FlateEncode = function FlateEncode(data) {
15559      var arr = new Uint8Array(data.length);
15560      var i = data.length;
15561
15562      while (i--) {
15563        arr[i] = data.charCodeAt(i);
15564      }
15565
15566      arr = zlibSync(arr);
15567      data = arr.reduce(function (data, byte) {
15568        return data + String.fromCharCode(byte);
15569      }, "");
15570      return data;
15571    };
15572
15573    jsPDFAPI.processDataByFilters = function (origData, filterChain) {
15574
15575      var i = 0;
15576      var data = origData || "";
15577      var reverseChain = [];
15578      filterChain = filterChain || [];
15579
15580      if (typeof filterChain === "string") {
15581        filterChain = [filterChain];
15582      }
15583
15584      for (i = 0; i < filterChain.length; i += 1) {
15585        switch (filterChain[i]) {
15586          case "ASCII85Decode":
15587          case "/ASCII85Decode":
15588            data = ASCII85Decode(data);
15589            reverseChain.push("/ASCII85Encode");
15590            break;
15591
15592          case "ASCII85Encode":
15593          case "/ASCII85Encode":
15594            data = ASCII85Encode(data);
15595            reverseChain.push("/ASCII85Decode");
15596            break;
15597
15598          case "ASCIIHexDecode":
15599          case "/ASCIIHexDecode":
15600            data = ASCIIHexDecode(data);
15601            reverseChain.push("/ASCIIHexEncode");
15602            break;
15603
15604          case "ASCIIHexEncode":
15605          case "/ASCIIHexEncode":
15606            data = ASCIIHexEncode(data);
15607            reverseChain.push("/ASCIIHexDecode");
15608            break;
15609
15610          case "FlateEncode":
15611          case "/FlateEncode":
15612            data = FlateEncode(data);
15613            reverseChain.push("/FlateDecode");
15614            break;
15615
15616          default:
15617            throw new Error('The filter: "' + filterChain[i] + '" is not implemented');
15618        }
15619      }
15620
15621      return {
15622        data: data,
15623        reverseChain: reverseChain.reverse().join(" ")
15624      };
15625    };
15626  })(jsPDF.API);
15627
15628  /**
15629   * @license
15630   * jsPDF fileloading PlugIn
15631   * Copyright (c) 2018 Aras Abbasi ([email protected])
15632   *
15633   * Licensed under the MIT License.
15634   * http://opensource.org/licenses/mit-license
15635   */
15636  /**
15637   * @name fileloading
15638   * @module
15639   */
15640
15641  (function (jsPDFAPI) {
15642    /**
15643     * @name loadFile
15644     * @function
15645     * @param {string} url
15646     * @param {boolean} sync
15647     * @param {function} callback
15648     * @returns {string|undefined} result
15649     */
15650
15651    jsPDFAPI.loadFile = function (url, sync, callback) {
15652      return browserRequest(url, sync, callback);
15653    };
15654    /**
15655     * @name loadImageFile
15656     * @function
15657     * @param {string} path
15658     * @param {boolean} sync
15659     * @param {function} callback
15660     */
15661
15662
15663    jsPDFAPI.loadImageFile = jsPDFAPI.loadFile;
15664
15665    function browserRequest(url, sync, callback) {
15666      sync = sync === false ? false : true;
15667      callback = typeof callback === "function" ? callback : function () {};
15668      var result = undefined;
15669
15670      var xhr = function xhr(url, sync, callback) {
15671        var request = new XMLHttpRequest();
15672        var i = 0;
15673
15674        var sanitizeUnicode = function sanitizeUnicode(data) {
15675          var dataLength = data.length;
15676          var charArray = [];
15677          var StringFromCharCode = String.fromCharCode; //Transform Unicode to ASCII
15678
15679          for (i = 0; i < dataLength; i += 1) {
15680            charArray.push(StringFromCharCode(data.charCodeAt(i) & 0xff));
15681          }
15682
15683          return charArray.join("");
15684        };
15685
15686        request.open("GET", url, !sync); // XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
15687
15688        request.overrideMimeType("text/plain; charset=x-user-defined");
15689
15690        if (sync === false) {
15691          request.onload = function () {
15692            if (request.status === 200) {
15693              callback(sanitizeUnicode(this.responseText));
15694            } else {
15695              callback(undefined);
15696            }
15697          };
15698        }
15699
15700        request.send(null);
15701
15702        if (sync && request.status === 200) {
15703          return sanitizeUnicode(request.responseText);
15704        }
15705      };
15706
15707      try {
15708        result = xhr(url, sync, callback); // eslint-disable-next-line no-empty
15709      } catch (e) {}
15710
15711      return result;
15712    }
15713  })(jsPDF.API);
15714
15715  /**
15716   * jsPDF html PlugIn
15717   *
15718   * @name html
15719   * @module
15720   */
15721
15722  (function (jsPDFAPI) {
15723
15724    function loadHtml2Canvas() {
15725      return function () {
15726        if (globalObject["html2canvas"]) {
15727          return Promise.resolve(globalObject["html2canvas"]);
15728        }
15729
15730        if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object" && typeof module !== "undefined") {
15731          return new Promise(function (resolve, reject) {
15732            try {
15733              resolve(require("html2canvas"));
15734            } catch (e) {
15735              reject(e);
15736            }
15737          });
15738        }
15739
15740        if (typeof define === "function" && define.amd) {
15741          return new Promise(function (resolve, reject) {
15742            try {
15743              require(["html2canvas"], resolve);
15744            } catch (e) {
15745              reject(e);
15746            }
15747          });
15748        }
15749
15750        return Promise.reject(new Error("Could not load html2canvas"));
15751      }().catch(function (e) {
15752        return Promise.reject(new Error("Could not load html2canvas: " + e));
15753      }).then(function (html2canvas) {
15754        return html2canvas.default ? html2canvas.default : html2canvas;
15755      });
15756    }
15757
15758    function loadDomPurify() {
15759      return function () {
15760        if (globalObject["DOMPurify"]) {
15761          return Promise.resolve(globalObject["DOMPurify"]);
15762        }
15763
15764        if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object" && typeof module !== "undefined") {
15765          return new Promise(function (resolve, reject) {
15766            try {
15767              resolve(require("dompurify"));
15768            } catch (e) {
15769              reject(e);
15770            }
15771          });
15772        }
15773
15774        if (typeof define === "function" && define.amd) {
15775          return new Promise(function (resolve, reject) {
15776            try {
15777              require(["dompurify"], resolve);
15778            } catch (e) {
15779              reject(e);
15780            }
15781          });
15782        }
15783
15784        return Promise.reject(new Error("Could not load dompurify"));
15785      }().catch(function (e) {
15786        return Promise.reject(new Error("Could not load dompurify: " + e));
15787      }).then(function (dompurify) {
15788        return dompurify.default ? dompurify.default : dompurify;
15789      });
15790    }
15791    /**
15792     * Determine the type of a variable/object.
15793     *
15794     * @private
15795     * @ignore
15796     */
15797
15798
15799    var objType = function objType(obj) {
15800      var type = _typeof(obj);
15801
15802      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";
15803    };
15804    /**
15805     * Create an HTML element with optional className, innerHTML, and style.
15806     *
15807     * @private
15808     * @ignore
15809     */
15810
15811
15812    var createElement = function createElement(tagName, opt) {
15813      var el = document.createElement(tagName);
15814      if (opt.className) el.className = opt.className;
15815
15816      if (opt.innerHTML && opt.dompurify) {
15817        el.innerHTML = opt.dompurify.sanitize(opt.innerHTML);
15818      }
15819
15820      for (var key in opt.style) {
15821        el.style[key] = opt.style[key];
15822      }
15823
15824      return el;
15825    };
15826    /**
15827     * Deep-clone a node and preserve contents/properties.
15828     *
15829     * @private
15830     * @ignore
15831     */
15832
15833
15834    var cloneNode = function cloneNode(node, javascriptEnabled) {
15835      // Recursively clone the node.
15836      var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);
15837
15838      for (var child = node.firstChild; child; child = child.nextSibling) {
15839        if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== "SCRIPT") {
15840          clone.appendChild(cloneNode(child, javascriptEnabled));
15841        }
15842      }
15843
15844      if (node.nodeType === 1) {
15845        // Preserve contents/properties of special nodes.
15846        if (node.nodeName === "CANVAS") {
15847          clone.width = node.width;
15848          clone.height = node.height;
15849          clone.getContext("2d").drawImage(node, 0, 0);
15850        } else if (node.nodeName === "TEXTAREA" || node.nodeName === "SELECT") {
15851          clone.value = node.value;
15852        } // Preserve the node's scroll position when it loads.
15853
15854
15855        clone.addEventListener("load", function () {
15856          clone.scrollTop = node.scrollTop;
15857          clone.scrollLeft = node.scrollLeft;
15858        }, true);
15859      }
vendor: 26,443 bytes, lines 15859-16627
15859 // Return the cloned node.
15860
15861
15862      return clone;
15863    };
15864    /* ----- CONSTRUCTOR ----- */
15865
15866
15867    var Worker = function Worker(opt) {
15868      // Create the root parent for the proto chain, and the starting Worker.
15869      var root = Object.assign(Worker.convert(Promise.resolve()), JSON.parse(JSON.stringify(Worker.template)));
15870      var self = Worker.convert(Promise.resolve(), root); // Set progress, optional settings, and return.
15871
15872      self = self.setProgress(1, Worker, 1, [Worker]);
15873      self = self.set(opt);
15874      return self;
15875    }; // Boilerplate for subclassing Promise.
15876
15877
15878    Worker.prototype = Object.create(Promise.prototype);
15879    Worker.prototype.constructor = Worker; // Converts/casts promises into Workers.
15880
15881    Worker.convert = function convert(promise, inherit) {
15882      // Uses prototypal inheritance to receive changes made to ancestors' properties.
15883      promise.__proto__ = inherit || Worker.prototype;
15884      return promise;
15885    };
15886
15887    Worker.template = {
15888      prop: {
15889        src: null,
15890        container: null,
15891        overlay: null,
15892        canvas: null,
15893        img: null,
15894        pdf: null,
15895        pageSize: null,
15896        callback: function callback() {}
15897      },
15898      progress: {
15899        val: 0,
15900        state: null,
15901        n: 0,
15902        stack: []
15903      },
15904      opt: {
15905        filename: "file.pdf",
15906        margin: [0, 0, 0, 0],
15907        enableLinks: true,
15908        x: 0,
15909        y: 0,
15910        html2canvas: {},
15911        jsPDF: {},
15912        backgroundColor: "transparent"
15913      }
15914    };
15915    /* ----- FROM / TO ----- */
15916
15917    Worker.prototype.from = function from(src, type) {
15918      function getType(src) {
15919        switch (objType(src)) {
15920          case "string":
15921            return "string";
15922
15923          case "element":
15924            return src.nodeName.toLowerCase() === "canvas" ? "canvas" : "element";
15925
15926          default:
15927            return "unknown";
15928        }
15929      }
15930
15931      return this.then(function from_main() {
15932        type = type || getType(src);
15933
15934        switch (type) {
15935          case "string":
15936            return this.then(loadDomPurify).then(function (dompurify) {
15937              return this.set({
15938                src: createElement("div", {
15939                  innerHTML: src,
15940                  dompurify: dompurify
15941                })
15942              });
15943            });
15944
15945          case "element":
15946            return this.set({
15947              src: src
15948            });
15949
15950          case "canvas":
15951            return this.set({
15952              canvas: src
15953            });
15954
15955          case "img":
15956            return this.set({
15957              img: src
15958            });
15959
15960          default:
15961            return this.error("Unknown source type.");
15962        }
15963      });
15964    };
15965
15966    Worker.prototype.to = function to(target) {
15967      // Route the 'to' request to the appropriate method.
15968      switch (target) {
15969        case "container":
15970          return this.toContainer();
15971
15972        case "canvas":
15973          return this.toCanvas();
15974
15975        case "img":
15976          return this.toImg();
15977
15978        case "pdf":
15979          return this.toPdf();
15980
15981        default:
15982          return this.error("Invalid target.");
15983      }
15984    };
15985
15986    Worker.prototype.toContainer = function toContainer() {
15987      // Set up function prerequisites.
15988      var prereqs = [function checkSrc() {
15989        return this.prop.src || this.error("Cannot duplicate - no source HTML.");
15990      }, function checkPageSize() {
15991        return this.prop.pageSize || this.setPageSize();
15992      }];
15993      return this.thenList(prereqs).then(function toContainer_main() {
15994        // Define the CSS styles for the container and its overlay parent.
15995        var overlayCSS = {
15996          position: "fixed",
15997          overflow: "hidden",
15998          zIndex: 1000,
15999          left: "-100000px",
16000          right: 0,
16001          bottom: 0,
16002          top: 0
16003        };
16004        var containerCSS = {
16005          position: "relative",
16006          display: "inline-block",
16007          width: (typeof this.opt.width === "number" && !isNaN(this.opt.width) && typeof this.opt.windowWidth === "number" && !isNaN(this.opt.windowWidth) ? this.opt.windowWidth : Math.max(this.prop.src.clientWidth, this.prop.src.scrollWidth, this.prop.src.offsetWidth)) + "px",
16008          left: 0,
16009          right: 0,
16010          top: 0,
16011          margin: "auto",
16012          backgroundColor: this.opt.backgroundColor
16013        }; // Set the overlay to hidden (could be changed in the future to provide a print preview).
16014
16015        var source = cloneNode(this.prop.src, this.opt.html2canvas.javascriptEnabled);
16016
16017        if (source.tagName === "BODY") {
16018          containerCSS.height = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight) + "px";
16019        }
16020
16021        this.prop.overlay = createElement("div", {
16022          className: "html2pdf__overlay",
16023          style: overlayCSS
16024        });
16025        this.prop.container = createElement("div", {
16026          className: "html2pdf__container",
16027          style: containerCSS
16028        });
16029        this.prop.container.appendChild(source);
16030        this.prop.container.firstChild.appendChild(createElement("div", {
16031          style: {
16032            clear: "both",
16033            border: "0 none transparent",
16034            margin: 0,
16035            padding: 0,
16036            height: 0
16037          }
16038        }));
16039        this.prop.container.style.float = "none";
16040        this.prop.overlay.appendChild(this.prop.container);
16041        document.body.appendChild(this.prop.overlay);
16042        this.prop.container.firstChild.style.position = "relative";
16043        this.prop.container.height = Math.max(this.prop.container.firstChild.clientHeight, this.prop.container.firstChild.scrollHeight, this.prop.container.firstChild.offsetHeight) + "px";
16044      });
16045    };
16046
16047    Worker.prototype.toCanvas = function toCanvas() {
16048      // Set up function prerequisites.
16049      var prereqs = [function checkContainer() {
16050        return document.body.contains(this.prop.container) || this.toContainer();
16051      }]; // Fulfill prereqs then create the canvas.
16052
16053      return this.thenList(prereqs).then(loadHtml2Canvas).then(function toCanvas_main(html2canvas) {
16054        // Handle old-fashioned 'onrendered' argument.
16055        var options = Object.assign({}, this.opt.html2canvas);
16056        delete options.onrendered;
16057        return html2canvas(this.prop.container, options);
16058      }).then(function toCanvas_post(canvas) {
16059        // Handle old-fashioned 'onrendered' argument.
16060        var onRendered = this.opt.html2canvas.onrendered || function () {};
16061
16062        onRendered(canvas);
16063        this.prop.canvas = canvas;
16064        document.body.removeChild(this.prop.overlay);
16065      });
16066    };
16067
16068    Worker.prototype.toContext2d = function toContext2d() {
16069      // Set up function prerequisites.
16070      var prereqs = [function checkContainer() {
16071        return document.body.contains(this.prop.container) || this.toContainer();
16072      }]; // Fulfill prereqs then create the canvas.
16073
16074      return this.thenList(prereqs).then(loadHtml2Canvas).then(function toContext2d_main(html2canvas) {
16075        // Handle old-fashioned 'onrendered' argument.
16076        var pdf = this.opt.jsPDF;
16077        var fontFaces = this.opt.fontFaces;
16078        var scale = typeof this.opt.width === "number" && !isNaN(this.opt.width) && typeof this.opt.windowWidth === "number" && !isNaN(this.opt.windowWidth) ? this.opt.width / this.opt.windowWidth : 1;
16079        var options = Object.assign({
16080          async: true,
16081          allowTaint: true,
16082          scale: scale,
16083          scrollX: this.opt.scrollX || 0,
16084          scrollY: this.opt.scrollY || 0,
16085          backgroundColor: "#ffffff",
16086          imageTimeout: 15000,
16087          logging: true,
16088          proxy: null,
16089          removeContainer: true,
16090          foreignObjectRendering: false,
16091          useCORS: false
16092        }, this.opt.html2canvas);
16093        delete options.onrendered;
16094        pdf.context2d.autoPaging = typeof this.opt.autoPaging === "undefined" ? true : this.opt.autoPaging;
16095        pdf.context2d.posX = this.opt.x;
16096        pdf.context2d.posY = this.opt.y;
16097        pdf.context2d.margin = this.opt.margin;
16098        pdf.context2d.fontFaces = fontFaces;
16099
16100        if (fontFaces) {
16101          for (var i = 0; i < fontFaces.length; ++i) {
16102            var font = fontFaces[i];
16103            var src = font.src.find(function (src) {
16104              return src.format === "truetype";
16105            });
16106
16107            if (src) {
16108              pdf.addFont(src.url, font.ref.name, font.ref.style);
16109            }
16110          }
16111        }
16112
16113        options.windowHeight = options.windowHeight || 0;
16114        options.windowHeight = options.windowHeight == 0 ? Math.max(this.prop.container.clientHeight, this.prop.container.scrollHeight, this.prop.container.offsetHeight) : options.windowHeight;
16115        pdf.context2d.save(true);
16116        return html2canvas(this.prop.container, options);
16117      }).then(function toContext2d_post(canvas) {
16118        this.opt.jsPDF.context2d.restore(true); // Handle old-fashioned 'onrendered' argument.
16119
16120        var onRendered = this.opt.html2canvas.onrendered || function () {};
16121
16122        onRendered(canvas);
16123        this.prop.canvas = canvas;
16124        document.body.removeChild(this.prop.overlay);
16125      });
16126    };
16127
16128    Worker.prototype.toImg = function toImg() {
16129      // Set up function prerequisites.
16130      var prereqs = [function checkCanvas() {
16131        return this.prop.canvas || this.toCanvas();
16132      }]; // Fulfill prereqs then create the image.
16133
16134      return this.thenList(prereqs).then(function toImg_main() {
16135        var imgData = this.prop.canvas.toDataURL("image/" + this.opt.image.type, this.opt.image.quality);
16136        this.prop.img = document.createElement("img");
16137        this.prop.img.src = imgData;
16138      });
16139    };
16140
16141    Worker.prototype.toPdf = function toPdf() {
16142      // Set up function prerequisites.
16143      var prereqs = [function checkContext2d() {
16144        return this.toContext2d();
16145      } //function checkCanvas() { return this.prop.canvas || this.toCanvas(); }
16146      ]; // Fulfill prereqs then create the image.
16147
16148      return this.thenList(prereqs).then(function toPdf_main() {
16149        // Create local copies of frequently used properties.
16150        this.prop.pdf = this.prop.pdf || this.opt.jsPDF;
16151      });
16152    };
16153    /* ----- OUTPUT / SAVE ----- */
16154
16155
16156    Worker.prototype.output = function output(type, options, src) {
16157      // Redirect requests to the correct function (outputPdf / outputImg).
16158      src = src || "pdf";
16159
16160      if (src.toLowerCase() === "img" || src.toLowerCase() === "image") {
16161        return this.outputImg(type, options);
16162      } else {
16163        return this.outputPdf(type, options);
16164      }
16165    };
16166
16167    Worker.prototype.outputPdf = function outputPdf(type, options) {
16168      // Set up function prerequisites.
16169      var prereqs = [function checkPdf() {
16170        return this.prop.pdf || this.toPdf();
16171      }]; // Fulfill prereqs then perform the appropriate output.
16172
16173      return this.thenList(prereqs).then(function outputPdf_main() {
16174        /* Currently implemented output types:
16175         *    https://rawgit.com/MrRio/jsPDF/master/docs/jspdf.js.html#line992
16176         *  save(options), arraybuffer, blob, bloburi/bloburl,
16177         *  datauristring/dataurlstring, dataurlnewwindow, datauri/dataurl
16178         */
16179        return this.prop.pdf.output(type, options);
16180      });
16181    };
16182
16183    Worker.prototype.outputImg = function outputImg(type) {
16184      // Set up function prerequisites.
16185      var prereqs = [function checkImg() {
16186        return this.prop.img || this.toImg();
16187      }]; // Fulfill prereqs then perform the appropriate output.
16188
16189      return this.thenList(prereqs).then(function outputImg_main() {
16190        switch (type) {
16191          case undefined:
16192          case "img":
16193            return this.prop.img;
16194
16195          case "datauristring":
16196          case "dataurlstring":
16197            return this.prop.img.src;
16198
16199          case "datauri":
16200          case "dataurl":
16201            return document.location.href = this.prop.img.src;
16202
16203          default:
16204            throw 'Image output type "' + type + '" is not supported.';
16205        }
16206      });
16207    };
16208
16209    Worker.prototype.save = function save(filename) {
16210      // Set up function prerequisites.
16211      var prereqs = [function checkPdf() {
16212        return this.prop.pdf || this.toPdf();
16213      }]; // Fulfill prereqs, update the filename (if provided), and save the PDF.
16214
16215      return this.thenList(prereqs).set(filename ? {
16216        filename: filename
16217      } : null).then(function save_main() {
16218        this.prop.pdf.save(this.opt.filename);
16219      });
16220    };
16221
16222    Worker.prototype.doCallback = function doCallback() {
16223      // Set up function prerequisites.
16224      var prereqs = [function checkPdf() {
16225        return this.prop.pdf || this.toPdf();
16226      }]; // Fulfill prereqs, update the filename (if provided), and save the PDF.
16227
16228      return this.thenList(prereqs).then(function doCallback_main() {
16229        this.prop.callback(this.prop.pdf);
16230      });
16231    };
16232    /* ----- SET / GET ----- */
16233
16234
16235    Worker.prototype.set = function set(opt) {
16236      // TODO: Implement ordered pairs?
16237      // Silently ignore invalid or empty input.
16238      if (objType(opt) !== "object") {
16239        return this;
16240      } // Build an array of setter functions to queue.
16241
16242
16243      var fns = Object.keys(opt || {}).map(function (key) {
16244        if (key in Worker.template.prop) {
16245          // Set pre-defined properties.
16246          return function set_prop() {
16247            this.prop[key] = opt[key];
16248          };
16249        } else {
16250          switch (key) {
16251            case "margin":
16252              return this.setMargin.bind(this, opt.margin);
16253
16254            case "jsPDF":
16255              return function set_jsPDF() {
16256                this.opt.jsPDF = opt.jsPDF;
16257                return this.setPageSize();
16258              };
16259
16260            case "pageSize":
16261              return this.setPageSize.bind(this, opt.pageSize);
16262
16263            default:
16264              // Set any other properties in opt.
16265              return function set_opt() {
16266                this.opt[key] = opt[key];
16267              };
16268          }
16269        }
16270      }, this); // Set properties within the promise chain.
16271
16272      return this.then(function set_main() {
16273        return this.thenList(fns);
16274      });
16275    };
16276
16277    Worker.prototype.get = function get(key, cbk) {
16278      return this.then(function get_main() {
16279        // Fetch the requested property, either as a predefined prop or in opt.
16280        var val = key in Worker.template.prop ? this.prop[key] : this.opt[key];
16281        return cbk ? cbk(val) : val;
16282      });
16283    };
16284
16285    Worker.prototype.setMargin = function setMargin(margin) {
16286      return this.then(function setMargin_main() {
16287        // Parse the margin property.
16288        switch (objType(margin)) {
16289          case "number":
16290            margin = [margin, margin, margin, margin];
16291          // eslint-disable-next-line no-fallthrough
16292
16293          case "array":
16294            if (margin.length === 2) {
16295              margin = [margin[0], margin[1], margin[0], margin[1]];
16296            }
16297
16298            if (margin.length === 4) {
16299              break;
16300            }
16301
16302          // eslint-disable-next-line no-fallthrough
16303
16304          default:
16305            return this.error("Invalid margin array.");
16306        } // Set the margin property, then update pageSize.
16307
16308
16309        this.opt.margin = margin;
16310      }).then(this.setPageSize);
16311    };
16312
16313    Worker.prototype.setPageSize = function setPageSize(pageSize) {
16314      function toPx(val, k) {
16315        return Math.floor(val * k / 72 * 96);
16316      }
16317
16318      return this.then(function setPageSize_main() {
16319        // Retrieve page-size based on jsPDF settings, if not explicitly provided.
16320        pageSize = pageSize || jsPDF.getPageSize(this.opt.jsPDF); // Add 'inner' field if not present.
16321
16322        if (!pageSize.hasOwnProperty("inner")) {
16323          pageSize.inner = {
16324            width: pageSize.width - this.opt.margin[1] - this.opt.margin[3],
16325            height: pageSize.height - this.opt.margin[0] - this.opt.margin[2]
16326          };
16327          pageSize.inner.px = {
16328            width: toPx(pageSize.inner.width, pageSize.k),
16329            height: toPx(pageSize.inner.height, pageSize.k)
16330          };
16331          pageSize.inner.ratio = pageSize.inner.height / pageSize.inner.width;
16332        } // Attach pageSize to this.
16333
16334
16335        this.prop.pageSize = pageSize;
16336      });
16337    };
16338
16339    Worker.prototype.setProgress = function setProgress(val, state, n, stack) {
16340      // Immediately update all progress values.
16341      if (val != null) this.progress.val = val;
16342      if (state != null) this.progress.state = state;
16343      if (n != null) this.progress.n = n;
16344      if (stack != null) this.progress.stack = stack;
16345      this.progress.ratio = this.progress.val / this.progress.state; // Return this for command chaining.
16346
16347      return this;
16348    };
16349
16350    Worker.prototype.updateProgress = function updateProgress(val, state, n, stack) {
16351      // Immediately update all progress values, using setProgress.
16352      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);
16353    };
16354    /* ----- PROMISE MAPPING ----- */
16355
16356
16357    Worker.prototype.then = function then(onFulfilled, onRejected) {
16358      // Wrap `this` for encapsulation.
16359      var self = this;
16360      return this.thenCore(onFulfilled, onRejected, function then_main(onFulfilled, onRejected) {
16361        // Update progress while queuing, calling, and resolving `then`.
16362        self.updateProgress(null, null, 1, [onFulfilled]);
16363        return Promise.prototype.then.call(this, function then_pre(val) {
16364          self.updateProgress(null, onFulfilled);
16365          return val;
16366        }).then(onFulfilled, onRejected).then(function then_post(val) {
16367          self.updateProgress(1);
16368          return val;
16369        });
16370      });
16371    };
16372
16373    Worker.prototype.thenCore = function thenCore(onFulfilled, onRejected, thenBase) {
16374      // Handle optional thenBase parameter.
16375      thenBase = thenBase || Promise.prototype.then; // Wrap `this` for encapsulation and bind it to the promise handlers.
16376
16377      var self = this;
16378
16379      if (onFulfilled) {
16380        onFulfilled = onFulfilled.bind(self);
16381      }
16382
16383      if (onRejected) {
16384        onRejected = onRejected.bind(self);
16385      } // Cast self into a Promise to avoid polyfills recursively defining `then`.
16386
16387
16388      var isNative = Promise.toString().indexOf("[native code]") !== -1 && Promise.name === "Promise";
16389      var selfPromise = isNative ? self : Worker.convert(Object.assign({}, self), Promise.prototype); // Return the promise, after casting it into a Worker and preserving props.
16390
16391      var returnVal = thenBase.call(selfPromise, onFulfilled, onRejected);
16392      return Worker.convert(returnVal, self.__proto__);
16393    };
16394
16395    Worker.prototype.thenExternal = function thenExternal(onFulfilled, onRejected) {
16396      // Call `then` and return a standard promise (exits the Worker chain).
16397      return Promise.prototype.then.call(this, onFulfilled, onRejected);
16398    };
16399
16400    Worker.prototype.thenList = function thenList(fns) {
16401      // Queue a series of promise 'factories' into the promise chain.
16402      var self = this;
16403      fns.forEach(function thenList_forEach(fn) {
16404        self = self.thenCore(fn);
16405      });
16406      return self;
16407    };
16408
16409    Worker.prototype["catch"] = function (onRejected) {
16410      // Bind `this` to the promise handler, call `catch`, and return a Worker.
16411      if (onRejected) {
16412        onRejected = onRejected.bind(this);
16413      }
16414
16415      var returnVal = Promise.prototype["catch"].call(this, onRejected);
16416      return Worker.convert(returnVal, this);
16417    };
16418
16419    Worker.prototype.catchExternal = function catchExternal(onRejected) {
16420      // Call `catch` and return a standard promise (exits the Worker chain).
16421      return Promise.prototype["catch"].call(this, onRejected);
16422    };
16423
16424    Worker.prototype.error = function error(msg) {
16425      // Throw the error in the Promise chain.
16426      return this.then(function error_main() {
16427        throw new Error(msg);
16428      });
16429    };
16430    /* ----- ALIASES ----- */
16431
16432
16433    Worker.prototype.using = Worker.prototype.set;
16434    Worker.prototype.saveAs = Worker.prototype.save;
16435    Worker.prototype.export = Worker.prototype.output;
16436    Worker.prototype.run = Worker.prototype.then; // Get dimensions of a PDF page, as determined by jsPDF.
16437
16438    jsPDF.getPageSize = function (orientation, unit, format) {
16439      // Decode options object
16440      if (_typeof(orientation) === "object") {
16441        var options = orientation;
16442        orientation = options.orientation;
16443        unit = options.unit || unit;
16444        format = options.format || format;
16445      } // Default options
16446
16447
16448      unit = unit || "mm";
16449      format = format || "a4";
16450      orientation = ("" + (orientation || "P")).toLowerCase();
16451      var format_as_string = ("" + format).toLowerCase(); // Size in pt of various paper formats
16452
16453      var pageFormats = {
16454        a0: [2383.94, 3370.39],
16455        a1: [1683.78, 2383.94],
16456        a2: [1190.55, 1683.78],
16457        a3: [841.89, 1190.55],
16458        a4: [595.28, 841.89],
16459        a5: [419.53, 595.28],
16460        a6: [297.64, 419.53],
16461        a7: [209.76, 297.64],
16462        a8: [147.4, 209.76],
16463        a9: [104.88, 147.4],
16464        a10: [73.7, 104.88],
16465        b0: [2834.65, 4008.19],
16466        b1: [2004.09, 2834.65],
16467        b2: [1417.32, 2004.09],
16468        b3: [1000.63, 1417.32],
16469        b4: [708.66, 1000.63],
16470        b5: [498.9, 708.66],
16471        b6: [354.33, 498.9],
16472        b7: [249.45, 354.33],
16473        b8: [175.75, 249.45],
16474        b9: [124.72, 175.75],
16475        b10: [87.87, 124.72],
16476        c0: [2599.37, 3676.54],
16477        c1: [1836.85, 2599.37],
16478        c2: [1298.27, 1836.85],
16479        c3: [918.43, 1298.27],
16480        c4: [649.13, 918.43],
16481        c5: [459.21, 649.13],
16482        c6: [323.15, 459.21],
16483        c7: [229.61, 323.15],
16484        c8: [161.57, 229.61],
16485        c9: [113.39, 161.57],
16486        c10: [79.37, 113.39],
16487        dl: [311.81, 623.62],
16488        letter: [612, 792],
16489        "government-letter": [576, 756],
16490        legal: [612, 1008],
16491        "junior-legal": [576, 360],
16492        ledger: [1224, 792],
16493        tabloid: [792, 1224],
16494        "credit-card": [153, 243]
16495      };
16496      var k; // Unit conversion
16497
16498      switch (unit) {
16499        case "pt":
16500          k = 1;
16501          break;
16502
16503        case "mm":
16504          k = 72 / 25.4;
16505          break;
16506
16507        case "cm":
16508          k = 72 / 2.54;
16509          break;
16510
16511        case "in":
16512          k = 72;
16513          break;
16514
16515        case "px":
16516          k = 72 / 96;
16517          break;
16518
16519        case "pc":
16520          k = 12;
16521          break;
16522
16523        case "em":
16524          k = 12;
16525          break;
16526
16527        case "ex":
16528          k = 6;
16529          break;
16530
16531        default:
16532          throw "Invalid unit: " + unit;
16533      }
16534
16535      var pageHeight = 0;
16536      var pageWidth = 0; // Dimensions are stored as user units and converted to points on output
16537
16538      if (pageFormats.hasOwnProperty(format_as_string)) {
16539        pageHeight = pageFormats[format_as_string][1] / k;
16540        pageWidth = pageFormats[format_as_string][0] / k;
16541      } else {
16542        try {
16543          pageHeight = format[1];
16544          pageWidth = format[0];
16545        } catch (err) {
16546          throw new Error("Invalid format: " + format);
16547        }
16548      }
16549
16550      var tmp; // Handle page orientation
16551
16552      if (orientation === "p" || orientation === "portrait") {
16553        orientation = "p";
16554
16555        if (pageWidth > pageHeight) {
16556          tmp = pageWidth;
16557          pageWidth = pageHeight;
16558          pageHeight = tmp;
16559        }
16560      } else if (orientation === "l" || orientation === "landscape") {
16561        orientation = "l";
16562
16563        if (pageHeight > pageWidth) {
16564          tmp = pageWidth;
16565          pageWidth = pageHeight;
16566          pageHeight = tmp;
16567        }
16568      } else {
16569        throw "Invalid orientation: " + orientation;
16570      } // Return information (k is the unit conversion ratio from pts)
16571
16572
16573      var info = {
16574        width: pageWidth,
16575        height: pageHeight,
16576        unit: unit,
16577        k: k,
16578        orientation: orientation
16579      };
16580      return info;
16581    };
16582    /**
16583     * @typedef FontFace
16584     *
16585     * The font-face type implements an interface similar to that of the font-face CSS rule,
16586     * and is used by jsPDF to match fonts when the font property of CanvasRenderingContext2D
16587     * is updated.
16588     *
16589     * All properties expect values similar to those in the font-face CSS rule. A difference
16590     * is the font-family, which do not need to be enclosed in double-quotes when containing
16591     * spaces like in CSS.
16592     *
16593     * @property {string} family The name of the font-family.
16594     * @property {string|undefined} style The style that this font-face defines, e.g. 'italic'.
16595     * @property {string|number|undefined} weight The weight of the font, either as a string or a number (400, 500, 600, e.g.)
16596     * @property {string|undefined} stretch The stretch of the font, e.g. condensed, normal, expanded.
16597     * @property {Object[]} src A list of URLs from where fonts of various formats can be fetched.
16598     * @property {string} [src] url A URL to a font of a specific format.
16599     * @property {string} [src] format Format of the font referenced by the URL.
16600     */
16601
16602    /**
16603     * Generate a PDF from an HTML element or string using.
16604     *
16605     * @name html
16606     * @function
16607     * @param {HTMLElement|string} source The source HTMLElement or a string containing HTML.
16608     * @param {Object} [options] Collection of settings
16609     * @param {function} [options.callback] The mandatory callback-function gets as first parameter the current jsPDF instance
16610     * @param {(number|number[])=} [options.margin] Page margins [top, right, bottom, left]. Default is 0.
16611     * @param {(boolean|'slice'|'text')=} [options.autoPaging] The auto paging mode.
16612     * <ul>
16613     * <li>
16614     *   <code>false</code>: Auto paging is disabled.
16615     * </li>
16616     * <li>
16617     *   <code>true</code> or <code>'slice'</code>: Will cut shapes or text chunks across page breaks. Will possibly
16618     *   slice text in half, making it difficult to read.
16619     * </li>
16620     * <li>
16621     *   <code>'text'</code>: Trys not to cut text in half across page breaks. Works best for documents consisting
16622     *   mostly of a single column of text.
16623     * </li>
16624     * </ul>
16625     * Default is <code>true</code>.
16626     * @param {string} [options.filename] name of the file
16627     * @param {HTMLOptionImage}
16627 [options.image] image settings when converting HTML to image
16628     * @param {Html2CanvasOptions} [options.html2canvas] html2canvas options
16629     * @param {FontFace[]} [options.fontFaces] A list of font-faces to match when resolving fonts. Fonts will be added to the PDF based on the specified URL. If omitted, the font match algorithm falls back to old algorithm.
16630     * @param {jsPDF} [options.jsPDF] jsPDF instance
16631     * @param {number=} [options.x] x position on the PDF document in jsPDF units.
16632     * @param {number=} [options.y] y position on the PDF document in jsPDF units.
16633     * @param {number=} [options.width] The target width in the PDF document in jsPDF units. The rendered element will be
16634     * scaled such that it fits into the specified width. Has no effect if either the <code>html2canvas.scale<code> is
16635     * specified or the <code>windowWidth</code> option is NOT specified.
16636     * @param {number=} [options.windowWidth] The window width in CSS pixels. In contrast to the
16637     * <code>html2canvas.windowWidth</code> option, this option affects the actual container size while rendering and
16638     * does NOT affect CSS media queries. This option only has an effect, if the <code>width<code> option is also specified.
16639     *
16640     * @example
16641     * var doc = new jsPDF();
16642     *
16643     * doc.html(document.body, {
16644     *    callback: function (doc) {
16645     *      doc.save();
16646     *    },
16647     *    x: 10,
16648     *    y: 10
16649     * });
16650     */
16651
16652
16653    jsPDFAPI.html = function (src, options) {
16654
16655      options = options || {};
16656
16657      options.callback = options.callback || function () {};
16658
16659      options.html2canvas = options.html2canvas || {};
16660      options.html2canvas.canvas = options.html2canvas.canvas || this.canvas;
16661      options.jsPDF = options.jsPDF || this;
16662      options.fontFaces = options.fontFaces ? options.fontFaces.map(normalizeFontFace) : null; // Create a new worker with the given options.
16663
16664      var worker = new Worker(options);
16665
16666      if (!options.worker) {
16667        // If worker is not set to true, perform the traditional 'simple' operation.
16668        return worker.from(src).doCallback();
16669      } else {
16670        // Otherwise, return the worker for new Promise-based operation.
16671        return worker;
16672      }
16673    };
16674  })(jsPDF.API);
16675
16676  /**
16677   * @license
16678   * ====================================================================
16679   * Copyright (c) 2013 Youssef Beddad, [email protected]
16680   *
16681   * Permission is hereby granted, free of charge, to any person obtaining
16682   * a copy of this software and associated documentation files (the
16683   * "Software"), to deal in the Software without restriction, including
16684   * without limitation the rights to use, copy, modify, merge, publish,
16685   * distribute, sublicense, and/or sell copies of the Software, and to
16686   * permit persons to whom the Software is furnished to do so, subject to
16687   * the following conditions:
16688   *
16689   * The above copyright notice and this permission notice shall be
16690   * included in all copies or substantial portions of the Software.
16691   *
16692   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16693   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16694   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16695   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16696   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
16697   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
16698   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16699   * ====================================================================
16700   */
16701  /**
16702   * jsPDF JavaScript plugin
16703   *
16704   * @name javascript
16705   * @module
16706   */
16707
16708  (function (jsPDFAPI) {
16709
16710    var jsNamesObj, jsJsObj, text;
16711    /**
16712     * @name addJS
16713     * @function
16714     * @param {string} javascript The javascript to be embedded into the PDF-file.
16715     * @returns {jsPDF}
16716     */
16717
16718    jsPDFAPI.addJS = function (javascript) {
16719      text = javascript;
16720      this.internal.events.subscribe("postPutResources", function () {
16721        jsNamesObj = this.internal.newObject();
16722        this.internal.out("<<");
16723        this.internal.out("/Names [(EmbeddedJS) " + (jsNamesObj + 1) + " 0 R]");
16724        this.internal.out(">>");
16725        this.internal.out("endobj");
16726        jsJsObj = this.internal.newObject();
16727        this.internal.out("<<");
16728        this.internal.out("/S /JavaScript");
vendor: 5,584 bytes, lines 16729-16914
16729        this.internal.out("/JS (" + text + ")");
16730        this.internal.out(">>");
16731        this.internal.out("endobj");
16732      });
16733      this.internal.events.subscribe("putCatalog", function () {
16734        if (jsNamesObj !== undefined && jsJsObj !== undefined) {
16735          this.internal.out("/Names <</JavaScript " + jsNamesObj + " 0 R>>");
16736        }
16737      });
16738      return this;
16739    };
16740  })(jsPDF.API);
16741
16742  /**
16743   * @license
16744   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  [email protected]
16745   *
16746   * Licensed under the MIT License.
16747   * http://opensource.org/licenses/mit-license
16748   */
16749  /**
16750   * jsPDF Outline PlugIn
16751   *
16752   * Generates a PDF Outline
16753   * @name outline
16754   * @module
16755   */
16756
16757  (function (jsPDFAPI) {
16758
16759    var namesOid; //var destsGoto = [];
16760
16761    jsPDFAPI.events.push(["postPutResources", function () {
16762      var pdf = this;
16763      var rx = /^(\d+) 0 obj$/; // Write action goto objects for each page
16764      // this.outline.destsGoto = [];
16765      // for (var i = 0; i < totalPages; i++) {
16766      // var id = pdf.internal.newObject();
16767      // this.outline.destsGoto.push(id);
16768      // pdf.internal.write("<</D[" + (i * 2 + 3) + " 0 R /XYZ null
16769      // null null]/S/GoTo>> endobj");
16770      // }
16771      //
16772      // for (var i = 0; i < dests.length; i++) {
16773      // pdf.internal.write("(page_" + (i + 1) + ")" + dests[i] + " 0
16774      // R");
16775      // }
16776      //
16777
16778      if (this.outline.root.children.length > 0) {
16779        var lines = pdf.outline.render().split(/\r\n/);
16780
16781        for (var i = 0; i < lines.length; i++) {
16782          var line = lines[i];
16783          var m = rx.exec(line);
16784
16785          if (m != null) {
16786            var oid = m[1];
16787            pdf.internal.newObjectDeferredBegin(oid, false);
16788          }
16789
16790          pdf.internal.write(line);
16791        }
16792      } // This code will write named destination for each page reference
16793      // (page_1, etc)
16794
16795
16796      if (this.outline.createNamedDestinations) {
16797        var totalPages = this.internal.pages.length; // WARNING: this assumes jsPDF starts on page 3 and pageIDs
16798        // follow 5, 7, 9, etc
16799        // Write destination objects for each page
16800
16801        var dests = [];
16802
16803        for (var i = 0; i < totalPages; i++) {
16804          var id = pdf.internal.newObject();
16805          dests.push(id);
16806          var info = pdf.internal.getPageInfo(i + 1);
16807          pdf.internal.write("<< /D[" + info.objId + " 0 R /XYZ null null null]>> endobj");
16808        } // assign a name for each destination
16809
16810
16811        var names2Oid = pdf.internal.newObject();
16812        pdf.internal.write("<< /Names [ ");
16813
16814        for (var i = 0; i < dests.length; i++) {
16815          pdf.internal.write("(page_" + (i + 1) + ")" + dests[i] + " 0 R");
16816        }
16817
16818        pdf.internal.write(" ] >>", "endobj"); // var kids = pdf.internal.newObject();
16819        // pdf.internal.write('<< /Kids [ ' + names2Oid + ' 0 R');
16820        // pdf.internal.write(' ] >>', 'endobj');
16821
16822        namesOid = pdf.internal.newObject();
16823        pdf.internal.write("<< /Dests " + names2Oid + " 0 R");
16824        pdf.internal.write(">>", "endobj");
16825      }
16826    }]);
16827    jsPDFAPI.events.push(["putCatalog", function () {
16828      var pdf = this;
16829
16830      if (pdf.outline.root.children.length > 0) {
16831        pdf.internal.write("/Outlines", this.outline.makeRef(this.outline.root));
16832
16833        if (this.outline.createNamedDestinations) {
16834          pdf.internal.write("/Names " + namesOid + " 0 R");
16835        } // Open with Bookmarks showing
16836        // pdf.internal.write("/PageMode /UseOutlines");
16837
16838      }
16839    }]);
16840    jsPDFAPI.events.push(["initialized", function () {
16841      var pdf = this;
16842      pdf.outline = {
16843        createNamedDestinations: false,
16844        root: {
16845          children: []
16846        }
16847      };
16848      /**
16849       * Options: pageNumber
16850       */
16851
16852      pdf.outline.add = function (parent, title, options) {
16853        var item = {
16854          title: title,
16855          options: options,
16856          children: []
16857        };
16858
16859        if (parent == null) {
16860          parent = this.root;
16861        }
16862
16863        parent.children.push(item);
16864        return item;
16865      };
16866
16867      pdf.outline.render = function () {
16868        this.ctx = {};
16869        this.ctx.val = "";
16870        this.ctx.pdf = pdf;
16871        this.genIds_r(this.root);
16872        this.renderRoot(this.root);
16873        this.renderItems(this.root);
16874        return this.ctx.val;
16875      };
16876
16877      pdf.outline.genIds_r = function (node) {
16878        node.id = pdf.internal.newObjectDeferred();
16879
16880        for (var i = 0; i < node.children.length; i++) {
16881          this.genIds_r(node.children[i]);
16882        }
16883      };
16884
16885      pdf.outline.renderRoot = function (node) {
16886        this.objStart(node);
16887        this.line("/Type /Outlines");
16888
16889        if (node.children.length > 0) {
16890          this.line("/First " + this.makeRef(node.children[0]));
16891          this.line("/Last " + this.makeRef(node.children[node.children.length - 1]));
16892        }
16893
16894        this.line("/Count " + this.count_r({
16895          count: 0
16896        }, node));
16897        this.objEnd();
16898      };
16899
16900      pdf.outline.renderItems = function (node) {
16901        var getVerticalCoordinateString = this.ctx.pdf.internal.getVerticalCoordinateString;
16902
16903        for (var i = 0; i < node.children.length; i++) {
16904          var item = node.children[i];
16905          this.objStart(item);
16906          this.line("/Title " + this.makeString(item.title));
16907          this.line("/Parent " + this.makeRef(node));
16908
16909          if (i > 0) {
16910            this.line("/Prev " + this.makeRef(node.children[i - 1]));
16911          }
16912
16913          if (i < node.children.length - 1) {
16914            this.line("/Next " + this.makeRef(node.children[i + 1])
16914);
16915          }
16916
16917          if (item.children.length > 0) {
16918            this.line("/First " + this.makeRef(item.children[0]));
16919            this.line("/Last " + this.makeRef(item.children[item.children.length - 1]));
16920          }
16921
16922          var count = this.count = this.count_r({
16923            count: 0
16924          }, item);
16925
16926          if (count > 0) {
16927            this.line("/Count " + count);
16928          }
16929
16930          if (item.options) {
16931            if (item.options.pageNumber) {
16932              // Explicit Destination
16933              //WARNING this assumes page ids are 3,5,7, etc.
16934              var info = pdf.internal.getPageInfo(item.options.pageNumber);
16935              this.line("/Dest " + "[" + info.objId + " 0 R /XYZ 0 " + getVerticalCoordinateString(0) + " 0]"); // this line does not work on all clients (pageNumber instead of page ref)
16936              //this.line('/Dest ' + '[' + (item.options.pageNumber - 1) + ' /XYZ 0 ' + this.ctx.pdf.internal.pageSize.getHeight() + ' 0]');
16937              // Named Destination
16938              // this.line('/Dest (page_' + (item.options.pageNumber) + ')');
16939              // Action Destination
16940              // var id = pdf.internal.newObject();
16941              // pdf.internal.write('<</D[' + (item.options.pageNumber - 1) + ' /XYZ null null null]/S/GoTo>> endobj');
16942              // this.line('/A ' + id + ' 0 R' );
16943            }
16944          }
16945
16946          this.objEnd();
16947        }
16948
16949        for (var z = 0; z < node.children.length; z++) {
16950          this.renderItems(node.children[z]);
16951        }
16952      };
16953
16954      pdf.outline.line = function (text) {
16955        this.ctx.val += text + "\r\n";
16956      };
16957
16958      pdf.outline.makeRef = function (node) {
16959        return node.id + " 0 R";
16960      };
16961
16962      pdf.outline.makeString = function (val) {
16963        return "(" + pdf.internal.pdfEscape(val) + ")";
16964      };
16965
16966      pdf.outline.objStart = function (node) {
16967        this.ctx.val += "\r\n" + node.id + " 0 obj" + "\r\n<<\r\n";
16968      };
16969
16970      pdf.outline.objEnd = function () {
16971        this.ctx.val += ">> \r\n" + "endobj" + "\r\n";
16972      };
16973
16974      pdf.outline.count_r = function (ctx, node) {
16975        for (var i = 0; i < node.children.length; i++) {
16976          ctx.count++;
16977          this.count_r(ctx, node.children[i]);
16978        }
16979
16980        return ctx.count;
16981      };
16982    }]);
16983    return this;
16984  })(jsPDF.API);
16985
16986  /**
16987   * @license
16988   *
16989   * Licensed under the MIT License.
16990   * http://opensource.org/licenses/mit-license
16991   */
16992  /**
16993   * jsPDF jpeg Support PlugIn
16994   *
16995   * @name jpeg_support
16996   * @module
16997   */
16998
16999  (function (jsPDFAPI) {
17000    /**
17001     * 0xc0 (SOF) Huffman  - Baseline DCT
17002     * 0xc1 (SOF) Huffman  - Extended sequential DCT
17003     * 0xc2 Progressive DCT (SOF2)
17004     * 0xc3 Spatial (sequential) lossless (SOF3)
17005     * 0xc4 Differential sequential DCT (SOF5)
17006     * 0xc5 Differential progressive DCT (SOF6)
17007     * 0xc6 Differential spatial (SOF7)
17008     * 0xc7
17009     */
17010
17011    var markers = [0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7]; //takes a string imgData containing the raw bytes of
17012    //a jpeg image and returns [width, height]
17013    //Algorithm from: http://www.64lines.com/jpeg-width-height
17014
17015    var getJpegInfo = function getJpegInfo(imgData) {
17016      var width, height, numcomponents;
17017      var blockLength = imgData.charCodeAt(4) * 256 + imgData.charCodeAt(5);
17018      var len = imgData.length;
17019      var result = {
17020        width: 0,
17021        height: 0,
17022        numcomponents: 1
17023      };
17024
17025      for (var i = 4; i < len; i += 2) {
17026        i += blockLength;
17027
17028        if (markers.indexOf(imgData.charCodeAt(i + 1)) !== -1) {
17029          height = imgData.charCodeAt(i + 5) * 256 + imgData.charCodeAt(i + 6);
17030          width = imgData.charCodeAt(i + 7) * 256 + imgData.charCodeAt(i + 8);
17031          numcomponents = imgData.charCodeAt(i + 9);
17032          result = {
17033            width: width,
17034            height: height,
17035            numcomponents: numcomponents
17036          };
17037          break;
17038        } else {
17039          blockLength = imgData.charCodeAt(i + 2) * 256 + imgData.charCodeAt(i + 3);
17040        }
17041      }
17042
17043      return result;
17044    };
17045    /**
17046     * @ignore
17047     */
17048
17049
17050    jsPDFAPI.processJPEG = function (data, index, alias, compression, dataAsBinaryString, colorSpace) {
17051      var filter = this.decode.DCT_DECODE,
17052          bpc = 8,
17053          dims,
17054          result = null;
17055
17056      if (typeof data === "string" || this.__addimage__.isArrayBuffer(data) || this.__addimage__.isArrayBufferView(data)) {
17057        // if we already have a stored binary string rep use that
17058        data = dataAsBinaryString || data;
17059        data = this.__addimage__.isArrayBuffer(data) ? new Uint8Array(data) : data;
17060        data = this.__addimage__.isArrayBufferView(data) ? this.__addimage__.arrayBufferToBinaryString(data) : data;
17061        dims = getJpegInfo(data);
17062
17063        switch (dims.numcomponents) {
17064          case 1:
17065            colorSpace = this.color_spaces.DEVICE_GRAY;
17066            break;
17067
17068          case 4:
17069            colorSpace = this.color_spaces.DEVICE_CMYK;
17070            break;
17071
17072          case 3:
17073            colorSpace = this.color_spaces.DEVICE_RGB;
17074            break;
17075        }
17076
17077        result = {
17078          data: data,
17079          width: dims.width,
17080          height: dims.height,
17081          colorSpace: colorSpace,
17082          bitsPerComponent: bpc,
17083          filter: filter,
17084          index: index,
17085          alias: alias
17086        };
17087      }
17088
17089      return result;
17090    };
17091  })(jsPDF.API);
17092
17093  // Generated by CoffeeScript 1.4.0
17094
17095  var PNG = function () {
17096    var APNG_BLEND_OP_SOURCE, APNG_DISPOSE_OP_BACKGROUND, APNG_DISPOSE_OP_PREVIOUS, makeImage, scratchCanvas, scratchCtx;
17097    APNG_DISPOSE_OP_BACKGROUND = 1;
17098    APNG_DISPOSE_OP_PREVIOUS = 2;
17099    APNG_BLEND_OP_SOURCE = 0;
17100
17101    function PNG(data) {
17102      var chunkSize, colors, palLen, delayDen, delayNum, frame, i, index, key, section, palShort, text, _i, _j, _ref;
17103
17104      this.data = data;
17105      this.pos = 8;
17106      this.palette = [];
17107      this.imgData = [];
17108      this.transparency = {};
17109      this.animation = null;
17110      this.text = {};
17111      frame = null;
17112
17113      while (true) {
17114        chunkSize = this.readUInt32();
17115
17116        section = function () {
17117          var _i, _results;
17118
17119          _results = [];
17120
17121          for (i = _i = 0; _i < 4; i = ++_i) {
17122            _results.push(String.fromCharCode(this.data[this.pos++]));
17123          }
17124
17125          return _results;
17126        }.call(this).join("");
17127
17128        switch (section) {
17129          case "IHDR":
17130            this.width = this.readUInt32();
17131            this.height = this.readUInt32();
17132            this.bits = this.data[this.pos++];
17133            this.colorType = this.data[this.pos++];
17134            this.compressionMethod = this.data[this.pos++];
17135            this.filterMethod = this.data[this.pos++];
17136            this.interlaceMethod = this.data[this.pos++];
17137            break;
17138
17139          case "acTL":
17140            this.animation = {
17141              numFrames: this.readUInt32(),
17142              numPlays: this.readUInt32() || Infinity,
17143              frames: []
17144            };
17145            break;
17146
17147          case "PLTE":
17148            this.palette = this.read(chunkSize);
17149            break;
17150
17151          case "fcTL":
17152            if (frame) {
17153              this.animation.frames.push(frame);
17154            }
17155
17156            this.pos += 4;
17157            frame = {
17158              width: this.readUInt32(),
17159              height: this.readUInt32(),
17160              xOffset: this.readUInt32(),
17161              yOffset: this.readUInt32()
17162            };
17163            delayNum = this.readUInt16();
17164            delayDen = this.readUInt16() || 100;
17165            frame.delay = 1000 * delayNum / delayDen;
17166            frame.disposeOp = this.data[this.pos++];
17167            frame.blendOp = this.data[this.pos++];
17168            frame.data = [];
17169            break;
17170
17171          case "IDAT":
17172          case "fdAT":
17173            if (section === "fdAT") {
17174              this.pos += 4;
17175              chunkSize -= 4;
17176            }
17177
17178            data = (frame != null ? frame.data : void 0) || this.imgData;
17179
17180            for (i = _i = 0; 0 <= chunkSize ? _i < chunkSize : _i > chunkSize; i = 0 <= chunkSize ? ++_i : --_i) {
17181              data.push(this.data[this.pos++]);
17182            }
17183
17184            break;
17185
17186          case "tRNS":
17187            this.transparency = {};
17188
17189            switch (this.colorType) {
17190              case 3:
17191                palLen = this.palette.length / 3;
17192                this.transparency.indexed = this.read(chunkSize);
17193                if (this.transparency.indexed.length > palLen) throw new Error("More transparent colors than palette size");
17194                /*
17195                 * According to the PNG spec trns should be increased to the same size as palette if shorter
17196                 */
17197                //palShort = 255 - this.transparency.indexed.length;
17198
17199                palShort = palLen - this.transparency.indexed.length;
17200
17201                if (palShort > 0) {
17202                  for (i = _j = 0; 0 <= palShort ? _j < palShort : _j > palShort; i = 0 <= palShort ? ++_j : --_j) {
17203                    this.transparency.indexed.push(255);
17204                  }
17205                }
17206
17207                break;
17208
17209              case 0:
17210                this.transparency.grayscale = this.read(chunkSize)[0];
17211                break;
17212
17213              case 2:
17214                this.transparency.rgb = this.read(chunkSize);
17215            }
17216
17217            break;
17218
17219          case "tEXt":
17220            text = this.read(chunkSize);
17221            index = text.indexOf(0);
17222            key = String.fromCharCode.apply(String, text.slice(0, index));
17223            this.text[key] = String.fromCharCode.apply(String, text.slice(index + 1));
17224            break;
17225
17226          case "IEND":
17227            if (frame) {
17228              this.animation.frames.push(frame);
17229            }
17230
17231            this.colors = function () {
17232              switch (this.colorType) {
17233                case 0:
17234                case 3:
17235                case 4:
17236                  return 1;
17237
17238                case 2:
17239                case 6:
17240                  return 3;
17241              }
17242            }.call(this);
17243
17244            this.hasAlphaChannel = (_ref = this.colorType) === 4 || _ref === 6;
17245            colors = this.colors + (this.hasAlphaChannel ? 1 : 0);
17246            this.pixelBitlength = this.bits * colors;
17247
17248            this.colorSpace = function () {
17249              switch (this.colors) {
17250                case 1:
17251                  return "DeviceGray";
17252
17253                case 3:
17254                  return "DeviceRGB";
17255              }
17256            }.call(this);
17257
17258            this.imgData = new Uint8Array(this.imgData);
17259            return;
17260
17261          default:
17262            this.pos += chunkSize;
17263        }
17264
17265        this.pos += 4;
17266
17267        if (this.pos > this.data.length) {
17268          throw new Error("Incomplete or corrupt PNG file");
17269        }
17270      }
17271    }
17272
17273    PNG.prototype.read = function (bytes) {
17274      var i, _i, _results;
17275
17276      _results = [];
17277
17278      for (i = _i = 0; 0 <= bytes ? _i < bytes : _i > bytes; i = 0 <= bytes ? ++_i : --_i) {
17279        _results.push(this.data[this.pos++]);
17280      }
17281
17282      return _results;
17283    };
17284
17285    PNG.prototype.readUInt32 = function () {
17286      var b1, b2, b3, b4;
17287      b1 = this.data[this.pos++] << 24;
17288      b2 = this.data[this.pos++] << 16;
17289      b3 = this.data[this.pos++] << 8;
17290      b4 = this.data[this.pos++];
17291      return b1 | b2 | b3 | b4;
17292    };
17293
17294    PNG.prototype.readUInt16 = function () {
17295      var b1, b2;
17296      b1 = this.data[this.pos++] << 8;
17297      b2 = this.data[this.pos++];
17298      return b1 | b2;
17299    };
17300
17301    PNG.prototype.decodePixels = function (data) {
17302      var pixelBytes = this.pixelBitlength / 8;
17303      var fullPixels = new Uint8Array(this.width * this.height * pixelBytes);
17304      var pos = 0;
17305
17306      var _this = this;
17307
17308      if (data == null) {
17309        data = this.imgData;
17310      }
17311
17312      if (data.length === 0) {
17313        return new Uint8Array(0);
17314      }
17315
17316      data = unzlibSync(data);
17317
17318      function pass(x0, y0, dx, dy) {
17319        var abyte, c, col, i, left, length, p, pa, paeth, pb, pc, pixels, row, scanlineLength, upper, upperLeft, _i, _j, _k, _l, _m;
17320
17321        var w = Math.ceil((_this.width - x0) / dx),
17322            h = Math.ceil((_this.height - y0) / dy);
17323        var isFull = _this.width == w && _this.height == h;
17324        scanlineLength = pixelBytes * w;
17325        pixels = isFull ? fullPixels : new Uint8Array(scanlineLength * h);
17326        length = data.length;
17327        row = 0;
17328        c = 0;
17329
17330        while (row < h && pos < length) {
17331          switch (data[pos++]) {
17332            case 0:
17333              for (i = _i = 0; _i < scanlineLength; i = _i += 1) {
17334                pixels[c++] = data[pos++];
17335              }
17336
17337              break;
17338
17339            case 1:
17340              for (i = _j = 0; _j < scanlineLength; i = _j += 1) {
17341                abyte = data[pos++];
17342                left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
17343                pixels[c++] = (abyte + left) % 256;
17344              }
17345
17346              break;
17347
17348            case 2:
17349              for (i = _k = 0; _k < scanlineLength; i = _k += 1) {
17350                abyte = data[pos++];
17351                col = (i - i % pixelBytes) / pixelBytes;
17352                upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + i % pixelBytes];
17353                pixels[c++] = (upper + abyte) % 256;
17354              }
17355
17356              break;
17357
17358            case 3:
17359              for (i = _l = 0; _l < scanlineLength; i = _l += 1) {
17360                abyte = data[pos++];
17361                col = (i - i % pixelBytes) / pixelBytes;
17362                left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
17363                upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + i % pixelBytes];
17364                pixels[c++] = (abyte + Math.floor((left + upper) / 2)) % 256;
17365              }
17366
17367              break;
17368
17369            case 4:
17370              for (i = _m = 0; _m < scanlineLength; i = _m += 1) {
17371                abyte = data[pos++];
17372                col = (i - i % pixelBytes) / pixelBytes;
17373                left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
17374
17375                if (row === 0) {
17376                  upper = upperLeft = 0;
17377                } else {
17378                  upper = pixels[(row - 1) * scanlineLength + col * pixelBytes + i % pixelBytes];
17379                  upperLeft = col && pixels[(row - 1) * scanlineLength + (col - 1) * pixelBytes + i % pixelBytes];
17380                }
17381
17382                p = left + upper - upperLeft;
17383                pa = Math.abs(p - left);
17384                pb = Math.abs(p - upper);
17385                pc = Math.abs(p - upperLeft);
17386
17387                if (pa <= pb && pa <= pc) {
17388                  paeth = left;
17389                } else if (pb <= pc) {
17390                  paeth = upper;
17391                } else {
17392                  paeth = upperLeft;
17393                }
17394
17395                pixels[c++] = (abyte + paeth) % 256;
17396              }
17397
17398              break;
17399
17400            default:
17401              throw new Error("Invalid filter algorithm: " + data[pos - 1]);
17402          }
17403
17404          if (!isFull) {
17405            var fullPos = ((y0 + row * dy) * _this.width + x0) * pixelBytes;
17406            var partPos = row * scanlineLength;
17407
17408            for (i = 0; i < w; i += 1) {
17409              for (var j = 0; j < pixelBytes; j += 1) {
17410                fullPixels[fullPos++] = pixels[partPos++];
17411              }
17412
17413              fullPos += (dx - 1) * pixelBytes;
17414            }
17415          }
17416
17417          row++;
17418        }
17419      }
17420
17421      if (_this.interlaceMethod == 1) {
17422        /*
17423            1 6 4 6 2 6 4 6
17424            7 7 7 7 7 7 7 7
17425            5 6 5 6 5 6 5 6
17426            7 7 7 7 7 7 7 7
17427            3 6 4 6 3 6 4 6
17428            7 7 7 7 7 7 7 7
17429            5 6 5 6 5 6 5 6
17430            7 7 7 7 7 7 7 7
17431          */
17432        pass(0, 0, 8, 8); // 1
17433
17434        /* NOTE these seem to follow the pattern:
17435         * pass(x, 0, 2*x, 2*x);
17436         * pass(0, x,   x, 2*x);
17437         * with x being 4, 2, 1.
17438         */
17439
17440        pass(4, 0, 8, 8); // 2
17441
17442        pass(0, 4, 4, 8); // 3
17443
17444        pass(2, 0, 4, 4); // 4
17445
17446        pass(0, 2, 2, 4); // 5
17447
17448        pass(1, 0, 2, 2); // 6
17449
17450        pass(0, 1, 1, 2); // 7
17451      } else {
17452        pass(0, 0, 1, 1);
17453      }
17454
17455      return fullPixels;
17456    };
17457
17458    PNG.prototype.decodePalette = function () {
17459      var c, i, length, palette, pos, ret, transparency, _i, _ref, _ref1;
17460
17461      palette = this.palette;
17462      transparency = this.transparency.indexed || [];
17463      ret = new Uint8Array((transparency.length || 0) + palette.length);
17464      pos = 0;
17465      length = palette.length;
17466      c = 0;
17467
17468      for (i = _i = 0, _ref = length; _i < _ref; i = _i += 3) {
17469        ret[pos++] = palette[i];
17470        ret[pos++] = palette[i + 1];
17471        ret[pos++] = palette[i + 2];
17472        ret[pos++] = (_ref1 = transparency[c++]) != null ? _ref1 : 255;
17473      }
17474
17475      return ret;
17476    };
17477
17478    PNG.prototype.copyToImageData = function (imageData, pixels) {
17479      var alpha, colors, data, i, input, j, k, length, palette, v, _ref;
17480
17481      colors = this.colors;
17482      palette = null;
17483      alpha = this.hasAlphaChannel;
17484
17485      if (this.palette.length) {
17486        palette = (_ref = this._decodedPalette) != null ? _ref : this._decodedPalette = this.decodePalette();
17487        colors = 4;
17488        alpha = true;
17489      }
17490
17491      data = imageData.data || imageData;
17492      length = data.length;
17493      input = palette || pixels;
17494      i = j = 0;
17495
17496      if (colors === 1) {
17497        while (i < length) {
17498          k = palette ? pixels[i / 4] * 4 : j;
17499          v = input[k++];
17500          data[i++] = v;
17501          data[i++] = v;
17502          data[i++] = v;
17503          data[i++] = alpha ? input[k++] : 255;
17504          j = k;
17505        }
17506      } else {
17507        while (i < length) {
17508          k = palette ? pixels[i / 4] * 4 : j;
17509          data[i++] = input[k++];
17510          data[i++] = input[k++];
17511          data[i++] = input[k++];
17512          data[i++] = alpha ? input[k++] : 255;
17513          j = k;
17514        }
17515      }
17516    };
17517
17518    PNG.prototype.decode = function () {
17519      var ret;
17520      ret = new Uint8Array(this.width * this.height * 4);
17521      this.copyToImageData(ret, this.decodePixels());
17522      return ret;
17523    };
17524
17525    var hasBrowserCanvas = function hasBrowserCanvas() {
17526      if (Object.prototype.toString.call(globalObject) === "[object Window]") {
17527        try {
17528          scratchCanvas = globalObject.document.createElement("canvas");
17529          scratchCtx = scratchCanvas.getContext("2d");
17530        } catch (e) {
17531          return false;
17532        }
17533
17534        return true;
17535      }
17536
17537      return false;
17538    };
17539
17540    hasBrowserCanvas();
17541
17542    makeImage = function makeImage(imageData) {
17543      if (hasBrowserCanvas() === true) {
17544        var img;
17545        scratchCtx.width = imageData.width;
17546        scratchCtx.height = imageData.height;
17547        scratchCtx.clearRect(0, 0, imageData.width, imageData.height);
17548        scratchCtx.putImageData(imageData, 0, 0);
17549        img = new Image();
17550        img.src = scratchCanvas.toDataURL();
17551        return img;
17552      }
17553
17554      throw new Error("This method requires a Browser with Canvas-capability.");
17555    };
17556
17557    PNG.prototype.decodeFrames = function (ctx) {
17558      var frame, i, imageData, pixels, _i, _len, _ref, _results;
17559
17560      if (!this.animation) {
17561        return;
17562      }
17563
17564      _ref = this.animation.frames;
17565      _results = [];
17566
17567      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
17568        frame = _ref[i];
17569        imageData = ctx.createImageData(frame.width, frame.height);
17570        pixels = this.decodePixels(new Uint8Array(frame.data));
17571        this.copyToImageData(imageData, pixels);
17572        frame.imageData = imageData;
17573
17574        _results.push(frame.image = makeImage(imageData));
17575      }
17576
17577      return _results;
17578    };
17579
17580    PNG.prototype.renderFrame = function (ctx, number) {
17581      var frame, frames, prev;
17582      frames = this.animation.frames;
17583      frame = frames[number];
17584      prev = frames[number - 1];
17585
17586      if (number === 0) {
17587        ctx.clearRect(0, 0, this.width, this.height);
17588      }
17589
17590      if ((prev != null ? prev.disposeOp : void 0) === APNG_DISPOSE_OP_BACKGROUND) {
17591        ctx.clearRect(prev.xOffset, prev.yOffset, prev.width, prev.height);
17592      } else if ((prev != null ? prev.disposeOp : void 0) === APNG_DISPOSE_OP_PREVIOUS) {
17593        ctx.putImageData(prev.imageData, prev.xOffset, prev.yOffset);
17594      }
17595
17596      if (frame.blendOp === APNG_BLEND_OP_SOURCE) {
17597        ctx.clearRect(frame.xOffset, frame.yOffset, frame.width, frame.height);
17598      }
17599
17600      return ctx.drawImage(frame.image, frame.xOffset, frame.yOffset);
17601    };
17602
17603    PNG.prototype.animate = function (ctx) {
17604      var _doFrame,
17605          frameNumber,
17606          frames,
17607          numFrames,
17608          numPlays,
17609          _ref,
17610          _this = this;
17611
17612      frameNumber = 0;
17613      _ref = this.animation, numFrames = _ref.numFrames, frames = _ref.frames, numPlays = _ref.numPlays;
17614      return (_doFrame = function doFrame() {
17615        var f, frame;
17616        f = frameNumber++ % numFrames;
17617        frame = frames[f];
17618
17619        _this.renderFrame(ctx, f);
17620
17621        if (numFrames > 1 && frameNumber / numFrames < numPlays) {
17622          return _this.animation._timeout = setTimeout(_doFrame, frame.delay);
17623        }
17624      })();
17625    };
17626
17627    PNG.prototype.stopAnimation = function () {
17628      var _ref;
17629
17630      return clearTimeout((_ref = this.animation) != null ? _ref._timeout : void 0);
17631    };
17632
17633    PNG.prototype.render = function (canvas) {
17634      var ctx, data;
17635
17636      if (canvas._png) {
17637        canvas._png.stopAnimation();
17638      }
17639
17640      canvas._png = this;
17641      canvas.width = this.width;
17642      canvas.height = this.height;
17643      ctx = canvas.getContext("2d");
17644
17645      if (this.animation) {
17646        this.decodeFrames(ctx);
17647        return this.animate(ctx);
17648      } else {
17649        data = ctx.createImageData(this.width, this.height);
17650        this.copyToImageData(data, this.decodePixels());
17651        return ctx.putImageData(data, 0, 0);
17652      }
17653    };
17654
17655    return PNG;
17656  }();
17657
17658  /**
17659   * @license
17660   *
17661   * Copyright (c) 2014 James Robb, https://github.com/jamesbrobb
17662   *
17663   * Permission is hereby granted, free of charge, to any person obtaining
17664   * a copy of this software and associated documentation files (the
17665   * "Software"), to deal in the Software without restriction, including
17666   * without limitation the rights to use, copy, modify, merge, publish,
17667   * distribute, sublicense, and/or sell copies of the Software, and to
17668   * permit persons to whom the Software is furnished to do so, subject to
17669   * the following conditions:
17670   *
17671   * The above copyright notice and this permission notice shall be
17672   * included in all copies or substantial portions of the Software.
17673   *
17674   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17675   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17676   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17677   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
17678   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17679   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
17680   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17681   * ====================================================================
17682   */
17683  /**
17684   * jsPDF PNG PlugIn
17685   * @name png_support
17686   * @module
17687   */
17688
17689  (function (jsPDFAPI) {
17690    /*
17691     * @see http://www.w3.org/TR/PNG-Chunks.html
17692     *
17693     Color    Allowed      Interpretation
17694     Type     Bit Depths
17695        0       1,2,4,8,16  Each pixel is a grayscale sample.
17696        2       8,16        Each pixel is an R,G,B triple.
17697        3       1,2,4,8     Each pixel is a palette index;
17698                           a PLTE chunk must appear.
17699        4       8,16        Each pixel is a grayscale sample,
17700                           followed by an alpha sample.
17701        6       8,16        Each pixel is an R,G,B triple,
17702                           followed by an alpha sample.
17703    */
17704
17705    /*
17706     * PNG filter method types
17707     *
17708     * @see http://www.w3.org/TR/PNG-Filters.html
17709     * @see http://www.libpng.org/pub/png/book/chapter09.html
17710     *
17711     * This is what the value 'Predictor' in decode params relates to
17712     *
17713     * 15 is "optimal prediction", which means the prediction algorithm can change from line to line.
17714     * 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.
17715     *
17716       0       None
17717       1       Sub
17718       2       Up
17719       3       Average
17720       4       Paeth
17721     */
17722
17723    var canCompress = function canCompress(value) {
17724      return value !== jsPDFAPI.image_compression.NONE && hasCompressionJS();
17725    };
17726
17727    var hasCompressionJS = function hasCompressionJS() {
17728      return typeof zlibSync === "function";
17729    };
17730
17731    var compressBytes = function compressBytes(bytes, lineLength, colorsPerPixel, compression) {
17732      var level = 4;
17733      var filter_method = filterUp;
17734
17735      switch (compression) {
17736        case jsPDFAPI.image_compression.FAST:
17737          level = 1;
17738          filter_method = filterSub;
17739          break;
17740
17741        case jsPDFAPI.image_compression.MEDIUM:
17742          level = 6;
17743          filter_method = filterAverage;
17744          break;
17745
17746        case jsPDFAPI.image_compression.SLOW:
17747          level = 9;
17748          filter_method = filterPaeth;
17749          break;
17750      }
17751
17752      bytes = applyPngFilterMethod(bytes, lineLength, colorsPerPixel, filter_method);
17753      var dat = zlibSync(bytes, {
17754        level: level
17755      });
17756      return jsPDFAPI.__addimage__.arrayBufferToBinaryString(dat);
17757    };
17758
17759    var applyPngFilterMethod = function applyPngFilterMethod(bytes, lineLength, colorsPerPixel, filter_method) {
17760      var lines = bytes.length / lineLength,
17761          result = new Uint8Array(bytes.length + lines),
17762          filter_methods = getFilterMethods(),
17763          line,
17764          prevLine,
17765          offset;
17766
17767      for (var i = 0; i < lines; i += 1) {
17768        offset = i * lineLength;
17769        line = bytes.subarray(offset, offset + lineLength);
17770
17771        if (filter_method) {
17772          result.set(filter_method(line, colorsPerPixel, prevLine), offset + i);
17773        } else {
17774          var len = filter_methods.length,
17775              results = [];
17776
17777          for (var j; j < len; j += 1) {
17778            results[j] = filter_methods[j](line, colorsPerPixel, prevLine);
17779          }
17780
17781          var ind = getIndexOfSmallestSum(results.concat());
17782          result.set(results[ind], offset + i);
17783        }
17784
17785        prevLine = line;
17786      }
17787
17788      return result;
17789    };
17790
17791    var filterNone = function filterNone(line) {
17792      /*var result = new Uint8Array(line.length + 1);
17793      result[0] = 0;
17794      result.set(line, 1);*/
17795      var result = Array.apply([], line);
17796      result.unshift(0);
17797      return result;
17798    };
17799
17800    var filterSub = function filterSub(line, colorsPerPixel) {
17801      var result = [],
17802          len = line.length,
17803          left;
17804      result[0] = 1;
17805
17806      for (var i = 0; i < len; i += 1) {
17807        left = line[i - colorsPerPixel] || 0;
17808        result[i + 1] = line[i] - left + 0x0100 & 0xff;
17809      }
17810
17811      return result;
17812    };
17813
17814    var filterUp = function filterUp(line, colorsPerPixel, prevLine) {
17815      var result = [],
17816          len = line.length,
17817          up;
17818      result[0] = 2;
17819
17820      for (var i = 0; i < len; i += 1) {
17821        up = prevLine && prevLine[i] || 0;
17822        result[i + 1] = line[i] - up + 0x0100 & 0xff;
17823      }
17824
17825      return result;
17826    };
17827
17828    var filterAverage = function filterAverage(line, colorsPerPixel, prevLine) {
17829      var result = [],
17830          len = line.length,
17831          left,
17832          up;
17833      result[0] = 3;
17834
17835      for (var i = 0; i < len; i += 1) {
17836        left = line[i - colorsPerPixel] || 0;
17837        up = prevLine && prevLine[i] || 0;
17838        result[i + 1] = line[i] + 0x0100 - (left + up >>> 1) & 0xff;
17839      }
17840
17841      return result;
17842    };
17843
17844    var filterPaeth = function filterPaeth(line, colorsPerPixel, prevLine) {
17845      var result = [],
17846          len = line.length,
17847          left,
17848          up,
17849          upLeft,
17850          paeth;
17851      result[0] = 4;
17852
17853      for (var i = 0; i < len; i += 1) {
17854        left = line[i - colorsPerPixel] || 0;
17855        up = prevLine && prevLine[i] || 0;
17856        upLeft = prevLine && prevLine[i - colorsPerPixel] || 0;
17857        paeth = paethPredictor(left, up, upLeft);
17858        result[i + 1] = line[i] - paeth + 0x0100 & 0xff;
17859      }
17860
17861      return result;
17862    };
17863
17864    var paethPredictor = function paethPredictor(left, up, upLeft) {
17865      if (left === up && up === upLeft) {
17866        return left;
17867      }
17868
17869      var pLeft = Math.abs(up - upLeft),
17870          pUp = Math.abs(left - upLeft),
17871          pUpLeft = Math.abs(left + up - upLeft - upLeft);
17872      return pLeft <= pUp && pLeft <= pUpLeft ? left : pUp <= pUpLeft ? up : upLeft;
17873    };
17874
17875    var getFilterMethods = function getFilterMethods() {
17876      return [filterNone, filterSub, filterUp, filterAverage, filterPaeth];
17877    };
17878
17879    var getIndexOfSmallestSum = function getIndexOfSmallestSum(arrays) {
17880      var sum = arrays.map(function (value) {
17881        return value.reduce(function (pv, cv) {
17882          return pv + Math.abs(cv);
17883        }, 0);
17884      });
17885      return sum.indexOf(Math.min.apply(null, sum));
17886    };
17887
17888    var getPredictorFromCompression = function getPredictorFromCompression(compression) {
17889      var predictor;
17890
17891      switch (compression) {
17892        case jsPDFAPI.image_compression.FAST:
17893          predictor = 11;
17894          break;
17895
17896        case jsPDFAPI.image_compression.MEDIUM:
17897          predictor = 13;
17898          break;
17899
17900        case jsPDFAPI.image_compression.SLOW:
17901          predictor = 14;
17902          break;
17903
17904        default:
17905          predictor = 12;
17906          break;
17907      }
17908
17909      return predictor;
17910    };
17911    /**
17912     * @name processPNG
17913     * @function
17914     * @ignore
17915     */
17916
17917
17918    jsPDFAPI.processPNG = function (imageData, index, alias, compression) {
17919
17920      var colorSpace,
17921          filter = this.decode.FLATE_DECODE,
17922          bitsPerComponent,
17923          image,
17924          decodeParameters = "",
17925          trns,
17926          colors,
17927          pal,
17928          smask,
17929          pixels,
17930          len,
17931          alphaData,
17932          imgData,
17933          hasColors,
17934          pixel,
17935          i,
17936          n;
17937      if (this.__addimage__.isArrayBuffer(imageData)) imageData = new Uint8Array(imageData);
17938
17939      if (this.__addimage__.isArrayBufferView(imageData)) {
17940        image = new PNG(imageData);
17941        imageData = image.imgData;
17942        bitsPerComponent = image.bits;
17943        colorSpace = image.colorSpace;
17944        colors = image.colors;
17945        /*
17946         * colorType 6 - Each pixel is an R,G,B triple, followed by an alpha sample.
17947         *
17948         * colorType 4 - Each pixel is a grayscale sample, followed by an alpha sample.
17949         *
17950         * Extract alpha to create two separate images, using the alpha as a sMask
17951         */
17952
17953        if ([4, 6].indexOf(image.colorType) !== -1) {
17954          /*
17955           * processes 8 bit RGBA and grayscale + alpha images
17956           */
17957          if (image.bits === 8) {
17958            pixels = image.pixelBitlength == 32 ? new Uint32Array(image.decodePixels().buffer) : image.pixelBitlength == 16 ? new Uint16Array(image.decodePixels().buffer) : new Uint8Array(image.decodePixels().buffer);
17959            len = pixels.length;
17960            imgData = new Uint8Array(len * image.colors);
17961            alphaData = new Uint8Array(len);
17962            var pDiff = image.pixelBitlength - image.bits;
17963            i = 0;
17964            n = 0;
17965            var pbl;
17966
17967            for (; i < len; i++) {
17968              pixel = pixels[i];
17969              pbl = 0;
17970
17971              while (pbl < pDiff) {
17972                imgData[n++] = pixel >>> pbl & 0xff;
17973                pbl = pbl + image.bits;
17974              }
17975
17976              alphaData[i] = pixel >>> pbl & 0xff;
17977            }
17978          }
17979          /*
17980           * processes 16 bit RGBA and grayscale + alpha images
17981           */
17982
17983
17984          if (image.bits === 16) {
17985            pixels = new Uint32Array(image.decodePixels().buffer);
17986            len = pixels.length;
17987            imgData = new Uint8Array(len * (32 / image.pixelBitlength) * image.colors);
17988            alphaData = new Uint8Array(len * (32 / image.pixelBitlength));
17989            hasColors = image.colors > 1;
17990            i = 0;
17991            n = 0;
17992            var a = 0;
17993
17994            while (i < len) {
17995              pixel = pixels[i++];
17996              imgData[n++] = pixel >>> 0 & 0xff;
17997
17998              if (hasColors) {
17999                imgData[n++] = pixel >>> 16 & 0xff;
18000                pixel = pixels[i++];
18001                imgData[n++] = pixel >>> 0 & 0xff;
18002              }
18003
18004              alphaData[a++] = pixel >>> 16 & 0xff;
18005            }
18006
18007            bitsPerComponent = 8;
18008          }
18009
18010          if (canCompress(compression)) {
18011            imageData = compressBytes(imgData, image.width * image.colors, image.colors, compression);
18012            smask = compressBytes(alphaData, image.width, 1, compression);
18013          } else {
18014            imageData = imgData;
18015            smask = alphaData;
18016            filter = undefined;
18017          }
18018        }
18019        /*
18020         * Indexed png. Each pixel is a palette index.
18021         */
18022
18023
18024        if (image.colorType === 3) {
18025          colorSpace = this.color_spaces.INDEXED;
18026          pal = image.palette;
18027
18028          if (image.transparency.indexed) {
18029            var trans = image.transparency.indexed;
18030            var total = 0;
18031            i = 0;
18032            len = trans.length;
18033
18034            for (; i < len; ++i) {
18035              total += trans[i];
18036            }
18037
18038            total = total / 255;
18039            /*
18040             * a single color is specified as 100% transparent (0),
18041             * so we set trns to use a /Mask with that index
18042             */
18043
18044            if (total === len - 1 && trans.indexOf(0) !== -1) {
18045              trns = [trans.indexOf(0)];
18046              /*
18047               * there's more than one colour within the palette that specifies
18048               * a transparency value less than 255, so we unroll the pixels to create an image sMask
18049               */
18050            } else if (total !== len) {
18051              pixels = image.decodePixels();
18052              alphaData = new Uint8Array(pixels.length);
18053              i = 0;
18054              len = pixels.length;
18055
18056              for (; i < len; i++) {
18057                alphaData[i] = trans[pixels[i]];
18058              }
18059
18060              smask = compressBytes(alphaData, image.width, 1);
18061            }
18062          }
18063        }
18064
18065        var predictor = getPredictorFromCompression(compression);
18066
18067        if (filter === this.decode.FLATE_DECODE) {
18068          decodeParameters = "/Predictor " + predictor + " ";
18069        }
18070
18071        decodeParameters += "/Colors " + colors + " /BitsPerComponent " + bitsPerComponent + " /Columns " + image.width;
18072
18073        if (this.__addimage__.isArrayBuffer(imageData) || this.__addimage__.isArrayBufferView(imageData)) {
18074          imageData = this.__addimage__.arrayBufferToBinaryString(imageData);
18075        }
18076
18077        if (smask && this.__addimage__.isArrayBuffer(smask) || this.__addimage__.isArrayBufferView(smask)) {
18078          smask = this.__addimage__.arrayBufferToBinaryString(smask);
18079        }
18080
18081        return {
18082          alias: alias,
18083          data: imageData,
18084          index: index,
18085          filter: filter,
18086          decodeParameters: decodeParameters,
18087          transparency: trns,
18088          palette: pal,
18089          sMask: smask,
18090          predictor: predictor,
18091          width: image.width,
18092          height: image.height,
18093          bitsPerComponent: bitsPerComponent,
18094          colorSpace: colorSpace
18095        };
18096      }
18097    };
18098  })(jsPDF.API);
18099
18100  /**
18101   * @license
18102   * (c) Dean McNamee <[email protected]>, 2013.
18103   *
18104   * https://github.com/deanm/omggif
18105   *
18106   * Permission is hereby granted, free of charge, to any person obtaining a copy
18107   * of this software and associated documentation files (the "Software"), to
18108   * deal in the Software without restriction, including without limitation the
18109   * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18110   * sell copies of the Software, and to permit persons to whom the Software is
18111   * furnished to do so, subject to the following conditions:
18112   *
18113   * The above copyright notice and this permission notice shall be included in
18114   * all copies or substantial portions of the Software.
18115   *
18116   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18117   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18118   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18119   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18120   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18121   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
18122   * IN THE SOFTWARE.
18123   *
18124   * omggif is a JavaScript implementation of a GIF 89a encoder and decoder,
18125   * including animation and compression.  It does not rely on any specific
18126   * underlying system, so should run in the browser, Node, or Plask.
18127   */
18128
18129  function GifReader(buf) {
18130    var p = 0; // - Header (GIF87a or GIF89a).
18131
18132    if (buf[p++] !== 0x47 || buf[p++] !== 0x49 || buf[p++] !== 0x46 || buf[p++] !== 0x38 || (buf[p++] + 1 & 0xfd) !== 0x38 || buf[p++] !== 0x61) {
18133      throw new Error("Invalid GIF 87a/89a header.");
18134    } // - Logical Screen Descriptor.
18135
18136
18137    var width = buf[p++] | buf[p++] << 8;
18138    var height = buf[p++] | buf[p++] << 8;
18139    var pf0 = buf[p++]; // <Packed Fields>.
18140
18141    var global_palette_flag = pf0 >> 7;
18142    var num_global_colors_pow2 = pf0 & 0x7;
18143    var num_global_colors = 1 << num_global_colors_pow2 + 1;
18144    var background = buf[p++];
18145    buf[p++]; // Pixel aspect ratio (unused?).
18146
18147    var global_palette_offset = null;
18148    var global_palette_size = null;
18149
18150    if (global_palette_flag) {
18151      global_palette_offset = p;
18152      global_palette_size = num_global_colors;
18153      p += num_global_colors * 3; // Seek past palette.
18154    }
18155
18156    var no_eof = true;
18157    var frames = [];
vendor: 18,334 bytes, lines 18158-18635
18158    var delay = 0;
18159    var transparent_index = null;
18160    var disposal = 0; // 0 - No disposal specified.
18161
18162    var loop_count = null;
18163    this.width = width;
18164    this.height = height;
18165
18166    while (no_eof && p < buf.length) {
18167      switch (buf[p++]) {
18168        case 0x21:
18169          // Graphics Control Extension Block
18170          switch (buf[p++]) {
18171            case 0xff:
18172              // Application specific block
18173              // Try if it's a Netscape block (with animation loop counter).
18174              if (buf[p] !== 0x0b || // 21 FF already read, check block size.
18175              // NETSCAPE2.0
18176              buf[p + 1] == 0x4e && buf[p + 2] == 0x45 && buf[p + 3] == 0x54 && buf[p + 4] == 0x53 && buf[p + 5] == 0x43 && buf[p + 6] == 0x41 && buf[p + 7] == 0x50 && buf[p + 8] == 0x45 && buf[p + 9] == 0x32 && buf[p + 10] == 0x2e && buf[p + 11] == 0x30 && // Sub-block
18177              buf[p + 12] == 0x03 && buf[p + 13] == 0x01 && buf[p + 16] == 0) {
18178                p += 14;
18179                loop_count = buf[p++] | buf[p++] << 8;
18180                p++; // Skip terminator.
18181              } else {
18182                // We don't know what it is, just try to get past it.
18183                p += 12;
18184
18185                while (true) {
18186                  // Seek through subblocks.
18187                  var block_size = buf[p++]; // Bad block size (ex: undefined from an out of bounds read).
18188
18189                  if (!(block_size >= 0)) throw Error("Invalid block size");
18190                  if (block_size === 0) break; // 0 size is terminator
18191
18192                  p += block_size;
18193                }
18194              }
18195
18196              break;
18197
18198            case 0xf9:
18199              // Graphics Control Extension
18200              if (buf[p++] !== 0x4 || buf[p + 4] !== 0) throw new Error("Invalid graphics extension block.");
18201              var pf1 = buf[p++];
18202              delay = buf[p++] | buf[p++] << 8;
18203              transparent_index = buf[p++];
18204              if ((pf1 & 1) === 0) transparent_index = null;
18205              disposal = pf1 >> 2 & 0x7;
18206              p++; // Skip terminator.
18207
18208              break;
18209
18210            case 0xfe:
18211              // Comment Extension.
18212              while (true) {
18213                // Seek through subblocks.
18214                var block_size = buf[p++]; // Bad block size (ex: undefined from an out of bounds read).
18215
18216                if (!(block_size >= 0)) throw Error("Invalid block size");
18217                if (block_size === 0) break; // 0 size is terminator
18218                // console.log(buf.slice(p, p+block_size).toString('ascii'));
18219
18220                p += block_size;
18221              }
18222
18223              break;
18224
18225            default:
18226              throw new Error("Unknown graphic control label: 0x" + buf[p - 1].toString(16));
18227          }
18228
18229          break;
18230
18231        case 0x2c:
18232          // Image Descriptor.
18233          var x = buf[p++] | buf[p++] << 8;
18234          var y = buf[p++] | buf[p++] << 8;
18235          var w = buf[p++] | buf[p++] << 8;
18236          var h = buf[p++] | buf[p++] << 8;
18237          var pf2 = buf[p++];
18238          var local_palette_flag = pf2 >> 7;
18239          var interlace_flag = pf2 >> 6 & 1;
18240          var num_local_colors_pow2 = pf2 & 0x7;
18241          var num_local_colors = 1 << num_local_colors_pow2 + 1;
18242          var palette_offset = global_palette_offset;
18243          var palette_size = global_palette_size;
18244          var has_local_palette = false;
18245
18246          if (local_palette_flag) {
18247            var has_local_palette = true;
18248            palette_offset = p; // Override with local palette.
18249
18250            palette_size = num_local_colors;
18251            p += num_local_colors * 3; // Seek past palette.
18252          }
18253
18254          var data_offset = p;
18255          p++; // codesize
18256
18257          while (true) {
18258            var block_size = buf[p++]; // Bad block size (ex: undefined from an out of bounds read).
18259
18260            if (!(block_size >= 0)) throw Error("Invalid block size");
18261            if (block_size === 0) break; // 0 size is terminator
18262
18263            p += block_size;
18264          }
18265
18266          frames.push({
18267            x: x,
18268            y: y,
18269            width: w,
18270            height: h,
18271            has_local_palette: has_local_palette,
18272            palette_offset: palette_offset,
18273            palette_size: palette_size,
18274            data_offset: data_offset,
18275            data_length: p - data_offset,
18276            transparent_index: transparent_index,
18277            interlaced: !!interlace_flag,
18278            delay: delay,
18279            disposal: disposal
18280          });
18281          break;
18282
18283        case 0x3b:
18284          // Trailer Marker (end of file).
18285          no_eof = false;
18286          break;
18287
18288        default:
18289          throw new Error("Unknown gif block: 0x" + buf[p - 1].toString(16));
18290      }
18291    }
18292
18293    this.numFrames = function () {
18294      return frames.length;
18295    };
18296
18297    this.loopCount = function () {
18298      return loop_count;
18299    };
18300
18301    this.frameInfo = function (frame_num) {
18302      if (frame_num < 0 || frame_num >= frames.length) throw new Error("Frame index out of range.");
18303      return frames[frame_num];
18304    };
18305
18306    this.decodeAndBlitFrameBGRA = function (frame_num, pixels) {
18307      var frame = this.frameInfo(frame_num);
18308      var num_pixels = frame.width * frame.height;
18309      var index_stream = new Uint8Array(num_pixels); // At most 8-bit indices.
18310
18311      GifReaderLZWOutputIndexStream(buf, frame.data_offset, index_stream, num_pixels);
18312      var palette_offset = frame.palette_offset; // NOTE(deanm): It seems to be much faster to compare index to 256 than
18313      // to === null.  Not sure why, but CompareStub_EQ_STRICT shows up high in
18314      // the profile, not sure if it's related to using a Uint8Array.
18315
18316      var trans = frame.transparent_index;
18317      if (trans === null) trans = 256; // We are possibly just blitting to a portion of the entire frame.
18318      // That is a subrect within the framerect, so the additional pixels
18319      // must be skipped over after we finished a scanline.
18320
18321      var framewidth = frame.width;
18322      var framestride = width - framewidth;
18323      var xleft = framewidth; // Number of subrect pixels left in scanline.
18324      // Output indices of the top left and bottom right corners of the subrect.
18325
18326      var opbeg = (frame.y * width + frame.x) * 4;
18327      var opend = ((frame.y + frame.height) * width + frame.x) * 4;
18328      var op = opbeg;
18329      var scanstride = framestride * 4; // Use scanstride to skip past the rows when interlacing.  This is skipping
18330      // 7 rows for the first two passes, then 3 then 1.
18331
18332      if (frame.interlaced === true) {
18333        scanstride += width * 4 * 7; // Pass 1.
18334      }
18335
18336      var interlaceskip = 8; // Tracking the row interval in the current pass.
18337
18338      for (var i = 0, il = index_stream.length; i < il; ++i) {
18339        var index = index_stream[i];
18340
18341        if (xleft === 0) {
18342          // Beginning of new scan line
18343          op += scanstride;
18344          xleft = framewidth;
18345
18346          if (op >= opend) {
18347            // Catch the wrap to switch passes when interlacing.
18348            scanstride = framestride * 4 + width * 4 * (interlaceskip - 1); // interlaceskip / 2 * 4 is interlaceskip << 1.
18349
18350            op = opbeg + (framewidth + framestride) * (interlaceskip << 1);
18351            interlaceskip >>= 1;
18352          }
18353        }
18354
18355        if (index === trans) {
18356          op += 4;
18357        } else {
18358          var r = buf[palette_offset + index * 3];
18359          var g = buf[palette_offset + index * 3 + 1];
18360          var b = buf[palette_offset + index * 3 + 2];
18361          pixels[op++] = b;
18362          pixels[op++] = g;
18363          pixels[op++] = r;
18364          pixels[op++] = 255;
18365        }
18366
18367        --xleft;
18368      }
18369    }; // I will go to copy and paste hell one day...
18370
18371
18372    this.decodeAndBlitFrameRGBA = function (frame_num, pixels) {
18373      var frame = this.frameInfo(frame_num);
18374      var num_pixels = frame.width * frame.height;
18375      var index_stream = new Uint8Array(num_pixels); // At most 8-bit indices.
18376
18377      GifReaderLZWOutputIndexStream(buf, frame.data_offset, index_stream, num_pixels);
18378      var palette_offset = frame.palette_offset; // NOTE(deanm): It seems to be much faster to compare index to 256 than
18379      // to === null.  Not sure why, but CompareStub_EQ_STRICT shows up high in
18380      // the profile, not sure if it's related to using a Uint8Array.
18381
18382      var trans = frame.transparent_index;
18383      if (trans === null) trans = 256; // We are possibly just blitting to a portion of the entire frame.
18384      // That is a subrect within the framerect, so the additional pixels
18385      // must be skipped over after we finished a scanline.
18386
18387      var framewidth = frame.width;
18388      var framestride = width - framewidth;
18389      var xleft = framewidth; // Number of subrect pixels left in scanline.
18390      // Output indices of the top left and bottom right corners of the subrect.
18391
18392      var opbeg = (frame.y * width + frame.x) * 4;
18393      var opend = ((frame.y + frame.height) * width + frame.x) * 4;
18394      var op = opbeg;
18395      var scanstride = framestride * 4; // Use scanstride to skip past the rows when interlacing.  This is skipping
18396      // 7 rows for the first two passes, then 3 then 1.
18397
18398      if (frame.interlaced === true) {
18399        scanstride += width * 4 * 7; // Pass 1.
18400      }
18401
18402      var interlaceskip = 8; // Tracking the row interval in the current pass.
18403
18404      for (var i = 0, il = index_stream.length; i < il; ++i) {
18405        var index = index_stream[i];
18406
18407        if (xleft === 0) {
18408          // Beginning of new scan line
18409          op += scanstride;
18410          xleft = framewidth;
18411
18412          if (op >= opend) {
18413            // Catch the wrap to switch passes when interlacing.
18414            scanstride = framestride * 4 + width * 4 * (interlaceskip - 1); // interlaceskip / 2 * 4 is interlaceskip << 1.
18415
18416            op = opbeg + (framewidth + framestride) * (interlaceskip << 1);
18417            interlaceskip >>= 1;
18418          }
18419        }
18420
18421        if (index === trans) {
18422          op += 4;
18423        } else {
18424          var r = buf[palette_offset + index * 3];
18425          var g = buf[palette_offset + index * 3 + 1];
18426          var b = buf[palette_offset + index * 3 + 2];
18427          pixels[op++] = r;
18428          pixels[op++] = g;
18429          pixels[op++] = b;
18430          pixels[op++] = 255;
18431        }
18432
18433        --xleft;
18434      }
18435    };
18436  }
18437
18438  function GifReaderLZWOutputIndexStream(code_stream, p, output, output_length) {
18439    var min_code_size = code_stream[p++];
18440    var clear_code = 1 << min_code_size;
18441    var eoi_code = clear_code + 1;
18442    var next_code = eoi_code + 1;
18443    var cur_code_size = min_code_size + 1; // Number of bits per code.
18444    // NOTE: This shares the same name as the encoder, but has a different
18445    // meaning here.  Here this masks each code coming from the code stream.
18446
18447    var code_mask = (1 << cur_code_size) - 1;
18448    var cur_shift = 0;
18449    var cur = 0;
18450    var op = 0; // Output pointer.
18451
18452    var subblock_size = code_stream[p++]; // TODO(deanm): Would using a TypedArray be any faster?  At least it would
18453    // solve the fast mode / backing store uncertainty.
18454    // var code_table = Array(4096);
18455
18456    var code_table = new Int32Array(4096); // Can be signed, we only use 20 bits.
18457
18458    var prev_code = null; // Track code-1.
18459
18460    while (true) {
18461      // Read up to two bytes, making sure we always 12-bits for max sized code.
18462      while (cur_shift < 16) {
18463        if (subblock_size === 0) break; // No more data to be read.
18464
18465        cur |= code_stream[p++] << cur_shift;
18466        cur_shift += 8;
18467
18468        if (subblock_size === 1) {
18469          // Never let it get to 0 to hold logic above.
18470          subblock_size = code_stream[p++]; // Next subblock.
18471        } else {
18472          --subblock_size;
18473        }
18474      } // TODO(deanm): We should never really get here, we should have received
18475      // and EOI.
18476
18477
18478      if (cur_shift < cur_code_size) break;
18479      var code = cur & code_mask;
18480      cur >>= cur_code_size;
18481      cur_shift -= cur_code_size; // TODO(deanm): Maybe should check that the first code was a clear code,
18482      // at least this is what you're supposed to do.  But actually our encoder
18483      // now doesn't emit a clear code first anyway.
18484
18485      if (code === clear_code) {
18486        // We don't actually have to clear the table.  This could be a good idea
18487        // for greater error checking, but we don't really do any anyway.  We
18488        // will just track it with next_code and overwrite old entries.
18489        next_code = eoi_code + 1;
18490        cur_code_size = min_code_size + 1;
18491        code_mask = (1 << cur_code_size) - 1; // Don't update prev_code ?
18492
18493        prev_code = null;
18494        continue;
18495      } else if (code === eoi_code) {
18496        break;
18497      } // We have a similar situation as the decoder, where we want to store
18498      // variable length entries (code table entries), but we want to do in a
18499      // faster manner than an array of arrays.  The code below stores sort of a
18500      // linked list within the code table, and then "chases" through it to
18501      // construct the dictionary entries.  When a new entry is created, just the
18502      // last byte is stored, and the rest (prefix) of the entry is only
18503      // referenced by its table entry.  Then the code chases through the
18504      // prefixes until it reaches a single byte code.  We have to chase twice,
18505      // first to compute the length, and then to actually copy the data to the
18506      // output (backwards, since we know the length).  The alternative would be
18507      // storing something in an intermediate stack, but that doesn't make any
18508      // more sense.  I implemented an approach where it also stored the length
18509      // in the code table, although it's a bit tricky because you run out of
18510      // bits (12 + 12 + 8), but I didn't measure much improvements (the table
18511      // entries are generally not the long).  Even when I created benchmarks for
18512      // very long table entries the complexity did not seem worth it.
18513      // The code table stores the prefix entry in 12 bits and then the suffix
18514      // byte in 8 bits, so each entry is 20 bits.
18515
18516
18517      var chase_code = code < next_code ? code : prev_code; // Chase what we will output, either {CODE} or {CODE-1}.
18518
18519      var chase_length = 0;
18520      var chase = chase_code;
18521
18522      while (chase > clear_code) {
18523        chase = code_table[chase] >> 8;
18524        ++chase_length;
18525      }
18526
18527      var k = chase;
18528      var op_end = op + chase_length + (chase_code !== code ? 1 : 0);
18529
18530      if (op_end > output_length) {
18531        console.log("Warning, gif stream longer than expected.");
18532        return;
18533      } // Already have the first byte from the chase, might as well write it fast.
18534
18535
18536      output[op++] = k;
18537      op += chase_length;
18538      var b = op; // Track pointer, writing backwards.
18539
18540      if (chase_code !== code) // The case of emitting {CODE-1} + k.
18541        output[op++] = k;
18542      chase = chase_code;
18543
18544      while (chase_length--) {
18545        chase = code_table[chase];
18546        output[--b] = chase & 0xff; // Write backwards.
18547
18548        chase >>= 8; // Pull down to the prefix code.
18549      }
18550
18551      if (prev_code !== null && next_code < 4096) {
18552        code_table[next_code++] = prev_code << 8 | k; // TODO(deanm): Figure out this clearing vs code growth logic better.  I
18553        // have an feeling that it should just happen somewhere else, for now it
18554        // is awkward between when we grow past the max and then hit a clear code.
18555        // For now just check if we hit the max 12-bits (then a clear code should
18556        // follow, also of course encoded in 12-bits).
18557
18558        if (next_code >= code_mask + 1 && cur_code_size < 12) {
18559          ++cur_code_size;
18560          code_mask = code_mask << 1 | 1;
18561        }
18562      }
18563
18564      prev_code = code;
18565    }
18566
18567    if (op !== output_length) {
18568      console.log("Warning, gif stream shorter than expected.");
18569    }
18570
18571    return output;
18572  }
18573
18574  /**
18575   * @license
18576    Copyright (c) 2008, Adobe Systems Incorporated
18577    All rights reserved.
18578
18579    Redistribution and use in source and binary forms, with or without 
18580    modification, are permitted provided that the following conditions are
18581    met:
18582
18583    * Redistributions of source code must retain the above copyright notice, 
18584      this list of conditions and the following disclaimer.
18585    
18586    * Redistributions in binary form must reproduce the above copyright
18587      notice, this list of conditions and the following disclaimer in the 
18588      documentation and/or other materials provided with the distribution.
18589    
18590    * Neither the name of Adobe Systems Incorporated nor the names of its 
18591      contributors may be used to endorse or promote products derived from 
18592      this software without specific prior written permission.
18593
18594    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18595    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18596    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18597    PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
18598    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18599    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
18600    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
18601    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18602    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
18603    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18604    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18605  */
18606
18607  /*
18608  JPEG encoder ported to JavaScript and optimized by Andreas Ritter, www.bytestrom.eu, 11/2009
18609
18610  Basic GUI blocking jpeg encoder
18611  */
18612  function JPEGEncoder(quality) {
18613    var ffloor = Math.floor;
18614    var YTable = new Array(64);
18615    var UVTable = new Array(64);
18616    var fdtbl_Y = new Array(64);
18617    var fdtbl_UV = new Array(64);
18618    var YDC_HT;
18619    var UVDC_HT;
18620    var YAC_HT;
18621    var UVAC_HT;
18622    var bitcode = new Array(65535);
18623    var category = new Array(65535);
18624    var outputfDCTQuant = new Array(64);
18625    var DU = new Array(64);
18626    var byteout = [];
18627    var bytenew = 0;
18628    var bytepos = 7;
18629    var YDU = new Array(64);
18630    var UDU = new Array(64);
18631    var VDU = new Array(64);
18632    var clt = new Array(256);
18633    var RGB_YUV_TABLE = new Array(2048);
18634    var currentQuality;
18635    var ZigZag = [0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 
1863510, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63];
18636    var std_dc_luminance_nrcodes = [0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0];
18637    var std_dc_luminance_values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
18638    var std_ac_luminance_nrcodes = [0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d];
18639    var std_ac_luminance_values = [0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa];
18640    var std_dc_chrominance_nrcodes = [0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0];
18641    var std_dc_chrominance_values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
18642    var std_ac_chrominance_nrcodes = [0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77];
18643    var std_ac_chrominance_values = [0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa];
18644
18645    function initQuantTables(sf) {
18646      var YQT = [16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99];
18647
18648      for (var i = 0; i < 64; i++) {
18649        var t = ffloor((YQT[i] * sf + 50) / 100);
18650        t = Math.min(Math.max(t, 1), 255);
18651        YTable[ZigZag[i]] = t;
18652      }
18653
18654      var UVQT = [17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99];
18655
18656      for (var j = 0; j < 64; j++) {
vendor: 140,191 bytes, lines 18657-23709
18657        var u = ffloor((UVQT[j] * sf + 50) / 100);
18658        u = Math.min(Math.max(u, 1), 255);
18659        UVTable[ZigZag[j]] = u;
18660      }
18661
18662      var aasf = [1.0, 1.387039845, 1.306562965, 1.175875602, 1.0, 0.785694958, 0.5411961, 0.275899379];
18663      var k = 0;
18664
18665      for (var row = 0; row < 8; row++) {
18666        for (var col = 0; col < 8; col++) {
18667          fdtbl_Y[k] = 1.0 / (YTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0);
18668          fdtbl_UV[k] = 1.0 / (UVTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0);
18669          k++;
18670        }
18671      }
18672    }
18673
18674    function computeHuffmanTbl(nrcodes, std_table) {
18675      var codevalue = 0;
18676      var pos_in_table = 0;
18677      var HT = new Array();
18678
18679      for (var k = 1; k <= 16; k++) {
18680        for (var j = 1; j <= nrcodes[k]; j++) {
18681          HT[std_table[pos_in_table]] = [];
18682          HT[std_table[pos_in_table]][0] = codevalue;
18683          HT[std_table[pos_in_table]][1] = k;
18684          pos_in_table++;
18685          codevalue++;
18686        }
18687
18688        codevalue *= 2;
18689      }
18690
18691      return HT;
18692    }
18693
18694    function initHuffmanTbl() {
18695      YDC_HT = computeHuffmanTbl(std_dc_luminance_nrcodes, std_dc_luminance_values);
18696      UVDC_HT = computeHuffmanTbl(std_dc_chrominance_nrcodes, std_dc_chrominance_values);
18697      YAC_HT = computeHuffmanTbl(std_ac_luminance_nrcodes, std_ac_luminance_values);
18698      UVAC_HT = computeHuffmanTbl(std_ac_chrominance_nrcodes, std_ac_chrominance_values);
18699    }
18700
18701    function initCategoryNumber() {
18702      var nrlower = 1;
18703      var nrupper = 2;
18704
18705      for (var cat = 1; cat <= 15; cat++) {
18706        //Positive numbers
18707        for (var nr = nrlower; nr < nrupper; nr++) {
18708          category[32767 + nr] = cat;
18709          bitcode[32767 + nr] = [];
18710          bitcode[32767 + nr][1] = cat;
18711          bitcode[32767 + nr][0] = nr;
18712        } //Negative numbers
18713
18714
18715        for (var nrneg = -(nrupper - 1); nrneg <= -nrlower; nrneg++) {
18716          category[32767 + nrneg] = cat;
18717          bitcode[32767 + nrneg] = [];
18718          bitcode[32767 + nrneg][1] = cat;
18719          bitcode[32767 + nrneg][0] = nrupper - 1 + nrneg;
18720        }
18721
18722        nrlower <<= 1;
18723        nrupper <<= 1;
18724      }
18725    }
18726
18727    function initRGBYUVTable() {
18728      for (var i = 0; i < 256; i++) {
18729        RGB_YUV_TABLE[i] = 19595 * i;
18730        RGB_YUV_TABLE[i + 256 >> 0] = 38470 * i;
18731        RGB_YUV_TABLE[i + 512 >> 0] = 7471 * i + 0x8000;
18732        RGB_YUV_TABLE[i + 768 >> 0] = -11059 * i;
18733        RGB_YUV_TABLE[i + 1024 >> 0] = -21709 * i;
18734        RGB_YUV_TABLE[i + 1280 >> 0] = 32768 * i + 0x807fff;
18735        RGB_YUV_TABLE[i + 1536 >> 0] = -27439 * i;
18736        RGB_YUV_TABLE[i + 1792 >> 0] = -5329 * i;
18737      }
18738    } // IO functions
18739
18740
18741    function writeBits(bs) {
18742      var value = bs[0];
18743      var posval = bs[1] - 1;
18744
18745      while (posval >= 0) {
18746        if (value & 1 << posval) {
18747          bytenew |= 1 << bytepos;
18748        }
18749
18750        posval--;
18751        bytepos--;
18752
18753        if (bytepos < 0) {
18754          if (bytenew == 0xff) {
18755            writeByte(0xff);
18756            writeByte(0);
18757          } else {
18758            writeByte(bytenew);
18759          }
18760
18761          bytepos = 7;
18762          bytenew = 0;
18763        }
18764      }
18765    }
18766
18767    function writeByte(value) {
18768      //byteout.push(clt[value]); // write char directly instead of converting later
18769      byteout.push(value);
18770    }
18771
18772    function writeWord(value) {
18773      writeByte(value >> 8 & 0xff);
18774      writeByte(value & 0xff);
18775    } // DCT & quantization core
18776
18777
18778    function fDCTQuant(data, fdtbl) {
18779      var d0, d1, d2, d3, d4, d5, d6, d7;
18780      /* Pass 1: process rows. */
18781
18782      var dataOff = 0;
18783      var i;
18784      var I8 = 8;
18785      var I64 = 64;
18786
18787      for (i = 0; i < I8; ++i) {
18788        d0 = data[dataOff];
18789        d1 = data[dataOff + 1];
18790        d2 = data[dataOff + 2];
18791        d3 = data[dataOff + 3];
18792        d4 = data[dataOff + 4];
18793        d5 = data[dataOff + 5];
18794        d6 = data[dataOff + 6];
18795        d7 = data[dataOff + 7];
18796        var tmp0 = d0 + d7;
18797        var tmp7 = d0 - d7;
18798        var tmp1 = d1 + d6;
18799        var tmp6 = d1 - d6;
18800        var tmp2 = d2 + d5;
18801        var tmp5 = d2 - d5;
18802        var tmp3 = d3 + d4;
18803        var tmp4 = d3 - d4;
18804        /* Even part */
18805
18806        var tmp10 = tmp0 + tmp3;
18807        /* phase 2 */
18808
18809        var tmp13 = tmp0 - tmp3;
18810        var tmp11 = tmp1 + tmp2;
18811        var tmp12 = tmp1 - tmp2;
18812        data[dataOff] = tmp10 + tmp11;
18813        /* phase 3 */
18814
18815        data[dataOff + 4] = tmp10 - tmp11;
18816        var z1 = (tmp12 + tmp13) * 0.707106781;
18817        /* c4 */
18818
18819        data[dataOff + 2] = tmp13 + z1;
18820        /* phase 5 */
18821
18822        data[dataOff + 6] = tmp13 - z1;
18823        /* Odd part */
18824
18825        tmp10 = tmp4 + tmp5;
18826        /* phase 2 */
18827
18828        tmp11 = tmp5 + tmp6;
18829        tmp12 = tmp6 + tmp7;
18830        /* The rotator is modified from fig 4-8 to avoid extra negations. */
18831
18832        var z5 = (tmp10 - tmp12) * 0.382683433;
18833        /* c6 */
18834
18835        var z2 = 0.5411961 * tmp10 + z5;
18836        /* c2-c6 */
18837
18838        var z4 = 1.306562965 * tmp12 + z5;
18839        /* c2+c6 */
18840
18841        var z3 = tmp11 * 0.707106781;
18842        /* c4 */
18843
18844        var z11 = tmp7 + z3;
18845        /* phase 5 */
18846
18847        var z13 = tmp7 - z3;
18848        data[dataOff + 5] = z13 + z2;
18849        /* phase 6 */
18850
18851        data[dataOff + 3] = z13 - z2;
18852        data[dataOff + 1] = z11 + z4;
18853        data[dataOff + 7] = z11 - z4;
18854        dataOff += 8;
18855        /* advance pointer to next row */
18856      }
18857      /* Pass 2: process columns. */
18858
18859
18860      dataOff = 0;
18861
18862      for (i = 0; i < I8; ++i) {
18863        d0 = data[dataOff];
18864        d1 = data[dataOff + 8];
18865        d2 = data[dataOff + 16];
18866        d3 = data[dataOff + 24];
18867        d4 = data[dataOff + 32];
18868        d5 = data[dataOff + 40];
18869        d6 = data[dataOff + 48];
18870        d7 = data[dataOff + 56];
18871        var tmp0p2 = d0 + d7;
18872        var tmp7p2 = d0 - d7;
18873        var tmp1p2 = d1 + d6;
18874        var tmp6p2 = d1 - d6;
18875        var tmp2p2 = d2 + d5;
18876        var tmp5p2 = d2 - d5;
18877        var tmp3p2 = d3 + d4;
18878        var tmp4p2 = d3 - d4;
18879        /* Even part */
18880
18881        var tmp10p2 = tmp0p2 + tmp3p2;
18882        /* phase 2 */
18883
18884        var tmp13p2 = tmp0p2 - tmp3p2;
18885        var tmp11p2 = tmp1p2 + tmp2p2;
18886        var tmp12p2 = tmp1p2 - tmp2p2;
18887        data[dataOff] = tmp10p2 + tmp11p2;
18888        /* phase 3 */
18889
18890        data[dataOff + 32] = tmp10p2 - tmp11p2;
18891        var z1p2 = (tmp12p2 + tmp13p2) * 0.707106781;
18892        /* c4 */
18893
18894        data[dataOff + 16] = tmp13p2 + z1p2;
18895        /* phase 5 */
18896
18897        data[dataOff + 48] = tmp13p2 - z1p2;
18898        /* Odd part */
18899
18900        tmp10p2 = tmp4p2 + tmp5p2;
18901        /* phase 2 */
18902
18903        tmp11p2 = tmp5p2 + tmp6p2;
18904        tmp12p2 = tmp6p2 + tmp7p2;
18905        /* The rotator is modified from fig 4-8 to avoid extra negations. */
18906
18907        var z5p2 = (tmp10p2 - tmp12p2) * 0.382683433;
18908        /* c6 */
18909
18910        var z2p2 = 0.5411961 * tmp10p2 + z5p2;
18911        /* c2-c6 */
18912
18913        var z4p2 = 1.306562965 * tmp12p2 + z5p2;
18914        /* c2+c6 */
18915
18916        var z3p2 = tmp11p2 * 0.707106781;
18917        /* c4 */
18918
18919        var z11p2 = tmp7p2 + z3p2;
18920        /* phase 5 */
18921
18922        var z13p2 = tmp7p2 - z3p2;
18923        data[dataOff + 40] = z13p2 + z2p2;
18924        /* phase 6 */
18925
18926        data[dataOff + 24] = z13p2 - z2p2;
18927        data[dataOff + 8] = z11p2 + z4p2;
18928        data[dataOff + 56] = z11p2 - z4p2;
18929        dataOff++;
18930        /* advance pointer to next column */
18931      } // Quantize/descale the coefficients
18932
18933
18934      var fDCTQuant;
18935
18936      for (i = 0; i < I64; ++i) {
18937        // Apply the quantization and scaling factor & Round to nearest integer
18938        fDCTQuant = data[i] * fdtbl[i];
18939        outputfDCTQuant[i] = fDCTQuant > 0.0 ? fDCTQuant + 0.5 | 0 : fDCTQuant - 0.5 | 0; //outputfDCTQuant[i] = fround(fDCTQuant);
18940      }
18941
18942      return outputfDCTQuant;
18943    }
18944
18945    function writeAPP0() {
18946      writeWord(0xffe0); // marker
18947
18948      writeWord(16); // length
18949
18950      writeByte(0x4a); // J
18951
18952      writeByte(0x46); // F
18953
18954      writeByte(0x49); // I
18955
18956      writeByte(0x46); // F
18957
18958      writeByte(0); // = "JFIF",'\0'
18959
18960      writeByte(1); // versionhi
18961
18962      writeByte(1); // versionlo
18963
18964      writeByte(0); // xyunits
18965
18966      writeWord(1); // xdensity
18967
18968      writeWord(1); // ydensity
18969
18970      writeByte(0); // thumbnwidth
18971
18972      writeByte(0); // thumbnheight
18973    }
18974
18975    function writeSOF0(width, height) {
18976      writeWord(0xffc0); // marker
18977
18978      writeWord(17); // length, truecolor YUV JPG
18979
18980      writeByte(8); // precision
18981
18982      writeWord(height);
18983      writeWord(width);
18984      writeByte(3); // nrofcomponents
18985
18986      writeByte(1); // IdY
18987
18988      writeByte(0x11); // HVY
18989
18990      writeByte(0); // QTY
18991
18992      writeByte(2); // IdU
18993
18994      writeByte(0x11); // HVU
18995
18996      writeByte(1); // QTU
18997
18998      writeByte(3); // IdV
18999
19000      writeByte(0x11); // HVV
19001
19002      writeByte(1); // QTV
19003    }
19004
19005    function writeDQT() {
19006      writeWord(0xffdb); // marker
19007
19008      writeWord(132); // length
19009
19010      writeByte(0);
19011
19012      for (var i = 0; i < 64; i++) {
19013        writeByte(YTable[i]);
19014      }
19015
19016      writeByte(1);
19017
19018      for (var j = 0; j < 64; j++) {
19019        writeByte(UVTable[j]);
19020      }
19021    }
19022
19023    function writeDHT() {
19024      writeWord(0xffc4); // marker
19025
19026      writeWord(0x01a2); // length
19027
19028      writeByte(0); // HTYDCinfo
19029
19030      for (var i = 0; i < 16; i++) {
19031        writeByte(std_dc_luminance_nrcodes[i + 1]);
19032      }
19033
19034      for (var j = 0; j <= 11; j++) {
19035        writeByte(std_dc_luminance_values[j]);
19036      }
19037
19038      writeByte(0x10); // HTYACinfo
19039
19040      for (var k = 0; k < 16; k++) {
19041        writeByte(std_ac_luminance_nrcodes[k + 1]);
19042      }
19043
19044      for (var l = 0; l <= 161; l++) {
19045        writeByte(std_ac_luminance_values[l]);
19046      }
19047
19048      writeByte(1); // HTUDCinfo
19049
19050      for (var m = 0; m < 16; m++) {
19051        writeByte(std_dc_chrominance_nrcodes[m + 1]);
19052      }
19053
19054      for (var n = 0; n <= 11; n++) {
19055        writeByte(std_dc_chrominance_values[n]);
19056      }
19057
19058      writeByte(0x11); // HTUACinfo
19059
19060      for (var o = 0; o < 16; o++) {
19061        writeByte(std_ac_chrominance_nrcodes[o + 1]);
19062      }
19063
19064      for (var p = 0; p <= 161; p++) {
19065        writeByte(std_ac_chrominance_values[p]);
19066      }
19067    }
19068
19069    function writeSOS() {
19070      writeWord(0xffda); // marker
19071
19072      writeWord(12); // length
19073
19074      writeByte(3); // nrofcomponents
19075
19076      writeByte(1); // IdY
19077
19078      writeByte(0); // HTY
19079
19080      writeByte(2); // IdU
19081
19082      writeByte(0x11); // HTU
19083
19084      writeByte(3); // IdV
19085
19086      writeByte(0x11); // HTV
19087
19088      writeByte(0); // Ss
19089
19090      writeByte(0x3f); // Se
19091
19092      writeByte(0); // Bf
19093    }
19094
19095    function processDU(CDU, fdtbl, DC, HTDC, HTAC) {
19096      var EOB = HTAC[0x00];
19097      var M16zeroes = HTAC[0xf0];
19098      var pos;
19099      var I16 = 16;
19100      var I63 = 63;
19101      var I64 = 64;
19102      var DU_DCT = fDCTQuant(CDU, fdtbl); //ZigZag reorder
19103
19104      for (var j = 0; j < I64; ++j) {
19105        DU[ZigZag[j]] = DU_DCT[j];
19106      }
19107
19108      var Diff = DU[0] - DC;
19109      DC = DU[0]; //Encode DC
19110
19111      if (Diff == 0) {
19112        writeBits(HTDC[0]); // Diff might be 0
19113      } else {
19114        pos = 32767 + Diff;
19115        writeBits(HTDC[category[pos]]);
19116        writeBits(bitcode[pos]);
19117      } //Encode ACs
19118
19119
19120      var end0pos = 63; // was const... which is crazy
19121
19122      while (end0pos > 0 && DU[end0pos] == 0) {
19123        end0pos--;
19124      } //end0pos = first element in reverse order !=0
19125
19126
19127      if (end0pos == 0) {
19128        writeBits(EOB);
19129        return DC;
19130      }
19131
19132      var i = 1;
19133      var lng;
19134
19135      while (i <= end0pos) {
19136        var startpos = i;
19137
19138        while (DU[i] == 0 && i <= end0pos) {
19139          ++i;
19140        }
19141
19142        var nrzeroes = i - startpos;
19143
19144        if (nrzeroes >= I16) {
19145          lng = nrzeroes >> 4;
19146
19147          for (var nrmarker = 1; nrmarker <= lng; ++nrmarker) {
19148            writeBits(M16zeroes);
19149          }
19150
19151          nrzeroes = nrzeroes & 0xf;
19152        }
19153
19154        pos = 32767 + DU[i];
19155        writeBits(HTAC[(nrzeroes << 4) + category[pos]]);
19156        writeBits(bitcode[pos]);
19157        i++;
19158      }
19159
19160      if (end0pos != I63) {
19161        writeBits(EOB);
19162      }
19163
19164      return DC;
19165    }
19166
19167    function initCharLookupTable() {
19168      var sfcc = String.fromCharCode;
19169
19170      for (var i = 0; i < 256; i++) {
19171        ///// ACHTUNG // 255
19172        clt[i] = sfcc(i);
19173      }
19174    }
19175
19176    this.encode = function (image, quality // image data object
19177    ) {
19178      if (quality) setQuality(quality); // Initialize bit writer
19179
19180      byteout = new Array();
19181      bytenew = 0;
19182      bytepos = 7; // Add JPEG headers
19183
19184      writeWord(0xffd8); // SOI
19185
19186      writeAPP0();
19187      writeDQT();
19188      writeSOF0(image.width, image.height);
19189      writeDHT();
19190      writeSOS(); // Encode 8x8 macroblocks
19191
19192      var DCY = 0;
19193      var DCU = 0;
19194      var DCV = 0;
19195      bytenew = 0;
19196      bytepos = 7;
19197      this.encode.displayName = "_encode_";
19198      var imageData = image.data;
19199      var width = image.width;
19200      var height = image.height;
19201      var quadWidth = width * 4;
19202      var x,
19203          y = 0;
19204      var r, g, b;
19205      var start, p, col, row, pos;
19206
19207      while (y < height) {
19208        x = 0;
19209
19210        while (x < quadWidth) {
19211          start = quadWidth * y + x;
19212          col = -1;
19213          row = 0;
19214
19215          for (pos = 0; pos < 64; pos++) {
19216            row = pos >> 3; // /8
19217
19218            col = (pos & 7) * 4; // %8
19219
19220            p = start + row * quadWidth + col;
19221
19222            if (y + row >= height) {
19223              // padding bottom
19224              p -= quadWidth * (y + 1 + row - height);
19225            }
19226
19227            if (x + col >= quadWidth) {
19228              // padding right
19229              p -= x + col - quadWidth + 4;
19230            }
19231
19232            r = imageData[p++];
19233            g = imageData[p++];
19234            b = imageData[p++];
19235            /* // calculate YUV values dynamically
19236            YDU[pos]=((( 0.29900)*r+( 0.58700)*g+( 0.11400)*b))-128; //-0x80
19237            UDU[pos]=(((-0.16874)*r+(-0.33126)*g+( 0.50000)*b));
19238            VDU[pos]=((( 0.50000)*r+(-0.41869)*g+(-0.08131)*b));
19239            */
19240            // use lookup table (slightly faster)
19241
19242            YDU[pos] = (RGB_YUV_TABLE[r] + RGB_YUV_TABLE[g + 256 >> 0] + RGB_YUV_TABLE[b + 512 >> 0] >> 16) - 128;
19243            UDU[pos] = (RGB_YUV_TABLE[r + 768 >> 0] + RGB_YUV_TABLE[g + 1024 >> 0] + RGB_YUV_TABLE[b + 1280 >> 0] >> 16) - 128;
19244            VDU[pos] = (RGB_YUV_TABLE[r + 1280 >> 0] + RGB_YUV_TABLE[g + 1536 >> 0] + RGB_YUV_TABLE[b + 1792 >> 0] >> 16) - 128;
19245          }
19246
19247          DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);
19248          DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
19249          DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
19250          x += 32;
19251        }
19252
19253        y += 8;
19254      } ////////////////////////////////////////////////////////////////
19255      // Do the bit alignment of the EOI marker
19256
19257
19258      if (bytepos >= 0) {
19259        var fillbits = [];
19260        fillbits[1] = bytepos + 1;
19261        fillbits[0] = (1 << bytepos + 1) - 1;
19262        writeBits(fillbits);
19263      }
19264
19265      writeWord(0xffd9); //EOI
19266
19267      return new Uint8Array(byteout);
19268    };
19269
19270    function setQuality(quality) {
19271      quality = Math.min(Math.max(quality, 1), 100);
19272      if (currentQuality == quality) return; // don't recalc if unchanged
19273
19274      var sf = quality < 50 ? Math.floor(5000 / quality) : Math.floor(200 - quality * 2);
19275      initQuantTables(sf);
19276      currentQuality = quality; //console.log('Quality set to: '+quality +'%');
19277    }
19278
19279    function init() {
19280      quality = quality || 50; // Create tables
19281
19282      initCharLookupTable();
19283      initHuffmanTbl();
19284      initCategoryNumber();
19285      initRGBYUVTable();
19286      setQuality(quality);
19287    }
19288
19289    init();
19290  }
19291
19292  /**
19293   * @license
19294   * Copyright (c) 2017 Aras Abbasi
19295   *
19296   * Licensed under the MIT License.
19297   * http://opensource.org/licenses/mit-license
19298   */
19299  /**
19300   * jsPDF Gif Support PlugIn
19301   *
19302   * @name gif_support
19303   * @module
19304   */
19305
19306  (function (jsPDFAPI) {
19307
19308    jsPDFAPI.processGIF89A = function (imageData, index, alias, compression) {
19309      var reader = new GifReader(imageData);
19310      var width = reader.width,
19311          height = reader.height;
19312      var qu = 100;
19313      var pixels = [];
19314      reader.decodeAndBlitFrameRGBA(0, pixels);
19315      var rawImageData = {
19316        data: pixels,
19317        width: width,
19318        height: height
19319      };
19320      var encoder = new JPEGEncoder(qu);
19321      var data = encoder.encode(rawImageData, qu);
19322      return jsPDFAPI.processJPEG.call(this, data, index, alias, compression);
19323    };
19324
19325    jsPDFAPI.processGIF87A = jsPDFAPI.processGIF89A;
19326  })(jsPDF.API);
19327
19328  /**
19329   * @author shaozilee
19330   *
19331   * Bmp format decoder,support 1bit 4bit 8bit 24bit bmp
19332   *
19333   */
19334
19335  function BmpDecoder(buffer, is_with_alpha) {
19336    this.pos = 0;
19337    this.buffer = buffer;
19338    this.datav = new DataView(buffer.buffer);
19339    this.is_with_alpha = !!is_with_alpha;
19340    this.bottom_up = true;
19341    this.flag = String.fromCharCode(this.buffer[0]) + String.fromCharCode(this.buffer[1]);
19342    this.pos += 2;
19343    if (["BM", "BA", "CI", "CP", "IC", "PT"].indexOf(this.flag) === -1) throw new Error("Invalid BMP File");
19344    this.parseHeader();
19345    this.parseBGR();
19346  }
19347
19348  BmpDecoder.prototype.parseHeader = function () {
19349    this.fileSize = this.datav.getUint32(this.pos, true);
19350    this.pos += 4;
19351    this.reserved = this.datav.getUint32(this.pos, true);
19352    this.pos += 4;
19353    this.offset = this.datav.getUint32(this.pos, true);
19354    this.pos += 4;
19355    this.headerSize = this.datav.getUint32(this.pos, true);
19356    this.pos += 4;
19357    this.width = this.datav.getUint32(this.pos, true);
19358    this.pos += 4;
19359    this.height = this.datav.getInt32(this.pos, true);
19360    this.pos += 4;
19361    this.planes = this.datav.getUint16(this.pos, true);
19362    this.pos += 2;
19363    this.bitPP = this.datav.getUint16(this.pos, true);
19364    this.pos += 2;
19365    this.compress = this.datav.getUint32(this.pos, true);
19366    this.pos += 4;
19367    this.rawSize = this.datav.getUint32(this.pos, true);
19368    this.pos += 4;
19369    this.hr = this.datav.getUint32(this.pos, true);
19370    this.pos += 4;
19371    this.vr = this.datav.getUint32(this.pos, true);
19372    this.pos += 4;
19373    this.colors = this.datav.getUint32(this.pos, true);
19374    this.pos += 4;
19375    this.importantColors = this.datav.getUint32(this.pos, true);
19376    this.pos += 4;
19377
19378    if (this.bitPP === 16 && this.is_with_alpha) {
19379      this.bitPP = 15;
19380    }
19381
19382    if (this.bitPP < 15) {
19383      var len = this.colors === 0 ? 1 << this.bitPP : this.colors;
19384      this.palette = new Array(len);
19385
19386      for (var i = 0; i < len; i++) {
19387        var blue = this.datav.getUint8(this.pos++, true);
19388        var green = this.datav.getUint8(this.pos++, true);
19389        var red = this.datav.getUint8(this.pos++, true);
19390        var quad = this.datav.getUint8(this.pos++, true);
19391        this.palette[i] = {
19392          red: red,
19393          green: green,
19394          blue: blue,
19395          quad: quad
19396        };
19397      }
19398    }
19399
19400    if (this.height < 0) {
19401      this.height *= -1;
19402      this.bottom_up = false;
19403    }
19404  };
19405
19406  BmpDecoder.prototype.parseBGR = function () {
19407    this.pos = this.offset;
19408
19409    try {
19410      var bitn = "bit" + this.bitPP;
19411      var len = this.width * this.height * 4;
19412      this.data = new Uint8Array(len);
19413      this[bitn]();
19414    } catch (e) {
19415      console.log("bit decode error:" + e);
19416    }
19417  };
19418
19419  BmpDecoder.prototype.bit1 = function () {
19420    var xlen = Math.ceil(this.width / 8);
19421    var mode = xlen % 4;
19422    var y;
19423
19424    for (y = this.height - 1; y >= 0; y--) {
19425      var line = this.bottom_up ? y : this.height - 1 - y;
19426
19427      for (var x = 0; x < xlen; x++) {
19428        var b = this.datav.getUint8(this.pos++, true);
19429        var location = line * this.width * 4 + x * 8 * 4;
19430
19431        for (var i = 0; i < 8; i++) {
19432          if (x * 8 + i < this.width) {
19433            var rgb = this.palette[b >> 7 - i & 0x1];
19434            this.data[location + i * 4] = rgb.blue;
19435            this.data[location + i * 4 + 1] = rgb.green;
19436            this.data[location + i * 4 + 2] = rgb.red;
19437            this.data[location + i * 4 + 3] = 0xff;
19438          } else {
19439            break;
19440          }
19441        }
19442      }
19443
19444      if (mode !== 0) {
19445        this.pos += 4 - mode;
19446      }
19447    }
19448  };
19449
19450  BmpDecoder.prototype.bit4 = function () {
19451    var xlen = Math.ceil(this.width / 2);
19452    var mode = xlen % 4;
19453
19454    for (var y = this.height - 1; y >= 0; y--) {
19455      var line = this.bottom_up ? y : this.height - 1 - y;
19456
19457      for (var x = 0; x < xlen; x++) {
19458        var b = this.datav.getUint8(this.pos++, true);
19459        var location = line * this.width * 4 + x * 2 * 4;
19460        var before = b >> 4;
19461        var after = b & 0x0f;
19462        var rgb = this.palette[before];
19463        this.data[location] = rgb.blue;
19464        this.data[location + 1] = rgb.green;
19465        this.data[location + 2] = rgb.red;
19466        this.data[location + 3] = 0xff;
19467        if (x * 2 + 1 >= this.width) break;
19468        rgb = this.palette[after];
19469        this.data[location + 4] = rgb.blue;
19470        this.data[location + 4 + 1] = rgb.green;
19471        this.data[location + 4 + 2] = rgb.red;
19472        this.data[location + 4 + 3] = 0xff;
19473      }
19474
19475      if (mode !== 0) {
19476        this.pos += 4 - mode;
19477      }
19478    }
19479  };
19480
19481  BmpDecoder.prototype.bit8 = function () {
19482    var mode = this.width % 4;
19483
19484    for (var y = this.height - 1; y >= 0; y--) {
19485      var line = this.bottom_up ? y : this.height - 1 - y;
19486
19487      for (var x = 0; x < this.width; x++) {
19488        var b = this.datav.getUint8(this.pos++, true);
19489        var location = line * this.width * 4 + x * 4;
19490
19491        if (b < this.palette.length) {
19492          var rgb = this.palette[b];
19493          this.data[location] = rgb.red;
19494          this.data[location + 1] = rgb.green;
19495          this.data[location + 2] = rgb.blue;
19496          this.data[location + 3] = 0xff;
19497        } else {
19498          this.data[location] = 0xff;
19499          this.data[location + 1] = 0xff;
19500          this.data[location + 2] = 0xff;
19501          this.data[location + 3] = 0xff;
19502        }
19503      }
19504
19505      if (mode !== 0) {
19506        this.pos += 4 - mode;
19507      }
19508    }
19509  };
19510
19511  BmpDecoder.prototype.bit15 = function () {
19512    var dif_w = this.width % 3;
19513
19514    var _11111 = parseInt("11111", 2),
19515        _1_5 = _11111;
19516
19517    for (var y = this.height - 1; y >= 0; y--) {
19518      var line = this.bottom_up ? y : this.height - 1 - y;
19519
19520      for (var x = 0; x < this.width; x++) {
19521        var B = this.datav.getUint16(this.pos, true);
19522        this.pos += 2;
19523        var blue = (B & _1_5) / _1_5 * 255 | 0;
19524        var green = (B >> 5 & _1_5) / _1_5 * 255 | 0;
19525        var red = (B >> 10 & _1_5) / _1_5 * 255 | 0;
19526        var alpha = B >> 15 ? 0xff : 0x00;
19527        var location = line * this.width * 4 + x * 4;
19528        this.data[location] = red;
19529        this.data[location + 1] = green;
19530        this.data[location + 2] = blue;
19531        this.data[location + 3] = alpha;
19532      } //skip extra bytes
19533
19534
19535      this.pos += dif_w;
19536    }
19537  };
19538
19539  BmpDecoder.prototype.bit16 = function () {
19540    var dif_w = this.width % 3;
19541
19542    var _11111 = parseInt("11111", 2),
19543        _1_5 = _11111;
19544
19545    var _111111 = parseInt("111111", 2),
19546        _1_6 = _111111;
19547
19548    for (var y = this.height - 1; y >= 0; y--) {
19549      var line = this.bottom_up ? y : this.height - 1 - y;
19550
19551      for (var x = 0; x < this.width; x++) {
19552        var B = this.datav.getUint16(this.pos, true);
19553        this.pos += 2;
19554        var alpha = 0xff;
19555        var blue = (B & _1_5) / _1_5 * 255 | 0;
19556        var green = (B >> 5 & _1_6) / _1_6 * 255 | 0;
19557        var red = (B >> 11) / _1_5 * 255 | 0;
19558        var location = line * this.width * 4 + x * 4;
19559        this.data[location] = red;
19560        this.data[location + 1] = green;
19561        this.data[location + 2] = blue;
19562        this.data[location + 3] = alpha;
19563      } //skip extra bytes
19564
19565
19566      this.pos += dif_w;
19567    }
19568  };
19569
19570  BmpDecoder.prototype.bit24 = function () {
19571    //when height > 0
19572    for (var y = this.height - 1; y >= 0; y--) {
19573      var line = this.bottom_up ? y : this.height - 1 - y;
19574
19575      for (var x = 0; x < this.width; x++) {
19576        var blue = this.datav.getUint8(this.pos++, true);
19577        var green = this.datav.getUint8(this.pos++, true);
19578        var red = this.datav.getUint8(this.pos++, true);
19579        var location = line * this.width * 4 + x * 4;
19580        this.data[location] = red;
19581        this.data[location + 1] = green;
19582        this.data[location + 2] = blue;
19583        this.data[location + 3] = 0xff;
19584      } //skip extra bytes
19585
19586
19587      this.pos += this.width % 4;
19588    }
19589  };
19590  /**
19591   * add 32bit decode func
19592   * @author soubok
19593   */
19594
19595
19596  BmpDecoder.prototype.bit32 = function () {
19597    //when height > 0
19598    for (var y = this.height - 1; y >= 0; y--) {
19599      var line = this.bottom_up ? y : this.height - 1 - y;
19600
19601      for (var x = 0; x < this.width; x++) {
19602        var blue = this.datav.getUint8(this.pos++, true);
19603        var green = this.datav.getUint8(this.pos++, true);
19604        var red = this.datav.getUint8(this.pos++, true);
19605        var alpha = this.datav.getUint8(this.pos++, true);
19606        var location = line * this.width * 4 + x * 4;
19607        this.data[location] = red;
19608        this.data[location + 1] = green;
19609        this.data[location + 2] = blue;
19610        this.data[location + 3] = alpha;
19611      } //skip extra bytes
19612      //this.pos += (this.width % 4);
19613
19614    }
19615  };
19616
19617  BmpDecoder.prototype.getData = function () {
19618    return this.data;
19619  };
19620
19621  /**
19622   * @license
19623   * Copyright (c) 2018 Aras Abbasi
19624   *
19625   * Licensed under the MIT License.
19626   * http://opensource.org/licenses/mit-license
19627   */
19628
19629  /**
19630   * jsPDF bmp Support PlugIn
19631   * @name bmp_support
19632   * @module
19633   */
19634
19635  (function (jsPDFAPI) {
19636
19637    jsPDFAPI.processBMP = function (imageData, index, alias, compression) {
19638      var reader = new BmpDecoder(imageData, false);
19639      var width = reader.width,
19640          height = reader.height;
19641      var qu = 100;
19642      var pixels = reader.getData();
19643      var rawImageData = {
19644        data: pixels,
19645        width: width,
19646        height: height
19647      };
19648      var encoder = new JPEGEncoder(qu);
19649      var data = encoder.encode(rawImageData, qu);
19650      return jsPDFAPI.processJPEG.call(this, data, index, alias, compression);
19651    };
19652  })(jsPDF.API);
19653
19654  function WebPDecoder(imageData) {
19655
19656    function x(F) {
19657      if (!F) throw Error("assert :P");
19658    }
19659
19660    function fa(F, L, J) {
19661      for (var H = 0; 4 > H; H++) {
19662        if (F[L + H] != J.charCodeAt(H)) return !0;
19663      }
19664
19665      return !1;
19666    }
19667
19668    function I(F, L, J, H, Z) {
19669      for (var O = 0; O < Z; O++) {
19670        F[L + O] = J[H + O];
19671      }
19672    }
19673
19674    function M(F, L, J, H) {
19675      for (var Z = 0; Z < H; Z++) {
19676        F[L + Z] = J;
19677      }
19678    }
19679
19680    function V(F) {
19681      return new Int32Array(F);
19682    }
19683
19684    function wa(F, L) {
19685      for (var J = [], H = 0; H < F; H++) {
19686        J.push(new L());
19687      }
19688
19689      return J;
19690    }
19691
19692    function wb() {
19693      function F(J, H, Z) {
19694        for (var O = Z[H], L = 0; L < O; L++) {
19695          J.push(Z.length > H + 1 ? [] : 0);
19696          if (Z.length < H + 1) break;
19697          F(J[L], H + 1, Z);
19698        }
19699      }
19700
19701      var L = [];
19702      F(L, 0, [3, 11]);
19703      return L;
19704    }
19705
19706    function Ed(F, L) {
19707      function J(H, O, F) {
19708        for (var Z = F[O], ma = 0; ma < Z; ma++) {
19709          H.push(F.length > O + 1 ? [] : new L());
19710          if (F.length < O + 1) break;
19711          J(H[ma], O + 1, F);
19712        }
19713      }
19714
19715      var H = [];
19716      J(H, 0, F);
19717      return H;
19718    }
19719
19720    var _WebPDecoder = function _WebPDecoder() {
19721      var self = this;
19722
19723      function L(a, b) {
19724        for (var c = 1 << b - 1 >>> 0; a & c;) {
19725          c >>>= 1;
19726        }
19727
19728        return c ? (a & c - 1) + c : a;
19729      }
19730
19731      function J(a, b, c, d, e) {
19732        x(!(d % c));
19733
19734        do {
19735          d -= c, a[b + d] = e;
19736        } while (0 < d);
19737      }
19738
19739      function H(a, b, c, d, e, f) {
19740        var g = b,
19741            h = 1 << c,
19742            k,
19743            l,
19744            m = V(16),
19745            n = V(16);
19746        x(0 != e);
19747        x(null != d);
19748        x(null != a);
19749        x(0 < c);
19750
19751        for (l = 0; l < e; ++l) {
19752          if (15 < d[l]) return 0;
19753          ++m[d[l]];
19754        }
19755
19756        if (m[0] == e) return 0;
19757        n[1] = 0;
19758
19759        for (k = 1; 15 > k; ++k) {
19760          if (m[k] > 1 << k) return 0;
19761          n[k + 1] = n[k] + m[k];
19762        }
19763
19764        for (l = 0; l < e; ++l) {
19765          k = d[l], 0 < d[l] && (f[n[k]++] = l);
19766        }
19767
19768        if (1 == n[15]) return d = new O(), d.g = 0, d.value = f[0], J(a, g, 1, h, d), h;
19769        var r = -1,
19770            q = h - 1,
19771            t = 0,
19772            v = 1,
19773            p = 1,
19774            u,
19775            w = 1 << c;
19776        l = 0;
19777        k = 1;
19778
19779        for (e = 2; k <= c; ++k, e <<= 1) {
19780          p <<= 1;
19781          v += p;
19782          p -= m[k];
19783          if (0 > p) return 0;
19784
19785          for (; 0 < m[k]; --m[k]) {
19786            d = new O(), d.g = k, d.value = f[l++], J(a, g + t, e, w, d), t = L(t, k);
19787          }
19788        }
19789
19790        k = c + 1;
19791
19792        for (e = 2; 15 >= k; ++k, e <<= 1) {
19793          p <<= 1;
19794          v += p;
19795          p -= m[k];
19796          if (0 > p) return 0;
19797
19798          for (; 0 < m[k]; --m[k]) {
19799            d = new O();
19800
19801            if ((t & q) != r) {
19802              g += w;
19803              r = k;
19804
19805              for (u = 1 << r - c; 15 > r;) {
19806                u -= m[r];
19807                if (0 >= u) break;
19808                ++r;
19809                u <<= 1;
19810              }
19811
19812              u = r - c;
19813              w = 1 << u;
19814              h += w;
19815              r = t & q;
19816              a[b + r].g = u + c;
19817              a[b + r].value = g - b - r;
19818            }
19819
19820            d.g = k - c;
19821            d.value = f[l++];
19822            J(a, g + (t >> c), e, w, d);
19823            t = L(t, k);
19824          }
19825        }
19826
19827        return v != 2 * n[15] - 1 ? 0 : h;
19828      }
19829
19830      function Z(a, b, c, d, e) {
19831        x(2328 >= e);
19832        if (512 >= e) var f = V(512);else if (f = V(e), null == f) return 0;
19833        return H(a, b, c, d, e, f);
19834      }
19835
19836      function O() {
19837        this.value = this.g = 0;
19838      }
19839
19840      function Fd() {
19841        this.value = this.g = 0;
19842      }
19843
19844      function Ub() {
19845        this.G = wa(5, O);
19846        this.H = V(5);
19847        this.jc = this.Qb = this.qb = this.nd = 0;
19848        this.pd = wa(xb, Fd);
19849      }
19850
19851      function ma(a, b, c, d) {
19852        x(null != a);
19853        x(null != b);
19854        x(2147483648 > d);
19855        a.Ca = 254;
19856        a.I = 0;
19857        a.b = -8;
19858        a.Ka = 0;
19859        a.oa = b;
19860        a.pa = c;
19861        a.Jd = b;
19862        a.Yc = c + d;
19863        a.Zc = 4 <= d ? c + d - 4 + 1 : c;
19864        Qa(a);
19865      }
19866
19867      function na(a, b) {
19868        for (var c = 0; 0 < b--;) {
19869          c |= K(a, 128) << b;
19870        }
19871
19872        return c;
19873      }
19874
19875      function ca(a, b) {
19876        var c = na(a, b);
19877        return G(a) ? -c : c;
19878      }
19879
19880      function cb(a, b, c, d) {
19881        var e,
19882            f = 0;
19883        x(null != a);
19884        x(null != b);
19885        x(4294967288 > d);
19886        a.Sb = d;
19887        a.Ra = 0;
19888        a.u = 0;
19889        a.h = 0;
19890        4 < d && (d = 4);
19891
19892        for (e = 0; e < d; ++e) {
19893          f += b[c + e] << 8 * e;
19894        }
19895
19896        a.Ra = f;
19897        a.bb = d;
19898        a.oa = b;
19899        a.pa = c;
19900      }
19901
19902      function Vb(a) {
19903        for (; 8 <= a.u && a.bb < a.Sb;) {
19904          a.Ra >>>= 8, a.Ra += a.oa[a.pa + a.bb] << ob - 8 >>> 0, ++a.bb, a.u -= 8;
19905        }
19906
19907        db(a) && (a.h = 1, a.u = 0);
19908      }
19909
19910      function D(a, b) {
19911        x(0 <= b);
19912
19913        if (!a.h && b <= Gd) {
19914          var c = pb(a) & Hd[b];
19915          a.u += b;
19916          Vb(a);
19917          return c;
19918        }
19919
19920        a.h = 1;
19921        return a.u = 0;
19922      }
19923
19924      function Wb() {
19925        this.b = this.Ca = this.I = 0;
19926        this.oa = [];
19927        this.pa = 0;
19928        this.Jd = [];
19929        this.Yc = 0;
19930        this.Zc = [];
19931        this.Ka = 0;
19932      }
19933
19934      function Ra() {
19935        this.Ra = 0;
19936        this.oa = [];
19937        this.h = this.u = this.bb = this.Sb = this.pa = 0;
19938      }
19939
19940      function pb(a) {
19941        return a.Ra >>> (a.u & ob - 1) >>> 0;
19942      }
19943
19944      function db(a) {
19945        x(a.bb <= a.Sb);
19946        return a.h || a.bb == a.Sb && a.u > ob;
19947      }
19948
19949      function qb(a, b) {
19950        a.u = b;
19951        a.h = db(a);
19952      }
19953
19954      function Sa(a) {
19955        a.u >= Xb && (x(a.u >= Xb), Vb(a));
19956      }
19957
19958      function Qa(a) {
19959        x(null != a && null != a.oa);
19960        a.pa < a.Zc ? (a.I = (a.oa[a.pa++] | a.I << 8) >>> 0, a.b += 8) : (x(null != a && null != a.oa), a.pa < a.Yc ? (a.b += 8, a.I = a.oa[a.pa++] | a.I << 8) : a.Ka ? a.b = 0 : (a.I <<= 8, a.b += 8, a.Ka = 1));
19961      }
19962
19963      function G(a) {
19964        return na(a, 1);
19965      }
19966
19967      function K(a, b) {
19968        var c = a.Ca;
19969        0 > a.b && Qa(a);
19970        var d = a.b,
19971            e = c * b >>> 8,
19972            f = (a.I >>> d > e) + 0;
19973        f ? (c -= e, a.I -= e + 1 << d >>> 0) : c = e + 1;
19974        d = c;
19975
19976        for (e = 0; 256 <= d;) {
19977          e += 8, d >>= 8;
19978        }
19979
19980        d = 7 ^ e + Id[d];
19981        a.b -= d;
19982        a.Ca = (c << d) - 1;
19983        return f;
19984      }
19985
19986      function ra(a, b, c) {
19987        a[b + 0] = c >> 24 & 255;
19988        a[b + 1] = c >> 16 & 255;
19989        a[b + 2] = c >> 8 & 255;
19990        a[b + 3] = c >> 0 & 255;
19991      }
19992
19993      function Ta(a, b) {
19994        return a[b + 0] << 0 | a[b + 1] << 8;
19995      }
19996
19997      function Yb(a, b) {
19998        return Ta(a, b) | a[b + 2] << 16;
19999      }
20000
20001      function Ha(a, b) {
20002        return Ta(a, b) | Ta(a, b + 2) << 16;
20003      }
20004
20005      function Zb(a, b) {
20006        var c = 1 << b;
20007        x(null != a);
20008        x(0 < b);
20009        a.X = V(c);
20010        if (null == a.X) return 0;
20011        a.Mb = 32 - b;
20012        a.Xa = b;
20013        return 1;
20014      }
20015
20016      function $b(a, b) {
20017        x(null != a);
20018        x(null != b);
20019        x(a.Xa == b.Xa);
20020        I(b.X, 0, a.X, 0, 1 << b.Xa);
20021      }
20022
20023      function ac() {
20024        this.X = [];
20025        this.Xa = this.Mb = 0;
20026      }
20027
20028      function bc(a, b, c, d) {
20029        x(null != c);
20030        x(null != d);
20031        var e = c[0],
20032            f = d[0];
20033        0 == e && (e = (a * f + b / 2) / b);
20034        0 == f && (f = (b * e + a / 2) / a);
20035        if (0 >= e || 0 >= f) return 0;
20036        c[0] = e;
20037        d[0] = f;
20038        return 1;
20039      }
20040
20041      function xa(a, b) {
20042        return a + (1 << b) - 1 >>> b;
20043      }
20044
20045      function yb(a, b) {
20046        return ((a & 4278255360) + (b & 4278255360) >>> 0 & 4278255360) + ((a & 16711935) + (b & 16711935) >>> 0 & 16711935) >>> 0;
20047      }
20048
20049      function X(a, b) {
20050        self[b] = function (b, d, e, f, g, h, k) {
20051          var c;
20052
20053          for (c = 0; c < g; ++c) {
20054            var m = self[a](h[k + c - 1], e, f + c);
20055            h[k + c] = yb(b[d + c], m);
20056          }
20057        };
20058      }
20059
20060      function Jd() {
20061        this.ud = this.hd = this.jd = 0;
20062      }
20063
20064      function aa(a, b) {
20065        return (((a ^ b) & 4278124286) >>> 1) + (a & b) >>> 0;
20066      }
20067
20068      function sa(a) {
20069        if (0 <= a && 256 > a) return a;
20070        if (0 > a) return 0;
20071        if (255 < a) return 255;
20072      }
20073
20074      function eb(a, b) {
20075        return sa(a + (a - b + 0.5 >> 1));
20076      }
20077
20078      function Ia(a, b, c) {
20079        return Math.abs(b - c) - Math.abs(a - c);
20080      }
20081
20082      function cc(a, b, c, d, e, f, g) {
20083        d = f[g - 1];
20084
20085        for (c = 0; c < e; ++c) {
20086          f[g + c] = d = yb(a[b + c], d);
20087        }
20088      }
20089
20090      function Kd(a, b, c, d, e) {
20091        var f;
20092
20093        for (f = 0; f < c; ++f) {
20094          var g = a[b + f],
20095              h = g >> 8 & 255,
20096              k = g & 16711935,
20097              k = k + ((h << 16) + h),
20098              k = k & 16711935;
20099          d[e + f] = (g & 4278255360) + k >>> 0;
20100        }
20101      }
20102
20103      function dc(a, b) {
20104        b.jd = a >> 0 & 255;
20105        b.hd = a >> 8 & 255;
20106        b.ud = a >> 16 & 255;
20107      }
20108
20109      function Ld(a, b, c, d, e, f) {
20110        var g;
20111
20112        for (g = 0; g < d; ++g) {
20113          var h = b[c + g],
20114              k = h >>> 8,
20115              l = h >>> 16,
20116              m = h,
20117              l = l + ((a.jd << 24 >> 24) * (k << 24 >> 24) >>> 5),
20118              l = l & 255,
20119              m = m + ((a.hd << 24 >> 24) * (k << 24 >> 24) >>> 5),
20120              m = m + ((a.ud << 24 >> 24) * (l << 24 >> 24) >>> 5),
20121              m = m & 255;
20122          e[f + g] = (h & 4278255360) + (l << 16) + m;
20123        }
20124      }
20125
20126      function ec(a, b, c, d, e) {
20127        self[b] = function (a, b, c, k, l, m, n, r, q) {
20128          for (k = n; k < r; ++k) {
20129            for (n = 0; n < q; ++n) {
20130              l[m++] = e(c[d(a[b++])]);
20131            }
20132          }
20133        };
20134
20135        self[a] = function (a, b, h, k, l, m, n) {
20136          var f = 8 >> a.b,
20137              g = a.Ea,
20138              t = a.K[0],
20139              v = a.w;
20140          if (8 > f) for (a = (1 << a.b) - 1, v = (1 << f) - 1; b < h; ++b) {
20141            var p = 0,
20142                u;
20143
20144            for (u = 0; u < g; ++u) {
20145              u & a || (p = d(k[l++])), m[n++] = e(t[p & v]), p >>= f;
20146            }
20147          } else self["VP8LMapColor" + c](k, l, t, v, m, n, b, h, g);
20148        };
20149      }
20150
20151      function Md(a, b, c, d, e) {
20152        for (c = b + c; b < c;) {
20153          var f = a[b++];
20154          d[e++] = f >> 16 & 255;
20155          d[e++] = f >> 8 & 255;
20156          d[e++] = f >> 0 & 255;
20157        }
20158      }
20159
20160      function Nd(a, b, c, d, e) {
20161        for (c = b + c; b < c;) {
20162          var f = a[b++];
20163          d[e++] = f >> 16 & 255;
20164          d[e++] = f >> 8 & 255;
20165          d[e++] = f >> 0 & 255;
20166          d[e++] = f >> 24 & 255;
20167        }
20168      }
20169
20170      function Od(a, b, c, d, e) {
20171        for (c = b + c; b < c;) {
20172          var f = a[b++],
20173              g = f >> 16 & 240 | f >> 12 & 15,
20174              f = f >> 0 & 240 | f >> 28 & 15;
20175          d[e++] = g;
20176          d[e++] = f;
20177        }
20178      }
20179
20180      function Pd(a, b, c, d, e) {
20181        for (c = b + c; b < c;) {
20182          var f = a[b++],
20183              g = f >> 16 & 248 | f >> 13 & 7,
20184              f = f >> 5 & 224 | f >> 3 & 31;
20185          d[e++] = g;
20186          d[e++] = f;
20187        }
20188      }
20189
20190      function Qd(a, b, c, d, e) {
20191        for (c = b + c; b < c;) {
20192          var f = a[b++];
20193          d[e++] = f >> 0 & 255;
20194          d[e++] = f >> 8 & 255;
20195          d[e++] = f >> 16 & 255;
20196        }
20197      }
20198
20199      function fb(a, b, c, d, e, f) {
20200        if (0 == f) for (c = b + c; b < c;) {
20201          f = a[b++], ra(d, (f[0] >> 24 | f[1] >> 8 & 65280 | f[2] << 8 & 16711680 | f[3] << 24) >>> 0), e += 32;
20202        } else I(d, e, a, b, c);
20203      }
20204
20205      function gb(a, b) {
20206        self[b][0] = self[a + "0"];
20207        self[b][1] = self[a + "1"];
20208        self[b][2] = self[a + "2"];
20209        self[b][3] = self[a + "3"];
20210        self[b][4] = self[a + "4"];
20211        self[b][5] = self[a + "5"];
20212        self[b][6] = self[a + "6"];
20213        self[b][7] = self[a + "7"];
20214        self[b][8] = self[a + "8"];
20215        self[b][9] = self[a + "9"];
20216        self[b][10] = self[a + "10"];
20217        self[b][11] = self[a + "11"];
20218        self[b][12] = self[a + "12"];
20219        self[b][13] = self[a + "13"];
20220        self[b][14] = self[a + "0"];
20221        self[b][15] = self[a + "0"];
20222      }
20223
20224      function hb(a) {
20225        return a == zb || a == Ab || a == Ja || a == Bb;
20226      }
20227
20228      function Rd() {
20229        this.eb = [];
20230        this.size = this.A = this.fb = 0;
20231      }
20232
20233      function Sd() {
20234        this.y = [];
20235        this.f = [];
20236        this.ea = [];
20237        this.F = [];
20238        this.Tc = this.Ed = this.Cd = this.Fd = this.lb = this.Db = this.Ab = this.fa = this.J = this.W = this.N = this.O = 0;
20239      }
20240
20241      function Cb() {
20242        this.Rd = this.height = this.width = this.S = 0;
20243        this.f = {};
20244        this.f.RGBA = new Rd();
20245        this.f.kb = new Sd();
20246        this.sd = null;
20247      }
20248
20249      function Td() {
20250        this.width = [0];
20251        this.height = [0];
20252        this.Pd = [0];
20253        this.Qd = [0];
20254        this.format = [0];
20255      }
20256
20257      function Ud() {
20258        this.Id = this.fd = this.Md = this.hb = this.ib = this.da = this.bd = this.cd = this.j = this.v = this.Da = this.Sd = this.ob = 0;
20259      }
20260
20261      function Vd(a) {
20262        alert("todo:WebPSamplerProcessPlane");
20263        return a.T;
20264      }
20265
20266      function Wd(a, b) {
20267        var c = a.T,
20268            d = b.ba.f.RGBA,
20269            e = d.eb,
20270            f = d.fb + a.ka * d.A,
20271            g = P[b.ba.S],
20272            h = a.y,
20273            k = a.O,
20274            l = a.f,
20275            m = a.N,
20276            n = a.ea,
20277            r = a.W,
20278            q = b.cc,
20279            t = b.dc,
20280            v = b.Mc,
20281            p = b.Nc,
20282            u = a.ka,
20283            w = a.ka + a.T,
20284            y = a.U,
20285            A = y + 1 >> 1;
20286        0 == u ? g(h, k, null, null, l, m, n, r, l, m, n, r, e, f, null, null, y) : (g(b.ec, b.fc, h, k, q, t, v, p, l, m, n, r, e, f - d.A, e, f, y), ++c);
20287
20288        for (; u + 2 < w; u += 2) {
20289          q = l, t = m, v = n, p = r, m += a.Rc, r += a.Rc, f += 2 * d.A, k += 2 * a.fa, g(h, k - a.fa, h, k, q, t, v, p, l, m, n, r, e, f - d.A, e, f, y);
20290        }
20291
20292        k += a.fa;
20293        a.j + w < a.o ? (I(b.ec, b.fc, h, k, y), I(b.cc, b.dc, l, m, A), I(b.Mc, b.Nc, n, r, A), c--) : w & 1 || g(h, k, null, null, l, m, n, r, l, m, n, r, e, f + d.A, null, null, y);
20294        return c;
20295      }
20296
20297      function Xd(a, b, c) {
20298        var d = a.F,
20299            e = [a.J];
20300
20301        if (null != d) {
20302          var f = a.U,
20303              g = b.ba.S,
20304              h = g == ya || g == Ja;
20305          b = b.ba.f.RGBA;
20306          var k = [0],
20307              l = a.ka;
20308          k[0] = a.T;
20309          a.Kb && (0 == l ? --k[0] : (--l, e[0] -= a.width), a.j + a.ka + a.T == a.o && (k[0] = a.o - a.j - l));
20310          var m = b.eb,
20311              l = b.fb + l * b.A;
20312          a = fc(d, e[0], a.width, f, k, m, l + (h ? 0 : 3), b.A);
20313          x(c == k);
20314          a && hb(g) && za(m, l, h, f, k, b.A);
20315        }
20316
20317        return 0;
20318      }
20319
20320      function gc(a) {
20321        var b = a.ma,
20322            c = b.ba.S,
20323            d = 11 > c,
20324            e = c == Ua || c == Va || c == ya || c == Db || 12 == c || hb(c);
20325        b.memory = null;
20326        b.Ib = null;
20327        b.Jb = null;
20328        b.Nd = null;
20329        if (!hc(b.Oa, a, e ? 11 : 12)) return 0;
20330        e && hb(c) && ic();
20331        if (a.da) alert("todo:use_scaling");else {
20332          if (d) {
20333            if (b.Ib = Vd, a.Kb) {
20334              c = a.U + 1 >> 1;
20335              b.memory = V(a.U + 2 * c);
20336              if (null == b.memory) return 0;
20337              b.ec = b.memory;
20338              b.fc = 0;
20339              b.cc = b.ec;
20340              b.dc = b.fc + a.U;
20341              b.Mc = b.cc;
20342              b.Nc = b.dc + c;
20343              b.Ib = Wd;
20344              ic();
20345            }
20346          } else alert("todo:EmitYUV");
20347
20348          e && (b.Jb = Xd, d && Aa());
20349        }
20350
20351        if (d && !jc) {
20352          for (a = 0; 256 > a; ++a) {
20353            Yd[a] = 89858 * (a - 128) + Ba >> Wa, Zd[a] = -22014 * (a - 128) + Ba, $d[a] = -45773 * (a - 128), ae[a] = 113618 * (a - 128) + Ba >> Wa;
20354          }
20355
20356          for (a = ta; a < Eb; ++a) {
20357            b = 76283 * (a - 16) + Ba >> Wa, be[a - ta] = ga(b, 255), ce[a - ta] = ga(b + 8 >> 4, 15);
20358          }
20359
20360          jc = 1;
20361        }
20362
20363        return 1;
20364      }
20365
20366      function kc(a) {
20367        var b = a.ma,
20368            c = a.U,
20369            d = a.T;
20370        x(!(a.ka & 1));
20371        if (0 >= c || 0 >= d) return 0;
20372        c = b.Ib(a, b);
20373        null != b.Jb && b.Jb(a, b, c);
20374        b.Dc += c;
20375        return 1;
20376      }
20377
20378      function lc(a) {
20379        a.ma.memory = null;
20380      }
20381
20382      function mc(a, b, c, d) {
20383        if (47 != D(a, 8)) return 0;
20384        b[0] = D(a, 14) + 1;
20385        c[0] = D(a, 14) + 1;
20386        d[0] = D(a, 1);
20387        return 0 != D(a, 3) ? 0 : !a.h;
20388      }
20389
20390      function ib(a, b) {
20391        if (4 > a) return a + 1;
20392        var c = a - 2 >> 1;
20393        return (2 + (a & 1) << c) + D(b, c) + 1;
20394      }
20395
20396      function nc(a, b) {
20397        if (120 < b) return b - 120;
20398        var c = de[b - 1],
20399            c = (c >> 4) * a + (8 - (c & 15));
20400        return 1 <= c ? c : 1;
20401      }
20402
20403      function ua(a, b, c) {
20404        var d = pb(c);
20405        b += d & 255;
20406        var e = a[b].g - 8;
20407        0 < e && (qb(c, c.u + 8), d = pb(c), b += a[b].value, b += d & (1 << e) - 1);
20408        qb(c, c.u + a[b].g);
20409        return a[b].value;
20410      }
20411
20412      function ub(a, b, c) {
20413        c.g += a.g;
20414        c.value += a.value << b >>> 0;
20415        x(8 >= c.g);
20416        return a.g;
20417      }
20418
20419      function ha(a, b, c) {
20420        var d = a.xc;
20421        b = 0 == d ? 0 : a.vc[a.md * (c >> d) + (b >> d)];
20422        x(b < a.Wb);
20423        return a.Ya[b];
20424      }
20425
20426      function oc(a, b, c, d) {
20427        var e = a.ab,
20428            f = a.c * b,
20429            g = a.C;
20430        b = g + b;
20431        var h = c,
20432            k = d;
20433        d = a.Ta;
20434
20435        for (c = a.Ua; 0 < e--;) {
20436          var l = a.gc[e],
20437              m = g,
20438              n = b,
20439              r = h,
20440              q = k,
20441              k = d,
20442              h = c,
20443              t = l.Ea;
20444          x(m < n);
20445          x(n <= l.nc);
20446
20447          switch (l.hc) {
20448            case 2:
20449              pc(r, q, (n - m) * t, k, h);
20450              break;
20451
20452            case 0:
20453              var v = l,
20454                  p = m,
20455                  u = n,
20456                  w = k,
20457                  y = h,
20458                  A = v.Ea;
20459              0 == p && (ee(r, q, null, null, 1, w, y), cc(r, q + 1, 0, 0, A - 1, w, y + 1), q += A, y += A, ++p);
20460
20461              for (var E = 1 << v.b, B = E - 1, C = xa(A, v.b), N = v.K, v = v.w + (p >> v.b) * C; p < u;) {
20462                var z = N,
20463                    Q = v,
20464                    S = 1;
20465
20466                for (fe(r, q, w, y - A, 1, w, y); S < A;) {
20467                  var K = qc[z[Q++] >> 8 & 15],
20468                      D = (S & ~B) + E;
20469                  D > A && (D = A);
20470                  K(r, q + +S, w, y + S - A, D - S, w, y + S);
20471                  S = D;
20472                }
20473
20474                q += A;
20475                y += A;
20476                ++p;
20477                p & B || (v += C);
20478              }
20479
20480              n != l.nc && I(k, h - t, k, h + (n - m - 1) * t, t);
20481              break;
20482
20483            case 1:
20484              t = r;
20485              u = q;
20486              r = l.Ea;
20487              q = 1 << l.b;
20488              w = q - 1;
20489              y = r & ~w;
20490              A = r - y;
20491              p = xa(r, l.b);
20492              E = l.K;
20493
20494              for (l = l.w + (m >> l.b) * p; m < n;) {
20495                B = E;
20496                C = l;
20497                N = new Jd();
20498                v = u + y;
20499
20500                for (z = u + r; u < v;) {
20501                  dc(B[C++], N), Fb(N, t, u, q, k, h), u += q, h += q;
20502                }
20503
20504                u < z && (dc(B[C++], N), Fb(N, t, u, A, k, h), u += A, h += A);
20505                ++m;
20506                m & w || (l += p);
20507              }
20508
20509              break;
20510
20511            case 3:
20512              if (r == k && q == h && 0 < l.b) {
20513                y = (n - m) * xa(l.Ea, l.b);
20514                t = h + (n - m) * t - y;
20515                u = k;
20516                r = t;
20517                q = k;
20518                w = h;
20519                A = y;
20520                p = [];
20521
20522                for (y = A - 1; 0 <= y; --y) {
20523                  p[y] = q[w + y];
20524                }
20525
20526                for (y = A - 1; 0 <= y; --y) {
20527                  u[r + y] = p[y];
20528                }
20529
20530                rc(l, m, n, k, t, k, h);
20531              } else rc(l, m, n, r, q, k, h);
20532
20533          }
20534
20535          h = d;
20536          k = c;
20537        }
20538
20539        k != c && I(d, c, h, k, f);
20540      }
20541
20542      function ge(a, b) {
20543        var c = a.V,
20544            d = a.Ba + a.c * a.C,
20545            e = b - a.C;
20546        x(b <= a.l.o);
20547        x(16 >= e);
20548
20549        if (0 < e) {
20550          var f = a.l,
20551              g = a.Ta,
20552              h = a.Ua,
20553              k = f.width;
20554          oc(a, e, c, d);
20555          h = [h];
20556          c = a.C;
20557          d = b;
20558          e = h;
20559          x(c < d);
20560          x(f.v < f.va);
20561          d > f.o && (d = f.o);
20562
20563          if (c < f.j) {
20564            var l = f.j - c,
20565                c = f.j;
20566            e[0] += l * k;
20567          }
20568
20569          c >= d ? c = 0 : (e[0] += 4 * f.v, f.ka = c - f.j, f.U = f.va - f.v, f.T = d - c, c = 1);
20570
20571          if (c) {
20572            h = h[0];
20573            c = a.ca;
20574
20575            if (11 > c.S) {
20576              for (var m = c.f.RGBA, d = c.S, e = f.U, f = f.T, l = m.eb, n = m.A, r = f, m = m.fb + a.Ma * m.A; 0 < r--;) {
20577                var q = g,
20578                    t = h,
20579                    v = e,
20580                    p = l,
20581                    u = m;
20582
20583                switch (d) {
20584                  case Ca:
20585                    sc(q, t, v, p, u);
20586                    break;
20587
20588                  case Ua:
20589                    Gb(q, t, v, p, u);
20590                    break;
20591
20592                  case zb:
20593                    Gb(q, t, v, p, u);
20594                    za(p, u, 0, v, 1, 0);
20595                    break;
20596
20597                  case tc:
20598                    uc(q, t, v, p, u);
20599                    break;
20600
20601                  case Va:
20602                    fb(q, t, v, p, u, 1);
20603                    break;
20604
20605                  case Ab:
20606                    fb(q, t, v, p, u, 1);
20607                    za(p, u, 0, v, 1, 0);
20608                    break;
20609
20610                  case ya:
20611                    fb(q, t, v, p, u, 0);
20612                    break;
20613
20614                  case Ja:
20615                    fb(q, t, v, p, u, 0);
20616                    za(p, u, 1, v, 1, 0);
20617                    break;
20618
20619                  case Db:
20620                    Hb(q, t, v, p, u);
20621                    break;
20622
20623                  case Bb:
20624                    Hb(q, t, v, p, u);
20625                    vc(p, u, v, 1, 0);
20626                    break;
20627
20628                  case wc:
20629                    xc(q, t, v, p, u);
20630                    break;
20631
20632                  default:
20633                    x(0);
20634                }
20635
20636                h += k;
20637                m += n;
20638              }
20639
20640              a.Ma += f;
20641            } else alert("todo:EmitRescaledRowsYUVA");
20642
20643            x(a.Ma <= c.height);
20644          }
20645        }
20646
20647        a.C = b;
20648        x(a.C <= a.i);
20649      }
20650
20651      function yc(a) {
20652        var b;
20653        if (0 < a.ua) return 0;
20654
20655        for (b = 0; b < a.Wb; ++b) {
20656          var c = a.Ya[b].G,
20657              d = a.Ya[b].H;
20658          if (0 < c[1][d[1] + 0].g || 0 < c[2][d[2] + 0].g || 0 < c[3][d[3] + 0].g) return 0;
20659        }
20660
20661        return 1;
20662      }
20663
20664      function zc(a, b, c, d, e, f) {
20665        if (0 != a.Z) {
20666          var g = a.qd,
20667              h = a.rd;
20668
20669          for (x(null != ia[a.Z]); b < c; ++b) {
20670            ia[a.Z](g, h, d, e, d, e, f), g = d, h = e, e += f;
20671          }
20672
20673          a.qd = g;
20674          a.rd = h;
20675        }
20676      }
20677
20678      function Ib(a, b) {
20679        var c = a.l.ma,
20680            d = 0 == c.Z || 1 == c.Z ? a.l.j : a.C,
20681            d = a.C < d ? d : a.C;
20682        x(b <= a.l.o);
20683
20684        if (b > d) {
20685          var e = a.l.width,
20686              f = c.ca,
20687              g = c.tb + e * d,
20688              h = a.V,
20689              k = a.Ba + a.c * d,
20690              l = a.gc;
20691          x(1 == a.ab);
20692          x(3 == l[0].hc);
20693          he(l[0], d, b, h, k, f, g);
20694          zc(c, d, b, f, g, e);
20695        }
20696
20697        a.C = a.Ma = b;
20698      }
20699
20700      function Jb(a, b, c, d, e, f, g) {
20701        var h = a.$ / d,
20702            k = a.$ % d,
20703            l = a.m,
20704            m = a.s,
20705            n = c + a.$,
20706            r = n;
20707        e = c + d * e;
20708        var q = c + d * f,
20709            t = 280 + m.ua,
20710            v = a.Pb ? h : 16777216,
20711            p = 0 < m.ua ? m.Wa : null,
20712            u = m.wc,
20713            w = n < q ? ha(m, k, h) : null;
20714        x(a.C < f);
20715        x(q <= e);
20716        var y = !1;
20717
20718        a: for (;;) {
20719          for (; y || n < q;) {
20720            var A = 0;
20721
20722            if (h >= v) {
20723              var v = a,
20724                  E = n - c;
20725              x(v.Pb);
20726              v.wd = v.m;
20727              v.xd = E;
20728              0 < v.s.ua && $b(v.s.Wa, v.s.vb);
20729              v = h + ie;
20730            }
20731
20732            k & u || (w = ha(m, k, h));
20733            x(null != w);
20734            w.Qb && (b[n] = w.qb, y = !0);
20735            if (!y) if (Sa(l), w.jc) {
20736              var A = l,
20737                  E = b,
20738                  B = n,
20739                  C = w.pd[pb(A) & xb - 1];
20740              x(w.jc);
20741              256 > C.g ? (qb(A, A.u + C.g), E[B] = C.value, A = 0) : (qb(A, A.u + C.g - 256), x(256 <= C.value), A = C.value);
20742              0 == A && (y = !0);
20743            } else A = ua(w.G[0], w.H[0], l);
20744            if (l.h) break;
20745
20746            if (y || 256 > A) {
20747              if (!y) if (w.nd) b[n] = (w.qb | A << 8) >>> 0;else {
20748                Sa(l);
20749                y = ua(w.G[1], w.H[1], l);
20750                Sa(l);
20751                E = ua(w.G[2], w.H[2], l);
20752                B = ua(w.G[3], w.H[3], l);
20753                if (l.h) break;
20754                b[n] = (B << 24 | y << 16 | A << 8 | E) >>> 0;
20755              }
20756              y = !1;
20757              ++n;
20758              ++k;
20759              if (k >= d && (k = 0, ++h, null != g && h <= f && !(h % 16) && g(a, h), null != p)) for (; r < n;) {
20760                A = b[r++], p.X[(506832829 * A & 4294967295) >>> p.Mb] = A;
20761              }
20762            } else if (280 > A) {
20763              A = ib(A - 256, l);
20764              E = ua(w.G[4], w.H[4], l);
20765              Sa(l);
20766              E = ib(E, l);
20767              E = nc(d, E);
20768              if (l.h) break;
20769              if (n - c < E || e - n < A) break a;else for (B = 0; B < A; ++B) {
20770                b[n + B] = b[n + B - E];
20771              }
20772              n += A;
20773
20774              for (k += A; k >= d;) {
20775                k -= d, ++h, null != g && h <= f && !(h % 16) && g(a, h);
20776              }
20777
20778              x(n <= e);
20779              k & u && (w = ha(m, k, h));
20780              if (null != p) for (; r < n;) {
20781                A = b[r++], p.X[(506832829 * A & 4294967295) >>> p.Mb] = A;
20782              }
20783            } else if (A < t) {
20784              y = A - 280;
20785
20786              for (x(null != p); r < n;) {
20787                A = b[r++], p.X[(506832829 * A & 4294967295) >>> p.Mb] = A;
20788              }
20789
20790              A = n;
20791              E = p;
20792              x(!(y >>> E.Xa));
20793              b[A] = E.X[y];
20794              y = !0;
20795            } else break a;
20796
20797            y || x(l.h == db(l));
20798          }
20799
20800          if (a.Pb && l.h && n < e) x(a.m.h), a.a = 5, a.m = a.wd, a.$ = a.xd, 0 < a.s.ua && $b(a.s.vb, a.s.Wa);else if (l.h) break a;else null != g && g(a, h > f ? f : h), a.a = 0, a.$ = n - c;
20801          return 1;
20802        }
20803
20804        a.a = 3;
20805        return 0;
20806      }
20807
20808      function Ac(a) {
20809        x(null != a);
20810        a.vc = null;
20811        a.yc = null;
20812        a.Ya = null;
20813        var b = a.Wa;
20814        null != b && (b.X = null);
20815        a.vb = null;
20816        x(null != a);
20817      }
20818
20819      function Bc() {
20820        var a = new je();
20821        if (null == a) return null;
20822        a.a = 0;
20823        a.xb = Cc;
20824        gb("Predictor", "VP8LPredictors");
20825        gb("Predictor", "VP8LPredictors_C");
20826        gb("PredictorAdd", "VP8LPredictorsAdd");
20827        gb("PredictorAdd", "VP8LPredictorsAdd_C");
20828        pc = Kd;
20829        Fb = Ld;
20830        sc = Md;
20831        Gb = Nd;
20832        Hb = Od;
20833        xc = Pd;
20834        uc = Qd;
20835        self.VP8LMapColor32b = ke;
20836        self.VP8LMapColor8b = le;
20837        return a;
20838      }
20839
20840      function rb(a, b, c, d, e) {
20841        var f = 1,
20842            g = [a],
20843            h = [b],
20844            k = d.m,
20845            l = d.s,
20846            m = null,
20847            n = 0;
20848
20849        a: for (;;) {
20850          if (c) for (; f && D(k, 1);) {
20851            var r = g,
20852                q = h,
20853                t = d,
20854                v = 1,
20855                p = t.m,
20856                u = t.gc[t.ab],
20857                w = D(p, 2);
20858            if (t.Oc & 1 << w) f = 0;else {
20859              t.Oc |= 1 << w;
20860              u.hc = w;
20861              u.Ea = r[0];
20862              u.nc = q[0];
20863              u.K = [null];
20864              ++t.ab;
20865              x(4 >= t.ab);
20866
20867              switch (w) {
20868                case 0:
20869                case 1:
20870                  u.b = D(p, 3) + 2;
20871                  v = rb(xa(u.Ea, u.b), xa(u.nc, u.b), 0, t, u.K);
20872                  u.K = u.K[0];
20873                  break;
20874
20875                case 3:
20876                  var y = D(p, 8) + 1,
20877                      A = 16 < y ? 0 : 4 < y ? 1 : 2 < y ? 2 : 3;
20878                  r[0] = xa(u.Ea, A);
20879                  u.b = A;
20880                  var v = rb(y, 1, 0, t, u.K),
20881                      E;
20882
20883                  if (E = v) {
20884                    var B,
20885                        C = y,
20886                        N = u,
20887                        z = 1 << (8 >> N.b),
20888                        Q = V(z);
20889                    if (null == Q) E = 0;else {
20890                      var S = N.K[0],
20891                          K = N.w;
20892                      Q[0] = N.K[0][0];
20893
20894                      for (B = 1; B < 1 * C; ++B) {
20895                        Q[B] = yb(S[K + B], Q[B - 1]);
20896                      }
20897
20898                      for (; B < 4 * z; ++B) {
20899                        Q[B] = 0;
20900                      }
20901
20902                      N.K[0] = null;
20903                      N.K[0] = Q;
20904                      E = 1;
20905                    }
20906                  }
20907
20908                  v = E;
20909                  break;
20910
20911                case 2:
20912                  break;
20913
20914                default:
20915                  x(0);
20916              }
20917
20918              f = v;
20919            }
20920          }
20921          g = g[0];
20922          h = h[0];
20923
20924          if (f && D(k, 1) && (n = D(k, 4), f = 1 <= n && 11 >= n, !f)) {
20925            d.a = 3;
20926            break a;
20927          }
20928
20929          var H;
20930          if (H = f) b: {
20931            var F = d,
20932                G = g,
20933                L = h,
20934                J = n,
20935                T = c,
20936                Da,
20937                ba,
20938                X = F.m,
20939                R = F.s,
20940                P = [null],
20941                U,
20942                W = 1,
20943                aa = 0,
20944                na = me[J];
20945
20946            c: for (;;) {
20947              if (T && D(X, 1)) {
20948                var ca = D(X, 3) + 2,
20949                    ga = xa(G, ca),
20950                    ka = xa(L, ca),
20951                    qa = ga * ka;
20952                if (!rb(ga, ka, 0, F, P)) break c;
20953                P = P[0];
20954                R.xc = ca;
20955
20956                for (Da = 0; Da < qa; ++Da) {
20957                  var ia = P[Da] >> 8 & 65535;
20958                  P[Da] = ia;
20959                  ia >= W && (W = ia + 1);
20960                }
20961              }
20962
20963              if (X.h) break c;
20964
20965              for (ba = 0; 5 > ba; ++ba) {
20966                var Y = Dc[ba];
20967                !ba && 0 < J && (Y += 1 << J);
20968                aa < Y && (aa = Y);
20969              }
20970
20971              var ma = wa(W * na, O);
20972              var ua = W,
20973                  va = wa(ua, Ub);
20974              if (null == va) var la = null;else x(65536 >= ua), la = va;
20975              var ha = V(aa);
20976
20977              if (null == la || null == ha || null == ma) {
20978                F.a = 1;
20979                break c;
20980              }
20981
20982              var pa = ma;
20983
20984              for (Da = U = 0; Da < W; ++Da) {
20985                var ja = la[Da],
20986                    da = ja.G,
20987                    ea = ja.H,
20988                    Fa = 0,
20989                    ra = 1,
20990                    Ha = 0;
20991
20992                for (ba = 0; 5 > ba; ++ba) {
20993                  Y = Dc[ba];
20994                  da[ba] = pa;
20995                  ea[ba] = U;
20996                  !ba && 0 < J && (Y += 1 << J);
20997
20998                  d: {
20999                    var sa,
21000                        za = Y,
21001                        ta = F,
21002                        oa = ha,
21003                        db = pa,
21004                        eb = U,
21005                        Ia = 0,
21006                        Ka = ta.m,
21007                        fb = D(Ka, 1);
21008                    M(oa, 0, 0, za);
21009
21010                    if (fb) {
21011                      var gb = D(Ka, 1) + 1,
21012                          hb = D(Ka, 1),
21013                          Ja = D(Ka, 0 == hb ? 1 : 8);
21014                      oa[Ja] = 1;
21015                      2 == gb && (Ja = D(Ka, 8), oa[Ja] = 1);
21016                      var ya = 1;
21017                    } else {
21018                      var Ua = V(19),
21019                          Va = D(Ka, 4) + 4;
21020
21021                      if (19 < Va) {
21022                        ta.a = 3;
21023                        var Aa = 0;
21024                        break d;
21025                      }
21026
21027                      for (sa = 0; sa < Va; ++sa) {
21028                        Ua[ne[sa]] = D(Ka, 3);
21029                      }
21030
21031                      var Ba = void 0,
21032                          sb = void 0,
21033                          Wa = ta,
21034                          ib = Ua,
21035                          Ca = za,
21036                          Xa = oa,
21037                          Oa = 0,
21038                          La = Wa.m,
21039                          Ya = 8,
21040                          Za = wa(128, O);
21041
21042                      e: for (;;) {
21043                        if (!Z(Za, 0, 7, ib, 19)) break e;
21044
21045                        if (D(La, 1)) {
21046                          var kb = 2 + 2 * D(La, 3),
21047                              Ba = 2 + D(La, kb);
21048                          if (Ba > Ca) break e;
21049                        } else Ba = Ca;
21050
21051                        for (sb = 0; sb < Ca && Ba--;) {
21052                          Sa(La);
21053                          var $a = Za[0 + (pb(La) & 127)];
21054                          qb(La, La.u + $a.g);
21055                          var jb = $a.value;
21056                          if (16 > jb) Xa[sb++] = jb, 0 != jb && (Ya = jb);else {
21057                            var lb = 16 == jb,
21058                                ab = jb - 16,
21059                                mb = oe[ab],
21060                                bb = D(La, pe[ab]) + mb;
21061                            if (sb + bb > Ca) break e;else for (var nb = lb ? Ya : 0; 0 < bb--;) {
21062                              Xa[sb++] = nb;
21063                            }
21064                          }
21065                        }
21066
21067                        Oa = 1;
21068                        break e;
21069                      }
21070
21071                      Oa || (Wa.a = 3);
21072                      ya = Oa;
21073                    }
21074
21075                    (ya = ya && !Ka.h) && (Ia = Z(db, eb, 8, oa, za));
21076                    ya && 0 != Ia ? Aa = Ia : (ta.a = 3, Aa = 0);
21077                  }
21078
21079                  if (0 == Aa) break c;
21080                  ra && 1 == qe[ba] && (ra = 0 == pa[U].g);
21081                  Fa += pa[U].g;
21082                  U += Aa;
21083
21084                  if (3 >= ba) {
21085                    var Pa = ha[0],
21086                        tb;
21087
21088                    for (tb = 1; tb < Y; ++tb) {
21089                      ha[tb] > Pa && (Pa = ha[tb]);
21090                    }
21091
21092                    Ha += Pa;
21093                  }
21094                }
21095
21096                ja.nd = ra;
21097                ja.Qb = 0;
21098                ra && (ja.qb = (da[3][ea[3] + 0].value << 24 | da[1][ea[1] + 0].value << 16 | da[2][ea[2] + 0].value) >>> 0, 0 == Fa && 256 > da[0][ea[0] + 0].value && (ja.Qb = 1, ja.qb += da[0][ea[0] + 0].value << 8));
21099                ja.jc = !ja.Qb && 6 > Ha;
21100
21101                if (ja.jc) {
21102                  var Ga,
21103                      Ea = ja;
21104
21105                  for (Ga = 0; Ga < xb; ++Ga) {
21106                    var Ma = Ga,
21107                        Na = Ea.pd[Ma],
21108                        vb = Ea.G[0][Ea.H[0] + Ma];
21109                    256 <= vb.value ? (Na.g = vb.g + 256, Na.value = vb.value) : (Na.g = 0, Na.value = 0, Ma >>= ub(vb, 8, Na), Ma >>= ub(Ea.G[1][Ea.H[1] + Ma], 16, Na), Ma >>= ub(Ea.G[2][Ea.H[2] + Ma], 0, Na), ub(Ea.G[3][Ea.H[3] + Ma], 24, Na));
21110                  }
21111                }
21112              }
21113
21114              R.vc = P;
21115              R.Wb = W;
21116              R.Ya = la;
21117              R.yc = ma;
21118              H = 1;
21119              break b;
21120            }
21121
21122            H = 0;
21123          }
21124          f = H;
21125
21126          if (!f) {
21127            d.a = 3;
21128            break a;
21129          }
21130
21131          if (0 < n) {
21132            if (l.ua = 1 << n, !Zb(l.Wa, n)) {
21133              d.a = 1;
21134              f = 0;
21135              break a;
21136            }
21137          } else l.ua = 0;
21138
21139          var Qa = d,
21140              cb = g,
21141              ob = h,
21142              Ra = Qa.s,
21143              Ta = Ra.xc;
21144          Qa.c = cb;
21145          Qa.i = ob;
21146          Ra.md = xa(cb, Ta);
21147          Ra.wc = 0 == Ta ? -1 : (1 << Ta) - 1;
21148
21149          if (c) {
21150            d.xb = re;
21151            break a;
21152          }
21153
21154          m = V(g * h);
21155
21156          if (null == m) {
21157            d.a = 1;
21158            f = 0;
21159            break a;
21160          }
21161
21162          f = (f = Jb(d, m, 0, g, h, h, null)) && !k.h;
21163          break a;
21164        }
21165
21166        f ? (null != e ? e[0] = m : (x(null == m), x(c)), d.$ = 0, c || Ac(l)) : Ac(l);
21167        return f;
21168      }
21169
21170      function Ec(a, b) {
21171        var c = a.c * a.i,
21172            d = c + b + 16 * b;
21173        x(a.c <= b);
21174        a.V = V(d);
21175        if (null == a.V) return a.Ta = null, a.Ua = 0, a.a = 1, 0;
21176        a.Ta = a.V;
21177        a.Ua = a.Ba + c + b;
21178        return 1;
21179      }
21180
21181      function se(a, b) {
21182        var c = a.C,
21183            d = b - c,
21184            e = a.V,
21185            f = a.Ba + a.c * c;
21186
21187        for (x(b <= a.l.o); 0 < d;) {
21188          var g = 16 < d ? 16 : d,
21189              h = a.l.ma,
21190              k = a.l.width,
21191              l = k * g,
21192              m = h.ca,
21193              n = h.tb + k * c,
21194              r = a.Ta,
21195              q = a.Ua;
21196          oc(a, g, e, f);
21197          Fc(r, q, m, n, l);
21198          zc(h, c, c + g, m, n, k);
21199          d -= g;
21200          e += g * a.c;
21201          c += g;
21202        }
21203
21204        x(c == b);
21205        a.C = a.Ma = b;
21206      }
21207
21208      function te(a, b) {
21209        var c = [0],
21210            d = [0],
21211            e = [0];
21212
21213        a: for (;;) {
21214          if (null == a) return 0;
21215          if (null == b) return a.a = 2, 0;
21216          a.l = b;
21217          a.a = 0;
21218          cb(a.m, b.data, b.w, b.ha);
21219
21220          if (!mc(a.m, c, d, e)) {
21221            a.a = 3;
21222            break a;
21223          }
21224
21225          a.xb = Cc;
21226          b.width = c[0];
21227          b.height = d[0];
21228          if (!rb(c[0], d[0], 1, a, null)) break a;
21229          return 1;
21230        }
21231
21232        x(0 != a.a);
21233        return 0;
21234      }
21235
21236      function ue() {
21237        this.ub = this.yd = this.td = this.Rb = 0;
21238      }
21239
21240      function ve() {
21241        this.Kd = this.Ld = this.Ud = this.Td = this.i = this.c = 0;
21242      }
21243
21244      function we() {
21245        this.Fb = this.Bb = this.Cb = 0;
21246        this.Zb = V(4);
21247        this.Lb = V(4);
21248      }
21249
21250      function Gc() {
21251        this.Yb = wb();
21252      }
21253
21254      function xe() {
21255        this.jb = V(3);
21256        this.Wc = Ed([4, 8], Gc);
21257        this.Xc = Ed([4, 17], Gc);
21258      }
21259
21260      function ye() {
21261        this.Pc = this.wb = this.Tb = this.zd = 0;
21262        this.vd = new V(4);
21263        this.od = new V(4);
21264      }
21265
21266      function Xa() {
21267        this.ld = this.La = this.dd = this.tc = 0;
21268      }
21269
21270      function Hc() {
21271        this.Na = this.la = 0;
21272      }
21273
21274      function ze() {
21275        this.Sc = [0, 0];
21276        this.Eb = [0, 0];
21277        this.Qc = [0, 0];
21278        this.ia = this.lc = 0;
21279      }
21280
21281      function Kb() {
21282        this.ad = V(384);
21283        this.Za = 0;
21284        this.Ob = V(16);
21285        this.$b = this.Ad = this.ia = this.Gc = this.Hc = this.Dd = 0;
21286      }
21287
21288      function Ae() {
21289        this.uc = this.M = this.Nb = 0;
21290        this.wa = Array(new Xa());
21291        this.Y = 0;
21292        this.ya = Array(new Kb());
21293        this.aa = 0;
21294        this.l = new Oa();
21295      }
21296
21297      function Ic() {
21298        this.y = V(16);
21299        this.f = V(8);
21300        this.ea = V(8);
21301      }
21302
21303      function Be() {
21304        this.cb = this.a = 0;
21305        this.sc = "";
21306        this.m = new Wb();
21307        this.Od = new ue();
21308        this.Kc = new ve();
21309        this.ed = new ye();
21310        this.Qa = new we();
21311        this.Ic = this.$c = this.Aa = 0;
21312        this.D = new Ae();
21313        this.Xb = this.Va = this.Hb = this.zb = this.yb = this.Ub = this.za = 0;
21314        this.Jc = wa(8, Wb);
21315        this.ia = 0;
21316        this.pb = wa(4, ze);
21317        this.Pa = new xe();
21318        this.Bd = this.kc = 0;
21319        this.Ac = [];
21320        this.Bc = 0;
21321        this.zc = [0, 0, 0, 0];
21322        this.Gd = Array(new Ic());
21323        this.Hd = 0;
21324        this.rb = Array(new Hc());
21325        this.sb = 0;
21326        this.wa = Array(new Xa());
21327        this.Y = 0;
21328        this.oc = [];
21329        this.pc = 0;
21330        this.sa = [];
21331        this.ta = 0;
21332        this.qa = [];
21333        this.ra = 0;
21334        this.Ha = [];
21335        this.B = this.R = this.Ia = 0;
21336        this.Ec = [];
21337        this.M = this.ja = this.Vb = this.Fc = 0;
21338        this.ya = Array(new Kb());
21339        this.L = this.aa = 0;
21340        this.gd = Ed([4, 2], Xa);
21341        this.ga = null;
21342        this.Fa = [];
21343        this.Cc = this.qc = this.P = 0;
21344        this.Gb = [];
21345        this.Uc = 0;
21346        this.mb = [];
21347        this.nb = 0;
21348        this.rc = [];
21349        this.Ga = this.Vc = 0;
21350      }
21351
21352      function ga(a, b) {
21353        return 0 > a ? 0 : a > b ? b : a;
21354      }
21355
21356      function Oa() {
21357        this.T = this.U = this.ka = this.height = this.width = 0;
21358        this.y = [];
21359        this.f = [];
21360        this.ea = [];
21361        this.Rc = this.fa = this.W = this.N = this.O = 0;
21362        this.ma = "void";
21363        this.put = "VP8IoPutHook";
21364        this.ac = "VP8IoSetupHook";
21365        this.bc = "VP8IoTeardownHook";
21366        this.ha = this.Kb = 0;
21367        this.data = [];
21368        this.hb = this.ib = this.da = this.o = this.j = this.va = this.v = this.Da = this.ob = this.w = 0;
21369        this.F = [];
21370        this.J = 0;
21371      }
21372
21373      function Ce() {
21374        var a = new Be();
21375        null != a && (a.a = 0, a.sc = "OK", a.cb = 0, a.Xb = 0, oa || (oa = De));
21376        return a;
21377      }
21378
21379      function T(a, b, c) {
21380        0 == a.a && (a.a = b, a.sc = c, a.cb = 0);
21381        return 0;
21382      }
21383
21384      function Jc(a, b, c) {
21385        return 3 <= c && 157 == a[b + 0] && 1 == a[b + 1] && 42 == a[b + 2];
21386      }
21387
21388      function Kc(a, b) {
21389        if (null == a) return 0;
21390        a.a = 0;
21391        a.sc = "OK";
21392        if (null == b) return T(a, 2, "null VP8Io passed to VP8GetHeaders()");
21393        var c = b.data;
21394        var d = b.w;
21395        var e = b.ha;
21396        if (4 > e) return T(a, 7, "Truncated header.");
21397        var f = c[d + 0] | c[d + 1] << 8 | c[d + 2] << 16;
21398        var g = a.Od;
21399        g.Rb = !(f & 1);
21400        g.td = f >> 1 & 7;
21401        g.yd = f >> 4 & 1;
21402        g.ub = f >> 5;
21403        if (3 < g.td) return T(a, 3, "Incorrect keyframe parameters.");
21404        if (!g.yd) return T(a, 4, "Frame not displayable.");
21405        d += 3;
21406        e -= 3;
21407        var h = a.Kc;
21408
21409        if (g.Rb) {
21410          if (7 > e) return T(a, 7, "cannot parse picture header");
21411          if (!Jc(c, d, e)) return T(a, 3, "Bad code word");
21412          h.c = (c[d + 4] << 8 | c[d + 3]) & 16383;
21413          h.Td = c[d + 4] >> 6;
21414          h.i = (c[d + 6] << 8 | c[d + 5]) & 16383;
21415          h.Ud = c[d + 6] >> 6;
21416          d += 7;
21417          e -= 7;
21418          a.za = h.c + 15 >> 4;
21419          a.Ub = h.i + 15 >> 4;
21420          b.width = h.c;
21421          b.height = h.i;
21422          b.Da = 0;
21423          b.j = 0;
21424          b.v = 0;
21425          b.va = b.width;
21426          b.o = b.height;
21427          b.da = 0;
21428          b.ib = b.width;
21429          b.hb = b.height;
21430          b.U = b.width;
21431          b.T = b.height;
21432          f = a.Pa;
21433          M(f.jb, 0, 255, f.jb.length);
21434          f = a.Qa;
21435          x(null != f);
21436          f.Cb = 0;
21437          f.Bb = 0;
21438          f.Fb = 1;
21439          M(f.Zb, 0, 0, f.Zb.length);
21440          M(f.Lb, 0, 0, f.Lb);
21441        }
21442
21443        if (g.ub > e) return T(a, 7, "bad partition length");
21444        f = a.m;
21445        ma(f, c, d, g.ub);
21446        d += g.ub;
21447        e -= g.ub;
21448        g.Rb && (h.Ld = G(f), h.Kd = G(f));
21449        h = a.Qa;
21450        var k = a.Pa,
21451            l;
21452        x(null != f);
21453        x(null != h);
21454        h.Cb = G(f);
21455
21456        if (h.Cb) {
21457          h.Bb = G(f);
21458
21459          if (G(f)) {
21460            h.Fb = G(f);
21461
21462            for (l = 0; 4 > l; ++l) {
21463              h.Zb[l] = G(f) ? ca(f, 7) : 0;
21464            }
21465
21466            for (l = 0; 4 > l; ++l) {
21467              h.Lb[l] = G(f) ? ca(f, 6) : 0;
21468            }
21469          }
21470
21471          if (h.Bb) for (l = 0; 3 > l; ++l) {
21472            k.jb[l] = G(f) ? na(f, 8) : 255;
21473          }
21474        } else h.Bb = 0;
21475
21476        if (f.Ka) return T(a, 3, "cannot parse segment header");
21477        h = a.ed;
21478        h.zd = G(f);
21479        h.Tb = na(f, 6);
21480        h.wb = na(f, 3);
21481        h.Pc = G(f);
21482
21483        if (h.Pc && G(f)) {
21484          for (k = 0; 4 > k; ++k) {
21485            G(f) && (h.vd[k] = ca(f, 6));
21486          }
21487
21488          for (k = 0; 4 > k; ++k) {
21489            G(f) && (h.od[k] = ca(f, 6));
21490          }
21491        }
21492
21493        a.L = 0 == h.Tb ? 0 : h.zd ? 1 : 2;
21494        if (f.Ka) return T(a, 3, "cannot parse filter header");
21495        l = d;
21496        var m = e;
21497        e = l;
21498        d = l + m;
21499        h = m;
21500        a.Xb = (1 << na(a.m, 2)) - 1;
21501        k = a.Xb;
21502        if (m < 3 * k) c = 7;else {
21503          l += 3 * k;
21504          h -= 3 * k;
21505
21506          for (m = 0; m < k; ++m) {
21507            var n = c[e + 0] | c[e + 1] << 8 | c[e + 2] << 16;
21508            n > h && (n = h);
21509            ma(a.Jc[+m], c, l, n);
21510            l += n;
21511            h -= n;
21512            e += 3;
21513          }
21514
21515          ma(a.Jc[+k], c, l, h);
21516          c = l < d ? 0 : 5;
21517        }
21518        if (0 != c) return T(a, c, "cannot parse partitions");
21519        l = a.m;
21520        c = na(l, 7);
21521        e = G(l) ? ca(l, 4) : 0;
21522        d = G(l) ? ca(l, 4) : 0;
21523        h = G(l) ? ca(l, 4) : 0;
21524        k = G(l) ? ca(l, 4) : 0;
21525        l = G(l) ? ca(l, 4) : 0;
21526        m = a.Qa;
21527
21528        for (n = 0; 4 > n; ++n) {
21529          if (m.Cb) {
21530            var r = m.Zb[n];
21531            m.Fb || (r += c);
21532          } else if (0 < n) {
21533            a.pb[n] = a.pb[0];
21534            continue;
21535          } else r = c;
21536
21537          var q = a.pb[n];
21538          q.Sc[0] = Lb[ga(r + e, 127)];
21539          q.Sc[1] = Mb[ga(r + 0, 127)];
21540          q.Eb[0] = 2 * Lb[ga(r + d, 127)];
21541          q.Eb[1] = 101581 * Mb[ga(r + h, 127)] >> 16;
21542          8 > q.Eb[1] && (q.Eb[1] = 8);
21543          q.Qc[0] = Lb[ga(r + k, 117)];
21544          q.Qc[1] = Mb[ga(r + l, 127)];
21545          q.lc = r + l;
21546        }
21547
21548        if (!g.Rb) return T(a, 4, "Not a key frame.");
21549        G(f);
21550        g = a.Pa;
21551
21552        for (c = 0; 4 > c; ++c) {
21553          for (e = 0; 8 > e; ++e) {
21554            for (d = 0; 3 > d; ++d) {
21555              for (h = 0; 11 > h; ++h) {
21556                k = K(f, Ee[c][e][d][h]) ? na(f, 8) : Fe[c][e][d][h], g.Wc[c][e].Yb[d][h] = k;
21557              }
21558            }
21559          }
21560
21561          for (e = 0; 17 > e; ++e) {
21562            g.Xc[c][e] = g.Wc[c][Ge[e]];
21563          }
21564        }
21565
21566        a.kc = G(f);
21567        a.kc && (a.Bd = na(f, 8));
21568        return a.cb = 1;
21569      }
21570
21571      function De(a, b, c, d, e, f, g) {
21572        var h = b[e].Yb[c];
21573
21574        for (c = 0; 16 > e; ++e) {
21575          if (!K(a, h[c + 0])) return e;
21576
21577          for (; !K(a, h[c + 1]);) {
21578            if (h = b[++e].Yb[0], c = 0, 16 == e) return 16;
21579          }
21580
21581          var k = b[e + 1].Yb;
21582
21583          if (K(a, h[c + 2])) {
21584            var l = a,
21585                m = h,
21586                n = c;
21587            var r = 0;
21588            if (K(l, m[n + 3])) {
21589              if (K(l, m[n + 6])) {
21590                h = 0;
21591                r = K(l, m[n + 8]);
21592                m = K(l, m[n + 9 + r]);
21593                n = 2 * r + m;
21594                r = 0;
21595
21596                for (m = He[n]; m[h]; ++h) {
21597                  r += r + K(l, m[h]);
21598                }
21599
21600                r += 3 + (8 << n);
21601              } else K(l, m[n + 7]) ? (r = 7 + 2 * K(l, 165), r += K(l, 145)) : r = 5 + K(l, 159);
21602            } else K(l, m[n + 4]) ? r = 3 + K(l, m[n + 5]) : r = 2;
21603            h = k[2];
21604          } else r = 1, h = k[1];
21605
21606          k = g + Ie[e];
21607          l = a;
21608          0 > l.b && Qa(l);
21609          var m = l.b,
21610              n = l.Ca >> 1,
21611              q = n - (l.I >> m) >> 31;
21612          --l.b;
21613          l.Ca += q;
21614          l.Ca |= 1;
21615          l.I -= (n + 1 & q) << m;
21616          f[k] = ((r ^ q) - q) * d[(0 < e) + 0];
21617        }
21618
21619        return 16;
21620      }
21621
21622      function Lc(a) {
21623        var b = a.rb[a.sb - 1];
21624        b.la = 0;
21625        b.Na = 0;
21626        M(a.zc, 0, 0, a.zc.length);
21627        a.ja = 0;
21628      }
21629
21630      function Je(a, b) {
21631        for (a.M = 0; a.M < a.Va; ++a.M) {
21632          var c = a.Jc[a.M & a.Xb],
21633              d = a.m,
21634              e = a,
21635              f;
21636
21637          for (f = 0; f < e.za; ++f) {
21638            var g = d;
21639            var h = e;
21640            var k = h.Ac,
21641                l = h.Bc + 4 * f,
21642                m = h.zc,
21643                n = h.ya[h.aa + f];
21644            h.Qa.Bb ? n.$b = K(g, h.Pa.jb[0]) ? 2 + K(g, h.Pa.jb[2]) : K(g, h.Pa.jb[1]) : n.$b = 0;
21645            h.kc && (n.Ad = K(g, h.Bd));
21646            n.Za = !K(g, 145) + 0;
21647
21648            if (n.Za) {
21649              var r = n.Ob,
21650                  q = 0;
21651
21652              for (h = 0; 4 > h; ++h) {
21653                var t = m[0 + h];
21654                var v;
21655
21656                for (v = 0; 4 > v; ++v) {
21657                  t = Ke[k[l + v]][t];
21658
21659                  for (var p = Mc[K(g, t[0])]; 0 < p;) {
21660                    p = Mc[2 * p + K(g, t[p])];
21661                  }
21662
21663                  t = -p;
21664                  k[l + v] = t;
21665                }
21666
21667                I(r, q, k, l, 4);
21668                q += 4;
21669                m[0 + h] = t;
21670              }
21671            } else t = K(g, 156) ? K(g, 128) ? 1 : 3 : K(g, 163) ? 2 : 0, n.Ob[0] = t, M(k, l, t, 4), M(m, 0, t, 4);
21672
21673            n.Dd = K(g, 142) ? K(g, 114) ? K(g, 183) ? 1 : 3 : 2 : 0;
21674          }
21675
21676          if (e.m.Ka) return T(a, 7, "Premature end-of-partition0 encountered.");
21677
21678          for (; a.ja < a.za; ++a.ja) {
21679            d = a;
21680            e = c;
21681            g = d.rb[d.sb - 1];
21682            k = d.rb[d.sb + d.ja];
21683            f = d.ya[d.aa + d.ja];
21684            if (l = d.kc ? f.Ad : 0) g.la = k.la = 0, f.Za || (g.Na = k.Na = 0), f.Hc = 0, f.Gc = 0, f.ia = 0;else {
21685              var u,
21686                  w,
21687                  g = k,
21688                  k = e,
21689                  l = d.Pa.Xc,
21690                  m = d.ya[d.aa + d.ja],
21691                  n = d.pb[m.$b];
21692              h = m.ad;
21693              r = 0;
21694              q = d.rb[d.sb - 1];
21695              t = v = 0;
21696              M(h, r, 0, 384);
21697
21698              if (m.Za) {
21699                var y = 0;
21700                var A = l[3];
21701              } else {
21702                p = V(16);
21703                var E = g.Na + q.Na;
21704                E = oa(k, l[1], E, n.Eb, 0, p, 0);
21705                g.Na = q.Na = (0 < E) + 0;
21706                if (1 < E) Nc(p, 0, h, r);else {
21707                  var B = p[0] + 3 >> 3;
21708
21709                  for (p = 0; 256 > p; p += 16) {
21710                    h[r + p] = B;
21711                  }
21712                }
21713                y = 1;
21714                A = l[0];
21715              }
21716
21717              var C = g.la & 15;
21718              var N = q.la & 15;
21719
21720              for (p = 0; 4 > p; ++p) {
21721                var z = N & 1;
21722
21723                for (B = w = 0; 4 > B; ++B) {
21724                  E = z + (C & 1), E = oa(k, A, E, n.Sc, y, h, r), z = E > y, C = C >> 1 | z << 7, w = w << 2 | (3 < E ? 3 : 1 < E ? 2 : 0 != h[r + 0]), r += 16;
21725                }
21726
21727                C >>= 4;
21728                N = N >> 1 | z << 7;
21729                v = (v << 8 | w) >>> 0;
21730              }
21731
21732              A = C;
21733              y = N >> 4;
21734
21735              for (u = 0; 4 > u; u += 2) {
21736                w = 0;
21737                C = g.la >> 4 + u;
21738                N = q.la >> 4 + u;
21739
21740                for (p = 0; 2 > p; ++p) {
21741                  z = N & 1;
21742
21743                  for (B = 0; 2 > B; ++B) {
21744                    E = z + (C & 1), E = oa(k, l[2], E, n.Qc, 0, h, r), z = 0 < E, C = C >> 1 | z << 3, w = w << 2 | (3 < E ? 3 : 1 < E ? 2 : 0 != h[r + 0]), r += 16;
21745                  }
21746
21747                  C >>= 2;
21748                  N = N >> 1 | z << 5;
21749                }
21750
21751                t |= w << 4 * u;
21752                A |= C << 4 << u;
21753                y |= (N & 240) << u;
21754              }
21755
21756              g.la = A;
21757              q.la = y;
21758              m.Hc = v;
21759              m.Gc = t;
21760              m.ia = t & 43690 ? 0 : n.ia;
21761              l = !(v | t);
21762            }
21763            0 < d.L && (d.wa[d.Y + d.ja] = d.gd[f.$b][f.Za], d.wa[d.Y + d.ja].La |= !l);
21764            if (e.Ka) return T(a, 7, "Premature end-of-file encountered.");
21765          }
21766
21767          Lc(a);
21768          c = a;
21769          d = b;
21770          e = 1;
21771          f = c.D;
21772          g = 0 < c.L && c.M >= c.zb && c.M <= c.Va;
21773          if (0 == c.Aa) a: {
21774            f.M = c.M, f.uc = g, Oc(c, f), e = 1;
21775            w = c.D;
21776            f = w.Nb;
21777            t = Ya[c.L];
21778            g = t * c.R;
21779            k = t / 2 * c.B;
21780            p = 16 * f * c.R;
21781            B = 8 * f * c.B;
21782            l = c.sa;
21783            m = c.ta - g + p;
21784            n = c.qa;
21785            h = c.ra - k + B;
21786            r = c.Ha;
21787            q = c.Ia - k + B;
21788            C = w.M;
21789            N = 0 == C;
21790            v = C >= c.Va - 1;
21791            2 == c.Aa && Oc(c, w);
21792            if (w.uc) for (E = c, z = E.D.M, x(E.D.uc), w = E.yb; w < E.Hb; ++w) {
21793              var Q = E;
21794              y = w;
21795              A = z;
21796              var S = Q.D,
21797                  D = S.Nb;
21798              u = Q.R;
21799              var S = S.wa[S.Y + y],
21800                  F = Q.sa,
21801                  H = Q.ta + 16 * D * u + 16 * y,
21802                  J = S.dd,
21803                  G = S.tc;
21804              if (0 != G) if (x(3 <= G), 1 == Q.L) 0 < y && Pc(F, H, u, G + 4), S.La && Qc(F, H, u, G), 0 < A && Rc(F, H, u, G + 4), S.La && Sc(F, H, u, G);else {
21805                var L = Q.B,
21806                    O = Q.qa,
21807                    P = Q.ra + 8 * D * L + 8 * y,
21808                    R = Q.Ha,
21809                    Q = Q.Ia + 8 * D * L + 8 * y,
21810                    D = S.ld;
21811                0 < y && (Tc(F, H, u, G + 4, J, D), Uc(O, P, R, Q, L, G + 4, J, D));
21812                S.La && (Vc(F, H, u, G, J, D), Wc(O, P, R, Q, L, G, J, D));
21813                0 < A && (Xc(F, H, u, G + 4, J, D), Yc(O, P, R, Q, L, G + 4, J, D));
21814                S.La && (Zc(F, H, u, G, J, D), $c(O, P, R, Q, L, G, J, D));
21815              }
21816            }
21817            c.ia && alert("todo:DitherRow");
21818
21819            if (null != d.put) {
21820              w = 16 * C;
21821              C = 16 * (C + 1);
21822              N ? (d.y = c.sa, d.O = c.ta + p, d.f = c.qa, d.N = c.ra + B, d.ea = c.Ha, d.W = c.Ia + B) : (w -= t, d.y = l, d.O = m, d.f = n, d.N = h, d.ea = r, d.W = q);
21823              v || (C -= t);
21824              C > d.o && (C = d.o);
21825              d.F = null;
21826              d.J = null;
21827
21828              if (null != c.Fa && 0 < c.Fa.length && w < C && (d.J = Le(c, d, w, C - w), d.F = c.mb, null == d.F && 0 == d.F.length)) {
21829                e = T(c, 3, "Could not decode alpha data.");
21830                break a;
21831              }
21832
21833              w < d.j && (t = d.j - w, w = d.j, x(!(t & 1)), d.O += c.R * t, d.N += c.B * (t >> 1), d.W += c.B * (t >> 1), null != d.F && (d.J += d.width * t));
21834              w < C && (d.O += d.v, d.N += d.v >> 1, d.W += d.v >> 1, null != d.F && (d.J += d.v), d.ka = w - d.j, d.U = d.va - d.v, d.T = C - w, e = d.put(d));
21835            }
21836
21837            f + 1 != c.Ic || v || (I(c.sa, c.ta - g, l, m + 16 * c.R, g), I(c.qa, c.ra - k, n, h + 8 * c.B, k), I(c.Ha, c.Ia - k, r, q + 8 * c.B, k));
21838          }
21839          if (!e) return T(a, 6, "Output aborted.");
21840        }
21841
21842        return 1;
21843      }
21844
21845      function Me(a, b) {
21846        if (null == a) return 0;
21847        if (null == b) return T(a, 2, "NULL VP8Io parameter in VP8Decode().");
21848        if (!a.cb && !Kc(a, b)) return 0;
21849        x(a.cb);
21850
21851        if (null == b.ac || b.ac(b)) {
21852          b.ob && (a.L = 0);
21853          var c = Ya[a.L];
21854          2 == a.L ? (a.yb = 0, a.zb = 0) : (a.yb = b.v - c >> 4, a.zb = b.j - c >> 4, 0 > a.yb && (a.yb = 0), 0 > a.zb && (a.zb = 0));
21855          a.Va = b.o + 15 + c >> 4;
21856          a.Hb = b.va + 15 + c >> 4;
21857          a.Hb > a.za && (a.Hb = a.za);
21858          a.Va > a.Ub && (a.Va = a.Ub);
21859
21860          if (0 < a.L) {
21861            var d = a.ed;
21862
21863            for (c = 0; 4 > c; ++c) {
21864              var e;
21865
21866              if (a.Qa.Cb) {
21867                var f = a.Qa.Lb[c];
21868                a.Qa.Fb || (f += d.Tb);
21869              } else f = d.Tb;
21870
21871              for (e = 0; 1 >= e; ++e) {
21872                var g = a.gd[c][e],
21873                    h = f;
21874                d.Pc && (h += d.vd[0], e && (h += d.od[0]));
21875                h = 0 > h ? 0 : 63 < h ? 63 : h;
21876
21877                if (0 < h) {
21878                  var k = h;
21879                  0 < d.wb && (k = 4 < d.wb ? k >> 2 : k >> 1, k > 9 - d.wb && (k = 9 - d.wb));
21880                  1 > k && (k = 1);
21881                  g.dd = k;
21882                  g.tc = 2 * h + k;
21883                  g.ld = 40 <= h ? 2 : 15 <= h ? 1 : 0;
21884                } else g.tc = 0;
21885
21886                g.La = e;
21887              }
21888            }
21889          }
21890
21891          c = 0;
21892        } else T(a, 6, "Frame setup failed"), c = a.a;
21893
21894        if (c = 0 == c) {
21895          if (c) {
21896            a.$c = 0;
21897            0 < a.Aa || (a.Ic = Ne);
21898
21899            b: {
21900              c = a.Ic;
21901              var k = a.za,
21902                  d = 4 * k,
21903                  l = 32 * k,
21904                  m = k + 1,
21905                  n = 0 < a.L ? k * (0 < a.Aa ? 2 : 1) : 0,
21906                  r = (2 == a.Aa ? 2 : 1) * k;
21907              e = 3 * (16 * c + Ya[a.L]) / 2 * l;
21908              f = null != a.Fa && 0 < a.Fa.length ? a.Kc.c * a.Kc.i : 0;
21909              g = d + 832 + e + f;
21910              if (g != g) c = 0;else {
21911                if (g > a.Vb) {
21912                  a.Vb = 0;
21913                  a.Ec = V(g);
21914                  a.Fc = 0;
21915
21916                  if (null == a.Ec) {
21917                    c = T(a, 1, "no memory during frame initialization.");
21918                    break b;
21919                  }
21920
21921                  a.Vb = g;
21922                }
21923
21924                g = a.Ec;
21925                h = a.Fc;
21926                a.Ac = g;
21927                a.Bc = h;
21928                h += d;
21929                a.Gd = wa(l, Ic);
21930                a.Hd = 0;
21931                a.rb = wa(m + 1, Hc);
21932                a.sb = 1;
21933                a.wa = n ? wa(n, Xa) : null;
21934                a.Y = 0;
21935                a.D.Nb = 0;
21936                a.D.wa = a.wa;
21937                a.D.Y = a.Y;
21938                0 < a.Aa && (a.D.Y += k);
21939                x(!0);
21940                a.oc = g;
21941                a.pc = h;
21942                h += 832;
21943                a.ya = wa(r, Kb);
21944                a.aa = 0;
21945                a.D.ya = a.ya;
21946                a.D.aa = a.aa;
21947                2 == a.Aa && (a.D.aa += k);
21948                a.R = 16 * k;
21949                a.B = 8 * k;
21950                l = Ya[a.L];
21951                k = l * a.R;
21952                l = l / 2 * a.B;
21953                a.sa = g;
21954                a.ta = h + k;
21955                a.qa = a.sa;
21956                a.ra = a.ta + 16 * c * a.R + l;
21957                a.Ha = a.qa;
21958                a.Ia = a.ra + 8 * c * a.B + l;
21959                a.$c = 0;
21960                h += e;
21961                a.mb = f ? g : null;
21962                a.nb = f ? h : null;
21963                x(h + f <= a.Fc + a.Vb);
21964                Lc(a);
21965                M(a.Ac, a.Bc, 0, d);
21966                c = 1;
21967              }
21968            }
21969
21970            if (c) {
21971              b.ka = 0;
21972              b.y = a.sa;
21973              b.O = a.ta;
21974              b.f = a.qa;
21975              b.N = a.ra;
21976              b.ea = a.Ha;
21977              b.Vd = a.Ia;
21978              b.fa = a.R;
21979              b.Rc = a.B;
21980              b.F = null;
21981              b.J = 0;
21982
21983              if (!ad) {
21984                for (c = -255; 255 >= c; ++c) {
21985                  bd[255 + c] = 0 > c ? -c : c;
21986                }
21987
21988                for (c = -1020; 1020 >= c; ++c) {
21989                  cd[1020 + c] = -128 > c ? -128 : 127 < c ? 127 : c;
21990                }
21991
21992                for (c = -112; 112 >= c; ++c) {
21993                  dd[112 + c] = -16 > c ? -16 : 15 < c ? 15 : c;
21994                }
21995
21996                for (c = -255; 510 >= c; ++c) {
21997                  ed[255 + c] = 0 > c ? 0 : 255 < c ? 255 : c;
21998                }
21999
22000                ad = 1;
22001              }
22002
22003              Nc = Oe;
22004              Za = Pe;
22005              Nb = Qe;
22006              pa = Re;
22007              Ob = Se;
22008              fd = Te;
22009              Xc = Ue;
22010              Tc = Ve;
22011              Yc = We;
22012              Uc = Xe;
22013              Zc = Ye;
22014              Vc = Ze;
22015              $c = $e;
22016              Wc = af;
22017              Rc = gd;
22018              Pc = hd;
22019              Sc = bf;
22020              Qc = cf;
22021              W[0] = df;
22022              W[1] = ef;
22023              W[2] = ff;
22024              W[3] = gf;
22025              W[4] = hf;
22026              W[5] = jf;
22027              W[6] = kf;
22028              W[7] = lf;
22029              W[8] = mf;
22030              W[9] = nf;
22031              Y[0] = of;
22032              Y[1] = pf;
22033              Y[2] = qf;
22034              Y[3] = rf;
22035              Y[4] = sf;
22036              Y[5] = tf;
22037              Y[6] = uf;
22038              ka[0] = vf;
22039              ka[1] = wf;
22040              ka[2] = xf;
22041              ka[3] = yf;
22042              ka[4] = zf;
22043              ka[5] = Af;
22044              ka[6] = Bf;
22045              c = 1;
22046            } else c = 0;
22047          }
22048
22049          c && (c = Je(a, b));
22050          null != b.bc && b.bc(b);
22051          c &= 1;
22052        }
22053
22054        if (!c) return 0;
22055        a.cb = 0;
22056        return c;
22057      }
22058
22059      function qa(a, b, c, d, e) {
22060        e = a[b + c + 32 * d] + (e >> 3);
22061        a[b + c + 32 * d] = e & -256 ? 0 > e ? 0 : 255 : e;
22062      }
22063
22064      function kb(a, b, c, d, e, f) {
22065        qa(a, b, 0, c, d + e);
22066        qa(a, b, 1, c, d + f);
22067        qa(a, b, 2, c, d - f);
22068        qa(a, b, 3, c, d - e);
22069      }
22070
22071      function da(a) {
22072        return (20091 * a >> 16) + a;
22073      }
22074
22075      function id(a, b, c, d) {
22076        var e = 0,
22077            f;
22078        var g = V(16);
22079
22080        for (f = 0; 4 > f; ++f) {
22081          var h = a[b + 0] + a[b + 8];
22082          var k = a[b + 0] - a[b + 8];
22083          var l = (35468 * a[b + 4] >> 16) - da(a[b + 12]);
22084          var m = da(a[b + 4]) + (35468 * a[b + 12] >> 16);
22085          g[e + 0] = h + m;
22086          g[e + 1] = k + l;
22087          g[e + 2] = k - l;
22088          g[e + 3] = h - m;
22089          e += 4;
22090          b++;
22091        }
22092
22093        for (f = e = 0; 4 > f; ++f) {
22094          a = g[e + 0] + 4, h = a + g[e + 8], k = a - g[e + 8], l = (35468 * g[e + 4] >> 16) - da(g[e + 12]), m = da(g[e + 4]) + (35468 * g[e + 12] >> 16), qa(c, d, 0, 0, h + m), qa(c, d, 1, 0, k + l), qa(c, d, 2, 0, k - l), qa(c, d, 3, 0, h - m), e++, d += 32;
22095        }
22096      }
22097
22098      function Te(a, b, c, d) {
22099        var e = a[b + 0] + 4,
22100            f = 35468 * a[b + 4] >> 16,
22101            g = da(a[b + 4]),
22102            h = 35468 * a[b + 1] >> 16;
22103        a = da(a[b + 1]);
22104        kb(c, d, 0, e + g, a, h);
22105        kb(c, d, 1, e + f, a, h);
22106        kb(c, d, 2, e - f, a, h);
22107        kb(c, d, 3, e - g, a, h);
22108      }
22109
22110      function Pe(a, b, c, d, e) {
22111        id(a, b, c, d);
22112        e && id(a, b + 16, c, d + 4);
22113      }
22114
22115      function Qe(a, b, c, d) {
22116        Za(a, b + 0, c, d, 1);
22117        Za(a, b + 32, c, d + 128, 1);
22118      }
22119
22120      function Re(a, b, c, d) {
22121        a = a[b + 0] + 4;
22122        var e;
22123
22124        for (e = 0; 4 > e; ++e) {
22125          for (b = 0; 4 > b; ++b) {
22126            qa(c, d, b, e, a);
22127          }
22128        }
22129      }
22130
22131      function Se(a, b, c, d) {
22132        a[b + 0] && pa(a, b + 0, c, d);
22133        a[b + 16] && pa(a, b + 16, c, d + 4);
22134        a[b + 32] && pa(a, b + 32, c, d + 128);
22135        a[b + 48] && pa(a, b + 48, c, d + 128 + 4);
22136      }
22137
22138      function Oe(a, b, c, d) {
22139        var e = V(16),
22140            f;
22141
22142        for (f = 0; 4 > f; ++f) {
22143          var g = a[b + 0 + f] + a[b + 12 + f];
22144          var h = a[b + 4 + f] + a[b + 8 + f];
22145          var k = a[b + 4 + f] - a[b + 8 + f];
22146          var l = a[b + 0 + f] - a[b + 12 + f];
22147          e[0 + f] = g + h;
22148          e[8 + f] = g - h;
22149          e[4 + f] = l + k;
22150          e[12 + f] = l - k;
22151        }
22152
22153        for (f = 0; 4 > f; ++f) {
22154          a = e[0 + 4 * f] + 3, g = a + e[3 + 4 * f], h = e[1 + 4 * f] + e[2 + 4 * f], k = e[1 + 4 * f] - e[2 + 4 * f], l = a - e[3 + 4 * f], c[d + 0] = g + h >> 3, c[d + 16] = l + k >> 3, c[d + 32] = g - h >> 3, c[d + 48] = l - k >> 3, d += 64;
22155        }
22156      }
22157
22158      function Pb(a, b, c) {
22159        var d = b - 32,
22160            e = R,
22161            f = 255 - a[d - 1],
22162            g;
22163
22164        for (g = 0; g < c; ++g) {
22165          var h = e,
22166              k = f + a[b - 1],
22167              l;
22168
22169          for (l = 0; l < c; ++l) {
22170            a[b + l] = h[k + a[d + l]];
22171          }
22172
22173          b += 32;
22174        }
22175      }
22176
22177      function ef(a, b) {
22178        Pb(a, b, 4);
22179      }
22180
22181      function wf(a, b) {
22182        Pb(a, b, 8);
22183      }
22184
22185      function pf(a, b) {
22186        Pb(a, b, 16);
22187      }
22188
22189      function qf(a, b) {
22190        var c;
22191
22192        for (c = 0; 16 > c; ++c) {
22193          I(a, b + 32 * c, a, b - 32, 16);
22194        }
22195      }
22196
22197      function rf(a, b) {
22198        var c;
22199
22200        for (c = 16; 0 < c; --c) {
22201          M(a, b, a[b - 1], 16), b += 32;
22202        }
22203      }
22204
22205      function $a(a, b, c) {
22206        var d;
22207
22208        for (d = 0; 16 > d; ++d) {
22209          M(b, c + 32 * d, a, 16);
22210        }
22211      }
22212
22213      function of(a, b) {
22214        var c = 16,
22215            d;
22216
22217        for (d = 0; 16 > d; ++d) {
22218          c += a[b - 1 + 32 * d] + a[b + d - 32];
22219        }
22220
22221        $a(c >> 5, a, b);
22222      }
22223
22224      function sf(a, b) {
22225        var c = 8,
22226            d;
22227
22228        for (d = 0; 16 > d; ++d) {
22229          c += a[b - 1 + 32 * d];
22230        }
22231
22232        $a(c >> 4, a, b);
22233      }
22234
22235      function tf(a, b) {
22236        var c = 8,
22237            d;
22238
22239        for (d = 0; 16 > d; ++d) {
22240          c += a[b + d - 32];
22241        }
22242
22243        $a(c >> 4, a, b);
22244      }
22245
22246      function uf(a, b) {
22247        $a(128, a, b);
22248      }
22249
22250      function z(a, b, c) {
22251        return a + 2 * b + c + 2 >> 2;
22252      }
22253
22254      function ff(a, b) {
22255        var c = b - 32,
22256            c = new Uint8Array([z(a[c - 1], a[c + 0], a[c + 1]), z(a[c + 0], a[c + 1], a[c + 2]), z(a[c + 1], a[c + 2], a[c + 3]), z(a[c + 2], a[c + 3], a[c + 4])]),
22257            d;
22258
22259        for (d = 0; 4 > d; ++d) {
22260          I(a, b + 32 * d, c, 0, c.length);
22261        }
22262      }
22263
22264      function gf(a, b) {
22265        var c = a[b - 1],
22266            d = a[b - 1 + 32],
22267            e = a[b - 1 + 64],
22268            f = a[b - 1 + 96];
22269        ra(a, b + 0, 16843009 * z(a[b - 1 - 32], c, d));
22270        ra(a, b + 32, 16843009 * z(c, d, e));
22271        ra(a, b + 64, 16843009 * z(d, e, f));
22272        ra(a, b + 96, 16843009 * z(e, f, f));
22273      }
22274
22275      function df(a, b) {
22276        var c = 4,
22277            d;
22278
22279        for (d = 0; 4 > d; ++d) {
22280          c += a[b + d - 32] + a[b - 1 + 32 * d];
22281        }
22282
22283        c >>= 3;
22284
22285        for (d = 0; 4 > d; ++d) {
22286          M(a, b + 32 * d, c, 4);
22287        }
22288      }
22289
22290      function hf(a, b) {
22291        var c = a[b - 1 + 0],
22292            d = a[b - 1 + 32],
22293            e = a[b - 1 + 64],
22294            f = a[b - 1 - 32],
22295            g = a[b + 0 - 32],
22296            h = a[b + 1 - 32],
22297            k = a[b + 2 - 32],
22298            l = a[b + 3 - 32];
22299        a[b + 0 + 96] = z(d, e, a[b - 1 + 96]);
22300        a[b + 1 + 96] = a[b + 0 + 64] = z(c, d, e);
22301        a[b + 2 + 96] = a[b + 1 + 64] = a[b + 0 + 32] = z(f, c, d);
22302        a[b + 3 + 96] = a[b + 2 + 64] = a[b + 1 + 32] = a[b + 0 + 0] = z(g, f, c);
22303        a[b + 3 + 64] = a[b + 2 + 32] = a[b + 1 + 0] = z(h, g, f);
22304        a[b + 3 + 32] = a[b + 2 + 0] = z(k, h, g);
22305        a[b + 3 + 0] = z(l, k, h);
22306      }
22307
22308      function kf(a, b) {
22309        var c = a[b + 1 - 32],
22310            d = a[b + 2 - 32],
22311            e = a[b + 3 - 32],
22312            f = a[b + 4 - 32],
22313            g = a[b + 5 - 32],
22314            h = a[b + 6 - 32],
22315            k = a[b + 7 - 32];
22316        a[b + 0 + 0] = z(a[b + 0 - 32], c, d);
22317        a[b + 1 + 0] = a[b + 0 + 32] = z(c, d, e);
22318        a[b + 2 + 0] = a[b + 1 + 32] = a[b + 0 + 64] = z(d, e, f);
22319        a[b + 3 + 0] = a[b + 2 + 32] = a[b + 1 + 64] = a[b + 0 + 96] = z(e, f, g);
22320        a[b + 3 + 32] = a[b + 2 + 64] = a[b + 1 + 96] = z(f, g, h);
22321        a[b + 3 + 64] = a[b + 2 + 96] = z(g, h, k);
22322        a[b + 3 + 96] = z(h, k, k);
22323      }
22324
22325      function jf(a, b) {
22326        var c = a[b - 1 + 0],
22327            d = a[b - 1 + 32],
22328            e = a[b - 1 + 64],
22329            f = a[b - 1 - 32],
22330            g = a[b + 0 - 32],
22331            h = a[b + 1 - 32],
22332            k = a[b + 2 - 32],
22333            l = a[b + 3 - 32];
22334        a[b + 0 + 0] = a[b + 1 + 64] = f + g + 1 >> 1;
22335        a[b + 1 + 0] = a[b + 2 + 64] = g + h + 1 >> 1;
22336        a[b + 2 + 0] = a[b + 3 + 64] = h + k + 1 >> 1;
22337        a[b + 3 + 0] = k + l + 1 >> 1;
22338        a[b + 0 + 96] = z(e, d, c);
22339        a[b + 0 + 64] = z(d, c, f);
22340        a[b + 0 + 32] = a[b + 1 + 96] = z(c, f, g);
22341        a[b + 1 + 32] = a[b + 2 + 96] = z(f, g, h);
22342        a[b + 2 + 32] = a[b + 3 + 96] = z(g, h, k);
22343        a[b + 3 + 32] = z(h, k, l);
22344      }
22345
22346      function lf(a, b) {
22347        var c = a[b + 0 - 32],
22348            d = a[b + 1 - 32],
22349            e = a[b + 2 - 32],
22350            f = a[b + 3 - 32],
22351            g = a[b + 4 - 32],
22352            h = a[b + 5 - 32],
22353            k = a[b + 6 - 32],
22354            l = a[b + 7 - 32];
22355        a[b + 0 + 0] = c + d + 1 >> 1;
22356        a[b + 1 + 0] = a[b + 0 + 64] = d + e + 1 >> 1;
22357        a[b + 2 + 0] = a[b + 1 + 64] = e + f + 1 >> 1;
22358        a[b + 3 + 0] = a[b + 2 + 64] = f + g + 1 >> 1;
22359        a[b + 0 + 32] = z(c, d, e);
22360        a[b + 1 + 32] = a[b + 0 + 96] = z(d, e, f);
22361        a[b + 2 + 32] = a[b + 1 + 96] = z(e, f, g);
22362        a[b + 3 + 32] = a[b + 2 + 96] = z(f, g, h);
22363        a[b + 3 + 64] = z(g, h, k);
22364        a[b + 3 + 96] = z(h, k, l);
22365      }
22366
22367      function nf(a, b) {
22368        var c = a[b - 1 + 0],
22369            d = a[b - 1 + 32],
22370            e = a[b - 1 + 64],
22371            f = a[b - 1 + 96];
22372        a[b + 0 + 0] = c + d + 1 >> 1;
22373        a[b + 2 + 0] = a[b + 0 + 32] = d + e + 1 >> 1;
22374        a[b + 2 + 32] = a[b + 0 + 64] = e + f + 1 >> 1;
22375        a[b + 1 + 0] = z(c, d, e);
22376        a[b + 3 + 0] = a[b + 1 + 32] = z(d, e, f);
22377        a[b + 3 + 32] = a[b + 1 + 64] = z(e, f, f);
22378        a[b + 3 + 64] = a[b + 2 + 64] = a[b + 0 + 96] = a[b + 1 + 96] = a[b + 2 + 96] = a[b + 3 + 96] = f;
22379      }
22380
22381      function mf(a, b) {
22382        var c = a[b - 1 + 0],
22383            d = a[b - 1 + 32],
22384            e = a[b - 1 + 64],
22385            f = a[b - 1 + 96],
22386            g = a[b - 1 - 32],
22387            h = a[b + 0 - 32],
22388            k = a[b + 1 - 32],
22389            l = a[b + 2 - 32];
22390        a[b + 0 + 0] = a[b + 2 + 32] = c + g + 1 >> 1;
22391        a[b + 0 + 32] = a[b + 2 + 64] = d + c + 1 >> 1;
22392        a[b + 0 + 64] = a[b + 2 + 96] = e + d + 1 >> 1;
22393        a[b + 0 + 96] = f + e + 1 >> 1;
22394        a[b + 3 + 0] = z(h, k, l);
22395        a[b + 2 + 0] = z(g, h, k);
22396        a[b + 1 + 0] = a[b + 3 + 32] = z(c, g, h);
22397        a[b + 1 + 32] = a[b + 3 + 64] = z(d, c, g);
22398        a[b + 1 + 64] = a[b + 3 + 96] = z(e, d, c);
22399        a[b + 1 + 96] = z(f, e, d);
22400      }
22401
22402      function xf(a, b) {
22403        var c;
22404
22405        for (c = 0; 8 > c; ++c) {
22406          I(a, b + 32 * c, a, b - 32, 8);
22407        }
22408      }
22409
22410      function yf(a, b) {
22411        var c;
22412
22413        for (c = 0; 8 > c; ++c) {
22414          M(a, b, a[b - 1], 8), b += 32;
22415        }
22416      }
22417
22418      function lb(a, b, c) {
22419        var d;
22420
22421        for (d = 0; 8 > d; ++d) {
22422          M(b, c + 32 * d, a, 8);
22423        }
22424      }
22425
22426      function vf(a, b) {
22427        var c = 8,
22428            d;
22429
22430        for (d = 0; 8 > d; ++d) {
22431          c += a[b + d - 32] + a[b - 1 + 32 * d];
22432        }
22433
22434        lb(c >> 4, a, b);
22435      }
22436
22437      function Af(a, b) {
22438        var c = 4,
22439            d;
22440
22441        for (d = 0; 8 > d; ++d) {
22442          c += a[b + d - 32];
22443        }
22444
22445        lb(c >> 3, a, b);
22446      }
22447
22448      function zf(a, b) {
22449        var c = 4,
22450            d;
22451
22452        for (d = 0; 8 > d; ++d) {
22453          c += a[b - 1 + 32 * d];
22454        }
22455
22456        lb(c >> 3, a, b);
22457      }
22458
22459      function Bf(a, b) {
22460        lb(128, a, b);
22461      }
22462
22463      function ab(a, b, c) {
22464        var d = a[b - c],
22465            e = a[b + 0],
22466            f = 3 * (e - d) + Qb[1020 + a[b - 2 * c] - a[b + c]],
22467            g = mb[112 + (f + 4 >> 3)];
22468        a[b - c] = R[255 + d + mb[112 + (f + 3 >> 3)]];
22469        a[b + 0] = R[255 + e - g];
22470      }
22471
22472      function jd(a, b, c, d) {
22473        var e = a[b + 0],
22474            f = a[b + c];
22475        return U[255 + a[b - 2 * c] - a[b - c]] > d || U[255 + f - e] > d;
22476      }
22477
22478      function kd(a, b, c, d) {
22479        return 4 * U[255 + a[b - c] - a[b + 0]] + U[255 + a[b - 2 * c] - a[b + c]] <= d;
22480      }
22481
22482      function ld(a, b, c, d, e) {
22483        var f = a[b - 3 * c],
22484            g = a[b - 2 * c],
22485            h = a[b - c],
22486            k = a[b + 0],
22487            l = a[b + c],
22488            m = a[b + 2 * c],
22489            n = a[b + 3 * c];
22490        return 4 * U[255 + h - k] + U[255 + g - l] > d ? 0 : U[255 + a[b - 4 * c] - f] <= e && U[255 + f - g] <= e && U[255 + g - h] <= e && U[255 + n - m] <= e && U[255 + m - l] <= e && U[255 + l - k] <= e;
22491      }
22492
22493      function gd(a, b, c, d) {
22494        var e = 2 * d + 1;
22495
22496        for (d = 0; 16 > d; ++d) {
22497          kd(a, b + d, c, e) && ab(a, b + d, c);
22498        }
22499      }
22500
22501      function hd(a, b, c, d) {
22502        var e = 2 * d + 1;
22503
22504        for (d = 0; 16 > d; ++d) {
22505          kd(a, b + d * c, 1, e) && ab(a, b + d * c, 1);
22506        }
22507      }
22508
22509      function bf(a, b, c, d) {
22510        var e;
22511
22512        for (e = 3; 0 < e; --e) {
22513          b += 4 * c, gd(a, b, c, d);
22514        }
22515      }
22516
22517      function cf(a, b, c, d) {
22518        var e;
22519
22520        for (e = 3; 0 < e; --e) {
22521          b += 4, hd(a, b, c, d);
22522        }
22523      }
22524
22525      function ea(a, b, c, d, e, f, g, h) {
22526        for (f = 2 * f + 1; 0 < e--;) {
22527          if (ld(a, b, c, f, g)) if (jd(a, b, c, h)) ab(a, b, c);else {
22528            var k = a,
22529                l = b,
22530                m = c,
22531                n = k[l - 2 * m],
22532                r = k[l - m],
22533                q = k[l + 0],
22534                t = k[l + m],
22535                v = k[l + 2 * m],
22536                p = Qb[1020 + 3 * (q - r) + Qb[1020 + n - t]],
22537                u = 27 * p + 63 >> 7,
22538                w = 18 * p + 63 >> 7,
22539                p = 9 * p + 63 >> 7;
22540            k[l - 3 * m] = R[255 + k[l - 3 * m] + p];
22541            k[l - 2 * m] = R[255 + n + w];
22542            k[l - m] = R[255 + r + u];
22543            k[l + 0] = R[255 + q - u];
22544            k[l + m] = R[255 + t - w];
22545            k[l + 2 * m] = R[255 + v - p];
22546          }
22547          b += d;
22548        }
22549      }
22550
22551      function Fa(a, b, c, d, e, f, g, h) {
22552        for (f = 2 * f + 1; 0 < e--;) {
22553          if (ld(a, b, c, f, g)) if (jd(a, b, c, h)) ab(a, b, c);else {
22554            var k = a,
22555                l = b,
22556                m = c,
22557                n = k[l - m],
22558                r = k[l + 0],
22559                q = k[l + m],
22560                t = 3 * (r - n),
22561                v = mb[112 + (t + 4 >> 3)],
22562                t = mb[112 + (t + 3 >> 3)],
22563                p = v + 1 >> 1;
22564            k[l - 2 * m] = R[255 + k[l - 2 * m] + p];
22565            k[l - m] = R[255 + n + t];
22566            k[l + 0] = R[255 + r - v];
22567            k[l + m] = R[255 + q - p];
22568          }
22569          b += d;
22570        }
22571      }
22572
22573      function Ue(a, b, c, d, e, f) {
22574        ea(a, b, c, 1, 16, d, e, f);
22575      }
22576
22577      function Ve(a, b, c, d, e, f) {
22578        ea(a, b, 1, c, 16, d, e, f);
22579      }
22580
22581      function Ye(a, b, c, d, e, f) {
22582        var g;
22583
22584        for (g = 3; 0 < g; --g) {
22585          b += 4 * c, Fa(a, b, c, 1, 16, d, e, f);
22586        }
22587      }
22588
22589      function Ze(a, b, c, d, e, f) {
22590        var g;
22591
22592        for (g = 3; 0 < g; --g) {
22593          b += 4, Fa(a, b, 1, c, 16, d, e, f);
22594        }
22595      }
22596
22597      function We(a, b, c, d, e, f, g, h) {
22598        ea(a, b, e, 1, 8, f, g, h);
22599        ea(c, d, e, 1, 8, f, g, h);
22600      }
22601
22602      function Xe(a, b, c, d, e, f, g, h) {
22603        ea(a, b, 1, e, 8, f, g, h);
22604        ea(c, d, 1, e, 8, f, g, h);
22605      }
22606
22607      function $e(a, b, c, d, e, f, g, h) {
22608        Fa(a, b + 4 * e, e, 1, 8, f, g, h);
22609        Fa(c, d + 4 * e, e, 1, 8, f, g, h);
22610      }
22611
22612      function af(a, b, c, d, e, f, g, h) {
22613        Fa(a, b + 4, 1, e, 8, f, g, h);
22614        Fa(c, d + 4, 1, e, 8, f, g, h);
22615      }
22616
22617      function Cf() {
22618        this.ba = new Cb();
22619        this.ec = [];
22620        this.cc = [];
22621        this.Mc = [];
22622        this.Dc = this.Nc = this.dc = this.fc = 0;
22623        this.Oa = new Ud();
22624        this.memory = 0;
22625        this.Ib = "OutputFunc";
22626        this.Jb = "OutputAlphaFunc";
22627        this.Nd = "OutputRowFunc";
22628      }
22629
22630      function md() {
22631        this.data = [];
22632        this.offset = this.kd = this.ha = this.w = 0;
22633        this.na = [];
22634        this.xa = this.gb = this.Ja = this.Sa = this.P = 0;
22635      }
22636
22637      function Df() {
22638        this.nc = this.Ea = this.b = this.hc = 0;
22639        this.K = [];
22640        this.w = 0;
22641      }
22642
22643      function Ef() {
22644        this.ua = 0;
22645        this.Wa = new ac();
22646        this.vb = new ac();
22647        this.md = this.xc = this.wc = 0;
22648        this.vc = [];
22649        this.Wb = 0;
22650        this.Ya = new Ub();
22651        this.yc = new O();
22652      }
22653
22654      function je() {
22655        this.xb = this.a = 0;
22656        this.l = new Oa();
22657        this.ca = new Cb();
22658        this.V = [];
22659        this.Ba = 0;
22660        this.Ta = [];
22661        this.Ua = 0;
22662        this.m = new Ra();
22663        this.Pb = 0;
22664        this.wd = new Ra();
22665        this.Ma = this.$ = this.C = this.i = this.c = this.xd = 0;
22666        this.s = new Ef();
22667        this.ab = 0;
22668        this.gc = wa(4, Df);
22669        this.Oc = 0;
22670      }
22671
22672      function Ff() {
22673        this.Lc = this.Z = this.$a = this.i = this.c = 0;
22674        this.l = new Oa();
22675        this.ic = 0;
22676        this.ca = [];
22677        this.tb = 0;
22678        this.qd = null;
22679        this.rd = 0;
22680      }
22681
22682      function Rb(a, b, c, d, e, f, g) {
22683        a = null == a ? 0 : a[b + 0];
22684
22685        for (b = 0; b < g; ++b) {
22686          e[f + b] = a + c[d + b] & 255, a = e[f + b];
22687        }
22688      }
22689
22690      function Gf(a, b, c, d, e, f, g) {
22691        if (null == a) Rb(null, null, c, d, e, f, g);else {
22692          var h;
22693
22694          for (h = 0; h < g; ++h) {
22695            e[f + h] = a[b + h] + c[d + h] & 255;
22696          }
22697        }
22698      }
22699
22700      function Hf(a, b, c, d, e, f, g) {
22701        if (null == a) Rb(null, null, c, d, e, f, g);else {
22702          var h = a[b + 0],
22703              k = h,
22704              l = h,
22705              m;
22706
22707          for (m = 0; m < g; ++m) {
22708            h = a[b + m], k = l + h - k, l = c[d + m] + (k & -256 ? 0 > k ? 0 : 255 : k) & 255, k = h, e[f + m] = l;
22709          }
22710        }
22711      }
22712
22713      function Le(a, b, c, d) {
22714        var e = b.width,
22715            f = b.o;
22716        x(null != a && null != b);
22717        if (0 > c || 0 >= d || c + d > f) return null;
22718
22719        if (!a.Cc) {
22720          if (null == a.ga) {
22721            a.ga = new Ff();
22722            var g;
22723            (g = null == a.ga) || (g = b.width * b.o, x(0 == a.Gb.length), a.Gb = V(g), a.Uc = 0, null == a.Gb ? g = 0 : (a.mb = a.Gb, a.nb = a.Uc, a.rc = null, g = 1), g = !g);
22724
22725            if (!g) {
22726              g = a.ga;
22727              var h = a.Fa,
22728                  k = a.P,
22729                  l = a.qc,
22730                  m = a.mb,
22731                  n = a.nb,
22732                  r = k + 1,
22733                  q = l - 1,
22734                  t = g.l;
22735              x(null != h && null != m && null != b);
22736              ia[0] = null;
22737              ia[1] = Rb;
22738              ia[2] = Gf;
22739              ia[3] = Hf;
22740              g.ca = m;
22741              g.tb = n;
22742              g.c = b.width;
22743              g.i = b.height;
22744              x(0 < g.c && 0 < g.i);
22745              if (1 >= l) b = 0;else if (g.$a = h[k + 0] >> 0 & 3, g.Z = h[k + 0] >> 2 & 3, g.Lc = h[k + 0] >> 4 & 3, k = h[k + 0] >> 6 & 3, 0 > g.$a || 1 < g.$a || 4 <= g.Z || 1 < g.Lc || k) b = 0;else if (t.put = kc, t.ac = gc, t.bc = lc, t.ma = g, t.width = b.width, t.height = b.height, t.Da = b.Da, t.v = b.v, t.va = b.va, t.j = b.j, t.o = b.o, g.$a) b: {
22746                x(1 == g.$a), b = Bc();
22747
22748                c: for (;;) {
22749                  if (null == b) {
22750                    b = 0;
22751                    break b;
22752                  }
22753
22754                  x(null != g);
22755                  g.mc = b;
22756                  b.c = g.c;
22757                  b.i = g.i;
22758                  b.l = g.l;
22759                  b.l.ma = g;
22760                  b.l.width = g.c;
22761                  b.l.height = g.i;
22762                  b.a = 0;
22763                  cb(b.m, h, r, q);
22764                  if (!rb(g.c, g.i, 1, b, null)) break c;
22765                  1 == b.ab && 3 == b.gc[0].hc && yc(b.s) ? (g.ic = 1, h = b.c * b.i, b.Ta = null, b.Ua = 0, b.V = V(h), b.Ba = 0, null == b.V ? (b.a = 1, b = 0) : b = 1) : (g.ic = 0, b = Ec(b, g.c));
22766                  if (!b) break c;
22767                  b = 1;
22768                  break b;
22769                }
22770
22771                g.mc = null;
22772                b = 0;
22773              } else b = q >= g.c * g.i;
22774              g = !b;
22775            }
22776
22777            if (g) return null;
22778            1 != a.ga.Lc ? a.Ga = 0 : d = f - c;
22779          }
22780
22781          x(null != a.ga);
22782          x(c + d <= f);
22783
22784          a: {
22785            h = a.ga;
22786            b = h.c;
22787            f = h.l.o;
22788
22789            if (0 == h.$a) {
22790              r = a.rc;
22791              q = a.Vc;
22792              t = a.Fa;
22793              k = a.P + 1 + c * b;
22794              l = a.mb;
22795              m = a.nb + c * b;
22796              x(k <= a.P + a.qc);
22797              if (0 != h.Z) for (x(null != ia[h.Z]), g = 0; g < d; ++g) {
22798                ia[h.Z](r, q, t, k, l, m, b), r = l, q = m, m += b, k += b;
22799              } else for (g = 0; g < d; ++g) {
22800                I(l, m, t, k, b), r = l, q = m, m += b, k += b;
22801              }
22802              a.rc = r;
22803              a.Vc = q;
22804            } else {
22805              x(null != h.mc);
22806              b = c + d;
22807              g = h.mc;
22808              x(null != g);
22809              x(b <= g.i);
22810              if (g.C >= b) b = 1;else if (h.ic || Aa(), h.ic) {
22811                var h = g.V,
22812                    r = g.Ba,
22813                    q = g.c,
22814                    v = g.i,
22815                    t = 1,
22816                    k = g.$ / q,
22817                    l = g.$ % q,
22818                    m = g.m,
22819                    n = g.s,
22820                    p = g.$,
22821                    u = q * v,
22822                    w = q * b,
22823                    y = n.wc,
22824                    A = p < w ? ha(n, l, k) : null;
22825                x(p <= u);
22826                x(b <= v);
22827                x(yc(n));
22828
22829                c: for (;;) {
22830                  for (; !m.h && p < w;) {
22831                    l & y || (A = ha(n, l, k));
22832                    x(null != A);
22833                    Sa(m);
22834                    v = ua(A.G[0], A.H[0], m);
22835                    if (256 > v) h[r + p] = v, ++p, ++l, l >= q && (l = 0, ++k, k <= b && !(k % 16) && Ib(g, k));else if (280 > v) {
22836                      var v = ib(v - 256, m);
22837                      var E = ua(A.G[4], A.H[4], m);
22838                      Sa(m);
22839                      E = ib(E, m);
22840                      E = nc(q, E);
22841
22842                      if (p >= E && u - p >= v) {
22843                        var B;
22844
22845                        for (B = 0; B < v; ++B) {
22846                          h[r + p + B] = h[r + p + B - E];
22847                        }
22848                      } else {
22849                        t = 0;
22850                        break c;
22851                      }
22852
22853                      p += v;
22854
22855                      for (l += v; l >= q;) {
22856                        l -= q, ++k, k <= b && !(k % 16) && Ib(g, k);
22857                      }
22858
22859                      p < w && l & y && (A = ha(n, l, k));
22860                    } else {
22861                      t = 0;
22862                      break c;
22863                    }
22864                    x(m.h == db(m));
22865                  }
22866
22867                  Ib(g, k > b ? b : k);
22868                  break c;
22869                }
22870
22871                !t || m.h && p < u ? (t = 0, g.a = m.h ? 5 : 3) : g.$ = p;
22872                b = t;
22873              } else b = Jb(g, g.V, g.Ba, g.c, g.i, b, se);
22874
22875              if (!b) {
22876                d = 0;
22877                break a;
22878              }
22879            }
22880
22881            c + d >= f && (a.Cc = 1);
22882            d = 1;
22883          }
22884
22885          if (!d) return null;
22886          if (a.Cc && (d = a.ga, null != d && (d.mc = null), a.ga = null, 0 < a.Ga)) return alert("todo:WebPDequantizeLevels"), null;
22887        }
22888
22889        return a.nb + c * e;
22890      }
22891
22892      function If(a, b, c, d, e, f) {
22893        for (; 0 < e--;) {
22894          var g = a,
22895              h = b + (c ? 1 : 0),
22896              k = a,
22897              l = b + (c ? 0 : 3),
22898              m;
22899
22900          for (m = 0; m < d; ++m) {
22901            var n = k[l + 4 * m];
22902            255 != n && (n *= 32897, g[h + 4 * m + 0] = g[h + 4 * m + 0] * n >> 23, g[h + 4 * m + 1] = g[h + 4 * m + 1] * n >> 23, g[h + 4 * m + 2] = g[h + 4 * m + 2] * n >> 23);
22903          }
22904
22905          b += f;
22906        }
22907      }
22908
22909      function Jf(a, b, c, d, e) {
22910        for (; 0 < d--;) {
22911          var f;
22912
22913          for (f = 0; f < c; ++f) {
22914            var g = a[b + 2 * f + 0],
22915                h = a[b + 2 * f + 1],
22916                k = h & 15,
22917                l = 4369 * k,
22918                h = (h & 240 | h >> 4) * l >> 16;
22919            a[b + 2 * f + 0] = (g & 240 | g >> 4) * l >> 16 & 240 | (g & 15 | g << 4) * l >> 16 >> 4 & 15;
22920            a[b + 2 * f + 1] = h & 240 | k;
22921          }
22922
22923          b += e;
22924        }
22925      }
22926
22927      function Kf(a, b, c, d, e, f, g, h) {
22928        var k = 255,
22929            l,
22930            m;
22931
22932        for (m = 0; m < e; ++m) {
22933          for (l = 0; l < d; ++l) {
22934            var n = a[b + l];
22935            f[g + 4 * l] = n;
22936            k &= n;
22937          }
22938
22939          b += c;
22940          g += h;
22941        }
22942
22943        return 255 != k;
22944      }
22945
22946      function Lf(a, b, c, d, e) {
22947        var f;
22948
22949        for (f = 0; f < e; ++f) {
22950          c[d + f] = a[b + f] >> 8;
22951        }
22952      }
22953
22954      function Aa() {
22955        za = If;
22956        vc = Jf;
22957        fc = Kf;
22958        Fc = Lf;
22959      }
22960
22961      function va(a, b, c) {
22962        self[a] = function (a, e, f, g, h, k, l, m, n, r, q, t, v, p, u, w, y) {
22963          var d,
22964              E = y - 1 >> 1;
22965          var B = h[k + 0] | l[m + 0] << 16;
22966          var C = n[r + 0] | q[t + 0] << 16;
22967          x(null != a);
22968          var z = 3 * B + C + 131074 >> 2;
22969          b(a[e + 0], z & 255, z >> 16, v, p);
22970          null != f && (z = 3 * C + B + 131074 >> 2, b(f[g + 0], z & 255, z >> 16, u, w));
22971
22972          for (d = 1; d <= E; ++d) {
22973            var D = h[k + d] | l[m + d] << 16;
22974            var G = n[r + d] | q[t + d] << 16;
22975            var F = B + D + C + G + 524296;
22976            var H = F + 2 * (D + C) >> 3;
22977            F = F + 2 * (B + G) >> 3;
22978            z = H + B >> 1;
22979            B = F + D >> 1;
22980            b(a[e + 2 * d - 1], z & 255, z >> 16, v, p + (2 * d - 1) * c);
22981            b(a[e + 2 * d - 0], B & 255, B >> 16, v, p + (2 * d - 0) * c);
22982            null != f && (z = F + C >> 1, B = H + G >> 1, b(f[g + 2 * d - 1], z & 255, z >> 16, u, w + (2 * d - 1) * c), b(f[g + 2 * d + 0], B & 255, B >> 16, u, w + (2 * d + 0) * c));
22983            B = D;
22984            C = G;
22985          }
22986
22987          y & 1 || (z = 3 * B + C + 131074 >> 2, b(a[e + y - 1], z & 255, z >> 16, v, p + (y - 1) * c), null != f && (z = 3 * C + B + 131074 >> 2, b(f[g + y - 1], z & 255, z >> 16, u, w + (y - 1) * c)));
22988        };
22989      }
22990
22991      function ic() {
22992        P[Ca] = Mf;
22993        P[Ua] = nd;
22994        P[tc] = Nf;
22995        P[Va] = od;
22996        P[ya] = pd;
22997        P[Db] = qd;
22998        P[wc] = Of;
22999        P[zb] = nd;
23000        P[Ab] = od;
23001        P[Ja] = pd;
23002        P[Bb] = qd;
23003      }
23004
23005      function Sb(a) {
23006        return a & ~Pf ? 0 > a ? 0 : 255 : a >> rd;
23007      }
23008
23009      function bb(a, b) {
23010        return Sb((19077 * a >> 8) + (26149 * b >> 8) - 14234);
23011      }
23012
23013      function nb(a, b, c) {
23014        return Sb((19077 * a >> 8) - (6419 * b >> 8) - (13320 * c >> 8) + 8708);
23015      }
23016
23017      function Pa(a, b) {
23018        return Sb((19077 * a >> 8) + (33050 * b >> 8) - 17685);
23019      }
23020
23021      function Ga(a, b, c, d, e) {
23022        d[e + 0] = bb(a, c);
23023        d[e + 1] = nb(a, b, c);
23024        d[e + 2] = Pa(a, b);
23025      }
23026
23027      function Tb(a, b, c, d, e) {
23028        d[e + 0] = Pa(a, b);
23029        d[e + 1] = nb(a, b, c);
23030        d[e + 2] = bb(a, c);
23031      }
23032
23033      function sd(a, b, c, d, e) {
23034        var f = nb(a, b, c);
23035        b = f << 3 & 224 | Pa(a, b) >> 3;
23036        d[e + 0] = bb(a, c) & 248 | f >> 5;
23037        d[e + 1] = b;
23038      }
23039
23040      function td(a, b, c, d, e) {
23041        var f = Pa(a, b) & 240 | 15;
23042        d[e + 0] = bb(a, c) & 240 | nb(a, b, c) >> 4;
23043        d[e + 1] = f;
23044      }
23045
23046      function ud(a, b, c, d, e) {
23047        d[e + 0] = 255;
23048        Ga(a, b, c, d, e + 1);
23049      }
23050
23051      function vd(a, b, c, d, e) {
23052        Tb(a, b, c, d, e);
23053        d[e + 3] = 255;
23054      }
23055
23056      function wd(a, b, c, d, e) {
23057        Ga(a, b, c, d, e);
23058        d[e + 3] = 255;
23059      }
23060
23061      function ga(a, b) {
23062        return 0 > a ? 0 : a > b ? b : a;
23063      }
23064
23065      function la(a, b, c) {
23066        self[a] = function (a, e, f, g, h, k, l, m, n) {
23067          for (var d = m + (n & -2) * c; m != d;) {
23068            b(a[e + 0], f[g + 0], h[k + 0], l, m), b(a[e + 1], f[g + 0], h[k + 0], l, m + c), e += 2, ++g, ++k, m += 2 * c;
23069          }
23070
23071          n & 1 && b(a[e + 0], f[g + 0], h[k + 0], l, m);
23072        };
23073      }
23074
23075      function xd(a, b, c) {
23076        return 0 == c ? 0 == a ? 0 == b ? 6 : 5 : 0 == b ? 4 : 0 : c;
23077      }
23078
23079      function yd(a, b, c, d, e) {
23080        switch (a >>> 30) {
23081          case 3:
23082            Za(b, c, d, e, 0);
23083            break;
23084
23085          case 2:
23086            fd(b, c, d, e);
23087            break;
23088
23089          case 1:
23090            pa(b, c, d, e);
23091        }
23092      }
23093
23094      function Oc(a, b) {
23095        var c,
23096            d,
23097            e = b.M,
23098            f = b.Nb,
23099            g = a.oc,
23100            h = a.pc + 40,
23101            k = a.oc,
23102            l = a.pc + 584,
23103            m = a.oc,
23104            n = a.pc + 600;
23105
23106        for (c = 0; 16 > c; ++c) {
23107          g[h + 32 * c - 1] = 129;
23108        }
23109
23110        for (c = 0; 8 > c; ++c) {
23111          k[l + 32 * c - 1] = 129, m[n + 32 * c - 1] = 129;
23112        }
23113
23114        0 < e ? g[h - 1 - 32] = k[l - 1 - 32] = m[n - 1 - 32] = 129 : (M(g, h - 32 - 1, 127, 21), M(k, l - 32 - 1, 127, 9), M(m, n - 32 - 1, 127, 9));
23115
23116        for (d = 0; d < a.za; ++d) {
23117          var r = b.ya[b.aa + d];
23118
23119          if (0 < d) {
23120            for (c = -1; 16 > c; ++c) {
23121              I(g, h + 32 * c - 4, g, h + 32 * c + 12, 4);
23122            }
23123
23124            for (c = -1; 8 > c; ++c) {
23125              I(k, l + 32 * c - 4, k, l + 32 * c + 4, 4), I(m, n + 32 * c - 4, m, n + 32 * c + 4, 4);
23126            }
23127          }
23128
23129          var q = a.Gd,
23130              t = a.Hd + d,
23131              v = r.ad,
23132              p = r.Hc;
23133          0 < e && (I(g, h - 32, q[t].y, 0, 16), I(k, l - 32, q[t].f, 0, 8), I(m, n - 32, q[t].ea, 0, 8));
23134
23135          if (r.Za) {
23136            var u = g;
23137            var w = h - 32 + 16;
23138            0 < e && (d >= a.za - 1 ? M(u, w, q[t].y[15], 4) : I(u, w, q[t + 1].y, 0, 4));
23139
23140            for (c = 0; 4 > c; c++) {
23141              u[w + 128 + c] = u[w + 256 + c] = u[w + 384 + c] = u[w + 0 + c];
23142            }
23143
23144            for (c = 0; 16 > c; ++c, p <<= 2) {
23145              u = g, w = h + zd[c], W[r.Ob[c]](u, w), yd(p, v, 16 * +c, u, w);
23146            }
23147          } else if (u = xd(d, e, r.Ob[0]), Y[u](g, h), 0 != p) for (c = 0; 16 > c; ++c, p <<= 2) {
23148            yd(p, v, 16 * +c, g, h + zd[c]);
23149          }
23150
23151          c = r.Gc;
23152          u = xd(d, e, r.Dd);
23153          ka[u](k, l);
23154          ka[u](m, n);
23155          r = c >> 0;
23156          p = v;
23157          u = k;
23158          w = l;
23159          r & 255 && (r & 170 ? Nb(p, 256, u, w) : Ob(p, 256, u, w));
23160          c >>= 8;
23161          r = m;
23162          p = n;
23163          c & 255 && (c & 170 ? Nb(v, 320, r, p) : Ob(v, 320, r, p));
23164          e < a.Ub - 1 && (I(q[t].y, 0, g, h + 480, 16), I(q[t].f, 0, k, l + 224, 8), I(q[t].ea, 0, m, n + 224, 8));
23165          c = 8 * f * a.B;
23166          q = a.sa;
23167          t = a.ta + 16 * d + 16 * f * a.R;
23168          v = a.qa;
23169          r = a.ra + 8 * d + c;
23170          p = a.Ha;
23171          u = a.Ia + 8 * d + c;
23172
23173          for (c = 0; 16 > c; ++c) {
23174            I(q, t + c * a.R, g, h + 32 * c, 16);
23175          }
23176
23177          for (c = 0; 8 > c; ++c) {
23178            I(v, r + c * a.B, k, l + 32 * c, 8), I(p, u + c * a.B, m, n + 32 * c, 8);
23179          }
23180        }
23181      }
23182
23183      function Ad(a, b, c, d, e, f, g, h, k) {
23184        var l = [0],
23185            m = [0],
23186            n = 0,
23187            r = null != k ? k.kd : 0,
23188            q = null != k ? k : new md();
23189        if (null == a || 12 > c) return 7;
23190        q.data = a;
23191        q.w = b;
23192        q.ha = c;
23193        b = [b];
23194        c = [c];
23195        q.gb = [q.gb];
23196
23197        a: {
23198          var t = b;
23199          var v = c;
23200          var p = q.gb;
23201          x(null != a);
23202          x(null != v);
23203          x(null != p);
23204          p[0] = 0;
23205
23206          if (12 <= v[0] && !fa(a, t[0], "RIFF")) {
23207            if (fa(a, t[0] + 8, "WEBP")) {
23208              p = 3;
23209              break a;
23210            }
23211
23212            var u = Ha(a, t[0] + 4);
23213
23214            if (12 > u || 4294967286 < u) {
23215              p = 3;
23216              break a;
23217            }
23218
23219            if (r && u > v[0] - 8) {
23220              p = 7;
23221              break a;
23222            }
23223
23224            p[0] = u;
23225            t[0] += 12;
23226            v[0] -= 12;
23227          }
23228
23229          p = 0;
23230        }
23231
23232        if (0 != p) return p;
23233        u = 0 < q.gb[0];
23234
23235        for (c = c[0];;) {
23236          t = [0];
23237          n = [n];
23238
23239          a: {
23240            var w = a;
23241            v = b;
23242            p = c;
23243            var y = n,
23244                A = l,
23245                z = m,
23246                B = t;
23247            y[0] = 0;
23248            if (8 > p[0]) p = 7;else {
23249              if (!fa(w, v[0], "VP8X")) {
23250                if (10 != Ha(w, v[0] + 4)) {
23251                  p = 3;
23252                  break a;
23253                }
23254
23255                if (18 > p[0]) {
23256                  p = 7;
23257                  break a;
23258                }
23259
23260                var C = Ha(w, v[0] + 8);
23261                var D = 1 + Yb(w, v[0] + 12);
23262                w = 1 + Yb(w, v[0] + 15);
23263
23264                if (2147483648 <= D * w) {
23265                  p = 3;
23266                  break a;
23267                }
23268
23269                null != B && (B[0] = C);
23270                null != A && (A[0] = D);
23271                null != z && (z[0] = w);
23272                v[0] += 18;
23273                p[0] -= 18;
23274                y[0] = 1;
23275              }
23276
23277              p = 0;
23278            }
23279          }
23280
23281          n = n[0];
23282          t = t[0];
23283          if (0 != p) return p;
23284          v = !!(t & 2);
23285          if (!u && n) return 3;
23286          null != f && (f[0] = !!(t & 16));
23287          null != g && (g[0] = v);
23288          null != h && (h[0] = 0);
23289          g = l[0];
23290          t = m[0];
23291
23292          if (n && v && null == k) {
23293            p = 0;
23294            break;
23295          }
23296
23297          if (4 > c) {
23298            p = 7;
23299            break;
23300          }
23301
23302          if (u && n || !u && !n && !fa(a, b[0], "ALPH")) {
23303            c = [c];
23304            q.na = [q.na];
23305            q.P = [q.P];
23306            q.Sa = [q.Sa];
23307
23308            a: {
23309              C = a;
23310              p = b;
23311              u = c;
23312              var y = q.gb,
23313                  A = q.na,
23314                  z = q.P,
23315                  B = q.Sa;
23316              D = 22;
23317              x(null != C);
23318              x(null != u);
23319              w = p[0];
23320              var F = u[0];
23321              x(null != A);
23322              x(null != B);
23323              A[0] = null;
23324              z[0] = null;
23325
23326              for (B[0] = 0;;) {
23327                p[0] = w;
23328                u[0] = F;
23329
23330                if (8 > F) {
23331                  p = 7;
23332                  break a;
23333                }
23334
23335                var G = Ha(C, w + 4);
23336
23337                if (4294967286 < G) {
23338                  p = 3;
23339                  break a;
23340                }
23341
23342                var H = 8 + G + 1 & -2;
23343                D += H;
23344
23345                if (0 < y && D > y) {
23346                  p = 3;
23347                  break a;
23348                }
23349
23350                if (!fa(C, w, "VP8 ") || !fa(C, w, "VP8L")) {
23351                  p = 0;
23352                  break a;
23353                }
23354
23355                if (F[0] < H) {
23356                  p = 7;
23357                  break a;
23358                }
23359
23360                fa(C, w, "ALPH") || (A[0] = C, z[0] = w + 8, B[0] = G);
23361                w += H;
23362                F -= H;
23363              }
23364            }
23365
23366            c = c[0];
23367            q.na = q.na[0];
23368            q.P = q.P[0];
23369            q.Sa = q.Sa[0];
23370            if (0 != p) break;
23371          }
23372
23373          c = [c];
23374          q.Ja = [q.Ja];
23375          q.xa = [q.xa];
23376
23377          a: if (y = a, p = b, u = c, A = q.gb[0], z = q.Ja, B = q.xa, C = p[0], w = !fa(y, C, "VP8 "), D = !fa(y, C, "VP8L"), x(null != y), x(null != u), x(null != z), x(null != B), 8 > u[0]) p = 7;else {
23378            if (w || D) {
23379              y = Ha(y, C + 4);
23380
23381              if (12 <= A && y > A - 12) {
23382                p = 3;
23383                break a;
23384              }
23385
23386              if (r && y > u[0] - 8) {
23387                p = 7;
23388                break a;
23389              }
23390
23391              z[0] = y;
23392              p[0] += 8;
23393              u[0] -= 8;
23394              B[0] = D;
23395            } else B[0] = 5 <= u[0] && 47 == y[C + 0] && !(y[C + 4] >> 5), z[0] = u[0];
23396
23397            p = 0;
23398          }
23399
23400          c = c[0];
23401          q.Ja = q.Ja[0];
23402          q.xa = q.xa[0];
23403          b = b[0];
23404          if (0 != p) break;
23405          if (4294967286 < q.Ja) return 3;
23406          null == h || v || (h[0] = q.xa ? 2 : 1);
23407          g = [g];
23408          t = [t];
23409
23410          if (q.xa) {
23411            if (5 > c) {
23412              p = 7;
23413              break;
23414            }
23415
23416            h = g;
23417            r = t;
23418            v = f;
23419            null == a || 5 > c ? a = 0 : 5 <= c && 47 == a[b + 0] && !(a[b + 4] >> 5) ? (u = [0], y = [0], A = [0], z = new Ra(), cb(z, a, b, c), mc(z, u, y, A) ? (null != h && (h[0] = u[0]), null != r && (r[0] = y[0]), null != v && (v[0] = A[0]), a = 1) : a = 0) : a = 0;
23420          } else {
23421            if (10 > c) {
23422              p = 7;
23423              break;
23424            }
23425
23426            h = t;
23427            null == a || 10 > c || !Jc(a, b + 3, c - 3) ? a = 0 : (r = a[b + 0] | a[b + 1] << 8 | a[b + 2] << 16, v = (a[b + 7] << 8 | a[b + 6]) & 16383, a = (a[b + 9] << 8 | a[b + 8]) & 16383, r & 1 || 3 < (r >> 1 & 7) || !(r >> 4 & 1) || r >> 5 >= q.Ja || !v || !a ? a = 0 : (g && (g[0] = v), h && (h[0] = a), a = 1));
23428          }
23429
23430          if (!a) return 3;
23431          g = g[0];
23432          t = t[0];
23433          if (n && (l[0] != g || m[0] != t)) return 3;
23434          null != k && (k[0] = q, k.offset = b - k.w, x(4294967286 > b - k.w), x(k.offset == k.ha - c));
23435          break;
23436        }
23437
23438        return 0 == p || 7 == p && n && null == k ? (null != f && (f[0] |= null != q.na && 0 < q.na.length), null != d && (d[0] = g), null != e && (e[0] = t), 0) : p;
23439      }
23440
23441      function hc(a, b, c) {
23442        var d = b.width,
23443            e = b.height,
23444            f = 0,
23445            g = 0,
23446            h = d,
23447            k = e;
23448        b.Da = null != a && 0 < a.Da;
23449        if (b.Da && (h = a.cd, k = a.bd, f = a.v, g = a.j, 11 > c || (f &= -2, g &= -2), 0 > f || 0 > g || 0 >= h || 0 >= k || f + h > d || g + k > e)) return 0;
23450        b.v = f;
23451        b.j = g;
23452        b.va = f + h;
23453        b.o = g + k;
23454        b.U = h;
23455        b.T = k;
23456        b.da = null != a && 0 < a.da;
23457
23458        if (b.da) {
23459          c = [a.ib];
23460          f = [a.hb];
23461          if (!bc(h, k, c, f)) return 0;
23462          b.ib = c[0];
23463          b.hb = f[0];
23464        }
23465
23466        b.ob = null != a && a.ob;
23467        b.Kb = null == a || !a.Sd;
23468        b.da && (b.ob = b.ib < 3 * d / 4 && b.hb < 3 * e / 4, b.Kb = 0);
23469        return 1;
23470      }
23471
23472      function Bd(a) {
23473        if (null == a) return 2;
23474
23475        if (11 > a.S) {
23476          var b = a.f.RGBA;
23477          b.fb += (a.height - 1) * b.A;
23478          b.A = -b.A;
23479        } else b = a.f.kb, a = a.height, b.O += (a - 1) * b.fa, b.fa = -b.fa, b.N += (a - 1 >> 1) * b.Ab, b.Ab = -b.Ab, b.W += (a - 1 >> 1) * b.Db, b.Db = -b.Db, null != b.F && (b.J += (a - 1) * b.lb, b.lb = -b.lb);
23480
23481        return 0;
23482      }
23483
23484      function Cd(a, b, c, d) {
23485        if (null == d || 0 >= a || 0 >= b) return 2;
23486
23487        if (null != c) {
23488          if (c.Da) {
23489            var e = c.cd,
23490                f = c.bd,
23491                g = c.v & -2,
23492                h = c.j & -2;
23493            if (0 > g || 0 > h || 0 >= e || 0 >= f || g + e > a || h + f > b) return 2;
23494            a = e;
23495            b = f;
23496          }
23497
23498          if (c.da) {
23499            e = [c.ib];
23500            f = [c.hb];
23501            if (!bc(a, b, e, f)) return 2;
23502            a = e[0];
23503            b = f[0];
23504          }
23505        }
23506
23507        d.width = a;
23508        d.height = b;
23509
23510        a: {
23511          var k = d.width;
23512          var l = d.height;
23513          a = d.S;
23514          if (0 >= k || 0 >= l || !(a >= Ca && 13 > a)) a = 2;else {
23515            if (0 >= d.Rd && null == d.sd) {
23516              var g = f = e = b = 0,
23517                  h = k * Dd[a],
23518                  m = h * l;
23519              11 > a || (b = (k + 1) / 2, f = (l + 1) / 2 * b, 12 == a && (e = k, g = e * l));
23520              l = V(m + 2 * f + g);
23521
23522              if (null == l) {
23523                a = 1;
23524                break a;
23525              }
23526
23527              d.sd = l;
23528              11 > a ? (k = d.f.RGBA, k.eb = l, k.fb = 0, k.A = h, k.size = m) : (k = d.f.kb, k.y = l, k.O = 0, k.fa = h, k.Fd = m, k.f = l, k.N = 0 + m, k.Ab = b, k.Cd = f, k.ea = l, k.W = 0 + m + f, k.Db = b, k.Ed = f, 12 == a && (k.F = l, k.J = 0 + m + 2 * f), k.Tc = g, k.lb = e);
23529            }
23530
23531            b = 1;
23532            e = d.S;
23533            f = d.width;
23534            g = d.height;
23535            if (e >= Ca && 13 > e) {
23536              if (11 > e) a = d.f.RGBA, h = Math.abs(a.A), b &= h * (g - 1) + f <= a.size, b &= h >= f * Dd[e], b &= null != a.eb;else {
23537                a = d.f.kb;
23538                h = (f + 1) / 2;
23539                m = (g + 1) / 2;
23540                k = Math.abs(a.fa);
23541                var l = Math.abs(a.Ab),
23542                    n = Math.abs(a.Db),
23543                    r = Math.abs(a.lb),
23544                    q = r * (g - 1) + f;
23545                b &= k * (g - 1) + f <= a.Fd;
23546                b &= l * (m - 1) + h <= a.Cd;
23547                b &= n * (m - 1) + h <= a.Ed;
23548                b = b & k >= f & l >= h & n >= h;
23549                b &= null != a.y;
23550                b &= null != a.f;
23551                b &= null != a.ea;
23552                12 == e && (b &= r >= f, b &= q <= a.Tc, b &= null != a.F);
23553              }
23554            } else b = 0;
23555            a = b ? 0 : 2;
23556          }
23557        }
23558
23559        if (0 != a) return a;
23560        null != c && c.fd && (a = Bd(d));
23561        return a;
23562      }
23563
23564      var xb = 64,
23565          Hd = [0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215],
23566          Gd = 24,
23567          ob = 32,
23568          Xb = 8,
23569          Id = [0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7];
23570      X("Predictor0", "PredictorAdd0");
23571
23572      self.Predictor0 = function () {
23573        return 4278190080;
23574      };
23575
23576      self.Predictor1 = function (a) {
23577        return a;
23578      };
23579
23580      self.Predictor2 = function (a, b, c) {
23581        return b[c + 0];
23582      };
23583
23584      self.Predictor3 = function (a, b, c) {
23585        return b[c + 1];
23586      };
23587
23588      self.Predictor4 = function (a, b, c) {
23589        return b[c - 1];
23590      };
23591
23592      self.Predictor5 = function (a, b, c) {
23593        return aa(aa(a, b[c + 1]), b[c + 0]);
23594      };
23595
23596      self.Predictor6 = function (a, b, c) {
23597        return aa(a, b[c - 1]);
23598      };
23599
23600      self.Predictor7 = function (a, b, c) {
23601        return aa(a, b[c + 0]);
23602      };
23603
23604      self.Predictor8 = function (a, b, c) {
23605        return aa(b[c - 1], b[c + 0]);
23606      };
23607
23608      self.Predictor9 = function (a, b, c) {
23609        return aa(b[c + 0], b[c + 1]);
23610      };
23611
23612      self.Predictor10 = function (a, b, c) {
23613        return aa(aa(a, b[c - 1]), aa(b[c + 0], b[c + 1]));
23614      };
23615
23616      self.Predictor11 = function (a, b, c) {
23617        var d = b[c + 0];
23618        b = b[c - 1];
23619        return 0 >= Ia(d >> 24 & 255, a >> 24 & 255, b >> 24 & 255) + Ia(d >> 16 & 255, a >> 16 & 255, b >> 16 & 255) + Ia(d >> 8 & 255, a >> 8 & 255, b >> 8 & 255) + Ia(d & 255, a & 255, b & 255) ? d : a;
23620      };
23621
23622      self.Predictor12 = function (a, b, c) {
23623        var d = b[c + 0];
23624        b = b[c - 1];
23625        return (sa((a >> 24 & 255) + (d >> 24 & 255) - (b >> 24 & 255)) << 24 | sa((a >> 16 & 255) + (d >> 16 & 255) - (b >> 16 & 255)) << 16 | sa((a >> 8 & 255) + (d >> 8 & 255) - (b >> 8 & 255)) << 8 | sa((a & 255) + (d & 255) - (b & 255))) >>> 0;
23626      };
23627
23628      self.Predictor13 = function (a, b, c) {
23629        var d = b[c - 1];
23630        a = aa(a, b[c + 0]);
23631        return (eb(a >> 24 & 255, d >> 24 & 255) << 24 | eb(a >> 16 & 255, d >> 16 & 255) << 16 | eb(a >> 8 & 255, d >> 8 & 255) << 8 | eb(a >> 0 & 255, d >> 0 & 255)) >>> 0;
23632      };
23633
23634      var ee = self.PredictorAdd0;
23635      self.PredictorAdd1 = cc;
23636      X("Predictor2", "PredictorAdd2");
23637      X("Predictor3", "PredictorAdd3");
23638      X("Predictor4", "PredictorAdd4");
23639      X("Predictor5", "PredictorAdd5");
23640      X("Predictor6", "PredictorAdd6");
23641      X("Predictor7", "PredictorAdd7");
23642      X("Predictor8", "PredictorAdd8");
23643      X("Predictor9", "PredictorAdd9");
23644      X("Predictor10", "PredictorAdd10");
23645      X("Predictor11", "PredictorAdd11");
23646      X("Predictor12", "PredictorAdd12");
23647      X("Predictor13", "PredictorAdd13");
23648      var fe = self.PredictorAdd2;
23649      ec("ColorIndexInverseTransform", "MapARGB", "32b", function (a) {
23650        return a >> 8 & 255;
23651      }, function (a) {
23652        return a;
23653      });
23654      ec("VP8LColorIndexInverseTransformAlpha", "MapAlpha", "8b", function (a) {
23655        return a;
23656      }, function (a) {
23657        return a >> 8 & 255;
23658      });
23659      var rc = self.ColorIndexInverseTransform,
23660          ke = self.MapARGB,
23661          he = self.VP8LColorIndexInverseTransformAlpha,
23662          le = self.MapAlpha,
23663          pc,
23664          qc = self.VP8LPredictorsAdd = [];
23665      qc.length = 16;
23666      (self.VP8LPredictors = []).length = 16;
23667      (self.VP8LPredictorsAdd_C = []).length = 16;
23668      (self.VP8LPredictors_C = []).length = 16;
23669      var Fb,
23670          sc,
23671          Gb,
23672          Hb,
23673          xc,
23674          uc,
23675          bd = V(511),
23676          cd = V(2041),
23677          dd = V(225),
23678          ed = V(767),
23679          ad = 0,
23680          Qb = cd,
23681          mb = dd,
23682          R = ed,
23683          U = bd,
23684          Ca = 0,
23685          Ua = 1,
23686          tc = 2,
23687          Va = 3,
23688          ya = 4,
23689          Db = 5,
23690          wc = 6,
23691          zb = 7,
23692          Ab = 8,
23693          Ja = 9,
23694          Bb = 10,
23695          pe = [2, 3, 7],
23696          oe = [3, 3, 11],
23697          Dc = [280, 256, 256, 256, 40],
23698          qe = [0, 1, 1, 1, 0],
23699          ne = [17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
23700          de = [24, 7, 23, 25, 40, 6, 39, 41, 22, 26, 38, 42, 56, 5, 55, 57, 21, 27, 54, 58, 37, 43, 72, 4, 71, 73, 20, 28, 53, 59, 70, 74, 36, 44, 88, 69, 75, 52, 60, 3, 87, 89, 19, 29, 86, 90, 35, 45, 68, 76, 85, 91, 51, 61, 104, 2, 103, 105, 18, 30, 102, 106, 34, 46, 84, 92, 67, 77, 101, 107, 50, 62, 120, 1, 119, 121, 83, 93, 17, 31, 100, 108, 66, 78, 118, 122, 33, 47, 117, 123, 49, 63, 99, 109, 82, 94, 0, 116, 124, 65, 79, 16, 32, 98, 110, 48, 115, 125, 81, 95, 64, 114, 126, 97, 111, 80, 113, 127, 96, 112],
23701          me = [2954, 2956, 2958, 2962, 2970, 2986, 3018, 3082, 3212, 3468, 3980, 5004],
23702          ie = 8,
23703          Lb = [4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 91, 93, 95, 96, 98, 100, 101, 102, 104, 106, 108, 110, 112, 114, 116, 118, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 143, 145, 148, 151, 154, 157],
23704          Mb = [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 119, 122, 125, 128, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 161, 164, 167, 170, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 234, 239, 245, 249, 254, 259, 264, 269, 274, 279, 284],
23705          oa = null,
23706          He = [[173, 148, 140, 0], [176, 155, 140, 135, 0], [180, 157, 141, 134, 130, 0], [254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0]],
23707          Ie = [0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15],
23708          Mc = [-0, 1, -1, 2, -2, 3, 4, 6, -3, 5, -4, -5, -6, 7, -7, 8, -8, -9],
23709          Fe = [[[[128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128]], [[253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128], [189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128], [106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128]], [[1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128], [181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128], [78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128]], [[1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128], [184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128], [77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128]], [[1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128], [170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128], [37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128]], [[1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128], [207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128], [102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128]], [[1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128], [177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128], [80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128]], [[1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128], [246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128], [255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128]]], [[[198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62], [131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1], [68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128]], [[1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128], [184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128], [81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128]], [[1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128], [99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128], [23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128]], [[1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128], [109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128], [44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128]], [[1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128], [94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128], [22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128]], [[1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128], [124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128], [35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128]], [[1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128], [121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128], [45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128]], [[1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128], [203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128], [137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128]]], [[[253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128], [175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128], [73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 
23709128]], [[1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128], [239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128], [155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128]], [[1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128], [201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128], [69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128]], [[1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128], [223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128], [141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128]], [[1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128], [190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128], [149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128]], [[1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128], [247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128], [240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128]], [[1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128], [213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128], [55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128]], [[128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128]]], [[[202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255], [126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128], [61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128]], [[1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128], [166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128], [39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128]], [[1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128], [124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128], [24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128]], [[1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128], [149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128], [28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128]], [[1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128], [123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128], [20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128]], [[1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128], [168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128], [47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128]], [[1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128], [141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128], [42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128]], [[1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128], [244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128], [238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128]]]],
23710          Ke = [[[231, 120, 48, 89, 115, 113, 120, 152, 112], [152, 179, 64, 126, 170, 118, 46, 70, 95], [175, 69, 143, 80, 85, 82, 72, 155, 103], [56, 58, 10, 171, 218, 189, 17, 13, 152], [114, 26, 17, 163, 44, 195, 21, 10, 173], [121, 24, 80, 195, 26, 62, 44, 64, 85], [144, 71, 10, 38, 171, 213, 144, 34, 26], [170, 46, 55, 19, 136, 160, 33, 206, 71], [63, 20, 8, 114, 114, 208, 12, 9, 226], [81, 40, 11, 96, 182, 84, 29, 16, 36]], [[134, 183, 89, 137, 98, 101, 106, 165, 148], [72, 187, 100, 130, 157, 111, 32, 75, 80], [66, 102, 16
237107, 99, 74, 62, 40, 234, 128], [41, 53, 9, 178, 241, 141, 26, 8, 107], [74, 43, 26, 146, 73, 166, 49, 23, 157], [65, 38, 105, 160, 51, 52, 31, 115, 128], [104, 79, 12, 27, 217, 255, 87, 17, 7], [87, 68, 71, 44, 114, 51, 15, 186, 23], [47, 41, 14, 110, 182, 183, 21, 17, 194], [66, 45, 25, 102, 197, 189, 23, 18, 22]], [[88, 88, 147, 150, 42, 46, 45, 196, 205], [43, 97, 183, 117, 85, 38, 35, 179, 61], [39, 53, 200, 87, 26, 21, 43, 232, 171], [56, 34, 51, 104, 114, 102, 29, 93, 77], [39, 28, 85, 171, 58, 165, 90, 98, 64], [34, 22, 116, 206, 23, 34, 43, 166, 73], [107, 54, 32, 26, 51, 1, 81, 43, 31], [68, 25, 106, 22, 64, 171, 36, 225, 114], [34, 19, 21, 102, 132, 188, 16, 76, 124], [62, 18, 78, 95, 85, 57, 50, 48, 51]], [[193, 101, 35, 159, 215, 111, 89, 46, 111], [60, 148, 31, 172, 219, 228, 21, 18, 111], [112, 113, 77, 85, 179, 255, 38, 120, 114], [40, 42, 1, 196, 245, 209, 10, 25, 109], [88, 43, 29, 140, 166, 213, 37, 43, 154], [61, 63, 30, 155, 67, 45, 68, 1, 209], [100, 80, 8, 43, 154, 1, 51, 26, 71], [142, 78, 78, 16, 255, 128, 34, 197, 171], [41, 40, 5, 102, 211, 183, 4, 1, 221], [51, 50, 17, 168, 209, 192, 23, 25, 82]], [[138, 31, 36, 171, 27, 166, 38, 44, 229], [67, 87, 58, 169, 82, 115, 26, 59, 179], [63, 59, 90, 180, 59, 166, 93, 73, 154], [40, 40, 21, 116, 143, 209, 34, 39, 175], [47, 15, 16, 183, 34, 223, 49, 45, 183], [46, 17, 33, 183, 6, 98, 15, 32, 183], [57, 46, 22, 24, 128, 1, 54, 17, 37], [65, 32, 73, 115, 28, 128, 23, 128, 205], [40, 3, 9, 115, 51, 192, 18, 6, 223], [87, 37, 9, 115, 59, 77, 64, 21, 47]], [[104, 55, 44, 218, 9, 54, 53, 130, 226], [64, 90, 70, 205, 40, 41, 23, 26, 57], [54, 57, 112, 184, 5, 41, 38, 166, 213], [30, 34, 26, 133, 152, 116, 10, 32, 134], [39, 19, 53, 221, 26, 114, 32, 73, 255], [31, 9, 65, 234, 2, 15, 1, 118, 73], [75, 32, 12, 51, 192, 255, 160, 43, 51], [88, 31, 35, 67, 102, 85, 55, 186, 85], [56, 21, 23, 111, 59, 205, 45, 37, 192], [55, 38, 70, 124, 73, 102, 1, 34, 98]], [[125, 98, 42, 88, 104, 85, 117, 175, 82], [95, 84, 53, 89, 128, 100, 113, 101, 45], [75, 79, 123, 47, 51, 128, 81, 171, 1], [57, 17, 5, 71, 102, 57, 53, 41, 49], [38, 33, 13, 121, 57, 73, 26, 1, 85], [41, 10, 67, 138, 77, 110, 90, 47, 114], [115, 21, 2, 10, 102, 255, 166, 23, 6], [101, 29, 16, 10, 85, 128, 101, 196, 26], [57, 18, 10, 102, 102, 213, 34, 20, 43], [117, 20, 15, 36, 163, 128, 68, 1, 26]], [[102, 61, 71, 37, 34, 53, 31, 243, 192], [69, 60, 71, 38, 73, 119, 28, 222, 37], [68, 45, 128, 34, 1, 47, 11, 245, 171], [62, 17, 19, 70, 146, 85, 55, 62, 70], [37, 43, 37, 154, 100, 163, 85, 160, 1], [63, 9, 92, 136, 28, 64, 32, 201, 85], [75, 15, 9, 9, 64, 255, 184, 119, 16], [86, 6, 28, 5, 64, 255, 25, 248, 1], [56, 8, 17, 132, 137, 255, 55, 116, 128], [58, 15, 20, 82, 135, 57, 26, 121, 40]], [[164, 50, 31, 137, 154, 133, 25, 35, 218], [51, 103, 44, 131, 131, 123, 31, 6, 158], [86, 40, 64, 135, 148, 224, 45, 183, 128], [22, 26, 17, 131, 240, 154, 14, 1, 209], [45, 16, 21, 91, 64, 222, 7, 1, 197], [56, 21, 39, 155, 60, 138, 23, 102, 213], [83, 12, 13, 54, 192, 255, 68, 47, 28], [85, 26, 85, 85, 128, 128, 32, 146, 171], [18, 11, 7, 63, 144, 171, 4, 4, 246], [35, 27, 10, 146, 174, 171, 12, 26, 128]], [[190, 80, 35, 99, 180, 80, 126, 54, 45], [85, 126, 47, 87, 176, 51, 41, 20, 32], [101, 75, 128, 139, 118, 146, 116, 128, 85], [56, 41, 15, 176, 236, 85, 37, 9, 62], [71, 30, 17, 119, 118, 255, 17, 18, 138], [101, 38, 60, 138, 55, 70, 43, 26, 142], [146, 36, 19, 30, 171, 255, 97, 27, 20], [138, 45, 61, 62, 219, 1, 81, 188, 64], [32, 41, 20, 117, 151, 142, 20, 21, 163], [112, 19, 12, 61, 195, 128, 48, 4, 24]]],
23711          Ee = [[[[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255], [223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255], [249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255], [234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255], [239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255], [251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255], [250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]]], [[[217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255], [234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255]], [[255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255]], [[255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255], [249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255], [247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255], [250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]]], [[[186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255], [234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255], [251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255]], [[255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255]], [[255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]]], [[[248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255], [248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255]], [[255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255], [246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255], [252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255]], [[255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255], [248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255], [253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255]], [[255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255], [245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255], [253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255], [252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255], [249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255], [250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]]]],
23712          Ge = [0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 0],
23713          Nc,
23714          Y = [],
23715          W = [],
23716          ka = [],
23717          Za,
23718          fd,
23719          Nb,
23720          pa,
23721          Ob,
23722          Xc,
23723          Tc,
23724          Yc,
23725          Uc,
23726          Zc,
23727          Vc,
23728          $c,
23729          Wc,
23730          Rc,
23731          Pc,
23732          Sc,
23733          Qc,
vendor: 7,620 bytes, lines 23734-23961
23734          re = 1,
23735          Cc = 2,
23736          ia = [],
23737          za,
23738          vc,
23739          fc,
23740          Fc,
23741          P = [];
23742      va("UpsampleRgbLinePair", Ga, 3);
23743      va("UpsampleBgrLinePair", Tb, 3);
23744      va("UpsampleRgbaLinePair", wd, 4);
23745      va("UpsampleBgraLinePair", vd, 4);
23746      va("UpsampleArgbLinePair", ud, 4);
23747      va("UpsampleRgba4444LinePair", td, 2);
23748      va("UpsampleRgb565LinePair", sd, 2);
23749      var Mf = self.UpsampleRgbLinePair,
23750          Nf = self.UpsampleBgrLinePair,
23751          nd = self.UpsampleRgbaLinePair,
23752          od = self.UpsampleBgraLinePair,
23753          pd = self.UpsampleArgbLinePair,
23754          qd = self.UpsampleRgba4444LinePair,
23755          Of = self.UpsampleRgb565LinePair,
23756          Wa = 16,
23757          Ba = 1 << Wa - 1,
23758          ta = -227,
23759          Eb = 482,
23760          rd = 6,
23761          Pf = (256 << rd) - 1,
23762          jc = 0,
23763          Yd = V(256),
23764          ae = V(256),
23765          $d = V(256),
23766          Zd = V(256),
23767          be = V(Eb - ta),
23768          ce = V(Eb - ta);
23769      la("YuvToRgbRow", Ga, 3);
23770      la("YuvToBgrRow", Tb, 3);
23771      la("YuvToRgbaRow", wd, 4);
23772      la("YuvToBgraRow", vd, 4);
23773      la("YuvToArgbRow", ud, 4);
23774      la("YuvToRgba4444Row", td, 2);
23775      la("YuvToRgb565Row", sd, 2);
23776      var zd = [0, 4, 8, 12, 128, 132, 136, 140, 256, 260, 264, 268, 384, 388, 392, 396],
23777          Ya = [0, 2, 8],
23778          Qf = [8, 7, 6, 4, 4, 2, 2, 2, 1, 1, 1, 1],
23779          Ne = 1;
23780
23781      this.WebPDecodeRGBA = function (a, b, c, d, e) {
23782        var f = Ua;
23783        var g = new Cf(),
23784            h = new Cb();
23785        g.ba = h;
23786        h.S = f;
23787        h.width = [h.width];
23788        h.height = [h.height];
23789        var k = h.width;
23790        var l = h.height,
23791            m = new Td();
23792        if (null == m || null == a) var n = 2;else x(null != m), n = Ad(a, b, c, m.width, m.height, m.Pd, m.Qd, m.format, null);
23793        0 != n ? k = 0 : (null != k && (k[0] = m.width[0]), null != l && (l[0] = m.height[0]), k = 1);
23794
23795        if (k) {
23796          h.width = h.width[0];
23797          h.height = h.height[0];
23798          null != d && (d[0] = h.width);
23799          null != e && (e[0] = h.height);
23800
23801          b: {
23802            d = new Oa();
23803            e = new md();
23804            e.data = a;
23805            e.w = b;
23806            e.ha = c;
23807            e.kd = 1;
23808            b = [0];
23809            x(null != e);
23810            a = Ad(e.data, e.w, e.ha, null, null, null, b, null, e);
23811            (0 == a || 7 == a) && b[0] && (a = 4);
23812            b = a;
23813
23814            if (0 == b) {
23815              x(null != g);
23816              d.data = e.data;
23817              d.w = e.w + e.offset;
23818              d.ha = e.ha - e.offset;
23819              d.put = kc;
23820              d.ac = gc;
23821              d.bc = lc;
23822              d.ma = g;
23823
23824              if (e.xa) {
23825                a = Bc();
23826
23827                if (null == a) {
23828                  g = 1;
23829                  break b;
23830                }
23831
23832                if (te(a, d)) {
23833                  b = Cd(d.width, d.height, g.Oa, g.ba);
23834
23835                  if (d = 0 == b) {
23836                    c: {
23837                      d = a;
23838
23839                      d: for (;;) {
23840                        if (null == d) {
23841                          d = 0;
23842                          break c;
23843                        }
23844
23845                        x(null != d.s.yc);
23846                        x(null != d.s.Ya);
23847                        x(0 < d.s.Wb);
23848                        c = d.l;
23849                        x(null != c);
23850                        e = c.ma;
23851                        x(null != e);
23852
23853                        if (0 != d.xb) {
23854                          d.ca = e.ba;
23855                          d.tb = e.tb;
23856                          x(null != d.ca);
23857
23858                          if (!hc(e.Oa, c, Va)) {
23859                            d.a = 2;
23860                            break d;
23861                          }
23862
23863                          if (!Ec(d, c.width)) break d;
23864                          if (c.da) break d;
23865                          (c.da || hb(d.ca.S)) && Aa();
23866                          11 > d.ca.S || (alert("todo:WebPInitConvertARGBToYUV"), null != d.ca.f.kb.F && Aa());
23867
23868                          if (d.Pb && 0 < d.s.ua && null == d.s.vb.X && !Zb(d.s.vb, d.s.Wa.Xa)) {
23869                            d.a = 1;
23870                            break d;
23871                          }
23872
23873                          d.xb = 0;
23874                        }
23875
23876                        if (!Jb(d, d.V, d.Ba, d.c, d.i, c.o, ge)) break d;
23877                        e.Dc = d.Ma;
23878                        d = 1;
23879                        break c;
23880                      }
23881
23882                      x(0 != d.a);
23883                      d = 0;
23884                    }
23885
23886                    d = !d;
23887                  }
23888
23889                  d && (b = a.a);
23890                } else b = a.a;
23891              } else {
23892                a = new Ce();
23893
23894                if (null == a) {
23895                  g = 1;
23896                  break b;
23897                }
23898
23899                a.Fa = e.na;
23900                a.P = e.P;
23901                a.qc = e.Sa;
23902
23903                if (Kc(a, d)) {
23904                  if (b = Cd(d.width, d.height, g.Oa, g.ba), 0 == b) {
23905                    a.Aa = 0;
23906                    c = g.Oa;
23907                    e = a;
23908                    x(null != e);
23909
23910                    if (null != c) {
23911                      k = c.Md;
23912                      k = 0 > k ? 0 : 100 < k ? 255 : 255 * k / 100;
23913
23914                      if (0 < k) {
23915                        for (l = m = 0; 4 > l; ++l) {
23916                          n = e.pb[l], 12 > n.lc && (n.ia = k * Qf[0 > n.lc ? 0 : n.lc] >> 3), m |= n.ia;
23917                        }
23918
23919                        m && (alert("todo:VP8InitRandom"), e.ia = 1);
23920                      }
23921
23922                      e.Ga = c.Id;
23923                      100 < e.Ga ? e.Ga = 100 : 0 > e.Ga && (e.Ga = 0);
23924                    }
23925
23926                    Me(a, d) || (b = a.a);
23927                  }
23928                } else b = a.a;
23929              }
23930
23931              0 == b && null != g.Oa && g.Oa.fd && (b = Bd(g.ba));
23932            }
23933
23934            g = b;
23935          }
23936
23937          f = 0 != g ? null : 11 > f ? h.f.RGBA.eb : h.f.kb.y;
23938        } else f = null;
23939
23940        return f;
23941      };
23942
23943      var Dd = [3, 4, 3, 4, 4, 2, 2, 4, 4, 4, 2, 1, 1];
23944    };
23945
23946    new _WebPDecoder();
23947    /** @license
23948     * Copyright (c) 2017 Dominik Homberger
23949    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:
23950    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
23951    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.
23952    https://webpjs.appspot.com
23953    WebPRiffParser [email protected]
23954    */
23955
23956    function memcmp(data, data_off, str, size) {
23957      for (var i = 0; i < size; i++) {
23958        if (data[data_off + i] != str.charCodeAt(i)) return true;
23959      }
23960
23961      return false;
23962    }
23963
23964    function GetTag(data, data_off) {
23965      var str = "";
23966
23967      for (var i = 0; i < 4; i++) {
23968        str += String.fromCharCode(data[data_off++]);
23969      }
23970
23971      return str;
23972    }
23973
23974    function GetLE16(data, data_off) {
23975      return data[data_off + 0] << 0 | data[data_off + 1] << 8;
23976    }
23977
23978    function GetLE24(data, data_off) {
23979      return (data[data_off + 0] << 0 | data[data_off + 1] << 8 | data[data_off + 2] << 16) >>> 0;
23980    }
23981
23982    function GetLE32(data, data_off) {
23983      return (data[data_off + 0] << 0 | data[data_off + 1] << 8 | data[data_off + 2] << 16 | data[data_off + 3] << 24) >>> 0;
23984    }
23985
23986    function WebPRiffParser(src, src_off) {
23987      var imagearray = {};
23988      var i = 0;
23989      var alpha_chunk = false;
23990      var alpha_size = 0;
23991      var alpha_offset = 0;
23992      imagearray["frames"] = [];
23993      if (memcmp(src, src_off, "RIFF", 4)) return;
23994      src_off += 4;
23995      var riff_size = GetLE32(src, src_off) + 8;
23996      src_off += 8;
23997
23998      while (src_off < src.length) {
23999        var fourcc = GetTag(src, src_off);
24000        src_off += 4;
24001        var payload_size = GetLE32(src, src_off);
24002        src_off += 4;
24003        var payload_size_padded = payload_size + (payload_size & 1);
24004
24005        switch (fourcc) {
24006          case "VP8 ":
24007          case "VP8L":
24008            if (typeof imagearray["frames"][i] === "undefined") imagearray["frames"][i] = {};
24009            var obj = imagearray["frames"][i];
24010            var height = [0];
24011            var width = [0];
24012            obj["src_off"] = alpha_chunk ? alpha_offset : src_off - 8;
24013            obj["src_size"] = alpha_size + payload_size + 8; //var rgba = webpdecoder.WebPDecodeRGBA(src,(alpha_chunk?alpha_offset:src_off-8),alpha_size+payload_size+8,width,height);
24014            //imagearray[i]={'rgba':rgba,'width':width[0],'height':height[0]};
24015
24016            i++;
24017
24018            if (alpha_chunk) {
24019              alpha_chunk = false;
24020              alpha_size = 0;
24021              alpha_offset = 0;
24022            }
24023
24024            break;
24025
24026          case "VP8X":
24027            var obj = imagearray["header"] = {};
24028            var feature_flags = obj["feature_flags"] = src[src_off];
24029            var src_off_ = src_off + 4;
24030            var canvas_width = obj["canvas_width"] = 1 + GetLE24(src, src_off_);
24031            src_off_ += 3;
24032            var canvas_height = obj["canvas_height"] = 1 + GetLE24(src, src_off_);
24033            src_off_ += 3;
24034            break;
24035
24036          case "ALPH":
24037            alpha_chunk = true;
24038            alpha_size = payload_size_padded + 8;
24039            alpha_offset = src_off - 8;
24040            break;
24041
24042          case "ANIM":
24043            var obj = imagearray["header"];
24044            var bgcolor = obj["bgcolor"] = GetLE32(src, src_off);
24045            src_off_ = src_off + 4;
24046            var loop_count = obj["loop_count"] = GetLE16(src, src_off_);
24047            src_off_ += 2;
24048            break;
24049
24050          case "ANMF":
24051            var offset_x = 0,
24052                offset_y = 0,
24053                width = 0,
24054                height = 0,
24055                duration = 0,
24056                blend = 0,
24057                dispose = 0,
24058                temp = 0;
24059            var obj = imagearray["frames"][i] = {};
24060            obj["offset_x"] = offset_x = 2 * GetLE24(src, src_off);
24061            src_off += 3;
24062            obj["offset_y"] = offset_y = 2 * GetLE24(src, src_off);
24063            src_off += 3;
24064            obj["width"] = width = 1 + GetLE24(src, src_off);
24065            src_off += 3;
24066            obj["height"] = height = 1 + GetLE24(src, src_off);
24067            src_off += 3;
24068            obj["duration"] = duration = GetLE24(src, src_off);
24069            src_off += 3;
24070            temp = src[src_off++];
24071            obj["dispose"] = dispose = temp & 1;
24072            obj["blend"] = blend = temp >> 1 & 1;
24073            break;
24074        }
24075
24076        if (fourcc != "ANMF") src_off += payload_size_padded;
24077      }
24078
24079      return imagearray;
24080    }
24081
24082    var height = [0];
24083    var width = [0];
24084    var pixels = [];
24085    var webpdecoder = new _WebPDecoder();
24086    var response = imageData;
24087    var imagearray = WebPRiffParser(response, 0);
24088    imagearray["response"] = response;
24089    imagearray["rgbaoutput"] = true;
24090    imagearray["dataurl"] = false;
vendor: 5,115 bytes, lines 24091-24263
24091    var header = imagearray["header"] ? imagearray["header"] : null;
24092    var frames = imagearray["frames"] ? imagearray["frames"] : null;
24093
24094    if (header) {
24095      header["loop_counter"] = header["loop_count"];
24096      height = [header["canvas_height"]];
24097      width = [header["canvas_width"]];
24098
24099      for (var f = 0; f < frames.length; f++) {
24100        if (frames[f]["blend"] == 0) {
24101          break;
24102        }
24103      }
24104    }
24105
24106    var frame = frames[0];
24107    var rgba = webpdecoder.WebPDecodeRGBA(response, frame["src_off"], frame["src_size"], width, height);
24108    frame["rgba"] = rgba;
24109    frame["imgwidth"] = width[0];
24110    frame["imgheight"] = height[0];
24111
24112    for (var i = 0; i < width[0] * height[0] * 4; i++) {
24113      pixels[i] = rgba[i];
24114    }
24115
24116    this.width = width;
24117    this.height = height;
24118    this.data = pixels;
24119    return this;
24120  }
24121
24122  WebPDecoder.prototype.getData = function () {
24123    return this.data;
24124  };
24125
24126  /**
24127   * @license
24128   * Copyright (c) 2019 Aras Abbasi
24129   *
24130   * Licensed under the MIT License.
24131   * http://opensource.org/licenses/mit-license
24132   */
24133  /**
24134   * jsPDF webp Support PlugIn
24135   *
24136   * @name webp_support
24137   * @module
24138   */
24139
24140  (function (jsPDFAPI) {
24141
24142    jsPDFAPI.processWEBP = function (imageData, index, alias, compression) {
24143      var reader = new WebPDecoder(imageData, false);
24144      var width = reader.width,
24145          height = reader.height;
24146      var qu = 100;
24147      var pixels = reader.getData();
24148      var rawImageData = {
24149        data: pixels,
24150        width: width,
24151        height: height
24152      };
24153      var encoder = new JPEGEncoder(qu);
24154      var data = encoder.encode(rawImageData, qu);
24155      return jsPDFAPI.processJPEG.call(this, data, index, alias, compression);
24156    };
24157  })(jsPDF.API);
24158
24159  /**
24160   * @license
24161   *
24162   * Copyright (c) 2021 Antti Palola, https://github.com/Pantura
24163   *
24164   * Permission is hereby granted, free of charge, to any person obtaining
24165   * a copy of this software and associated documentation files (the
24166   * "Software"), to deal in the Software without restriction, including
24167   * without limitation the rights to use, copy, modify, merge, publish,
24168   * distribute, sublicense, and/or sell copies of the Software, and to
24169   * permit persons to whom the Software is furnished to do so, subject to
24170   * the following conditions:
24171   *
24172   * The above copyright notice and this permission notice shall be
24173   * included in all copies or substantial portions of the Software.
24174   *
24175   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24176   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24177   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24178   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24179   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24180   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24181   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24182   * ====================================================================
24183   */
24184  /**
24185   * jsPDF RGBA array PlugIn
24186   * @name rgba_support
24187   * @module
24188   */
24189
24190  (function (jsPDFAPI) {
24191    /**
24192     * @name processRGBA
24193     * @function
24194     *
24195     * Process RGBA Array. This is a one-dimension array with pixel data [red, green, blue, alpha, red, green, ...].
24196     * RGBA array data can be obtained from DOM canvas getImageData.
24197     * @ignore
24198     */
24199
24200    jsPDFAPI.processRGBA = function (imageData, index, alias) {
24201
24202      var imagePixels = imageData.data;
24203      var length = imagePixels.length; // jsPDF takes alpha data separately so extract that.
24204
24205      var rgbOut = new Uint8Array(length / 4 * 3);
24206      var alphaOut = new Uint8Array(length / 4);
24207      var outIndex = 0;
24208      var alphaIndex = 0;
24209
24210      for (var i = 0; i < length; i += 4) {
24211        var r = imagePixels[i];
24212        var g = imagePixels[i + 1];
24213        var b = imagePixels[i + 2];
24214        var alpha = imagePixels[i + 3];
24215        rgbOut[outIndex++] = r;
24216        rgbOut[outIndex++] = g;
24217        rgbOut[outIndex++] = b;
24218        alphaOut[alphaIndex++] = alpha;
24219      }
24220
24221      var rgbData = this.__addimage__.arrayBufferToBinaryString(rgbOut);
24222
24223      var alphaData = this.__addimage__.arrayBufferToBinaryString(alphaOut);
24224
24225      return {
24226        alpha: alphaData,
24227        data: rgbData,
24228        index: index,
24229        alias: alias,
24230        colorSpace: "DeviceRGB",
24231        bitsPerComponent: 8,
24232        width: imageData.width,
24233        height: imageData.height
24234      };
24235    };
24236  })(jsPDF.API);
24237
24238  /**
24239   * @license
24240   * Licensed under the MIT License.
24241   * http://opensource.org/licenses/mit-license
24242   */
24243  /**
24244   * jsPDF setLanguage Plugin
24245   *
24246   * @name setLanguage
24247   * @module
24248   */
24249
24250  (function (jsPDFAPI) {
24251    /**
24252     * Add Language Tag to the generated PDF
24253     *
24254     * @name setLanguage
24255     * @function
24256     * @param {string} langCode The Language code as ISO-639-1 (e.g. 'en') or as country language code (e.g. 'en-GB').
24257     * @returns {jsPDF}
24258     * @example
24259     * var doc = new jsPDF()
24260     * doc.text(10, 10, 'This is a test')
24261     * doc.setLanguage("en-US")
24262     * doc.save('english.pdf')
24263     */
vendor: 5,873 bytes, lines 24264-24464
24264
24265    jsPDFAPI.setLanguage = function (langCode) {
24266
24267      var langCodes = {
24268        af: "Afrikaans",
24269        sq: "Albanian",
24270        ar: "Arabic (Standard)",
24271        "ar-DZ": "Arabic (Algeria)",
24272        "ar-BH": "Arabic (Bahrain)",
24273        "ar-EG": "Arabic (Egypt)",
24274        "ar-IQ": "Arabic (Iraq)",
24275        "ar-JO": "Arabic (Jordan)",
24276        "ar-KW": "Arabic (Kuwait)",
24277        "ar-LB": "Arabic (Lebanon)",
24278        "ar-LY": "Arabic (Libya)",
24279        "ar-MA": "Arabic (Morocco)",
24280        "ar-OM": "Arabic (Oman)",
24281        "ar-QA": "Arabic (Qatar)",
24282        "ar-SA": "Arabic (Saudi Arabia)",
24283        "ar-SY": "Arabic (Syria)",
24284        "ar-TN": "Arabic (Tunisia)",
24285        "ar-AE": "Arabic (U.A.E.)",
24286        "ar-YE": "Arabic (Yemen)",
24287        an: "Aragonese",
24288        hy: "Armenian",
24289        as: "Assamese",
24290        ast: "Asturian",
24291        az: "Azerbaijani",
24292        eu: "Basque",
24293        be: "Belarusian",
24294        bn: "Bengali",
24295        bs: "Bosnian",
24296        br: "Breton",
24297        bg: "Bulgarian",
24298        my: "Burmese",
24299        ca: "Catalan",
24300        ch: "Chamorro",
24301        ce: "Chechen",
24302        zh: "Chinese",
24303        "zh-HK": "Chinese (Hong Kong)",
24304        "zh-CN": "Chinese (PRC)",
24305        "zh-SG": "Chinese (Singapore)",
24306        "zh-TW": "Chinese (Taiwan)",
24307        cv: "Chuvash",
24308        co: "Corsican",
24309        cr: "Cree",
24310        hr: "Croatian",
24311        cs: "Czech",
24312        da: "Danish",
24313        nl: "Dutch (Standard)",
24314        "nl-BE": "Dutch (Belgian)",
24315        en: "English",
24316        "en-AU": "English (Australia)",
24317        "en-BZ": "English (Belize)",
24318        "en-CA": "English (Canada)",
24319        "en-IE": "English (Ireland)",
24320        "en-JM": "English (Jamaica)",
24321        "en-NZ": "English (New Zealand)",
24322        "en-PH": "English (Philippines)",
24323        "en-ZA": "English (South Africa)",
24324        "en-TT": "English (Trinidad & Tobago)",
24325        "en-GB": "English (United Kingdom)",
24326        "en-US": "English (United States)",
24327        "en-ZW": "English (Zimbabwe)",
24328        eo: "Esperanto",
24329        et: "Estonian",
24330        fo: "Faeroese",
24331        fj: "Fijian",
24332        fi: "Finnish",
24333        fr: "French (Standard)",
24334        "fr-BE": "French (Belgium)",
24335        "fr-CA": "French (Canada)",
24336        "fr-FR": "French (France)",
24337        "fr-LU": "French (Luxembourg)",
24338        "fr-MC": "French (Monaco)",
24339        "fr-CH": "French (Switzerland)",
24340        fy: "Frisian",
24341        fur: "Friulian",
24342        gd: "Gaelic (Scots)",
24343        "gd-IE": "Gaelic (Irish)",
24344        gl: "Galacian",
24345        ka: "Georgian",
24346        de: "German (Standard)",
24347        "de-AT": "German (Austria)",
24348        "de-DE": "German (Germany)",
24349        "de-LI": "German (Liechtenstein)",
24350        "de-LU": "German (Luxembourg)",
24351        "de-CH": "German (Switzerland)",
24352        el: "Greek",
24353        gu: "Gujurati",
24354        ht: "Haitian",
24355        he: "Hebrew",
24356        hi: "Hindi",
24357        hu: "Hungarian",
24358        is: "Icelandic",
24359        id: "Indonesian",
24360        iu: "Inuktitut",
24361        ga: "Irish",
24362        it: "Italian (Standard)",
24363        "it-CH": "Italian (Switzerland)",
24364        ja: "Japanese",
24365        kn: "Kannada",
24366        ks: "Kashmiri",
24367        kk: "Kazakh",
24368        km: "Khmer",
24369        ky: "Kirghiz",
24370        tlh: "Klingon",
24371        ko: "Korean",
24372        "ko-KP": "Korean (North Korea)",
24373        "ko-KR": "Korean (South Korea)",
24374        la: "Latin",
24375        lv: "Latvian",
24376        lt: "Lithuanian",
24377        lb: "Luxembourgish",
24378        mk: "North Macedonia",
24379        ms: "Malay",
24380        ml: "Malayalam",
24381        mt: "Maltese",
24382        mi: "Maori",
24383        mr: "Marathi",
24384        mo: "Moldavian",
24385        nv: "Navajo",
24386        ng: "Ndonga",
24387        ne: "Nepali",
24388        no: "Norwegian",
24389        nb: "Norwegian (Bokmal)",
24390        nn: "Norwegian (Nynorsk)",
24391        oc: "Occitan",
24392        or: "Oriya",
24393        om: "Oromo",
24394        fa: "Persian",
24395        "fa-IR": "Persian/Iran",
24396        pl: "Polish",
24397        pt: "Portuguese",
24398        "pt-BR": "Portuguese (Brazil)",
24399        pa: "Punjabi",
24400        "pa-IN": "Punjabi (India)",
24401        "pa-PK": "Punjabi (Pakistan)",
24402        qu: "Quechua",
24403        rm: "Rhaeto-Romanic",
24404        ro: "Romanian",
24405        "ro-MO": "Romanian (Moldavia)",
24406        ru: "Russian",
24407        "ru-MO": "Russian (Moldavia)",
24408        sz: "Sami (Lappish)",
24409        sg: "Sango",
24410        sa: "Sanskrit",
24411        sc: "Sardinian",
24412        sd: "Sindhi",
24413        si: "Singhalese",
24414        sr: "Serbian",
24415        sk: "Slovak",
24416        sl: "Slovenian",
24417        so: "Somani",
24418        sb: "Sorbian",
24419        es: "Spanish",
24420        "es-AR": "Spanish (Argentina)",
24421        "es-BO": "Spanish (Bolivia)",
24422        "es-CL": "Spanish (Chile)",
24423        "es-CO": "Spanish (Colombia)",
24424        "es-CR": "Spanish (Costa Rica)",
24425        "es-DO": "Spanish (Dominican Republic)",
24426        "es-EC": "Spanish (Ecuador)",
24427        "es-SV": "Spanish (El Salvador)",
24428        "es-GT": "Spanish (Guatemala)",
24429        "es-HN": "Spanish (Honduras)",
24430        "es-MX": "Spanish (Mexico)",
24431        "es-NI": "Spanish (Nicaragua)",
24432        "es-PA": "Spanish (Panama)",
24433        "es-PY": "Spanish (Paraguay)",
24434        "es-PE": "Spanish (Peru)",
24435        "es-PR": "Spanish (Puerto Rico)",
24436        "es-ES": "Spanish (Spain)",
24437        "es-UY": "Spanish (Uruguay)",
24438        "es-VE": "Spanish (Venezuela)",
24439        sx: "Sutu",
24440        sw: "Swahili",
24441        sv: "Swedish",
24442        "sv-FI": "Swedish (Finland)",
24443        "sv-SV": "Swedish (Sweden)",
24444        ta: "Tamil",
24445        tt: "Tatar",
24446        te: "Teluga",
24447        th: "Thai",
24448        tig: "Tigre",
24449        ts: "Tsonga",
24450        tn: "Tswana",
24451        tr: "Turkish",
24452        tk: "Turkmen",
24453        uk: "Ukrainian",
24454        hsb: "Upper Sorbian",
24455        ur: "Urdu",
24456        ve: "Venda",
24457        vi: "Vietnamese",
24458        vo: "Volapuk",
24459        wa: "Walloon",
24460        cy: "Welsh",
24461        xh: "Xhosa",
24462        ji: "Yiddish",
24463        zu: "Zulu"
24464      };
vendor: 12,007 bytes, lines 24465-24823
24465
24466      if (this.internal.languageSettings === undefined) {
24467        this.internal.languageSettings = {};
24468        this.internal.languageSettings.isSubscribed = false;
24469      }
24470
24471      if (langCodes[langCode] !== undefined) {
24472        this.internal.languageSettings.languageCode = langCode;
24473
24474        if (this.internal.languageSettings.isSubscribed === false) {
24475          this.internal.events.subscribe("putCatalog", function () {
24476            this.internal.write("/Lang (" + this.internal.languageSettings.languageCode + ")");
24477          });
24478          this.internal.languageSettings.isSubscribed = true;
24479        }
24480      }
24481
24482      return this;
24483    };
24484  })(jsPDF.API);
24485
24486  /**
24487   * jsPDF split_text_to_size plugin
24488   *
24489   * @name split_text_to_size
24490   * @module
24491   */
24492
24493  (function (API) {
24494    /**
24495     * Returns an array of length matching length of the 'word' string, with each
24496     * cell occupied by the width of the char in that position.
24497     *
24498     * @name getCharWidthsArray
24499     * @function
24500     * @param {string} text
24501     * @param {Object} options
24502     * @returns {Array}
24503     */
24504
24505    var getCharWidthsArray = API.getCharWidthsArray = function (text, options) {
24506      options = options || {};
24507      var activeFont = options.font || this.internal.getFont();
24508      var fontSize = options.fontSize || this.internal.getFontSize();
24509      var charSpace = options.charSpace || this.internal.getCharSpace();
24510      var widths = options.widths ? options.widths : activeFont.metadata.Unicode.widths;
24511      var widthsFractionOf = widths.fof ? widths.fof : 1;
24512      var kerning = options.kerning ? options.kerning : activeFont.metadata.Unicode.kerning;
24513      var kerningFractionOf = kerning.fof ? kerning.fof : 1;
24514      var doKerning = options.doKerning === false ? false : true;
24515      var kerningValue = 0;
24516      var i;
24517      var length = text.length;
24518      var char_code;
24519      var prior_char_code = 0; //for kerning
24520
24521      var default_char_width = widths[0] || widthsFractionOf;
24522      var output = [];
24523
24524      for (i = 0; i < length; i++) {
24525        char_code = text.charCodeAt(i);
24526
24527        if (typeof activeFont.metadata.widthOfString === "function") {
24528          output.push((activeFont.metadata.widthOfGlyph(activeFont.metadata.characterToGlyph(char_code)) + charSpace * (1000 / fontSize) || 0) / 1000);
24529        } else {
24530          if (doKerning && _typeof(kerning[char_code]) === "object" && !isNaN(parseInt(kerning[char_code][prior_char_code], 10))) {
24531            kerningValue = kerning[char_code][prior_char_code] / kerningFractionOf;
24532          } else {
24533            kerningValue = 0;
24534          }
24535
24536          output.push((widths[char_code] || default_char_width) / widthsFractionOf + kerningValue);
24537        }
24538
24539        prior_char_code = char_code;
24540      }
24541
24542      return output;
24543    };
24544    /**
24545     * Returns a widths of string in a given font, if the font size is set as 1 point.
24546     *
24547     * In other words, this is "proportional" value. For 1 unit of font size, the length
24548     * of the string will be that much.
24549     *
24550     * Multiply by font size to get actual width in *points*
24551     * Then divide by 72 to get inches or divide by (72/25.6) to get 'mm' etc.
24552     *
24553     * @name getStringUnitWidth
24554     * @public
24555     * @function
24556     * @param {string} text
24557     * @param {string} options
24558     * @returns {number} result
24559     */
24560
24561
24562    var getStringUnitWidth = API.getStringUnitWidth = function (text, options) {
24563      options = options || {};
24564      var fontSize = options.fontSize || this.internal.getFontSize();
24565      var font = options.font || this.internal.getFont();
24566      var charSpace = options.charSpace || this.internal.getCharSpace();
24567      var result = 0;
24568
24569      if (API.processArabic) {
24570        text = API.processArabic(text);
24571      }
24572
24573      if (typeof font.metadata.widthOfString === "function") {
24574        result = font.metadata.widthOfString(text, fontSize, charSpace) / fontSize;
24575      } else {
24576        result = getCharWidthsArray.apply(this, arguments).reduce(function (pv, cv) {
24577          return pv + cv;
24578        }, 0);
24579      }
24580
24581      return result;
24582    };
24583    /**
24584    returns array of lines
24585    */
24586
24587
24588    var splitLongWord = function splitLongWord(word, widths_array, firstLineMaxLen, maxLen) {
24589      var answer = []; // 1st, chop off the piece that can fit on the hanging line.
24590
24591      var i = 0,
24592          l = word.length,
24593          workingLen = 0;
24594
24595      while (i !== l && workingLen + widths_array[i] < firstLineMaxLen) {
24596        workingLen += widths_array[i];
24597        i++;
24598      } // this is first line.
24599
24600
24601      answer.push(word.slice(0, i)); // 2nd. Split the rest into maxLen pieces.
24602
24603      var startOfLine = i;
24604      workingLen = 0;
24605
24606      while (i !== l) {
24607        if (workingLen + widths_array[i] > maxLen) {
24608          answer.push(word.slice(startOfLine, i));
24609          workingLen = 0;
24610          startOfLine = i;
24611        }
24612
24613        workingLen += widths_array[i];
24614        i++;
24615      }
24616
24617      if (startOfLine !== i) {
24618        answer.push(word.slice(startOfLine, i));
24619      }
24620
24621      return answer;
24622    }; // Note, all sizing inputs for this function must be in "font measurement units"
24623    // By default, for PDF, it's "point".
24624
24625
24626    var splitParagraphIntoLines = function splitParagraphIntoLines(text, maxlen, options) {
24627      // at this time works only on Western scripts, ones with space char
24628      // separating the words. Feel free to expand.
24629      if (!options) {
24630        options = {};
24631      }
24632
24633      var line = [],
24634          lines = [line],
24635          line_length = options.textIndent || 0,
24636          separator_length = 0,
24637          current_word_length = 0,
24638          word,
24639          widths_array,
24640          words = text.split(" "),
24641          spaceCharWidth = getCharWidthsArray.apply(this, [" ", options])[0],
24642          i,
24643          l,
24644          tmp,
24645          lineIndent;
24646
24647      if (options.lineIndent === -1) {
24648        lineIndent = words[0].length + 2;
24649      } else {
24650        lineIndent = options.lineIndent || 0;
24651      }
24652
24653      if (lineIndent) {
24654        var pad = Array(lineIndent).join(" "),
24655            wrds = [];
24656        words.map(function (wrd) {
24657          wrd = wrd.split(/\s*\n/);
24658
24659          if (wrd.length > 1) {
24660            wrds = wrds.concat(wrd.map(function (wrd, idx) {
24661              return (idx && wrd.length ? "\n" : "") + wrd;
24662            }));
24663          } else {
24664            wrds.push(wrd[0]);
24665          }
24666        });
24667        words = wrds;
24668        lineIndent = getStringUnitWidth.apply(this, [pad, options]);
24669      }
24670
24671      for (i = 0, l = words.length; i < l; i++) {
24672        var force = 0;
24673        word = words[i];
24674
24675        if (lineIndent && word[0] == "\n") {
24676          word = word.substr(1);
24677          force = 1;
24678        }
24679
24680        widths_array = getCharWidthsArray.apply(this, [word, options]);
24681        current_word_length = widths_array.reduce(function (pv, cv) {
24682          return pv + cv;
24683        }, 0);
24684
24685        if (line_length + separator_length + current_word_length > maxlen || force) {
24686          if (current_word_length > maxlen) {
24687            // this happens when you have space-less long URLs for example.
24688            // we just chop these to size. We do NOT insert hiphens
24689            tmp = splitLongWord.apply(this, [word, widths_array, maxlen - (line_length + separator_length), maxlen]); // first line we add to existing line object
24690
24691            line.push(tmp.shift()); // it's ok to have extra space indicator there
24692            // last line we make into new line object
24693
24694            line = [tmp.pop()]; // lines in the middle we apped to lines object as whole lines
24695
24696            while (tmp.length) {
24697              lines.push([tmp.shift()]); // single fragment occupies whole line
24698            }
24699
24700            current_word_length = widths_array.slice(word.length - (line[0] ? line[0].length : 0)).reduce(function (pv, cv) {
24701              return pv + cv;
24702            }, 0);
24703          } else {
24704            // just put it on a new line
24705            line = [word];
24706          } // now we attach new line to lines
24707
24708
24709          lines.push(line);
24710          line_length = current_word_length + lineIndent;
24711          separator_length = spaceCharWidth;
24712        } else {
24713          line.push(word);
24714          line_length += separator_length + current_word_length;
24715          separator_length = spaceCharWidth;
24716        }
24717      }
24718
24719      var postProcess;
24720
24721      if (lineIndent) {
24722        postProcess = function postProcess(ln, idx) {
24723          return (idx ? pad : "") + ln.join(" ");
24724        };
24725      } else {
24726        postProcess = function postProcess(ln) {
24727          return ln.join(" ");
24728        };
24729      }
24730
24731      return lines.map(postProcess);
24732    };
24733    /**
24734     * Splits a given string into an array of strings. Uses 'size' value
24735     * (in measurement units declared as default for the jsPDF instance)
24736     * and the font's "widths" and "Kerning" tables, where available, to
24737     * determine display length of a given string for a given font.
24738     *
24739     * We use character's 100% of unit size (height) as width when Width
24740     * table or other default width is not available.
24741     *
24742     * @name splitTextToSize
24743     * @public
24744     * @function
24745     * @param {string} text Unencoded, regular JavaScript (Unicode, UTF-16 / UCS-2) string.
24746     * @param {number} size Nominal number, measured in units default to this instance of jsPDF.
24747     * @param {Object} options Optional flags needed for chopper to do the right thing.
24748     * @returns {Array} array Array with strings chopped to size.
24749     */
24750
24751
24752    API.splitTextToSize = function (text, maxlen, options) {
24753
24754      options = options || {};
24755
24756      var fsize = options.fontSize || this.internal.getFontSize(),
24757          newOptions = function (options) {
24758        var widths = {
24759          0: 1
24760        },
24761            kerning = {};
24762
24763        if (!options.widths || !options.kerning) {
24764          var f = this.internal.getFont(options.fontName, options.fontStyle),
24765              encoding = "Unicode"; // NOT UTF8, NOT UTF16BE/LE, NOT UCS2BE/LE
24766          // Actual JavaScript-native String's 16bit char codes used.
24767          // no multi-byte logic here
24768
24769          if (f.metadata[encoding]) {
24770            return {
24771              widths: f.metadata[encoding].widths || widths,
24772              kerning: f.metadata[encoding].kerning || kerning
24773            };
24774          } else {
24775            return {
24776              font: f.metadata,
24777              fontSize: this.internal.getFontSize(),
24778              charSpace: this.internal.getCharSpace()
24779            };
24780          }
24781        } else {
24782          return {
24783            widths: options.widths,
24784            kerning: options.kerning
24785          };
24786        }
24787      }.call(this, options); // first we split on end-of-line chars
24788
24789
24790      var paragraphs;
24791
24792      if (Array.isArray(text)) {
24793        paragraphs = text;
24794      } else {
24795        paragraphs = String(text).split(/\r?\n/);
24796      } // now we convert size (max length of line) into "font size units"
24797      // at present time, the "font size unit" is always 'point'
24798      // 'proportional' means, "in proportion to font size"
24799
24800
24801      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.
24802      // this may change in the future?
24803      // until then, proportional_maxlen is likely to be in 'points'
24804      // If first line is to be indented (shorter or longer) than maxLen
24805      // we indicate that by using CSS-style "text-indent" option.
24806      // here it's in font units too (which is likely 'points')
24807      // it can be negative (which makes the first line longer than maxLen)
24808
24809      newOptions.textIndent = options.textIndent ? options.textIndent * 1.0 * this.internal.scaleFactor / fsize : 0;
24810      newOptions.lineIndent = options.lineIndent;
24811      var i,
24812          l,
24813          output = [];
24814
24815      for (i = 0, l = paragraphs.length; i < l; i++) {
24816        output = output.concat(splitParagraphIntoLines.apply(this, [paragraphs[i], fontUnit_maxLen, newOptions]));
24817      }
24818
24819      return output;
24820    };
24821  })(jsPDF.API);
24822
24823  /**
24824   * This file adds the standard font metrics to jsPDF.
24825   *
24826   * Font metrics data is reprocessed derivative of contents of
24827   * "Font Metrics for PDF Core 14 Fonts" package, which exhibits the following copyright and license:
24828   *
24829   * Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
24830   *
24831   * This file and the 14 PostScript(R) AFM files it accompanies may be used,
24832   * copied, and distributed for any purpose and without charge, with or without
24833   * modification, provided that all copyright notices are retained; that the AFM
24834   * files are not distributed without this file; that all modifications to this
24835   * file or any of the AFM files are prominently noted in the modified file(s);
24836   * and that this paragraph is not modified. Adobe Systems has no responsibility
24837   * or obligation to support the use of the AFM files.
24838   *
24839   * @name standard_fonts_metrics
24840   * @module
24841   */
24842
24843  (function (API) {
24844
24845    API.__fontmetrics__ = API.__fontmetrics__ || {};
24846    var decoded = "0123456789abcdef",
24847        encoded = "klmnopqrstuvwxyz",
24848        mappingUncompress = {},
24849        mappingCompress = {};
24850
24851    for (var i = 0; i < encoded.length; i++) {
24852      mappingUncompress[encoded[i]] = decoded[i];
24853      mappingCompress[decoded[i]] = encoded[i];
24854    }
24855
24856    var hex = function hex(value) {
24857      return "0x" + parseInt(value, 10).toString(16);
24858    };
24859
24860    var compress = API.__fontmetrics__.compress = function (data) {
24861      var vals = ["{"];
24862      var value, keystring, valuestring, numberprefix;
24863
24864      for (var key in data) {
24865        value = data[key];
24866
24867        if (!isNaN(parseInt(key, 10))) {
24868          key = parseInt(key, 10);
24869          keystring = hex(key).slice(2);
24870          keystring = keystring.slice(0, -1) + mappingCompress[keystring.slice(-1)];
24871        } else {
24872          keystring = "'" + key + "'";
24873        }
24874
24875        if (typeof value == "number") {
24876          if (value < 0) {
24877            valuestring = hex(value).slice(3);
24878            numberprefix = "-";
24879          } else {
24880            valuestring = hex(value).slice(2);
24881            numberprefix = "";
24882          }
24883
24884          valuestring = numberprefix + valuestring.slice(0, -1) + mappingCompress[valuestring.slice(-1)];
24885        } else {
24886          if (_typeof(value) === "object") {
24887            valuestring = compress(value);
24888          } else {
24889            throw new Error("Don't know what to do with value type " + _typeof(value) + ".");
24890          }
24891        }
24892
24893        vals.push(keystring + valuestring);
24894      }
24895
24896      vals.push("}");
24897      return vals.join("");
24898    };
24899    /**
24900     * Uncompresses data compressed into custom, base16-like format.
24901     *
24902     * @public
24903     * @function
24904     * @param
24905     * @returns {Type}
24906     */
24907
24908
24909    var uncompress = API.__fontmetrics__.uncompress = function (data) {
24910      if (typeof data !== "string") {
24911        throw new Error("Invalid argument passed to uncompress.");
24912      }
24913
24914      var output = {},
24915          sign = 1,
24916          stringparts,
24917          // undef. will be [] in string mode
24918      activeobject = output,
24919          parentchain = [],
24920          parent_key_pair,
24921          keyparts = "",
24922          valueparts = "",
24923          key,
24924          // undef. will be Truthy when Key is resolved.
24925      datalen = data.length - 1,
24926          // stripping ending }
24927      ch;
24928
24929      for (var i = 1; i < datalen; i += 1) {
24930        // - { } ' are special.
24931        ch = data[i];
24932
24933        if (ch == "'") {
24934          if (stringparts) {
24935            // end of string mode
24936            key = stringparts.join("");
24937            stringparts = undefined;
24938          } else {
24939            // start of string mode
24940            stringparts = [];
24941          }
24942        } else if (stringparts) {
24943          stringparts.push(ch);
24944        } else if (ch == "{") {
24945          // start of object
24946          parentchain.push([activeobject, key]);
24947          activeobject = {};
24948          key = undefined;
24949        } else if (ch == "}") {
24950          // end of object
24951          parent_key_pair = parentchain.pop();
24952          parent_key_pair[0][parent_key_pair[1]] = activeobject;
24953          key = undefined;
24954          activeobject = parent_key_pair[0];
24955        } else if (ch == "-") {
24956          sign = -1;
24957        } else {
24958          // must be number
24959          if (key === undefined) {
24960            if (mappingUncompress.hasOwnProperty(ch)) {
24961              keyparts += mappingUncompress[ch];
24962              key = parseInt(keyparts, 16) * sign;
24963              sign = +1;
24964              keyparts = "";
24965            } else {
24966              keyparts += ch;
24967            }
24968          } else {
24969            if (mappingUncompress.hasOwnProperty(ch)) {
24970              valueparts += mappingUncompress[ch];
24971              activeobject[key] = parseInt(valueparts, 16) * sign;
24972              sign = +1;
24973              key = undefined;
24974              valueparts = "";
24975            } else {
24976              valueparts += ch;
24977            }
24978          }
24979        }
24980      }
24981
24982      return output;
24983    }; // encoding = 'Unicode'
24984    // NOT UTF8, NOT UTF16BE/LE, NOT UCS2BE/LE. NO clever BOM behavior
24985    // Actual 16bit char codes used.
24986    // no multi-byte logic here
24987    // Unicode characters to WinAnsiEncoding:
24988    // {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}
24989    // as you can see, all Unicode chars are outside of 0-255 range. No char code conflicts.
24990    // this means that you can give Win cp1252 encoded strings to jsPDF for rendering directly
24991    // as well as give strings with some (supported by these fonts) Unicode characters and
24992    // these will be mapped to win cp1252
24993    // for example, you can send char code (cp1252) 0x80 or (unicode) 0x20AC, getting "Euro" glyph displayed in both cases.
24994
24995
24996    var encodingBlock = {
24997      codePages: ["WinAnsiEncoding"],
24998      WinAnsiEncoding: uncompress("{19m8n201n9q201o9r201s9l201t9m201u8m201w9n201x9o201y8o202k8q202l8r202m9p202q8p20aw8k203k8t203t8v203u9v2cq8s212m9t15m8w15n9w2dw9s16k8u16l9u17s9z17x8y17y9y}")
24999    };
25000    var encodings = {
25001      Unicode: {
25002        Courier: encodingBlock,
25003        "Courier-Bold": encodingBlock,
25004        "Courier-BoldOblique": encodingBlock,
25005        "Courier-Oblique": encodingBlock,
25006        Helvetica: encodingBlock,
25007        "Helvetica-Bold": encodingBlock,
25008        "Helvetica-BoldOblique": encodingBlock,
25009        "Helvetica-Oblique": encodingBlock,
25010        "Times-Roman": encodingBlock,
25011        "Times-Bold": encodingBlock,
25012        "Times-BoldItalic": encodingBlock,
25013        "Times-Italic": encodingBlock //	, 'Symbol'
25014        //	, 'ZapfDingbats'
25015
25016      }
25017    };
25018    var fontMetrics = {
25019      Unicode: {
25020        // all sizing numbers are n/fontMetricsFractionOf = one font size unit
25021        // this means that if fontMetricsFractionOf = 1000, and letter A's width is 476, it's
25022        // width is 476/1000 or 47.6% of its height (regardless of font size)
25023        // At this time this value applies to "widths" and "kerning" numbers.
25024        // char code 0 represents "default" (average) width - use it for chars missing in this table.
25025        // key 'fof' represents the "fontMetricsFractionOf" value
vendor: 14,961 bytes, lines 25025-25041
25025
25026        "Courier-Oblique": uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
25027        "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}}}"),
25028        "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}}}"),
25029        Courier: uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
25030        "Courier-BoldOblique": uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
25031        "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}}}"),
25032        Symbol: uncompress("{'widths'{k3uaw4r19m3m2k1t2l2l202m2y2n3m2p5n202q6o3k3m2s2l2t2l2v3r2w1t3m3m2y1t2z1wbk2sbl3r'fof'6o3n3m3o3m3p3m3q3m3r3m3s3m3t3m3u1w3v1w3w3r3x3r3y3r3z2wbp3t3l3m5v2l5x2l5z3m2q4yfr3r7v3k7w1o7x3k}'kerning'{'fof'-6o}}"),
25033        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}}}"),
25034        "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}}}"),
25035        ZapfDingbats: uncompress("{'widths'{k4u2k1w'fof'6o}'kerning'{'fof'-6o}}"),
25036        "Courier-Bold": uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
25037        "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}}}"),
25038        "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}}}"),
25039        "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}}}")
25040      }
25041    };
vendor: 4,228 bytes, lines 25042-25184
25042    /*
25043    This event handler is fired when a new jsPDF object is initialized
25044    This event handler appends metrics data to standard fonts within
25045    that jsPDF instance. The metrics are mapped over Unicode character
25046    codes, NOT CIDs or other codes matching the StandardEncoding table of the
25047    standard PDF fonts.
25048    Future:
25049    Also included is the encoding maping table, converting Unicode (UCS-2, UTF-16)
25050    char codes to StandardEncoding character codes. The encoding table is to be used
25051    somewhere around "pdfEscape" call.
25052    */
25053
25054    API.events.push(["addFont", function (data) {
25055      var font = data.font;
25056      var metrics = fontMetrics["Unicode"][font.postScriptName];
25057
25058      if (metrics) {
25059        font.metadata["Unicode"] = {};
25060        font.metadata["Unicode"].widths = metrics.widths;
25061        font.metadata["Unicode"].kerning = metrics.kerning;
25062      }
25063
25064      var encodingBlock = encodings["Unicode"][font.postScriptName];
25065
25066      if (encodingBlock) {
25067        font.metadata["Unicode"].encoding = encodingBlock;
25068        font.encoding = encodingBlock.codePages[0];
25069      }
25070    }]); // end of adding event handler
25071  })(jsPDF.API);
25072
25073  /**
25074   * @license
25075   * Licensed under the MIT License.
25076   * http://opensource.org/licenses/mit-license
25077   */
25078  /**
25079   * @name ttfsupport
25080   * @module
25081   */
25082
25083  (function (jsPDF) {
25084
25085    var binaryStringToUint8Array = function binaryStringToUint8Array(binary_string) {
25086      var len = binary_string.length;
25087      var bytes = new Uint8Array(len);
25088
25089      for (var i = 0; i < len; i++) {
25090        bytes[i] = binary_string.charCodeAt(i);
25091      }
25092
25093      return bytes;
25094    };
25095
25096    var addFont = function addFont(font, file) {
25097      // eslint-disable-next-line no-control-regex
25098      if (/^\x00\x01\x00\x00/.test(file)) {
25099        file = binaryStringToUint8Array(file);
25100      } else {
25101        file = binaryStringToUint8Array(atob(file));
25102      }
25103
25104      font.metadata = jsPDF.API.TTFFont.open(file);
25105      font.metadata.Unicode = font.metadata.Unicode || {
25106        encoding: {},
25107        kerning: {},
25108        widths: []
25109      };
25110      font.metadata.glyIdsUsed = [0];
25111    };
25112
25113    jsPDF.API.events.push(["addFont", function (data) {
25114      var file = undefined;
25115      var font = data.font;
25116      var instance = data.instance;
25117
25118      if (font.isStandardFont) {
25119        return;
25120      }
25121
25122      if (typeof instance !== "undefined") {
25123        if (instance.existsFileInVFS(font.postScriptName) === false) {
25124          file = instance.loadFile(font.postScriptName);
25125        } else {
25126          file = instance.getFileFromVFS(font.postScriptName);
25127        }
25128
25129        if (typeof file !== "string") {
25130          throw new Error("Font is not stored as string-data in vFS, import fonts or remove declaration doc.addFont('" + font.postScriptName + "').");
25131        }
25132
25133        addFont(font, file);
25134      } else {
25135        throw new Error("Font does not exist in vFS, import fonts or remove declaration doc.addFont('" + font.postScriptName + "').");
25136      }
25137    }]); // end of adding event handler
25138  })(jsPDF);
25139
25140  /**
25141   * jsPDF SVG plugin
25142   *
25143   * @name svg
25144   * @module
25145   */
25146
25147  (function (jsPDFAPI) {
25148
25149    function loadCanvg() {
25150      return function () {
25151        if (globalObject["canvg"]) {
25152          return Promise.resolve(globalObject["canvg"]);
25153        }
25154
25155        if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object" && typeof module !== "undefined") {
25156          return new Promise(function (resolve, reject) {
25157            try {
25158              resolve(require("canvg"));
25159            } catch (e) {
25160              reject(e);
25161            }
25162          });
25163        }
25164
25165        if (typeof define === "function" && define.amd) {
25166          return new Promise(function (resolve, reject) {
25167            try {
25168              require(["canvg"], resolve);
25169            } catch (e) {
25170              reject(e);
25171            }
25172          });
25173        }
25174
25175        return Promise.reject(new Error("Could not load canvg"));
25176      }().catch(function (e) {
25177        return Promise.reject(new Error("Could not load canvg: " + e));
25178      }).then(function (canvg) {
25179        return canvg.default ? canvg.default : canvg;
25180      });
25181    }
25182    /**
25183     * Parses SVG XML and saves it as image into the PDF.
25184     *
25185     * Depends on canvas-element and canvg
25186     *
25187     * @name addSvgAsImage
25188     * @public
25189     * @function
25190     * @param {string} SVG-Data as Text
25191     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
25192     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
25193     * @param {number} width of SVG-Image (in units declared at inception of PDF document)
25194     * @param {number} height of SVG-Image (in units declared at inception of PDF document)
25195     * @param {string} alias of SVG-Image (if used multiple times)
25196     * @param {string} compression of the generated JPEG, can have the values 'NONE', 'FAST', 'MEDIUM' and 'SLOW'
25197     * @param {number} rotation of the image in degrees (0-359)
25198     *
25199     * @returns jsPDF jsPDF-instance
25200     */
25201
25202
25203    jsPDFAPI.addSvgAsImage = function (svg, x, y, w, h, alias, compression, rotation) {
25204      if (isNaN(x) || isNaN(y)) {
25205        console.error("jsPDF.addSvgAsImage: Invalid coordinates", arguments);
25206        throw new Error("Invalid coordinates passed to jsPDF.addSvgAsImage");
25207      }
25208
25209      if (isNaN(w) || isNaN(h)) {
25210        console.error("jsPDF.addSvgAsImage: Invalid measurements", arguments);
25211        throw new Error("Invalid measurements (width and/or height) passed to jsPDF.addSvgAsImage");
25212      }
25213
25214      var canvas = document.createElement("canvas");
25215      canvas.width = w;
25216      canvas.height = h;
25217      var ctx = canvas.getContext("2d");
25218      ctx.fillStyle = "#fff"; /// set white fill style
25219
25220      ctx.fillRect(0, 0, canvas.width, canvas.height);
25221      var options = {
25222        ignoreMouse: true,
25223        ignoreAnimation: true,
25224        ignoreDimensions: true
25225      };
25226      var doc = this;
25227      return loadCanvg().then(function (canvg) {
25228        return canvg.fromString(ctx, svg, options);
25229      }, function () {
25230        return Promise.reject(new Error("Could not load canvg."));
25231      }).then(function (instance) {
25232        return instance.render(options);
25233      }).then(function () {
25234        doc.addImage(canvas.toDataURL("image/jpeg", 1.0), x, y, w, h, compression, rotation);
25235      });
25236    };
25237  })(jsPDF.API);
25238
25239  /**
25240   * @license
25241   * ====================================================================
25242   * Copyright (c) 2013 Eduardo Menezes de Morais, [email protected]
25243   *
25244   * Permission is hereby granted, free of charge, to any person obtaining
25245   * a copy of this software and associated documentation files (the
25246   * "Software"), to deal in the Software without restriction, including
25247   * without limitation the rights to use, copy, modify, merge, publish,
25248   * distribute, sublicense, and/or sell copies of the Software, and to
25249   * permit persons to whom the Software is furnished to do so, subject to
25250   * the following conditions:
25251   *
25252   * The above copyright notice and this permission notice shall be
25253   * included in all copies or substantial portions of the Software.
25254   *
25255   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25256   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25257   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25258   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25259   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25260   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25261   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25262   * ====================================================================
25263   */
25264  /**
25265   * jsPDF total_pages plugin
25266   * @name total_pages
25267   * @module
25268   */
25269
25270  (function (jsPDFAPI) {
25271    /**
25272     * @name putTotalPages
25273     * @function
25274     * @param {string} pageExpression Regular Expression
25275     * @returns {jsPDF} jsPDF-instance
25276     */
25277
25278    jsPDFAPI.putTotalPages = function (pageExpression) {
25279
25280      var replaceExpression;
25281      var totalNumberOfPages = 0;
25282
25283      if (parseInt(this.internal.getFont().id.substr(1), 10) < 15) {
25284        replaceExpression = new RegExp(pageExpression, "g");
25285        totalNumberOfPages = this.internal.getNumberOfPages();
25286      } else {
25287        replaceExpression = new RegExp(this.pdfEscape16(pageExpression, this.internal.getFont()), "g");
25288        totalNumberOfPages = this.pdfEscape16(this.internal.getNumberOfPages() + "", this.internal.getFont());
25289      }
25290
25291      for (var n = 1; n <= this.internal.getNumberOfPages(); n++) {
25292        for (var i = 0; i < this.internal.pages[n].length; i++) {
25293          this.internal.pages[n][i] = this.internal.pages[n][i].replace(replaceExpression, totalNumberOfPages);
25294        }
25295      }
25296
25297      return this;
25298    };
25299  })(jsPDF.API);
25300
25301  /**
25302   * Adds the ability to set ViewerPreferences and by thus
25303   * controlling the way the document is to be presented on the
25304   * screen or in print.
25305   * @name viewerpreferences
25306   * @module
25307   */
25308
25309  (function (jsPDFAPI) {
25310    /**
25311     * Set the ViewerPreferences of the generated PDF
25312     *
25313     * @name viewerPreferences
25314     * @function
25315     * @public
25316     * @param {Object} options Array with the ViewerPreferences<br />
25317     * Example: doc.viewerPreferences({"FitWindow":true});<br />
25318     * <br />
25319     * You can set following preferences:<br />
25320     * <br/>
25321     * <b>HideToolbar</b> <i>(boolean)</i><br />
25322     * Default value: false<br />
25323     * <br />
25324     * <b>HideMenubar</b> <i>(boolean)</i><br />
25325     * Default value: false.<br />
25326     * <br />
25327     * <b>HideWindowUI</b> <i>(boolean)</i><br />
25328     * Default value: false.<br />
25329     * <br />
25330     * <b>FitWindow</b> <i>(boolean)</i><br />
25331     * Default value: false.<br />
25332     * <br />
25333     * <b>CenterWindow</b> <i>(boolean)</i><br />
25334     * Default value: false<br />
25335     * <br />
25336     * <b>DisplayDocTitle</b> <i>(boolean)</i><br />
25337     * Default value: false.<br />
25338     * <br />
25339     * <b>NonFullScreenPageMode</b> <i>(string)</i><br />
25340     * Possible values: UseNone, UseOutlines, UseThumbs, UseOC<br />
25341     * Default value: UseNone<br/>
25342     * <br />
25343     * <b>Direction</b> <i>(string)</i><br />
25344     * Possible values: L2R, R2L<br />
25345     * Default value: L2R.<br />
25346     * <br />
25347     * <b>ViewArea</b> <i>(string)</i><br />
25348     * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
25349     * Default value: CropBox.<br />
25350     * <br />
25351     * <b>ViewClip</b> <i>(string)</i><br />
25352     * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
25353     * Default value: CropBox<br />
25354     * <br />
25355     * <b>PrintArea</b> <i>(string)</i><br />
25356     * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
25357     * Default value: CropBox<br />
25358     * <br />
25359     * <b>PrintClip</b> <i>(string)</i><br />
25360     * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
25361     * Default value: CropBox.<br />
25362     * <br />
25363     * <b>PrintScaling</b> <i>(string)</i><br />
25364     * Possible values: AppDefault, None<br />
25365     * Default value: AppDefault.<br />
25366     * <br />
25367     * <b>Duplex</b> <i>(string)</i><br />
25368     * Possible values: Simplex, DuplexFlipLongEdge, DuplexFlipShortEdge
25369     * Default value: none<br />
25370     * <br />
25371     * <b>PickTrayByPDFSize</b> <i>(boolean)</i><br />
25372     * Default value: false<br />
25373     * <br />
25374     * <b>PrintPageRange</b> <i>(Array)</i><br />
25375     * Example: [[1,5], [7,9]]<br />
25376     * Default value: as defined by PDF viewer application<br />
25377     * <br />
25378     * <b>NumCopies</b> <i>(Number)</i><br />
25379     * Possible values: 1, 2, 3, 4, 5<br />
25380     * Default value: 1<br />
25381     * <br />
25382     * For more information see the PDF Reference, sixth edition on Page 577
25383     * @param {boolean} doReset True to reset the settings
25384     * @function
25385     * @returns jsPDF jsPDF-instance
25386     * @example
25387     * var doc = new jsPDF()
25388     * doc.text('This is a test', 10, 10)
25389     * doc.viewerPreferences({'FitWindow': true}, true)
25390     * doc.save("viewerPreferences.pdf")
25391     *
25392     * // Example printing 10 copies, using cropbox, and hiding UI.
25393     * doc.viewerPreferences({
25394     *   'HideWindowUI': true,
25395     *   'PrintArea': 'CropBox',
25396     *   'NumCopies': 10
25397     * })
25398     */
25399
25400    jsPDFAPI.viewerPreferences = function (options, doReset) {
25401      options = options || {};
25402      doReset = doReset || false;
25403      var configuration;
25404      var configurationTemplate = {
25405        HideToolbar: {
25406          defaultValue: false,
25407          value: false,
25408          type: "boolean",
25409          explicitSet: false,
25410          valueSet: [true, false],
25411          pdfVersion: 1.3
25412        },
25413        HideMenubar: {
25414          defaultValue: false,
25415          value: false,
25416          type: "boolean",
25417          explicitSet: false,
25418          valueSet: [true, false],
25419          pdfVersion: 1.3
25420        },
25421        HideWindowUI: {
25422          defaultValue: false,
25423          value: false,
25424          type: "boolean",
25425          explicitSet: false,
25426          valueSet: [true, false],
25427          pdfVersion: 1.3
25428        },
25429        FitWindow: {
25430          defaultValue: false,
25431          value: false,
25432          type: "boolean",
25433          explicitSet: false,
25434          valueSet: [true, false],
25435          pdfVersion: 1.3
25436        },
25437        CenterWindow: {
25438          defaultValue: false,
25439          value: false,
25440          type: "boolean",
25441          explicitSet: false,
25442          valueSet: [true, false],
25443          pdfVersion: 1.3
25444        },
25445        DisplayDocTitle: {
25446          defaultValue: false,
25447          value: false,
25448          type: "boolean",
25449          explicitSet: false,
25450          valueSet: [true, false],
25451          pdfVersion: 1.4
25452        },
25453        NonFullScreenPageMode: {
25454          defaultValue: "UseNone",
25455          value: "UseNone",
25456          type: "name",
25457          explicitSet: false,
25458          valueSet: ["UseNone", "UseOutlines", "UseThumbs", "UseOC"],
25459          pdfVersion: 1.3
25460        },
25461        Direction: {
25462          defaultValue: "L2R",
25463          value: "L2R",
25464          type: "name",
25465          explicitSet: false,
25466          valueSet: ["L2R", "R2L"],
25467          pdfVersion: 1.3
25468        },
25469        ViewArea: {
25470          defaultValue: "CropBox",
25471          value: "CropBox",
25472          type: "name",
25473          explicitSet: false,
25474          valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"],
25475          pdfVersion: 1.4
25476        },
25477        ViewClip: {
25478          defaultValue: "CropBox",
25479          value: "CropBox",
25480          type: "name",
25481          explicitSet: false,
25482          valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"],
25483          pdfVersion: 1.4
25484        },
25485        PrintArea: {
25486          defaultValue: "CropBox",
25487          value: "CropBox",
25488          type: "name",
25489          explicitSet: false,
25490          valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"],
25491          pdfVersion: 1.4
25492        },
25493        PrintClip: {
25494          defaultValue: "CropBox",
25495          value: "CropBox",
25496          type: "name",
25497          explicitSet: false,
25498          valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"],
25499          pdfVersion: 1.4
25500        },
25501        PrintScaling: {
25502          defaultValue: "AppDefault",
25503          value: "AppDefault",
25504          type: "name",
25505          explicitSet: false,
25506          valueSet: ["AppDefault", "None"],
25507          pdfVersion: 1.6
25508        },
25509        Duplex: {
25510          defaultValue: "",
25511          value: "none",
25512          type: "name",
25513          explicitSet: false,
25514          valueSet: ["Simplex", "DuplexFlipShortEdge", "DuplexFlipLongEdge", "none"],
25515          pdfVersion: 1.7
25516        },
25517        PickTrayByPDFSize: {
25518          defaultValue: false,
25519          value: false,
25520          type: "boolean",
25521          explicitSet: false,
25522          valueSet: [true, false],
25523          pdfVersion: 1.7
25524        },
25525        PrintPageRange: {
25526          defaultValue: "",
25527          value: "",
25528          type: "array",
25529          explicitSet: false,
25530          valueSet: null,
25531          pdfVersion: 1.7
25532        },
25533        NumCopies: {
25534          defaultValue: 1,
25535          value: 1,
25536          type: "integer",
25537          explicitSet: false,
25538          valueSet: null,
25539          pdfVersion: 1.7
25540        }
25541      };
25542      var configurationKeys = Object.keys(configurationTemplate);
25543      var rangeArray = [];
25544      var i = 0;
25545      var j = 0;
25546      var k = 0;
25547      var isValid;
25548      var method;
25549      var value;
25550
25551      function arrayContainsElement(array, element) {
25552        var iterator;
25553        var result = false;
vendor: 20,374 bytes, lines 25554-26129
25554
25555        for (iterator = 0; iterator < array.length; iterator += 1) {
25556          if (array[iterator] === element) {
25557            result = true;
25558          }
25559        }
25560
25561        return result;
25562      }
25563
25564      if (this.internal.viewerpreferences === undefined) {
25565        this.internal.viewerpreferences = {};
25566        this.internal.viewerpreferences.configuration = JSON.parse(JSON.stringify(configurationTemplate));
25567        this.internal.viewerpreferences.isSubscribed = false;
25568      }
25569
25570      configuration = this.internal.viewerpreferences.configuration;
25571
25572      if (options === "reset" || doReset === true) {
25573        var len = configurationKeys.length;
25574
25575        for (k = 0; k < len; k += 1) {
25576          configuration[configurationKeys[k]].value = configuration[configurationKeys[k]].defaultValue;
25577          configuration[configurationKeys[k]].explicitSet = false;
25578        }
25579      }
25580
25581      if (_typeof(options) === "object") {
25582        for (method in options) {
25583          value = options[method];
25584
25585          if (arrayContainsElement(configurationKeys, method) && value !== undefined) {
25586            if (configuration[method].type === "boolean" && typeof value === "boolean") {
25587              configuration[method].value = value;
25588            } else if (configuration[method].type === "name" && arrayContainsElement(configuration[method].valueSet, value)) {
25589              configuration[method].value = value;
25590            } else if (configuration[method].type === "integer" && Number.isInteger(value)) {
25591              configuration[method].value = value;
25592            } else if (configuration[method].type === "array") {
25593              for (i = 0; i < value.length; i += 1) {
25594                isValid = true;
25595
25596                if (value[i].length === 1 && typeof value[i][0] === "number") {
25597                  rangeArray.push(String(value[i] - 1));
25598                } else if (value[i].length > 1) {
25599                  for (j = 0; j < value[i].length; j += 1) {
25600                    if (typeof value[i][j] !== "number") {
25601                      isValid = false;
25602                    }
25603                  }
25604
25605                  if (isValid === true) {
25606                    rangeArray.push([value[i][0] - 1, value[i][1] - 1].join(" "));
25607                  }
25608                }
25609              }
25610
25611              configuration[method].value = "[" + rangeArray.join(" ") + "]";
25612            } else {
25613              configuration[method].value = configuration[method].defaultValue;
25614            }
25615
25616            configuration[method].explicitSet = true;
25617          }
25618        }
25619      }
25620
25621      if (this.internal.viewerpreferences.isSubscribed === false) {
25622        this.internal.events.subscribe("putCatalog", function () {
25623          var pdfDict = [];
25624          var vPref;
25625
25626          for (vPref in configuration) {
25627            if (configuration[vPref].explicitSet === true) {
25628              if (configuration[vPref].type === "name") {
25629                pdfDict.push("/" + vPref + " /" + configuration[vPref].value);
25630              } else {
25631                pdfDict.push("/" + vPref + " " + configuration[vPref].value);
25632              }
25633            }
25634          }
25635
25636          if (pdfDict.length !== 0) {
25637            this.internal.write("/ViewerPreferences\n<<\n" + pdfDict.join("\n") + "\n>>");
25638          }
25639        });
25640        this.internal.viewerpreferences.isSubscribed = true;
25641      }
25642
25643      this.internal.viewerpreferences.configuration = configuration;
25644      return this;
25645    };
25646  })(jsPDF.API);
25647
25648  /** ====================================================================
25649   * @license
25650   * jsPDF XMP metadata plugin
25651   * Copyright (c) 2016 Jussi Utunen, [email protected]
25652   *
25653   * Permission is hereby granted, free of charge, to any person obtaining
25654   * a copy of this software and associated documentation files (the
25655   * "Software"), to deal in the Software without restriction, including
25656   * without limitation the rights to use, copy, modify, merge, publish,
25657   * distribute, sublicense, and/or sell copies of the Software, and to
25658   * permit persons to whom the Software is furnished to do so, subject to
25659   * the following conditions:
25660   *
25661   * The above copyright notice and this permission notice shall be
25662   * included in all copies or substantial portions of the Software.
25663   *
25664   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25665   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25666   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25667   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25668   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25669   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25670   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25671   * ====================================================================
25672   */
25673  /**
25674   * @name xmp_metadata
25675   * @module
25676   */
25677
25678  (function (jsPDFAPI) {
25679
25680    var postPutResources = function postPutResources() {
25681      var xmpmeta_beginning = '<x:xmpmeta xmlns:x="adobe:ns:meta/">';
25682      var rdf_beginning = '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:jspdf="' + this.internal.__metadata__.namespaceuri + '"><jspdf:metadata>';
25683      var rdf_ending = "</jspdf:metadata></rdf:Description></rdf:RDF>";
25684      var xmpmeta_ending = "</x:xmpmeta>";
25685      var utf8_xmpmeta_beginning = unescape(encodeURIComponent(xmpmeta_beginning));
25686      var utf8_rdf_beginning = unescape(encodeURIComponent(rdf_beginning));
25687      var utf8_metadata = unescape(encodeURIComponent(this.internal.__metadata__.metadata));
25688      var utf8_rdf_ending = unescape(encodeURIComponent(rdf_ending));
25689      var utf8_xmpmeta_ending = unescape(encodeURIComponent(xmpmeta_ending));
25690      var total_len = utf8_rdf_beginning.length + utf8_metadata.length + utf8_rdf_ending.length + utf8_xmpmeta_beginning.length + utf8_xmpmeta_ending.length;
25691      this.internal.__metadata__.metadata_object_number = this.internal.newObject();
25692      this.internal.write("<< /Type /Metadata /Subtype /XML /Length " + total_len + " >>");
25693      this.internal.write("stream");
25694      this.internal.write(utf8_xmpmeta_beginning + utf8_rdf_beginning + utf8_metadata + utf8_rdf_ending + utf8_xmpmeta_ending);
25695      this.internal.write("endstream");
25696      this.internal.write("endobj");
25697    };
25698
25699    var putCatalog = function putCatalog() {
25700      if (this.internal.__metadata__.metadata_object_number) {
25701        this.internal.write("/Metadata " + this.internal.__metadata__.metadata_object_number + " 0 R");
25702      }
25703    };
25704    /**
25705     * Adds XMP formatted metadata to PDF
25706     *
25707     * @name addMetadata
25708     * @function
25709     * @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.
25710     * @param {String} namespaceuri Sets the namespace URI for the metadata. Last character should be slash or hash.
25711     * @returns {jsPDF} jsPDF-instance
25712     */
25713
25714
25715    jsPDFAPI.addMetadata = function (metadata, namespaceuri) {
25716      if (typeof this.internal.__metadata__ === "undefined") {
25717        this.internal.__metadata__ = {
25718          metadata: metadata,
25719          namespaceuri: namespaceuri || "http://jspdf.default.namespaceuri/"
25720        };
25721        this.internal.events.subscribe("putCatalog", putCatalog);
25722        this.internal.events.subscribe("postPutResources", postPutResources);
25723      }
25724
25725      return this;
25726    };
25727  })(jsPDF.API);
25728
25729  /**
25730   * @name utf8
25731   * @module
25732   */
25733
25734  (function (jsPDF) {
25735
25736    var jsPDFAPI = jsPDF.API;
25737    /***************************************************************************************************/
25738
25739    /* function : pdfEscape16                                                                          */
25740
25741    /* comment : The character id of a 2-byte string is converted to a hexadecimal number by obtaining */
25742
25743    /*   the corresponding glyph id and width, and then adding padding to the string.                  */
25744
25745    /***************************************************************************************************/
25746
25747    var pdfEscape16 = jsPDFAPI.pdfEscape16 = function (text, font) {
25748      var widths = font.metadata.Unicode.widths;
25749      var padz = ["", "0", "00", "000", "0000"];
25750      var ar = [""];
25751
25752      for (var i = 0, l = text.length, t; i < l; ++i) {
25753        t = font.metadata.characterToGlyph(text.charCodeAt(i));
25754        font.metadata.glyIdsUsed.push(t);
25755        font.metadata.toUnicode[t] = text.charCodeAt(i);
25756
25757        if (widths.indexOf(t) == -1) {
25758          widths.push(t);
25759          widths.push([parseInt(font.metadata.widthOfGlyph(t), 10)]);
25760        }
25761
25762        if (t == "0") {
25763          //Spaces are not allowed in cmap.
25764          return ar.join("");
25765        } else {
25766          t = t.toString(16);
25767          ar.push(padz[4 - t.length], t);
25768        }
25769      }
25770
25771      return ar.join("");
25772    };
25773
25774    var toUnicodeCmap = function toUnicodeCmap(map) {
25775      var code, codes, range, unicode, unicodeMap, _i, _len;
25776
25777      unicodeMap = "/CIDInit /ProcSet findresource begin\n12 dict begin\nbegincmap\n/CIDSystemInfo <<\n  /Registry (Adobe)\n  /Ordering (UCS)\n  /Supplement 0\n>> def\n/CMapName /Adobe-Identity-UCS def\n/CMapType 2 def\n1 begincodespacerange\n<0000><ffff>\nendcodespacerange";
25778      codes = Object.keys(map).sort(function (a, b) {
25779        return a - b;
25780      });
25781      range = [];
25782
25783      for (_i = 0, _len = codes.length; _i < _len; _i++) {
25784        code = codes[_i];
25785
25786        if (range.length >= 100) {
25787          unicodeMap += "\n" + range.length + " beginbfchar\n" + range.join("\n") + "\nendbfchar";
25788          range = [];
25789        }
25790
25791        if (map[code] !== undefined && map[code] !== null && typeof map[code].toString === "function") {
25792          unicode = ("0000" + map[code].toString(16)).slice(-4);
25793          code = ("0000" + (+code).toString(16)).slice(-4);
25794          range.push("<" + code + "><" + unicode + ">");
25795        }
25796      }
25797
25798      if (range.length) {
25799        unicodeMap += "\n" + range.length + " beginbfchar\n" + range.join("\n") + "\nendbfchar\n";
25800      }
25801
25802      unicodeMap += "endcmap\nCMapName currentdict /CMap defineresource pop\nend\nend";
25803      return unicodeMap;
25804    };
25805
25806    var identityHFunction = function identityHFunction(options) {
25807      var font = options.font;
25808      var out = options.out;
25809      var newObject = options.newObject;
25810      var putStream = options.putStream;
25811
25812      if (font.metadata instanceof jsPDF.API.TTFFont && font.encoding === "Identity-H") {
25813        //Tag with Identity-H
25814        var widths = font.metadata.Unicode.widths;
25815        var data = font.metadata.subset.encode(font.metadata.glyIdsUsed, 1);
25816        var pdfOutput = data;
25817        var pdfOutput2 = "";
25818
25819        for (var i = 0; i < pdfOutput.length; i++) {
25820          pdfOutput2 += String.fromCharCode(pdfOutput[i]);
25821        }
25822
25823        var fontTable = newObject();
25824        putStream({
25825          data: pdfOutput2,
25826          addLength1: true,
25827          objectId: fontTable
25828        });
25829        out("endobj");
25830        var cmap = newObject();
25831        var cmapData = toUnicodeCmap(font.metadata.toUnicode);
25832        putStream({
25833          data: cmapData,
25834          addLength1: true,
25835          objectId: cmap
25836        });
25837        out("endobj");
25838        var fontDescriptor = newObject();
25839        out("<<");
25840        out("/Type /FontDescriptor");
25841        out("/FontName /" + toPDFName(font.fontName));
25842        out("/FontFile2 " + fontTable + " 0 R");
25843        out("/FontBBox " + jsPDF.API.PDFObject.convert(font.metadata.bbox));
25844        out("/Flags " + font.metadata.flags);
25845        out("/StemV " + font.metadata.stemV);
25846        out("/ItalicAngle " + font.metadata.italicAngle);
25847        out("/Ascent " + font.metadata.ascender);
25848        out("/Descent " + font.metadata.decender);
25849        out("/CapHeight " + font.metadata.capHeight);
25850        out(">>");
25851        out("endobj");
25852        var DescendantFont = newObject();
25853        out("<<");
25854        out("/Type /Font");
25855        out("/BaseFont /" + toPDFName(font.fontName));
25856        out("/FontDescriptor " + fontDescriptor + " 0 R");
25857        out("/W " + jsPDF.API.PDFObject.convert(widths));
25858        out("/CIDToGIDMap /Identity");
25859        out("/DW 1000");
25860        out("/Subtype /CIDFontType2");
25861        out("/CIDSystemInfo");
25862        out("<<");
25863        out("/Supplement 0");
25864        out("/Registry (Adobe)");
25865        out("/Ordering (" + font.encoding + ")");
25866        out(">>");
25867        out(">>");
25868        out("endobj");
25869        font.objectNumber = newObject();
25870        out("<<");
25871        out("/Type /Font");
25872        out("/Subtype /Type0");
25873        out("/ToUnicode " + cmap + " 0 R");
25874        out("/BaseFont /" + toPDFName(font.fontName));
25875        out("/Encoding /" + font.encoding);
25876        out("/DescendantFonts [" + DescendantFont + " 0 R]");
25877        out(">>");
25878        out("endobj");
25879        font.isAlreadyPutted = true;
25880      }
25881    };
25882
25883    jsPDFAPI.events.push(["putFont", function (args) {
25884      identityHFunction(args);
25885    }]);
25886
25887    var winAnsiEncodingFunction = function winAnsiEncodingFunction(options) {
25888      var font = options.font;
25889      var out = options.out;
25890      var newObject = options.newObject;
25891      var putStream = options.putStream;
25892
25893      if (font.metadata instanceof jsPDF.API.TTFFont && font.encoding === "WinAnsiEncoding") {
25894        //Tag with WinAnsi encoding
25895        var data = font.metadata.rawData;
25896        var pdfOutput = data;
25897        var pdfOutput2 = "";
25898
25899        for (var i = 0; i < pdfOutput.length; i++) {
25900          pdfOutput2 += String.fromCharCode(pdfOutput[i]);
25901        }
25902
25903        var fontTable = newObject();
25904        putStream({
25905          data: pdfOutput2,
25906          addLength1: true,
25907          objectId: fontTable
25908        });
25909        out("endobj");
25910        var cmap = newObject();
25911        var cmapData = toUnicodeCmap(font.metadata.toUnicode);
25912        putStream({
25913          data: cmapData,
25914          addLength1: true,
25915          objectId: cmap
25916        });
25917        out("endobj");
25918        var fontDescriptor = newObject();
25919        out("<<");
25920        out("/Descent " + font.metadata.decender);
25921        out("/CapHeight " + font.metadata.capHeight);
25922        out("/StemV " + font.metadata.stemV);
25923        out("/Type /FontDescriptor");
25924        out("/FontFile2 " + fontTable + " 0 R");
25925        out("/Flags 96");
25926        out("/FontBBox " + jsPDF.API.PDFObject.convert(font.metadata.bbox));
25927        out("/FontName /" + toPDFName(font.fontName));
25928        out("/ItalicAngle " + font.metadata.italicAngle);
25929        out("/Ascent " + font.metadata.ascender);
25930        out(">>");
25931        out("endobj");
25932        font.objectNumber = newObject();
25933
25934        for (var j = 0; j < font.metadata.hmtx.widths.length; j++) {
25935          font.metadata.hmtx.widths[j] = parseInt(font.metadata.hmtx.widths[j] * (1000 / font.metadata.head.unitsPerEm)); //Change the width of Em units to Point units.
25936        }
25937
25938        out("<</Subtype/TrueType/Type/Font/ToUnicode " + cmap + " 0 R/BaseFont/" + toPDFName(font.fontName) + "/FontDescriptor " + fontDescriptor + " 0 R" + "/Encoding/" + font.encoding + " /FirstChar 29 /LastChar 255 /Widths " + jsPDF.API.PDFObject.convert(font.metadata.hmtx.widths) + ">>");
25939        out("endobj");
25940        font.isAlreadyPutted = true;
25941      }
25942    };
25943
25944    jsPDFAPI.events.push(["putFont", function (args) {
25945      winAnsiEncodingFunction(args);
25946    }]);
25947
25948    var utf8TextFunction = function utf8TextFunction(args) {
25949      var text = args.text || "";
25950      var x = args.x;
25951      var y = args.y;
25952      var options = args.options || {};
25953      var mutex = args.mutex || {};
25954      var pdfEscape = mutex.pdfEscape;
25955      var activeFontKey = mutex.activeFontKey;
25956      var fonts = mutex.fonts;
25957      var key = activeFontKey;
25958      var str = "",
25959          s = 0,
25960          cmapConfirm;
25961      var strText = "";
25962      var encoding = fonts[key].encoding;
25963
25964      if (fonts[key].encoding !== "Identity-H") {
25965        return {
25966          text: text,
25967          x: x,
25968          y: y,
25969          options: options,
25970          mutex: mutex
25971        };
25972      }
25973
25974      strText = text;
25975      key = activeFontKey;
25976
25977      if (Array.isArray(text)) {
25978        strText = text[0];
25979      }
25980
25981      for (s = 0; s < strText.length; s += 1) {
25982        if (fonts[key].metadata.hasOwnProperty("cmap")) {
25983          cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)];
25984          /*
25985               if (Object.prototype.toString.call(text) === '[object Array]') {
25986                  var i = 0;
25987                 // for (i = 0; i < text.length; i += 1) {
25988                      if (Object.prototype.toString.call(text[s]) === '[object Array]') {
25989                          cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s][0].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id
25990                      } else {
25991                       }
25992                  //}
25993               } else {
25994                  cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id
25995              }*/
25996        }
25997
25998        if (!cmapConfirm) {
25999          if (strText[s].charCodeAt(0) < 256 && fonts[key].metadata.hasOwnProperty("Unicode")) {
26000            str += strText[s];
26001          } else {
26002            str += "";
26003          }
26004        } else {
26005          str += strText[s];
26006        }
26007      }
26008
26009      var result = "";
26010
26011      if (parseInt(key.slice(1)) < 14 || encoding === "WinAnsiEncoding") {
26012        //For the default 13 font
26013        result = pdfEscape(str, key).split("").map(function (cv) {
26014          return cv.charCodeAt(0).toString(16);
26015        }).join("");
26016      } else if (encoding === "Identity-H") {
26017        result = pdfEscape16(str, fonts[key]);
26018      }
26019
26020      mutex.isHex = true;
26021      return {
26022        text: result,
26023        x: x,
26024        y: y,
26025        options: options,
26026        mutex: mutex
26027      };
26028    };
26029
26030    var utf8EscapeFunction = function utf8EscapeFunction(parms) {
26031      var text = parms.text || "",
26032          x = parms.x,
26033          y = parms.y,
26034          options = parms.options,
26035          mutex = parms.mutex;
26036      var tmpText = [];
26037      var args = {
26038        text: text,
26039        x: x,
26040        y: y,
26041        options: options,
26042        mutex: mutex
26043      };
26044
26045      if (Array.isArray(text)) {
26046        var i = 0;
26047
26048        for (i = 0; i < text.length; i += 1) {
26049          if (Array.isArray(text[i])) {
26050            if (text[i].length === 3) {
26051              tmpText.push([utf8TextFunction(Object.assign({}, args, {
26052                text: text[i][0]
26053              })).text, text[i][1], text[i][2]]);
26054            } else {
26055              tmpText.push(utf8TextFunction(Object.assign({}, args, {
26056                text: text[i]
26057              })).text);
26058            }
26059          } else {
26060            tmpText.push(utf8TextFunction(Object.assign({}, args, {
26061              text: text[i]
26062            })).text);
26063          }
26064        }
26065
26066        parms.text = tmpText;
26067      } else {
26068        parms.text = utf8TextFunction(Object.assign({}, args, {
26069          text: text
26070        })).text;
26071      }
26072    };
26073
26074    jsPDFAPI.events.push(["postProcessText", utf8EscapeFunction]);
26075  })(jsPDF);
26076
26077  /**
26078   * @license
26079   * jsPDF virtual FileSystem functionality
26080   *
26081   * Licensed under the MIT License.
26082   * http://opensource.org/licenses/mit-license
26083   */
26084  /**
26085   * Use the vFS to handle files
26086   *
26087   * @name vFS
26088   * @module
26089   */
26090
26091  (function (jsPDFAPI) {
26092
26093    var _initializeVFS = function _initializeVFS() {
26094      if (typeof this.internal.vFS === "undefined") {
26095        this.internal.vFS = {};
26096      }
26097
26098      return true;
26099    };
26100    /**
26101     * Check if the file exists in the vFS
26102     *
26103     * @name existsFileInVFS
26104     * @function
26105     * @param {string} Possible filename in the vFS.
26106     * @returns {boolean}
26107     * @example
26108     * doc.existsFileInVFS("someFile.txt");
26109     */
26110
26111
26112    jsPDFAPI.existsFileInVFS = function (filename) {
26113      _initializeVFS.call(this);
26114
26115      return typeof this.internal.vFS[filename] !== "undefined";
26116    };
26117    /**
26118     * Add a file to the vFS
26119     *
26120     * @name addFileToVFS
26121     * @function
26122     * @param {string} filename The name of the file which should be added.
26123     * @param {string} filecontent The content of the file.
26124     * @returns {jsPDF}
26125     * @example
26126     * doc.addFileToVFS("someFile.txt", "BADFACE1");
26127     */
26128
26129
26130    jsPDFAPI.addFileToVFS = function (filename, filecontent) {
26131      _initializeVFS.call(this);
26132
26133      this.internal.vFS[filename] = filecontent;
26134      return this;
26135    };
26136    /**
26137     * Get the file from the vFS
26138     *
26139     * @name getFileFromVFS
26140     * @function
26141     * @param {string} The name of the file which gets requested.
26142     * @returns {string}
26143     * @example
26144     * doc.getFileFromVFS("someFile.txt");
26145     */
26146
26147
26148    jsPDFAPI.getFileFromVFS = function (filename) {
26149      _initializeVFS.call(this);
26150
26151      if (typeof this.internal.vFS[filename] !== "undefined") {
26152        return this.internal.vFS[filename];
26153      }
26154
26155      return null;
26156    };
26157  })(jsPDF.API);
26158
26159  /**
26160   * @license
26161   * Unicode Bidi Engine based on the work of Alex Shensis (@asthensis)
26162   * MIT License
26163   */
26164
26165  (function (jsPDF) {
26166    /**
26167     * Table of Unicode types.
26168     *
26169     * Generated by:
26170     *
26171     * var bidi = require("./bidi/index");
26172     * var bidi_accumulate = bidi.slice(0, 256).concat(bidi.slice(0x0500, 0x0500 + 256 * 3)).
26173     * concat(bidi.slice(0x2000, 0x2000 + 256)).concat(bidi.slice(0xFB00, 0xFB00 + 256)).
26174     * concat(bidi.slice(0xFE00, 0xFE00 + 2 * 256));
26175     *
26176     * for( var i = 0; i < bidi_accumulate.length; i++) {
26177     * 	if(bidi_accumulate[i] === undefined || bidi_accumulate[i] === 'ON')
26178     * 		bidi_accumulate[i] = 'N'; //mark as neutral to conserve space and substitute undefined
26179     * }
26180     * var bidiAccumulateStr = 'return [ "' + bidi_accumulate.toString().replace(/,/g, '", "') + '" ];';
26181     * require("fs").writeFile('unicode-types.js', bidiAccumulateStr);
26182     *
26183     * Based on:
26184     * https://github.com/mathiasbynens/unicode-8.0.0
26185     */
26186
26187    var bidiUnicodeTypes = ["BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "S", "B", "S", "WS", "B", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "B", "B", "B", "S", "WS", "N", "N", "ET", "ET", "ET", "N", "N", "N", "N", "N", "ES", "CS", "ES", "CS", "CS", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "CS", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "N", "BN", "BN", "BN", "BN", "BN", "BN", "B", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "CS", "N", "ET", "ET", "ET", "ET", "N", "N", "N", "N", "L", "N", "N", "BN", "N", "N", "ET", "ET", "EN", "EN", "N", "L", "N", "N", "N", "EN", "L", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "L", "L", "L", "L", "L", "L", "L", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "L", "N", "N", "N", "N", "N", "ET", "N", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "R", "NSM", "R", "NSM", "NSM", "R", "NSM", "NSM", "R", "NSM", "N", "N", "N", "N", "N", "N", "N", "N", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "N", "N", "N", "N", "N", "R", "R", "R", "R", "R", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "AN", "AN", "AN", "AN", "AN", "AN", "N", "N", "AL", "ET", "ET", "AL", "CS", "AL", "N", "N", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "N", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "ET", "AN", "AN", "AL", "AL", "AL", "NSM", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AN", "N", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "NSM", "NSM", "N", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "N", "AL", "AL", "NSM", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "N", "N", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "R", "R", "N", "N", "N", "N", "R", "N", "N", "N", "N", "N", "WS", "WS", "WS", "WS", "WS", "WS", "WS", "WS", "WS", "WS", "WS", "BN", "BN", "BN", "L", "R", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "WS", "B", "LRE", "RLE", "PDF", "LRO", "RLO", "CS", "ET", "ET", "ET", "ET", "ET", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "CS", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "WS", "BN", "BN", "BN", "BN", "BN", "N", "LRI", "RLI", "FSI", "PDI", "BN", "BN", "BN", "BN", "BN", "BN", "EN", "L", "N", "N", "EN", "EN", "EN", "EN", "EN", "EN", "ES", "ES", "N", "N", "N", "L", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "ES", "ES", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "N", "N", "N", "N", "N", "R", "NSM", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "ES", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "N", "R", "R", "R", "R", "R", "N", "R", "N", "R", "R", "N", "R", "R", "N", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "CS", "N", "CS", "N", "N", "CS", "N", "N", "N", "N", "N", "N", "N", "N", "N", "ET", "N", "N", "ES", "ES", "N", "N", "N", "N", "N", "ET", "ET", "N", "N", "N", "N", "N", "AL", "AL", "AL", "AL", "AL", "N", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "N", "N", "BN", "N", "N", "N", "ET", "ET", "ET", "N", "N", "N", "N", "N", "ES", "CS", "ES", "CS", "CS", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "CS", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "L", "L", "L", "L", "L", "L", "N", "N", "L", "L", "L", "L", "L", "L", "N", "N", "L", "L", "L", "L", "L", "L", "N", "N", "L", "L", "L", "N", "N", "N", "ET", "ET", "N", "N", "N", "ET", "ET", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N"];
26188    /**
26189     * Unicode Bidi algorithm compliant Bidi engine.
26190     * For reference see http://unicode.org/reports/tr9/
26191     */
26192
26193    /**
26194     * constructor ( options )
26195     *
26196     * Initializes Bidi engine
26197     *
26198     * @param {Object} See 'setOptions' below for detailed description.
26199     * options are cashed between invocation of 'doBidiReorder' method
26200     *
26201     * sample usage pattern of BidiEngine:
26202     * var opt = {
26203     * 	isInputVisual: true,
26204     * 	isInputRtl: false,
26205     * 	isOutputVisual: false,
26206     * 	isOutputRtl: false,
26207     * 	isSymmetricSwapping: true
26208     * }
26209     * var sourceToTarget = [], levels = [];
26210     * var bidiEng = Globalize.bidiEngine(opt);
vendor: 75,010 bytes, lines 26211-28708
26211     * var src = "text string to be reordered";
26212     * var ret = bidiEng.doBidiReorder(src, sourceToTarget, levels);
26213     */
26214
26215    jsPDF.__bidiEngine__ = jsPDF.prototype.__bidiEngine__ = function (options) {
26216      var _UNICODE_TYPES = _bidiUnicodeTypes;
26217      var _STATE_TABLE_LTR = [[0, 3, 0, 1, 0, 0, 0], [0, 3, 0, 1, 2, 2, 0], [0, 3, 0, 0x11, 2, 0, 1], [0, 3, 5, 5, 4, 1, 0], [0, 3, 0x15, 0x15, 4, 0, 1], [0, 3, 5, 5, 4, 2, 0]];
26218      var _STATE_TABLE_RTL = [[2, 0, 1, 1, 0, 1, 0], [2, 0, 1, 1, 0, 2, 0], [2, 0, 2, 1, 3, 2, 0], [2, 0, 2, 0x21, 3, 1, 1]];
26219      var _TYPE_NAMES_MAP = {
26220        L: 0,
26221        R: 1,
26222        EN: 2,
26223        AN: 3,
26224        N: 4,
26225        B: 5,
26226        S: 6
26227      };
26228      var _UNICODE_RANGES_MAP = {
26229        0: 0,
26230        5: 1,
26231        6: 2,
26232        7: 3,
26233        0x20: 4,
26234        0xfb: 5,
26235        0xfe: 6,
26236        0xff: 7
26237      };
26238      var _SWAP_TABLE = ["(", ")", "(", "<", ">", "<", "[", "]", "[", "{", "}", "{", "\xAB", "\xBB", "\xAB", "\u2039", "\u203A", "\u2039", "\u2045", "\u2046", "\u2045", "\u207D", "\u207E", "\u207D", "\u208D", "\u208E", "\u208D", "\u2264", "\u2265", "\u2264", "\u2329", "\u232A", "\u2329", "\uFE59", "\uFE5A", "\uFE59", "\uFE5B", "\uFE5C", "\uFE5B", "\uFE5D", "\uFE5E", "\uFE5D", "\uFE64", "\uFE65", "\uFE64"];
26239
26240      var _LTR_RANGES_REG_EXPR = new RegExp(/^([1-4|9]|1[0-9]|2[0-9]|3[0168]|4[04589]|5[012]|7[78]|159|16[0-9]|17[0-2]|21[569]|22[03489]|250)$/);
26241
26242      var _lastArabic = false,
26243          _hasUbatB,
26244          _hasUbatS,
26245          DIR_LTR = 0,
26246          DIR_RTL = 1,
26247          _isInVisual,
26248          _isInRtl,
26249          _isOutVisual,
26250          _isOutRtl,
26251          _isSymmetricSwapping,
26252          _dir = DIR_LTR;
26253
26254      this.__bidiEngine__ = {};
26255
26256      var _init = function _init(text, sourceToTargetMap) {
26257        if (sourceToTargetMap) {
26258          for (var i = 0; i < text.length; i++) {
26259            sourceToTargetMap[i] = i;
26260          }
26261        }
26262
26263        if (_isInRtl === undefined) {
26264          _isInRtl = _isContextualDirRtl(text);
26265        }
26266
26267        if (_isOutRtl === undefined) {
26268          _isOutRtl = _isContextualDirRtl(text);
26269        }
26270      }; // for reference see 3.2 in http://unicode.org/reports/tr9/
26271      //
26272
26273
26274      var _getCharType = function _getCharType(ch) {
26275        var charCode = ch.charCodeAt(),
26276            range = charCode >> 8,
26277            rangeIdx = _UNICODE_RANGES_MAP[range];
26278
26279        if (rangeIdx !== undefined) {
26280          return _UNICODE_TYPES[rangeIdx * 256 + (charCode & 0xff)];
26281        } else if (range === 0xfc || range === 0xfd) {
26282          return "AL";
26283        } else if (_LTR_RANGES_REG_EXPR.test(range)) {
26284          //unlikely case
26285          return "L";
26286        } else if (range === 8) {
26287          // even less likely
26288          return "R";
26289        }
26290
26291        return "N"; //undefined type, mark as neutral
26292      };
26293
26294      var _isContextualDirRtl = function _isContextualDirRtl(text) {
26295        for (var i = 0, charType; i < text.length; i++) {
26296          charType = _getCharType(text.charAt(i));
26297
26298          if (charType === "L") {
26299            return false;
26300          } else if (charType === "R") {
26301            return true;
26302          }
26303        }
26304
26305        return false;
26306      }; // for reference see 3.3.4 & 3.3.5 in http://unicode.org/reports/tr9/
26307      //
26308
26309
26310      var _resolveCharType = function _resolveCharType(chars, types, resolvedTypes, index) {
26311        var cType = types[index],
26312            wType,
26313            nType,
26314            i,
26315            len;
26316
26317        switch (cType) {
26318          case "L":
26319          case "R":
26320            _lastArabic = false;
26321            break;
26322
26323          case "N":
26324          case "AN":
26325            break;
26326
26327          case "EN":
26328            if (_lastArabic) {
26329              cType = "AN";
26330            }
26331
26332            break;
26333
26334          case "AL":
26335            _lastArabic = true;
26336            cType = "R";
26337            break;
26338
26339          case "WS":
26340            cType = "N";
26341            break;
26342
26343          case "CS":
26344            if (index < 1 || index + 1 >= types.length || (wType = resolvedTypes[index - 1]) !== "EN" && wType !== "AN" || (nType = types[index + 1]) !== "EN" && nType !== "AN") {
26345              cType = "N";
26346            } else if (_lastArabic) {
26347              nType = "AN";
26348            }
26349
26350            cType = nType === wType ? nType : "N";
26351            break;
26352
26353          case "ES":
26354            wType = index > 0 ? resolvedTypes[index - 1] : "B";
26355            cType = wType === "EN" && index + 1 < types.length && types[index + 1] === "EN" ? "EN" : "N";
26356            break;
26357
26358          case "ET":
26359            if (index > 0 && resolvedTypes[index - 1] === "EN") {
26360              cType = "EN";
26361              break;
26362            } else if (_lastArabic) {
26363              cType = "N";
26364              break;
26365            }
26366
26367            i = index + 1;
26368            len = types.length;
26369
26370            while (i < len && types[i] === "ET") {
26371              i++;
26372            }
26373
26374            if (i < len && types[i] === "EN") {
26375              cType = "EN";
26376            } else {
26377              cType = "N";
26378            }
26379
26380            break;
26381
26382          case "NSM":
26383            if (_isInVisual && !_isInRtl) {
26384              //V->L
26385              len = types.length;
26386              i = index + 1;
26387
26388              while (i < len && types[i] === "NSM") {
26389                i++;
26390              }
26391
26392              if (i < len) {
26393                var c = chars[index];
26394                var rtlCandidate = c >= 0x0591 && c <= 0x08ff || c === 0xfb1e;
26395                wType = types[i];
26396
26397                if (rtlCandidate && (wType === "R" || wType === "AL")) {
26398                  cType = "R";
26399                  break;
26400                }
26401              }
26402            }
26403
26404            if (index < 1 || (wType = types[index - 1]) === "B") {
26405              cType = "N";
26406            } else {
26407              cType = resolvedTypes[index - 1];
26408            }
26409
26410            break;
26411
26412          case "B":
26413            _lastArabic = false;
26414            _hasUbatB = true;
26415            cType = _dir;
26416            break;
26417
26418          case "S":
26419            _hasUbatS = true;
26420            cType = "N";
26421            break;
26422
26423          case "LRE":
26424          case "RLE":
26425          case "LRO":
26426          case "RLO":
26427          case "PDF":
26428            _lastArabic = false;
26429            break;
26430
26431          case "BN":
26432            cType = "N";
26433            break;
26434        }
26435
26436        return cType;
26437      };
26438
26439      var _handleUbatS = function _handleUbatS(types, levels, length) {
26440        for (var i = 0; i < length; i++) {
26441          if (types[i] === "S") {
26442            levels[i] = _dir;
26443
26444            for (var j = i - 1; j >= 0; j--) {
26445              if (types[j] === "WS") {
26446                levels[j] = _dir;
26447              } else {
26448                break;
26449              }
26450            }
26451          }
26452        }
26453      };
26454
26455      var _invertString = function _invertString(text, sourceToTargetMap, levels) {
26456        var charArray = text.split("");
26457
26458        if (levels) {
26459          _computeLevels(charArray, levels, {
26460            hiLevel: _dir
26461          });
26462        }
26463
26464        charArray.reverse();
26465        sourceToTargetMap && sourceToTargetMap.reverse();
26466        return charArray.join("");
26467      }; // For reference see 3.3 in http://unicode.org/reports/tr9/
26468      //
26469
26470
26471      var _computeLevels = function _computeLevels(chars, levels, params) {
26472        var action,
26473            condition,
26474            i,
26475            index,
26476            newLevel,
26477            prevState,
26478            condPos = -1,
26479            len = chars.length,
26480            newState = 0,
26481            resolvedTypes = [],
26482            stateTable = _dir ? _STATE_TABLE_RTL : _STATE_TABLE_LTR,
26483            types = [];
26484        _lastArabic = false;
26485        _hasUbatB = false;
26486        _hasUbatS = false;
26487
26488        for (i = 0; i < len; i++) {
26489          types[i] = _getCharType(chars[i]);
26490        }
26491
26492        for (index = 0; index < len; index++) {
26493          prevState = newState;
26494          resolvedTypes[index] = _resolveCharType(chars, types, resolvedTypes, index);
26495          newState = stateTable[prevState][_TYPE_NAMES_MAP[resolvedTypes[index]]];
26496          action = newState & 0xf0;
26497          newState &= 0x0f;
26498          levels[index] = newLevel = stateTable[newState][5];
26499
26500          if (action > 0) {
26501            if (action === 0x10) {
26502              for (i = condPos; i < index; i++) {
26503                levels[i] = 1;
26504              }
26505
26506              condPos = -1;
26507            } else {
26508              condPos = -1;
26509            }
26510          }
26511
26512          condition = stateTable[newState][6];
26513
26514          if (condition) {
26515            if (condPos === -1) {
26516              condPos = index;
26517            }
26518          } else {
26519            if (condPos > -1) {
26520              for (i = condPos; i < index; i++) {
26521                levels[i] = newLevel;
26522              }
26523
26524              condPos = -1;
26525            }
26526          }
26527
26528          if (types[index] === "B") {
26529            levels[index] = 0;
26530          }
26531
26532          params.hiLevel |= newLevel;
26533        }
26534
26535        if (_hasUbatS) {
26536          _handleUbatS(types, levels, len);
26537        }
26538      }; // for reference see 3.4 in http://unicode.org/reports/tr9/
26539      //
26540
26541
26542      var _invertByLevel = function _invertByLevel(level, charArray, sourceToTargetMap, levels, params) {
26543        if (params.hiLevel < level) {
26544          return;
26545        }
26546
26547        if (level === 1 && _dir === DIR_RTL && !_hasUbatB) {
26548          charArray.reverse();
26549          sourceToTargetMap && sourceToTargetMap.reverse();
26550          return;
26551        }
26552
26553        var ch,
26554            high,
26555            end,
26556            low,
26557            len = charArray.length,
26558            start = 0;
26559
26560        while (start < len) {
26561          if (levels[start] >= level) {
26562            end = start + 1;
26563
26564            while (end < len && levels[end] >= level) {
26565              end++;
26566            }
26567
26568            for (low = start, high = end - 1; low < high; low++, high--) {
26569              ch = charArray[low];
26570              charArray[low] = charArray[high];
26571              charArray[high] = ch;
26572
26573              if (sourceToTargetMap) {
26574                ch = sourceToTargetMap[low];
26575                sourceToTargetMap[low] = sourceToTargetMap[high];
26576                sourceToTargetMap[high] = ch;
26577              }
26578            }
26579
26580            start = end;
26581          }
26582
26583          start++;
26584        }
26585      }; // for reference see 7 & BD16 in http://unicode.org/reports/tr9/
26586      //
26587
26588
26589      var _symmetricSwap = function _symmetricSwap(charArray, levels, params) {
26590        if (params.hiLevel !== 0 && _isSymmetricSwapping) {
26591          for (var i = 0, index; i < charArray.length; i++) {
26592            if (levels[i] === 1) {
26593              index = _SWAP_TABLE.indexOf(charArray[i]);
26594
26595              if (index >= 0) {
26596                charArray[i] = _SWAP_TABLE[index + 1];
26597              }
26598            }
26599          }
26600        }
26601      };
26602
26603      var _reorder = function _reorder(text, sourceToTargetMap, levels) {
26604        var charArray = text.split(""),
26605            params = {
26606          hiLevel: _dir
26607        };
26608
26609        if (!levels) {
26610          levels = [];
26611        }
26612
26613        _computeLevels(charArray, levels, params);
26614
26615        _symmetricSwap(charArray, levels, params);
26616
26617        _invertByLevel(DIR_RTL + 1, charArray, sourceToTargetMap, levels, params);
26618
26619        _invertByLevel(DIR_RTL, charArray, sourceToTargetMap, levels, params);
26620
26621        return charArray.join("");
26622      }; // doBidiReorder( text, sourceToTargetMap, levels )
26623      // Performs Bidi reordering by implementing Unicode Bidi algorithm.
26624      // Returns reordered string
26625      // @text [String]:
26626      // - input string to be reordered, this is input parameter
26627      // $sourceToTargetMap [Array] (optional)
26628      // - resultant mapping between input and output strings, this is output parameter
26629      // $levels [Array] (optional)
26630      // - array of calculated Bidi levels, , this is output parameter
26631
26632
26633      this.__bidiEngine__.doBidiReorder = function (text, sourceToTargetMap, levels) {
26634        _init(text, sourceToTargetMap);
26635
26636        if (!_isInVisual && _isOutVisual && !_isOutRtl) {
26637          // LLTR->VLTR, LRTL->VLTR
26638          _dir = _isInRtl ? DIR_RTL : DIR_LTR;
26639          text = _reorder(text, sourceToTargetMap, levels);
26640        } else if (_isInVisual && _isOutVisual && _isInRtl ^ _isOutRtl) {
26641          // VRTL->VLTR, VLTR->VRTL
26642          _dir = _isInRtl ? DIR_RTL : DIR_LTR;
26643          text = _invertString(text, sourceToTargetMap, levels);
26644        } else if (!_isInVisual && _isOutVisual && _isOutRtl) {
26645          // LLTR->VRTL, LRTL->VRTL
26646          _dir = _isInRtl ? DIR_RTL : DIR_LTR;
26647          text = _reorder(text, sourceToTargetMap, levels);
26648          text = _invertString(text, sourceToTargetMap);
26649        } else if (_isInVisual && !_isInRtl && !_isOutVisual && !_isOutRtl) {
26650          // VLTR->LLTR
26651          _dir = DIR_LTR;
26652          text = _reorder(text, sourceToTargetMap, levels);
26653        } else if (_isInVisual && !_isOutVisual && _isInRtl ^ _isOutRtl) {
26654          // VLTR->LRTL, VRTL->LLTR
26655          text = _invertString(text, sourceToTargetMap);
26656
26657          if (_isInRtl) {
26658            //LLTR -> VLTR
26659            _dir = DIR_LTR;
26660            text = _reorder(text, sourceToTargetMap, levels);
26661          } else {
26662            //LRTL -> VRTL
26663            _dir = DIR_RTL;
26664            text = _reorder(text, sourceToTargetMap, levels);
26665            text = _invertString(text, sourceToTargetMap);
26666          }
26667        } else if (_isInVisual && _isInRtl && !_isOutVisual && _isOutRtl) {
26668          //  VRTL->LRTL
26669          _dir = DIR_RTL;
26670          text = _reorder(text, sourceToTargetMap, levels);
26671          text = _invertString(text, sourceToTargetMap);
26672        } else if (!_isInVisual && !_isOutVisual && _isInRtl ^ _isOutRtl) {
26673          // LRTL->LLTR, LLTR->LRTL
26674          var isSymmetricSwappingOrig = _isSymmetricSwapping;
26675
26676          if (_isInRtl) {
26677            //LRTL->LLTR
26678            _dir = DIR_RTL;
26679            text = _reorder(text, sourceToTargetMap, levels);
26680            _dir = DIR_LTR;
26681            _isSymmetricSwapping = false;
26682            text = _reorder(text, sourceToTargetMap, levels);
26683            _isSymmetricSwapping = isSymmetricSwappingOrig;
26684          } else {
26685            //LLTR->LRTL
26686            _dir = DIR_LTR;
26687            text = _reorder(text, sourceToTargetMap, levels);
26688            text = _invertString(text, sourceToTargetMap);
26689            _dir = DIR_RTL;
26690            _isSymmetricSwapping = false;
26691            text = _reorder(text, sourceToTargetMap, levels);
26692            _isSymmetricSwapping = isSymmetricSwappingOrig;
26693            text = _invertString(text, sourceToTargetMap);
26694          }
26695        }
26696
26697        return text;
26698      };
26699      /**
26700       * @name setOptions( options )
26701       * @function
26702       * Sets options for Bidi conversion
26703       * @param {Object}:
26704       * - isInputVisual {boolean} (defaults to false): allowed values: true(Visual mode), false(Logical mode)
26705       * - isInputRtl {boolean}: allowed values true(Right-to-left direction), false (Left-to-right directiion), undefined(Contectual direction, i.e.direction defined by first strong character of input string)
26706       * - isOutputVisual {boolean} (defaults to false): allowed values: true(Visual mode), false(Logical mode)
26707       * - isOutputRtl {boolean}: allowed values true(Right-to-left direction), false (Left-to-right directiion), undefined(Contectual direction, i.e.direction defined by first strong characterof input string)
26708       * - isSymmetricSwapping {boolean} (defaults to false): allowed values true(needs symmetric swapping), false (no need in symmetric swapping),
26709       */
26710
26711
26712      this.__bidiEngine__.setOptions = function (options) {
26713        if (options) {
26714          _isInVisual = options.isInputVisual;
26715          _isOutVisual = options.isOutputVisual;
26716          _isInRtl = options.isInputRtl;
26717          _isOutRtl = options.isOutputRtl;
26718          _isSymmetricSwapping = options.isSymmetricSwapping;
26719        }
26720      };
26721
26722      this.__bidiEngine__.setOptions(options);
26723
26724      return this.__bidiEngine__;
26725    };
26726
26727    var _bidiUnicodeTypes = bidiUnicodeTypes;
26728    var bidiEngine = new jsPDF.__bidiEngine__({
26729      isInputVisual: true
26730    });
26731
26732    var bidiEngineFunction = function bidiEngineFunction(args) {
26733      var text = args.text;
26734      var x = args.x;
26735      var y = args.y;
26736      var options = args.options || {};
26737      var mutex = args.mutex || {};
26738      var lang = options.lang;
26739      var tmpText = [];
26740      options.isInputVisual = typeof options.isInputVisual === "boolean" ? options.isInputVisual : true;
26741      bidiEngine.setOptions(options);
26742
26743      if (Object.prototype.toString.call(text) === "[object Array]") {
26744        var i = 0;
26745        tmpText = [];
26746
26747        for (i = 0; i < text.length; i += 1) {
26748          if (Object.prototype.toString.call(text[i]) === "[object Array]") {
26749            tmpText.push([bidiEngine.doBidiReorder(text[i][0]), text[i][1], text[i][2]]);
26750          } else {
26751            tmpText.push([bidiEngine.doBidiReorder(text[i])]);
26752          }
26753        }
26754
26755        args.text = tmpText;
26756      } else {
26757        args.text = bidiEngine.doBidiReorder(text);
26758      }
26759
26760      bidiEngine.setOptions({
26761        isInputVisual: true
26762      });
26763    };
26764
26765    jsPDF.API.events.push(["postProcessText", bidiEngineFunction]);
26766  })(jsPDF);
26767
26768  /* eslint-disable no-control-regex */
26769
26770  jsPDF.API.TTFFont = function () {
26771    /************************************************************************/
26772
26773    /* function : open                                                       */
26774
26775    /* comment : Decode the encoded ttf content and create a TTFFont object. */
26776
26777    /************************************************************************/
26778    TTFFont.open = function (file) {
26779      return new TTFFont(file);
26780    };
26781    /***************************************************************/
26782
26783    /* function : TTFFont gernerator                               */
26784
26785    /* comment : Decode TTF contents are parsed, Data,             */
26786
26787    /* Subset object is created, and registerTTF function is called.*/
26788
26789    /***************************************************************/
26790
26791
26792    function TTFFont(rawData) {
26793      var data;
26794      this.rawData = rawData;
26795      data = this.contents = new Data(rawData);
26796      this.contents.pos = 4;
26797
26798      if (data.readString(4) === "ttcf") {
26799        throw new Error("TTCF not supported.");
26800      } else {
26801        data.pos = 0;
26802        this.parse();
26803        this.subset = new Subset(this);
26804        this.registerTTF();
26805      }
26806    }
26807    /********************************************************/
26808
26809    /* function : parse                                     */
26810
26811    /* comment : TTF Parses the file contents by each table.*/
26812
26813    /********************************************************/
26814
26815
26816    TTFFont.prototype.parse = function () {
26817      this.directory = new Directory(this.contents);
26818      this.head = new HeadTable(this);
26819      this.name = new NameTable(this);
26820      this.cmap = new CmapTable(this);
26821      this.toUnicode = {};
26822      this.hhea = new HheaTable(this);
26823      this.maxp = new MaxpTable(this);
26824      this.hmtx = new HmtxTable(this);
26825      this.post = new PostTable(this);
26826      this.os2 = new OS2Table(this);
26827      this.loca = new LocaTable(this);
26828      this.glyf = new GlyfTable(this);
26829      this.ascender = this.os2.exists && this.os2.ascender || this.hhea.ascender;
26830      this.decender = this.os2.exists && this.os2.decender || this.hhea.decender;
26831      this.lineGap = this.os2.exists && this.os2.lineGap || this.hhea.lineGap;
26832      return this.bbox = [this.head.xMin, this.head.yMin, this.head.xMax, this.head.yMax];
26833    };
26834    /***************************************************************/
26835
26836    /* function : registerTTF                                      */
26837
26838    /* comment : Get the value to assign pdf font descriptors.     */
26839
26840    /***************************************************************/
26841
26842
26843    TTFFont.prototype.registerTTF = function () {
26844      var e, hi, low, raw, _ref;
26845
26846      this.scaleFactor = 1000.0 / this.head.unitsPerEm;
26847
26848      this.bbox = function () {
26849        var _i, _len, _ref, _results;
26850
26851        _ref = this.bbox;
26852        _results = [];
26853
26854        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
26855          e = _ref[_i];
26856
26857          _results.push(Math.round(e * this.scaleFactor));
26858        }
26859
26860        return _results;
26861      }.call(this);
26862
26863      this.stemV = 0;
26864
26865      if (this.post.exists) {
26866        raw = this.post.italic_angle;
26867        hi = raw >> 16;
26868        low = raw & 0xff;
26869
26870        if ((hi & 0x8000) !== 0) {
26871          hi = -((hi ^ 0xffff) + 1);
26872        }
26873
26874        this.italicAngle = +("" + hi + "." + low);
26875      } else {
26876        this.italicAngle = 0;
26877      }
26878
26879      this.ascender = Math.round(this.ascender * this.scaleFactor);
26880      this.decender = Math.round(this.decender * this.scaleFactor);
26881      this.lineGap = Math.round(this.lineGap * this.scaleFactor);
26882      this.capHeight = this.os2.exists && this.os2.capHeight || this.ascender;
26883      this.xHeight = this.os2.exists && this.os2.xHeight || 0;
26884      this.familyClass = (this.os2.exists && this.os2.familyClass || 0) >> 8;
26885      this.isSerif = (_ref = this.familyClass) === 1 || _ref === 2 || _ref === 3 || _ref === 4 || _ref === 5 || _ref === 7;
26886      this.isScript = this.familyClass === 10;
26887      this.flags = 0;
26888
26889      if (this.post.isFixedPitch) {
26890        this.flags |= 1 << 0;
26891      }
26892
26893      if (this.isSerif) {
26894        this.flags |= 1 << 1;
26895      }
26896
26897      if (this.isScript) {
26898        this.flags |= 1 << 3;
26899      }
26900
26901      if (this.italicAngle !== 0) {
26902        this.flags |= 1 << 6;
26903      }
26904
26905      this.flags |= 1 << 5;
26906
26907      if (!this.cmap.unicode) {
26908        throw new Error("No unicode cmap for font");
26909      }
26910    };
26911
26912    TTFFont.prototype.characterToGlyph = function (character) {
26913      var _ref;
26914
26915      return ((_ref = this.cmap.unicode) != null ? _ref.codeMap[character] : void 0) || 0;
26916    };
26917
26918    TTFFont.prototype.widthOfGlyph = function (glyph) {
26919      var scale;
26920      scale = 1000.0 / this.head.unitsPerEm;
26921      return this.hmtx.forGlyph(glyph).advance * scale;
26922    };
26923
26924    TTFFont.prototype.widthOfString = function (string, size, charSpace) {
26925      var charCode, i, scale, width, _ref;
26926
26927      string = "" + string;
26928      width = 0;
26929
26930      for (i = 0, _ref = string.length; 0 <= _ref ? i < _ref : i > _ref; i = 0 <= _ref ? ++i : --i) {
26931        charCode = string.charCodeAt(i);
26932        width += this.widthOfGlyph(this.characterToGlyph(charCode)) + charSpace * (1000 / size) || 0;
26933      }
26934
26935      scale = size / 1000;
26936      return width * scale;
26937    };
26938
26939    TTFFont.prototype.lineHeight = function (size, includeGap) {
26940      var gap;
26941
26942      if (includeGap == null) {
26943        includeGap = false;
26944      }
26945
26946      gap = includeGap ? this.lineGap : 0;
26947      return (this.ascender + gap - this.decender) / 1000 * size;
26948    };
26949
26950    return TTFFont;
26951  }();
26952  /************************************************************************************************/
26953
26954  /* function : Data                                                                              */
26955
26956  /* comment : The ttf data decoded and stored in an array is read and written to the Data object.*/
26957
26958  /************************************************************************************************/
26959
26960
26961  var Data = function () {
26962    function Data(data) {
26963      this.data = data != null ? data : [];
26964      this.pos = 0;
26965      this.length = this.data.length;
26966    }
26967
26968    Data.prototype.readByte = function () {
26969      return this.data[this.pos++];
26970    };
26971
26972    Data.prototype.writeByte = function (byte) {
26973      return this.data[this.pos++] = byte;
26974    };
26975
26976    Data.prototype.readUInt32 = function () {
26977      var b1, b2, b3, b4;
26978      b1 = this.readByte() * 0x1000000;
26979      b2 = this.readByte() << 16;
26980      b3 = this.readByte() << 8;
26981      b4 = this.readByte();
26982      return b1 + b2 + b3 + b4;
26983    };
26984
26985    Data.prototype.writeUInt32 = function (val) {
26986      this.writeByte(val >>> 24 & 0xff);
26987      this.writeByte(val >> 16 & 0xff);
26988      this.writeByte(val >> 8 & 0xff);
26989      return this.writeByte(val & 0xff);
26990    };
26991
26992    Data.prototype.readInt32 = function () {
26993      var int;
26994      int = this.readUInt32();
26995
26996      if (int >= 0x80000000) {
26997        return int - 0x100000000;
26998      } else {
26999        return int;
27000      }
27001    };
27002
27003    Data.prototype.writeInt32 = function (val) {
27004      if (val < 0) {
27005        val += 0x100000000;
27006      }
27007
27008      return this.writeUInt32(val);
27009    };
27010
27011    Data.prototype.readUInt16 = function () {
27012      var b1, b2;
27013      b1 = this.readByte() << 8;
27014      b2 = this.readByte();
27015      return b1 | b2;
27016    };
27017
27018    Data.prototype.writeUInt16 = function (val) {
27019      this.writeByte(val >> 8 & 0xff);
27020      return this.writeByte(val & 0xff);
27021    };
27022
27023    Data.prototype.readInt16 = function () {
27024      var int;
27025      int = this.readUInt16();
27026
27027      if (int >= 0x8000) {
27028        return int - 0x10000;
27029      } else {
27030        return int;
27031      }
27032    };
27033
27034    Data.prototype.writeInt16 = function (val) {
27035      if (val < 0) {
27036        val += 0x10000;
27037      }
27038
27039      return this.writeUInt16(val);
27040    };
27041
27042    Data.prototype.readString = function (length) {
27043      var i, ret;
27044      ret = [];
27045
27046      for (i = 0; 0 <= length ? i < length : i > length; i = 0 <= length ? ++i : --i) {
27047        ret[i] = String.fromCharCode(this.readByte());
27048      }
27049
27050      return ret.join("");
27051    };
27052
27053    Data.prototype.writeString = function (val) {
27054      var i, _ref, _results;
27055
27056      _results = [];
27057
27058      for (i = 0, _ref = val.length; 0 <= _ref ? i < _ref : i > _ref; i = 0 <= _ref ? ++i : --i) {
27059        _results.push(this.writeByte(val.charCodeAt(i)));
27060      }
27061
27062      return _results;
27063    };
27064    /*Data.prototype.stringAt = function (pos, length) {
27065              this.pos = pos;
27066              return this.readString(length);
27067          };*/
27068
27069
27070    Data.prototype.readShort = function () {
27071      return this.readInt16();
27072    };
27073
27074    Data.prototype.writeShort = function (val) {
27075      return this.writeInt16(val);
27076    };
27077
27078    Data.prototype.readLongLong = function () {
27079      var b1, b2, b3, b4, b5, b6, b7, b8;
27080      b1 = this.readByte();
27081      b2 = this.readByte();
27082      b3 = this.readByte();
27083      b4 = this.readByte();
27084      b5 = this.readByte();
27085      b6 = this.readByte();
27086      b7 = this.readByte();
27087      b8 = this.readByte();
27088
27089      if (b1 & 0x80) {
27090        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;
27091      }
27092
27093      return b1 * 0x100000000000000 + b2 * 0x1000000000000 + b3 * 0x10000000000 + b4 * 0x100000000 + b5 * 0x1000000 + b6 * 0x10000 + b7 * 0x100 + b8;
27094    };
27095
27096    Data.prototype.writeLongLong = function (val) {
27097      var high, low;
27098      high = Math.floor(val / 0x100000000);
27099      low = val & 0xffffffff;
27100      this.writeByte(high >> 24 & 0xff);
27101      this.writeByte(high >> 16 & 0xff);
27102      this.writeByte(high >> 8 & 0xff);
27103      this.writeByte(high & 0xff);
27104      this.writeByte(low >> 24 & 0xff);
27105      this.writeByte(low >> 16 & 0xff);
27106      this.writeByte(low >> 8 & 0xff);
27107      return this.writeByte(low & 0xff);
27108    };
27109
27110    Data.prototype.readInt = function () {
27111      return this.readInt32();
27112    };
27113
27114    Data.prototype.writeInt = function (val) {
27115      return this.writeInt32(val);
27116    };
27117    /*Data.prototype.slice = function (start, end) {
27118              return this.data.slice(start, end);
27119          };*/
27120
27121
27122    Data.prototype.read = function (bytes) {
27123      var buf, i;
27124      buf = [];
27125
27126      for (i = 0; 0 <= bytes ? i < bytes : i > bytes; i = 0 <= bytes ? ++i : --i) {
27127        buf.push(this.readByte());
27128      }
27129
27130      return buf;
27131    };
27132
27133    Data.prototype.write = function (bytes) {
27134      var byte, i, _len, _results;
27135
27136      _results = [];
27137
27138      for (i = 0, _len = bytes.length; i < _len; i++) {
27139        byte = bytes[i];
27140
27141        _results.push(this.writeByte(byte));
27142      }
27143
27144      return _results;
27145    };
27146
27147    return Data;
27148  }();
27149
27150  var Directory = function () {
27151    var checksum;
27152    /*****************************************************************************************************/
27153
27154    /* function : Directory generator                                                                    */
27155
27156    /* comment : Initialize the offset, tag, length, and checksum for each table for the font to be used.*/
27157
27158    /*****************************************************************************************************/
27159
27160    function Directory(data) {
27161      var entry, i, _ref;
27162
27163      this.scalarType = data.readInt();
27164      this.tableCount = data.readShort();
27165      this.searchRange = data.readShort();
27166      this.entrySelector = data.readShort();
27167      this.rangeShift = data.readShort();
27168      this.tables = {};
27169
27170      for (i = 0, _ref = this.tableCount; 0 <= _ref ? i < _ref : i > _ref; i = 0 <= _ref ? ++i : --i) {
27171        entry = {
27172          tag: data.readString(4),
27173          checksum: data.readInt(),
27174          offset: data.readInt(),
27175          length: data.readInt()
27176        };
27177        this.tables[entry.tag] = entry;
27178      }
27179    }
27180    /********************************************************************************************************/
27181
27182    /* function : encode                                                                                    */
27183
27184    /* comment : It encodes and stores the font table object and information used for the directory object. */
27185
27186    /********************************************************************************************************/
27187
27188
27189    Directory.prototype.encode = function (tables) {
27190      var adjustment, directory, directoryLength, entrySelector, headOffset, log2, offset, rangeShift, searchRange, sum, table, tableCount, tableData, tag;
27191      tableCount = Object.keys(tables).length;
27192      log2 = Math.log(2);
27193      searchRange = Math.floor(Math.log(tableCount) / log2) * 16;
27194      entrySelector = Math.floor(searchRange / log2);
27195      rangeShift = tableCount * 16 - searchRange;
27196      directory = new Data();
27197      directory.writeInt(this.scalarType);
27198      directory.writeShort(tableCount);
27199      directory.writeShort(searchRange);
27200      directory.writeShort(entrySelector);
27201      directory.writeShort(rangeShift);
27202      directoryLength = tableCount * 16;
27203      offset = directory.pos + directoryLength;
27204      headOffset = null;
27205      tableData = [];
27206
27207      for (tag in tables) {
27208        table = tables[tag];
27209        directory.writeString(tag);
27210        directory.writeInt(checksum(table));
27211        directory.writeInt(offset);
27212        directory.writeInt(table.length);
27213        tableData = tableData.concat(table);
27214
27215        if (tag === "head") {
27216          headOffset = offset;
27217        }
27218
27219        offset += table.length;
27220
27221        while (offset % 4) {
27222          tableData.push(0);
27223          offset++;
27224        }
27225      }
27226
27227      directory.write(tableData);
27228      sum = checksum(directory.data);
27229      adjustment = 0xb1b0afba - sum;
27230      directory.pos = headOffset + 8;
27231      directory.writeUInt32(adjustment);
27232      return directory.data;
27233    };
27234    /***************************************************************/
27235
27236    /* function : checksum                                         */
27237
27238    /* comment : Duplicate the table for the tag.                  */
27239
27240    /***************************************************************/
27241
27242
27243    checksum = function checksum(data) {
27244      var i, sum, tmp, _ref;
27245
27246      data = __slice.call(data);
27247
27248      while (data.length % 4) {
27249        data.push(0);
27250      }
27251
27252      tmp = new Data(data);
27253      sum = 0;
27254
27255      for (i = 0, _ref = data.length; i < _ref; i = i += 4) {
27256        sum += tmp.readUInt32();
27257      }
27258
27259      return sum & 0xffffffff;
27260    };
27261
27262    return Directory;
27263  }();
27264
27265  var Table,
27266      __hasProp = {}.hasOwnProperty,
27267      __extends = function __extends(child, parent) {
27268    for (var key in parent) {
27269      if (__hasProp.call(parent, key)) child[key] = parent[key];
27270    }
27271
27272    function ctor() {
27273      this.constructor = child;
27274    }
27275
27276    ctor.prototype = parent.prototype;
27277    child.prototype = new ctor();
27278    child.__super__ = parent.prototype;
27279    return child;
27280  };
27281  /***************************************************************/
27282
27283  /* function : Table                                            */
27284
27285  /* comment : Save info for each table, and parse the table.    */
27286
27287  /***************************************************************/
27288
27289
27290  Table = function () {
27291    function Table(file) {
27292      var info;
27293      this.file = file;
27294      info = this.file.directory.tables[this.tag];
27295      this.exists = !!info;
27296
27297      if (info) {
27298        this.offset = info.offset, this.length = info.length;
27299        this.parse(this.file.contents);
27300      }
27301    }
27302
27303    Table.prototype.parse = function () {};
27304
27305    Table.prototype.encode = function () {};
27306
27307    Table.prototype.raw = function () {
27308      if (!this.exists) {
27309        return null;
27310      }
27311
27312      this.file.contents.pos = this.offset;
27313      return this.file.contents.read(this.length);
27314    };
27315
27316    return Table;
27317  }();
27318
27319  var HeadTable = function (_super) {
27320    __extends(HeadTable, _super);
27321
27322    function HeadTable() {
27323      return HeadTable.__super__.constructor.apply(this, arguments);
27324    }
27325
27326    HeadTable.prototype.tag = "head";
27327
27328    HeadTable.prototype.parse = function (data) {
27329      data.pos = this.offset;
27330      this.version = data.readInt();
27331      this.revision = data.readInt();
27332      this.checkSumAdjustment = data.readInt();
27333      this.magicNumber = data.readInt();
27334      this.flags = data.readShort();
27335      this.unitsPerEm = data.readShort();
27336      this.created = data.readLongLong();
27337      this.modified = data.readLongLong();
27338      this.xMin = data.readShort();
27339      this.yMin = data.readShort();
27340      this.xMax = data.readShort();
27341      this.yMax = data.readShort();
27342      this.macStyle = data.readShort();
27343      this.lowestRecPPEM = data.readShort();
27344      this.fontDirectionHint = data.readShort();
27345      this.indexToLocFormat = data.readShort();
27346      return this.glyphDataFormat = data.readShort();
27347    };
27348
27349    HeadTable.prototype.encode = function (indexToLocFormat) {
27350      var table;
27351      table = new Data();
27352      table.writeInt(this.version);
27353      table.writeInt(this.revision);
27354      table.writeInt(this.checkSumAdjustment);
27355      table.writeInt(this.magicNumber);
27356      table.writeShort(this.flags);
27357      table.writeShort(this.unitsPerEm);
27358      table.writeLongLong(this.created);
27359      table.writeLongLong(this.modified);
27360      table.writeShort(this.xMin);
27361      table.writeShort(this.yMin);
27362      table.writeShort(this.xMax);
27363      table.writeShort(this.yMax);
27364      table.writeShort(this.macStyle);
27365      table.writeShort(this.lowestRecPPEM);
27366      table.writeShort(this.fontDirectionHint);
27367      table.writeShort(indexToLocFormat);
27368      table.writeShort(this.glyphDataFormat);
27369      return table.data;
27370    };
27371
27372    return HeadTable;
27373  }(Table);
27374  /************************************************************************************/
27375
27376  /* function : CmapEntry                                                             */
27377
27378  /* comment : Cmap Initializes and encodes object information (required by pdf spec).*/
27379
27380  /************************************************************************************/
27381
27382
27383  var CmapEntry = function () {
27384    function CmapEntry(data, offset) {
27385      var code, count, endCode, glyphId, glyphIds, i, idDelta, idRangeOffset, index, saveOffset, segCount, segCountX2, start, startCode, tail, _j, _k, _len;
27386
27387      this.platformID = data.readUInt16();
27388      this.encodingID = data.readShort();
27389      this.offset = offset + data.readInt();
27390      saveOffset = data.pos;
27391      data.pos = this.offset;
27392      this.format = data.readUInt16();
27393      this.length = data.readUInt16();
27394      this.language = data.readUInt16();
27395      this.isUnicode = this.platformID === 3 && this.encodingID === 1 && this.format === 4 || this.platformID === 0 && this.format === 4;
27396      this.codeMap = {};
27397
27398      switch (this.format) {
27399        case 0:
27400          for (i = 0; i < 256; ++i) {
27401            this.codeMap[i] = data.readByte();
27402          }
27403
27404          break;
27405
27406        case 4:
27407          segCountX2 = data.readUInt16();
27408          segCount = segCountX2 / 2;
27409          data.pos += 6;
27410
27411          endCode = function () {
27412            var _j, _results;
27413
27414            _results = [];
27415
27416            for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
27417              _results.push(data.readUInt16());
27418            }
27419
27420            return _results;
27421          }();
27422
27423          data.pos += 2;
27424
27425          startCode = function () {
27426            var _j, _results;
27427
27428            _results = [];
27429
27430            for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
27431              _results.push(data.readUInt16());
27432            }
27433
27434            return _results;
27435          }();
27436
27437          idDelta = function () {
27438            var _j, _results;
27439
27440            _results = [];
27441
27442            for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
27443              _results.push(data.readUInt16());
27444            }
27445
27446            return _results;
27447          }();
27448
27449          idRangeOffset = function () {
27450            var _j, _results;
27451
27452            _results = [];
27453
27454            for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
27455              _results.push(data.readUInt16());
27456            }
27457
27458            return _results;
27459          }();
27460
27461          count = (this.length - data.pos + this.offset) / 2;
27462
27463          glyphIds = function () {
27464            var _j, _results;
27465
27466            _results = [];
27467
27468            for (i = _j = 0; 0 <= count ? _j < count : _j > count; i = 0 <= count ? ++_j : --_j) {
27469              _results.push(data.readUInt16());
27470            }
27471
27472            return _results;
27473          }();
27474
27475          for (i = _j = 0, _len = endCode.length; _j < _len; i = ++_j) {
27476            tail = endCode[i];
27477            start = startCode[i];
27478
27479            for (code = _k = start; start <= tail ? _k <= tail : _k >= tail; code = start <= tail ? ++_k : --_k) {
27480              if (idRangeOffset[i] === 0) {
27481                glyphId = code + idDelta[i];
27482              } else {
27483                index = idRangeOffset[i] / 2 + (code - start) - (segCount - i);
27484                glyphId = glyphIds[index] || 0;
27485
27486                if (glyphId !== 0) {
27487                  glyphId += idDelta[i];
27488                }
27489              }
27490
27491              this.codeMap[code] = glyphId & 0xffff;
27492            }
27493          }
27494
27495      }
27496
27497      data.pos = saveOffset;
27498    }
27499
27500    CmapEntry.encode = function (charmap, encoding) {
27501      var charMap, code, codeMap, codes, delta, deltas, diff, endCode, endCodes, entrySelector, glyphIDs, i, id, indexes, last, map, nextID, offset, old, rangeOffsets, rangeShift, 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;
27502
27503      subtable = new Data();
27504      codes = Object.keys(charmap).sort(function (a, b) {
27505        return a - b;
27506      });
27507
27508      switch (encoding) {
27509        case "macroman":
27510          id = 0;
27511
27512          indexes = function () {
27513            var _results = [];
27514
27515            for (i = 0; i < 256; ++i) {
27516              _results.push(0);
27517            }
27518
27519            return _results;
27520          }();
27521
27522          map = {
27523            0: 0
27524          };
27525          codeMap = {};
27526
27527          for (_i = 0, _len = codes.length; _i < _len; _i++) {
27528            code = codes[_i];
27529
27530            if (map[_name = charmap[code]] == null) {
27531              map[_name] = ++id;
27532            }
27533
27534            codeMap[code] = {
27535              old: charmap[code],
27536              new: map[charmap[code]]
27537            };
27538            indexes[code] = map[charmap[code]];
27539          }
27540
27541          subtable.writeUInt16(1);
27542          subtable.writeUInt16(0);
27543          subtable.writeUInt32(12);
27544          subtable.writeUInt16(0);
27545          subtable.writeUInt16(262);
27546          subtable.writeUInt16(0);
27547          subtable.write(indexes);
27548          return {
27549            charMap: codeMap,
27550            subtable: subtable.data,
27551            maxGlyphID: id + 1
27552          };
27553
27554        case "unicode":
27555          startCodes = [];
27556          endCodes = [];
27557          nextID = 0;
27558          map = {};
27559          charMap = {};
27560          last = diff = null;
27561
27562          for (_j = 0, _len1 = codes.length; _j < _len1; _j++) {
27563            code = codes[_j];
27564            old = charmap[code];
27565
27566            if (map[old] == null) {
27567              map[old] = ++nextID;
27568            }
27569
27570            charMap[code] = {
27571              old: old,
27572              new: map[old]
27573            };
27574            delta = map[old] - code;
27575
27576            if (last == null || delta !== diff) {
27577              if (last) {
27578                endCodes.push(last);
27579              }
27580
27581              startCodes.push(code);
27582              diff = delta;
27583            }
27584
27585            last = code;
27586          }
27587
27588          if (last) {
27589            endCodes.push(last);
27590          }
27591
27592          endCodes.push(0xffff);
27593          startCodes.push(0xffff);
27594          segCount = startCodes.length;
27595          segCountX2 = segCount * 2;
27596          searchRange = 2 * Math.pow(Math.log(segCount) / Math.LN2, 2);
27597          entrySelector = Math.log(searchRange / 2) / Math.LN2;
27598          rangeShift = 2 * segCount - searchRange;
27599          deltas = [];
27600          rangeOffsets = [];
27601          glyphIDs = [];
27602
27603          for (i = _k = 0, _len2 = startCodes.length; _k < _len2; i = ++_k) {
27604            startCode = startCodes[i];
27605            endCode = endCodes[i];
27606
27607            if (startCode === 0xffff) {
27608              deltas.push(0);
27609              rangeOffsets.push(0);
27610              break;
27611            }
27612
27613            startGlyph = charMap[startCode]["new"];
27614
27615            if (startCode - startGlyph >= 0x8000) {
27616              deltas.push(0);
27617              rangeOffsets.push(2 * (glyphIDs.length + segCount - i));
27618
27619              for (code = _l = startCode; startCode <= endCode ? _l <= endCode : _l >= endCode; code = startCode <= endCode ? ++_l : --_l) {
27620                glyphIDs.push(charMap[code]["new"]);
27621              }
27622            } else {
27623              deltas.push(startGlyph - startCode);
27624              rangeOffsets.push(0);
27625            }
27626          }
27627
27628          subtable.writeUInt16(3);
27629          subtable.writeUInt16(1);
27630          subtable.writeUInt32(12);
27631          subtable.writeUInt16(4);
27632          subtable.writeUInt16(16 + segCount * 8 + glyphIDs.length * 2);
27633          subtable.writeUInt16(0);
27634          subtable.writeUInt16(segCountX2);
27635          subtable.writeUInt16(searchRange);
27636          subtable.writeUInt16(entrySelector);
27637          subtable.writeUInt16(rangeShift);
27638
27639          for (_m = 0, _len3 = endCodes.length; _m < _len3; _m++) {
27640            code = endCodes[_m];
27641            subtable.writeUInt16(code);
27642          }
27643
27644          subtable.writeUInt16(0);
27645
27646          for (_n = 0, _len4 = startCodes.length; _n < _len4; _n++) {
27647            code = startCodes[_n];
27648            subtable.writeUInt16(code);
27649          }
27650
27651          for (_o = 0, _len5 = deltas.length; _o < _len5; _o++) {
27652            delta = deltas[_o];
27653            subtable.writeUInt16(delta);
27654          }
27655
27656          for (_p = 0, _len6 = rangeOffsets.length; _p < _len6; _p++) {
27657            offset = rangeOffsets[_p];
27658            subtable.writeUInt16(offset);
27659          }
27660
27661          for (_q = 0, _len7 = glyphIDs.length; _q < _len7; _q++) {
27662            id = glyphIDs[_q];
27663            subtable.writeUInt16(id);
27664          }
27665
27666          return {
27667            charMap: charMap,
27668            subtable: subtable.data,
27669            maxGlyphID: nextID + 1
27670          };
27671      }
27672    };
27673
27674    return CmapEntry;
27675  }();
27676
27677  var CmapTable = function (_super) {
27678    __extends(CmapTable, _super);
27679
27680    function CmapTable() {
27681      return CmapTable.__super__.constructor.apply(this, arguments);
27682    }
27683
27684    CmapTable.prototype.tag = "cmap";
27685
27686    CmapTable.prototype.parse = function (data) {
27687      var entry, i, tableCount;
27688      data.pos = this.offset;
27689      this.version = data.readUInt16();
27690      tableCount = data.readUInt16();
27691      this.tables = [];
27692      this.unicode = null;
27693
27694      for (i = 0; 0 <= tableCount ? i < tableCount : i > tableCount; i = 0 <= tableCount ? ++i : --i) {
27695        entry = new CmapEntry(data, this.offset);
27696        this.tables.push(entry);
27697
27698        if (entry.isUnicode) {
27699          if (this.unicode == null) {
27700            this.unicode = entry;
27701          }
27702        }
27703      }
27704
27705      return true;
27706    };
27707    /*************************************************************************/
27708
27709    /* function : encode                                                     */
27710
27711    /* comment : Encode the cmap table corresponding to the input character. */
27712
27713    /*************************************************************************/
27714
27715
27716    CmapTable.encode = function (charmap, encoding) {
27717      var result, table;
27718
27719      if (encoding == null) {
27720        encoding = "macroman";
27721      }
27722
27723      result = CmapEntry.encode(charmap, encoding);
27724      table = new Data();
27725      table.writeUInt16(0);
27726      table.writeUInt16(1);
27727      result.table = table.data.concat(result.subtable);
27728      return result;
27729    };
27730
27731    return CmapTable;
27732  }(Table);
27733
27734  var HheaTable = function (_super) {
27735    __extends(HheaTable, _super);
27736
27737    function HheaTable() {
27738      return HheaTable.__super__.constructor.apply(this, arguments);
27739    }
27740
27741    HheaTable.prototype.tag = "hhea";
27742
27743    HheaTable.prototype.parse = function (data) {
27744      data.pos = this.offset;
27745      this.version = data.readInt();
27746      this.ascender = data.readShort();
27747      this.decender = data.readShort();
27748      this.lineGap = data.readShort();
27749      this.advanceWidthMax = data.readShort();
27750      this.minLeftSideBearing = data.readShort();
27751      this.minRightSideBearing = data.readShort();
27752      this.xMaxExtent = data.readShort();
27753      this.caretSlopeRise = data.readShort();
27754      this.caretSlopeRun = data.readShort();
27755      this.caretOffset = data.readShort();
27756      data.pos += 4 * 2;
27757      this.metricDataFormat = data.readShort();
27758      return this.numberOfMetrics = data.readUInt16();
27759    };
27760    /*HheaTable.prototype.encode = function (ids) {
27761              var i, table, _i, _ref;
27762              table = new Data;
27763              table.writeInt(this.version);
27764              table.writeShort(this.ascender);
27765              table.writeShort(this.decender);
27766              table.writeShort(this.lineGap);
27767              table.writeShort(this.advanceWidthMax);
27768              table.writeShort(this.minLeftSideBearing);
27769              table.writeShort(this.minRightSideBearing);
27770              table.writeShort(this.xMaxExtent);
27771              table.writeShort(this.caretSlopeRise);
27772              table.writeShort(this.caretSlopeRun);
27773              table.writeShort(this.caretOffset);
27774              for (i = _i = 0, _ref = 4 * 2; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
27775                  table.writeByte(0);
27776              }
27777              table.writeShort(this.metricDataFormat);
27778              table.writeUInt16(ids.length);
27779              return table.data;
27780          };*/
27781
27782
27783    return HheaTable;
27784  }(Table);
27785
27786  var OS2Table = function (_super) {
27787    __extends(OS2Table, _super);
27788
27789    function OS2Table() {
27790      return OS2Table.__super__.constructor.apply(this, arguments);
27791    }
27792
27793    OS2Table.prototype.tag = "OS/2";
27794
27795    OS2Table.prototype.parse = function (data) {
27796      data.pos = this.offset;
27797      this.version = data.readUInt16();
27798      this.averageCharWidth = data.readShort();
27799      this.weightClass = data.readUInt16();
27800      this.widthClass = data.readUInt16();
27801      this.type = data.readShort();
27802      this.ySubscriptXSize = data.readShort();
27803      this.ySubscriptYSize = data.readShort();
27804      this.ySubscriptXOffset = data.readShort();
27805      this.ySubscriptYOffset = data.readShort();
27806      this.ySuperscriptXSize = data.readShort();
27807      this.ySuperscriptYSize = data.readShort();
27808      this.ySuperscriptXOffset = data.readShort();
27809      this.ySuperscriptYOffset = data.readShort();
27810      this.yStrikeoutSize = data.readShort();
27811      this.yStrikeoutPosition = data.readShort();
27812      this.familyClass = data.readShort();
27813
27814      this.panose = function () {
27815        var i, _results;
27816
27817        _results = [];
27818
27819        for (i = 0; i < 10; ++i) {
27820          _results.push(data.readByte());
27821        }
27822
27823        return _results;
27824      }();
27825
27826      this.charRange = function () {
27827        var i, _results;
27828
27829        _results = [];
27830
27831        for (i = 0; i < 4; ++i) {
27832          _results.push(data.readInt());
27833        }
27834
27835        return _results;
27836      }();
27837
27838      this.vendorID = data.readString(4);
27839      this.selection = data.readShort();
27840      this.firstCharIndex = data.readShort();
27841      this.lastCharIndex = data.readShort();
27842
27843      if (this.version > 0) {
27844        this.ascent = data.readShort();
27845        this.descent = data.readShort();
27846        this.lineGap = data.readShort();
27847        this.winAscent = data.readShort();
27848        this.winDescent = data.readShort();
27849
27850        this.codePageRange = function () {
27851          var i, _results;
27852
27853          _results = [];
27854
27855          for (i = 0; i < 2; i = ++i) {
27856            _results.push(data.readInt());
27857          }
27858
27859          return _results;
27860        }();
27861
27862        if (this.version > 1) {
27863          this.xHeight = data.readShort();
27864          this.capHeight = data.readShort();
27865          this.defaultChar = data.readShort();
27866          this.breakChar = data.readShort();
27867          return this.maxContext = data.readShort();
27868        }
27869      }
27870    };
27871    /*OS2Table.prototype.encode = function () {
27872              return this.raw();
27873          };*/
27874
27875
27876    return OS2Table;
27877  }(Table);
27878
27879  var PostTable = function (_super) {
27880
27881    __extends(PostTable, _super);
27882
27883    function PostTable() {
27884      return PostTable.__super__.constructor.apply(this, arguments);
27885    }
27886
27887    PostTable.prototype.tag = "post";
27888
27889    PostTable.prototype.parse = function (data) {
27890      var length, numberOfGlyphs, _results;
27891
27892      data.pos = this.offset;
27893      this.format = data.readInt();
27894      this.italicAngle = data.readInt();
27895      this.underlinePosition = data.readShort();
27896      this.underlineThickness = data.readShort();
27897      this.isFixedPitch = data.readInt();
27898      this.minMemType42 = data.readInt();
27899      this.maxMemType42 = data.readInt();
27900      this.minMemType1 = data.readInt();
27901      this.maxMemType1 = data.readInt();
27902
27903      switch (this.format) {
27904        case 0x00010000:
27905          break;
27906
27907        case 0x00020000:
27908          numberOfGlyphs = data.readUInt16();
27909          this.glyphNameIndex = [];
27910          var i;
27911
27912          for (i = 0; 0 <= numberOfGlyphs ? i < numberOfGlyphs : i > numberOfGlyphs; i = 0 <= numberOfGlyphs ? ++i : --i) {
27913            this.glyphNameIndex.push(data.readUInt16());
27914          }
27915
27916          this.names = [];
27917          _results = [];
27918
27919          while (data.pos < this.offset + this.length) {
27920            length = data.readByte();
27921
27922            _results.push(this.names.push(data.readString(length)));
27923          }
27924
27925          return _results;
27926
27927        case 0x00025000:
27928          numberOfGlyphs = data.readUInt16();
27929          return this.offsets = data.read(numberOfGlyphs);
27930
27931        case 0x00030000:
27932          break;
27933
27934        case 0x00040000:
27935          return this.map = function () {
27936            var _j, _ref, _results1;
27937
27938            _results1 = [];
27939
27940            for (i = _j = 0, _ref = this.file.maxp.numGlyphs; 0 <= _ref ? _j < _ref : _j > _ref; i = 0 <= _ref ? ++_j : --_j) {
27941              _results1.push(data.readUInt32());
27942            }
27943
27944            return _results1;
27945          }.call(this);
27946      }
27947    };
27948    return PostTable;
27949  }(Table);
27950  /*********************************************************************************************************/
27951
27952  /* function : NameEntry                                                                                  */
27953
27954  /* comment : Store copyright information, platformID, encodingID, and languageID in the NameEntry object.*/
27955
27956  /*********************************************************************************************************/
27957
27958
27959  var NameEntry = function () {
27960    function NameEntry(raw, entry) {
27961      this.raw = raw;
27962      this.length = raw.length;
27963      this.platformID = entry.platformID;
27964      this.encodingID = entry.encodingID;
27965      this.languageID = entry.languageID;
27966    }
27967
27968    return NameEntry;
27969  }();
27970
27971  var NameTable = function (_super) {
27972
27973    __extends(NameTable, _super);
27974
27975    function NameTable() {
27976      return NameTable.__super__.constructor.apply(this, arguments);
27977    }
27978
27979    NameTable.prototype.tag = "name";
27980
27981    NameTable.prototype.parse = function (data) {
27982      var count, entries, entry, i, name, stringOffset, strings, text, _j, _len, _name;
27983
27984      data.pos = this.offset;
27985      data.readShort(); //format
27986
27987      count = data.readShort();
27988      stringOffset = data.readShort();
27989      entries = [];
27990
27991      for (i = 0; 0 <= count ? i < count : i > count; i = 0 <= count ? ++i : --i) {
27992        entries.push({
27993          platformID: data.readShort(),
27994          encodingID: data.readShort(),
27995          languageID: data.readShort(),
27996          nameID: data.readShort(),
27997          length: data.readShort(),
27998          offset: this.offset + stringOffset + data.readShort()
27999        });
28000      }
28001
28002      strings = {};
28003
28004      for (i = _j = 0, _len = entries.length; _j < _len; i = ++_j) {
28005        entry = entries[i];
28006        data.pos = entry.offset;
28007        text = data.readString(entry.length);
28008        name = new NameEntry(text, entry);
28009
28010        if (strings[_name = entry.nameID] == null) {
28011          strings[_name] = [];
28012        }
28013
28014        strings[entry.nameID].push(name);
28015      }
28016
28017      this.strings = strings;
28018      this.copyright = strings[0];
28019      this.fontFamily = strings[1];
28020      this.fontSubfamily = strings[2];
28021      this.uniqueSubfamily = strings[3];
28022      this.fontName = strings[4];
28023      this.version = strings[5];
28024
28025      try {
28026        this.postscriptName = strings[6][0].raw.replace(/[\x00-\x19\x80-\xff]/g, "");
28027      } catch (e) {
28028        this.postscriptName = strings[4][0].raw.replace(/[\x00-\x19\x80-\xff]/g, "");
28029      }
28030
28031      this.trademark = strings[7];
28032      this.manufacturer = strings[8];
28033      this.designer = strings[9];
28034      this.description = strings[10];
28035      this.vendorUrl = strings[11];
28036      this.designerUrl = strings[12];
28037      this.license = strings[13];
28038      this.licenseUrl = strings[14];
28039      this.preferredFamily = strings[15];
28040      this.preferredSubfamily = strings[17];
28041      this.compatibleFull = strings[18];
28042      return this.sampleText = strings[19];
28043    };
28044    /*NameTable.prototype.encode = function () {
28045              var id, list, nameID, nameTable, postscriptName, strCount, strTable, string, strings, table, val, _i, _len, _ref;
28046              strings = {};
28047              _ref = this.strings;
28048              for (id in _ref) {
28049                  val = _ref[id];
28050                  strings[id] = val;
28051              }
28052              postscriptName = new NameEntry("" + subsetTag + "+" + this.postscriptName, {
28053                  platformID: 1
28054                  , encodingID: 0
28055                  , languageID: 0
28056              });
28057              strings[6] = [postscriptName];
28058              subsetTag = successorOf(subsetTag);
28059              strCount = 0;
28060              for (id in strings) {
28061                  list = strings[id];
28062                  if (list != null) {
28063                      strCount += list.length;
28064                  }
28065              }
28066              table = new Data;
28067              strTable = new Data;
28068              table.writeShort(0);
28069              table.writeShort(strCount);
28070              table.writeShort(6 + 12 * strCount);
28071              for (nameID in strings) {
28072                  list = strings[nameID];
28073                  if (list != null) {
28074                      for (_i = 0, _len = list.length; _i < _len; _i++) {
28075                          string = list[_i];
28076                          table.writeShort(string.platformID);
28077                          table.writeShort(string.encodingID);
28078                          table.writeShort(string.languageID);
28079                          table.writeShort(nameID);
28080                          table.writeShort(string.length);
28081                          table.writeShort(strTable.pos);
28082                          strTable.writeString(string.raw);
28083                      }
28084                  }
28085              }
28086              return nameTable = {
28087                  postscriptName: postscriptName.raw
28088                  , table: table.data.concat(strTable.data)
28089              };
28090          };*/
28091
28092    return NameTable;
28093  }(Table);
28094
28095  var MaxpTable = function (_super) {
28096    __extends(MaxpTable, _super);
28097
28098    function MaxpTable() {
28099      return MaxpTable.__super__.constructor.apply(this, arguments);
28100    }
28101
28102    MaxpTable.prototype.tag = "maxp";
28103
28104    MaxpTable.prototype.parse = function (data) {
28105      data.pos = this.offset;
28106      this.version = data.readInt();
28107      this.numGlyphs = data.readUInt16();
28108      this.maxPoints = data.readUInt16();
28109      this.maxContours = data.readUInt16();
28110      this.maxCompositePoints = data.readUInt16();
28111      this.maxComponentContours = data.readUInt16();
28112      this.maxZones = data.readUInt16();
28113      this.maxTwilightPoints = data.readUInt16();
28114      this.maxStorage = data.readUInt16();
28115      this.maxFunctionDefs = data.readUInt16();
28116      this.maxInstructionDefs = data.readUInt16();
28117      this.maxStackElements = data.readUInt16();
28118      this.maxSizeOfInstructions = data.readUInt16();
28119      this.maxComponentElements = data.readUInt16();
28120      return this.maxComponentDepth = data.readUInt16();
28121    };
28122    /*MaxpTable.prototype.encode = function (ids) {
28123              var table;
28124              table = new Data;
28125              table.writeInt(this.version);
28126              table.writeUInt16(ids.length);
28127              table.writeUInt16(this.maxPoints);
28128              table.writeUInt16(this.maxContours);
28129              table.writeUInt16(this.maxCompositePoints);
28130              table.writeUInt16(this.maxComponentContours);
28131              table.writeUInt16(this.maxZones);
28132              table.writeUInt16(this.maxTwilightPoints);
28133              table.writeUInt16(this.maxStorage);
28134              table.writeUInt16(this.maxFunctionDefs);
28135              table.writeUInt16(this.maxInstructionDefs);
28136              table.writeUInt16(this.maxStackElements);
28137              table.writeUInt16(this.maxSizeOfInstructions);
28138              table.writeUInt16(this.maxComponentElements);
28139              table.writeUInt16(this.maxComponentDepth);
28140              return table.data;
28141          };*/
28142
28143
28144    return MaxpTable;
28145  }(Table);
28146
28147  var HmtxTable = function (_super) {
28148    __extends(HmtxTable, _super);
28149
28150    function HmtxTable() {
28151      return HmtxTable.__super__.constructor.apply(this, arguments);
28152    }
28153
28154    HmtxTable.prototype.tag = "hmtx";
28155
28156    HmtxTable.prototype.parse = function (data) {
28157      var i, last, lsbCount, m, _j, _ref, _results;
28158
28159      data.pos = this.offset;
28160      this.metrics = [];
28161
28162      for (i = 0, _ref = this.file.hhea.numberOfMetrics; 0 <= _ref ? i < _ref : i > _ref; i = 0 <= _ref ? ++i : --i) {
28163        this.metrics.push({
28164          advance: data.readUInt16(),
28165          lsb: data.readInt16()
28166        });
28167      }
28168
28169      lsbCount = this.file.maxp.numGlyphs - this.file.hhea.numberOfMetrics;
28170
28171      this.leftSideBearings = function () {
28172        var _j, _results;
28173
28174        _results = [];
28175
28176        for (i = _j = 0; 0 <= lsbCount ? _j < lsbCount : _j > lsbCount; i = 0 <= lsbCount ? ++_j : --_j) {
28177          _results.push(data.readInt16());
28178        }
28179
28180        return _results;
28181      }();
28182
28183      this.widths = function () {
28184        var _j, _len, _ref1, _results;
28185
28186        _ref1 = this.metrics;
28187        _results = [];
28188
28189        for (_j = 0, _len = _ref1.length; _j < _len; _j++) {
28190          m = _ref1[_j];
28191
28192          _results.push(m.advance);
28193        }
28194
28195        return _results;
28196      }.call(this);
28197
28198      last = this.widths[this.widths.length - 1];
28199      _results = [];
28200
28201      for (i = _j = 0; 0 <= lsbCount ? _j < lsbCount : _j > lsbCount; i = 0 <= lsbCount ? ++_j : --_j) {
28202        _results.push(this.widths.push(last));
28203      }
28204
28205      return _results;
28206    };
28207    /***************************************************************/
28208
28209    /* function : forGlyph                                         */
28210
28211    /* comment : Returns the advance width and lsb for this glyph. */
28212
28213    /***************************************************************/
28214
28215
28216    HmtxTable.prototype.forGlyph = function (id) {
28217      if (id in this.metrics) {
28218        return this.metrics[id];
28219      }
28220
28221      return {
28222        advance: this.metrics[this.metrics.length - 1].advance,
28223        lsb: this.leftSideBearings[id - this.metrics.length]
28224      };
28225    };
28226    /*HmtxTable.prototype.encode = function (mapping) {
28227              var id, metric, table, _i, _len;
28228              table = new Data;
28229              for (_i = 0, _len = mapping.length; _i < _len; _i++) {
28230                  id = mapping[_i];
28231                  metric = this.forGlyph(id);
28232                  table.writeUInt16(metric.advance);
28233                  table.writeUInt16(metric.lsb);
28234              }
28235              return table.data;
28236          };*/
28237
28238
28239    return HmtxTable;
28240  }(Table);
28241
28242  var __slice = [].slice;
28243
28244  var GlyfTable = function (_super) {
28245    __extends(GlyfTable, _super);
28246
28247    function GlyfTable() {
28248      return GlyfTable.__super__.constructor.apply(this, arguments);
28249    }
28250
28251    GlyfTable.prototype.tag = "glyf";
28252
28253    GlyfTable.prototype.parse = function () {
28254      return this.cache = {};
28255    };
28256
28257    GlyfTable.prototype.glyphFor = function (id) {
28258      var data, index, length, loca, numberOfContours, raw, xMax, xMin, yMax, yMin;
28259
28260      if (id in this.cache) {
28261        return this.cache[id];
28262      }
28263
28264      loca = this.file.loca;
28265      data = this.file.contents;
28266      index = loca.indexOf(id);
28267      length = loca.lengthOf(id);
28268
28269      if (length === 0) {
28270        return this.cache[id] = null;
28271      }
28272
28273      data.pos = this.offset + index;
28274      raw = new Data(data.read(length));
28275      numberOfContours = raw.readShort();
28276      xMin = raw.readShort();
28277      yMin = raw.readShort();
28278      xMax = raw.readShort();
28279      yMax = raw.readShort();
28280
28281      if (numberOfContours === -1) {
28282        this.cache[id] = new CompoundGlyph(raw, xMin, yMin, xMax, yMax);
28283      } else {
28284        this.cache[id] = new SimpleGlyph(raw, numberOfContours, xMin, yMin, xMax, yMax);
28285      }
28286
28287      return this.cache[id];
28288    };
28289
28290    GlyfTable.prototype.encode = function (glyphs, mapping, old2new) {
28291      var glyph, id, offsets, table, _i, _len;
28292
28293      table = [];
28294      offsets = [];
28295
28296      for (_i = 0, _len = mapping.length; _i < _len; _i++) {
28297        id = mapping[_i];
28298        glyph = glyphs[id];
28299        offsets.push(table.length);
28300
28301        if (glyph) {
28302          table = table.concat(glyph.encode(old2new));
28303        }
28304      }
28305
28306      offsets.push(table.length);
28307      return {
28308        table: table,
28309        offsets: offsets
28310      };
28311    };
28312
28313    return GlyfTable;
28314  }(Table);
28315
28316  var SimpleGlyph = function () {
28317    /**************************************************************************/
28318
28319    /* function : SimpleGlyph                                                 */
28320
28321    /* comment : Stores raw, xMin, yMin, xMax, and yMax values for this glyph.*/
28322
28323    /**************************************************************************/
28324    function SimpleGlyph(raw, numberOfContours, xMin, yMin, xMax, yMax) {
28325      this.raw = raw;
28326      this.numberOfContours = numberOfContours;
28327      this.xMin = xMin;
28328      this.yMin = yMin;
28329      this.xMax = xMax;
28330      this.yMax = yMax;
28331      this.compound = false;
28332    }
28333
28334    SimpleGlyph.prototype.encode = function () {
28335      return this.raw.data;
28336    };
28337
28338    return SimpleGlyph;
28339  }();
28340
28341  var CompoundGlyph = function () {
28342    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;
28343    ARG_1_AND_2_ARE_WORDS = 0x0001;
28344    WE_HAVE_A_SCALE = 0x0008;
28345    MORE_COMPONENTS = 0x0020;
28346    WE_HAVE_AN_X_AND_Y_SCALE = 0x0040;
28347    WE_HAVE_A_TWO_BY_TWO = 0x0080;
28348    /********************************************************************************************************************/
28349
28350    /* function : CompoundGlypg generator                                                                               */
28351
28352    /* comment : It stores raw, xMin, yMin, xMax, yMax, glyph id, and glyph offset for the corresponding compound glyph.*/
28353
28354    /********************************************************************************************************************/
28355
28356    function CompoundGlyph(raw, xMin, yMin, xMax, yMax) {
28357      var data, flags;
28358      this.raw = raw;
28359      this.xMin = xMin;
28360      this.yMin = yMin;
28361      this.xMax = xMax;
28362      this.yMax = yMax;
28363      this.compound = true;
28364      this.glyphIDs = [];
28365      this.glyphOffsets = [];
28366      data = this.raw;
28367
28368      while (true) {
28369        flags = data.readShort();
28370        this.glyphOffsets.push(data.pos);
28371        this.glyphIDs.push(data.readUInt16());
28372
28373        if (!(flags & MORE_COMPONENTS)) {
28374          break;
28375        }
28376
28377        if (flags & ARG_1_AND_2_ARE_WORDS) {
28378          data.pos += 4;
28379        } else {
28380          data.pos += 2;
28381        }
28382
28383        if (flags & WE_HAVE_A_TWO_BY_TWO) {
28384          data.pos += 8;
28385        } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {
28386          data.pos += 4;
28387        } else if (flags & WE_HAVE_A_SCALE) {
28388          data.pos += 2;
28389        }
28390      }
28391    }
28392    /****************************************************************************************************************/
28393
28394    /* function : CompoundGlypg encode                                                                              */
28395
28396    /* comment : After creating a table for the characters you typed, you call directory.encode to encode the table.*/
28397
28398    /****************************************************************************************************************/
28399
28400
28401    CompoundGlyph.prototype.encode = function () {
28402      var i, result, _len, _ref;
28403
28404      result = new Data(__slice.call(this.raw.data));
28405      _ref = this.glyphIDs;
28406
28407      for (i = 0, _len = _ref.length; i < _len; ++i) {
28408        result.pos = this.glyphOffsets[i];
28409      }
28410
28411      return result.data;
28412    };
28413
28414    return CompoundGlyph;
28415  }();
28416
28417  var LocaTable = function (_super) {
28418    __extends(LocaTable, _super);
28419
28420    function LocaTable() {
28421      return LocaTable.__super__.constructor.apply(this, arguments);
28422    }
28423
28424    LocaTable.prototype.tag = "loca";
28425
28426    LocaTable.prototype.parse = function (data) {
28427      var format, i;
28428      data.pos = this.offset;
28429      format = this.file.head.indexToLocFormat;
28430
28431      if (format === 0) {
28432        return this.offsets = function () {
28433          var _ref, _results;
28434
28435          _results = [];
28436
28437          for (i = 0, _ref = this.length; i < _ref; i += 2) {
28438            _results.push(data.readUInt16() * 2);
28439          }
28440
28441          return _results;
28442        }.call(this);
28443      } else {
28444        return this.offsets = function () {
28445          var _ref, _results;
28446
28447          _results = [];
28448
28449          for (i = 0, _ref = this.length; i < _ref; i += 4) {
28450            _results.push(data.readUInt32());
28451          }
28452
28453          return _results;
28454        }.call(this);
28455      }
28456    };
28457
28458    LocaTable.prototype.indexOf = function (id) {
28459      return this.offsets[id];
28460    };
28461
28462    LocaTable.prototype.lengthOf = function (id) {
28463      return this.offsets[id + 1] - this.offsets[id];
28464    };
28465
28466    LocaTable.prototype.encode = function (offsets, activeGlyphs) {
28467      var LocaTable = new Uint32Array(this.offsets.length);
28468      var glyfPtr = 0;
28469      var listGlyf = 0;
28470
28471      for (var k = 0; k < LocaTable.length; ++k) {
28472        LocaTable[k] = glyfPtr;
28473
28474        if (listGlyf < activeGlyphs.length && activeGlyphs[listGlyf] == k) {
28475          ++listGlyf;
28476          LocaTable[k] = glyfPtr;
28477          var start = this.offsets[k];
28478          var len = this.offsets[k + 1] - start;
28479
28480          if (len > 0) {
28481            glyfPtr += len;
28482          }
28483        }
28484      }
28485
28486      var newLocaTable = new Array(LocaTable.length * 4);
28487
28488      for (var j = 0; j < LocaTable.length; ++j) {
28489        newLocaTable[4 * j + 3] = LocaTable[j] & 0x000000ff;
28490        newLocaTable[4 * j + 2] = (LocaTable[j] & 0x0000ff00) >> 8;
28491        newLocaTable[4 * j + 1] = (LocaTable[j] & 0x00ff0000) >> 16;
28492        newLocaTable[4 * j] = (LocaTable[j] & 0xff000000) >> 24;
28493      }
28494
28495      return newLocaTable;
28496    };
28497
28498    return LocaTable;
28499  }(Table);
28500  /************************************************************************************/
28501
28502  /* function : invert                                                                */
28503
28504  /* comment : Change the object's (key: value) to create an object with (value: key).*/
28505
28506  /************************************************************************************/
28507
28508
28509  var invert = function invert(object) {
28510    var key, ret, val;
28511    ret = {};
28512
28513    for (key in object) {
28514      val = object[key];
28515      ret[val] = key;
28516    }
28517
28518    return ret;
28519  };
28520  /*var successorOf = function (input) {
28521          var added, alphabet, carry, i, index, isUpperCase, last, length, next, result;
28522          alphabet = 'abcdefghijklmnopqrstuvwxyz';
28523          length = alphabet.length;
28524          result = input;
28525          i = input.length;
28526          while (i >= 0) {
28527              last = input.charAt(--i);
28528              if (isNaN(last)) {
28529                  index = alphabet.indexOf(last.toLowerCase());
28530                  if (index === -1) {
28531                      next = last;
28532                      carry = true;
28533                  }
28534                  else {
28535                      next = alphabet.charAt((index + 1) % length);
28536                      isUpperCase = last === last.toUpperCase();
28537                      if (isUpperCase) {
28538                          next = next.toUpperCase();
28539                      }
28540                      carry = index + 1 >= length;
28541                      if (carry && i === 0) {
28542                          added = isUpperCase ? 'A' : 'a';
28543                          result = added + next + result.slice(1);
28544                          break;
28545                      }
28546                  }
28547              }
28548              else {
28549                  next = +last + 1;
28550                  carry = next > 9;
28551                  if (carry) {
28552                      next = 0;
28553                  }
28554                  if (carry && i === 0) {
28555                      result = '1' + next + result.slice(1);
28556                      break;
28557                  }
28558              }
28559              result = result.slice(0, i) + next + result.slice(i + 1);
28560              if (!carry) {
28561                  break;
28562              }
28563          }
28564          return result;
28565      };*/
28566
28567
28568  var Subset = function () {
28569    function Subset(font) {
28570      this.font = font;
28571      this.subset = {};
28572      this.unicodes = {};
28573      this.next = 33;
28574    }
28575    /*Subset.prototype.use = function (character) {
28576              var i, _i, _ref;
28577              if (typeof character === 'string') {
28578                  for (i = _i = 0, _ref = character.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
28579                      this.use(character.charCodeAt(i));
28580                  }
28581                  return;
28582              }
28583              if (!this.unicodes[character]) {
28584                  this.subset[this.next] = character;
28585                  return this.unicodes[character] = this.next++;
28586              }
28587          };*/
28588
28589    /*Subset.prototype.encodeText = function (text) {
28590              var char, i, string, _i, _ref;
28591              string = '';
28592              for (i = _i = 0, _ref = text.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
28593                  char = this.unicodes[text.charCodeAt(i)];
28594                  string += String.fromCharCode(char);
28595              }
28596              return string;
28597          };*/
28598
28599    /***************************************************************/
28600
28601    /* function : generateCmap                                     */
28602
28603    /* comment : Returns the unicode cmap for this font.         */
28604
28605    /***************************************************************/
28606
28607
28608    Subset.prototype.generateCmap = function () {
28609      var mapping, roman, unicode, unicodeCmap, _ref;
28610
28611      unicodeCmap = this.font.cmap.tables[0].codeMap;
28612      mapping = {};
28613      _ref = this.subset;
28614
28615      for (roman in _ref) {
28616        unicode = _ref[roman];
28617        mapping[roman] = unicodeCmap[unicode];
28618      }
28619
28620      return mapping;
28621    };
28622    /*Subset.prototype.glyphIDs = function () {
28623              var ret, roman, unicode, unicodeCmap, val, _ref;
28624              unicodeCmap = this.font.cmap.tables[0].codeMap;
28625              ret = [0];
28626              _ref = this.subset;
28627              for (roman in _ref) {
28628                  unicode = _ref[roman];
28629                  val = unicodeCmap[unicode];
28630                  if ((val != null) && __indexOf.call(ret, val) < 0) {
28631                      ret.push(val);
28632                  }
28633              }
28634              return ret.sort();
28635          };*/
28636
28637    /******************************************************************/
28638
28639    /* function : glyphsFor                                           */
28640
28641    /* comment : Returns simple glyph objects for the input character.*/
28642
28643    /******************************************************************/
28644
28645
28646    Subset.prototype.glyphsFor = function (glyphIDs) {
28647      var additionalIDs, glyph, glyphs, id, _i, _len, _ref;
28648
28649      glyphs = {};
28650
28651      for (_i = 0, _len = glyphIDs.length; _i < _len; _i++) {
28652        id = glyphIDs[_i];
28653        glyphs[id] = this.font.glyf.glyphFor(id);
28654      }
28655
28656      additionalIDs = [];
28657
28658      for (id in glyphs) {
28659        glyph = glyphs[id];
28660
28661        if (glyph != null ? glyph.compound : void 0) {
28662          additionalIDs.push.apply(additionalIDs, glyph.glyphIDs);
28663        }
28664      }
28665
28666      if (additionalIDs.length > 0) {
28667        _ref = this.glyphsFor(additionalIDs);
28668
28669        for (id in _ref) {
28670          glyph = _ref[id];
28671          glyphs[id] = glyph;
28672        }
28673      }
28674
28675      return glyphs;
28676    };
28677    /***************************************************************/
28678
28679    /* function : encode                                           */
28680
28681    /* comment : Encode various tables for the characters you use. */
28682
28683    /***************************************************************/
28684
28685
28686    Subset.prototype.encode = function (glyID, indexToLocFormat) {
28687      var cmap, code, glyf, glyphs, id, ids, loca, new2old, newIDs, nextGlyphID, old2new, oldID, oldIDs, tables, _ref;
28688
28689      cmap = CmapTable.encode(this.generateCmap(), "unicode");
28690      glyphs = this.glyphsFor(glyID);
28691      old2new = {
28692        0: 0
28693      };
28694      _ref = cmap.charMap;
28695
28696      for (code in _ref) {
28697        ids = _ref[code];
28698        old2new[ids.old] = ids["new"];
28699      }
28700
28701      nextGlyphID = cmap.maxGlyphID;
28702
28703      for (oldID in glyphs) {
28704        if (!(oldID in old2new)) {
28705          old2new[oldID] = nextGlyphID++;
28706        }
28707      }
28708
vendor: 3,649 bytes, lines 28709-28833
28709      new2old = invert(old2new);
28710      newIDs = Object.keys(new2old).sort(function (a, b) {
28711        return a - b;
28712      });
28713
28714      oldIDs = function () {
28715        var _i, _len, _results;
28716
28717        _results = [];
28718
28719        for (_i = 0, _len = newIDs.length; _i < _len; _i++) {
28720          id = newIDs[_i];
28721
28722          _results.push(new2old[id]);
28723        }
28724
28725        return _results;
28726      }();
28727
28728      glyf = this.font.glyf.encode(glyphs, oldIDs, old2new);
28729      loca = this.font.loca.encode(glyf.offsets, oldIDs);
28730      tables = {
28731        cmap: this.font.cmap.raw(),
28732        glyf: glyf.table,
28733        loca: loca,
28734        hmtx: this.font.hmtx.raw(),
28735        hhea: this.font.hhea.raw(),
28736        maxp: this.font.maxp.raw(),
28737        post: this.font.post.raw(),
28738        name: this.font.name.raw(),
28739        head: this.font.head.encode(indexToLocFormat)
28740      };
28741
28742      if (this.font.os2.exists) {
28743        tables["OS/2"] = this.font.os2.raw();
28744      }
28745
28746      return this.font.directory.encode(tables);
28747    };
28748
28749    return Subset;
28750  }();
28751
28752  jsPDF.API.PDFObject = function () {
28753    var pad;
28754
28755    function PDFObject() {}
28756
28757    pad = function pad(str, length) {
28758      return (Array(length + 1).join("0") + str).slice(-length);
28759    };
28760    /*****************************************************************************/
28761
28762    /* function : convert                                                        */
28763
28764    /* comment :Converts pdf tag's / FontBBox and array values in / W to strings */
28765
28766    /*****************************************************************************/
28767
28768
28769    PDFObject.convert = function (object) {
28770      var e, items, key, out, val;
28771
28772      if (Array.isArray(object)) {
28773        items = function () {
28774          var _i, _len, _results;
28775
28776          _results = [];
28777
28778          for (_i = 0, _len = object.length; _i < _len; _i++) {
28779            e = object[_i];
28780
28781            _results.push(PDFObject.convert(e));
28782          }
28783
28784          return _results;
28785        }().join(" ");
28786
28787        return "[" + items + "]";
28788      } else if (typeof object === "string") {
28789        return "/" + object;
28790      } else if (object != null ? object.isString : void 0) {
28791        return "(" + object + ")";
28792      } else if (object instanceof Date) {
28793        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)";
28794      } else if ({}.toString.call(object) === "[object Object]") {
28795        out = ["<<"];
28796
28797        for (key in object) {
28798          val = object[key];
28799          out.push("/" + key + " " + PDFObject.convert(val));
28800        }
28801
28802        out.push(">>");
28803        return out.join("\n");
28804      } else {
28805        return "" + object;
28806      }
28807    };
28808
28809    return PDFObject;
28810  }();
28811
28812  exports.AcroForm = AcroForm;
28813  exports.AcroFormAppearance = AcroFormAppearance;
28814  exports.AcroFormButton = AcroFormButton;
28815  exports.AcroFormCheckBox = AcroFormCheckBox;
28816  exports.AcroFormChoiceField = AcroFormChoiceField;
28817  exports.AcroFormComboBox = AcroFormComboBox;
28818  exports.AcroFormEditBox = AcroFormEditBox;
28819  exports.AcroFormListBox = AcroFormListBox;
28820  exports.AcroFormPasswordField = AcroFormPasswordField;
28821  exports.AcroFormPushButton = AcroFormPushButton;
28822  exports.AcroFormRadioButton = AcroFormRadioButton;
28823  exports.AcroFormTextField = AcroFormTextField;
28824  exports.GState = GState;
28825  exports.ShadingPattern = ShadingPattern;
28826  exports.TilingPattern = TilingPattern;
28827  exports.default = jsPDF;
28828  exports.jsPDF = jsPDF;
28829
28830  Object.defineProperty(exports, '__esModule', { value: true });
28831
28832})));
28833//# sourceMappingURL=jspdf.umd.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.