1/* HTML2canvas */ 2 3/* 4 html2canvas 0.5.0-alpha1 <http://html2canvas.hertzen.com> 5 Copyright (c) 2015 Niklas von Hertzen 6 7 Released under MIT License 8*/ 9 10(function(window, document, exports, global, define, undefined){ 11 12/*! 13 * @overview es6-promise - a tiny implementation of Promises/A+. 14 * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) 15 * @license Licensed under MIT license 16 * See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE 17 * @version 2.0.1 18 */ 19 20(function(){function r(a,b){n[l]=a;n[l+1]=b;l+=2;2===l&&A()}function s(a){return"function"===typeof a}function F(){return function(){process.nextTick(t)}}function G(){var a=0,b=new B(t),c=document.createTextNode("");b.observe(c,{characterData:!0});return function(){c.data=a=++a%2}}function H(){var a=new MessageChannel;a.port1.onmessage=t;return function(){a.port2.postMessage(0)}}function I(){return function(){setTimeout(t,1)}}function t(){for(var a=0;a<l;a+=2)(0,n[a])(n[a+1]),n[a]=void 0,n[a+1]=void 0; 21l=0}function p(){}function J(a,b,c,d){try{a.call(b,c,d)}catch(e){return e}}function K(a,b,c){r(function(a){var e=!1,f=J(c,b,function(c){e||(e=!0,b!==c?q(a,c):m(a,c))},function(b){e||(e=!0,g(a,b))});!e&&f&&(e=!0,g(a,f))},a)}function L(a,b){1===b.a?m(a,b.b):2===a.a?g(a,b.b):u(b,void 0,function(b){q(a,b)},function(b){g(a,b)})}function q(a,b){if(a===b)g(a,new TypeError("You cannot resolve a promise with itself"));else if("function"===typeof b||"object"===typeof b&&null!==b)if(b.constructor===a.constructor)L(a, 22b);else{var c;try{c=b.then}catch(d){v.error=d,c=v}c===v?g(a,v.error):void 0===c?m(a,b):s(c)?K(a,b,c):m(a,b)}else m(a,b)}function M(a){a.f&&a.f(a.b);x(a)}function m(a,b){void 0===a.a&&(a.b=b,a.a=1,0!==a.e.length&&r(x,a))}function g(a,b){void 0===a.a&&(a.a=2,a.b=b,r(M,a))}function u(a,b,c,d){var e=a.e,f=e.length;a.f=null;e[f]=b;e[f+1]=c;e[f+2]=d;0===f&&a.a&&r(x,a)}function x(a){var b=a.e,c=a.a;if(0!==b.length){for(var d,e,f=a.b,g=0;g<b.length;g+=3)d=b[g],e=b[g+c],d?C(c,d,e,f):e(f);a.e.length=0}}function D(){this.error= 23null}function C(a,b,c,d){var e=s(c),f,k,h,l;if(e){try{f=c(d)}catch(n){y.error=n,f=y}f===y?(l=!0,k=f.error,f=null):h=!0;if(b===f){g(b,new TypeError("A promises callback cannot return that same promise."));return}}else f=d,h=!0;void 0===b.a&&(e&&h?q(b,f):l?g(b,k):1===a?m(b,f):2===a&&g(b,f))}function N(a,b){try{b(function(b){q(a,b)},function(b){g(a,b)})}catch(c){g(a,c)}}function k(a,b,c,d){this.n=a;this.c=new a(p,d);this.i=c;this.o(b)?(this.m=b,this.d=this.length=b.length,this.l(),0===this.length?m(this.c, 24this.b):(this.length=this.length||0,this.k(),0===this.d&&m(this.c,this.b))):g(this.c,this.p())}function h(a){O++;this.b=this.a=void 0;this.e=[];if(p!==a){if(!s(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof h))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object c
24onstructor cannot be called as a function.");N(this,a)}}var E=Array.isArray?Array.isArray:function(a){return"[object Array]"=== 25Object.prototype.toString.call(a)},l=0,w="undefined"!==typeof window?window:{},B=w.MutationObserver||w.WebKitMutationObserver,w="undefined"!==typeof Uint8ClampedArray&&"undefined"!==typeof importScripts&&"undefined"!==typeof MessageChannel,n=Array(1E3),A;A="undefined"!==typeof process&&"[object process]"==={}.toString.call(process)?F():B?G():w?H():I();var v=new D,y=new D;k.prototype.o=function(a){return E(a)};k.prototype.p=function(){return Error("Array Methods must be provided an Array")};k.prototype.l= 26function(){this.b=Array(this.length)};k.prototype.k=function(){for(var a=this.length,b=this.c,c=this.m,d=0;void 0===b.a&&d<a;d++)this.j(c[d],d)};k.prototype.j=function(a,b){var c=this.n;"object"===typeof a&&null!==a?a.constructor===c&&void 0!==a.a?(a.f=null,this.g(a.a,b,a.b)):this.q(c.resolve(a),b):(this.d--,this.b[b]=this.h(a))};k.prototype.g=function(a,b,c){var d=this.c;void 0===d.a&&(this.d--,this.i&&2===a?g(d,c):this.b[b]=this.h(c));0===this.d&&m(d,this.b)};k.prototype.h=function(a){return a}; 27k.prototype.q=function(a,b){var c=this;u(a,void 0,function(a){c.g(1,b,a)},function(a){c.g(2,b,a)})};var O=0;h.all=function(a,b){return(new k(this,a,!0,b)).c};h.race=function(a,b){function c(a){q(e,a)}function d(a){g(e,a)}var e=new this(p,b);if(!E(a))return (g(e,new TypeError("You must pass an array to race.")), e);for(var f=a.length,h=0;void 0===e.a&&h<f;h++)u(this.resolve(a[h]),void 0,c,d);return e};h.resolve=function(a,b){if(a&&"object"===typeof a&&a.constructor===this)return a;var c=new this(p,b); 28q(c,a);return c};h.reject=function(a,b){var c=new this(p,b);g(c,a);return c};h.prototype={constructor:h,then:function(a,b){var c=this.a;if(1===c&&!a||2===c&&!b)return this;var d=new this.constructor(p),e=this.b;if(c){var f=arguments[c-1];r(function(){C(c,d,f,e)})}else u(this,d,a,b);return d},"catch":function(a){return this.then(null,a)}};var z={Promise:h,polyfill:function(){var a;a="undefined"!==typeof global?global:"undefined"!==typeof window&&window.document?window:self;"Promise"in a&&"resolve"in 29a.Promise&&"reject"in a.Promise&&"all"in a.Promise&&"race"in a.Promise&&function(){var b;new a.Promise(function(a){b=a});return s(b)}()||(a.Promise=h)}};"function"===typeof define&&define.amd?define(function(){return z}):"undefined"!==typeof module&&module.exports?module.exports=z:"undefined"!==typeof this&&(this.ES6Promise=z);}).call(window); 30if (window) { 31 window.ES6Promise.polyfill(); 32} 33 34 35if (typeof(document) === "undefined" || typeof(Object.create) !== "function" || typeof(document.createElement("canvas").getContext) !== "function") { 36 (window || module.exports).html2canvas = function() { 37 return Promise.reject("No canvas support"); 38 }; 39 return; 40} 41 42/*! https://mths.be/punycode v1.3.1 by @mathias */ 43;(function(root) { 44 45 /** Detect free variables */ 46 var freeExports = typeof exports == 'object' && exports && 47 !exports.nodeType && exports; 48 var freeModule = typeof module == 'object' && module && 49 !module.nodeType && module; 50 var freeGlobal = typeof global == 'object' && global; 51 if ( 52 freeGlobal.global === freeGlobal || 53 freeGlobal.window === freeGlobal || 54 freeGlobal.self === freeGlobal 55 ) { 56 root = freeGlobal; 57 } 58 59 /** 60 * The `punycode` object. 61 * @name punycode 62 * @type Object 63 */ 64 var punycode, 65 66 /** Highest positive signed 32-bit float value */ 67 maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 68 69 /** Bootstring parameters */ 70 base = 36, 71 tMin = 1, 72 tMax = 26, 73 skew = 38, 74 damp = 700, 75 initialBias = 72, 76 initialN = 128, // 0x80 77 delimiter = '-', // '\x2D' 78 79 /** Regular expressions */ 80 regexPunycode = /^xn--/, 81 regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars 82 regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators 83 84 /** Error messages */ 85 errors = { 86 'overflow': 'Overflow: input needs wider integers to process', 87 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', 88 'invalid-input': 'Invalid input' 89 }, 90 91 /** Convenience shortcuts */ 92 baseMinusTMin = base - tMin, 93 floor = Math.floor, 94 stringFromCharCode = String.fromCharCode, 95 96 /** Temporary variable */ 97 key; 98 99 /*--------------------------------------------------------------------------*/ 100 101 /** 102 * A generic error utility function. 103 * @private 104 * @param {String} type The error type. 105 * @returns {Error} Throws a `RangeError` with the applicable error message. 106 */ 107 function error(type) { 108 throw RangeError(errors[type]); 109 } 110 111 /** 112 * A generic `Array#map` utility function. 113 * @private 114 * @param {Array} array The array to iterate over. 115 * @param {Function} callback The function that gets called for every array 116 * item. 117 * @returns {Array} A new array of values returned by the callback function. 118 */ 119 function map(array, fn) { 120 var length = array.length; 121 var result = []; 122 while (length--) { 123 result[length] = fn(array[length]); 124 } 125 return result; 126 } 127 128 /** 129 * A simple `Array#map`-like wrapper to work with domain name strings or email 130 * addresses. 131 * @private 132 * @param {String} domain The domain name or email address. 133 * @param {Function} callback The function that gets called for every 134 * character. 135 * @returns {Array} A new string of characters returned by the callback 136 * function. 137 */ 138 function mapDomain(string, fn) { 139 var parts = string.split('@'); 140 var result = ''; 141 if (parts.length > 1) { 142 // In email addresses, only the domain name should be punycoded. Leave 143 // the local part (i.e. everything up to `@`) intact. 144 result = parts[0] + '@';
vendor: 11,811 bytes, lines 145-525
145 string = parts[1]; 146 } 147 var labels = string.split(regexSeparators); 148 var encoded = map(labels, fn).join('.'); 149 return result + encoded; 150 } 151 152 /** 153 * Creates an array containing the numeric code points of each Unicode 154 * character in the string. While JavaScript uses UCS-2 internally, 155 * this function will convert a pair of surrogate halves (each of which 156 * UCS-2 exposes as separate characters) into a single code point, 157 * matching UTF-16. 158 * @see `punycode.ucs2.encode` 159 * @see <https://mathiasbynens.be/notes/javascript-encoding> 160 * @memberOf punycode.ucs2 161 * @name decode 162 * @param {String} string The Unicode input string (UCS-2). 163 * @returns {Array} The new array of code points. 164 */ 165 function ucs2decode(string) { 166 var output = [], 167 counter = 0, 168 length = string.length, 169 value, 170 extra; 171 while (counter < length) { 172 value = string.charCodeAt(counter++); 173 if (value >= 0xD800 && value <= 0xDBFF && counter < length) { 174 // high surrogate, and there is a next character 175 extra = string.charCodeAt(counter++); 176 if ((extra & 0xFC00) == 0xDC00) { // low surrogate 177 output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); 178 } else { 179 // unmatched surrogate; only append this code unit, in case the next 180 // code unit is the high surrogate of a surrogate pair 181 output.push(value); 182 counter--; 183 } 184 } else { 185 output.push(value); 186 } 187 } 188 return output; 189 } 190 191 /** 192 * Creates a string based on an array of numeric code points. 193 * @see `punycode.ucs2.decode` 194 * @memberOf punycode.ucs2 195 * @name encode 196 * @param {Array} codePoints The array of numeric code points. 197 * @returns {String} The new Unicode string (UCS-2). 198 */ 199 function ucs2encode(array) { 200 return map(array, function(value) { 201 var output = ''; 202 if (value > 0xFFFF) { 203 value -= 0x10000; 204 output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); 205 value = 0xDC00 | value & 0x3FF; 206 } 207 output += stringFromCharCode(value); 208 return output; 209 }).join(''); 210 } 211 212 /** 213 * Converts a basic code point into a digit/integer. 214 * @see `digitToBasic()` 215 * @private 216 * @param {Number} codePoint The basic numeric code point value. 217 * @returns {Number} The numeric value of a basic code point (for use in 218 * representing integers) in the range `0` to `base - 1`, or `base` if 219 * the code point does not represent a value. 220 */ 221 function basicToDigit(codePoint) { 222 if (codePoint - 48 < 10) { 223 return codePoint - 22; 224 } 225 if (codePoint - 65 < 26) { 226 return codePoint - 65; 227 } 228 if (codePoint - 97 < 26) { 229 return codePoint - 97; 230 } 231 return base; 232 } 233 234 /** 235 * Converts a digit/integer into a basic code point. 236 * @see `basicToDigit()` 237 * @private 238 * @param {Number} digit The numeric value of a basic code point. 239 * @returns {Number} The basic code point whose value (when used for 240 * representing integers) is `digit`, which needs to be in the range 241 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is 242 * used; else, the lowercase form is used. The behavior is undefined 243 * if `flag` is non-zero and `digit` has no uppercase form. 244 */ 245 function digitToBasic(digit, flag) { 246 // 0..25 map to ASCII a..z or A..Z 247 // 26..35 map to ASCII 0..9 248 return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); 249 } 250 251 /** 252 * Bias adaptation function as per section 3.4 of RFC 3492. 253 * http://tools.ietf.org/html/rfc3492#section-3.4 254 * @private 255 */ 256 function adapt(delta, numPoints, firstTime) { 257 var k = 0; 258 delta = firstTime ? floor(delta / damp) : delta >> 1; 259 delta += floor(delta / numPoints); 260 for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { 261 delta = floor(delta / baseMinusTMin); 262 } 263 return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); 264 } 265 266 /** 267 * Converts a Punycode string of ASCII-only symbols to a string of Unicode 268 * symbols. 269 * @memberOf punycode 270 * @param {String} input The Punycode string of ASCII-only symbols. 271 * @returns {String} The resulting string of Unicode symbols. 272 */ 273 function decode(input) { 274 // Don't use UCS-2 275 var output = [], 276 inputLength = input.length, 277 out, 278 i = 0, 279 n = initialN, 280 bias = initialBias, 281 basic, 282 j, 283 index, 284 oldi, 285 w, 286 k, 287 digit, 288 t, 289 /** Cached calculation results */ 290 baseMinusT; 291 292 // Handle the basic code points: let `basic` be the number of input code 293 // points before the last delimiter, or `0` if there is none, then copy 294 // the first basic code points to the output. 295 296 basic = input.lastIndexOf(delimiter); 297 if (basic < 0) { 298 basic = 0; 299 } 300 301 for (j = 0; j < basic; ++j) { 302 // if it's not a basic code point 303 if (input.charCodeAt(j) >= 0x80) { 304 error('not-basic'); 305 } 306 output.push(input.charCodeAt(j)); 307 } 308 309 // Main decoding loop: start just after the last delimiter if any basic code 310 // points were copied; start at the beginning otherwise. 311 312 for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { 313 314 // `index` is the index of the next character to be consumed. 315 // Decode a generalized variable-length integer into `delta`, 316 // which gets added to `i`. The overflow checking is easier 317 // if we increase `i` as we go, then subtract off its starting 318 // value at the end to obtain `delta`. 319 for (oldi = i, w = 1, k = base; /* no condition */; k += base) { 320 321 if (index >= inputLength) { 322 error('invalid-input'); 323 } 324 325 digit = basicToDigit(input.charCodeAt(index++)); 326 327 if (digit >= base || digit > floor((maxInt - i) / w)) { 328 error('overflow'); 329 } 330 331 i += digit * w; 332 t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); 333 334 if (digit < t) { 335 break; 336 } 337 338 baseMinusT = base - t; 339 if (w > floor(maxInt / baseMinusT)) { 340 error('overflow'); 341 } 342 343 w *= baseMinusT; 344 345 } 346 347 out = output.length + 1; 348 bias = adapt(i - oldi, out, oldi == 0); 349 350 // `i` was supposed to wrap around from `out` to `0`, 351 // incrementing `n` each time, so we'll fix that now: 352 if (floor(i / out) > maxInt - n) { 353 error('overflow'); 354 } 355 356 n += floor(i / out); 357 i %= out; 358 359 // Insert `n` at position `i` of the output 360 output.splice(i++, 0, n); 361 362 } 363 364 return ucs2encode(output); 365 } 366 367 /** 368 * Converts a string of Unicode symbols (e.g. a domain name label) to a 369 * Punycode string of ASCII-only symbols. 370 * @memberOf punycode 371 * @param {String} input The string of Unicode symbols. 372 * @returns {String} The resulting Punycode string of ASCII-only symbols. 373 */ 374 function encode(input) { 375 var n, 376 delta, 377 handledCPCount, 378 basicLength, 379 bias, 380 j, 381 m, 382 q, 383 k, 384 t, 385 currentValue, 386 output = [], 387 /** `inputLength` will hold the number of code points in `input`. */ 388 inputLength, 389 /** Cached calculation results */ 390 handledCPCountPlusOne, 391 baseMinusT, 392 qMinusT; 393 394 // Convert the input in UCS-2 to Unicode 395 input = ucs2decode(input); 396 397 // Cache the length 398 inputLength = input.length; 399 400 // Initialize the state 401 n = initialN; 402 delta = 0; 403 bias = initialBias; 404 405 // Handle the basic code points 406 for (j = 0; j < inputLength; ++j) { 407 currentValue = input[j]; 408 if (currentValue < 0x80) { 409 output.push(stringFromCharCode(currentValue)); 410 } 411 } 412 413 handledCPCount = basicLength = output.length; 414 415 // `handledCPCount` is the number of code points that have been handled; 416 // `basicLength` is the number of basic code points. 417 418 // Finish the basic string - if it is not empty - with a delimiter 419 if (basicLength) { 420 output.push(delimiter); 421 } 422 423 // Main encoding loop: 424 while (handledCPCount < inputLength) { 425 426 // All non-basic code points < n have been handled already. Find the next 427 // larger one: 428 for (m = maxInt, j = 0; j < inputLength; ++j) { 429 currentValue = input[j]; 430 if (currentValue >= n && currentValue < m) { 431 m = currentValue; 432 } 433 } 434 435 // Increase `delta` enough to advance the decoder's <n,i> state to <m,0>, 436 // but guard against overflow 437 handledCPCountPlusOne = handledCPCount + 1; 438 if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { 439 error('overflow'); 440 } 441 442 delta += (m - n) * handledCPCountPlusOne; 443 n = m; 444 445 for (j = 0; j < inputLength; ++j) { 446 currentValue = input[j]; 447 448 if (currentValue < n && ++delta > maxInt) { 449 error('overflow'); 450 } 451 452 if (currentValue == n) { 453 // Represent delta as a generalized variable-length integer 454 for (q = delta, k = base; /* no condition */; k += base) { 455 t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); 456 if (q < t) { 457 break; 458 } 459 qMinusT = q - t; 460 baseMinusT = base - t; 461 output.push( 462 stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) 463 ); 464 q = floor(qMinusT / baseMinusT); 465 } 466 467 output.push(stringFromCharCode(digitToBasic(q, 0))); 468 bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); 469 delta = 0; 470 ++handledCPCount; 471 } 472 } 473 474 ++delta; 475 ++n; 476 477 } 478 return output.join(''); 479 } 480 481 /** 482 * Converts a Punycode string representing a domain name or an email address 483 * to Unicode. Only the Punycoded parts of the input will be converted, i.e. 484 * it doesn't matter if you call it on a string that has already been 485 * converted to Unicode. 486 * @memberOf punycode 487 * @param {String} input The Punycoded domain name or email address to 488 * convert to Unicode. 489 * @returns {String} The Unicode representation of the given Punycode 490 * string. 491 */ 492 function toUnicode(input) { 493 return mapDomain(input, function(string) { 494 return regexPunycode.test(string) 495 ? decode(string.slice(4).toLowerCase()) 496 : string; 497 }); 498 } 499 500 /** 501 * Converts a Unicode string representing a domain name or an email address to 502 * Punycode. Only the non-ASCII parts of the domain name will be converted, 503 * i.e. it doesn't matter if you call it with a domain that's already in 504 * ASCII. 505 * @memberOf punycode 506 * @param {String} input The domain name or email address to convert, as a 507 * Unicode string. 508 * @returns {String} The Punycode representation of the given domain name or 509 * email address. 510 */ 511 function toASCII(input) { 512 return mapDomain(input, function(string) { 513 return regexNonASCII.test(string) 514 ? 'xn--' + encode(string) 515 : string; 516 }); 517 } 518 519 /*--------------------------------------------------------------------------*/ 520 521 /** Define the public API */ 522 punycode = { 523 /** 524 * A string representing the current Punycode.js version number. 525 * @memberOf punycode
526 * @type String 527 */ 528 'version': '1.3.1', 529 /** 530 * An object of methods to convert from JavaScript's internal character 531 * representation (UCS-2) to Unicode code points, and back. 532 * @see <https://mathiasbynens.be/notes/javascript-encoding> 533 * @memberOf punycode 534 * @type Object 535 */ 536 'ucs2': { 537 'decode': ucs2decode, 538 'encode': ucs2encode 539 }, 540 'decode': decode, 541 'encode': encode, 542 'toASCII': toASCII, 543 'toUnicode': toUnicode 544 }; 545 546 /** Expose `punycode` */ 547 // Some AMD build optimizers, like r.js, check for specific condition patterns 548 // like the following: 549 if ( 550 typeof define == 'function' && 551 typeof define.amd == 'object' && 552 define.amd 553 ) { 554 define('punycode', function() { 555 return punycode; 556 }); 557 } else if (freeExports && freeModule) { 558 if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+ 559 freeModule.exports = punycode; 560 } else { // in Narwhal or RingoJS v0.7.0- 561 for (key in punycode) { 562 punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); 563 } 564 } 565 } else { // in Rhino or a web browser 566 root.punycode = punycode; 567 } 568 569}(this)); 570 571var html2canvasNodeAttribute = "data-html2canvas-node"; 572var html2canvasCanvasCloneAttribute = "data-html2canvas-canvas-clone"; 573var html2canvasCanvasCloneIndex = 0; 574var html2canvasCloneIndex = 0; 575 576window.html2canvas = function(nodeList, options) { 577 var index = html2canvasCloneIndex++; 578 options = options || {}; 579 if (options.logging) { 580 window.html2canvas.logging = true; 581 window.html2canvas.start = Date.now(); 582 } 583 584 options.async = typeof(options.async) === "undefined" ? true : options.async; 585 options.allowTaint = typeof(options.allowTaint) === "undefined" ? false : options.allowTaint; 586 options.removeContainer = typeof(options.removeContainer) === "undefined" ? true : options.removeContainer; 587 options.javascriptEnabled = typeof(options.javascriptEnabled) === "undefined" ? false : options.javascriptEnabled; 588 options.imageTimeout = typeof(options.imageTimeout) === "undefined" ? 10000 : options.imageTimeout; 589 options.renderer = typeof(options.renderer) === "function" ? options.renderer : CanvasRenderer; 590 options.strict = !!options.strict; 591 592 if (typeof(nodeList) === "string") { 593 if (typeof(options.proxy) !== "string") { 594 return Promise.reject("Proxy must be used when rendering url"); 595 } 596 var width = options.width != null ? options.width : window.innerWidth; 597 var height = options.height != null ? options.height : window.innerHeight; 598 return loadUrlDocument(absoluteUrl(nodeList), options.proxy, document, width, height, options).then(function(container) { 599 return renderWindow(container.contentWindow.document.documentElement, container, options, width, height); 600 }); 601 } 602 603 var node = ((nodeList === undefined) ? [document.documentElement] : ((nodeList.length) ? nodeList : [nodeList]))[0]; 604 node.setAttribute(html2canvasNodeAttribute + index, index); 605 return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function(canvas) { 606 if (typeof(options.onrendered) === "function") { 607 log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas"); 608 options.onrendered(canvas); 609 } 610 return canvas; 611 }); 612}; 613 614window.html2canvas.punycode = this.punycode; 615window.html2canvas.proxy = {}; 616 617function renderDocument(document, options, windowWidth, windowHeight, html2canvasIndex) { 618 return createWindowClone(document, document, windowWidth, windowHeight, options, document.defaultView.pageXOffset, document.defaultView.pageYOffset).then(function(container) { 619 log("Document cloned"); 620 var attributeName = html2canvasNodeAttribute + html2canvasIndex; 621 var selector = "[" + attributeName + "='" + html2canvasIndex + "']"; 622 document.querySelector(selector).removeAttribute(attributeName); 623 var clonedWindow = container.contentWindow; 624 var node = clonedWindow.document.querySelector(selector);
625 var oncloneHandler = (typeof(options.onclone) === "function") ? Promise.resolve(options.onclone(clonedWindow.document)) : Promise.resolve(true); 626 return oncloneHandler.then(function() { 627 return renderWindow(node, container, options, windowWidth, windowHeight); 628 }); 629 }); 630} 631 632function renderWindow(node, container, options, windowWidth, windowHeight) { 633 var clonedWindow = container.contentWindow; 634 var support = new Support(clonedWindow.document); 635 var imageLoader = new ImageLoader(options, support); 636 var bounds = getBounds(node); 637 var width = options.type === "view" ? windowWidth : documentWidth(clonedWindow.document); 638 var height = options.type === "view" ? windowHeight : documentHeight(clonedWindow.document); 639 var renderer = new options.renderer(width, height, imageLoader, options, document); 640 var parser = new NodeParser(node, renderer, support, imageLoader, options); 641 return parser.ready.then(function() { 642 log("Finished rendering"); 643 var canvas; 644 645 if (options.type === "view") { 646 canvas = crop(renderer.canvas, {width: renderer.canvas.width, height: renderer.canvas.height, top: 0, left: 0, x: 0, y: 0}); 647 } else if (node === clonedWindow.document.body || node === clonedWindow.document.documentElement || options.canvas != null) { 648 canvas = renderer.canvas; 649 } else { 650 canvas = crop(renderer.canvas, {width: options.width != null ? options.width : bounds.width, height: options.height != null ? options.height : bounds.height, top: bounds.top, left: bounds.left, x: clonedWindow.pageXOffset, y: clonedWindow.pageYOffset}); 651 } 652 653 cleanupContainer(container, options); 654 return canvas; 655 }); 656} 657 658function cleanupContainer(container, options) { 659 if (options.removeContainer) { 660 container.parentNode.removeChild(container); 661 log("Cleaned up container"); 662 } 663} 664 665function crop(canvas, bounds) { 666 var croppedCanvas = document.createElement("canvas"); 667 var x1 = Math.min(canvas.width - 1, Math.max(0, bounds.left)); 668 var x2 = Math.min(canvas.width, Math.max(1, bounds.left + bounds.width)); 669 var y1 = Math.min(canvas.height - 1, Math.max(0, bounds.top)); 670 var y2 = Math.min(canvas.height, Math.max(1, bounds.top + bounds.height)); 671 croppedCanvas.width = bounds.width; 672 croppedCanvas.height = bounds.height; 673 log("Cropping canvas at:", "left:", bounds.left, "top:", bounds.top, "width:", (x2-x1), "height:", (y2-y1)); 674 log("Resulting crop with width", bounds.width, "and height", bounds.height, " with x", x1, "and y", y1); 675 croppedCanvas.getContext("2d").drawImage(canvas, x1, y1, x2-x1, y2-y1, bounds.x, bounds.y, x2-x1, y2-y1); 676 return croppedCanvas; 677} 678 679function documentWidth (doc) { 680 return Math.max( 681 Math.max(doc.body.scrollWidth, doc.documentElement.scrollWidth), 682 Math.max(doc.body.offsetWidth, doc.documentElement.offsetWidth), 683 Math.max(doc.body.clientWidth, doc.documentElement.clientWidth) 684 ); 685} 686 687function documentHeight (doc) { 688 return Math.max( 689 Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight), 690 Math.max(doc.body.offsetHeight, doc.documentElement.offsetHeight), 691 Math.max(doc.body.clientHeight, doc.documentElement.clientHeight) 692 ); 693} 694 695function smallImage() { 696 return "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"; 697} 698 699function isIE9() { 700 return document.documentMode && document.documentMode <= 9; 701} 702 703// https://github.com/niklasvh/html2canvas/issues/503 704function cloneNodeIE9(node, javascriptEnabled) { 705 var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false); 706 707 var child = node.firstChild; 708 while(child) { 709 if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') { 710 clone.appendChild(cloneNodeIE9(child, javascriptEnabled)); 711 } 712 child = child.nextSibling; 713 } 714 715 return clone; 716} 717 718function createWindowClone(ownerDocument, containerDocument, width, height, options, x ,y) { 719 labelCanvasElements(ownerDocument); 720 var documentElement = isIE9() ? cloneNodeIE9(ownerDocument.documentElement, options.javascriptEnabled) : ownerDocument.documentElement.cloneNode(true); 721 var container = containerDocument.createElement("iframe"); 722 723 container.className = "html2canvas-container"; 724 container.style.visibility = "hidden"; 725 container.style.position = "fixed"; 726 container.style.left = "-10000px"; 727 container.style.top = "0px"; 728 container.style.border = "0"; 729 container.width = width; 730 container.height = height; 731 container.scrolling = "no"; // ios won't scroll without it 732 containerDocument.body.appendChild(container); 733 734 return new Promise(function(resolve) { 735 var documentClone = container.contentWindow.document; 736 737 cloneNodeValues(ownerDocument.documentElement, documentElement, "textarea"); 738 cloneNodeValues(ownerDocument.documentElement, documentElement, "select"); 739 740 /* Chrome doesn't detect relative background-images assigned in inline <style> sheets when fetched through getComputedStyle 741 if window url is about:blank, we can assign the url to current by writing onto the document 742 */ 743 container.contentWindow.onload = container.onload = function() { 744 var interval = setInterval(function() { 745 if (documentClone.body.childNodes.length > 0) { 746 cloneCanvasContents(ownerDocument, documentClone); 747 clearInterval(interval); 748 if (options.type === "view") { 749 container.contentWindow.scrollTo(x, y); 750 } 751 resolve(container); 752 } 753 }, 50); 754 }; 755 756 documentClone.open(); 757 documentClone.write("<!DOCTYPE html><html></html>"); 758 // Chrome scrolls the parent document for some reason after the write to the cloned window??? 759 restoreOwnerScroll(ownerDocument, x, y); 760 documentClone.replaceChild(options.javascriptEnabled === true ? documentClone.adoptNode(documentElement) : removeScriptNodes(documentClone.adoptNode(documentElement)), documentClone.documentElement); 761 documentClone.close(); 762 });
763} 764 765function cloneNodeValues(document, clone, nodeName) { 766 var originalNodes = document.getElementsByTagName(nodeName); 767 var clonedNodes = clone.getElementsByTagName(nodeName); 768 var count = originalNodes.length; 769 for (var i = 0; i < count; i++) { 770 clonedNodes[i].value = originalNodes[i].value; 771 } 772} 773 774function restoreOwnerScroll(ownerDocument, x, y) { 775 if (ownerDocument.defaultView && (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset)) { 776 ownerDocument.defaultView.scrollTo(x, y); 777 } 778} 779 780function loadUrlDocument(src, proxy, document, width, height, options) { 781 return new Proxy(src, proxy, window.document).then(documentFromHTML(src)).then(function(doc) { 782 return createWindowClone(doc, document, width, height, options, 0, 0); 783 }); 784} 785 786function documentFromHTML(src) { 787 return function(html) { 788 var parser = new DOMParser(), doc; 789 try { 790 doc = parser.parseFromString(html, "text/html"); 791 } catch(e) { 792 log("DOMParser not supported, falling back to createHTMLDocument"); 793 doc = document.implementation.createHTMLDocument(""); 794 try { 795 doc.open(); 796 doc.write(html); 797 doc.close(); 798 } catch(ee) { 799 log("createHTMLDocument write not supported, falling back to document.body.innerHTML"); 800 doc.body.innerHTML = html; // ie9 doesnt support writing to documentElement 801 } 802 } 803 804 var b = doc.querySelector("base"); 805 if (!b || !b.href.host) { 806 var base = doc.createElement("base"); 807 base.href = src; 808 doc.head.insertBefore(base, doc.head.firstChild); 809 } 810 811 return doc; 812 }; 813} 814 815 816function labelCanvasElements(ownerDocument) { 817 [].slice.call(ownerDocument.querySelectorAll("canvas"), 0).forEach(function(canvas) { 818 canvas.setAttribute(html2canvasCanvasCloneAttribute, "canvas-" + html2canvasCanvasCloneIndex++); 819 }); 820} 821 822function cloneCanvasContents(ownerDocument, documentClone) { 823 [].slice.call(ownerDocument.querySelectorAll("[" + html2canvasCanvasCloneAttribute + "]"), 0).forEach(function(canvas) { 824 try { 825 var clonedCanvas = documentClone.querySelector('[' + html2canvasCanvasCloneAttribute + '="' + canvas.getAttribute(html2canvasCanvasCloneAttribute) + '"]'); 826 if (clonedCanvas) { 827 clonedCanvas.width = canvas.width; 828 clonedCanvas.height = canvas.height; 829 clonedCanvas.getContext("2d").putImageData(canvas.getContext("2d").getImageData(0, 0, canvas.width, canvas.height), 0, 0); 830 } 831 } catch(e) { 832 log("Unable to copy canvas content from", canvas, e); 833 } 834 canvas.removeAttribute(html2canvasCanvasCloneAttribute); 835 }); 836} 837 838function removeScriptNodes(parent) { 839 [].slice.call(parent.childNodes, 0).filter(isElementNode).forEach(function(node) { 840 if (node.tagName === "SCRIPT") { 841 parent.removeChild(node); 842 } else { 843 removeScriptNodes(node); 844 } 845 }); 846 return parent; 847} 848 849function isElementNode(node) { 850 return node.nodeType === Node.ELEMENT_NODE; 851} 852 853function absoluteUrl(url) { 854 var link = document.createElement("a"); 855 link.href = url; 856 link.href = link.href; 857 return link; 858} 859 860// http://dev.w3.org/csswg/css-color/ 861 862function Color(value) { 863 this.r = 0; 864 this.g = 0; 865 this.b = 0; 866 this.a = null; 867 var result = this.fromArray(value) || 868 this.namedColor(value) || 869 this.rgb(value) || 870 this.rgba(value) || 871 this.hex6(value) || 872 this.hex3(value); 873} 874 875Color.prototype.darken = function(amount) { 876 var a = 1 - amount; 877 return new Color([ 878 Math.round(this.r * a), 879 Math.round(this.g * a), 880 Math.round(this.b * a), 881 this.a 882 ]); 883}; 884 885Color.prototype.isTransparent = function() { 886 return this.a === 0; 887}; 888 889Color.prototype.isBlack = function() { 890 return this.r === 0 && this.g === 0 && this.b === 0; 891}; 892 893Color.prototype.fromArray = function(array) { 894 if (Array.isArray(array)) { 895 this.r = Math.min(array[0], 255); 896 this.g = Math.min(array[1], 255); 897 this.b = Math.min(array[2], 255); 898 if (array.length > 3) { 899 this.a = array[3]; 900 } 901 } 902 903 return (Array.isArray(array)); 904}; 905 906var _hex3 = /^#([a-f0-9]{3})$/i; 907 908Color.prototype.hex3 = function(value) { 909 var match = null; 910 if ((match = value.match(_hex3)) !== null) { 911 this.r = parseInt(match[1][0] + match[1][0], 16); 912 this.g = parseInt(match[1][1] + match[1][1], 16); 913 this.b = parseInt(match[1][2] + match[1][2], 16); 914 } 915 return match !== null; 916}; 917 918var _hex6 = /^#([a-f0-9]{6})$/i; 919 920Color.prototype.hex6 = function(value) { 921 var match = null; 922 if ((match = value.match(_hex6)) !== null) { 923 this.r = parseInt(match[1].substring(0, 2), 16); 924 this.g = parseInt(match[1].substring(2, 4), 16); 925 this.b = parseInt(match[1].substring(4, 6), 16); 926 } 927 return match !== null; 928}; 929 930 931var _rgb = /^rgb\((\d{1,3}) *, *(\d{1,3}) *, *(\d{1,3})\)$/; 932 933Color.prototype.rgb = function(value) { 934 var match = null; 935 if ((match = value.match(_rgb)) !== null) { 936 this.r = Number(match[1]); 937 this.g = Number(match[2]); 938 this.b = Number(match[3]); 939 } 940 return match !== null; 941}; 942 943var _rgba = /^rgba\((\d{1,3}) *, *(\d{1,3}) *, *(\d{1,3}) *, *(\d+\.?\d*)\)$/; 944 945Color.prototype.rgba = function(value) { 946 var match = null; 947 if ((match = value.match(_rgba)) !== null) { 948 this.r = Number(match[1]); 949 this.g = Number(match[2]); 950 this.b = Number(match[3]); 951 this.a = Number(match[4]); 952 } 953 return match !== null; 954}; 955 956Color.prototype.toString = function() { 957 return this.a !== null && this.a !== 1 ? 958 "rgba(" + [this.r, this.g, this.b, this.a].join(",") + ")" : 959 "rgb(" + [this.r, this.g, this.b].join(",") + ")"; 960}; 961 962Color.prototype.namedColor = function(value) { 963 var color = colors[value.toLowerCase()]; 964 if (color) { 965 this.r = color[0]; 966 this.g = color[1];
967 this.b = color[2]; 968 } else if (value.toLowerCase() === "transparent") { 969 this.r = this.g = this.b = this.a = 0; 970 return true; 971 } 972 973 return !!color; 974}; 975 976Color.prototype.isColor = true; 977 978// JSON.stringify([].slice.call($$('.named-color-table tr'), 1).map(function(row) { return [row.childNodes[3].textContent, row.childNodes[5].textContent.trim().split(",").map(Number)] }).reduce(function(data, row) {data[row[0]] = row[1]; return data}, {})) 979var colors = { 980 "aliceblue": [240, 248, 255], 981 "antiquewhite": [250, 235, 215], 982 "aqua": [0, 255, 255], 983 "aquamarine": [127, 255, 212], 984 "azure": [240, 255, 255], 985 "beige": [245, 245, 220], 986 "bisque": [255, 228, 196], 987 "black": [0, 0, 0], 988 "blanchedalmond": [255, 235, 205], 989 "blue": [0, 0, 255], 990 "blueviolet": [138, 43, 226], 991 "brown": [165, 42, 42], 992 "burlywood": [222, 184, 135], 993 "cadetblue": [95, 158, 160], 994 "chartreuse": [127, 255, 0], 995 "chocolate": [210, 105, 30], 996 "coral": [255, 127, 80], 997 "cornflowerblue": [100, 149, 237], 998 "cornsilk": [255, 248, 220], 999 "crimson": [220, 20, 60], 1000 "cyan": [0, 255, 255], 1001 "darkblue": [0, 0, 139], 1002 "darkcyan": [0, 139, 139], 1003 "darkgoldenrod": [184, 134, 11], 1004 "darkgray": [169, 169, 169], 1005 "darkgreen": [0, 100, 0], 1006 "darkgrey": [169, 169, 169], 1007 "darkkhaki": [189, 183, 107], 1008 "darkmagenta": [139, 0, 139], 1009 "darkolivegreen": [85, 107, 47], 1010 "darkorange": [255, 140, 0], 1011 "darkorchid": [153, 50, 204], 1012 "darkred": [139, 0, 0], 1013 "darksalmon": [233, 150, 122], 1014 "darkseagreen": [143, 188, 143], 1015 "darkslateblue": [72, 61, 139], 1016 "darkslategray": [47, 79, 79], 1017 "darkslategrey": [47, 79, 79], 1018 "darkturquoise": [0, 206, 209], 1019 "darkviolet": [148, 0, 211], 1020 "deeppink": [255, 20, 147], 1021 "deepskyblue": [0, 191, 255], 1022 "dimgray": [105, 105, 105], 1023 "dimgrey": [105, 105, 105], 1024 "dodgerblue": [30, 144, 255], 1025 "firebrick": [178, 34, 34], 1026 "floralwhite": [255, 250, 240], 1027 "forestgreen": [34, 139, 34], 1028 "fuchsia": [255, 0, 255], 1029 "gainsboro": [220, 220, 220], 1030 "ghostwhite": [248, 248, 255], 1031 "gold": [255, 215, 0], 1032 "goldenrod": [218, 165, 32], 1033 "gray": [128, 128, 128], 1034 "green": [0, 128, 0], 1035 "greenyellow": [173, 255, 47], 1036 "grey": [128, 128, 128], 1037 "honeydew": [240, 255, 240], 1038 "hotpink": [255, 105, 180], 1039 "indianred": [205, 92, 92], 1040 "indigo": [75, 0, 130], 1041 "ivory": [255, 255, 240], 1042 "khaki": [240, 230, 140], 1043 "lavender": [230, 230, 250], 1044 "lavenderblush": [255, 240, 245], 1045 "lawngreen": [124, 252, 0], 1046 "lemonchiffon": [255, 250, 205], 1047 "lightblue": [173, 216, 230], 1048 "lightcoral": [240, 128, 128], 1049 "lightcyan": [224, 255, 255], 1050 "lightgoldenrodyellow": [250, 250, 210], 1051 "lightgray": [211, 211, 211], 1052 "lightgreen": [144, 238, 144], 1053 "lightgrey": [211, 211, 211], 1054 "lightpink": [255, 182, 193], 1055 "lightsalmon": [255, 160, 122], 1056 "lightseagreen": [32, 178, 170], 1057 "lightskyblue": [135, 206, 250], 1058 "lightslategray": [119, 136, 153], 1059 "lightslategrey": [119, 136, 153], 1060 "lightsteelblue": [176, 196, 222], 1061 "lightyellow": [255, 255, 224], 1062 "lime": [0, 255, 0], 1063 "limegreen": [50, 205, 50], 1064 "linen": [250, 240, 230], 1065 "magenta": [255, 0, 255], 1066 "maroon": [128, 0, 0], 1067 "mediumaquamarine": [102, 205, 170], 1068 "mediumblue": [0, 0, 205], 1069 "mediumorchid": [186, 85, 211], 1070 "mediumpurple": [147, 112, 219], 1071 "mediumseagreen": [60, 179, 113], 1072 "mediumslateblue": [123, 104, 238], 1073 "mediumspringgreen": [0, 250, 154], 1074 "mediumturquoise": [72, 209, 204], 1075 "mediumvioletred": [199, 21, 133], 1076 "midnightblue": [25, 25, 112], 1077 "mintcream": [245, 255, 250], 1078 "mistyrose": [255, 228, 225], 1079 "moccasin": [255, 228, 181], 1080 "navajowhite": [255, 222, 173], 1081 "navy": [0, 0, 128], 1082 "oldlace": [253, 245, 230], 1083 "olive": [128, 128, 0], 1084 "olivedrab": [107, 142, 35], 1085 "orange": [255, 165, 0], 1086 "orangered": [255, 69, 0], 1087 "orchid": [218, 112, 214], 1088 "palegoldenrod": [238, 232, 170], 1089 "palegreen": [152, 251, 152],
1090 "paleturquoise": [175, 238, 238], 1091 "palevioletred": [219, 112, 147], 1092 "papayawhip": [255, 239, 213], 1093 "peachpuff": [255, 218, 185], 1094 "peru": [205, 133, 63], 1095 "pink": [255, 192, 203], 1096 "plum": [221, 160, 221], 1097 "powderblue": [176, 224, 230], 1098 "purple": [128, 0, 128], 1099 "rebeccapurple": [102, 51, 153], 1100 "red": [255, 0, 0], 1101 "rosybrown": [188, 143, 143], 1102 "royalblue": [65, 105, 225], 1103 "saddlebrown": [139, 69, 19], 1104 "salmon": [250, 128, 114], 1105 "sandybrown": [244, 164, 96], 1106 "seagreen": [46, 139, 87], 1107 "seashell": [255, 245, 238], 1108 "sienna": [160, 82, 45], 1109 "silver": [192, 192, 192], 1110 "skyblue": [135, 206, 235], 1111 "slateblue": [106, 90, 205], 1112 "slategray": [112, 128, 144], 1113 "slategrey": [112, 128, 144], 1114 "snow": [255, 250, 250], 1115 "springgreen": [0, 255, 127], 1116 "steelblue": [70, 130, 180], 1117 "tan": [210, 180, 140], 1118 "teal": [0, 128, 128], 1119 "thistle": [216, 191, 216], 1120 "tomato": [255, 99, 71], 1121 "turquoise": [64, 224, 208], 1122 "violet": [238, 130, 238], 1123 "wheat": [245, 222, 179], 1124 "white": [255, 255, 255], 1125 "whitesmoke": [245, 245, 245], 1126 "yellow": [255, 255, 0], 1127 "yellowgreen": [154, 205, 50] 1128}; 1129 1130 1131function DummyImageContainer(src) { 1132 this.src = src; 1133 log("DummyImageContainer for", src); 1134 if (!this.promise || !this.image) { 1135 log("Initiating DummyImageContainer"); 1136 DummyImageContainer.prototype.image = new Image(); 1137 var image = this.image; 1138 DummyImageContainer.prototype.promise = new Promise(function(resolve, reject) { 1139 image.onload = resolve; 1140 image.onerror = reject; 1141 image.src = smallImage(); 1142 if (image.complete === true) { 1143 resolve(image); 1144 } 1145 }); 1146 } 1147} 1148 1149function Font(family, size) { 1150 var container = document.createElement('div'), 1151 img = document.createElement('img'), 1152 span = document.createElement('span'), 1153 sampleText = 'Hidden Text', 1154 baseline, 1155 middle; 1156 1157 container.style.visibility = "hidden"; 1158 container.style.fontFamily = family; 1159 container.style.fontSize = size; 1160 container.style.margin = 0; 1161 container.style.padding = 0; 1162 1163 document.body.appendChild(container); 1164 1165 img.src = smallImage(); 1166 img.width = 1; 1167 img.height = 1; 1168 1169 img.style.margin = 0; 1170 img.style.padding = 0; 1171 img.style.verticalAlign = "baseline"; 1172 1173 span.style.fontFamily = family; 1174 span.style.fontSize = size; 1175 span.style.margin = 0; 1176 span.style.padding = 0; 1177 1178 span.appendChild(document.createTextNode(sampleText)); 1179 container.appendChild(span); 1180 container.appendChild(img); 1181 baseline = (img.offsetTop - span.offsetTop) + 1; 1182 1183 container.removeChild(span); 1184 container.appendChild(document.createTextNode(sampleText)); 1185 1186 container.style.lineHeight = "normal"; 1187 img.style.verticalAlign = "super"; 1188 1189 middle = (img.offsetTop-container.offsetTop) + 1; 1190 1191 document.body.removeChild(container); 1192 1193 this.baseline = baseline; 1194 this.lineWidth = 1; 1195 this.middle = middle; 1196} 1197 1198function FontMetrics() { 1199 this.data = {}; 1200} 1201 1202FontMetrics.prototype.getMetrics = function(family, size) { 1203 if (this.data[family + "-" + size] === undefined) { 1204 this.data[family + "-" + size] = new Font(family, size); 1205 } 1206 return this.data[family + "-" + size]; 1207}; 1208 1209function FrameContainer(container, sameOrigin, options) { 1210 this.image = null; 1211 this.src = container; 1212 var self = this; 1213 var bounds = getBounds(container); 1214 this.promise = (!sameOrigin ? this.proxyLoad(options.proxy, bounds, options) : new Promise(function(resolve) { 1215 if (container.contentWindow.document.URL === "about:blank" || container.contentWindow.document.documentElement == null) { 1216 container.contentWindow.onload = container.onload = function() { 1217 resolve(container); 1218 }; 1219 } else { 1220 resolve(container); 1221 } 1222 })).then(function(container) { 1223 return html2canvas(container.contentWindow.document.documentElement, {type: 'view', width: container.width, height: container.height, proxy: options.proxy, javascriptEnabled: options.javascriptEnabled, removeContainer: options.removeContainer, allowTaint: options.allowTaint, imageTimeout: options.imageTimeout / 2}); 1224 }).then(function(canvas) { 1225 return self.image = canvas; 1226 });
1227} 1228 1229FrameContainer.prototype.proxyLoad = function(proxy, bounds, options) { 1230 var container = this.src; 1231 return loadUrlDocument(container.src, proxy, container.ownerDocument, bounds.width, bounds.height, options); 1232}; 1233 1234function GradientContainer(imageData) { 1235 this.src = imageData.value; 1236 this.colorStops = []; 1237 this.type = null; 1238 this.x0 = 0.5; 1239 this.y0 = 0.5; 1240 this.x1 = 0.5; 1241 this.y1 = 0.5; 1242 this.promise = Promise.resolve(true); 1243} 1244 1245GradientContainer.prototype.TYPES = { 1246 LINEAR: 1, 1247 RADIAL: 2 1248}; 1249 1250function ImageContainer(src, cors) { 1251 this.src = src; 1252 this.image = new Image(); 1253 var self = this; 1254 this.tainted = null; 1255 this.promise = new Promise(function(resolve, reject) { 1256 self.image.onload = resolve; 1257 self.image.onerror = reject; 1258 if (cors) { 1259 self.image.crossOrigin = "anonymous"; 1260 } 1261 self.image.src = src; 1262 if (self.image.complete === true) { 1263 resolve(self.image); 1264 } 1265 }); 1266} 1267 1268function ImageLoader(options, support) { 1269 this.link = null; 1270 this.options = options; 1271 this.support = support; 1272 this.origin = this.getOrigin(window.location.href); 1273} 1274 1275ImageLoader.prototype.findImages = function(nodes) { 1276 var images = []; 1277 nodes.reduce(function(imageNodes, container) { 1278 switch(container.node.nodeName) { 1279 case "IMG": 1280 return imageNodes.concat([{ 1281 args: [container.node.src], 1282 method: "url" 1283 }]); 1284 case "svg": 1285 case "IFRAME": 1286 return imageNodes.concat([{ 1287 args: [container.node], 1288 method: container.node.nodeName 1289 }]); 1290 } 1291 return imageNodes; 1292 }, []).forEach(this.addImage(images, this.loadImage), this); 1293 return images; 1294}; 1295 1296ImageLoader.prototype.findBackgroundImage = function(images, container) { 1297 container.parseBackgroundImages().filter(this.hasImageBackground).forEach(this.addImage(images, this.loadImage), this); 1298 return images; 1299}; 1300 1301ImageLoader.prototype.addImage = function(images, callback) { 1302 return function(newImage) { 1303 newImage.args.forEach(function(image) { 1304 if (!this.imageExists(images, image)) { 1305 images.splice(0, 0, callback.call(this, newImage)); 1306 log('Added image #' + (images.length), typeof(image) === "string" ? image.substring(0, 100) : image); 1307 } 1308 }, this); 1309 }; 1310};
1311 1312ImageLoader.prototype.hasImageBackground = function(imageData) { 1313 return imageData.method !== "none"; 1314}; 1315 1316ImageLoader.prototype.loadImage = function(imageData) { 1317 if (imageData.method === "url") { 1318 var src = imageData.args[0]; 1319 if (this.isSVG(src) && !this.support.svg && !this.options.allowTaint) { 1320 return new SVGContainer(src); 1321 } else if (src.match(/data:image\/.*;base64,/i)) { 1322 return new ImageContainer(src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, ''), false); 1323 } else if (this.isSameOrigin(src) || this.options.allowTaint === true || this.isSVG(src)) { 1324 return new ImageContainer(src, false); 1325 } else if (this.support.cors && !this.options.allowTaint && this.options.useCORS) { 1326 return new ImageContainer(src, true); 1327 } else if (this.options.proxy) { 1328 return new ProxyImageContainer(src, this.options.proxy); 1329 } else { 1330 return new DummyImageContainer(src); 1331 } 1332 } else if (imageData.method === "linear-gradient") { 1333 return new LinearGradientContainer(imageData); 1334 } else if (imageData.method === "gradient") { 1335 return new WebkitGradientContainer(imageData); 1336 } else if (imageData.method === "svg") { 1337 return new SVGNodeContainer(imageData.args[0], this.support.svg); 1338 } else if (imageData.method === "IFRAME") { 1339 return new FrameContainer(imageData.args[0], this.isSameOrigin(imageData.args[0].src), this.options); 1340 } else { 1341 return new DummyImageContainer(imageData); 1342 } 1343}; 1344 1345ImageLoader.prototype.isSVG = function(src) { 1346 return src.substring(src.length - 3).toLowerCase() === "svg" || SVGContainer.prototype.isInline(src); 1347}; 1348 1349ImageLoader.prototype.imageExists = function(images, src) { 1350 return images.some(function(image) { 1351 return image.src === src; 1352 }); 1353}; 1354 1355ImageLoader.prototype.isSameOrigin = function(url) { 1356 return (this.getOrigin(url) === this.origin); 1357}; 1358 1359ImageLoader.prototype.getOrigin = function(url) { 1360 var link = this.link || (this.link = document.createElement("a")); 1361 link.href = url; 1362 link.href = link.href; // IE9, LOL! - http://jsfiddle.net/niklasvh/2e48b/ 1363 return link.protocol + link.hostname + link.port; 1364}; 1365 1366ImageLoader.prototype.getPromise = function(container) { 1367 return this.timeout(container, this.options.imageTimeout)['catch'](function() { 1368 var dummy = new DummyImageContainer(container.src); 1369 return dummy.promise.then(function(image) { 1370 container.image = image; 1371 }); 1372 }); 1373}; 1374 1375ImageLoader.prototype.get = function(src) { 1376 var found = null; 1377 return this.images.some(function(img) { 1378 return (found = img).src === src; 1379 }) ? found : null; 1380}; 1381 1382ImageLoader.prototype.fetch = function(nodes) { 1383 this.images = nodes.reduce(bind(this.findBackgroundImage, this), this.findImages(nodes)); 1384 this.images.forEach(function(image, index) { 1385 image.promise.then(function() { 1386 log("Succesfully loaded image #"+ (index+1), image); 1387 }, function(e) { 1388 log("Failed loading image #"+ (index+1), image, e); 1389 }); 1390 }); 1391 this.ready = Promise.all(this.images.map(this.getPromise, this)); 1392 log("Finished searching images"); 1393 return this; 1394}; 1395 1396ImageLoader.prototype.timeout = function(container, timeout) { 1397 var timer; 1398 var promise = Promise.race([container.promise, new Promise(function(res, reject) { 1399 timer = setTimeout(function() { 1400 log("Timed out loading image", container); 1401 reject(container); 1402 }, timeout); 1403 })]).then(function(container) { 1404 clearTimeout(timer); 1405 return container; 1406 }); 1407 promise['catch'](function() { 1408 clearTimeout(timer); 1409 }); 1410 return promise; 1411}; 1412 1413function LinearGradientContainer(imageData) { 1414 GradientContainer.apply(this, arguments); 1415 this.type = this.TYPES.LINEAR; 1416 1417 var hasDirection = imageData.args[0].match(this.stepRegExp) === null; 1418 1419 if (hasDirection) {
1420 imageData.args[0].split(" ").reverse().forEach(function(position) { 1421 switch(position) { 1422 case "left": 1423 this.x0 = 0; 1424 this.x1 = 1; 1425 break; 1426 case "top": 1427 this.y0 = 0; 1428 this.y1 = 1; 1429 break; 1430 case "right": 1431 this.x0 = 1; 1432 this.x1 = 0; 1433 break; 1434 case "bottom": 1435 this.y0 = 1; 1436 this.y1 = 0; 1437 break; 1438 case "to": 1439 var y0 = this.y0; 1440 var x0 = this.x0; 1441 this.y0 = this.y1; 1442 this.x0 = this.x1; 1443 this.x1 = x0; 1444 this.y1 = y0; 1445 break; 1446 } 1447 }, this); 1448 } else { 1449 this.y0 = 0; 1450 this.y1 = 1; 1451 } 1452 1453 this.colorStops = imageData.args.slice(hasDirection ? 1 : 0).map(function(colorStop) { 1454 var colorStopMatch = colorStop.match(this.stepRegExp); 1455 return { 1456 color: new Color(colorStopMatch[1]), 1457 stop: colorStopMatch[3] === "%" ? colorStopMatch[2] / 100 : null 1458 }; 1459 }, this); 1460 1461 if (this.colorStops[0].stop === null) { 1462 this.colorStops[0].stop = 0; 1463 } 1464 1465 if (this.colorStops[this.colorStops.length - 1].stop === null) { 1466 this.colorStops[this.colorStops.length - 1].stop = 1; 1467 } 1468 1469 this.colorStops.forEach(function(colorStop, index) { 1470 if (colorStop.stop === null) { 1471 this.colorStops.slice(index).some(function(find, count) { 1472 if (find.stop !== null) { 1473 colorStop.stop = ((find.stop - this.colorStops[index - 1].stop) / (count + 1)) + this.colorStops[index - 1].stop; 1474 return true; 1475 } else { 1476 return false; 1477 } 1478 }, this); 1479 } 1480 }, this); 1481} 1482 1483LinearGradientContainer.prototype = Object.create(GradientContainer.prototype); 1484 1485LinearGradientContainer.prototype.stepRegExp = /((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%|px)?/; 1486 1487function log() { 1488 if (window.html2canvas.logging && window.console && window.console.log) { 1489 Function.prototype.bind.call(window.console.log, (window.console)).apply(window.console, [(Date.now() - window.html2canvas.start) + "ms", "html2canvas:"].concat([].slice.call(arguments, 0))); 1490 } 1491} 1492 1493function NodeContainer(node, parent) { 1494 this.node = node; 1495 this.parent = parent; 1496 this.stack = null; 1497 this.bounds = null; 1498 this.borders = null; 1499 this.clip = []; 1500 this.backgroundClip = []; 1501 this.offsetBounds = null; 1502 this.visible = null; 1503 this.computedStyles = null; 1504 this.colors = {}; 1505 this.styles = {}; 1506 this.backgroundImages = null; 1507 this.transformData = null; 1508 this.transformMatrix = null; 1509 this.isPseudoElement = false; 1510 this.opacity = null; 1511} 1512 1513NodeContainer.prototype.cloneTo = function(stack) { 1514 stack.visible = this.visible; 1515 stack.borders = this.borders; 1516 stack.bounds = this.bounds; 1517 stack.clip = this.clip; 1518 stack.backgroundClip = this.backgroundClip; 1519 stack.computedStyles = this.computedStyles; 1520 stack.styles = this.styles; 1521 stack.backgroundImages = this.backgroundImages; 1522 stack.opacity = this.opacity; 1523}; 1524 1525NodeContainer.prototype.getOpacity = function() { 1526 return this.opacity === null ? (this.opacity = this.cssFloat('opacity')) : this.opacity; 1527}; 1528 1529NodeContainer.prototype.assignStack = function(stack) { 1530 this.stack = stack; 1531 stack.children.push(this); 1532}; 1533 1534NodeContainer.prototype.isElementVisible = function() { 1535 return this.node.nodeType === Node.TEXT_NODE ? this.parent.visible : ( 1536 this.css('display') !== "none" && 1537 this.css('visibility') !== "hidden" && 1538 !this.node.hasAttribute("data-html2canvas-ignore") && 1539 (this.node.nodeName !== "INPUT" || this.node.getAttribute("type") !== "hidden") 1540 ); 1541}; 1542 1543NodeContainer.prototype.css = function(attribute) { 1544 if (!this.computedStyles) { 1545 this.computedStyles = this.isPseudoElement ? this.parent.computedStyle(this.before ? ":before" : ":after")
1545: this.computedStyle(null); 1546 } 1547 1548 return this.styles[attribute] || (this.styles[attribute] = this.computedStyles[attribute]); 1549}; 1550 1551NodeContainer.prototype.prefixedCss = function(attribute) { 1552 var prefixes = ["webkit", "moz", "ms", "o"]; 1553 var value = this.css(attribute); 1554 if (value === undefined) { 1555 prefixes.some(function(prefix) { 1556 value = this.css(prefix + attribute.substr(0, 1).toUpperCase() + attribute.substr(1)); 1557 return value !== undefined; 1558 }, this); 1559 } 1560 return value === undefined ? null : value; 1561}; 1562 1563NodeContainer.prototype.computedStyle = function(type) { 1564 return this.node.ownerDocument.defaultView.getComputedStyle(this.node, type); 1565}; 1566 1567NodeContainer.prototype.cssInt = function(attribute) { 1568 var value = parseInt(this.css(attribute), 10); 1569 return (isNaN(value)) ? 0 : value; // borders in old IE are throwing 'medium' for demo.html 1570}; 1571 1572NodeContainer.prototype.color = function(attribute) { 1573 return this.colors[attribute] || (this.colors[attribute] = new Color(this.css(attribute))); 1574}; 1575 1576NodeContainer.prototype.cssFloat = function(attribute) { 1577 var value = parseFloat(this.css(attribute)); 1578 return (isNaN(value)) ? 0 : value; 1579}; 1580 1581NodeContainer.prototype.fontWeight = function() { 1582 var weight = this.css("fontWeight"); 1583 switch(parseInt(weight, 10)){ 1584 case 401: 1585 weight = "bold"; 1586 break; 1587 case 400: 1588 weight = "normal"; 1589 break; 1590 } 1591 return weight; 1592}; 1593 1594NodeContainer.prototype.parseClip = function() { 1595 var matches = this.css('clip').match(this.CLIP); 1596 if (matches) { 1597 return { 1598 top: parseInt(matches[1], 10), 1599 right: parseInt(matches[2], 10), 1600 bottom: parseInt(matches[3], 10), 1601 left: parseInt(matches[4], 10) 1602 }; 1603 } 1604 return null; 1605}; 1606 1607NodeContainer.prototype.parseBackgroundImages = function() { 1608 return this.backgroundImages || (this.backgroundImages = parseBackgrounds(this.css("backgroundImage"))); 1609}; 1610 1611NodeContainer.prototype.cssList = function(property, index) { 1612 var value = (this.css(property) || '').split(','); 1613 value = value[index || 0] || value[0] || 'auto'; 1614 value = value.trim().split(' '); 1615 if (value.length === 1) { 1616 value = [value[0], value[0]]; 1617 } 1618 return value; 1619}; 1620 1621NodeContainer.prototype.parseBackgroundSize = function(bounds, image, index) { 1622 var size = this.cssList("backgroundSize", index); 1623 var width, height; 1624 1625 if (isPercentage(size[0])) { 1626 width = bounds.width * parseFloat(size[0]) / 100; 1627 } else if (/contain|cover/.test(size[0])) { 1628 var targetRatio = bounds.width / bounds.height, currentRatio = image.width / image.height; 1629 return (targetRatio < currentRatio ^ size[0] === 'contain') ? {width: bounds.height * currentRatio, height: bounds.height} : {width: bounds.width, height: bounds.width / currentRatio}; 1630 } else { 1631 width = parseInt(size[0], 10); 1632 } 1633 1634 if (size[0] === 'auto' && size[1] === 'auto') { 1635 height = image.height; 1636 } else if (size[1] === 'auto') { 1637 height = width / image.width * image.height; 1638 } else if (isPercentage(size[1])) { 1639 height = bounds.height * parseFloat(size[1]) / 100; 1640 } else { 1641 height = parseInt(size[1], 10); 1642 } 1643 1644 if (size[0] === 'auto') { 1645 width = height / image.height * image.width; 1646 } 1647 1648 return {width: width, height: height}; 1649}; 1650 1651NodeContainer.prototype.parseBackgroundPosition = function(bounds, image, index, backgroundSize) { 1652 var position = this.cssList('backgroundPosition', index); 1653 var left, top; 1654 1655 if (isPercentage(position[0])){ 1656 left = (bounds.width - (backgroundSize || image).width) * (parseFloat(position[0]) / 100); 1657 } else { 1658 left = parseInt(position[0], 10); 1659 } 1660 1661 if (position[1] === 'auto') { 1662 top = left / image.width * image.height; 1663 } else if (isPercentage(position[1])){ 1664 top = (bounds.height - (backgroundSize || image).height) * parseFloat(position[1]) / 100; 1665 } else { 1666 top = parseInt(position[1], 10); 1667 } 1668 1669 if (position[0] === 'auto') { 1670 left = top / image.height * image.width; 1671 } 1672 1673 return {left: left, top: top}; 1674}; 1675
1676NodeContainer.prototype.parseBackgroundRepeat = function(index) { 1677 return this.cssList("backgroundRepeat", index)[0]; 1678}; 1679 1680NodeContainer.prototype.parseTextShadows = function() { 1681 var textShadow = this.css("textShadow"); 1682 var results = []; 1683 1684 if (textShadow && textShadow !== 'none') { 1685 var shadows = textShadow.match(this.TEXT_SHADOW_PROPERTY); 1686 for (var i = 0; shadows && (i < shadows.length); i++) { 1687 var s = shadows[i].match(this.TEXT_SHADOW_VALUES); 1688 results.push({ 1689 color: new Color(s[0]), 1690 offsetX: s[1] ? parseFloat(s[1].replace('px', '')) : 0, 1691 offsetY: s[2] ? parseFloat(s[2].replace('px', '')) : 0, 1692 blur: s[3] ? s[3].replace('px', '') : 0 1693 }); 1694 } 1695 } 1696 return results; 1697}; 1698 1699NodeContainer.prototype.parseTransform = function() { 1700 if (!this.transformData) { 1701 if (this.hasTransform()) { 1702 var offset = this.parseBounds(); 1703 var origin = this.prefixedCss("transformOrigin").split(" ").map(removePx).map(asFloat); 1704 origin[0] += offset.left; 1705 origin[1] += offset.top; 1706 this.transformData = { 1707 origin: origin, 1708 matrix: this.parseTransformMatrix() 1709 }; 1710 } else { 1711 this.transformData = { 1712 origin: [0, 0], 1713 matrix: [1, 0, 0, 1, 0, 0] 1714 }; 1715 } 1716 } 1717 return this.transformData; 1718}; 1719 1720NodeContainer.prototype.parseTransformMatrix = function() { 1721 if (!this.transformMatrix) { 1722 var transform = this.prefixedCss("transform"); 1723 var matrix = transform ? parseMatrix(transform.match(this.MATRIX_PROPERTY)) : null; 1724 this.transformMatrix = matrix ? matrix : [1, 0, 0, 1, 0, 0]; 1725 } 1726 return this.transformMatrix; 1727}; 1728 1729NodeContainer.prototype.parseBounds = function() { 1730 return this.bounds || (this.bounds = this.hasTransform() ? offsetBounds(this.node) : getBounds(this.node)); 1731}; 1732 1733NodeContainer.prototype.hasTransform = function() { 1734 return this.parseTransformMatrix().join(",") !== "1,0,0,1,0,0" || (this.parent && this.parent.hasTransform()); 1735}; 1736 1737NodeContainer.prototype.getValue = function() { 1738 var value = this.node.value || ""; 1739 if (this.node.tagName === "SELECT") { 1740 value = selectionValue(this.node); 1741 } else if (this.node.type === "password") { 1742 value = Array(value.length + 1).join('\u2022'); // jshint ignore:line 1743 } 1744 return value.length === 0 ? (this.node.placeholder || "") : value; 1745}; 1746 1747NodeContainer.prototype.MATRIX_PROPERTY = /(matrix)\((.+)\)/; 1748NodeContainer.prototype.TEXT_SHADOW_PROPERTY = /((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g; 1749NodeContainer.prototype.TEXT_SHADOW_VALUES = /(-?\d+px)|(#.+)|(rgb\(.+\))|(rgba\(.+\))/g; 1750NodeContainer.prototype.CLIP = /^rect\((\d+)px,? (\d+)px,? (\d+)px,? (\d+)px\)$/; 1751 1752function selectionValue(node) { 1753 var option = node.options[node.selectedIndex || 0]; 1754 return option ? (option.text || "") : ""; 1755} 1756 1757function parseMatrix(match) { 1758 if (match && match[1] === "matrix") { 1759 return match[2].split(",").map(function(s) { 1760 return parseFloat(s.trim()); 1761 }); 1762 } 1763} 1764 1765function isPercentage(value) { 1766 return value.toString().indexOf("%") !== -1; 1767} 1768 1769function parseBackgrounds(backgroundImage) { 1770 var whitespace = ' \r\n\t', 1771 method, definition, prefix, prefix_i, block, results = [], 1772 mode = 0, numParen = 0, quote, args; 1773 var appendResult = function() { 1774 if(method) { 1775 if (definition.substr(0, 1) === '"') { 1776 definition = definition.substr(1, definition.length - 2); 1777 } 1778 if (definition) { 1779 args.push(definition); 1780 } 1781 if (method.substr(0, 1) === '-' && (prefix_i = method.indexOf('-', 1 ) + 1) > 0) { 1782 prefix = method.substr(0, prefix_i); 1783 method = method.substr(prefix_i); 1784 } 1785 results.push({ 1786 prefix: prefix, 1787 method: method.toLowerCase(), 1788 value: block, 1789 args: args, 1790 image: null 1791 }); 1792 } 1793 args = []; 1794 method = prefix = definition = block = ''; 1795 }; 1796 args = []; 1797 method = prefix = definition = block = ''; 1798 backgroundImage.split("").forEach(function(c) { 1799 if (mode === 0 && whitespace.indexOf(c) > -1) { 1800 return; 1801 } 1802 switch(c) { 1803 case '"': 1804 if(!quote) { 1805 quote = c; 1806 } else if(quote === c) { 1807 quote = null; 1808 } 1809 break; 1810 case '(': 1811 if(quote) { 1812 break; 1813 } else if(mode === 0) { 1814 mode = 1; 1815 block += c; 1816 return; 1817 } else { 1818 numParen++; 1819 } 1820 break; 1821 case ')': 1822 if (quote) { 1823 break; 1824 } else if(mode === 1) { 1825 if(numParen === 0) { 1826 mode = 0; 1827 block += c; 1828 appendResult(); 1829 return; 1830 } else { 1831 numParen--; 1832 } 1833 } 1834 break; 1835 1836 case ',': 1837 if (quote) { 1838 break; 1839 } else if(mode === 0) { 1840 appendResult(); 1841 return; 1842 } else if (mode === 1) { 1843 if (numParen === 0 && !method.match(/^url$/i)) { 1844 args.push(definition); 1845 definition = ''; 1846 block += c; 1847 return; 1848 } 1849 } 1850 break; 1851 } 1852 1853 block += c; 1854 if (mode === 0) { 1855 method += c;
1856 } else { 1857 definition += c; 1858 } 1859 }); 1860 1861 appendResult(); 1862 return results; 1863} 1864 1865function removePx(str) { 1866 return str.replace("px", ""); 1867} 1868 1869function asFloat(str) { 1870 return parseFloat(str); 1871} 1872 1873function getBounds(node) { 1874 if (node.getBoundingClientRect) { 1875 var clientRect = node.getBoundingClientRect(); 1876 var width = node.offsetWidth == null ? clientRect.width : node.offsetWidth; 1877 return { 1878 top: clientRect.top, 1879 bottom: clientRect.bottom || (clientRect.top + clientRect.height), 1880 right: clientRect.left + width, 1881 left: clientRect.left, 1882 width: width, 1883 height: node.offsetHeight == null ? clientRect.height : node.offsetHeight 1884 }; 1885 } 1886 return {}; 1887} 1888 1889function offsetBounds(node) { 1890 var parent = node.offsetParent ? offsetBounds(node.offsetParent) : {top: 0, left: 0}; 1891 1892 return { 1893 top: node.offsetTop + parent.top, 1894 bottom: node.offsetTop + node.offsetHeight + parent.top, 1895 right: node.offsetLeft + parent.left + node.offsetWidth, 1896 left: node.offsetLeft + parent.left, 1897 width: node.offsetWidth, 1898 height: node.offsetHeight 1899 }; 1900} 1901 1902function NodeParser(element, renderer, support, imageLoader, options) { 1903 log("Starting NodeParser"); 1904 this.renderer = renderer; 1905 this.options = options; 1906 this.range = null; 1907 this.support = support; 1908 this.renderQueue = []; 1909 this.stack = new StackingContext(true, 1, element.ownerDocument, null); 1910 var parent = new NodeContainer(element, null); 1911 if (options.background) { 1912 renderer.rectangle(0, 0, renderer.width, renderer.height, new Color(options.background)); 1913 } 1914 if (element === element.ownerDocument.documentElement) { 1915 // http://www.w3.org/TR/css3-background/#special-backgrounds 1916 var canvasBackground = new NodeContainer(parent.color('backgroundColor').isTransparent() ? element.ownerDocument.body : element.ownerDocument.documentElement, null); 1917 renderer.rectangle(0, 0, renderer.width, renderer.height, canvasBackground.color('backgroundColor')); 1918 } 1919 parent.visibile = parent.isElementVisible(); 1920 this.createPseudoHideStyles(element.ownerDocument); 1921 this.disableAnimations(element.ownerDocument); 1922 this.nodes = flatten([parent].concat(this.getChildren(parent)).filter(function(container) { 1923 return container.visible = container.isElementVisible(); 1924 }).map(this.getPseudoElements, this)); 1925 this.fontMetrics = new FontMetrics(); 1926 log("Fetched nodes, total:", this.nodes.length); 1927 log("Calculate overflow clips"); 1928 this.calculateOverflowClips(); 1929 log("Start fetching images"); 1930 this.images = imageLoader.fetch(this.nodes.filter(isElement)); 1931 this.ready = this.images.ready.then(bind(function() { 1932 log("Images loaded, starting parsing"); 1933 log("Creating stacking contexts"); 1934 this.createStackingContexts(); 1935 log("Sorting stacking contexts"); 1936 this.sortStackingContexts(this.stack); 1937 this.parse(this.stack); 1938 log("Render queue created with " + this.renderQueue.length + " items"); 1939 return new Promise(bind(function(resolve) { 1940 if (!options.async) { 1941 this.renderQueue.forEach(this.paint, this); 1942 resolve(); 1943 } else if (typeof(options.async) === "function") { 1944 options.async.call(this, this.renderQueue, resolve); 1945 } else if (this.renderQueue.length > 0){ 1946 this.renderIndex = 0; 1947 this.asyncRenderer(this.renderQueue, resolve); 1948 } else { 1949 resolve(); 1950 } 1951 }, this)); 1952 }, this)); 1953} 1954 1955NodeParser.prototype.calculateOverflowClips = function() { 1956 this.nodes.forEach(function(container) { 1957 if (isElement(container)) { 1958 if (isPseudoElement(container)) { 1959 container.appendToDOM(); 1960 } 1961 container.borders = this.parseBorders(container); 1962 var clip = (container.css('overflow') === "hidden") ? [container.borders.clip] : []; 1963 var cssClip = container.parseClip(); 1964 if (cssClip && ["absolute", "fixed"].indexOf(container.css('position')) !== -1) { 1965 clip.push([["rect", 1966 container.bounds.left + cssClip.left, 1967 container.bounds.top + cssClip.top, 1968 cssClip.right - cssClip.left, 1969 cssClip.bottom - cssClip.top 1970 ]]); 1971 } 1972 container.clip = hasParentClip(container) ? container.parent.clip.concat(clip) : clip; 1973 container.backgroundClip = (container.css('overflow') !== "hidden") ? c
1973ontainer.clip.concat([container.borders.clip]) : container.clip; 1974 if (isPseudoElement(container)) { 1975 container.cleanDOM(); 1976 } 1977 } else if (isTextNode(container)) { 1978 container.clip = hasParentClip(container) ? container.parent.clip : []; 1979 } 1980 if (!isPseudoElement(container)) { 1981 container.bounds = null; 1982 } 1983 }, this); 1984}; 1985 1986function hasParentClip(container) { 1987 return container.parent && container.parent.clip.length; 1988} 1989 1990NodeParser.prototype.asyncRenderer = function(queue, resolve, asyncTimer) { 1991 asyncTimer = asyncTimer || Date.now(); 1992 this.paint(queue[this.renderIndex++]); 1993 if (queue.length === this.renderIndex) { 1994 resolve(); 1995 } else if (asyncTimer + 20 > Date.now()) { 1996 this.asyncRenderer(queue, resolve, asyncTimer); 1997 } else { 1998 setTimeout(bind(function() { 1999 this.asyncRenderer(queue, resolve); 2000 }, this), 0); 2001 } 2002}; 2003 2004NodeParser.prototype.createPseudoHideStyles = function(document) { 2005 this.createStyles(document, '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + ':before { content: "" !important; display: none !important; }' + 2006 '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER + ':after { content: "" !important; display: none !important; }'); 2007}; 2008 2009NodeParser.prototype.disableAnimations = function(document) { 2010 this.createStyles(document, '* { -webkit-animation: none !important; -moz-animation: none !important; -o-animation: none !important; animation: none !important; ' + 2011 '-webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; transition: none !important;}'); 2012}; 2013 2014NodeParser.prototype.createStyles = function(document, styles) { 2015 var hidePseudoElements = document.createElement('style'); 2016 hidePseudoElements.innerHTML = styles; 2017 document.body.appendChild(hidePseudoElements); 2018}; 2019 2020NodeParser.prototype.getPseudoElements = function(container) { 2021 var nodes = [[container]]; 2022 if (container.node.nodeType === Node.ELEMENT_NODE) { 2023 var before = this.getPseudoElement(container, ":before"); 2024 var after = this.getPseudoElement(container, ":after"); 2025 2026 if (before) { 2027 nodes.push(before); 2028 } 2029 2030 if (after) { 2031 nodes.push(after); 2032 } 2033 } 2034 return flatten(nodes); 2035}; 2036 2037function toCamelCase(str) { 2038 return str.replace(/(\-[a-z])/g, function(match){ 2039 return match.toUpperCase().replace('-',''); 2040 }); 2041} 2042 2043NodeParser.prototype.getPseudoElement = function(container, type) { 2044 var style = container.computedStyle(type); 2045 if(!style || !style.content || style.content === "none" || style.content === "-moz-alt-content" || style.display === "none") { 2046 return null; 2047 } 2048 2049 var content = stripQuotes(style.content); 2050 var isImage = content.substr(0, 3) === 'url'; 2051 var pseudoNode = document.createElement(isImage ? 'img' : 'html2canvaspseudoelement'); 2052 var pseudoContainer = new PseudoElementContainer(pseudoNode, container, type); 2053 2054 for (var i = style.length-1; i >= 0; i--) { 2055 var property = toCamelCase(style.item(i)); 2056 pseudoNode.style[property] = style[property]; 2057 } 2058 2059 pseudoNode.className = PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + " " + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER; 2060 2061 if (isImage) { 2062 pseudoNode.src = parseBackgrounds(content)[0].args[0]; 2063 return [pseudoContainer]; 2064 } else { 2065 var text = document.createTextNode(content); 2066 pseudoNode.appendChild(text); 2067 return [pseudoContainer, new TextContainer(text, pseudoContainer)]; 2068 } 2069}; 2070 2071 2072NodeParser.prototype.getChildren = function(parentContainer) { 2073 return flatten([].filter.call(parentContainer.node.childNodes, renderableNode).map(function(node) { 2074 var container = [node.nodeType === Node.TEXT_NODE ? new TextContainer(node, parentContainer) : new NodeContainer(node, parentContainer)].filter(nonIgnoredElement); 2075 return node.nodeType === Node.ELEMENT_NODE && container.length && node.tagName !== "TEXTAREA" ? (container[0].isElementVisible() ? container.concat(this.getChildren(container[0])) : []) : container; 2076 }, this)); 2077}; 2078 2079NodeParser.prototype.newStackingContext = function(container, hasOwnStacking) { 2080 var stack = new StackingContext(hasOwnStacking, container.getOpacity(), container.node, container.parent); 2081 container.cloneTo(stack); 2082 var parentStack = hasOwnStacking ? stack.getParentStack(this) : stack.parent.stack; 2083 parentStack.contexts.push(stack); 2084 container.stack = stack; 2085}; 2086 2087NodeParser.prototype.createStackingContexts = function() {
2088 this.nodes.forEach(function(container) { 2089 if (isElement(container) && (this.isRootElement(container) || hasOpacity(container) || isPositionedForStacking(container) || this.isBodyWithTransparentRoot(container) || container.hasTransform())) { 2090 this.newStackingContext(container, true); 2091 } else if (isElement(container) && ((isPositioned(container) && zIndex0(container)) || isInlineBlock(container) || isFloating(container))) { 2092 this.newStackingContext(container, false); 2093 } else { 2094 container.assignStack(container.parent.stack); 2095 } 2096 }, this); 2097}; 2098 2099NodeParser.prototype.isBodyWithTransparentRoot = function(container) { 2100 return container.node.nodeName === "BODY" && container.parent.color('backgroundColor').isTransparent(); 2101}; 2102 2103NodeParser.prototype.isRootElement = function(container) { 2104 return container.parent === null; 2105}; 2106 2107NodeParser.prototype.sortStackingContexts = function(stack) { 2108 stack.contexts.sort(zIndexSort(stack.contexts.slice(0)));
2109 stack.contexts.forEach(this.sortStackingContexts, this); 2110}; 2111 2112NodeParser.prototype.parseTextBounds = function(container) { 2113 return function(text, index, textList) { 2114 if (container.parent.css("textDecoration").substr(0, 4) !== "none" || text.trim().length !== 0) { 2115 if (this.support.rangeBounds && !container.parent.hasTransform()) { 2116 var offset = textList.slice(0, index).join("").length; 2117 return this.getRangeBounds(container.node, offset, text.length); 2118 } else if (container.node && typeof(container.node.data) === "string") { 2119 var replacementNode = container.node.splitText(text.length); 2120 var bounds = this.getWrapperBounds(container.node, container.parent.hasTransform()); 2121 container.node = replacementNode; 2122 return bounds; 2123 } 2124 } else if(!this.support.rangeBounds || container.parent.hasTransform()){ 2125 container.node = container.node.splitText(text.length); 2126 } 2127 return {}; 2128 }; 2129};
2130 2131NodeParser.prototype.getWrapperBounds = function(node, transform) { 2132 var wrapper = node.ownerDocument.createElement('html2canvaswrapper'); 2133 var parent = node.parentNode, 2134 backupText = node.cloneNode(true); 2135 2136 wrapper.appendChild(node.cloneNode(true)); 2137 parent.replaceChild(wrapper, node); 2138 var bounds = transform ? offsetBounds(wrapper) : getBounds(wrapper); 2139 parent.replaceChild(backupText, wrapper); 2140 return bounds; 2141}; 2142 2143NodeParser.prototype.getRangeBounds = function(node, offset, length) { 2144 var range = this.range || (this.range = node.ownerDocument.createRange()); 2145 range.setStart(node, offset); 2146 range.setEnd(node, offset + length); 2147 return range.getBoundingClientRect(); 2148}; 2149 2150function ClearTransform() {} 2151 2152NodeParser.prototype.parse = function(stack) { 2153 // http://www.w3.org/TR/CSS21/visuren.html#z-index 2154 var negativeZindex = stack.contexts.filter(negativeZIndex); // 2. the child stacking contexts with negative stack levels (most negative first). 2155 var descendantElements = stack.children.filter(isElement); 2156 var descendantNonFloats = descendantElements.filter(not(isFloating)); 2157 var nonInlineNonPositionedDescendants = descendantNonFloats.filter(not(isPositioned)).filter(not(inlineLevel)); // 3 the in-flow, non-inline-level, non-positioned descendants. 2158 var nonPositionedFloats = descendantElements.filter(not(isPositioned)).filter(isFloating); // 4. the non-positioned floats. 2159 var inFlow = descendantNonFloats.filter(not(isPositioned)).filter(inlineLevel); // 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks. 2160 var stackLevel0 = stack.contexts.concat(descendantNonFloats.filter(isPositioned)).filter(zIndex0); // 6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0. 2161 var text = stack.children.filter(isTextNode).filter(hasText); 2162 var positiveZindex = stack.contexts.filter(positiveZIndex); // 7. the child stacking contexts with positive stack levels (least positive first). 2163 negativeZindex.concat(nonInlineNonPositionedDescendants).concat(nonPositionedFloats) 2164 .concat(inFlow).concat(stackLevel0).concat(text).concat(positiveZindex).forEach(function(container) { 2165 this.renderQueue.push(container); 2166 if (isStackingContext(container)) { 2167 this.parse(container); 2168 this.renderQueue.push(new ClearTransform()); 2169 } 2170 }, this); 2171}; 2172 2173NodeParser.prototype.paint = function(container) { 2174 try { 2175 if (container instanceof ClearTransform) { 2176 this.renderer.ctx.restore(); 2177 } else if (isTextNode(container)) { 2178 if (isPseudoElement(container.parent)) { 2179 container.parent.appendToDOM(); 2180 } 2181 this.paintText(container); 2182 if (isPseudoElement(container.parent)) { 2183 container.parent.cleanDOM(); 2184 } 2185 } else { 2186 this.paintNode(container); 2187 } 2188 } catch(e) { 2189 log(e); 2190 if (this.options.strict) { 2191 throw e; 2192 } 2193 } 2194}; 2195 2196NodeParser.prototype.paintNode = function(container) { 2197 if (isStackingContext(container)) { 2198 this.renderer.setOpacity(container.opacity); 2199 this.renderer.ctx.save(); 2200 if (container.hasTransform()) { 2201 this.renderer.setTransform(container.parseTransform()); 2202 } 2203 } 2204 2205 if (container.node.nodeName === "INPUT" && container.node.type === "checkbox") { 2206 this.paintCheckbox(container); 2207 } else if (container.node.nodeName === "INPUT" && container.node.type === "radio") { 2208 this.paintRadio(container); 2209 } else { 2210 this.paintElement(container); 2211 } 2212}; 2213 2214NodeParser.prototype.paintElement = function(container) { 2215 var bounds = container.parseBounds(); 2216 this.renderer.clip(container.backgroundClip, function() { 2217 this.renderer.renderBackground(container, bounds, container.borders.borders.map(getWidth)); 2218 }, this); 2219 2220 this.renderer.clip(container.clip, function() { 2221 this.renderer.renderBorders(container.borders.borders); 2222 }, this); 2223 2224 this.renderer.clip(container.backgroundClip, function() { 2225 switch (container.node.nodeName) { 2226 case "svg": 2227 case "IFRAME": 2228 var imgContainer = this.images.get(container.node); 2229 if (imgContainer) { 2230 this.renderer.renderImage(container, bounds, container.borders, imgContainer); 2231 } else { 2232 log("Error loading <" + container.node.nodeName + ">", container.node); 2233 } 2234 break; 2235 case "IMG": 2236 var imageContainer = this.images.get(container.node.src); 2237 if (imageContainer) { 2238 this.renderer.renderImage(container, bounds, container.borders, imageContainer); 2239 } else { 2240 log("Error loading <img>", container.node.src); 2241 } 2242 break; 2243 case "CANVAS": 2244 this.renderer.renderImage(container, bounds, container.borders, {image: container.node}); 2245 break; 2246 case "SELECT": 2247 case "INPUT": 2248 case "TEXTAREA": 2249 this.paintFormValue(container); 2250 break; 2251 } 2252 }, this); 2253}; 2254 2255NodeParser.prototype.paintCheckbox = function(container) { 2256 var b = container.parseBounds(); 2257 2258 var size = Math.min(b.width, b.height); 2259 var bounds = {width: size - 1, height: size - 1, top: b.top, left: b.left}; 2260 var r = [3, 3]; 2261 var radius = [r, r, r, r]; 2262 var borders = [1,1,1,1].map(function(w) { 2263 return {color: new Color('#A5A5A5'), width: w};
2264 }); 2265 2266 var borderPoints = calculateCurvePoints(bounds, radius, borders); 2267 2268 this.renderer.clip(container.backgroundClip, function() { 2269 this.renderer.rectangle(bounds.left + 1, bounds.top + 1, bounds.width - 2, bounds.height - 2, new Color("#DEDEDE")); 2270 this.renderer.renderBorders(calculateBorders(borders, bounds, borderPoints, radius)); 2271 if (container.node.checked) { 2272 this.renderer.font(new Color('#424242'), 'normal', 'normal', 'bold', (size - 3) + "px", 'arial'); 2273 this.renderer.text("\u2714", bounds.left + size / 6, bounds.top + size - 1); 2274 } 2275 }, this); 2276}; 2277 2278NodeParser.prototype.paintRadio = function(container) { 2279 var bounds = container.parseBounds(); 2280 2281 var size = Math.min(bounds.width, bounds.height) - 2; 2282 2283 this.renderer.clip(container.backgroundClip, function() { 2284 this.renderer.circleStroke(bounds.left + 1, bounds.top + 1, size, new Color('#DEDEDE'), 1, new Color('#A5A5A5')); 2285 if (container.node.checked) { 2286 this.renderer.circle(Math.ceil(bounds.left + size / 4) + 1, Math.ceil(bounds.top + size / 4) + 1, Math.floor(size / 2), new Color('#424242')); 2287 } 2288 }, this); 2289}; 2290 2291NodeParser.prototype.paintFormValue = function(container) { 2292 var value = container.getValue(); 2293 if (value.length > 0) { 2294 var document = container.node.ownerDocument; 2295 var wrapper = document.createElement('html2canvaswrapper'); 2296 var properties = ['lineHeight', 'textAlign', 'fontFamily', 'fontWeight', 'fontSize', 'color', 2297 'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 2298 'width', 'height', 'borderLeftStyle', 'borderTopStyle', 'borderLeftWidth', 'borderTopWidth', 2299 'boxSizing', 'whiteSpace', 'wordWrap']; 2300 2301 properties.forEach(function(property) { 2302 try { 2303 wrapper.style[property] = container.css(property); 2304 } catch(e) { 2305 // Older IE has issues with "border" 2306 log("html2canvas: Parse: Exception caught in renderFormValue: " + e.message); 2307 } 2308 }); 2309 var bounds = container.parseBounds(); 2310 wrapper.style.position = "fixed"; 2311 wrapper.style.left = bounds.left + "px"; 2312 wrapper.style.top = bounds.top + "px"; 2313 wrapper.textContent = value; 2314 document.body.appendChild(wrapper); 2315 this.paintText(new TextContainer(wrapper.firstChild, container)); 2316 document.body.removeChild(wrapper); 2317 } 2318}; 2319 2320NodeParser.prototype.paintText = function(container) { 2321 container.applyTextTransform(); 2322 var characters = window.html2canvas.punycode.ucs2.decode(container.node.data); 2323 var textList = (!this.options.letterRendering || noLetterSpacing(container)) && !hasUnicode(container.node.data) ? getWords(characters) : characters.map(function(character) { 2324 return window.html2canvas.punycode.ucs2.encode([character]); 2325 }); 2326 2327 var weight = container.parent.fontWeight(); 2328 var size = container.parent.css('fontSize'); 2329 var family = container.parent.css('fontFamily'); 2330 var shadows = container.parent.parseTextShadows(); 2331 2332 this.renderer.font(container.parent.color('color'), container.parent.css('fontStyle'), container.parent.css('fontVariant'), weight, size, family); 2333 if (shadows.length) { 2334 // TODO: support multiple text shadows 2335 this.renderer.fontShadow(shadows[0].color, shadows[0].offsetX, shadows[0].offsetY, shadows[0].blur); 2336 } else { 2337 this.renderer.clearShadow(); 2338 } 2339 2340 this.renderer.clip(container.parent.clip, function() { 2341 textList.map(this.parseTextBounds(container), this).forEach(function(bounds, index) { 2342 if (bounds) { 2343 this.renderer.text(textList[index], bounds.left, bounds.bottom); 2344 this.renderTextDecoration(container.parent, bounds, this.fontMetrics.getMetrics(family, size)); 2345 } 2346 }, this); 2347 }, this); 2348}; 2349 2350NodeParser.prototype.renderTextDecoration = function(container, bounds, metrics) { 2351 switch(container.css("textDecoration").split(" ")[0]) { 2352 case "underline": 2353 // Draws a line at the baseline of the font 2354 // TODO As some browsers display the line as more than 1px if the font-size is big, need to take that into account both in position and size 2355 this.renderer.rectangle(bounds.left, Math.round(bounds.top + metrics.baseline + metrics.lineWidth), bounds.width, 1, container.color("color")); 2356 break; 2357 case "overline": 2358 this.renderer.rectangle(bounds.left, Math.round(bounds.top), bounds.width, 1, container.color("color")); 2359 break; 2360 case "line-through": 2361 // TODO try and find exact position for line-through 2362 this.renderer.rectangle(bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, container.color("color")); 2363 break; 2364 } 2365}; 2366 2367var borderColorTransforms = { 2368 inset: [
2369 ["darken", 0.60], 2370 ["darken", 0.10], 2371 ["darken", 0.10], 2372 ["darken", 0.60] 2373 ] 2374}; 2375 2376NodeParser.prototype.parseBorders = function(container) { 2377 var nodeBounds = container.parseBounds(); 2378 var radius = getBorderRadiusData(container); 2379 var borders = ["Top", "Right", "Bottom", "Left"].map(function(side, index) { 2380 var style = container.css('border' + side + 'Style'); 2381 var color = container.color('border' + side + 'Color'); 2382 if (style === "inset" && color.isBlack()) { 2383 color = new Color([255, 255, 255, color.a]); // this is wrong, but 2384 } 2385 var colorTransform = borderColorTransforms[style] ? borderColorTransforms[style][index] : null; 2386 return { 2387 width: container.cssInt('border' + side + 'Width'), 2388 color: colorTransform ? color[colorTransform[0]](colorTransform[1]) : color, 2389 args: null 2390 }; 2391 }); 2392 var borderPoints = calculateCurvePoints(nodeBounds, radius, borders); 2393 2394 return { 2395 clip: this.parseBackgroundClip(container, borderPoints, borders, radius, nodeBounds), 2396 borders: calculateBorders(borders, nodeBounds, borderPoints, radius) 2397 }; 2398};
2399 2400function calculateBorders(borders, nodeBounds, borderPoints, radius) { 2401 return borders.map(function(border, borderSide) { 2402 if (border.width > 0) { 2403 var bx = nodeBounds.left; 2404 var by = nodeBounds.top; 2405 var bw = nodeBounds.width; 2406 var bh = nodeBounds.height - (borders[2].width); 2407 2408 switch(borderSide) { 2409 case 0: 2410 // top border 2411 bh = borders[0].width; 2412 border.args = drawSide({ 2413 c1: [bx, by], 2414 c2: [bx + bw, by], 2415 c3: [bx + bw - borders[1].width, by + bh], 2416 c4: [bx + borders[3].width, by + bh] 2417 }, radius[0], radius[1], 2418 borderPoints.topLeftOuter, borderPoints.topLeftInner, borderPoints.topRightOuter, borderPoints.topRightInner); 2419 break; 2420 case 1: 2421 // right border 2422 bx = nodeBounds.left + nodeBounds.width - (borders[1].width); 2423 bw = borders[1].width; 2424 2425 border.args = drawSide({ 2426 c1: [bx + bw, by], 2427 c2: [bx + bw, by + bh + borders[2].width], 2428 c3: [bx, by + bh], 2429 c4: [bx, by + borders[0].width] 2430 }, radius[1], radius[2], 2431 borderPoints.topRightOuter, borderPoints.topRightInner, borderPoints.bottomRightOuter, borderPoints.bottomRightInner); 2432 break; 2433 case 2: 2434 // bottom border 2435 by = (by + nodeBounds.height) - (borders[2].width); 2436 bh = borders[2].width; 2437 border.args = drawSide({ 2438 c1: [bx + bw, by + bh], 2439 c2: [bx, by + bh], 2440 c3: [bx + borders[3].width, by], 2441 c4: [bx + bw - borders[3].width, by] 2442 }, radius[2], radius[3], 2443 borderPoints.bottomRightOuter, borderPoints.bottomRightInner, borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner); 2444 break; 2445 case 3: 2446 // left border 2447 bw = borders[3].width; 2448 border.args = drawSide({ 2449 c1: [bx, by + bh + borders[2].width], 2450 c2: [bx, by], 2451 c3: [bx + bw, by + borders[0].width], 2452 c4: [bx + bw, by + bh] 2453 }, radius[3], radius[0], 2454 borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner, borderPoints.topLeftOuter, borderPoints.topLeftInner); 2455 break; 2456 } 2457 } 2458 return border; 2459 }); 2460} 2461 2462NodeParser.prototype.parseBackgroundClip = function(container, borderPoints, borders, radius, bounds) { 2463 var backgroundClip = container.css('backgroundClip'), 2464 borderArgs = []; 2465 2466 switch(backgroundClip) { 2467 case "content-box": 2468 case "padding-box": 2469 parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftInner, borderPoints.topRightInner, bounds.left + borders[3].width, bounds.top + borders[0].width); 2470 parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightInner, borderPoints.bottomRightInner, bounds.left + bounds.width - borders[1].width, bounds.top + borders[0].width); 2471 parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightInner, borderPoints.bottomLeftInner, bounds.left + bounds.width - borders[1].width, bounds.top + bounds.height - borders[2].width); 2472 parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftInner, borderPoints.topLeftInner, bounds.left + borders[3].width, bounds.top + bounds.height - borders[2].width); 2473 break; 2474 2475 default: 2476 parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftOuter, borderPoints.topRightOuter, bounds.left, bounds.top); 2477 parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightOuter, borderPoints.bottomRightOuter, bounds.left + bounds.width, bounds.top); 2478 parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightOuter, borderPoints.bottomLeftOuter, bounds.left + bounds.width, bounds.top + bounds.height); 2479 parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftOuter, borderPoints.topLeftOuter, bounds.left, bounds.top + bounds.height); 2480 break; 2481 } 2482 2483 return borderArgs; 2484}; 2485 2486function getCurvePoints(x, y, r1, r2) { 2487 var kappa = 4 * ((Math.sqrt(2) - 1) / 3); 2488 var ox = (r1) * kappa, // control point offset horizontal 2489 oy = (r2) * kappa, // control point offset vertical 2490 xm = x + r1, // x-middle 2491 ym = y + r2; // y-middle 2492 return { 2493 topLeft: bezierCurve({x: x, y: ym}, {x: x, y: ym - oy}, {x: xm - ox, y: y}, {x: xm, y: y}), 2494 topRight: bezierCurve({x: x, y: y}, {x: x + ox,y: y}, {x: xm, y: ym - oy}, {x: xm, y: ym}), 2495 bottomRight: bezierCurve({x: xm, y: y}, {x: xm, y: y + oy}, {x: x + ox, y: ym}, {x: x, y: ym}), 2496 bottomLeft: bezierCurve({x: xm, y: ym}, {x: xm - ox, y: ym}, {x: x, y: y + oy}, {x: x, y:y}) 2497 }; 2498} 2499 2500function calculateCurvePoints(bounds, borderRadius, borders) { 2501 var x = bounds.left, 2502 y = bounds.top, 2503 width = bounds.width, 2504 height = bounds.height, 2505 2506 tlh = borderRadius[0][0], 2507 tlv = borderRadius[0][1], 2508 trh = borderRadius[1][0], 2509 trv = borderRadius[1][1], 2510 brh = borderRadius[2][0], 2511 brv = borderRadius[2][1], 2512 blh = borderRadius[3][0], 2513 blv = borderRadius[3][1]; 2514 2515 var topWidth = width - trh, 2516 rightHeight = height - brv, 2517 bottomWidth = width - brh, 2518 leftHeight = height - blv; 2519 2520 return { 2521 topLeftOuter: getCurvePoints(x, y, tlh, tlv).topLeft.subdivide(0.5), 2522 topLeftInner: getCurvePoints(x + borders[3].width, y + borders[0].width, Math.max(0, tlh - borders[3].width), Math.max(0, tlv - borders[0].width)).topLeft.subdivide(0.5), 2523 topRightOuter: getCurvePoints(x + topWidth, y, trh, trv).topRight.subdivide(0.5), 2524 topRightInner: getCurvePoints(x + Math.min(topWidth, width + borders[3].width), y + borders[0].width, (topWidth > width + borders[3].width) ? 0 :trh - borders[3].width, trv - borders[0].width).topRight.subdivide(0.5), 2525 bottomRightOuter: getCurvePoints(x + bottomWidth, y + rightHeight, brh, brv).bottomRight.subdivide(0.5), 2526 bottomRightInner: getCurvePoints(x + Math.min(bottomWidth, width - borders[3].width), y + Math.min(rightHeight, height + borders[0].width), Math.max(0, brh - borders[1].width), brv - borders[2].width).bottomRight.subdivide(0.5), 2527 bottomLeftOuter: getCurvePoints(x, y + leftHeight, blh, blv).bottomLeft.subdivide(0.5), 2528 bottomLeftInner: getCurvePoints(x + borders[3].width, y + leftHeight, Math.max(0, blh - borders[3].width), blv - borders[2].width).bottomLeft.subdivide(0.5) 2529 }; 2530} 2531 2532function bezierCurve(start, startControl, endControl, end) { 2533 var lerp = function (a, b, t) { 2534 return { 2535 x: a.x + (b.x - a.x) * t, 2536 y: a.y + (b.y - a.y) * t 2537 }; 2538 }; 2539 2540 return { 2541 start: start, 2542 startControl: startControl, 2543 endControl: endControl, 2544 end: end, 2545 subdivide: function(t) { 2546 var ab = lerp(start, startControl, t), 2547 bc = lerp(startControl, endControl, t), 2548 cd = lerp(endControl, end, t), 2549 abbc = lerp(ab, bc, t), 2550 bccd = lerp(bc, cd, t), 2551 dest = lerp(abbc, bccd, t); 2552 return [bezierCurve(start, ab, abbc, dest), bezierCurve(dest, bccd, cd, end)]; 2553 }, 2554 curveTo: function(borderArgs) { 2555 borderArgs.push(["bezierCurve", startControl.x, startControl.y, endControl.x, endControl.y, end.x, end.y]); 2556 }, 2557 curveToReversed: function(borderArgs) { 2558 borderArgs.push(["bezierCurve", endControl.x, endControl.y, startControl.x, startControl.y, start.x, start.y]); 2559 } 2560 }; 2561} 2562 2563function drawSide(borderData, radius1, radius2, outer1, inner1, outer2, inner2) { 2564 var borderArgs = []; 2565 2566 if (radius1[0] > 0 || radius1[1] > 0) { 2567 borderArgs.push(["line", outer1[1].start.x, outer1[1].start.y]); 2568 outer1[1].curveTo(borderArgs); 2569 } else { 2570 borderArgs.push([ "line", borderData.c1[0], borderData.c1[1]]); 2571 } 2572 2573 if (radius2[0] > 0 || radius2[1] > 0) { 2574 borderArgs.push(["line", outer2[0].start.x, outer2[0].start.y]); 2575 outer2[0].curveTo(borderArgs); 2576 borderArgs.push(["line", inner2[0].end.x, inner2[0].end.y]); 2577 inner2[0].curveToReversed(borderArgs); 2578 } else { 2579 borderArgs.push(["line", borderData.c2[0], borderData.c2[1]]); 2580 borderArgs.push(["line", borderData.c3[0], borderData.c3[1]]); 2581 } 2582 2583 if (radius1[0] > 0 || radius1[1] > 0) { 2584 borderArgs.push(["line", inner1[1].end.x, inner1[1].end.y]); 2585 inner1[1].curveToReversed(borderArgs); 2586 } else { 2587 borderArgs.push(["line", borderData.c4[0], borderData.c4[1]]); 2588 } 2589 2590 return borderArgs; 2591} 2592 2593function parseCorner(borderArgs, radius1, radius2, corner1, corner2, x, y) { 2594 if (radius1[0] > 0 || radius1[1] > 0) {
2595 borderArgs.push(["line", corner1[0].start.x, corner1[0].start.y]); 2596 corner1[0].curveTo(borderArgs); 2597 corner1[1].curveTo(borderArgs); 2598 } else { 2599 borderArgs.push(["line", x, y]); 2600 } 2601 2602 if (radius2[0] > 0 || radius2[1] > 0) { 2603 borderArgs.push(["line", corner2[0].start.x, corner2[0].start.y]); 2604 } 2605} 2606 2607function negativeZIndex(container) { 2608 return container.cssInt("zIndex") < 0; 2609} 2610 2611function positiveZIndex(container) { 2612 return container.cssInt("zIndex") > 0; 2613} 2614 2615function zIndex0(container) { 2616 return container.cssInt("zIndex") === 0; 2617} 2618 2619function inlineLevel(container) { 2620 return ["inline", "inline-block", "inline-table"].indexOf(container.css("display")) !== -1; 2621} 2622 2623function isStackingContext(container) { 2624 return (container instanceof StackingContext); 2625} 2626 2627function hasText(container) { 2628 return container.node.data.trim().length > 0; 2629} 2630 2631function noLetterSpacing(container) { 2632 return (/^(normal|none|0px)$/.test(container.parent.css("letterSpacing"))); 2633} 2634 2635function getBorderRadiusData(container) { 2636 return ["TopLeft", "TopRight", "BottomRight", "BottomLeft"].map(function(side) { 2637 var value = container.css('border' + side + 'Radius'); 2638 var arr = value.split(" "); 2639 if (arr.length <= 1) { 2640 arr[1] = arr[0]; 2641 } 2642 return arr.map(asInt); 2643 }); 2644} 2645 2646function renderableNode(node) { 2647 return (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.ELEMENT_NODE); 2648} 2649 2650function isPositionedForStacking(container) { 2651 var position = container.css("position"); 2652 var zIndex = (["absolute", "relative", "fixed"].indexOf(position) !== -1) ? container.css("zIndex") : "auto"; 2653 return zIndex !== "auto"; 2654} 2655 2656function isPositioned(container) { 2657 return container.css("position") !== "static"; 2658} 2659 2660function isFloating(container) { 2661 return container.css("float") !== "none"; 2662} 2663 2664function isInlineBlock(container) { 2665 return ["inline-block", "inline-table"].indexOf(container.css("display")) !== -1; 2666} 2667 2668function not(callback) { 2669 var context = this; 2670 return function() { 2671 return !callback.apply(context, arguments); 2672 }; 2673} 2674 2675function isElement(container) { 2676 return container.node.nodeType === Node.ELEMENT_NODE; 2677} 2678 2679function isPseudoElement(container) { 2680 return container.isPseudoElement === true; 2681} 2682 2683function isTextNode(container) { 2684 return container.node.nodeType === Node.TEXT_NODE; 2685} 2686 2687function zIndexSort(contexts) { 2688 return function(a, b) { 2689 return (a.cssInt("zIndex") + (contexts.indexOf(a) / contexts.length)) - (b.cssInt("zIndex") + (contexts.indexOf(b) / contexts.length)); 2690 }; 2691} 2692 2693function hasOpacity(container) { 2694 return container.getOpacity() < 1; 2695} 2696 2697function bind(callback, context) { 2698 return function() { 2699 return callback.apply(context, arguments); 2700 }; 2701} 2702 2703function asInt(value) { 2704 return parseInt(value, 10); 2705} 2706 2707function getWidth(border) { 2708 return border.width; 2709} 2710 2711function nonIgnoredElement(nodeContainer) { 2712 return (nodeContainer.node.nodeType !== Node.ELEMENT_NODE || ["SCRIPT", "HEAD", "TITLE", "OBJECT", "BR", "OPTION"].indexOf(nodeContainer.node.nodeName) === -1); 2713} 2714 2715function flatten(arrays) { 2716 return [].concat.apply([], arrays); 2717} 2718 2719function stripQuotes(content) { 2720 var first = content.substr(0, 1); 2721 return (first === content.substr(content.length - 1) && first.match(/'|"/)) ? content.substr(1, content.length - 2) : content; 2722} 2723 2724function getWords(characters) { 2725 var words = [], i = 0, onWordBoundary = false, word; 2726 while(characters.length) { 2727 if (isWordBoundary(characters[i]) === onWordBoundary) { 2728 word = characters.splice(0, i); 2729 if (word.length) { 2730 words.push(window.html2canvas.punycode.ucs2.encode(word)); 2731 } 2732 onWordBoundary =! onWordBoundary; 2733 i = 0; 2734 } else { 2735 i++; 2736 } 2737 2738 if (i >= characters.length) { 2739 word = characters.splice(0, i); 2740 if (word.length) { 2741 words.push(window.html2canvas.punycode.ucs2.encode(word)); 2742 } 2743 } 2744 } 2745 return words; 2746} 2747 2748function isWordBoundary(characterCode) { 2749 return [ 2750 32, // <space> 2751 13, // \r 2752 10, // \n 2753 9, // \t 2754 45 // - 2755 ].indexOf(characterCode) !== -1; 2756} 2757 2758function hasUnicode(string) { 2759 return (/[^\u0000-\u00ff]/).test(string); 2760} 2761 2762function Proxy(src, proxyUrl, document) { 2763 if (!proxyUrl) { 2764 return Promise.reject("No proxy configured"); 2765 } 2766 var callback = createCallback(supportsCORS); 2767 var url = createProxyUrl(proxyUrl, src, callback); 2768 2769 return supportsCORS ? XHR(url) : (jsonp(document, url, callback).then(function(response) { 2770 return decode64(response.content); 2771 })); 2772} 2773var proxyCount = 0; 2774 2775var supportsCORS = ('withCredentials' in new XMLHttpRequest()); 2776var supportsCORSImage = ('crossOrigin' in new Image()); 2777 2778function ProxyURL(src, proxyUrl, document) { 2779 var callback = createCallback(supportsCORSImage); 2780 var url = createProxyUrl(proxyUrl, src, callback); 2781 return (supportsCORSImage ? Promise.resolve(url) : jsonp(document, url, callback).then(function(response) { 2782 return "data:" + response.type + ";base64," + response.content; 2783 })); 2784} 2785 2786function jsonp(document, url, callback) { 2787 return new Promise(function(resolve, reject) { 2788 var s = document.createElement("script"); 2789 var cleanup = function() { 2790 delete window.html2canvas.proxy[callback]; 2791 document.body.removeChild(s); 2792 }; 2793 window.html2canvas.proxy[callback] = function(response) { 2794 cleanup(); 2795 resolve(response); 2796 }; 2797 s.src = url; 2798 s.onerror = function(e) { 2799 cleanup(); 2800 reject(e); 2801 }; 2802 document.body.appendChild(s); 2803 });
2804} 2805 2806function createCallback(useCORS) { 2807 return !useCORS ? "html2canvas_" + Date.now() + "_" + (++proxyCount) + "_" + Math.round(Math.random() * 100000) : ""; 2808} 2809 2810function createProxyUrl(proxyUrl, src, callback) { 2811 return proxyUrl + "?url=" + encodeURIComponent(src) + (callback.length ? "&callback=html2canvas.proxy." + callback : ""); 2812} 2813 2814function ProxyImageContainer(src, proxy) { 2815 var script = document.createElement("script"); 2816 var link = document.createElement("a"); 2817 link.href = src; 2818 src = link.href; 2819 this.src = src; 2820 this.image = new Image(); 2821 var self = this; 2822 this.promise = new Promise(function(resolve, reject) { 2823 self.image.crossOrigin = "Anonymous"; 2824 self.image.onload = resolve; 2825 self.image.onerror = reject; 2826 2827 new ProxyURL(src, proxy, document).then(function(url) { 2828 self.image.src = url; 2829 })['catch'](reject); 2830 }); 2831} 2832 2833function PseudoElementContainer(node, parent, type) { 2834 NodeContainer.call(this, node, parent); 2835 this.isPseudoElement = true; 2836 this.before = type === ":before"; 2837} 2838 2839PseudoElementContainer.prototype.cloneTo = function(stack) { 2840 PseudoElementContainer.prototype.cloneTo.call(this, stack); 2841 stack.isPseudoElement = true; 2842 stack.before = this.before; 2843}; 2844 2845PseudoElementContainer.prototype = Object.create(NodeContainer.prototype); 2846 2847PseudoElementContainer.prototype.appendToDOM = function() { 2848 if (this.before) { 2849 this.parent.node.insertBefore(this.node, this.parent.node.firstChild); 2850 } else { 2851 this.parent.node.appendChild(this.node); 2852 } 2853 this.parent.node.className += " " + this.getHideClass(); 2854}; 2855 2856PseudoElementContainer.prototype.cleanDOM = function() { 2857 this.node.parentNode.removeChild(this.node); 2858 this.parent.node.className = this.parent.node.className.replace(this.getHideClass(), ""); 2859}; 2860 2861PseudoElementContainer.prototype.getHideClass = function() { 2862 return this["PSEUDO_HIDE_ELEMENT_CLASS_" + (this.before ? "BEFORE" : "AFTER")]; 2863}; 2864 2865PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE = "___html2canvas___pseudoelement_before"; 2866PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER = "___html2canvas___pseudoelement_after"; 2867 2868function Renderer(width, height, images, options, document) { 2869 this.width = width; 2870 this.height = height; 2871 this.images = images; 2872 this.options = options; 2873 this.document = document; 2874} 2875 2876Renderer.prototype.renderImage = function(container, bounds, borderData, imageContainer) { 2877 var paddingLeft = container.cssInt('paddingLeft'), 2878 paddingTop = container.cssInt('paddingTop'), 2879 paddingRight = container.cssInt('paddingRight'), 2880 paddingBottom = container.cssInt('paddingBottom'), 2881 borders = borderData.borders; 2882 2883 var width = bounds.width - (borders[1].width + borders[3].width + paddingLeft + paddingRight); 2884 var height = bounds.height - (borders[0].width + borders[2].width + paddingTop + paddingBottom); 2885 this.drawImage( 2886 imageContainer, 2887 0, 2888 0, 2889 imageContainer.image.width || width, 2890 imageContainer.image.height || height, 2891 bounds.left + paddingLeft + borders[3].width, 2892 bounds.top + paddingTop + borders[0].width, 2893 width, 2894 height 2895 ); 2896}; 2897 2898Renderer.prototype.renderBackground = function(container, bounds, borderData) { 2899 if (bounds.height > 0 && bounds.width > 0) { 2900 this.renderBackgroundColor(container, bounds); 2901 this.renderBackgroundImage(container, bounds, borderData); 2902 } 2903}; 2904 2905Renderer.prototype.renderBackgroundColor = function(container, bounds) { 2906 var color = container.color("backgroundColor"); 2907 if (!color.isTransparent()) { 2908 this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, color); 2909 } 2910}; 2911 2912Renderer.prototype.renderBorders = function(borders) { 2913 borders.forEach(this.renderBorder, this); 2914}; 2915 2916Renderer.prototype.renderBorder = function(data) { 2917 if (!data.color.isTransparent() && data.args !== null) { 2918 this.drawShape(data.args, data.color); 2919 } 2920}; 2921
2922Renderer.prototype.renderBackgroundImage = function(container, bounds, borderData) { 2923 var backgroundImages = container.parseBackgroundImages(); 2924 backgroundImages.reverse().forEach(function(backgroundImage, index, arr) { 2925 switch(backgroundImage.method) { 2926 case "url": 2927 var image = this.images.get(backgroundImage.args[0]); 2928 if (image) { 2929 this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1), borderData); 2930 } else { 2931 log("Error loading background-image", backgroundImage.args[0]); 2932 } 2933 break; 2934 case "linear-gradient": 2935 case "gradient": 2936 var gradientImage = this.images.get(backgroundImage.value); 2937 if (gradientImage) { 2938 this.renderBackgroundGradient(gradientImage, bounds, borderData); 2939 } else { 2940 log("Error loading background-image", backgroundImage.args[0]); 2941 } 2942 break; 2943 case "none": 2944 break; 2945 default: 2946 log("Unknown background-image type", backgroundImage.args[0]); 2947 } 2948 }, this); 2949}; 2950 2951Renderer.prototype.renderBackgroundRepeating = function(container, bounds, imageContainer, index, borderData) { 2952 var size = container.parseBackgroundSize(bounds, imageContainer.image, index); 2953 var position = container.parseBackgroundPosition(bounds, imageContainer.image, index, size); 2954 var repeat = container.parseBackgroundRepeat(index); 2955 switch (repeat) { 2956 case "repeat-x": 2957 case "repeat no-repeat": 2958 this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + borderData[3], bounds.top + position.top + borderData[0], 99999, size.height, borderData); 2959 break; 2960 case "repeat-y": 2961 case "no-repeat repeat": 2962 this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + borderData[0], size.width, 99999, borderData); 2963 break; 2964 case "no-repeat": 2965 this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + position.top + borderData[0], size.width, size.height, borderData); 2966 break; 2967 default: 2968 this.renderBackgroundRepeat(imageContainer, position, size, {top: bounds.top, left: bounds.left}, borderData[3], borderData[0]); 2969 break; 2970 } 2971}; 2972 2973function StackingContext(hasOwnStacking, opacity, element, parent) { 2974 NodeContainer.call(this, element, parent); 2975 this.ownStacking = hasOwnStacking; 2976 this.contexts = []; 2977 this.children = []; 2978 this.opacity = (this.parent ? this.parent.stack.opacity : 1) * opacity; 2979} 2980 2981StackingContext.prototype = Object.create(NodeContainer.prototype); 2982 2983StackingContext.prototype.getParentStack = function(context) { 2984 var parentStack = (this.parent) ? this.parent.stack : null; 2985 return parentStack ? (parentStack.ownStacking ? parentStack : parentStack.getParentStack(context)) : context.stack; 2986}; 2987 2988function Support(document) { 2989 this.rangeBounds = this.testRangeBounds(document); 2990 this.cors = this.testCORS(); 2991 this.svg = this.testSVG(); 2992} 2993 2994Support.prototype.testRangeBounds = function(document) { 2995 var range, testElement, rangeBounds, rangeHeight, support = false; 2996 2997 if (document.createRange) { 2998 range = document.createRange(); 2999 if (range.getBoundingClientRect) { 3000 testElement = document.createElement('boundtest'); 3001 testElement.style.height = "123px"; 3002 testElement.style.display = "block"; 3003 document.body.appendChild(testElement); 3004 3005 range.selectNode(testElement); 3006 rangeBounds = range.getBoundingClientRect(); 3007 rangeHeight = rangeBounds.height; 3008 3009 if (rangeHeight === 123) { 3010 support = true; 3011 } 3012 document.body.removeChild(testElement); 3013 } 3014 } 3015 3016 return support; 3017}; 3018 3019Support.prototype.testCORS = function() { 3020 return typeof((new Image()).crossOrigin) !== "undefined"; 3021}; 3022 3023Support.prototype.testSVG = function() { 3024 var img = new Image(); 3025 var canvas = document.createElement("canvas");
3026 var ctx = canvas.getContext("2d"); 3027 img.src = "data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>"; 3028 3029 try { 3030 ctx.drawImage(img, 0, 0); 3031 canvas.toDataURL(); 3032 } catch(e) { 3033 return false; 3034 } 3035 return true; 3036}; 3037 3038function SVGContainer(src) { 3039 this.src = src; 3040 this.image = null; 3041 var self = this; 3042 3043 this.promise = this.hasFabric().then(function() { 3044 return (self.isInline(src) ? Promise.resolve(self.inlineFormatting(src)) : XHR(src)); 3045 }).then(function(svg) { 3046 return new Promise(function(resolve) { 3047 html2canvas.fabric.loadSVGFromString(svg, self.createCanvas.call(self, resolve)); 3048 }); 3049 }); 3050} 3051 3052SVGContainer.prototype.hasFabric = function() { 3053 return !html2canvas.fabric ? Promise.reject(new Error("html2canvas.svg.js is not loaded, cannot render svg")) : Promise.resolve(); 3054}; 3055 3056SVGContainer.prototype.inlineFormatting = function(src) { 3057 return (/^data:image\/svg\+xml;base64,/.test(src)) ? this.decode64(this.removeContentType(src)) : this.removeContentType(src); 3058}; 3059 3060SVGContainer.prototype.removeContentType = function(src) { 3061 return src.replace(/^data:image\/svg\+xml(;base64)?,/,''); 3062}; 3063 3064SVGContainer.prototype.isInline = function(src) { 3065 return (/^data:image\/svg\+xml/i.test(src)); 3066}; 3067 3068SVGContainer.prototype.createCanvas = function(resolve) { 3069 var self = this; 3070 return function (objects, options) { 3071 var canvas = new html2canvas.fabric.StaticCanvas('c'); 3072 self.image = canvas.lowerCanvasEl; 3073 canvas 3074 .setWidth(options.width) 3075 .setHeight(options.height) 3076 .add(html2canvas.fabric.util.groupSVGElements(objects, options)) 3077 .renderAll(); 3078 resolve(canvas.lowerCanvasEl); 3079 }; 3080};
3081 3082SVGContainer.prototype.decode64 = function(str) { 3083 return (typeof(window.atob) === "function") ? window.atob(str) : decode64(str); 3084}; 3085 3086/* 3087 * base64-arraybuffer 3088 * https://github.com/niklasvh/base64-arraybuffer 3089 * 3090 * Copyright (c) 2012 Niklas von Hertzen 3091 * Licensed under the MIT license. 3092 */ 3093 3094function decode64(base64) { 3095 var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 3096 var len = base64.length, i, encoded1, encoded2, encoded3, encoded4, byte1, byte2, byte3; 3097 3098 var output = ""; 3099 3100 for (i = 0; i < len; i+=4) { 3101 encoded1 = chars.indexOf(base64[i]); 3102 encoded2 = chars.indexOf(base64[i+1]); 3103 encoded3 = chars.indexOf(base64[i+2]); 3104 encoded4 = chars.indexOf(base64[i+3]); 3105 3106 byte1 = (encoded1 << 2) | (encoded2 >> 4); 3107 byte2 = ((encoded2 & 15) << 4) | (encoded3 >> 2); 3108 byte3 = ((encoded3 & 3) << 6) | encoded4; 3109 if (encoded3 === 64) { 3110 output += String.fromCharCode(byte1); 3111 } else if (encoded4 === 64 || encoded4 === -1) { 3112 output += String.fromCharCode(byte1, byte2); 3113 } else{ 3114 output += String.fromCharCode(byte1, byte2, byte3); 3115 } 3116 } 3117 3118 return output; 3119} 3120 3121function SVGNodeContainer(node, native) { 3122 this.src = node; 3123 this.image = null; 3124 var self = this; 3125 3126 this.promise = native ? new Promise(function(resolve, reject) { 3127 self.image = new Image(); 3128 self.image.onload = resolve; 3129 self.image.onerror = reject; 3130 self.image.src = "data:image/svg+xml," + (new XMLSerializer()).serializeToString(node); 3131 if (self.image.complete === true) { 3132 resolve(self.image); 3133 } 3134 }) : this.hasFabric().then(function() { 3135 return new Promise(function(resolve) { 3136 html2canvas.fabric.parseSVGDocument(node, self.createCanvas.call(self, resolve)); 3137 }); 3138 }); 3139} 3140 3141SVGNodeContainer.prototype = Object.create(SVGContainer.prototype); 3142 3143function TextContainer(node, parent) { 3144 NodeContainer.call(this, node, parent); 3145} 3146 3147TextContainer.prototype = Object.create(NodeContainer.prototype); 3148 3149TextContainer.prototype.applyTextTransform = function() { 3150 this.node.data = this.transform(this.parent.css("textTransform")); 3151}; 3152 3153TextContainer.prototype.transform = function(transform) { 3154 var text = this.node.data; 3155 switch(transform){ 3156 case "lowercase": 3157 return text.toLowerCase(); 3158 case "capitalize": 3159 return text.replace(/(^|\s|:|-|\(|\))([a-z])/g, capitalize); 3160 case "uppercase": 3161 return text.toUpperCase(); 3162 default: 3163 return text; 3164 } 3165}; 3166 3167function capitalize(m, p1, p2) { 3168 if (m.length > 0) { 3169 return p1 + p2.toUpperCase(); 3170 } 3171} 3172 3173function WebkitGradientContainer(imageData) { 3174 GradientContainer.apply(this, arguments); 3175 this.type = (imageData.args[0] === "linear") ? this.TYPES.LINEAR : this.TYPES.RADIAL; 3176} 3177 3178WebkitGradientContainer.prototype = Object.create(GradientContainer.prototype); 3179 3180function XHR(url) { 3181 return new Promise(function(resolve, reject) { 3182 var xhr = new XMLHttpRequest(); 3183 xhr.open('GET', url); 3184 3185 xhr.onload = function() { 3186 if (xhr.status === 200) { 3187 resolve(xhr.responseText); 3188 } else { 3189 reject(new Error(xhr.statusText)); 3190 } 3191 }; 3192 3193 xhr.onerror = function() { 3194 reject(new Error("Network Error")); 3195 }; 3196 3197 xhr.send(); 3198 }); 3199} 3200 3201function CanvasRenderer(width, height) { 3202 Renderer.apply(this, arguments); 3203 this.canvas = this.options.canvas || this.document.createElement("canvas"); 3204 if (!this.options.canvas) { 3205 this.canvas.width = width; 3206 this.canvas.height = height; 3207 } 3208 this.ctx = this.canvas.getContext("2d"); 3209 this.taintCtx = this.document.createElement("canvas").getContext("2d"); 3210 this.ctx.textBaseline = "bottom"; 3211 this.variables = {}; 3212 log("Initialized CanvasRenderer with size", width, "x", height); 3213} 3214 3215CanvasRenderer.prototype = Object.create(Renderer.prototype); 3216 3217CanvasRenderer.prototype.setFillStyle = function(fillStyle) { 3218 this.ctx.fillStyle = typeof(fillStyle) === "object" && !!fillStyle.isColor ? fillStyle.toString() : fillStyle; 3219 return this.ctx; 3220}; 3221 3222CanvasRenderer.prototype.rectangle = function(left, top, width, height, color) { 3223 this.setFillStyle(color).fillRect(left, top, width, height); 3224}; 3225 3226CanvasRenderer.prototype.circle = function(left, top, size, color) { 3227 this.setFillStyle(color); 3228 this.ctx.beginPath(); 3229 this.ctx.arc(left + size / 2, top + size / 2, size / 2, 0, Math.PI*2, true); 3230 this.ctx.closePath(); 3231 this.ctx.fill(); 3232}; 3233 3234CanvasRenderer.prototype.circleStroke = function(left, top, size, color, stroke, strokeColor) { 3235 this.circle(left, top, size, color); 3236 this.ctx.strokeStyle = strokeColor.toString(); 3237 this.ctx.stroke(); 3238}; 3239 3240CanvasRenderer.prototype.drawShape = function(shape, color) { 3241 this.shape(shape); 3242 this.setFillStyle(color).fill(); 3243}; 3244 3245CanvasRenderer.prototype.taints = function(imageContainer) { 3246 if (imageContainer.tainted === null) {
3247 this.taintCtx.drawImage(imageContainer.image, 0, 0); 3248 try { 3249 this.taintCtx.getImageData(0, 0, 1, 1); 3250 imageContainer.tainted = false; 3251 } catch(e) { 3252 this.taintCtx = document.createElement("canvas").getContext("2d"); 3253 imageContainer.tainted = true; 3254 } 3255 } 3256 3257 return imageContainer.tainted; 3258}; 3259 3260CanvasRenderer.prototype.drawImage = function(imageContainer, sx, sy, sw, sh, dx, dy, dw, dh) { 3261 if (!this.taints(imageContainer) || this.options.allowTaint) { 3262 this.ctx.drawImage(imageContainer.image, sx, sy, sw, sh, dx, dy, dw, dh); 3263 } 3264}; 3265 3266CanvasRenderer.prototype.clip = function(shapes, callback, context) { 3267 this.ctx.save(); 3268 shapes.filter(hasEntries).forEach(function(shape) { 3269 this.shape(shape).clip(); 3270 }, this); 3271 callback.call(context); 3272 this.ctx.restore(); 3273}; 3274 3275CanvasRenderer.prototype.shape = function(shape) { 3276 this.ctx.beginPath(); 3277 shape.forEach(function(point, index) { 3278 if (point[0] === "rect") { 3279 this.ctx.rect.apply(this.ctx, point.slice(1)); 3280 } else { 3281 this.ctx[(index === 0) ? "moveTo" : point[0] + "To" ].apply(this.ctx, point.slice(1)); 3282 } 3283 }, this); 3284 this.ctx.closePath(); 3285 return this.ctx; 3286}; 3287 3288CanvasRenderer.prototype.font = function(color, style, variant, weight, size, family) { 3289 this.setFillStyle(color).font = [style, variant, weight, size, family].join(" ").split(",")[0]; 3290}; 3291 3292CanvasRenderer.prototype.fontShadow = function(color, offsetX, offsetY, blur) { 3293 this.setVariable("shadowColor", color.toString()) 3294 .setVariable("shadowOffsetY", offsetX) 3295 .setVariable("shadowOffsetX", offsetY) 3296 .setVariable("shadowBlur", blur); 3297}; 3298 3299CanvasRenderer.prototype.clearShadow = function() { 3300 this.setVariable("shadowColor", "rgba(0,0,0,0)"); 3301}; 3302 3303CanvasRenderer.prototype.setOpacity = function(opacity) { 3304 this.ctx.globalAlpha = opacity; 3305}; 3306 3307CanvasRenderer.prototype.setTransform = function(transform) { 3308 this.ctx.translate(transform.origin[0], transform.origin[1]); 3309 this.ctx.transform.apply(this.ctx, transform.matrix); 3310 this.ctx.translate(-transform.origin[0], -transform.origin[1]); 3311}; 3312 3313CanvasRenderer.prototype.setVariable = function(property, value) { 3314 if (this.variables[property] !== value) { 3315 this.variables[property] = this.ctx[property] = value; 3316 } 3317 3318 return this; 3319}; 3320 3321CanvasRenderer.prototype.text = function(text, left, bottom) { 3322 this.ctx.fillText(text, left, bottom); 3323}; 3324 3325CanvasRenderer.prototype.backgroundRepeatShape = function(imageContainer, backgroundPosition, size, bounds, left, top, width, height, borderData) { 3326 var shape = [ 3327 ["line", Math.round(left), Math.round(top)], 3328 ["line", Math.round(left + width), Math.round(top)], 3329 ["line", Math.round(left + width), Math.round(height + top)], 3330 ["line", Math.round(left), Math.round(height + top)] 3331 ]; 3332 this.clip([shape], function() { 3333 this.renderBackgroundRepeat(imageContainer, backgroundPosition, size, bounds, borderData[3], borderData[0]); 3334 }, this); 3335}; 3336 3337CanvasRenderer.prototype.renderBackgroundRepeat = function(imageContainer, backgroundPosition, size, bounds, borderLeft, borderTop) { 3338 var offsetX = Math.round(bounds.left + backgroundPosition.left + borderLeft), offsetY = Math.round(bounds.top + backgroundPosition.top + borderTop); 3339 this.setFillStyle(this.ctx.createPattern(this.resizeImage(imageContainer, size), "repeat")); 3340 this.ctx.translate(offsetX, offsetY); 3341 this.ctx.fill(); 3342 this.ctx.translate(-offsetX, -offsetY); 3343}; 3344 3345CanvasRenderer.prototype.renderBackgroundGradient = function(gradientImage, bounds) { 3346 if (gradientImage instanceof LinearGradientContainer) { 3347 var gradient = this.ctx.createLinearGradient( 3348 bounds.left + bounds.width * gradientImage.x0, 3349 bounds.top + bounds.height * gradientImage.y0, 3350 bounds.left + bounds.width * gradientImage.x1, 3351 bounds.top + bounds.height * gradientImage.y1); 3352 gradientImage.colorStops.forEach(function(colorStop) { 3353 gradient.addColorStop(colorStop.stop, colorStop.color.toString()); 3354 }); 3355 this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, gradient); 3356 } 3357}; 3358 3359CanvasRenderer.prototype.resizeImage = function(imageContainer, size) { 3360 var image = imageContainer.image; 3361 if(image.width === size.width && image.height === size.height) { 3362 return image; 3363 } 3364 3365 var ctx, canvas = document.createElement('canvas'); 3366 canvas.width = size.width; 3367 canvas.height = size.height; 3368 ctx = canvas.getContext("2d"); 3369 ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, size.width, size.height ); 3370 return canvas; 3371};
3372 3373function hasEntries(array) { 3374 return array.length > 0; 3375} 3376 3377}).call({}, typeof(window) !== "undefined" ? window : undefined, typeof(document) !== "undefined" ? document : undefined); 3378/*! 3379 * jquery.confirm 3380 * 3381 * @version 2.0.1 3382 * 3383 * @author My C-Labs 3384 * @author Matthieu Napoli <[email protected]> 3385 * @author Russel Vela 3386 * 3387 * @license MIT 3388 * @url http://myclabs.github.io/jquery.confirm/ 3389 */ 3390(function($){$.fn.confirm=function(options){if(typeof options==="undefined"){options={}}this.click(function(e){e.preventDefault();var newOptions=$.extend({button:$(this)},options);$.confirm(newOptions,e)});return this};$.confirm=function(options,e){var settings=$.extend({text:"Are you sure?",title:"",confirmButton:"Yes",cancelButton:"Cancel",post:false,confirm:function(o){var url=e.currentTarget.attributes["href"].value;if(options.post){var form=$('<form method="post" class="hide" action="'+url+'"></form>');$("body").append(form);form.submit()}else{window.location=url}},cancel:function(o){},button:null},options);var modalHeader="";if(settings.title!==""){modalHeader="<div class=modal-header>"+'<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>'+'<h4 class="modal-title">'+settings.title+"</h4>"+"</div>"}var modalHTML='<div class="confirmation-modal modal fade" tabindex="-1" role="dialog">'+'<div class="modal-dialog">'+'<div class="modal-content">'+modalHeader+'<div class="modal-body">'+settings.text+"</div>"+'<div class="modal-footer">'+'<button class="confirm btn btn-primary" type="button" data-dismiss="modal">'+settings.confirmButton+"</button>"+'<button class="cancel btn btn-default" type="button" data-dismiss="modal">'+settings.cancelButton+"</div>"+"</div>"+"</div>"+"</div>"+"</div>";var modal=$(modalHTML);modal.on("shown",function(){modal.find(".btn-primary:first").focus()});modal.on("hidden",function(){modal.remove()});modal.find(".confirm").click(function(){settings.confirm(settings.button)});modal.find(".cancel").click(function(){settings.cancel(settings.button)});$("body").append(modal);modal.modal("show")}})(jQuery); 3391 3392/* 3393 3394jsPDF fromHTML plugin. BETA stage. API subject to change. Needs browser, jQuery 3395Copyright (c) 2012 2012 Willow Systems Corporation, willow-systems.com 3396 jsPDF 0.9.0rc1 ( 2013-04-07T16:52 commit ID d95d8f69915bb999f6704e8021108e2e755bd868 ) 3397Copyright (c) 2010-2012 James Hall, [email protected], https://github.com/MrRio/jsPDF 3398Copyright (c) 2012 Willow Systems Corporation, willow-systems.com 3399MIT license. 3400 3401 ----------------------------------------------------------------------------------------------- 3402 JavaScript PubSub library 3403 2012 (c) [email protected] 3404 based on Peter Higgins ([email protected])
3405 Loosely based on Dojo publish/subscribe API, limited in scope. Rewritten blindly. 3406 Original is (c) Dojo Foundation 2004-2010. Released under either AFL or new BSD, see: 3407 http://dojofoundation.org/license for more information. 3408 ----------------------------------------------------------------------------------------------- 3409 3410jsPDF addImage plugin (JPEG only at this time) 3411Copyright (c) 2012 https://github.com/siefkenj/ 3412 3413jsPDF Silly SVG plugin 3414Copyright (c) 2012 Willow Systems Corporation, willow-systems.com 3415 3416jsPDF split_text_to_size plugin 3417Copyright (c) 2012 Willow Systems Corporation, willow-systems.com 3418MIT license. 3419 3420jsPDF standard_fonts_metrics plugin 3421Copyright (c) 2012 Willow Systems Corporation, willow-systems.com 3422MIT license. 3423*/ 3424var jsPDF=function(){function f(g,d,e,h){g="undefined"===typeof g?"p":g.toString().toLowerCase();"undefined"===typeof d&&(d="mm");"undefined"===typeof e&&(e="a4");"undefined"===typeof h&&"undefined"===typeof zpipe&&(h=!1);var a=e.toString().toLowerCase(),p=[],j=0,m=h;h={a3:[841.89,1190.55],a4:[595.28,841.89],a5:[420.94,595.28],letter:[612,792],legal:[612,1008]};var u="0 g",c=0,q=[],C=2,F=!1,H=[],n={},x={},z=16,A,y,s,r,I={title:"",subject:"",author:"",keywords:"",creator:""},w=0,aa=0,D={},G=new k(D), 3425B,v=function(c){return c.toFixed(2)},V=function(c){var e=c.toFixed(0);return 10>c?"0"+e:e},l=function(e){F?q[c].push(e):(p.push(e),j+=e.length+1)},N=function(){C++;H[C]=j;l(C+" 0 obj");return C},Q=function(c){l("stream");l(c);l("endstream")},J,ca,R,t=function(c,e){var d;d=c;var j=e,a,h,b,p,g,m;void 0===j&&(j={});a=j.sourceEncoding?a:"Unicode";b=j.outputEncoding;if((j.autoencode||b)&&n[A].metadata&&n[A].metadata[a]&&n[A].metadata[a].encoding)if(a=n[A].metadata[a].encoding,!b&&n[A].encoding&&(b=n[A].encoding), 3426!b&&a.codePages&&(b=a.codePages[0]),"string"===typeof b&&(b=a[b]),b){g=!1;p=[];a=0;for(h=d.length;a<h;a++)(m=b[d.charCodeAt(a)])?p.push(String.fromCharCode(m)):p.push(d[a]),p[a].charCodeAt(0)>>8&&(g=!0);d=p.join("")}for(a=d.length;void 0===g&&0!==a;)d.charCodeAt(a-1)>>8&&(g=!0),a--;if(g){p=j.noBOM?[]:[254,255];a=0;for(h=d.length;a<h;a++){m=d.charCodeAt(a);j=m>>8;if(j>>8)throw Error("Character at position "+a.toString(10)+" of string '"+d+"' exceeds 16bits. Cannot be encoded into UCS-2 BE");p.push(j); 3427p.push(m-(j<<8))}d=String.fromCharCode.apply(void 0,p)}return d.replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)")},W=function(){c++;F=!0;q[c]=[];l(v(0.200025*r)+" w");l("0 G");0!==w&&l(w.toString(10)+" J");0!==aa&&l(aa.toString(10)+" j");G.publish("addPage",{pageNumber:c})},E=function(c,a){var d;void 0===c&&(c=n[A].fontName);void 0===a&&(a=n[A].fontStyle);try{d=x[c][a]}catch(e){d=void 0}if(!d)throw Error("Unable to look up font label for font '"+c+"', '"+a+"'. Refer to getFontList() for available fonts."); 3428return d},K=function(){F=!1;p=[];H=[];l("%PDF-1.3");J=s*r;ca=y*r;var a,d,e,b,h;for(a=1;a<=c;a++){N();l("<</Type /Page");l("/Parent 1 0 R");l("/Resources 2 0 R");l("/Contents "+(C+1)+" 0 R>>");l("endobj");d=q[a].join("\n");N();if(m){e=[];for(b=0;b<d.length;++b)e[b]=d.charCodeAt(b);h=adler32cs.from(d);d=new Deflater(6);d.append(new Uint8Array(e));d=d.flush();e=[new Uint8Array([120,156]),new Uint8Array(d),new Uint8Array([h&255,h>>8&255,h>>16&255,h>>24&255])];d="";for(b in e)e.hasOwnProperty(b)&&(d+= 3429String.fromCharCode.apply(null,e[b]));l("<</Length "+d.length+" /Filter [/FlateDecode]>>")}else l("<</Length "+d.length+">>");Q(d);l("endobj")}H[1]=j;l("1 0 obj");l("<</Type /Pages");R="/Kids [";for(b=0;b<c;b++)R+=3+2*b+" 0 R ";l(R+"]");l("/Count "+c);l("/MediaBox [0 0 "+v(J)+" "+v(ca)+"]");l(">>");l("endobj");for(var g in n)n.hasOwnProperty(g)&&(a=n[g],a.objectNumber=N(),l("<</BaseFont/"+a.PostScriptName+"/Type/Font"),"string"===typeof a.encoding&&l("/Encoding/"+a.encoding),l("/Subtype/Type1>>"), 3430l("endobj"));G.publish("putResources");H[2]=j;l("2 0 obj");l("<<");l("/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]");l("/Font <<");for(var f in n)n.hasOwnProperty(f)&&l("/"+f+" "+n[f].objectNumber+" 0 R");l(">>");l("/XObject <<");G.publish("putXobjectDict");l(">>");l(">>");l("endobj");G.publish("postPutResources");N();l("<<");
3430l("/Producer (jsPDF 20120619)");I.title&&l("/Title ("+t(I.title)+")");I.subject&&l("/Subject ("+t(I.subject)+")");I.author&&l("/Author ("+t(I.author)+")");I.keywords&&l("/Keywords ("+ 3431t(I.keywords)+")");I.creator&&l("/Creator ("+t(I.creator)+")");g=new Date;l("/CreationDate (D:"+[g.getFullYear(),V(g.getMonth()+1),V(g.getDate()),V(g.getHours()),V(g.getMinutes()),V(g.getSeconds())].join("")+")");l(">>");l("endobj");N();l("<<");l("/Type /Catalog");l("/Pages 1 0 R");l("/OpenAction [3 0 R /FitH null]");l("/PageLayout /OneColumn");G.publish("putCatalog");l(">>");l("endobj");g=j;l("xref");l("0 "+(C+1));l("0000000000 65535 f ");for(f=1;f<=C;f++)a=H[f].toFixed(0),a=10>a.length?Array(11- 3432a.length).join("0")+a:a,l(a+" 00000 n ");l("trailer");l("<<");l("/Size "+(C+1));l("/Root "+C+" 0 R");l("/Info "+(C-1)+" 0 R");l(">>");l("startxref");l(g);l("%%EOF");F=!0;return p.join("\n")},Y=function(c){var a="S";if("F"===c)a="f";else if("FD"===c||"DF"===c)a="B";return a},Z=function(c,a){var d,e,b,j;switch(c){case void 0:return K();case "save":if(navigator.getUserMedia&&(void 0===window.URL||void 0===window.URL.createObjectURL))return D.output("dataurlnewwindow");d=K();e=d.length;b=new Uint8Array(new ArrayBuffer(e)); 3433for(j=0;j<e;j++)b[j]=d.charCodeAt(j);d=new Blob([b],{type:"application/pdf"});saveAs(d,a);break;case "datauristring":case "dataurlstring":return"data:application/pdf;base64,"+btoa(K());case "datauri":case "dataurl":document.location.href="data:application/pdf;base64,"+btoa(K());break;case "dataurlnewwindow":window.open("data:application/pdf;base64,"+btoa(K()));break;default:throw Error('Output type "'+c+'" is not supported.');}};if("pt"===d)r=1;else if("mm"===d)r=72/25.4;else if("cm"===d)r=72/2.54; 3434else if("in"===d)r=72;else throw"Invalid unit: "+d;if(h.hasOwnProperty(a))y=h[a][1]/r,s=h[a][0]/r;else try{y=e[1],s=e[0]}catch(M){throw"Invalid format: "+e;}if("p"===g||"portrait"===g)g="p",s>y&&(g=s,s=y,y=g);else if("l"===g||"landscape"===g)g="l",y>s&&(g=s,s=y,y=g);else throw"Invalid orientation: "+g;D.internal={pdfEscape:t,getStyle:Y,getFont:function(){return n[E.apply(D,arguments)]},getFontSize:function(){return z},btoa:btoa,write:function(c,a,d,e){l(1===arguments.length?c:Array.prototype.join.call(arguments, 3435" "))},getCoordinateString:function(c){return v(c*r)},getVerticalCoordinateString:function(c){return v((y-c)*r)},collections:{},newObject:N,putStream:Q,events:G,scaleFactor:r,pageSize:{width:s,height:y},output:function(c,a){return Z(c,a)}};D.addPage=function(){W();return this};D.text=function(c,a,d,e){var b,j;"number"===typeof c&&(b=c,j=a,c=d,a=b,d=j);"string"===typeof c&&c.match(/[\n\r]/)&&(c=c.split(/\r\n|\r|\n/g));"undefined"===typeof e?e={noBOM:!0,autoencode:!0}:(void 0===e.noBOM&&(e.noBOM=!0), 3436void 0===e.autoencode&&(e.autoencode=!0));if("string"===typeof c)e=t(c,e);else if(c instanceof Array){c=c.concat();for(b=c.length-1;-1!==b;b--)c[b]=t(c[b],e);e=c.join(") Tj\nT* (")}else throw Error('Type of text must be string or Array. "'+c+'" is not recognized.');l("BT\n/"+A+" "+z+" Tf\n"+z+" TL\n"+u+"\n"+v(a*r)+" "+v((y-d)*r)+" Td\n("+e+") Tj\nET");return this};D.line=function(c,a,d,e){l(v(c*r)+" "+v((y-a)*r)+" m "+v(d*r)+" "+v((y-e)*r)+" l S");return this};D.lines=function(c,a,d,e,b){var j,g, 3437h,p,m,f,q,u;"number"===typeof c&&(j=c,g=a,c=d,a=j,d=g);b=Y(b);e=void 0===e?[1,1]:e;l((a*r).toFixed(3)+" "+((y-d)*r).toFixed(3)+" m ");j=e[0];e=e[1];g=c.length;u=d;for(d=0;d<g;d++)h=c[d],2===h.length?(a=h[0]*j+a,u=h[1]*e+u,l((a*r).toFixed(3)+" "+((y-u)*r).toFixed(3)+" l")):(p=h[0]*j+a,m=h[1]*e+u,f=h[2]*j+a,q=h[3]*e+u,a=h[4]*j+a,u=h[5]*e+u,l((p*r).toFixed(3)+" "+((y-m)*r).toFixed(3)+" "+(f*r).toFixed(3)+" "+((y-q)*r).toFixed(3)+" "+(a*r).toFixed(3)+" "+((y-u)*r).toFixed(3)+" c"));l(b);return this}; 3438D.rect=function(c,a,d,e,b){b=Y(b);l([v(c*r),v((y-a)*r),v(d*r),v(-e*r),"re",b].join(" "));return this};D.triangle=function(c,a,d,e,b,j,h){this.lines([[d-c,e-a],[b-d,j-e],[c-b,a-j]],c,a,[1,1],h);return this};D.roundedRect=function(c,a,d,e,b,j,h){var g=4/3*(Math.SQRT2-1);this.lines([[d-2*b,0],[b*g,0,b,j-j*g,b,j],[0,e-2*j],[0,j*g,-(b*g),j,-b,j],[-d+2*b,0],[-(b*g),0,-b,-(j*g),-b,-j],[0,-e+2*j],[0,-(j*g),b*g,-j,b,-j]],c+b,a,[1,1],h);return this};D.ellipse=function(c,a,d,e,b){b=Y(b);var j=4/3*(Math.SQRT2- 34391)*d,g=4/3*(Math.SQRT2-1)*e;l([v((c+d)*r),v((y-a)*r),"m",v((c+d)*r),v((y-(a-g))*r),v((c+j)*r),v((y-(a-e))*r),v(c*r),v((y-(a-e))*r),"c"].join(" "));l([v((c-j)*r),v((y-(a-e))*r),v((c-d)*r),v((y-(a-g))*r),v((c-d)*r),v((y-a)*r),"c"].join(" "));l([v((c-d)*r),v((y-(a+g))*r),v((c-j)*r),v((y-(a+e))*r),v(c*r),v((y-(a+e))*r),"c"].join(" "));l([v((c+j)*r),v((y-(a+e))*r),v((c+d)*r),v((y-(a+g))*r),v((c+d)*r),v((y-a)*r),"c",b].join(" "));return this};D.circle=function(c,a,d,e){return this.ellipse(c,a,d,d,e)};D.setProperties= 3440function(c){for(var a in I)I.hasOwnProperty(a)&&c[a]&&(I[a]=c[a]);return this};D.setFontSize=function(c){z=c;return this};D.setFont=function(c,a){A=E(c,a);return this};D.setFontStyle=D.setFontType=function(c){A=E(void 0,c);return this};D.getFontList=function(){var c={},a,d,e;for(a in x)if(x.hasOwnProperty(a))for(d in c[a]=e=[],x[a])x[a].hasOwnProperty(d)&&e.push(d);return c};D.setLineWidth=function(c){l((c*r).toFixed(2)+" w");return this};D.setDrawColor=function(c,a,d,e){c=void 0===a||void 0===e&& 3441c===a===d?"string"===typeof c?c+" G":v(c/255)+" G":void 0===e?"string"===typeof c?[c,a,d,"RG"].join(" "):[v(c/255),v(a/255),v(d/255),"RG"].join(" "):"str
3441ing"===typeof c?[c,a,d,e,"K"].join(" "):[v(c),v(a),v(d),v(e),"K"].join(" ");l(c);return this};D.setFillColor=function(c,a,d,e){c=void 0===a||void 0===e&&c===a===d?"string"===typeof c?c+" g":v(c/255)+" g":void 0===e?"string"===typeof c?[c,a,d,"rg"].join(" "):[v(c/255),v(a/255),v(d/255),"rg"].join(" "):"string"===typeof c?[c,a,d,e,"k"].join(" "):[v(c), 3442v(a),v(d),v(e),"k"].join(" ");l(c);return this};D.setTextColor=function(c,a,d){u=0===c&&0===a&&0===d||"undefined"===typeof a?(c/255).toFixed(3)+" g":[(c/255).toFixed(3),(a/255).toFixed(3),(d/255).toFixed(3),"rg"].join(" ");return this};D.CapJoinStyles={"0":0,butt:0,but:0,bevel:0,1:1,round:1,rounded:1,circle:1,2:2,projecting:2,project:2,square:2,milter:2};D.setLineCap=function(c){var a=this.CapJoinStyles[c];if(void 0===a)throw Error("Line cap style of '"+c+"' is not recognized. See or extend .CapJoinStyles property for valid styles"); 3443w=a;l(a.toString(10)+" J");return this};D.setLineJoin=function(c){var a=this.CapJoinStyles[c];if(void 0===a)throw Error("Line join style of '"+c+"' is not recognized. See or extend .CapJoinStyles property for valid styles");aa=a;l(a.toString(10)+" j");return this};D.output=Z;D.save=function(c){D.output("save",c)};for(B in f.API)if(f.API.hasOwnProperty(B))if("events"===B&&f.API.events.length){g=G;d=f.API.events;h=a=e=void 0;for(h=d.length-1;-1!==h;h--)e=d[h][0],a=d[h][1],g.subscribe.apply(g,[e].concat("function"=== 3444typeof a?[a]:a))}else D[B]=f.API[B];B=[["Helvetica","helvetica","normal"],["Helvetica-Bold","helvetica","bold"],["Helvetica-Oblique","helvetica","italic"],["Helvetica-BoldOblique","helvetica","bolditalic"],["Courier","courier","normal"],["Courier-Bold","courier","bold"],["Courier-Oblique","courier","italic"],["Courier-BoldOblique","courier","bolditalic"],["Times-Roman","times","normal"],["Times-Bold","times","bold"],["Times-Italic","times","italic"],["Times-BoldItalic","times","bolditalic"]];g=0; 3445for(d=B.length;g<d;g++){h=B[g][0];var T=B[g][1],a=B[g][2];e="F"+(b(n)+1).toString(10);h=n[e]={id:e,PostScriptName:h,fontName:T,fontStyle:a,encoding:"StandardEncoding",metadata:{}};var ha=e;void 0===x[T]&&(x[T]={});x[T][a]=ha;G.publish("addFont",h);a=e;e=B[g][0].split("-");h=e[0];e=e[1]||"";void 0===x[h]&&(x[h]={});x[h][e]=a}G.publish("addFonts",{fonts:n,dictionary:x});A="F1";W();G.publish("initialized");return D}"undefined"===typeof btoa&&(window.btoa=function(b){var d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".split(""), 3446e,h,a,p,j=0,m=0,f="",f=[];do e=b.charCodeAt(j++),h=b.charCodeAt(j++),a=b.charCodeAt(j++),p=e<<16|h<<8|a,e=p>>18&63,h=p>>12&63,a=p>>6&63,p&=63,f[m++]=d[e]+d[h]+d[a]+d[p];while(j<b.length);f=f.join("");b=b.length%3;return(b?f.slice(0,b-3):f)+"===".slice(b||3)});"undefined"===typeof atob&&(window.atob=function(b){var d,e,h,a,p,j=0,m=0;a="";var f=[];if(!b)return b;b+="";do d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(b.charAt(j++)),e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(b.charAt(j++)), 3447a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(b.charAt(j++)),p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(b.charAt(j++)),h=d<<18|e<<12|a<<6|p,d=h>>16&255,e=h>>8&255,h&=255,64===a?f[m++]=String.fromCharCode(d):64===p?f[m++]=String.fromCharCode(d,e):f[m++]=String.fromCharCode(d,e,h);while(j<b.length);return a=f.join("")});var b="function"===typeof Object.keys?function(b){return Object.keys(b).length}:function(b){var d=0,e;for(e in b)b.hasOwnProperty(e)&& 3448d++;return d},k=function(b){this.topics={};this.context=b;this.publish=function(d,b){if(this.topics[d]){var h=this.topics[d],a=[],p,j,g,f,c=function(){};b=Array.prototype.slice.call(arguments,1);j=0;for(g=h.length;j<g;j++)f=h[j],p=f[0],f[1]&&(f[0]=c,a.push(j)),p.apply(this.context,b);j=0;for(g=a.length;j<g;j++)h.splice(a[j],1)}};this.subscribe=function(d,b,h){this.topics[d]?this.topics[d].push([b,h]):this.topics[d]=[[b,h]];return{topic:d,callback:b}};this.unsubscribe=function(d){if(this.topics[d.topic]){var b= 3449this.topics[d.topic],h,a;h=0;for(a=b.length;h<a;h++)b[h][0]===d.callback&&b.splice(h,1)}}};f.API={events:[]};return f}(); 3450(function(f){var b=function(){var b=this.internal.collections.addImage_images,d;for(d in b){var e=b[d],h=this.internal.newObject(),a=this.internal.write,p=this.internal.putStream;e.n=h;a("<</Type /XObject");a("/Subtype /Image");a("/Width "+e.w);a("/Height "+e.h);"Indexed"===e.cs?a("/ColorSpace [/Indexed /DeviceRGB "+(e.pal.length/3-1)+" "+(h+1)+" 0 R]"):(a("/ColorSpace /"+e.cs),"DeviceCMYK"===e.cs&&a("/Decode [1 0 1 0 1 0 1 0]"));a("/BitsPerComponent "+e.bpc);"f"in e&&a("/Filter /"+e.f);"dp"in e&& 3451a("/DecodeParms <<"+e.dp+">>");if("trns"in e&&e.trns.constructor==Array)for(var j="",f=0;f<e.trns.length;f++)j+=e[j][f]+" "+e.trns[f]+" ",a("/Mask ["+j+"]");"smask"in e&&a("/SMask "+(h+1)+" 0 R");a("/Length "+e.data.length+">>");p(e.data);a("endobj")}},k=function(){var b=this.internal.collections.addImage_images,d=this.internal.write,e,h;for(h in b)e=b[h],d("/I"+e.i,e.n,"0","R")};f.addImage=function(g,d,e,h,a,p){if("object"===typeof g&&1===g.nodeType){d=document.createElement("canvas");d.width=g.clientWidth; 3452d.height=g.clientHeight;var j=d.getContext("2d");if(!j)throw"addImage requires canvas to be supported by browser.";j.drawImage(g,0,0,d.width,d.height);g=d.toDataURL("image/jpeg");d="JPEG"}if("JPEG"!==d.toUpperCase())throw Error("addImage currently only supports format 'JPEG', not '"+d+"'");var f;d=this.internal.collections.addImage_images;var j=this.internal.getCoordinateString,u=this.internal.getVerticalCoordinateString;"data:image/jpeg;base64,"===g.substring(0,23)&&(g=atob(g.replace("data:image/jpeg;base64,", 3453"")));if(d)if(Object.keys)f=Object.keys(d).length;else{var c=d,q=0;for(f in c)c.hasOwnProperty(f)&&q++;f=q}else f=0,this.internal.collections.addImage_images=d={},this.internal.events.subscribe("putResources",b),this.internal.events.subscribe("putXobjectDict",k);a:{var c=g,C;if(255===!c.charCodeAt(0)||216===!c.charCodeAt(1)||255===!c.charCodeAt(2)||224===!c.charCodeAt(3)||74===!c.charCodeAt(6)||70===!c.charCodeAt(7)||73===!c.charCodeAt(8)||70===!c.charCodeAt(9)||0===!c.charCodeAt(10))throw Error("getJpegSize requires a binary jpeg file");
3454C=256*c.charCodeAt(4)+c.charCodeAt(5);for(var q=4,F=c.length;q<F;){q+=C;if(255!==c.charCodeAt(q))throw Error("getJpegSize could not find the size of the image");if(192===c.charCodeAt(q+1)){C=256*c.charCodeAt(q+5)+c.charCodeAt(q+6);c=256*c.charCodeAt(q+7)+c.charCodeAt(q+8);c=[c,C];break a}else q+=2,C=256*c.charCodeAt(q)+c.charCodeAt(q+1)}c=void 0}g={w:c[0],h:c[1],cs:"DeviceRGB",bpc:8,f:"DCTDecode",i:f,data:g};d[f]=g;!a&&!p&&(p=a=-96);0>a&&(a=-72*g.w/a/this.internal.scaleFactor);0>p&&(p=-72*g.h/p/this.internal.scaleFactor); 34550===a&&(a=p*g.w/g.h);0===p&&(p=a*g.h/g.w);this.internal.write("q",j(a),"0 0",j(p),j(e),u(h+p),"cm /I"+g.i,"Do Q");return this}})(jsPDF.API); 3456(function(f){function b(a,b,d,e){this.pdf=a;this.x=b;this.y=d;this.settings=e;this.init();return this}function k(b){var d=a[b];if(d)return d;d={"xx-small":9,"x-small":11,small:13,medium:16,large:19,"x-large":23,"xx-large":28,auto:0}[b];if(void 0!==d||(d=parseFloat(b)))return a[b]=d/16;d=b.match(/([\d\.]+)(px)/);return 3===d.length?a[b]=parseFloat(d[1])/16:a[b]=1}function g(a,b,f){var u=a.childNodes,c;c=$(a);a={};for(var q,C=c.css("font-family").split(","),F=C.shift();!q&&F;)q=d[F.trim().toLowerCase()], 3457F=C.shift();a["font-family"]=q||"times";a["font-style"]=h[c.css("font-style")]||"normal";q=e[c.css("font-weight")]||"normal";"bold"===q&&(a["font-style"]="normal"===a["font-style"]?q:q+a["font-style"]);a["font-size"]=k(c.css("font-size"))||1;a["line-height"]=k(c.css("line-height"))||1;a.display="inline"===c.css("display")?"inline":"block";"block"===a.display&&(a["margin-top"]=k(c.css("margin-top"))||0,a["margin-bottom"]=k(c.css("margin-bottom"))||0,a["padding-top"]=k(c.css("padding-top"))||0,a["padding-bottom"]= 3458k(c.css("padding-bottom"))||0);if(q="block"===a.display)b.setBlockBoundary(),b.setBlockStyle(a);C=0;for(F=u.length;C<F;C++)if(c=u[C],"object"===typeof c)if(1===c.nodeType&&"SCRIPT"!=c.nodeName){var H=c,n=b,x=f,z=!1,A=void 0,y=void 0,s=x["#"+H.id];if(s)if("function"===typeof s)z=s(H,n);else{A=0;for(y=s.length;!z&&A!==y;)z=s[A](H,n),A++}s=x[H.nodeName];if(!z&&s)if("function"===typeof s)z=s(H,n);else{A=0;for(y=s.length;!z&&A!==y;)z=s[A](H,n),A++}z||g(c,b,f)}else 3===c.nodeType&&b.addText(c.nodeValue, 3459a);else"string"===typeof c&&b.addText(c,a);q&&b.setBlockBoundary()}String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")});String.prototype.trimLeft||(String.prototype.trimLeft=function(){return this.replace(/^\s+/g,"")});String.prototype.trimRight||(String.prototype.trimRight=function(){return this.replace(/\s+$/g,"")});b.prototype.init=function(){this.paragraph={text:[],style:[]};this.pdf.internal.write("q")};b.prototype.dispose=function(){this.pdf.internal.write("Q"); 3460return{x:this.x,y:this.y}};b.prototype.splitFragmentsIntoLines=function(a,b){for(var d=this.pdf.internal.scaleFactor,e={},c,h,g,f,k,n=[],x=[n],z=0,A=this.settings.width;a.length;)if(f=a.shift(),k=b.shift(),f)if(c=k["font-family"],h=k["font-style"],g=e[c+h],g||(g=this.pdf.internal.getFont(c,h).metadata.Unicode,e[c+h]=g),c={widths:g.widths,kerning:g.kerning,fontSize:12*k["font-size"],textIndent:z},h=this.pdf.getStringUnitWidth(f,c)*c.fontSize/d,z+h>A){f=this.pdf.splitTextToSize(f,A,c);for(n.push([f.shift(), 3461k]);f.length;)n=[[f.shift(),k]],x.push(n);z=this.pdf.getStringUnitWidth(n[0][0],c)*c.fontSize/d}else n.push([f,k]),z+=h;return x};b.prototype.RenderTextFragment=function(a,b){var d=this.pdf.internal.getFont(b["font-family"],b["font-style"]);this.pdf.internal.write("/"+d.id,(12*b["font-size"]).toFixed(2),"Tf","("+this.pdf.internal.pdfEscape(a)+") Tj")};b.prototype.renderParagraph=function(){for(var a=this.paragraph.text,b=0,d=a.length,e,c=!1,h=!1;!c&&b!==d;)(e=a[b]=a[b].trimLeft())&&(c=!0),b++;for(b= 3462d-1;d&&!h&&-1!==b;)(e=a[b]=a[b].trimRight())&&(h=!0),b--;c=/\s+$/g;h=!0;for(b=0;b!==d;b++)e=a[b].replace(/\s+/g," "),h&&(e=e.trimLeft()),e&&(h=c.test(e)),a[b]=e;b=this.paragraph.style;e=(d=this.paragraph.blockstyle)||{};this.paragraph={text:[],style:[],blockstyle:{},priorblockstyle:d};if(a.join("").trim()){a=this.splitFragmentsIntoLines(a,b);b=12/this.pdf.internal.scaleFactor;c=(Math.max((d["margin-top"]||0)-(e["margin-bottom"]||0),0)+(d["padding-top"]||0))*b;d=((d["margin-bottom"]||0)+(d["padding-bottom"]|| 34630))*b;e=this.pdf.internal.write;var g,f;this.y+=c;for(e("q","BT",this.pdf.internal.getCoordinateString(this.x),this.pdf.internal.getVerticalCoordinateString(this.y),"Td");a.length;){c=a.shift();g=h=0;for(f=c.length;g!==f;g++)c[g][0].trim()&&(h=Math.max(h,c[g][1]["line-height"],c[g][1]["font-size"]));e(0,(-12*h).toFixed(2),"Td");g=0;for(f=c.length;g!==f;g++)c[g][0]&&this.RenderTextFragment(c[g][0],c[g][1]);this.y+=h*b}e("ET","Q");this.y+=d}};b.prototype.setBlockBoundary=function(){this.renderParagraph()}; 3464b.prototype.setBlockStyle=function(a){this.paragraph.blockstyle=a};b.prototype.addText=function(a,b){this.paragraph.text.push(a);this.paragraph.style.push(b)};var d={helvetica:"helvetica","sans-serif":"helvetica",serif:"times",times:"times","times new roman":"times",monospace:"courier",courier:"courier"},e={100:"normal",200:"normal",300:"normal",400:"normal",500:"bold",600:"bold",700:"bold",800:"bold",900:"bold",normal:"normal",bold:"bold",bolder:"bold",lighter:"normal"},h={normal:"normal",italic:"italic", 3465oblique:"italic"},a={normal:1};f.fromHTML=function(a,d,e,h){if("string"===typeof a){var c="jsPDFhtmlText"+Date.now().toString()+(1E3*Math.random()).toFixed(0);
3465$('<div style="position: absolute !important;clip: rect(1px 1px 1px 1px); /* IE6, IE7 */clip: rect(1px, 1px, 1px, 1px);padding:0 !important;border:0 !important;height: 1px !important;width: 1px !important; top:auto;left:-100px;overflow: hidden;"><iframe style="height:1px;width:1px" name="'+c+'" /></div>').appendTo(document.body);a=$(window.frames[c].document.body).html(a)[0]}d= 3466new b(this,d,e,h);g(a,d,h.elementHandlers);return d.dispose()}})(jsPDF.API); 3467(function(f){f.addSVG=function(b,f,g,d,e){if(void 0===f||void 0===f)throw Error("addSVG needs values for 'x' and 'y'");var h=document.createElement("iframe"),a=document.createElement("style");a.type="text/css";a.styleSheet?a.styleSheet.cssText=".jsPDF_sillysvg_iframe {display:none;position:absolute;}":a.appendChild(document.createTextNode(".jsPDF_sillysvg_iframe {display:none;position:absolute;}"));document.getElementsByTagName("head")[0].appendChild(a);h.name="childframe";h.setAttribute("width", 34680);h.setAttribute("height",0);h.setAttribute("frameborder","0");h.setAttribute("scrolling","no");h.setAttribute("seamless","seamless");h.setAttribute("class","jsPDF_sillysvg_iframe");document.body.appendChild(h);h=(h.contentWindow||h.contentDocument).document;h.write(b);h.close();h=h.getElementsByTagName("svg")[0];b=[1,1];var a=parseFloat(h.getAttribute("width")),p=parseFloat(h.getAttribute("height"));a&&p&&(d&&e?b=[d/a,e/p]:d?b=[d/a,d/a]:e&&(b=[e/p,e/p]));h=h.childNodes;d=0;for(e=h.length;d<e;d++)if(a= 3469h[d],a.tagName&&"PATH"===a.tagName.toUpperCase()){for(var a=a.getAttribute("d").split(" "),p=parseFloat(a[1]),j=parseFloat(a[2]),m=[],u=3,c=a.length;u<c;)"c"===a[u]?(m.push([parseFloat(a[u+1]),parseFloat(a[u+2]),parseFloat(a[u+3]),parseFloat(a[u+4]),parseFloat(a[u+5]),parseFloat(a[u+6])]),u+=7):"l"===a[u]?(m.push([parseFloat(a[u+1]),parseFloat(a[u+2])]),u+=3):u+=1;a=[p,j,m];a[0]=a[0]*b[0]+f;a[1]=a[1]*b[1]+g;this.lines.call(this,a[2],a[0],a[1],b)}return this}})(jsPDF.API); 3470(function(f){var b=f.getCharWidthsArray=function(b,e){e||(e={});var h=e.widths?e.widths:this.internal.getFont().metadata.Unicode.widths,a=h.fof?h.fof:1,g=e.kerning?e.kerning:this.internal.getFont().metadata.Unicode.kerning,f=g.fof?g.fof:1,m,k,c,q=0,C=h[0]||a,F=[];m=0;for(k=b.length;m<k;m++)c=b.charCodeAt(m),F.push((h[c]||C)/a+(g[c]&&g[c][q]||0)/f),q=c;return F},k=function(b){for(var e=b.length,h=0;e;)e--,h+=b[e];return h};f.getStringUnitWidth=function(d,e){return k(b.call(this,d,e))};var g=function(d, 3471e,h){h||(h={});var a=b(" ",h)[0],g=d.split(" "),f=[];d=[f];var m=h.textIndent||0,u=0,c=0,q,C,F,H;F=0;for(H=g.length;F<H;F++){q=g[F];C=b(q,h);c=k(C);if(m+u+c>e){if(c>e){for(var c=q,n=C,x=e,z=[],A=0,y=c.length,s=0;A!==y&&s+n[A]<e-(m+u);)s+=n[A],A++;z.push(c.slice(0,A));m=A;for(s=0;A!==y;)s+n[A]>x&&(z.push(c.slice(m,A)),s=0,m=A),s+=n[A],A++;m!==A&&z.push(c.slice(m,A));m=z;f.push(m.shift());for(f=[m.pop()];m.length;)d.push([m.shift()]);c=k(C.slice(q.length-f[0].length))}else f=[q];d.push(f);m=c}else f.push(q), 3472m+=u+c;u=a}e=[];F=0;for(H=d.length;F<H;F++)e.push(d[F].join(" "));return e};f.splitTextToSize=function(b,e,h){h||(h={});var a=h.fontSize||this.internal.getFontSize(),f;var j=h;f={"0":1};var m={};!j.widths||!j.kerning?(j=this.internal.getFont(j.fontName,j.fontStyle),f=j.metadata.Unicode?{widths:j.metadata.Unicode.widths||f,kerning:j.metadata.Unicode.kerning||m}:{widths:f,kerning:m}):f={widths:j.widths,kerning:j.kerning};b=b.match(/[\n\r]/)?b.split(/\r\n|\r|\n/g):[b];e=1*this.internal.scaleFactor*e/ 3473a;f.textIndent=h.textIndent?1*h.textIndent*this.internal.scaleFactor/a:0;m=[];h=0;for(a=b.length;h<a;h++)m=m.concat(g(b[h],e,f));return m}})(jsPDF.API); 3474(function(f){var b=function(b){for(var d={},a=0;16>a;a++)d["klmnopqrstuvwxyz"[a]]="0123456789abcdef"[a];for(var g={},f=1,m,k=g,c=[],q,C="",F="",H,n=b.length-1,a=1;a!=n;)q=b[a],a+=1,"'"==q?m?(H=m.join(""),m=void 0):m=[]:m?m.push(q):"{"==q?(c.push([k,H]),k={},H=void 0):"}"==q?(q=c.pop(),q[0][q[1]]=k,H=void 0,k=q[0]):"-"==q?f=-1:void 0===H?d.hasOwnProperty(q)?(C+=d[q],H=parseInt(C,16)*f,f=1,C=""):C+=q:d.hasOwnProperty(q)?(F+=d[q],k[H]=parseInt(F,16)*f,f=1,H=void 0,F=""):F+=q;return g},k={codePages:["WinAnsiEncoding"], 3475WinAnsiEncoding:b("{19m8n201n9q201o9r201s9l201t9m201u8m201w9n201x9o201y8o202k8q202l8r202m9p202q8p20aw8k203k8t203t8v203u9v2cq8s212m9t15m8w15n9w2dw9s16k8u16l9u17s9z17x8y17y9y}")},g={Unicode:{Courier:k,"Courier-Bold":k,"Courier-BoldOblique":k,"Courier-Oblique":k,Helvetica:k,"Helvetica-Bold":k,"Helvetica-BoldOblique":k,"Helvetica-Oblique":k,"Times-Roman":k,"Times-Bold":k,"Times-BoldItalic":k,"Times-Italic":k}},d={Unicode:{"Courier-Oblique":b("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-BoldItalic":b("{'widths'{k3o2q4ycx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2r202m2n2n3m2o3m2p5n202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5n4l4m4m4m4n4m4o4s4p4m4q4m4r4s4s4y4t2r4u3m4v4m4w3x4x5t4y4s4z4s5k3x5l4s5m4m5n3r5o3x5p4s5q4m5r5t5s4m5t3x5u3x5v2l5w1w5x2l5y3t5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q2l6r3m6s3r6t1w6u1w6v3m6w1w6x4y6y3r6z3m7k3m7l3m7m2r7n2r7o1w7p3r7q2w7r4m7s3m7t2w7u2r7v2n7w1q7x2n7y3t202l3mcl4mal2ram3man3mao3map3mar3mas2lat4uau1uav3maw3way4uaz2lbk2sbl3t'fof'6obo2lbp3tbq3mbr1tbs2lbu1ybv3mbz3mck4m202k3mcm4mcn4mco4mcp4mcq5ycr4mcs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3me
3475k3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz2w203k6o212m6o2dw2l2cq2l3t3m3u2l17s3x19m3m}'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}}}"), 3476"Helvetica-Bold":b("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4y
3476dn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'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}}}"), 3477Courier:b("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Courier-BoldOblique":b("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-Bold":b("{'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}}}"), 3478Helvetica:b("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4y
3478dn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'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}}}"), 3479"Helvetica-BoldOblique":b("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4y
3479dn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'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}}}"), 3480"Courier-Bold":b("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-Italic":b("{'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}
3480fv{17su5tu5qs}fw{17su5tu5qs}}}"), 3481"Times-Roman":b("{'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}}}"), 3482"Helvetica-Oblique":b("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4y
3482dn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'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}}}")}}; 3483f.events.push(["addFonts",function(b){var h,a,f,j;for(a in b.fonts)if(b.fonts.hasOwnProperty(a)){h=b.fonts[a];if(f=d.Unicode[h.PostScriptName])j=h.metadata.Unicode?h.metadata.Unicode:h.metadata.Unicode={},j.widths=f.widths,j.kerning=f.kerning;if(f=g.Unicode[h.PostScriptName])j=h.metadata.Unicode?h.metadata.Unicode:h.metadata.Unicode={},j.encoding=f,f.codePages&&f.codePages.length&&(h.encoding=f.codePages[0])}}])})(jsPDF.API); 3484var BlobBuilder=BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder||function(f){var b=function(a){return Object.prototype.toString.call(a).match(/^\[object\s(.*)\]$/)[1]},k=function(){this.data=[]},g=function(a,b,c){this.data=a;this.size=a.length;this.type=b;this.encoding=c},d=k.prototype,e=g.prototype,h=f.FileReaderSync,a=function(a){this.code=this[this.name=a]},p="NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR".split(" "), 3485j=p.length,m=f.URL||f.webkitURL||f,u=m.createObjectURL,c=m.revokeObjectURL,q=m,C=f.btoa,F=f.atob,H=!1,n=function(a){H=!a},x=f.ArrayBuffer,z=f.Uint8Array;for(k.fake=e.fake=!0;j--;)a.prototype[p[j]]=j+1;try{z&&n.apply(0,new z(1))}catch(A){}m.createObjectURL||(q=f.URL={});q.createObjectURL=function(a){var b=a.type;null===b&&(b="application/octet-stream");if(a instanceof g)return b="data:"+b,"base64"===a.encoding?b+";base64,"+a.data:"URI"===a.encoding?b+","+decodeURIComponent(a.data):C?b+";base64,"+C(a.data): 3486b+","+encodeURIComponent(a.data);if(u)return u.call(m,a)};q.revokeObjectURL=function(a){"data:"!==a.substring(0,5)&&c&&c.call(m,a)};d.append=function(c){var d=this.data;if(z&&c instanceof x)if(H)d.push(String.fromCharCode.apply(String,new z(c)));else{d="";c=new z(c);for(var e=0,f=c.length;e<f;e++)d+=String.fromCharCode(c[e])}else if("Blob"===b(c)||"File"===b(c))if(h)e=new h,d.push(e.readAsBinaryString(c));else throw new a("NOT_READABLE_ERR");else c instanceof g?"base64"===c.encoding&&F?d.push(F(c.data)): 3487"URI"===c.encoding?d.push(decodeURIComponent(c.data)):"raw"===c.encoding&&d.push(c.data):("string"!==typeof c&&(c+=""),d.push(unescape(encodeURIComponent(c))))};d.getBlob=function(a){arguments.length||(a=null);return new g(this.data.join(""),a,"raw")};d.toString=function(){return"[object BlobBuilder]"};e.slice=function(a,c,b){var d=arguments.length;3>d&&(b=null);return new g(this.data.slice(a,1<d?c:this.data.length),b,this.encoding)};e.toString=function(){return"[object Blob]"};return k}(self),saveAs= 3488saveAs||navigator.msSaveBlob&&navigator.msSaveBlob.bind(navigator)||function(f){var b=f.document,k=f.URL||f.webkitURL||f,g=b.createElementNS("http://www.w3.org/1999/xhtml","a"),d="download"in g,e=f.webkitRequestFileSystem,h=f.requestFileSystem||e||f.mozRequestFileSystem,a=function(a){(f.setImmediate||f.setTimeout)(function(){throw a;},0)},p=0,j=[],m=function(c,b,d){b=[].concat(b);for(var e=b.length;e--;){var f=c["on"+b[e]];if("function"===typeof f)try{f.call(c,d||c)}catch(h){a(h)}}},u=function(a, 3489c){var k=this,u=a.type,n=!1,x,z,A=function(){var c=(f.URL||f.webkitURL||f).createObjectURL(a);j.push(c);return c},y=function(){m(k,["writestart","progress","write","writeend"])}
3489,s=function(){if(n||!x)x=A(a);z&&(z.location.href=x);k.readyState=k.DONE;y()},r=function(a){return function(){if(k.readyState!==k.DONE)return a.apply(this,arguments)}},I={create:!0,exclusive:!1},w;k.readyState=k.INIT;c||(c="download");if(d&&(x=A(a),g.href=x,g.download=c,w=b.createEvent("MouseEvents"),w.initMouseEvent("click", 3490!0,!1,f,0,0,0,0,0,!1,!1,!1,!1,0,null),g.dispatchEvent(w))){k.readyState=k.DONE;y();return}f.chrome&&(u&&"application/octet-stream"!==u)&&(w=a.slice||a.webkitSlice,a=w.call(a,0,a.size,"application/octet-stream"),n=!0);e&&"download"!==c&&(c+=".download");z="application/octet-stream"===u||e?f:f.open();h?(p+=a.size,h(f.TEMPORARY,p,r(function(b){b.root.getDirectory("saved",I,r(function(b){var d=function(){b.getFile(c,I,r(function(c){c.createWriter(r(function(b){b.onwriteend=function(a){z.location.href= 3491c.toURL();j.push(c);k.readyState=k.DONE;m(k,"writeend",a)};b.onerror=function(){var a=b.error;a.code!==a.ABORT_ERR&&s()};["writestart","progress","write","abort"].forEach(function(a){b["on"+a]=k["on"+a]});b.write(a);k.abort=function(){b.abort();k.readyState=k.DONE};k.readyState=k.WRITING}),s)}),s)};b.getFile(c,{create:!1},r(function(a){a.remove();d()}),r(function(a){a.code===a.NOT_FOUND_ERR?d():s()}))}),s)}),s)):s()},c=u.prototype;c.abort=function(){this.readyState=this.DONE;m(this,"abort")};c.readyState= 3492c.INIT=0;c.WRITING=1;c.DONE=2;c.error=c.onwritestart=c.onprogress=c.onwrite=c.onabort=c.onerror=c.onwriteend=null;f.addEventListener("unload",function(){for(var a=j.length;a--;){var c=j[a];"string"===typeof c?k.revokeObjectURL(c):c.remove()}j.length=0},!1);return function(a,c){return new u(a,c)}}(self),MAX_BITS=15,D_CODES=30,BL_CODES=19,LENGTH_CODES=29,LITERALS=256,L_CODES=LITERALS+1+LENGTH_CODES,HEAP_SIZE=2*L_CODES+1,END_BLOCK=256,MAX_BL_BITS=7,REP_3_6=16,REPZ_3_10=17,REPZ_11_138=18,Buf_size=16, 3493Z_DEFAULT_COMPRESSION=-1,Z_FILTERED=1,Z_HUFFMAN_ONLY=2,Z_DEFAULT_STRATEGY=0,Z_NO_FLUSH=0,Z_PARTIAL_FLUSH=1,Z_FULL_FLUSH=3,Z_FINISH=4,Z_OK=0,Z_STREAM_END=1,Z_NEED_DICT=2,Z_STREAM_ERROR=-2,Z_DATA_ERROR=-3,Z_BUF_ERROR=-5,_dist_code=[0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13, 349413,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,0,0,16,17,18,18,19,19,20,20,20,20,21, 349521,21,21,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, 349628,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29]; 3497function Tree(){var f=this;f.build_tree=function(b){var k=f.dyn_tree,g=f.stat_desc.static_tree,d=f.stat_desc.elems,e,h=-1,a;b.heap_len=0;b.heap_max=HEAP_SIZE;for(e=0;e<d;e++)0!==k[2*e]?(b.heap[++b.heap_len]=h=e,b.depth[e]=0):k[2*e+1]=0;for(;2>b.heap_len;)a=b.heap[++b.heap_len]=2>h?++h:0,k[2*a]=1,b.depth[a]=0,b.opt_len--,g&&(b.static_len-=g[2*a+1]);f.max_code=h;for(e=Math.floor(b.heap_len/2);1<=e;e--)b.pqdownheap(k,e);a=d;do e=b.heap[1],b.heap[1]=b.heap[b.heap_len--],b.pqdownheap(k,1),g=b.heap[1],
3498b.heap[--b.heap_max]=e,b.heap[--b.heap_max]=g,k[2*a]=k[2*e]+k[2*g],b.depth[a]=Math.max(b.depth[e],b.depth[g])+1,k[2*e+1]=k[2*g+1]=a,b.heap[1]=a++,b.pqdownheap(k,1);while(2<=b.heap_len);b.heap[--b.heap_max]=b.heap[1];e=f.dyn_tree;for(var h=f.stat_desc.static_tree,p=f.stat_desc.extra_bits,j=f.stat_desc.extra_base,m=f.stat_desc.max_length,u,c,q=0,d=0;d<=MAX_BITS;d++)b.bl_count[d]=0;e[2*b.heap[b.heap_max]+1]=0;for(a=b.heap_max+1;a<HEAP_SIZE;a++)g=b.heap[a],d=e[2*e[2*g+1]+1]+1,d>m&&(d=m,q++),e[2*g+1]= 3499d,g>f.max_code||(b.bl_count[d]++,u=0,g>=j&&(u=p[g-j]),c=e[2*g],b.opt_len+=c*(d+u),h&&(b.static_len+=c*(h[2*g+1]+u)));if(0!==q){do{for(d=m-1;0===b.bl_count[d];)d--;b.bl_count[d]--;b.bl_count[d+1]+=2;b.bl_count[m]--;q-=2}while(0<q);for(d=m;0!==d;d--)for(g=b.bl_count[d];0!==g;)h=b.heap[--a],h>f.max_code||(e[2*h+1]!=d&&(b.opt_len+=(d-e[2*h+1])*e[2*h],e[2*h+1]=d),g--)}e=f.max_code;a=b.bl_count;b=[];g=0;for(d=1;d<=MAX_BITS;d++)b[d]=g=g+a[d-1]<<1;for(a=0;a<=e;a++)if(p=k[2*a+1],0!==p){g=k;d=2*a;h=b[p]++; 3500j=0;do j|=h&1,h>>>=1,j<<=1;while(0<--p);g[d]=j>>>1}}} 3501Tree._length_code=[0,1,2,3,4,5,6,7,8,8,9,9,10,10,11,11,12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25, 350225,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28];Tree.base_length=[0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224,0];Tree.base_dist=[0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576]; 3503Tree.d_code=function(f){return 256>f?_dist_code[f]:_dist_code[256+(f>>>7)]};Tree.extra_lbits=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0];Tree.extra_dbits=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13];Tree.extra_blbits=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7];Tree.bl_order=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];function StaticTree(f,b,k,g,d){this.static_tree=f;this.extra_bits=b;this.extra_base=k;this.elems=g;this.max_length=d} 3504StaticTree.static_ltree=[12,8,140,8,76,8,204,8,44,8,172,8,108,8,236,8,28,8,156,8,92,8,220,8,60,8,188,8,124,8,252,8,2,8,130,8,66,8,194,8,34,8,162,8,98,8,226,8,18,8,146,8,82,8,210,8,50,8,178,8,114,8,242,8,10,8,138,8,74,8,202,8,42,8,170,8,106,8,234,8,26,8,154,8,90,8,218,8,58,8,186,8,122,8,250,8,6,8,134,8,70,8,198,8,38,8,166,8,102,8,230,8,22,8,150,8,86,8,214,8,54,8,182,8,118,8,246,8,14,8,142,8,78,8,206,8,46,8,174,8,110,8,238,8,30,8,158,8,94,8,222,8,62,8,190,8,126,8,254,8,1,8,129,8,65,8,193,8,33,8,161, 35058,97,8,225,8,17,8,145,8,81,8,209,8,49,8,177,8,113,8,241,8,9,8,137,8,73,8,201,8,41,8,169,8,105,8,233,8,25,8,153,8,89,8,217,8,57,8,185,8,121,8,249,8,5,8,133,8,69,8,197,8,37,8,165,8,101,8,229,8,21,8,149,8,85,8,213,8,53,8,181,8,117,8,245,8,13,8,141,8,77,8,205,8,45,8,173,8,109,8,237,8,29,8,157,8,93,8,221,8,61,8,189,8,125,8,253,8,19,9,275,9,147,9,403,9,83,9,339,9,211,9,467,9,51,9,307,9,179,9,435,9,115,9,371,9,243,9,499,9,11,9,267,9,139,9,395,9,75,9,331,9,203,9,459,9,43,9,299,9,171,9,427,9,107,9,363,9,235, 35069,491,9,27,9,283,9,155,9,411,9,91,9,347,9,219,9,475,9,59,9,315,9,187,9,443,9,123,9,379,9,251,9,507,9,7,9,263,9,135,9,391,9,71,9,327,9,199,9,455,9,39,9,295,9,167,9,423,9,103,9,359,9,231,9,487,9,23,9,279,9,151,9,407,9,87,9,343,9,215,9,471,9,55,9,311,9,183,9,439,9,119,9,375,9,247,9,503,9,15,9,271,9,143,9,399,9,79,9,335,9,207,9,463,9,47,9,303,9,175,9,431,9,111,9,367,9,239,9,495,9,31,9,287,9,159,9,415,9,95,9,351,9,223,9,479,9,63,9,319,9,191,9,447,9,127,9,383,9,255,9,511,9,0,7,64,7,32,7,96,7,16,7,80,7, 350748,7,112,7,8,7,72,7,40,7,104,7,24,7,88,7,56,7,120,7,4,7,68,7,36,7,100,7,20,7,84,7,52,7,116,7,3,8,131,8,67,8,195,8,35,8,163,8,99,8,227,8];StaticTree.static_dtree=[0,5,16,5,8,5,24,5,4,5,20,5,12,5,28,5,2,5,18,5,10,5,26,5,6,5,22,5,14,5,30,5,1,5,17,5,9,5,25,5,5,5,21,5,13,5,29,5,3,5,19,5,11,5,27,5,7,5,23,5];StaticTree.static_l_desc=new StaticTree(StaticTree.static_ltree,Tree.extra_lbits,LITERALS+1,L_CODES,MAX_BITS); 3508StaticTree.static_d_desc=new StaticTree(StaticTree.static_dtree,Tree.extra_dbits,0,D_CODES,MAX_BITS);StaticTree.static_bl_desc=new StaticTree(null,Tree.extra_blbits,0,BL_CODES,MAX_BL_BITS);var MAX_MEM_LEVEL=9,DEF_MEM_LEVEL=8;function Config(f,b,k,g,d){this.good_length=f;this.max_lazy=b;this.nice_length=k;this.max_chain=g;this.func=d} 3509var STORED=0,FAST=1,SLOW=2,config_table=[new Config(0,0,0,0,STORED),new Config(4,4,8,4,FAST),new Config(4,5,16,8,FAST),new Config(4,6,32,32,FAST),new Config(4,4,16,16,SLOW),new Config(8,16,32,32,SLOW),new Config(8,16,128,128,SLOW),new Config(8,32,128,256,SLOW),new Config(32,128,258,1024,SLOW),new Config(32,258,258,4096,SLOW)],z_errmsg="need dictionary;stream end;;;stream error;data error;;buffer error;;".split(";"),NeedMore=0,BlockDone=1,FinishStarted=2,FinishDone=3,PRESET_DICT=32,INIT_STATE=42,BUSY_STATE= 3510113,FINISH_STATE=666,Z_DEFLATED=8,STORED_BLOCK=0,STATIC_TREES=1,DYN_TREES=2,MIN_MATCH=3,MAX_MATCH=258,MIN_LOOKAHEAD=MAX_MATCH+MIN_MATCH+1;function smaller(f,b,k,g){var d=f[2*b];f=f[2*k];return d<f||d==f&&g[b]<=g[k]} 3511function Deflate(){function f(){var a;for(a=0;a<L_CODES;a++)U[2*a]=0;for(a=0;a<D_CODES;a++)X[2*a]=0;for(a=0;a<BL_CODES;a++)O[2*a]=0;U[2*END_BLOCK]=1;S=la=n.opt_len=n.static_len=0}function b(a,c){var b,d=-1,e,f=a[1],h=0,g=7,j=4;0===f&&(g=138,j=3);a[2*(c+1)+1]=65535;for(b=0;b<=c;b++)e=f,f=a[2*(b+1)+1],++h<g&&e==f||(h<j?O[2*e]+=h:0!==e?(e!=d&&O[2*e]++,O[2*REP_3_6]++):10>=h?O[2*REPZ_3_10]++:O[2*REPZ_11_138]++,h=0,d=e,0===f?(g=138,j=3):e==f?(g=6,j=3):(g=7,j=4))}function k(a){n.pending_buf[n.pending++]= 3512a}
3512function g(a){k(a&255);k(a>>>8&255)}function d(a,c){L>Buf_size-c?(P|=a<<L&65535,g(P),P=a>>>Buf_size-L,L+=c-Buf_size):(P|=a<<L&65535,L+=c)}function e(a,c){var b=2*a;d(c[b]&65535,c[b+1]&65535)}function h(a,c){var b,f=-1,h,g=a[1],j=0,k=7,l=4;0===g&&(k=138,l=3);for(b=0;b<=c;b++)if(h=g,g=a[2*(b+1)+1],!(++j<k&&h==g)){if(j<l){do e(h,O);while(0!==--j)}else 0!==h?(h!=f&&(e(h,O),j--),e(REP_3_6,O),d(j-3,2)):10>=j?(e(REPZ_3_10,O),d(j-3,3)):(e(REPZ_11_138,O),d(j-11,7));j=0;f=h;0===g?(k=138,l=3):h==g?(k=6,l= 35133):(k=7,l=4)}}function a(){16==L?(g(P),L=P=0):8<=L&&(k(P&255),P>>>=8,L-=8)}function p(a,c){var b,d,e;n.pending_buf[fa+2*S]=a>>>8&255;n.pending_buf[fa+2*S+1]=a&255;n.pending_buf[ka+S]=c&255;S++;0===a?U[2*c]++:(la++,a--,U[2*(Tree._length_code[c]+LITERALS+1)]++,X[2*Tree.d_code(a)]++);if(0===(S&8191)&&2<M){b=8*S;d=t-Q;for(e=0;e<D_CODES;e++)b+=X[2*e]*(5+Tree.extra_dbits[e]);if(la<Math.floor(S/2)&&b>>>3<Math.floor(d/2))return!0}return S==ba-1}function j(a,c){var b,f,h=0,g,j;if(0!==S){do b=n.pending_buf[fa+ 35142*h]<<8&65280|n.pending_buf[fa+2*h+1]&255,f=n.pending_buf[ka+h]&255,h++,0===b?e(f,a):(g=Tree._length_code[f],e(g+LITERALS+1,a),j=Tree.extra_lbits[g],0!==j&&(f-=Tree.base_length[g],d(f,j)),b--,g=Tree.d_code(b),e(g,c),j=Tree.extra_dbits[g],0!==j&&(b-=Tree.base_dist[g],d(b,j)));while(h<S)}e(END_BLOCK,a);ga=a[2*END_BLOCK+1]}function m(){8<L?g(P):0<L&&k(P&255);L=P=0}function u(a,c,b){d((STORED_BLOCK<<1)+(b?1:0),3);m();ga=8;g(c);g(~c);n.pending_buf.set(w.subarray(a,a+c),n.pending);n.pending+=c}function c(a){var c= 35150<=Q?Q:-1,e=t-Q,g,k,l=0;if(0<M){da.build_tree(n);ea.build_tree(n);b(U,da.max_code);b(X,ea.max_code);ja.build_tree(n);for(l=BL_CODES-1;3<=l&&0===O[2*Tree.bl_order[l]+1];l--);n.opt_len+=3*(l+1)+14;g=n.opt_len+3+7>>>3;k=n.static_len+3+7>>>3;k<=g&&(g=k)}else g=k=e+5;if(e+4<=g&&-1!=c)u(c,e,a);else if(k==g)d((STATIC_TREES<<1)+(a?1:0),3),j(StaticTree.static_ltree,StaticTree.static_dtree);else{d((DYN_TREES<<1)+(a?1:0),3);c=da.max_code+1;e=ea.max_code+1;l+=1;d(c-257,5);d(e-1,5);d(l-4,4);for(g=0;g<l;g++)d(O[2* 3516Tree.bl_order[g]+1],3);h(U,c-1);h(X,e-1);j(U,X)}f();a&&m();Q=t;x.flush_pending()}function q(){var a,c,b,d;do{d=aa-E-t;if(0===d&&0===t&&0===E)d=s;else if(-1==d)d--;else if(t>=s+s-MIN_LOOKAHEAD){w.set(w.subarray(s,s+s),0);W-=s;t-=s;Q-=s;b=a=v;do c=G[--b]&65535,G[b]=c>=s?c-s:0;while(0!==--a);b=a=s;do c=D[--b]&65535,D[b]=c>=s?c-s:0;while(0!==--a);d+=s}if(0===x.avail_in)break;a=x.read_buf(w,t+E,d);E+=a;E>=MIN_MATCH&&(B=w[t]&255,B=(B<<N^w[t+1]&255)&l)}while(E<MIN_LOOKAHEAD&&0!==x.avail_in)}function C(a){var b= 351765535,d;for(b>A-5&&(b=A-5);;){if(1>=E){q();if(0===E&&a==Z_NO_FLUSH)return NeedMore;if(0===E)break}t+=E;E=0;d=Q+b;if(0===t||t>=d)if(E=t-d,t=d,c(!1),0===x.avail_out)return NeedMore;if(t-Q>=s-MIN_LOOKAHEAD&&(c(!1),0===x.avail_out))return NeedMore}c(a==Z_FINISH);return 0===x.avail_out?a==Z_FINISH?FinishStarted:NeedMore:a==Z_FINISH?FinishDone:BlockDone}function F(a){var c=Y,b=t,d,e=K,g=t>s-MIN_LOOKAHEAD?t-(s-MIN_LOOKAHEAD):0,f=ia,h=I,j=t+MAX_MATCH,k=w[b+e-1],l=w[b+e];K>=ha&&(c>>=2);f>E&&(f=E);do if(d= 3518a,!(w[d+e]!=l||w[d+e-1]!=k||w[d]!=w[b]||w[++d]!=w[b+1])){b+=2;d++;do;while(w[++b]==w[++d]&&w[++b]==w[++d]&&w[++b]==w[++d]&&w[++b]==w[++d]&&w[++b]==w[++d]&&w[++b]==w[++d]&&w[++b]==w[++d]&&w[++b]==w[++d]&&b<j);d=MAX_MATCH-(j-b);b=j-MAX_MATCH;if(d>e){W=a;e=d;if(d>=f)break;k=w[b+e-1];l=w[b+e]}}while((a=D[a&h]&65535)>g&&0!==--c);return e<=E?e:E}function H(a){for(var b=0,d,e;;){if(E<MIN_LOOKAHEAD){q();if(E<MIN_LOOKAHEAD&&a==Z_NO_FLUSH)return NeedMore;if(0===E)break}E>=MIN_MATCH&&(B=(B<<N^w[t+(MIN_MATCH- 35191)]&255)&l,b=G[B]&65535,D[t&I]=G[B],G[B]=t);K=J;ca=W;J=MIN_MATCH-1;if(0!==b&&(K<Z&&(t-b&65535)<=s-MIN_LOOKAHEAD)&&(T!=Z_HUFFMAN_ONLY&&(J=F(b)),5>=J&&(T==Z_FILTERED||J==MIN_MATCH&&4096<t-W)))J=MIN_MATCH-1;if(K>=MIN_MATCH&&J<=K){e=t+E-MIN_MATCH;d=p(t-1-ca,K-MIN_MATCH);E-=K-1;K-=2;do++t<=e&&(B=(B<<N^w[t+(MIN_MATCH-1)]&255)&l,b=G[B]&65535,D[t&I]=G[B],G[B]=t);while(0!==--K);R=0;J=MIN_MATCH-1;t++;if(d&&(c(!1),0===x.avail_out))return NeedMore}else if(0!==R){if((d=p(0,w[t-1]&255))&&c(!1),t++,E--,0===x.avail_out)return NeedMore}else R= 35201,t++,E--}0!==R&&(p(0,w[t-1]&255),R=0);c(a==Z_FINISH);return 0===x.avail_out?a==Z_FINISH?FinishStarted:NeedMore:a==Z_FINISH?FinishDone:BlockDone}var n=this,x,z,A,y,s,r,I,w,aa,D,G,B,v,V,l,N,Q,J,ca,R,t,W,E,K,Y,Z,M,T,ha,ia,U,X,O,da=new Tree,ea=new Tree,ja=new Tree;n.depth=[];var ka,ba,S,fa,la,ga,P,L;n.bl_count=[];n.heap=[];U=[];X=[];O=[];n.pqdownheap=function(a,b){for(var c=n.heap,d=c[b],e=b<<1;e<=n.heap_len;){e<n.heap_len&&smaller(a,c[e+1],c[e],n.depth)&&e++;if(smaller(a,d,c[e],n.depth))break;c[b]= 3521c[e];b=e;e<<=1}c[b]=d};n.deflateInit=function(a,b,c,d,e,g){d||(d=Z_DEFLATED);e||(e=DEF_MEM_LEVEL);g||(g=Z_DEFAULT_STRATEGY);a.msg=null;b==Z_DEFAULT_COMPRESSION&&(b=6);if(1>e||e>MAX_MEM_LEVEL||d!=Z_DEFLATED||9>c||15<c||0>b||9<b||0>g||g>Z_HUFFMAN_ONLY)return Z_STREAM_ERROR;a.dstate=n;r=c;s=1<<r;I=s-1;V=e+7;v=1<<V;l=v-1;N=Math.floor((V+MIN_MATCH-1)/MIN_MATCH);w=new Uint8Array(2*s);D=[];G=[];ba=1<<e+6;n.pending_buf=new Uint8Array(4*ba);A=4*ba;fa=Math.floor(ba/2);ka=3*ba;M=b;T=g;a.total_in=a.total_out= 35220;a.msg=null;n.pending=0;n.pending_out=0;z=BUSY_STATE;y=Z_NO_FLUSH;da.dyn_tree=U;da.stat_desc=StaticTree.static_l_desc;ea.dyn_tree=X;ea.stat_desc=StaticTree.static_d_desc;ja.dyn_tree=O;ja.stat_desc=StaticTree.static_bl_desc;L=P=0;ga=8;f();aa=2*s;for(a=G[v-1]=0;a<v-1;a++)G[a]=0;Z=config_table[M].max_lazy;ha=config_table[M].good_length;ia=config_table[M].nice_length;Y=config_table[M].max_chain;E=Q=t=0;J=K=MIN_MATCH-1;B=R=0;return Z_OK};n.deflateEnd=function(){if(z!=INIT_STATE&&z!=BUSY_STATE&&z!=FINISH_STATE)return Z_STREAM_ERROR; 3523w=D=G=n.pending_buf=null;n.dstate=null;return z==BUSY_STATE?Z_DATA_ERROR:Z_OK};n.deflateParams=function(a,b,c){var d=Z_OK;b==Z_DEFAULT_COMPRESSION&&(b=6);if(0>b||9<b||0>c||c>Z_HUFFMAN_ONLY)return Z_STREAM_ERROR;config_table[M].func!=config_table[b].func&&0!==a.total_in&&(d=a.deflate(Z_PARTIAL_FLUSH));M!=b&&(M=b,Z=config_table[M].max_lazy,ha=config_table[M].good_length,ia=config_table[M].nice_length,Y=config_table[M].max_chain);T=c;return d};n.deflateSetDictionary=function(a,b,c){a=c;var d=0;if(!b|| 3524z!=INIT_STATE)return Z_STREAM_ERROR;if(a<MIN_MATCH)return Z_OK;a>s-MIN_LOOKAHEAD&&(a=s-MIN_LOOKAHEAD,d=c-a);w.set(b.subarray(d,d+a),0);Q=t=a;B=w[0]&255;B=(B<<N^w[1]&255)&l;for(b=0;b<=a-MIN_MATCH;b++)B=(B<<N^w[b+(MIN_MATCH-1)]&255)&l,D[b&I]=G[B],G[B]=b;return Z_OK};n.deflate=function(b,g){var f,h,j;if(g>Z_FINISH||0>g)return Z_STREAM_ERROR;if(!b.next_out||!b.next_in&&0!==b.avail_in||z==FINISH_STATE&&g!=Z_FINISH)return b.msg=z_errmsg[Z_NEED_DICT-Z_STREAM_ERROR],Z_STREAM_ERROR;if(0===b.avail_out)return b.msg=
3525z_errmsg[Z_NEED_DICT-Z_BUF_ERROR],Z_BUF_ERROR;x=b;f=y;y=g;z==INIT_STATE&&(h=Z_DEFLATED+(r-8<<4)<<8,j=(M-1&255)>>1,3<j&&(j=3),h|=j<<6,0!==t&&(h|=PRESET_DICT),z=BUSY_STATE,h+=31-h%31,k(h>>8&255),k(h&255));if(0!==n.pending){if(x.flush_pending(),0===x.avail_out)return y=-1,Z_OK}else if(0===x.avail_in&&g<=f&&g!=Z_FINISH)return x.msg=z_errmsg[Z_NEED_DICT-Z_BUF_ERROR],Z_BUF_ERROR;if(z==FINISH_STATE&&0!==x.avail_in)return b.msg=z_errmsg[Z_NEED_DICT-Z_BUF_ERROR],Z_BUF_ERROR;if(0!==x.avail_in||0!==E||g!=Z_NO_FLUSH&& 3526z!=FINISH_STATE){f=-1;switch(config_table[M].func){case STORED:f=C(g);break;case FAST:a:{for(f=0;;){if(E<MIN_LOOKAHEAD){q();if(E<MIN_LOOKAHEAD&&g==Z_NO_FLUSH){f=NeedMore;break a}if(0===E)break}E>=MIN_MATCH&&(B=(B<<N^w[t+(MIN_MATCH-1)]&255)&l,f=G[B]&65535,D[t&I]=G[B],G[B]=t);0!==f&&(t-f&65535)<=s-MIN_LOOKAHEAD&&T!=Z_HUFFMAN_ONLY&&(J=F(f));if(J>=MIN_MATCH)if(h=p(t-W,J-MIN_MATCH),E-=J,J<=Z&&E>=MIN_MATCH){J--;do t++,B=(B<<N^w[t+(MIN_MATCH-1)]&255)&l,f=G[B]&65535,D[t&I]=G[B],G[B]=t;while(0!==--J);t++}else t+= 3527J,J=0,B=w[t]&255,B=(B<<N^w[t+1]&255)&l;else h=p(0,w[t]&255),E--,t++;if(h&&(c(!1),0===x.avail_out)){f=NeedMore;break a}}c(g==Z_FINISH);f=0===x.avail_out?g==Z_FINISH?FinishStarted:NeedMore:g==Z_FINISH?FinishDone:BlockDone}break;case SLOW:f=H(g)}if(f==FinishStarted||f==FinishDone)z=FINISH_STATE;if(f==NeedMore||f==FinishStarted)return 0===x.avail_out&&(y=-1),Z_OK;if(f==BlockDone){if(g==Z_PARTIAL_FLUSH)d(STATIC_TREES<<1,3),e(END_BLOCK,StaticTree.static_ltree),a(),9>1+ga+10-L&&(d(STATIC_TREES<<1,3),e(END_BLOCK, 3528StaticTree.static_ltree),a()),ga=7;else if(u(0,0,!1),g==Z_FULL_FLUSH)for(f=0;f<v;f++)G[f]=0;x.flush_pending();if(0===x.avail_out)return y=-1,Z_OK}}return g!=Z_FINISH?Z_OK:Z_STREAM_END}}function ZStream(){this.total_out=this.avail_out=this.total_in=this.avail_in=this.next_out_index=this.next_in_index=0} 3529ZStream.prototype={deflateInit:function(f,b){this.dstate=new Deflate;b||(b=MAX_BITS);return this.dstate.deflateInit(this,f,b)},deflate:function(f){return!this.dstate?Z_STREAM_ERROR:this.dstate.deflate(this,f)},deflateEnd:function(){if(!this.dstate)return Z_STREAM_ERROR;var f=this.dstate.deflateEnd();this.dstate=null;return f},deflateParams:function(f,b){return!this.dstate?Z_STREAM_ERROR:this.dstate.deflateParams(this,f,b)},deflateSetDictionary:function(f,b){return!this.dstate?Z_STREAM_ERROR:this.dstate.deflateSetDictionary(this, 3530f,b)},read_buf:function(f,b,k){var g=this.avail_in;g>k&&(g=k);if(0===g)return 0;this.avail_in-=g;f.set(this.next_in.subarray(this.next_in_index,this.next_in_index+g),b);this.next_in_index+=g;this.total_in+=g;return g},flush_pending:function(){var f=this.dstate.pending;f>this.avail_out&&(f=this.avail_out);0!==f&&(this.next_out.set(this.dstate.pending_buf.subarray(this.dstate.pending_out,this.dstate.pending_out+f),this.next_out_index),this.next_out_index+=f,this.dstate.pending_out+=f,this.total_out+= 3531f,this.avail_out-=f,this.dstate.pending-=f,0===this.dstate.pending&&(this.dstate.pending_out=0))}}; 3532function Deflater(f){var b=new ZStream,k=Z_NO_FLUSH,g=new Uint8Array(512);"undefined"==typeof f&&(f=Z_DEFAULT_COMPRESSION);b.deflateInit(f);b.next_out=g;this.append=function(d,e){var f,a=[],p=0,j=0,m=0,u;if(d.length){b.next_in_index=0;b.next_in=d;b.avail_in=d.length;do{b.next_out_index=0;b.avail_out=512;f=b.deflate(k);if(f!=Z_OK)throw"deflating: "+b.msg;b.next_out_index&&(512==b.next_out_index?a.push(new Uint8Array(g)):a.push(new Uint8Array(g.subarray(0,b.next_out_index))));m+=b.next_out_index;e&& 3533(0<b.next_in_index&&b.next_in_index!=p)&&(e(b.next_in_index),p=b.next_in_index)}while(0<b.avail_in||0===b.avail_out);u=new Uint8Array(m);a.forEach(function(a){u.set(a,j);j+=a.length});return u}};this.flush=function(){var d,e=[],f=0,a=0,k;do{b.next_out_index=0;b.avail_out=512;d=b.deflate(Z_FINISH);if(d!=Z_STREAM_END&&d!=Z_OK)throw"deflating: "+b.msg;0<512-b.avail_out&&e.push(new Uint8Array(g.subarray(0,b.next_out_index)));a+=b.next_out_index}while(0<b.avail_in||0===b.avail_out);b.deflateEnd();k=new Uint8Array(a); 3534e.forEach(function(a){k.set(a,f);f+=a.length});return k}} 3535void function(f,b){"object"===typeof module?module.exports=b():"function"===typeof define?define(b):f.adler32cs=b()}(this,function(){var f="function"===typeof ArrayBuffer&&"function"===typeof Uint8Array,b=null,k;if(f){try{var g=require("buffer");"function"===typeof g.Buffer&&(b=g.Buffer)}catch(d){}k=function(a){return a instanceof ArrayBuffer||null!==b&&a instanceof b}}else k=function(){return!1};var e;e=null!==b?function(a){return(new b(a,"utf8")).toString("binary")}:function(a){return unescape(encodeURIComponent(a))};
3536var h=function(a,b){for(var d=a&65535,e=a>>>16,f=0,g=b.length;f<g;f++)d=(d+(b.charCodeAt(f)&255))%65521,e=(e+d)%65521;return(e<<16|d)>>>0},a=function(a,b){for(var d=a&65535,e=a>>>16,f=0,g=b.length;f<g;f++)d=(d+b[f])%65521,e=(e+d)%65521;return(e<<16|d)>>>0},g={},p=function(a){if(!(this instanceof p))throw new TypeError("Constructor cannot called be as a function.");if(!isFinite(a=null==a?1:+a))throw Error("First arguments needs to be a finite number.");this.checksum=a>>>0},j=p.prototype={};j.constructor= 3537p;var m=function(a){if(!(this instanceof p))throw new TypeError("Constructor cannot called be as a function.");if(null==a)throw Error("First argument needs to be a string.");this.checksum=h(1,a.toString())};m.prototype=j;p.from=m;m=function(a){if(!(this instanceof p))throw new TypeError("Constructor cannot called be as a function.");if(null==a)throw Error("First argument needs to be a string.");a=e(a.toString());this.checksum=h(1,a)};m.prototype=j;p.fromUtf8=m;f&&(m=function(b){if(!(this instanceof 3538p))throw new TypeError("Constructor cannot called be as a function.");if(!k(b))throw Error("First argument needs to be ArrayBuffer.");b=new Uint8Array(b);return this.checksum=a(1,b)},m.prototype=j,p.fromBuffer=m);j.update=function(a){if(null==a)throw Error("First argument needs to be a string.");a=a.toString();return this.checksum=h(this.checksum,a)};j.updateUtf8=function(a){if(null==a)throw Error("First argument needs to be a string.");a=e(a.toString());return this.checksum=h(this.checksum,a)};f&& 3539(j.updateBuffer=function(b){if(!k(b))throw Error("First argument needs to be ArrayBuffer.");b=new Uint8Array(b);return this.checksum=a(this.checksum,b)});j.clone=function(){return new u(this.checksum)};var u=g.Adler32=p;g.from=function(a){if(null==a)throw Error("First argument needs to be a string.");return h(1,a.toString())};g.fromUtf8=function(a){if(null==a)throw Error("First argument needs to be a string.");a=e(a.toString());return h(1,a)};f&&(g.fromBuffer=function(b){if(!k(b))throw Error("First argument need to be ArrayBuffer."); 3540b=new Uint8Array(b);return a(1,b)});return g}); 3541 3542!function(t){t.fn.liveEdit=function(e){var n,o,i,a,s,l,u=t.extend({afterSaveAll:function(){},doubleClick:function(){}},t.fn.liveEdit.defaults,e),c=[],d=function(e){t(e).attr("contenteditable","true")},r=function(e){t(e).find("a").click(function(t){t.preventDefault()})},f=function(){var t=window.getSelection(),e=t.getRangeAt(0),n=e.getBoundingClientRect();i.addClass("appear"),i.css("top",n.top-(i.height()+8)+window.pageYOffset+"px"),i.css("left",(n.left+n.right)/2-i.width()/2+"px")},h=function(){i.removeClass("appear"),i.css("top","-999px"),i.css("left","-999px")},g=function(e){t(e.focusNode).closest("b").length>0?i.addClass("bold"):i.removeClass("bold"),t(e.focusNode).closest("i").length>0?i.addClass("italic"):i.removeClass("italic"),t(e.focusNode).closest("li").length>0?i.addClass("unorderedlist"):i.removeClass("unorderedlist"),t(e.focusNode).closest("strike").length>0?i.addClass("strikethrough"):i.removeClass("strikethrough"),t(e.focusNode).closest("a").length>0?i.addClass("url"):i.removeClass("url")},b=function(){var t=document.getSelection().anchorNode,e=t&&3===t.nodeType?t.parentNode:t;return e},m=function(e){var n=window.getSelection();return y(),D(t(n.focusNode).closest("[data-editable=true]")),t(e.target).closest(".text-options").length>0?void g(n):(t(n.focusNode).closest("[data-editable=true]").length>0&&0==t(n.focusNode).closest("figure").length?(0===b().children.length&&t(n.focusNode).closest("[data-text-options=true]").length>0&&0==t(n.focusNode).closest("li").length&&0==t(n.focusNode).closest(".caption").length&&document.execCommand("formatBlock",!1,"p"),n.isCollapsed===!0&&l===!1&&h(),n.isCollapsed===!1?t(n.focusNode).closest("[data-text-options=true]").length>0&&(f(),g(n)):h()):h(),void(l=n.isCollapsed))},v=function(){document.execCommand("strong",!1,null)},C=function(){document.execCommand("italic",!1)},x=function(){document.execCommand("strikethrough",!1)},k=function(){document.execCommand("insertunorderedlist",!1),h(),E()},B=function(){i.hasClass("edit-url")?i.removeClass("edit-url"):(i.addClass("edit-url"),setTimeout(function(){var e=window.getSelection();
3542t(e.focusNode).closest("a").length>0?t(urlField).find("input").val(t(e.focusNode).closest("a").attr("href")):document.execCommand("createLink",!1,"/"),lastSelection=window.getSelection().getRangeAt(0),l=!1,t(urlField).find("input").focus()},100))},w=function(){window.getSelection().addRange(lastSelection)},L=function(t){w(),document.execCommand("unlink",!1),""!==t&&(t.match("^(http|https)://")||(t="http://"+t),document.execCommand("createLink",!1,t))},N=function(e){t(e).on("paste",function(t){if(t.preventDefault(),t.originalEvent.clipboardData&&t.originalEvent.clipboardData.getData){var n="",o=t.originalEvent.clipboardData.getData("text/plain").split(/[\r\n]/g);for(p=0;p<o.length;p+=1)""!==o[p]&&(n+="<p>"+o[p]+"</p>");document.execCommand("insertHTML",!1,n),setTimeout(function(){D(e)},10)}})},S=function(e){t(e).on("dblclick",function(){setTimeout(function(){var t=window.getSelection();return t.isCollapsed===!0?u.doubleClick.call(this,e,t):void 0},10)})},y=function(){t.each(c,function(e,n){t(n).find("[data-editable=true]").each(function(){1==t(this).data("text-options")&&t(this).find("figure").each(function(){0===t(this).next("p").length&&t(this).after("<p><br></p>")})})})},D=function(e){t(e).find("span").each(function(){t(this).hasClass("caption")||t(this).contents().unwrap()})},E=function(){t.each(c,function(e,n){t(n).find("[data-editable=true]").each(function(){t(this).find("ul").each(function(){t(this).parent("p").length&&t(this).parent("p").contents().unwrap()})})})},T=function(){var e=[];return t.each(c,function(n,o){var i={},a=t(o).data("model"),s=t(o).data("id").toString(),l=t(o).data("url");i.model=a,i.id=s,i.url=l,t(o).find("[data-editable=true]").each(function(){var e=t(this).data("name"),n=t(this).html().replace(/\n/g,"").trim();i[e]=n}),e.push(i)}),u.afterSaveAll.call(this,e)},A=function(){sidebarInterface='<div class="live-edit-sidebar" draggable="true"><a href="#" class="save-button">'+u.saveButtonLabel+"</a></div>",textOptionsInterface='<span class="text-options"><button class="url-button">'+u.urlButtonLabel+'</button><span class="input-text"><input type="text" name="liveedit-url" /></span><button class="bold-button">'+u.boldButtonLabel+'</button><button class="italic-button">'+u.italicButtonLabel+'</button><button class="strikethrough-button">'+u.strikethroughButtonLabel+'</button><button class="unorderedlist-button">'+u.unorderedlistButtonLabel+"</button></span>",t("body").append(textOptionsInterface)},F=function(){n=t(".live-edit-sidebar"),o=t(".live-edit-sidebar .save-button"),i=t(".text-options"),urlButton=t(".text-options .url-button"),urlField=t(".text-options span.input-text"),a=t(".text-options .bold-button"),s=t(".text-options .italic-button"),strikethroughButton=t(".text-options .strikethrough-button"),unorderedListButton=t(".text-options .unorderedlist-button")},I=function(){o.on("click",T),urlButton.on("click",B),a.on("click",v),s.on("click",C),strikethroughButton.on("click",x),unorderedListButton.on("click",k),t(urlField).find("input").on("keydown",function(e){13===e.keyCode&&(e.preventDefault(),L(t(this).val()),t(this).blur())}),t(urlField).find("input").on("blur",function(){i.removeClass("edit-url"),L(t(this).val()),t(this).val(""),g(window.getSelection().focusNode)}),t(document).on("keyup",m),t(document).on("mousedown",m),t(document).on("mouseup",function(t){setTimeout(function(){m(t)},1)})};A(),F(),I();var R=function(e){var n=t(e).data("max-length");n&&t(e).on("keypress",function(t){(t.target.innerText.length>n||13===t.keyCode)&&t.preventDefault()})};return t.fn.liveEdit.loadingState=function(t){"on"==t?n.addClass("loading-state"):n.removeClass("loading-state")},this.each(function(){c.push(this),t(this).find("[data-editable=true]").each(function(){d(this),r(this),R(this),N(this),S(this)})})},t.fn.liveEdit.defaults={saveButtonLabel:"S",urlButtonLabel:"U",boldButtonLabel:"B",italicButtonLabel:"I",strikethroughButtonLabel:"ABC",unorderedlistButtonLabel:"L"}}(jQuery); 3543(function(e){"use strict";function t(t){var n=e("");try{n=e(t).clone()}catch(r){n=e("<span />").html(t)}return n}function n(e){return!!(typeof Node==="object"?e instanceof Node:e&&typeof e==="object"&&typeof e.nodeType==="number"&&typeof e.nodeName==="string")}e.print=e.fn.print=function(){var r,i,s=this;if(s instanceof e){s=s.get(0)}if(n(s)){i=e(s);if(arguments.length>0){r=arguments[0]}}else{if(arguments.length>0){i=e(arguments[0]);if(n(i[0])){if(arguments.length>1){r=arguments[1]}}else{r=arguments[0];i=e("html")}}else{i=e("html")}}var o={globalStyles:true,mediaPrint:false,stylesheet:null,noPrintSelector:".no-print",iframe:true,append:null,prepe
3543nd:null};r=e.extend({},o,r||{});var u=e("");if(r.globalStyles){u=e("style, link, meta, title")}else if(r.mediaPrint){u=e("link[media=print]")}if(r.stylesheet){u=e.merge(u,e('<link rel="stylesheet" href="'+r.stylesheet+'">'))}var a=i.clone();a=e("<span/>").append(a);a.find(r.noPrintSelector).remove();a.append(u.clone());a.append(t(r.append));a.prepend(t(r.prepend));var f=a.html();a.remove();var l,c;if(r.iframe){try{var h=e(r.iframe+"");var p=h.length;if(p===0){h=e('<iframe height="0" width="0" border="0" wmode="Opaque"/>').prependTo("body").css({position:"absolute",top:-999,left:-999})}l=h.get(0);l=l.contentWindow||l.contentDocument||l;c=l.document||l.contentDocument||l;c.open();c.write(f);c.close();setTimeout(function(){l.focus();l.print();setTimeout(function(){if(p===0){h.remove()}},100)},250)}catch(d){console.error("Failed to print from iframe",d.stack,d.message);l=window.open();l.document.write(f);l.document.close();l.focus();l.print();l.close()}}else{l=window.open();l.document.write(f);l.document.close();l.focus();l.print();l.close()}return this}})(jQuery); 3544
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.