Skip to content
Snippets Groups Projects
fabric.min.js 361 KiB
Newer Older
Carsten  Rose's avatar
Carsten Rose committed
2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000
                for (var n = e + 1; n < this._objects.length; ++n) {
                    var s = t.intersectsWithObject(this._objects[n]) || t.isContainedWithinObject(this._objects[n]) || this._objects[n].isContainedWithinObject(t);
                    if (s) {
                        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.renderAll && this.renderAll()
        },
        dispose: function () {
            return this.clear(), this
        },
        toString: function () {
            return "#<fabric.Canvas (" + this.complexity() + "): { objects: " + this.getObjects().length + " }>"
        }
    }), t(fabric.StaticCanvas.prototype, fabric.Observable), t(fabric.StaticCanvas.prototype, fabric.Collection), t(fabric.StaticCanvas.prototype, fabric.DataURLExporter), t(fabric.StaticCanvas, {
        EMPTY_JSON: '{"objects": [], "background": "white"}',
        supports: function (t) {
            var e = fabric.util.createCanvasElement();
            if (!e || !e.getContext)return null;
            var i = e.getContext("2d");
            if (!i)return null;
            switch (t) {
                case"getImageData":
                    return "undefined" != typeof i.getImageData;
                case"setLineDash":
                    return "undefined" != typeof i.setLineDash;
                case"toDataURL":
                    return "undefined" != typeof e.toDataURL;
                case"toDataURLWithQuality":
                    try {
                        return e.toDataURL("image/jpeg", 0), !0
                    } catch (t) {
                    }
                    return !1;
                default:
                    return null
            }
        }
    }), fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject
}(), fabric.BaseBrush = fabric.util.createClass({
    color: "rgb(0, 0, 0)",
    width: 1,
    shadow: null,
    strokeLineCap: "round",
    strokeLineJoin: "round",
    strokeDashArray: null,
    setShadow: function (t) {
        return this.shadow = new fabric.Shadow(t), this
    },
    _setBrushStyles: function () {
        var t = this.canvas.contextTop;
        t.strokeStyle = this.color, t.lineWidth = this.width, t.lineCap = this.strokeLineCap, t.lineJoin = this.strokeLineJoin, this.strokeDashArray && fabric.StaticCanvas.supports("setLineDash") && t.setLineDash(this.strokeDashArray)
    },
    _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
        }
    },
    _resetShadow: function () {
        var t = this.canvas.contextTop;
        t.shadowColor = "", t.shadowBlur = t.shadowOffsetX = t.shadowOffsetY = 0
    }
}), function () {
    fabric.PencilBrush = fabric.util.createClass(fabric.BaseBrush, {
        initialize: function (t) {
            this.canvas = t, this._points = []
        }, onMouseDown: function (t) {
            this._prepareForDrawing(t), this._captureDrawingPath(t), this._render()
        }, onMouseMove: function (t) {
            this._captureDrawingPath(t), this.canvas.clearContext(this.canvas.contextTop), this._render()
        }, onMouseUp: function () {
            this._finalizeAndAddPath()
        }, _prepareForDrawing: function (t) {
            var e = new fabric.Point(t.x, t.y);
            this._reset(), this._addPoint(e), this.canvas.contextTop.moveTo(e.x, e.y)
        }, _addPoint: function (t) {
            this._points.push(t)
        }, _reset: function () {
            this._points.length = 0, this._setBrushStyles(), this._setShadow()
        }, _captureDrawingPath: function (t) {
            var e = new fabric.Point(t.x, t.y);
            this._addPoint(e)
        }, _render: function () {
            var t = this.canvas.contextTop, e = this.canvas.viewportTransform, i = this._points[0], r = this._points[1];
            t.save(), t.transform(e[0], e[1], e[2], e[3], e[4], e[5]), t.beginPath(), 2 === this._points.length && i.x === r.x && i.y === r.y && (i.x -= .5, r.x += .5), t.moveTo(i.x, i.y);
            for (var n = 1, s = this._points.length; n < s; n++) {
                var o = i.midPointFrom(r);
                t.quadraticCurveTo(i.x, i.y, o.x, o.y), i = this._points[n], r = this._points[n + 1]
            }
            t.lineTo(i.x, i.y), t.stroke(), t.restore()
        }, convertPointsToSVGPath: function (t) {
            var e = [], i = new fabric.Point(t[0].x, t[0].y), r = new fabric.Point(t[1].x, t[1].y);
            e.push("M ", t[0].x, " ", t[0].y, " ");
            for (var n = 1, s = t.length; n < s; n++) {
                var o = i.midPointFrom(r);
                e.push("Q ", i.x, " ", i.y, " ", o.x, " ", o.y, " "), i = new fabric.Point(t[n].x, t[n].y), n + 1 < t.length && (r = new fabric.Point(t[n + 1].x, t[n + 1].y))
            }
            return e.push("L ", i.x, " ", i.y, " "), e
        }, createPath: function (t) {
            var e = new fabric.Path(t, {
                fill: null,
                stroke: this.color,
                strokeWidth: this.width,
                strokeLineCap: this.strokeLineCap,
                strokeLineJoin: this.strokeLineJoin,
                strokeDashArray: this.strokeDashArray,
                originX: "center",
                originY: "center"
            });
            return this.shadow && (this.shadow.affectStroke = !0, e.setShadow(this.shadow)), e
        }, _finalizeAndAddPath: function () {
            var t = this.canvas.contextTop;
            t.closePath();
            var e = this.convertPointsToSVGPath(this._points).join("");
            if ("M 0 0 Q 0 0 0 0 L 0 0" === e)return void this.canvas.renderAll();
            var i = this.createPath(e);
            this.canvas.add(i), i.setCoords(), this.canvas.clearContext(this.canvas.contextTop), this._resetShadow(), this.canvas.renderAll(), this.canvas.fire("path:created", {path: i})
        }
    })
}(), fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, {
    width: 10, initialize: function (t) {
        this.canvas = t, this.points = []
    }, drawDot: function (t) {
        var e = this.addPoint(t), i = this.canvas.contextTop, r = this.canvas.viewportTransform;
        i.save(), i.transform(r[0], r[1], r[2], r[3], r[4], r[5]), i.fillStyle = e.fill, i.beginPath(), i.arc(e.x, e.y, e.radius, 0, 2 * Math.PI, !1), i.closePath(), i.fill(), i.restore()
    }, onMouseDown: function (t) {
        this.points.length = 0, this.canvas.clearContext(this.canvas.contextTop), this._setShadow(), this.drawDot(t)
    }, onMouseMove: function (t) {
        this.drawDot(t)
    }, onMouseUp: function () {
        var t = this.canvas.renderOnAddRemove;
        this.canvas.renderOnAddRemove = !1;
        for (var e = [], i = 0, r = this.points.length; i < r; i++) {
            var n = this.points[i], s = new fabric.Circle({
                radius: n.radius,
                left: n.x,
                top: n.y,
                originX: "center",
                originY: "center",
                fill: n.fill
            });
            this.shadow && s.setShadow(this.shadow), e.push(s)
        }
        var o = new fabric.Group(e, {originX: "center", originY: "center"});
        o.canvas = this.canvas, this.canvas.add(o), this.canvas.fire("path:created", {path: o}), this.canvas.clearContext(this.canvas.contextTop), this._resetShadow(), this.canvas.renderOnAddRemove = t, this.canvas.renderAll()
    }, addPoint: function (t) {
        var e = new fabric.Point(t.x, t.y), i = fabric.util.getRandomInt(Math.max(0, this.width - 20), this.width + 20) / 2, r = new fabric.Color(this.color).setAlpha(fabric.util.getRandomInt(0, 100) / 100).toRgba();
        return e.radius = i, e.fill = r, this.points.push(e), e
    }
}), fabric.SprayBrush = fabric.util.createClass(fabric.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()
    },
    onMouseMove: function (t) {
        this.addSprayChunk(t), this.render()
    },
    onMouseUp: function () {
        var t = this.canvas.renderOnAddRemove;
        this.canvas.renderOnAddRemove = !1;
        for (var e = [], i = 0, r = this.sprayChunks.length; i < r; i++)for (var n = this.sprayChunks[i], s = 0, o = n.length; s < o; s++) {
            var a = new fabric.Rect({
                width: n[s].width,
                height: n[s].width,
                left: n[s].x + 1,
                top: n[s].y + 1,
                originX: "center",
                originY: "center",
                fill: this.color
            });
            this.shadow && a.setShadow(this.shadow), e.push(a)
        }
        this.optimizeOverlapping && (e = this._getOptimizedRects(e));
        var h = new fabric.Group(e, {originX: "center", originY: "center"});
        h.canvas = this.canvas, this.canvas.add(h), this.canvas.fire("path:created", {path: h}), this.canvas.clearContext(this.canvas.contextTop), this._resetShadow(), this.canvas.renderOnAddRemove = t, this.canvas.renderAll()
    },
    _getOptimizedRects: function (t) {
        for (var e, i = {}, r = 0, n = t.length; r < n; r++)e = t[r].left + "" + t[r].top, i[e] || (i[e] = t[r]);
        var s = [];
        for (e in i)s.push(i[e]);
        return s
    },
    render: function () {
        var t = this.canvas.contextTop;
        t.fillStyle = this.color;
        var e = this.canvas.viewportTransform;
        t.save(), t.transform(e[0], e[1], e[2], e[3], e[4], e[5]);
        for (var i = 0, r = this.sprayChunkPoints.length; i < r; i++) {
            var n = this.sprayChunkPoints[i];
            "undefined" != typeof n.opacity && (t.globalAlpha = n.opacity), t.fillRect(n.x, n.y, n.width, n.width)
        }
        t.restore()
    },
    addSprayChunk: function (t) {
        this.sprayChunkPoints = [];
        for (var e, i, r, n = this.width / 2, s = 0; s < this.density; s++) {
            e = fabric.util.getRandomInt(t.x - n, t.x + n), i = fabric.util.getRandomInt(t.y - n, t.y + n), r = this.dotWidthVariance ? fabric.util.getRandomInt(Math.max(1, this.dotWidth - this.dotWidthVariance), this.dotWidth + this.dotWidthVariance) : this.dotWidth;
            var o = new fabric.Point(e, i);
            o.width = r, this.randomOpacity && (o.opacity = fabric.util.getRandomInt(0, 100) / 100), this.sprayChunkPoints.push(o)
        }
        this.sprayChunks.push(this.sprayChunkPoints)
    }
}), fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, {
    getPatternSrc: function () {
        var t = 20, e = 5, i = fabric.document.createElement("canvas"), r = i.getContext("2d");
        return i.width = i.height = t + e, r.fillStyle = this.color, r.beginPath(), r.arc(t / 2, t / 2, t / 2, 0, 2 * Math.PI, !1), r.closePath(), r.fill(), i
    }, 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 fabric.Pattern({
            source: this.source || this.getPatternSrcFunction(),
            offsetX: -i.x,
            offsetY: -i.y
        }), e
    }
}), function () {
    var t = fabric.util.getPointer, e = fabric.util.degreesToRadians, i = fabric.util.radiansToDegrees, r = Math.atan2, n = Math.abs, s = fabric.StaticCanvas.supports("setLineDash"), o = .5;
    fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, {
        initialize: function (t, e) {
            e || (e = {}), 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,
        hoverCursor: "move",
        moveCursor: "move",
        defaultCursor: "default",
        freeDrawingCursor: "crosshair",
        rotationCursor: "crosshair",
        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 = fabric.PencilBrush && new fabric.PencilBrush(this), this.calcOffset()
        },
        _chooseObjectsToRender: function () {
            var t, e = this.getActiveGroup(), i = this.getActiveObject(), r = [], n = [];
            if (!e && !i || this.preserveObjectStacking)r = this._objects; else {
                for (var s = 0, o = this._objects.length; s < o; s++)t = this._objects[s], e && e.contains(t) || t === i ? n.push(t) : r.push(t);
                e && (e._set("_objects", n), r.push(e)), i && r.push(i)
            }
            return r
        },
        renderAll: function () {
            !this.contextTopDirty || this._groupSelector || this.isDrawingMode || (this.clearContext(this.contextTop), this.contextTopDirty = !1);
            var t = this.contextContainer;
            return this.renderCanvas(t, this._chooseObjectsToRender()), this
        },
        renderTop: function () {
            var t = this.contextTop;
            return this.clearContext(t), this.selection && this._groupSelector && this._drawSelection(t), this.fire("after:render"), this.contextTopDirty = !0, 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) ? "rotate" === t.action ? this._setOriginToCenter(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 = !0, s = i || this.getPointer(t, n);
            return r = e.group && e.group === this.getActiveGroup() ? this._normalizePointer(e.group, s) : {
                x: s.x,
                y: s.y
            }, e.containsPoint(r) || e._findTargetCorner(s)
        },
        _normalizePointer: function (t, e) {
            var i = t.calcTransformMatrix(), r = fabric.util.invertTransform(i), n = this.restorePointerVpt(e);
            return fabric.util.transformPoint(n, r)
        },
        isTargetTransparent: function (t, e, i) {
            var r = t.hasBorders, n = t.transparentCorners, s = this.contextCache, o = t.selectionBackgroundColor;
            t.hasBorders = t.transparentCorners = !1, t.selectionBackgroundColor = "", s.save(), s.transform.apply(s, this.viewportTransform), t.render(s), s.restore(), t.active && t._renderControls(s), t.hasBorders = r, t.transparentCorners = n, t.selectionBackgroundColor = o;
            var a = fabric.util.isTransparent(s, e, i, this.targetFindTolerance);
            return this.clearContext(s), a
        },
        _shouldClearSelection: function (t, e) {
            var i = this.getActiveGroup(), r = this.getActiveObject();
            return !e || e && i && !i.contains(e) && i !== e && !t[this.selectionKey] || 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)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) {
            if (i) {
                var r = this.getPointer(t), n = i._findTargetCorner(this.getPointer(t, !0)), s = this._getActionFromCorner(i, n, t), o = this._getOriginFromCorner(i, n);
                this._currentTransform = {
                    target: i,
                    action: s,
                    corner: n,
                    scaleX: i.scaleX,
                    scaleY: i.scaleY,
                    skewX: i.skewX,
                    skewY: i.skewY,
                    offsetX: r.x - i.left,
                    offsetY: r.y - i.top,
                    originX: o.x,
                    originY: o.y,
                    ex: r.x,
                    ey: r.y,
                    lastX: r.x,
                    lastY: r.y,
                    left: i.left,
                    top: i.top,
                    theta: e(i.angle),
                    width: i.width * i.scaleX,
                    mouseXSign: 1,
                    mouseYSign: 1,
                    shiftKey: t.shiftKey,
                    altKey: t[this.centeredKey]
                }, this._currentTransform.original = {
                    left: i.left,
                    top: i.top,
                    scaleX: i.scaleX,
                    scaleY: i.scaleY,
                    skewX: i.skewX,
                    skewY: i.skewY,
                    originX: o.x,
                    originY: o.y
                }, this._resetCurrentTransform()
            }
        },
        _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 r = this._currentTransform, n = r.target, s = !1, o = n.get("lockSkewingX"), a = n.get("lockSkewingY");
            if (o && "x" === i || a && "y" === i)return !1;
            var h, c, l = n.getCenterPoint(), u = n.toLocalPoint(new fabric.Point(t, e), "center", "center")[i], f = n.toLocalPoint(new fabric.Point(r.lastX, r.lastY), "center", "center")[i], d = n._getTransformedDimensions();
            return this._changeSkewTransformOrigin(u - f, r, i), h = n.toLocalPoint(new fabric.Point(t, e), r.originX, r.originY)[i], c = n.translateToOriginPoint(l, r.originX, r.originY), s = this._setObjectSkew(h, r, i, d), r.lastX = t, r.lastY = e, n.setPositionByOrigin(c, r.originX, r.originY), s
        },
        _setObjectSkew: function (t, e, i, r) {
            var n, s, o, a, h, c, l, u, f, d = e.target, g = !1, p = e.skewSign;
            return "x" === i ? (a = "y", h = "Y", c = "X", u = 0, f = d.skewY) : (a = "x", h = "X", c = "Y", u = d.skewX, f = 0), o = d._getTransformedDimensions(u, f), l = 2 * Math.abs(t) - o[i], l <= 2 ? n = 0 : (n = p * Math.atan(l / d["scale" + c] / (o[a] / d["scale" + h])), n = fabric.util.radiansToDegrees(n)), g = d["skew" + c] !== n, d.set("skew" + c, n), 0 !== d["skew" + h] && (s = d._getTransformedDimensions(), n = r[a] / s[a] * d["scale" + h], d.set("scale" + h, n)), g
        },
        _scaleObject: function (t, e, i) {
            var r = this._currentTransform, n = r.target, s = n.get("lockScalingX"), o = n.get("lockScalingY"), a = n.get("lockScalingFlip");
            if (s && o)return !1;
            var h = n.translateToOriginPoint(n.getCenterPoint(), r.originX, r.originY), c = n.toLocalPoint(new fabric.Point(t, e), r.originX, r.originY), l = n._getTransformedDimensions(), u = !1;
            return this._setLocalMouse(c, r), u = this._setObjectScale(c, r, s, o, i, a, l), n.setPositionByOrigin(h, r.originX, r.originY), u
        },
        _setObjectScale: function (t, e, i, r, n, s, o) {
            var a, h, c, l, u = e.target, f = !1, d = !1, g = !1;
            return c = t.x * u.scaleX / o.x, l = t.y * u.scaleY / o.y, a = u.scaleX !== c, h = u.scaleY !== l, s && c <= 0 && c < u.scaleX && (f = !0), s && l <= 0 && l < u.scaleY && (d = !0), "equally" !== n || i || r ? n ? "x" !== n || u.get("lockUniScaling") ? "y" !== n || u.get("lockUniScaling") || d || r || u.set("scaleY", l) && (g = g || h) : f || i || u.set("scaleX", c) && (g = g || a) : (f || i || u.set("scaleX", c) && (g = g || a), d || r || u.set("scaleY", l) && (g = g || h)) : f || d || (g = this._scaleObjectEqually(t, u, e, o)), e.newScaleX = c, e.newScaleY = l, f || d || this._flipObject(e, n), g
        },
        _scaleObjectEqually: function (t, e, i, r) {
            var n, s = t.y + t.x, o = r.y * i.original.scaleY / e.scaleY + r.x * i.original.scaleX / e.scaleX;
            return i.newScaleX = i.original.scaleX * s / o, i.newScaleY = i.original.scaleY * s / o, n = i.newScaleX !== e.scaleX || i.newScaleY !== e.scaleY, e.set("scaleX", i.newScaleX), e.set("scaleY", i.newScaleY), 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(), s = 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)), n(t.x) > s ? t.x < 0 ? t.x += s : t.x -= s : t.x = 0, n(t.y) > s ? t.y < 0 ? t.y += s : t.y -= s : t.y = 0
        },
        _rotateObject: function (t, e) {
            var n = this._currentTransform;
            if (n.target.get("lockRotation"))return !1;
            var s = r(n.ey - n.top, n.ex - n.left), o = r(e - n.top, t - n.left), a = i(o - s + n.theta), h = !0;
            if (n.target.snapAngle > 0) {
                var c = n.target.snapAngle, l = n.target.snapThreshold || c, u = Math.ceil(a / c) * c, f = Math.floor(a / c) * c;
                Math.abs(a - f) < l ? a = f : Math.abs(a - u) < l && (a = u)
            }
            return a < 0 && (a = 360 + a), a %= 360, n.target.angle === a ? h = !1 : n.target.angle = a, h
        },
        setCursor: function (t) {
            this.upperCanvasEl.style.cursor = t
        },
        _resetObjectTransform: function (t) {
            t.scaleX = 1, t.scaleY = 1, t.skewX = 0, t.skewY = 0, t.setAngle(0)
        },
        _drawSelection: function (t) {
            var e = this._groupSelector, i = e.left, r = e.top, a = n(i), h = n(r);
            if (this.selectionColor && (t.fillStyle = this.selectionColor, t.fillRect(e.ex - (i > 0 ? 0 : -i), e.ey - (r > 0 ? 0 : -r), a, h)), this.selectionLineWidth && this.selectionBorderColor)if (t.lineWidth = this.selectionLineWidth, t.strokeStyle = this.selectionBorderColor, this.selectionDashArray.length > 1 && !s) {
                var c = e.ex + o - (i > 0 ? 0 : a), l = e.ey + o - (r > 0 ? 0 : h);
                t.beginPath(), fabric.util.drawDashedLine(t, c, l, c + a, l, this.selectionDashArray), fabric.util.drawDashedLine(t, c, l + h - 1, c + a, l + h - 1, this.selectionDashArray), fabric.util.drawDashedLine(t, c, l, c, l + h, this.selectionDashArray), fabric.util.drawDashedLine(t, c + a - 1, l, c + a - 1, l + h, this.selectionDashArray), t.closePath(), t.stroke()
            } else fabric.Object.prototype._setLineDash.call(this, t, this.selectionDashArray), t.strokeRect(e.ex + o - (i > 0 ? 0 : a), e.ey + o - (r > 0 ? 0 : h), a, h)
        },
        findTarget: function (t, e) {
            if (!this.skipTargetFind) {
                var i, r = !0, n = this.getPointer(t, r), s = this.getActiveGroup(), o = this.getActiveObject();
                if (this.targets = [], s && !e && s === this._searchPossibleTargets([s], n))return this._fireOverOutEvents(s, t), s;
                if (o && o._findTargetCorner(n))return this._fireOverOutEvents(o, t), o;
                if (o && o === this._searchPossibleTargets([o], n)) {
                    if (!this.preserveObjectStacking)return this._fireOverOutEvents(o, t), o;
                    i = o
                }
                var a = this._searchPossibleTargets(this._objects, n);
                return t[this.altSelectionKey] && a && i && a !== i && (a = i), this._fireOverOutEvents(a, t), a
            }
        },
        _fireOverOutEvents: function (t, e) {
            var i, r, n = this._hoveredTarget;
            n !== t && (i = {e: e, target: t, previousTarget: this._hoveredTarget}, r = {
                e: e,
                target: this._hoveredTarget,
                nextTarget: t
            }, this._hoveredTarget = t), t ? n !== t && (n && (this.fire("mouse:out", r), n.fire("mouseout", r)), this.fire("mouse:over", i), t.fire("mouseover", i)) : n && (this.fire("mouse:out", r), n.fire("mouseout", r))
        },
        _checkTarget: function (t, e) {
            if (e && e.visible && e.evented && this.containsPoint(null, e, t)) {
                if (!this.perPixelTargetFind && !e.perPixelTargetFind || e.isEditing)return !0;
                var i = this.isTargetTransparent(e, t.x, t.y);
                if (!i)return !0
            }
        },
        _searchPossibleTargets: function (t, e) {
            for (var i, r, n, s = t.length; s--;)if (this._checkTarget(e, t[s])) {
                i = t[s], "group" === i.type && i.subTargetCheck && (r = this._normalizePointer(i, e), n = this._searchPossibleTargets(i._objects, r), n && this.targets.push(n));
                break
            }
            return i
        },
        restorePointerVpt: function (t) {
            return fabric.util.transformPoint(t, fabric.util.invertTransform(this.viewportTransform))
        },
        getPointer: function (e, i, r) {
            r || (r = this.upperCanvasEl);
            var n, s = t(e), o = r.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(), s.x = s.x - this._offset.left, s.y = s.y - this._offset.top, i || (s = this.restorePointerVpt(s)), n = 0 === a || 0 === h ? {
                width: 1,
                height: 1
            } : {width: r.width / a, height: r.height / h}, {x: s.x * n.width, y: s.y * n.height}
        },
        _createUpperCanvas: function () {
            var t = this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/, "");
            this.upperCanvasEl ? this.upperCanvasEl.className = "" : this.upperCanvasEl = this._createCanvasElement(), fabric.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 = fabric.util.wrapElement(this.lowerCanvasEl, "div", {class: this.containerClass}), fabric.util.setStyle(this.wrapperEl, {
                width: this.getWidth() + "px",
                height: this.getHeight() + "px",
                position: "relative"
            }), fabric.util.makeElementUnselectable(this.wrapperEl)
        },
        _applyCanvasStyle: function (t) {
            var e = this.getWidth() || t.width, i = this.getHeight() || t.height;
            fabric.util.setStyle(t, {
                position: "absolute",
                width: e + "px",
                height: i + "px",
                left: 0,
                top: 0,
                "touch-action": "none"
            }), t.width = e, t.height = i, fabric.util.makeElementUnselectable(t)
        },
        _copyCanvasStyle: function (t, e) {
            e.style.cssText = t.style.cssText
        },
        getSelectionContext: function () {
            return this.contextTop
        },
        getSelectionElement: function () {
            return this.upperCanvasEl
        },
        _setActiveObject: function (t) {
            var e = this._activeObject;
            e && (e.set("active", !1), t !== e && e.onDeselect && "function" == typeof e.onDeselect && e.onDeselect()), this._activeObject = t, t.set("active", !0)
        },
        setActiveObject: function (t, e) {
            var i = this.getActiveObject();
            return i && i !== t && i.fire("deselected", {e: e}), this._setActiveObject(t), this.fire("object:selected", {
                target: t,
                e: e
            }), t.fire("selected", {e: e}), this.renderAll(), this
        },
        getActiveObject: function () {
            return this._activeObject
        },
        _onObjectRemoved: function (t) {
            this.getActiveObject() === t && (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)
        },
        _discardActiveObject: function () {
            var t = this._activeObject;
            t && (t.set("active", !1), t.onDeselect && "function" == typeof t.onDeselect && t.onDeselect()), this._activeObject = null
        },
        discardActiveObject: function (t) {
            var e = this._activeObject;
            return e && (this.fire("before:selection:cleared", {
                target: e,
                e: t
            }), this._discardActiveObject(), this.fire("selection:cleared", {e: t}), e.fire("deselected", {e: t})), this
        },
        _setActiveGroup: function (t) {
            this._activeGroup = t, t && t.set("active", !0)
        },
        setActiveGroup: function (t, e) {
            return this._setActiveGroup(t), t && (this.fire("object:selected", {
                target: t,
                e: e
            }), t.fire("selected", {e: e})), this
        },
        getActiveGroup: function () {
            return this._activeGroup
        },
        _discardActiveGroup: function () {
            var t = this.getActiveGroup();
            t && t.destroy(), this.setActiveGroup(null)
        },
        discardActiveGroup: function (t) {
            var e = this.getActiveGroup();
            return e && (this.fire("before:selection:cleared", {
                e: t,
                target: e
            }), this._discardActiveGroup(), this.fire("selection:cleared", {e: t})), this
        },
        deactivateAll: function () {
            for (var t, e = this.getObjects(), i = 0, r = e.length; i < r; i++)t = e[i], t && t.set("active", !1);
            return this._discardActiveGroup(), this._discardActiveObject(), this
        },
        deactivateAllWithDispatch: function (t) {
            for (var e, i = this.getObjects(), r = 0, n = i.length; r < n; r++)e = i[r], e && e.set("active", !1);
            return this.discardActiveGroup(t), this.discardActiveObject(t), this
        },
        dispose: function () {
            fabric.StaticCanvas.prototype.dispose.call(this);
            var t = this.wrapperEl;
            return this.removeListeners(), t.removeChild(this.upperCanvasEl),
                t.removeChild(this.lowerCanvasEl), delete this.upperCanvasEl, t.parentNode && t.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl), delete this.wrapperEl, this
        },
        clear: function () {
            return this.discardActiveGroup(), this.discardActiveObject(), this.clearContext(this.contextTop), this.callSuper("clear")
        },
        drawControls: function (t) {
            var e = this.getActiveGroup();
            e ? e._renderControls(t) : this._drawObjectsControls(t)
        },
        _drawObjectsControls: function (t) {
            for (var e = 0, i = this._objects.length; e < i; ++e)this._objects[e] && this._objects[e].active && this._objects[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 && t.group === this.getActiveGroup()) {
                var e = {}, i = ["angle", "flipX", "flipY", "left", "scaleX", "scaleY", "skewX", "skewY", "top"];
                return i.forEach(function (i) {
                    e[i] = t[i]
                }), this.getActiveGroup().realizeTransform(t), e
            }
            return null
        },
        _unwindGroupTransformOnObject: function (t, e) {
            e && t.set(e)
        },
        _setSVGObject: function (t, e, i) {
            var r;
            r = this._realizeGroupTransformOnObject(e), this.callSuper("_setSVGObject", t, e, i), this._unwindGroupTransformOnObject(e, r)
        }
    });
    for (var a in fabric.StaticCanvas)"prototype" !== a && (fabric.Canvas[a] = fabric.StaticCanvas[a]);
    fabric.isTouchSupported && (fabric.Canvas.prototype._setCursorFromEvent = function () {
    }), fabric.Element = fabric.Canvas
}(), function () {
    function t(t, e) {
        return "which"in t ? t.which === e : t.button === e - 1
    }

    var e = {
        mt: 0,
        tr: 1,
        mr: 2,
        br: 3,
        mb: 4,
        bl: 5,
        ml: 6,
        tl: 7
    }, i = fabric.util.addListener, r = fabric.util.removeListener, n = 3, s = 2, o = 1;
    fabric.util.object.extend(fabric.Canvas.prototype, {
        cursorMap: ["n-resize", "ne-resize", "e-resize", "se-resize", "s-resize", "sw-resize", "w-resize", "nw-resize"],
        _initEventListeners: function () {
            this.removeListeners(), this._bindEvents(), i(fabric.window, "resize", this._onResize), i(this.upperCanvasEl, "mousedown", this._onMouseDown), i(this.upperCanvasEl, "mousemove", this._onMouseMove), i(this.upperCanvasEl, "mouseout", this._onMouseOut), i(this.upperCanvasEl, "mouseenter", this._onMouseEnter), i(this.upperCanvasEl, "wheel", this._onMouseWheel), i(this.upperCanvasEl, "contextmenu", this._onContextMenu), i(this.upperCanvasEl, "touchstart", this._onMouseDown, {passive: !1}), i(this.upperCanvasEl, "touchmove", this._onMouseMove, {passive: !1}), "undefined" != typeof eventjs && "add"in eventjs && (eventjs.add(this.upperCanvasEl, "gesture", this._onGesture), eventjs.add(this.upperCanvasEl, "drag", this._onDrag), eventjs.add(this.upperCanvasEl, "orientation", this._onOrientationChange), eventjs.add(this.upperCanvasEl, "shake", this._onShake), eventjs.add(this.upperCanvasEl, "longpress", this._onLongPress))
        },
        _bindEvents: function () {
            this.eventsBinded || (this._onMouseDown = this._onMouseDown.bind(this), this._onMouseMove = this._onMouseMove.bind(this), this._onMouseUp = this._onMouseUp.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.eventsBinded = !0)
        },
        removeListeners: function () {
            r(fabric.window, "resize", this._onResize), r(this.upperCanvasEl, "mousedown", this._onMouseDown), r(this.upperCanvasEl, "mousemove", this._onMouseMove), r(this.upperCanvasEl, "mouseout", this._onMouseOut), r(this.upperCanvasEl, "mouseenter", this._onMouseEnter), r(this.upperCanvasEl, "wheel", this._onMouseWheel), r(this.upperCanvasEl, "contextmenu", this._onContextMenu), r(this.upperCanvasEl, "touchstart", this._onMouseDown), r(this.upperCanvasEl, "touchmove", this._onMouseMove), "undefined" != typeof eventjs && "remove"in eventjs && (eventjs.remove(this.upperCanvasEl, "gesture", this._onGesture), eventjs.remove(this.upperCanvasEl, "drag", this._onDrag), eventjs.remove(this.upperCanvasEl, "orientation", this._onOrientationChange), eventjs.remove(this.upperCanvasEl, "shake", this._onShake), eventjs.remove(this.upperCanvasEl, "longpress", this._onLongPress))
        },
        _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.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)
        },
        _onContextMenu: function (t) {
            return this.stopContextMenu && (t.stopPropagation(), t.preventDefault()), !1
        },
        _onMouseDown: function (t) {
            this.__onMouseDown(t), i(fabric.document, "touchend", this._onMouseUp, {passive: !1}), i(fabric.document, "touchmove", this._onMouseMove, {passive: !1}), r(this.upperCanvasEl, "mousemove", this._onMouseMove), r(this.upperCanvasEl, "touchmove", this._onMouseMove), "touchstart" === t.type ? r(this.upperCanvasEl, "mousedown", this._onMouseDown) : (i(fabric.document, "mouseup", this._onMouseUp), i(fabric.document, "mousemove", this._onMouseMove))
        },
        _onMouseUp: function (t) {
            if (this.__onMouseUp(t), r(fabric.document, "mouseup", this._onMouseUp), r(fabric.document, "touchend", this._onMouseUp), r(fabric.document, "mousemove", this._onMouseMove), r(fabric.document, "touchmove", this._onMouseMove), i(this.upperCanvasEl, "mousemove", this._onMouseMove), i(this.upperCanvasEl, "touchmove", this._onMouseMove, {passive: !1}), "touchend" === t.type) {
                var e = this;
                setTimeout(function () {
                    i(e.upperCanvasEl, "mousedown", e._onMouseDown)
                }, 400)
            }
        },
        _onMouseMove: function (t) {
            !this.allowTouchScrolling && t.preventDefault && t.preventDefault(), this.__onMouseMove(t)
        },
        _onResize: function () {
            this.calcOffset()
        },
        _shouldRender: function (t, e) {
            var i = this.getActiveGroup() || this.getActiveObject();
            return (!i || !i.isEditing || t !== i) && !!(t && (t.isMoving || t !== i) || !t && i || !t && !i && !this._groupSelector || e && this._previousPointer && this.selection && (e.x !== this._previousPointer.x || e.y !== this._previousPointer.y))
        },
        __onMouseUp: function (e) {
            var i;
            if (t(e, n))return void(this.fireRightClick && this._handleEvent(e, "up", i, n));
            if (t(e, s))return void(this.fireMiddleClick && this._handleEvent(e, "up", i, s));
            if (this.isDrawingMode && this._isCurrentlyDrawing)return void this._onMouseUpInDrawingMode(e);
            var r = !0, a = this._currentTransform, h = this._groupSelector, c = !h || 0 === h.left && 0 === h.top;
            a && (this._finalizeCurrentTransform(e), r = !a.actionPerformed), i = r ? this.findTarget(e, !0) : a.target;
            var l = this._shouldRender(i, this.getPointer(e));
            i || !c ? this._maybeGroupObjects(e) : (this._groupSelector = null, this._currentTransform = null), i && (i.isMoving = !1), this._setCursorFromEvent(e, i), this._handleEvent(e, "up", i ? i : null, o, c), i && (i.__corner = 0), l && this.renderAll()
        },
        _handleEvent: function (t, e, i, r, n) {
            var s = "undefined" == typeof i ? this.findTarget(t) : i, a = this.targets || [], h = {
                e: t,
                target: s,
                subTargets: a,
                button: r || o,
                isClick: n || !1
            };
            this.fire("mouse:" + e, h), s && s.fire("mouse" + e, h);
            for (var c = 0; c < a.length; c++)a[c].fire("mouse" + e, h)
        },
        _finalizeCurrentTransform: function (t) {
            var e = this._currentTransform, i = e.target;
            i._scaling && (i._scaling = !1), i.setCoords(), this._restoreOriginXY(i), (e.actionPerformed || this.stateful && i.hasStateChanged()) && (this.fire("object:modified", {
                target: i,
                e: t
            }), i.fire("modified", {e: t}))
        },
        _restoreOriginXY: function (t) {
            if (this._previousOriginX && this._previousOriginY) {
                var e = t.translateToOriginPoint(t.getCenterPoint(), this._previousOriginX, this._previousOriginY);
                t.originX = this._previousOriginX, t.originY = this._previousOriginY, t.left = e.x, t.top = e.y, this._previousOriginX = null, this._previousOriginY = null
            }
        },
        _onMouseDownInDrawingMode: function (t) {
            this._isCurrentlyDrawing = !0, this.discardActiveObject(t).renderAll(), this.clipTo && fabric.util.clipContext(this, this.contextTop);
            var e = this.getPointer(t);
            this.freeDrawingBrush.onMouseDown(e), this._handleEvent(t, "down")
        },
        _onMouseMoveInDrawingMode: function (t) {
            if (this._isCurrentlyDrawing) {
                var e = this.getPointer(t);
                this.freeDrawingBrush.onMouseMove(e)
            }
            this.setCursor(this.freeDrawingCursor), this._handleEvent(t, "move")
        },
        _onMouseUpInDrawingMode: function (t) {
            this._isCurrentlyDrawing = !1, this.clipTo && this.contextTop.restore(), this.freeDrawingBrush.onMouseUp(), this._handleEvent(t, "up")
        },
        __onMouseDown: function (e) {
            var i = this.findTarget(e);
            if (t(e, n))return void(this.fireRightClick && this._handleEvent(e, "down", i ? i : null, n));
            if (t(e, s))return void(this.fireMiddleClick && this._handleEvent(e, "down", i ? i : null, s));
            if (this.isDrawingMode)return void this._onMouseDownInDrawingMode(e);
            if (!this._currentTransform) {
                var r = this.getPointer(e, !0);
                this._previousPointer = r;
                var o = this._shouldRender(i, r), a = this._shouldGroup(e, i);
                if (this._shouldClearSelection(e, i) ? this.deactivateAllWithDispatch(e) : a && (this._handleGrouping(e, i), i = this.getActiveGroup()), !this.selection || i && (i.selectable || i.isEditing) || (this._groupSelector = {
                        ex: r.x,
                        ey: r.y,
                        top: 0,
                        left: 0
                    }), i) {
                    !i.selectable || !i.__corner && a || (this._beforeTransform(e, i), this._setupCurrentTransform(e, i));
                    var h = this.getActiveObject();
                    i !== this.getActiveGroup() && i !== h && (this.deactivateAll(), i.selectable && (h && h.fire("deselected", {e: e}), this.setActiveObject(i, e)))
                }
                this._handleEvent(e, "down", i ? i : null), o && this.renderAll()
            }
        },
        _beforeTransform: function (t, e) {
            this.stateful && e.saveState(), e._findTargetCorner(this.getPointer(t)) && this.onBeforeScaleRotate(e)
        },
        _setOriginToCenter: function (t) {
            this._previousOriginX = this._currentTransform.target.originX, this._previousOriginY = this._currentTransform.target.originY;
            var e = t.getCenterPoint();
            t.originX = "center", t.originY = "center", t.left = e.x, t.top = e.y, this._currentTransform.left = t.left, this._currentTransform.top = t.top
        },
        _setCenterToOrigin: function (t) {
            var e = t.translateToOriginPoint(t.getCenterPoint(), this._previousOriginX, this._previousOriginY);
            t.originX = this._previousOriginX, t.originY = this._previousOriginY, t.left = e.x, t.top = e.y, this._previousOriginX = null, this._previousOriginY = null
        },
        __onMouseMove: function (t) {
            var e, i;
            if (this.isDrawingMode)return void this._onMouseMoveInDrawingMode(t);
            if (!("undefined" != typeof t.touches && t.touches.length > 1)) {
                var r = this._groupSelector;
                r ? (i = this.getPointer(t, !0), r.left = i.x - r.ex, r.top = i.y - r.ey, this.renderTop()) : this._currentTransform ? this._transformObject(t) : (e = this.findTarget(t), this._setCursorFromEvent(t, e)), this._handleEvent(t, "move", e ? e : null)
            }
        },
        __onMouseWheel: function (t) {
            this._handleEvent(t, "wheel")
        },
        _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.renderAll()
        },
        _performTransformAction: function (t, e, i) {
            var r = i.x, n = i.y, s = e.target, o = e.action, a = !1;
            "rotate" === o ? (a = this._rotateObject(r, n)) && this._fire("rotating", s, t) : "scale" === o ? (a = this._onScale(t, e, r, n)) && this._fire("scaling", s, t) : "scaleX" === o ? (a = this._scaleObject(r, n, "x")) && this._fire("scaling", s, t) : "scaleY" === o ? (a = this._scaleObject(r, n, "y")) && this._fire("scaling", s, t) : "skewX" === o ? (a = this._skewObject(r, n, "x")) && this._fire("skewing", s, t) : "skewY" === o ? (a = this._skewObject(r, n, "y")) && this._fire("skewing", s, t) : (a = this._translateObject(r, n), a && (this._fire("moving", s, t), this.setCursor(s.moveCursor || this.moveCursor))), e.actionPerformed = e.actionPerformed || a
        },
        _fire: function (t, e, i) {
            this.fire("object:" + t, {target: e, e: i}), e.fire(t, {e: i})
        },
        _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 !t[this.uniScaleKey] && !this.uniScaleTransform || e.target.get("lockUniScaling") ? (e.reset || "scale" !== e.currentAction || this._resetCurrentTransform(), e.currentAction = "scaleEqually", this._scaleObject(i, r, "equally")) : (e.currentAction = "scale", this._scaleObject(i, r))
        },
        _setCursorFromEvent: function (t, e) {
            if (!e)return this.setCursor(this.defaultCursor), !1;
            var i = e.hoverCursor || this.hoverCursor, r = this.getActiveGroup(), n = e._findTargetCorner && (!r || !r.contains(e)) && e._findTargetCorner(this.getPointer(t, !0));
            return n ? this._setCornerCursor(n, e, t) : this.setCursor(i), !0
        },
        _setCornerCursor: function (t, i, r) {
            if (t in e)this.setCursor(this._getRotatedCornerCursor(t, i, r)); else {
                if ("mtr" !== t || !i.hasRotatingPoint)return this.setCursor(this.defaultCursor), !1;
                this.setCursor(this.rotationCursor)
            }
        },
        _getRotatedCornerCursor: function (t, i, r) {
            var n = Math.round(i.getAngle() % 360 / 45);
            return n < 0 && (n += 8), n += e[t], r[this.altActionKey] && e[t] % 2 === 0 && (n += 2), n %= 8, this.cursorMap[n]
        }
    })
}(), function () {
    var t = Math.min, e = Math.max;
    fabric.util.object.extend(fabric.Canvas.prototype, {
        _shouldGroup: function (t, e) {
            var i = this.getActiveObject();
            return t[this.selectionKey] && e && e.selectable && (this.getActiveGroup() || i && i !== e) && this.selection
        }, _handleGrouping: function (t, e) {
            var i = this.getActiveGroup();
            (e !== i || (e = this.findTarget(t, !0))) && (i ? this._updateActiveGroup(e, t) : this._createActiveGroup(e, t), this._activeGroup && this._activeGroup.saveCoords())
        }, _updateActiveGroup: function (t, e) {
            var i = this.getActiveGroup();
            if (i.contains(t)) {
                if (i.removeWithUpdate(t), t.set("active", !1), 1 === i.size())return this.discardActiveGroup(e), void this.setActiveObject(i.item(0), e)
            } else i.addWithUpdate(t);
            this.fire("selection:created", {target: i, e: e}), i.set("active", !0)
        }, _createActiveGroup: function (t, e) {
            if (this._activeObject && t !== this._activeObject) {
                var i = this._createGroup(t);
                i.addWithUpdate(), this.setActiveGroup(i, e), this._activeObject = null, this.fire("selection:created", {
                    target: i,
                    e: e
                })
            }
            t.set("active", !0)
        }, _createGroup: function (t) {
            var e = this.getObjects(), i = e.indexOf(this._activeObject) < e.indexOf(t), r = i ? [this._activeObject, t] : [t, this._activeObject];
            return this._activeObject.isEditing && this._activeObject.exitEditing(), new fabric.Group(r, {canvas: this})
        }, _groupSelectedObjects: function (t) {
            var e = this._collectObjects();
            1 === e.length ? this.setActiveObject(e[0], t) : e.length > 1 && (e = new fabric.Group(e.reverse(), {canvas: this}), e.addWithUpdate(), this.setActiveGroup(e, t), e.saveCoords(), this.fire("selection:created", {
                target: e,
                e: t
            }), this.renderAll())
        }, _collectObjects: function () {
            for (var i, r = [], n = this._groupSelector.ex, s = this._groupSelector.ey, o = n + this._groupSelector.left, a = s + this._groupSelector.top, h = new fabric.Point(t(n, o), t(s, a)), c = new fabric.Point(e(n, o), e(s, a)), l = n === o && s === a, u = this._objects.length; u-- && (i = this._objects[u], !(i && i.selectable && i.visible && (i.intersectsWithRect(h, c) || i.isContainedWithinRect(h, c) || i.containsPoint(h) || i.containsPoint(c)) && (i.set("active", !0), r.push(i), l))););
            return r
        }, _maybeGroupObjects: function (t) {
            this.selection && this._groupSelector && this._groupSelectedObjects(t);
            var e = this.getActiveGroup();
            e && (e.setObjectsCoords().setCoords(), e.isMoving = !1, this.setCursor(this.defaultCursor)), this._groupSelector = null, this._currentTransform = null
        }
    })
}(), function () {
    var t = fabric.StaticCanvas.supports("toDataURLWithQuality");
    fabric.util.object.extend(fabric.StaticCanvas.prototype, {
        toDataURL: function (t) {
            t || (t = {});
            var e = t.format || "png", i = t.quality || 1, r = t.multiplier || 1, n = {
                left: t.left || 0,
                top: t.top || 0,
                width: t.width || 0,
                height: t.height || 0
            };
            return this.__toDataURLWithMultiplier(e, i, n, r)
        }, __toDataURLWithMultiplier: function (t, e, i, r) {
            var n = this.getWidth(), s = this.getHeight(), o = (i.width || this.getWidth()) * r, a = (i.height || this.getHeight()) * r, h = this.getZoom(), c = h * r, l = this.viewportTransform, u = (l[4] - i.left) * r, f = (l[5] - i.top) * r, d = [c, 0, 0, c, u, f], g = this.interactive;
            this.viewportTransform = d, this.interactive && (this.interactive = !1), n !== o || s !== a ? this.setDimensions({
                width: o,
                height: a
            }) : this.renderAll();
            var p = this.__toDataURL(t, e, i);
            return g && (this.interactive = g), this.viewportTransform = l, this.setDimensions({width: n, height: s}), p
        }, __toDataURL: function (e, i) {
            var r = this.contextContainer.canvas;
            "jpg" === e && (e = "jpeg");
            var n = t ? r.toDataURL("image/" + e, i) : r.toDataURL("image/" + e);
            return n
        }, toDataURLWithMultiplier: function (t, e, i) {
            return this.toDataURL({format: t, multiplier: e, quality: i})
        }
    })
}(), fabric.util.object.extend(fabric.StaticCanvas.prototype, {
    loadFromDatalessJSON: function (t, e, i) {
        return this.loadFromJSON(t, e, i)
    }, loadFromJSON: function (t, e, i) {
        if (t) {
            var r = "string" == typeof t ? JSON.parse(t) : fabric.util.object.clone(t), n = this, s = this.renderOnAddRemove;
            return this.renderOnAddRemove = !1, this._enlivenObjects(r.objects, function (t) {
                n.clear(), n._setBgOverlay(r, function () {
                    t.forEach(function (t, e) {
                        n.insertAt(t, e)
                    }), n.renderOnAddRemove = s, delete r.objects, delete r.backgroundImage, delete r.overlayImage, delete r.background, delete r.overlay, n._setOptions(r), n.renderAll(), e && e()
                })
            }, i), this
        }
    }, _setBgOverlay: function (t, e) {
        var i = {backgroundColor: !1, overlayColor: !1, backgroundImage: !1, overlayImage: !1};
        if (!(t.backgroundImage || t.overlayImage || t.background || t.overlay))return void(e && e());
        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)
    }, __setBgOverlay: function (t, e, i, r) {
        var n = this;
        return e ? void("backgroundImage" === t || "overlayImage" === t ? fabric.util.enlivenObjects([e], function (e) {
            n[t] = e[0], i[t] = !0, r && r()
        }) : this["set" + fabric.util.string.capitalize(t, !0)](e, function () {
            i[t] = !0, r && r()
        })) : (i[t] = !0, void(r && r()))
    }, _enlivenObjects: function (t, e, i) {
        return t && 0 !== t.length ? void fabric.util.enlivenObjects(t, function (t) {
            e && e(t)
        }, null, i) : void(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 = fabric.document.createElement("canvas");
        e.width = this.getWidth(), e.height = this.getHeight();
        var i = new fabric.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, c = 2;
    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: "",