/**
 * @license
 * Copyright (c) 2018 amCharts (Antanas Marcelionis, Martynas Majeris)
 *
 * This sofware is provided under multiple licenses. Please see below for
 * links to appropriate usage.
 *
 * Free amCharts linkware license. Details and conditions:
 * https://github.com/amcharts/amcharts4/blob/master/LICENSE
 *
 * One of the amCharts commercial licenses. Details and pricing:
 * https://www.amcharts.com/online-store/
 * https://www.amcharts.com/online-store/licenses-explained/
 *
 * If in doubt, contact amCharts at contact@amcharts.com
 *
 * PLEASE DO NOT REMOVE THIS COPYRIGHT NOTICE.
 * @hidden
 */
am4internal_webpackJsonp(["71c9"], {
    "/Im6": function(t, e, i) {
        (function(t) { var r = r || { version: "3.3.0" }; if (e.fabric = r, "undefined" != typeof document && "undefined" != typeof window) document instanceof("undefined" != typeof HTMLDocument ? HTMLDocument : Document) ? r.document = document : r.document = document.implementation.createHTMLDocument(""), r.window = window;
            else { var n = new(i("M4QQ").JSDOM)(decodeURIComponent("%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E"), { features: { FetchExternalResources: ["img"] }, resources: "usable" }).window;
                r.document = n.document, r.jsdomImplForWrapper = i(0).implForWrapper, r.nodeCanvas = i(1).Canvas, r.window = n, DOMParser = r.window.DOMParser }

            function s(t, e) { var i = t.canvas,
                    r = e.targetCanvas,
                    n = r.getContext("2d");
                n.translate(0, r.height), n.scale(1, -1); var s = i.height - r.height;
                n.drawImage(i, 0, s, r.width, r.height, 0, 0, r.width, r.height) }

            function o(t, e) { var i = e.targetCanvas.getContext("2d"),
                    r = e.destinationWidth,
                    n = e.destinationHeight,
                    s = r * n * 4,
                    o = new Uint8Array(this.imageBuffer, 0, s),
                    a = new Uint8ClampedArray(this.imageBuffer, 0, s);
                t.readPixels(0, 0, r, n, t.RGBA, t.UNSIGNED_BYTE, o); var h = new ImageData(a, r, n);
                i.putImageData(h, 0, 0) } r.isTouchSupported = "ontouchstart" in r.window || "ontouchstart" in r.document || r.window && r.window.navigator && r.window.navigator.maxTouchPoints > 0, r.isLikelyNode = void 0 !== t && "undefined" == typeof window, r.SHARED_ATTRIBUTES = ["display", "transform", "fill", "fill-opacity", "fill-rule", "opacity", "stroke", "stroke-dasharray", "stroke-linecap", "stroke-dashoffset", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "id", "paint-order", "vector-effect", "instantiated_by_use", "clip-path"], r.DPI = 96, r.reNum = "(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:[eE][-+]?\\d+)?)", r.fontPaths = {}, r.iMatrix = [1, 0, 0, 1, 0, 0], r.perfLimitSizeTotal = 2097152, r.maxCacheSideLimit = 4096, r.minCacheSideLimit = 256, r.charWidthsCache = {}, r.textureSize = 2048, r.disableStyleCopyPaste = !1, r.enableGLFiltering = !0, r.devicePixelRatio = r.window.devicePixelRatio || r.window.webkitDevicePixelRatio || r.window.mozDevicePixelRatio || 1, r.browserShadowBlurConstant = 1, r.arcToSegmentsCache = {}, r.boundsOfCurveCache = {}, r.cachesBoundsOfCurve = !0, r.forceGLPutImageData = !1, r.initFilterBackend = function() { return r.enableGLFiltering && r.isWebglSupported && r.isWebglSupported(r.textureSize) ? (console.log("max texture size: " + r.maxTextureSize), new r.WebglFilterBackend({ tileSize: r.textureSize })) : r.Canvas2dFilterBackend ? new r.Canvas2dFilterBackend : void 0 },
                function() {
                    function t(t, e) { if (this.__eventListeners[t]) { var i = this.__eventListeners[t];
                            e ? i[i.indexOf(e)] = !1 : r.util.array.fill(i, !1) } }

                    function e(t, e) { if (this.__eventListeners || (this.__eventListeners = {}), 1 === arguments.length)
                            for (var i in t) this.on(i, t[i]);
                        else this.__eventListeners[t] || (this.__eventListeners[t] = []), this.__eventListeners[t].push(e); return this }

                    function i(e, i) { if (!this.__eventListeners) return this; if (0 === arguments.length)
                            for (e in this.__eventListeners) t.call(this, e);
                        else if (1 === arguments.length && "object" == typeof arguments[0])
                            for (var r in e) t.call(this, r, e[r]);
                        else t.call(this, e, i); return this }

                    function n(t, e) { if (!this.__eventListeners) return this; var i = this.__eventListeners[t]; if (!i) return this; for (var r = 0, n = i.length; r < n; r++) i[r] && i[r].call(this, e || {}); return this.__eventListeners[t] = i.filter(function(t) { return !1 !== t }), this } r.Observable = { observe: e, stopObserving: i, fire: n, on: e, off: i, trigger: n } }(), r.Collection = { _objects: [], add: function() { if (this._objects.push.apply(this._objects, arguments), this._onObjectAdded)
                            for (var t = 0, e = arguments.length; t < e; t++) this._onObjectAdded(arguments[t]); return this.renderOnAddRemove && this.requestRenderAll(), this }, insertAt: function(t, e, i) { var r = this._objects; return i ? r[e] = t : r.splice(e, 0, t), this._onObjectAdded && this._onObjectAdded(t), this.renderOnAddRemove && this.requestRenderAll(), this }, remove: function() { for (var t, e = this._objects, i = !1, r = 0, n = arguments.length; r < n; r++) - 1 !== (t = e.indexOf(arguments[r])) && (i = !0, e.splice(t, 1), this._onObjectRemoved && this._onObjectRemoved(arguments[r])); return this.renderOnAddRemove && i && this.requestRenderAll(), this }, forEachObject: function(t, e) { for (var i = this.getObjects(), r = 0, n = i.length; r < n; r++) t.call(e, i[r], r, i); return this }, getObjects: function(t) { return void 0 === t ? this._objects.concat() : this._objects.filter(function(e) { return e.type === t }) }, item: function(t) { return this._objects[t] }, isEmpty: function() { return 0 === this._objects.length }, size: function() { return this._objects.length }, contains: function(t) { return this._objects.indexOf(t) > -1 }, complexity: function() { return this._objects.reduce(function(t, e) { return t += e.complexity ? e.complexity() : 0 }, 0) } }, r.CommonMethods = { _setOptions: function(t) { for (var e in t) this.set(e, t[e]) }, _initGradient: function(t, e) {!t || !t.colorStops || t instanceof r.Gradient || this.set(e, new r.Gradient(t)) }, _initPattern: function(t, e, i) {!t || !t.source || t instanceof r.Pattern ? i && i() : this.set(e, new r.Pattern(t, i)) }, _initClipping: function(t) { if (t.clipTo && "string" == typeof t.clipTo) { var e = r.util.getFunctionBody(t.clipTo);
                            void 0 !== e && (this.clipTo = new Function("ctx", e)) } }, _setObject: function(t) { for (var e in t) this._set(e, t[e]) }, set: function(t, e) { return "object" == typeof t ? this._setObject(t) : "function" == typeof e && "clipTo" !== t ? this._set(t, e(this.get(t))) : this._set(t, e), this }, _set: function(t, e) { this[t] = e }, toggle: function(t) { var e = this.get(t); return "boolean" == typeof e && this.set(t, !e), this }, get: function(t) { return this[t] } },
                function(t) { var e = Math.sqrt,
                        i = Math.atan2,
                        n = Math.pow,
                        s = Math.abs,
                        o = Math.PI / 180,
                        a = Math.PI / 2;
                    r.util = { cos: function(t) { if (0 === t) return 1; switch (t < 0 && (t = -t), t / a) {
                                case 1:
                                case 3:
                                    return 0;
                                case 2:
                                    return -1 } return Math.cos(t) }, sin: function(t) { if (0 === t) return 0; var e = 1; switch (t < 0 && (e = -1), t / a) {
                                case 1:
                                    return e;
                                case 2:
                                    return 0;
                                case 3:
                                    return -e } return Math.sin(t) }, removeFromArray: function(t, e) { var i = t.indexOf(e); return -1 !== i && t.splice(i, 1), t }, getRandomInt: function(t, e) { return Math.floor(Math.random() * (e - t + 1)) + t }, degreesToRadians: function(t) { return t * o }, radiansToDegrees: function(t) { return t / o }, rotatePoint: function(t, e, i) { t.subtractEquals(e); var n = r.util.rotateVector(t, i); return new r.Point(n.x, n.y).addEquals(e) }, rotateVector: function(t, e) { var i = r.util.sin(e),
                                n = r.util.cos(e); return { x: t.x * n - t.y * i, y: t.x * i + t.y * n } }, transformPoint: function(t, e, i) { return i ? new r.Point(e[0] * t.x + e[2] * t.y, e[1] * t.x + e[3] * t.y) : new r.Point(e[0] * t.x + e[2] * t.y + e[4], e[1] * t.x + e[3] * t.y + e[5]) }, makeBoundingBoxFromPoints: function(t) { var e = [t[0].x, t[1].x, t[2].x, t[3].x],
                                i = r.util.array.min(e),
                                n = r.util.array.max(e) - i,
                                s = [t[0].y, t[1].y, t[2].y, t[3].y],
                                o = r.util.array.min(s); return { left: i, top: o, width: n, height: r.util.array.max(s) - o } }, invertTransform: function(t) { var e = 1 / (t[0] * t[3] - t[1] * t[2]),
                                i = [e * t[3], -e * t[1], -e * t[2], e * t[0]],
                                n = r.util.transformPoint({ x: t[4], y: t[5] }, i, !0); return i[4] = -n.x, i[5] = -n.y, i }, toFixed: function(t, e) { return parseFloat(Number(t).toFixed(e)) }, parseUnit: function(t, e) { var i = /\D{0,2}$/.exec(t),
                                n = parseFloat(t); switch (e || (e = r.Text.DEFAULT_SVG_FONT_SIZE), i[0]) {
                                case "mm":
                                    return n * r.DPI / 25.4;
                                case "cm":
                                    return n * r.DPI / 2.54;
                                case "in":
                                    return n * r.DPI;
                                case "pt":
                                    return n * r.DPI / 72;
                                case "pc":
                                    return n * r.DPI / 72 * 12;
                                case "em":
                                    return n * e;
                                default:
                                    return n } }, falseFunction: function() { return !1 }, getKlass: function(t, e) { return t = r.util.string.camelize(t.charAt(0).toUpperCase() + t.slice(1)), r.util.resolveNamespace(e)[t] }, getSvgAttributes: function(t) { var e = ["instantiated_by_use", "style", "id", "class"]; switch (t) {
                                case "linearGradient":
                                    e = e.concat(["x1", "y1", "x2", "y2", "gradientUnits", "gradientTransform"]); break;
                                case "radialGradient":
                                    e = e.concat(["gradientUnits", "gradientTransform", "cx", "cy", "r", "fx", "fy", "fr"]); break;
                                case "stop":
                                    e = e.concat(["offset", "stop-color", "stop-opacity"]) } return e }, resolveNamespace: function(e) { if (!e) return r; var i, n = e.split("."),
                                s = n.length,
                                o = t || r.window; for (i = 0; i < s; ++i) o = o[n[i]]; return o }, loadImage: function(t, e, i, n) { if (t) { var s = r.util.createImage(),
                                    o = function() { e && e.call(i, s), s = s.onload = s.onerror = null };
                                s.onload = o, s.onerror = function() { r.log("Error loading " + s.src), e && e.call(i, null, !0), s = s.onload = s.onerror = null }, 0 !== t.indexOf("data") && n && (s.crossOrigin = n), "data:image/svg" === t.substring(0, 14) && (s.onload = null, r.util.loadImageInDom(s, o)), s.src = t } else e && e.call(i, t) }, loadImageInDom: function(t, e) { var i = r.document.createElement("div");
                            i.style.width = i.style.height = "1px", i.style.left = i.style.top = "-100%", i.style.position = "absolute", i.appendChild(t), r.document.querySelector("body").appendChild(i), t.onload = function() { e(), i.parentNode.removeChild(i), i = null } }, enlivenObjects: function(t, e, i, n) { var s = [],
                                o = 0,
                                a = (t = t || []).length;

                            function h() {++o === a && e && e(s.filter(function(t) { return t })) } a ? t.forEach(function(t, e) { t && t.type ? r.util.getKlass(t.type, i).fromObject(t, function(i, r) { r || (s[e] = i), n && n(t, i, r), h() }) : h() }) : e && e(s) }, enlivenPatterns: function(t, e) {
                            function i() {++s === o && e && e(n) } var n = [],
                                s = 0,
                                o = (t = t || []).length;
                            o ? t.forEach(function(t, e) { t && t.source ? new r.Pattern(t, function(t) { n[e] = t, i() }) : (n[e] = t, i()) }) : e && e(n) }, groupSVGElements: function(t, e, i) { var n; return t && 1 === t.length ? t[0] : (e && (e.width && e.height ? e.centerPoint = { x: e.width / 2, y: e.height / 2 } : (delete e.width, delete e.height)), n = new r.Group(t, e), void 0 !== i && (n.sourcePath = i), n) }, populateWithProperties: function(t, e, i) { if (i && "[object Array]" === Object.prototype.toString.call(i))
                                for (var r = 0, n = i.length; r < n; r++) i[r] in t && (e[i[r]] = t[i[r]]) }, drawDashedLine: function(t, r, n, s, o, a) { var h = s - r,
                                c = o - n,
                                l = e(h * h + c * c),
                                u = i(c, h),
                                f = a.length,
                                d = 0,
                                g = !0; for (t.save(), t.translate(r, n), t.moveTo(0, 0), t.rotate(u), r = 0; l > r;)(r += a[d++ % f]) > l && (r = l), t[g ? "lineTo" : "moveTo"](r, 0), g = !g;
                            t.restore() }, createCanvasElement: function() { return r.document.createElement("canvas") }, copyCanvasElement: function(t) { var e = r.util.createCanvasElement(); return e.width = t.width, e.height = t.height, e.getContext("2d").drawImage(t, 0, 0), e }, toDataURL: function(t, e, i) { return t.toDataURL("image/" + e, i) }, createImage: function() { return r.document.createElement("img") }, clipContext: function(t, e) { e.save(), e.beginPath(), t.clipTo(e), e.clip() }, multiplyTransformMatrices: function(t, e, i) { return [t[0] * e[0] + t[2] * e[1], t[1] * e[0] + t[3] * e[1], t[0] * e[2] + t[2] * e[3], t[1] * e[2] + t[3] * e[3], i ? 0 : t[0] * e[4] + t[2] * e[5] + t[4], i ? 0 : t[1] * e[4] + t[3] * e[5] + t[5]] }, qrDecompose: function(t) { var r = i(t[1], t[0]),
                                s = n(t[0], 2) + n(t[1], 2),
                                a = e(s),
                                h = (t[0] * t[3] - t[2] * t[1]) / a,
                                c = i(t[0] * t[2] + t[1] * t[3], s); return { angle: r / o, scaleX: a, scaleY: h, skewX: c / o, skewY: 0, translateX: t[4], translateY: t[5] } }, customTransformMatrix: function(t, e, i) { var n = [1, 0, s(Math.tan(i * o)), 1],
                                a = [s(t), 0, 0, s(e)]; return r.util.multiplyTransformMatrices(a, n, !0) }, resetObjectTransform: function(t) { t.scaleX = 1, t.scaleY = 1, t.skewX = 0, t.skewY = 0, t.flipX = !1, t.flipY = !1, t.rotate(0) }, saveObjectTransform: function(t) { return { scaleX: t.scaleX, scaleY: t.scaleY, skewX: t.skewX, skewY: t.skewY, angle: t.angle, left: t.left, flipX: t.flipX, flipY: t.flipY, top: t.top } }, getFunctionBody: function(t) { return (String(t).match(/function[^{]*\{([\s\S]*)\}/) || {})[1] }, isTransparent: function(t, e, i, r) { r > 0 && (e > r ? e -= r : e = 0, i > r ? i -= r : i = 0); var n, s = !0,
                                o = t.getImageData(e, i, 2 * r || 1, 2 * r || 1),
                                a = o.data.length; for (n = 3; n < a && !1 !== (s = o.data[n] <= 0); n += 4); return o = null, s }, parsePreserveAspectRatioAttribute: function(t) { var e, i = "meet",
                                r = t.split(" "); return r && r.length && ("meet" !== (i = r.pop()) && "slice" !== i ? (e = i, i = "meet") : r.length && (e = r.pop())), { meetOrSlice: i, alignX: "none" !== e ? e.slice(1, 4) : "none", alignY: "none" !== e ? e.slice(5, 8) : "none" } }, clearFabricFontCache: function(t) {
                            (t = (t || "").toLowerCase()) ? r.charWidthsCache[t] && delete r.charWidthsCache[t]: r.charWidthsCache = {} }, limitDimsByArea: function(t, e) { var i = Math.sqrt(e * t),
                                r = Math.floor(e / i); return { x: Math.floor(i), y: r } }, capValue: function(t, e, i) { return Math.max(t, Math.min(e, i)) }, findScaleToFit: function(t, e) { return Math.min(e.width / t.width, e.height / t.height) }, findScaleToCover: function(t, e) { return Math.max(e.width / t.width, e.height / t.height) }, matrixToSVG: function(t) { return "matrix(" + t.map(function(t) { return r.util.toFixed(t, r.Object.NUM_FRACTION_DIGITS) }).join(" ") + ")" } } }(e),
                function() { var t = Array.prototype.join;

                    function e(e, s, o, a, h, c, l) { var u = t.call(arguments); if (r.arcToSegmentsCache[u]) return r.arcToSegmentsCache[u]; var f = Math.PI,
                            d = l * f / 180,
                            g = r.util.sin(d),
                            p = r.util.cos(d),
                            v = 0,
                            m = 0,
                            _ = -p * e * .5 - g * s * .5,
                            y = -p * s * .5 + g * e * .5,
                            b = (o = Math.abs(o)) * o,
                            x = (a = Math.abs(a)) * a,
                            C = y * y,
                            w = _ * _,
                            S = b * x - b * C - x * w,
                            T = 0; if (S < 0) { var O = Math.sqrt(1 - S / (b * x));
                            o *= O, a *= O } else T = (h === c ? -1 : 1) * Math.sqrt(S / (b * C + x * w)); var k = T * o * y / a,
                            P = -T * a * _ / o,
                            E = p * k - g * P + .5 * e,
                            A = g * k + p * P + .5 * s,
                            D = n(1, 0, (_ - k) / o, (y - P) / a),
                            j = n((_ - k) / o, (y - P) / a, (-_ - k) / o, (-y - P) / a);
                        0 === c && j > 0 ? j -= 2 * f : 1 === c && j < 0 && (j += 2 * f); for (var M = Math.ceil(Math.abs(j / f * 2)), F = [], I = j / M, B = 8 / 3 * Math.sin(I / 4) * Math.sin(I / 4) / Math.sin(I / 2), L = D + I, R = 0; R < M; R++) F[R] = i(D, L, p, g, o, a, E, A, B, v, m), v = F[R][4], m = F[R][5], D = L, L += I; return r.arcToSegmentsCache[u] = F, F }

                    function i(t, e, i, n, s, o, a, h, c, l, u) { var f = r.util.cos(t),
                            d = r.util.sin(t),
                            g = r.util.cos(e),
                            p = r.util.sin(e),
                            v = i * s * g - n * o * p + a,
                            m = n * s * g + i * o * p + h; return [l + c * (-i * s * d - n * o * f), u + c * (-n * s * d + i * o * f), v + c * (i * s * p + n * o * g), m + c * (n * s * p - i * o * g), v, m] }

                    function n(t, e, i, r) { var n = Math.atan2(e, t),
                            s = Math.atan2(r, i); return s >= n ? s - n : 2 * Math.PI - (n - s) }

                    function s(e, i, n, s, o, a, h, c) { var l; if (r.cachesBoundsOfCurve && (l = t.call(arguments), r.boundsOfCurveCache[l])) return r.boundsOfCurveCache[l]; var u, f, d, g, p, v, m, _, y = Math.sqrt,
                            b = Math.min,
                            x = Math.max,
                            C = Math.abs,
                            w = [],
                            S = [
                                [],
                                []
                            ];
                        f = 6 * e - 12 * n + 6 * o, u = -3 * e + 9 * n - 9 * o + 3 * h, d = 3 * n - 3 * e; for (var T = 0; T < 2; ++T)
                            if (T > 0 && (f = 6 * i - 12 * s + 6 * a, u = -3 * i + 9 * s - 9 * a + 3 * c, d = 3 * s - 3 * i), C(u) < 1e-12) { if (C(f) < 1e-12) continue;
                                0 < (g = -d / f) && g < 1 && w.push(g) } else(m = f * f - 4 * d * u) < 0 || (0 < (p = (-f + (_ = y(m))) / (2 * u)) && p < 1 && w.push(p), 0 < (v = (-f - _) / (2 * u)) && v < 1 && w.push(v)); for (var O, k, P, E = w.length, A = E; E--;) O = (P = 1 - (g = w[E])) * P * P * e + 3 * P * P * g * n + 3 * P * g * g * o + g * g * g * h, S[0][E] = O, k = P * P * P * i + 3 * P * P * g * s + 3 * P * g * g * a + g * g * g * c, S[1][E] = k;
                        S[0][A] = e, S[1][A] = i, S[0][A + 1] = h, S[1][A + 1] = c; var D = [{ x: b.apply(null, S[0]), y: b.apply(null, S[1]) }, { x: x.apply(null, S[0]), y: x.apply(null, S[1]) }]; return r.cachesBoundsOfCurve && (r.boundsOfCurveCache[l] = D), D } r.util.drawArc = function(t, i, r, n) { for (var s = n[0], o = n[1], a = n[2], h = n[3], c = n[4], l = [
                                [],
                                [],
                                [],
                                []
                            ], u = e(n[5] - i, n[6] - r, s, o, h, c, a), f = 0, d = u.length; f < d; f++) l[f][0] = u[f][0] + i, l[f][1] = u[f][1] + r, l[f][2] = u[f][2] + i, l[f][3] = u[f][3] + r, l[f][4] = u[f][4] + i, l[f][5] = u[f][5] + r, t.bezierCurveTo.apply(t, l[f]) }, r.util.getBoundsOfArc = function(t, i, r, n, o, a, h, c, l) { for (var u, f = 0, d = 0, g = [], p = e(c - t, l - i, r, n, a, h, o), v = 0, m = p.length; v < m; v++) u = s(f, d, p[v][0], p[v][1], p[v][2], p[v][3], p[v][4], p[v][5]), g.push({ x: u[0].x + t, y: u[0].y + i }), g.push({ x: u[1].x + t, y: u[1].y + i }), f = p[v][4], d = p[v][5]; return g }, r.util.getBoundsOfCurve = s }(),
                function() { var t = Array.prototype.slice;

                    function e(t, e, i) { if (t && 0 !== t.length) { var r = t.length - 1,
                                n = e ? t[r][e] : t[r]; if (e)
                                for (; r--;) i(t[r][e], n) && (n = t[r][e]);
                            else
                                for (; r--;) i(t[r], n) && (n = t[r]); return n } } r.util.array = { fill: function(t, e) { for (var i = t.length; i--;) t[i] = e; return t }, invoke: function(e, i) { for (var r = t.call(arguments, 2), n = [], s = 0, o = e.length; s < o; s++) n[s] = r.length ? e[s][i].apply(e[s], r) : e[s][i].call(e[s]); return n }, min: function(t, i) { return e(t, i, function(t, e) { return t < e }) }, max: function(t, i) { return e(t, i, function(t, e) { return t >= e }) } } }(),
                function() {
                    function t(e, i, n) { if (n)
                            if (!r.isLikelyNode && i instanceof Element) e = i;
                            else if (i instanceof Array) { e = []; for (var s = 0, o = i.length; s < o; s++) e[s] = t({}, i[s], n) } else if (i && "object" == typeof i)
                            for (var a in i) "canvas" === a ? e[a] = t({}, i[a]) : i.hasOwnProperty(a) && (e[a] = t({}, i[a], n));
                        else e = i;
                        else
                            for (var a in i) e[a] = i[a]; return e } r.util.object = { extend: t, clone: function(e, i) { return t({}, e, i) } }, r.util.object.extend(r.util, r.Observable) }(),
                function() {
                    function t(t, e) { var i = t.charCodeAt(e); if (isNaN(i)) return ""; if (i < 55296 || i > 57343) return t.charAt(e); if (55296 <= i && i <= 56319) { if (t.length <= e + 1) throw "High surrogate without following low surrogate"; var r = t.charCodeAt(e + 1); if (56320 > r || r > 57343) throw "High surrogate without following low surrogate"; return t.charAt(e) + t.charAt(e + 1) } if (0 === e) throw "Low surrogate without preceding high surrogate"; var n = t.charCodeAt(e - 1); if (55296 > n || n > 56319) throw "Low surrogate without preceding high surrogate"; return !1 } r.util.string = { camelize: function(t) { return t.replace(/-+(.)?/g, function(t, e) { return e ? e.toUpperCase() : "" }) }, capitalize: function(t, e) { return t.charAt(0).toUpperCase() + (e ? t.slice(1) : t.slice(1).toLowerCase()) }, escapeXml: function(t) { return t.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/'/g, "&apos;").replace(/</g, "&lt;").replace(/>/g, "&gt;") }, graphemeSplit: function(e) { var i, r = 0,
                                n = []; for (r = 0; r < e.length; r++) !1 !== (i = t(e, r)) && n.push(i); return n } } }(),
                function() { var t = Array.prototype.slice,
                        e = function() {},
                        i = function() { for (var t in { toString: 1 })
                                if ("toString" === t) return !1; return !0 }(),
                        n = function(t, e, r) { for (var n in e) n in t.prototype && "function" == typeof t.prototype[n] && (e[n] + "").indexOf("callSuper") > -1 ? t.prototype[n] = function(t) { return function() { var i = this.constructor.superclass;
                                    this.constructor.superclass = r; var n = e[t].apply(this, arguments); if (this.constructor.superclass = i, "initialize" !== t) return n } }(n) : t.prototype[n] = e[n], i && (e.toString !== Object.prototype.toString && (t.prototype.toString = e.toString), e.valueOf !== Object.prototype.valueOf && (t.prototype.valueOf = e.valueOf)) };

                    function s() {}

                    function o(e) { for (var i = null, r = this; r.constructor.superclass;) { var n = r.constructor.superclass.prototype[e]; if (r[e] !== n) { i = n; break } r = r.constructor.superclass.prototype } return i ? arguments.length > 1 ? i.apply(this, t.call(arguments, 1)) : i.call(this) : console.log("tried to callSuper " + e + ", method not found in prototype chain", this) } r.util.createClass = function() { var i = null,
                            r = t.call(arguments, 0);

                        function a() { this.initialize.apply(this, arguments) } "function" == typeof r[0] && (i = r.shift()), a.superclass = i, a.subclasses = [], i && (s.prototype = i.prototype, a.prototype = new s, i.subclasses.push(a)); for (var h = 0, c = r.length; h < c; h++) n(a, r[h], i); return a.prototype.initialize || (a.prototype.initialize = e), a.prototype.constructor = a, a.prototype.callSuper = o, a } }(),
                function() { var t = !!r.document.createElement("div").attachEvent;
                    r.util.addListener = function(e, i, r, n) { e && e.addEventListener(i, r, !t && n) }, r.util.removeListener = function(e, i, r, n) { e && e.removeEventListener(i, r, !t && n) }, r.util.getPointer = function(t) { var e = t.target,
                            i = r.util.getScrollLeftTop(e),
                            n = function(t) { var e = t.changedTouches; return e && e[0] ? e[0] : t }(t); return { x: n.clientX + i.left, y: n.clientY + i.top } } }(),
                function() { var t = r.document.createElement("div"),
                        e = "string" == typeof t.style.opacity,
                        i = "string" == typeof t.style.filter,
                        n = /alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,
                        s = function(t) { return t };
                    e ? s = function(t, e) { return t.style.opacity = e, t } : i && (s = function(t, e) { var i = t.style; return t.currentStyle && !t.currentStyle.hasLayout && (i.zoom = 1), n.test(i.filter) ? (e = e >= .9999 ? "" : "alpha(opacity=" + 100 * e + ")", i.filter = i.filter.replace(n, e)) : i.filter += " alpha(opacity=" + 100 * e + ")", t }), r.util.setStyle = function(t, e) { var i = t.style; if (!i) return t; if ("string" == typeof e) return t.style.cssText += ";" + e, e.indexOf("opacity") > -1 ? s(t, e.match(/opacity:\s*(\d?\.?\d*)/)[1]) : t; for (var r in e) "opacity" === r ? s(t, e[r]) : i["float" === r || "cssFloat" === r ? void 0 === i.styleFloat ? "cssFloat" : "styleFloat" : r] = e[r]; return t } }(),
                function() { var t = Array.prototype.slice; var e, i, n = function(e) { return t.call(e, 0) }; try { e = n(r.document.childNodes) instanceof Array } catch (t) {}

                    function s(t, e) { var i = r.document.createElement(t); for (var n in e) "class" === n ? i.className = e[n] : "for" === n ? i.htmlFor = e[n] : i.setAttribute(n, e[n]); return i }

                    function o(t) { for (var e = 0, i = 0, n = r.document.documentElement, s = r.document.body || { scrollLeft: 0, scrollTop: 0 }; t && (t.parentNode || t.host) && ((t = t.parentNode || t.host) === r.document ? (e = s.scrollLeft || n.scrollLeft || 0, i = s.scrollTop || n.scrollTop || 0) : (e += t.scrollLeft || 0, i += t.scrollTop || 0), 1 !== t.nodeType || "fixed" !== t.style.position);); return { left: e, top: i } } e || (n = function(t) { for (var e = new Array(t.length), i = t.length; i--;) e[i] = t[i]; return e }), i = r.document.defaultView && r.document.defaultView.getComputedStyle ? function(t, e) { var i = r.document.defaultView.getComputedStyle(t, null); return i ? i[e] : void 0 } : function(t, e) { var i = t.style[e]; return !i && t.currentStyle && (i = t.currentStyle[e]), i },
                        function() { var t = r.document.documentElement.style,
                                e = "userSelect" in t ? "userSelect" : "MozUserSelect" in t ? "MozUserSelect" : "WebkitUserSelect" in t ? "WebkitUserSelect" : "KhtmlUserSelect" in t ? "KhtmlUserSelect" : "";
                            r.util.makeElementUnselectable = function(t) { return void 0 !== t.onselectstart && (t.onselectstart = r.util.falseFunction), e ? t.style[e] = "none" : "string" == typeof t.unselectable && (t.unselectable = "on"), t }, r.util.makeElementSelectable = function(t) { return void 0 !== t.onselectstart && (t.onselectstart = null), e ? t.style[e] = "" : "string" == typeof t.unselectable && (t.unselectable = ""), t } }(),
                        function() { r.util.getScript = function(t, e) { var i = r.document.getElementsByTagName("head")[0],
                                    n = r.document.createElement("script"),
                                    s = !0;
                                n.onload = n.onreadystatechange = function(t) { if (s) { if ("string" == typeof this.readyState && "loaded" !== this.readyState && "complete" !== this.readyState) return;
                                        s = !1, e(t || r.window.event), n = n.onload = n.onreadystatechange = null } }, n.src = t, i.appendChild(n) } }(), r.util.getById = function(t) { return "string" == typeof t ? r.document.getElementById(t) : t }, r.util.toArray = n, r.util.makeElement = s, r.util.addClass = function(t, e) { t && -1 === (" " + t.className + " ").indexOf(" " + e + " ") && (t.className += (t.className ? " " : "") + e) }, r.util.wrapElement = function(t, e, i) { return "string" == typeof e && (e = s(e, i)), t.parentNode && t.parentNode.replaceChild(e, t), e.appendChild(t), e }, r.util.getScrollLeftTop = o, r.util.getElementOffset = function(t) { var e, r, n = t && t.ownerDocument,
                                s = { left: 0, top: 0 },
                                a = { left: 0, top: 0 },
                                h = { borderLeftWidth: "left", borderTopWidth: "top", paddingLeft: "left", paddingTop: "top" }; if (!n) return a; for (var c in h) a[h[c]] += parseInt(i(t, c), 10) || 0; return e = n.documentElement, void 0 !== t.getBoundingClientRect && (s = t.getBoundingClientRect()), r = o(t), { left: s.left + r.left - (e.clientLeft || 0) + a.left, top: s.top + r.top - (e.clientTop || 0) + a.top } }, r.util.getElementStyle = i, r.util.getNodeCanvas = function(t) { var e = r.jsdomImplForWrapper(t); return e._canvas || e._image }, r.util.cleanUpJsdomNode = function(t) { if (r.isLikelyNode) { var e = r.jsdomImplForWrapper(t);
                                e && (e._image = null, e._canvas = null, e._currentSrc = null, e._attributes = null, e._classList = null) } } }(),
                function() {
                    function t() {} r.util.request = function(e, i) { i || (i = {}); var n = i.method ? i.method.toUpperCase() : "GET",
                            s = i.onComplete || function() {},
                            o = new r.window.XMLHttpRequest,
                            a = i.body || i.parameters; return o.onreadystatechange = function() { 4 === o.readyState && (s(o), o.onreadystatechange = t) }, "GET" === n && (a = null, "string" == typeof i.parameters && (e = function(t, e) { return t + (/\?/.test(t) ? "&" : "?") + e }(e, i.parameters))), o.open(n, e, !0), "POST" !== n && "PUT" !== n || o.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"), o.send(a), o } }(), r.log = function() {}, r.warn = function() {}, "undefined" != typeof console && ["log", "warn"].forEach(function(t) { void 0 !== console[t] && "function" == typeof console[t].apply && (r[t] = function() { return console[t].apply(console, arguments) }) }),
                function() {
                    function t() { return !1 } var e = r.window.requestAnimationFrame || r.window.webkitRequestAnimationFrame || r.window.mozRequestAnimationFrame || r.window.oRequestAnimationFrame || r.window.msRequestAnimationFrame || function(t) { return r.window.setTimeout(t, 1e3 / 60) },
                        i = r.window.cancelAnimationFrame || r.window.clearTimeout;

                    function n() { return e.apply(r.window, arguments) } r.util.animate = function(e) { n(function(i) { e || (e = {}); var r, s = i || +new Date,
                                o = e.duration || 500,
                                a = s + o,
                                h = e.onChange || t,
                                c = e.abort || t,
                                l = e.onComplete || t,
                                u = e.easing || function(t, e, i, r) { return -i * Math.cos(t / r * (Math.PI / 2)) + i + e },
                                f = "startValue" in e ? e.startValue : 0,
                                d = "endValue" in e ? e.endValue : 100,
                                g = e.byValue || d - f;
                            e.onStart && e.onStart(),
                                function t(i) { if (c()) l(d, 1, 1);
                                    else { var p = (r = i || +new Date) > a ? o : r - s,
                                            v = p / o,
                                            m = u(p, f, g, o),
                                            _ = Math.abs((m - f) / g);
                                        h(m, _, v), r > a ? e.onComplete && e.onComplete() : n(t) } }(s) }) }, r.util.requestAnimFrame = n, r.util.cancelAnimFrame = function() { return i.apply(r.window, arguments) } }(),
                function() { r.util.animateColor = function(t, e, i, n) { var s = new r.Color(t).getSource(),
                            o = new r.Color(e).getSource();
                        n = n || {}, r.util.animate(r.util.object.extend(n, { duration: i || 500, startValue: s, endValue: o, byValue: o, easing: function(t, e, i, r) { return function(t, e, i) { var r = "rgba(" + parseInt(t[0] + i * (e[0] - t[0]), 10) + "," + parseInt(t[1] + i * (e[1] - t[1]), 10) + "," + parseInt(t[2] + i * (e[2] - t[2]), 10); return r += "," + (t && e ? parseFloat(t[3] + i * (e[3] - t[3])) : 1), r += ")" }(e, i, n.colorEasing ? n.colorEasing(t, r) : 1 - Math.cos(t / r * (Math.PI / 2))) } })) } }(),
                function() {
                    function t(t, e, i, r) { return t < Math.abs(e) ? (t = e, r = i / 4) : r = 0 === e && 0 === t ? i / (2 * Math.PI) * Math.asin(1) : i / (2 * Math.PI) * Math.asin(e / t), { a: t, c: e, p: i, s: r } }

                    function e(t, e, i) { return t.a * Math.pow(2, 10 * (e -= 1)) * Math.sin((e * i - t.s) * (2 * Math.PI) / t.p) }

                    function i(t, e, i, r) { return i - n(r - t, 0, i, r) + e }

                    function n(t, e, i, r) { return (t /= r) < 1 / 2.75 ? i * (7.5625 * t * t) + e : t < 2 / 2.75 ? i * (7.5625 * (t -= 1.5 / 2.75) * t + .75) + e : t < 2.5 / 2.75 ? i * (7.5625 * (t -= 2.25 / 2.75) * t + .9375) + e : i * (7.5625 * (t -= 2.625 / 2.75) * t + .984375) + e } r.util.ease = { easeInQuad: function(t, e, i, r) { return i * (t /= r) * t + e }, easeOutQuad: function(t, e, i, r) { return -i * (t /= r) * (t - 2) + e }, easeInOutQuad: function(t, e, i, r) { return (t /= r / 2) < 1 ? i / 2 * t * t + e : -i / 2 * (--t * (t - 2) - 1) + e }, easeInCubic: function(t, e, i, r) { return i * (t /= r) * t * t + e }, easeOutCubic: function(t, e, i, r) { return i * ((t = t / r - 1) * t * t + 1) + e }, easeInOutCubic: function(t, e, i, r) { return (t /= r / 2) < 1 ? i / 2 * t * t * t + e : i / 2 * ((t -= 2) * t * t + 2) + e }, easeInQuart: function(t, e, i, r) { return i * (t /= r) * t * t * t + e }, easeOutQuart: function(t, e, i, r) { return -i * ((t = t / r - 1) * t * t * t - 1) + e }, easeInOutQuart: function(t, e, i, r) { return (t /= r / 2) < 1 ? i / 2 * t * t * t * t + e : -i / 2 * ((t -= 2) * t * t * t - 2) + e }, easeInQuint: function(t, e, i, r) { return i * (t /= r) * t * t * t * t + e }, easeOutQuint: function(t, e, i, r) { return i * ((t = t / r - 1) * t * t * t * t + 1) + e }, easeInOutQuint: function(t, e, i, r) { return (t /= r / 2) < 1 ? i / 2 * t * t * t * t * t + e : i / 2 * ((t -= 2) * t * t * t * t + 2) + e }, easeInSine: function(t, e, i, r) { return -i * Math.cos(t / r * (Math.PI / 2)) + i + e }, easeOutSine: function(t, e, i, r) { return i * Math.sin(t / r * (Math.PI / 2)) + e }, easeInOutSine: function(t, e, i, r) { return -i / 2 * (Math.cos(Math.PI * t / r) - 1) + e }, easeInExpo: function(t, e, i, r) { return 0 === t ? e : i * Math.pow(2, 10 * (t / r - 1)) + e }, easeOutExpo: function(t, e, i, r) { return t === r ? e + i : i * (1 - Math.pow(2, -10 * t / r)) + e }, easeInOutExpo: function(t, e, i, r) { return 0 === t ? e : t === r ? e + i : (t /= r / 2) < 1 ? i / 2 * Math.pow(2, 10 * (t - 1)) + e : i / 2 * (2 - Math.pow(2, -10 * --t)) + e }, easeInCirc: function(t, e, i, r) { return -i * (Math.sqrt(1 - (t /= r) * t) - 1) + e }, easeOutCirc: function(t, e, i, r) { return i * Math.sqrt(1 - (t = t / r - 1) * t) + e }, easeInOutCirc: function(t, e, i, r) { return (t /= r / 2) < 1 ? -i / 2 * (Math.sqrt(1 - t * t) - 1) + e : i / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + e }, easeInElastic: function(i, r, n, s) { var o = 0; return 0 === i ? r : 1 == (i /= s) ? r + n : (o || (o = .3 * s), -e(t(n, n, o, 1.70158), i, s) + r) }, easeOutElastic: function(e, i, r, n) { var s = 0,
                                o = r; if (0 === e) return i; if (1 == (e /= n)) return i + r;
                            s || (s = .3 * n); var a = t(o, r, s, 1.70158); return a.a * Math.pow(2, -10 * e) * Math.sin((e * n - a.s) * (2 * Math.PI) / a.p) + a.c + i }, easeInOutElastic: function(i, r, n, s) { var o = 0,
                                a = n; if (0 === i) return r; if (2 == (i /= s / 2)) return r + n;
                            o || (o = s * (.3 * 1.5)); var h = t(a, n, o, 1.70158); return i < 1 ? -.5 * e(h, i, s) + r : h.a * Math.pow(2, -10 * (i -= 1)) * Math.sin((i * s - h.s) * (2 * Math.PI) / h.p) * .5 + h.c + r }, easeInBack: function(t, e, i, r, n) { return void 0 === n && (n = 1.70158), i * (t /= r) * t * ((n + 1) * t - n) + e }, easeOutBack: function(t, e, i, r, n) { return void 0 === n && (n = 1.70158), i * ((t = t / r - 1) * t * ((n + 1) * t + n) + 1) + e }, easeInOutBack: function(t, e, i, r, n) { return void 0 === n && (n = 1.70158), (t /= r / 2) < 1 ? i / 2 * (t * t * ((1 + (n *= 1.525)) * t - n)) + e : i / 2 * ((t -= 2) * t * ((1 + (n *= 1.525)) * t + n) + 2) + e }, easeInBounce: i, easeOutBounce: n, easeInOutBounce: function(t, e, r, s) { return t < s / 2 ? .5 * i(2 * t, 0, r, s) + e : .5 * n(2 * t - s, 0, r, s) + .5 * r + e } } }(),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.util.object.extend,
                        r = e.util.object.clone,
                        n = e.util.toFixed,
                        s = e.util.parseUnit,
                        o = e.util.multiplyTransformMatrices,
                        a = { cx: "left", x: "left", r: "radius", cy: "top", y: "top", display: "visible", visibility: "visible", transform: "transformMatrix", "fill-opacity": "fillOpacity", "fill-rule": "fillRule", "font-family": "fontFamily", "font-size": "fontSize", "font-style": "fontStyle", "font-weight": "fontWeight", "letter-spacing": "charSpacing", "paint-order": "paintFirst", "stroke-dasharray": "strokeDashArray", "stroke-dashoffset": "strokeDashOffset", "stroke-linecap": "strokeLineCap", "stroke-linejoin": "strokeLineJoin", "stroke-miterlimit": "strokeMiterLimit", "stroke-opacity": "strokeOpacity", "stroke-width": "strokeWidth", "text-decoration": "textDecoration", "text-anchor": "textAnchor", opacity: "opacity", "clip-path": "clipPath", "clip-rule": "clipRule", "vector-effect": "strokeUniform" },
                        h = { stroke: "strokeOpacity", fill: "fillOpacity" };

                    function c(t) { return t in a ? a[t] : t }

                    function l(t, i, r, n) { var a, h = "[object Array]" === Object.prototype.toString.call(i); if ("fill" !== t && "stroke" !== t || "none" !== i)
                            if ("vector-effect" === t) i = "non-scaling-stroke" === i;
                            else if ("strokeDashArray" === t) i = "none" === i ? null : i.replace(/,/g, " ").split(/\s+/).map(parseFloat);
                        else if ("transformMatrix" === t) i = r && r.transformMatrix ? o(r.transformMatrix, e.parseTransformAttribute(i)) : e.parseTransformAttribute(i);
                        else if ("visible" === t) i = "none" !== i && "hidden" !== i, r && !1 === r.visible && (i = !1);
                        else if ("opacity" === t) i = parseFloat(i), r && void 0 !== r.opacity && (i *= r.opacity);
                        else if ("textAnchor" === t) i = "start" === i ? "left" : "end" === i ? "right" : "center";
                        else if ("charSpacing" === t) a = s(i, n) / n * 1e3;
                        else if ("paintFirst" === t) { var c = i.indexOf("fill"),
                                l = i.indexOf("stroke");
                            i = "fill";
                            c > -1 && l > -1 && l < c ? i = "stroke" : -1 === c && l > -1 && (i = "stroke") } else { if ("href" === t || "xlink:href" === t) return i;
                            a = h ? i.map(s) : s(i, n) } else i = ""; return !h && isNaN(a) ? i : a }

                    function u(t) { return new RegExp("^(" + t.join("|") + ")\\b", "i") }

                    function f(t, e) { var i, r, n, s, o = []; for (n = 0, s = e.length; n < s; n++) i = e[n], r = t.getElementsByTagName(i), o = o.concat(Array.prototype.slice.call(r)); return o }

                    function d(t, e) { var i, r = !0; return (i = g(t, e.pop())) && e.length && (r = function(t, e) { var i, r = !0; for (; t.parentNode && 1 === t.parentNode.nodeType && e.length;) r && (i = e.pop()), t = t.parentNode, r = g(t, i); return 0 === e.length }(t, e)), i && r && 0 === e.length }

                    function g(t, e) { var i, r, n = t.nodeName,
                            s = t.getAttribute("class"),
                            o = t.getAttribute("id"); if (i = new RegExp("^" + n, "i"), e = e.replace(i, ""), o && e.length && (i = new RegExp("#" + o + "(?![a-zA-Z\\-]+)", "i"), e = e.replace(i, "")), s && e.length)
                            for (r = (s = s.split(" ")).length; r--;) i = new RegExp("\\." + s[r] + "(?![a-zA-Z\\-]+)", "i"), e = e.replace(i, ""); return 0 === e.length }

                    function p(t, e) { var i; if (t.getElementById && (i = t.getElementById(e)), i) return i; var r, n, s, o = t.getElementsByTagName("*"); for (n = 0, s = o.length; n < s; n++)
                            if (e === (r = o[n]).getAttribute("id")) return r } e.svgValidTagNamesRegEx = u(["path", "circle", "polygon", "polyline", "ellipse", "rect", "line", "image", "text"]), e.svgViewBoxElementsRegEx = u(["symbol", "image", "marker", "pattern", "view", "svg"]), e.svgInvalidAncestorsRegEx = u(["pattern", "defs", "symbol", "metadata", "clipPath", "mask", "desc"]), e.svgValidParentsRegEx = u(["symbol", "g", "a", "svg", "clipPath", "defs"]), e.cssRules = {}, e.gradientDefs = {}, e.clipPaths = {}, e.parseTransformAttribute = function() {
                        function t(t, i, r) { t[r] = Math.tan(e.util.degreesToRadians(i[0])) } var i = e.iMatrix,
                            r = e.reNum,
                            n = "(?:\\s+,?\\s*|,\\s*)",
                            s = "(?:" + ("(?:(matrix)\\s*\\(\\s*(" + r + ")" + n + "(" + r + ")" + n + "(" + r + ")" + n + "(" + r + ")" + n + "(" + r + ")" + n + "(" + r + ")\\s*\\))") + "|" + ("(?:(translate)\\s*\\(\\s*(" + r + ")(?:" + n + "(" + r + "))?\\s*\\))") + "|" + ("(?:(scale)\\s*\\(\\s*(" + r + ")(?:" + n + "(" + r + "))?\\s*\\))") + "|" + ("(?:(rotate)\\s*\\(\\s*(" + r + ")(?:" + n + "(" + r + ")" + n + "(" + r + "))?\\s*\\))") + "|" + ("(?:(skewX)\\s*\\(\\s*(" + r + ")\\s*\\))") + "|" + ("(?:(skewY)\\s*\\(\\s*(" + r + ")\\s*\\))") + ")",
                            o = new RegExp("^\\s*(?:" + ("(?:" + s + "(?:" + n + "*" + s + ")*)") + "?)\\s*$"),
                            a = new RegExp(s, "g"); return function(r) { var n = i.concat(),
                                h = []; if (!r || r && !o.test(r)) return n;
                            r.replace(a, function(r) { var o = new RegExp(s).exec(r).filter(function(t) { return !!t }),
                                    a = o[1],
                                    c = o.slice(2).map(parseFloat); switch (a) {
                                    case "translate":
                                        ! function(t, e) { t[4] = e[0], 2 === e.length && (t[5] = e[1]) }(n, c); break;
                                    case "rotate":
                                        c[0] = e.util.degreesToRadians(c[0]),
                                            function(t, i) { var r = e.util.cos(i[0]),
                                                    n = e.util.sin(i[0]),
                                                    s = 0,
                                                    o = 0;
                                                3 === i.length && (s = i[1], o = i[2]), t[0] = r, t[1] = n, t[2] = -n, t[3] = r, t[4] = s - (r * s - n * o), t[5] = o - (n * s + r * o) }(n, c); break;
                                    case "scale":
                                        ! function(t, e) { var i = e[0],
                                                r = 2 === e.length ? e[1] : e[0];
                                            t[0] = i, t[3] = r }(n, c); break;
                                    case "skewX":
                                        t(n, c, 2); break;
                                    case "skewY":
                                        t(n, c, 1); break;
                                    case "matrix":
                                        n = c } h.push(n.concat()), n = i.concat() }); for (var c = h[0]; h.length > 1;) h.shift(), c = e.util.multiplyTransformMatrices(c, h[0]); return c } }(); var v = new RegExp("^\\s*(" + e.reNum + "+)\\s*,?\\s*(" + e.reNum + "+)\\s*,?\\s*(" + e.reNum + "+)\\s*,?\\s*(" + e.reNum + "+)\\s*$");

                    function m(t) { var i, r, n, o, a, h, c = t.getAttribute("viewBox"),
                            l = 1,
                            u = 1,
                            f = t.getAttribute("width"),
                            d = t.getAttribute("height"),
                            g = t.getAttribute("x") || 0,
                            p = t.getAttribute("y") || 0,
                            m = t.getAttribute("preserveAspectRatio") || "",
                            _ = !c || !e.svgViewBoxElementsRegEx.test(t.nodeName) || !(c = c.match(v)),
                            y = !f || !d || "100%" === f || "100%" === d,
                            b = _ && y,
                            x = {},
                            C = "",
                            w = 0,
                            S = 0; if (x.width = 0, x.height = 0, x.toBeParsed = b, b) return x; if (_) return x.width = s(f), x.height = s(d), x; if (i = -parseFloat(c[1]), r = -parseFloat(c[2]), n = parseFloat(c[3]), o = parseFloat(c[4]), y ? (x.width = n, x.height = o) : (x.width = s(f), x.height = s(d), l = x.width / n, u = x.height / o), "none" !== (m = e.util.parsePreserveAspectRatioAttribute(m)).alignX && ("meet" === m.meetOrSlice && (u = l = l > u ? u : l), "slice" === m.meetOrSlice && (u = l = l > u ? l : u), w = x.width - n * l, S = x.height - o * l, "Mid" === m.alignX && (w /= 2), "Mid" === m.alignY && (S /= 2), "Min" === m.alignX && (w = 0), "Min" === m.alignY && (S = 0)), 1 === l && 1 === u && 0 === i && 0 === r && 0 === g && 0 === p) return x; if ((g || p) && (C = " translate(" + s(g) + " " + s(p) + ") "), a = C + " matrix(" + l + " 0 0 " + u + " " + (i * l + w) + " " + (r * u + S) + ") ", x.viewboxTransform = e.parseTransformAttribute(a), "svg" === t.nodeName) { for (h = t.ownerDocument.createElement("g"); t.firstChild;) h.appendChild(t.firstChild);
                            t.appendChild(h) } else a = (h = t).getAttribute("transform") + a; return h.setAttribute("transform", a), x }

                    function _(t, e) { var i = p(t, e.getAttribute("xlink:href").substr(1)); if (i && i.getAttribute("xlink:href") && _(t, i), ["gradientTransform", "x1", "x2", "y1", "y2", "gradientUnits", "cx", "cy", "r", "fx", "fy"].forEach(function(t) { e.hasAttribute(t) || e.setAttribute(t, i.getAttribute(t)) }), !e.children.length)
                            for (var r = i.cloneNode(!0); r.firstChild;) e.appendChild(r.firstChild);
                        e.removeAttribute("xlink:href") } e.parseSVGDocument = function(t, i, n, s) { if (t) {! function(t) { for (var e = f(t, ["use", "svg:use"]), i = 0; e.length && i < e.length;) { var r, n, s, o, a = e[i],
                                        h = (a.getAttribute("xlink:href") || a.getAttribute("href")).substr(1),
                                        c = a.getAttribute("x") || 0,
                                        l = a.getAttribute("y") || 0,
                                        u = p(t, h).cloneNode(!0),
                                        d = (u.getAttribute("transform") || "") + " translate(" + c + ", " + l + ")",
                                        g = e.length; if (m(u), /^svg$/i.test(u.nodeName)) { var v = u.ownerDocument.createElement("g"); for (n = 0, o = (s = u.attributes).length; n < o; n++) r = s.item(n), v.setAttribute(r.nodeName, r.nodeValue); for (; u.firstChild;) v.appendChild(u.firstChild);
                                        u = v } for (n = 0, o = (s = a.attributes).length; n < o; n++) "x" !== (r = s.item(n)).nodeName && "y" !== r.nodeName && "xlink:href" !== r.nodeName && "href" !== r.nodeName && ("transform" === r.nodeName ? d = r.nodeValue + " " + d : u.setAttribute(r.nodeName, r.nodeValue));
                                    u.setAttribute("transform", d), u.setAttribute("instantiated_by_use", "1"), u.removeAttribute("id"), a.parentNode.replaceChild(u, a), e.length === g && i++ } }(t); var o, a, h = e.Object.__uid++,
                                c = m(t),
                                l = e.util.toArray(t.getElementsByTagName("*")); if (c.crossOrigin = s && s.crossOrigin, c.svgUid = h, 0 === l.length && e.isLikelyNode) { var u = []; for (o = 0, a = (l = t.selectNodes('//*[name(.)!="svg"]')).length; o < a; o++) u[o] = l[o];
                                l = u } var d = l.filter(function(t) { return m(t), e.svgValidTagNamesRegEx.test(t.nodeName.replace("svg:", "")) && ! function(t, e) { for (; t && (t = t.parentNode);)
                                        if (t.nodeName && e.test(t.nodeName.replace("svg:", "")) && !t.getAttribute("instantiated_by_use")) return !0; return !1 }(t, e.svgInvalidAncestorsRegEx) }); if (!d || d && !d.length) i && i([], {});
                            else { var g = {};
                                l.filter(function(t) { return "clipPath" === t.nodeName.replace("svg:", "") }).forEach(function(t) { var i = t.getAttribute("id");
                                    g[i] = e.util.toArray(t.getElementsByTagName("*")).filter(function(t) { return e.svgValidTagNamesRegEx.test(t.nodeName.replace("svg:", "")) }) }), e.gradientDefs[h] = e.getGradientDefs(t), e.cssRules[h] = e.getCSSRules(t), e.clipPaths[h] = g, e.parseElements(d, function(t, r) { i && (i(t, c, r, l), delete e.gradientDefs[h], delete e.cssRules[h], delete e.clipPaths[h]) }, r(c), n, s) } } }; var y = new RegExp("(normal|italic)?\\s*(normal|small-caps)?\\s*(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*(" + e.reNum + "(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|" + e.reNum + "))?\\s+(.*)");
                    i(e, { parseFontDeclaration: function(t, e) { var i = t.match(y); if (i) { var r = i[1],
                                    n = i[3],
                                    o = i[4],
                                    a = i[5],
                                    h = i[6];
                                r && (e.fontStyle = r), n && (e.fontWeight = isNaN(parseFloat(n)) ? n : parseFloat(n)), o && (e.fontSize = s(o)), h && (e.fontFamily = h), a && (e.lineHeight = "normal" === a ? 1 : a) } }, getGradientDefs: function(t) { var e, i = f(t, ["linearGradient", "radialGradient", "svg:linearGradient", "svg:radialGradient"]),
                                r = 0,
                                n = {}; for (r = i.length; r--;)(e = i[r]).getAttribute("xlink:href") && _(t, e), n[e.getAttribute("id")] = e; return n }, parseAttributes: function(t, r, o) { if (t) { var a, u, f, g = {};
                                void 0 === o && (o = t.getAttribute("svgUid")), t.parentNode && e.svgValidParentsRegEx.test(t.parentNode.nodeName) && (g = e.parseAttributes(t.parentNode, r, o)); var p = r.reduce(function(e, i) { return (a = t.getAttribute(i)) && (e[i] = a), e }, {});
                                p = i(p, i(function(t, i) { var r = {}; for (var n in e.cssRules[i])
                                        if (d(t, n.split(" ")))
                                            for (var s in e.cssRules[i][n]) r[s] = e.cssRules[i][n][s]; return r }(t, o), e.parseStyleAttribute(t))), u = f = g.fontSize || e.Text.DEFAULT_SVG_FONT_SIZE, p["font-size"] && (p["font-size"] = u = s(p["font-size"], f)); var v, m, _ = {}; for (var y in p) m = l(v = c(y), p[y], g, u), _[v] = m;
                                _ && _.font && e.parseFontDeclaration(_.font, _); var b = i(g, _); return e.svgValidParentsRegEx.test(t.nodeName) ? b : function(t) { for (var i in h)
                                        if (void 0 !== t[h[i]] && "" !== t[i]) { if (void 0 === t[i]) { if (!e.Object.prototype[i]) continue;
                                                t[i] = e.Object.prototype[i] } if (0 !== t[i].indexOf("url(")) { var r = new e.Color(t[i]);
                                                t[i] = r.setAlpha(n(r.getAlpha() * t[h[i]], 2)).toRgba() } } return t }(b) } }, parseElements: function(t, i, r, n, s) { new e.ElementsParser(t, i, r, n, s).parse() }, parseStyleAttribute: function(t) { var e = {},
                                i = t.getAttribute("style"); return i ? ("string" == typeof i ? function(t, e) { var i, r;
                                t.replace(/;\s*$/, "").split(";").forEach(function(t) { var n = t.split(":");
                                    i = n[0].trim().toLowerCase(), r = n[1].trim(), e[i] = r }) }(i, e) : function(t, e) { var i, r; for (var n in t) void 0 !== t[n] && (i = n.toLowerCase(), r = t[n], e[i] = r) }(i, e), e) : e }, parsePointsAttribute: function(t) { if (!t) return null; var e, i, r = []; for (e = 0, i = (t = (t = t.replace(/,/g, " ").trim()).split(/\s+/)).length; e < i; e += 2) r.push({ x: parseFloat(t[e]), y: parseFloat(t[e + 1]) }); return r }, getCSSRules: function(t) { var i, r, n = t.getElementsByTagName("style"),
                                s = {}; for (i = 0, r = n.length; i < r; i++) { var o = n[i].textContent || n[i].text; "" !== (o = o.replace(/\/\*[\s\S]*?\*\//g, "")).trim() && o.match(/[^{]*\{[\s\S]*?\}/g).map(function(t) { return t.trim() }).forEach(function(t) { var n = t.match(/([\s\S]*?)\s*\{([^}]*)\}/),
                                        o = {},
                                        a = n[2].trim().replace(/;$/, "").split(/\s*;\s*/); for (i = 0, r = a.length; i < r; i++) { var h = a[i].split(/\s*:\s*/),
                                            c = h[0],
                                            l = h[1];
                                        o[c] = l }(t = n[1]).split(",").forEach(function(t) { "" !== (t = t.replace(/^svg/i, "").trim()) && (s[t] ? e.util.object.extend(s[t], o) : s[t] = e.util.object.clone(o)) }) }) } return s }, loadSVGFromURL: function(t, i, r, n) { t = t.replace(/^\n\s*/, "").trim(), new e.util.request(t, { method: "get", onComplete: function(t) { var s = t.responseXML;
                                    s && !s.documentElement && e.window.ActiveXObject && t.responseText && ((s = new ActiveXObject("Microsoft.XMLDOM")).async = "false", s.loadXML(t.responseText.replace(/<!DOCTYPE[\s\S]*?(\[[\s\S]*\])*?>/i, ""))); if (!s || !s.documentElement) return i && i(null), !1;
                                    e.parseSVGDocument(s.documentElement, function(t, e, r, n) { i && i(t, e, r, n) }, r, n) } }) }, loadSVGFromString: function(t, i, r, n) { var s; if (t = t.trim(), void 0 !== e.window.DOMParser) { var o = new e.window.DOMParser;
                                o && o.parseFromString && (s = o.parseFromString(t, "text/xml")) } else e.window.ActiveXObject && ((s = new ActiveXObject("Microsoft.XMLDOM")).async = "false", s.loadXML(t.replace(/<!DOCTYPE[\s\S]*?(\[[\s\S]*\])*?>/i, "")));
                            e.parseSVGDocument(s.documentElement, function(t, e, r, n) { i(t, e, r, n) }, r, n) } }) }(e), r.ElementsParser = function(t, e, i, r, n) { this.elements = t, this.callback = e, this.options = i, this.reviver = r, this.svgUid = i && i.svgUid || 0, this.parsingOptions = n, this.regexUrl = /^url\(['"]?#([^'"]+)['"]?\)/g },
                function(t) { t.parse = function() { this.instances = new Array(this.elements.length), this.numElements = this.elements.length, this.createObjects() }, t.createObjects = function() { var t = this;
                        this.elements.forEach(function(e, i) { e.setAttribute("svgUid", t.svgUid), t.createObject(e, i) }) }, t.findTag = function(t) { return r[r.util.string.capitalize(t.tagName.replace("svg:", ""))] }, t.createObject = function(t, e) { var i = this.findTag(t); if (i && i.fromElement) try { i.fromElement(t, this.createCallback(e, t), this.options) } catch (t) { r.log(t) } else this.checkIfDone() }, t.createCallback = function(t, e) { var i = this; return function(n) { var s;
                            i.resolveGradient(n, "fill"), i.resolveGradient(n, "stroke"), n instanceof r.Image && n._originalElement && (s = n.parsePreserveAspectRatioAttribute(e)), n._removeTransformMatrix(s), i.resolveClipPath(n), i.reviver && i.reviver(e, n), i.instances[t] = n, i.checkIfDone() } }, t.extractPropertyDefinition = function(t, e, i) { var n = t[e]; if (/^url\(/.test(n)) { var s = this.regexUrl.exec(n)[1]; return this.regexUrl.lastIndex = 0, r[i][this.svgUid][s] } }, t.resolveGradient = function(t, e) { var i = this.extractPropertyDefinition(t, e, "gradientDefs");
                        i && t.set(e, r.Gradient.fromElement(i, t)) }, t.createClipPathCallback = function(t, e) { return function(t) { t._removeTransformMatrix(), t.fillRule = t.clipRule, e.push(t) } }, t.resolveClipPath = function(t) { var e, i, n, s, o = this.extractPropertyDefinition(t, "clipPath", "clipPaths"); if (o) { n = [], i = r.util.invertTransform(t.calcTransformMatrix()); for (var a = 0; a < o.length; a++) e = o[a], this.findTag(e).fromElement(e, this.createClipPathCallback(t, n), this.options);
                            o = 1 === n.length ? n[0] : new r.Group(n), s = r.util.multiplyTransformMatrices(i, o.calcTransformMatrix()); var h = r.util.qrDecompose(s);
                            o.flipX = !1, o.flipY = !1, o.set("scaleX", h.scaleX), o.set("scaleY", h.scaleY), o.angle = h.angle, o.skewX = h.skewX, o.skewY = 0, o.setPositionByOrigin({ x: h.translateX, y: h.translateY }, "center", "center"), t.clipPath = o } }, t.checkIfDone = function() { 0 == --this.numElements && (this.instances = this.instances.filter(function(t) { return null != t }), this.callback(this.instances, this.elements)) } }(r.ElementsParser.prototype),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {});

                    function i(t, e) { this.x = t, this.y = e } e.Point ? e.warn("fabric.Point is already defined") : (e.Point = i, i.prototype = { type: "point", constructor: i, add: function(t) { return new i(this.x + t.x, this.y + t.y) }, addEquals: function(t) { return this.x += t.x, this.y += t.y, this }, scalarAdd: function(t) { return new i(this.x + t, this.y + t) }, scalarAddEquals: function(t) { return this.x += t, this.y += t, this }, subtract: function(t) { return new i(this.x - t.x, this.y - t.y) }, subtractEquals: function(t) { return this.x -= t.x, this.y -= t.y, this }, scalarSubtract: function(t) { return new i(this.x - t, this.y - t) }, scalarSubtractEquals: function(t) { return this.x -= t, this.y -= t, this }, multiply: function(t) { return new i(this.x * t, this.y * t) }, multiplyEquals: function(t) { return this.x *= t, this.y *= t, this }, divide: function(t) { return new i(this.x / t, this.y / t) }, divideEquals: function(t) { return this.x /= t, this.y /= t, this }, eq: function(t) { return this.x === t.x && this.y === t.y }, lt: function(t) { return this.x < t.x && this.y < t.y }, lte: function(t) { return this.x <= t.x && this.y <= t.y }, gt: function(t) { return this.x > t.x && this.y > t.y }, gte: function(t) { return this.x >= t.x && this.y >= t.y }, lerp: function(t, e) { return void 0 === e && (e = .5), e = Math.max(Math.min(1, e), 0), new i(this.x + (t.x - this.x) * e, this.y + (t.y - this.y) * e) }, distanceFrom: function(t) { var e = this.x - t.x,
                                i = this.y - t.y; return Math.sqrt(e * e + i * i) }, midPointFrom: function(t) { return this.lerp(t) }, min: function(t) { return new i(Math.min(this.x, t.x), Math.min(this.y, t.y)) }, max: function(t) { return new i(Math.max(this.x, t.x), Math.max(this.y, t.y)) }, toString: function() { return this.x + "," + this.y }, setXY: function(t, e) { return this.x = t, this.y = e, this }, setX: function(t) { return this.x = t, this }, setY: function(t) { return this.y = t, this }, setFromPoint: function(t) { return this.x = t.x, this.y = t.y, this }, swap: function(t) { var e = this.x,
                                i = this.y;
                            this.x = t.x, this.y = t.y, t.x = e, t.y = i }, clone: function() { return new i(this.x, this.y) } }) }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {});

                    function i(t) { this.status = t, this.points = [] } e.Intersection ? e.warn("fabric.Intersection is already defined") : (e.Intersection = i, e.Intersection.prototype = { constructor: i, appendPoint: function(t) { return this.points.push(t), this }, appendPoints: function(t) { return this.points = this.points.concat(t), this } }, e.Intersection.intersectLineLine = function(t, r, n, s) { var o, a = (s.x - n.x) * (t.y - n.y) - (s.y - n.y) * (t.x - n.x),
                            h = (r.x - t.x) * (t.y - n.y) - (r.y - t.y) * (t.x - n.x),
                            c = (s.y - n.y) * (r.x - t.x) - (s.x - n.x) * (r.y - t.y); if (0 !== c) { var l = a / c,
                                u = h / c;
                            0 <= l && l <= 1 && 0 <= u && u <= 1 ? (o = new i("Intersection")).appendPoint(new e.Point(t.x + l * (r.x - t.x), t.y + l * (r.y - t.y))) : o = new i } else o = new i(0 === a || 0 === h ? "Coincident" : "Parallel"); return o }, e.Intersection.intersectLinePolygon = function(t, e, r) { var n, s, o, a, h = new i,
                            c = r.length; for (a = 0; a < c; a++) n = r[a], s = r[(a + 1) % c], o = i.intersectLineLine(t, e, n, s), h.appendPoints(o.points); return h.points.length > 0 && (h.status = "Intersection"), h }, e.Intersection.intersectPolygonPolygon = function(t, e) { var r, n = new i,
                            s = t.length; for (r = 0; r < s; r++) { var o = t[r],
                                a = t[(r + 1) % s],
                                h = i.intersectLinePolygon(o, a, e);
                            n.appendPoints(h.points) } return n.points.length > 0 && (n.status = "Intersection"), n }, e.Intersection.intersectPolygonRectangle = function(t, r, n) { var s = r.min(n),
                            o = r.max(n),
                            a = new e.Point(o.x, s.y),
                            h = new e.Point(s.x, o.y),
                            c = i.intersectLinePolygon(s, a, t),
                            l = i.intersectLinePolygon(a, o, t),
                            u = i.intersectLinePolygon(o, h, t),
                            f = i.intersectLinePolygon(h, s, t),
                            d = new i; return d.appendPoints(c.points), d.appendPoints(l.points), d.appendPoints(u.points), d.appendPoints(f.points), d.points.length > 0 && (d.status = "Intersection"), d }) }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {});

                    function i(t) { t ? this._tryParsingColor(t) : this.setSource([0, 0, 0, 1]) }

                    function r(t, e, i) { return i < 0 && (i += 1), i > 1 && (i -= 1), i < 1 / 6 ? t + 6 * (e - t) * i : i < .5 ? e : i < 2 / 3 ? t + (e - t) * (2 / 3 - i) * 6 : t } e.Color ? e.warn("fabric.Color is already defined.") : (e.Color = i, e.Color.prototype = { _tryParsingColor: function(t) { var e;
                            t in i.colorNameMap && (t = i.colorNameMap[t]), "transparent" === t && (e = [255, 255, 255, 0]), e || (e = i.sourceFromHex(t)), e || (e = i.sourceFromRgb(t)), e || (e = i.sourceFromHsl(t)), e || (e = [0, 0, 0, 1]), e && this.setSource(e) }, _rgbToHsl: function(t, i, r) { t /= 255, i /= 255, r /= 255; var n, s, o, a = e.util.array.max([t, i, r]),
                                h = e.util.array.min([t, i, r]); if (o = (a + h) / 2, a === h) n = s = 0;
                            else { var c = a - h; switch (s = o > .5 ? c / (2 - a - h) : c / (a + h), a) {
                                    case t:
                                        n = (i - r) / c + (i < r ? 6 : 0); break;
                                    case i:
                                        n = (r - t) / c + 2; break;
                                    case r:
                                        n = (t - i) / c + 4 } n /= 6 } return [Math.round(360 * n), Math.round(100 * s), Math.round(100 * o)] }, getSource: function() { return this._source }, setSource: function(t) { this._source = t }, toRgb: function() { var t = this.getSource(); return "rgb(" + t[0] + "," + t[1] + "," + t[2] + ")" }, toRgba: function() { var t = this.getSource(); return "rgba(" + t[0] + "," + t[1] + "," + t[2] + "," + t[3] + ")" }, toHsl: function() { var t = this.getSource(),
                                e = this._rgbToHsl(t[0], t[1], t[2]); return "hsl(" + e[0] + "," + e[1] + "%," + e[2] + "%)" }, toHsla: function() { var t = this.getSource(),
                                e = this._rgbToHsl(t[0], t[1], t[2]); return "hsla(" + e[0] + "," + e[1] + "%," + e[2] + "%," + t[3] + ")" }, toHex: function() { var t, e, i, r = this.getSource(); return t = 1 === (t = r[0].toString(16)).length ? "0" + t : t, e = 1 === (e = r[1].toString(16)).length ? "0" + e : e, i = 1 === (i = r[2].toString(16)).length ? "0" + i : i, t.toUpperCase() + e.toUpperCase() + i.toUpperCase() }, toHexa: function() { var t, e = this.getSource(); return t = 1 === (t = (t = Math.round(255 * e[3])).toString(16)).length ? "0" + t : t, this.toHex() + t.toUpperCase() }, getAlpha: function() { return this.getSource()[3] }, setAlpha: function(t) { var e = this.getSource(); return e[3] = t, this.setSource(e), this }, toGrayscale: function() { var t = this.getSource(),
                                e = parseInt((.3 * t[0] + .59 * t[1] + .11 * t[2]).toFixed(0), 10),
                                i = t[3]; return this.setSource([e, e, e, i]), this }, toBlackWhite: function(t) { var e = this.getSource(),
                                i = (.3 * e[0] + .59 * e[1] + .11 * e[2]).toFixed(0),
                                r = e[3]; return t = t || 127, i = Number(i) < Number(t) ? 0 : 255, this.setSource([i, i, i, r]), this }, overlayWith: function(t) { t instanceof i || (t = new i(t)); var e, r = [],
                                n = this.getAlpha(),
                                s = this.getSource(),
                                o = t.getSource(); for (e = 0; e < 3; e++) r.push(Math.round(.5 * s[e] + .5 * o[e])); return r[3] = n, this.setSource(r), this } }, e.Color.reRGBa = /^rgba?\(\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*(?:\s*,\s*((?:\d*\.?\d+)?)\s*)?\)$/i, e.Color.reHSLa = /^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3}\%)\s*,\s*(\d{1,3}\%)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/i, e.Color.reHex = /^#?([0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{4}|[0-9a-f]{3})$/i, e.Color.colorNameMap = { aliceblue: "#F0F8FF", antiquewhite: "#FAEBD7", aqua: "#00FFFF", aquamarine: "#7FFFD4", azure: "#F0FFFF", beige: "#F5F5DC", bisque: "#FFE4C4", black: "#000000", blanchedalmond: "#FFEBCD", blue: "#0000FF", blueviolet: "#8A2BE2", brown: "#A52A2A", burlywood: "#DEB887", cadetblue: "#5F9EA0", chartreuse: "#7FFF00", chocolate: "#D2691E", coral: "#FF7F50", cornflowerblue: "#6495ED", cornsilk: "#FFF8DC", crimson: "#DC143C", cyan: "#00FFFF", darkblue: "#00008B", darkcyan: "#008B8B", darkgoldenrod: "#B8860B", darkgray: "#A9A9A9", darkgrey: "#A9A9A9", darkgreen: "#006400", darkkhaki: "#BDB76B", darkmagenta: "#8B008B", darkolivegreen: "#556B2F", darkorange: "#FF8C00", darkorchid: "#9932CC", darkred: "#8B0000", darksalmon: "#E9967A", darkseagreen: "#8FBC8F", darkslateblue: "#483D8B", darkslategray: "#2F4F4F", darkslategrey: "#2F4F4F", darkturquoise: "#00CED1", darkviolet: "#9400D3", deeppink: "#FF1493", deepskyblue: "#00BFFF", dimgray: "#696969", dimgrey: "#696969", dodgerblue: "#1E90FF", firebrick: "#B22222", floralwhite: "#FFFAF0", forestgreen: "#228B22", fuchsia: "#FF00FF", gainsboro: "#DCDCDC", ghostwhite: "#F8F8FF", gold: "#FFD700", goldenrod: "#DAA520", gray: "#808080", grey: "#808080", green: "#008000", greenyellow: "#ADFF2F", honeydew: "#F0FFF0", hotpink: "#FF69B4", indianred: "#CD5C5C", indigo: "#4B0082", ivory: "#FFFFF0", khaki: "#F0E68C", lavender: "#E6E6FA", lavenderblush: "#FFF0F5", lawngreen: "#7CFC00", lemonchiffon: "#FFFACD", lightblue: "#ADD8E6", lightcoral: "#F08080", lightcyan: "#E0FFFF", lightgoldenrodyellow: "#FAFAD2", lightgray: "#D3D3D3", lightgrey: "#D3D3D3", lightgreen: "#90EE90", lightpink: "#FFB6C1", lightsalmon: "#FFA07A", lightseagreen: "#20B2AA", lightskyblue: "#87CEFA", lightslategray: "#778899", lightslategrey: "#778899", lightsteelblue: "#B0C4DE", lightyellow: "#FFFFE0", lime: "#00FF00", limegreen: "#32CD32", linen: "#FAF0E6", magenta: "#FF00FF", maroon: "#800000", mediumaquamarine: "#66CDAA", mediumblue: "#0000CD", mediumorchid: "#BA55D3", mediumpurple: "#9370DB", mediumseagreen: "#3CB371", mediumslateblue: "#7B68EE", mediumspringgreen: "#00FA9A", mediumturquoise: "#48D1CC", mediumvioletred: "#C71585", midnightblue: "#191970", mintcream: "#F5FFFA", mistyrose: "#FFE4E1", moccasin: "#FFE4B5", navajowhite: "#FFDEAD", navy: "#000080", oldlace: "#FDF5E6", olive: "#808000", olivedrab: "#6B8E23", orange: "#FFA500", orangered: "#FF4500", orchid: "#DA70D6", palegoldenrod: "#EEE8AA", palegreen: "#98FB98", paleturquoise: "#AFEEEE", palevioletred: "#DB7093", papayawhip: "#FFEFD5", peachpuff: "#FFDAB9", peru: "#CD853F", pink: "#FFC0CB", plum: "#DDA0DD", powderblue: "#B0E0E6", purple: "#800080", rebeccapurple: "#663399", red: "#FF0000", rosybrown: "#BC8F8F", royalblue: "#4169E1", saddlebrown: "#8B4513", salmon: "#FA8072", sandybrown: "#F4A460", seagreen: "#2E8B57", seashell: "#FFF5EE", sienna: "#A0522D", silver: "#C0C0C0", skyblue: "#87CEEB", slateblue: "#6A5ACD", slategray: "#708090", slategrey: "#708090", snow: "#FFFAFA", springgreen: "#00FF7F", steelblue: "#4682B4", tan: "#D2B48C", teal: "#008080", thistle: "#D8BFD8", tomato: "#FF6347", turquoise: "#40E0D0", violet: "#EE82EE", wheat: "#F5DEB3", white: "#FFFFFF", whitesmoke: "#F5F5F5", yellow: "#FFFF00", yellowgreen: "#9ACD32" }, e.Color.fromRgb = function(t) { return i.fromSource(i.sourceFromRgb(t)) }, e.Color.sourceFromRgb = function(t) { var e = t.match(i.reRGBa); if (e) { var r = parseInt(e[1], 10) / (/%$/.test(e[1]) ? 100 : 1) * (/%$/.test(e[1]) ? 255 : 1),
                                n = parseInt(e[2], 10) / (/%$/.test(e[2]) ? 100 : 1) * (/%$/.test(e[2]) ? 255 : 1),
                                s = parseInt(e[3], 10) / (/%$/.test(e[3]) ? 100 : 1) * (/%$/.test(e[3]) ? 255 : 1); return [parseInt(r, 10), parseInt(n, 10), parseInt(s, 10), e[4] ? parseFloat(e[4]) : 1] } }, e.Color.fromRgba = i.fromRgb, e.Color.fromHsl = function(t) { return i.fromSource(i.sourceFromHsl(t)) }, e.Color.sourceFromHsl = function(t) { var e = t.match(i.reHSLa); if (e) { var n, s, o, a = (parseFloat(e[1]) % 360 + 360) % 360 / 360,
                                h = parseFloat(e[2]) / (/%$/.test(e[2]) ? 100 : 1),
                                c = parseFloat(e[3]) / (/%$/.test(e[3]) ? 100 : 1); if (0 === h) n = s = o = c;
                            else { var l = c <= .5 ? c * (h + 1) : c + h - c * h,
                                    u = 2 * c - l;
                                n = r(u, l, a + 1 / 3), s = r(u, l, a), o = r(u, l, a - 1 / 3) } return [Math.round(255 * n), Math.round(255 * s), Math.round(255 * o), e[4] ? parseFloat(e[4]) : 1] } }, e.Color.fromHsla = i.fromHsl, e.Color.fromHex = function(t) { return i.fromSource(i.sourceFromHex(t)) }, e.Color.sourceFromHex = function(t) { if (t.match(i.reHex)) { var e = t.slice(t.indexOf("#") + 1),
                                r = 3 === e.length || 4 === e.length,
                                n = 8 === e.length || 4 === e.length,
                                s = r ? e.charAt(0) + e.charAt(0) : e.substring(0, 2),
                                o = r ? e.charAt(1) + e.charAt(1) : e.substring(2, 4),
                                a = r ? e.charAt(2) + e.charAt(2) : e.substring(4, 6),
                                h = n ? r ? e.charAt(3) + e.charAt(3) : e.substring(6, 8) : "FF"; return [parseInt(s, 16), parseInt(o, 16), parseInt(a, 16), parseFloat((parseInt(h, 16) / 255).toFixed(2))] } }, e.Color.fromSource = function(t) { var e = new i; return e.setSource(t), e }) }(e),
                function() {
                    function t(t) { var e, i, n, s, o = t.getAttribute("style"),
                            a = t.getAttribute("offset") || 0; if (a = (a = parseFloat(a) / (/%$/.test(a) ? 100 : 1)) < 0 ? 0 : a > 1 ? 1 : a, o) { var h = o.split(/\s*;\s*/); for ("" === h[h.length - 1] && h.pop(), s = h.length; s--;) { var c = h[s].split(/\s*:\s*/),
                                    l = c[0].trim(),
                                    u = c[1].trim(); "stop-color" === l ? e = u : "stop-opacity" === l && (n = u) } } return e || (e = t.getAttribute("stop-color") || "rgb(0,0,0)"), n || (n = t.getAttribute("stop-opacity")), i = (e = new r.Color(e)).getAlpha(), n = isNaN(parseFloat(n)) ? 1 : parseFloat(n), n *= i, { offset: a, color: e.toRgb(), opacity: n } } var e = r.util.object.clone;

                    function i(t, e, i) { var r, n = 0,
                            s = 1,
                            o = ""; for (var a in e) "Infinity" === e[a] ? e[a] = 1 : "-Infinity" === e[a] && (e[a] = 0), r = parseFloat(e[a], 10), s = "string" == typeof e[a] && /^(\d+\.\d+)%|(\d+)%$/.test(e[a]) ? .01 : 1, "x1" === a || "x2" === a || "r2" === a ? (s *= "objectBoundingBox" === i ? t.width : 1, n = "objectBoundingBox" === i && t.left || 0) : "y1" !== a && "y2" !== a || (s *= "objectBoundingBox" === i ? t.height : 1, n = "objectBoundingBox" === i && t.top || 0), e[a] = r * s + n; if ("ellipse" === t.type && null !== e.r2 && "objectBoundingBox" === i && t.rx !== t.ry) { var h = t.ry / t.rx;
                            o = " scale(1, " + h + ")", e.y1 && (e.y1 /= h), e.y2 && (e.y2 /= h) } return o } r.Gradient = r.util.createClass({ offsetX: 0, offsetY: 0, initialize: function(t) { t || (t = {}); var e = {};
                            this.id = r.Object.__uid++, this.type = t.type || "linear", e = { x1: t.coords.x1 || 0, y1: t.coords.y1 || 0, x2: t.coords.x2 || 0, y2: t.coords.y2 || 0 }, "radial" === this.type && (e.r1 = t.coords.r1 || 0, e.r2 = t.coords.r2 || 0), this.coords = e, this.colorStops = t.colorStops.slice(), t.gradientTransform && (this.gradientTransform = t.gradientTransform), this.offsetX = t.offsetX || this.offsetX, this.offsetY = t.offsetY || this.offsetY }, addColorStop: function(t) { for (var e in t) { var i = new r.Color(t[e]);
                                this.colorStops.push({ offset: parseFloat(e), color: i.toRgb(), opacity: i.getAlpha() }) } return this }, toObject: function(t) { var e = { type: this.type, coords: this.coords, colorStops: this.colorStops, offsetX: this.offsetX, offsetY: this.offsetY, gradientTransform: this.gradientTransform ? this.gradientTransform.concat() : this.gradientTransform }; return r.util.populateWithProperties(this, e, t), e }, toSVG: function(t, i) { var n, s, o, a, h = e(this.coords, !0),
                                c = (i = i || {}, e(this.colorStops, !0)),
                                l = h.r1 > h.r2,
                                u = this.gradientTransform ? this.gradientTransform.concat() : r.iMatrix.concat(),
                                f = t.width / 2 - this.offsetX,
                                d = t.height / 2 - this.offsetY,
                                g = !!i.additionalTransform; if (c.sort(function(t, e) { return t.offset - e.offset }), "path" === t.type && (f -= t.pathOffset.x, d -= t.pathOffset.y), u[4] -= f, u[5] -= d, a = 'id="SVGID_' + this.id + '" gradientUnits="userSpaceOnUse"', a += ' gradientTransform="' + (g ? i.additionalTransform + " " : "") + r.util.matrixToSVG(u) + '" ', "linear" === this.type ? o = ["<linearGradient ", a, ' x1="', h.x1, '" y1="', h.y1, '" x2="', h.x2, '" y2="', h.y2, '">\n'] : "radial" === this.type && (o = ["<radialGradient ", a, ' cx="', l ? h.x1 : h.x2, '" cy="', l ? h.y1 : h.y2, '" r="', l ? h.r1 : h.r2, '" fx="', l ? h.x2 : h.x1, '" fy="', l ? h.y2 : h.y1, '">\n']), "radial" === this.type) { if (l)
                                    for ((c = c.concat()).reverse(), n = 0, s = c.length; n < s; n++) c[n].offset = 1 - c[n].offset; var p = Math.min(h.r1, h.r2); if (p > 0) { var v = p / Math.max(h.r1, h.r2); for (n = 0, s = c.length; n < s; n++) c[n].offset += v * (1 - c[n].offset) } } for (n = 0, s = c.length; n < s; n++) { var m = c[n];
                                o.push("<stop ", 'offset="', 100 * m.offset + "%", '" style="stop-color:', m.color, void 0 !== m.opacity ? ";stop-opacity: " + m.opacity : ";", '"/>\n') } return o.push("linear" === this.type ? "</linearGradient>\n" : "</radialGradient>\n"), o.join("") }, toLive: function(t) { var e, i, n, s = r.util.object.clone(this.coords); if (this.type) { for ("linear" === this.type ? e = t.createLinearGradient(s.x1, s.y1, s.x2, s.y2) : "radial" === this.type && (e = t.createRadialGradient(s.x1, s.y1, s.r1, s.x2, s.y2, s.r2)), i = 0, n = this.colorStops.length; i < n; i++) { var o = this.colorStops[i].color,
                                        a = this.colorStops[i].opacity,
                                        h = this.colorStops[i].offset;
                                    void 0 !== a && (o = new r.Color(o).setAlpha(a).toRgba()), e.addColorStop(h, o) } return e } } }), r.util.object.extend(r.Gradient, { fromElement: function(e, n) { var s, o, a, h, c = e.getElementsByTagName("stop"),
                                l = e.getAttribute("gradientUnits") || "objectBoundingBox",
                                u = e.getAttribute("gradientTransform"),
                                f = []; for ("linear" === (s = "linearGradient" === e.nodeName || "LINEARGRADIENT" === e.nodeName ? "linear" : "radial") ? o = function(t) { return { x1: t.getAttribute("x1") || 0, y1: t.getAttribute("y1") || 0, x2: t.getAttribute("x2") || "100%", y2: t.getAttribute("y2") || 0 } }(e) : "radial" === s && (o = function(t) { return { x1: t.getAttribute("fx") || t.getAttribute("cx") || "50%", y1: t.getAttribute("fy") || t.getAttribute("cy") || "50%", r1: 0, x2: t.getAttribute("cx") || "50%", y2: t.getAttribute("cy") || "50%", r2: t.getAttribute("r") || "50%" } }(e)), h = c.length; h--;) f.push(t(c[h]));
                            a = i(n, o, l); var d = new r.Gradient({ type: s, coords: o, colorStops: f, offsetX: -n.left, offsetY: -n.top }); return (u || "" !== a) && (d.gradientTransform = r.parseTransformAttribute((u || "") + a)), d }, forObject: function(t, e) { return e || (e = {}), i(t, e.coords, "userSpaceOnUse"), new r.Gradient(e) } }) }(),
                function() { "use strict"; var t = r.util.toFixed;
                    r.Pattern = r.util.createClass({ repeat: "repeat", offsetX: 0, offsetY: 0, crossOrigin: "", patternTransform: null, initialize: function(t, e) { if (t || (t = {}), this.id = r.Object.__uid++, this.setOptions(t), !t.source || t.source && "string" != typeof t.source) e && e(this);
                            else if (void 0 !== r.util.getFunctionBody(t.source)) this.source = new Function(r.util.getFunctionBody(t.source)), e && e(this);
                            else { var i = this;
                                this.source = r.util.createImage(), r.util.loadImage(t.source, function(t) { i.source = t, e && e(i) }, null, this.crossOrigin) } }, toObject: function(e) { var i, n, s = r.Object.NUM_FRACTION_DIGITS; return "function" == typeof this.source ? i = String(this.source) : "string" == typeof this.source.src ? i = this.source.src : "object" == typeof this.source && this.source.toDataURL && (i = this.source.toDataURL()), n = { type: "pattern", source: i, repeat: this.repeat, crossOrigin: this.crossOrigin, offsetX: t(this.offsetX, s), offsetY: t(this.offsetY, s), patternTransform: this.patternTransform ? this.patternTransform.concat() : null }, r.util.populateWithProperties(this, n, e), n }, toSVG: function(t) { var e = "function" == typeof this.source ? this.source() : this.source,
                                i = e.width / t.width,
                                r = e.height / t.height,
                                n = this.offsetX / t.width,
                                s = this.offsetY / t.height,
                                o = ""; return "repeat-x" !== this.repeat && "no-repeat" !== this.repeat || (r = 1, s && (r += Math.abs(s))), "repeat-y" !== this.repeat && "no-repeat" !== this.repeat || (i = 1, n && (i += Math.abs(n))), e.src ? o = e.src : e.toDataURL && (o = e.toDataURL()), '<pattern id="SVGID_' + this.id + '" x="' + n + '" y="' + s + '" width="' + i + '" height="' + r + '">\n<image x="0" y="0" width="' + e.width + '" height="' + e.height + '" xlink:href="' + o + '"></image>\n</pattern>\n' }, setOptions: function(t) { for (var e in t) this[e] = t[e] }, toLive: function(t) { var e = "function" == typeof this.source ? this.source() : this.source; if (!e) return ""; if (void 0 !== e.src) { if (!e.complete) return ""; if (0 === e.naturalWidth || 0 === e.naturalHeight) return "" } return t.createPattern(e, this.repeat) } }) }(),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.util.toFixed;
                    e.Shadow ? e.warn("fabric.Shadow is already defined.") : (e.Shadow = e.util.createClass({ color: "rgb(0,0,0)", blur: 0, offsetX: 0, offsetY: 0, affectStroke: !1, includeDefaultValues: !0, nonScaling: !1, initialize: function(t) { for (var i in "string" == typeof t && (t = this._parseShadow(t)), t) this[i] = t[i];
                            this.id = e.Object.__uid++ }, _parseShadow: function(t) { var i = t.trim(),
                                r = e.Shadow.reOffsetsAndBlur.exec(i) || []; return { color: (i.replace(e.Shadow.reOffsetsAndBlur, "") || "rgb(0,0,0)").trim(), offsetX: parseInt(r[1], 10) || 0, offsetY: parseInt(r[2], 10) || 0, blur: parseInt(r[3], 10) || 0 } }, toString: function() { return [this.offsetX, this.offsetY, this.blur, this.color].join("px ") }, toSVG: function(t) { var r = 40,
                                n = 40,
                                s = e.Object.NUM_FRACTION_DIGITS,
                                o = e.util.rotateVector({ x: this.offsetX, y: this.offsetY }, e.util.degreesToRadians(-t.angle)),
                                a = new e.Color(this.color); return t.width && t.height && (r = 100 * i((Math.abs(o.x) + this.blur) / t.width, s) + 20, n = 100 * i((Math.abs(o.y) + this.blur) / t.height, s) + 20), t.flipX && (o.x *= -1), t.flipY && (o.y *= -1), '<filter id="SVGID_' + this.id + '" y="-' + n + '%" height="' + (100 + 2 * n) + '%" x="-' + r + '%" width="' + (100 + 2 * r) + '%" >\n\t<feGaussianBlur in="SourceAlpha" stdDeviation="' + i(this.blur ? this.blur / 2 : 0, s) + '"></feGaussianBlur>\n\t<feOffset dx="' + i(o.x, s) + '" dy="' + i(o.y, s) + '" result="oBlur" ></feOffset>\n\t<feFlood flood-color="' + a.toRgb() + '" flood-opacity="' + a.getAlpha() + '"/>\n\t<feComposite in2="oBlur" operator="in" />\n\t<feMerge>\n\t\t<feMergeNode></feMergeNode>\n\t\t<feMergeNode in="SourceGraphic"></feMergeNode>\n\t</feMerge>\n</filter>\n' }, toObject: function() { if (this.includeDefaultValues) return { color: this.color, blur: this.blur, offsetX: this.offsetX, offsetY: this.offsetY, affectStroke: this.affectStroke, nonScaling: this.nonScaling }; var t = {},
                                i = e.Shadow.prototype; return ["color", "blur", "offsetX", "offsetY", "affectStroke", "nonScaling"].forEach(function(e) { this[e] !== i[e] && (t[e] = this[e]) }, this), t } }), e.Shadow.reOffsetsAndBlur = /(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/) }(e),
                function() { "use strict"; if (r.StaticCanvas) r.warn("fabric.StaticCanvas is already defined.");
                    else { var t = r.util.object.extend,
                            e = r.util.getElementOffset,
                            i = r.util.removeFromArray,
                            n = r.util.toFixed,
                            s = r.util.transformPoint,
                            o = r.util.invertTransform,
                            a = r.util.getNodeCanvas,
                            h = r.util.createCanvasElement,
                            c = new Error("Could not initialize `canvas` element");
                        r.StaticCanvas = r.util.createClass(r.CommonMethods, { initialize: function(t, e) { e || (e = {}), this.renderAndResetBound = this.renderAndReset.bind(this), this.requestRenderAllBound = this.requestRenderAll.bind(this), this._initStatic(t, e) }, backgroundColor: "", backgroundImage: null, overlayColor: "", overlayImage: null, includeDefaultValues: !0, stateful: !1, renderOnAddRemove: !0, clipTo: null, controlsAboveOverlay: !1, allowTouchScrolling: !1, imageSmoothingEnabled: !0, viewportTransform: r.iMatrix.concat(), backgroundVpt: !0, overlayVpt: !0, onBeforeScaleRotate: function() {}, enableRetinaScaling: !0, vptCoords: {}, skipOffscreen: !0, clipPath: void 0, _initStatic: function(t, e) { var i = this.requestRenderAllBound;
                                this._objects = [], this._createLowerCanvas(t), this._initOptions(e), this._setImageSmoothing(), this.interactive || this._initRetinaScaling(), e.overlayImage && this.setOverlayImage(e.overlayImage, i), e.backgroundImage && this.setBackgroundImage(e.backgroundImage, i), e.backgroundColor && this.setBackgroundColor(e.backgroundColor, i), e.overlayColor && this.setOverlayColor(e.overlayColor, i), this.calcOffset() }, _isRetinaScaling: function() { return 1 !== r.devicePixelRatio && this.enableRetinaScaling }, getRetinaScaling: function() { return this._isRetinaScaling() ? r.devicePixelRatio : 1 }, _initRetinaScaling: function() { this._isRetinaScaling() && (this.lowerCanvasEl.setAttribute("width", this.width * r.devicePixelRatio), this.lowerCanvasEl.setAttribute("height", this.height * r.devicePixelRatio), this.contextContainer.scale(r.devicePixelRatio, r.devicePixelRatio)) }, calcOffset: function() { return this._offset = e(this.lowerCanvasEl), this }, setOverlayImage: function(t, e, i) { return this.__setBgOverlayImage("overlayImage", t, e, i) }, setBackgroundImage: function(t, e, i) { return this.__setBgOverlayImage("backgroundImage", t, e, i) }, setOverlayColor: function(t, e) { return this.__setBgOverlayColor("overlayColor", t, e) }, setBackgroundColor: function(t, e) { return this.__setBgOverlayColor("backgroundColor", t, e) }, _setImageSmoothing: function() { var t = this.getContext();
                                t.imageSmoothingEnabled = t.imageSmoothingEnabled || t.webkitImageSmoothingEnabled || t.mozImageSmoothingEnabled || t.msImageSmoothingEnabled || t.oImageSmoothingEnabled, t.imageSmoothingEnabled = this.imageSmoothingEnabled }, __setBgOverlayImage: function(t, e, i, n) { return "string" == typeof e ? r.util.loadImage(e, function(e) { if (e) { var s = new r.Image(e, n);
                                        this[t] = s, s.canvas = this } i && i(e) }, this, n && n.crossOrigin) : (n && e.setOptions(n), this[t] = e, e && (e.canvas = this), i && i(e)), this }, __setBgOverlayColor: function(t, e, i) { return this[t] = e, this._initGradient(e, t), this._initPattern(e, t, i), this }, _createCanvasElement: function() { var t = h(); if (!t) throw c; if (t.style || (t.style = {}), void 0 === t.getContext) throw c; return t }, _initOptions: function(t) { var e = this.lowerCanvasEl;
                                this._setOptions(t), this.width = this.width || parseInt(e.width, 10) || 0, this.height = this.height || parseInt(e.height, 10) || 0, this.lowerCanvasEl.style && (e.width = this.width, e.height = this.height, e.style.width = this.width + "px", e.style.height = this.height + "px", this.viewportTransform = this.viewportTransform.slice()) }, _createLowerCanvas: function(t) { t && t.getContext ? this.lowerCanvasEl = t : this.lowerCanvasEl = r.util.getById(t) || this._createCanvasElement(), r.util.addClass(this.lowerCanvasEl, "lower-canvas"), this.interactive && this._applyCanvasStyle(this.lowerCanvasEl), this.contextContainer = this.lowerCanvasEl.getContext("2d") }, getWidth: function() { return this.width }, getHeight: function() { return this.height }, setWidth: function(t, e) { return this.setDimensions({ width: t }, e) }, setHeight: function(t, e) { return this.setDimensions({ height: t }, e) }, setDimensions: function(t, e) { var i; for (var r in e = e || {}, t) i = t[r], e.cssOnly || (this._setBackstoreDimension(r, t[r]), i += "px", this.hasLostContext = !0), e.backstoreOnly || this._setCssDimension(r, i); return this._isCurrentlyDrawing && this.freeDrawingBrush && this.freeDrawingBrush._setBrushStyles(), this._initRetinaScaling(), this._setImageSmoothing(), this.calcOffset(), e.cssOnly || this.requestRenderAll(), this }, _setBackstoreDimension: function(t, e) { return this.lowerCanvasEl[t] = e, this.upperCanvasEl && (this.upperCanvasEl[t] = e), this.cacheCanvasEl && (this.cacheCanvasEl[t] = e), this[t] = e, this }, _setCssDimension: function(t, e) { return this.lowerCanvasEl.style[t] = e, this.upperCanvasEl && (this.upperCanvasEl.style[t] = e), this.wrapperEl && (this.wrapperEl.style[t] = e), this }, getZoom: function() { return this.viewportTransform[0] }, setViewportTransform: function(t) { var e, i, r, n = this._activeObject; for (this.viewportTransform = t, i = 0, r = this._objects.length; i < r; i++)(e = this._objects[i]).group || e.setCoords(!1, !0); return n && "activeSelection" === n.type && n.setCoords(!1, !0), this.calcViewportBoundaries(), this.renderOnAddRemove && this.requestRenderAll(), this }, zoomToPoint: function(t, e) { var i = t,
                                    r = this.viewportTransform.slice(0);
                                t = s(t, o(this.viewportTransform)), r[0] = e, r[3] = e; var n = s(t, r); return r[4] += i.x - n.x, r[5] += i.y - n.y, this.setViewportTransform(r) }, setZoom: function(t) { return this.zoomToPoint(new r.Point(0, 0), t), this }, absolutePan: function(t) { var e = this.viewportTransform.slice(0); return e[4] = -t.x, e[5] = -t.y, this.setViewportTransform(e) }, relativePan: function(t) { return this.absolutePan(new r.Point(-t.x - this.viewportTransform[4], -t.y - this.viewportTransform[5])) }, getElement: function() { return this.lowerCanvasEl }, _onObjectAdded: function(t) { this.stateful && t.setupState(), t._set("canvas", this), t.setCoords(), this.fire("object:added", { target: t }), t.fire("added") }, _onObjectRemoved: function(t) { this.fire("object:removed", { target: t }), t.fire("removed"), delete t.canvas }, clearContext: function(t) { return t.clearRect(0, 0, this.width, this.height), this }, getContext: function() { return this.contextContainer }, clear: function() { return this._objects.length = 0, this.backgroundImage = null, this.overlayImage = null, this.backgroundColor = "", this.overlayColor = "", this._hasITextHandlers && (this.off("mouse:up", this._mouseUpITextHandler), this._iTextInstances = null, this._hasITextHandlers = !1), this.clearContext(this.contextContainer), this.fire("canvas:cleared"), this.renderOnAddRemove && this.requestRenderAll(), this }, renderAll: function() { var t = this.contextContainer; return this.renderCanvas(t, this._objects), this }, renderAndReset: function() { this.isRendering = 0, this.renderAll() }, requestRenderAll: function() { return this.isRendering || (this.isRendering = r.util.requestAnimFrame(this.renderAndResetBound)), this }, calcViewportBoundaries: function() { var t = {},
                                    e = this.width,
                                    i = this.height,
                                    n = o(this.viewportTransform); return t.tl = s({ x: 0, y: 0 }, n), t.br = s({ x: e, y: i }, n), t.tr = new r.Point(t.br.x, t.tl.y), t.bl = new r.Point(t.tl.x, t.br.y), this.vptCoords = t, t }, cancelRequestedRender: function() { this.isRendering && (r.util.cancelAnimFrame(this.isRendering), this.isRendering = 0) }, renderCanvas: function(t, e) { var i = this.viewportTransform,
                                    n = this.clipPath;
                                this.cancelRequestedRender(), this.calcViewportBoundaries(), this.clearContext(t), this.fire("before:render", { ctx: t }), this.clipTo && r.util.clipContext(this, t), this._renderBackground(t), t.save(), t.transform(i[0], i[1], i[2], i[3], i[4], i[5]), this._renderObjects(t, e), t.restore(), !this.controlsAboveOverlay && this.interactive && this.drawControls(t), this.clipTo && t.restore(), n && (n.canvas = this, n.shouldCache(), n._transformDone = !0, n.renderCache({ forClipping: !0 }), this.drawClipPathOnCanvas(t)), this._renderOverlay(t), this.controlsAboveOverlay && this.interactive && this.drawControls(t), this.fire("after:render", { ctx: t }) }, drawClipPathOnCanvas: function(t) { var e = this.viewportTransform,
                                    i = this.clipPath;
                                t.save(), t.transform(e[0], e[1], e[2], e[3], e[4], e[5]), t.globalCompositeOperation = "destination-in", i.transform(t), t.scale(1 / i.zoomX, 1 / i.zoomY), t.drawImage(i._cacheCanvas, -i.cacheTranslationX, -i.cacheTranslationY), t.restore() }, _renderObjects: function(t, e) { var i, r; for (i = 0, r = e.length; i < r; ++i) e[i] && e[i].render(t) }, _renderBackgroundOrOverlay: function(t, e) { var i = this[e + "Color"],
                                    r = this[e + "Image"],
                                    n = this.viewportTransform,
                                    s = this[e + "Vpt"]; if (i || r) { if (i) { t.save(), t.beginPath(), t.moveTo(0, 0), t.lineTo(this.width, 0), t.lineTo(this.width, this.height), t.lineTo(0, this.height), t.closePath(), t.fillStyle = i.toLive ? i.toLive(t, this) : i, s && t.transform(n[0], n[1], n[2], n[3], n[4] + (i.offsetX || 0), n[5] + (i.offsetY || 0)); var o = i.gradientTransform || i.patternTransform;
                                        o && t.transform(o[0], o[1], o[2], o[3], o[4], o[5]), t.fill(), t.restore() } r && (t.save(), s && t.transform(n[0], n[1], n[2], n[3], n[4], n[5]), r.render(t), t.restore()) } }, _renderBackground: function(t) { this._renderBackgroundOrOverlay(t, "background") }, _renderOverlay: function(t) { this._renderBackgroundOrOverlay(t, "overlay") }, getCenter: function() { return { top: this.height / 2, left: this.width / 2 } }, centerObjectH: function(t) { return this._centerObject(t, new r.Point(this.getCenter().left, t.getCenterPoint().y)) }, centerObjectV: function(t) { return this._centerObject(t, new r.Point(t.getCenterPoint().x, this.getCenter().top)) }, centerObject: function(t) { var e = this.getCenter(); return this._centerObject(t, new r.Point(e.left, e.top)) }, viewportCenterObject: function(t) { var e = this.getVpCenter(); return this._centerObject(t, e) }, viewportCenterObjectH: function(t) { var e = this.getVpCenter(); return this._centerObject(t, new r.Point(e.x, t.getCenterPoint().y)), this }, viewportCenterObjectV: function(t) { var e = this.getVpCenter(); return this._centerObject(t, new r.Point(t.getCenterPoint().x, e.y)) }, getVpCenter: function() { var t = this.getCenter(),
                                    e = o(this.viewportTransform); return s({ x: t.left, y: t.top }, e) }, _centerObject: function(t, e) { return t.setPositionByOrigin(e, "center", "center"), t.setCoords(), this.renderOnAddRemove && this.requestRenderAll(), this }, toDatalessJSON: function(t) { return this.toDatalessObject(t) }, toObject: function(t) { return this._toObjectMethod("toObject", t) }, toDatalessObject: function(t) { return this._toObjectMethod("toDatalessObject", t) }, _toObjectMethod: function(e, i) { var n = this.clipPath,
                                    s = { version: r.version, objects: this._toObjects(e, i) }; return n && (s.clipPath = this._toObject(this.clipPath, e, i)), t(s, this.__serializeBgOverlay(e, i)), r.util.populateWithProperties(this, s, i), s }, _toObjects: function(t, e) { return this._objects.filter(function(t) { return !t.excludeFromExport }).map(function(i) { return this._toObject(i, t, e) }, this) }, _toObject: function(t, e, i) { var r;
                                this.includeDefaultValues || (r = t.includeDefaultValues, t.includeDefaultValues = !1); var n = t[e](i); return this.includeDefaultValues || (t.includeDefaultValues = r), n }, __serializeBgOverlay: function(t, e) { var i = {},
                                    r = this.backgroundImage,
                                    n = this.overlayImage; return this.backgroundColor && (i.background = this.backgroundColor.toObject ? this.backgroundColor.toObject(e) : this.backgroundColor), this.overlayColor && (i.overlay = this.overlayColor.toObject ? this.overlayColor.toObject(e) : this.overlayColor), r && !r.excludeFromExport && (i.backgroundImage = this._toObject(r, t, e)), n && !n.excludeFromExport && (i.overlayImage = this._toObject(n, t, e)), i }, svgViewportTransformation: !0, toSVG: function(t, e) { t || (t = {}), t.reviver = e; var i = []; return this._setSVGPreamble(i, t), this._setSVGHeader(i, t), this.clipPath && i.push('<g clip-path="url(#' + this.clipPath.clipPathId + ')" >\n'), this._setSVGBgOverlayColor(i, "background"), this._setSVGBgOverlayImage(i, "backgroundImage", e), this._setSVGObjects(i, e), this.clipPath && i.push("</g>\n"), this._setSVGBgOverlayColor(i, "overlay"), this._setSVGBgOverlayImage(i, "overlayImage", e), i.push("</svg>"), i.join("") }, _setSVGPreamble: function(t, e) { e.suppressPreamble || t.push('<?xml version="1.0" encoding="', e.encoding || "UTF-8", '" standalone="no" ?>\n', '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" ', '"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n') }, _setSVGHeader: function(t, e) { var i, s = e.width || this.width,
                                    o = e.height || this.height,
                                    a = 'viewBox="0 0 ' + this.width + " " + this.height + '" ',
                                    h = r.Object.NUM_FRACTION_DIGITS;
                                e.viewBox ? a = 'viewBox="' + e.viewBox.x + " " + e.viewBox.y + " " + e.viewBox.width + " " + e.viewBox.height + '" ' : this.svgViewportTransformation && (i = this.viewportTransform, a = 'viewBox="' + n(-i[4] / i[0], h) + " " + n(-i[5] / i[3], h) + " " + n(this.width / i[0], h) + " " + n(this.height / i[3], h) + '" '), t.push("<svg ", 'xmlns="http://www.w3.org/2000/svg" ', 'xmlns:xlink="http://www.w3.org/1999/xlink" ', 'version="1.1" ', 'width="', s, '" ', 'height="', o, '" ', a, 'xml:space="preserve">\n', "<desc>Created with Fabric.js ", r.version, "</desc>\n", "<defs>\n", this.createSVGFontFacesMarkup(), this.createSVGRefElementsMarkup(), this.createSVGClipPathMarkup(e), "</defs>\n") }, createSVGClipPathMarkup: function(t) { var e = this.clipPath; return e ? (e.clipPathId = "CLIPPATH_" + r.Object.__uid++, '<clipPath id="' + e.clipPathId + '" >\n' + this.clipPath.toClipPathSVG(t.reviver) + "</clipPath>\n") : "" }, createSVGRefElementsMarkup: function() { var t = this; return ["background", "overlay"].map(function(e) { var i = t[e + "Color"]; if (i && i.toLive) { var n = t[e + "Vpt"],
                                            s = t.viewportTransform,
                                            o = { width: t.width / (n ? s[0] : 1), height: t.height / (n ? s[3] : 1) }; return i.toSVG(o, { additionalTransform: n ? r.util.matrixToSVG(s) : "" }) } }).join("") }, createSVGFontFacesMarkup: function() { var t, e, i, n, s, o, a, h, c = "",
                                    l = {},
                                    u = r.fontPaths,
                                    f = this._objects; for (a = 0, h = f.length; a < h; a++)
                                    if (e = (t = f[a]).fontFamily, -1 !== t.type.indexOf("text") && !l[e] && u[e] && (l[e] = !0, t.styles))
                                        for (s in i = t.styles)
                                            for (o in n = i[s]) !l[e = n[o].fontFamily] && u[e] && (l[e] = !0); for (var d in l) c += ["\t\t@font-face {\n", "\t\t\tfont-family: '", d, "';\n", "\t\t\tsrc: url('", u[d], "');\n", "\t\t}\n"].join(""); return c && (c = ['\t<style type="text/css">', "<![CDATA[\n", c, "]]>", "</style>\n"].join("")), c }, _setSVGObjects: function(t, e) { var i, r, n, s = this._objects; for (r = 0, n = s.length; r < n; r++)(i = s[r]).excludeFromExport || this._setSVGObject(t, i, e) }, _setSVGObject: function(t, e, i) { t.push(e.toSVG(i)) }, _setSVGBgOverlayImage: function(t, e, i) { this[e] && !this[e].excludeFromExport && this[e].toSVG && t.push(this[e].toSVG(i)) }, _setSVGBgOverlayColor: function(t, e) { var i = this[e + "Color"],
                                    n = this.viewportTransform,
                                    s = this.width,
                                    o = this.height; if (i)
                                    if (i.toLive) { var a = i.repeat,
                                            h = r.util.invertTransform(n),
                                            c = this[e + "Vpt"] ? r.util.matrixToSVG(h) : "";
                                        t.push('<rect transform="' + c + " translate(", s / 2, ",", o / 2, ')"', ' x="', i.offsetX - s / 2, '" y="', i.offsetY - o / 2, '" ', 'width="', "repeat-y" === a || "no-repeat" === a ? i.source.width : s, '" height="', "repeat-x" === a || "no-repeat" === a ? i.source.height : o, '" fill="url(#SVGID_' + i.id + ')"', "></rect>\n") } else t.push('<rect x="0" y="0" width="100%" height="100%" ', 'fill="', i, '"', "></rect>\n") }, sendToBack: function(t) { if (!t) return this; var e, r, n, s = this._activeObject; if (t === s && "activeSelection" === t.type)
                                    for (e = (n = s._objects).length; e--;) r = n[e], i(this._objects, r), this._objects.unshift(r);
                                else i(this._objects, t), this._objects.unshift(t); return this.renderOnAddRemove && this.requestRenderAll(), this }, bringToFront: function(t) { if (!t) return this; var e, r, n, s = this._activeObject; if (t === s && "activeSelection" === t.type)
                                    for (n = s._objects, e = 0; e < n.length; e++) r = n[e], i(this._objects, r), this._objects.push(r);
                                else i(this._objects, t), this._objects.push(t); return this.renderOnAddRemove && this.requestRenderAll(), this }, sendBackwards: function(t, e) { if (!t) return this; var r, n, s, o, a, h = this._activeObject,
                                    c = 0; if (t === h && "activeSelection" === t.type)
                                    for (a = h._objects, r = 0; r < a.length; r++) n = a[r], (s = this._objects.indexOf(n)) > 0 + c && (o = s - 1, i(this._objects, n), this._objects.splice(o, 0, n)), c++;
                                else 0 !== (s = this._objects.indexOf(t)) && (o = this._findNewLowerIndex(t, s, e), i(this._objects, t), this._objects.splice(o, 0, t)); return this.renderOnAddRemove && this.requestRenderAll(), this }, _findNewLowerIndex: function(t, e, i) { var r, n; if (i)
                                    for (r = e, n = e - 1; n >= 0; --n) { if (t.intersectsWithObject(this._objects[n]) || t.isContainedWithinObject(this._objects[n]) || this._objects[n].isContainedWithinObject(t)) { r = n; break } } else r = e - 1; return r }, bringForward: function(t, e) { if (!t) return this; var r, n, s, o, a, h = this._activeObject,
                                    c = 0; if (t === h && "activeSelection" === t.type)
                                    for (r = (a = h._objects).length; r--;) n = a[r], (s = this._objects.indexOf(n)) < this._objects.length - 1 - c && (o = s + 1, i(this._objects, n), this._objects.splice(o, 0, n)), c++;
                                else(s = this._objects.indexOf(t)) !== this._objects.length - 1 && (o = this._findNewUpperIndex(t, s, e), i(this._objects, t), this._objects.splice(o, 0, t)); return this.renderOnAddRemove && this.requestRenderAll(), this }, _findNewUpperIndex: function(t, e, i) { var r, n, s; if (i)
                                    for (r = e, n = e + 1, s = this._objects.length; n < s; ++n) { if (t.intersectsWithObject(this._objects[n]) || t.isContainedWithinObject(this._objects[n]) || this._objects[n].isContainedWithinObject(t)) { r = n; break } } else r = e + 1; return r }, moveTo: function(t, e) { return i(this._objects, t), this._objects.splice(e, 0, t), this.renderOnAddRemove && this.requestRenderAll() }, dispose: function() { return this.isRendering && (r.util.cancelAnimFrame(this.isRendering), this.isRendering = 0), this.forEachObject(function(t) { t.dispose && t.dispose() }), this._objects = [], this.backgroundImage && this.backgroundImage.dispose && this.backgroundImage.dispose(), this.backgroundImage = null, this.overlayImage && this.overlayImage.dispose && this.overlayImage.dispose(), this.overlayImage = null, this._iTextInstances = null, this.contextContainer = null, r.util.cleanUpJsdomNode(this.lowerCanvasEl), this.lowerCanvasEl = void 0, this }, toString: function() { return "#<fabric.Canvas (" + this.complexity() + "): { objects: " + this._objects.length + " }>" } }), t(r.StaticCanvas.prototype, r.Observable), t(r.StaticCanvas.prototype, r.Collection), t(r.StaticCanvas.prototype, r.DataURLExporter), t(r.StaticCanvas, { EMPTY_JSON: '{"objects": [], "background": "white"}', supports: function(t) { var e = h(); if (!e || !e.getContext) return null; var i = e.getContext("2d"); if (!i) return null; switch (t) {
                                    case "setLineDash":
                                        return void 0 !== i.setLineDash;
                                    default:
                                        return null } } }), r.StaticCanvas.prototype.toJSON = r.StaticCanvas.prototype.toObject, r.isLikelyNode && (r.StaticCanvas.prototype.createPNGStream = function() { var t = a(this.lowerCanvasEl); return t && t.createPNGStream() }, r.StaticCanvas.prototype.createJPEGStream = function(t) { var e = a(this.lowerCanvasEl); return e && e.createJPEGStream(t) }) } }(), r.BaseBrush = r.util.createClass({ color: "rgb(0, 0, 0)", width: 1, shadow: null, strokeLineCap: "round", strokeLineJoin: "round", strokeMiterLimit: 10, strokeDashArray: null, setShadow: function(t) { return this.shadow = new r.Shadow(t), this }, _setBrushStyles: function() { var t = this.canvas.contextTop;
                        t.strokeStyle = this.color, t.lineWidth = this.width, t.lineCap = this.strokeLineCap, t.miterLimit = this.strokeMiterLimit, t.lineJoin = this.strokeLineJoin, r.StaticCanvas.supports("setLineDash") && t.setLineDash(this.strokeDashArray || []) }, _saveAndTransform: function(t) { var e = this.canvas.viewportTransform;
                        t.save(), t.transform(e[0], e[1], e[2], e[3], e[4], e[5]) }, _setShadow: function() { if (this.shadow) { var t = this.canvas.contextTop,
                                e = this.canvas.getZoom();
                            t.shadowColor = this.shadow.color, t.shadowBlur = this.shadow.blur * e, t.shadowOffsetX = this.shadow.offsetX * e, t.shadowOffsetY = this.shadow.offsetY * e } }, needsFullRender: function() { return new r.Color(this.color).getAlpha() < 1 || !!this.shadow }, _resetShadow: function() { var t = this.canvas.contextTop;
                        t.shadowColor = "", t.shadowBlur = t.shadowOffsetX = t.shadowOffsetY = 0 } }), r.PencilBrush = r.util.createClass(r.BaseBrush, { decimate: .4, initialize: function(t) { this.canvas = t, this._points = [] }, _drawSegment: function(t, e, i) { var r = e.midPointFrom(i); return t.quadraticCurveTo(e.x, e.y, r.x, r.y), r }, onMouseDown: function(t, e) { this.canvas._isMainEvent(e.e) && (this._prepareForDrawing(t), this._captureDrawingPath(t), this._render()) }, onMouseMove: function(t, e) { if (this.canvas._isMainEvent(e.e) && this._captureDrawingPath(t) && this._points.length > 1)
                            if (this.needsFullRender()) this.canvas.clearContext(this.canvas.contextTop), this._render();
                            else { var i = this._points,
                                    r = i.length,
                                    n = this.canvas.contextTop;
                                this._saveAndTransform(n), this.oldEnd && (n.beginPath(), n.moveTo(this.oldEnd.x, this.oldEnd.y)), this.oldEnd = this._drawSegment(n, i[r - 2], i[r - 1], !0), n.stroke(), n.restore() } }, onMouseUp: function(t) { return !this.canvas._isMainEvent(t.e) || (this.oldEnd = void 0, this._finalizeAndAddPath(), !1) }, _prepareForDrawing: function(t) { var e = new r.Point(t.x, t.y);
                        this._reset(), this._addPoint(e), this.canvas.contextTop.moveTo(e.x, e.y) }, _addPoint: function(t) { return !(this._points.length > 1 && t.eq(this._points[this._points.length - 1]) || (this._points.push(t), 0)) }, _reset: function() { this._points = [], this._setBrushStyles(), this._setShadow() }, _captureDrawingPath: function(t) { var e = new r.Point(t.x, t.y); return this._addPoint(e) }, _render: function() { var t, e, i = this.canvas.contextTop,
                            n = this._points[0],
                            s = this._points[1]; if (this._saveAndTransform(i), i.beginPath(), 2 === this._points.length && n.x === s.x && n.y === s.y) { var o = this.width / 1e3;
                            n = new r.Point(n.x, n.y), s = new r.Point(s.x, s.y), n.x -= o, s.x += o } for (i.moveTo(n.x, n.y), t = 1, e = this._points.length; t < e; t++) this._drawSegment(i, n, s), n = this._points[t], s = this._points[t + 1];
                        i.lineTo(n.x, n.y), i.stroke(), i.restore() }, convertPointsToSVGPath: function(t) { var e, i = [],
                            n = this.width / 1e3,
                            s = new r.Point(t[0].x, t[0].y),
                            o = new r.Point(t[1].x, t[1].y),
                            a = t.length,
                            h = 1,
                            c = 0,
                            l = a > 2; for (l && (h = t[2].x < o.x ? -1 : t[2].x === o.x ? 0 : 1, c = t[2].y < o.y ? -1 : t[2].y === o.y ? 0 : 1), i.push("M ", s.x - h * n, " ", s.y - c * n, " "), e = 1; e < a; e++) { if (!s.eq(o)) { var u = s.midPointFrom(o);
                                i.push("Q ", s.x, " ", s.y, " ", u.x, " ", u.y, " ") } s = t[e], e + 1 < t.length && (o = t[e + 1]) } return l && (h = s.x > t[e - 2].x ? 1 : s.x === t[e - 2].x ? 0 : -1, c = s.y > t[e - 2].y ? 1 : s.y === t[e - 2].y ? 0 : -1), i.push("L ", s.x + h * n, " ", s.y + c * n), i }, createPath: function(t) { var e = new r.Path(t, { fill: null, stroke: this.color, strokeWidth: this.width, strokeLineCap: this.strokeLineCap, strokeMiterLimit: this.strokeMiterLimit, strokeLineJoin: this.strokeLineJoin, strokeDashArray: this.strokeDashArray }); return this.shadow && (this.shadow.affectStroke = !0, e.setShadow(this.shadow)), e }, decimatePoints: function(t, e) { if (t.length <= 2) return t; var i, n = this.canvas.getZoom(),
                            s = Math.pow(e / n, 2),
                            o = t.length - 1,
                            a = t[0],
                            h = [a]; for (i = 1; i < o; i++) Math.pow(a.x - t[i].x, 2) + Math.pow(a.y - t[i].y, 2) >= s && (a = t[i], h.push(a)); return 1 === h.length && h.push(new r.Point(h[0].x, h[0].y)), h }, _finalizeAndAddPath: function() { this.canvas.contextTop.closePath(), this.decimate && (this._points = this.decimatePoints(this._points, this.decimate)); var t = this.convertPointsToSVGPath(this._points).join(""); if ("M 0 0 Q 0 0 0 0 L 0 0" !== t) { var e = this.createPath(t);
                            this.canvas.clearContext(this.canvas.contextTop), this.canvas.add(e), this.canvas.renderAll(), e.setCoords(), this._resetShadow(), this.canvas.fire("path:created", { path: e }) } else this.canvas.requestRenderAll() } }), r.CircleBrush = r.util.createClass(r.BaseBrush, { width: 10, initialize: function(t) { this.canvas = t, this.points = [] }, drawDot: function(t) { var e = this.addPoint(t),
                            i = this.canvas.contextTop;
                        this._saveAndTransform(i), this.dot(i, e), i.restore() }, dot: function(t, e) { t.fillStyle = e.fill, t.beginPath(), t.arc(e.x, e.y, e.radius, 0, 2 * Math.PI, !1), t.closePath(), t.fill() }, onMouseDown: function(t) { this.points.length = 0, this.canvas.clearContext(this.canvas.contextTop), this._setShadow(), this.drawDot(t) }, _render: function() { var t, e, i = this.canvas.contextTop,
                            r = this.points; for (this._saveAndTransform(i), t = 0, e = r.length; t < e; t++) this.dot(i, r[t]);
                        i.restore() }, onMouseMove: function(t) { this.needsFullRender() ? (this.canvas.clearContext(this.canvas.contextTop), this.addPoint(t), this._render()) : this.drawDot(t) }, onMouseUp: function() { var t, e, i = this.canvas.renderOnAddRemove;
                        this.canvas.renderOnAddRemove = !1; var n = []; for (t = 0, e = this.points.length; t < e; t++) { var s = this.points[t],
                                o = new r.Circle({ radius: s.radius, left: s.x, top: s.y, originX: "center", originY: "center", fill: s.fill });
                            this.shadow && o.setShadow(this.shadow), n.push(o) } var a = new r.Group(n);
                        a.canvas = this.canvas, this.canvas.add(a), this.canvas.fire("path:created", { path: a }), this.canvas.clearContext(this.canvas.contextTop), this._resetShadow(), this.canvas.renderOnAddRemove = i, this.canvas.requestRenderAll() }, addPoint: function(t) { var e = new r.Point(t.x, t.y),
                            i = r.util.getRandomInt(Math.max(0, this.width - 20), this.width + 20) / 2,
                            n = new r.Color(this.color).setAlpha(r.util.getRandomInt(0, 100) / 100).toRgba(); return e.radius = i, e.fill = n, this.points.push(e), e } }), r.SprayBrush = r.util.createClass(r.BaseBrush, { width: 10, density: 20, dotWidth: 1, dotWidthVariance: 1, randomOpacity: !1, optimizeOverlapping: !0, initialize: function(t) { this.canvas = t, this.sprayChunks = [] }, onMouseDown: function(t) { this.sprayChunks.length = 0, this.canvas.clearContext(this.canvas.contextTop), this._setShadow(), this.addSprayChunk(t), this.render(this.sprayChunkPoints) }, onMouseMove: function(t) { this.addSprayChunk(t), this.render(this.sprayChunkPoints) }, onMouseUp: function() { var t = this.canvas.renderOnAddRemove;
                        this.canvas.renderOnAddRemove = !1; for (var e = [], i = 0, n = this.sprayChunks.length; i < n; i++)
                            for (var s = this.sprayChunks[i], o = 0, a = s.length; o < a; o++) { var h = new r.Rect({ width: s[o].width, height: s[o].width, left: s[o].x + 1, top: s[o].y + 1, originX: "center", originY: "center", fill: this.color });
                                e.push(h) } this.optimizeOverlapping && (e = this._getOptimizedRects(e)); var c = new r.Group(e);
                        this.shadow && c.setShadow(this.shadow), this.canvas.add(c), this.canvas.fire("path:created", { path: c }), this.canvas.clearContext(this.canvas.contextTop), this._resetShadow(), this.canvas.renderOnAddRemove = t, this.canvas.requestRenderAll() }, _getOptimizedRects: function(t) { var e, i, r, n = {}; for (i = 0, r = t.length; i < r; i++) n[e = t[i].left + "" + t[i].top] || (n[e] = t[i]); var s = []; for (e in n) s.push(n[e]); return s }, render: function(t) { var e, i, r = this.canvas.contextTop; for (r.fillStyle = this.color, this._saveAndTransform(r), e = 0, i = t.length; e < i; e++) { var n = t[e];
                            void 0 !== n.opacity && (r.globalAlpha = n.opacity), r.fillRect(n.x, n.y, n.width, n.width) } r.restore() }, _render: function() { var t, e, i = this.canvas.contextTop; for (i.fillStyle = this.color, this._saveAndTransform(i), t = 0, e = this.sprayChunks.length; t < e; t++) this.render(this.sprayChunks[t]);
                        i.restore() }, addSprayChunk: function(t) { this.sprayChunkPoints = []; var e, i, n, s, o = this.width / 2; for (s = 0; s < this.density; s++) { e = r.util.getRandomInt(t.x - o, t.x + o), i = r.util.getRandomInt(t.y - o, t.y + o), n = this.dotWidthVariance ? r.util.getRandomInt(Math.max(1, this.dotWidth - this.dotWidthVariance), this.dotWidth + this.dotWidthVariance) : this.dotWidth; var a = new r.Point(e, i);
                            a.width = n, this.randomOpacity && (a.opacity = r.util.getRandomInt(0, 100) / 100), this.sprayChunkPoints.push(a) } this.sprayChunks.push(this.sprayChunkPoints) } }), r.PatternBrush = r.util.createClass(r.PencilBrush, { getPatternSrc: function() { var t = r.util.createCanvasElement(),
                            e = t.getContext("2d"); return t.width = t.height = 25, e.fillStyle = this.color, e.beginPath(), e.arc(10, 10, 10, 0, 2 * Math.PI, !1), e.closePath(), e.fill(), t }, getPatternSrcFunction: function() { return String(this.getPatternSrc).replace("this.color", '"' + this.color + '"') }, getPattern: function() { return this.canvas.contextTop.createPattern(this.source || this.getPatternSrc(), "repeat") }, _setBrushStyles: function() { this.callSuper("_setBrushStyles"), this.canvas.contextTop.strokeStyle = this.getPattern() }, createPath: function(t) { var e = this.callSuper("createPath", t),
                            i = e._getLeftTopCoords().scalarAdd(e.strokeWidth / 2); return e.stroke = new r.Pattern({ source: this.source || this.getPatternSrcFunction(), offsetX: -i.x, offsetY: -i.y }), e } }),
                function() { var t = r.util.getPointer,
                        e = r.util.degreesToRadians,
                        i = r.util.radiansToDegrees,
                        n = Math.atan2,
                        s = Math.abs,
                        o = r.StaticCanvas.supports("setLineDash"); for (var a in r.Canvas = r.util.createClass(r.StaticCanvas, { initialize: function(t, e) { e || (e = {}), this.renderAndResetBound = this.renderAndReset.bind(this), this.requestRenderAllBound = this.requestRenderAll.bind(this), this._initStatic(t, e), this._initInteractive(), this._createCacheCanvas() }, uniScaleTransform: !1, uniScaleKey: "shiftKey", centeredScaling: !1, centeredRotation: !1, centeredKey: "altKey", altActionKey: "shiftKey", interactive: !0, selection: !0, selectionKey: "shiftKey", altSelectionKey: null, selectionColor: "rgba(100, 100, 255, 0.3)", selectionDashArray: [], selectionBorderColor: "rgba(255, 255, 255, 0.3)", selectionLineWidth: 1, selectionFullyContained: !1, hoverCursor: "move", moveCursor: "move", defaultCursor: "default", freeDrawingCursor: "crosshair", rotationCursor: "crosshair", notAllowedCursor: "not-allowed", containerClass: "canvas-container", perPixelTargetFind: !1, targetFindTolerance: 0, skipTargetFind: !1, isDrawingMode: !1, preserveObjectStacking: !1, snapAngle: 0, snapThreshold: null, stopContextMenu: !1, fireRightClick: !1, fireMiddleClick: !1, _initInteractive: function() { this._currentTransform = null, this._groupSelector = null, this._initWrapperElement(), this._createUpperCanvas(), this._initEventListeners(), this._initRetinaScaling(), this.freeDrawingBrush = r.PencilBrush && new r.PencilBrush(this), this.calcOffset() }, _chooseObjectsToRender: function() { var t, e, i, r = this.getActiveObjects(); if (r.length > 0 && !this.preserveObjectStacking) { e = [], i = []; for (var n = 0, s = this._objects.length; n < s; n++) t = this._objects[n], -1 === r.indexOf(t) ? e.push(t) : i.push(t);
                                    r.length > 1 && (this._activeObject._objects = i), e.push.apply(e, i) } else e = this._objects; return e }, renderAll: function() {!this.contextTopDirty || this._groupSelector || this.isDrawingMode || (this.clearContext(this.contextTop), this.contextTopDirty = !1), this.hasLostContext && this.renderTopLayer(this.contextTop); var t = this.contextContainer; return this.renderCanvas(t, this._chooseObjectsToRender()), this }, renderTopLayer: function(t) { t.save(), this.isDrawingMode && this._isCurrentlyDrawing && (this.freeDrawingBrush && this.freeDrawingBrush._render(), this.contextTopDirty = !0), this.selection && this._groupSelector && (this._drawSelection(t), this.contextTopDirty = !0), t.restore() }, renderTop: function() { var t = this.contextTop; return this.clearContext(t), this.renderTopLayer(t), this.fire("after:render"), this }, _resetCurrentTransform: function() { var t = this._currentTransform;
                                t.target.set({ scaleX: t.original.scaleX, scaleY: t.original.scaleY, skewX: t.original.skewX, skewY: t.original.skewY, left: t.original.left, top: t.original.top }), this._shouldCenterTransform(t.target) ? ("center" !== t.originX && ("right" === t.originX ? t.mouseXSign = -1 : t.mouseXSign = 1), "center" !== t.originY && ("bottom" === t.originY ? t.mouseYSign = -1 : t.mouseYSign = 1), t.originX = "center", t.originY = "center") : (t.originX = t.original.originX, t.originY = t.original.originY) }, containsPoint: function(t, e, i) { var r, n = i || this.getPointer(t, !0); return r = e.group && e.group === this._activeObject && "activeSelection" === e.group.type ? this._normalizePointer(e.group, n) : { x: n.x, y: n.y }, e.containsPoint(r) || e._findTargetCorner(n) }, _normalizePointer: function(t, e) { var i = t.calcTransformMatrix(),
                                    n = r.util.invertTransform(i),
                                    s = this.restorePointerVpt(e); return r.util.transformPoint(s, n) }, isTargetTransparent: function(t, e, i) { if (t.shouldCache() && t._cacheCanvas && t !== this._activeObject) { var n = this._normalizePointer(t, { x: e, y: i }),
                                        s = Math.max(t.cacheTranslationX + n.x * t.zoomX, 0),
                                        o = Math.max(t.cacheTranslationY + n.y * t.zoomY, 0); return r.util.isTransparent(t._cacheContext, Math.round(s), Math.round(o), this.targetFindTolerance) } var a = this.contextCache,
                                    h = t.selectionBackgroundColor,
                                    c = this.viewportTransform; return t.selectionBackgroundColor = "", this.clearContext(a), a.save(), a.transform(c[0], c[1], c[2], c[3], c[4], c[5]), t.render(a), a.restore(), t === this._activeObject && t._renderControls(a, { hasBorders: !1, transparentCorners: !1 }, { hasBorders: !1 }), t.selectionBackgroundColor = h, r.util.isTransparent(a, e, i, this.targetFindTolerance) }, _isSelectionKeyPressed: function(t) { return "[object Array]" === Object.prototype.toString.call(this.selectionKey) ? !!this.selectionKey.find(function(e) { return !0 === t[e] }) : t[this.selectionKey] }, _shouldClearSelection: function(t, e) { var i = this.getActiveObjects(),
                                    r = this._activeObject; return !e || e && r && i.length > 1 && -1 === i.indexOf(e) && r !== e && !this._isSelectionKeyPressed(t) || e && !e.evented || e && !e.selectable && r && r !== e }, _shouldCenterTransform: function(t) { if (t) { var e, i = this._currentTransform; return "scale" === i.action || "scaleX" === i.action || "scaleY" === i.action ? e = this.centeredScaling || t.centeredScaling : "rotate" === i.action && (e = this.centeredRotation || t.centeredRotation), e ? !i.altKey : i.altKey } }, _getOriginFromCorner: function(t, e) { var i = { x: t.originX, y: t.originY }; return "ml" === e || "tl" === e || "bl" === e ? i.x = "right" : "mr" !== e && "tr" !== e && "br" !== e || (i.x = "left"), "tl" === e || "mt" === e || "tr" === e ? i.y = "bottom" : "bl" !== e && "mb" !== e && "br" !== e || (i.y = "top"), i }, _getActionFromCorner: function(t, e, i) { if (!e || !t) return "drag"; switch (e) {
                                    case "mtr":
                                        return "rotate";
                                    case "ml":
                                    case "mr":
                                        return i[this.altActionKey] ? "skewY" : "scaleX";
                                    case "mt":
                                    case "mb":
                                        return i[this.altActionKey] ? "skewX" : "scaleY";
                                    default:
                                        return "scale" } }, _setupCurrentTransform: function(t, i, n) { if (i) { var s = this.getPointer(t),
                                        o = i._findTargetCorner(this.getPointer(t, !0)),
                                        a = this._getActionFromCorner(n, o, t, i),
                                        h = this._getOriginFromCorner(i, o);
                                    this._currentTransform = { target: i, action: a, corner: o, scaleX: i.scaleX, scaleY: i.scaleY, skewX: i.skewX, skewY: i.skewY, offsetX: s.x - i.left, offsetY: s.y - i.top, originX: h.x, originY: h.y, ex: s.x, ey: s.y, lastX: s.x, lastY: s.y, theta: e(i.angle), width: i.width * i.scaleX, mouseXSign: 1, mouseYSign: 1, shiftKey: t.shiftKey, altKey: t[this.centeredKey], original: r.util.saveObjectTransform(i) }, this._currentTransform.original.originX = h.x, this._currentTransform.original.originY = h.y, this._resetCurrentTransform(), this._beforeTransform(t) } }, _translateObject: function(t, e) { var i = this._currentTransform,
                                    r = i.target,
                                    n = t - i.offsetX,
                                    s = e - i.offsetY,
                                    o = !r.get("lockMovementX") && r.left !== n,
                                    a = !r.get("lockMovementY") && r.top !== s; return o && r.set("left", n), a && r.set("top", s), o || a }, _changeSkewTransformOrigin: function(t, e, i) { var r = "originX",
                                    n = { 0: "center" },
                                    s = e.target.skewX,
                                    o = "left",
                                    a = "right",
                                    h = "mt" === e.corner || "ml" === e.corner ? 1 : -1,
                                    c = 1;
                                t = t > 0 ? 1 : -1, "y" === i && (s = e.target.skewY, o = "top", a = "bottom", r = "originY"), n[-1] = o, n[1] = a, e.target.flipX && (c *= -1), e.target.flipY && (c *= -1), 0 === s ? (e.skewSign = -h * t * c, e[r] = n[-t]) : (s = s > 0 ? 1 : -1, e.skewSign = s, e[r] = n[s * h * c]) }, _skewObject: function(t, e, i) { var n, s = this._currentTransform,
                                    o = s.target,
                                    a = o.get("lockSkewingX"),
                                    h = o.get("lockSkewingY"); if (a && "x" === i || h && "y" === i) return !1; var c, l, u = o.getCenterPoint(),
                                    f = o.toLocalPoint(new r.Point(t, e), "center", "center")[i],
                                    d = o.toLocalPoint(new r.Point(s.lastX, s.lastY), "center", "center")[i],
                                    g = o._getTransformedDimensions(); return this._changeSkewTransformOrigin(f - d, s, i), c = o.toLocalPoint(new r.Point(t, e), s.originX, s.originY)[i], l = o.translateToOriginPoint(u, s.originX, s.originY), n = this._setObjectSkew(c, s, i, g), s.lastX = t, s.lastY = e, o.setPositionByOrigin(l, s.originX, s.originY), n }, _setObjectSkew: function(t, e, i, n) { var s, o, a, h, c, l, u, f, d, g, p = e.target,
                                    v = e.skewSign; return "x" === i ? (c = "y", l = "Y", u = "X", d = 0, g = p.skewY) : (c = "x", l = "X", u = "Y", d = p.skewX, g = 0), h = p._getTransformedDimensions(d, g), (f = 2 * Math.abs(t) - h[i]) <= 2 ? s = 0 : (s = v * Math.atan(f / p["scale" + u] / (h[c] / p["scale" + l])), s = r.util.radiansToDegrees(s)), o = p["skew" + u] !== s, p.set("skew" + u, s), 0 !== p["skew" + l] && (a = p._getTransformedDimensions(), s = n[c] / a[c] * p["scale" + l], p.set("scale" + l, s)), o }, _scaleObject: function(t, e, i) { var n = this._currentTransform,
                                    s = n.target,
                                    o = s.lockScalingX,
                                    a = s.lockScalingY,
                                    h = s.lockScalingFlip; if (o && a) return !1; var c, l = s.translateToOriginPoint(s.getCenterPoint(), n.originX, n.originY),
                                    u = s.toLocalPoint(new r.Point(t, e), n.originX, n.originY),
                                    f = s._getTransformedDimensions(); return this._setLocalMouse(u, n), c = this._setObjectScale(u, n, o, a, i, h, f), s.setPositionByOrigin(l, n.originX, n.originY), c }, _setObjectScale: function(t, e, i, n, s, o, a) { var h = e.target,
                                    c = !1,
                                    l = !1,
                                    u = !1,
                                    f = t.x * h.scaleX / a.x,
                                    d = t.y * h.scaleY / a.y,
                                    g = h.scaleX !== f,
                                    p = h.scaleY !== d; if (e.newScaleX = f, e.newScaleY = d, "x" === s && h instanceof r.Textbox) { var v = h.width * (t.x / a.x); return v >= h.getMinWidth() && (u = v !== h.width, h.set("width", v), u) } return o && f <= 0 && f < h.scaleX && (c = !0, t.x = 0), o && d <= 0 && d < h.scaleY && (l = !0, t.y = 0), "equally" !== s || i || n ? s ? "x" !== s || h.get("lockUniScaling") ? "y" !== s || h.get("lockUniScaling") || l || n || h.set("scaleY", d) && (u = p) : c || i || h.set("scaleX", f) && (u = g) : (c || i || h.set("scaleX", f) && (u = u || g), l || n || h.set("scaleY", d) && (u = u || p)) : u = this._scaleObjectEqually(t, h, e, a), c || l || this._flipObject(e, s), u }, _scaleObjectEqually: function(t, e, i, r) { var n, s, o, a = t.y + t.x,
                                    h = r.y * i.original.scaleY / e.scaleY + r.x * i.original.scaleX / e.scaleX,
                                    c = t.x < 0 ? -1 : 1,
                                    l = t.y < 0 ? -1 : 1; return s = c * Math.abs(i.original.scaleX * a / h), o = l * Math.abs(i.original.scaleY * a / h), n = s !== e.scaleX || o !== e.scaleY, e.set("scaleX", s), e.set("scaleY", o), n }, _flipObject: function(t, e) { t.newScaleX < 0 && "y" !== e && ("left" === t.originX ? t.originX = "right" : "right" === t.originX && (t.originX = "left")), t.newScaleY < 0 && "x" !== e && ("top" === t.originY ? t.originY = "bottom" : "bottom" === t.originY && (t.originY = "top")) }, _setLocalMouse: function(t, e) { var i = e.target,
                                    r = this.getZoom(),
                                    n = i.padding / r; "right" === e.originX ? t.x *= -1 : "center" === e.originX && (t.x *= 2 * e.mouseXSign, t.x < 0 && (e.mouseXSign = -e.mouseXSign)), "bottom" === e.originY ? t.y *= -1 : "center" === e.originY && (t.y *= 2 * e.mouseYSign, t.y < 0 && (e.mouseYSign = -e.mouseYSign)), s(t.x) > n ? t.x < 0 ? t.x += n : t.x -= n : t.x = 0, s(t.y) > n ? t.y < 0 ? t.y += n : t.y -= n : t.y = 0 }, _rotateObject: function(t, e) { var r = this._currentTransform,
                                    s = r.target,
                                    o = s.translateToOriginPoint(s.getCenterPoint(), r.originX, r.originY); if (s.lockRotation) return !1; var a = n(r.ey - o.y, r.ex - o.x),
                                    h = n(e - o.y, t - o.x),
                                    c = i(h - a + r.theta),
                                    l = !0; if (s.snapAngle > 0) { var u = s.snapAngle,
                                        f = s.snapThreshold || u,
                                        d = Math.ceil(c / u) * u,
                                        g = Math.floor(c / u) * u;
                                    Math.abs(c - g) < f ? c = g : Math.abs(c - d) < f && (c = d) } return c < 0 && (c = 360 + c), c %= 360, s.angle === c ? l = !1 : (s.angle = c, s.setPositionByOrigin(o, r.originX, r.originY)), l }, setCursor: function(t) { this.upperCanvasEl.style.cursor = t }, _drawSelection: function(t) { var e = this._groupSelector,
                                    i = e.left,
                                    n = e.top,
                                    a = s(i),
                                    h = s(n); if (this.selectionColor && (t.fillStyle = this.selectionColor, t.fillRect(e.ex - (i > 0 ? 0 : -i), e.ey - (n > 0 ? 0 : -n), a, h)), this.selectionLineWidth && this.selectionBorderColor)
                                    if (t.lineWidth = this.selectionLineWidth, t.strokeStyle = this.selectionBorderColor, this.selectionDashArray.length > 1 && !o) { var c = e.ex + .5 - (i > 0 ? 0 : a),
                                            l = e.ey + .5 - (n > 0 ? 0 : h);
                                        t.beginPath(), r.util.drawDashedLine(t, c, l, c + a, l, this.selectionDashArray), r.util.drawDashedLine(t, c, l + h - 1, c + a, l + h - 1, this.selectionDashArray), r.util.drawDashedLine(t, c, l, c, l + h, this.selectionDashArray), r.util.drawDashedLine(t, c + a - 1, l, c + a - 1, l + h, this.selectionDashArray), t.closePath(), t.stroke() } else r.Object.prototype._setLineDash.call(this, t, this.selectionDashArray), t.strokeRect(e.ex + .5 - (i > 0 ? 0 : a), e.ey + .5 - (n > 0 ? 0 : h), a, h) }, findTarget: function(t, e) { if (!this.skipTargetFind) { var i, r, n = this.getPointer(t, !0),
                                        s = this._activeObject,
                                        o = this.getActiveObjects(); if (this.targets = [], o.length > 1 && !e && s === this._searchPossibleTargets([s], n)) return s; if (1 === o.length && s._findTargetCorner(n)) return s; if (1 === o.length && s === this._searchPossibleTargets([s], n)) { if (!this.preserveObjectStacking) return s;
                                        i = s, r = this.targets, this.targets = [] } var a = this._searchPossibleTargets(this._objects, n); return t[this.altSelectionKey] && a && i && a !== i && (a = i, this.targets = r), a } }, _checkTarget: function(t, e, i) { if (e && e.visible && e.evented && this.containsPoint(null, e, t)) { if (!this.perPixelTargetFind && !e.perPixelTargetFind || e.isEditing) return !0; if (!this.isTargetTransparent(e, i.x, i.y)) return !0 } }, _searchPossibleTargets: function(t, e) { for (var i, n, s = t.length; s--;) { var o = t[s],
                                        a = o.group && "activeSelection" !== o.group.type ? this._normalizePointer(o.group, e) : e; if (this._checkTarget(a, o, e)) {
                                        (i = t[s]).subTargetCheck && i instanceof r.Group && (n = this._searchPossibleTargets(i._objects, e)) && this.targets.push(n); break } } return i }, restorePointerVpt: function(t) { return r.util.transformPoint(t, r.util.invertTransform(this.viewportTransform)) }, getPointer: function(e, i) { if (this._absolutePointer && !i) return this._absolutePointer; if (this._pointer && i) return this._pointer; var r, n = t(e),
                                    s = this.upperCanvasEl,
                                    o = s.getBoundingClientRect(),
                                    a = o.width || 0,
                                    h = o.height || 0; return a && h || ("top" in o && "bottom" in o && (h = Math.abs(o.top - o.bottom)), "right" in o && "left" in o && (a = Math.abs(o.right - o.left))), this.calcOffset(), n.x = n.x - this._offset.left, n.y = n.y - this._offset.top, i || (n = this.restorePointerVpt(n)), r = 0 === a || 0 === h ? { width: 1, height: 1 } : { width: s.width / a, height: s.height / h }, { x: n.x * r.width, y: n.y * r.height } }, _createUpperCanvas: function() { var t = this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/, "");
                                this.upperCanvasEl ? this.upperCanvasEl.className = "" : this.upperCanvasEl = this._createCanvasElement(), r.util.addClass(this.upperCanvasEl, "upper-canvas " + t), this.wrapperEl.appendChild(this.upperCanvasEl), this._copyCanvasStyle(this.lowerCanvasEl, this.upperCanvasEl), this._applyCanvasStyle(this.upperCanvasEl), this.contextTop = this.upperCanvasEl.getContext("2d") }, _createCacheCanvas: function() { this.cacheCanvasEl = this._createCanvasElement(), this.cacheCanvasEl.setAttribute("width", this.width), this.cacheCanvasEl.setAttribute("height", this.height), this.contextCache = this.cacheCanvasEl.getContext("2d") }, _initWrapperElement: function() { this.wrapperEl = r.util.wrapElement(this.lowerCanvasEl, "div", { class: this.containerClass }), r.util.setStyle(this.wrapperEl, { width: this.width + "px", height: this.height + "px", position: "relative" }), r.util.makeElementUnselectable(this.wrapperEl) }, _applyCanvasStyle: function(t) { var e = this.width || t.width,
                                    i = this.height || t.height;
                                r.util.setStyle(t, { position: "absolute", width: e + "px", height: i + "px", left: 0, top: 0, "touch-action": this.allowTouchScrolling ? "manipulation" : "none", "-ms-touch-action": this.allowTouchScrolling ? "manipulation" : "none" }), t.width = e, t.height = i, r.util.makeElementUnselectable(t) }, _copyCanvasStyle: function(t, e) { e.style.cssText = t.style.cssText }, getSelectionContext: function() { return this.contextTop }, getSelectionElement: function() { return this.upperCanvasEl }, getActiveObject: function() { return this._activeObject }, getActiveObjects: function() { var t = this._activeObject; return t ? "activeSelection" === t.type && t._objects ? t._objects.slice(0) : [t] : [] }, _onObjectRemoved: function(t) { t === this._activeObject && (this.fire("before:selection:cleared", { target: t }), this._discardActiveObject(), this.fire("selection:cleared", { target: t }), t.fire("deselected")), this._hoveredTarget === t && (this._hoveredTarget = null), this.callSuper("_onObjectRemoved", t) }, _fireSelectionEvents: function(t, e) { var i = !1,
                                    r = this.getActiveObjects(),
                                    n = [],
                                    s = [],
                                    o = { e: e };
                                t.forEach(function(t) {-1 === r.indexOf(t) && (i = !0, t.fire("deselected", o), s.push(t)) }), r.forEach(function(e) {-1 === t.indexOf(e) && (i = !0, e.fire("selected", o), n.push(e)) }), t.length > 0 && r.length > 0 ? (o.selected = n, o.deselected = s, o.updated = n[0] || s[0], o.target = this._activeObject, i && this.fire("selection:updated", o)) : r.length > 0 ? (1 === r.length && (o.target = n[0], this.fire("object:selected", o)), o.selected = n, o.target = this._activeObject, this.fire("selection:created", o)) : t.length > 0 && (o.deselected = s, this.fire("selection:cleared", o)) }, setActiveObject: function(t, e) { var i = this.getActiveObjects(); return this._setActiveObject(t, e), this._fireSelectionEvents(i, e), this }, _setActiveObject: function(t, e) { return this._activeObject !== t && (!!this._discardActiveObject(e, t) && (!t.onSelect({ e: e }) && (this._activeObject = t, !0))) }, _discardActiveObject: function(t, e) { var i = this._activeObject; if (i) { if (i.onDeselect({ e: t, object: e })) return !1;
                                    this._activeObject = null } return !0 }, discardActiveObject: function(t) { var e = this.getActiveObjects(),
                                    i = this.getActiveObject(); return e.length && this.fire("before:selection:cleared", { target: i, e: t }), this._discardActiveObject(t), this._fireSelectionEvents(e, t), this }, dispose: function() { var t = this.wrapperEl; return this.removeListeners(), t.removeChild(this.upperCanvasEl), t.removeChild(this.lowerCanvasEl), this.contextCache = null, this.contextTop = null, ["upperCanvasEl", "cacheCanvasEl"].forEach(function(t) { r.util.cleanUpJsdomNode(this[t]), this[t] = void 0 }.bind(this)), t.parentNode && t.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl), delete this.wrapperEl, r.StaticCanvas.prototype.dispose.call(this), this }, clear: function() { return this.discardActiveObject(), this.clearContext(this.contextTop), this.callSuper("clear") }, drawControls: function(t) { var e = this._activeObject;
                                e && e._renderControls(t) }, _toObject: function(t, e, i) { var r = this._realizeGroupTransformOnObject(t),
                                    n = this.callSuper("_toObject", t, e, i); return this._unwindGroupTransformOnObject(t, r), n }, _realizeGroupTransformOnObject: function(t) { if (t.group && "activeSelection" === t.group.type && this._activeObject === t.group) { var e = {}; return ["angle", "flipX", "flipY", "left", "scaleX", "scaleY", "skewX", "skewY", "top"].forEach(function(i) { e[i] = t[i] }), this._activeObject.realizeTransform(t), e } return null }, _unwindGroupTransformOnObject: function(t, e) { e && t.set(e) }, _setSVGObject: function(t, e, i) { var r = this._realizeGroupTransformOnObject(e);
                                this.callSuper("_setSVGObject", t, e, i), this._unwindGroupTransformOnObject(e, r) }, setViewportTransform: function(t) { this.renderOnAddRemove && this._activeObject && this._activeObject.isEditing && this._activeObject.clearContextTop(), r.StaticCanvas.prototype.setViewportTransform.call(this, t) } }), r.StaticCanvas) "prototype" !== a && (r.Canvas[a] = r.StaticCanvas[a]) }(),
                function() { var t = { mt: 0, tr: 1, mr: 2, br: 3, mb: 4, bl: 5, ml: 6, tl: 7 },
                        e = r.util.addListener,
                        i = r.util.removeListener,
                        n = { passive: !1 };

                    function s(t, e) { return t.button && t.button === e - 1 } r.util.object.extend(r.Canvas.prototype, { cursorMap: ["n-resize", "ne-resize", "e-resize", "se-resize", "s-resize", "sw-resize", "w-resize", "nw-resize"], mainTouchId: null, _initEventListeners: function() { this.removeListeners(), this._bindEvents(), this.addOrRemove(e, "add") }, _getEventPrefix: function() { return this.enablePointerEvents ? "pointer" : "mouse" }, addOrRemove: function(t, e) { var i = this.upperCanvasEl,
                                s = this._getEventPrefix();
                            t(r.window, "resize", this._onResize), t(i, s + "down", this._onMouseDown), t(i, s + "move", this._onMouseMove, n), t(i, s + "out", this._onMouseOut), t(i, s + "enter", this._onMouseEnter), t(i, "wheel", this._onMouseWheel), t(i, "contextmenu", this._onContextMenu), t(i, "dblclick", this._onDoubleClick), t(i, "dragover", this._onDragOver), t(i, "dragenter", this._onDragEnter), t(i, "dragleave", this._onDragLeave), t(i, "drop", this._onDrop), this.enablePointerEvents || t(i, "touchstart", this._onTouchStart, n), "undefined" != typeof eventjs && e in eventjs && (eventjs[e](i, "gesture", this._onGesture), eventjs[e](i, "drag", this._onDrag), eventjs[e](i, "orientation", this._onOrientationChange), eventjs[e](i, "shake", this._onShake), eventjs[e](i, "longpress", this._onLongPress)) }, removeListeners: function() { this.addOrRemove(i, "remove"); var t = this._getEventPrefix();
                            i(r.document, t + "up", this._onMouseUp), i(r.document, "touchend", this._onTouchEnd, n), i(r.document, t + "move", this._onMouseMove, n), i(r.document, "touchmove", this._onMouseMove, n) }, _bindEvents: function() { this.eventsBound || (this._onMouseDown = this._onMouseDown.bind(this), this._onTouchStart = this._onTouchStart.bind(this), this._onMouseMove = this._onMouseMove.bind(this), this._onMouseUp = this._onMouseUp.bind(this), this._onTouchEnd = this._onTouchEnd.bind(this), this._onResize = this._onResize.bind(this), this._onGesture = this._onGesture.bind(this), this._onDrag = this._onDrag.bind(this), this._onShake = this._onShake.bind(this), this._onLongPress = this._onLongPress.bind(this), this._onOrientationChange = this._onOrientationChange.bind(this), this._onMouseWheel = this._onMouseWheel.bind(this), this._onMouseOut = this._onMouseOut.bind(this), this._onMouseEnter = this._onMouseEnter.bind(this), this._onContextMenu = this._onContextMenu.bind(this), this._onDoubleClick = this._onDoubleClick.bind(this), this._onDragOver = this._onDragOver.bind(this), this._onDragEnter = this._simpleEventHandler.bind(this, "dragenter"), this._onDragLeave = this._simpleEventHandler.bind(this, "dragleave"), this._onDrop = this._simpleEventHandler.bind(this, "drop"), this.eventsBound = !0) }, _onGesture: function(t, e) { this.__onTransformGesture && this.__onTransformGesture(t, e) }, _onDrag: function(t, e) { this.__onDrag && this.__onDrag(t, e) }, _onMouseWheel: function(t) { this.__onMouseWheel(t) }, _onMouseOut: function(t) { var e = this._hoveredTarget;
                            this.fire("mouse:out", { target: e, e: t }), this._hoveredTarget = null, e && e.fire("mouseout", { e: t }), this._iTextInstances && this._iTextInstances.forEach(function(t) { t.isEditing && t.hiddenTextarea.focus() }) }, _onMouseEnter: function(t) { this.currentTransform || this.findTarget(t) || (this.fire("mouse:over", { target: null, e: t }), this._hoveredTarget = null) }, _onOrientationChange: function(t, e) { this.__onOrientationChange && this.__onOrientationChange(t, e) }, _onShake: function(t, e) { this.__onShake && this.__onShake(t, e) }, _onLongPress: function(t, e) { this.__onLongPress && this.__onLongPress(t, e) }, _onDragOver: function(t) { t.preventDefault(); var e = this._simpleEventHandler("dragover", t);
                            this._fireEnterLeaveEvents(e, t) }, _onContextMenu: function(t) { return this.stopContextMenu && (t.stopPropagation(), t.preventDefault()), !1 }, _onDoubleClick: function(t) { this._cacheTransformEventData(t), this._handleEvent(t, "dblclick"), this._resetTransformEventData(t) }, getPointerId: function(t) { var e = t.changedTouches; return e ? e[0] && e[0].identifier : this.enablePointerEvents ? t.pointerId : -1 }, _isMainEvent: function(t) { return !0 === t.isPrimary || !1 !== t.isPrimary && ("touchend" === t.type && 0 === t.touches.length || (!t.changedTouches || t.changedTouches[0].identifier === this.mainTouchId)) }, _onTouchStart: function(t) { t.preventDefault(), null === this.mainTouchId && (this.mainTouchId = this.getPointerId(t)), this.__onMouseDown(t), this._resetTransformEventData(); var s = this.upperCanvasEl,
                                o = this._getEventPrefix();
                            e(r.document, "touchend", this._onTouchEnd, n), e(r.document, "touchmove", this._onMouseMove, n), i(s, o + "down", this._onMouseDown) }, _onMouseDown: function(t) { this.__onMouseDown(t), this._resetTransformEventData(); var s = this.upperCanvasEl,
                                o = this._getEventPrefix();
                            i(s, o + "move", this._onMouseMove, n), e(r.document, o + "up", this._onMouseUp), e(r.document, o + "move", this._onMouseMove, n) }, _onTouchEnd: function(t) { if (!(t.touches.length > 0)) { this.__onMouseUp(t), this._resetTransformEventData(), this.mainTouchId = null; var s = this._getEventPrefix();
                                i(r.document, "touchend", this._onTouchEnd, n), i(r.document, "touchmove", this._onMouseMove, n); var o = this;
                                this._willAddMouseDown && clearTimeout(this._willAddMouseDown), this._willAddMouseDown = setTimeout(function() { e(o.upperCanvasEl, s + "down", o._onMouseDown), o._willAddMouseDown = 0 }, 400) } }, _onMouseUp: function(t) { this.__onMouseUp(t), this._resetTransformEventData(); var s = this.upperCanvasEl,
                                o = this._getEventPrefix();
                            this._isMainEvent(t) && (i(r.document, o + "up", this._onMouseUp), i(r.document, o + "move", this._onMouseMove, n), e(s, o + "move", this._onMouseMove, n)) }, _onMouseMove: function(t) {!this.allowTouchScrolling && t.preventDefault && t.preventDefault(), this.__onMouseMove(t) }, _onResize: function() { this.calcOffset() }, _shouldRender: function(t) { var e = this._activeObject; return !!(!!e != !!t || e && t && e !== t) || (e && e.isEditing, !1) }, __onMouseUp: function(t) { var e, i = this._currentTransform,
                                r = this._groupSelector,
                                n = !1,
                                o = !r || 0 === r.left && 0 === r.top; if (this._cacheTransformEventData(t), e = this._target, this._handleEvent(t, "up:before"), !s(t, 3)) return s(t, 2) ? (this.fireMiddleClick && this._handleEvent(t, "up", 2, o), void this._resetTransformEventData()) : void(this.isDrawingMode && this._isCurrentlyDrawing ? this._onMouseUpInDrawingMode(t) : this._isMainEvent(t) && (i && (this._finalizeCurrentTransform(t), n = i.actionPerformed), o || (this._maybeGroupObjects(t), n || (n = this._shouldRender(e))), e && (e.isMoving = !1), this._setCursorFromEvent(t, e), this._handleEvent(t, "up", 1, o), this._groupSelector = null, this._currentTransform = null, e && (e.__corner = 0), n ? this.requestRenderAll() : o || this.renderTop()));
                            this.fireRightClick && this._handleEvent(t, "up", 3, o) }, _simpleEventHandler: function(t, e) { var i = this.findTarget(e),
                                r = this.targets,
                                n = { e: e, target: i, subTargets: r }; if (this.fire(t, n), i && i.fire(t, n), !r) return i; for (var s = 0; s < r.length; s++) r[s].fire(t, n); return i }, _handleEvent: function(t, e, i, r) { var n = this._target,
                                s = this.targets || [],
                                o = { e: t, target: n, subTargets: s, button: i || 1, isClick: r || !1, pointer: this._pointer, absolutePointer: this._absolutePointer, transform: this._currentTransform };
                            this.fire("mouse:" + e, o), n && n.fire("mouse" + e, o); for (var a = 0; a < s.length; a++) s[a].fire("mouse" + e, o) }, _finalizeCurrentTransform: function(t) { var e, i = this._currentTransform,
                                r = i.target,
                                n = { e: t, target: r, transform: i };
                            r._scaling && (r._scaling = !1), r.setCoords(), (i.actionPerformed || this.stateful && r.hasStateChanged()) && (i.actionPerformed && (e = this._addEventOptions(n, i), this._fire(e, n)), this._fire("modified", n)) }, _addEventOptions: function(t, e) { var i, r; switch (e.action) {
                                case "scaleX":
                                    i = "scaled", r = "x"; break;
                                case "scaleY":
                                    i = "scaled", r = "y"; break;
                                case "skewX":
                                    i = "skewed", r = "x"; break;
                                case "skewY":
                                    i = "skewed", r = "y"; break;
                                case "scale":
                                    i = "scaled", r = "equally"; break;
                                case "rotate":
                                    i = "rotated"; break;
                                case "drag":
                                    i = "moved" } return t.by = r, i }, _onMouseDownInDrawingMode: function(t) { this._isCurrentlyDrawing = !0, this.getActiveObject() && this.discardActiveObject(t).requestRenderAll(), this.clipTo && r.util.clipContext(this, this.contextTop); var e = this.getPointer(t);
                            this.freeDrawingBrush.onMouseDown(e, { e: t, pointer: e }), this._handleEvent(t, "down") }, _onMouseMoveInDrawingMode: function(t) { if (this._isCurrentlyDrawing) { var e = this.getPointer(t);
                                this.freeDrawingBrush.onMouseMove(e, { e: t, pointer: e }) } this.setCursor(this.freeDrawingCursor), this._handleEvent(t, "move") }, _onMouseUpInDrawingMode: function(t) { this.clipTo && this.contextTop.restore(); var e = this.getPointer(t);
                            this._isCurrentlyDrawing = this.freeDrawingBrush.onMouseUp({ e: t, pointer: e }), this._handleEvent(t, "up") }, __onMouseDown: function(t) { this._cacheTransformEventData(t), this._handleEvent(t, "down:before"); var e = this._target; if (s(t, 3)) this.fireRightClick && this._handleEvent(t, "down", 3);
                            else if (s(t, 2)) this.fireMiddleClick && this._handleEvent(t, "down", 2);
                            else if (this.isDrawingMode) this._onMouseDownInDrawingMode(t);
                            else if (this._isMainEvent(t) && !this._currentTransform) { var i = this._pointer;
                                this._previousPointer = i; var r = this._shouldRender(e),
                                    n = this._shouldGroup(t, e); if (this._shouldClearSelection(t, e) ? this.discardActiveObject(t) : n && (this._handleGrouping(t, e), e = this._activeObject), !this.selection || e && (e.selectable || e.isEditing || e === this._activeObject) || (this._groupSelector = { ex: i.x, ey: i.y, top: 0, left: 0 }), e) { var o = e === this._activeObject;
                                    e.selectable && this.setActiveObject(e, t), e !== this._activeObject || !e.__corner && n || this._setupCurrentTransform(t, e, o) } this._handleEvent(t, "down"), (r || n) && this.requestRenderAll() } }, _resetTransformEventData: function() { this._target = null, this._pointer = null, this._absolutePointer = null }, _cacheTransformEventData: function(t) { this._resetTransformEventData(), this._pointer = this.getPointer(t, !0), this._absolutePointer = this.restorePointerVpt(this._pointer), this._target = this._currentTransform ? this._currentTransform.target : this.findTarget(t) || null }, _beforeTransform: function(t) { var e = this._currentTransform;
                            this.stateful && e.target.saveState(), this.fire("before:transform", { e: t, transform: e }), e.corner && this.onBeforeScaleRotate(e.target) }, __onMouseMove: function(t) { var e, i; if (this._handleEvent(t, "move:before"), this._cacheTransformEventData(t), this.isDrawingMode) this._onMouseMoveInDrawingMode(t);
                            else if (this._isMainEvent(t)) { var r = this._groupSelector;
                                r ? (i = this._pointer, r.left = i.x - r.ex, r.top = i.y - r.ey, this.renderTop()) : this._currentTransform ? this._transformObject(t) : (e = this.findTarget(t) || null, this._setCursorFromEvent(t, e), this._fireOverOutEvents(e, t)), this._handleEvent(t, "move"), this._resetTransformEventData() } }, _fireOverOutEvents: function(t, e) { this.fireSyntheticInOutEvents(t, e, { targetName: "_hoveredTarget", canvasEvtOut: "mouse:out", evtOut: "mouseout", canvasEvtIn: "mouse:over", evtIn: "mouseover" }) }, _fireEnterLeaveEvents: function(t, e) { this.fireSyntheticInOutEvents(t, e, { targetName: "_draggedoverTarget", evtOut: "dragleave", evtIn: "dragenter" }) }, fireSyntheticInOutEvents: function(t, e, i) { var r, n, s, o = this[i.targetName],
                                a = o !== t,
                                h = i.canvasEvtIn,
                                c = i.canvasEvtOut;
                            a && (r = { e: e, target: t, previousTarget: o }, n = { e: e, target: o, nextTarget: t }, this[i.targetName] = t), s = t && a, o && a && (c && this.fire(c, n), o.fire(i.evtOut, n)), s && (h && this.fire(h, r), t.fire(i.evtIn, r)) }, __onMouseWheel: function(t) { this._cacheTransformEventData(t), this._handleEvent(t, "wheel"), this._resetTransformEventData() }, _transformObject: function(t) { var e = this.getPointer(t),
                                i = this._currentTransform;
                            i.reset = !1, i.target.isMoving = !0, i.shiftKey = t.shiftKey, i.altKey = t[this.centeredKey], this._beforeScaleTransform(t, i), this._performTransformAction(t, i, e), i.actionPerformed && this.requestRenderAll() }, _performTransformAction: function(t, e, i) { var r = i.x,
                                n = i.y,
                                s = e.action,
                                o = !1,
                                a = { target: e.target, e: t, transform: e, pointer: i }; "rotate" === s ? (o = this._rotateObject(r, n)) && this._fire("rotating", a) : "scale" === s ? (o = this._onScale(t, e, r, n)) && this._fire("scaling", a) : "scaleX" === s ? (o = this._scaleObject(r, n, "x")) && this._fire("scaling", a) : "scaleY" === s ? (o = this._scaleObject(r, n, "y")) && this._fire("scaling", a) : "skewX" === s ? (o = this._skewObject(r, n, "x")) && this._fire("skewing", a) : "skewY" === s ? (o = this._skewObject(r, n, "y")) && this._fire("skewing", a) : (o = this._translateObject(r, n)) && (this._fire("moving", a), this.setCursor(a.target.moveCursor || this.moveCursor)), e.actionPerformed = e.actionPerformed || o }, _fire: function(t, e) { this.fire("object:" + t, e), e.target.fire(t, e) }, _beforeScaleTransform: function(t, e) { if ("scale" === e.action || "scaleX" === e.action || "scaleY" === e.action) { var i = this._shouldCenterTransform(e.target);
                                (i && ("center" !== e.originX || "center" !== e.originY) || !i && "center" === e.originX && "center" === e.originY) && (this._resetCurrentTransform(), e.reset = !0) } }, _onScale: function(t, e, i, r) { return this._isUniscalePossible(t, e.target) ? (e.currentAction = "scale", this._scaleObject(i, r)) : (e.reset || "scale" !== e.currentAction || this._resetCurrentTransform(), e.currentAction = "scaleEqually", this._scaleObject(i, r, "equally")) }, _isUniscalePossible: function(t, e) { return (t[this.uniScaleKey] || this.uniScaleTransform) && !e.get("lockUniScaling") }, _setCursorFromEvent: function(t, e) { if (!e) return this.setCursor(this.defaultCursor), !1; var i = e.hoverCursor || this.hoverCursor,
                                r = this._activeObject && "activeSelection" === this._activeObject.type ? this._activeObject : null,
                                n = (!r || !r.contains(e)) && e._findTargetCorner(this.getPointer(t, !0));
                            n ? this.setCursor(this.getCornerCursor(n, e, t)) : this.setCursor(i) }, getCornerCursor: function(e, i, r) { return this.actionIsDisabled(e, i, r) ? this.notAllowedCursor : e in t ? this._getRotatedCornerCursor(e, i, r) : "mtr" === e && i.hasRotatingPoint ? this.rotationCursor : this.defaultCursor }, actionIsDisabled: function(t, e, i) { return "mt" === t || "mb" === t ? i[this.altActionKey] ? e.lockSkewingX : e.lockScalingY : "ml" === t || "mr" === t ? i[this.altActionKey] ? e.lockSkewingY : e.lockScalingX : "mtr" === t ? e.lockRotation : this._isUniscalePossible(i, e) ? e.lockScalingX && e.lockScalingY : e.lockScalingX || e.lockScalingY }, _getRotatedCornerCursor: function(e, i, r) { var n = Math.round(i.angle % 360 / 45); return n < 0 && (n += 8), n += t[e], r[this.altActionKey] && t[e] % 2 == 0 && (n += 2), n %= 8, this.cursorMap[n] } }) }(),
                function() { var t = Math.min,
                        e = Math.max;
                    r.util.object.extend(r.Canvas.prototype, { _shouldGroup: function(t, e) { var i = this._activeObject; return i && this._isSelectionKeyPressed(t) && e && e.selectable && this.selection && (i !== e || "activeSelection" === i.type) && !e.onSelect({ e: t }) }, _handleGrouping: function(t, e) { var i = this._activeObject;
                            i.__corner || (e !== i || (e = this.findTarget(t, !0)) && e.selectable) && (i && "activeSelection" === i.type ? this._updateActiveSelection(e, t) : this._createActiveSelection(e, t)) }, _updateActiveSelection: function(t, e) { var i = this._activeObject,
                                r = i._objects.slice(0);
                            i.contains(t) ? (i.removeWithUpdate(t), this._hoveredTarget = t, 1 === i.size() && this._setActiveObject(i.item(0), e)) : (i.addWithUpdate(t), this._hoveredTarget = i), this._fireSelectionEvents(r, e) }, _createActiveSelection: function(t, e) { var i = this.getActiveObjects(),
                                r = this._createGroup(t);
                            this._hoveredTarget = r, this._setActiveObject(r, e), this._fireSelectionEvents(i, e) }, _createGroup: function(t) { var e = this._objects,
                                i = e.indexOf(this._activeObject) < e.indexOf(t) ? [this._activeObject, t] : [t, this._activeObject]; return this._activeObject.isEditing && this._activeObject.exitEditing(), new r.ActiveSelection(i, { canvas: this }) }, _groupSelectedObjects: function(t) { var e, i = this._collectObjects(t);
                            1 === i.length ? this.setActiveObject(i[0], t) : i.length > 1 && (e = new r.ActiveSelection(i.reverse(), { canvas: this }), this.setActiveObject(e, t)) }, _collectObjects: function(i) { for (var n, s = [], o = this._groupSelector.ex, a = this._groupSelector.ey, h = o + this._groupSelector.left, c = a + this._groupSelector.top, l = new r.Point(t(o, h), t(a, c)), u = new r.Point(e(o, h), e(a, c)), f = !this.selectionFullyContained, d = o === h && a === c, g = this._objects.length; g-- && !((n = this._objects[g]) && n.selectable && n.visible && (f && n.intersectsWithRect(l, u) || n.isContainedWithinRect(l, u) || f && n.containsPoint(l) || f && n.containsPoint(u)) && (s.push(n), d));); return s.length > 1 && (s = s.filter(function(t) { return !t.onSelect({ e: i }) })), s }, _maybeGroupObjects: function(t) { this.selection && this._groupSelector && this._groupSelectedObjects(t), this.setCursor(this.defaultCursor), this._groupSelector = null } }) }(), r.util.object.extend(r.StaticCanvas.prototype, { toDataURL: function(t) { t || (t = {}); var e = t.format || "png",
                            i = t.quality || 1,
                            n = (t.multiplier || 1) * (t.enableRetinaScaling ? this.getRetinaScaling() : 1),
                            s = this.toCanvasElement(n, t); return r.util.toDataURL(s, e, i) }, toCanvasElement: function(t, e) { t = t || 1; var i = ((e = e || {}).width || this.width) * t,
                            n = (e.height || this.height) * t,
                            s = this.getZoom(),
                            o = this.width,
                            a = this.height,
                            h = s * t,
                            c = this.viewportTransform,
                            l = (c[4] - (e.left || 0)) * t,
                            u = (c[5] - (e.top || 0)) * t,
                            f = this.interactive,
                            d = [h, 0, 0, h, l, u],
                            g = this.enableRetinaScaling,
                            p = r.util.createCanvasElement(),
                            v = this.contextTop; return p.width = i, p.height = n, this.contextTop = null, this.enableRetinaScaling = !1, this.interactive = !1, this.viewportTransform = d, this.width = i, this.height = n, this.calcViewportBoundaries(), this.renderCanvas(p.getContext("2d"), this._objects), this.viewportTransform = c, this.width = o, this.height = a, this.calcViewportBoundaries(), this.interactive = f, this.enableRetinaScaling = g, this.contextTop = v, p } }), r.util.object.extend(r.StaticCanvas.prototype, { loadFromDatalessJSON: function(t, e, i) { return this.loadFromJSON(t, e, i) }, loadFromJSON: function(t, e, i) { if (t) { var n = "string" == typeof t ? JSON.parse(t) : r.util.object.clone(t),
                                s = this,
                                o = n.clipPath,
                                a = this.renderOnAddRemove; return this.renderOnAddRemove = !1, delete n.clipPath, this._enlivenObjects(n.objects, function(t) { s.clear(), s._setBgOverlay(n, function() { o ? s._enlivenObjects([o], function(i) { s.clipPath = i[0], s.__setupCanvas.call(s, n, t, a, e) }) : s.__setupCanvas.call(s, n, t, a, e) }) }, i), this } }, __setupCanvas: function(t, e, i, r) { var n = this;
                        e.forEach(function(t, e) { n.insertAt(t, e) }), this.renderOnAddRemove = i, delete t.objects, delete t.backgroundImage, delete t.overlayImage, delete t.background, delete t.overlay, this._setOptions(t), this.renderAll(), r && r() }, _setBgOverlay: function(t, e) { var i = { backgroundColor: !1, overlayColor: !1, backgroundImage: !1, overlayImage: !1 }; if (t.backgroundImage || t.overlayImage || t.background || t.overlay) { var r = function() { i.backgroundImage && i.overlayImage && i.backgroundColor && i.overlayColor && e && e() };
                            this.__setBgOverlay("backgroundImage", t.backgroundImage, i, r), this.__setBgOverlay("overlayImage", t.overlayImage, i, r), this.__setBgOverlay("backgroundColor", t.background, i, r), this.__setBgOverlay("overlayColor", t.overlay, i, r) } else e && e() }, __setBgOverlay: function(t, e, i, n) { var s = this; if (!e) return i[t] = !0, void(n && n()); "backgroundImage" === t || "overlayImage" === t ? r.util.enlivenObjects([e], function(e) { s[t] = e[0], i[t] = !0, n && n() }) : this["set" + r.util.string.capitalize(t, !0)](e, function() { i[t] = !0, n && n() }) }, _enlivenObjects: function(t, e, i) { t && 0 !== t.length ? r.util.enlivenObjects(t, function(t) { e && e(t) }, null, i) : e && e([]) }, _toDataURL: function(t, e) { this.clone(function(i) { e(i.toDataURL(t)) }) }, _toDataURLWithMultiplier: function(t, e, i) { this.clone(function(r) { i(r.toDataURLWithMultiplier(t, e)) }) }, clone: function(t, e) { var i = JSON.stringify(this.toJSON(e));
                        this.cloneWithoutData(function(e) { e.loadFromJSON(i, function() { t && t(e) }) }) }, cloneWithoutData: function(t) { var e = r.util.createCanvasElement();
                        e.width = this.width, e.height = this.height; var i = new r.Canvas(e);
                        i.clipTo = this.clipTo, this.backgroundImage ? (i.setBackgroundImage(this.backgroundImage.src, function() { i.renderAll(), t && t(i) }), i.backgroundImageOpacity = this.backgroundImageOpacity, i.backgroundImageStretch = this.backgroundImageStretch) : t && t(i) } }),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.util.object.extend,
                        r = e.util.object.clone,
                        n = e.util.toFixed,
                        s = e.util.string.capitalize,
                        o = e.util.degreesToRadians,
                        a = e.StaticCanvas.supports("setLineDash"),
                        h = !e.isLikelyNode;
                    e.Object || (e.Object = e.util.createClass(e.CommonMethods, { type: "object", originX: "left", originY: "top", top: 0, left: 0, width: 0, height: 0, scaleX: 1, scaleY: 1, flipX: !1, flipY: !1, opacity: 1, angle: 0, skewX: 0, skewY: 0, cornerSize: 13, transparentCorners: !0, hoverCursor: null, moveCursor: null, padding: 0, borderColor: "rgba(102,153,255,0.75)", borderDashArray: null, cornerColor: "rgba(102,153,255,0.5)", cornerStrokeColor: null, cornerStyle: "rect", cornerDashArray: null, centeredScaling: !1, centeredRotation: !0, fill: "rgb(0,0,0)", fillRule: "nonzero", globalCompositeOperation: "source-over", backgroundColor: "", selectionBackgroundColor: "", stroke: null, strokeWidth: 1, strokeDashArray: null, strokeDashOffset: 0, strokeLineCap: "butt", strokeLineJoin: "miter", strokeMiterLimit: 4, shadow: null, borderOpacityWhenMoving: .4, borderScaleFactor: 1, transformMatrix: null, minScaleLimit: 0, selectable: !0, evented: !0, visible: !0, hasControls: !0, hasBorders: !0, hasRotatingPoint: !0, rotatingPointOffset: 40, perPixelTargetFind: !1, includeDefaultValues: !0, clipTo: null, lockMovementX: !1, lockMovementY: !1, lockRotation: !1, lockScalingX: !1, lockScalingY: !1, lockUniScaling: !1, lockSkewingX: !1, lockSkewingY: !1, lockScalingFlip: !1, excludeFromExport: !1, objectCaching: h, statefullCache: !1, noScaleCache: !0, strokeUniform: !1, dirty: !0, __corner: 0, paintFirst: "fill", stateProperties: "top left width height scaleX scaleY flipX flipY originX originY transformMatrix stroke strokeWidth strokeDashArray strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit angle opacity fill globalCompositeOperation shadow clipTo visible backgroundColor skewX skewY fillRule paintFirst clipPath strokeUniform".split(" "), cacheProperties: "fill stroke strokeWidth strokeDashArray width height paintFirst strokeUniform strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit backgroundColor clipPath".split(" "), clipPath: void 0, inverted: !1, absolutePositioned: !1, initialize: function(t) { t && this.setOptions(t) }, _createCacheCanvas: function() { this._cacheProperties = {}, this._cacheCanvas = e.util.createCanvasElement(), this._cacheContext = this._cacheCanvas.getContext("2d"), this._updateCacheCanvas(), this.dirty = !0 }, _limitCacheSize: function(t) { var i = e.perfLimitSizeTotal,
                                r = t.width,
                                n = t.height,
                                s = e.maxCacheSideLimit,
                                o = e.minCacheSideLimit; if (r <= s && n <= s && r * n <= i) return r < o && (t.width = o), n < o && (t.height = o), t; var a = r / n,
                                h = e.util.limitDimsByArea(a, i),
                                c = e.util.capValue,
                                l = c(o, h.x, s),
                                u = c(o, h.y, s); return r > l && (t.zoomX /= r / l, t.width = l, t.capped = !0), n > u && (t.zoomY /= n / u, t.height = u, t.capped = !0), t }, _getCacheCanvasDimensions: function() { var t = this.getTotalObjectScaling(),
                                e = this._getTransformedDimensions(0, 0),
                                i = e.x * t.scaleX / this.scaleX,
                                r = e.y * t.scaleY / this.scaleY; return { width: i + 2, height: r + 2, zoomX: t.scaleX, zoomY: t.scaleY, x: i, y: r } }, _updateCacheCanvas: function() { var t = this.canvas; if (this.noScaleCache && t && t._currentTransform) { var i = t._currentTransform.target,
                                    r = t._currentTransform.action; if (this === i && r.slice && "scale" === r.slice(0, 5)) return !1 } var n, s, o = this._cacheCanvas,
                                a = this._limitCacheSize(this._getCacheCanvasDimensions()),
                                h = e.minCacheSideLimit,
                                c = a.width,
                                l = a.height,
                                u = a.zoomX,
                                f = a.zoomY,
                                d = c !== this.cacheWidth || l !== this.cacheHeight,
                                g = this.zoomX !== u || this.zoomY !== f,
                                p = d || g,
                                v = 0,
                                m = 0,
                                _ = !1; if (d) { var y = this._cacheCanvas.width,
                                    b = this._cacheCanvas.height,
                                    x = c > y || l > b;
                                _ = x || (c < .9 * y || l < .9 * b) && y > h && b > h, x && !a.capped && (c > h || l > h) && (v = .1 * c, m = .1 * l) } return !!p && (_ ? (o.width = Math.ceil(c + v), o.height = Math.ceil(l + m)) : (this._cacheContext.setTransform(1, 0, 0, 1, 0, 0), this._cacheContext.clearRect(0, 0, o.width, o.height)), n = a.x / 2, s = a.y / 2, this.cacheTranslationX = Math.round(o.width / 2 - n) + n, this.cacheTranslationY = Math.round(o.height / 2 - s) + s, this.cacheWidth = c, this.cacheHeight = l, this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY), this._cacheContext.scale(u, f), this.zoomX = u, this.zoomY = f, !0) }, setOptions: function(t) { this._setOptions(t), this._initGradient(t.fill, "fill"), this._initGradient(t.stroke, "stroke"), this._initClipping(t), this._initPattern(t.fill, "fill"), this._initPattern(t.stroke, "stroke") }, transform: function(t) { var e;
                            e = this.group && !this.group._transformDone ? this.calcTransformMatrix() : this.calcOwnMatrix(), t.transform(e[0], e[1], e[2], e[3], e[4], e[5]) }, toObject: function(t) { var i = e.Object.NUM_FRACTION_DIGITS,
                                r = { type: this.type, version: e.version, originX: this.originX, originY: this.originY, left: n(this.left, i), top: n(this.top, i), width: n(this.width, i), height: n(this.height, i), fill: this.fill && this.fill.toObject ? this.fill.toObject() : this.fill, stroke: this.stroke && this.stroke.toObject ? this.stroke.toObject() : this.stroke, strokeWidth: n(this.strokeWidth, i), strokeDashArray: this.strokeDashArray ? this.strokeDashArray.concat() : this.strokeDashArray, strokeLineCap: this.strokeLineCap, strokeDashOffset: this.strokeDashOffset, strokeLineJoin: this.strokeLineJoin, strokeMiterLimit: n(this.strokeMiterLimit, i), scaleX: n(this.scaleX, i), scaleY: n(this.scaleY, i), angle: n(this.angle, i), flipX: this.flipX, flipY: this.flipY, opacity: n(this.opacity, i), shadow: this.shadow && this.shadow.toObject ? this.shadow.toObject() : this.shadow, visible: this.visible, clipTo: this.clipTo && String(this.clipTo), backgroundColor: this.backgroundColor, fillRule: this.fillRule, paintFirst: this.paintFirst, globalCompositeOperation: this.globalCompositeOperation, transformMatrix: this.transformMatrix ? this.transformMatrix.concat() : null, skewX: n(this.skewX, i), skewY: n(this.skewY, i) }; return this.clipPath && (r.clipPath = this.clipPath.toObject(t), r.clipPath.inverted = this.clipPath.inverted, r.clipPath.absolutePositioned = this.clipPath.absolutePositioned), e.util.populateWithProperties(this, r, t), this.includeDefaultValues || (r = this._removeDefaultValues(r)), r }, toDatalessObject: function(t) { return this.toObject(t) }, _removeDefaultValues: function(t) { var i = e.util.getKlass(t.type).prototype; return i.stateProperties.forEach(function(e) { "left" !== e && "top" !== e && (t[e] === i[e] && delete t[e], "[object Array]" === Object.prototype.toString.call(t[e]) && "[object Array]" === Object.prototype.toString.call(i[e]) && 0 === t[e].length && 0 === i[e].length && delete t[e]) }), t }, toString: function() { return "#<fabric." + s(this.type) + ">" }, getObjectScaling: function() { var t = this.scaleX,
                                e = this.scaleY; if (this.group) { var i = this.group.getObjectScaling();
                                t *= i.scaleX, e *= i.scaleY } return { scaleX: t, scaleY: e } }, getTotalObjectScaling: function() { var t = this.getObjectScaling(),
                                e = t.scaleX,
                                i = t.scaleY; if (this.canvas) { var r = this.canvas.getZoom(),
                                    n = this.canvas.getRetinaScaling();
                                e *= r * n, i *= r * n } return { scaleX: e, scaleY: i } }, getObjectOpacity: function() { var t = this.opacity; return this.group && (t *= this.group.getObjectOpacity()), t }, _set: function(t, i) { var r = "scaleX" === t || "scaleY" === t,
                                n = this[t] !== i,
                                s = !1; return r && (i = this._constrainScale(i)), "scaleX" === t && i < 0 ? (this.flipX = !this.flipX, i *= -1) : "scaleY" === t && i < 0 ? (this.flipY = !this.flipY, i *= -1) : "shadow" !== t || !i || i instanceof e.Shadow ? "dirty" === t && this.group && this.group.set("dirty", i) : i = new e.Shadow(i), this[t] = i, n && (s = this.group && this.group.isOnACache(), this.cacheProperties.indexOf(t) > -1 ? (this.dirty = !0, s && this.group.set("dirty", !0)) : s && this.stateProperties.indexOf(t) > -1 && this.group.set("dirty", !0)), this }, setOnGroup: function() {}, getViewportTransform: function() { return this.canvas && this.canvas.viewportTransform ? this.canvas.viewportTransform : e.iMatrix.concat() }, isNotVisible: function() { return 0 === this.opacity || 0 === this.width && 0 === this.height && 0 === this.strokeWidth || !this.visible }, render: function(t) { this.isNotVisible() || this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen() || (t.save(), this._setupCompositeOperation(t), this.drawSelectionBackground(t), this.transform(t), this._setOpacity(t), this._setShadow(t, this), this.transformMatrix && t.transform.apply(t, this.transformMatrix), this.clipTo && e.util.clipContext(this, t), this.shouldCache() ? (this.renderCache(), this.drawCacheOnCanvas(t)) : (this._removeCacheCanvas(), this.dirty = !1, this.drawObject(t), this.objectCaching && this.statefullCache && this.saveState({ propertySet: "cacheProperties" })), this.clipTo && t.restore(), t.restore()) }, renderCache: function(t) { t = t || {}, this._cacheCanvas || this._createCacheCanvas(), this.isCacheDirty() && (this.statefullCache && this.saveState({ propertySet: "cacheProperties" }), this.drawObject(this._cacheContext, t.forClipping), this.dirty = !1) }, _removeCacheCanvas: function() { this._cacheCanvas = null, this.cacheWidth = 0, this.cacheHeight = 0 }, hasStroke: function() { return this.stroke && "transparent" !== this.stroke && 0 !== this.strokeWidth }, hasFill: function() { return this.fill && "transparent" !== this.fill }, needsItsOwnCache: function() { return !("stroke" !== this.paintFirst || !this.hasFill() || !this.hasStroke() || "object" != typeof this.shadow) || !!this.clipPath }, shouldCache: function() { return this.ownCaching = this.needsItsOwnCache() || this.objectCaching && (!this.group || !this.group.isOnACache()), this.ownCaching }, willDrawShadow: function() { return !!this.shadow && (0 !== this.shadow.offsetX || 0 !== this.shadow.offsetY) }, drawClipPathOnCache: function(t) { var i = this.clipPath; if (t.save(), i.inverted ? t.globalCompositeOperation = "destination-out" : t.globalCompositeOperation = "destination-in", i.absolutePositioned) { var r = e.util.invertTransform(this.calcTransformMatrix());
                                t.transform(r[0], r[1], r[2], r[3], r[4], r[5]) } i.transform(t), t.scale(1 / i.zoomX, 1 / i.zoomY), t.drawImage(i._cacheCanvas, -i.cacheTranslationX, -i.cacheTranslationY), t.restore() }, drawObject: function(t, e) { var i = this.fill,
                                r = this.stroke;
                            e ? (this.fill = "black", this.stroke = "", this._setClippingProperties(t)) : (this._renderBackground(t), this._setStrokeStyles(t, this), this._setFillStyles(t, this)), this._render(t), this._drawClipPath(t), this.fill = i, this.stroke = r }, _drawClipPath: function(t) { var e = this.clipPath;
                            e && (e.canvas = this.canvas, e.shouldCache(), e._transformDone = !0, e.renderCache({ forClipping: !0 }), this.drawClipPathOnCache(t)) }, drawCacheOnCanvas: function(t) { t.scale(1 / this.zoomX, 1 / this.zoomY), t.drawImage(this._cacheCanvas, -this.cacheTranslationX, -this.cacheTranslationY) }, isCacheDirty: function(t) { if (this.isNotVisible()) return !1; if (this._cacheCanvas && !t && this._updateCacheCanvas()) return !0; if (this.dirty || this.clipPath && this.clipPath.absolutePositioned || this.statefullCache && this.hasStateChanged("cacheProperties")) { if (this._cacheCanvas && !t) { var e = this.cacheWidth / this.zoomX,
                                        i = this.cacheHeight / this.zoomY;
                                    this._cacheContext.clearRect(-e / 2, -i / 2, e, i) } return !0 } return !1 }, _renderBackground: function(t) { if (this.backgroundColor) { var e = this._getNonTransformedDimensions();
                                t.fillStyle = this.backgroundColor, t.fillRect(-e.x / 2, -e.y / 2, e.x, e.y), this._removeShadow(t) } }, _setOpacity: function(t) { this.group && !this.group._transformDone ? t.globalAlpha = this.getObjectOpacity() : t.globalAlpha *= this.opacity }, _setStrokeStyles: function(t, e) { e.stroke && (t.lineWidth = e.strokeWidth, t.lineCap = e.strokeLineCap, t.lineDashOffset = e.strokeDashOffset, t.lineJoin = e.strokeLineJoin, t.miterLimit = e.strokeMiterLimit, t.strokeStyle = e.stroke.toLive ? e.stroke.toLive(t, this) : e.stroke) }, _setFillStyles: function(t, e) { e.fill && (t.fillStyle = e.fill.toLive ? e.fill.toLive(t, this) : e.fill) }, _setClippingProperties: function(t) { t.globalAlpha = 1, t.strokeStyle = "transparent", t.fillStyle = "#000000" }, _setLineDash: function(t, e, i) { e && (1 & e.length && e.push.apply(e, e), a ? t.setLineDash(e) : i && i(t), this.strokeUniform && t.setLineDash(t.getLineDash().map(function(e) { return e * t.lineWidth }))) }, _renderControls: function(t, i) { var r, n, s, a = this.getViewportTransform(),
                                h = this.calcTransformMatrix();
                            n = void 0 !== (i = i || {}).hasBorders ? i.hasBorders : this.hasBorders, s = void 0 !== i.hasControls ? i.hasControls : this.hasControls, h = e.util.multiplyTransformMatrices(a, h), r = e.util.qrDecompose(h), t.save(), t.translate(r.translateX, r.translateY), t.lineWidth = 1 * this.borderScaleFactor, this.group || (t.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1), i.forActiveSelection ? (t.rotate(o(r.angle)), n && this.drawBordersInGroup(t, r, i)) : (t.rotate(o(this.angle)), n && this.drawBorders(t, i)), s && this.drawControls(t, i), t.restore() }, _setShadow: function(t) { if (this.shadow) { var i, r = this.shadow,
                                    n = this.canvas,
                                    s = n && n.viewportTransform[0] || 1,
                                    o = n && n.viewportTransform[3] || 1;
                                i = r.nonScaling ? { scaleX: 1, scaleY: 1 } : this.getObjectScaling(), n && n._isRetinaScaling() && (s *= e.devicePixelRatio, o *= e.devicePixelRatio), t.shadowColor = r.color, t.shadowBlur = r.blur * e.browserShadowBlurConstant * (s + o) * (i.scaleX + i.scaleY) / 4, t.shadowOffsetX = r.offsetX * s * i.scaleX, t.shadowOffsetY = r.offsetY * o * i.scaleY } }, _removeShadow: function(t) { this.shadow && (t.shadowColor = "", t.shadowBlur = t.shadowOffsetX = t.shadowOffsetY = 0) }, _applyPatternGradientTransform: function(t, e) { if (!e || !e.toLive) return { offsetX: 0, offsetY: 0 }; var i = e.gradientTransform || e.patternTransform,
                                r = -this.width / 2 + e.offsetX || 0,
                                n = -this.height / 2 + e.offsetY || 0; return t.translate(r, n), i && t.transform(i[0], i[1], i[2], i[3], i[4], i[5]), { offsetX: r, offsetY: n } }, _renderPaintInOrder: function(t) { "stroke" === this.paintFirst ? (this._renderStroke(t), this._renderFill(t)) : (this._renderFill(t), this._renderStroke(t)) }, _render: function() {}, _renderFill: function(t) { this.fill && (t.save(), this._applyPatternGradientTransform(t, this.fill), "evenodd" === this.fillRule ? t.fill("evenodd") : t.fill(), t.restore()) }, _renderStroke: function(t) { this.stroke && 0 !== this.strokeWidth && (this.shadow && !this.shadow.affectStroke && this._removeShadow(t), t.save(), this.strokeUniform && t.scale(1 / this.scaleX, 1 / this.scaleY), this._setLineDash(t, this.strokeDashArray, this._renderDashedStroke), this._applyPatternGradientTransform(t, this.stroke), t.stroke(), t.restore()) }, _findCenterFromElement: function() { return { x: this.left + this.width / 2, y: this.top + this.height / 2 } }, _assignTransformMatrixProps: function() { if (this.transformMatrix) { var t = e.util.qrDecompose(this.transformMatrix);
                                this.flipX = !1, this.flipY = !1, this.set("scaleX", t.scaleX), this.set("scaleY", t.scaleY), this.angle = t.angle, this.skewX = t.skewX, this.skewY = 0 } }, _removeTransformMatrix: function(t) { var i = this._findCenterFromElement();
                            this.transformMatrix && (this._assignTransformMatrixProps(), i = e.util.transformPoint(i, this.transformMatrix)), this.transformMatrix = null, t && (this.scaleX *= t.scaleX, this.scaleY *= t.scaleY, this.cropX = t.cropX, this.cropY = t.cropY, i.x += t.offsetLeft, i.y += t.offsetTop, this.width = t.width, this.height = t.height), this.setPositionByOrigin(i, "center", "center") }, clone: function(t, i) { var r = this.toObject(i);
                            this.constructor.fromObject ? this.constructor.fromObject(r, t) : e.Object._fromObject("Object", r, t) }, cloneAsImage: function(t, i) { var r = this.toCanvasElement(i); return t && t(new e.Image(r)), this }, toCanvasElement: function(t) { t || (t = {}); var i = e.util,
                                r = i.saveObjectTransform(this),
                                n = this.shadow,
                                s = Math.abs,
                                o = (t.multiplier || 1) * (t.enableRetinaScaling ? e.devicePixelRatio : 1);
                            t.withoutTransform && i.resetObjectTransform(this), t.withoutShadow && (this.shadow = null); var a, h, c = e.util.createCanvasElement(),
                                l = this.getBoundingRect(!0, !0),
                                u = this.shadow,
                                f = { x: 0, y: 0 };
                            u && (h = u.blur, a = u.nonScaling ? { scaleX: 1, scaleY: 1 } : this.getObjectScaling(), f.x = 2 * Math.round(s(u.offsetX) + h) * s(a.scaleX), f.y = 2 * Math.round(s(u.offsetY) + h) * s(a.scaleY)), c.width = l.width + f.x, c.height = l.height + f.y, c.width += c.width % 2 ? 2 - c.width % 2 : 0, c.height += c.height % 2 ? 2 - c.height % 2 : 0; var d = new e.StaticCanvas(c, { enableRetinaScaling: !1, renderOnAddRemove: !1, skipOffscreen: !1 }); "jpeg" === t.format && (d.backgroundColor = "#fff"), this.setPositionByOrigin(new e.Point(d.width / 2, d.height / 2), "center", "center"); var g = this.canvas;
                            d.add(this); var p = d.toCanvasElement(o || 1, t); return this.shadow = n, this.canvas = g, this.set(r).setCoords(), d._objects = [], d.dispose(), d = null, p }, toDataURL: function(t) { return t || (t = {}), e.util.toDataURL(this.toCanvasElement(t), t.format || "png", t.quality || 1) }, isType: function(t) { return this.type === t }, complexity: function() { return 1 }, toJSON: function(t) { return this.toObject(t) }, setGradient: function(t, i) { i || (i = {}); var r = { colorStops: [] }; return r.type = i.type || (i.r1 || i.r2 ? "radial" : "linear"), r.coords = { x1: i.x1, y1: i.y1, x2: i.x2, y2: i.y2 }, (i.r1 || i.r2) && (r.coords.r1 = i.r1, r.coords.r2 = i.r2), r.gradientTransform = i.gradientTransform, e.Gradient.prototype.addColorStop.call(r, i.colorStops), this.set(t, e.Gradient.forObject(this, r)) }, setPatternFill: function(t, i) { return this.set("fill", new e.Pattern(t, i)) }, setShadow: function(t) { return this.set("shadow", t ? new e.Shadow(t) : null) }, setColor: function(t) { return this.set("fill", t), this }, rotate: function(t) { var e = ("center" !== this.originX || "center" !== this.originY) && this.centeredRotation; return e && this._setOriginToCenter(), this.set("angle", t), e && this._resetOrigin(), this }, centerH: function() { return this.canvas && this.canvas.centerObjectH(this), this }, viewportCenterH: function() { return this.canvas && this.canvas.viewportCenterObjectH(this), this }, centerV: function() { return this.canvas && this.canvas.centerObjectV(this), this }, viewportCenterV: function() { return this.canvas && this.canvas.viewportCenterObjectV(this), this }, center: function() { return this.canvas && this.canvas.centerObject(this), this }, viewportCenter: function() { return this.canvas && this.canvas.viewportCenterObject(this), this }, getLocalPointer: function(t, i) { i = i || this.canvas.getPointer(t); var r = new e.Point(i.x, i.y),
                                n = this._getLeftTopCoords(); return this.angle && (r = e.util.rotatePoint(r, n, o(-this.angle))), { x: r.x - n.x, y: r.y - n.y } }, _setupCompositeOperation: function(t) { this.globalCompositeOperation && (t.globalCompositeOperation = this.globalCompositeOperation) } }), e.util.createAccessors && e.util.createAccessors(e.Object), i(e.Object.prototype, e.Observable), e.Object.NUM_FRACTION_DIGITS = 2, e.Object._fromObject = function(t, i, n, s) { var o = e[t];
                        i = r(i, !0), e.util.enlivenPatterns([i.fill, i.stroke], function(t) { void 0 !== t[0] && (i.fill = t[0]), void 0 !== t[1] && (i.stroke = t[1]), e.util.enlivenObjects([i.clipPath], function(t) { i.clipPath = t[0]; var e = s ? new o(i[s], i) : new o(i);
                                n && n(e) }) }) }, e.Object.__uid = 0) }(e),
                function() { var t = r.util.degreesToRadians,
                        e = { left: -.5, center: 0, right: .5 },
                        i = { top: -.5, center: 0, bottom: .5 };
                    r.util.object.extend(r.Object.prototype, { translateToGivenOrigin: function(t, n, s, o, a) { var h, c, l, u = t.x,
                                f = t.y; return "string" == typeof n ? n = e[n] : n -= .5, "string" == typeof o ? o = e[o] : o -= .5, h = o - n, "string" == typeof s ? s = i[s] : s -= .5, "string" == typeof a ? a = i[a] : a -= .5, c = a - s, (h || c) && (l = this._getTransformedDimensions(), u = t.x + h * l.x, f = t.y + c * l.y), new r.Point(u, f) }, translateToCenterPoint: function(e, i, n) { var s = this.translateToGivenOrigin(e, i, n, "center", "center"); return this.angle ? r.util.rotatePoint(s, e, t(this.angle)) : s }, translateToOriginPoint: function(e, i, n) { var s = this.translateToGivenOrigin(e, "center", "center", i, n); return this.angle ? r.util.rotatePoint(s, e, t(this.angle)) : s }, getCenterPoint: function() { var t = new r.Point(this.left, this.top); return this.translateToCenterPoint(t, this.originX, this.originY) }, getPointByOrigin: function(t, e) { var i = this.getCenterPoint(); return this.translateToOriginPoint(i, t, e) }, toLocalPoint: function(e, i, n) { var s, o, a = this.getCenterPoint(); return s = void 0 !== i && void 0 !== n ? this.translateToGivenOrigin(a, "center", "center", i, n) : new r.Point(this.left, this.top), o = new r.Point(e.x, e.y), this.angle && (o = r.util.rotatePoint(o, a, -t(this.angle))), o.subtractEquals(s) }, setPositionByOrigin: function(t, e, i) { var r = this.translateToCenterPoint(t, e, i),
                                n = this.translateToOriginPoint(r, this.originX, this.originY);
                            this.set("left", n.x), this.set("top", n.y) }, adjustPosition: function(i) { var n, s, o = t(this.angle),
                                a = this.getScaledWidth(),
                                h = r.util.cos(o) * a,
                                c = r.util.sin(o) * a;
                            n = "string" == typeof this.originX ? e[this.originX] : this.originX - .5, s = "string" == typeof i ? e[i] : i - .5, this.left += h * (s - n), this.top += c * (s - n), this.setCoords(), this.originX = i }, _setOriginToCenter: function() { this._originalOriginX = this.originX, this._originalOriginY = this.originY; var t = this.getCenterPoint();
                            this.originX = "center", this.originY = "center", this.left = t.x, this.top = t.y }, _resetOrigin: function() { var t = this.translateToOriginPoint(this.getCenterPoint(), this._originalOriginX, this._originalOriginY);
                            this.originX = this._originalOriginX, this.originY = this._originalOriginY, this.left = t.x, this.top = t.y, this._originalOriginX = null, this._originalOriginY = null }, _getLeftTopCoords: function() { return this.translateToOriginPoint(this.getCenterPoint(), "left", "top") } }) }(),
                function() { var t = r.util.degreesToRadians,
                        e = r.util.multiplyTransformMatrices,
                        i = r.util.transformPoint;
                    r.util.object.extend(r.Object.prototype, { oCoords: null, aCoords: null, ownMatrixCache: null, matrixCache: null, getCoords: function(t, e) { this.oCoords || this.setCoords(); var i = t ? this.aCoords : this.oCoords; return function(t) { return [new r.Point(t.tl.x, t.tl.y), new r.Point(t.tr.x, t.tr.y), new r.Point(t.br.x, t.br.y), new r.Point(t.bl.x, t.bl.y)] }(e ? this.calcCoords(t) : i) }, intersectsWithRect: function(t, e, i, n) { var s = this.getCoords(i, n); return "Intersection" === r.Intersection.intersectPolygonRectangle(s, t, e).status }, intersectsWithObject: function(t, e, i) { return "Intersection" === r.Intersection.intersectPolygonPolygon(this.getCoords(e, i), t.getCoords(e, i)).status || t.isContainedWithinObject(this, e, i) || this.isContainedWithinObject(t, e, i) }, isContainedWithinObject: function(t, e, i) { for (var r = this.getCoords(e, i), n = 0, s = t._getImageLines(i ? t.calcCoords(e) : e ? t.aCoords : t.oCoords); n < 4; n++)
                                if (!t.containsPoint(r[n], s)) return !1; return !0 }, isContainedWithinRect: function(t, e, i, r) { var n = this.getBoundingRect(i, r); return n.left >= t.x && n.left + n.width <= e.x && n.top >= t.y && n.top + n.height <= e.y }, containsPoint: function(t, e, i, r) { e = e || this._getImageLines(r ? this.calcCoords(i) : i ? this.aCoords : this.oCoords); var n = this._findCrossPoints(t, e); return 0 !== n && n % 2 == 1 }, isOnScreen: function(t) { if (!this.canvas) return !1; for (var e, i = this.canvas.vptCoords.tl, r = this.canvas.vptCoords.br, n = this.getCoords(!0, t), s = 0; s < 4; s++)
                                if ((e = n[s]).x <= r.x && e.x >= i.x && e.y <= r.y && e.y >= i.y) return !0; return !!this.intersectsWithRect(i, r, !0, t) || this._containsCenterOfCanvas(i, r, t) }, _containsCenterOfCanvas: function(t, e, i) { var r = { x: (t.x + e.x) / 2, y: (t.y + e.y) / 2 }; return !!this.containsPoint(r, null, !0, i) }, isPartiallyOnScreen: function(t) { if (!this.canvas) return !1; var e = this.canvas.vptCoords.tl,
                                i = this.canvas.vptCoords.br; return !!this.intersectsWithRect(e, i, !0, t) || this._containsCenterOfCanvas(e, i, t) }, _getImageLines: function(t) { return { topline: { o: t.tl, d: t.tr }, rightline: { o: t.tr, d: t.br }, bottomline: { o: t.br, d: t.bl }, leftline: { o: t.bl, d: t.tl } } }, _findCrossPoints: function(t, e) { var i, r, n, s, o = 0; for (var a in e)
                                if (!((s = e[a]).o.y < t.y && s.d.y < t.y || s.o.y >= t.y && s.d.y >= t.y || (s.o.x === s.d.x && s.o.x >= t.x ? n = s.o.x : (i = 0, r = (s.d.y - s.o.y) / (s.d.x - s.o.x), n = -(t.y - i * t.x - (s.o.y - r * s.o.x)) / (i - r)), n >= t.x && (o += 1), 2 !== o))) break; return o }, getBoundingRect: function(t, e) { var i = this.getCoords(t, e); return r.util.makeBoundingBoxFromPoints(i) }, getScaledWidth: function() { return this._getTransformedDimensions().x }, getScaledHeight: function() { return this._getTransformedDimensions().y }, _constrainScale: function(t) { return Math.abs(t) < this.minScaleLimit ? t < 0 ? -this.minScaleLimit : this.minScaleLimit : 0 === t ? 1e-4 : t }, scale: function(t) { return this._set("scaleX", t), this._set("scaleY", t), this.setCoords() }, scaleToWidth: function(t, e) { var i = this.getBoundingRect(e).width / this.getScaledWidth(); return this.scale(t / this.width / i) }, scaleToHeight: function(t, e) { var i = this.getBoundingRect(e).height / this.getScaledHeight(); return this.scale(t / this.height / i) }, calcCoords: function(n) { var s = this._calcRotateMatrix(),
                                o = this._calcTranslateMatrix(),
                                a = e(o, s),
                                h = this.getViewportTransform(),
                                c = n ? a : e(h, a),
                                l = this._getTransformedDimensions(),
                                u = l.x / 2,
                                f = l.y / 2,
                                d = i({ x: -u, y: -f }, c),
                                g = i({ x: u, y: -f }, c),
                                p = i({ x: -u, y: f }, c),
                                v = i({ x: u, y: f }, c); if (!n) { var m = this.padding,
                                    _ = t(this.angle),
                                    y = r.util.cos(_),
                                    b = r.util.sin(_),
                                    x = y * m,
                                    C = b * m,
                                    w = x + C,
                                    S = x - C;
                                m && (d.x -= S, d.y -= w, g.x += w, g.y -= S, p.x -= w, p.y += S, v.x += S, v.y += w); var T = new r.Point((d.x + p.x) / 2, (d.y + p.y) / 2),
                                    O = new r.Point((g.x + d.x) / 2, (g.y + d.y) / 2),
                                    k = new r.Point((v.x + g.x) / 2, (v.y + g.y) / 2),
                                    P = new r.Point((v.x + p.x) / 2, (v.y + p.y) / 2),
                                    E = new r.Point(O.x + b * this.rotatingPointOffset, O.y - y * this.rotatingPointOffset) } var A = { tl: d, tr: g, br: v, bl: p }; return n || (A.ml = T, A.mt = O, A.mr = k, A.mb = P, A.mtr = E), A }, setCoords: function(t, e) { return this.oCoords = this.calcCoords(t), e || (this.aCoords = this.calcCoords(!0)), t || this._setCornerCoords && this._setCornerCoords(), this }, _calcRotateMatrix: function() { if (this.angle) { var e = t(this.angle),
                                    i = r.util.cos(e),
                                    n = r.util.sin(e); return [i, n, -n, i, 0, 0] } return r.iMatrix.concat() }, _calcTranslateMatrix: function() { var t = this.getCenterPoint(); return [1, 0, 0, 1, t.x, t.y] }, transformMatrixKey: function(t) { var e = ""; return !t && this.group && (e = this.group.transformMatrixKey(t) + "_"), e + this.top + "_" + this.left + "_" + this.scaleX + "_" + this.scaleY + "_" + this.skewX + "_" + this.skewY + "_" + this.angle + "_" + this.originX + "_" + this.originY + "_" + this.width + "_" + this.height + "_" + this.strokeWidth + this.flipX + this.flipY }, calcTransformMatrix: function(t) { if (t) return this.calcOwnMatrix(); var i = this.transformMatrixKey(),
                                r = this.matrixCache || (this.matrixCache = {}); if (r.key === i) return r.value; var n = this.calcOwnMatrix(); return this.group && (n = e(this.group.calcTransformMatrix(), n)), r.key = i, r.value = n, n }, calcOwnMatrix: function() { var t = this.transformMatrixKey(!0),
                                i = this.ownMatrixCache || (this.ownMatrixCache = {}); if (i.key === t) return i.value; var r, n = this._calcTranslateMatrix(),
                                s = this._calcDimensionsTransformMatrix(this.skewX, this.skewY, !0); return this.angle && (r = this._calcRotateMatrix(), n = e(n, r)), n = e(n, s), i.key = t, i.value = n, n }, _calcDimensionsTransformMatrix: function(i, r, n) { var s, o = [this.scaleX * (n && this.flipX ? -1 : 1), 0, 0, this.scaleY * (n && this.flipY ? -1 : 1), 0, 0]; return i && (s = [1, 0, Math.tan(t(i)), 1], o = e(o, s, !0)), r && (s = [1, Math.tan(t(r)), 0, 1], o = e(o, s, !0)), o }, _getNonTransformedDimensions: function() { var t = this.strokeWidth; return { x: this.width + t, y: this.height + t } }, _getTransformedDimensions: function(t, e) { void 0 === t && (t = this.skewX), void 0 === e && (e = this.skewY); var i, n, s = this._getNonTransformedDimensions(),
                                o = 0 === t && 0 === e; if (this.strokeUniform ? (i = this.width, n = this.height) : (i = s.x, n = s.y), o) return this._finalizeDimensions(i * this.scaleX, n * this.scaleY); var a, h, c = [{ x: -(i /= 2), y: -(n /= 2) }, { x: i, y: -n }, { x: -i, y: n }, { x: i, y: n }],
                                l = this._calcDimensionsTransformMatrix(t, e, !1); for (a = 0; a < c.length; a++) c[a] = r.util.transformPoint(c[a], l); return h = r.util.makeBoundingBoxFromPoints(c), this._finalizeDimensions(h.width, h.height) }, _finalizeDimensions: function(t, e) { return this.strokeUniform ? { x: t + this.strokeWidth, y: e + this.strokeWidth } : { x: t, y: e } }, _calculateCurrentDimensions: function() { var t = this.getViewportTransform(),
                                e = this._getTransformedDimensions(); return r.util.transformPoint(e, t, !0).scalarAdd(2 * this.padding) } }) }(), r.util.object.extend(r.Object.prototype, { sendToBack: function() { return this.group ? r.StaticCanvas.prototype.sendToBack.call(this.group, this) : this.canvas.sendToBack(this), this }, bringToFront: function() { return this.group ? r.StaticCanvas.prototype.bringToFront.call(this.group, this) : this.canvas.bringToFront(this), this }, sendBackwards: function(t) { return this.group ? r.StaticCanvas.prototype.sendBackwards.call(this.group, this, t) : this.canvas.sendBackwards(this, t), this }, bringForward: function(t) { return this.group ? r.StaticCanvas.prototype.bringForward.call(this.group, this, t) : this.canvas.bringForward(this, t), this }, moveTo: function(t) { return this.group && "activeSelection" !== this.group.type ? r.StaticCanvas.prototype.moveTo.call(this.group, this, t) : this.canvas.moveTo(this, t), this } }),
                function() {
                    function t(t, e) { if (e) { if (e.toLive) return t + ": url(#SVGID_" + e.id + "); "; var i = new r.Color(e),
                                n = t + ": " + i.toRgb() + "; ",
                                s = i.getAlpha(); return 1 !== s && (n += t + "-opacity: " + s.toString() + "; "), n } return t + ": none; " } var e = r.util.toFixed;
                    r.util.object.extend(r.Object.prototype, { getSvgStyles: function(e) { var i = this.fillRule ? this.fillRule : "nonzero",
                                r = this.strokeWidth ? this.strokeWidth : "0",
                                n = this.strokeDashArray ? this.strokeDashArray.join(" ") : "none",
                                s = this.strokeDashOffset ? this.strokeDashOffset : "0",
                                o = this.strokeLineCap ? this.strokeLineCap : "butt",
                                a = this.strokeLineJoin ? this.strokeLineJoin : "miter",
                                h = this.strokeMiterLimit ? this.strokeMiterLimit : "4",
                                c = void 0 !== this.opacity ? this.opacity : "1",
                                l = this.visible ? "" : " visibility: hidden;",
                                u = e ? "" : this.getSvgFilter(),
                                f = t("fill", this.fill); return [t("stroke", this.stroke), "stroke-width: ", r, "; ", "stroke-dasharray: ", n, "; ", "stroke-linecap: ", o, "; ", "stroke-dashoffset: ", s, "; ", "stroke-linejoin: ", a, "; ", "stroke-miterlimit: ", h, "; ", f, "fill-rule: ", i, "; ", "opacity: ", c, ";", u, l].join("") }, getSvgSpanStyles: function(e, i) { var r = e.fontFamily ? "font-family: " + (-1 === e.fontFamily.indexOf("'") && -1 === e.fontFamily.indexOf('"') ? "'" + e.fontFamily + "'" : e.fontFamily) + "; " : "",
                                n = e.strokeWidth ? "stroke-width: " + e.strokeWidth + "; " : "",
                                s = (r = r, e.fontSize ? "font-size: " + e.fontSize + "px; " : ""),
                                o = e.fontStyle ? "font-style: " + e.fontStyle + "; " : "",
                                a = e.fontWeight ? "font-weight: " + e.fontWeight + "; " : "",
                                h = e.fill ? t("fill", e.fill) : "",
                                c = e.stroke ? t("stroke", e.stroke) : "",
                                l = this.getSvgTextDecoration(e),
                                u = e.deltaY ? "baseline-shift: " + -e.deltaY + "; " : ""; return l && (l = "text-decoration: " + l + "; "), [c, n, r, s, o, a, l, h, u, i ? "white-space: pre; " : ""].join("") }, getSvgTextDecoration: function(t) { return "overline" in t || "underline" in t || "linethrough" in t ? (t.overline ? "overline " : "") + (t.underline ? "underline " : "") + (t.linethrough ? "line-through " : "") : "" }, getSvgFilter: function() { return this.shadow ? "filter: url(#SVGID_" + this.shadow.id + ");" : "" }, getSvgCommons: function() { return [this.id ? 'id="' + this.id + '" ' : "", this.clipPath ? 'clip-path="url(#' + this.clipPath.clipPathId + ')" ' : ""].join("") }, getSvgTransform: function(t, e) { var i = t ? this.calcTransformMatrix() : this.calcOwnMatrix(); return 'transform="' + r.util.matrixToSVG(i) + (e || "") + this.getSvgTransformMatrix() + '" ' }, getSvgTransformMatrix: function() { return this.transformMatrix ? " " + r.util.matrixToSVG(this.transformMatrix) : "" }, _setSVGBg: function(t) { if (this.backgroundColor) { var i = r.Object.NUM_FRACTION_DIGITS;
                                t.push("\t\t<rect ", this._getFillAttributes(this.backgroundColor), ' x="', e(-this.width / 2, i), '" y="', e(-this.height / 2, i), '" width="', e(this.width, i), '" height="', e(this.height, i), '"></rect>\n') } }, toSVG: function(t) { return this._createBaseSVGMarkup(this._toSVG(t), { reviver: t }) }, toClipPathSVG: function(t) { return "\t" + this._createBaseClipPathSVGMarkup(this._toSVG(t), { reviver: t }) }, _createBaseClipPathSVGMarkup: function(t, e) { var i = (e = e || {}).reviver,
                                r = e.additionalTransform || "",
                                n = [this.getSvgTransform(!0, r), this.getSvgCommons()].join(""); return t[t.indexOf("COMMON_PARTS")] = n, i ? i(t.join("")) : t.join("") }, _createBaseSVGMarkup: function(t, e) { var i, n, s = (e = e || {}).noStyle,
                                o = e.reviver,
                                a = s ? "" : 'style="' + this.getSvgStyles() + '" ',
                                h = e.withShadow ? 'style="' + this.getSvgFilter() + '" ' : "",
                                c = this.clipPath,
                                l = this.strokeUniform ? 'vector-effect="non-scaling-stroke" ' : "",
                                u = c && c.absolutePositioned,
                                f = this.stroke,
                                d = this.fill,
                                g = this.shadow,
                                p = [],
                                v = t.indexOf("COMMON_PARTS"),
                                m = e.additionalTransform; return c && (c.clipPathId = "CLIPPATH_" + r.Object.__uid++, n = '<clipPath id="' + c.clipPathId + '" >\n' + c.toClipPathSVG(o) + "</clipPath>\n"), u && p.push("<g ", h, this.getSvgCommons(), " >\n"), p.push("<g ", this.getSvgTransform(!1), u ? "" : h + this.getSvgCommons(), " >\n"), i = [a, l, s ? "" : this.addPaintOrder(), " ", m ? 'transform="' + m + '" ' : ""].join(""), t[v] = i, d && d.toLive && p.push(d.toSVG(this)), f && f.toLive && p.push(f.toSVG(this)), g && p.push(g.toSVG(this)), c && p.push(n), p.push(t.join("")), p.push("</g>\n"), u && p.push("</g>\n"), o ? o(p.join("")) : p.join("") }, addPaintOrder: function() { return "fill" !== this.paintFirst ? ' paint-order="' + this.paintFirst + '" ' : "" } }) }(),
                function() { var t = r.util.object.extend;

                    function e(e, i, r) { var n = {};
                        r.forEach(function(t) { n[t] = e[t] }), t(e[i], n, !0) } r.util.object.extend(r.Object.prototype, { hasStateChanged: function(t) { var e = "_" + (t = t || "stateProperties"); return Object.keys(this[e]).length < this[t].length || ! function t(e, i, r) { if (e === i) return !0; if (Array.isArray(e)) { if (!Array.isArray(i) || e.length !== i.length) return !1; for (var n = 0, s = e.length; n < s; n++)
                                        if (!t(e[n], i[n])) return !1; return !0 } if (e && "object" == typeof e) { var o, a = Object.keys(e); if (!i || "object" != typeof i || !r && a.length !== Object.keys(i).length) return !1; for (n = 0, s = a.length; n < s; n++)
                                        if ("canvas" !== (o = a[n]) && !t(e[o], i[o])) return !1; return !0 } }(this[e], this, !0) }, saveState: function(t) { var i = t && t.propertySet || "stateProperties",
                                r = "_" + i; return this[r] ? (e(this, r, this[i]), t && t.stateProperties && e(this, r, t.stateProperties), this) : this.setupState(t) }, setupState: function(t) { var e = (t = t || {}).propertySet || "stateProperties"; return t.propertySet = e, this["_" + e] = {}, this.saveState(t), this } }) }(),
                function() { var t = r.util.degreesToRadians;
                    r.util.object.extend(r.Object.prototype, { _controlsVisibility: null, _findTargetCorner: function(t) { if (!this.hasControls || this.group || !this.canvas || this.canvas._activeObject !== this) return !1; var e, i, r = t.x,
                                n = t.y; for (var s in this.__corner = 0, this.oCoords)
                                if (this.isControlVisible(s) && ("mtr" !== s || this.hasRotatingPoint) && (!this.get("lockUniScaling") || "mt" !== s && "mr" !== s && "mb" !== s && "ml" !== s) && (i = this._getImageLines(this.oCoords[s].corner), 0 !== (e = this._findCrossPoints({ x: r, y: n }, i)) && e % 2 == 1)) return this.__corner = s, s; return !1 }, _setCornerCoords: function() { var e, i, n = this.oCoords,
                                s = t(45 - this.angle),
                                o = .707106 * this.cornerSize,
                                a = o * r.util.cos(s),
                                h = o * r.util.sin(s); for (var c in n) e = n[c].x, i = n[c].y, n[c].corner = { tl: { x: e - h, y: i - a }, tr: { x: e + a, y: i - h }, bl: { x: e - a, y: i + h }, br: { x: e + h, y: i + a } } }, drawSelectionBackground: function(e) { if (!this.selectionBackgroundColor || this.canvas && !this.canvas.interactive || this.canvas && this.canvas._activeObject !== this) return this;
                            e.save(); var i = this.getCenterPoint(),
                                r = this._calculateCurrentDimensions(),
                                n = this.canvas.viewportTransform; return e.translate(i.x, i.y), e.scale(1 / n[0], 1 / n[3]), e.rotate(t(this.angle)), e.fillStyle = this.selectionBackgroundColor, e.fillRect(-r.x / 2, -r.y / 2, r.x, r.y), e.restore(), this }, drawBorders: function(t, e) { e = e || {}; var i = this._calculateCurrentDimensions(),
                                r = 1 / this.borderScaleFactor,
                                n = i.x + r,
                                s = i.y + r,
                                o = void 0 !== e.hasRotatingPoint ? e.hasRotatingPoint : this.hasRotatingPoint,
                                a = void 0 !== e.hasControls ? e.hasControls : this.hasControls,
                                h = void 0 !== e.rotatingPointOffset ? e.rotatingPointOffset : this.rotatingPointOffset; if (t.save(), t.strokeStyle = e.borderColor || this.borderColor, this._setLineDash(t, e.borderDashArray || this.borderDashArray, null), t.strokeRect(-n / 2, -s / 2, n, s), o && this.isControlVisible("mtr") && a) { var c = -s / 2;
                                t.beginPath(), t.moveTo(0, c), t.lineTo(0, c - h), t.stroke() } return t.restore(), this }, drawBordersInGroup: function(t, e, i) { i = i || {}; var n = this._getNonTransformedDimensions(),
                                s = r.util.customTransformMatrix(e.scaleX, e.scaleY, e.skewX),
                                o = r.util.transformPoint(n, s),
                                a = 1 / this.borderScaleFactor,
                                h = o.x + a,
                                c = o.y + a; return t.save(), this._setLineDash(t, i.borderDashArray || this.borderDashArray, null), t.strokeStyle = i.borderColor || this.borderColor, t.strokeRect(-h / 2, -c / 2, h, c), t.restore(), this }, drawControls: function(t, e) { e = e || {}; var i = this._calculateCurrentDimensions(),
                                r = i.x,
                                n = i.y,
                                s = e.cornerSize || this.cornerSize,
                                o = -(r + s) / 2,
                                a = -(n + s) / 2,
                                h = void 0 !== e.transparentCorners ? e.transparentCorners : this.transparentCorners,
                                c = void 0 !== e.hasRotatingPoint ? e.hasRotatingPoint : this.hasRotatingPoint,
                                l = h ? "stroke" : "fill"; return t.save(), t.strokeStyle = t.fillStyle = e.cornerColor || this.cornerColor, this.transparentCorners || (t.strokeStyle = e.cornerStrokeColor || this.cornerStrokeColor), this._setLineDash(t, e.cornerDashArray || this.cornerDashArray, null), this._drawControl("tl", t, l, o, a, e), this._drawControl("tr", t, l, o + r, a, e), this._drawControl("bl", t, l, o, a + n, e), this._drawControl("br", t, l, o + r, a + n, e), this.get("lockUniScaling") || (this._drawControl("mt", t, l, o + r / 2, a, e), this._drawControl("mb", t, l, o + r / 2, a + n, e), this._drawControl("mr", t, l, o + r, a + n / 2, e), this._drawControl("ml", t, l, o, a + n / 2, e)), c && this._drawControl("mtr", t, l, o + r / 2, a - this.rotatingPointOffset, e), t.restore(), this }, _drawControl: function(t, e, i, r, n, s) { if (s = s || {}, this.isControlVisible(t)) { var o = this.cornerSize,
                                    a = !this.transparentCorners && this.cornerStrokeColor; switch (s.cornerStyle || this.cornerStyle) {
                                    case "circle":
                                        e.beginPath(), e.arc(r + o / 2, n + o / 2, o / 2, 0, 2 * Math.PI, !1), e[i](), a && e.stroke(); break;
                                    default:
                                        this.transparentCorners || e.clearRect(r, n, o, o), e[i + "Rect"](r, n, o, o), a && e.strokeRect(r, n, o, o) } } }, isControlVisible: function(t) { return this._getControlsVisibility()[t] }, setControlVisible: function(t, e) { return this._getControlsVisibility()[t] = e, this }, setControlsVisibility: function(t) { for (var e in t || (t = {}), t) this.setControlVisible(e, t[e]); return this }, _getControlsVisibility: function() { return this._controlsVisibility || (this._controlsVisibility = { tl: !0, tr: !0, br: !0, bl: !0, ml: !0, mt: !0, mr: !0, mb: !0, mtr: !0 }), this._controlsVisibility }, onDeselect: function() {}, onSelect: function() {} }) }(), r.util.object.extend(r.StaticCanvas.prototype, { FX_DURATION: 500, fxCenterObjectH: function(t, e) { var i = function() {},
                            n = (e = e || {}).onComplete || i,
                            s = e.onChange || i,
                            o = this; return r.util.animate({ startValue: t.left, endValue: this.getCenter().left, duration: this.FX_DURATION, onChange: function(e) { t.set("left", e), o.requestRenderAll(), s() }, onComplete: function() { t.setCoords(), n() } }), this }, fxCenterObjectV: function(t, e) { var i = function() {},
                            n = (e = e || {}).onComplete || i,
                            s = e.onChange || i,
                            o = this; return r.util.animate({ startValue: t.top, endValue: this.getCenter().top, duration: this.FX_DURATION, onChange: function(e) { t.set("top", e), o.requestRenderAll(), s() }, onComplete: function() { t.setCoords(), n() } }), this }, fxRemove: function(t, e) { var i = function() {},
                            n = (e = e || {}).onComplete || i,
                            s = e.onChange || i,
                            o = this; return r.util.animate({ startValue: t.opacity, endValue: 0, duration: this.FX_DURATION, onChange: function(e) { t.set("opacity", e), o.requestRenderAll(), s() }, onComplete: function() { o.remove(t), n() } }), this } }), r.util.object.extend(r.Object.prototype, { animate: function() { if (arguments[0] && "object" == typeof arguments[0]) { var t, e, i = []; for (t in arguments[0]) i.push(t); for (var r = 0, n = i.length; r < n; r++) t = i[r], e = r !== n - 1, this._animate(t, arguments[0][t], arguments[1], e) } else this._animate.apply(this, arguments); return this }, _animate: function(t, e, i, n) { var s, o = this;
                        e = e.toString(), i = i ? r.util.object.clone(i) : {}, ~t.indexOf(".") && (s = t.split(".")); var a = s ? this.get(s[0])[s[1]] : this.get(t); "from" in i || (i.from = a), e = ~e.indexOf("=") ? a + parseFloat(e.replace("=", "")) : parseFloat(e), r.util.animate({ startValue: i.from, endValue: e, byValue: i.by, easing: i.easing, duration: i.duration, abort: i.abort && function() { return i.abort.call(o) }, onChange: function(e, r, a) { s ? o[s[0]][s[1]] = e : o.set(t, e), n || i.onChange && i.onChange(e, r, a) }, onComplete: function(t, e, r) { n || (o.setCoords(), i.onComplete && i.onComplete(t, e, r)) } }) } }),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.util.object.extend,
                        r = e.util.object.clone,
                        n = { x1: 1, x2: 1, y1: 1, y2: 1 },
                        s = e.StaticCanvas.supports("setLineDash");

                    function o(t, e) { var i = t.origin,
                            r = t.axis1,
                            n = t.axis2,
                            s = t.dimension,
                            o = e.nearest,
                            a = e.center,
                            h = e.farthest; return function() { switch (this.get(i)) {
                                case o:
                                    return Math.min(this.get(r), this.get(n));
                                case a:
                                    return Math.min(this.get(r), this.get(n)) + .5 * this.get(s);
                                case h:
                                    return Math.max(this.get(r), this.get(n)) } } } e.Line ? e.warn("fabric.Line is already defined") : (e.Line = e.util.createClass(e.Object, { type: "line", x1: 0, y1: 0, x2: 0, y2: 0, cacheProperties: e.Object.prototype.cacheProperties.concat("x1", "x2", "y1", "y2"), initialize: function(t, e) { t || (t = [0, 0, 0, 0]), this.callSuper("initialize", e), this.set("x1", t[0]), this.set("y1", t[1]), this.set("x2", t[2]), this.set("y2", t[3]), this._setWidthHeight(e) }, _setWidthHeight: function(t) { t || (t = {}), this.width = Math.abs(this.x2 - this.x1), this.height = Math.abs(this.y2 - this.y1), this.left = "left" in t ? t.left : this._getLeftToOriginX(), this.top = "top" in t ? t.top : this._getTopToOriginY() }, _set: function(t, e) { return this.callSuper("_set", t, e), void 0 !== n[t] && this._setWidthHeight(), this }, _getLeftToOriginX: o({ origin: "originX", axis1: "x1", axis2: "x2", dimension: "width" }, { nearest: "left", center: "center", farthest: "right" }), _getTopToOriginY: o({ origin: "originY", axis1: "y1", axis2: "y2", dimension: "height" }, { nearest: "top", center: "center", farthest: "bottom" }), _render: function(t) { if (t.beginPath(), !this.strokeDashArray || this.strokeDashArray && s) { var e = this.calcLinePoints();
                                t.moveTo(e.x1, e.y1), t.lineTo(e.x2, e.y2) } t.lineWidth = this.strokeWidth; var i = t.strokeStyle;
                            t.strokeStyle = this.stroke || t.fillStyle, this.stroke && this._renderStroke(t), t.strokeStyle = i }, _renderDashedStroke: function(t) { var i = this.calcLinePoints();
                            t.beginPath(), e.util.drawDashedLine(t, i.x1, i.y1, i.x2, i.y2, this.strokeDashArray), t.closePath() }, _findCenterFromElement: function() { return { x: (this.x1 + this.x2) / 2, y: (this.y1 + this.y2) / 2 } }, toObject: function(t) { return i(this.callSuper("toObject", t), this.calcLinePoints()) }, _getNonTransformedDimensions: function() { var t = this.callSuper("_getNonTransformedDimensions"); return "butt" === this.strokeLineCap && (0 === this.width && (t.y -= this.strokeWidth), 0 === this.height && (t.x -= this.strokeWidth)), t }, calcLinePoints: function() { var t = this.x1 <= this.x2 ? -1 : 1,
                                e = this.y1 <= this.y2 ? -1 : 1,
                                i = t * this.width * .5,
                                r = e * this.height * .5; return { x1: i, x2: t * this.width * -.5, y1: r, y2: e * this.height * -.5 } }, _toSVG: function() { var t = this.calcLinePoints(); return ["<line ", "COMMON_PARTS", 'x1="', t.x1, '" y1="', t.y1, '" x2="', t.x2, '" y2="', t.y2, '" />\n'] } }), e.Line.ATTRIBUTE_NAMES = e.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")), e.Line.fromElement = function(t, r, n) { n = n || {}; var s = e.parseAttributes(t, e.Line.ATTRIBUTE_NAMES),
                            o = [s.x1 || 0, s.y1 || 0, s.x2 || 0, s.y2 || 0];
                        r(new e.Line(o, i(s, n))) }, e.Line.fromObject = function(t, i) { var n = r(t, !0);
                        n.points = [t.x1, t.y1, t.x2, t.y2], e.Object._fromObject("Line", n, function(t) { delete t.points, i && i(t) }, "points") }) }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = Math.PI;
                    e.Circle ? e.warn("fabric.Circle is already defined.") : (e.Circle = e.util.createClass(e.Object, { type: "circle", radius: 0, startAngle: 0, endAngle: 2 * i, cacheProperties: e.Object.prototype.cacheProperties.concat("radius", "startAngle", "endAngle"), _set: function(t, e) { return this.callSuper("_set", t, e), "radius" === t && this.setRadius(e), this }, toObject: function(t) { return this.callSuper("toObject", ["radius", "startAngle", "endAngle"].concat(t)) }, _toSVG: function() { var t, r = (this.endAngle - this.startAngle) % (2 * i); if (0 === r) t = ["<circle ", "COMMON_PARTS", 'cx="0" cy="0" ', 'r="', this.radius, '" />\n'];
                            else { var n = e.util.cos(this.startAngle) * this.radius,
                                    s = e.util.sin(this.startAngle) * this.radius,
                                    o = e.util.cos(this.endAngle) * this.radius,
                                    a = e.util.sin(this.endAngle) * this.radius,
                                    h = r > i ? "1" : "0";
                                t = ['<path d="M ' + n + " " + s, " A " + this.radius + " " + this.radius, " 0 ", +h + " 1", " " + o + " " + a, '" ', "COMMON_PARTS", " />\n"] } return t }, _render: function(t) { t.beginPath(), t.arc(0, 0, this.radius, this.startAngle, this.endAngle, !1), this._renderPaintInOrder(t) }, getRadiusX: function() { return this.get("radius") * this.get("scaleX") }, getRadiusY: function() { return this.get("radius") * this.get("scaleY") }, setRadius: function(t) { return this.radius = t, this.set("width", 2 * t).set("height", 2 * t) } }), e.Circle.ATTRIBUTE_NAMES = e.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")), e.Circle.fromElement = function(t, i) { var r = e.parseAttributes(t, e.Circle.ATTRIBUTE_NAMES); if (! function(t) { return "radius" in t && t.radius >= 0 }(r)) throw new Error("value of `r` attribute is required and can not be negative");
                        r.left = (r.left || 0) - r.radius, r.top = (r.top || 0) - r.radius, i(new e.Circle(r)) }, e.Circle.fromObject = function(t, i) { return e.Object._fromObject("Circle", t, i) }) }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {});
                    e.Triangle ? e.warn("fabric.Triangle is already defined") : (e.Triangle = e.util.createClass(e.Object, { type: "triangle", width: 100, height: 100, _render: function(t) { var e = this.width / 2,
                                i = this.height / 2;
                            t.beginPath(), t.moveTo(-e, i), t.lineTo(0, -i), t.lineTo(e, i), t.closePath(), this._renderPaintInOrder(t) }, _renderDashedStroke: function(t) { var i = this.width / 2,
                                r = this.height / 2;
                            t.beginPath(), e.util.drawDashedLine(t, -i, r, 0, -r, this.strokeDashArray), e.util.drawDashedLine(t, 0, -r, i, r, this.strokeDashArray), e.util.drawDashedLine(t, i, r, -i, r, this.strokeDashArray), t.closePath() }, _toSVG: function() { var t = this.width / 2,
                                e = this.height / 2; return ["<polygon ", "COMMON_PARTS", 'points="', [-t + " " + e, "0 " + -e, t + " " + e].join(","), '" />'] } }), e.Triangle.fromObject = function(t, i) { return e.Object._fromObject("Triangle", t, i) }) }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = 2 * Math.PI;
                    e.Ellipse ? e.warn("fabric.Ellipse is already defined.") : (e.Ellipse = e.util.createClass(e.Object, { type: "ellipse", rx: 0, ry: 0, cacheProperties: e.Object.prototype.cacheProperties.concat("rx", "ry"), initialize: function(t) { this.callSuper("initialize", t), this.set("rx", t && t.rx || 0), this.set("ry", t && t.ry || 0) }, _set: function(t, e) { switch (this.callSuper("_set", t, e), t) {
                                case "rx":
                                    this.rx = e, this.set("width", 2 * e); break;
                                case "ry":
                                    this.ry = e, this.set("height", 2 * e) } return this }, getRx: function() { return this.get("rx") * this.get("scaleX") }, getRy: function() { return this.get("ry") * this.get("scaleY") }, toObject: function(t) { return this.callSuper("toObject", ["rx", "ry"].concat(t)) }, _toSVG: function() { return ["<ellipse ", "COMMON_PARTS", 'cx="0" cy="0" ', 'rx="', this.rx, '" ry="', this.ry, '" />\n'] }, _render: function(t) { t.beginPath(), t.save(), t.transform(1, 0, 0, this.ry / this.rx, 0, 0), t.arc(0, 0, this.rx, 0, i, !1), t.restore(), this._renderPaintInOrder(t) } }), e.Ellipse.ATTRIBUTE_NAMES = e.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")), e.Ellipse.fromElement = function(t, i) { var r = e.parseAttributes(t, e.Ellipse.ATTRIBUTE_NAMES);
                        r.left = (r.left || 0) - r.rx, r.top = (r.top || 0) - r.ry, i(new e.Ellipse(r)) }, e.Ellipse.fromObject = function(t, i) { return e.Object._fromObject("Ellipse", t, i) }) }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.util.object.extend;
                    e.Rect ? e.warn("fabric.Rect is already defined") : (e.Rect = e.util.createClass(e.Object, { stateProperties: e.Object.prototype.stateProperties.concat("rx", "ry"), type: "rect", rx: 0, ry: 0, cacheProperties: e.Object.prototype.cacheProperties.concat("rx", "ry"), initialize: function(t) { this.callSuper("initialize", t), this._initRxRy() }, _initRxRy: function() { this.rx && !this.ry ? this.ry = this.rx : this.ry && !this.rx && (this.rx = this.ry) }, _render: function(t) { var e = this.rx ? Math.min(this.rx, this.width / 2) : 0,
                                i = this.ry ? Math.min(this.ry, this.height / 2) : 0,
                                r = this.width,
                                n = this.height,
                                s = -this.width / 2,
                                o = -this.height / 2,
                                a = 0 !== e || 0 !== i,
                                h = .4477152502;
                            t.beginPath(), t.moveTo(s + e, o), t.lineTo(s + r - e, o), a && t.bezierCurveTo(s + r - h * e, o, s + r, o + h * i, s + r, o + i), t.lineTo(s + r, o + n - i), a && t.bezierCurveTo(s + r, o + n - h * i, s + r - h * e, o + n, s + r - e, o + n), t.lineTo(s + e, o + n), a && t.bezierCurveTo(s + h * e, o + n, s, o + n - h * i, s, o + n - i), t.lineTo(s, o + i), a && t.bezierCurveTo(s, o + h * i, s + h * e, o, s + e, o), t.closePath(), this._renderPaintInOrder(t) }, _renderDashedStroke: function(t) { var i = -this.width / 2,
                                r = -this.height / 2,
                                n = this.width,
                                s = this.height;
                            t.beginPath(), e.util.drawDashedLine(t, i, r, i + n, r, this.strokeDashArray), e.util.drawDashedLine(t, i + n, r, i + n, r + s, this.strokeDashArray), e.util.drawDashedLine(t, i + n, r + s, i, r + s, this.strokeDashArray), e.util.drawDashedLine(t, i, r + s, i, r, this.strokeDashArray), t.closePath() }, toObject: function(t) { return this.callSuper("toObject", ["rx", "ry"].concat(t)) }, _toSVG: function() { return ["<rect ", "COMMON_PARTS", 'x="', -this.width / 2, '" y="', -this.height / 2, '" rx="', this.rx, '" ry="', this.ry, '" width="', this.width, '" height="', this.height, '" />\n'] } }), e.Rect.ATTRIBUTE_NAMES = e.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")), e.Rect.fromElement = function(t, r, n) { if (!t) return r(null);
                        n = n || {}; var s = e.parseAttributes(t, e.Rect.ATTRIBUTE_NAMES);
                        s.left = s.left || 0, s.top = s.top || 0, s.height = s.height || 0, s.width = s.width || 0; var o = new e.Rect(i(n ? e.util.object.clone(n) : {}, s));
                        o.visible = o.visible && o.width > 0 && o.height > 0, r(o) }, e.Rect.fromObject = function(t, i) { return e.Object._fromObject("Rect", t, i) }) }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.util.object.extend,
                        r = e.util.array.min,
                        n = e.util.array.max,
                        s = e.util.toFixed;
                    e.Polyline ? e.warn("fabric.Polyline is already defined") : (e.Polyline = e.util.createClass(e.Object, { type: "polyline", points: null, cacheProperties: e.Object.prototype.cacheProperties.concat("points"), initialize: function(t, e) { e = e || {}, this.points = t || [], this.callSuper("initialize", e), this._setPositionDimensions(e) }, _setPositionDimensions: function(t) { var e, i = this._calcDimensions(t);
                            this.width = i.width, this.height = i.height, t.fromSVG || (e = this.translateToGivenOrigin({ x: i.left - this.strokeWidth / 2, y: i.top - this.strokeWidth / 2 }, "left", "top", this.originX, this.originY)), void 0 === t.left && (this.left = t.fromSVG ? i.left : e.x), void 0 === t.top && (this.top = t.fromSVG ? i.top : e.y), this.pathOffset = { x: i.left + this.width / 2, y: i.top + this.height / 2 } }, _calcDimensions: function() { var t = this.points,
                                e = r(t, "x") || 0,
                                i = r(t, "y") || 0; return { left: e, top: i, width: (n(t, "x") || 0) - e, height: (n(t, "y") || 0) - i } }, toObject: function(t) { return i(this.callSuper("toObject", t), { points: this.points.concat() }) }, _toSVG: function() { for (var t = [], i = this.pathOffset.x, r = this.pathOffset.y, n = e.Object.NUM_FRACTION_DIGITS, o = 0, a = this.points.length; o < a; o++) t.push(s(this.points[o].x - i, n), ",", s(this.points[o].y - r, n), " "); return ["<" + this.type + " ", "COMMON_PARTS", 'points="', t.join(""), '" />\n'] }, commonRender: function(t) { var e, i = this.points.length,
                                r = this.pathOffset.x,
                                n = this.pathOffset.y; if (!i || isNaN(this.points[i - 1].y)) return !1;
                            t.beginPath(), t.moveTo(this.points[0].x - r, this.points[0].y - n); for (var s = 0; s < i; s++) e = this.points[s], t.lineTo(e.x - r, e.y - n); return !0 }, _render: function(t) { this.commonRender(t) && this._renderPaintInOrder(t) }, _renderDashedStroke: function(t) { var i, r;
                            t.beginPath(); for (var n = 0, s = this.points.length; n < s; n++) i = this.points[n], r = this.points[n + 1] || i, e.util.drawDashedLine(t, i.x, i.y, r.x, r.y, this.strokeDashArray) }, complexity: function() { return this.get("points").length } }), e.Polyline.ATTRIBUTE_NAMES = e.SHARED_ATTRIBUTES.concat(), e.Polyline.fromElementGenerator = function(t) { return function(r, n, s) { if (!r) return n(null);
                            s || (s = {}); var o = e.parsePointsAttribute(r.getAttribute("points")),
                                a = e.parseAttributes(r, e[t].ATTRIBUTE_NAMES);
                            a.fromSVG = !0, n(new e[t](o, i(a, s))) } }, e.Polyline.fromElement = e.Polyline.fromElementGenerator("Polyline"), e.Polyline.fromObject = function(t, i) { return e.Object._fromObject("Polyline", t, i, "points") }) }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {});
                    e.Polygon ? e.warn("fabric.Polygon is already defined") : (e.Polygon = e.util.createClass(e.Polyline, { type: "polygon", _render: function(t) { this.commonRender(t) && (t.closePath(), this._renderPaintInOrder(t)) }, _renderDashedStroke: function(t) { this.callSuper("_renderDashedStroke", t), t.closePath() } }), e.Polygon.ATTRIBUTE_NAMES = e.SHARED_ATTRIBUTES.concat(), e.Polygon.fromElement = e.Polyline.fromElementGenerator("Polygon"), e.Polygon.fromObject = function(t, i) { return e.Object._fromObject("Polygon", t, i, "points") }) }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.util.array.min,
                        r = e.util.array.max,
                        n = e.util.object.extend,
                        s = Object.prototype.toString,
                        o = e.util.drawArc,
                        a = e.util.toFixed,
                        h = { m: 2, l: 2, h: 1, v: 1, c: 6, s: 4, q: 4, t: 2, a: 7 },
                        c = { m: "l", M: "L" };
                    e.Path ? e.warn("fabric.Path is already defined") : (e.Path = e.util.createClass(e.Object, { type: "path", path: null, cacheProperties: e.Object.prototype.cacheProperties.concat("path", "fillRule"), stateProperties: e.Object.prototype.stateProperties.concat("path"), initialize: function(t, i) { i = i || {}, this.callSuper("initialize", i), t || (t = []); var r = "[object Array]" === s.call(t);
                            this.path = r ? t : t.match && t.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi), this.path && (r || (this.path = this._parsePath()), e.Polyline.prototype._setPositionDimensions.call(this, i)) }, _renderPathCommands: function(t) { var e, i, r, n = null,
                                s = 0,
                                a = 0,
                                h = 0,
                                c = 0,
                                l = 0,
                                u = 0,
                                f = -this.pathOffset.x,
                                d = -this.pathOffset.y;
                            t.beginPath(); for (var g = 0, p = this.path.length; g < p; ++g) { switch ((e = this.path[g])[0]) {
                                    case "l":
                                        h += e[1], c += e[2], t.lineTo(h + f, c + d); break;
                                    case "L":
                                        h = e[1], c = e[2], t.lineTo(h + f, c + d); break;
                                    case "h":
                                        h += e[1], t.lineTo(h + f, c + d); break;
                                    case "H":
                                        h = e[1], t.lineTo(h + f, c + d); break;
                                    case "v":
                                        c += e[1], t.lineTo(h + f, c + d); break;
                                    case "V":
                                        c = e[1], t.lineTo(h + f, c + d); break;
                                    case "m":
                                        s = h += e[1], a = c += e[2], t.moveTo(h + f, c + d); break;
                                    case "M":
                                        s = h = e[1], a = c = e[2], t.moveTo(h + f, c + d); break;
                                    case "c":
                                        i = h + e[5], r = c + e[6], l = h + e[3], u = c + e[4], t.bezierCurveTo(h + e[1] + f, c + e[2] + d, l + f, u + d, i + f, r + d), h = i, c = r; break;
                                    case "C":
                                        h = e[5], c = e[6], l = e[3], u = e[4], t.bezierCurveTo(e[1] + f, e[2] + d, l + f, u + d, h + f, c + d); break;
                                    case "s":
                                        i = h + e[3], r = c + e[4], null === n[0].match(/[CcSs]/) ? (l = h, u = c) : (l = 2 * h - l, u = 2 * c - u), t.bezierCurveTo(l + f, u + d, h + e[1] + f, c + e[2] + d, i + f, r + d), l = h + e[1], u = c + e[2], h = i, c = r; break;
                                    case "S":
                                        i = e[3], r = e[4], null === n[0].match(/[CcSs]/) ? (l = h, u = c) : (l = 2 * h - l, u = 2 * c - u), t.bezierCurveTo(l + f, u + d, e[1] + f, e[2] + d, i + f, r + d), h = i, c = r, l = e[1], u = e[2]; break;
                                    case "q":
                                        i = h + e[3], r = c + e[4], l = h + e[1], u = c + e[2], t.quadraticCurveTo(l + f, u + d, i + f, r + d), h = i, c = r; break;
                                    case "Q":
                                        i = e[3], r = e[4], t.quadraticCurveTo(e[1] + f, e[2] + d, i + f, r + d), h = i, c = r, l = e[1], u = e[2]; break;
                                    case "t":
                                        i = h + e[1], r = c + e[2], null === n[0].match(/[QqTt]/) ? (l = h, u = c) : (l = 2 * h - l, u = 2 * c - u), t.quadraticCurveTo(l + f, u + d, i + f, r + d), h = i, c = r; break;
                                    case "T":
                                        i = e[1], r = e[2], null === n[0].match(/[QqTt]/) ? (l = h, u = c) : (l = 2 * h - l, u = 2 * c - u), t.quadraticCurveTo(l + f, u + d, i + f, r + d), h = i, c = r; break;
                                    case "a":
                                        o(t, h + f, c + d, [e[1], e[2], e[3], e[4], e[5], e[6] + h + f, e[7] + c + d]), h += e[6], c += e[7]; break;
                                    case "A":
                                        o(t, h + f, c + d, [e[1], e[2], e[3], e[4], e[5], e[6] + f, e[7] + d]), h = e[6], c = e[7]; break;
                                    case "z":
                                    case "Z":
                                        h = s, c = a, t.closePath() } n = e } }, _render: function(t) { this._renderPathCommands(t), this._renderPaintInOrder(t) }, toString: function() { return "#<fabric.Path (" + this.complexity() + '): { "top": ' + this.top + ', "left": ' + this.left + " }>" }, toObject: function(t) { return n(this.callSuper("toObject", t), { path: this.path.map(function(t) { return t.slice() }) }) }, toDatalessObject: function(t) { var e = this.toObject(["sourcePath"].concat(t)); return e.sourcePath && delete e.path, e }, _toSVG: function() { return ["<path ", "COMMON_PARTS", 'd="', this.path.map(function(t) { return t.join(" ") }).join(" "), '" stroke-linecap="round" ', "/>\n"] }, _getOffsetTransform: function() { var t = e.Object.NUM_FRACTION_DIGITS; return " translate(" + a(-this.pathOffset.x, t) + ", " + a(-this.pathOffset.y, t) + ")" }, toClipPathSVG: function(t) { var e = this._getOffsetTransform(); return "\t" + this._createBaseClipPathSVGMarkup(this._toSVG(), { reviver: t, additionalTransform: e }) }, toSVG: function(t) { var e = this._getOffsetTransform(); return this._createBaseSVGMarkup(this._toSVG(), { reviver: t, additionalTransform: e }) }, complexity: function() { return this.path.length }, _parsePath: function() { for (var t, e, i, r, n, s = [], o = [], a = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi, l = 0, u = this.path.length; l < u; l++) { for (r = (t = this.path[l]).slice(1).trim(), o.length = 0; i = a.exec(r);) o.push(i[0]);
                                n = [t.charAt(0)]; for (var f = 0, d = o.length; f < d; f++) e = parseFloat(o[f]), isNaN(e) || n.push(e); var g = n[0],
                                    p = h[g.toLowerCase()],
                                    v = c[g] || g; if (n.length - 1 > p)
                                    for (var m = 1, _ = n.length; m < _; m += p) s.push([g].concat(n.slice(m, m + p))), g = v;
                                else s.push(n) } return s }, _calcDimensions: function() { for (var t, n, s, o, a = [], h = [], c = null, l = 0, u = 0, f = 0, d = 0, g = 0, p = 0, v = 0, m = this.path.length; v < m; ++v) { switch ((t = this.path[v])[0]) {
                                    case "l":
                                        f += t[1], d += t[2], o = []; break;
                                    case "L":
                                        f = t[1], d = t[2], o = []; break;
                                    case "h":
                                        f += t[1], o = []; break;
                                    case "H":
                                        f = t[1], o = []; break;
                                    case "v":
                                        d += t[1], o = []; break;
                                    case "V":
                                        d = t[1], o = []; break;
                                    case "m":
                                        l = f += t[1], u = d += t[2], o = []; break;
                                    case "M":
                                        l = f = t[1], u = d = t[2], o = []; break;
                                    case "c":
                                        n = f + t[5], s = d + t[6], g = f + t[3], p = d + t[4], o = e.util.getBoundsOfCurve(f, d, f + t[1], d + t[2], g, p, n, s), f = n, d = s; break;
                                    case "C":
                                        g = t[3], p = t[4], o = e.util.getBoundsOfCurve(f, d, t[1], t[2], g, p, t[5], t[6]), f = t[5], d = t[6]; break;
                                    case "s":
                                        n = f + t[3], s = d + t[4], null === c[0].match(/[CcSs]/) ? (g = f, p = d) : (g = 2 * f - g, p = 2 * d - p), o = e.util.getBoundsOfCurve(f, d, g, p, f + t[1], d + t[2], n, s), g = f + t[1], p = d + t[2], f = n, d = s; break;
                                    case "S":
                                        n = t[3], s = t[4], null === c[0].match(/[CcSs]/) ? (g = f, p = d) : (g = 2 * f - g, p = 2 * d - p), o = e.util.getBoundsOfCurve(f, d, g, p, t[1], t[2], n, s), f = n, d = s, g = t[1], p = t[2]; break;
                                    case "q":
                                        n = f + t[3], s = d + t[4], g = f + t[1], p = d + t[2], o = e.util.getBoundsOfCurve(f, d, g, p, g, p, n, s), f = n, d = s; break;
                                    case "Q":
                                        g = t[1], p = t[2], o = e.util.getBoundsOfCurve(f, d, g, p, g, p, t[3], t[4]), f = t[3], d = t[4]; break;
                                    case "t":
                                        n = f + t[1], s = d + t[2], null === c[0].match(/[QqTt]/) ? (g = f, p = d) : (g = 2 * f - g, p = 2 * d - p), o = e.util.getBoundsOfCurve(f, d, g, p, g, p, n, s), f = n, d = s; break;
                                    case "T":
                                        n = t[1], s = t[2], null === c[0].match(/[QqTt]/) ? (g = f, p = d) : (g = 2 * f - g, p = 2 * d - p), o = e.util.getBoundsOfCurve(f, d, g, p, g, p, n, s), f = n, d = s; break;
                                    case "a":
                                        o = e.util.getBoundsOfArc(f, d, t[1], t[2], t[3], t[4], t[5], t[6] + f, t[7] + d), f += t[6], d += t[7]; break;
                                    case "A":
                                        o = e.util.getBoundsOfArc(f, d, t[1], t[2], t[3], t[4], t[5], t[6], t[7]), f = t[6], d = t[7]; break;
                                    case "z":
                                    case "Z":
                                        f = l, d = u } c = t, o.forEach(function(t) { a.push(t.x), h.push(t.y) }), a.push(f), h.push(d) } var _ = i(a) || 0,
                                y = i(h) || 0; return { left: _, top: y, width: (r(a) || 0) - _, height: (r(h) || 0) - y } } }), e.Path.fromObject = function(t, i) { if ("string" == typeof t.sourcePath) { var r = t.sourcePath;
                            e.loadSVGFromURL(r, function(e) { var r = e[0];
                                r.setOptions(t), i && i(r) }) } else e.Object._fromObject("Path", t, i, "path") }, e.Path.ATTRIBUTE_NAMES = e.SHARED_ATTRIBUTES.concat(["d"]), e.Path.fromElement = function(t, i, r) { var s = e.parseAttributes(t, e.Path.ATTRIBUTE_NAMES);
                        s.fromSVG = !0, i(new e.Path(s.d, n(s, r))) }) }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.util.array.min,
                        r = e.util.array.max;
                    e.Group || (e.Group = e.util.createClass(e.Object, e.Collection, { type: "group", strokeWidth: 0, subTargetCheck: !1, cacheProperties: [], useSetOnGroup: !1, initialize: function(t, e, i) { e = e || {}, this._objects = [], i && this.callSuper("initialize", e), this._objects = t || []; for (var r = this._objects.length; r--;) this._objects[r].group = this; if (i) this._updateObjectsACoords();
                            else { var n = e && e.centerPoint;
                                void 0 !== e.originX && (this.originX = e.originX), void 0 !== e.originY && (this.originY = e.originY), n || this._calcBounds(), this._updateObjectsCoords(n), delete e.centerPoint, this.callSuper("initialize", e) } this.setCoords() }, _updateObjectsACoords: function() { for (var t = this._objects.length; t--;) this._objects[t].setCoords(!0, !0) }, _updateObjectsCoords: function(t) { t = t || this.getCenterPoint(); for (var e = this._objects.length; e--;) this._updateObjectCoords(this._objects[e], t) }, _updateObjectCoords: function(t, e) { var i = t.left,
                                r = t.top;
                            t.set({ left: i - e.x, top: r - e.y }), t.group = this, t.setCoords(!0, !0) }, toString: function() { return "#<fabric.Group: (" + this.complexity() + ")>" }, addWithUpdate: function(t) { return this._restoreObjectsState(), e.util.resetObjectTransform(this), t && (this._objects.push(t), t.group = this, t._set("canvas", this.canvas)), this._calcBounds(), this._updateObjectsCoords(), this.setCoords(), this.dirty = !0, this }, removeWithUpdate: function(t) { return this._restoreObjectsState(), e.util.resetObjectTransform(this), this.remove(t), this._calcBounds(), this._updateObjectsCoords(), this.setCoords(), this.dirty = !0, this }, _onObjectAdded: function(t) { this.dirty = !0, t.group = this, t._set("canvas", this.canvas) }, _onObjectRemoved: function(t) { this.dirty = !0, delete t.group }, _set: function(t, i) { var r = this._objects.length; if (this.useSetOnGroup)
                                for (; r--;) this._objects[r].setOnGroup(t, i); if ("canvas" === t)
                                for (; r--;) this._objects[r]._set(t, i);
                            e.Object.prototype._set.call(this, t, i) }, toObject: function(t) { var i = this.includeDefaultValues,
                                r = this._objects.map(function(e) { var r = e.includeDefaultValues;
                                    e.includeDefaultValues = i; var n = e.toObject(t); return e.includeDefaultValues = r, n }),
                                n = e.Object.prototype.toObject.call(this, t); return n.objects = r, n }, toDatalessObject: function(t) { var i, r = this.sourcePath; if (r) i = r;
                            else { var n = this.includeDefaultValues;
                                i = this._objects.map(function(e) { var i = e.includeDefaultValues;
                                    e.includeDefaultValues = n; var r = e.toDatalessObject(t); return e.includeDefaultValues = i, r }) } var s = e.Object.prototype.toDatalessObject.call(this, t); return s.objects = i, s }, render: function(t) { this._transformDone = !0, this.callSuper("render", t), this._transformDone = !1 }, shouldCache: function() { var t = e.Object.prototype.shouldCache.call(this); if (t)
                                for (var i = 0, r = this._objects.length; i < r; i++)
                                    if (this._objects[i].willDrawShadow()) return this.ownCaching = !1, !1; return t }, willDrawShadow: function() { if (this.shadow) return e.Object.prototype.willDrawShadow.call(this); for (var t = 0, i = this._objects.length; t < i; t++)
                                if (this._objects[t].willDrawShadow()) return !0; return !1 }, isOnACache: function() { return this.ownCaching || this.group && this.group.isOnACache() }, drawObject: function(t) { for (var e = 0, i = this._objects.length; e < i; e++) this._objects[e].render(t);
                            this._drawClipPath(t) }, isCacheDirty: function(t) { if (this.callSuper("isCacheDirty", t)) return !0; if (!this.statefullCache) return !1; for (var e = 0, i = this._objects.length; e < i; e++)
                                if (this._objects[e].isCacheDirty(!0)) { if (this._cacheCanvas) { var r = this.cacheWidth / this.zoomX,
                                            n = this.cacheHeight / this.zoomY;
                                        this._cacheContext.clearRect(-r / 2, -n / 2, r, n) } return !0 } return !1 }, _restoreObjectsState: function() { return this._objects.forEach(this._restoreObjectState, this), this }, realizeTransform: function(t) { var i = t.calcTransformMatrix(),
                                r = e.util.qrDecompose(i),
                                n = new e.Point(r.translateX, r.translateY); return t.flipX = !1, t.flipY = !1, t.set("scaleX", r.scaleX), t.set("scaleY", r.scaleY), t.skewX = r.skewX, t.skewY = r.skewY, t.angle = r.angle, t.setPositionByOrigin(n, "center", "center"), t }, _restoreObjectState: function(t) { return this.realizeTransform(t), t.setCoords(), delete t.group, this }, destroy: function() { return this._objects.forEach(function(t) { t.set("dirty", !0) }), this._restoreObjectsState() }, toActiveSelection: function() { if (this.canvas) { var t = this._objects,
                                    i = this.canvas;
                                this._objects = []; var r = this.toObject();
                                delete r.objects; var n = new e.ActiveSelection([]); return n.set(r), n.type = "activeSelection", i.remove(this), t.forEach(function(t) { t.group = n, t.dirty = !0, i.add(t) }), n.canvas = i, n._objects = t, i._activeObject = n, n.setCoords(), n } }, ungroupOnCanvas: function() { return this._restoreObjectsState() }, setObjectsCoords: function() { return this.forEachObject(function(t) { t.setCoords(!0, !0) }), this }, _calcBounds: function(t) { for (var e, i, r, n = [], s = [], o = ["tr", "br", "bl", "tl"], a = 0, h = this._objects.length, c = o.length; a < h; ++a)
                                for ((e = this._objects[a]).setCoords(!0), r = 0; r < c; r++) i = o[r], n.push(e.oCoords[i].x), s.push(e.oCoords[i].y);
                            this._getBounds(n, s, t) }, _getBounds: function(t, n, s) { var o = new e.Point(i(t), i(n)),
                                a = new e.Point(r(t), r(n)),
                                h = o.y || 0,
                                c = o.x || 0,
                                l = a.x - o.x || 0,
                                u = a.y - o.y || 0;
                            this.width = l, this.height = u, s || this.setPositionByOrigin({ x: c, y: h }, "left", "top") }, _toSVG: function(t) { for (var e = ["<g ", "COMMON_PARTS", " >\n"], i = 0, r = this._objects.length; i < r; i++) e.push("\t\t", this._objects[i].toSVG(t)); return e.push("</g>\n"), e }, getSvgStyles: function() { var t = void 0 !== this.opacity && 1 !== this.opacity ? "opacity: " + this.opacity + ";" : "",
                                e = this.visible ? "" : " visibility: hidden;"; return [t, this.getSvgFilter(), e].join("") }, toClipPathSVG: function(t) { for (var e = [], i = 0, r = this._objects.length; i < r; i++) e.push("\t", this._objects[i].toClipPathSVG(t)); return this._createBaseClipPathSVGMarkup(e, { reviver: t }) } }), e.Group.fromObject = function(t, i) { e.util.enlivenObjects(t.objects, function(r) { e.util.enlivenObjects([t.clipPath], function(n) { var s = e.util.object.clone(t, !0);
                                s.clipPath = n[0], delete s.objects, i && i(new e.Group(r, s, !0)) }) }) }) }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {});
                    e.ActiveSelection || (e.ActiveSelection = e.util.createClass(e.Group, { type: "activeSelection", initialize: function(t, i) { i = i || {}, this._objects = t || []; for (var r = this._objects.length; r--;) this._objects[r].group = this;
                            i.originX && (this.originX = i.originX), i.originY && (this.originY = i.originY), this._calcBounds(), this._updateObjectsCoords(), e.Object.prototype.initialize.call(this, i), this.setCoords() }, toGroup: function() { var t = this._objects.concat();
                            this._objects = []; var i = e.Object.prototype.toObject.call(this),
                                r = new e.Group([]); if (delete i.type, r.set(i), t.forEach(function(t) { t.canvas.remove(t), t.group = r }), r._objects = t, !this.canvas) return r; var n = this.canvas; return n.add(r), n._activeObject = r, r.setCoords(), r }, onDeselect: function() { return this.destroy(), !1 }, toString: function() { return "#<fabric.ActiveSelection: (" + this.complexity() + ")>" }, shouldCache: function() { return !1 }, isOnACache: function() { return !1 }, _renderControls: function(t, e, i) { t.save(), t.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1, this.callSuper("_renderControls", t, e), void 0 === (i = i || {}).hasControls && (i.hasControls = !1), void 0 === i.hasRotatingPoint && (i.hasRotatingPoint = !1), i.forActiveSelection = !0; for (var r = 0, n = this._objects.length; r < n; r++) this._objects[r]._renderControls(t, i);
                            t.restore() } }), e.ActiveSelection.fromObject = function(t, i) { e.util.enlivenObjects(t.objects, function(r) { delete t.objects, i && i(new e.ActiveSelection(r, t, !0)) }) }) }(e),
                function(t) { "use strict"; var e = r.util.object.extend;
                    t.fabric || (t.fabric = {}), t.fabric.Image ? r.warn("fabric.Image is already defined.") : (r.Image = r.util.createClass(r.Object, { type: "image", crossOrigin: "", strokeWidth: 0, srcFromAttribute: !1, _lastScaleX: 1, _lastScaleY: 1, _filterScalingX: 1, _filterScalingY: 1, minimumScaleTrigger: .5, stateProperties: r.Object.prototype.stateProperties.concat("cropX", "cropY"), cacheKey: "", cropX: 0, cropY: 0, initialize: function(t, e) { e || (e = {}), this.filters = [], this.cacheKey = "texture" + r.Object.__uid++, this.callSuper("initialize", e), this._initElement(t, e) }, getElement: function() { return this._element || {} }, setElement: function(t, e) { return this.removeTexture(this.cacheKey), this.removeTexture(this.cacheKey + "_filtered"), this._element = t, this._originalElement = t, this._initConfig(e), 0 !== this.filters.length && this.applyFilters(), this.resizeFilter && this.applyResizeFilters(), this }, removeTexture: function(t) { var e = r.filterBackend;
                            e && e.evictCachesForKey && e.evictCachesForKey(t) }, dispose: function() { this.removeTexture(this.cacheKey), this.removeTexture(this.cacheKey + "_filtered"), this._cacheContext = void 0, ["_originalElement", "_element", "_filteredEl", "_cacheCanvas"].forEach(function(t) { r.util.cleanUpJsdomNode(this[t]), this[t] = void 0 }.bind(this)) }, setCrossOrigin: function(t) { return this.crossOrigin = t, this._element.crossOrigin = t, this }, getOriginalSize: function() { var t = this.getElement(); return { width: t.naturalWidth || t.width, height: t.naturalHeight || t.height } }, _stroke: function(t) { if (this.stroke && 0 !== this.strokeWidth) { var e = this.width / 2,
                                    i = this.height / 2;
                                t.beginPath(), t.moveTo(-e, -i), t.lineTo(e, -i), t.lineTo(e, i), t.lineTo(-e, i), t.lineTo(-e, -i), t.closePath() } }, _renderDashedStroke: function(t) { var e = -this.width / 2,
                                i = -this.height / 2,
                                n = this.width,
                                s = this.height;
                            t.save(), this._setStrokeStyles(t, this), t.beginPath(), r.util.drawDashedLine(t, e, i, e + n, i, this.strokeDashArray), r.util.drawDashedLine(t, e + n, i, e + n, i + s, this.strokeDashArray), r.util.drawDashedLine(t, e + n, i + s, e, i + s, this.strokeDashArray), r.util.drawDashedLine(t, e, i + s, e, i, this.strokeDashArray), t.closePath(), t.restore() }, toObject: function(t) { var i = [];
                            this.filters.forEach(function(t) { t && i.push(t.toObject()) }); var r = e(this.callSuper("toObject", ["crossOrigin", "cropX", "cropY"].concat(t)), { src: this.getSrc(), filters: i }); return this.resizeFilter && (r.resizeFilter = this.resizeFilter.toObject()), r }, hasCrop: function() { return this.cropX || this.cropY || this.width < this._element.width || this.height < this._element.height }, _toSVG: function() { var t, e = [],
                                i = [],
                                n = -this.width / 2,
                                s = -this.height / 2,
                                o = ""; if (this.hasCrop()) { var a = r.Object.__uid++;
                                e.push('<clipPath id="imageCrop_' + a + '">\n', '\t<rect x="' + n + '" y="' + s + '" width="' + this.width + '" height="' + this.height + '" />\n', "</clipPath>\n"), o = ' clip-path="url(#imageCrop_' + a + ')" ' } if (i.push("\t<image ", "COMMON_PARTS", 'xlink:href="', this.getSvgSrc(!0), '" x="', n - this.cropX, '" y="', s - this.cropY, '" width="', this._element.width || this._element.naturalWidth, '" height="', this._element.height || this._element.height, '"', o, "></image>\n"), this.stroke || this.strokeDashArray) { var h = this.fill;
                                this.fill = null, t = ["\t<rect ", 'x="', n, '" y="', s, '" width="', this.width, '" height="', this.height, '" style="', this.getSvgStyles(), '"/>\n'], this.fill = h } return e = "fill" !== this.paintFirst ? e.concat(t, i) : e.concat(i, t) }, getSrc: function(t) { var e = t ? this._element : this._originalElement; return e ? e.toDataURL ? e.toDataURL() : this.srcFromAttribute ? e.getAttribute("src") : e.src : this.src || "" }, setSrc: function(t, e, i) { return r.util.loadImage(t, function(t) { this.setElement(t, i), this._setWidthHeight(), e && e(this) }, this, i && i.crossOrigin), this }, toString: function() { return '#<fabric.Image: { src: "' + this.getSrc() + '" }>' }, applyResizeFilters: function() { var t = this.resizeFilter,
                                e = this.minimumScaleTrigger,
                                i = this.getTotalObjectScaling(),
                                n = i.scaleX,
                                s = i.scaleY,
                                o = this._filteredEl || this._originalElement; if (this.group && this.set("dirty", !0), !t || n > e && s > e) return this._element = o, this._filterScalingX = 1, this._filterScalingY = 1, this._lastScaleX = n, void(this._lastScaleY = s);
                            r.filterBackend || (r.filterBackend = r.initFilterBackend()); var a = r.util.createCanvasElement(),
                                h = this._filteredEl ? this.cacheKey + "_filtered" : this.cacheKey,
                                c = o.width,
                                l = o.height;
                            a.width = c, a.height = l, this._element = a, this._lastScaleX = t.scaleX = n, this._lastScaleY = t.scaleY = s, r.filterBackend.applyFilters([t], o, c, l, this._element, h), this._filterScalingX = a.width / this._originalElement.width, this._filterScalingY = a.height / this._originalElement.height }, applyFilters: function(t) { if (t = (t = t || this.filters || []).filter(function(t) { return t && !t.isNeutralState() }), this.set("dirty", !0), this.removeTexture(this.cacheKey + "_filtered"), 0 === t.length) return this._element = this._originalElement, this._filteredEl = null, this._filterScalingX = 1, this._filterScalingY = 1, this; var e = this._originalElement,
                                i = e.naturalWidth || e.width,
                                n = e.naturalHeight || e.height; if (this._element === this._originalElement) { var s = r.util.createCanvasElement();
                                s.width = i, s.height = n, this._element = s, this._filteredEl = s } else this._element = this._filteredEl, this._filteredEl.getContext("2d").clearRect(0, 0, i, n), this._lastScaleX = 1, this._lastScaleY = 1; return r.filterBackend || (r.filterBackend = r.initFilterBackend()), r.filterBackend.applyFilters(t, this._originalElement, i, n, this._element, this.cacheKey), this._originalElement.width === this._element.width && this._originalElement.height === this._element.height || (this._filterScalingX = this._element.width / this._originalElement.width, this._filterScalingY = this._element.height / this._originalElement.height), this }, _render: function(t) {!0 !== this.isMoving && this.resizeFilter && this._needsResize() && this.applyResizeFilters(), this._stroke(t), this._renderPaintInOrder(t) }, shouldCache: function() { return this.needsItsOwnCache() }, _renderFill: function(t) { var e = this._element,
                                i = this.width,
                                r = this.height,
                                n = Math.min(e.naturalWidth || e.width, i * this._filterScalingX),
                                s = Math.min(e.naturalHeight || e.height, r * this._filterScalingY),
                                o = -i / 2,
                                a = -r / 2,
                                h = Math.max(0, this.cropX * this._filterScalingX),
                                c = Math.max(0, this.cropY * this._filterScalingY);
                            e && t.drawImage(e, h, c, n, s, o, a, i, r) }, _needsResize: function() { var t = this.getTotalObjectScaling(); return t.scaleX !== this._lastScaleX || t.scaleY !== this._lastScaleY }, _resetWidthHeight: function() { this.set(this.getOriginalSize()) }, _initElement: function(t, e) { this.setElement(r.util.getById(t), e), r.util.addClass(this.getElement(), r.Image.CSS_CANVAS) }, _initConfig: function(t) { t || (t = {}), this.setOptions(t), this._setWidthHeight(t), this._element && this.crossOrigin && (this._element.crossOrigin = this.crossOrigin) }, _initFilters: function(t, e) { t && t.length ? r.util.enlivenObjects(t, function(t) { e && e(t) }, "fabric.Image.filters") : e && e() }, _setWidthHeight: function(t) { t || (t = {}); var e = this.getElement();
                            this.width = t.width || e.naturalWidth || e.width || 0, this.height = t.height || e.naturalHeight || e.height || 0 }, parsePreserveAspectRatioAttribute: function() { var t, e = r.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio || ""),
                                i = this._element.width,
                                n = this._element.height,
                                s = 1,
                                o = 1,
                                a = 0,
                                h = 0,
                                c = 0,
                                l = 0,
                                u = this.width,
                                f = this.height,
                                d = { width: u, height: f }; return !e || "none" === e.alignX && "none" === e.alignY ? (s = u / i, o = f / n) : ("meet" === e.meetOrSlice && (t = (u - i * (s = o = r.util.findScaleToFit(this._element, d))) / 2, "Min" === e.alignX && (a = -t), "Max" === e.alignX && (a = t), t = (f - n * o) / 2, "Min" === e.alignY && (h = -t), "Max" === e.alignY && (h = t)), "slice" === e.meetOrSlice && (t = i - u / (s = o = r.util.findScaleToCover(this._element, d)), "Mid" === e.alignX && (c = t / 2), "Max" === e.alignX && (c = t), t = n - f / o, "Mid" === e.alignY && (l = t / 2), "Max" === e.alignY && (l = t), i = u / s, n = f / o)), { width: i, height: n, scaleX: s, scaleY: o, offsetLeft: a, offsetTop: h, cropX: c, cropY: l } } }), r.Image.CSS_CANVAS = "canvas-img", r.Image.prototype.getSvgSrc = r.Image.prototype.getSrc, r.Image.fromObject = function(t, e) { var i = r.util.object.clone(t);
                        r.util.loadImage(i.src, function(t, n) { n ? e && e(null, n) : r.Image.prototype._initFilters.call(i, i.filters, function(n) { i.filters = n || [], r.Image.prototype._initFilters.call(i, [i.resizeFilter], function(n) { i.resizeFilter = n[0], r.util.enlivenObjects([i.clipPath], function(n) { i.clipPath = n[0]; var s = new r.Image(t, i);
                                        e(s) }) }) }) }, null, i.crossOrigin) }, r.Image.fromURL = function(t, e, i) { r.util.loadImage(t, function(t) { e && e(new r.Image(t, i)) }, null, i && i.crossOrigin) }, r.Image.ATTRIBUTE_NAMES = r.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href crossOrigin".split(" ")), r.Image.fromElement = function(t, i, n) { var s = r.parseAttributes(t, r.Image.ATTRIBUTE_NAMES);
                        r.Image.fromURL(s["xlink:href"], i, e(n ? r.util.object.clone(n) : {}, s)) }) }(e), r.util.object.extend(r.Object.prototype, { _getAngleValueForStraighten: function() { var t = this.angle % 360; return t > 0 ? 90 * Math.round((t - 1) / 90) : 90 * Math.round(t / 90) }, straighten: function() { return this.rotate(this._getAngleValueForStraighten()), this }, fxStraighten: function(t) { var e = function() {},
                            i = (t = t || {}).onComplete || e,
                            n = t.onChange || e,
                            s = this; return r.util.animate({ startValue: this.get("angle"), endValue: this._getAngleValueForStraighten(), duration: this.FX_DURATION, onChange: function(t) { s.rotate(t), n() }, onComplete: function() { s.setCoords(), i() } }), this } }), r.util.object.extend(r.StaticCanvas.prototype, { straightenObject: function(t) { return t.straighten(), this.requestRenderAll(), this }, fxStraightenObject: function(t) { return t.fxStraighten({ onChange: this.requestRenderAllBound }), this } }),
                function() { "use strict";

                    function t(t, e) { var i = "precision " + e + " float;\nvoid main(){}",
                            r = t.createShader(t.FRAGMENT_SHADER); return t.shaderSource(r, i), t.compileShader(r), !!t.getShaderParameter(r, t.COMPILE_STATUS) }

                    function e(t) { t && t.tileSize && (this.tileSize = t.tileSize), this.setupGLContext(this.tileSize, this.tileSize), this.captureGPUInfo() } r.isWebglSupported = function(e) { if (r.isLikelyNode) return !1;
                        e = e || r.WebglFilterBackend.prototype.tileSize; var i = document.createElement("canvas"),
                            n = i.getContext("webgl") || i.getContext("experimental-webgl"),
                            s = !1; if (n) { r.maxTextureSize = n.getParameter(n.MAX_TEXTURE_SIZE), s = r.maxTextureSize >= e; for (var o = ["highp", "mediump", "lowp"], a = 0; a < 3; a++)
                                if (t(n, o[a])) { r.webGlPrecision = o[a]; break } } return this.isSupported = s, s }, r.WebglFilterBackend = e, e.prototype = { tileSize: 2048, resources: {}, setupGLContext: function(t, e) { this.dispose(), this.createWebGLCanvas(t, e), this.aPosition = new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]), this.chooseFastestCopyGLTo2DMethod(t, e) }, chooseFastestCopyGLTo2DMethod: function(t, e) { var i, n = void 0 !== window.performance; try { new ImageData(1, 1), i = !0 } catch (t) { i = !1 } var a = "undefined" != typeof ArrayBuffer,
                                h = "undefined" != typeof Uint8ClampedArray; if (n && i && a && h) { var c = r.util.createCanvasElement(),
                                    l = new ArrayBuffer(t * e * 4); if (r.forceGLPutImageData) return this.imageBuffer = l, void(this.copyGLTo2D = o); var u, f, d = { imageBuffer: l, destinationWidth: t, destinationHeight: e, targetCanvas: c };
                                c.width = t, c.height = e, u = window.performance.now(), s.call(d, this.gl, d), f = window.performance.now() - u, u = window.performance.now(), o.call(d, this.gl, d), f > window.performance.now() - u ? (this.imageBuffer = l, this.copyGLTo2D = o) : this.copyGLTo2D = s } }, createWebGLCanvas: function(t, e) { var i = r.util.createCanvasElement();
                            i.width = t, i.height = e; var n = { alpha: !0, premultipliedAlpha: !1, depth: !1, stencil: !1, antialias: !1 },
                                s = i.getContext("webgl", n);
                            s || (s = i.getContext("experimental-webgl", n)), s && (s.clearColor(0, 0, 0, 0), this.canvas = i, this.gl = s) }, applyFilters: function(t, e, i, r, n, s) { var o, a = this.gl;
                            s && (o = this.getCachedTexture(s, e)); var h = { originalWidth: e.width || e.originalWidth, originalHeight: e.height || e.originalHeight, sourceWidth: i, sourceHeight: r, destinationWidth: i, destinationHeight: r, context: a, sourceTexture: this.createTexture(a, i, r, !o && e), targetTexture: this.createTexture(a, i, r), originalTexture: o || this.createTexture(a, i, r, !o && e), passes: t.length, webgl: !0, aPosition: this.aPosition, programCache: this.programCache, pass: 0, filterBackend: this, targetCanvas: n },
                                c = a.createFramebuffer(); return a.bindFramebuffer(a.FRAMEBUFFER, c), t.forEach(function(t) { t && t.applyTo(h) }),
                                function(t) { var e = t.targetCanvas,
                                        i = e.width,
                                        r = e.height,
                                        n = t.destinationWidth,
                                        s = t.destinationHeight;
                                    i === n && r === s || (e.width = n, e.height = s) }(h), this.copyGLTo2D(a, h), a.bindTexture(a.TEXTURE_2D, null), a.deleteTexture(h.sourceTexture), a.deleteTexture(h.targetTexture), a.deleteFramebuffer(c), n.getContext("2d").setTransform(1, 0, 0, 1, 0, 0), h }, dispose: function() { this.canvas && (this.canvas = null, this.gl = null), this.clearWebGLCaches() }, clearWebGLCaches: function() { this.programCache = {}, this.textureCache = {} }, createTexture: function(t, e, i, r) { var n = t.createTexture(); return t.bindTexture(t.TEXTURE_2D, n), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MAG_FILTER, t.NEAREST), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MIN_FILTER, t.NEAREST), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_S, t.CLAMP_TO_EDGE), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_T, t.CLAMP_TO_EDGE), r ? t.texImage2D(t.TEXTURE_2D, 0, t.RGBA, t.RGBA, t.UNSIGNED_BYTE, r) : t.texImage2D(t.TEXTURE_2D, 0, t.RGBA, e, i, 0, t.RGBA, t.UNSIGNED_BYTE, null), n }, getCachedTexture: function(t, e) { if (this.textureCache[t]) return this.textureCache[t]; var i = this.createTexture(this.gl, e.width, e.height, e); return this.textureCache[t] = i, i }, evictCachesForKey: function(t) { this.textureCache[t] && (this.gl.deleteTexture(this.textureCache[t]), delete this.textureCache[t]) }, copyGLTo2D: s, captureGPUInfo: function() { if (this.gpuInfo) return this.gpuInfo; var t = this.gl,
                                e = { renderer: "", vendor: "" }; if (!t) return e; var i = t.getExtension("WEBGL_debug_renderer_info"); if (i) { var r = t.getParameter(i.UNMASKED_RENDERER_WEBGL),
                                    n = t.getParameter(i.UNMASKED_VENDOR_WEBGL);
                                r && (e.renderer = r.toLowerCase()), n && (e.vendor = n.toLowerCase()) } return this.gpuInfo = e, e } } }(),
                function() { "use strict"; var t = function() {};

                    function e() {} r.Canvas2dFilterBackend = e, e.prototype = { evictCachesForKey: t, dispose: t, clearWebGLCaches: t, resources: {}, applyFilters: function(t, e, i, r, n) { var s = n.getContext("2d");
                            s.drawImage(e, 0, 0, i, r); var o = { sourceWidth: i, sourceHeight: r, imageData: s.getImageData(0, 0, i, r), originalEl: e, originalImageData: s.getImageData(0, 0, i, r), canvasEl: n, ctx: s, filterBackend: this }; return t.forEach(function(t) { t.applyTo(o) }), o.imageData.width === i && o.imageData.height === r || (n.width = o.imageData.width, n.height = o.imageData.height), s.putImageData(o.imageData, 0, 0), o } } }(), r.Image = r.Image || {}, r.Image.filters = r.Image.filters || {}, r.Image.filters.BaseFilter = r.util.createClass({ type: "BaseFilter", vertexSource: "attribute vec2 aPosition;\nvarying vec2 vTexCoord;\nvoid main() {\nvTexCoord = aPosition;\ngl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n}", fragmentSource: "precision highp float;\nvarying vec2 vTexCoord;\nuniform sampler2D uTexture;\nvoid main() {\ngl_FragColor = texture2D(uTexture, vTexCoord);\n}", initialize: function(t) { t && this.setOptions(t) }, setOptions: function(t) { for (var e in t) this[e] = t[e] }, createProgram: function(t, e, i) { e = e || this.fragmentSource, i = i || this.vertexSource, "highp" !== r.webGlPrecision && (e = e.replace(/precision highp float/g, "precision " + r.webGlPrecision + " float")); var n = t.createShader(t.VERTEX_SHADER); if (t.shaderSource(n, i), t.compileShader(n), !t.getShaderParameter(n, t.COMPILE_STATUS)) throw new Error("Vertex shader compile error for " + this.type + ": " + t.getShaderInfoLog(n)); var s = t.createShader(t.FRAGMENT_SHADER); if (t.shaderSource(s, e), t.compileShader(s), !t.getShaderParameter(s, t.COMPILE_STATUS)) throw new Error("Fragment shader compile error for " + this.type + ": " + t.getShaderInfoLog(s)); var o = t.createProgram(); if (t.attachShader(o, n), t.attachShader(o, s), t.linkProgram(o), !t.getProgramParameter(o, t.LINK_STATUS)) throw new Error('Shader link error for "${this.type}" ' + t.getProgramInfoLog(o)); var a = this.getAttributeLocations(t, o),
                            h = this.getUniformLocations(t, o) || {}; return h.uStepW = t.getUniformLocation(o, "uStepW"), h.uStepH = t.getUniformLocation(o, "uStepH"), { program: o, attributeLocations: a, uniformLocations: h } }, getAttributeLocations: function(t, e) { return { aPosition: t.getAttribLocation(e, "aPosition") } }, getUniformLocations: function() { return {} }, sendAttributeData: function(t, e, i) { var r = e.aPosition,
                            n = t.createBuffer();
                        t.bindBuffer(t.ARRAY_BUFFER, n), t.enableVertexAttribArray(r), t.vertexAttribPointer(r, 2, t.FLOAT, !1, 0, 0), t.bufferData(t.ARRAY_BUFFER, i, t.STATIC_DRAW) }, _setupFrameBuffer: function(t) { var e, i, r = t.context;
                        t.passes > 1 ? (e = t.destinationWidth, i = t.destinationHeight, t.sourceWidth === e && t.sourceHeight === i || (r.deleteTexture(t.targetTexture), t.targetTexture = t.filterBackend.createTexture(r, e, i)), r.framebufferTexture2D(r.FRAMEBUFFER, r.COLOR_ATTACHMENT0, r.TEXTURE_2D, t.targetTexture, 0)) : (r.bindFramebuffer(r.FRAMEBUFFER, null), r.finish()) }, _swapTextures: function(t) { t.passes--, t.pass++; var e = t.targetTexture;
                        t.targetTexture = t.sourceTexture, t.sourceTexture = e }, isNeutralState: function() { var t = this.mainParameter,
                            e = r.Image.filters[this.type].prototype; if (t) { if (Array.isArray(e[t])) { for (var i = e[t].length; i--;)
                                    if (this[t][i] !== e[t][i]) return !1; return !0 } return e[t] === this[t] } return !1 }, applyTo: function(t) { t.webgl ? (this._setupFrameBuffer(t), this.applyToWebGL(t), this._swapTextures(t)) : this.applyTo2d(t) }, retrieveShader: function(t) { return t.programCache.hasOwnProperty(this.type) || (t.programCache[this.type] = this.createProgram(t.context)), t.programCache[this.type] }, applyToWebGL: function(t) { var e = t.context,
                            i = this.retrieveShader(t);
                        0 === t.pass && t.originalTexture ? e.bindTexture(e.TEXTURE_2D, t.originalTexture) : e.bindTexture(e.TEXTURE_2D, t.sourceTexture), e.useProgram(i.program), this.sendAttributeData(e, i.attributeLocations, t.aPosition), e.uniform1f(i.uniformLocations.uStepW, 1 / t.sourceWidth), e.uniform1f(i.uniformLocations.uStepH, 1 / t.sourceHeight), this.sendUniformData(e, i.uniformLocations), e.viewport(0, 0, t.destinationWidth, t.destinationHeight), e.drawArrays(e.TRIANGLE_STRIP, 0, 4) }, bindAdditionalTexture: function(t, e, i) { t.activeTexture(i), t.bindTexture(t.TEXTURE_2D, e), t.activeTexture(t.TEXTURE0) }, unbindAdditionalTexture: function(t, e) { t.activeTexture(e), t.bindTexture(t.TEXTURE_2D, null), t.activeTexture(t.TEXTURE0) }, getMainParameter: function() { return this[this.mainParameter] }, setMainParameter: function(t) { this[this.mainParameter] = t }, sendUniformData: function() {}, createHelpLayer: function(t) { if (!t.helpLayer) { var e = document.createElement("canvas");
                            e.width = t.sourceWidth, e.height = t.sourceHeight, t.helpLayer = e } }, toObject: function() { var t = { type: this.type },
                            e = this.mainParameter; return e && (t[e] = this[e]), t }, toJSON: function() { return this.toObject() } }), r.Image.filters.BaseFilter.fromObject = function(t, e) { var i = new r.Image.filters[t.type](t); return e && e(i), i },
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.Image.filters,
                        r = e.util.createClass;
                    i.ColorMatrix = r(i.BaseFilter, { type: "ColorMatrix", fragmentSource: "precision highp float;\nuniform sampler2D uTexture;\nvarying vec2 vTexCoord;\nuniform mat4 uColorMatrix;\nuniform vec4 uConstants;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\ncolor *= uColorMatrix;\ncolor += uConstants;\ngl_FragColor = color;\n}", matrix: [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0], mainParameter: "matrix", colorsOnly: !0, initialize: function(t) { this.callSuper("initialize", t), this.matrix = this.matrix.slice(0) }, applyTo2d: function(t) { var e, i, r, n, s, o = t.imageData.data,
                                a = o.length,
                                h = this.matrix,
                                c = this.colorsOnly; for (s = 0; s < a; s += 4) e = o[s], i = o[s + 1], r = o[s + 2], c ? (o[s] = e * h[0] + i * h[1] + r * h[2] + 255 * h[4], o[s + 1] = e * h[5] + i * h[6] + r * h[7] + 255 * h[9], o[s + 2] = e * h[10] + i * h[11] + r * h[12] + 255 * h[14]) : (n = o[s + 3], o[s] = e * h[0] + i * h[1] + r * h[2] + n * h[3] + 255 * h[4], o[s + 1] = e * h[5] + i * h[6] + r * h[7] + n * h[8] + 255 * h[9], o[s + 2] = e * h[10] + i * h[11] + r * h[12] + n * h[13] + 255 * h[14], o[s + 3] = e * h[15] + i * h[16] + r * h[17] + n * h[18] + 255 * h[19]) }, getUniformLocations: function(t, e) { return { uColorMatrix: t.getUniformLocation(e, "uColorMatrix"), uConstants: t.getUniformLocation(e, "uConstants") } }, sendUniformData: function(t, e) { var i = this.matrix,
                                r = [i[0], i[1], i[2], i[3], i[5], i[6], i[7], i[8], i[10], i[11], i[12], i[13], i[15], i[16], i[17], i[18]],
                                n = [i[4], i[9], i[14], i[19]];
                            t.uniformMatrix4fv(e.uColorMatrix, !1, r), t.uniform4fv(e.uConstants, n) } }), e.Image.filters.ColorMatrix.fromObject = e.Image.filters.BaseFilter.fromObject }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.Image.filters,
                        r = e.util.createClass;
                    i.Brightness = r(i.BaseFilter, { type: "Brightness", fragmentSource: "precision highp float;\nuniform sampler2D uTexture;\nuniform float uBrightness;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\ncolor.rgb += uBrightness;\ngl_FragColor = color;\n}", brightness: 0, mainParameter: "brightness", applyTo2d: function(t) { if (0 !== this.brightness) { var e, i = t.imageData.data,
                                    r = i.length,
                                    n = Math.round(255 * this.brightness); for (e = 0; e < r; e += 4) i[e] = i[e] + n, i[e + 1] = i[e + 1] + n, i[e + 2] = i[e + 2] + n } }, getUniformLocations: function(t, e) { return { uBrightness: t.getUniformLocation(e, "uBrightness") } }, sendUniformData: function(t, e) { t.uniform1f(e.uBrightness, this.brightness) } }), e.Image.filters.Brightness.fromObject = e.Image.filters.BaseFilter.fromObject }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.util.object.extend,
                        r = e.Image.filters,
                        n = e.util.createClass;
                    r.Convolute = n(r.BaseFilter, { type: "Convolute", opaque: !1, matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0], fragmentSource: { Convolute_3_1: "precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[9];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 0);\nfor (float h = 0.0; h < 3.0; h+=1.0) {\nfor (float w = 0.0; w < 3.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\ncolor += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\n}\n}\ngl_FragColor = color;\n}", Convolute_3_0: "precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[9];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 1);\nfor (float h = 0.0; h < 3.0; h+=1.0) {\nfor (float w = 0.0; w < 3.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\ncolor.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\n}\n}\nfloat alpha = texture2D(uTexture, vTexCoord).a;\ngl_FragColor = color;\ngl_FragColor.a = alpha;\n}", Convolute_5_1: "precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[25];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 0);\nfor (float h = 0.0; h < 5.0; h+=1.0) {\nfor (float w = 0.0; w < 5.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\ncolor += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\n}\n}\ngl_FragColor = color;\n}", Convolute_5_0: "precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[25];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 1);\nfor (float h = 0.0; h < 5.0; h+=1.0) {\nfor (float w = 0.0; w < 5.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\ncolor.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\n}\n}\nfloat alpha = texture2D(uTexture, vTexCoord).a;\ngl_FragColor = color;\ngl_FragColor.a = alpha;\n}", Convolute_7_1: "precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[49];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 0);\nfor (float h = 0.0; h < 7.0; h+=1.0) {\nfor (float w = 0.0; w < 7.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\ncolor += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\n}\n}\ngl_FragColor = color;\n}", Convolute_7_0: "precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[49];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 1);\nfor (float h = 0.0; h < 7.0; h+=1.0) {\nfor (float w = 0.0; w < 7.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\ncolor.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\n}\n}\nfloat alpha = texture2D(uTexture, vTexCoord).a;\ngl_FragColor = color;\ngl_FragColor.a = alpha;\n}", Convolute_9_1: "precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[81];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 0);\nfor (float h = 0.0; h < 9.0; h+=1.0) {\nfor (float w = 0.0; w < 9.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\ncolor += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\n}\n}\ngl_FragColor = color;\n}", Convolute_9_0: "precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[81];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 1);\nfor (float h = 0.0; h < 9.0; h+=1.0) {\nfor (float w = 0.0; w < 9.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\ncolor.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\n}\n}\nfloat alpha = texture2D(uTexture, vTexCoord).a;\ngl_FragColor = color;\ngl_FragColor.a = alpha;\n}" }, retrieveShader: function(t) { var e = Math.sqrt(this.matrix.length),
                                i = this.type + "_" + e + "_" + (this.opaque ? 1 : 0),
                                r = this.fragmentSource[i]; return t.programCache.hasOwnProperty(i) || (t.programCache[i] = this.createProgram(t.context, r)), t.programCache[i] }, applyTo2d: function(t) { var e, i, r, n, s, o, a, h, c, l, u, f, d, g = t.imageData,
                                p = g.data,
                                v = this.matrix,
                                m = Math.round(Math.sqrt(v.length)),
                                _ = Math.floor(m / 2),
                                y = g.width,
                                b = g.height,
                                x = t.ctx.createImageData(y, b),
                                C = x.data,
                                w = this.opaque ? 1 : 0; for (u = 0; u < b; u++)
                                for (l = 0; l < y; l++) { for (s = 4 * (u * y + l), e = 0, i = 0, r = 0, n = 0, d = 0; d < m; d++)
                                        for (f = 0; f < m; f++) o = l + f - _, (a = u + d - _) < 0 || a > b || o < 0 || o > y || (h = 4 * (a * y + o), c = v[d * m + f], e += p[h] * c, i += p[h + 1] * c, r += p[h + 2] * c, w || (n += p[h + 3] * c));
                                    C[s] = e, C[s + 1] = i, C[s + 2] = r, C[s + 3] = w ? p[s + 3] : n } t.imageData = x }, getUniformLocations: function(t, e) { return { uMatrix: t.getUniformLocation(e, "uMatrix"), uOpaque: t.getUniformLocation(e, "uOpaque"), uHalfSize: t.getUniformLocation(e, "uHalfSize"), uSize: t.getUniformLocation(e, "uSize") } }, sendUniformData: function(t, e) { t.uniform1fv(e.uMatrix, this.matrix) }, toObject: function() { return i(this.callSuper("toObject"), { opaque: this.opaque, matrix: this.matrix }) } }), e.Image.filters.Convolute.fromObject = e.Image.filters.BaseFilter.fromObject }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.Image.filters,
                        r = e.util.createClass;
                    i.Grayscale = r(i.BaseFilter, { type: "Grayscale", fragmentSource: { average: "precision highp float;\nuniform sampler2D uTexture;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nfloat average = (color.r + color.b + color.g) / 3.0;\ngl_FragColor = vec4(average, average, average, color.a);\n}", lightness: "precision highp float;\nuniform sampler2D uTexture;\nuniform int uMode;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 col = texture2D(uTexture, vTexCoord);\nfloat average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\ngl_FragColor = vec4(average, average, average, col.a);\n}", luminosity: "precision highp float;\nuniform sampler2D uTexture;\nuniform int uMode;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 col = texture2D(uTexture, vTexCoord);\nfloat average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\ngl_FragColor = vec4(average, average, average, col.a);\n}" }, mode: "average", mainParameter: "mode", applyTo2d: function(t) { var e, i, r = t.imageData.data,
                                n = r.length,
                                s = this.mode; for (e = 0; e < n; e += 4) "average" === s ? i = (r[e] + r[e + 1] + r[e + 2]) / 3 : "lightness" === s ? i = (Math.min(r[e], r[e + 1], r[e + 2]) + Math.max(r[e], r[e + 1], r[e + 2])) / 2 : "luminosity" === s && (i = .21 * r[e] + .72 * r[e + 1] + .07 * r[e + 2]), r[e] = i, r[e + 1] = i, r[e + 2] = i }, retrieveShader: function(t) { var e = this.type + "_" + this.mode; if (!t.programCache.hasOwnProperty(e)) { var i = this.fragmentSource[this.mode];
                                t.programCache[e] = this.createProgram(t.context, i) } return t.programCache[e] }, getUniformLocations: function(t, e) { return { uMode: t.getUniformLocation(e, "uMode") } }, sendUniformData: function(t, e) { t.uniform1i(e.uMode, 1) }, isNeutralState: function() { return !1 } }), e.Image.filters.Grayscale.fromObject = e.Image.filters.BaseFilter.fromObject }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.Image.filters,
                        r = e.util.createClass;
                    i.Invert = r(i.BaseFilter, { type: "Invert", fragmentSource: "precision highp float;\nuniform sampler2D uTexture;\nuniform int uInvert;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nif (uInvert == 1) {\ngl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\n} else {\ngl_FragColor = color;\n}\n}", invert: !0, mainParameter: "invert", applyTo2d: function(t) { var e, i = t.imageData.data,
                                r = i.length; for (e = 0; e < r; e += 4) i[e] = 255 - i[e], i[e + 1] = 255 - i[e + 1], i[e + 2] = 255 - i[e + 2] }, isNeutralState: function() { return !this.invert }, getUniformLocations: function(t, e) { return { uInvert: t.getUniformLocation(e, "uInvert") } }, sendUniformData: function(t, e) { t.uniform1i(e.uInvert, this.invert) } }), e.Image.filters.Invert.fromObject = e.Image.filters.BaseFilter.fromObject }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.util.object.extend,
                        r = e.Image.filters,
                        n = e.util.createClass;
                    r.Noise = n(r.BaseFilter, { type: "Noise", fragmentSource: "precision highp float;\nuniform sampler2D uTexture;\nuniform float uStepH;\nuniform float uNoise;\nuniform float uSeed;\nvarying vec2 vTexCoord;\nfloat rand(vec2 co, float seed, float vScale) {\nreturn fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\n}\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\ncolor.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\ngl_FragColor = color;\n}", mainParameter: "noise", noise: 0, applyTo2d: function(t) { if (0 !== this.noise) { var e, i, r = t.imageData.data,
                                    n = r.length,
                                    s = this.noise; for (e = 0, n = r.length; e < n; e += 4) i = (.5 - Math.random()) * s, r[e] += i, r[e + 1] += i, r[e + 2] += i } }, getUniformLocations: function(t, e) { return { uNoise: t.getUniformLocation(e, "uNoise"), uSeed: t.getUniformLocation(e, "uSeed") } }, sendUniformData: function(t, e) { t.uniform1f(e.uNoise, this.noise / 255), t.uniform1f(e.uSeed, Math.random()) }, toObject: function() { return i(this.callSuper("toObject"), { noise: this.noise }) } }), e.Image.filters.Noise.fromObject = e.Image.filters.BaseFilter.fromObject }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.Image.filters,
                        r = e.util.createClass;
                    i.Pixelate = r(i.BaseFilter, { type: "Pixelate", blocksize: 4, mainParameter: "blocksize", fragmentSource: "precision highp float;\nuniform sampler2D uTexture;\nuniform float uBlocksize;\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nfloat blockW = uBlocksize * uStepW;\nfloat blockH = uBlocksize * uStepW;\nint posX = int(vTexCoord.x / blockW);\nint posY = int(vTexCoord.y / blockH);\nfloat fposX = float(posX);\nfloat fposY = float(posY);\nvec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\nvec4 color = texture2D(uTexture, squareCoords);\ngl_FragColor = color;\n}", applyTo2d: function(t) { var e, i, r, n, s, o, a, h, c, l, u, f = t.imageData,
                                d = f.data,
                                g = f.height,
                                p = f.width; for (i = 0; i < g; i += this.blocksize)
                                for (r = 0; r < p; r += this.blocksize)
                                    for (n = d[e = 4 * i * p + 4 * r], s = d[e + 1], o = d[e + 2], a = d[e + 3], l = Math.min(i + this.blocksize, g), u = Math.min(r + this.blocksize, p), h = i; h < l; h++)
                                        for (c = r; c < u; c++) d[e = 4 * h * p + 4 * c] = n, d[e + 1] = s, d[e + 2] = o, d[e + 3] = a }, isNeutralState: function() { return 1 === this.blocksize }, getUniformLocations: function(t, e) { return { uBlocksize: t.getUniformLocation(e, "uBlocksize"), uStepW: t.getUniformLocation(e, "uStepW"), uStepH: t.getUniformLocation(e, "uStepH") } }, sendUniformData: function(t, e) { t.uniform1f(e.uBlocksize, this.blocksize) } }), e.Image.filters.Pixelate.fromObject = e.Image.filters.BaseFilter.fromObject }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.util.object.extend,
                        r = e.Image.filters,
                        n = e.util.createClass;
                    r.RemoveColor = n(r.BaseFilter, { type: "RemoveColor", color: "#FFFFFF", fragmentSource: "precision highp float;\nuniform sampler2D uTexture;\nuniform vec4 uLow;\nuniform vec4 uHigh;\nvarying vec2 vTexCoord;\nvoid main() {\ngl_FragColor = texture2D(uTexture, vTexCoord);\nif(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\ngl_FragColor.a = 0.0;\n}\n}", distance: .02, useAlpha: !1, applyTo2d: function(t) { var i, r, n, s, o = t.imageData.data,
                                a = 255 * this.distance,
                                h = new e.Color(this.color).getSource(),
                                c = [h[0] - a, h[1] - a, h[2] - a],
                                l = [h[0] + a, h[1] + a, h[2] + a]; for (i = 0; i < o.length; i += 4) r = o[i], n = o[i + 1], s = o[i + 2], r > c[0] && n > c[1] && s > c[2] && r < l[0] && n < l[1] && s < l[2] && (o[i + 3] = 0) }, getUniformLocations: function(t, e) { return { uLow: t.getUniformLocation(e, "uLow"), uHigh: t.getUniformLocation(e, "uHigh") } }, sendUniformData: function(t, i) { var r = new e.Color(this.color).getSource(),
                                n = parseFloat(this.distance),
                                s = [0 + r[0] / 255 - n, 0 + r[1] / 255 - n, 0 + r[2] / 255 - n, 1],
                                o = [r[0] / 255 + n, r[1] / 255 + n, r[2] / 255 + n, 1];
                            t.uniform4fv(i.uLow, s), t.uniform4fv(i.uHigh, o) }, toObject: function() { return i(this.callSuper("toObject"), { color: this.color, distance: this.distance }) } }), e.Image.filters.RemoveColor.fromObject = e.Image.filters.BaseFilter.fromObject }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.Image.filters,
                        r = e.util.createClass,
                        n = { Brownie: [.5997, .34553, -.27082, 0, .186, -.0377, .86095, .15059, 0, -.1449, .24113, -.07441, .44972, 0, -.02965, 0, 0, 0, 1, 0], Vintage: [.62793, .32021, -.03965, 0, .03784, .02578, .64411, .03259, 0, .02926, .0466, -.08512, .52416, 0, .02023, 0, 0, 0, 1, 0], Kodachrome: [1.12855, -.39673, -.03992, 0, .24991, -.16404, 1.08352, -.05498, 0, .09698, -.16786, -.56034, 1.60148, 0, .13972, 0, 0, 0, 1, 0], Technicolor: [1.91252, -.85453, -.09155, 0, .04624, -.30878, 1.76589, -.10601, 0, -.27589, -.2311, -.75018, 1.84759, 0, .12137, 0, 0, 0, 1, 0], Polaroid: [1.438, -.062, -.062, 0, 0, -.122, 1.378, -.122, 0, 0, -.016, -.016, 1.483, 0, 0, 0, 0, 0, 1, 0], Sepia: [.393, .769, .189, 0, 0, .349, .686, .168, 0, 0, .272, .534, .131, 0, 0, 0, 0, 0, 1, 0], BlackWhite: [1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 0, 0, 0, 1, 0] }; for (var s in n) i[s] = r(i.ColorMatrix, { type: s, matrix: n[s], mainParameter: !1, colorsOnly: !0 }), e.Image.filters[s].fromObject = e.Image.filters.BaseFilter.fromObject }(e),
                function(t) { "use strict"; var e = t.fabric,
                        i = e.Image.filters,
                        r = e.util.createClass;
                    i.BlendColor = r(i.BaseFilter, { type: "BlendColor", color: "#F95C63", mode: "multiply", alpha: 1, fragmentSource: { multiply: "gl_FragColor.rgb *= uColor.rgb;\n", screen: "gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\n", add: "gl_FragColor.rgb += uColor.rgb;\n", diff: "gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\n", subtract: "gl_FragColor.rgb -= uColor.rgb;\n", lighten: "gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\n", darken: "gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\n", exclusion: "gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\n", overlay: "if (uColor.r < 0.5) {\ngl_FragColor.r *= 2.0 * uColor.r;\n} else {\ngl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n}\nif (uColor.g < 0.5) {\ngl_FragColor.g *= 2.0 * uColor.g;\n} else {\ngl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n}\nif (uColor.b < 0.5) {\ngl_FragColor.b *= 2.0 * uColor.b;\n} else {\ngl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n}\n", tint: "gl_FragColor.rgb *= (1.0 - uColor.a);\ngl_FragColor.rgb += uColor.rgb;\n" }, buildSource: function(t) { return "precision highp float;\nuniform sampler2D uTexture;\nuniform vec4 uColor;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\ngl_FragColor = color;\nif (color.a > 0.0) {\n" + this.fragmentSource[t] + "}\n}" }, retrieveShader: function(t) { var e, i = this.type + "_" + this.mode; return t.programCache.hasOwnProperty(i) || (e = this.buildSource(this.mode), t.programCache[i] = this.createProgram(t.context, e)), t.programCache[i] }, applyTo2d: function(t) { var i, r, n, s, o, a, h, c = t.imageData.data,
                                l = c.length,
                                u = 1 - this.alpha;
                            i = (h = new e.Color(this.color).getSource())[0] * this.alpha, r = h[1] * this.alpha, n = h[2] * this.alpha; for (var f = 0; f < l; f += 4) switch (s = c[f], o = c[f + 1], a = c[f + 2], this.mode) {
                                case "multiply":
                                    c[f] = s * i / 255, c[f + 1] = o * r / 255, c[f + 2] = a * n / 255; break;
                                case "screen":
                                    c[f] = 255 - (255 - s) * (255 - i) / 255, c[f + 1] = 255 - (255 - o) * (255 - r) / 255, c[f + 2] = 255 - (255 - a) * (255 - n) / 255; break;
                                case "add":
                                    c[f] = s + i, c[f + 1] = o + r, c[f + 2] = a + n; break;
                                case "diff":
                                case "difference":
                                    c[f] = Math.abs(s - i), c[f + 1] = Math.abs(o - r), c[f + 2] = Math.abs(a - n); break;
                                case "subtract":
                                    c[f] = s - i, c[f + 1] = o - r, c[f + 2] = a - n; break;
                                case "darken":
                                    c[f] = Math.min(s, i), c[f + 1] = Math.min(o, r), c[f + 2] = Math.min(a, n); break;
                                case "lighten":
                                    c[f] = Math.max(s, i), c[f + 1] = Math.max(o, r), c[f + 2] = Math.max(a, n); break;
                                case "overlay":
                                    c[f] = i < 128 ? 2 * s * i / 255 : 255 - 2 * (255 - s) * (255 - i) / 255, c[f + 1] = r < 128 ? 2 * o * r / 255 : 255 - 2 * (255 - o) * (255 - r) / 255, c[f + 2] = n < 128 ? 2 * a * n / 255 : 255 - 2 * (255 - a) * (255 - n) / 255; break;
                                case "exclusion":
                                    c[f] = i + s - 2 * i * s / 255, c[f + 1] = r + o - 2 * r * o / 255, c[f + 2] = n + a - 2 * n * a / 255; break;
                                case "tint":
                                    c[f] = i + s * u, c[f + 1] = r + o * u, c[f + 2] = n + a * u } }, getUniformLocations: function(t, e) { return { uColor: t.getUniformLocation(e, "uColor") } }, sendUniformData: function(t, i) { var r = new e.Color(this.color).getSource();
                            r[0] = this.alpha * r[0] / 255, r[1] = this.alpha * r[1] / 255, r[2] = this.alpha * r[2] / 255, r[3] = this.alpha, t.uniform4fv(i.uColor, r) }, toObject: function() { return { type: this.type, color: this.color, mode: this.mode, alpha: this.alpha } } }), e.Image.filters.BlendColor.fromObject = e.Image.filters.BaseFilter.fromObject }(e),
                function(t) { "use strict"; var e = t.fabric,
                        i = e.Image.filters,
                        r = e.util.createClass;
                    i.BlendImage = r(i.BaseFilter, { type: "BlendImage", image: null, mode: "multiply", alpha: 1, vertexSource: "attribute vec2 aPosition;\nvarying vec2 vTexCoord;\nvarying vec2 vTexCoord2;\nuniform mat3 uTransformMatrix;\nvoid main() {\nvTexCoord = aPosition;\nvTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\ngl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n}", fragmentSource: { multiply: "precision highp float;\nuniform sampler2D uTexture;\nuniform sampler2D uImage;\nuniform vec4 uColor;\nvarying vec2 vTexCoord;\nvarying vec2 vTexCoord2;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nvec4 color2 = texture2D(uImage, vTexCoord2);\ncolor.rgba *= color2.rgba;\ngl_FragColor = color;\n}", mask: "precision highp float;\nuniform sampler2D uTexture;\nuniform sampler2D uImage;\nuniform vec4 uColor;\nvarying vec2 vTexCoord;\nvarying vec2 vTexCoord2;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nvec4 color2 = texture2D(uImage, vTexCoord2);\ncolor.a = color2.a;\ngl_FragColor = color;\n}" }, retrieveShader: function(t) { var e = this.type + "_" + this.mode,
                                i = this.fragmentSource[this.mode]; return t.programCache.hasOwnProperty(e) || (t.programCache[e] = this.createProgram(t.context, i)), t.programCache[e] }, applyToWebGL: function(t) { var e = t.context,
                                i = this.createTexture(t.filterBackend, this.image);
                            this.bindAdditionalTexture(e, i, e.TEXTURE1), this.callSuper("applyToWebGL", t), this.unbindAdditionalTexture(e, e.TEXTURE1) }, createTexture: function(t, e) { return t.getCachedTexture(e.cacheKey, e._element) }, calculateMatrix: function() { var t = this.image,
                                e = t._element.width,
                                i = t._element.height; return [1 / t.scaleX, 0, 0, 0, 1 / t.scaleY, 0, -t.left / e, -t.top / i, 1] }, applyTo2d: function(t) { var i, r, n, s, o, a, h, c, l, u, f, d = t.imageData,
                                g = t.filterBackend.resources,
                                p = d.data,
                                v = p.length,
                                m = d.width,
                                _ = d.height,
                                y = this.image;
                            g.blendImage || (g.blendImage = e.util.createCanvasElement()), u = (l = g.blendImage).getContext("2d"), l.width !== m || l.height !== _ ? (l.width = m, l.height = _) : u.clearRect(0, 0, m, _), u.setTransform(y.scaleX, 0, 0, y.scaleY, y.left, y.top), u.drawImage(y._element, 0, 0, m, _), f = u.getImageData(0, 0, m, _).data; for (var b = 0; b < v; b += 4) switch (o = p[b], a = p[b + 1], h = p[b + 2], c = p[b + 3], i = f[b], r = f[b + 1], n = f[b + 2], s = f[b + 3], this.mode) {
                                case "multiply":
                                    p[b] = o * i / 255, p[b + 1] = a * r / 255, p[b + 2] = h * n / 255, p[b + 3] = c * s / 255; break;
                                case "mask":
                                    p[b + 3] = s } }, getUniformLocations: function(t, e) { return { uTransformMatrix: t.getUniformLocation(e, "uTransformMatrix"), uImage: t.getUniformLocation(e, "uImage") } }, sendUniformData: function(t, e) { var i = this.calculateMatrix();
                            t.uniform1i(e.uImage, 1), t.uniformMatrix3fv(e.uTransformMatrix, !1, i) }, toObject: function() { return { type: this.type, image: this.image && this.image.toObject(), mode: this.mode, alpha: this.alpha } } }), e.Image.filters.BlendImage.fromObject = function(t, i) { e.Image.fromObject(t.image, function(r) { var n = e.util.object.clone(t);
                            n.image = r, i(new e.Image.filters.BlendImage(n)) }) } }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = Math.pow,
                        r = Math.floor,
                        n = Math.sqrt,
                        s = Math.abs,
                        o = Math.round,
                        a = Math.sin,
                        h = Math.ceil,
                        c = e.Image.filters,
                        l = e.util.createClass;
                    c.Resize = l(c.BaseFilter, { type: "Resize", resizeType: "hermite", scaleX: 1, scaleY: 1, lanczosLobes: 3, getUniformLocations: function(t, e) { return { uDelta: t.getUniformLocation(e, "uDelta"), uTaps: t.getUniformLocation(e, "uTaps") } }, sendUniformData: function(t, e) { t.uniform2fv(e.uDelta, this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height]), t.uniform1fv(e.uTaps, this.taps) }, retrieveShader: function(t) { var e = this.getFilterWindow(),
                                i = this.type + "_" + e; if (!t.programCache.hasOwnProperty(i)) { var r = this.generateShader(e);
                                t.programCache[i] = this.createProgram(t.context, r) } return t.programCache[i] }, getFilterWindow: function() { var t = this.tempScale; return Math.ceil(this.lanczosLobes / t) }, getTaps: function() { for (var t = this.lanczosCreate(this.lanczosLobes), e = this.tempScale, i = this.getFilterWindow(), r = new Array(i), n = 1; n <= i; n++) r[n - 1] = t(n * e); return r }, generateShader: function(t) { for (var e = new Array(t), i = this.fragmentSourceTOP, r = 1; r <= t; r++) e[r - 1] = r + ".0 * uDelta"; return i += "uniform float uTaps[" + t + "];\n", i += "void main() {\n", i += "  vec4 color = texture2D(uTexture, vTexCoord);\n", i += "  float sum = 1.0;\n", e.forEach(function(t, e) { i += "  color += texture2D(uTexture, vTexCoord + " + t + ") * uTaps[" + e + "];\n", i += "  color += texture2D(uTexture, vTexCoord - " + t + ") * uTaps[" + e + "];\n", i += "  sum += 2.0 * uTaps[" + e + "];\n" }), i += "  gl_FragColor = color / sum;\n", i += "}" }, fragmentSourceTOP: "precision highp float;\nuniform sampler2D uTexture;\nuniform vec2 uDelta;\nvarying vec2 vTexCoord;\n", applyTo: function(t) { t.webgl ? (t.passes++, this.width = t.sourceWidth, this.horizontal = !0, this.dW = Math.round(this.width * this.scaleX), this.dH = t.sourceHeight, this.tempScale = this.dW / this.width, this.taps = this.getTaps(), t.destinationWidth = this.dW, this._setupFrameBuffer(t), this.applyToWebGL(t), this._swapTextures(t), t.sourceWidth = t.destinationWidth, this.height = t.sourceHeight, this.horizontal = !1, this.dH = Math.round(this.height * this.scaleY), this.tempScale = this.dH / this.height, this.taps = this.getTaps(), t.destinationHeight = this.dH, this._setupFrameBuffer(t), this.applyToWebGL(t), this._swapTextures(t), t.sourceHeight = t.destinationHeight) : this.applyTo2d(t) }, isNeutralState: function() { return 1 === this.scaleX && 1 === this.scaleY }, lanczosCreate: function(t) { return function(e) { if (e >= t || e <= -t) return 0; if (e < 1.1920929e-7 && e > -1.1920929e-7) return 1; var i = (e *= Math.PI) / t; return a(e) / e * a(i) / i } }, applyTo2d: function(t) { var e = t.imageData,
                                i = this.scaleX,
                                r = this.scaleY;
                            this.rcpScaleX = 1 / i, this.rcpScaleY = 1 / r; var n, s = e.width,
                                a = e.height,
                                h = o(s * i),
                                c = o(a * r); "sliceHack" === this.resizeType ? n = this.sliceByTwo(t, s, a, h, c) : "hermite" === this.resizeType ? n = this.hermiteFastResize(t, s, a, h, c) : "bilinear" === this.resizeType ? n = this.bilinearFiltering(t, s, a, h, c) : "lanczos" === this.resizeType && (n = this.lanczosResize(t, s, a, h, c)), t.imageData = n }, sliceByTwo: function(t, i, n, s, o) { var a, h, c = t.imageData,
                                l = !1,
                                u = !1,
                                f = .5 * i,
                                d = .5 * n,
                                g = e.filterBackend.resources,
                                p = 0,
                                v = 0,
                                m = i,
                                _ = 0; for (g.sliceByTwo || (g.sliceByTwo = document.createElement("canvas")), ((a = g.sliceByTwo).width < 1.5 * i || a.height < n) && (a.width = 1.5 * i, a.height = n), (h = a.getContext("2d")).clearRect(0, 0, 1.5 * i, n), h.putImageData(c, 0, 0), s = r(s), o = r(o); !l || !u;) i = f, n = d, s < r(.5 * f) ? f = r(.5 * f) : (f = s, l = !0), o < r(.5 * d) ? d = r(.5 * d) : (d = o, u = !0), h.drawImage(a, p, v, i, n, m, _, f, d), p = m, v = _, _ += d; return h.getImageData(p, v, s, o) }, lanczosResize: function(t, e, o, a, c) { var l = t.imageData.data,
                                u = t.ctx.createImageData(a, c),
                                f = u.data,
                                d = this.lanczosCreate(this.lanczosLobes),
                                g = this.rcpScaleX,
                                p = this.rcpScaleY,
                                v = 2 / this.rcpScaleX,
                                m = 2 / this.rcpScaleY,
                                _ = h(g * this.lanczosLobes / 2),
                                y = h(p * this.lanczosLobes / 2),
                                b = {},
                                x = {},
                                C = {}; return function t(h) { var w, S, T, O, k, P, E, A, D, j, M; for (x.x = (h + .5) * g, C.x = r(x.x), w = 0; w < c; w++) { for (x.y = (w + .5) * p, C.y = r(x.y), k = 0, P = 0, E = 0, A = 0, D = 0, S = C.x - _; S <= C.x + _; S++)
                                        if (!(S < 0 || S >= e)) { j = r(1e3 * s(S - x.x)), b[j] || (b[j] = {}); for (var F = C.y - y; F <= C.y + y; F++) F < 0 || F >= o || (M = r(1e3 * s(F - x.y)), b[j][M] || (b[j][M] = d(n(i(j * v, 2) + i(M * m, 2)) / 1e3)), (T = b[j][M]) > 0 && (k += T, P += T * l[O = 4 * (F * e + S)], E += T * l[O + 1], A += T * l[O + 2], D += T * l[O + 3])) } f[O = 4 * (w * a + h)] = P / k, f[O + 1] = E / k, f[O + 2] = A / k, f[O + 3] = D / k } return ++h < a ? t(h) : u }(0) }, bilinearFiltering: function(t, e, i, n, s) { var o, a, h, c, l, u, f, d, g, p = 0,
                                v = this.rcpScaleX,
                                m = this.rcpScaleY,
                                _ = 4 * (e - 1),
                                y = t.imageData.data,
                                b = t.ctx.createImageData(n, s),
                                x = b.data; for (h = 0; h < s; h++)
                                for (c = 0; c < n; c++)
                                    for (l = v * c - (o = r(v * c)), u = m * h - (a = r(m * h)), g = 4 * (a * e + o), f = 0; f < 4; f++) d = y[g + f] * (1 - l) * (1 - u) + y[g + 4 + f] * l * (1 - u) + y[g + _ + f] * u * (1 - l) + y[g + _ + 4 + f] * l * u, x[p++] = d; return b }, hermiteFastResize: function(t, e, i, o, a) { for (var c = this.rcpScaleX, l = this.rcpScaleY, u = h(c / 2), f = h(l / 2), d = t.imageData.data, g = t.ctx.createImageData(o, a), p = g.data, v = 0; v < a; v++)
                                for (var m = 0; m < o; m++) { for (var _ = 4 * (m + v * o), y = 0, b = 0, x = 0, C = 0, w = 0, S = 0, T = 0, O = (v + .5) * l, k = r(v * l); k < (v + 1) * l; k++)
                                        for (var P = s(O - (k + .5)) / f, E = (m + .5) * c, A = P * P, D = r(m * c); D < (m + 1) * c; D++) { var j = s(E - (D + .5)) / u,
                                                M = n(A + j * j);
                                            M > 1 && M < -1 || (y = 2 * M * M * M - 3 * M * M + 1) > 0 && (T += y * d[(j = 4 * (D + k * e)) + 3], x += y, d[j + 3] < 255 && (y = y * d[j + 3] / 250), C += y * d[j], w += y * d[j + 1], S += y * d[j + 2], b += y) } p[_] = C / b, p[_ + 1] = w / b, p[_ + 2] = S / b, p[_ + 3] = T / x }
                            return g }, toObject: function() { return { type: this.type, scaleX: this.scaleX, scaleY: this.scaleY, resizeType: this.resizeType, lanczosLobes: this.lanczosLobes } } }), e.Image.filters.Resize.fromObject = e.Image.filters.BaseFilter.fromObject }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.Image.filters,
                        r = e.util.createClass;
                    i.Contrast = r(i.BaseFilter, { type: "Contrast", fragmentSource: "precision highp float;\nuniform sampler2D uTexture;\nuniform float uContrast;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nfloat contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\ncolor.rgb = contrastF * (color.rgb - 0.5) + 0.5;\ngl_FragColor = color;\n}", contrast: 0, mainParameter: "contrast", applyTo2d: function(t) { if (0 !== this.contrast) { var e, i = t.imageData.data,
                                    r = i.length,
                                    n = Math.floor(255 * this.contrast),
                                    s = 259 * (n + 255) / (255 * (259 - n)); for (e = 0; e < r; e += 4) i[e] = s * (i[e] - 128) + 128, i[e + 1] = s * (i[e + 1] - 128) + 128, i[e + 2] = s * (i[e + 2] - 128) + 128 } }, getUniformLocations: function(t, e) { return { uContrast: t.getUniformLocation(e, "uContrast") } }, sendUniformData: function(t, e) { t.uniform1f(e.uContrast, this.contrast) } }), e.Image.filters.Contrast.fromObject = e.Image.filters.BaseFilter.fromObject }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.Image.filters,
                        r = e.util.createClass;
                    i.Saturation = r(i.BaseFilter, { type: "Saturation", fragmentSource: "precision highp float;\nuniform sampler2D uTexture;\nuniform float uSaturation;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nfloat rgMax = max(color.r, color.g);\nfloat rgbMax = max(rgMax, color.b);\ncolor.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\ncolor.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\ncolor.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\ngl_FragColor = color;\n}", saturation: 0, mainParameter: "saturation", applyTo2d: function(t) { if (0 !== this.saturation) { var e, i, r = t.imageData.data,
                                    n = r.length,
                                    s = -this.saturation; for (e = 0; e < n; e += 4) i = Math.max(r[e], r[e + 1], r[e + 2]), r[e] += i !== r[e] ? (i - r[e]) * s : 0, r[e + 1] += i !== r[e + 1] ? (i - r[e + 1]) * s : 0, r[e + 2] += i !== r[e + 2] ? (i - r[e + 2]) * s : 0 } }, getUniformLocations: function(t, e) { return { uSaturation: t.getUniformLocation(e, "uSaturation") } }, sendUniformData: function(t, e) { t.uniform1f(e.uSaturation, -this.saturation) } }), e.Image.filters.Saturation.fromObject = e.Image.filters.BaseFilter.fromObject }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.Image.filters,
                        r = e.util.createClass;
                    i.Blur = r(i.BaseFilter, { type: "Blur", fragmentSource: "precision highp float;\nuniform sampler2D uTexture;\nuniform vec2 uDelta;\nvarying vec2 vTexCoord;\nconst float nSamples = 15.0;\nvec3 v3offset = vec3(12.9898, 78.233, 151.7182);\nfloat random(vec3 scale) {\nreturn fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\n}\nvoid main() {\nvec4 color = vec4(0.0);\nfloat total = 0.0;\nfloat offset = random(v3offset);\nfor (float t = -nSamples; t <= nSamples; t++) {\nfloat percent = (t + offset - 0.5) / nSamples;\nfloat weight = 1.0 - abs(percent);\ncolor += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\ntotal += weight;\n}\ngl_FragColor = color / total;\n}", blur: 0, mainParameter: "blur", applyTo: function(t) { t.webgl ? (this.aspectRatio = t.sourceWidth / t.sourceHeight, t.passes++, this._setupFrameBuffer(t), this.horizontal = !0, this.applyToWebGL(t), this._swapTextures(t), this._setupFrameBuffer(t), this.horizontal = !1, this.applyToWebGL(t), this._swapTextures(t)) : this.applyTo2d(t) }, applyTo2d: function(t) { t.imageData = this.simpleBlur(t) }, simpleBlur: function(t) { var i, r, n = t.filterBackend.resources,
                                s = t.imageData.width,
                                o = t.imageData.height;
                            n.blurLayer1 || (n.blurLayer1 = e.util.createCanvasElement(), n.blurLayer2 = e.util.createCanvasElement()), i = n.blurLayer1, r = n.blurLayer2, i.width === s && i.height === o || (r.width = i.width = s, r.height = i.height = o); var a, h, c, l, u = i.getContext("2d"),
                                f = r.getContext("2d"),
                                d = .06 * this.blur * .5; for (u.putImageData(t.imageData, 0, 0), f.clearRect(0, 0, s, o), l = -15; l <= 15; l++) a = (Math.random() - .5) / 4, c = d * (h = l / 15) * s + a, f.globalAlpha = 1 - Math.abs(h), f.drawImage(i, c, a), u.drawImage(r, 0, 0), f.globalAlpha = 1, f.clearRect(0, 0, r.width, r.height); for (l = -15; l <= 15; l++) a = (Math.random() - .5) / 4, c = d * (h = l / 15) * o + a, f.globalAlpha = 1 - Math.abs(h), f.drawImage(i, a, c), u.drawImage(r, 0, 0), f.globalAlpha = 1, f.clearRect(0, 0, r.width, r.height);
                            t.ctx.drawImage(i, 0, 0); var g = t.ctx.getImageData(0, 0, i.width, i.height); return u.globalAlpha = 1, u.clearRect(0, 0, i.width, i.height), g }, getUniformLocations: function(t, e) { return { delta: t.getUniformLocation(e, "uDelta") } }, sendUniformData: function(t, e) { var i = this.chooseRightDelta();
                            t.uniform2fv(e.delta, i) }, chooseRightDelta: function() { var t, e = 1,
                                i = [0, 0]; return this.horizontal ? this.aspectRatio > 1 && (e = 1 / this.aspectRatio) : this.aspectRatio < 1 && (e = this.aspectRatio), t = e * this.blur * .12, this.horizontal ? i[0] = t : i[1] = t, i } }), i.Blur.fromObject = e.Image.filters.BaseFilter.fromObject }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.Image.filters,
                        r = e.util.createClass;
                    i.Gamma = r(i.BaseFilter, { type: "Gamma", fragmentSource: "precision highp float;\nuniform sampler2D uTexture;\nuniform vec3 uGamma;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nvec3 correction = (1.0 / uGamma);\ncolor.r = pow(color.r, correction.r);\ncolor.g = pow(color.g, correction.g);\ncolor.b = pow(color.b, correction.b);\ngl_FragColor = color;\ngl_FragColor.rgb *= color.a;\n}", gamma: [1, 1, 1], mainParameter: "gamma", initialize: function(t) { this.gamma = [1, 1, 1], i.BaseFilter.prototype.initialize.call(this, t) }, applyTo2d: function(t) { var e, i = t.imageData.data,
                                r = this.gamma,
                                n = i.length,
                                s = 1 / r[0],
                                o = 1 / r[1],
                                a = 1 / r[2]; for (this.rVals || (this.rVals = new Uint8Array(256), this.gVals = new Uint8Array(256), this.bVals = new Uint8Array(256)), e = 0, n = 256; e < n; e++) this.rVals[e] = 255 * Math.pow(e / 255, s), this.gVals[e] = 255 * Math.pow(e / 255, o), this.bVals[e] = 255 * Math.pow(e / 255, a); for (e = 0, n = i.length; e < n; e += 4) i[e] = this.rVals[i[e]], i[e + 1] = this.gVals[i[e + 1]], i[e + 2] = this.bVals[i[e + 2]] }, getUniformLocations: function(t, e) { return { uGamma: t.getUniformLocation(e, "uGamma") } }, sendUniformData: function(t, e) { t.uniform3fv(e.uGamma, this.gamma) } }), e.Image.filters.Gamma.fromObject = e.Image.filters.BaseFilter.fromObject }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.Image.filters,
                        r = e.util.createClass;
                    i.Composed = r(i.BaseFilter, { type: "Composed", subFilters: [], initialize: function(t) { this.callSuper("initialize", t), this.subFilters = this.subFilters.slice(0) }, applyTo: function(t) { t.passes += this.subFilters.length - 1, this.subFilters.forEach(function(e) { e.applyTo(t) }) }, toObject: function() { return e.util.object.extend(this.callSuper("toObject"), { subFilters: this.subFilters.map(function(t) { return t.toObject() }) }) }, isNeutralState: function() { return !this.subFilters.some(function(t) { return !t.isNeutralState() }) } }), e.Image.filters.Composed.fromObject = function(t, i) { var r = (t.subFilters || []).map(function(t) { return new e.Image.filters[t.type](t) }),
                            n = new e.Image.filters.Composed({ subFilters: r }); return i && i(n), n } }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.Image.filters,
                        r = e.util.createClass;
                    i.HueRotation = r(i.ColorMatrix, { type: "HueRotation", rotation: 0, mainParameter: "rotation", calculateMatrix: function() { var t = this.rotation * Math.PI,
                                i = e.util.cos(t),
                                r = e.util.sin(t),
                                n = Math.sqrt(1 / 3) * r,
                                s = 1 - i;
                            this.matrix = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0], this.matrix[0] = i + s / 3, this.matrix[1] = 1 / 3 * s - n, this.matrix[2] = 1 / 3 * s + n, this.matrix[5] = 1 / 3 * s + n, this.matrix[6] = i + 1 / 3 * s, this.matrix[7] = 1 / 3 * s - n, this.matrix[10] = 1 / 3 * s - n, this.matrix[11] = 1 / 3 * s + n, this.matrix[12] = i + 1 / 3 * s }, isNeutralState: function(t) { return this.calculateMatrix(), i.BaseFilter.prototype.isNeutralState.call(this, t) }, applyTo: function(t) { this.calculateMatrix(), i.BaseFilter.prototype.applyTo.call(this, t) } }), e.Image.filters.HueRotation.fromObject = e.Image.filters.BaseFilter.fromObject }(e),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {}),
                        i = e.util.object.clone;
                    e.Text ? e.warn("fabric.Text is already defined") : (e.Text = e.util.createClass(e.Object, { _dimensionAffectingProps: ["fontSize", "fontWeight", "fontFamily", "fontStyle", "lineHeight", "text", "charSpacing", "textAlign", "styles"], _reNewline: /\r?\n/, _reSpacesAndTabs: /[ \t\r]/g, _reSpaceAndTab: /[ \t\r]/, _reWords: /\S+/g, type: "text", fontSize: 40, fontWeight: "normal", fontFamily: "Times New Roman", underline: !1, overline: !1, linethrough: !1, textAlign: "left", fontStyle: "normal", lineHeight: 1.16, superscript: { size: .6, baseline: -.35 }, subscript: { size: .6, baseline: .11 }, textBackgroundColor: "", stateProperties: e.Object.prototype.stateProperties.concat("fontFamily", "fontWeight", "fontSize", "text", "underline", "overline", "linethrough", "textAlign", "fontStyle", "lineHeight", "textBackgroundColor", "charSpacing", "styles"), cacheProperties: e.Object.prototype.cacheProperties.concat("fontFamily", "fontWeight", "fontSize", "text", "underline", "overline", "linethrough", "textAlign", "fontStyle", "lineHeight", "textBackgroundColor", "charSpacing", "styles"), stroke: null, shadow: null, _fontSizeFraction: .222, offsets: { underline: .1, linethrough: -.315, overline: -.88 }, _fontSizeMult: 1.13, charSpacing: 0, styles: null, _measuringContext: null, deltaY: 0, _styleProperties: ["stroke", "strokeWidth", "fill", "fontFamily", "fontSize", "fontWeight", "fontStyle", "underline", "overline", "linethrough", "deltaY", "textBackgroundColor"], __charBounds: [], CACHE_FONT_SIZE: 400, MIN_TEXT_WIDTH: 2, initialize: function(t, e) { this.styles = e && e.styles || {}, this.text = t, this.__skipDimension = !0, this.callSuper("initialize", e), this.__skipDimension = !1, this.initDimensions(), this.setCoords(), this.setupState({ propertySet: "_dimensionAffectingProps" }) }, getMeasuringContext: function() { return e._measuringContext || (e._measuringContext = this.canvas && this.canvas.contextCache || e.util.createCanvasElement().getContext("2d")), e._measuringContext }, _splitText: function() { var t = this._splitTextIntoLines(this.text); return this.textLines = t.lines, this._textLines = t.graphemeLines, this._unwrappedTextLines = t._unwrappedLines, this._text = t.graphemeText, t }, initDimensions: function() { this.__skipDimension || (this._splitText(), this._clearCache(), this.width = this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH, -1 !== this.textAlign.indexOf("justify") && this.enlargeSpaces(), this.height = this.calcTextHeight(), this.saveState({ propertySet: "_dimensionAffectingProps" })) }, enlargeSpaces: function() { for (var t, e, i, r, n, s, o, a = 0, h = this._textLines.length; a < h; a++)
                                if (("justify" === this.textAlign || a !== h - 1 && !this.isEndOfWrapping(a)) && (r = 0, n = this._textLines[a], (e = this.getLineWidth(a)) < this.width && (o = this.textLines[a].match(this._reSpacesAndTabs)))) { i = o.length, t = (this.width - e) / i; for (var c = 0, l = n.length; c <= l; c++) s = this.__charBounds[a][c], this._reSpaceAndTab.test(n[c]) ? (s.width += t, s.kernedWidth += t, s.left += r, r += t) : s.left += r } }, isEndOfWrapping: function(t) { return t === this._textLines.length - 1 }, missingNewlineOffset: function() { return 1 }, toString: function() { return "#<fabric.Text (" + this.complexity() + '): { "text": "' + this.text + '", "fontFamily": "' + this.fontFamily + '" }>' }, _getCacheCanvasDimensions: function() { var t = this.callSuper("_getCacheCanvasDimensions"),
                                e = this.fontSize; return t.width += e * t.zoomX, t.height += e * t.zoomY, t }, _render: function(t) { this._setTextStyles(t), this._renderTextLinesBackground(t), this._renderTextDecoration(t, "underline"), this._renderText(t), this._renderTextDecoration(t, "overline"), this._renderTextDecoration(t, "linethrough") }, _renderText: function(t) { "stroke" === this.paintFirst ? (this._renderTextStroke(t), this._renderTextFill(t)) : (this._renderTextFill(t), this._renderTextStroke(t)) }, _setTextStyles: function(t, e, i) { t.textBaseline = "alphabetic", t.font = this._getFontDeclaration(e, i) }, calcTextWidth: function() { for (var t = this.getLineWidth(0), e = 1, i = this._textLines.length; e < i; e++) { var r = this.getLineWidth(e);
                                r > t && (t = r) } return t }, _renderTextLine: function(t, e, i, r, n, s) { this._renderChars(t, e, i, r, n, s) }, _renderTextLinesBackground: function(t) { if (this.textBackgroundColor || this.styleHas("textBackgroundColor")) { for (var e, i, r, n, s, o, a = 0, h = t.fillStyle, c = this._getLeftOffset(), l = this._getTopOffset(), u = 0, f = 0, d = 0, g = this._textLines.length; d < g; d++)
                                    if (e = this.getHeightOfLine(d), this.textBackgroundColor || this.styleHas("textBackgroundColor", d)) { r = this._textLines[d], i = this._getLineLeftOffset(d), f = 0, u = 0, n = this.getValueOfPropertyAt(d, 0, "textBackgroundColor"); for (var p = 0, v = r.length; p < v; p++) s = this.__charBounds[d][p], (o = this.getValueOfPropertyAt(d, p, "textBackgroundColor")) !== n ? (t.fillStyle = n, n && t.fillRect(c + i + u, l + a, f, e / this.lineHeight), u = s.left, f = s.width, n = o) : f += s.kernedWidth;
                                        o && (t.fillStyle = o, t.fillRect(c + i + u, l + a, f, e / this.lineHeight)), a += e } else a += e;
                                t.fillStyle = h, this._removeShadow(t) } }, getFontCache: function(t) { var i = t.fontFamily.toLowerCase();
                            e.charWidthsCache[i] || (e.charWidthsCache[i] = {}); var r = e.charWidthsCache[i],
                                n = t.fontStyle.toLowerCase() + "_" + (t.fontWeight + "").toLowerCase(); return r[n] || (r[n] = {}), r[n] }, _applyCharStyles: function(t, e, i, r, n) { this._setFillStyles(e, n), this._setStrokeStyles(e, n), e.font = this._getFontDeclaration(n) }, _measureChar: function(t, e, i, r) { var n, s, o, a, h = this.getFontCache(e),
                                c = i + t,
                                l = this._getFontDeclaration(e) === this._getFontDeclaration(r),
                                u = e.fontSize / this.CACHE_FONT_SIZE; if (i && void 0 !== h[i] && (o = h[i]), void 0 !== h[t] && (a = n = h[t]), l && void 0 !== h[c] && (a = (s = h[c]) - o), void 0 === n || void 0 === o || void 0 === s) { var f = this.getMeasuringContext();
                                this._setTextStyles(f, e, !0) } return void 0 === n && (a = n = f.measureText(t).width, h[t] = n), void 0 === o && l && i && (o = f.measureText(i).width, h[i] = o), l && void 0 === s && (s = f.measureText(c).width, h[c] = s, a = s - o), { width: n * u, kernedWidth: a * u } }, getHeightOfChar: function(t, e) { return this.getValueOfPropertyAt(t, e, "fontSize") }, measureLine: function(t) { var e = this._measureLine(t); return 0 !== this.charSpacing && (e.width -= this._getWidthOfCharSpacing()), e.width < 0 && (e.width = 0), e }, _measureLine: function(t) { var e, i, r, n, s = 0,
                                o = this._textLines[t],
                                a = new Array(o.length); for (this.__charBounds[t] = a, e = 0; e < o.length; e++) i = o[e], n = this._getGraphemeBox(i, t, e, r), a[e] = n, s += n.kernedWidth, r = i; return a[e] = { left: n ? n.left + n.width : 0, width: 0, kernedWidth: 0, height: this.fontSize }, { width: s, numOfSpaces: 0 } }, _getGraphemeBox: function(t, e, i, r, n) { var s, o = this.getCompleteStyleDeclaration(e, i),
                                a = r ? this.getCompleteStyleDeclaration(e, i - 1) : {},
                                h = this._measureChar(t, o, r, a),
                                c = h.kernedWidth,
                                l = h.width;
                            0 !== this.charSpacing && (l += s = this._getWidthOfCharSpacing(), c += s); var u = { width: l, left: 0, height: o.fontSize, kernedWidth: c, deltaY: o.deltaY }; if (i > 0 && !n) { var f = this.__charBounds[e][i - 1];
                                u.left = f.left + f.width + h.kernedWidth - h.width } return u }, getHeightOfLine: function(t) { if (this.__lineHeights[t]) return this.__lineHeights[t]; for (var e = this._textLines[t], i = this.getHeightOfChar(t, 0), r = 1, n = e.length; r < n; r++) i = Math.max(this.getHeightOfChar(t, r), i); return this.__lineHeights[t] = i * this.lineHeight * this._fontSizeMult }, calcTextHeight: function() { for (var t, e = 0, i = 0, r = this._textLines.length; i < r; i++) t = this.getHeightOfLine(i), e += i === r - 1 ? t / this.lineHeight : t; return e }, _getLeftOffset: function() { return -this.width / 2 }, _getTopOffset: function() { return -this.height / 2 }, _renderTextCommon: function(t, e) { t.save(); for (var i = 0, r = this._getLeftOffset(), n = this._getTopOffset(), s = this._applyPatternGradientTransform(t, "fillText" === e ? this.fill : this.stroke), o = 0, a = this._textLines.length; o < a; o++) { var h = this.getHeightOfLine(o),
                                    c = h / this.lineHeight,
                                    l = this._getLineLeftOffset(o);
                                this._renderTextLine(e, t, this._textLines[o], r + l - s.offsetX, n + i + c - s.offsetY, o), i += h } t.restore() }, _renderTextFill: function(t) {
                            (this.fill || this.styleHas("fill")) && this._renderTextCommon(t, "fillText") }, _renderTextStroke: function(t) {
                            (this.stroke && 0 !== this.strokeWidth || !this.isEmptyStyles()) && (this.shadow && !this.shadow.affectStroke && this._removeShadow(t), t.save(), this._setLineDash(t, this.strokeDashArray), t.beginPath(), this._renderTextCommon(t, "strokeText"), t.closePath(), t.restore()) }, _renderChars: function(t, e, i, r, n, s) { var o, a, h, c, l = this.getHeightOfLine(s),
                                u = -1 !== this.textAlign.indexOf("justify"),
                                f = "",
                                d = 0,
                                g = !u && 0 === this.charSpacing && this.isEmptyStyles(s); if (e.save(), n -= l * this._fontSizeFraction / this.lineHeight, g) return this._renderChar(t, e, s, 0, this.textLines[s], r, n, l), void e.restore(); for (var p = 0, v = i.length - 1; p <= v; p++) c = p === v || this.charSpacing, f += i[p], h = this.__charBounds[s][p], 0 === d ? (r += h.kernedWidth - h.width, d += h.width) : d += h.kernedWidth, u && !c && this._reSpaceAndTab.test(i[p]) && (c = !0), c || (o = o || this.getCompleteStyleDeclaration(s, p), a = this.getCompleteStyleDeclaration(s, p + 1), c = this._hasStyleChanged(o, a)), c && (this._renderChar(t, e, s, p, f, r, n, l), f = "", o = a, r += d, d = 0);
                            e.restore() }, _renderChar: function(t, e, i, r, n, s, o) { var a = this._getStyleDeclaration(i, r),
                                h = this.getCompleteStyleDeclaration(i, r),
                                c = "fillText" === t && h.fill,
                                l = "strokeText" === t && h.stroke && h.strokeWidth;
                            (l || c) && (a && e.save(), this._applyCharStyles(t, e, i, r, h), a && a.textBackgroundColor && this._removeShadow(e), a && a.deltaY && (o += a.deltaY), c && e.fillText(n, s, o), l && e.strokeText(n, s, o), a && e.restore()) }, setSuperscript: function(t, e) { return this._setScript(t, e, this.superscript) }, setSubscript: function(t, e) { return this._setScript(t, e, this.subscript) }, _setScript: function(t, e, i) { var r = this.get2DCursorLocation(t, !0),
                                n = this.getValueOfPropertyAt(r.lineIndex, r.charIndex, "fontSize"),
                                s = this.getValueOfPropertyAt(r.lineIndex, r.charIndex, "deltaY"),
                                o = { fontSize: n * i.size, deltaY: s + n * i.baseline }; return this.setSelectionStyles(o, t, e), this }, _hasStyleChanged: function(t, e) { return t.fill !== e.fill || t.stroke !== e.stroke || t.strokeWidth !== e.strokeWidth || t.fontSize !== e.fontSize || t.fontFamily !== e.fontFamily || t.fontWeight !== e.fontWeight || t.fontStyle !== e.fontStyle || t.deltaY !== e.deltaY }, _hasStyleChangedForSvg: function(t, e) { return this._hasStyleChanged(t, e) || t.overline !== e.overline || t.underline !== e.underline || t.linethrough !== e.linethrough }, _getLineLeftOffset: function(t) { var e = this.getLineWidth(t); return "center" === this.textAlign ? (this.width - e) / 2 : "right" === this.textAlign ? this.width - e : "justify-center" === this.textAlign && this.isEndOfWrapping(t) ? (this.width - e) / 2 : "justify-right" === this.textAlign && this.isEndOfWrapping(t) ? this.width - e : 0 }, _clearCache: function() { this.__lineWidths = [], this.__lineHeights = [], this.__charBounds = [] }, _shouldClearDimensionCache: function() { var t = this._forceClearCache; return t || (t = this.hasStateChanged("_dimensionAffectingProps")), t && (this.dirty = !0, this._forceClearCache = !1), t }, getLineWidth: function(t) { return this.__lineWidths[t] ? this.__lineWidths[t] : (e = "" === this._textLines[t] ? 0 : this.measureLine(t).width, this.__lineWidths[t] = e, e); var e }, _getWidthOfCharSpacing: function() { return 0 !== this.charSpacing ? this.fontSize * this.charSpacing / 1e3 : 0 }, getValueOfPropertyAt: function(t, e, i) { var r = this._getStyleDeclaration(t, e); return r && void 0 !== r[i] ? r[i] : this[i] }, _renderTextDecoration: function(t, e) { if (this[e] || this.styleHas(e)) { for (var i, r, n, s, o, a, h, c, l, u, f, d, g, p, v, m, _ = this._getLeftOffset(), y = this._getTopOffset(), b = this._getWidthOfCharSpacing(), x = 0, C = this._textLines.length; x < C; x++)
                                    if (i = this.getHeightOfLine(x), this[e] || this.styleHas(e, x)) { h = this._textLines[x], p = i / this.lineHeight, s = this._getLineLeftOffset(x), u = 0, f = 0, c = this.getValueOfPropertyAt(x, 0, e), m = this.getValueOfPropertyAt(x, 0, "fill"), l = y + p * (1 - this._fontSizeFraction), r = this.getHeightOfChar(x, 0), o = this.getValueOfPropertyAt(x, 0, "deltaY"); for (var w = 0, S = h.length; w < S; w++) d = this.__charBounds[x][w], g = this.getValueOfPropertyAt(x, w, e), v = this.getValueOfPropertyAt(x, w, "fill"), n = this.getHeightOfChar(x, w), a = this.getValueOfPropertyAt(x, w, "deltaY"), (g !== c || v !== m || n !== r || a !== o) && f > 0 ? (t.fillStyle = m, c && m && t.fillRect(_ + s + u, l + this.offsets[e] * r + o, f, this.fontSize / 15), u = d.left, f = d.width, c = g, m = v, r = n, o = a) : f += d.kernedWidth;
                                        t.fillStyle = v, g && v && t.fillRect(_ + s + u, l + this.offsets[e] * r + o, f - b, this.fontSize / 15), y += i } else y += i;
                                this._removeShadow(t) } }, _getFontDeclaration: function(t, i) { var r = t || this,
                                n = this.fontFamily,
                                s = e.Text.genericFonts.indexOf(n.toLowerCase()) > -1,
                                o = void 0 === n || n.indexOf("'") > -1 || n.indexOf(",") > -1 || n.indexOf('"') > -1 || s ? r.fontFamily : '"' + r.fontFamily + '"'; return [e.isLikelyNode ? r.fontWeight : r.fontStyle, e.isLikelyNode ? r.fontStyle : r.fontWeight, i ? this.CACHE_FONT_SIZE + "px" : r.fontSize + "px", o].join(" ") }, render: function(t) { this.visible && (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen() || (this._shouldClearDimensionCache() && this.initDimensions(), this.callSuper("render", t))) }, _splitTextIntoLines: function(t) { for (var i = t.split(this._reNewline), r = new Array(i.length), n = ["\n"], s = [], o = 0; o < i.length; o++) r[o] = e.util.string.graphemeSplit(i[o]), s = s.concat(r[o], n); return s.pop(), { _unwrappedLines: r, lines: i, graphemeText: s, graphemeLines: r } }, toObject: function(t) { var e = ["text", "fontSize", "fontWeight", "fontFamily", "fontStyle", "lineHeight", "underline", "overline", "linethrough", "textAlign", "textBackgroundColor", "charSpacing"].concat(t),
                                r = this.callSuper("toObject", e); return r.styles = i(this.styles, !0), r }, set: function(t, e) { this.callSuper("set", t, e); var i = !1; if ("object" == typeof t)
                                for (var r in t) i = i || -1 !== this._dimensionAffectingProps.indexOf(r);
                            else i = -1 !== this._dimensionAffectingProps.indexOf(t); return i && (this.initDimensions(), this.setCoords()), this }, complexity: function() { return 1 } }), e.Text.ATTRIBUTE_NAMES = e.SHARED_ATTRIBUTES.concat("x y dx dy font-family font-style font-weight font-size letter-spacing text-decoration text-anchor".split(" ")), e.Text.DEFAULT_SVG_FONT_SIZE = 16, e.Text.fromElement = function(t, r, n) { if (!t) return r(null); var s = e.parseAttributes(t, e.Text.ATTRIBUTE_NAMES),
                            o = s.textAnchor || "left"; if ((n = e.util.object.extend(n ? i(n) : {}, s)).top = n.top || 0, n.left = n.left || 0, s.textDecoration) { var a = s.textDecoration; - 1 !== a.indexOf("underline") && (n.underline = !0), -1 !== a.indexOf("overline") && (n.overline = !0), -1 !== a.indexOf("line-through") && (n.linethrough = !0), delete n.textDecoration } "dx" in s && (n.left += s.dx), "dy" in s && (n.top += s.dy), "fontSize" in n || (n.fontSize = e.Text.DEFAULT_SVG_FONT_SIZE); var h = ""; "textContent" in t ? h = t.textContent : "firstChild" in t && null !== t.firstChild && "data" in t.firstChild && null !== t.firstChild.data && (h = t.firstChild.data), h = h.replace(/^\s+|\s+$|\n+/g, "").replace(/\s+/g, " "); var c = n.strokeWidth;
                        n.strokeWidth = 0; var l = new e.Text(h, n),
                            u = l.getScaledHeight() / l.height,
                            f = ((l.height + l.strokeWidth) * l.lineHeight - l.height) * u,
                            d = l.getScaledHeight() + f,
                            g = 0; "center" === o && (g = l.getScaledWidth() / 2), "right" === o && (g = l.getScaledWidth()), l.set({ left: l.left - g, top: l.top - (d - l.fontSize * (.07 + l._fontSizeFraction)) / l.lineHeight, strokeWidth: void 0 !== c ? c : 1 }), r(l) }, e.Text.fromObject = function(t, i) { return e.Object._fromObject("Text", t, i, "text") }, e.Text.genericFonts = ["sans-serif", "serif", "cursive", "fantasy", "monospace"], e.util.createAccessors && e.util.createAccessors(e.Text)) }(e), r.util.object.extend(r.Text.prototype, { isEmptyStyles: function(t) { if (!this.styles) return !0; if (void 0 !== t && !this.styles[t]) return !0; var e = void 0 === t ? this.styles : { line: this.styles[t] }; for (var i in e)
                            for (var r in e[i])
                                for (var n in e[i][r]) return !1; return !0 }, styleHas: function(t, e) { if (!this.styles || !t || "" === t) return !1; if (void 0 !== e && !this.styles[e]) return !1; var i = void 0 === e ? this.styles : { 0: this.styles[e] }; for (var r in i)
                            for (var n in i[r])
                                if (void 0 !== i[r][n][t]) return !0; return !1 }, cleanStyle: function(t) { if (!this.styles || !t || "" === t) return !1; var e, i, r = this.styles,
                            n = 0,
                            s = !0,
                            o = 0; for (var a in r) { for (var h in e = 0, r[a]) { var c;
                                n++, (c = r[a][h]).hasOwnProperty(t) ? (i ? c[t] !== i && (s = !1) : i = c[t], c[t] === this[t] && delete c[t]) : s = !1, 0 !== Object.keys(c).length ? e++ : delete r[a][h] } 0 === e && delete r[a] } for (var l = 0; l < this._textLines.length; l++) o += this._textLines[l].length;
                        s && n === o && (this[t] = i, this.removeStyle(t)) }, removeStyle: function(t) { if (this.styles && t && "" !== t) { var e, i, r, n = this.styles; for (i in n) { for (r in e = n[i]) delete e[r][t], 0 === Object.keys(e[r]).length && delete e[r];
                                0 === Object.keys(e).length && delete n[i] } } }, _extendStyles: function(t, e) { var i = this.get2DCursorLocation(t);
                        this._getLineStyle(i.lineIndex) || this._setLineStyle(i.lineIndex), this._getStyleDeclaration(i.lineIndex, i.charIndex) || this._setStyleDeclaration(i.lineIndex, i.charIndex, {}), r.util.object.extend(this._getStyleDeclaration(i.lineIndex, i.charIndex), e) }, get2DCursorLocation: function(t, e) { void 0 === t && (t = this.selectionStart); for (var i = e ? this._unwrappedTextLines : this._textLines, r = i.length, n = 0; n < r; n++) { if (t <= i[n].length) return { lineIndex: n, charIndex: t };
                            t -= i[n].length + this.missingNewlineOffset(n) } return { lineIndex: n - 1, charIndex: i[n - 1].length < t ? i[n - 1].length : t } }, getSelectionStyles: function(t, e, i) { void 0 === t && (t = this.selectionStart || 0), void 0 === e && (e = this.selectionEnd || t); for (var r = [], n = t; n < e; n++) r.push(this.getStyleAtPosition(n, i)); return r }, getStyleAtPosition: function(t, e) { var i = this.get2DCursorLocation(t); return (e ? this.getCompleteStyleDeclaration(i.lineIndex, i.charIndex) : this._getStyleDeclaration(i.lineIndex, i.charIndex)) || {} }, setSelectionStyles: function(t, e, i) { void 0 === e && (e = this.selectionStart || 0), void 0 === i && (i = this.selectionEnd || e); for (var r = e; r < i; r++) this._extendStyles(r, t); return this._forceClearCache = !0, this }, _getStyleDeclaration: function(t, e) { var i = this.styles && this.styles[t]; return i ? i[e] : null }, getCompleteStyleDeclaration: function(t, e) { for (var i, r = this._getStyleDeclaration(t, e) || {}, n = {}, s = 0; s < this._styleProperties.length; s++) n[i = this._styleProperties[s]] = void 0 === r[i] ? this[i] : r[i]; return n }, _setStyleDeclaration: function(t, e, i) { this.styles[t][e] = i }, _deleteStyleDeclaration: function(t, e) { delete this.styles[t][e] }, _getLineStyle: function(t) { return !!this.styles[t] }, _setLineStyle: function(t) { this.styles[t] = {} }, _deleteLineStyle: function(t) { delete this.styles[t] } }),
                function() {
                    function t(t) { t.textDecoration && (t.textDecoration.indexOf("underline") > -1 && (t.underline = !0), t.textDecoration.indexOf("line-through") > -1 && (t.linethrough = !0), t.textDecoration.indexOf("overline") > -1 && (t.overline = !0), delete t.textDecoration) } r.IText = r.util.createClass(r.Text, r.Observable, { type: "i-text", selectionStart: 0, selectionEnd: 0, selectionColor: "rgba(17,119,255,0.3)", isEditing: !1, editable: !0, editingBorderColor: "rgba(102,153,255,0.25)", cursorWidth: 2, cursorColor: "#333", cursorDelay: 1e3, cursorDuration: 600, caching: !0, _reSpace: /\s|\n/, _currentCursorOpacity: 0, _selectionDirection: null, _abortCursorAnimation: !1, __widthOfSpace: [], inCompositionMode: !1, initialize: function(t, e) { this.callSuper("initialize", t, e), this.initBehavior() }, setSelectionStart: function(t) { t = Math.max(t, 0), this._updateAndFire("selectionStart", t) }, setSelectionEnd: function(t) { t = Math.min(t, this.text.length), this._updateAndFire("selectionEnd", t) }, _updateAndFire: function(t, e) { this[t] !== e && (this._fireSelectionChanged(), this[t] = e), this._updateTextarea() }, _fireSelectionChanged: function() { this.fire("selection:changed"), this.canvas && this.canvas.fire("text:selection:changed", { target: this }) }, initDimensions: function() { this.isEditing && this.initDelayedCursor(), this.clearContextTop(), this.callSuper("initDimensions") }, render: function(t) { this.clearContextTop(), this.callSuper("render", t), this.cursorOffsetCache = {}, this.renderCursorOrSelection() }, _render: function(t) { this.callSuper("_render", t) }, clearContextTop: function(t) { if (this.isEditing && this.canvas && this.canvas.contextTop) { var e = this.canvas.contextTop,
                                    i = this.canvas.viewportTransform;
                                e.save(), e.transform(i[0], i[1], i[2], i[3], i[4], i[5]), this.transform(e), this.transformMatrix && e.transform.apply(e, this.transformMatrix), this._clearTextArea(e), t || e.restore() } }, renderCursorOrSelection: function() { if (this.isEditing && this.canvas && this.canvas.contextTop) { var t = this._getCursorBoundaries(),
                                    e = this.canvas.contextTop;
                                this.clearContextTop(!0), this.selectionStart === this.selectionEnd ? this.renderCursor(t, e) : this.renderSelection(t, e), e.restore() } }, _clearTextArea: function(t) { var e = this.width + 4,
                                i = this.height + 4;
                            t.clearRect(-e / 2, -i / 2, e, i) }, _getCursorBoundaries: function(t) { void 0 === t && (t = this.selectionStart); var e = this._getLeftOffset(),
                                i = this._getTopOffset(),
                                r = this._getCursorBoundariesOffsets(t); return { left: e, top: i, leftOffset: r.left, topOffset: r.top } }, _getCursorBoundariesOffsets: function(t) { if (this.cursorOffsetCache && "top" in this.cursorOffsetCache) return this.cursorOffsetCache; var e, i, r, n, s = 0,
                                o = 0,
                                a = this.get2DCursorLocation(t);
                            r = a.charIndex, i = a.lineIndex; for (var h = 0; h < i; h++) s += this.getHeightOfLine(h);
                            e = this._getLineLeftOffset(i); var c = this.__charBounds[i][r]; return c && (o = c.left), 0 !== this.charSpacing && r === this._textLines[i].length && (o -= this._getWidthOfCharSpacing()), n = { top: s, left: e + (o > 0 ? o : 0) }, this.cursorOffsetCache = n, this.cursorOffsetCache }, renderCursor: function(t, e) { var i = this.get2DCursorLocation(),
                                r = i.lineIndex,
                                n = i.charIndex > 0 ? i.charIndex - 1 : 0,
                                s = this.getValueOfPropertyAt(r, n, "fontSize"),
                                o = this.scaleX * this.canvas.getZoom(),
                                a = this.cursorWidth / o,
                                h = t.topOffset,
                                c = this.getValueOfPropertyAt(r, n, "deltaY");
                            h += (1 - this._fontSizeFraction) * this.getHeightOfLine(r) / this.lineHeight - s * (1 - this._fontSizeFraction), this.inCompositionMode && this.renderSelection(t, e), e.fillStyle = this.getValueOfPropertyAt(r, n, "fill"), e.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity, e.fillRect(t.left + t.leftOffset - a / 2, h + t.top + c, a, s) }, renderSelection: function(t, e) { for (var i = this.inCompositionMode ? this.hiddenTextarea.selectionStart : this.selectionStart, r = this.inCompositionMode ? this.hiddenTextarea.selectionEnd : this.selectionEnd, n = -1 !== this.textAlign.indexOf("justify"), s = this.get2DCursorLocation(i), o = this.get2DCursorLocation(r), a = s.lineIndex, h = o.lineIndex, c = s.charIndex < 0 ? 0 : s.charIndex, l = o.charIndex < 0 ? 0 : o.charIndex, u = a; u <= h; u++) { var f, d = this._getLineLeftOffset(u) || 0,
                                    g = this.getHeightOfLine(u),
                                    p = 0,
                                    v = 0; if (u === a && (p = this.__charBounds[a][c].left), u >= a && u < h) v = n && !this.isEndOfWrapping(u) ? this.width : this.getLineWidth(u) || 5;
                                else if (u === h)
                                    if (0 === l) v = this.__charBounds[h][l].left;
                                    else { var m = this._getWidthOfCharSpacing();
                                        v = this.__charBounds[h][l - 1].left + this.__charBounds[h][l - 1].width - m } f = g, (this.lineHeight < 1 || u === h && this.lineHeight > 1) && (g /= this.lineHeight), this.inCompositionMode ? (e.fillStyle = this.compositionColor || "black", e.fillRect(t.left + d + p, t.top + t.topOffset + g, v - p, 1)) : (e.fillStyle = this.selectionColor, e.fillRect(t.left + d + p, t.top + t.topOffset, v - p, g)), t.topOffset += f } }, getCurrentCharFontSize: function() { var t = this._getCurrentCharIndex(); return this.getValueOfPropertyAt(t.l, t.c, "fontSize") }, getCurrentCharColor: function() { var t = this._getCurrentCharIndex(); return this.getValueOfPropertyAt(t.l, t.c, "fill") }, _getCurrentCharIndex: function() { var t = this.get2DCursorLocation(this.selectionStart, !0),
                                e = t.charIndex > 0 ? t.charIndex - 1 : 0; return { l: t.lineIndex, c: e } } }), r.IText.fromObject = function(e, i) { if (t(e), e.styles)
                            for (var n in e.styles)
                                for (var s in e.styles[n]) t(e.styles[n][s]);
                        r.Object._fromObject("IText", e, i, "text") } }(),
                function() { var t = r.util.object.clone;
                    r.util.object.extend(r.IText.prototype, { initBehavior: function() { this.initAddedHandler(), this.initRemovedHandler(), this.initCursorSelectionHandlers(), this.initDoubleClickSimulation(), this.mouseMoveHandler = this.mouseMoveHandler.bind(this) }, onDeselect: function() { this.isEditing && this.exitEditing(), this.selected = !1 }, initAddedHandler: function() { var t = this;
                            this.on("added", function() { var e = t.canvas;
                                e && (e._hasITextHandlers || (e._hasITextHandlers = !0, t._initCanvasHandlers(e)), e._iTextInstances = e._iTextInstances || [], e._iTextInstances.push(t)) }) }, initRemovedHandler: function() { var t = this;
                            this.on("removed", function() { var e = t.canvas;
                                e && (e._iTextInstances = e._iTextInstances || [], r.util.removeFromArray(e._iTextInstances, t), 0 === e._iTextInstances.length && (e._hasITextHandlers = !1, t._removeCanvasHandlers(e))) }) }, _initCanvasHandlers: function(t) { t._mouseUpITextHandler = function() { t._iTextInstances && t._iTextInstances.forEach(function(t) { t.__isMousedown = !1 }) }, t.on("mouse:up", t._mouseUpITextHandler) }, _removeCanvasHandlers: function(t) { t.off("mouse:up", t._mouseUpITextHandler) }, _tick: function() { this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, "_onTickComplete") }, _animateCursor: function(t, e, i, r) { var n; return n = { isAborted: !1, abort: function() { this.isAborted = !0 } }, t.animate("_currentCursorOpacity", e, { duration: i, onComplete: function() { n.isAborted || t[r]() }, onChange: function() { t.canvas && t.selectionStart === t.selectionEnd && t.renderCursorOrSelection() }, abort: function() { return n.isAborted } }), n }, _onTickComplete: function() { var t = this;
                            this._cursorTimeout1 && clearTimeout(this._cursorTimeout1), this._cursorTimeout1 = setTimeout(function() { t._currentTickCompleteState = t._animateCursor(t, 0, this.cursorDuration / 2, "_tick") }, 100) }, initDelayedCursor: function(t) { var e = this,
                                i = t ? 0 : this.cursorDelay;
                            this.abortCursorAnimation(), this._currentCursorOpacity = 1, this._cursorTimeout2 = setTimeout(function() { e._tick() }, i) }, abortCursorAnimation: function() { var t = this._currentTickState || this._currentTickCompleteState,
                                e = this.canvas;
                            this._currentTickState && this._currentTickState.abort(), this._currentTickCompleteState && this._currentTickCompleteState.abort(), clearTimeout(this._cursorTimeout1), clearTimeout(this._cursorTimeout2), this._currentCursorOpacity = 0, t && e && e.clearContext(e.contextTop || e.contextContainer) }, selectAll: function() { return this.selectionStart = 0, this.selectionEnd = this._text.length, this._fireSelectionChanged(), this._updateTextarea(), this }, getSelectedText: function() { return this._text.slice(this.selectionStart, this.selectionEnd).join("") }, findWordBoundaryLeft: function(t) { var e = 0,
                                i = t - 1; if (this._reSpace.test(this._text[i]))
                                for (; this._reSpace.test(this._text[i]);) e++, i--; for (;
                                /\S/.test(this._text[i]) && i > -1;) e++, i--; return t - e }, findWordBoundaryRight: function(t) { var e = 0,
                                i = t; if (this._reSpace.test(this._text[i]))
                                for (; this._reSpace.test(this._text[i]);) e++, i++; for (;
                                /\S/.test(this._text[i]) && i < this._text.length;) e++, i++; return t + e }, findLineBoundaryLeft: function(t) { for (var e = 0, i = t - 1; !/\n/.test(this._text[i]) && i > -1;) e++, i--; return t - e }, findLineBoundaryRight: function(t) { for (var e = 0, i = t; !/\n/.test(this._text[i]) && i < this._text.length;) e++, i++; return t + e }, searchWordBoundary: function(t, e) { for (var i = this._reSpace.test(this._text[t]) ? t - 1 : t, r = this._text[i], n = /[ \n\.,;!\?\-]/; !n.test(r) && i > 0 && i < this._text.length;) i += e, r = this._text[i]; return n.test(r) && "\n" !== r && (i += 1 === e ? 0 : 1), i }, selectWord: function(t) { t = t || this.selectionStart; var e = this.searchWordBoundary(t, -1),
                                i = this.searchWordBoundary(t, 1);
                            this.selectionStart = e, this.selectionEnd = i, this._fireSelectionChanged(), this._updateTextarea(), this.renderCursorOrSelection() }, selectLine: function(t) { t = t || this.selectionStart; var e = this.findLineBoundaryLeft(t),
                                i = this.findLineBoundaryRight(t); return this.selectionStart = e, this.selectionEnd = i, this._fireSelectionChanged(), this._updateTextarea(), this }, enterEditing: function(t) { if (!this.isEditing && this.editable) return this.canvas && (this.canvas.calcOffset(), this.exitEditingOnOthers(this.canvas)), this.isEditing = !0, this.initHiddenTextarea(t), this.hiddenTextarea.focus(), this.hiddenTextarea.value = this.text, this._updateTextarea(), this._saveEditingProps(), this._setEditingProps(), this._textBeforeEdit = this.text, this._tick(), this.fire("editing:entered"), this._fireSelectionChanged(), this.canvas ? (this.canvas.fire("text:editing:entered", { target: this }), this.initMouseMoveHandler(), this.canvas.requestRenderAll(), this) : this }, exitEditingOnOthers: function(t) { t._iTextInstances && t._iTextInstances.forEach(function(t) { t.selected = !1, t.isEditing && t.exitEditing() }) }, initMouseMoveHandler: function() { this.canvas.on("mouse:move", this.mouseMoveHandler) }, mouseMoveHandler: function(t) { if (this.__isMousedown && this.isEditing) { var e = this.getSelectionStartFromPointer(t.e),
                                    i = this.selectionStart,
                                    r = this.selectionEnd;
                                (e === this.__selectionStartOnMouseDown && i !== r || i !== e && r !== e) && (e > this.__selectionStartOnMouseDown ? (this.selectionStart = this.__selectionStartOnMouseDown, this.selectionEnd = e) : (this.selectionStart = e, this.selectionEnd = this.__selectionStartOnMouseDown), this.selectionStart === i && this.selectionEnd === r || (this.restartCursorIfNeeded(), this._fireSelectionChanged(), this._updateTextarea(), this.renderCursorOrSelection())) } }, _setEditingProps: function() { this.hoverCursor = "text", this.canvas && (this.canvas.defaultCursor = this.canvas.moveCursor = "text"), this.borderColor = this.editingBorderColor, this.hasControls = this.selectable = !1, this.lockMovementX = this.lockMovementY = !0 }, fromStringToGraphemeSelection: function(t, e, i) { var n = i.slice(0, t),
                                s = r.util.string.graphemeSplit(n).length; if (t === e) return { selectionStart: s, selectionEnd: s }; var o = i.slice(t, e); return { selectionStart: s, selectionEnd: s + r.util.string.graphemeSplit(o).length } }, fromGraphemeToStringSelection: function(t, e, i) { var r = i.slice(0, t).join("").length; return t === e ? { selectionStart: r, selectionEnd: r } : { selectionStart: r, selectionEnd: r + i.slice(t, e).join("").length } }, _updateTextarea: function() { if (this.cursorOffsetCache = {}, this.hiddenTextarea) { if (!this.inCompositionMode) { var t = this.fromGraphemeToStringSelection(this.selectionStart, this.selectionEnd, this._text);
                                    this.hiddenTextarea.selectionStart = t.selectionStart, this.hiddenTextarea.selectionEnd = t.selectionEnd } this.updateTextareaPosition() } }, updateFromTextArea: function() { if (this.hiddenTextarea) { this.cursorOffsetCache = {}, this.text = this.hiddenTextarea.value, this._shouldClearDimensionCache() && (this.initDimensions(), this.setCoords()); var t = this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value);
                                this.selectionEnd = this.selectionStart = t.selectionEnd, this.inCompositionMode || (this.selectionStart = t.selectionStart), this.updateTextareaPosition() } }, updateTextareaPosition: function() { if (this.selectionStart === this.selectionEnd) { var t = this._calcTextareaPosition();
                                this.hiddenTextarea.style.left = t.left, this.hiddenTextarea.style.top = t.top } }, _calcTextareaPosition: function() { if (!this.canvas) return { x: 1, y: 1 }; var t = this.inCompositionMode ? this.compositionStart : this.selectionStart,
                                e = this._getCursorBoundaries(t),
                                i = this.get2DCursorLocation(t),
                                n = i.lineIndex,
                                s = i.charIndex,
                                o = this.getValueOfPropertyAt(n, s, "fontSize") * this.lineHeight,
                                a = e.leftOffset,
                                h = this.calcTransformMatrix(),
                                c = { x: e.left + a, y: e.top + e.topOffset + o },
                                l = this.canvas.upperCanvasEl,
                                u = l.width,
                                f = l.height,
                                d = u - o,
                                g = f - o,
                                p = l.clientWidth / u,
                                v = l.clientHeight / f; return c = r.util.transformPoint(c, h), (c = r.util.transformPoint(c, this.canvas.viewportTransform)).x *= p, c.y *= v, c.x < 0 && (c.x = 0), c.x > d && (c.x = d), c.y < 0 && (c.y = 0), c.y > g && (c.y = g), c.x += this.canvas._offset.left, c.y += this.canvas._offset.top, { left: c.x + "px", top: c.y + "px", fontSize: o + "px", charHeight: o } }, _saveEditingProps: function() { this._savedProps = { hasControls: this.hasControls, borderColor: this.borderColor, lockMovementX: this.lockMovementX, lockMovementY: this.lockMovementY, hoverCursor: this.hoverCursor, selectable: this.selectable, defaultCursor: this.canvas && this.canvas.defaultCursor, moveCursor: this.canvas && this.canvas.moveCursor } }, _restoreEditingProps: function() { this._savedProps && (this.hoverCursor = this._savedProps.hoverCursor, this.hasControls = this._savedProps.hasControls, this.borderColor = this._savedProps.borderColor, this.selectable = this._savedProps.selectable, this.lockMovementX = this._savedProps.lockMovementX, this.lockMovementY = this._savedProps.lockMovementY, this.canvas && (this.canvas.defaultCursor = this._savedProps.defaultCursor, this.canvas.moveCursor = this._savedProps.moveCursor)) }, exitEditing: function() { var t = this._textBeforeEdit !== this.text; return this.selected = !1, this.isEditing = !1, this.selectionEnd = this.selectionStart, this.hiddenTextarea && (this.hiddenTextarea.blur && this.hiddenTextarea.blur(), this.canvas && this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea), this.hiddenTextarea = null), this.abortCursorAnimation(), this._restoreEditingProps(), this._currentCursorOpacity = 0, this._shouldClearDimensionCache() && (this.initDimensions(), this.setCoords()), this.fire("editing:exited"), t && this.fire("modified"), this.canvas && (this.canvas.off("mouse:move", this.mouseMoveHandler), this.canvas.fire("text:editing:exited", { target: this }), t && this.canvas.fire("object:modified", { target: this })), this }, _removeExtraneousStyles: function() { for (var t in this.styles) this._textLines[t] || delete this.styles[t] }, removeStyleFromTo: function(t, e) { var i, r, n = this.get2DCursorLocation(t, !0),
                                s = this.get2DCursorLocation(e, !0),
                                o = n.lineIndex,
                                a = n.charIndex,
                                h = s.lineIndex,
                                c = s.charIndex; if (o !== h) { if (this.styles[o])
                                    for (i = a; i < this._unwrappedTextLines[o].length; i++) delete this.styles[o][i]; if (this.styles[h])
                                    for (i = c; i < this._unwrappedTextLines[h].length; i++)(r = this.styles[h][i]) && (this.styles[o] || (this.styles[o] = {}), this.styles[o][a + i - c] = r); for (i = o + 1; i <= h; i++) delete this.styles[i];
                                this.shiftLineStyles(h, o - h) } else if (this.styles[o]) { r = this.styles[o]; var l, u, f = c - a; for (i = a; i < c; i++) delete r[i]; for (u in this.styles[o])(l = parseInt(u, 10)) >= c && (r[l - f] = r[u], delete r[u]) } }, shiftLineStyles: function(e, i) { var r = t(this.styles); for (var n in this.styles) { var s = parseInt(n, 10);
                                s > e && (this.styles[s + i] = r[s], r[s - i] || delete this.styles[s]) } }, restartCursorIfNeeded: function() { this._currentTickState && !this._currentTickState.isAborted && this._currentTickCompleteState && !this._currentTickCompleteState.isAborted || this.initDelayedCursor() }, insertNewlineStyleObject: function(e, i, r, n) { var s, o = {},
                                a = !1; for (var h in r || (r = 1), this.shiftLineStyles(e, r), this.styles[e] && (s = this.styles[e][0 === i ? i : i - 1]), this.styles[e]) { var c = parseInt(h, 10);
                                c >= i && (a = !0, o[c - i] = this.styles[e][h], delete this.styles[e][h]) } for (a ? this.styles[e + r] = o : delete this.styles[e + r]; r > 1;) r--, n && n[r] ? this.styles[e + r] = { 0: t(n[r]) } : s ? this.styles[e + r] = { 0: t(s) } : delete this.styles[e + r];
                            this._forceClearCache = !0 }, insertCharStyleObject: function(e, i, r, n) { this.styles || (this.styles = {}); var s = this.styles[e],
                                o = s ? t(s) : {}; for (var a in r || (r = 1), o) { var h = parseInt(a, 10);
                                h >= i && (s[h + r] = o[h], o[h - r] || delete s[h]) } if (this._forceClearCache = !0, n)
                                for (; r--;) Object.keys(n[r]).length && (this.styles[e] || (this.styles[e] = {}), this.styles[e][i + r] = t(n[r]));
                            else if (s)
                                for (var c = s[i ? i - 1 : 1]; c && r--;) this.styles[e][i + r] = t(c) }, insertNewStyleBlock: function(t, e, i) { for (var r = this.get2DCursorLocation(e, !0), n = [0], s = 0, o = 0; o < t.length; o++) "\n" === t[o] ? n[++s] = 0 : n[s]++;
                            n[0] > 0 && (this.insertCharStyleObject(r.lineIndex, r.charIndex, n[0], i), i = i && i.slice(n[0] + 1)), s && this.insertNewlineStyleObject(r.lineIndex, r.charIndex + n[0], s); for (o = 1; o < s; o++) n[o] > 0 ? this.insertCharStyleObject(r.lineIndex + o, 0, n[o], i) : i && (this.styles[r.lineIndex + o][0] = i[0]), i = i && i.slice(n[o] + 1);
                            n[o] > 0 && this.insertCharStyleObject(r.lineIndex + o, 0, n[o], i) }, setSelectionStartEndWithShift: function(t, e, i) { i <= t ? (e === t ? this._selectionDirection = "left" : "right" === this._selectionDirection && (this._selectionDirection = "left", this.selectionEnd = t), this.selectionStart = i) : i > t && i < e ? "right" === this._selectionDirection ? this.selectionEnd = i : this.selectionStart = i : (e === t ? this._selectionDirection = "right" : "left" === this._selectionDirection && (this._selectionDirection = "right", this.selectionStart = e), this.selectionEnd = i) }, setSelectionInBoundaries: function() { var t = this.text.length;
                            this.selectionStart > t ? this.selectionStart = t : this.selectionStart < 0 && (this.selectionStart = 0), this.selectionEnd > t ? this.selectionEnd = t : this.selectionEnd < 0 && (this.selectionEnd = 0) } }) }(), r.util.object.extend(r.IText.prototype, { initDoubleClickSimulation: function() { this.__lastClickTime = +new Date, this.__lastLastClickTime = +new Date, this.__lastPointer = {}, this.on("mousedown", this.onMouseDown) }, onMouseDown: function(t) { if (this.canvas) { this.__newClickTime = +new Date; var e = t.pointer;
                            this.isTripleClick(e) && (this.fire("tripleclick", t), this._stopEvent(t.e)), this.__lastLastClickTime = this.__lastClickTime, this.__lastClickTime = this.__newClickTime, this.__lastPointer = e, this.__lastIsEditing = this.isEditing, this.__lastSelected = this.selected } }, isTripleClick: function(t) { return this.__newClickTime - this.__lastClickTime < 500 && this.__lastClickTime - this.__lastLastClickTime < 500 && this.__lastPointer.x === t.x && this.__lastPointer.y === t.y }, _stopEvent: function(t) { t.preventDefault && t.preventDefault(), t.stopPropagation && t.stopPropagation() }, initCursorSelectionHandlers: function() { this.initMousedownHandler(), this.initMouseupHandler(), this.initClicks() }, initClicks: function() { this.on("mousedblclick", function(t) { this.selectWord(this.getSelectionStartFromPointer(t.e)) }), this.on("tripleclick", function(t) { this.selectLine(this.getSelectionStartFromPointer(t.e)) }) }, _mouseDownHandler: function(t) {!this.canvas || !this.editable || t.e.button && 1 !== t.e.button || (this.__isMousedown = !0, this.selected && this.setCursorByClick(t.e), this.isEditing && (this.__selectionStartOnMouseDown = this.selectionStart, this.selectionStart === this.selectionEnd && this.abortCursorAnimation(), this.renderCursorOrSelection())) }, _mouseDownHandlerBefore: function(t) {!this.canvas || !this.editable || t.e.button && 1 !== t.e.button || this === this.canvas._activeObject && (this.selected = !0) }, initMousedownHandler: function() { this.on("mousedown", this._mouseDownHandler), this.on("mousedown:before", this._mouseDownHandlerBefore) }, initMouseupHandler: function() { this.on("mouseup", this.mouseUpHandler) }, mouseUpHandler: function(t) { if (this.__isMousedown = !1, !(!this.editable || this.group || t.transform && t.transform.actionPerformed || t.e.button && 1 !== t.e.button)) { if (this.canvas) { var e = this.canvas._activeObject; if (e && e !== this) return } this.__lastSelected && !this.__corner ? (this.selected = !1, this.__lastSelected = !1, this.enterEditing(t.e), this.selectionStart === this.selectionEnd ? this.initDelayedCursor(!0) : this.renderCursorOrSelection()) : this.selected = !0 } }, setCursorByClick: function(t) { var e = this.getSelectionStartFromPointer(t),
                            i = this.selectionStart,
                            r = this.selectionEnd;
                        t.shiftKey ? this.setSelectionStartEndWithShift(i, r, e) : (this.selectionStart = e, this.selectionEnd = e), this.isEditing && (this._fireSelectionChanged(), this._updateTextarea()) }, getSelectionStartFromPointer: function(t) { for (var e = this.getLocalPointer(t), i = 0, r = 0, n = 0, s = 0, o = 0, a = 0, h = this._textLines.length; a < h && n <= e.y; a++) n += this.getHeightOfLine(a) * this.scaleY, o = a, a > 0 && (s += this._textLines[a - 1].length + this.missingNewlineOffset(a - 1));
                        r = this._getLineLeftOffset(o) * this.scaleX; for (var c = 0, l = this._textLines[o].length; c < l && (i = r, (r += this.__charBounds[o][c].kernedWidth * this.scaleX) <= e.x); c++) s++; return this._getNewSelectionStartFromOffset(e, i, r, s, l) }, _getNewSelectionStartFromOffset: function(t, e, i, r, n) { var s = t.x - e,
                            o = i - t.x,
                            a = r + (o > s || o < 0 ? 0 : 1); return this.flipX && (a = n - a), a > this._text.length && (a = this._text.length), a } }), r.util.object.extend(r.IText.prototype, { initHiddenTextarea: function() { this.hiddenTextarea = r.document.createElement("textarea"), this.hiddenTextarea.setAttribute("autocapitalize", "off"), this.hiddenTextarea.setAttribute("autocorrect", "off"), this.hiddenTextarea.setAttribute("autocomplete", "off"), this.hiddenTextarea.setAttribute("spellcheck", "false"), this.hiddenTextarea.setAttribute("data-fabric-hiddentextarea", ""), this.hiddenTextarea.setAttribute("wrap", "off"); var t = this._calcTextareaPosition();
                        this.hiddenTextarea.style.cssText = "position: absolute; top: " + t.top + "; left: " + t.left + "; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; paddingｰtop: " + t.fontSize + ";", r.document.body.appendChild(this.hiddenTextarea), r.util.addListener(this.hiddenTextarea, "keydown", this.onKeyDown.bind(this)), r.util.addListener(this.hiddenTextarea, "keyup", this.onKeyUp.bind(this)), r.util.addListener(this.hiddenTextarea, "input", this.onInput.bind(this)), r.util.addListener(this.hiddenTextarea, "copy", this.copy.bind(this)), r.util.addListener(this.hiddenTextarea, "cut", this.copy.bind(this)), r.util.addListener(this.hiddenTextarea, "paste", this.paste.bind(this)), r.util.addListener(this.hiddenTextarea, "compositionstart", this.onCompositionStart.bind(this)), r.util.addListener(this.hiddenTextarea, "compositionupdate", this.onCompositionUpdate.bind(this)), r.util.addListener(this.hiddenTextarea, "compositionend", this.onCompositionEnd.bind(this)), !this._clickHandlerInitialized && this.canvas && (r.util.addListener(this.canvas.upperCanvasEl, "click", this.onClick.bind(this)), this._clickHandlerInitialized = !0) }, keysMap: { 9: "exitEditing", 27: "exitEditing", 33: "moveCursorUp", 34: "moveCursorDown", 35: "moveCursorRight", 36: "moveCursorLeft", 37: "moveCursorLeft", 38: "moveCursorUp", 39: "moveCursorRight", 40: "moveCursorDown" }, ctrlKeysMapUp: { 67: "copy", 88: "cut" }, ctrlKeysMapDown: { 65: "selectAll" }, onClick: function() { this.hiddenTextarea && this.hiddenTextarea.focus() }, onKeyDown: function(t) { if (this.isEditing && !this.inCompositionMode) { if (t.keyCode in this.keysMap) this[this.keysMap[t.keyCode]](t);
                            else { if (!(t.keyCode in this.ctrlKeysMapDown && (t.ctrlKey || t.metaKey))) return;
                                this[this.ctrlKeysMapDown[t.keyCode]](t) } t.stopImmediatePropagation(), t.preventDefault(), t.keyCode >= 33 && t.keyCode <= 40 ? (this.clearContextTop(), this.renderCursorOrSelection()) : this.canvas && this.canvas.requestRenderAll() } }, onKeyUp: function(t) {!this.isEditing || this._copyDone || this.inCompositionMode ? this._copyDone = !1 : t.keyCode in this.ctrlKeysMapUp && (t.ctrlKey || t.metaKey) && (this[this.ctrlKeysMapUp[t.keyCode]](t), t.stopImmediatePropagation(), t.preventDefault(), this.canvas && this.canvas.requestRenderAll()) }, onInput: function(t) { var e = this.fromPaste; if (this.fromPaste = !1, t && t.stopPropagation(), this.isEditing) { var i, n, s = this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,
                                o = this._text.length,
                                a = s.length,
                                h = a - o; if ("" === this.hiddenTextarea.value) return this.styles = {}, this.updateFromTextArea(), this.fire("changed"), void(this.canvas && (this.canvas.fire("text:changed", { target: this }), this.canvas.requestRenderAll())); var c = this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value),
                                l = this.selectionStart > c.selectionStart;
                            this.selectionStart !== this.selectionEnd ? (i = this._text.slice(this.selectionStart, this.selectionEnd), h += this.selectionEnd - this.selectionStart) : a < o && (i = l ? this._text.slice(this.selectionEnd + h, this.selectionEnd) : this._text.slice(this.selectionStart, this.selectionStart - h)), n = s.slice(c.selectionEnd - h, c.selectionEnd), i && i.length && (this.selectionStart !== this.selectionEnd ? this.removeStyleFromTo(this.selectionStart, this.selectionEnd) : l ? this.removeStyleFromTo(this.selectionEnd - i.length, this.selectionEnd) : this.removeStyleFromTo(this.selectionEnd, this.selectionEnd + i.length)), n.length && (e && n.join("") === r.copiedText && !r.disableStyleCopyPaste ? this.insertNewStyleBlock(n, this.selectionStart, r.copiedTextStyle) : this.insertNewStyleBlock(n, this.selectionStart)), this.updateFromTextArea(), this.fire("changed"), this.canvas && (this.canvas.fire("text:changed", { target: this }), this.canvas.requestRenderAll()) } }, onCompositionStart: function() { this.inCompositionMode = !0 }, onCompositionEnd: function() { this.inCompositionMode = !1 }, onCompositionUpdate: function(t) { this.compositionStart = t.target.selectionStart, this.compositionEnd = t.target.selectionEnd, this.updateTextareaPosition() }, copy: function() { this.selectionStart !== this.selectionEnd && (r.copiedText = this.getSelectedText(), r.disableStyleCopyPaste ? r.copiedTextStyle = null : r.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd, !0), this._copyDone = !0) }, paste: function() { this.fromPaste = !0 }, _getClipboardData: function(t) { return t && t.clipboardData || r.window.clipboardData }, _getWidthBeforeCursor: function(t, e) { var i, r = this._getLineLeftOffset(t); return e > 0 && (r += (i = this.__charBounds[t][e - 1]).left + i.width), r }, getDownCursorOffset: function(t, e) { var i = this._getSelectionForOffset(t, e),
                            r = this.get2DCursorLocation(i),
                            n = r.lineIndex; if (n === this._textLines.length - 1 || t.metaKey || 34 === t.keyCode) return this._text.length - i; var s = r.charIndex,
                            o = this._getWidthBeforeCursor(n, s),
                            a = this._getIndexOnLine(n + 1, o); return this._textLines[n].slice(s).length + a + 1 + this.missingNewlineOffset(n) }, _getSelectionForOffset: function(t, e) { return t.shiftKey && this.selectionStart !== this.selectionEnd && e ? this.selectionEnd : this.selectionStart }, getUpCursorOffset: function(t, e) { var i = this._getSelectionForOffset(t, e),
                            r = this.get2DCursorLocation(i),
                            n = r.lineIndex; if (0 === n || t.metaKey || 33 === t.keyCode) return -i; var s = r.charIndex,
                            o = this._getWidthBeforeCursor(n, s),
                            a = this._getIndexOnLine(n - 1, o),
                            h = this._textLines[n].slice(0, s),
                            c = this.missingNewlineOffset(n - 1); return -this._textLines[n - 1].length + a - h.length + (1 - c) }, _getIndexOnLine: function(t, e) { for (var i, r, n = this._textLines[t], s = this._getLineLeftOffset(t), o = 0, a = 0, h = n.length; a < h; a++)
                            if ((s += i = this.__charBounds[t][a].width) > e) { r = !0; var c = s - i,
                                    l = s,
                                    u = Math.abs(c - e);
                                o = Math.abs(l - e) < u ? a : a - 1; break } return r || (o = n.length - 1), o }, moveCursorDown: function(t) { this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length || this._moveCursorUpOrDown("Down", t) }, moveCursorUp: function(t) { 0 === this.selectionStart && 0 === this.selectionEnd || this._moveCursorUpOrDown("Up", t) }, _moveCursorUpOrDown: function(t, e) { var i = this["get" + t + "CursorOffset"](e, "right" === this._selectionDirection);
                        e.shiftKey ? this.moveCursorWithShift(i) : this.moveCursorWithoutShift(i), 0 !== i && (this.setSelectionInBoundaries(), this.abortCursorAnimation(), this._currentCursorOpacity = 1, this.initDelayedCursor(), this._fireSelectionChanged(), this._updateTextarea()) }, moveCursorWithShift: function(t) { var e = "left" === this._selectionDirection ? this.selectionStart + t : this.selectionEnd + t; return this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, e), 0 !== t }, moveCursorWithoutShift: function(t) { return t < 0 ? (this.selectionStart += t, this.selectionEnd = this.selectionStart) : (this.selectionEnd += t, this.selectionStart = this.selectionEnd), 0 !== t }, moveCursorLeft: function(t) { 0 === this.selectionStart && 0 === this.selectionEnd || this._moveCursorLeftOrRight("Left", t) }, _move: function(t, e, i) { var r; if (t.altKey) r = this["findWordBoundary" + i](this[e]);
                        else { if (!t.metaKey && 35 !== t.keyCode && 36 !== t.keyCode) return this[e] += "Left" === i ? -1 : 1, !0;
                            r = this["findLineBoundary" + i](this[e]) } if (void 0 !== typeof r && this[e] !== r) return this[e] = r, !0 }, _moveLeft: function(t, e) { return this._move(t, e, "Left") }, _moveRight: function(t, e) { return this._move(t, e, "Right") }, moveCursorLeftWithoutShift: function(t) { var e = !0; return this._selectionDirection = "left", this.selectionEnd === this.selectionStart && 0 !== this.selectionStart && (e = this._moveLeft(t, "selectionStart")), this.selectionEnd = this.selectionStart, e }, moveCursorLeftWithShift: function(t) { return "right" === this._selectionDirection && this.selectionStart !== this.selectionEnd ? this._moveLeft(t, "selectionEnd") : 0 !== this.selectionStart ? (this._selectionDirection = "left", this._moveLeft(t, "selectionStart")) : void 0 }, moveCursorRight: function(t) { this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length || this._moveCursorLeftOrRight("Right", t) }, _moveCursorLeftOrRight: function(t, e) { var i = "moveCursor" + t + "With";
                        this._currentCursorOpacity = 1, e.shiftKey ? i += "Shift" : i += "outShift", this[i](e) && (this.abortCursorAnimation(), this.initDelayedCursor(), this._fireSelectionChanged(), this._updateTextarea()) }, moveCursorRightWithShift: function(t) { return "left" === this._selectionDirection && this.selectionStart !== this.selectionEnd ? this._moveRight(t, "selectionStart") : this.selectionEnd !== this._text.length ? (this._selectionDirection = "right", this._moveRight(t, "selectionEnd")) : void 0 }, moveCursorRightWithoutShift: function(t) { var e = !0; return this._selectionDirection = "right", this.selectionStart === this.selectionEnd ? (e = this._moveRight(t, "selectionStart"), this.selectionEnd = this.selectionStart) : this.selectionStart = this.selectionEnd, e }, removeChars: function(t, e) { void 0 === e && (e = t + 1), this.removeStyleFromTo(t, e), this._text.splice(t, e - t), this.text = this._text.join(""), this.set("dirty", !0), this._shouldClearDimensionCache() && (this.initDimensions(), this.setCoords()), this._removeExtraneousStyles() }, insertChars: function(t, e, i, n) { void 0 === n && (n = i), n > i && this.removeStyleFromTo(i, n); var s = r.util.string.graphemeSplit(t);
                        this.insertNewStyleBlock(s, i, e), this._text = [].concat(this._text.slice(0, i), s, this._text.slice(n)), this.text = this._text.join(""), this.set("dirty", !0), this._shouldClearDimensionCache() && (this.initDimensions(), this.setCoords()), this._removeExtraneousStyles() } }),
                function() { var t = r.util.toFixed,
                        e = /  +/g;
                    r.util.object.extend(r.Text.prototype, { _toSVG: function() { var t = this._getSVGLeftTopOffsets(),
                                e = this._getSVGTextAndBg(t.textTop, t.textLeft); return this._wrapSVGTextAndBg(e) }, toSVG: function(t) { return this._createBaseSVGMarkup(this._toSVG(), { reviver: t, noStyle: !0, withShadow: !0 }) }, _getSVGLeftTopOffsets: function() { return { textLeft: -this.width / 2, textTop: -this.height / 2, lineTop: this.getHeightOfLine(0) } }, _wrapSVGTextAndBg: function(t) { var e = this.getSvgTextDecoration(this); return [t.textBgRects.join(""), '\t\t<text xml:space="preserve" ', this.fontFamily ? 'font-family="' + this.fontFamily.replace(/"/g, "'") + '" ' : "", this.fontSize ? 'font-size="' + this.fontSize + '" ' : "", this.fontStyle ? 'font-style="' + this.fontStyle + '" ' : "", this.fontWeight ? 'font-weight="' + this.fontWeight + '" ' : "", e ? 'text-decoration="' + e + '" ' : "", 'style="', this.getSvgStyles(!0), '"', this.addPaintOrder(), " >", t.textSpans.join(""), "</text>\n"] }, _getSVGTextAndBg: function(t, e) { var i, r = [],
                                n = [],
                                s = t;
                            this._setSVGBg(n); for (var o = 0, a = this._textLines.length; o < a; o++) i = this._getLineLeftOffset(o), (this.textBackgroundColor || this.styleHas("textBackgroundColor", o)) && this._setSVGTextLineBg(n, o, e + i, s), this._setSVGTextLineText(r, o, e + i, s), s += this.getHeightOfLine(o); return { textSpans: r, textBgRects: n } }, _createTextCharSpan: function(i, n, s, o) { var a = i !== i.trim() || i.match(e),
                                h = this.getSvgSpanStyles(n, a),
                                c = h ? 'style="' + h + '"' : "",
                                l = n.deltaY,
                                u = "",
                                f = r.Object.NUM_FRACTION_DIGITS; return l && (u = ' dy="' + t(l, f) + '" '), ['<tspan x="', t(s, f), '" y="', t(o, f), '" ', u, c, ">", r.util.string.escapeXml(i), "</tspan>"].join("") }, _setSVGTextLineText: function(t, e, i, r) { var n, s, o, a, h, c = this.getHeightOfLine(e),
                                l = -1 !== this.textAlign.indexOf("justify"),
                                u = "",
                                f = 0,
                                d = this._textLines[e];
                            r += c * (1 - this._fontSizeFraction) / this.lineHeight; for (var g = 0, p = d.length - 1; g <= p; g++) h = g === p || this.charSpacing, u += d[g], o = this.__charBounds[e][g], 0 === f ? (i += o.kernedWidth - o.width, f += o.width) : f += o.kernedWidth, l && !h && this._reSpaceAndTab.test(d[g]) && (h = !0), h || (n = n || this.getCompleteStyleDeclaration(e, g), s = this.getCompleteStyleDeclaration(e, g + 1), h = this._hasStyleChangedForSvg(n, s)), h && (a = this._getStyleDeclaration(e, g) || {}, t.push(this._createTextCharSpan(u, a, i, r)), u = "", n = s, i += f, f = 0) }, _pushTextBgRect: function(e, i, n, s, o, a) { var h = r.Object.NUM_FRACTION_DIGITS;
                            e.push("\t\t<rect ", this._getFillAttributes(i), ' x="', t(n, h), '" y="', t(s, h), '" width="', t(o, h), '" height="', t(a, h), '"></rect>\n') }, _setSVGTextLineBg: function(t, e, i, r) { for (var n, s, o = this._textLines[e], a = this.getHeightOfLine(e) / this.lineHeight, h = 0, c = 0, l = this.getValueOfPropertyAt(e, 0, "textBackgroundColor"), u = 0, f = o.length; u < f; u++) n = this.__charBounds[e][u], (s = this.getValueOfPropertyAt(e, u, "textBackgroundColor")) !== l ? (l && this._pushTextBgRect(t, l, i + c, r, h, a), c = n.left, h = n.width, l = s) : h += n.kernedWidth;
                            s && this._pushTextBgRect(t, s, i + c, r, h, a) }, _getFillAttributes: function(t) { var e = t && "string" == typeof t ? new r.Color(t) : ""; return e && e.getSource() && 1 !== e.getAlpha() ? 'opacity="' + e.getAlpha() + '" fill="' + e.setAlpha(1).toRgb() + '"' : 'fill="' + t + '"' }, _getSVGLineTopOffset: function(t) { for (var e, i = 0, r = 0; r < t; r++) i += this.getHeightOfLine(r); return e = this.getHeightOfLine(r), { lineTop: i, offset: (this._fontSizeMult - this._fontSizeFraction) * e / (this.lineHeight * this._fontSizeMult) } }, getSvgStyles: function(t) { return r.Object.prototype.getSvgStyles.call(this, t) + " white-space: pre;" } }) }(),
                function(t) { "use strict"; var e = t.fabric || (t.fabric = {});
                    e.Textbox = e.util.createClass(e.IText, e.Observable, { type: "textbox", minWidth: 20, dynamicMinWidth: 2, __cachedLines: null, lockScalingFlip: !0, noScaleCache: !1, _dimensionAffectingProps: e.Text.prototype._dimensionAffectingProps.concat("width"), _wordJoiners: /[ \t\r]/, splitByGrapheme: !1, initDimensions: function() { this.__skipDimension || (this.isEditing && this.initDelayedCursor(), this.clearContextTop(), this._clearCache(), this.dynamicMinWidth = 0, this._styleMap = this._generateStyleMap(this._splitText()), this.dynamicMinWidth > this.width && this._set("width", this.dynamicMinWidth), -1 !== this.textAlign.indexOf("justify") && this.enlargeSpaces(), this.height = this.calcTextHeight(), this.saveState({ propertySet: "_dimensionAffectingProps" })) }, _generateStyleMap: function(t) { for (var e = 0, i = 0, r = 0, n = {}, s = 0; s < t.graphemeLines.length; s++) "\n" === t.graphemeText[r] && s > 0 ? (i = 0, r++, e++) : !this.splitByGrapheme && this._reSpaceAndTab.test(t.graphemeText[r]) && s > 0 && (i++, r++), n[s] = { line: e, offset: i }, r += t.graphemeLines[s].length, i += t.graphemeLines[s].length; return n }, styleHas: function(t, i) { if (this._styleMap && !this.isWrapping) { var r = this._styleMap[i];
                                r && (i = r.line) } return e.Text.prototype.styleHas.call(this, t, i) }, isEmptyStyles: function(t) { var e, i, r = 0,
                                n = !1,
                                s = this._styleMap[t],
                                o = this._styleMap[t + 1]; for (var a in s && (t = s.line, r = s.offset), o && (n = o.line === t, e = o.offset), i = void 0 === t ? this.styles : { line: this.styles[t] })
                                for (var h in i[a])
                                    if (h >= r && (!n || h < e))
                                        for (var c in i[a][h]) return !1; return !0 }, _getStyleDeclaration: function(t, e) { if (this._styleMap && !this.isWrapping) { var i = this._styleMap[t]; if (!i) return null;
                                t = i.line, e = i.offset + e } return this.callSuper("_getStyleDeclaration", t, e) }, _setStyleDeclaration: function(t, e, i) { var r = this._styleMap[t];
                            t = r.line, e = r.offset + e, this.styles[t][e] = i }, _deleteStyleDeclaration: function(t, e) { var i = this._styleMap[t];
                            t = i.line, e = i.offset + e, delete this.styles[t][e] }, _getLineStyle: function(t) { var e = this._styleMap[t]; return !!this.styles[e.line] }, _setLineStyle: function(t) { var e = this._styleMap[t];
                            this.styles[e.line] = {} }, _wrapText: function(t, e) { var i, r = []; for (this.isWrapping = !0, i = 0; i < t.length; i++) r = r.concat(this._wrapLine(t[i], i, e)); return this.isWrapping = !1, r }, _measureWord: function(t, e, i) { var r, n = 0;
                            i = i || 0; for (var s = 0, o = t.length; s < o; s++) { n += this._getGraphemeBox(t[s], e, s + i, r, !0).kernedWidth, r = t[s] } return n }, _wrapLine: function(t, i, r, n) { var s = 0,
                                o = this.splitByGrapheme,
                                a = [],
                                h = [],
                                c = o ? e.util.string.graphemeSplit(t) : t.split(this._wordJoiners),
                                l = "",
                                u = 0,
                                f = o ? "" : " ",
                                d = 0,
                                g = 0,
                                p = 0,
                                v = !0,
                                m = o ? 0 : this._getWidthOfCharSpacing();
                            n = n || 0;
                            0 === c.length && c.push([]), r -= n; for (var _ = 0; _ < c.length; _++) l = o ? c[_] : e.util.string.graphemeSplit(c[_]), d = this._measureWord(l, i, u), u += l.length, (s += g + d - m) >= r && !v ? (a.push(h), h = [], s = d, v = !0) : s += m, v || o || h.push(f), h = h.concat(l), g = this._measureWord([f], i, u), u++, v = !1, d > p && (p = d); return _ && a.push(h), p + n > this.dynamicMinWidth && (this.dynamicMinWidth = p - m + n), a }, isEndOfWrapping: function(t) { return !this._styleMap[t + 1] || this._styleMap[t + 1].line !== this._styleMap[t].line }, missingNewlineOffset: function(t) { return this.splitByGrapheme ? this.isEndOfWrapping(t) ? 1 : 0 : 1 }, _splitTextIntoLines: function(t) { for (var i = e.Text.prototype._splitTextIntoLines.call(this, t), r = this._wrapText(i.lines, this.width), n = new Array(r.length), s = 0; s < r.length; s++) n[s] = r[s].join(""); return i.lines = n, i.graphemeLines = r, i }, getMinWidth: function() { return Math.max(this.minWidth, this.dynamicMinWidth) }, _removeExtraneousStyles: function() { var t = {}; for (var e in this._styleMap) this._textLines[e] && (t[this._styleMap[e].line] = 1); for (var e in this.styles) t[e] || delete this.styles[e] }, toObject: function(t) { return this.callSuper("toObject", ["minWidth", "splitByGrapheme"].concat(t)) } }), e.Textbox.fromObject = function(t, i) { return e.Object._fromObject("Textbox", t, i, "text") } }(e) }).call(e, i("Ul5o").Buffer) },
    0: function(t, e) {},
    1: function(t, e) {},
    "1x5Z": function(t, e) { e.read = function(t, e, i, r, n) { var s, o, a = 8 * n - r - 1,
                h = (1 << a) - 1,
                c = h >> 1,
                l = -7,
                u = i ? n - 1 : 0,
                f = i ? -1 : 1,
                d = t[e + u]; for (u += f, s = d & (1 << -l) - 1, d >>= -l, l += a; l > 0; s = 256 * s + t[e + u], u += f, l -= 8); for (o = s & (1 << -l) - 1, s >>= -l, l += r; l > 0; o = 256 * o + t[e + u], u += f, l -= 8); if (0 === s) s = 1 - c;
            else { if (s === h) return o ? NaN : 1 / 0 * (d ? -1 : 1);
                o += Math.pow(2, r), s -= c } return (d ? -1 : 1) * o * Math.pow(2, s - r) }, e.write = function(t, e, i, r, n, s) { var o, a, h, c = 8 * s - n - 1,
                l = (1 << c) - 1,
                u = l >> 1,
                f = 23 === n ? Math.pow(2, -24) - Math.pow(2, -77) : 0,
                d = r ? 0 : s - 1,
                g = r ? 1 : -1,
                p = e < 0 || 0 === e && 1 / e < 0 ? 1 : 0; for (e = Math.abs(e), isNaN(e) || e === 1 / 0 ? (a = isNaN(e) ? 1 : 0, o = l) : (o = Math.floor(Math.log(e) / Math.LN2), e * (h = Math.pow(2, -o)) < 1 && (o--, h *= 2), (e += o + u >= 1 ? f / h : f * Math.pow(2, 1 - u)) * h >= 2 && (o++, h /= 2), o + u >= l ? (a = 0, o = l) : o + u >= 1 ? (a = (e * h - 1) * Math.pow(2, n), o += u) : (a = e * Math.pow(2, u - 1) * Math.pow(2, n), o = 0)); n >= 8; t[i + d] = 255 & a, d += g, a /= 256, n -= 8); for (o = o << n | a, c += n; c > 0; t[i + d] = 255 & o, d += g, o /= 256, c -= 8);
            t[i + d - g] |= 128 * p } },
    "6I2M": function(t, e) { var i = {}.toString;
        t.exports = Array.isArray || function(t) { return "[object Array]" == i.call(t) } },
    "KW+G": function(t, e, i) { "use strict";
        Object.defineProperty(e, "__esModule", { value: !0 }); var r = {};
        i.d(r, "Annotation", function() { return g }), i.d(r, "AnnotationIcons", function() { return o }); var n = i("m4/l"),
            s = i("/Im6"),
            o = function() {
                function t() {} return t.line = '<svg viewBox="0 0 128 128" version="1" xmlns="http://www.w3.org/2000/svg"><path d="M1 59h126v10H1z"/></svg>', t.arrow = '<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"><path d="M44 24l-8-8v6H6v4h30v6z"/></svg>', t.blank = '<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h48v48H0z" fill="none"/></svg>', t.colors = '<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"><path d="M24 6a18 18 0 0 0 0 36 3 3 0 0 0 2-5l-1-2c0-2 2-3 3-3h4c6 0 10-4 10-10 0-9-8-16-18-16zM13 24a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm6-8a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm10 0a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm6 8a3 3 0 1 1 0-6 3 3 0 0 1 0 6z"/></svg>', t.delete = '<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"><path d="M12 38c0 2 2 4 4 4h16c2 0 4-2 4-4V14H12v24zM38 8h-7l-2-2H19l-2 2h-7v4h28V8z"/></svg>', t.discard = '<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><path d="M16 0a16 16 0 1 0 0 32 16 16 0 0 0 0-32zm0 30a14 14 0 1 1 0-28 14 14 0 0 1 0 28z"/><path d="M9.27 22.7c.4.4 1.04.4 1.43 0l5.32-5.27 5.28 5.27a1 1 0 0 0 1.43 0c.4-.4.4-1.03 0-1.43L17.46 16l5.24-5.2a1 1 0 0 0 0-1.4c-.4-.4-1.04-.4-1.43 0l-5.23 5.18-5.31-5.3a1 1 0 0 0-1.43 0c-.4.39-.4 1.03 0 1.42l5.3 5.3-5.33 5.3a1 1 0 0 0 0 1.4z"/></svg>', t.done = '<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><path d="M30 0H2a2 2 0 0 0-2 2v28c0 1.1.9 2 2 2h28a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 30H2V2h28v28z"/><path d="M12.3 22.6c.38.39 1.04.4 1.43 0l11-10.9a1 1 0 0 0 0-1.4c-.4-.4-1.04-.4-1.43 0L13.01 20.48l-4.28-4.2c-.4-.39-1.03-.39-1.43 0a1 1 0 0 0 0 1.42l5 4.9z"/></svg>', t.draw = '<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"><path d="M9.2 13.8c1.4-1.5 2.8-2.7 3.4-2.5 1 .4 0 2.1-.6 3-.5 1-5.7 7.8-5.7 12.7 0 2.6 1 4.7 2.7 6a6 6 0 0 0 5.3.9c2.1-.7 3.9-2.8 6-5.6 2.5-3 5.8-6.8 8.3-6.8 3.2 0 3.2 2 3.5 3.6-7.6 1.3-10.8 7.3-10.8 10.7s2.9 6.2 6.4 6.2c3.3 0 8.6-2.7 9.4-12.2H42v-5h-5c-.2-3.3-2.1-8.4-8-8.4-4.5 0-8.4 3.8-9.9 5.7l-4.5 5.5c-.5.5-1.4 1.6-2.3 1.6-.9 0-1.4-1.6-.7-3.8.7-2.2 2.8-5.7 3.7-7 1.6-2.3 2.6-3.9 2.6-6.6 0-4.4-3.3-5.8-5-5.8-2.7 0-5 2-5.5 2.5-.7.7-1.3 1.3-1.7 1.9l3.5 3.4zM27.8 37c-.7 0-1.5-.5-1.5-1.4 0-1.2 1.4-4.4 5.7-5.6-.6 5.4-2.8 7-4.2 7z"/></svg>', t.icon = '<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"><path d="M42 38V10c0-2-2-4-4-4H10c-2 0-4 2-4 4v28c0 2 2 4 4 4h28c2 0 4-2 4-4zM17 27l5 6 7-9 9 12H10l7-9z"/></svg>', t.more = '<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"><path d="M12 20a4 4 0 1 0 0 8 4 4 0 0 0 0-8zm24 0a4 4 0 1 0 0 8 4 4 0 0 0 0-8zm-12 0a4 4 0 1 0 0 8 4 4 0 0 0 0-8z"/></svg>', t.pencil = '<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"><path d="M6 35v7h8l22-22-8-8L6 35zm35-21v-3l-4-4h-3l-4 3 8 8 3-4z"/></svg>', t.ok = '<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"><path d="M18 32l-8-8-3 3 11 11 24-24-3-3z" stroke="#fff"/></svg>', t.opacity = '<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"><path d="M35.32 15.99L24 4.69l-11.32 11.3C9.56 19.11 8 23.27 8 27.27s1.56 8.22 4.68 11.34a15.98 15.98 0 0 0 22.64 0C38.44 35.49 40 31.27 40 27.27s-1.56-8.16-4.68-11.28zM12 28c.02-4 1.24-6.55 3.52-8.81L24 10.53l8.48 8.75C34.76 21.55 35.98 24 36 28H12z"/></svg>', t.redo = '<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"><path d="M37 21c-4-3-9-5-14-5-9 0-17 6-20 14l5 2a16 16 0 0 1 25-7l-7 7h18V14l-7 7z"/></svg>', t.select = '<svg version="1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M7 2l12 11-6 1 3 7-2 1-3-7-4 4V2"/></svg>', t.text = '<svg viewBox="0 0 32 32" version="1" xmlns="http://www.w3.org/2000/svg"><g><path d="M4 6v4h8v18h4V10h8V6zM30 4V2h-6v2h2v24h-2v2h6v-2h-2V4z"/></g></svg>', t.textAdd = '<svg viewBox="0 0 32 32" version="1" xmlns="http://www.w3.org/2000/svg"><path d="M4 4v24h24V4H4zm22 22H6V6h20v20zM8 22h12v-2H8v2zm16-6H8v2h16v-2zm0-4H8v2h16v-2z"/></svg>', t.textWeight = '<svg viewBox="0 0 32 32" version="1" xmlns="http://www.w3.org/2000/svg"><path d="M24 10V8s0-6-6-6H8v28h10c6 0 6-6 6-6v-2c0-6-6-6-6-6s6 0 6-6zm-8 14h-2v-4h2s2 0 2 2-2 2-2 2zm0-12h-2V8h2s2 0 2 2-2 2-2 2z"/></svg>', t.textSize = '<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M16 9v8h-2V9h-4V7h10v2h-4zM8 5v12H6V5H0V3h15v2H8z"/></svg>', t.tools = '<svg viewBox="0 0 24 24" version="1" xmlns="http://www.w3.org/2000/svg"><path d="M0 5v18l1 1h8l1-1V5L5 0 0 5zm8 17H2v-3h6v3zm0-4H2V6h6v12zM3 5l2-2 3 2H3zM21 0h-5l-1 1v2h-2l-1 1v8l1 1 1-1V5h1v18l1 1h5l1-1V1l-1-1zm-1 22h-3V10h3v12zm0-13h-3V8h3v1zm0-2h-3V2h3v5z"/></svg>', t.undo = '<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"><path d="M25 16c-5 0-10 2-14 5l-7-7v18h18l-7-7c3-3 6-4 10-4 7 0 13 5 15 11l5-2c-3-8-11-14-20-14z"/></svg>', t.width = '<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M6 34h36v-4H6v4zm0 6h36v-2H6v2zm0-14h36v-6H6v6zM6 8v8h36V8H6z"/></svg>', t.heart = '<svg viewBox="0 0 48 48" width="48" height="48" xmlns="http://www.w3.org/2000/svg"><path d="M24 43l-3-3C11 31 4 25 4 17 4 11 9 6 15 6c3 0 7 2 9 4 2-2 6-4 9-4 6 0 11 5 11 11 0 8-7 14-17 23l-3 3z"/></svg>', t.check = '<svg viewBox="0 0 29.75 22.87" width="29.75" height="22.87" xmlns="http://www.w3.org/2000/svg"><path d="M29.05 1.57L28.19.7a2.43 2.43 0 0 0-3.43 0L10.17 15.29 5 10.12a2.43 2.43 0 0 0-3.43 0l-.86.86a2.44 2.44 0 0 0 0 3.43l7.74 7.75c.95.95 2.49.95 3.43 0L29.05 5c.94-.95.94-2.49 0-3.43z"/></svg>', t.pin = '<svg viewBox="0 0 48 48" width="48" height="48" xmlns="http://www.w3.org/2000/svg"><path d="M24 4c-8 0-14 6-14 14 0 11 14 26 14 26s14-15 14-26c0-8-6-14-14-14zm0 19a5 5 0 1 1 0-10 5 5 0 0 1 0 10z"/></svg>', t.like = '<svg viewBox="0 0 48 48" width="48" height="48" xmlns="http://www.w3.org/2000/svg"><path d="M2 42h8V18H2v24zm44-22c0-2-2-4-4-4H29l2-9V6l-1-2-2-2-13 13-1 3v20c0 2 2 4 4 4h18l4-2 6-15v-5z"/></svg>', t.dislike = '<svg viewBox="0 0 48 48" width="48" height="48" xmlns="http://www.w3.org/2000/svg"><path d="M30 6H12L8 8 2 23v5c0 2 2 4 4 4h13l-2 9v1l1 2 2 2 13-13 1-3V10c0-2-2-4-4-4zm8 0v24h8V6h-8z"/></svg>', t.tag = '<svg viewBox="0 0 48 48" width="48" height="48" xmlns="http://www.w3.org/2000/svg"><path d="M35 12l-3-2H10c-2 0-4 2-4 4v20c0 2 2 4 4 4h22l3-2 9-12-9-12z"/></svg>', t.attention = '<svg viewBox="0 0 48 48" width="48" height="48" xmlns="http://www.w3.org/2000/svg"><path d="M40 4H8C6 4 4 6 4 8v36l8-8h28c2 0 4-2 4-4V8c0-2-2-4-4-4zM26 22h-4V10h4v12zm0 8h-4v-4h4v4z"/></svg>', t.smiley = '<svg viewBox="0 0 48 48" width="48" height="48" xmlns="http://www.w3.org/2000/svg"><path d="M31 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-14 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm7 14c5 0 10-3 11-8H13c1 5 6 8 11 8zm0-32a20 20 0 1 0 0 40 20 20 0 0 0 0-40zm0 36a16 16 0 1 1 0-32 16 16 0 0 1 0 32z"/></svg>', t }(),
            a = i("Iz1H"),
            h = i("qJno"),
            c = i("aCit"),
            l = i("8ZqG"),
            u = i("zhwk"),
            f = i("WYhe"),
            d = i("Gg2j"),
            g = function(t) {
                function e() { var e = t.call(this) || this; return e._active = !1, e._currentTool = "draw", e._currentColor = Object(l.c)("#c00"), e._currentWidth = 2, e._currentOpacity = .8, e._currentFontSize = 20, e._currentFontWeight = 400, e._colors = [], e._widths = [], e._opacities = [], e._fontSizes = [], e._fontWeights = [], e._useMenu = !0, e._ownMenu = !0, e._pointerDown = !1, e._exportInited = !1, e.icons = [], e.autoSize = !1, e._colors = [Object(l.c)("#000"), Object(l.c)("#fff"), Object(l.c)("#c00"), Object(l.c)("#0c0"), Object(l.c)("#00c")], e._widths = [1, 2, 4, 10], e._opacities = [.2, .4, .6, .8, 1], e._fontSizes = [10, 15, 20, 30], e._fontWeights = [200, 300, 400, 800], e.icons = [o.pin, o.heart, o.check, o.like, o.dislike, o.tag, o.attention, o.smiley], e } return Object(n.c)(e, t), e.prototype.init = function() { t.prototype.init.call(this), this.initExporting(), this._data && this.loadData() }, e.prototype.initExporting = function() { var t = this,
                        e = this.target; if (this.useMenu && (e.exporting.menu ? (e.exporting.menu.invalidate(), this._ownMenu = !1) : (e.exporting.menu = new h.a, e.exporting.menu.items[0].menu = [], this._ownMenu = !0)), e.exporting.events.once("menucreated", this.updateIndicator), e.events.on("sizechanged", this.sizeAnnotations, this), Object(u.b)().body.events.on("keyup", function(e) { t.active && f.b.isKey(e.event, "del") && t.deleteSelected() }), e.exporting.events.on("exportstarted", function(e) { t.active && (t.updateSVG(), t.fabric.wrapperEl.style.display = "none", t._group.style.display = "") }), e.exporting.events.on("exportfinished", function(e) { t.active && (t._group.style.display = "none", t.fabric.wrapperEl.style.display = "block") }), this._indicatorId = c.c.getUniqueId(), this.useMenu) { e.exporting.menu.items[0].menu.push({ label: e.language.translateAny("Annotate"), type: "custom", options: { callback: this.handleClick, callbackTarget: this } }); for (var i = [], r = function(e) { i.push({ type: "custom", svg: o.ok, color: n.colors[e], options: { callback: function() { t.setColor(t.colors[e]) } } }) }, n = this, s = 0; s < this.colors.length; s++) r(s); var a = [],
                            l = function(e) { a.push({ type: "custom", label: d.widths[e] + "px", options: { callback: function() { t.setWidth(t.widths[e]) } } }) },
                            d = this; for (s = 0; s < this.widths.length; s++) l(s); var g = [],
                            p = function(e) { g.push({ type: "custom", label: '<span style="opacity: ' + v.opacities[e] + '">' + 100 * v.opacities[e] + "%</span>", options: { callback: function() { t.setOpacity(t.opacities[e]) } } }) },
                            v = this; for (s = 0; s < this.opacities.length; s++) p(s); var m = [],
                            _ = function(e) { m.push({ type: "custom", label: "" + y.fontSizes[e], options: { callback: function() { t.setFontSize(t.fontSizes[e]) } } }) },
                            y = this; for (s = 0; s < this.fontSizes.length; s++) _(s); var b = [],
                            x = function(e) { b.push({ type: "custom", label: "" + C.fontWeights[e], options: { callback: function() { t.setFontWeight(t.fontWeights[e]) } } }) },
                            C = this; for (s = 0; s < this.fontWeights.length; s++) x(s); var w = [],
                            S = function(e) { w.push({ type: "custom", svg: T.icons[e], options: { callback: function() { t.addIcon(t.icons[e]) } } }) },
                            T = this; for (s = 0; s < this.icons.length; s++) S(s); var O = '<svg xmlns="http://www.w3.org/2000/svg" version="1" viewBox="0 0 24 24"></svg>';
                        O += '<span class="' + this._indicatorId + '_color" style="display: block; background-color: ' + this.currentColor.hex + '; width: 1.2em; height: 1.2em; margin: 0.2em auto 0.4em auto;"></span>', this._menu = { hidden: !this.active, label: O, id: this._indicatorId, menu: [{ type: "custom", svg: o.tools, label: e.language.translateAny("Tools"), menu: [{ type: "custom", svg: o.select, label: e.language.translateAny("Select"), options: { callback: this.select, callbackTarget: this } }, { type: "custom", svg: o.draw, label: e.language.translateAny("Draw"), options: { callback: this.draw, callbackTarget: this } }, { type: "custom", svg: o.line, label: e.language.translateAny("Line"), options: { callback: this.line, callbackTarget: this } }, { type: "custom", svg: o.arrow, label: e.language.translateAny("Arrow"), options: { callback: this.arrow, callbackTarget: this } }, { type: "custom", svg: o.width, label: e.language.translateAny("Weight"), menu: a }, { type: "custom", svg: o.delete, label: e.language.translateAny("Delete"), options: { callback: this.delete, callbackTarget: this } }] }, { type: "custom", svg: o.text, label: e.language.translateAny("Text"), menu: [{ type: "custom", svg: o.textAdd, label: e.language.translateAny("Add"), options: { callback: this.addText, callbackTarget: this } }, { type: "custom", svg: o.textWeight, label: e.language.translateAny("Weight"), menu: b }, { type: "custom", svg: o.textSize, label: e.language.translateAny("Size"), menu: m }] }, { type: "custom", svg: o.colors, label: e.language.translateAny("Color"), menu: i }, { type: "custom", svg: o.opacity, label: e.language.translateAny("Opacity"), menu: g }, { type: "custom", svg: o.icon, label: e.language.translateAny("Icon"), menu: w }, { type: "custom", svg: o.more, label: e.language.translateAny("More"), menu: [{ type: "custom", svg: o.done, label: e.language.translateAny("Done"), options: { callback: this.deactivate, callbackTarget: this } }, { type: "custom", svg: o.discard, label: e.language.translateAny("Discard"), options: { callback: this.discard, callbackTarget: this } }] }] }, e.exporting.menu.items.push(this._menu) } this._exportInited = !0 }, e.prototype.handleClick = function(t) { this.active = !this.active }, Object.defineProperty(e.prototype, "fabric", { get: function() { var t = this; if (!this._fabric) { var e = document.createElement("canvas");
                            e.width = this.target.pixelWidth, e.height = this.target.pixelHeight, e.style.position = "absolute", e.style.top = "0", e.style.left = "0", this.target.svgContainer.SVGContainer.appendChild(e), this._fabric = new s.fabric.Canvas(e, { containerClass: "am4plugins_annotation_canvas_container" }), this.fabric.wrapperEl.style.position = "absolute", this.fabric.wrapperEl.style.top = "0", this.fabric.wrapperEl.style.left = "0", this.fabric.on("selection:created", function(e) { "delete" == t.currentTool && t.deleteSelected() }), this._fabric.on("mouse:down", function(e) { if ("line" == t.currentTool || "arrow" == t.currentTool) { t._pointerDown = !0; var i = t._fabric.getPointer(e.e),
                                        r = [i.x, i.y, i.x, i.y];
                                    t._currentLine = new s.fabric.Line(r, { strokeWidth: t.currentWidth, fill: t.currentColor.hex, stroke: t.currentColor.hex, opacity: t.currentOpacity, originX: "center", originY: "center" }), t._fabric.add(t._currentLine), "arrow" == t.currentTool && (t._currentArrowhead = new s.fabric.Triangle({ width: 10, height: 10, strokeWidth: t.currentWidth, fill: t.currentColor.hex, stroke: t.currentColor.hex, opacity: t.currentOpacity, left: i.x - 5, top: i.y - 10, originX: "center", originY: "center", angle: 0 }), t._fabric.add(t._currentArrowhead)) } }), this._fabric.on("mouse:move", function(e) { if (t._pointerDown && ("line" == t.currentTool || "arrow" == t.currentTool)) { var i = t._fabric.getPointer(e.e); if (t._currentLine.set({ x2: i.x, y2: i.y }), "arrow" == t.currentTool) { var r = d.getAngle({ x: t._currentLine.x1, y: t._currentLine.y1 }, { x: t._currentLine.x2, y: t._currentLine.y2 });
                                        t._currentArrowhead.set({ left: i.x, top: i.y, angle: r + 90 }) } t._fabric.renderAll() } }), this._fabric.on("mouse:up", function(e) { t._pointerDown = !1 }), this._data && this.loadData() } return this._fabric }, enumerable: !0, configurable: !0 }), Object.defineProperty(e.prototype, "group", { get: function() { return this._group || (this._group = this.target.paper.add("g").node, this._group.style.pointerEvents = "none", this._group.setAttribute("clip-path", this.target.dom.getAttribute("clip-path")), this.target.svgContainer.container.dom.appendChild(this._group)), this._group }, enumerable: !0, configurable: !0 }), e.prototype.activate = function() { this.active = !0, this.updateTool(), this.fabric.wrapperEl.style.display = "block", this.group.style.display = "none" }, e.prototype.deactivate = function() { this.active = !1, this.updateTool(), this.fabric.wrapperEl.style.display = "none", this.updateSVG(), this.group.style.display = "" }, e.prototype.updateSVG = function() { var t = this.fabric.toSVG().replace(/[\n\r]*/g, "").match(/<g.*<\/g>/g);
                    this.group.innerHTML = t ? t[0] : "" }, Object.defineProperty(e.prototype, "active", { get: function() { return this._active }, set: function(t) { this._active != t && (this._active = t, t ? (this.activate(), this.useMenu && this.target.exporting.menu.showBranch(this._menu)) : (this.deactivate(), this.useMenu && this.target.exporting.menu.hideBranch(this._menu)), this.updateIndicator()) }, enumerable: !0, configurable: !0 }), Object.defineProperty(e.prototype, "currentColor", { get: function() { return this._currentColor }, set: function(t) { this._currentColor != t && (this._currentColor = t, this.updateIndicator()) }, enumerable: !0, configurable: !0 }), Object.defineProperty(e.prototype, "colors", { get: function() { return this._colors }, set: function(t) { this._colors != t && (this._colors = t, this.updateIndicator(), this.setColor(this._currentColor)) }, enumerable: !0, configurable: !0 }), Object.defineProperty(e.prototype, "currentWidth", { get: function() { return this._currentWidth }, set: function(t) { this._currentWidth != t && (this._currentWidth = t, this.updateIndicator(), this.setWidth(this._currentWidth)) }, enumerable: !0, configurable: !0 }), Object.defineProperty(e.prototype, "widths", { get: function() { return this._widths }, set: function(t) { this._widths != t && (this._widths = t, this.updateIndicator()) }, enumerable: !0, configurable: !0 }), Object.defineProperty(e.prototype, "currentOpacity", { get: function() { return this._currentOpacity }, set: function(t) { this._currentOpacity != t && (this._currentOpacity = t, this.updateIndicator(), this.setOpacity(this._currentOpacity)) }, enumerable: !0, configurable: !0 }), Object.defineProperty(e.prototype, "opacities", { get: function() { return this._opacities }, set: function(t) { this._opacities != t && (this._opacities = t, this.updateIndicator()) }, enumerable: !0, configurable: !0 }), Object.defineProperty(e.prototype, "currentFontSize", { get: function() { return this._currentFontSize }, set: function(t) { this._currentFontSize != t && (this._currentFontSize = t, this.updateIndicator(), this.setFontSize(this._currentFontSize)) }, enumerable: !0, configurable: !0 }), Object.defineProperty(e.prototype, "fontSizes", { get: function() { return this._fontSizes }, set: function(t) { this._fontSizes != t && (this._fontSizes = t, this.updateIndicator()) }, enumerable: !0, configurable: !0 }), Object.defineProperty(e.prototype, "currentFontWeight", { get: function() { return this._currentFontWeight }, set: function(t) { this._currentFontWeight != t && (this._currentFontWeight = t, this.updateIndicator()) }, enumerable: !0, configurable: !0 }), Object.defineProperty(e.prototype, "fontWeights", { get: function() { return this._fontWeights }, set: function(t) { this._fontWeights != t && (this._fontWeights = t, this.updateIndicator()) }, enumerable: !0, configurable: !0 }), Object.defineProperty(e.prototype, "currentTool", { get: function() { return this._currentTool }, set: function(t) { this._currentTool != t && (this._currentTool = t, this.updateTool(), this.updateIndicator()) }, enumerable: !0, configurable: !0 }), e.prototype.updateTool = function() { switch (this.currentTool) {
                        case "select":
                            this.select(); break;
                        case "draw":
                            this.draw(); break;
                        case "delete":
                            this.delete(); break;
                        case "line":
                            this.line(); break;
                        case "arrow":
                            this.arrow() } }, e.prototype.updateIndicator = function() { if (this.indicator) { var t = this.indicator.getElementsByTagName("a")[0],
                            e = this.target.exporting.menu.createSvgElement(0, "custom", o[this.currentTool]),
                            i = this.indicator.getElementsByTagName("svg")[0];
                        t.insertBefore(e, i), t.removeChild(i), this.indicator.getElementsByClassName(this._indicatorId + "_color")[0].style.backgroundColor = this.currentColor.hex } }, Object.defineProperty(e.prototype, "indicator", { get: function() { return document.getElementById(this._indicatorId) }, enumerable: !0, configurable: !0 }), e.prototype.setColor = function(t) { this.currentColor = t; var e = Object(l.c)(t);
                    e.alpha = this.currentOpacity, this.fabric.freeDrawingBrush.color = e.rgba; for (var i = this.fabric.getActiveObjects(), r = 0; r < i.length; r++) i[r].isType("textbox") || i[r].isType("path") && i[r].fill ? i[r].set("fill", t.hex) : i[r].isType("triangle") ? (i[r].set("stroke", t.hex), i[r].set("fill", t.hex)) : i[r].getSrc ? this.setIconFill(i[r]) : i[r].set("stroke", t.hex);
                    this.fabric.requestRenderAll() }, e.prototype.setWidth = function(t) { this.currentWidth = t, this.fabric.freeDrawingBrush.width = t; for (var e = this.fabric.getActiveObjects(), i = 0; i < e.length; i++) e[i].set("strokeWidth", t);
                    this.fabric.requestRenderAll() }, e.prototype.setOpacity = function(t) { this.currentOpacity = t; var e = Object(l.c)(this.currentColor);
                    e.alpha = this.currentOpacity, this.fabric.freeDrawingBrush.color = e.rgba; for (var i = this.fabric.getActiveObjects(), r = 0; r < i.length; r++) i[r].isType("path") && i[r].set("stroke", this.currentColor.hex), i[r].set("opacity", t);
                    this.fabric.requestRenderAll() }, e.prototype.setFontSize = function(t) { this.currentFontSize = t; for (var e = this.fabric.getActiveObjects(), i = 0; i < e.length; i++) e[i].text && e[i].set("fontSize", t);
                    this.fabric.requestRenderAll() }, e.prototype.setFontWeight = function(t) { this.currentFontWeight = t; for (var e = this.fabric.getActiveObjects(), i = 0; i < e.length; i++) e[i].text && e[i].set("fontWeight", t);
                    this.fabric.requestRenderAll() }, e.prototype.underConstruction = function() { alert("This feature is not yet implemented") }, e.prototype.select = function() { this.currentTool = "select", this.fabric.isDrawingMode = !1, this.fabric.selection = !0 }, e.prototype.draw = function() { this.currentTool = "draw", this.fabric.isDrawingMode = !0, this.fabric.selection = !1; var t = Object(l.c)(this.currentColor);
                    t.alpha = this.currentOpacity, this.fabric.freeDrawingBrush.color = t.rgba, this.fabric.freeDrawingBrush.width = this.currentWidth }, e.prototype.line = function() { this.currentTool = "line", this.fabric.isDrawingMode = !1, this.fabric.selection = !1 }, e.prototype.arrow = function() { this.currentTool = "arrow", this.fabric.isDrawingMode = !1, this.fabric.selection = !1 }, e.prototype.addText = function() { this.fabric.isDrawingMode = !1, this.fabric.selection = !0, this.select(); var t = new s.fabric.Textbox(this.target.language.translateAny("Type..."), { fontSize: this.currentFontSize, fontWeight: this.currentFontWeight, fill: this.currentColor.hex, opacity: this.currentOpacity });
                    this.fabric.add(t), this.fabric.centerObject(t), t.enterEditing(), t.selectAll(), this.fabric.setActiveObject(t) }, e.prototype.addIcon = function(t) { var e = this;
                    this.fabric.isDrawingMode = !1, this.fabric.selection = !0, this.select(), s.fabric.loadSVGFromString(t, function(t) { for (var i = 0; i < t.length; i++) e.fabric.add(t[i]), e.fabric.centerObject(t[i]), e.fabric.setActiveObject(t[i]), e.fabric.setActiveObject(t[i]), t[i].opacity = e.currentOpacity, t[i].fill = e.currentColor.hex }) }, e.prototype.setIconFill = function(t) { var e = t.getSrc(),
                        i = ""; if (e.match(/;base64\,/)) try { i = (i = (i = atob(e.replace(/^.*;base64\,/g, ""))).replace(/fill="[^"]+"/, "")).replace(/\/>/g, ' fill="' + this.currentColor.hex + '" />'), e = e.replace(/(^.*;base64\,).*$/, "$1") + btoa(i), t.setSrc(e) } catch (t) { return } else e.match(/^data:/) && (i = (i = (i = e.replace(/^data:[^,]*\,/, "")).replace(/fill="[^"]+"/, "")).replace(/\/>/g, ' fill="' + this.currentColor.hex + '" />'), e = e.replace(/(^.*;base64\,).*$/, "$1") + i, t.setSrc(e)) }, e.prototype.delete = function() { this.currentTool = "delete", this.fabric.isDrawingMode = !1 }, e.prototype.clear = function() { this.fabric.clear() }, e.prototype.discard = function() { this.fabric.clear(), this.updateSVG(), this.deactivate() }, e.prototype.deleteSelected = function() { for (var t = this.fabric.getActiveObjects(), e = 0; e < t.length; e++) this.fabric.remove(t[e]);
                    this.fabric.requestRenderAll() }, Object.defineProperty(e.prototype, "data", { get: function() { return this._fabric ? this.fabric.toObject() : this._data }, set: function(t) { this._data = t, (this._fabric || this._exportInited) && this.loadData() }, enumerable: !0, configurable: !0 }), Object.defineProperty(e.prototype, "useMenu", { get: function() { return this._useMenu }, set: function(t) { this._useMenu = t, !t && this.target.exporting.menu && (this._ownMenu ? (this.target.exporting.menu.items[0].menu = [], this.target.exporting.menu.invalidate()) : (this.target.exporting.menu.items[0].menu.pop(), this.target.exporting.menu.invalidate())) }, enumerable: !0, configurable: !0 }), e.prototype.loadData = function() { var t = this;
                    this.fabric.loadFromJSON(this._data, function(e) { t.updateSVG(), t._data = void 0 }) }, e.prototype.sizeAnnotations = function() { if (this.autoSize) { if (!this._originalBbox) { var t = this.group.getBBox();
                            this._originalBbox = { width: t.width, height: t.height } } for (var e = this.target.pixelWidth, i = this.target.pixelHeight, r = e / this._originalBbox.width, n = i / this._originalBbox.height, s = this.data, o = 0; o < s.objects.length; o++) { var a = s.objects[o];
                            a.left *= r, a.top *= n } this.data = s, this._originalBbox = { width: e, height: i } } }, e }(a.a);
        c.c.registeredClasses.Annotation = g, window.am4plugins_annotation = r },
    M4QQ: function(t, e) { t.exports = jsdom },
    Ul5o: function(t, e, i) {
        "use strict";
        (function(t) {
            /*!
             * The buffer module from node.js, for the browser.
             *
             * @author   Feross Aboukhadijeh <http://feross.org>
             * @license  MIT
             */
            var r = i("ZUfS"),
                n = i("1x5Z"),
                s = i("6I2M");

            function o() { return h.TYPED_ARRAY_SUPPORT ? 2147483647 : 1073741823 }

            function a(t, e) { if (o() < e) throw new RangeError("Invalid typed array length"); return h.TYPED_ARRAY_SUPPORT ? (t = new Uint8Array(e)).__proto__ = h.prototype : (null === t && (t = new h(e)), t.length = e), t }

            function h(t, e, i) { if (!(h.TYPED_ARRAY_SUPPORT || this instanceof h)) return new h(t, e, i); if ("number" == typeof t) { if ("string" == typeof e) throw new Error("If encoding is specified then the first argument must be a string"); return u(this, t) } return c(this, t, e, i) }

            function c(t, e, i, r) { if ("number" == typeof e) throw new TypeError('"value" argument must not be a number'); return "undefined" != typeof ArrayBuffer && e instanceof ArrayBuffer ? function(t, e, i, r) { if (e.byteLength, i < 0 || e.byteLength < i) throw new RangeError("'offset' is out of bounds"); if (e.byteLength < i + (r || 0)) throw new RangeError("'length' is out of bounds");
                    e = void 0 === i && void 0 === r ? new Uint8Array(e) : void 0 === r ? new Uint8Array(e, i) : new Uint8Array(e, i, r);
                    h.TYPED_ARRAY_SUPPORT ? (t = e).__proto__ = h.prototype : t = f(t, e); return t }(t, e, i, r) : "string" == typeof e ? function(t, e, i) { "string" == typeof i && "" !== i || (i = "utf8"); if (!h.isEncoding(i)) throw new TypeError('"encoding" must be a valid string encoding'); var r = 0 | g(e, i),
                        n = (t = a(t, r)).write(e, i);
                    n !== r && (t = t.slice(0, n)); return t }(t, e, i) : function(t, e) { if (h.isBuffer(e)) { var i = 0 | d(e.length); return 0 === (t = a(t, i)).length ? t : (e.copy(t, 0, 0, i), t) } if (e) { if ("undefined" != typeof ArrayBuffer && e.buffer instanceof ArrayBuffer || "length" in e) return "number" != typeof e.length || function(t) { return t != t }(e.length) ? a(t, 0) : f(t, e); if ("Buffer" === e.type && s(e.data)) return f(t, e.data) } throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.") }(t, e) }

            function l(t) { if ("number" != typeof t) throw new TypeError('"size" argument must be a number'); if (t < 0) throw new RangeError('"size" argument must not be negative') }

            function u(t, e) { if (l(e), t = a(t, e < 0 ? 0 : 0 | d(e)), !h.TYPED_ARRAY_SUPPORT)
                    for (var i = 0; i < e; ++i) t[i] = 0; return t }

            function f(t, e) { var i = e.length < 0 ? 0 : 0 | d(e.length);
                t = a(t, i); for (var r = 0; r < i; r += 1) t[r] = 255 & e[r]; return t }

            function d(t) { if (t >= o()) throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x" + o().toString(16) + " bytes"); return 0 | t }

            function g(t, e) { if (h.isBuffer(t)) return t.length; if ("undefined" != typeof ArrayBuffer && "function" == typeof ArrayBuffer.isView && (ArrayBuffer.isView(t) || t instanceof ArrayBuffer)) return t.byteLength; "string" != typeof t && (t = "" + t); var i = t.length; if (0 === i) return 0; for (var r = !1;;) switch (e) {
                    case "ascii":
                    case "latin1":
                    case "binary":
                        return i;
                    case "utf8":
                    case "utf-8":
                    case void 0:
                        return Y(t).length;
                    case "ucs2":
                    case "ucs-2":
                    case "utf16le":
                    case "utf-16le":
                        return 2 * i;
                    case "hex":
                        return i >>> 1;
                    case "base64":
                        return W(t).length;
                    default:
                        if (r) return Y(t).length;
                        e = ("" + e).toLowerCase(), r = !0 } }

            function p(t, e, i) { var r = t[e];
                t[e] = t[i], t[i] = r }

            function v(t, e, i, r, n) { if (0 === t.length) return -1; if ("string" == typeof i ? (r = i, i = 0) : i > 2147483647 ? i = 2147483647 : i < -2147483648 && (i = -2147483648), i = +i, isNaN(i) && (i = n ? 0 : t.length - 1), i < 0 && (i = t.length + i), i >= t.length) { if (n) return -1;
                    i = t.length - 1 } else if (i < 0) { if (!n) return -1;
                    i = 0 } if ("string" == typeof e && (e = h.from(e, r)), h.isBuffer(e)) return 0 === e.length ? -1 : m(t, e, i, r, n); if ("number" == typeof e) return e &= 255, h.TYPED_ARRAY_SUPPORT && "function" == typeof Uint8Array.prototype.indexOf ? n ? Uint8Array.prototype.indexOf.call(t, e, i) : Uint8Array.prototype.lastIndexOf.call(t, e, i) : m(t, [e], i, r, n); throw new TypeError("val must be string, number or Buffer") }

            function m(t, e, i, r, n) { var s, o = 1,
                    a = t.length,
                    h = e.length; if (void 0 !== r && ("ucs2" === (r = String(r).toLowerCase()) || "ucs-2" === r || "utf16le" === r || "utf-16le" === r)) { if (t.length < 2 || e.length < 2) return -1;
                    o = 2, a /= 2, h /= 2, i /= 2 }

                function c(t, e) { return 1 === o ? t[e] : t.readUInt16BE(e * o) } if (n) { var l = -1; for (s = i; s < a; s++)
                        if (c(t, s) === c(e, -1 === l ? 0 : s - l)) { if (-1 === l && (l = s), s - l + 1 === h) return l * o } else -1 !== l && (s -= s - l), l = -1 } else
                    for (i + h > a && (i = a - h), s = i; s >= 0; s--) { for (var u = !0, f = 0; f < h; f++)
                            if (c(t, s + f) !== c(e, f)) { u = !1; break } if (u) return s }
                return -1 }

            function _(t, e, i, r) { i = Number(i) || 0; var n = t.length - i;
                r ? (r = Number(r)) > n && (r = n) : r = n; var s = e.length; if (s % 2 != 0) throw new TypeError("Invalid hex string");
                r > s / 2 && (r = s / 2); for (var o = 0; o < r; ++o) { var a = parseInt(e.substr(2 * o, 2), 16); if (isNaN(a)) return o;
                    t[i + o] = a } return o }

            function y(t, e, i, r) { return X(Y(e, t.length - i), t, i, r) }

            function b(t, e, i, r) { return X(function(t) { for (var e = [], i = 0; i < t.length; ++i) e.push(255 & t.charCodeAt(i)); return e }(e), t, i, r) }

            function x(t, e, i, r) { return b(t, e, i, r) }

            function C(t, e, i, r) { return X(W(e), t, i, r) }

            function w(t, e, i, r) { return X(function(t, e) { for (var i, r, n, s = [], o = 0; o < t.length && !((e -= 2) < 0); ++o) i = t.charCodeAt(o), r = i >> 8, n = i % 256, s.push(n), s.push(r); return s }(e, t.length - i), t, i, r) }

            function S(t, e, i) { return 0 === e && i === t.length ? r.fromByteArray(t) : r.fromByteArray(t.slice(e, i)) }

            function T(t, e, i) { i = Math.min(t.length, i); for (var r = [], n = e; n < i;) { var s, o, a, h, c = t[n],
                        l = null,
                        u = c > 239 ? 4 : c > 223 ? 3 : c > 191 ? 2 : 1; if (n + u <= i) switch (u) {
                        case 1:
                            c < 128 && (l = c); break;
                        case 2:
                            128 == (192 & (s = t[n + 1])) && (h = (31 & c) << 6 | 63 & s) > 127 && (l = h); break;
                        case 3:
                            s = t[n + 1], o = t[n + 2], 128 == (192 & s) && 128 == (192 & o) && (h = (15 & c) << 12 | (63 & s) << 6 | 63 & o) > 2047 && (h < 55296 || h > 57343) && (l = h); break;
                        case 4:
                            s = t[n + 1], o = t[n + 2], a = t[n + 3], 128 == (192 & s) && 128 == (192 & o) && 128 == (192 & a) && (h = (15 & c) << 18 | (63 & s) << 12 | (63 & o) << 6 | 63 & a) > 65535 && h < 1114112 && (l = h) } null === l ? (l = 65533, u = 1) : l > 65535 && (l -= 65536, r.push(l >>> 10 & 1023 | 55296), l = 56320 | 1023 & l), r.push(l), n += u } return function(t) { var e = t.length; if (e <= O) return String.fromCharCode.apply(String, t); var i = "",
                        r = 0; for (; r < e;) i += String.fromCharCode.apply(String, t.slice(r, r += O)); return i }(r) } e.Buffer = h, e.SlowBuffer = function(t) {+t != t && (t = 0); return h.alloc(+t) }, e.INSPECT_MAX_BYTES = 50, h.TYPED_ARRAY_SUPPORT = void 0 !== t.TYPED_ARRAY_SUPPORT ? t.TYPED_ARRAY_SUPPORT : function() { try { var t = new Uint8Array(1); return t.__proto__ = { __proto__: Uint8Array.prototype, foo: function() { return 42 } }, 42 === t.foo() && "function" == typeof t.subarray && 0 === t.subarray(1, 1).byteLength } catch (t) { return !1 } }(), e.kMaxLength = o(), h.poolSize = 8192, h._augment = function(t) { return t.__proto__ = h.prototype, t }, h.from = function(t, e, i) { return c(null, t, e, i) }, h.TYPED_ARRAY_SUPPORT && (h.prototype.__proto__ = Uint8Array.prototype, h.__proto__ = Uint8Array, "undefined" != typeof Symbol && Symbol.species && h[Symbol.species] === h && Object.defineProperty(h, Symbol.species, { value: null, configurable: !0 })), h.alloc = function(t, e, i) { return function(t, e, i, r) { return l(e), e <= 0 ? a(t, e) : void 0 !== i ? "string" == typeof r ? a(t, e).fill(i, r) : a(t, e).fill(i) : a(t, e) }(null, t, e, i) }, h.allocUnsafe = function(t) { return u(null, t) }, h.allocUnsafeSlow = function(t) { return u(null, t) }, h.isBuffer = function(t) { return !(null == t || !t._isBuffer) }, h.compare = function(t, e) { if (!h.isBuffer(t) || !h.isBuffer(e)) throw new TypeError("Arguments must be Buffers"); if (t === e) return 0; for (var i = t.length, r = e.length, n = 0, s = Math.min(i, r); n < s; ++n)
                    if (t[n] !== e[n]) { i = t[n], r = e[n]; break } return i < r ? -1 : r < i ? 1 : 0 }, h.isEncoding = function(t) { switch (String(t).toLowerCase()) {
                    case "hex":
                    case "utf8":
                    case "utf-8":
                    case "ascii":
                    case "latin1":
                    case "binary":
                    case "base64":
                    case "ucs2":
                    case "ucs-2":
                    case "utf16le":
                    case "utf-16le":
                        return !0;
                    default:
                        return !1 } }, h.concat = function(t, e) { if (!s(t)) throw new TypeError('"list" argument must be an Array of Buffers'); if (0 === t.length) return h.alloc(0); var i; if (void 0 === e)
                    for (e = 0, i = 0; i < t.length; ++i) e += t[i].length; var r = h.allocUnsafe(e),
                    n = 0; for (i = 0; i < t.length; ++i) { var o = t[i]; if (!h.isBuffer(o)) throw new TypeError('"list" argument must be an Array of Buffers');
                    o.copy(r, n), n += o.length } return r }, h.byteLength = g, h.prototype._isBuffer = !0, h.prototype.swap16 = function() { var t = this.length; if (t % 2 != 0) throw new RangeError("Buffer size must be a multiple of 16-bits"); for (var e = 0; e < t; e += 2) p(this, e, e + 1); return this }, h.prototype.swap32 = function() { var t = this.length; if (t % 4 != 0) throw new RangeError("Buffer size must be a multiple of 32-bits"); for (var e = 0; e < t; e += 4) p(this, e, e + 3), p(this, e + 1, e + 2); return this }, h.prototype.swap64 = function() { var t = this.length; if (t % 8 != 0) throw new RangeError("Buffer size must be a multiple of 64-bits"); for (var e = 0; e < t; e += 8) p(this, e, e + 7), p(this, e + 1, e + 6), p(this, e + 2, e + 5), p(this, e + 3, e + 4); return this }, h.prototype.toString = function() { var t = 0 | this.length; return 0 === t ? "" : 0 === arguments.length ? T(this, 0, t) : function(t, e, i) { var r = !1; if ((void 0 === e || e < 0) && (e = 0), e > this.length) return ""; if ((void 0 === i || i > this.length) && (i = this.length), i <= 0) return ""; if ((i >>>= 0) <= (e >>>= 0)) return ""; for (t || (t = "utf8");;) switch (t) {
                        case "hex":
                            return E(this, e, i);
                        case "utf8":
                        case "utf-8":
                            return T(this, e, i);
                        case "ascii":
                            return k(this, e, i);
                        case "latin1":
                        case "binary":
                            return P(this, e, i);
                        case "base64":
                            return S(this, e, i);
                        case "ucs2":
                        case "ucs-2":
                        case "utf16le":
                        case "utf-16le":
                            return A(this, e, i);
                        default:
                            if (r) throw new TypeError("Unknown encoding: " + t);
                            t = (t + "").toLowerCase(), r = !0 } }.apply(this, arguments) }, h.prototype.equals = function(t) { if (!h.isBuffer(t)) throw new TypeError("Argument must be a Buffer"); return this === t || 0 === h.compare(this, t) }, h.prototype.inspect = function() { var t = "",
                    i = e.INSPECT_MAX_BYTES; return this.length > 0 && (t = this.toString("hex", 0, i).match(/.{2}/g).join(" "), this.length > i && (t += " ... ")), "<Buffer " + t + ">" }, h.prototype.compare = function(t, e, i, r, n) { if (!h.isBuffer(t)) throw new TypeError("Argument must be a Buffer"); if (void 0 === e && (e = 0), void 0 === i && (i = t ? t.length : 0), void 0 === r && (r = 0), void 0 === n && (n = this.length), e < 0 || i > t.length || r < 0 || n > this.length) throw new RangeError("out of range index"); if (r >= n && e >= i) return 0; if (r >= n) return -1; if (e >= i) return 1; if (e >>>= 0, i >>>= 0, r >>>= 0, n >>>= 0, this === t) return 0; for (var s = n - r, o = i - e, a = Math.min(s, o), c = this.slice(r, n), l = t.slice(e, i), u = 0; u < a; ++u)
                    if (c[u] !== l[u]) { s = c[u], o = l[u]; break } return s < o ? -1 : o < s ? 1 : 0 }, h.prototype.includes = function(t, e, i) { return -1 !== this.indexOf(t, e, i) }, h.prototype.indexOf = function(t, e, i) { return v(this, t, e, i, !0) }, h.prototype.lastIndexOf = function(t, e, i) { return v(this, t, e, i, !1) }, h.prototype.write = function(t, e, i, r) { if (void 0 === e) r = "utf8", i = this.length, e = 0;
                else if (void 0 === i && "string" == typeof e) r = e, i = this.length, e = 0;
                else { if (!isFinite(e)) throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");
                    e |= 0, isFinite(i) ? (i |= 0, void 0 === r && (r = "utf8")) : (r = i, i = void 0) } var n = this.length - e; if ((void 0 === i || i > n) && (i = n), t.length > 0 && (i < 0 || e < 0) || e > this.length) throw new RangeError("Attempt to write outside buffer bounds");
                r || (r = "utf8"); for (var s = !1;;) switch (r) {
                    case "hex":
                        return _(this, t, e, i);
                    case "utf8":
                    case "utf-8":
                        return y(this, t, e, i);
                    case "ascii":
                        return b(this, t, e, i);
                    case "latin1":
                    case "binary":
                        return x(this, t, e, i);
                    case "base64":
                        return C(this, t, e, i);
                    case "ucs2":
                    case "ucs-2":
                    case "utf16le":
                    case "utf-16le":
                        return w(this, t, e, i);
                    default:
                        if (s) throw new TypeError("Unknown encoding: " + r);
                        r = ("" + r).toLowerCase(), s = !0 } }, h.prototype.toJSON = function() { return { type: "Buffer", data: Array.prototype.slice.call(this._arr || this, 0) } };
            var O = 4096;

            function k(t, e, i) { var r = "";
                i = Math.min(t.length, i); for (var n = e; n < i; ++n) r += String.fromCharCode(127 & t[n]); return r }

            function P(t, e, i) { var r = "";
                i = Math.min(t.length, i); for (var n = e; n < i; ++n) r += String.fromCharCode(t[n]); return r }

            function E(t, e, i) { var r = t.length;
                (!e || e < 0) && (e = 0), (!i || i < 0 || i > r) && (i = r); for (var n = "", s = e; s < i; ++s) n += z(t[s]); return n }

            function A(t, e, i) { for (var r = t.slice(e, i), n = "", s = 0; s < r.length; s += 2) n += String.fromCharCode(r[s] + 256 * r[s + 1]); return n }

            function D(t, e, i) { if (t % 1 != 0 || t < 0) throw new RangeError("offset is not uint"); if (t + e > i) throw new RangeError("Trying to access beyond buffer length") }

            function j(t, e, i, r, n, s) { if (!h.isBuffer(t)) throw new TypeError('"buffer" argument must be a Buffer instance'); if (e > n || e < s) throw new RangeError('"value" argument is out of bounds'); if (i + r > t.length) throw new RangeError("Index out of range") }

            function M(t, e, i, r) { e < 0 && (e = 65535 + e + 1); for (var n = 0, s = Math.min(t.length - i, 2); n < s; ++n) t[i + n] = (e & 255 << 8 * (r ? n : 1 - n)) >>> 8 * (r ? n : 1 - n) }

            function F(t, e, i, r) { e < 0 && (e = 4294967295 + e + 1); for (var n = 0, s = Math.min(t.length - i, 4); n < s; ++n) t[i + n] = e >>> 8 * (r ? n : 3 - n) & 255 }

            function I(t, e, i, r, n, s) { if (i + r > t.length) throw new RangeError("Index out of range"); if (i < 0) throw new RangeError("Index out of range") }

            function B(t, e, i, r, s) { return s || I(t, 0, i, 4), n.write(t, e, i, r, 23, 4), i + 4 }

            function L(t, e, i, r, s) { return s || I(t, 0, i, 8), n.write(t, e, i, r, 52, 8), i + 8 } h.prototype.slice = function(t, e) { var i, r = this.length; if (t = ~~t, e = void 0 === e ? r : ~~e, t < 0 ? (t += r) < 0 && (t = 0) : t > r && (t = r), e < 0 ? (e += r) < 0 && (e = 0) : e > r && (e = r), e < t && (e = t), h.TYPED_ARRAY_SUPPORT)(i = this.subarray(t, e)).__proto__ = h.prototype;
                else { var n = e - t;
                    i = new h(n, void 0); for (var s = 0; s < n; ++s) i[s] = this[s + t] } return i }, h.prototype.readUIntLE = function(t, e, i) { t |= 0, e |= 0, i || D(t, e, this.length); for (var r = this[t], n = 1, s = 0; ++s < e && (n *= 256);) r += this[t + s] * n; return r }, h.prototype.readUIntBE = function(t, e, i) { t |= 0, e |= 0, i || D(t, e, this.length); for (var r = this[t + --e], n = 1; e > 0 && (n *= 256);) r += this[t + --e] * n; return r }, h.prototype.readUInt8 = function(t, e) { return e || D(t, 1, this.length), this[t] }, h.prototype.readUInt16LE = function(t, e) { return e || D(t, 2, this.length), this[t] | this[t + 1] << 8 }, h.prototype.readUInt16BE = function(t, e) { return e || D(t, 2, this.length), this[t] << 8 | this[t + 1] }, h.prototype.readUInt32LE = function(t, e) { return e || D(t, 4, this.length), (this[t] | this[t + 1] << 8 | this[t + 2] << 16) + 16777216 * this[t + 3] }, h.prototype.readUInt32BE = function(t, e) { return e || D(t, 4, this.length), 16777216 * this[t] + (this[t + 1] << 16 | this[t + 2] << 8 | this[t + 3]) }, h.prototype.readIntLE = function(t, e, i) { t |= 0, e |= 0, i || D(t, e, this.length); for (var r = this[t], n = 1, s = 0; ++s < e && (n *= 256);) r += this[t + s] * n; return r >= (n *= 128) && (r -= Math.pow(2, 8 * e)), r }, h.prototype.readIntBE = function(t, e, i) { t |= 0, e |= 0, i || D(t, e, this.length); for (var r = e, n = 1, s = this[t + --r]; r > 0 && (n *= 256);) s += this[t + --r] * n; return s >= (n *= 128) && (s -= Math.pow(2, 8 * e)), s }, h.prototype.readInt8 = function(t, e) { return e || D(t, 1, this.length), 128 & this[t] ? -1 * (255 - this[t] + 1) : this[t] }, h.prototype.readInt16LE = function(t, e) { e || D(t, 2, this.length); var i = this[t] | this[t + 1] << 8; return 32768 & i ? 4294901760 | i : i }, h.prototype.readInt16BE = function(t, e) { e || D(t, 2, this.length); var i = this[t + 1] | this[t] << 8; return 32768 & i ? 4294901760 | i : i }, h.prototype.readInt32LE = function(t, e) { return e || D(t, 4, this.length), this[t] | this[t + 1] << 8 | this[t + 2] << 16 | this[t + 3] << 24 }, h.prototype.readInt32BE = function(t, e) { return e || D(t, 4, this.length), this[t] << 24 | this[t + 1] << 16 | this[t + 2] << 8 | this[t + 3] }, h.prototype.readFloatLE = function(t, e) { return e || D(t, 4, this.length), n.read(this, t, !0, 23, 4) }, h.prototype.readFloatBE = function(t, e) { return e || D(t, 4, this.length), n.read(this, t, !1, 23, 4) }, h.prototype.readDoubleLE = function(t, e) { return e || D(t, 8, this.length), n.read(this, t, !0, 52, 8) }, h.prototype.readDoubleBE = function(t, e) { return e || D(t, 8, this.length), n.read(this, t, !1, 52, 8) }, h.prototype.writeUIntLE = function(t, e, i, r) {
                (t = +t, e |= 0, i |= 0, r) || j(this, t, e, i, Math.pow(2, 8 * i) - 1, 0); var n = 1,
                    s = 0; for (this[e] = 255 & t; ++s < i && (n *= 256);) this[e + s] = t / n & 255; return e + i }, h.prototype.writeUIntBE = function(t, e, i, r) {
                (t = +t, e |= 0, i |= 0, r) || j(this, t, e, i, Math.pow(2, 8 * i) - 1, 0); var n = i - 1,
                    s = 1; for (this[e + n] = 255 & t; --n >= 0 && (s *= 256);) this[e + n] = t / s & 255; return e + i }, h.prototype.writeUInt8 = function(t, e, i) { return t = +t, e |= 0, i || j(this, t, e, 1, 255, 0), h.TYPED_ARRAY_SUPPORT || (t = Math.floor(t)), this[e] = 255 & t, e + 1 }, h.prototype.writeUInt16LE = function(t, e, i) { return t = +t, e |= 0, i || j(this, t, e, 2, 65535, 0), h.TYPED_ARRAY_SUPPORT ? (this[e] = 255 & t, this[e + 1] = t >>> 8) : M(this, t, e, !0), e + 2 }, h.prototype.writeUInt16BE = function(t, e, i) { return t = +t, e |= 0, i || j(this, t, e, 2, 65535, 0), h.TYPED_ARRAY_SUPPORT ? (this[e] = t >>> 8, this[e + 1] = 255 & t) : M(this, t, e, !1), e + 2 }, h.prototype.writeUInt32LE = function(t, e, i) { return t = +t, e |= 0, i || j(this, t, e, 4, 4294967295, 0), h.TYPED_ARRAY_SUPPORT ? (this[e + 3] = t >>> 24, this[e + 2] = t >>> 16, this[e + 1] = t >>> 8, this[e] = 255 & t) : F(this, t, e, !0), e + 4 }, h.prototype.writeUInt32BE = function(t, e, i) { return t = +t, e |= 0, i || j(this, t, e, 4, 4294967295, 0), h.TYPED_ARRAY_SUPPORT ? (this[e] = t >>> 24, this[e + 1] = t >>> 16, this[e + 2] = t >>> 8, this[e + 3] = 255 & t) : F(this, t, e, !1), e + 4 }, h.prototype.writeIntLE = function(t, e, i, r) { if (t = +t, e |= 0, !r) { var n = Math.pow(2, 8 * i - 1);
                    j(this, t, e, i, n - 1, -n) } var s = 0,
                    o = 1,
                    a = 0; for (this[e] = 255 & t; ++s < i && (o *= 256);) t < 0 && 0 === a && 0 !== this[e + s - 1] && (a = 1), this[e + s] = (t / o >> 0) - a & 255; return e + i }, h.prototype.writeIntBE = function(t, e, i, r) { if (t = +t, e |= 0, !r) { var n = Math.pow(2, 8 * i - 1);
                    j(this, t, e, i, n - 1, -n) } var s = i - 1,
                    o = 1,
                    a = 0; for (this[e + s] = 255 & t; --s >= 0 && (o *= 256);) t < 0 && 0 === a && 0 !== this[e + s + 1] && (a = 1), this[e + s] = (t / o >> 0) - a & 255; return e + i }, h.prototype.writeInt8 = function(t, e, i) { return t = +t, e |= 0, i || j(this, t, e, 1, 127, -128), h.TYPED_ARRAY_SUPPORT || (t = Math.floor(t)), t < 0 && (t = 255 + t + 1), this[e] = 255 & t, e + 1 }, h.prototype.writeInt16LE = function(t, e, i) { return t = +t, e |= 0, i || j(this, t, e, 2, 32767, -32768), h.TYPED_ARRAY_SUPPORT ? (this[e] = 255 & t, this[e + 1] = t >>> 8) : M(this, t, e, !0), e + 2 }, h.prototype.writeInt16BE = function(t, e, i) { return t = +t, e |= 0, i || j(this, t, e, 2, 32767, -32768), h.TYPED_ARRAY_SUPPORT ? (this[e] = t >>> 8, this[e + 1] = 255 & t) : M(this, t, e, !1), e + 2 }, h.prototype.writeInt32LE = function(t, e, i) { return t = +t, e |= 0, i || j(this, t, e, 4, 2147483647, -2147483648), h.TYPED_ARRAY_SUPPORT ? (this[e] = 255 & t, this[e + 1] = t >>> 8, this[e + 2] = t >>> 16, this[e + 3] = t >>> 24) : F(this, t, e, !0), e + 4 }, h.prototype.writeInt32BE = function(t, e, i) { return t = +t, e |= 0, i || j(this, t, e, 4, 2147483647, -2147483648), t < 0 && (t = 4294967295 + t + 1), h.TYPED_ARRAY_SUPPORT ? (this[e] = t >>> 24, this[e + 1] = t >>> 16, this[e + 2] = t >>> 8, this[e + 3] = 255 & t) : F(this, t, e, !1), e + 4 }, h.prototype.writeFloatLE = function(t, e, i) { return B(this, t, e, !0, i) }, h.prototype.writeFloatBE = function(t, e, i) { return B(this, t, e, !1, i) }, h.prototype.writeDoubleLE = function(t, e, i) { return L(this, t, e, !0, i) }, h.prototype.writeDoubleBE = function(t, e, i) { return L(this, t, e, !1, i) }, h.prototype.copy = function(t, e, i, r) { if (i || (i = 0), r || 0 === r || (r = this.length), e >= t.length && (e = t.length), e || (e = 0), r > 0 && r < i && (r = i), r === i) return 0; if (0 === t.length || 0 === this.length) return 0; if (e < 0) throw new RangeError("targetStart out of bounds"); if (i < 0 || i >= this.length) throw new RangeError("sourceStart out of bounds"); if (r < 0) throw new RangeError("sourceEnd out of bounds");
                r > this.length && (r = this.length), t.length - e < r - i && (r = t.length - e + i); var n, s = r - i; if (this === t && i < e && e < r)
                    for (n = s - 1; n >= 0; --n) t[n + e] = this[n + i];
                else if (s < 1e3 || !h.TYPED_ARRAY_SUPPORT)
                    for (n = 0; n < s; ++n) t[n + e] = this[n + i];
                else Uint8Array.prototype.set.call(t, this.subarray(i, i + s), e); return s }, h.prototype.fill = function(t, e, i, r) { if ("string" == typeof t) { if ("string" == typeof e ? (r = e, e = 0, i = this.length) : "string" == typeof i && (r = i, i = this.length), 1 === t.length) { var n = t.charCodeAt(0);
                        n < 256 && (t = n) } if (void 0 !== r && "string" != typeof r) throw new TypeError("encoding must be a string"); if ("string" == typeof r && !h.isEncoding(r)) throw new TypeError("Unknown encoding: " + r) } else "number" == typeof t && (t &= 255); if (e < 0 || this.length < e || this.length < i) throw new RangeError("Out of range index"); if (i <= e) return this; var s; if (e >>>= 0, i = void 0 === i ? this.length : i >>> 0, t || (t = 0), "number" == typeof t)
                    for (s = e; s < i; ++s) this[s] = t;
                else { var o = h.isBuffer(t) ? t : Y(new h(t, r).toString()),
                        a = o.length; for (s = 0; s < i - e; ++s) this[s + e] = o[s % a] } return this };
            var R = /[^+\/0-9A-Za-z-_]/g;

            function z(t) { return t < 16 ? "0" + t.toString(16) : t.toString(16) }

            function Y(t, e) { var i;
                e = e || 1 / 0; for (var r = t.length, n = null, s = [], o = 0; o < r; ++o) { if ((i = t.charCodeAt(o)) > 55295 && i < 57344) { if (!n) { if (i > 56319) {
                                (e -= 3) > -1 && s.push(239, 191, 189); continue } if (o + 1 === r) {
                                (e -= 3) > -1 && s.push(239, 191, 189); continue } n = i; continue } if (i < 56320) {
                            (e -= 3) > -1 && s.push(239, 191, 189), n = i; continue } i = 65536 + (n - 55296 << 10 | i - 56320) } else n && (e -= 3) > -1 && s.push(239, 191, 189); if (n = null, i < 128) { if ((e -= 1) < 0) break;
                        s.push(i) } else if (i < 2048) { if ((e -= 2) < 0) break;
                        s.push(i >> 6 | 192, 63 & i | 128) } else if (i < 65536) { if ((e -= 3) < 0) break;
                        s.push(i >> 12 | 224, i >> 6 & 63 | 128, 63 & i | 128) } else { if (!(i < 1114112)) throw new Error("Invalid code point"); if ((e -= 4) < 0) break;
                        s.push(i >> 18 | 240, i >> 12 & 63 | 128, i >> 6 & 63 | 128, 63 & i | 128) } } return s }

            function W(t) { return r.toByteArray(function(t) { if ((t = function(t) { return t.trim ? t.trim() : t.replace(/^\s+|\s+$/g, "") }(t).replace(R, "")).length < 2) return ""; for (; t.length % 4 != 0;) t += "="; return t }(t)) }

            function X(t, e, i, r) { for (var n = 0; n < r && !(n + i >= e.length || n >= t.length); ++n) e[n + i] = t[n]; return n }
        }).call(e, i("VTyh"))
    },
    ZUfS: function(t, e, i) { "use strict";
        e.byteLength = function(t) { var e = c(t),
                i = e[0],
                r = e[1]; return 3 * (i + r) / 4 - r }, e.toByteArray = function(t) { var e, i, r = c(t),
                o = r[0],
                a = r[1],
                h = new s(function(t, e, i) { return 3 * (e + i) / 4 - i }(0, o, a)),
                l = 0,
                u = a > 0 ? o - 4 : o; for (i = 0; i < u; i += 4) e = n[t.charCodeAt(i)] << 18 | n[t.charCodeAt(i + 1)] << 12 | n[t.charCodeAt(i + 2)] << 6 | n[t.charCodeAt(i + 3)], h[l++] = e >> 16 & 255, h[l++] = e >> 8 & 255, h[l++] = 255 & e;
            2 === a && (e = n[t.charCodeAt(i)] << 2 | n[t.charCodeAt(i + 1)] >> 4, h[l++] = 255 & e);
            1 === a && (e = n[t.charCodeAt(i)] << 10 | n[t.charCodeAt(i + 1)] << 4 | n[t.charCodeAt(i + 2)] >> 2, h[l++] = e >> 8 & 255, h[l++] = 255 & e); return h }, e.fromByteArray = function(t) { for (var e, i = t.length, n = i % 3, s = [], o = 0, a = i - n; o < a; o += 16383) s.push(u(t, o, o + 16383 > a ? a : o + 16383));
            1 === n ? (e = t[i - 1], s.push(r[e >> 2] + r[e << 4 & 63] + "==")) : 2 === n && (e = (t[i - 2] << 8) + t[i - 1], s.push(r[e >> 10] + r[e >> 4 & 63] + r[e << 2 & 63] + "=")); return s.join("") }; for (var r = [], n = [], s = "undefined" != typeof Uint8Array ? Uint8Array : Array, o = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", a = 0, h = o.length; a < h; ++a) r[a] = o[a], n[o.charCodeAt(a)] = a;

        function c(t) { var e = t.length; if (e % 4 > 0) throw new Error("Invalid string. Length must be a multiple of 4"); var i = t.indexOf("="); return -1 === i && (i = e), [i, i === e ? 0 : 4 - i % 4] }

        function l(t) { return r[t >> 18 & 63] + r[t >> 12 & 63] + r[t >> 6 & 63] + r[63 & t] }

        function u(t, e, i) { for (var r, n = [], s = e; s < i; s += 3) r = (t[s] << 16 & 16711680) + (t[s + 1] << 8 & 65280) + (255 & t[s + 2]), n.push(l(r)); return n.join("") } n["-".charCodeAt(0)] = 62, n["_".charCodeAt(0)] = 63 }
}, ["KW+G"]);
//# sourceMappingURL=annotation.js.map