diff --git a/.code.js.swo b/.code.js.swo
new file mode 100644
index 0000000..a7ae1ba
Binary files /dev/null and b/.code.js.swo differ
diff --git a/.code.js.swp b/.code.js.swp
new file mode 100644
index 0000000..d09c1c0
Binary files /dev/null and b/.code.js.swp differ
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..434f4b4
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+cy_v1
\ No newline at end of file
diff --git a/.idea/cy_v1.iml b/.idea/cy_v1.iml
new file mode 100644
index 0000000..c956989
--- /dev/null
+++ b/.idea/cy_v1.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..99b1a92
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..3b31283
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..19f74da
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..3323ef2
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..6564d52
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..34483ab
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,457 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+ 1440617170231
+
+ 1440617170231
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/code.js b/code.js
new file mode 100644
index 0000000..631ca26
--- /dev/null
+++ b/code.js
@@ -0,0 +1,309 @@
+$(function () { // on dom ready
+
+ function onChange(event) {
+ var reader = new FileReader();
+ reader.onload = onReaderLoad;
+ reader.readAsText(event.target.files[0]);
+ }
+
+ function onReaderLoad(event) {
+ console.log(event.target.result);
+ var obj = JSON.parse(event.target.result);
+ visual_pathway(obj);
+ }
+
+ /*
+ function sendFileToServer(formData, status) {
+ var uploadURL = "http://localhost/pathway/cy_v1/index.php"; //Upload URL
+ var extraData = {}; //Extra Data.
+ var jqXHR = $.ajax({
+ xhr: function () {
+ var xhrobj = $.ajaxSettings.xhr();
+ if (xhrobj.upload) {
+ xhrobj.upload.addEventListener('progress', function (event) {
+ var percent = 0;
+ var position = event.loaded || event.position;
+ var total = event.total;
+ if (event.lengthComputable) {
+ percent = Math.ceil(position / total * 100);
+ }
+ //Set progress
+ status.setProgress(percent);
+ }, false);
+ }
+ return xhrobj;
+ },
+ url: uploadURL,
+ type: "POST",
+ contentType: false,
+ processData: false,
+ cache: false,
+ data: formData,
+ success: function (data) {
+ status.setProgress(100);
+ $("#information").html(data);
+ $("#status1").append("File upload Done
");
+ }
+ });
+
+ status.setAbort(jqXHR);
+ }
+
+ var rowCount = 0;
+
+ function createStatusbar(obj) {
+ rowCount++;
+ var row = "odd";
+ if (rowCount % 2 == 0) row = "even";
+ this.statusbar = $("
");
+ this.filename = $("").appendTo(this.statusbar);
+ this.size = $("").appendTo(this.statusbar);
+ this.progressBar = $("").appendTo(this.statusbar);
+ this.abort = $("Abort
").appendTo(this.statusbar);
+ obj.after(this.statusbar);
+
+ this.setFileNameSize = function (name, size) {
+ var sizeStr = "";
+ var sizeKB = size / 1024;
+ if (parseInt(sizeKB) > 1024) {
+ var sizeMB = sizeKB / 1024;
+ sizeStr = sizeMB.toFixed(2) + " MB";
+ }
+ else {
+ sizeStr = sizeKB.toFixed(2) + " KB";
+ }
+
+ this.filename.html(name);
+ this.size.html(sizeStr);
+ }
+ this.setProgress = function (progress) {
+ var progressBarWidth = progress * this.progressBar.width() / 100;
+ this.progressBar.find('div').animate({width: progressBarWidth}, 10).html(progress + "% ");
+ if (parseInt(progress) >= 100) {
+ this.abort.hide();
+ }
+ }
+ this.setAbort = function (jqxhr) {
+ var sb = this.statusbar;
+ this.abort.click(function () {
+ jqxhr.abort();
+ sb.hide();
+ });
+ }
+ }
+
+ function handleFileUpload(files, obj) {
+ for (var i = 0; i < files.length; i++) {
+ var fd = new FormData();
+ fd.append('file', files[i]);
+
+ var status = new createStatusbar(obj); //Using this we can set progress.
+ status.setFileNameSize(files[i].name, files[i].size);
+ sendFileToServer(fd, status);
+
+ }
+ }
+
+ var obj = $("#dragandrophandler");
+ obj.on('dragenter', function (e) {
+ e.stopPropagation();
+ e.preventDefault();
+ $(this).css('border', '2px solid #0B85A1');
+ });
+ obj.on('dragover', function (e) {
+ e.stopPropagation();
+ e.preventDefault();
+ });
+ obj.on('drop', function (e) {
+
+ $(this).css('border', '2px dotted #0B85A1');
+ e.preventDefault();
+ var files = e.originalEvent.dataTransfer.files;
+
+ //We need to send dropped files to Server
+ handleFileUpload(files, obj);
+ });
+ $(document).on('dragenter', function (e) {
+ e.stopPropagation();
+ e.preventDefault();
+ });
+ $(document).on('dragover', function (e) {
+ e.stopPropagation();
+ e.preventDefault();
+ obj.css('border', '2px dotted #0B85A1');
+ });
+ $(document).on('drop', function (e) {
+ e.stopPropagation();
+ e.preventDefault();
+ });
+
+ function addCircle(nodeId, circleText) {
+ console.log(nodeId, circleText);
+ var parentNode = cy.$('#' + nodeId);
+ if (parentNode.data('isCircle') || parentNode.data('circleId'))
+ return;
+ parentNode.lock();
+ var px = parentNode.position('x') + 10;
+ var py = parentNode.position('y') - 10;
+ var circleId = (cy.nodes().size() + 1).toString();
+ parentNode.data('circleId', circleId);
+ cy.add({
+ group: 'nodes',
+ data: {weight: 75, id: circleId, name: circleText, isCircle: true},
+ position: {x: px, y: py},
+ locked: true
+ }).css({
+ 'background-color': 'yellow',
+ 'shape': 'ellipse',
+ 'background-opacity': 0.5
+ }).unselectify();
+ }
+ */
+
+
+ //dCircle('1', 'Bubble A');
+
+ function visual_pathway(obj) {
+ $('#cy').cytoscape({
+ style: cytoscape.stylesheet()
+ .selector('node').css({
+ 'content': 'data(name)',
+ 'text-valign': 'center',
+ 'color': 'black',
+ 'padding-left': 2,
+ 'padding-right': 2,
+ 'font-family': 'data(LabelSize)',
+ 'background-color': 'white'
+ })
+ .selector('node[Type="GeneProduct"]').css({
+ 'shape': 'rectangle',
+ 'width': 'data(Width)',
+ 'height': 'data(Height)',
+ 'text-valign': 'middle',
+ 'background-color': 'white',
+ 'border-color': 'black',
+ 'border-width': 1
+ })
+ .selector('node[Type="Protein"]').css({
+ 'shape': 'rectangle',
+ 'width': 'data(Width)',
+ 'height': 'data(Height)',
+ 'background-color': 'white',
+ 'color': '#ff3333',
+ 'border-color': '#ff3333',
+ 'border-style': 'solid',
+ 'border-width': 1
+ })
+ .selector('node[Shape="Brace"]').css({
+ 'shape': 'rectangle',
+ 'width': '1',
+ 'height': 'data(Width)',
+ 'background-color': 'black',
+ 'color': 'black',
+ 'border-color': 'black',
+ 'border-style': 'solid',
+ 'border-width': 1
+ })
+ .selector('node[FillColor="ffffff"]').css({
+ 'background-color': 'white',
+ 'color': 'blue',
+ 'text-halign': 'center',
+ 'text-valign': 'top'
+ })
+ .selector('edge').css({
+ 'line-color': 'black',
+ 'line-style': 'solid',
+ 'width': 1
+ })
+ .selector('edge[LineStyle="Dashed"]').css({
+ 'line-style': 'dashed',
+ 'line-color': 'black',
+ 'background-color': 'black',
+ 'color': 'black'
+ })
+ .selector('edge[EndArrow="Arrow"]').css({
+ 'target-arrow-shape': 'triangle',
+ 'target-arrow-color': 'black',
+ 'target-arrow-fill': 'filled'
+ })
+ .selector('edge[EndArrow="TBar"]').css({
+ 'target-arrow-shape': 'tee',
+ 'target-arrow-color': 'black',
+ 'target-arrow-fill': 'filled'
+ })
+ .selector('edge[ConnectorType="Elbow"]').css({
+ 'line-color': 'yellow',
+ 'line-style': 'solid'
+ })
+ .selector('edge:selected').css({
+ 'background-color': 'black',
+ 'line-color': 'black',
+ 'target-arrow-color': 'black',
+ 'source-arrow-color': 'black'
+ })
+ .selector('node:selected').css({
+ 'width': 10
+ })
+ .selector('.faded').css({
+ 'opacity': 1,
+ 'text-opacity': 0
+ })
+ .selector('.green').css({
+ 'background-color': 'green',
+ 'color': 'black'
+ })
+ .selector('.red').css({
+ 'background-color': 'red',
+ 'color': 'white'
+ }),
+
+ elements: obj.elements,
+
+ layout: {
+ name: 'preset',
+ padding: 10
+ },
+ //style: {
+ // name: 'WikiPathways'
+ //},
+
+ // on graph initial layout done (could be async depending on layout...)
+
+
+ ready: function () {
+ window.cy = this;
+
+ cy.elements().unselectify();
+
+ var selectedNodes = [];
+ var counts = {};
+ var str_info;
+
+ //$('#information').append("You have selected:" + "
");
+
+ cy.off('click', 'node').on('click', 'node', function (e) {
+ e.preventDefault();
+
+ var node = this;
+
+ var node_name = node.data("shared_name");
+ var node_id = node.data("id");
+ //console.log(node_name);
+
+ if ($.inArray(node_name, selectedNodes) !== -1) {
+ node.addClass('red');
+ var old_html = $('#params').text;
+ console.log(old_html);
+ $('#params').append(node_name + ":" + "high" + "\n");
+ } else {
+ selectedNodes.push(node_name);
+ node.addClass('green');
+ $('#params').append(node_name + ":" + "low" + "\n");
+ }
+ });
+ }
+ });
+ }
+
+ document.getElementById('file').addEventListener('change', onChange);
+}); // on dom ready
diff --git a/code.js~ b/code.js~
new file mode 100644
index 0000000..f9eba4f
--- /dev/null
+++ b/code.js~
@@ -0,0 +1,79 @@
+$(function(){ // on dom ready
+
+$('#cy').cytoscape({
+ style: cytoscape.stylesheet()
+ .selector('node').css({
+ 'content': 'data(name)',
+ 'text-valign': 'center',
+ 'color': 'black',
+ 'text-outline-color': '#000'
+ })
+ .selector('edge').css({
+ 'target-arrow-shape': 'triangle'
+ })
+ .selector(':selected').css({
+ 'background-color': 'black',
+ 'line-color': 'black',
+ 'target-arrow-color': 'black',
+ 'source-arrow-color': 'black'
+ })
+ .selector('.faded').css({
+ 'opacity': 1,
+ 'text-opacity': 0
+ })
+ .selector('.green').css({
+ 'color': 'green'
+ })
+ .selector('.red').css({
+ 'color': 'red'
+ }),
+
+ elements: {
+ nodes: [
+ { data: { id: 'p53', name: 'p53' } },
+ { data: { id: 'MDM2', name: 'MDM2' } },
+ { data: { id: 'p14ARF', name: 'p14/ARF' } },
+ { data: { id: 'p21', name: 'p21' } },
+ { data: { id: 'Rb', name: 'Rb' } },
+ { data: { id: 'E2F', name: 'E2F' } },
+ { data: { id: 'CDK2', name: 'CDK2' } },
+ { data: { id: 'CKS1', name: 'CKS1' } },
+ { data: { id: 'Skp2', name: 'Skp2' } }
+ ],
+ edges: [
+ { data: { source: 'p53', target: 'p21' } },
+ { data: { source: 'MDM2', target: 'p53' } },
+ { data: { source: 'p14ARF', target: 'MDM2' } },
+ { data: { source: 'Rb', target: 'E2F' } },
+ { data: { source: 'CDK2', target: 'Rb' } },
+ { data: { source: 'CKS1', target: 'Skp2' } }
+ ]
+ },
+
+
+ layout: {
+ name: 'grid',
+ padding: 10
+ },
+
+ // on graph initial layout done (could be async depending on layout...)
+ ready: function(){
+
+ window.cy = this;
+
+ // giddy up...
+
+ cy.elements().unselectify();
+
+ cy.on('tap', 'node', function(e){
+ e.preventDefault();
+
+ var node = this;
+ console.log(node.position());
+ $('#information').append(node.id() + ', ');
+ node.addClass('green');
+ });
+ }
+});
+
+}); // on dom ready
diff --git a/database.png b/database.png
new file mode 100644
index 0000000..2f883a9
Binary files /dev/null and b/database.png differ
diff --git a/get.php b/get.php
new file mode 100644
index 0000000..b7cb468
--- /dev/null
+++ b/get.php
@@ -0,0 +1,10 @@
+'; print_r($params); echo '';
\ No newline at end of file
diff --git a/html2canvas.js b/html2canvas.js
new file mode 100644
index 0000000..c83e0e4
--- /dev/null
+++ b/html2canvas.js
@@ -0,0 +1,3667 @@
+/*
+ html2canvas 0.5.0-alpha1
+ Copyright (c) 2015 Niklas von Hertzen
+
+ Released under MIT License
+ */
+
+(function (window, document, exports, global, define, undefined) {
+
+ /*!
+ * @overview es6-promise - a tiny implementation of Promises/A+.
+ * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
+ * @license Licensed under MIT license
+ * See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE
+ * @version 2.0.1
+ */
+
+ (function () {
+ function r(a, b) {
+ n[l] = a;
+ n[l + 1] = b;
+ l += 2;
+ 2 === l && A()
+ }
+
+ function s(a) {
+ return "function" === typeof a
+ }
+
+ function F() {
+ return function () {
+ process.nextTick(t)
+ }
+ }
+
+ function G() {
+ var a = 0, b = new B(t), c = document.createTextNode("");
+ b.observe(c, {characterData: !0});
+ return function () {
+ c.data = a = ++a % 2
+ }
+ }
+
+ function H() {
+ var a = new MessageChannel;
+ a.port1.onmessage = t;
+ return function () {
+ a.port2.postMessage(0)
+ }
+ }
+
+ function I() {
+ return function () {
+ setTimeout(t, 1)
+ }
+ }
+
+ function t() {
+ for (var a = 0; a < l; a += 2)(0, n[a])(n[a + 1]), n[a] = void 0, n[a + 1] = void 0;
+ l = 0
+ }
+
+ function p() {
+ }
+
+ function J(a, b, c, d) {
+ try {
+ a.call(b, c, d)
+ } catch (e) {
+ return e
+ }
+ }
+
+ function K(a, b, c) {
+ r(function (a) {
+ var e = !1, f = J(c, b, function (c) {
+ e || (e = !0, b !== c ? q(a, c) : m(a, c))
+ }, function (b) {
+ e || (e = !0, g(a, b))
+ });
+ !e && f && (e = !0, g(a, f))
+ }, a)
+ }
+
+ function L(a, b) {
+ 1 === b.a ? m(a, b.b) : 2 === a.a ? g(a, b.b) : u(b, void 0, function (b) {
+ q(a, b)
+ }, function (b) {
+ g(a, b)
+ })
+ }
+
+ function q(a, b) {
+ if (a === b)g(a, new TypeError("You cannot resolve a promise with itself")); else if ("function" === typeof b || "object" === typeof b && null !== b)if (b.constructor === a.constructor)L(a,
+ b); else {
+ var c;
+ try {
+ c = b.then
+ } catch (d) {
+ v.error = d, c = v
+ }
+ c === v ? g(a, v.error) : void 0 === c ? m(a, b) : s(c) ? K(a, b, c) : m(a, b)
+ } else m(a, b)
+ }
+
+ function M(a) {
+ a.f && a.f(a.b);
+ x(a)
+ }
+
+ function m(a, b) {
+ void 0 === a.a && (a.b = b, a.a = 1, 0 !== a.e.length && r(x, a))
+ }
+
+ function g(a, b) {
+ void 0 === a.a && (a.a = 2, a.b = b, r(M, a))
+ }
+
+ function u(a, b, c, d) {
+ var e = a.e, f = e.length;
+ a.f = null;
+ e[f] = b;
+ e[f + 1] = c;
+ e[f + 2] = d;
+ 0 === f && a.a && r(x, a)
+ }
+
+ function x(a) {
+ var b = a.e, c = a.a;
+ if (0 !== b.length) {
+ for (var d, e, f = a.b, g = 0; g < b.length; g += 3)d = b[g], e = b[g + c], d ? C(c, d, e, f) : e(f);
+ a.e.length = 0
+ }
+ }
+
+ function D() {
+ this.error =
+ null
+ }
+
+ function C(a, b, c, d) {
+ var e = s(c), f, k, h, l;
+ if (e) {
+ try {
+ f = c(d)
+ } catch (n) {
+ y.error = n, f = y
+ }
+ f === y ? (l = !0, k = f.error, f = null) : h = !0;
+ if (b === f) {
+ g(b, new TypeError("A promises callback cannot return that same promise."));
+ return
+ }
+ } else f = d, h = !0;
+ void 0 === b.a && (e && h ? q(b, f) : l ? g(b, k) : 1 === a ? m(b, f) : 2 === a && g(b, f))
+ }
+
+ function N(a, b) {
+ try {
+ b(function (b) {
+ q(a, b)
+ }, function (b) {
+ g(a, b)
+ })
+ } catch (c) {
+ g(a, c)
+ }
+ }
+
+ function k(a, b, c, d) {
+ this.n = a;
+ this.c = new a(p, d);
+ this.i = c;
+ this.o(b) ? (this.m = b, this.d = this.length = b.length, this.l(), 0 === this.length ? m(this.c,
+ this.b) : (this.length = this.length || 0, this.k(), 0 === this.d && m(this.c, this.b))) : g(this.c, this.p())
+ }
+
+ function h(a) {
+ O++;
+ this.b = this.a = void 0;
+ this.e = [];
+ if (p !== a) {
+ if (!s(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");
+ if (!(this instanceof h))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
+ N(this, a)
+ }
+ }
+
+ var E = Array.isArray ? Array.isArray : function (a) {
+ return "[object Array]" ===
+ Object.prototype.toString.call(a)
+ }, l = 0, w = "undefined" !== typeof window ? window : {}, B = w.MutationObserver || w.WebKitMutationObserver, w = "undefined" !== typeof Uint8ClampedArray && "undefined" !== typeof importScripts && "undefined" !== typeof MessageChannel, n = Array(1E3), A;
+ A = "undefined" !== typeof process && "[object process]" === {}.toString.call(process) ? F() : B ? G() : w ? H() : I();
+ var v = new D, y = new D;
+ k.prototype.o = function (a) {
+ return E(a)
+ };
+ k.prototype.p = function () {
+ return Error("Array Methods must be provided an Array")
+ };
+ k.prototype.l =
+ function () {
+ this.b = Array(this.length)
+ };
+ k.prototype.k = function () {
+ for (var a = this.length, b = this.c, c = this.m, d = 0; void 0 === b.a && d < a; d++)this.j(c[d], d)
+ };
+ k.prototype.j = function (a, b) {
+ var c = this.n;
+ "object" === typeof a && null !== a ? a.constructor === c && void 0 !== a.a ? (a.f = null, this.g(a.a, b, a.b)) : this.q(c.resolve(a), b) : (this.d--, this.b[b] = this.h(a))
+ };
+ k.prototype.g = function (a, b, c) {
+ var d = this.c;
+ void 0 === d.a && (this.d--, this.i && 2 === a ? g(d, c) : this.b[b] = this.h(c));
+ 0 === this.d && m(d, this.b)
+ };
+ k.prototype.h = function (a) {
+ return a
+ };
+ k.prototype.q = function (a, b) {
+ var c = this;
+ u(a, void 0, function (a) {
+ c.g(1, b, a)
+ }, function (a) {
+ c.g(2, b, a)
+ })
+ };
+ var O = 0;
+ h.all = function (a, b) {
+ return (new k(this, a, !0, b)).c
+ };
+ h.race = function (a, b) {
+ function c(a) {
+ q(e, a)
+ }
+
+ function d(a) {
+ g(e, a)
+ }
+
+ var e = new this(p, b);
+ if (!E(a))return (g(e, new TypeError("You must pass an array to race.")), e);
+ for (var f = a.length, h = 0; void 0 === e.a && h < f; h++)u(this.resolve(a[h]), void 0, c, d);
+ return e
+ };
+ h.resolve = function (a, b) {
+ if (a && "object" === typeof a && a.constructor === this)return a;
+ var c = new this(p, b);
+ q(c, a);
+ return c
+ };
+ h.reject = function (a, b) {
+ var c = new this(p, b);
+ g(c, a);
+ return c
+ };
+ h.prototype = {
+ constructor: h, then: function (a, b) {
+ var c = this.a;
+ if (1 === c && !a || 2 === c && !b)return this;
+ var d = new this.constructor(p), e = this.b;
+ if (c) {
+ var f = arguments[c - 1];
+ r(function () {
+ C(c, d, f, e)
+ })
+ } else u(this, d, a, b);
+ return d
+ }, "catch": function (a) {
+ return this.then(null, a)
+ }
+ };
+ var z = {
+ Promise: h, polyfill: function () {
+ var a;
+ a = "undefined" !== typeof global ? global : "undefined" !== typeof window && window.document ? window : self;
+ "Promise"in a && "resolve"in
+ a.Promise && "reject"in a.Promise && "all"in a.Promise && "race"in a.Promise && function () {
+ var b;
+ new a.Promise(function (a) {
+ b = a
+ });
+ return s(b)
+ }() || (a.Promise = h)
+ }
+ };
+ "function" === typeof define && define.amd ? define(function () {
+ return z
+ }) : "undefined" !== typeof module && module.exports ? module.exports = z : "undefined" !== typeof this && (this.ES6Promise = z);
+ }).call(window);
+ if (window) {
+ window.ES6Promise.polyfill();
+ }
+
+
+ if (typeof(document) === "undefined" || typeof(Object.create) !== "function" || typeof(document.createElement("canvas").getContext) !== "function") {
+ (window || module.exports).html2canvas = function () {
+ return Promise.reject("No canvas support");
+ };
+ return;
+ }
+
+ /*! https://mths.be/punycode v1.3.1 by @mathias */
+ ;
+ (function (root) {
+
+ /** Detect free variables */
+ var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
+ var freeModule = typeof module == 'object' && module && !module.nodeType && module;
+ var freeGlobal = typeof global == 'object' && global;
+ if (
+ freeGlobal.global === freeGlobal ||
+ freeGlobal.window === freeGlobal ||
+ freeGlobal.self === freeGlobal
+ ) {
+ root = freeGlobal;
+ }
+
+ /**
+ * The `punycode` object.
+ * @name punycode
+ * @type Object
+ */
+ var punycode,
+
+ /** Highest positive signed 32-bit float value */
+ maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
+
+ /** Bootstring parameters */
+ base = 36,
+ tMin = 1,
+ tMax = 26,
+ skew = 38,
+ damp = 700,
+ initialBias = 72,
+ initialN = 128, // 0x80
+ delimiter = '-', // '\x2D'
+
+ /** Regular expressions */
+ regexPunycode = /^xn--/,
+ regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
+ regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
+
+ /** Error messages */
+ errors = {
+ 'overflow': 'Overflow: input needs wider integers to process',
+ 'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
+ 'invalid-input': 'Invalid input'
+ },
+
+ /** Convenience shortcuts */
+ baseMinusTMin = base - tMin,
+ floor = Math.floor,
+ stringFromCharCode = String.fromCharCode,
+
+ /** Temporary variable */
+ key;
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * A generic error utility function.
+ * @private
+ * @param {String} type The error type.
+ * @returns {Error} Throws a `RangeError` with the applicable error message.
+ */
+ function error(type) {
+ throw RangeError(errors[type]);
+ }
+
+ /**
+ * A generic `Array#map` utility function.
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} callback The function that gets called for every array
+ * item.
+ * @returns {Array} A new array of values returned by the callback function.
+ */
+ function map(array, fn) {
+ var length = array.length;
+ var result = [];
+ while (length--) {
+ result[length] = fn(array[length]);
+ }
+ return result;
+ }
+
+ /**
+ * A simple `Array#map`-like wrapper to work with domain name strings or email
+ * addresses.
+ * @private
+ * @param {String} domain The domain name or email address.
+ * @param {Function} callback The function that gets called for every
+ * character.
+ * @returns {Array} A new string of characters returned by the callback
+ * function.
+ */
+ function mapDomain(string, fn) {
+ var parts = string.split('@');
+ var result = '';
+ if (parts.length > 1) {
+ // In email addresses, only the domain name should be punycoded. Leave
+ // the local part (i.e. everything up to `@`) intact.
+ result = parts[0] + '@';
+ string = parts[1];
+ }
+ var labels = string.split(regexSeparators);
+ var encoded = map(labels, fn).join('.');
+ return result + encoded;
+ }
+
+ /**
+ * Creates an array containing the numeric code points of each Unicode
+ * character in the string. While JavaScript uses UCS-2 internally,
+ * this function will convert a pair of surrogate halves (each of which
+ * UCS-2 exposes as separate characters) into a single code point,
+ * matching UTF-16.
+ * @see `punycode.ucs2.encode`
+ * @see
+ * @memberOf punycode.ucs2
+ * @name decode
+ * @param {String} string The Unicode input string (UCS-2).
+ * @returns {Array} The new array of code points.
+ */
+ function ucs2decode(string) {
+ var output = [],
+ counter = 0,
+ length = string.length,
+ value,
+ extra;
+ while (counter < length) {
+ value = string.charCodeAt(counter++);
+ if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
+ // high surrogate, and there is a next character
+ extra = string.charCodeAt(counter++);
+ if ((extra & 0xFC00) == 0xDC00) { // low surrogate
+ output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
+ } else {
+ // unmatched surrogate; only append this code unit, in case the next
+ // code unit is the high surrogate of a surrogate pair
+ output.push(value);
+ counter--;
+ }
+ } else {
+ output.push(value);
+ }
+ }
+ return output;
+ }
+
+ /**
+ * Creates a string based on an array of numeric code points.
+ * @see `punycode.ucs2.decode`
+ * @memberOf punycode.ucs2
+ * @name encode
+ * @param {Array} codePoints The array of numeric code points.
+ * @returns {String} The new Unicode string (UCS-2).
+ */
+ function ucs2encode(array) {
+ return map(array, function (value) {
+ var output = '';
+ if (value > 0xFFFF) {
+ value -= 0x10000;
+ output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
+ value = 0xDC00 | value & 0x3FF;
+ }
+ output += stringFromCharCode(value);
+ return output;
+ }).join('');
+ }
+
+ /**
+ * Converts a basic code point into a digit/integer.
+ * @see `digitToBasic()`
+ * @private
+ * @param {Number} codePoint The basic numeric code point value.
+ * @returns {Number} The numeric value of a basic code point (for use in
+ * representing integers) in the range `0` to `base - 1`, or `base` if
+ * the code point does not represent a value.
+ */
+ function basicToDigit(codePoint) {
+ if (codePoint - 48 < 10) {
+ return codePoint - 22;
+ }
+ if (codePoint - 65 < 26) {
+ return codePoint - 65;
+ }
+ if (codePoint - 97 < 26) {
+ return codePoint - 97;
+ }
+ return base;
+ }
+
+ /**
+ * Converts a digit/integer into a basic code point.
+ * @see `basicToDigit()`
+ * @private
+ * @param {Number} digit The numeric value of a basic code point.
+ * @returns {Number} The basic code point whose value (when used for
+ * representing integers) is `digit`, which needs to be in the range
+ * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
+ * used; else, the lowercase form is used. The behavior is undefined
+ * if `flag` is non-zero and `digit` has no uppercase form.
+ */
+ function digitToBasic(digit, flag) {
+ // 0..25 map to ASCII a..z or A..Z
+ // 26..35 map to ASCII 0..9
+ return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
+ }
+
+ /**
+ * Bias adaptation function as per section 3.4 of RFC 3492.
+ * http://tools.ietf.org/html/rfc3492#section-3.4
+ * @private
+ */
+ function adapt(delta, numPoints, firstTime) {
+ var k = 0;
+ delta = firstTime ? floor(delta / damp) : delta >> 1;
+ delta += floor(delta / numPoints);
+ for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
+ delta = floor(delta / baseMinusTMin);
+ }
+ return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
+ }
+
+ /**
+ * Converts a Punycode string of ASCII-only symbols to a string of Unicode
+ * symbols.
+ * @memberOf punycode
+ * @param {String} input The Punycode string of ASCII-only symbols.
+ * @returns {String} The resulting string of Unicode symbols.
+ */
+ function decode(input) {
+ // Don't use UCS-2
+ var output = [],
+ inputLength = input.length,
+ out,
+ i = 0,
+ n = initialN,
+ bias = initialBias,
+ basic,
+ j,
+ index,
+ oldi,
+ w,
+ k,
+ digit,
+ t,
+ /** Cached calculation results */
+ baseMinusT;
+
+ // Handle the basic code points: let `basic` be the number of input code
+ // points before the last delimiter, or `0` if there is none, then copy
+ // the first basic code points to the output.
+
+ basic = input.lastIndexOf(delimiter);
+ if (basic < 0) {
+ basic = 0;
+ }
+
+ for (j = 0; j < basic; ++j) {
+ // if it's not a basic code point
+ if (input.charCodeAt(j) >= 0x80) {
+ error('not-basic');
+ }
+ output.push(input.charCodeAt(j));
+ }
+
+ // Main decoding loop: start just after the last delimiter if any basic code
+ // points were copied; start at the beginning otherwise.
+
+ for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
+
+ // `index` is the index of the next character to be consumed.
+ // Decode a generalized variable-length integer into `delta`,
+ // which gets added to `i`. The overflow checking is easier
+ // if we increase `i` as we go, then subtract off its starting
+ // value at the end to obtain `delta`.
+ for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
+
+ if (index >= inputLength) {
+ error('invalid-input');
+ }
+
+ digit = basicToDigit(input.charCodeAt(index++));
+
+ if (digit >= base || digit > floor((maxInt - i) / w)) {
+ error('overflow');
+ }
+
+ i += digit * w;
+ t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
+
+ if (digit < t) {
+ break;
+ }
+
+ baseMinusT = base - t;
+ if (w > floor(maxInt / baseMinusT)) {
+ error('overflow');
+ }
+
+ w *= baseMinusT;
+
+ }
+
+ out = output.length + 1;
+ bias = adapt(i - oldi, out, oldi == 0);
+
+ // `i` was supposed to wrap around from `out` to `0`,
+ // incrementing `n` each time, so we'll fix that now:
+ if (floor(i / out) > maxInt - n) {
+ error('overflow');
+ }
+
+ n += floor(i / out);
+ i %= out;
+
+ // Insert `n` at position `i` of the output
+ output.splice(i++, 0, n);
+
+ }
+
+ return ucs2encode(output);
+ }
+
+ /**
+ * Converts a string of Unicode symbols (e.g. a domain name label) to a
+ * Punycode string of ASCII-only symbols.
+ * @memberOf punycode
+ * @param {String} input The string of Unicode symbols.
+ * @returns {String} The resulting Punycode string of ASCII-only symbols.
+ */
+ function encode(input) {
+ var n,
+ delta,
+ handledCPCount,
+ basicLength,
+ bias,
+ j,
+ m,
+ q,
+ k,
+ t,
+ currentValue,
+ output = [],
+ /** `inputLength` will hold the number of code points in `input`. */
+ inputLength,
+ /** Cached calculation results */
+ handledCPCountPlusOne,
+ baseMinusT,
+ qMinusT;
+
+ // Convert the input in UCS-2 to Unicode
+ input = ucs2decode(input);
+
+ // Cache the length
+ inputLength = input.length;
+
+ // Initialize the state
+ n = initialN;
+ delta = 0;
+ bias = initialBias;
+
+ // Handle the basic code points
+ for (j = 0; j < inputLength; ++j) {
+ currentValue = input[j];
+ if (currentValue < 0x80) {
+ output.push(stringFromCharCode(currentValue));
+ }
+ }
+
+ handledCPCount = basicLength = output.length;
+
+ // `handledCPCount` is the number of code points that have been handled;
+ // `basicLength` is the number of basic code points.
+
+ // Finish the basic string - if it is not empty - with a delimiter
+ if (basicLength) {
+ output.push(delimiter);
+ }
+
+ // Main encoding loop:
+ while (handledCPCount < inputLength) {
+
+ // All non-basic code points < n have been handled already. Find the next
+ // larger one:
+ for (m = maxInt, j = 0; j < inputLength; ++j) {
+ currentValue = input[j];
+ if (currentValue >= n && currentValue < m) {
+ m = currentValue;
+ }
+ }
+
+ // Increase `delta` enough to advance the decoder's state to ,
+ // but guard against overflow
+ handledCPCountPlusOne = handledCPCount + 1;
+ if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
+ error('overflow');
+ }
+
+ delta += (m - n) * handledCPCountPlusOne;
+ n = m;
+
+ for (j = 0; j < inputLength; ++j) {
+ currentValue = input[j];
+
+ if (currentValue < n && ++delta > maxInt) {
+ error('overflow');
+ }
+
+ if (currentValue == n) {
+ // Represent delta as a generalized variable-length integer
+ for (q = delta, k = base; /* no condition */; k += base) {
+ t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
+ if (q < t) {
+ break;
+ }
+ qMinusT = q - t;
+ baseMinusT = base - t;
+ output.push(
+ stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
+ );
+ q = floor(qMinusT / baseMinusT);
+ }
+
+ output.push(stringFromCharCode(digitToBasic(q, 0)));
+ bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
+ delta = 0;
+ ++handledCPCount;
+ }
+ }
+
+ ++delta;
+ ++n;
+
+ }
+ return output.join('');
+ }
+
+ /**
+ * Converts a Punycode string representing a domain name or an email address
+ * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
+ * it doesn't matter if you call it on a string that has already been
+ * converted to Unicode.
+ * @memberOf punycode
+ * @param {String} input The Punycoded domain name or email address to
+ * convert to Unicode.
+ * @returns {String} The Unicode representation of the given Punycode
+ * string.
+ */
+ function toUnicode(input) {
+ return mapDomain(input, function (string) {
+ return regexPunycode.test(string)
+ ? decode(string.slice(4).toLowerCase())
+ : string;
+ });
+ }
+
+ /**
+ * Converts a Unicode string representing a domain name or an email address to
+ * Punycode. Only the non-ASCII parts of the domain name will be converted,
+ * i.e. it doesn't matter if you call it with a domain that's already in
+ * ASCII.
+ * @memberOf punycode
+ * @param {String} input The domain name or email address to convert, as a
+ * Unicode string.
+ * @returns {String} The Punycode representation of the given domain name or
+ * email address.
+ */
+ function toASCII(input) {
+ return mapDomain(input, function (string) {
+ return regexNonASCII.test(string)
+ ? 'xn--' + encode(string)
+ : string;
+ });
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /** Define the public API */
+ punycode = {
+ /**
+ * A string representing the current Punycode.js version number.
+ * @memberOf punycode
+ * @type String
+ */
+ 'version': '1.3.1',
+ /**
+ * An object of methods to convert from JavaScript's internal character
+ * representation (UCS-2) to Unicode code points, and back.
+ * @see
+ * @memberOf punycode
+ * @type Object
+ */
+ 'ucs2': {
+ 'decode': ucs2decode,
+ 'encode': ucs2encode
+ },
+ 'decode': decode,
+ 'encode': encode,
+ 'toASCII': toASCII,
+ 'toUnicode': toUnicode
+ };
+
+ /** Expose `punycode` */
+ // Some AMD build optimizers, like r.js, check for specific condition patterns
+ // like the following:
+ if (
+ typeof define == 'function' &&
+ typeof define.amd == 'object' &&
+ define.amd
+ ) {
+ define('punycode', function () {
+ return punycode;
+ });
+ } else if (freeExports && freeModule) {
+ if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+
+ freeModule.exports = punycode;
+ } else { // in Narwhal or RingoJS v0.7.0-
+ for (key in punycode) {
+ punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
+ }
+ }
+ } else { // in Rhino or a web browser
+ root.punycode = punycode;
+ }
+
+ }(this));
+
+ var html2canvasNodeAttribute = "data-html2canvas-node";
+ var html2canvasCanvasCloneAttribute = "data-html2canvas-canvas-clone";
+ var html2canvasCanvasCloneIndex = 0;
+ var html2canvasCloneIndex = 0;
+
+ window.html2canvas = function (nodeList, options) {
+ var index = html2canvasCloneIndex++;
+ options = options || {};
+ if (options.logging) {
+ window.html2canvas.logging = true;
+ window.html2canvas.start = Date.now();
+ }
+
+ options.async = typeof(options.async) === "undefined" ? true : options.async;
+ options.allowTaint = typeof(options.allowTaint) === "undefined" ? false : options.allowTaint;
+ options.removeContainer = typeof(options.removeContainer) === "undefined" ? true : options.removeContainer;
+ options.javascriptEnabled = typeof(options.javascriptEnabled) === "undefined" ? false : options.javascriptEnabled;
+ options.imageTimeout = typeof(options.imageTimeout) === "undefined" ? 10000 : options.imageTimeout;
+ options.renderer = typeof(options.renderer) === "function" ? options.renderer : CanvasRenderer;
+ options.strict = !!options.strict;
+
+ if (typeof(nodeList) === "string") {
+ if (typeof(options.proxy) !== "string") {
+ return Promise.reject("Proxy must be used when rendering url");
+ }
+ var width = options.width != null ? options.width : window.innerWidth;
+ var height = options.height != null ? options.height : window.innerHeight;
+ return loadUrlDocument(absoluteUrl(nodeList), options.proxy, document, width, height, options).then(function (container) {
+ return renderWindow(container.contentWindow.document.documentElement, container, options, width, height);
+ });
+ }
+
+ var node = ((nodeList === undefined) ? [document.documentElement] : ((nodeList.length) ? nodeList : [nodeList]))[0];
+ node.setAttribute(html2canvasNodeAttribute + index, index);
+ return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function (canvas) {
+ if (typeof(options.onrendered) === "function") {
+ log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");
+ options.onrendered(canvas);
+ }
+ return canvas;
+ });
+ };
+
+ window.html2canvas.punycode = this.punycode;
+ window.html2canvas.proxy = {};
+
+ function renderDocument(document, options, windowWidth, windowHeight, html2canvasIndex) {
+ return createWindowClone(document, document, windowWidth, windowHeight, options, document.defaultView.pageXOffset, document.defaultView.pageYOffset).then(function (container) {
+ log("Document cloned");
+ var attributeName = html2canvasNodeAttribute + html2canvasIndex;
+ var selector = "[" + attributeName + "='" + html2canvasIndex + "']";
+ document.querySelector(selector).removeAttribute(attributeName);
+ var clonedWindow = container.contentWindow;
+ var node = clonedWindow.document.querySelector(selector);
+ var oncloneHandler = (typeof(options.onclone) === "function") ? Promise.resolve(options.onclone(clonedWindow.document)) : Promise.resolve(true);
+ return oncloneHandler.then(function () {
+ return renderWindow(node, container, options, windowWidth, windowHeight);
+ });
+ });
+ }
+
+ function renderWindow(node, container, options, windowWidth, windowHeight) {
+ var clonedWindow = container.contentWindow;
+ var support = new Support(clonedWindow.document);
+ var imageLoader = new ImageLoader(options, support);
+ var bounds = getBounds(node);
+ var width = options.type === "view" ? windowWidth : documentWidth(clonedWindow.document);
+ var height = options.type === "view" ? windowHeight : documentHeight(clonedWindow.document);
+ var renderer = new options.renderer(width, height, imageLoader, options, document);
+ var parser = new NodeParser(node, renderer, support, imageLoader, options);
+ return parser.ready.then(function () {
+ log("Finished rendering");
+ var canvas;
+
+ if (options.type === "view") {
+ canvas = crop(renderer.canvas, {
+ width: renderer.canvas.width,
+ height: renderer.canvas.height,
+ top: 0,
+ left: 0,
+ x: 0,
+ y: 0
+ });
+ } else if (node === clonedWindow.document.body || node === clonedWindow.document.documentElement || options.canvas != null) {
+ canvas = renderer.canvas;
+ } else {
+ canvas = crop(renderer.canvas, {
+ width: options.width != null ? options.width : bounds.width,
+ height: options.height != null ? options.height : bounds.height,
+ top: bounds.top,
+ left: bounds.left,
+ x: clonedWindow.pageXOffset,
+ y: clonedWindow.pageYOffset
+ });
+ }
+
+ cleanupContainer(container, options);
+ return canvas;
+ });
+ }
+
+ function cleanupContainer(container, options) {
+ if (options.removeContainer) {
+ container.parentNode.removeChild(container);
+ log("Cleaned up container");
+ }
+ }
+
+ function crop(canvas, bounds) {
+ var croppedCanvas = document.createElement("canvas");
+ var x1 = Math.min(canvas.width - 1, Math.max(0, bounds.left));
+ var x2 = Math.min(canvas.width, Math.max(1, bounds.left + bounds.width));
+ var y1 = Math.min(canvas.height - 1, Math.max(0, bounds.top));
+ var y2 = Math.min(canvas.height, Math.max(1, bounds.top + bounds.height));
+ croppedCanvas.width = bounds.width;
+ croppedCanvas.height = bounds.height;
+ log("Cropping canvas at:", "left:", bounds.left, "top:", bounds.top, "width:", (x2 - x1), "height:", (y2 - y1));
+ log("Resulting crop with width", bounds.width, "and height", bounds.height, " with x", x1, "and y", y1);
+ croppedCanvas.getContext("2d").drawImage(canvas, x1, y1, x2 - x1, y2 - y1, bounds.x, bounds.y, x2 - x1, y2 - y1);
+ return croppedCanvas;
+ }
+
+ function documentWidth(doc) {
+ return Math.max(
+ Math.max(doc.body.scrollWidth, doc.documentElement.scrollWidth),
+ Math.max(doc.body.offsetWidth, doc.documentElement.offsetWidth),
+ Math.max(doc.body.clientWidth, doc.documentElement.clientWidth)
+ );
+ }
+
+ function documentHeight(doc) {
+ return Math.max(
+ Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight),
+ Math.max(doc.body.offsetHeight, doc.documentElement.offsetHeight),
+ Math.max(doc.body.clientHeight, doc.documentElement.clientHeight)
+ );
+ }
+
+ function smallImage() {
+ return "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
+ }
+
+ function isIE9() {
+ return document.documentMode && document.documentMode <= 9;
+ }
+
+// https://github.com/niklasvh/html2canvas/issues/503
+ function cloneNodeIE9(node, javascriptEnabled) {
+ var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);
+
+ var child = node.firstChild;
+ while (child) {
+ if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') {
+ clone.appendChild(cloneNodeIE9(child, javascriptEnabled));
+ }
+ child = child.nextSibling;
+ }
+
+ return clone;
+ }
+
+ function createWindowClone(ownerDocument, containerDocument, width, height, options, x, y) {
+ labelCanvasElements(ownerDocument);
+ var documentElement = isIE9() ? cloneNodeIE9(ownerDocument.documentElement, options.javascriptEnabled) : ownerDocument.documentElement.cloneNode(true);
+ var container = containerDocument.createElement("iframe");
+
+ container.className = "html2canvas-container";
+ container.style.visibility = "hidden";
+ container.style.position = "fixed";
+ container.style.left = "-10000px";
+ container.style.top = "0px";
+ container.style.border = "0";
+ container.width = width;
+ container.height = height;
+ container.scrolling = "no"; // ios won't scroll without it
+ containerDocument.body.appendChild(container);
+
+ return new Promise(function (resolve) {
+ var documentClone = container.contentWindow.document;
+
+ cloneNodeValues(ownerDocument.documentElement, documentElement, "textarea");
+ cloneNodeValues(ownerDocument.documentElement, documentElement, "select");
+
+ /* Chrome doesn't detect relative background-images assigned in inline
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+