From 15ca3381eb55254da45438ad97e5d33ea3a3a5fe Mon Sep 17 00:00:00 2001 From: Niklas von Hertzen Date: Sun, 2 Mar 2014 16:00:59 +0200 Subject: [PATCH] Fix text rendering for IE and Opera --- .jshintrc | 2 +- build/html2canvas.js | 145 ++++++++++++++++----------- build/html2canvas.min.js | 4 +- src/core.js | 4 +- src/nodecontainer.js | 72 ++++++++++--- src/nodeparser.js | 59 ++++------- src/renderers/canvas.js | 4 +- src/support.js | 6 +- tests/cases/transform/nested.html | 9 +- tests/cases/transform/translate.html | 45 +++++++++ 10 files changed, 225 insertions(+), 125 deletions(-) create mode 100644 tests/cases/transform/translate.html diff --git a/.jshintrc b/.jshintrc index 04ec9e6..493331c 100644 --- a/.jshintrc +++ b/.jshintrc @@ -13,6 +13,6 @@ "globals": { "jQuery": true }, - "predef": ["NodeParser", "NodeContainer", "StackingContext", "TextContainer", "ImageLoader", "CanvasRenderer", "Renderer", "Support", "bind", "Promise", + "predef": ["NodeParser", "NodeContainer", "StackingContext", "TextContainer", "ImageLoader", "CanvasRenderer", "Renderer", "Support", "bind", "Promise", "getBounds", "offsetBounds", "ImageContainer", "ProxyImageContainer", "DummyImageContainer", "Font", "FontMetrics", "GradientContainer", "LinearGradientContainer", "WebkitGradientContainer", "log", "smallImage", "parseBackgrounds"] } diff --git a/build/html2canvas.js b/build/html2canvas.js index 2d8c039..23d37d9 100644 --- a/build/html2canvas.js +++ b/build/html2canvas.js @@ -37,9 +37,9 @@ function renderDocument(document, options, windowWidth, windowHeight) { document.querySelector(selector).removeAttribute(html2canvasNodeAttribute); var clonedWindow = container.contentWindow; var node = clonedWindow.document.querySelector(selector); - var support = new Support(); + var support = new Support(clonedWindow.document); var imageLoader = new ImageLoader(options, support); - var bounds = NodeParser.prototype.getBounds(node); + var bounds = getBounds(node); var width = options.type === "view" ? Math.min(bounds.width, windowWidth) : documentWidth(); var height = options.type === "view" ? Math.min(bounds.height, windowHeight) : documentHeight(); var renderer = new CanvasRenderer(width, height, imageLoader); @@ -343,6 +343,7 @@ function NodeContainer(node, parent) { this.parent = parent; this.stack = null; this.bounds = null; + this.offsetBounds = null; this.visible = null; this.computedStyles = null; this.styles = {}; @@ -500,19 +501,28 @@ NodeContainer.prototype.parseTextShadows = function() { NodeContainer.prototype.parseTransform = function() { var transformRegExp = /(matrix)\((.+)\)/; var transform = this.prefixedCss("transform"); - if (transform !== null && transform !== "none") { - var matrix = parseMatrix(transform.match(transformRegExp)); - if (matrix) { - return { - origin: this.prefixedCss("transformOrigin"), - matrix: matrix - }; - } + var matrix = parseMatrix(transform.match(transformRegExp)); + var offset = this.parseBounds(); + if (matrix) { + var origin = this.prefixedCss("transformOrigin").split(" ").map(removePx).map(asFloat); + origin[0] += offset.left; + origin[1] += offset.top; + + return { + origin: origin, + matrix: matrix + }; } - return { - origin: [0, 0], - matrix: [1, 0, 0, 1, 0, 0] - }; +}; + +NodeContainer.prototype.parseBounds = function() { + return this.bounds || (this.bounds = this.hasTransform() ? offsetBounds(this.node) : getBounds(this.node)); +}; + + +NodeContainer.prototype.hasTransform = function() { + var transform = this.prefixedCss("transform"); + return (transform !== null && transform !== "none" && transform !== "matrix(1, 0, 0, 1, 0, 0)"); }; NodeContainer.prototype.TEXT_SHADOW_PROPERTY = /((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g; @@ -627,6 +637,44 @@ function parseBackgrounds(backgroundImage) { return results; } +function removePx(str) { + return str.replace("px", ""); +} + +function asFloat(str) { + return parseFloat(str); +} + +function getBounds(node) { + if (node.getBoundingClientRect) { + var clientRect = node.getBoundingClientRect(); + var isBody = node.nodeName === "BODY"; + var width = isBody ? node.scrollWidth : node.offsetWidth; + return { + top: clientRect.top, + bottom: clientRect.bottom || (clientRect.top + clientRect.height), + right: clientRect.left + width, + left: clientRect.left, + width: width, + height: isBody ? node.scrollHeight : node.offsetHeight + }; + } + return {}; +} + +function offsetBounds(node) { + var parent = node.offsetParent ? offsetBounds(node.offsetParent) : {top: 0, left: 0}; + + return { + top: node.offsetTop + parent.top, + bottom: node.offsetTop + node.offsetHeight + parent.top, + right: node.offsetLeft + parent.left + node.offsetWidth, + left: node.offsetLeft + parent.left, + width: node.offsetWidth, + height: node.offsetHeight + }; +} + function NodeParser(element, renderer, support, imageLoader, options) { log("Starting NodeParser"); this.renderer = renderer; @@ -763,7 +811,7 @@ NodeParser.prototype.newStackingContext = function(container, hasOwnStacking) { NodeParser.prototype.createStackingContexts = function() { this.nodes.forEach(function(container) { - if (isElement(container) && (this.isRootElement(container) || hasOpacity(container) || isPositionedForStacking(container) || this.isBodyWithTransparentRoot(container) || hasTransform(container))) { + if (isElement(container) && (this.isRootElement(container) || hasOpacity(container) || isPositionedForStacking(container) || this.isBodyWithTransparentRoot(container) || container.hasTransform())) { this.newStackingContext(container, true); } else if (isElement(container) && ((isPositioned(container) && zIndex0(container)) || isInlineBlock(container) || isFloating(container))) { this.newStackingContext(container, false); @@ -786,55 +834,33 @@ NodeParser.prototype.sortStackingContexts = function(stack) { stack.contexts.forEach(this.sortStackingContexts, this); }; -NodeParser.prototype.parseBounds = function(nodeContainer) { - return nodeContainer.bounds = this.getBounds(nodeContainer.node); -}; - -NodeParser.prototype.getBounds = function(node) { - if (node.getBoundingClientRect) { - var clientRect = node.getBoundingClientRect(); - var isBody = node.nodeName === "BODY"; - var width = isBody ? node.scrollWidth : node.offsetWidth; - return { - top: clientRect.top, - bottom: clientRect.bottom || (clientRect.top + clientRect.height), - right: clientRect.left + width, - left: clientRect.left, - width: width, - height: isBody ? node.scrollHeight : node.offsetHeight - }; - } - return {}; -}; - NodeParser.prototype.parseTextBounds = function(container) { return function(text, index, textList) { - if (container.parent.css("textDecoration") !== "none" || text.trim().length !== 0) { - if (this.support.rangeBounds) { + if (container.parent.css("textDecoration").substr(0, 4) !== "none" || text.trim().length !== 0) { + if (this.support.rangeBounds && !container.parent.hasTransform()) { var offset = textList.slice(0, index).join("").length; return this.getRangeBounds(container.node, offset, text.length); } else if (container.node && typeof(container.node.data) === "string") { var replacementNode = container.node.splitText(text.length); - var bounds = this.getWrapperBounds(container.node); + var bounds = this.getWrapperBounds(container.node, container.parent.hasTransform()); container.node = replacementNode; return bounds; } - } else if (!this.support.rangeBounds) { + } else if(!this.support.rangeBounds || container.parent.hasTransform()){ container.node = container.node.splitText(text.length); } return {}; }; }; -NodeParser.prototype.getWrapperBounds = function(node) { - var wrapper = node.ownerDocument.createElement('wrapper'); +NodeParser.prototype.getWrapperBounds = function(node, transform) { + var wrapper = node.ownerDocument.createElement('html2canvaswrapper'); var parent = node.parentNode, backupText = node.cloneNode(true); wrapper.appendChild(node.cloneNode(true)); parent.replaceChild(wrapper, node); - - var bounds = this.getBounds(wrapper); + var bounds = transform ? offsetBounds(wrapper) : getBounds(wrapper); parent.replaceChild(backupText, wrapper); return bounds; }; @@ -846,6 +872,8 @@ NodeParser.prototype.getRangeBounds = function(node, offset, length) { return range.getBoundingClientRect(); }; +function ClearTransform() {} + NodeParser.prototype.parse = function(stack) { // http://www.w3.org/TR/CSS21/visuren.html#z-index var negativeZindex = stack.contexts.filter(negativeZIndex); // 2. the child stacking contexts with negative stack levels (most negative first). @@ -862,13 +890,16 @@ NodeParser.prototype.parse = function(stack) { this.renderQueue.push(container); if (isStackingContext(container)) { this.parse(container); + this.renderQueue.push(new ClearTransform()); } }, this); }; NodeParser.prototype.paint = function(container) { try { - if (isTextNode(container)) { + if (container instanceof ClearTransform) { + this.renderer.ctx.restore(); + } else if (isTextNode(container)) { this.paintText(container); } else { this.paintNode(container); @@ -881,13 +912,12 @@ NodeParser.prototype.paint = function(container) { NodeParser.prototype.paintNode = function(container) { if (isStackingContext(container)) { this.renderer.setOpacity(container.opacity); - var transform = container.parseTransform(); - if (transform) { - this.renderer.setTransform(transform); + this.renderer.ctx.save(); + if (container.hasTransform()) { + this.renderer.setTransform(container.parseTransform()); } } - - var bounds = this.parseBounds(container); + var bounds = container.parseBounds(); var borderData = this.parseBorders(container); this.renderer.clip(borderData.clip, function() { this.renderer.renderBackground(container, bounds, borderData.borders.map(getWidth)); @@ -1254,11 +1284,6 @@ function hasOpacity(container) { return container.css("opacity") < 1; } -function hasTransform(container) { - var transform = container.prefixedCss("transform"); - return transform !== null && transform !== "none"; -} - function bind(callback, context) { return function() { return callback.apply(context, arguments); @@ -1516,8 +1541,8 @@ CanvasRenderer.prototype.setOpacity = function(opacity) { CanvasRenderer.prototype.setTransform = function(transform) { this.ctx.translate(transform.origin[0], transform.origin[1]); - this.ctx.setTransform.apply(this.ctx, transform.matrix); - this.ctx.translate(transform.origin[0], transform.origin[1]); + this.ctx.transform.apply(this.ctx, transform.matrix); + this.ctx.translate(-transform.origin[0], -transform.origin[1]); }; CanvasRenderer.prototype.setVariable = function(property, value) { @@ -1588,12 +1613,12 @@ StackingContext.prototype.getParentStack = function(context) { return parentStack ? (parentStack.ownStacking ? parentStack : parentStack.getParentStack(context)) : context.stack; }; -function Support() { - this.rangeBounds = this.testRangeBounds(); +function Support(document) { + this.rangeBounds = this.testRangeBounds(document); this.cors = this.testCORS(); } -Support.prototype.testRangeBounds = function() { +Support.prototype.testRangeBounds = function(document) { var range, testElement, rangeBounds, rangeHeight, support = false; if (document.createRange) { diff --git a/build/html2canvas.min.js b/build/html2canvas.min.js index 44ff343..f090931 100644 --- a/build/html2canvas.min.js +++ b/build/html2canvas.min.js @@ -4,5 +4,5 @@ Released under MIT License */ -(function(t,e,n){function r(t,e,n,r){return a(t,n,r,e).then(function(s){m("Document cloned");var a="["+ae+"='true']";t.querySelector(a).removeAttribute(ae);var c=s.contentWindow,h=c.document.querySelector(a),u=new re,p=new d(e,u),l=x.prototype.getBounds(h),f="view"===e.type?Math.min(l.width,n):i(),g="view"===e.type?Math.min(l.height,r):o(),y=new ee(f,g,p),v=new x(h,y,u,p,e);return v.ready.then(function(){return m("Finished rendering"),e.removeContainer&&s.parentNode.removeChild(s),y.canvas})})}function i(){return Math.max(Math.max(e.body.scrollWidth,e.documentElement.scrollWidth),Math.max(e.body.offsetWidth,e.documentElement.offsetWidth),Math.max(e.body.clientWidth,e.documentElement.clientWidth))}function o(){return Math.max(Math.max(e.body.scrollHeight,e.documentElement.scrollHeight),Math.max(e.body.offsetHeight,e.documentElement.offsetHeight),Math.max(e.body.clientHeight,e.documentElement.clientHeight))}function s(){return"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"}function a(e,n,r,i){var o=e.documentElement.cloneNode(!0),s=e.createElement("iframe");return s.style.visibility="hidden",s.style.position="absolute",s.style.left=s.style.top="-10000px",s.width=n,s.height=r,s.scrolling="no",e.body.appendChild(s),new Promise(function(e){var n=s.contentWindow.document;n.open(),n.write(""),n.close(),n.replaceChild(n.adoptNode(o),n.documentElement),"view"===i.type&&s.contentWindow.scrollTo(t.scrollX,t.scrollY),e(s)})}function c(t,n){var r,i,o=e.createElement("div"),a=e.createElement("img"),c=e.createElement("span"),h="Hidden Text";o.style.visibility="hidden",o.style.fontFamily=t,o.style.fontSize=n,o.style.margin=0,o.style.padding=0,e.body.appendChild(o),a.src=s(),a.width=1,a.height=1,a.style.margin=0,a.style.padding=0,a.style.verticalAlign="baseline",c.style.fontFamily=t,c.style.fontSize=n,c.style.margin=0,c.style.padding=0,c.appendChild(e.createTextNode(h)),o.appendChild(c),o.appendChild(a),r=a.offsetTop-c.offsetTop+1,o.removeChild(c),o.appendChild(e.createTextNode(h)),o.style.lineHeight="normal",a.style.verticalAlign="super",i=a.offsetTop-o.offsetTop+1,e.body.removeChild(o),this.baseline=r,this.lineWidth=1,this.middle=i}function h(){this.data={}}function u(t){this.src=t.value,this.colorStops=[],this.type=null,this.x0=.5,this.y0=.5,this.x1=.5,this.y1=.5,this.promise=Promise.resolve(!0)}function p(t,e){this.src=t,this.image=new Image;var n=this.image;this.promise=new Promise(function(r,i){n.onload=r,n.onerror=i,e&&(n.crossOrigin="anonymous"),n.src=t,n.complete===!0&&r(n)})}function d(e,n){this.link=null,this.options=e,this.support=n,this.origin=t.location.protocol+t.location.host}function l(t){return"IMG"===t.node.nodeName}function f(t){return{args:[t.node.src],method:"url"}}function g(t){u.apply(this,arguments),this.type=this.TYPES.LINEAR,t.args[0].split(" ").forEach(function(t){switch(t){case"left":this.x0=0,this.x1=1;break;case"top":this.y0=0,this.y1=1;break;case"right":this.x0=1,this.x1=0;break;case"bottom":this.y0=1,this.y1=0}},this),t.args.slice(1).forEach(function(){},this)}function m(){t.html2canvas.logging&&t.console&&t.console.log&&t.console.log.apply(t.console,[Date.now()-t.html2canvas.start+"ms","html2canvas:"].concat([].slice.call(arguments,0)))}function y(t,e){this.node=t,this.parent=e,this.stack=null,this.bounds=null,this.visible=null,this.computedStyles=null,this.styles={},this.backgroundImages=null}function v(t){return t&&"matrix"===t[1]?t[2].split(",").map(function(t){return parseFloat(t.trim())}):n}function b(t){return-1!==(""+t).indexOf("%")}function w(t){var e,r,i,o,s,a,c,h=" \r\n ",u=[],p=0,d=0,l=function(){e&&('"'===r.substr(0,1)&&(r=r.substr(1,r.length-2)),r&&c.push(r),"-"===e.substr(0,1)&&(o=e.indexOf("-",1)+1)>0&&(i=e.substr(0,o),e=e.substr(o)),u.push({prefix:i,method:e.toLowerCase(),value:s,args:c,image:null})),c=[],e=i=r=s=""};return c=[],e=i=r=s="",t.split("").forEach(function(t){if(!(0===p&&h.indexOf(t)>-1)){switch(t){case'"':a?a===t&&(a=null):a=t;break;case"(":if(a)break;if(0===p)return p=1,s+=t,n;d++;break;case")":if(a)break;if(1===p){if(0===d)return p=0,s+=t,l(),n;d--}break;case",":if(a)break;if(0===p)return l(),n;if(1===p&&0===d&&!e.match(/^url$/i))return c.push(r),r="",s+=t,n}s+=t,0===p?e+=t:r+=t}}),l(),u}function x(t,e,n,r,i){m("Starting NodeParser"),this.renderer=e,this.options=i,this.range=null,this.support=n,this.renderQueue=[],this.stack=new ne(!0,1,t.ownerDocument,null);var o=new y(t,null);o.visibile=o.isElementVisible(),this.createPseudoHideStyles(t.ownerDocument),this.nodes=J([o].concat(this.getChildren(o)).filter(function(t){return t.visible=t.isElementVisible()}).map(this.getPseudoElements,this)),this.fontMetrics=new h,m("Fetched nodes"),this.images=r.fetch(this.nodes.filter(z)),m("Creating stacking contexts"),this.createStackingContexts(),m("Sorting stacking contexts"),this.sortStackingContexts(this.stack),this.ready=this.images.ready.then(Q(function(){return m("Images loaded, starting parsing"),this.parse(this.stack),m("Render queue created with "+this.renderQueue.length+" items"),new Promise(Q(function(t){i.async?"function"==typeof i.async?i.async.call(this,this.renderQueue,t):(this.renderIndex=0,this.asyncRenderer(this.renderQueue,t)):(this.renderQueue.forEach(this.paint,this),t())},this))},this))}function k(t){return t.replace(/(\-[a-z])/g,function(t){return t.toUpperCase().replace("-","")})}function E(t,e,n,r){var i=4*((Math.sqrt(2)-1)/3),o=n*i,s=r*i,a=t+n,c=e+r;return{topLeft:I({x:t,y:c},{x:t,y:c-s},{x:a-o,y:e},{x:a,y:e}),topRight:I({x:t,y:e},{x:t+o,y:e},{x:a,y:c-s},{x:a,y:c}),bottomRight:I({x:a,y:e},{x:a,y:e+s},{x:t+o,y:c},{x:t,y:c}),bottomLeft:I({x:a,y:c},{x:a-o,y:c},{x:t,y:e+s},{x:t,y:e})}}function T(t,e,n){var r=t.left,i=t.top,o=t.width,s=t.height,a=e[0][0],c=e[0][1],h=e[1][0],u=e[1][1],p=e[2][0],d=e[2][1],l=e[3][0],f=e[3][1],g=o-h,m=s-d,y=o-p,v=s-f;return{topLeftOuter:E(r,i,a,c).topLeft.subdivide(.5),topLeftInner:E(r+n[3].width,i+n[0].width,Math.max(0,a-n[3].width),Math.max(0,c-n[0].width)).topLeft.subdivide(.5),topRightOuter:E(r+g,i,h,u).topRight.subdivide(.5),topRightInner:E(r+Math.min(g,o+n[3].width),i+n[0].width,g>o+n[3].width?0:h-n[3].width,u-n[0].width).topRight.subdivide(.5),bottomRightOuter:E(r+y,i+m,p,d).bottomRight.subdivide(.5),bottomRightInner:E(r+Math.min(y,o+n[3].width),i+Math.min(m,s+n[0].width),Math.max(0,p-n[1].width),Math.max(0,d-n[2].width)).bottomRight.subdivide(.5),bottomLeftOuter:E(r,i+v,l,f).bottomLeft.subdivide(.5),bottomLeftInner:E(r+n[3].width,i+v,Math.max(0,l-n[3].width),Math.max(0,f-n[2].width)).bottomLeft.subdivide(.5)}}function I(t,e,n,r){var i=function(t,e,n){return{x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n}};return{start:t,startControl:e,endControl:n,end:r,subdivide:function(o){var s=i(t,e,o),a=i(e,n,o),c=i(n,r,o),h=i(s,a,o),u=i(a,c,o),p=i(h,u,o);return[I(t,s,h,p),I(p,u,c,r)]},curveTo:function(t){t.push(["bezierCurve",e.x,e.y,n.x,n.y,r.x,r.y])},curveToReversed:function(r){r.push(["bezierCurve",n.x,n.y,e.x,e.y,t.x,t.y])}}}function R(t,e,n,r,i,o,s){var a=[];return e[0]>0||e[1]>0?(a.push(["line",r[1].start.x,r[1].start.y]),r[1].curveTo(a)):a.push(["line",t.c1[0],t.c1[1]]),n[0]>0||n[1]>0?(a.push(["line",o[0].start.x,o[0].start.y]),o[0].curveTo(a),a.push(["line",s[0].end.x,s[0].end.y]),s[0].curveToReversed(a)):(a.push(["line",t.c2[0],t.c2[1]]),a.push(["line",t.c3[0],t.c3[1]])),e[0]>0||e[1]>0?(a.push(["line",i[1].end.x,i[1].end.y]),i[1].curveToReversed(a)):a.push(["line",t.c4[0],t.c4[1]]),a}function C(t,e,n,r,i,o,s){e[0]>0||e[1]>0?(t.push(["line",r[0].start.x,r[0].start.y]),r[0].curveTo(t),r[1].curveTo(t)):t.push(["line",o,s]),(n[0]>0||n[1]>0)&&t.push(["line",i[0].start.x,i[0].start.y])}function S(t){return 0>t.cssInt("zIndex")}function B(t){return t.cssInt("zIndex")>0}function O(t){return 0===t.cssInt("zIndex")}function A(t){return-1!==["inline","inline-block","inline-table"].indexOf(t.css("display"))}function N(t){return t instanceof ne}function L(t){return t.node.data.trim().length>0}function P(t){return/^(normal|none|0px)$/.test(t.parent.css("letterSpacing"))}function M(t){return["TopLeft","TopRight","BottomRight","BottomLeft"].map(function(e){var n=t.css("border"+e+"Radius"),r=n.split(" ");return 1>=r.length&&(r[1]=r[0]),r.map(G)})}function _(t){return t.nodeType===Node.TEXT_NODE||t.nodeType===Node.ELEMENT_NODE}function D(t){var e=t.css("position"),n="absolute"===e||"relative"===e?t.css("zIndex"):"auto";return"auto"!==n}function W(t){return"static"!==t.css("position")}function F(t){return"none"!==t.css("float")}function H(t){return-1!==["inline-block","inline-table"].indexOf(t.css("display"))}function j(t){var e=this;return function(){return!t.apply(e,arguments)}}function z(t){return t.node.nodeType===Node.ELEMENT_NODE}function Y(t){return t.node.nodeType===Node.TEXT_NODE}function V(t,e){return t.cssInt("zIndex")-e.cssInt("zIndex")}function X(t){return 1>t.css("opacity")}function U(t){var e=t.prefixedCss("transform");return null!==e&&"none"!==e}function Q(t,e){return function(){return t.apply(e,arguments)}}function G(t){return parseInt(t,10)}function q(t){return t.width}function $(t){return t.node.nodeType!==Node.ELEMENT_NODE||-1===["SCRIPT","HEAD","TITLE","OBJECT","BR"].indexOf(t.node.nodeName)}function J(t){return[].concat.apply([],t)}function K(t){var e=t.substr(0,1);return e===t.substr(t.length-1)&&e.match(/'|"/)?t.substr(1,t.length-2):t}function Z(r,i){var o="html2canvas_"+ce++,s=e.createElement("script"),a=e.createElement("a");a.href=r,r=a.href;var c=i+(i.indexOf("?")>-1?"&":"?")+"url="+encodeURIComponent(r)+"&callback="+o;this.src=r,this.image=new Image;var h=this.image;this.promise=new Promise(function(r,i){h.onload=r,h.onerror=i,t[o]=function(e){"error:"===e.substring(0,6)?i():h.src=e,t[o]=n;try{delete t[o]}catch(r){}s.parentNode.removeChild(s)},s.setAttribute("type","text/javascript"),s.setAttribute("src",c),e.body.appendChild(s)})}function te(t,e,n){this.width=t,this.height=e,this.images=n}function ee(t,n){te.apply(this,arguments),this.canvas=e.createElement("canvas"),this.canvas.width=t,this.canvas.height=n,this.ctx=this.canvas.getContext("2d"),this.ctx.textBaseline="bottom",this.variables={},m("Initialized CanvasRenderer")}function ne(t,e,n,r){y.call(this,n,r),this.ownStacking=t,this.contexts=[],this.children=[],this.opacity=(this.parent?this.parent.stack.opacity:1)*e}function re(){this.rangeBounds=this.testRangeBounds(),this.cors=this.testCORS()}function ie(t,e){y.call(this,t,e)}function oe(t,e,r){return t.length>0?e+r.toUpperCase():n}function se(t){u.apply(this,arguments),this.type="linear"===t.args[0]?this.TYPES.LINEAR:this.TYPES.RADIAL}var ae="data-html2canvas-node";t.html2canvas=function(i,o){o=o||{},o.logging&&(t.html2canvas.logging=!0,t.html2canvas.start=Date.now()),o.async=o.async===n?!0:o.async,o.removeContainer=o.removeContainer===n?!0:o.removeContainer;var s=(i===n?[e.documentElement]:i.length?i:[i])[0];return s.setAttribute(ae,"true"),r(s.ownerDocument,o,t.innerWidth,t.innerHeight).then(function(t){return"function"==typeof o.onrendered&&(m("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas"),o.onrendered(t)),t})},h.prototype.getMetrics=function(t,e){return this.data[t+"-"+e]===n&&(this.data[t+"-"+e]=new c(t,e)),this.data[t+"-"+e]},u.prototype.TYPES={LINEAR:1,RADIAL:2},d.prototype.findImages=function(t){var e=[];return t.filter(l).map(f).forEach(this.addImage(e,this.loadImage),this),e},d.prototype.findBackgroundImage=function(t,e){return e.parseBackgroundImages().filter(this.hasImageBackground).forEach(this.addImage(t,this.loadImage),this),t},d.prototype.addImage=function(t,e){return function(n){this.imageExists(t,n)||(t.splice(0,0,e.apply(this,arguments)),m("Added image #"+t.length,n))}},d.prototype.hasImageBackground=function(t){return"none"!==t.method},d.prototype.loadImage=function(t){if("url"===t.method){var e=t.args[0];return e.match(/data:image\/.*;base64,/i)?new p(e.replace(/url\(['"]{0,}|['"]{0,}\)$/gi,""),!1):this.isSameOrigin(e)||this.options.allowTaint===!0?new p(e,!1):this.support.cors&&!this.options.allowTaint&&this.options.useCORS?new p(e,!0):this.options.proxy?new Z(e,this.options.proxy):new DummyImageContainer(e)}return"linear-gradient"===t.method?new g(t):"gradient"===t.method?new se(t):n},d.prototype.imageExists=function(t,e){return t.some(function(t){return t.src===e})},d.prototype.isSameOrigin=function(t){var n=this.link||(this.link=e.createElement("a"));n.href=t,n.href=n.href;var r=n.protocol+n.host;return r===this.origin},d.prototype.getPromise=function(t){return t.promise},d.prototype.get=function(t){var e=null;return this.images.some(function(n){return(e=n).src===t})?e:null},d.prototype.fetch=function(t){return this.images=t.reduce(Q(this.findBackgroundImage,this),this.findImages(t)),this.images.forEach(function(t,e){t.promise.then(function(){m("Succesfully loaded image #"+(e+1))},function(){m("Failed loading image #"+(e+1))})}),this.ready=Promise.all(this.images.map(this.getPromise)),m("Finished searching images"),this},g.prototype=Object.create(u.prototype),g.prototype.stepRegExp=/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%|px)?/,y.prototype.assignStack=function(t){this.stack=t,t.children.push(this)},y.prototype.isElementVisible=function(){return this.node.nodeType===Node.TEXT_NODE?this.parent.visible:"none"!==this.css("display")&&"hidden"!==this.css("visibility")&&!this.node.hasAttribute("data-html2canvas-ignore")},y.prototype.css=function(t){return this.computedStyles||(this.computedStyles=this.computedStyle(null)),this.styles[t]||(this.styles[t]=this.computedStyles[t])},y.prototype.prefixedCss=function(t){var e=["webkit","moz","ms","o"],r=this.css(t);return r===n&&e.some(function(e){return r=this.css(e+t.substr(0,1).toUpperCase()+t.substr(1)),r!==n},this),r===n?null:r},y.prototype.computedStyle=function(t){return this.node.ownerDocument.defaultView.getComputedStyle(this.node,t)},y.prototype.cssInt=function(t){var e=parseInt(this.css(t),10);return isNaN(e)?0:e},y.prototype.cssFloat=function(t){var e=parseFloat(this.css(t));return isNaN(e)?0:e},y.prototype.fontWeight=function(){var t=this.css("fontWeight");switch(parseInt(t,10)){case 401:t="bold";break;case 400:t="normal"}return t},y.prototype.parseBackgroundImages=function(){return this.backgroundImages||(this.backgroundImages=w(this.css("backgroundImage")))},y.prototype.cssList=function(t,e){var n=(this.css(t)||"").split(",");return n=n[e||0]||n[0]||"auto",n=n.trim().split(" "),1===n.length&&(n=[n[0],n[0]]),n},y.prototype.parseBackgroundSize=function(t,e,n){var r,i,o=this.cssList("backgroundSize",n);if(b(o[0]))r=t.width*parseFloat(o[0])/100;else{if(/contain|cover/.test(o[0])){var s=t.width/t.height,a=e.width/e.height;return a>s^"contain"===o[0]?{width:t.height*a,height:t.height}:{width:t.width,height:t.width/a}}r=parseInt(o[0],10)}return i="auto"===o[0]&&"auto"===o[1]?e.height:"auto"===o[1]?r/e.width*e.height:b(o[1])?t.height*parseFloat(o[1])/100:parseInt(o[1],10),"auto"===o[0]&&(r=i/e.height*e.width),{width:r,height:i}},y.prototype.parseBackgroundPosition=function(t,e,n,r){var i,o,s=this.cssList("backgroundPosition",n);return i=b(s[0])?(t.width-(r||e).width)*(parseFloat(s[0])/100):parseInt(s[0],10),o="auto"===s[1]?i/e.width*e.height:b(s[1])?(t.height-(r||e).height)*parseFloat(s[1])/100:parseInt(s[1],10),"auto"===s[0]&&(i=o/e.height*e.width),{left:i,top:o}},y.prototype.parseBackgroundRepeat=function(t){return this.cssList("backgroundRepeat",t)[0]},y.prototype.parseTextShadows=function(){var t=this.css("textShadow"),e=[];if(t&&"none"!==t)for(var n=t.match(this.TEXT_SHADOW_PROPERTY),r=0;n&&n.length>r;r++){var i=n[r].match(this.TEXT_SHADOW_VALUES);e.push({color:i[0],offsetX:i[1]?i[1].replace("px",""):0,offsetY:i[2]?i[2].replace("px",""):0,blur:i[3]?i[3].replace("px",""):0})}return e},y.prototype.parseTransform=function(){var t=/(matrix)\((.+)\)/,e=this.prefixedCss("transform");if(null!==e&&"none"!==e){var n=v(e.match(t));if(n)return{origin:this.prefixedCss("transformOrigin"),matrix:n}}return{origin:[0,0],matrix:[1,0,0,1,0,0]}},y.prototype.TEXT_SHADOW_PROPERTY=/((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g,y.prototype.TEXT_SHADOW_VALUES=/(-?\d+px)|(#.+)|(rgb\(.+\))|(rgba\(.+\))/g,x.prototype.asyncRenderer=function(t,e,n){n=n||Date.now(),this.paint(t[this.renderIndex++]),t.length===this.renderIndex?e():n+20>Date.now()?this.asyncRenderer(t,e,n):setTimeout(Q(function(){this.asyncRenderer(t,e)},this),0)},x.prototype.createPseudoHideStyles=function(t){var e=t.createElement("style");e.innerHTML="."+this.pseudoHideClass+':before { content: "" !important; display: none !important; }'+"."+this.pseudoHideClass+':after { content: "" !important; display: none !important; }',t.body.appendChild(e)},x.prototype.getPseudoElements=function(t){var e=[[t]];if(t.node.nodeType===Node.ELEMENT_NODE){var n=this.getPseudoElement(t,":before"),r=this.getPseudoElement(t,":after");n&&(t.node.insertBefore(n[0].node,t.node.firstChild),e.push(n)),r&&(t.node.appendChild(r[0].node),e.push(r)),(n||r)&&(t.node.className+=" "+this.pseudoHideClass)}return J(e)},x.prototype.getPseudoElement=function(t,n){var r=t.computedStyle(n);if(!r||!r.content||"none"===r.content||"-moz-alt-content"===r.content||"none"===r.display)return null;for(var i=K(r.content),o="url"===i.substr(0,3),s=e.createElement(o?"img":"html2canvaspseudoelement"),a=new y(s,t),c=r.length-1;c>=0;c--){var h=k(r.item(c));s.style[h]=r[h]}if(s.className=this.pseudoHideClass,o)return s.src=w(i)[0].args[0],[a];var u=e.createTextNode(i);return s.appendChild(u),[a,new ie(u,a)]},x.prototype.getChildren=function(t){return J([].filter.call(t.node.childNodes,_).map(function(e){var n=[e.nodeType===Node.TEXT_NODE?new ie(e,t):new y(e,t)].filter($);return e.nodeType===Node.ELEMENT_NODE&&n.length?n[0].isElementVisible()?n.concat(this.getChildren(n[0])):[]:n},this))},x.prototype.newStackingContext=function(t,e){var n=new ne(e,t.cssFloat("opacity"),t.node,t.parent);n.visible=t.visible;var r=e?n.getParentStack(this):n.parent.stack;r.contexts.push(n),t.stack=n},x.prototype.createStackingContexts=function(){this.nodes.forEach(function(t){z(t)&&(this.isRootElement(t)||X(t)||D(t)||this.isBodyWithTransparentRoot(t)||U(t))?this.newStackingContext(t,!0):z(t)&&(W(t)&&O(t)||H(t)||F(t))?this.newStackingContext(t,!1):t.assignStack(t.parent.stack)},this)},x.prototype.isBodyWithTransparentRoot=function(t){return"BODY"===t.node.nodeName&&this.renderer.isTransparent(t.parent.css("backgroundColor"))},x.prototype.isRootElement=function(t){return null===t.parent},x.prototype.sortStackingContexts=function(t){t.contexts.sort(V),t.contexts.forEach(this.sortStackingContexts,this)},x.prototype.parseBounds=function(t){return t.bounds=this.getBounds(t.node)},x.prototype.getBounds=function(t){if(t.getBoundingClientRect){var e=t.getBoundingClientRect(),n="BODY"===t.nodeName,r=n?t.scrollWidth:t.offsetWidth;return{top:e.top,bottom:e.bottom||e.top+e.height,right:e.left+r,left:e.left,width:r,height:n?t.scrollHeight:t.offsetHeight}}return{}},x.prototype.parseTextBounds=function(t){return function(e,n,r){if("none"!==t.parent.css("textDecoration")||0!==e.trim().length){if(this.support.rangeBounds){var i=r.slice(0,n).join("").length;return this.getRangeBounds(t.node,i,e.length)}if(t.node&&"string"==typeof t.node.data){var o=t.node.splitText(e.length),s=this.getWrapperBounds(t.node);return t.node=o,s}}else this.support.rangeBounds||(t.node=t.node.splitText(e.length));return{}}},x.prototype.getWrapperBounds=function(t){var e=t.ownerDocument.createElement("wrapper"),n=t.parentNode,r=t.cloneNode(!0);e.appendChild(t.cloneNode(!0)),n.replaceChild(e,t);var i=this.getBounds(e);return n.replaceChild(r,e),i},x.prototype.getRangeBounds=function(t,e,n){var r=this.range||(this.range=t.ownerDocument.createRange());return r.setStart(t,e),r.setEnd(t,e+n),r.getBoundingClientRect()},x.prototype.parse=function(t){var e=t.contexts.filter(S),n=t.children.filter(z),r=n.filter(j(F)),i=r.filter(j(W)).filter(j(A)),o=n.filter(j(W)).filter(F),s=r.filter(j(W)).filter(A),a=t.contexts.concat(r.filter(W)).filter(O),c=t.children.filter(Y).filter(L),h=t.contexts.filter(B);e.concat(i).concat(o).concat(s).concat(a).concat(c).concat(h).forEach(function(t){this.renderQueue.push(t),N(t)&&this.parse(t)},this)},x.prototype.paint=function(t){try{Y(t)?this.paintText(t):this.paintNode(t)}catch(e){m(e)}},x.prototype.paintNode=function(t){if(N(t)){this.renderer.setOpacity(t.opacity);var e=t.parseTransform();e&&this.renderer.setTransform(e)}var n=this.parseBounds(t),r=this.parseBorders(t);switch(this.renderer.clip(r.clip,function(){this.renderer.renderBackground(t,n,r.borders.map(q))},this),this.renderer.renderBorders(r.borders),t.node.nodeName){case"IMG":var i=this.images.get(t.node.src);i?this.renderer.renderImage(t,n,r,i.image):m("Error loading ",t.node.src)}},x.prototype.paintText=function(t){t.applyTextTransform();var e=t.node.data.split(!this.options.letterRendering||P(t)?/(\b| )/:""),n=t.parent.fontWeight(),r=t.parent.css("fontSize"),i=t.parent.css("fontFamily"),o=t.parent.parseTextShadows();this.renderer.font(t.parent.css("color"),t.parent.css("fontStyle"),t.parent.css("fontVariant"),n,r,i),o.length?this.renderer.fontShadow(o[0].color,o[0].offsetX,o[0].offsetY,o[0].blur):this.renderer.clearShadow(),e.map(this.parseTextBounds(t),this).forEach(function(n,o){n&&(this.renderer.text(e[o],n.left,n.bottom),this.renderTextDecoration(t.parent,n,this.fontMetrics.getMetrics(i,r)))},this)},x.prototype.renderTextDecoration=function(t,e,n){switch(t.css("textDecoration").split(" ")[0]){case"underline":this.renderer.rectangle(e.left,Math.round(e.top+n.baseline+n.lineWidth),e.width,1,t.css("color"));break;case"overline":this.renderer.rectangle(e.left,Math.round(e.top),e.width,1,t.css("color"));break;case"line-through":this.renderer.rectangle(e.left,Math.ceil(e.top+n.middle+n.lineWidth),e.width,1,t.css("color"))}},x.prototype.parseBorders=function(t){var e=t.bounds,n=M(t),r=["Top","Right","Bottom","Left"].map(function(e){return{width:t.cssInt("border"+e+"Width"),color:t.css("border"+e+"Color"),args:null}}),i=T(e,n,r);return{clip:this.parseBackgroundClip(t,i,r,n,e),borders:r.map(function(t,o){if(t.width>0){var s=e.left,a=e.top,c=e.width,h=e.height-r[2].width;switch(o){case 0:h=r[0].width,t.args=R({c1:[s,a],c2:[s+c,a],c3:[s+c-r[1].width,a+h],c4:[s+r[3].width,a+h]},n[0],n[1],i.topLeftOuter,i.topLeftInner,i.topRightOuter,i.topRightInner);break;case 1:s=e.left+e.width-r[1].width,c=r[1].width,t.args=R({c1:[s+c,a],c2:[s+c,a+h+r[2].width],c3:[s,a+h],c4:[s,a+r[0].width]},n[1],n[2],i.topRightOuter,i.topRightInner,i.bottomRightOuter,i.bottomRightInner);break;case 2:a=a+e.height-r[2].width,h=r[2].width,t.args=R({c1:[s+c,a+h],c2:[s,a+h],c3:[s+r[3].width,a],c4:[s+c-r[3].width,a]},n[2],n[3],i.bottomRightOuter,i.bottomRightInner,i.bottomLeftOuter,i.bottomLeftInner);break;case 3:c=r[3].width,t.args=R({c1:[s,a+h+r[2].width],c2:[s,a],c3:[s+c,a+r[0].width],c4:[s+c,a+h]},n[3],n[0],i.bottomLeftOuter,i.bottomLeftInner,i.topLeftOuter,i.topLeftInner)}}return t})}},x.prototype.parseBackgroundClip=function(t,e,n,r,i){var o=t.css("backgroundClip"),s=[];switch(o){case"content-box":case"padding-box":C(s,r[0],r[1],e.topLeftInner,e.topRightInner,i.left+n[3].width,i.top+n[0].width),C(s,r[1],r[2],e.topRightInner,e.bottomRightInner,i.left+i.width-n[1].width,i.top+n[0].width),C(s,r[2],r[3],e.bottomRightInner,e.bottomLeftInner,i.left+i.width-n[1].width,i.top+i.height-n[2].width),C(s,r[3],r[0],e.bottomLeftInner,e.topLeftInner,i.left+n[3].width,i.top+i.height-n[2].width);break;default:C(s,r[0],r[1],e.topLeftOuter,e.topRightOuter,i.left,i.top),C(s,r[1],r[2],e.topRightOuter,e.bottomRightOuter,i.left+i.width,i.top),C(s,r[2],r[3],e.bottomRightOuter,e.bottomLeftOuter,i.left+i.width,i.top+i.height),C(s,r[3],r[0],e.bottomLeftOuter,e.topLeftOuter,i.left,i.top+i.height)}return s},x.prototype.pseudoHideClass="___html2canvas___pseudoelement",!function(){var r,i,o,s;!function(){var t={},e={};r=function(e,n,r){t[e]={deps:n,callback:r}},s=o=i=function(n){function r(t){if("."!==t.charAt(0))return t;for(var e=t.split("/"),r=n.split("/").slice(0,-1),i=0,o=e.length;o>i;i++){var s=e[i];if(".."===s)r.pop();else{if("."===s)continue;r.push(s)}}return r.join("/")}if(s._eak_seen=t,e[n])return e[n];if(e[n]={},!t[n])throw Error("Could not find module "+n);for(var o,a=t[n],c=a.deps,h=a.callback,u=[],p=0,d=c.length;d>p;p++)"exports"===c[p]?u.push(o={}):u.push(i(r(c[p])));var l=h.apply(this,u);return e[n]=o||l}}(),r("promise/all",["./utils","exports"],function(t,e){"use strict";function n(t){var e=this;if(!r(t))throw new TypeError("You must pass an array to all.");return new e(function(e,n){function r(t){return function(e){o(t,e)}}function o(t,n){a[t]=n,0===--c&&e(a)}var s,a=[],c=t.length;0===c&&e([]);for(var h=0;t.length>h;h++)s=t[h],s&&i(s.then)?s.then(r(h),n):o(h,s)})}var r=t.isArray,i=t.isFunction;e.all=n}),r("promise/asap",["exports"],function(r){"use strict";function i(){return function(){process.nextTick(a)}}function o(){var t=0,n=new p(a),r=e.createTextNode("");return n.observe(r,{characterData:!0}),function(){r.data=t=++t%2}}function s(){return function(){d.setTimeout(a,1)}}function a(){for(var t=0;l.length>t;t++){var e=l[t],n=e[0],r=e[1];n(r)}l=[]}function c(t,e){var n=l.push([t,e]);1===n&&h()}var h,u=t!==n?t:{},p=u.MutationObserver||u.WebKitMutationObserver,d="undefined"!=typeof global?global:this,l=[];h="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?i():p?o():s(),r.asap=c}),r("promise/cast",["exports"],function(t){"use strict";function e(t){if(t&&"object"==typeof t&&t.constructor===this)return t;var e=this;return new e(function(e){e(t)})}t.cast=e}),r("promise/config",["exports"],function(t){"use strict";function e(t,e){return 2!==arguments.length?n[t]:(n[t]=e,void 0)}var n={instrument:!1};t.config=n,t.configure=e}),r("promise/polyfill",["./promise","./utils","exports"],function(e,n,r){"use strict";function i(){var e="Promise"in t&&"cast"in t.Promise&&"resolve"in t.Promise&&"reject"in t.Promise&&"all"in t.Promise&&"race"in t.Promise&&function(){var e;return new t.Promise(function(t){e=t}),s(e)}();e||(t.Promise=o)}var o=e.Promise,s=n.isFunction;r.polyfill=i}),r("promise/promise",["./config","./utils","./cast","./all","./race","./resolve","./reject","./asap","exports"],function(t,e,n,r,i,o,s,a,c){"use strict";function h(t){if(!k(t))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 constructor cannot be called as a function.");this._subscribers=[],u(t,this)}function u(t,e){function n(t){g(e,t)}function r(t){y(e,t)}try{t(n,r)}catch(i){r(i)}}function p(t,e,n,r){var i,o,s,a,c=k(n);if(c)try{i=n(r),s=!0}catch(h){a=!0,o=h}else i=r,s=!0;f(e,i)||(c&&s?g(e,i):a?y(e,o):t===A?g(e,i):t===N&&y(e,i))}function d(t,e,n,r){var i=t._subscribers,o=i.length;i[o]=e,i[o+A]=n,i[o+N]=r}function l(t,e){for(var n,r,i=t._subscribers,o=t._detail,s=0;i.length>s;s+=3)n=i[s],r=i[s+e],p(e,n,r,o);t._subscribers=null}function f(t,e){var n,r=null;try{if(t===e)throw new TypeError("A promises callback cannot return that same promise.");if(x(e)&&(r=e.then,k(r)))return r.call(e,function(r){return n?!0:(n=!0,e!==r?g(t,r):m(t,r),void 0)},function(e){return n?!0:(n=!0,y(t,e),void 0)}),!0}catch(i){return n?!0:(y(t,i),!0)}return!1}function g(t,e){t===e?m(t,e):f(t,e)||m(t,e)}function m(t,e){t._state===B&&(t._state=O,t._detail=e,w.async(v,t))}function y(t,e){t._state===B&&(t._state=O,t._detail=e,w.async(b,t))}function v(t){l(t,t._state=A)}function b(t){l(t,t._state=N)}var w=t.config,x=(t.configure,e.objectOrFunction),k=e.isFunction,E=(e.now,n.cast),T=r.all,I=i.race,R=o.resolve,C=s.reject,S=a.asap;w.async=S;var B=void 0,O=0,A=1,N=2;h.prototype={constructor:h,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(t,e){var n=this,r=new this.constructor(function(){});if(this._state){var i=arguments;w.async(function(){p(n._state,r,i[n._state-1],n._detail)})}else d(this,r,t,e);return r},"catch":function(t){return this.then(null,t)}},h.all=T,h.cast=E,h.race=I,h.resolve=R,h.reject=C,c.Promise=h}),r("promise/race",["./utils","exports"],function(t,e){"use strict";function n(t){var e=this;if(!r(t))throw new TypeError("You must pass an array to race.");return new e(function(e,n){for(var r,i=0;t.length>i;i++)r=t[i],r&&"function"==typeof r.then?r.then(e,n):e(r)})}var r=t.isArray;e.race=n}),r("promise/reject",["exports"],function(t){"use strict";function e(t){var e=this;return new e(function(e,n){n(t)})}t.reject=e}),r("promise/resolve",["exports"],function(t){"use strict";function e(t){var e=this;return new e(function(e){e(t)})}t.resolve=e}),r("promise/utils",["exports"],function(t){"use strict";function e(t){return n(t)||"object"==typeof t&&null!==t}function n(t){return"function"==typeof t}function r(t){return"[object Array]"===Object.prototype.toString.call(t)}var i=Date.now||function(){return(new Date).getTime()};t.objectOrFunction=e,t.isFunction=n,t.isArray=r,t.now=i}),i("promise/polyfill").polyfill()}();var ce=0;te.prototype.renderImage=function(t,e,n,r){var i=t.cssInt("paddingLeft"),o=t.cssInt("paddingTop"),s=t.cssInt("paddingRight"),a=t.cssInt("paddingBottom"),c=n.borders;this.drawImage(r,0,0,r.width,r.height,e.left+i+c[3].width,e.top+o+c[0].width,e.width-(c[1].width+c[3].width+i+s),e.height-(c[0].width+c[2].width+o+a))},te.prototype.renderBackground=function(t,e,n){e.height>0&&e.width>0&&(this.renderBackgroundColor(t,e),this.renderBackgroundImage(t,e,n))},te.prototype.renderBackgroundColor=function(t,e){var n=t.css("backgroundColor");this.isTransparent(n)||this.rectangle(e.left,e.top,e.width,e.height,t.css("backgroundColor"))},te.prototype.renderBorders=function(t){t.forEach(this.renderBorder,this)},te.prototype.renderBorder=function(t){this.isTransparent(t.color)||null===t.args||this.drawShape(t.args,t.color)},te.prototype.renderBackgroundImage=function(t,e,n){var r=t.parseBackgroundImages();r.reverse().forEach(function(r,i,o){switch(r.method){case"url":var s=this.images.get(r.args[0]);s?this.renderBackgroundRepeating(t,e,s,o.length-(i+1),n):m("Error loading background-image",r.args[0]);break;case"linear-gradient":case"gradient":var a=this.images.get(r.value);a?this.renderBackgroundGradient(a,e,n):m("Error loading background-image",r.args[0]);break;case"none":break;default:m("Unknown background-image type",r.args[0])}},this)},te.prototype.renderBackgroundRepeating=function(t,e,n,r,i){var o=t.parseBackgroundSize(e,n.image,r),s=t.parseBackgroundPosition(e,n.image,r,o),a=t.parseBackgroundRepeat(r);switch(a){case"repeat-x":case"repeat no-repeat":this.backgroundRepeatShape(n,s,o,e,e.left+i[3],e.top+s.top+i[0],99999,n.image.height,i);break;case"repeat-y":case"no-repeat repeat":this.backgroundRepeatShape(n,s,o,e,e.left+s.left+i[3],e.top+i[0],n.image.width,99999,i);break;case"no-repeat":this.backgroundRepeatShape(n,s,o,e,e.left+s.left+i[3],e.top+s.top+i[0],n.image.width,n.image.height,i);break;default:this.renderBackgroundRepeat(n,s,o,{top:e.top,left:e.left},i[3],i[0])}},te.prototype.isTransparent=function(t){return!t||"transparent"===t||"rgba(0, 0, 0, 0)"===t},ee.prototype=Object.create(te.prototype),ee.prototype.setFillStyle=function(t){return this.ctx.fillStyle=t,this.ctx},ee.prototype.rectangle=function(t,e,n,r,i){this.setFillStyle(i).fillRect(t,e,n,r)},ee.prototype.drawShape=function(t,e){this.shape(t),this.setFillStyle(e).fill()},ee.prototype.drawImage=function(t,e,n,r,i,o,s,a,c){this.ctx.drawImage(t,e,n,r,i,o,s,a,c)},ee.prototype.clip=function(t,e,n){this.ctx.save(),this.shape(t).clip(),e.call(n),this.ctx.restore()},ee.prototype.shape=function(t){return this.ctx.beginPath(),t.forEach(function(t,e){this.ctx[0===e?"moveTo":t[0]+"To"].apply(this.ctx,t.slice(1))},this),this.ctx.closePath(),this.ctx},ee.prototype.font=function(t,e,n,r,i,o){this.setFillStyle(t).font=[e,n,r,i,o].join(" ")},ee.prototype.fontShadow=function(t,e,n,r){this.setVariable("shadowColor",t).setVariable("shadowOffsetY",e).setVariable("shadowOffsetX",n).setVariable("shadowBlur",r) -},ee.prototype.clearShadow=function(){this.setVariable("shadowColor","rgba(0,0,0,0)")},ee.prototype.setOpacity=function(t){this.ctx.globalAlpha=t},ee.prototype.setTransform=function(t){this.ctx.translate(t.origin[0],t.origin[1]),this.ctx.setTransform.apply(this.ctx,t.matrix),this.ctx.translate(t.origin[0],t.origin[1])},ee.prototype.setVariable=function(t,e){return this.variables[t]!==e&&(this.variables[t]=this.ctx[t]=e),this},ee.prototype.text=function(t,e,n){this.ctx.fillText(t,e,n)},ee.prototype.backgroundRepeatShape=function(t,e,n,r,i,o,s,a,c){var h=[["line",Math.round(i),Math.round(o)],["line",Math.round(i+s),Math.round(o)],["line",Math.round(i+s),Math.round(a+o)],["line",Math.round(i),Math.round(a+o)]];this.clip(h,function(){this.renderBackgroundRepeat(t,e,n,r,c[3],c[0])},this)},ee.prototype.renderBackgroundRepeat=function(t,e,n,r,i,o){var s=Math.round(r.left+e.left+i),a=Math.round(r.top+e.top+o);this.setFillStyle(this.ctx.createPattern(this.resizeImage(t,n),"repeat")),this.ctx.translate(s,a),this.ctx.fill(),this.ctx.translate(-s,-a)},ee.prototype.renderBackgroundGradient=function(t,e){t instanceof g&&this.ctx.createLinearGradient(e.left,e.top,e.right,e.bottom)},ee.prototype.resizeImage=function(t,n){var r=t.image;if(r.width===n.width&&r.height===n.height)return r;var i,o=e.createElement("canvas");return o.width=n.width,o.height=n.height,i=o.getContext("2d"),i.drawImage(r,0,0,r.width,r.height,0,0,n.width,n.height),o},ne.prototype=Object.create(y.prototype),ne.prototype.getParentStack=function(t){var e=this.parent?this.parent.stack:null;return e?e.ownStacking?e:e.getParentStack(t):t.stack},re.prototype.testRangeBounds=function(){var t,n,r,i,o=!1;return e.createRange&&(t=e.createRange(),t.getBoundingClientRect&&(n=e.createElement("boundtest"),n.style.height="123px",n.style.display="block",e.body.appendChild(n),t.selectNode(n),r=t.getBoundingClientRect(),i=r.height,123===i&&(o=!0),e.body.removeChild(n))),o},re.prototype.testCORS=function(){return(new Image).crossOrigin!==n},ie.prototype=Object.create(y.prototype),ie.prototype.applyTextTransform=function(){this.node.data=this.transform(this.parent.css("textTransform"))},ie.prototype.transform=function(t){var e=this.node.data;switch(t){case"lowercase":return e.toLowerCase();case"capitalize":return e.replace(/(^|\s|:|-|\(|\))([a-z])/g,oe);case"uppercase":return e.toUpperCase();default:return e}},se.prototype=Object.create(u.prototype)})(window,document); \ No newline at end of file +(function(t,e,n){function r(t,e,n,r){return a(t,n,r,e).then(function(s){m("Document cloned");var a="["+pe+"='true']";t.querySelector(a).removeAttribute(pe);var c=s.contentWindow,h=c.document.querySelector(a),u=new ae(c.document),p=new d(e,u),l=k(h),f="view"===e.type?Math.min(l.width,n):i(),g="view"===e.type?Math.min(l.height,r):o(),y=new oe(f,g,p),b=new I(h,y,u,p,e);return b.ready.then(function(){return m("Finished rendering"),e.removeContainer&&s.parentNode.removeChild(s),y.canvas})})}function i(){return Math.max(Math.max(e.body.scrollWidth,e.documentElement.scrollWidth),Math.max(e.body.offsetWidth,e.documentElement.offsetWidth),Math.max(e.body.clientWidth,e.documentElement.clientWidth))}function o(){return Math.max(Math.max(e.body.scrollHeight,e.documentElement.scrollHeight),Math.max(e.body.offsetHeight,e.documentElement.offsetHeight),Math.max(e.body.clientHeight,e.documentElement.clientHeight))}function s(){return"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"}function a(e,n,r,i){var o=e.documentElement.cloneNode(!0),s=e.createElement("iframe");return s.style.visibility="hidden",s.style.position="absolute",s.style.left=s.style.top="-10000px",s.width=n,s.height=r,s.scrolling="no",e.body.appendChild(s),new Promise(function(e){var n=s.contentWindow.document;n.open(),n.write(""),n.close(),n.replaceChild(n.adoptNode(o),n.documentElement),"view"===i.type&&s.contentWindow.scrollTo(t.scrollX,t.scrollY),e(s)})}function c(t,n){var r,i,o=e.createElement("div"),a=e.createElement("img"),c=e.createElement("span"),h="Hidden Text";o.style.visibility="hidden",o.style.fontFamily=t,o.style.fontSize=n,o.style.margin=0,o.style.padding=0,e.body.appendChild(o),a.src=s(),a.width=1,a.height=1,a.style.margin=0,a.style.padding=0,a.style.verticalAlign="baseline",c.style.fontFamily=t,c.style.fontSize=n,c.style.margin=0,c.style.padding=0,c.appendChild(e.createTextNode(h)),o.appendChild(c),o.appendChild(a),r=a.offsetTop-c.offsetTop+1,o.removeChild(c),o.appendChild(e.createTextNode(h)),o.style.lineHeight="normal",a.style.verticalAlign="super",i=a.offsetTop-o.offsetTop+1,e.body.removeChild(o),this.baseline=r,this.lineWidth=1,this.middle=i}function h(){this.data={}}function u(t){this.src=t.value,this.colorStops=[],this.type=null,this.x0=.5,this.y0=.5,this.x1=.5,this.y1=.5,this.promise=Promise.resolve(!0)}function p(t,e){this.src=t,this.image=new Image;var n=this.image;this.promise=new Promise(function(r,i){n.onload=r,n.onerror=i,e&&(n.crossOrigin="anonymous"),n.src=t,n.complete===!0&&r(n)})}function d(e,n){this.link=null,this.options=e,this.support=n,this.origin=t.location.protocol+t.location.host}function l(t){return"IMG"===t.node.nodeName}function f(t){return{args:[t.node.src],method:"url"}}function g(t){u.apply(this,arguments),this.type=this.TYPES.LINEAR,t.args[0].split(" ").forEach(function(t){switch(t){case"left":this.x0=0,this.x1=1;break;case"top":this.y0=0,this.y1=1;break;case"right":this.x0=1,this.x1=0;break;case"bottom":this.y0=1,this.y1=0}},this),t.args.slice(1).forEach(function(){},this)}function m(){t.html2canvas.logging&&t.console&&t.console.log&&t.console.log.apply(t.console,[Date.now()-t.html2canvas.start+"ms","html2canvas:"].concat([].slice.call(arguments,0)))}function y(t,e){this.node=t,this.parent=e,this.stack=null,this.bounds=null,this.offsetBounds=null,this.visible=null,this.computedStyles=null,this.styles={},this.backgroundImages=null}function b(t){return t&&"matrix"===t[1]?t[2].split(",").map(function(t){return parseFloat(t.trim())}):n}function v(t){return-1!==(""+t).indexOf("%")}function w(t){var e,r,i,o,s,a,c,h=" \r\n ",u=[],p=0,d=0,l=function(){e&&('"'===r.substr(0,1)&&(r=r.substr(1,r.length-2)),r&&c.push(r),"-"===e.substr(0,1)&&(o=e.indexOf("-",1)+1)>0&&(i=e.substr(0,o),e=e.substr(o)),u.push({prefix:i,method:e.toLowerCase(),value:s,args:c,image:null})),c=[],e=i=r=s=""};return c=[],e=i=r=s="",t.split("").forEach(function(t){if(!(0===p&&h.indexOf(t)>-1)){switch(t){case'"':a?a===t&&(a=null):a=t;break;case"(":if(a)break;if(0===p)return p=1,s+=t,n;d++;break;case")":if(a)break;if(1===p){if(0===d)return p=0,s+=t,l(),n;d--}break;case",":if(a)break;if(0===p)return l(),n;if(1===p&&0===d&&!e.match(/^url$/i))return c.push(r),r="",s+=t,n}s+=t,0===p?e+=t:r+=t}}),l(),u}function x(t){return t.replace("px","")}function T(t){return parseFloat(t)}function k(t){if(t.getBoundingClientRect){var e=t.getBoundingClientRect(),n="BODY"===t.nodeName,r=n?t.scrollWidth:t.offsetWidth;return{top:e.top,bottom:e.bottom||e.top+e.height,right:e.left+r,left:e.left,width:r,height:n?t.scrollHeight:t.offsetHeight}}return{}}function E(t){var e=t.offsetParent?E(t.offsetParent):{top:0,left:0};return{top:t.offsetTop+e.top,bottom:t.offsetTop+t.offsetHeight+e.top,right:t.offsetLeft+e.left+t.offsetWidth,left:t.offsetLeft+e.left,width:t.offsetWidth,height:t.offsetHeight}}function I(t,e,n,r,i){m("Starting NodeParser"),this.renderer=e,this.options=i,this.range=null,this.support=n,this.renderQueue=[],this.stack=new se(!0,1,t.ownerDocument,null);var o=new y(t,null);o.visibile=o.isElementVisible(),this.createPseudoHideStyles(t.ownerDocument),this.nodes=ee([o].concat(this.getChildren(o)).filter(function(t){return t.visible=t.isElementVisible()}).map(this.getPseudoElements,this)),this.fontMetrics=new h,m("Fetched nodes"),this.images=r.fetch(this.nodes.filter(U)),m("Creating stacking contexts"),this.createStackingContexts(),m("Sorting stacking contexts"),this.sortStackingContexts(this.stack),this.ready=this.images.ready.then(J(function(){return m("Images loaded, starting parsing"),this.parse(this.stack),m("Render queue created with "+this.renderQueue.length+" items"),new Promise(J(function(t){i.async?"function"==typeof i.async?i.async.call(this,this.renderQueue,t):(this.renderIndex=0,this.asyncRenderer(this.renderQueue,t)):(this.renderQueue.forEach(this.paint,this),t())},this))},this))}function R(t){return t.replace(/(\-[a-z])/g,function(t){return t.toUpperCase().replace("-","")})}function C(){}function S(t,e,n,r){var i=4*((Math.sqrt(2)-1)/3),o=n*i,s=r*i,a=t+n,c=e+r;return{topLeft:O({x:t,y:c},{x:t,y:c-s},{x:a-o,y:e},{x:a,y:e}),topRight:O({x:t,y:e},{x:t+o,y:e},{x:a,y:c-s},{x:a,y:c}),bottomRight:O({x:a,y:e},{x:a,y:e+s},{x:t+o,y:c},{x:t,y:c}),bottomLeft:O({x:a,y:c},{x:a-o,y:c},{x:t,y:e+s},{x:t,y:e})}}function B(t,e,n){var r=t.left,i=t.top,o=t.width,s=t.height,a=e[0][0],c=e[0][1],h=e[1][0],u=e[1][1],p=e[2][0],d=e[2][1],l=e[3][0],f=e[3][1],g=o-h,m=s-d,y=o-p,b=s-f;return{topLeftOuter:S(r,i,a,c).topLeft.subdivide(.5),topLeftInner:S(r+n[3].width,i+n[0].width,Math.max(0,a-n[3].width),Math.max(0,c-n[0].width)).topLeft.subdivide(.5),topRightOuter:S(r+g,i,h,u).topRight.subdivide(.5),topRightInner:S(r+Math.min(g,o+n[3].width),i+n[0].width,g>o+n[3].width?0:h-n[3].width,u-n[0].width).topRight.subdivide(.5),bottomRightOuter:S(r+y,i+m,p,d).bottomRight.subdivide(.5),bottomRightInner:S(r+Math.min(y,o+n[3].width),i+Math.min(m,s+n[0].width),Math.max(0,p-n[1].width),Math.max(0,d-n[2].width)).bottomRight.subdivide(.5),bottomLeftOuter:S(r,i+b,l,f).bottomLeft.subdivide(.5),bottomLeftInner:S(r+n[3].width,i+b,Math.max(0,l-n[3].width),Math.max(0,f-n[2].width)).bottomLeft.subdivide(.5)}}function O(t,e,n,r){var i=function(t,e,n){return{x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n}};return{start:t,startControl:e,endControl:n,end:r,subdivide:function(o){var s=i(t,e,o),a=i(e,n,o),c=i(n,r,o),h=i(s,a,o),u=i(a,c,o),p=i(h,u,o);return[O(t,s,h,p),O(p,u,c,r)]},curveTo:function(t){t.push(["bezierCurve",e.x,e.y,n.x,n.y,r.x,r.y])},curveToReversed:function(r){r.push(["bezierCurve",n.x,n.y,e.x,e.y,t.x,t.y])}}}function A(t,e,n,r,i,o,s){var a=[];return e[0]>0||e[1]>0?(a.push(["line",r[1].start.x,r[1].start.y]),r[1].curveTo(a)):a.push(["line",t.c1[0],t.c1[1]]),n[0]>0||n[1]>0?(a.push(["line",o[0].start.x,o[0].start.y]),o[0].curveTo(a),a.push(["line",s[0].end.x,s[0].end.y]),s[0].curveToReversed(a)):(a.push(["line",t.c2[0],t.c2[1]]),a.push(["line",t.c3[0],t.c3[1]])),e[0]>0||e[1]>0?(a.push(["line",i[1].end.x,i[1].end.y]),i[1].curveToReversed(a)):a.push(["line",t.c4[0],t.c4[1]]),a}function L(t,e,n,r,i,o,s){e[0]>0||e[1]>0?(t.push(["line",r[0].start.x,r[0].start.y]),r[0].curveTo(t),r[1].curveTo(t)):t.push(["line",o,s]),(n[0]>0||n[1]>0)&&t.push(["line",i[0].start.x,i[0].start.y])}function N(t){return 0>t.cssInt("zIndex")}function P(t){return t.cssInt("zIndex")>0}function M(t){return 0===t.cssInt("zIndex")}function _(t){return-1!==["inline","inline-block","inline-table"].indexOf(t.css("display"))}function D(t){return t instanceof se}function W(t){return t.node.data.trim().length>0}function F(t){return/^(normal|none|0px)$/.test(t.parent.css("letterSpacing"))}function H(t){return["TopLeft","TopRight","BottomRight","BottomLeft"].map(function(e){var n=t.css("border"+e+"Radius"),r=n.split(" ");return 1>=r.length&&(r[1]=r[0]),r.map(K)})}function j(t){return t.nodeType===Node.TEXT_NODE||t.nodeType===Node.ELEMENT_NODE}function z(t){var e=t.css("position"),n="absolute"===e||"relative"===e?t.css("zIndex"):"auto";return"auto"!==n}function Y(t){return"static"!==t.css("position")}function V(t){return"none"!==t.css("float")}function X(t){return-1!==["inline-block","inline-table"].indexOf(t.css("display"))}function Q(t){var e=this;return function(){return!t.apply(e,arguments)}}function U(t){return t.node.nodeType===Node.ELEMENT_NODE}function G(t){return t.node.nodeType===Node.TEXT_NODE}function q(t,e){return t.cssInt("zIndex")-e.cssInt("zIndex")}function $(t){return 1>t.css("opacity")}function J(t,e){return function(){return t.apply(e,arguments)}}function K(t){return parseInt(t,10)}function Z(t){return t.width}function te(t){return t.node.nodeType!==Node.ELEMENT_NODE||-1===["SCRIPT","HEAD","TITLE","OBJECT","BR"].indexOf(t.node.nodeName)}function ee(t){return[].concat.apply([],t)}function ne(t){var e=t.substr(0,1);return e===t.substr(t.length-1)&&e.match(/'|"/)?t.substr(1,t.length-2):t}function re(r,i){var o="html2canvas_"+de++,s=e.createElement("script"),a=e.createElement("a");a.href=r,r=a.href;var c=i+(i.indexOf("?")>-1?"&":"?")+"url="+encodeURIComponent(r)+"&callback="+o;this.src=r,this.image=new Image;var h=this.image;this.promise=new Promise(function(r,i){h.onload=r,h.onerror=i,t[o]=function(e){"error:"===e.substring(0,6)?i():h.src=e,t[o]=n;try{delete t[o]}catch(r){}s.parentNode.removeChild(s)},s.setAttribute("type","text/javascript"),s.setAttribute("src",c),e.body.appendChild(s)})}function ie(t,e,n){this.width=t,this.height=e,this.images=n}function oe(t,n){ie.apply(this,arguments),this.canvas=e.createElement("canvas"),this.canvas.width=t,this.canvas.height=n,this.ctx=this.canvas.getContext("2d"),this.ctx.textBaseline="bottom",this.variables={},m("Initialized CanvasRenderer")}function se(t,e,n,r){y.call(this,n,r),this.ownStacking=t,this.contexts=[],this.children=[],this.opacity=(this.parent?this.parent.stack.opacity:1)*e}function ae(t){this.rangeBounds=this.testRangeBounds(t),this.cors=this.testCORS()}function ce(t,e){y.call(this,t,e)}function he(t,e,r){return t.length>0?e+r.toUpperCase():n}function ue(t){u.apply(this,arguments),this.type="linear"===t.args[0]?this.TYPES.LINEAR:this.TYPES.RADIAL}var pe="data-html2canvas-node";t.html2canvas=function(i,o){o=o||{},o.logging&&(t.html2canvas.logging=!0,t.html2canvas.start=Date.now()),o.async=o.async===n?!0:o.async,o.removeContainer=o.removeContainer===n?!0:o.removeContainer;var s=(i===n?[e.documentElement]:i.length?i:[i])[0];return s.setAttribute(pe,"true"),r(s.ownerDocument,o,t.innerWidth,t.innerHeight).then(function(t){return"function"==typeof o.onrendered&&(m("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas"),o.onrendered(t)),t})},h.prototype.getMetrics=function(t,e){return this.data[t+"-"+e]===n&&(this.data[t+"-"+e]=new c(t,e)),this.data[t+"-"+e]},u.prototype.TYPES={LINEAR:1,RADIAL:2},d.prototype.findImages=function(t){var e=[];return t.filter(l).map(f).forEach(this.addImage(e,this.loadImage),this),e},d.prototype.findBackgroundImage=function(t,e){return e.parseBackgroundImages().filter(this.hasImageBackground).forEach(this.addImage(t,this.loadImage),this),t},d.prototype.addImage=function(t,e){return function(n){this.imageExists(t,n)||(t.splice(0,0,e.apply(this,arguments)),m("Added image #"+t.length,n))}},d.prototype.hasImageBackground=function(t){return"none"!==t.method},d.prototype.loadImage=function(t){if("url"===t.method){var e=t.args[0];return e.match(/data:image\/.*;base64,/i)?new p(e.replace(/url\(['"]{0,}|['"]{0,}\)$/gi,""),!1):this.isSameOrigin(e)||this.options.allowTaint===!0?new p(e,!1):this.support.cors&&!this.options.allowTaint&&this.options.useCORS?new p(e,!0):this.options.proxy?new re(e,this.options.proxy):new DummyImageContainer(e)}return"linear-gradient"===t.method?new g(t):"gradient"===t.method?new ue(t):n},d.prototype.imageExists=function(t,e){return t.some(function(t){return t.src===e})},d.prototype.isSameOrigin=function(t){var n=this.link||(this.link=e.createElement("a"));n.href=t,n.href=n.href;var r=n.protocol+n.host;return r===this.origin},d.prototype.getPromise=function(t){return t.promise},d.prototype.get=function(t){var e=null;return this.images.some(function(n){return(e=n).src===t})?e:null},d.prototype.fetch=function(t){return this.images=t.reduce(J(this.findBackgroundImage,this),this.findImages(t)),this.images.forEach(function(t,e){t.promise.then(function(){m("Succesfully loaded image #"+(e+1))},function(){m("Failed loading image #"+(e+1))})}),this.ready=Promise.all(this.images.map(this.getPromise)),m("Finished searching images"),this},g.prototype=Object.create(u.prototype),g.prototype.stepRegExp=/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%|px)?/,y.prototype.assignStack=function(t){this.stack=t,t.children.push(this)},y.prototype.isElementVisible=function(){return this.node.nodeType===Node.TEXT_NODE?this.parent.visible:"none"!==this.css("display")&&"hidden"!==this.css("visibility")&&!this.node.hasAttribute("data-html2canvas-ignore")},y.prototype.css=function(t){return this.computedStyles||(this.computedStyles=this.computedStyle(null)),this.styles[t]||(this.styles[t]=this.computedStyles[t])},y.prototype.prefixedCss=function(t){var e=["webkit","moz","ms","o"],r=this.css(t);return r===n&&e.some(function(e){return r=this.css(e+t.substr(0,1).toUpperCase()+t.substr(1)),r!==n},this),r===n?null:r},y.prototype.computedStyle=function(t){return this.node.ownerDocument.defaultView.getComputedStyle(this.node,t)},y.prototype.cssInt=function(t){var e=parseInt(this.css(t),10);return isNaN(e)?0:e},y.prototype.cssFloat=function(t){var e=parseFloat(this.css(t));return isNaN(e)?0:e},y.prototype.fontWeight=function(){var t=this.css("fontWeight");switch(parseInt(t,10)){case 401:t="bold";break;case 400:t="normal"}return t},y.prototype.parseBackgroundImages=function(){return this.backgroundImages||(this.backgroundImages=w(this.css("backgroundImage")))},y.prototype.cssList=function(t,e){var n=(this.css(t)||"").split(",");return n=n[e||0]||n[0]||"auto",n=n.trim().split(" "),1===n.length&&(n=[n[0],n[0]]),n},y.prototype.parseBackgroundSize=function(t,e,n){var r,i,o=this.cssList("backgroundSize",n);if(v(o[0]))r=t.width*parseFloat(o[0])/100;else{if(/contain|cover/.test(o[0])){var s=t.width/t.height,a=e.width/e.height;return a>s^"contain"===o[0]?{width:t.height*a,height:t.height}:{width:t.width,height:t.width/a}}r=parseInt(o[0],10)}return i="auto"===o[0]&&"auto"===o[1]?e.height:"auto"===o[1]?r/e.width*e.height:v(o[1])?t.height*parseFloat(o[1])/100:parseInt(o[1],10),"auto"===o[0]&&(r=i/e.height*e.width),{width:r,height:i}},y.prototype.parseBackgroundPosition=function(t,e,n,r){var i,o,s=this.cssList("backgroundPosition",n);return i=v(s[0])?(t.width-(r||e).width)*(parseFloat(s[0])/100):parseInt(s[0],10),o="auto"===s[1]?i/e.width*e.height:v(s[1])?(t.height-(r||e).height)*parseFloat(s[1])/100:parseInt(s[1],10),"auto"===s[0]&&(i=o/e.height*e.width),{left:i,top:o}},y.prototype.parseBackgroundRepeat=function(t){return this.cssList("backgroundRepeat",t)[0]},y.prototype.parseTextShadows=function(){var t=this.css("textShadow"),e=[];if(t&&"none"!==t)for(var n=t.match(this.TEXT_SHADOW_PROPERTY),r=0;n&&n.length>r;r++){var i=n[r].match(this.TEXT_SHADOW_VALUES);e.push({color:i[0],offsetX:i[1]?i[1].replace("px",""):0,offsetY:i[2]?i[2].replace("px",""):0,blur:i[3]?i[3].replace("px",""):0})}return e},y.prototype.parseTransform=function(){var t=/(matrix)\((.+)\)/,e=this.prefixedCss("transform"),n=b(e.match(t)),r=this.parseBounds();if(n){var i=this.prefixedCss("transformOrigin").split(" ").map(x).map(T);return i[0]+=r.left,i[1]+=r.top,{origin:i,matrix:n}}},y.prototype.parseBounds=function(){return this.bounds||(this.bounds=this.hasTransform()?E(this.node):k(this.node))},y.prototype.hasTransform=function(){var t=this.prefixedCss("transform");return null!==t&&"none"!==t&&"matrix(1, 0, 0, 1, 0, 0)"!==t},y.prototype.TEXT_SHADOW_PROPERTY=/((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g,y.prototype.TEXT_SHADOW_VALUES=/(-?\d+px)|(#.+)|(rgb\(.+\))|(rgba\(.+\))/g,I.prototype.asyncRenderer=function(t,e,n){n=n||Date.now(),this.paint(t[this.renderIndex++]),t.length===this.renderIndex?e():n+20>Date.now()?this.asyncRenderer(t,e,n):setTimeout(J(function(){this.asyncRenderer(t,e)},this),0)},I.prototype.createPseudoHideStyles=function(t){var e=t.createElement("style");e.innerHTML="."+this.pseudoHideClass+':before { content: "" !important; display: none !important; }'+"."+this.pseudoHideClass+':after { content: "" !important; display: none !important; }',t.body.appendChild(e)},I.prototype.getPseudoElements=function(t){var e=[[t]];if(t.node.nodeType===Node.ELEMENT_NODE){var n=this.getPseudoElement(t,":before"),r=this.getPseudoElement(t,":after");n&&(t.node.insertBefore(n[0].node,t.node.firstChild),e.push(n)),r&&(t.node.appendChild(r[0].node),e.push(r)),(n||r)&&(t.node.className+=" "+this.pseudoHideClass)}return ee(e)},I.prototype.getPseudoElement=function(t,n){var r=t.computedStyle(n);if(!r||!r.content||"none"===r.content||"-moz-alt-content"===r.content||"none"===r.display)return null;for(var i=ne(r.content),o="url"===i.substr(0,3),s=e.createElement(o?"img":"html2canvaspseudoelement"),a=new y(s,t),c=r.length-1;c>=0;c--){var h=R(r.item(c));s.style[h]=r[h]}if(s.className=this.pseudoHideClass,o)return s.src=w(i)[0].args[0],[a];var u=e.createTextNode(i);return s.appendChild(u),[a,new ce(u,a)]},I.prototype.getChildren=function(t){return ee([].filter.call(t.node.childNodes,j).map(function(e){var n=[e.nodeType===Node.TEXT_NODE?new ce(e,t):new y(e,t)].filter(te);return e.nodeType===Node.ELEMENT_NODE&&n.length?n[0].isElementVisible()?n.concat(this.getChildren(n[0])):[]:n},this))},I.prototype.newStackingContext=function(t,e){var n=new se(e,t.cssFloat("opacity"),t.node,t.parent);n.visible=t.visible;var r=e?n.getParentStack(this):n.parent.stack;r.contexts.push(n),t.stack=n},I.prototype.createStackingContexts=function(){this.nodes.forEach(function(t){U(t)&&(this.isRootElement(t)||$(t)||z(t)||this.isBodyWithTransparentRoot(t)||t.hasTransform())?this.newStackingContext(t,!0):U(t)&&(Y(t)&&M(t)||X(t)||V(t))?this.newStackingContext(t,!1):t.assignStack(t.parent.stack)},this)},I.prototype.isBodyWithTransparentRoot=function(t){return"BODY"===t.node.nodeName&&this.renderer.isTransparent(t.parent.css("backgroundColor"))},I.prototype.isRootElement=function(t){return null===t.parent},I.prototype.sortStackingContexts=function(t){t.contexts.sort(q),t.contexts.forEach(this.sortStackingContexts,this)},I.prototype.parseTextBounds=function(t){return function(e,n,r){if("none"!==t.parent.css("textDecoration").substr(0,4)||0!==e.trim().length){if(this.support.rangeBounds&&!t.parent.hasTransform()){var i=r.slice(0,n).join("").length;return this.getRangeBounds(t.node,i,e.length)}if(t.node&&"string"==typeof t.node.data){var o=t.node.splitText(e.length),s=this.getWrapperBounds(t.node,t.parent.hasTransform());return t.node=o,s}}else(!this.support.rangeBounds||t.parent.hasTransform())&&(t.node=t.node.splitText(e.length));return{}}},I.prototype.getWrapperBounds=function(t,e){var n=t.ownerDocument.createElement("html2canvaswrapper"),r=t.parentNode,i=t.cloneNode(!0);n.appendChild(t.cloneNode(!0)),r.replaceChild(n,t);var o=e?E(n):k(n);return r.replaceChild(i,n),o},I.prototype.getRangeBounds=function(t,e,n){var r=this.range||(this.range=t.ownerDocument.createRange());return r.setStart(t,e),r.setEnd(t,e+n),r.getBoundingClientRect()},I.prototype.parse=function(t){var e=t.contexts.filter(N),n=t.children.filter(U),r=n.filter(Q(V)),i=r.filter(Q(Y)).filter(Q(_)),o=n.filter(Q(Y)).filter(V),s=r.filter(Q(Y)).filter(_),a=t.contexts.concat(r.filter(Y)).filter(M),c=t.children.filter(G).filter(W),h=t.contexts.filter(P);e.concat(i).concat(o).concat(s).concat(a).concat(c).concat(h).forEach(function(t){this.renderQueue.push(t),D(t)&&(this.parse(t),this.renderQueue.push(new C))},this)},I.prototype.paint=function(t){try{t instanceof C?this.renderer.ctx.restore():G(t)?this.paintText(t):this.paintNode(t)}catch(e){m(e)}},I.prototype.paintNode=function(t){D(t)&&(this.renderer.setOpacity(t.opacity),this.renderer.ctx.save(),t.hasTransform()&&this.renderer.setTransform(t.parseTransform()));var e=t.parseBounds(),n=this.parseBorders(t);switch(this.renderer.clip(n.clip,function(){this.renderer.renderBackground(t,e,n.borders.map(Z))},this),this.renderer.renderBorders(n.borders),t.node.nodeName){case"IMG":var r=this.images.get(t.node.src);r?this.renderer.renderImage(t,e,n,r.image):m("Error loading ",t.node.src)}},I.prototype.paintText=function(t){t.applyTextTransform();var e=t.node.data.split(!this.options.letterRendering||F(t)?/(\b| )/:""),n=t.parent.fontWeight(),r=t.parent.css("fontSize"),i=t.parent.css("fontFamily"),o=t.parent.parseTextShadows();this.renderer.font(t.parent.css("color"),t.parent.css("fontStyle"),t.parent.css("fontVariant"),n,r,i),o.length?this.renderer.fontShadow(o[0].color,o[0].offsetX,o[0].offsetY,o[0].blur):this.renderer.clearShadow(),e.map(this.parseTextBounds(t),this).forEach(function(n,o){n&&(this.renderer.text(e[o],n.left,n.bottom),this.renderTextDecoration(t.parent,n,this.fontMetrics.getMetrics(i,r)))},this)},I.prototype.renderTextDecoration=function(t,e,n){switch(t.css("textDecoration").split(" ")[0]){case"underline":this.renderer.rectangle(e.left,Math.round(e.top+n.baseline+n.lineWidth),e.width,1,t.css("color"));break;case"overline":this.renderer.rectangle(e.left,Math.round(e.top),e.width,1,t.css("color"));break;case"line-through":this.renderer.rectangle(e.left,Math.ceil(e.top+n.middle+n.lineWidth),e.width,1,t.css("color"))}},I.prototype.parseBorders=function(t){var e=t.bounds,n=H(t),r=["Top","Right","Bottom","Left"].map(function(e){return{width:t.cssInt("border"+e+"Width"),color:t.css("border"+e+"Color"),args:null}}),i=B(e,n,r);return{clip:this.parseBackgroundClip(t,i,r,n,e),borders:r.map(function(t,o){if(t.width>0){var s=e.left,a=e.top,c=e.width,h=e.height-r[2].width;switch(o){case 0:h=r[0].width,t.args=A({c1:[s,a],c2:[s+c,a],c3:[s+c-r[1].width,a+h],c4:[s+r[3].width,a+h]},n[0],n[1],i.topLeftOuter,i.topLeftInner,i.topRightOuter,i.topRightInner);break;case 1:s=e.left+e.width-r[1].width,c=r[1].width,t.args=A({c1:[s+c,a],c2:[s+c,a+h+r[2].width],c3:[s,a+h],c4:[s,a+r[0].width]},n[1],n[2],i.topRightOuter,i.topRightInner,i.bottomRightOuter,i.bottomRightInner);break;case 2:a=a+e.height-r[2].width,h=r[2].width,t.args=A({c1:[s+c,a+h],c2:[s,a+h],c3:[s+r[3].width,a],c4:[s+c-r[3].width,a]},n[2],n[3],i.bottomRightOuter,i.bottomRightInner,i.bottomLeftOuter,i.bottomLeftInner);break;case 3:c=r[3].width,t.args=A({c1:[s,a+h+r[2].width],c2:[s,a],c3:[s+c,a+r[0].width],c4:[s+c,a+h]},n[3],n[0],i.bottomLeftOuter,i.bottomLeftInner,i.topLeftOuter,i.topLeftInner)}}return t})}},I.prototype.parseBackgroundClip=function(t,e,n,r,i){var o=t.css("backgroundClip"),s=[];switch(o){case"content-box":case"padding-box":L(s,r[0],r[1],e.topLeftInner,e.topRightInner,i.left+n[3].width,i.top+n[0].width),L(s,r[1],r[2],e.topRightInner,e.bottomRightInner,i.left+i.width-n[1].width,i.top+n[0].width),L(s,r[2],r[3],e.bottomRightInner,e.bottomLeftInner,i.left+i.width-n[1].width,i.top+i.height-n[2].width),L(s,r[3],r[0],e.bottomLeftInner,e.topLeftInner,i.left+n[3].width,i.top+i.height-n[2].width);break;default:L(s,r[0],r[1],e.topLeftOuter,e.topRightOuter,i.left,i.top),L(s,r[1],r[2],e.topRightOuter,e.bottomRightOuter,i.left+i.width,i.top),L(s,r[2],r[3],e.bottomRightOuter,e.bottomLeftOuter,i.left+i.width,i.top+i.height),L(s,r[3],r[0],e.bottomLeftOuter,e.topLeftOuter,i.left,i.top+i.height)}return s},I.prototype.pseudoHideClass="___html2canvas___pseudoelement",!function(){var r,i,o,s;!function(){var t={},e={};r=function(e,n,r){t[e]={deps:n,callback:r}},s=o=i=function(n){function r(t){if("."!==t.charAt(0))return t;for(var e=t.split("/"),r=n.split("/").slice(0,-1),i=0,o=e.length;o>i;i++){var s=e[i];if(".."===s)r.pop();else{if("."===s)continue;r.push(s)}}return r.join("/")}if(s._eak_seen=t,e[n])return e[n];if(e[n]={},!t[n])throw Error("Could not find module "+n);for(var o,a=t[n],c=a.deps,h=a.callback,u=[],p=0,d=c.length;d>p;p++)"exports"===c[p]?u.push(o={}):u.push(i(r(c[p])));var l=h.apply(this,u);return e[n]=o||l}}(),r("promise/all",["./utils","exports"],function(t,e){"use strict";function n(t){var e=this;if(!r(t))throw new TypeError("You must pass an array to all.");return new e(function(e,n){function r(t){return function(e){o(t,e)}}function o(t,n){a[t]=n,0===--c&&e(a)}var s,a=[],c=t.length;0===c&&e([]);for(var h=0;t.length>h;h++)s=t[h],s&&i(s.then)?s.then(r(h),n):o(h,s)})}var r=t.isArray,i=t.isFunction;e.all=n}),r("promise/asap",["exports"],function(r){"use strict";function i(){return function(){process.nextTick(a)}}function o(){var t=0,n=new p(a),r=e.createTextNode("");return n.observe(r,{characterData:!0}),function(){r.data=t=++t%2}}function s(){return function(){d.setTimeout(a,1)}}function a(){for(var t=0;l.length>t;t++){var e=l[t],n=e[0],r=e[1];n(r)}l=[]}function c(t,e){var n=l.push([t,e]);1===n&&h()}var h,u=t!==n?t:{},p=u.MutationObserver||u.WebKitMutationObserver,d="undefined"!=typeof global?global:this,l=[];h="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?i():p?o():s(),r.asap=c}),r("promise/cast",["exports"],function(t){"use strict";function e(t){if(t&&"object"==typeof t&&t.constructor===this)return t;var e=this;return new e(function(e){e(t)})}t.cast=e}),r("promise/config",["exports"],function(t){"use strict";function e(t,e){return 2!==arguments.length?n[t]:(n[t]=e,void 0)}var n={instrument:!1};t.config=n,t.configure=e}),r("promise/polyfill",["./promise","./utils","exports"],function(e,n,r){"use strict";function i(){var e="Promise"in t&&"cast"in t.Promise&&"resolve"in t.Promise&&"reject"in t.Promise&&"all"in t.Promise&&"race"in t.Promise&&function(){var e;return new t.Promise(function(t){e=t}),s(e)}();e||(t.Promise=o)}var o=e.Promise,s=n.isFunction;r.polyfill=i}),r("promise/promise",["./config","./utils","./cast","./all","./race","./resolve","./reject","./asap","exports"],function(t,e,n,r,i,o,s,a,c){"use strict";function h(t){if(!T(t))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 constructor cannot be called as a function.");this._subscribers=[],u(t,this)}function u(t,e){function n(t){g(e,t)}function r(t){y(e,t)}try{t(n,r)}catch(i){r(i)}}function p(t,e,n,r){var i,o,s,a,c=T(n);if(c)try{i=n(r),s=!0}catch(h){a=!0,o=h}else i=r,s=!0;f(e,i)||(c&&s?g(e,i):a?y(e,o):t===A?g(e,i):t===L&&y(e,i))}function d(t,e,n,r){var i=t._subscribers,o=i.length;i[o]=e,i[o+A]=n,i[o+L]=r}function l(t,e){for(var n,r,i=t._subscribers,o=t._detail,s=0;i.length>s;s+=3)n=i[s],r=i[s+e],p(e,n,r,o);t._subscribers=null}function f(t,e){var n,r=null;try{if(t===e)throw new TypeError("A promises callback cannot return that same promise.");if(x(e)&&(r=e.then,T(r)))return r.call(e,function(r){return n?!0:(n=!0,e!==r?g(t,r):m(t,r),void 0)},function(e){return n?!0:(n=!0,y(t,e),void 0)}),!0}catch(i){return n?!0:(y(t,i),!0)}return!1}function g(t,e){t===e?m(t,e):f(t,e)||m(t,e)}function m(t,e){t._state===B&&(t._state=O,t._detail=e,w.async(b,t))}function y(t,e){t._state===B&&(t._state=O,t._detail=e,w.async(v,t))}function b(t){l(t,t._state=A)}function v(t){l(t,t._state=L)}var w=t.config,x=(t.configure,e.objectOrFunction),T=e.isFunction,k=(e.now,n.cast),E=r.all,I=i.race,R=o.resolve,C=s.reject,S=a.asap;w.async=S;var B=void 0,O=0,A=1,L=2;h.prototype={constructor:h,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(t,e){var n=this,r=new this.constructor(function(){});if(this._state){var i=arguments;w.async(function(){p(n._state,r,i[n._state-1],n._detail)})}else d(this,r,t,e);return r},"catch":function(t){return this.then(null,t)}},h.all=E,h.cast=k,h.race=I,h.resolve=R,h.reject=C,c.Promise=h}),r("promise/race",["./utils","exports"],function(t,e){"use strict";function n(t){var e=this;if(!r(t))throw new TypeError("You must pass an array to race.");return new e(function(e,n){for(var r,i=0;t.length>i;i++)r=t[i],r&&"function"==typeof r.then?r.then(e,n):e(r)})}var r=t.isArray;e.race=n}),r("promise/reject",["exports"],function(t){"use strict";function e(t){var e=this;return new e(function(e,n){n(t)})}t.reject=e}),r("promise/resolve",["exports"],function(t){"use strict";function e(t){var e=this;return new e(function(e){e(t)})}t.resolve=e}),r("promise/utils",["exports"],function(t){"use strict";function e(t){return n(t)||"object"==typeof t&&null!==t}function n(t){return"function"==typeof t}function r(t){return"[object Array]"===Object.prototype.toString.call(t)}var i=Date.now||function(){return(new Date).getTime()};t.objectOrFunction=e,t.isFunction=n,t.isArray=r,t.now=i}),i("promise/polyfill").polyfill()}();var de=0;ie.prototype.renderImage=function(t,e,n,r){var i=t.cssInt("paddingLeft"),o=t.cssInt("paddingTop"),s=t.cssInt("paddingRight"),a=t.cssInt("paddingBottom"),c=n.borders;this.drawImage(r,0,0,r.width,r.height,e.left+i+c[3].width,e.top+o+c[0].width,e.width-(c[1].width+c[3].width+i+s),e.height-(c[0].width+c[2].width+o+a))},ie.prototype.renderBackground=function(t,e,n){e.height>0&&e.width>0&&(this.renderBackgroundColor(t,e),this.renderBackgroundImage(t,e,n))},ie.prototype.renderBackgroundColor=function(t,e){var n=t.css("backgroundColor");this.isTransparent(n)||this.rectangle(e.left,e.top,e.width,e.height,t.css("backgroundColor"))},ie.prototype.renderBorders=function(t){t.forEach(this.renderBorder,this)},ie.prototype.renderBorder=function(t){this.isTransparent(t.color)||null===t.args||this.drawShape(t.args,t.color)},ie.prototype.renderBackgroundImage=function(t,e,n){var r=t.parseBackgroundImages();r.reverse().forEach(function(r,i,o){switch(r.method){case"url":var s=this.images.get(r.args[0]);s?this.renderBackgroundRepeating(t,e,s,o.length-(i+1),n):m("Error loading background-image",r.args[0]);break;case"linear-gradient":case"gradient":var a=this.images.get(r.value);a?this.renderBackgroundGradient(a,e,n):m("Error loading background-image",r.args[0]);break;case"none":break;default:m("Unknown background-image type",r.args[0])}},this)},ie.prototype.renderBackgroundRepeating=function(t,e,n,r,i){var o=t.parseBackgroundSize(e,n.image,r),s=t.parseBackgroundPosition(e,n.image,r,o),a=t.parseBackgroundRepeat(r);switch(a){case"repeat-x":case"repeat no-repeat":this.backgroundRepeatShape(n,s,o,e,e.left+i[3],e.top+s.top+i[0],99999,n.image.height,i);break;case"repeat-y":case"no-repeat repeat":this.backgroundRepeatShape(n,s,o,e,e.left+s.left+i[3],e.top+i[0],n.image.width,99999,i);break;case"no-repeat":this.backgroundRepeatShape(n,s,o,e,e.left+s.left+i[3],e.top+s.top+i[0],n.image.width,n.image.height,i);break;default:this.renderBackgroundRepeat(n,s,o,{top:e.top,left:e.left},i[3],i[0])}},ie.prototype.isTransparent=function(t){return!t||"transparent"===t||"rgba(0, 0, 0, 0)"===t},oe.prototype=Object.create(ie.prototype),oe.prototype.setFillStyle=function(t){return this.ctx.fillStyle=t,this.ctx},oe.prototype.rectangle=function(t,e,n,r,i){this.setFillStyle(i).fillRect(t,e,n,r) +},oe.prototype.drawShape=function(t,e){this.shape(t),this.setFillStyle(e).fill()},oe.prototype.drawImage=function(t,e,n,r,i,o,s,a,c){this.ctx.drawImage(t,e,n,r,i,o,s,a,c)},oe.prototype.clip=function(t,e,n){this.ctx.save(),this.shape(t).clip(),e.call(n),this.ctx.restore()},oe.prototype.shape=function(t){return this.ctx.beginPath(),t.forEach(function(t,e){this.ctx[0===e?"moveTo":t[0]+"To"].apply(this.ctx,t.slice(1))},this),this.ctx.closePath(),this.ctx},oe.prototype.font=function(t,e,n,r,i,o){this.setFillStyle(t).font=[e,n,r,i,o].join(" ")},oe.prototype.fontShadow=function(t,e,n,r){this.setVariable("shadowColor",t).setVariable("shadowOffsetY",e).setVariable("shadowOffsetX",n).setVariable("shadowBlur",r)},oe.prototype.clearShadow=function(){this.setVariable("shadowColor","rgba(0,0,0,0)")},oe.prototype.setOpacity=function(t){this.ctx.globalAlpha=t},oe.prototype.setTransform=function(t){this.ctx.translate(t.origin[0],t.origin[1]),this.ctx.transform.apply(this.ctx,t.matrix),this.ctx.translate(-t.origin[0],-t.origin[1])},oe.prototype.setVariable=function(t,e){return this.variables[t]!==e&&(this.variables[t]=this.ctx[t]=e),this},oe.prototype.text=function(t,e,n){this.ctx.fillText(t,e,n)},oe.prototype.backgroundRepeatShape=function(t,e,n,r,i,o,s,a,c){var h=[["line",Math.round(i),Math.round(o)],["line",Math.round(i+s),Math.round(o)],["line",Math.round(i+s),Math.round(a+o)],["line",Math.round(i),Math.round(a+o)]];this.clip(h,function(){this.renderBackgroundRepeat(t,e,n,r,c[3],c[0])},this)},oe.prototype.renderBackgroundRepeat=function(t,e,n,r,i,o){var s=Math.round(r.left+e.left+i),a=Math.round(r.top+e.top+o);this.setFillStyle(this.ctx.createPattern(this.resizeImage(t,n),"repeat")),this.ctx.translate(s,a),this.ctx.fill(),this.ctx.translate(-s,-a)},oe.prototype.renderBackgroundGradient=function(t,e){t instanceof g&&this.ctx.createLinearGradient(e.left,e.top,e.right,e.bottom)},oe.prototype.resizeImage=function(t,n){var r=t.image;if(r.width===n.width&&r.height===n.height)return r;var i,o=e.createElement("canvas");return o.width=n.width,o.height=n.height,i=o.getContext("2d"),i.drawImage(r,0,0,r.width,r.height,0,0,n.width,n.height),o},se.prototype=Object.create(y.prototype),se.prototype.getParentStack=function(t){var e=this.parent?this.parent.stack:null;return e?e.ownStacking?e:e.getParentStack(t):t.stack},ae.prototype.testRangeBounds=function(t){var e,n,r,i,o=!1;return t.createRange&&(e=t.createRange(),e.getBoundingClientRect&&(n=t.createElement("boundtest"),n.style.height="123px",n.style.display="block",t.body.appendChild(n),e.selectNode(n),r=e.getBoundingClientRect(),i=r.height,123===i&&(o=!0),t.body.removeChild(n))),o},ae.prototype.testCORS=function(){return(new Image).crossOrigin!==n},ce.prototype=Object.create(y.prototype),ce.prototype.applyTextTransform=function(){this.node.data=this.transform(this.parent.css("textTransform"))},ce.prototype.transform=function(t){var e=this.node.data;switch(t){case"lowercase":return e.toLowerCase();case"capitalize":return e.replace(/(^|\s|:|-|\(|\))([a-z])/g,he);case"uppercase":return e.toUpperCase();default:return e}},ue.prototype=Object.create(u.prototype)})(window,document); \ No newline at end of file diff --git a/src/core.js b/src/core.js index 27d9d3d..6d6e35b 100644 --- a/src/core.js +++ b/src/core.js @@ -28,9 +28,9 @@ function renderDocument(document, options, windowWidth, windowHeight) { document.querySelector(selector).removeAttribute(html2canvasNodeAttribute); var clonedWindow = container.contentWindow; var node = clonedWindow.document.querySelector(selector); - var support = new Support(); + var support = new Support(clonedWindow.document); var imageLoader = new ImageLoader(options, support); - var bounds = NodeParser.prototype.getBounds(node); + var bounds = getBounds(node); var width = options.type === "view" ? Math.min(bounds.width, windowWidth) : documentWidth(); var height = options.type === "view" ? Math.min(bounds.height, windowHeight) : documentHeight(); var renderer = new CanvasRenderer(width, height, imageLoader); diff --git a/src/nodecontainer.js b/src/nodecontainer.js index e107ce8..253d3c7 100644 --- a/src/nodecontainer.js +++ b/src/nodecontainer.js @@ -3,6 +3,7 @@ function NodeContainer(node, parent) { this.parent = parent; this.stack = null; this.bounds = null; + this.offsetBounds = null; this.visible = null; this.computedStyles = null; this.styles = {}; @@ -160,19 +161,28 @@ NodeContainer.prototype.parseTextShadows = function() { NodeContainer.prototype.parseTransform = function() { var transformRegExp = /(matrix)\((.+)\)/; var transform = this.prefixedCss("transform"); - if (transform !== null && transform !== "none") { - var matrix = parseMatrix(transform.match(transformRegExp)); - if (matrix) { - return { - origin: this.prefixedCss("transformOrigin"), - matrix: matrix - }; - } + var matrix = parseMatrix(transform.match(transformRegExp)); + var offset = this.parseBounds(); + if (matrix) { + var origin = this.prefixedCss("transformOrigin").split(" ").map(removePx).map(asFloat); + origin[0] += offset.left; + origin[1] += offset.top; + + return { + origin: origin, + matrix: matrix + }; } - return { - origin: [0, 0], - matrix: [1, 0, 0, 1, 0, 0] - }; +}; + +NodeContainer.prototype.parseBounds = function() { + return this.bounds || (this.bounds = this.hasTransform() ? offsetBounds(this.node) : getBounds(this.node)); +}; + + +NodeContainer.prototype.hasTransform = function() { + var transform = this.prefixedCss("transform"); + return (transform !== null && transform !== "none" && transform !== "matrix(1, 0, 0, 1, 0, 0)"); }; NodeContainer.prototype.TEXT_SHADOW_PROPERTY = /((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g; @@ -286,3 +296,41 @@ function parseBackgrounds(backgroundImage) { appendResult(); return results; } + +function removePx(str) { + return str.replace("px", ""); +} + +function asFloat(str) { + return parseFloat(str); +} + +function getBounds(node) { + if (node.getBoundingClientRect) { + var clientRect = node.getBoundingClientRect(); + var isBody = node.nodeName === "BODY"; + var width = isBody ? node.scrollWidth : node.offsetWidth; + return { + top: clientRect.top, + bottom: clientRect.bottom || (clientRect.top + clientRect.height), + right: clientRect.left + width, + left: clientRect.left, + width: width, + height: isBody ? node.scrollHeight : node.offsetHeight + }; + } + return {}; +} + +function offsetBounds(node) { + var parent = node.offsetParent ? offsetBounds(node.offsetParent) : {top: 0, left: 0}; + + return { + top: node.offsetTop + parent.top, + bottom: node.offsetTop + node.offsetHeight + parent.top, + right: node.offsetLeft + parent.left + node.offsetWidth, + left: node.offsetLeft + parent.left, + width: node.offsetWidth, + height: node.offsetHeight + }; +} diff --git a/src/nodeparser.js b/src/nodeparser.js index cb0d1b3..9307296 100644 --- a/src/nodeparser.js +++ b/src/nodeparser.js @@ -134,7 +134,7 @@ NodeParser.prototype.newStackingContext = function(container, hasOwnStacking) { NodeParser.prototype.createStackingContexts = function() { this.nodes.forEach(function(container) { - if (isElement(container) && (this.isRootElement(container) || hasOpacity(container) || isPositionedForStacking(container) || this.isBodyWithTransparentRoot(container) || hasTransform(container))) { + if (isElement(container) && (this.isRootElement(container) || hasOpacity(container) || isPositionedForStacking(container) || this.isBodyWithTransparentRoot(container) || container.hasTransform())) { this.newStackingContext(container, true); } else if (isElement(container) && ((isPositioned(container) && zIndex0(container)) || isInlineBlock(container) || isFloating(container))) { this.newStackingContext(container, false); @@ -157,55 +157,33 @@ NodeParser.prototype.sortStackingContexts = function(stack) { stack.contexts.forEach(this.sortStackingContexts, this); }; -NodeParser.prototype.parseBounds = function(nodeContainer) { - return nodeContainer.bounds = this.getBounds(nodeContainer.node); -}; - -NodeParser.prototype.getBounds = function(node) { - if (node.getBoundingClientRect) { - var clientRect = node.getBoundingClientRect(); - var isBody = node.nodeName === "BODY"; - var width = isBody ? node.scrollWidth : node.offsetWidth; - return { - top: clientRect.top, - bottom: clientRect.bottom || (clientRect.top + clientRect.height), - right: clientRect.left + width, - left: clientRect.left, - width: width, - height: isBody ? node.scrollHeight : node.offsetHeight - }; - } - return {}; -}; - NodeParser.prototype.parseTextBounds = function(container) { return function(text, index, textList) { - if (container.parent.css("textDecoration") !== "none" || text.trim().length !== 0) { - if (this.support.rangeBounds) { + if (container.parent.css("textDecoration").substr(0, 4) !== "none" || text.trim().length !== 0) { + if (this.support.rangeBounds && !container.parent.hasTransform()) { var offset = textList.slice(0, index).join("").length; return this.getRangeBounds(container.node, offset, text.length); } else if (container.node && typeof(container.node.data) === "string") { var replacementNode = container.node.splitText(text.length); - var bounds = this.getWrapperBounds(container.node); + var bounds = this.getWrapperBounds(container.node, container.parent.hasTransform()); container.node = replacementNode; return bounds; } - } else if (!this.support.rangeBounds) { + } else if(!this.support.rangeBounds || container.parent.hasTransform()){ container.node = container.node.splitText(text.length); } return {}; }; }; -NodeParser.prototype.getWrapperBounds = function(node) { - var wrapper = node.ownerDocument.createElement('wrapper'); +NodeParser.prototype.getWrapperBounds = function(node, transform) { + var wrapper = node.ownerDocument.createElement('html2canvaswrapper'); var parent = node.parentNode, backupText = node.cloneNode(true); wrapper.appendChild(node.cloneNode(true)); parent.replaceChild(wrapper, node); - - var bounds = this.getBounds(wrapper); + var bounds = transform ? offsetBounds(wrapper) : getBounds(wrapper); parent.replaceChild(backupText, wrapper); return bounds; }; @@ -217,6 +195,8 @@ NodeParser.prototype.getRangeBounds = function(node, offset, length) { return range.getBoundingClientRect(); }; +function ClearTransform() {} + NodeParser.prototype.parse = function(stack) { // http://www.w3.org/TR/CSS21/visuren.html#z-index var negativeZindex = stack.contexts.filter(negativeZIndex); // 2. the child stacking contexts with negative stack levels (most negative first). @@ -233,13 +213,16 @@ NodeParser.prototype.parse = function(stack) { this.renderQueue.push(container); if (isStackingContext(container)) { this.parse(container); + this.renderQueue.push(new ClearTransform()); } }, this); }; NodeParser.prototype.paint = function(container) { try { - if (isTextNode(container)) { + if (container instanceof ClearTransform) { + this.renderer.ctx.restore(); + } else if (isTextNode(container)) { this.paintText(container); } else { this.paintNode(container); @@ -252,13 +235,12 @@ NodeParser.prototype.paint = function(container) { NodeParser.prototype.paintNode = function(container) { if (isStackingContext(container)) { this.renderer.setOpacity(container.opacity); - var transform = container.parseTransform(); - if (transform) { - this.renderer.setTransform(transform); + this.renderer.ctx.save(); + if (container.hasTransform()) { + this.renderer.setTransform(container.parseTransform()); } } - - var bounds = this.parseBounds(container); + var bounds = container.parseBounds(); var borderData = this.parseBorders(container); this.renderer.clip(borderData.clip, function() { this.renderer.renderBackground(container, bounds, borderData.borders.map(getWidth)); @@ -625,11 +607,6 @@ function hasOpacity(container) { return container.css("opacity") < 1; } -function hasTransform(container) { - var transform = container.prefixedCss("transform"); - return transform !== null && transform !== "none"; -} - function bind(callback, context) { return function() { return callback.apply(context, arguments); diff --git a/src/renderers/canvas.js b/src/renderers/canvas.js index c58f730..0c8661c 100644 --- a/src/renderers/canvas.js +++ b/src/renderers/canvas.js @@ -66,8 +66,8 @@ CanvasRenderer.prototype.setOpacity = function(opacity) { CanvasRenderer.prototype.setTransform = function(transform) { this.ctx.translate(transform.origin[0], transform.origin[1]); - this.ctx.setTransform.apply(this.ctx, transform.matrix); - this.ctx.translate(transform.origin[0], transform.origin[1]); + this.ctx.transform.apply(this.ctx, transform.matrix); + this.ctx.translate(-transform.origin[0], -transform.origin[1]); }; CanvasRenderer.prototype.setVariable = function(property, value) { diff --git a/src/support.js b/src/support.js index f4a95c5..0434635 100644 --- a/src/support.js +++ b/src/support.js @@ -1,9 +1,9 @@ -function Support() { - this.rangeBounds = this.testRangeBounds(); +function Support(document) { + this.rangeBounds = this.testRangeBounds(document); this.cors = this.testCORS(); } -Support.prototype.testRangeBounds = function() { +Support.prototype.testRangeBounds = function(document) { var range, testElement, rangeBounds, rangeHeight, support = false; if (document.createRange) { diff --git a/tests/cases/transform/nested.html b/tests/cases/transform/nested.html index 946d519..b523ad7 100644 --- a/tests/cases/transform/nested.html +++ b/tests/cases/transform/nested.html @@ -10,7 +10,7 @@ margin-top: 100px; } #second { - border: 10px solid red; + border: 15px solid red; background: darkseagreen; -webkit-transform: rotate(7.5deg); /* Chrome, Safari 3.1+ */ -moz-transform: rotate(7.5deg); /* Firefox 3.5-15 */ @@ -27,14 +27,19 @@ transform: rotate(-70.5deg); /* Firefox 16+, IE 10+, Opera 12.10+ */ } + #fourth { + background: #bc8f8f; + } + div { display: inline-block; - padding: 10px; + }
First level content
with second level content
and third level content
, ending second
, ending first
+
something else
diff --git a/tests/cases/transform/translate.html b/tests/cases/transform/translate.html new file mode 100644 index 0000000..86301b3 --- /dev/null +++ b/tests/cases/transform/translate.html @@ -0,0 +1,45 @@ + + + + Nested transform tests + + + + + + +
First level content
with second level content
and third level content
, ending second
, ending first
+ +